Форк Rambox
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

152945 lines
4.4 MiB

/*
This file is part of Ext JS 5.1.1.451
Copyright (c) 2011-2015 Sencha Inc
Contact: http://www.sencha.com/contact
GNU General Public License Usage
This file may be used under the terms of the GNU General Public License version 3.0 as
published by the Free Software Foundation and appearing in the file LICENSE included in the
packaging of this file.
Please review the following information to ensure the GNU General Public License version 3.0
requirements will be met: http://www.gnu.org/copyleft/gpl.html.
If you are unsure which license is appropriate for your use, please contact the sales department
at http://www.sencha.com/contact.
Version: 5.1.1.451 Build date: 2015-05-06 21:53:32 (130b7b8a6334f33aee5c2952cefb768cadb3bf78)
*/
var Ext = Ext || {};
Ext.Boot = Ext.Boot || (function (emptyFn) {
var doc = document,
apply = function (dest, src, defaults) {
if (defaults) {
apply(dest, defaults);
}
if (dest && src && typeof src == 'object') {
for (var key in src) {
dest[key] = src[key];
}
}
return dest;
},
_config = {
disableCaching: (/[?&](?:cache|disableCacheBuster)\b/i.test(location.search) ||
!(/http[s]?\:/i.test(location.href)) ||
/(^|[ ;])ext-cache=1/.test(doc.cookie)) ? false :
true,
disableCachingParam: '_dc',
loadDelay: false,
preserveScripts: true,
charset: undefined
},
cssRe = /\.css(?:\?|$)/i,
resolverEl = doc.createElement('a'),
isBrowser = typeof window !== 'undefined',
_environment = {
browser: isBrowser,
node: !isBrowser && (typeof require === 'function'),
phantom: (typeof phantom !== 'undefined' && phantom.fs)
},
_tags = (Ext.platformTags = {}),
_debug = function (message) {
},
_apply = function (object, config, defaults) {
if (defaults) {
_apply(object, defaults);
}
if (object && config && typeof config === 'object') {
for (var i in config) {
object[i] = config[i];
}
}
return object;
},
Boot = {
loading: 0,
loaded: 0,
env: _environment,
config: _config,
scripts: {
},
currentFile: null,
suspendedQueue: [],
currentRequest: null,
syncMode: false,
debug: _debug,
useElements: true,
listeners: [],
Request: Request,
Entry: Entry,
detectPlatformTags: function () {
var ua = navigator.userAgent,
isMobile = _tags.isMobile = /Mobile(\/|\s)/.test(ua),
isPhone, isDesktop, isTablet, touchSupported, isIE10, isBlackberry,
element = document.createElement('div'),
uaTagChecks = [
'iPhone',
'iPod',
'Android',
'Silk',
'Android 2',
'BlackBerry',
'BB',
'iPad',
'RIM Tablet OS',
'MSIE 10',
'Trident',
'Chrome',
'Tizen',
'Firefox',
'Safari',
'Windows Phone'
],
isEventSupported = function(name, tag) {
if (tag === undefined) {
tag = window;
}
var eventName = 'on' + name.toLowerCase(),
isSupported = (eventName in element);
if (!isSupported) {
if (element.setAttribute && element.removeAttribute) {
element.setAttribute(eventName, '');
isSupported = typeof element[eventName] === 'function';
if (typeof element[eventName] !== 'undefined') {
element[eventName] = undefined;
}
element.removeAttribute(eventName);
}
}
return isSupported;
},
uaTags = {},
len = uaTagChecks.length, check, c;
for (c = 0; c < len; c++) {
check = uaTagChecks[c];
uaTags[check] = new RegExp(check).test(ua);
}
isPhone =
(uaTags.iPhone || uaTags.iPod) ||
(!uaTags.Silk && (uaTags.Android && (uaTags['Android 2'] || isMobile))) ||
((uaTags.BlackBerry || uaTags.BB) && uaTags.isMobile) ||
(uaTags['Windows Phone']);
isTablet =
(!_tags.isPhone) && (
uaTags.iPad ||
uaTags.Android ||
uaTags.Silk ||
uaTags['RIM Tablet OS'] ||
(uaTags['MSIE 10'] && /; Touch/.test(ua))
);
touchSupported =
isEventSupported('touchend') ||
navigator.maxTouchPoints ||
navigator.msMaxTouchPoints;
isDesktop = !isPhone && !isTablet;
isIE10 = uaTags['MSIE 10'];
isBlackberry = uaTags.Blackberry || uaTags.BB;
apply(_tags, Boot.loadPlatformsParam(), {
phone: isPhone,
tablet: isTablet,
desktop: isDesktop,
touch: touchSupported,
ios: (uaTags.iPad || uaTags.iPhone || uaTags.iPod),
android: uaTags.Android || uaTags.Silk,
blackberry: isBlackberry,
safari: uaTags.Safari && !isBlackberry,
chrome: uaTags.Chrome,
ie10: isIE10,
windows: isIE10 || uaTags.Trident,
tizen: uaTags.Tizen,
firefox: uaTags.Firefox
});
},
loadPlatformsParam: function () {
var paramsString = window.location.search.substr(1),
paramsArray = paramsString.split("&"),
params = {}, i,
platforms = {},
tmpArray, tmplen, platform, name, enabled;
for (i = 0; i < paramsArray.length; i++) {
tmpArray = paramsArray[i].split("=");
params[tmpArray[0]] = tmpArray[1];
}
if (params.platformTags) {
tmpArray = params.platform.split(/\W/);
for (tmplen = tmpArray.length, i = 0; i < tmplen; i++) {
platform = tmpArray[i].split(":");
name = platform[0];
if (platform.length > 1) {
enabled = platform[1];
if (enabled === 'false' || enabled === '0') {
enabled = false;
} else {
enabled = true;
}
}
platforms[name] = enabled;
}
}
return platform;
},
filterPlatform: function (platform) {
platform = [].concat(platform);
var len, p, tag;
for (len = platform.length, p = 0; p < len; p++) {
tag = platform[p];
if (_tags.hasOwnProperty(tag)) {
return !!_tags[tag];
}
}
return false;
},
init: function () {
var scriptEls = doc.getElementsByTagName('script'),
len = scriptEls.length,
re = /\/ext(\-[a-z\-]+)?\.js$/,
entry, script, src, state, baseUrl, key, n, origin;
for (n = 0; n < len; n++) {
src = (script = scriptEls[n]).src;
if (!src) {
continue;
}
state = script.readyState || null;
if (!baseUrl) {
if (re.test(src)) {
Boot.hasReadyState = ("readyState" in script);
Boot.hasAsync = ("async" in script) || !Boot.hasReadyState;
baseUrl = src;
}
}
if (!Boot.scripts[key = Boot.canonicalUrl(src)]) {
_debug("creating entry " + key + " in Boot.init");
entry = new Entry({
key: key,
url: src,
done: state === null ||
state === 'loaded' || state === 'complete',
el: script,
prop: 'src'
});
}
}
if (!baseUrl) {
script = scriptEls[scriptEls.length - 1];
baseUrl = script.src;
Boot.hasReadyState = ('readyState' in script);
Boot.hasAsync = ("async" in script) || !Boot.hasReadyState;
}
Boot.baseUrl = baseUrl.substring(0, baseUrl.lastIndexOf('/') + 1);
origin = window.location.origin ||
window.location.protocol +
"//" +
window.location.hostname +
(window.location.port ? ':' + window.location.port: '');
Boot.origin = origin;
Boot.detectPlatformTags();
Ext.filterPlatform = Boot.filterPlatform;
},
canonicalUrl: function (url) {
resolverEl.href = url;
var ret = resolverEl.href,
dc = _config.disableCachingParam,
pos = dc ? ret.indexOf(dc + '=') : -1,
c, end;
if (pos > 0 && ((c = ret.charAt(pos - 1)) === '?' || c === '&')) {
end = ret.indexOf('&', pos);
end = (end < 0) ? '' : ret.substring(end);
if (end && c === '?') {
++pos;
end = end.substring(1);
}
ret = ret.substring(0, pos - 1) + end;
}
return ret;
},
getConfig: function (name) {
return name ? Boot.config[name] : Boot.config;
},
setConfig: function (name, value) {
if (typeof name === 'string') {
Boot.config[name] = value;
} else {
for (var s in name) {
Boot.setConfig(s, name[s]);
}
}
return Boot;
},
getHead: function () {
return Boot.docHead ||
(Boot.docHead = doc.head ||
doc.getElementsByTagName('head')[0]);
},
create: function (url, key, cfg) {
var config = cfg || {};
config.url = url;
config.key = key;
return Boot.scripts[key] = new Entry(config);
},
getEntry: function (url, cfg) {
var key = Boot.canonicalUrl(url),
entry = Boot.scripts[key];
if (!entry) {
entry = Boot.create(url, key, cfg);
}
return entry;
},
processRequest: function(request, sync) {
request.loadEntries(sync);
},
load: function (request) {
_debug("Boot.load called");
var request = new Request(request);
if (request.sync || Boot.syncMode) {
return Boot.loadSync(request);
}
if (Boot.currentRequest) {
_debug("current active request, suspending this request");
request.getEntries();
Boot.suspendedQueue.push(request);
} else {
Boot.currentRequest = request;
Boot.processRequest(request, false);
}
return Boot;
},
loadSync: function (request) {
_debug("Boot.loadSync called");
var request = new Request(request);
Boot.syncMode++;
Boot.processRequest(request, true);
Boot.syncMode--;
return Boot;
},
loadBasePrefix: function(request) {
request = new Request(request);
request.prependBaseUrl = true;
return Boot.load(request);
},
loadSyncBasePrefix: function(request) {
request = new Request(request);
request.prependBaseUrl = true;
return Boot.loadSync(request);
},
requestComplete: function(request) {
var next;
if (Boot.currentRequest === request) {
Boot.currentRequest = null;
while(Boot.suspendedQueue.length > 0) {
next = Boot.suspendedQueue.shift();
if(!next.done) {
_debug("resuming suspended request");
Boot.load(next);
break;
}
}
}
if (!Boot.currentRequest && Boot.suspendedQueue.length == 0) {
Boot.fireListeners();
}
},
isLoading: function () {
return !Boot.currentRequest && Boot.suspendedQueue.length == 0;
},
fireListeners: function () {
var listener;
while (Boot.isLoading() && (listener = Boot.listeners.shift())) {
listener();
}
},
onBootReady: function (listener) {
if (!Boot.isLoading()) {
listener();
} else {
Boot.listeners.push(listener);
}
},
getPathsFromIndexes: function (indexMap, loadOrder) {
return Request.prototype.getPathsFromIndexes(indexMap, loadOrder);
},
createLoadOrderMap: function(loadOrder) {
return Request.prototype.createLoadOrderMap(loadOrder);
},
fetch: function(url, complete, scope, async) {
async = (async === undefined) ? !!complete : async;
var xhr = new XMLHttpRequest(),
result, status, content, exception = false,
readyStateChange = function () {
if (xhr && xhr.readyState == 4) {
status = (xhr.status === 1223) ? 204 :
(xhr.status === 0 && ((self.location || {}).protocol === 'file:' ||
(self.location || {}).protocol === 'ionp:')) ? 200 : xhr.status;
content = xhr.responseText;
result = {
content: content,
status: status,
exception: exception
};
if (complete) {
complete.call(scope, result);
}
xhr = null;
}
};
if (async) {
xhr.onreadystatechange = readyStateChange;
}
try {
_debug("fetching " + url + " " + (async ? "async" : "sync"));
xhr.open('GET', url, async);
xhr.send(null);
} catch (err) {
exception = err;
readyStateChange();
return result;
}
if (!async) {
readyStateChange();
}
return result;
},
notifyAll: function(entry) {
entry.notifyRequests();
}
};
function Request(cfg) {
if(cfg.$isRequest) {
return cfg;
}
var cfg = cfg.url ? cfg : {url: cfg},
url = cfg.url,
urls = url.charAt ? [ url ] : url,
charset = cfg.charset || Boot.config.charset;
_apply(cfg, {
urls: urls,
charset: charset
});
_apply(this, cfg);
};
Request.prototype = {
$isRequest: true,
createLoadOrderMap: function (loadOrder) {
var len = loadOrder.length,
loadOrderMap = {},
i, element;
for (i = 0; i < len; i++) {
element = loadOrder[i];
loadOrderMap[element.path] = element;
}
return loadOrderMap;
},
getLoadIndexes: function (index, indexMap, loadOrder, includeUses, skipLoaded) {
var item = loadOrder[index],
len, i, reqs, entry, stop, added, idx, ridx, url;
if (indexMap[index]) {
return indexMap;
}
indexMap[index] = true;
stop = false;
while (!stop) {
added = false;
for (idx in indexMap) {
if (indexMap.hasOwnProperty(idx)) {
item = loadOrder[idx];
if (!item) {
continue;
}
url = this.prepareUrl(item.path);
entry = Boot.getEntry(url);
if (!skipLoaded || !entry || !entry.done) {
reqs = item.requires;
if (includeUses && item.uses) {
reqs = reqs.concat(item.uses);
}
for (len = reqs.length, i = 0; i < len; i++) {
ridx = reqs[i];
if (!indexMap[ridx]) {
indexMap[ridx] = true;
added = true;
}
}
}
}
}
if (!added) {
stop = true;
}
}
return indexMap;
},
getPathsFromIndexes: function (indexMap, loadOrder) {
var indexes = [],
paths = [],
index, len, i;
for (index in indexMap) {
if (indexMap.hasOwnProperty(index) && indexMap[index]) {
indexes.push(index);
}
}
indexes.sort(function (a, b) {
return a - b;
});
for (len = indexes.length, i = 0; i < len; i++) {
paths.push(loadOrder[indexes[i]].path);
}
return paths;
},
expandUrl: function (url, indexMap, includeUses, skipLoaded) {
if (typeof url == 'string') {
url = [url];
}
var me = this,
loadOrder = me.loadOrder,
loadOrderMap = me.loadOrderMap;
if (loadOrder) {
loadOrderMap = loadOrderMap || me.createLoadOrderMap(loadOrder);
me.loadOrderMap = loadOrderMap;
indexMap = indexMap || {};
var len = url.length,
unmapped = [],
i, item;
for (i = 0; i < len; i++) {
item = loadOrderMap[url[i]];
if (item) {
me.getLoadIndexes(item.idx, indexMap, loadOrder, includeUses, skipLoaded);
} else {
unmapped.push(url[i]);
}
}
return me.getPathsFromIndexes(indexMap, loadOrder).concat(unmapped);
}
return url;
},
expandUrls: function (urls, includeUses) {
if (typeof urls == "string") {
urls = [urls];
}
var expanded = [],
expandMap = {},
tmpExpanded,
len = urls.length,
i, t, tlen, tUrl;
for (i = 0; i < len; i++) {
tmpExpanded = this.expandUrl(urls[i], {}, includeUses, true);
for (t = 0, tlen = tmpExpanded.length; t < tlen; t++) {
tUrl = tmpExpanded[t];
if (!expandMap[tUrl]) {
expandMap[tUrl] = true;
expanded.push(tUrl);
}
}
}
if (expanded.length == 0) {
expanded = urls;
}
return expanded;
},
expandLoadOrder: function () {
var me = this,
urls = me.urls,
expanded;
if (!me.expanded) {
expanded = this.expandUrls(urls, true);
me.expanded = true;
} else {
expanded = urls;
}
me.urls = expanded;
if (urls.length != expanded.length) {
me.sequential = true;
}
return me;
},
getUrls: function () {
this.expandLoadOrder();
return this.urls;
},
prepareUrl: function(url) {
if(this.prependBaseUrl) {
return Boot.baseUrl + url;
}
return url;
},
getEntries: function () {
var me = this,
entries = me.entries,
i, entry, urls, url;
if (!entries) {
entries = [];
urls = me.getUrls();
for (i = 0; i < urls.length; i++) {
url = me.prepareUrl(urls[i]);
entry = Boot.getEntry(url, {
buster: me.buster,
charset: me.charset
});
entry.requests.push(me);
entries.push(entry);
}
me.entries = entries;
}
return entries;
},
loadEntries: function(sync) {
var me = this,
entries = me.getEntries(),
len = entries.length,
start = me.loadStart || 0,
continueLoad, entry, i;
if(sync !== undefined) {
me.sync = sync;
}
me.loaded = me.loaded || 0;
me.loading = me.loading || len;
for(i = start; i < len; i++) {
entry = entries[i];
if(!entry.loaded) {
continueLoad = entries[i].load(me.sync);
} else {
continueLoad = true;
}
if(!continueLoad) {
me.loadStart = i;
entry.onDone(function(){
me.loadEntries(sync);
});
break;
}
}
me.processLoadedEntries();
},
processLoadedEntries: function () {
var me = this,
entries = me.getEntries(),
len = entries.length,
start = me.startIndex || 0,
i, entry;
if (!me.done) {
for (i = start; i < len; i++) {
entry = entries[i];
if (!entry.loaded) {
me.startIndex = i;
return;
}
if (!entry.evaluated) {
entry.evaluate();
}
if (entry.error) {
me.error = true;
}
}
me.notify();
}
},
notify: function () {
var me = this;
if (!me.done) {
var error = me.error,
fn = me[error ? 'failure' : 'success'],
delay = ('delay' in me)
? me.delay
: (error ? 1 : Boot.config.chainDelay),
scope = me.scope || me;
me.done = true;
if (fn) {
if (delay === 0 || delay > 0) {
setTimeout(function () {
fn.call(scope, me);
}, delay);
} else {
fn.call(scope, me);
}
}
me.fireListeners();
Boot.requestComplete(me);
}
},
onDone: function(listener) {
var me = this,
listeners = me.listeners || (me.listeners = []);
if(me.done) {
listener(me);
} else {
listeners.push(listener);
}
},
fireListeners: function() {
var listeners = this.listeners,
listener;
if(listeners) {
_debug("firing request listeners");
while((listener = listeners.shift())) {
listener(this);
}
}
}
};
function Entry(cfg) {
if(cfg.$isEntry) {
return cfg;
}
_debug("creating entry for " + cfg.url);
var charset = cfg.charset || Boot.config.charset,
manifest = Ext.manifest,
loader = manifest && manifest.loader,
cache = (cfg.cache !== undefined) ? cfg.cache : (loader && loader.cache),
buster, busterParam;
if(cache === undefined) {
cache = !Boot.config.disableCaching;
}
if(cache === false) {
buster = +new Date();
} else if(cache !== true) {
buster = cache;
}
if(buster) {
busterParam = (loader && loader.cacheParam) || Boot.config.disableCachingParam;
buster = busterParam + "=" + buster;
};
_apply(cfg, {
charset: charset,
buster: buster,
requests: []
});
_apply(this, cfg);
};
Entry.prototype = {
$isEntry: true,
done: false,
evaluated: false,
loaded: false,
isCrossDomain: function() {
var me = this;
if(me.crossDomain === undefined) {
_debug("checking " + me.getLoadUrl() + " for prefix " + Boot.origin);
me.crossDomain = (me.getLoadUrl().indexOf(Boot.origin) !== 0);
}
return me.crossDomain;
},
isCss: function () {
var me = this;
if (me.css === undefined) {
me.css = me.url && cssRe.test(me.url);
}
return this.css;
},
getElement: function (tag) {
var me = this,
el = me.el;
if (!el) {
_debug("creating element for " + me.url);
if (me.isCss()) {
tag = tag || "link";
el = doc.createElement(tag);
if(tag == "link") {
el.rel = 'stylesheet';
me.prop = 'href';
} else {
me.prop="textContent";
}
el.type = "text/css";
} else {
tag = tag || "script";
el = doc.createElement(tag);
el.type = 'text/javascript';
me.prop = 'src';
if (Boot.hasAsync) {
el.async = false;
}
}
me.el = el;
}
return el;
},
getLoadUrl: function () {
var me = this,
url = Boot.canonicalUrl(me.url);
if (!me.loadUrl) {
me.loadUrl = !!me.buster
? (url + (url.indexOf('?') === -1 ? '?' : '&') + me.buster)
: url;
}
return me.loadUrl;
},
fetch: function (req) {
var url = this.getLoadUrl(),
async = !!req.async,
complete = req.complete;
Boot.fetch(url, complete, this, async);
},
onContentLoaded: function (response) {
var me = this,
status = response.status,
content = response.content,
exception = response.exception,
url = this.getLoadUrl();
me.loaded = true;
if ((exception || status === 0) && !_environment.phantom) {
me.error =
("Failed loading synchronously via XHR: '" + url +
"'. It's likely that the file is either being loaded from a " +
"different domain or from the local file system where cross " +
"origin requests are not allowed for security reasons. Try " +
"asynchronous loading instead.") ||
true;
me.evaluated = true;
}
else if ((status >= 200 && status < 300) || status === 304
|| _environment.phantom
|| (status === 0 && content.length > 0)
) {
me.content = content;
}
else {
me.error =
("Failed loading synchronously via XHR: '" + url +
"'. Please verify that the file exists. XHR status code: " +
status) ||
true;
me.evaluated = true;
}
},
createLoadElement: function(callback) {
var me = this,
el = me.getElement(),
readyStateChange = function(){
if (this.readyState === 'loaded' || this.readyState === 'complete') {
if(callback) {
callback();
}
}
},
errorFn = function() {
me.error = true;
if(callback) {
callback();
}
};
me.preserve = true;
el.onerror = errorFn;
if(Boot.hasReadyState) {
el.onreadystatechange = readyStateChange;
} else {
el.onload = callback;
}
el[me.prop] = me.getLoadUrl();
},
onLoadElementReady: function() {
Boot.getHead().appendChild(this.getElement());
this.evaluated = true;
},
inject: function (content, asset) {
_debug("injecting content for " + this.url);
var me = this,
head = Boot.getHead(),
url = me.url,
key = me.key,
base, el, ieMode, basePath;
if (me.isCss()) {
me.preserve = true;
basePath = key.substring(0, key.lastIndexOf("/") + 1);
base = doc.createElement('base');
base.href = basePath;
if(head.firstChild) {
head.insertBefore(base, head.firstChild);
} else {
head.appendChild(base);
}
base.href = base.href;
if (url) {
content += "\n/*# sourceURL=" + key + " */";
}
el = me.getElement("style");
ieMode = ('styleSheet' in el);
head.appendChild(base);
if(ieMode) {
head.appendChild(el);
el.styleSheet.cssText = content;
} else {
el.textContent = content;
head.appendChild(el);
}
head.removeChild(base);
} else {
if (url) {
content += "\n//# sourceURL=" + key;
}
Ext.globalEval(content);
}
return me;
},
loadCrossDomain: function() {
var me = this,
complete = function(){
me.loaded = me.evaluated = me.done = true;
me.notifyRequests();
};
if(me.isCss()) {
me.createLoadElement();
me.evaluateLoadElement();
complete();
} else {
me.createLoadElement(function(){
complete();
});
me.evaluateLoadElement();
return false;
}
return true;
},
loadElement: function() {
var me = this,
complete = function(){
me.loaded = me.evaluated = me.done = true;
me.notifyRequests();
};
if(me.isCss()) {
return me.loadCrossDomain();
} else {
me.createLoadElement(function(){
complete();
});
me.evaluateLoadElement();
}
return true;
},
loadSync: function() {
var me = this;
me.fetch({
async: false,
complete: function (response) {
me.onContentLoaded(response);
}
});
me.evaluate();
me.notifyRequests();
},
load: function (sync) {
var me = this;
if (!me.loaded) {
if(me.loading) {
return false;
}
me.loading = true;
if (!sync) {
if(me.isCrossDomain()) {
return me.loadCrossDomain();
}
else if(!me.isCss() && Boot.hasReadyState) {
me.createLoadElement(function () {
me.loaded = true;
me.notifyRequests();
});
}
else if(Boot.useElements) {
return me.loadElement();
}
else {
me.fetch({
async: !sync,
complete: function (response) {
me.onContentLoaded(response);
me.notifyRequests();
}
});
}
}
else {
me.loadSync();
}
}
return true;
},
evaluateContent: function () {
this.inject(this.content);
this.content = null;
},
evaluateLoadElement: function() {
Boot.getHead().appendChild(this.getElement());
},
evaluate: function () {
var me = this;
if(!me.evaluated) {
if(me.evaluating) {
return;
}
me.evaluating = true;
if(me.content !== undefined) {
me.evaluateContent();
} else if(!me.error) {
me.evaluateLoadElement();
}
me.evaluated = me.done = true;
me.cleanup();
}
},
cleanup: function () {
var me = this,
el = me.el,
prop;
if (!el) {
return;
}
if (!me.preserve) {
me.el = null;
el.parentNode.removeChild(el);
for (prop in el) {
try {
if (prop !== me.prop) {
el[prop] = null;
}
delete el[prop];
} catch (cleanEx) {
}
}
}
el.onload = el.onerror = el.onreadystatechange = emptyFn;
},
notifyRequests: function () {
var requests = this.requests,
len = requests.length,
i, request;
for (i = 0; i < len; i++) {
request = requests[i];
request.processLoadedEntries();
}
if(this.done) {
this.fireListeners();
}
},
onDone: function(listener) {
var me = this,
listeners = me.listeners || (me.listeners = []);
if(me.done) {
listener(me);
} else {
listeners.push(listener);
}
},
fireListeners: function() {
var listeners = this.listeners,
listener;
if(listeners && listeners.length > 0) {
_debug("firing event listeners for url " + this.url);
while((listener = listeners.shift())) {
listener(this);
}
}
}
};
Ext.disableCacheBuster = function (disable, path) {
var date = new Date();
date.setTime(date.getTime() + (disable ? 10 * 365 : -1) * 24 * 60 * 60 * 1000);
date = date.toGMTString();
doc.cookie = 'ext-cache=1; expires=' + date + '; path=' + (path || '/');
};
if (_environment.node) {
Boot.prototype.load = Boot.prototype.loadSync = function (request) {
require(filePath);
onLoad.call(scope);
};
Boot.prototype.init = emptyFn;
}
Boot.init();
return Boot;
}(function () {
}));
Ext.globalEval = Ext.globalEval || (this.execScript
? function (code) { execScript(code); }
: function ($$code) { eval.call(window, $$code); });
if (!Function.prototype.bind) {
(function () {
var slice = Array.prototype.slice,
bind = function (me) {
var args = slice.call(arguments, 1),
method = this;
if (args.length) {
return function () {
var t = arguments;
return method.apply(me, t.length ? args.concat(slice.call(t)) : args);
};
}
args = null;
return function () {
return method.apply(me, arguments);
};
};
Function.prototype.bind = bind;
bind.$extjs = true;
}());
}
var Ext = Ext || {};
Ext._startTime = Date.now ? Date.now() : (+new Date());
(function() {
var global = this,
objectPrototype = Object.prototype,
toString = objectPrototype.toString,
enumerables = [
'valueOf',
'toLocaleString',
'toString',
'constructor'
],
emptyFn = function() {},
privateFn = function() {},
identityFn = function(o) {
return o;
},
callOverrideParent = function() {
var method = callOverrideParent.caller.caller;
return method.$owner.prototype[method.$name].apply(this, arguments);
},
manifest = Ext.manifest || {},
i,
iterableRe = /\[object\s*(?:Array|Arguments|\w*Collection|\w*List|HTML\s+document\.all\s+class)\]/,
MSDateRe = /^\\?\/Date\(([-+])?(\d+)(?:[+-]\d{4})?\)\\?\/$/;
Ext.global = global;
emptyFn.$nullFn = identityFn.$nullFn = emptyFn.$emptyFn = identityFn.$identityFn = privateFn.$nullFn = true;
privateFn.$privacy = 'framework';
Ext['suspendLayouts'] = Ext['resumeLayouts'] = emptyFn;
for (i in {
toString: 1
}) {
enumerables = null;
}
Ext.enumerables = enumerables;
Ext.apply = function(object, config, defaults) {
if (defaults) {
Ext.apply(object, defaults);
}
if (object && config && typeof config === 'object') {
var i, j, k;
for (i in config) {
object[i] = config[i];
}
if (enumerables) {
for (j = enumerables.length; j--; ) {
k = enumerables[j];
if (config.hasOwnProperty(k)) {
object[k] = config[k];
}
}
}
}
return object;
};
Ext.buildSettings = Ext.apply({
baseCSSPrefix: 'x-'
}, Ext.buildSettings || {});
Ext.apply(Ext, {
idSeed: 0,
idPrefix: 'ext-',
isSecure: /^https/i.test(window.location.protocol),
enableGarbageCollector: false,
enableListenerCollection: true,
name: Ext.sandboxName || 'Ext',
privateFn: privateFn,
emptyFn: emptyFn,
identityFn: identityFn,
frameStartTime: +new Date(),
manifest: manifest,
debugConfig: Ext.debugConfig || manifest.debug || {
hooks: {
'*': true
}
},
validIdRe: /^[a-z_][a-z0-9\-_]*$/i,
BLANK_IMAGE_URL: 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
makeIdSelector: function(id) {
if (!Ext.validIdRe.test(id)) {
Ext.Error.raise('Invalid id selector: "' + id + '"');
}
return '#' + id;
},
id: function(o, prefix) {
if (o && o.id) {
return o.id;
}
var id = (prefix || Ext.idPrefix) + (++Ext.idSeed);
if (o) {
o.id = id;
}
return id;
},
returnId: function(o) {
return o.getId();
},
returnTrue: function() {
return true;
},
emptyString: new String(),
baseCSSPrefix: Ext.buildSettings.baseCSSPrefix,
$eventNameMap: {},
$vendorEventRe: /^(Moz.+|MS.+|webkit.+)/,
canonicalEventName: function(name) {
return Ext.$eventNameMap[name] || (Ext.$eventNameMap[name] = (Ext.$vendorEventRe.test(name) ? name : name.toLowerCase()));
},
applyIf: function(object, config) {
var property;
if (object) {
for (property in config) {
if (object[property] === undefined) {
object[property] = config[property];
}
}
}
return object;
},
now: (global.performance && global.performance.now) ? function() {
return performance.now();
} :
(Date.now || (Date.now = function() {
return +new Date();
})),
destroy: function() {
var ln = arguments.length,
i, arg;
for (i = 0; i < ln; i++) {
arg = arguments[i];
if (arg) {
if (Ext.isArray(arg)) {
this.destroy.apply(this, arg);
} else if (Ext.isFunction(arg.destroy)) {
arg.destroy();
}
}
}
return null;
},
destroyMembers: function(object) {
for (var ref, name,
i = 1,
a = arguments,
len = a.length; i < len; i++) {
ref = object[name = a[i]];
if (ref != null) {
object[name] = Ext.destroy(ref);
}
}
},
override: function(target, overrides) {
if (target.$isClass) {
target.override(overrides);
} else if (typeof target === 'function') {
Ext.apply(target.prototype, overrides);
} else {
var owner = target.self,
name, value;
if (owner && owner.$isClass) {
for (name in overrides) {
if (overrides.hasOwnProperty(name)) {
value = overrides[name];
if (typeof value === 'function') {
if (owner.$className) {
value.name = owner.$className + '#' + name;
}
value.$name = name;
value.$owner = owner;
value.$previous = target.hasOwnProperty(name) ? target[name] :
callOverrideParent;
}
target[name] = value;
}
}
} else {
Ext.apply(target, overrides);
}
}
return target;
},
valueFrom: function(value, defaultValue, allowBlank) {
return Ext.isEmpty(value, allowBlank) ? defaultValue : value;
},
isEmpty: function(value, allowEmptyString) {
return (value == null) || (!allowEmptyString ? value === '' : false) || (Ext.isArray(value) && value.length === 0);
},
isArray: ('isArray' in Array) ? Array.isArray : function(value) {
return toString.call(value) === '[object Array]';
},
isDate: function(value) {
return toString.call(value) === '[object Date]';
},
isMSDate: function(value) {
if (!Ext.isString(value)) {
return false;
}
return MSDateRe.test(value);
},
isObject: (toString.call(null) === '[object Object]') ? function(value) {
return value !== null && value !== undefined && toString.call(value) === '[object Object]' && value.ownerDocument === undefined;
} : function(value) {
return toString.call(value) === '[object Object]';
},
isSimpleObject: function(value) {
return value instanceof Object && value.constructor === Object;
},
isPrimitive: function(value) {
var type = typeof value;
return type === 'string' || type === 'number' || type === 'boolean';
},
isFunction:
(typeof document !== 'undefined' && typeof document.getElementsByTagName('body') === 'function') ? function(value) {
return !!value && toString.call(value) === '[object Function]';
} : function(value) {
return !!value && typeof value === 'function';
},
isNumber: function(value) {
return typeof value === 'number' && isFinite(value);
},
isNumeric: function(value) {
return !isNaN(parseFloat(value)) && isFinite(value);
},
isString: function(value) {
return typeof value === 'string';
},
isBoolean: function(value) {
return typeof value === 'boolean';
},
isElement: function(value) {
return value ? value.nodeType === 1 : false;
},
isTextNode: function(value) {
return value ? value.nodeName === "#text" : false;
},
isDefined: function(value) {
return typeof value !== 'undefined';
},
isIterable: function(value) {
if (!value || typeof value.length !== 'number' || typeof value === 'string' || Ext.isFunction(value)) {
return false;
}
if (!value.propertyIsEnumerable) {
return !!value.item;
}
if (value.hasOwnProperty('length') && !value.propertyIsEnumerable('length')) {
return true;
}
return iterableRe.test(toString.call(value));
},
isDebugEnabled: function(className, defaultEnabled) {
var debugConfig = Ext.debugConfig.hooks;
if (debugConfig.hasOwnProperty(className)) {
return debugConfig[className];
}
var enabled = debugConfig['*'],
prefixLength = 0;
if (defaultEnabled !== undefined) {
enabled = defaultEnabled;
}
if (!className) {
return enabled;
}
for (var prefix in debugConfig) {
var value = debugConfig[prefix];
if (className.charAt(prefix.length) === '.') {
if (className.substring(0, prefix.length) === prefix) {
if (prefixLength < prefix.length) {
prefixLength = prefix.length;
enabled = value;
}
}
}
}
return enabled;
} || emptyFn,
clone: function(item) {
if (item === null || item === undefined) {
return item;
}
if (item.nodeType && item.cloneNode) {
return item.cloneNode(true);
}
var type = toString.call(item),
i, j, k, clone, key;
if (type === '[object Date]') {
return new Date(item.getTime());
}
if (type === '[object Array]') {
i = item.length;
clone = [];
while (i--) {
clone[i] = Ext.clone(item[i]);
}
}
else if (type === '[object Object]' && item.constructor === Object) {
clone = {};
for (key in item) {
clone[key] = Ext.clone(item[key]);
}
if (enumerables) {
for (j = enumerables.length; j--; ) {
k = enumerables[j];
if (item.hasOwnProperty(k)) {
clone[k] = item[k];
}
}
}
}
return clone || item;
},
getUniqueGlobalNamespace: function() {
var uniqueGlobalNamespace = this.uniqueGlobalNamespace,
i;
if (uniqueGlobalNamespace === undefined) {
i = 0;
do {
uniqueGlobalNamespace = 'ExtBox' + (++i);
} while (global[uniqueGlobalNamespace] !== undefined);
global[uniqueGlobalNamespace] = Ext;
this.uniqueGlobalNamespace = uniqueGlobalNamespace;
}
return uniqueGlobalNamespace;
},
functionFactoryCache: {},
cacheableFunctionFactory: function() {
var me = this,
args = Array.prototype.slice.call(arguments),
cache = me.functionFactoryCache,
idx, fn, ln;
if (Ext.isSandboxed) {
ln = args.length;
if (ln > 0) {
ln--;
args[ln] = 'var Ext=window.' + Ext.name + ';' + args[ln];
}
}
idx = args.join('');
fn = cache[idx];
if (!fn) {
fn = Function.prototype.constructor.apply(Function.prototype, args);
cache[idx] = fn;
}
return fn;
},
functionFactory: function() {
var args = Array.prototype.slice.call(arguments),
ln;
if (Ext.isSandboxed) {
ln = args.length;
if (ln > 0) {
ln--;
args[ln] = 'var Ext=window.' + Ext.name + ';' + args[ln];
}
}
return Function.prototype.constructor.apply(Function.prototype, args);
},
Logger: {
log: function(message, priority) {
if (message && global.console) {
if (!priority || !(priority in global.console)) {
priority = 'log';
}
message = '[' + priority.toUpperCase() + '] ' + message;
global.console[priority](message);
}
},
verbose: function(message) {
this.log(message, 'verbose');
},
info: function(message) {
this.log(message, 'info');
},
warn: function(message) {
this.log(message, 'warn');
},
error: function(message) {
throw new Error(message);
},
deprecate: function(message) {
this.log(message, 'warn');
}
} || {
verbose: emptyFn,
log: emptyFn,
info: emptyFn,
warn: emptyFn,
error: function(message) {
throw new Error(message);
},
deprecate: emptyFn
},
getElementById: function(id) {
return document.getElementById(id);
},
splitAndUnescape: (function() {
var cache = {};
return function(origin, delimiter) {
if (!origin) {
return [];
} else if (!delimiter) {
return [
origin
];
}
var replaceRe = cache[delimiter] || (cache[delimiter] = new RegExp('\\\\' + delimiter, 'g')),
result = [],
parts, part;
parts = origin.split(delimiter);
while ((part = parts.shift()) !== undefined) {
while (part.charAt(part.length - 1) === '\\' && parts.length > 0) {
part = part + delimiter + parts.shift();
}
part = part.replace(replaceRe, delimiter);
result.push(part);
}
return result;
};
})()
});
Ext.returnTrue.$nullFn = Ext.returnId.$nullFn = true;
}());
(function() {
function toString() {
var me = this,
cls = me.sourceClass,
method = me.sourceMethod,
msg = me.msg;
if (method) {
if (msg) {
method += '(): ';
method += msg;
} else {
method += '()';
}
}
if (cls) {
method = method ? (cls + '.' + method) : cls;
}
return method || msg || '';
}
Ext.Error = function(config) {
if (Ext.isString(config)) {
config = {
msg: config
};
}
var error = new Error();
Ext.apply(error, config);
error.message = error.message || error.msg;
error.toString = toString;
return error;
};
Ext.apply(Ext.Error, {
ignore: false,
raise: function(err) {
err = err || {};
if (Ext.isString(err)) {
err = {
msg: err
};
}
var me = this,
method = me.raise.caller,
msg, name;
if (method) {
if (!err.sourceMethod && (name = method.$name)) {
err.sourceMethod = name;
}
if (!err.sourceClass && (name = method.$owner) && (name = name.$className)) {
err.sourceClass = name;
}
}
if (me.handle(err) !== true) {
msg = toString.call(err);
Ext.log({
msg: msg,
level: 'error',
dump: err,
stack: true
});
throw new Ext.Error(err);
}
},
handle: function() {
return this.ignore;
}
});
})();
Ext.deprecated = function(suggestion) {
if (!suggestion) {
suggestion = '';
}
function fail() {
Ext.Error.raise('The method "' + fail.$owner.$className + '.' + fail.$name + '" has been removed. ' + suggestion);
}
return fail;
return Ext.emptyFn;
};
(function() {
if (typeof window === 'undefined') {
return;
}
var last = 0,
notify = function() {
var cnt = Ext.log && Ext.log.counters,
n = cnt && (cnt.error + cnt.warn + cnt.info + cnt.log),
msg;
if (n && last !== n) {
msg = [];
if (cnt.error) {
msg.push('Errors: ' + cnt.error);
}
if (cnt.warn) {
msg.push('Warnings: ' + cnt.warn);
}
if (cnt.info) {
msg.push('Info: ' + cnt.info);
}
if (cnt.log) {
msg.push('Log: ' + cnt.log);
}
window.status = '*** ' + msg.join(' -- ');
last = n;
}
};
setInterval(notify, 1000);
}());
Ext.Array = (function() {
var arrayPrototype = Array.prototype,
slice = arrayPrototype.slice,
supportsSplice = (function() {
var array = [],
lengthBefore,
j = 20;
if (!array.splice) {
return false;
}
while (j--) {
array.push("A");
}
array.splice(15, 0, "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F");
lengthBefore = array.length;
array.splice(13, 0, "XXX");
if (lengthBefore + 1 !== array.length) {
return false;
}
return true;
}()),
supportsIndexOf = 'indexOf' in arrayPrototype,
supportsSliceOnNodeList = true;
function stableSort(array, userComparator) {
var len = array.length,
indices = new Array(len),
i;
for (i = 0; i < len; i++) {
indices[i] = i;
}
indices.sort(function(index1, index2) {
return userComparator(array[index1], array[index2]) || (index1 - index2);
});
for (i = 0; i < len; i++) {
indices[i] = array[indices[i]];
}
for (i = 0; i < len; i++) {
array[i] = indices[i];
}
return array;
}
try {
if (typeof document !== 'undefined') {
slice.call(document.getElementsByTagName('body'));
}
} catch (e) {
supportsSliceOnNodeList = false;
}
var fixArrayIndex = function(array, index) {
return (index < 0) ? Math.max(0, array.length + index) : Math.min(array.length, index);
},
replaceSim = function(array, index, removeCount, insert) {
var add = insert ? insert.length : 0,
length = array.length,
pos = fixArrayIndex(array, index);
if (pos === length) {
if (add) {
array.push.apply(array, insert);
}
} else {
var remove = Math.min(removeCount, length - pos),
tailOldPos = pos + remove,
tailNewPos = tailOldPos + add - remove,
tailCount = length - tailOldPos,
lengthAfterRemove = length - remove,
i;
if (tailNewPos < tailOldPos) {
for (i = 0; i < tailCount; ++i) {
array[tailNewPos + i] = array[tailOldPos + i];
}
} else if (tailNewPos > tailOldPos) {
for (i = tailCount; i--; ) {
array[tailNewPos + i] = array[tailOldPos + i];
}
}
if (add && pos === lengthAfterRemove) {
array.length = lengthAfterRemove;
array.push.apply(array, insert);
} else {
array.length = lengthAfterRemove + add;
for (i = 0; i < add; ++i) {
array[pos + i] = insert[i];
}
}
}
return array;
},
replaceNative = function(array, index, removeCount, insert) {
if (insert && insert.length) {
if (index === 0 && !removeCount) {
array.unshift.apply(array, insert);
}
else if (index < array.length) {
array.splice.apply(array, [
index,
removeCount
].concat(insert));
} else
{
array.push.apply(array, insert);
}
} else {
array.splice(index, removeCount);
}
return array;
},
eraseSim = function(array, index, removeCount) {
return replaceSim(array, index, removeCount);
},
eraseNative = function(array, index, removeCount) {
array.splice(index, removeCount);
return array;
},
spliceSim = function(array, index, removeCount) {
var pos = fixArrayIndex(array, index),
removed = array.slice(index, fixArrayIndex(array, pos + removeCount));
if (arguments.length < 4) {
replaceSim(array, pos, removeCount);
} else {
replaceSim(array, pos, removeCount, slice.call(arguments, 3));
}
return removed;
},
spliceNative = function(array) {
return array.splice.apply(array, slice.call(arguments, 1));
},
erase = supportsSplice ? eraseNative : eraseSim,
replace = supportsSplice ? replaceNative : replaceSim,
splice = supportsSplice ? spliceNative : spliceSim,
ExtArray = {
binarySearch: function(array, item, begin, end, compareFn) {
var length = array.length,
middle, comparison;
if (begin instanceof Function) {
compareFn = begin;
begin = 0;
end = length;
} else if (end instanceof Function) {
compareFn = end;
end = length;
} else {
if (begin === undefined) {
begin = 0;
}
if (end === undefined) {
end = length;
}
compareFn = compareFn || ExtArray.lexicalCompare;
}
--end;
while (begin <= end) {
middle = (begin + end) >> 1;
comparison = compareFn(item, array[middle]);
if (comparison >= 0) {
begin = middle + 1;
} else if (comparison < 0) {
end = middle - 1;
}
}
return begin;
},
defaultCompare: function(lhs, rhs) {
return (lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0);
},
lexicalCompare: function(lhs, rhs) {
lhs = String(lhs);
rhs = String(rhs);
return (lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0);
},
each: function(array, fn, scope, reverse) {
array = ExtArray.from(array);
var i,
ln = array.length;
if (reverse !== true) {
for (i = 0; i < ln; i++) {
if (fn.call(scope || array[i], array[i], i, array) === false) {
return i;
}
}
} else {
for (i = ln - 1; i > -1; i--) {
if (fn.call(scope || array[i], array[i], i, array) === false) {
return i;
}
}
}
return true;
},
forEach: ('forEach' in arrayPrototype) ? function(array, fn, scope) {
return array.forEach(fn, scope);
} : function(array, fn, scope) {
for (var i = 0,
ln = array.length; i < ln; i++) {
fn.call(scope, array[i], i, array);
}
},
indexOf: supportsIndexOf ? function(array, item, from) {
return arrayPrototype.indexOf.call(array, item, from);
} : function(array, item, from) {
var i,
length = array.length;
for (i = (from < 0) ? Math.max(0, length + from) : from || 0; i < length; i++) {
if (array[i] === item) {
return i;
}
}
return -1;
},
contains: supportsIndexOf ? function(array, item) {
return arrayPrototype.indexOf.call(array, item) !== -1;
} : function(array, item) {
var i, ln;
for (i = 0 , ln = array.length; i < ln; i++) {
if (array[i] === item) {
return true;
}
}
return false;
},
toArray: function(iterable, start, end) {
if (!iterable || !iterable.length) {
return [];
}
if (typeof iterable === 'string') {
iterable = iterable.split('');
}
if (supportsSliceOnNodeList) {
return slice.call(iterable, start || 0, end || iterable.length);
}
var array = [],
i;
start = start || 0;
end = end ? ((end < 0) ? iterable.length + end : end) : iterable.length;
for (i = start; i < end; i++) {
array.push(iterable[i]);
}
return array;
},
pluck: function(array, propertyName) {
var ret = [],
i, ln, item;
for (i = 0 , ln = array.length; i < ln; i++) {
item = array[i];
ret.push(item[propertyName]);
}
return ret;
},
map: ('map' in arrayPrototype) ? function(array, fn, scope) {
Ext.Assert.isFunction(fn, 'Ext.Array.map must have a callback function passed as second argument.');
return array.map(fn, scope);
} : function(array, fn, scope) {
Ext.Assert.isFunction(fn, 'Ext.Array.map must have a callback function passed as second argument.');
var results = [],
i = 0,
len = array.length;
for (; i < len; i++) {
results[i] = fn.call(scope, array[i], i, array);
}
return results;
},
every: ('every' in arrayPrototype) ? function(array, fn, scope) {
Ext.Assert.isFunction(fn, 'Ext.Array.every must have a callback function passed as second argument.');
return array.every(fn, scope);
} : function(array, fn, scope) {
Ext.Assert.isFunction(fn, 'Ext.Array.every must have a callback function passed as second argument.');
var i = 0,
ln = array.length;
for (; i < ln; ++i) {
if (!fn.call(scope, array[i], i, array)) {
return false;
}
}
return true;
},
some: ('some' in arrayPrototype) ? function(array, fn, scope) {
Ext.Assert.isFunction(fn, 'Ext.Array.some must have a callback function passed as second argument.');
return array.some(fn, scope);
} : function(array, fn, scope) {
Ext.Assert.isFunction(fn, 'Ext.Array.some must have a callback function passed as second argument.');
var i = 0,
ln = array.length;
for (; i < ln; ++i) {
if (fn.call(scope, array[i], i, array)) {
return true;
}
}
return false;
},
equals: function(array1, array2) {
var len1 = array1.length,
len2 = array2.length,
i;
if (array1 === array2) {
return true;
}
if (len1 !== len2) {
return false;
}
for (i = 0; i < len1; ++i) {
if (array1[i] !== array2[i]) {
return false;
}
}
return true;
},
clean: function(array) {
var results = [],
i = 0,
ln = array.length,
item;
for (; i < ln; i++) {
item = array[i];
if (!Ext.isEmpty(item)) {
results.push(item);
}
}
return results;
},
unique: function(array) {
var clone = [],
i = 0,
ln = array.length,
item;
for (; i < ln; i++) {
item = array[i];
if (ExtArray.indexOf(clone, item) === -1) {
clone.push(item);
}
}
return clone;
},
filter: ('filter' in arrayPrototype) ? function(array, fn, scope) {
Ext.Assert.isFunction(fn, 'Ext.Array.filter must have a filter function passed as second argument.');
return array.filter(fn, scope);
} : function(array, fn, scope) {
Ext.Assert.isFunction(fn, 'Ext.Array.filter must have a filter function passed as second argument.');
var results = [],
i = 0,
ln = array.length;
for (; i < ln; i++) {
if (fn.call(scope, array[i], i, array)) {
results.push(array[i]);
}
}
return results;
},
findBy: function(array, fn, scope) {
var i = 0,
len = array.length;
for (; i < len; i++) {
if (fn.call(scope || array, array[i], i)) {
return array[i];
}
}
return null;
},
from: function(value, newReference) {
if (value === undefined || value === null) {
return [];
}
if (Ext.isArray(value)) {
return (newReference) ? slice.call(value) : value;
}
var type = typeof value;
if (value && value.length !== undefined && type !== 'string' && (type !== 'function' || !value.apply)) {
return ExtArray.toArray(value);
}
return [
value
];
},
remove: function(array, item) {
var index = ExtArray.indexOf(array, item);
if (index !== -1) {
erase(array, index, 1);
}
return array;
},
removeAt: function(array, index, count) {
var len = array.length;
if (index >= 0 && index < len) {
count = count || 1;
count = Math.min(count, len - index);
erase(array, index, count);
}
return array;
},
include: function(array, item) {
if (!ExtArray.contains(array, item)) {
array.push(item);
}
},
clone: function(array) {
return slice.call(array);
},
merge: function() {
var args = slice.call(arguments),
array = [],
i, ln;
for (i = 0 , ln = args.length; i < ln; i++) {
array = array.concat(args[i]);
}
return ExtArray.unique(array);
},
intersect: function() {
var intersection = [],
arrays = slice.call(arguments),
arraysLength, array, arrayLength, minArray, minArrayIndex, minArrayCandidate, minArrayLength, element, elementCandidate, elementCount, i, j, k;
if (!arrays.length) {
return intersection;
}
arraysLength = arrays.length;
for (i = minArrayIndex = 0; i < arraysLength; i++) {
minArrayCandidate = arrays[i];
if (!minArray || minArrayCandidate.length < minArray.length) {
minArray = minArrayCandidate;
minArrayIndex = i;
}
}
minArray = ExtArray.unique(minArray);
erase(arrays, minArrayIndex, 1);
minArrayLength = minArray.length;
arraysLength = arrays.length;
for (i = 0; i < minArrayLength; i++) {
element = minArray[i];
elementCount = 0;
for (j = 0; j < arraysLength; j++) {
array = arrays[j];
arrayLength = array.length;
for (k = 0; k < arrayLength; k++) {
elementCandidate = array[k];
if (element === elementCandidate) {
elementCount++;
break;
}
}
}
if (elementCount === arraysLength) {
intersection.push(element);
}
}
return intersection;
},
difference: function(arrayA, arrayB) {
var clone = slice.call(arrayA),
ln = clone.length,
i, j, lnB;
for (i = 0 , lnB = arrayB.length; i < lnB; i++) {
for (j = 0; j < ln; j++) {
if (clone[j] === arrayB[i]) {
erase(clone, j, 1);
j--;
ln--;
}
}
}
return clone;
},
slice: ([
1,
2
].slice(1, undefined).length ? function(array, begin, end) {
return slice.call(array, begin, end);
} : function(array, begin, end) {
if (typeof begin === 'undefined') {
return slice.call(array);
}
if (typeof end === 'undefined') {
return slice.call(array, begin);
}
return slice.call(array, begin, end);
}),
sort: function(array, sortFn) {
return stableSort(array, sortFn || ExtArray.lexicalCompare);
},
flatten: function(array) {
var worker = [];
function rFlatten(a) {
var i, ln, v;
for (i = 0 , ln = a.length; i < ln; i++) {
v = a[i];
if (Ext.isArray(v)) {
rFlatten(v);
} else {
worker.push(v);
}
}
return worker;
}
return rFlatten(array);
},
min: function(array, comparisonFn) {
var min = array[0],
i, ln, item;
for (i = 0 , ln = array.length; i < ln; i++) {
item = array[i];
if (comparisonFn) {
if (comparisonFn(min, item) === 1) {
min = item;
}
} else {
if (item < min) {
min = item;
}
}
}
return min;
},
max: function(array, comparisonFn) {
var max = array[0],
i, ln, item;
for (i = 0 , ln = array.length; i < ln; i++) {
item = array[i];
if (comparisonFn) {
if (comparisonFn(max, item) === -1) {
max = item;
}
} else {
if (item > max) {
max = item;
}
}
}
return max;
},
mean: function(array) {
return array.length > 0 ? ExtArray.sum(array) / array.length : undefined;
},
sum: function(array) {
var sum = 0,
i, ln, item;
for (i = 0 , ln = array.length; i < ln; i++) {
item = array[i];
sum += item;
}
return sum;
},
toMap: function(array, getKey, scope) {
var map = {},
i = array.length;
if (!getKey) {
while (i--) {
map[array[i]] = i + 1;
}
} else if (typeof getKey === 'string') {
while (i--) {
map[array[i][getKey]] = i + 1;
}
} else {
while (i--) {
map[getKey.call(scope, array[i])] = i + 1;
}
}
return map;
},
toValueMap: function(array, getKey, scope, arrayify) {
var map = {},
i = array.length,
autoArray, alwaysArray, entry, fn, key, value;
if (!getKey) {
while (i--) {
value = array[i];
map[value] = value;
}
} else {
if (!(fn = (typeof getKey !== 'string'))) {
arrayify = scope;
}
alwaysArray = arrayify === 1;
autoArray = arrayify === 2;
while (i--) {
value = array[i];
key = fn ? getKey.call(scope, value) : value[getKey];
if (alwaysArray) {
if (key in map) {
map[key].push(value);
} else {
map[key] = [
value
];
}
} else if (autoArray && (key in map)) {
if ((entry = map[key]) instanceof Array) {
entry.push(value);
} else {
map[key] = [
entry,
value
];
}
} else {
map[key] = value;
}
}
}
return map;
},
_replaceSim: replaceSim,
_spliceSim: spliceSim,
erase: erase,
insert: function(array, index, items) {
return replace(array, index, 0, items);
},
replace: replace,
splice: splice,
push: function(target) {
var len = arguments.length,
i = 1,
newItem;
if (target === undefined) {
target = [];
} else if (!Ext.isArray(target)) {
target = [
target
];
}
for (; i < len; i++) {
newItem = arguments[i];
Array.prototype.push[Ext.isIterable(newItem) ? 'apply' : 'call'](target, newItem);
}
return target;
},
numericSortFn: function(a, b) {
return a - b;
}
};
Ext.each = ExtArray.each;
ExtArray.union = ExtArray.merge;
Ext.min = ExtArray.min;
Ext.max = ExtArray.max;
Ext.sum = ExtArray.sum;
Ext.mean = ExtArray.mean;
Ext.flatten = ExtArray.flatten;
Ext.clean = ExtArray.clean;
Ext.unique = ExtArray.unique;
Ext.pluck = ExtArray.pluck;
Ext.toArray = function() {
return ExtArray.toArray.apply(ExtArray, arguments);
};
return ExtArray;
}());
Ext.Assert = {
falsey: function(b, msg) {
if (b) {
Ext.Error.raise(msg || ('Expected a falsey value but was ' + b));
}
},
falseyProp: function(object, property) {
Ext.Assert.truthy(object);
var b = object[property];
if (b) {
if (object.$className) {
property = object.$className + '#' + property;
}
Ext.Error.raise('Expected a falsey value for ' + property + ' but was ' + b);
}
},
truthy: function(b, msg) {
if (!b) {
Ext.Error.raise(msg || ('Expected a truthy value but was ' + typeof b));
}
},
truthyProp: function(object, property) {
Ext.Assert.truthy(object);
var b = object[property];
if (!b) {
if (object.$className) {
property = object.$className + '#' + property;
}
Ext.Error.raise('Expected a truthy value for ' + property + ' but was ' + typeof b);
}
}
};
(function() {
function makeAssert(name, kind) {
var testFn = Ext[name],
def;
return function(value, msg) {
if (!testFn(value)) {
Ext.Error.raise(msg || def || (def = 'Expected value to be ' + kind));
}
};
}
function makeAssertProp(name, kind) {
var testFn = Ext[name],
def;
return function(object, prop) {
Ext.Assert.truthy(object);
if (!testFn(object[prop])) {
Ext.Error.raise(def || (def = 'Expected ' + (object.$className ? object.$className + '#' : '') + prop + ' to be ' + kind));
}
};
}
function makeNotAssert(name, kind) {
var testFn = Ext[name],
def;
return function(value, msg) {
if (testFn(value)) {
Ext.Error.raise(msg || def || (def = 'Expected value to NOT be ' + kind));
}
};
}
function makeNotAssertProp(name, kind) {
var testFn = Ext[name],
def;
return function(object, prop) {
Ext.Assert.truthy(object);
if (testFn(object[prop])) {
Ext.Error.raise(def || (def = 'Expected ' + (object.$className ? object.$className + '#' : '') + prop + ' to NOT be ' + kind));
}
};
}
for (var name in Ext) {
if (name.substring(0, 2) == "is" && Ext.isFunction(Ext[name])) {
var kind = name.substring(2);
Ext.Assert[name] = makeAssert(name, kind);
Ext.Assert[name + 'Prop'] = makeAssertProp(name, kind);
Ext.Assert['isNot' + kind] = makeNotAssert(name, kind);
Ext.Assert['isNot' + kind + 'Prop'] = makeNotAssertProp(name, kind);
}
}
}());
Ext.String = (function() {
var trimRegex = /^[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000]+|[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000]+$/g,
escapeRe = /('|\\)/g,
escapeRegexRe = /([-.*+?\^${}()|\[\]\/\\])/g,
basicTrimRe = /^\s+|\s+$/g,
whitespaceRe = /\s+/,
varReplace = /(^[^a-z]*|[^\w])/gi,
charToEntity, entityToChar, charToEntityRegex, entityToCharRegex,
htmlEncodeReplaceFn = function(match, capture) {
return charToEntity[capture];
},
htmlDecodeReplaceFn = function(match, capture) {
return (capture in entityToChar) ? entityToChar[capture] : String.fromCharCode(parseInt(capture.substr(2), 10));
},
boundsCheck = function(s, other) {
if (s === null || s === undefined || other === null || other === undefined) {
return false;
}
return other.length <= s.length;
},
ExtString;
return ExtString = {
insert: function(s, value, index) {
if (!s) {
return value;
}
if (!value) {
return s;
}
var len = s.length;
if (!index && index !== 0) {
index = len;
}
if (index < 0) {
index *= -1;
if (index >= len) {
index = 0;
} else {
index = len - index;
}
}
if (index === 0) {
s = value + s;
} else if (index >= s.length) {
s += value;
} else {
s = s.substr(0, index) + value + s.substr(index);
}
return s;
},
startsWith: function(s, start, ignoreCase) {
var result = boundsCheck(s, start);
if (result) {
if (ignoreCase) {
s = s.toLowerCase();
start = start.toLowerCase();
}
result = s.lastIndexOf(start, 0) === 0;
}
return result;
},
endsWith: function(s, end, ignoreCase) {
var result = boundsCheck(s, end);
if (result) {
if (ignoreCase) {
s = s.toLowerCase();
end = end.toLowerCase();
}
result = s.indexOf(end, s.length - end.length) !== -1;
}
return result;
},
createVarName: function(s) {
return s.replace(varReplace, '');
},
htmlEncode: function(value) {
return (!value) ? value : String(value).replace(charToEntityRegex, htmlEncodeReplaceFn);
},
htmlDecode: function(value) {
return (!value) ? value : String(value).replace(entityToCharRegex, htmlDecodeReplaceFn);
},
hasHtmlCharacters: function(s) {
return charToEntityRegex.test(s);
},
addCharacterEntities: function(newEntities) {
var charKeys = [],
entityKeys = [],
key, echar;
for (key in newEntities) {
echar = newEntities[key];
entityToChar[key] = echar;
charToEntity[echar] = key;
charKeys.push(echar);
entityKeys.push(key);
}
charToEntityRegex = new RegExp('(' + charKeys.join('|') + ')', 'g');
entityToCharRegex = new RegExp('(' + entityKeys.join('|') + '|&#[0-9]{1,5};' + ')', 'g');
},
resetCharacterEntities: function() {
charToEntity = {};
entityToChar = {};
this.addCharacterEntities({
'&amp;': '&',
'&gt;': '>',
'&lt;': '<',
'&quot;': '"',
'&#39;': "'"
});
},
urlAppend: function(url, string) {
if (!Ext.isEmpty(string)) {
return url + (url.indexOf('?') === -1 ? '?' : '&') + string;
}
return url;
},
trim: function(string) {
if (string) {
string = string.replace(trimRegex, "");
}
return string || '';
},
capitalize: function(string) {
if (string) {
string = string.charAt(0).toUpperCase() + string.substr(1);
}
return string || '';
},
uncapitalize: function(string) {
if (string) {
string = string.charAt(0).toLowerCase() + string.substr(1);
}
return string || '';
},
ellipsis: function(value, length, word) {
if (value && value.length > length) {
if (word) {
var vs = value.substr(0, length - 2),
index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));
if (index !== -1 && index >= (length - 15)) {
return vs.substr(0, index) + "...";
}
}
return value.substr(0, length - 3) + "...";
}
return value;
},
escapeRegex: function(string) {
return string.replace(escapeRegexRe, "\\$1");
},
createRegex: function(value, startsWith, endsWith, ignoreCase) {
var ret = value;
if (value != null && !value.exec) {
ret = ExtString.escapeRegex(String(value));
if (startsWith !== false) {
ret = '^' + ret;
}
if (endsWith !== false) {
ret += '$';
}
ret = new RegExp(ret, (ignoreCase !== false) ? 'i' : '');
}
return ret;
},
escape: function(string) {
return string.replace(escapeRe, "\\$1");
},
toggle: function(string, value, other) {
return string === value ? other : value;
},
leftPad: function(string, size, character) {
var result = String(string);
character = character || " ";
while (result.length < size) {
result = character + result;
}
return result;
},
repeat: function(pattern, count, sep) {
if (count < 1) {
count = 0;
}
for (var buf = [],
i = count; i--; ) {
buf.push(pattern);
}
return buf.join(sep || '');
},
splitWords: function(words) {
if (words && typeof words == 'string') {
return words.replace(basicTrimRe, '').split(whitespaceRe);
}
return words || [];
}
};
}());
Ext.String.resetCharacterEntities();
Ext.htmlEncode = Ext.String.htmlEncode;
Ext.htmlDecode = Ext.String.htmlDecode;
Ext.urlAppend = Ext.String.urlAppend;
Ext.Date = (function() {
var utilDate,
nativeDate = Date,
stripEscapeRe = /(\\.)/g,
hourInfoRe = /([gGhHisucUOPZ]|MS)/,
dateInfoRe = /([djzmnYycU]|MS)/,
slashRe = /\\/gi,
numberTokenRe = /\{(\d+)\}/g,
MSFormatRe = new RegExp('\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/'),
pad = Ext.String.leftPad,
code = [
"var me = this, dt, y, m, d, h, i, s, ms, o, O, z, zz, u, v, W, year, jan4, week1monday, daysInMonth, dayMatched,",
"def = me.defaults,",
"from = Ext.Number.from,",
"results = String(input).match(me.parseRegexes[{0}]);",
"if(results){",
"{1}",
"if(u != null){",
"v = new Date(u * 1000);",
"}else{",
"dt = me.clearTime(new Date);",
"y = from(y, from(def.y, dt.getFullYear()));",
"m = from(m, from(def.m - 1, dt.getMonth()));",
"dayMatched = d !== undefined;",
"d = from(d, from(def.d, dt.getDate()));",
"if (!dayMatched) {",
"dt.setDate(1);",
"dt.setMonth(m);",
"dt.setFullYear(y);",
"daysInMonth = me.getDaysInMonth(dt);",
"if (d > daysInMonth) {",
"d = daysInMonth;",
"}",
"}",
"h = from(h, from(def.h, dt.getHours()));",
"i = from(i, from(def.i, dt.getMinutes()));",
"s = from(s, from(def.s, dt.getSeconds()));",
"ms = from(ms, from(def.ms, dt.getMilliseconds()));",
"if(z >= 0 && y >= 0){",
"v = me.add(new Date(y < 100 ? 100 : y, 0, 1, h, i, s, ms), me.YEAR, y < 100 ? y - 100 : 0);",
"v = !strict? v : (strict === true && (z <= 364 || (me.isLeapYear(v) && z <= 365))? me.add(v, me.DAY, z) : null);",
"}else if(strict === true && !me.isValid(y, m + 1, d, h, i, s, ms)){",
"v = null;",
"}else{",
"if (W) {",
"year = y || (new Date()).getFullYear();",
"jan4 = new Date(year, 0, 4, 0, 0, 0);",
"d = jan4.getDay();",
"week1monday = new Date(jan4.getTime() - ((d === 0 ? 6 : d - 1) * 86400000));",
"v = Ext.Date.clearTime(new Date(week1monday.getTime() + ((W - 1) * 604800000 + 43200000)));",
"} else {",
"v = me.add(new Date(y < 100 ? 100 : y, m, d, h, i, s, ms), me.YEAR, y < 100 ? y - 100 : 0);",
"}",
"}",
"}",
"}",
"if(v){",
"if(zz != null){",
"v = me.add(v, me.SECOND, -v.getTimezoneOffset() * 60 - zz);",
"}else if(o){",
"v = me.add(v, me.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));",
"}",
"}",
"return (v != null) ? v : null;"
].join('\n');
if (!Date.prototype.toISOString) {
Date.prototype.toISOString = function() {
var me = this;
return pad(me.getUTCFullYear(), 4, '0') + '-' + pad(me.getUTCMonth() + 1, 2, '0') + '-' + pad(me.getUTCDate(), 2, '0') + 'T' + pad(me.getUTCHours(), 2, '0') + ':' + pad(me.getUTCMinutes(), 2, '0') + ':' + pad(me.getUTCSeconds(), 2, '0') + '.' + pad(me.getUTCMilliseconds(), 3, '0') + 'Z';
};
}
function xf(format) {
var args = Array.prototype.slice.call(arguments, 1);
return format.replace(numberTokenRe, function(m, i) {
return args[i];
});
}
return utilDate = {
now: nativeDate.now,
toString: function(date) {
if (!date) {
date = new nativeDate();
}
return date.getFullYear() + "-" + pad(date.getMonth() + 1, 2, '0') + "-" + pad(date.getDate(), 2, '0') + "T" + pad(date.getHours(), 2, '0') + ":" + pad(date.getMinutes(), 2, '0') + ":" + pad(date.getSeconds(), 2, '0');
},
getElapsed: function(dateA, dateB) {
return Math.abs(dateA - (dateB || utilDate.now()));
},
useStrict: false,
formatCodeToRegex: function(character, currentGroup) {
var p = utilDate.parseCodes[character];
if (p) {
p = typeof p === 'function' ? p() : p;
utilDate.parseCodes[character] = p;
}
return p ? Ext.applyIf({
c: p.c ? xf(p.c, currentGroup || "{0}") : p.c
}, p) : {
g: 0,
c: null,
s: Ext.String.escapeRegex(character)
};
},
parseFunctions: {
"MS": function(input, strict) {
var r = (input || '').match(MSFormatRe);
return r ? new nativeDate(((r[1] || '') + r[2]) * 1) : null;
},
"time": function(input, strict) {
var num = parseInt(input, 10);
if (num || num === 0) {
return new nativeDate(num);
}
return null;
},
"timestamp": function(input, strict) {
var num = parseInt(input, 10);
if (num || num === 0) {
return new nativeDate(num * 1000);
}
return null;
}
},
parseRegexes: [],
formatFunctions: {
"MS": function() {
return '\\/Date(' + this.getTime() + ')\\/';
},
"time": function() {
return this.getTime().toString();
},
"timestamp": function() {
return utilDate.format(this, 'U');
}
},
y2kYear: 50,
MILLI: "ms",
SECOND: "s",
MINUTE: "mi",
HOUR: "h",
DAY: "d",
MONTH: "mo",
YEAR: "y",
defaults: {},
dayNames: [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
],
monthNames: [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
],
monthNumbers: {
January: 0,
Jan: 0,
February: 1,
Feb: 1,
March: 2,
Mar: 2,
April: 3,
Apr: 3,
May: 4,
June: 5,
Jun: 5,
July: 6,
Jul: 6,
August: 7,
Aug: 7,
September: 8,
Sep: 8,
October: 9,
Oct: 9,
November: 10,
Nov: 10,
December: 11,
Dec: 11
},
defaultFormat: "m/d/Y",
getShortMonthName: function(month) {
return utilDate.monthNames[month].substring(0, 3);
},
getShortDayName: function(day) {
return utilDate.dayNames[day].substring(0, 3);
},
getMonthNumber: function(name) {
return utilDate.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];
},
formatContainsHourInfo: function(format) {
return hourInfoRe.test(format.replace(stripEscapeRe, ''));
},
formatContainsDateInfo: function(format) {
return dateInfoRe.test(format.replace(stripEscapeRe, ''));
},
unescapeFormat: function(format) {
return format.replace(slashRe, '');
},
formatCodes: {
d: "Ext.String.leftPad(m.getDate(), 2, '0')",
D: "Ext.Date.getShortDayName(m.getDay())",
j: "m.getDate()",
l: "Ext.Date.dayNames[m.getDay()]",
N: "(m.getDay() ? m.getDay() : 7)",
S: "Ext.Date.getSuffix(m)",
w: "m.getDay()",
z: "Ext.Date.getDayOfYear(m)",
W: "Ext.String.leftPad(Ext.Date.getWeekOfYear(m), 2, '0')",
F: "Ext.Date.monthNames[m.getMonth()]",
m: "Ext.String.leftPad(m.getMonth() + 1, 2, '0')",
M: "Ext.Date.getShortMonthName(m.getMonth())",
n: "(m.getMonth() + 1)",
t: "Ext.Date.getDaysInMonth(m)",
L: "(Ext.Date.isLeapYear(m) ? 1 : 0)",
o: "(m.getFullYear() + (Ext.Date.getWeekOfYear(m) == 1 && m.getMonth() > 0 ? +1 : (Ext.Date.getWeekOfYear(m) >= 52 && m.getMonth() < 11 ? -1 : 0)))",
Y: "Ext.String.leftPad(m.getFullYear(), 4, '0')",
y: "('' + m.getFullYear()).substring(2, 4)",
a: "(m.getHours() < 12 ? 'am' : 'pm')",
A: "(m.getHours() < 12 ? 'AM' : 'PM')",
g: "((m.getHours() % 12) ? m.getHours() % 12 : 12)",
G: "m.getHours()",
h: "Ext.String.leftPad((m.getHours() % 12) ? m.getHours() % 12 : 12, 2, '0')",
H: "Ext.String.leftPad(m.getHours(), 2, '0')",
i: "Ext.String.leftPad(m.getMinutes(), 2, '0')",
s: "Ext.String.leftPad(m.getSeconds(), 2, '0')",
u: "Ext.String.leftPad(m.getMilliseconds(), 3, '0')",
O: "Ext.Date.getGMTOffset(m)",
P: "Ext.Date.getGMTOffset(m, true)",
T: "Ext.Date.getTimezone(m)",
Z: "(m.getTimezoneOffset() * -60)",
c: function() {
var c = "Y-m-dTH:i:sP",
code = [],
i,
l = c.length,
e;
for (i = 0; i < l; ++i) {
e = c.charAt(i);
code.push(e === "T" ? "'T'" : utilDate.getFormatCode(e));
}
return code.join(" + ");
},
C: function() {
return 'm.toISOString()';
},
U: "Math.round(m.getTime() / 1000)"
},
isValid: function(y, m, d, h, i, s, ms) {
h = h || 0;
i = i || 0;
s = s || 0;
ms = ms || 0;
var dt = utilDate.add(new nativeDate(y < 100 ? 100 : y, m - 1, d, h, i, s, ms), utilDate.YEAR, y < 100 ? y - 100 : 0);
return y === dt.getFullYear() && m === dt.getMonth() + 1 && d === dt.getDate() && h === dt.getHours() && i === dt.getMinutes() && s === dt.getSeconds() && ms === dt.getMilliseconds();
},
parse: function(input, format, strict) {
var p = utilDate.parseFunctions;
if (p[format] == null) {
utilDate.createParser(format);
}
return p[format].call(utilDate, input, Ext.isDefined(strict) ? strict : utilDate.useStrict);
},
parseDate: function(input, format, strict) {
return utilDate.parse(input, format, strict);
},
getFormatCode: function(character) {
var f = utilDate.formatCodes[character];
if (f) {
f = typeof f === 'function' ? f() : f;
utilDate.formatCodes[character] = f;
}
return f || ("'" + Ext.String.escape(character) + "'");
},
createFormat: function(format) {
var code = [],
special = false,
ch = '',
i;
for (i = 0; i < format.length; ++i) {
ch = format.charAt(i);
if (!special && ch === "\\") {
special = true;
} else if (special) {
special = false;
code.push("'" + Ext.String.escape(ch) + "'");
} else {
if (ch === '\n') {
code.push("'\\n'");
} else {
code.push(utilDate.getFormatCode(ch));
}
}
}
utilDate.formatFunctions[format] = Ext.functionFactory("var m=this;return " + code.join('+'));
},
createParser: function(format) {
var regexNum = utilDate.parseRegexes.length,
currentGroup = 1,
calc = [],
regex = [],
special = false,
ch = "",
i = 0,
len = format.length,
atEnd = [],
obj;
for (; i < len; ++i) {
ch = format.charAt(i);
if (!special && ch === "\\") {
special = true;
} else if (special) {
special = false;
regex.push(Ext.String.escape(ch));
} else {
obj = utilDate.formatCodeToRegex(ch, currentGroup);
currentGroup += obj.g;
regex.push(obj.s);
if (obj.g && obj.c) {
if (obj.calcAtEnd) {
atEnd.push(obj.c);
} else {
calc.push(obj.c);
}
}
}
}
calc = calc.concat(atEnd);
utilDate.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", 'i');
utilDate.parseFunctions[format] = Ext.functionFactory("input", "strict", xf(code, regexNum, calc.join('')));
},
parseCodes: {
d: {
g: 1,
c: "d = parseInt(results[{0}], 10);\n",
s: "(3[0-1]|[1-2][0-9]|0[1-9])"
},
j: {
g: 1,
c: "d = parseInt(results[{0}], 10);\n",
s: "(3[0-1]|[1-2][0-9]|[1-9])"
},
D: function() {
for (var a = [],
i = 0; i < 7; a.push(utilDate.getShortDayName(i)) , ++i){}
return {
g: 0,
c: null,
s: "(?:" + a.join("|") + ")"
};
},
l: function() {
return {
g: 0,
c: null,
s: "(?:" + utilDate.dayNames.join("|") + ")"
};
},
N: {
g: 0,
c: null,
s: "[1-7]"
},
S: {
g: 0,
c: null,
s: "(?:st|nd|rd|th)"
},
w: {
g: 0,
c: null,
s: "[0-6]"
},
z: {
g: 1,
c: "z = parseInt(results[{0}], 10);\n",
s: "(\\d{1,3})"
},
W: {
g: 1,
c: "W = parseInt(results[{0}], 10);\n",
s: "(\\d{2})"
},
F: function() {
return {
g: 1,
c: "m = parseInt(me.getMonthNumber(results[{0}]), 10);\n",
s: "(" + utilDate.monthNames.join("|") + ")"
};
},
M: function() {
for (var a = [],
i = 0; i < 12; a.push(utilDate.getShortMonthName(i)) , ++i){}
return Ext.applyIf({
s: "(" + a.join("|") + ")"
}, utilDate.formatCodeToRegex("F"));
},
m: {
g: 1,
c: "m = parseInt(results[{0}], 10) - 1;\n",
s: "(1[0-2]|0[1-9])"
},
n: {
g: 1,
c: "m = parseInt(results[{0}], 10) - 1;\n",
s: "(1[0-2]|[1-9])"
},
t: {
g: 0,
c: null,
s: "(?:\\d{2})"
},
L: {
g: 0,
c: null,
s: "(?:1|0)"
},
o: {
g: 1,
c: "y = parseInt(results[{0}], 10);\n",
s: "(\\d{4})"
},
Y: {
g: 1,
c: "y = parseInt(results[{0}], 10);\n",
s: "(\\d{4})"
},
y: {
g: 1,
c: "var ty = parseInt(results[{0}], 10);\n" + "y = ty > me.y2kYear ? 1900 + ty : 2000 + ty;\n",
s: "(\\d{2})"
},
a: {
g: 1,
c: "if (/(am)/i.test(results[{0}])) {\n" + "if (!h || h == 12) { h = 0; }\n" + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
s: "(am|pm|AM|PM)",
calcAtEnd: true
},
A: {
g: 1,
c: "if (/(am)/i.test(results[{0}])) {\n" + "if (!h || h == 12) { h = 0; }\n" + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
s: "(AM|PM|am|pm)",
calcAtEnd: true
},
g: {
g: 1,
c: "h = parseInt(results[{0}], 10);\n",
s: "(1[0-2]|[0-9])"
},
G: {
g: 1,
c: "h = parseInt(results[{0}], 10);\n",
s: "(2[0-3]|1[0-9]|[0-9])"
},
h: {
g: 1,
c: "h = parseInt(results[{0}], 10);\n",
s: "(1[0-2]|0[1-9])"
},
H: {
g: 1,
c: "h = parseInt(results[{0}], 10);\n",
s: "(2[0-3]|[0-1][0-9])"
},
i: {
g: 1,
c: "i = parseInt(results[{0}], 10);\n",
s: "([0-5][0-9])"
},
s: {
g: 1,
c: "s = parseInt(results[{0}], 10);\n",
s: "([0-5][0-9])"
},
u: {
g: 1,
c: "ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n",
s: "(\\d+)"
},
O: {
g: 1,
c: [
"o = results[{0}];",
"var sn = o.substring(0,1),",
"hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),",
"mn = o.substring(3,5) % 60;",
"o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + Ext.String.leftPad(hr, 2, '0') + Ext.String.leftPad(mn, 2, '0')) : null;\n"
].
join("\n"),
s: "([+-]\\d{4})"
},
P: {
g: 1,
c: [
"o = results[{0}];",
"var sn = o.substring(0,1),",
"hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),",
"mn = o.substring(4,6) % 60;",
"o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + Ext.String.leftPad(hr, 2, '0') + Ext.String.leftPad(mn, 2, '0')) : null;\n"
].
join("\n"),
s: "([+-]\\d{2}:\\d{2})"
},
T: {
g: 0,
c: null,
s: "[A-Z]{1,5}"
},
Z: {
g: 1,
c: "zz = results[{0}] * 1;\n" +
"zz = (-43200 <= zz && zz <= 50400)? zz : null;\n",
s: "([+-]?\\d{1,5})"
},
c: function() {
var calc = [],
arr = [
utilDate.formatCodeToRegex("Y", 1),
utilDate.formatCodeToRegex("m", 2),
utilDate.formatCodeToRegex("d", 3),
utilDate.formatCodeToRegex("H", 4),
utilDate.formatCodeToRegex("i", 5),
utilDate.formatCodeToRegex("s", 6),
{
c: "ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"
},
{
c: [
"if(results[8]) {",
"if(results[8] == 'Z'){",
"zz = 0;",
"}else if (results[8].indexOf(':') > -1){",
utilDate.formatCodeToRegex("P", 8).c,
"}else{",
utilDate.formatCodeToRegex("O", 8).c,
"}",
"}"
].join('\n')
}
],
i, l;
for (i = 0 , l = arr.length; i < l; ++i) {
calc.push(arr[i].c);
}
return {
g: 1,
c: calc.join(""),
s: [
arr[0].s,
"(?:",
"-",
arr[1].s,
"(?:",
"-",
arr[2].s,
"(?:",
"(?:T| )?",
arr[3].s,
":",
arr[4].s,
"(?::",
arr[5].s,
")?",
"(?:(?:\\.|,)(\\d+))?",
"(Z|(?:[-+]\\d{2}(?::)?\\d{2}))?",
")?",
")?",
")?"
].join("")
};
},
U: {
g: 1,
c: "u = parseInt(results[{0}], 10);\n",
s: "(-?\\d+)"
}
},
dateFormat: function(date, format) {
return utilDate.format(date, format);
},
isEqual: function(date1, date2) {
if (date1 && date2) {
return (date1.getTime() === date2.getTime());
}
return !(date1 || date2);
},
format: function(date, format) {
var formatFunctions = utilDate.formatFunctions;
if (!Ext.isDate(date)) {
return '';
}
if (formatFunctions[format] == null) {
utilDate.createFormat(format);
}
return formatFunctions[format].call(date) + '';
},
getTimezone: function(date) {
return date.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,5})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");
},
getGMTOffset: function(date, colon) {
var offset = date.getTimezoneOffset();
return (offset > 0 ? "-" : "+") + Ext.String.leftPad(Math.floor(Math.abs(offset) / 60), 2, "0") + (colon ? ":" : "") + Ext.String.leftPad(Math.abs(offset % 60), 2, "0");
},
getDayOfYear: function(date) {
var num = 0,
d = utilDate.clone(date),
m = date.getMonth(),
i;
for (i = 0 , d.setDate(1) , d.setMonth(0); i < m; d.setMonth(++i)) {
num += utilDate.getDaysInMonth(d);
}
return num + date.getDate() - 1;
},
getWeekOfYear: (function() {
var ms1d = 86400000,
ms7d = 7 * ms1d;
return function(date) {
var DC3 = nativeDate.UTC(date.getFullYear(), date.getMonth(), date.getDate() + 3) / ms1d,
AWN = Math.floor(DC3 / 7),
Wyr = new nativeDate(AWN * ms7d).getUTCFullYear();
return AWN - Math.floor(nativeDate.UTC(Wyr, 0, 7) / ms7d) + 1;
};
}()),
isLeapYear: function(date) {
var year = date.getFullYear();
return !!((year & 3) === 0 && (year % 100 || (year % 400 === 0 && year)));
},
getFirstDayOfMonth: function(date) {
var day = (date.getDay() - (date.getDate() - 1)) % 7;
return (day < 0) ? (day + 7) : day;
},
getLastDayOfMonth: function(date) {
return utilDate.getLastDateOfMonth(date).getDay();
},
getFirstDateOfMonth: function(date) {
return new nativeDate(date.getFullYear(), date.getMonth(), 1);
},
getLastDateOfMonth: function(date) {
return new nativeDate(date.getFullYear(), date.getMonth(), utilDate.getDaysInMonth(date));
},
getDaysInMonth: (function() {
var daysInMonth = [
31,
28,
31,
30,
31,
30,
31,
31,
30,
31,
30,
31
];
return function(date) {
var m = date.getMonth();
return m === 1 && utilDate.isLeapYear(date) ? 29 : daysInMonth[m];
};
}()),
getSuffix: function(date) {
switch (date.getDate()) {
case 1:
case 21:
case 31:
return "st";
case 2:
case 22:
return "nd";
case 3:
case 23:
return "rd";
default:
return "th";
}
},
clone: function(date) {
return new nativeDate(date.getTime());
},
isDST: function(date) {
return new nativeDate(date.getFullYear(), 0, 1).getTimezoneOffset() !== date.getTimezoneOffset();
},
clearTime: function(date, clone) {
if (clone) {
return utilDate.clearTime(utilDate.clone(date));
}
var d = date.getDate(),
hr, c;
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
date.setMilliseconds(0);
if (date.getDate() !== d) {
for (hr = 1 , c = utilDate.add(date, utilDate.HOUR, hr); c.getDate() !== d; hr++ , c = utilDate.add(date, utilDate.HOUR, hr)){}
date.setDate(d);
date.setHours(c.getHours());
}
return date;
},
add: function(date, interval, value) {
var d = utilDate.clone(date),
day, decimalValue,
base = 0;
if (!interval || value === 0) {
return d;
}
decimalValue = value - parseInt(value, 10);
value = parseInt(value, 10);
if (value) {
switch (interval.toLowerCase()) {
case utilDate.MILLI:
d.setTime(d.getTime() + value);
break;
case utilDate.SECOND:
d.setTime(d.getTime() + value * 1000);
break;
case utilDate.MINUTE:
d.setTime(d.getTime() + value * 60 * 1000);
break;
case utilDate.HOUR:
d.setTime(d.getTime() + value * 60 * 60 * 1000);
break;
case utilDate.DAY:
d.setDate(d.getDate() + value);
break;
case utilDate.MONTH:
day = date.getDate();
if (day > 28) {
day = Math.min(day, utilDate.getLastDateOfMonth(utilDate.add(utilDate.getFirstDateOfMonth(date), utilDate.MONTH, value)).getDate());
};
d.setDate(day);
d.setMonth(date.getMonth() + value);
break;
case utilDate.YEAR:
day = date.getDate();
if (day > 28) {
day = Math.min(day, utilDate.getLastDateOfMonth(utilDate.add(utilDate.getFirstDateOfMonth(date), utilDate.YEAR, value)).getDate());
};
d.setDate(day);
d.setFullYear(date.getFullYear() + value);
break;
}
}
if (decimalValue) {
switch (interval.toLowerCase()) {
case utilDate.MILLI:
base = 1;
break;
case utilDate.SECOND:
base = 1000;
break;
case utilDate.MINUTE:
base = 1000 * 60;
break;
case utilDate.HOUR:
base = 1000 * 60 * 60;
break;
case utilDate.DAY:
base = 1000 * 60 * 60 * 24;
break;
case utilDate.MONTH:
day = utilDate.getDaysInMonth(d);
base = 1000 * 60 * 60 * 24 * day;
break;
case utilDate.YEAR:
day = (utilDate.isLeapYear(d) ? 366 : 365);
base = 1000 * 60 * 60 * 24 * day;
break;
}
if (base) {
d.setTime(d.getTime() + base * decimalValue);
}
}
return d;
},
subtract: function(date, interval, value) {
return utilDate.add(date, interval, -value);
},
between: function(date, start, end) {
var t = date.getTime();
return start.getTime() <= t && t <= end.getTime();
},
compat: function() {
var p,
statics = [
'useStrict',
'formatCodeToRegex',
'parseFunctions',
'parseRegexes',
'formatFunctions',
'y2kYear',
'MILLI',
'SECOND',
'MINUTE',
'HOUR',
'DAY',
'MONTH',
'YEAR',
'defaults',
'dayNames',
'monthNames',
'monthNumbers',
'getShortMonthName',
'getShortDayName',
'getMonthNumber',
'formatCodes',
'isValid',
'parseDate',
'getFormatCode',
'createFormat',
'createParser',
'parseCodes'
],
proto = [
'dateFormat',
'format',
'getTimezone',
'getGMTOffset',
'getDayOfYear',
'getWeekOfYear',
'isLeapYear',
'getFirstDayOfMonth',
'getLastDayOfMonth',
'getDaysInMonth',
'getSuffix',
'clone',
'isDST',
'clearTime',
'add',
'between'
],
sLen = statics.length,
pLen = proto.length,
stat, prot, s;
for (s = 0; s < sLen; s++) {
stat = statics[s];
nativeDate[stat] = utilDate[stat];
}
for (p = 0; p < pLen; p++) {
prot = proto[p];
nativeDate.prototype[prot] = function() {
var args = Array.prototype.slice.call(arguments);
args.unshift(this);
return utilDate[prot].apply(utilDate, args);
};
}
},
diff: function(min, max, unit) {
var est,
diff = +max - min;
switch (unit) {
case utilDate.MILLI:
return diff;
case utilDate.SECOND:
return Math.floor(diff / 1000);
case utilDate.MINUTE:
return Math.floor(diff / 60000);
case utilDate.HOUR:
return Math.floor(diff / 3600000);
case utilDate.DAY:
return Math.floor(diff / 86400000);
case 'w':
return Math.floor(diff / 604800000);
case utilDate.MONTH:
est = (max.getFullYear() * 12 + max.getMonth()) - (min.getFullYear() * 12 + min.getMonth());
if (utilDate.add(min, unit, est) > max) {
return est - 1;
};
return est;
case utilDate.YEAR:
est = max.getFullYear() - min.getFullYear();
if (utilDate.add(min, unit, est) > max) {
return est - 1;
} else {
return est;
};
}
},
align: function(date, unit, step) {
var num = new nativeDate(+date);
switch (unit.toLowerCase()) {
case utilDate.MILLI:
return num;
case utilDate.SECOND:
num.setUTCSeconds(num.getUTCSeconds() - num.getUTCSeconds() % step);
num.setUTCMilliseconds(0);
return num;
case utilDate.MINUTE:
num.setUTCMinutes(num.getUTCMinutes() - num.getUTCMinutes() % step);
num.setUTCSeconds(0);
num.setUTCMilliseconds(0);
return num;
case utilDate.HOUR:
num.setUTCHours(num.getUTCHours() - num.getUTCHours() % step);
num.setUTCMinutes(0);
num.setUTCSeconds(0);
num.setUTCMilliseconds(0);
return num;
case utilDate.DAY:
if (step === 7 || step === 14) {
num.setUTCDate(num.getUTCDate() - num.getUTCDay() + 1);
};
num.setUTCHours(0);
num.setUTCMinutes(0);
num.setUTCSeconds(0);
num.setUTCMilliseconds(0);
return num;
case utilDate.MONTH:
num.setUTCMonth(num.getUTCMonth() - (num.getUTCMonth() - 1) % step, 1);
num.setUTCHours(0);
num.setUTCMinutes(0);
num.setUTCSeconds(0);
num.setUTCMilliseconds(0);
return num;
case utilDate.YEAR:
num.setUTCFullYear(num.getUTCFullYear() - num.getUTCFullYear() % step, 1, 1);
num.setUTCHours(0);
num.setUTCMinutes(0);
num.setUTCSeconds(0);
num.setUTCMilliseconds(0);
return date;
}
}
};
}());
Ext.Function = (function() {
var lastTime = 0,
animFrameId,
animFrameHandlers = [],
animFrameNoArgs = [],
idSource = 0,
animFrameMap = {},
win = window,
requestAnimFrame = win.requestAnimationFrame || win.webkitRequestAnimationFrame || win.mozRequestAnimationFrame || win.oRequestAnimationFrame || function(callback) {
var currTime = Ext.now(),
timeToCall = Math.max(0, 16 - (currTime - lastTime)),
id = win.setTimeout(function() {
callback(currTime + timeToCall);
}, timeToCall);
lastTime = currTime + timeToCall;
return id;
},
fireHandlers = function() {
var len = animFrameHandlers.length,
id, i, handler;
animFrameId = null;
for (i = 0; i < len; i++) {
handler = animFrameHandlers[i];
id = handler[3];
if (animFrameMap[id]) {
handler[0].apply(handler[1] || Ext.global, handler[2] || animFrameNoArgs);
delete animFrameMap[id];
}
}
animFrameHandlers = animFrameHandlers.slice(len);
},
fireElevatedHandlers = function() {
Ext.elevateFunction(fireHandlers);
},
ExtFunction = {
flexSetter: function(setter) {
return function(name, value) {
var k, i;
if (name !== null) {
if (typeof name !== 'string') {
for (k in name) {
if (name.hasOwnProperty(k)) {
setter.call(this, k, name[k]);
}
}
if (Ext.enumerables) {
for (i = Ext.enumerables.length; i--; ) {
k = Ext.enumerables[i];
if (name.hasOwnProperty(k)) {
setter.call(this, k, name[k]);
}
}
}
} else {
setter.call(this, name, value);
}
}
return this;
};
},
bind: function(fn, scope, args, appendArgs) {
if (arguments.length === 2) {
return function() {
return fn.apply(scope, arguments);
};
}
var method = fn,
slice = Array.prototype.slice;
return function() {
var callArgs = args || arguments;
if (appendArgs === true) {
callArgs = slice.call(arguments, 0);
callArgs = callArgs.concat(args);
} else if (typeof appendArgs == 'number') {
callArgs = slice.call(arguments, 0);
Ext.Array.insert(callArgs, appendArgs, args);
}
return method.apply(scope || Ext.global, callArgs);
};
},
bindCallback: function(callback, scope, args, delay, caller) {
return function() {
var a = Ext.Array.slice(arguments);
return Ext.callback(callback, scope, args ? args.concat(a) : a, delay, caller);
};
},
pass: function(fn, args, scope) {
if (!Ext.isArray(args)) {
if (Ext.isIterable(args)) {
args = Ext.Array.clone(args);
} else {
args = args !== undefined ? [
args
] : [];
}
}
return function() {
var fnArgs = args.slice();
fnArgs.push.apply(fnArgs, arguments);
return fn.apply(scope || this, fnArgs);
};
},
alias: function(object, methodName) {
return function() {
return object[methodName].apply(object, arguments);
};
},
clone: function(method) {
return function() {
return method.apply(this, arguments);
};
},
createInterceptor: function(origFn, newFn, scope, returnValue) {
if (!Ext.isFunction(newFn)) {
return origFn;
} else {
returnValue = Ext.isDefined(returnValue) ? returnValue : null;
return function() {
var me = this,
args = arguments;
newFn.target = me;
newFn.method = origFn;
return (newFn.apply(scope || me || Ext.global, args) !== false) ? origFn.apply(me || Ext.global, args) : returnValue;
};
}
},
createDelayed: function(fn, delay, scope, args, appendArgs) {
if (scope || args) {
fn = Ext.Function.bind(fn, scope, args, appendArgs);
}
return function() {
var me = this,
args = Array.prototype.slice.call(arguments);
setTimeout(function() {
if (Ext.elevateFunction) {
Ext.elevateFunction(fn, me, args);
} else {
fn.apply(me, args);
}
}, delay);
};
},
defer: function(fn, millis, scope, args, appendArgs) {
fn = Ext.Function.bind(fn, scope, args, appendArgs);
if (millis > 0) {
return setTimeout(function() {
if (Ext.elevateFunction) {
Ext.elevateFunction(fn);
} else {
fn();
}
}, millis);
}
fn();
return 0;
},
interval: function(fn, millis, scope, args, appendArgs) {
fn = Ext.Function.bind(fn, scope, args, appendArgs);
return setInterval(function() {
if (Ext.elevateFunction) {
Ext.elevateFunction(fn);
} else {
fn();
}
}, millis);
},
createSequence: function(originalFn, newFn, scope) {
if (!newFn) {
return originalFn;
} else {
return function() {
var result = originalFn.apply(this, arguments);
newFn.apply(scope || this, arguments);
return result;
};
}
},
createBuffered: function(fn, buffer, scope, args) {
var timerId;
return function() {
var callArgs = args || Array.prototype.slice.call(arguments, 0),
me = scope || this;
if (timerId) {
clearTimeout(timerId);
}
timerId = setTimeout(function() {
if (Ext.elevateFunction) {
Ext.elevateFunction(fn, me, callArgs);
} else {
fn.apply(me, callArgs);
}
}, buffer);
};
},
createAnimationFrame: function(fn, scope, args, queueStrategy) {
var timerId;
queueStrategy = queueStrategy || 3;
return function() {
var callArgs = args || Array.prototype.slice.call(arguments, 0);
scope = scope || this;
if (queueStrategy === 3 && timerId) {
ExtFunction.cancelAnimationFrame(timerId);
}
if ((queueStrategy & 1) || !timerId) {
timerId = ExtFunction.requestAnimationFrame(function() {
timerId = null;
fn.apply(scope, callArgs);
});
}
};
},
requestAnimationFrame: function(fn, scope, args) {
var id = ++idSource,
handler = Array.prototype.slice.call(arguments, 0);
handler[3] = id;
animFrameMap[id] = 1;
animFrameHandlers.push(handler);
if (!animFrameId) {
animFrameId = requestAnimFrame(Ext.elevateFunction ? fireElevatedHandlers : fireHandlers);
}
return id;
},
cancelAnimationFrame: function(id) {
delete animFrameMap[id];
},
createThrottled: function(fn, interval, scope) {
var lastCallTime = 0,
elapsed, lastArgs, timer,
execute = function() {
if (Ext.elevateFunction) {
Ext.elevateFunction(fn, scope, lastArgs);
} else {
fn.apply(scope, lastArgs);
}
lastCallTime = Ext.now();
timer = null;
};
return function() {
if (!scope) {
scope = this;
}
elapsed = Ext.now() - lastCallTime;
lastArgs = arguments;
if (elapsed >= interval) {
clearTimeout(timer);
execute();
}
else if (!timer) {
timer = Ext.defer(execute, interval - elapsed);
}
};
},
createBarrier: function(count, fn, scope) {
return function() {
if (!--count) {
fn.apply(scope, arguments);
}
};
},
interceptBefore: function(object, methodName, fn, scope) {
var method = object[methodName] || Ext.emptyFn;
return (object[methodName] = function() {
var ret = fn.apply(scope || this, arguments);
method.apply(this, arguments);
return ret;
});
},
interceptAfter: function(object, methodName, fn, scope) {
var method = object[methodName] || Ext.emptyFn;
return (object[methodName] = function() {
method.apply(this, arguments);
return fn.apply(scope || this, arguments);
});
},
makeCallback: function(callback, scope) {
if (!scope[callback]) {
if (scope.$className) {
Ext.Error.raise('No method "' + callback + '" on ' + scope.$className);
}
Ext.Error.raise('No method "' + callback + '"');
}
return function() {
return scope[callback].apply(scope, arguments);
};
}
};
Ext.defer = ExtFunction.defer;
Ext.interval = ExtFunction.interval;
Ext.pass = ExtFunction.pass;
Ext.bind = ExtFunction.bind;
Ext.deferCallback = ExtFunction.requestAnimationFrame;
return ExtFunction;
})();
Ext.Number = (new function() {
var ExtNumber = this,
isToFixedBroken = (0.9).toFixed() !== '1',
math = Math,
ClipDefault = {
count: false,
inclusive: false,
wrap: true
};
Ext.apply(ExtNumber, {
Clip: {
DEFAULT: ClipDefault,
COUNT: Ext.applyIf({
count: true
}, ClipDefault),
INCLUSIVE: Ext.applyIf({
inclusive: true
}, ClipDefault),
NOWRAP: Ext.applyIf({
wrap: false
}, ClipDefault)
},
clipIndices: function(length, indices, options) {
options = options || ClipDefault;
var defaultValue = 0,
wrap = options.wrap,
begin, end, i;
indices = indices || [];
for (i = 0; i < 2; ++i) {
begin = end;
end = indices[i];
if (end == null) {
end = defaultValue;
} else if (i && options.count) {
end += begin;
end = (end > length) ? length : end;
} else {
if (wrap) {
end = (end < 0) ? (length + end) : end;
}
if (i && options.inclusive) {
++end;
}
end = (end < 0) ? 0 : ((end > length) ? length : end);
}
defaultValue = length;
}
indices[0] = begin;
indices[1] = (end < begin) ? begin : end;
return indices;
},
constrain: function(number, min, max) {
var x = parseFloat(number);
if (min === null) {
min = number;
}
if (max === null) {
max = number;
}
return (x < min) ? min : ((x > max) ? max : x);
},
snap: function(value, increment, minValue, maxValue) {
var m;
if (value === undefined || value < minValue) {
return minValue || 0;
}
if (increment) {
m = value % increment;
if (m !== 0) {
value -= m;
if (m * 2 >= increment) {
value += increment;
} else if (m * 2 < -increment) {
value -= increment;
}
}
}
return ExtNumber.constrain(value, minValue, maxValue);
},
snapInRange: function(value, increment, minValue, maxValue) {
var tween;
minValue = (minValue || 0);
if (value === undefined || value < minValue) {
return minValue;
}
if (increment && (tween = ((value - minValue) % increment))) {
value -= tween;
tween *= 2;
if (tween >= increment) {
value += increment;
}
}
if (maxValue !== undefined) {
if (value > (maxValue = ExtNumber.snapInRange(maxValue, increment, minValue))) {
value = maxValue;
}
}
return value;
},
sign: function(x) {
x = +x;
if (x === 0 || isNaN(x)) {
return x;
}
return (x > 0) ? 1 : -1;
},
toFixed: isToFixedBroken ? function(value, precision) {
precision = precision || 0;
var pow = math.pow(10, precision);
return (math.round(value * pow) / pow).toFixed(precision);
} : function(value, precision) {
return value.toFixed(precision);
},
from: function(value, defaultValue) {
if (isFinite(value)) {
value = parseFloat(value);
}
return !isNaN(value) ? value : defaultValue;
},
randomInt: function(from, to) {
return math.floor(math.random() * (to - from + 1) + from);
},
correctFloat: function(n) {
return parseFloat(n.toPrecision(14));
}
});
Ext.num = function() {
return ExtNumber.from.apply(this, arguments);
};
}());
(function() {
var TemplateClass = function() {},
queryRe = /^\?/,
keyRe = /(\[):?([^\]]*)\]/g,
nameRe = /^([^\[]+)/,
plusRe = /\+/g,
ExtObject = Ext.Object = {
chain: Object.create || function(object) {
TemplateClass.prototype = object;
var result = new TemplateClass();
TemplateClass.prototype = null;
return result;
},
clear: function(object) {
for (var key in object) {
delete object[key];
}
return object;
},
freeze: Object.freeze ? function(obj, deep) {
if (obj && typeof obj === 'object' && !Object.isFrozen(obj)) {
Object.freeze(obj);
if (deep) {
for (var name in obj) {
ExtObject.freeze(obj[name], deep);
}
}
}
return obj;
} : Ext.identityFn,
toQueryObjects: function(name, value, recursive) {
var self = ExtObject.toQueryObjects,
objects = [],
i, ln;
if (Ext.isArray(value)) {
for (i = 0 , ln = value.length; i < ln; i++) {
if (recursive) {
objects = objects.concat(self(name + '[' + i + ']', value[i], true));
} else {
objects.push({
name: name,
value: value[i]
});
}
}
} else if (Ext.isObject(value)) {
for (i in value) {
if (value.hasOwnProperty(i)) {
if (recursive) {
objects = objects.concat(self(name + '[' + i + ']', value[i], true));
} else {
objects.push({
name: name,
value: value[i]
});
}
}
}
} else {
objects.push({
name: name,
value: value
});
}
return objects;
},
toQueryString: function(object, recursive) {
var paramObjects = [],
params = [],
i, j, ln, paramObject, value;
for (i in object) {
if (object.hasOwnProperty(i)) {
paramObjects = paramObjects.concat(ExtObject.toQueryObjects(i, object[i], recursive));
}
}
for (j = 0 , ln = paramObjects.length; j < ln; j++) {
paramObject = paramObjects[j];
value = paramObject.value;
if (Ext.isEmpty(value)) {
value = '';
} else if (Ext.isDate(value)) {
value = Ext.Date.toString(value);
}
params.push(encodeURIComponent(paramObject.name) + '=' + encodeURIComponent(String(value)));
}
return params.join('&');
},
fromQueryString: function(queryString, recursive) {
var parts = queryString.replace(queryRe, '').split('&'),
object = {},
temp, components, name, value, i, ln, part, j, subLn, matchedKeys, matchedName, keys, key, nextKey;
for (i = 0 , ln = parts.length; i < ln; i++) {
part = parts[i];
if (part.length > 0) {
components = part.split('=');
name = components[0];
name = name.replace(plusRe, '%20');
name = decodeURIComponent(name);
value = components[1];
if (value !== undefined) {
value = value.replace(plusRe, '%20');
value = decodeURIComponent(value);
} else {
value = '';
}
if (!recursive) {
if (object.hasOwnProperty(name)) {
if (!Ext.isArray(object[name])) {
object[name] = [
object[name]
];
}
object[name].push(value);
} else {
object[name] = value;
}
} else {
matchedKeys = name.match(keyRe);
matchedName = name.match(nameRe);
if (!matchedName) {
throw new Error('[Ext.Object.fromQueryString] Malformed query string given, failed parsing name from "' + part + '"');
}
name = matchedName[0];
keys = [];
if (matchedKeys === null) {
object[name] = value;
continue;
}
for (j = 0 , subLn = matchedKeys.length; j < subLn; j++) {
key = matchedKeys[j];
key = (key.length === 2) ? '' : key.substring(1, key.length - 1);
keys.push(key);
}
keys.unshift(name);
temp = object;
for (j = 0 , subLn = keys.length; j < subLn; j++) {
key = keys[j];
if (j === subLn - 1) {
if (Ext.isArray(temp) && key === '') {
temp.push(value);
} else {
temp[key] = value;
}
} else {
if (temp[key] === undefined || typeof temp[key] === 'string') {
nextKey = keys[j + 1];
temp[key] = (Ext.isNumeric(nextKey) || nextKey === '') ? [] : {};
}
temp = temp[key];
}
}
}
}
}
return object;
},
each: function(object, fn, scope) {
var enumerables = Ext.enumerables,
i, property;
if (object) {
scope = scope || object;
for (property in object) {
if (object.hasOwnProperty(property)) {
if (fn.call(scope, property, object[property], object) === false) {
return;
}
}
}
if (enumerables) {
for (i = enumerables.length; i--; ) {
if (object.hasOwnProperty(property = enumerables[i])) {
if (fn.call(scope, property, object[property], object) === false) {
return;
}
}
}
}
}
},
eachValue: function(object, fn, scope) {
var enumerables = Ext.enumerables,
i, property;
scope = scope || object;
for (property in object) {
if (object.hasOwnProperty(property)) {
if (fn.call(scope, object[property]) === false) {
return;
}
}
}
if (enumerables) {
for (i = enumerables.length; i--; ) {
if (object.hasOwnProperty(property = enumerables[i])) {
if (fn.call(scope, object[property]) === false) {
return;
}
}
}
}
},
merge: function(destination) {
var i = 1,
ln = arguments.length,
mergeFn = ExtObject.merge,
cloneFn = Ext.clone,
object, key, value, sourceKey;
for (; i < ln; i++) {
object = arguments[i];
for (key in object) {
value = object[key];
if (value && value.constructor === Object) {
sourceKey = destination[key];
if (sourceKey && sourceKey.constructor === Object) {
mergeFn(sourceKey, value);
} else {
destination[key] = cloneFn(value);
}
} else {
destination[key] = value;
}
}
}
return destination;
},
mergeIf: function(destination) {
var i = 1,
ln = arguments.length,
cloneFn = Ext.clone,
object, key, value;
for (; i < ln; i++) {
object = arguments[i];
for (key in object) {
if (!(key in destination)) {
value = object[key];
if (value && value.constructor === Object) {
destination[key] = cloneFn(value);
} else {
destination[key] = value;
}
}
}
}
return destination;
},
getAllKeys: function(object) {
var keys = [],
property;
for (property in object) {
keys.push(property);
}
return keys;
},
getKey: function(object, value) {
for (var property in object) {
if (object.hasOwnProperty(property) && object[property] === value) {
return property;
}
}
return null;
},
getValues: function(object) {
var values = [],
property;
for (property in object) {
if (object.hasOwnProperty(property)) {
values.push(object[property]);
}
}
return values;
},
getKeys: (typeof Object.keys == 'function') ? function(object) {
if (!object) {
return [];
}
return Object.keys(object);
} : function(object) {
var keys = [],
property;
for (property in object) {
if (object.hasOwnProperty(property)) {
keys.push(property);
}
}
return keys;
},
getSize: function(object) {
var size = 0,
property;
for (property in object) {
if (object.hasOwnProperty(property)) {
size++;
}
}
return size;
},
isEmpty: function(object) {
for (var key in object) {
if (object.hasOwnProperty(key)) {
return false;
}
}
return true;
},
equals: (function() {
var check = function(o1, o2) {
var key;
for (key in o1) {
if (o1.hasOwnProperty(key)) {
if (o1[key] !== o2[key]) {
return false;
}
}
}
return true;
};
return function(object1, object2) {
if (object1 === object2) {
return true;
}
if (object1 && object2) {
return check(object1, object2) && check(object2, object1);
} else if (!object1 && !object2) {
return object1 === object2;
} else {
return false;
}
};
})(),
fork: function(obj) {
var ret, key, value;
if (obj && obj.constructor === Object) {
ret = ExtObject.chain(obj);
for (key in obj) {
value = obj[key];
if (value) {
if (value.constructor === Object) {
ret[key] = ExtObject.fork(value);
} else if (value instanceof Array) {
ret[key] = Ext.Array.clone(value);
}
}
}
} else {
ret = obj;
}
return ret;
},
defineProperty: ('defineProperty' in Object) ? Object.defineProperty : function(object, name, descriptor) {
if (!Object.prototype.__defineGetter__) {
return;
}
if (descriptor.get) {
object.__defineGetter__(name, descriptor.get);
}
if (descriptor.set) {
object.__defineSetter__(name, descriptor.set);
}
},
classify: function(object) {
var prototype = object,
objectProperties = [],
propertyClassesMap = {},
objectClass = function() {
var i = 0,
ln = objectProperties.length,
property;
for (; i < ln; i++) {
property = objectProperties[i];
this[property] = new propertyClassesMap[property]();
}
},
key, value;
for (key in object) {
if (object.hasOwnProperty(key)) {
value = object[key];
if (value && value.constructor === Object) {
objectProperties.push(key);
propertyClassesMap[key] = ExtObject.classify(value);
}
}
}
objectClass.prototype = prototype;
return objectClass;
}
};
Ext.merge = Ext.Object.merge;
Ext.mergeIf = Ext.Object.mergeIf;
}());
Ext.apply(Ext, {
_namedScopes: {
'this': {
isThis: 1
},
controller: {
isController: 1
},
self: {
isSelf: 1
},
'self.controller': {
isSelf: 1,
isController: 1
}
},
escapeId: (function() {
var validIdRe = /^[a-zA-Z_][a-zA-Z0-9_\-]*$/i,
escapeRx = /([\W]{1})/g,
leadingNumRx = /^(\d)/g,
escapeFn = function(match, capture) {
return "\\" + capture;
},
numEscapeFn = function(match, capture) {
return '\\00' + capture.charCodeAt(0).toString(16) + ' ';
};
return function(id) {
return validIdRe.test(id) ? id :
id.replace(escapeRx, escapeFn).replace(leadingNumRx, numEscapeFn);
};
}()),
callback: function(callback, scope, args, delay, caller, defaultScope) {
if (!callback) {
return;
}
var namedScope = (scope in Ext._namedScopes);
if (callback.charAt) {
if ((!scope || namedScope) && caller) {
scope = caller.resolveListenerScope(namedScope ? scope : defaultScope);
}
if (!scope || !Ext.isObject(scope)) {
Ext.Error.raise('Named method "' + callback + '" requires a scope object');
}
if (!Ext.isFunction(scope[callback])) {
Ext.Error.raise('No method named "' + callback + '" on ' + (scope.$className || 'scope object'));
}
callback = scope[callback];
} else if (namedScope) {
scope = defaultScope || caller;
} else if (!scope) {
scope = caller;
}
var ret;
if (callback && Ext.isFunction(callback)) {
scope = scope || Ext.global;
if (delay) {
Ext.defer(callback, delay, scope, args);
} else if (Ext.elevateFunction) {
ret = Ext.elevateFunction(callback, scope, args);
} else if (args) {
ret = callback.apply(scope, args);
} else {
ret = callback.call(scope);
}
}
return ret;
},
coerce: function(from, to) {
var fromType = Ext.typeOf(from),
toType = Ext.typeOf(to),
isString = typeof from === 'string';
if (fromType !== toType) {
switch (toType) {
case 'string':
return String(from);
case 'number':
return Number(from);
case 'boolean':
return isString && (!from || from === 'false') ? false : Boolean(from);
case 'null':
return isString && (!from || from === 'null') ? null : from;
case 'undefined':
return isString && (!from || from === 'undefined') ? undefined : from;
case 'date':
return isString && isNaN(from) ? Ext.Date.parse(from, Ext.Date.defaultFormat) : Date(Number(from));
}
}
return from;
},
copyTo: function(dest, source, names, usePrototypeKeys) {
if (typeof names === 'string') {
names = names.split(Ext.propertyNameSplitRe);
}
for (var name,
i = 0,
n = names ? names.length : 0; i < n; i++) {
name = names[i];
if (usePrototypeKeys || source.hasOwnProperty(name)) {
dest[name] = source[name];
}
}
return dest;
},
propertyNameSplitRe: /[,;\s]+/,
copyToIf: function(destination, source, names) {
if (typeof names === 'string') {
names = names.split(Ext.propertyNameSplitRe);
}
for (var name,
i = 0,
n = names ? names.length : 0; i < n; i++) {
name = names[i];
if (destination[name] === undefined) {
destination[name] = source[name];
}
}
return destination;
},
extend: (function() {
var objectConstructor = Object.prototype.constructor,
inlineOverrides = function(o) {
for (var m in o) {
if (!o.hasOwnProperty(m)) {
continue;
}
this[m] = o[m];
}
};
return function(subclass, superclass, overrides) {
if (Ext.isObject(superclass)) {
overrides = superclass;
superclass = subclass;
subclass = overrides.constructor !== objectConstructor ? overrides.constructor : function() {
superclass.apply(this, arguments);
};
}
if (!superclass) {
Ext.Error.raise({
sourceClass: 'Ext',
sourceMethod: 'extend',
msg: 'Attempting to extend from a class which has not been loaded on the page.'
});
}
var F = function() {},
subclassProto,
superclassProto = superclass.prototype;
F.prototype = superclassProto;
subclassProto = subclass.prototype = new F();
subclassProto.constructor = subclass;
subclass.superclass = superclassProto;
if (superclassProto.constructor === objectConstructor) {
superclassProto.constructor = superclass;
}
subclass.override = function(overrides) {
Ext.override(subclass, overrides);
};
subclassProto.override = inlineOverrides;
subclassProto.proto = subclassProto;
subclass.override(overrides);
subclass.extend = function(o) {
return Ext.extend(subclass, o);
};
return subclass;
};
}()),
iterate: function(object, fn, scope) {
if (Ext.isEmpty(object)) {
return;
}
if (scope === undefined) {
scope = object;
}
if (Ext.isIterable(object)) {
Ext.Array.each.call(Ext.Array, object, fn, scope);
} else {
Ext.Object.each.call(Ext.Object, object, fn, scope);
}
},
urlEncode: function() {
var args = Ext.Array.from(arguments),
prefix = '';
if (Ext.isString(args[1])) {
prefix = args[1] + '&';
args[1] = false;
}
return prefix + Ext.Object.toQueryString.apply(Ext.Object, args);
},
urlDecode: function() {
return Ext.Object.fromQueryString.apply(Ext.Object, arguments);
},
getScrollbarSize: function(force) {
if (!Ext.isDomReady) {
Ext.Error.raise("getScrollbarSize called before DomReady");
}
var scrollbarSize = Ext._scrollbarSize;
if (force || !scrollbarSize) {
var db = document.body,
div = document.createElement('div');
div.style.width = div.style.height = '100px';
div.style.overflow = 'scroll';
div.style.position = 'absolute';
db.appendChild(div);
Ext._scrollbarSize = scrollbarSize = {
width: div.offsetWidth - div.clientWidth,
height: div.offsetHeight - div.clientHeight
};
db.removeChild(div);
}
return scrollbarSize;
},
typeOf: (function() {
var nonWhitespaceRe = /\S/,
toString = Object.prototype.toString,
typeofTypes = {
number: 1,
string: 1,
'boolean': 1,
'undefined': 1
},
toStringTypes = {
'[object Array]': 'array',
'[object Date]': 'date',
'[object Boolean]': 'boolean',
'[object Number]': 'number',
'[object RegExp]': 'regexp'
};
return function(value) {
if (value === null) {
return 'null';
}
var type = typeof value,
ret, typeToString;
if (typeofTypes[type]) {
return type;
}
ret = toStringTypes[typeToString = toString.call(value)];
if (ret) {
return ret;
}
if (type === 'function') {
return 'function';
}
if (type === 'object') {
if (value.nodeType !== undefined) {
if (value.nodeType === 3) {
return nonWhitespaceRe.test(value.nodeValue) ? 'textnode' : 'whitespace';
} else {
return 'element';
}
}
return 'object';
}
Ext.Error.raise({
sourceClass: 'Ext',
sourceMethod: 'typeOf',
msg: 'Failed to determine the type of "' + value + '".'
});
return typeToString;
};
}()),
factory: function(config, classReference, instance, aliasNamespace) {
var manager = Ext.ClassManager,
newInstance;
if (!config || config.isInstance) {
if (instance && instance !== config) {
instance.destroy();
}
return config;
}
if (aliasNamespace) {
if (typeof config === 'string') {
return manager.instantiateByAlias(aliasNamespace + '.' + config);
}
else if (Ext.isObject(config) && 'type' in config) {
return manager.instantiateByAlias(aliasNamespace + '.' + config.type, config);
}
}
if (config === true) {
return instance || Ext.create(classReference);
}
if (!Ext.isObject(config)) {
Ext.Logger.error("Invalid config, must be a valid config object");
}
if ('xtype' in config) {
newInstance = manager.instantiateByAlias('widget.' + config.xtype, config);
} else if ('xclass' in config) {
newInstance = Ext.create(config.xclass, config);
}
if (newInstance) {
if (instance) {
instance.destroy();
}
return newInstance;
}
if (instance) {
return instance.setConfig(config);
}
return Ext.create(classReference, config);
},
log: (function() {
var primitiveRe = /string|number|boolean/;
function dumpObject(object, level, maxLevel, withFunctions) {
var member, type, value, name, prefix, suffix,
members = [];
if (Ext.isArray(object)) {
prefix = '[';
suffix = ']';
} else if (Ext.isObject(object)) {
prefix = '{';
suffix = '}';
}
if (!maxLevel) {
maxLevel = 3;
}
if (level > maxLevel) {
return prefix + '...' + suffix;
}
level = level || 1;
var spacer = (new Array(level)).join(' ');
for (name in object) {
if (object.hasOwnProperty(name)) {
value = object[name];
type = typeof value;
if (type === 'function') {
if (!withFunctions) {
continue;
}
member = type;
} else if (type === 'undefined') {
member = type;
} else if (value === null || primitiveRe.test(type) || Ext.isDate(value)) {
member = Ext.encode(value);
} else if (Ext.isArray(value)) {
member = this.dumpObject(value, level + 1, maxLevel, withFunctions);
} else if (Ext.isObject(value)) {
member = this.dumpObject(value, level + 1, maxLevel, withFunctions);
} else {
member = type;
}
members.push(spacer + name + ': ' + member);
}
}
if (members.length) {
return prefix + '\n ' + members.join(',\n ') + '\n' + spacer + suffix;
}
return prefix + suffix;
}
function log(message) {
var options, dump,
con = Ext.global.console,
level = 'log',
indent = log.indent || 0,
prefix, stack, fn, out, max;
log.indent = indent;
if (typeof message !== 'string') {
options = message;
message = options.msg || '';
level = options.level || level;
dump = options.dump;
stack = options.stack;
prefix = options.prefix;
fn = options.fn;
if (options.indent) {
++log.indent;
} else if (options.outdent) {
log.indent = indent = Math.max(indent - 1, 0);
}
if (dump && !(con && con.dir)) {
message += dumpObject(dump);
dump = null;
}
}
if (arguments.length > 1) {
message += Array.prototype.slice.call(arguments, 1).join('');
}
if (prefix) {
message = prefix + ' - ' + message;
}
message = indent ? Ext.String.repeat(' ', log.indentSize * indent) + message : message;
if (level !== 'log') {
message = '[' + level.charAt(0).toUpperCase() + '] ' + message;
}
if (fn) {
message += '\nCaller: ' + fn.toString();
}
if (con) {
if (con[level]) {
con[level](message);
} else {
con.log(message);
}
if (dump) {
con.dir(dump);
}
if (stack && con.trace) {
if (!con.firebug || level !== 'error') {
con.trace();
}
}
} else if (Ext.isOpera) {
opera.postError(message);
} else
{
out = log.out;
max = log.max;
if (out.length >= max) {
Ext.Array.erase(out, 0, out.length - 3 * Math.floor(max / 4));
}
out.push(message);
}
++log.count;
++log.counters[level];
}
function logx(level, args) {
if (typeof args[0] === 'string') {
args.unshift({});
}
args[0].level = level;
log.apply(this, args);
}
log.error = function() {
logx('error', Array.prototype.slice.call(arguments));
};
log.info = function() {
logx('info', Array.prototype.slice.call(arguments));
};
log.warn = function() {
logx('warn', Array.prototype.slice.call(arguments));
};
log.count = 0;
log.counters = {
error: 0,
warn: 0,
info: 0,
log: 0
};
log.indentSize = 2;
log.out = [];
log.max = 750;
return log;
}()) || (function() {
var nullLog = function() {};
nullLog.info = nullLog.warn = nullLog.error = Ext.emptyFn;
return nullLog;
}())
});
(function() {
var
checkVerTemp = [
''
],
endOfVersionRe = /([^\d\.])/,
notDigitsRe = /[^\d]/g,
plusMinusRe = /[\-+]/g,
stripRe = /\s/g,
underscoreRe = /_/g,
Version;
Ext.Version = Version = function(version, defaultMode) {
var me = this,
padModes = me.padModes,
ch, i, pad, parts, release, releaseStartIndex, ver;
if (version.isVersion) {
version = version.version;
}
me.version = ver = String(version).toLowerCase().replace(underscoreRe, '.').replace(plusMinusRe, '');
ch = ver.charAt(0);
if (ch in padModes) {
ver = ver.substring(1);
pad = padModes[ch];
} else {
pad = defaultMode ? padModes[defaultMode] : 0;
}
me.pad = pad;
releaseStartIndex = ver.search(endOfVersionRe);
me.shortVersion = ver;
if (releaseStartIndex !== -1) {
me.release = release = ver.substr(releaseStartIndex, version.length);
me.shortVersion = ver.substr(0, releaseStartIndex);
release = Version.releaseValueMap[release] || release;
}
me.releaseValue = release || pad;
me.shortVersion = me.shortVersion.replace(notDigitsRe, '');
me.parts = parts = ver.split('.');
for (i = parts.length; i--; ) {
parts[i] = parseInt(parts[i], 10);
}
if (pad === Infinity) {
parts.push(pad);
}
me.major = parts[0] || pad;
me.minor = parts[1] || pad;
me.patch = parts[2] || pad;
me.build = parts[3] || pad;
return me;
};
Version.prototype = {
isVersion: true,
padModes: {
'~': NaN,
'^': Infinity
},
release: '',
compareTo: function(other) {
var me = this,
lhsPad = me.pad,
lhsParts = me.parts,
lhsLength = lhsParts.length,
rhsVersion = other.isVersion ? other : new Version(other),
rhsPad = rhsVersion.pad,
rhsParts = rhsVersion.parts,
rhsLength = rhsParts.length,
length = Math.max(lhsLength, rhsLength),
i, lhs, rhs;
for (i = 0; i < length; i++) {
lhs = (i < lhsLength) ? lhsParts[i] : lhsPad;
rhs = (i < rhsLength) ? rhsParts[i] : rhsPad;
if (lhs < rhs) {
return -1;
}
if (lhs > rhs) {
return 1;
}
}
lhs = me.releaseValue;
rhs = rhsVersion.releaseValue;
if (lhs < rhs) {
return -1;
}
if (lhs > rhs) {
return 1;
}
return 0;
},
toString: function() {
return this.version;
},
valueOf: function() {
return this.version;
},
getMajor: function() {
return this.major;
},
getMinor: function() {
return this.minor;
},
getPatch: function() {
return this.patch;
},
getBuild: function() {
return this.build;
},
getRelease: function() {
return this.release;
},
getReleaseValue: function() {
return this.releaseValue;
},
isGreaterThan: function(target) {
return this.compareTo(target) > 0;
},
isGreaterThanOrEqual: function(target) {
return this.compareTo(target) >= 0;
},
isLessThan: function(target) {
return this.compareTo(target) < 0;
},
isLessThanOrEqual: function(target) {
return this.compareTo(target) <= 0;
},
equals: function(target) {
return this.compareTo(target) === 0;
},
match: function(target) {
target = String(target);
return this.version.substr(0, target.length) === target;
},
toArray: function() {
var me = this;
return [
me.getMajor(),
me.getMinor(),
me.getPatch(),
me.getBuild(),
me.getRelease()
];
},
getShortVersion: function() {
return this.shortVersion;
},
gt: function(target) {
return this.compareTo(target) > 0;
},
lt: function(target) {
return this.compareTo(target) < 0;
},
gtEq: function(target) {
return this.compareTo(target) >= 0;
},
ltEq: function(target) {
return this.compareTo(target) <= 0;
}
};
Ext.apply(Version, {
aliases: {
from: {
extjs: 'ext',
core: 'sencha-core'
},
to: {
ext: [
'extjs'
],
'sencha-core': [
'core'
]
}
},
releaseValueMap: {
dev: -6,
alpha: -5,
a: -5,
beta: -4,
b: -4,
rc: -3,
'#': -2,
p: -1,
pl: -1
},
getComponentValue: function(value) {
return !value ? 0 : (isNaN(value) ? this.releaseValueMap[value] || value : parseInt(value, 10));
},
compare: function(current, target) {
var ver = current.isVersion ? current : new Version(current);
return ver.compareTo(target);
},
set: function(collection, packageName, version) {
var aliases = Version.aliases.to[packageName],
ver = version.isVersion ? version : new Version(version),
i;
collection[packageName] = ver;
if (aliases) {
for (i = aliases.length; i-- > 0; ) {
collection[aliases[i]] = ver;
}
}
return ver;
}
});
Ext.apply(Ext, {
compatVersions: {},
versions: {},
lastRegisteredVersion: null,
getCompatVersion: function(packageName) {
var versions = Ext.compatVersions,
compat;
if (!packageName) {
compat = versions.ext || versions.touch || versions.core;
} else {
compat = versions[Version.aliases.from[packageName] || packageName];
}
return compat || Ext.getVersion(packageName);
},
setCompatVersion: function(packageName, version) {
Version.set(Ext.compatVersions, packageName, version);
},
setVersion: function(packageName, version) {
Ext.lastRegisteredVersion = Version.set(Ext.versions, packageName, version);
return this;
},
getVersion: function(packageName) {
var versions = Ext.versions;
if (!packageName) {
return versions.ext || versions.touch || versions.core;
}
return versions[Version.aliases.from[packageName] || packageName];
},
checkVersion: function(specs, matchAll) {
var isArray = Ext.isArray(specs),
aliases = Version.aliases.from,
compat = isArray ? specs : checkVerTemp,
length = compat.length,
versions = Ext.versions,
frameworkVer = versions.ext || versions.touch,
i, index, matches, minVer, maxVer, packageName, spec, range, ver;
if (!isArray) {
checkVerTemp[0] = specs;
}
for (i = 0; i < length; ++i) {
if (!Ext.isString(spec = compat[i])) {
matches = Ext.checkVersion(spec.and || spec.or, !spec.or);
if (spec.not) {
matches = !matches;
}
} else {
if (spec.indexOf(' ') >= 0) {
spec = spec.replace(stripRe, '');
}
index = spec.indexOf('@');
if (index < 0) {
range = spec;
ver = frameworkVer;
} else {
packageName = spec.substring(0, index);
if (!(ver = versions[aliases[packageName] || packageName])) {
if (matchAll) {
return false;
}
continue;
}
range = spec.substring(index + 1);
}
index = range.indexOf('-');
if (index < 0) {
if (range.charAt(index = range.length - 1) === '+') {
minVer = range.substring(0, index);
maxVer = null;
} else {
minVer = maxVer = range;
}
} else if (index > 0) {
minVer = range.substring(0, index);
maxVer = range.substring(index + 1);
} else
{
minVer = null;
maxVer = range.substring(index + 1);
}
matches = true;
if (minVer) {
minVer = new Version(minVer, '~');
matches = minVer.ltEq(ver);
}
if (matches && maxVer) {
maxVer = new Version(maxVer, '~');
matches = maxVer.gtEq(ver);
}
}
if (matches) {
if (!matchAll) {
return true;
}
} else if (matchAll) {
return false;
}
}
return !!matchAll;
},
deprecate: function(packageName, since, closure, scope) {
if (Version.compare(Ext.getVersion(packageName), since) < 1) {
closure.call(scope);
}
}
});
}());
(function(manifest) {
var packages = (manifest && manifest.packages) || {},
compat = manifest && manifest.compatibility,
name, pkg;
for (name in packages) {
pkg = packages[name];
Ext.setVersion(name, pkg.version);
}
if (compat) {
if (Ext.isString(compat)) {
Ext.setCompatVersion('core', compat);
} else {
for (name in compat) {
Ext.setCompatVersion(name, compat[name]);
}
}
}
if (!packages.ext && !packages.touch) {
Ext.setVersion('ext','5.1.1.451');Ext.setVersion('sencha-core','5.1.1.451');
}
})(Ext.manifest);
Ext.Config = function(name) {
var me = this,
capitalizedName = name.charAt(0).toUpperCase() + name.substr(1);
me.name = name;
me.names = {
internal: '_' + name,
initializing: 'is' + capitalizedName + 'Initializing',
apply: 'apply' + capitalizedName,
update: 'update' + capitalizedName,
get: 'get' + capitalizedName,
set: 'set' + capitalizedName,
initGet: 'initGet' + capitalizedName,
doSet: 'doSet' + capitalizedName,
changeEvent: name.toLowerCase() + 'change'
};
me.root = me;
};
Ext.Config.map = {};
Ext.Config.get = function(name) {
var map = Ext.Config.map,
ret = map[name] || (map[name] = new Ext.Config(name));
return ret;
};
Ext.Config.prototype = {
self: Ext.Config,
isConfig: true,
getGetter: function() {
return this.getter || (this.root.getter = this.makeGetter());
},
getInitGetter: function() {
return this.initGetter || (this.root.initGetter = this.makeInitGetter());
},
getSetter: function() {
return this.setter || (this.root.setter = this.makeSetter());
},
getInternalName: function(target) {
return target.$configPrefixed ? this.names.internal : this.name;
},
mergeNew: function(newValue, oldValue, target, mixinClass) {
var ret, key;
if (!oldValue) {
ret = newValue;
} else if (!newValue) {
ret = oldValue;
} else {
ret = Ext.Object.chain(oldValue);
for (key in newValue) {
if (!mixinClass || !(key in ret)) {
ret[key] = newValue[key];
}
}
}
return ret;
},
mergeSets: function(newValue, oldValue, preserveExisting) {
var ret = oldValue ? Ext.Object.chain(oldValue) : {},
i, val;
if (newValue instanceof Array) {
for (i = newValue.length; i--; ) {
val = newValue[i];
if (!preserveExisting || !(val in ret)) {
ret[val] = true;
}
}
} else if (newValue) {
if (newValue.constructor === Object) {
for (i in newValue) {
val = newValue[i];
if (!preserveExisting || !(i in ret)) {
ret[i] = val;
}
}
} else if (!preserveExisting || !(newValue in ret)) {
ret[newValue] = true;
}
}
return ret;
},
makeGetter: function() {
var name = this.name,
prefixedName = this.names.internal;
return function() {
var internalName = this.$configPrefixed ? prefixedName : name;
return this[internalName];
};
},
makeInitGetter: function() {
var name = this.name,
names = this.names,
setName = names.set,
getName = names.get,
initializingName = names.initializing;
return function() {
var me = this;
me[initializingName] = true;
delete me[getName];
me[setName](me.config[name]);
delete me[initializingName];
return me[getName].apply(me, arguments);
};
},
makeSetter: function() {
var name = this.name,
names = this.names,
prefixedName = names.internal,
getName = names.get,
applyName = names.apply,
updateName = names.update,
setter;
setter = function(value) {
var me = this,
internalName = me.$configPrefixed ? prefixedName : name,
oldValue = me[internalName];
delete me[getName];
if (!me[applyName] || (value = me[applyName](value, oldValue)) !== undefined) {
if (value !== (oldValue = me[internalName])) {
me[internalName] = value;
if (me[updateName]) {
me[updateName](value, oldValue);
}
}
}
return me;
};
setter.$isDefault = true;
return setter;
}
};
(function() {
var ExtConfig = Ext.Config,
configPropMap = ExtConfig.map,
ExtObject = Ext.Object;
Ext.Configurator = function(cls) {
var me = this,
prototype = cls.prototype,
zuper = cls.superclass ? cls.superclass.self.$config : null;
me.cls = cls;
if (zuper) {
me.configs = ExtObject.chain(zuper.configs);
me.cachedConfigs = ExtObject.chain(zuper.cachedConfigs);
me.initMap = ExtObject.chain(zuper.initMap);
me.values = ExtObject.chain(zuper.values);
me.needsFork = zuper.needsFork;
} else {
me.configs = {};
me.cachedConfigs = {};
me.initMap = {};
me.values = {};
}
prototype.config = prototype.defaultConfig = me.values;
cls.$config = me;
};
Ext.Configurator.prototype = {
self: Ext.Configurator,
needsFork: false,
initList: null,
add: function(config, mixinClass) {
var me = this,
Cls = me.cls,
configs = me.configs,
cachedConfigs = me.cachedConfigs,
initMap = me.initMap,
prototype = Cls.prototype,
mixinConfigs = mixinClass && mixinClass.$config.configs,
values = me.values,
isObject, meta, isCached, merge, cfg, currentValue, name, names, s, value;
for (name in config) {
value = config[name];
isObject = value && value.constructor === Object;
meta = isObject && '$value' in value ? value : null;
if (meta) {
isCached = !!meta.cached;
value = meta.$value;
isObject = value && value.constructor === Object;
}
merge = meta && meta.merge;
cfg = configs[name];
if (cfg) {
if (mixinClass) {
merge = cfg.merge;
if (!merge) {
continue;
}
meta = null;
} else {
merge = merge || cfg.merge;
}
if (!mixinClass && isCached && !cachedConfigs[name]) {
Ext.Error.raise('Redefining config as cached: ' + name + ' in class: ' + Cls.$className);
}
currentValue = values[name];
if (merge) {
value = merge.call(cfg, value, currentValue, Cls, mixinClass);
} else if (isObject) {
if (currentValue && currentValue.constructor === Object) {
value = ExtObject.merge({}, currentValue, value);
}
}
} else
{
if (mixinConfigs) {
cfg = mixinConfigs[name];
meta = null;
} else {
cfg = ExtConfig.get(name);
}
configs[name] = cfg;
if (cfg.cached || isCached) {
cachedConfigs[name] = true;
}
names = cfg.names;
if (!prototype[s = names.get]) {
prototype[s] = cfg.getGetter();
}
if (!prototype[s = names.set]) {
prototype[s] = cfg.getSetter();
}
}
if (meta) {
if (cfg.owner !== Cls) {
configs[name] = cfg = Ext.Object.chain(cfg);
cfg.owner = Cls;
}
Ext.apply(cfg, meta);
delete cfg.$value;
}
if (!me.needsFork && value && (value.constructor === Object || value instanceof Array)) {
me.needsFork = true;
}
if (value !== null) {
initMap[name] = true;
} else {
if (prototype.$configPrefixed) {
prototype[configs[name].names.internal] = null;
} else {
prototype[configs[name].name] = null;
}
if (name in initMap) {
initMap[name] = false;
}
}
values[name] = value;
}
},
configure: function(instance, instanceConfig) {
var me = this,
configs = me.configs,
initMap = me.initMap,
initListMap = me.initListMap,
initList = me.initList,
prototype = me.cls.prototype,
values = me.values,
remaining = 0,
firstInstance = !initList,
cachedInitList, cfg, getter, needsInit, i, internalName, ln, names, name, value, isCached, valuesKey;
values = me.needsFork ? ExtObject.fork(values) : ExtObject.chain(values);
if (firstInstance) {
me.initList = initList = [];
me.initListMap = initListMap = {};
instance.isFirstInstance = true;
for (name in initMap) {
needsInit = initMap[name];
cfg = configs[name];
isCached = cfg.cached;
if (needsInit) {
names = cfg.names;
value = values[name];
if (!prototype[names.set].$isDefault || prototype[names.apply] || prototype[names.update] || typeof value === 'object') {
if (isCached) {
(cachedInitList || (cachedInitList = [])).push(cfg);
} else {
initList.push(cfg);
initListMap[name] = true;
}
instance[names.get] = cfg.initGetter || cfg.getInitGetter();
} else {
prototype[cfg.getInternalName(prototype)] = value;
}
} else if (isCached) {
prototype[cfg.getInternalName(prototype)] = undefined;
}
}
}
ln = cachedInitList && cachedInitList.length;
if (ln) {
for (i = 0; i < ln; ++i) {
internalName = cachedInitList[i].getInternalName(prototype);
instance[internalName] = null;
}
for (i = 0; i < ln; ++i) {
names = (cfg = cachedInitList[i]).names;
getter = names.get;
if (instance.hasOwnProperty(getter)) {
instance[names.set](values[cfg.name]);
delete instance[getter];
}
}
for (i = 0; i < ln; ++i) {
internalName = cachedInitList[i].getInternalName(prototype);
prototype[internalName] = instance[internalName];
delete instance[internalName];
}
}
if (instanceConfig && instanceConfig.platformConfig) {
instanceConfig = me.resolvePlatformConfig(instance, instanceConfig);
}
if (firstInstance) {
if (instance.afterCachedConfig && !instance.afterCachedConfig.$nullFn) {
instance.afterCachedConfig(instanceConfig);
}
}
instance.isConfiguring = true;
instance.config = values;
for (i = 0 , ln = initList.length; i < ln; ++i) {
cfg = initList[i];
instance[cfg.names.get] = cfg.initGetter || cfg.getInitGetter();
}
if (instance.transformInstanceConfig) {
instanceConfig = instance.transformInstanceConfig(instanceConfig);
}
if (instanceConfig) {
for (name in instanceConfig) {
value = instanceConfig[name];
cfg = configs[name];
if (!cfg) {
if (instance.$configStrict && typeof instance.self.prototype[name] === 'function') {
Ext.Error.raise("Cannot override method " + name + " on " + instance.$className + " instance.");
}
instance[name] = value;
} else {
if (!cfg.lazy) {
++remaining;
}
if (!initListMap[name]) {
instance[cfg.names.get] = cfg.initGetter || cfg.getInitGetter();
}
if (cfg.merge) {
value = cfg.merge(value, values[name], instance);
} else if (value && value.constructor === Object) {
valuesKey = values[name];
if (valuesKey && valuesKey.constructor === Object) {
value = ExtObject.merge(values[name], value);
} else {
value = Ext.clone(value);
}
}
}
values[name] = value;
}
}
if (instance.beforeInitConfig && !instance.beforeInitConfig.$nullFn) {
if (instance.beforeInitConfig(instanceConfig) === false) {
return;
}
}
if (instanceConfig) {
for (name in instanceConfig) {
if (!remaining) {
break;
}
cfg = configs[name];
if (cfg && !cfg.lazy) {
--remaining;
names = cfg.names;
getter = names.get;
if (instance.hasOwnProperty(getter)) {
instance[names.set](values[name]);
delete instance[names.get];
}
}
}
}
for (i = 0 , ln = initList.length; i < ln; ++i) {
cfg = initList[i];
names = cfg.names;
getter = names.get;
if (!cfg.lazy && instance.hasOwnProperty(getter)) {
instance[names.set](values[cfg.name]);
delete instance[getter];
}
}
delete instance.isConfiguring;
},
getCurrentConfig: function(instance) {
var defaultConfig = instance.defaultConfig,
config = {},
name;
for (name in defaultConfig) {
config[name] = instance[configPropMap[name].names.get]();
}
return config;
},
merge: function(instance, baseConfig, config) {
var configs = this.configs,
name, value, baseValue, cfg;
for (name in config) {
value = config[name];
cfg = configs[name];
if (cfg) {
if (cfg.merge) {
value = cfg.merge(value, baseConfig[name], instance);
} else if (value && value.constructor === Object) {
baseValue = baseConfig[name];
if (baseValue && baseValue.constructor === Object) {
value = Ext.Object.merge(baseValue, value);
} else {
value = Ext.clone(value);
}
}
}
baseConfig[name] = value;
}
return baseConfig;
},
reconfigure: function(instance, instanceConfig, options) {
var currentConfig = instance.config,
configList = [],
strict = instance.$configStrict,
configs = this.configs,
defaults = options && options.defaults,
applyProps = options && options.strict === false,
cfg, getter, i, len, name, names, setter;
for (name in instanceConfig) {
if (defaults && instance.hasOwnProperty(name)) {
continue;
}
currentConfig[name] = instanceConfig[name];
cfg = configs[name];
if (cfg) {
instance[cfg.names.get] = cfg.initGetter || cfg.getInitGetter();
} else if (strict) {
if (name !== 'type') {
Ext.log.error('No such config "' + name + '" for class ' + instance.$className);
}
continue;
}
configList.push(name);
}
for (i = 0 , len = configList.length; i < len; i++) {
name = configList[i];
cfg = configs[name];
if (cfg) {
names = cfg.names;
getter = names.get;
if (instance.hasOwnProperty(getter)) {
instance[names.set](instanceConfig[name]);
delete instance[getter];
}
} else {
cfg = configPropMap[name] || Ext.Config.get(name);
names = cfg.names;
if (instance[names.set]) {
instance[names.set](instanceConfig[name]);
} else if (applyProps) {
if (instance.$configStrict && typeof instance.self.prototype[name] === 'function') {
Ext.Error.raise("Cannot override method " + name + " on " + instance.$className + " instance.");
}
instance[name] = instanceConfig[name];
} else if (name !== 'type') {
Ext.Error.raise('Config "' + name + '" has no setter on class ' + instance.$className);
}
}
}
},
resolvePlatformConfig: function(instance, instanceConfig) {
var platformConfig = instanceConfig && instanceConfig.platformConfig,
ret = instanceConfig,
i, keys, n;
if (platformConfig) {
keys = Ext.getPlatformConfigKeys(platformConfig);
n = keys.length;
if (n) {
ret = Ext.merge({}, ret);
for (i = 0 , n = keys.length; i < n; ++i) {
this.merge(instance, ret, platformConfig[keys[i]]);
}
}
}
return ret;
}
};
}());
Ext.Base = (function(flexSetter) {
var noArgs = [],
baseStaticMember,
baseStaticMembers = [],
getConfig = function(name, peek) {
var me = this,
ret, cfg, getterName;
if (name) {
cfg = Ext.Config.map[name];
if (!cfg) {
Ext.Logger.error("Invalid property name for getter: '" + name + "' for '" + me.$className + "'.");
}
getterName = cfg.names.get;
if (peek && me.hasOwnProperty(getterName)) {
ret = me.config[name];
} else {
ret = me[getterName]();
}
} else {
ret = me.getCurrentConfig();
}
return ret;
},
makeDeprecatedMethod = function(oldName, newName, msg) {
var message = '"' + oldName + '" is deprecated.';
if (msg) {
message += ' ' + msg;
} else if (newName) {
message += ' Please use "' + newName + '" instead.';
}
return function() {
Ext.Error.raise(message);
};
},
addDeprecatedProperty = function(object, oldName, newName, message) {
if (!message) {
message = '"' + oldName + '" is deprecated.';
}
if (newName) {
message += ' Please use "' + newName + '" instead.';
}
if (message) {
Ext.Object.defineProperty(object, oldName, {
get: function() {
Ext.Error.raise(message);
},
set: function(value) {
Ext.Error.raise(message);
},
configurable: true
});
}
},
makeAliasFn = function(name) {
return function() {
return this[name].apply(this, arguments);
};
},
Version = Ext.Version,
leadingDigitRe = /^\d/,
oneMember = {},
aliasOneMember = {},
Base = function() {},
BasePrototype = Base.prototype;
Ext.apply(Base, {
$className: 'Ext.Base',
$isClass: true,
create: function() {
return Ext.create.apply(Ext, [
this
].concat(Array.prototype.slice.call(arguments, 0)));
},
addDeprecations: function(deprecations) {
var me = this,
all = [],
compatVersion = Ext.getCompatVersion(deprecations.name),
displayName = (me.$className || '') + '#',
deprecate, versionSpec, index, message, target, enabled, existing, fn, names, oldName, newName, member, statics, version;
for (versionSpec in deprecations) {
if (leadingDigitRe.test(versionSpec)) {
version = new Ext.Version(versionSpec);
version.deprecations = deprecations[versionSpec];
all.push(version);
}
}
all.sort(Version.compare);
for (index = all.length; index--; ) {
deprecate = (version = all[index]).deprecations;
target = me.prototype;
statics = deprecate.statics;
enabled = compatVersion && compatVersion.lt(version);
if (!enabled) {} else if (!enabled) {
break;
}
while (deprecate) {
names = deprecate.methods;
if (names) {
for (oldName in names) {
member = names[oldName];
fn = null;
if (!member) {
Ext.Assert.isNotDefinedProp(target, oldName);
fn = makeDeprecatedMethod(displayName + oldName);
} else if (Ext.isString(member)) {
Ext.Assert.isNotDefinedProp(target, oldName);
Ext.Assert.isDefinedProp(target, member);
if (enabled) {
fn = makeAliasFn(member);
} else {
fn = makeDeprecatedMethod(displayName + oldName, member);
}
} else {
message = '';
if (member.message || member.fn) {
message = member.message;
member = member.fn;
}
existing = target.hasOwnProperty(oldName) && target[oldName];
if (enabled && member) {
member.$owner = me;
member.$name = oldName;
member.name = displayName + oldName;
if (existing) {
member.$previous = existing;
}
fn = member;
} else if (!existing) {
fn = makeDeprecatedMethod(displayName + oldName, null, message);
}
}
if (fn) {
target[oldName] = fn;
}
}
}
names = deprecate.properties;
if (names && !enabled) {
for (oldName in names) {
newName = names[oldName];
if (Ext.isString(newName)) {
addDeprecatedProperty(target, displayName + oldName, newName);
} else if (newName && newName.message) {
addDeprecatedProperty(target, displayName + oldName, null, newName.message);
} else {
addDeprecatedProperty(target, displayName + oldName);
}
}
}
deprecate = statics;
statics = null;
target = me;
}
}
},
extend: function(parent) {
var me = this,
parentPrototype = parent.prototype,
prototype, i, ln, name, statics;
prototype = me.prototype = Ext.Object.chain(parentPrototype);
prototype.self = me;
me.superclass = prototype.superclass = parentPrototype;
if (!parent.$isClass) {
for (i in BasePrototype) {
if (i in prototype) {
prototype[i] = BasePrototype[i];
}
}
}
statics = parentPrototype.$inheritableStatics;
if (statics) {
for (i = 0 , ln = statics.length; i < ln; i++) {
name = statics[i];
if (!me.hasOwnProperty(name)) {
me[name] = parent[name];
}
}
}
if (parent.$onExtended) {
me.$onExtended = parent.$onExtended.slice();
}
me.getConfigurator();
},
$onExtended: [],
triggerExtended: function() {
Ext.classSystemMonitor && Ext.classSystemMonitor(this, 'Ext.Base#triggerExtended', arguments);
var callbacks = this.$onExtended,
ln = callbacks.length,
i, callback;
if (ln > 0) {
for (i = 0; i < ln; i++) {
callback = callbacks[i];
callback.fn.apply(callback.scope || this, arguments);
}
}
},
onExtended: function(fn, scope) {
this.$onExtended.push({
fn: fn,
scope: scope
});
return this;
},
addStatics: function(members) {
this.addMembers(members, true);
return this;
},
addInheritableStatics: function(members) {
var inheritableStatics, hasInheritableStatics,
prototype = this.prototype,
name, member;
inheritableStatics = prototype.$inheritableStatics;
hasInheritableStatics = prototype.$hasInheritableStatics;
if (!inheritableStatics) {
inheritableStatics = prototype.$inheritableStatics = [];
hasInheritableStatics = prototype.$hasInheritableStatics = {};
}
var className = Ext.getClassName(this) + '.';
for (name in members) {
if (members.hasOwnProperty(name)) {
member = members[name];
if (typeof member == 'function') {
member.name = className + name;
}
this[name] = member;
if (!hasInheritableStatics[name]) {
hasInheritableStatics[name] = true;
inheritableStatics.push(name);
}
}
}
return this;
},
addMembers: function(members, isStatic, privacy) {
var me = this,
cloneFunction = Ext.Function.clone,
target = isStatic ? me : me.prototype,
defaultConfig = !isStatic && target.defaultConfig,
enumerables = Ext.enumerables,
privates = members.privates,
configs, i, ln, member, name, subPrivacy, privateStatics;
var displayName = (me.$className || '') + '#';
if (privates) {
delete members.privates;
if (!isStatic) {
privateStatics = privates.statics;
delete privates.statics;
}
subPrivacy = privates.privacy || privacy || 'framework';
me.addMembers(privates, isStatic, subPrivacy);
if (privateStatics) {
me.addMembers(privateStatics, true, subPrivacy);
}
}
for (name in members) {
if (members.hasOwnProperty(name)) {
member = members[name];
if (privacy === true) {
privacy = 'framework';
}
if (member && member.$nullFn && privacy !== member.$privacy) {
Ext.Error.raise('Cannot use stock function for private method ' + (me.$className ? me.$className + '#' : '') + name);
}
if (typeof member === 'function' && !member.$isClass && !member.$nullFn) {
if (member.$owner) {
member = cloneFunction(member);
}
if (target.hasOwnProperty(name)) {
member.$previous = target[name];
}
member.$owner = me;
member.$name = name;
member.name = displayName + name;
var existing = target[name];
if (privacy) {
member.$privacy = privacy;
if (existing && existing.$privacy && existing.$privacy !== privacy) {
Ext.privacyViolation(me, existing, member, isStatic);
}
} else if (existing && existing.$privacy) {
Ext.privacyViolation(me, existing, member, isStatic);
}
}
else if (defaultConfig && (name in defaultConfig) && !target.config.hasOwnProperty(name)) {
(configs || (configs = {}))[name] = member;
continue;
}
target[name] = member;
}
}
if (configs) {
me.addConfig(configs);
}
if (enumerables) {
for (i = 0 , ln = enumerables.length; i < ln; ++i) {
if (members.hasOwnProperty(name = enumerables[i])) {
member = members[name];
if (member && !member.$nullFn) {
if (member.$owner) {
member = cloneFunction(member);
}
member.$owner = me;
member.$name = name;
member.name = displayName + name;
if (target.hasOwnProperty(name)) {
member.$previous = target[name];
}
}
target[name] = member;
}
}
}
return this;
},
addMember: function(name, member) {
oneMember[name] = member;
this.addMembers(oneMember);
delete oneMember[name];
return this;
},
borrow: function(fromClass, members) {
Ext.classSystemMonitor && Ext.classSystemMonitor(this, 'Ext.Base#borrow', arguments);
var prototype = fromClass.prototype,
membersObj = {},
i, ln, name;
members = Ext.Array.from(members);
for (i = 0 , ln = members.length; i < ln; i++) {
name = members[i];
membersObj[name] = prototype[name];
}
return this.addMembers(membersObj);
},
override: function(members) {
var me = this,
statics = members.statics,
inheritableStatics = members.inheritableStatics,
config = members.config,
mixins = members.mixins,
cachedConfig = members.cachedConfig;
if (statics || inheritableStatics || config) {
members = Ext.apply({}, members);
}
if (statics) {
me.addMembers(statics, true);
delete members.statics;
}
if (inheritableStatics) {
me.addInheritableStatics(inheritableStatics);
delete members.inheritableStatics;
}
if (config) {
me.addConfig(config);
delete members.config;
}
if (cachedConfig) {
me.addCachedConfig(cachedConfig);
delete members.cachedConfig;
}
delete members.mixins;
me.addMembers(members);
if (mixins) {
me.mixin(mixins);
}
return me;
},
callParent: function(args) {
var method;
return (method = this.callParent.caller) && (method.$previous || ((method = method.$owner ? method : method.caller) && method.$owner.superclass.self[method.$name])).apply(this, args || noArgs);
},
callSuper: function(args) {
var method;
return (method = this.callSuper.caller) && ((method = method.$owner ? method : method.caller) && method.$owner.superclass.self[method.$name]).apply(this, args || noArgs);
},
mixin: function(name, mixinClass) {
var me = this,
mixin, prototype, key, statics, i, ln, staticName, mixinValue, mixins;
if (typeof name !== 'string') {
mixins = name;
if (mixins instanceof Array) {
for (i = 0 , ln = mixins.length; i < ln; i++) {
mixin = mixins[i];
me.mixin(mixin.prototype.mixinId || mixin.$className, mixin);
}
} else {
for (var mixinName in mixins) {
me.mixin(mixinName, mixins[mixinName]);
}
}
return;
}
mixin = mixinClass.prototype;
prototype = me.prototype;
if (mixin.onClassMixedIn) {
mixin.onClassMixedIn.call(mixinClass, me);
}
if (!prototype.hasOwnProperty('mixins')) {
if ('mixins' in prototype) {
prototype.mixins = Ext.Object.chain(prototype.mixins);
} else {
prototype.mixins = {};
}
}
for (key in mixin) {
mixinValue = mixin[key];
if (key === 'mixins') {
Ext.applyIf(prototype.mixins, mixinValue);
} else if (!(key === 'mixinId' || key === 'config') && (prototype[key] === undefined)) {
prototype[key] = mixinValue;
}
}
statics = mixin.$inheritableStatics;
if (statics) {
for (i = 0 , ln = statics.length; i < ln; i++) {
staticName = statics[i];
if (!me.hasOwnProperty(staticName)) {
me[staticName] = mixinClass[staticName];
}
}
}
if ('config' in mixin) {
me.addConfig(mixin.config, mixinClass);
}
prototype.mixins[name] = mixin;
if (mixin.afterClassMixedIn) {
mixin.afterClassMixedIn.call(mixinClass, me);
}
return me;
},
addConfig: function(config, mixinClass) {
var cfg = this.$config || this.getConfigurator();
cfg.add(config, mixinClass);
},
addCachedConfig: function(config, isMixin) {
var cached = {},
key;
for (key in config) {
cached[key] = {
cached: true,
$value: config[key]
};
}
this.addConfig(cached, isMixin);
},
getConfigurator: function() {
return this.$config || new Ext.Configurator(this);
},
getName: function() {
return Ext.getClassName(this);
},
createAlias: flexSetter(function(alias, origin) {
aliasOneMember[alias] = function() {
return this[origin].apply(this, arguments);
};
this.override(aliasOneMember);
delete aliasOneMember[alias];
})
});
for (baseStaticMember in Base) {
if (Base.hasOwnProperty(baseStaticMember)) {
baseStaticMembers.push(baseStaticMember);
}
}
Base.$staticMembers = baseStaticMembers;
Base.getConfigurator();
Base.addMembers({
$className: 'Ext.Base',
isInstance: true,
$configPrefixed: true,
$configStrict: true,
isConfiguring: false,
isFirstInstance: false,
statics: function() {
var method = this.statics.caller,
self = this.self;
if (!method) {
return self;
}
return method.$owner;
},
callParent: function(args) {
var method,
superMethod = (method = this.callParent.caller) && (method.$previous || ((method = method.$owner ? method : method.caller) && method.$owner.superclass[method.$name]));
if (!superMethod) {
method = this.callParent.caller;
var parentClass, methodName;
if (!method.$owner) {
if (!method.caller) {
throw new Error("Attempting to call a protected method from the public scope, which is not allowed");
}
method = method.caller;
}
parentClass = method.$owner.superclass;
methodName = method.$name;
if (!(methodName in parentClass)) {
throw new Error("this.callParent() was called but there's no such method (" + methodName + ") found in the parent class (" + (Ext.getClassName(parentClass) || 'Object') + ")");
}
}
return superMethod.apply(this, args || noArgs);
},
callSuper: function(args) {
var method,
superMethod = (method = this.callSuper.caller) && ((method = method.$owner ? method : method.caller) && method.$owner.superclass[method.$name]);
if (!superMethod) {
method = this.callSuper.caller;
var parentClass, methodName;
if (!method.$owner) {
if (!method.caller) {
throw new Error("Attempting to call a protected method from the public scope, which is not allowed");
}
method = method.caller;
}
parentClass = method.$owner.superclass;
methodName = method.$name;
if (!(methodName in parentClass)) {
throw new Error("this.callSuper() was called but there's no such method (" + methodName + ") found in the parent class (" + (Ext.getClassName(parentClass) || 'Object') + ")");
}
}
return superMethod.apply(this, args || noArgs);
},
self: Base,
constructor: function() {
return this;
},
getConfigurator: function() {
return this.$config || this.self.getConfigurator();
},
initConfig: function(instanceConfig) {
var me = this,
cfg = me.getConfigurator();
me.initConfig = Ext.emptyFn;
me.initialConfig = instanceConfig || {};
cfg.configure(me, instanceConfig);
return me;
},
beforeInitConfig: Ext.emptyFn,
getConfig: getConfig,
setConfig: function(name, value,
options) {
var me = this,
config;
if (name) {
if (typeof name === 'string') {
config = {};
config[name] = value;
} else {
config = name;
}
me.getConfigurator().reconfigure(me, config, options);
}
return me;
},
getCurrentConfig: function() {
var cfg = this.getConfigurator();
return cfg.getCurrentConfig(this);
},
hasConfig: function(name) {
return name in this.defaultConfig;
},
getInitialConfig: function(name) {
var config = this.config;
if (!name) {
return config;
}
return config[name];
},
$links: null,
link: function(name, value) {
var me = this,
links = me.$links || (me.$links = {});
links[name] = true;
me[name] = value;
return value;
},
unlink: function(names) {
var me = this,
i, ln, link, value;
if (!Ext.isArray(names)) {
Ext.Error.raise('Invalid argument - expected array of strings');
}
for (i = 0 , ln = names.length; i < ln; i++) {
link = names[i];
value = me[link];
if (value) {
if (value.isInstance && !value.isDestroyed) {
value.destroy();
} else if (value.parentNode && 'nodeType' in value) {
value.parentNode.removeChild(value);
}
}
me[link] = null;
}
return me;
},
destroy: function() {
var me = this,
links = me.$links;
me.destroy = Ext.emptyFn;
me.isDestroyed = true;
if (links) {
me.$links = null;
me.unlink(Ext.Object.getKeys(links));
}
}
});
BasePrototype.callOverridden = BasePrototype.callParent;
Ext.privacyViolation = function(cls, existing, member, isStatic) {
var name = member.$name,
conflictCls = existing.$owner && existing.$owner.$className,
s = isStatic ? 'static ' : '',
msg = member.$privacy ? 'Private ' + s + member.$privacy + ' method "' + name + '"' : 'Public ' + s + 'method "' + name + '"';
if (cls.$className) {
msg = cls.$className + ': ' + msg;
}
if (!existing.$privacy) {
msg += conflictCls ? ' hides public method inherited from ' + conflictCls : ' hides inherited public method.';
} else {
msg += conflictCls ? ' conflicts with private ' + existing.$privacy + ' method declared by ' + conflictCls : ' conflicts with inherited private ' + existing.$privacy + ' method.';
}
var compat = Ext.getCompatVersion();
var ver = Ext.getVersion();
if (ver && compat && compat.lt(ver)) {
Ext.log.error(msg);
} else {
Ext.Error.raise(msg);
}
};
return Base;
}(Ext.Function.flexSetter));
(function(Cache, prototype) {
(Ext.util || (Ext.util = {})).Cache = Cache = function(config) {
var me = this,
head;
if (config) {
Ext.apply(me, config);
}
me.head = head = {
id: (me.seed = 0),
key: null,
value: null
};
me.map = {};
head.next = head.prev = head;
};
Cache.prototype = prototype = {
maxSize: 100,
count: 0,
clear: function() {
var me = this,
head = me.head,
entry = head.next;
head.next = head.prev = head;
if (!me.evict.$nullFn) {
for (; entry !== head; entry = entry.next) {
me.evict(entry.key, entry.value);
}
}
me.count = 0;
},
each: function(fn, scope) {
scope = scope || this;
for (var head = this.head,
ent = head.next; ent !== head; ent = ent.next) {
if (fn.call(scope, ent.key, ent.value)) {
break;
}
}
},
get: function(key) {
var me = this,
head = me.head,
map = me.map,
entry = map[key];
if (entry) {
if (entry.prev !== head) {
me.unlinkEntry(entry);
me.linkEntry(entry);
}
} else {
map[key] = entry = {
id: ++me.seed,
key: key,
value: me.miss.apply(me, arguments)
};
me.linkEntry(entry);
++me.count;
while (me.count > me.maxSize) {
me.unlinkEntry(head.prev, true);
--me.count;
}
}
return entry.value;
},
evict: Ext.emptyFn,
linkEntry: function(entry) {
var head = this.head,
first = head.next;
entry.next = first;
entry.prev = head;
head.next = entry;
first.prev = entry;
},
unlinkEntry: function(entry, evicted) {
var next = entry.next,
prev = entry.prev;
prev.next = next;
next.prev = prev;
if (evicted) {
this.evict(entry.key, entry.value);
}
}
};
prototype.destroy = prototype.clear;
}());
(function() {
var ExtClass,
Base = Ext.Base,
baseStaticMembers = Base.$staticMembers,
ruleKeySortFn = function(a, b) {
return (a.length - b.length) || ((a < b) ? -1 : ((a > b) ? 1 : 0));
};
function makeCtor(className) {
function constructor() {
return this.constructor.apply(this, arguments) || null;
}
if (className) {
constructor.name = className;
}
return constructor;
}
Ext.Class = ExtClass = function(Class, data, onCreated) {
if (typeof Class != 'function') {
onCreated = data;
data = Class;
Class = null;
}
if (!data) {
data = {};
}
Class = ExtClass.create(Class, data);
ExtClass.process(Class, data, onCreated);
return Class;
};
Ext.apply(ExtClass, {
makeCtor: makeCtor,
onBeforeCreated: function(Class, data, hooks) {
Ext.classSystemMonitor && Ext.classSystemMonitor(Class, '>> Ext.Class#onBeforeCreated', arguments);
Class.addMembers(data);
hooks.onCreated.call(Class, Class);
Ext.classSystemMonitor && Ext.classSystemMonitor(Class, '<< Ext.Class#onBeforeCreated', arguments);
},
create: function(Class, data) {
var i = baseStaticMembers.length,
name;
if (!Class) {
Class = makeCtor(data.$className);
}
while (i--) {
name = baseStaticMembers[i];
Class[name] = Base[name];
}
return Class;
},
process: function(Class, data, onCreated) {
var preprocessorStack = data.preprocessors || ExtClass.defaultPreprocessors,
registeredPreprocessors = this.preprocessors,
hooks = {
onBeforeCreated: this.onBeforeCreated
},
preprocessors = [],
preprocessor, preprocessorsProperties, i, ln, j, subLn, preprocessorProperty;
delete data.preprocessors;
Class._classHooks = hooks;
for (i = 0 , ln = preprocessorStack.length; i < ln; i++) {
preprocessor = preprocessorStack[i];
if (typeof preprocessor == 'string') {
preprocessor = registeredPreprocessors[preprocessor];
preprocessorsProperties = preprocessor.properties;
if (preprocessorsProperties === true) {
preprocessors.push(preprocessor.fn);
} else if (preprocessorsProperties) {
for (j = 0 , subLn = preprocessorsProperties.length; j < subLn; j++) {
preprocessorProperty = preprocessorsProperties[j];
if (data.hasOwnProperty(preprocessorProperty)) {
preprocessors.push(preprocessor.fn);
break;
}
}
}
} else {
preprocessors.push(preprocessor);
}
}
hooks.onCreated = onCreated ? onCreated : Ext.emptyFn;
hooks.preprocessors = preprocessors;
this.doProcess(Class, data, hooks);
},
doProcess: function(Class, data, hooks) {
var me = this,
preprocessors = hooks.preprocessors,
preprocessor = preprocessors.shift(),
doProcess = me.doProcess;
for (; preprocessor; preprocessor = preprocessors.shift()) {
if (preprocessor.call(me, Class, data, hooks, doProcess) === false) {
return;
}
}
hooks.onBeforeCreated.apply(me, arguments);
},
preprocessors: {},
registerPreprocessor: function(name, fn, properties, position, relativeTo) {
if (!position) {
position = 'last';
}
if (!properties) {
properties = [
name
];
}
this.preprocessors[name] = {
name: name,
properties: properties || false,
fn: fn
};
this.setDefaultPreprocessorPosition(name, position, relativeTo);
return this;
},
getPreprocessor: function(name) {
return this.preprocessors[name];
},
getPreprocessors: function() {
return this.preprocessors;
},
defaultPreprocessors: [],
getDefaultPreprocessors: function() {
return this.defaultPreprocessors;
},
setDefaultPreprocessors: function(preprocessors) {
this.defaultPreprocessors = Ext.Array.from(preprocessors);
return this;
},
setDefaultPreprocessorPosition: function(name, offset, relativeName) {
var defaultPreprocessors = this.defaultPreprocessors,
index;
if (typeof offset == 'string') {
if (offset === 'first') {
defaultPreprocessors.unshift(name);
return this;
} else if (offset === 'last') {
defaultPreprocessors.push(name);
return this;
}
offset = (offset === 'after') ? 1 : -1;
}
index = Ext.Array.indexOf(defaultPreprocessors, relativeName);
if (index !== -1) {
Ext.Array.splice(defaultPreprocessors, Math.max(0, index + offset), 0, name);
}
return this;
}
});
ExtClass.registerPreprocessor('extend', function(Class, data, hooks) {
Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#extendPreProcessor', arguments);
var Base = Ext.Base,
basePrototype = Base.prototype,
extend = data.extend,
Parent, parentPrototype, i;
delete data.extend;
if (extend && extend !== Object) {
Parent = extend;
} else {
Parent = Base;
}
parentPrototype = Parent.prototype;
if (!Parent.$isClass) {
for (i in basePrototype) {
if (!parentPrototype[i]) {
parentPrototype[i] = basePrototype[i];
}
}
}
Class.extend(Parent);
Class.triggerExtended.apply(Class, arguments);
if (data.onClassExtended) {
Class.onExtended(data.onClassExtended, Class);
delete data.onClassExtended;
}
}, true);
ExtClass.registerPreprocessor('privates', function(Class, data) {
Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#privatePreprocessor', arguments);
var privates = data.privates,
statics = privates.statics,
privacy = privates.privacy || true;
delete data.privates;
delete privates.statics;
Class.addMembers(privates, false, privacy);
if (statics) {
Class.addMembers(statics, true, privacy);
}
});
ExtClass.registerPreprocessor('statics', function(Class, data) {
Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#staticsPreprocessor', arguments);
Class.addStatics(data.statics);
delete data.statics;
});
ExtClass.registerPreprocessor('inheritableStatics', function(Class, data) {
Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#inheritableStaticsPreprocessor', arguments);
Class.addInheritableStatics(data.inheritableStatics);
delete data.inheritableStatics;
});
Ext.createRuleFn = function(code) {
return new Function('$c', 'with($c) { return (' + code + '); }');
};
Ext.expressionCache = new Ext.util.Cache({
miss: Ext.createRuleFn
});
Ext.ruleKeySortFn = ruleKeySortFn;
Ext.getPlatformConfigKeys = function(platformConfig) {
var ret = [],
platform, rule;
for (platform in platformConfig) {
rule = Ext.expressionCache.get(platform);
if (rule(Ext.platformTags)) {
ret.push(platform);
}
}
ret.sort(ruleKeySortFn);
return ret;
};
ExtClass.registerPreprocessor('platformConfig', function(Class, data, hooks) {
var platformConfigs = data.platformConfig,
config = data.config,
added, classConfigs, configs, configurator, hoisted, keys, name, value, platform, theme, platformConfig, i, ln, j, ln2, themeName;
delete data.platformConfig;
if (platformConfigs instanceof Array) {
config = config || {};
themeName = (Ext.theme || (Ext.theme = {
name: 'Default'
})).name;
for (i = 0 , ln = platformConfigs.length; i < ln; i++) {
platformConfig = platformConfigs[i];
platform = platformConfig.platform;
delete platformConfig.platform;
theme = [].concat(platformConfig.theme);
ln2 = theme.length;
delete platformConfig.theme;
if (platform && Ext.filterPlatform(platform)) {
Ext.merge(config, platformConfig);
}
if (ln2) {
for (j = 0; j < ln2; j++) {
if (themeName === theme[j]) {
Ext.merge(config, platformConfig);
}
}
}
}
} else {
configurator = Class.getConfigurator();
classConfigs = configurator.configs;
keys = Ext.getPlatformConfigKeys(platformConfigs);
for (i = 0 , ln = keys.length; i < ln; ++i) {
configs = platformConfigs[keys[i]];
hoisted = added = null;
for (name in configs) {
value = configs[name];
if (config && name in config) {
(added || (added = {}))[name] = value;
(hoisted || (hoisted = {}))[name] = config[name];
delete config[name];
} else if (name in classConfigs) {
(added || (added = {}))[name] = value;
} else {
data[name] = value;
}
}
if (hoisted) {
configurator.add(hoisted);
}
if (added) {
configurator.add(added);
}
}
}
});
ExtClass.registerPreprocessor('config', function(Class, data) {
if (data.hasOwnProperty('$configPrefixed')) {
Class.prototype.$configPrefixed = data.$configPrefixed;
}
Class.addConfig(data.config);
delete data.config;
});
ExtClass.registerPreprocessor('cachedConfig', function(Class, data) {
if (data.hasOwnProperty('$configPrefixed')) {
Class.prototype.$configPrefixed = data.$configPrefixed;
}
Class.addCachedConfig(data.cachedConfig);
delete data.cachedConfig;
});
ExtClass.registerPreprocessor('mixins', function(Class, data, hooks) {
Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#mixinsPreprocessor', arguments);
var mixins = data.mixins,
onCreated = hooks.onCreated;
delete data.mixins;
hooks.onCreated = function() {
Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#mixinsPreprocessor#beforeCreated', arguments);
hooks.onCreated = onCreated;
Class.mixin(mixins);
return hooks.onCreated.apply(this, arguments);
};
});
Ext.extend = function(Class, Parent, members) {
Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#extend-backwards-compatible', arguments);
if (arguments.length === 2 && Ext.isObject(Parent)) {
members = Parent;
Parent = Class;
Class = null;
}
var cls;
if (!Parent) {
throw new Error("[Ext.extend] Attempting to extend from a class which has not been loaded on the page.");
}
members.extend = Parent;
members.preprocessors = [
'extend',
'statics',
'inheritableStatics',
'mixins',
'platformConfig',
'config'
];
if (Class) {
cls = new ExtClass(Class, members);
cls.prototype.constructor = Class;
} else {
cls = new ExtClass(members);
}
cls.prototype.override = function(o) {
for (var m in o) {
if (o.hasOwnProperty(m)) {
this[m] = o[m];
}
}
};
return cls;
};
}());
Ext.Inventory = function() {
var me = this;
me.names = [];
me.paths = {};
me.alternateToName = {};
me.aliasToName = {};
me.nameToAliases = {};
me.nameToAlternates = {};
};
Ext.Inventory.prototype = {
_array1: [
0
],
prefixes: null,
dotRe: /\./g,
wildcardRe: /\*/g,
addAlias: function(className, alias) {
return this.addMapping(className, alias, this.aliasToName, this.nameToAliases);
},
addAlternate: function(className, alternate) {
return this.addMapping(className, alternate, this.alternateToName, this.nameToAlternates);
},
addMapping: function(className, alternate, toName, nameTo) {
var name = className.$className || className,
mappings = name,
array = this._array1,
a, aliases, cls, i, length, nameMapping;
if (Ext.isString(name)) {
mappings = {};
mappings[name] = alternate;
}
for (cls in mappings) {
aliases = mappings[cls];
if (Ext.isString(aliases)) {
array[0] = aliases;
aliases = array;
}
length = aliases.length;
nameMapping = nameTo[cls] || (nameTo[cls] = []);
for (i = 0; i < length; ++i) {
if (!(a = aliases[i])) {
continue;
}
if (toName[a] !== cls) {
if (toName[a]) {
Ext.log.warn("Overriding existing mapping: '" + a + "' From '" + toName[a] + "' to '" + cls + "'. Is this intentional?");
}
toName[a] = cls;
nameMapping.push(a);
}
}
}
},
getAliasesByName: function(name) {
return this.nameToAliases[name] || null;
},
getAlternatesByName: function(name) {
return this.nameToAlternates[name] || null;
},
getNameByAlias: function(alias) {
return this.aliasToName[alias] || '';
},
getNameByAlternate: function(alternate) {
return this.alternateToName[alternate] || '';
},
getNamesByExpression: function(expression, exclude, accumulate) {
var me = this,
aliasToName = me.aliasToName,
alternateToName = me.alternateToName,
nameToAliases = me.nameToAliases,
nameToAlternates = me.nameToAlternates,
map = accumulate ? exclude : {},
names = [],
expressions = Ext.isString(expression) ? [
expression
] : expression,
length = expressions.length,
wildcardRe = me.wildcardRe,
expr, i, list, match, n, name, regex;
for (i = 0; i < length; ++i) {
if ((expr = expressions[i]).indexOf('*') < 0) {
if (!(name = aliasToName[expr])) {
if (!(name = alternateToName[expr])) {
name = expr;
}
}
if (!(name in map) && !(exclude && (name in exclude))) {
map[name] = 1;
names.push(name);
}
} else {
regex = new RegExp('^' + expr.replace(wildcardRe, '(.*?)') + '$');
for (name in nameToAliases) {
if (!(name in map) && !(exclude && (name in exclude))) {
if (!(match = regex.test(name))) {
n = (list = nameToAliases[name]).length;
while (!match && n-- > 0) {
match = regex.test(list[n]);
}
list = nameToAlternates[name];
if (list && !match) {
n = list.length;
while (!match && n-- > 0) {
match = regex.test(list[n]);
}
}
}
if (match) {
map[name] = 1;
names.push(name);
}
}
}
}
}
return names;
},
getPath: function(className) {
var me = this,
paths = me.paths,
ret = '',
prefix;
if (className in paths) {
ret = paths[className];
} else {
prefix = me.getPrefix(className);
if (prefix) {
className = className.substring(prefix.length + 1);
ret = paths[prefix];
if (ret) {
ret += '/';
}
}
ret += className.replace(me.dotRe, '/') + '.js';
}
return ret;
},
getPrefix: function(className) {
if (className in this.paths) {
return className;
}
var prefixes = this.getPrefixes(),
i = prefixes.length,
length, prefix;
while (i-- > 0) {
length = (prefix = prefixes[i]).length;
if (length < className.length && className.charAt(length) === '.' && prefix === className.substring(0, length)) {
return prefix;
}
}
return '';
},
getPrefixes: function() {
var me = this,
prefixes = me.prefixes;
if (!prefixes) {
me.prefixes = prefixes = me.names.slice(0);
prefixes.sort(me._compareNames);
}
return prefixes;
},
removeName: function(name) {
var me = this,
aliasToName = me.aliasToName,
alternateToName = me.alternateToName,
nameToAliases = me.nameToAliases,
nameToAlternates = me.nameToAlternates,
aliases = nameToAliases[name],
alternates = nameToAlternates[name],
i, a;
delete nameToAliases[name];
delete nameToAlternates[name];
if (aliases) {
for (i = aliases.length; i--; ) {
if (name === (a = aliases[i])) {
delete aliasToName[a];
}
}
}
if (alternates) {
for (i = alternates.length; i--; ) {
if (name === (a = alternates[i])) {
delete alternateToName[a];
}
}
}
},
resolveName: function(name) {
var me = this,
trueName;
if (!(name in me.nameToAliases)) {
if (!(trueName = me.aliasToName[name])) {
trueName = me.alternateToName[name];
}
}
return trueName || name;
},
select: function(receiver, scope) {
var me = this,
excludes = {},
ret = {
excludes: excludes,
exclude: function() {
me.getNamesByExpression(arguments, excludes, true);
return this;
}
},
name;
for (name in receiver) {
ret[name] = me.selectMethod(excludes, receiver[name], scope || receiver);
}
return ret;
},
selectMethod: function(excludes, fn, scope) {
var me = this;
return function(include) {
var args = Ext.Array.slice(arguments, 1);
args.unshift(me.getNamesByExpression(include, excludes));
return fn.apply(scope, args);
};
},
setPath: Ext.Function.flexSetter(function(name, path) {
var me = this;
me.paths[name] = path;
me.names.push(name);
me.prefixes = null;
return me;
}),
_compareNames: function(lhs, rhs) {
var cmp = lhs.length - rhs.length;
if (!cmp) {
cmp = (lhs < rhs) ? -1 : 1;
}
return cmp;
}
};
Ext.ClassManager = (function(Class, alias, arraySlice, arrayFrom, global) {
var makeCtor = Ext.Class.makeCtor,
Manager = Ext.apply(new Ext.Inventory(), {
classes: {},
classState: {},
existCache: {},
namespaceRewrites: [
{
from: 'Ext.',
to: Ext
}
],
enableNamespaceParseCache: true,
namespaceParseCache: {},
instantiators: [],
isCreated: function(className) {
var i, ln, part, root, parts;
if (typeof className !== 'string' || className.length < 1) {
throw new Error("[Ext.ClassManager] Invalid classname, must be a string and must not be empty");
}
if (Manager.classes[className] || Manager.existCache[className]) {
return true;
}
root = global;
parts = Manager.parseNamespace(className);
for (i = 0 , ln = parts.length; i < ln; i++) {
part = parts[i];
if (typeof part !== 'string') {
root = part;
} else {
if (!root || !root[part]) {
return false;
}
root = root[part];
}
}
Manager.triggerCreated(className);
return true;
},
createdListeners: [],
nameCreatedListeners: {},
existsListeners: [],
nameExistsListeners: {},
overrideMap: {},
triggerCreated: function(className, state) {
Manager.existCache[className] = state || 1;
Manager.classState[className] += 40;
Manager.notify(className, Manager.createdListeners, Manager.nameCreatedListeners);
},
onCreated: function(fn, scope, className) {
Manager.addListener(fn, scope, className, Manager.createdListeners, Manager.nameCreatedListeners);
},
notify: function(className, listeners, nameListeners) {
var alternateNames = Manager.getAlternatesByName(className),
names = [
className
],
i, ln, j, subLn, listener, name;
for (i = 0 , ln = listeners.length; i < ln; i++) {
listener = listeners[i];
listener.fn.call(listener.scope, className);
}
while (names) {
for (i = 0 , ln = names.length; i < ln; i++) {
name = names[i];
listeners = nameListeners[name];
if (listeners) {
for (j = 0 , subLn = listeners.length; j < subLn; j++) {
listener = listeners[j];
listener.fn.call(listener.scope, name);
}
delete nameListeners[name];
}
}
names = alternateNames;
alternateNames = null;
}
},
addListener: function(fn, scope, className, listeners, nameListeners) {
if (Ext.isArray(className)) {
fn = Ext.Function.createBarrier(className.length, fn, scope);
for (i = 0; i < className.length; i++) {
this.addListener(fn, null, className[i], listeners, nameListeners);
}
return;
}
var i,
listener = {
fn: fn,
scope: scope
};
if (className) {
if (this.isCreated(className)) {
fn.call(scope, className);
return;
}
if (!nameListeners[className]) {
nameListeners[className] = [];
}
nameListeners[className].push(listener);
} else {
listeners.push(listener);
}
},
parseNamespace: function(namespace) {
if (typeof namespace !== 'string') {
throw new Error("[Ext.ClassManager] Invalid namespace, must be a string");
}
var cache = this.namespaceParseCache,
parts, rewrites, root, name, rewrite, from, to, i, ln;
if (this.enableNamespaceParseCache) {
if (cache.hasOwnProperty(namespace)) {
return cache[namespace];
}
}
parts = [];
rewrites = this.namespaceRewrites;
root = global;
name = namespace;
for (i = 0 , ln = rewrites.length; i < ln; i++) {
rewrite = rewrites[i];
from = rewrite.from;
to = rewrite.to;
if (name === from || name.substring(0, from.length) === from) {
name = name.substring(from.length);
if (typeof to !== 'string') {
root = to;
} else {
parts = parts.concat(to.split('.'));
}
break;
}
}
parts.push(root);
parts = parts.concat(name.split('.'));
if (this.enableNamespaceParseCache) {
cache[namespace] = parts;
}
return parts;
},
setNamespace: function(name, value) {
var root = global,
parts = this.parseNamespace(name),
ln = parts.length - 1,
leaf = parts[ln],
i, part;
for (i = 0; i < ln; i++) {
part = parts[i];
if (typeof part !== 'string') {
root = part;
} else {
if (!root[part]) {
root[part] = {};
}
root = root[part];
}
}
root[leaf] = value;
return root[leaf];
},
createNamespaces: function() {
var root = global,
parts, part, i, j, ln, subLn;
for (i = 0 , ln = arguments.length; i < ln; i++) {
parts = this.parseNamespace(arguments[i]);
for (j = 0 , subLn = parts.length; j < subLn; j++) {
part = parts[j];
if (typeof part !== 'string') {
root = part;
} else {
if (!root[part]) {
root[part] = {};
}
root = root[part];
}
}
}
return root;
},
set: function(name, value) {
var me = this,
targetName = me.getName(value);
me.classes[name] = me.setNamespace(name, value);
if (targetName && targetName !== name) {
me.addAlternate(targetName, name);
}
return this;
},
get: function(name) {
var classes = this.classes,
root, parts, part, i, ln;
if (classes[name]) {
return classes[name];
}
root = global;
parts = this.parseNamespace(name);
for (i = 0 , ln = parts.length; i < ln; i++) {
part = parts[i];
if (typeof part !== 'string') {
root = part;
} else {
if (!root || !root[part]) {
return null;
}
root = root[part];
}
}
return root;
},
addNameAliasMappings: function(aliases) {
this.addAlias(aliases);
},
addNameAlternateMappings: function(alternates) {
this.addAlternate(alternates);
},
getByAlias: function(alias) {
return this.get(this.getNameByAlias(alias));
},
getName: function(object) {
return object && object.$className || '';
},
getClass: function(object) {
return object && object.self || null;
},
create: function(className, data, createdFn) {
if (className != null && typeof className !== 'string') {
throw new Error("[Ext.define] Invalid class name '" + className + "' specified, must be a non-empty string");
}
var ctor = makeCtor(className);
if (typeof data === 'function') {
data = data(ctor);
}
if (className) {
if (Manager.classes[className]) {
Ext.log.warn("[Ext.define] Duplicate class name '" + className + "' specified, must be a non-empty string");
}
ctor.name = className;
}
data.$className = className;
return new Class(ctor, data, function() {
var postprocessorStack = data.postprocessors || Manager.defaultPostprocessors,
registeredPostprocessors = Manager.postprocessors,
postprocessors = [],
postprocessor, i, ln, j, subLn, postprocessorProperties, postprocessorProperty;
delete data.postprocessors;
for (i = 0 , ln = postprocessorStack.length; i < ln; i++) {
postprocessor = postprocessorStack[i];
if (typeof postprocessor === 'string') {
postprocessor = registeredPostprocessors[postprocessor];
postprocessorProperties = postprocessor.properties;
if (postprocessorProperties === true) {
postprocessors.push(postprocessor.fn);
} else if (postprocessorProperties) {
for (j = 0 , subLn = postprocessorProperties.length; j < subLn; j++) {
postprocessorProperty = postprocessorProperties[j];
if (data.hasOwnProperty(postprocessorProperty)) {
postprocessors.push(postprocessor.fn);
break;
}
}
}
} else {
postprocessors.push(postprocessor);
}
}
data.postprocessors = postprocessors;
data.createdFn = createdFn;
Manager.processCreate(className, this, data);
});
},
processCreate: function(className, cls, clsData) {
var me = this,
postprocessor = clsData.postprocessors.shift(),
createdFn = clsData.createdFn;
if (!postprocessor) {
Ext.classSystemMonitor && Ext.classSystemMonitor(className, 'Ext.ClassManager#classCreated', arguments);
if (className) {
me.set(className, cls);
}
delete cls._classHooks;
if (createdFn) {
createdFn.call(cls, cls);
}
if (className) {
me.triggerCreated(className);
}
return;
}
if (postprocessor.call(me, className, cls, clsData, me.processCreate) !== false) {
me.processCreate(className, cls, clsData);
}
},
createOverride: function(className, data, createdFn) {
var me = this,
overriddenClassName = data.override,
requires = data.requires,
uses = data.uses,
mixins = data.mixins,
mixinsIsArray,
compat = data.compatibility,
depedenciesLoaded,
classReady = function() {
var cls, dependencies, i, key, temp;
if (!depedenciesLoaded) {
dependencies = requires ? requires.slice(0) : [];
if (mixins) {
if (!(mixinsIsArray = mixins instanceof Array)) {
for (key in mixins) {
if (Ext.isString(cls = mixins[key])) {
dependencies.push(cls);
}
}
} else {
for (i = 0 , temp = mixins.length; i < temp; ++i) {
if (Ext.isString(cls = mixins[i])) {
dependencies.push(cls);
}
}
}
}
depedenciesLoaded = true;
if (dependencies.length) {
Ext.require(dependencies, classReady);
return;
}
}
if (mixinsIsArray) {
for (i = 0 , temp = mixins.length; i < temp; ++i) {
if (Ext.isString(cls = mixins[i])) {
mixins[i] = Ext.ClassManager.get(cls);
}
}
} else if (mixins) {
for (key in mixins) {
if (Ext.isString(cls = mixins[key])) {
mixins[key] = Ext.ClassManager.get(cls);
}
}
}
cls = me.get(overriddenClassName);
delete data.override;
delete data.compatibility;
delete data.requires;
delete data.uses;
Ext.override(cls, data);
Ext.Loader.history.push(className);
if (uses) {
Ext['Loader'].addUsedClasses(uses);
}
if (createdFn) {
createdFn.call(cls, cls);
}
};
Manager.overrideMap[className] = true;
if (!compat || Ext.checkVersion(compat)) {
me.onCreated(classReady, me, overriddenClassName);
}
me.triggerCreated(className, 2);
return me;
},
instantiateByAlias: function() {
var alias = arguments[0],
args = arraySlice.call(arguments),
className = this.getNameByAlias(alias);
if (!className) {
throw new Error("[Ext.createByAlias] Unrecognized alias: " + alias);
}
args[0] = className;
return Ext.create.apply(Ext, args);
},
instantiate: function() {
Ext.log.warn('Ext.ClassManager.instantiate() is deprecated. Use Ext.create() instead.');
return Ext.create.apply(Ext, arguments);
},
dynInstantiate: function(name, args) {
args = arrayFrom(args, true);
args.unshift(name);
return Ext.create.apply(Ext, args);
},
getInstantiator: function(length) {
var instantiators = this.instantiators,
instantiator, i, args;
instantiator = instantiators[length];
if (!instantiator) {
i = length;
args = [];
for (i = 0; i < length; i++) {
args.push('a[' + i + ']');
}
instantiator = instantiators[length] = new Function('c', 'a', 'return new c(' + args.join(',') + ')');
instantiator.name = "Ext.create" + length;
}
return instantiator;
},
postprocessors: {},
defaultPostprocessors: [],
registerPostprocessor: function(name, fn, properties, position, relativeTo) {
if (!position) {
position = 'last';
}
if (!properties) {
properties = [
name
];
}
this.postprocessors[name] = {
name: name,
properties: properties || false,
fn: fn
};
this.setDefaultPostprocessorPosition(name, position, relativeTo);
return this;
},
setDefaultPostprocessors: function(postprocessors) {
this.defaultPostprocessors = arrayFrom(postprocessors);
return this;
},
setDefaultPostprocessorPosition: function(name, offset, relativeName) {
var defaultPostprocessors = this.defaultPostprocessors,
index;
if (typeof offset === 'string') {
if (offset === 'first') {
defaultPostprocessors.unshift(name);
return this;
} else if (offset === 'last') {
defaultPostprocessors.push(name);
return this;
}
offset = (offset === 'after') ? 1 : -1;
}
index = Ext.Array.indexOf(defaultPostprocessors, relativeName);
if (index !== -1) {
Ext.Array.splice(defaultPostprocessors, Math.max(0, index + offset), 0, name);
}
return this;
}
});
Manager.registerPostprocessor('alias', function(name, cls, data) {
Ext.classSystemMonitor && Ext.classSystemMonitor(name, 'Ext.ClassManager#aliasPostProcessor', arguments);
var aliases = Ext.Array.from(data.alias),
i, ln;
for (i = 0 , ln = aliases.length; i < ln; i++) {
alias = aliases[i];
this.addAlias(cls, alias);
}
}, [
'xtype',
'alias'
]);
Manager.registerPostprocessor('singleton', function(name, cls, data, fn) {
Ext.classSystemMonitor && Ext.classSystemMonitor(name, 'Ext.ClassManager#singletonPostProcessor', arguments);
if (data.singleton) {
fn.call(this, name, new cls(), data);
} else {
return true;
}
return false;
});
Manager.registerPostprocessor('alternateClassName', function(name, cls, data) {
Ext.classSystemMonitor && Ext.classSystemMonitor(name, 'Ext.ClassManager#alternateClassNamePostprocessor', arguments);
var alternates = data.alternateClassName,
i, ln, alternate;
if (!(alternates instanceof Array)) {
alternates = [
alternates
];
}
for (i = 0 , ln = alternates.length; i < ln; i++) {
alternate = alternates[i];
if (typeof alternate !== 'string') {
throw new Error("[Ext.define] Invalid alternate of: '" + alternate + "' for class: '" + name + "'; must be a valid string");
}
this.set(alternate, cls);
}
});
Manager.registerPostprocessor('debugHooks', function(name, Class, data) {
Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#debugHooks', arguments);
if (Ext.isDebugEnabled(Class.$className, data.debugHooks.$enabled)) {
delete data.debugHooks.$enabled;
Ext.override(Class, data.debugHooks);
}
var target = Class.isInstance ? Class.self : Class;
delete target.prototype.debugHooks;
});
Manager.registerPostprocessor('deprecated', function(name, Class, data) {
Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#deprecated', arguments);
var target = Class.isInstance ? Class.self : Class;
target.addDeprecations(data.deprecated);
delete target.prototype.deprecated;
});
Ext.apply(Ext, {
create: function() {
var name = arguments[0],
nameType = typeof name,
args = arraySlice.call(arguments, 1),
cls;
if (nameType === 'function') {
cls = name;
} else {
if (nameType !== 'string' && args.length === 0) {
args = [
name
];
if (!(name = name.xclass)) {
name = args[0].xtype;
if (name) {
name = 'widget.' + name;
}
}
}
if (typeof name !== 'string' || name.length < 1) {
throw new Error("[Ext.create] Invalid class name or alias '" + name + "' specified, must be a non-empty string");
}
name = Manager.resolveName(name);
cls = Manager.get(name);
}
if (!cls) {
Ext.log.warn("[Ext.Loader] Synchronously loading '" + name + "'; consider adding " + "Ext.require('" + name + "') above Ext.onReady");
Ext.syncRequire(name);
cls = Manager.get(name);
}
if (!cls) {
throw new Error("[Ext.create] Unrecognized class name / alias: " + name);
}
if (typeof cls !== 'function') {
throw new Error("[Ext.create] Singleton '" + name + "' cannot be instantiated.");
}
return Manager.getInstantiator(args.length)(cls, args);
},
widget: function(name, config) {
var xtype = name,
alias, className, T;
if (typeof xtype !== 'string') {
config = name;
xtype = config.xtype;
className = config.xclass;
} else {
config = config || {};
}
if (config.isComponent) {
return config;
}
if (!className) {
alias = 'widget.' + xtype;
className = Manager.getNameByAlias(alias);
}
if (className) {
T = Manager.get(className);
}
if (!T) {
return Ext.create(className || alias, config);
}
return new T(config);
},
createByAlias: alias(Manager, 'instantiateByAlias'),
define: function(className, data, createdFn) {
Ext.classSystemMonitor && Ext.classSystemMonitor(className, 'ClassManager#define', arguments);
if (data.override) {
Manager.classState[className] = 20;
return Manager.createOverride.apply(Manager, arguments);
}
Manager.classState[className] = 10;
return Manager.create.apply(Manager, arguments);
},
undefine: function(className) {
Ext.classSystemMonitor && Ext.classSystemMonitor(className, 'Ext.ClassManager#undefine', arguments);
var classes = Manager.classes,
parts, partCount, namespace, i;
delete Manager.namespaceParseCache[className];
delete classes[className];
delete Manager.existCache[className];
delete Manager.classState[className];
Manager.removeName(className);
parts = Manager.parseNamespace(className);
partCount = parts.length - 1;
namespace = parts[0];
for (i = 1; i < partCount; i++) {
namespace = namespace[parts[i]];
if (!namespace) {
return;
}
}
try {
delete namespace[parts[partCount]];
} catch (e) {
namespace[parts[partCount]] = undefined;
}
},
getClassName: alias(Manager, 'getName'),
getDisplayName: function(object) {
if (object) {
if (object.displayName) {
return object.displayName;
}
if (object.$name && object.$class) {
return Ext.getClassName(object.$class) + '#' + object.$name;
}
if (object.$className) {
return object.$className;
}
}
return 'Anonymous';
},
getClass: alias(Manager, 'getClass'),
namespace: alias(Manager, 'createNamespaces')
});
Ext.createWidget = Ext.widget;
Ext.ns = Ext.namespace;
Class.registerPreprocessor('className', function(cls, data) {
if ('$className' in data) {
cls.$className = data.$className;
cls.displayName = cls.$className;
}
Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.ClassManager#classNamePreprocessor', arguments);
}, true, 'first');
Class.registerPreprocessor('alias', function(cls, data) {
Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.ClassManager#aliasPreprocessor', arguments);
var prototype = cls.prototype,
xtypes = arrayFrom(data.xtype),
aliases = arrayFrom(data.alias),
widgetPrefix = 'widget.',
widgetPrefixLength = widgetPrefix.length,
xtypesChain = Array.prototype.slice.call(prototype.xtypesChain || []),
xtypesMap = Ext.merge({}, prototype.xtypesMap || {}),
i, ln, alias, xtype;
for (i = 0 , ln = aliases.length; i < ln; i++) {
alias = aliases[i];
if (typeof alias !== 'string' || alias.length < 1) {
throw new Error("[Ext.define] Invalid alias of: '" + alias + "' for class: '" + name + "'; must be a valid string");
}
if (alias.substring(0, widgetPrefixLength) === widgetPrefix) {
xtype = alias.substring(widgetPrefixLength);
Ext.Array.include(xtypes, xtype);
}
}
cls.xtype = data.xtype = xtypes[0];
data.xtypes = xtypes;
for (i = 0 , ln = xtypes.length; i < ln; i++) {
xtype = xtypes[i];
if (!xtypesMap[xtype]) {
xtypesMap[xtype] = true;
xtypesChain.push(xtype);
}
}
data.xtypesChain = xtypesChain;
data.xtypesMap = xtypesMap;
Ext.Function.interceptAfter(data, 'onClassCreated', function() {
Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.ClassManager#aliasPreprocessor#afterClassCreated', arguments);
var mixins = prototype.mixins,
key, mixin;
for (key in mixins) {
if (mixins.hasOwnProperty(key)) {
mixin = mixins[key];
xtypes = mixin.xtypes;
if (xtypes) {
for (i = 0 , ln = xtypes.length; i < ln; i++) {
xtype = xtypes[i];
if (!xtypesMap[xtype]) {
xtypesMap[xtype] = true;
xtypesChain.push(xtype);
}
}
}
}
}
});
for (i = 0 , ln = xtypes.length; i < ln; i++) {
xtype = xtypes[i];
if (typeof xtype !== 'string' || xtype.length < 1) {
throw new Error("[Ext.define] Invalid xtype of: '" + xtype + "' for class: '" + name + "'; must be a valid non-empty string");
}
Ext.Array.include(aliases, widgetPrefix + xtype);
}
data.alias = aliases;
}, [
'xtype',
'alias'
]);
if (Ext.manifest) {
var manifest = Ext.manifest,
classes = manifest.classes,
paths = manifest.paths,
aliases = {},
alternates = {},
className, obj, name, path, baseUrl;
if (paths) {
if (manifest.bootRelative) {
baseUrl = Ext.Boot.baseUrl;
for (path in paths) {
if (paths.hasOwnProperty(path)) {
paths[path] = baseUrl + paths[path];
}
}
}
Manager.setPath(paths);
}
if (classes) {
for (className in classes) {
alternates[className] = [];
aliases[className] = [];
obj = classes[className];
if (obj.alias) {
aliases[className] = obj.alias;
}
if (obj.alternates) {
alternates[className] = obj.alternates;
}
}
}
Manager.addAlias(aliases);
Manager.addAlternate(alternates);
}
return Manager;
}(Ext.Class, Ext.Function.alias, Array.prototype.slice, Ext.Array.from, Ext.global));
(Ext.env || (Ext.env = {})).Browser = function(userAgent, publish) {
var me = this,
browserPrefixes = me.browserPrefixes,
enginePrefixes = me.enginePrefixes,
browserMatch = userAgent.match(new RegExp('((?:' + Ext.Object.getValues(browserPrefixes).join(')|(?:') + '))([\\w\\._]+)')),
engineMatch = userAgent.match(new RegExp('((?:' + Ext.Object.getValues(enginePrefixes).join(')|(?:') + '))([\\w\\._]+)')),
browserNames = me.browserNames,
browserName = browserNames.other,
engineNames = me.engineNames,
engineName = engineNames.other,
browserVersion = '',
engineVersion = '',
majorVer = '',
isWebView = false,
i, prefix, mode, name, maxIEVersion;
me.userAgent = userAgent;
if (browserMatch) {
browserName = browserNames[Ext.Object.getKey(browserPrefixes, browserMatch[1])];
if (browserName === 'Safari' && /^Opera/.test(userAgent)) {
browserName = 'Opera';
}
browserVersion = new Ext.Version(browserMatch[2]);
}
if (engineMatch) {
engineName = engineNames[Ext.Object.getKey(enginePrefixes, engineMatch[1])];
engineVersion = new Ext.Version(engineMatch[2]);
}
if (engineName === 'Trident' && browserName !== 'IE') {
browserName = 'IE';
var version = userAgent.match(/.*rv:(\d+.\d+)/);
if (version && version.length) {
version = version[1];
browserVersion = new Ext.Version(version);
}
}
if (userAgent.match(/FB/) && browserName === "Other") {
browserName = browserNames.safari;
engineName = engineNames.webkit;
}
if (userAgent.match(/Android.*Chrome/g)) {
browserName = 'ChromeMobile';
}
if (userAgent.match(/OPR/)) {
browserName = 'Opera';
browserMatch = userAgent.match(/OPR\/(\d+.\d+)/);
browserVersion = new Ext.Version(browserMatch[1]);
}
Ext.apply(this, {
engineName: engineName,
engineVersion: engineVersion,
name: browserName,
version: browserVersion
});
this.setFlag(browserName, true, publish);
if (browserVersion) {
majorVer = browserVersion.getMajor() || '';
if (me.is.IE) {
majorVer = parseInt(majorVer, 10);
mode = document.documentMode;
if (mode === 7 || (majorVer === 7 && mode !== 8 && mode !== 9 && mode !== 10)) {
majorVer = 7;
} else if (mode === 8 || (majorVer === 8 && mode !== 8 && mode !== 9 && mode !== 10)) {
majorVer = 8;
} else if (mode === 9 || (majorVer === 9 && mode !== 7 && mode !== 8 && mode !== 10)) {
majorVer = 9;
} else if (mode === 10 || (majorVer === 10 && mode !== 7 && mode !== 8 && mode !== 9)) {
majorVer = 10;
} else if (mode === 11 || (majorVer === 11 && mode !== 7 && mode !== 8 && mode !== 9 && mode !== 10)) {
majorVer = 11;
}
maxIEVersion = Math.max(majorVer, 11);
for (i = 7; i <= maxIEVersion; ++i) {
prefix = 'isIE' + i;
if (majorVer <= i) {
Ext[prefix + 'm'] = true;
}
if (majorVer === i) {
Ext[prefix] = true;
}
if (majorVer >= i) {
Ext[prefix + 'p'] = true;
}
}
}
if (me.is.Opera && parseInt(majorVer, 10) <= 12) {
Ext.isOpera12m = true;
}
Ext.chromeVersion = Ext.isChrome ? majorVer : 0;
Ext.firefoxVersion = Ext.isFirefox ? majorVer : 0;
Ext.ieVersion = Ext.isIE ? majorVer : 0;
Ext.operaVersion = Ext.isOpera ? majorVer : 0;
Ext.safariVersion = Ext.isSafari ? majorVer : 0;
Ext.webKitVersion = Ext.isWebKit ? majorVer : 0;
this.setFlag(browserName + majorVer, true, publish);
this.setFlag(browserName + browserVersion.getShortVersion());
}
for (i in browserNames) {
if (browserNames.hasOwnProperty(i)) {
name = browserNames[i];
this.setFlag(name, browserName === name);
}
}
this.setFlag(name);
if (engineVersion) {
this.setFlag(engineName + (engineVersion.getMajor() || ''));
this.setFlag(engineName + engineVersion.getShortVersion());
}
for (i in engineNames) {
if (engineNames.hasOwnProperty(i)) {
name = engineNames[i];
this.setFlag(name, engineName === name, publish);
}
}
this.setFlag('Standalone', !!navigator.standalone);
this.setFlag('Ripple', !!document.getElementById("tinyhippos-injected") && !Ext.isEmpty(window.top.ripple));
this.setFlag('WebWorks', !!window.blackberry);
if (window.PhoneGap !== undefined || window.Cordova !== undefined || window.cordova !== undefined) {
isWebView = true;
this.setFlag('PhoneGap');
this.setFlag('Cordova');
} else if (!!window.isNK) {
isWebView = true;
this.setFlag('Sencha');
}
if (/(Glass)/i.test(userAgent)) {
this.setFlag('GoogleGlass');
}
if (/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)(?!.*FBAN)/i.test(userAgent)) {
isWebView = true;
}
this.setFlag('WebView', isWebView);
this.isStrict = Ext.isStrict = document.compatMode === "CSS1Compat";
this.isSecure = Ext.isSecure;
this.identity = browserName + majorVer + (this.isStrict ? 'Strict' : 'Quirks');
};
Ext.env.Browser.prototype = {
constructor: Ext.env.Browser,
browserNames: {
ie: 'IE',
firefox: 'Firefox',
safari: 'Safari',
chrome: 'Chrome',
opera: 'Opera',
dolfin: 'Dolfin',
webosbrowser: 'webOSBrowser',
chromeMobile: 'ChromeMobile',
chromeiOS: 'ChromeiOS',
silk: 'Silk',
other: 'Other'
},
engineNames: {
webkit: 'WebKit',
gecko: 'Gecko',
presto: 'Presto',
trident: 'Trident',
other: 'Other'
},
enginePrefixes: {
webkit: 'AppleWebKit/',
gecko: 'Gecko/',
presto: 'Presto/',
trident: 'Trident/'
},
browserPrefixes: {
ie: 'MSIE ',
firefox: 'Firefox/',
chrome: 'Chrome/',
safari: 'Version/',
opera: 'OPR/',
dolfin: 'Dolfin/',
webosbrowser: 'wOSBrowser/',
chromeMobile: 'CrMo/',
chromeiOS: 'CriOS/',
silk: 'Silk/'
},
styleDashPrefixes: {
WebKit: '-webkit-',
Gecko: '-moz-',
Trident: '-ms-',
Presto: '-o-',
Other: ''
},
stylePrefixes: {
WebKit: 'Webkit',
Gecko: 'Moz',
Trident: 'ms',
Presto: 'O',
Other: ''
},
propertyPrefixes: {
WebKit: 'webkit',
Gecko: 'moz',
Trident: 'ms',
Presto: 'o',
Other: ''
},
is: function(name) {
return !!this.is[name];
},
name: null,
version: null,
engineName: null,
engineVersion: null,
setFlag: function(name, value, publish) {
if (value === undefined) {
value = true;
}
this.is[name] = value;
this.is[name.toLowerCase()] = value;
if (publish) {
Ext['is' + name] = value;
}
return this;
},
getStyleDashPrefix: function() {
return this.styleDashPrefixes[this.engineName];
},
getStylePrefix: function() {
return this.stylePrefixes[this.engineName];
},
getVendorProperyName: function(name) {
var prefix = this.propertyPrefixes[this.engineName];
if (prefix.length > 0) {
return prefix + Ext.String.capitalize(name);
}
return name;
},
getPreferredTranslationMethod: function(config) {
if (typeof config === 'object' && 'translationMethod' in config && config.translationMethod !== 'auto') {
return config.translationMethod;
} else {
return 'csstransform';
}
}
};
(function(userAgent) {
Ext.browser = new Ext.env.Browser(userAgent, true);
Ext.userAgent = userAgent.toLowerCase();
Ext.SSL_SECURE_URL = Ext.isSecure && Ext.isIE ? 'javascript:\'\'' : 'about:blank';
}(
Ext.global.navigator.userAgent));
Ext.env.OS = function(userAgent, platform, browserScope) {
var me = this,
names = me.names,
prefixes = me.prefixes,
name,
version = '',
is = me.is,
i, prefix, match, item, match1;
browserScope = browserScope || Ext.browser;
for (i in prefixes) {
if (prefixes.hasOwnProperty(i)) {
prefix = prefixes[i];
match = userAgent.match(new RegExp('(?:' + prefix + ')([^\\s;]+)'));
if (match) {
name = names[i];
match1 = match[1];
if (match1 && match1 === "HTC_") {
version = new Ext.Version("2.3");
} else if (match1 && match1 === "Silk/") {
version = new Ext.Version("2.3");
} else {
version = new Ext.Version(match[match.length - 1]);
}
break;
}
}
}
if (!name) {
name = names[(userAgent.toLowerCase().match(/mac|win|linux/) || [
'other'
])[0]];
version = new Ext.Version('');
}
this.name = name;
this.version = version;
if (platform) {
this.setFlag(platform.replace(/ simulator$/i, ''));
}
this.setFlag(name);
if (version) {
this.setFlag(name + (version.getMajor() || ''));
this.setFlag(name + version.getShortVersion());
}
for (i in names) {
if (names.hasOwnProperty(i)) {
item = names[i];
if (!is.hasOwnProperty(name)) {
this.setFlag(item, (name === item));
}
}
}
if (this.name === "iOS" && window.screen.height === 568) {
this.setFlag('iPhone5');
}
if (browserScope.is.Safari || browserScope.is.Silk) {
if (this.is.Android2 || this.is.Android3 || browserScope.version.shortVersion === 501) {
browserScope.setFlag("AndroidStock");
browserScope.setFlag("AndroidStock2");
}
if (this.is.Android4) {
browserScope.setFlag("AndroidStock");
browserScope.setFlag("AndroidStock4");
}
}
};
Ext.env.OS.prototype = {
constructor: Ext.env.OS,
names: {
ios: 'iOS',
android: 'Android',
windowsPhone: 'WindowsPhone',
webos: 'webOS',
blackberry: 'BlackBerry',
rimTablet: 'RIMTablet',
mac: 'MacOS',
win: 'Windows',
tizen: 'Tizen',
linux: 'Linux',
bada: 'Bada',
chrome: 'ChromeOS',
other: 'Other'
},
prefixes: {
tizen: '(Tizen )',
ios: 'i(?:Pad|Phone|Pod)(?:.*)CPU(?: iPhone)? OS ',
android: '(Android |HTC_|Silk/)',
windowsPhone: 'Windows Phone ',
blackberry: '(?:BlackBerry|BB)(?:.*)Version/',
rimTablet: 'RIM Tablet OS ',
webos: '(?:webOS|hpwOS)/',
bada: 'Bada/',
chrome: 'CrOS '
},
is: function(name) {
return !!this[name];
},
name: null,
version: null,
setFlag: function(name, value) {
if (value === undefined) {
value = true;
}
if (this.flags) {
this.flags[name] = value;
}
this.is[name] = value;
this.is[name.toLowerCase()] = value;
return this;
}
};
(function() {
var navigation = Ext.global.navigator,
userAgent = navigation.userAgent,
OS = Ext.env.OS,
is = (Ext.is || (Ext.is = {})),
osEnv, osName, deviceType;
OS.prototype.flags = is;
Ext.os = osEnv = new OS(userAgent, navigation.platform);
osName = osEnv.name;
Ext['is' + osName] = true;
Ext.isMac = is.Mac = is.MacOS;
var search = window.location.search.match(/deviceType=(Tablet|Phone)/),
nativeDeviceType = window.deviceType;
if (search && search[1]) {
deviceType = search[1];
} else if (nativeDeviceType === 'iPhone') {
deviceType = 'Phone';
} else if (nativeDeviceType === 'iPad') {
deviceType = 'Tablet';
} else {
if (!osEnv.is.Android && !osEnv.is.iOS && !osEnv.is.WindowsPhone && /Windows|Linux|MacOS/.test(osName)) {
deviceType = 'Desktop';
Ext.browser.is.WebView = !!Ext.browser.is.Ripple;
} else if (osEnv.is.iPad || osEnv.is.RIMTablet || osEnv.is.Android3 || Ext.browser.is.Silk || (osEnv.is.Android4 && userAgent.search(/mobile/i) === -1)) {
deviceType = 'Tablet';
} else {
deviceType = 'Phone';
}
}
osEnv.setFlag(deviceType, true);
osEnv.deviceType = deviceType;
delete OS.prototype.flags;
}());
Ext.feature = {
has: function(name) {
return !!this.has[name];
},
testElements: {},
getTestElement: function(tag, createNew) {
if (tag === undefined) {
tag = 'div';
} else if (typeof tag !== 'string') {
return tag;
}
if (createNew) {
return document.createElement(tag);
}
if (!this.testElements[tag]) {
this.testElements[tag] = document.createElement(tag);
}
return this.testElements[tag];
},
isStyleSupported: function(name, tag) {
var elementStyle = this.getTestElement(tag).style,
cName = Ext.String.capitalize(name);
if (typeof elementStyle[name] !== 'undefined' || typeof elementStyle[Ext.browser.getStylePrefix(name) + cName] !== 'undefined') {
return true;
}
return false;
},
isStyleSupportedWithoutPrefix: function(name, tag) {
var elementStyle = this.getTestElement(tag).style;
if (typeof elementStyle[name] !== 'undefined') {
return true;
}
return false;
},
isEventSupported: function(name, tag) {
if (tag === undefined) {
tag = window;
}
var element = this.getTestElement(tag),
eventName = 'on' + name.toLowerCase(),
isSupported = (eventName in element);
if (!isSupported) {
if (element.setAttribute && element.removeAttribute) {
element.setAttribute(eventName, '');
isSupported = typeof element[eventName] === 'function';
if (typeof element[eventName] !== 'undefined') {
element[eventName] = undefined;
}
element.removeAttribute(eventName);
}
}
return isSupported;
},
getStyle: function(element, styleName) {
var view = element.ownerDocument.defaultView,
style = (view ? view.getComputedStyle(element, null) : element.currentStyle);
return (style || element.style)[styleName];
},
getSupportedPropertyName: function(object, name) {
var vendorName = Ext.browser.getVendorProperyName(name);
if (vendorName in object) {
return vendorName;
} else if (name in object) {
return name;
}
return null;
},
detect: function(isReady) {
var me = this,
doc = document,
toRun = me.toRun || me.tests,
n = toRun.length,
div = doc.createElement('div'),
notRun = [],
supports = Ext.supports,
has = me.has,
name, test, vector, value;
if (!Ext.theme) {
Ext.theme = {
name: 'Default'
};
}
Ext.theme.is = {};
Ext.theme.is[Ext.theme.name] = true;
div.innerHTML = '<div style="height:30px;width:50px;">' + '<div style="height:20px;width:20px;"></div>' + '</div>' + '<div style="width: 200px; height: 200px; position: relative; padding: 5px;">' + '<div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></div>' + '</div>' + '<div style="position: absolute; left: 10%; top: 10%;"></div>' + '<div style="float:left; background-color:transparent;"></div>';
if (isReady) {
doc.body.appendChild(div);
}
vector = me.preDetected[Ext.browser.identity] || [];
while (n--) {
test = toRun[n];
value = vector[n];
name = test.name;
if (value === undefined) {
if (!isReady && test.ready) {
notRun.push(test);
continue;
}
value = test.fn.call(me, doc, div);
}
supports[name] = has[name] = value;
}
if (isReady) {
doc.body.removeChild(div);
}
me.toRun = notRun;
},
report: function() {
var values = [],
len = this.tests.length,
i;
for (i = 0; i < len; ++i) {
values.push(this.has[this.tests[i].name] ? 1 : 0);
}
Ext.log(Ext.browser.identity + ': [' + values.join(',') + ']');
},
preDetected: {},
tests: [
{
name: 'CSSPointerEvents',
fn: function(doc) {
return 'pointerEvents' in doc.documentElement.style;
}
},
{
name: 'CSS3BoxShadow',
fn: function(doc) {
return 'boxShadow' in doc.documentElement.style || 'WebkitBoxShadow' in doc.documentElement.style || 'MozBoxShadow' in doc.documentElement.style;
}
},
{
name: 'ClassList',
fn: function(doc) {
return !!doc.documentElement.classList;
}
},
{
name: 'Canvas',
fn: function() {
var element = this.getTestElement('canvas');
return !!(element && element.getContext && element.getContext('2d'));
}
},
{
name: 'Svg',
fn: function(doc) {
return !!(doc.createElementNS && !!doc.createElementNS("http:/" + "/www.w3.org/2000/svg", "svg").createSVGRect);
}
},
{
name: 'Vml',
fn: function() {
var element = this.getTestElement(),
ret = false;
element.innerHTML = "<!--[if vml]><br><![endif]-->";
ret = (element.childNodes.length === 1);
element.innerHTML = "";
return ret;
}
},
{
name: 'touchScroll',
fn: function() {
var supports = Ext.supports,
touchScroll = 0;
if (navigator.msMaxTouchPoints || (Ext.isWebKit && supports.TouchEvents && Ext.os.is.Desktop)) {
touchScroll = 1;
} else if (supports.Touch) {
touchScroll = 2;
}
return touchScroll;
}
},
{
name: 'Touch',
fn: function() {
var maxTouchPoints = navigator.msMaxTouchPoints || navigator.maxTouchPoints;
return (Ext.supports.TouchEvents && maxTouchPoints !== 1) || maxTouchPoints > 1;
}
},
{
name: 'TouchEvents',
fn: function() {
return this.isEventSupported('touchend');
}
},
{
name: 'PointerEvents',
fn: function() {
return navigator.pointerEnabled;
}
},
{
name: 'MSPointerEvents',
fn: function() {
return navigator.msPointerEnabled;
}
},
{
name: 'Orientation',
fn: function() {
return ('orientation' in window) && this.isEventSupported('orientationchange');
}
},
{
name: 'OrientationChange',
fn: function() {
return this.isEventSupported('orientationchange');
}
},
{
name: 'DeviceMotion',
fn: function() {
return this.isEventSupported('devicemotion');
}
},
{
names: [
'Geolocation',
'GeoLocation'
],
fn: function() {
return 'geolocation' in window.navigator;
}
},
{
name: 'SqlDatabase',
fn: function() {
return 'openDatabase' in window;
}
},
{
name: 'WebSockets',
fn: function() {
return 'WebSocket' in window;
}
},
{
name: 'Range',
fn: function() {
return !!document.createRange;
}
},
{
name: 'CreateContextualFragment',
fn: function() {
var range = !!document.createRange ? document.createRange() : false;
return range && !!range.createContextualFragment;
}
},
{
name: 'History',
fn: function() {
return ('history' in window && 'pushState' in window.history);
}
},
{
name: 'CssTransforms',
fn: function() {
return this.isStyleSupported('transform');
}
},
{
name: 'CssTransformNoPrefix',
fn: function() {
return this.isStyleSupportedWithoutPrefix('transform');
}
},
{
name: 'Css3dTransforms',
fn: function() {
return this.has('CssTransforms') && this.isStyleSupported('perspective') && !Ext.browser.is.AndroidStock2;
}
},
{
name: 'CssAnimations',
fn: function() {
return this.isStyleSupported('animationName');
}
},
{
names: [
'CssTransitions',
'Transitions'
],
fn: function() {
return this.isStyleSupported('transitionProperty');
}
},
{
names: [
'Audio',
'AudioTag'
],
fn: function() {
return !!this.getTestElement('audio').canPlayType;
}
},
{
name: 'Video',
fn: function() {
return !!this.getTestElement('video').canPlayType;
}
},
{
name: 'LocalStorage',
fn: function() {
try {
if ('localStorage' in window && window['localStorage'] !== null) {
localStorage.setItem('sencha-localstorage-test', 'test success');
localStorage.removeItem('sencha-localstorage-test');
return true;
}
} catch (e) {}
return false;
}
},
{
name: 'XHR2',
fn: function() {
return window.ProgressEvent && window.FormData && window.XMLHttpRequest && ('withCredentials' in new XMLHttpRequest());
}
},
{
name: 'XHRUploadProgress',
fn: function() {
if (window.XMLHttpRequest && !Ext.browser.is.AndroidStock) {
var xhr = new XMLHttpRequest();
return xhr && ('upload' in xhr) && ('onprogress' in xhr.upload);
}
return false;
}
},
{
name: 'NumericInputPlaceHolder',
fn: function() {
return !(Ext.browser.is.AndroidStock4 && Ext.os.version.getMinor() < 2);
}
},
{
name: 'ProperHBoxStretching',
ready: true,
fn: function() {
var bodyElement = document.createElement('div'),
innerElement = bodyElement.appendChild(document.createElement('div')),
contentElement = innerElement.appendChild(document.createElement('div')),
innerWidth;
bodyElement.setAttribute('style', 'width: 100px; height: 100px; position: relative;');
innerElement.setAttribute('style', 'position: absolute; display: -ms-flexbox; display: -webkit-flex; display: -moz-flexbox; display: flex; -ms-flex-direction: row; -webkit-flex-direction: row; -moz-flex-direction: row; flex-direction: row; min-width: 100%;');
contentElement.setAttribute('style', 'width: 200px; height: 50px;');
document.body.appendChild(bodyElement);
innerWidth = innerElement.offsetWidth;
document.body.removeChild(bodyElement);
return (innerWidth > 100);
}
},
{
name: 'matchesSelector',
fn: function() {
var el = document.documentElement,
w3 = 'matches',
wk = 'webkitMatchesSelector',
ms = 'msMatchesSelector',
mz = 'mozMatchesSelector';
return el[w3] ? w3 : el[wk] ? wk : el[ms] ? ms : el[mz] ? mz : null;
}
},
{
name: 'RightMargin',
ready: true,
fn: function(doc, div) {
var view = doc.defaultView;
return !(view && view.getComputedStyle(div.firstChild.firstChild, null).marginRight !== '0px');
}
},
{
name: 'DisplayChangeInputSelectionBug',
fn: function() {
var webKitVersion = Ext.webKitVersion;
return 0 < webKitVersion && webKitVersion < 533;
}
},
{
name: 'DisplayChangeTextAreaSelectionBug',
fn: function() {
var webKitVersion = Ext.webKitVersion;
return 0 < webKitVersion && webKitVersion < 534.24;
}
},
{
name: 'TransparentColor',
ready: true,
fn: function(doc, div, view) {
view = doc.defaultView;
return !(view && view.getComputedStyle(div.lastChild, null).backgroundColor !== 'transparent');
}
},
{
name: 'ComputedStyle',
ready: true,
fn: function(doc, div, view) {
view = doc.defaultView;
return view && view.getComputedStyle;
}
},
{
name: 'Float',
fn: function(doc) {
return 'cssFloat' in doc.documentElement.style;
}
},
{
name: 'CSS3BorderRadius',
ready: true,
fn: function(doc) {
var domPrefixes = [
'borderRadius',
'BorderRadius',
'MozBorderRadius',
'WebkitBorderRadius',
'OBorderRadius',
'KhtmlBorderRadius'
],
pass = false,
i;
for (i = 0; i < domPrefixes.length; i++) {
if (doc.documentElement.style[domPrefixes[i]] !== undefined) {
pass = true;
}
}
return pass && !Ext.isIE9;
}
},
{
name: 'CSS3LinearGradient',
fn: function(doc, div) {
var property = 'background-image:',
webkit = '-webkit-gradient(linear, left top, right bottom, from(black), to(white))',
w3c = 'linear-gradient(left top, black, white)',
moz = '-moz-' + w3c,
ms = '-ms-' + w3c,
opera = '-o-' + w3c,
options = [
property + webkit,
property + w3c,
property + moz,
property + ms,
property + opera
];
div.style.cssText = options.join(';');
return (("" + div.style.backgroundImage).indexOf('gradient') !== -1) && !Ext.isIE9;
}
},
{
name: 'MouseEnterLeave',
fn: function(doc) {
return ('onmouseenter' in doc.documentElement && 'onmouseleave' in doc.documentElement);
}
},
{
name: 'MouseWheel',
fn: function(doc) {
return ('onmousewheel' in doc.documentElement);
}
},
{
name: 'Opacity',
fn: function(doc, div) {
if (Ext.isIE8) {
return false;
}
div.firstChild.style.cssText = 'opacity:0.73';
return div.firstChild.style.opacity == '0.73';
}
},
{
name: 'Placeholder',
fn: function(doc) {
return 'placeholder' in doc.createElement('input');
}
},
{
name: 'Direct2DBug',
fn: function(doc) {
return Ext.isString(doc.documentElement.style.msTransformOrigin) && Ext.isIE9m;
}
},
{
name: 'BoundingClientRect',
fn: function(doc) {
return 'getBoundingClientRect' in doc.documentElement;
}
},
{
name: 'RotatedBoundingClientRect',
ready: true,
fn: function(doc) {
var body = doc.body,
supports = false,
el = this.getTestElement(),
style = el.style;
if (el.getBoundingClientRect) {
style.WebkitTransform = style.MozTransform = style.msTransform = style.OTransform = style.transform = 'rotate(90deg)';
style.width = '100px';
style.height = '30px';
body.appendChild(el);
supports = el.getBoundingClientRect().height !== 100;
body.removeChild(el);
}
return supports;
}
},
{
name: 'ChildContentClearedWhenSettingInnerHTML',
ready: true,
fn: function() {
var el = this.getTestElement(),
child;
el.innerHTML = '<div>a</div>';
child = el.firstChild;
el.innerHTML = '<div>b</div>';
return child.innerHTML !== 'a';
}
},
{
name: 'IncludePaddingInWidthCalculation',
ready: true,
fn: function(doc, div) {
return div.childNodes[1].firstChild.offsetWidth === 210;
}
},
{
name: 'IncludePaddingInHeightCalculation',
ready: true,
fn: function(doc, div) {
return div.childNodes[1].firstChild.offsetHeight === 210;
}
},
{
name: 'TextAreaMaxLength',
fn: function(doc) {
return ('maxlength' in doc.createElement('textarea'));
}
},
{
name: 'GetPositionPercentage',
ready: true,
fn: function(doc, div) {
return Ext.feature.getStyle(div.childNodes[2], 'left') === '10%';
}
},
{
name: 'PercentageHeightOverflowBug',
ready: true,
fn: function(doc) {
var hasBug = false,
style, el;
if (Ext.getScrollbarSize().height) {
el = this.getTestElement();
style = el.style;
style.height = '50px';
style.width = '50px';
style.overflow = 'auto';
style.position = 'absolute';
el.innerHTML = [
'<div style="display:table;height:100%;">',
'<div style="width:51px;"></div>',
'</div>'
].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 = '<div id="b1" style="height:100px;width:100px;direction:rtl;position:relative;overflow:scroll">' + '<div id="b2" style="position:relative;width:100%;height:20px;"></div>' + '<div id="b3" style="position:absolute;width:20px;height:20px;top:0px;right:0px"></div>' + '</div>';
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 = '<span style="display:inline-block;zoom:1;height:60px;width:60px;"></span>';
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 = '<div style="height:100px;width:100px;direction:rtl;overflow:scroll">' + '<div style="width:20px;height:200px;"></div>' + '</div>';
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 = '<div style="height:100px;width:100px;direction:rtl;overflow:auto">' + '<div style="width:95px;height:200px;"></div>' + '</div>';
var outerBox = div.firstChild;
return outerBox.clientHeight === outerBox.offsetHeight;
}
},
{
identity: 'defineProperty',
fn: function() {
if (Ext.isIE8m) {
Ext.Object.defineProperty = Ext.emptyFn;
return false;
}
return true;
}
},
{
identify: 'nativeXhr',
fn: function() {
if (typeof XMLHttpRequest !== 'undefined') {
return true;
}
XMLHttpRequest = function() {
try {
return new ActiveXObject('MSXML2.XMLHTTP.3.0');
}
catch (ex) {
return null;
}
};
return false;
}
},
{
name: 'SpecialKeyDownRepeat',
fn: function() {
return Ext.isWebKit ? parseInt(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1], 10) >= 525 : !((Ext.isGecko && !Ext.isWindows) || (Ext.isOpera && Ext.operaVersion < 12));
}
},
{
name: 'EmulatedMouseOver',
fn: function() {
return Ext.os.is.iOS;
}
},
{
name: 'Hashchange',
fn: function() {
var docMode = document.documentMode;
return 'onhashchange' in window && (docMode === undefined || docMode > 7);
}
},
{
name: 'FixedTableWidthBug',
ready: true,
fn: function() {
if (Ext.isIE8) {
return false;
}
var outer = document.createElement('div'),
inner = document.createElement('div'),
width;
outer.setAttribute('style', 'display:table;table-layout:fixed;');
inner.setAttribute('style', 'display:table-cell;min-width:50px;');
outer.appendChild(inner);
document.body.appendChild(outer);
outer.offsetWidth;
outer.style.width = '25px';
width = outer.offsetWidth;
document.body.removeChild(outer);
return width === 50;
}
},
{
name: 'FocusinFocusoutEvents',
fn: function() {
return !Ext.isGecko;
}
},
0
]
};
Ext.feature.tests.pop();
Ext.supports = {};
Ext.feature.detect();
Ext.env.Ready = {
blocks: (location.search || '').indexOf('ext-pauseReadyFire') > 0 ? 1 : 0,
bound: 0,
delay: 1,
events: [],
firing: false,
generation: 0,
listeners: [],
nextId: 0,
sortGeneration: 0,
state: 0,
timer: null,
bind: function() {
var me = Ext.env.Ready,
doc = document;
if (!me.bound) {
if (doc.readyState === 'complete') {
me.onReadyEvent({
type: doc.readyState || 'body'
});
} else {
me.bound = 1;
if (Ext.browser.is.PhoneGap && !Ext.os.is.Desktop) {
me.bound = 2;
doc.addEventListener('deviceready', me.onReadyEvent, false);
}
doc.addEventListener('DOMContentLoaded', me.onReadyEvent, false);
window.addEventListener('load', me.onReadyEvent, false);
}
}
},
block: function() {
++this.blocks;
Ext.isReady = false;
},
fireReady: function() {
var me = Ext.env.Ready;
if (!me.state) {
Ext._readyTime = Ext.now();
Ext.isDomReady = true;
me.state = 1;
Ext.feature.detect(true);
if (!me.delay) {
me.handleReady();
} else if (navigator.standalone) {
me.timer = Ext.defer(function() {
me.timer = null;
me.handleReadySoon();
}, 1);
} else {
me.handleReadySoon();
}
}
},
handleReady: function() {
var me = this;
if (me.state === 1) {
me.state = 2;
Ext._beforeReadyTime = Ext.now();
me.invokeAll();
Ext._afterReadytime = Ext.now();
}
},
handleReadySoon: function(delay) {
var me = this;
if (!me.timer) {
me.timer = Ext.defer(function() {
me.timer = null;
me.handleReady();
}, delay || me.delay);
}
},
invoke: function(listener) {
var delay = listener.delay;
if (delay) {
Ext.defer(listener.fn, delay, listener.scope);
} else {
if (Ext.elevateFunction) {
Ext.elevateFunction(listener.fn, listener.scope);
} else {
listener.fn.call(listener.scope);
}
}
},
invokeAll: function() {
if (Ext.elevateFunction) {
Ext.elevateFunction(this.doInvokeAll, this);
} else {
this.doInvokeAll();
}
},
doInvokeAll: function() {
var me = this,
listeners = me.listeners,
listener;
if (!me.blocks) {
Ext.isReady = true;
}
me.firing = true;
while (listeners.length) {
if (me.sortGeneration !== me.generation) {
me.sortGeneration = me.generation;
listeners.sort(me.sortFn);
}
listener = listeners.pop();
if (me.blocks && !listener.dom) {
listeners.push(listener);
break;
}
me.invoke(listener);
}
me.firing = false;
},
makeListener: function(fn, scope, options) {
var ret = {
fn: fn,
id: ++this.nextId,
scope: scope,
dom: false,
priority: 0
};
if (options) {
Ext.apply(ret, options);
}
ret.phase = ret.dom ? 0 : 1;
return ret;
},
on: function(fn, scope, options) {
var me = Ext.env.Ready,
listener = me.makeListener(fn, scope, options);
if (me.state === 2 && !me.firing && (listener.dom || !me.blocks)) {
me.invoke(listener);
} else {
me.listeners.push(listener);
++me.generation;
if (!me.bound) {
me.bind();
}
}
},
onReadyEvent: function(ev) {
var me = Ext.env.Ready;
if (Ext.elevateFunction) {
Ext.elevateFunction(me.doReadyEvent, me, arguments);
} else {
me.doReadyEvent(ev);
}
},
doReadyEvent: function(ev) {
var me = this;
if (ev && ev.type) {
me.events.push(ev);
}
if (me.bound > 0) {
me.unbind();
me.bound = -1;
}
if (!me.state) {
me.fireReady();
}
},
sortFn: function(a, b) {
return -((a.phase - b.phase) || (b.priority - a.priority) || (a.id - b.id));
},
unblock: function() {
var me = this;
if (me.blocks) {
if (!--me.blocks) {
if (me.state === 2 && !me.firing) {
me.invokeAll();
}
}
}
},
unbind: function() {
var me = this,
doc = document;
if (me.bound > 1) {
doc.removeEventListener('deviceready', me.onReadyEvent, false);
}
doc.removeEventListener('DOMContentLoaded', me.onReadyEvent, false);
window.removeEventListener('load', me.onReadyEvent, false);
}
};
(function() {
var Ready = Ext.env.Ready;
if (Ext.isIE9m) {
Ext.apply(Ready, {
scrollTimer: null,
readyStatesRe: /complete/i,
pollScroll: function() {
var scrollable = true;
try {
document.documentElement.doScroll('left');
} catch (e) {
scrollable = false;
}
if (scrollable && document.body) {
Ready.onReadyEvent({
type: 'doScroll'
});
} else {
Ready.scrollTimer = Ext.defer(Ready.pollScroll, 20);
}
return scrollable;
},
bind: function() {
if (Ready.bound) {
return;
}
var doc = document,
topContext;
try {
topContext = window.frameElement === undefined;
} catch (e) {}
if (!topContext || !doc.documentElement.doScroll) {
Ready.pollScroll = Ext.emptyFn;
}
else if (Ready.pollScroll()) {
return;
}
if (doc.readyState === 'complete') {
Ready.onReadyEvent({
type: 'already ' + (doc.readyState || 'body')
});
} else {
doc.attachEvent('onreadystatechange', Ready.onReadyStateChange);
window.attachEvent('onload', Ready.onReadyEvent);
Ready.bound = 1;
}
},
unbind: function() {
document.detachEvent('onreadystatechange', Ready.onReadyStateChange);
window.detachEvent('onload', Ready.onReadyEvent);
if (Ext.isNumber(Ready.scrollTimer)) {
clearTimeout(Ready.scrollTimer);
Ready.scrollTimer = null;
}
},
onReadyStateChange: function() {
var state = document.readyState;
if (Ready.readyStatesRe.test(state)) {
Ready.onReadyEvent({
type: state
});
}
}
});
}
Ext.onDocumentReady = function(fn, scope, options) {
var opt = {
dom: true
};
if (options) {
Ext.apply(opt, options);
}
Ready.on(fn, scope, opt);
};
Ext.onReady = function(fn, scope, options) {
Ready.on(fn, scope, options);
};
Ext.onInternalReady = function(fn, scope, options) {
Ready.on(fn, scope, Ext.apply({
priority: 1000
}, options));
};
Ready.bind();
}());
Ext.Loader = (new function() {
var Loader = this,
Manager = Ext.ClassManager,
Boot = Ext.Boot,
Class = Ext.Class,
Ready = Ext.env.Ready,
alias = Ext.Function.alias,
dependencyProperties = [
'extend',
'mixins',
'requires'
],
isInHistory = {},
history = [],
readyListeners = [],
usedClasses = [],
_requiresMap = {},
_missingQueue = {},
_config = {
enabled: true,
scriptChainDelay: false,
disableCaching: true,
disableCachingParam: '_dc',
paths: Manager.paths,
preserveScripts: true,
scriptCharset: undefined
},
delegatedConfigs = {
disableCaching: true,
disableCachingParam: true,
preserveScripts: true,
scriptChainDelay: 'loadDelay'
};
Ext.apply(Loader, {
isInHistory: isInHistory,
isLoading: false,
history: history,
config: _config,
readyListeners: readyListeners,
optionalRequires: usedClasses,
requiresMap: _requiresMap,
hasFileLoadError: false,
scriptsLoading: 0,
classesLoading: [],
syncModeEnabled: false,
missingQueue: _missingQueue,
init: function() {
var scripts = document.getElementsByTagName('script'),
src = scripts[scripts.length - 1].src,
path = src.substring(0, src.lastIndexOf('/') + 1),
meta = Ext._classPathMetadata,
microloader = Ext.Microloader,
manifest = Ext.manifest,
loadOrder, baseUrl, loadlen, l, loadItem;
if (src.indexOf("packages/sencha-core/src/") !== -1) {
path = path + "../../";
} else if (src.indexOf("/core/src/class/") !== -1) {
path = path + "../../../";
}
if (!Manager.getPath("Ext")) {
Manager.setPath('Ext', path + 'src');
}
if (meta) {
Ext._classPathMetadata = null;
Loader.addClassPathMappings(meta);
}
if (manifest) {
loadOrder = manifest.loadOrder;
baseUrl = Ext.Boot.baseUrl;
if (loadOrder && manifest.bootRelative) {
for (loadlen = loadOrder.length , l = 0; l < loadlen; l++) {
loadItem = loadOrder[l];
loadItem.path = baseUrl + loadItem.path;
}
}
}
if (microloader) {
Ready.block();
microloader.onMicroloaderReady(function() {
Ready.unblock();
});
}
},
setConfig: Ext.Function.flexSetter(function(name, value) {
if (name === 'paths') {
Loader.setPath(value);
} else {
_config[name] = value;
var delegated = delegatedConfigs[name];
if (delegated) {
Boot.setConfig((delegated === true) ? name : delegated, value);
}
}
return Loader;
}),
getConfig: function(name) {
return name ? _config[name] : _config;
},
setPath: function() {
Manager.setPath.apply(Manager, arguments);
return Loader;
},
addClassPathMappings: function(paths) {
Manager.setPath(paths);
return Loader;
},
addBaseUrlClassPathMappings: function(pathConfig) {
for (var name in pathConfig) {
pathConfig[name] = Boot.baseUrl + pathConfig[name];
}
Ext.Loader.addClassPathMappings(pathConfig);
},
getPath: function(className) {
return Manager.getPath(className);
},
require: function(expressions, fn, scope, excludes) {
if (excludes) {
return Loader.exclude(excludes).require(expressions, fn, scope);
}
var classNames = Manager.getNamesByExpression(expressions);
return Loader.load(classNames, fn, scope);
},
syncRequire: function() {
var wasEnabled = Loader.syncModeEnabled;
Loader.syncModeEnabled = true;
var ret = Loader.require.apply(Loader, arguments);
Loader.syncModeEnabled = wasEnabled;
return ret;
},
exclude: function(excludes) {
var selector = Manager.select({
require: function(classNames, fn, scope) {
return Loader.load(classNames, fn, scope);
},
syncRequire: function(classNames, fn, scope) {
var wasEnabled = Loader.syncModeEnabled;
Loader.syncModeEnabled = true;
var ret = Loader.load(classNames, fn, scope);
Loader.syncModeEnabled = wasEnabled;
return ret;
}
});
selector.exclude(excludes);
return selector;
},
load: function(classNames, callback, scope) {
if (callback) {
if (callback.length) {
callback = Loader.makeLoadCallback(classNames, callback);
}
callback = callback.bind(scope || Ext.global);
}
var missingClassNames = [],
numClasses = classNames.length,
className, i, numMissing,
urls = [],
state = Manager.classState;
for (i = 0; i < numClasses; ++i) {
className = Manager.resolveName(classNames[i]);
if (!Manager.isCreated(className)) {
missingClassNames.push(className);
_missingQueue[className] = Loader.getPath(className);
if (!state[className]) {
urls.push(_missingQueue[className]);
}
}
}
numMissing = missingClassNames.length;
if (numMissing) {
Loader.missingCount += numMissing;
Ext.Array.push(Loader.classesLoading, missingClassNames);
Manager.onCreated(function() {
Ext.Array.remove(Loader.classesLoading, missingClassNames);
Ext.each(missingClassNames, function(name) {
Ext.Array.remove(Loader.classesLoading, name);
});
if (callback) {
Ext.callback(callback, scope, arguments);
}
Loader.checkReady();
}, Loader, missingClassNames);
if (!_config.enabled) {
Ext.Error.raise("Ext.Loader is not enabled, so dependencies cannot be resolved dynamically. " + "Missing required class" + ((missingClassNames.length > 1) ? "es" : "") + ": " + missingClassNames.join(', '));
}
if (urls.length) {
Loader.loadScripts({
url: urls,
_classNames: missingClassNames
});
} else {
Loader.checkReady();
}
} else {
if (callback) {
callback.call(scope);
}
Loader.checkReady();
}
if (Loader.syncModeEnabled) {
if (numClasses === 1) {
return Manager.get(classNames[0]);
}
}
return Loader;
},
makeLoadCallback: function(classNames, callback) {
return function() {
var classes = [],
i = classNames.length;
while (i-- > 0) {
classes[i] = Manager.get(classNames[i]);
}
return callback.apply(this, classes);
};
},
onLoadFailure: function() {
var options = this,
onError = options.onError;
Loader.hasFileLoadError = true;
--Loader.scriptsLoading;
if (onError) {
onError.call(options.userScope, options);
} else {
Ext.log.error("[Ext.Loader] Some requested files failed to load.");
}
Loader.checkReady();
},
onLoadSuccess: function() {
var options = this,
onLoad = options.onLoad;
--Loader.scriptsLoading;
if (onLoad) {
onLoad.call(options.userScope, options);
}
Loader.checkReady();
},
reportMissingClasses: function() {
if (!Loader.syncModeEnabled && !Loader.scriptsLoading && Loader.isLoading && !Loader.hasFileLoadError) {
var missingClasses = [],
missingPaths = [];
for (var missingClassName in _missingQueue) {
missingClasses.push(missingClassName);
missingPaths.push(_missingQueue[missingClassName]);
}
if (missingClasses.length) {
throw new Error("The following classes are not declared even if their files have been " + "loaded: '" + missingClasses.join("', '") + "'. Please check the source code of their " + "corresponding files for possible typos: '" + missingPaths.join("', '"));
}
}
},
onReady: function(fn, scope, withDomReady, options) {
if (withDomReady) {
Ready.on(fn, scope, options);
} else {
var listener = Ready.makeListener(fn, scope, options);
if (Loader.isLoading) {
readyListeners.push(listener);
} else {
Ready.invoke(listener);
}
}
},
addUsedClasses: function(classes) {
var cls, i, ln;
if (classes) {
classes = (typeof classes === 'string') ? [
classes
] : classes;
for (i = 0 , ln = classes.length; i < ln; i++) {
cls = classes[i];
if (typeof cls === 'string' && !Ext.Array.contains(usedClasses, cls)) {
usedClasses.push(cls);
}
}
}
return Loader;
},
triggerReady: function() {
var listener,
refClasses = usedClasses;
if (Loader.isLoading && refClasses.length) {
usedClasses = [];
Loader.require(refClasses);
} else {
Loader.isLoading = false;
readyListeners.sort(Ready.sortFn);
while (readyListeners.length && !Loader.isLoading) {
listener = readyListeners.pop();
Ready.invoke(listener);
}
Ready.unblock();
}
},
historyPush: function(className) {
if (className && !isInHistory[className] && !Manager.overrideMap[className]) {
isInHistory[className] = true;
history.push(className);
}
return Loader;
},
loadScripts: function(params) {
var manifest = Ext.manifest,
loadOrder = manifest && manifest.loadOrder,
loadOrderMap = manifest && manifest.loadOrderMap,
options;
++Loader.scriptsLoading;
if (loadOrder && !loadOrderMap) {
manifest.loadOrderMap = loadOrderMap = Boot.createLoadOrderMap(loadOrder);
}
Loader.checkReady();
options = Ext.apply({
loadOrder: loadOrder,
loadOrderMap: loadOrderMap,
charset: _config.scriptCharset,
success: Loader.onLoadSuccess,
failure: Loader.onLoadFailure,
sync: Loader.syncModeEnabled,
_classNames: []
}, params);
options.userScope = options.scope;
options.scope = options;
Boot.load(options);
},
loadScriptsSync: function(urls) {
var syncwas = Loader.syncModeEnabled;
Loader.syncModeEnabled = true;
Loader.loadScripts({
url: urls
});
Loader.syncModeEnabled = syncwas;
},
loadScriptsSyncBasePrefix: function(urls) {
var syncwas = Loader.syncModeEnabled;
Loader.syncModeEnabled = true;
Loader.loadScripts({
url: urls,
prependBaseUrl: true
});
Loader.syncModeEnabled = syncwas;
},
loadScript: function(options) {
var isString = typeof options === 'string',
isArray = options instanceof Array,
isObject = !isArray && !isString,
url = isObject ? options.url : options,
onError = isObject && options.onError,
onLoad = isObject && options.onLoad,
scope = isObject && options.scope,
request = {
url: url,
scope: scope,
onLoad: onLoad,
onError: onError,
_classNames: []
};
Loader.loadScripts(request);
},
flushMissingQueue: function() {
var name, val,
missingwas = 0,
missing = 0;
for (name in _missingQueue) {
missingwas++;
val = _missingQueue[name];
if (Manager.isCreated(name)) {
delete _missingQueue[name];
} else if (Manager.existCache[name] === 2) {
delete _missingQueue[name];
} else {
++missing;
}
}
this.missingCount = missing;
},
checkReady: function() {
var wasLoading = Loader.isLoading,
isLoading;
Loader.flushMissingQueue();
isLoading = Loader.missingCount + Loader.scriptsLoading;
if (isLoading && !wasLoading) {
Ready.block();
Loader.isLoading = !!isLoading;
} else if (!isLoading && wasLoading) {
Loader.triggerReady();
}
}
});
Ext.require = alias(Loader, 'require');
Ext.syncRequire = alias(Loader, 'syncRequire');
Ext.exclude = alias(Loader, 'exclude');
Class.registerPreprocessor('loader', function(cls, data, hooks, continueFn) {
Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.Loader#loaderPreprocessor', arguments);
var me = this,
dependencies = [],
dependency,
className = Manager.getName(cls),
i, j, ln, subLn, value, propertyName, propertyValue, requiredMap;
for (i = 0 , ln = dependencyProperties.length; i < ln; i++) {
propertyName = dependencyProperties[i];
if (data.hasOwnProperty(propertyName)) {
propertyValue = data[propertyName];
if (typeof propertyValue === 'string') {
dependencies.push(propertyValue);
} else if (propertyValue instanceof Array) {
for (j = 0 , subLn = propertyValue.length; j < subLn; j++) {
value = propertyValue[j];
if (typeof value === 'string') {
dependencies.push(value);
}
}
} else if (typeof propertyValue !== 'function') {
for (j in propertyValue) {
if (propertyValue.hasOwnProperty(j)) {
value = propertyValue[j];
if (typeof value === 'string') {
dependencies.push(value);
}
}
}
}
}
}
if (dependencies.length === 0) {
return;
}
if (className) {
_requiresMap[className] = dependencies;
}
var deadlockPath = [],
detectDeadlock;
if (className) {
requiredMap = Loader.requiredByMap || (Loader.requiredByMap = {});
for (i = 0 , ln = dependencies.length; i < ln; i++) {
dependency = dependencies[i];
(requiredMap[dependency] || (requiredMap[dependency] = [])).push(className);
}
detectDeadlock = function(cls) {
deadlockPath.push(cls);
if (_requiresMap[cls]) {
if (Ext.Array.contains(_requiresMap[cls], className)) {
Ext.Error.raise("Circular requirement detected! '" + className + "' and '" + deadlockPath[1] + "' mutually require each other. Path: " + deadlockPath.join(' -> ') + " -> " + deadlockPath[0]);
}
for (i = 0 , ln = _requiresMap[cls].length; i < ln; i++) {
detectDeadlock(_requiresMap[cls][i]);
}
}
};
detectDeadlock(className);
}
(className ? Loader.exclude(className) : Loader).require(dependencies, function() {
for (i = 0 , ln = dependencyProperties.length; i < ln; i++) {
propertyName = dependencyProperties[i];
if (data.hasOwnProperty(propertyName)) {
propertyValue = data[propertyName];
if (typeof propertyValue === 'string') {
data[propertyName] = Manager.get(propertyValue);
} else if (propertyValue instanceof Array) {
for (j = 0 , subLn = propertyValue.length; j < subLn; j++) {
value = propertyValue[j];
if (typeof value === 'string') {
data[propertyName][j] = Manager.get(value);
}
}
} else if (typeof propertyValue !== 'function') {
for (var k in propertyValue) {
if (propertyValue.hasOwnProperty(k)) {
value = propertyValue[k];
if (typeof value === 'string') {
data[propertyName][k] = Manager.get(value);
}
}
}
}
}
}
continueFn.call(me, cls, data, hooks);
});
return false;
}, true, 'after', 'className');
Manager.registerPostprocessor('uses', function(name, cls, data) {
Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.Loader#usesPostprocessor', arguments);
var manifest = Ext.manifest,
loadOrder = manifest && manifest.loadOrder,
classes = manifest && manifest.classes,
uses, clazz, item, len, i, indexMap;
if (loadOrder) {
clazz = classes[name];
if (clazz && !isNaN(i = clazz.idx)) {
item = loadOrder[i];
uses = item.uses;
indexMap = {};
for (len = uses.length , i = 0; i < len; i++) {
indexMap[uses[i]] = true;
}
uses = Ext.Boot.getPathsFromIndexes(indexMap, loadOrder, true);
if (uses.length > 0) {
Loader.loadScripts({
url: uses,
sequential: true
});
}
}
}
if (data.uses) {
uses = data.uses;
Loader.addUsedClasses(uses);
}
});
Manager.onCreated(Loader.historyPush);
Loader.init();
}());
Ext._endTime = new Date().getTime();
if (Ext._beforereadyhandler) {
Ext._beforereadyhandler();
}
Ext.define('Ext.Mixin', function(Mixin) {
return {
statics: {
addHook: function(hookFn, targetClass, methodName, mixinClassPrototype) {
var isFunc = Ext.isFunction(hookFn),
hook = function() {
var a = arguments,
fn = isFunc ? hookFn : mixinClassPrototype[hookFn],
result = this.callParent(a);
fn.apply(this, a);
return result;
},
existingFn = targetClass.hasOwnProperty(methodName) && targetClass[methodName];
if (isFunc) {
hookFn.$previous = Ext.emptyFn;
}
hook.$name = methodName;
hook.$owner = targetClass.self;
if (existingFn) {
hook.$previous = existingFn.$previous;
existingFn.$previous = hook;
} else {
targetClass[methodName] = hook;
}
}
},
onClassExtended: function(cls, data) {
var mixinConfig = data.mixinConfig,
hooks = data.xhooks,
superclass = cls.superclass,
onClassMixedIn = data.onClassMixedIn,
parentMixinConfig, befores, afters, extended;
if (hooks) {
delete data.xhooks;
(mixinConfig || (data.mixinConfig = mixinConfig = {})).on = hooks;
}
if (mixinConfig) {
parentMixinConfig = superclass.mixinConfig;
if (parentMixinConfig) {
data.mixinConfig = mixinConfig = Ext.merge({}, parentMixinConfig, mixinConfig);
}
data.mixinId = mixinConfig.id;
if (mixinConfig.beforeHooks) {
Ext.Error.raise('Use of "beforeHooks" is deprecated - use "before" instead');
}
if (mixinConfig.hooks) {
Ext.Error.raise('Use of "hooks" is deprecated - use "after" instead');
}
if (mixinConfig.afterHooks) {
Ext.Error.raise('Use of "afterHooks" is deprecated - use "after" instead');
}
befores = mixinConfig.before;
afters = mixinConfig.after;
hooks = mixinConfig.on;
extended = mixinConfig.extended;
}
if (befores || afters || hooks || extended) {
data.onClassMixedIn = function(targetClass) {
var mixin = this.prototype,
targetProto = targetClass.prototype,
key;
if (befores) {
Ext.Object.each(befores, function(key, value) {
targetClass.addMember(key, function() {
if (mixin[value].apply(this, arguments) !== false) {
return this.callParent(arguments);
}
});
});
}
if (afters) {
Ext.Object.each(afters, function(key, value) {
targetClass.addMember(key, function() {
var ret = this.callParent(arguments);
mixin[value].apply(this, arguments);
return ret;
});
});
}
if (hooks) {
for (key in hooks) {
Mixin.addHook(hooks[key], targetProto, key, mixin);
}
}
if (extended) {
targetClass.onExtended(function() {
var args = Ext.Array.slice(arguments, 0);
args.unshift(targetClass);
return extended.apply(this, args);
}, this);
}
if (onClassMixedIn) {
onClassMixedIn.apply(this, arguments);
}
};
}
}
};
});
Ext.util = Ext.util || {};
Ext.util.DelayedTask = function(fn, scope, args, cancelOnDelay, fireIdleEvent) {
var me = this,
delay,
call = function() {
var globalEvents = Ext.GlobalEvents;
clearInterval(me.id);
me.id = null;
fn.apply(scope, args || []);
if (fireIdleEvent !== false && globalEvents.hasListeners.idle) {
globalEvents.fireEvent('idle');
}
};
cancelOnDelay = typeof cancelOnDelay === 'boolean' ? cancelOnDelay : true;
me.id = null;
me.delay = function(newDelay, newFn, newScope, newArgs) {
if (cancelOnDelay) {
me.cancel();
}
if (typeof newDelay === 'number') {
delay = newDelay;
}
fn = newFn || fn;
scope = newScope || scope;
args = newArgs || args;
if (!me.id) {
me.id = Ext.interval(call, delay);
}
};
me.cancel = function() {
if (me.id) {
clearInterval(me.id);
me.id = null;
}
};
};
Ext.define('Ext.util.Event', function() {
var arraySlice = Array.prototype.slice,
arrayInsert = Ext.Array.insert,
toArray = Ext.Array.toArray,
fireArgs = {};
return {
requires: 'Ext.util.DelayedTask',
isEvent: true,
suspended: 0,
noOptions: {},
constructor: function(observable, name) {
this.name = name;
this.observable = observable;
this.listeners = [];
},
addListener: function(fn, scope, options, caller, manager) {
var me = this,
added = false,
observable = me.observable,
eventName = me.name,
listeners, listener, priority, isNegativePriority, highestNegativePriorityIndex, hasNegativePriorityIndex, length, index, i, listenerPriority;
if (scope && !Ext._namedScopes[scope] && (typeof fn === 'string') && (typeof scope[fn] !== 'function')) {
Ext.Error.raise("No method named '" + fn + "' found on scope object");
}
if (me.findListener(fn, scope) === -1) {
listener = me.createListener(fn, scope, options, caller, manager);
if (me.firing) {
me.listeners = me.listeners.slice(0);
}
listeners = me.listeners;
index = length = listeners.length;
priority = options && options.priority;
highestNegativePriorityIndex = me._highestNegativePriorityIndex;
hasNegativePriorityIndex = highestNegativePriorityIndex !== undefined;
if (priority) {
isNegativePriority = (priority < 0);
if (!isNegativePriority || hasNegativePriorityIndex) {
for (i = (isNegativePriority ? highestNegativePriorityIndex : 0); i < length; i++) {
listenerPriority = listeners[i].o ? listeners[i].o.priority || 0 : 0;
if (listenerPriority < priority) {
index = i;
break;
}
}
} else {
me._highestNegativePriorityIndex = index;
}
} else if (hasNegativePriorityIndex) {
index = highestNegativePriorityIndex;
}
if (!isNegativePriority && index <= highestNegativePriorityIndex) {
me._highestNegativePriorityIndex++;
}
if (index === length) {
listeners[length] = listener;
} else {
arrayInsert(listeners, index, [
listener
]);
}
if (observable.isElement) {
observable._getPublisher(eventName).subscribe(observable, eventName, options.delegated !== false, options.capture);
}
added = true;
}
return added;
},
createListener: function(fn, scope, o, caller, manager) {
var me = this,
namedScope = Ext._namedScopes[scope],
listener = {
fn: fn,
scope: scope,
ev: me,
caller: caller,
manager: manager,
namedScope: namedScope,
defaultScope: namedScope ? (scope || me.observable) : undefined,
lateBound: typeof fn === 'string'
},
handler = fn,
wrapped = false,
type;
if (o) {
listener.o = o;
if (o.single) {
handler = me.createSingle(handler, listener, o, scope);
wrapped = true;
}
if (o.target) {
handler = me.createTargeted(handler, listener, o, scope, wrapped);
wrapped = true;
}
if (o.delay) {
handler = me.createDelayed(handler, listener, o, scope, wrapped);
wrapped = true;
}
if (o.buffer) {
handler = me.createBuffered(handler, listener, o, scope, wrapped);
wrapped = true;
}
if (me.observable.isElement) {
type = o.type;
if (type) {
listener.type = type;
}
}
}
listener.fireFn = handler;
listener.wrapped = wrapped;
return listener;
},
findListener: function(fn, scope) {
var listeners = this.listeners,
i = listeners.length,
listener;
while (i--) {
listener = listeners[i];
if (listener) {
if (listener.fn === fn && listener.scope == scope) {
return i;
}
}
}
return -1;
},
removeListener: function(fn, scope, index) {
var me = this,
removed = false,
observable = me.observable,
eventName = me.name,
listener, highestNegativePriorityIndex, options, k, manager, managedListeners, managedListener, i;
index = index || me.findListener(fn, scope);
if (index != -1) {
listener = me.listeners[index];
options = listener.o;
highestNegativePriorityIndex = me._highestNegativePriorityIndex;
if (me.firing) {
me.listeners = me.listeners.slice(0);
}
if (listener.task) {
listener.task.cancel();
delete listener.task;
}
k = listener.tasks && listener.tasks.length;
if (k) {
while (k--) {
listener.tasks[k].cancel();
}
delete listener.tasks;
}
me.listeners.splice(index, 1);
manager = listener.manager;
if (manager) {
managedListeners = manager.managedListeners;
if (managedListeners) {
for (i = managedListeners.length; i--; ) {
managedListener = managedListeners[i];
if (managedListener.item === me.observable && managedListener.ename === eventName && managedListener.fn === fn && managedListener.scope === scope) {
managedListeners.splice(i, 1);
}
}
}
}
if (highestNegativePriorityIndex) {
if (index < highestNegativePriorityIndex) {
me._highestNegativePriorityIndex--;
} else if (index === highestNegativePriorityIndex && index === me.listeners.length) {
delete me._highestNegativePriorityIndex;
}
}
if (observable.isElement) {
observable._getPublisher(eventName).unsubscribe(observable, eventName, options.delegated !== false, options.capture);
}
removed = true;
}
return removed;
},
clearListeners: function() {
var listeners = this.listeners,
i = listeners.length,
listener;
while (i--) {
listener = listeners[i];
this.removeListener(listener.fn, listener.scope);
}
},
suspend: function() {
++this.suspended;
},
resume: function() {
if (this.suspended) {
--this.suspended;
}
},
isSuspended: function() {
return this.suspended > 0;
},
fire: function() {
var me = this,
listeners = me.listeners,
count = listeners.length,
isElement = me.observable.isElement,
options, delegate, fireInfo, i, args, listener, len, delegateEl, currentTarget, type, chained, firingArgs, e;
if (!me.suspended && count > 0) {
me.firing = true;
args = arguments.length ? arraySlice.call(arguments, 0) : [];
len = args.length;
if (isElement) {
e = args[0];
}
for (i = 0; i < count; i++) {
listener = listeners[i];
options = listener.o;
if (isElement) {
if (currentTarget) {
e.setCurrentTarget(currentTarget);
}
type = listener.type;
if (type) {
chained = e;
e = args[0] = chained.chain({
type: type
});
}
Ext.EventObject = e;
}
firingArgs = args;
if (options) {
if (isElement) {
delegate = options.delegate;
if (delegate) {
delegateEl = e.getTarget('#' + e.currentTarget.id + ' ' + delegate);
if (delegateEl) {
args[1] = delegateEl;
currentTarget = e.currentTarget;
e.setCurrentTarget(delegateEl);
} else {
continue;
}
}
if (options.preventDefault) {
e.preventDefault();
}
if (options.stopPropagation) {
e.stopPropagation();
}
if (options.stopEvent) {
e.stopEvent();
}
}
args[len] = options;
if (options.args) {
firingArgs = options.args.concat(args);
}
}
fireInfo = me.getFireInfo(listener);
if (fireInfo.fn.apply(fireInfo.scope, firingArgs) === false) {
return (me.firing = false);
}
if (chained) {
e = args[0] = chained;
chained = null;
}
}
}
me.firing = false;
return true;
},
getFireInfo: function(listener, fromWrapped) {
var observable = this.observable,
fireFn = listener.fireFn,
scope = listener.scope,
namedScope = listener.namedScope,
fn;
if (!fromWrapped && listener.wrapped) {
fireArgs.fn = fireFn;
return fireArgs;
}
fn = fromWrapped ? listener.fn : fireFn;
var name = fn;
if (listener.lateBound) {
if (!scope || namedScope) {
scope = (listener.caller || observable).resolveListenerScope(listener.defaultScope);
}
if (!scope) {
Ext.Error.raise('Unable to dynamically resolve scope for "' + listener.ev.name + '" listener on ' + this.observable.id);
}
if (!Ext.isFunction(scope[fn])) {
Ext.Error.raise('No method named "' + fn + '" on ' + (scope.$className || 'scope object.'));
}
fn = scope[fn];
} else if (namedScope && namedScope.isController) {
scope = (listener.caller || observable).resolveListenerScope(listener.defaultScope);
if (!scope) {
Ext.Error.raise('Unable to dynamically resolve scope for "' + listener.ev.name + '" listener on ' + this.observable.id);
}
} else if (!scope || namedScope) {
scope = observable;
}
fireArgs.fn = fn;
fireArgs.scope = scope;
if (!fn) {
Ext.Error.raise('Unable to dynamically resolve method "' + name + '" on ' + this.observable.$className);
}
return fireArgs;
},
createTargeted: function(handler, listener, o, scope, wrapped) {
return function() {
if (o.target === arguments[0]) {
var fireInfo;
if (!wrapped) {
fireInfo = listener.ev.getFireInfo(listener, true);
handler = fireInfo.fn;
scope = fireInfo.scope;
}
return handler.apply(scope, arguments);
}
};
},
createBuffered: function(handler, listener, o, scope, wrapped) {
listener.task = new Ext.util.DelayedTask();
return function() {
var fireInfo;
if (!wrapped) {
fireInfo = listener.ev.getFireInfo(listener, true);
handler = fireInfo.fn;
scope = fireInfo.scope;
}
listener.task.delay(o.buffer, handler, scope, toArray(arguments));
};
},
createDelayed: function(handler, listener, o, scope, wrapped) {
return function() {
var task = new Ext.util.DelayedTask(),
fireInfo;
if (!wrapped) {
fireInfo = listener.ev.getFireInfo(listener, true);
handler = fireInfo.fn;
scope = fireInfo.scope;
}
if (!listener.tasks) {
listener.tasks = [];
}
listener.tasks.push(task);
task.delay(o.delay || 10, handler, scope, toArray(arguments));
};
},
createSingle: function(handler, listener, o, scope, wrapped) {
return function() {
var event = listener.ev,
fireInfo;
if (event.removeListener(listener.fn, scope) && event.observable) {
event.observable.hasListeners[event.name]--;
}
if (!wrapped) {
fireInfo = event.getFireInfo(listener, true);
handler = fireInfo.fn;
scope = fireInfo.scope;
}
return handler.apply(scope, arguments);
};
}
};
});
//@tag dom,core
Ext.define('Ext.mixin.Identifiable', {
statics: {
uniqueIds: {}
},
isIdentifiable: true,
mixinId: 'identifiable',
idCleanRegex: /\.|[^\w\-]/g,
defaultIdPrefix: 'ext-',
defaultIdSeparator: '-',
getOptimizedId: function() {
return this.id;
},
getUniqueId: function() {
var id = this.id,
prototype, separator, xtype, uniqueIds, prefix;
if (!(id || id === 0)) {
prototype = this.self.prototype;
separator = this.defaultIdSeparator;
uniqueIds = Ext.mixin.Identifiable.uniqueIds;
if (!prototype.hasOwnProperty('identifiablePrefix')) {
xtype = this.xtype;
if (xtype) {
prefix = this.defaultIdPrefix + xtype.replace(this.idCleanRegex, separator) + separator;
} else if (!(prefix = prototype.$className)) {
prefix = this.defaultIdPrefix + 'anonymous' + separator;
} else {
prefix = prefix.replace(this.idCleanRegex, separator).toLowerCase() + separator;
}
prototype.identifiablePrefix = prefix;
}
prefix = this.identifiablePrefix;
if (!uniqueIds.hasOwnProperty(prefix)) {
uniqueIds[prefix] = 0;
}
id = this.id = prefix + (++uniqueIds[prefix]);
}
this.getUniqueId = this.getOptimizedId;
return id;
},
setId: function(id) {
this.id = id;
},
getId: function() {
var id = this.id;
if (!id) {
id = this.getUniqueId();
}
this.getId = this.getOptimizedId;
return id;
}
});
Ext.define('Ext.mixin.Observable', function(Observable) {
var emptyFn = Ext.emptyFn,
emptyArray = [],
arrayProto = Array.prototype,
arraySlice = arrayProto.slice,
ListenerRemover = function(observable) {
if (observable instanceof ListenerRemover) {
return observable;
}
this.observable = observable;
if (arguments[1].isObservable) {
this.managedListeners = true;
}
this.args = arraySlice.call(arguments, 1);
};
ListenerRemover.prototype.destroy = function() {
this.destroy = Ext.emptyFn;
var observable = this.observable;
observable[this.managedListeners ? 'mun' : 'un'].apply(observable, this.args);
};
return {
extend: 'Ext.Mixin',
mixinConfig: {
id: 'observable',
after: {
destroy: 'clearListeners'
}
},
requires: [
'Ext.util.Event'
],
mixins: [
'Ext.mixin.Identifiable'
],
statics: {
releaseCapture: function(o) {
o.fireEventArgs = this.prototype.fireEventArgs;
},
capture: function(o, fn, scope) {
var newFn = function(eventName, args) {
return fn.apply(scope, [
eventName
].concat(args));
};
this.captureArgs(o, newFn, scope);
},
captureArgs: function(o, fn, scope) {
o.fireEventArgs = Ext.Function.createInterceptor(o.fireEventArgs, fn, scope);
},
observe: function(cls, listeners) {
if (cls) {
if (!cls.isObservable) {
Ext.applyIf(cls, new this());
this.captureArgs(cls.prototype, cls.fireEventArgs, cls);
}
if (Ext.isObject(listeners)) {
cls.on(listeners);
}
}
return cls;
},
prepareClass: function(T, mixin, data) {
var listeners = T.listeners = [],
target = data || T.prototype,
targetListeners = target.listeners,
superListeners = mixin ? mixin.listeners : T.superclass.self.listeners,
name, scope, namedScope;
if (superListeners) {
listeners.push(superListeners);
}
if (targetListeners) {
scope = targetListeners.scope;
if (!scope) {
targetListeners.scope = 'self';
} else {
namedScope = Ext._namedScopes[scope];
if (namedScope && namedScope.isController) {
targetListeners.scope = 'self.controller';
}
}
listeners.push(targetListeners);
target.listeners = null;
}
if (!T.HasListeners) {
var HasListeners = function() {},
SuperHL = T.superclass.HasListeners || (mixin && mixin.HasListeners) || Observable.HasListeners;
T.prototype.HasListeners = T.HasListeners = HasListeners;
HasListeners.prototype = T.hasListeners = new SuperHL();
}
}
},
isObservable: true,
eventsSuspended: 0,
constructor: function(config) {
var me = this,
self = me.self,
declaredListeners, listeners, bubbleEvents, len, i;
if (me.$observableInitialized) {
return;
}
me.$observableInitialized = true;
me.hasListeners = new me.HasListeners();
me.events = me.events || {};
declaredListeners = self.listeners;
if (declaredListeners && !me._addDeclaredListeners(declaredListeners)) {
self.listeners = null;
}
listeners = (config && config.listeners) || me.listeners;
if (listeners) {
if (listeners instanceof Array) {
for (i = 0 , len = listeners.length; i < len; ++i) {
me.addListener(listeners[i]);
}
} else {
me.addListener(listeners);
}
}
bubbleEvents = (config && config.bubbleEvents) || me.bubbleEvents;
if (bubbleEvents) {
me.enableBubble(bubbleEvents);
}
if (me.$applyConfigs) {
Ext.apply(me, config);
} else {
me.initConfig(config);
}
if (listeners) {
me.listeners = null;
}
},
onClassExtended: function(T, data) {
if (!T.HasListeners) {
Observable.prepareClass(T, T.prototype.$observableMixedIn ? undefined : data);
}
},
$eventOptions: {
scope: 1,
delay: 1,
buffer: 1,
onFrame: 1,
single: 1,
args: 1,
destroyable: 1,
priority: 1,
order: 1
},
$orderToPriority: {
before: 100,
current: 0,
after: -100
},
_addDeclaredListeners: function(listeners) {
var me = this;
if (listeners instanceof Array) {
Ext.each(listeners, me._addDeclaredListeners, me);
} else {
me._addedDeclaredListeners = true;
me.addListener(listeners);
}
return me._addedDeclaredListeners;
},
addManagedListener: function(item, ename, fn, scope, options,
noDestroy) {
var me = this,
managedListeners = me.managedListeners = me.managedListeners || [],
config, passedOptions;
if (typeof ename !== 'string') {
passedOptions = arguments.length > 4 ? options : ename;
options = ename;
for (ename in options) {
if (options.hasOwnProperty(ename)) {
config = options[ename];
if (!item.$eventOptions[ename]) {
me.addManagedListener(item, ename, config.fn || config, config.scope || options.scope || scope, config.fn ? config : passedOptions, true);
}
}
}
if (options && options.destroyable) {
return new ListenerRemover(me, item, options);
}
} else {
if (fn !== emptyFn) {
item.doAddListener(ename, fn, scope, options, null, me, me);
if (!noDestroy && options && options.destroyable) {
return new ListenerRemover(me, item, ename, fn, scope);
}
}
}
},
removeManagedListener: function(item, ename, fn, scope) {
var me = this,
options, config, managedListeners, length, i;
if (typeof ename !== 'string') {
options = ename;
for (ename in options) {
if (options.hasOwnProperty(ename)) {
config = options[ename];
if (!item.$eventOptions[ename]) {
me.removeManagedListener(item, ename, config.fn || config, config.scope || options.scope || scope);
}
}
}
} else {
managedListeners = me.managedListeners ? me.managedListeners.slice() : [];
ename = Ext.canonicalEventName(ename);
for (i = 0 , length = managedListeners.length; i < length; i++) {
me.removeManagedListenerItem(false, managedListeners[i], item, ename, fn, scope);
}
}
},
fireEvent: function(eventName) {
return this.fireEventArgs(eventName, arraySlice.call(arguments, 1));
},
resolveListenerScope: function(defaultScope) {
var namedScope = Ext._namedScopes[defaultScope];
if (namedScope) {
if (namedScope.isController) {
Ext.Error.raise('scope: "controller" can only be specified on classes that derive from Ext.Component or Ext.Widget');
}
if (namedScope.isSelf || namedScope.isThis) {
defaultScope = null;
}
}
return defaultScope || this;
},
fireEventArgs: function(eventName, args) {
eventName = Ext.canonicalEventName(eventName);
var me = this,
events = me.events,
event = events && events[eventName],
ret = true;
if (me.hasListeners[eventName]) {
ret = me.doFireEvent(eventName, args || emptyArray, event ? event.bubble : false);
}
return ret;
},
fireAction: function(eventName, args, fn, scope, options, order) {
options = options ? Ext.Object.chain(options) : {};
options.single = true;
options.priority = ((order === 'after') ? -99.5 : 99.5);
this.doAddListener(eventName, fn, scope, options);
this.fireEventArgs(eventName, args);
},
doFireEvent: function(eventName, args, bubbles) {
var target = this,
queue, event,
ret = true;
do {
if (target.eventsSuspended) {
if ((queue = target.eventQueue)) {
queue.push([
eventName,
args
]);
}
return ret;
} else {
event = target.events && target.events[eventName];
if (event && event !== true) {
if ((ret = event.fire.apply(event, args)) === false) {
break;
}
}
}
} while (
bubbles && (target = target.getBubbleParent()));
return ret;
},
getBubbleParent: function() {
var me = this,
parent = me.getBubbleTarget && me.getBubbleTarget();
if (parent && parent.isObservable) {
return parent;
}
return null;
},
addListener: function(ename, fn, scope, options, order,
caller) {
var me = this,
namedScopes = Ext._namedScopes,
config, namedScope, isClassListener, innerScope, eventOptions;
if (typeof ename !== 'string') {
options = ename;
scope = options.scope;
namedScope = scope && namedScopes[scope];
isClassListener = namedScope && namedScope.isSelf;
eventOptions = ((me.isComponent || me.isWidget) && options.element) ? me.$elementEventOptions : me.$eventOptions;
for (ename in options) {
config = options[ename];
if (!eventOptions[ename]) {
innerScope = config.scope;
if (innerScope && isClassListener) {
namedScope = namedScopes[innerScope];
if (namedScope && namedScope.isController) {
innerScope = 'self.controller';
}
}
me.doAddListener(ename, config.fn || config, innerScope || scope, config.fn ? config : options, order, caller);
}
}
if (options && options.destroyable) {
return new ListenerRemover(me, options);
}
} else {
me.doAddListener(ename, fn, scope, options, order, caller);
if (options && options.destroyable) {
return new ListenerRemover(me, ename, fn, scope, options);
}
}
return me;
},
removeListener: function(ename, fn, scope,
eventOptions) {
var me = this,
config, options;
if (typeof ename !== 'string') {
options = ename;
eventOptions = eventOptions || me.$eventOptions;
for (ename in options) {
if (options.hasOwnProperty(ename)) {
config = options[ename];
if (!me.$eventOptions[ename]) {
me.doRemoveListener(ename, config.fn || config, config.scope || options.scope);
}
}
}
} else {
me.doRemoveListener(ename, fn, scope);
}
return me;
},
clearListeners: function() {
var me = this,
events = me.events,
hasListeners = me.hasListeners,
event, key;
if (events) {
for (key in events) {
if (events.hasOwnProperty(key)) {
event = events[key];
if (event.isEvent) {
delete hasListeners[key];
event.clearListeners();
}
}
}
}
me.clearManagedListeners();
},
purgeListeners: function() {
if (Ext.global.console) {
Ext.global.console.warn('Observable: purgeListeners has been deprecated. Please use clearListeners.');
}
return this.clearListeners.apply(this, arguments);
},
clearManagedListeners: function() {
var me = this,
managedListeners = me.managedListeners ? me.managedListeners.slice() : [],
i = 0,
len = managedListeners.length;
for (; i < len; i++) {
me.removeManagedListenerItem(true, managedListeners[i]);
}
me.managedListeners = [];
},
removeManagedListenerItem: function(isClear, managedListener, item, ename, fn, scope) {
if (isClear || (managedListener.item === item && managedListener.ename === ename && (!fn || managedListener.fn === fn) && (!scope || managedListener.scope === scope))) {
managedListener.item.doRemoveListener(managedListener.ename, managedListener.fn, managedListener.scope, managedListener.options);
if (!isClear) {
Ext.Array.remove(this.managedListeners, managedListener);
}
}
},
purgeManagedListeners: function() {
if (Ext.global.console) {
Ext.global.console.warn('Observable: purgeManagedListeners has been deprecated. Please use clearManagedListeners.');
}
return this.clearManagedListeners.apply(this, arguments);
},
hasListener: function(ename) {
ename = Ext.canonicalEventName(ename);
return !!this.hasListeners[ename];
},
isSuspended: function(event) {
var suspended = this.eventsSuspended > 0,
events = this.events;
if (!suspended && event && events) {
event = events[event];
if (event && event.isEvent) {
return event.isSuspended();
}
}
return suspended;
},
suspendEvents: function(queueSuspended) {
++this.eventsSuspended;
if (queueSuspended && !this.eventQueue) {
this.eventQueue = [];
}
},
suspendEvent: function() {
var me = this,
events = me.events,
len = arguments.length,
i, event, ename;
for (i = 0; i < len; i++) {
ename = arguments[i];
ename = Ext.canonicalEventName(ename);
event = events[ename];
if (!event || !event.isEvent) {
event = me._initEvent(ename);
}
event.suspend();
}
},
resumeEvent: function() {
var events = this.events || 0,
len = events && arguments.length,
i, event;
for (i = 0; i < len; i++) {
event = events[arguments[i]];
if (event && event.resume) {
event.resume();
}
}
},
resumeEvents: function(discardQueue) {
var me = this,
queued = me.eventQueue,
qLen, q;
if (me.eventsSuspended && !--me.eventsSuspended) {
delete me.eventQueue;
if (!discardQueue && queued) {
qLen = queued.length;
for (q = 0; q < qLen; q++) {
me.fireEventArgs.apply(me, queued[q]);
}
}
}
},
relayEvents: function(origin, events, prefix) {
var me = this,
len = events.length,
i = 0,
oldName,
relayers = {};
for (; i < len; i++) {
oldName = events[i];
relayers[oldName] = me.createRelayer(prefix ? prefix + oldName : oldName);
}
me.mon(origin, relayers, null, null, undefined);
return new ListenerRemover(me, origin, relayers);
},
createRelayer: function(newName, beginEnd) {
var me = this;
return function() {
return me.fireEventArgs.call(me, newName, beginEnd ? arraySlice.apply(arguments, beginEnd) : arguments);
};
},
enableBubble: function(eventNames) {
if (eventNames) {
var me = this,
names = (typeof eventNames == 'string') ? arguments : eventNames,
events = me.events,
length = events && names.length,
ename, event, i;
for (i = 0; i < length; ++i) {
ename = names[i];
ename = Ext.canonicalEventName(ename);
event = events[ename];
if (!event || !event.isEvent) {
event = me._initEvent(ename);
}
me.hasListeners._incr_(ename);
event.bubble = true;
}
}
},
destroy: function() {
this.clearListeners();
this.callParent();
},
privates: {
doAddListener: function(ename, fn, scope, options, order, caller, manager) {
var me = this,
event, managedListeners, priority;
order = order || (options && options.order);
if (order) {
priority = (options && options.priority);
if (!priority) {
options = options ? Ext.Object.chain(options) : {};
options.priority = me.$orderToPriority[order];
}
}
ename = Ext.canonicalEventName(ename);
if (!fn) {
Ext.Error.raise("Cannot add '" + ename + "' listener to " + me.$className + " instance. No function specified.");
}
if (!manager && (scope && scope.isObservable && (scope !== me))) {
manager = scope;
}
if (manager) {
managedListeners = manager.managedListeners = manager.managedListeners || [];
managedListeners.push({
item: me,
ename: ename,
fn: fn,
scope: scope,
options: options
});
}
event = (me.events || (me.events = {}))[ename];
if (!event || !event.isEvent) {
event = me._initEvent(ename);
}
if (fn !== emptyFn) {
if (event.addListener(fn, scope, options, caller, manager)) {
me.hasListeners._incr_(ename);
}
}
},
doRemoveListener: function(ename, fn, scope) {
var me = this,
events = me.events,
event;
ename = Ext.canonicalEventName(ename);
event = events && events[ename];
if (!fn) {
Ext.Error.raise("Cannot remove '" + ename + "' listener to " + me.$className + " instance. No function specified.");
}
if (event && event.isEvent) {
if (event.removeListener(fn, scope)) {
me.hasListeners._decr_(ename);
}
}
},
_initEvent: function(eventName) {
return (this.events[eventName] = new Ext.util.Event(this, eventName));
}
},
deprecated: {
'5.0': {
methods: {
addEvents: null
}
},
'5.1': {
methods: {
addBeforeListener: function(eventName, fn, scope, options) {
return this.addListener(eventName, fn, scope, options, 'before');
},
addAfterListener: function(eventName, fn, scope, options) {
return this.addListener(eventName, fn, scope, options, 'after');
},
removeBeforeListener: function(eventName, fn, scope, options) {
return this.removeListener(eventName, fn, scope, options, 'before');
},
removeAfterListener: function(eventName, fn, scope, options) {
return this.removeListener(eventName, fn, scope, options, 'after');
},
onBefore: 'addBeforeListener',
onAfter: 'addAfterListener',
unBefore: 'removeBeforeListener',
unAfter: 'removeAfterListener'
}
}
}
};
}, function() {
var Observable = this,
proto = Observable.prototype,
HasListeners = function() {},
prepareMixin = function(T) {
if (!T.HasListeners) {
var proto = T.prototype;
proto.$observableMixedIn = 1;
Observable.prepareClass(T, this);
T.onExtended(function(U, data) {
Ext.classSystemMonitor && Ext.classSystemMonitor('extend mixin', arguments);
Observable.prepareClass(U, null, data);
});
if (proto.onClassMixedIn) {
Ext.override(T, {
onClassMixedIn: function(U) {
prepareMixin.call(this, U);
this.callParent(arguments);
}
});
} else {
proto.onClassMixedIn = function(U) {
prepareMixin.call(this, U);
};
}
}
superOnClassMixedIn.call(this, T);
},
superOnClassMixedIn = proto.onClassMixedIn;
HasListeners.prototype = {
_decr_: function(ev) {
if (!--this[ev]) {
delete this[ev];
}
},
_incr_: function(ev) {
if (this.hasOwnProperty(ev)) {
++this[ev];
} else {
this[ev] = 1;
}
}
};
proto.HasListeners = Observable.HasListeners = HasListeners;
Observable.createAlias({
on: 'addListener',
un: 'removeListener',
mon: 'addManagedListener',
mun: 'removeManagedListener',
setListeners: 'addListener'
});
Observable.observeClass = Observable.observe;
function getMethodEvent(method) {
var e = (this.methodEvents = this.methodEvents || {})[method],
returnValue, v, cancel,
obj = this,
makeCall;
if (!e) {
this.methodEvents[method] = e = {};
e.originalFn = this[method];
e.methodName = method;
e.before = [];
e.after = [];
makeCall = function(fn, scope, args) {
if ((v = fn.apply(scope || obj, args)) !== undefined) {
if (typeof v == 'object') {
if (v.returnValue !== undefined) {
returnValue = v.returnValue;
} else {
returnValue = v;
}
cancel = !!v.cancel;
} else if (v === false) {
cancel = true;
} else {
returnValue = v;
}
}
};
this[method] = function() {
var args = Array.prototype.slice.call(arguments, 0),
b, i, len;
returnValue = v = undefined;
cancel = false;
for (i = 0 , len = e.before.length; i < len; i++) {
b = e.before[i];
makeCall(b.fn, b.scope, args);
if (cancel) {
return returnValue;
}
}
if ((v = e.originalFn.apply(obj, args)) !== undefined) {
returnValue = v;
}
for (i = 0 , len = e.after.length; i < len; i++) {
b = e.after[i];
makeCall(b.fn, b.scope, args);
if (cancel) {
return returnValue;
}
}
return returnValue;
};
}
return e;
}
Ext.apply(proto, {
onClassMixedIn: prepareMixin,
beforeMethod: function(method, fn, scope) {
getMethodEvent.call(this, method).before.push({
fn: fn,
scope: scope
});
},
afterMethod: function(method, fn, scope) {
getMethodEvent.call(this, method).after.push({
fn: fn,
scope: scope
});
},
removeMethodListener: function(method, fn, scope) {
var e = this.getMethodEvent(method),
i, len;
for (i = 0 , len = e.before.length; i < len; i++) {
if (e.before[i].fn == fn && e.before[i].scope == scope) {
Ext.Array.erase(e.before, i, 1);
return;
}
}
for (i = 0 , len = e.after.length; i < len; i++) {
if (e.after[i].fn == fn && e.after[i].scope == scope) {
Ext.Array.erase(e.after, i, 1);
return;
}
}
},
toggleEventLogging: function(toggle) {
Ext.util.Observable[toggle ? 'capture' : 'releaseCapture'](this, function(en) {
if (Ext.isDefined(Ext.global.console)) {
Ext.global.console.log(en, arguments);
}
});
}
});
});
Ext.define('Ext.util.HashMap', {
mixins: [
'Ext.mixin.Observable'
],
generation: 0,
config: {
keyFn: null
},
constructor: function(config) {
var me = this,
fn;
me.mixins.observable.constructor.call(me, config);
me.clear(true);
fn = me.getKeyFn();
if (fn) {
me.getKey = fn;
}
},
getCount: function() {
return this.length;
},
getData: function(key, value) {
if (value === undefined) {
value = key;
key = this.getKey(value);
}
return [
key,
value
];
},
getKey: function(o) {
return o.id;
},
add: function(key, value) {
var me = this;
if (arguments.length === 1) {
value = key;
key = me.getKey(value);
}
if (me.containsKey(key)) {
return me.replace(key, value);
}
me.map[key] = value;
++me.length;
me.generation++;
if (me.hasListeners.add) {
me.fireEvent('add', me, key, value);
}
return value;
},
replace: function(key, value) {
var me = this,
map = me.map,
old;
if (arguments.length === 1) {
value = key;
key = me.getKey(value);
}
if (!me.containsKey(key)) {
me.add(key, value);
}
old = map[key];
map[key] = value;
me.generation++;
if (me.hasListeners.replace) {
me.fireEvent('replace', me, key, value, old);
}
return value;
},
remove: function(o) {
var key = this.findKey(o);
if (key !== undefined) {
return this.removeAtKey(key);
}
return false;
},
removeAtKey: function(key) {
var me = this,
value;
if (me.containsKey(key)) {
value = me.map[key];
delete me.map[key];
--me.length;
me.generation++;
if (me.hasListeners.remove) {
me.fireEvent('remove', me, key, value);
}
return true;
}
return false;
},
get: function(key) {
var map = this.map;
return map.hasOwnProperty(key) ? map[key] : undefined;
},
clear: function(
initial) {
var me = this;
if (initial || me.generation) {
me.map = {};
me.length = 0;
me.generation = initial ? 0 : me.generation + 1;
}
if (initial !== true && me.hasListeners.clear) {
me.fireEvent('clear', me);
}
return me;
},
containsKey: function(key) {
var map = this.map;
return map.hasOwnProperty(key) && map[key] !== undefined;
},
contains: function(value) {
return this.containsKey(this.findKey(value));
},
getKeys: function() {
return this.getArray(true);
},
getValues: function() {
return this.getArray(false);
},
getArray: function(isKey) {
var arr = [],
key,
map = this.map;
for (key in map) {
if (map.hasOwnProperty(key)) {
arr.push(isKey ? key : map[key]);
}
}
return arr;
},
each: function(fn, scope) {
var items = Ext.apply({}, this.map),
key,
length = this.length;
scope = scope || this;
for (key in items) {
if (items.hasOwnProperty(key)) {
if (fn.call(scope, key, items[key], length) === false) {
break;
}
}
}
return this;
},
clone: function() {
var hash = new this.self(this.initialConfig),
map = this.map,
key;
hash.suspendEvents();
for (key in map) {
if (map.hasOwnProperty(key)) {
hash.add(key, map[key]);
}
}
hash.resumeEvents();
return hash;
},
findKey: function(value) {
var key,
map = this.map;
for (key in map) {
if (map.hasOwnProperty(key) && map[key] === value) {
return key;
}
}
return undefined;
}
});
Ext.define('Ext.AbstractManager', {
requires: [
'Ext.util.HashMap'
],
typeName: 'type',
constructor: function(config) {
Ext.apply(this, config || {});
this.all = new Ext.util.HashMap();
this.types = {};
},
get: function(id) {
return this.all.get(id);
},
register: function(item) {
var key = this.all.getKey(item);
if (key === undefined) {
Ext.Error.raise('Key is undefined. Please ensure the item has a key before registering the item.');
}
if (this.all.containsKey(key)) {
Ext.Error.raise('Registering duplicate id "' + key + '" with ' + this.$className);
}
this.all.add(item);
},
unregister: function(item) {
this.all.remove(item);
},
registerType: function(type, cls) {
this.types[type] = cls;
cls[this.typeName] = type;
},
isRegistered: function(type) {
return this.types[type] !== undefined;
},
create: function(config, defaultType) {
var type = config[this.typeName] || config.type || defaultType,
Constructor = this.types[type];
if (Constructor === undefined) {
Ext.Error.raise("The '" + type + "' type has not been registered with this manager");
}
return new Constructor(config);
},
onAvailable: function(id, fn, scope) {
var all = this.all,
item, callback;
if (all.containsKey(id)) {
item = all.get(id);
fn.call(scope || item, item);
} else {
callback = function(map, key, item) {
if (key == id) {
fn.call(scope || item, item);
all.un('add', callback);
}
};
all.on('add', callback);
}
},
each: function(fn, scope) {
this.all.each(fn, scope || this);
},
getCount: function() {
return this.all.getCount();
}
});
Ext.define('Ext.data.flash.BinaryXhr', {
statics: {
flashPluginActivated: function() {
Ext.data.flash.BinaryXhr.flashPluginActive = true;
Ext.data.flash.BinaryXhr.flashPlugin = document.getElementById("ext-flash-polyfill");
Ext.GlobalEvents.fireEvent("flashready");
},
flashPluginActive: false,
flashPluginInjected: false,
connectionIndex: 1,
liveConnections: {},
flashPlugin: null,
onFlashStateChange: function(javascriptId, state, data) {
var connection;
connection = this.liveConnections[Number(javascriptId)];
if (connection) {
connection.onFlashStateChange(state, data);
} else {
Ext.warn.log("onFlashStateChange for unknown connection ID: " + javascriptId);
}
},
registerConnection: function(conn) {
var i = this.connectionIndex;
this.conectionIndex = this.connectionIndex + 1;
this.liveConnections[i] = conn;
return i;
},
injectFlashPlugin: function() {
var me = this,
flashLoaderPath, flashObjectPath;
me.flashPolyfillEl = Ext.getBody().appendChild({
id: 'ext-flash-polyfill',
cn: [
{
tag: 'p',
html: 'To view this page ensure that Adobe Flash Player version 11.1.0 or greater is installed.'
},
{
tag: 'a',
href: 'http://www.adobe.com/go/getflashplayer',
cn: [
{
tag: 'img',
src: window.location.protocol + '//www.adobe.com/images/shared/download_buttons/get_flash_player.gif',
alt: 'Get Adobe Flash player'
}
]
}
]
});
flashLoaderPath = [
Ext.Loader.getPath('Ext.data.Connection'),
'../../../plugins/flash/swfobject.js'
].join('/');
flashObjectPath = "/plugins/flash/FlashPlugin.swf";
flashObjectPath = [
Ext.Loader.getPath('Ext.data.Connection'),
'../../plugins/flash/FlashPlugin.swf'
].join('/');
if (Ext.flashPluginPath) {
flashObjectPath = Ext.flashPluginPath;
}
Ext.Loader.loadScript({
url: flashLoaderPath,
onLoad: function() {
var swfVersionStr = "11.4.0";
var xiSwfUrlStr = "playerProductInstall.swf";
var flashvars = {};
var params = {};
params.quality = "high";
params.bgcolor = "#ffffff";
params.allowscriptaccess = "sameDomain";
params.allowfullscreen = "true";
var attributes = {};
attributes.id = "ext-flash-polyfill";
attributes.name = "polyfill";
attributes.align = "middle";
swfobject.embedSWF(flashObjectPath, "ext-flash-polyfill", "0", "0",
swfVersionStr, xiSwfUrlStr, flashvars, params, attributes);
},
onError: function() {
Ext.Error.raise("Could not load flash-loader file swfobject.js from " + flashLoader);
},
scope: me
});
Ext.data.flash.BinaryXhr.flashPluginInjected = true;
}
},
readyState: 0,
status: 0,
statusText: "",
responseBytes: null,
javascriptId: null,
constructor: function(config) {
if (!Ext.data.flash.BinaryXhr.flashPluginInjected) {
Ext.data.flash.BinaryXhr.injectFlashPlugin();
}
var me = this;
Ext.apply(me, config);
me.requestHeaders = {};
},
abort: function() {
var me = this;
if (me.readyState == 4) {
Ext.warn.log("Aborting a connection that's completed its transfer: " + this.url);
return;
}
me.aborted = true;
if (!Ext.data.flash.BinaryXhr.flashPluginActive) {
Ext.GlobalEvents.removeListener("flashready", me.onFlashReady, me);
return;
}
Ext.data.flash.BinaryXhr.flashPlugin.abortRequest(me.javascriptId);
delete Ext.data.flash.BinaryXhr.liveConnections[me.javascriptId];
},
getAllResponseHeaders: function() {
var headers = [];
Ext.Object.each(this.responseHeaders, function(name, value) {
headers.push(name + ': ' + value);
});
return headers.join('\r\n');
},
getResponseHeader: function(header) {
var headers = this.responseHeaders;
return (headers && headers[header]) || null;
},
open: function(method, url, async, user, password) {
var me = this;
me.method = method;
me.url = url;
me.async = async !== false;
me.user = user;
me.password = password;
if (!me.async) {
Ext.Error.raise("Binary posts are only supported in async mode: " + url);
}
if (me.method != "POST") {
Ext.log.warn("Binary data can only be sent as a POST request: " + url);
}
},
overrideMimeType: function(mimeType) {
this.mimeType = mimeType;
},
send: function(body) {
var me = this;
me.body = body;
if (!Ext.data.flash.BinaryXhr.flashPluginActive) {
Ext.GlobalEvents.addListener("flashready", me.onFlashReady, me);
} else {
this.onFlashReady();
}
},
onFlashReady: function() {
var me = this,
req, status;
me.javascriptId = Ext.data.flash.BinaryXhr.registerConnection(me);
req = {
method: me.method,
url: me.url,
user: me.user,
password: me.password,
mimeType: me.mimeType,
requestHeaders: me.requestHeaders,
body: me.body,
javascriptId: me.javascriptId
};
status = Ext.data.flash.BinaryXhr.flashPlugin.postBinary(req);
},
setReadyState: function(state) {
var me = this;
if (me.readyState != state) {
me.readyState = state;
me.onreadystatechange();
}
},
setRequestHeader: function(header, value) {
this.requestHeaders[header] = value;
},
onreadystatechange: Ext.emptyFn,
parseData: function(data) {
var me = this;
this.status = data.status || 0;
me.responseHeaders = {};
if (me.mimeType) {
me.responseHeaders["content-type"] = me.mimeType;
}
if (data.reason == "complete") {
this.responseBytes = data.data;
me.responseHeaders["content-length"] = data.data.length;
} else if (data.reason == "error" || data.reason == "securityError") {
this.statusText = data.text;
me.responseHeaders["content-length"] = 0;
} else
{
Ext.Error.raise("Unkown reason code in data: " + data.reason);
}
},
onFlashStateChange: function(state, data) {
var me = this;
if (state == 4) {
me.parseData(data);
delete Ext.data.flash.BinaryXhr.liveConnections[me.javascriptId];
}
me.setReadyState(state);
}
});
Ext.define('Ext.data.Connection', {
mixins: {
observable: 'Ext.mixin.Observable'
},
requires: [
'Ext.data.flash.BinaryXhr'
],
statics: {
requestId: 0
},
config: {
url: null,
async: true,
username: '',
password: '',
disableCaching: true,
withCredentials: false,
binary: false,
cors: false,
isXdr: false,
defaultXdrContentType: 'text/plain',
disableCachingParam: '_dc',
timeout: 30000,
extraParams: null,
autoAbort: false,
method: null,
defaultHeaders: null,
defaultPostHeader: 'application/x-www-form-urlencoded; charset=UTF-8',
useDefaultXhrHeader: true,
defaultXhrHeader: 'XMLHttpRequest'
},
constructor: function(config) {
this.mixins.observable.constructor.call(this, config);
this.requests = {};
},
request: function(options) {
options = options || {};
var me = this,
scope = options.scope || window,
username = options.username || me.getUsername(),
password = options.password || me.getPassword() || '',
async, requestOptions, request, headers, xdr, xhr;
if (me.fireEvent('beforerequest', me, options) !== false) {
requestOptions = me.setOptions(options, scope);
if (me.isFormUpload(options)) {
me.upload(options.form, requestOptions.url, requestOptions.data, options);
return null;
}
if (options.autoAbort || me.getAutoAbort()) {
me.abort();
}
async = options.async !== false ? (options.async || me.getAsync()) : false;
xhr = me.openRequest(options, requestOptions, async, username, password);
xdr = me.getIsXdr();
if (!xdr) {
headers = me.setupHeaders(xhr, options, requestOptions.data, requestOptions.params);
}
request = {
id: ++Ext.data.Connection.requestId,
xhr: xhr,
headers: headers,
options: options,
async: async,
binary: options.binary || me.getBinary(),
timeout: Ext.defer(function() {
request.timedout = true;
me.abort(request);
}, options.timeout || me.getTimeout())
};
me.requests[request.id] = request;
me.latestId = request.id;
if (async) {
if (!xdr) {
xhr.onreadystatechange = Ext.Function.bind(me.onStateChange, me, [
request
]);
}
}
if (xdr) {
me.processXdrRequest(request, xhr);
}
xhr.send(requestOptions.data);
if (!async) {
return me.onComplete(request);
}
return request;
} else {
Ext.callback(options.callback, options.scope, [
options,
undefined,
undefined
]);
return null;
}
},
processXdrRequest: function(request, xhr) {
var me = this;
delete request.headers;
request.contentType = request.options.contentType || me.getDefaultXdrContentType();
xhr.onload = Ext.Function.bind(me.onStateChange, me, [
request,
true
]);
xhr.onerror = xhr.ontimeout = Ext.Function.bind(me.onStateChange, me, [
request,
false
]);
},
processXdrResponse: function(response, xhr) {
response.getAllResponseHeaders = function() {
return [];
};
response.getResponseHeader = function() {
return '';
};
response.contentType = xhr.contentType || this.getDefaultXdrContentType();
},
upload: function(form, url, params, options) {
form = Ext.getDom(form);
options = options || {};
var id = Ext.id(),
frame = document.createElement('iframe'),
hiddens = [],
encoding = 'multipart/form-data',
buf = {
target: form.target,
method: form.method,
encoding: form.encoding,
enctype: form.enctype,
action: form.action
},
addField = function(name, value) {
hiddenItem = document.createElement('input');
Ext.fly(hiddenItem).set({
type: 'hidden',
value: value,
name: name
});
form.appendChild(hiddenItem);
hiddens.push(hiddenItem);
},
hiddenItem, obj, value, name, vLen, v, hLen, h;
Ext.fly(frame).set({
id: id,
name: id,
cls: Ext.baseCSSPrefix + 'hidden-display',
src: Ext.SSL_SECURE_URL,
tabIndex: -1
});
document.body.appendChild(frame);
if (document.frames) {
document.frames[id].name = id;
}
Ext.fly(form).set({
target: id,
method: 'POST',
enctype: encoding,
encoding: encoding,
action: url || buf.action
});
if (params) {
obj = Ext.Object.fromQueryString(params) || {};
for (name in obj) {
if (obj.hasOwnProperty(name)) {
value = obj[name];
if (Ext.isArray(value)) {
vLen = value.length;
for (v = 0; v < vLen; v++) {
addField(name, value[v]);
}
} else {
addField(name, value);
}
}
}
}
Ext.get(frame).on({
load: Ext.Function.bind(this.onUploadComplete, this, [
frame,
options
]),
single: !Ext.isOpera
});
form.submit();
Ext.fly(form).set(buf);
for (hLen = hiddens.length , h = 0; h < hLen; h++) {
Ext.removeNode(hiddens[h]);
}
},
onUploadComplete: function(frame, options) {
var me = this,
response = {
responseText: '',
responseXML: null
},
callback, success, doc, contentNode;
try {
doc = (frame && (frame.contentWindow.document || frame.contentDocument)) || (window.frames[frame.id] || {}).document;
if (doc) {
if (Ext.isOpera && doc.location == Ext.SSL_SECURE_URL) {
return;
}
if (doc.body) {
if ((contentNode = doc.body.firstChild) && /pre/i.test(contentNode.tagName)) {
response.responseText = contentNode.textContent || contentNode.innerText;
}
else if ((contentNode = doc.getElementsByTagName('textarea')[0])) {
response.responseText = contentNode.value;
} else
{
response.responseText = doc.body.textContent || doc.body.innerText;
}
}
response.responseXML = doc.XMLDocument || doc;
callback = options.success;
success = true;
} else {
Ext.Error.raise("Could not acquire a suitable connection for the file upload service.");
}
} catch (e) {
response.responseText = '{success:false,message:"' + Ext.String.trim(e.message || e.description) + '"}';
callback = options.failure;
success = false;
}
me.fireEvent(success ? 'requestcomplete' : 'requestexception', me, response, options);
Ext.callback(callback, options.scope, [
response,
options
]);
Ext.callback(options.callback, options.scope, [
options,
success,
response
]);
Ext.defer(Ext.removeNode, 100, Ext, [
frame
]);
},
isFormUpload: function(options) {
var form = this.getForm(options);
if (form) {
return (options.isUpload || (/multipart\/form-data/i).test(form.getAttribute('enctype')));
}
return false;
},
getForm: function(options) {
var form = options.form || null;
if (form) {
form = Ext.getDom(form);
}
return form;
},
setOptions: function(options, scope) {
var me = this,
params = options.params || {},
extraParams = me.getExtraParams(),
urlParams = options.urlParams,
url = options.url || me.getUrl(),
cors = options.cors,
jsonData = options.jsonData,
method, disableCache, data;
if (cors !== undefined) {
me.setCors(cors);
}
if (Ext.isFunction(params)) {
params = params.call(scope, options);
}
if (Ext.isFunction(url)) {
url = url.call(scope, options);
}
url = this.setupUrl(options, url);
if (!url) {
Ext.Error.raise({
options: options,
msg: 'No URL specified'
});
}
data = options.rawData || options.binaryData || options.xmlData || jsonData || null;
if (jsonData && !Ext.isPrimitive(jsonData)) {
data = Ext.encode(data);
}
if (options.binaryData) {
if (!Ext.isArray(options.binaryData)) {
Ext.log.warn("Binary submission data must be an array of byte values! Instead got " + typeof (options.binaryData));
}
if (me.nativeBinaryPostSupport()) {
data = (new Uint8Array(options.binaryData));
if ((Ext.isChrome && Ext.chromeVersion < 22) || Ext.isSafari || Ext.isGecko) {
data = data.buffer;
}
}
}
if (Ext.isObject(params)) {
params = Ext.Object.toQueryString(params);
}
if (Ext.isObject(extraParams)) {
extraParams = Ext.Object.toQueryString(extraParams);
}
params = params + ((extraParams) ? ((params) ? '&' : '') + extraParams : '');
urlParams = Ext.isObject(urlParams) ? Ext.Object.toQueryString(urlParams) : urlParams;
params = this.setupParams(options, params);
method = (options.method || me.getMethod() || ((params || data) ? 'POST' : 'GET')).toUpperCase();
this.setupMethod(options, method);
disableCache = options.disableCaching !== false ? (options.disableCaching || me.getDisableCaching()) : false;
if (method === 'GET' && disableCache) {
url = Ext.urlAppend(url, (options.disableCachingParam || me.getDisableCachingParam()) + '=' + (new Date().getTime()));
}
if ((method == 'GET' || data) && params) {
url = Ext.urlAppend(url, params);
params = null;
}
if (urlParams) {
url = Ext.urlAppend(url, urlParams);
}
return {
url: url,
method: method,
data: data || params || null
};
},
setupUrl: function(options, url) {
var form = this.getForm(options);
if (form) {
url = url || form.action;
}
return url;
},
setupParams: function(options, params) {
var form = this.getForm(options),
serializedForm;
if (form && !this.isFormUpload(options)) {
serializedForm = Ext.Element.serializeForm(form);
params = params ? (params + '&' + serializedForm) : serializedForm;
}
return params;
},
setupMethod: function(options, method) {
if (this.isFormUpload(options)) {
return 'POST';
}
return method;
},
setupHeaders: function(xhr, options, data, params) {
var me = this,
headers = Ext.apply({}, options.headers || {}, me.getDefaultHeaders() || {}),
contentType = me.getDefaultPostHeader(),
jsonData = options.jsonData,
xmlData = options.xmlData,
type = 'Content-Type',
useHeader = Ext.isDefined(options.useDefaultXhrHeader) ? options.useDefaultXhrHeader : me.getUseDefaultXhrHeader(),
key, header;
if (!headers.hasOwnProperty(type) && (data || params)) {
if (data) {
if (options.rawData) {
contentType = 'text/plain';
} else {
if (xmlData && Ext.isDefined(xmlData)) {
contentType = 'text/xml';
} else if (jsonData && Ext.isDefined(jsonData)) {
contentType = 'application/json';
}
}
}
headers[type] = contentType;
}
if (useHeader && !headers['X-Requested-With']) {
headers['X-Requested-With'] = me.getDefaultXhrHeader();
}
if (headers[type] === undefined || headers[type] === null) {
delete headers[type];
}
try {
for (key in headers) {
if (headers.hasOwnProperty(key)) {
header = headers[key];
xhr.setRequestHeader(key, header);
}
}
} catch (e) {
me.fireEvent('exception', key, header);
}
return headers;
},
newRequest: function(options) {
var me = this,
xhr;
if (options.binaryData) {
if (me.nativeBinaryPostSupport()) {
xhr = me.getXhrInstance();
} else
{
xhr = new Ext.data.flash.BinaryXhr();
}
} else if (me.getCors() && Ext.isIE && Ext.ieVersion <= 9) {
xhr = me.getXdrInstance();
me.setIsXdr(true);
} else {
xhr = me.getXhrInstance();
me.setIsXdr(false);
}
return xhr;
},
openRequest: function(options, requestOptions, async, username, password) {
var me = this,
xhr = me.newRequest(options);
if (username) {
xhr.open(requestOptions.method, requestOptions.url, async, username, password);
} else {
if (me.getIsXdr()) {
xhr.open(requestOptions.method, requestOptions.url);
} else {
xhr.open(requestOptions.method, requestOptions.url, async);
}
}
if (options.binary || me.getBinary()) {
if (window.Uint8Array) {
xhr.responseType = 'arraybuffer';
} else if (xhr.overrideMimeType) {
xhr.overrideMimeType('text/plain; charset=x-user-defined');
} else if (!Ext.isIE) {
Ext.log.warn("Your browser does not support loading binary data using Ajax.");
}
}
if (options.withCredentials || me.getWithCredentials()) {
xhr.withCredentials = true;
}
return xhr;
},
getXdrInstance: function() {
var xdr;
if (Ext.ieVersion >= 8) {
xdr = new XDomainRequest();
} else {
Ext.Error.raise({
msg: 'Your browser does not support CORS'
});
}
return xdr;
},
getXhrInstance: (function() {
var options = [
function() {
return new XMLHttpRequest();
},
function() {
return new ActiveXObject('MSXML2.XMLHTTP.3.0');
},
function() {
return new ActiveXObject('MSXML2.XMLHTTP');
},
function() {
return new ActiveXObject('Microsoft.XMLHTTP');
}
],
i = 0,
len = options.length,
xhr;
for (; i < len; ++i) {
try {
xhr = options[i];
xhr();
break;
} catch (e) {}
}
return xhr;
}()),
isLoading: function(request) {
if (!request) {
request = this.getLatest();
}
if (!(request && request.xhr)) {
return false;
}
var state = request.xhr.readyState,
Cls = Ext.data.flash && Ext.data.flash.BinaryXhr;
return ((request.xhr instanceof Cls) && state != 4) || !(state === 0 || state == 4);
},
abort: function(request) {
var me = this,
xhr;
if (!request) {
request = me.getLatest();
}
if (request && me.isLoading(request)) {
xhr = request.xhr;
try {
xhr.onreadystatechange = null;
} catch (e) {
xhr.onreadystatechange = Ext.emptyFn;
}
xhr.abort();
me.clearTimeout(request);
if (!request.timedout) {
request.aborted = true;
}
me.onComplete(request);
me.cleanup(request);
}
},
abortAll: function() {
var requests = this.requests,
id;
for (id in requests) {
if (requests.hasOwnProperty(id)) {
this.abort(requests[id]);
}
}
},
getLatest: function() {
var id = this.latestId,
request;
if (id) {
request = this.requests[id];
}
return request || null;
},
onStateChange: function(request, xdrResult) {
var me = this,
globalEvents = Ext.GlobalEvents;
if ((request.xhr && request.xhr.readyState == 4) || me.getIsXdr()) {
me.clearTimeout(request);
me.onComplete(request, xdrResult);
me.cleanup(request);
if (globalEvents.hasListeners.idle) {
globalEvents.fireEvent('idle');
}
}
},
clearTimeout: function(request) {
clearTimeout(request.timeout);
delete request.timeout;
},
cleanup: function(request) {
request.xhr = null;
delete request.xhr;
},
onComplete: function(request, xdrResult) {
var me = this,
options = request.options,
xhr, result, success, response;
try {
xhr = request.xhr;
result = me.parseStatus(xhr.status);
if (result.success) {
result.success = xhr.readyState === 4;
}
} catch (e) {
result = {
success: false,
isException: false
};
}
success = me.getIsXdr() ? xdrResult : result.success;
if (success) {
response = me.createResponse(request);
me.fireEvent('requestcomplete', me, response, options);
Ext.callback(options.success, options.scope, [
response,
options
]);
} else {
if (result.isException || request.aborted || request.timedout) {
response = me.createException(request);
} else {
response = me.createResponse(request);
}
me.fireEvent('requestexception', me, response, options);
Ext.callback(options.failure, options.scope, [
response,
options
]);
}
Ext.callback(options.callback, options.scope, [
options,
success,
response
]);
delete me.requests[request.id];
return response;
},
parseStatus: function(status) {
status = status == 1223 ? 204 : status;
var success = (status >= 200 && status < 300) || status == 304,
isException = false;
if (!success) {
switch (status) {
case 12002:
case 12029:
case 12030:
case 12031:
case 12152:
case 13030:
isException = true;
break;
}
}
return {
success: success,
isException: isException
};
},
createResponse: function(request) {
var me = this,
xhr = request.xhr,
isXdr = me.getIsXdr(),
headers = {},
lines = isXdr ? [] : xhr.getAllResponseHeaders().replace(/\r\n/g, '\n').split('\n'),
count = lines.length,
line, index, key, response, byteArray;
while (count--) {
line = lines[count];
index = line.indexOf(':');
if (index >= 0) {
key = line.substr(0, index).toLowerCase();
if (line.charAt(index + 1) == ' ') {
++index;
}
headers[key] = line.substr(index + 1);
}
}
request.xhr = null;
delete request.xhr;
response = {
request: request,
requestId: request.id,
status: xhr.status,
statusText: xhr.statusText,
getResponseHeader: function(header) {
return headers[header.toLowerCase()];
},
getAllResponseHeaders: function() {
return headers;
}
};
if (isXdr) {
me.processXdrResponse(response, xhr);
}
if (request.binary) {
response.responseBytes = me.getByteArray(xhr);
} else {
response.responseText = xhr.responseText;
response.responseXML = xhr.responseXML;
}
xhr = null;
return response;
},
createException: function(request) {
return {
request: request,
requestId: request.id,
status: request.aborted ? -1 : 0,
statusText: request.aborted ? 'transaction aborted' : 'communication failure',
aborted: request.aborted,
timedout: request.timedout
};
},
getByteArray: function(xhr) {
var response = xhr.response,
responseBody = xhr.responseBody,
Cls = Ext.data.flash && Ext.data.flash.BinaryXhr,
byteArray, responseText, len, i;
if (xhr instanceof Cls) {
byteArray = xhr.responseBytes;
} else if (window.Uint8Array) {
byteArray = response ? new Uint8Array(response) : [];
} else if (Ext.isIE9p) {
try {
byteArray = new VBArray(responseBody).toArray();
}
catch (e) {
byteArray = [];
}
} else if (Ext.isIE) {
if (!this.self.vbScriptInjected) {
this.injectVBScript();
}
getIEByteArray(xhr.responseBody, byteArray = []);
} else
{
byteArray = [];
responseText = xhr.responseText;
len = responseText.length;
for (i = 0; i < len; i++) {
byteArray.push(responseText.charCodeAt(i) & 255);
}
}
return byteArray;
},
injectVBScript: function() {
var scriptTag = document.createElement('script');
scriptTag.type = 'text/vbscript';
scriptTag.text = [
'Function getIEByteArray(byteArray, out)',
'Dim len, i',
'len = LenB(byteArray)',
'For i = 1 to len',
'out.push(AscB(MidB(byteArray, i, 1)))',
'Next',
'End Function'
].join('\n');
Ext.getHead().dom.appendChild(scriptTag);
this.self.vbScriptInjected = true;
},
nativeBinaryPostSupport: function() {
return Ext.isChrome || (Ext.isSafari && Ext.isDefined(window.Uint8Array)) || (Ext.isGecko && Ext.isDefined(window.Uint8Array));
}
});
Ext.define('Ext.Ajax', {
extend: 'Ext.data.Connection',
singleton: true,
autoAbort: false
});
Ext.define('Ext.AnimationQueue', {
singleton: true,
constructor: function() {
this.queue = [];
this.taskQueue = [];
this.runningQueue = [];
this.idleQueue = [];
this.isRunning = false;
this.isIdle = true;
this.run = Ext.Function.bind(this.run, this);
if (Ext.os.is.iOS) {
Ext.interval(this.watch, 500, this);
}
},
start: function(fn, scope, args) {
this.queue.push(arguments);
if (!this.isRunning) {
if (this.hasOwnProperty('idleTimer')) {
clearTimeout(this.idleTimer);
delete this.idleTimer;
}
if (this.hasOwnProperty('idleQueueTimer')) {
clearTimeout(this.idleQueueTimer);
delete this.idleQueueTimer;
}
this.isIdle = false;
this.isRunning = true;
this.startCountTime = Ext.now();
this.count = 0;
this.doStart();
}
},
watch: function() {
if (this.isRunning && Ext.now() - this.lastRunTime >= 500) {
this.run();
}
},
run: function() {
if (!this.isRunning) {
return;
}
var queue = this.runningQueue,
i, ln;
this.lastRunTime = Ext.now();
this.frameStartTime = Ext.now();
queue.push.apply(queue, this.queue);
for (i = 0 , ln = queue.length; i < ln; i++) {
this.invoke(queue[i]);
}
queue.length = 0;
var now = this.frameStartTime,
startCountTime = this.startCountTime,
elapse = now - startCountTime,
count = ++this.count;
if (elapse >= 200) {
this.onFpsChanged(count * 1000 / elapse, count, elapse);
this.startCountTime = now;
this.count = 0;
}
this.doIterate();
},
onFpsChanged: Ext.emptyFn,
onStop: Ext.emptyFn,
doStart: function() {
this.animationFrameId = Ext.Function.requestAnimationFrame(this.run);
this.lastRunTime = Ext.now();
},
doIterate: function() {
this.animationFrameId = Ext.Function.requestAnimationFrame(this.run);
},
doStop: function() {
Ext.Function.cancelAnimationFrame(this.animationFrameId);
},
stop: function(fn, scope, args) {
if (!this.isRunning) {
return;
}
var queue = this.queue,
ln = queue.length,
i, item;
for (i = 0; i < ln; i++) {
item = queue[i];
if (item[0] === fn && item[1] === scope && item[2] === args) {
queue.splice(i, 1);
i--;
ln--;
}
}
if (ln === 0) {
this.doStop();
this.onStop();
this.isRunning = false;
this.idleTimer = Ext.defer(this.whenIdle, 100, this);
}
},
onIdle: function(fn, scope, args) {
var listeners = this.idleQueue,
i, ln, listener;
for (i = 0 , ln = listeners.length; i < ln; i++) {
listener = listeners[i];
if (fn === listener[0] && scope === listener[1] && args === listener[2]) {
return;
}
}
listeners.push(arguments);
if (this.isIdle) {
this.processIdleQueue();
}
},
unIdle: function(fn, scope, args) {
var listeners = this.idleQueue,
i, ln, listener;
for (i = 0 , ln = listeners.length; i < ln; i++) {
listener = listeners[i];
if (fn === listener[0] && scope === listener[1] && args === listener[2]) {
listeners.splice(i, 1);
return true;
}
}
return false;
},
queueTask: function(fn, scope, args) {
this.taskQueue.push(arguments);
this.processTaskQueue();
},
dequeueTask: function(fn, scope, args) {
var listeners = this.taskQueue,
i, ln, listener;
for (i = 0 , ln = listeners.length; i < ln; i++) {
listener = listeners[i];
if (fn === listener[0] && scope === listener[1] && args === listener[2]) {
listeners.splice(i, 1);
i--;
ln--;
}
}
},
invoke: function(listener) {
var fn = listener[0],
scope = listener[1],
args = listener[2];
fn = (typeof fn == 'string' ? scope[fn] : fn);
if (Ext.isArray(args)) {
fn.apply(scope, args);
} else {
fn.call(scope, args);
}
},
whenIdle: function() {
this.isIdle = true;
this.processIdleQueue();
},
processIdleQueue: function() {
if (!this.hasOwnProperty('idleQueueTimer')) {
this.idleQueueTimer = Ext.defer(this.processIdleQueueItem, 1, this);
}
},
processIdleQueueItem: function() {
delete this.idleQueueTimer;
if (!this.isIdle) {
return;
}
var listeners = this.idleQueue,
listener;
if (listeners.length > 0) {
listener = listeners.shift();
this.invoke(listener);
this.processIdleQueue();
}
},
processTaskQueue: function() {
if (!this.hasOwnProperty('taskQueueTimer')) {
this.taskQueueTimer = Ext.defer(this.processTaskQueueItem, 15, this);
}
},
processTaskQueueItem: function() {
delete this.taskQueueTimer;
var listeners = this.taskQueue,
listener;
if (listeners.length > 0) {
listener = listeners.shift();
this.invoke(listener);
this.processTaskQueue();
}
},
showFps: function() {
Ext.onInternalReady(function() {
Ext.Viewport.add([
{
xtype: 'component',
bottom: 50,
left: 0,
width: 50,
height: 20,
html: 'Average',
style: 'background-color: black; color: white; text-align: center; line-height: 20px; font-size: 8px;'
},
{
id: '__averageFps',
xtype: 'component',
bottom: 0,
left: 0,
width: 50,
height: 50,
html: '0',
style: 'background-color: red; color: white; text-align: center; line-height: 50px;'
},
{
xtype: 'component',
bottom: 50,
left: 50,
width: 50,
height: 20,
html: 'Min (Last 1k)',
style: 'background-color: black; color: white; text-align: center; line-height: 20px; font-size: 8px;'
},
{
id: '__minFps',
xtype: 'component',
bottom: 0,
left: 50,
width: 50,
height: 50,
html: '0',
style: 'background-color: orange; color: white; text-align: center; line-height: 50px;'
},
{
xtype: 'component',
bottom: 50,
left: 100,
width: 50,
height: 20,
html: 'Max (Last 1k)',
style: 'background-color: black; color: white; text-align: center; line-height: 20px; font-size: 8px;'
},
{
id: '__maxFps',
xtype: 'component',
bottom: 0,
left: 100,
width: 50,
height: 50,
html: '0',
style: 'background-color: yellow; color: black; text-align: center; line-height: 50px;'
},
{
xtype: 'component',
bottom: 50,
left: 150,
width: 50,
height: 20,
html: 'Current',
style: 'background-color: black; color: white; text-align: center; line-height: 20px; font-size: 8px;'
},
{
id: '__currentFps',
xtype: 'component',
bottom: 0,
left: 150,
width: 50,
height: 50,
html: '0',
style: 'background-color: green; color: white; text-align: center; line-height: 50px;'
}
]);
Ext.AnimationQueue.resetFps();
});
},
resetFps: function() {
var currentFps = Ext.getCmp('__currentFps'),
averageFps = Ext.getCmp('__averageFps'),
minFps = Ext.getCmp('__minFps'),
maxFps = Ext.getCmp('__maxFps'),
min = 1000,
max = 0,
count = 0,
sum = 0;
Ext.AnimationQueue.onFpsChanged = function(fps) {
count++;
if (!(count % 10)) {
min = 1000;
max = 0;
}
sum += fps;
min = Math.min(min, fps);
max = Math.max(max, fps);
currentFps.setHtml(Math.round(fps));
averageFps.setHtml(Math.round(sum / count));
minFps.setHtml(Math.round(min));
maxFps.setHtml(Math.round(max));
};
}
}, function() {
var paramsString = window.location.search.substr(1),
paramsArray = paramsString.split("&");
if (Ext.Array.contains(paramsArray, "showfps")) {
Ext.AnimationQueue.showFps();
}
});
Ext.define('Ext.ComponentManager', {
alternateClassName: 'Ext.ComponentMgr',
singleton: true,
count: 0,
typeName: 'xtype',
constructor: function(config) {
var me = this;
Ext.apply(me, config || {});
me.all = {};
me.references = {};
me.onAvailableCallbacks = {};
},
create: function(config, defaultType) {
if (typeof config === 'string') {
return Ext.widget(config);
}
if (config.isComponent) {
return config;
}
if ('xclass' in config) {
return Ext.create(config.xclass, config);
}
return Ext.widget(config.xtype || defaultType, config);
},
get: function(id) {
return this.all[id];
},
register: function(component) {
var me = this,
all = me.all,
key = component.getId(),
onAvailableCallbacks = me.onAvailableCallbacks;
if (key === undefined) {
Ext.Error.raise('Component id is undefined. Please ensure the component has an id.');
}
if (key in all) {
Ext.Error.raise('Registering duplicate component id "' + key + '"');
}
all[key] = component;
if (component.reference) {
me.references[key] = component;
}
++me.count;
if (!me.hasFocusListener) {
Ext.on('focus', me.onGlobalFocus, me);
me.hasFocusListener = true;
}
onAvailableCallbacks = onAvailableCallbacks && onAvailableCallbacks[key];
if (onAvailableCallbacks && onAvailableCallbacks.length) {
me.notifyAvailable(component);
}
},
unregister: function(component) {
var id = component.getId();
if (component.reference) {
delete this.references[id];
}
delete this.all[id];
this.count--;
},
markReferencesDirty: function() {
this.referencesDirty = true;
},
fixReferences: function() {
var me = this,
references = me.references,
key;
if (me.referencesDirty) {
for (key in references) {
if (references.hasOwnProperty(key)) {
references[key].fixReference();
}
}
me.referencesDirty = false;
}
},
onAvailable: function(id, fn, scope) {
var me = this,
callbacks = me.onAvailableCallbacks,
all = me.all,
item;
if (id in all) {
item = all[id];
fn.call(scope || item, item);
} else if (id) {
if (!Ext.isArray(callbacks[id])) {
callbacks[id] = [];
}
callbacks[id].push(function(item) {
fn.call(scope || item, item);
});
}
},
notifyAvailable: function(item) {
var callbacks = this.onAvailableCallbacks[item && item.getId()] || [];
while (callbacks.length) {
(callbacks.shift())(item);
}
},
each: function(fn, scope) {
return Ext.Object.each(this.all, fn, scope);
},
getCount: function() {
return this.count;
},
getAll: function() {
return Ext.Object.getValues(this.all);
},
getActiveComponent: function() {
return Ext.Component.fromElement(Ext.dom.Element.getActiveElement());
},
onGlobalFocus: function(e) {
var me = this,
toElement = e.toElement,
fromElement = e.fromElement,
toComponent = Ext.Component.fromElement(toElement),
fromComponent = Ext.Component.fromElement(fromElement),
commonAncestor = me.getCommonAncestor(fromComponent, toComponent),
event, targetComponent;
if (fromComponent && !(fromComponent.isDestroyed || fromComponent.destroying)) {
if (fromComponent.focusable && fromElement === fromComponent.getFocusEl().dom) {
event = new Ext.event.Event(e.event);
event.type = 'blur';
event.target = fromElement;
event.relatedTarget = toElement;
fromComponent.onBlur(event);
}
for (targetComponent = fromComponent; targetComponent && targetComponent !== commonAncestor; targetComponent = targetComponent.getRefOwner()) {
if (!(targetComponent.isDestroyed || targetComponent.destroying)) {
targetComponent.onFocusLeave({
event: e.event,
type: 'focusleave',
target: fromElement,
relatedTarget: toElement,
fromComponent: fromComponent,
toComponent: toComponent
});
}
}
}
if (toComponent && !toComponent.isDestroyed) {
if (toComponent.focusable && toElement === toComponent.getFocusEl().dom) {
event = new Ext.event.Event(e.event);
event.type = 'focus';
event.relatedTarget = fromElement;
event.target = toElement;
toComponent.onFocus(event);
}
for (targetComponent = toComponent; targetComponent && targetComponent !== commonAncestor; targetComponent = targetComponent.getRefOwner()) {
targetComponent.onFocusEnter({
event: e.event,
type: 'focusenter',
relatedTarget: fromElement,
target: toElement,
fromComponent: fromComponent,
toComponent: toComponent
});
}
}
},
getCommonAncestor: function(compA, compB) {
if (compA === compB) {
return compA;
}
while (compA && !(compA.isAncestor(compB) || compA === compB)) {
compA = compA.getRefOwner();
}
return compA;
},
deprecated: {
5: {
methods: {
isRegistered: null,
registerType: null
}
}
}
}, function() {
Ext.getCmp = function(id) {
return Ext.ComponentManager.get(id);
};
});
Ext.ns('Ext.util').Operators = {
"=": function(a, v) {
return a == v;
},
"!=": function(a, v) {
return a != v;
},
"^=": function(a, v) {
return a && a.substr(0, v.length) == v;
},
"$=": function(a, v) {
return a && a.substr(a.length - v.length) == v;
},
"*=": function(a, v) {
return a && a.indexOf(v) !== -1;
},
"%=": function(a, v) {
return (a % v) === 0;
},
"|=": function(a, v) {
return a && (a == v || a.substr(0, v.length + 1) == v + '-');
},
"~=": function(a, v) {
return a && (' ' + a + ' ').indexOf(' ' + v + ' ') != -1;
}
};
Ext.define('Ext.util.LruCache', {
extend: 'Ext.util.HashMap',
config: {
maxSize: null
},
add: function(key, newValue) {
var me = this,
entry, last;
me.removeAtKey(key);
last = me.last;
entry = {
prev: last,
next: null,
key: key,
value: newValue
};
if (last) {
last.next = entry;
} else {
me.first = entry;
}
me.last = entry;
me.callParent([
key,
entry
]);
me.prune();
return newValue;
},
insertBefore: function(key, newValue, sibling) {
var me = this,
existingKey, entry;
if (sibling = this.map[this.findKey(sibling)]) {
existingKey = me.findKey(newValue);
if (existingKey) {
me.unlinkEntry(entry = me.map[existingKey]);
} else
{
entry = {
prev: sibling.prev,
next: sibling,
key: key,
value: newValue
};
}
if (sibling.prev) {
entry.prev.next = entry;
} else {
me.first = entry;
}
entry.next = sibling;
sibling.prev = entry;
me.prune();
return newValue;
} else
{
return me.add(key, newValue);
}
},
get: function(key) {
var entry = this.map[key];
if (entry) {
if (entry.next) {
this.moveToEnd(entry);
}
return entry.value;
}
},
removeAtKey: function(key) {
this.unlinkEntry(this.map[key]);
return this.callParent(arguments);
},
clear: function(
initial) {
this.first = this.last = null;
return this.callParent(arguments);
},
unlinkEntry: function(entry) {
if (entry) {
if (entry.next) {
entry.next.prev = entry.prev;
} else {
this.last = entry.prev;
}
if (entry.prev) {
entry.prev.next = entry.next;
} else {
this.first = entry.next;
}
entry.prev = entry.next = null;
}
},
moveToEnd: function(entry) {
this.unlinkEntry(entry);
if (entry.prev = this.last) {
this.last.next = entry;
} else
{
this.first = entry;
}
this.last = entry;
},
getArray: function(isKey) {
var arr = [],
entry = this.first;
while (entry) {
arr.push(isKey ? entry.key : entry.value);
entry = entry.next;
}
return arr;
},
each: function(fn, scope, reverse) {
var me = this,
entry = reverse ? me.last : me.first,
length = me.length;
scope = scope || me;
while (entry) {
if (fn.call(scope, entry.key, entry.value, length) === false) {
break;
}
entry = reverse ? entry.prev : entry.next;
}
return me;
},
findKey: function(value) {
var key,
map = this.map;
for (key in map) {
if (map.hasOwnProperty(key) && map[key].value === value) {
return key;
}
}
return undefined;
},
clone: function() {
var newCache = new this.self(this.initialConfig),
map = this.map,
key;
newCache.suspendEvents();
for (key in map) {
if (map.hasOwnProperty(key)) {
newCache.add(key, map[key].value);
}
}
newCache.resumeEvents();
return newCache;
},
prune: function() {
var me = this,
max = me.getMaxSize(),
purgeCount = max ? (me.length - max) : 0;
if (purgeCount > 0) {
for (; me.first && purgeCount; purgeCount--) {
me.removeAtKey(me.first.key);
}
}
}
});
Ext.define('Ext.ComponentQuery', {
singleton: true,
requires: [
'Ext.ComponentManager',
'Ext.util.Operators',
'Ext.util.LruCache'
]
}, function() {
var cq = this,
queryOperators = Ext.util.Operators,
nthRe = /(\d*)n\+?(\d*)/,
nthRe2 = /\D/,
stripLeadingSpaceRe = /^(\s)+/,
unescapeRe = /\\(.)/g,
regexCache = new Ext.util.LruCache({
maxSize: 100
}),
filterFnPattern = [
'var r = [],',
'i = 0,',
'it = items,',
'l = it.length,',
'c;',
'for (; i < l; i++) {',
'c = it[i];',
'if (c.{0}) {',
'r.push(c);',
'}',
'}',
'return r;'
].join(''),
filterItems = function(items, operation) {
return operation.method.apply(this, [
items
].concat(operation.args));
},
getItems = function(items, mode) {
var result = [],
i = 0,
length = items.length,
candidate,
deep = mode !== '>';
for (; i < length; i++) {
candidate = items[i];
if (candidate.getRefItems) {
result = result.concat(candidate.getRefItems(deep));
}
}
return result;
},
getAncestors = function(items) {
var result = [],
i = 0,
length = items.length,
candidate;
for (; i < length; i++) {
candidate = items[i];
while (!!(candidate = candidate.getRefOwner())) {
result.push(candidate);
}
}
return result;
},
filterByXType = function(items, xtype, shallow) {
if (xtype === '*') {
return items.slice();
} else {
var result = [],
i = 0,
length = items.length,
candidate;
for (; i < length; i++) {
candidate = items[i];
if (candidate.isXType(xtype, shallow)) {
result.push(candidate);
}
}
return result;
}
},
filterByAttribute = function(items, property, operator, compareTo) {
var result = [],
i = 0,
length = items.length,
mustBeOwnProperty, presenceOnly, candidate, propValue, j, propLen, config;
if (property.charAt(0) === '@') {
mustBeOwnProperty = true;
property = property.substr(1);
}
if (property.charAt(0) === '?') {
mustBeOwnProperty = true;
presenceOnly = true;
property = property.substr(1);
}
for (; i < length; i++) {
candidate = items[i];
config = candidate.self.$config.configs[property];
if (config) {
propValue = candidate[config.names.get]();
} else if (mustBeOwnProperty && !candidate.hasOwnProperty(property)) {
continue;
} else {
propValue = candidate[property];
}
if (presenceOnly) {
result.push(candidate);
}
else if (operator === '~=') {
if (propValue) {
if (!Ext.isArray(propValue)) {
propValue = propValue.split(' ');
}
for (j = 0 , propLen = propValue.length; j < propLen; j++) {
if (queryOperators[operator](Ext.coerce(propValue[j], compareTo), compareTo)) {
result.push(candidate);
break;
}
}
}
} else if (operator === '/=') {
if (propValue != null && compareTo.test(propValue)) {
result.push(candidate);
}
} else if (!compareTo ? !!candidate[property] : queryOperators[operator](Ext.coerce(propValue, compareTo), compareTo)) {
result.push(candidate);
}
}
return result;
},
filterById = function(items, id) {
var result = [],
i = 0,
length = items.length,
candidate;
for (; i < length; i++) {
candidate = items[i];
if (candidate.getItemId() === id) {
result.push(candidate);
}
}
return result;
},
filterByPseudo = function(items, name, value) {
return cq.pseudos[name](items, value);
},
modeRe = /^(\s?([>\^])\s?|\s|$)/,
tokenRe = /^(#)?((?:\\\.|[\w\-])+|\*)(?:\((true|false)\))?/,
matchers = [
{
re: /^\.((?:\\\.|[\w\-])+)(?:\((true|false)\))?/,
method: filterByXType,
argTransform: function(args) {
var selector = args[0];
Ext.log.warn('"' + selector + '" ComponentQuery selector style is deprecated,' + ' use "' + selector.replace(/^\./, '') + '" without the leading dot instead');
if (args[1] !== undefined) {
args[1] = args[1].replace(unescapeRe, '$1');
}
return args.slice(1);
}
},
{
re: /^(?:\[((?:[@?$])?[\w\-]*)\s*(?:([\^$*~%!\/]?=)\s*(['"])?((?:\\\]|.)*?)\3)?(?!\\)\])/,
method: filterByAttribute,
argTransform: function(args) {
var selector = args[0],
property = args[1],
operator = args[2],
compareTo = args[4],
compareRe;
if (compareTo !== undefined) {
compareTo = compareTo.replace(unescapeRe, '$1');
var format = Ext.String.format,
msg = "ComponentQuery selector '{0}' has an unescaped ({1}) character at the {2} " + "of the attribute value pattern. Usually that indicates an error " + "where the opening quote is not followed by the closing quote. " + "If you need to match a ({1}) character at the {2} of the attribute " + "value, escape the quote character in your pattern: (\\{1})",
match;
if (match = /^(['"]).*?[^'"]$/.exec(compareTo)) {
Ext.log.warn(format(msg, selector, match[1], 'beginning'));
} else if (match = /^[^'"].*?(['"])$/.exec(compareTo)) {
Ext.log.warn(format(msg, selector, match[1], 'end'));
}
}
if (operator === '/=') {
compareRe = regexCache.get(compareTo);
if (compareRe) {
compareTo = compareRe;
} else {
compareTo = regexCache.add(compareTo, new RegExp(compareTo));
}
}
return [
property,
operator,
compareTo
];
}
},
{
re: /^#((?:\\\.|[\w\-])+)/,
method: filterById
},
{
re: /^\:([\w\-]+)(?:\(((?:\{[^\}]+\})|(?:(?!\{)[^\s>\/]*?(?!\})))\))?/,
method: filterByPseudo,
argTransform: function(args) {
if (args[2] !== undefined) {
args[2] = args[2].replace(unescapeRe, '$1');
}
return args.slice(1);
}
},
{
re: /^(?:\{([^\}]+)\})/,
method: filterFnPattern
}
];
cq.Query = Ext.extend(Object, {
constructor: function(cfg) {
cfg = cfg || {};
Ext.apply(this, cfg);
},
execute: function(root) {
var operations = this.operations,
result = [],
op, i, len;
for (i = 0 , len = operations.length; i < len; i++) {
op = operations[i];
result = result.concat(this._execute(root, op));
}
return result;
},
_execute: function(root, operations) {
var i = 0,
length = operations.length,
operation, workingItems;
if (!root) {
workingItems = Ext.ComponentManager.getAll();
}
else if (Ext.isIterable(root)) {
workingItems = root;
}
else if (root.isMixedCollection) {
workingItems = root.items;
}
for (; i < length; i++) {
operation = operations[i];
if (operation.mode === '^') {
workingItems = getAncestors(workingItems || [
root
]);
} else if (operation.mode) {
workingItems = getItems(workingItems || [
root
], operation.mode);
} else {
workingItems = filterItems(workingItems || getItems([
root
]), operation);
}
if (i === length - 1) {
return workingItems;
}
}
return [];
},
is: function(component) {
var operations = this.operations,
result = false,
len = operations.length,
op, i;
if (len === 0) {
return true;
}
for (i = 0; i < len; i++) {
op = operations[i];
result = this._is(component, op);
if (result) {
return result;
}
}
return false;
},
_is: function(component, operations) {
var len = operations.length,
active = [
component
],
operation, i, j, mode, items, item;
for (i = len - 1; i >= 0; --i) {
operation = operations[i];
mode = operation.mode;
if (mode) {
if (mode === '^') {
active = getItems(active, ' ');
} else if (mode === '>') {
items = [];
for (j = 0 , len = active.length; j < len; ++j) {
item = active[j].getRefOwner();
if (item) {
items.push(item);
}
}
active = items;
} else {
active = getAncestors(active);
}
if (active.length === 0) {
return false;
}
} else {
active = filterItems(active, operation);
if (active.length === 0) {
return false;
}
}
}
return true;
},
getMatches: function(components, operations) {
var len = operations.length,
i;
for (i = 0; i < len; ++i) {
components = filterItems(components, operations[i]);
if (components.length === 0) {
break;
}
}
return components;
},
isMultiMatch: function() {
return this.operations.length > 1;
}
});
Ext.apply(cq, {
cache: new Ext.util.LruCache({
maxSize: 100
}),
pseudos: {
not: function(components, selector) {
var i = 0,
length = components.length,
results = [],
index = -1,
component;
for (; i < length; ++i) {
component = components[i];
if (!cq.is(component, selector)) {
results[++index] = component;
}
}
return results;
},
first: function(components) {
var ret = [];
if (components.length > 0) {
ret.push(components[0]);
}
return ret;
},
last: function(components) {
var len = components.length,
ret = [];
if (len > 0) {
ret.push(components[len - 1]);
}
return ret;
},
focusable: function(cmps) {
var len = cmps.length,
results = [],
i = 0,
c;
for (; i < len; i++) {
c = cmps[i];
if (c.isFocusable && c.isFocusable()) {
results.push(c);
}
}
return results;
},
"nth-child": function(c, a) {
var result = [],
m = nthRe.exec(a === "even" && "2n" || a === "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a),
f = (m[1] || 1) - 0,
len = m[2] - 0,
i, n, nodeIndex;
for (i = 0; n = c[i]; i++) {
nodeIndex = i + 1;
if (f === 1) {
if (len === 0 || nodeIndex === len) {
result.push(n);
}
} else if ((nodeIndex + len) % f === 0) {
result.push(n);
}
}
return result;
}
},
query: function(selector, root) {
if (!selector) {
return Ext.ComponentManager.all.getArray();
}
var results = [],
noDupResults = [],
dupMatcher = {},
query = cq.cache.get(selector),
resultsLn, cmp, i;
if (!query) {
query = cq.cache.add(selector, cq.parse(selector));
}
results = query.execute(root);
if (query.isMultiMatch()) {
resultsLn = results.length;
for (i = 0; i < resultsLn; i++) {
cmp = results[i];
if (!dupMatcher[cmp.id]) {
noDupResults.push(cmp);
dupMatcher[cmp.id] = true;
}
}
results = noDupResults;
}
return results;
},
visitPreOrder: function(selector, root, fn, scope, extraArgs) {
cq._visit(true, selector, root, fn, scope, extraArgs);
},
visitPostOrder: function(selector, root, fn, scope, extraArgs) {
cq._visit(false, selector, root, fn, scope, extraArgs);
},
_visit: function(preOrder, selector, root, fn, scope, extraArgs) {
var query = cq.cache.get(selector),
callArgs = [
root
],
children,
len = 0,
i, rootMatch;
if (!query) {
query = cq.cache.add(selector, cq.parse(selector));
}
rootMatch = query.is(root);
if (root.getRefItems) {
children = root.getRefItems();
len = children.length;
}
if (extraArgs) {
Ext.Array.push(callArgs, extraArgs);
}
if (preOrder) {
if (rootMatch) {
if (fn.apply(scope || root, callArgs) === false) {
return false;
}
}
}
for (i = 0; i < len; i++) {
if (cq._visit.call(cq, preOrder, selector, children[i], fn, scope, extraArgs) === false) {
return false;
}
}
if (!preOrder) {
if (rootMatch) {
if (fn.apply(scope || root, callArgs) === false) {
return false;
}
}
}
},
is: function(component, selector) {
if (!selector) {
return true;
}
var query = cq.cache.get(selector);
if (!query) {
query = cq.cache.add(selector, cq.parse(selector));
}
return query.is(component);
},
parse: function(selector) {
var operations = [],
selectors, sel, i, len;
selectors = Ext.splitAndUnescape(selector, ',');
for (i = 0 , len = selectors.length; i < len; i++) {
sel = Ext.String.trim(selectors[i]);
if (sel === '') {
Ext.Error.raise('Invalid ComponentQuery selector: ""');
}
operations.push(cq._parse(sel));
}
return new cq.Query({
operations: operations
});
},
_parse: function(selector) {
var operations = [],
trim = Ext.String.trim,
length = matchers.length,
lastSelector, tokenMatch, token, matchedChar, modeMatch, selectorMatch, transform, i, matcher, method, args;
while (selector && lastSelector !== selector) {
lastSelector = selector;
tokenMatch = selector.match(tokenRe);
if (tokenMatch) {
matchedChar = tokenMatch[1];
token = trim(tokenMatch[2]).replace(unescapeRe, '$1');
if (matchedChar === '#') {
operations.push({
method: filterById,
args: [
token
]
});
} else
{
operations.push({
method: filterByXType,
args: [
token,
Boolean(tokenMatch[3])
]
});
}
selector = selector.replace(tokenMatch[0], '').replace(stripLeadingSpaceRe, '$1');
}
while (!(modeMatch = selector.match(modeRe))) {
for (i = 0; selector && i < length; i++) {
matcher = matchers[i];
selectorMatch = selector.match(matcher.re);
method = matcher.method;
transform = matcher.argTransform;
if (selectorMatch) {
if (transform) {
args = transform(selectorMatch);
} else {
args = selectorMatch.slice(1);
}
operations.push({
method: Ext.isString(matcher.method) ?
Ext.functionFactory('items', Ext.String.format.apply(Ext.String, [
method
].concat(selectorMatch.slice(1)))) : matcher.method,
args: args
});
selector = selector.replace(selectorMatch[0], '').replace(stripLeadingSpaceRe, '$1');
break;
}
if (i === (length - 1)) {
Ext.Error.raise('Invalid ComponentQuery selector: "' + arguments[0] + '"');
}
}
}
if (modeMatch[1]) {
operations.push({
mode: modeMatch[2] || modeMatch[1]
});
selector = selector.replace(modeMatch[0], '').replace(stripLeadingSpaceRe, '');
}
}
return operations;
}
});
});
Ext.define('Ext.Evented', {
alternateClassName: 'Ext.EventedBase',
mixins: [
'Ext.mixin.Observable'
],
statics: {
generateSetter: function(cfg) {
var names = cfg.names,
name = cfg.name,
prefixedName = names.internal,
applyName = names.apply,
changeEventName = names.changeEvent,
doSetName = names.doSet;
return function(value) {
var me = this,
internalName = me.$configPrefixed ? prefixedName : name,
initialized = me.initialized,
oldValue,
applier = me[applyName];
if (applier) {
value = applier.call(me, value, me[internalName]);
if (value === undefined) {
return me;
}
}
oldValue = me[internalName];
if (value !== oldValue) {
if (initialized) {
me.fireAction(changeEventName, [
me,
value,
oldValue
], me.doSet, me, {
nameMap: names
});
} else {
me[internalName] = value;
if (me[doSetName]) {
me[doSetName](value, oldValue);
}
}
}
return this;
};
}
},
initialized: false,
constructor: function(config) {
this.mixins.observable.constructor.call(this, config);
this.initialized = true;
},
doSet: function(me, value, oldValue, options) {
var nameMap = options.nameMap;
me[nameMap.internal] = value;
if (me[nameMap.doSet]) {
me[nameMap.doSet].call(this, value, oldValue);
}
},
onClassExtended: function(cls, data) {
if (!data.hasOwnProperty('eventedConfig')) {
return;
}
var config = data.config,
eventedConfig = data.eventedConfig,
cacheName = 'eventedSetter',
name, cfg;
if (config) {
Ext.applyIf(config, eventedConfig);
} else {
cls.addConfig(eventedConfig);
}
for (name in eventedConfig) {
if (eventedConfig.hasOwnProperty(name)) {
cfg = Ext.Config.get(name);
data[cfg.names.set] = cfg[cacheName] || (cfg[cacheName] = this.generateSetter(cfg));
}
}
}
});
Ext.define('Ext.util.Positionable', {
mixinId: 'positionable',
_positionTopLeft: [
'position',
'top',
'left'
],
_alignRe: /^([a-z]+)-([a-z]+)(\?)?$/,
afterSetPosition: Ext.emptyFn,
getAnchorToXY: function() {
Ext.Error.raise("getAnchorToXY is not implemented in " + this.$className);
},
getBorderPadding: function() {
Ext.Error.raise("getBorderPadding is not implemented in " + this.$className);
},
getLocalX: function() {
Ext.Error.raise("getLocalX is not implemented in " + this.$className);
},
getLocalXY: function() {
Ext.Error.raise("getLocalXY is not implemented in " + this.$className);
},
getLocalY: function() {
Ext.Error.raise("getLocalY is not implemented in " + this.$className);
},
getX: function() {
Ext.Error.raise("getX is not implemented in " + this.$className);
},
getXY: function() {
Ext.Error.raise("getXY is not implemented in " + this.$className);
},
getY: function() {
Ext.Error.raise("getY is not implemented in " + this.$className);
},
setLocalX: function() {
Ext.Error.raise("setLocalX is not implemented in " + this.$className);
},
setLocalXY: function() {
Ext.Error.raise("setLocalXY is not implemented in " + this.$className);
},
setLocalY: function() {
Ext.Error.raise("setLocalY is not implemented in " + this.$className);
},
setX: function() {
Ext.Error.raise("setX is not implemented in " + this.$className);
},
setXY: function() {
Ext.Error.raise("setXY is not implemented in " + this.$className);
},
setY: function() {
Ext.Error.raise("setY is not implemented in " + this.$className);
},
adjustForConstraints: function(xy, parent) {
var vector = this.getConstrainVector(parent, xy);
if (vector) {
xy[0] += vector[0];
xy[1] += vector[1];
}
return xy;
},
alignTo: function(element, position, offsets,
animate) {
var me = this,
el = me.el;
return me.setXY(me.getAlignToXY(element, position, offsets), el.anim && !!animate ? el.anim(animate) : false);
},
calculateAnchorXY: function(anchor, extraX, extraY, mySize) {
var me = this,
el = me.el,
doc = document,
isViewport = (el.dom === doc.body || el.dom === doc),
round = Math.round,
xy, myWidth, myHeight;
anchor = (anchor || "tl").toLowerCase();
mySize = mySize || {};
myWidth = mySize.width || (isViewport ? Ext.Element.getViewportWidth() : me.getWidth());
myHeight = mySize.height || (isViewport ? Ext.Element.getViewportHeight() : me.getHeight());
switch (anchor) {
case 'tl':
xy = [
0,
0
];
break;
case 'bl':
xy = [
0,
myHeight
];
break;
case 'tr':
xy = [
myWidth,
0
];
break;
case 'c':
xy = [
round(myWidth * 0.5),
round(myHeight * 0.5)
];
break;
case 't':
xy = [
round(myWidth * 0.5),
0
];
break;
case 'l':
xy = [
0,
round(myHeight * 0.5)
];
break;
case 'r':
xy = [
myWidth,
round(myHeight * 0.5)
];
break;
case 'b':
xy = [
round(myWidth * 0.5),
myHeight
];
break;
case 'tc':
xy = [
round(myWidth * 0.5),
0
];
break;
case 'bc':
xy = [
round(myWidth * 0.5),
myHeight
];
break;
case 'br':
xy = [
myWidth,
myHeight
];
}
return [
xy[0] + extraX,
xy[1] + extraY
];
},
convertPositionSpec: Ext.identityFn,
getAlignToXY: function(alignToEl, posSpec, offset) {
var me = this,
constrainToEl, constrainTo, alignMatch, myPosition, alignToElPosition, myWidth, myHeight, alignToElRegion, swapY, swapX, constrain, align1, align2, p1y, p1x, p2y, p2x, x, y;
alignToEl = Ext.get(alignToEl.el || alignToEl);
if (!alignToEl || !alignToEl.dom) {
Ext.Error.raise({
sourceClass: 'Ext.util.Positionable',
sourceMethod: 'getAlignToXY',
msg: 'Attempted to align an element that doesn\'t exist'
});
}
offset = offset || [
0,
0
];
posSpec = (!posSpec || posSpec === "?" ? "tl-bl?" : (!(/-/).test(posSpec) && posSpec !== "" ? "tl-" + posSpec : posSpec || "tl-bl")).toLowerCase();
posSpec = me.convertPositionSpec(posSpec);
alignMatch = posSpec.match(me._alignRe);
if (!alignMatch) {
Ext.Error.raise({
sourceClass: 'Ext.util.Positionable',
sourceMethod: 'getAlignToXY',
el: alignToEl,
position: posSpec,
offset: offset,
msg: 'Attemmpted to align an element with an invalid position: "' + posSpec + '"'
});
}
align1 = alignMatch[1];
align2 = alignMatch[2];
constrain = !!alignMatch[3];
myPosition = me.getAnchorXY(align1, true);
alignToElPosition = me.getAnchorToXY(alignToEl, align2, false);
x = alignToElPosition[0] - myPosition[0] + offset[0];
y = alignToElPosition[1] - myPosition[1] + offset[1];
if (constrain) {
constrainToEl = me.constrainTo || me.container || me.el.parent();
constrainToEl = Ext.get(constrainToEl.el || constrainToEl);
constrainTo = constrainToEl.getConstrainRegion();
constrainTo.right = constrainTo.left + constrainToEl.el.dom.clientWidth;
myWidth = me.getWidth();
myHeight = me.getHeight();
alignToElRegion = alignToEl.getRegion();
p1y = align1.charAt(0);
p1x = align1.charAt(align1.length - 1);
p2y = align2.charAt(0);
p2x = align2.charAt(align2.length - 1);
swapY = (x < alignToElRegion.right && x + myWidth >= alignToElRegion.left) && ((p1y == "t" && p2y == "b") || (p1y == "b" && p2y == "t"));
swapX = (y < alignToElRegion.bottom && y + myHeight >= alignToElRegion.top) && ((p1x == "r" && p2x == "l") || (p1x == "l" && p2x == "r"));
if (x + myWidth > constrainTo.right) {
if (swapX) {
x = alignToElRegion.left - myWidth;
swapX = false;
} else {
x = constrainTo.right - myWidth;
}
}
if (x < constrainTo.left) {
x = swapX ? alignToElRegion.right : constrainTo.left;
}
if (y + myHeight > constrainTo.bottom) {
if (swapY) {
y = alignToElRegion.top - myHeight;
swapY = false;
} else {
y = constrainTo.bottom - myHeight;
}
}
if (y < constrainTo.top) {
y = swapY ? alignToElRegion.bottom : constrainTo.top;
}
}
return [
x,
y
];
},
getAnchorXY: function(anchor, local, mySize) {
var me = this,
myPos = me.getXY(),
el = me.el,
doc = document,
isViewport = el.dom == doc.body || el.dom == doc,
scroll = el.getScroll(),
extraX = isViewport ? scroll.left : local ? 0 : myPos[0],
extraY = isViewport ? scroll.top : local ? 0 : myPos[1];
return me.calculateAnchorXY(anchor, extraX, extraY, mySize);
},
getBox: function(contentBox, local) {
var me = this,
xy = local ? me.getLocalXY() : me.getXY(),
x = xy[0],
y = xy[1],
w = me.getWidth(),
h = me.getHeight(),
borderPadding, beforeX, beforeY;
if (contentBox) {
borderPadding = me.getBorderPadding();
beforeX = borderPadding.beforeX;
beforeY = borderPadding.beforeY;
x += beforeX;
y += beforeY;
w -= (beforeX + borderPadding.afterX);
h -= (beforeY + borderPadding.afterY);
}
return {
x: x,
left: x,
0: x,
y: y,
top: y,
1: y,
width: w,
height: h,
right: x + w,
bottom: y + h
};
},
calculateConstrainedPosition: function(constrainTo, proposedPosition, local, proposedSize) {
var me = this,
vector,
fp = me.floatParent,
parentNode = fp ? fp.getTargetEl() : null,
parentOffset, borderPadding, proposedConstrainPosition,
xy = false,
localXY;
if (local && fp) {
parentOffset = parentNode.getXY();
borderPadding = parentNode.getBorderPadding();
parentOffset[0] += borderPadding.beforeX;
parentOffset[1] += borderPadding.beforeY;
if (proposedPosition) {
proposedConstrainPosition = [
proposedPosition[0] + parentOffset[0],
proposedPosition[1] + parentOffset[1]
];
}
} else {
proposedConstrainPosition = proposedPosition;
}
constrainTo = constrainTo || me.constrainTo || parentNode || me.container || me.el.parent();
if (local && proposedConstrainPosition) {
proposedConstrainPosition = me.reverseTranslateXY(proposedConstrainPosition);
}
vector = ((me.constrainHeader && me.header.rendered) ? me.header : me).getConstrainVector(constrainTo, proposedConstrainPosition, proposedSize);
if (vector) {
xy = proposedPosition || me.getPosition(local);
xy[0] += vector[0];
xy[1] += vector[1];
}
return xy;
},
getConstrainRegion: function() {
var me = this,
el = me.el,
isBody = el.dom.nodeName === 'BODY',
dom = el.dom,
borders = el.getBorders(),
pos = el.getXY(),
left = pos[0] + borders.beforeX,
top = pos[1] + borders.beforeY,
scroll, width, height;
if (isBody) {
scroll = el.getScroll();
left = scroll.left;
top = scroll.top;
width = Ext.Element.getViewportWidth();
height = Ext.Element.getViewportHeight();
} else {
width = dom.clientWidth;
height = dom.clientHeight;
}
return new Ext.util.Region(top, left + width, top + height, left);
},
getConstrainVector: function(constrainTo, proposedPosition, proposedSize) {
var thisRegion = this.getRegion(),
vector = [
0,
0
],
shadowSize = (this.shadow && this.constrainShadow && !this.shadowDisabled) ? this.shadow.getShadowSize() : undefined,
overflowed = false,
constrainSize,
constraintInsets = this.constraintInsets;
if (!(constrainTo instanceof Ext.util.Region)) {
constrainTo = Ext.get(constrainTo.el || constrainTo);
constrainSize = constrainTo.getViewSize();
constrainTo = constrainTo.getConstrainRegion();
constrainTo.right = constrainTo.left + constrainSize.width;
constrainTo.bottom = constrainTo.top + constrainSize.height;
}
if (constraintInsets) {
constraintInsets = Ext.isObject(constraintInsets) ? constraintInsets : Ext.Element.parseBox(constraintInsets);
constrainTo.adjust(constraintInsets.top, constraintInsets.right, constraintInsets.bottom, constraintInsets.length);
}
if (proposedPosition) {
thisRegion.translateBy(proposedPosition[0] - thisRegion.x, proposedPosition[1] - thisRegion.y);
}
if (proposedSize) {
thisRegion.right = thisRegion.left + proposedSize[0];
thisRegion.bottom = thisRegion.top + proposedSize[1];
}
if (shadowSize) {
constrainTo.adjust(shadowSize[0], -shadowSize[1], -shadowSize[2], shadowSize[3]);
}
if (thisRegion.right > constrainTo.right) {
overflowed = true;
vector[0] = (constrainTo.right - thisRegion.right);
}
if (thisRegion.left + vector[0] < constrainTo.left) {
overflowed = true;
vector[0] = (constrainTo.left - thisRegion.left);
}
if (thisRegion.bottom > constrainTo.bottom) {
overflowed = true;
vector[1] = (constrainTo.bottom - thisRegion.bottom);
}
if (thisRegion.top + vector[1] < constrainTo.top) {
overflowed = true;
vector[1] = (constrainTo.top - thisRegion.top);
}
return overflowed ? vector : false;
},
getOffsetsTo: function(offsetsTo) {
var o = this.getXY(),
e = Ext.fly(offsetsTo.el || offsetsTo).getXY();
return [
o[0] - e[0],
o[1] - e[1]
];
},
getRegion: function() {
var box = this.getBox();
return new Ext.util.Region(box.top, box.right, box.bottom, box.left);
},
getViewRegion: function() {
var me = this,
el = me.el,
isBody = el.dom.nodeName === 'BODY',
borderPadding, scroll, pos, top, left, width, height;
if (isBody) {
scroll = el.getScroll();
left = scroll.left;
top = scroll.top;
width = Ext.Element.getViewportWidth();
height = Ext.Element.getViewportHeight();
} else {
borderPadding = me.getBorderPadding();
pos = me.getXY();
left = pos[0] + borderPadding.beforeX;
top = pos[1] + borderPadding.beforeY;
width = me.getWidth(true);
height = me.getHeight(true);
}
return new Ext.util.Region(top, left + width, top + height, left);
},
move: function(direction, distance,
animate) {
var me = this,
xy = me.getXY(),
x = xy[0],
y = xy[1],
left = [
x - distance,
y
],
right = [
x + distance,
y
],
top = [
x,
y - distance
],
bottom = [
x,
y + distance
],
hash = {
l: left,
left: left,
r: right,
right: right,
t: top,
top: top,
up: top,
b: bottom,
bottom: bottom,
down: bottom
};
direction = direction.toLowerCase();
me.setXY([
hash[direction][0],
hash[direction][1]
], animate);
},
setBox: function(box) {
var me = this,
x, y;
if (box.isRegion) {
box = {
x: box.left,
y: box.top,
width: box.right - box.left,
height: box.bottom - box.top
};
}
me.constrainBox(box);
x = box.x;
y = box.y;
me.setXY([
x,
y
]);
me.setSize(box.width, box.height);
me.afterSetPosition(x, y);
return me;
},
constrainBox: function(box) {
var me = this,
constrainedPos, x, y;
if (me.constrain || me.constrainHeader) {
x = ('x' in box) ? box.x : box.left;
y = ('y' in box) ? box.y : box.top;
constrainedPos = me.calculateConstrainedPosition(null, [
x,
y
], false, [
box.width,
box.height
]);
if (constrainedPos) {
box.x = constrainedPos[0];
box.y = constrainedPos[1];
}
}
},
translatePoints: function(x, y) {
var pos = this.translateXY(x, y);
return {
left: pos.x,
top: pos.y
};
},
translateXY: function(x, y) {
var me = this,
el = me.el,
styles = el.getStyle(me._positionTopLeft),
relative = styles.position === 'relative',
left = parseFloat(styles.left),
top = parseFloat(styles.top),
xy = me.getXY();
if (Ext.isArray(x)) {
y = x[1];
x = x[0];
}
if (isNaN(left)) {
left = relative ? 0 : el.dom.offsetLeft;
}
if (isNaN(top)) {
top = relative ? 0 : el.dom.offsetTop;
}
left = (typeof x === 'number') ? x - xy[0] + left : undefined;
top = (typeof y === 'number') ? y - xy[1] + top : undefined;
return {
x: left,
y: top
};
},
reverseTranslateXY: function(xy) {
var coords = xy,
el = this.el,
translatedXY = [],
dom = el.dom,
offsetParent = dom.offsetParent,
relative, offsetParentXY, x, y;
if (offsetParent) {
relative = el.isStyle('position', 'relative') , offsetParentXY = Ext.fly(offsetParent).getXY() , x = xy[0] + offsetParentXY[0] + offsetParent.clientLeft;
y = xy[1] + offsetParentXY[1] + offsetParent.clientTop;
if (relative) {
x += el.getPadding('l');
y += el.getPadding('t');
}
coords = [
x,
y
];
}
return coords;
}
});
Ext.define('Ext.overrides.util.Positionable', {
override: 'Ext.util.Positionable',
anchorTo: function(anchorToEl, alignment, offsets, animate, monitorScroll, callback) {
var me = this,
scroll = !Ext.isEmpty(monitorScroll),
action = function() {
me.alignTo(anchorToEl, alignment, offsets, animate);
Ext.callback(callback, me);
},
anchor = me.getAnchor();
me.removeAnchor();
Ext.apply(anchor, {
fn: action,
scroll: scroll
});
Ext.on('resize', action, null);
if (scroll) {
Ext.getWin().on('scroll', action, null, {
buffer: !isNaN(monitorScroll) ? monitorScroll : 50
});
}
action();
return me;
},
getAnchor: function() {
var el = this.el,
data, anchor;
if (!el.dom) {
return;
}
data = el.getData();
anchor = data._anchor;
if (!anchor) {
anchor = data._anchor = {};
}
return anchor;
},
removeAnchor: function() {
var anchor = this.getAnchor();
if (anchor && anchor.fn) {
Ext.un('resize', anchor.fn);
if (anchor.scroll) {
Ext.getWin().on('scroll', anchor.fn);
}
delete anchor.fn;
}
return this;
},
setBox: function(box, animate) {
var me = this;
if (box.isRegion) {
box = {
x: box.left,
y: box.top,
width: box.right - box.left,
height: box.bottom - box.top
};
}
if (animate) {
me.constrainBox(box);
me.animate(Ext.applyIf({
to: box,
listeners: {
afteranimate: Ext.Function.bind(me.afterSetPosition, me, [
box.x,
box.y
])
}
}, animate));
} else {
me.callParent([
box
]);
}
return me;
}
});
Ext.define('Ext.dom.UnderlayPool', {
constructor: function(elementConfig) {
this.elementConfig = elementConfig;
this.cache = [];
},
checkOut: function() {
var el = this.cache.shift();
if (!el) {
el = Ext.Element.create(this.elementConfig);
el.setVisibilityMode(2);
el.dom.setAttribute('data-sticky', true);
}
return el;
},
checkIn: function(el) {
this.cache.push(el);
},
reset: function() {
var cache = this.cache,
i = cache.length;
while (i--) {
cache[i].destroy();
}
this.cache = [];
}
});
Ext.define('Ext.dom.Underlay', {
requires: [
'Ext.dom.UnderlayPool'
],
constructor: function(config) {
Ext.apply(this, config);
},
beforeShow: Ext.emptyFn,
getInsertionTarget: function() {
return this.target;
},
getPool: function() {
return this.pool || (this.self.prototype.pool = new Ext.dom.UnderlayPool(this.elementConfig));
},
hide: function() {
var me = this,
el = me.el;
if (el) {
el.hide();
me.getPool().checkIn(el);
me.el = null;
me.hidden = true;
}
},
realign: function(x, y, width, height) {
var me = this,
el = me.el,
target = me.target,
offsets = me.offsets,
max = Math.max;
if (el) {
if (x == null) {
x = target.getX();
}
if (y == null) {
y = target.getY();
}
if (width == null) {
width = target.getWidth();
}
if (height == null) {
height = target.getHeight();
}
if (offsets) {
x = x + offsets.x;
y = y + offsets.y;
width = max(width + offsets.w, 0);
height = max(height + offsets.h, 0);
}
el.setXY([
x,
y
]);
el.setSize(width, height);
}
},
setZIndex: function(zIndex) {
this.zIndex = zIndex;
if (this.el) {
this.el.setStyle("z-index", zIndex);
}
},
show: function() {
var me = this,
target = me.target,
zIndex = me.zIndex,
el = me.el,
insertionTarget = me.getInsertionTarget().dom,
dom;
if (!el) {
el = me.el = me.getPool().checkOut();
}
me.beforeShow();
if (zIndex == null) {
zIndex = (parseInt(target.getStyle("z-index"), 10));
}
if (zIndex) {
el.setStyle("z-index", zIndex);
}
el.setStyle('position', me.fixed ? 'fixed' : '');
dom = el.dom;
if (dom.nextSibling !== insertionTarget) {
target.dom.parentNode.insertBefore(dom, insertionTarget);
}
el.show();
me.realign();
me.hidden = false;
}
});
Ext.define('Ext.dom.Shadow', {
extend: 'Ext.dom.Underlay',
alternateClassName: 'Ext.Shadow',
mode: 'drop',
offset: 4,
cls: Ext.baseCSSPrefix + (!Ext.supports.CSS3BoxShadow ? 'ie' : 'css') + '-shadow',
constructor: function(config) {
var me = this,
outerOffsets, offsets, offset, rad;
me.callParent([
config
]);
me.elementConfig = {
cls: me.cls,
role: 'presentation'
};
offset = me.offset;
rad = Math.floor(offset / 2);
me.opacity = 50;
switch (me.mode.toLowerCase()) {
case "drop":
outerOffsets = {
x: 0,
y: 0,
w: offset,
h: offset
};
if (Ext.supports.CSS3BoxShadow) {
offsets = {
x: offset,
y: offset,
h: -offset,
w: -offset
};
} else {
offsets = {
x: -rad,
y: -rad,
h: -rad,
w: -rad
};
};
break;
case "sides":
outerOffsets = {
x: -offset,
y: 0,
w: offset * 2,
h: offset
};
if (Ext.supports.CSS3BoxShadow) {
offsets = {
x: 0,
y: offset,
h: -offset,
w: 0
};
} else {
offsets = {
x: 1 + rad - 2 * offset,
y: -(1 + rad),
h: -1,
w: rad - 1
};
};
break;
case "frame":
outerOffsets = {
x: -offset,
y: -offset,
w: offset * 2,
h: offset * 2
};
if (Ext.supports.CSS3BoxShadow) {
offsets = {
x: 0,
y: 0,
h: 0,
w: 0
};
} else {
offsets = {
x: 1 + rad - 2 * offset,
y: 1 + rad - 2 * offset,
h: offset - rad - 1,
w: offset - rad - 1
};
};
break;
case "bottom":
outerOffsets = {
x: -offset,
y: 0,
w: offset * 2,
h: offset
};
if (Ext.supports.CSS3BoxShadow) {
offsets = {
x: 0,
y: offset,
h: -offset,
w: 0
};
} else {
offsets = {
x: 0,
y: offset,
h: 0,
w: 0
};
};
break;
}
me.offsets = offsets;
me.outerOffsets = outerOffsets;
},
getShadowSize: function() {
var me = this,
offset = me.el ? me.offset : 0,
result = [
offset,
offset,
offset,
offset
],
mode = me.mode.toLowerCase();
if (me.el && mode !== 'frame') {
result[0] = 0;
if (mode == 'drop') {
result[3] = 0;
}
}
return result;
},
boxShadowProperty: (function() {
var property = 'boxShadow',
style = document.documentElement.style;
if (!('boxShadow' in style)) {
if ('WebkitBoxShadow' in style) {
property = 'WebkitBoxShadow';
} else if ('MozBoxShadow' in style) {
property = 'MozBoxShadow';
}
}
return property;
}()),
beforeShow: function() {
var me = this,
style = me.el.dom.style,
shim = me.shim;
if (Ext.supports.CSS3BoxShadow) {
style[me.boxShadowProperty] = '0 0 ' + (me.offset + 2) + 'px #888';
} else {
style.filter = "progid:DXImageTransform.Microsoft.alpha(opacity=" + me.opacity + ") progid:DXImageTransform.Microsoft.Blur(pixelradius=" + (me.offset) + ")";
}
if (shim) {
shim.realign();
}
},
setOpacity: function(opacity) {
var el = this.el;
if (el) {
if (Ext.isIE && !Ext.supports.CSS3BoxShadow) {
opacity = Math.floor(opacity * 100 / 2) / 100;
}
this.opacity = opacity;
el.setOpacity(opacity);
}
}
});
Ext.define('Ext.dom.Shim', {
extend: 'Ext.dom.Underlay',
cls: Ext.baseCSSPrefix + 'shim',
constructor: function(config) {
this.callParent([
config
]);
this.elementConfig = {
tag: 'iframe',
cls: this.cls,
role: 'presentation',
frameBorder: '0',
src: Ext.SSL_SECURE_URL,
tabindex: '-1'
};
},
getInsertionTarget: function() {
var shadow = this.shadow;
return (shadow && shadow.el) || this.target;
}
});
Ext.define('Ext.dom.ElementEvent', {
extend: 'Ext.util.Event',
addListener: function(fn, scope, options, caller, manager) {
var me = this,
added = false,
name = me.name,
captures, directs, directCaptures;
options = options || {};
if (options.delegated === false || Ext.event.publisher.Dom.instance.directEvents[name]) {
if (options.capture) {
directCaptures = me.directCaptures || (me.directCaptures = new Ext.util.Event(me.observable, name));
added = directCaptures.addListener(fn, scope, options, caller, manager);
} else {
directs = me.directs || (me.directs = new Ext.util.Event(me.observable, name));
added = directs.addListener(fn, scope, options, caller, manager);
}
} else if (options.capture) {
captures = me.captures || (me.captures = new Ext.util.Event(me.observable, name));
added = captures.addListener(fn, scope, options, caller, manager);
} else {
added = me.callParent([
fn,
scope,
options,
caller,
manager
]);
}
return added;
},
removeListener: function(fn, scope) {
var me = this,
captures = me.captures,
directs = me.directs,
directCaptures = me.directCaptures,
removed = false,
index = me.findListener(fn, scope);
if (index !== -1) {
removed = me.callParent([
fn,
scope,
index
]);
} else {
if (directs) {
index = directs.findListener(fn, scope);
}
if (index !== -1) {
removed = directs.removeListener(fn, scope, index);
} else {
if (captures) {
index = captures.findListener(fn, scope);
}
if (index !== -1) {
removed = captures.removeListener(fn, scope, index);
} else if (directCaptures) {
index = directCaptures.findListener(fn, scope);
if (index !== -1) {
removed = directCaptures.removeListener(fn, scope, index);
}
}
}
}
return removed;
},
clearListeners: function() {
var me = this,
directCaptures = me.directCaptures,
directs = me.directs,
captures = me.captures;
if (directCaptures) {
directCaptures.clearListeners();
}
if (directs) {
directs.clearListeners();
}
if (captures) {
captures.clearListeners();
}
me.callParent();
},
suspend: function() {
var me = this,
directCaptures = me.directCaptures,
directs = me.directs,
captures = me.captures;
if (directCaptures) {
directCaptures.suspend();
}
if (directs) {
directs.suspend();
}
if (captures) {
captures.suspend();
}
me.callParent();
},
resume: function() {
var me = this,
directCaptures = me.directCaptures,
directs = me.directs,
captures = me.captures;
if (directCaptures) {
directCaptures.resume();
}
if (directs) {
directs.resume();
}
if (captures) {
captures.resume();
}
me.callParent();
}
});
Ext.define('Ext.event.publisher.Publisher', {
handledEvents: [],
statics: {
publishers: {},
publishersByEvent: {}
},
constructor: function() {
var me = this,
type = me.type;
me.handles = {};
if (!type) {
Ext.Error.raise("Event publisher '" + me.$className + "' defined without a 'type' property.");
}
if (me.self.instance) {
Ext.Error.raise("Cannot create multiple instances of '" + me.$className + "'. " + "Use '" + me.$className + ".instance' to retrieve the singleton instance.");
}
me.registerEvents();
Ext.event.publisher.Publisher.publishers[type] = me;
},
registerEvents: function(events) {
var me = this,
publishersByEvent = Ext.event.publisher.Publisher.publishersByEvent,
handledEvents = events || me.handledEvents,
ln = handledEvents.length,
eventName, i;
for (i = 0; i < ln; i++) {
eventName = handledEvents[i];
me.handles[eventName] = 1;
publishersByEvent[eventName] = me;
}
},
fire: function(element, eventName, args) {
var event;
if (element.hasListeners[eventName]) {
event = element.events[eventName];
if (event) {
event.fire.apply(event, args);
}
}
},
subscribe: function() {
Ext.Error.raise("Ext.event.publisher.Publisher subclass '" + this.$className + '" has no subscribe method.');
},
unsubscribe: function() {
Ext.Error.raise("Ext.event.publisher.Publisher subclass '" + this.$className + '" has no unsubscribe method.');
},
destroy: Ext.emptyFn
});
Ext.define('Ext.util.Offset', {
statics: {
fromObject: function(obj) {
return new this(obj.x, obj.y);
}
},
constructor: function(x, y) {
this.x = (x != null && !isNaN(x)) ? x : 0;
this.y = (y != null && !isNaN(y)) ? y : 0;
return this;
},
copy: function() {
return new Ext.util.Offset(this.x, this.y);
},
copyFrom: function(p) {
this.x = p.x;
this.y = p.y;
},
toString: function() {
return "Offset[" + this.x + "," + this.y + "]";
},
equals: function(offset) {
if (!(offset instanceof this.statics())) {
Ext.Error.raise('Offset must be an instance of Ext.util.Offset');
}
return (this.x == offset.x && this.y == offset.y);
},
round: function(to) {
if (!isNaN(to)) {
var factor = Math.pow(10, to);
this.x = Math.round(this.x * factor) / factor;
this.y = Math.round(this.y * factor) / factor;
} else {
this.x = Math.round(this.x);
this.y = Math.round(this.y);
}
},
isZero: function() {
return this.x == 0 && this.y == 0;
}
});
Ext.define('Ext.util.Region', {
requires: [
'Ext.util.Offset'
],
isRegion: true,
statics: {
getRegion: function(el) {
return Ext.fly(el).getRegion();
},
from: function(o) {
return new this(o.top, o.right, o.bottom, o.left);
}
},
constructor: function(t, r, b, l) {
var me = this;
me.y = me.top = me[1] = t;
me.right = r;
me.bottom = b;
me.x = me.left = me[0] = l;
},
contains: function(region) {
var me = this;
return (region.x >= me.x && region.right <= me.right && region.y >= me.y && region.bottom <= me.bottom);
},
intersect: function(region) {
var me = this,
t = Math.max(me.y, region.y),
r = Math.min(me.right, region.right),
b = Math.min(me.bottom, region.bottom),
l = Math.max(me.x, region.x);
if (b > t && r > l) {
return new this.self(t, r, b, l);
} else {
return false;
}
},
union: function(region) {
var me = this,
t = Math.min(me.y, region.y),
r = Math.max(me.right, region.right),
b = Math.max(me.bottom, region.bottom),
l = Math.min(me.x, region.x);
return new this.self(t, r, b, l);
},
constrainTo: function(r) {
var me = this,
constrain = Ext.Number.constrain;
me.top = me.y = constrain(me.top, r.y, r.bottom);
me.bottom = constrain(me.bottom, r.y, r.bottom);
me.left = me.x = constrain(me.left, r.x, r.right);
me.right = constrain(me.right, r.x, r.right);
return me;
},
adjust: function(t, r, b, l) {
var me = this;
me.top = me.y += t;
me.left = me.x += l;
me.right += r;
me.bottom += b;
return me;
},
getOutOfBoundOffset: function(axis, p) {
if (!Ext.isObject(axis)) {
if (axis == 'x') {
return this.getOutOfBoundOffsetX(p);
} else {
return this.getOutOfBoundOffsetY(p);
}
} else {
p = axis;
var d = new Ext.util.Offset();
d.x = this.getOutOfBoundOffsetX(p.x);
d.y = this.getOutOfBoundOffsetY(p.y);
return d;
}
},
getOutOfBoundOffsetX: function(p) {
if (p <= this.x) {
return this.x - p;
} else if (p >= this.right) {
return this.right - p;
}
return 0;
},
getOutOfBoundOffsetY: function(p) {
if (p <= this.y) {
return this.y - p;
} else if (p >= this.bottom) {
return this.bottom - p;
}
return 0;
},
isOutOfBound: function(axis, p) {
if (!Ext.isObject(axis)) {
if (axis == 'x') {
return this.isOutOfBoundX(p);
} else {
return this.isOutOfBoundY(p);
}
} else {
p = axis;
return (this.isOutOfBoundX(p.x) || this.isOutOfBoundY(p.y));
}
},
isOutOfBoundX: function(p) {
return (p < this.x || p > this.right);
},
isOutOfBoundY: function(p) {
return (p < this.y || p > this.bottom);
},
restrict: function(axis, p, factor) {
if (Ext.isObject(axis)) {
var newP;
factor = p;
p = axis;
if (p.copy) {
newP = p.copy();
} else {
newP = {
x: p.x,
y: p.y
};
}
newP.x = this.restrictX(p.x, factor);
newP.y = this.restrictY(p.y, factor);
return newP;
} else {
if (axis == 'x') {
return this.restrictX(p, factor);
} else {
return this.restrictY(p, factor);
}
}
},
restrictX: function(p, factor) {
if (!factor) {
factor = 1;
}
if (p <= this.x) {
p -= (p - this.x) * factor;
} else if (p >= this.right) {
p -= (p - this.right) * factor;
}
return p;
},
restrictY: function(p, factor) {
if (!factor) {
factor = 1;
}
if (p <= this.y) {
p -= (p - this.y) * factor;
} else if (p >= this.bottom) {
p -= (p - this.bottom) * factor;
}
return p;
},
getSize: function() {
return {
width: this.right - this.x,
height: this.bottom - this.y
};
},
copy: function() {
return new this.self(this.y, this.right, this.bottom, this.x);
},
copyFrom: function(p) {
var me = this;
me.top = me.y = me[1] = p.y;
me.right = p.right;
me.bottom = p.bottom;
me.left = me.x = me[0] = p.x;
return this;
},
toString: function() {
return "Region[" + this.top + "," + this.right + "," + this.bottom + "," + this.left + "]";
},
translateBy: function(x, y) {
if (arguments.length == 1) {
y = x.y;
x = x.x;
}
var me = this;
me.top = me.y += y;
me.right += x;
me.bottom += y;
me.left = me.x += x;
return me;
},
round: function() {
var me = this;
me.top = me.y = Math.round(me.y);
me.right = Math.round(me.right);
me.bottom = Math.round(me.bottom);
me.left = me.x = Math.round(me.x);
return me;
},
equals: function(region) {
return (this.top === region.top && this.right === region.right && this.bottom === region.bottom && this.left === region.left);
}
});
Ext.define('Ext.util.Point', {
extend: 'Ext.util.Region',
radianToDegreeConstant: 180 / Math.PI,
origin: {
x: 0,
y: 0
},
statics: {
fromEvent: function(e) {
var changedTouches = e.changedTouches,
touch = (changedTouches && changedTouches.length > 0) ? changedTouches[0] : e;
return this.fromTouch(touch);
},
fromTouch: function(touch) {
return new this(touch.pageX, touch.pageY);
},
from: function(object) {
if (!object) {
return new this(0, 0);
}
if (!(object instanceof this)) {
return new this(object.x, object.y);
}
return object;
}
},
constructor: function(x, y) {
if (x == null) {
x = 0;
}
if (y == null) {
y = 0;
}
this.callParent([
y,
x,
y,
x
]);
},
clone: function() {
return new this.self(this.x, this.y);
},
copy: function() {
return this.clone.apply(this, arguments);
},
copyFrom: function(point) {
this.x = point.x;
this.y = point.y;
return this;
},
toString: function() {
return "Point[" + this.x + "," + this.y + "]";
},
isCloseTo: function(point, threshold) {
if (typeof threshold == 'number') {
return this.getDistanceTo(point) <= threshold;
}
var x = point.x,
y = point.y,
thresholdX = threshold.x,
thresholdY = threshold.y;
return (this.x <= x + thresholdX && this.x >= x - thresholdX && this.y <= y + thresholdY && this.y >= y - thresholdY);
},
isWithin: function() {
return this.isCloseTo.apply(this, arguments);
},
isContainedBy: function(region) {
if (!(region instanceof Ext.util.Region)) {
region = Ext.get(region.el || region).getRegion();
}
return region.contains(this);
},
roundedEquals: function(point) {
if (!point || typeof point !== 'object') {
point = this.origin;
}
return (Math.round(this.x) === Math.round(point.x) && Math.round(this.y) === Math.round(point.y));
},
getDistanceTo: function(point) {
if (!point || typeof point !== 'object') {
point = this.origin;
}
var deltaX = this.x - point.x,
deltaY = this.y - point.y;
return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
},
getAngleTo: function(point) {
if (!point || typeof point !== 'object') {
point = this.origin;
}
var deltaX = this.x - point.x,
deltaY = this.y - point.y;
return Math.atan2(deltaY, deltaX) * this.radianToDegreeConstant;
}
}, function() {
this.prototype.translate = this.prototype.translateBy;
});
Ext.define('Ext.event.Event', {
alternateClassName: 'Ext.EventObjectImpl',
requires: [
'Ext.util.Point'
],
isStopped: false,
defaultPrevented: false,
isEvent: true,
statics: {
resolveTextNode: function(node) {
return (node && node.nodeType === 3) ? node.parentNode : node;
},
pointerEvents: {
pointerdown: 1,
pointermove: 1,
pointerup: 1,
pointercancel: 1,
pointerover: 1,
pointerout: 1,
pointerenter: 1,
pointerleave: 1,
MSPointerDown: 1,
MSPointerMove: 1,
MSPointerUp: 1,
MSPointerOver: 1,
MSPointerOut: 1,
MSPointerCancel: 1,
MSPointerEnter: 1,
MSPointerLeave: 1
},
mouseEvents: {
mousedown: 1,
mousemove: 1,
mouseup: 1,
mouseover: 1,
mouseout: 1,
mouseenter: 1,
mouseleave: 1
},
clickEvents: {
click: 1,
dblclick: 1
},
touchEvents: {
touchstart: 1,
touchmove: 1,
touchend: 1,
touchcancel: 1
},
focusEvents: {
focus: 1,
blur: 1,
focusin: 1,
focusout: 1,
focusenter: 1,
focusleave: 1
},
pointerTypes: {
2: 'touch',
3: 'pen',
4: 'mouse',
touch: 'touch',
pen: 'pen',
mouse: 'mouse'
}
},
constructor: function(event) {
var me = this,
self = me.self,
resolveTextNode = me.self.resolveTextNode,
changedTouches = event.changedTouches,
coordinateOwner = changedTouches ? changedTouches[0] : event,
type = event.type,
pointerType, relatedTarget;
me.pageX = coordinateOwner.pageX;
me.pageY = coordinateOwner.pageY;
me.target = me.delegatedTarget = resolveTextNode(event.target);
relatedTarget = event.relatedTarget;
if (relatedTarget) {
me.relatedTarget = resolveTextNode(relatedTarget);
}
me.browserEvent = me.event = event;
me.type = type;
me.button = event.button || 0;
me.shiftKey = event.shiftKey;
me.ctrlKey = event.ctrlKey || event.metaKey || false;
me.altKey = event.altKey;
me.charCode = event.charCode;
me.keyCode = event.keyCode;
me.buttons = event.buttons;
if (me.button === 0 && me.buttons === 0) {
me.buttons = 1;
}
if (self.forwardTab !== undefined && self.focusEvents[type]) {
me.forwardTab = self.forwardTab;
}
if (self.mouseEvents[type] || self.clickEvents[type]) {
pointerType = 'mouse';
} else if (self.pointerEvents[type]) {
pointerType = self.pointerTypes[event.pointerType];
} else if (self.touchEvents[type]) {
pointerType = 'touch';
}
if (pointerType) {
me.pointerType = pointerType;
}
me.timeStamp = me.time = +(event.timeStamp || new Date());
},
chain: function(props) {
var e = Ext.Object.chain(this);
e.parentEvent = this;
return Ext.apply(e, props);
},
correctWheelDelta: function(delta) {
var scale = this.WHEEL_SCALE,
ret = Math.round(delta / scale);
if (!ret && delta) {
ret = (delta < 0) ? -1 : 1;
}
return ret;
},
getCharCode: function() {
return this.charCode || this.keyCode;
},
getKey: function() {
return this.keyCode || this.charCode;
},
getPoint: function() {
var xy = this.getXY();
return new Ext.util.Point(xy[0], xy[1]);
},
getRelatedTarget: function(selector, maxDepth, returnEl) {
var relatedTarget = this.relatedTarget,
target = null;
if (relatedTarget) {
if (selector) {
target = Ext.fly(relatedTarget).findParent(selector, maxDepth, returnEl);
} else {
target = returnEl ? Ext.get(relatedTarget) : relatedTarget;
}
}
return target;
},
getTarget: function(selector, maxDepth, returnEl) {
return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target);
},
getTime: function() {
return this.time;
},
getWheelDelta: function() {
var deltas = this.getWheelDeltas();
return deltas.y;
},
getWheelDeltas: function() {
var me = this,
event = me.browserEvent,
dx = 0,
dy = 0;
if (Ext.isDefined(event.wheelDeltaX)) {
dx = event.wheelDeltaX;
dy = event.wheelDeltaY;
} else if (event.wheelDelta) {
dy = event.wheelDelta;
} else if (event.detail) {
dy = -event.detail;
if (dy > 100) {
dy = 3;
} else if (dy < -100) {
dy = -3;
}
if (Ext.isDefined(event.axis) && event.axis === event.HORIZONTAL_AXIS) {
dx = dy;
dy = 0;
}
}
return {
x: me.correctWheelDelta(dx),
y: me.correctWheelDelta(dy)
};
},
getX: function() {
return this.getXY()[0];
},
getXY: function() {
var me = this,
xy = me.xy;
if (!xy) {
xy = me.xy = [
me.pageX,
me.pageY
];
var x = xy[0],
browserEvent, doc, docEl, body;
if (!x && x !== 0) {
browserEvent = me.browserEvent;
doc = document;
docEl = doc.documentElement;
body = doc.body;
xy[0] = browserEvent.clientX + (docEl && docEl.scrollLeft || body && body.scrollLeft || 0) - (docEl && docEl.clientLeft || body && body.clientLeft || 0);
xy[1] = browserEvent.clientY + (docEl && docEl.scrollTop || body && body.scrollTop || 0) - (docEl && docEl.clientTop || body && body.clientTop || 0);
}
}
return xy;
},
getY: function() {
return this.getXY()[1];
},
hasModifier: function() {
var me = this;
return !!(me.ctrlKey || me.altKey || me.shiftKey || me.metaKey);
},
isNavKeyPress: function(scrollableOnly) {
var me = this,
k = me.keyCode;
return (k >= 33 && k <= 40) ||
(!scrollableOnly && (k === me.RETURN || k === me.TAB || k === me.ESC));
},
isSpecialKey: function() {
var k = this.keyCode;
return (this.type === 'keypress' && this.ctrlKey) || this.isNavKeyPress() || (k === this.BACKSPACE) ||
(k >= 16 && k <= 20) ||
(k >= 44 && k <= 46);
},
makeUnpreventable: function() {
this.browserEvent.preventDefault = Ext.emptyFn;
},
preventDefault: function() {
var me = this,
parentEvent = me.parentEvent;
me.defaultPrevented = true;
if (parentEvent) {
parentEvent.defaultPrevented = true;
}
me.browserEvent.preventDefault();
return me;
},
setCurrentTarget: function(target) {
this.currentTarget = this.delegatedTarget = target;
},
stopEvent: function() {
return this.preventDefault().stopPropagation();
},
stopPropagation: function() {
var me = this,
browserEvent = me.browserEvent,
parentEvent = me.parentEvent;
me.isStopped = true;
if (parentEvent) {
parentEvent.isStopped = true;
}
if (!browserEvent.stopPropagation) {
browserEvent.cancelBubble = true;
return me;
}
browserEvent.stopPropagation();
return me;
},
within: function(el, related, allowEl) {
var t;
if (el) {
t = related ? this.getRelatedTarget() : this.getTarget();
}
return t ? Ext.fly(el).contains(t) || !!(allowEl && t === Ext.getDom(el)) : false;
},
deprecated: {
'4.0': {
methods: {
getPageX: 'getX',
getPageY: 'getY'
}
}
}
}, function(Event) {
var prototype = Event.prototype,
constants = {
BACKSPACE: 8,
TAB: 9,
NUM_CENTER: 12,
ENTER: 13,
RETURN: 13,
SHIFT: 16,
CTRL: 17,
ALT: 18,
PAUSE: 19,
CAPS_LOCK: 20,
ESC: 27,
SPACE: 32,
PAGE_UP: 33,
PAGE_DOWN: 34,
END: 35,
HOME: 36,
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40,
PRINT_SCREEN: 44,
INSERT: 45,
DELETE: 46,
ZERO: 48,
ONE: 49,
TWO: 50,
THREE: 51,
FOUR: 52,
FIVE: 53,
SIX: 54,
SEVEN: 55,
EIGHT: 56,
NINE: 57,
A: 65,
B: 66,
C: 67,
D: 68,
E: 69,
F: 70,
G: 71,
H: 72,
I: 73,
J: 74,
K: 75,
L: 76,
M: 77,
N: 78,
O: 79,
P: 80,
Q: 81,
R: 82,
S: 83,
T: 84,
U: 85,
V: 86,
W: 87,
X: 88,
Y: 89,
Z: 90,
CONTEXT_MENU: 93,
NUM_ZERO: 96,
NUM_ONE: 97,
NUM_TWO: 98,
NUM_THREE: 99,
NUM_FOUR: 100,
NUM_FIVE: 101,
NUM_SIX: 102,
NUM_SEVEN: 103,
NUM_EIGHT: 104,
NUM_NINE: 105,
NUM_MULTIPLY: 106,
NUM_PLUS: 107,
NUM_MINUS: 109,
NUM_PERIOD: 110,
NUM_DIVISION: 111,
F1: 112,
F2: 113,
F3: 114,
F4: 115,
F5: 116,
F6: 117,
F7: 118,
F8: 119,
F9: 120,
F10: 121,
F11: 122,
F12: 123,
WHEEL_SCALE: (function() {
var scale;
if (Ext.isGecko) {
scale = 3;
} else if (Ext.isMac) {
if (Ext.isSafari && Ext.webKitVersion >= 532) {
scale = 120;
} else {
scale = 12;
}
scale *= 3;
} else {
scale = 120;
}
return scale;
}())
};
Ext.apply(Event, constants);
Ext.apply(prototype, constants);
prototype.getTrueXY = prototype.getXY;
});
Ext.define('Ext.overrides.event.Event', {
override: 'Ext.event.Event',
mousedownEvents: {
mousedown: 1,
pointerdown: 1,
touchstart: 1
},
injectEvent: (function() {
var API,
dispatchers = {},
crazyIEButtons;
if (!Ext.isIE9m && document.createEvent) {
API = {
createHtmlEvent: function(doc, type, bubbles, cancelable) {
var event = doc.createEvent('HTMLEvents');
event.initEvent(type, bubbles, cancelable);
return event;
},
createMouseEvent: function(doc, type, bubbles, cancelable, detail, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget) {
var event = doc.createEvent('MouseEvents'),
view = doc.defaultView || window;
if (event.initMouseEvent) {
event.initMouseEvent(type, bubbles, cancelable, view, detail, clientX, clientY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget);
} else {
event = doc.createEvent('UIEvents');
event.initEvent(type, bubbles, cancelable);
event.view = view;
event.detail = detail;
event.screenX = clientX;
event.screenY = clientY;
event.clientX = clientX;
event.clientY = clientY;
event.ctrlKey = ctrlKey;
event.altKey = altKey;
event.metaKey = metaKey;
event.shiftKey = shiftKey;
event.button = button;
event.relatedTarget = relatedTarget;
}
return event;
},
createUIEvent: function(doc, type, bubbles, cancelable, detail) {
var event = doc.createEvent('UIEvents'),
view = doc.defaultView || window;
event.initUIEvent(type, bubbles, cancelable, view, detail);
return event;
},
fireEvent: function(target, type, event) {
target.dispatchEvent(event);
}
};
} else if (document.createEventObject) {
crazyIEButtons = {
0: 1,
1: 4,
2: 2
};
API = {
createHtmlEvent: function(doc, type, bubbles, cancelable) {
var event = doc.createEventObject();
event.bubbles = bubbles;
event.cancelable = cancelable;
return event;
},
createMouseEvent: function(doc, type, bubbles, cancelable, detail, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget) {
var event = doc.createEventObject();
event.bubbles = bubbles;
event.cancelable = cancelable;
event.detail = detail;
event.screenX = clientX;
event.screenY = clientY;
event.clientX = clientX;
event.clientY = clientY;
event.ctrlKey = ctrlKey;
event.altKey = altKey;
event.shiftKey = shiftKey;
event.metaKey = metaKey;
event.button = crazyIEButtons[button] || button;
event.relatedTarget = relatedTarget;
return event;
},
createUIEvent: function(doc, type, bubbles, cancelable, detail) {
var event = doc.createEventObject();
event.bubbles = bubbles;
event.cancelable = cancelable;
return event;
},
fireEvent: function(target, type, event) {
target.fireEvent('on' + type, event);
}
};
}
Ext.Object.each({
load: [
false,
false
],
unload: [
false,
false
],
select: [
true,
false
],
change: [
true,
false
],
submit: [
true,
true
],
reset: [
true,
false
],
resize: [
true,
false
],
scroll: [
true,
false
]
}, function(name, value) {
var bubbles = value[0],
cancelable = value[1];
dispatchers[name] = function(targetEl, srcEvent) {
var e = API.createHtmlEvent(name, bubbles, cancelable);
API.fireEvent(targetEl, name, e);
};
});
function createMouseEventDispatcher(type, detail) {
var cancelable = (type !== 'mousemove');
return function(targetEl, srcEvent) {
var xy = srcEvent.getXY(),
e = API.createMouseEvent(targetEl.ownerDocument, type, true, cancelable, detail, xy[0], xy[1], srcEvent.ctrlKey, srcEvent.altKey, srcEvent.shiftKey, srcEvent.metaKey, srcEvent.button, srcEvent.relatedTarget);
API.fireEvent(targetEl, type, e);
};
}
Ext.each([
'click',
'dblclick',
'mousedown',
'mouseup',
'mouseover',
'mousemove',
'mouseout'
], function(eventName) {
dispatchers[eventName] = createMouseEventDispatcher(eventName, 1);
});
Ext.Object.each({
focusin: [
true,
false
],
focusout: [
true,
false
],
activate: [
true,
true
],
focus: [
false,
false
],
blur: [
false,
false
]
}, function(name, value) {
var bubbles = value[0],
cancelable = value[1];
dispatchers[name] = function(targetEl, srcEvent) {
var e = API.createUIEvent(targetEl.ownerDocument, name, bubbles, cancelable, 1);
API.fireEvent(targetEl, name, e);
};
});
if (!API) {
dispatchers = {};
API = {};
}
function cannotInject(target, srcEvent) {}
return function(target) {
var me = this,
dispatcher = dispatchers[me.type] || cannotInject,
t = target ? (target.dom || target) : me.getTarget();
dispatcher(t, me);
};
}()),
preventDefault: function() {
var me = this,
event = me.browserEvent,
parentEvent = me.parentEvent,
unselectable, target;
if (typeof event.type !== 'unknown') {
me.defaultPrevented = true;
if (parentEvent) {
parentEvent.defaultPrevented = true;
}
if (event.preventDefault) {
event.preventDefault();
} else {
if (event.type === 'mousedown') {
target = event.target;
unselectable = target.getAttribute('unselectable');
if (unselectable !== 'on') {
target.setAttribute('unselectable', 'on');
Ext.defer(function() {
target.setAttribute('unselectable', unselectable);
}, 1);
}
}
event.returnValue = false;
if (event.ctrlKey || event.keyCode > 111 && event.keyCode < 124) {
event.keyCode = -1;
}
}
}
return me;
},
stopPropagation: function() {
var me = this,
event = me.browserEvent;
if (typeof event.type !== 'unknown') {
if (me.mousedownEvents[me.type]) {
Ext.GlobalEvents.fireMouseDown(me);
}
me.callParent();
}
return me;
},
deprecated: {
'5.0': {
methods: {
clone: function() {
return new this.self(this.browserEvent, this);
}
}
}
}
}, function() {
var Event = this,
btnMap,
onKeyDown = function(e) {
if (e.keyCode === 9) {
Event.forwardTab = !e.shiftKey;
}
},
onKeyUp = function(e) {
if (e.keyCode === 9) {
delete Event.forwardTab;
}
};
if (Ext.isIE9m) {
btnMap = {
0: 0,
1: 0,
4: 1,
2: 2
};
Event.override({
statics: {
enableIEAsync: function(browserEvent) {
var name,
fakeEvent = {};
for (name in browserEvent) {
fakeEvent[name] = browserEvent[name];
}
return fakeEvent;
}
},
constructor: function(event, info, touchesMap, identifiers) {
var me = this;
me.callParent([
event,
info,
touchesMap,
identifiers
]);
me.button = btnMap[event.button];
if (event.type === 'contextmenu') {
me.button = 2;
}
me.toElement = event.toElement;
me.fromElement = event.fromElement;
},
mouseLeaveRe: /(mouseout|mouseleave)/,
mouseEnterRe: /(mouseover|mouseenter)/,
enableIEAsync: function(browserEvent) {
this.browserEvent = this.self.enableIEAsync(browserEvent);
},
getRelatedTarget: function(selector, maxDepth, returnEl) {
var me = this,
type, target;
if (!me.relatedTarget) {
type = me.type;
if (me.mouseLeaveRe.test(type)) {
target = me.toElement;
} else if (me.mouseEnterRe.test(type)) {
target = me.fromElement;
}
if (target) {
me.relatedTarget = me.self.resolveTextNode(target);
}
}
return me.callParent([
selector,
maxDepth,
returnEl
]);
}
});
document.attachEvent('onkeydown', onKeyDown);
document.attachEvent('onkeyup', onKeyUp);
window.attachEvent('onunload', function() {
document.detachEvent('onkeydown', onKeyDown);
document.detachEvent('onkeyup', onKeyUp);
});
} else if (document.addEventListener) {
document.addEventListener('keydown', onKeyDown, true);
document.addEventListener('keyup', onKeyUp, true);
}
});
Ext.define('Ext.event.publisher.Dom', {
extend: 'Ext.event.publisher.Publisher',
requires: [
'Ext.event.Event'
],
type: 'dom',
handledDomEvents: [],
reEnterCount: 0,
captureEvents: {
resize: 1,
focus: 1,
blur: 1,
paste: 1,
input: 1,
change: 1,
animationstart: 1,
animationend: 1,
scroll: 1
},
directEvents: {
mouseenter: 1,
mouseleave: 1,
pointerenter: 1,
pointerleave: 1,
MSPointerEnter: 1,
MSPointerLeave: 1,
load: 1,
unload: 1,
beforeunload: 1,
error: 1,
DOMContentLoaded: 1,
DOMFrameContentLoaded: 1,
hashchange: 1
},
blockedPointerEvents: {
pointerover: 1,
pointerout: 1,
pointerenter: 1,
pointerleave: 1,
MSPointerOver: 1,
MSPointerOut: 1,
MSPointerEnter: 1,
MSPointerLeave: 1
},
blockedCompatibilityMouseEvents: {
mouseenter: 1,
mouseleave: 1
},
constructor: function() {
var me = this;
me.bubbleSubscribers = {};
me.captureSubscribers = {};
me.directSubscribers = {};
me.directCaptureSubscribers = {};
me.delegatedListeners = {};
me.initHandlers();
Ext.onInternalReady(me.onReady, me);
me.callParent();
},
registerEvents: function() {
var me = this,
publishersByEvent = Ext.event.publisher.Publisher.publishersByEvent,
domEvents = me.handledDomEvents,
ln = domEvents.length,
i = 0,
eventName;
for (; i < ln; i++) {
eventName = domEvents[i];
me.handles[eventName] = 1;
publishersByEvent[eventName] = me;
}
this.callParent();
},
onReady: function() {
var me = this,
domEvents = me.handledDomEvents,
ln, i;
if (domEvents) {
for (i = 0 , ln = domEvents.length; i < ln; i++) {
me.addDelegatedListener(domEvents[i]);
}
}
Ext.getWin().on('unload', me.destroy, me);
},
initHandlers: function() {
var me = this;
me.onDelegatedEvent = Ext.bind(me.onDelegatedEvent, me);
me.onDirectEvent = Ext.bind(me.onDirectEvent, me);
me.onDirectCaptureEvent = Ext.bind(me.onDirectCaptureEvent, me);
},
addDelegatedListener: function(eventName) {
this.delegatedListeners[eventName] = 1;
this.target.addEventListener(eventName, this.onDelegatedEvent, !!this.captureEvents[eventName]);
},
removeDelegatedListener: function(eventName) {
delete this.delegatedListeners[eventName];
this.target.removeEventListener(eventName, this.onDelegatedEvent, !!this.captureEvents[eventName]);
},
addDirectListener: function(eventName, element, capture) {
element.dom.addEventListener(eventName, capture ? this.onDirectCaptureEvent : this.onDirectEvent, capture);
},
removeDirectListener: function(eventName, element, capture) {
element.dom.removeEventListener(eventName, capture ? this.onDirectCaptureEvent : this.onDirectEvent, capture);
},
subscribe: function(element, eventName, delegated, capture) {
var me = this,
subscribers, id;
if (delegated && !me.directEvents[eventName]) {
subscribers = capture ? me.captureSubscribers : me.bubbleSubscribers;
if (!me.handles[eventName] && !me.delegatedListeners[eventName]) {
me.addDelegatedListener(eventName);
}
if (subscribers[eventName]) {
++subscribers[eventName];
} else {
subscribers[eventName] = 1;
}
} else {
subscribers = capture ? me.directCaptureSubscribers : me.directSubscribers;
id = element.id;
subscribers = subscribers[eventName] || (subscribers[eventName] = {});
if (subscribers[id]) {
++subscribers[id];
} else {
subscribers[id] = 1;
me.addDirectListener(eventName, element, capture);
}
}
},
unsubscribe: function(element, eventName, delegated, capture) {
var me = this,
captureSubscribers, bubbleSubscribers, subscribers, id;
if (delegated && !me.directEvents[eventName]) {
captureSubscribers = me.captureSubscribers;
bubbleSubscribers = me.bubbleSubscribers;
subscribers = capture ? captureSubscribers : bubbleSubscribers;
if (subscribers[eventName]) {
--subscribers[eventName];
}
if (!me.handles[eventName] && !bubbleSubscribers[eventName] && !captureSubscribers[eventName]) {
this.removeDelegatedListener(eventName);
}
} else {
subscribers = capture ? me.directCaptureSubscribers : me.directSubscribers;
id = element.id;
subscribers = subscribers[eventName];
if (subscribers[id]) {
--subscribers[id];
}
if (!subscribers[id]) {
delete subscribers[id];
me.removeDirectListener(eventName, element, capture);
}
}
},
getPropagatingTargets: function(target) {
var currentNode = target,
targets = [],
parentNode;
while (currentNode) {
targets.push(currentNode);
parentNode = currentNode.parentNode;
if (!parentNode) {
parentNode = currentNode.defaultView;
}
currentNode = parentNode;
}
return targets;
},
publish: function(eventName, target, e) {
var me = this,
targets, el, i, ln;
if (Ext.isArray(target)) {
targets = target;
} else if (me.captureEvents[eventName]) {
el = Ext.cache[target.id];
targets = el ? [
el
] : [];
} else {
targets = me.getPropagatingTargets(target);
}
ln = targets.length;
if (me.captureSubscribers[eventName]) {
for (i = ln; i--; ) {
el = Ext.cache[targets[i].id];
if (el) {
me.fire(el, eventName, e, false, true);
if (e.isStopped) {
break;
}
}
}
}
if (!e.isStopped && me.bubbleSubscribers[eventName]) {
for (i = 0; i < ln; i++) {
el = Ext.cache[targets[i].id];
if (el) {
me.fire(el, eventName, e, false, false);
if (e.isStopped) {
break;
}
}
}
}
},
fire: function(element, eventName, e, direct, capture) {
var event;
if (element.hasListeners[eventName]) {
event = element.events[eventName];
if (event) {
if (capture && direct) {
event = event.directCaptures;
} else if (capture) {
event = event.captures;
} else if (direct) {
event = event.directs;
}
if (event) {
e.setCurrentTarget(element.dom);
event.fire(e, e.target);
}
}
}
},
onDelegatedEvent: function(e) {
if (Ext.elevateFunction) {
Ext.elevateFunction(this.doDelegatedEvent, this, [
e
]);
} else {
this.doDelegatedEvent(e);
}
},
doDelegatedEvent: function(e, invokeAfter) {
var me = this,
timeStamp = e.timeStamp;
e = new Ext.event.Event(e);
if (me.isEventBlocked(e)) {
return false;
}
me.beforeEvent(e);
Ext.frameStartTime = timeStamp;
me.reEnterCount++;
me.publish(e.type, e.target, e);
me.reEnterCount--;
if (invokeAfter !== false) {
me.afterEvent(e);
}
return e;
},
onDirectEvent: function(e) {
if (Ext.elevateFunction) {
Ext.elevateFunction(this.doDirectEvent, this, [
e,
false
]);
} else {
this.doDirectEvent(e, false);
}
},
onDirectCaptureEvent: function(e) {
if (Ext.elevateFunction) {
Ext.elevateFunction(this.doDirectEvent, this, [
e,
true
]);
} else {
this.doDirectEvent(e, true);
}
},
doDirectEvent: function(e, capture) {
var me = this,
currentTarget = e.currentTarget,
timeStamp = e.timeStamp;
e = new Ext.event.Event(e);
if (me.isEventBlocked(e)) {
return;
}
me.beforeEvent(e);
Ext.frameStartTime = timeStamp;
me.reEnterCount++;
me.fire(Ext.cache[currentTarget.id], e.type, e, true, capture);
me.reEnterCount--;
me.afterEvent(e);
},
beforeEvent: function(e) {
var browserEvent = e.browserEvent,
self = Ext.event.publisher.Dom,
touches, touch;
if (browserEvent.type === 'touchstart') {
touches = browserEvent.touches;
if (touches.length === 1) {
touch = touches[0];
self.lastTouchStartX = touch.pageX;
self.lastTouchStartY = touch.pageY;
}
}
},
afterEvent: function(e) {
var browserEvent = e.browserEvent,
type = browserEvent.type,
self = Ext.event.publisher.Dom,
GlobalEvents = Ext.GlobalEvents;
if (e.self.pointerEvents[type] && e.pointerType !== 'mouse') {
self.lastScreenPointerEventTime = Ext.now();
}
if (type === 'touchend') {
self.lastTouchEndTime = Ext.now();
}
if (!this.reEnterCount && GlobalEvents.hasListeners.idle && !GlobalEvents.idleEventMask[type]) {
GlobalEvents.fireEvent('idle');
}
},
isEventBlocked: function(e) {
var me = this,
type = e.type,
self = Ext.event.publisher.Dom,
now = Ext.now();
return (me.blockedPointerEvents[type] && e.pointerType !== 'mouse') ||
(me.blockedCompatibilityMouseEvents[type] && (now - self.lastScreenPointerEventTime < 1000)) || (Ext.supports.TouchEvents && e.self.mouseEvents[e.type] &&
Math.abs(e.pageX - self.lastTouchStartX) < 15 && Math.abs(e.pageY - self.lastTouchStartY) < 15 &&
(Ext.now() - self.lastTouchEndTime) < 1000);
},
destroy: function() {
var eventName;
for (eventName in this.delegatedListeners) {
this.removeDelegatedListener(eventName);
}
},
reset: function() {
var self = Ext.event.publisher.Dom;
self.lastScreenPointerEventTime = self.lastTouchEndTime = self.lastTouchStartX = self.lastTouchStartY = undefined;
}
}, function(Dom) {
var doc = document,
defaultView = doc.defaultView,
prototype = Dom.prototype;
if ((Ext.os.is.iOS && Ext.os.version.getMajor() < 5) || Ext.browser.is.AndroidStock || !(defaultView && defaultView.addEventListener)) {
prototype.target = doc;
} else {
prototype.target = defaultView;
}
Dom.instance = new Dom();
});
Ext.define('Ext.overrides.event.publisher.Dom', {
override: 'Ext.event.publisher.Dom'
}, function(DomPublisher) {
if (Ext.isIE9m) {
var docBody = document.body,
prototype = DomPublisher.prototype,
onDirectEvent, onDirectCaptureEvent;
prototype.target = document;
prototype.directBoundListeners = {};
onDirectEvent = function(e, publisher, capture) {
e.target = e.srcElement || window;
e.currentTarget = this;
if (capture) {
publisher.onDirectCaptureEvent(e);
} else {
publisher.onDirectEvent(e);
}
};
onDirectCaptureEvent = function(e, publisher) {
e.target = e.srcElement || window;
e.currentTarget = this;
publisher.onDirectCaptureEvent(e);
};
DomPublisher.override({
addDelegatedListener: function(eventName) {
this.delegatedListeners[eventName] = 1;
this.target.attachEvent('on' + eventName, this.onDelegatedEvent);
},
removeDelegatedListener: function(eventName) {
delete this.delegatedListeners[eventName];
this.target.detachEvent('on' + eventName, this.onDelegatedEvent);
},
addDirectListener: function(eventName, element, capture) {
var me = this,
dom = element.dom,
boundFn = Ext.Function.bind(onDirectEvent, dom, [
me,
capture
], true),
directBoundListeners = me.directBoundListeners,
handlers = directBoundListeners[eventName] || (directBoundListeners[eventName] = {});
handlers[dom.id] = boundFn;
if (dom.attachEvent) {
dom.attachEvent('on' + eventName, boundFn);
} else {
me.callParent(arguments);
}
},
removeDirectListener: function(eventName, element) {
var dom = element.dom;
if (dom.detachEvent) {
dom.detachEvent('on' + eventName, this.directBoundListeners[eventName][dom.id]);
} else {
this.callParent(arguments);
}
},
doDelegatedEvent: function(e, invokeAfter) {
e.target = e.srcElement || window;
if (e.type === 'focusin') {
e.relatedTarget = e.fromElement === docBody ? null : e.fromElement;
} else if (e.type === 'focusout') {
e.relatedTarget = e.toElement === docBody ? null : e.toElement;
}
return this.callParent([
e,
invokeAfter
]);
}
});
Ext.apply(prototype.directEvents, prototype.captureEvents);
prototype.captureEvents = {};
}
});
Ext.define('Ext.event.publisher.Gesture', {
extend: 'Ext.event.publisher.Dom',
requires: [
'Ext.util.Point',
'Ext.AnimationQueue'
],
uses: 'Ext.event.gesture.*',
type: 'gesture',
config: {
async: true
},
isCancelEvent: {
touchcancel: 1,
pointercancel: 1,
MSPointerCancel: 1
},
handledEvents: [],
handledDomEvents: [],
constructor: function(config) {
var me = this,
handledDomEvents = me.handledDomEvents,
supports = Ext.supports,
supportsTouchEvents = supports.TouchEvents,
Fn = Ext.Function,
onTouchStart = me.onTouchStart,
onTouchMove = me.onTouchMove,
onTouchEnd = me.onTouchEnd,
asyncTouchStart = Fn.createAnimationFrame(me.onTouchStart, me, null, 1),
asyncTouchMove = Fn.createAnimationFrame(me.onTouchMove, me),
asyncTouchEnd = Fn.createAnimationFrame(me.onTouchEnd, me, null, 1);
me._handlers = {
touchstart: onTouchStart,
touchmove: onTouchMove,
touchend: onTouchEnd,
touchcancel: onTouchEnd,
pointerdown: onTouchStart,
pointermove: onTouchMove,
pointerup: onTouchEnd,
pointercancel: onTouchEnd,
MSPointerDown: onTouchStart,
MSPointerMove: onTouchMove,
MSPointerUp: onTouchEnd,
MSPointerCancel: onTouchEnd,
mousedown: onTouchStart,
mousemove: onTouchMove,
mouseup: onTouchEnd
};
me._asyncHandlers = {
touchstart: asyncTouchStart,
touchmove: asyncTouchMove,
touchend: asyncTouchEnd,
touchcancel: asyncTouchEnd,
pointerdown: asyncTouchStart,
pointermove: asyncTouchMove,
pointerup: asyncTouchEnd,
pointercancel: asyncTouchEnd,
MSPointerDown: asyncTouchStart,
MSPointerMove: asyncTouchMove,
MSPointerUp: asyncTouchEnd,
MSPointerCancel: asyncTouchEnd,
mousedown: asyncTouchStart,
mousemove: asyncTouchMove,
mouseup: asyncTouchEnd
};
me.activeTouchesMap = {};
me.activeTouches = [];
me.changedTouches = [];
me.recognizers = [];
if (supportsTouchEvents) {
me.onTargetTouchMove = me.onTargetTouchMove.bind(me);
me.onTargetTouchEnd = me.onTargetTouchEnd.bind(me);
}
if (supports.PointerEvents) {
handledDomEvents.push('pointerdown', 'pointermove', 'pointerup', 'pointercancel');
me.mousePointerType = 'mouse';
} else if (supports.MSPointerEvents) {
handledDomEvents.push('MSPointerDown', 'MSPointerMove', 'MSPointerUp', 'MSPointerCancel');
me.mousePointerType = 4;
} else if (supportsTouchEvents) {
handledDomEvents.push('touchstart', 'touchmove', 'touchend', 'touchcancel');
}
if (!handledDomEvents.length || (supportsTouchEvents && Ext.isWebKit && Ext.os.is.Desktop)) {
handledDomEvents.push('mousedown', 'mousemove', 'mouseup');
}
me.initConfig(config);
return me.callParent();
},
onReady: function() {
this.callParent();
Ext.Array.sort(this.recognizers, function(recognizerA, recognizerB) {
var a = recognizerA.priority,
b = recognizerB.priority;
return (a > b) ? 1 : (a < b) ? -1 : 0;
});
},
registerRecognizer: function(recognizer) {
var me = this,
handledEvents = recognizer.handledEvents,
ln = handledEvents.length,
i;
recognizer.setOnRecognized(me.onRecognized);
recognizer.setCallbackScope(me);
for (i = 0; i < ln; i++) {
me.handledEvents.push(handledEvents[i]);
}
me.registerEvents(handledEvents);
me.recognizers.push(recognizer);
},
onRecognized: function(eventName, e, info) {
var me = this,
changedTouches = e.changedTouches,
ln = changedTouches.length,
targetGroups, targets, i, touch;
info = info || {};
info.type = eventName;
info.target = changedTouches[0].target;
info.isStopped = false;
e = e.chain(info);
if (ln > 1) {
targetGroups = [];
for (i = 0; i < ln; i++) {
touch = changedTouches[i];
targetGroups.push(touch.targets);
}
targets = me.getCommonTargets(targetGroups);
} else {
targets = changedTouches[0].targets;
}
me.publish(eventName, targets, e);
},
getCommonTargets: function(targetGroups) {
var firstTargetGroup = targetGroups[0],
ln = targetGroups.length;
if (ln === 1) {
return firstTargetGroup;
}
var commonTargets = [],
i = 1,
target, targets, j;
while (true) {
target = firstTargetGroup[firstTargetGroup.length - i];
if (!target) {
return commonTargets;
}
for (j = 1; j < ln; j++) {
targets = targetGroups[j];
if (targets[targets.length - i] !== target) {
return commonTargets;
}
}
commonTargets.unshift(target);
i++;
}
return commonTargets;
},
invokeRecognizers: function(methodName, e) {
var recognizers = this.recognizers,
ln = recognizers.length,
i, recognizer;
if (methodName === 'onStart') {
for (i = 0; i < ln; i++) {
recognizers[i].isActive = true;
}
}
for (i = 0; i < ln; i++) {
recognizer = recognizers[i];
if (recognizer.isActive && recognizer[methodName].call(recognizer, e) === false) {
recognizer.isActive = false;
}
}
},
updateTouches: function(e, isEnd) {
var me = this,
browserEvent = e.browserEvent,
touchSources = browserEvent.changedTouches || [
browserEvent
],
activeTouches = me.activeTouches,
activeTouchesMap = me.activeTouchesMap,
changedTouches = [],
touchSource, identifier, touch, target, i, ln, x, y;
for (i = 0 , ln = touchSources.length; i < ln; i++) {
touchSource = touchSources[i];
if ('identifier' in touchSource) {
identifier = touchSource.identifier;
} else if ('pointerId' in touchSource) {
identifier = touchSource.pointerId;
} else {
identifier = 1;
}
touch = activeTouchesMap[identifier];
if (!touch) {
target = Ext.event.Event.resolveTextNode(touchSource.target);
touch = activeTouchesMap[identifier] = {
identifier: identifier,
target: target,
targets: me.getPropagatingTargets(target)
};
activeTouches.push(touch);
}
if (isEnd) {
delete activeTouchesMap[identifier];
Ext.Array.remove(activeTouches, touch);
}
x = touchSource.pageX;
y = touchSource.pageY;
touch.pageX = x;
touch.pageY = y;
touch.point = new Ext.util.Point(x, y);
changedTouches.push(touch);
}
e.touches = Ext.Array.clone(activeTouches);
e.changedTouches = changedTouches;
},
doDelegatedEvent: function(e) {
var me = this;
e = me.callParent([
e,
false
]);
if (e) {
if (!e.button || e.button < 1) {
me.handlers[e.type].call(me, e);
}
me.afterEvent(e);
}
},
onTouchStart: function(e) {
var me = this,
target = e.target;
if (e.browserEvent.type === 'touchstart') {
target.addEventListener('touchmove', me.onTargetTouchMove);
target.addEventListener('touchend', me.onTargetTouchEnd);
target.addEventListener('touchcancel', me.onTargetTouchEnd);
}
me.updateTouches(e);
if (!me.isStarted) {
me.isStarted = true;
me.invokeRecognizers('onStart', e);
if (Ext.enableGarbageCollector) {
Ext.dom.GarbageCollector.pause();
}
}
me.invokeRecognizers('onTouchStart', e);
},
onTouchMove: function(e) {
var me = this,
mousePointerType = me.mousePointerType;
if (me.isStarted) {
if (mousePointerType && e.browserEvent.pointerType === mousePointerType && e.buttons === 0) {
e.type = Ext.dom.Element.prototype.eventMap.touchend;
e.button = 0;
me.onTouchEnd(e);
return;
}
me.updateTouches(e);
if (e.changedTouches.length > 0) {
me.invokeRecognizers('onTouchMove', e);
}
}
},
onTouchEnd: function(e) {
var me = this;
if (!me.isStarted) {
return;
}
me.updateTouches(e, true);
me.invokeRecognizers(me.isCancelEvent[e.type] ? 'onTouchCancel' : 'onTouchEnd', e);
if (!me.activeTouches.length) {
me.isStarted = false;
me.invokeRecognizers('onEnd', e);
if (Ext.enableGarbageCollector) {
Ext.dom.GarbageCollector.resume();
}
}
},
onTargetTouchMove: function(e) {
if (Ext.elevateFunction) {
Ext.elevateFunction(this.doTargetTouchMove, this, [
e
]);
} else {
this.doTargetTouchMove(e);
}
},
doTargetTouchMove: function(e) {
if (!Ext.getBody().contains(e.target)) {
this.onTouchMove(new Ext.event.Event(e));
}
},
onTargetTouchEnd: function(e) {
if (Ext.elevateFunction) {
Ext.elevateFunction(this.doTargetTouchEnd, this, [
e
]);
} else {
this.doTargetTouchEnd(e);
}
},
doTargetTouchEnd: function(e) {
var me = this,
target = e.target;
target.removeEventListener('touchmove', me.onTargetTouchMove);
target.removeEventListener('touchend', me.onTargetTouchEnd);
target.removeEventListener('touchcancel', me.onTargetTouchEnd);
if (!Ext.getBody().contains(target)) {
me.onTouchEnd(new Ext.event.Event(e));
}
},
updateAsync: function(async) {
this.handlers = async ? this._asyncHandlers : this._handlers;
},
reset: function() {
var me = this,
recognizers = me.recognizers,
ln = recognizers.length,
i, recognizer;
me.activeTouchesMap = {};
me.activeTouches = [];
me.changedTouches = [];
me.isStarted = false;
for (i = 0; i < ln; i++) {
recognizer = recognizers[i];
recognizer.reset();
recognizer.isActive = false;
}
this.callParent();
}
}, function(Gesture) {
Gesture.instance = new Gesture();
});
Ext.define('Ext.overrides.event.publisher.Gesture', {
override: 'Ext.event.publisher.Gesture'
}, function() {
if (Ext.isIE9m) {
this.override({
updateTouches: function(e, isEnd) {
var browserEvent = e.browserEvent,
xy = e.getXY();
browserEvent.pageX = xy[0];
browserEvent.pageY = xy[1];
this.callParent([
e,
isEnd
]);
},
doDelegatedEvent: function(e) {
this.callParent([
Ext.event.Event.enableIEAsync(e)
]);
}
});
}
});
Ext.define('Ext.event.publisher.Focus', {
extend: 'Ext.event.publisher.Dom',
type: 'focus',
handledEvents: [
'focusenter',
'focusleave'
],
handledDomEvents: [
'focusin',
'focusout'
],
doDelegatedEvent: function(e, invokeAfter) {
var me = this,
relatedTarget;
e = me.callParent([
e,
false
]);
if (e) {
if (e.type === 'focusout') {
if (e.relatedTarget == null) {
me.processFocusIn(e, e.target, document.body, invokeAfter);
}
} else {
relatedTarget = e.relatedTarget;
me.processFocusIn(e, (relatedTarget == null || !relatedTarget.tagName) ? document.body : relatedTarget, e.target, invokeAfter);
}
}
},
processFocusIn: function(e, fromElement, toElement, invokeAfter) {
var me = this,
commonAncestor = Ext.Element.getCommonAncestor(toElement, fromElement, true),
node,
targets = [],
event;
for (node = fromElement; node && node !== commonAncestor; node = node.parentNode) {
targets.push(node);
}
if (targets.length) {
event = me.createSyntheticEvent('focusleave', e, fromElement, toElement);
me.publish('focusleave', targets, event);
targets.length = 0;
if (event.isStopped) {
return;
}
}
for (node = toElement; node !== commonAncestor; node = node.parentNode) {
targets.push(node);
}
event = me.createSyntheticEvent('focusenter', e, toElement, fromElement);
me.publish('focusenter', targets, event);
if (event.isStopped) {
return;
}
if (invokeAfter) {
me.afterEvent(e);
}
Ext.GlobalEvents.fireEvent('focus', {
event: event,
toElement: toElement,
fromElement: fromElement
});
},
createSyntheticEvent: function(eventName, browserEvent, target, relatedTarget) {
var event = new Ext.event.Event(browserEvent);
event.type = eventName;
event.relatedTarget = relatedTarget;
event.target = target;
return event;
}
}, function(Focus) {
var focusTimeout;
if (!Ext.supports.FocusinFocusoutEvents) {
this.override({
handledDomEvents: [
'focus',
'blur'
],
doDelegatedEvent: function(e, invokeAfter) {
var me = this;
e = me.callSuper([
e,
false
]);
if (e) {
clearTimeout(focusTimeout);
focusTimeout = 0;
if (e.type === 'blur') {
var blurredEl = e.target === window ? document.body : e.target;
focusTimeout = setTimeout(function() {
focusTimeout = 0;
me.processFocusIn(e, blurredEl, document.body, invokeAfter);
Focus.previousActiveElement = null;
}, 0);
if (e.target === window || e.target === document) {
Focus.previousActiveElement = null;
} else {
Focus.previousActiveElement = e.target;
}
} else {
me.processFocusIn(e, Focus.previousActiveElement || document.body, e.target === window ? document.body : e.target, invokeAfter);
}
}
}
});
}
Focus.instance = new Focus();
});
Ext.define('Ext.mixin.Templatable', {
extend: 'Ext.Mixin',
mixinConfig: {
id: 'templatable'
},
referenceAttributeName: 'reference',
referenceSelector: '[reference]',
getElementConfig: function() {
return {
reference: 'element'
};
},
getElementTemplate: function() {
var elementTemplate = document.createDocumentFragment();
elementTemplate.appendChild(Ext.Element.create(this.getElementConfig(), true));
return elementTemplate;
},
initElement: function() {
var prototype = this.self.prototype;
prototype.elementTemplate = this.getElementTemplate();
prototype.initElement = prototype.doInitElement;
this.initElement.apply(this, arguments);
},
linkElement: function(reference, node) {
this.link(reference, node);
},
doInitElement: function() {
var referenceAttributeName = this.referenceAttributeName,
renderElement, referenceNodes, i, ln, referenceNode, reference;
renderElement = this.elementTemplate.cloneNode(true);
referenceNodes = renderElement.querySelectorAll(this.referenceSelector);
for (i = 0 , ln = referenceNodes.length; i < ln; i++) {
referenceNode = referenceNodes[i];
reference = referenceNode.getAttribute(referenceAttributeName);
referenceNode.removeAttribute(referenceAttributeName);
this.linkElement(reference, referenceNode);
}
}
});
Ext.define('Ext.TaskQueue', {
requires: 'Ext.AnimationQueue',
singleton: true,
pending: false,
mode: true,
constructor: function() {
this.readQueue = [];
this.writeQueue = [];
this.run = Ext.Function.bind(this.run, this);
if (Ext.os.is.iOS) {
Ext.interval(this.watch, 500, this);
}
},
requestRead: function(fn, scope, args) {
this.request(true);
this.readQueue.push(arguments);
},
requestWrite: function(fn, scope, args) {
this.request(false);
this.writeQueue.push(arguments);
},
request: function(mode) {
if (!this.pending) {
this.pendingTime = Date.now();
this.pending = true;
this.mode = mode;
if (mode) {
Ext.defer(this.run, 1, this);
} else {
Ext.Function.requestAnimationFrame(this.run);
}
}
},
watch: function() {
if (this.pending && Date.now() - this.pendingTime >= 500) {
this.run();
}
},
run: function() {
this.pending = false;
var readQueue = this.readQueue,
writeQueue = this.writeQueue,
request = null,
queue;
if (this.mode) {
queue = readQueue;
if (writeQueue.length > 0) {
request = false;
}
} else {
queue = writeQueue;
if (readQueue.length > 0) {
request = true;
}
}
var tasks = queue.slice(),
i, ln, task, fn, scope;
queue.length = 0;
for (i = 0 , ln = tasks.length; i < ln; i++) {
task = tasks[i];
fn = task[0];
scope = task[1];
if (typeof fn === 'string') {
fn = scope[fn];
}
if (task.length > 2) {
fn.apply(scope, task[2]);
} else {
fn.call(scope);
}
}
tasks.length = 0;
if (request !== null) {
this.request(request);
}
}
});
Ext.define('Ext.util.sizemonitor.Abstract', {
mixins: [
'Ext.mixin.Templatable'
],
requires: [
'Ext.TaskQueue'
],
config: {
element: null,
callback: Ext.emptyFn,
scope: null,
args: []
},
width: 0,
height: 0,
contentWidth: 0,
contentHeight: 0,
constructor: function(config) {
this.refresh = Ext.Function.bind(this.refresh, this);
this.info = {
width: 0,
height: 0,
contentWidth: 0,
contentHeight: 0,
flag: 0
};
this.initElement();
this.initConfig(config);
this.bindListeners(true);
},
bindListeners: Ext.emptyFn,
applyElement: function(element) {
if (element) {
return Ext.get(element);
}
},
updateElement: function(element) {
element.append(this.detectorsContainer);
element.addCls(Ext.baseCSSPrefix + 'size-monitored');
},
applyArgs: function(args) {
return args.concat([
this.info
]);
},
refreshMonitors: Ext.emptyFn,
forceRefresh: function() {
Ext.TaskQueue.requestRead('refresh', this);
},
getContentBounds: function() {
return this.detectorsContainer.getBoundingClientRect();
},
getContentWidth: function() {
return this.detectorsContainer.offsetWidth;
},
getContentHeight: function() {
return this.detectorsContainer.offsetHeight;
},
refreshSize: function() {
var element = this.getElement();
if (!element || element.isDestroyed) {
return false;
}
var width = element.getWidth(),
height = element.getHeight(),
contentWidth = this.getContentWidth(),
contentHeight = this.getContentHeight(),
currentContentWidth = this.contentWidth,
currentContentHeight = this.contentHeight,
info = this.info,
resized = false,
flag;
this.width = width;
this.height = height;
this.contentWidth = contentWidth;
this.contentHeight = contentHeight;
flag = ((currentContentWidth !== contentWidth ? 1 : 0) + (currentContentHeight !== contentHeight ? 2 : 0));
if (flag > 0) {
info.width = width;
info.height = height;
info.contentWidth = contentWidth;
info.contentHeight = contentHeight;
info.flag = flag;
resized = true;
this.getCallback().apply(this.getScope(), this.getArgs());
}
return resized;
},
refresh: function(force) {
if (this.refreshSize() || force) {
Ext.TaskQueue.requestWrite('refreshMonitors', this);
}
},
destroy: function() {
var element = this.getElement();
this.bindListeners(false);
if (element && !element.isDestroyed) {
element.removeCls(Ext.baseCSSPrefix + 'size-monitored');
}
delete this._element;
this.callParent();
}
});
Ext.define('Ext.util.sizemonitor.Default', {
extend: 'Ext.util.sizemonitor.Abstract',
updateElement: function(element) {},
bindListeners: function(bind) {
var element = this.getElement().dom;
if (!element) {
return;
}
if (bind) {
element.onresize = this.refresh;
} else {
delete element.onresize;
}
},
getContentBounds: function() {
return this.getElement().dom.getBoundingClientRect();
},
getContentWidth: function() {
return this.getElement().getWidth();
},
getContentHeight: function() {
return this.getElement().getHeight();
}
});
Ext.define('Ext.util.sizemonitor.Scroll', {
extend: 'Ext.util.sizemonitor.Abstract',
getElementConfig: function() {
return {
reference: 'detectorsContainer',
classList: [
Ext.baseCSSPrefix + 'size-monitors',
'scroll'
],
children: [
{
reference: 'expandMonitor',
className: 'expand'
},
{
reference: 'shrinkMonitor',
className: 'shrink'
}
]
};
},
constructor: function(config) {
this.onScroll = Ext.Function.bind(this.onScroll, this);
this.callParent(arguments);
},
bindListeners: function(bind) {
var method = bind ? 'addEventListener' : 'removeEventListener';
this.expandMonitor[method]('scroll', this.onScroll, true);
this.shrinkMonitor[method]('scroll', this.onScroll, true);
},
forceRefresh: function() {
Ext.TaskQueue.requestRead('refresh', this, [
true
]);
},
onScroll: function() {
Ext.TaskQueue.requestRead('refresh', this);
},
refreshMonitors: function() {
var expandMonitor = this.expandMonitor,
shrinkMonitor = this.shrinkMonitor,
end = 1000000;
if (expandMonitor && !expandMonitor.isDestroyed) {
expandMonitor.scrollLeft = end;
expandMonitor.scrollTop = end;
}
if (shrinkMonitor && !shrinkMonitor.isDestroyed) {
shrinkMonitor.scrollLeft = end;
shrinkMonitor.scrollTop = end;
}
}
});
Ext.define('Ext.util.sizemonitor.OverflowChange', {
extend: 'Ext.util.sizemonitor.Abstract',
constructor: function(config) {
this.onExpand = Ext.Function.bind(this.onExpand, this);
this.onShrink = Ext.Function.bind(this.onShrink, this);
this.callParent(arguments);
},
getElementConfig: function() {
return {
reference: 'detectorsContainer',
classList: [
Ext.baseCSSPrefix + 'size-monitors',
'overflowchanged'
],
children: [
{
reference: 'expandMonitor',
className: 'expand',
children: [
{
reference: 'expandHelper'
}
]
},
{
reference: 'shrinkMonitor',
className: 'shrink',
children: [
{
reference: 'shrinkHelper'
}
]
}
]
};
},
bindListeners: function(bind) {
var method = bind ? 'addEventListener' : 'removeEventListener';
this.expandMonitor[method](Ext.browser.is.Firefox ? 'underflow' : 'overflowchanged', this.onExpand, true);
this.shrinkMonitor[method](Ext.browser.is.Firefox ? 'overflow' : 'overflowchanged', this.onShrink, true);
},
onExpand: function(e) {
if (Ext.browser.is.Webkit && e.horizontalOverflow && e.verticalOverflow) {
return;
}
Ext.TaskQueue.requestRead('refresh', this);
},
onShrink: function(e) {
if (Ext.browser.is.Webkit && !e.horizontalOverflow && !e.verticalOverflow) {
return;
}
Ext.TaskQueue.requestRead('refresh', this);
},
refreshMonitors: function() {
if (this.isDestroyed) {
return;
}
var expandHelper = this.expandHelper,
shrinkHelper = this.shrinkHelper,
contentBounds = this.getContentBounds(),
width = contentBounds.width,
height = contentBounds.height,
style;
if (expandHelper && !expandHelper.isDestroyed) {
style = expandHelper.style;
style.width = (width + 1) + 'px';
style.height = (height + 1) + 'px';
}
if (shrinkHelper && !shrinkHelper.isDestroyed) {
style = shrinkHelper.style;
style.width = width + 'px';
style.height = height + 'px';
}
Ext.TaskQueue.requestRead('refresh', this);
}
});
Ext.define('Ext.util.SizeMonitor', {
requires: [
'Ext.util.sizemonitor.Default',
'Ext.util.sizemonitor.Scroll',
'Ext.util.sizemonitor.OverflowChange'
],
constructor: function(config) {
var namespace = Ext.util.sizemonitor;
if (Ext.browser.is.Firefox) {
return new namespace.OverflowChange(config);
} else if (Ext.browser.is.WebKit) {
if (!Ext.browser.is.Silk && Ext.browser.engineVersion.gtEq('535')) {
return new namespace.OverflowChange(config);
} else {
return new namespace.Scroll(config);
}
} else if (Ext.browser.is.IE11) {
return new namespace.Scroll(config);
} else {
return new namespace.Default(config);
}
}
});
Ext.define('Ext.event.publisher.ElementSize', {
extend: 'Ext.event.publisher.Publisher',
requires: [
'Ext.util.SizeMonitor'
],
type: 'size',
handledEvents: [
'resize'
],
constructor: function() {
this.monitors = {};
this.subscribers = {};
this.callParent(arguments);
},
subscribe: function(element) {
var id = element.id,
subscribers = this.subscribers,
monitors = this.monitors;
if (subscribers[id]) {
++subscribers[id];
} else {
subscribers[id] = 1;
monitors[id] = new Ext.util.SizeMonitor({
element: element,
callback: this.onElementResize,
scope: this,
args: [
element
]
});
}
element.on('painted', 'forceRefresh', monitors[id]);
return true;
},
unsubscribe: function(element) {
var id = element.id,
subscribers = this.subscribers,
monitors = this.monitors,
sizeMonitor;
if (subscribers[id] && !--subscribers[id]) {
delete subscribers[id];
sizeMonitor = monitors[id];
element.un('painted', 'forceRefresh', sizeMonitor);
sizeMonitor.destroy();
delete monitors[id];
}
},
onElementResize: function(element, info) {
Ext.TaskQueue.requestRead('fire', this, [
element,
'resize',
[
element,
info
]
]);
}
}, function(ElementSize) {
ElementSize.instance = new ElementSize();
});
Ext.define('Ext.util.paintmonitor.Abstract', {
config: {
element: null,
callback: Ext.emptyFn,
scope: null,
args: []
},
eventName: '',
monitorClass: '',
constructor: function(config) {
this.onElementPainted = Ext.Function.bind(this.onElementPainted, this);
this.initConfig(config);
},
bindListeners: function(bind) {
this.monitorElement[bind ? 'addEventListener' : 'removeEventListener'](this.eventName, this.onElementPainted, true);
},
applyElement: function(element) {
if (element) {
return Ext.get(element);
}
},
updateElement: function(element) {
this.monitorElement = Ext.Element.create({
classList: [
Ext.baseCSSPrefix + 'paint-monitor',
this.monitorClass
]
}, true);
element.appendChild(this.monitorElement);
element.addCls(Ext.baseCSSPrefix + 'paint-monitored');
this.bindListeners(true);
},
onElementPainted: function() {},
destroy: function() {
var monitorElement = this.monitorElement,
parentNode = monitorElement.parentNode,
element = this.getElement();
this.bindListeners(false);
delete this.monitorElement;
if (element && !element.isDestroyed) {
element.removeCls(Ext.baseCSSPrefix + 'paint-monitored');
delete this._element;
}
if (parentNode) {
parentNode.removeChild(monitorElement);
}
this.callParent();
}
});
Ext.define('Ext.util.paintmonitor.CssAnimation', {
extend: 'Ext.util.paintmonitor.Abstract',
eventName: Ext.browser.is.WebKit ? 'webkitAnimationEnd' : 'animationend',
monitorClass: 'cssanimation',
onElementPainted: function(e) {
if (e.animationName === Ext.baseCSSPrefix + 'paint-monitor-helper') {
this.getCallback().apply(this.getScope(), this.getArgs());
}
}
});
Ext.define('Ext.util.paintmonitor.OverflowChange', {
extend: 'Ext.util.paintmonitor.Abstract',
eventName: Ext.browser.is.Firefox ? 'overflow' : 'overflowchanged',
monitorClass: 'overflowchange',
onElementPainted: function(e) {
this.getCallback().apply(this.getScope(), this.getArgs());
}
});
Ext.define('Ext.util.PaintMonitor', {
requires: [
'Ext.util.paintmonitor.CssAnimation',
'Ext.util.paintmonitor.OverflowChange'
],
constructor: function(config) {
if (Ext.browser.is.Firefox || (Ext.browser.is.WebKit && Ext.browser.engineVersion.gtEq('536') && !Ext.os.is.Blackberry)) {
return new Ext.util.paintmonitor.OverflowChange(config);
} else {
return new Ext.util.paintmonitor.CssAnimation(config);
}
}
});
Ext.define('Ext.event.publisher.ElementPaint', {
extend: 'Ext.event.publisher.Publisher',
requires: [
'Ext.util.PaintMonitor',
'Ext.TaskQueue'
],
type: 'paint',
handledEvents: [
'painted'
],
constructor: function() {
this.monitors = {};
this.subscribers = {};
this.callParent(arguments);
},
subscribe: function(element) {
var id = element.id,
subscribers = this.subscribers;
if (subscribers[id]) {
++subscribers[id];
} else {
subscribers[id] = 1;
this.monitors[id] = new Ext.util.PaintMonitor({
element: element,
callback: this.onElementPainted,
scope: this,
args: [
element
]
});
}
},
unsubscribe: function(element) {
var id = element.id,
subscribers = this.subscribers,
monitors = this.monitors;
if (subscribers[id] && !--subscribers[id]) {
delete subscribers[id];
monitors[id].destroy();
delete monitors[id];
}
},
onElementPainted: function(element) {
Ext.TaskQueue.requestRead('fire', this, [
element,
'painted',
[
element
]
]);
}
}, function(ElementPaint) {
ElementPaint.instance = new ElementPaint();
});
Ext.define('Ext.dom.Element', function(Element) {
var WIN = window,
DOC = document,
windowId = 'ext-window',
documentId = 'ext-document',
WIDTH = 'width',
HEIGHT = 'height',
MIN_WIDTH = 'min-width',
MIN_HEIGHT = 'min-height',
MAX_WIDTH = 'max-width',
MAX_HEIGHT = 'max-height',
TOP = 'top',
RIGHT = 'right',
BOTTOM = 'bottom',
LEFT = 'left',
VISIBILITY = 'visibility',
HIDDEN = 'hidden',
DISPLAY = "display",
NONE = "none",
ZINDEX = "z-index",
POSITION = "position",
RELATIVE = "relative",
STATIC = "static",
SEPARATOR = '-',
wordsRe = /\w/g,
spacesRe = /\s+/,
classNameSplitRegex = /[\s]+/,
transparentRe = /^(?:transparent|(?:rgba[(](?:\s*\d+\s*[,]){3}\s*0\s*[)]))$/i,
adjustDirect2DTableRe = /table-row|table-.*-group/,
topRe = /top/i,
borders = {
t: 'border-top-width',
r: 'border-right-width',
b: 'border-bottom-width',
l: 'border-left-width'
},
paddings = {
t: 'padding-top',
r: 'padding-right',
b: 'padding-bottom',
l: 'padding-left'
},
margins = {
t: 'margin-top',
r: 'margin-right',
b: 'margin-bottom',
l: 'margin-left'
},
paddingsTLRB = [
paddings.l,
paddings.r,
paddings.t,
paddings.b
],
bordersTLRB = [
borders.l,
borders.r,
borders.t,
borders.b
],
numberRe = /\d+$/,
unitRe = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,
defaultUnit = 'px',
camelRe = /(-[a-z])/gi,
cssRe = /([a-z0-9\-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi,
pxRe = /^\d+(?:\.\d*)?px$/i,
propertyCache = {},
camelReplaceFn = function(m, a) {
return a.charAt(1).toUpperCase();
},
visibilityCls = Ext.baseCSSPrefix + 'hidden-visibility',
displayCls = Ext.baseCSSPrefix + 'hidden-display',
offsetsCls = Ext.baseCSSPrefix + 'hidden-offsets',
sizedCls = Ext.baseCSSPrefix + 'sized',
unsizedCls = Ext.baseCSSPrefix + 'unsized',
stretchedCls = Ext.baseCSSPrefix + 'stretched',
noTouchScrollCls = Ext.baseCSSPrefix + 'no-touch-scroll',
CREATE_ATTRIBUTES = {
style: 'style',
className: 'className',
cls: 'cls',
classList: 'classList',
text: 'text',
hidden: 'hidden',
html: 'html',
children: 'children'
},
visFly, scrollFly, caFly;
return {
alternateClassName: [
'Ext.Element'
],
mixins: [
'Ext.util.Positionable',
'Ext.mixin.Observable'
],
requires: [
'Ext.dom.Shadow',
'Ext.dom.Shim',
'Ext.dom.ElementEvent',
'Ext.event.publisher.Dom',
'Ext.event.publisher.Gesture',
'Ext.event.publisher.Focus',
'Ext.event.publisher.ElementSize',
'Ext.event.publisher.ElementPaint'
],
uses: [
'Ext.dom.Helper',
'Ext.dom.CompositeElement',
'Ext.dom.Fly'
],
observableType: 'element',
isElement: true,
skipGarbageCollection: true,
identifiablePrefix: 'ext-element-',
styleHooks: {},
validIdRe: Ext.validIdRe,
blockedEvents: Ext.supports.EmulatedMouseOver ? {
mouseover: 1
} : {},
longpressEvents: {
longpress: 1,
taphold: 1
},
constructor: function(dom) {
var me = this,
id;
if (typeof dom === 'string') {
dom = DOC.getElementById(dom);
}
if (!dom) {
Ext.Error.raise("Invalid domNode reference or an id of an existing domNode: " + dom);
return null;
}
if (Ext.cache[dom.id]) {
Ext.Error.raise("Element cache already contains an entry for id '" + dom.id + "'. Use Ext.get() to create or retrieve Element instances.");
}
me.dom = dom;
id = dom.id;
if (id) {
me.id = id;
} else {
id = dom.id = me.getUniqueId();
}
if (!me.validIdRe.test(me.id)) {
Ext.Error.raise('Invalid Element "id": "' + me.id + '"');
}
me.el = me;
Ext.cache[id] = me;
me.mixins.observable.constructor.call(me);
},
inheritableStatics: {
cache: Ext.cache = {},
VISIBILITY: 1,
DISPLAY: 2,
OFFSETS: 3,
unitRe: unitRe,
useDelegatedEvents: true,
validNodeTypes: {
1: 1,
9: 1
},
addUnits: function(size, units) {
if (typeof size === 'number') {
return size + (units || defaultUnit);
}
if (size === "" || size === "auto" || size == null) {
return size || '';
}
if (numberRe.test(size)) {
return size + (units || defaultUnit);
}
if (!unitRe.test(size)) {
Ext.Logger.warn("Warning, size detected (" + size + ") not a valid property value on Element.addUnits.");
return size || '';
}
return size;
},
create: function(attributes, domNode) {
var me = this,
hidden = CREATE_ATTRIBUTES.hidden,
element, elementStyle, tag, value, name, i, ln, className;
if (!attributes) {
attributes = {};
}
if (attributes.isElement) {
return domNode ? attributes.dom : attributes;
} else if ('nodeType' in attributes) {
return domNode ? attributes : Ext.get(attributes);
}
if (typeof attributes === 'string') {
return DOC.createTextNode(attributes);
}
tag = attributes.tag;
if (!tag) {
tag = 'div';
}
if (attributes.namespace) {
element = DOC.createElementNS(attributes.namespace, tag);
} else {
element = DOC.createElement(tag);
}
elementStyle = element.style;
if (attributes[hidden]) {
className = attributes.className;
className = (className == null) ? '' : className + ' ';
attributes.className = className + displayCls;
delete attributes[hidden];
}
for (name in attributes) {
if (name !== 'tag') {
value = attributes[name];
switch (name) {
case CREATE_ATTRIBUTES.style:
if (typeof value === 'string') {
element.setAttribute(name, value);
} else {
for (i in value) {
if (value.hasOwnProperty(i)) {
elementStyle[i] = value[i];
}
}
};
break;
case CREATE_ATTRIBUTES.className:
case CREATE_ATTRIBUTES.cls:
element.className = value;
break;
case CREATE_ATTRIBUTES.classList:
element.className = value.join(' ');
break;
case CREATE_ATTRIBUTES.text:
element.textContent = value;
break;
case CREATE_ATTRIBUTES.html:
element.innerHTML = value;
break;
case CREATE_ATTRIBUTES.children:
for (i = 0 , ln = value.length; i < ln; i++) {
element.appendChild(me.create(value[i], true));
};
break;
default:
if (value != null) {
element.setAttribute(name, value);
};
}
}
}
if (domNode) {
return element;
} else {
return me.get(element);
}
},
detach: function() {
var dom = this.dom;
if (dom && dom.parentNode && dom.tagName !== 'BODY') {
dom.parentNode.removeChild(dom);
}
return this;
},
fly: function(dom, named) {
return Ext.fly(dom, named);
},
fromPoint: function(x, y) {
return Ext.get(DOC.elementFromPoint(x, y));
},
get: function(el) {
var me = this,
cache = Ext.cache,
nodeType, dom, id, entry, isDoc, isWin, isValidNodeType;
if (!el) {
return null;
}
function warnDuplicate(id) {
Ext.Error.raise("DOM element with id " + id + " in Element cache is not the same as element in the DOM. " + "Make sure to clean up Element instances using destroy()");
}
if (el.isFly) {
el = el.dom;
}
if (typeof el === 'string') {
id = el;
if (cache.hasOwnProperty(id)) {
entry = cache[id];
if (entry.skipGarbageCollection || !Ext.isGarbage(entry.dom)) {
dom = Ext.getElementById ? Ext.getElementById(id) : DOC.getElementById(id);
if (dom && (dom !== entry.dom)) {
warnDuplicate(id);
}
return entry;
} else {
entry.destroy();
}
}
if (id === windowId) {
return Element.get(WIN);
} else if (id === documentId) {
return Element.get(DOC);
}
dom = Ext.getElementById ? Ext.getElementById(id) : DOC.getElementById(id);
if (dom) {
return new Element(dom);
}
}
nodeType = el.nodeType;
if (nodeType) {
isDoc = (nodeType === 9);
isValidNodeType = me.validNodeTypes[nodeType];
} else {
isWin = (el.window == el);
}
if (isValidNodeType || isWin) {
id = el.id;
if (cache.hasOwnProperty(id)) {
entry = cache[id];
if (entry.skipGarbageCollection || el === entry.dom || !Ext.isGarbage(entry.dom)) {
if (el !== entry.dom) {
warnDuplicate(id);
}
return entry;
} else {
entry.destroy();
}
}
if (el === DOC) {
el.id = documentId;
}
if (el == WIN) {
el.id = windowId;
}
el = new Element(el);
if (isWin || isDoc) {
el.skipGarbageCollection = true;
}
return el;
}
if (el.isElement) {
return el;
}
if (el.isComposite) {
return el;
}
if (Ext.isIterable(el)) {
return me.select(el);
}
return null;
},
getActiveElement: function() {
var active = DOC.activeElement;
if (!active || !active.focus) {
active = DOC.body;
}
return active;
},
getDocumentHeight: function() {
return Math.max(!Ext.isStrict ? DOC.body.scrollHeight : DOC.documentElement.scrollHeight, this.getViewportHeight());
},
getDocumentWidth: function() {
return Math.max(!Ext.isStrict ? DOC.body.scrollWidth : DOC.documentElement.scrollWidth, this.getViewportWidth());
},
getOrientation: function() {
if (Ext.supports.OrientationChange) {
return (WIN.orientation == 0) ? 'portrait' : 'landscape';
}
return (WIN.innerHeight > WIN.innerWidth) ? 'portrait' : 'landscape';
},
getViewportHeight: function() {
return WIN.innerHeight;
},
getViewportWidth: function() {
return WIN.innerWidth;
},
getViewSize: function() {
return {
width: Element.getViewportWidth(),
height: Element.getViewportHeight()
};
},
normalize: function(prop) {
return propertyCache[prop] || (propertyCache[prop] = prop.replace(camelRe, camelReplaceFn));
},
parseBox: function(box) {
box = box || 0;
var type = typeof box,
parts, ln;
if (type === 'number') {
return {
top: box,
right: box,
bottom: box,
left: box
};
} else if (type !== 'string') {
return box;
}
parts = box.split(' ');
ln = parts.length;
if (ln === 1) {
parts[1] = parts[2] = parts[3] = parts[0];
} else if (ln === 2) {
parts[2] = parts[0];
parts[3] = parts[1];
} else if (ln === 3) {
parts[3] = parts[1];
}
return {
top: parseFloat(parts[0]) || 0,
right: parseFloat(parts[1]) || 0,
bottom: parseFloat(parts[2]) || 0,
left: parseFloat(parts[3]) || 0
};
},
parseStyles: function(styles) {
var out = {},
matches;
if (styles) {
cssRe.lastIndex = 0;
while ((matches = cssRe.exec(styles))) {
out[matches[1]] = matches[2] || '';
}
}
return out;
},
select: function(selector, composite, root) {
return Ext.fly(root || DOC).select(selector, composite);
},
query: function(selector, asDom, root) {
return Ext.fly(root || DOC).query(selector, asDom);
},
unitizeBox: function(box, units) {
var me = this;
box = me.parseBox(box);
return me.addUnits(box.top, units) + ' ' + me.addUnits(box.right, units) + ' ' + me.addUnits(box.bottom, units) + ' ' + me.addUnits(box.left, units);
},
serializeForm: function(form) {
var fElements = form.elements || (DOC.forms[form] || Ext.getDom(form)).elements,
hasSubmit = false,
encoder = encodeURIComponent,
data = '',
eLen = fElements.length,
element, name, type, options, hasValue, e, o, oLen, opt;
for (e = 0; e < eLen; e++) {
element = fElements[e];
name = element.name;
type = element.type;
options = element.options;
if (!element.disabled && name) {
if (/select-(one|multiple)/i.test(type)) {
oLen = options.length;
for (o = 0; o < oLen; o++) {
opt = options[o];
if (opt.selected) {
hasValue = opt.hasAttribute('value');
data += Ext.String.format('{0}={1}&', encoder(name), encoder(hasValue ? opt.value : opt.text));
}
}
} else if (!(/file|undefined|reset|button/i.test(type))) {
if (!(/radio|checkbox/i.test(type) && !element.checked) && !(type == 'submit' && hasSubmit)) {
data += encoder(name) + '=' + encoder(element.value) + '&';
hasSubmit = /submit/i.test(type);
}
}
}
}
return data.substr(0, data.length - 1);
},
getCommonAncestor: function(nodeA, nodeB, returnDom) {
caFly = caFly || new Ext.dom.Fly();
caFly.attach(Ext.getDom(nodeA));
while (!caFly.isAncestor(nodeB)) {
if (caFly.dom.parentNode) {
caFly.attach(caFly.dom.parentNode);
} else
{
caFly.attach(document.body);
break;
}
}
return returnDom ? caFly.dom : Ext.get(caFly);
}
},
addCls: function(names, prefix, suffix) {
var me = this,
elementData = me.getData(),
hasNewCls, dom, map, classList, i, ln, name;
if (!names) {
return me;
}
if (!elementData.isSynchronized) {
me.synchronize();
}
dom = me.dom;
map = elementData.classMap;
classList = elementData.classList;
prefix = prefix ? prefix + SEPARATOR : '';
suffix = suffix ? SEPARATOR + suffix : '';
if (typeof names === 'string') {
names = names.split(spacesRe);
}
for (i = 0 , ln = names.length; i < ln; i++) {
name = names[i];
if (name) {
name = prefix + name + suffix;
if (!map[name]) {
map[name] = true;
classList.push(name);
hasNewCls = true;
}
}
}
if (hasNewCls) {
dom.className = classList.join(' ');
}
return me;
},
addStyles: function(sides, styles) {
var totalSize = 0,
sidesArr = (sides || '').match(wordsRe),
i,
len = sidesArr.length,
side,
styleSides = [];
if (len === 1) {
totalSize = Math.abs(parseFloat(this.getStyle(styles[sidesArr[0]])) || 0);
} else if (len) {
for (i = 0; i < len; i++) {
side = sidesArr[i];
styleSides.push(styles[side]);
}
styleSides = this.getStyle(styleSides);
for (i = 0; i < len; i++) {
side = sidesArr[i];
totalSize += parseFloat(styleSides[styles[side]]) || 0;
}
}
return totalSize;
},
addUnits: function(size, units) {
return Element.addUnits(size, units);
},
adjustDirect2DDimension: function(dimension) {
var me = this,
dom = me.dom,
display = me.getStyle('display'),
inlineDisplay = dom.style.display,
inlinePosition = dom.style.position,
originIndex = dimension === WIDTH ? 0 : 1,
currentStyle = dom.currentStyle,
floating;
if (display === 'inline') {
dom.style.display = 'inline-block';
}
dom.style.position = display.match(adjustDirect2DTableRe) ? 'absolute' : 'static';
floating = (parseFloat(currentStyle[dimension]) || parseFloat(currentStyle.msTransformOrigin.split(' ')[originIndex]) * 2) % 1;
dom.style.position = inlinePosition;
if (display === 'inline') {
dom.style.display = inlineDisplay;
}
return floating;
},
animate: function(animation) {
animation = new Ext.fx.Animation(animation);
animation.setElement(this);
this._activeAnimation = animation;
animation.on({
animationend: this._onAnimationEnd
});
Ext.Animator.run(animation);
},
_onAnimationEnd: function() {
this._activeAnimation = null;
},
getActiveAnimation: function() {
return this._activeAnimation;
},
append: function() {
this.appendChild.apply(this, arguments);
},
appendChild: function(el, returnDom) {
var me = this,
insertEl, eLen, e;
if (el.nodeType || el.dom || typeof el === 'string') {
el = Ext.getDom(el);
me.dom.appendChild(el);
return !returnDom ? Ext.get(el) : el;
} else if (el.length) {
insertEl = Ext.fly(document.createDocumentFragment());
eLen = el.length;
for (e = 0; e < eLen; e++) {
insertEl.appendChild(el[e], returnDom);
}
me.dom.appendChild(insertEl.dom);
return returnDom ? insertEl.dom : insertEl;
} else {
return me.createChild(el, null, returnDom);
}
},
appendTo: function(el) {
Ext.getDom(el).appendChild(this.dom);
return this;
},
applyStyles: function(styles) {
if (styles) {
if (typeof styles === "function") {
styles = styles.call();
}
if (typeof styles === "string") {
styles = Element.parseStyles(styles);
}
if (typeof styles === "object") {
this.setStyle(styles);
}
}
return this;
},
blur: function() {
var me = this,
dom = me.dom;
if (dom !== DOC.body) {
try {
dom.blur();
} catch (e) {}
return me;
} else {
return me.focus(undefined, dom);
}
},
cacheScrollValues: function() {
var me = this,
scrollValues = [],
scrolledDescendants = [],
descendants, descendant, i, len;
scrollFly = scrollFly || new Ext.dom.Fly();
descendants = me.query('*');
for (i = 0 , len = descendants.length; i < len; i++) {
descendant = descendants[i];
if (descendant.scrollTop > 0 || descendant.scrollLeft !== 0) {
scrolledDescendants.push(descendant);
scrollValues.push(scrollFly.attach(descendant).getScroll());
}
}
return function() {
var scroll, i, len;
for (i = 0 , len = scrolledDescendants.length; i < len; i++) {
scroll = scrollValues[i];
scrollFly.attach(scrolledDescendants[i]);
scrollFly.setScrollLeft(scroll.left);
scrollFly.setScrollTop(scroll.top);
}
};
},
center: function(centerIn) {
return this.alignTo(centerIn || DOC, 'c-c');
},
child: function(selector, returnDom) {
var me = this,
id = Ext.get(me).id;
return me.selectNode(Ext.makeIdSelector(id) + " > " + selector, !!returnDom);
},
constrainScrollLeft: function(left) {
var dom = this.dom;
return Math.max(Math.min(left, dom.scrollWidth - dom.clientWidth), 0);
},
constrainScrollTop: function(top) {
var dom = this.dom;
return Math.max(Math.min(top, dom.scrollHeight - dom.clientHeight), 0);
},
createChild: function(config, insertBefore, returnDom) {
config = config || {
tag: 'div'
};
if (insertBefore) {
return Ext.DomHelper.insertBefore(insertBefore, config, returnDom !== true);
} else {
return Ext.DomHelper.append(this.dom, config, returnDom !== true);
}
},
contains: function(element) {
if (!element) {
return false;
}
var me = this,
dom = Ext.getDom(element);
return (dom === me.dom) || me.isAncestor(dom);
},
destroy: function() {
var me = this,
dom = me.dom;
if (me.isDestroyed) {
Ext.Logger.warn("Cannot destroy Element \"" + me.id + "\". Already destroyed.");
return;
}
if (dom) {
if (dom === DOC.body) {
Ext.Error.raise("Cannot destroy body element.");
} else if (dom === DOC) {
Ext.Error.raise("Cannot destroy document object.");
} else if (dom === WIN) {
Ext.Error.raise("Cannot destroy window object");
}
}
if (dom && dom.parentNode) {
dom.parentNode.removeChild(dom);
}
me.collect();
},
detach: function() {
var dom = this.dom;
if (dom && dom.parentNode && dom.tagName !== 'BODY') {
dom.parentNode.removeChild(dom);
}
return this;
},
disableShadow: function() {
var shadow = this.shadow;
if (shadow) {
shadow.hide();
shadow.disabled = true;
}
},
disableShim: function() {
var shim = this.shim;
if (shim) {
shim.hide();
shim.disabled = true;
}
},
disableTouchContextMenu: function() {
this._contextMenuListenerRemover = this.on({
MSHoldVisual: function(e) {
e.preventDefault();
},
destroyable: true,
delegated: false
});
},
disableTouchScroll: function() {
this.addCls(noTouchScrollCls);
this.on({
touchmove: function(e) {
e.preventDefault();
},
translate: false
});
},
doReplaceWith: function(element) {
var dom = this.dom;
dom.parentNode.replaceChild(Ext.getDom(element), dom);
},
doScrollIntoView: function(container, hscroll, animate, highlight, getScrollX, scrollTo) {
scrollFly = scrollFly || new Ext.dom.Fly();
var me = this,
dom = me.dom,
scrollX = scrollFly.attach(container)[getScrollX](),
scrollY = container.scrollTop,
position = me.getScrollIntoViewXY(container, scrollX, scrollY),
newScrollX = position.x,
newScrollY = position.y;
if (highlight) {
if (animate) {
animate = Ext.apply({
listeners: {
afteranimate: function() {
scrollFly.attach(dom).highlight();
}
}
}, animate);
} else {
scrollFly.attach(dom).highlight();
}
}
if (newScrollY !== scrollY) {
scrollFly.attach(container).scrollTo('top', newScrollY, animate);
}
if (hscroll !== false && (newScrollX !== scrollX)) {
scrollFly.attach(container)[scrollTo]('left', newScrollX, animate);
}
return me;
},
down: function(selector, returnDom) {
return this.selectNode(selector, !!returnDom);
},
enableShadow: function(options,
isVisible) {
var me = this,
shadow = me.shadow || (me.shadow = new Ext.dom.Shadow(Ext.apply({
target: me
}, options))),
shim = me.shim;
if (shim) {
shim.offsets = shadow.outerOffsets;
shim.shadow = shadow;
shadow.shim = shim;
}
if (isVisible === true || (isVisible !== false && me.isVisible())) {
shadow.show();
} else {
shadow.hide();
}
shadow.disabled = false;
},
enableShim: function(options,
isVisible) {
var me = this,
shim = me.shim || (me.shim = new Ext.dom.Shim(Ext.apply({
target: me
}, options))),
shadow = me.shadow;
if (shadow) {
shim.offsets = shadow.outerOffsets;
shim.shadow = shadow;
shadow.shim = shim;
}
if (isVisible === true || (isVisible !== false && me.isVisible())) {
shim.show();
} else {
shim.hide();
}
shim.disabled = false;
},
findParent: function(simpleSelector, limit, returnEl) {
var me = this,
target = me.dom,
topmost = DOC.documentElement,
depth = 0;
if (limit || limit === 0) {
if (typeof limit !== 'number') {
topmost = Ext.getDom(limit);
limit = Number.MAX_VALUE;
}
} else {
limit = 50;
}
while (target && target.nodeType === 1 && depth < limit && target !== topmost) {
if (Ext.fly(target).is(simpleSelector)) {
return returnEl ? Ext.get(target) : target;
}
depth++;
target = target.parentNode;
}
return null;
},
findParentNode: function(simpleSelector, limit, returnEl) {
var p = Ext.fly(this.dom.parentNode);
return p ? p.findParent(simpleSelector, limit, returnEl) : null;
},
first: function(selector, returnDom) {
return this.matchNode('nextSibling', 'firstChild', selector, returnDom);
},
focus: function(defer,
dom) {
var me = this;
dom = dom || me.dom;
try {
if (Number(defer)) {
Ext.defer(me.focus, defer, me, [
null,
dom
]);
} else {
Ext.GlobalEvents.fireEvent('beforefocus', dom);
dom.focus();
}
} catch (e) {}
return me;
},
collect: function() {
var me = this,
dom = me.dom,
shadow = me.shadow,
shim = me.shim;
if (!me.isFly) {
me.mixins.observable.destroy.call(me);
delete Ext.cache[me.id];
me.isDestroyed = true;
me.el = null;
}
if (dom) {
dom._extData = me.dom = null;
}
if (shadow) {
shadow.hide();
me.shadow = null;
}
if (shim) {
shim.hide();
me.shim = null;
}
},
getAnchorToXY: function(el, anchor, local, mySize) {
return el.getAnchorXY(anchor, local, mySize);
},
getAttribute: function(name, namespace) {
var dom = this.dom;
return namespace ? (dom.getAttributeNS(namespace, name) || dom.getAttribute(namespace + ":" + name)) : (dom.getAttribute(name) || dom[name] || null);
},
getAttributes: function() {
var attributes = this.dom.attributes,
result = {},
attr, i, len;
for (i = 0 , len = attributes.length; i < len; i++) {
attr = attributes[i];
result[attr.name] = attr.value;
}
return result;
},
getBottom: function(local) {
return (local ? this.getLocalY() : this.getY()) + this.getHeight();
},
getById: function(id, asDom) {
var dom = DOC.getElementById(id) || this.dom.querySelector(Ext.makeIdSelector(id));
return asDom ? dom : (dom ? Ext.get(dom) : null);
},
getBorderPadding: function() {
var paddingWidth = this.getStyle(paddingsTLRB),
bordersWidth = this.getStyle(bordersTLRB);
return {
beforeX: (parseFloat(bordersWidth[borders.l]) || 0) + (parseFloat(paddingWidth[paddings.l]) || 0),
afterX: (parseFloat(bordersWidth[borders.r]) || 0) + (parseFloat(paddingWidth[paddings.r]) || 0),
beforeY: (parseFloat(bordersWidth[borders.t]) || 0) + (parseFloat(paddingWidth[paddings.t]) || 0),
afterY: (parseFloat(bordersWidth[borders.b]) || 0) + (parseFloat(paddingWidth[paddings.b]) || 0)
};
},
getBorders: function() {
var bordersWidth = this.getStyle(bordersTLRB);
return {
beforeX: (parseFloat(bordersWidth[borders.l]) || 0),
afterX: (parseFloat(bordersWidth[borders.r]) || 0),
beforeY: (parseFloat(bordersWidth[borders.t]) || 0),
afterY: (parseFloat(bordersWidth[borders.b]) || 0)
};
},
getBorderWidth: function(side) {
return this.addStyles(side, borders);
},
getData: function(preventCreate) {
var dom = this.dom,
data;
if (dom) {
data = dom._extData;
if (!data && !preventCreate) {
dom._extData = data = {};
}
}
return data;
},
getFirstChild: function() {
return Ext.get(this.dom.firstElementChild);
},
getHeight: function(contentHeight, preciseHeight) {
var me = this,
hidden = me.isStyle('display', 'none'),
height, floating;
if (hidden) {
return 0;
}
height = me.dom.offsetHeight;
if (Ext.supports.Direct2DBug) {
floating = me.adjustDirect2DDimension(HEIGHT);
if (preciseHeight) {
height += floating;
} else if (floating > 0 && floating < 0.5) {
height++;
}
}
if (contentHeight) {
height -= me.getBorderWidth("tb") + me.getPadding("tb");
}
return (height < 0) ? 0 : height;
},
getHtml: function() {
return this.dom ? this.dom.innerHTML : '';
},
getLeft: function(local) {
return local ? this.getLocalX() : this.getX();
},
getLocalX: function() {
var me = this,
offsetParent,
x = me.getStyle('left');
if (!x || x === 'auto') {
x = 0;
} else if (pxRe.test(x)) {
x = parseFloat(x);
} else {
x = me.getX();
offsetParent = me.dom.offsetParent;
if (offsetParent) {
x -= Ext.fly(offsetParent).getX();
}
}
return x;
},
getLocalXY: function() {
var me = this,
offsetParent,
style = me.getStyle([
'left',
'top'
]),
x = style.left,
y = style.top;
if (!x || x === 'auto') {
x = 0;
} else if (pxRe.test(x)) {
x = parseFloat(x);
} else {
x = me.getX();
offsetParent = me.dom.offsetParent;
if (offsetParent) {
x -= Ext.fly(offsetParent).getX();
}
}
if (!y || y === 'auto') {
y = 0;
} else if (pxRe.test(y)) {
y = parseFloat(y);
} else {
y = me.getY();
offsetParent = me.dom.offsetParent;
if (offsetParent) {
y -= Ext.fly(offsetParent).getY();
}
}
return [
x,
y
];
},
getLocalY: function() {
var me = this,
offsetParent,
y = me.getStyle('top');
if (!y || y === 'auto') {
y = 0;
} else if (pxRe.test(y)) {
y = parseFloat(y);
} else {
y = me.getY();
offsetParent = me.dom.offsetParent;
if (offsetParent) {
y -= Ext.fly(offsetParent).getY();
}
}
return y;
},
getMargin: (function() {
var hash = {
t: "top",
l: "left",
r: "right",
b: "bottom"
},
allMargins = [
'margin-top',
'margin-left',
'margin-right',
'margin-bottom'
];
return function(side) {
var me = this,
style, key, o;
if (!side) {
style = me.getStyle(allMargins);
o = {};
if (style && typeof style === 'object') {
o = {};
for (key in margins) {
o[key] = o[hash[key]] = parseFloat(style[margins[key]]) || 0;
}
}
} else {
o = me.addStyles(side, margins);
}
return o;
};
})(),
getPadding: function(side) {
return this.addStyles(side, paddings);
},
getParent: function() {
return Ext.get(this.dom.parentNode);
},
getRight: function(local) {
return (local ? this.getLocalX() : this.getX()) + this.getWidth();
},
getScroll: function() {
var me = this,
dom = me.dom,
docElement = DOC.documentElement,
left, top,
body = document.body;
if (dom === DOC || dom === body) {
left = docElement.scrollLeft || (body ? body.scrollLeft : 0);
top = docElement.scrollTop || (body ? body.scrollTop : 0);
} else {
left = dom.scrollLeft;
top = dom.scrollTop;
}
return {
left: left,
top: top
};
},
getScrollIntoViewXY: function(container, scrollX, scrollY) {
var dom = this.dom,
ct = Ext.getDom(container),
offsets = this.getOffsetsTo(ct),
width = dom.offsetWidth,
height = dom.offsetHeight,
left = offsets[0] + scrollX,
top = offsets[1] + scrollY,
bottom = top + height,
right = left + width,
viewHeight = ct.clientHeight,
viewWidth = ct.clientWidth,
viewLeft = scrollX,
viewTop = scrollY,
viewBottom = viewTop + viewHeight,
viewRight = viewLeft + viewWidth;
if (height > viewHeight || top < viewTop) {
scrollY = top;
} else if (bottom > viewBottom) {
scrollY = bottom - viewHeight;
}
if (width > viewWidth || left < viewLeft) {
scrollX = left;
} else if (right > viewRight) {
scrollX = right - viewWidth;
}
return {
x: scrollX,
y: scrollY
};
},
getScrollLeft: function() {
var dom = this.dom;
if (dom === DOC || dom === document.body) {
return this.getScroll().left;
} else {
return dom.scrollLeft;
}
},
getScrollTop: function() {
var dom = this.dom;
if (dom === DOC || dom === document.body) {
return this.getScroll().top;
} else {
return dom.scrollTop;
}
},
getSize: function(contentSize) {
return {
width: this.getWidth(contentSize),
height: this.getHeight(contentSize)
};
},
getStyle: function(property, inline) {
var me = this,
dom = me.dom,
multiple = typeof property !== 'string',
hooks = me.styleHooks,
prop = property,
props = prop,
len = 1,
domStyle, camel, values, hook, out, style, i;
if (multiple) {
values = {};
prop = props[0];
i = 0;
if (!(len = props.length)) {
return values;
}
}
if (!dom || dom.documentElement) {
return values || '';
}
domStyle = dom.style;
if (inline) {
style = domStyle;
} else {
style = dom.ownerDocument.defaultView.getComputedStyle(dom, null);
if (!style) {
inline = true;
style = domStyle;
}
}
do {
hook = hooks[prop];
if (!hook) {
hooks[prop] = hook = {
name: Element.normalize(prop)
};
}
if (hook.get) {
out = hook.get(dom, me, inline, style);
} else {
camel = hook.name;
out = style[camel];
}
if (!multiple) {
return out;
}
values[prop] = out;
prop = props[++i];
} while (i < len);
return values;
},
getStyleValue: function(name) {
return this.dom.style.getPropertyValue(name);
},
getTop: function(local) {
return local ? this.getLocalY() : this.getY();
},
getValue: function(asNumber) {
var value = this.dom.value;
return asNumber ? parseInt(value, 10) : value;
},
getViewSize: function() {
var dom = this.dom;
if (dom === DOC || dom === DOC.body) {
return {
width: Element.getViewportWidth(),
height: Element.getViewportHeight()
};
} else {
return {
width: dom.clientWidth,
height: dom.clientHeight
};
}
},
getVisibilityMode: function() {
var me = this,
data = me.getData(),
mode = data.visibilityMode;
if (mode === undefined) {
data.visibilityMode = mode = Element.DISPLAY;
}
return mode;
},
getWidth: function(contentWidth, preciseWidth) {
var me = this,
dom = me.dom,
hidden = me.isStyle('display', 'none'),
rect, width, floating;
if (hidden) {
return 0;
}
if (Ext.supports.BoundingClientRect) {
rect = dom.getBoundingClientRect();
width = (me.vertical && !Ext.supports.RotatedBoundingClientRect) ? (rect.bottom - rect.top) : (rect.right - rect.left);
width = preciseWidth ? width : Math.ceil(width);
} else {
width = dom.offsetWidth;
}
if (Ext.supports.Direct2DBug && !me.vertical) {
floating = me.adjustDirect2DDimension(WIDTH);
if (preciseWidth) {
width += floating;
}
else if (floating > 0 && floating < 0.5) {
width++;
}
}
if (contentWidth) {
width -= me.getBorderWidth("lr") + me.getPadding("lr");
}
return (width < 0) ? 0 : width;
},
getX: function() {
return this.getXY()[0];
},
getXY: function() {
var round = Math.round,
dom = this.dom,
x = 0,
y = 0,
box, scroll;
if (dom !== DOC && dom !== DOC.body) {
try {
box = dom.getBoundingClientRect();
} catch (ex) {
box = {
left: 0,
top: 0
};
}
x = round(box.left);
y = round(box.top);
scroll = Ext.getDoc().getScroll();
x += scroll.left;
y += scroll.top;
}
return [
x,
y
];
},
getY: function() {
return this.getXY()[1];
},
getZIndex: function() {
return parseInt(this.getStyle('z-index'), 10);
},
hasCls: function(name) {
var elementData = this.getData();
if (!elementData.isSynchronized) {
this.synchronize();
}
return elementData.classMap.hasOwnProperty(name);
},
hide: function() {
this.setVisible(false);
return this;
},
insertAfter: function(el) {
el = Ext.getDom(el);
el.parentNode.insertBefore(this.dom, el.nextSibling);
return this;
},
insertBefore: function(el) {
el = Ext.getDom(el);
el.parentNode.insertBefore(this.dom, el);
return this;
},
insertFirst: function(el, returnDom) {
el = el || {};
if (el.nodeType || el.dom || typeof el === 'string') {
el = Ext.getDom(el);
this.dom.insertBefore(el, this.dom.firstChild);
return !returnDom ? Ext.get(el) : el;
} else {
return this.createChild(el, this.dom.firstChild, returnDom);
}
},
insertHtml: function(where, html, returnEl) {
var el = Ext.DomHelper.insertHtml(where, this.dom, html);
return returnEl ? Ext.get(el) : el;
},
insertSibling: function(el, where, returnDom) {
var me = this,
DomHelper = Ext.DomHelper,
isAfter = (where || 'before').toLowerCase() === 'after',
rt, insertEl, eLen, e;
if (Ext.isIterable(el)) {
eLen = el.length;
insertEl = Ext.fly(document.createDocumentFragment());
if (Ext.isArray(el)) {
for (e = 0; e < eLen; e++) {
rt = insertEl.appendChild(el[e], returnDom);
}
} else
{
for (e = 0; e < eLen; e++) {
insertEl.dom.appendChild(rt = el[0]);
}
if (returnDom === false) {
rt = Ext.get(rt);
}
}
me.dom.parentNode.insertBefore(insertEl.dom, isAfter ? me.dom.nextSibling : me.dom);
return rt;
}
el = el || {};
if (el.nodeType || el.dom) {
rt = me.dom.parentNode.insertBefore(Ext.getDom(el), isAfter ? me.dom.nextSibling : me.dom);
if (!returnDom) {
rt = Ext.get(rt);
}
} else {
if (isAfter && !me.dom.nextSibling) {
rt = DomHelper.append(me.dom.parentNode, el, !returnDom);
} else {
rt = DomHelper[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom);
}
}
return rt;
},
is: function(selector) {
var dom = this.dom,
is;
if (!selector) {
is = true;
} else if (!dom.tagName) {
is = false;
} else if (Ext.isFunction(selector)) {
is = selector(dom);
} else {
is = dom[Ext.supports.matchesSelector](selector);
}
return is;
},
isAncestor: function(el) {
var ret = false,
dom = this.dom,
child = Ext.getDom(el);
if (dom && child) {
if (dom.contains) {
return dom.contains(child);
} else if (dom.compareDocumentPosition) {
return !!(dom.compareDocumentPosition(child) & 16);
} else {
while ((child = child.parentNode)) {
ret = child === dom || ret;
}
}
}
return ret;
},
isPainted: (function() {
return !Ext.browser.is.IE ? function() {
var dom = this.dom;
return Boolean(dom && dom.offsetParent);
} : function() {
var dom = this.dom;
return Boolean(dom && (dom.offsetHeight !== 0 && dom.offsetWidth !== 0));
};
})(),
isStyle: function(style, val) {
return this.getStyle(style) === val;
},
isVisible: function(deep) {
var dom = this.dom,
end;
if (!dom) {
return false;
}
if (!visFly) {
visFly = new Ext.dom.Fly();
}
for (end = dom.ownerDocument.documentElement; dom !== end; dom = dom.parentNode) {
if (!dom || dom.nodeType === 11 || (visFly.attach(dom)).isStyle(VISIBILITY, HIDDEN) || visFly.isStyle(DISPLAY, NONE)) {
return false;
}
if (!deep) {
break;
}
}
return true;
},
last: function(selector, returnDom) {
return this.matchNode('previousSibling', 'lastChild', selector, returnDom);
},
matchNode: function(dir, start, selector, returnDom) {
var dom = this.dom,
n;
if (!dom) {
return null;
}
n = dom[start];
while (n) {
if (n.nodeType === 1 && (!selector || Ext.fly(n, '_matchNode').is(selector))) {
return !returnDom ? Ext.get(n) : n;
}
n = n[dir];
}
return null;
},
next: function(selector, returnDom) {
return this.matchNode('nextSibling', 'nextSibling', selector, returnDom);
},
parent: function(selector, returnDom) {
return this.matchNode('parentNode', 'parentNode', selector, returnDom);
},
position: function(pos, zIndex, x, y) {
var me = this;
if (me.dom.tagName !== 'BODY') {
if (!pos && me.isStyle(POSITION, STATIC)) {
me.setStyle(POSITION, RELATIVE);
} else if (pos) {
me.setStyle(POSITION, pos);
}
if (zIndex) {
me.setStyle(ZINDEX, zIndex);
}
if (x || y) {
me.setXY([
x || false,
y || false
]);
}
}
},
prev: function(selector, returnDom) {
return this.matchNode('previousSibling', 'previousSibling', selector, returnDom);
},
query: function(selector, asDom,
single) {
var dom = this.dom,
results, len, nlen, node, nodes, i, j;
if (!dom) {
return null;
}
asDom = (asDom !== false);
selector = selector.split(",");
if (!single) {
results = [];
}
for (i = 0 , len = selector.length; i < len; i++) {
if (typeof selector[i] === 'string') {
if (single) {
node = dom.querySelector(selector[i]);
return asDom ? node : Ext.get(node);
}
nodes = dom.querySelectorAll(selector[i]);
for (j = 0 , nlen = nodes.length; j < nlen; j++) {
results.push(asDom ? nodes[j] : Ext.get(nodes[j]));
}
}
}
return results;
},
radioCls: function(className) {
var cn = this.dom.parentNode.childNodes,
v;
className = Ext.isArray(className) ? className : [
className
];
for (var i = 0,
len = cn.length; i < len; i++) {
v = cn[i];
if (v && v.nodeType === 1) {
Ext.fly(v).removeCls(className);
}
}
return this.addCls(className);
},
redraw: function() {
var dom = this.dom,
domStyle = dom.style;
domStyle.display = 'none';
dom.offsetHeight;
domStyle.display = '';
},
remove: function() {
this.destroy();
},
removeChild: function(element) {
this.dom.removeChild(Ext.getDom(element));
return this;
},
removeCls: function(names, prefix, suffix) {
var me = this,
elementData = me.getData(),
hasNewCls, dom, map, classList, i, ln, name;
if (!names) {
return me;
}
if (!elementData.isSynchronized) {
me.synchronize();
}
dom = me.dom;
map = elementData.classMap;
classList = elementData.classList;
prefix = prefix ? prefix + SEPARATOR : '';
suffix = suffix ? SEPARATOR + suffix : '';
if (typeof names === 'string') {
names = names.split(spacesRe);
}
for (i = 0 , ln = names.length; i < ln; i++) {
name = names[i];
if (name) {
name = prefix + name + suffix;
if (map[name]) {
delete map[name];
Ext.Array.remove(classList, name);
hasNewCls = true;
}
}
}
if (hasNewCls) {
dom.className = classList.join(' ');
}
return me;
},
repaint: function() {
var me = this;
me.addCls(Ext.baseCSSPrefix + 'repaint');
Ext.defer(function() {
if (me.dom) {
Ext.fly(me.dom).removeCls(Ext.baseCSSPrefix + 'repaint');
}
}, 1);
return me;
},
replace: function(el, destroy) {
el = Ext.getDom(el);
var parentNode = el.parentNode,
id = el.id,
dom = this.dom;
if (!parentNode) {
Ext.Error.raise('Cannot replace element "' + id + '". It is not attached to a parent node.');
}
if (destroy !== false && id && Ext.cache[id]) {
parentNode.insertBefore(dom, el);
Ext.get(el).destroy();
} else {
parentNode.replaceChild(dom, el);
}
return this;
},
replaceCls: function(oldName, newName, prefix, suffix) {
var me = this,
dom, map, classList, i, ln, name,
elementData = me.getData();
if (!oldName && !newName) {
return me;
}
oldName = oldName || [];
newName = newName || [];
if (!elementData.isSynchronized) {
me.synchronize();
}
if (!suffix) {
suffix = '';
}
dom = me.dom;
map = elementData.classMap;
classList = elementData.classList;
prefix = prefix ? prefix + SEPARATOR : '';
suffix = suffix ? SEPARATOR + suffix : '';
if (typeof oldName === 'string') {
oldName = oldName.split(spacesRe);
}
if (typeof newName === 'string') {
newName = newName.split(spacesRe);
}
for (i = 0 , ln = oldName.length; i < ln; i++) {
name = prefix + oldName[i] + suffix;
if (map[name]) {
delete map[name];
Ext.Array.remove(classList, name);
}
}
for (i = 0 , ln = newName.length; i < ln; i++) {
name = prefix + newName[i] + suffix;
if (!map[name]) {
map[name] = true;
classList.push(name);
}
}
dom.className = classList.join(' ');
return me;
},
replaceWith: function(el) {
var me = this,
dom = me.dom,
parent = dom.parentNode,
cache = Ext.cache,
newDom;
me.clearListeners();
if (el.nodeType || el.dom || typeof el === 'string') {
el = Ext.get(el);
newDom = parent.insertBefore(el.dom, dom);
} else {
newDom = Ext.DomHelper.insertBefore(dom, el);
}
parent.removeChild(dom);
me.dom = newDom;
if (!me.isFly) {
delete cache[me.id];
cache[me.id = Ext.id(newDom)] = me;
}
return me;
},
resolveListenerScope: function(defaultScope) {
var component = this.component;
return component ? component.resolveListenerScope(defaultScope) : this;
},
scroll: function(direction, distance, animate) {
if (!this.isScrollable()) {
return false;
}
direction = direction.charAt(0);
var me = this,
dom = me.dom,
side = direction === 'r' || direction === 'l' ? 'left' : 'top',
scrolled = false,
currentScroll, constrainedScroll;
if (direction === 'l' || direction === 't' || direction === 'u') {
distance = -distance;
}
if (side === 'left') {
currentScroll = dom.scrollLeft;
constrainedScroll = me.constrainScrollLeft(currentScroll + distance);
} else {
currentScroll = dom.scrollTop;
constrainedScroll = me.constrainScrollTop(currentScroll + distance);
}
if (constrainedScroll !== currentScroll) {
this.scrollTo(side, constrainedScroll, animate);
scrolled = true;
}
return scrolled;
},
scrollBy: function(deltaX, deltaY, animate) {
var me = this,
dom = me.dom;
if (deltaX.length) {
animate = deltaY;
deltaY = deltaX[1];
deltaX = deltaX[0];
} else if (typeof deltaX != 'number') {
animate = deltaY;
deltaY = deltaX.y;
deltaX = deltaX.x;
}
if (deltaX) {
me.scrollTo('left', me.constrainScrollLeft(dom.scrollLeft + deltaX), animate);
}
if (deltaY) {
me.scrollTo('top', me.constrainScrollTop(dom.scrollTop + deltaY), animate);
}
return me;
},
scrollChildIntoView: function(child, hscroll) {
Ext.fly(child).scrollIntoView(this, hscroll);
},
scrollIntoView: function(container, hscroll, animate, highlight) {
container = Ext.getDom(container) || Ext.getBody().dom;
return this.doScrollIntoView(container, hscroll, animate, highlight, 'getScrollLeft', 'scrollTo');
},
scrollTo: function(side, value, animate) {
var top = topRe.test(side),
me = this,
prop = top ? 'scrollTop' : 'scrollLeft',
dom = me.dom,
animCfg;
if (!animate || !me.anim) {
dom[prop] = value;
} else {
animCfg = {
to: {}
};
animCfg.to[prop] = value;
if (Ext.isObject(animate)) {
Ext.applyIf(animCfg, animate);
}
me.animate(animCfg);
}
return me;
},
select: function(selector, composite) {
var isElementArray, elements;
if (typeof selector === "string") {
elements = this.query(selector, !composite);
} else if (selector.length === undefined) {
Ext.Error.raise("Invalid selector specified: " + selector);
} else {
elements = selector;
isElementArray = true;
}
return composite ? new Ext.CompositeElement(elements, !isElementArray) : new Ext.CompositeElementLite(elements, true);
},
selectNode: function(selector, asDom) {
return this.query(selector, asDom, true);
},
set: function(attributes, useSet) {
var me = this,
dom = me.dom,
attribute, value;
for (attribute in attributes) {
if (attributes.hasOwnProperty(attribute)) {
value = attributes[attribute];
if (attribute === 'style') {
me.applyStyles(value);
} else if (attribute === 'cls') {
dom.className = value;
} else if (useSet !== false) {
if (value === undefined) {
dom.removeAttribute(attribute);
} else {
dom.setAttribute(attribute, value);
}
} else {
dom[attribute] = value;
}
}
}
return me;
},
setBottom: function(bottom) {
this.dom.style[BOTTOM] = Element.addUnits(bottom);
return this;
},
setBorder: function(border) {
var me = this,
domStyle = me.dom.style;
if (border || border === 0) {
border = me.self.unitizeBox((border === true) ? 1 : border);
domStyle.setProperty('border-width', border, 'important');
} else {
domStyle.removeProperty('border-top-width');
domStyle.removeProperty('border-right-width');
domStyle.removeProperty('border-bottom-width');
domStyle.removeProperty('border-left-width');
}
},
setCls: function(className) {
var me = this,
elementData = me.getData(),
i, ln, name, map;
if (!elementData.isSynchronized) {
me.synchronize();
}
map = elementData.classMap;
if (typeof className === 'string') {
className = className.split(spacesRe);
}
for (i = 0 , ln = className.length; i < ln; i++) {
name = className[i];
if (!map[name]) {
map[name] = true;
}
}
elementData.classList = className.slice();
me.dom.className = className.join(' ');
},
setHeight: function(height) {
var me = this;
me.dom.style[HEIGHT] = Element.addUnits(height);
if (me.shadow || me.shim) {
me.syncUnderlays();
}
return me;
},
setHtml: function(html) {
if (this.dom) {
this.dom.innerHTML = html;
}
},
setId: function(id) {
var me = this,
currentId = me.id,
cache = Ext.cache;
if (currentId) {
delete cache[currentId];
}
me.dom.id = id;
me.id = id;
cache[id] = me;
return me;
},
setLeft: function(left) {
var me = this;
me.dom.style[LEFT] = Element.addUnits(left);
if (me.shadow || me.shim) {
me.syncUnderlays();
}
return me;
},
setLocalX: function(x) {
var me = this,
style = me.dom.style;
style.right = 'auto';
style.left = (x === null) ? 'auto' : x + 'px';
if (me.shadow || me.shim) {
me.syncUnderlays();
}
return me;
},
setLocalXY: function(x, y) {
var me = this,
style = me.dom.style;
style.right = 'auto';
if (x && x.length) {
y = x[1];
x = x[0];
}
if (x === null) {
style.left = 'auto';
} else if (x !== undefined) {
style.left = x + 'px';
}
if (y === null) {
style.top = 'auto';
} else if (y !== undefined) {
style.top = y + 'px';
}
if (me.shadow || me.shim) {
me.syncUnderlays();
}
return me;
},
setLocalY: function(y) {
var me = this;
me.dom.style.top = (y === null) ? 'auto' : y + 'px';
if (me.shadow || me.shim) {
me.syncUnderlays();
}
return me;
},
setMargin: function(margin) {
var me = this,
domStyle = me.dom.style;
if (margin || margin === 0) {
margin = me.self.unitizeBox((margin === true) ? 5 : margin);
domStyle.setProperty('margin', margin, 'important');
} else {
domStyle.removeProperty('margin-top');
domStyle.removeProperty('margin-right');
domStyle.removeProperty('margin-bottom');
domStyle.removeProperty('margin-left');
}
},
setMaxHeight: function(height) {
this.dom.style[MAX_HEIGHT] = Element.addUnits(height);
return this;
},
setMaxWidth: function(width) {
this.dom.style[MAX_WIDTH] = Element.addUnits(width);
return this;
},
setMinHeight: function(height) {
this.dom.style[MIN_HEIGHT] = Element.addUnits(height);
return this;
},
setMinWidth: function(width) {
this.dom.style[MIN_WIDTH] = Element.addUnits(width);
return this;
},
setPadding: function(padding) {
var me = this,
domStyle = me.dom.style;
if (padding || padding === 0) {
padding = me.self.unitizeBox((padding === true) ? 5 : padding);
domStyle.setProperty('padding', padding, 'important');
} else {
domStyle.removeProperty('padding-top');
domStyle.removeProperty('padding-right');
domStyle.removeProperty('padding-bottom');
domStyle.removeProperty('padding-left');
}
},
setRight: function(right) {
this.dom.style[RIGHT] = Element.addUnits(right);
return this;
},
setScrollLeft: function(left) {
this.dom.scrollLeft = left;
return this;
},
setScrollTop: function(top) {
this.dom.scrollTop = top;
return this;
},
setSize: function(width, height) {
var me = this,
style = me.dom.style;
if (Ext.isObject(width)) {
height = width.height;
width = width.width;
}
style.width = Element.addUnits(width);
style.height = Element.addUnits(height);
if (me.shadow || me.shim) {
me.syncUnderlays();
}
return me;
},
setSizeState: function(state) {
var me = this,
add, remove;
if (state === true) {
add = sizedCls;
remove = [
unsizedCls,
stretchedCls
];
} else if (state === false) {
add = unsizedCls;
remove = [
sizedCls,
stretchedCls
];
} else if (state === null) {
add = stretchedCls;
remove = [
sizedCls,
unsizedCls
];
} else {
remove = [
sizedCls,
unsizedCls,
stretchedCls
];
}
if (add) {
me.addCls(add);
}
me.removeCls(remove);
return me;
},
setStyle: function(prop, value) {
var me = this,
dom = me.dom,
hooks = me.styleHooks,
style = dom.style,
name = prop,
hook;
if (typeof name === 'string') {
hook = hooks[name];
if (!hook) {
hooks[name] = hook = {
name: Element.normalize(name)
};
}
value = (value == null) ? '' : value;
if (hook.set) {
hook.set(dom, value, me);
} else {
style[hook.name] = value;
}
if (hook.afterSet) {
hook.afterSet(dom, value, me);
}
} else {
for (name in prop) {
if (prop.hasOwnProperty(name)) {
hook = hooks[name];
if (!hook) {
hooks[name] = hook = {
name: Element.normalize(name)
};
}
value = prop[name];
value = (value == null) ? '' : value;
if (hook.set) {
hook.set(dom, value, me);
} else {
style[hook.name] = value;
}
if (hook.afterSet) {
hook.afterSet(dom, value, me);
}
}
}
}
return me;
},
setText: function(text) {
this.dom.textContent = text;
},
setTop: function(top) {
var me = this;
me.dom.style[TOP] = Element.addUnits(top);
if (me.shadow || me.shim) {
me.syncUnderlays();
}
return me;
},
setUnderlaysVisible: function(visible) {
var shadow = this.shadow,
shim = this.shim;
if (shadow && !shadow.disabled) {
if (visible) {
shadow.show();
} else {
shadow.hide();
}
}
if (shim && !shim.disabled) {
if (visible) {
shim.show();
} else {
shim.hide();
}
}
},
setVisibility: function(isVisible) {
var domStyle = this.dom.style;
if (isVisible) {
domStyle.removeProperty('visibility');
} else {
domStyle.setProperty('visibility', 'hidden', 'important');
}
},
setVisibilityMode: function(mode) {
if (mode !== 1 && mode !== 2 && mode !== 3) {
Ext.Error.raise("visibilityMode must be one of the following: " + "Ext.Element.DISPLAY, Ext.Element.VISIBILITY, or Ext.Element.OFFSETS");
}
this.getData().visibilityMode = mode;
return this;
},
setVisible: function(visible) {
var me = this,
mode = me.getVisibilityMode(),
method = visible ? 'removeCls' : 'addCls';
switch (mode) {
case Element.DISPLAY:
me.removeCls([
visibilityCls,
offsetsCls
]);
me[method](displayCls);
break;
case Element.VISIBILITY:
me.removeCls([
displayCls,
offsetsCls
]);
me[method](visibilityCls);
break;
case Element.OFFSETS:
me.removeCls([
visibilityCls,
displayCls
]);
me[method](offsetsCls);
break;
}
if (me.shadow || me.shim) {
me.setUnderlaysVisible(visible);
}
return me;
},
setWidth: function(width) {
var me = this;
me.dom.style[WIDTH] = Element.addUnits(width);
if (me.shadow || me.shim) {
me.syncUnderlays();
}
return me;
},
setX: function(x) {
return this.setXY([
x,
false
]);
},
setXY: function(xy) {
var me = this,
pts = me.translatePoints(xy),
style = me.dom.style,
pos;
me.position();
style.right = 'auto';
for (pos in pts) {
if (!isNaN(pts[pos])) {
style[pos] = pts[pos] + 'px';
}
}
if (me.shadow || me.shim) {
me.syncUnderlays();
}
return me;
},
setY: function(y) {
return this.setXY([
false,
y
]);
},
setZIndex: function(zindex) {
var me = this;
if (me.shadow) {
me.shadow.setZIndex(zindex);
}
if (me.shim) {
me.shim.setZIndex(zindex);
}
return me.setStyle('z-index', zindex);
},
show: function() {
this.setVisible(true);
return this;
},
swapCls: function(firstClass, secondClass, flag, prefix) {
if (flag === undefined) {
flag = true;
}
var me = this,
addedClass = flag ? firstClass : secondClass,
removedClass = flag ? secondClass : firstClass;
if (removedClass) {
me.removeCls(prefix ? prefix + '-' + removedClass : removedClass);
}
if (addedClass) {
me.addCls(prefix ? prefix + '-' + addedClass : addedClass);
}
return me;
},
synchronize: function() {
var me = this,
dom = me.dom,
hasClassMap = {},
className = dom.className,
classList, i, ln, name,
elementData = me.getData();
if (className && className.length > 0) {
classList = dom.className.split(classNameSplitRegex);
for (i = 0 , ln = classList.length; i < ln; i++) {
name = classList[i];
hasClassMap[name] = true;
}
} else {
classList = [];
}
elementData.classList = classList;
elementData.classMap = hasClassMap;
elementData.isSynchronized = true;
return me;
},
syncUnderlays: function() {
var me = this,
shadow = me.shadow,
shim = me.shim,
dom = me.dom,
xy, x, y, w, h;
if (me.isVisible()) {
xy = me.getXY();
x = xy[0];
y = xy[1];
w = dom.offsetWidth;
h = dom.offsetHeight;
if (shadow && !shadow.hidden) {
shadow.realign(x, y, w, h);
}
if (shim && !shim.hidden) {
shim.realign(x, y, w, h);
}
}
},
toggleCls: function(className, force) {
if (typeof force !== 'boolean') {
force = !this.hasCls(className);
}
return (force) ? this.addCls(className) : this.removeCls(className);
},
toggle: function() {
this.setVisible(!this.isVisible());
return this;
},
translate: function() {
var transformStyleName = 'webkitTransform' in DOC.createElement('div').style ? 'webkitTransform' : 'transform';
return function(x, y, z) {
this.dom.style[transformStyleName] = 'translate3d(' + (x || 0) + 'px, ' + (y || 0) + 'px, ' + (z || 0) + 'px)';
};
}(),
unwrap: function() {
var dom = this.dom,
parentNode = dom.parentNode,
grandparentNode,
activeElement = Ext.fly(Ext.Element.getActiveElement()),
resumeFocus;
if (this.contains(activeElement)) {
Ext.GlobalEvents.suspendEvent('focus');
activeElement.suspendEvent('focus', 'blur');
resumeFocus = true;
}
if (parentNode) {
grandparentNode = parentNode.parentNode;
grandparentNode.insertBefore(dom, parentNode);
grandparentNode.removeChild(parentNode);
} else {
grandparentNode = document.createDocumentFragment();
grandparentNode.appendChild(dom);
}
if (resumeFocus) {
activeElement.focus();
Ext.GlobalEvents.resumeEvent('focus');
activeElement.resumeEvent('focus', 'blur');
}
return this;
},
up: function(simpleSelector, limit, returnDom) {
return this.findParentNode(simpleSelector, limit, !returnDom);
},
update: function(html) {
return this.setHtml(html);
},
wrap: function(config, returnDom, selector) {
var me = this,
dom = me.dom,
newEl = Ext.DomHelper.insertBefore(dom, config || {
tag: "div"
}, !returnDom),
target = newEl,
activeElement = Ext.fly(Ext.Element.getActiveElement()),
resumeFocus;
if (selector) {
target = newEl.selectNode(selector, returnDom);
}
if (me.contains(activeElement)) {
Ext.GlobalEvents.suspendEvent('focus');
activeElement.suspendEvent('focus', 'blur');
resumeFocus = true;
}
target.appendChild(dom);
if (resumeFocus) {
activeElement.focus();
activeElement.resumeEvent('focus', 'blur');
Ext.GlobalEvents.resumeEvent('focus');
}
return newEl;
},
privates: {
doAddListener: function(eventName, fn, scope, options, order, caller, manager) {
var me = this,
observableDoAddListener, additiveEventName, translatedEventName;
eventName = Ext.canonicalEventName(eventName);
if (!me.blockedEvents[eventName]) {
observableDoAddListener = me.mixins.observable.doAddListener;
options = options || {};
if (me.longpressEvents[eventName]) {
me.disableTouchContextMenu();
}
if (Element.useDelegatedEvents === false) {
options.delegated = options.delegated || false;
}
if (options.translate !== false) {
additiveEventName = me.additiveEvents[eventName];
if (additiveEventName) {
options.type = eventName;
eventName = additiveEventName;
observableDoAddListener.call(me, eventName, fn, scope, options, order, caller, manager);
}
translatedEventName = me.eventMap[eventName];
if (translatedEventName) {
options.type = options.type || eventName;
eventName = translatedEventName;
}
}
observableDoAddListener.call(me, eventName, fn, scope, options, order, caller, manager);
delete options.type;
}
},
doRemoveListener: function(eventName, fn, scope) {
var me = this,
observableDoRemoveListener, translatedEventName, additiveEventName, contextMenuListenerRemover;
if (!me.blockedEvents[eventName]) {
observableDoRemoveListener = me.mixins.observable.doRemoveListener;
if (me.longpressEvents[eventName]) {
contextMenuListenerRemover = this._contextMenuListenerRemover;
if (contextMenuListenerRemover) {
contextMenuListenerRemover.destroy();
}
}
additiveEventName = me.additiveEvents[eventName];
if (additiveEventName) {
eventName = additiveEventName;
observableDoRemoveListener.call(me, eventName, fn, scope);
}
translatedEventName = me.eventMap[eventName];
if (translatedEventName) {
observableDoRemoveListener.call(me, translatedEventName, fn, scope);
}
observableDoRemoveListener.call(me, eventName, fn, scope);
}
},
_initEvent: function(eventName) {
return (this.events[eventName] = new Ext.dom.ElementEvent(this, eventName));
},
_getPublisher: function(eventName) {
var Publisher = Ext.event.publisher.Publisher,
publisher = Publisher.publishersByEvent[eventName];
if (!publisher || (this.dom === window && eventName === 'resize')) {
publisher = Publisher.publishers.dom;
}
return publisher;
}
},
deprecated: {
'5.0': {
methods: {
cssTranslate: null,
getHTML: 'getHtml',
getOuterHeight: null,
getOuterWidth: null,
getPageBox: function(getRegion) {
var me = this,
dom = me.dom,
isDoc = dom.nodeName === 'BODY',
w = isDoc ? Element.getViewportWidth() : dom.offsetWidth,
h = isDoc ? Element.getViewportHeight() : dom.offsetHeight,
xy = me.getXY(),
t = xy[1],
r = xy[0] + w,
b = xy[1] + h,
l = xy[0];
if (getRegion) {
return new Ext.util.Region(t, r, b, l);
} else {
return {
left: l,
top: t,
width: w,
height: h,
right: r,
bottom: b
};
}
},
getScrollParent: null,
isDescendent: null,
isTransparent: function(prop) {
var value = this.getStyle(prop);
return value ? transparentRe.test(value) : false;
},
purgeAllListeners: 'clearListeners',
removeAllListeners: 'clearListeners',
setHTML: 'setHtml',
setTopLeft: null
}
}
}
};
}, function(Element) {
var DOC = document,
prototype = Element.prototype,
supports = Ext.supports,
pointerdown = 'pointerdown',
pointermove = 'pointermove',
pointerup = 'pointerup',
pointercancel = 'pointercancel',
MSPointerDown = 'MSPointerDown',
MSPointerMove = 'MSPointerMove',
MSPointerUp = 'MSPointerUp',
MSPointerCancel = 'MSPointerCancel',
mousedown = 'mousedown',
mousemove = 'mousemove',
mouseup = 'mouseup',
mouseover = 'mouseover',
mouseout = 'mouseout',
mouseenter = 'mouseenter',
mouseleave = 'mouseleave',
touchstart = 'touchstart',
touchmove = 'touchmove',
touchend = 'touchend',
touchcancel = 'touchcancel',
click = 'click',
dblclick = 'dblclick',
tap = 'tap',
doubletap = 'doubletap',
eventMap = prototype.eventMap = {},
additiveEvents = prototype.additiveEvents = {},
oldId = Ext.id,
eventOptions;
Ext.id = function(obj, prefix) {
var el = Ext.getDom(obj, true),
sandboxPrefix, id;
if (!el) {
id = oldId(obj, prefix);
} else if (!(id = el.id)) {
id = oldId(null, prefix || Element.prototype.identifiablePrefix);
if (Ext.isSandboxed) {
sandboxPrefix = Ext.sandboxPrefix || (Ext.sandboxPrefix = Ext.sandboxName.toLowerCase() + '-');
id = sandboxPrefix + id;
}
el.id = id;
}
return id;
};
if (supports.PointerEvents) {
eventMap[mousedown] = pointerdown;
eventMap[mousemove] = pointermove;
eventMap[mouseup] = pointerup;
eventMap[touchstart] = pointerdown;
eventMap[touchmove] = pointermove;
eventMap[touchend] = pointerup;
eventMap[touchcancel] = pointercancel;
eventMap[click] = tap;
eventMap[dblclick] = doubletap;
eventMap[mouseover] = 'pointerover';
eventMap[mouseout] = 'pointerout';
eventMap[mouseenter] = 'pointerenter';
eventMap[mouseleave] = 'pointerleave';
} else if (supports.MSPointerEvents) {
eventMap[pointerdown] = MSPointerDown;
eventMap[pointermove] = MSPointerMove;
eventMap[pointerup] = MSPointerUp;
eventMap[pointercancel] = MSPointerCancel;
eventMap[mousedown] = MSPointerDown;
eventMap[mousemove] = MSPointerMove;
eventMap[mouseup] = MSPointerUp;
eventMap[touchstart] = MSPointerDown;
eventMap[touchmove] = MSPointerMove;
eventMap[touchend] = MSPointerUp;
eventMap[touchcancel] = MSPointerCancel;
eventMap[click] = tap;
eventMap[dblclick] = doubletap;
eventMap[mouseover] = 'MSPointerOver';
eventMap[mouseout] = 'MSPointerOut';
} else if (supports.TouchEvents) {
eventMap[pointerdown] = touchstart;
eventMap[pointermove] = touchmove;
eventMap[pointerup] = touchend;
eventMap[pointercancel] = touchcancel;
eventMap[mousedown] = touchstart;
eventMap[mousemove] = touchmove;
eventMap[mouseup] = touchend;
eventMap[click] = tap;
eventMap[dblclick] = doubletap;
if (Ext.isWebKit && Ext.os.is.Desktop) {
eventMap[touchstart] = mousedown;
eventMap[touchmove] = mousemove;
eventMap[touchend] = mouseup;
eventMap[touchcancel] = mouseup;
additiveEvents[mousedown] = mousedown;
additiveEvents[mousemove] = mousemove;
additiveEvents[mouseup] = mouseup;
additiveEvents[touchstart] = touchstart;
additiveEvents[touchmove] = touchmove;
additiveEvents[touchend] = touchend;
additiveEvents[touchcancel] = touchcancel;
additiveEvents[pointerdown] = mousedown;
additiveEvents[pointermove] = mousemove;
additiveEvents[pointerup] = mouseup;
additiveEvents[pointercancel] = mouseup;
}
} else {
eventMap[pointerdown] = mousedown;
eventMap[pointermove] = mousemove;
eventMap[pointerup] = mouseup;
eventMap[pointercancel] = mouseup;
eventMap[touchstart] = mousedown;
eventMap[touchmove] = mousemove;
eventMap[touchend] = mouseup;
eventMap[touchcancel] = mouseup;
}
if (Ext.isWebKit) {
eventMap.transitionend = Ext.browser.getVendorProperyName('transitionEnd');
eventMap.animationstart = Ext.browser.getVendorProperyName('animationStart');
eventMap.animationend = Ext.browser.getVendorProperyName('animationEnd');
}
if (!Ext.supports.MouseWheel && !Ext.isOpera) {
eventMap.mousewheel = 'DOMMouseScroll';
}
eventOptions = prototype.$eventOptions = Ext.Object.chain(prototype.$eventOptions);
eventOptions.translate = eventOptions.capture = eventOptions.delegate = eventOptions.delegated = eventOptions.stopEvent = eventOptions.preventDefault = eventOptions.stopPropagation =
eventOptions.element = 1;
prototype.getTrueXY = prototype.getXY;
Ext.select = Element.select;
Ext.query = Element.query;
Ext.apply(Ext, {
get: function(element) {
return Element.get(element);
},
getDom: function(el) {
if (!el || !DOC) {
return null;
}
return el.dom || (typeof el === 'string' ? Ext.getElementById(el) : el);
},
getBody: function() {
if (!Ext._bodyEl) {
if (!DOC.body) {
throw new Error("[Ext.getBody] document.body does not yet exist");
}
Ext._bodyEl = Ext.get(DOC.body);
}
return Ext._bodyEl;
},
getHead: function() {
if (!Ext._headEl) {
Ext._headEl = Ext.get(DOC.head || DOC.getElementsByTagName('head')[0]);
}
return Ext._headEl;
},
getDoc: function() {
if (!Ext._docEl) {
Ext._docEl = Ext.get(DOC);
}
return Ext._docEl;
},
getWin: function() {
if (!Ext._winEl) {
Ext._winEl = Ext.get(window);
}
return Ext._winEl;
},
removeNode: function(node) {
node = node.dom || node;
var id = node && node.id,
el = Ext.cache[id],
parent;
if (el) {
el.destroy();
} else if (node && (node.nodeType === 3 || node.tagName.toUpperCase() !== 'BODY')) {
parent = node.parentNode;
if (parent) {
parent.removeChild(node);
}
}
}
});
Ext.isGarbage = function(dom) {
return dom &&
dom.nodeType === 1 && dom.tagName !== 'BODY' && dom.tagName !== 'HTML' &&
(!dom.parentNode ||
(!dom.offsetParent &&
((Ext.isIE8 ? DOC.all[dom.id] : DOC.getElementById(dom.id)) !== dom) &&
!(Ext.detachedBodyEl && Ext.detachedBodyEl.isAncestor(dom))));
};
});
Ext.define('Ext.util.Filter', {
isFilter: true,
config: {
property: null,
value: null,
filterFn: null,
id: null,
anyMatch: false,
exactMatch: false,
caseSensitive: false,
disabled: false,
disableOnEmpty: false,
operator: null,
root: null,
serializer: null,
convert: null
},
scope: null,
$configStrict: false,
statics: {
createFilterFn: function(filters) {
if (!filters) {
return Ext.returnTrue;
}
return function(candidate) {
var items = filters.isCollection ? filters.items : filters,
length = items.length,
match = true,
i, filter;
for (i = 0; match && i < length; i++) {
filter = items[i];
if (!filter.getDisabled()) {
match = filter.filter(candidate);
}
}
return match;
};
},
isInvalid: function(cfg) {
if (!cfg.filterFn) {
if (!cfg.property) {
return 'A Filter requires either a property or a filterFn to be set';
}
if (!cfg.hasOwnProperty('value') && !cfg.operator) {
return 'A Filter requires either a property and value, or a filterFn to be set';
}
}
return false;
}
},
constructor: function(config) {
var warn = Ext.util.Filter.isInvalid(config);
if (warn) {
Ext.log.warn(warn);
}
this.initConfig(config);
},
preventConvert: {
'in': 1
},
filter: function(item) {
var me = this,
filterFn = me._filterFn || me.getFilterFn(),
convert = me.getConvert(),
value = me._value;
me._filterValue = value;
me.isDateValue = Ext.isDate(value);
if (me.isDateValue) {
me.dateValue = value.getTime();
}
if (convert && !me.preventConvert[me.getOperator()]) {
me._filterValue = convert.call(me.scope || me, value);
}
return filterFn.call(me.scope || me, item);
},
getId: function() {
var id = this._id;
if (!id) {
id = this.getProperty();
if (!id) {
id = Ext.id(null, 'ext-filter-');
}
this._id = id;
}
return id;
},
getFilterFn: function() {
var me = this,
filterFn = me._filterFn,
operator;
if (!filterFn) {
operator = me.getOperator();
if (operator) {
filterFn = me.operatorFns[operator];
} else {
filterFn = me.createRegexFilter();
}
me._filterFn = filterFn;
}
return filterFn;
},
createRegexFilter: function() {
var me = this,
anyMatch = !!me.getAnyMatch(),
exact = !!me.getExactMatch(),
value = me.getValue(),
matcher = Ext.String.createRegex(value, !anyMatch,
!anyMatch && exact,
!me.getCaseSensitive());
return function(item) {
var val = me.getPropertyValue(item);
return matcher ? matcher.test(val) : (val == null);
};
},
getPropertyValue: function(item) {
var root = this._root,
value = (root == null) ? item : item[root];
return value[this._property];
},
getState: function() {
var config = this.getInitialConfig(),
result = {},
name;
for (name in config) {
if (config.hasOwnProperty(name)) {
result[name] = config[name];
}
}
delete result.root;
result.value = this.getValue();
return result;
},
getScope: function() {
return this.scope;
},
serialize: function() {
var result = this.getState(),
serializer = this.getSerializer();
delete result.id;
delete result.serializer;
if (serializer) {
serializer.call(this, result);
}
return result;
},
updateOperator: function() {
this._filterFn = null;
},
updateValue: function(value) {
this._filterFn = null;
if (this.getDisableOnEmpty()) {
this.setDisabled(Ext.isEmpty(value));
}
},
updateDisableOnEmpty: function(disableOnEmpty) {
var disabled = false;
if (disableOnEmpty) {
disabled = Ext.isEmpty(this.getValue());
}
this.setDisabled(disabled);
},
privates: {
getCandidateValue: function(candidate, v, preventCoerce) {
var me = this,
convert = me._convert,
result = me.getPropertyValue(candidate);
if (convert) {
result = convert.call(me.scope || me, result);
} else if (!preventCoerce) {
result = Ext.coerce(result, v);
}
return result;
}
}
}, function() {
var prototype = this.prototype,
operatorFns = (prototype.operatorFns = {
"<": function(candidate) {
var v = this._filterValue;
return this.getCandidateValue(candidate, v) < v;
},
"<=": function(candidate) {
var v = this._filterValue;
return this.getCandidateValue(candidate, v) <= v;
},
"=": function(candidate) {
var me = this,
v = me._filterValue;
candidate = me.getCandidateValue(candidate, v);
if (me.isDateValue && candidate instanceof Date) {
candidate = candidate.getTime();
v = me.dateValue;
}
return candidate == v;
},
"===": function(candidate) {
var me = this,
v = me._filterValue;
candidate = me.getCandidateValue(candidate, v, true);
if (me.isDateValue && candidate instanceof Date) {
candidate = candidate.getTime();
v = me.dateValue;
}
return candidate === v;
},
">=": function(candidate) {
var v = this._filterValue;
return this.getCandidateValue(candidate, v) >= v;
},
">": function(candidate) {
var v = this._filterValue;
return this.getCandidateValue(candidate, v) > v;
},
"!=": function(candidate) {
var me = this,
v = me._filterValue;
candidate = me.getCandidateValue(candidate, v);
if (me.isDateValue && candidate instanceof Date) {
candidate = candidate.getTime();
v = me.dateValue;
}
return candidate != v;
},
"!==": function(candidate) {
var me = this,
v = me._filterValue;
candidate = me.getCandidateValue(candidate, v, true);
if (me.isDateValue && candidate instanceof Date) {
candidate = candidate.getTime();
v = me.dateValue;
}
return candidate !== v;
},
"in": function(candidate) {
var v = this._filterValue;
return Ext.Array.contains(v, this.getCandidateValue(candidate, v));
},
like: function(candidate) {
var v = this._filterValue;
return v && this.getCandidateValue(candidate, v).toLowerCase().indexOf(v.toLowerCase()) > -1;
}
});
operatorFns['=='] = operatorFns['='];
operatorFns.gt = operatorFns['>'];
operatorFns.ge = operatorFns['>='];
operatorFns.lt = operatorFns['<'];
operatorFns.le = operatorFns['<='];
operatorFns.eq = operatorFns['='];
operatorFns.ne = operatorFns['!='];
});
Ext.define('Ext.util.Observable', {
extend: 'Ext.mixin.Observable',
$applyConfigs: true
}, function(Observable) {
var Super = Ext.mixin.Observable;
Observable.releaseCapture = Super.releaseCapture;
Observable.capture = Super.capture;
Observable.captureArgs = Super.captureArgs;
Observable.observe = Observable.observeClass = Super.observe;
});
Ext.define('Ext.util.AbstractMixedCollection', {
requires: [
'Ext.util.Filter'
],
mixins: {
observable: 'Ext.util.Observable'
},
isMixedCollection: true,
generation: 0,
indexGeneration: 0,
constructor: function(allowFunctions, keyFn) {
var me = this;
if (arguments.length === 1 && Ext.isObject(allowFunctions)) {
me.initialConfig = allowFunctions;
Ext.apply(me, allowFunctions);
} else
{
me.allowFunctions = allowFunctions === true;
if (keyFn) {
me.getKey = keyFn;
}
me.initialConfig = {
allowFunctions: me.allowFunctions,
getKey: me.getKey
};
}
me.items = [];
me.map = {};
me.keys = [];
me.indexMap = {};
me.length = 0;
me.mixins.observable.constructor.call(me);
},
allowFunctions: false,
add: function(key, obj) {
var len = this.length,
out;
if (arguments.length === 1) {
out = this.insert(len, key);
} else {
out = this.insert(len, key, obj);
}
return out;
},
getKey: function(o) {
return o.id;
},
replace: function(key, o) {
var me = this,
old, index;
if (arguments.length == 1) {
o = arguments[0];
key = me.getKey(o);
}
old = me.map[key];
if (typeof key == 'undefined' || key === null || typeof old == 'undefined') {
return me.add(key, o);
}
me.generation++;
index = me.indexOfKey(key);
me.items[index] = o;
me.map[key] = o;
if (me.hasListeners.replace) {
me.fireEvent('replace', key, old, o);
}
return o;
},
updateKey: function(oldKey, newKey) {
var me = this,
map = me.map,
index = me.indexOfKey(oldKey),
indexMap = me.indexMap,
item;
if (index > -1) {
item = map[oldKey];
delete map[oldKey];
delete indexMap[oldKey];
map[newKey] = item;
indexMap[newKey] = index;
me.keys[index] = newKey;
me.indexGeneration = ++me.generation;
}
},
addAll: function(objs) {
var me = this,
key;
if (arguments.length > 1 || Ext.isArray(objs)) {
me.insert(me.length, arguments.length > 1 ? arguments : objs);
} else {
for (key in objs) {
if (objs.hasOwnProperty(key)) {
if (me.allowFunctions || typeof objs[key] != 'function') {
me.add(key, objs[key]);
}
}
}
}
},
each: function(fn, scope) {
var items = Ext.Array.push([], this.items),
i = 0,
len = items.length,
item;
for (; i < len; i++) {
item = items[i];
if (fn.call(scope || item, item, i, len) === false) {
break;
}
}
},
eachKey: function(fn, scope) {
var keys = this.keys,
items = this.items,
i = 0,
len = keys.length;
for (; i < len; i++) {
fn.call(scope || window, keys[i], items[i], i, len);
}
},
findBy: function(fn, scope) {
var keys = this.keys,
items = this.items,
i = 0,
len = items.length;
for (; i < len; i++) {
if (fn.call(scope || window, items[i], keys[i])) {
return items[i];
}
}
return null;
},
find: function() {
if (Ext.isDefined(Ext.global.console)) {
Ext.global.console.warn('Ext.util.MixedCollection: find has been deprecated. Use findBy instead.');
}
return this.findBy.apply(this, arguments);
},
insert: function(index, key, obj) {
var out;
if (Ext.isIterable(key)) {
out = this.doInsert(index, key, obj);
} else {
if (arguments.length > 2) {
out = this.doInsert(index, [
key
], [
obj
]);
} else {
out = this.doInsert(index, [
key
]);
}
out = out[0];
}
return out;
},
doInsert: function(index, keys, objects) {
var me = this,
itemKey, removeIndex, i,
len = keys.length,
deDupedLen = len,
fireAdd = me.hasListeners.add,
syncIndices,
newKeys = {},
passedDuplicates, oldKeys, oldObjects;
if (objects != null) {
me.useLinearSearch = true;
} else
{
objects = keys;
keys = new Array(len);
for (i = 0; i < len; i++) {
keys[i] = this.getKey(objects[i]);
}
}
me.suspendEvents();
for (i = 0; i < len; i++) {
itemKey = keys[i];
removeIndex = me.indexOfKey(itemKey);
if (removeIndex !== -1) {
if (removeIndex < index) {
index--;
}
me.removeAt(removeIndex);
}
if (itemKey != null) {
if (newKeys[itemKey] != null) {
passedDuplicates = true;
deDupedLen--;
}
newKeys[itemKey] = i;
}
}
me.resumeEvents();
if (passedDuplicates) {
oldKeys = keys;
oldObjects = objects;
keys = new Array(deDupedLen);
objects = new Array(deDupedLen);
i = 0;
for (itemKey in newKeys) {
keys[i] = oldKeys[newKeys[itemKey]];
objects[i] = oldObjects[newKeys[itemKey]];
i++;
}
len = deDupedLen;
}
syncIndices = index === me.length && me.indexGeneration === me.generation;
Ext.Array.insert(me.items, index, objects);
Ext.Array.insert(me.keys, index, keys);
me.length += len;
me.generation++;
if (syncIndices) {
me.indexGeneration = me.generation;
}
for (i = 0; i < len; i++ , index++) {
itemKey = keys[i];
if (itemKey != null) {
me.map[itemKey] = objects[i];
if (syncIndices) {
me.indexMap[itemKey] = index;
}
}
if (fireAdd) {
me.fireEvent('add', index, objects[i], itemKey);
}
}
return objects;
},
remove: function(o) {
var me = this,
removeKey, index;
if (!me.useLinearSearch && (removeKey = me.getKey(o))) {
index = me.indexOfKey(removeKey);
} else
{
index = Ext.Array.indexOf(me.items, o);
}
return (index === -1) ? false : me.removeAt(index);
},
removeAll: function(items) {
var me = this,
i;
if (items || me.hasListeners.remove) {
if (items) {
for (i = items.length - 1; i >= 0; --i) {
me.remove(items[i]);
}
} else {
while (me.length) {
me.removeAt(0);
}
}
} else {
me.length = me.items.length = me.keys.length = 0;
me.map = {};
me.indexMap = {};
me.generation++;
me.indexGeneration = me.generation;
}
},
removeAt: function(index) {
var me = this,
o, key;
if (index < me.length && index >= 0) {
me.length--;
o = me.items[index];
Ext.Array.erase(me.items, index, 1);
key = me.keys[index];
if (typeof key != 'undefined') {
delete me.map[key];
}
Ext.Array.erase(me.keys, index, 1);
if (me.hasListeners.remove) {
me.fireEvent('remove', o, key);
}
me.generation++;
return o;
}
return false;
},
removeRange: function(index, removeCount) {
var me = this,
o, key, i, limit, syncIndices, trimming;
if (index < me.length && index >= 0) {
if (!removeCount) {
removeCount = 1;
}
limit = Math.min(index + removeCount, me.length);
removeCount = limit - index;
trimming = limit === me.length;
syncIndices = trimming && me.indexGeneration === me.generation;
for (i = index; i < limit; i++) {
key = me.keys[i];
if (key != null) {
delete me.map[key];
if (syncIndices) {
delete me.indexMap[key];
}
}
}
o = me.items[i - 1];
me.length -= removeCount;
me.generation++;
if (syncIndices) {
me.indexGeneration = me.generation;
}
if (trimming) {
me.items.length = me.keys.length = me.length;
} else {
me.items.splice(index, removeCount);
me.keys.splice(index, removeCount);
}
return o;
}
return false;
},
removeAtKey: function(key) {
var me = this,
keys = me.keys,
i;
if (key == null) {
for (i = keys.length - 1; i >= 0; i--) {
if (keys[i] == null) {
me.removeAt(i);
}
}
} else
{
return me.removeAt(me.indexOfKey(key));
}
},
getCount: function() {
return this.length;
},
indexOf: function(o) {
var me = this,
key;
if (o != null) {
if (!me.useLinearSearch && (key = me.getKey(o))) {
return this.indexOfKey(key);
}
return Ext.Array.indexOf(me.items, o);
}
return -1;
},
indexOfKey: function(key) {
if (!this.map.hasOwnProperty(key)) {
return -1;
}
if (this.indexGeneration !== this.generation) {
this.rebuildIndexMap();
}
return this.indexMap[key];
},
rebuildIndexMap: function() {
var me = this,
indexMap = me.indexMap = {},
keys = me.keys,
len = keys.length,
i;
for (i = 0; i < len; i++) {
indexMap[keys[i]] = i;
}
me.indexGeneration = me.generation;
},
get: function(key) {
var me = this,
mk = me.map[key],
item = mk !== undefined ? mk : (typeof key == 'number') ? me.items[key] : undefined;
return typeof item != 'function' || me.allowFunctions ? item : null;
},
getAt: function(index) {
return this.items[index];
},
getByKey: function(key) {
return this.map[key];
},
contains: function(o) {
var me = this,
key;
if (o != null) {
if (!me.useLinearSearch && (key = me.getKey(o))) {
return this.map[key] != null;
}
return Ext.Array.indexOf(this.items, o) !== -1;
}
return false;
},
containsKey: function(key) {
return this.map.hasOwnProperty(key);
},
clear: function() {
var me = this;
if (me.generation) {
me.length = 0;
me.items = [];
me.keys = [];
me.map = {};
me.indexMap = {};
me.generation++;
me.indexGeneration = me.generation;
}
if (me.hasListeners.clear) {
me.fireEvent('clear');
}
},
first: function() {
return this.items[0];
},
last: function() {
return this.items[this.length - 1];
},
sum: function(property, root, start, end) {
var values = this.extractValues(property, root),
length = values.length,
sum = 0,
i;
start = start || 0;
end = (end || end === 0) ? end : length - 1;
for (i = start; i <= end; i++) {
sum += values[i];
}
return sum;
},
collect: function(property, root, allowNull) {
var values = this.extractValues(property, root),
length = values.length,
hits = {},
unique = [],
value, strValue, i;
for (i = 0; i < length; i++) {
value = values[i];
strValue = String(value);
if ((allowNull || !Ext.isEmpty(value)) && !hits[strValue]) {
hits[strValue] = true;
unique.push(value);
}
}
return unique;
},
extractValues: function(property, root) {
var values = this.items;
if (root) {
values = Ext.Array.pluck(values, root);
}
return Ext.Array.pluck(values, property);
},
hasRange: function(start, end) {
return (end < this.length);
},
getRange: function(start, end) {
var me = this,
items = me.items,
range = [],
len = items.length,
tmp, reverse;
if (len < 1) {
return range;
}
if (start > end) {
reverse = true;
tmp = start;
start = end;
end = tmp;
}
if (start < 0) {
start = 0;
}
if (end == null || end >= len) {
end = len - 1;
}
range = items.slice(start, end + 1);
if (reverse && range.length) {
range.reverse();
}
return range;
},
filter: function(property, value, anyMatch, caseSensitive) {
var filters = [];
if (Ext.isString(property)) {
filters.push(new Ext.util.Filter({
property: property,
value: value,
anyMatch: anyMatch,
caseSensitive: caseSensitive
}));
} else if (Ext.isArray(property) || property instanceof Ext.util.Filter) {
filters = filters.concat(property);
}
return this.filterBy(Ext.util.Filter.createFilterFn(filters));
},
filterBy: function(fn, scope) {
var me = this,
newMC = new me.self(me.initialConfig),
keys = me.keys,
items = me.items,
length = items.length,
i;
newMC.getKey = me.getKey;
for (i = 0; i < length; i++) {
if (fn.call(scope || me, items[i], keys[i])) {
newMC.add(keys[i], items[i]);
}
}
newMC.useLinearSearch = me.useLinearSearch;
return newMC;
},
findIndex: function(property, value, start, anyMatch, caseSensitive) {
if (Ext.isEmpty(value, false)) {
return -1;
}
value = this.createValueMatcher(value, anyMatch, caseSensitive);
return this.findIndexBy(function(o) {
return o && value.test(o[property]);
}, null, start);
},
findIndexBy: function(fn, scope, start) {
var me = this,
keys = me.keys,
items = me.items,
i = start || 0,
len = items.length;
for (; i < len; i++) {
if (fn.call(scope || me, items[i], keys[i])) {
return i;
}
}
return -1;
},
createValueMatcher: function(value, anyMatch, caseSensitive, exactMatch) {
if (!value.exec) {
var er = Ext.String.escapeRegex;
value = String(value);
if (anyMatch === true) {
value = er(value);
} else {
value = '^' + er(value);
if (exactMatch === true) {
value += '$';
}
}
value = new RegExp(value, caseSensitive ? '' : 'i');
}
return value;
},
clone: function() {
var me = this,
copy = new me.self(me.initialConfig);
copy.add(me.keys, me.items);
copy.useLinearSearch = me.useLinearSearch;
return copy;
}
});
Ext.define('Ext.util.Sorter', {
isSorter: true,
config: {
property: null,
sorterFn: null,
root: null,
transform: null,
direction: "ASC",
id: undefined
},
statics: {
createComparator: function(sorters, nextFn) {
nextFn = nextFn || 0;
return function(lhs, rhs) {
var items = sorters.isCollection ? sorters.items : sorters,
n = items.length,
comp, i;
for (i = 0; i < n; ++i) {
comp = items[i].sort(lhs, rhs);
if (comp) {
return comp;
}
}
return nextFn && nextFn(lhs, rhs);
};
}
},
multiplier: 1,
constructor: function(config) {
if (config && !this.isGrouper) {
if (!config.property === !config.sorterFn) {
Ext.Error.raise("A Sorter requires either a property or a sorterFn.");
}
}
this.initConfig(config);
},
getId: function() {
var id = this._id;
if (!id) {
id = this.getProperty();
if (!id) {
id = Ext.id(null, 'ext-sorter-');
}
this._id = id;
}
return id;
},
sort: function(lhs, rhs) {
return this.multiplier * this.sortFn(lhs, rhs);
},
sortFn: function(item1, item2) {
var me = this,
transform = me._transform,
root = me._root,
property = me._property,
lhs, rhs;
if (root) {
item1 = item1[root];
item2 = item2[root];
}
lhs = item1[property];
rhs = item2[property];
if (transform) {
lhs = transform(lhs);
rhs = transform(rhs);
}
return (lhs > rhs) ? 1 : (lhs < rhs ? -1 : 0);
},
applyDirection: function(direction) {
return direction ? direction : 'ASC';
},
updateDirection: function(direction) {
this.multiplier = (direction.toUpperCase() === "DESC") ? -1 : 1;
},
updateProperty: function(property) {
if (property) {
delete this.sortFn;
}
},
updateSorterFn: function(sorterFn) {
this.sortFn = sorterFn;
},
toggle: function() {
this.setDirection(Ext.String.toggle(this.getDirection(), "ASC", "DESC"));
},
getState: function() {
return {
root: this.getRoot(),
property: this.getProperty(),
direction: this.getDirection()
};
},
serialize: function() {
return {
property: this.getProperty(),
direction: this.getDirection()
};
}
});
Ext.define("Ext.util.Sortable", {
isSortable: true,
$configPrefixed: false,
$configStrict: false,
config: {
sorters: null
},
defaultSortDirection: "ASC",
requires: [
'Ext.util.Sorter'
],
multiSortLimit: 3,
statics: {
createComparator: function(sorters) {
return sorters && sorters.length ? function(r1, r2) {
var result = sorters[0].sort(r1, r2),
length = sorters.length,
i = 1;
for (; !result && i < length; i++) {
result = sorters[i].sort.call(this, r1, r2);
}
return result;
} : function() {
return 0;
};
}
},
applySorters: function(sorters) {
var me = this,
sortersCollection = me.getSorters() || new Ext.util.MixedCollection(false, Ext.returnId);
if (sorters) {
sortersCollection.addAll(me.decodeSorters(sorters));
}
return sortersCollection;
},
sort: function(sorters, direction, insertionPosition, doSort) {
var me = this,
sorter, overFlow,
currentSorters = me.getSorters();
if (!currentSorters) {
me.setSorters(null);
currentSorters = me.getSorters();
}
if (Ext.isArray(sorters)) {
doSort = insertionPosition;
insertionPosition = direction;
} else if (Ext.isObject(sorters)) {
sorters = [
sorters
];
doSort = insertionPosition;
insertionPosition = direction;
} else if (Ext.isString(sorters)) {
sorter = currentSorters.get(sorters);
if (!sorter) {
sorter = {
property: sorters,
direction: direction
};
} else if (direction == null) {
sorter.toggle();
} else {
sorter.setDirection(direction);
}
sorters = [
sorter
];
}
if (sorters && sorters.length) {
sorters = me.decodeSorters(sorters);
switch (insertionPosition) {
case "multi":
currentSorters.insert(0, sorters[0]);
overFlow = currentSorters.getCount() - me.multiSortLimit;
if (overFlow > 0) {
currentSorters.removeRange(me.multiSortLimit, overFlow);
};
break;
case "prepend":
currentSorters.insert(0, sorters);
break;
case "append":
currentSorters.addAll(sorters);
break;
case undefined:
case null:
case "replace":
currentSorters.clear();
currentSorters.addAll(sorters);
break;
default:
Ext.Error.raise('Sorter insertion point must be "multi", "prepend", "append" or "replace"');
}
}
if (doSort !== false) {
me.fireEvent('beforesort', me, sorters);
me.onBeforeSort(sorters);
if (me.getSorterCount()) {
me.doSort(me.generateComparator());
}
}
return sorters;
},
getSorterCount: function() {
return this.getSorters().items.length;
},
generateComparator: function() {
var sorters = this.getSorters().getRange();
return sorters.length ? this.createComparator(sorters) : this.emptyComparator;
},
emptyComparator: function() {
return 0;
},
onBeforeSort: Ext.emptyFn,
decodeSorters: function(sorters) {
if (!Ext.isArray(sorters)) {
if (sorters === undefined) {
sorters = [];
} else {
sorters = [
sorters
];
}
}
var length = sorters.length,
Sorter = Ext.util.Sorter,
model = this.getModel ? this.getModel() : this.model,
field, config, i;
for (i = 0; i < length; i++) {
config = sorters[i];
if (!(config instanceof Sorter)) {
if (Ext.isString(config)) {
config = {
property: config
};
}
Ext.applyIf(config, {
root: this.sortRoot,
direction: "ASC"
});
if (config.fn) {
config.sorterFn = config.fn;
}
if (typeof config == 'function') {
config = {
sorterFn: config
};
}
if (model && !config.transform) {
field = model.getField(config.property);
config.transform = field && field.sortType !== Ext.identityFn ? field.sortType : undefined;
}
sorters[i] = new Ext.util.Sorter(config);
}
}
return sorters;
},
getFirstSorter: function() {
var sorters = this.getSorters().items,
len = sorters.length,
i = 0,
sorter;
for (; i < len; ++i) {
sorter = sorters[i];
if (!sorter.isGrouper) {
return sorter;
}
}
return null;
}
}, function() {
this.prototype.createComparator = this.createComparator;
});
Ext.define('Ext.util.MixedCollection', {
extend: 'Ext.util.AbstractMixedCollection',
mixins: {
sortable: 'Ext.util.Sortable'
},
constructor: function() {
this.initConfig();
this.callParent(arguments);
},
doSort: function(sorterFn) {
this.sortBy(sorterFn);
},
_sort: function(property, dir, fn) {
var me = this,
i, len,
dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1,
c = [],
keys = me.keys,
items = me.items,
o;
fn = fn || function(a, b) {
return a - b;
};
for (i = 0 , len = items.length; i < len; i++) {
c[c.length] = {
key: keys[i],
value: items[i],
index: i
};
}
Ext.Array.sort(c, function(a, b) {
return fn(a[property], b[property]) * dsc ||
(a.index < b.index ? -1 : 1);
});
for (i = 0 , len = c.length; i < len; i++) {
o = c[i];
items[i] = o.value;
keys[i] = o.key;
me.indexMap[o.key] = i;
}
me.generation++;
me.indexGeneration = me.generation;
me.fireEvent('sort', me);
},
sortBy: function(sorterFn) {
var me = this,
items = me.items,
item,
keys = me.keys,
key,
length = items.length,
i;
for (i = 0; i < length; i++) {
items[i].$extCollectionIndex = i;
}
Ext.Array.sort(items, function(a, b) {
return sorterFn(a, b) ||
(a.$extCollectionIndex < b.$extCollectionIndex ? -1 : 1);
});
for (i = 0; i < length; i++) {
item = items[i];
key = me.getKey(item);
keys[i] = key;
me.indexMap[key] = i;
delete items.$extCollectionIndex;
}
me.generation++;
me.indexGeneration = me.generation;
me.fireEvent('sort', me, items, keys);
},
findInsertionIndex: function(newItem, sorterFn) {
var me = this,
items = me.items,
start = 0,
end = items.length - 1,
middle, comparison;
if (!sorterFn) {
sorterFn = me.generateComparator();
}
while (start <= end) {
middle = (start + end) >> 1;
comparison = sorterFn(newItem, items[middle]);
if (comparison >= 0) {
start = middle + 1;
} else if (comparison < 0) {
end = middle - 1;
}
}
return start;
},
reorder: function(mapping) {
var me = this,
items = me.items,
index = 0,
length = items.length,
order = [],
remaining = [],
oldIndex;
me.suspendEvents();
for (oldIndex in mapping) {
order[mapping[oldIndex]] = items[oldIndex];
}
for (index = 0; index < length; index++) {
if (mapping[index] == undefined) {
remaining.push(items[index]);
}
}
for (index = 0; index < length; index++) {
if (order[index] == undefined) {
order[index] = remaining.shift();
}
}
me.clear();
me.addAll(order);
me.resumeEvents();
me.fireEvent('sort', me);
},
sortByKey: function(dir, fn) {
this._sort('key', dir, fn || function(a, b) {
var v1 = String(a).toUpperCase(),
v2 = String(b).toUpperCase();
return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
});
}
});
Ext.define('Ext.util.TaskRunner', {
interval: 10,
timerId: null,
constructor: function(interval) {
var me = this;
if (typeof interval == 'number') {
me.interval = interval;
} else if (interval) {
Ext.apply(me, interval);
}
me.tasks = [];
me.timerFn = Ext.Function.bind(me.onTick, me);
},
newTask: function(config) {
var task = new Ext.util.TaskRunner.Task(config);
task.manager = this;
return task;
},
start: function(task) {
var me = this,
now = Ext.Date.now();
if (!task.pending) {
me.tasks.push(task);
task.pending = true;
}
task.stopped = false;
task.taskStartTime = now;
task.taskRunTime = task.fireOnStart !== false ? 0 : task.taskStartTime;
task.taskRunCount = 0;
if (!me.firing) {
if (task.fireOnStart !== false) {
me.startTimer(0, now);
} else {
me.startTimer(task.interval, now);
}
}
return task;
},
stop: function(task) {
if (!task.stopped) {
task.stopped = true;
if (task.onStop) {
task.onStop.call(task.scope || task, task);
}
}
return task;
},
stopAll: function() {
Ext.each(this.tasks, this.stop, this);
},
firing: false,
nextExpires: 1.0E99,
onTick: function() {
var me = this,
tasks = me.tasks,
now = Ext.Date.now(),
nextExpires = 1.0E99,
len = tasks.length,
globalEvents = Ext.GlobalEvents,
expires, newTasks, i, task, rt, remove, fireIdleEvent;
me.timerId = null;
me.firing = true;
for (i = 0; i < len || i < (len = tasks.length); ++i) {
task = tasks[i];
if (!(remove = task.stopped)) {
expires = task.taskRunTime + task.interval;
if (expires <= now) {
rt = 1;
if (task.hasOwnProperty('fireIdleEvent')) {
fireIdleEvent = task.fireIdleEvent;
} else {
fireIdleEvent = me.fireIdleEvent;
}
try {
rt = task.run.apply(task.scope || task, task.args || [
++task.taskRunCount
]);
} catch (taskError) {
try {
Ext.log({
fn: task.run,
prefix: 'Error while running task',
stack: taskError.stack,
msg: taskError,
level: 'error'
});
if (task.onError) {
rt = task.onError.call(task.scope || task, task, taskError);
}
} catch (ignore) {}
}
task.taskRunTime = now;
if (rt === false || task.taskRunCount === task.repeat) {
me.stop(task);
remove = true;
} else {
remove = task.stopped;
expires = now + task.interval;
}
}
if (!remove && task.duration && task.duration <= (now - task.taskStartTime)) {
me.stop(task);
remove = true;
}
}
if (remove) {
task.pending = false;
if (!newTasks) {
newTasks = tasks.slice(0, i);
}
} else
{
if (newTasks) {
newTasks.push(task);
}
if (nextExpires > expires) {
nextExpires = expires;
}
}
}
if (newTasks) {
me.tasks = newTasks;
}
me.firing = false;
if (me.tasks.length) {
me.startTimer(nextExpires - now, Ext.Date.now());
}
if (fireIdleEvent !== false && globalEvents.hasListeners.idle) {
globalEvents.fireEvent('idle');
}
},
startTimer: function(timeout, now) {
var me = this,
expires = now + timeout,
timerId = me.timerId;
if (timerId && me.nextExpires - expires > me.interval) {
clearTimeout(timerId);
timerId = null;
}
if (!timerId) {
if (timeout < me.interval) {
timeout = me.interval;
}
me.timerId = Ext.defer(me.timerFn, timeout);
me.nextExpires = expires;
}
}
}, function() {
var me = this,
proto = me.prototype;
proto.destroy = proto.stopAll;
me.Task = new Ext.Class({
isTask: true,
stopped: true,
fireOnStart: false,
constructor: function(config) {
Ext.apply(this, config);
},
restart: function(interval) {
if (interval !== undefined) {
this.interval = interval;
}
this.manager.start(this);
},
start: function(interval) {
if (this.stopped) {
this.restart(interval);
}
},
stop: function() {
this.manager.stop(this);
}
});
proto = me.Task.prototype;
proto.destroy = proto.stop;
});
Ext.define('Ext.fx.target.Target', {
isAnimTarget: true,
constructor: function(target) {
this.target = target;
this.id = this.getId();
},
getId: function() {
return this.target.id;
},
remove: function() {
Ext.destroy(this.target);
}
});
Ext.define('Ext.fx.target.Element', {
extend: 'Ext.fx.target.Target',
type: 'element',
getElVal: function(el, attr, val) {
if (val === undefined) {
if (attr === 'x') {
val = el.getX();
} else if (attr === 'y') {
val = el.getY();
} else if (attr === 'scrollTop') {
val = el.getScroll().top;
} else if (attr === 'scrollLeft') {
val = el.getScroll().left;
} else if (attr === 'height') {
val = el.getHeight();
} else if (attr === 'width') {
val = el.getWidth();
} else {
val = el.getStyle(attr);
}
}
return val;
},
getAttr: function(attr, val) {
var el = this.target;
return [
[
el,
this.getElVal(el, attr, val)
]
];
},
setAttr: function(targetData) {
var ln = targetData.length,
attrs, attr, o, i, j, ln2;
for (i = 0; i < ln; i++) {
attrs = targetData[i].attrs;
for (attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
ln2 = attrs[attr].length;
for (j = 0; j < ln2; j++) {
o = attrs[attr][j];
this.setElVal(o[0], attr, o[1]);
}
}
}
}
},
setElVal: function(element, attr, value) {
if (attr === 'x') {
element.setX(value);
} else if (attr === 'y') {
element.setY(value);
} else if (attr === 'scrollTop') {
element.scrollTo('top', value);
} else if (attr === 'scrollLeft') {
element.scrollTo('left', value);
} else if (attr === 'width') {
element.setWidth(value);
} else if (attr === 'height') {
element.setHeight(value);
} else {
element.setStyle(attr, value);
}
}
});
Ext.define('Ext.fx.target.ElementCSS', {
extend: 'Ext.fx.target.Element',
setAttr: function(targetData, isFirstFrame) {
var cssArr = {
attrs: [],
duration: [],
easing: []
},
ln = targetData.length,
cleanerFn = function() {
this.setStyle(Ext.supports.CSS3Prefix + 'TransitionProperty', null);
this.setStyle(Ext.supports.CSS3Prefix + 'TransitionDuration', null);
this.setStyle(Ext.supports.CSS3Prefix + 'TransitionTimingFunction', null);
},
single = {
single: true
},
attributes, attrs, attr, easing, duration, o, i, j, ln2;
for (i = 0; i < ln; i++) {
attrs = targetData[i];
duration = attrs.duration;
easing = attrs.easing;
attrs = attrs.attrs;
for (attr in attrs) {
if (Ext.Array.indexOf(cssArr.attrs, attr) == -1) {
cssArr.attrs.push(attr.replace(/[A-Z]/g, function(v) {
return '-' + v.toLowerCase();
}));
cssArr.duration.push(duration + 'ms');
cssArr.easing.push(easing);
}
}
}
attributes = cssArr.attrs.join(',');
duration = cssArr.duration.join(',');
easing = cssArr.easing.join(', ');
for (i = 0; i < ln; i++) {
attrs = targetData[i].attrs;
for (attr in attrs) {
ln2 = attrs[attr].length;
for (j = 0; j < ln2; j++) {
o = attrs[attr][j];
o[0].setStyle(Ext.supports.CSS3Prefix + 'TransitionProperty', isFirstFrame ? '' : attributes);
o[0].setStyle(Ext.supports.CSS3Prefix + 'TransitionDuration', isFirstFrame ? '' : duration);
o[0].setStyle(Ext.supports.CSS3Prefix + 'TransitionTimingFunction', isFirstFrame ? '' : easing);
o[0].setStyle(attr, o[1]);
if (isFirstFrame) {
o = o[0].dom.offsetWidth;
} else {
o[0].on(Ext.supports.CSS3TransitionEnd, cleanerFn, o[0], single);
}
}
}
}
}
});
Ext.define('Ext.fx.target.CompositeElement', {
extend: 'Ext.fx.target.Element',
isComposite: true,
constructor: function(target) {
target.id = target.id || Ext.id(null, 'ext-composite-');
this.callParent([
target
]);
},
getAttr: function(attr, val) {
var out = [],
target = this.target,
elements = target.elements,
length = elements.length,
i, el;
for (i = 0; i < length; i++) {
el = elements[i];
if (el) {
el = target.getElement(el);
out.push([
el,
this.getElVal(el, attr, val)
]);
}
}
return out;
},
setAttr: function(targetData) {
var target = this.target,
ln = targetData.length,
elements = target.elements,
ln3 = elements.length,
value, k, attrs, attr, el, i, j, ln2;
for (i = 0; i < ln; i++) {
attrs = targetData[i].attrs;
for (attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
ln2 = attrs[attr].length;
for (j = 0; j < ln2; j++) {
value = attrs[attr][j][1];
for (k = 0; k < ln3; ++k) {
el = elements[k];
if (el) {
el = target.getElement(el);
this.setElVal(el, attr, value);
}
}
}
}
}
}
},
remove: function() {
this.target.destroy();
}
});
Ext.define('Ext.fx.target.CompositeElementCSS', {
extend: 'Ext.fx.target.CompositeElement',
requires: [
'Ext.fx.target.ElementCSS'
],
setAttr: function() {
return Ext.fx.target.ElementCSS.prototype.setAttr.apply(this, arguments);
}
});
Ext.define('Ext.fx.target.Sprite', {
extend: 'Ext.fx.target.Target',
type: 'draw',
getFromPrim: function(sprite, attr) {
var obj;
switch (attr) {
case 'rotate':
case 'rotation':
obj = sprite.attr.rotation;
return {
x: obj.x || 0,
y: obj.y || 0,
degrees: obj.degrees || 0
};
case 'scale':
case 'scaling':
obj = sprite.attr.scaling;
return {
x: obj.x || 1,
y: obj.y || 1,
cx: obj.cx || 0,
cy: obj.cy || 0
};
case 'translate':
case 'translation':
obj = sprite.attr.translation;
return {
x: obj.x || 0,
y: obj.y || 0
};
default:
return sprite.attr[attr];
}
},
getAttr: function(attr, val) {
return [
[
this.target,
val !== undefined ? val : this.getFromPrim(this.target, attr)
]
];
},
setAttr: function(targetData) {
var ln = targetData.length,
spriteArr = [],
attrsConf, attr, attrArr, attrs, sprite, idx, value, i, j, x, y, ln2;
for (i = 0; i < ln; i++) {
attrsConf = targetData[i].attrs;
for (attr in attrsConf) {
attrArr = attrsConf[attr];
ln2 = attrArr.length;
for (j = 0; j < ln2; j++) {
sprite = attrArr[j][0];
attrs = attrArr[j][1];
if (attr === 'translate' || attr === 'translation') {
value = {
x: attrs.x,
y: attrs.y
};
} else if (attr === 'rotate' || attr === 'rotation') {
x = attrs.x;
if (isNaN(x)) {
x = null;
}
y = attrs.y;
if (isNaN(y)) {
y = null;
}
value = {
degrees: attrs.degrees,
x: x,
y: y
};
} else if (attr === 'scale' || attr === 'scaling') {
x = attrs.x;
if (isNaN(x)) {
x = null;
}
y = attrs.y;
if (isNaN(y)) {
y = null;
}
value = {
x: x,
y: y,
cx: attrs.cx,
cy: attrs.cy
};
} else if (attr === 'width' || attr === 'height' || attr === 'x' || attr === 'y') {
value = parseFloat(attrs);
} else {
value = attrs;
}
idx = Ext.Array.indexOf(spriteArr, sprite);
if (idx === -1) {
spriteArr.push([
sprite,
{}
]);
idx = spriteArr.length - 1;
}
spriteArr[idx][1][attr] = value;
}
}
}
ln = spriteArr.length;
for (i = 0; i < ln; i++) {
spriteArr[i][0].setAttributes(spriteArr[i][1]);
}
this.target.redraw();
}
});
Ext.define('Ext.fx.target.CompositeSprite', {
extend: 'Ext.fx.target.Sprite',
getAttr: function(attr, val) {
var out = [],
sprites = [].concat(this.target.items),
length = sprites.length,
i, sprite;
for (i = 0; i < length; i++) {
sprite = sprites[i];
out.push([
sprite,
val !== undefined ? val : this.getFromPrim(sprite, attr)
]);
}
return out;
}
});
Ext.define('Ext.fx.target.Component', {
extend: 'Ext.fx.target.Target',
type: 'component',
getPropMethod: {
top: function() {
return this.getPosition(true)[1];
},
left: function() {
return this.getPosition(true)[0];
},
x: function() {
return this.getPosition()[0];
},
y: function() {
return this.getPosition()[1];
},
height: function() {
return this.getHeight();
},
width: function() {
return this.getWidth();
},
opacity: function() {
return this.el.getStyle('opacity');
}
},
setMethods: {
top: 'setPosition',
left: 'setPosition',
x: 'setPagePosition',
y: 'setPagePosition',
height: 'setSize',
width: 'setSize',
opacity: 'setOpacity'
},
getAttr: function(attr, val) {
return [
[
this.target,
val !== undefined ? val : this.getPropMethod[attr].call(this.target)
]
];
},
setAttr: function(targetData, isFirstFrame, isLastFrame) {
var me = this,
ln = targetData.length,
attrs, attr, o, i, j, targets, left, top, w, h,
methodsToCall = {},
methodProps;
for (i = 0; i < ln; i++) {
attrs = targetData[i].attrs;
for (attr in attrs) {
targets = attrs[attr].length;
for (j = 0; j < targets; j++) {
o = attrs[attr][j];
methodProps = methodsToCall[me.setMethods[attr]] || (methodsToCall[me.setMethods[attr]] = {});
methodProps.target = o[0];
methodProps[attr] = o[1];
}
}
if (methodsToCall.setPosition) {
o = methodsToCall.setPosition;
left = (o.left === undefined) ? undefined : parseFloat(o.left);
top = (o.top === undefined) ? undefined : parseFloat(o.top);
o.target.setPosition(left, top);
}
if (methodsToCall.setPagePosition) {
o = methodsToCall.setPagePosition;
o.target.setPagePosition(o.x, o.y);
}
if (methodsToCall.setSize) {
o = methodsToCall.setSize;
w = (o.width === undefined) ? o.target.getWidth() : parseFloat(o.width);
h = (o.height === undefined) ? o.target.getHeight() : parseFloat(o.height);
o.target.el.setSize(w, h);
if (isLastFrame || me.dynamic) {
Ext.GlobalEvents.on({
idle: Ext.Function.bind(o.target.setSize, o.target, [
w,
h
]),
single: true
});
}
}
if (methodsToCall.setOpacity) {
o = methodsToCall.setOpacity;
o.target.el.setStyle('opacity', o.opacity);
}
}
}
});
Ext.define('Ext.fx.Queue', {
requires: [
'Ext.util.HashMap'
],
constructor: function() {
this.targets = new Ext.util.HashMap();
this.fxQueue = {};
},
getFxDefaults: function(targetId) {
var target = this.targets.get(targetId);
if (target) {
return target.fxDefaults;
}
return {};
},
setFxDefaults: function(targetId, obj) {
var target = this.targets.get(targetId);
if (target) {
target.fxDefaults = Ext.apply(target.fxDefaults || {}, obj);
}
},
stopAnimation: function(targetId) {
var me = this,
queue = me.getFxQueue(targetId),
ln = queue.length;
while (ln) {
queue[ln - 1].end();
ln--;
}
},
getActiveAnimation: function(targetId) {
var queue = this.getFxQueue(targetId);
return (queue && !!queue.length) ? queue[0] : false;
},
hasFxBlock: function(targetId) {
var queue = this.getFxQueue(targetId);
return queue && queue[0] && queue[0].block;
},
getFxQueue: function(targetId) {
if (!targetId) {
return false;
}
var me = this,
queue = me.fxQueue[targetId],
target = me.targets.get(targetId);
if (!target) {
return false;
}
if (!queue) {
me.fxQueue[targetId] = [];
if (target.type !== 'element') {
target.target.on('destroy', function() {
me.fxQueue[targetId] = [];
});
}
}
return me.fxQueue[targetId];
},
queueFx: function(anim) {
var me = this,
target = anim.target,
queue, ln;
if (!target) {
return;
}
queue = me.getFxQueue(target.getId());
ln = queue.length;
if (ln) {
if (anim.concurrent) {
anim.paused = false;
} else {
queue[ln - 1].on('afteranimate', function() {
anim.paused = false;
});
}
} else {
anim.paused = false;
}
anim.on('afteranimate', function() {
Ext.Array.remove(queue, anim);
if (queue.length === 0) {
me.targets.remove(anim.target);
}
if (anim.remove) {
if (target.type === 'element') {
var el = Ext.get(target.id);
if (el) {
el.destroy();
}
}
}
}, me, {
single: true
});
queue.push(anim);
}
});
Ext.define('Ext.fx.Manager', {
singleton: true,
requires: [
'Ext.util.MixedCollection',
'Ext.util.TaskRunner',
'Ext.fx.target.Element',
'Ext.fx.target.ElementCSS',
'Ext.fx.target.CompositeElement',
'Ext.fx.target.CompositeElementCSS',
'Ext.fx.target.Sprite',
'Ext.fx.target.CompositeSprite',
'Ext.fx.target.Component'
],
mixins: {
queue: 'Ext.fx.Queue'
},
constructor: function() {
var me = this;
me.items = new Ext.util.MixedCollection();
me.targetArr = {};
me.mixins.queue.constructor.call(me);
me.taskRunner = new Ext.util.TaskRunner();
},
interval: 16,
forceJS: true,
createTarget: function(target) {
var me = this,
useCSS3 = !me.forceJS && Ext.supports.Transitions,
targetObj;
me.useCSS3 = useCSS3;
if (target) {
if (target.tagName || Ext.isString(target) || target.isFly) {
target = Ext.get(target);
targetObj = new Ext.fx.target['Element' + (useCSS3 ? 'CSS' : '')](target);
}
else if (target.dom) {
targetObj = new Ext.fx.target['Element' + (useCSS3 ? 'CSS' : '')](target);
}
else if (target.isComposite) {
targetObj = new Ext.fx.target['CompositeElement' + (useCSS3 ? 'CSS' : '')](target);
}
else if (target.isSprite) {
targetObj = new Ext.fx.target.Sprite(target);
}
else if (target.isCompositeSprite) {
targetObj = new Ext.fx.target.CompositeSprite(target);
}
else if (target.isComponent) {
targetObj = new Ext.fx.target.Component(target);
} else if (target.isAnimTarget) {
return target;
} else {
return null;
}
me.targets.add(targetObj);
return targetObj;
} else {
return null;
}
},
addAnim: function(anim) {
var me = this,
items = me.items,
task = me.task;
items.add(anim.id, anim);
if (!task && items.length) {
task = me.task = {
run: me.runner,
interval: me.interval,
scope: me
};
me.taskRunner.start(task);
}
},
removeAnim: function(anim) {
var me = this,
items = me.items,
task = me.task;
items.removeAtKey(anim.id);
if (task && !items.length) {
me.taskRunner.stop(task);
delete me.task;
}
},
runner: function() {
var me = this,
items = me.items.getRange(),
i = 0,
len = items.length,
anim;
me.targetArr = {};
me.timestamp = new Date();
for (; i < len; i++) {
anim = items[i];
if (anim.isReady()) {
me.startAnim(anim);
}
}
for (i = 0; i < len; i++) {
anim = items[i];
if (anim.isRunning()) {
me.runAnim(anim);
}
}
me.applyPendingAttrs();
},
startAnim: function(anim) {
anim.start(this.timestamp);
},
runAnim: function(anim, forceEnd) {
if (!anim) {
return;
}
var me = this,
useCSS3 = me.useCSS3 && anim.target.type === 'element',
elapsedTime = me.timestamp - anim.startTime,
lastFrame = (elapsedTime >= anim.duration),
target, o;
if (forceEnd) {
elapsedTime = anim.duration;
lastFrame = true;
}
target = this.collectTargetData(anim, elapsedTime, useCSS3, lastFrame);
if (useCSS3) {
anim.target.setAttr(target.anims[anim.id].attributes, true);
me.collectTargetData(anim, anim.duration, useCSS3, lastFrame);
anim.paused = true;
target = anim.target.target;
if (anim.target.isComposite) {
target = anim.target.target.last();
}
o = {};
o[Ext.supports.CSS3TransitionEnd] = anim.lastFrame;
o.scope = anim;
o.single = true;
target.on(o);
}
return target;
},
jumpToEnd: function(anim) {
var target = this.runAnim(anim, true);
this.applyAnimAttrs(target, target.anims[anim.id]);
},
collectTargetData: function(anim, elapsedTime, useCSS3, isLastFrame) {
var targetId = anim.target.getId(),
target = this.targetArr[targetId];
if (!target) {
target = this.targetArr[targetId] = {
id: targetId,
el: anim.target,
anims: {}
};
}
target.anims[anim.id] = {
id: anim.id,
anim: anim,
elapsed: elapsedTime,
isLastFrame: isLastFrame,
attributes: [
{
duration: anim.duration,
easing: (useCSS3 && anim.reverse) ? anim.easingFn.reverse().toCSS3() : anim.easing,
attrs: anim.runAnim(elapsedTime)
}
]
};
return target;
},
applyAnimAttrs: function(target, animWrap) {
var anim = animWrap.anim;
if (animWrap.attributes && anim.isRunning()) {
target.el.setAttr(animWrap.attributes, false, animWrap.isLastFrame);
if (animWrap.isLastFrame) {
anim.lastFrame();
}
}
},
applyPendingAttrs: function() {
var targetArr = this.targetArr,
target, targetId, animWrap, anim, animId;
for (targetId in targetArr) {
if (targetArr.hasOwnProperty(targetId)) {
target = targetArr[targetId];
for (animId in target.anims) {
if (target.anims.hasOwnProperty(animId)) {
animWrap = target.anims[animId];
anim = animWrap.anim;
if (animWrap.attributes && anim.isRunning()) {
target.el.setAttr(animWrap.attributes, false, animWrap.isLastFrame);
if (animWrap.isLastFrame) {
anim.lastFrame();
}
}
}
}
}
}
}
});
Ext.define('Ext.fx.Animator', {
mixins: {
observable: 'Ext.util.Observable'
},
requires: [
'Ext.fx.Manager'
],
isAnimator: true,
duration: 250,
delay: 0,
delayStart: 0,
dynamic: false,
easing: 'ease',
running: false,
paused: false,
damper: 1,
iterations: 1,
currentIteration: 0,
keyframeStep: 0,
animKeyFramesRE: /^(from|to|\d+%?)$/,
constructor: function(config) {
var me = this;
config = Ext.apply(me, config || {});
me.config = config;
me.id = Ext.id(null, 'ext-animator-');
me.mixins.observable.constructor.call(me, config);
me.timeline = [];
me.createTimeline(me.keyframes);
if (me.target) {
me.applyAnimator(me.target);
Ext.fx.Manager.addAnim(me);
}
},
sorter: function(a, b) {
return a.pct - b.pct;
},
createTimeline: function(keyframes) {
var me = this,
attrs = [],
to = me.to || {},
duration = me.duration,
prevMs, ms, i, ln, pct, attr;
for (pct in keyframes) {
if (keyframes.hasOwnProperty(pct) && me.animKeyFramesRE.test(pct)) {
attr = {
attrs: Ext.apply(keyframes[pct], to)
};
if (pct === "from") {
pct = 0;
} else if (pct === "to") {
pct = 100;
}
attr.pct = parseInt(pct, 10);
attrs.push(attr);
}
}
Ext.Array.sort(attrs, me.sorter);
ln = attrs.length;
for (i = 0; i < ln; i++) {
prevMs = (attrs[i - 1]) ? duration * (attrs[i - 1].pct / 100) : 0;
ms = duration * (attrs[i].pct / 100);
me.timeline.push({
duration: ms - prevMs,
attrs: attrs[i].attrs
});
}
},
applyAnimator: function(target) {
var me = this,
anims = [],
timeline = me.timeline,
ln = timeline.length,
anim, easing, damper, attrs, i;
if (me.fireEvent('beforeanimate', me) !== false) {
for (i = 0; i < ln; i++) {
anim = timeline[i];
attrs = anim.attrs;
easing = attrs.easing || me.easing;
damper = attrs.damper || me.damper;
delete attrs.easing;
delete attrs.damper;
anim = new Ext.fx.Anim({
target: target,
easing: easing,
damper: damper,
duration: anim.duration,
paused: true,
to: attrs
});
anims.push(anim);
}
me.animations = anims;
me.target = anim.target;
for (i = 0; i < ln - 1; i++) {
anim = anims[i];
anim.nextAnim = anims[i + 1];
anim.on('afteranimate', function() {
this.nextAnim.paused = false;
});
anim.on('afteranimate', function() {
this.fireEvent('keyframe', this, ++this.keyframeStep);
}, me);
}
anims[ln - 1].on('afteranimate', function() {
this.lastFrame();
}, me);
}
},
start: function(startTime) {
var me = this,
delay = me.delay,
delayStart = me.delayStart,
delayDelta;
if (delay) {
if (!delayStart) {
me.delayStart = startTime;
return;
} else {
delayDelta = startTime - delayStart;
if (delayDelta < delay) {
return;
} else {
startTime = new Date(delayStart.getTime() + delay);
}
}
}
if (me.fireEvent('beforeanimate', me) !== false) {
me.startTime = startTime;
me.running = true;
me.animations[me.keyframeStep].paused = false;
}
},
lastFrame: function() {
var me = this,
iter = me.iterations,
iterCount = me.currentIteration;
iterCount++;
if (iterCount < iter) {
me.startTime = new Date();
me.currentIteration = iterCount;
me.keyframeStep = 0;
me.applyAnimator(me.target);
me.animations[me.keyframeStep].paused = false;
} else {
me.currentIteration = 0;
me.end();
}
},
end: function() {
var me = this;
me.fireEvent('afteranimate', me, me.startTime, new Date() - me.startTime);
},
isReady: function() {
return this.paused === false && this.running === false && this.iterations > 0;
},
isRunning: function() {
return false;
}
});
Ext.define('Ext.fx.CubicBezier', {
singleton: true,
cubicBezierAtTime: function(t, p1x, p1y, p2x, p2y, duration) {
var cx = 3 * p1x,
bx = 3 * (p2x - p1x) - cx,
ax = 1 - cx - bx,
cy = 3 * p1y,
by = 3 * (p2y - p1y) - cy,
ay = 1 - cy - by;
function sampleCurveX(t) {
return ((ax * t + bx) * t + cx) * t;
}
function solve(x, epsilon) {
var t = solveCurveX(x, epsilon);
return ((ay * t + by) * t + cy) * t;
}
function solveCurveX(x, epsilon) {
var t0, t1, t2, x2, d2, i;
for (t2 = x , i = 0; i < 8; i++) {
x2 = sampleCurveX(t2) - x;
if (Math.abs(x2) < epsilon) {
return t2;
}
d2 = (3 * ax * t2 + 2 * bx) * t2 + cx;
if (Math.abs(d2) < 1.0E-6) {
break;
}
t2 = t2 - x2 / d2;
}
t0 = 0;
t1 = 1;
t2 = x;
if (t2 < t0) {
return t0;
}
if (t2 > t1) {
return t1;
}
while (t0 < t1) {
x2 = sampleCurveX(t2);
if (Math.abs(x2 - x) < epsilon) {
return t2;
}
if (x > x2) {
t0 = t2;
} else {
t1 = t2;
}
t2 = (t1 - t0) / 2 + t0;
}
return t2;
}
return solve(t, 1 / (200 * duration));
},
cubicBezier: function(x1, y1, x2, y2) {
var fn = function(pos) {
return Ext.fx.CubicBezier.cubicBezierAtTime(pos, x1, y1, x2, y2, 1);
};
fn.toCSS3 = function() {
return 'cubic-bezier(' + [
x1,
y1,
x2,
y2
].join(',') + ')';
};
fn.reverse = function() {
return Ext.fx.CubicBezier.cubicBezier(1 - x2, 1 - y2, 1 - x1, 1 - y1);
};
return fn;
}
});
Ext.define('Ext.fx.Easing', function() {
var math = Math,
pi = math.PI,
pow = math.pow,
sin = math.sin,
sqrt = math.sqrt,
abs = math.abs,
backInSeed = 1.70158;
return {
requires: [
'Ext.fx.CubicBezier'
],
singleton: true,
linear: Ext.identityFn,
ease: function(n) {
var q = 0.07813 - n / 2,
Q = sqrt(0.0066 + q * q),
x = Q - q,
X = pow(abs(x), 1 / 3) * (x < 0 ? -1 : 1),
y = -Q - q,
Y = pow(abs(y), 1 / 3) * (y < 0 ? -1 : 1),
t = X + Y + 0.25;
return pow(1 - t, 2) * 3 * t * 0.1 + (1 - t) * 3 * t * t + t * t * t;
},
easeIn: function(n) {
return pow(n, 1.7);
},
easeOut: function(n) {
return pow(n, 0.48);
},
easeInOut: function(n) {
var q = 0.48 - n / 1.04,
Q = sqrt(0.1734 + q * q),
x = Q - q,
X = pow(abs(x), 1 / 3) * (x < 0 ? -1 : 1),
y = -Q - q,
Y = pow(abs(y), 1 / 3) * (y < 0 ? -1 : 1),
t = X + Y + 0.5;
return (1 - t) * 3 * t * t + t * t * t;
},
backIn: function(n) {
return n * n * ((backInSeed + 1) * n - backInSeed);
},
backOut: function(n) {
n = n - 1;
return n * n * ((backInSeed + 1) * n + backInSeed) + 1;
},
elasticIn: function(n) {
if (n === 0 || n === 1) {
return n;
}
var p = 0.3,
s = p / 4;
return pow(2, -10 * n) * sin((n - s) * (2 * pi) / p) + 1;
},
elasticOut: function(n) {
return 1 - Ext.fx.Easing.elasticIn(1 - n);
},
bounceIn: function(n) {
return 1 - Ext.fx.Easing.bounceOut(1 - n);
},
bounceOut: function(n) {
var s = 7.5625,
p = 2.75,
l;
if (n < (1 / p)) {
l = s * n * n;
} else {
if (n < (2 / p)) {
n -= (1.5 / p);
l = s * n * n + 0.75;
} else {
if (n < (2.5 / p)) {
n -= (2.25 / p);
l = s * n * n + 0.9375;
} else {
n -= (2.625 / p);
l = s * n * n + 0.984375;
}
}
}
return l;
}
};
}, function(me) {
var Easing = me.self,
proto = Easing.prototype;
Easing.addMembers({
'back-in': proto.backIn,
'back-out': proto.backOut,
'ease-in': proto.easeIn,
'ease-out': proto.easeOut,
'elastic-in': proto.elasticIn,
'elastic-out': proto.elasticOut,
'bounce-in': proto.bounceIn,
'bounce-out': proto.bounceOut,
'ease-in-out': proto.easeInOut
});
});
Ext.define('Ext.fx.DrawPath', {
singleton: true,
pathToStringRE: /,?([achlmqrstvxz]),?/gi,
pathCommandRE: /([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,
pathValuesRE: /(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig,
stopsRE: /^(\d+%?)$/,
radian: Math.PI / 180,
is: function(o, type) {
type = String(type).toLowerCase();
return (type == "object" && o === Object(o)) || (type == "undefined" && typeof o == type) || (type == "null" && o === null) || (type == "array" && Array.isArray && Array.isArray(o)) || (Object.prototype.toString.call(o).toLowerCase().slice(8, -1)) == type;
},
path2string: function() {
return this.join(",").replace(Ext.fx.DrawPath.pathToStringRE, "$1");
},
pathToString: function(arrayPath) {
return arrayPath.join(",").replace(Ext.fx.DrawPath.pathToStringRE, "$1");
},
parsePathString: function(pathString) {
if (!pathString) {
return null;
}
var paramCounts = {
a: 7,
c: 6,
h: 1,
l: 2,
m: 2,
q: 4,
s: 4,
t: 2,
v: 1,
z: 0
},
data = [],
me = this;
if (me.is(pathString, "array") && me.is(pathString[0], "array")) {
data = me.pathClone(pathString);
}
if (!data.length) {
String(pathString).replace(me.pathCommandRE, function(a, b, c) {
var params = [],
name = b.toLowerCase();
c.replace(me.pathValuesRE, function(a, b) {
if (b) {
params.push(+b);
}
});
if (name == "m" && params.length > 2) {
data.push([
b
].concat(Ext.Array.splice(params, 0, 2)));
name = "l";
b = (b == "m") ? "l" : "L";
}
while (params.length >= paramCounts[name]) {
data.push([
b
].concat(Ext.Array.splice(params, 0, paramCounts[name])));
if (!paramCounts[name]) {
break;
}
}
});
}
data.toString = me.path2string;
return data;
},
pathClone: function(pathArray) {
var res = [],
j, jj, i, ii;
if (!this.is(pathArray, "array") || !this.is(pathArray && pathArray[0], "array")) {
pathArray = this.parsePathString(pathArray);
}
for (i = 0 , ii = pathArray.length; i < ii; i++) {
res[i] = [];
for (j = 0 , jj = pathArray[i].length; j < jj; j++) {
res[i][j] = pathArray[i][j];
}
}
res.toString = this.path2string;
return res;
},
pathToAbsolute: function(pathArray) {
if (!this.is(pathArray, "array") || !this.is(pathArray && pathArray[0], "array")) {
pathArray = this.parsePathString(pathArray);
}
var res = [],
x = 0,
y = 0,
mx = 0,
my = 0,
i = 0,
ln = pathArray.length,
r, pathSegment, j, ln2;
if (ln && pathArray[0][0] == "M") {
x = +pathArray[0][1];
y = +pathArray[0][2];
mx = x;
my = y;
i++;
res[0] = [
"M",
x,
y
];
}
for (; i < ln; i++) {
r = res[i] = [];
pathSegment = pathArray[i];
if (pathSegment[0] != pathSegment[0].toUpperCase()) {
r[0] = pathSegment[0].toUpperCase();
switch (r[0]) {
case "A":
r[1] = pathSegment[1];
r[2] = pathSegment[2];
r[3] = pathSegment[3];
r[4] = pathSegment[4];
r[5] = pathSegment[5];
r[6] = +(pathSegment[6] + x);
r[7] = +(pathSegment[7] + y);
break;
case "V":
r[1] = +pathSegment[1] + y;
break;
case "H":
r[1] = +pathSegment[1] + x;
break;
case "M":
mx = +pathSegment[1] + x;
my = +pathSegment[2] + y;
default:
j = 1;
ln2 = pathSegment.length;
for (; j < ln2; j++) {
r[j] = +pathSegment[j] + ((j % 2) ? x : y);
};
}
} else {
j = 0;
ln2 = pathSegment.length;
for (; j < ln2; j++) {
res[i][j] = pathSegment[j];
}
}
switch (r[0]) {
case "Z":
x = mx;
y = my;
break;
case "H":
x = r[1];
break;
case "V":
y = r[1];
break;
case "M":
pathSegment = res[i];
ln2 = pathSegment.length;
mx = pathSegment[ln2 - 2];
my = pathSegment[ln2 - 1];
default:
pathSegment = res[i];
ln2 = pathSegment.length;
x = pathSegment[ln2 - 2];
y = pathSegment[ln2 - 1];
}
}
res.toString = this.path2string;
return res;
},
interpolatePaths: function(path, path2) {
var me = this,
p = me.pathToAbsolute(path),
p2 = me.pathToAbsolute(path2),
attrs = {
x: 0,
y: 0,
bx: 0,
by: 0,
X: 0,
Y: 0,
qx: null,
qy: null
},
attrs2 = {
x: 0,
y: 0,
bx: 0,
by: 0,
X: 0,
Y: 0,
qx: null,
qy: null
},
fixArc = function(pp, i) {
if (pp[i].length > 7) {
pp[i].shift();
var pi = pp[i];
while (pi.length) {
Ext.Array.splice(pp, i++, 0, [
"C"
].concat(Ext.Array.splice(pi, 0, 6)));
}
Ext.Array.erase(pp, i, 1);
ii = Math.max(p.length, p2.length || 0);
}
},
fixM = function(path1, path2, a1, a2, i) {
if (path1 && path2 && path1[i][0] == "M" && path2[i][0] != "M") {
Ext.Array.splice(path2, i, 0, [
"M",
a2.x,
a2.y
]);
a1.bx = 0;
a1.by = 0;
a1.x = path1[i][1];
a1.y = path1[i][2];
ii = Math.max(p.length, p2.length || 0);
}
},
i, ii, seg, seg2, seglen, seg2len;
for (i = 0 , ii = Math.max(p.length, p2.length || 0); i < ii; i++) {
p[i] = me.command2curve(p[i], attrs);
fixArc(p, i);
(p2[i] = me.command2curve(p2[i], attrs2));
fixArc(p2, i);
fixM(p, p2, attrs, attrs2, i);
fixM(p2, p, attrs2, attrs, i);
seg = p[i];
seg2 = p2[i];
seglen = seg.length;
seg2len = seg2.length;
attrs.x = seg[seglen - 2];
attrs.y = seg[seglen - 1];
attrs.bx = parseFloat(seg[seglen - 4]) || attrs.x;
attrs.by = parseFloat(seg[seglen - 3]) || attrs.y;
attrs2.bx = (parseFloat(seg2[seg2len - 4]) || attrs2.x);
attrs2.by = (parseFloat(seg2[seg2len - 3]) || attrs2.y);
attrs2.x = seg2[seg2len - 2];
attrs2.y = seg2[seg2len - 1];
}
return [
p,
p2
];
},
command2curve: function(pathCommand, d) {
var me = this;
if (!pathCommand) {
return [
"C",
d.x,
d.y,
d.x,
d.y,
d.x,
d.y
];
}
if (pathCommand[0] != "T" && pathCommand[0] != "Q") {
d.qx = d.qy = null;
}
switch (pathCommand[0]) {
case "M":
d.X = pathCommand[1];
d.Y = pathCommand[2];
break;
case "A":
pathCommand = [
"C"
].concat(me.arc2curve.apply(me, [
d.x,
d.y
].concat(pathCommand.slice(1))));
break;
case "S":
pathCommand = [
"C",
d.x + (d.x - (d.bx || d.x)),
d.y + (d.y - (d.by || d.y))
].concat(pathCommand.slice(1));
break;
case "T":
d.qx = d.x + (d.x - (d.qx || d.x));
d.qy = d.y + (d.y - (d.qy || d.y));
pathCommand = [
"C"
].concat(me.quadratic2curve(d.x, d.y, d.qx, d.qy, pathCommand[1], pathCommand[2]));
break;
case "Q":
d.qx = pathCommand[1];
d.qy = pathCommand[2];
pathCommand = [
"C"
].concat(me.quadratic2curve(d.x, d.y, pathCommand[1], pathCommand[2], pathCommand[3], pathCommand[4]));
break;
case "L":
pathCommand = [
"C"
].concat(d.x, d.y, pathCommand[1], pathCommand[2], pathCommand[1], pathCommand[2]);
break;
case "H":
pathCommand = [
"C"
].concat(d.x, d.y, pathCommand[1], d.y, pathCommand[1], d.y);
break;
case "V":
pathCommand = [
"C"
].concat(d.x, d.y, d.x, pathCommand[1], d.x, pathCommand[1]);
break;
case "Z":
pathCommand = [
"C"
].concat(d.x, d.y, d.X, d.Y, d.X, d.Y);
break;
}
return pathCommand;
},
quadratic2curve: function(x1, y1, ax, ay, x2, y2) {
var _13 = 1 / 3,
_23 = 2 / 3;
return [
_13 * x1 + _23 * ax,
_13 * y1 + _23 * ay,
_13 * x2 + _23 * ax,
_13 * y2 + _23 * ay,
x2,
y2
];
},
rotate: function(x, y, rad) {
var cos = Math.cos(rad),
sin = Math.sin(rad),
X = x * cos - y * sin,
Y = x * sin + y * cos;
return {
x: X,
y: Y
};
},
arc2curve: function(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) {
var me = this,
PI = Math.PI,
radian = me.radian,
_120 = PI * 120 / 180,
rad = radian * (+angle || 0),
res = [],
math = Math,
mcos = math.cos,
msin = math.sin,
msqrt = math.sqrt,
mabs = math.abs,
masin = math.asin,
xy, x, y, h, rx2, ry2, k, cx, cy, f1, f2, df, c1, s1, c2, s2, t, hx, hy, m1, m2, m3, m4, newres, i, ln, f2old, x2old, y2old;
if (!recursive) {
xy = me.rotate(x1, y1, -rad);
x1 = xy.x;
y1 = xy.y;
xy = me.rotate(x2, y2, -rad);
x2 = xy.x;
y2 = xy.y;
x = (x1 - x2) / 2;
y = (y1 - y2) / 2;
h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
if (h > 1) {
h = msqrt(h);
rx = h * rx;
ry = h * ry;
}
rx2 = rx * rx;
ry2 = ry * ry;
k = (large_arc_flag == sweep_flag ? -1 : 1) * msqrt(mabs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x)));
cx = k * rx * y / ry + (x1 + x2) / 2;
cy = k * -ry * x / rx + (y1 + y2) / 2;
f1 = masin(((y1 - cy) / ry).toFixed(7));
f2 = masin(((y2 - cy) / ry).toFixed(7));
f1 = x1 < cx ? PI - f1 : f1;
f2 = x2 < cx ? PI - f2 : f2;
if (f1 < 0) {
f1 = PI * 2 + f1;
}
if (f2 < 0) {
f2 = PI * 2 + f2;
}
if (sweep_flag && f1 > f2) {
f1 = f1 - PI * 2;
}
if (!sweep_flag && f2 > f1) {
f2 = f2 - PI * 2;
}
} else {
f1 = recursive[0];
f2 = recursive[1];
cx = recursive[2];
cy = recursive[3];
}
df = f2 - f1;
if (mabs(df) > _120) {
f2old = f2;
x2old = x2;
y2old = y2;
f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);
x2 = cx + rx * mcos(f2);
y2 = cy + ry * msin(f2);
res = me.arc2curve(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [
f2,
f2old,
cx,
cy
]);
}
df = f2 - f1;
c1 = mcos(f1);
s1 = msin(f1);
c2 = mcos(f2);
s2 = msin(f2);
t = math.tan(df / 4);
hx = 4 / 3 * rx * t;
hy = 4 / 3 * ry * t;
m1 = [
x1,
y1
];
m2 = [
x1 + hx * s1,
y1 - hy * c1
];
m3 = [
x2 + hx * s2,
y2 - hy * c2
];
m4 = [
x2,
y2
];
m2[0] = 2 * m1[0] - m2[0];
m2[1] = 2 * m1[1] - m2[1];
if (recursive) {
return [
m2,
m3,
m4
].concat(res);
} else {
res = [
m2,
m3,
m4
].concat(res).join().split(",");
newres = [];
ln = res.length;
for (i = 0; i < ln; i++) {
newres[i] = i % 2 ? me.rotate(res[i - 1], res[i], rad).y : me.rotate(res[i], res[i + 1], rad).x;
}
return newres;
}
}
});
Ext.define('Ext.fx.PropertyHandler', {
requires: [
'Ext.fx.DrawPath'
],
statics: {
defaultHandler: {
pixelDefaultsRE: /width|height|top$|bottom$|left$|right$/i,
unitRE: /^(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)*$/,
scrollRE: /^scroll/i,
computeDelta: function(from, end, damper, initial, attr) {
damper = (typeof damper == 'number') ? damper : 1;
var unitRE = this.unitRE,
match = unitRE.exec(from),
start, units;
if (match) {
from = match[1];
units = match[2];
if (!this.scrollRE.test(attr) && !units && this.pixelDefaultsRE.test(attr)) {
units = 'px';
}
}
from = +from || 0;
match = unitRE.exec(end);
if (match) {
end = match[1];
units = match[2] || units;
}
end = +end || 0;
start = (initial != null) ? initial : from;
return {
from: from,
delta: (end - start) * damper,
units: units
};
},
get: function(from, end, damper, initialFrom, attr) {
var ln = from.length,
out = [],
i, initial, res, j, len;
for (i = 0; i < ln; i++) {
if (initialFrom) {
initial = initialFrom[i][1].from;
}
if (Ext.isArray(from[i][1]) && Ext.isArray(end)) {
res = [];
j = 0;
len = from[i][1].length;
for (; j < len; j++) {
res.push(this.computeDelta(from[i][1][j], end[j], damper, initial, attr));
}
out.push([
from[i][0],
res
]);
} else {
out.push([
from[i][0],
this.computeDelta(from[i][1], end, damper, initial, attr)
]);
}
}
return out;
},
set: function(values, easing) {
var ln = values.length,
out = [],
i, val, res, len, j;
for (i = 0; i < ln; i++) {
val = values[i][1];
if (Ext.isArray(val)) {
res = [];
j = 0;
len = val.length;
for (; j < len; j++) {
res.push(val[j].from + val[j].delta * easing + (val[j].units || 0));
}
out.push([
values[i][0],
res
]);
} else {
out.push([
values[i][0],
val.from + val.delta * easing + (val.units || 0)
]);
}
}
return out;
}
},
stringHandler: {
computeDelta: function(from, end, damper, initial, attr) {
return {
from: from,
delta: end
};
},
get: function(from, end, damper, initialFrom, attr) {
var ln = from.length,
out = [],
i, initial;
for (i = 0; i < ln; i++) {
out.push([
from[i][0],
this.computeDelta(from[i][1], end, damper, initial, attr)
]);
}
return out;
},
set: function(values, easing) {
var ln = values.length,
out = [],
i, val;
for (i = 0; i < ln; i++) {
val = values[i][1];
out.push([
values[i][0],
val.delta
]);
}
return out;
}
},
color: {
rgbRE: /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i,
hexRE: /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i,
hex3RE: /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i,
parseColor: function(color, damper) {
damper = (typeof damper == 'number') ? damper : 1;
var out = false,
reList = [
this.hexRE,
this.rgbRE,
this.hex3RE
],
length = reList.length,
match, base, re, i;
for (i = 0; i < length; i++) {
re = reList[i];
base = (i % 2 === 0) ? 16 : 10;
match = re.exec(color);
if (match && match.length === 4) {
if (i === 2) {
match[1] += match[1];
match[2] += match[2];
match[3] += match[3];
}
out = {
red: parseInt(match[1], base),
green: parseInt(match[2], base),
blue: parseInt(match[3], base)
};
break;
}
}
return out || color;
},
computeDelta: function(from, end, damper, initial) {
from = this.parseColor(from);
end = this.parseColor(end, damper);
var start = initial ? initial : from,
tfrom = typeof start,
tend = typeof end;
if (tfrom === 'string' || tfrom === 'undefined' || tend === 'string' || tend === 'undefined') {
return end || start;
}
return {
from: from,
delta: {
red: Math.round((end.red - start.red) * damper),
green: Math.round((end.green - start.green) * damper),
blue: Math.round((end.blue - start.blue) * damper)
}
};
},
get: function(start, end, damper, initialFrom) {
var ln = start.length,
out = [],
i, initial;
for (i = 0; i < ln; i++) {
if (initialFrom) {
initial = initialFrom[i][1].from;
}
out.push([
start[i][0],
this.computeDelta(start[i][1], end, damper, initial)
]);
}
return out;
},
set: function(values, easing) {
var ln = values.length,
out = [],
i, val, parsedString, from, delta;
for (i = 0; i < ln; i++) {
val = values[i][1];
if (val) {
from = val.from;
delta = val.delta;
val = (typeof val === 'object' && 'red' in val) ? 'rgb(' + val.red + ', ' + val.green + ', ' + val.blue + ')' : val;
val = (typeof val === 'object' && val.length) ? val[0] : val;
if (typeof val === 'undefined') {
return [];
}
parsedString = typeof val === 'string' ? val : 'rgb(' + [
(from.red + Math.round(delta.red * easing)) % 256,
(from.green + Math.round(delta.green * easing)) % 256,
(from.blue + Math.round(delta.blue * easing)) % 256
].join(',') + ')';
out.push([
values[i][0],
parsedString
]);
}
}
return out;
}
},
object: {
interpolate: function(prop, damper) {
damper = (typeof damper === 'number') ? damper : 1;
var out = {},
p;
for (p in prop) {
out[p] = parseFloat(prop[p]) * damper;
}
return out;
},
computeDelta: function(from, end, damper, initial) {
from = this.interpolate(from);
end = this.interpolate(end, damper);
var start = initial ? initial : from,
delta = {},
p;
for (p in end) {
delta[p] = end[p] - start[p];
}
return {
from: from,
delta: delta
};
},
get: function(start, end, damper, initialFrom) {
var ln = start.length,
out = [],
i, initial;
for (i = 0; i < ln; i++) {
if (initialFrom) {
initial = initialFrom[i][1].from;
}
out.push([
start[i][0],
this.computeDelta(start[i][1], end, damper, initial)
]);
}
return out;
},
set: function(values, easing) {
var ln = values.length,
out = [],
outObject = {},
i, from, delta, val, p;
for (i = 0; i < ln; i++) {
val = values[i][1];
from = val.from;
delta = val.delta;
for (p in from) {
outObject[p] = from[p] + delta[p] * easing;
}
out.push([
values[i][0],
outObject
]);
}
return out;
}
},
path: {
computeDelta: function(from, end, damper, initial) {
damper = (typeof damper === 'number') ? damper : 1;
var start;
from = +from || 0;
end = +end || 0;
start = (initial != null) ? initial : from;
return {
from: from,
delta: (end - start) * damper
};
},
forcePath: function(path) {
if (!Ext.isArray(path) && !Ext.isArray(path[0])) {
path = Ext.fx.DrawPath.parsePathString(path);
}
return path;
},
get: function(start, end, damper, initialFrom) {
var endPath = this.forcePath(end),
out = [],
startLn = start.length,
startPathLn, pointsLn, i, deltaPath, initial, j, k, path, startPath;
for (i = 0; i < startLn; i++) {
startPath = this.forcePath(start[i][1]);
deltaPath = Ext.fx.DrawPath.interpolatePaths(startPath, endPath);
startPath = deltaPath[0];
endPath = deltaPath[1];
startPathLn = startPath.length;
path = [];
for (j = 0; j < startPathLn; j++) {
deltaPath = [
startPath[j][0]
];
pointsLn = startPath[j].length;
for (k = 1; k < pointsLn; k++) {
initial = initialFrom && initialFrom[0][1][j][k].from;
deltaPath.push(this.computeDelta(startPath[j][k], endPath[j][k], damper, initial));
}
path.push(deltaPath);
}
out.push([
start[i][0],
path
]);
}
return out;
},
set: function(values, easing) {
var ln = values.length,
out = [],
i, j, k, newPath, calcPath, deltaPath, deltaPathLn, pointsLn;
for (i = 0; i < ln; i++) {
deltaPath = values[i][1];
newPath = [];
deltaPathLn = deltaPath.length;
for (j = 0; j < deltaPathLn; j++) {
calcPath = [
deltaPath[j][0]
];
pointsLn = deltaPath[j].length;
for (k = 1; k < pointsLn; k++) {
calcPath.push(deltaPath[j][k].from + deltaPath[j][k].delta * easing);
}
newPath.push(calcPath.join(','));
}
out.push([
values[i][0],
newPath.join(',')
]);
}
return out;
}
}
}
},
function() {
var props = [
'outlineColor',
'backgroundColor',
'borderColor',
'borderTopColor',
'borderRightColor',
'borderBottomColor',
'borderLeftColor',
'fill',
'stroke'
],
length = props.length,
i = 0,
prop;
for (; i < length; i++) {
prop = props[i];
this[prop] = this.color;
}
props = [
'cursor'
];
length = props.length;
i = 0;
for (; i < length; i++) {
prop = props[i];
this[prop] = this.stringHandler;
}
});
Ext.define('Ext.fx.Anim', {
mixins: {
observable: 'Ext.util.Observable'
},
requires: [
'Ext.fx.Manager',
'Ext.fx.Animator',
'Ext.fx.Easing',
'Ext.fx.CubicBezier',
'Ext.fx.PropertyHandler'
],
isAnimation: true,
duration: 250,
delay: 0,
delayStart: 0,
dynamic: false,
easing: 'ease',
damper: 1,
bezierRE: /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,
reverse: false,
running: false,
paused: false,
iterations: 1,
autoEnd: false,
alternate: false,
currentIteration: 0,
startTime: 0,
frameCount: 0,
constructor: function(config) {
var me = this,
curve;
config = config || {};
if (config.keyframes) {
return new Ext.fx.Animator(config);
}
Ext.apply(me, config);
if (me.from === undefined) {
me.from = {};
}
me.propHandlers = {};
me.config = config;
me.target = Ext.fx.Manager.createTarget(me.target);
me.easingFn = Ext.fx.Easing[me.easing];
me.target.dynamic = me.dynamic;
if (!me.easingFn) {
me.easingFn = String(me.easing).match(me.bezierRE);
if (me.easingFn && me.easingFn.length === 5) {
curve = me.easingFn;
me.easingFn = Ext.fx.CubicBezier.cubicBezier(+curve[1], +curve[2], +curve[3], +curve[4]);
}
}
me.id = Ext.id(null, 'ext-anim-');
me.mixins.observable.constructor.call(me);
Ext.fx.Manager.addAnim(me);
if (config.autoEnd) {
me.running = true;
me.jumpToEnd();
}
},
setAttr: function(attr, value) {
return Ext.fx.Manager.items.get(this.id).setAttr(this.target, attr, value);
},
initAttrs: function() {
var me = this,
from = me.from,
to = me.to,
initialFrom = me.initialFrom || {},
out = {},
start, end, propHandler, attr;
for (attr in to) {
if (to.hasOwnProperty(attr)) {
start = me.target.getAttr(attr, from[attr]);
end = to[attr];
if (!Ext.fx.PropertyHandler[attr]) {
if (Ext.isObject(end)) {
propHandler = me.propHandlers[attr] = Ext.fx.PropertyHandler.object;
} else {
propHandler = me.propHandlers[attr] = Ext.fx.PropertyHandler.defaultHandler;
}
} else
{
propHandler = me.propHandlers[attr] = Ext.fx.PropertyHandler[attr];
}
out[attr] = propHandler.get(start, end, me.damper, initialFrom[attr], attr);
}
}
me.currentAttrs = out;
},
start: function(startTime) {
var me = this,
delay = me.delay,
delayStart = me.delayStart,
delayDelta;
if (delay) {
if (!delayStart) {
me.delayStart = startTime;
return;
} else {
delayDelta = startTime - delayStart;
if (delayDelta < delay) {
return;
} else {
startTime = new Date(delayStart.getTime() + delay);
}
}
}
if (me.fireEvent('beforeanimate', me) !== false) {
me.startTime = startTime;
if (!me.paused && !me.currentAttrs) {
me.initAttrs();
}
me.running = true;
me.frameCount = 0;
}
},
jumpToEnd: function() {
var me = this;
if (!me.endWasCalled) {
if (!me.currentAttrs) {
me.initAttrs();
}
Ext.fx.Manager.jumpToEnd(me);
me.end();
}
},
runAnim: function(elapsedTime) {
var me = this,
attrs = me.currentAttrs,
duration = me.duration,
easingFn = me.easingFn,
propHandlers = me.propHandlers,
ret = {},
easing, values, attr, lastFrame;
if (elapsedTime >= duration) {
elapsedTime = duration;
lastFrame = true;
}
if (me.reverse) {
elapsedTime = duration - elapsedTime;
}
for (attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
values = attrs[attr];
easing = lastFrame ? 1 : easingFn(elapsedTime / duration);
ret[attr] = propHandlers[attr].set(values, easing);
}
}
me.frameCount++;
return ret;
},
lastFrame: function() {
var me = this,
iter = me.iterations,
iterCount = me.currentIteration;
iterCount++;
if (iterCount < iter) {
if (me.alternate) {
me.reverse = !me.reverse;
}
me.startTime = new Date();
me.currentIteration = iterCount;
me.paused = false;
} else {
me.currentIteration = 0;
me.end();
me.fireEvent('lastframe', me, me.startTime);
}
},
endWasCalled: 0,
end: function() {
var me = this;
if (me.endWasCalled++) {
return;
}
me.startTime = 0;
me.paused = false;
me.running = false;
Ext.fx.Manager.removeAnim(me);
me.fireEvent('afteranimate', me, me.startTime);
Ext.callback(me.callback, me.scope, [
me,
me.startTime
]);
if (me.remove) {
me.target.destroy();
}
},
isReady: function() {
return this.paused === false && this.running === false && this.iterations > 0;
},
isRunning: function() {
return this.paused === false && this.running === true && this.isAnimator !== true;
}
});
Ext.enableFx = true;
Ext.define('Ext.util.Animate', {
mixinId: 'animate',
requires: [
'Ext.fx.Manager',
'Ext.fx.Anim'
],
isAnimate: true,
animate: function(animObj) {
var me = this;
if (Ext.fx.Manager.hasFxBlock(me.id)) {
return me;
}
Ext.fx.Manager.queueFx(new Ext.fx.Anim(me.anim(animObj)));
return this;
},
anim: function(config) {
if (!Ext.isObject(config)) {
return (config) ? {} : false;
}
var me = this;
if (config.stopAnimation) {
me.stopAnimation();
}
Ext.applyIf(config, Ext.fx.Manager.getFxDefaults(me.id));
return Ext.apply({
target: me,
paused: true
}, config);
},
getAnimationProps: function() {
var me = this,
layout = me.layout;
return layout && layout.animate ? layout.animate : {};
},
stopFx: Ext.Function.alias(Ext.util.Animate, 'stopAnimation'),
stopAnimation: function() {
Ext.fx.Manager.stopAnimation(this.id);
return this;
},
syncFx: function() {
Ext.fx.Manager.setFxDefaults(this.id, {
concurrent: true
});
return this;
},
sequenceFx: function() {
Ext.fx.Manager.setFxDefaults(this.id, {
concurrent: false
});
return this;
},
hasActiveFx: Ext.Function.alias(Ext.util.Animate, 'getActiveAnimation'),
getActiveAnimation: function() {
return Ext.fx.Manager.getActiveAnimation(this.id);
}
});
Ext.define('Ext.dom.Fly', {
extend: 'Ext.dom.Element',
alternateClassName: 'Ext.dom.Element.Fly',
validNodeTypes: {
1: 1,
9: 1,
11: 1
},
isFly: true,
constructor: function(dom) {
this.dom = dom;
this.el = this;
},
attach: function(dom) {
var me = this;
if (!dom) {
return me.detach();
}
me.dom = dom;
if (!Ext.cache[dom.id]) {
me.getData().isSynchronized = false;
}
return me;
},
detach: function() {
this.dom = null;
},
addListener: function() {
Ext.Error.raise("Cannot use addListener() on Ext.dom.Fly instances. " + "Please use Ext.get() to retrieve an Ext.dom.Element instance instead.");
} || null,
removeListener: function() {
Ext.Error.raise("Cannot use removeListener() on Ext.dom.Fly instances. " + "Please use Ext.get() to retrieve an Ext.dom.Element instance instead.");
} || null
}, function(Fly) {
var flyweights = {};
Fly.cache = flyweights;
Ext.fly = function(dom, named) {
var fly = null,
fn = Ext.fly,
nodeType, data;
named = named || (fn.caller && fn.caller.$name) || '_global';
dom = Ext.getDom(dom);
if (dom) {
nodeType = dom.nodeType;
if (Fly.prototype.validNodeTypes[nodeType] || (!nodeType && (dom.window == dom))) {
fly = Ext.cache[dom.id];
if (!fly || fly.dom !== dom) {
fly = flyweights[named] || (flyweights[named] = new Fly());
fly.dom = dom;
data = fly.getData(true);
if (data) {
data.isSynchronized = false;
}
}
}
}
return fly;
};
});
Ext.define('Ext.dom.CompositeElementLite', {
alternateClassName: [
'Ext.CompositeElementLite'
],
requires: [
'Ext.dom.Fly'
],
isComposite: true,
isLite: true,
statics: {
importElementMethods: function() {
var Element = Ext.dom.Element,
prototype = this.prototype;
Ext.Object.each(Element.prototype, function(name, member) {
if (typeof member === 'function' && !prototype[name]) {
prototype[name] = function() {
return this.invoke(name, arguments);
};
}
});
}
},
constructor: function(elements,
skipValidation) {
if (skipValidation) {
this.elements = elements || [];
} else {
this.elements = [];
this.add(elements);
}
},
getElement: function(el) {
var fly = this._fly || (this._fly = new Ext.dom.Fly());
return fly.attach(el);
},
transformElement: function(el) {
return Ext.getDom(el);
},
getCount: function() {
return this.elements.length;
},
add: function(els, root) {
var elements = this.elements,
i, ln;
if (!els) {
return this;
}
if (typeof els == "string") {
els = Ext.fly(root || document).query(els);
} else if (els.isComposite) {
els = els.elements;
} else if (!Ext.isIterable(els)) {
els = [
els
];
}
for (i = 0 , ln = els.length; i < ln; ++i) {
elements.push(this.transformElement(els[i]));
}
return this;
},
invoke: function(fn, args) {
var me = this,
elements = me.elements,
ln = elements.length,
prototype, element, i;
if (i !== 0) {
prototype = (me.isLite ? Ext.dom.Fly : Ext.dom.Element).prototype;
for (i = 0; i < ln; i++) {
element = elements[i];
if (element) {
prototype[fn].apply(me.getElement(element), args);
}
}
}
return me;
},
item: function(index) {
var el = this.elements[index],
out = null;
if (el) {
out = this.getElement(el);
}
return out;
},
slice: function(start, end) {
return Ext.Array.slice(this.elements, start, end);
},
each: function(fn, scope) {
var me = this,
els = me.elements,
len = els.length,
i, e;
for (i = 0; i < len; i++) {
e = els[i];
if (e) {
e = this.getElement(e);
if (fn.call(scope || e, e, me, i) === false) {
break;
}
}
}
return me;
},
fill: function(els) {
var me = this;
me.elements = [];
me.add(els);
return me;
},
insert: function(index, nodes) {
Ext.Array.insert(this.elements, index, nodes);
},
filter: function(selector) {
var me = this,
els = me.elements,
len = els.length,
out = [],
i = 0,
isFunc = typeof selector == 'function',
add, el;
for (; i < len; i++) {
el = els[i];
add = false;
if (el) {
el = me.getElement(el);
if (isFunc) {
add = selector.call(el, el, me, i) !== false;
} else {
add = el.is(selector);
}
if (add) {
out.push(me.transformElement(el));
}
}
}
me.elements = out;
return me;
},
indexOf: function(el) {
return Ext.Array.indexOf(this.elements, this.transformElement(el));
},
replaceElement: function(el, replacement, domReplace) {
var index = !isNaN(el) ? el : this.indexOf(el),
d;
if (index > -1) {
replacement = Ext.getDom(replacement);
if (domReplace) {
d = this.elements[index];
d.parentNode.insertBefore(replacement, d);
Ext.removeNode(d);
}
Ext.Array.splice(this.elements, index, 1, replacement);
}
return this;
},
clear: function(removeDom) {
var me = this,
els = me.elements,
i = els.length - 1;
if (removeDom) {
for (; i >= 0; i--) {
Ext.removeNode(els[i]);
}
}
this.elements = [];
},
addElements: function(els, root) {
if (!els) {
return this;
}
if (typeof els === "string") {
els = Ext.dom.Element.selectorFunction(els, root);
}
var yels = this.elements,
eLen = els.length,
e;
for (e = 0; e < eLen; e++) {
yels.push(Ext.get(els[e]));
}
return this;
},
first: function() {
return this.item(0);
},
last: function() {
return this.item(this.getCount() - 1);
},
contains: function(el) {
return this.indexOf(el) != -1;
},
removeElement: function(keys, removeDom) {
keys = [].concat(keys);
var me = this,
elements = me.elements,
kLen = keys.length,
val, el, k;
for (k = 0; k < kLen; k++) {
val = keys[k];
if ((el = (elements[val] || elements[val = me.indexOf(val)]))) {
if (removeDom) {
if (el.dom) {
el.destroy();
} else {
Ext.removeNode(el);
}
}
Ext.Array.erase(elements, val, 1);
}
}
return me;
},
destroy: function() {
return this.invoke('destroy', arguments);
}
}, function(CompositeElementLite) {
var prototype = CompositeElementLite.prototype;
CompositeElementLite.importElementMethods();
prototype.on = prototype.addListener;
});
Ext.define('Ext.overrides.dom.Element', (function() {
var Element,
WIN = window,
DOC = document,
HIDDEN = 'hidden',
ISCLIPPED = 'isClipped',
OVERFLOW = 'overflow',
OVERFLOWX = 'overflow-x',
OVERFLOWY = 'overflow-y',
ORIGINALCLIP = 'originalClip',
HEIGHT = 'height',
WIDTH = 'width',
VISIBILITY = 'visibility',
DISPLAY = 'display',
NONE = 'none',
OFFSETS = 'offsets',
ORIGINALDISPLAY = 'originalDisplay',
VISMODE = 'visibilityMode',
ISVISIBLE = 'isVisible',
OFFSETCLASS = Ext.baseCSSPrefix + 'hidden-offsets',
boxMarkup = [
'<div class="{0}-tl" role="presentation">',
'<div class="{0}-tr" role="presentation">',
'<div class="{0}-tc" role="presentation"></div>',
'</div>',
'</div>',
'<div class="{0}-ml" role="presentation">',
'<div class="{0}-mr" role="presentation">',
'<div class="{0}-mc" role="presentation"></div>',
'</div>',
'</div>',
'<div class="{0}-bl" role="presentation">',
'<div class="{0}-br" role="presentation">',
'<div class="{0}-bc" role="presentation"></div>',
'</div>',
'</div>'
].join(''),
scriptTagRe = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig,
replaceScriptTagRe = /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,
srcRe = /\ssrc=([\'\"])(.*?)\1/i,
nonSpaceRe = /\S/,
typeRe = /\stype=([\'\"])(.*?)\1/i,
msRe = /^-ms-/,
camelRe = /(-[a-z])/gi,
camelReplaceFn = function(m, a) {
return a.charAt(1).toUpperCase();
},
XMASKED = Ext.baseCSSPrefix + "masked",
XMASKEDRELATIVE = Ext.baseCSSPrefix + "masked-relative",
EXTELMASKMSG = Ext.baseCSSPrefix + "mask-msg",
bodyRe = /^body/i,
propertyCache = {},
getDisplay = function(el) {
var data = el.getData(),
display = data[ORIGINALDISPLAY];
if (display === undefined) {
data[ORIGINALDISPLAY] = display = '';
}
return display;
},
getVisMode = function(el) {
var data = el.getData(),
visMode = data[VISMODE];
if (visMode === undefined) {
data[VISMODE] = visMode = Element.VISIBILITY;
}
return visMode;
},
emptyRange = DOC.createRange ? DOC.createRange() : null,
inputTags = {
INPUT: true,
TEXTAREA: true
};
if (Ext.isIE8) {
var removeNode = Ext.removeNode,
garbageBin = DOC.createElement('div'),
destroyQueue = [],
clearGarbage = Ext.Function.createBuffered(function() {
var len = destroyQueue.length,
i;
for (i = 0; i < len; i++) {
garbageBin.appendChild(destroyQueue[i]);
}
garbageBin.innerHTML = '';
destroyQueue.length = 0;
}, 10);
Ext.removeNode = function(node) {
node = node.dom || node;
removeNode(node);
destroyQueue[destroyQueue.length] = node;
clearGarbage();
};
}
return {
override: 'Ext.dom.Element',
mixins: [
'Ext.util.Animate'
],
uses: [
'Ext.dom.GarbageCollector',
'Ext.dom.Fly',
'Ext.event.publisher.MouseEnterLeave',
'Ext.fx.Manager',
'Ext.fx.Anim'
],
skipGarbageCollection: false,
_init: function(E) {
Element = E;
},
statics: {
selectableCls: Ext.baseCSSPrefix + 'selectable',
unselectableCls: Ext.baseCSSPrefix + 'unselectable',
tabIndexAttributeName: Ext.isIE8 ? 'tabIndex' : 'tabindex',
tabbableSelector: 'a[href],button,iframe,input,select,textarea,[tabindex],[contenteditable="true"]',
naturallyFocusableTags: {
BUTTON: true,
IFRAME: true,
EMBED: true,
INPUT: true,
OBJECT: true,
SELECT: true,
TEXTAREA: true,
HTML: Ext.isIE ? true : false
},
naturallyTabbableTags: {
BUTTON: true,
IFRAME: true,
INPUT: true,
SELECT: true,
TEXTAREA: true,
OBJECT: Ext.isIE8m ? true : false
},
tabbableSavedFlagAttribute: 'data-tabindexsaved',
tabbableSavedAttribute: 'data-savedtabindex',
normalize: function(prop) {
if (prop === 'float') {
prop = Ext.supports.Float ? 'cssFloat' : 'styleFloat';
}
return propertyCache[prop] || (propertyCache[prop] = prop.replace(msRe, 'ms-').replace(camelRe, camelReplaceFn));
},
getViewportHeight: function() {
return Ext.isIE9m ? DOC.documentElement.clientHeight : WIN.innerHeight;
},
getViewportWidth: function() {
return (!Ext.isStrict && !Ext.isOpera) ? document.body.clientWidth : Ext.isIE9m ? DOC.documentElement.clientWidth : WIN.innerWidth;
}
},
addClsOnClick: function(className, testFn, scope) {
var me = this,
dom = me.dom,
hasTest = Ext.isFunction(testFn);
me.on("mousedown", function() {
if (hasTest && testFn.call(scope || me, me) === false) {
return false;
}
Ext.fly(dom).addCls(className);
var d = Ext.getDoc(),
fn = function() {
Ext.fly(dom).removeCls(className);
d.removeListener("mouseup", fn);
};
d.on("mouseup", fn);
});
return me;
},
addClsOnFocus: function(className, testFn, scope) {
var me = this,
dom = me.dom,
hasTest = Ext.isFunction(testFn);
me.on("focus", function() {
if (hasTest && testFn.call(scope || me, me) === false) {
return false;
}
Ext.fly(dom).addCls(className);
});
me.on("blur", function() {
Ext.fly(dom).removeCls(className);
});
return me;
},
addClsOnOver: function(className, testFn, scope) {
var me = this,
dom = me.dom,
hasTest = Ext.isFunction(testFn);
me.hover(function() {
if (hasTest && testFn.call(scope || me, me) === false) {
return;
}
Ext.fly(dom).addCls(className);
}, function() {
Ext.fly(dom).removeCls(className);
});
return me;
},
addKeyListener: function(key, fn, scope) {
var config;
if (typeof key !== 'object' || Ext.isArray(key)) {
config = {
target: this,
key: key,
fn: fn,
scope: scope
};
} else {
config = {
target: this,
key: key.key,
shift: key.shift,
ctrl: key.ctrl,
alt: key.alt,
fn: fn,
scope: scope
};
}
return new Ext.util.KeyMap(config);
},
addKeyMap: function(config) {
return new Ext.util.KeyMap(Ext.apply({
target: this
}, config));
},
afterAnimate: function() {
var shadow = this.shadow;
if (shadow && !shadow.disabled && !shadow.animate) {
shadow.show();
}
},
anchorAnimX: function(anchor) {
var xName = (anchor === 'l') ? 'right' : 'left';
this.dom.style[xName] = '0px';
},
anim: function(config) {
if (!Ext.isObject(config)) {
return (config) ? {} : false;
}
var me = this,
duration = config.duration || Ext.fx.Anim.prototype.duration,
easing = config.easing || 'ease',
animConfig;
if (config.stopAnimation) {
me.stopAnimation();
}
Ext.applyIf(config, Ext.fx.Manager.getFxDefaults(me.id));
Ext.fx.Manager.setFxDefaults(me.id, {
delay: 0
});
animConfig = {
target: me.dom,
remove: config.remove,
alternate: config.alternate || false,
duration: duration,
easing: easing,
callback: config.callback,
listeners: config.listeners,
iterations: config.iterations || 1,
scope: config.scope,
block: config.block,
concurrent: config.concurrent,
delay: config.delay || 0,
paused: true,
keyframes: config.keyframes,
from: config.from || {},
to: Ext.apply({}, config)
};
Ext.apply(animConfig.to, config.to);
delete animConfig.to.to;
delete animConfig.to.from;
delete animConfig.to.remove;
delete animConfig.to.alternate;
delete animConfig.to.keyframes;
delete animConfig.to.iterations;
delete animConfig.to.listeners;
delete animConfig.to.target;
delete animConfig.to.paused;
delete animConfig.to.callback;
delete animConfig.to.scope;
delete animConfig.to.duration;
delete animConfig.to.easing;
delete animConfig.to.concurrent;
delete animConfig.to.block;
delete animConfig.to.stopAnimation;
delete animConfig.to.delay;
return animConfig;
},
animate: function(config) {
var me = this,
animId = me.dom.id || Ext.id(me.dom),
listeners, anim, end;
if (!Ext.fx.Manager.hasFxBlock(animId)) {
if (config.listeners) {
listeners = config.listeners;
delete config.listeners;
}
if (config.internalListeners) {
config.listeners = config.internalListeners;
delete config.internalListeners;
}
end = config.autoEnd;
delete config.autoEnd;
anim = new Ext.fx.Anim(me.anim(config));
anim.on({
afteranimate: 'afterAnimate',
beforeanimate: 'beforeAnimate',
scope: me,
single: true
});
if (listeners) {
anim.on(listeners);
}
Ext.fx.Manager.queueFx(anim);
if (end) {
anim.jumpToEnd();
}
}
return me;
},
beforeAnimate: function() {
var shadow = this.shadow;
if (shadow && !shadow.disabled && !shadow.animate) {
shadow.hide();
}
},
boxWrap: function(cls) {
cls = cls || Ext.baseCSSPrefix + 'box';
var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "' role='presentation'>" + Ext.String.format(boxMarkup, cls) + "</div>"));
el.selectNode('.' + cls + '-mc').appendChild(this.dom);
return el;
},
clean: function(forceReclean) {
var me = this,
dom = me.dom,
data = me.getData(),
n = dom.firstChild,
ni = -1,
nx;
if (data.isCleaned && forceReclean !== true) {
return me;
}
while (n) {
nx = n.nextSibling;
if (n.nodeType === 3) {
if (!(nonSpaceRe.test(n.nodeValue))) {
dom.removeChild(n);
}
else if (nx && nx.nodeType === 3) {
n.appendData(Ext.String.trim(nx.data));
dom.removeChild(nx);
nx = n.nextSibling;
n.nodeIndex = ++ni;
}
} else {
Ext.fly(n, '_clean').clean();
n.nodeIndex = ++ni;
}
n = nx;
}
data.isCleaned = true;
return me;
},
empty: emptyRange ? function() {
var dom = this.dom;
if (dom.firstChild) {
emptyRange.setStartBefore(dom.firstChild);
emptyRange.setEndAfter(dom.lastChild);
emptyRange.deleteContents();
}
} : function() {
var dom = this.dom;
while (dom.lastChild) {
dom.removeChild(dom.lastChild);
}
},
clearListeners: function() {
this.removeAnchor();
this.callParent();
},
clearPositioning: function(value) {
value = value || '';
return this.setStyle({
left: value,
right: value,
top: value,
bottom: value,
'z-index': '',
position: 'static'
});
},
createProxy: function(config, renderTo, matchBox) {
config = (typeof config === 'object') ? config : {
tag: "div",
role: 'presentation',
cls: config
};
var me = this,
proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) : Ext.DomHelper.insertBefore(me.dom, config, true);
proxy.setVisibilityMode(Element.DISPLAY);
proxy.hide();
if (matchBox && me.setBox && me.getBox) {
proxy.setBox(me.getBox());
}
return proxy;
},
clearOpacity: function() {
return this.setOpacity('');
},
clip: function() {
var me = this,
data = me.getData(),
style;
if (!data[ISCLIPPED]) {
data[ISCLIPPED] = true;
style = me.getStyle([
OVERFLOW,
OVERFLOWX,
OVERFLOWY
]);
data[ORIGINALCLIP] = {
o: style[OVERFLOW],
x: style[OVERFLOWX],
y: style[OVERFLOWY]
};
me.setStyle(OVERFLOW, HIDDEN);
me.setStyle(OVERFLOWX, HIDDEN);
me.setStyle(OVERFLOWY, HIDDEN);
}
return me;
},
destroy: function() {
var me = this,
dom = me.dom,
data = me.getData(),
maskEl, maskMsg;
if (dom && me.isAnimate) {
me.stopAnimation();
}
me.callParent();
if (dom && Ext.isIE8 && (dom.window != dom) && (dom.nodeType !== 9) && (dom.tagName !== 'BODY') && (dom.tagName !== 'HTML')) {
destroyQueue[destroyQueue.length] = dom;
clearGarbage();
}
if (data) {
maskEl = data.maskEl;
maskMsg = data.maskMsg;
if (maskEl) {
maskEl.destroy();
}
if (maskMsg) {
maskMsg.destroy();
}
}
},
enableDisplayMode: function(display) {
var me = this;
me.setVisibilityMode(Element.DISPLAY);
if (display !== undefined) {
me.getData()[ORIGINALDISPLAY] = display;
}
return me;
},
fadeIn: function(o) {
var me = this,
dom = me.dom;
me.animate(Ext.apply({}, o, {
opacity: 1,
internalListeners: {
beforeanimate: function(anim) {
var el = Ext.fly(dom, '_anim');
if (el.isStyle('display', 'none')) {
el.setDisplayed('');
} else {
el.show();
}
}
}
}));
return this;
},
fadeOut: function(o) {
var me = this,
dom = me.dom;
o = Ext.apply({
opacity: 0,
internalListeners: {
afteranimate: function(anim) {
if (dom && anim.to.opacity === 0) {
var el = Ext.fly(dom, '_anim');
if (o.useDisplay) {
el.setDisplayed(false);
} else {
el.hide();
}
}
}
}
}, o);
me.animate(o);
return me;
},
fixDisplay: function() {
var me = this;
if (me.isStyle(DISPLAY, NONE)) {
me.setStyle(VISIBILITY, HIDDEN);
me.setStyle(DISPLAY, getDisplay(me));
if (me.isStyle(DISPLAY, NONE)) {
me.setStyle(DISPLAY, "block");
}
}
},
frame: function(color, count, obj) {
var me = this,
dom = me.dom,
beforeAnim;
color = color || '#C3DAF9';
count = count || 1;
obj = obj || {};
beforeAnim = function() {
var el = Ext.fly(dom, '_anim'),
animScope = this,
box, proxy, proxyAnim;
el.show();
box = el.getBox();
proxy = Ext.getBody().createChild({
role: 'presentation',
id: el.dom.id + '-anim-proxy',
style: {
position: 'absolute',
'pointer-events': 'none',
'z-index': 35000,
border: '0px solid ' + color
}
});
proxyAnim = new Ext.fx.Anim({
target: proxy,
duration: obj.duration || 1000,
iterations: count,
from: {
top: box.y,
left: box.x,
borderWidth: 0,
opacity: 1,
height: box.height,
width: box.width
},
to: {
top: box.y - 20,
left: box.x - 20,
borderWidth: 10,
opacity: 0,
height: box.height + 40,
width: box.width + 40
}
});
proxyAnim.on('afteranimate', function() {
proxy.destroy();
animScope.end();
});
};
me.animate({
duration: (Math.max(obj.duration, 500) * 2) || 2000,
listeners: {
beforeanimate: {
fn: beforeAnim
}
},
callback: obj.callback,
scope: obj.scope
});
return me;
},
getColor: function(attr, defaultValue, prefix) {
var v = this.getStyle(attr),
color = prefix || prefix === '' ? prefix : '#',
h, len,
i = 0;
if (!v || (/transparent|inherit/.test(v))) {
return defaultValue;
}
if (/^r/.test(v)) {
v = v.slice(4, v.length - 1).split(',');
len = v.length;
for (; i < len; i++) {
h = parseInt(v[i], 10);
color += (h < 16 ? '0' : '') + h.toString(16);
}
} else {
v = v.replace('#', '');
color += v.length === 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v;
}
return (color.length > 5 ? color.toLowerCase() : defaultValue);
},
getLoader: function() {
var me = this,
data = me.getData(),
loader = data.loader;
if (!loader) {
data.loader = loader = new Ext.ElementLoader({
target: me
});
}
return loader;
},
getPositioning: function(autoPx) {
var styles = this.getStyle([
'left',
'top',
'position',
'z-index'
]),
dom = this.dom;
if (autoPx) {
if (styles.left === 'auto') {
styles.left = dom.offsetLeft + 'px';
}
if (styles.top === 'auto') {
styles.top = dom.offsetTop + 'px';
}
}
return styles;
},
ghost: function(anchor, obj) {
var me = this,
dom = me.dom,
beforeAnim;
anchor = anchor || "b";
beforeAnim = function() {
var el = Ext.fly(dom, '_anim'),
width = el.getWidth(),
height = el.getHeight(),
xy = el.getXY(),
position = el.getPositioning(),
to = {
opacity: 0
};
switch (anchor) {
case 't':
to.y = xy[1] - height;
break;
case 'l':
to.x = xy[0] - width;
break;
case 'r':
to.x = xy[0] + width;
break;
case 'b':
to.y = xy[1] + height;
break;
case 'tl':
to.x = xy[0] - width;
to.y = xy[1] - height;
break;
case 'bl':
to.x = xy[0] - width;
to.y = xy[1] + height;
break;
case 'br':
to.x = xy[0] + width;
to.y = xy[1] + height;
break;
case 'tr':
to.x = xy[0] + width;
to.y = xy[1] - height;
break;
}
this.to = to;
this.on('afteranimate', function() {
var el = Ext.fly(dom, '_anim');
if (el) {
el.hide();
el.clearOpacity();
el.setPositioning(position);
}
});
};
me.animate(Ext.applyIf(obj || {}, {
duration: 500,
easing: 'ease-out',
listeners: {
beforeanimate: beforeAnim
}
}));
return me;
},
hide: function(animate) {
if (typeof animate === 'string') {
this.setVisible(false, animate);
return this;
}
this.setVisible(false, this.anim(animate));
return this;
},
highlight: function(color, o) {
var me = this,
dom = me.dom,
from = {},
restore, to, attr, lns, event, fn;
o = o || {};
lns = o.listeners || {};
attr = o.attr || 'backgroundColor';
from[attr] = color || 'ffff9c';
if (!o.to) {
to = {};
to[attr] = o.endColor || me.getColor(attr, 'ffffff', '');
} else {
to = o.to;
}
o.listeners = Ext.apply(Ext.apply({}, lns), {
beforeanimate: function() {
restore = dom.style[attr];
var el = Ext.fly(dom, '_anim');
el.clearOpacity();
el.show();
event = lns.beforeanimate;
if (event) {
fn = event.fn || event;
return fn.apply(event.scope || lns.scope || WIN, arguments);
}
},
afteranimate: function() {
if (dom) {
dom.style[attr] = restore;
}
event = lns.afteranimate;
if (event) {
fn = event.fn || event;
fn.apply(event.scope || lns.scope || WIN, arguments);
}
}
});
me.animate(Ext.apply({}, o, {
duration: 1000,
easing: 'ease-in',
from: from,
to: to
}));
return me;
},
hover: function(overFn, outFn, scope, options) {
var me = this;
me.on('mouseenter', overFn, scope || me.dom, options);
me.on('mouseleave', outFn, scope || me.dom, options);
return me;
},
initDD: function(group, config, overrides) {
var dd = new Ext.dd.DD(Ext.id(this.dom), group, config);
return Ext.apply(dd, overrides);
},
initDDProxy: function(group, config, overrides) {
var dd = new Ext.dd.DDProxy(Ext.id(this.dom), group, config);
return Ext.apply(dd, overrides);
},
initDDTarget: function(group, config, overrides) {
var dd = new Ext.dd.DDTarget(Ext.id(this.dom), group, config);
return Ext.apply(dd, overrides);
},
isFocusable: function() {
var dom = this.dom,
focusable = false,
nodeName;
if (dom && !dom.disabled) {
nodeName = dom.nodeName;
focusable = !!Ext.Element.naturallyFocusableTags[nodeName] || ((nodeName === 'A' || nodeName === 'LINK') && !!dom.href) || dom.getAttribute('tabindex') != null || dom.contentEditable === 'true';
if (Ext.isIE8 && nodeName === 'INPUT' && dom.type === 'hidden') {
focusable = false;
}
focusable = focusable && this.isVisible(true);
}
return focusable;
},
isInputField: function() {
var dom = this.dom,
contentEditable = dom.contentEditable;
if ((inputTags[dom.tagName] && dom.type !== 'button') || (contentEditable === '' || contentEditable === 'true')) {
return true;
}
return false;
},
isTabbable: function() {
var dom = this.dom,
tabbable = false,
nodeName, hasIndex, tabIndex;
if (dom && !dom.disabled) {
nodeName = dom.nodeName;
tabIndex = dom.getAttribute('tabindex');
hasIndex = tabIndex != null;
tabIndex -= 0;
if (nodeName === 'A' || nodeName === 'LINK') {
if (dom.href) {
tabbable = hasIndex && tabIndex < 0 ? false : true;
} else
{
if (dom.contentEditable === 'true') {
tabbable = !hasIndex || (hasIndex && tabIndex >= 0) ? true : false;
} else {
tabbable = hasIndex && tabIndex >= 0 ? true : false;
}
}
}
else if (dom.contentEditable === 'true' || Ext.Element.naturallyTabbableTags[nodeName]) {
tabbable = hasIndex && tabIndex < 0 ? false : true;
} else
{
if (hasIndex && tabIndex >= 0) {
tabbable = true;
}
}
if (Ext.isIE8 && nodeName === 'INPUT' && dom.type === 'hidden') {
tabbable = false;
}
tabbable = tabbable && (!this.component || this.component.isVisible(true)) && this.isVisible(true);
}
return tabbable;
},
isMasked: function(deep) {
var me = this,
data = me.getData(),
maskEl = data.maskEl,
maskMsg = data.maskMsg,
hasMask = false,
parent;
if (maskEl && maskEl.isVisible()) {
if (maskMsg) {
maskMsg.center(me);
}
hasMask = true;
} else if (deep) {
parent = me.findParentNode();
if (parent) {
return Ext.fly(parent).isMasked(deep);
}
}
return hasMask;
},
isScrollable: function() {
var dom = this.dom;
return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth;
},
load: function(options) {
this.getLoader().load(options);
return this;
},
mask: function(msg, msgCls,
elHeight) {
var me = this,
dom = me.dom,
data = me.getData(),
maskEl = data.maskEl,
maskMsg;
if (!(bodyRe.test(dom.tagName) && me.getStyle('position') === 'static')) {
me.addCls(XMASKEDRELATIVE);
}
if (maskEl) {
maskEl.destroy();
}
maskEl = Ext.DomHelper.append(dom, {
role: 'presentation',
cls: Ext.baseCSSPrefix + "mask " + Ext.baseCSSPrefix + "border-box",
children: {
role: 'presentation',
cls: msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG,
cn: {
tag: 'div',
role: 'presentation',
cls: Ext.baseCSSPrefix + 'mask-msg-inner',
cn: {
tag: 'div',
role: 'presentation',
cls: Ext.baseCSSPrefix + 'mask-msg-text',
html: msg || ''
}
}
}
}, true);
maskMsg = Ext.get(maskEl.dom.firstChild);
data.maskEl = maskEl;
me.addCls(XMASKED);
maskEl.setDisplayed(true);
if (typeof msg === 'string') {
maskMsg.setDisplayed(true);
maskMsg.center(me);
} else {
maskMsg.setDisplayed(false);
}
if (dom === DOC.body) {
maskEl.addCls(Ext.baseCSSPrefix + 'mask-fixed');
} else {
me.saveTabbableState();
}
me.saveChildrenTabbableState();
if (Ext.isIE9m && dom !== DOC.body && me.isStyle('height', 'auto')) {
maskEl.setSize(undefined, elHeight || me.getHeight());
}
return maskEl;
},
monitorMouseLeave: function(delay, handler, scope) {
var me = this,
timer,
listeners = {
mouseleave: function(e) {
if (Ext.isIE9m) {
e.enableIEAsync();
}
timer = Ext.defer(handler, delay, scope || me, [
e
]);
},
mouseenter: function() {
clearTimeout(timer);
}
};
me.on(listeners);
return listeners;
},
puff: function(obj) {
var me = this,
dom = me.dom,
beforeAnim,
box = me.getBox(),
originalStyles = me.getStyle([
'width',
'height',
'left',
'right',
'top',
'bottom',
'position',
'z-index',
'font-size',
'opacity'
], true);
obj = Ext.applyIf(obj || {}, {
easing: 'ease-out',
duration: 500,
useDisplay: false
});
beforeAnim = function() {
var el = Ext.fly(dom, '_anim');
el.clearOpacity();
el.show();
this.to = {
width: box.width * 2,
height: box.height * 2,
x: box.x - (box.width / 2),
y: box.y - (box.height / 2),
opacity: 0,
fontSize: '200%'
};
this.on('afteranimate', function() {
var el = Ext.fly(dom, '_anim');
if (el) {
if (obj.useDisplay) {
el.setDisplayed(false);
} else {
el.hide();
}
el.setStyle(originalStyles);
Ext.callback(obj.callback, obj.scope);
}
});
};
me.animate({
duration: obj.duration,
easing: obj.easing,
listeners: {
beforeanimate: {
fn: beforeAnim
}
}
});
return me;
},
selectable: function() {
var me = this;
me.dom.unselectable = '';
me.removeCls(Element.unselectableCls);
me.addCls(Element.selectableCls);
return me;
},
setCapture: function() {
var dom = this.dom;
if (Ext.isIE9m && dom.setCapture) {
dom.setCapture();
}
},
setDisplayed: function(value) {
var me = this;
if (typeof value === "boolean") {
value = value ? getDisplay(me) : NONE;
}
me.setStyle(DISPLAY, value);
if (me.shadow || me.shim) {
me.setUnderlaysVisible(value !== NONE);
}
return me;
},
setHeight: function(height, animate) {
var me = this;
if (!animate || !me.anim) {
me.callParent(arguments);
} else {
if (!Ext.isObject(animate)) {
animate = {};
}
me.animate(Ext.applyIf({
to: {
height: height
}
}, animate));
}
return me;
},
setHorizontal: function() {
var me = this,
cls = me.verticalCls;
delete me.vertical;
if (cls) {
delete me.verticalCls;
me.removeCls(cls);
}
delete me.setWidth;
delete me.setHeight;
if (!Ext.isIE8) {
delete me.getWidth;
delete me.getHeight;
}
delete me.styleHooks;
},
updateText: function(text) {
var me = this,
dom, textNode;
if (dom) {
textNode = dom.firstChild;
if (!textNode || (textNode.nodeType !== 3 || textNode.nextSibling)) {
textNode = DOC.createTextNode();
me.empty();
dom.appendChild(textNode);
}
if (text) {
textNode.data = text;
}
}
},
setHtml: function(html, loadScripts, callback) {
var me = this,
id, dom, interval;
if (!me.dom) {
return me;
}
html = html || '';
dom = me.dom;
if (loadScripts !== true) {
dom.innerHTML = html;
Ext.callback(callback, me);
return me;
}
id = Ext.id();
html += '<span id="' + id + '" role="presentation"></span>';
interval = Ext.interval(function() {
var hd, match, attrs, srcMatch, typeMatch, el, s;
if (!(el = DOC.getElementById(id))) {
return false;
}
clearInterval(interval);
Ext.removeNode(el);
hd = Ext.getHead().dom;
while ((match = scriptTagRe.exec(html))) {
attrs = match[1];
srcMatch = attrs ? attrs.match(srcRe) : false;
if (srcMatch && srcMatch[2]) {
s = DOC.createElement("script");
s.src = srcMatch[2];
typeMatch = attrs.match(typeRe);
if (typeMatch && typeMatch[2]) {
s.type = typeMatch[2];
}
hd.appendChild(s);
} else if (match[2] && match[2].length > 0) {
(WIN.execScript || WIN.eval)(match[2]);
}
}
Ext.callback(callback, me);
}, 20);
dom.innerHTML = html.replace(replaceScriptTagRe, '');
return me;
},
setOpacity: function(opacity, animate) {
var me = this;
if (!me.dom) {
return me;
}
if (!animate || !me.anim) {
me.setStyle('opacity', opacity);
} else {
if (typeof animate != 'object') {
animate = {
duration: 350,
easing: 'ease-in'
};
}
me.animate(Ext.applyIf({
to: {
opacity: opacity
}
}, animate));
}
return me;
},
setPositioning: function(pc) {
return this.setStyle(pc);
},
setVertical: function(angle, cls) {
var me = this,
proto = Element.prototype;
me.vertical = true;
if (cls) {
me.addCls(me.verticalCls = cls);
}
me.setWidth = proto.setHeight;
me.setHeight = proto.setWidth;
if (!Ext.isIE8) {
me.getWidth = proto.getHeight;
me.getHeight = proto.getWidth;
}
me.styleHooks = (angle === 270) ? proto.verticalStyleHooks270 : proto.verticalStyleHooks90;
},
setSize: function(width, height, animate) {
var me = this;
if (Ext.isObject(width)) {
animate = height;
height = width.height;
width = width.width;
}
if (!animate || !me.anim) {
me.dom.style.width = Element.addUnits(width);
me.dom.style.height = Element.addUnits(height);
if (me.shadow || me.shim) {
me.syncUnderlays();
}
} else {
if (animate === true) {
animate = {};
}
me.animate(Ext.applyIf({
to: {
width: width,
height: height
}
}, animate));
}
return me;
},
setVisible: function(visible, animate) {
var me = this,
dom = me.dom,
visMode = getVisMode(me);
if (typeof animate === 'string') {
switch (animate) {
case DISPLAY:
visMode = Element.DISPLAY;
break;
case VISIBILITY:
visMode = Element.VISIBILITY;
break;
case OFFSETS:
visMode = Element.OFFSETS;
break;
}
me.setVisibilityMode(visMode);
animate = false;
}
if (!animate || !me.anim) {
if (visMode === Element.DISPLAY) {
return me.setDisplayed(visible);
} else if (visMode === Element.OFFSETS) {
me[visible ? 'removeCls' : 'addCls'](OFFSETCLASS);
} else if (visMode === Element.VISIBILITY) {
me.fixDisplay();
dom.style.visibility = visible ? '' : HIDDEN;
}
} else {
if (visible) {
me.setOpacity(0.01);
me.setVisible(true);
}
if (!Ext.isObject(animate)) {
animate = {
duration: 350,
easing: 'ease-in'
};
}
me.animate(Ext.applyIf({
callback: function() {
if (!visible) {
Ext.fly(dom).setVisible(false).setOpacity(1);
}
},
to: {
opacity: (visible) ? 1 : 0
}
}, animate));
}
me.getData()[ISVISIBLE] = visible;
if (me.shadow || me.shim) {
me.setUnderlaysVisible(visible);
}
return me;
},
setWidth: function(width, animate) {
var me = this;
if (!animate || !me.anim) {
me.callParent(arguments);
} else {
if (!Ext.isObject(animate)) {
animate = {};
}
me.animate(Ext.applyIf({
to: {
width: width
}
}, animate));
}
return me;
},
setX: function(x, animate) {
return this.setXY([
x,
this.getY()
], animate);
},
setXY: function(xy, animate) {
var me = this;
if (!animate || !me.anim) {
me.callParent([
xy
]);
} else {
if (!Ext.isObject(animate)) {
animate = {};
}
me.animate(Ext.applyIf({
to: {
x: xy[0],
y: xy[1]
}
}, animate));
}
return this;
},
setY: function(y, animate) {
return this.setXY([
this.getX(),
y
], animate);
},
show: function(animate) {
if (typeof animate === 'string') {
this.setVisible(true, animate);
return this;
}
this.setVisible(true, this.anim(animate));
return this;
},
slideIn: function(anchor, obj, slideOut) {
var me = this,
dom = me.dom,
elStyle = dom.style,
beforeAnim, wrapAnim, restoreScroll, wrapDomParentNode;
anchor = anchor || "t";
obj = obj || {};
beforeAnim = function() {
var animScope = this,
listeners = obj.listeners,
el = Ext.fly(dom, '_anim'),
box, originalStyles, anim, wrap;
if (!slideOut) {
el.fixDisplay();
}
box = el.getBox();
if ((anchor == 't' || anchor == 'b') && box.height === 0) {
box.height = dom.scrollHeight;
} else if ((anchor == 'l' || anchor == 'r') && box.width === 0) {
box.width = dom.scrollWidth;
}
originalStyles = el.getStyle([
'width',
'height',
'left',
'right',
'top',
'bottom',
'position',
'z-index'
], true);
el.setSize(box.width, box.height);
if (obj.preserveScroll) {
restoreScroll = el.cacheScrollValues();
}
wrap = el.wrap({
role: 'presentation',
id: Ext.id() + '-anim-wrap-for-' + el.dom.id,
style: {
visibility: slideOut ? 'visible' : 'hidden'
}
});
wrapDomParentNode = wrap.dom.parentNode;
wrap.setPositioning(el.getPositioning());
if (wrap.isStyle('position', 'static')) {
wrap.position('relative');
}
el.clearPositioning('auto');
wrap.clip();
if (restoreScroll) {
restoreScroll();
}
el.setStyle({
visibility: '',
position: 'absolute'
});
if (slideOut) {
wrap.setSize(box.width, box.height);
}
switch (anchor) {
case 't':
anim = {
from: {
width: box.width + 'px',
height: '0px'
},
to: {
width: box.width + 'px',
height: box.height + 'px'
}
};
elStyle.bottom = '0px';
break;
case 'l':
anim = {
from: {
width: '0px',
height: box.height + 'px'
},
to: {
width: box.width + 'px',
height: box.height + 'px'
}
};
me.anchorAnimX(anchor);
break;
case 'r':
anim = {
from: {
x: box.x + box.width,
width: '0px',
height: box.height + 'px'
},
to: {
x: box.x,
width: box.width + 'px',
height: box.height + 'px'
}
};
me.anchorAnimX(anchor);
break;
case 'b':
anim = {
from: {
y: box.y + box.height,
width: box.width + 'px',
height: '0px'
},
to: {
y: box.y,
width: box.width + 'px',
height: box.height + 'px'
}
};
break;
case 'tl':
anim = {
from: {
x: box.x,
y: box.y,
width: '0px',
height: '0px'
},
to: {
width: box.width + 'px',
height: box.height + 'px'
}
};
elStyle.bottom = '0px';
me.anchorAnimX('l');
break;
case 'bl':
anim = {
from: {
y: box.y + box.height,
width: '0px',
height: '0px'
},
to: {
y: box.y,
width: box.width + 'px',
height: box.height + 'px'
}
};
me.anchorAnimX('l');
break;
case 'br':
anim = {
from: {
x: box.x + box.width,
y: box.y + box.height,
width: '0px',
height: '0px'
},
to: {
x: box.x,
y: box.y,
width: box.width + 'px',
height: box.height + 'px'
}
};
me.anchorAnimX('r');
break;
case 'tr':
anim = {
from: {
x: box.x + box.width,
width: '0px',
height: '0px'
},
to: {
x: box.x,
width: box.width + 'px',
height: box.height + 'px'
}
};
elStyle.bottom = '0px';
me.anchorAnimX('r');
break;
}
wrap.show();
wrapAnim = Ext.apply({}, obj);
delete wrapAnim.listeners;
wrapAnim = new Ext.fx.Anim(Ext.applyIf(wrapAnim, {
target: wrap,
duration: 500,
easing: 'ease-out',
from: slideOut ? anim.to : anim.from,
to: slideOut ? anim.from : anim.to
}));
wrapAnim.on('afteranimate', function() {
var el = Ext.fly(dom, '_anim');
el.setStyle(originalStyles);
if (slideOut) {
if (obj.useDisplay) {
el.setDisplayed(false);
} else {
el.hide();
}
}
if (wrap.dom) {
if (wrap.dom.parentNode) {
wrap.dom.parentNode.insertBefore(el.dom, wrap.dom);
} else {
wrapDomParentNode.appendChild(el.dom);
}
wrap.destroy();
}
if (restoreScroll) {
restoreScroll();
}
animScope.end();
});
if (listeners) {
wrapAnim.on(listeners);
}
};
me.animate({
duration: obj.duration ? Math.max(obj.duration, 500) * 2 : 1000,
listeners: {
beforeanimate: beforeAnim
}
});
return me;
},
slideOut: function(anchor, o) {
return this.slideIn(anchor, o, true);
},
swallowEvent: function(eventName, preventDefault) {
var me = this,
e, eLen,
fn = function(e) {
e.stopPropagation();
if (preventDefault) {
e.preventDefault();
}
};
if (Ext.isArray(eventName)) {
eLen = eventName.length;
for (e = 0; e < eLen; e++) {
me.on(eventName[e], fn);
}
return me;
}
me.on(eventName, fn);
return me;
},
switchOff: function(obj) {
var me = this,
dom = me.dom,
beforeAnim;
obj = Ext.applyIf(obj || {}, {
easing: 'ease-in',
duration: 500,
remove: false,
useDisplay: false
});
beforeAnim = function() {
var el = Ext.fly(dom, '_anim'),
animScope = this,
size = el.getSize(),
xy = el.getXY(),
keyframe, position;
el.clearOpacity();
el.clip();
position = el.getPositioning();
keyframe = new Ext.fx.Animator({
target: dom,
duration: obj.duration,
easing: obj.easing,
keyframes: {
33: {
opacity: 0.3
},
66: {
height: 1,
y: xy[1] + size.height / 2
},
100: {
width: 1,
x: xy[0] + size.width / 2
}
}
});
keyframe.on('afteranimate', function() {
var el = Ext.fly(dom, '_anim');
if (obj.useDisplay) {
el.setDisplayed(false);
} else {
el.hide();
}
el.clearOpacity();
el.setPositioning(position);
el.setSize(size);
animScope.end();
});
};
me.animate({
duration: (Math.max(obj.duration, 500) * 2),
listeners: {
beforeanimate: {
fn: beforeAnim
}
},
callback: obj.callback,
scope: obj.scope
});
return me;
},
syncContent: function(source) {
source = Ext.getDom(source);
var sourceNodes = source.childNodes,
sourceLen = sourceNodes.length,
dest = this.dom,
destNodes = dest.childNodes,
destLen = destNodes.length,
i, destNode, sourceNode, nodeType, newAttrs, attLen, attName,
elData = dest._extData;
if (Ext.isIE9m && dest.mergeAttributes) {
dest.mergeAttributes(source, true);
dest.src = source.src;
} else {
newAttrs = source.attributes;
attLen = newAttrs.length;
for (i = 0; i < attLen; i++) {
attName = newAttrs[i].name;
if (attName !== 'id') {
dest.setAttribute(attName, newAttrs[i].value);
}
}
}
if (elData) {
elData.isSynchronized = false;
}
if (sourceLen !== destLen) {
dest.innerHTML = source.innerHTML;
return;
}
for (i = 0; i < sourceLen; i++) {
sourceNode = sourceNodes[i];
destNode = destNodes[i];
nodeType = sourceNode.nodeType;
if (nodeType !== destNode.nodeType || (nodeType === 1 && sourceNode.tagName !== destNode.tagName)) {
dest.innerHTML = source.innerHTML;
return;
}
if (nodeType === 3) {
destNode.data = sourceNode.data;
} else
{
if (sourceNode.id && destNode.id !== sourceNode.id) {
destNode.id = sourceNode.id;
}
destNode.style.cssText = sourceNode.style.cssText;
destNode.className = sourceNode.className;
Ext.fly(destNode, '_syncContent').syncContent(sourceNode);
}
}
},
toggle: function(animate) {
var me = this;
me.setVisible(!me.isVisible(), me.anim(animate));
return me;
},
unmask: function() {
var me = this,
data = me.getData(),
maskEl = data.maskEl,
style;
if (maskEl) {
style = maskEl.dom.style;
if (style.clearExpression) {
style.clearExpression('width');
style.clearExpression('height');
}
if (maskEl) {
maskEl.destroy();
delete data.maskEl;
}
me.removeCls([
XMASKED,
XMASKEDRELATIVE
]);
}
me.restoreChildrenTabbableState();
if (me.dom !== DOC.body) {
me.restoreTabbableState();
}
},
unclip: function() {
var me = this,
data = me.getData(),
clip;
if (data[ISCLIPPED]) {
data[ISCLIPPED] = false;
clip = data[ORIGINALCLIP];
if (clip.o) {
me.setStyle(OVERFLOW, clip.o);
}
if (clip.x) {
me.setStyle(OVERFLOWX, clip.x);
}
if (clip.y) {
me.setStyle(OVERFLOWY, clip.y);
}
}
return me;
},
translate: function(x, y, z) {
if (Ext.supports.CssTransforms && !Ext.isIE9m) {
this.callParent(arguments);
} else {
if (x != null) {
this.dom.style.left = x + 'px';
}
if (y != null) {
this.dom.style.top = y + 'px';
}
}
},
unselectable: function() {
var me = this;
if (Ext.isOpera) {
me.dom.unselectable = 'on';
}
me.removeCls(Element.selectableCls);
me.addCls(Element.unselectableCls);
return me;
},
privates: {
needsTabIndex: function() {
var dom = this.dom,
nodeName, isFocusable;
if (dom) {
nodeName = dom.nodeName;
isFocusable = !!Ext.Element.naturallyFocusableTags[nodeName] || ((nodeName === 'A' || nodeName === 'LINK') && !!dom.href) || dom.getAttribute('tabindex') != null || dom.contentEditable === 'true';
return !isFocusable;
}
},
findTabbableElements: function(asDom, selector,
limit, backward) {
asDom = asDom != undefined ? asDom : true;
var me = this,
selection;
selection = me.selectTabbableElements(asDom, selector, limit, backward);
if (me.isTabbable()) {
selection.unshift(asDom ? me.dom : me);
}
return selection;
},
selectTabbableElements: function(asDom, selector,
limit, backward) {
var selection = [],
nodes, node, el, i, len, to, step, tabIndex;
asDom = asDom != undefined ? asDom : true;
nodes = this.dom.querySelectorAll(selector || Ext.Element.tabbableSelector);
len = nodes.length;
if (!len) {
return selection;
}
if (backward) {
i = len - 1;
to = 0;
step = -1;
} else {
i = 0;
to = len - 1;
step = 1;
}
for (; ; i += step) {
if ((step > 0 && i > to) || (step < 0 && i < to)) {
break;
}
node = nodes[i];
tabIndex = node.getAttribute('tabindex') - 0;
if (!(tabIndex < 0)) {
el = asDom ? Ext.fly(node) : Ext.get(node);
if (el.isTabbable()) {
selection.push(asDom ? node : el);
}
}
if (selection.length >= limit) {
return selection;
}
}
return selection;
},
selectFirstTabbableElement: function(asDom, selector) {
var els = this.selectTabbableElements(asDom, selector, 1, false);
return els[0];
},
selectLastTabbableElement: function(asDom, selector) {
var el = this.selectTabbableElements(true, selector, 1, true)[0];
return (asDom !== false) ? el : Ext.get(el);
},
saveTabbableState: function(attribute) {
var tabbableSavedFlagAttribute = Ext.Element.tabbableSavedFlagAttribute,
dom = this.dom;
if (dom.hasAttribute(tabbableSavedFlagAttribute)) {
return;
}
attribute = attribute || Ext.Element.tabbableSavedAttribute;
if (dom.hasAttribute('tabindex')) {
dom.setAttribute(attribute, dom.getAttribute('tabindex'));
} else
{
dom.setAttribute(attribute, 'none');
}
dom.setAttribute('tabindex', -1);
dom.setAttribute(tabbableSavedFlagAttribute, true);
return this;
},
restoreTabbableState: function(attribute) {
var tabbableSavedFlagAttribute = Ext.Element.tabbableSavedFlagAttribute,
dom = this.dom,
idx;
attribute = attribute || Ext.Element.tabbableSavedAttribute;
if (!dom.hasAttribute(tabbableSavedFlagAttribute) || !dom.hasAttribute(attribute)) {
return;
}
idx = dom.getAttribute(attribute);
if (idx === 'none') {
dom.removeAttribute('tabindex');
} else {
dom.setAttribute('tabindex', idx);
}
dom.removeAttribute(attribute);
dom.removeAttribute(tabbableSavedFlagAttribute);
return this;
},
saveChildrenTabbableState: function(attribute) {
var children, child, i, len;
if (this.dom) {
children = this.selectTabbableElements();
for (i = 0 , len = children.length; i < len; i++) {
child = Ext.fly(children[i]);
child.saveTabbableState(attribute);
}
}
return children;
},
restoreChildrenTabbableState: function(attribute, children) {
var child, i, len;
if (this.dom) {
attribute = attribute || Ext.Element.tabbableSavedAttribute;
children = children || this.dom.querySelectorAll('[' + attribute + ']');
for (i = 0 , len = children.length; i < len; i++) {
child = Ext.fly(children[i]);
child.restoreTabbableState(attribute);
}
}
return children;
}
},
deprecated: {
'4.0': {
methods: {
pause: function(ms) {
var me = this;
Ext.fx.Manager.setFxDefaults(me.id, {
delay: ms
});
return me;
},
scale: function(w, h, o) {
this.animate(Ext.apply({}, o, {
width: w,
height: h
}));
return this;
},
shift: function(config) {
this.animate(config);
return this;
}
}
},
'4.2': {
methods: {
moveTo: function(x, y, animate) {
return this.setXY([
x,
y
], animate);
},
setBounds: function(x, y, width, height, animate) {
return this.setBox({
x: x,
y: y,
width: width,
height: height
}, animate);
},
setLeftTop: function(left, top) {
var me = this,
style = me.dom.style;
style.left = Element.addUnits(left);
style.top = Element.addUnits(top);
if (me.shadow || me.shim) {
me.syncUnderlays();
}
return me;
},
setLocation: function(x, y, animate) {
return this.setXY([
x,
y
], animate);
}
}
},
'5.0': {
methods: {
getAttributeNS: function(namespace, name) {
return this.getAttribute(name, namespace);
},
getCenterXY: function() {
return this.getAlignToXY(DOC, 'c-c');
},
getComputedHeight: function() {
return Math.max(this.dom.offsetHeight, this.dom.clientHeight) || parseFloat(this.getStyle(HEIGHT)) || 0;
},
getComputedWidth: function() {
return Math.max(this.dom.offsetWidth, this.dom.clientWidth) || parseFloat(this.getStyle(WIDTH)) || 0;
},
getStyleSize: function() {
var me = this,
d = this.dom,
isDoc = (d === DOC || d === DOC.body),
s, w, h;
if (isDoc) {
return {
width: Element.getViewportWidth(),
height: Element.getViewportHeight()
};
}
s = me.getStyle([
'height',
'width'
], true);
if (s.width && s.width !== 'auto') {
w = parseFloat(s.width);
}
if (s.height && s.height !== 'auto') {
h = parseFloat(s.height);
}
return {
width: w || me.getWidth(true),
height: h || me.getHeight(true)
};
},
isBorderBox: function() {
return true;
},
isDisplayed: function() {
return !this.isStyle('display', 'none');
},
focusable: 'isFocusable'
}
}
}
};
})(), function() {
var Element = Ext.dom.Element,
proto = Element.prototype,
useDocForId = !Ext.isIE8,
DOC = document,
view = DOC.defaultView,
opacityRe = /alpha\(opacity=(.*)\)/i,
trimRe = /^\s+|\s+$/g,
styleHooks = proto.styleHooks,
supports = Ext.supports,
verticalStyleHooks90, verticalStyleHooks270, edges, k, edge, borderWidth, getBorderWidth;
proto._init(Element);
delete proto._init;
Ext.plainTableCls = Ext.baseCSSPrefix + 'table-plain';
Ext.plainListCls = Ext.baseCSSPrefix + 'list-plain';
if (Ext.CompositeElementLite) {
Ext.CompositeElementLite.importElementMethods();
}
styleHooks.opacity = {
name: 'opacity',
afterSet: function(dom, value, el) {
var shadow = el.shadow;
if (shadow) {
shadow.setOpacity(value);
}
}
};
if (!supports.Opacity && Ext.isIE) {
Ext.apply(styleHooks.opacity, {
get: function(dom) {
var filter = dom.style.filter,
match, opacity;
if (filter.match) {
match = filter.match(opacityRe);
if (match) {
opacity = parseFloat(match[1]);
if (!isNaN(opacity)) {
return opacity ? opacity / 100 : 0;
}
}
}
return 1;
},
set: function(dom, value) {
var style = dom.style,
val = style.filter.replace(opacityRe, '').replace(trimRe, '');
style.zoom = 1;
if (typeof (value) === 'number' && value >= 0 && value < 1) {
value *= 100;
style.filter = val + (val.length ? ' ' : '') + 'alpha(opacity=' + value + ')';
} else {
style.filter = val;
}
}
});
}
if (!supports.matchesSelector) {
var simpleSelectorRe = /^([a-z]+|\*)?(?:\.([a-z][a-z\-_0-9]*))?$/i,
dashRe = /\-/g,
fragment,
classMatcher = function(tag, cls) {
var classRe = new RegExp('(?:^|\\s+)' + cls.replace(dashRe, '\\-') + '(?:\\s+|$)');
if (tag && tag !== '*') {
tag = tag.toUpperCase();
return function(el) {
return el.tagName === tag && classRe.test(el.className);
};
}
return function(el) {
return classRe.test(el.className);
};
},
tagMatcher = function(tag) {
tag = tag.toUpperCase();
return function(el) {
return el.tagName === tag;
};
},
cache = {};
proto.matcherCache = cache;
proto.is = function(selector) {
if (!selector) {
return true;
}
var dom = this.dom,
cls, match, testFn, root, isOrphan, is, tag;
if (dom.nodeType !== 1) {
return false;
}
if (!(testFn = Ext.isFunction(selector) ? selector : cache[selector])) {
if (!(match = selector.match(simpleSelectorRe))) {
root = dom.parentNode;
if (!root) {
isOrphan = true;
root = fragment || (fragment = DOC.createDocumentFragment());
fragment.appendChild(dom);
}
is = Ext.Array.indexOf(Ext.fly(root, '_is').query(selector), dom) !== -1;
if (isOrphan) {
fragment.removeChild(dom);
}
return is;
}
tag = match[1];
cls = match[2];
cache[selector] = testFn = cls ? classMatcher(tag, cls) : tagMatcher(tag);
}
return testFn(dom);
};
}
if (!view || !view.getComputedStyle) {
proto.getStyle = function(property, inline) {
var me = this,
dom = me.dom,
multiple = typeof property !== 'string',
prop = property,
props = prop,
len = 1,
isInline = inline,
styleHooks = me.styleHooks,
camel, domStyle, values, hook, out, style, i;
if (multiple) {
values = {};
prop = props[0];
i = 0;
if (!(len = props.length)) {
return values;
}
}
if (!dom || dom.documentElement) {
return values || '';
}
domStyle = dom.style;
if (inline) {
style = domStyle;
} else {
style = dom.currentStyle;
if (!style) {
isInline = true;
style = domStyle;
}
}
do {
hook = styleHooks[prop];
if (!hook) {
styleHooks[prop] = hook = {
name: Element.normalize(prop)
};
}
if (hook.get) {
out = hook.get(dom, me, isInline, style);
} else {
camel = hook.name;
out = style[camel];
}
if (!multiple) {
return out;
}
values[prop] = out;
prop = props[++i];
} while (i < len);
return values;
};
}
if (Ext.isIE8) {
getBorderWidth = function(dom, el, inline, style) {
if (style[this.styleName] === 'none') {
return '0px';
}
return style[this.name];
};
edges = [
'Top',
'Right',
'Bottom',
'Left'
];
k = edges.length;
while (k--) {
edge = edges[k];
borderWidth = 'border' + edge + 'Width';
styleHooks['border-' + edge.toLowerCase() + '-width'] = styleHooks[borderWidth] = {
name: borderWidth,
styleName: 'border' + edge + 'Style',
get: getBorderWidth
};
}
}
Ext.apply(Ext, {
enableGarbageCollector: true,
isBorderBox: true,
useShims: false,
getDetachedBody: function() {
var detachedEl = Ext.detachedBodyEl;
if (!detachedEl) {
detachedEl = DOC.createElement('div');
Ext.detachedBodyEl = detachedEl = new Ext.dom.Fly(detachedEl);
detachedEl.isDetachedBody = true;
}
return detachedEl;
},
getElementById: function(id) {
var el = DOC.getElementById(id),
detachedBodyEl;
if (!el && (detachedBodyEl = Ext.detachedBodyEl)) {
el = detachedBodyEl.dom.querySelector(Ext.makeIdSelector(id));
}
return el;
},
addBehaviors: function(o) {
if (!Ext.isReady) {
Ext.onInternalReady(function() {
Ext.addBehaviors(o);
});
} else {
var cache = {},
parts, b, s;
for (b in o) {
if ((parts = b.split('@'))[1]) {
s = parts[0];
if (!cache[s]) {
cache[s] = Ext.fly(document).select(s, true);
}
cache[s].on(parts[1], o[b]);
}
}
cache = null;
}
}
});
if (Ext.isIE9m) {
Ext.getElementById = function(id) {
var el = DOC.getElementById(id),
detachedBodyEl;
if (!el && (detachedBodyEl = Ext.detachedBodyEl)) {
el = detachedBodyEl.dom.all[id];
}
return el;
};
proto.getById = function(id, asDom) {
var dom = this.dom,
ret = null,
entry, el;
if (dom) {
el = (useDocForId && DOC.getElementById(id)) || dom.all[id];
if (el) {
if (asDom) {
ret = el;
} else {
entry = Ext.cache[id];
if (entry) {
if (entry.skipGarbageCollection || !Ext.isGarbage(entry.dom)) {
ret = entry;
} else {
Ext.Error.raise("Stale Element with id '" + el.id + "' found in Element cache. " + "Make sure to clean up Element instances using destroy()");
entry.destroy();
}
}
ret = ret || new Ext.Element(el);
}
}
}
return ret;
};
} else if (!DOC.querySelector) {
Ext.getDetachedBody = Ext.getBody;
Ext.getElementById = function(id) {
return DOC.getElementById(id);
};
proto.getById = function(id, asDom) {
var dom = DOC.getElementById(id);
return asDom ? dom : (dom ? Ext.get(dom) : null);
};
}
if (Ext.isIE && !(Ext.isIE9p && DOC.documentMode >= 9)) {
proto.getAttribute = function(name, ns) {
var d = this.dom,
type;
if (ns) {
type = typeof d[ns + ":" + name];
if (type !== 'undefined' && type !== 'unknown') {
return d[ns + ":" + name] || null;
}
return null;
}
if (name === "for") {
name = "htmlFor";
}
return d[name] || null;
};
}
Ext.onInternalReady(function() {
var transparentRe = /^(?:transparent|(?:rgba[(](?:\s*\d+\s*[,]){3}\s*0\s*[)]))$/i,
bodyCls = [],
origSetWidth = proto.setWidth,
origSetHeight = proto.setHeight,
origSetSize = proto.setSize,
pxRe = /^\d+(?:\.\d*)?px$/i,
colorStyles, i, name, camel;
if (supports.FixedTableWidthBug) {
styleHooks.width = {
name: 'width',
set: function(dom, value, el) {
var style = dom.style,
needsFix = el._needsTableWidthFix,
origDisplay = style.display;
if (needsFix) {
style.display = 'none';
}
style.width = value;
if (needsFix) {
dom.scrollWidth;
style.display = origDisplay;
}
}
};
proto.setWidth = function(width, animate) {
var me = this,
dom = me.dom,
style = dom.style,
needsFix = me._needsTableWidthFix,
origDisplay = style.display;
if (needsFix && !animate) {
style.display = 'none';
}
origSetWidth.call(me, width, animate);
if (needsFix && !animate) {
dom.scrollWidth;
style.display = origDisplay;
}
return me;
};
proto.setSize = function(width, height, animate) {
var me = this,
dom = me.dom,
style = dom.style,
needsFix = me._needsTableWidthFix,
origDisplay = style.display;
if (needsFix && !animate) {
style.display = 'none';
}
origSetSize.call(me, width, height, animate);
if (needsFix && !animate) {
dom.scrollWidth;
style.display = origDisplay;
}
return me;
};
}
if (Ext.isIE8) {
styleHooks.height = {
name: 'height',
set: function(dom, value, el) {
var component = el.component,
frameInfo, frameBodyStyle;
if (component && component._syncFrameHeight && this === component.el) {
frameBodyStyle = component.frameBody.dom.style;
if (pxRe.test(value)) {
frameInfo = component.getFrameInfo();
if (frameInfo) {
frameBodyStyle.height = (parseInt(value, 10) - frameInfo.height) + 'px';
}
} else if (!value || value === 'auto') {
frameBodyStyle.height = '';
}
}
dom.style.height = value;
}
};
proto.setHeight = function(height, animate) {
var component = this.component,
frameInfo, frameBodyStyle;
if (component && component._syncFrameHeight && this === component.el) {
frameBodyStyle = component.frameBody.dom.style;
if (!height || height === 'auto') {
frameBodyStyle.height = '';
} else {
frameInfo = component.getFrameInfo();
if (frameInfo) {
frameBodyStyle.height = (height - frameInfo.height) + 'px';
}
}
}
return origSetHeight.call(this, height, animate);
};
proto.setSize = function(width, height, animate) {
var component = this.component,
frameInfo, frameBodyStyle;
if (component && component._syncFrameHeight && this === component.el) {
frameBodyStyle = component.frameBody.dom.style;
if (!height || height === 'auto') {
frameBodyStyle.height = '';
} else {
frameInfo = component.getFrameInfo();
if (frameInfo) {
frameBodyStyle.height = (height - frameInfo.height) + 'px';
}
}
}
return origSetSize.call(this, width, height, animate);
};
}
Ext.getDoc().on('selectstart', function(ev, dom) {
var selectableCls = Element.selectableCls,
unselectableCls = Element.unselectableCls,
tagName = dom && dom.tagName;
tagName = tagName && tagName.toLowerCase();
if (tagName === 'input' || tagName === 'textarea') {
return;
}
while (dom && dom.nodeType === 1 && dom !== DOC.documentElement) {
var el = Ext.fly(dom);
if (el.hasCls(selectableCls)) {
return;
}
if (el.hasCls(unselectableCls)) {
ev.stopEvent();
return;
}
dom = dom.parentNode;
}
});
function fixTransparent(dom, el, inline, style) {
var value = style[this.name] || '';
return transparentRe.test(value) ? 'transparent' : value;
}
function makeSelectionRestoreFn(activeEl, start, end) {
return function() {
activeEl.selectionStart = start;
activeEl.selectionEnd = end;
};
}
function getRightMarginFixCleaner(target) {
var hasInputBug = supports.DisplayChangeInputSelectionBug,
hasTextAreaBug = supports.DisplayChangeTextAreaSelectionBug,
activeEl, tag, start, end;
if (hasInputBug || hasTextAreaBug) {
activeEl = Element.getActiveElement();
tag = activeEl && activeEl.tagName;
if ((hasTextAreaBug && tag === 'TEXTAREA') || (hasInputBug && tag === 'INPUT' && activeEl.type === 'text')) {
if (Ext.fly(target).isAncestor(activeEl)) {
start = activeEl.selectionStart;
end = activeEl.selectionEnd;
if (Ext.isNumber(start) && Ext.isNumber(end)) {
return makeSelectionRestoreFn(activeEl, start, end);
}
}
}
}
return Ext.emptyFn;
}
function fixRightMargin(dom, el, inline, style) {
var result = style.marginRight,
domStyle, display;
if (result !== '0px') {
domStyle = dom.style;
display = domStyle.display;
domStyle.display = 'inline-block';
result = (inline ? style : dom.ownerDocument.defaultView.getComputedStyle(dom, null)).marginRight;
domStyle.display = display;
}
return result;
}
function fixRightMarginAndInputFocus(dom, el, inline, style) {
var result = style.marginRight,
domStyle, cleaner, display;
if (result !== '0px') {
domStyle = dom.style;
cleaner = getRightMarginFixCleaner(dom);
display = domStyle.display;
domStyle.display = 'inline-block';
result = (inline ? style : dom.ownerDocument.defaultView.getComputedStyle(dom, '')).marginRight;
domStyle.display = display;
cleaner();
}
return result;
}
if (!supports.RightMargin) {
styleHooks.marginRight = styleHooks['margin-right'] = {
name: 'marginRight',
get: (supports.DisplayChangeInputSelectionBug || supports.DisplayChangeTextAreaSelectionBug) ? fixRightMarginAndInputFocus : fixRightMargin
};
}
if (!supports.TransparentColor) {
colorStyles = [
'background-color',
'border-color',
'color',
'outline-color'
];
for (i = colorStyles.length; i--; ) {
name = colorStyles[i];
camel = Element.normalize(name);
styleHooks[name] = styleHooks[camel] = {
name: camel,
get: fixTransparent
};
}
}
proto.verticalStyleHooks90 = verticalStyleHooks90 = Ext.Object.chain(styleHooks);
proto.verticalStyleHooks270 = verticalStyleHooks270 = Ext.Object.chain(styleHooks);
verticalStyleHooks90.width = styleHooks.height || {
name: 'height'
};
verticalStyleHooks90.height = styleHooks.width || {
name: 'width'
};
verticalStyleHooks90['margin-top'] = {
name: 'marginLeft'
};
verticalStyleHooks90['margin-right'] = {
name: 'marginTop'
};
verticalStyleHooks90['margin-bottom'] = {
name: 'marginRight'
};
verticalStyleHooks90['margin-left'] = {
name: 'marginBottom'
};
verticalStyleHooks90['padding-top'] = {
name: 'paddingLeft'
};
verticalStyleHooks90['padding-right'] = {
name: 'paddingTop'
};
verticalStyleHooks90['padding-bottom'] = {
name: 'paddingRight'
};
verticalStyleHooks90['padding-left'] = {
name: 'paddingBottom'
};
verticalStyleHooks90['border-top'] = {
name: 'borderLeft'
};
verticalStyleHooks90['border-right'] = {
name: 'borderTop'
};
verticalStyleHooks90['border-bottom'] = {
name: 'borderRight'
};
verticalStyleHooks90['border-left'] = {
name: 'borderBottom'
};
verticalStyleHooks270.width = styleHooks.height || {
name: 'height'
};
verticalStyleHooks270.height = styleHooks.width || {
name: 'width'
};
verticalStyleHooks270['margin-top'] = {
name: 'marginRight'
};
verticalStyleHooks270['margin-right'] = {
name: 'marginBottom'
};
verticalStyleHooks270['margin-bottom'] = {
name: 'marginLeft'
};
verticalStyleHooks270['margin-left'] = {
name: 'marginTop'
};
verticalStyleHooks270['padding-top'] = {
name: 'paddingRight'
};
verticalStyleHooks270['padding-right'] = {
name: 'paddingBottom'
};
verticalStyleHooks270['padding-bottom'] = {
name: 'paddingLeft'
};
verticalStyleHooks270['padding-left'] = {
name: 'paddingTop'
};
verticalStyleHooks270['border-top'] = {
name: 'borderRight'
};
verticalStyleHooks270['border-right'] = {
name: 'borderBottom'
};
verticalStyleHooks270['border-bottom'] = {
name: 'borderLeft'
};
verticalStyleHooks270['border-left'] = {
name: 'borderTop'
};
if (!Ext.scopeCss) {
bodyCls.push(Ext.baseCSSPrefix + 'body');
}
if (supports.Touch) {
bodyCls.push(Ext.baseCSSPrefix + 'touch');
}
if (Ext.isIE && Ext.isIE9m) {
bodyCls.push(Ext.baseCSSPrefix + 'ie', Ext.baseCSSPrefix + 'ie9m');
bodyCls.push(Ext.baseCSSPrefix + 'ie8p');
if (Ext.isIE8) {
bodyCls.push(Ext.baseCSSPrefix + 'ie8');
} else {
bodyCls.push(Ext.baseCSSPrefix + 'ie9', Ext.baseCSSPrefix + 'ie9p');
}
if (Ext.isIE8m) {
bodyCls.push(Ext.baseCSSPrefix + 'ie8m');
}
}
if (Ext.isIE10) {
bodyCls.push(Ext.baseCSSPrefix + 'ie10');
}
if (Ext.isIE11) {
bodyCls.push(Ext.baseCSSPrefix + 'ie11');
}
if (Ext.isGecko) {
bodyCls.push(Ext.baseCSSPrefix + 'gecko');
}
if (Ext.isOpera) {
bodyCls.push(Ext.baseCSSPrefix + 'opera');
}
if (Ext.isOpera12m) {
bodyCls.push(Ext.baseCSSPrefix + 'opera12m');
}
if (Ext.isWebKit) {
bodyCls.push(Ext.baseCSSPrefix + 'webkit');
}
if (Ext.isSafari) {
bodyCls.push(Ext.baseCSSPrefix + 'safari');
}
if (Ext.isChrome) {
bodyCls.push(Ext.baseCSSPrefix + 'chrome');
}
if (Ext.isMac) {
bodyCls.push(Ext.baseCSSPrefix + 'mac');
}
if (Ext.isLinux) {
bodyCls.push(Ext.baseCSSPrefix + 'linux');
}
if (!supports.CSS3BorderRadius) {
bodyCls.push(Ext.baseCSSPrefix + 'nbr');
}
if (!supports.CSS3LinearGradient) {
bodyCls.push(Ext.baseCSSPrefix + 'nlg');
}
if (supports.Touch) {
bodyCls.push(Ext.baseCSSPrefix + 'touch');
}
Ext.getBody().addCls(bodyCls);
}, null, {
priority: 1500
});
});
Ext.define('Ext.GlobalEvents', {
extend: 'Ext.mixin.Observable',
alternateClassName: 'Ext.globalEvents',
requires: [
'Ext.dom.Element'
],
observableType: 'global',
singleton: true,
resizeBuffer: 100,
idleEventMask: {
mousemove: 1,
touchmove: 1,
pointermove: 1,
MSPointerMove: 1,
unload: 1
},
constructor: function() {
var me = this;
me.callParent();
Ext.onInternalReady(function() {
me.attachListeners();
});
},
attachListeners: function() {
Ext.get(window).on('resize', this.fireResize, this, {
buffer: this.resizeBuffer
});
},
fireResize: function() {
var me = this,
Element = Ext.Element,
w = Element.getViewportWidth(),
h = Element.getViewportHeight();
if (me.curHeight !== h || me.curWidth !== w) {
me.curHeight = h;
me.curWidth = w;
me.fireEvent('resize', w, h);
}
}
}, function(GlobalEvents) {
Ext.on = function() {
return GlobalEvents.addListener.apply(GlobalEvents, arguments);
};
Ext.un = function() {
return GlobalEvents.removeListener.apply(GlobalEvents, arguments);
};
});
Ext.define('Ext.overrides.GlobalEvents', {
override: 'Ext.GlobalEvents',
attachListeners: function() {
this.callParent();
Ext.getDoc().on('mousedown', this.fireMouseDown, this);
},
fireMouseDown: function(e) {
this.fireEvent('mousedown', e);
},
deprecated: {
5: {
methods: {
addListener: function(ename, fn, scope, options, order, caller, eventOptions) {
var name, readyFn;
if (ename === 'ready') {
readyFn = fn;
} else if (typeof ename !== 'string') {
for (name in ename) {
if (name === 'ready') {
readyFn = ename[name];
}
}
}
if (readyFn) {
Ext.log.warn("Ext.on('ready', fn) is deprecated. Please use Ext.onReady(fn) instead.");
Ext.onReady(readyFn);
}
this.callParent([
ename,
fn,
scope,
options,
order,
caller,
eventOptions
]);
}
}
}
}
});
Ext.USE_NATIVE_JSON = false;
Ext.JSON = (new (function() {
var me = this,
hasNative = window.JSON && JSON.toString() === '[object JSON]',
useHasOwn = !!{}.hasOwnProperty,
pad = function(n) {
return n < 10 ? "0" + n : n;
},
doDecode = function(json) {
return eval("(" + json + ')');
},
doEncode = function(o, newline) {
if (o === null || o === undefined) {
return "null";
} else if (Ext.isDate(o)) {
return me.encodeDate(o);
} else if (Ext.isString(o)) {
if (Ext.isMSDate(o)) {
return me.encodeMSDate(o);
} else {
return me.encodeString(o);
}
} else if (typeof o === "number") {
return isFinite(o) ? String(o) : "null";
} else if (Ext.isBoolean(o)) {
return String(o);
}
else if (o.toJSON) {
return o.toJSON();
} else if (Ext.isArray(o)) {
return encodeArray(o, newline);
} else if (Ext.isObject(o)) {
return encodeObject(o, newline);
} else if (typeof o === "function") {
return "null";
}
return 'undefined';
},
m = {
"\b": '\\b',
"\t": '\\t',
"\n": '\\n',
"\f": '\\f',
"\r": '\\r',
'"': '\\"',
"\\": '\\\\',
'\v': '\\u000b'
},
charToReplace = /[\\\"\x00-\x1f\x7f-\uffff]/g,
encodeString = function(s) {
return '"' + s.replace(charToReplace, function(a) {
var c = m[a];
return typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"';
},
encodeMSDate = function(o) {
return '"' + o + '"';
},
encodeArrayPretty = function(o, newline) {
var len = o.length,
cnewline = newline + ' ',
sep = ',' + cnewline,
a = [
"[",
cnewline
],
i;
for (i = 0; i < len; i += 1) {
a.push(me.encodeValue(o[i], cnewline), sep);
}
a[a.length - 1] = newline + ']';
return a.join('');
},
encodeObjectPretty = function(o, newline) {
var cnewline = newline + ' ',
sep = ',' + cnewline,
a = [
"{",
cnewline
],
i, val;
for (i in o) {
val = o[i];
if (!useHasOwn || o.hasOwnProperty(i)) {
if (typeof val === 'function' || val === undefined) {
continue;
}
a.push(me.encodeValue(i) + ': ' + me.encodeValue(val, cnewline), sep);
}
}
a[a.length - 1] = newline + '}';
return a.join('');
},
encodeArray = function(o, newline) {
if (newline) {
return encodeArrayPretty(o, newline);
}
var a = [
"[",
""
],
len = o.length,
i;
for (i = 0; i < len; i += 1) {
a.push(me.encodeValue(o[i]), ',');
}
a[a.length - 1] = ']';
return a.join("");
},
encodeObject = function(o, newline) {
if (newline) {
return encodeObjectPretty(o, newline);
}
var a = [
"{",
""
],
i, val;
for (i in o) {
val = o[i];
if (!useHasOwn || o.hasOwnProperty(i)) {
if (typeof val === 'function' || val === undefined) {
continue;
}
a.push(me.encodeValue(i), ":", me.encodeValue(val), ',');
}
}
a[a.length - 1] = '}';
return a.join("");
};
me.encodeString = encodeString;
me.encodeValue = doEncode;
me.encodeDate = function(o) {
return '"' + o.getFullYear() + "-" + pad(o.getMonth() + 1) + "-" + pad(o.getDate()) + "T" + pad(o.getHours()) + ":" + pad(o.getMinutes()) + ":" + pad(o.getSeconds()) + '"';
};
me.encode = function(o) {
if (hasNative && Ext.USE_NATIVE_JSON) {
return JSON.stringify(o);
}
return me.encodeValue(o);
};
me.decode = function(json, safe) {
try {
if (hasNative && Ext.USE_NATIVE_JSON) {
return JSON.parse(json);
}
return doDecode(json);
} catch (e) {
if (safe) {
return null;
}
Ext.Error.raise({
sourceClass: "Ext.JSON",
sourceMethod: "decode",
msg: "You're trying to decode an invalid JSON String: " + json
});
}
};
me.encodeMSDate = encodeMSDate;
//@private Alias for backwards compatibility
if (!Ext.util) {
Ext.util = {};
}
Ext.util.JSON = me;
Ext.encode = me.encode;
Ext.decode = me.decode;
})());
Ext.define('Ext.util.Format', function() {
var me;
return {
requires: [
'Ext.Error',
'Ext.Number',
'Ext.String',
'Ext.Date'
],
singleton: true,
defaultDateFormat: 'm/d/Y',
thousandSeparator: ',',
decimalSeparator: '.',
currencyPrecision: 2,
currencySign: '$',
percentSign: '%',
currencyAtEnd: false,
stripTagsRe: /<\/?[^>]+>/gi,
stripScriptsRe: /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,
nl2brRe: /\r?\n/g,
hashRe: /#+$/,
allHashes: /^#+$/,
formatPattern: /[\d,\.#]+/,
formatCleanRe: /[^\d\.#]/g,
I18NFormatCleanRe: null,
formatFns: {},
constructor: function() {
me = this;
},
undef: function(value) {
return value !== undefined ? value : "";
},
defaultValue: function(value, defaultValue) {
return value !== undefined && value !== '' ? value : defaultValue;
},
substr: 'ab'.substr(-1) != 'b' ? function(value, start, length) {
var str = String(value);
return (start < 0) ? str.substr(Math.max(str.length + start, 0), length) : str.substr(start, length);
} : function(value, start, length) {
return String(value).substr(start, length);
},
lowercase: function(value) {
return String(value).toLowerCase();
},
uppercase: function(value) {
return String(value).toUpperCase();
},
usMoney: function(v) {
return me.currency(v, '$', 2);
},
currency: function(v, currencySign, decimals, end) {
var negativeSign = '',
format = ",0",
i = 0;
v = v - 0;
if (v < 0) {
v = -v;
negativeSign = '-';
}
decimals = Ext.isDefined(decimals) ? decimals : me.currencyPrecision;
format += (decimals > 0 ? '.' : '');
for (; i < decimals; i++) {
format += '0';
}
v = me.number(v, format);
if ((end || me.currencyAtEnd) === true) {
return Ext.String.format("{0}{1}{2}", negativeSign, v, currencySign || me.currencySign);
} else {
return Ext.String.format("{0}{1}{2}", negativeSign, currencySign || me.currencySign, v);
}
},
date: function(v, format) {
if (!v) {
return "";
}
if (!Ext.isDate(v)) {
v = new Date(Date.parse(v));
}
return Ext.Date.dateFormat(v, format || Ext.Date.defaultFormat);
},
dateRenderer: function(format) {
return function(v) {
return me.date(v, format);
};
},
hex: function(value, digits) {
var s = parseInt(value || 0, 10).toString(16);
if (digits) {
if (digits < 0) {
digits = -digits;
if (s.length > digits) {
s = s.substring(s.length - digits);
}
}
while (s.length < digits) {
s = '0' + s;
}
}
return s;
},
or: function(value, orValue) {
return value || orValue;
},
pick: function(value, firstValue, secondValue) {
if (Ext.isNumber(value)) {
var ret = arguments[value + 1];
if (ret) {
return ret;
}
}
return value ? secondValue : firstValue;
},
stripTags: function(v) {
return !v ? v : String(v).replace(me.stripTagsRe, "");
},
stripScripts: function(v) {
return !v ? v : String(v).replace(me.stripScriptsRe, "");
},
fileSize: (function() {
var byteLimit = 1024,
kbLimit = 1048576,
mbLimit = 1073741824;
return function(size) {
var out;
if (size < byteLimit) {
if (size === 1) {
out = '1 byte';
} else {
out = size + ' bytes';
}
} else if (size < kbLimit) {
out = (Math.round(((size * 10) / byteLimit)) / 10) + ' KB';
} else if (size < mbLimit) {
out = (Math.round(((size * 10) / kbLimit)) / 10) + ' MB';
} else {
out = (Math.round(((size * 10) / mbLimit)) / 10) + ' GB';
}
return out;
};
})(),
math: (function() {
var fns = {};
return function(v, a) {
if (!fns[a]) {
fns[a] = Ext.functionFactory('v', 'return v ' + a + ';');
}
return fns[a](v);
};
}()),
round: function(value, precision) {
var result = Number(value);
if (typeof precision === 'number') {
precision = Math.pow(10, precision);
result = Math.round(value * precision) / precision;
} else if (precision === undefined) {
result = Math.round(result);
}
return result;
},
number: function(v, formatString) {
if (!formatString) {
return v;
}
if (isNaN(v)) {
return '';
}
var formatFn = me.formatFns[formatString];
if (!formatFn) {
var originalFormatString = formatString,
comma = me.thousandSeparator,
decimalSeparator = me.decimalSeparator,
precision = 0,
trimPart = '',
hasComma, splitFormat, extraChars, trimTrailingZeroes, code, len;
if (formatString.substr(formatString.length - 2) === '/i') {
if (!me.I18NFormatCleanRe || me.lastDecimalSeparator !== decimalSeparator) {
me.I18NFormatCleanRe = new RegExp('[^\\d\\' + decimalSeparator + ']', 'g');
me.lastDecimalSeparator = decimalSeparator;
}
formatString = formatString.substr(0, formatString.length - 2);
hasComma = formatString.indexOf(comma) !== -1;
splitFormat = formatString.replace(me.I18NFormatCleanRe, '').split(decimalSeparator);
} else {
hasComma = formatString.indexOf(',') !== -1;
splitFormat = formatString.replace(me.formatCleanRe, '').split('.');
}
extraChars = formatString.replace(me.formatPattern, '');
if (splitFormat.length > 2) {
Ext.Error.raise({
sourceClass: "Ext.util.Format",
sourceMethod: "number",
value: v,
formatString: formatString,
msg: "Invalid number format, should have no more than 1 decimal"
});
} else if (splitFormat.length === 2) {
precision = splitFormat[1].length;
trimTrailingZeroes = splitFormat[1].match(me.hashRe);
if (trimTrailingZeroes) {
len = trimTrailingZeroes[0].length;
trimPart = 'trailingZeroes=new RegExp(Ext.String.escapeRegex(utilFormat.decimalSeparator) + "*0{0,' + len + '}$")';
}
}
code = [
'var utilFormat=Ext.util.Format,extNumber=Ext.Number,neg,absVal,fnum,parts' + (hasComma ? ',thousandSeparator,thousands=[],j,n,i' : '') + (extraChars ? ',formatString="' + formatString + '",formatPattern=/[\\d,\\.#]+/' : '') + ',trailingZeroes;' + 'return function(v){' + 'if(typeof v!=="number"&&isNaN(v=extNumber.from(v,NaN)))return"";' + 'neg=v<0;',
'absVal=Math.abs(v);',
'fnum=Ext.Number.toFixed(absVal, ' + precision + ');',
trimPart,
';'
];
if (hasComma) {
if (precision) {
code[code.length] = 'parts=fnum.split(".");';
code[code.length] = 'fnum=parts[0];';
}
code[code.length] = 'if(absVal>=1000) {';
code[code.length] = 'thousandSeparator=utilFormat.thousandSeparator;' + 'thousands.length=0;' + 'j=fnum.length;' + 'n=fnum.length%3||3;' + 'for(i=0;i<j;i+=n){' + 'if(i!==0){' + 'n=3;' + '}' + 'thousands[thousands.length]=fnum.substr(i,n);' + '}' + 'fnum=thousands.join(thousandSeparator);' + '}';
if (precision) {
code[code.length] = 'fnum += utilFormat.decimalSeparator+parts[1];';
}
} else if (precision) {
code[code.length] = 'if(utilFormat.decimalSeparator!=="."){' + 'parts=fnum.split(".");' + 'fnum=parts[0]+utilFormat.decimalSeparator+parts[1];' + '}';
}
code[code.length] = 'if(neg&&fnum!=="' + (precision ? '0.' + Ext.String.repeat('0', precision) : '0') + '") { fnum="-"+fnum; }';
if (trimTrailingZeroes) {
code[code.length] = 'fnum=fnum.replace(trailingZeroes,"");';
}
code[code.length] = 'return ';
if (extraChars) {
code[code.length] = 'formatString.replace(formatPattern, fnum);';
} else {
code[code.length] = 'fnum;';
}
code[code.length] = '};';
formatFn = me.formatFns[originalFormatString] = Ext.functionFactory('Ext', code.join(''))(Ext);
}
return formatFn(v);
},
numberRenderer: function(format) {
return function(v) {
return me.number(v, format);
};
},
percent: function(value, formatString) {
return me.number(value * 100, formatString || '0') + me.percentSign;
},
attributes: function(attributes) {
if (typeof attributes === 'object') {
var result = [],
name;
for (name in attributes) {
if (attributes.hasOwnProperty(name)) {
result.push(name, '="', name === 'style' ? Ext.DomHelper.generateStyles(attributes[name], null, true) : Ext.htmlEncode(attributes[name]), '" ');
}
}
attributes = result.join('');
}
return attributes || '';
},
plural: function(v, s, p) {
return v + ' ' + (v === 1 ? s : (p ? p : s + 's'));
},
nl2br: function(v) {
return Ext.isEmpty(v) ? '' : v.replace(me.nl2brRe, '<br/>');
},
capitalize: Ext.String.capitalize,
uncapitalize: Ext.String.uncapitalize,
ellipsis: Ext.String.ellipsis,
escape: Ext.String.escape,
escapeRegex: Ext.String.escapeRegex,
htmlDecode: Ext.String.htmlDecode,
htmlEncode: Ext.String.htmlEncode,
leftPad: Ext.String.leftPad,
toggle: Ext.String.toggle,
trim: Ext.String.trim,
parseBox: function(box) {
box = box || 0;
if (typeof box === 'number') {
return {
top: box,
right: box,
bottom: box,
left: box
};
}
var parts = box.split(' '),
ln = parts.length;
if (ln === 1) {
parts[1] = parts[2] = parts[3] = parts[0];
} else if (ln === 2) {
parts[2] = parts[0];
parts[3] = parts[1];
} else if (ln === 3) {
parts[3] = parts[1];
}
return {
top: parseInt(parts[0], 10) || 0,
right: parseInt(parts[1], 10) || 0,
bottom: parseInt(parts[2], 10) || 0,
left: parseInt(parts[3], 10) || 0
};
}
};
});
Ext.define('Ext.Template', {
requires: [
'Ext.util.Format'
],
inheritableStatics: {
from: function(el, config) {
el = Ext.getDom(el);
return new this(el.value || el.innerHTML, config || '');
}
},
useEval: Ext.isGecko,
constructor: function(html) {
var me = this,
args = arguments,
buffer = [],
i,
length = args.length,
value;
me.initialConfig = {};
if (length === 1 && Ext.isArray(html)) {
args = html;
length = args.length;
}
if (length > 1) {
for (i = 0; i < length; i++) {
value = args[i];
if (typeof value === 'object') {
Ext.apply(me.initialConfig, value);
Ext.apply(me, value);
} else {
buffer.push(value);
}
}
} else {
buffer.push(html);
}
me.html = buffer.join('');
},
isTemplate: true,
disableFormats: false,
tokenRe: /\{(?:(?:(\d+)|([a-z_][\w\-]*))(?::([a-z_\.]+)(?:\(([^\)]*?)?\))?)?)\}/gi,
apply: function(values) {
var me = this;
if (me.compiled) {
if (!me.fn) {
me.compile();
}
return me.fn(values).join('');
}
return me.evaluate(values);
},
evaluate: function(values) {
var me = this,
useFormat = !me.disableFormats,
fm = Ext.util.Format,
tpl = me;
function fn(match, index, name, formatFn, args) {
if (name == null || name === '') {
name = index;
}
if (formatFn && useFormat) {
if (args) {
args = [
values[name]
].concat(Ext.functionFactory('return [' + args + '];')());
} else {
args = [
values[name]
];
}
if (formatFn.substr(0, 5) === "this.") {
return tpl[formatFn.substr(5)].apply(tpl, args);
}
else if (fm[formatFn]) {
return fm[formatFn].apply(fm, args);
} else
{
return match;
}
} else {
return values[name] !== undefined ? values[name] : "";
}
}
return me.html.replace(me.tokenRe, fn);
},
applyOut: function(values, out) {
var me = this;
if (me.compiled) {
if (!me.fn) {
me.compile();
}
out.push.apply(out, me.fn(values));
} else {
out.push(me.apply(values));
}
return out;
},
applyTemplate: function() {
return this.apply.apply(this, arguments);
},
set: function(html, compile) {
var me = this;
me.html = html;
me.compiled = !!compile;
me.fn = null;
return me;
},
compileARe: /\\/g,
compileBRe: /(\r\n|\n)/g,
compileCRe: /'/g,
compile: function() {
var me = this,
code;
code = me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.tokenRe, me.regexReplaceFn.bind(me));
code = (this.disableFormats !== true ? 'var fm=Ext.util.Format;' : '') + (me.useEval ? '$=' : 'return') + " function(v){return ['" + code + "'];};";
me.fn = me.useEval ? me.evalCompiled(code) : (new Function('Ext', code))(Ext);
me.compiled = true;
return me;
},
evalCompiled: function($) {
eval($);
return $;
},
regexReplaceFn: function(match, index, name, formatFn, args) {
if (index == null || index === '') {
index = '"' + name + '"';
}
else if (this.stringFormat) {
index = parseInt(index) + 1;
}
if (formatFn && this.disableFormats !== true) {
args = args ? ',' + args : "";
if (formatFn.substr(0, 5) === "this.") {
formatFn = formatFn + '(';
}
else if (Ext.util.Format[formatFn]) {
formatFn = "fm." + formatFn + '(';
} else
{
return match;
}
return "'," + formatFn + "v[" + index + "]" + args + "),'";
} else {
return "',v[" + index + "] == undefined ? '' : v[" + index + "],'";
}
},
insertFirst: function(el, values, returnElement) {
return this.doInsert('afterBegin', el, values, returnElement);
},
insertBefore: function(el, values, returnElement) {
return this.doInsert('beforeBegin', el, values, returnElement);
},
insertAfter: function(el, values, returnElement) {
return this.doInsert('afterEnd', el, values, returnElement);
},
append: function(el, values, returnElement) {
return this.doInsert('beforeEnd', el, values, returnElement);
},
doInsert: function(where, el, values, returnElement) {
var newNode = Ext.DomHelper.insertHtml(where, Ext.getDom(el), this.apply(values));
return returnElement ? Ext.get(newNode) : newNode;
},
overwrite: function(el, values, returnElement) {
var newNode = Ext.DomHelper.overwrite(Ext.getDom(el), this.apply(values));
return returnElement ? Ext.get(newNode) : newNode;
}
}, function(Template) {
var formatRe = /\{\d+\}/,
generateFormatFn = function(format) {
if (formatRe.test(format)) {
format = new Template(format, formatTplConfig);
return function() {
return format.apply(arguments);
};
} else
{
return function() {
return format;
};
}
},
formatTplConfig = {
useFormat: false,
compiled: true,
stringFormat: true
},
formatFns = {};
Ext.String.format = Ext.util.Format.format = function(format) {
var formatFn = formatFns[format] || (formatFns[format] = generateFormatFn(format));
return formatFn.apply(this, arguments);
};
});
Ext.define('Ext.mixin.Inheritable', {
extend: 'Ext.Mixin',
mixinConfig: {
id: 'inheritable'
},
getInherited: function(inner) {
var me = this,
inheritedState = (inner && me.inheritedStateInner) || me.inheritedState,
ownerCt = me.ownerCt || me.initOwnerCt,
isContainer = me.isContainer,
parent, inheritedStateInner, getInner;
if (!inheritedState || inheritedState.invalid) {
parent = me.getRefOwner();
if (ownerCt) {
getInner = me.ownerLayout === ownerCt.layout;
}
me.inheritedState = inheritedState =
Ext.Object.chain(parent ? parent.getInherited(getInner) : Ext.rootInheritedState);
if (isContainer) {
me.inheritedStateInner = inheritedStateInner = Ext.Object.chain(inheritedState);
}
me.initInheritedState(inheritedState, inheritedStateInner);
inheritedState = (isContainer && inner) ? me.inheritedStateInner : me.inheritedState;
}
return inheritedState;
},
getInheritedConfig: function(property, skipThis) {
var state = this.inheritedState,
old, ret;
if (!state || state.invalid) {
state = this.getInherited();
}
ret = state[property];
if (skipThis && state.hasOwnProperty(property)) {
old = ret;
delete state[property];
ret = state[property];
state[property] = old;
}
return ret;
},
fixReference: function() {
var me = this,
refHolder;
if (me.reference) {
refHolder = me.lookupReferenceHolder();
if (refHolder) {
refHolder.attachReference(me);
}
}
},
resolveListenerScope: function(defaultScope,
skipThis) {
var me = this,
hasSkipThis = (typeof skipThis === 'boolean'),
namedScope = Ext._namedScopes[defaultScope],
ret;
if (!namedScope) {
ret = me.getInheritedConfig('defaultListenerScope', hasSkipThis ? skipThis : true) || defaultScope || me;
} else if (namedScope.isController) {
ret = me.getInheritedConfig('controller', hasSkipThis ? skipThis : !namedScope.isSelf);
} else if (namedScope.isSelf) {
ret = me.getInheritedConfig('defaultListenerScope', hasSkipThis && skipThis) || me;
} else if (namedScope.isThis) {
ret = me;
}
return ret || null;
},
resolveSatelliteListenerScope: function(satellite, defaultScope) {
var me = this,
namedScope = Ext._namedScopes[defaultScope],
ret;
if (!namedScope) {
ret = me.getInheritedConfig('defaultListenerScope') || defaultScope || me;
} else if (namedScope.isController) {
ret = me.getInheritedConfig('controller');
} else if (namedScope.isSelf) {
ret = me.getInheritedConfig('defaultListenerScope') || satellite;
} else if (namedScope.isThis) {
ret = satellite;
}
return ret || null;
},
lookupReferenceHolder: function(skipThis) {
return this.getInheritedConfig('referenceHolder', skipThis !== false) || null;
},
getRefOwner: function() {
return this.ownerCt || this.initOwnerCt || this.ownerCmp || this.floatParent;
},
invalidateInheritedState: function() {
var inheritedState = this.inheritedState;
if (inheritedState) {
inheritedState.invalid = true;
delete this.inheritedState;
}
}
}, function() {
Ext.rootInheritedState = {};
});
Ext.define('Ext.mixin.Bindable', {
mixinId: 'bindable',
config: {
bind: {
$value: null,
lazy: true
},
controller: null,
defaultListenerScope: false,
publishes: {
$value: null,
lazy: true,
merge: function(newValue, oldValue) {
return this.mergeSets(newValue, oldValue);
}
},
reference: null,
session: {
$value: null,
lazy: true
},
twoWayBindable: {
$value: null,
lazy: true,
merge: function(newValue, oldValue) {
return this.mergeSets(newValue, oldValue);
}
},
viewModel: {
$value: null,
lazy: true
}
},
defaultBindProperty: null,
validRefRe: /^[a-z_][a-z0-9_]*$/i,
initInheritedState: function(inheritedState) {
var me = this,
reference = me.getReference(),
controller = me.getController(),
viewModel = me.getConfig('viewModel', true),
session = me.getConfig('session', true),
defaultListenerScope = me.getDefaultListenerScope();
if (controller) {
inheritedState.controller = controller;
}
if (defaultListenerScope) {
inheritedState.defaultListenerScope = me;
} else if (controller) {
inheritedState.defaultListenerScope = controller;
}
if (viewModel) {
if (!viewModel.isViewModel) {
viewModel = me;
}
inheritedState.viewModel = viewModel;
}
if (session) {
if (!session.isSession) {
session = me;
}
inheritedState.session = session;
}
if (reference) {
me.referenceKey = (inheritedState.referencePath || '') + reference;
me.viewModelKey = (inheritedState.viewModelPath || '') + reference;
}
},
lookupController: function(skipThis) {
return this.getInheritedConfig('controller', skipThis) || null;
},
lookupSession: function(skipThis) {
var ret = skipThis ? null : this.getSession();
if (!ret) {
ret = this.getInheritedConfig('session', skipThis);
if (ret && !ret.isSession) {
ret = ret.getInherited().session = ret.getSession();
}
}
return ret || null;
},
lookupViewModel: function(skipThis) {
var ret = skipThis ? null : this.getViewModel();
if (!ret) {
ret = this.getInheritedConfig('viewModel', skipThis);
if (ret && !ret.isViewModel) {
ret = ret.getInherited().viewModel = ret.getViewModel();
}
}
return ret || null;
},
publishState: function(property, value) {
var me = this,
path = me.viewModelKey,
state = me.publishedState,
binds = me.getBind(),
binding = binds && property && binds[property],
count = 0,
name, publishes, vm;
if (binding && !binding.syncing && !binding.isReadOnly()) {
if (!(binding.calls === 0 && (value == null || value === me.getInitialConfig()[property]))) {
binding.setValue(value);
}
}
if (!path || !(publishes = me.getPublishes())) {
return;
}
if (!(vm = me.lookupViewModel())) {
return;
}
if (property && state) {
if (!publishes[property]) {
return;
}
if (!(value && value.constructor === Object) && !(value instanceof Array)) {
if (state[property] === value) {
return;
}
}
path += '.';
path += property;
} else {
state = state || (me.publishedState = {});
for (name in publishes) {
++count;
if (name === property) {
state[name] = value;
} else {
state[name] = me[name];
}
}
if (!count) {
return;
}
value = state;
}
vm.set(path, value);
},
privates: {
addBindableUpdater: function(property) {
var me = this,
configs = me.self.$config.configs,
cfg = configs[property],
updateName;
if (cfg && !me.hasOwnProperty(updateName = cfg.names.update)) {
me[updateName] = cfg.bindableUpdater || (cfg.root.bindableUpdater = me.makeBindableUpdater(cfg));
}
},
applyBind: function(binds, currentBindings) {
var me = this,
viewModel = me.lookupViewModel(),
twoWayable = me.getTwoWayBindable(),
getBindTemplateScope = me._getBindTemplateScope,
b, property, descriptor;
if (!currentBindings || typeof currentBindings === 'string') {
currentBindings = {};
}
if (!viewModel) {
Ext.Error.raise('Cannot use bind config without a viewModel');
}
if (Ext.isString(binds)) {
if (!me.defaultBindProperty) {
Ext.Error.raise(me.$className + ' has no defaultBindProperty - ' + 'Please specify a bind object');
}
b = binds;
binds = {};
binds[me.defaultBindProperty] = b;
}
for (property in binds) {
descriptor = binds[property];
b = currentBindings[property];
if (b && typeof b !== 'string') {
b.destroy();
b = null;
}
if (descriptor) {
b = viewModel.bind(descriptor, me.onBindNotify, me);
b._config = Ext.Config.get(property);
b.getTemplateScope = getBindTemplateScope;
if (!me[b._config.names.set]) {
Ext.Error.raise('Cannot bind ' + property + ' on ' + me.$className + ' - missing a ' + b._config.names.set + ' method.');
}
}
currentBindings[property] = b;
if (twoWayable && twoWayable[property] && !b.isReadOnly()) {
me.addBindableUpdater(property);
}
}
return currentBindings;
},
applyController: function(controller) {
if (controller) {
controller = Ext.Factory.controller(controller);
controller.setView(this);
}
return controller;
},
applyPublishes: function(all) {
if (this.lookupViewModel()) {
for (var property in all) {
this.addBindableUpdater(property);
}
}
return all;
},
applyReference: function(reference) {
var validIdRe = this.validRefRe || Ext.validIdRe;
if (reference && !validIdRe.test(reference)) {
Ext.Error.raise('Invalid reference "' + reference + '" for ' + this.getId() + ' - not a valid identifier');
}
return reference;
},
applySession: function(session) {
if (!session) {
return null;
}
if (!session.isSession) {
var parentSession = this.lookupSession(true),
config = (session === true) ? {} : session;
if (parentSession) {
session = parentSession.spawn(config);
} else {
session = new Ext.data['Session'](config);
}
}
return session;
},
applyViewModel: function(viewModel) {
var me = this,
config, session;
if (!(viewModel && viewModel.isViewModel)) {
config = {
parent: me.lookupViewModel(true)
};
config.session = me.getSession();
if (!session && !config.parent) {
config.session = me.lookupSession();
}
if (viewModel) {
if (viewModel.constructor === Object) {
Ext.apply(config, viewModel);
} else if (typeof viewModel === 'string') {
config.type = viewModel;
}
}
viewModel = Ext.Factory.viewModel(config);
}
return viewModel;
},
_getBindTemplateScope: function() {
return this.scope.resolveListenerScope();
},
initBindable: function() {
this.initBindable = Ext.emptyFn;
this.getBind();
this.getPublishes();
},
makeBindableUpdater: function(cfg) {
var updateName = cfg.names.update;
return function(newValue, oldValue) {
var me = this,
updater = me.self.prototype[updateName];
if (updater) {
updater.call(me, newValue, oldValue);
}
me.publishState(cfg.name, newValue);
};
},
onBindNotify: function(value, oldValue, binding) {
binding.syncing = (binding.syncing + 1) || 1;
this[binding._config.names.set](value);
--binding.syncing;
},
removeBindings: function() {
var bindings = this.bind,
key, binding;
if (bindings && typeof bindings !== 'string') {
for (key in bindings) {
binding = bindings[key];
binding.destroy();
binding._config = binding.getTemplateScope = null;
}
}
this.bind = null;
},
updateSession: function(session) {
var state = this.getInherited();
if (session) {
state.session = session;
} else {
delete state.session;
}
},
updateViewModel: function(viewModel) {
var state = this.getInherited(),
controller = this.getController();
if (viewModel) {
state.viewModel = viewModel;
viewModel.setView(this);
if (controller) {
controller.initViewModel(viewModel);
}
} else {
delete state.viewModel;
}
}
}
});
Ext.define('Ext.Widget', {
extend: 'Ext.Evented',
xtype: 'widget',
requires: [
'Ext.dom.Element'
],
mixins: [
'Ext.mixin.Inheritable',
'Ext.mixin.Bindable'
],
isWidget: true,
element: {
reference: 'element'
},
observableType: 'component',
eventedConfig: {
width: null,
height: null
},
template: [],
constructor: function(config) {
var me = this;
me.initId(config);
me.initElement();
me.mixins.observable.constructor.call(me, config);
Ext.ComponentManager.register(me);
},
afterCachedConfig: function() {
var me = this,
prototype = me.self.prototype,
referenceList = me.referenceList,
renderElement = me.renderElement.dom,
renderTemplate, element, i, ln, reference, elements;
prototype.renderTemplate = renderTemplate = document.createDocumentFragment();
renderTemplate.appendChild(renderElement.cloneNode(true));
elements = renderTemplate.querySelectorAll('[id]');
for (i = 0 , ln = elements.length; i < ln; i++) {
element = elements[i];
element.removeAttribute('id');
}
for (i = 0 , ln = referenceList.length; i < ln; i++) {
reference = referenceList[i];
me[reference].dom.removeAttribute('reference');
}
},
applyWidth: function(width) {
return this.filterLengthValue(width);
},
applyHeight: function(height) {
return this.filterLengthValue(height);
},
destroy: function() {
var me = this,
referenceList = me.referenceList,
i, ln, reference;
for (i = 0 , ln = referenceList.length; i < ln; i++) {
reference = referenceList[i];
if (me.hasOwnProperty(reference)) {
me[reference].destroy();
me[reference] = null;
}
}
me.callParent();
Ext.ComponentManager.unregister(me);
},
doSetWidth: function(width) {
this.element.setWidth(width);
},
doSetHeight: function(height) {
this.element.setHeight(height);
},
getElementConfig: function() {
var me = this,
el = me.element;
if (!('children' in el)) {
el = Ext.apply({
children: me.getTemplate()
}, el);
}
return el;
},
getItemId: function() {
return this.itemId || this.id;
},
getSize: function() {
return {
width: this.getWidth(),
height: this.getHeight()
};
},
getTemplate: function() {
return this.template;
},
initElement: function() {
var me = this,
prototype = me.self.prototype,
id = me.getId(),
referenceList = me.referenceList = [],
cleanAttributes = true,
renderTemplate, renderElement, element, referenceNodes, i, ln, referenceNode, reference;
if (prototype.hasOwnProperty('renderTemplate')) {
renderTemplate = me.renderTemplate.cloneNode(true);
renderElement = renderTemplate.firstChild;
} else {
cleanAttributes = false;
renderTemplate = document.createDocumentFragment();
renderElement = Ext.Element.create(me.processElementConfig.call(prototype), true);
renderTemplate.appendChild(renderElement);
}
referenceNodes = renderTemplate.querySelectorAll('[reference]');
for (i = 0 , ln = referenceNodes.length; i < ln; i++) {
referenceNode = referenceNodes[i];
reference = referenceNode.getAttribute('reference');
if (cleanAttributes) {
referenceNode.removeAttribute('reference');
}
if (reference === 'element') {
if (element) {
Ext.Error.raise("Duplicate 'element' reference detected in '" + me.$className + "' template.");
}
referenceNode.id = id;
element = me.el = me.addElementReference(reference, referenceNode);
} else {
me.addElementReferenceOnDemand(reference, referenceNode);
}
referenceList.push(reference);
}
if (!element) {
Ext.Error.raise("No 'element' reference found in '" + me.$className + "' template.");
}
if (renderElement === element.dom) {
me.renderElement = element;
} else {
me.addElementReferenceOnDemand('renderElement', renderElement);
}
},
is: function(selector) {
return Ext.ComponentQuery.is(this, selector);
},
isXType: function(xtype, shallow) {
return shallow ? (Ext.Array.indexOf(this.xtypes, xtype) !== -1) : !!this.xtypesMap[xtype];
},
resolveListenerScope: function(defaultType) {
return this.mixins.inheritable.resolveListenerScope.call(this, defaultType);
},
setSize: function(width, height) {
if (width !== undefined) {
this.setWidth(width);
}
if (height !== undefined) {
this.setHeight(height);
}
},
privates: {
addElementReferenceOnDemand: function(name, domNode) {
if (this._elementListeners[name]) {
this.addElementReference(name, domNode);
} else {
Ext.Object.defineProperty(this, name, {
get: function() {
delete this[name];
return this.addElementReference(name, domNode);
},
configurable: true
});
}
},
addElementReference: function(name, domNode) {
var me = this,
referenceEl = me[name] = Ext.get(domNode),
listeners = me._elementListeners[name],
eventName, listener;
referenceEl.skipGarbageCollection = true;
referenceEl.component = me;
if (listeners) {
listeners = Ext.clone(listeners);
listeners.scope = me;
for (eventName in listeners) {
listener = listeners[eventName];
if (typeof listener === 'object') {
listener.scope = me;
}
}
referenceEl.on(listeners);
}
return referenceEl;
},
detachFromBody: function() {
Ext.getDetachedBody().appendChild(this.element);
this.isDetached = true;
},
//@private
doAddListener: function(name, fn, scope, options, order, caller, manager) {
if (options && 'element' in options) {
if (this.referenceList.indexOf(options.element) === -1) {
Ext.Logger.error("Adding event listener with an invalid element reference of '" + options.element + "' for this component. Available values are: '" + this.referenceList.join("', '") + "'", this);
}
this[options.element].doAddListener(name, fn, scope || this, options, order);
}
this.callParent([
name,
fn,
scope,
options,
order,
caller,
manager
]);
},
filterLengthValue: function(value) {
if (value === 'auto' || (!value && value !== 0)) {
return null;
}
return value;
},
getFocusEl: function() {
return this.element;
},
initElementListeners: function(elementConfig) {
var prototype = this,
superPrototype = prototype.self.superclass,
superElementListeners = superPrototype._elementListeners,
reference = elementConfig.reference,
children = elementConfig.children,
elementListeners, listeners, superListeners, ln, i;
if (prototype.hasOwnProperty('_elementListeners')) {
elementListeners = prototype._elementListeners;
} else {
elementListeners = prototype._elementListeners = (superElementListeners ? Ext.Object.chain(superElementListeners) : {});
}
if (reference) {
listeners = elementConfig.listeners;
if (listeners) {
if (superElementListeners) {
superListeners = superElementListeners[reference];
if (superListeners) {
listeners = Ext.Object.chain(superListeners);
Ext.apply(listeners, elementConfig.listeners);
}
}
elementListeners[reference] = listeners;
elementConfig.listeners = null;
}
}
if (children) {
for (i = 0 , ln = children.length; i < ln; i++) {
prototype.initElementListeners(children[i]);
}
}
},
initId: function(config) {
var me = this,
defaultConfig = me.config,
id = (config && config.id) || (defaultConfig && defaultConfig.id);
if (id) {
me.setId(id);
me.id = id;
} else {
me.getId();
}
},
processElementConfig: function() {
var prototype = this,
superPrototype = prototype.self.superclass,
elementConfig;
if (prototype.hasOwnProperty('_elementConfig')) {
elementConfig = prototype._elementConfig;
} else {
elementConfig = prototype._elementConfig = prototype.getElementConfig();
if (superPrototype.isWidget) {
prototype.processElementConfig.call(superPrototype);
}
prototype.initElementListeners(elementConfig);
}
return elementConfig;
},
reattachToBody: function() {
this.isDetached = false;
}
}
}, function(Widget) {
(Widget.prototype.$elementEventOptions = Ext.Object.chain(Ext.Element.prototype.$eventOptions)).element = 1;
});
Ext.define('Ext.overrides.Widget', {
override: 'Ext.Widget',
uses: [
'Ext.Component'
],
$configStrict: false,
isComponent: true,
liquidLayout: true,
rendered: true,
rendering: true,
config: {
renderTo: null
},
cachedConfig: {
baseCls: Ext.baseCSSPrefix + 'widget'
},
constructor: function(config) {
var me = this,
renderTo;
me.callParent([
config
]);
me.getComponentLayout();
renderTo = me.getRenderTo();
if (renderTo) {
me.render(renderTo);
}
},
addCls: function(cls) {
this.el.addCls(cls);
},
addClsWithUI: function(cls) {
this.el.addCls(cls);
},
afterComponentLayout: Ext.emptyFn,
finishRender: function() {
this.rendering = false;
this.initBindable();
},
getComponentLayout: function() {
var me = this,
layout = me.componentLayout;
if (!layout) {
layout = me.componentLayout = new Ext.layout.component.Auto();
layout.setOwner(me);
}
return layout;
},
getTdCls: function() {
return Ext.baseCSSPrefix + this.getTdType() + '-' + (this.ui || 'default') + '-cell';
},
getTdType: function() {
return this.xtype;
},
getItemId: function() {
return this.itemId || this.id;
},
getSizeModel: function() {
return Ext.Component.prototype.getSizeModel.apply(this, arguments);
},
onAdded: function(container, pos, instanced) {
var me = this,
inheritedState = me.inheritedState;
me.ownerCt = container;
if (inheritedState && instanced) {
me.invalidateInheritedState();
}
if (me.reference) {
me.fixReference();
}
},
onRemoved: function(destroying) {
var me = this,
refHolder;
if (me.reference) {
refHolder = me.lookupReferenceHolder();
if (refHolder) {
refHolder.clearReference(me);
}
}
if (!destroying) {
me.removeBindings();
}
if (me.inheritedState && !destroying) {
me.invalidateInheritedState();
}
me.ownerCt = me.ownerLayout = null;
},
parseBox: function(box) {
return Ext.Element.parseBox(box);
},
removeCls: function(cls) {
this.el.removeCls(cls);
},
removeClsWithUI: function(cls) {
this.el.removeCls(cls);
},
render: function(container, position) {
var me = this,
element = me.element,
proto = Ext.Component.prototype,
nextSibling;
if (!me.ownerCt || me.floating) {
if (Ext.scopeCss) {
element.addCls(proto.rootCls);
}
element.addCls(proto.borderBoxCls);
}
if (position) {
nextSibling = container.childNodes[position];
if (nextSibling) {
Ext.fly(container).insertBefore(element, nextSibling);
return;
}
}
Ext.fly(container).appendChild(element);
},
setPosition: function(x, y) {
this.el.setLocalXY(x, y);
},
up: function() {
return Ext.Component.prototype.up.apply(this, arguments);
},
isAncestor: function() {
return Ext.Component.prototype.isAncestor.apply(this, arguments);
},
onFocusEnter: function() {
return Ext.Component.prototype.onFocusEnter.apply(this, arguments);
},
onFocusLeave: function() {
return Ext.Component.prototype.onFocusLeave.apply(this, arguments);
},
focus: Ext.emptyFn,
isFocusable: Ext.emptyFn
}, function(Cls) {
var prototype = Cls.prototype;
if (Ext.isIE8) {
prototype.addElementReferenceOnDemand = prototype.addElementReference;
}
});
Ext.define('Ext.util.XTemplateParser', {
requires: [
'Ext.String'
],
constructor: function(config) {
Ext.apply(this, config);
},
doTpl: Ext.emptyFn,
parse: function(str) {
var me = this,
len = str.length,
aliases = {
elseif: 'elif'
},
topRe = me.topRe,
actionsRe = me.actionsRe,
index, stack, s, m, t, prev, frame, subMatch, begin, end, actions, prop, expectTplNext;
me.level = 0;
me.stack = stack = [];
for (index = 0; index < len; index = end) {
topRe.lastIndex = index;
m = topRe.exec(str);
if (!m) {
me.doText(str.substring(index, len));
break;
}
begin = m.index;
end = topRe.lastIndex;
if (index < begin) {
s = str.substring(index, begin);
if (!(expectTplNext && Ext.String.trim(s) === '')) {
me.doText(s);
}
}
expectTplNext = false;
if (m[1]) {
end = str.indexOf('%}', begin + 2);
me.doEval(str.substring(begin + 2, end));
end += 2;
} else if (m[2]) {
end = str.indexOf(']}', begin + 2);
me.doExpr(str.substring(begin + 2, end));
end += 2;
} else if (m[3]) {
me.doTag(m[3]);
} else if (m[4]) {
actions = null;
while ((subMatch = actionsRe.exec(m[4])) !== null) {
s = subMatch[2] || subMatch[3];
if (s) {
s = Ext.String.htmlDecode(s);
t = subMatch[1];
t = aliases[t] || t;
actions = actions || {};
prev = actions[t];
if (typeof prev == 'string') {
actions[t] = [
prev,
s
];
} else if (prev) {
actions[t].push(s);
} else {
actions[t] = s;
}
}
}
if (!actions) {
if (me.elseRe.test(m[4])) {
me.doElse();
} else if (me.defaultRe.test(m[4])) {
me.doDefault();
} else {
me.doTpl();
stack.push({
type: 'tpl'
});
}
} else if (actions['if']) {
me.doIf(actions['if'], actions);
stack.push({
type: 'if'
});
} else if (actions['switch']) {
me.doSwitch(actions['switch'], actions);
stack.push({
type: 'switch'
});
expectTplNext = true;
} else if (actions['case']) {
me.doCase(actions['case'], actions);
} else if (actions['elif']) {
me.doElseIf(actions['elif'], actions);
} else if (actions['for']) {
++me.level;
if (prop = me.propRe.exec(m[4])) {
actions.propName = prop[1] || prop[2];
}
me.doFor(actions['for'], actions);
stack.push({
type: 'for',
actions: actions
});
} else if (actions['foreach']) {
++me.level;
if (prop = me.propRe.exec(m[4])) {
actions.propName = prop[1] || prop[2];
}
me.doForEach(actions['foreach'], actions);
stack.push({
type: 'foreach',
actions: actions
});
} else if (actions.exec) {
me.doExec(actions.exec, actions);
stack.push({
type: 'exec',
actions: actions
});
}
}
else if (m[0].length === 5) {
stack.push({
type: 'tpl'
});
} else {
frame = stack.pop();
me.doEnd(frame.type, frame.actions);
if (frame.type == 'for' || frame.type == 'foreach') {
--me.level;
}
}
}
},
topRe: /(?:(\{\%)|(\{\[)|\{([^{}]+)\})|(?:<tpl([^>]*)\>)|(?:<\/tpl>)/g,
actionsRe: /\s*(elif|elseif|if|for|foreach|exec|switch|case|eval|between)\s*\=\s*(?:(?:"([^"]*)")|(?:'([^']*)'))\s*/g,
propRe: /prop=(?:(?:"([^"]*)")|(?:'([^']*)'))/,
defaultRe: /^\s*default\s*$/,
elseRe: /^\s*else\s*$/
});
Ext.define('Ext.util.XTemplateCompiler', {
extend: 'Ext.util.XTemplateParser',
useEval: Ext.isGecko,
useIndex: Ext.isIE8m,
useFormat: true,
propNameRe: /^[\w\d\$]*$/,
compile: function(tpl) {
var me = this,
code = me.generate(tpl);
return me.useEval ? me.evalTpl(code) : (new Function('Ext', code))(Ext);
},
generate: function(tpl) {
var me = this,
definitions = 'var fm=Ext.util.Format,ts=Object.prototype.toString;',
code;
me.maxLevel = 0;
me.body = [
'var c0=values, a0=' + me.createArrayTest(0) + ', p0=parent, n0=xcount, i0=xindex, k0, v;\n'
];
if (me.definitions) {
if (typeof me.definitions === 'string') {
me.definitions = [
me.definitions,
definitions
];
} else {
me.definitions.push(definitions);
}
} else {
me.definitions = [
definitions
];
}
me.switches = [];
me.parse(tpl);
me.definitions.push((me.useEval ? '$=' : 'return') + ' function (' + me.fnArgs + ') {', me.body.join(''), '}');
code = me.definitions.join('\n');
me.definitions.length = me.body.length = me.switches.length = 0;
delete me.definitions;
delete me.body;
delete me.switches;
return code;
},
doText: function(text) {
var me = this,
out = me.body;
text = text.replace(me.aposRe, "\\'").replace(me.newLineRe, '\\n');
if (me.useIndex) {
out.push('out[out.length]=\'', text, '\'\n');
} else {
out.push('out.push(\'', text, '\')\n');
}
},
doExpr: function(expr) {
var out = this.body;
out.push('if ((v=' + expr + ') != null) out');
if (this.useIndex) {
out.push('[out.length]=v+\'\'\n');
} else {
out.push('.push(v+\'\')\n');
}
},
doTag: function(tag) {
var expr = this.parseTag(tag);
if (expr) {
this.doExpr(expr);
} else {
this.doText('{' + tag + '}');
}
},
doElse: function() {
this.body.push('} else {\n');
},
doEval: function(text) {
this.body.push(text, '\n');
},
doIf: function(action, actions) {
var me = this;
if (action === '.') {
me.body.push('if (values) {\n');
} else if (me.propNameRe.test(action)) {
me.body.push('if (', me.parseTag(action), ') {\n');
} else
{
me.body.push('if (', me.addFn(action), me.callFn, ') {\n');
}
if (actions.exec) {
me.doExec(actions.exec);
}
},
doElseIf: function(action, actions) {
var me = this;
if (action === '.') {
me.body.push('else if (values) {\n');
} else if (me.propNameRe.test(action)) {
me.body.push('} else if (', me.parseTag(action), ') {\n');
} else
{
me.body.push('} else if (', me.addFn(action), me.callFn, ') {\n');
}
if (actions.exec) {
me.doExec(actions.exec);
}
},
doSwitch: function(action) {
var me = this,
key;
if (action === '.' || action === '#') {
key = action === '.' ? 'values' : 'xindex';
me.body.push('switch (', key, ') {\n');
} else if (me.propNameRe.test(action)) {
me.body.push('switch (', me.parseTag(action), ') {\n');
} else
{
me.body.push('switch (', me.addFn(action), me.callFn, ') {\n');
}
me.switches.push(0);
},
doCase: function(action) {
var me = this,
cases = Ext.isArray(action) ? action : [
action
],
n = me.switches.length - 1,
match, i;
if (me.switches[n]) {
me.body.push('break;\n');
} else {
me.switches[n]++;
}
for (i = 0 , n = cases.length; i < n; ++i) {
match = me.intRe.exec(cases[i]);
cases[i] = match ? match[1] : ("'" + cases[i].replace(me.aposRe, "\\'") + "'");
}
me.body.push('case ', cases.join(': case '), ':\n');
},
doDefault: function() {
var me = this,
n = me.switches.length - 1;
if (me.switches[n]) {
me.body.push('break;\n');
} else {
me.switches[n]++;
}
me.body.push('default:\n');
},
doEnd: function(type, actions) {
var me = this,
L = me.level - 1;
if (type == 'for' || type == 'foreach') {
if (actions.exec) {
me.doExec(actions.exec);
}
me.body.push('}\n');
me.body.push('parent=p', L, ';values=r', L + 1, ';xcount=n' + L + ';xindex=i', L, '+1;xkey=k', L, ';\n');
} else if (type == 'if' || type == 'switch') {
me.body.push('}\n');
}
},
doFor: function(action, actions) {
var me = this,
s,
L = me.level,
up = L - 1,
parentAssignment;
if (action === '.') {
s = 'values';
} else if (me.propNameRe.test(action)) {
s = me.parseTag(action);
} else
{
s = me.addFn(action) + me.callFn;
}
if (me.maxLevel < L) {
me.maxLevel = L;
me.body.push('var ');
}
if (action == '.') {
parentAssignment = 'c' + L;
} else {
parentAssignment = 'a' + up + '?c' + up + '[i' + up + ']:c' + up;
}
me.body.push('i', L, '=0,n', L, '=0,c', L, '=', s, ',a', L, '=', me.createArrayTest(L), ',r', L, '=values,p', L, ',k', L, ';\n', 'p', L, '=parent=', parentAssignment, '\n', 'if (c', L, '){if(a', L, '){n', L, '=c', L, '.length;}else if (c', L, '.isMixedCollection){c', L, '=c', L, '.items;n', L, '=c', L, '.length;}else if(c', L, '.isStore){c', L, '=c', L, '.data.items;n', L, '=c', L, '.length;}else{c', L, '=[c', L, '];n', L, '=1;}}\n', 'for (xcount=n', L, ';i', L, '<n' + L + ';++i', L, '){\n', 'values=c', L, '[i', L, ']');
if (actions.propName) {
me.body.push('.', actions.propName);
}
me.body.push('\n', 'xindex=i', L, '+1\n');
if (actions.between) {
me.body.push('if(xindex>1){ out.push("', actions.between, '"); } \n');
}
},
doForEach: function(action, actions) {
var me = this,
s,
L = me.level,
up = L - 1,
parentAssignment;
if (action === '.') {
s = 'values';
} else if (me.propNameRe.test(action)) {
s = me.parseTag(action);
} else
{
s = me.addFn(action) + me.callFn;
}
if (me.maxLevel < L) {
me.maxLevel = L;
me.body.push('var ');
}
if (action == '.') {
parentAssignment = 'c' + L;
} else {
parentAssignment = 'a' + up + '?c' + up + '[i' + up + ']:c' + up;
}
me.body.push('i', L, '=-1,n', L, '=0,c', L, '=', s, ',a', L, '=', me.createArrayTest(L), ',r', L, '=values,p', L, ',k', L, ';\n', 'p', L, '=parent=', parentAssignment, '\n', 'for(k', L, ' in c', L, '){\n', 'xindex=++i', L, '+1;\n', 'xkey=k', L, ';\n', 'values=c', L, '[k', L, '];');
if (actions.propName) {
me.body.push('.', actions.propName);
}
if (actions.between) {
me.body.push('if(xindex>1){ out.push("', actions.between, '"); } \n');
}
},
createArrayTest: ('isArray' in Array) ? function(L) {
return 'Array.isArray(c' + L + ')';
} : function(L) {
return 'ts.call(c' + L + ')==="[object Array]"';
},
doExec: function(action, actions) {
var me = this,
name = 'f' + me.definitions.length,
guards = me.guards[me.strict ? 0 : 1];
me.definitions.push('function ' + name + '(' + me.fnArgs + ') {', guards.doTry, ' var $v = values; with($v) {', ' ' + action, ' }', guards.doCatch, '}');
me.body.push(name + me.callFn + '\n');
},
guards: [
{
doTry: '',
doCatch: ''
},
{
doTry: 'try { ',
doCatch: ' } catch(e) {\n' + 'Ext.log.warn("XTemplate evaluation exception: " + e.message);\n' + '}'
}
],
addFn: function(body) {
var me = this,
name = 'f' + me.definitions.length,
guards = me.guards[me.strict ? 0 : 1];
if (body === '.') {
me.definitions.push('function ' + name + '(' + me.fnArgs + ') {', ' return values', '}');
} else if (body === '..') {
me.definitions.push('function ' + name + '(' + me.fnArgs + ') {', ' return parent', '}');
} else {
me.definitions.push('function ' + name + '(' + me.fnArgs + ') {', guards.doTry, ' var $v = values; with($v) {', ' return(' + body + ')', ' }', guards.doCatch, '}');
}
return name;
},
parseTag: function(tag) {
var me = this,
m = me.tagRe.exec(tag),
name, format, args, math, v;
if (!m) {
return null;
}
name = m[1];
format = m[2];
args = m[3];
math = m[4];
if (name == '.') {
if (!me.validTypes) {
me.definitions.push('var validTypes={string:1,number:1,boolean:1};');
me.validTypes = true;
}
v = 'validTypes[typeof values] || ts.call(values) === "[object Date]" ? values : ""';
}
else if (name == '#') {
v = 'xindex';
}
else if (name == '$') {
v = 'xkey';
} else if (name.substr(0, 7) == "parent.") {
v = name;
}
else if (isNaN(name) && name.indexOf('-') == -1 && name.indexOf('.') != -1) {
v = "values." + name;
} else
{
v = "values['" + name + "']";
}
if (math) {
v = '(' + v + math + ')';
}
if (format && me.useFormat) {
args = args ? ',' + args : "";
if (format.substr(0, 5) != "this.") {
format = "fm." + format + '(';
} else {
format += '(';
}
} else {
return v;
}
return format + v + args + ')';
},
evalTpl: function($) {
eval($);
return $;
},
newLineRe: /\r\n|\r|\n/g,
aposRe: /[']/g,
intRe: /^\s*(\d+)\s*$/,
tagRe: /^([\w-\.\#\$]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\/]\s?[\d\.\+\-\*\/\(\)]+)?$/
}, function() {
var proto = this.prototype;
proto.fnArgs = 'out,values,parent,xindex,xcount,xkey';
proto.callFn = '.call(this,' + proto.fnArgs + ')';
});
Ext.define('Ext.XTemplate', {
extend: 'Ext.Template',
requires: [
'Ext.util.XTemplateCompiler'
],
emptyObj: {},
fn: null,
strict: false,
apply: function(values, parent) {
return this.applyOut(values, [], parent).join('');
},
applyOut: function(values, out, parent) {
var me = this,
compiler;
if (!me.fn) {
compiler = new Ext.util.XTemplateCompiler({
useFormat: me.disableFormats !== true,
definitions: me.definitions,
strict: me.strict
});
me.fn = compiler.compile(me.html);
}
if (me.strict) {
me.fn(out, values, parent || me.emptyObj, 1, 1);
} else {
try {
me.fn(out, values, parent || me.emptyObj, 1, 1);
} catch (e) {
Ext.log.warn('XTemplate evaluation exception: ' + e.message);
}
}
return out;
},
compile: function() {
return this;
},
statics: {
getTpl: function(instance, name) {
var tpl = instance[name],
owner;
if (tpl && !tpl.isTemplate) {
tpl = Ext.ClassManager.dynInstantiate('Ext.XTemplate', tpl);
if (instance.hasOwnProperty(name)) {
owner = instance;
} else {
for (owner = instance.self.prototype; owner && !owner.hasOwnProperty(name); owner = owner.superclass) {}
}
owner[name] = tpl;
tpl.owner = owner;
}
return tpl || null;
}
}
});
Ext.define('Ext.app.EventDomain', {
requires: [
'Ext.util.Event'
],
statics: {
instances: {}
},
isEventDomain: true,
isInstance: false,
constructor: function() {
var me = this;
if (!me.isInstance) {
Ext.app.EventDomain.instances[me.type] = me;
}
me.bus = {};
me.monitoredClasses = [];
},
dispatch: function(target, ev, args) {
ev = Ext.canonicalEventName(ev);
var me = this,
bus = me.bus,
selectors = bus[ev],
selector, controllers, id, info, events, len, i, event;
if (!selectors) {
return true;
}
for (selector in selectors) {
if (selectors.hasOwnProperty(selector) && me.match(target, selector, me.controller)) {
controllers = selectors[selector];
for (id in controllers) {
if (controllers.hasOwnProperty(id)) {
info = controllers[id];
if (info.controller.isActive()) {
events = info.list;
len = events.length;
for (i = 0; i < len; i++) {
event = events[i];
if (event.fire.apply(event, args) === false) {
return false;
}
}
}
}
}
}
}
return true;
},
listen: function(selectors, controller) {
var me = this,
bus = me.bus,
idProperty = me.idProperty,
monitoredClasses = me.monitoredClasses,
monitoredClassesCount = monitoredClasses.length,
controllerId = controller.getId(),
isComponentDomain = (me.type === 'component'),
refMap = isComponentDomain ? controller.getRefMap() : null,
i, tree, info, selector, options, listener, scope, event, listeners, ev, classHasListeners;
for (selector in selectors) {
listeners = selectors[selector];
if (isComponentDomain) {
selector = refMap[selector] || selector;
}
if (listeners) {
if (idProperty) {
if (!/^[*#]/.test(selector)) {
Ext.Error.raise('Selectors containing id should begin with #');
}
selector = selector === '*' ? selector : selector.substring(1);
}
for (ev in listeners) {
options = null;
listener = listeners[ev];
scope = controller;
ev = Ext.canonicalEventName(ev);
event = new Ext.util.Event(controller, ev);
if (Ext.isObject(listener)) {
options = listener;
listener = options.fn;
scope = options.scope || controller;
delete options.fn;
delete options.scope;
}
if ((!options || !options.scope) && typeof listener === 'string') {
if (!scope[listener]) {
Ext.Error.raise('Cannot resolve "' + listener + '" on controller.');
}
scope = null;
} else if (typeof listener === 'string') {
listener = scope[listener];
}
event.addListener(listener, scope, options);
for (i = 0; i < monitoredClassesCount; ++i) {
classHasListeners = monitoredClasses[i].hasListeners;
if (classHasListeners) {
classHasListeners._incr_(ev);
}
}
tree = bus[ev] || (bus[ev] = {});
tree = tree[selector] || (tree[selector] = {});
info = tree[controllerId] || (tree[controllerId] = {
controller: controller,
list: []
});
info.list.push(event);
}
}
}
},
match: function(target, selector) {
var idProperty = this.idProperty;
if (idProperty) {
return selector === '*' || target[idProperty] === selector;
}
return false;
},
monitor: function(observable) {
var domain = this,
prototype = observable.isInstance ? observable : observable.prototype,
doFireEvent = prototype.doFireEvent;
domain.monitoredClasses.push(observable);
prototype.doFireEvent = function(ev, args) {
var ret = doFireEvent.apply(this, arguments);
if (ret !== false && !this.isSuspended(ev)) {
ret = domain.dispatch(this, ev, args);
}
return ret;
};
},
unlisten: function(controllerId) {
var bus = this.bus,
id = controllerId,
monitoredClasses = this.monitoredClasses,
monitoredClassesCount = monitoredClasses.length,
controllers, ev, events, len, item, selector, selectors, i, j, info, classHasListeners;
if (controllerId.isController) {
id = controllerId.getId();
}
for (ev in bus) {
ev = Ext.canonicalEventName(ev);
if (bus.hasOwnProperty(ev) && (selectors = bus[ev])) {
for (selector in selectors) {
controllers = selectors[selector];
info = controllers[id];
if (info) {
events = info.list;
if (events) {
for (i = 0 , len = events.length; i < len; ++i) {
item = events[i];
item.clearListeners();
for (j = 0; j < monitoredClassesCount; ++j) {
classHasListeners = monitoredClasses[j].hasListeners;
if (classHasListeners) {
classHasListeners._decr_(item.name);
}
}
}
delete controllers[id];
}
}
}
}
}
},
destroy: function() {
this.monitoredClasses = this.bus = null;
}
});
Ext.define('Ext.app.domain.Component', {
extend: 'Ext.app.EventDomain',
singleton: true,
requires: [
'Ext.Widget'
],
type: 'component',
constructor: function() {
this.callParent();
this.monitor(Ext.Widget);
},
dispatch: function(target, ev, args) {
var controller = target.lookupController(false),
domain, view;
while (controller) {
domain = controller.compDomain;
if (domain) {
if (domain.dispatch(target, ev, args) === false) {
return false;
}
}
view = controller.getView();
controller = view ? view.lookupController(true) : null;
}
return this.callParent(arguments);
},
match: function(target, selector) {
return target.is(selector);
}
});
Ext.define('Ext.util.ProtoElement', function() {
var splitWords = Ext.String.splitWords,
toMap = Ext.Array.toMap;
return {
isProtoEl: true,
clsProp: 'cls',
styleProp: 'style',
removedProp: 'removed',
styleIsText: false,
constructor: function(config) {
var me = this,
cls, style;
if (config) {
Ext.apply(me, config);
cls = me.cls;
style = me.style;
delete me.cls;
}
me.classList = cls ? splitWords(cls) : [];
me.classMap = cls ? toMap(me.classList) : {};
if (style) {
if (typeof style === 'string') {
me.style = Ext.Element.parseStyles(style);
} else if (Ext.isFunction(style)) {
me.styleFn = style;
delete me.style;
} else {
me.style = Ext.apply({}, style);
}
}
},
flush: function() {
this.flushClassList = [];
this.removedClasses = {};
delete this.style;
delete this.unselectableAttr;
},
addCls: function(cls) {
if (!cls) {
return this;
}
var me = this,
add = (typeof cls === 'string') ? splitWords(cls) : cls,
length = add.length,
list = me.classList,
map = me.classMap,
flushList = me.flushClassList,
i = 0,
c;
for (; i < length; ++i) {
c = add[i];
if (!map[c]) {
map[c] = true;
list.push(c);
if (flushList) {
flushList.push(c);
delete me.removedClasses[c];
}
}
}
return me;
},
hasCls: function(cls) {
return cls in this.classMap;
},
removeCls: function(cls) {
var me = this,
list = me.classList,
newList = (me.classList = []),
remove = toMap(splitWords(cls)),
length = list.length,
map = me.classMap,
removedClasses = me.removedClasses,
i, c;
for (i = 0; i < length; ++i) {
c = list[i];
if (remove[c]) {
if (removedClasses) {
if (map[c]) {
removedClasses[c] = true;
Ext.Array.remove(me.flushClassList, c);
}
}
delete map[c];
} else {
newList.push(c);
}
}
return me;
},
setStyle: function(prop, value) {
var me = this,
style = me.style || (me.style = {});
if (typeof prop === 'string') {
if (arguments.length === 1) {
me.setStyle(Ext.Element.parseStyles(prop));
} else {
style[prop] = value;
}
} else {
Ext.apply(style, prop);
}
return me;
},
unselectable: function() {
this.addCls(Ext.dom.Element.unselectableCls);
if (Ext.isOpera) {
this.unselectableAttr = true;
}
},
writeTo: function(to) {
var me = this,
classList = me.flushClassList || me.classList,
removedClasses = me.removedClasses,
style;
if (me.styleFn) {
style = Ext.apply({}, me.styleFn());
Ext.apply(style, me.style);
} else {
style = me.style;
}
to[me.clsProp] = classList.join(' ');
if (style) {
to[me.styleProp] = me.styleIsText ? Ext.DomHelper.generateStyles(style, null, true) : style;
}
if (removedClasses) {
removedClasses = Ext.Object.getKeys(removedClasses);
if (removedClasses.length) {
to[me.removedProp] = removedClasses.join(' ');
}
}
if (me.unselectableAttr) {
to.unselectable = 'on';
}
return to;
}
};
});
Ext.define('Ext.dom.CompositeElement', {
alternateClassName: 'Ext.CompositeElement',
extend: 'Ext.dom.CompositeElementLite',
isLite: false,
getElement: function(el) {
return el;
},
transformElement: function(el) {
return Ext.get(el);
}
});
Ext.Factory = function(type) {
var me = this;
me.aliasPrefix = type + '.';
me.cache = {};
me.name = type.replace(me.fixNameRe, me.fixNameFn);
me.type = type;
};
Ext.Factory.prototype = {
defaultProperty: 'type',
instanceProp: 'isInstance',
create: function(config, defaultType) {
var me = this,
Manager = Ext.ClassManager,
cache = me.cache,
alias, className, klass, suffix;
if (config) {
if (config[me.instanceProp]) {
return config;
}
if (typeof config === 'string') {
suffix = config;
config = {};
config[me.defaultProperty] = suffix;
}
className = config.xclass;
suffix = config.type;
}
if (className) {
if (!(klass = Manager.get(className))) {
return Manager.instantiate(className, config);
}
} else {
if (!(suffix = suffix || defaultType || me.defaultType)) {
klass = me.defaultClass;
}
if (!suffix && !klass) {
Ext.Error.raise('No type specified for ' + me.type + '.create');
}
if (!klass && !(klass = cache[suffix])) {
alias = me.aliasPrefix + suffix;
className = Manager.getNameByAlias(alias);
if (!(klass = className && Manager.get(className))) {
return Manager.instantiateByAlias(alias, config);
}
cache[suffix] = klass;
}
}
return klass.isInstance ? klass : new klass(config);
},
fixNameRe: /\.[a-z]/ig,
fixNameFn: function(match) {
return match.substring(1).toUpperCase();
},
clearCache: function() {
this.cache = {};
}
};
Ext.Factory.define = function(type, config) {
var Factory = Ext.Factory,
defaultClass, factory, fn;
if (type.constructor === Object) {
Ext.Object.each(type, Factory.define, Factory);
} else {
factory = new Ext.Factory(type);
if (config) {
if (config.constructor === Object) {
Ext.apply(factory, config);
if (typeof (defaultClass = factory.xclass) === 'string') {
factory.defaultClass = Ext.ClassManager.get(defaultClass);
}
} else {
factory.defaultType = config;
}
}
Factory[factory.name] = fn = factory.create.bind(factory);
fn.instance = factory;
}
return fn;
};
Ext.define('Ext.mixin.Factoryable', {
mixinId: 'factoryable',
onClassMixedIn: function(targetClass) {
var proto = targetClass.prototype,
factoryConfig = proto.factoryConfig,
alias = proto.alias,
config = {},
dot, createFn;
alias = alias && alias.length && alias[0];
if (alias && (dot = alias.lastIndexOf('.')) > 0) {
config.type = alias.substring(0, dot);
config.defaultType = alias.substring(dot + 1);
}
if (factoryConfig) {
delete proto.factoryConfig;
Ext.apply(config, factoryConfig);
}
createFn = Ext.Factory.define(config.type, config);
if (targetClass.create === Ext.Base.create) {
targetClass.create = createFn;
}
}
});
Ext.define('Ext.scroll.Scroller', {
extend: 'Ext.Evented',
alias: 'scroller.scroller',
mixins: [
'Ext.mixin.Factoryable'
],
uses: [
'Ext.scroll.TouchScroller',
'Ext.scroll.DomScroller'
],
factoryConfig: {
defaultType: 'dom'
},
isScroller: true,
config: {
direction: undefined,
directionLock: false,
disabled: null,
element: undefined,
indicators: null,
maxPosition: null,
maxUserPosition: null,
minPosition: {
x: 0,
y: 0
},
minUserPosition: {
x: 0,
y: 0
},
momentumEasing: null,
size: null,
x: true,
y: true
},
statics: {
create: function(config) {
return Ext.Factory.scroller(config, Ext.supports.Touch ? 'touch' : 'dom');
}
},
constructor: function(config) {
var me = this;
me.callParent([
config
]);
me.onDomScrollEnd = Ext.Function.createBuffered(me.onDomScrollEnd, 100, me);
},
addPartner: function(partner, axis) {
var me = this,
partners = me._partners || (me._partners = {}),
otherPartners = partner._partners || (partner._partners = {});
partners[partner.getId()] = {
scroller: partner,
axis: axis
};
otherPartners[me.getId()] = {
scroller: me,
axis: axis
};
},
applyElement: function(element) {
var el;
if (element) {
if (element.isElement) {
el = element;
} else {
el = Ext.get(element);
if (!el && (typeof element === 'string')) {
Ext.Error.raise("Cannot create Ext.scroll.Scroller instance. " + "Element with id '" + element + "' not found.");
}
}
}
return el;
},
updateDirectionLock: Ext.emptyFn,
updateDisabled: Ext.emptyFn,
updateIndicators: Ext.emptyFn,
updateMaxPosition: Ext.emptyFn,
updateMaxUserPosition: Ext.emptyFn,
updateMinPosition: Ext.emptyFn,
updateMinUserPosition: Ext.emptyFn,
updateMomenumEasing: Ext.emptyFn,
updateSize: Ext.emptyFn,
updateX: Ext.emptyFn,
updateY: Ext.emptyFn,
updateElement: function(element) {
element.on('scroll', 'onDomScroll', this);
},
refresh: function() {
this.fireEvent('refresh', this);
return this;
},
removePartner: function(partner) {
var partners = this._partners,
otherPartners = partner._partners;
if (partners) {
delete partners[partner.getId()];
}
if (otherPartners) {
delete (otherPartners[this.getId()]);
}
},
scrollBy: function(deltaX, deltaY, animate) {
var position = this.getPosition();
if (deltaX) {
if (deltaX.length) {
animate = deltaY;
deltaY = deltaX[1];
deltaX = deltaX[0];
} else if (typeof deltaX !== 'number') {
animate = deltaY;
deltaY = deltaX.y;
deltaX = deltaX.x;
}
}
deltaX = (typeof deltaX === 'number') ? deltaX + position.x : null;
deltaY = (typeof deltaY === 'number') ? deltaY + position.y : null;
return this.doScrollTo(deltaX, deltaY, animate);
},
scrollIntoView: function(el, hscroll, animate, highlight) {
var me = this,
position = me.getPosition(),
newPosition, newX, newY,
myEl = me.getElement();
if (el) {
newPosition = Ext.fly(el).getScrollIntoViewXY(myEl, position.x, position.y);
newX = (hscroll === false) ? position.x : newPosition.x;
newY = newPosition.y;
if (highlight) {
me.on({
scrollend: 'doHighlight',
scope: me,
single: true,
args: [
el,
highlight
]
});
}
me.doScrollTo(newX, newY, animate);
}
},
scrollTo: function(x, y, animate) {
var maxPosition;
if (x) {
if (x.length) {
animate = y;
y = x[1];
x = x[0];
} else if (typeof x !== 'number') {
animate = y;
y = x.y;
x = x.x;
}
}
if (x < 0 || y < 0) {
maxPosition = this.getMaxPosition();
if (x < 0) {
x += maxPosition.x;
}
if (y < 0) {
y += maxPosition.y;
}
}
this.doScrollTo(x, y, animate);
},
updateDirection: function(direction) {
var me = this,
x, y;
if (!direction) {
x = me.getX();
y = me.getY();
if (x && y) {
direction = (y === 'scroll' && x === 'scroll') ? 'both' : 'auto';
} else if (y) {
direction = 'vertical';
} else if (x) {
direction = 'horizontal';
}
me._direction = direction;
} else {
if (direction === 'auto') {
x = true;
y = true;
} else if (direction === 'vertical') {
x = false;
y = true;
} else if (direction === 'horizontal') {
x = true;
y = false;
} else if (direction === 'both') {
x = 'scroll';
y = 'scroll';
}
me.setX(x);
me.setY(y);
}
},
deprecated: {
'5': {
methods: {
getScroller: function() {
return this;
}
}
},
'5.1.0': {
methods: {
scrollToTop: function(animate) {
return this.scrollTo(0, 0, animate);
},
scrollToEnd: function(animate) {
return this.scrollTo(Infinity, Infinity, animate);
}
}
}
},
privates: {
convertX: function(x) {
return x;
},
doHighlight: function(el, highlight) {
if (highlight !== true) {
Ext.fly(el).highlight(highlight);
} else {
Ext.fly(el).highlight();
}
},
fireScrollStart: function(x, y) {
var me = this,
component = me.component;
me.invokePartners('onPartnerScrollStart', x, y);
if (me.hasListeners.scrollstart) {
me.fireEvent('scrollstart', me, x, y);
}
if (component && component.onScrollStart) {
component.onScrollStart(x, y);
}
Ext.GlobalEvents.fireEvent('scrollstart', me, x, y);
},
fireScroll: function(x, y) {
var me = this,
component = me.component;
me.invokePartners('onPartnerScroll', x, y);
if (me.hasListeners.scroll) {
me.fireEvent('scroll', me, x, y);
}
if (component && component.onScrollMove) {
component.onScrollMove(x, y);
}
Ext.GlobalEvents.fireEvent('scroll', me, x, y);
},
fireScrollEnd: function(x, y) {
var me = this,
component = me.component;
me.invokePartners('onPartnerScrollEnd', x, y);
if (me.hasListeners.scrollend) {
me.fireEvent('scrollend', me, x, y);
}
if (component && component.onScrollEnd) {
component.onScrollEnd(x, y);
}
Ext.GlobalEvents.fireEvent('scrollend', me, x, y);
},
initXStyle: function() {
var element = this.getElement(),
x = this.getX();
if (!x) {
x = 'hidden';
} else if (x === true) {
x = 'auto';
}
if (element) {
element.setStyle('overflow-x', x);
}
},
initYStyle: function() {
var element = this.getElement(),
y = this.getY();
if (!y) {
y = 'hidden';
} else if (y === true) {
y = 'auto';
}
if (element) {
element.setStyle('overflow-y', y);
}
},
invokePartners: function(method, x, y) {
var partners = this._partners,
partner, id;
if (!this.suspendSync) {
for (id in partners) {
partner = partners[id].scroller;
partner[method](this, x, y);
}
}
},
suspendPartnerSync: function() {
this.suspendSync = (this.suspendSync || 0) + 1;
},
resumePartnerSync: function() {
if (this.suspendSync) {
this.suspendSync--;
}
},
onDomScroll: function() {
var me = this,
position = me.getPosition(),
x = position.x,
y = position.y;
if (!me.isScrolling) {
me.isScrolling = true;
me.fireScrollStart(x, y);
}
me.fireScroll(x, y);
me.onDomScrollEnd();
},
onDomScrollEnd: function() {
var me = this,
position = me.getPosition(),
x = position.x,
y = position.y;
me.isScrolling = false;
me.trackingScrollLeft = x;
me.trackingScrollTop = y;
me.fireScrollEnd(x, y);
},
onPartnerScroll: function(partner, x, y) {
var axis = partner._partners[this.getId()].axis;
if (axis) {
if (axis === 'x') {
y = null;
} else if (axis === 'y') {
x = null;
}
}
this.doScrollTo(x, y);
},
restoreState: function() {
var me = this,
el = me.getElement(),
dom;
if (el) {
dom = el.dom;
if (me.trackingScrollTop !== undefined) {
dom.scrollTop = me.trackingScrollTop;
dom.scrollLeft = me.trackingScrollLeft;
}
}
},
onPartnerScrollStart: function() {
this.suspendPartnerSync();
},
onPartnerScrollEnd: function() {
this.resumePartnerSync();
}
}
});
Ext.define('Ext.fx.easing.Abstract', {
config: {
startTime: 0,
startValue: 0
},
isEasing: true,
isEnded: false,
constructor: function(config) {
this.initConfig(config);
return this;
},
applyStartTime: function(startTime) {
if (!startTime) {
startTime = Ext.Date.now();
}
return startTime;
},
updateStartTime: function(startTime) {
this.reset();
},
reset: function() {
this.isEnded = false;
},
getValue: Ext.emptyFn
});
Ext.define('Ext.fx.easing.Momentum', {
extend: 'Ext.fx.easing.Abstract',
config: {
acceleration: 30,
friction: 0,
startVelocity: 0
},
alpha: 0,
updateFriction: function(friction) {
var theta = Math.log(1 - (friction / 10));
this.theta = theta;
this.alpha = theta / this.getAcceleration();
},
updateStartVelocity: function(velocity) {
this.velocity = velocity * this.getAcceleration();
},
updateAcceleration: function(acceleration) {
this.velocity = this.getStartVelocity() * acceleration;
this.alpha = this.theta / acceleration;
},
getValue: function() {
return this.getStartValue() - this.velocity * (1 - this.getFrictionFactor()) / this.theta;
},
getFrictionFactor: function() {
var deltaTime = Ext.Date.now() - this.getStartTime();
return Math.exp(deltaTime * this.alpha);
},
getVelocity: function() {
return this.getFrictionFactor() * this.velocity;
}
});
Ext.define('Ext.fx.easing.Bounce', {
extend: 'Ext.fx.easing.Abstract',
config: {
springTension: 0.3,
acceleration: 30,
startVelocity: 0
},
getValue: function() {
var deltaTime = Ext.Date.now() - this.getStartTime(),
theta = (deltaTime / this.getAcceleration()),
powTime = theta * Math.pow(Math.E, -this.getSpringTension() * theta);
return this.getStartValue() + (this.getStartVelocity() * powTime);
}
});
Ext.define('Ext.fx.easing.BoundMomentum', {
extend: 'Ext.fx.easing.Abstract',
requires: [
'Ext.fx.easing.Momentum',
'Ext.fx.easing.Bounce'
],
config: {
momentum: null,
bounce: null,
minMomentumValue: 0,
maxMomentumValue: 0,
minVelocity: 0.01,
startVelocity: 0
},
applyMomentum: function(config, currentEasing) {
return Ext.factory(config, Ext.fx.easing.Momentum, currentEasing);
},
applyBounce: function(config, currentEasing) {
return Ext.factory(config, Ext.fx.easing.Bounce, currentEasing);
},
updateStartTime: function(startTime) {
this.getMomentum().setStartTime(startTime);
this.callParent(arguments);
},
updateStartVelocity: function(startVelocity) {
this.getMomentum().setStartVelocity(startVelocity);
},
updateStartValue: function(startValue) {
this.getMomentum().setStartValue(startValue);
},
reset: function() {
this.lastValue = null;
this.isBouncingBack = false;
this.isOutOfBound = false;
return this.callParent(arguments);
},
getValue: function() {
var momentum = this.getMomentum(),
bounce = this.getBounce(),
startVelocity = momentum.getStartVelocity(),
direction = startVelocity > 0 ? 1 : -1,
minValue = this.getMinMomentumValue(),
maxValue = this.getMaxMomentumValue(),
boundedValue = (direction == 1) ? maxValue : minValue,
lastValue = this.lastValue,
value, velocity;
if (startVelocity === 0) {
return this.getStartValue();
}
if (!this.isOutOfBound) {
value = momentum.getValue();
velocity = momentum.getVelocity();
if (Math.abs(velocity) < this.getMinVelocity()) {
this.isEnded = true;
}
if (value >= minValue && value <= maxValue) {
return value;
}
this.isOutOfBound = true;
bounce.setStartTime(Ext.Date.now()).setStartVelocity(velocity).setStartValue(boundedValue);
}
value = bounce.getValue();
if (!this.isEnded) {
if (!this.isBouncingBack) {
if (lastValue !== null) {
if ((direction == 1 && value < lastValue) || (direction == -1 && value > lastValue)) {
this.isBouncingBack = true;
}
}
} else {
if (Math.round(value) == boundedValue) {
this.isEnded = true;
}
}
}
this.lastValue = value;
return value;
}
});
Ext.define('Ext.fx.easing.Linear', {
extend: 'Ext.fx.easing.Abstract',
alias: 'easing.linear',
config: {
duration: 0,
endValue: 0
},
updateStartValue: function(startValue) {
this.distance = this.getEndValue() - startValue;
},
updateEndValue: function(endValue) {
this.distance = endValue - this.getStartValue();
},
getValue: function() {
var deltaTime = Ext.Date.now() - this.getStartTime(),
duration = this.getDuration();
if (deltaTime > duration) {
this.isEnded = true;
return this.getEndValue();
} else {
return this.getStartValue() + ((deltaTime / duration) * this.distance);
}
}
});
Ext.define('Ext.fx.easing.EaseOut', {
extend: 'Ext.fx.easing.Linear',
alias: 'easing.ease-out',
config: {
exponent: 4,
duration: 1500
},
getValue: function() {
var deltaTime = Ext.Date.now() - this.getStartTime(),
duration = this.getDuration(),
startValue = this.getStartValue(),
endValue = this.getEndValue(),
distance = this.distance,
theta = deltaTime / duration,
thetaC = 1 - theta,
thetaEnd = 1 - Math.pow(thetaC, this.getExponent()),
currentValue = startValue + (thetaEnd * distance);
if (deltaTime >= duration) {
this.isEnded = true;
return endValue;
}
return currentValue;
}
});
Ext.define('Ext.util.translatable.Abstract', {
extend: 'Ext.Evented',
requires: [
'Ext.fx.easing.Linear'
],
config: {
useWrapper: null,
easing: null,
easingX: null,
easingY: null
},
x: 0,
y: 0,
activeEasingX: null,
activeEasingY: null,
isAnimating: false,
isTranslatable: true,
constructor: function(config) {
this.mixins.observable.constructor.call(this, config);
this.position = {
x: 0,
y: 0
};
},
factoryEasing: function(easing) {
return Ext.factory(easing, Ext.fx.easing.Linear, null, 'easing');
},
applyEasing: function(easing) {
if (!this.getEasingX()) {
this.setEasingX(this.factoryEasing(easing));
}
if (!this.getEasingY()) {
this.setEasingY(this.factoryEasing(easing));
}
},
applyEasingX: function(easing) {
return this.factoryEasing(easing);
},
applyEasingY: function(easing) {
return this.factoryEasing(easing);
},
doTranslate: Ext.emptyFn,
translate: function(x, y, animation) {
if (animation) {
return this.translateAnimated(x, y, animation);
}
if (this.isAnimating) {
this.stopAnimation();
}
if (!isNaN(x) && typeof x == 'number') {
this.x = x;
}
if (!isNaN(y) && typeof y == 'number') {
this.y = y;
}
this.doTranslate(x, y);
},
translateAxis: function(axis, value, animation) {
var x, y;
if (axis == 'x') {
x = value;
} else {
y = value;
}
return this.translate(x, y, animation);
},
getPosition: function() {
var me = this,
position = me.position;
position.x = -me.x;
position.y = -me.y;
return position;
},
animate: function(easingX, easingY) {
this.activeEasingX = easingX;
this.activeEasingY = easingY;
this.isAnimating = true;
this.lastX = null;
this.lastY = null;
Ext.AnimationQueue.start(this.doAnimationFrame, this);
this.fireEvent('animationstart', this, this.x, this.y);
return this;
},
translateAnimated: function(x, y, animation) {
var me = this;
if (!Ext.isObject(animation)) {
animation = {};
}
if (me.isAnimating) {
me.stopAnimation();
}
me.callback = animation.callback;
me.callbackScope = animation.scope;
var now = Ext.Date.now(),
easing = animation.easing,
easingX = (typeof x == 'number') ? (animation.easingX || easing || me.getEasingX() || true) : null,
easingY = (typeof y == 'number') ? (animation.easingY || easing || me.getEasingY() || true) : null;
if (easingX) {
easingX = me.factoryEasing(easingX);
easingX.setStartTime(now);
easingX.setStartValue(me.x);
easingX.setEndValue(x);
if ('duration' in animation) {
easingX.setDuration(animation.duration);
}
}
if (easingY) {
easingY = me.factoryEasing(easingY);
easingY.setStartTime(now);
easingY.setStartValue(me.y);
easingY.setEndValue(y);
if ('duration' in animation) {
easingY.setDuration(animation.duration);
}
}
return me.animate(easingX, easingY);
},
doAnimationFrame: function() {
var me = this,
easingX = me.activeEasingX,
easingY = me.activeEasingY,
now = Date.now(),
x, y;
if (!me.isAnimating) {
return;
}
me.lastRun = now;
if (easingX === null && easingY === null) {
me.stopAnimation();
return;
}
if (easingX !== null) {
me.x = x = Math.round(easingX.getValue());
if (easingX.isEnded) {
me.activeEasingX = null;
me.fireEvent('axisanimationend', me, 'x', x);
}
} else {
x = me.x;
}
if (easingY !== null) {
me.y = y = Math.round(easingY.getValue());
if (easingY.isEnded) {
me.activeEasingY = null;
me.fireEvent('axisanimationend', me, 'y', y);
}
} else {
y = me.y;
}
if (me.lastX !== x || me.lastY !== y) {
me.doTranslate(x, y);
me.lastX = x;
me.lastY = y;
}
me.fireEvent('animationframe', me, x, y);
},
stopAnimation: function() {
var me = this;
if (!me.isAnimating) {
return;
}
me.activeEasingX = null;
me.activeEasingY = null;
me.isAnimating = false;
Ext.AnimationQueue.stop(me.doAnimationFrame, me);
me.fireEvent('animationend', me, me.x, me.y);
if (me.callback) {
me.callback.call(me.callbackScope);
me.callback = null;
}
},
refresh: function() {
this.translate(this.x, this.y);
},
destroy: function() {
if (this.isAnimating) {
this.stopAnimation();
}
this.callParent(arguments);
}
});
Ext.define('Ext.util.translatable.Dom', {
extend: 'Ext.util.translatable.Abstract',
config: {
element: null
},
applyElement: function(element) {
if (!element) {
return;
}
return Ext.get(element);
},
updateElement: function() {
this.refresh();
}
});
Ext.define('Ext.util.translatable.CssTransform', {
extend: 'Ext.util.translatable.Dom',
doTranslate: function(x, y) {
var element = this.getElement();
if (!this.isDestroyed && !element.isDestroyed) {
element.translate(x, y);
}
},
destroy: function() {
var element = this.getElement();
if (element && !element.isDestroyed) {
element.dom.style.webkitTransform = null;
}
this.callParent();
}
});
Ext.define('Ext.util.translatable.ScrollPosition', {
extend: 'Ext.util.translatable.Dom',
type: 'scrollposition',
config: {
useWrapper: true
},
getWrapper: function() {
var wrapper = this.wrapper,
element = this.getElement(),
container;
if (!wrapper) {
container = element.getParent();
if (!container) {
return null;
}
if (container.hasCls(Ext.baseCSSPrefix + 'translatable-hboxfix')) {
container = container.getParent();
}
if (this.getUseWrapper()) {
wrapper = element.wrap();
} else {
wrapper = container;
}
element.addCls(Ext.baseCSSPrefix + 'translatable');
wrapper.addCls(Ext.baseCSSPrefix + 'translatable-container');
this.wrapper = wrapper;
wrapper.on('painted', function() {
if (!this.isAnimating) {
this.refresh();
}
}, this);
this.refresh();
}
return wrapper;
},
doTranslate: function(x, y) {
var wrapper = this.getWrapper(),
dom;
if (wrapper) {
dom = wrapper.dom;
if (typeof x == 'number') {
dom.scrollLeft = 500000 - x;
}
if (typeof y == 'number') {
dom.scrollTop = 500000 - y;
}
}
},
destroy: function() {
var element = this.getElement(),
wrapper = this.wrapper;
if (wrapper) {
if (!element.isDestroyed) {
if (this.getUseWrapper()) {
wrapper.doReplaceWith(element);
}
element.removeCls(Ext.baseCSSPrefix + 'translatable');
}
if (!wrapper.isDestroyed) {
wrapper.removeCls(Ext.baseCSSPrefix + 'translatable-container');
wrapper.un('painted', 'refresh', this);
}
delete this.wrapper;
delete this._element;
}
this.callParent();
}
});
Ext.define('Ext.util.translatable.ScrollParent', {
extend: 'Ext.util.translatable.Dom',
isScrollParent: true,
applyElement: function(element) {
var el = Ext.get(element);
if (el) {
this.parent = el.parent();
}
return el;
},
doTranslate: function(x, y) {
var parent = this.parent;
parent.setScrollLeft(Math.round(-x));
parent.setScrollTop(Math.round(-y));
},
getPosition: function() {
var me = this,
position = me.position,
parent = me.parent;
position.x = parent.getScrollLeft();
position.y = parent.getScrollTop();
return position;
}
});
Ext.define('Ext.util.translatable.CssPosition', {
extend: 'Ext.util.translatable.Dom',
doTranslate: function(x, y) {
var domStyle = this.getElement().dom.style;
if (typeof x == 'number') {
domStyle.left = x + 'px';
}
if (typeof y == 'number') {
domStyle.top = y + 'px';
}
},
destroy: function() {
var domStyle = this.getElement().dom.style;
domStyle.left = null;
domStyle.top = null;
this.callParent(arguments);
}
});
Ext.define('Ext.util.Translatable', {
requires: [
'Ext.util.translatable.CssTransform',
'Ext.util.translatable.ScrollPosition',
'Ext.util.translatable.ScrollParent',
'Ext.util.translatable.CssPosition'
],
constructor: function(config) {
var namespace = Ext.util.translatable;
switch (Ext.browser.getPreferredTranslationMethod(config)) {
case 'scrollposition':
return new namespace.ScrollPosition(config);
case 'scrollparent':
return new namespace.ScrollParent(config);
case 'csstransform':
return new namespace.CssTransform(config);
case 'cssposition':
return new namespace.CssPosition(config);
}
}
});
Ext.define('Ext.scroll.Indicator', {
extend: 'Ext.Widget',
xtype: 'scrollindicator',
config: {
axis: null,
hideAnimation: true,
hideDelay: 0,
scroller: null,
minLength: 24
},
defaultHideAnimation: {
to: {
opacity: 0
},
duration: 300
},
names: {
x: {
side: 'l',
getSize: 'getHeight',
setLength: 'setWidth',
translate: 'translateX'
},
y: {
side: 't',
getSize: 'getWidth',
setLength: 'setHeight',
translate: 'translateY'
}
},
oppositeAxis: {
x: 'y',
y: 'x'
},
cls: Ext.baseCSSPrefix + 'scroll-indicator',
applyHideAnimation: function(hideAnimation) {
if (hideAnimation) {
hideAnimation = Ext.mergeIf({
onEnd: this.onHideAnimationEnd,
scope: this
}, this.defaultHideAnimation, hideAnimation);
}
return hideAnimation;
},
constructor: function(config) {
var me = this,
axis;
me.callParent([
config
]);
axis = me.getAxis();
me.names = me.names[axis];
me.element.addCls(me.cls + ' ' + me.cls + '-' + axis);
},
hide: function() {
var me = this,
delay = me.getHideDelay();
if (delay) {
me._hideTimer = Ext.defer(me.doHide, delay, me);
} else {
me.doHide();
}
},
setValue: function(value) {
var me = this,
el = me.element,
names = me.names,
axis = me.getAxis(),
scroller = me.getScroller(),
maxScrollPosition = scroller.getMaxUserPosition()[axis],
elementSize = scroller.getElementSize()[axis],
baseLength = me.length,
minLength = me.getMinLength(),
length = baseLength,
maxPosition = elementSize - baseLength - me.sizeAdjust,
round = Math.round,
max = Math.max,
position;
if (value < 0) {
length = round(max(baseLength + (baseLength * value / elementSize), minLength));
position = 0;
} else if (value > maxScrollPosition) {
length = round(max(baseLength - (baseLength * (value - maxScrollPosition) / elementSize), minLength));
position = maxPosition + baseLength - length;
} else {
position = round(value / maxScrollPosition * maxPosition);
}
me[names.translate](position);
el[names.setLength](length);
},
show: function() {
var me = this,
el = me.element,
anim = el.getActiveAnimation();
if (anim) {
anim.end();
}
if (!me._inDom) {
me.getScroller().getElement().appendChild(el);
me._inDom = true;
if (!me.size) {
me.cacheStyles();
}
}
me.refreshLength();
clearTimeout(me._hideTimer);
el.setStyle('opacity', '');
},
privates: {
cacheStyles: function() {
var me = this,
el = me.element,
names = me.names;
me.size = el[names.getSize]();
me.margin = el.getMargin(names.side);
},
doHide: function() {
var animation = this.getHideAnimation(),
el = this.element;
if (animation) {
el.animate(animation);
} else {
el.setStyle('opacity', 0);
}
},
hasOpposite: function() {
return this.getScroller().isAxisEnabled(this.oppositeAxis[this.getAxis()]);
},
onHideAnimationEnd: function() {
this.element.setStyle('opacity', '0');
},
refreshLength: function() {
var me = this,
names = me.names,
axis = me.getAxis(),
scroller = me.getScroller(),
scrollSize = scroller.getSize()[axis],
elementSize = scroller.getElementSize()[axis],
ratio = elementSize / scrollSize,
baseSizeAdjust = me.margin * 2,
sizeAdjust = me.hasOpposite() ? (baseSizeAdjust + me.size) : baseSizeAdjust,
length = Math.max(Math.round((elementSize - sizeAdjust) * ratio), me.getMinLength());
me.sizeAdjust = sizeAdjust;
me.length = length;
me.element[names.setLength](length);
},
translateX: function(value) {
this.element.translate(value);
},
translateY: function(value) {
this.element.translate(0, value);
}
}
});
Ext.define('Ext.scroll.TouchScroller', {
extend: 'Ext.scroll.Scroller',
alias: 'scroller.touch',
requires: [
'Ext.fx.easing.BoundMomentum',
'Ext.fx.easing.EaseOut',
'Ext.util.Translatable',
'Ext.scroll.Indicator',
'Ext.GlobalEvents'
],
isTouchScroller: true,
config: {
autoRefresh: true,
bounceEasing: {
duration: 400
},
elementSize: undefined,
indicators: true,
fps: 'auto',
maxAbsoluteVelocity: 6,
momentumEasing: {
momentum: {
acceleration: 30,
friction: 0.5
},
bounce: {
acceleration: 30,
springTension: 0.3
},
minVelocity: 1
},
outOfBoundRestrictFactor: 0.5,
innerElement: null,
size: undefined,
slotSnapEasing: {
duration: 150
},
slotSnapSize: {
x: 0,
y: 0
},
slotSnapOffset: {
x: 0,
y: 0
},
startMomentumResetTime: 300,
translatable: {
translationMethod: 'auto',
useWrapper: false
}
},
cls: Ext.baseCSSPrefix + 'scroll-container',
scrollerCls: Ext.baseCSSPrefix + 'scroll-scroller',
dragStartTime: 0,
dragEndTime: 0,
isDragging: false,
isAnimating: false,
isMouseEvent: {
mousedown: 1,
mousemove: 1,
mouseup: 1
},
listenerMap: {
touchstart: 'onTouchStart',
touchmove: 'onTouchMove',
dragstart: 'onDragStart',
drag: 'onDrag',
dragend: 'onDragEnd'
},
refreshCounter: 0,
constructor: function(config) {
var me = this,
onEvent = 'onEvent';
me.elementListeners = {
touchstart: onEvent,
touchmove: onEvent,
dragstart: onEvent,
drag: onEvent,
dragend: onEvent,
scope: me
};
me.minPosition = {
x: 0,
y: 0
};
me.startPosition = {
x: 0,
y: 0
};
me.position = {
x: 0,
y: 0
};
me.velocity = {
x: 0,
y: 0
};
me.isAxisEnabledFlags = {
x: false,
y: false
};
me.flickStartPosition = {
x: 0,
y: 0
};
me.flickStartTime = {
x: 0,
y: 0
};
me.lastDragPosition = {
x: 0,
y: 0
};
me.dragDirection = {
x: 0,
y: 0
};
Ext.GlobalEvents.on('idle', me.onIdle, me);
me.callParent([
config
]);
me.refreshAxes();
},
applyBounceEasing: function(easing) {
var defaultClass = Ext.fx.easing.EaseOut;
return {
x: Ext.factory(easing, defaultClass),
y: Ext.factory(easing, defaultClass)
};
},
applyElementSize: function(size) {
var el = this.getElement(),
dom, x, y;
if (!el) {
return null;
}
dom = el.dom;
if (!dom) {
return;
}
if (size == null) {
x = dom.clientWidth;
y = dom.clientHeight;
} else {
x = size.x;
y = size.y;
}
return {
x: x,
y: y
};
},
applyIndicators: function(indicators, oldIndicators) {
var me = this,
xIndicator, yIndicator, x, y;
if (indicators) {
if (indicators === true) {
xIndicator = yIndicator = {};
} else {
x = indicators.x;
y = indicators.y;
if (x || y) {
xIndicator = (x == null || x === true) ? {} : x;
yIndicator = (x == null || y === true) ? {} : y;
} else {
xIndicator = yIndicator = indicators;
}
}
if (oldIndicators) {
if (xIndicator) {
oldIndicators.x.setConfig(xIndicator);
} else {
oldIndicators.x.destroy();
oldIndicators.x = null;
}
if (yIndicator) {
oldIndicators.y.setConfig(yIndicator);
} else {
oldIndicators.y.destroy();
oldIndicators.y = null;
}
indicators = oldIndicators;
} else {
indicators = {
x: null,
y: null
};
if (xIndicator) {
indicators.x = new Ext.scroll.Indicator(Ext.applyIf({
axis: 'x',
scroller: me
}, xIndicator));
}
if (yIndicator) {
indicators.y = new Ext.scroll.Indicator(Ext.applyIf({
axis: 'y',
scroller: me
}, yIndicator));
}
}
} else if (oldIndicators) {
oldIndicators.x.destroy();
oldIndicators.y.destroy();
oldIndicators.x = null;
oldIndicators.y = null;
}
return indicators;
},
applyMomentumEasing: function(easing) {
var defaultClass = Ext.fx.easing.BoundMomentum;
return {
x: Ext.factory(easing, defaultClass),
y: Ext.factory(easing, defaultClass)
};
},
applyInnerElement: function(innerElement) {
if (innerElement && !innerElement.isElement) {
innerElement = Ext.get(innerElement);
}
if (this.isConfiguring && !innerElement) {
Ext.Error.raise("Cannot create Ext.scroll.TouchScroller instance with null innerElement");
}
return innerElement;
},
applySize: function(size) {
var el, dom, scrollerDom, x, y;
if (size == null) {
el = this.getElement();
if (!el) {
return null;
}
dom = el.dom;
scrollerDom = this.getInnerElement().dom;
x = Math.max(scrollerDom.scrollWidth, dom.clientWidth);
y = Math.max(scrollerDom.scrollHeight, dom.clientHeight);
} else if (typeof size === 'number') {
x = size;
y = size;
} else {
x = size.x;
y = size.y;
}
return {
x: x,
y: y
};
},
applySlotSnapOffset: function(snapOffset) {
if (typeof snapOffset === 'number') {
return {
x: snapOffset,
y: snapOffset
};
}
return snapOffset;
},
applySlotSnapSize: function(snapSize) {
if (typeof snapSize === 'number') {
return {
x: snapSize,
y: snapSize
};
}
return snapSize;
},
applySlotSnapEasing: function(easing) {
var defaultClass = Ext.fx.easing.EaseOut;
return {
x: Ext.factory(easing, defaultClass),
y: Ext.factory(easing, defaultClass)
};
},
applyTranslatable: function(config, translatable) {
return Ext.factory(config, Ext.util.Translatable, translatable);
},
destroy: function() {
var me = this,
element = me.getElement(),
innerElement = me.getInnerElement(),
sizeMonitors = me.sizeMonitors;
if (sizeMonitors) {
sizeMonitors.element.destroy();
sizeMonitors.container.destroy();
}
if (element && !element.isDestroyed) {
element.removeCls(me.cls);
}
if (innerElement && !innerElement.isDestroyed) {
innerElement.removeCls(me.scrollerCls);
}
if (me._isWrapped) {
if (!element.isDestroyed) {
me.unwrapContent();
}
innerElement.destroy();
if (me.FixedHBoxStretching) {
innerElement.parent().destroy();
}
}
me.setElement(null);
me.setInnerElement(null);
Ext.GlobalEvents.un('idle', me.onIdle, me);
Ext.destroy(me.getTranslatable());
me.callParent(arguments);
},
getPosition: function() {
return this.position;
},
refresh: function(immediate,
options) {
++this.refreshCounter;
if (immediate) {
this.doRefresh(options);
}
},
updateAutoRefresh: function(autoRefresh) {
this.toggleResizeListeners(autoRefresh);
},
updateBounceEasing: function(easing) {
this.getTranslatable().setEasingX(easing.x).setEasingY(easing.y);
},
updateElementSize: function() {
if (!this.isConfiguring) {
this.refreshAxes();
}
},
updateDisabled: function(disabled) {
if (!this.isConfiguring) {
if (disabled) {
this.detachListeners();
} else {
this.attachListeners();
}
}
},
updateElement: function(element, oldElement) {
var me = this,
innerElement = me.getInnerElement(),
fixedHBoxStretching = this.FixedHBoxStretching,
listeners;
if (!innerElement) {
innerElement = element.dom.firstChild;
if (fixedHBoxStretching && innerElement) {
innerElement = innerElement.dom.firstChild;
}
if (!innerElement || innerElement.nodeType !== 1 || !Ext.fly(innerElement).hasCls(me.scrollerCls)) {
innerElement = me.wrapContent(element);
}
me.setInnerElement(innerElement);
}
if (!fixedHBoxStretching) {
element.addCls(me.cls);
}
if (me.isConfiguring) {
if (!me.getTranslatable().isScrollParent) {
listeners = me.elementListeners;
listeners.mousewheel = 'onMouseWheel';
listeners.scroll = {
fn: 'onElementScroll',
delegated: false,
scope: me
};
}
}
if (!me.getDisabled()) {
me.attachListeners();
}
if (!me.isConfiguring) {
if (me.getAutoRefresh()) {
me.toggleResizeListeners(true);
}
me.setSize(null);
me.setElementSize(null);
}
me.callParent([
element,
oldElement
]);
},
updateFps: function(fps) {
if (fps !== 'auto') {
this.getTranslatable().setFps(fps);
}
},
updateMaxUserPosition: function() {
this.snapToBoundary();
},
updateMinUserPosition: function() {
this.snapToBoundary();
},
updateInnerElement: function(innerElement) {
if (innerElement) {
innerElement.addCls(this.scrollerCls);
}
this.getTranslatable().setElement(innerElement);
},
updateSize: function() {
if (!this.isConfiguring) {
this.refreshAxes();
}
},
updateTranslatable: function(translatable) {
translatable.setElement(this.getInnerElement());
translatable.on({
animationframe: 'onAnimationFrame',
animationend: 'onAnimationEnd',
scope: this
});
},
updateX: function() {
if (!this.isConfiguring) {
this.refreshAxes();
}
},
updateY: function() {
if (!this.isConfiguring) {
this.refreshAxes();
}
},
privates: {
attachListeners: function() {
this.getElement().on(this.elementListeners);
},
constrainX: function(x) {
return Math.min(this.getMaxPosition().x, Math.max(x, 0));
},
constrainY: function(y) {
return Math.min(this.getMaxPosition().y, Math.max(y, 0));
},
convertEasingConfig: function(config) {
return config;
},
detachListeners: function() {
this.getElement().un(this.elementListeners);
},
doRefresh: function(options) {
var me = this,
size, elementSize;
if (me.refreshCounter && me.getElement()) {
me.stopAnimation();
me.getTranslatable().refresh();
if (options) {
size = options.size;
elementSize = options.elementSize;
if (size) {
me.setSize(size);
}
if (elementSize) {
me.setElementSize(elementSize);
}
} else {
me.setSize(null);
me.setElementSize(null);
}
me.fireEvent('refresh', me);
me.refreshCounter = 0;
}
},
doScrollTo: function(x, y, animation,
allowOverscroll) {
var me = this,
isDragging = me.isDragging,
fireScrollCallback;
if (me.isDestroyed || !me.getElement()) {
return me;
}
allowOverscroll = allowOverscroll || me.isDragging;
var translatable = me.getTranslatable(),
position = me.position,
positionChanged = false,
translationX, translationY;
if (!isDragging || me.isAxisEnabled('x')) {
if (isNaN(x) || typeof x !== 'number') {
x = position.x;
} else {
if (!allowOverscroll) {
x = me.constrainX(x);
}
if (position.x !== x) {
position.x = x;
positionChanged = true;
}
}
translationX = me.convertX(-x);
}
if (!isDragging || me.isAxisEnabled('y')) {
if (isNaN(y) || typeof y !== 'number') {
y = position.y;
} else {
if (!allowOverscroll) {
y = me.constrainY(y);
}
if (position.y !== y) {
position.y = y;
positionChanged = true;
}
}
translationY = -y;
}
if (positionChanged) {
if (animation) {
fireScrollCallback = function() {
me.onScroll();
};
if (animation === true) {
animation = {
callback: fireScrollCallback
};
}
else if (animation.callback) {
animation.callback = Ext.Function.createSequence(animation.callback, fireScrollCallback);
} else
{
animation.callback = fireScrollCallback;
}
translatable.translateAnimated(translationX, translationY, animation);
} else {
translatable.translate(translationX, translationY);
me.onScroll();
}
}
return me;
},
getAnimationEasing: function(axis, e) {
if (!this.isAxisEnabled(axis)) {
return null;
}
var me = this,
currentPosition = me.position[axis],
minPosition = me.getMinUserPosition()[axis],
maxPosition = me.getMaxUserPosition()[axis],
maxAbsVelocity = me.getMaxAbsoluteVelocity(),
boundValue = null,
dragEndTime = me.dragEndTime,
velocity = e.flick.velocity[axis],
isX = axis === 'x',
easingConfig, easing;
if (currentPosition < minPosition) {
boundValue = minPosition;
} else if (currentPosition > maxPosition) {
boundValue = maxPosition;
}
if (isX) {
currentPosition = me.convertX(currentPosition);
boundValue = me.convertX(boundValue);
}
if (boundValue !== null) {
easing = me.getBounceEasing()[axis];
easing.setConfig({
startTime: dragEndTime,
startValue: -currentPosition,
endValue: -boundValue
});
return easing;
}
if (velocity === 0) {
return null;
}
if (velocity < -maxAbsVelocity) {
velocity = -maxAbsVelocity;
} else if (velocity > maxAbsVelocity) {
velocity = maxAbsVelocity;
}
if (Ext.browser.is.IE) {
velocity *= 2;
}
easing = me.getMomentumEasing()[axis];
easingConfig = {
startTime: dragEndTime,
startValue: -currentPosition,
startVelocity: velocity * 1.5,
minMomentumValue: -maxPosition,
maxMomentumValue: 0
};
if (isX) {
me.convertEasingConfig(easingConfig);
}
easing.setConfig(easingConfig);
return easing;
},
getSnapPosition: function(axis) {
var me = this,
snapSize = me.getSlotSnapSize()[axis],
snapPosition = null,
position, snapOffset, maxPosition, mod;
if (snapSize !== 0 && me.isAxisEnabled(axis)) {
position = me.position[axis];
snapOffset = me.getSlotSnapOffset()[axis];
maxPosition = me.getMaxUserPosition()[axis];
mod = Math.floor((position - snapOffset) % snapSize);
if (mod !== 0) {
if (position !== maxPosition) {
if (Math.abs(mod) > snapSize / 2) {
snapPosition = Math.min(maxPosition, position + ((mod > 0) ? snapSize - mod : mod - snapSize));
} else {
snapPosition = position - mod;
}
} else {
snapPosition = position - mod;
}
}
}
return snapPosition;
},
hideIndicators: function() {
var me = this,
indicators = me.getIndicators(),
xIndicator, yIndicator;
if (indicators) {
if (me.isAxisEnabled('x')) {
xIndicator = indicators.x;
if (xIndicator) {
xIndicator.hide();
}
}
if (me.isAxisEnabled('y')) {
yIndicator = indicators.y;
if (yIndicator) {
yIndicator.hide();
}
}
}
},
isAxisEnabled: function(axis) {
this.getX();
this.getY();
return this.isAxisEnabledFlags[axis];
},
onAnimationEnd: function() {
this.snapToBoundary();
this.onScrollEnd();
},
onAnimationFrame: function(translatable, x, y) {
var position = this.position;
position.x = this.convertX(-x);
position.y = -y;
this.onScroll();
},
onAxisDrag: function(axis, delta) {
if (!this.isAxisEnabled(axis)) {
return;
}
var me = this,
flickStartPosition = me.flickStartPosition,
flickStartTime = me.flickStartTime,
lastDragPosition = me.lastDragPosition,
dragDirection = me.dragDirection,
old = me.position[axis],
min = me.getMinUserPosition()[axis],
max = me.getMaxUserPosition()[axis],
start = me.startPosition[axis],
last = lastDragPosition[axis],
current = start - delta,
lastDirection = dragDirection[axis],
restrictFactor = me.getOutOfBoundRestrictFactor(),
startMomentumResetTime = me.getStartMomentumResetTime(),
now = Ext.Date.now(),
distance;
if (current < min) {
current *= restrictFactor;
} else if (current > max) {
distance = current - max;
current = max + distance * restrictFactor;
}
if (current > last) {
dragDirection[axis] = 1;
} else if (current < last) {
dragDirection[axis] = -1;
}
if ((lastDirection !== 0 && (dragDirection[axis] !== lastDirection)) || (now - flickStartTime[axis]) > startMomentumResetTime) {
flickStartPosition[axis] = old;
flickStartTime[axis] = now;
}
lastDragPosition[axis] = current;
},
onDomScroll: function() {
var me = this,
dom, position;
if (me.getTranslatable().isScrollParent) {
dom = me.getElement().dom;
position = me.position;
position.x = dom.scrollLeft;
position.y = dom.scrollTop;
}
me.callParent();
},
onDrag: function(e) {
var me = this,
lastDragPosition = me.lastDragPosition;
if (!me.isDragging) {
return;
}
me.onAxisDrag('x', me.convertX(e.deltaX));
me.onAxisDrag('y', e.deltaY);
me.doScrollTo(lastDragPosition.x, lastDragPosition.y);
},
onDragEnd: function(e) {
var me = this,
easingX, easingY;
if (!me.isDragging) {
return;
}
me.dragEndTime = Ext.Date.now();
me.onDrag(e);
me.isDragging = false;
easingX = me.getAnimationEasing('x', e);
easingY = me.getAnimationEasing('y', e);
if (easingX || easingY) {
me.getTranslatable().animate(easingX, easingY);
} else {
me.onScrollEnd();
}
},
onDragStart: function(e) {
var me = this,
direction = me.getDirection(),
absDeltaX = e.absDeltaX,
absDeltaY = e.absDeltaY,
directionLock = me.getDirectionLock(),
startPosition = me.startPosition,
flickStartPosition = me.flickStartPosition,
flickStartTime = me.flickStartTime,
lastDragPosition = me.lastDragPosition,
currentPosition = me.position,
dragDirection = me.dragDirection,
x = currentPosition.x,
y = currentPosition.y,
now = Ext.Date.now();
me.isDragging = true;
if (directionLock && direction !== 'both') {
if ((direction === 'horizontal' && absDeltaX > absDeltaY) || (direction === 'vertical' && absDeltaY > absDeltaX)) {
e.stopPropagation();
} else {
me.isDragging = false;
return;
}
}
lastDragPosition.x = x;
lastDragPosition.y = y;
flickStartPosition.x = x;
flickStartPosition.y = y;
startPosition.x = x;
startPosition.y = y;
flickStartTime.x = now;
flickStartTime.y = now;
dragDirection.x = 0;
dragDirection.y = 0;
me.dragStartTime = now;
me.isDragging = true;
me.onScrollStart();
},
onElementResize: function(element, info) {
this.refresh(true, {
elementSize: {
x: info.width,
y: info.height
}
});
},
onElementScroll: function(event, targetEl) {
targetEl.scrollTop = targetEl.scrollLeft = 0;
},
onEvent: function(e) {
var me = this,
browserEvent = e.browserEvent;
if ((!me.self.isTouching || me.isTouching) &&
((!me.getTranslatable().isScrollParent) || (!me.isMouseEvent[browserEvent.type] && browserEvent.pointerType !== 'mouse')) && (me.getY() || me.getX())) {
me[me.listenerMap[e.type]](e);
}
},
onIdle: function() {
this.doRefresh();
},
onInnerElementResize: function(element, info) {
this.refresh(true, {
size: {
x: info.width,
y: info.height
}
});
},
onMouseWheel: function(e) {
var me = this,
delta = e.getWheelDeltas(),
deltaX = -delta.x,
deltaY = -delta.y,
position = me.position,
maxPosition = me.getMaxUserPosition(),
minPosition = me.getMinUserPosition(),
max = Math.max,
min = Math.min,
positionX = max(min(position.x + deltaX, maxPosition.x), minPosition.x),
positionY = max(min(position.y + deltaY, maxPosition.y), minPosition.y);
deltaX = positionX - position.x;
deltaY = positionY - position.y;
if (!deltaX && !deltaY) {
return;
}
e.stopEvent();
me.onScrollStart();
me.scrollBy(deltaX, deltaY);
me.onScroll();
me.onScrollEnd();
},
onPartnerScrollEnd: function() {
this.hideIndicators();
},
onPartnerScrollStart: function() {
this.showIndicators();
},
onScroll: function() {
var me = this,
position = me.position,
x = position.x,
y = position.y,
indicators = me.getIndicators(),
xIndicator, yIndicator;
if (indicators) {
if (me.isAxisEnabled('x')) {
xIndicator = indicators.x;
if (xIndicator) {
xIndicator.setValue(x);
}
}
if (me.isAxisEnabled('y')) {
yIndicator = indicators.y;
if (yIndicator) {
yIndicator.setValue(y);
}
}
}
me.fireScroll(x, y);
},
onScrollEnd: function() {
var me = this,
position = me.position;
if (!me.isTouching && !me.snapToSlot()) {
me.hideIndicators();
Ext.isScrolling = false;
me.fireScrollEnd(position.x, position.y);
}
},
onScrollStart: function() {
var me = this,
position = me.position;
me.showIndicators();
Ext.isScrolling = true;
me.fireScrollStart(position.x, position.y);
},
onTouchEnd: function() {
var me = this;
me.isTouching = me.self.isTouching = false;
if (!me.isDragging && me.snapToSlot()) {
me.onScrollStart();
}
},
onTouchMove: function(e) {
e.preventDefault();
},
onTouchStart: function() {
var me = this;
me.isTouching = me.self.isTouching = true;
Ext.getDoc().on({
touchend: 'onTouchEnd',
scope: me,
single: true
});
me.stopAnimation();
},
refreshAxes: function() {
var me = this,
flags = me.isAxisEnabledFlags,
size = me.getSize(),
elementSize = me.getElementSize(),
indicators = me.getIndicators(),
maxX, maxY, x, y, xIndicator, yIndicator;
if (!size || !elementSize) {
return;
}
maxX = Math.max(0, size.x - elementSize.x);
maxY = Math.max(0, size.y - elementSize.y);
x = me.getX();
y = me.getY();
me.setMaxPosition({
x: maxX,
y: maxY
});
if (x === true || x === 'auto') {
flags.x = !!maxX;
} else if (x === false) {
flags.x = false;
xIndicator = indicators && indicators.x;
if (xIndicator) {
xIndicator.hide();
}
} else if (x === 'scroll') {
flags.x = true;
}
if (y === true || y === 'auto') {
flags.y = !!maxY;
} else if (y === false) {
flags.y = false;
yIndicator = indicators && indicators.y;
if (yIndicator) {
yIndicator.hide();
}
} else if (y === 'scroll') {
flags.y = true;
}
me.setMaxUserPosition({
x: flags.x ? maxX : 0,
y: flags.y ? maxY : 0
});
if (Ext.supports.touchScroll === 1) {
me.initXStyle();
me.initYStyle();
}
},
showIndicators: function() {
var me = this,
indicators = me.getIndicators(),
xIndicator, yIndicator;
if (indicators) {
if (me.isAxisEnabled('x')) {
xIndicator = indicators.x;
if (xIndicator) {
xIndicator.show();
}
}
if (me.isAxisEnabled('y')) {
yIndicator = indicators.y;
if (yIndicator) {
yIndicator.show();
}
}
}
},
snapToBoundary: function() {
if (this.isConfiguring) {
return;
}
var me = this,
position = me.position,
minPosition = me.getMinUserPosition(),
maxPosition = me.getMaxUserPosition(),
minX = minPosition.x,
minY = minPosition.y,
maxX = maxPosition.x,
maxY = maxPosition.y,
x = Math.round(position.x),
y = Math.round(position.y);
if (x < minX) {
x = minX;
} else if (x > maxX) {
x = maxX;
}
if (y < minY) {
y = minY;
} else if (y > maxY) {
y = maxY;
}
me.doScrollTo(x, y);
},
snapToSlot: function() {
var me = this,
snapX = me.getSnapPosition('x'),
snapY = me.getSnapPosition('y'),
easing = me.getSlotSnapEasing();
if (snapX !== null || snapY !== null) {
me.doScrollTo(snapX, snapY, {
easingX: easing.x,
easingY: easing.y
});
return true;
}
return false;
},
stopAnimation: function() {
this.getTranslatable().stopAnimation();
},
toggleResizeListeners: function(on) {
var me = this,
element = me.getElement(),
method = on ? 'on' : 'un';
if (element) {
element[method]('resize', 'onElementResize', me);
me.getInnerElement()[method]('resize', 'onInnerElementResize', me);
}
},
unwrapContent: function() {
var innerDom = this.getInnerElement().dom,
dom = this.getElement().dom,
child;
while ((child = innerDom.firstChild)) {
dom.insertBefore(child, innerDom);
}
},
wrapContent: function(element) {
var wrap = document.createElement('div'),
dom = element.dom,
child;
while (child = dom.lastChild) {
wrap.insertBefore(child, wrap.firstChild);
}
dom.appendChild(wrap);
this.setInnerElement(wrap);
this._isWrapped = true;
return this.getInnerElement();
}
}
});
Ext.define('Ext.scroll.DomScroller', {
extend: 'Ext.scroll.Scroller',
alias: 'scroller.dom',
isDomScroller: true,
getMaxPosition: function() {
var element = this.getElement(),
x = 0,
y = 0,
dom;
if (element && !element.isDestroyed) {
dom = element.dom;
x = dom.scrollWidth - dom.clientWidth;
y = dom.scrollHeight - dom.clientHeight;
}
return {
x: x,
y: y
};
},
getMaxUserPosition: function() {
var me = this,
element = me.getElement(),
x = 0,
y = 0,
dom;
if (element && !element.isDestroyed) {
dom = element.dom;
if (me.getX()) {
x = dom.scrollWidth - dom.clientWidth;
}
if (me.getY()) {
y = dom.scrollHeight - dom.clientHeight;
}
}
return {
x: x,
y: y
};
},
getPosition: function() {
var element = this.getElement(),
x = 0,
y = 0,
position;
if (element && !element.isDestroyed) {
position = this.getElementScroll(element);
x = position.left;
y = position.top;
}
return {
x: x,
y: y
};
},
getSize: function() {
var element = this.getElement(),
size, dom;
if (element && !element.isDestroyed) {
dom = element.dom;
size = {
x: dom.scrollWidth,
y: dom.scrollHeight
};
} else {
size = {
x: 0,
y: 0
};
}
return size;
},
setSize: Ext.emptyFn,
updateElement: function(element, oldElement) {
this.initXStyle();
this.initYStyle();
this.callParent([
element,
oldElement
]);
},
updateX: function(x) {
this.initXStyle();
},
updateY: function(y) {
this.initYStyle();
},
privates: {
doScrollTo: function(x, y, animate) {
var me = this,
element = me.getElement(),
maxPosition, dom, to, xInf, yInf;
if (element && !element.isDestroyed) {
dom = this.getElement().dom;
xInf = (x === Infinity);
yInf = (y === Infinity);
if (xInf || yInf) {
maxPosition = me.getMaxPosition();
if (xInf) {
x = maxPosition.x;
}
if (yInf) {
y = maxPosition.y;
}
}
x = me.convertX(x);
if (animate) {
to = {};
if (y != null) {
to.scrollTop = y;
}
if (x != null) {
to.scrollLeft = x;
}
element.animate(Ext.mergeIf({
to: {
scrollTop: y,
scrollLeft: x
}
}, animate));
} else {
if (y != null) {
dom.scrollTop = y;
}
if (x != null) {
dom.scrollLeft = x;
}
}
}
},
getElementScroll: function(element) {
return element.getScroll();
},
stopAnimation: function() {
var anim = this.getElement().getActiveAnimation();
if (anim) {
anim.end();
}
}
}
});
Ext.define('Ext.util.Floating', {
mixinId: 'floating',
uses: [
'Ext.ZIndexManager'
],
focusOnToFront: true,
shadow: 'sides',
animateShadow: false,
constrain: false,
config: {
activeCounter: 0,
alwaysOnTop: false
},
preventDefaultAlign: false,
_visModeMap: {
visibility: 1,
display: 2,
offsets: 3
},
constructor: function() {
var me = this,
el = me.el,
shadow = me.shadow,
shadowOffset, shadowConfig;
if (shadow) {
shadowConfig = {
mode: (shadow === true) ? 'sides' : shadow
};
shadowOffset = me.shadowOffset;
if (shadowOffset) {
shadowConfig.offset = shadowOffset;
}
shadowConfig.animate = me.animateShadow;
shadowConfig.fixed = me.fixed;
el.enableShadow(shadowConfig, false);
}
if (me.shim || Ext.useShims) {
el.enableShim({
fixed: me.fixed
}, false);
}
el.setVisibilityMode(me._visModeMap[me.hideMode]);
if (me.modal && !(Ext.enableFocusManager)) {
me.el.on('keydown', me.onKeyDown, me);
}
me.el.on({
mousedown: me.onMouseDown,
scope: me,
capture: true
});
me.registerWithOwnerCt();
me.initHierarchyEvents();
},
alignTo: function(element, position, offsets, animate) {
var me = this;
if (!me._lastAlignToEl) {
Ext.on('scroll', me.onAlignToScroll, me);
}
me._lastAlignToEl = element;
me._lastAlignToPos = position;
me.mixins.positionable.alignTo.call(me, element, position, offsets, animate);
},
initFloatConstrain: function() {
var me = this,
floatParent = me.floatParent;
if ((me.constrain || me.constrainHeader) && !me.constrainTo) {
me.constrainTo = floatParent ? floatParent.getTargetEl() : me.container;
}
},
initHierarchyEvents: function() {
var me = this,
syncHidden = this.syncHidden;
if (!me.hasHierarchyEventListeners) {
me.mon(Ext.GlobalEvents, {
hide: syncHidden,
collapse: syncHidden,
show: syncHidden,
expand: syncHidden,
added: syncHidden,
scope: me
});
me.hasHierarchyEventListeners = true;
}
},
registerWithOwnerCt: function() {
var me = this,
ownerCt = me.ownerCt,
zip = me.zIndexParent;
if (zip) {
zip.unregisterFloatingItem(me);
}
zip = me.zIndexParent = me.up('[floating]');
me.floatParent = ownerCt || zip;
me.initFloatConstrain();
delete me.ownerCt;
if (zip) {
zip.registerFloatingItem(me);
} else {
Ext.WindowManager.register(me);
}
},
onKeyDown: function(e) {
var me = this,
shift, focusables, first, last;
if (e.getKey() === e.TAB) {
shift = e.shiftKey;
focusables = me.query(':focusable');
if (focusables.length) {
first = focusables[0];
last = focusables[focusables.length - 1];
if (!shift && last.hasFocus) {
e.stopEvent();
first.focus();
} else if (shift && first.hasFocus) {
e.stopEvent();
last.focus();
}
}
}
},
onMouseDown: function(e) {
var me = this,
focusTask = me.focusTask,
parentEvent = e.parentEvent,
preventFocus = parentEvent && parentEvent.type === 'touchstart',
target, dom, skipFronting;
if (me.floating &&
(!focusTask || !focusTask.id)) {
target = e.target;
dom = me.el.dom;
while (!preventFocus && target && target !== dom) {
if (Ext.fly(target).isFocusable()) {
preventFocus = true;
}
target = target.parentNode;
}
skipFronting = Ext.WindowManager.getActive() === me && (target === dom || preventFocus);
if (!skipFronting) {
me.toFront(preventFocus);
}
}
},
onBeforeFloatLayout: function() {
this.el.preventSync = true;
},
onAfterFloatLayout: function() {
var el = this.el;
if (el.shadow || el.shim) {
el.setUnderlaysVisible(true);
el.syncUnderlays();
}
},
syncHidden: function() {
var me = this,
hidden = me.hidden || !me.rendered,
hierarchicallyHidden = me.hierarchicallyHidden = me.isHierarchicallyHidden(),
pendingShow = me.pendingShow;
if (hidden !== hierarchicallyHidden) {
if (hierarchicallyHidden) {
me.hide();
me.pendingShow = true;
} else if (pendingShow) {
delete me.pendingShow;
if (pendingShow.length) {
me.show.apply(me, pendingShow);
} else {
me.show();
}
}
}
},
setZIndex: function(index) {
var me = this;
me.el.setZIndex(index);
index += 10;
if (me.floatingDescendants) {
index = Math.floor(me.floatingDescendants.setBase(index) / 100) * 100 + 10000;
}
return index;
},
doConstrain: function(constrainTo) {
var me = this,
xy = me.calculateConstrainedPosition(constrainTo, null, true);
if (xy) {
me.setPosition(xy);
}
},
updateActiveCounter: function(activeCounter) {
var zim = this.zIndexParent;
if (zim && this.bringParentToFront !== false) {
zim.setActiveCounter(++Ext.ZIndexManager.activeCounter);
}
zim = this.zIndexManager;
if (zim) {
zim.onComponentUpdate(this);
}
},
updateAlwaysOnTop: function(alwaysOnTop) {
var z = this.zIndexManager;
if (z) {
z.onComponentUpdate(this);
}
},
toFront: function(preventFocus) {
var me = this;
if (me.zIndexManager.bringToFront(me, preventFocus || !me.focusOnToFront)) {
if (me.hasListeners.tofront) {
me.fireEvent('tofront', me, me.el.getZIndex());
}
}
return me;
},
setActive: function(active, doFocus) {
var me = this,
activeCmp;
if (active) {
if (me.el.shadow && !me.maximized) {
me.el.enableShadow(null, true);
}
if (doFocus) {
activeCmp = Ext.ComponentManager.getActiveComponent();
if (!activeCmp || !activeCmp.up(me)) {
me.focus();
}
}
me.fireEvent('activate', me);
} else
{
me.fireEvent('deactivate', me);
}
},
toBack: function() {
this.zIndexManager.sendToBack(this);
return this;
},
center: function() {
var me = this,
xy;
if (me.isVisible()) {
xy = me.getAlignToXY(me.container, 'c-c');
me.setPagePosition(xy);
} else {
me.needsCenter = true;
}
return me;
},
onFloatShow: function() {
if (this.needsCenter) {
this.center();
}
delete this.needsCenter;
if (this.toFrontOnShow) {
this.toFront();
}
},
fitContainer: function(animate) {
var me = this,
parent = me.floatParent,
container = parent ? parent.getTargetEl() : me.container,
newBox = container.getViewSize(),
newPosition = parent || (container.dom !== document.body) ?
[
0,
0
] :
container.getXY();
newBox.x = newPosition[0];
newBox.y = newPosition[1];
me.setBox(newBox, animate);
},
privates: {
onFloatDestroy: function() {
this.clearAlignEl();
},
clearAlignEl: function() {
var me = this;
if (me._lastAlignToEl) {
Ext.un('scroll', me.onAlignToScroll, me);
me._lastAlignPos = me._lastAlignToEl = null;
}
},
onAlignToScroll: function(scroller) {
var me = this,
el = me._lastAlignToEl,
dom;
if (el && !scroller.getElement().contains(me.el)) {
dom = el.isElement ? el.dom : el;
if (dom && !Ext.isGarbage(dom)) {
me.alignTo(el, me._lastAlignToPos);
} else {
me.clearAlignEl();
}
}
}
}
});
Ext.define('Ext.util.ElementContainer', {
mixinId: 'elementCt',
config: {
childEls: {
$value: {},
cached: true,
lazy: true,
merge: function(newValue, oldValue, target, mixinClass) {
var childEls = oldValue ? Ext.Object.chain(oldValue) : {},
i, val;
if (newValue instanceof Array) {
for (i = newValue.length; i--; ) {
val = newValue[i];
if (!mixinClass || !(val in childEls)) {
if (typeof val === 'string') {
childEls[val] = {
name: val,
itemId: val
};
} else {
childEls[val.name] = val;
}
}
}
} else if (newValue) {
if (newValue.constructor === Object) {
for (i in newValue) {
if (!mixinClass || !(i in childEls)) {
val = newValue[i];
if (val === true) {
childEls[i] = {
itemId: i
};
} else if (typeof val === 'string') {
childEls[i] = {
itemId: val
};
} else {
childEls[i] = val;
if (!('itemId' in val)) {
val.itemId = i;
}
}
childEls[i].name = i;
}
}
} else {
if (!mixinClass || !(newValue in childEls)) {
childEls[newValue] = {
name: newValue,
itemId: newValue
};
}
}
}
return childEls;
}
}
},
destroy: function() {
var me = this,
childEls = me.getChildEls(),
child, childName;
for (childName in childEls) {
child = me[childName];
if (child) {
if (child.destroy) {
child.component = null;
child.destroy();
}
me[childName] = null;
}
}
},
privates: {
afterClassMixedIn: function(targetClass) {
var proto = targetClass.prototype,
childEls = proto.childEls;
if (childEls) {
delete proto.childEls;
targetClass.getConfigurator().add({
childEls: childEls
});
}
},
attachChildEls: function(el, owner) {
var me = this,
childEls = me.getChildEls(),
comp = owner || me,
baseId = comp.id + '-',
unframed = !comp.frame,
childName, elements, entry, k, selector, value, id;
for (childName in childEls) {
entry = childEls[childName];
if (unframed && entry.frame) {
continue;
}
selector = entry.select;
if (selector) {
value = el.select(selector, true);
}
else if (!(selector = entry.selectNode)) {
if (!(id = entry.id)) {
id = baseId + entry.itemId;
value = Ext.cache[id];
} else
{
value = Ext.cache[id] || el.getById(id);
}
} else {
value = el.selectNode(selector, false);
}
if (value) {
if (value.isElement) {
value.component = comp;
} else if (value.isComposite && !value.isLite) {
elements = value.elements;
for (k = elements.length; k--; ) {
elements[k].component = comp;
}
}
}
me[childName] = value || null;
}
}
}
});
Ext.define('Ext.util.Renderable', {
mixinId: 'renderable',
requires: [
'Ext.dom.Element'
],
frameCls: Ext.baseCSSPrefix + 'frame',
frameIdRegex: /[\-]frame\d+[TMB][LCR]$/,
frameElNames: [
'TL',
'TC',
'TR',
'ML',
'MC',
'MR',
'BL',
'BC',
'BR',
'Table'
],
frameTpl: [
'{%this.renderDockedItems(out,values,0);%}',
'<tpl if="top">',
'<tpl if="left"><div id="{fgid}TL" data-ref="frameTL" class="{frameCls}-tl {baseCls}-tl {baseCls}-{ui}-tl<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tl</tpl>{frameElCls}" role="presentation"></tpl>',
'<tpl if="right"><div id="{fgid}TR" data-ref="frameTR" class="{frameCls}-tr {baseCls}-tr {baseCls}-{ui}-tr<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tr</tpl>{frameElCls}" role="presentation"></tpl>',
'<div id="{fgid}TC" data-ref="frameTC" class="{frameCls}-tc {baseCls}-tc {baseCls}-{ui}-tc<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tc</tpl>{frameElCls}" role="presentation"></div>',
'<tpl if="right"></div></tpl>',
'<tpl if="left"></div></tpl>',
'</tpl>',
'<tpl if="left"><div id="{fgid}ML" data-ref="frameML" class="{frameCls}-ml {baseCls}-ml {baseCls}-{ui}-ml<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-ml</tpl>{frameElCls}" role="presentation"></tpl>',
'<tpl if="right"><div id="{fgid}MR" data-ref="frameMR" class="{frameCls}-mr {baseCls}-mr {baseCls}-{ui}-mr<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-mr</tpl>{frameElCls}" role="presentation"></tpl>',
'<div id="{fgid}Body" data-ref="frameBody" class="{frameBodyCls} {frameCls}-mc {baseCls}-mc {baseCls}-{ui}-mc<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-mc</tpl>{frameElCls}" role="presentation">',
'{%this.applyRenderTpl(out, values)%}',
'</div>',
'<tpl if="right"></div></tpl>',
'<tpl if="left"></div></tpl>',
'<tpl if="bottom">',
'<tpl if="left"><div id="{fgid}BL" data-ref="frameBL" class="{frameCls}-bl {baseCls}-bl {baseCls}-{ui}-bl<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-bl</tpl>{frameElCls}" role="presentation"></tpl>',
'<tpl if="right"><div id="{fgid}BR" data-ref="frameBR" class="{frameCls}-br {baseCls}-br {baseCls}-{ui}-br<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-br</tpl>{frameElCls}" role="presentation"></tpl>',
'<div id="{fgid}BC" data-ref="frameBC" class="{frameCls}-bc {baseCls}-bc {baseCls}-{ui}-bc<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-bc</tpl>{frameElCls}" role="presentation"></div>',
'<tpl if="right"></div></tpl>',
'<tpl if="left"></div></tpl>',
'</tpl>',
'{%this.renderDockedItems(out,values,1);%}'
],
frameTableTpl: [
'{%this.renderDockedItems(out,values,0);%}',
'<table id="{fgid}Table" data-ref="frameTable" class="{frameCls} ',
Ext.baseCSSPrefix + 'table-plain" cellpadding="0" role="presentation">',
'<tpl if="top">',
'<tr role="presentation">',
'<tpl if="left"><td id="{fgid}TL" data-ref="frameTL" class="{frameCls}-tl {baseCls}-tl {baseCls}-{ui}-tl<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tl</tpl>{frameElCls}" role="presentation"></td></tpl>',
'<td id="{fgid}TC" data-ref="frameTC" class="{frameCls}-tc {baseCls}-tc {baseCls}-{ui}-tc<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tc</tpl>{frameElCls}" role="presentation"></td>',
'<tpl if="right"><td id="{fgid}TR" data-ref="frameTR" class="{frameCls}-tr {baseCls}-tr {baseCls}-{ui}-tr<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tr</tpl>{frameElCls}" role="presentation"></td></tpl>',
'</tr>',
'</tpl>',
'<tr role="presentation">',
'<tpl if="left"><td id="{fgid}ML" data-ref="frameML" class="{frameCls}-ml {baseCls}-ml {baseCls}-{ui}-ml<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-ml</tpl>{frameElCls}" role="presentation"></td></tpl>',
'<td id="{fgid}Body" data-ref="frameBody" class="{frameBodyCls} {frameCls}-mc {baseCls}-mc {baseCls}-{ui}-mc<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-mc</tpl>{frameElCls}" style="{mcStyle}" role="presentation">',
'{%this.applyRenderTpl(out, values)%}',
'</td>',
'<tpl if="right"><td id="{fgid}MR" data-ref="frameMR" class="{frameCls}-mr {baseCls}-mr {baseCls}-{ui}-mr<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-mr</tpl>{frameElCls}" role="presentation"></td></tpl>',
'</tr>',
'<tpl if="bottom">',
'<tr role="presentation">',
'<tpl if="left"><td id="{fgid}BL" data-ref="frameBL" class="{frameCls}-bl {baseCls}-bl {baseCls}-{ui}-bl<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-bl</tpl>{frameElCls}" role="presentation"></td></tpl>',
'<td id="{fgid}BC" data-ref="frameBC" class="{frameCls}-bc {baseCls}-bc {baseCls}-{ui}-bc<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-bc</tpl>{frameElCls}" role="presentation"></td>',
'<tpl if="right"><td id="{fgid}BR" data-ref="frameBR" class="{frameCls}-br {baseCls}-br {baseCls}-{ui}-br<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-br</tpl>{frameElCls}" role="presentation"></td></tpl>',
'</tr>',
'</tpl>',
'</table>',
'{%this.renderDockedItems(out,values,1);%}'
],
_renderState: 0,
_layerCls: Ext.baseCSSPrefix + 'layer',
_fixedLayerCls: Ext.baseCSSPrefix + 'fixed-layer',
statics: {
makeRenderSetter: function(cfg, renderState) {
var name = cfg.name;
return function(value) {
var me = this,
bucket = (me.renderConfigs || (me.renderConfigs = {})),
pending = bucket[renderState];
if (me._renderState >= renderState) {
(cfg.setter || cfg.getSetter()).call(me, value);
} else {
if (!pending) {
bucket[renderState] = pending = {};
}
if (!(name in pending)) {
pending[name] = me[name];
}
me[name] = value;
}
return me;
};
},
processRenderConfig: function(source, configName, state) {
var proto = this.prototype,
configurator = this.getConfigurator(),
Renderable = Ext.util.Renderable,
makeSetter = Renderable.makeRenderSetter,
renderConfig = source[configName],
cachedSetter, cfg, name, setterName;
for (name in renderConfig) {
cfg = Ext.Config.get(name);
if (!proto[setterName = cfg.names.set]) {
cachedSetter = (cfg.renderSetter || (cfg.renderSetter = {}));
proto[setterName] = cachedSetter[state] || (cachedSetter[state] = makeSetter(cfg, state));
}
}
delete source[configName];
configurator.add(renderConfig);
}
},
onClassMixedIn: function(targetClass) {
var override = targetClass.override,
processRenderConfig = this.processRenderConfig,
processOverride = function(body) {
if (body.beforeRenderConfig) {
this.processRenderConfig(body, 'beforeRenderConfig', 1);
}
if (body.renderConfig) {
this.processRenderConfig(body, 'renderConfig', 3);
}
override.call(this, body);
},
processClass = function(theClass, classBody) {
theClass.override = processOverride;
theClass.processRenderConfig = processRenderConfig;
if (classBody.beforeRenderConfig) {
theClass.processRenderConfig(classBody, 'beforeRenderConfig', 1);
}
if (classBody.renderConfig) {
theClass.processRenderConfig(classBody, 'renderConfig', 3);
}
};
processClass(targetClass, targetClass.prototype);
targetClass.onExtended(processClass);
},
afterRender: function() {
var me = this,
data = {},
protoEl = me.protoEl,
target = me.el,
controller, item, pre, hidden, contentEl;
me.finishRenderChildren();
me._renderState = 4;
if (me.contentEl) {
pre = Ext.baseCSSPrefix;
hidden = pre + 'hidden-';
contentEl = me.contentEl = Ext.get(me.contentEl);
contentEl.component = me;
contentEl.removeCls([
pre + 'hidden',
hidden + 'display',
hidden + 'offsets'
]);
me.getContentTarget().appendChild(contentEl.dom);
}
protoEl.writeTo(data);
item = data.removed;
if (item) {
target.removeCls(item);
}
item = data.cls;
if (item.length) {
target.addCls(item);
}
item = data.style;
if (data.style) {
target.setStyle(item);
}
me.protoEl = null;
if (!me.ownerCt) {
me.updateLayout();
}
if (!(me.x && me.y) && (me.pageX || me.pageY)) {
me.setPagePosition(me.pageX, me.pageY);
}
if (me.disableOnRender) {
me.onDisable();
}
if (Ext.enableAria) {
me.ariaApplyAfterRenderAttributes();
}
controller = me.controller;
if (controller && controller.afterRender) {
controller.afterRender(me);
}
},
afterFirstLayout: function(width, height) {
var me = this,
x = me.x,
y = me.y,
alignSpec = me.defaultAlign,
alignOffset = me.alignOffset,
controller, hasX, hasY, pos, xy;
if (!me.ownerLayout) {
hasX = x !== undefined;
hasY = y !== undefined;
}
if (me.floating && !me.preventDefaultAlign && (!hasX || !hasY)) {
if (me.floatParent) {
pos = me.floatParent.getTargetEl().getViewRegion();
xy = me.el.getAlignToXY(me.alignTarget || me.floatParent.getTargetEl(), alignSpec, alignOffset);
pos.x = xy[0] - pos.x;
pos.y = xy[1] - pos.y;
} else {
xy = me.el.getAlignToXY(me.alignTarget || me.container, alignSpec, alignOffset);
pos = me.el.translateXY(xy[0], xy[1]);
}
x = hasX ? x : pos.x;
y = hasY ? y : pos.y;
hasX = hasY = true;
}
if (hasX || hasY) {
me.setPosition(x, y);
}
me.onBoxReady(width, height);
controller = me.controller;
if (controller && controller.boxReady) {
controller.boxReady(me);
}
},
beforeRender: function() {
var me = this,
floating = me.floating,
layout = me.getComponentLayout(),
cls, controller;
me._renderState = 1;
controller = me.controller;
if (controller && controller.beforeRender) {
controller.beforeRender(me);
}
me.initBindable();
if (me.renderConfigs) {
me.flushRenderConfigs();
}
if (me.reference) {
me.publishState();
}
if (floating) {
me.addCls(me.fixed ? me._fixedLayerCls : me._layerCls);
cls = floating.cls;
if (cls) {
me.addCls(cls);
}
}
me.frame = me.frame || me.alwaysFramed;
if (!layout.initialized) {
layout.initLayout();
}
me.initOverflow();
me.setUI(me.ui);
},
doApplyRenderTpl: function(out, values) {
var me = values.$comp,
tpl;
if (!me.rendered) {
tpl = me.initRenderTpl();
tpl.applyOut(values.renderData, out);
}
},
getElConfig: function() {
var me = this,
autoEl = me.autoEl,
frameInfo = me.getFrameInfo(),
config = {
tag: 'div',
tpl: frameInfo ? me.initFramingTpl(frameInfo.table) : me.initRenderTpl()
},
layoutTargetCls = me.layoutTargetCls,
protoEl = me.protoEl,
frameData;
me.initStyles(protoEl);
if (layoutTargetCls && !frameInfo) {
protoEl.addCls(layoutTargetCls);
}
protoEl.writeTo(config);
protoEl.flush();
if (Ext.isString(autoEl)) {
config.tag = autoEl;
} else {
Ext.apply(config, autoEl);
}
if (Ext.enableAria && me.ariaRenderAttributesToElement) {
Ext.apply(config, me.ariaGetRenderAttributes());
}
config.id = me.id;
if (config.tpl) {
if (frameInfo) {
config.tplData = frameData = me.getFrameRenderData();
frameData.renderData = me.initRenderData();
} else {
config.tplData = me.initRenderData();
}
}
return config;
},
getInsertPosition: function(position) {
if (position !== undefined) {
if (Ext.isNumber(position)) {
position = this.container.dom.childNodes[position];
} else {
position = Ext.getDom(position);
}
}
return position;
},
getRenderTree: function() {
var me = this,
ret = null;
if (!me.hasListeners.beforerender || me.fireEvent('beforerender', me) !== false) {
me._renderState = 1;
me.beforeRender();
me.rendering = true;
me._renderState = 2;
ret = me.getElConfig();
if (me.el) {
ret.id = me.$pid = Ext.id(null, me.el.identifiablePrefix);
}
}
return ret;
},
initRenderData: function() {
var me = this;
return Ext.apply({
$comp: me,
id: me.id,
ui: me.ui,
uiCls: me.uiCls,
baseCls: me.baseCls,
componentCls: me.componentCls,
frame: me.frame,
renderScroller: me.touchScroll,
scrollerCls: me.scrollerCls,
role: me.ariaRole,
childElCls: ''
},
me.renderData);
},
onRender: function(parentNode, containerIdx) {
var me = this,
x = me.x,
y = me.y,
lastBox = null,
el = me.el,
width, height;
me.applyRenderSelectors();
me.rendering = null;
me.rendered = true;
me._renderState = 3;
if (me.renderConfigs) {
me.flushRenderConfigs();
}
if (x != null) {
lastBox = {
x: x
};
}
if (y != null) {
(lastBox = lastBox || {}).y = y;
}
if (!me.getFrameInfo()) {
width = me.width;
height = me.height;
if (typeof width === 'number') {
lastBox = lastBox || {};
lastBox.width = width;
}
if (typeof height === 'number') {
lastBox = lastBox || {};
lastBox.height = height;
}
}
if (me.touchScroll === 1) {
me.getOverflowEl().disableTouchScroll();
}
me.lastBox = el.lastBox = lastBox;
},
render: function(container, position) {
var me = this,
el = me.el,
ownerLayout = me.ownerLayout,
vetoed, tree, nextSibling;
if (el && !el.isElement) {
me.wrapPrimaryEl(el);
el = me.el;
}
Ext.suspendLayouts();
container = me.initContainer(container);
nextSibling = me.getInsertPosition(position);
if (!el) {
tree = me.getRenderTree();
if (ownerLayout && ownerLayout.transformItemRenderTree) {
tree = ownerLayout.transformItemRenderTree(tree);
}
if (tree) {
if (nextSibling) {
el = Ext.DomHelper.insertBefore(nextSibling, tree);
} else {
el = Ext.DomHelper.append(container, tree);
}
me.wrapPrimaryEl(el);
me.cacheRefEls(el);
}
} else {
if (!me.hasListeners.beforerender || me.fireEvent('beforerender', me) !== false) {
me.beforeRender();
me.needsRenderTpl = me.rendering = true;
me._renderState = 2;
me.initStyles(el);
if (me.allowDomMove !== false) {
if (nextSibling) {
container.dom.insertBefore(el.dom, nextSibling);
} else {
container.dom.appendChild(el.dom);
}
}
} else {
vetoed = true;
}
}
if (el && !vetoed) {
me.finishRender(position);
}
Ext.resumeLayouts(!me.hidden && !container.isDetachedBody);
},
ensureAttachedToBody: function(runLayout) {
var comp = this,
body;
while (comp.ownerCt) {
comp = comp.ownerCt;
}
if (comp.container.isDetachedBody) {
comp.container = body = Ext.getBody();
body.appendChild(comp.el.dom);
if (runLayout) {
comp.updateLayout();
}
if (typeof comp.x === 'number' || typeof comp.y === 'number') {
comp.setPosition(comp.x, comp.y);
}
}
},
privates: {
applyRenderSelectors: function() {
var me = this,
selectors = me.renderSelectors,
el = me.el,
query, selector;
me.attachChildEls(el);
if (selectors) {
for (selector in selectors) {
query = selectors[selector];
if (query) {
me[selector] = el.selectNode(query, false);
}
}
}
},
cacheRefEls: function(el) {
el = el || this.el;
var cache = Ext.cache,
El = Ext.dom.Element,
dom = el.isElement ? el.dom : el,
refs = dom.querySelectorAll('[data-ref]'),
len = refs.length,
ref, i;
for (i = 0; i < len; i++) {
ref = refs[i];
if (!cache[ref.id]) {
new El(ref);
}
}
},
doAutoRender: function() {
var me = this;
if (!me.rendered) {
if (me.floating) {
me.render(me.renderTo || document.body);
} else {
me.render(Ext.isBoolean(me.autoRender) ? Ext.getBody() : me.autoRender);
}
}
},
doRenderContent: function(out, renderData) {
var me = renderData.$comp,
data = me.data;
if (me.html) {
Ext.DomHelper.generateMarkup(me.html, out);
delete me.html;
}
if (me.tpl) {
if (!me.tpl.isTemplate) {
me.tpl = new Ext.XTemplate(me.tpl);
}
if (data) {
me.data = data = data.isEntity ? data.getData(true) : data;
me.tpl.applyOut(data, out);
}
}
},
doRenderFramingDockedItems: function(out, renderData, after) {
var me = renderData.$comp;
if (!me.rendered && me.doRenderDockedItems) {
renderData.renderData.$skipDockedItems = true;
me.doRenderDockedItems.call(this, out, renderData, after);
}
},
flushRenderConfigs: function() {
var me = this,
configs = me.renderConfigs,
state = me._renderState,
bucket, i, name, newConfigs, value;
if (configs) {
for (i = 0; i <= state; ++i) {
bucket = configs[i];
if (bucket) {
configs[i] = null;
for (name in bucket) {
value = bucket[name];
(newConfigs || (newConfigs = {}))[name] = me[name];
me[name] = value;
}
}
}
if (newConfigs) {
me.setConfig(newConfigs);
}
}
},
finishRender: function(containerIdx) {
var me = this,
cache = Ext.cache,
proxy, first, id, tpl, data, dom, el;
if (!me.el || me.$pid) {
if (me.container) {
el = cache[me.id];
dom = el ? el.dom : me.container.getById(me.id, true);
} else {
id = me.$pid || me.id;
el = cache[id];
dom = el ? el.dom : Ext.getDom(id);
}
if (!me.el) {
me.wrapPrimaryEl(dom);
} else {
delete me.$pid;
if (!me.el.dom) {
me.wrapPrimaryEl(me.el);
}
dom.parentNode.insertBefore(me.el.dom, dom);
proxy = dom;
dom = me.el.dom;
first = dom.firstChild;
while (proxy.firstChild) {
dom.insertBefore(proxy.firstChild, first);
}
me.el.addCls(proxy.className);
Ext.removeNode(proxy);
}
}
else if (me.needsRenderTpl) {
tpl = me.initRenderTpl();
if (tpl) {
data = me.initRenderData();
tpl.insertFirst(me.getTargetEl(), data);
}
me.cacheRefEls();
}
me.el.component = me;
if (!me.container) {
me.container = Ext.get(me.el.dom.parentNode);
}
if (me.ctCls) {
me.container.addCls(me.ctCls);
}
me.onRender(me.container, containerIdx);
if (!me.overflowInited) {
me.initOverflow();
}
me.el.setVisibilityMode(Ext.Element[me.hideMode.toUpperCase()]);
if (me.overCls) {
me.el.hover(me.addOverCls, me.removeOverCls, me);
}
if (me.hasListeners.render) {
me.fireEvent('render', me);
}
me.afterRender();
if (me.hasListeners.afterrender) {
me.fireEvent('afterrender', me);
}
me.initEvents();
if (me.hidden) {
me.el.hide();
}
},
finishRenderChildren: function() {
var layout = this.getComponentLayout();
layout.finishRender();
},
getFrameRenderData: function() {
var me = this,
frameInfo = me.frameSize,
mcStyle = '';
if (me._syncFrameHeight && me.height) {
mcStyle = 'height:' + (me.height - frameInfo.height) + 'px';
}
return {
$comp: me,
fgid: me.id + '-frame',
ui: me.ui,
uiCls: me.uiCls,
frameCls: me.frameCls,
frameBodyCls: me.layoutTargetCls || '',
baseCls: me.baseCls,
top: !!frameInfo.top,
left: !!frameInfo.left,
right: !!frameInfo.right,
bottom: !!frameInfo.bottom,
mcStyle: mcStyle,
frameElCls: ''
};
},
getFrameInfo: function() {
if (Ext.supports.CSS3BorderRadius || !this.frame) {
return false;
}
var me = this,
frameInfoCache = me.frameInfoCache,
cls = me.getFramingInfoCls() + '-frameInfo',
frameInfo = frameInfoCache[cls],
styleEl, info, frameTop, frameRight, frameBottom, frameLeft, borderTopWidth, borderRightWidth, borderBottomWidth, borderLeftWidth, paddingTop, paddingRight, paddingBottom, paddingLeft;
if (frameInfo == null) {
styleEl = Ext.fly(me.getStyleProxy(cls), 'frame-style-el');
info = styleEl.getStyle('font-family');
if (info) {
info = info.split('-');
frameTop = parseInt(info[1], 10);
frameRight = parseInt(info[2], 10);
frameBottom = parseInt(info[3], 10);
frameLeft = parseInt(info[4], 10);
borderTopWidth = parseInt(info[5], 10);
borderRightWidth = parseInt(info[6], 10);
borderBottomWidth = parseInt(info[7], 10);
borderLeftWidth = parseInt(info[8], 10);
paddingTop = parseInt(info[9], 10);
paddingRight = parseInt(info[10], 10);
paddingBottom = parseInt(info[11], 10);
paddingLeft = parseInt(info[12], 10);
frameInfo = {
table: info[0].charAt(0) === 't',
vertical: info[0].charAt(1) === 'v',
top: frameTop,
right: frameRight,
bottom: frameBottom,
left: frameLeft,
width: frameLeft + frameRight,
height: frameTop + frameBottom,
border: {
top: borderTopWidth,
right: borderRightWidth,
bottom: borderBottomWidth,
left: borderLeftWidth,
width: borderLeftWidth + borderRightWidth,
height: borderTopWidth + borderBottomWidth
},
padding: {
top: paddingTop,
right: paddingRight,
bottom: paddingBottom,
left: paddingLeft,
width: paddingLeft + paddingRight,
height: paddingTop + paddingBottom
}
};
} else {
frameInfo = false;
}
if (me.frame === true && !frameInfo) {
Ext.log.error('You have set frame: true explicity on this component (' + me.getXType() + ') and it ' + 'does not have any framing defined in the CSS template. In this case IE cannot figure out ' + 'what sizes to use and thus framing on this component will be disabled.');
}
frameInfoCache[cls] = frameInfo;
}
me.frame = !!frameInfo;
me.frameSize = frameInfo;
return frameInfo;
},
getFramingInfoCls: function() {
return this.baseCls + '-' + this.ui;
},
getStyleProxy: function(cls) {
var result = this.styleProxyEl || (Ext.Component.prototype.styleProxyEl = Ext.getBody().createChild({
'data-sticky': true,
role: 'presentation',
style: {
position: 'absolute',
top: '-10000px'
}
}, null, true));
result.className = cls;
return result;
},
getFrameTpl: function(table) {
return this.getTpl(table ? 'frameTableTpl' : 'frameTpl');
},
initContainer: function(container) {
var me = this;
if (!container && me.el) {
container = me.el.dom.parentNode;
me.allowDomMove = false;
}
me.container = container.dom ? container : Ext.get(container);
return me.container;
},
initOverflow: function() {
var me = this,
overflowStyle = me.getOverflowStyle(),
scrollFlags = me.scrollFlags,
overflowEl = me.getOverflowEl(),
hasOverflow = (scrollFlags.y || scrollFlags.x),
touchScroll = me.touchScroll = (hasOverflow && Ext.supports.touchScroll);
if (!hasOverflow || !overflowEl || !overflowEl.isElement) {
return;
}
me.overflowInited = true;
if (touchScroll === 2) {
overflowEl.setStyle('overflow', 'hidden');
} else {
overflowEl.setStyle(overflowStyle);
}
},
doRenderPadding: function(out, renderData) {
var me = renderData.$comp;
if (me.touchScroll) {
out.push('padding:', me.unitizeBox(me.padding));
}
},
initFramingTpl: function(table) {
var tpl = this.getFrameTpl(table);
if (tpl && !tpl.applyRenderTpl) {
this.setupFramingTpl(tpl);
}
return tpl;
},
initRenderTpl: function() {
var tpl = this.getTpl('renderTpl');
if (tpl && !tpl.renderContent) {
this.setupRenderTpl(tpl);
}
return tpl;
},
setupFramingTpl: function(frameTpl) {
frameTpl.applyRenderTpl = this.doApplyRenderTpl;
frameTpl.renderDockedItems = this.doRenderFramingDockedItems;
},
setupRenderTpl: function(renderTpl) {
renderTpl.renderBody = renderTpl.renderContent = this.doRenderContent;
renderTpl.renderPadding = this.doRenderPadding;
},
updateFrame: function() {
if (Ext.supports.CSS3BorderRadius || !this.frame) {
return;
}
var me = this,
dom = me.el.dom,
frameTable = me.frameTable,
oldFrameBody = me.frameBody,
oldFrameBodyDom = oldFrameBody.dom,
frameInfo = me.getFrameInfo(),
childEls, childElName, div, el, first, frameData, frameDom, frameTpl, i, newBody, newFrameEls;
div = document.createElement('div');
frameData = me.getFrameRenderData();
frameTpl = me.getFrameTpl(frameInfo.table);
frameTpl.insertFirst(div, frameData);
newFrameEls = div.querySelectorAll('[data-ref]');
newBody = div.querySelector('[data-ref="frameBody"]');
for (first = oldFrameBodyDom; first.parentNode !== dom; ) {
first = first.parentNode;
}
while (div.firstChild) {
dom.insertBefore(div.firstChild, first);
}
newBody.parentNode.replaceChild(oldFrameBodyDom, newBody);
oldFrameBodyDom.className = newBody.className;
oldFrameBody.setSize();
childEls = me.getChildEls();
if (frameTable) {
frameTable.destroy();
me.frameTable = null;
}
for (childElName in childEls) {
if (childEls[childElName].frame) {
el = me[childElName];
if (el && el !== oldFrameBody) {
el.destroy();
me[childElName] = null;
}
}
}
for (i = newFrameEls.length; i--; ) {
childElName = (frameDom = newFrameEls[i]).getAttribute('data-ref');
if (childElName !== 'frameBody') {
me[childElName] = new Ext.dom.Element(frameDom);
}
}
},
frameInfoCache: {}
}
});
Ext.define('Ext.state.Provider', {
mixins: {
observable: 'Ext.util.Observable'
},
prefix: 'ext-',
constructor: function(config) {
var me = this;
Ext.apply(me, config);
me.state = {};
me.mixins.observable.constructor.call(me);
},
get: function(name, defaultValue) {
var ret = this.state[name];
return ret === undefined ? defaultValue : ret;
},
clear: function(name) {
var me = this;
delete me.state[name];
me.fireEvent("statechange", me, name, null);
},
set: function(name, value) {
var me = this;
me.state[name] = value;
me.fireEvent("statechange", me, name, value);
},
decodeValue: function(value) {
var me = this,
re = /^(a|n|d|b|s|o|e)\:(.*)$/,
matches = re.exec(unescape(value)),
all, type, keyValue, values, vLen, v;
if (!matches || !matches[1]) {
return;
}
type = matches[1];
value = matches[2];
switch (type) {
case 'e':
return null;
case 'n':
return parseFloat(value);
case 'd':
return new Date(Date.parse(value));
case 'b':
return (value === '1');
case 'a':
all = [];
if (value) {
values = value.split('^');
vLen = values.length;
for (v = 0; v < vLen; v++) {
value = values[v];
all.push(me.decodeValue(value));
}
};
return all;
case 'o':
all = {};
if (value) {
values = value.split('^');
vLen = values.length;
for (v = 0; v < vLen; v++) {
value = values[v];
keyValue = value.split('=');
all[keyValue[0]] = me.decodeValue(keyValue[1]);
}
};
return all;
default:
return value;
}
},
encodeValue: function(value) {
var flat = '',
i = 0,
enc, len, key;
if (value == null) {
return 'e:1';
} else if (typeof value === 'number') {
enc = 'n:' + value;
} else if (typeof value === 'boolean') {
enc = 'b:' + (value ? '1' : '0');
} else if (Ext.isDate(value)) {
enc = 'd:' + value.toUTCString();
} else if (Ext.isArray(value)) {
for (len = value.length; i < len; i++) {
flat += this.encodeValue(value[i]);
if (i !== len - 1) {
flat += '^';
}
}
enc = 'a:' + flat;
} else if (typeof value === 'object') {
for (key in value) {
if (typeof value[key] !== 'function' && value[key] !== undefined) {
flat += key + '=' + this.encodeValue(value[key]) + '^';
}
}
enc = 'o:' + flat.substring(0, flat.length - 1);
} else {
enc = 's:' + value;
}
return escape(enc);
}
});
Ext.define('Ext.state.Manager', {
singleton: true,
requires: [
'Ext.state.Provider'
],
constructor: function() {
this.provider = new Ext.state.Provider();
},
setProvider: function(stateProvider) {
this.provider = stateProvider;
},
get: function(key, defaultValue) {
return this.provider.get(key, defaultValue);
},
set: function(key, value) {
this.provider.set(key, value);
},
clear: function(key) {
this.provider.clear(key);
},
getProvider: function() {
return this.provider;
}
});
Ext.define('Ext.state.Stateful', {
mixinId: 'state',
requires: [
'Ext.state.Manager'
],
stateful: false,
saveDelay: 100,
constructor: function() {
var me = this;
if (!me.stateEvents) {
me.stateEvents = [];
}
if (me.stateful !== false) {
me.addStateEvents(me.stateEvents);
me.initState();
}
},
addStateEvents: function(events) {
var me = this,
i, event, stateEventsByName, eventArray;
if (me.stateful && me.getStateId()) {
eventArray = (typeof events === 'string') ? arguments : events;
stateEventsByName = me.stateEventsByName || (me.stateEventsByName = {});
for (i = eventArray.length; i--; ) {
event = eventArray[i];
if (event && !stateEventsByName[event]) {
stateEventsByName[event] = 1;
me.on(event, me.onStateChange, me);
}
}
}
},
onStateChange: function() {
var me = this,
delay = me.saveDelay,
statics, runner;
if (!me.stateful) {
return;
}
if (delay) {
if (!me.stateTask) {
statics = Ext.state.Stateful;
runner = statics.runner || (statics.runner = new Ext.util.TaskRunner());
me.stateTask = runner.newTask({
run: me.saveState,
scope: me,
interval: delay,
repeat: 1,
fireIdleEvent: false
});
}
me.stateTask.start();
} else {
me.saveState();
}
},
saveState: function() {
var me = this,
id = me.stateful && me.getStateId(),
hasListeners = me.hasListeners,
plugins, plugin, i, len, state, pluginState;
if (id) {
state = me.getState() || {};
plugins = me.getPlugins() || [];
for (i = 0 , len = plugins.length; i < len; i++) {
plugin = plugins[i];
if (plugin && plugin.getState) {
pluginState = plugin.getState(state);
if (pluginState && !state[plugin.ptype]) {
state[plugin.ptype] = pluginState;
}
}
}
if (!hasListeners.beforestatesave || me.fireEvent('beforestatesave', me, state) !== false) {
Ext.state.Manager.set(id, state);
if (hasListeners.statesave) {
me.fireEvent('statesave', me, state);
}
}
}
},
getState: function() {
return null;
},
applyState: function(state) {
if (state) {
Ext.apply(this, state);
}
},
getStateId: function() {
var me = this;
return me.stateId || (me.autoGenId ? null : me.id);
},
initState: function() {
var me = this,
id = me.stateful && me.getStateId(),
hasListeners = me.hasListeners,
state, combinedState, i, len, plugins, plugin, pluginType;
if (id) {
combinedState = Ext.state.Manager.get(id);
if (combinedState) {
state = Ext.apply({}, combinedState);
if (!hasListeners.beforestaterestore || me.fireEvent('beforestaterestore', me, combinedState) !== false) {
plugins = me.getPlugins() || [];
for (i = 0 , len = plugins.length; i < len; i++) {
plugin = plugins[i];
if (plugin) {
pluginType = plugin.ptype;
if (plugin.applyState) {
plugin.applyState(state[pluginType], combinedState);
}
delete state[pluginType];
}
}
me.applyState(state);
if (hasListeners.staterestore) {
me.fireEvent('staterestore', me, combinedState);
}
}
}
}
},
savePropToState: function(propName, state, stateName) {
var me = this,
value = me[propName],
config = me.initialConfig;
if (me.hasOwnProperty(propName)) {
if (!config || config[propName] !== value) {
if (state) {
state[stateName || propName] = value;
}
return true;
}
}
return false;
},
savePropsToState: function(propNames, state) {
var me = this,
i, n;
if (typeof propNames === 'string') {
me.savePropToState(propNames, state);
} else {
for (i = 0 , n = propNames.length; i < n; ++i) {
me.savePropToState(propNames[i], state);
}
}
return state;
},
destroy: function() {
var me = this,
task = me.stateTask;
if (task) {
task.destroy();
me.stateTask = null;
}
me.clearListeners();
}
});
Ext.define('Ext.util.Focusable', {
mixinId: 'focusable',
hasFocus: false,
focusable: false,
focusCls: 'focus',
initFocusable: Ext.emptyFn,
initFocusableEvents: function() {
this.initFocusableElement();
},
getFocusClsEl: function() {
return this.getFocusEl();
},
getFocusEl: function() {
return this.element || this.el;
},
destroyFocusable: function() {
this.focusListeners = Ext.destroy(this.focusListeners);
delete this.focusTask;
},
enableFocusable: Ext.emptyFn,
disableFocusable: function() {
var me = this,
focusTarget,
focusCls = me.focusCls,
focusClsEl;
if (me.hasFocus) {
focusTarget = me.findFocusTarget();
if (focusTarget) {
focusTarget.focus();
}
}
focusClsEl = me.getFocusClsEl();
if (focusCls && focusClsEl) {
focusClsEl.removeCls(me.removeClsWithUI(focusCls, true));
}
},
isFocusable: function(deep) {
var me = this,
focusEl;
if (!me.focusable && (!me.isContainer || !deep)) {
return false;
}
focusEl = me.getFocusEl();
if (focusEl && me.canFocus()) {
return focusEl.isFocusable(deep);
}
return false;
},
canFocus: function() {
var me = this;
return (me.isContainer || me.focusable) && me.rendered && !me.destroying && !me.isDestroyed && !me.disabled && me.isVisible(true);
},
focus: function(selectText, delay, callback, scope) {
var me = this,
focusTarget, focusElDom, containerScrollTop;
if ((!me.focusable && !me.isContainer) || me.isDestroyed || me.destroying) {
return;
}
if (delay) {
me.getFocusTask().delay(Ext.isNumber(delay) ? delay : 10, me.focus, me, [
selectText,
false,
callback,
scope
]);
return me;
}
me.cancelFocus();
if (me.canFocus()) {
if (focusTarget = me.getFocusEl()) {
if (focusTarget.isComponent) {
return focusTarget.focus(selectText, delay, callback, scope);
}
focusElDom = focusTarget.dom;
if (focusElDom) {
if (focusTarget.needsTabIndex()) {
focusElDom.tabIndex = -1;
}
if (me.floating) {
containerScrollTop = me.container.dom.scrollTop;
}
focusTarget.focus();
if (selectText) {
if (Ext.isArray(selectText)) {
if (me.selectText) {
me.selectText.apply(me, selectText);
}
} else if (focusElDom.select) {
focusElDom.select();
} else if (me.selectText) {
me.selectText();
}
}
Ext.callback(callback, scope);
}
if (me.floating) {
if (me !== me.zIndexManager.getActive()) {
me.toFront(true);
}
if (containerScrollTop !== undefined) {
me.container.dom.scrollTop = containerScrollTop;
}
}
}
} else {
focusTarget = me.findFocusTarget();
if (focusTarget) {
return focusTarget.focus(selectText, delay, callback, scope);
}
}
return me;
},
cancelFocus: function() {
var task = this.getFocusTask();
if (task) {
task.cancel();
}
},
beforeBlur: Ext.emptyFn,
onBlur: function(e) {
var me = this,
container = me.focusableContainer,
focusCls = me.focusCls,
focusClsEl;
if (!me.focusable || me.destroying) {
return;
}
me.beforeBlur(e);
if (container) {
container.beforeFocusableChildBlur(me, e);
}
focusClsEl = me.getFocusClsEl();
if (focusCls && focusClsEl) {
focusClsEl.removeCls(me.removeClsWithUI(focusCls, true));
}
if (me.validateOnBlur) {
me.validate();
}
me.hasFocus = false;
me.fireEvent('blur', me, e);
me.postBlur(e);
if (container) {
container.afterFocusableChildBlur(me, e);
}
},
postBlur: Ext.emptyFn,
beforeFocus: Ext.emptyFn,
onFocus: function(e) {
var me = this,
container = me.focusableContainer,
focusCls = me.focusCls,
focusClsEl;
if (!me.focusable) {
return;
}
if (me.canFocus()) {
me.beforeFocus(e);
if (container) {
container.beforeFocusableChildFocus(me, e);
}
focusClsEl = me.getFocusClsEl();
if (focusCls && focusClsEl) {
focusClsEl.addCls(me.addClsWithUI(focusCls, true));
}
if (!me.hasFocus) {
me.hasFocus = true;
me.fireEvent('focus', me, e);
}
me.postFocus(e);
if (container) {
container.afterFocusableChildFocus(me, e);
}
}
},
postFocus: Ext.emptyFn,
getTabIndex: function() {
var me = this,
el, index;
if (!me.focusable) {
return;
}
el = me.getFocusEl();
if (el) {
if (el.isComponent) {
index = el.getTabIndex();
}
else if (el.isElement) {
index = el.getAttribute(Ext.Element.tabIndexAttributeName);
} else
{
return;
}
me.tabIndex = index;
} else {
index = me.tabIndex;
}
return index - 0;
},
setTabIndex: function(newTabIndex) {
var me = this,
el;
if (!me.focusable) {
return;
}
me.tabIndex = newTabIndex;
el = me.getFocusEl();
if (el) {
if (el.isComponent) {
el.setTabIndex(newTabIndex);
}
else if (el.isElement) {
el.set({
tabindex: newTabIndex
});
}
}
},
onFocusEnter: function(e) {
var me = this;
me.previousFocus = e.fromComponent || e.relatedTarget;
me.containsFocus = true;
me.fireEvent('focusenter', me, e);
},
onFocusLeave: function(e) {
var me = this;
me.previousFocus = null;
me.containsFocus = false;
me.fireEvent('focusleave', me, e);
},
privates: {
revertFocus: function() {
var me = this,
focusTarget = me.previousFocus;
me.previousFocus = null;
if (focusTarget && me.containsFocus) {
if (focusTarget.isComponent) {
focusTarget.focus();
} else
{
focusTarget = Ext.fly(focusTarget);
if (Ext.isIE8 || (focusTarget.isFocusable && focusTarget.isFocusable())) {
focusTarget.focus();
}
}
}
},
findFocusTarget: function() {
var me = this,
owner, focusTargets;
for (owner = me.up(':not([disabled])'); owner; owner = owner.up(':not([disabled])')) {
focusTargets = Ext.ComponentQuery.query(':focusable:not([hasFocus])', owner);
if (focusTargets.length) {
return focusTargets[0];
}
if (owner.isFocusable && owner.isFocusable()) {
return owner;
}
}
},
initFocusableElement: function() {
var me = this,
tabIndex = me.tabIndex,
focusEl = me.getFocusEl(),
needsTabIndex;
if (focusEl && !focusEl.isComponent) {
needsTabIndex = focusEl.needsTabIndex();
if (needsTabIndex || tabIndex != null) {
focusEl.dom.setAttribute('tabindex', tabIndex);
}
focusEl.dom.setAttribute(Ext.Component.componentIdAttribute, me.id);
}
},
getFocusTask: function() {
if (!this.focusTask) {
this.focusTask = Ext.focusTask;
}
return this.focusTask;
},
blur: function() {
var me = this,
focusEl;
if (!me.focusable || !me.rendered) {
return;
}
focusEl = me.getFocusEl();
if (focusEl) {
me.blurring = true;
focusEl.blur();
delete me.blurring;
}
return me;
},
disableTabbing: function() {
var me = this,
el = me.el,
focusEl;
if (!me.focusable) {
return;
}
focusEl = me.getFocusEl();
if (el) {
el.saveChildrenTabbableState();
}
if (focusEl) {
focusEl = focusEl.isComponent ? focusEl.getFocusEl() : focusEl;
focusEl.saveTabbableState();
}
},
enableTabbing: function() {
var me = this,
el = me.el,
focusEl;
if (!me.focusable) {
return;
}
focusEl = me.getFocusEl();
if (focusEl) {
focusEl = focusEl.isComponent ? focusEl.getFocusEl() : focusEl;
focusEl.restoreTabbableState();
}
if (el) {
el.restoreChildrenTabbableState();
}
}
}
}, function() {
if (!Ext.focusTask) {
Ext.focusTask = new Ext.util.DelayedTask();
}
});
Ext.define('Ext.Component', {
alternateClassName: 'Ext.AbstractComponent',
xtype: [
'component',
'box'
],
requires: [
'Ext.ComponentQuery',
'Ext.ComponentManager',
'Ext.util.ProtoElement',
'Ext.dom.CompositeElement',
'Ext.scroll.Scroller',
'Ext.scroll.TouchScroller',
'Ext.scroll.DomScroller'
],
mixins: [
'Ext.mixin.Inheritable',
'Ext.util.Floating',
'Ext.util.Positionable',
'Ext.util.Observable',
'Ext.mixin.Bindable',
'Ext.util.Animate',
'Ext.util.ElementContainer',
'Ext.util.Renderable',
'Ext.state.Stateful',
'Ext.util.Focusable'
],
uses: [
'Ext.overrides.*',
'Ext.Element',
'Ext.DomHelper',
'Ext.XTemplate',
'Ext.ComponentLoader',
'Ext.layout.Context',
'Ext.layout.Layout',
'Ext.layout.component.Auto',
'Ext.LoadMask',
'Ext.ZIndexManager',
'Ext.util.DelayedTask',
'Ext.resizer.Resizer',
'Ext.util.ComponentDragger'
],
statics: {
AUTO_ID: 1000,
pendingLayouts: null,
layoutSuspendCount: 0,
DIRECTION_TOP: 'top',
DIRECTION_RIGHT: 'right',
DIRECTION_BOTTOM: 'bottom',
DIRECTION_LEFT: 'left',
VERTICAL_DIRECTION_Re: /^(?:top|bottom)$/,
INVALID_ID_CHARS_Re: /[\.,\s]/g,
componentIdAttribute: 'componentId',
cancelLayout: function(comp, isDestroying) {
var context = this.runningLayoutContext || this.pendingLayouts;
if (context) {
context.cancelComponent(comp, false, isDestroying);
}
},
fromElement: function(node, topmost) {
var cmpIdAttr = Ext.Component.componentIdAttribute,
target = Ext.getDom(node),
cache = Ext.ComponentManager.all,
cmpId, cmp;
if (topmost) {
topmost = Ext.getDom(topmost);
} else {
topmost = document.body.parentNode;
}
while (target && target.nodeType === 1 && target !== topmost) {
cmpId = target.getAttribute(cmpIdAttr) || target.id;
if (cmpId) {
cmp = cache[cmpId];
if (cmp) {
return cmp;
}
}
target = target.parentNode;
}
return null;
},
flushLayouts: function() {
var me = this,
context = me.pendingLayouts;
if (context && context.invalidQueue.length) {
me.pendingLayouts = null;
me.runningLayoutContext = context;
Ext.override(context, {
runComplete: function() {
me.runningLayoutContext = null;
var result = this.callParent();
if (Ext.GlobalEvents.hasListeners.afterlayout) {
Ext.GlobalEvents.fireEvent('afterlayout');
}
return result;
}
});
context.run();
}
},
resumeLayouts: function(flush) {
if (this.layoutSuspendCount && !--this.layoutSuspendCount) {
if (flush) {
this.flushLayouts();
}
if (Ext.GlobalEvents.hasListeners.resumelayouts) {
Ext.GlobalEvents.fireEvent('resumelayouts');
}
}
},
suspendLayouts: function() {
++this.layoutSuspendCount;
},
updateLayout: function(comp, defer) {
var me = this,
running = me.runningLayoutContext,
pending;
if (running) {
running.queueInvalidate(comp);
} else {
pending = me.pendingLayouts || (me.pendingLayouts = new Ext.layout.Context());
pending.queueInvalidate(comp);
if (!defer && !me.layoutSuspendCount && !comp.isLayoutSuspended()) {
me.flushLayouts();
}
}
}
},
$configPrefixed: false,
$configStrict: false,
config: {
data: null,
maxHeight: null,
maxWidth: null,
minHeight: null,
minWidth: null,
scrollable: null
},
defaultBindProperty: 'html',
alignTarget: null,
autoRender: false,
autoShow: false,
baseCls: Ext.baseCSSPrefix + 'component',
childEls: {
frameTable: {
frame: true
},
frameTL: {
frame: 'tl'
},
frameTC: {
frame: 'tc'
},
frameTR: {
frame: 'tr'
},
frameML: {
frame: 'ml'
},
frameBody: {
frame: 'mc'
},
frameMR: {
frame: 'mr'
},
frameBL: {
frame: 'bl'
},
frameBC: {
frame: 'bc'
},
frameBR: {
frame: 'br'
}
},
componentLayout: 'autocomponent',
defaultAlign: 'c-c',
disabled: false,
disabledRe: /^(?:button|input|select|textarea|optgroup|option|fieldset)$/i,
nonMaskableRe: (function() {
var re = [
'input',
'select',
'textarea',
'optgroup',
'option',
'table'
];
if (Ext.isIE9m && !(Ext.isIE9 && !Ext.isIEQuirks)) {
re.push('p');
}
return new RegExp('^(?:' + re.join('|') + ')$', 'i');
}()),
disabledCls: Ext.baseCSSPrefix + 'item-disabled',
draggable: false,
floating: false,
hidden: false,
hideMode: 'display',
maskElement: null,
renderTpl: [
'<tpl if="renderScroller">',
'<div class="{scrollerCls}" style="{%this.renderPadding(out, values)%}">',
'</tpl>',
'{%this.renderContent(out,values)%}',
'<tpl if="renderScroller"></div></tpl>'
],
resizeHandles: 'all',
shrinkWrap: 2,
toFrontOnShow: true,
synthetic: false,
tplWriteMode: 'overwrite',
ui: 'default',
uiCls: [],
weight: null,
allowDomMove: true,
autoGenId: false,
borderBoxCls: Ext.baseCSSPrefix + 'border-box',
componentLayoutCounter: 0,
contentPaddingProperty: 'padding',
deferLayouts: false,
frameSize: null,
horizontalPosProp: 'left',
isComponent: true,
_isLayoutRoot: false,
layoutSuspendCount: 0,
liquidLayout: false,
maskOnDisable: true,
offsetsCls: Ext.baseCSSPrefix + 'hidden-offsets',
rendered: false,
rootCls: Ext.baseCSSPrefix + 'body',
scrollerCls: Ext.baseCSSPrefix + 'scroll-scroller',
scrollerSelector: '.' + Ext.baseCSSPrefix + 'scroll-scroller',
_scrollFlags: {
auto: {
auto: {
overflowX: 'auto',
overflowY: 'auto',
x: true,
y: true,
both: true
},
'false': {
overflowX: 'auto',
overflowY: 'hidden',
x: true,
y: false,
both: false
},
scroll: {
overflowX: 'auto',
overflowY: 'scroll',
x: true,
y: true,
both: true
}
},
'false': {
auto: {
overflowX: 'hidden',
overflowY: 'auto',
x: false,
y: true,
both: false
},
'false': {
overflowX: 'hidden',
overflowY: 'hidden',
x: false,
y: false,
both: false
},
scroll: {
overflowX: 'hidden',
overflowY: 'scroll',
x: false,
y: true,
both: false
}
},
scroll: {
auto: {
overflowX: 'scroll',
overflowY: 'auto',
x: true,
y: true,
both: true
},
'false': {
overflowX: 'scroll',
overflowY: 'hidden',
x: true,
y: false,
both: false
},
scroll: {
overflowX: 'scroll',
overflowY: 'scroll',
x: true,
y: true,
both: true
}
},
none: {
overflowX: '',
overflowY: '',
x: false,
y: false,
both: false
}
},
_scrollableCfg: {
x: {
x: true,
y: false
},
y: {
x: false,
y: true
},
horizontal: {
x: true,
y: false
},
vertical: {
x: false,
y: true
},
both: {
x: true,
y: true
},
'true': {
x: true,
y: true
}
},
validIdRe: Ext.validIdRe,
constructor: function(config) {
var me = this,
i, len, xhooks, controller, autoScroll, overflowX, overflowY, scrollable;
config = config || {};
if (config.initialConfig) {
if (config.isAction) {
me.baseAction = config;
}
config = config.initialConfig;
}
else if (config.tagName || config.dom || Ext.isString(config)) {
config = {
applyTo: config,
id: config.id || config
};
}
me.initialConfig = config;
me.getId();
me.protoEl = new Ext.util.ProtoElement();
me.$calledInitConfig = true;
me.initConfig(config);
delete me.$calledInitConfig;
if (me.scrollable == null) {
autoScroll = me.autoScroll;
if (autoScroll) {
scrollable = !!autoScroll;
} else {
overflowX = me.overflowX;
overflowY = me.overflowY;
if (overflowX || overflowY) {
scrollable = {
x: (overflowX && overflowX !== 'hidden') ? overflowX : false,
y: (overflowY && overflowY !== 'hidden') ? overflowY : false
};
}
}
if (scrollable) {
me.setScrollable(scrollable);
}
}
xhooks = me.xhooks;
if (xhooks) {
delete me.xhooks;
Ext.override(me, xhooks);
}
me.mixins.elementCt.constructor.call(me);
if (!me.validIdRe.test(me.id)) {
Ext.Error.raise('Invalid component "id": "' + me.id + '"');
}
if (!me.validIdRe.test(me.itemId)) {
Ext.Error.raise('Invalid component "itemId": "' + me.itemId + '"');
}
me.setupProtoEl();
if (me.cls) {
me.initialCls = me.cls;
me.protoEl.addCls(me.cls);
}
if (me.style) {
me.initialStyle = me.style;
me.protoEl.setStyle(me.style);
}
me.renderData = me.renderData || {};
me.initComponent();
if (!me.preventRegister) {
Ext.ComponentManager.register(me);
}
me.mixins.state.constructor.call(me);
me.addStateEvents('resize');
controller = me.getController();
if (controller) {
controller.init(me);
}
if (me.plugins) {
for (i = 0 , len = me.plugins.length; i < len; i++) {
me.plugins[i] = me.initPlugin(me.plugins[i]);
}
}
me.loader = me.getLoader();
if (me.disabled) {
me.disabled = false;
me.disable(true);
}
if (me.renderTo) {
me.render(me.renderTo);
}
if (me.autoShow && !me.initOwnerCt) {
me.show();
}
if (Ext.isDefined(me.disabledClass)) {
if (Ext.isDefined(Ext.global.console)) {
Ext.global.console.warn('Ext.Component: disabledClass has been deprecated. Please use disabledCls.');
}
me.disabledCls = me.disabledClass;
delete me.disabledClass;
}
if (me.baseAction) {
me.baseAction.addComponent(me);
}
},
beforeInitConfig: function() {
if (!this.$calledInitConfig) {
Ext.Error.raise('initConfig should not be called by subclasses, it will be called by Ext.Component');
}
this.mixins.observable.constructor.call(this);
},
addCls: function(cls) {
var me = this,
el = me.rendered ? me.el : me.protoEl;
el.addCls.apply(el, arguments);
return me;
},
addClsWithUI: function(classes, skip) {
var me = this,
clsArray = [],
i = 0,
uiCls = me.uiCls = Ext.Array.clone(me.uiCls),
activeUI = me.activeUI,
length, cls;
if (typeof classes === "string") {
classes = (classes.indexOf(' ') < 0) ? [
classes
] : Ext.String.splitWords(classes);
}
length = classes.length;
for (; i < length; i++) {
cls = classes[i];
if (cls && !me.hasUICls(cls)) {
uiCls.push(cls);
if (activeUI) {
clsArray = clsArray.concat(me.addUIClsToElement(cls));
}
}
}
if (skip !== true && activeUI) {
me.addCls(clsArray);
}
return clsArray;
},
afterComponentLayout: function(width, height, oldWidth, oldHeight) {
var me = this;
if (++me.componentLayoutCounter === 1) {
me.afterFirstLayout(width, height);
}
if (width !== oldWidth || height !== oldHeight) {
me.onResize(width, height, oldWidth, oldHeight);
}
if (me.floating) {
me.onAfterFloatLayout();
}
},
addPlugin: function(plugin) {
var me = this;
plugin = me.constructPlugin(plugin);
if (me.plugins) {
me.plugins.push(plugin);
} else {
me.plugins = [
plugin
];
}
if (me.pluginsInitialized) {
me.initPlugin(plugin);
}
return plugin;
},
addPropertyToState: function(state, propName, value) {
var me = this,
len = arguments.length;
if (len === 3 || me.hasOwnProperty(propName)) {
if (len < 3) {
value = me[propName];
}
if (value !== me.initialConfig[propName]) {
(state || (state = {}))[propName] = value;
}
}
return state;
},
addUIClsToElement: function(uiCls) {
var me = this,
baseClsUI = me.baseCls + '-' + me.ui + '-' + uiCls,
result = [
Ext.baseCSSPrefix + uiCls,
me.baseCls + '-' + uiCls,
baseClsUI
],
childEls, childElName, el, suffix;
if (me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) {
baseClsUI += '-';
childEls = me.getChildEls();
for (childElName in childEls) {
suffix = childEls[childElName].frame;
if (suffix && suffix !== true) {
el = me[childElName];
if (el) {
el.addCls(baseClsUI + suffix);
}
}
}
}
return result;
},
removeUIClsFromElement: function(uiCls) {
var me = this,
baseClsUI = me.baseCls + '-' + me.ui + '-' + uiCls,
result = [
Ext.baseCSSPrefix + uiCls,
me.baseCls + '-' + uiCls,
baseClsUI
],
childEls, childElName, el, suffix;
if (me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) {
baseClsUI += '-';
childEls = me.getChildEls();
for (childElName in childEls) {
suffix = childEls[childElName].frame;
if (suffix && suffix !== true) {
el = me[childElName];
if (el) {
el.removeCls(baseClsUI + suffix);
}
}
}
}
return result;
},
adjustPosition: function(x, y) {
var me = this,
floatParentBox;
if (me.isContainedFloater()) {
floatParentBox = me.floatParent.getTargetEl().getViewRegion();
x += floatParentBox.left;
y += floatParentBox.top;
}
return {
x: x,
y: y
};
},
afterHide: function(cb, scope) {
var me = this,
container = me.focusableContainer;
me.hiddenByLayout = null;
if (this.ownerLayout) {
this.updateLayout({
isRoot: false
});
}
Ext.callback(cb, scope || me);
me.fireHierarchyEvent('hide');
me.fireEvent('hide', me);
if (container) {
container.onFocusableChildHide(me);
}
},
afterSetPosition: function(x, y) {
var me = this;
me.onPosition(x, y);
if (me.hasListeners.move) {
me.fireEvent('move', me, x, y);
}
},
afterShow: function(animateTarget, cb, scope) {
var me = this,
myEl = me.el,
fromBox, toBox, ghostPanel;
animateTarget = me.getAnimateTarget(animateTarget);
if (!me.ghost) {
animateTarget = null;
}
if (animateTarget) {
toBox = {
x: myEl.getX(),
y: myEl.getY(),
width: myEl.dom.offsetWidth,
height: myEl.dom.offsetHeight
};
fromBox = {
x: animateTarget.getX(),
y: animateTarget.getY(),
width: animateTarget.dom.offsetWidth,
height: animateTarget.dom.offsetHeight
};
myEl.addCls(me.offsetsCls);
ghostPanel = me.ghost();
ghostPanel.el.stopAnimation();
ghostPanel.setX(-10000);
me.ghostBox = toBox;
ghostPanel.el.animate({
from: fromBox,
to: toBox,
listeners: {
afteranimate: function() {
delete ghostPanel.componentLayout.lastComponentSize;
me.unghost();
delete me.ghostBox;
myEl.removeCls(me.offsetsCls);
me.onShowComplete(cb, scope);
}
}
});
} else {
me.onShowComplete(cb, scope);
}
me.fireHierarchyEvent('show');
},
animate: function(animObj) {
var me = this,
hasToWidth, hasToHeight, toHeight, toWidth, to, clearWidth, clearHeight, curWidth, w, curHeight, h, isExpanding, wasConstrained, wasConstrainedHeader, passedCallback, oldOverflow;
animObj = animObj || {};
to = animObj.to || {};
if (Ext.fx.Manager.hasFxBlock(me.id)) {
return me;
}
hasToWidth = Ext.isDefined(to.width);
if (hasToWidth) {
toWidth = Ext.Number.constrain(to.width, me.minWidth, me.maxWidth);
}
hasToHeight = Ext.isDefined(to.height);
if (hasToHeight) {
toHeight = Ext.Number.constrain(to.height, me.minHeight, me.maxHeight);
}
if (!animObj.dynamic && (hasToWidth || hasToHeight)) {
curWidth = (animObj.from ? animObj.from.width : undefined) || me.getWidth();
w = curWidth;
curHeight = (animObj.from ? animObj.from.height : undefined) || me.getHeight();
h = curHeight;
isExpanding = false;
if (hasToHeight && toHeight > curHeight) {
h = toHeight;
isExpanding = true;
}
if (hasToWidth && toWidth > curWidth) {
w = toWidth;
isExpanding = true;
}
if (hasToHeight || hasToWidth) {
oldOverflow = me.el.getStyle('overflow');
if (oldOverflow !== 'hidden') {
me.el.setStyle('overflow', 'hidden');
}
}
if (isExpanding) {
clearWidth = !Ext.isNumber(me.width);
clearHeight = !Ext.isNumber(me.height);
me.setSize(w, h);
me.el.setSize(curWidth, curHeight);
if (clearWidth) {
delete me.width;
}
if (clearHeight) {
delete me.height;
}
}
if (hasToWidth) {
to.width = toWidth;
}
if (hasToHeight) {
to.height = toHeight;
}
}
wasConstrained = me.constrain;
wasConstrainedHeader = me.constrainHeader;
if (wasConstrained || wasConstrainedHeader) {
me.constrain = me.constrainHeader = false;
passedCallback = animObj.callback;
animObj.callback = function() {
me.constrain = wasConstrained;
me.constrainHeader = wasConstrainedHeader;
if (passedCallback) {
passedCallback.call(animObj.scope || me, arguments);
}
if (oldOverflow !== 'hidden') {
me.el.setStyle('overflow', oldOverflow);
}
};
}
return me.mixins.animate.animate.apply(me, arguments);
},
applyScrollable: function(scrollable, oldScrollable) {
var me = this,
rendered = me.rendered,
scrollableCfg, innerEl;
if (scrollable) {
if (scrollable === true || typeof scrollable === 'string') {
scrollableCfg = me._scrollableCfg[scrollable];
if (!scrollableCfg) {
Ext.Error.raise("'" + scrollable + "' is not a valid value for 'scrollable'");
}
scrollable = scrollableCfg;
}
if (oldScrollable) {
oldScrollable.setConfig(scrollable);
scrollable = oldScrollable;
} else {
scrollable = Ext.Object.chain(scrollable);
if (rendered) {
scrollable.element = me.getOverflowEl();
innerEl = me.getScrollerEl();
if (innerEl) {
scrollable.innerElement = innerEl;
}
}
scrollable.autoRefresh = false;
if (Ext.supports.touchScroll === 1) {
scrollable.translatable = {
translationMethod: 'scrollparent'
};
scrollable.indicators = false;
}
scrollable = Ext.scroll.Scroller.create(scrollable);
scrollable.component = me;
}
} else if (oldScrollable) {
oldScrollable.setConfig({
x: false,
y: false
});
oldScrollable.destroy();
}
if (me.rendered) {
me.getOverflowStyle();
me.updateLayout();
}
return scrollable;
},
beforeComponentLayout: function() {
return true;
},
beforeDestroy: Ext.emptyFn,
beforeLayout: function() {
if (this.floating) {
this.onBeforeFloatLayout();
}
},
beforeSetPosition: function(x, y, animate) {
var me = this,
pos = null,
x0, hasX, hasY, adj;
if (x) {
if (Ext.isNumber(x0 = x[0])) {
animate = y;
y = x[1];
x = x0;
}
else if ((x0 = x.x) !== undefined) {
animate = y;
y = x.y;
x = x0;
}
}
if (me.constrain || me.constrainHeader) {
pos = me.calculateConstrainedPosition(null, [
x,
y
], true);
if (pos) {
x = pos[0];
y = pos[1];
}
}
hasX = (x !== undefined);
hasY = (y !== undefined);
if (hasX || hasY) {
me.x = x;
me.y = y;
adj = me.adjustPosition(x, y);
pos = {
x: adj.x,
y: adj.y,
anim: animate,
hasX: hasX,
hasY: hasY
};
}
return pos;
},
beforeShow: Ext.emptyFn,
bubble: function(fn, scope, args) {
var p = this;
while (p) {
if (fn.apply(scope || p, args || [
p
]) === false) {
break;
}
p = p.getBubbleTarget();
}
return this;
},
cloneConfig: function(overrides) {
overrides = overrides || {};
var id = overrides.id || Ext.id(),
cfg = Ext.applyIf(overrides, this.initialConfig),
self;
cfg.id = id;
self = Ext.getClass(this);
return new self(cfg);
},
destroy: function() {
var me = this,
selectors = me.renderSelectors,
viewModel = me.getConfig('viewModel', true),
session = me.getConfig('session', true),
selector, ownerCt, el;
if (!me.isDestroyed) {
if (!me.hasListeners.beforedestroy || me.fireEvent('beforedestroy', me) !== false) {
me.destroying = true;
ownerCt = me.floatParent || me.ownerCt;
if (me.floating) {
delete me.floatParent;
if (me.zIndexManager) {
me.zIndexManager.unregister(me);
me.zIndexManager = null;
}
}
me.removeBindings();
me.beforeDestroy();
if (viewModel && viewModel.isViewModel) {
viewModel.destroy();
me.viewModel = null;
}
if (session && session.isSession) {
if (session.getAutoDestroy()) {
session.destroy();
}
me.session = null;
}
if (ownerCt && ownerCt.remove) {
ownerCt.remove(me, false);
}
me.stopAnimation();
me.onDestroy();
Ext.destroy(me.plugins);
me.componentLayout = null;
if (me.hasListeners.destroy) {
me.fireEvent('destroy', me);
}
if (!me.preventRegister) {
Ext.ComponentManager.unregister(me);
}
me.mixins.state.destroy.call(me);
if (me.floating) {
me.onFloatDestroy();
}
me.clearListeners();
if (me.rendered) {
if (!me.preserveElOnDestroy) {
me.el.destroy();
}
me.el.component = null;
me.mixins.elementCt.destroy.call(me);
if (selectors) {
for (selector in selectors) {
if (selectors.hasOwnProperty(selector)) {
el = me[selector];
if (el) {
delete me[selector];
el.destroy();
}
}
}
}
me.data = me.el = me.frameBody = me.rendered = null;
}
me.destroying = false;
me.isDestroyed = true;
}
}
},
disable: function(silent,
fromParent) {
var me = this,
container = me.focusableContainer,
inherited = me.getInherited();
if (!fromParent) {
inherited.disabled = true;
}
if (me.maskOnDisable) {
inherited.disableMask = true;
}
if (!me.disabled) {
me.addCls(me.disabledCls);
if (me.rendered) {
me.onDisable();
} else {
me.disableOnRender = true;
}
me.disabled = true;
if (silent !== true) {
me.fireEvent('disable', me);
}
if (container) {
container.onFocusableChildDisable(me);
}
}
return me;
},
enable: function(silent,
fromParent) {
var me = this,
container = me.focusableContainer,
inherited = me.getInherited();
if (!fromParent) {
delete me.getInherited().disabled;
}
if (me.maskOnDisable) {
delete inherited.disableMask;
}
if (me.disabled) {
if (!(fromParent && inherited.hasOwnProperty('disabled'))) {
me.disableOnRender = false;
me.removeCls(me.disabledCls);
if (me.rendered) {
me.onEnable();
}
me.disabled = false;
if (silent !== true) {
me.fireEvent('enable', me);
}
if (container) {
container.onFocusableChildEnable(me);
}
}
}
return me;
},
findParentBy: function(fn) {
var p;
for (p = this.getRefOwner(); p && !fn(p, this); p = p.getRefOwner()) {}
return p || null;
},
findParentByType: function(xtype) {
return Ext.isFunction(xtype) ? this.findParentBy(function(p) {
return p.constructor === xtype;
}) : this.up(xtype);
},
findPlugin: function(ptype) {
var i,
plugins = this.plugins,
ln = plugins && plugins.length;
for (i = 0; i < ln; i++) {
if (plugins[i].ptype === ptype) {
return plugins[i];
}
}
},
getAnimateTarget: function(target) {
target = target || this.animateTarget;
if (target) {
target = target.isComponent ? target.getEl() : Ext.get(target);
}
return target || null;
},
getBubbleTarget: function() {
return this.getRefOwner();
},
getComponentLayout: function() {
var me = this;
if (!me.componentLayout || !me.componentLayout.isLayout) {
me.setComponentLayout(Ext.layout.Layout.create(me.componentLayout, 'autocomponent'));
}
return me.componentLayout;
},
getEl: function() {
return this.el;
},
getHeight: function() {
return this.el.getHeight();
},
initInheritedState: function(inheritedState) {
var me = this,
layout = me.componentLayout;
if (me.hidden) {
inheritedState.hidden = true;
}
if (me.collapseImmune) {
inheritedState.collapseImmune = true;
}
if (me.modelValidation !== undefined) {
inheritedState.modelValidation = me.modelValidation;
}
me.mixins.bindable.initInheritedState.call(me, inheritedState);
if (layout && layout.initInheritedState) {
layout.initInheritedState(inheritedState);
}
},
getId: function() {
var me = this,
xtype;
if (!(me.id || (me.id = me.initialConfig.id))) {
xtype = me.getXType();
if (xtype) {
xtype = xtype.replace(Ext.Component.INVALID_ID_CHARS_Re, '-');
} else {
xtype = Ext.name.toLowerCase() + '-comp';
}
me.id = xtype + '-' + me.getAutoId();
}
return me.id;
},
getItemId: function() {
return this.itemId || this.id;
},
getLoader: function() {
var me = this,
loader = me.loader;
if (loader) {
if (!loader.isLoader) {
me.loader = new Ext.ComponentLoader(Ext.apply({
target: me
}, loader));
} else {
loader.setTarget(me);
}
return me.loader;
}
return null;
},
getMaskTarget: function() {
return this.maskElement ? this[this.maskElement] : null;
},
getPlugin: function(pluginId) {
var i,
plugins = this.plugins,
ln = plugins && plugins.length;
for (i = 0; i < ln; i++) {
if (plugins[i].pluginId === pluginId) {
return plugins[i];
}
}
return null;
},
getPosition: function(local) {
var me = this,
xy,
isContainedFloater = me.isContainedFloater(),
floatParentBox;
if ((local === true) && !isContainedFloater) {
return [
me.getLocalX(),
me.getLocalY()
];
}
xy = me.getXY();
if ((local === true) && isContainedFloater) {
floatParentBox = me.floatParent.getTargetEl().getViewRegion();
xy[0] -= floatParentBox.left;
xy[1] -= floatParentBox.top;
}
return xy;
},
getScrollX: function() {
var scroller = this.getScrollable();
return scroller ? scroller.getPosition().x : 0;
},
getScrollY: function() {
var scroller = this.getScrollable();
return scroller ? scroller.getPosition().y : 0;
},
getSize: function(contentSize) {
return this.el.getSize(contentSize);
},
getSizeModel: function(ownerCtSizeModel) {
var me = this,
models = Ext.layout.SizeModel,
ownerContext = me.componentLayout.ownerContext,
width = me.width,
height = me.height,
typeofWidth, typeofHeight, hasPixelWidth, hasPixelHeight, heightModel, ownerLayout, policy, shrinkWrap, topLevel, widthModel,
isFloating = me.floating || me.floated;
if (ownerContext) {
widthModel = ownerContext.widthModel;
heightModel = ownerContext.heightModel;
}
if (!widthModel || !heightModel) {
hasPixelWidth = ((typeofWidth = typeof width) === 'number');
hasPixelHeight = ((typeofHeight = typeof height) === 'number');
topLevel = isFloating || !(ownerLayout = me.ownerLayout);
if (topLevel) {
policy = Ext.layout.Layout.prototype.autoSizePolicy;
shrinkWrap = isFloating ? 3 : me.shrinkWrap;
if (hasPixelWidth) {
widthModel = models.configured;
}
if (hasPixelHeight) {
heightModel = models.configured;
}
} else {
policy = ownerLayout.getItemSizePolicy(me, ownerCtSizeModel);
shrinkWrap = ownerLayout.isItemShrinkWrap(me);
}
if (ownerContext) {
ownerContext.ownerSizePolicy = policy;
}
shrinkWrap = (shrinkWrap === true) ? 3 : (shrinkWrap || 0);
if (topLevel && shrinkWrap) {
if (width && typeofWidth === 'string') {
shrinkWrap &= 2;
}
if (height && typeofHeight === 'string') {
shrinkWrap &= 1;
}
}
if (shrinkWrap !== 3) {
if (!ownerCtSizeModel) {
ownerCtSizeModel = me.ownerCt && me.ownerCt.getSizeModel();
}
if (ownerCtSizeModel) {
shrinkWrap |= (ownerCtSizeModel.width.shrinkWrap ? 1 : 0) | (ownerCtSizeModel.height.shrinkWrap ? 2 : 0);
}
}
if (!widthModel) {
if (!policy.setsWidth) {
if (hasPixelWidth) {
widthModel = models.configured;
} else {
widthModel = (shrinkWrap & 1) ? models.shrinkWrap : models.natural;
}
} else if (policy.readsWidth) {
if (hasPixelWidth) {
widthModel = models.calculatedFromConfigured;
} else {
widthModel = (shrinkWrap & 1) ? models.calculatedFromShrinkWrap : models.calculatedFromNatural;
}
} else {
widthModel = models.calculated;
}
}
if (!heightModel) {
if (!policy.setsHeight) {
if (hasPixelHeight) {
heightModel = models.configured;
} else {
heightModel = (shrinkWrap & 2) ? models.shrinkWrap : models.natural;
}
} else if (policy.readsHeight) {
if (hasPixelHeight) {
heightModel = models.calculatedFromConfigured;
} else {
heightModel = (shrinkWrap & 2) ? models.calculatedFromShrinkWrap : models.calculatedFromNatural;
}
} else {
heightModel = models.calculated;
}
}
}
return widthModel.pairsByHeightOrdinal[heightModel.ordinal];
},
getState: function() {
var me = this,
state = null,
sizeModel = me.getSizeModel();
if (sizeModel.width.configured) {
state = me.addPropertyToState(state, 'width');
}
if (sizeModel.height.configured) {
state = me.addPropertyToState(state, 'height');
}
return state;
},
getWidth: function() {
return this.el.getWidth();
},
getXType: function() {
return this.self.xtype;
},
getXTypes: function() {
var self = this.self,
xtypes, parentPrototype, parentXtypes;
if (!self.xtypes) {
xtypes = [];
parentPrototype = this;
while (parentPrototype) {
parentXtypes = parentPrototype.xtypes;
if (parentXtypes !== undefined) {
xtypes.unshift.apply(xtypes, parentXtypes);
}
parentPrototype = parentPrototype.superclass;
}
self.xtypeChain = xtypes;
self.xtypes = xtypes.join('/');
}
return self.xtypes;
},
hasCls: function(cls) {
var el = this.rendered ? this.el : this.protoEl;
return el.hasCls.apply(el, arguments);
},
hasUICls: function(cls) {
var me = this,
uiCls = me.uiCls || [];
return Ext.Array.contains(uiCls, cls);
},
hide: function(animateTarget, cb, scope) {
var me = this;
if (me.pendingShow) {
me.pendingShow = false;
}
if (!(me.rendered && !me.isVisible())) {
if (!me.hasListeners.beforehide || me.fireEvent('beforehide', me) !== false || me.hierarchicallyHidden) {
me.getInherited().hidden = me.hidden = true;
if (me.rendered) {
me.onHide.apply(me, arguments);
}
}
}
return me;
},
initComponent: function() {
var me = this,
width = me.width,
height = me.height;
if (me.plugins && !me.plugins.processed) {
me.plugins = me.constructPlugins();
}
me.pluginsInitialized = true;
if (width != null || height != null) {
me.setSize(width, height);
}
if (me.listeners) {
me.on(me.listeners);
me.listeners = null;
}
if (me.focusable) {
me.initFocusable();
}
},
initEvents: function() {
var me = this,
afterRenderEvents = me.afterRenderEvents,
afterRenderEvent, el, property, index, len;
if (afterRenderEvents) {
for (property in afterRenderEvents) {
el = me[property];
if (el && el.on) {
afterRenderEvent = afterRenderEvents[property];
for (index = 0 , len = afterRenderEvent.length; index < len; ++index) {
me.mon(el, afterRenderEvent[index]);
}
}
}
}
if (me.focusable) {
me.initFocusableEvents();
}
},
is: function(selector) {
return Ext.ComponentQuery.is(this, selector);
},
isDescendantOf: function(ancestor) {
var p;
for (p = this.getRefOwner(); p && p !== ancestor; p = p.getRefOwner()) {}
return p || null;
},
isAncestor: function(possibleDescendant) {
while (possibleDescendant) {
if (possibleDescendant.getRefOwner() === this) {
return true;
}
possibleDescendant = possibleDescendant.getRefOwner();
}
},
isDisabled: function() {
return this.disabled;
},
isDraggable: function() {
return !!this.draggable;
},
isDroppable: function() {
return !!this.droppable;
},
isFloating: function() {
return this.floating;
},
isHidden: function() {
return this.hidden;
},
isHierarchicallyHidden: function() {
var child = this,
hidden = false,
parent, parentInheritedState;
for (; (parent = child.ownerCt || child.floatParent); child = parent) {
parentInheritedState = parent.getInherited();
if (parentInheritedState.hidden) {
hidden = true;
break;
}
if (child.getInherited().collapseImmune) {
if (parent.collapsed && !child.collapseImmune) {
hidden = true;
break;
}
} else {
hidden = !!parentInheritedState.collapsed;
break;
}
}
return hidden;
},
isLayoutChild: function(ownerCandidate) {
return !this.floating && !!this.up(ownerCandidate);
},
isLayoutRoot: function() {
var me = this,
ownerLayout = me.ownerLayout;
if (!ownerLayout || me._isLayoutRoot || me.floating) {
return true;
}
return ownerLayout.isItemLayoutRoot(me);
},
isLayoutSuspended: function() {
var comp = this,
ownerLayout;
while (comp) {
if (comp.layoutSuspendCount || comp.suspendLayout) {
return true;
}
ownerLayout = comp.ownerLayout;
if (!ownerLayout) {
break;
}
comp = ownerLayout.owner;
}
return false;
},
isVisible: function(deep) {
var me = this,
hidden;
if (me.hidden || !me.rendered || me.isDestroyed) {
hidden = true;
} else if (deep) {
hidden = me.isHierarchicallyHidden();
}
return !hidden;
},
isXType: function(xtype, shallow) {
return shallow ? (Ext.Array.indexOf(this.xtypes, xtype) !== -1) : !!this.xtypesMap[xtype];
},
isMasked: function(deep) {
var me = this;
return !!(me.masked || (me.loadMask && me.loadMask.isVisible()) || (deep && me.getInherited().masked));
},
setMasked: function(isMasked) {
var me = this,
container = me.focusableContainer;
if (isMasked) {
me.masked = true;
me.getInherited().masked = isMasked;
} else {
me.masked = false;
delete me.getInherited().masked;
}
if (container) {
container.onFocusableChildMasked(me, isMasked);
}
return me;
},
mask: function(msg, msgCls, elHeight) {
var box = this.lastBox,
target = this.getMaskTarget() || this.el;
if (box) {
elHeight = box.height;
}
target.mask(msg, msgCls, elHeight);
this.setMasked(true);
},
nextNode: function(selector,
includeSelf) {
var node = this,
ownerCt = node.ownerCt,
result, it, len, i, sib;
if (includeSelf && node.is(selector)) {
return node;
}
if (ownerCt) {
for (it = ownerCt.items.items , i = Ext.Array.indexOf(it, node) + 1 , len = it.length; i < len; i++) {
sib = it[i];
if (sib.is(selector)) {
return sib;
}
if (sib.down) {
result = sib.down(selector);
if (result) {
return result;
}
}
}
return ownerCt.nextNode(selector);
}
return null;
},
nextSibling: function(selector) {
var o = this.ownerCt,
it, last, idx, c;
if (o) {
it = o.items;
idx = it.indexOf(this) + 1;
if (idx) {
if (selector) {
for (last = it.getCount(); idx < last; idx++) {
if ((c = it.getAt(idx)).is(selector)) {
return c;
}
}
} else {
if (idx < it.getCount()) {
return it.getAt(idx);
}
}
}
}
return null;
},
onAdded: function(container, pos, instanced) {
var me = this,
inheritedState = me.inheritedState;
me.ownerCt = container;
if (inheritedState && instanced) {
me.invalidateInheritedState();
}
if (me.reference) {
me.fixReference();
}
if (me.hasListeners && me.hasListeners.added) {
me.fireEvent('added', me, container, pos);
}
if (Ext.GlobalEvents.hasListeners.added) {
me.fireHierarchyEvent('added');
}
},
onRemoved: function(destroying) {
var me = this,
refHolder;
if (Ext.GlobalEvents.hasListeners.removed) {
me.fireHierarchyEvent('removed');
}
if (me.hasListeners.removed) {
me.fireEvent('removed', me, me.ownerCt);
}
if (me.reference) {
refHolder = me.lookupReferenceHolder();
if (refHolder) {
refHolder.clearReference(me);
}
}
if (!destroying) {
me.removeBindings();
}
if (me.inheritedState && !destroying) {
me.invalidateInheritedState();
}
me.ownerCt = me.ownerLayout = null;
},
onBoxReady: function(width, height) {
var me = this,
scroller = me.scrollable;
if (me.resizable) {
me.initResizable(me.resizable);
}
if (me.draggable) {
me.initDraggable();
}
if (scroller) {
if (me.touchScroll && scroller.isTouchScroller) {
scroller.setInnerElement(me.getScrollerEl());
}
scroller.setElement(me.getOverflowEl());
if (Ext.isIE) {
Ext.on('show', me.onGlobalShow, me);
}
}
if (me.hasListeners.boxready) {
me.fireEvent('boxready', me, width, height);
}
},
onDestroy: function() {
var me = this,
controller = me.controller,
container = me.focusableContainer;
if (me.bind) {
me.removeBindings();
}
if (controller) {
controller.destroy();
}
me.controller = null;
if (me.rendered) {
Ext.destroy(me.dd, me.resizer, me.proxy, me.proxyWrap, me.resizerComponent, me.scrollable, me.contentEl);
}
if (container) {
container.onFocusableChildDestroy(me);
}
if (me.focusable) {
me.destroyFocusable();
}
Ext.destroy(me.componentLayout, me.loadMask, me.floatingDescendants);
},
onDisable: function() {
var me = this,
dom, nodeName;
if (me.focusable) {
me.disableFocusable();
}
if (me.maskOnDisable && !me.getInheritedConfig('disableMask', true)) {
dom = me.el.dom;
nodeName = dom.nodeName;
if (me.disabledRe.test(nodeName)) {
dom.disabled = true;
}
if (!me.nonMaskableRe.test(nodeName)) {
me.mask();
}
}
},
onEnable: function() {
var me = this,
dom, nodeName;
if (me.focusable) {
me.enableFocusable();
}
if (me.maskOnDisable && me.getInherited().hasOwnProperty('masked')) {
dom = me.el.dom;
nodeName = dom.nodeName;
if (me.disabledRe.test(nodeName)) {
dom.disabled = false;
}
if (!me.nonMaskableRe.test(nodeName)) {
me.unmask();
}
}
},
onGlobalShow: function(c) {
if (this.up(c)) {
this.getScrollable().restoreState();
}
},
onHide: function(animateTarget, cb, scope) {
var me = this,
ghostPanel, fromSize, toBox;
me.revertFocus();
animateTarget = me.getAnimateTarget(animateTarget);
if (!me.ghost) {
animateTarget = null;
}
if (animateTarget) {
toBox = {
x: animateTarget.getX(),
y: animateTarget.getY(),
width: animateTarget.dom.offsetWidth,
height: animateTarget.dom.offsetHeight
};
ghostPanel = me.ghost();
ghostPanel.el.stopAnimation();
fromSize = me.getSize();
ghostPanel.el.animate({
to: toBox,
listeners: {
afteranimate: function() {
delete ghostPanel.componentLayout.lastComponentSize;
ghostPanel.el.hide();
ghostPanel.setHiddenState(true);
ghostPanel.el.setSize(fromSize);
me.afterHide(cb, scope);
}
}
});
}
me.el.hide();
if (!animateTarget) {
me.afterHide(cb, scope);
}
},
onPosition: Ext.emptyFn,
onResize: function(width, height, oldWidth, oldHeight) {
var me = this;
if (me.floating && me.constrain) {
me.doConstrain();
}
if (oldWidth) {
me.refreshScroll();
}
if (me.hasListeners.resize) {
me.fireEvent('resize', me, width, height, oldWidth, oldHeight);
}
},
onShow: function() {
var me = this;
me.el.show();
me.updateLayout({
isRoot: false
});
if (me.floating) {
if (me.maximized) {
me.fitContainer();
} else if (me.constrain) {
me.doConstrain();
}
}
},
onShowComplete: function(cb, scope) {
var me = this,
container = me.focusableContainer;
if (me.floating) {
me.onFloatShow();
}
Ext.callback(cb, scope || me);
me.fireEvent('show', me);
if (container) {
container.onFocusableChildShow(me);
}
delete me.hiddenByLayout;
},
onShowVeto: Ext.emptyFn,
previousNode: function(selector,
includeSelf) {
var node = this,
ownerCt = node.ownerCt,
result, it, i, sib;
if (includeSelf && node.is(selector)) {
return node;
}
if (ownerCt) {
for (it = ownerCt.items.items , i = Ext.Array.indexOf(it, node) - 1; i > -1; i--) {
sib = it[i];
if (sib.query) {
result = sib.query(selector);
result = result[result.length - 1];
if (result) {
return result;
}
}
if (sib.is(selector)) {
return sib;
}
}
return ownerCt.previousNode(selector, true);
}
return null;
},
previousSibling: function(selector) {
var o = this.ownerCt,
it, idx, c;
if (o) {
it = o.items;
idx = it.indexOf(this);
if (idx !== -1) {
if (selector) {
for (--idx; idx >= 0; idx--) {
if ((c = it.getAt(idx)).is(selector)) {
return c;
}
}
} else {
if (idx) {
return it.getAt(--idx);
}
}
}
}
return null;
},
registerFloatingItem: function(cmp) {
var me = this;
if (!me.floatingDescendants) {
me.floatingDescendants = new Ext.ZIndexManager(me);
}
me.floatingDescendants.register(cmp);
},
removeCls: function(cls) {
var me = this,
el = me.rendered ? me.el : me.protoEl;
el.removeCls.apply(el, arguments);
return me;
},
removeClsWithUI: function(classes, skip) {
var me = this,
clsArray = [],
i = 0,
extArray = Ext.Array,
remove = extArray.remove,
uiCls = me.uiCls = extArray.clone(me.uiCls),
activeUI = me.activeUI,
length, cls;
if (typeof classes === "string") {
classes = (classes.indexOf(' ') < 0) ? [
classes
] : Ext.String.splitWords(classes);
}
length = classes.length;
for (i = 0; i < length; i++) {
cls = classes[i];
if (cls && me.hasUICls(cls)) {
remove(uiCls, cls);
if (activeUI) {
clsArray = clsArray.concat(me.removeUIClsFromElement(cls));
}
}
}
if (skip !== true && activeUI) {
me.removeCls(clsArray);
}
return clsArray;
},
resumeLayouts: function(flushOptions) {
var me = this;
if (!me.rendered) {
return;
}
if (!me.layoutSuspendCount) {
Ext.log.warn('Mismatched call to resumeLayouts - layouts are currently not suspended.');
}
if (me.layoutSuspendCount && !--me.layoutSuspendCount) {
me.suspendLayout = false;
if (flushOptions && !me.isLayoutSuspended()) {
me.updateLayout(flushOptions);
}
}
},
scrollBy: function(deltaX, deltaY, animate) {
var scroller = this.getScrollable();
if (scroller) {
scroller.scrollBy(deltaX, deltaY, animate);
}
},
scrollTo: function(x, y, animate) {
var scroller = this.getScrollable();
if (scroller) {
scroller.scrollTo(x, y, animate);
}
},
setAutoScroll: function(scroll) {
this.setScrollable(!!scroll);
return this;
},
setBorder: function(border,
targetEl) {
var me = this,
initial = !!targetEl;
if (me.rendered || initial) {
if (!initial) {
targetEl = me.el;
}
if (!border) {
border = 0;
} else if (border === true) {
border = '1px';
} else {
border = this.unitizeBox(border);
}
targetEl.setStyle('border-width', border);
if (!initial) {
me.updateLayout();
}
}
me.border = border;
},
setDock: function(dock) {
var me = this,
ownerCt = me.ownerCt;
if (dock !== me.dock) {
if (ownerCt && ownerCt.moveDocked) {
ownerCt.moveDocked(me, dock);
} else {
me.dock = dock;
}
}
return me;
},
setDisabled: function(disabled) {
return this[disabled ? 'disable' : 'enable']();
},
setFlex: function(flex) {
this.flex = flex;
},
setHeight: function(height) {
return this.setSize(undefined, height);
},
setLoading: function(load,
targetEl) {
var me = this,
config = {
target: me
};
if (me.rendered) {
if (load !== false) {
if (Ext.isString(load)) {
config.msg = load;
} else {
Ext.apply(config, load);
}
if (!me.loadMask || !me.loadMask.isLoadMask) {
if (targetEl && config.useTargetEl == null) {
config.useTargetEl = true;
}
me.loadMask = new Ext.LoadMask(config);
} else
{
Ext.apply(me.loadMask, config);
}
if (me.loadMask.isVisible()) {
me.loadMask.afterShow();
} else
{
me.loadMask.show();
}
} else
{
if (me.loadMask && me.loadMask.isLoadMask) {
me.loadMask.hide();
}
}
}
return me.loadMask;
},
setMargin: function(margin,
preventLayout) {
var me = this;
if (me.rendered) {
if (!margin && margin !== 0) {
margin = '';
} else {
if (margin === true) {
margin = 5;
}
margin = this.unitizeBox(margin);
}
me.margin = margin;
me.margin$ = null;
me.getEl().setStyle('margin', margin);
if (!preventLayout) {
me.updateLayout(me._notAsLayoutRoot);
}
} else {
me.margin = margin;
}
},
setOverflowXY: function(overflowX, overflowY) {
this.setScrollable({
x: (overflowX && overflowX !== 'hidden') ? overflowX : false,
y: (overflowY && overflowY !== 'hidden') ? overflowY : false
});
return this;
},
setPagePosition: function(x, y, animate) {
var me = this,
p, floatParentBox;
if (Ext.isArray(x)) {
y = x[1];
x = x[0];
}
me.pageX = x;
me.pageY = y;
if (me.floating) {
if (me.isContainedFloater()) {
floatParentBox = me.floatParent.getTargetEl().getViewRegion();
if (Ext.isNumber(x) && Ext.isNumber(floatParentBox.left)) {
x -= floatParentBox.left;
}
if (Ext.isNumber(y) && Ext.isNumber(floatParentBox.top)) {
y -= floatParentBox.top;
}
} else {
p = me.el.translateXY(x, y);
x = p.x;
y = p.y;
}
me.setPosition(x, y, animate);
} else {
p = me.el.translateXY(x, y);
me.setPosition(p.x, p.y, animate);
}
return me;
},
setPosition: function(x, y, animate) {
var me = this,
pos = me.beforeSetPosition.apply(me, arguments);
if (pos && me.rendered) {
x = pos.x;
y = pos.y;
if (animate) {
if (x !== me.getLocalX() || y !== me.getLocalY()) {
me.stopAnimation();
me.animate(Ext.apply({
duration: 1000,
listeners: {
afteranimate: Ext.Function.bind(me.afterSetPosition, me, [
x,
y
])
},
to: {
left: x,
top: y
}
}, animate));
}
} else {
me.setLocalXY(x, y);
me.afterSetPosition(x, y);
}
}
return me;
},
setScrollX: function(x, animate) {
var scroller = this.getScrollable();
if (scroller) {
scroller.scrollTo(x, null, animate);
}
},
setScrollY: function(y, animate) {
var scroller = this.getScrollable();
if (scroller) {
scroller.scrollTo(null, y, animate);
}
},
setSize: function(width, height) {
var me = this,
widthIsString, heightIsString,
oldWidth = me.width,
oldHeight = me.height;
if (width && typeof width === 'object') {
height = width.height;
width = width.width;
}
if (typeof width === 'number') {
me.width = Ext.Number.constrain(width, me.minWidth, me.maxWidth);
} else if (width === null) {
delete me.width;
} else if (typeof width === 'string') {
widthIsString = true;
me.width = width;
}
if (typeof height === 'number') {
me.height = Ext.Number.constrain(height, me.minHeight, me.maxHeight);
} else if (height === null) {
delete me.height;
} else if (typeof height === 'string') {
heightIsString = true;
me.height = height;
}
if (me.rendered && me.isVisible()) {
if (oldWidth !== me.width || oldHeight !== me.height) {
if (me.liquidLayout || widthIsString || heightIsString) {
me.el.setSize(me.width, me.height);
}
me.updateLayout(me._notAsLayoutRoot);
}
}
return me;
},
setStyle: function(prop, value) {
var el = this.el || this.protoEl;
el.setStyle(prop, value);
return this;
},
setUI: function(ui) {
var me = this,
uiCls = me.uiCls,
activeUI = me.activeUI,
classes;
if (ui === activeUI) {
return;
}
if (activeUI) {
classes = me.removeClsWithUI(uiCls, true);
if (classes.length) {
me.removeCls(classes);
}
me.removeUIFromElement();
} else {
me.uiCls = [];
}
me.ui = ui;
me.activeUI = ui;
me.addUIToElement();
classes = me.addClsWithUI(uiCls, true);
if (classes.length) {
me.addCls(classes);
}
if (me.rendered) {
me.updateLayout();
}
},
setVisible: function(visible) {
return this[visible ? 'show' : 'hide']();
},
setHidden: function(hidden) {
return this.setVisible(!hidden);
},
setWidth: function(width) {
return this.setSize(width);
},
show: function(animateTarget, cb, scope) {
var me = this,
rendered = me.rendered;
if (me.hierarchicallyHidden || (me.floating && !rendered && me.isHierarchicallyHidden())) {
if (!rendered) {
me.initHierarchyEvents();
}
if (arguments.length > 1) {
arguments[0] = null;
me.pendingShow = arguments;
} else {
me.pendingShow = true;
}
} else if (rendered && me.isVisible()) {
if (me.floating) {
me.onFloatShow();
}
} else {
if (me.fireEvent('beforeshow', me) !== false) {
me.hidden = false;
delete this.getInherited().hidden;
Ext.suspendLayouts();
if (!rendered && (me.autoRender || me.floating)) {
me.doAutoRender();
rendered = me.rendered;
}
if (rendered) {
me.beforeShow();
Ext.resumeLayouts();
me.onShow.apply(me, arguments);
me.afterShow.apply(me, arguments);
} else {
Ext.resumeLayouts(true);
}
} else {
me.onShowVeto();
}
}
return me;
},
showAt: function(x, y, animate) {
var me = this;
if (!me.rendered && (me.autoRender || me.floating)) {
me.x = x;
me.y = y;
return me.show();
}
if (me.floating) {
me.setPosition(x, y, animate);
} else {
me.setPagePosition(x, y, animate);
}
me.show();
},
showBy: function(cmp, pos, off) {
var me = this;
if (!me.floating) {
Ext.log.warn('Using showBy on a non-floating component');
}
if (me.floating && cmp) {
me.alignTarget = cmp;
if (pos) {
me.defaultAlign = pos;
}
if (off) {
me.alignOffset = off;
}
me.show();
if (!me.hidden) {
me.alignTo(cmp, pos || me.defaultAlign, off || me.alignOffset);
}
}
return me;
},
suspendLayouts: function() {
var me = this;
if (!me.rendered) {
return;
}
if (++me.layoutSuspendCount === 1) {
me.suspendLayout = true;
}
},
unitizeBox: function(box) {
return Ext.Element.unitizeBox(box);
},
unmask: function() {
(this.getMaskTarget() || this.el).unmask();
this.setMasked(false);
},
unregisterFloatingItem: function(cmp) {
var me = this;
if (me.floatingDescendants) {
me.floatingDescendants.unregister(cmp);
}
},
up: function(selector, limit) {
var result = this.getRefOwner(),
limitSelector = typeof limit === 'string',
limitCount = typeof limit === 'number',
limitComponent = limit && limit.isComponent,
steps = 0;
if (selector) {
for (; result; result = result.getRefOwner()) {
steps++;
if (selector.isComponent) {
if (result === selector) {
return result;
}
} else {
if (Ext.ComponentQuery.is(result, selector)) {
return result;
}
}
if (limitSelector && result.is(limit)) {
return;
}
if (limitCount && steps === limit) {
return;
}
if (limitComponent && result === limit) {
return;
}
}
}
return result;
},
update: function(htmlOrData, loadScripts, callback) {
var me = this,
isData = (me.tpl && !Ext.isString(htmlOrData)),
scroller = me.getScrollable(),
container = me.focusableContainer,
sizeModel, doLayout, el;
if (isData) {
me.data = (htmlOrData && htmlOrData.isEntity) ? htmlOrData.getData(true) : htmlOrData;
} else {
me.html = Ext.isObject(htmlOrData) ? Ext.DomHelper.markup(htmlOrData) : htmlOrData;
}
if (me.rendered) {
sizeModel = me.getSizeModel();
doLayout = sizeModel.width.shrinkWrap || sizeModel.height.shrinkWrap;
if (me.isContainer) {
el = me.layout.getRenderTarget();
doLayout = doLayout || me.items.items.length > 0;
} else {
el = me.touchScroll ? me.getScrollerEl() : me.getTargetEl();
}
if (isData) {
me.tpl[me.tplWriteMode](el, me.data || {});
} else {
el.setHtml(me.html, loadScripts, callback);
}
if (doLayout) {
me.updateLayout();
}
if (scroller) {
scroller.refresh(true);
}
if (container) {
container.onFocusableChildUpdate(me);
}
}
},
setHtml: function(html) {
this.update(html);
},
applyData: function(data) {
this.update(data);
},
updateBox: function(box) {
this.setSize(box.width, box.height);
this.setPagePosition(box.x, box.y);
return this;
},
_asLayoutRoot: {
isRoot: true
},
_notAsLayoutRoot: {
isRoot: false
},
updateLayout: function(options) {
var me = this,
defer,
lastBox = me.lastBox,
isRoot = options && options.isRoot;
if (lastBox) {
lastBox.invalid = true;
}
if (!me.rendered || me.layoutSuspendCount || me.suspendLayout) {
return;
}
if (me.hidden) {
Ext.Component.cancelLayout(me);
} else if (typeof isRoot !== 'boolean') {
isRoot = me.isLayoutRoot();
}
if (isRoot || !me.ownerLayout || !me.ownerLayout.onContentChange(me)) {
if (!me.isLayoutSuspended()) {
defer = (options && options.hasOwnProperty('defer')) ? options.defer : me.deferLayouts;
Ext.Component.updateLayout(me, defer);
}
}
},
updateMaxHeight: function(maxHeight, oldMaxHeight) {
this.changeConstraint(maxHeight, oldMaxHeight, 'min', 'max-height', 'height');
},
updateMaxWidth: function(maxWidth, oldMaxWidth) {
this.changeConstraint(maxWidth, oldMaxWidth, 'min', 'max-width', 'width');
},
updateMinHeight: function(minHeight, oldMinHeight) {
this.changeConstraint(minHeight, oldMinHeight, 'max', 'min-height', 'height');
},
updateMinWidth: function(minWidth, oldMinWidth) {
this.changeConstraint(minWidth, oldMinWidth, 'max', 'min-width', 'width');
},
getAnchorToXY: function(el, anchor, local, mySize) {
return el.getAnchorXY(anchor, local, mySize);
},
getBorderPadding: function() {
return this.el.getBorderPadding();
},
getLocalX: function() {
return this.el.getLocalX();
},
getLocalXY: function() {
return this.el.getLocalXY();
},
getLocalY: function() {
return this.el.getLocalY();
},
getX: function() {
return this.el.getX();
},
getXY: function() {
return this.el.getXY();
},
getY: function() {
return this.el.getY();
},
setLocalX: function(x) {
this.el.setLocalX(x);
},
setLocalXY: function(x, y) {
this.el.setLocalXY(x, y);
},
setLocalY: function(y) {
this.el.setLocalY(y);
},
setX: function(x, animate) {
this.el.setX(x, animate);
},
setXY: function(xy, animate) {
this.el.setXY(xy, animate);
},
setY: function(y, animate) {
this.el.setY(y, animate);
},
privates: {
addOverCls: function() {
var me = this;
if (!me.disabled) {
me.el.addCls(me.overCls);
}
},
addUIToElement: function() {
var me = this,
baseClsUI = me.baseCls + '-' + me.ui,
childEls, childElName, el, suffix;
me.addCls(baseClsUI);
if (me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) {
baseClsUI += '-';
childEls = me.getChildEls();
for (childElName in childEls) {
suffix = childEls[childElName].frame;
if (suffix && suffix !== true) {
el = me[childElName];
if (el) {
el.addCls(baseClsUI + suffix);
}
}
}
}
},
changeConstraint: function(newValue, oldValue, constrainMethod, styleName, sizeName) {
var me = this,
size = me[sizeName];
if (newValue != null && typeof size === 'number') {
me[sizeName] = Math[constrainMethod](size, newValue);
}
if (me.liquidLayout) {
if (newValue != null) {
me.setStyle(styleName, newValue + 'px');
} else if (oldValue) {
me.setStyle(styleName, '');
}
}
if (me.rendered) {
me.updateLayout();
}
},
constructPlugin: function(plugin) {
var me = this;
if (typeof plugin === 'string') {
plugin = Ext.PluginManager.create({}, plugin, me);
} else
{
plugin = Ext.PluginManager.create(plugin, null, me);
}
return plugin;
},
constructPlugins: function() {
var me = this,
plugins = me.plugins,
result, i, len;
if (plugins) {
result = [];
result.processed = true;
if (!Ext.isArray(plugins)) {
plugins = [
plugins
];
}
for (i = 0 , len = plugins.length; i < len; i++) {
result[i] = me.constructPlugin(plugins[i]);
}
}
me.pluginsInitialized = true;
return result;
},
detachFromBody: function() {
Ext.getDetachedBody().appendChild(this.el);
Ext.Component.cancelLayout(this);
this.isDetached = true;
},
doAddListener: function(ename, fn, scope, options, order, caller, manager) {
var me = this,
listeners, option, eventOptions, elementName, element;
if (Ext.isObject(fn) || (options && options.element)) {
if (options.element) {
elementName = options.element;
listeners = {};
listeners[ename] = fn;
if (scope) {
listeners.scope = scope;
}
eventOptions = me.$elementEventOptions;
for (option in options) {
if (eventOptions[option]) {
listeners[option] = options[option];
}
}
} else {
listeners = fn;
elementName = ename;
}
element = me[elementName];
if (element && element.isObservable) {
me.mon(element, listeners);
} else {
me.afterRenderEvents = me.afterRenderEvents || {};
if (!me.afterRenderEvents[elementName]) {
me.afterRenderEvents[elementName] = [];
}
me.afterRenderEvents[elementName].push(listeners);
}
return;
}
me.mixins.observable.doAddListener.call(me, ename, fn, scope, options, order, caller, manager);
},
fireHierarchyEvent: function(eventName) {
var globalEvents = Ext.GlobalEvents;
if (globalEvents.hasListeners[eventName]) {
globalEvents.fireEvent(eventName, this);
}
},
getActionEl: function() {
return this.el;
},
getAutoId: function() {
this.autoGenId = true;
return ++Ext.Component.AUTO_ID;
},
getContentTarget: function() {
return this.el;
},
getDragEl: function() {
return this.el;
},
getOverflowEl: function() {
return this.getTargetEl();
},
getOverflowStyle: function() {
var me = this,
scroller = me.getScrollable(),
flags = me._scrollFlags,
x, y, scrollFlags;
if (scroller) {
x = scroller.getX();
if (x === true) {
x = 'auto';
}
y = scroller.getY();
if (y === true) {
y = 'auto';
}
scrollFlags = flags[x][y];
} else {
scrollFlags = flags.none;
}
me.scrollFlags = scrollFlags;
return {
overflowX: scrollFlags.overflowX,
overflowY: scrollFlags.overflowY
};
},
getPlugins: function() {
var plugins = this.plugins;
plugins = (plugins && plugins.processed) ? plugins : this.constructPlugins();
return plugins || null;
},
getProxy: function() {
var me = this,
target;
if (!me.proxy) {
target = Ext.getBody();
me.proxy = me.el.createProxy(Ext.baseCSSPrefix + 'proxy-el', target, true);
}
return me.proxy;
},
getScrollerEl: function() {
var me = this;
return me.scrollerEl || (me.scrollerEl = me.componentLayout.getScrollerEl() || me.getOverflowEl().child(me.scrollerSelector));
},
getTargetEl: function() {
return this.frameBody || this.el;
},
getTdCls: function() {
return Ext.baseCSSPrefix + this.getTdType() + '-' + this.ui + '-cell';
},
getTdType: function() {
return this.xtype;
},
getTpl: function(name) {
return Ext.XTemplate.getTpl(this, name);
},
initCls: function() {
var me = this,
cls = [
me.baseCls
],
targetCls = me.getComponentLayout().targetCls;
if (targetCls) {
cls.push(targetCls);
}
if (Ext.isDefined(me.cmpCls)) {
if (Ext.isDefined(Ext.global.console)) {
Ext.global.console.warn('Ext.Component: cmpCls has been deprecated. Please use componentCls.');
}
me.componentCls = me.cmpCls;
delete me.cmpCls;
}
if (me.componentCls) {
cls.push(me.componentCls);
} else {
me.componentCls = me.baseCls;
}
return cls;
},
initDraggable: function() {
var me = this,
dragTarget = (me.resizer && me.resizer.el !== me.el) ? me.resizerComponent = new Ext.Component({
ariaRole: 'presentation',
el: me.resizer.el,
rendered: true,
container: me.container
}) : me,
ddConfig = Ext.applyIf({
el: dragTarget.getDragEl(),
constrainTo: (me.constrain || me.draggable.constrain) ? (me.constrainTo || (me.floatParent ? me.floatParent.getTargetEl() : me.container)) : undefined
}, me.draggable);
if (me.constrain || me.constrainDelegate) {
ddConfig.constrain = me.constrain;
ddConfig.constrainDelegate = me.constrainDelegate;
}
me.dd = new Ext.util.ComponentDragger(dragTarget, ddConfig);
},
initPadding: function(targetEl) {
var me = this,
padding = me.padding;
if (padding != null) {
if (me.touchScroll || (me.layout && me.layout.managePadding && me.contentPaddingProperty === 'padding')) {
targetEl.setStyle('padding', 0);
} else {
targetEl.setStyle('padding', this.unitizeBox((padding === true) ? 5 : padding));
}
}
},
initPlugin: function(plugin) {
plugin.init(this);
return plugin;
},
initResizable: function(resizable) {
var me = this;
resizable = Ext.apply({
target: me,
dynamic: false,
constrainTo: (me.constrain || (resizable && resizable.constrain)) ? (me.constrainTo || (me.floatParent ? me.floatParent.getTargetEl() : me.container)) : undefined,
handles: me.resizeHandles
}, resizable);
resizable.target = me;
me.resizer = new Ext.resizer.Resizer(resizable);
},
initStyles: function(targetEl) {
var me = this,
margin = me.margin,
border = me.border,
cls = me.cls,
style = me.style,
x = me.x,
y = me.y,
liquidLayout = me.liquidLayout,
width, height;
me.initPadding(targetEl);
if (margin != null) {
targetEl.setStyle('margin', this.unitizeBox((margin === true) ? 5 : margin));
}
if (border != null) {
me.setBorder(border, targetEl);
}
if (cls && cls !== me.initialCls) {
targetEl.addCls(cls);
me.cls = me.initialCls = null;
}
if (style && style !== me.initialStyle) {
targetEl.setStyle(style);
me.style = me.initialStyle = null;
}
if (x != null) {
targetEl.setStyle(me.horizontalPosProp, (typeof x === 'number') ? (x + 'px') : x);
}
if (y != null) {
targetEl.setStyle('top', (typeof y === 'number') ? (y + 'px') : y);
}
if (!me.ownerCt || me.floating) {
if (Ext.scopeCss) {
targetEl.addCls(me.rootCls);
}
targetEl.addCls(me.borderBoxCls);
}
if (liquidLayout || !me.getFrameInfo()) {
width = me.width;
height = me.height;
if (width != null) {
if (typeof width === 'number') {
targetEl.setStyle('width', width + 'px');
} else {
targetEl.setStyle('width', width);
}
}
if (height != null) {
if (typeof height === 'number') {
targetEl.setStyle('height', height + 'px');
} else {
targetEl.setStyle('height', height);
}
}
}
},
isContainedFloater: function() {
return (this.floating && this.floatParent);
},
isDescendant: function(ancestor) {
if (ancestor.isContainer) {
for (var c = this.ownerCt; c; c = c.ownerCt) {
if (c === ancestor) {
return true;
}
}
}
return false;
},
owns: function(element) {
var result = false,
cmp;
if (element.isEvent) {
element = element.target;
} else if (element.isElement) {
element = element.dom;
}
cmp = Ext.Component.fromElement(element);
if (cmp) {
result = (cmp === this) || (!!cmp.up(this));
}
return result;
},
parseBox: function(box) {
return Ext.Element.parseBox(box);
},
reattachToBody: function() {
this.isDetached = false;
},
refreshScroll: function() {
var scroller = this.getScrollable();
if (scroller) {
scroller.refresh();
}
},
removeManagedListenerItem: function(isClear, managedListener, item, ename, fn, scope) {
var me = this,
element = managedListener.options ? managedListener.options.element : null;
if (element) {
element = me[element];
if (element && element.un) {
if (isClear || (managedListener.item === item && managedListener.ename === ename && (!fn || managedListener.fn === fn) && (!scope || managedListener.scope === scope))) {
element.un(managedListener.ename, managedListener.fn, managedListener.scope);
if (!isClear) {
Ext.Array.remove(me.managedListeners, managedListener);
}
}
}
} else {
return me.mixins.observable.removeManagedListenerItem.apply(me, arguments);
}
},
removeOverCls: function() {
this.el.removeCls(this.overCls);
},
removePlugin: function(plugin) {
Ext.Array.remove(this.plugins, plugin);
plugin.destroy();
},
removeUIFromElement: function() {
var me = this,
baseClsUI = me.baseCls + '-' + me.ui,
childEls, childElName, el, suffix;
me.removeCls(baseClsUI);
if (me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) {
baseClsUI += '-';
childEls = me.getChildEls();
for (childElName in childEls) {
suffix = childEls[childElName].frame;
if (suffix && suffix !== true) {
el = me[childElName];
if (el) {
el.removeCls(baseClsUI + suffix);
}
}
}
}
},
setComponentLayout: function(layout) {
var currentLayout = this.componentLayout;
if (currentLayout && currentLayout.isLayout && currentLayout !== layout) {
currentLayout.setOwner(null);
}
this.componentLayout = layout;
layout.setOwner(this);
},
setHiddenState: function(hidden) {
var me = this,
inheritedState = me.getInherited(),
zIndexManager = me.zIndexManager;
me.hidden = hidden;
if (hidden) {
inheritedState.hidden = true;
} else {
delete inheritedState.hidden;
}
if (zIndexManager) {
zIndexManager.onComponentShowHide(me);
}
},
setupProtoEl: function() {
var cls = this.initCls();
this.protoEl.addCls(cls);
},
wrapPrimaryEl: function(dom) {
var me = this,
el = me.el;
if (!el || !el.isElement) {
me.el = Ext.get(dom);
}
if (me.floating) {
this.mixins.floating.constructor.call(this);
}
}
},
deprecated: {
5: {
methods: {
addClass: 'addCls',
doComponentLayout: function() {
this.updateLayout();
return this;
},
removeClass: 'removeCls',
forceComponentLayout: 'updateLayout',
setDocked: 'setDock'
}
}
}
}, function(Component) {
(Component.prototype.$elementEventOptions = Ext.Object.chain(Ext.Element.prototype.$eventOptions)).element = 1;
Component.createAlias({
on: 'addListener',
prev: 'previousSibling',
next: 'nextSibling'
});
Ext.resumeLayouts = function(flush) {
Component.resumeLayouts(flush);
};
Ext.suspendLayouts = function() {
Component.suspendLayouts();
};
Ext.batchLayouts = function(fn, scope) {
Component.suspendLayouts();
fn.call(scope);
Component.resumeLayouts(true);
};
Ext.setGlyphFontFamily = function(fontFamily) {
Ext._glyphFontFamily = fontFamily;
};
Component.hierarchyEventSource = Component.prototype.hierarchyEventSource = Ext.GlobalEvents;
var metaTags = document.getElementsByTagName('head')[0].getElementsByTagName('meta'),
len = metaTags.length,
i, hasViewport;
for (i = 0; i < len; i++) {
if (metaTags[i].name === 'viewport') {
hasViewport = true;
}
}
if (!hasViewport) {
Ext.log.warn('Ext JS requires a viewport meta tag in order to function correctly on mobile devices. Please add the following tag to the <head> of your html page: \n <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">');
}
});
Ext.define('Ext.layout.container.border.Region', {
override: 'Ext.Component',
initBorderRegion: function() {
var me = this;
if (!me._borderRegionInited) {
me._borderRegionInited = true;
me.addStateEvents([
'changeregion',
'changeweight'
]);
Ext.override(me, {
getState: function() {
var state = me.callParent();
state = me.addPropertyToState(state, 'region');
state = me.addPropertyToState(state, 'weight');
return state;
}
});
}
},
getOwningBorderContainer: function() {
var layout = this.getOwningBorderLayout();
return layout && layout.owner;
},
getOwningBorderLayout: function() {
var layout = this.ownerLayout;
return (layout && layout.isBorderLayout) ? layout : null;
},
setRegion: function(region) {
var me = this,
borderLayout,
old = me.region;
if (typeof region !== 'string') {
Ext.Error.raise('Use setBox to set the size or position of a component.');
}
if (region !== old) {
borderLayout = me.getOwningBorderLayout();
if (borderLayout) {
var regionFlags = borderLayout.regionFlags[region],
placeholder = me.placeholder,
splitter = me.splitter,
owner = borderLayout.owner,
regionMeta = borderLayout.regionMeta,
collapsed = me.collapsed || me.floated,
delta, items, index;
if (me.fireEventArgs('beforechangeregion', [
me,
region
]) === false) {
return old;
}
Ext.suspendLayouts();
me.region = region;
Ext.apply(me, regionFlags);
if (me.updateCollapseTool) {
me.updateCollapseTool();
}
if (splitter) {
Ext.apply(splitter, regionFlags);
splitter.updateOrientation();
items = owner.items;
index = items.indexOf(me);
if (index >= 0) {
delta = regionMeta[region].splitterDelta;
if (items.getAt(index + delta) !== splitter) {
items.remove(splitter);
index = items.indexOf(me);
if (delta > 0) {
++index;
}
items.insert(index, splitter);
}
}
}
if (placeholder) {
if (collapsed) {
me.expand(false);
}
owner.remove(placeholder);
me.placeholder = null;
if (collapsed) {
me.collapse(null, false);
}
}
owner.updateLayout();
Ext.resumeLayouts(true);
me.fireEventArgs('changeregion', [
me,
old
]);
} else {
me.region = region;
}
}
return old;
},
setWeight: function(weight) {
var me = this,
ownerCt = me.getOwningBorderContainer(),
placeholder = me.placeholder,
old = me.weight;
if (weight !== old) {
if (me.fireEventArgs('beforechangeweight', [
me,
weight
]) !== false) {
me.weight = weight;
if (placeholder) {
placeholder.weight = weight;
}
if (ownerCt) {
ownerCt.updateLayout();
}
me.fireEventArgs('changeweight', [
me,
old
]);
}
}
return old;
}
}, function(Component) {
var proto = Component.prototype;
proto.setBorderRegion = proto.setRegion;
proto.setRegionWeight = proto.setWeight;
});
Ext.define('Ext.overrides.app.domain.Component', {
override: 'Ext.app.domain.Component',
requires: [
'Ext.Component'
]
}, function(ComponentDomain) {
ComponentDomain.monitor(Ext.Component);
});
Ext.define('Ext.app.EventBus', {
singleton: true,
requires: [
'Ext.app.domain.Component'
],
constructor: function() {
var me = this,
domains = Ext.app.EventDomain.instances;
me.callParent();
me.domains = domains;
me.bus = domains.component.bus;
},
control: function(selectors, controller) {
return this.domains.component.listen(selectors, controller);
},
listen: function(to, controller) {
var domains = this.domains,
domain;
for (domain in to) {
if (to.hasOwnProperty(domain)) {
domains[domain].listen(to[domain], controller);
}
}
},
unlisten: function(controllerId) {
var domains = Ext.app.EventDomain.instances,
domain;
for (domain in domains) {
domains[domain].unlisten(controllerId);
}
}
});
Ext.define('Ext.app.domain.Global', {
extend: 'Ext.app.EventDomain',
requires: [
'Ext.GlobalEvents'
],
singleton: true,
type: 'global',
constructor: function() {
var me = this;
me.callParent();
me.monitor(Ext.GlobalEvents);
},
listen: function(listeners, controller) {
this.callParent([
{
global: listeners
},
controller
]);
},
match: Ext.returnTrue
});
Ext.define('Ext.app.BaseController', {
requires: [
'Ext.app.EventBus',
'Ext.app.domain.Global'
],
uses: [
'Ext.app.domain.Controller'
],
mixins: [
'Ext.mixin.Observable'
],
isController: true,
config: {
id: null,
control: null,
listen: null,
routes: null,
before: null
},
constructor: function(config) {
var me = this;
Ext.apply(me, config);
delete me.control;
delete me.listen;
me.eventbus = Ext.app.EventBus;
me.mixins.observable.constructor.call(me, config);
me.ensureId();
},
applyListen: function(listen) {
if (Ext.isObject(listen)) {
listen = Ext.clone(listen);
}
return listen;
},
applyControl: function(control) {
if (Ext.isObject(control)) {
control = Ext.clone(control);
}
return control;
},
updateControl: function(control) {
this.ensureId();
if (control) {
this.control(control);
}
},
updateListen: function(listen) {
this.ensureId();
if (listen) {
this.listen(listen);
}
},
updateRoutes: function(routes) {
if (routes) {
var me = this,
befores = me.getBefore() || {},
Router = Ext.app.route.Router,
url, config, method;
for (url in routes) {
config = routes[url];
if (Ext.isString(config)) {
config = {
action: config
};
}
method = config.action;
if (!config.before) {
config.before = befores[method];
} else if (befores[method]) {
Ext.log.warn('You have a before method configured on a route ("' + url + '") and in the before object property also in the "' + me.self.getName() + '" controller. Will use the before method in the route and disregard the one in the before property.');
}
Router.connect(url, config, me);
}
}
},
isActive: function() {
return true;
},
control: function(selectors, listeners, controller) {
var me = this,
ctrl = controller,
obj;
if (Ext.isString(selectors)) {
obj = {};
obj[selectors] = listeners;
} else {
obj = selectors;
ctrl = listeners;
}
me.eventbus.control(obj, ctrl || me);
},
listen: function(to, controller) {
this.eventbus.listen(to, controller || this);
},
destroy: function() {
var me = this,
bus = me.eventbus;
Ext.app.route.Router.disconnectAll(me);
if (bus) {
bus.unlisten(me);
me.eventbus = null;
}
me.clearListeners();
me.callParent();
},
redirectTo: function(token, force) {
if (token.isModel) {
token = token.toUrl();
}
if (!force) {
var currentToken = Ext.util.History.getToken();
if (currentToken === token) {
return false;
}
} else {
Ext.app.route.Router.onStateChange(token);
}
Ext.util.History.add(token);
return true;
}
});
Ext.define('Ext.app.Util', {}, function() {
Ext.apply(Ext.app, {
namespaces: {
Ext: {}
},
addNamespaces: function(namespace) {
var namespaces = Ext.app.namespaces,
i, l;
if (!Ext.isArray(namespace)) {
namespace = [
namespace
];
}
for (i = 0 , l = namespace.length; i < l; i++) {
namespaces[namespace[i]] = true;
}
},
clearNamespaces: function() {
Ext.app.namespaces = {};
},
getNamespace: function(className) {
var namespaces = Ext.apply({}, Ext.ClassManager.paths, Ext.app.namespaces),
deepestPrefix = '',
prefix;
for (prefix in namespaces) {
if (namespaces.hasOwnProperty(prefix) && prefix.length > deepestPrefix.length && (prefix + '.' === className.substring(0, prefix.length + 1))) {
deepestPrefix = prefix;
}
}
return deepestPrefix === '' ? undefined : deepestPrefix;
}
});
Ext.getNamespace = Ext.app.getNamespace;
});
Ext.define('Ext.util.CollectionKey', {
mixins: [
'Ext.mixin.Identifiable'
],
isCollectionKey: true,
observerPriority: -200,
config: {
collection: null,
keyFn: null,
property: null,
rootProperty: null,
unique: true
},
generation: 0,
map: null,
mapRebuilds: 0,
constructor: function(config) {
this.initConfig(config);
if (!Ext.isFunction(this.getKey)) {
Ext.Error.raise('CollectionKey requires a keyFn or property config');
}
},
get: function(key) {
var map = this.map || this.getMap();
return map[key] || null;
},
clear: function() {
this.map = null;
},
getRootProperty: function() {
var me = this,
root = this.callParent();
return root !== null ? root : me.getCollection().getRootProperty();
},
indexOf: function(key, startAt) {
var map = this.map || this.getMap(),
item = map[key],
collection = this.getCollection(),
length = collection.length,
i, index, items, n;
if (!item) {
return -1;
}
if (startAt === undefined) {
startAt = -1;
}
if (item instanceof Array) {
items = item;
index = length;
for (n = items.length; n-- > 0; ) {
i = collection.indexOf(items[n]);
if (i < index && i > startAt) {
index = i;
}
}
if (index === length) {
return -1;
}
} else {
index = collection.indexOf(item);
}
return (index > startAt) ? index : -1;
},
updateKey: function(item, oldKey) {
var me = this,
map = me.map,
bucket, index;
if (map) {
bucket = map[oldKey];
if (bucket instanceof Array) {
index = Ext.Array.indexOf(bucket, item);
if (index >= 0) {
if (bucket.length > 2) {
bucket.splice(index, 1);
} else {
map[oldKey] = bucket[1 - index];
}
}
}
else if (bucket) {
if (me.getUnique() && bucket !== item) {
Ext.Error.raise('Incorrect oldKey "' + oldKey + '" for item with newKey "' + me.getKey(item) + '"');
}
delete map[oldKey];
}
me.add([
item
]);
}
},
onCollectionAdd: function(collection, add) {
if (this.map) {
this.add(add.items);
}
},
onCollectionItemChange: function(collection, details) {
this.map = null;
},
onCollectionRefresh: function() {
this.map = null;
},
onCollectionRemove: function(collection, remove) {
var me = this,
map = me.map,
items = remove.items,
length = items.length,
i, item, key;
if (map) {
if (me.getUnique() && length < collection.length / 2) {
for (i = 0; i < length; ++i) {
key = me.getKey(item = items[i]);
delete map[key];
}
} else {
me.map = null;
}
}
},
add: function(items) {
var me = this,
map = me.map,
bucket, i, item, key, length, unique;
length = items.length;
unique = me.getUnique();
for (i = 0; i < length; ++i) {
key = me.getKey(item = items[i]);
if (unique || !(key in map)) {
map[key] = item;
} else {
if (!((bucket = map[key]) instanceof Array)) {
map[key] = bucket = [
bucket
];
}
bucket.push(item);
}
}
},
applyKeyFn: function(keyFn) {
if (Ext.isString(keyFn)) {
this.getKey = function(item) {
return item[keyFn]();
};
} else {
this.getKey = keyFn;
}
},
updateProperty: function(property) {
var root = this.getRootProperty();
this.getKey = function(item) {
return (root ? item[root] : item)[property];
};
},
getMap: function() {
var me = this,
map = me.map;
if (!map) {
me.map = map = {};
me.keysByItemKey = {};
++me.mapRebuilds;
me.add(me.getCollection().items);
}
return map;
},
updateCollection: function(collection) {
collection.addObserver(this);
},
clone: function() {
return new Ext.util.CollectionKey(this.getCurrentConfig());
}
});
Ext.define('Ext.util.Grouper', {
extend: 'Ext.util.Sorter',
isGrouper: true,
config: {
groupFn: null,
sortProperty: null
},
constructor: function(config) {
if (config) {
if (config.getGroupString) {
Ext.Error.raise("Cannot set getGroupString - use groupFn instead");
}
}
this.callParent(arguments);
},
getGroupString: function(item) {
var group = this._groupFn(item);
return (group != null) ? String(group) : '';
},
sortFn: function(item1, item2) {
var me = this,
lhs = me._groupFn(item1),
rhs = me._groupFn(item2),
property = me._sortProperty,
root = me._root,
sorterFn = me._sorterFn,
transform = me._transform;
if (lhs === rhs) {
return 0;
}
if (property || sorterFn) {
if (sorterFn) {
return sorterFn.call(this, item1, item2);
}
if (root) {
item1 = item1[root];
item2 = item2[root];
}
lhs = item1[property];
rhs = item2[property];
if (transform) {
lhs = transform(lhs);
rhs = transform(rhs);
}
}
return (lhs > rhs) ? 1 : (lhs < rhs ? -1 : 0);
},
standardGroupFn: function(item) {
var root = this._root;
return (root ? item[root] : item)[this._property];
},
updateSorterFn: function() {},
updateProperty: function() {
if (!this.getGroupFn()) {
this.setGroupFn(this.standardGroupFn);
}
}
});
Ext.define('Ext.util.Collection', {
mixins: [
'Ext.mixin.Observable'
],
requires: [
'Ext.util.CollectionKey',
'Ext.util.Filter',
'Ext.util.Sorter',
'Ext.util.Grouper'
],
uses: [
'Ext.util.SorterCollection',
'Ext.util.FilterCollection',
'Ext.util.GroupCollection'
],
isCollection: true,
config: {
autoFilter: true,
autoSort: true,
autoGroup: true,
decoder: null,
extraKeys: null,
filters: null,
grouper: null,
groups: null,
rootProperty: null,
sorters: null,
multiSortLimit: 3,
defaultSortDirection: 'ASC',
source: null
},
generation: 0,
indices: null,
indexRebuilds: 0,
updating: 0,
grouped: false,
sorted: false,
filtered: false,
$endUpdatePriority: 1001,
constructor: function(config) {
var me = this;
me.items = [];
me.map = {};
me.length = 0;
if (config && config.keyFn) {
me.getKey = config.keyFn;
}
me.mixins.observable.constructor.call(me, config);
},
destroy: function() {
var me = this,
filters = me._filters,
sorters = me._sorters,
groups = me._groups;
if (filters) {
filters.destroy();
me._filters = null;
}
if (sorters) {
sorters.destroy();
me._sorters = null;
}
if (groups) {
groups.destroy();
me._groups = null;
}
me.setSource(null);
me.observers = me.items = me.map = null;
},
add: function(item) {
var me = this,
items = me.decodeItems(arguments, 0),
ret = items;
if (items.length) {
me.requestedIndex = me.length;
me.splice(me.length, 0, items);
delete me.requestedIndex;
ret = (items.length === 1) ? items[0] : items;
}
return ret;
},
replaceAll: function() {
var me = this,
len = me.length,
ret, items;
if (len === 0) {
return me.add.apply(me, arguments);
}
items = me.decodeItems(arguments, 0);
ret = items;
if (items.length) {
me.splice(0, me.length, items);
ret = (items.length === 1) ? items[0] : items;
} else {
me.removeAll();
}
return ret;
},
aggregate: function(property, operation, begin, end, scope) {
var me = this,
args = Ext.Array.slice(arguments);
args.unshift(me.items);
return me.aggregateItems.apply(me, args);
},
aggregateByGroup: function(property, operation, scope) {
var groups = this.getGroups();
return this.aggregateGroups(groups, property, operation, scope);
},
aggregateItems: function(items, property, operation, begin, end, scope) {
var me = this,
range = Ext.Number.clipIndices(items.length, [
begin,
end
]),
subsetRequested = (begin !== 0 && end !== items.length),
i, j, rangeLen, root, value, values, valueItems;
begin = range[0];
end = range[1];
if (!Ext.isFunction(operation)) {
operation = me._aggregators[operation];
return operation.call(me, items, begin, end, property, me.getRootProperty());
}
root = me.getRootProperty();
values = new Array(rangeLen);
valueItems = subsetRequested ? new Array(rangeLen) : items;
for (i = begin , j = 0; i < end; ++i , j++) {
if (subsetRequested) {
valueItems[j] = value = items[i];
}
values[j] = (root ? value[root] : value)[property];
}
return operation.call(scope || me, items, values, 0);
},
aggregateGroups: function(groups, property, operation, scope) {
var items = groups.items,
len = items.length,
callDirect = !Ext.isFunction(operation),
out = {},
i, group, result;
for (i = 0; i < len; ++i) {
group = items[i];
if (!callDirect) {
result = this.aggregateItems(group.items, property, operation, null, null, scope);
} else {
result = group[operation](property);
}
out[group.getGroupKey()] = result;
}
return out;
},
beginUpdate: function() {
if (!this.updating++) {
this.notify('beginupdate');
}
},
clear: function() {
var me = this,
generation = me.generation,
ret = generation ? me.items : [],
extraKeys, indexName;
if (generation) {
me.items = [];
me.length = 0;
me.map = {};
me.indices = {};
me.generation++;
extraKeys = me.getExtraKeys();
if (extraKeys) {
for (indexName in extraKeys) {
extraKeys[indexName].clear();
}
}
}
return ret;
},
clone: function() {
var me = this,
copy = new me.self(me.initialConfig);
copy.add(me.items);
return copy;
},
collect: function(property, root, allowNull) {
var items = this.items,
length = items.length,
map = {},
ret = [],
i, strValue, value;
for (i = 0; i < length; ++i) {
value = items[i];
value = (root ? value[root] : value)[property];
strValue = String(value);
if ((allowNull || !Ext.isEmpty(value)) && !map[strValue]) {
map[strValue] = 1;
ret.push(value);
}
}
return ret;
},
contains: function(item) {
var ret = false,
key;
if (item != null) {
key = this.getKey(item);
ret = this.map[key] === item;
}
return ret;
},
containsKey: function(key) {
return key in this.map;
},
createFiltered: function(property, value, anyMatch, caseSensitive, exactMatch) {
var me = this,
ret = new me.self(me.initialConfig),
root = me.getRootProperty(),
items = me.items,
length, i, filters, fn, scope;
if (Ext.isFunction(property)) {
fn = property;
scope = value;
} else {
if (Ext.isString(property)) {
filters = [
new Ext.util.Filter({
property: property,
value: value,
root: root,
anyMatch: anyMatch,
caseSensitive: caseSensitive,
exactMatch: exactMatch
})
];
} else if (property instanceof Ext.util.Filter) {
filters = [
property
];
property.setRoot(root);
} else if (Ext.isArray(property)) {
filters = property.slice(0);
for (i = 0 , length = filters.length; i < length; ++i) {
filters[i].setRoot(root);
}
}
fn = Ext.util.Filter.createFilterFn(filters);
}
scope = scope || me;
for (i = 0 , length = items.length; i < length; i++) {
if (fn.call(scope, items[i])) {
ret.add(items[i]);
}
}
return ret;
},
filterBy: function(fn, scope) {
return this.createFiltered(fn, scope);
},
each: function(fn, scope) {
var items = this.items,
len = items.length,
i, ret;
if (len) {
scope = scope || this;
items = items.slice(0);
for (i = 0; i < len; i++) {
ret = fn.call(scope, items[i], i, len);
if (ret === false) {
break;
}
}
}
return ret;
},
eachKey: function(fn, scope) {
var me = this,
items = me.items,
len = items.length,
i, item, key, ret;
if (len) {
scope = scope || me;
items = items.slice(0);
for (i = 0; i < len; i++) {
key = me.getKey(item = items[i]);
ret = fn.call(scope, key, item, i, len);
if (ret === false) {
break;
}
}
}
return ret;
},
endUpdate: function() {
if (!--this.updating) {
this.notify('endupdate');
}
},
find: function(property, value, start, startsWith, endsWith, ignoreCase) {
if (Ext.isEmpty(value, false)) {
return null;
}
var regex = Ext.String.createRegex(value, startsWith, endsWith, ignoreCase),
root = this.getRootProperty();
return this.findBy(function(item) {
return item && regex.test((root ? item[root] : item)[property]);
}, null, start);
},
findBy: function(fn, scope, start) {
var me = this,
items = me.items,
len = items.length,
i, item, key;
scope = scope || me;
for (i = start || 0; i < len; i++) {
key = me.getKey(item = items[i]);
if (fn.call(scope, item, key)) {
return items[i];
}
}
return null;
},
findIndex: function(property, value, start, startsWith, endsWith, ignoreCase) {
var item = this.find(property, value, start, startsWith, endsWith, ignoreCase);
return item ? this.indexOf(item) : -1;
},
findIndexBy: function(fn, scope, start) {
var item = this.findBy(fn, scope, start);
return item ? this.indexOf(item) : -1;
},
first: function(grouped) {
var groups = grouped ? this.getGroups() : undefined;
return groups ? this.aggregateGroups(groups, null, 'first') : this.items[0];
},
last: function(grouped) {
var groups = grouped ? this.getGroups() : undefined;
return groups ? this.aggregateGroups(groups, null, 'last') : this.items[this.length - 1];
},
get: function(key) {
return this.map[key];
},
getAt: function(index) {
return this.items[index];
},
getByKey: function(key) {
return this.map[key];
},
getCount: function() {
return this.length;
},
getKey: function(item) {
var id = item.id;
return (id === 0 || id) ? id : ((id = item._id) === 0 || id) ? id : item.getId();
},
getRange: function(begin, end) {
var items = this.items,
length = items.length,
range;
if (begin > end) {
Ext.Error.raise('Inverted range passed to Collection.getRange: [' + begin + ',' + end + ']');
}
if (!length) {
range = [];
} else {
range = Ext.Number.clipIndices(length, [
begin,
end
]);
range = items.slice(range[0], range[1]);
}
return range;
},
getValues: function(property, root, start, end) {
var items = this.items,
range = Ext.Number.clipIndices(items.length, [
start,
end
]),
ret = [],
i, value;
for (i = range[0] , end = range[1]; i < end; ++i) {
value = items[i];
value = (root ? value[root] : value)[property];
ret.push(value);
}
return ret;
},
indexOf: function(item) {
if (!item) {
return -1;
}
var key = this.getKey(item);
return this.indexOfKey(key);
},
indexOfKey: function(key) {
var me = this,
indices = me.indices;
if (key in me.map) {
if (!indices) {
indices = me.getIndices();
}
return indices[key];
}
return -1;
},
insert: function(index, item) {
var me = this,
items = me.decodeItems(arguments, 1),
ret = items;
if (items.length) {
me.requestedIndex = index;
me.splice(index, 0, items);
delete me.requestedIndex;
ret = (items.length === 1) ? items[0] : items;
}
return ret;
},
itemChanged: function(item, modified, oldKey,
meta) {
var me = this,
keyChanged = oldKey === 0 || !!oldKey,
filtered = me.filtered && me.getAutoFilter(),
filterChanged = false,
itemMovement = 0,
items = me.items,
last = me.length - 1,
sorted = me.sorted && last > 0 && me.getAutoSort(),
source = me.getSource(),
toAdd,
toRemove = 0,
index,
itemFiltered = false,
newIndex,
wasFiltered = false,
details, newKey, sortFn;
if (source && !source.updating) {
source.itemChanged(item, modified, oldKey, meta);
} else
{
newKey = me.getKey(item);
if (filtered) {
index = me.indexOfKey(keyChanged ? oldKey : newKey);
wasFiltered = (index < 0);
itemFiltered = me.isItemFiltered(item);
filterChanged = (wasFiltered !== itemFiltered);
}
if (filterChanged) {
if (itemFiltered) {
toRemove = [
item
];
newIndex = -1;
} else {
toAdd = [
item
];
newIndex = me.length;
}
}
else if (sorted && !itemFiltered) {
if (!filtered) {
index = me.indexOfKey(keyChanged ? oldKey : newKey);
}
sortFn = me.getSortFn();
if (index && sortFn(items[index - 1], items[index]) > 0) {
itemMovement = -1;
newIndex = Ext.Array.binarySearch(items, item, 0, index, sortFn);
} else if (index < last && sortFn(items[index], items[index + 1]) > 0) {
itemMovement = 1;
newIndex = Ext.Array.binarySearch(items, item, index + 1, sortFn);
}
if (itemMovement) {
toAdd = [
item
];
}
}
details = {
item: item,
key: newKey,
index: newIndex,
filterChanged: filterChanged,
keyChanged: keyChanged,
indexChanged: !!itemMovement,
filtered: itemFiltered,
oldIndex: index,
newIndex: newIndex,
wasFiltered: wasFiltered,
meta: meta
};
if (keyChanged) {
details.oldKey = oldKey;
}
if (modified) {
details.modified = modified;
}
me.beginUpdate();
me.notify('beforeitemchange', [
details
]);
if (keyChanged) {
me.updateKey(item, oldKey);
}
if (toAdd || toRemove) {
me.splice(newIndex, toRemove, toAdd);
}
if (itemMovement > 0) {
details.newIndex--;
} else if (itemMovement < 0) {
details.oldIndex++;
}
me.notify(itemFiltered ? 'filtereditemchange' : 'itemchange', [
details
]);
me.endUpdate();
}
},
remove: function(item) {
var me = this,
items = me.decodeRemoveItems(arguments, 0),
length = me.length;
me.splice(0, items);
return length - me.length;
},
removeAll: function() {
var me = this,
length = me.length;
if (me.generation && length) {
me.splice(0, length);
}
return me;
},
removeAt: function(index, count) {
var me = this,
length = me.length,
Num = Ext.Number,
range = Num.clipIndices(length, [
index,
(count === undefined) ? 1 : count
], Num.Clip.COUNT),
n = range[0],
removeCount = range[1] - n,
item = (removeCount === 1) && me.getAt(n),
removed;
me.splice(n, removeCount);
removed = me.length - length;
return (item && removed) ? item : removed;
},
removeByKey: function(key) {
var item = this.getByKey(key);
if (!item || !this.remove(item)) {
return false;
}
return item;
},
replace: function(item) {
var index = this.indexOf(item);
if (index === -1) {
this.add(item);
} else {
this.insert(index, item);
}
},
splice: function(index, toRemove, toAdd) {
var me = this,
autoSort = me.sorted && me.getAutoSort(),
map = me.map,
items = me.items,
length = me.length,
removeItems = (toRemove instanceof Array) ? me.decodeRemoveItems(toRemove) : null,
isRemoveCount = !removeItems,
Num = Ext.Number,
range = Num.clipIndices(length, [
index,
isRemoveCount ? toRemove : 0
], Num.Clip.COUNT),
begin = range[0],
end = range[1],
removeCount = end - begin,
newItems = me.decodeItems(arguments, 2),
newCount = newItems ? newItems.length : 0,
addItems, newItemsMap, removeMap,
insertAt = begin,
indices = me.indices || ((newCount || removeItems) ? me.getIndices() : null),
adds = null,
removes = removeCount ? [
begin
] : null,
newKeys = null,
source = me.getSource(),
chunk, chunkItems, chunks, i, item, itemIndex, k, key, keys, n, duplicates, sorters;
if (source && !source.updating) {
if (isRemoveCount) {
removeItems = [];
for (i = 0; i < removeCount; ++i) {
removeItems.push(items[begin + i]);
}
}
if (begin < length) {
i = source.indexOf(items[begin]);
} else {
i = source.length;
}
source.splice(i, removeItems, newItems);
return me;
}
if (newCount) {
addItems = newItems;
newKeys = [];
newItemsMap = {};
if (autoSort) {
sorters = me.getSorters();
if (newCount > 1) {
if (!addItems.$cloned) {
newItems = addItems = addItems.slice(0);
}
me.sortData(addItems);
}
}
for (i = 0; i < newCount; ++i) {
key = me.getKey(item = newItems[i]);
if ((k = newItemsMap[key]) !== undefined) {
(duplicates || (duplicates = {}))[k] = 1;
} else {
itemIndex = indices[key];
if (itemIndex < begin || end <= itemIndex) {
(removes || (removes = [])).push(itemIndex);
}
}
newItemsMap[key] = i;
newKeys.push(key);
}
if (duplicates) {
keys = newKeys;
addItems = [];
newKeys = [];
addItems.$cloned = true;
for (i = 0; i < newCount; ++i) {
if (!duplicates[i]) {
item = newItems[i];
addItems.push(item);
newKeys.push(keys[i]);
}
}
newCount = addItems.length;
}
adds = {
items: addItems,
keys: newKeys
};
}
for (i = removeItems ? removeItems.length : 0; i-- > 0; ) {
key = me.getKey(removeItems[i]);
if ((itemIndex = indices[key]) !== undefined) {
(removes || (removes = [])).push(itemIndex);
}
}
if (!adds && !removes) {
return me;
}
me.beginUpdate();
if (removes) {
chunk = null;
chunks = [];
removeMap = {};
if (removes.length > 1) {
removes.sort(Ext.Array.numericSortFn);
}
for (i = 0 , n = removes.length; i < n; ++i) {
key = me.getKey(item = items[itemIndex = removes[i]]);
if (!(key in map)) {
continue;
}
delete map[key];
if (!chunk || itemIndex > (chunk.at + chunkItems.length)) {
chunks.push(chunk = {
at: itemIndex,
items: (chunkItems = []),
keys: (keys = []),
map: removeMap,
next: chunk,
replacement: adds
});
if (adds) {
adds.replaced = chunk;
}
}
chunkItems.push(removeMap[key] = item);
keys.push(key);
if (itemIndex < insertAt) {
--insertAt;
}
if (removeCount > 1 && itemIndex === begin) {
--removeCount;
removes[i--] = ++begin;
}
}
if (adds) {
adds.at = insertAt;
}
for (k = chunks.length; k-- > 0; ) {
chunk = chunks[k];
i = chunk.at;
n = chunk.items.length;
if (i + n < length) {
me.indices = indices = null;
}
me.length = length -= n;
items.splice(i, n);
if (indices) {
keys = chunk.keys;
for (i = 0; i < n; ++i) {
delete indices[keys[i]];
}
}
++me.generation;
me.notify('remove', [
chunk
]);
}
}
if (adds) {
if (autoSort && newCount > 1 && length) {
me.spliceMerge(addItems, newKeys);
} else {
if (autoSort) {
if (newCount > 1) {
insertAt = 0;
me.indices = indices = null;
} else {
insertAt = sorters.findInsertionIndex(adds.items[0], items, me.getSortFn());
}
}
if (insertAt === length) {
items.push.apply(items, addItems);
indices = me.indices;
if (indices) {
for (i = 0; i < newCount; ++i) {
indices[newKeys[i]] = insertAt + i;
}
}
} else {
me.indices = null;
Ext.Array.insert(items, insertAt, addItems);
}
for (i = 0; i < newCount; ++i) {
map[newKeys[i]] = addItems[i];
}
me.length += newCount;
adds.at = insertAt;
adds.atItem = insertAt === 0 ? null : items[insertAt - 1];
++me.generation;
me.notify('add', [
adds
]);
}
}
me.endUpdate();
return me;
},
update: function(fn, scope) {
var me = this;
me.beginUpdate();
try {
return fn.call(scope || me, me);
} catch (e) {
Ext.log.error(this.$className + ': Unhandled Exception: ', e.description || e.message);
throw e;
} finally {
me.endUpdate();
}
},
updateKey: function(item, oldKey) {
var me = this,
map = me.map,
indices = me.indices,
source = me.getSource(),
newKey;
if (source && !source.updating) {
source.updateKey(item, oldKey);
} else if ((newKey = me.getKey(item)) !== oldKey) {
if (map[oldKey] === item && !(newKey in map)) {
delete map[oldKey];
me.updating++;
me.generation++;
map[newKey] = item;
if (indices) {
indices[newKey] = indices[oldKey];
delete indices[oldKey];
}
me.notify('updatekey', [
{
item: item,
newKey: newKey,
oldKey: oldKey
}
]);
me.updating--;
} else {
if (newKey in map && map[newKey] !== item) {
Ext.Error.raise('Duplicate newKey "' + newKey + '" for item with oldKey "' + oldKey + '"');
}
if (oldKey in map && map[oldKey] !== item) {
Ext.Error.raise('Incorrect oldKey "' + oldKey + '" for item with newKey "' + newKey + '"');
}
}
}
},
findInsertIndex: function(item) {
var source = this.getSource(),
sourceItems = source.items,
i = source.indexOf(item) - 1,
sourceItem, index;
while (i > -1) {
sourceItem = sourceItems[i];
index = this.indexOf(sourceItem);
if (index > -1) {
return index + 1;
}
--i;
}
return 0;
},
onCollectionAdd: function(source, details) {
var me = this,
atItem = details.atItem,
items = details.items,
requestedIndex = me.requestedIndex,
filtered, index, copy, i, item, n;
if (!me.sorted) {
if (requestedIndex !== undefined) {
index = requestedIndex;
} else if (atItem) {
index = me.indexOf(atItem);
if (index === -1) {
index = me.findInsertIndex(items[0]);
} else {
++index;
}
} else {
index = 0;
}
}
if (me.getAutoFilter() && me.filtered) {
for (i = 0 , n = items.length; i < n; ++i) {
item = items[i];
if (me.isItemFiltered(item)) {
if (!copy) {
copy = items.slice(0, i);
}
if (!filtered) {
filtered = [];
}
filtered.push(item);
} else if (copy) {
copy.push(item);
}
}
}
me.splice((index < 0) ? me.length : index, 0, copy || items);
if (filtered) {
me.notify('filteradd', [
filtered
]);
}
},
onCollectionBeforeItemChange: function(source, details) {
this.onCollectionUpdateKey = null;
},
onCollectionBeginUpdate: function() {
this.beginUpdate();
},
onCollectionEndUpdate: function() {
this.endUpdate();
},
onCollectionItemChange: function(source, details) {
delete this.onCollectionUpdateKey;
this.itemChanged(details.item, details.modified, details.oldKey, details.meta);
},
onCollectionFilteredItemChange: null,
onCollectionRefresh: function(source) {
var me = this,
map = {},
indices = {},
i, item, items, key, length;
items = source.items;
items = me.filtered && me.getAutoFilter() ? Ext.Array.filter(items, me.getFilterFn()) : items.slice(0);
if (me.sorted) {
me.sortData(items);
}
me.items = items;
me.length = length = items.length;
me.map = map;
me.indices = indices;
for (i = 0; i < length; ++i) {
key = me.getKey(item = items[i]);
map[key] = item;
indices[key] = i;
}
me.notify('refresh');
},
onCollectionRemove: function(source, details) {
this.splice(0, details.items);
},
onCollectionUpdateKey: function(source, details) {
this.updateKey(details.item, details.oldKey);
},
_aggregators: {
average: function(items, begin, end, property, root) {
var n = end - begin;
return n && this._aggregators.sum.call(this, items, begin, end, property, root) / n;
},
bounds: function(items, begin, end, property, root) {
for (var value, max, min,
i = begin; i < end; ++i) {
value = items[i];
value = (root ? value[root] : value)[property];
if (!(value < max)) {
max = value;
}
if (!(value > min)) {
min = value;
}
}
return [
min,
max
];
},
count: function(items) {
return items.length;
},
extremes: function(items, begin, end, property, root) {
var most = null,
least = null,
i, item, max, min, value;
for (i = begin; i < end; ++i) {
item = items[i];
value = (root ? item[root] : item)[property];
if (!(value < max)) {
max = value;
most = item;
}
if (!(value > min)) {
min = value;
least = item;
}
}
return [
least,
most
];
},
max: function(items, begin, end, property, root) {
var b = this._aggregators.bounds.call(this, items, begin, end, property, root);
return b[1];
},
maxItem: function(items, begin, end, property, root) {
var b = this._aggregators.extremes.call(this, items, begin, end, property, root);
return b[1];
},
min: function(items, begin, end, property, root) {
var b = this._aggregators.bounds.call(this, items, begin, end, property, root);
return b[0];
},
minItem: function(items, begin, end, property, root) {
var b = this._aggregators.extremes.call(this, items, begin, end, property, root);
return b[0];
},
sum: function(items, begin, end, property, root) {
for (var value,
sum = 0,
i = begin; i < end; ++i) {
value = items[i];
value = (root ? value[root] : value)[property];
sum += value;
}
return sum;
}
},
_eventToMethodMap: {
add: 'onCollectionAdd',
beforeitemchange: 'onCollectionBeforeItemChange',
beginupdate: 'onCollectionBeginUpdate',
endupdate: 'onCollectionEndUpdate',
itemchange: 'onCollectionItemChange',
filtereditemchange: 'onCollectionFilteredItemChange',
refresh: 'onCollectionRefresh',
remove: 'onCollectionRemove',
beforesort: 'beforeCollectionSort',
sort: 'onCollectionSort',
filter: 'onCollectionFilter',
filteradd: 'onCollectionFilterAdd',
updatekey: 'onCollectionUpdateKey'
},
addObserver: function(observer) {
var me = this,
observers = me.observers;
if (!observers) {
me.observers = observers = [];
}
if (Ext.Array.contains(observers, observer)) {
Ext.Error.raise('Observer already added');
}
observers.push(observer);
if (observers.length > 1) {
Ext.Array.sort(observers, me.prioritySortFn);
}
},
prioritySortFn: function(o1, o2) {
var a = o1.observerPriority || 0,
b = o2.observerPriority || 0;
return a - b;
},
applyExtraKeys: function(extraKeys, oldExtraKeys) {
var me = this,
ret = oldExtraKeys || {},
config, name, value;
for (name in extraKeys) {
value = extraKeys[name];
if (!value.isCollectionKey) {
config = {
collection: me
};
if (Ext.isString(value)) {
config.property = value;
} else {
config = Ext.apply(config, value);
}
value = new Ext.util.CollectionKey(config);
} else {
value.setCollection(me);
}
ret[name] = me[name] = value;
value.name = name;
}
return ret;
},
applyGrouper: function(grouper) {
if (grouper) {
grouper = this.getSorters().decodeSorter(grouper, 'Ext.util.Grouper');
}
return grouper;
},
decodeItems: function(args, index) {
var me = this,
ret = (index === undefined) ? args : args[index],
cloned, decoder, i;
if (!ret || !ret.$cloned) {
cloned = args.length > index + 1 || !Ext.isIterable(ret);
if (cloned) {
ret = Ext.Array.slice(args, index);
if (ret.length === 1 && ret[0] === undefined) {
ret.length = 0;
}
}
decoder = me.getDecoder();
if (decoder) {
if (!cloned) {
ret = ret.slice(0);
cloned = true;
}
for (i = ret.length; i-- > 0; ) {
if ((ret[i] = decoder.call(me, ret[i])) === false) {
ret.splice(i, 1);
}
}
}
if (cloned) {
ret.$cloned = true;
}
}
return ret;
},
getIndices: function() {
var me = this,
indices = me.indices,
items = me.items,
n = items.length,
i, key;
if (!indices) {
me.indices = indices = {};
++me.indexRebuilds;
for (i = 0; i < n; ++i) {
key = me.getKey(items[i]);
indices[key] = i;
}
}
return indices;
},
notify: function(eventName, args) {
var me = this,
observers = me.observers,
methodName = me._eventToMethodMap[eventName],
added = 0,
index, length, method, observer;
args = args || [];
if (observers && methodName) {
for (index = 0 , length = observers.length; index < length; ++index) {
method = (observer = observers[index])[methodName];
if (method) {
if (!added++) {
args.unshift(me);
}
method.apply(observer, args);
}
}
}
if (!me.hasListeners) {
return;
}
if (me.hasListeners[eventName]) {
if (!added) {
args.unshift(me);
}
me.fireEventArgs(eventName, args);
}
},
getFilterFn: function() {
return this.getFilters().getFilterFn();
},
getFilters: function(autoCreate) {
var ret = this._filters;
if (!ret && autoCreate !== false) {
ret = new Ext.util.FilterCollection();
this.setFilters(ret);
}
return ret;
},
isItemFiltered: function(item) {
return !this.getFilters().filterFn(item);
},
onFilterChange: function(filters) {
var me = this,
source = me.getSource(),
extraKeys, newKeys, key;
if (!source) {
extraKeys = me.getExtraKeys();
if (extraKeys) {
newKeys = {};
for (key in extraKeys) {
newKeys[key] = extraKeys[key].clone(me);
}
}
source = new Ext.util.Collection({
keyFn: me.getKey,
extraKeys: newKeys,
rootProperty: me.getRootProperty()
});
if (me.length) {
source.add(me.items);
}
me.setSource(source);
me.autoSource = source;
} else if (source.length || me.length) {
me.onCollectionRefresh(source);
}
me.notify('filter');
},
applyFilters: function(filters, collection) {
if (filters == null || (filters && filters.isFilterCollection)) {
return filters;
}
if (filters) {
if (!collection) {
collection = this.getFilters();
}
collection.splice(0, collection.length, filters);
}
return collection;
},
updateFilters: function(newFilters, oldFilters) {
var me = this;
if (oldFilters) {
oldFilters.un('endupdate', 'onEndUpdateFilters', me);
}
if (newFilters) {
newFilters.on({
endupdate: 'onEndUpdateFilters',
scope: me,
priority: me.$endUpdatePriority
});
newFilters.$filterable = me;
}
me.onEndUpdateFilters(newFilters);
},
onEndUpdateFilters: function(filters) {
var me = this,
was = me.filtered,
is = !!filters && (filters.length > 0);
if (was || is) {
me.filtered = is;
me.onFilterChange(filters);
}
},
getSortFn: function() {
return this._sortFn || this.createSortFn();
},
getSorters: function(autoCreate) {
var ret = this._sorters;
if (!ret && autoCreate !== false) {
ret = new Ext.util.SorterCollection();
this.setSorters(ret);
}
return ret;
},
onSortChange: function() {
if (this.sorted) {
this.sortItems();
}
},
sort: function(property, direction, mode) {
var sorters = this.getSorters();
sorters.addSort.apply(sorters, arguments);
return this;
},
sortData: function(data) {
Ext.Array.sort(data, this.getSortFn());
return data;
},
sortItems: function(sortFn) {
var me = this;
if (me.sorted) {
if (sortFn) {
Ext.Error.raise('Collections with sorters cannot resorted');
}
sortFn = me.getSortFn();
}
me.indices = null;
me.notify('beforesort', [
me.getSorters(false)
]);
if (me.length) {
Ext.Array.sort(me.items, sortFn);
}
me.notify('sort');
},
sortBy: function(sortFn) {
return this.sortItems(sortFn);
},
findInsertionIndex: function(item, items, comparatorFn) {
if (!items) {
items = this.items;
}
if (!comparatorFn) {
comparatorFn = this.getSortFn();
}
return Ext.Array.binarySearch(items, item, comparatorFn);
},
applySorters: function(sorters, collection) {
if (sorters == null || (sorters && sorters.isSorterCollection)) {
return sorters;
}
if (sorters) {
if (!collection) {
collection = this.getSorters();
}
collection.splice(0, collection.length, sorters);
}
return collection;
},
createSortFn: function() {
var me = this,
grouper = me.getGrouper(),
sorters = me.getSorters(false),
sorterFn = sorters ? sorters.getSortFn() : null;
if (!grouper) {
return sorterFn;
}
return function(lhs, rhs) {
var ret = grouper.sort(lhs, rhs);
if (!ret && sorterFn) {
ret = sorterFn(lhs, rhs);
}
return ret;
};
},
updateGrouper: function(grouper) {
var me = this,
groups = me.getGroups(),
sorters = me.getSorters(),
populate;
me.onSorterChange();
me.grouped = !!grouper;
if (grouper) {
if (!groups) {
groups = new Ext.util.GroupCollection({
itemRoot: me.getRootProperty()
});
groups.$groupable = me;
me.setGroups(groups);
}
groups.setGrouper(grouper);
populate = true;
} else {
if (groups) {
me.removeObserver(groups);
groups.destroy();
}
me.setGroups(null);
}
if (!sorters.updating) {
me.onEndUpdateSorters(sorters);
}
if (populate) {
groups.onCollectionRefresh(me);
}
},
updateSorters: function(newSorters, oldSorters) {
var me = this;
if (oldSorters) {
oldSorters.un('endupdate', 'onEndUpdateSorters', me);
}
if (newSorters) {
newSorters.on({
endupdate: 'onEndUpdateSorters',
scope: me,
priority: me.$endUpdatePriority
});
newSorters.$sortable = me;
}
me.onSorterChange();
me.onEndUpdateSorters(newSorters);
},
onSorterChange: function() {
this._sortFn = null;
},
onEndUpdateSorters: function(sorters) {
var me = this,
was = me.sorted,
is = (me.grouped && me.getAutoGroup()) || (sorters && sorters.length > 0);
if (was || is) {
me.sorted = !!is;
me.onSortChange(sorters);
}
},
removeObserver: function(observer) {
var observers = this.observers;
if (observers) {
Ext.Array.remove(observers, observer);
}
},
spliceMerge: function(newItems, newKeys) {
var me = this,
map = me.map,
newLength = newItems.length,
oldIndex = 0,
oldItems = me.items,
oldLength = oldItems.length,
adds = [],
count = 0,
items = [],
sortFn = me.getSortFn(),
addItems, end, i, newItem, oldItem, newIndex;
me.items = items;
for (newIndex = 0; newIndex < newLength; newIndex = end) {
newItem = newItems[newIndex];
for (; oldIndex < oldLength; ++oldIndex) {
if (sortFn(newItem, oldItem = oldItems[oldIndex]) < 0) {
break;
}
items.push(oldItem);
}
if (oldIndex === oldLength) {
adds[count++] = {
at: items.length,
itemAt: items[items.length - 1],
items: (addItems = [])
};
if (count > 1) {
adds[count - 2].next = adds[count - 1];
}
for (; newIndex < newLength; ++newIndex) {
addItems.push(newItem = newItems[newIndex]);
items.push(newItem);
}
break;
}
adds[count++] = {
at: items.length,
itemAt: items[items.length - 1],
items: (addItems = [
newItem
])
};
if (count > 1) {
adds[count - 2].next = adds[count - 1];
}
items.push(newItem);
for (end = newIndex + 1; end < newLength; ++end) {
if (sortFn(newItem = newItems[end], oldItem) >= 0) {
break;
}
items.push(newItem);
addItems.push(newItem);
}
}
for (; oldIndex < oldLength; ++oldIndex) {
items.push(oldItems[oldIndex]);
}
for (i = 0; i < newLength; ++i) {
map[newKeys[i]] = newItems[i];
}
me.length = items.length;
++me.generation;
me.indices = null;
for (i = 0; i < count; ++i) {
me.notify('add', [
adds[i]
]);
}
},
getGroups: function() {
return this.callParent() || null;
},
updateAutoGroup: function(autoGroup) {
var groups = this.getGroups();
if (groups) {
groups.setAutoGroup(autoGroup);
}
this.onEndUpdateSorters(this._sorters);
},
updateGroups: function(newGroups, oldGroups) {
if (oldGroups) {
this.removeObserver(oldGroups);
}
if (newGroups) {
this.addObserver(newGroups);
}
},
updateSource: function(newSource, oldSource) {
var auto = this.autoSource;
if (oldSource) {
oldSource.removeObserver(this);
if (oldSource === auto) {
auto.destroy();
this.autoSource = null;
}
}
if (newSource) {
newSource.addObserver(this);
if (newSource.length || this.length) {
this.onCollectionRefresh(newSource);
}
}
}
}, function() {
var prototype = this.prototype;
prototype.removeAtKey = prototype.removeByKey;
prototype.decodeRemoveItems = prototype.decodeItems;
Ext.Object.each(prototype._aggregators, function(name) {
prototype[name] = function(property, begin, end) {
return this.aggregate(property, name, begin, end);
};
prototype[name + 'ByGroup'] = function(property) {
return this.aggregateByGroup(property, name);
};
});
});
Ext.define('Ext.util.ObjectTemplate', {
requires: [
'Ext.XTemplate'
],
isObjectTemplate: true,
excludeProperties: {},
valueRe: /^[{][a-z\.]+[}]$/i,
statics: {
create: function(template, options) {
if (!Ext.isObject(template)) {
Ext.Error.raise('The template is not an Object');
}
return template.isObjectTemplate ? template : new Ext.util.ObjectTemplate(template, options);
}
},
constructor: function(template, options) {
Ext.apply(this, options);
this.template = template;
},
apply: function(context) {
var me = this;
delete me.apply;
me.apply = me.compile(me.template);
return me.apply(context);
},
privates: {
compile: function(template) {
var me = this,
exclude = me.excludeProperties,
compiled, i, len, fn;
if (Ext.isString(template)) {
if (template.indexOf('{') < 0) {
fn = function() {
return template;
};
} else if (me.valueRe.test(template)) {
template = template.substring(1, template.length - 1).split('.');
fn = function(context) {
for (var v = context,
i = 0; v && i < template.length; ++i) {
v = v[template[i]];
}
return v;
};
} else {
template = new Ext.XTemplate(template);
fn = function(context) {
return template.apply(context);
};
}
} else if (!template || Ext.isPrimitive(template) || Ext.isFunction(template)) {
fn = function() {
return template;
};
} else if (template instanceof Array) {
compiled = [];
for (i = 0 , len = template.length; i < len; ++i) {
compiled[i] = me.compile(template[i]);
}
fn = function(context) {
var ret = [],
i;
for (i = 0; i < len; ++i) {
ret[i] = compiled[i](context);
}
return ret;
};
} else {
compiled = {};
for (i in template) {
if (!exclude[i]) {
compiled[i] = me.compile(template[i]);
}
}
fn = function(context) {
var ret = {},
i, v;
for (i in template) {
v = exclude[i] ? template[i] : compiled[i](context);
if (v !== undefined) {
ret[i] = v;
}
}
return ret;
};
}
return fn;
}
}
});
Ext.define('Ext.data.schema.Role', {
isRole: true,
left: true,
owner: false,
side: 'left',
isMany: false,
defaultReaderType: 'json',
_internalReadOptions: {
recordsOnly: true,
asRoot: true
},
constructor: function(association, config) {
var me = this,
extra = config.extra;
Ext.apply(me, config);
if (extra) {
delete extra.type;
Ext.apply(me, extra);
delete me.extra;
}
me.association = association;
if (association.owner === me.side) {
association.owner = me;
me.owner = true;
}
},
processUpdate: function() {
Ext.Error.raise('Only the "many" for an association may be processed. "' + this.role + '" is not valid.');
},
processLoad: function(store, associatedEntity, records, session) {
return records;
},
checkMembership: Ext.emptyFn,
adoptAssociated: function(record, session) {
var other = this.getAssociatedItem(record);
if (other) {
session.adopt(other);
}
},
createAssociationStore: function(session, from, records, isComplete) {
var me = this,
association = me.association,
foreignKeyName = association.getFieldName(),
isMany = association.isManyToMany,
storeConfig = me.storeConfig,
id = from.getId(),
config = {
model: me.cls,
role: me,
session: session,
associatedEntity: from,
disableMetaChangeEvent: true,
pageSize: null,
remoteFilter: true,
trackRemoved: !session
},
store;
if (isMany) {
config.filters = [
{
property: me.inverse.field,
value: id,
exactMatch: true
}
];
} else if (foreignKeyName) {
config.filters = [
{
property: foreignKeyName,
value: id,
exactMatch: true
}
];
config.foreignKeyName = foreignKeyName;
}
if (storeConfig) {
Ext.apply(config, storeConfig);
}
store = Ext.Factory.store(config);
me.onStoreCreate(store, session, id);
if (foreignKeyName || (isMany && session)) {
store.on({
scope: me,
add: 'onAddToMany',
remove: 'onRemoveFromMany',
clear: 'onRemoveFromMany'
});
}
if (records) {
store.loadData(records);
store.complete = !!isComplete;
}
return store;
},
onStoreCreate: Ext.emptyFn,
getAssociatedStore: function(inverseRecord, options, scope, records, isComplete) {
var me = this,
storeName = me.getStoreName(),
store = inverseRecord[storeName],
load = options && options.reload,
source = inverseRecord.$source,
session = inverseRecord.session,
args, i, len, raw, rec, sourceStore;
if (!store) {
if (!records && source) {
source = source[storeName];
if (source && !source.isLoading()) {
sourceStore = source;
records = [];
raw = source.getData().items;
for (i = 0 , len = raw.length; i < len; ++i) {
rec = raw[i];
records.push(session.getRecord(rec.self, rec.id));
}
isComplete = true;
}
}
store = me.createAssociationStore(session, inverseRecord, records, isComplete);
store.$source = sourceStore;
if (!records && (me.autoLoad || options)) {
load = true;
}
inverseRecord[storeName] = store;
}
if (options) {
if (load || store.isLoading()) {
store.on('load', function(store, records, success, operation) {
args = [
store,
operation
];
scope = scope || options.scope || inverseRecord;
if (success) {
Ext.callback(options.success, scope, args);
} else {
Ext.callback(options.failure, scope, args);
}
args.push(success);
Ext.callback(options, scope, args);
Ext.callback(options.callback, scope, args);
}, null, {
single: true
});
} else {
args = [
store,
null
];
scope = scope || options.scope || inverseRecord;
Ext.callback(options.success, scope, args);
args.push(true);
Ext.callback(options, scope, args);
Ext.callback(options.callback, scope, args);
}
}
if (load && !store.isLoading()) {
store.load();
}
return store;
},
getAssociatedItem: function(rec) {
var key = this.isMany ? this.getStoreName() : this.getInstanceName();
return rec[key] || null;
},
onDrop: Ext.emptyFn,
getReaderRoot: function() {
var me = this;
return me.associationKey || (me.associationKey = me.association.schema.getNamer().readerRoot(me.role));
},
getReader: function() {
var me = this,
reader = me.reader,
Model = me.cls,
useSimpleAccessors = !me.associationKey,
root = this.getReaderRoot();
if (reader && !reader.isReader) {
if (Ext.isString(reader)) {
reader = {
type: reader
};
}
Ext.applyIf(reader, {
model: Model,
rootProperty: root,
useSimpleAccessors: useSimpleAccessors,
type: me.defaultReaderType
});
reader = me.reader = Ext.createByAlias('reader.' + reader.type, reader);
}
return reader;
},
getInstanceName: function() {
var me = this;
return me.instanceName || (me.instanceName = me.association.schema.getNamer().instanceName(me.role));
},
getOldInstanceName: function() {
return this.oldInstanceName || (this.oldInstanceName = '$old' + this.getInstanceName());
},
getStoreName: function() {
var me = this;
return me.storeName || (me.storeName = me.association.schema.getNamer().storeName(me.role));
},
constructReader: function(fromReader) {
var me = this,
reader = me.getReader(),
Model = me.cls,
useSimpleAccessors = !me.associationKey,
root = me.getReaderRoot(),
proxyReader, proxy;
if (!reader) {
proxy = Model.getProxy();
if (proxy) {
proxyReader = proxy.getReader();
reader = new proxyReader.self();
reader.copyFrom(proxyReader);
reader.setRootProperty(root);
} else {
reader = new fromReader.self({
model: Model,
useSimpleAccessors: useSimpleAccessors,
rootProperty: root
});
}
me.reader = reader;
}
return reader;
},
read: function(record, data, fromReader, readOptions) {
var reader = this.constructReader(fromReader),
root = reader.getRoot(data);
if (root) {
return reader.readRecords(root, readOptions, this._internalReadOptions);
}
},
getCallbackOptions: function(options, scope, defaultScope) {
if (typeof options === 'function') {
options = {
callback: options,
scope: scope || defaultScope
};
} else if (options) {
options = Ext.apply({}, options);
options.scope = scope || options.scope || defaultScope;
}
return options;
},
doGetFK: function(leftRecord, options, scope) {
var me = this,
cls = me.cls,
foreignKey = me.association.getFieldName(),
instanceName = me.getInstanceName(),
rightRecord = leftRecord[instanceName],
reload = options && options.reload,
done = rightRecord !== undefined && !reload,
session = leftRecord.session,
foreignKeyId, args;
if (!done) {
if (session) {
foreignKeyId = leftRecord.get(foreignKey);
if (foreignKeyId || foreignKeyId === 0) {
done = session.peekRecord(cls, foreignKeyId, true) && !reload;
rightRecord = session.getRecord(cls, foreignKeyId, false);
} else {
done = true;
leftRecord[instanceName] = rightRecord = null;
}
} else if (foreignKey) {
foreignKeyId = leftRecord.get(foreignKey);
if (!foreignKeyId && foreignKeyId !== 0) {
done = true;
leftRecord[instanceName] = rightRecord = null;
} else {
if (!rightRecord) {
rightRecord = cls.createWithId(foreignKeyId);
}
}
} else
{
done = true;
}
} else if (rightRecord) {
done = !rightRecord.isLoading();
}
if (done) {
if (options) {
args = [
rightRecord,
null
];
scope = scope || options.scope || leftRecord;
Ext.callback(options.success, scope, args);
args.push(true);
Ext.callback(options, scope, args);
Ext.callback(options.callback, scope, args);
}
} else {
leftRecord[instanceName] = rightRecord;
options = me.getCallbackOptions(options, scope, leftRecord);
rightRecord.load(options);
}
return rightRecord;
},
doSetFK: function(leftRecord, rightRecord, options, scope) {
var me = this,
foreignKey = me.association.getFieldName(),
instanceName = me.getInstanceName(),
current = leftRecord[instanceName],
inverse = me.inverse,
inverseSetter = inverse.setterName,
session = leftRecord.session,
modified, oldInstanceName;
if (rightRecord && rightRecord.isEntity) {
if (current !== rightRecord) {
oldInstanceName = me.getOldInstanceName();
leftRecord[oldInstanceName] = current;
leftRecord[instanceName] = rightRecord;
if (current && current.isEntity) {
current[inverse.getInstanceName()] = undefined;
}
if (foreignKey) {
leftRecord.set(foreignKey, rightRecord.getId());
}
delete leftRecord[oldInstanceName];
if (inverseSetter) {
rightRecord[inverseSetter](leftRecord);
}
}
} else {
if (!foreignKey) {
Ext.Error.raise('No foreignKey specified for "' + me.association.left.role + '" by ' + leftRecord.$className);
}
modified = (leftRecord.changingKey && !inverse.isMany) || leftRecord.set(foreignKey, rightRecord);
if (modified && current && current.isEntity && !current.isEqual(current.getId(), rightRecord)) {
leftRecord[instanceName] = undefined;
if (!inverse.isMany) {
current[inverse.getInstanceName()] = undefined;
}
}
}
if (options) {
if (Ext.isFunction(options)) {
options = {
callback: options,
scope: scope || leftRecord
};
}
return leftRecord.save(options);
}
}
});
Ext.define('Ext.data.schema.Association', {
requires: [
'Ext.data.schema.Role'
],
isOneToOne: false,
isManyToOne: false,
isManyToMany: false,
owner: null,
field: null,
constructor: function(config) {
var me = this,
left, right;
Ext.apply(me, config);
me.left = left = new me.Left(me, me.left);
me.right = right = new me.Right(me, me.right);
left.inverse = right;
right.inverse = left;
},
hasField: function() {
return !!this.field;
},
getFieldName: function() {
var field = this.field;
return field ? field.name : '';
}
});
Ext.define('Ext.data.schema.OneToOne', {
extend: 'Ext.data.schema.Association',
isOneToOne: true,
isToOne: true,
kind: 'one-to-one',
Left: Ext.define(null, {
extend: 'Ext.data.schema.Role',
onDrop: function(rightRecord, session) {
var leftRecord = this.getAssociatedItem(rightRecord);
rightRecord[this.getInstanceName()] = null;
if (leftRecord) {
leftRecord[this.inverse.getInstanceName()] = null;
}
},
createGetter: function() {
var me = this;
return function() {
return me.doGet(this);
};
},
createSetter: function() {
var me = this;
return function(value) {
return me.doSet(this, value);
};
},
doGet: function(rightRecord) {
var instanceName = this.getInstanceName(),
ret = rightRecord[instanceName],
session = rightRecord.session;
if (!ret && session) {}
return ret || null;
},
doSet: function(rightRecord, leftRecord) {
var instanceName = this.getInstanceName(),
ret = rightRecord[instanceName],
inverseSetter = this.inverse.setterName;
if (ret !== leftRecord) {
rightRecord[instanceName] = leftRecord;
if (inverseSetter) {
leftRecord[inverseSetter](rightRecord);
}
}
return ret;
},
read: function(rightRecord, node, fromReader, readOptions) {
var me = this,
leftRecords = me.callParent([
rightRecord,
node,
fromReader,
readOptions
]),
leftRecord;
if (leftRecords) {
leftRecord = leftRecords[0];
if (leftRecord) {
leftRecord[me.inverse.getInstanceName()] = rightRecord;
rightRecord[me.getInstanceName()] = leftRecord;
delete rightRecord.data[me.role];
}
}
}
}),
Right: Ext.define(null, {
extend: 'Ext.data.schema.Role',
left: false,
side: 'right',
createGetter: function() {
var me = this;
return function(options, scope) {
return me.doGetFK(this, options, scope);
};
},
createSetter: function() {
var me = this;
return function(value, options, scope) {
return me.doSetFK(this, value, options, scope);
};
},
onDrop: function(leftRecord, session) {
var me = this,
field = me.association.field,
rightRecord = me.getAssociatedItem(leftRecord),
id;
if (me.inverse.owner) {
if (session) {
id = leftRecord.get(field.name);
if (id || id === 0) {
rightRecord = session.getEntry(me.cls, id).record;
if (rightRecord) {
rightRecord.drop();
}
}
} else {
if (rightRecord) {
rightRecord.drop();
}
}
}
if (field) {
leftRecord.set(field.name, null);
}
leftRecord[me.getInstanceName()] = null;
if (rightRecord) {
rightRecord[me.inverse.getInstanceName()] = null;
}
},
onValueChange: function(leftRecord, session, newValue) {
var me = this,
rightRecord = leftRecord[me.getOldInstanceName()] || me.getAssociatedItem(leftRecord),
hasNewValue = newValue || newValue === 0,
instanceName = me.getInstanceName(),
cls = me.cls;
leftRecord.changingKey = true;
me.doSetFK(leftRecord, newValue);
if (!hasNewValue) {
leftRecord[instanceName] = null;
} else if (session && cls) {
leftRecord[instanceName] = session.peekRecord(cls, newValue) || undefined;
}
if (me.inverse.owner && rightRecord) {
me.association.schema.queueKeyCheck(rightRecord, me);
}
leftRecord.changingKey = false;
},
checkKeyForDrop: function(rightRecord) {
var leftRecord = this.inverse.getAssociatedItem(rightRecord);
if (!leftRecord) {
rightRecord.drop();
}
},
read: function(leftRecord, node, fromReader, readOptions) {
var me = this,
rightRecords = me.callParent([
leftRecord,
node,
fromReader,
readOptions
]),
rightRecord, field, fieldName, session, refs, id, oldId, setKey, data;
if (rightRecords) {
rightRecord = rightRecords[0];
field = me.association.field;
fieldName = field.name;
session = leftRecord.session;
data = leftRecord.data;
if (rightRecord) {
if (session) {
refs = session.getRefs(rightRecord, this.inverse, true);
setKey = (refs && refs[leftRecord.id]) || (data[fieldName] === undefined);
} else {
setKey = true;
}
if (setKey) {
if (field) {
oldId = data[fieldName];
id = rightRecord.id;
if (oldId !== id) {
data[fieldName] = id;
if (session) {
session.updateReference(leftRecord, field, id, oldId);
}
}
}
rightRecord[me.inverse.getInstanceName()] = leftRecord;
leftRecord[me.getInstanceName()] = rightRecord;
}
delete data[me.role];
}
}
}
})
});
Ext.define('Ext.data.schema.ManyToOne', {
extend: 'Ext.data.schema.Association',
isManyToOne: true,
isToOne: true,
kind: 'many-to-one',
Left: Ext.define(null, {
extend: 'Ext.data.schema.Role',
isMany: true,
onDrop: function(rightRecord, session) {
var me = this,
store = me.getAssociatedItem(rightRecord),
leftRecords, len, i, refs, id;
if (store) {
leftRecords = store.removeAll();
if (leftRecords && me.inverse.owner) {
for (i = 0 , len = leftRecords.length; i < len; ++i) {
leftRecords[i].drop();
}
}
store.destroy();
rightRecord[me.getStoreName()] = null;
} else if (session) {
leftRecords = session.getRefs(rightRecord, me);
if (leftRecords) {
for (id in leftRecords) {
leftRecords[id].drop();
}
}
}
},
processUpdate: function(session, associationData) {
var me = this,
entityType = me.inverse.cls,
items = associationData.R,
id, rightRecord, store, leftRecords;
if (items) {
for (id in items) {
rightRecord = session.peekRecord(entityType, id);
if (rightRecord) {
leftRecords = session.getEntityList(me.cls, items[id]);
store = me.getAssociatedItem(rightRecord);
if (store) {
store.loadData(leftRecords);
store.complete = true;
} else {
rightRecord[me.getterName](null, null, leftRecords);
}
} else {
session.onInvalidAssociationEntity(entityType, id);
}
}
}
},
findRecords: function(session, rightRecord, leftRecords, allowInfer) {
var ret = leftRecords,
refs = session.getRefs(rightRecord, this, true),
field = this.association.field,
fieldName = field.name,
leftRecord, id, i, len, seen;
if (!rightRecord.phantom) {
ret = [];
if (refs || allowInfer) {
if (leftRecords) {
seen = {};
for (i = 0 , len = leftRecords.length; i < len; ++i) {
leftRecord = leftRecords[i];
id = leftRecord.id;
if (refs && refs[id]) {
ret.push(leftRecord);
} else if (allowInfer && leftRecord.data[fieldName] === undefined) {
ret.push(leftRecord);
leftRecord.data[fieldName] = rightRecord.id;
session.updateReference(leftRecord, field, rightRecord.id, undefined);
}
seen[id] = true;
}
}
if (refs) {
for (id in refs) {
if (!seen || !seen[id]) {
ret.push(refs[id]);
}
}
}
}
}
return ret;
},
processLoad: function(store, rightRecord, leftRecords, session) {
var ret = leftRecords;
if (session) {
ret = this.findRecords(session, rightRecord, leftRecords);
}
this.onLoadMany(rightRecord, ret, session);
return ret;
},
adoptAssociated: function(rightRecord, session) {
var store = this.getAssociatedItem(rightRecord),
leftRecords, i, len;
if (store) {
store.setSession(session);
leftRecords = store.getData().items;
for (i = 0 , len = leftRecords.length; i < len; ++i) {
session.adopt(leftRecords[i]);
}
}
},
createGetter: function() {
var me = this;
return function(options, scope, leftRecords) {
var session = this.session,
hadRecords = !!leftRecords;
if (session) {
leftRecords = me.findRecords(session, this, leftRecords, true);
if (!hadRecords && (!leftRecords || !leftRecords.length)) {
leftRecords = null;
}
}
return me.getAssociatedStore(this, options, scope, leftRecords, hadRecords);
};
},
createSetter: null,
onAddToMany: function(store, leftRecords) {
this.syncFK(leftRecords, store.getAssociatedEntity(), false);
},
onLoadMany: function(rightRecord, leftRecords, session) {
var instanceName = this.inverse.getInstanceName(),
id = rightRecord.getId(),
field = this.association.field,
i, len, leftRecord, oldId, data, name;
if (field) {
for (i = 0 , len = leftRecords.length; i < len; ++i) {
leftRecord = leftRecords[i];
leftRecord[instanceName] = rightRecord;
if (field) {
name = field.name;
data = leftRecord.data;
oldId = data[name];
if (oldId !== id) {
data[name] = id;
if (session) {
session.updateReference(leftRecord, field, id, oldId);
}
}
}
}
}
},
onRemoveFromMany: function(store, leftRecords) {
this.syncFK(leftRecords, store.getAssociatedEntity(), true);
},
read: function(rightRecord, node, fromReader, readOptions) {
var me = this,
instanceName = me.inverse.getInstanceName(),
leftRecords = me.callParent([
rightRecord,
node,
fromReader,
readOptions
]),
store, len, i;
if (leftRecords) {
store = rightRecord[me.getterName](null, null, leftRecords);
delete rightRecord.data[me.role];
leftRecords = store.getData().items;
for (i = 0 , len = leftRecords.length; i < len; ++i) {
leftRecords[i][instanceName] = rightRecord;
}
}
},
syncFK: function(leftRecords, rightRecord, clearing) {
var foreignKeyName = this.association.getFieldName(),
inverse = this.inverse,
setter = inverse.setterName,
instanceName = inverse.getInstanceName(),
i = leftRecords.length,
id = rightRecord.getId(),
different, leftRecord, val;
while (i-- > 0) {
leftRecord = leftRecords[i];
different = !leftRecord.isEqual(id, leftRecord.get(foreignKeyName));
val = clearing ? null : rightRecord;
if (different !== clearing) {
leftRecord.changingKey = true;
leftRecord[setter](val);
leftRecord.changingKey = false;
} else {
leftRecord[instanceName] = val;
}
}
}
}),
Right: Ext.define(null, {
extend: 'Ext.data.schema.Role',
left: false,
side: 'right',
onDrop: function(leftRecord, session) {
var field = this.association.field;
if (field) {
leftRecord.set(field.name, null);
}
leftRecord[this.getInstanceName()] = null;
},
createGetter: function() {
var me = this;
return function(options, scope) {
return me.doGetFK(this, options, scope);
};
},
createSetter: function() {
var me = this;
return function(rightRecord, options, scope) {
return me.doSetFK(this, rightRecord, options, scope);
};
},
checkMembership: function(session, leftRecord) {
var field = this.association.field,
store;
store = this.getSessionStore(session, leftRecord.get(field.name));
if (store && !store.contains(leftRecord)) {
store.add(leftRecord);
}
},
onValueChange: function(leftRecord, session, newValue, oldValue) {
var me = this,
instanceName = me.getInstanceName(),
cls = me.cls,
hasNewValue, joined, store, i, len, associated, rightRecord;
if (!leftRecord.changingKey) {
hasNewValue = newValue || newValue === 0;
if (!hasNewValue) {
leftRecord[instanceName] = null;
}
if (session) {
store = me.getSessionStore(session, oldValue);
if (store) {
store.remove(leftRecord);
}
if (hasNewValue) {
store = me.getSessionStore(session, newValue);
if (store && !store.isLoading()) {
store.add(leftRecord);
}
if (cls) {
rightRecord = session.peekRecord(cls, newValue);
}
leftRecord[instanceName] = rightRecord || undefined;
}
} else {
joined = leftRecord.joined;
if (joined) {
for (i = 0 , len = joined.length; i < len; ++i) {
store = joined[i];
if (store.isStore) {
associated = store.getAssociatedEntity();
if (associated && associated.self === me.cls && associated.getId() === oldValue) {
store.remove(leftRecord);
}
}
}
}
}
}
if (me.owner && newValue === null) {
me.association.schema.queueKeyCheck(leftRecord, me);
}
},
checkKeyForDrop: function(leftRecord) {
var field = this.association.field;
if (leftRecord.get(field.name) === null) {
leftRecord.drop();
}
},
getSessionStore: function(session, value) {
var cls = this.cls,
rec;
if (cls) {
rec = session.peekRecord(cls, value);
if (rec) {
return this.inverse.getAssociatedItem(rec);
}
}
},
read: function(leftRecord, node, fromReader, readOptions) {
var rightRecords = this.callParent([
leftRecord,
node,
fromReader,
readOptions
]),
rightRecord;
if (rightRecords) {
rightRecord = rightRecords[0];
if (rightRecord) {
leftRecord[this.getInstanceName()] = rightRecord;
delete leftRecord.data[this.role];
}
}
}
})
});
Ext.define('Ext.data.schema.ManyToMany', {
extend: 'Ext.data.schema.Association',
isManyToMany: true,
isToMany: true,
kind: 'many-to-many',
Left: Ext.define(null, {
extend: 'Ext.data.schema.Role',
isMany: true,
digitRe: /^\d+$/,
findRecords: function(session, rightRecord, leftRecords) {
var slice = session.getMatrixSlice(this.inverse, rightRecord.id),
members = slice.members,
ret = [],
cls = this.cls,
seen, i, len, id, member, leftRecord;
if (leftRecords) {
seen = {};
for (i = 0 , len = leftRecords.length; i < len; ++i) {
leftRecord = leftRecords[i];
id = leftRecord.id;
member = members[id];
if (!(member && member[2] === -1)) {
ret.push(leftRecord);
}
seen[id] = true;
}
}
for (id in members) {
member = members[id];
if (!seen || !seen[id] && (member && member[2] !== -1)) {
leftRecord = session.peekRecord(cls, id);
if (leftRecord) {
ret.push(leftRecord);
}
}
}
return ret;
},
processLoad: function(store, rightRecord, leftRecords, session) {
var ret = leftRecords;
if (session) {
ret = this.findRecords(session, rightRecord, leftRecords);
this.onAddToMany(store, ret, true);
}
return ret;
},
processUpdate: function(session, associationData) {
var me = this,
entityType = me.inverse.cls,
items = associationData.R,
id, rightRecord, store, leftRecords;
if (items) {
for (id in items) {
rightRecord = session.peekRecord(entityType, id);
if (rightRecord) {
leftRecords = session.getEntityList(me.cls, items[id]);
store = me.getAssociatedItem(rightRecord);
if (store) {
store.loadData(leftRecords);
store.complete = true;
} else {
rightRecord[me.getterName](null, null, leftRecords);
}
} else {
session.onInvalidAssociationEntity(entityType, id);
}
}
}
me.processMatrixBlock(session, associationData.C, 1);
me.processMatrixBlock(session, associationData.D, -1);
},
checkMembership: function(session, rightRecord) {
var matrix = session.getMatrix(this.association, true),
side, entityType, inverse, slice, slices, id, members, member, leftRecord, store;
if (!matrix) {
return;
}
side = this.left ? matrix.right : matrix.left;
entityType = side.inverse.role.cls;
inverse = this.inverse;
slices = side.slices;
if (slices) {
slice = slices[rightRecord.id];
if (slice) {
members = slice.members;
for (id in members) {
member = members[id];
if (member[2] !== -1) {
leftRecord = session.peekRecord(entityType, id);
if (leftRecord) {
store = inverse.getAssociatedItem(leftRecord);
if (store) {
store.matrixUpdate = 1;
store.add(rightRecord);
store.matrixUpdate = 0;
}
}
}
}
}
}
},
onStoreCreate: function(store, session, id) {
var me = this,
matrix;
if (session) {
matrix = session.getMatrixSlice(me.inverse, id);
matrix.attach(store);
matrix.notify = me.onMatrixUpdate;
matrix.scope = me;
}
},
processMatrixBlock: function(session, leftKeys, state) {
var inverse = this.inverse,
digitRe = this.digitRe,
slice, id;
if (leftKeys) {
for (id in leftKeys) {
if (digitRe.test(id)) {
id = parseInt(id, 10);
}
slice = session.getMatrixSlice(inverse, id);
slice.update(leftKeys[id], state);
}
}
},
createGetter: function() {
var me = this;
return function(options, scope, leftRecords) {
var session = this.session,
hadRecords;
if (session) {
hadRecords = !!leftRecords;
leftRecords = me.findRecords(session, this, leftRecords);
if (!hadRecords && !leftRecords.length) {
leftRecords = null;
}
}
return me.getAssociatedStore(this, options, scope, leftRecords, hadRecords);
};
},
onAddToMany: function(store, leftRecords, load) {
if (!store.matrixUpdate) {
store.matrixUpdate = 1;
store.matrix.update(leftRecords, load === true ? 0 : 1);
store.matrixUpdate = 0;
}
},
onRemoveFromMany: function(store, records) {
if (!store.matrixUpdate) {
store.matrixUpdate = 1;
store.matrix.update(records, -1);
store.matrixUpdate = 0;
}
},
read: function(rightRecord, node, fromReader, readOptions) {
var me = this,
leftRecords = me.callParent([
rightRecord,
node,
fromReader,
readOptions
]);
if (leftRecords) {
rightRecord[me.getterName](null, null, leftRecords);
delete rightRecord.data[me.role];
}
},
onMatrixUpdate: function(matrixSlice, id, state) {
var store = matrixSlice.store,
index, leftRecord, entry;
if (store && !store.loading && !store.matrixUpdate) {
store.matrixUpdate = 1;
index = store.indexOfId(id);
if (state < 0) {
if (index >= 0) {
store.remove([
index
]);
}
} else if (index < 0) {
entry = store.getSession().getEntry(this.type, id);
leftRecord = entry && entry.record;
if (leftRecord) {
store.add(leftRecord);
}
}
store.matrixUpdate = 0;
}
},
adoptAssociated: function(record, session) {
var store = this.getAssociatedItem(record),
records, i, len;
if (store) {
store.setSession(session);
this.onStoreCreate(store, session, record.getId());
records = store.getData().items;
for (i = 0 , len = records.length; i < len; ++i) {
session.adopt(records[i]);
}
}
}
}, function() {
var Left = this;
Ext.ClassManager.onCreated(function() {
Ext.data.schema.ManyToMany.prototype.Right = Ext.define(null, {
extend: Left,
left: false,
side: 'right'
});
}, null, 'Ext.data.schema.ManyToMany');
})
});
Ext.define('Ext.util.Inflector', {
singleton: true,
plurals: [
[
(/(quiz)$/i),
"$1zes"
],
[
(/^(ox)$/i),
"$1en"
],
[
(/([m|l])ouse$/i),
"$1ice"
],
[
(/(matr|vert|ind)ix|ex$/i),
"$1ices"
],
[
(/(x|ch|ss|sh)$/i),
"$1es"
],
[
(/([^aeiouy]|qu)y$/i),
"$1ies"
],
[
(/(hive)$/i),
"$1s"
],
[
(/(?:([^f])fe|([lr])f)$/i),
"$1$2ves"
],
[
(/sis$/i),
"ses"
],
[
(/([ti])um$/i),
"$1a"
],
[
(/(buffal|tomat|potat)o$/i),
"$1oes"
],
[
(/(bu)s$/i),
"$1ses"
],
[
(/(alias|status|sex)$/i),
"$1es"
],
[
(/(octop|vir)us$/i),
"$1i"
],
[
(/(ax|test)is$/i),
"$1es"
],
[
(/^(p)erson$/i),
"$1eople"
],
[
(/^(m)an$/i),
"$1en"
],
[
(/(.*)(child)(ren)?$/i),
"$1$2ren"
],
[
(/s$/i),
"s"
],
[
(/$/),
"s"
]
],
singulars: [
[
(/(address)$/i),
"$1"
],
[
(/(quiz)zes$/i),
"$1"
],
[
(/(matr)ices$/i),
"$1ix"
],
[
(/(vert|ind)ices$/i),
"$1ex"
],
[
(/^(ox)en/i),
"$1"
],
[
(/(alias|status)es$/i),
"$1"
],
[
(/(octop|vir)i$/i),
"$1us"
],
[
(/(cris|ax|test)es$/i),
"$1is"
],
[
(/(shoe)s$/i),
"$1"
],
[
(/(o)es$/i),
"$1"
],
[
(/(bus)es$/i),
"$1"
],
[
(/([m|l])ice$/i),
"$1ouse"
],
[
(/(x|ch|ss|sh)es$/i),
"$1"
],
[
(/(m)ovies$/i),
"$1ovie"
],
[
(/(s)eries$/i),
"$1eries"
],
[
(/([^aeiouy]|qu)ies$/i),
"$1y"
],
[
(/([lr])ves$/i),
"$1f"
],
[
(/(tive)s$/i),
"$1"
],
[
(/(hive)s$/i),
"$1"
],
[
(/([^f])ves$/i),
"$1fe"
],
[
(/(^analy)ses$/i),
"$1sis"
],
[
(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i),
"$1$2sis"
],
[
(/([ti])a$/i),
"$1um"
],
[
(/(n)ews$/i),
"$1ews"
],
[
(/(p)eople$/i),
"$1erson"
],
[
(/s$/i),
""
]
],
uncountable: [
"sheep",
"fish",
"series",
"species",
"money",
"rice",
"information",
"equipment",
"grass",
"mud",
"offspring",
"deer",
"means"
],
singular: function(matcher, replacer) {
this.singulars.unshift([
matcher,
replacer
]);
},
plural: function(matcher, replacer) {
this.plurals.unshift([
matcher,
replacer
]);
},
clearSingulars: function() {
this.singulars = [];
},
clearPlurals: function() {
this.plurals = [];
},
isTransnumeral: function(word) {
return Ext.Array.indexOf(this.uncountable, word) != -1;
},
pluralize: function(word) {
if (this.isTransnumeral(word)) {
return word;
}
var plurals = this.plurals,
length = plurals.length,
tuple, regex, i;
for (i = 0; i < length; i++) {
tuple = plurals[i];
regex = tuple[0];
if (regex == word || (regex.test && regex.test(word))) {
return word.replace(regex, tuple[1]);
}
}
return word;
},
singularize: function(word) {
if (this.isTransnumeral(word)) {
return word;
}
var singulars = this.singulars,
length = singulars.length,
tuple, regex, i;
for (i = 0; i < length; i++) {
tuple = singulars[i];
regex = tuple[0];
if (regex == word || (regex.test && regex.test(word))) {
return word.replace(regex, tuple[1]);
}
}
return word;
},
classify: function(word) {
return Ext.String.capitalize(this.singularize(word));
},
ordinalize: function(number) {
var parsed = parseInt(number, 10),
mod10 = parsed % 10,
mod100 = parsed % 100;
if (11 <= mod100 && mod100 <= 13) {
return number + "th";
} else {
switch (mod10) {
case 1:
return number + "st";
case 2:
return number + "nd";
case 3:
return number + "rd";
default:
return number + "th";
}
}
}
}, function() {
var irregulars = {
alumnus: 'alumni',
cactus: 'cacti',
focus: 'foci',
nucleus: 'nuclei',
radius: 'radii',
stimulus: 'stimuli',
ellipsis: 'ellipses',
paralysis: 'paralyses',
oasis: 'oases',
appendix: 'appendices',
index: 'indexes',
beau: 'beaux',
bureau: 'bureaux',
tableau: 'tableaux',
woman: 'women',
child: 'children',
man: 'men',
corpus: 'corpora',
criterion: 'criteria',
curriculum: 'curricula',
genus: 'genera',
memorandum: 'memoranda',
phenomenon: 'phenomena',
foot: 'feet',
goose: 'geese',
tooth: 'teeth',
antenna: 'antennae',
formula: 'formulae',
nebula: 'nebulae',
vertebra: 'vertebrae',
vita: 'vitae'
},
singular;
for (singular in irregulars) {
if (irregulars.hasOwnProperty(singular)) {
this.plural(singular, irregulars[singular]);
this.singular(irregulars[singular], singular);
}
}
});
Ext.define('Ext.data.schema.Namer', {
mixins: [
'Ext.mixin.Factoryable'
],
requires: [
'Ext.util.Inflector'
],
alias: 'namer.default',
isNamer: true,
capitalize: function(name) {
return Ext.String.capitalize(name);
},
fieldRole: function(name) {
var match = name.match(this.endsWithIdRe, '');
if (match) {
name = name.substr(0, name.length - (match[1] || match[2]).length);
}
return this.apply('uncapitalize', name);
},
idField: function(name) {
return this.apply('uncapitalize,singularize', name) + 'Id';
},
instanceName: function(roleName) {
return this.apply('underscore', roleName);
},
multiRole: function(name) {
return this.apply('undotted,uncapitalize,pluralize', name);
},
pluralize: function(name) {
return Ext.util.Inflector.pluralize(name);
},
readerRoot: function(roleName) {
return this.apply('uncapitalize', roleName);
},
singularize: function(name) {
return Ext.util.Inflector.singularize(name);
},
storeName: function(roleName) {
return this.apply('underscore', roleName);
},
uncapitalize: function(name) {
return Ext.String.uncapitalize(name);
},
underscore: function(name) {
return '_' + name;
},
uniRole: function(name) {
return this.apply('undotted,uncapitalize,singularize', name);
},
undotted: function(name) {
if (name.indexOf('.') < 0) {
return name;
}
var parts = name.split('.'),
index = parts.length;
while (index-- > 1) {
parts[index] = this.apply('capitalize', parts[index]);
}
return parts.join('');
},
getterName: function(role) {
var name = role.role;
if (role && role.isMany) {
return name;
}
return 'get' + this.apply('capitalize', name);
},
inverseFieldRole: function(leftType, unique, rightRole, rightType) {
var me = this,
leftRole = me.apply(unique ? 'uniRole' : 'multiRole', leftType),
s1 = me.apply('pluralize', rightRole),
s2 = me.apply('undotted,pluralize', rightType);
if (s1.toLowerCase() !== s2.toLowerCase()) {
leftRole = rightRole + me.apply('capitalize', leftRole);
}
return leftRole;
},
manyToMany: function(relation, leftType, rightType) {
var me = this,
ret = me.apply('undotted,capitalize,singularize', leftType) + me.apply('undotted,capitalize,pluralize', rightType);
if (relation) {
ret = me.apply('capitalize', relation + ret);
}
return ret;
},
manyToOne: function(leftType, leftRole, rightType, rightRole) {
return this.apply('capitalize,singularize', rightType) + this.apply('capitalize', leftRole);
},
matrixRole: function(relation, entityType) {
var ret = this.apply(relation ? 'multiRole,capitalize' : 'multiRole', entityType);
return relation ? relation + ret : ret;
},
oneToOne: function(leftType, leftRole, rightType, rightRole) {
return this.apply('undotted,capitalize,singularize', rightType) + this.apply('capitalize', leftRole);
},
setterName: function(role) {
return 'set' + this.apply('capitalize', role.role);
},
endsWithIdRe: /(?:(_id)|[^A-Z](Id))$/,
cache: {},
apply: function(operation, name) {
var me = this,
cache = me.cache,
entry = cache[name] || (cache[name] = {}),
ret = entry[operation],
i, length, operations;
if (!ret) {
if (operation.indexOf(',') < 0) {
ret = me[operation](name);
} else {
length = (operations = operation.split(',')).length;
ret = name;
for (i = 0; i < length; ++i) {
ret = me.apply(operations[i], ret);
}
}
entry[operation] = ret;
}
return ret;
}
});
Ext.define('Ext.data.schema.Schema', {
mixins: [
'Ext.mixin.Factoryable'
],
requires: [
'Ext.util.ObjectTemplate',
'Ext.data.schema.OneToOne',
'Ext.data.schema.ManyToOne',
'Ext.data.schema.ManyToMany',
'Ext.data.schema.Namer'
],
alias: 'schema.default',
aliasPrefix: 'schema.',
isSchema: true,
type: 'default',
statics: {
instances: {},
get: function(config) {
var Schema = this,
cache = Schema.instances,
id = 'default',
isString = config && Ext.isString(config),
instance, newConfig;
if (config) {
if (config.isSchema) {
return config;
}
id = isString ? config : (config.id || id);
}
if (!(instance = cache[id])) {
cache[id] = instance = Schema.create(config);
instance.id = id;
} else if (config && !isString) {
if (id !== 'default') {
Ext.Error.raise('Only the default Schema instance can be reconfigured');
}
newConfig = Ext.merge({}, instance.config);
Ext.merge(newConfig, config);
instance.setConfig(newConfig);
instance.config = newConfig;
instance.setConfig = function() {
Ext.Error.raise('The schema can only be reconfigured once');
};
}
return instance;
},
lookupEntity: function(entity) {
var ret = null,
instances = this.instances,
match, name, schema;
if (entity) {
if (entity.isEntity) {
ret = entity.self;
}
else if (Ext.isFunction(entity)) {
ret = entity;
} else if (Ext.isString(entity)) {
ret = Ext.ClassManager.get(entity);
if (ret && (!ret.prototype || !ret.prototype.isEntity)) {
ret = null;
}
if (!ret) {
for (name in instances) {
schema = instances[name];
match = schema.getEntity(entity);
if (match) {
if (ret) {
Ext.Error.raise('Ambiguous entity name "' + entity + '". Defined by schema "' + ret.schema.type + '" and "' + name + '"');
}
ret = match;
}
}
}
if (!ret) {
Ext.Error.raise('No such Entity "' + entity + '".');
}
}
}
return ret;
}
},
assocCount: 0,
entityCount: 0,
config: {
defaultIdentifier: null,
keyCheckDelay: 10,
namer: 'default',
namespace: null,
proxy: {
type: 'ajax',
url: '{prefix}/{entityName}'
},
urlPrefix: ''
},
onClassExtended: function(cls, data) {
var alias = data.alias;
if (alias && !data.type) {
if (!Ext.isString(alias)) {
alias = alias[0];
}
cls.prototype.type = alias.substring(this.prototype.aliasPrefix.length);
}
},
constructor: function(config) {
this.initConfig(config);
this.clear();
},
applyDefaultIdentifier: function(identifier) {
return identifier && Ext.Factory.dataIdentifier(identifier);
},
applyNamer: function(namer) {
var ret = Ext.data.schema.Namer.create(namer);
ret.schema = this;
return ret;
},
applyNamespace: function(namespace) {
if (namespace) {
var end = namespace.length - 1;
if (namespace.charAt(end) !== '.') {
namespace += '.';
}
}
return namespace;
},
applyProxy: function(proxy) {
return Ext.util.ObjectTemplate.create(proxy);
},
eachAssociation: function(fn, scope) {
var associations = this.associations,
name;
for (name in associations) {
if (associations.hasOwnProperty(name)) {
if (fn.call(scope, name, associations[name]) === false) {
break;
}
}
}
},
eachEntity: function(fn, scope) {
var entities = this.entities,
name;
for (name in entities) {
if (entities.hasOwnProperty(name)) {
if (fn.call(scope, name, entities[name].cls) === false) {
break;
}
}
}
},
getAssociation: function(name) {
var entry = this.associations[name];
return entry || null;
},
getEntity: function(name) {
var entry = this.entityClasses[name] || this.entities[name];
return (entry && entry.cls) || null;
},
getEntityName: function(cls) {
var ns = this.getNamespace(),
index, name;
if (typeof cls === 'string') {
name = cls;
} else {
name = cls.$className || null;
}
if (name) {
if (ns) {
index = ns.length;
if (name.substring(0, index) !== ns) {
return name;
}
}
if (index) {
name = name.substring(index);
}
}
return name;
},
hasAssociations: function(name) {
name = name.entityName || name;
return !!this.associationEntityMap[name];
},
hasEntity: function(entity) {
var name = this.getEntityName(entity);
return !!(this.entities[name] || this.entityClasses[name]);
},
addMatrix: function(entityType, matrixName, relation, left, right) {
var me = this,
namer = me.getNamer(),
associations = me.associations,
entities = me.entities,
leftType = left.type,
rightType = right.type,
leftField = left.field || namer.apply('idField', leftType),
rightField = right.field || namer.apply('idField', rightType),
leftRole = left.role || namer.matrixRole(relation, leftType),
rightRole = right.role || namer.matrixRole(relation, rightType),
matrix, leftEntry, rightEntry;
leftEntry = entities[leftType] || (entities[leftType] = {
cls: null,
name: leftType,
associations: {}
});
rightEntry = entities[rightType] || (entities[rightType] = {
cls: null,
name: rightType,
associations: {}
});
++me.assocCount;
associations[matrixName] = matrix = new Ext.data.schema.ManyToMany({
name: matrixName,
schema: me,
definedBy: entityType,
left: {
cls: leftEntry.cls,
type: leftType,
role: leftRole,
field: leftField,
associationKey: left.associationKey
},
right: {
cls: rightEntry.cls,
type: rightType,
role: rightRole,
field: rightField,
associationKey: right.associationKey
}
});
leftEntry.associations[matrix.right.role] = matrix.right;
rightEntry.associations[matrix.left.role] = matrix.left;
if (leftEntry.cls) {
me.associationEntityMap[leftEntry.cls.entityName] = true;
}
if (rightEntry.cls) {
me.associationEntityMap[rightEntry.cls.entityName] = true;
}
me.decorateModel(matrix);
},
addReference: function(entityType, referenceField, descr, unique) {
var me = this,
namer = me.getNamer(),
entities = me.entities,
associations = me.associations,
entityName = entityType.entityName,
association = descr.association,
legacy = !!descr.legacy,
child = descr.child,
parent = descr.parent,
rightRole = descr.role,
rightType = descr.type || parent || child,
leftVal = descr.inverse,
left = Ext.isString(leftVal) ? {
role: leftVal
} : leftVal,
leftRole = left && left.role,
entry, T;
if (!rightRole) {
if (legacy) {
rightRole = namer.apply('uncapitalize', rightType);
} else {
rightRole = namer.apply('fieldRole', referenceField.name);
}
}
if (!leftRole) {
leftRole = namer.inverseFieldRole(entityName, unique, rightRole, rightType);
}
if (!association) {
if (unique) {
association = namer.oneToOne(entityType, leftRole, rightType, rightRole);
} else {
association = namer.manyToOne(entityType, leftRole, rightType, rightRole);
}
}
if (association in associations) {
Ext.Error.raise('Duplicate association: "' + association + '" declared by ' + entityName + (referenceField ? ('.' + referenceField.name) : '') + ' (collides with ' + associations[association].definedBy.entityName + ')');
}
if (referenceField && referenceField.definedBy === entities[rightType]) {
Ext.Error.raise('ForeignKey reference should not be owned by the target model');
}
entry = entities[rightType] || (entities[rightType] = {
cls: null,
name: rightType,
associations: {}
});
T = unique ? Ext.data.schema.OneToOne : Ext.data.schema.ManyToOne;
association = new T({
name: association,
owner: child ? 'left' : (parent ? 'right' : null),
definedBy: entityType,
schema: me,
field: referenceField,
nullable: referenceField ? !!referenceField.allowBlank : true,
legacy: descr.legacy,
left: {
cls: entityType,
type: entityName,
role: leftRole,
extra: left
},
right: {
cls: entry.cls,
type: rightType,
role: rightRole,
extra: descr
}
});
entityType.associations[rightRole] = association.right;
entry.associations[leftRole] = association.left;
if (referenceField) {
referenceField.reference = association.right;
entityType.references.push(referenceField);
}
++me.assocCount;
me.associationEntityMap[entityName] = true;
if (entry.cls) {
me.associationEntityMap[entry.cls.entityName] = true;
}
associations[association.name] = association;
if (association.right.cls) {
me.decorateModel(association);
}
},
privates: {
addEntity: function(entityType) {
var me = this,
entities = me.entities,
entityName = entityType.entityName,
entry = entities[entityName],
fields = entityType.fields,
associations, field, i, length, name;
if (!entry) {
entities[entityName] = entry = {
name: entityName,
associations: {}
};
} else if (entry.cls) {
Ext.Error.raise('Duplicate entity name "' + entityName + '": ' + entry.cls.$className + ' and ' + entityType.$className);
} else {
associations = entry.associations;
for (name in associations) {
associations[name].inverse.cls = entityType;
me.associationEntityMap[entityName] = true;
me.decorateModel(associations[name].association);
}
}
entry.cls = entityType;
entityType.prototype.associations = entityType.associations = entry.associations;
me.entityClasses[entityType.$className] = entry;
++me.entityCount;
for (i = 0 , length = fields.length; i < length; ++i) {
field = fields[i];
if (field.reference) {
me.addReferenceDescr(entityType, field);
}
}
},
addMatrices: function(entityType, matrices) {
var me = this,
i, length, matrixName;
if (Ext.isString(matrices)) {
me.addMatrixDescr(entityType, null, matrices);
} else if (matrices[0]) {
for (i = 0 , length = matrices.length; i < length; ++i) {
me.addMatrixDescr(entityType, null, matrices[i]);
}
} else {
for (matrixName in matrices) {
me.addMatrixDescr(entityType, matrixName, matrices[matrixName]);
}
}
},
addMatrixDescr: function(entityType, matrixName, matrixDef) {
var me = this,
entityName = entityType.entityName,
associations = me.associations,
namer = me.getNamer(),
left = matrixDef.left,
right = matrixDef.right,
last, relation;
if (Ext.isString(matrixDef)) {
if (matrixDef.charAt(0) === '#') {
left = {
type: entityName
};
right = {
type: matrixDef.substring(1)
};
}
else if (matrixDef.charAt(last = matrixDef.length - 1) === '#') {
left = {
type: matrixDef.substring(0, last)
};
right = {
type: entityName
};
}
else if (namer.apply('multiRole', entityName) < namer.apply('multiRole', matrixDef)) {
left = {
type: entityName
};
right = {
type: matrixDef
};
} else
{
left = {
type: matrixDef
};
right = {
type: entityName
};
}
} else
{
Ext.Assert.isString(matrixDef.type, 'No "type" for manyToMany in ' + entityName);
relation = matrixDef.relation;
if (left || (!right && namer.apply('multiRole', entityName) < namer.apply('multiRole', matrixDef.type))) {
if (!left || left === true) {
left = {
type: entityName
};
} else
{
left = Ext.apply({
type: entityName
}, left);
}
right = matrixDef;
} else
{
if (!right || right === true) {
right = {
type: entityName
};
} else
{
right = Ext.apply({
type: entityName
}, right);
}
left = matrixDef;
}
}
if (!matrixName) {
matrixName = namer.manyToMany(relation, left.type, right.type);
}
if (!(matrixName in associations)) {
me.addMatrix(entityType, matrixName, relation, left, right);
} else
{
var entry = associations[matrixName],
before = [
entry.kind,
entry.left.type,
entry.left.role,
entry.left.field,
entry.right.type,
entry.right.role,
entry.right.field
].join('|');
delete associations[matrixName];
me.addMatrix(entityType, matrixName, relation, left, right);
var after = associations[matrixName];
associations[matrixName] = entry;
entry.left.cls.associations[entry.right.role] = entry.right;
entry.right.cls.associations[entry.left.role] = entry.left;
--me.assocCount;
after = [
after.kind,
after.left.type,
after.left.role,
after.left.field,
after.right.type,
after.right.role,
after.right.field
].join('|');
if (before != after) {
Ext.log.warn(matrixName + '(' + entry.definedBy.entityName + '): ' + before);
Ext.log.warn(matrixName + '(' + entityName + '): ' + after);
Ext.Error.raise('Conflicting association: "' + matrixName + '" declared by ' + entityName + ' was previously declared by ' + entry.definedBy.entityName);
}
}
},
addReferenceDescr: function(entityType, referenceField) {
var me = this,
descr = referenceField.$reference;
if (Ext.isString(descr)) {
descr = {
type: descr
};
} else {
descr = Ext.apply({}, descr);
}
if (descr.legacy) {
if (descr.single) {
me.addLegacySingle(entityType, descr);
} else {
me.addLegacyHasMany(entityType, descr);
}
} else {
me.addReference(entityType, referenceField, descr, referenceField.unique);
}
},
addPending: function(name, entityType, assoc, type) {
var pending = this.pending;
if (!pending[name]) {
pending[name] = [];
}
pending[name].push([
entityType,
assoc,
type
]);
},
addLegacyBelongsTo: function(entityType, assoc) {
this.addLegacySingle(entityType, assoc);
},
addLegacyHasOne: function(entityType, assoc) {
this.addLegacySingle(entityType, assoc);
},
addLegacySingle: function(entityType, assoc) {
var foreignKey, name, referenceField;
assoc = this.constructLegacyAssociation(entityType, assoc);
assoc.single = true;
name = assoc.type;
foreignKey = assoc.foreignKey || (name.toLowerCase() + '_id');
referenceField = entityType.getField(foreignKey);
if (referenceField) {
referenceField.$reference = assoc;
}
this.addReference(entityType, referenceField, assoc, true);
},
addLegacyHasMany: function(entityType, assoc) {
var me = this,
entities = me.entities,
pending = me.pending,
associationKey = assoc.associationKey,
cls, name, referenceField, target, foreignKey, assocName;
assoc = this.constructLegacyAssociation(entityType, assoc);
name = assoc.type;
target = entities[name];
if (target && target.cls) {
assoc.type = entityType.entityName;
foreignKey = assoc.foreignKey || (assoc.type.toLowerCase() + '_id');
cls = target.cls;
referenceField = cls.getField(foreignKey);
assoc.inverse = assoc || {};
assocName = assoc.name;
if (assocName || associationKey) {
if (assocName) {
assoc.inverse.role = assocName;
}
if (associationKey) {
assoc.inverse.associationKey = associationKey;
}
}
if (referenceField) {
referenceField.$reference = assoc;
}
me.addReference(cls, referenceField, assoc, false);
} else {
if (!pending[name]) {
pending[name] = [];
}
pending[name].push([
entityType,
assoc
]);
}
},
constructLegacyAssociation: function(entityType, assoc) {
if (Ext.isString(assoc)) {
assoc = {
model: assoc
};
}
assoc.legacy = true;
assoc.type = this.getEntityName(assoc.model);
var name = assoc.associatedName || assoc.name;
if (name) {
assoc.role = name;
}
return assoc;
},
afterLegacyAssociations: function(cls) {
var pending = this.pending,
name = cls.entityName,
mine = pending[name],
i, len;
if (mine) {
for (i = 0 , len = mine.length; i < len; ++i) {
this.addLegacyHasMany.apply(this, mine[i]);
}
delete pending[name];
}
},
clear: function(clearNamespace) {
var me = this,
timer = me.timer;
delete me.setConfig;
if (timer) {
window.clearTimeout(timer);
me.timer = null;
}
me.associations = {};
me.associationEntityMap = {};
me.entities = {};
me.entityClasses = {};
me.pending = {};
me.assocCount = me.entityCount = 0;
if (clearNamespace) {
me.setNamespace(null);
}
},
constructProxy: function(Model) {
var me = this,
data = Ext.Object.chain(Model),
proxy = me.getProxy();
data.schema = me;
data.prefix = me.getUrlPrefix();
return proxy.apply(data);
},
applyDecoration: function(role) {
var me = this,
cls = role.inverse.cls,
namer = me.getNamer(),
getterName, setterName, proto;
if (cls && !role.decorated) {
role.decorated = true;
proto = cls.prototype;
if (!(getterName = role.getterName)) {
role.getterName = getterName = namer.getterName(role);
}
proto[getterName] = role.createGetter();
if (role.createSetter) {
if (!(setterName = role.setterName)) {
role.setterName = setterName = namer.setterName(role);
}
proto[setterName] = role.createSetter();
}
}
},
decorateModel: function(association) {
this.applyDecoration(association.left);
this.applyDecoration(association.right);
},
processKeyChecks: function(processAll) {
var me = this,
keyCheckQueue = me.keyCheckQueue,
timer = me.timer,
len, i, item;
if (timer) {
window.clearTimeout(timer);
me.timer = null;
}
if (!keyCheckQueue) {
return;
}
do {
keyCheckQueue = me.keyCheckQueue;
me.keyCheckQueue = [];
for (i = 0 , len = keyCheckQueue.length; i < len; ++i) {
item = keyCheckQueue[i];
item.role.checkKeyForDrop(item.record);
}
} while (processAll && me.keyCheckQueue.length);
},
queueKeyCheck: function(record, role) {
var me = this,
keyCheckQueue = me.keyCheckQueue,
timer = me.timer;
if (!keyCheckQueue) {
me.keyCheckQueue = keyCheckQueue = [];
}
keyCheckQueue.push({
record: record,
role: role
});
if (!timer) {
me.timer = timer = Ext.Function.defer(me.processKeyChecks, me.getKeyCheckDelay(), me);
}
},
rankEntities: function() {
var me = this,
entities = me.entities,
entityNames = Ext.Object.getKeys(entities),
length = entityNames.length,
entityType, i;
me.nextRank = 1;
entityNames.sort();
for (i = 0; i < length; ++i) {
entityType = entities[entityNames[i]].cls;
if (!entityType.rank) {
me.rankEntity(entityType);
}
}
me.topoStack = null;
},
rankEntity: function(entityType) {
var associations = entityType.associations,
associatedType, role, roleName;
var topoStack = this.topoStack || (this.topoStack = []),
entityName = entityType.entityName;
topoStack.push(entityName);
if (entityType.rank === 0) {
Ext.Error.raise(entityName + " has circular foreign-key references: " + topoStack.join(" --> "));
}
entityType.rank = 0;
for (roleName in associations) {
role = associations[roleName];
if (!role.left && role.association.field) {
associatedType = role.cls;
if (!associatedType.rank) {
this.rankEntity(associatedType);
}
}
}
entityType.rank = this.nextRank++;
topoStack.pop();
}
}
});
Ext.define('Ext.data.AbstractStore', {
mixins: [
'Ext.mixin.Observable',
'Ext.mixin.Factoryable'
],
requires: [
'Ext.util.Collection',
'Ext.data.schema.Schema',
'Ext.util.Filter'
],
factoryConfig: {
defaultType: 'store',
type: 'store'
},
$configPrefixed: false,
$configStrict: false,
config: {
filters: null,
autoDestroy: undefined,
storeId: null,
statefulFilters: false,
sorters: null,
remoteSort: {
lazy: true,
$value: false
},
remoteFilter: {
lazy: true,
$value: false
},
groupField: undefined,
groupDir: 'ASC',
grouper: null,
pageSize: 25
},
currentPage: 1,
loading: false,
isDestroyed: false,
isStore: true,
updating: 0,
constructor: function(config) {
var me = this,
storeId;
me.isInitializing = true;
me.mixins.observable.constructor.call(me, config);
me.isInitializing = false;
storeId = me.getStoreId();
if (!storeId && (config && config.id)) {
me.setStoreId(storeId = config.id);
}
if (storeId) {
Ext.data.StoreManager.register(me);
}
},
getCount: function() {
return this.getData().getCount();
},
rangeCached: function(start, end) {
return this.getData().getCount() >= Math.max(start, end);
},
find: function(property, value, startIndex, anyMatch, caseSensitive, exactMatch) {
var startsWith = !anyMatch,
endsWith = !!(startsWith && exactMatch);
return this.getData().findIndex(property, value, startIndex, startsWith, endsWith, !caseSensitive);
},
findRecord: function() {
var me = this,
index = me.find.apply(me, arguments);
return index !== -1 ? me.getAt(index) : null;
},
findExact: function(property, value, start) {
return this.getData().findIndexBy(function(rec) {
return rec.isEqual(rec.get(property), value);
}, this, start);
},
findBy: function(fn, scope, start) {
return this.getData().findIndexBy(fn, scope, start);
},
getAt: function(index) {
return this.getData().getAt(index) || null;
},
getRange: function(start, end,
options) {
var result = this.getData().getRange(start, Ext.isNumber(end) ? end + 1 : end);
if (options && options.callback) {
options.callback.call(options.scope || this, result, start, end, options);
}
return result;
},
getFilters: function(
autoCreate) {
var result = this.callParent();
if (!result && autoCreate !== false) {
this.setFilters([]);
result = this.callParent();
}
return result;
},
applyFilters: function(filters, filtersCollection) {
var created;
if (!filtersCollection) {
filtersCollection = this.createFiltersCollection();
created = true;
}
filtersCollection.add(filters);
if (created) {
this.onRemoteFilterSet(filtersCollection, this.getRemoteFilter());
}
return filtersCollection;
},
getSorters: function(
autoCreate) {
var result = this.callParent();
if (!result && autoCreate !== false) {
this.setSorters([]);
result = this.callParent();
}
return result;
},
applySorters: function(sorters, sortersCollection) {
var created;
if (!sortersCollection) {
sortersCollection = this.createSortersCollection();
created = true;
}
sortersCollection.add(sorters);
if (created) {
this.onRemoteSortSet(sortersCollection, this.getRemoteSort());
}
return sortersCollection;
},
filter: function(filters, value, supressEvent) {
if (Ext.isString(filters)) {
filters = {
property: filters,
value: value
};
}
this.suppressNextFilter = !!supressEvent;
this.getFilters().add(filters);
this.suppressNextFilter = false;
},
removeFilter: function(filter, supressEvent) {
var me = this,
filters = me.getFilters();
me.suppressNextFilter = !!supressEvent;
if (filter instanceof Ext.util.Filter) {
filters.remove(filter);
} else {
filters.removeByKey(filter);
}
me.suppressNextFilter = false;
},
updateRemoteSort: function(remoteSort) {
this.onRemoteSortSet(this.getSorters(false), remoteSort);
},
updateRemoteFilter: function(remoteFilter) {
this.onRemoteFilterSet(this.getFilters(false), remoteFilter);
},
addFilter: function(filters, supressEvent) {
this.suppressNextFilter = !!supressEvent;
this.getFilters().add(filters);
this.suppressNextFilter = false;
},
filterBy: function(fn, scope) {
this.getFilters().add({
filterFn: fn,
scope: scope || this
});
},
clearFilter: function(supressEvent) {
var me = this,
filters = me.getFilters(false);
if (!filters || filters.getCount() === 0) {
return;
}
me.suppressNextFilter = !!supressEvent;
filters.removeAll();
me.suppressNextFilter = false;
},
isFiltered: function() {
return this.getFilters().getCount() > 0;
},
isSorted: function() {
var sorters = this.getSorters(false);
return !!(sorters && sorters.length > 0) || this.isGrouped();
},
addFieldTransform: function(sorter) {
if (sorter.getTransform()) {
return;
}
var fieldName = sorter.getProperty(),
Model = this.getModel(),
field, sortType;
if (Model) {
field = Model.getField(fieldName);
sortType = field ? field.getSortType() : null;
}
if (sortType && sortType !== Ext.identityFn) {
sorter.setTransform(sortType);
}
},
beginUpdate: function() {
if (!this.updating++) {
this.fireEvent('beginupdate');
}
},
endUpdate: function() {
if (this.updating && !--this.updating) {
this.fireEvent('endupdate');
this.onEndUpdate();
}
},
getState: function() {
var me = this,
sorters = [],
filters = me.getFilters(),
grouper = me.getGrouper(),
filterState, hasState, result;
me.getSorters().each(function(s) {
sorters[sorters.length] = s.getState();
hasState = true;
});
if (me.statefulFilters && me.saveStatefulFilters) {
hasState = true;
filterState = [];
filters.each(function(f) {
filterState[filterState.length] = f.getState();
});
}
if (grouper) {
hasState = true;
}
if (hasState) {
result = {};
if (sorters.length) {
result.sorters = sorters;
}
if (filterState) {
result.filters = filterState;
}
if (grouper) {
result.grouper = grouper.getState();
}
}
return result;
},
applyState: function(state) {
var me = this,
stateSorters = state.sorters,
stateFilters = state.filters,
stateGrouper = state.grouper;
if (stateSorters) {
me.getSorters().replaceAll(stateSorters);
}
if (stateFilters) {
me.saveStatefulFilters = true;
me.getFilters().replaceAll(stateFilters);
}
if (stateGrouper) {
this.setGrouper(stateGrouper);
}
},
hasPendingLoad: Ext.emptyFn,
isLoaded: Ext.emptyFn,
isLoading: Ext.emptyFn,
destroy: function() {
var me = this;
me.clearListeners();
if (me.getStoreId()) {
Ext.data.StoreManager.unregister(me);
}
me.onDestroy();
me.callParent();
},
sort: function(field, direction, mode) {
var me = this;
if (arguments.length === 0) {
if (me.getRemoteSort()) {
me.attemptLoad();
} else {
me.forceLocalSort();
}
} else {
me.getSorters().addSort(field, direction, mode);
}
},
onBeforeCollectionSort: function(store, sorters) {
if (sorters) {
this.fireEvent('beforesort', this, sorters.getRange());
}
},
onSorterEndUpdate: function() {
var me = this,
sorters;
sorters = me.getSorters(false);
if (me.settingGroups || !sorters) {
return;
}
sorters = sorters.getRange();
if (sorters.length) {
if (me.getRemoteSort()) {
me.attemptLoad({
callback: function() {
me.fireEvent('sort', me, sorters);
}
});
} else {
me.fireEvent('datachanged', me);
me.fireEvent('refresh', me);
me.fireEvent('sort', me, sorters);
}
} else {
me.fireEvent('sort', me, sorters);
}
},
onFilterEndUpdate: function() {
var me = this,
suppressNext = me.suppressNextFilter;
if (me.getRemoteFilter()) {
me.getFilters().each(function(filter) {
if (filter.getInitialConfig().filterFn) {
Ext.Error.raise('Unable to use a filtering function in conjunction with remote filtering.');
}
});
me.currentPage = 1;
if (!suppressNext) {
me.attemptLoad();
}
} else if (!suppressNext) {
me.fireEvent('datachanged', me);
me.fireEvent('refresh', me);
}
if (me.trackStateChanges) {
me.saveStatefulFilters = true;
}
me.fireEvent('filterchange', me, me.getFilters().getRange());
},
updateGroupField: function(field) {
if (field) {
this.setGrouper({
property: field,
direction: this.getGroupDir()
});
} else {
this.setGrouper(null);
}
},
getGrouper: function() {
return this.getData().getGrouper();
},
group: function(grouper, direction) {
var me = this,
sorters = me.getSorters(false),
change = grouper || (sorters && sorters.length);
if (grouper && typeof grouper === 'string') {
grouper = {
property: grouper,
direction: direction || me.getGroupDir()
};
}
me.settingGroups = true;
me.getData().setGrouper(grouper);
delete me.settingGroups;
if (me.isLoadBlocked()) {
return;
}
if (change) {
if (me.getRemoteSort()) {
me.attemptLoad({
scope: me,
callback: me.fireGroupChange
});
} else {
me.fireEvent('datachanged', me);
me.fireEvent('refresh', me);
me.fireGroupChange();
}
} else
{
me.fireGroupChange();
}
},
fireGroupChange: function() {
this.fireEvent('groupchange', this, this.getGrouper());
},
clearGrouping: function() {
this.group(null);
},
getGroupField: function() {
var grouper = this.getGrouper(),
group = '';
if (grouper) {
group = grouper.getProperty();
}
return group;
},
isGrouped: function() {
return !!this.getGrouper();
},
applyGrouper: function(grouper) {
this.group(grouper);
return this.getData().getGrouper();
},
getGroups: function() {
return this.getData().getGroups();
},
onEndUpdate: Ext.emptyFn,
privates: {
loadsSynchronously: Ext.privateFn,
onRemoteFilterSet: function(filters, remoteFilter) {
if (filters) {
filters[remoteFilter ? 'on' : 'un']('endupdate', this.onFilterEndUpdate, this);
}
},
onRemoteSortSet: function(sorters, remoteSort) {
var me = this;
if (sorters) {
sorters[remoteSort ? 'on' : 'un']('endupdate', me.onSorterEndUpdate, me);
me.getData()[remoteSort ? 'un' : 'on']('beforesort', me.onBeforeCollectionSort, me);
}
}
},
deprecated: {
5: {
methods: {
destroyStore: function() {
this.destroy();
}
}
}
}
});
Ext.define('Ext.data.Error', {
isError: true,
$configPrefixed: false,
config: {
field: null,
message: ''
},
constructor: function(config) {
this.initConfig(config);
this.msg = this.message;
}
});
Ext.define('Ext.data.ErrorCollection', {
extend: 'Ext.util.MixedCollection',
alternateClassName: 'Ext.data.Errors',
requires: [
'Ext.data.Error'
],
init: function(record) {
var me = this,
fields = record.fields,
data = record.data,
before, field, item, i, len, msg, val, name;
for (i = 0 , len = fields.length; i < len; ++i) {
field = fields[i];
name = field.name;
val = data[name];
if (field.validate && !field.validate.$nullFn) {
before = me.length;
msg = field.validate(val, null, me);
if (before === me.length && msg !== true) {
me.add(name, msg);
}
}
}
return me;
},
add: function(key, value) {
var me = this,
defaultMessage = Ext.data.field.Field.defaultInvalidMessage,
obj = key,
current;
if (Ext.isString(key)) {
obj = new Ext.data.Error({
field: key,
message: value || defaultMessage
});
} else {
if (!(obj.isError)) {
obj = new Ext.data.Error({
field: obj.field || obj.name,
message: obj.error || obj.message || obj.msg || defaultMessage
});
}
key = obj.field;
}
current = me.get(key);
if (current) {
if (Ext.isArray(current)) {
current.push(obj);
return current;
}
me.removeAtKey(key);
obj = [
current,
obj
];
obj.field = key;
obj = [
obj
];
}
return me.callParent([
obj
]);
},
getKey: function(item) {
return item.field;
},
isValid: function() {
return this.length === 0;
},
getByField: function(fieldName) {
var values = this.get(fieldName);
if (values && !Ext.isArray(values)) {
values = [
values
];
}
return values || [];
}
});
Ext.define('Ext.data.operation.Operation', {
alternateClassName: 'Ext.data.Operation',
isOperation: true,
config: {
synchronous: false,
url: '',
params: undefined,
callback: undefined,
scope: undefined,
resultSet: null,
response: null,
request: null,
records: null,
id: undefined,
proxy: null,
batch: null,
recordCreator: null,
internalCallback: null,
internalScope: null
},
order: 0,
foreignKeyDirection: 1,
started: false,
running: false,
complete: false,
success: undefined,
exception: false,
error: undefined,
idPrefix: 'ext-operation-',
constructor: function(config) {
var scope = config && config.scope;
this.initConfig(config);
if (config) {
config.scope = scope;
}
if (scope) {
this.setScope(scope);
this.initialConfig.scope = scope;
}
this._internalId = Ext.id(this, this.idPrefix);
},
getAction: function() {
return this.action;
},
execute: function() {
var me = this;
delete me.error;
delete me.success;
me.complete = me.exception = false;
me.setStarted();
return me.request = me.doExecute();
},
doExecute: Ext.emptyFn,
abort: function() {
var me = this,
request = me.request;
if (me.running && request) {
me.getProxy().abort(request);
me.request = null;
}
},
process: function(resultSet, request, response, autoComplete) {
var me = this;
autoComplete = autoComplete !== false;
me.setResponse(response);
me.setResultSet(resultSet);
if (resultSet.getSuccess()) {
me.doProcess(resultSet, request, response);
me.setSuccessful(autoComplete);
} else if (autoComplete) {
me.setException(resultSet.getMessage());
}
},
_commitSetOptions: {
convert: true,
commit: true
},
doProcess: function(resultSet, request, response) {
var me = this,
commitSetOptions = me._commitSetOptions,
clientRecords = me.getRecords(),
clientLen = clientRecords.length,
clientIdProperty = clientRecords[0].clientIdProperty,
serverRecords = resultSet.getRecords(),
serverLen = serverRecords ? serverRecords.length : 0,
clientMap, serverRecord, clientRecord, i;
if (serverLen && clientIdProperty) {
clientMap = Ext.Array.toValueMap(clientRecords, 'id');
for (i = 0; i < serverLen; ++i) {
serverRecord = serverRecords[i];
clientRecord = clientMap[serverRecord[clientIdProperty]];
if (clientRecord) {
delete clientMap[clientRecord.id];
delete serverRecord[clientIdProperty];
clientRecord.set(serverRecord, commitSetOptions);
} else
{
Ext.log.warn('Ignoring server record: ' + Ext.encode(serverRecord));
}
}
for (i in clientMap) {
clientMap[i].commit();
}
} else {
for (i = 0; i < clientLen; ++i) {
clientRecord = clientRecords[i];
if (serverLen === 0 || !(serverRecord = serverRecords[i])) {
clientRecord.commit();
} else {
clientRecord.set(serverRecord, commitSetOptions);
}
}
}
},
setStarted: function() {
this.started = this.running = true;
},
setCompleted: function() {
var me = this,
proxy = me.getProxy();
me.complete = true;
me.running = false;
me.triggerCallbacks();
if (proxy) {
proxy.completeOperation(me);
}
},
setSuccessful: function(complete) {
this.success = true;
if (complete) {
this.setCompleted();
}
},
setException: function(error) {
var me = this;
me.exception = true;
me.success = me.running = false;
me.error = error;
me.setCompleted();
},
triggerCallbacks: function() {
var me = this,
callback = me.getInternalCallback();
if (callback) {
callback.call(me.getInternalScope() || me, me);
me.setInternalCallback(null);
me.setInternalScope(null);
}
if (callback = me.getCallback()) {
callback.call(me.getScope() || me, me.getRecords(), me, me.wasSuccessful());
me.setCallback(null);
me.setScope(null);
}
},
hasException: function() {
return this.exception;
},
getError: function() {
return this.error;
},
getRecords: function() {
var resultSet;
return this._records || ((resultSet = this.getResultSet()) ? resultSet.getRecords() : null);
},
isStarted: function() {
return this.started;
},
isRunning: function() {
return this.running;
},
isComplete: function() {
return this.complete;
},
wasSuccessful: function() {
return this.isComplete() && this.success === true;
},
allowWrite: function() {
return true;
}
});
Ext.define('Ext.data.operation.Create', {
extend: 'Ext.data.operation.Operation',
alias: 'data.operation.create',
action: 'create',
isCreateOperation: true,
order: 10,
config: {
recordCreator: Ext.identityFn
},
doExecute: function() {
return this.getProxy().create(this);
}
});
Ext.define('Ext.data.operation.Destroy', {
extend: 'Ext.data.operation.Operation',
alias: 'data.operation.destroy',
action: 'destroy',
isDestroyOperation: true,
order: 30,
foreignKeyDirection: -1,
doProcess: function()
{
var clientRecords = this.getRecords(),
clientLen = clientRecords.length,
i;
for (i = 0; i < clientLen; ++i) {
clientRecords[i].setErased();
}
},
doExecute: function() {
return this.getProxy().erase(this);
},
getRecordData: function(record, operation) {
var data = {},
idField = record.idField,
nameProperty = this.getNameProperty() || 'name';
data[idField[nameProperty]] = record.id;
return data;
}
});
Ext.define('Ext.data.operation.Read', {
extend: 'Ext.data.operation.Operation',
alias: 'data.operation.read',
action: 'read',
isReadOperation: true,
config: {
filters: undefined,
sorters: undefined,
grouper: undefined,
start: undefined,
limit: undefined,
page: undefined,
addRecords: false
},
doExecute: function() {
return this.getProxy().read(this);
},
doProcess: Ext.emptyFn,
allowWrite: function() {
return false;
}
});
Ext.define('Ext.data.operation.Update', {
extend: 'Ext.data.operation.Operation',
alias: 'data.operation.update',
action: 'update',
isUpdateOperation: true,
order: 20,
config: {
recordCreator: Ext.identityFn
},
doExecute: function() {
return this.getProxy().update(this);
}
});
Ext.define('Ext.data.SortTypes', {
singleton: true,
none: Ext.identityFn,
stripCommasRe: /,/g,
stripTagsRE: /<\/?[^>]+>/gi,
asText: function(s) {
return (s != null) ? String(s).replace(this.stripTagsRe, '') : '\x00';
},
asUCText: function(s) {
return (s != null) ? String(s).toUpperCase().replace(this.stripTagsRe, '') : '\x00';
},
asUCString: function(s) {
return (s != null) ? String(s).toUpperCase() : '\x00';
},
asDate: function(s) {
if (!s) {
return 0;
}
if (Ext.isDate(s)) {
return s.getTime();
}
return Date.parse(String(s));
},
asFloat: function(s) {
var val = parseFloat(String(s).replace(this.stripCommasRe, ''));
return isNaN(val) ? 0 : val;
},
asInt: function(s) {
var val = parseInt(String(s).replace(this.stripCommasRe, ''), 10);
return isNaN(val) ? 0 : val;
}
});
Ext.define('Ext.data.validator.Validator', {
mixins: [
'Ext.mixin.Factoryable'
],
alias: 'data.validator.base',
isValidator: true,
type: 'base',
statics: {
all: {},
register: function(name, cls) {
var all = this.all;
all[name.toUpperCase()] = all[name.toLowerCase()] = all[name] = cls.prototype;
}
},
onClassExtended: function(cls, data) {
if (data.type) {
Ext.data.validator.Validator.register(data.type, cls);
}
},
constructor: function(config) {
if (typeof config === 'function') {
this.fnOnly = true;
this.validate = config;
} else {
this.initConfig(config);
}
},
validate: function() {
return true;
},
clone: function() {
var me = this;
if (me.fnOnly) {
return new Ext.data.validator.Validator(me.validate);
}
return new me.self(me.getCurrentConfig());
}
}, function() {
this.register(this.prototype.type, this);
});
Ext.define('Ext.data.field.Field', {
mixins: [
'Ext.mixin.Factoryable'
],
requires: [
'Ext.data.SortTypes',
'Ext.data.validator.Validator'
],
alternateClassName: 'Ext.data.Field',
alias: 'data.field.auto',
aliasPrefix: 'data.field.',
type: 'auto',
factoryConfig: {
defaultProperty: 'name'
},
isDataField: true,
isField: true,
allowBlank: true,
allowNull: false,
critical: false,
defaultInvalidMessage: 'This field is invalid',
defaultValue: undefined,
definedBy: null,
depends: null,
dependents: null,
mapping: null,
name: null,
ordinal: undefined,
persist: null,
reference: null,
unique: false,
rank: null,
stripRe: /[\$,%]/g,
calculated: false,
evil: false,
identifier: false,
onClassExtended: function(cls, data) {
var sortType = data.sortType,
proto = cls.prototype,
superValidators = proto.validators,
validators = data.validators;
if (sortType && Ext.isString(sortType)) {
proto.sortType = Ext.data.SortTypes[sortType];
}
if (validators) {
if (!Ext.isArray(validators)) {
validators = [
validators
];
}
delete data.validators;
if (superValidators) {
validators = superValidators.concat(validators);
}
proto.validators = validators;
}
},
argumentNamesRe: /^function\s+\(\s*([^,\)\s]+)/,
calculateRe: /[^\.a-z0-9_]([a-z_][a-z_0-9]*)\.([a-z_][a-z_0-9]*)/gi,
constructor: function(config) {
var me = this,
calculateRe = me.calculateRe,
calculate, calculated, defaultValue, sortType, depends, map, match, dataProp, str, fld, validators;
if (config) {
if (Ext.isString(config)) {
me.name = config;
} else {
validators = config.validators;
if (validators) {
delete config.validators;
me.instanceValidators = validators;
}
Ext.apply(me, config);
}
}
if (!me.allowNull) {
me.allowNull = !!me.reference;
}
calculate = me.calculate;
depends = me.depends;
if (calculate) {
me.convert = me.doCalculate;
if (!depends) {
if (!(depends = calculate.$depends)) {
map = {};
str = calculate.toString();
calculate.$depends = depends = [];
match = me.argumentNamesRe.exec(str);
dataProp = match ? match[1] : 'data';
while ((match = calculateRe.exec(str))) {
if (dataProp === match[1] && !map[fld = match[2]]) {
map[fld] = 1;
depends.push(fld);
}
}
}
me.depends = depends;
}
}
defaultValue = me.defaultValue;
if (me.convert) {
me.calculated = calculated = me.convert.length > 1;
me.evil = calculated && !depends;
}
if (me.persist === null) {
me.persist = !calculate;
}
sortType = me.sortType;
if (!me.sortType) {
me.sortType = Ext.data.SortTypes.none;
} else if (Ext.isString(sortType)) {
me.sortType = Ext.data.SortTypes[sortType];
}
if (depends && typeof depends === 'string') {
me.depends = [
depends
];
}
me.cloneDefaultValue = defaultValue !== undefined && (Ext.isDate(defaultValue) || Ext.isArray(defaultValue) || Ext.isObject(defaultValue));
},
setModelValidators: function(modelValidators) {
this._validators = null;
this.modelValidators = modelValidators;
},
compileValidators: function() {
var me = this;
me._validators = [];
me.constructValidators(me.validators);
me.constructValidators(me.modelValidators);
me.constructValidators(me.instanceValidators);
},
constructValidators: function(validators) {
if (validators) {
if (!(validators instanceof Array)) {
validators = [
validators
];
}
var length = validators.length,
all = this._validators,
i, item;
for (i = 0; i < length; ++i) {
item = validators[i];
if (item.fn) {
item = item.fn;
}
all.push(Ext.Factory.dataValidator(item));
}
}
},
collate: function(value1, value2) {
var me = this,
lhs = value1,
rhs = value2;
if (me.sortType) {
lhs = me.sortType(lhs);
rhs = me.sortType(rhs);
}
return (lhs === rhs) ? 0 : ((lhs < rhs) ? -1 : 1);
},
compare: function(value1, value2) {
return (value1 === value2) ? 0 : ((value1 < value2) ? -1 : 1);
},
isEqual: function(value1, value2) {
return this.compare(value1, value2) === 0;
},
convert: null,
serialize: null,
validate: function(value, separator, errors) {
var me = this,
ret = '',
result, validator, validators, length, i;
if (!me._validators) {
me.compileValidators();
}
validators = me._validators;
for (i = 0 , length = validators.length; i < length; ++i) {
validator = validators[i];
result = validator.validate(value);
if (result !== true) {
result = result || me.defaultInvalidMessage;
if (errors) {
errors.add(me.name, result);
ret = ret || result;
} else if (separator) {
if (ret) {
ret += separator;
}
ret += result;
} else {
ret = result;
break;
}
}
}
return ret || true;
},
doCalculate: function(v, rec) {
return rec ? this.calculate(rec.data) : v;
},
getName: function() {
return this.name;
},
getAllowBlank: function() {
return this.allowBlank;
},
getAllowNull: function() {
return this.allowNull;
},
getConvert: function() {
return this.convert;
},
getDefaultValue: function() {
return this.defaultValue;
},
getDepends: function() {
return this.depends;
},
getMapping: function() {
return this.mapping;
},
hasMapping: function() {
var map = this.mapping;
return !!(map || map === 0);
},
getPersist: function() {
return this.persist;
},
getSortType: function() {
return this.sortType;
},
getType: function() {
return 'auto';
},
deprecated: {
5.1: {
methods: {
getSortDir: function() {
return this.sortDir;
}
}
}
}
});
Ext.define('Ext.data.field.Boolean', {
extend: 'Ext.data.field.Field',
alias: [
'data.field.bool',
'data.field.boolean'
],
isBooleanField: true,
trueRe: /^\s*(?:true|yes|on|1)\s*$/i,
convert: function(v) {
if (typeof v === 'boolean') {
return v;
}
if (this.allowNull && (v === undefined || v === null || v === '')) {
return null;
}
return this.trueRe.test(String(v));
},
getType: function() {
return 'bool';
}
});
Ext.define('Ext.data.field.Date', {
extend: 'Ext.data.field.Field',
alias: 'data.field.date',
sortType: 'asDate',
isDateField: true,
dateFormat: null,
dateReadFormat: null,
dateWriteFormat: null,
compare: function(lhs, rhs) {
var lhsIsDate = lhs instanceof Date,
rhsIsDate = rhs instanceof Date,
result;
if (rhsIsDate && lhsIsDate) {
result = lhs.getTime() - rhs.getTime();
if (result === 0) {
result = 0;
} else {
result = result < 0 ? -1 : 1;
}
} else if (lhsIsDate === rhsIsDate) {
result = 0;
} else {
result = lhsIsDate ? 1 : -1;
}
return result;
},
convert: function(v) {
if (!v) {
return null;
}
if (v instanceof Date) {
return v;
}
var dateFormat = this.dateReadFormat || this.dateFormat,
parsed;
if (dateFormat) {
return Ext.Date.parse(v, dateFormat);
}
parsed = Date.parse(v);
return parsed ? new Date(parsed) : null;
},
serialize: function(value) {
var result = null,
format;
if (Ext.isDate(value)) {
format = this.getDateWriteFormat();
result = format ? Ext.Date.format(value, format) : value;
}
return result;
},
getDateFormat: function() {
return this.dateFormat;
},
getDateReadFormat: function() {
return this.dateReadFormat;
},
getDateWriteFormat: function() {
var me = this;
if (me.hasOwnProperty('dateWriteFormat')) {
return me.dateWriteFormat;
}
if (me.hasOwnProperty('dateFormat')) {
return me.dateFormat;
}
return me.dateWriteFormat || me.dateFormat || 'timestamp';
},
getType: function() {
return 'date';
}
});
Ext.define('Ext.data.field.Integer', {
extend: 'Ext.data.field.Field',
alias: [
'data.field.int',
'data.field.integer'
],
isNumeric: true,
isIntegerField: true,
numericType: 'int',
convert: function(v) {
if (typeof v === 'number') {
return this.getNumber(v);
}
var empty = v === undefined || v === null || v === '',
allowNull = this.allowNull,
out;
if (empty) {
out = allowNull ? null : 0;
} else {
out = this.parse(v);
if (allowNull && isNaN(out)) {
out = null;
}
}
return out;
},
getNumber: function(v) {
return parseInt(v, 10);
},
getType: function() {
return this.numericType;
},
parse: function(v) {
return parseInt(String(v).replace(this.stripRe, ''), 10);
},
sortType: function(s) {
if (s == null) {
s = Infinity;
}
return s;
}
});
Ext.define('Ext.data.field.Number', {
extend: 'Ext.data.field.Integer',
alias: [
'data.field.float',
'data.field.number'
],
isIntegerField: false,
isNumberField: true,
numericType: 'float',
getNumber: Ext.identityFn,
parse: function(v) {
return parseFloat(String(v).replace(this.stripRe, ''));
}
});
Ext.define('Ext.data.field.String', {
extend: 'Ext.data.field.Field',
alias: 'data.field.string',
sortType: 'asUCString',
isStringField: true,
convert: function(v) {
var defaultValue = this.allowNull ? null : '';
return (v === undefined || v === null) ? defaultValue : String(v);
},
getType: function() {
return 'string';
}
});
Ext.define('Ext.data.identifier.Generator', {
'abstract': true,
mixins: [
'Ext.mixin.Factoryable'
],
alias: 'data.identifier.default',
factoryConfig: {
defaultType: 'sequential'
},
isGenerator: true,
config: {
id: null
},
constructor: function(config) {
var me = this,
cache, id;
me.initConfig(config);
id = me.getId();
if (id) {
cache = (config && config.cache) || Ext.data.identifier.Generator.all;
cache[id] = me;
}
},
privates: {
clone: function(config) {
var cfg = this.getInitialConfig();
cfg = config ? Ext.apply({}, config, cfg) : cfg;
return new this.self(cfg);
},
statics: {
all: {}
}
}
}, function() {
var Generator = this,
Factory = Ext.Factory,
factory = Factory.dataIdentifier;
Factory.dataIdentifier = function(config) {
var id = Ext.isString(config) ? config : (config && config.id),
existing = id && ((config && config.cache) || Generator.all)[id];
return existing || factory(config);
};
});
Ext.define('Ext.data.identifier.Sequential', {
extend: 'Ext.data.identifier.Generator',
alias: 'data.identifier.sequential',
config: {
increment: 1,
prefix: null,
seed: 1
},
generate: function() {
var me = this,
seed = me._seed,
prefix = me._prefix;
me._seed += me._increment;
return (prefix !== null) ? prefix + seed : seed;
}
});
Ext.define('Ext.data.Model', {
alternateClassName: 'Ext.data.Record',
requires: [
'Ext.data.ErrorCollection',
'Ext.data.operation.*',
'Ext.data.field.*',
'Ext.data.validator.Validator',
'Ext.data.schema.Schema',
'Ext.data.identifier.Generator',
'Ext.data.identifier.Sequential'
],
uses: [
'Ext.data.Validation'
],
isEntity: true,
isModel: true,
validIdRe: null,
erasing: false,
observableType: 'record',
constructor: function(data, session) {
var me = this,
cls = me.self,
identifier = cls.identifier,
Model = Ext.data.Model,
modelIdentifier = Model.identifier,
idProperty = me.idField.name,
array, id, initializeFn, internalId, len, i, fields;
me.data = me.data = data || (data = {});
me.session = session || null;
me.internalId = internalId = modelIdentifier.generate();
var dataId = data[idProperty];
if (session && !session.isSession) {
Ext.Error.raise('Bad Model constructor argument 2 - "session" is not a Session');
}
if ((array = data) instanceof Array) {
me.data = data = {};
fields = me.getFields();
len = Math.min(fields.length, array.length);
for (i = 0; i < len; ++i) {
data[fields[i].name] = array[i];
}
}
if (!(initializeFn = cls.initializeFn)) {
cls.initializeFn = initializeFn = Model.makeInitializeFn(cls);
}
if (!initializeFn.$nullFn) {
cls.initializeFn(me);
}
if (!(me.id = id = data[idProperty]) && id !== 0) {
if (dataId) {
Ext.Error.raise('The model ID configured in data ("' + dataId + '") has been rejected by the ' + me.fieldsMap[idProperty].type + ' field converter for the ' + idProperty + ' field');
}
if (session) {
identifier = session.getIdentifier(cls);
id = identifier.generate();
} else if (modelIdentifier === identifier) {
id = internalId;
} else {
id = identifier.generate();
}
data[idProperty] = me.id = id;
me.phantom = true;
}
if (session) {
session.add(me);
}
if (me.init && Ext.isFunction(me.init)) {
me.init();
}
},
editing: false,
dirty: false,
session: null,
dropped: false,
erased: false,
clientIdProperty: null,
evented: false,
phantom: false,
idProperty: 'id',
manyToMany: null,
identifier: null,
previousValues: undefined,
proxy: undefined,
schema: 'default',
versionProperty: null,
generation: 1,
validationSeparator: null,
convertOnSet: true,
beginEdit: function() {
var me = this,
modified = me.modified,
previousValues = me.previousValues;
if (!me.editing) {
me.editing = true;
me.editMemento = {
dirty: me.dirty,
data: Ext.apply({}, me.data),
generation: me.generation,
modified: modified && Ext.apply({}, modified),
previousValues: previousValues && Ext.apply({}, previousValues)
};
}
},
cancelEdit: function() {
var me = this,
editMemento = me.editMemento;
if (editMemento) {
me.editing = false;
Ext.apply(me, editMemento);
me.editMemento = null;
}
},
endEdit: function(silent, modifiedFieldNames) {
var me = this,
editMemento = me.editMemento;
if (editMemento) {
me.editing = false;
me.editMemento = null;
me.previousValues = editMemento.previousValues;
if (!silent) {
if (!modifiedFieldNames) {
modifiedFieldNames = me.getModifiedFieldNames(editMemento.data);
}
if (me.dirty || (modifiedFieldNames && modifiedFieldNames.length)) {
me.callJoined('afterEdit', [
modifiedFieldNames
]);
}
}
}
},
getField: function(name) {
return this.self.getField(name);
},
getFields: function() {
return this.self.getFields();
},
getFieldsMap: function() {
return this.fieldsMap;
},
getIdProperty: function() {
return this.idProperty;
},
getId: function() {
return this.id;
},
getObservableId: function() {
return this.internalId;
},
setId: function(id) {
this.set(this.idProperty, id);
},
getPrevious: function(fieldName) {
var previousValues = this.previousValues;
return previousValues && previousValues[fieldName];
},
isModified: function(fieldName) {
var modified = this.modified;
return !!(modified && modified.hasOwnProperty(fieldName));
},
getModified: function(fieldName) {
var out;
if (this.isModified(fieldName)) {
out = this.modified[fieldName];
}
return out;
},
get: function(fieldName) {
return this.data[fieldName];
},
_singleProp: {},
_rejectOptions: {
convert: false,
silent: true
},
set: function(fieldName, newValue, options) {
var me = this,
cls = me.self,
data = me.data,
modified = me.modified,
prevVals = me.previousValues,
session = me.session,
single = Ext.isString(fieldName),
opt = (single ? options : newValue),
convertOnSet = opt ? opt.convert !== false : me.convertOnSet,
fieldsMap = me.fieldsMap,
silent = opt && opt.silent,
commit = opt && opt.commit,
updateRefs = !(opt && opt.refs === false) && session,
dirty = !(opt && opt.dirty === false && !commit),
modifiedFieldNames = null,
currentValue, field, idChanged, key, name, oldId, comparator, dep, dependents, i,
dirtyRank = 0,
numFields, newId, rankedFields, reference, value, values;
if (single) {
values = me._singleProp;
values[fieldName] = newValue;
} else {
values = fieldName;
}
if (!(rankedFields = cls.rankedFields)) {
rankedFields = cls.rankFields();
}
numFields = rankedFields.length;
do {
for (name in values) {
value = values[name];
currentValue = data[name];
comparator = me;
field = fieldsMap[name];
if (field) {
if (convertOnSet && field.convert) {
value = field.convert(value, me);
}
comparator = field;
reference = field.reference;
} else {
reference = null;
}
if (comparator.isEqual(currentValue, value)) {
continue;
}
data[name] = value;
(modifiedFieldNames || (modifiedFieldNames = [])).push(name);
(prevVals || (me.previousValues = prevVals = {}))[name] = currentValue;
if (reference && reference.cls) {
if (updateRefs) {
session.updateReference(me, field, value, currentValue);
}
reference.onValueChange(me, session, value, currentValue);
}
i = (dependents = field && field.dependents) && dependents.length;
while (i-- > 0) {
(dep = dependents[i]).dirty = true;
dirtyRank = dirtyRank ? Math.min(dirtyRank, dep.rank) : dep.rank;
}
if (!field || field.persist) {
if (modified && modified.hasOwnProperty(name)) {
if (!dirty || comparator.isEqual(modified[name], value)) {
delete modified[name];
me.dirty = -1;
}
} else if (dirty) {
if (!modified) {
me.modified = modified = {};
}
me.dirty = true;
modified[name] = currentValue;
}
}
if (name === me.idField.name) {
idChanged = true;
oldId = currentValue;
newId = value;
}
}
if (!dirtyRank) {
break;
}
field = rankedFields[dirtyRank - 1];
field.dirty = false;
if (single) {
delete values[fieldName];
} else {
values = me._singleProp;
single = true;
}
fieldName = field.name;
values[fieldName] = data[fieldName];
convertOnSet = true;
for (; dirtyRank < numFields; ++dirtyRank) {
if (rankedFields[dirtyRank].dirty) {
break;
}
}
if (dirtyRank < numFields) {
++dirtyRank;
} else {
dirtyRank = 0;
}
} while (
1);
if (me.dirty < 0) {
me.dirty = false;
for (key in modified) {
if (modified.hasOwnProperty(key)) {
me.dirty = true;
break;
}
}
}
if (single) {
delete values[fieldName];
}
++me.generation;
if (idChanged) {
me.id = newId;
me.callJoined('onIdChanged', [
oldId,
newId
]);
}
if (commit) {
me.commit(silent, modifiedFieldNames);
} else if (!silent && !me.editing && modifiedFieldNames) {
me.callJoined('afterEdit', [
modifiedFieldNames
]);
}
return modifiedFieldNames;
},
reject: function(silent) {
var me = this,
modified = me.modified;
if (me.erased) {
Ext.Error.raise('Cannot reject once a record has been erased.');
}
if (modified) {
me.set(modified, me._rejectOptions);
}
me.dropped = false;
me.clearState();
if (!silent) {
me.callJoined('afterReject');
}
},
commit: function(silent, modifiedFieldNames) {
var me = this,
versionProperty = me.versionProperty,
data = me.data,
erased;
me.clearState();
if (versionProperty && !me.phantom && !isNaN(data[versionProperty])) {
++data[versionProperty];
}
me.phantom = false;
if (me.dropped) {
me.erased = erased = true;
}
if (!silent) {
if (erased) {
me.callJoined('afterErase');
} else {
me.callJoined('afterCommit', [
modifiedFieldNames
]);
}
}
},
clearState: function() {
var me = this;
me.dirty = me.editing = false;
me.editMemento = me.modified = null;
},
drop: function(cascade) {
var me = this,
associations = me.associations,
session = me.session,
roleName;
if (me.erased || me.dropped) {
return;
}
me.dropped = true;
if (associations && cascade !== false) {
for (roleName in associations) {
associations[roleName].onDrop(me, session);
}
}
me.callJoined('afterDrop');
if (me.phantom) {
me.setErased();
}
},
join: function(item) {
var me = this,
joined = me.joined;
if (!joined) {
joined = me.joined = [
item
];
} else if (!joined.length) {
joined[0] = item;
} else {
Ext.Array.include(joined, item);
}
if (item.isStore && !me.store) {
me.store = item;
}
},
unjoin: function(item) {
var me = this,
joined = me.joined,
len = joined && joined.length,
store = me.store,
i;
if (len === 1 && joined[0] === item) {
joined.length = 0;
} else if (len) {
Ext.Array.remove(joined, item);
}
if (store === item) {
store = null;
if (joined) {
for (i = 0 , len = joined.length; i < len; ++i) {
item = joined[i];
if (item.isStore) {
store = item;
break;
}
}
}
me.store = store;
}
},
clone: function(session) {
var me = this,
modified = me.modified,
ret = me.copy(me.id, session);
if (modified) {
ret.modified = Ext.apply({}, modified);
}
ret.dirty = me.dirty;
ret.dropped = me.dropped;
ret.phantom = me.phantom;
return ret;
},
copy: function(newId, session) {
var me = this,
data = Ext.apply({}, me.data),
idProperty = me.idProperty,
T = me.self;
if (newId || newId === 0) {
data[idProperty] = newId;
} else if (newId === null) {
delete data[idProperty];
}
return new T(data, session);
},
getProxy: function() {
return this.self.getProxy();
},
getValidation: function(refresh) {
var me = this,
ret = me.validation;
if (!ret) {
me.validation = ret = new Ext.data.Validation();
ret.attach(me);
}
if (refresh === true || (refresh !== false && ret.syncGeneration !== me.generation)) {
ret.refresh(refresh);
}
return ret;
},
validate: function() {
return new Ext.data.ErrorCollection().init(this);
},
isValid: function() {
return this.getValidation().isValid();
},
toUrl: function() {
var pieces = this.$className.split('.'),
name = pieces[pieces.length - 1].toLowerCase();
return name + '/' + this.getId();
},
erase: function(options) {
var me = this;
me.erasing = true;
me.drop();
me.erasing = false;
return me.save(options);
},
setErased: function() {
this.erased = true;
this.callJoined('afterErase');
},
getChanges: function() {
return this.getData(this._getChangesOptions);
},
getCriticalFields: function() {
var cls = this.self,
ret = cls.criticalFields;
if (!ret) {
cls.rankFields();
ret = cls.criticalFields;
}
return ret;
},
getAssociatedData: function(result, options) {
var me = this,
associations = me.associations,
deep, i, item, items, itemData, length, record, role, roleName, opts, clear, associated;
result = result || {};
me.$gathering = 1;
if (options) {
options = Ext.Object.chain(options);
}
for (roleName in associations) {
role = associations[roleName];
item = role.getAssociatedItem(me);
if (!item || item.$gathering) {
continue;
}
if (item.isStore) {
item.$gathering = 1;
items = item.getData().items;
length = items.length;
itemData = [];
for (i = 0; i < length; ++i) {
record = items[i];
deep = !record.$gathering;
record.$gathering = 1;
if (options) {
associated = options.associated;
if (associated === undefined) {
options.associated = deep;
clear = true;
} else if (!deep) {
options.associated = false;
clear = true;
}
opts = options;
} else {
opts = deep ? me._getAssociatedOptions : me._getNotAssociatedOptions;
}
itemData.push(record.getData(opts));
if (clear) {
options.associated = associated;
clear = false;
}
delete record.$gathering;
}
delete item.$gathering;
} else {
opts = options || me._getAssociatedOptions;
if (options && options.associated === undefined) {
opts.associated = true;
}
itemData = item.getData(opts);
}
result[roleName] = itemData;
}
delete me.$gathering;
return result;
},
getData: function(options) {
var me = this,
ret = {},
opts = (options === true) ? me._getAssociatedOptions : (options || ret),
data = me.data,
associated = opts.associated,
changes = opts.changes,
critical = changes && opts.critical,
content = changes ? me.modified : data,
fieldsMap = me.fieldsMap,
persist = opts.persist,
serialize = opts.serialize,
criticalFields, field, n, name, value;
if (content) {
for (name in content) {
value = data[name];
field = fieldsMap[name];
if (field) {
if (persist && !field.persist) {
continue;
}
if (serialize && field.serialize) {
value = field.serialize(value, me);
}
}
ret[name] = value;
}
}
if (critical) {
criticalFields = me.self.criticalFields || me.getCriticalFields();
for (n = criticalFields.length; n-- > 0; ) {
name = (field = criticalFields[n]).name;
if (!(name in ret)) {
value = data[name];
if (serialize && field.serialize) {
value = field.serialize(value, me);
}
ret[name] = value;
}
}
}
if (associated) {
me.getAssociatedData(ret, opts);
}
return ret;
},
getTransientFields: function() {
var cls = this.self,
ret = cls.transientFields;
if (!ret) {
cls.rankFields();
ret = cls.transientFields;
}
return ret;
},
isLoading: function() {
return !!this.loadOperation;
},
abort: function() {
var operation = this.loadOperation;
if (operation) {
operation.abort();
}
},
load: function(options) {
options = Ext.apply({}, options);
var me = this,
scope = options.scope || me,
proxy = me.getProxy(),
callback = options.callback,
operation = me.loadOperation,
id = me.getId(),
extras;
if (operation) {
extras = operation.extraCalls;
if (!extras) {
extras = operation.extraCalls = [];
}
extras.push(options);
return operation;
}
var doIdCheck = true;
if (me.phantom) {
doIdCheck = false;
}
options.id = id;
options.recordCreator = function(data, type, readOptions) {
var session = me.session;
if (readOptions) {
readOptions.recordCreator = session ? session.recordCreator : null;
}
me.set(data, me._commitOptions);
if (doIdCheck && me.getId() !== id) {
Ext.Error.raise('Invalid record id returned for ' + id + '@' + me.entityName);
}
return me;
};
options.internalCallback = function(operation) {
var success = operation.wasSuccessful() && operation.getRecords().length > 0,
op = me.loadOperation,
extras = op.extraCalls,
successFailArgs = [
me,
operation
],
callbackArgs = [
me,
operation,
success
],
i, len;
me.loadOperation = null;
if (success) {
Ext.callback(options.success, scope, successFailArgs);
} else {
Ext.callback(options.failure, scope, successFailArgs);
}
Ext.callback(callback, scope, callbackArgs);
if (extras) {
for (i = 0 , len = extras.length; i < len; ++i) {
options = extras[i];
if (success) {
Ext.callback(options.success, scope, successFailArgs);
} else {
Ext.callback(options.failure, scope, successFailArgs);
}
Ext.callback(options.callback, scope, callbackArgs);
}
}
me.callJoined('afterLoad');
};
delete options.callback;
me.loadOperation = operation = proxy.createOperation('read', options);
operation.execute();
return operation;
},
save: function(options) {
options = Ext.apply({}, options);
var me = this,
phantom = me.phantom,
dropped = me.dropped,
action = dropped ? 'destroy' : (phantom ? 'create' : 'update'),
scope = options.scope || me,
callback = options.callback,
proxy = me.getProxy(),
operation;
options.records = [
me
];
options.internalCallback = function(operation) {
var args = [
me,
operation
],
success = operation.wasSuccessful();
if (success) {
Ext.callback(options.success, scope, args);
} else {
Ext.callback(options.failure, scope, args);
}
args.push(success);
Ext.callback(callback, scope, args);
};
delete options.callback;
operation = proxy.createOperation(action, options);
if (dropped && phantom) {
operation.setResultSet(Ext.data.reader.Reader.prototype.nullResultSet);
me.setErased();
operation.setSuccessful(true);
} else {
operation.execute();
}
return operation;
},
inheritableStatics: {
addFields: function(newFields) {
this.replaceFields(newFields);
},
replaceFields: function(newFields, removeFields) {
var me = this,
proto = me.prototype,
Field = Ext.data.field.Field,
fields = me.fields,
fieldsMap = me.fieldsMap,
ordinals = me.fieldOrdinals,
field, i, idField, len, name, ordinal;
if (removeFields === true) {
fields.length = 0;
me.fieldsMap = fieldsMap = {};
me.fieldOrdinals = ordinals = {};
} else if (removeFields) {
for (i = removeFields.length; i-- > 0; ) {
name = removeFields[i];
if (name in ordinals) {
delete ordinals[name];
delete fieldsMap[name];
}
}
for (i = 0 , len = fields.length; i < len; ++i) {
name = (field = fields[i]).name;
if (name in ordinals) {
ordinals[name] = i;
} else {
fields.splice(i, 1);
--i;
--len;
}
}
}
for (i = 0 , len = newFields ? newFields.length : 0; i < len; i++) {
name = (field = newFields[i]).name;
if (!(name in ordinals)) {
ordinals[name] = ordinal = fields.length;
fields.push(field = Field.create(field));
fieldsMap[name] = field;
field.ordinal = ordinal;
field.definedBy = field.owner = this;
}
}
me.idField = proto.idField = idField = fieldsMap[proto.idProperty];
idField.allowNull = idField.critical = idField.identifier = true;
idField.defaultValue = null;
me.initializeFn = me.rankedFields = me.transientFields = me.criticalFields = null;
},
removeFields: function(removeFields) {
this.replaceFields(null, removeFields);
},
getIdFromData: function(data) {
var T = this,
idField = T.idField,
id = idField.calculated ? (new T(data)).id : data[idField.name];
return id;
},
createWithId: function(id, data, session) {
var d = data,
T = this;
if (id || id === 0) {
d = {};
if (data) {
Ext.apply(d, data);
}
d[T.idField.name] = id;
}
return new T(d, session);
},
getFields: function() {
return this.fields;
},
getFieldsMap: function() {
return this.fieldsMap;
},
getField: function(name) {
return this.fieldsMap[name] || null;
},
getProxy: function() {
var me = this,
proxy = me.proxy,
defaults;
if (!proxy) {
proxy = me.proxyConfig;
if (!proxy || !proxy.isProxy) {
if (typeof proxy === 'string') {
proxy = {
type: proxy
};
}
defaults = me.schema.constructProxy(me);
proxy = proxy ? Ext.merge(defaults, proxy) : defaults;
}
proxy = me.setProxy(proxy);
}
return proxy;
},
setProxy: function(proxy) {
var me = this,
model;
if (proxy) {
if (!proxy.isProxy) {
proxy = Ext.Factory.proxy(proxy);
} else {
model = proxy.getModel();
if (model && model !== me) {
proxy = proxy.clone();
}
}
proxy.setModel(me);
}
return (me.prototype.proxy = me.proxy = proxy);
},
load: function(id, options, session) {
var data = {},
rec;
data[this.prototype.idProperty] = id;
rec = new this(data, session);
rec.load(options);
return rec;
}
},
deprecated: {
5: {
methods: {
hasId: null,
markDirty: null,
setDirty: null,
eachStore: function(callback, scope) {
var me = this,
stores = me.stores,
len = stores.length,
i;
for (i = 0; i < len; ++i) {
callback.call(scope, stores[i]);
}
},
join: function(item) {
var me = this,
stores = me.stores,
joined = me.joined;
if (!joined) {
joined = me.joined = [
item
];
} else {
joined.push(item);
}
if (item.isStore) {
me.store = me.store || item;
if (!stores) {
stores = me.stores = [];
}
stores.push(item);
}
},
unjoin: function(item) {
var me = this,
stores = me.stores,
joined = me.joined;
if (joined.length === 1) {
joined.length = 0;
} else {
Ext.Array.remove(joined, item);
}
if (item.isStore) {
Ext.Array.remove(stores, item);
me.store = stores[0] || null;
}
}
},
properties: {
persistenceProperty: null
},
inheritableStatics: {
methods: {
setFields: null
}
}
}
},
privates: {
_commitOptions: {
commit: true
},
_getChangesOptions: {
changes: true
},
_getAssociatedOptions: {
associated: true
},
_getNotAssociatedOptions: {
associated: false
},
copyFrom: function(sourceRecord) {
var me = this,
fields = me.fields,
fieldCount = fields.length,
modifiedFieldNames = [],
field,
i = 0,
myData, sourceData,
idProperty = me.idProperty,
name, value;
if (sourceRecord) {
myData = me.data;
sourceData = sourceRecord.data;
for (; i < fieldCount; i++) {
field = fields[i];
name = field.name;
if (name !== idProperty) {
value = sourceData[name];
if (value !== undefined && !me.isEqual(myData[name], value)) {
myData[name] = value;
modifiedFieldNames.push(name);
}
}
}
if (me.phantom && !sourceRecord.phantom) {
me.beginEdit();
me.setId(sourceRecord.getId());
me.endEdit(true);
me.commit(true);
}
}
return modifiedFieldNames;
},
callJoined: function(funcName, args) {
var me = this,
joined = me.joined,
session = me.session,
i, len, fn, item;
if (!joined && !session) {
return;
}
if (args) {
args.unshift(me);
} else {
args = [
me
];
}
if (joined) {
for (i = 0 , len = joined.length; i < len; ++i) {
item = joined[i];
if (item && (fn = item[funcName])) {
fn.apply(item, args);
}
}
}
fn = session && session[funcName];
if (fn) {
fn.apply(session, args);
}
},
setSession: function(session) {
if (session) {
if (this.session) {
Ext.Error.raise('This model already belongs to a session.');
}
if (!this.id) {
Ext.Error.raise('The model must have an id to participate in a session.');
}
}
this.session = session;
if (session) {
session.add(this);
}
},
getModifiedFieldNames: function(old) {
var me = this,
data = me.data,
modified = [],
oldData = old || me.editMemento.data,
key;
for (key in data) {
if (data.hasOwnProperty(key)) {
if (!me.isEqual(data[key], oldData[key], key)) {
modified.push(key);
}
}
}
return modified;
},
isEqual: function(lhs, rhs, field) {
var f;
if (field) {
f = field.isField ? field : this.fieldsMap[field];
if (f) {
return f.compare(lhs, rhs) === 0;
}
}
if (lhs instanceof Date && rhs instanceof Date) {
return lhs.getTime() === rhs.getTime();
}
return lhs === rhs;
},
statics: {
EDIT: 'edit',
REJECT: 'reject',
COMMIT: 'commit',
rankFields: function() {
var cls = this,
prototype = cls.prototype,
fields = cls.fields,
length = fields.length,
rankedFields = [],
criticalFields = [],
transientFields = [],
evilFields, field, i;
cls.rankedFields = prototype.rankedFields = rankedFields;
cls.criticalFields = prototype.criticalFields = criticalFields;
cls.transientFields = prototype.transientFields = transientFields;
for (i = 0; i < length; ++i) {
field = fields[i];
if (field.critical) {
criticalFields.push(field);
}
if (!field.persist) {
transientFields.push(field);
}
if (field.evil) {
(evilFields || (evilFields = [])).push(field);
} else if (!field.depends) {
rankedFields.push(field);
field.rank = rankedFields.length;
}
}
for (i = 0; i < length; ++i) {
if (!(field = fields[i]).rank && !field.evil) {
cls.topoAdd(field);
}
}
if (evilFields) {
for (i = 0 , length = evilFields.length; i < length; ++i) {
rankedFields.push(field = evilFields[i]);
field.rank = rankedFields.length;
}
}
cls.topoStack = null;
return rankedFields;
},
topoAdd: function(field) {
var cls = this,
dep = field.depends,
dependsLength = dep ? dep.length : 0,
rankedFields = cls.rankedFields,
i, targetField;
var topoStack = cls.topoStack || (cls.topoStack = []);
topoStack.push(field.name);
if (field.rank === 0) {
Ext.Error.raise(cls.$className + " has circular field dependencies: " + topoStack.join(" --> "));
}
if (topoStack.length && field.evil) {
Ext.Error.raise(cls.$className + ": Field " + topoStack[topoStack.length - 1] + " cannot depend on depends-less field " + field.name);
}
field.rank = 0;
for (i = 0; i < dependsLength; ++i) {
targetField = cls.fieldsMap[dep[i]];
if (!targetField) {
Ext.Error.raise(cls.$className + ": Field " + field.name + " depends on undefined field " + dep[i]);
}
(targetField.dependents || (targetField.dependents = [])).push(field);
if (!targetField.rank) {
cls.topoAdd(targetField);
}
}
rankedFields.push(field);
field.rank = rankedFields.length;
topoStack.pop();
},
initFields: function(data, cls, proto) {
var Field = Ext.data.field.Field,
fieldDefs = data.fields,
fields = [],
fieldOrdinals = {},
fieldsMap = {},
references = [],
superFields = proto.fields,
versionProperty = data.versionProperty || proto.versionProperty,
idProperty = cls.idProperty,
idField, field, i, length, name, ordinal, reference, superIdField, superIdFieldName, idDeclared;
cls.fields = proto.fields = fields;
cls.fieldOrdinals = proto.fieldOrdinals = fieldOrdinals;
cls.fieldsMap = proto.fieldsMap = fieldsMap;
cls.references = proto.references = references;
if (superFields) {
for (i = 0 , length = superFields.length; i < length; ++i) {
fields[i] = field = Ext.Object.chain(superFields[i]);
field.dependents = null;
field.owner = cls;
fieldOrdinals[name = field.name] = i;
fieldsMap[name] = field;
field.rank = null;
if (field.generated) {
superIdField = field;
superIdFieldName = field.name;
}
}
}
if (fieldDefs) {
delete data.fields;
for (i = 0 , length = fieldDefs.length; i < length; ++i) {
field = fieldDefs[i];
reference = field.reference;
if (reference && typeof reference !== 'string') {
reference = Ext.merge({}, reference);
}
field.$reference = reference;
field = Field.create(fieldDefs[i]);
name = field.name;
ordinal = fieldOrdinals[name];
if (ordinal === undefined) {
fieldOrdinals[name] = ordinal = fields.length;
}
fieldsMap[name] = field;
fields[ordinal] = field;
field.definedBy = field.owner = cls;
field.ordinal = ordinal;
if (name === idProperty) {
idDeclared = field;
}
}
}
idField = fieldsMap[idProperty];
if (!idField) {
if (superIdField && superIdField.generated) {
ordinal = superIdField.ordinal;
} else {
ordinal = fields.length;
}
delete fieldsMap[superIdFieldName];
delete fieldOrdinals[superIdFieldName];
idField = new Field(idProperty);
fields[ordinal] = idField;
fieldOrdinals[idProperty] = ordinal;
fieldsMap[idProperty] = idField;
idField.definedBy = cls;
idField.ordinal = ordinal;
idField.generated = true;
} else if (idDeclared && superIdField && superIdField.generated) {
Ext.Array.remove(fields, superIdField);
delete fieldsMap[superIdFieldName];
delete fieldOrdinals[superIdFieldName];
fieldsMap[idProperty] = idDeclared;
for (i = 0 , length = fields.length; i < length; ++i) {
field = fields[i];
fields.ordinal = i;
fieldOrdinals[field.name] = i;
}
}
idField.allowNull = idField.critical = idField.identifier = true;
idField.defaultValue = null;
cls.idField = proto.idField = idField;
if (versionProperty) {
field = fieldsMap[versionProperty];
if (!field) {
ordinal = fields.length;
field = new Field({
name: versionProperty,
type: 'int'
});
fields[ordinal] = field;
fieldOrdinals[versionProperty] = ordinal;
fieldsMap[versionProperty] = field;
field.definedBy = cls;
field.ordinal = ordinal;
field.generated = true;
}
field.defaultValue = 1;
field.critical = true;
}
},
initValidators: function(data, cls, proto) {
var superValidators = proto.validators,
validators, field, copy, validatorDefs, i, length, fieldValidator, name, validator, item;
if (superValidators) {
validators = {};
for (field in superValidators) {
validators[field] = Ext.Array.clone(superValidators[field]);
}
}
validatorDefs = data.validators || data.validations;
if (data.validations) {
delete data.validations;
Ext.log.warn((cls.$className || 'Ext.data.Model') + ': validations has been deprecated. Please use validators instead.');
}
if (validatorDefs) {
delete data.validators;
validators = validators || {};
if (Ext.isArray(validatorDefs)) {
copy = {};
for (i = 0 , length = validatorDefs.length; i < length; ++i) {
item = validatorDefs[i];
name = item.field;
if (!copy[name]) {
copy[name] = [];
}
item = item.fn || item;
copy[name].push(item);
}
validatorDefs = copy;
}
for (name in validatorDefs) {
fieldValidator = validatorDefs[name];
if (!Ext.isArray(fieldValidator)) {
fieldValidator = [
fieldValidator
];
}
validator = validators[name];
if (validators[name]) {
Ext.Array.push(validator, fieldValidator);
} else {
validators[name] = fieldValidator;
}
}
}
if (validators) {
for (name in validators) {
field = cls.getField(name);
if (field) {
field.setModelValidators(validators[name]);
}
}
}
cls.validators = proto.validators = validators;
},
initAssociations: function(schema, data, cls) {
var associations = data.associations,
belongsTo = data.belongsTo,
hasMany = data.hasMany,
hasOne = data.hasOne,
matrices = data.manyToMany,
i, length, assoc;
if (data.belongsTo) {
Ext.log.warn('Use of "belongsTo" is obsolete' + (cls.$className ? ' in ' + cls.$className : ''));
delete data.belongsTo;
}
delete data.manyToMany;
if (matrices) {
schema.addMatrices(cls, matrices);
}
delete data.associations;
delete data.belongsTo;
delete data.hasMany;
delete data.hasOne;
if (associations) {
associations = Ext.isArray(associations) ? associations : [
associations
];
for (i = 0 , length = associations.length; i < length; ++i) {
assoc = associations[i];
switch (assoc.type) {
case 'belongsTo':
schema.addLegacyBelongsTo(cls, assoc);
break;
case 'hasMany':
schema.addLegacyHasMany(cls, assoc);
break;
case 'hasOne':
schema.addLegacyHasOne(cls, assoc);
break;
default:
Ext.Error.raise('Invalid association type: "' + assoc.type + '"');
}
}
}
if (belongsTo) {
belongsTo = Ext.isArray(belongsTo) ? belongsTo : [
belongsTo
];
for (i = 0 , length = belongsTo.length; i < length; ++i) {
schema.addLegacyBelongsTo(cls, belongsTo[i]);
}
}
if (hasMany) {
hasMany = Ext.isArray(hasMany) ? hasMany : [
hasMany
];
for (i = 0 , length = hasMany.length; i < length; ++i) {
schema.addLegacyHasMany(cls, hasMany[i]);
}
}
if (hasOne) {
hasOne = Ext.isArray(hasOne) ? hasOne : [
hasOne
];
for (i = 0 , length = hasOne.length; i < length; ++i) {
schema.addLegacyHasOne(cls, hasOne[i]);
}
}
schema.afterLegacyAssociations(cls);
},
initIdentifier: function(data, cls, proto) {
var identifier = data.identifier || data.idgen,
superIdent = proto.identifier || cls.schema._defaultIdentifier,
generatorPrefix;
if (data.idgen) {
Ext.log.warn('Ext.data.Model: idgen has been deprecated. Please use identifier instead.');
}
if (identifier) {
delete data.identifier;
delete data.idgen;
identifier = Ext.Factory.dataIdentifier(identifier);
} else if (superIdent) {
if (superIdent.clone && !superIdent.getId()) {
identifier = superIdent.clone();
} else if (superIdent.isGenerator) {
identifier = superIdent;
} else {
identifier = Ext.Factory.dataIdentifier(superIdent);
}
}
cls.identifier = proto.identifier = identifier;
if (!identifier) {
generatorPrefix = cls.entityName;
if (!generatorPrefix) {
generatorPrefix = Ext.id(null, 'extModel');
}
cls.identifier = Ext.Factory.dataIdentifier({
type: 'sequential',
prefix: generatorPrefix + '-'
});
}
},
findValidator: function(validators, name, cfg) {
var type = cfg.type || cfg,
field = validators[name],
len, i, item;
if (field) {
for (i = 0 , len = field.length; i < len; ++i) {
item = field[i];
if (item.type === type) {
return item;
}
}
}
return null;
},
makeInitializeFn: function(cls) {
var code = [
'var '
],
body = [
'\nreturn function (e) {\n var data = e.data, v;\n'
],
fieldVars = [],
work = 0,
bc, ec,
convert, expr, factory, field, fields, fs, hasDefValue, i, length;
if (!(fields = cls.rankedFields)) {
fields = cls.rankFields();
}
for (i = 0 , length = fields.length; i < length; ++i) {
field = fields[i];
fieldVars[i] = fs = 'f' + i;
convert = field.convert;
if (i) {
code.push(', \n ');
}
code.push(fs, ' = $fields[' + i + ']');
code.push(' /* ', field.name, ' */');
if ((hasDefValue = (field.defaultValue !== undefined)) || convert) {
expr = 'data["' + field.name + '"]';
++work;
bc = ec = '';
if (field.cloneDefaultValue) {
bc = 'Ext.clone(';
ec = ')';
}
body.push('\n');
if (convert && hasDefValue) {
body.push(' v = ', expr, ';\n' + ' if (v !== undefined) {\n' + ' v = ', fs, '.convert(v, e);\n' + ' }\n' + ' if (v === undefined) {\n' + ' v = ', bc, fs, '.defaultValue', ec, ';\n' + ' }\n' + ' ', expr, ' = v;');
} else if (convert) {
body.push(' v = ', fs, '.convert(', expr, ',e);\n' + ' if (v !== undefined) {\n' + ' ', expr, ' = v;\n' + ' }\n');
} else if (hasDefValue) {
body.push(' if (', expr, ' === undefined) {\n' + ' ', expr, ' = ', bc, fs, '.defaultValue', ec, ';\n' + ' }\n');
}
}
}
if (!work) {
return Ext.emptyFn;
}
code.push(';\n');
code.push.apply(code, body);
code.push('}');
code = code.join('');
factory = new Function('$fields', 'Ext', code);
return factory(fields, Ext);
}
}
}
},
function() {
var Model = this,
proto = Model.prototype,
Schema = Ext.data.schema.Schema,
defaultSchema;
Model.proxyConfig = proto.proxy;
delete proto.proxy;
Model.fields = [];
Model.fieldsMap = proto.fieldsMap = {};
Model.schema = proto.schema = Schema.get(proto.schema);
proto.idField = new Ext.data.field.Field(proto.idProperty);
Model.identifier = new Ext.data.identifier.Sequential();
Model.onExtended(function(cls, data) {
var proto = cls.prototype,
schemaName = data.schema,
superCls = proto.superclass.self,
schema, entityName, proxy;
cls.idProperty = data.idProperty || proto.idProperty;
if (schemaName) {
delete data.schema;
schema = Schema.get(schemaName);
} else if (!(schema = proto.schema)) {
schema = defaultSchema || (defaultSchema = Schema.get('default'));
}
cls.rankFields = Model.rankFields;
cls.topoAdd = Model.topoAdd;
proto.schema = cls.schema = schema;
if (!(entityName = data.entityName)) {
proto.entityName = entityName = schema.getEntityName(cls);
if (!entityName) {
if (data.associations) {
Ext.Error.raise('Anonymous entities cannot specify "associations"');
}
if (data.belongsTo) {
Ext.Error.raise('Anonymous entities cannot specify "belongsTo"');
}
if (data.hasMany) {
Ext.Error.raise('Anonymous entities cannot specify "hasMany"');
}
if (data.hasOne) {
Ext.Error.raise('Anonymous entities cannot specify "hasOne"');
}
if (data.matrices) {
Ext.Error.raise('Anonymous entities cannot specify "manyToMany"');
}
}
}
cls.entityName = entityName;
cls.fieldExtractors = {};
Model.initIdentifier(data, cls, proto);
Model.initFields(data, cls, proto);
Model.initValidators(data, cls, proto);
cls.fields.items = cls.fields;
if (entityName) {
schema.addEntity(cls);
Model.initAssociations(schema, data, cls);
}
proxy = data.proxy;
if (proxy) {
delete data.proxy;
} else if (superCls !== Model) {
proxy = superCls.proxyConfig || superCls.proxy;
}
cls.proxyConfig = proxy;
});
});
Ext.define('Ext.data.ResultSet', {
isResultSet: true,
$configPrefixed: false,
config: {
loaded: true,
count: null,
total: null,
success: false,
records: null,
message: null
},
constructor: function(config) {
this.initConfig(config);
},
getCount: function() {
var count = this.callParent(),
records;
if (!count) {
records = this.getRecords();
if (records) {
count = records.length;
}
}
return count;
}
});
Ext.define('Ext.data.reader.Reader', {
alternateClassName: [
'Ext.data.Reader',
'Ext.data.DataReader'
],
requires: [
'Ext.data.ResultSet',
'Ext.XTemplate',
'Ext.util.LruCache'
],
mixins: [
'Ext.mixin.Observable',
'Ext.mixin.Factoryable'
],
alias: 'reader.base',
factoryConfig: {
defaultType: null
},
config: {
totalProperty: 'total',
successProperty: 'success',
rootProperty: '',
messageProperty: '',
typeProperty: '',
implicitIncludes: true,
readRecordsOnFailure: true,
model: null,
proxy: null,
transform: null,
keepRawData: true
},
isReader: true,
constructor: function(config) {
if (config && config.hasOwnProperty('root')) {
config = Ext.apply({}, config);
config.rootProperty = config.root;
delete config.root;
Ext.log.error('Ext.data.reader.Reader: Using the deprecated "root" configuration. Use "rootProperty" instead.');
}
var me = this;
me.duringInit = 1;
me.mixins.observable.constructor.call(me, config);
--me.duringInit;
me.buildExtractors();
},
applyModel: function(model) {
return Ext.data.schema.Schema.lookupEntity(model);
},
applyTransform: function(transform) {
if (transform) {
if (Ext.isFunction(transform)) {
transform = {
fn: transform
};
}
return transform.fn.bind(transform.scope || this);
}
return transform;
},
forceBuildExtractors: function() {
if (!this.duringInit) {
this.buildExtractors(true);
}
},
updateTotalProperty: function() {
this.forceBuildExtractors();
},
updateMessageProperty: function() {
this.forceBuildExtractors();
},
updateSuccessProperty: function() {
this.forceBuildExtractors();
},
read: function(response, readOptions) {
var data, result;
if (response) {
if (response.responseText) {
result = this.getResponseData(response);
if (result && result.__$isError) {
return new Ext.data.ResultSet({
total: 0,
count: 0,
records: [],
success: false,
message: result.msg
});
} else {
data = this.readRecords(result, readOptions);
}
} else {
data = this.readRecords(response, readOptions);
}
}
return data || this.nullResultSet;
},
getNullResultSet: function() {
return this.nullResultSet;
},
createReadError: function(msg) {
return {
__$isError: true,
msg: msg
};
},
readRecords: function(data, readOptions,
internalReadOptions) {
var me = this,
recordsOnly = internalReadOptions && internalReadOptions.recordsOnly,
asRoot = internalReadOptions && internalReadOptions.asRoot,
success, recordCount, records, root, total, value, message, transform;
transform = this.getTransform();
if (transform) {
data = transform(data);
}
me.buildExtractors();
if (me.getKeepRawData()) {
me.rawData = data;
}
data = me.getData(data);
success = true;
recordCount = 0;
records = [];
if (me.getSuccessProperty()) {
value = me.getSuccess(data);
if (value === false || value === 'false') {
success = false;
}
}
if (me.getMessageProperty()) {
message = me.getMessage(data);
}
if (success || me.getReadRecordsOnFailure()) {
root = (asRoot || Ext.isArray(data)) ? data : me.getRoot(data);
if (root) {
total = root.length;
}
if (me.getTotalProperty()) {
value = parseInt(me.getTotal(data), 10);
if (!isNaN(value)) {
total = value;
}
}
if (root) {
records = me.extractData(root, readOptions);
recordCount = records.length;
}
}
return recordsOnly ? records : new Ext.data.ResultSet({
total: total || recordCount,
count: recordCount,
records: records,
success: success,
message: message
});
},
extractData: function(root, readOptions) {
var me = this,
entityType = readOptions && readOptions.model ? Ext.data.schema.Schema.lookupEntity(readOptions.model) : me.getModel(),
schema = entityType.schema,
includes = schema.hasAssociations(entityType) && me.getImplicitIncludes(),
fieldExtractorInfo = me.getFieldExtractorInfo(entityType.fieldExtractors),
length = root.length,
records = new Array(length),
typeProperty = me.getTypeProperty(),
reader, node, nodeType, record, i;
if (!length && Ext.isObject(root)) {
root = [
root
];
length = 1;
}
for (i = 0; i < length; i++) {
record = root[i];
if (!record.isModel) {
node = record;
if (typeProperty && (nodeType = me.getChildType(schema, node, typeProperty))) {
reader = nodeType.getProxy().getReader();
record = reader.extractRecord(node, readOptions, nodeType, schema.hasAssociations(nodeType) && reader.getImplicitIncludes(), reader.getFieldExtractorInfo(nodeType.fieldExtractors));
} else {
record = me.extractRecord(node, readOptions, entityType, includes, fieldExtractorInfo);
}
if (record.isModel && record.isNode) {
record.raw = node;
}
}
if (record.onLoad) {
record.onLoad();
}
records[i] = record;
}
return records;
},
getChildType: function(schema, rawNode, typeProperty) {
var namespace;
switch (typeof typeProperty) {
case 'string':
return schema.getEntity(rawNode[typeProperty]);
case 'object':
namespace = typeProperty.namespace;
return schema.getEntity((namespace ? namespace + '.' : '') + rawNode[typeProperty.name]);
case 'function':
return schema.getEntity(typeProperty(rawNode));
}
},
extractRecordData: function(node, readOptions) {
var entityType = readOptions && readOptions.model ? Ext.data.schema.Schema.lookupEntity(readOptions.model) : this.getModel(),
fieldExtractorInfo = this.getFieldExtractorInfo(entityType.fieldExtractors);
return this.extractRecord(node, readOptions, entityType, false, fieldExtractorInfo);
},
extractRecord: function(node, readOptions, entityType, includes, fieldExtractorInfo) {
var me = this,
creatorFn = (readOptions && readOptions.recordCreator) || me.defaultRecordCreator,
modelData, record;
modelData = me.extractModelData(node, fieldExtractorInfo);
record = creatorFn.call(me, modelData, entityType || me.getModel(), readOptions);
if (includes && record.isModel) {
me.readAssociated(record, node, readOptions);
}
return record;
},
getFieldExtractorInfo: function(extractors) {
if (!extractors) {
return;
}
var type = this.$className,
extractor = extractors[type];
if (extractor === undefined) {
extractors[type] = extractor = this.buildFieldExtractors();
}
return extractor;
},
buildFieldExtractors: function() {
var fields = this.getFields(),
len = fields.length,
buffer = [],
extractors = [],
out = null,
cnt = 0,
field, name, i, extractor;
for (i = 0; i < len; ++i) {
field = fields[i];
extractor = this.createFieldAccessor(field);
if (extractor) {
name = field.name;
buffer.push('val = extractors[' + cnt + '](raw); if (val !== undefined) { data[\'' + name + '\'] = val; }');
extractors.push(extractor);
++cnt;
}
}
if (buffer.length) {
out = {
extractors: extractors,
fn: new Function('raw', 'data', 'extractors', 'var val;' + buffer.join(''))
};
}
return out;
},
defaultRecordCreator: function(data, Model) {
var record = new Model(data);
record.phantom = false;
return record;
},
getModelData: function(raw) {
return {};
},
extractModelData: function(raw, fieldExtractorInfo) {
var data = this.getModelData(raw),
fn;
if (fieldExtractorInfo) {
fn = fieldExtractorInfo.fn;
fn(raw, data, fieldExtractorInfo.extractors);
}
return data;
},
readAssociated: function(record, data, readOptions) {
var roles = record.associations,
key, role;
for (key in roles) {
if (roles.hasOwnProperty(key)) {
role = roles[key];
if (role.cls) {
role.read(record, data, this, readOptions);
}
}
}
},
getFields: function() {
return this.getModel().fields;
},
getData: Ext.identityFn,
getRoot: Ext.identityFn,
getResponseData: function(response) {
Ext.Error.raise("getResponseData must be implemented in the Ext.data.reader.Reader subclass");
},
onMetaChange: function(meta) {
var me = this,
fields = meta.fields,
model, newModel, clientIdProperty, proxy;
me.metaData = meta;
if (meta.root) {
me.setRootProperty(meta.root);
}
if (meta.totalProperty) {
me.setTotalProperty(meta.totalProperty);
}
if (meta.successProperty) {
me.setSuccessProperty(meta.successProperty);
}
if (meta.messageProperty) {
me.setMessageProperty(meta.messageProperty);
}
clientIdProperty = meta.clientIdProperty;
if (fields) {
newModel = Ext.define(null, {
extend: 'Ext.data.Model',
fields: fields,
clientIdProperty: clientIdProperty
});
me.setModel(newModel);
proxy = me.getProxy();
if (proxy) {
proxy.setModel(newModel);
}
} else if (clientIdProperty) {
model = me.getModel();
if (model) {
model.self.prototype.clientIdProperty = clientIdProperty;
}
}
},
buildExtractors: function(force) {
var me = this,
totalProp, successProp, messageProp;
if (force || !me.hasExtractors) {
totalProp = me.getTotalProperty();
successProp = me.getSuccessProperty();
messageProp = me.getMessageProperty();
if (totalProp) {
me.getTotal = me.getAccessor(totalProp);
}
if (successProp) {
me.getSuccess = me.getAccessor(successProp);
}
if (messageProp) {
me.getMessage = me.getAccessor(messageProp);
}
me.hasExtractors = true;
return true;
}
},
getAccessor: function(prop) {
var me = this,
cache = me.extractorCache,
ret, key;
if (typeof prop === 'string') {
key = me.getAccessorKey(prop);
ret = cache.get(key);
if (!ret) {
ret = me.createAccessor(prop);
cache.add(key, ret);
}
} else {
ret = me.createAccessor(prop);
}
return ret;
},
getAccessorKey: function(prop) {
return this.$className + prop;
},
createAccessor: Ext.emptyFn,
createFieldAccessor: Ext.emptyFn,
destroy: function() {
var me = this;
me.model = me.getTotal = me.getSuccess = me.getMessage = me.rawData = null;
},
privates: {
copyFrom: function(reader) {
var me = this;
reader.buildExtractors();
me.getTotal = reader.getTotal;
me.getSuccess = reader.getSuccess;
me.getMessage = reader.getMessage;
++me.duringInit;
me.setConfig(reader.getConfig());
--me.duringInit;
me.hasExtractors = true;
}
}
}, function(Cls) {
var proto = Cls.prototype;
Ext.apply(proto, {
nullResultSet: new Ext.data.ResultSet({
total: 0,
count: 0,
records: [],
success: true,
message: ''
})
});
proto.extractorCache = new Ext.util.LruCache();
});
Ext.define('Ext.data.writer.Writer', {
mixins: [
'Ext.mixin.Factoryable'
],
alias: 'writer.base',
factoryConfig: {
defaultType: null
},
alternateClassName: [
'Ext.data.DataWriter',
'Ext.data.Writer'
],
config: {
clientIdProperty: null,
allDataOptions: {
persist: true
},
partialDataOptions: {
changes: true,
critical: true
},
writeAllFields: false,
dateFormat: null,
nameProperty: 'name',
writeRecordId: true,
transform: null
},
isWriter: true,
constructor: function(config) {
this.initConfig(config);
},
applyTransform: function(transform) {
if (transform) {
if (Ext.isFunction(transform)) {
transform = {
fn: transform
};
}
return transform.fn.bind(transform.scope || this);
}
return transform;
},
write: function(request) {
var operation = request.getOperation(),
records = operation.getRecords() || [],
len = records.length,
data = [],
i;
for (i = 0; i < len; i++) {
data.push(this.getRecordData(records[i], operation));
}
return this.writeRecords(request, data);
},
writeRecords: Ext.emptyFn,
getRecordData: function(record, operation) {
var me = this,
nameProperty = me.getNameProperty(),
mapping = nameProperty !== 'name',
idField = record.self.idField,
key = idField[nameProperty] || idField.name,
value = record.id,
writeAll = me.getWriteAllFields(),
ret, dateFormat, phantom, options, clientIdProperty, fieldsMap, data, field;
if (idField.serialize) {
value = idField.serialize(value);
}
if (!writeAll && operation && operation.isDestroyOperation) {
ret = {};
ret[key] = value;
} else {
dateFormat = me.getDateFormat();
phantom = record.phantom;
options = (phantom || writeAll) ? me.getAllDataOptions() : me.getPartialDataOptions();
clientIdProperty = phantom && me.getClientIdProperty();
fieldsMap = record.getFieldsMap();
options.serialize = false;
data = record.getData(options);
ret = mapping ? {} : data;
if (clientIdProperty) {
ret[clientIdProperty] = value;
delete data[key];
}
else if (!me.getWriteRecordId()) {
delete data[key];
}
for (key in data) {
value = data[key];
if (!(field = fieldsMap[key])) {
if (mapping) {
ret[key] = value;
}
} else {
if (field.isDateField && dateFormat && Ext.isDate(value)) {
value = Ext.Date.format(value, dateFormat);
} else if (field.serialize) {
value = field.serialize(value, record);
}
if (mapping) {
key = field[nameProperty] || key;
}
ret[key] = value;
}
}
}
return ret;
}
});
Ext.define('Ext.data.proxy.Proxy', {
mixins: [
'Ext.mixin.Factoryable',
'Ext.mixin.Observable'
],
$configPrefixed: false,
alias: 'proxy.proxy',
alternateClassName: [
'Ext.data.DataProxy',
'Ext.data.Proxy'
],
requires: [
'Ext.data.schema.Schema',
'Ext.data.reader.Reader',
'Ext.data.writer.Writer'
],
uses: [
'Ext.data.Batch',
'Ext.data.operation.*',
'Ext.data.Model'
],
config: {
batchOrder: 'create,update,destroy',
batchActions: true,
model: undefined,
reader: {
type: 'json'
},
writer: {
type: 'json'
}
},
isProxy: true,
isSynchronous: false,
constructor: function(config) {
this.mixins.observable.constructor.call(this, config);
this.pendingOperations = {};
},
applyModel: function(model) {
return Ext.data.schema.Schema.lookupEntity(model);
},
updateModel: function(model) {
if (model) {
var reader = this.getReader();
if (reader && !reader.getModel()) {
reader.setModel(model);
}
}
},
applyReader: function(reader) {
return Ext.Factory.reader(reader);
},
updateReader: function(reader) {
if (reader) {
var me = this,
model = me.getModel();
if (!model) {
model = reader.getModel();
if (model) {
me.setModel(model);
}
} else {
reader.setModel(model);
}
if (reader.onMetaChange) {
reader.onMetaChange = Ext.Function.createSequence(reader.onMetaChange, me.onMetaChange, me);
}
}
},
applyWriter: function(writer) {
var reader = this.getReader();
writer = Ext.Factory.writer(writer);
if (writer.getRecord && !writer.getRecord() && reader && reader.getRecord) {
reader = reader.getRecord();
if (reader) {
writer.setRecord(reader);
}
}
return writer;
},
abort: Ext.emptyFn,
onMetaChange: function(meta) {
this.fireEvent('metachange', this, meta);
},
create: Ext.emptyFn,
read: Ext.emptyFn,
update: Ext.emptyFn,
erase: Ext.emptyFn,
batch: function(options,
listeners) {
var me = this,
useBatch = me.getBatchActions(),
batch, records, actions, aLen, action, a, r, rLen, record;
if (options.operations === undefined) {
options = {
operations: options,
listeners: listeners
};
}
if (options.batch) {
if (Ext.isDefined(options.batch.runOperation)) {
batch = Ext.applyIf(options.batch, {
proxy: me,
listeners: {}
});
}
} else {
options.batch = {
proxy: me,
listeners: options.listeners || {}
};
}
if (!batch) {
batch = new Ext.data.Batch(options.batch);
}
batch.on('complete', Ext.bind(me.onBatchComplete, me, [
options
], 0));
actions = me.getBatchOrder().split(',');
aLen = actions.length;
for (a = 0; a < aLen; a++) {
action = actions[a];
records = options.operations[action];
if (records) {
if (useBatch) {
batch.add(me.createOperation(action, {
records: records,
params: options.params
}));
} else {
rLen = records.length;
for (r = 0; r < rLen; r++) {
record = records[r];
batch.add(me.createOperation(action, {
records: [
record
],
params: options.params
}));
}
}
}
}
batch.start();
return batch;
},
onBatchComplete: function(batchOptions, batch) {
var scope = batchOptions.scope || this;
if (batch.hasException()) {
if (Ext.isFunction(batchOptions.failure)) {
Ext.callback(batchOptions.failure, scope, [
batch,
batchOptions
]);
}
} else if (Ext.isFunction(batchOptions.success)) {
Ext.callback(batchOptions.success, scope, [
batch,
batchOptions
]);
}
if (Ext.isFunction(batchOptions.callback)) {
Ext.callback(batchOptions.callback, scope, [
batch,
batchOptions
]);
}
},
createOperation: function(action, config) {
var operation = Ext.createByAlias('data.operation.' + action, config);
operation.setProxy(this);
this.pendingOperations[operation._internalId] = operation;
return operation;
},
completeOperation: function(operation) {
delete this.pendingOperations[operation._internalId];
},
clone: function() {
return new this.self(this.getInitialConfig());
},
destroy: function() {
var ops = this.pendingOperations,
opId, op;
for (opId in ops) {
op = ops[opId];
if (op && op.isRunning()) {
op.abort();
}
}
this.pendingOperations = null;
}
});
Ext.define('Ext.data.proxy.Client', {
extend: 'Ext.data.proxy.Proxy',
alternateClassName: 'Ext.data.ClientProxy',
isSynchronous: true,
clear: function() {
Ext.Error.raise("The Ext.data.proxy.Client subclass that you are using has not defined a 'clear' function. See src/data/ClientProxy.js for details.");
}
});
Ext.define('Ext.data.proxy.Memory', {
extend: 'Ext.data.proxy.Client',
alias: 'proxy.memory',
alternateClassName: 'Ext.data.MemoryProxy',
isMemoryProxy: true,
config: {
enablePaging: false,
data: {
$value: null,
merge: function(newValue, currentValue, target, mixinClass) {
if (Ext.isArray(newValue)) {
return Ext.Array.clone(newValue);
} else {
return Ext.clone(newValue);
}
}
}
},
finishOperation: function(operation) {
var i = 0,
recs = operation.getRecords(),
len = recs.length;
for (i; i < len; i++) {
recs[i].commit();
}
operation.setSuccessful(true);
},
create: function(operation) {
this.finishOperation(operation);
},
update: function(operation) {
this.finishOperation(operation);
},
erase: function(operation) {
this.finishOperation(operation);
},
read: function(operation) {
var me = this,
resultSet = me.getReader().read(me.getData()),
records = resultSet.getRecords(),
sorters = operation.getSorters(),
grouper = operation.getGrouper(),
filters = operation.getFilters(),
start = operation.getStart(),
limit = operation.getLimit();
if (operation.process(resultSet, null, null, false) !== false) {
if (filters && filters.length) {
resultSet.setRecords(records = Ext.Array.filter(records, Ext.util.Filter.createFilterFn(filters)));
resultSet.setTotal(records.length);
}
if (grouper) {
sorters = sorters ? sorters.concat(grouper) : sorters;
}
if (sorters && sorters.length) {
resultSet.setRecords(records = Ext.Array.sort(records, Ext.util.Sortable.createComparator(sorters)));
}
if (me.getEnablePaging() && start !== undefined && limit !== undefined) {
if (start >= resultSet.getTotal()) {
resultSet.setConfig({
success: false,
records: [],
total: 0
});
} else
{
resultSet.setRecords(Ext.Array.slice(records, start, start + limit));
}
}
operation.setCompleted();
}
},
clear: Ext.emptyFn
});
Ext.define('Ext.data.ProxyStore', {
extend: 'Ext.data.AbstractStore',
requires: [
'Ext.data.Model',
'Ext.data.proxy.Proxy',
'Ext.data.proxy.Memory',
'Ext.data.operation.*'
],
config: {
model: undefined,
fields: null,
proxy: undefined,
autoLoad: undefined,
autoSync: false,
batchUpdateMode: 'operation',
sortOnLoad: true,
trackRemoved: true,
autoLoadDelay: 1
},
onClassExtended: function(cls, data, hooks) {
var model = data.model,
onBeforeClassCreated;
if (typeof model === 'string') {
onBeforeClassCreated = hooks.onBeforeCreated;
hooks.onBeforeCreated = function() {
var me = this,
args = arguments;
Ext.require(model, function() {
onBeforeClassCreated.apply(me, args);
});
};
}
},
implicitModel: false,
blockLoadCounter: 0,
loadsWhileBlocked: 0,
autoSyncSuspended: 0,
constructor: function(config) {
var me = this;
var configModel = me.model;
me.removed = [];
me.blockLoad();
me.callParent(arguments);
me.unblockLoad();
if (!me.getModel() && me.useModelWarning !== false && me.getStoreId() !== 'ext-empty-store') {
var logMsg = [
Ext.getClassName(me) || 'Store',
' created with no model.'
];
if (typeof configModel === 'string') {
logMsg.push(" The name '", configModel, "'", ' does not correspond to a valid model.');
}
Ext.log.warn(logMsg.join(''));
}
},
updateAutoLoad: function(autoLoad) {
var me = this,
task;
me.getData();
if (autoLoad) {
task = me.loadTask || (me.loadTask = new Ext.util.DelayedTask(null, null, null, null, false));
task.delay(me.autoLoadDelay, me.attemptLoad, me, Ext.isObject(autoLoad) ? [
autoLoad
] : undefined);
}
},
getTotalCount: function() {
return this.totalCount || 0;
},
applyFields: function(fields) {
var me = this,
model, proxy;
if (fields) {
me.implicitModel = true;
me.setModel(model = Ext.define(null, {
extend: 'Ext.data.Model',
fields: fields,
proxy: (proxy = me.getProxy())
}));
if (proxy && !proxy.getModel()) {
proxy.setModel(model);
}
}
},
applyModel: function(model) {
if (model) {
model = Ext.data.schema.Schema.lookupEntity(model);
} else
{
this.getFields();
model = this.getModel();
}
return model;
},
applyProxy: function(proxy) {
var model = this.getModel();
if (proxy !== null) {
if (proxy) {
if (proxy.isProxy) {
proxy.setModel(model);
} else {
if (Ext.isString(proxy)) {
proxy = {
type: proxy,
model: model
};
} else if (!proxy.model) {
proxy = Ext.apply({
model: model
}, proxy);
}
proxy = Ext.createByAlias('proxy.' + proxy.type, proxy);
proxy.autoCreated = true;
}
} else if (model) {
proxy = model.getProxy();
}
if (!proxy) {
proxy = Ext.createByAlias('proxy.memory');
proxy.autoCreated = true;
}
}
return proxy;
},
applyState: function(state) {
var me = this,
doLoad = me.getAutoLoad() || me.isLoaded();
me.blockLoad();
me.callParent([
state
]);
me.unblockLoad(doLoad);
},
updateProxy: function(proxy, oldProxy) {
this.proxyListeners = Ext.destroy(this.proxyListeners);
},
updateTrackRemoved: function(track) {
this.cleanRemoved();
this.removed = track ? [] : null;
},
onMetaChange: function(proxy, meta) {
this.fireEvent('metachange', this, meta);
},
create: function(data, options) {
var me = this,
Model = me.getModel(),
instance = new Model(data),
operation;
options = Ext.apply({}, options);
if (!options.records) {
options.records = [
instance
];
}
options.internalScope = me;
options.internalCallback = me.onProxyWrite;
operation = me.createOperation('create', options);
return operation.execute();
},
read: function() {
return this.load.apply(this, arguments);
},
update: function(options) {
var me = this,
operation;
options = Ext.apply({}, options);
if (!options.records) {
options.records = me.getUpdatedRecords();
}
options.internalScope = me;
options.internalCallback = me.onProxyWrite;
operation = me.createOperation('update', options);
return operation.execute();
},
onProxyWrite: function(operation) {
var me = this,
success = operation.wasSuccessful(),
records = operation.getRecords();
switch (operation.getAction()) {
case 'create':
me.onCreateRecords(records, operation, success);
break;
case 'update':
me.onUpdateRecords(records, operation, success);
break;
case 'destroy':
me.onDestroyRecords(records, operation, success);
break;
}
if (success) {
me.fireEvent('write', me, operation);
me.fireEvent('datachanged', me);
}
},
onCreateRecords: Ext.emptyFn,
onUpdateRecords: Ext.emptyFn,
onDestroyRecords: function(records, operation, success) {
if (success) {
this.cleanRemoved();
}
},
erase: function(options) {
var me = this,
operation;
options = Ext.apply({}, options);
if (!options.records) {
options.records = me.getRemovedRecords();
}
options.internalScope = me;
options.internalCallback = me.onProxyWrite;
operation = me.createOperation('destroy', options);
return operation.execute();
},
onBatchOperationComplete: function(batch, operation) {
return this.onProxyWrite(operation);
},
onBatchComplete: function(batch, operation) {
var me = this,
operations = batch.operations,
length = operations.length,
i;
if (me.batchUpdateMode !== 'operation') {
me.suspendEvents();
for (i = 0; i < length; i++) {
me.onProxyWrite(operations[i]);
}
me.resumeEvents();
}
me.isSyncing = false;
me.fireEvent('datachanged', me);
},
onBatchException: function(batch, operation) {},
filterNew: function(item) {
return item.phantom === true && item.isValid();
},
getNewRecords: function() {
return [];
},
getUpdatedRecords: function() {
return [];
},
getModifiedRecords: function() {
return [].concat(this.getNewRecords(), this.getUpdatedRecords());
},
filterUpdated: function(item) {
return item.dirty === true && item.phantom !== true && item.isValid();
},
getRemovedRecords: function() {
return this.removed;
},
sync: function(options) {
var me = this,
operations = {},
toCreate = me.getNewRecords(),
toUpdate = me.getUpdatedRecords(),
toDestroy = me.getRemovedRecords(),
needsSync = false;
if (me.isSyncing) {
Ext.log.warn('Sync called while a sync operation is in progress. Consider configuring autoSync as false.');
}
me.needsSync = false;
if (toCreate.length > 0) {
operations.create = toCreate;
needsSync = true;
}
if (toUpdate.length > 0) {
operations.update = toUpdate;
needsSync = true;
}
if (toDestroy.length > 0) {
operations.destroy = toDestroy;
needsSync = true;
}
if (needsSync && me.fireEvent('beforesync', operations) !== false) {
me.isSyncing = true;
options = options || {};
me.proxy.batch(Ext.apply(options, {
operations: operations,
listeners: me.getBatchListeners()
}));
}
return me;
},
getBatchListeners: function() {
var me = this,
listeners = {
scope: me,
exception: me.onBatchException,
complete: me.onBatchComplete
};
if (me.batchUpdateMode === 'operation') {
listeners.operationcomplete = me.onBatchOperationComplete;
}
return listeners;
},
save: function() {
return this.sync.apply(this, arguments);
},
load: function(options) {
if (this.isLoadBlocked()) {
return;
}
var me = this,
operation = {
internalScope: me,
internalCallback: me.onProxyLoad
},
filters, sorters;
if (me.getRemoteFilter()) {
filters = me.getFilters(false);
if (filters && filters.getCount()) {
operation.filters = filters.getRange();
}
}
if (me.getRemoteSort()) {
sorters = me.getSorters(false);
if (sorters && sorters.getCount()) {
operation.sorters = sorters.getRange();
}
me.fireEvent('beforesort', me, operation.sorters);
}
Ext.apply(operation, options);
operation.scope = operation.scope || me;
me.lastOptions = operation;
operation = me.createOperation('read', operation);
if (me.fireEvent('beforeload', me, operation) !== false) {
me.onBeforeLoad(operation);
me.loading = true;
me.clearLoadTask();
operation.execute();
}
return me;
},
reload: function(options) {
var o = Ext.apply({}, options, this.lastOptions);
return this.load(o);
},
onEndUpdate: function() {
var me = this;
if (me.needsSync && me.autoSync && !me.autoSyncSuspended) {
me.sync();
}
},
afterReject: function(record) {
var me = this;
if (me.contains(record)) {
me.onUpdate(record, Ext.data.Model.REJECT, null);
me.fireEvent('update', me, record, Ext.data.Model.REJECT, null);
}
},
afterCommit: function(record, modifiedFieldNames) {
var me = this;
if (!modifiedFieldNames) {
modifiedFieldNames = null;
}
if (me.contains(record)) {
me.onUpdate(record, Ext.data.Model.COMMIT, modifiedFieldNames);
me.fireEvent('update', me, record, Ext.data.Model.COMMIT, modifiedFieldNames);
}
},
afterErase: function(record) {
this.onErase(record);
},
onErase: Ext.emptyFn,
onUpdate: Ext.emptyFn,
onDestroy: function() {
var me = this,
proxy = me.getProxy();
me.blockLoad();
me.clearData();
me.setProxy(null);
if (proxy.autoCreated) {
proxy.destroy();
}
me.setModel(null);
},
hasPendingLoad: function() {
return !!this.loadTask || this.isLoading();
},
isLoading: function() {
return !!this.loading;
},
isLoaded: function() {
return this.loadCount > 0;
},
suspendAutoSync: function() {
++this.autoSyncSuspended;
},
resumeAutoSync: function(syncNow) {
var me = this;
if (!me.autoSyncSuspended) {
Ext.log.warn('Mismatched call to resumeAutoSync - auto synchronization is currently not suspended.');
}
if (me.autoSyncSuspended && !--me.autoSyncSuspended) {
if (syncNow) {
me.sync();
}
}
},
removeAll: Ext.emptyFn,
clearData: Ext.emptyFn,
privates: {
attemptLoad: function(options) {
if (this.isLoadBlocked()) {
++this.loadsWhileBlocked;
return;
}
this.load(options);
},
blockLoad: function(value) {
++this.blockLoadCounter;
},
clearLoadTask: function() {
var loadTask = this.loadTask;
if (loadTask) {
loadTask.cancel();
this.loadTask = null;
}
},
cleanRemoved: function() {
var removed = this.removed,
len, i;
if (removed) {
for (i = 0 , len = removed.length; i < len; ++i) {
removed[i].unjoin(this);
}
removed.length = 0;
}
},
createOperation: function(type, options) {
var me = this,
proxy = me.getProxy(),
listeners;
if (!me.proxyListeners) {
listeners = {
scope: me,
destroyable: true,
beginprocessresponse: me.beginUpdate,
endprocessresponse: me.endUpdate
};
if (!me.disableMetaChangeEvent) {
listeners.metachange = me.onMetaChange;
}
me.proxyListeners = proxy.on(listeners);
}
return proxy.createOperation(type, options);
},
isLoadBlocked: function() {
return !!this.blockLoadCounter;
},
loadsSynchronously: function() {
return this.getProxy().isSynchronous;
},
onBeforeLoad: Ext.privateFn,
removeFromRemoved: function(record) {
var removed = this.removed;
if (removed) {
Ext.Array.remove(removed, record);
record.unjoin(this);
}
},
unblockLoad: function(doLoad) {
var me = this,
loadsWhileBlocked = me.loadsWhileBlocked;
--me.blockLoadCounter;
if (!me.blockLoadCounter) {
me.loadsWhileBlocked = 0;
if (doLoad && loadsWhileBlocked) {
me.load();
}
}
}
}
});
Ext.define('Ext.data.LocalStore', {
extend: 'Ext.Mixin',
mixinConfig: {
id: 'localstore'
},
config: {
extraKeys: null
},
applyExtraKeys: function(extraKeys) {
var indexName,
data = this.getData();
data.setExtraKeys(extraKeys);
extraKeys = data.getExtraKeys();
for (indexName in extraKeys) {
this[indexName] = extraKeys[indexName];
}
},
add: function(arg) {
return this.insert(this.getCount(), arguments.length === 1 ? arg : arguments);
},
constructDataCollection: function() {
return new Ext.util.Collection({
rootProperty: 'data'
});
},
createModel: function(record) {
var session = this.getSession(),
Model;
if (!record.isModel) {
Model = this.getModel();
record = new Model(record, session);
}
return record;
},
createFiltersCollection: function() {
return this.getData().getFilters();
},
createSortersCollection: function() {
var sorters = this.getData().getSorters();
sorters.setSorterConfigure(this.addFieldTransform, this);
return sorters;
},
onCollectionSort: function() {
this.onSorterEndUpdate();
},
onCollectionFilter: function() {
this.onFilterEndUpdate();
},
notifySorterChange: function() {
this.getData().onSorterChange();
},
forceLocalSort: function() {
this.getData().onSortChange();
},
contains: function(record) {
return this.indexOf(record) > -1;
},
each: function(fn, scope) {
var data = this.data.items,
len = data.length,
record, i;
for (i = 0; i < len; ++i) {
record = data[i];
if (fn.call(scope || record, record, i, len) === false) {
break;
}
}
},
collect: function(dataIndex, allowNull, bypassFilter) {
var me = this,
data = me.getData();
if (bypassFilter === true && data.filtered) {
data = data.getSource();
}
return data.collect(dataIndex, 'data', allowNull);
},
getById: function(id) {
var data = this.getData();
if (data.filtered) {
data = data.getSource();
}
return data.get(id) || null;
},
getByInternalId: function(internalId) {
var data = this.getData(),
keyCfg;
if (!this.hasInternalKeys) {
keyCfg = {
byInternalId: {
property: 'internalId',
rootProperty: ''
}
};
this.hasInternalKeys = true;
}
if (data.filtered) {
if (keyCfg) {
data.setExtraKeys(keyCfg);
}
data = data.getSource();
}
if (keyCfg) {
data.setExtraKeys(keyCfg);
}
return data.byInternalId.get(internalId) || null;
},
indexOf: function(record) {
return this.getData().indexOf(record);
},
indexOfId: function(id) {
return this.indexOf(this.getById(id));
},
insert: function(index, records) {
var me = this,
len, i;
if (records) {
if (!Ext.isIterable(records)) {
records = [
records
];
} else {
records = Ext.Array.clone(records);
}
len = records.length;
}
if (!len) {
return [];
}
for (i = 0; i < len; ++i) {
records[i] = me.createModel(records[i]);
}
me.getData().insert(index, records);
return records;
},
queryBy: function(fn, scope) {
var data = this.getData();
return (data.getSource() || data).createFiltered(fn, scope);
},
query: function(property, value, anyMatch, caseSensitive, exactMatch) {
var data = this.getData();
return (data.getSource() || data).createFiltered(property, value, anyMatch, caseSensitive, exactMatch);
},
first: function(grouped) {
return this.getData().first(grouped) || null;
},
last: function(grouped) {
return this.getData().last(grouped) || null;
},
sum: function(field, grouped) {
var data = this.getData();
return (grouped && this.isGrouped()) ? data.sumByGroup(field) : data.sum(field);
},
count: function(grouped) {
var data = this.getData();
return (grouped && this.isGrouped()) ? data.countByGroup() : data.count();
},
min: function(field, grouped) {
var data = this.getData();
return (grouped && this.isGrouped()) ? data.minByGroup(field) : data.min(field);
},
max: function(field, grouped) {
var data = this.getData();
return (grouped && this.isGrouped()) ? data.maxByGroup(field) : data.max(field);
},
average: function(field, grouped) {
var data = this.getData();
return (grouped && this.isGrouped()) ? data.averageByGroup(field) : data.average(field);
},
aggregate: function(fn, scope, grouped, field) {
var me = this,
groups, len, out, group, i;
if (grouped && me.isGrouped()) {
groups = me.getGroups().items;
len = groups.length;
out = {};
for (i = 0; i < len; ++i) {
group = groups[i];
out[group.getGroupKey()] = me.getAggregate(fn, scope || me, group.items, field);
}
return out;
} else {
return me.getAggregate(fn, scope, me.getData().items, field);
}
},
getAggregate: function(fn, scope, records, field) {
var values = [],
len = records.length,
i;
for (i = 0; i < len; ++i) {
values[i] = records[i].get(field);
}
return fn.call(scope || this, records, values);
},
addObserver: function(observer) {
var observers = this.observers;
if (!observers) {
this.observers = observers = new Ext.util.Collection();
}
observers.add(observer);
},
removeObserver: function(observer) {
var observers = this.observers;
if (observers) {
observers.remove(observer);
}
},
callObservers: function(action, args) {
var observers = this.observers,
len, items, i, methodName, item;
if (observers) {
items = observers.items;
if (args) {
args.unshift(this);
} else {
args = [
this
];
}
for (i = 0 , len = items.length; i < len; ++i) {
item = items[i];
methodName = 'onSource' + action;
if (item[methodName]) {
item[methodName].apply(item, args);
}
}
}
},
queryRecordsBy: function(fn, scope) {
var data = this.getData(),
matches = [],
len, i, record;
data = (data.getSource() || data).items;
scope = scope || this;
for (i = 0 , len = data.length; i < len; ++i) {
record = data[i];
if (fn.call(scope, record) === true) {
matches.push(record);
}
}
return matches;
},
queryRecords: function(field, value) {
var data = this.getData(),
matches = [],
len, i, record;
data = (data.getSource() || data).items;
for (i = 0 , len = data.length; i < len; ++i) {
record = data[i];
if (record.get(field) === value) {
matches.push(record);
}
}
return matches;
},
privates: {
isLast: function(record) {
return record === this.last();
}
}
});
Ext.define('Ext.data.proxy.Server', {
extend: 'Ext.data.proxy.Proxy',
alias: 'proxy.server',
alternateClassName: 'Ext.data.ServerProxy',
uses: [
'Ext.data.Request'
],
isRemote: true,
config: {
url: '',
pageParam: 'page',
startParam: 'start',
limitParam: 'limit',
groupParam: 'group',
groupDirectionParam: 'groupDir',
sortParam: 'sort',
filterParam: 'filter',
directionParam: 'dir',
idParam: 'id',
simpleSortMode: false,
simpleGroupMode: false,
noCache: true,
cacheString: "_dc",
timeout: 30000,
api: {
create: undefined,
read: undefined,
update: undefined,
destroy: undefined
},
extraParams: {}
},
create: function() {
return this.doRequest.apply(this, arguments);
},
read: function() {
return this.doRequest.apply(this, arguments);
},
update: function() {
return this.doRequest.apply(this, arguments);
},
erase: function() {
return this.doRequest.apply(this, arguments);
},
setExtraParam: function(name, value) {
this.getExtraParams()[name] = value;
},
buildRequest: function(operation) {
var me = this,
initialParams = Ext.apply({}, operation.getParams()),
params = Ext.applyIf(initialParams, me.getExtraParams() || {}),
request, operationId, idParam;
Ext.applyIf(params, me.getParams(operation));
operationId = operation.getId();
idParam = me.getIdParam();
if (operationId !== undefined && params[idParam] === undefined) {
params[idParam] = operationId;
}
request = new Ext.data.Request({
params: params,
action: operation.getAction(),
records: operation.getRecords(),
url: operation.getUrl(),
operation: operation,
proxy: me
});
request.setUrl(me.buildUrl(request));
operation.setRequest(request);
return request;
},
processResponse: function(success, operation, request, response) {
var me = this,
exception, reader, resultSet;
me.fireEvent('beginprocessresponse', me, response, operation);
if (success === true) {
reader = me.getReader();
if (response.status === 204) {
resultSet = reader.getNullResultSet();
} else {
resultSet = reader.read(me.extractResponseData(response), {
recordCreator: operation.getRecordCreator()
});
}
operation.process(resultSet, request, response);
exception = !operation.wasSuccessful();
} else {
me.setException(operation, response);
exception = true;
}
if (exception) {
me.fireEvent('exception', me, response, operation);
}
me.afterRequest(request, success);
me.fireEvent('endprocessresponse', me, response, operation);
},
setException: function(operation, response) {
operation.setException({
status: response.status,
statusText: response.statusText,
response: response
});
},
extractResponseData: Ext.identityFn,
applyEncoding: function(value) {
return Ext.encode(value);
},
encodeSorters: function(sorters, preventArray) {
var out = [],
length = sorters.length,
i;
for (i = 0; i < length; i++) {
out[i] = sorters[i].serialize();
}
return this.applyEncoding(preventArray ? out[0] : out);
},
encodeFilters: function(filters) {
var out = [],
length = filters.length,
i, op;
for (i = 0; i < length; i++) {
out[i] = filters[i].serialize();
}
return this.applyEncoding(out);
},
getParams: function(operation) {
if (!operation.isReadOperation) {
return {};
}
var me = this,
params = {},
grouper = operation.getGrouper(),
sorters = operation.getSorters(),
filters = operation.getFilters(),
page = operation.getPage(),
start = operation.getStart(),
limit = operation.getLimit(),
simpleSortMode = me.getSimpleSortMode(),
simpleGroupMode = me.getSimpleGroupMode(),
pageParam = me.getPageParam(),
startParam = me.getStartParam(),
limitParam = me.getLimitParam(),
groupParam = me.getGroupParam(),
groupDirectionParam = me.getGroupDirectionParam(),
sortParam = me.getSortParam(),
filterParam = me.getFilterParam(),
directionParam = me.getDirectionParam(),
hasGroups, index;
if (pageParam && page) {
params[pageParam] = page;
}
if (startParam && (start || start === 0)) {
params[startParam] = start;
}
if (limitParam && limit) {
params[limitParam] = limit;
}
hasGroups = groupParam && grouper;
if (hasGroups) {
if (simpleGroupMode) {
params[groupParam] = grouper.getProperty();
params[groupDirectionParam] = grouper.getDirection();
} else {
params[groupParam] = me.encodeSorters([
grouper
], true);
}
}
if (sortParam && sorters && sorters.length > 0) {
if (simpleSortMode) {
index = 0;
if (sorters.length > 1 && hasGroups) {
index = 1;
}
params[sortParam] = sorters[index].getProperty();
params[directionParam] = sorters[index].getDirection();
} else {
params[sortParam] = me.encodeSorters(sorters);
}
}
if (filterParam && filters && filters.length > 0) {
params[filterParam] = me.encodeFilters(filters);
}
return params;
},
buildUrl: function(request) {
var me = this,
url = me.getUrl(request);
if (!url) {
Ext.Error.raise("You are using a ServerProxy but have not supplied it with a url.");
}
if (me.getNoCache()) {
url = Ext.urlAppend(url, Ext.String.format("{0}={1}", me.getCacheString(), Ext.Date.now()));
}
return url;
},
getUrl: function(request) {
var url;
if (request) {
url = request.getUrl() || this.getApi()[request.getAction()];
}
return url ? url : this.callParent();
},
doRequest: function(operation) {
Ext.Error.raise("The doRequest function has not been implemented on your Ext.data.proxy.Server subclass. See src/data/ServerProxy.js for details");
},
afterRequest: Ext.emptyFn,
destroy: function() {
this.callParent();
Ext.destroy(this.getReader(), this.getWriter());
this.reader = this.writer = null;
}
});
Ext.define('Ext.data.proxy.Ajax', {
requires: [
'Ext.Ajax'
],
extend: 'Ext.data.proxy.Server',
alias: 'proxy.ajax',
alternateClassName: [
'Ext.data.HttpProxy',
'Ext.data.AjaxProxy'
],
defaultActionMethods: {
create: 'POST',
read: 'GET',
update: 'POST',
destroy: 'POST'
},
config: {
binary: false,
headers: undefined,
paramsAsJson: false,
withCredentials: false,
useDefaultXhrHeader: true,
username: null,
password: null,
actionMethods: {
create: 'POST',
read: 'GET',
update: 'POST',
destroy: 'POST'
}
},
doRequest: function(operation) {
var me = this,
writer = me.getWriter(),
request = me.buildRequest(operation),
method = me.getMethod(request),
jsonData, params;
if (writer && operation.allowWrite()) {
request = writer.write(request);
}
request.setConfig({
binary: me.getBinary(),
headers: me.getHeaders(),
timeout: me.getTimeout(),
scope: me,
callback: me.createRequestCallback(request, operation),
method: method,
useDefaultXhrHeader: me.getUseDefaultXhrHeader(),
disableCaching: false
});
if (method.toUpperCase() !== 'GET' && me.getParamsAsJson()) {
params = request.getParams();
if (params) {
jsonData = request.getJsonData();
if (jsonData) {
jsonData = Ext.Object.merge({}, jsonData, params);
} else {
jsonData = params;
}
request.setJsonData(jsonData);
request.setParams(undefined);
}
}
if (me.getWithCredentials()) {
request.setWithCredentials(true);
request.setUsername(me.getUsername());
request.setPassword(me.getPassword());
}
return me.sendRequest(request);
},
sendRequest: function(request) {
request.setRawRequest(Ext.Ajax.request(request.getCurrentConfig()));
this.lastRequest = request;
return request;
},
abort: function(request) {
request = request || this.lastRequest;
if (request) {
Ext.Ajax.abort(request.getRawRequest());
}
},
getMethod: function(request) {
var actions = this.getActionMethods(),
action = request.getAction(),
method;
if (actions) {
method = actions[action];
}
return method || this.defaultActionMethods[action];
},
createRequestCallback: function(request, operation) {
var me = this;
return function(options, success, response) {
if (request === me.lastRequest) {
me.lastRequest = null;
}
me.processResponse(success, operation, request, response);
};
},
destroy: function() {
this.lastRequest = null;
this.callParent();
}
});
Ext.define('Ext.data.reader.Json', {
extend: 'Ext.data.reader.Reader',
requires: [
'Ext.JSON'
],
alternateClassName: 'Ext.data.JsonReader',
alias: 'reader.json',
config: {
record: null,
metaProperty: 'metaData',
useSimpleAccessors: false,
preserveRawData: false
},
updateRootProperty: function() {
this.forceBuildExtractors();
},
updateMetaProperty: function() {
this.forceBuildExtractors();
},
readRecords: function(data, readOptions,
internalReadOptions) {
var me = this,
meta;
if (me.getMeta) {
meta = me.getMeta(data);
if (meta) {
me.onMetaChange(meta);
}
} else if (data.metaData) {
me.onMetaChange(data.metaData);
}
return me.callParent([
data,
readOptions,
internalReadOptions
]);
},
getResponseData: function(response) {
try {
return Ext.decode(response.responseText);
} catch (ex) {
Ext.Logger.warn('Unable to parse the JSON returned by the server');
return this.createReadError(ex.message);
}
},
buildExtractors: function() {
var me = this,
metaProp, rootProp;
if (me.callParent(arguments)) {
metaProp = me.getMetaProperty();
rootProp = me.getRootProperty();
if (rootProp) {
me.getRoot = me.getAccessor(rootProp);
} else {
me.getRoot = Ext.identityFn;
}
if (metaProp) {
me.getMeta = me.getAccessor(metaProp);
}
}
},
extractData: function(root, readOptions) {
var recordName = this.getRecord(),
data = [],
length, i;
if (recordName) {
length = root.length;
if (!length && Ext.isObject(root)) {
length = 1;
root = [
root
];
}
for (i = 0; i < length; i++) {
data[i] = root[i][recordName];
}
} else {
data = root;
}
return this.callParent([
data,
readOptions
]);
},
getModelData: function(raw) {
return this.getPreserveRawData() ? Ext.apply({}, raw) : raw;
},
createAccessor: (function() {
var re = /[\[\.]/;
return function(expr) {
var me = this,
simple = me.getUseSimpleAccessors(),
operatorIndex, result, current, parts, part, inExpr, isDot, isLeft, isRight, special, c, i, bracketed, len;
if (!(expr || expr === 0)) {
return;
}
if (typeof expr === 'function') {
return expr;
}
if (!simple) {
operatorIndex = String(expr).search(re);
}
if (simple === true || operatorIndex < 0) {
result = function(raw) {
return raw[expr];
};
} else {
current = 'raw';
parts = [];
part = '';
inExpr = 0;
len = expr.length;
for (i = 0; i <= len; ++i) {
c = expr[i];
isDot = c === '.';
isLeft = c === '[';
isRight = c === ']';
special = isDot || isLeft || isRight || !c;
if (!special || inExpr > 1 || (inExpr && !isRight)) {
part += c;
} else if (special) {
bracketed = false;
if (isLeft) {
++inExpr;
} else if (isRight) {
--inExpr;
bracketed = true;
}
if (part) {
if (bracketed) {
part = '[' + part + ']';
} else {
part = '.' + part;
}
current += part;
parts.push('' + current);
part = '';
}
}
}
result = parts.join(' && ');
result = Ext.functionFactory('raw', 'return ' + result);
}
return result;
};
}()),
createFieldAccessor: function(field) {
var me = this,
mapping = field.mapping,
hasMap = mapping || mapping === 0,
map = hasMap ? mapping : field.name;
if (hasMap) {
if (typeof map === 'function') {
return function(raw) {
return field.mapping(raw, me);
};
} else {
return me.createAccessor(map);
}
}
},
getAccessorKey: function(prop) {
var simple = this.getUseSimpleAccessors() ? 'simple' : '';
return this.$className + simple + prop;
},
privates: {
copyFrom: function(reader) {
this.callParent([
reader
]);
this.getRoot = reader.getRoot;
}
}
});
Ext.define('Ext.data.writer.Json', {
extend: 'Ext.data.writer.Writer',
alternateClassName: 'Ext.data.JsonWriter',
alias: 'writer.json',
config: {
rootProperty: undefined,
encode: false,
allowSingle: true,
expandData: false
},
constructor: function(config) {
if (config && config.hasOwnProperty('root')) {
config = Ext.apply({}, config);
config.rootProperty = config.root;
delete config.root;
Ext.log.warn('Ext.data.writer.Json: Using the deprecated "root" configuration. Use "rootProperty" instead.');
}
this.callParent([
config
]);
},
getExpandedData: function(data) {
var dataLength = data.length,
i = 0,
item, prop, nameParts, j, tempObj,
toObject = function(name, value) {
var o = {};
o[name] = value;
return o;
};
for (; i < dataLength; i++) {
item = data[i];
for (prop in item) {
if (item.hasOwnProperty(prop)) {
nameParts = prop.split('.');
j = nameParts.length - 1;
if (j > 0) {
tempObj = item[prop];
for (; j > 0; j--) {
tempObj = toObject(nameParts[j], tempObj);
}
item[nameParts[0]] = item[nameParts[0]] || {};
Ext.Object.merge(item[nameParts[0]], tempObj);
delete item[prop];
}
}
}
}
return data;
},
writeRecords: function(request, data) {
var me = this,
root = me.getRootProperty(),
json, single, transform;
if (me.getExpandData()) {
data = me.getExpandedData(data);
}
if (me.getAllowSingle() && data.length === 1) {
data = data[0];
single = true;
}
transform = this.getTransform();
if (transform) {
data = transform(data, request);
}
if (me.getEncode()) {
if (root) {
request.setParam(root, Ext.encode(data));
} else {
Ext.Error.raise('Must specify a root when using encode');
}
} else if (single || (data && data.length)) {
json = request.getJsonData() || {};
if (root) {
json[root] = data;
} else {
json = data;
}
request.setJsonData(json);
}
return request;
}
});
Ext.define('Ext.util.Group', {
extend: 'Ext.util.Collection',
config: {
groupKey: null
},
$endUpdatePriority: 2001
});
Ext.define('Ext.util.SorterCollection', {
extend: 'Ext.util.Collection',
requires: [
'Ext.util.Sorter'
],
isSorterCollection: true,
$sortable: null,
sortFn: null,
config: {
sorterOptionsFn: null,
sorterOptionsScope: null
},
constructor: function(config) {
var me = this;
me.sortFn = Ext.util.Sorter.createComparator(me);
me.callParent([
config
]);
me.setDecoder(me.decodeSorter);
},
addSort: function(property, direction, mode) {
var me = this,
count, index, limit, options, primary, sorter, sorters;
if (!property) {
me.beginUpdate();
me.endUpdate();
} else {
options = me.getOptions();
if (property instanceof Array) {
sorters = property;
mode = direction;
direction = null;
} else if (Ext.isString(property)) {
if (!(sorter = me.get(property))) {
sorters = [
{
property: property,
direction: direction || options.getDefaultSortDirection()
}
];
} else {
sorters = [
sorter
];
}
} else if (Ext.isFunction(property)) {
sorters = [
{
sorterFn: property,
direction: direction || options.getDefaultSortDirection()
}
];
} else {
if (!Ext.isObject(property)) {
Ext.Error.raise('Invalid sort descriptor: ' + property);
}
sorters = [
property
];
mode = direction;
direction = null;
}
if (mode && !me._sortModes[mode]) {
Ext.Error.raise('Sort mode should be "multi", "append", "prepend" or "replace", not "' + mode + '"');
}
mode = me._sortModes[mode || 'replace'];
primary = me.getAt(0);
count = me.length;
index = mode.append ? count : 0;
me.beginUpdate();
me.splice(index, mode.replace ? count : 0, sorters);
if (mode.multi) {
count = me.length;
limit = options.getMultiSortLimit();
if (count > limit) {
me.removeAt(limit, count);
}
}
if (sorter && direction) {
sorter.setDirection(direction);
} else if (index === 0 && primary && primary === me.getAt(0)) {
primary.toggle();
}
me.endUpdate();
}
},
getSortFn: function() {
return this.sortFn;
},
getByProperty: function(prop) {
var items = this.items,
len = items.length,
i, item;
for (i = 0; i < len; ++i) {
item = items[i];
if (item.getProperty() === prop) {
return item;
}
}
return null;
},
_sortModes: {
append: {
append: 1
},
multi: {
multi: 1
},
prepend: {
prepend: 1
},
replace: {
replace: 1
}
},
decodeSorter: function(sorter, xclass) {
var me = this,
options = me.getOptions(),
root = options.getRootProperty(),
sorterOptionsFn = me.getSorterOptionsFn(),
currentSorter, sorterConfig, type;
if (sorter.isSorter) {
if (!sorter.getRoot()) {
sorter.setRoot(root);
}
} else {
sorterConfig = {
direction: options.getDefaultSortDirection(),
root: root
};
type = typeof sorter;
if (type === 'string') {
currentSorter = me.get(sorter);
if (currentSorter) {
return currentSorter;
}
sorterConfig.property = sorter;
}
else if (type === 'function') {
sorterConfig.sorterFn = sorter;
} else
{
if (!Ext.isObject(sorter)) {
Ext.Error.raise('Invalid sorter specified: ' + sorter);
}
sorterConfig = Ext.apply(sorterConfig, sorter);
if (sorterConfig.fn) {
sorterConfig.sorterFn = sorterConfig.fn;
delete sorterConfig.fn;
}
}
sorter = Ext.create(xclass || 'Ext.util.Sorter', sorterConfig);
}
if (sorterOptionsFn) {
sorterOptionsFn.call(me.getSorterOptionsScope() || me, sorter);
}
return sorter;
},
setSorterConfigure: function(fn, scope) {
this.setSorterOptionsFn(fn);
this.setSorterOptionsScope(scope);
},
decodeRemoveItems: function(args, index) {
var me = this,
ret = (index === undefined) ? args : args[index];
if (!ret || !ret.$cloned) {
if (args.length > index + 1 || !Ext.isIterable(ret)) {
ret = Ext.Array.slice(args, index);
}
var currentSorters = me.items,
ln = ret.length,
remove = [],
i, item, n, sorter, type;
for (i = 0; i < ln; i++) {
sorter = ret[i];
if (sorter && sorter.isSorter) {
remove.push(sorter);
} else {
type = typeof sorter;
if (type === 'string') {
sorter = me.get(sorter);
if (sorter) {
remove.push(sorter);
}
} else if (type === 'function') {
for (n = currentSorters.length; n-- > 0; ) {
item = currentSorters[n];
if (item.getSorterFn() === sorter) {
remove.push(item);
}
}
} else {
Ext.Error.raise('Invalid sorter specification: ' + sorter);
}
}
}
ret = remove;
ret.$cloned = true;
}
return ret;
},
getOptions: function() {
return this.$sortable || this;
}
});
Ext.define('Ext.util.FilterCollection', {
extend: 'Ext.util.Collection',
requires: [
'Ext.util.Filter'
],
isFilterCollection: true,
$filterable: null,
filterFn: null,
constructor: function(config) {
var me = this;
me.filterFn = Ext.util.Filter.createFilterFn(me);
me.callParent([
config
]);
me.setDecoder(me.decodeFilter);
},
filterData: function(data) {
return this.filtered ? Ext.Array.filter(data, this.filterFn) : data;
},
getFilterFn: function() {
return this.filterFn;
},
isItemFiltered: function(item) {
return !this.filterFn(item);
},
decodeFilter: function(filter) {
var options = this.getOptions(),
filterRoot = options.getRootProperty(),
filterConfig;
if (filter.isFilter) {
if (!filter.getRoot()) {
filter.setRoot(filterRoot);
}
} else {
filterConfig = {
root: filterRoot
};
if (Ext.isFunction(filter)) {
filterConfig.filterFn = filter;
} else
{
if (!Ext.isObject(filter)) {
Ext.Error.raise('Invalid filter specified: ' + filter);
}
filterConfig = Ext.apply(filterConfig, filter);
if (filterConfig.fn) {
filterConfig.filterFn = filterConfig.fn;
delete filterConfig.fn;
}
if (Ext.util.Filter.isInvalid(filterConfig)) {
return false;
}
}
filter = new Ext.util.Filter(filterConfig);
}
return filter;
},
decodeRemoveItems: function(args, index) {
var me = this,
ret = (index === undefined) ? args : args[index];
if (!ret.$cloned) {
if (args.length > index + 1 || !Ext.isIterable(ret)) {
ret = Ext.Array.slice(args, index);
}
var currentFilters = me.items,
ln = ret.length,
remove = [],
filter, i, isFunction, isProp, isString, item, match, n, type;
for (i = 0; i < ln; i++) {
filter = ret[i];
if (filter && filter.isFilter) {
remove.push(filter);
} else {
type = typeof filter;
isFunction = type === 'function';
isProp = filter.property !== undefined && filter.value !== undefined;
isString = type === 'string';
if (!isFunction && !isProp && !isString) {
Ext.Error.raise('Invalid filter specification: ' + filter);
}
for (n = currentFilters.length; n-- > 0; ) {
item = currentFilters[n];
match = false;
if (isString) {
match = item.getProperty() === filter;
} else if (isFunction) {
match = item.getFilterFn() === filter;
} else if (isProp) {
match = item.getProperty() === filter.property && item.getValue() === filter.value;
}
if (match) {
remove.push(item);
}
}
}
}
ret = remove;
ret.$cloned = true;
}
return ret;
},
getOptions: function() {
return this.$filterable || this;
}
});
Ext.define('Ext.util.GroupCollection', {
extend: 'Ext.util.Collection',
requires: [
'Ext.util.Group',
'Ext.util.SorterCollection',
'Ext.util.FilterCollection'
],
isGroupCollection: true,
config: {
grouper: null,
itemRoot: null
},
observerPriority: -100,
onCollectionAdd: function(source, details) {
this.addItemsToGroups(source, details.items);
},
onCollectionBeforeItemChange: function(source, details) {
this.changeDetails = details;
},
onCollectionBeginUpdate: function() {
this.beginUpdate();
},
onCollectionEndUpdate: function() {
this.endUpdate();
},
onCollectionItemChange: function(source, details) {
var item = details.item;
if (!details.indexChanged) {
this.syncItemGrouping(source, item, source.getKey(item), details.oldKey, details.oldIndex);
}
this.changeDetails = null;
},
onCollectionRefresh: function(source) {
this.removeAll();
this.addItemsToGroups(source, source.items);
},
onCollectionRemove: function(source, details) {
var me = this,
changeDetails = me.changeDetails,
entries, entry, group, i, n, removeGroups, item;
if (changeDetails) {
item = changeDetails.item;
group = me.findGroupForItem(item);
entries = [];
if (group) {
entries.push({
group: group,
items: [
item
]
});
}
} else {
entries = me.groupItems(source, details.items, false);
}
for (i = 0 , n = entries.length; i < n; ++i) {
group = (entry = entries[i]).group;
if (group) {
group.remove(entry.items);
if (!group.length) {
(removeGroups || (removeGroups = [])).push(group);
}
}
}
if (removeGroups) {
me.remove(removeGroups);
}
},
onCollectionSort: function(source) {
var me = this,
sorters = source.getSorters(false),
items, length, i, group;
if (sorters) {
items = me.items;
length = me.length;
for (i = 0; i < length; ++i) {
group = items[i];
if (group.getSorters() !== sorters) {
group.setSorters(sorters);
}
}
}
},
onCollectionUpdateKey: function(source, details) {
var index = details.index,
item = details.item;
if (!details.indexChanged) {
index = source.indexOf(item);
this.syncItemGrouping(source, item, details.newKey, details.oldKey, index);
}
},
addItemsToGroups: function(source, items) {
this.groupItems(source, items, true);
},
groupItems: function(source, items, adding) {
var me = this,
byGroup = {},
entries = [],
grouper = source.getGrouper(),
groupKeys = me.itemGroupKeys,
entry, group, groupKey, i, item, itemKey, len, newGroups;
for (i = 0 , len = items.length; i < len; ++i) {
groupKey = grouper.getGroupString(item = items[i]);
itemKey = source.getKey(item);
if (adding) {
(groupKeys || (me.itemGroupKeys = groupKeys = {}))[itemKey] = groupKey;
} else if (groupKeys) {
delete groupKeys[itemKey];
}
if (!(entry = byGroup[groupKey])) {
if (!(group = me.getByKey(groupKey)) && adding) {
(newGroups || (newGroups = [])).push(group = me.createGroup(source, groupKey));
}
entries.push(byGroup[groupKey] = entry = {
group: group,
items: []
});
}
entry.items.push(item);
}
for (i = 0 , len = entries.length; i < len; ++i) {
entry = entries[i];
entry.group.add(entry.items);
}
if (newGroups) {
me.add(newGroups);
}
return entries;
},
syncItemGrouping: function(source, item, itemKey, oldKey, itemIndex) {
var me = this,
itemGroupKeys = me.itemGroupKeys || (me.itemGroupKeys = {}),
grouper = source.getGrouper(),
groupKey = grouper.getGroupString(item),
removeGroups = 0,
index = -1,
addGroups, group, oldGroup, oldGroupKey, firstIndex;
if (oldKey) {
oldGroupKey = itemGroupKeys[oldKey];
delete itemGroupKeys[oldKey];
} else {
oldGroupKey = itemGroupKeys[itemKey];
}
itemGroupKeys[itemKey] = groupKey;
if (!(group = me.get(groupKey))) {
group = me.createGroup(source, groupKey);
addGroups = [
group
];
}
if (group.get(itemKey) !== item) {
if (group.getCount() > 0 && source.getSorters().getCount() === 0) {
firstIndex = source.indexOf(group.items[0]);
if (itemIndex < firstIndex) {
index = 0;
} else {
index = itemIndex - firstIndex;
}
}
if (index === -1) {
group.add(item);
} else {
group.insert(index, item);
}
} else {
group.itemChanged(item);
}
if (groupKey !== oldGroupKey && (oldGroupKey === 0 || oldGroupKey)) {
oldGroup = me.get(oldGroupKey);
if (oldGroup) {
oldGroup.remove(item);
if (!oldGroup.length) {
removeGroups = [
oldGroup
];
}
}
}
if (addGroups) {
me.splice(0, removeGroups, addGroups);
} else if (removeGroups) {
me.splice(0, removeGroups);
}
},
createGroup: function(source, key) {
var group = new Ext.util.Group({
groupKey: key,
rootProperty: this.getItemRoot(),
sorters: source.getSorters()
});
return group;
},
getKey: function(item) {
return item.getGroupKey();
},
createSortFn: function() {
var me = this,
grouper = me.getGrouper(),
sorterFn = me.getSorters().getSortFn();
if (!grouper) {
return sorterFn;
}
return function(lhs, rhs) {
return grouper.sort(lhs.items[0], rhs.items[0]) || sorterFn(lhs, rhs);
};
},
updateGrouper: function(grouper) {
var me = this;
me.grouped = !!(grouper && me.$groupable.getAutoGroup());
me.onSorterChange();
me.onEndUpdateSorters(me.getSorters());
},
destroy: function() {
this.$groupable = null;
this.callParent();
},
privates: {
findGroupForItem: function(item) {
var items = this.items,
len = items.length,
i, group;
for (i = 0; i < len; ++i) {
group = items[i];
if (group.contains(item)) {
return group;
}
}
}
}
});
Ext.define('Ext.data.Store', {
extend: 'Ext.data.ProxyStore',
alias: 'store.store',
mixins: [
'Ext.data.LocalStore'
],
requires: [
'Ext.data.Model',
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json',
'Ext.data.writer.Json',
'Ext.util.GroupCollection',
'Ext.util.DelayedTask'
],
uses: [
'Ext.data.StoreManager',
'Ext.util.Grouper'
],
config: {
data: 0,
clearRemovedOnLoad: true,
clearOnPageLoad: true,
associatedEntity: null,
role: null,
session: null
},
addRecordsOptions: {
addRecords: true
},
loadCount: 0,
complete: false,
moveMapCount: 0,
constructor: function(config) {
var me = this,
data;
if (config) {
if (config.buffered) {
if (this.self !== Ext.data.Store) {
Ext.Error.raise('buffered config not supported on derived Store classes. ' + 'Please derive from Ext.data.BufferedStore.');
}
return new Ext.data.BufferedStore(config);
}
if (config.remoteGroup) {
Ext.log.warn('Ext.data.Store: remoteGroup has been removed. Use remoteSort instead.');
}
}
me.callParent([
config
]);
me.getData().addObserver(me);
data = me.inlineData;
if (data) {
delete me.inlineData;
me.loadInlineData(data);
}
},
onCollectionBeginUpdate: function() {
this.beginUpdate();
},
onCollectionEndUpdate: function() {
this.endUpdate();
},
applyData: function(data, dataCollection) {
var me = this;
me.getFields();
me.getModel();
if (data && data.isCollection) {
dataCollection = data;
} else {
if (!dataCollection) {
dataCollection = me.constructDataCollection();
}
if (data) {
if (me.isInitializing) {
me.inlineData = data;
} else {
me.loadData(data);
}
}
}
return dataCollection;
},
loadInlineData: function(data) {
var me = this,
proxy = me.getProxy(),
blocked;
if (proxy && proxy.isMemoryProxy) {
proxy.setData(data);
blocked = me.blockLoadCounter;
me.blockLoadCounter = 0;
me.suspendEvents();
me.read();
me.resumeEvents();
me.blockLoadCounter = blocked;
} else {
me.removeAll(true);
me.suspendEvents();
me.loadData(data);
me.resumeEvents();
}
},
onCollectionAdd: function(collection, info) {
this.onCollectionAddItems(collection, info.items, info);
},
onCollectionFilterAdd: function(collection, items) {
this.onCollectionAddItems(collection, items);
},
onCollectionAddItems: function(collection, records, info) {
var me = this,
len = records.length,
lastChunk = info ? !info.next : false,
removed = me.getRemovedRecords(),
ignoreAdd = me.ignoreCollectionAdd,
session = me.getSession(),
replaced = info && info.replaced,
i, sync, record, replacedItems;
for (i = 0; i < len; ++i) {
record = records[i];
if (session) {
session.adopt(record);
}
if (!ignoreAdd) {
record.join(me);
if (removed && removed.length) {
Ext.Array.remove(removed, record);
}
sync = sync || record.phantom || record.dirty;
}
}
if (ignoreAdd) {
return;
}
if (replaced) {
replacedItems = [];
do {
Ext.Array.push(replacedItems, replaced.items);
replaced = replaced.next;
} while (replaced);
me.setMoving(replacedItems, true);
}
if (info) {
me.fireEvent('add', me, records, info.at);
if (lastChunk) {
me.fireEvent('datachanged', me);
}
}
if (replacedItems) {
me.setMoving(replacedItems, false);
}
me.needsSync = me.needsSync || sync;
},
onCollectionFilteredItemChange: function() {
this.onCollectionItemChange.apply(this, arguments);
},
onCollectionItemChange: function(collection, info) {
var me = this,
record = info.item,
modifiedFieldNames = info.modified || null,
type = info.meta;
if (me.fireChangeEvent(record)) {
me.onUpdate(record, type, modifiedFieldNames, info);
me.fireEvent('update', me, record, type, modifiedFieldNames, info);
}
},
fireChangeEvent: function(record) {
var data = this.getData();
data = data.getSource() || data;
return data.contains(record);
},
afterChange: function(record, modifiedFieldNames, type) {
this.getData().itemChanged(record, modifiedFieldNames || null, undefined, type);
},
afterCommit: function(record, modifiedFieldNames) {
this.afterChange(record, modifiedFieldNames, Ext.data.Model.COMMIT);
},
afterEdit: function(record, modifiedFieldNames) {
this.needsSync = this.needsSync || record.dirty;
this.afterChange(record, modifiedFieldNames, Ext.data.Model.EDIT);
},
afterReject: function(record) {
this.afterChange(record, null, Ext.data.Model.REJECT);
},
afterDrop: function(record) {
this.getData().remove(record);
},
afterErase: function(record) {
this.removeFromRemoved(record);
},
addSorted: function(record) {
var me = this,
remote = me.getRemoteSort(),
data = me.getData(),
index;
if (remote) {
data.setSorters(me.getSorters());
}
index = data.findInsertionIndex(record);
if (remote) {
data.setSorters(null);
}
return me.insert(index, record);
},
remove: function(records,
isMove, silent) {
var me = this,
data = me.getData(),
len, i, toRemove, record;
if (records) {
if (records.isModel) {
if (me.indexOf(records) > -1) {
toRemove = [
records
];
len = 1;
} else {
len = 0;
}
} else {
toRemove = [];
for (i = 0 , len = records.length; i < len; ++i) {
record = records[i];
if (record && record.isEntity) {
if (!data.contains(record)) {
continue;
}
} else if (!(record = data.getAt(record))) {
continue;
}
toRemove.push(record);
}
len = toRemove.length;
}
}
if (!len) {
return [];
}
me.removeIsMove = isMove === true;
me.removeIsSilent = silent;
data.remove(toRemove);
me.removeIsSilent = false;
return toRemove;
},
onCollectionRemove: function(collection, info) {
var me = this,
removed = me.removed,
records = info.items,
len = records.length,
index = info.at,
isMove = me.removeIsMove,
silent = me.removeIsSilent,
lastChunk = !info.next,
replacement = info.replacement,
data = me.getData(),
i, record;
if (me.ignoreCollectionRemove) {
return;
}
data = data.getSource() || data;
if (replacement) {
me.setMoving(replacement.items, true);
}
for (i = 0; i < len; ++i) {
record = records[i];
if (!data.contains(record)) {
if (removed && !isMove && !record.phantom && !record.erasing) {
record.removedFrom = index + i;
removed.push(record);
me.needsSync = true;
} else {
record.unjoin(me);
}
}
}
if (!silent) {
me.fireEvent('remove', me, records, index, isMove);
if (lastChunk) {
me.fireEvent('datachanged', me);
}
}
if (replacement) {
me.setMoving(replacement.items, false);
}
},
onFilterEndUpdate: function() {
this.callParent(arguments);
this.callObservers('Filter');
},
removeAt: function(index, count) {
var data = this.getData();
index = Math.max(index, 0);
if (index < data.length) {
if (arguments.length === 1) {
count = 1;
} else if (!count) {
return;
}
data.removeAt(index, count);
}
},
removeAll: function(silent) {
var me = this,
data = me.getData(),
hasClear = me.hasListeners.clear,
records = data.getRange();
if (data.length) {
me.removeIsSilent = true;
me.callObservers('BeforeRemoveAll');
data.removeAll();
me.removeIsSilent = false;
if (!silent) {
me.fireEvent('clear', me, records);
me.fireEvent('datachanged', me);
}
me.callObservers('AfterRemoveAll', [
!!silent
]);
}
return records;
},
setRecords: function(records) {
var count = this.getCount();
++this.loadCount;
if (count) {
this.getData().splice(0, count, records);
} else {
this.add(records);
}
},
splice: function(index, toRemove, toAdd) {
return this.getData().splice(index, toRemove, toAdd);
},
load: function(options) {
var me = this,
pageSize = me.getPageSize(),
session;
if (typeof options === 'function') {
options = {
callback: options
};
} else {
options = Ext.apply({}, options);
}
if (me.getRemoteSort() && !options.grouper && me.getGrouper()) {
options.grouper = me.getGrouper();
}
if (pageSize || 'start' in options || 'limit' in options || 'page' in options) {
options.page = options.page != null ? options.page : me.currentPage;
options.start = (options.start !== undefined) ? options.start : (options.page - 1) * pageSize;
options.limit = options.limit != null ? options.limit : pageSize;
me.currentPage = options.page;
}
options.addRecords = options.addRecords || false;
if (!options.recordCreator) {
session = me.getSession();
if (session) {
options.recordCreator = session.recordCreator;
}
}
return me.callParent([
options
]);
},
onProxyLoad: function(operation) {
var me = this,
resultSet = operation.getResultSet(),
records = operation.getRecords(),
successful = operation.wasSuccessful();
if (me.isDestroyed) {
return;
}
if (resultSet) {
me.totalCount = resultSet.getTotal();
}
if (successful) {
records = me.processAssociation(records);
me.loadRecords(records, operation.getAddRecords() ? {
addRecords: true
} : undefined);
} else {
me.loading = false;
}
if (me.hasListeners.load) {
me.fireEvent('load', me, records, successful, operation);
}
me.callObservers('AfterLoad', [
records,
successful,
operation
]);
},
getUnfiltered: function() {
var data = this.getData();
return data.getSource() || data;
},
getNewRecords: function() {
return this.getUnfiltered().createFiltered(this.filterNew).getRange();
},
getUpdatedRecords: function() {
return this.getUnfiltered().createFiltered(this.filterUpdated).getRange();
},
loadData: function(data, append) {
var me = this,
length = data.length,
newData = [],
i;
for (i = 0; i < length; i++) {
newData.push(me.createModel(data[i]));
}
newData = me.processAssociation(newData);
me.loadRecords(newData, append ? me.addRecordsOptions : undefined);
},
loadRawData: function(data, append) {
var me = this,
session = me.getSession(),
result = me.getProxy().getReader().read(data, session ? {
recordCreator: session.recordCreator
} : undefined),
records = result.getRecords(),
success = result.getSuccess();
if (success) {
me.totalCount = result.getTotal();
me.loadRecords(records, append ? me.addRecordsOptions : undefined);
}
return success;
},
loadRecords: function(records, options) {
var me = this,
length = records.length,
data = me.getData(),
addRecords, i, skipSort;
if (options) {
addRecords = options.addRecords;
}
if (!me.getRemoteSort() && !me.getSortOnLoad()) {
skipSort = true;
data.setAutoSort(false);
}
if (!addRecords) {
me.clearData(true);
}
me.loading = false;
me.ignoreCollectionAdd = true;
me.callObservers('BeforePopulate');
data.add(records);
me.ignoreCollectionAdd = false;
if (skipSort) {
data.setAutoSort(true);
}
for (i = 0; i < length; i++) {
records[i].join(me);
}
++me.loadCount;
me.complete = true;
me.fireEvent('datachanged', me);
me.fireEvent('refresh', me);
me.callObservers('AfterPopulate');
},
loadPage: function(page, options) {
var me = this,
size = me.getPageSize();
me.currentPage = page;
options = Ext.apply({
page: page,
start: (page - 1) * size,
limit: size,
addRecords: !me.getClearOnPageLoad()
}, options);
me.read(options);
},
nextPage: function(options) {
this.loadPage(this.currentPage + 1, options);
},
previousPage: function(options) {
this.loadPage(this.currentPage - 1, options);
},
clearData: function(isLoad) {
var me = this,
removed = me.removed,
data = me.getData(),
clearRemovedOnLoad = me.getClearRemovedOnLoad(),
needsUnjoinCheck = removed && isLoad && !clearRemovedOnLoad,
records, record, i, len, unjoin;
data = data.getSource() || data;
if (data) {
records = data.items;
for (i = 0 , len = records.length; i < len; ++i) {
record = records[i];
if (needsUnjoinCheck && Ext.Array.contains(removed, record)) {
continue;
}
record.unjoin(me);
}
me.ignoreCollectionRemove = true;
me.callObservers('BeforeClear');
data.removeAll();
me.ignoreCollectionRemove = false;
me.callObservers('AfterClear');
}
if (removed && (!isLoad || clearRemovedOnLoad)) {
removed.length = 0;
}
},
onIdChanged: function(rec, oldId, newId) {
this.getData().updateKey(rec, oldId);
this.fireEvent('idchanged', this, rec, oldId, newId);
},
commitChanges: function() {
var me = this,
recs = me.getModifiedRecords(),
len = recs.length,
i = 0;
Ext.suspendLayouts();
me.beginUpdate();
for (; i < len; i++) {
recs[i].commit();
}
me.cleanRemoved();
me.endUpdate();
Ext.resumeLayouts(true);
},
filterNewOnly: function(item) {
return item.phantom === true;
},
filterRejects: function(item) {
return item.phantom || item.dirty;
},
getRejectRecords: function() {
return this.getData().createFiltered(this.filterRejects).getRange();
},
rejectChanges: function() {
var me = this,
recs = me.getRejectRecords(),
len = recs.length,
i, rec, toRemove, sorted, data, currentAutoSort;
Ext.suspendLayouts();
me.beginUpdate();
for (i = 0; i < len; i++) {
rec = recs[i];
if (rec.phantom) {
toRemove = toRemove || [];
toRemove.push(rec);
} else {
rec.reject();
}
}
if (toRemove) {
me.remove(toRemove);
for (i = 0 , len = toRemove.length; i < len; ++i) {
toRemove[i].reject();
}
}
recs = me.removed;
if (recs) {
len = recs.length;
sorted = !me.getRemoteSort() && me.isSorted();
if (sorted) {
data = me.getData();
currentAutoSort = data.getAutoSort();
data.setAutoSort(false);
}
for (i = len - 1; i >= 0; i--) {
rec = recs[i];
rec.reject();
if (!sorted) {
me.insert(rec.removedFrom || 0, rec);
}
}
if (sorted) {
data.setAutoSort(currentAutoSort);
me.add(recs);
}
recs.length = 0;
}
me.endUpdate();
Ext.resumeLayouts(true);
},
onDestroy: function() {
var me = this,
task = me.loadTask,
data = me.getData(),
source = data.getSource();
me.callParent();
me.setSession(null);
me.observers = null;
if (task) {
task.cancel();
me.loadTask = null;
}
me.clearData();
data.destroy();
if (source) {
source.destroy();
}
me.setData(null);
},
privates: {
onBeforeLoad: function(operation) {
this.callObservers('BeforeLoad', [
operation
]);
},
onRemoteFilterSet: function(filters, remoteFilter) {
if (filters) {
this.getData().setFilters(remoteFilter ? null : filters);
}
this.callParent([
filters,
remoteFilter
]);
},
onRemoteSortSet: function(sorters, remoteSort) {
var data = this.getData();
if (sorters) {
data.setSorters(remoteSort ? null : sorters);
}
data.setAutoGroup(!remoteSort);
this.callParent([
sorters,
remoteSort
]);
},
isMoving: function(records, getMap) {
var map = this.moveMap,
moving = 0,
len, i;
if (map) {
if (records) {
if (Ext.isArray(records)) {
for (i = 0 , len = records.length; i < len; ++i) {
moving += map[records[i].id] ? 1 : 0;
}
} else if (map[records.id]) {
++moving;
}
} else {
moving = getMap ? map : this.moveMapCount;
}
}
return moving;
},
setMoving: function(records, isMoving) {
var me = this,
map = me.moveMap || (me.moveMap = {}),
len = records.length,
i, id;
for (i = 0; i < len; ++i) {
id = records[i].id;
if (isMoving) {
if (map[id]) {
++map[id];
} else {
map[id] = 1;
++me.moveMapCount;
}
} else {
if (--map[id] === 0) {
delete map[id];
--me.moveMapCount;
}
}
}
if (me.moveMapCount === 0) {
me.moveMap = null;
}
},
processAssociation: function(records) {
var me = this,
associatedEntity = me.getAssociatedEntity();
if (associatedEntity) {
records = me.getRole().processLoad(me, associatedEntity, records, me.getSession());
}
return records;
}
}
});
Ext.define('Ext.data.reader.Array', {
extend: 'Ext.data.reader.Json',
alternateClassName: 'Ext.data.ArrayReader',
alias: 'reader.array',
config: {
totalProperty: undefined,
successProperty: undefined
},
createFieldAccessor: function(field) {
var oldMap = field.mapping,
index = field.hasMapping() ? oldMap : field.ordinal,
result;
field.mapping = index;
result = this.callParent(arguments);
field.mapping = oldMap;
return result;
},
getModelData: function(raw) {
return {};
}
});
Ext.define('Ext.data.ArrayStore', {
extend: 'Ext.data.Store',
alias: 'store.array',
alternateClassName: [
'Ext.data.SimpleStore'
],
requires: [
'Ext.data.proxy.Memory',
'Ext.data.reader.Array'
],
config: {
proxy: {
type: 'memory',
reader: 'array'
}
},
loadData: function(data, append) {
if (this.expandData) {
var r = [],
i = 0,
ln = data.length;
for (; i < ln; i++) {
r[r.length] = [
data[i]
];
}
data = r;
}
this.callParent([
data,
append
]);
}
});
Ext.define('Ext.data.StoreManager', {
extend: 'Ext.util.MixedCollection',
alternateClassName: [
'Ext.StoreMgr',
'Ext.data.StoreMgr',
'Ext.StoreManager'
],
singleton: true,
requires: [
'Ext.data.ArrayStore'
],
register: function() {
for (var i = 0,
s; (s = arguments[i]); i++) {
this.add(s);
}
},
unregister: function() {
for (var i = 0,
s; (s = arguments[i]); i++) {
this.remove(this.lookup(s));
}
},
lookup: function(store) {
if (Ext.isArray(store)) {
var fields = [
'field1'
],
expand = !Ext.isArray(store[0]),
data = store,
i, len;
if (expand) {
data = [];
for (i = 0 , len = store.length; i < len; ++i) {
data.push([
store[i]
]);
}
} else {
for (i = 2 , len = store[0].length; i <= len; ++i) {
fields.push('field' + i);
}
}
return new Ext.data.ArrayStore({
data: data,
fields: fields,
autoDestroy: true,
autoCreated: true,
expanded: expand
});
}
if (Ext.isString(store)) {
return this.get(store);
} else {
return Ext.Factory.store(store);
}
},
getKey: function(o) {
return o.storeId;
}
}, function() {
Ext.regStore = function(name, config) {
var store;
if (Ext.isObject(name)) {
config = name;
} else {
if (Ext.data.StoreManager.containsKey(name)) {
return Ext.data.StoreManager.lookup(name);
}
config.storeId = name;
}
if (config instanceof Ext.data.Store) {
store = config;
} else {
store = new Ext.data.Store(config);
}
Ext.data.StoreManager.register(store);
return store;
};
Ext.getStore = function(name) {
return Ext.data.StoreManager.lookup(name);
};
var emptyStore = Ext.regStore('ext-empty-store', {
proxy: 'memory',
useModelWarning: false
});
emptyStore.isEmptyStore = true;
emptyStore.add = emptyStore.remove = emptyStore.insert = emptyStore.load = emptyStore.loadData = function() {
Ext.Error.raise('Cannot modify ext-empty-store');
};
});
Ext.define('Ext.app.domain.Store', {
extend: 'Ext.app.EventDomain',
singleton: true,
requires: [
'Ext.data.AbstractStore'
],
type: 'store',
prefix: 'store.',
idMatchRe: /^\#/,
constructor: function() {
var me = this;
me.callParent();
me.monitor(Ext.data.AbstractStore);
},
match: function(target, selector) {
var result = false,
alias = target.alias;
if (selector === '*') {
result = true;
} else if (this.idMatchRe.test(selector)) {
result = target.getStoreId() === selector.substring(1);
} else if (alias) {
result = Ext.Array.indexOf(alias, this.prefix + selector) > -1;
}
return result;
}
});
Ext.define('Ext.app.route.Queue', {
queue: null,
token: null,
constructor: function(config) {
Ext.apply(this, config);
this.queue = new Ext.util.MixedCollection();
},
queueAction: function(route, args) {
this.queue.add({
route: route,
args: args
});
},
clearQueue: function() {
this.queue.removeAll();
},
runQueue: function() {
var queue = this.queue,
action = queue.removeAt(0),
route;
if (action) {
route = action && action.route;
route.execute(this.token, action.args, this.onActionExecute, this);
}
},
onActionExecute: function(clearQueue) {
if (clearQueue) {
this.clearQueue();
} else {
this.runQueue();
}
}
});
Ext.define('Ext.app.route.Route', {
action: null,
conditions: null,
controller: null,
allowInactive: false,
url: null,
before: null,
caseInsensitive: false,
matcherRegex: null,
paramMatchingRegex: null,
paramsInMatchString: null,
constructor: function(config) {
var me = this,
url;
Ext.apply(me, config, {
conditions: {}
});
url = me.url;
me.paramMatchingRegex = new RegExp(/:([0-9A-Za-z\_]*)/g);
me.paramsInMatchString = url.match(me.paramMatchingRegex) || [];
me.matcherRegex = me.createMatcherRegex(url);
},
recognize: function(url) {
var me = this,
controller = me.controller,
matches, args;
if ((me.allowInactive || controller.isActive()) && me.recognizes(url)) {
matches = me.matchesFor(url);
args = url.match(me.matcherRegex);
args.shift();
return Ext.applyIf(matches, {
controller: controller,
action: me.action,
historyUrl: url,
args: args
});
}
return false;
},
recognizes: function(url) {
return this.matcherRegex.test(url);
},
execute: function(token, argConfig, callback, scope) {
var args = argConfig.args || [],
before = this.before,
controller = this.controller,
beforeCallback = this.createCallback(argConfig, callback, scope);
if (before) {
args.push(beforeCallback);
if (Ext.isString(before)) {
before = this.before = controller[before];
}
if (before) {
before.apply(controller, args);
} else {
Ext.log.warn('The before action: ' + this.before + ' was not found on the controller. The action method will not be executed.');
}
} else {
beforeCallback.resume();
}
},
matchesFor: function(url) {
var params = {},
keys = this.paramsInMatchString,
values = url.match(this.matcherRegex),
i = 0,
len = keys.length;
values.shift();
for (; i < len; i++) {
params[keys[i].replace(':', '')] = values[i];
}
return params;
},
createMatcherRegex: function(url) {
var paramsInMatchString = this.paramsInMatchString,
conditions = this.conditions,
i = 0,
len = paramsInMatchString.length,
format = Ext.util.Format.format,
modifiers = this.caseInsensitive ? 'i' : '',
params, cond, matcher;
for (; i < len; i++) {
params = paramsInMatchString[i];
cond = conditions[params];
matcher = format('{0}', cond || '([%a-zA-Z0-9\\-\\_\\s,]+)');
url = url.replace(new RegExp(params), matcher);
}
return new RegExp('^' + url + '$', modifiers);
},
createCallback: function(args, callback, scope) {
var me = this;
scope = scope || me;
return {
resume: function() {
var controller = me.controller,
action = me.action,
resume;
if (Ext.isString(action)) {
action = controller[action];
}
args = args && args.args ? args.args : [];
resume = args.pop();
if (resume && !Ext.isObject(resume)) {
args.push(resume);
}
if (action) {
me.action = action;
action.apply(controller, args);
} else {
Ext.log.warn('The action: ' + me.action + ' was not found on the controller.');
}
if (callback) {
callback.call(scope);
}
},
stop: function(all) {
if (callback) {
callback.call(scope, all);
}
}
};
}
});
Ext.define('Ext.util.History', {
singleton: true,
alternateClassName: 'Ext.History',
mixins: {
observable: 'Ext.util.Observable'
},
useTopWindow: false,
constructor: function() {
var me = this;
me.hiddenField = null;
me.ready = false;
me.currentToken = null;
me.mixins.observable.constructor.call(me);
},
getHash: function() {
return this.win.location.hash.substr(1);
},
setHash: function(hash) {
try {
this.win.location.hash = hash;
this.currentToken = hash;
} catch (e) {}
},
handleStateChange: function(token) {
this.currentToken = token;
this.fireEvent('change', token);
},
startUp: function() {
var me = this;
me.currentToken = me.getHash();
if (Ext.supports.Hashchange) {
Ext.get(me.win).on('hashchange', me.onHashChange, me);
} else {
Ext.TaskManager.start({
fireIdleEvent: false,
run: me.onHashChange,
interval: 50,
scope: me
});
}
me.ready = true;
me.fireEvent('ready', me);
},
onHashChange: function() {
var me = this,
newHash = me.getHash();
if (newHash !== me.hash) {
me.hash = newHash;
me.handleStateChange(newHash);
}
},
init: function(onReady, scope) {
var me = this;
if (me.ready) {
Ext.callback(onReady, scope, [
me
]);
return;
}
if (!Ext.isReady) {
Ext.onInternalReady(function() {
me.init(onReady, scope);
});
return;
}
me.win = me.useTopWindow ? window.top : window;
me.hash = me.getHash();
if (onReady) {
me.on('ready', onReady, scope, {
single: true
});
}
me.startUp();
},
add: function(token, preventDuplicates) {
var me = this,
set = false;
if (preventDuplicates === false || me.getToken() !== token) {
me.setHash(token);
set = true;
}
return set;
},
back: function() {
var win = this.useTopWindow ? window.top : window;
win.history.go(-1);
},
forward: function() {
var win = this.useTopWindow ? window.top : window;
win.history.go(1);
},
getToken: function() {
return this.ready ? this.currentToken : this.getHash();
}
});
Ext.define('Ext.app.route.Router', {
singleton: true,
requires: [
'Ext.app.route.Queue',
'Ext.app.route.Route',
'Ext.util.History'
],
multipleToken: '|',
queueRoutes: true,
constructor: function() {
var History = Ext.util.History;
if (!History.ready) {
History.init();
}
History.on('change', this.onStateChange, this);
this.clear();
},
onStateChange: function(token) {
var me = this,
app = me.application,
routes = me.routes,
len = routes.length,
queueRoutes = me.queueRoutes,
tokens = token.split(me.multipleToken),
t = 0,
length = tokens.length,
i, queue, route, args, matched;
for (; t < length; t++) {
token = tokens[t];
matched = false;
if (queueRoutes) {
queue = new Ext.app.route.Queue({
token: token
});
}
for (i = 0; i < len; i++) {
route = routes[i];
args = route.recognize(token);
if (args) {
matched = true;
if (queueRoutes) {
queue.queueAction(route, args);
} else {
route.execute(token, args);
}
}
}
if (queueRoutes) {
queue.runQueue();
}
if (!matched && app) {
app.fireEvent('unmatchedroute', token);
}
}
},
connect: function(url, action, controller) {
var config = {
url: url,
action: action,
controller: controller
};
if (Ext.isObject(action)) {
Ext.merge(config, action);
}
this.routes.push(new Ext.app.route.Route(config));
},
disconnectAll: function(controller) {
var routes = this.routes,
len = routes.length,
newRoutes = [],
i, route;
for (i = 0; i < len; ++i) {
route = routes[i];
if (route.controller !== controller) {
newRoutes.push(route);
}
}
this.routes = newRoutes;
},
recognize: function(url) {
var routes = this.routes || [],
i = 0,
len = routes.length,
route, args;
for (; i < len; i++) {
route = routes[i];
args = route.recognize(url);
if (args) {
return {
route: route,
args: args
};
}
}
return false;
},
draw: function(fn) {
fn.call(this, this);
},
clear: function() {
this.routes = [];
}
});
Ext.define('Ext.app.Controller', {
extend: 'Ext.app.BaseController',
requires: [
'Ext.app.Util',
'Ext.data.StoreManager',
'Ext.ComponentManager',
'Ext.app.domain.Component',
'Ext.app.domain.Store',
'Ext.app.route.Router'
],
statics: {
strings: {
model: {
getter: 'getModel',
upper: 'Model'
},
view: {
getter: 'getView',
upper: 'View'
},
controller: {
getter: 'getController',
upper: 'Controller'
},
store: {
getter: 'getStore',
upper: 'Store'
},
profile: {
getter: 'getProfile',
upper: 'Profiles'
}
},
controllerRegex: /^(.*)\.controller\./,
createGetter: function(baseGetter, name) {
return function() {
return this[baseGetter](name);
};
},
getGetterName: function(name, kindUpper) {
var fn = 'get',
parts = name.split('.'),
numParts = parts.length,
index;
for (index = 0; index < numParts; index++) {
fn += Ext.String.capitalize(parts[index]);
}
fn += kindUpper;
return fn;
},
resolveNamespace: function(cls, data) {
var Controller = Ext.app.Controller,
ctrlRegex = Controller.controllerRegex,
className, namespace, match;
className = Ext.getClassName(cls);
namespace = data.$namespace || data.namespace || Ext.app.getNamespace(className) || ((match = ctrlRegex.exec(className)) && match[1]);
if (!namespace) {
Ext.log.warn("Missing namespace for " + className + ", please define it " + "in namespaces property of your Application class.");
}
return namespace;
},
processDependencies: function(cls, requires, namespace, kind, names) {
if (!names || !names.length) {
return;
}
var me = this,
strings = me.strings[kind],
o, absoluteName, shortName, name, j, subLn, getterName, getter;
if (!Ext.isArray(names)) {
names = [
names
];
}
for (j = 0 , subLn = names.length; j < subLn; j++) {
name = names[j];
o = me.getFullName(name, kind, namespace);
absoluteName = o.absoluteName;
shortName = o.shortName;
requires.push(absoluteName);
getterName = me.getGetterName(shortName, strings.upper);
cls[getterName] = getter = me.createGetter(strings.getter, name);
if (kind !== 'controller') {
getter['Ext.app.getter'] = true;
}
}
},
getFullName: function(name, kind, namespace) {
var shortName = name,
sep, absoluteName;
if ((sep = name.indexOf('@')) > 0) {
shortName = name.substring(0, sep);
absoluteName = name.substring(sep + 1) + '.' + shortName;
}
else if (name.indexOf('.') > 0 && (Ext.ClassManager.isCreated(name) || this.hasRegisteredPrefix(name))) {
absoluteName = name;
} else {
if (!namespace) {
Ext.log.warn("Cannot find namespace for " + kind + " " + name + ", " + "assuming it is fully qualified class name");
}
if (namespace) {
absoluteName = namespace + '.' + kind + '.' + name;
shortName = name;
} else {
absoluteName = name;
}
}
return {
absoluteName: absoluteName,
shortName: shortName
};
},
hasRegisteredPrefix: function(className) {
var inventory = Ext.ClassManager,
prefix = inventory.getPrefix(className);
return prefix && prefix !== className;
}
},
models: null,
views: null,
stores: null,
controllers: null,
config: {
application: null,
refs: null,
active: true,
moduleClassName: null
},
onClassExtended: function(cls, data, hooks) {
var onBeforeClassCreated = hooks.onBeforeCreated;
hooks.onBeforeCreated = function(cls, data) {
var Controller = Ext.app.Controller,
requires = [],
namespace, proto;
proto = cls.prototype;
namespace = Controller.resolveNamespace(cls, data);
if (namespace) {
proto.$namespace = namespace;
}
Controller.processDependencies(proto, requires, namespace, 'model', data.models);
Controller.processDependencies(proto, requires, namespace, 'view', data.views);
Controller.processDependencies(proto, requires, namespace, 'store', data.stores);
Controller.processDependencies(proto, requires, namespace, 'controller', data.controllers);
Ext.require(requires, Ext.Function.pass(onBeforeClassCreated, arguments, this));
};
},
constructor: function(config) {
this.initAutoGetters();
this.callParent(arguments);
},
normalizeRefs: function(refs) {
var me = this,
newRefs = [];
if (refs) {
if (Ext.isObject(refs)) {
Ext.Object.each(refs, function(key, value) {
if (Ext.isString(value)) {
value = {
selector: value
};
}
value.ref = key;
newRefs.push(value);
});
} else if (Ext.isArray(refs)) {
newRefs = Ext.Array.merge(newRefs, refs);
}
}
refs = me.refs;
if (refs) {
me.refs = null;
refs = me.normalizeRefs(refs);
if (refs) {
newRefs = Ext.Array.merge(newRefs, refs);
}
}
return newRefs;
},
getRefMap: function() {
var me = this,
refMap = me._refMap,
refs, ref, ln, i;
if (!refMap) {
refs = me.getRefs();
refMap = me._refMap = {};
if (refs) {
for (i = 0 , ln = refs.length; i < ln; i++) {
ref = refs[i];
refMap[ref.ref] = ref.selector;
}
}
}
return refMap;
},
applyRefs: function(refs) {
return this.normalizeRefs(Ext.clone(refs));
},
updateRefs: function(refs) {
if (refs) {
this.ref(refs);
}
},
initAutoGetters: function() {
var proto = this.self.prototype,
prop, fn;
for (prop in proto) {
fn = proto[prop];
if (fn && fn['Ext.app.getter']) {
fn.call(this);
}
}
},
doInit: function(app) {
var me = this;
if (!me._initialized) {
me.init(app);
me._initialized = true;
}
},
finishInit: function(app) {
var me = this,
controllers = me.controllers,
controller, i, l;
if (me._initialized && controllers && controllers.length) {
for (i = 0 , l = controllers.length; i < l; i++) {
controller = me.getController(controllers[i]);
controller.finishInit(app);
}
}
},
init: Ext.emptyFn,
onLaunch: Ext.emptyFn,
activate: function() {
this.setActive(true);
},
deactivate: function() {
this.setActive(false);
},
isActive: function() {
return this.getActive();
},
ref: function(refs) {
var me = this,
i = 0,
length = refs.length,
info, ref, fn;
refs = Ext.Array.from(refs);
me.references = me.references || [];
for (; i < length; i++) {
info = refs[i];
ref = info.ref;
fn = 'get' + Ext.String.capitalize(ref);
if (!me[fn]) {
me[fn] = Ext.Function.pass(me.getRef, [
ref,
info
], me);
}
me.references.push(ref.toLowerCase());
}
},
addRef: function(refs) {
this.ref(refs);
},
getRef: function(ref, info, config) {
var me = this,
refCache = me.refCache || (me.refCache = {}),
cached = refCache[ref];
info = info || {};
config = config || {};
Ext.apply(info, config);
if (info.forceCreate) {
return Ext.ComponentManager.create(info, 'component');
}
if (!cached) {
if (info.selector) {
refCache[ref] = cached = Ext.ComponentQuery.query(info.selector)[0];
}
if (!cached && info.autoCreate) {
refCache[ref] = cached = Ext.ComponentManager.create(info, 'component');
}
if (cached) {
cached.on('beforedestroy', function() {
refCache[ref] = null;
});
}
}
return cached;
},
hasRef: function(ref) {
var references = this.references;
return references && Ext.Array.indexOf(references, ref.toLowerCase()) !== -1;
},
getController: function(id) {
var app = this.getApplication();
if (id === this.getId()) {
return this;
}
return app && app.getController(id);
},
getStore: function(name) {
var storeId, store;
storeId = (name.indexOf('@') === -1) ? name : name.split('@')[0];
store = Ext.StoreManager.get(storeId);
if (!store) {
name = Ext.app.Controller.getFullName(name, 'store', this.$namespace);
if (name) {
store = Ext.create(name.absoluteName, {
storeId: storeId
});
}
}
return store;
},
getModel: function(model) {
var name = Ext.app.Controller.getFullName(model, 'model', this.$namespace),
ret = Ext.ClassManager.get(name.absoluteName);
if (!ret) {
ret = Ext.data.schema.Schema.lookupEntity(model);
}
return ret;
},
getProfile: function(name) {
name = Ext.app.Controller.getFullName(name, 'profile', this.$namespace);
return name;
},
getView: function(view) {
var name = Ext.app.Controller.getFullName(view, 'view', this.$namespace);
return name && Ext.ClassManager.get(name.absoluteName);
},
ensureId: function() {
var id = this.getId();
if (!id) {
this.setId(this.getModuleClassName(this.$className, 'controller'));
}
},
destroy: function(destroyRefs,
fromApp) {
var me = this,
app = me.application,
refCache, ref;
if (!fromApp && app) {
app.unregister(me);
}
me.application = null;
if (destroyRefs) {
refCache = me.refCache;
for (ref in refCache) {
if (refCache.hasOwnProperty(ref)) {
Ext.destroy(refCache[ref]);
}
}
}
me.callParent();
}
});
Ext.define('Ext.app.Application', {
extend: 'Ext.app.Controller',
requires: [
'Ext.util.History',
'Ext.util.MixedCollection'
],
isApplication: true,
scope: undefined,
namespaces: [],
paths: null,
appFolder: 'app',
config: {
name: '',
appProperty: 'app',
profiles: [],
currentProfile: null,
mainView: {
$value: null,
lazy: true
},
defaultToken: null,
glyphFontFamily: null
},
onClassExtended: function(cls, data, hooks) {
var Controller = Ext.app.Controller,
proto = cls.prototype,
requires = [],
onBeforeClassCreated, paths, namespace, ns, appFolder;
namespace = data.name || cls.superclass.name;
appFolder = data.appFolder || cls.superclass.appFolder;
if (namespace) {
data.$namespace = namespace;
Ext.app.addNamespaces(namespace);
}
if (data.namespaces) {
Ext.app.addNamespaces(data.namespaces);
}
if (!data['paths processed']) {
if (namespace && appFolder) {
Ext.Loader.setPath(namespace, appFolder);
}
paths = data.paths;
if (paths) {
for (ns in paths) {
if (paths.hasOwnProperty(ns)) {
Ext.Loader.setPath(ns, paths[ns]);
}
}
}
} else {
delete data['paths processed'];
}
Controller.processDependencies(proto, requires, namespace, 'profile', data.profiles);
proto.getDependencies(cls, data, requires);
if (requires.length) {
onBeforeClassCreated = hooks.onBeforeCreated;
hooks.onBeforeCreated = function(cls, data) {
var args = Ext.Array.clone(arguments);
Ext.require(requires, function() {
return onBeforeClassCreated.apply(this, args);
});
};
}
},
getDependencies: Ext.emptyFn,
constructor: function(config) {
var me = this;
Ext.app.route.Router.application = me;
me.callParent(arguments);
if (Ext.isEmpty(me.getName())) {
Ext.Error.raise("[Ext.app.Application] Name property is required");
}
me.doInit(me);
me.initNamespace();
Ext.Loader.setConfig({
enabled: true
});
var profiles = this.getProfiles();
if (profiles && profiles.length) {
Ext.require(profiles, this.onProfilesLoaded, this);
} else {
this.onProfilesReady();
}
},
onProfilesReady: function() {
var me = this;
me.initControllers();
me.onBeforeLaunch();
me.finishInitControllers();
},
initNamespace: function() {
var me = this,
appProperty = me.getAppProperty(),
ns;
ns = Ext.namespace(me.getName());
if (ns) {
ns.getApplication = function() {
return me;
};
if (appProperty) {
if (!ns[appProperty]) {
ns[appProperty] = me;
} else if (ns[appProperty] !== me) {
Ext.log.warn('An existing reference is being overwritten for ' + name + '.' + appProperty + '. See the appProperty config.');
}
}
}
},
initControllers: function() {
var me = this,
controllers = Ext.Array.from(me.controllers);
me.controllers = new Ext.util.MixedCollection();
for (var i = 0,
ln = controllers.length; i < ln; i++) {
me.getController(controllers[i]);
}
},
finishInitControllers: function() {
var me = this,
controllers, i, l;
controllers = me.controllers.getRange();
for (i = 0 , l = controllers.length; i < l; i++) {
controllers[i].finishInit(me);
}
},
launch: Ext.emptyFn,
onBeforeLaunch: function() {
var me = this,
History = Ext.util.History,
defaultToken = me.getDefaultToken(),
currentProfile = me.getCurrentProfile(),
controllers, c, cLen, controller, token;
me.initMainView();
if (currentProfile) {
currentProfile.launch();
}
me.launch.call(me.scope || me);
me.launched = true;
me.fireEvent('launch', me);
controllers = me.controllers.items;
cLen = controllers.length;
for (c = 0; c < cLen; c++) {
controller = controllers[c];
controller.onLaunch(me);
}
if (!History.ready) {
History.init();
}
token = History.getToken();
if (token) {
Ext.app.route.Router.onStateChange(token);
} else if (defaultToken) {
History.add(defaultToken);
}
},
getModuleClassName: function(name, kind) {
return Ext.app.Controller.getFullName(name, kind, this.getName()).absoluteName;
},
initMainView: function() {
var me = this,
currentProfile = me.getCurrentProfile(),
mainView;
if (currentProfile) {
mainView = currentProfile.getMainView();
}
if (mainView) {
me.setMainView(mainView);
} else {
me.getMainView();
}
},
applyMainView: function(value) {
var view;
view = this.getView(value);
return view.create();
},
createController: function(name) {
return this.getController(name);
},
destroyController: function(controller) {
if (typeof controller === 'string') {
controller = this.getController(controller, true);
}
Ext.destroy(controller);
},
getController: function(name,
preventCreate) {
var me = this,
controllers = me.controllers,
className, controller, len, i, c, all;
controller = controllers.get(name);
if (!controller) {
all = controllers.items;
for (i = 0 , len = all.length; i < len; ++i) {
c = all[i];
className = c.getModuleClassName();
if (className && className === name) {
controller = c;
break;
}
}
}
if (!controller && !preventCreate) {
className = me.getModuleClassName(name, 'controller');
controller = Ext.create(className, {
application: me,
moduleClassName: name
});
controllers.add(controller);
if (me._initialized) {
controller.doInit(me);
}
}
return controller;
},
unregister: function(controller) {
this.controllers.remove(controller);
},
getApplication: function() {
return this;
},
destroy: function(destroyRefs) {
var me = this,
controllers = me.controllers,
ns = Ext.namespace(me.getName()),
appProp = me.getAppProperty();
Ext.destroy(me.viewport);
if (controllers) {
controllers.each(function(controller) {
controller.destroy(destroyRefs, true);
});
}
me.controllers = null;
me.callParent([
destroyRefs,
true
]);
if (ns && ns[appProp] === me) {
delete ns[appProp];
}
},
updateGlyphFontFamily: function(fontFamily) {
Ext.setGlyphFontFamily(fontFamily);
},
applyProfiles: function(profiles) {
var me = this;
return Ext.Array.map(profiles, function(profile) {
return me.getModuleClassName(profile, "profile");
});
},
onProfilesLoaded: function() {
var me = this,
profiles = me.getProfiles(),
length = profiles.length,
instances = [],
current, i, profileDeps, requires, controllers, profileControllers, views, profileViews, stores, profileStores, models, profileModels;
for (i = 0; i < length; i++) {
instances[i] = Ext.create(profiles[i], {
application: me
});
if (instances[i].isActive() && !current) {
current = instances[i];
profileDeps = current.getDependencies();
requires = profileDeps.all;
me.setCurrentProfile(current);
profileControllers = profileDeps.controller;
if (profileControllers.length) {
controllers = me.controllers = (me.controllers || []);
controllers.push.apply(controllers, profileControllers);
}
profileViews = profileDeps.view;
if (profileViews.length) {
views = me.views = (me.views || []);
views.push.apply(views, profileViews);
}
profileStores = profileDeps.store;
if (profileStores.length) {
stores = me.stores = (me.stores || []);
stores.push.apply(stores, profileStores);
}
profileModels = profileDeps.model;
if (profileModels.length) {
models = me.models = (me.models || []);
models.push.apply(models, profileModels);
}
}
}
if (requires) {
Ext.require(requires, me.onProfilesReady, me);
} else {
me.onProfilesReady();
}
}
});
Ext.application = function(config) {
var createApp = function(App) {
Ext.onReady(function() {
Ext.app.Application.instance = new App();
});
},
paths = config.paths,
ns;
if (typeof config === "string") {
Ext.require(config, function() {
createApp(Ext.ClassManager.get(config));
});
} else {
config = Ext.apply({
extend: 'Ext.app.Application'
},
config);
Ext.Loader.setPath(config.name, config.appFolder || 'app');
if (paths) {
for (ns in paths) {
if (paths.hasOwnProperty(ns)) {
Ext.Loader.setPath(ns, paths[ns]);
}
}
}
config['paths processed'] = true;
Ext.define(config.name + ".$application", config, function() {
createApp(this);
});
}
};
Ext.define('Ext.overrides.app.Application', {
override: 'Ext.app.Application',
uses: [
'Ext.tip.QuickTipManager'
],
autoCreateViewport: false,
config: {
enableQuickTips: true
},
applyMainView: function(value) {
var view = this.getView(value),
proto = view.prototype,
config, plugins;
if (!proto.isViewport) {
plugins = proto.plugins;
plugins = [
'viewport'
].concat(plugins ? Ext.Array.from(plugins, true) : []);
config = {
plugins: plugins
};
}
return view.create(config);
},
getDependencies: function(cls, data, requires) {
var Controller = Ext.app.Controller,
proto = cls.prototype,
namespace = data.$namespace,
viewportClass = data.autoCreateViewport;
if (viewportClass) {
if (!namespace) {
Ext.Error.raise("[Ext.app.Application] Can't resolve namespace for " + data.$className + ", did you forget to specify 'name' property?");
}
if (viewportClass === true) {
viewportClass = 'Viewport';
} else {
requires.push('Ext.plugin.Viewport');
}
Controller.processDependencies(proto, requires, namespace, 'view', viewportClass);
}
},
onBeforeLaunch: function() {
var me = this,
autoCreateViewport = me.autoCreateViewport;
if (me.getEnableQuickTips()) {
me.initQuickTips();
}
if (autoCreateViewport) {
me.initViewport();
}
this.callParent(arguments);
},
getViewportName: function() {
var name = null,
autoCreate = this.autoCreateViewport;
if (autoCreate) {
name = (autoCreate === true) ? 'Viewport' : autoCreate;
}
return name;
},
initViewport: function() {
this.setMainView(this.getViewportName());
},
initQuickTips: function() {
Ext.tip.QuickTipManager.init();
}
});
Ext.define('Ext.app.Profile', {
mixins: {
observable: "Ext.mixin.Observable"
},
config: {
namespace: 'auto',
name: 'auto',
mainView: {
$value: null,
lazy: true
},
application: null,
controllers: [],
models: [],
views: [],
stores: []
},
constructor: function(config) {
this.initConfig(config);
this.mixins.observable.constructor.apply(this, arguments);
},
isActive: function() {
return false;
},
launch: Ext.emptyFn,
applyNamespace: function(name) {
if (name == 'auto') {
name = this.getName();
}
return name.toLowerCase();
},
applyName: function(name) {
if (name == 'auto') {
var pieces = this.$className.split('.');
name = pieces[pieces.length - 1];
}
return name;
},
onClassExtended: function(cls, data, hooks) {
var onBeforeClassCreated = hooks.onBeforeCreated;
hooks.onBeforeCreated = function(cls, data) {
var Controller = Ext.app.Controller,
requires = [],
proto = cls.prototype,
namespace;
namespace = Controller.resolveNamespace(cls, data);
Controller.processDependencies(proto, requires, namespace, 'model', data.models);
Controller.processDependencies(proto, requires, namespace, 'view', data.views);
Controller.processDependencies(proto, requires, namespace, 'store', data.stores);
Controller.processDependencies(proto, requires, namespace, 'controller', data.controllers);
Ext.require(requires, Ext.Function.pass(onBeforeClassCreated, arguments, this));
};
},
getDependencies: function() {
var allClasses = [],
appName = this.getApplication().getName(),
namespace = this.getNamespace(),
map = {
model: this.getModels(),
view: this.getViews(),
controller: this.getControllers(),
store: this.getStores()
},
classType, classNames;
for (classType in map) {
classNames = [];
Ext.each(map[classType], function(className) {
if (Ext.isString(className)) {
if (Ext.isString(className) && (Ext.ClassManager.getPrefix(className) === "" || className === appName)) {
className = appName + '.' + classType + '.' + namespace + '.' + className;
}
classNames.push(className);
allClasses.push(className);
}
}, this);
map[classType] = classNames;
}
map.all = allClasses;
return map;
}
});
Ext.define('Ext.app.domain.View', {
extend: 'Ext.app.EventDomain',
isInstance: true,
constructor: function(controller) {
this.callParent(arguments);
this.controller = controller;
this.monitoredClasses = [
Ext.Component
];
},
match: function(target, selector, controller) {
var out = false;
if (selector === '#') {
out = controller === target.getController();
} else {
out = target.is(selector);
}
return out;
},
destroy: function() {
this.controller = null;
this.callParent();
}
});
Ext.define('Ext.app.ViewController', {
extend: 'Ext.app.BaseController',
requires: [
'Ext.app.domain.View'
],
mixins: [
'Ext.mixin.Factoryable'
],
isViewController: true,
factoryConfig: {
type: 'controller'
},
config: {
closeViewAction: 'destroy'
},
constructor: function() {
this.compDomain = new Ext.app.domain.View(this);
this.callParent(arguments);
},
beforeInit: Ext.emptyFn,
init: Ext.emptyFn,
initViewModel: Ext.emptyFn,
destroy: function() {
var me = this,
domain = me.compDomain;
if (domain) {
domain.unlisten(me);
domain.destroy();
}
me.compDomain = me.view = null;
me.callParent();
},
closeView: function() {
var view = this.getView(),
action;
if (view) {
action = this.getCloseViewAction();
view[action]();
}
},
control: function(selectors, listeners) {
var obj = selectors;
if (Ext.isString(selectors)) {
obj = {};
obj[selectors] = listeners;
}
this.compDomain.listen(obj, this);
},
listen: function(to, controller) {
var component = to.component;
if (component) {
to = Ext.apply({}, to);
delete to.component;
this.control(component);
}
this.callParent([
to,
controller
]);
},
getReferences: function() {
return this.view.getReferences();
},
getView: function() {
return this.view;
},
lookupReference: function(key) {
var view = this.view;
return view && view.lookupReference(key);
},
getSession: function() {
var view = this.view;
return view && view.lookupSession();
},
getViewModel: function() {
var view = this.view;
return view && view.lookupViewModel();
},
getStore: function(name) {
var viewModel = this.getViewModel();
return viewModel ? viewModel.getStore(name) : null;
},
fireViewEvent: function(eventName) {
var view = this.view,
result = false;
if (view) {
result = view.fireEvent.apply(view, arguments);
}
return result;
},
privates: {
view: null,
ensureId: function() {
var id = this.getId();
if (!id) {
this.setId(Ext.id(null, 'controller-'));
}
},
attachReference: function(component) {
var view = this.view;
if (view) {
view.attachReference(component);
}
},
clearReference: function(ref) {
var view = this.view;
if (view) {
view.clearReference(ref);
}
},
clearReferences: function() {
var view = this.view;
if (view) {
view.clearReferences();
}
},
setView: function(view) {
this.view = view;
if (!this.beforeInit.$nullFn) {
this.beforeInit(view);
}
}
}
});
Ext.define('Ext.util.Bag', {
isBag: true,
constructor: function() {
this.items = [];
this.map = {};
},
generation: 0,
length: 0,
add: function(item) {
var me = this,
id = me.getKey(item),
map = me.map,
items = me.items,
idx = map[id],
old;
if (idx === undefined) {
items.push(item);
map[id] = me.length++;
old = item;
} else {
old = items[idx];
items[idx] = item;
}
++me.generation;
return old;
},
clear: function() {
var me = this,
needsClear = me.generation || me.length,
ret = needsClear ? me.items : [];
if (needsClear) {
me.items = [];
me.length = 0;
me.map = {};
++me.generation;
}
return ret;
},
clone: function() {
var me = this,
ret = new me.self(),
len = me.length;
if (len) {
Ext.apply(ret.map, me.map);
ret.items = me.items.slice();
ret.length = me.length;
}
return ret;
},
contains: function(item) {
var ret = false,
map = this.map,
key;
if (item != null) {
key = this.getKey(item);
if (key in map) {
ret = this.items[map[key]] === item;
}
}
return ret;
},
containsKey: function(key) {
return key in this.map;
},
destroy: function() {
this.items = this.map = null;
this.callParent();
},
getAt: function(index) {
var out = null;
if (index < this.length) {
out = this.items[index];
}
return out;
},
getByKey: function(key) {
var map = this.map,
ret = null;
if (key in map) {
ret = this.items[map[key]];
}
return ret;
},
getCount: function() {
return this.length;
},
getKey: function(item) {
return item.id || item.getId();
},
remove: function(item) {
var me = this,
map = me.map,
items = me.items,
old = null,
idx, id, last;
if (me.length) {
idx = map[id = me.getKey(item)];
if (idx !== undefined) {
delete map[id];
old = items[idx];
last = items.pop();
if (idx < --me.length) {
items[idx] = last;
map[me.getKey(last)] = idx;
}
++me.generation;
}
}
return old;
},
removeByKey: function(key) {
var item = this.getByKey(key);
if (item) {
this.remove(item);
}
return item || null;
},
sort: function(fn) {
var me = this,
items = me.items,
n = items.length,
item;
if (n) {
Ext.Array.sort(items, fn);
me.map = {};
while (n-- > 0) {
item = items[n];
me.map[me.getKey(item)] = n;
}
++me.generation;
}
}
});
Ext.define('Ext.util.Scheduler', {
mixins: [
'Ext.mixin.Observable'
],
requires: [
'Ext.util.Bag'
],
busyCounter: 0,
lastBusyCounter: 0,
destroyed: false,
firing: null,
notifyIndex: -1,
nextId: 0,
orderedItems: null,
passes: 0,
scheduledCount: 0,
validIdRe: null,
config: {
cycleLimit: 5,
preSort: null,
tickDelay: 5
},
constructor: function(config) {
if (Ext.util.Scheduler.instances) {
Ext.util.Scheduler.instances.push(this);
} else {
Ext.util.Scheduler.instances = [
this
];
}
this.id = Ext.util.Scheduler.count = (Ext.util.Scheduler.count || 0) + 1;
this.mixins.observable.constructor.call(this, config);
this.items = new Ext.util.Bag();
},
destroy: function() {
var me = this,
timer = me.timer;
if (timer) {
window.clearTimeout(timer);
me.timer = null;
}
me.destroyed = true;
me.items.destroy();
me.items = me.orderedItems = null;
me.destroy = Ext.emptyFn;
Ext.Array.remove(Ext.util.Scheduler.instances, this);
},
add: function(item) {
var me = this,
items = me.items;
if (items === me.firing) {
me.items = items = items.clone();
}
item.id = item.id || ++me.nextId;
item.scheduler = me;
items.add(item);
if (!me.sortMap) {
me.orderedItems = null;
}
},
remove: function(item) {
var me = this,
items = me.items;
if (me.destroyed) {
return;
}
if (me.sortMap) {
Ext.Error.raise('Items cannot be removed during sort');
}
if (items === me.firing) {
me.items = items = items.clone();
}
if (item.scheduled) {
me.unscheduleItem(item);
item.scheduled = false;
}
items.remove(item);
me.orderedItems = null;
},
sort: function() {
var me = this,
items = me.items,
sortMap = {},
preSort = me.getPreSort(),
i, item;
me.orderedItems = [];
me.sortMap = sortMap;
me.sortStack = [];
if (preSort) {
items.sort(preSort);
}
items = items.items;
for (i = 0; i < items.length; ++i) {
item = items[i];
if (!sortMap[item.id]) {
me.sortItem(item);
}
}
me.sortMap = null;
me.sortStack = null;
},
sortItem: function(item) {
var me = this,
sortMap = me.sortMap,
orderedItems = me.orderedItems,
itemId;
if (!item.scheduler) {
me.add(item);
}
itemId = item.id;
if (item.scheduler !== me) {
Ext.Error.raise('Item ' + itemId + ' belongs to another Scheduler');
}
me.sortStack.push(item);
if (sortMap[itemId] === 0) {
for (var cycle = [],
i = 0; i < me.sortStack.length; ++i) {
cycle[i] = me.sortStack[i].getFullName();
}
Ext.Error.raise('Dependency cycle detected: ' + cycle.join('\n --> '));
}
if (!(itemId in sortMap)) {
sortMap[itemId] = 0;
if (!item.sort.$nullFn) {
item.sort();
}
sortMap[itemId] = 1;
item.order = me.orderedItems.length;
orderedItems.push(item);
}
me.sortStack.pop();
return me;
},
sortItems: function(items) {
var me = this,
sortItem = me.sortItem;
if (items) {
if (items instanceof Array) {
Ext.each(items, sortItem, me);
} else {
Ext.Object.eachValue(items, sortItem, me);
}
}
return me;
},
applyPreSort: function(preSort) {
if (typeof preSort === 'function') {
return preSort;
}
var parts = preSort.split(','),
direction = [],
length = parts.length,
c, i, s;
for (i = 0; i < length; ++i) {
direction[i] = 1;
s = parts[i];
if ((c = s.charAt(0)) === '-') {
direction[i] = -1;
} else if (c !== '+') {
c = 0;
}
if (c) {
parts[i] = s.substring(1);
}
}
return function(lhs, rhs) {
var ret = 0,
i, prop, v1, v2;
for (i = 0; !ret && i < length; ++i) {
prop = parts[i];
v1 = lhs[prop];
v2 = rhs[prop];
ret = direction[i] * ((v1 < v2) ? -1 : ((v2 < v1) ? 1 : 0));
}
return ret;
};
},
notify: function() {
var me = this,
timer = me.timer,
cyclesLeft = me.getCycleLimit(),
globalEvents = Ext.GlobalEvents,
busyCounter, i, item, len, queue, firedEvent;
if (timer) {
window.clearTimeout(timer);
me.timer = null;
}
if (me.firing) {
Ext.Error.raise('Notify cannot be called recursively');
}
while (me.scheduledCount) {
if (cyclesLeft) {
--cyclesLeft;
} else {
me.firing = null;
if (me.onCycleLimitExceeded) {
me.onCycleLimitExceeded();
}
break;
}
if (!firedEvent) {
firedEvent = true;
if (globalEvents.hasListeners.beforebindnotify) {
globalEvents.fireEvent('beforebindnotify', me);
}
}
++me.passes;
if (!(queue = me.orderedItems)) {
me.sort();
queue = me.orderedItems;
}
len = queue.length;
if (len) {
me.firing = me.items;
for (i = 0; i < len; ++i) {
item = queue[i];
if (item.scheduled) {
item.scheduled = false;
--me.scheduledCount;
me.notifyIndex = i;
item.react();
if (!me.scheduledCount) {
break;
}
}
}
}
}
me.firing = null;
me.notifyIndex = -1;
if ((busyCounter = me.busyCounter) !== me.lastBusyCounter) {
if (!(me.lastBusyCounter = busyCounter)) {
me.fireEvent('idle', me);
}
}
},
onTick: function() {
this.timer = null;
this.notify();
},
scheduleItem: function(item) {
var me = this;
++me.scheduledCount;
if (!me.timer && !me.firing) {
me.scheduleTick();
}
},
scheduleTick: function() {
var me = this;
if (!me.destroyed && !me.timer) {
me.timer = Ext.Function.defer(me.onTick, me.getTickDelay(), me);
}
},
unscheduleItem: function(item) {
if (this.scheduledCount) {
--this.scheduledCount;
}
},
adjustBusy: function(adjustment) {
var me = this,
busyCounter = me.busyCounter + adjustment;
me.busyCounter = busyCounter;
if (busyCounter) {
if (!me.lastBusyCounter) {
me.lastBusyCounter = busyCounter;
me.fireEvent('busy', me);
}
} else if (me.lastBusyCounter && !me.timer) {
me.scheduleTick();
}
},
isBusy: function() {
return !this.isIdle();
},
isIdle: function() {
return !(this.busyCounter + this.lastBusyCounter);
},
debugHooks: {
$enabled: false,
onCycleLimitExceeded: function() {
Ext.Error.raise('Exceeded cycleLimit ' + this.getCycleLimit());
},
scheduleItem: function(item) {
if (!item) {
Ext.Error.raise('scheduleItem: Invalid argument');
}
Ext.log('Schedule item: ' + item.getFullName() + ' - ' + (this.scheduledCount + 1));
if (item.order <= this.notifyIndex) {
Ext.log.warn('Suboptimal order: ' + item.order + ' < ' + this.notifyIndex);
}
this.callParent([
item
]);
},
unscheduleItem: function(item) {
if (!this.scheduledCount) {
Ext.Error.raise('Invalid scheduleCount');
}
this.callParent([
item
]);
Ext.log('Unschedule item: ' + item.getFullName() + ' - ' + this.scheduledCount);
}
}
});
Ext.define('Ext.data.Batch', {
mixins: {
observable: 'Ext.mixin.Observable'
},
config: {
pauseOnException: false
},
current: -1,
total: 0,
running: false,
complete: false,
exception: false,
constructor: function(config) {
var me = this;
me.mixins.observable.constructor.call(me, config);
me.operations = [];
me.exceptions = [];
},
add: function(operation) {
var me = this,
i, len;
if (Ext.isArray(operation)) {
for (i = 0 , len = operation.length; i < len; ++i) {
me.add(operation[i]);
}
} else {
me.total++;
operation.setBatch(me);
me.operations.push(operation);
}
return me;
},
sort: function() {
this.operations.sort(this.sortFn);
},
sortFn: function(operation1, operation2) {
var ret = operation1.order - operation2.order;
if (ret) {
return ret;
}
var entityType1 = operation1.entityType,
entityType2 = operation2.entityType,
rank;
if (!entityType1 || !entityType2) {
return 0;
}
if (!(rank = entityType1.rank)) {
entityType1.schema.rankEntities();
rank = entityType1.rank;
}
return (rank - entityType2.rank) * operation1.foreignKeyDirection;
},
start: function(
index) {
var me = this;
if (!me.operations.length || me.running) {
return me;
}
me.exceptions.length = 0;
me.exception = false;
me.running = true;
return me.runOperation(Ext.isDefined(index) ? index : me.current + 1);
},
retry: function() {
return this.start(this.current);
},
runNextOperation: function() {
var me = this;
if (me.running) {
me.runOperation(me.current + 1);
}
return me;
},
pause: function() {
this.running = false;
return this;
},
getOperations: function() {
return this.operations;
},
getExceptions: function() {
return this.exceptions;
},
getCurrent: function() {
var out = null,
current = this.current;
if (!(current === -1 || this.complete)) {
out = this.operations[current];
}
return out;
},
getTotal: function() {
return this.total;
},
isRunning: function() {
return this.running;
},
isComplete: function() {
return this.complete;
},
hasException: function() {
return this.exception;
},
runOperation: function(index) {
var me = this,
operations = me.operations,
operation = operations[index];
if (operation === undefined) {
me.running = false;
me.complete = true;
me.fireEvent('complete', me, operations[operations.length - 1]);
} else {
me.current = index;
operation.setInternalCallback(me.onOperationComplete);
operation.setInternalScope(me);
operation.execute();
}
return me;
},
onOperationComplete: function(operation) {
var me = this,
exception = operation.hasException();
if (exception) {
me.exception = true;
me.exceptions.push(operation);
me.fireEvent('exception', me, operation);
}
if (exception && me.getPauseOnException()) {
me.pause();
} else {
me.fireEvent('operationcomplete', me, operation);
me.runNextOperation();
}
}
});
Ext.define('Ext.data.matrix.Slice', {
stub: null,
constructor: function(side, id) {
this.id = id;
this.side = side;
this.members = {};
},
attach: function(store) {
var me = this;
Ext.Assert.falsey(me.store, 'Store is already attached');
me.store = store;
store.matrix = me;
store.on('load', me.onStoreLoad, me, {
single: true
});
},
changeId: function(newId) {
var me = this,
oldId = me.id,
side = me.side,
slices = side.slices,
slice = slices[oldId],
members = slice.members,
index = side.index,
otherSlices = side.inverse.slices,
assoc, otherId, otherMembers;
me.id = newId;
slices[newId] = slice;
delete slices[oldId];
for (otherId in members) {
assoc = members[otherId];
assoc[index] = newId;
otherMembers = otherSlices[otherId].members;
otherMembers[newId] = otherMembers[oldId];
delete otherMembers[oldId];
}
},
onStoreLoad: function(store) {
this.update(store.getData().items, 0);
},
update: function(recordsOrIds, state) {
if (!(recordsOrIds instanceof Array)) {
Ext.Error.raise('Only array of records or record ids are supported');
}
var me = this,
MatrixSlice = Ext.data.matrix.Slice,
side = me.side,
assocIndex = side.index,
length = recordsOrIds.length,
id = me.id,
members = me.members,
otherSide = side.inverse,
otherSlices = otherSide.slices,
assoc, call, i, item, otherId, otherSlice, record;
for (i = 0; i < length; ++i) {
call = record = null;
item = recordsOrIds[i];
otherId = item.isEntity ? (record = item).id : item;
assoc = members[otherId];
if (state < 0 && assoc && assoc[2] === 1) {
delete members[otherId];
otherSlice = otherSlices[otherId];
if (otherSlice) {
delete otherSlice.members[id];
}
call = 1;
} else {
if (!assoc) {
assoc = [
otherId,
otherId,
state
];
assoc[assocIndex] = id;
members[otherId] = assoc;
otherSlice = otherSlices[otherId];
if (!otherSlice) {
otherSlices[otherId] = otherSlice = new MatrixSlice(otherSide, otherId);
}
otherSlice.members[id] = assoc;
call = 1;
} else if (state !== assoc[2] && state !== 0) {
assoc[2] = state;
otherSlice = otherSlices[otherId];
call = 1;
}
}
if (call) {
if (me.notify) {
me.notify.call(me.scope, me, otherId, state);
}
if (otherSlice && otherSlice.notify) {
otherSlice.notify.call(otherSlice.scope, otherSlice, id, state);
}
}
}
},
destroy: function() {
var me = this,
store = me.store;
if (store) {
store.matrix = null;
store.un('load', me.onStoreLoad, me);
}
me.notify = me.scope = me.store = me.side = me.members = null;
me.callParent();
}
});
Ext.define('Ext.data.matrix.Side', {
requires: [
'Ext.data.matrix.Slice'
],
constructor: function(matrix, index, role) {
var me = this;
me.matrix = matrix;
me.index = index;
me.role = role;
me.slices = {};
},
get: function(id1, id2) {
var me = this,
slices = me.slices,
slice = slices[id1] || (slices[id1] = new Ext.data.matrix.Slice(me, id1));
return (id2 || id2 === 0) ? slice.members[id2] : slice;
},
update: function(id1, id2, state) {
var slice = this.get(id1);
return slice.update(id2, state);
},
destroy: function() {
var me = this,
slices = me.slices,
id;
for (id in slices) {
slices[id].destroy();
}
me.inverse = me.matrix = me.role = me.slices = null;
me.callParent();
}
});
Ext.define('Ext.data.matrix.Matrix', {
requires: [
'Ext.data.matrix.Side'
],
constructor: function(session, matrix) {
var me = this,
association = matrix.isManyToMany ? matrix : session.getSchema().getAssociation(matrix),
Side = Ext.data.matrix.Side,
left = new Side(me, 0, association.left),
right = new Side(me, 1, association.right);
Ext.Assert.truthy(association.isManyToMany, 'Association is not many-to-many');
me.association = association;
me.session = session;
me.left = left;
me.right = right;
left.inverse = right;
right.inverse = left;
},
update: function(id1, id2, state) {
return this.left.update(id1, id2, state);
},
destroy: function() {
var me = this;
me.left.destroy();
me.right.destroy();
me.association = me.session = me.left = me.right = null;
me.callParent();
}
});
Ext.define('Ext.data.session.ChangesVisitor', {
constructor: function(session) {
var me = this,
crud;
me.session = session;
crud = session.getCrudProperties();
me.result = null;
me.writerOptions = {};
me.createKey = crud.create;
me.readKey = crud.read;
me.updateKey = crud.update;
me.dropKey = crud.drop;
},
onDirtyRecord: function(record) {
var me = this,
crud = me.crud,
created = record.phantom,
dropped = record.dropped,
updated = !created && !dropped,
type = record.$className,
prop = (created || dropped) ? 'allDataOptions' : 'partialDataOptions',
writerOptions = me.writerOptions,
name = record.entityName,
options, bucket, entry, result;
if (created && dropped) {
return false;
}
crud = created ? me.createKey : (dropped ? me.dropKey : me.updateKey);
writerOptions = writerOptions[type] || (writerOptions[type] = {});
if (dropped) {
if (!(options = writerOptions.drop)) {
writerOptions.drop = options = {
all: record.getProxy().getWriter().getWriteAllFields()
};
}
if (!options.all) {
entry = record.id;
}
}
if (!entry) {
if (!(options = writerOptions[prop])) {
options = record.getProxy().getWriter().getConfig(prop);
writerOptions[prop] = options = Ext.Object.chain(options);
me.setupOptions(options);
}
entry = record.getData(options);
}
result = me.result || (me.result = {});
bucket = result[name] || (result[name] = {});
bucket = bucket[crud] || (bucket[crud] = []);
bucket.push(entry);
},
setupOptions: function(options) {
options.serialize = true;
},
onMatrixChange: function(association, id1, id2, state) {
var me = this,
name = association.left.type,
assocName = association.right.role,
operation = state < 0 ? me.dropKey : me.createKey,
bucket, result;
result = me.result || (me.result = {});
bucket = result[name] || (result[name] = {});
bucket = bucket[assocName] || (bucket[assocName] = {});
bucket = bucket[operation] || (bucket[operation] = {});
bucket = bucket[id1] || (bucket[id1] = []);
bucket.push(id2);
}
});
Ext.define('Ext.data.session.ChildChangesVisitor', {
extend: 'Ext.data.session.ChangesVisitor',
constructor: function() {
this.seen = {};
this.callParent(arguments);
},
setupOptions: function(options) {
this.callParent([
options
]);
options.serialize = false;
},
onDirtyRecord: function(record) {
if (this.callParent(arguments) !== false) {
if (!record.$source && (record.dropped || !record.phantom)) {
this.readEntity(record);
}
}
},
readEntity: function(record) {
var me = this,
readKey = me.readKey,
name = record.entityName,
id = record.id,
seen = me.seen,
seenKey = name + id,
result, bucket;
if (seen[seenKey]) {
return;
}
seen[seenKey] = true;
result = me.result || (me.result = {});
bucket = result[name] || (result[name] = {});
bucket = bucket[readKey] || (bucket[readKey] = []);
bucket.push(Ext.apply({}, record.modified, record.data));
}
});
Ext.define('Ext.data.session.BatchVisitor', {
map: null,
constructor: function(batch) {
this.batch = batch;
},
getBatch: function(sort) {
var map = this.map,
batch = this.batch,
bucket, entity, name, operation, proxy;
if (map) {
if (!batch) {
batch = new Ext.data.Batch();
}
for (name in map) {
bucket = map[name];
entity = bucket.entity;
proxy = entity.getProxy();
delete bucket.entity;
for (operation in bucket) {
operation = proxy.createOperation(operation, {
records: bucket[operation]
});
operation.entityType = entity;
batch.add(operation);
}
}
}
if (batch && sort !== false) {
batch.sort();
}
return batch;
},
onDirtyRecord: function(record) {
var me = this,
operation = record.phantom ? 'create' : (record.dropped ? 'destroy' : 'update'),
name = record.$className,
map = (me.map || (me.map = {})),
bucket = (map[name] || (map[name] = {
entity: record.self
}));
bucket = bucket[operation] || (bucket[operation] = []);
bucket.push(record);
}
});
Ext.define('Ext.data.Session', {
requires: [
'Ext.data.schema.Schema',
'Ext.data.Batch',
'Ext.data.matrix.Matrix',
'Ext.data.session.ChangesVisitor',
'Ext.data.session.ChildChangesVisitor',
'Ext.data.session.BatchVisitor'
],
isSession: true,
config: {
schema: 'default',
parent: null,
autoDestroy: true,
crudProperties: {
create: 'C',
read: 'R',
update: 'U',
drop: 'D'
}
},
destroyed: false,
crudOperations: [
{
type: 'R',
entityMethod: 'readEntities'
},
{
type: 'C',
entityMethod: 'createEntities'
},
{
type: 'U',
entityMethod: 'updateEntities'
},
{
type: 'D',
entityMethod: 'dropEntities'
}
],
crudKeys: {
C: 1,
R: 1,
U: 1,
D: 1
},
constructor: function(config) {
var me = this;
me.data = {};
me.matrices = {};
me.identifierCache = {};
me.recordCreator = me.recordCreator.bind(me);
me.initConfig(config);
},
destroy: function() {
var me = this,
matrices = me.matrices,
data = me.data,
entityName, entities, record, id;
for (id in matrices) {
matrices[id].destroy();
}
for (entityName in data) {
entities = data[entityName];
for (id in entities) {
record = entities[id].record;
if (record) {
record.$source = record.session = null;
}
}
}
me.recordCreator = me.matrices = me.data = null;
me.setSchema(null);
me.callParent();
},
adopt: function(record) {
var me = this,
associations = record.associations,
roleName;
me.checkModelType(record.self);
if (record.session && record.session !== me) {
Ext.Error.raise('Record already belongs to an existing session');
}
if (record.session !== me) {
record.session = me;
me.add(record);
if (associations) {
for (roleName in associations) {
associations[roleName].adoptAssociated(record, me);
}
}
}
},
commit: function() {
var data = this.data,
entityName, entities, id, record;
for (entityName in data) {
entities = data[entityName];
for (id in entities) {
record = entities[id].record;
if (record) {
record.commit();
}
}
}
},
createRecord: function(type, data) {
this.checkModelType(type);
var Model = type.$isClass ? type : this.getSchema().getEntity(type),
parent = this.getParent(),
id;
if (data && parent) {
id = Model.getIdFromData(data);
if (parent.peekRecord(Model, id)) {
Ext.Error.raise('A parent session already contains an entry for ' + Model.entityName + ': ' + id);
}
}
return new Model(data, this);
},
getChanges: function() {
var visitor = new Ext.data.session.ChangesVisitor(this);
this.visitData(visitor);
return visitor.result;
},
getChangesForParent: function() {
var visitor = new Ext.data.session.ChildChangesVisitor(this);
this.visitData(visitor);
return visitor.result;
},
getRecord: function(type, id, autoLoad) {
var me = this,
record = me.peekRecord(type, id),
Model, parent, parentRec;
if (!record) {
Model = type.$isClass ? type : me.getSchema().getEntity(type);
parent = me.getParent();
if (parent) {
parentRec = parent.peekRecord(Model, id);
}
if (parentRec && !parentRec.isLoading()) {
record = parentRec.copy(undefined, me);
record.$source = parentRec;
} else {
record = Model.createWithId(id, null, me);
if (autoLoad !== false) {
record.load(Ext.isObject(autoLoad) ? autoLoad : undefined);
}
}
}
return record;
},
getSaveBatch: function(sort) {
var visitor = new Ext.data.session.BatchVisitor();
this.visitData(visitor);
return visitor.getBatch(sort);
},
onInvalidAssociationEntity: function(entityType, id) {
Ext.Error.raise('Unable to read association entity: ' + this.getModelIdentifier(entityType, id));
},
onInvalidEntityCreate: function(entityType, id) {
Ext.Error.raise('Cannot create, record already not exists: ' + this.getModelIdentifier(entityType, id));
},
onInvalidEntityDrop: function(entityType, id) {
Ext.Error.raise('Cannot drop, record does not exist: ' + this.getModelIdentifier(entityType, id));
},
onInvalidEntityRead: function(entityType, id) {
Ext.Error.raise('Cannot read, record already not exists: ' + this.getModelIdentifier(entityType, id));
},
onInvalidEntityUpdate: function(entityType, id, dropped) {
if (dropped) {
Ext.Error.raise('Cannot update, record dropped: ' + this.getModelIdentifier(entityType, id));
} else {
Ext.Error.raise('Cannot update, record does not exist: ' + this.getModelIdentifier(entityType, id));
}
},
peekRecord: function(type, id, deep) {
this.checkModelType(type);
var entityType = type.$isClass ? type : this.getSchema().getEntity(type),
entityName = entityType.entityName,
entry = this.data[entityName],
ret, parent;
entry = entry && entry[id];
ret = entry && entry.record;
if (!ret && deep) {
parent = this.getParent();
ret = parent && parent.peekRecord(type, id, deep);
}
return ret || null;
},
save: function() {
if (!this.getParent()) {
Ext.Error.raise('Cannot commit session, no parent exists');
}
var visitor = new Ext.data.session.ChildChangesVisitor(this);
this.visitData(visitor);
this.getParent().update(visitor.result);
},
spawn: function() {
return new this.self({
schema: this.getSchema(),
parent: this
});
},
update: function(data) {
var me = this,
schema = me.getSchema(),
crudOperations = me.crudOperations,
len = crudOperations.length,
crudKeys = me.crudKeys,
entityName, entityType, entityInfo, i, operation, item, associations, key, role, associationData;
me.getSchema().processKeyChecks(true);
for (entityName in data) {
entityType = schema.getEntity(entityName);
if (!entityType) {
Ext.Error.raise('Invalid entity type: ' + entityName);
}
entityInfo = data[entityName];
for (i = 0; i < len; ++i) {
operation = crudOperations[i];
item = entityInfo[operation.type];
if (item) {
me[operation.entityMethod](entityType, item);
}
}
}
for (entityName in data) {
entityType = schema.getEntity(entityName);
associations = entityType.associations;
entityInfo = data[entityName];
for (key in entityInfo) {
if (crudKeys[key]) {
continue;
}
role = associations[key];
if (!role) {
Ext.Error.raise('Invalid association key for ' + entityName + ', "' + key + '"');
}
associationData = entityInfo[role.role];
role.processUpdate(me, associationData);
}
}
},
privates: {
add: function(record) {
var me = this,
id = record.id,
entry = me.getEntry(record.self, id),
associations, roleName;
if (entry.record) {
Ext.Error.raise('Duplicate id ' + record.id + ' for ' + record.entityName);
}
entry.record = record;
me.registerReferences(record);
associations = record.associations;
for (roleName in associations) {
associations[roleName].checkMembership(me, record);
}
},
afterErase: function(record) {
this.evict(record);
},
applySchema: function(schema) {
return Ext.data.schema.Schema.get(schema);
},
checkModelType: function(name) {
if (name.$isClass) {
name = name.entityName;
}
if (!name) {
Ext.Error.raise('Unable to use anonymous models in a Session');
} else if (!this.getSchema().getEntity(name)) {
Ext.Error.raise('Unknown entity type ' + name);
}
},
createEntities: function(entityType, items) {
var len = items.length,
i, data, rec, id;
for (i = 0; i < len; ++i) {
data = items[i];
id = entityType.getIdFromData(data);
rec = this.peekRecord(entityType, id);
if (!rec) {
rec = this.createRecord(entityType, data);
} else {
this.onInvalidEntityCreate(entityType, id);
}
rec.phantom = true;
}
},
dropEntities: function(entityType, ids) {
var len = ids.length,
i, rec, id, extractId;
if (len) {
extractId = Ext.isObject(ids[0]);
}
for (i = 0; i < len; ++i) {
id = ids[i];
if (extractId) {
id = entityType.getIdFromData(id);
}
rec = this.peekRecord(entityType, id);
if (rec) {
rec.drop();
} else {
this.onInvalidEntityDrop(entityType, id);
}
}
},
evict: function(record) {
var entityName = record.entityName,
entities = this.data[entityName],
id = record.id,
entry;
if (entities) {
delete entities[id];
}
},
getEntityList: function(entityType, ids) {
var len = ids.length,
i, id, rec, invalid;
for (i = 0; i < len; ++i) {
id = ids[i];
rec = this.peekRecord(entityType, id);
if (rec) {
ids[i] = rec;
} else {
invalid = true;
ids[i] = null;
this.onInvalidAssociationEntity(entityType, id);
}
}
if (invalid) {
ids = Ext.Array.clean(ids);
}
return ids;
},
getEntry: function(type, id) {
if (type.isModel) {
id = type.getId();
type = type.self;
}
var entityType = type.$isClass ? type : this.getSchema().getEntity(type),
entityName = entityType.entityName,
data = this.data,
entry;
entry = data[entityName] || (data[entityName] = {});
entry = entry[id] || (entry[id] = {});
return entry;
},
getRefs: function(record, role, includeParent) {
var entry = this.getEntry(record),
refs = entry && entry.refs && entry.refs[role.role],
parent = includeParent && this.getParent(),
parentRefs, id, rec;
if (parent) {
parentRefs = parent.getRefs(record, role);
if (parentRefs) {
for (id in parentRefs) {
rec = parentRefs[id];
if ((!refs || !refs[id])) {
this.getRecord(rec.self, rec.id);
}
}
refs = entry && entry.refs && entry.refs[role.role];
}
}
return refs || null;
},
getIdentifier: function(entityType) {
var parent = this.getParent(),
cache, identifier, key, ret;
if (parent) {
ret = parent.getIdentifier(entityType);
} else {
cache = this.identifierCache;
identifier = entityType.identifier;
key = identifier.id || entityType.entityName;
ret = cache[key];
if (!ret) {
if (identifier.clone) {
ret = identifier.clone({
cache: cache
});
} else {
ret = identifier;
}
cache[key] = ret;
}
}
return ret;
},
getMatrix: function(matrix, preventCreate) {
var name = matrix.isManyToMany ? matrix.name : matrix,
matrices = this.matrices,
ret;
ret = matrices[name];
if (!ret && !preventCreate) {
ret = matrices[name] = new Ext.data.matrix.Matrix(this, matrix);
}
return ret || null;
},
getMatrixSlice: function(role, id) {
var matrix = this.getMatrix(role.association),
side = matrix[role.side];
return side.get(id);
},
getModelIdentifier: function(entityType, id) {
return id + '@' + entityType.entityName;
},
onIdChanged: function(record, oldId, newId) {
var me = this,
entityName = record.entityName,
id = record.id,
bucket = me.data[entityName],
entry = bucket[oldId],
associations = record.associations,
refs = entry.refs,
setNoRefs = me._setNoRefs,
association, fieldName, matrix, refId, role, roleName, roleRefs, store;
if (bucket[newId]) {
Ext.Error.raise('Cannot change ' + entityName + ' id from ' + oldId + ' to ' + newId + ' id already exists');
}
delete bucket[oldId];
bucket[newId] = entry;
for (roleName in associations) {
role = associations[roleName];
if (role.isMany) {
store = role.getAssociatedItem(record);
if (store) {
matrix = store.matrix;
if (matrix) {
matrix.changeId(newId);
}
}
}
}
if (refs) {
for (roleName in refs) {
roleRefs = refs[roleName];
role = associations[roleName];
association = role.association;
if (association.isManyToMany) {} else
{
fieldName = association.field.name;
for (refId in roleRefs) {
roleRefs[refId].set(fieldName, id, setNoRefs);
}
}
}
}
me.registerReferences(record, oldId);
},
processManyBlock: function(entityType, role, items, processor) {
var me = this,
id, record, records, store;
if (items) {
for (id in items) {
record = me.peekRecord(entityType, id);
if (record) {
records = me.getEntityList(role.cls, items[id]);
store = role.getAssociatedItem(record);
me[processor](role, store, record, records);
} else {
me.onInvalidAssociationEntity(entityType, id);
}
}
}
},
processManyCreate: function(role, store, record, records) {
if (store) {
store.add(records);
} else {
record[role.getterName](null, null, records);
}
},
processManyDrop: function(role, store, record, records) {
if (store) {
store.remove(records);
}
},
processManyRead: function(role, store, record, records) {
if (store) {
store.setRecords(records);
} else {
record[role.getterName](null, null, records);
}
},
readEntities: function(entityType, items) {
var len = items.length,
i, data, rec, id;
for (i = 0; i < len; ++i) {
data = items[i];
id = entityType.getIdFromData(data);
rec = this.peekRecord(entityType, id);
if (!rec) {
rec = this.createRecord(entityType, data);
} else {
this.onInvalidEntityRead(entityType, id);
}
rec.phantom = false;
}
},
recordCreator: function(data, Model) {
var me = this,
id = Model.getIdFromData(data),
record = me.peekRecord(Model, id, true);
if (!record) {
record = new Model(data, me);
} else {
record = me.getRecord(Model, id);
}
return record;
},
registerReferences: function(record, oldId) {
var entityName = record.entityName,
id = record.id,
recordData = record.data,
remove = oldId || oldId === 0,
entry, i, fk, len, reference, references, refs, roleName;
len = (references = record.references).length;
for (i = 0; i < len; ++i) {
reference = references[i];
fk = recordData[reference.name];
if (fk || fk === 0) {
reference = reference.reference;
entityName = reference.type;
roleName = reference.inverse.role;
entry = this.getEntry(reference.cls, fk);
refs = entry.refs || (entry.refs = {});
refs = refs[roleName] || (refs[roleName] = {});
refs[id] = record;
if (remove) {
delete refs[oldId];
}
}
}
},
updateEntities: function(entityType, items) {
var len = items.length,
i, data, rec, id, modified;
if (Ext.isArray(items)) {
for (i = 0; i < len; ++i) {
data = items[i];
id = entityType.getIdFromData(data);
rec = this.peekRecord(entityType, id);
if (rec) {
rec.set(data);
} else {
this.onInvalidEntityUpdate(entityType, id);
}
}
} else {
for (id in items) {
data = items[id];
rec = this.peekRecord(entityType, id);
if (rec && !rec.dropped) {
modified = rec.set(data);
} else {
this.onInvalidEntityUpdate(entityType, id, !!rec);
}
}
}
},
updateReference: function(record, field, newValue, oldValue) {
var reference = field.reference,
entityName = reference.type,
roleName = reference.inverse.role,
id = record.id,
entry, refs;
if (oldValue || oldValue === 0) {
refs = this.getEntry(entityName, oldValue).refs[roleName];
delete refs[id];
}
if (newValue || newValue === 0) {
entry = this.getEntry(entityName, newValue);
refs = entry.refs || (entry.refs = {});
refs = refs[roleName] || (refs[roleName] = {});
refs[id] = record;
}
},
visitData: function(visitor) {
var me = this,
data = me.data,
matrices = me.matrices,
all, assoc, id, id2, matrix, members, name, record, slice, slices, state;
me.getSchema().processKeyChecks(true);
for (name in data) {
all = data[name];
for (id in all) {
record = all[id].record;
if (record) {
if (record.phantom || record.dirty || record.dropped) {
if (visitor.onDirtyRecord) {
visitor.onDirtyRecord(record);
}
} else if (visitor.onCleanRecord) {
visitor.onCleanRecord(record);
}
}
}
}
if (visitor.onMatrixChange) {
for (name in matrices) {
matrix = matrices[name].left;
slices = matrix.slices;
assoc = matrix.role.association;
for (id in slices) {
slice = slices[id];
members = slice.members;
for (id2 in members) {
state = (record = members[id2])[2];
if (state) {
visitor.onMatrixChange(assoc, record[0], record[1], state);
}
}
}
}
}
return visitor;
},
_setNoRefs: {
refs: false
}
}
});
Ext.define('Ext.util.Schedulable', {
'abstract': true,
isSchedulable: true,
scheduled: false,
constructor: function() {
this.getScheduler().add(this);
},
destroy: function() {
var me = this,
scheduler = me.getScheduler();
if (scheduler) {
scheduler.remove(me);
}
me.destroyed = true;
me.scheduler = null;
me.schedule = me.destroy = me.react = Ext.emptyFn;
},
getFullName: function() {
return this.name || this.id;
},
privates: {
getScheduler: function() {
return this.scheduler;
},
schedule: function() {
var me = this,
scheduler;
if (!me.scheduled) {
scheduler = me.getScheduler();
if (scheduler) {
me.scheduled = true;
if (me.onSchedule) {
me.onSchedule();
}
scheduler.scheduleItem(me);
}
}
},
unschedule: function() {
var me = this,
scheduler;
if (me.scheduled) {
scheduler = me.getScheduler();
if (scheduler) {
scheduler.unscheduleItem(me);
}
me.scheduled = false;
}
},
sort: function() {}
}
});
Ext.define('Ext.app.bind.BaseBinding', {
extend: 'Ext.util.Schedulable',
calls: 0,
kind: 20,
defaultOptions: {},
lastValue: undefined,
constructor: function(owner, callback, scope, options) {
var me = this;
me.options = options;
me.owner = owner;
me.scope = scope;
me.callback = callback;
if (!callback) {
Ext.Error.raise('Callback is required');
}
me.lateBound = Ext.isString(callback);
if (options && options.deep) {
me.deep = true;
}
me.callParent();
},
destroy: function() {
var me = this,
owner = me.owner;
me.callParent();
if (owner) {
owner.onBindDestroy();
}
me.scope = me.callback = me.owner = null;
},
privates: {
getScheduler: function() {
var owner = this.owner;
return owner && owner.getScheduler();
},
getSession: function() {
var owner = this.owner;
return owner.isSession ? owner : owner.getSession();
},
notify: function(value) {
var me = this,
options = me.options || me.defaultOptions,
previous = me.lastValue;
if (!me.calls || me.deep || previous !== value || Ext.isArray(value)) {
++me.calls;
me.lastValue = value;
if (me.lateBound) {
me.scope[me.callback](value, previous, me);
} else {
me.callback.call(me.scope, value, previous, me);
}
if (options.single) {
me.destroy();
}
}
}
}
});
Ext.define('Ext.app.bind.Binding', {
extend: 'Ext.app.bind.BaseBinding',
constructor: function(stub, callback, scope, options) {
var me = this;
me.callParent([
stub.owner,
callback,
scope,
options
]);
me.stub = stub;
me.depth = stub.depth;
if (!stub.isLoading() && !stub.scheduled) {
me.schedule();
}
},
destroy: function(
fromParent) {
var me = this,
stub = me.stub;
if (stub && !fromParent) {
stub.unbind(me);
me.stub = null;
}
me.callParent();
},
bindValidation: function(callback, scope) {
var stub = this.stub;
return stub && stub.bindValidation(callback, scope);
},
bindValidationField: function(callback, scope) {
var stub = this.stub;
return stub && stub.bindValidationField(callback, scope);
},
getFullName: function() {
return this.fullName || (this.fullName = '@(' + this.stub.getFullName() + ')');
},
getValue: function() {
var me = this,
stub = me.stub,
ret = stub && stub.getValue();
if (me.transform) {
ret = me.transform(ret);
}
return ret;
},
isLoading: function() {
var stub = this.stub;
return stub && stub.isLoading();
},
isReadOnly: function() {
var stub = this.stub,
options = this.options;
if (!(options && options.twoWay === false)) {
if (stub) {
return stub.isReadOnly();
}
}
return true;
},
refresh: function() {},
setValue: function(value) {
if (this.isReadOnly()) {
Ext.Error.raise('Cannot setValue on a readonly binding');
}
this.stub.set(value);
},
privates: {
getDataObject: function() {
var stub = this.stub;
return stub && stub.getDataObject();
},
getRawValue: function() {
var me = this,
stub = me.stub,
ret = stub && stub.getRawValue();
if (me.transform) {
ret = me.transform(ret);
}
return ret;
},
isDescendantOf: function(item) {
var stub = this.stub;
return stub ? (item === stub) || stub.isDescendantOf(item) : false;
},
react: function() {
this.notify(this.getValue());
},
schedule: function() {
if (!this.stub.scheduled) {
this.callParent();
}
},
sort: function() {
var stub = this.stub;
stub.scheduler.sortItem(stub);
}
}
});
Ext.define('Ext.app.bind.AbstractStub', {
extend: 'Ext.util.Schedulable',
requires: [
'Ext.app.bind.Binding'
],
children: null,
depth: 0,
generation: 1,
kind: 10,
parent: null,
constructor: function(owner, name) {
var me = this;
me.owner = owner;
me.name = name;
me.callParent();
},
destroy: function() {
var me = this,
children = me.children,
bindings = me.bindings,
len, i, key;
if (bindings) {
for (i = 0 , len = bindings.length; i < len; ++i) {
bindings[i].destroy(true);
}
}
for (key in children) {
children[key].destroy();
}
me.callParent();
me.bindings = me.children = me.owner = null;
},
add: function(child) {
var me = this;
(me.children || (me.children = {}))[child.name] = child;
child.depth = me.depth + 1;
child.parent = me;
},
getChild: function(path) {
var pathArray = Ext.isString(path) ? path.split('.') : path;
if (pathArray && pathArray.length) {
return this.descend(pathArray, 0);
}
return this;
},
getFullName: function() {
var me = this,
name = me.fullName,
parent = me.parent,
s;
if (!name) {
name = me.name || me.id;
if (parent && (s = parent.getFullName())) {
name = ((s.charAt(s.length - 1) !== ':') ? s + '.' : s) + name;
}
me.fullName = name;
}
return name;
},
getSession: function() {
var owner = this.owner;
return owner.isSession ? owner : owner.getSession();
},
bind: function(callback, scope, options) {
var me = this,
binding = new Ext.app.bind.Binding(me, callback, scope, options),
bindings = (me.bindings || (me.bindings = []));
binding.depth = me.depth;
bindings.push(binding);
return binding;
},
getValue: function() {
return this.isLoading() ? null : this.getRawValue();
},
graft: function(replacement) {
var me = this,
bindings = me.bindings,
name = me.name,
i;
me.parent = me.bindings = null;
me.destroy();
replacement.depth = me.depth;
replacement.bindings = bindings;
replacement.generation = me.generation + 1;
replacement.name = name;
replacement.id = me.id;
replacement.path = me.path;
if (bindings) {
for (i = bindings.length; i-- > 0; ) {
bindings[i].stub = replacement;
}
}
return replacement;
},
isDescendantOf: function(item) {
for (var parent = this; parent = parent.parent; ) {
if (parent === item) {
return true;
}
}
return false;
},
onSchedule: function() {
for (var i, len, binding, bindings,
p = this.parent; p; p = p.parent) {
bindings = p.bindings;
if (bindings) {
for (i = 0 , len = bindings.length; i < len; ++i) {
binding = bindings[i];
if (binding.deep && !binding.scheduled) {
binding.schedule();
}
}
}
}
},
react: function() {
var bindings = this.bindings,
binding, i, len;
if (bindings) {
for (i = 0 , len = bindings.length; i < len; ++i) {
binding = bindings[i];
if (!binding.scheduled) {
binding.schedule();
}
}
}
},
unbind: function(binding) {
var bindings = this.bindings;
if (bindings && bindings.length) {
Ext.Array.remove(bindings, binding);
}
},
privates: {
collect: function() {
var children = this.children,
bindings = this.bindings,
totalCount = 0,
count = 0,
child, key;
if (children) {
for (key in children) {
child = children[key];
count = child.collect();
if (count === 0) {
child.destroy();
delete children[key];
}
totalCount += count;
}
}
if (bindings) {
totalCount += bindings.length;
}
return totalCount;
},
getScheduler: function() {
var owner = this.owner;
return owner && owner.getScheduler();
},
sort: function() {
var parent = this.parent;
if (parent) {
this.scheduler.sortItem(parent);
}
}
}
});
Ext.define('Ext.app.bind.Stub', {
extend: 'Ext.app.bind.AbstractStub',
requires: [
'Ext.app.bind.Binding'
],
isStub: true,
dirty: true,
formula: null,
validationKey: 'validation',
statics: {
trackHadValue: function(value, owner, path, stub) {
var children = stub && stub.children,
child, key, hadValue;
hadValue = value !== undefined;
if (!owner.hadValue[path]) {
owner.hadValue[path] = hadValue;
}
if (stub) {
stub.hadValue = hadValue;
}
if (value && (value.constructor === Object || value.isModel)) {
if (value.isModel) {
value = value.data;
}
for (key in value) {
Ext.app.bind.Stub.trackHadValue(value[key], owner, path + '.' + key, children && children[key]);
}
}
}
},
constructor: function(owner, name, parent) {
var me = this,
path = name;
me.callParent([
owner,
name
]);
me.boundValue = null;
if (parent) {
parent.add(me);
if (!parent.isRootStub) {
path = parent.path + '.' + name;
}
}
me.hadValue = owner.hadValue[path];
me.path = path;
},
destroy: function() {
var me = this,
formula = me.formula,
parent = me.parent,
storeBinding = me.storeBinding;
if (formula) {
formula.destroy();
}
if (storeBinding) {
storeBinding.destroy();
}
me.detachBound();
me.parentValue = me.formula = me.storeBinding = null;
me.callParent();
},
bindValidation: function(callback, scope) {
var parent = this.parent;
return parent && parent.descend([
this.validationKey,
this.name
]).bind(callback, scope);
},
bindValidationField: function(callback, scope) {
var parent = this.parent,
name = this.name,
lateBound = typeof callback === 'string',
ret;
if (parent) {
ret = parent.bind(function(value) {
var field = null;
if (value && value.isModel) {
field = value.getField(name);
}
if (lateBound) {
scope[callback](field, null, this);
} else {
callback.call(scope, field, null, this);
}
});
}
return ret || null;
},
descend: function(path, index) {
var me = this,
children = me.children || (me.children = {}),
pos = index || 0,
name = path[pos++],
ret;
if (!(ret = children[name])) {
ret = new Ext.app.bind.Stub(me.owner, name, me);
}
if (pos < path.length) {
ret = ret.descend(path, pos);
}
return ret;
},
getChildValue: function(parentData) {
var me = this,
name = me.name,
ret;
if (!parentData && !Ext.isString(parentData)) {
ret = me.hadValue ? null : undefined;
} else {
ret = me.inspectValue(parentData);
if (!ret) {
if (parentData.isEntity) {
ret = parentData.data[name];
} else {
ret = parentData[name];
}
}
}
return ret;
},
getDataObject: function() {
var me = this,
parentData = me.parent.getDataObject(),
name = me.name,
ret = parentData ? parentData[name] : null,
associations, association;
if (!ret && parentData && parentData.isEntity) {
associations = parentData.associations;
if (associations && name in associations) {
ret = parentData[associations[name].getterName]();
}
}
if (!ret || !(ret.$className || Ext.isObject(ret))) {
parentData[name] = ret = {};
me.hadValue = me.owner.hadValue[me.path] = true;
me.invalidate(true, true);
}
return ret;
},
getRawValue: function() {
return this.getChildValue(this.getParentValue());
},
graft: function(replacement) {
var me = this,
parent = me.parent,
children = me.children,
name = me.name,
i;
replacement.parent = parent;
replacement.children = children;
if (parent) {
parent.children[name] = replacement;
}
if (children) {
for (i in children) {
children[i].parent = replacement;
}
}
me.children = null;
return me.callParent([
replacement
]);
},
isLoading: function() {
var me = this,
parent = me.parent,
loading = false,
associations, parentValue, value, loadSet;
if (parent && !(loading = parent.isLoading())) {
parentValue = me.getParentValue();
value = me.inspectValue(parentValue);
if (value) {
loading = value.isLoading();
} else {
if (parentValue && parentValue.isModel) {
associations = parentValue.associations;
if (!(associations && me.name in associations)) {
loading = false;
loadSet = true;
}
}
if (!loadSet) {
loading = !me.hadValue && me.getRawValue() === undefined;
}
}
}
return loading;
},
invalidate: function(deep, dirtyOnly) {
var me = this,
children = me.children,
name;
me.dirty = true;
if (!dirtyOnly && !me.isLoading()) {
if (!me.scheduled) {
me.schedule();
}
}
if (deep && children) {
for (name in children) {
children[name].invalidate(deep, dirtyOnly);
}
}
},
isReadOnly: function() {
var formula = this.formula;
return !!(formula && !formula.set);
},
set: function(value) {
var me = this,
parent = me.parent,
name = me.name,
formula = me.formula,
parentData, associations, association, formulaStub;
if (formula && !formula.settingValue && formula.set) {
formula.setValue(value);
return;
} else if (me.isLinkStub) {
formulaStub = me.getLinkFormulaStub();
formula = formulaStub ? formulaStub.formula : null;
if (formula) {
if (formulaStub.isReadOnly()) {
Ext.Error.raise('Cannot setValue on a readonly formula');
}
formula.setValue(value);
return;
}
}
parentData = parent.getDataObject();
if (parentData.isEntity) {
associations = parentData.associations;
if (associations && (name in associations)) {
association = associations[name];
parentData[association.setterName](value);
me.invalidate(true);
} else {
parentData.set(name, value);
}
}
else if ((value && value.constructor === Object) || value !== parentData[name]) {
if (!me.setByLink(value)) {
if (value === undefined) {
delete parentData[name];
} else {
parentData[name] = value;
Ext.app.bind.Stub.trackHadValue(value, me.owner, me.path, me);
}
me.inspectValue(parentData);
me.invalidate(true);
}
}
},
onStoreLoad: function() {
this.invalidate(true);
},
afterLoad: function(record) {
this.invalidate(true);
},
afterCommit: function(record) {
this.afterEdit(record, null);
},
afterEdit: function(record, modifiedFieldNames) {
var children = this.children,
len = modifiedFieldNames && modifiedFieldNames.length,
associations = record.associations,
key, i, child, scheduled;
if (children) {
if (len) {
for (i = 0; i < len; ++i) {
child = children[modifiedFieldNames[i]];
if (child) {
child.invalidate();
}
}
} else {
for (key in children) {
if (!(associations && key in associations)) {
children[key].invalidate();
}
}
}
}
this.invalidate();
},
afterReject: function(record) {
this.afterEdit(record, null);
},
setByLink: function(value) {
var me = this,
n = 0,
i, link, path, stub;
for (stub = me; stub; stub = stub.parent) {
if (stub.isLinkStub) {
link = stub;
if (n) {
for (path = [] , i = 0 , stub = me; stub !== link; stub = stub.parent) {
++i;
path[n - i] = stub.name;
}
}
break;
}
++n;
}
if (!link || !(stub = link.getTargetStub())) {
return false;
}
if (path) {
stub = stub.descend(path);
}
stub.set(value);
return true;
},
setFormula: function(formula) {
var me = this,
oldFormula = me.formula;
if (oldFormula) {
oldFormula.destroy();
}
me.formula = new Ext.app.bind.Formula(me, formula);
},
react: function() {
var me = this,
bound = this.boundValue,
children = me.children,
generation;
if (bound) {
if (bound.isValidation) {
bound.refresh();
generation = bound.generation;
if (me.lastValidationGeneration === generation) {
return;
}
me.lastValidationGeneration = generation;
} else if (bound.isModel) {
if (children && children[me.validationKey]) {
bound.isValid();
}
} else if (bound.isStore) {
if (bound.isLoading() && !bound.loadCount) {
return;
}
}
}
this.callParent();
},
privates: {
collect: function() {
var me = this,
result = me.callParent(),
storeBinding = me.storeBinding ? 1 : 0,
formula = me.formula ? 1 : 0;
return result + storeBinding + formula;
},
getLinkFormulaStub: function() {
var stub = this;
while (stub.isLinkStub) {
stub = stub.binding.stub;
}
return stub.formula ? stub : null;
},
getParentValue: function() {
var me = this;
if (me.dirty) {
me.parentValue = me.parent.getValue();
me.dirty = false;
}
return me.parentValue;
},
setStore: function(storeBinding) {
this.storeBinding = storeBinding;
},
inspectValue: function(parentData) {
var me = this,
name = me.name,
current = me.boundValue,
boundValue = null,
associations, raw, changed, associatedEntity;
if (parentData && parentData.isEntity) {
associations = parentData.associations;
if (associations && (name in associations)) {
boundValue = parentData[associations[name].getterName]();
if (boundValue && boundValue.isStore) {
boundValue.$associatedStore = true;
}
} else if (name === me.validationKey) {
boundValue = parentData.getValidation();
me.lastValidationGeneration = null;
}
} else if (parentData) {
raw = parentData[name];
if (raw && (raw.isModel || raw.isStore)) {
boundValue = raw;
}
}
changed = current !== boundValue;
if (changed) {
if (current) {
me.detachBound();
}
if (boundValue) {
if (boundValue.isModel) {
boundValue.join(me);
} else {
associatedEntity = boundValue.associatedEntity;
if (associatedEntity && !associatedEntity.phantom && !boundValue.complete && !boundValue.hasPendingLoad()) {
boundValue.load();
}
boundValue.on('load', me.onStoreLoad, me, {
single: true
});
}
}
me.boundValue = boundValue;
}
return boundValue;
},
detachBound: function() {
var me = this,
current = me.boundValue;
if (current) {
if (current.isModel) {
current.unjoin(me);
} else {
current.un('load', me.onStoreLoad, me);
}
}
},
sort: function() {
var me = this,
formula = me.formula,
scheduler = me.scheduler,
storeBinding = me.storeBinding;
me.callParent();
if (storeBinding) {
scheduler.sortItem(storeBinding);
}
if (formula) {
scheduler.sortItem(formula);
}
}
}
});
Ext.define('Ext.app.bind.LinkStub', {
extend: 'Ext.app.bind.Stub',
isLinkStub: true,
binding: null,
destroy: function() {
var me = this,
binding = me.binding,
owner = me.owner;
if (binding) {
me.binding = null;
binding.destroy();
if (owner) {
delete owner.linkData[me.name];
}
}
me.target = null;
me.callParent();
},
getFullName: function() {
var me = this;
return me.fullName || (me.fullName = '(' + me.callParent() + ' -> ' + me.binding.getFullName() + ')');
},
getDataObject: function() {
var binding = this.binding;
return binding && binding.getDataObject();
},
getRawValue: function() {
var binding = this.binding;
return binding && binding.getRawValue();
},
getValue: function() {
var binding = this.binding;
return binding && binding.getValue();
},
getTargetStub: function() {
var binding = this.binding;
return binding && binding.stub;
},
isLoading: function() {
var binding = this.binding;
return binding ? binding.isLoading() : false;
},
link: function(bindDescriptor, target) {
var me = this,
binding = me.binding;
if (binding) {
binding.destroy();
}
target = me.target = target || me.owner;
me.linkDescriptor = bindDescriptor;
me.binding = target.bind(bindDescriptor, me.onChange, me);
me.binding.deep = true;
},
onChange: function() {
this.invalidate(true);
},
react: function() {
var me = this,
linkData = me.owner.linkData;
linkData[me.name] = me.getValue();
me.callParent();
},
privates: {
collect: function() {
var me = this,
result = me.callParent(),
binding = me.binding ? 1 : 0;
return result + binding;
},
sort: function() {
var binding = this.binding;
if (binding) {
this.scheduler.sortItem(binding);
}
}
}
});
Ext.define('Ext.app.bind.RootStub', {
extend: 'Ext.app.bind.AbstractStub',
requires: [
'Ext.app.bind.LinkStub',
'Ext.app.bind.Stub'
],
isRootStub: true,
depth: 0,
createRootChild: function(name, direct) {
var me = this,
owner = me.owner,
ownerData = owner.getData(),
children = me.children,
previous = children && children[name],
parentStub = previous ? null : me,
parentVM, stub;
if (direct || ownerData.hasOwnProperty(name) || !(parentVM = owner.getParent())) {
stub = new Ext.app.bind.Stub(owner, name, parentStub);
} else {
stub = new Ext.app.bind.LinkStub(owner, name, previous ? null : parentStub);
stub.link('{' + name + '}', parentVM);
}
if (previous) {
previous.graft(stub);
}
return stub;
},
createStubChild: function(name) {
return this.createRootChild(name, true);
},
descend: function(path, index) {
var me = this,
children = me.children,
pos = index || 0,
name = path[pos++],
ret = (children && children[name]) || me.createRootChild(name);
if (pos < path.length) {
ret = ret.descend(path, pos);
}
return ret;
},
getFullName: function() {
return this.fullName || (this.fullName = this.owner.id + ':');
},
getDataObject: function() {
return this.owner.data;
},
getRawValue: function() {
return this.owner.data;
},
getValue: function() {
return this.owner.data;
},
isDescendantOf: function() {
return false;
},
isLoading: function() {
return false;
},
set: function(value) {
if (!value || value.constructor !== Object) {
Ext.Error.raise('Only an object can be set at the root');
}
var me = this,
children = me.children || (me.children = {}),
owner = me.owner,
data = owner.data,
parentVM = owner.getParent(),
linkStub, stub, v, key;
for (key in value) {
if (key.indexOf('.') >= 0) {
Ext.Error.raise('Value names cannot contain dots');
}
if ((v = value[key]) !== undefined) {
if (!(stub = children[key])) {
stub = new Ext.app.bind.Stub(owner, key, me);
} else if (stub.isLinkStub) {
if (!stub.getLinkFormulaStub()) {
linkStub = stub;
stub = new Ext.app.bind.Stub(owner, key);
linkStub.graft(stub);
}
}
stub.set(v);
} else if (data.hasOwnProperty(key)) {
delete data[key];
stub = children[key];
if (stub && !stub.isLinkStub && parentVM) {
stub = me.createRootChild(key);
}
stub.invalidate(true);
}
}
},
schedule: Ext.emptyFn,
unschedule: Ext.emptyFn
});
Ext.define('Ext.app.bind.Multi', {
extend: 'Ext.app.bind.BaseBinding',
isMultiBinding: true,
missing: 1,
deep: true,
constructor: function(descriptor, owner, callback, scope, options) {
var me = this,
trackStatics = options && options.trackStatics;
me.callParent([
owner,
callback,
scope,
options
]);
me.bindings = [];
me.literal = descriptor.$literal;
if (descriptor.constructor === Object) {
if (trackStatics) {
me.staticKeys = [];
}
me.addObject(descriptor, me.lastValue = {}, me.staticKeys);
} else {
me.addArray(descriptor, me.lastValue = []);
}
if (!--me.missing && !me.scheduled) {
me.schedule();
}
},
destroy: function() {
var me = this;
me.bindings = Ext.destroy(me.bindings);
me.callParent();
},
add: function(descriptor, data, property) {
var me = this,
owner = me.owner,
bindings = me.bindings,
method = me.literal ? (descriptor.reference ? 'bindEntity' : 'bindExpression') : 'bind',
binding, depth;
++me.missing;
binding = owner[method](descriptor, function(value) {
data[property] = value;
if (binding.calls === 1) {
--me.missing;
}
if (!me.missing && !me.scheduled) {
me.schedule();
}
},
me, null);
depth = binding.depth;
if (!bindings.length || depth < me.depth) {
me.depth = depth;
}
bindings.push(binding);
return !this.isBindingStatic(binding);
},
addArray: function(multiBindDescr, array) {
var me = this,
n = multiBindDescr.length,
hasDynamic = false,
dynamic, b, i;
for (i = 0; i < n; ++i) {
b = multiBindDescr[i];
if (b && (b.reference || Ext.isString(b))) {
dynamic = me.add(b, array, i);
} else if (Ext.isArray(b)) {
dynamic = me.addArray(b, array[i] = []);
} else if (b && b.constructor === Object) {
dynamic = me.addObject(b, array[i] = {});
} else {
array[i] = b;
dynamic = false;
}
hasDynamic = hasDynamic || dynamic;
}
return hasDynamic;
},
addObject: function(multiBindDescr, object, staticKeys) {
var me = this,
hasDynamic = false,
dynamic, b, name;
for (name in multiBindDescr) {
b = multiBindDescr[name];
if (b && (b.reference || Ext.isString(b))) {
dynamic = me.add(b, object, name);
} else if (Ext.isArray(b)) {
dynamic = me.addArray(b, object[name] = []);
} else if (b && b.constructor === Object) {
dynamic = me.addObject(b, object[name] = {});
} else {
object[name] = b;
dynamic = false;
}
if (staticKeys && !dynamic) {
staticKeys.push(name);
}
hasDynamic = hasDynamic || dynamic;
}
return hasDynamic;
},
getFullName: function() {
var me = this,
fullName = me.fullName,
bindings = me.bindings,
length = bindings.length,
i;
if (!fullName) {
fullName = '@[';
for (i = 0; i < length; ++i) {
if (i) {
fullName += ',';
}
fullName += bindings[i].getFullName();
}
fullName += ']';
me.fullName = fullName;
}
return fullName;
},
getRawValue: function() {
return this.lastValue;
},
isDescendantOf: function() {
return false;
},
isLoading: function() {
for (var bindings = this.bindings,
n = bindings.length; n-- > 0; ) {
if (bindings[n].isLoading()) {
return true;
}
}
return false;
},
isBindingStatic: function(binding) {
return binding.isTemplateBinding && binding.isStatic;
},
isStatic: function() {
var bindings = this.bindings,
len = bindings.length,
i, binding;
for (i = 0; i < len; ++i) {
binding = bindings[i];
if (!this.isBindingStatic(binding)) {
return false;
}
}
return true;
},
pruneStaticKeys: function() {
var value = Ext.apply({}, this.lastValue),
keys = this.staticKeys,
len = keys.length,
i;
for (i = 0; i < len; ++i) {
delete value[keys[i]];
}
return value;
},
react: function() {
this.notify(this.lastValue);
},
refresh: function() {},
privates: {
sort: function() {
this.scheduler.sortItems(this.bindings);
}
}
});
Ext.define('Ext.app.bind.Formula', {
extend: 'Ext.util.Schedulable',
requires: [
'Ext.util.LruCache'
],
statics: {
getFormulaParser: function(name) {
var cache = this.formulaCache,
parser, s;
if (!cache) {
cache = this.formulaCache = new Ext.util.LruCache({
maxSize: 20
});
}
parser = cache.get(name);
if (!parser) {
s = '[^\\.a-z0-9_]' + name + '\\(\\s*([\'"])(.*?)\\1\\s*\\)';
parser = new RegExp(s, 'gi');
cache.add(name, parser);
}
return parser;
}
},
isFormula: true,
calculation: null,
explicit: false,
set: null,
single: false,
argumentNamesRe: /^function\s*\(\s*([^,\)\s]+)/,
constructor: function(stub, formula) {
var me = this,
owner = stub.owner,
bindTo, expressions, getter, options;
me.owner = owner;
me.stub = stub;
me.callParent();
if (formula instanceof Function) {
me.get = getter = formula;
} else {
me.get = getter = formula.get;
me.set = formula.set;
expressions = formula.bind;
if (formula.single) {
me.single = formula.single;
}
if (expressions) {
bindTo = expressions.bindTo;
if (bindTo) {
options = Ext.apply({}, expressions);
delete options.bindTo;
expressions = bindTo;
}
}
}
if (!getter) {
Ext.Error.raise('Must specify a getter method for a formula');
}
if (expressions) {
me.explicit = true;
} else {
expressions = getter.$expressions || me.parseFormula(getter);
}
me.binding = owner.bind(expressions, me.onChange, me, options);
},
destroy: function() {
var me = this,
binding = me.binding,
stub = me.stub;
if (binding) {
binding.destroy();
me.binding = null;
}
if (stub) {
stub.formula = null;
}
me.callParent();
me.getterFn = me.owner = null;
},
getFullName: function() {
return this.fullName || (this.fullName = this.stub.getFullName() + '=' + this.callParent() + ')');
},
getRawValue: function() {
return this.calculation;
},
onChange: function() {
if (!this.scheduled) {
this.schedule();
}
},
parseFormula: function(formula) {
var str = formula.toString(),
expressions = {
$literal: true
},
match, getterProp, formulaRe, expr;
match = this.argumentNamesRe.exec(str);
getterProp = match ? match[1] : 'get';
formulaRe = Ext.app.bind.Formula.getFormulaParser(getterProp);
while ((match = formulaRe.exec(str))) {
expr = match[2];
expressions[expr] = expr;
}
expressions.$literal = true;
formula.$expressions = expressions;
return expressions;
},
react: function() {
var me = this,
owner = me.owner,
data = me.binding.lastValue,
getterFn = me.getterFn,
arg;
if (me.explicit) {
arg = data;
} else {
arg = owner.getFormulaFn(data);
}
me.settingValue = true;
me.stub.set(me.calculation = me.get.call(owner, arg));
me.settingValue = false;
if (me.single) {
me.destroy();
}
},
setValue: function(value) {
this.set.call(this.stub.owner, value);
},
privates: {
getScheduler: function() {
var owner = this.owner;
return owner && owner.getScheduler();
},
sort: function() {
var me = this,
binding = me.binding;
if (!binding.destroyed) {
me.scheduler.sortItem(binding);
}
}
}
});
Ext.define('Ext.app.bind.Template', {
requires: [
'Ext.util.Format'
],
numberRe: /^(?:\d+(?:\.\d*)?)$/,
stringRe: /^(?:["][^"]*["])$/,
tokenRe: /\{[!]?(?:(?:(\d+)|([a-z_][\w\-\.]*))(?::([a-z_\.]+)(?:\(([^\)]*?)?\))?)?)\}/gi,
formatRe: /^([a-z_]+)(?:\(([^\)]*?)?\))?$/i,
buffer: null,
slots: null,
tokens: null,
constructor: function(text) {
var me = this,
initters = me._initters,
name;
me.text = text;
for (name in initters) {
me[name] = initters[name];
}
},
_initters: {
apply: function(values, scope) {
return this.parse().apply(values, scope);
},
getTokens: function() {
return this.parse().getTokens();
}
},
apply: function(values, scope) {
var me = this,
slots = me.slots,
buffer = me.buffer,
length = slots.length,
i, slot, value;
for (i = 0; i < length; ++i) {
slot = slots[i];
if (slot) {
if ((value = values[slot.pos]) == null) {
value = '';
}
if (slot.not) {
value = !value;
}
if (slot.format) {
value = slot.format(value, scope);
}
buffer[i] = value;
}
}
return buffer.join('');
},
getTokens: function() {
return this.tokens;
},
parse: function() {
var me = this,
text = me.text,
buffer = [],
slots = [],
tokens = [],
tokenMap = {},
last = 0,
tokenRe = me.tokenRe,
pos = 0,
fmt, i, length, match, s, slot, token;
for (i in me._initters) {
delete me[i];
}
me.buffer = buffer;
me.slots = slots;
me.tokens = tokens;
while ((match = tokenRe.exec(text))) {
length = match.index - last;
if (length) {
buffer[pos++] = text.substring(last, last + length);
last += length;
}
last += (s = match[0]).length;
slot = {
fmt: (fmt = match[3] || null),
index: match[1] ? parseInt(match[1], 10) : null,
not: s.charAt(1) === '!',
token: match[2] || null
};
token = slot.token || String(slot.index);
if (token in tokenMap) {
slot.pos = tokenMap[token];
} else {
tokenMap[token] = slot.pos = tokens.length;
tokens.push(token);
}
if (fmt) {
if (fmt.substring(0, 5) === 'this.') {
slot.fmt = fmt.substring(5);
} else {
if (!(fmt in Ext.util.Format)) {
Ext.Error.raise('Invalid format specified: "' + fmt + '"');
}
slot.scope = Ext.util.Format;
}
me.parseArgs(match[4], slot);
}
slots[pos++] = slot;
}
if (last < text.length) {
buffer[pos++] = text.substring(last);
}
return me;
},
parseArgs: function(argsString, slot) {
var me = this,
numberRe = me.numberRe,
stringRe = me.stringRe,
arg, args, i, length;
if (!argsString) {
args = [];
} else if (argsString.indexOf(',') < 0) {
args = [
argsString
];
} else {
args = argsString.split(',');
}
slot = slot || {};
length = args.length;
slot.args = args;
for (i = 0; i < length; ++i) {
arg = args[i];
if (arg === 'true') {
args[i] = true;
} else if (arg === 'false') {
args[i] = false;
} else if (arg === 'null') {
args[i] = null;
} else if (numberRe.test(arg)) {
args[i] = parseFloat(arg);
} else if (stringRe.test(arg)) {
args[i] = arg.substring(1, arg.length - 1);
} else {
slot.fn = Ext.functionFactory('return [' + argsString + '];');
slot.format = me._formatEval;
break;
}
}
if (!slot.format) {
args.unshift(0);
slot.format = me._formatArgs;
}
return slot;
},
parseFormat: function(fmt) {
var me = this,
match = me.formatRe.exec(fmt),
slot = {
fmt: fmt,
scope: Ext.util.Format
},
args;
if (!match) {
Ext.Error.raise('Invalid format syntax: "' + slot + '"');
}
args = match[2];
if (args) {
slot.fmt = match[1];
me.parseArgs(args, slot);
} else {
slot.args = [
0
];
slot.format = me._formatArgs;
}
return slot;
},
_formatArgs: function(value, scope) {
scope = this.scope || scope;
this.args[0] = value;
return scope[this.fmt].apply(scope, this.args);
},
_formatEval: function(value, scope) {
var args = this.fn();
args.unshift(value);
scope = this.scope || scope;
return scope[this.fmt].apply(scope, args);
}
});
Ext.define('Ext.app.bind.TemplateBinding', {
extend: 'Ext.app.bind.BaseBinding',
requires: [
'Ext.app.bind.Multi',
'Ext.app.bind.Template'
],
isTemplateBinding: true,
lastValue: undefined,
value: undefined,
constructor: function(template, owner, callback, scope, options) {
var me = this,
tpl = new Ext.app.bind.Template(template),
tokens = tpl.getTokens();
me.callParent([
owner,
callback,
scope,
options
]);
me.tpl = tpl;
me.tokens = tokens;
tokens.$literal = true;
if (tokens.length) {
me.multiBinding = new Ext.app.bind.Multi(tokens, owner, me.onBindData, me);
} else {
me.isStatic = true;
me.onData(tpl.text);
}
},
destroy: function() {
var me = this;
Ext.destroy(me.multiBinding);
me.tpl = me.multiBinding = null;
me.callParent();
},
getFullName: function() {
var multi = this.multiBinding;
return this.fullName || (this.fullName = '$' + (multi ? multi.getFullName() : this.callParent()));
},
getRawValue: function() {
return this.value;
},
getTemplateScope: function() {
return null;
},
isDescendantOf: function() {
return false;
},
isLoading: function() {
var multi = this.multiBinding;
return multi ? multi.isLoading() : false;
},
onBindData: function(data) {
this.onData(this.tpl.apply(data, this.getTemplateScope()));
},
onData: function(value) {
var me = this,
lastValue = me.value;
if (lastValue !== (me.value = value)) {
me.lastValue = lastValue;
me.schedule();
}
},
react: function() {
this.notify(this.value);
},
refresh: function() {
var multi = this.multiBinding;
if (multi) {
multi.refresh();
}
},
privates: {
sort: function() {
var multi = this.multiBinding;
if (multi) {
this.scheduler.sortItem(multi);
}
}
}
});
Ext.define('Ext.data.ChainedStore', {
extend: 'Ext.data.AbstractStore',
alias: 'store.chained',
config: {
source: null,
remoteFilter: false,
remoteSort: false
},
mixins: [
'Ext.data.LocalStore'
],
constructor: function() {
this.callParent(arguments);
this.getData().addObserver(this);
},
blockLoad: Ext.emptyFn,
unblockLoad: Ext.emptyFn,
updateRemoteFilter: function(remoteFilter, oldRemoteFilter) {
if (remoteFilter) {
Ext.Error.raise('Remote filtering cannot be used with chained stores.');
}
this.callParent([
remoteFilter,
oldRemoteFilter
]);
},
updateRemoteSort: function(remoteSort, oldRemoteSort) {
if (remoteSort) {
Ext.Error.raise('Remote sorting cannot be used with chained stores.');
}
this.callParent([
remoteSort,
oldRemoteSort
]);
},
remove: function() {
var source = this.getSource();
return source.remove.apply(source, arguments);
},
getData: function() {
var me = this,
data = me.data;
if (!data) {
me.data = data = me.constructDataCollection();
}
return data;
},
getSession: function() {
return this.getSource().getSession();
},
applySource: function(source) {
if (source) {
var original = source,
s;
source = Ext.data.StoreManager.lookup(source);
if (!source) {
s = 'Invalid source {0}specified for Ext.data.ChainedStore';
s = Ext.String.format(s, typeof original === 'string' ? '"' + original + '" ' : '');
Ext.Error.raise(s);
}
}
return source;
},
updateSource: function(source, oldSource) {
var me = this,
data;
if (oldSource) {
oldSource.removeObserver(me);
}
if (source) {
data = me.getData();
data.setSource(source.getData());
if (!me.isInitializing) {
me.fireEvent('refresh', me);
me.fireEvent('datachanged', me);
}
source.addObserver(me);
}
},
getModel: function() {
return this.getSource().getModel();
},
getProxy: function() {
return null;
},
onCollectionAdd: function(collection, info) {
var me = this,
records = info.items,
lastChunk = !info.next;
if (me.ignoreCollectionAdd) {
return;
}
me.fireEvent('add', me, records, info.at);
if (lastChunk) {
me.fireEvent('datachanged', me);
}
},
onCollectionItemChange: function(collection, info) {
var me = this,
record = info.item,
modifiedFieldNames = info.modified || null,
type = info.meta;
me.onUpdate(record, type, modifiedFieldNames, info);
me.fireEvent('update', me, record, type, modifiedFieldNames, info);
},
onUpdate: Ext.emptyFn,
onCollectionRemove: function(collection, info) {
var me = this,
records = info.items,
lastChunk = !info.next;
if (me.ignoreCollectionRemove) {
return;
}
me.fireEvent('remove', me, records, info.at, false);
if (lastChunk) {
me.fireEvent('datachanged', me);
}
},
onSourceBeforeLoad: function(source, operation) {
this.fireEvent('beforeload', this, operation);
},
onSourceAfterLoad: function(source, records, successful, operation) {
this.fireEvent('load', this, records, successful, operation);
},
onFilterEndUpdate: function() {
this.callParent(arguments);
this.callObservers('Filter');
},
onSourceBeforePopulate: function() {
this.ignoreCollectionAdd = true;
this.callObservers('BeforePopulate');
},
onSourceAfterPopulate: function() {
var me = this;
me.ignoreCollectionAdd = false;
me.fireEvent('datachanged', me);
me.fireEvent('refresh', me);
this.callObservers('AfterPopulate');
},
onSourceBeforeClear: function() {
this.ignoreCollectionRemove = true;
this.callObservers('BeforeClear');
},
onSourceAfterClear: function() {
this.ignoreCollectionRemove = false;
this.callObservers('AfterClear');
},
onSourceBeforeRemoveAll: function() {
this.ignoreCollectionRemove = true;
this.callObservers('BeforeRemoveAll');
},
onSourceAfterRemoveAll: function(source, silent) {
var me = this;
me.ignoreCollectionRemove = false;
if (!silent) {
me.fireEvent('clear', me);
me.fireEvent('datachanged', me);
}
this.callObservers('AfterRemoveAll', [
silent
]);
},
onSourceFilter: function() {
var me = this;
me.fireEvent('refresh', me);
me.fireEvent('datachanged', me);
},
hasPendingLoad: function() {
return this.getSource().hasPendingLoad();
},
isLoaded: function() {
return this.getSource().isLoaded();
},
isLoading: function() {
return this.getSource().isLoading();
},
onDestroy: function() {
var me = this;
me.observers = null;
me.setSource(null);
me.getData().destroy(true);
me.data = null;
},
privates: {
isMoving: function() {
var source = this.getSource();
return source.isMoving ? source.isMoving.apply(source, arguments) : false;
},
loadsSynchronously: function() {
return this.getSource().loadsSynchronously();
}
}
});
Ext.define('Ext.app.ViewModel', {
mixins: [
'Ext.mixin.Factoryable',
'Ext.mixin.Identifiable'
],
requires: [
'Ext.util.Scheduler',
'Ext.data.Session',
'Ext.app.bind.RootStub',
'Ext.app.bind.LinkStub',
'Ext.app.bind.Multi',
'Ext.app.bind.Formula',
'Ext.app.bind.TemplateBinding',
'Ext.data.ChainedStore'
],
alias: 'viewmodel.default',
isViewModel: true,
factoryConfig: {
name: 'viewModel'
},
destroyed: false,
collectTimeout: 100,
expressionRe: /^(?:\{[!]?(?:(\d+)|([a-z_][\w\-\.]*))\})$/i,
$configStrict: false,
config: {
data: true,
formulas: {
$value: null,
merge: function(newValue, currentValue, target, mixinClass) {
return this.mergeNew(newValue, currentValue, target, mixinClass);
}
},
links: null,
parent: null,
root: true,
scheduler: null,
schema: 'default',
session: null,
stores: null,
view: null
},
constructor: function(config) {
this.hadValue = {};
this.initConfig(config);
},
destroy: function() {
var me = this,
scheduler = me._scheduler,
stores = me.storeInfo,
parent = me.getParent(),
task = me.collectTask,
children = me.children,
key, store, autoDestroy;
me.destroying = true;
if (task) {
task.cancel();
me.collectTask = null;
}
if (children) {
for (key in children) {
children[key].destroy();
}
}
if (stores) {
for (key in stores) {
store = stores[key];
autoDestroy = store.autoDestroy;
if (autoDestroy || (!store.$wasInstance && autoDestroy !== false)) {
store.destroy();
}
Ext.destroy(store.$binding);
}
}
if (parent) {
parent.unregisterChild(me);
}
me.getRoot().destroy();
if (scheduler && scheduler.$owner === me) {
scheduler.$owner = null;
scheduler.destroy();
}
me.hadValue = me.children = me.storeInfo = me._session = me._view = me._scheduler = me._root = me._parent = me.formulaFn = me.$formulaData = null;
me.callParent();
},
bind: function(descriptor, callback, scope, options) {
var me = this,
binding;
scope = scope || me;
if (!options && descriptor.bindTo !== undefined && !Ext.isString(descriptor)) {
options = descriptor;
descriptor = options.bindTo;
}
if (!Ext.isString(descriptor)) {
binding = new Ext.app.bind.Multi(descriptor, me, callback, scope, options);
} else if (me.expressionRe.test(descriptor)) {
descriptor = descriptor.substring(1, descriptor.length - 1);
binding = me.bindExpression(descriptor, callback, scope, options);
} else {
binding = new Ext.app.bind.TemplateBinding(descriptor, me, callback, scope, options);
}
return binding;
},
getSession: function() {
var me = this,
session = me._session,
parent;
if (!session && (parent = me.getParent())) {
me.setSession(session = parent.getSession());
}
return session || null;
},
getStore: function(key) {
var storeInfo = this.storeInfo,
store;
if (storeInfo) {
store = storeInfo[key];
}
return store || null;
},
linkTo: function(key, reference) {
var me = this,
stub = me.getStub(key),
create, id, modelType, linkStub, rec;
if (stub.depth - me.getRoot().depth > 1) {
Ext.Error.raise('Links can only be at the top-level: "' + key + '"');
}
if (reference.isModel) {
reference = {
type: reference.entityName,
id: reference.id
};
}
modelType = reference.type || reference.reference;
create = reference.create;
if (modelType) {
id = reference.id;
if (!reference.create && Ext.isEmpty(id)) {
Ext.Error.raise('No id specified. To create a phantom model, specify "create: true" as part of the reference.');
}
if (create) {
id = undefined;
}
rec = me.getRecord(modelType, id);
if (Ext.isObject(create)) {
rec.set(create);
rec.commit();
rec.phantom = true;
}
stub.set(rec);
} else {
if (!stub.isLinkStub) {
linkStub = new Ext.app.bind.LinkStub(me, stub.name);
stub.graft(linkStub);
stub = linkStub;
}
stub.link(reference);
}
},
notify: function() {
this.getScheduler().notify();
},
get: function(path) {
return this.getStub(path).getValue();
},
set: function(path, value) {
var me = this,
obj, stub;
me.getData();
if (value === undefined && path && path.constructor === Object) {
stub = me.getRoot();
value = path;
} else if (path && path.indexOf('.') < 0) {
obj = {};
obj[path] = value;
value = obj;
stub = me.getRoot();
} else {
stub = me.getStub(path);
}
stub.set(value);
},
privates: {
registerChild: function(child) {
var children = this.children;
if (!children) {
this.children = children = {};
}
children[child.getId()] = child;
},
unregisterChild: function(child) {
var children = this.children;
if (!this.destroying && children) {
delete children[child.getId()];
}
},
getRecord: function(type, id) {
var session = this.getSession(),
Model = type,
hasId = id !== undefined,
record;
if (session) {
if (hasId) {
record = session.getRecord(type, id);
} else {
record = session.createRecord(type);
}
} else {
if (!Model.$isClass) {
Model = this.getSchema().getEntity(Model);
if (!Model) {
Ext.Error.raise('Invalid model name: ' + type);
}
}
if (hasId) {
record = Model.createWithId(id);
record.load();
} else {
record = new Model();
}
}
return record;
},
notFn: function(v) {
return !v;
},
bindExpression: function(descriptor, callback, scope, options) {
var ch = descriptor.charAt(0),
not = (ch === '!'),
path = not ? descriptor.substring(1) : descriptor,
stub = this.getStub(path),
binding;
binding = stub.bind(callback, scope, options);
if (not) {
binding.transform = this.notFn;
}
return binding;
},
applyScheduler: function(scheduler) {
if (scheduler && !scheduler.isInstance) {
scheduler = new Ext.util.Scheduler(scheduler);
scheduler.$owner = this;
}
return scheduler;
},
getScheduler: function() {
var me = this,
scheduler = me._scheduler,
parent, session;
if (!scheduler) {
if (!(parent = me.getParent())) {
scheduler = new Ext.util.Scheduler({
preSort: 'kind,-depth'
});
scheduler.$owner = me;
} else {
scheduler = parent.getScheduler();
}
me.setScheduler(scheduler);
}
return scheduler;
},
getStub: function(bindDescr) {
var root = this.getRoot();
return bindDescr ? root.getChild(bindDescr) : root;
},
collect: function() {
var me = this,
parent = me.getParent(),
task = me.collectTask;
if (parent) {
parent.collect();
return;
}
if (!task) {
task = me.collectTask = new Ext.util.DelayedTask(me.doCollect, me);
}
if (me.collectTimeout === 0) {
me.doCollect();
} else {
task.delay(me.collectTimeout);
}
},
doCollect: function() {
var children = this.children,
key;
if (children) {
for (key in children) {
children[key].doCollect();
}
}
this.getRoot().collect();
},
onBindDestroy: function() {
var me = this,
parent;
if (me.destroying) {
return;
}
parent = me.getParent();
if (parent) {
parent.onBindDestroy();
} else {
me.collect();
}
},
applyData: function(newData, data) {
var me = this,
linkData, parent;
me.getSession();
if (!data) {
parent = me.getParent();
me.linkData = linkData = parent ? Ext.Object.chain(parent.getData()) : {};
me.data = me._data = Ext.Object.chain(linkData);
}
if (newData && newData.constructor === Object) {
me.getRoot().set(newData);
}
},
applyParent: function(parent) {
if (parent) {
parent.registerChild(this);
}
return parent;
},
applyStores: function(stores) {
var me = this,
root = me.getRoot(),
key, cfg, storeBind, stub, listeners, isStatic;
me.storeInfo = {};
me.listenerScopeFn = function() {
return me.getView().getInheritedConfig('defaultListenerScope');
};
for (key in stores) {
cfg = stores[key];
if (cfg.isStore) {
cfg.$wasInstance = true;
me.setupStore(cfg, key);
continue;
} else if (Ext.isString(cfg)) {
cfg = {
source: cfg
};
} else {
cfg = Ext.apply({}, cfg);
}
listeners = cfg.listeners;
delete cfg.listeners;
storeBind = me.bind(cfg, me.onStoreBind, me, {
trackStatics: true
});
if (storeBind.isStatic()) {
storeBind.destroy();
me.createStore(key, cfg, listeners);
} else {
storeBind.$storeKey = key;
storeBind.$listeners = listeners;
stub = root.createStubChild(key);
stub.setStore(storeBind);
}
}
},
onStoreBind: function(cfg, oldValue, binding) {
var info = this.storeInfo,
key = binding.$storeKey,
store = info[key],
proxy;
if (!store) {
this.createStore(key, cfg, binding.$listeners, binding);
} else {
cfg = Ext.merge({}, binding.pruneStaticKeys());
proxy = cfg.proxy;
delete cfg.type;
delete cfg.model;
delete cfg.fields;
delete cfg.proxy;
delete cfg.listeners;
if (proxy) {
delete proxy.reader;
delete proxy.writer;
store.getProxy().setConfig(proxy);
}
store.blockLoad();
store.setConfig(cfg);
store.unblockLoad(true);
}
},
createStore: function(key, cfg, listeners, binding) {
var session = this.getSession(),
store;
cfg = Ext.apply({}, cfg);
if (cfg.session) {
cfg.session = session;
}
if (cfg.source) {
cfg.type = cfg.type || 'chained';
}
cfg.listeners = listeners;
store = Ext.Factory.store(cfg);
store.$binding = binding;
this.setupStore(store, key);
},
setupStore: function(store, key) {
store.resolveListenerScope = this.listenerScopeFn;
this.storeInfo[key] = store;
this.set(key, store);
},
applyFormulas: function(formulas) {
var me = this,
root = me.getRoot(),
name, stub;
me.getData();
for (name in formulas) {
if (name.indexOf('.') >= 0) {
Ext.Error.raise('Formula names cannot contain dots: ' + name);
}
root.createStubChild(name);
stub = me.getStub(name);
stub.setFormula(formulas[name]);
}
return formulas;
},
applyLinks: function(links) {
for (var link in links) {
this.linkTo(link, links[link]);
}
},
applySchema: function(schema) {
return Ext.data.schema.Schema.get(schema);
},
applyRoot: function() {
var root = new Ext.app.bind.RootStub(this),
parent = this.getParent();
if (parent) {
root.depth = parent.getRoot().depth - 1000;
}
return root;
},
getFormulaFn: function(data) {
var me = this,
fn = me.formulaFn;
if (!fn) {
fn = me.formulaFn = function(name) {
return me.$formulaData[name];
};
}
me.$formulaData = data;
return fn;
}
}
});
Ext.define('Ext.app.domain.Controller', {
extend: 'Ext.app.EventDomain',
singleton: true,
requires: [
'Ext.app.Controller'
],
type: 'controller',
prefix: 'controller.',
idMatchRe: /^\#/,
constructor: function() {
var me = this;
me.callParent();
me.monitor(Ext.app.BaseController);
},
match: function(target, selector) {
var result = false,
alias = target.alias;
if (selector === '*') {
result = true;
} else if (selector === '#') {
result = !!target.isApplication;
} else if (this.idMatchRe.test(selector)) {
result = target.getId() === selector.substring(1);
} else if (alias) {
result = Ext.Array.indexOf(alias, this.prefix + selector) > -1;
}
return result;
}
});
Ext.define('Ext.direct.Manager', {
singleton: true,
requires: [
'Ext.util.MixedCollection'
],
mixins: [
'Ext.mixin.Observable'
],
exceptions: {
TRANSPORT: 'xhr',
PARSE: 'parse',
DATA: 'data',
LOGIN: 'login',
SERVER: 'exception'
},
providerClasses: {},
remotingMethods: {},
config: {
varName: 'Ext.app.REMOTING_API'
},
apiNotFoundError: 'Ext Direct API was not found at {0}',
constructor: function() {
var me = this;
me.mixins.observable.constructor.call(me);
me.transactions = new Ext.util.MixedCollection();
me.providers = new Ext.util.MixedCollection();
},
addProvider: function(provider) {
var me = this,
args = arguments,
relayers = me.relayers || (me.relayers = {}),
i, len;
if (args.length > 1) {
for (i = 0 , len = args.length; i < len; ++i) {
me.addProvider(args[i]);
}
return;
}
if (!provider.isProvider) {
provider = Ext.create('direct.' + provider.type + 'provider', provider);
}
me.providers.add(provider);
provider.on('data', me.onProviderData, me);
if (provider.relayedEvents) {
relayers[provider.id] = me.relayEvents(provider, provider.relayedEvents);
}
if (!provider.isConnected()) {
provider.connect();
}
return provider;
},
loadProvider: function(config, callback, scope) {
var me = this,
classes = me.providerClasses,
type, url, varName, provider, i, len;
if (Ext.isArray(config)) {
for (i = 0 , len = config.length; i < len; i++) {
me.loadProvider(config[i], callback, scope);
}
return;
}
type = config.type;
url = config.url;
if (classes[type] && classes[type].checkConfig(config)) {
provider = me.addProvider(config);
me.fireEventArgs('providerload', [
url,
provider
]);
Ext.callback(callback, scope, [
url,
provider
]);
return;
}
varName = config.varName || me.getVarName();
delete config.varName;
if (!url) {
Ext.Error.raise("Need API discovery URL to load a Remoting provider!");
}
delete config.url;
Ext.Loader.loadScript({
url: url,
scope: me,
onLoad: function() {
this.onApiLoadSuccess({
url: url,
varName: varName,
config: config,
callback: callback,
scope: scope
});
},
onError: function() {
this.onApiLoadFailure({
url: url,
callback: callback,
scope: scope
});
}
});
},
getProvider: function(id) {
return id.isProvider ? id : this.providers.get(id);
},
removeProvider: function(provider) {
var me = this,
providers = me.providers,
relayers = me.relayers,
id;
provider = provider.isProvider ? provider : providers.get(provider);
if (provider) {
provider.un('data', me.onProviderData, me);
id = provider.id;
if (relayers[id]) {
relayers[id].destroy();
delete relayers[id];
}
providers.remove(provider);
return provider;
}
return null;
},
addTransaction: function(transaction) {
this.transactions.add(transaction);
return transaction;
},
removeTransaction: function(transaction) {
var me = this;
transaction = me.getTransaction(transaction);
me.transactions.remove(transaction);
return transaction;
},
getTransaction: function(transaction) {
return typeof transaction === 'object' ? transaction : this.transactions.get(transaction);
},
onProviderData: function(provider, event) {
var me = this,
i, len;
if (Ext.isArray(event)) {
for (i = 0 , len = event.length; i < len; ++i) {
me.onProviderData(provider, event[i]);
}
return;
}
if (event.name && event.name !== 'event' && event.name !== 'exception') {
me.fireEvent(event.name, event);
} else if (event.status === false) {
me.fireEvent('exception', event);
}
me.fireEvent('event', event, provider);
},
parseMethod: function(fn) {
var current = Ext.global,
i = 0,
resolved, parts, len;
if (Ext.isFunction(fn)) {
resolved = fn;
} else if (Ext.isString(fn)) {
resolved = this.remotingMethods[fn];
if (!resolved) {
parts = fn.split('.');
len = parts.length;
while (current && i < len) {
current = current[parts[i]];
++i;
}
resolved = Ext.isFunction(current) ? current : null;
}
}
return resolved || null;
},
privates: {
addProviderClass: function(type, cls) {
this.providerClasses[type] = cls;
},
onApiLoadSuccess: function(options) {
var me = this,
url = options.url,
varName = options.varName,
api, provider, error;
try {
api = Ext.apply(options.config, eval(varName));
provider = me.addProvider(api);
} catch (e) {
error = e + '';
}
if (error) {
me.fireEventArgs('providerloaderror', [
url,
error
]);
Ext.callback(options.callback, options.scope, [
url,
error
]);
} else {
me.fireEventArgs('providerload', [
url,
provider
]);
Ext.callback(options.callback, options.scope, [
url,
provider
]);
}
},
onApiLoadFailure: function(options) {
var url = options.url,
error;
error = Ext.String.format(this.apiNotFoundError, url);
this.fireEventArgs('providerloaderror', [
url,
error
]);
Ext.callback(options.callback, options.scope, [
url,
error
]);
},
registerMethod: function(name, method) {
this.remotingMethods[name] = method;
},
clearAllMethods: function() {
this.remotingMethods = {};
}
}
}, function() {
Ext.Direct = Ext.direct.Manager;
});
Ext.define('Ext.direct.Provider', {
alias: 'direct.provider',
mixins: [
'Ext.util.Observable'
],
requires: [
'Ext.direct.Manager'
],
isProvider: true,
subscribers: 0,
constructor: function(config) {
var me = this;
Ext.apply(me, config);
Ext.applyIf(me, {
id: Ext.id(null, 'provider-')
});
me.mixins.observable.constructor.call(me, config);
},
destroy: function() {
var me = this;
me.disconnect(true);
me.mixins.observable.destroy.call(me);
},
isConnected: function() {
return this.subscribers > 0;
},
connect: function() {
var me = this;
if (me.subscribers === 0) {
me.doConnect();
me.fireEventArgs('connect', [
me
]);
}
me.subscribers++;
},
doConnect: Ext.emptyFn,
disconnect: function(
force) {
var me = this;
if (me.subscribers > 0) {
if (force) {
me.subscribers = 0;
} else {
me.subscribers--;
}
if (me.subscribers === 0) {
me.doDisconnect();
me.fireEventArgs('disconnect', [
me
]);
}
}
},
doDisconnect: Ext.emptyFn,
inheritableStatics: {
checkConfig: Ext.returnFalse
},
onClassExtended: function(cls, data, hooks) {
if (data.type) {
Ext.direct.Manager.addProviderClass(data.type, cls);
}
}
});
Ext.define('Ext.app.domain.Direct', {
extend: 'Ext.app.EventDomain',
singleton: true,
requires: [
'Ext.direct.Provider'
],
type: 'direct',
idProperty: 'id',
constructor: function() {
var me = this;
me.callParent();
me.monitor(Ext.direct.Provider);
}
});
Ext.define('Ext.data.PageMap', {
extend: 'Ext.util.LruCache',
config: {
store: null,
pageSize: 0,
rootProperty: ''
},
clear: function(initial) {
var me = this;
me.pageMapGeneration = (me.pageMapGeneration || 0) + 1;
me.indexMap = {};
me.callParent(arguments);
},
forEach: function(fn, scope) {
var me = this,
pageNumbers = Ext.Object.getKeys(me.map),
pageCount = pageNumbers.length,
pageSize = me.getPageSize(),
i, j, pageNumber, page, len;
for (i = 0; i < pageCount; i++) {
pageNumbers[i] = +pageNumbers[i];
}
Ext.Array.sort(pageNumbers, Ext.Array.numericSortFn);
scope = scope || me;
for (i = 0; i < pageCount; i++) {
pageNumber = pageNumbers[i];
page = me.getPage(pageNumber);
len = page.length;
for (j = 0; j < len; j++) {
if (fn.call(scope, page[j], (pageNumber - 1) * pageSize + j) === false) {
return;
}
}
}
},
findBy: function(fn, scope) {
var me = this,
result = null;
scope = scope || me;
me.forEach(function(rec, index) {
if (fn.call(scope, rec, index)) {
result = rec;
return false;
}
});
return result;
},
findIndexBy: function(fn, scope) {
var me = this,
result = -1;
scope = scope || me;
me.forEach(function(rec, index) {
if (fn.call(scope, rec)) {
result = index;
return false;
}
});
return result;
},
find: function(property, value, start, startsWith, endsWith, ignoreCase) {
if (Ext.isEmpty(value, false)) {
return null;
}
var regex = Ext.String.createRegex(value, startsWith, endsWith, ignoreCase),
root = this.getRootProperty();
return this.findBy(function(item) {
return item && regex.test((root ? item[root] : item)[property]);
}, null, start);
},
findIndex: function(property, value, start, startsWith, endsWith, ignoreCase) {
if (Ext.isEmpty(value, false)) {
return null;
}
var regex = Ext.String.createRegex(value, startsWith, endsWith, ignoreCase),
root = this.getRootProperty();
return this.findIndexBy(function(item) {
return item && regex.test((root ? item[root] : item)[property]);
}, null, start);
},
getPageFromRecordIndex: function(index) {
return Math.floor(index / this.getPageSize()) + 1;
},
addAll: function(records) {
if (this.getCount()) {
Ext.Error.raise('Cannot addAll to a non-empty PageMap');
}
this.addPage(1, records);
},
addPage: function(pageNumber, records) {
var me = this,
pageSize = me.getPageSize(),
lastPage = pageNumber + Math.floor((records.length - 1) / pageSize),
startIdx,
storeIndex = (pageNumber - 1) * pageSize,
indexMap = me.indexMap,
page, i, len;
for (startIdx = 0; pageNumber <= lastPage; pageNumber++ , startIdx += pageSize) {
page = Ext.Array.slice(records, startIdx, startIdx + pageSize);
for (i = 0 , len = page.length; i < len; i++) {
indexMap[page[i].internalId] = storeIndex++;
}
me.add(pageNumber, page);
me.fireEvent('pageadd', me, pageNumber, page);
}
},
getCount: function() {
var result = this.callParent();
if (result) {
result = (result - 1) * this.getPageSize() + this.last.value.length;
}
return result;
},
getByInternalId: function(internalId) {
var index = this.indexMap[internalId];
if (index !== -1) {
return this.getAt(index);
}
},
indexOf: function(record) {
var result = -1;
if (record) {
result = this.indexMap[record.internalId];
if (result == null) {
result = -1;
}
}
return result;
},
insert: function() {
Ext.Error.raise('insert operation not suppported into buffered Store');
},
remove: function() {
Ext.Error.raise('remove operation not suppported from buffered Store');
},
removeAt: function() {
Ext.Error.raise('removeAt operation not suppported from buffered Store');
},
removeAtKey: function(page) {
var me = this,
thePage = me.getPage(page),
len, i, result;
if (thePage) {
if (me.fireEvent('beforepageremove', me, page, thePage) !== false) {
len = thePage.length;
for (i = 0; i < len; i++) {
delete me.indexMap[thePage[i].internalId];
}
result = me.callParent(arguments);
me.fireEvent('pageremove', me, page, thePage);
thePage.length = 0;
}
}
return result;
},
getPage: function(pageNumber) {
return this.get(pageNumber);
},
hasRange: function(start, end) {
var pageNumber = this.getPageFromRecordIndex(start),
endPageNumber = this.getPageFromRecordIndex(end);
for (; pageNumber <= endPageNumber; pageNumber++) {
if (!this.hasPage(pageNumber)) {
return false;
}
}
return true;
},
hasPage: function(pageNumber) {
return !!this.get(pageNumber);
},
peekPage: function(pageNumber) {
return this.map[pageNumber];
},
getAt: function(index) {
return this.getRange(index, index + 1)[0];
},
getRange: function(start, end) {
end--;
if (!this.hasRange(start, end)) {
Ext.Error.raise('PageMap asked for range which it does not have');
}
var me = this,
pageSize = me.getPageSize(),
startPageNumber = me.getPageFromRecordIndex(start),
endPageNumber = me.getPageFromRecordIndex(end),
dataStart = (startPageNumber - 1) * pageSize,
dataEnd = (endPageNumber * pageSize) - 1,
pageNumber = startPageNumber,
result = [],
sliceBegin, sliceEnd, doSlice;
for (; pageNumber <= endPageNumber; pageNumber++) {
if (pageNumber === startPageNumber) {
sliceBegin = start - dataStart;
doSlice = true;
} else {
sliceBegin = 0;
doSlice = false;
}
if (pageNumber === endPageNumber) {
sliceEnd = pageSize - (dataEnd - end);
doSlice = true;
}
if (doSlice) {
Ext.Array.push(result, Ext.Array.slice(me.getPage(pageNumber), sliceBegin, sliceEnd));
} else {
Ext.Array.push(result, me.getPage(pageNumber));
}
}
return result;
}
});
Ext.define('Ext.data.BufferedStore', {
extend: 'Ext.data.ProxyStore',
alias: 'store.buffered',
requires: [
'Ext.data.PageMap',
'Ext.util.Filter',
'Ext.util.Sorter',
'Ext.util.Grouper'
],
uses: [
'Ext.util.SorterCollection',
'Ext.util.FilterCollection',
'Ext.util.GroupCollection'
],
isBufferedStore: true,
buffered: true,
config: {
data: 0,
pageSize: 25,
remoteSort: true,
remoteFilter: true,
sortOnLoad: false,
purgePageCount: 5,
trailingBufferZone: 25,
leadingBufferZone: 200,
defaultViewSize: 100,
viewSize: 0,
trackRemoved: false
},
applyData: function(data) {
var dataCollection = this.data || (this.data = this.createDataCollection());
if (data && data !== true) {
Ext.Error.raise('Cannot load a buffered store with local data - the store is a map of remote data');
}
return dataCollection;
},
applyProxy: function(proxy) {
proxy = this.callParent([
proxy
]);
if (proxy && proxy.setEnablePaging) {
proxy.setEnablePaging(true);
}
return proxy;
},
createFiltersCollection: function() {
return new Ext.util.FilterCollection();
},
createSortersCollection: function() {
return new Ext.util.SorterCollection();
},
updateRemoteFilter: function(remoteFilter, oldRemoteFilter) {
if (remoteFilter === false) {
Ext.Error.raise('Buffered stores are always remotely filtered.');
}
this.callParent([
remoteFilter,
oldRemoteFilter
]);
},
updateRemoteSort: function(remoteSort, oldRemoteSort) {
if (remoteSort === false) {
Ext.Error.raise('Buffered stores are always remotely sorted.');
}
this.callParent([
remoteSort,
oldRemoteSort
]);
},
updateTrackRemoved: function(value) {
if (value !== false) {
Ext.Error.raise('Cannot use trackRemoved with a buffered store.');
}
this.callParent(arguments);
},
updateGroupField: function(field) {
var me = this;
if (me.isInitializing) {
me.blockLoad();
}
me.group(field);
if (me.isInitializing) {
me.unblockLoad();
}
},
getGrouper: function() {
return this.grouper;
},
isGrouped: function() {
return !!this.grouper;
},
createDataCollection: function() {
var me = this,
result = new Ext.data.PageMap({
store: me,
rootProperty: 'data',
pageSize: me.getPageSize(),
maxSize: me.getPurgePageCount(),
listeners: {
clear: me.onPageMapClear,
scope: me
}
});
me.relayEvents(result, [
'beforepageremove',
'pageadd',
'pageremove'
]);
me.pageRequests = {};
return result;
},
add: function() {
Ext.Error.raise('add method may not be called on a buffered store - the store is a map of remote data');
},
insert: function() {
Ext.Error.raise('insert method may not be called on a buffered store - the store is a map of remote data');
},
removeAll: function(silent) {
var me = this,
data = me.getData();
if (data) {
if (silent) {
me.suspendEvent('clear');
}
data.clear();
if (silent) {
me.resumeEvent('clear');
}
}
},
load: function(options) {
var me = this;
options = options || {};
me.getData().clear();
options.page = 1;
options.start = 0;
options.limit = me.getViewSize() || me.getDefaultViewSize();
options.loadCallback = options.callback;
delete options.callback;
return me.loadToPrefetch(options);
},
reload: function(options) {
var me = this,
data = me.getData(),
lastTotal = Number.MAX_VALUE,
startIdx, endIdx, startPage, endPage, i, waitForReload, bufferZone, records;
if (me.loading) {
return;
}
if (!options) {
options = {};
}
data.clear(true);
waitForReload = function() {
if (me.rangeCached(startIdx, endIdx)) {
me.loading = false;
data.un('pageadd', waitForReload);
records = data.getRange(startIdx, endIdx + 1);
me.fireEvent('load', me, records, true);
me.fireEvent('refresh', me);
}
};
bufferZone = Math.ceil((me.getLeadingBufferZone() + me.getTrailingBufferZone()) / 2);
if (!me.lastRequestStart) {
startIdx = options.start || 0;
endIdx = startIdx + (options.count || me.getPageSize()) - 1;
} else {
startIdx = me.lastRequestStart;
endIdx = me.lastRequestEnd;
lastTotal = me.getTotalCount();
}
delete me.totalCount;
startIdx = Math.max(startIdx - bufferZone, 0);
endIdx = Math.min(endIdx + bufferZone, lastTotal);
startPage = me.getPageFromRecordIndex(startIdx);
endPage = me.getPageFromRecordIndex(endIdx);
if (me.fireEvent('beforeload', me, options) !== false) {
me.loading = true;
data.on('pageadd', waitForReload);
for (i = startPage; i <= endPage; i++) {
me.prefetchPage(i, options);
}
}
},
filter: function() {
if (!this.getRemoteFilter()) {
Ext.Error.raise('Local filtering may not be used on a buffered store - the store is a map of remote data');
}
this.getData().clear();
this.callParent(arguments);
},
clearFilter: function() {
this.getData().clear();
this.callParent(arguments);
},
filterBy: function(fn, scope) {
Ext.Error.raise('Local filtering may not be used on a buffered store - the store is a map of remote data');
},
loadData: function(data, append) {
Ext.Error.raise('LoadData may not be used on a buffered store - the store is a map of remote data');
},
loadPage: function(page, options) {
var me = this;
options = options || {};
options.page = me.currentPage = page;
options.start = (page - 1) * me.getPageSize();
options.limit = me.getViewSize() || me.getDefaultViewSize();
options.loadCallback = options.callback;
delete options.callback;
return me.loadToPrefetch(options);
},
clearData: function(isLoad) {
var me = this,
data = me.getData();
if (data) {
data.clear();
}
},
getCount: function() {
return this.totalCount || 0;
},
getRange: function(start, end, options) {
var me = this,
maxIndex = me.totalCount - 1,
lastRequestStart = me.lastRequestStart,
result = [],
data = me.getData(),
pageAddHandler, requiredStart, requiredEnd, requiredStartPage, requiredEndPage;
options = Ext.apply({
prefetchStart: start,
prefetchEnd: end
}, options);
end = (end >= me.totalCount) ? maxIndex : end;
requiredStart = start === 0 ? 0 : start - 1;
requiredEnd = end === maxIndex ? end : end + 1;
me.lastRequestStart = start;
me.lastRequestEnd = end;
if (me.rangeCached(requiredStart, requiredEnd)) {
me.onRangeAvailable(options);
result = data.getRange(start, end + 1);
} else
{
me.fireEvent('cachemiss', me, start, end);
requiredStartPage = me.getPageFromRecordIndex(requiredStart);
requiredEndPage = me.getPageFromRecordIndex(requiredEnd);
pageAddHandler = function(pageMap, page, records) {
if (page >= requiredStartPage && page <= requiredEndPage && me.rangeCached(requiredStart, requiredEnd)) {
me.fireEvent('cachefilled', me, start, end);
data.un('pageadd', pageAddHandler);
me.onRangeAvailable(options);
}
};
data.on('pageadd', pageAddHandler);
me.prefetchRange(start, end);
}
me.primeCache(start, end, start < lastRequestStart ? -1 : 1);
return result;
},
getById: function(id) {
var result = this.data.findBy(function(record) {
return record.getId() === id;
});
return result;
},
getAt: function(index) {
var data = this.getData();
if (data.hasRange(index, index)) {
return data.getAt(index);
}
},
getByInternalId: function(internalId) {
return this.data.getByInternalId(internalId);
},
indexOf: function(record) {
return this.getData().indexOf(record);
},
indexOfId: function(id) {
return this.indexOf(this.getById(id));
},
group: function(grouper, direction) {
var me = this,
oldGrouper;
if (grouper && typeof grouper === 'string') {
oldGrouper = me.grouper;
if (!oldGrouper) {
me.grouper = new Ext.util.Grouper({
property: grouper,
direction: direction || 'ASC',
root: 'data'
});
} else if (direction === undefined) {
oldGrouper.toggle();
} else {
oldGrouper.setDirection(direction);
}
} else {
me.grouper = grouper ? me.getSorters().decodeSorter(grouper, 'Ext.util.Grouper') : null;
}
if (me.isLoadBlocked()) {
return;
}
me.getData().clear();
me.loadPage(1, {
callback: function() {
me.fireEvent('groupchange', me, me.getGrouper());
}
});
},
getPageFromRecordIndex: function(index) {
return Math.floor(index / this.getPageSize()) + 1;
},
calculatePageCacheSize: function(rangeSizeRequested) {
var me = this,
purgePageCount = me.getPurgePageCount();
return purgePageCount ? Math.max(me.getData().getMaxSize() || 0, Math.ceil((rangeSizeRequested + me.getTrailingBufferZone() + me.getLeadingBufferZone()) / me.getPageSize()) * 2 + purgePageCount) : 0;
},
loadToPrefetch: function(options) {
var me = this,
prefetchOptions = options,
i, records, dataSetSize,
startIdx = options.start,
endIdx = options.start + options.limit - 1,
rangeSizeRequested = (me.getViewSize() || options.limit),
loadEndIdx = Math.min(endIdx, options.start + rangeSizeRequested - 1),
startPage = me.getPageFromRecordIndex(Math.max(startIdx - me.getTrailingBufferZone(), 0)),
endPage = me.getPageFromRecordIndex(endIdx + me.getLeadingBufferZone()),
data = me.getData(),
callbackFn = function() {
records = records || [];
if (options.loadCallback) {
options.loadCallback.call(options.scope || me, records, operation, true);
}
if (options.callback) {
options.callback.call(options.scope || me, records, startIdx || 0, endIdx || 0, options);
}
},
fireEventsFn = function() {
me.fireEvent('datachanged', me);
me.fireEvent('refresh', me);
me.fireEvent('load', me, records, true);
},
waitForRequestedRange = function() {
if (me.rangeCached(startIdx, loadEndIdx)) {
me.loading = false;
records = data.getRange(startIdx, loadEndIdx + 1);
data.un('pageadd', waitForRequestedRange);
if (me.hasListeners.guaranteedrange) {
me.guaranteeRange(startIdx, loadEndIdx, options.callback, options.scope);
}
callbackFn();
fireEventsFn();
}
},
operation;
if (isNaN(me.pageSize) || !me.pageSize) {
Ext.Error.raise('Buffered store configured without a pageSize', me);
}
data.setMaxSize(me.calculatePageCacheSize(rangeSizeRequested));
if (me.fireEvent('beforeload', me, options) !== false) {
delete me.totalCount;
me.loading = true;
if (options.callback) {
prefetchOptions = Ext.apply({}, options);
delete prefetchOptions.callback;
}
me.on('prefetch', function(store, records, successful, op) {
operation = op;
if (successful) {
if ((dataSetSize = me.getTotalCount())) {
data.on('pageadd', waitForRequestedRange);
loadEndIdx = Math.min(loadEndIdx, dataSetSize - 1);
endPage = me.getPageFromRecordIndex(Math.min(loadEndIdx + me.getLeadingBufferZone(), dataSetSize - 1));
for (i = startPage + 1; i <= endPage; ++i) {
me.prefetchPage(i, prefetchOptions);
}
} else {
callbackFn();
fireEventsFn();
}
} else
{
callbackFn();
me.fireEvent('load', me, records, false);
}
}, null, {
single: true
});
me.prefetchPage(startPage, prefetchOptions);
}
},
prefetch: function(options) {
var me = this,
pageSize = me.getPageSize(),
data = me.getData(),
operation;
if (pageSize) {
if (me.lastPageSize && pageSize != me.lastPageSize) {
Ext.Error.raise("pageSize cannot be dynamically altered");
}
if (!data.getPageSize()) {
data.setPageSize(pageSize);
}
} else
{
me.pageSize = data.setPageSize(pageSize = options.limit);
}
me.lastPageSize = pageSize;
if (!options.page) {
options.page = me.getPageFromRecordIndex(options.start);
options.start = (options.page - 1) * pageSize;
options.limit = Math.ceil(options.limit / pageSize) * pageSize;
}
if (!me.pageRequests[options.page]) {
options = Ext.apply({
action: 'read',
filters: me.getFilters().items,
sorters: me.getSorters().items,
grouper: me.getGrouper(),
internalCallback: me.onProxyPrefetch,
internalScope: me
}, options);
operation = me.createOperation('read', options);
operation.pageMapGeneration = data.pageMapGeneration;
if (me.fireEvent('beforeprefetch', me, operation) !== false) {
me.pageRequests[options.page] = operation.execute();
if (me.getProxy().isSynchronous) {
delete me.pageRequests[options.page];
}
}
}
return me;
},
onPageMapClear: function() {
var me = this,
loadingFlag = me.wasLoading,
reqs = me.pageRequests,
data = me.getData(),
req, page;
data.clearListeners();
data.on('clear', me.onPageMapClear, me);
me.relayEvents(data, [
'beforepageremove',
'pageadd',
'pageremove'
]);
me.loading = true;
me.totalCount = 0;
for (page in reqs) {
if (reqs.hasOwnProperty(page)) {
req = reqs[page];
delete reqs[page];
delete req.callback;
}
}
me.fireEvent('clear', me);
me.loading = loadingFlag;
},
prefetchPage: function(page, options) {
var me = this,
pageSize = me.getPageSize(),
start = (page - 1) * pageSize,
total = me.totalCount;
if (total !== undefined && me.data.getCount() === total) {
return;
}
me.prefetch(Ext.applyIf({
page: page,
start: start,
limit: pageSize
}, options));
},
onProxyPrefetch: function(operation) {
var me = this,
resultSet = operation.getResultSet(),
records = operation.getRecords(),
successful = operation.wasSuccessful(),
page = operation.getPage(),
oldTotal = me.totalCount;
if (operation.pageMapGeneration === me.getData().pageMapGeneration) {
if (resultSet) {
me.totalCount = resultSet.getTotal();
if (me.totalCount !== oldTotal) {
me.fireEvent('totalcountchange', me.totalCount);
}
}
if (page !== undefined) {
delete me.pageRequests[page];
}
me.loading = false;
me.fireEvent('prefetch', me, records, successful, operation);
if (successful) {
me.cachePage(records, operation.getPage());
}
Ext.callback(operation.getCallback(), operation.getScope() || me, [
records,
operation,
successful
]);
}
},
cachePage: function(records, page) {
var me = this,
len = records.length,
i;
if (!Ext.isDefined(me.totalCount)) {
me.totalCount = records.length;
me.fireEvent('totalcountchange', me.totalCount);
}
for (i = 0; i < len; i++) {
records[i].join(me);
}
me.getData().addPage(page, records);
},
rangeCached: function(start, end) {
return this.getData().hasRange(start, end);
},
pageCached: function(page) {
return this.getData().hasPage(page);
},
pagePending: function(page) {
return !!this.pageRequests[page];
},
rangeSatisfied: function(start, end) {
return this.rangeCached(start, end);
},
onRangeAvailable: function(options) {
var me = this,
totalCount = me.getTotalCount(),
start = options.prefetchStart,
end = (options.prefetchEnd > totalCount - 1) ? totalCount - 1 : options.prefetchEnd,
range;
end = Math.max(0, end);
if (start > end) {
Ext.log({
level: 'warn',
msg: 'Start (' + start + ') was greater than end (' + end + ') for the range of records requested (' + start + '-' + options.prefetchEnd + ')' + (this.storeId ? ' from store "' + this.storeId + '"' : '')
});
}
range = me.getData().getRange(start, end + 1);
if (options.fireEvent !== false) {
me.fireEvent('guaranteedrange', range, start, end, options);
}
if (options.callback) {
options.callback.call(options.scope || me, range, start, end, options);
}
},
guaranteeRange: function(start, end, callback, scope, options) {
options = Ext.apply({
callback: callback,
scope: scope
}, options);
this.getRange(start, end + 1, options);
},
prefetchRange: function(start, end) {
var me = this,
startPage, endPage, page,
data = me.getData();
if (!me.rangeCached(start, end)) {
startPage = me.getPageFromRecordIndex(start);
endPage = me.getPageFromRecordIndex(end);
data.setMaxSize(me.calculatePageCacheSize(end - start + 1));
for (page = startPage; page <= endPage; page++) {
if (!me.pageCached(page)) {
me.prefetchPage(page);
}
}
}
},
primeCache: function(start, end, direction) {
var me = this,
leadingBufferZone = me.getLeadingBufferZone(),
trailingBufferZone = me.getTrailingBufferZone(),
pageSize = me.getPageSize(),
totalCount = me.totalCount;
if (direction === -1) {
start = Math.max(start - leadingBufferZone, 0);
end = Math.min(end + trailingBufferZone, totalCount - 1);
}
else if (direction === 1) {
start = Math.max(Math.min(start - trailingBufferZone, totalCount - pageSize), 0);
end = Math.min(end + leadingBufferZone, totalCount - 1);
} else
{
start = Math.min(Math.max(Math.floor(start - ((leadingBufferZone + trailingBufferZone) / 2)), 0), totalCount - me.pageSize);
end = Math.min(Math.max(Math.ceil(end + ((leadingBufferZone + trailingBufferZone) / 2)), 0), totalCount - 1);
}
me.prefetchRange(start, end);
},
sort: function(field, direction, mode) {
if (arguments.length === 0) {
this.clearAndLoad();
} else {
this.getSorters().addSort(field, direction, mode);
}
},
onSorterEndUpdate: function() {
var me = this,
sorters = me.getSorters().getRange();
if (sorters.length) {
me.clearAndLoad({
callback: function() {
me.fireEvent('sort', me, sorters);
}
});
} else {
me.fireEvent('sort', me, sorters);
}
},
clearAndLoad: function(options) {
if (this.isLoadBlocked()) {
return;
}
this.getData().clear();
this.loadPage(1, options);
},
privates: {
isLast: function(record) {
return this.indexOf(record) === this.getTotalCount() - 1;
},
isMoving: function() {
return false;
}
}
});
Ext.define('Ext.data.proxy.Direct', {
extend: 'Ext.data.proxy.Server',
alternateClassName: 'Ext.data.DirectProxy',
alias: 'proxy.direct',
requires: [
'Ext.direct.Manager'
],
config: {
paramOrder: undefined,
paramsAsHash: true,
directFn: undefined,
api: undefined,
metadata: undefined
},
paramOrderRe: /[\s,|]/,
applyParamOrder: function(paramOrder) {
if (Ext.isString(paramOrder)) {
paramOrder = paramOrder.split(this.paramOrderRe);
}
return paramOrder;
},
updateApi: function() {
this.methodsResolved = false;
},
updateDirectFn: function() {
this.methodsResolved = false;
},
resolveMethods: function() {
var me = this,
fn = me.getDirectFn(),
api = me.getApi(),
Manager = Ext.direct.Manager,
method;
if (fn) {
me.setDirectFn(method = Manager.parseMethod(fn));
if (!Ext.isFunction(method)) {
Ext.Error.raise('Cannot resolve directFn ' + fn);
}
}
if (api) {
for (fn in api) {
if (api.hasOwnProperty(fn)) {
method = api[fn];
api[fn] = Manager.parseMethod(method);
if (!Ext.isFunction(api[fn])) {
Ext.Error.raise('Cannot resolve Direct api ' + fn + ' method ' + method);
}
}
}
}
me.methodsResolved = true;
},
doRequest: function(operation) {
var me = this,
writer, request, action, params, args, api, fn, callback;
if (!me.methodsResolved) {
me.resolveMethods();
}
request = me.buildRequest(operation);
action = request.getAction();
api = me.getApi();
if (api) {
fn = api[action];
}
fn = fn || me.getDirectFn();
if (!fn) {
Ext.Error.raise('No Ext.Direct function specified for this proxy');
}
writer = me.getWriter();
if (writer && operation.allowWrite()) {
request = writer.write(request);
}
if (action === 'read') {
params = request.getParams();
} else {
params = request.getJsonData();
}
args = fn.directCfg.method.getArgs({
params: params,
paramOrder: me.getParamOrder(),
paramsAsHash: me.getParamsAsHash(),
metadata: me.getMetadata(),
callback: me.createRequestCallback(request, operation),
scope: me
});
request.setConfig({
args: args,
directFn: fn
});
fn.apply(window, args);
return request;
},
applyEncoding: Ext.identityFn,
createRequestCallback: function(request, operation) {
var me = this;
return function(data, event) {
me.processResponse(event.status, operation, request, event);
};
},
extractResponseData: function(response) {
return Ext.isDefined(response.result) ? response.result : response.data;
},
setException: function(operation, response) {
operation.setException(response.message);
},
buildUrl: function() {
return '';
}
});
Ext.define('Ext.data.DirectStore', {
extend: 'Ext.data.Store',
alias: 'store.direct',
requires: [
'Ext.data.proxy.Direct'
],
constructor: function(config) {
config = Ext.apply({}, config);
if (!config.proxy) {
var proxy = {
type: 'direct',
reader: {
type: 'json'
}
};
Ext.copyTo(proxy, config, 'paramOrder,paramsAsHash,directFn,api,simpleSortMode,extraParams');
Ext.copyTo(proxy.reader, config, 'totalProperty,root,rootProperty,idProperty');
config.proxy = proxy;
}
this.callParent([
config
]);
}
});
Ext.define('Ext.data.JsonP', {
singleton: true,
requestCount: 0,
requests: {},
timeout: 30000,
disableCaching: true,
disableCachingParam: '_dc',
callbackKey: 'callback',
request: function(options) {
options = Ext.apply({}, options);
if (!options.url) {
Ext.Error.raise('A url must be specified for a JSONP request.');
}
var me = this,
disableCaching = Ext.isDefined(options.disableCaching) ? options.disableCaching : me.disableCaching,
cacheParam = options.disableCachingParam || me.disableCachingParam,
id = ++me.requestCount,
callbackName = options.callbackName || 'callback' + id,
callbackKey = options.callbackKey || me.callbackKey,
timeout = Ext.isDefined(options.timeout) ? options.timeout : me.timeout,
params = Ext.apply({}, options.params),
url = options.url,
name = Ext.name,
request, script;
if (disableCaching && !params[cacheParam]) {
params[cacheParam] = Ext.Date.now();
}
options.params = params;
params[callbackKey] = name + '.data.JsonP.' + callbackName;
script = me.createScript(url, params, options);
me.requests[id] = request = {
url: url,
params: params,
script: script,
id: id,
scope: options.scope,
success: options.success,
failure: options.failure,
callback: options.callback,
callbackKey: callbackKey,
callbackName: callbackName
};
if (timeout > 0) {
request.timeout = Ext.defer(me.handleTimeout, timeout, me, [
request
]);
}
me.setupErrorHandling(request);
me[callbackName] = Ext.bind(me.handleResponse, me, [
request
], true);
me.loadScript(request);
return request;
},
abort: function(request) {
var me = this,
requests = me.requests,
key;
if (request) {
if (!request.id) {
request = requests[request];
}
me.handleAbort(request);
} else {
for (key in requests) {
if (requests.hasOwnProperty(key)) {
me.abort(requests[key]);
}
}
}
},
setupErrorHandling: function(request) {
request.script.onerror = Ext.bind(this.handleError, this, [
request
]);
},
handleAbort: function(request) {
request.errorType = 'abort';
this.handleResponse(null, request);
},
handleError: function(request) {
request.errorType = 'error';
this.handleResponse(null, request);
},
cleanupErrorHandling: function(request) {
request.script.onerror = null;
},
handleTimeout: function(request) {
request.errorType = 'timeout';
this.handleResponse(null, request);
},
handleResponse: function(result, request) {
var success = true,
globalEvents = Ext.GlobalEvents;
if (request.timeout) {
clearTimeout(request.timeout);
}
delete this[request.callbackName];
delete this.requests[request.id];
this.cleanupErrorHandling(request);
Ext.fly(request.script).destroy();
if (request.errorType) {
success = false;
Ext.callback(request.failure, request.scope, [
request.errorType
]);
} else {
Ext.callback(request.success, request.scope, [
result
]);
}
Ext.callback(request.callback, request.scope, [
success,
result,
request.errorType
]);
if (globalEvents.hasListeners.idle) {
globalEvents.fireEvent('idle');
}
},
createScript: function(url, params, options) {
var script = document.createElement('script');
script.setAttribute("src", Ext.urlAppend(url, Ext.Object.toQueryString(params)));
script.setAttribute("async", true);
script.setAttribute("type", "text/javascript");
return script;
},
loadScript: function(request) {
Ext.getHead().appendChild(request.script);
}
});
Ext.define('Ext.data.proxy.JsonP', {
extend: 'Ext.data.proxy.Server',
alternateClassName: 'Ext.data.ScriptTagProxy',
alias: [
'proxy.jsonp',
'proxy.scripttag'
],
requires: [
'Ext.data.JsonP'
],
config: {
callbackKey: 'callback',
recordParam: 'records',
autoAppendParams: true
},
doRequest: function(operation) {
var me = this,
request = me.buildRequest(operation),
params = request.getParams();
request.setConfig({
callbackKey: me.callbackKey,
timeout: me.timeout,
scope: me,
disableCaching: false,
callback: me.createRequestCallback(request, operation)
});
if (me.getAutoAppendParams()) {
request.setParams({});
}
request.setRawRequest(Ext.data.JsonP.request(request.getCurrentConfig()));
request.setParams(params);
me.lastRequest = request;
return request;
},
createRequestCallback: function(request, operation) {
var me = this;
return function(success, response, errorType) {
if (request === me.lastRequest) {
me.lastRequest = null;
}
me.processResponse(success, operation, request, response);
};
},
setException: function(operation, response) {
operation.setException(operation.getRequest().getRawRequest().errorType);
},
buildUrl: function(request) {
var me = this,
url = me.callParent(arguments),
records = request.getRecords(),
writer = me.getWriter(),
params, filters, filter, i, v;
if (writer && request.getOperation().allowWrite()) {
request = writer.write(request);
}
params = request.getParams();
filters = params.filters;
delete params.filters;
if (filters && filters.length) {
for (i = 0; i < filters.length; i++) {
filter = filters[i];
v = filter.getValue();
if (v) {
params[filter.getProperty()] = v;
}
}
}
if (Ext.isArray(records) && records.length > 0 && (!writer || !writer.getEncode())) {
params[me.getRecordParam()] = me.encodeRecords(records);
}
if (me.getAutoAppendParams()) {
url = Ext.urlAppend(url, Ext.Object.toQueryString(params));
}
return url;
},
abort: function(request) {
request = request || this.lastRequest;
if (request) {
Ext.data.JsonP.abort(request.getRawRequest());
}
},
encodeRecords: function(records) {
var encoded = [],
i = 0,
len = records.length;
for (; i < len; i++) {
encoded.push(Ext.encode(records[i].getData()));
}
return encoded;
}
});
Ext.define('Ext.data.JsonPStore', {
extend: 'Ext.data.Store',
alias: 'store.jsonp',
requires: [
'Ext.data.proxy.JsonP',
'Ext.data.reader.Json'
],
constructor: function(config) {
config = Ext.apply({
proxy: {
type: 'jsonp',
reader: 'json'
}
}, config);
this.callParent([
config
]);
}
});
Ext.define('Ext.data.JsonStore', {
extend: 'Ext.data.Store',
alias: 'store.json',
requires: [
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json',
'Ext.data.writer.Json'
],
constructor: function(config) {
config = Ext.apply({
proxy: {
type: 'ajax',
reader: 'json',
writer: 'json'
}
}, config);
this.callParent([
config
]);
}
});
Ext.define('Ext.data.ModelManager', {
alternateClassName: 'Ext.ModelMgr',
requires: [
'Ext.data.schema.Schema'
],
singleton: true,
deprecated: {
5: {
methods: {
clear: null,
create: function(data, name, id) {
var T = name;
if (!T.isEntity) {
T = this.getModel(name || data.name);
}
return T.createWithId(id, data);
},
each: function(fn, scope) {
Ext.data.Model.schema.eachEntity(fn, scope);
},
get: function(name) {
return this.getModel(name);
},
getCount: function() {
return Ext.data.Model.schema.entityCount;
},
getModel: function(id) {
return Ext.data.schema.Schema.lookupEntity(id);
},
isRegistered: function(name) {
return !!this.getModel(name);
}
}
}
}
});
Ext.define('Ext.data.NodeInterface', {
requires: [
'Ext.data.field.Boolean',
'Ext.data.field.Integer',
'Ext.data.field.String',
'Ext.data.writer.Json',
'Ext.mixin.Observable'
],
statics: {
decorate: function(modelClass) {
var model = Ext.data.schema.Schema.lookupEntity(modelClass),
proto = model.prototype,
idName, idField, idType;
if (!model.prototype.isObservable) {
model.mixin(Ext.mixin.Observable.prototype.mixinId, Ext.mixin.Observable);
}
if (proto.isNode) {
return;
}
idName = proto.idProperty;
idField = model.getField(idName);
idType = idField.type;
model.override(this.getPrototypeBody());
model.addFields([
{
name: 'parentId',
type: idType,
defaultValue: null,
allowNull: idField.allowNull
},
{
name: 'index',
type: 'int',
defaultValue: -1,
persist: false,
convert: null
},
{
name: 'depth',
type: 'int',
defaultValue: 0,
persist: false,
convert: null
},
{
name: 'expanded',
type: 'bool',
defaultValue: false,
persist: false,
convert: null
},
{
name: 'expandable',
type: 'bool',
defaultValue: true,
persist: false,
convert: null
},
{
name: 'checked',
type: 'auto',
defaultValue: null,
persist: false,
convert: null
},
{
name: 'leaf',
type: 'bool',
defaultValue: false
},
{
name: 'cls',
type: 'string',
defaultValue: '',
persist: false,
convert: null
},
{
name: 'iconCls',
type: 'string',
defaultValue: '',
persist: false,
convert: null
},
{
name: 'icon',
type: 'string',
defaultValue: '',
persist: false,
convert: null
},
{
name: 'root',
type: 'boolean',
defaultValue: false,
persist: false,
convert: null
},
{
name: 'isLast',
type: 'boolean',
defaultValue: false,
persist: false,
convert: null
},
{
name: 'isFirst',
type: 'boolean',
defaultValue: false,
persist: false,
convert: null
},
{
name: 'allowDrop',
type: 'boolean',
defaultValue: true,
persist: false,
convert: null
},
{
name: 'allowDrag',
type: 'boolean',
defaultValue: true,
persist: false,
convert: null
},
{
name: 'loaded',
type: 'boolean',
defaultValue: false,
persist: false,
convert: null
},
{
name: 'loading',
type: 'boolean',
defaultValue: false,
persist: false,
convert: null
},
{
name: 'href',
type: 'string',
defaultValue: '',
persist: false,
convert: null
},
{
name: 'hrefTarget',
type: 'string',
defaultValue: '',
persist: false,
convert: null
},
{
name: 'qtip',
type: 'string',
defaultValue: '',
persist: false,
convert: null
},
{
name: 'qtitle',
type: 'string',
defaultValue: '',
persist: false,
convert: null
},
{
name: 'qshowDelay',
type: 'int',
defaultValue: 0,
persist: false,
convert: null
},
{
name: 'children',
type: 'auto',
defaultValue: null,
persist: false,
convert: null
},
{
name: 'visible',
type: 'boolean',
defaultValue: true,
persist: false
},
{
name: 'text',
type: 'string',
persist: false
}
]);
},
getPrototypeBody: function() {
var bubbledEvents = {
idchanged: true,
append: true,
remove: true,
move: true,
insert: true,
beforeappend: true,
beforeremove: true,
beforemove: true,
beforeinsert: true,
expand: true,
collapse: true,
beforeexpand: true,
beforecollapse: true,
sort: true
},
silently = {
silent: true
};
return {
isNode: true,
firstChild: null,
lastChild: null,
parentNode: null,
previousSibling: null,
nextSibling: null,
constructor: function() {
var me = this;
me.mixins.observable.constructor.call(me);
me.callParent(arguments);
me.childNodes = [];
return me;
},
createNode: function(node) {
var me = this,
childType = me.childType,
store, storeReader, nodeProxy, nodeReader, reader, typeProperty,
T = me.self;
if (!node.isModel) {
if (childType) {
T = me.schema.getEntity(childType);
} else
{
store = me.getTreeStore();
storeReader = store && store.getProxy().getReader();
nodeProxy = me.getProxy();
nodeReader = nodeProxy ? nodeProxy.getReader() : null;
reader = !storeReader || (nodeReader && nodeReader.initialConfig.typeProperty) ? nodeReader : storeReader;
if (reader) {
typeProperty = reader.getTypeProperty();
if (typeProperty) {
T = reader.getChildType(me.schema, node, typeProperty);
}
}
}
node = new T(node);
}
if (!node.childNodes) {
node.firstChild = node.lastChild = node.parentNode = node.previousSibling = node.nextSibling = null;
node.childNodes = [];
}
return node;
},
isLeaf: function() {
return this.get('leaf') === true;
},
setFirstChild: function(node) {
this.firstChild = node;
},
setLastChild: function(node) {
this.lastChild = node;
},
updateInfo: function(commit, info) {
var me = this,
dataObject = me.data,
oldDepth = dataObject.depth,
childInfo = {},
children = me.childNodes,
childCount = children.length,
phantom = me.phantom,
fields = me.fields,
modified = me.modified || (me.modified = {}),
propName, newValue, field, currentValue, key,
newParentId = info.parentId,
settingIndexInNewParent, persistentField, i;
if (!info) {
Ext.Error.raise('NodeInterface expects update info to be passed');
}
for (propName in info) {
field = fields[me.fieldOrdinals[propName]];
newValue = info[propName];
persistentField = field && field.persist;
currentValue = dataObject[propName];
settingIndexInNewParent = persistentField && (propName === 'index') && (currentValue !== -1) && (newParentId && newParentId !== modified.parentId);
if (!settingIndexInNewParent && me.isEqual(currentValue, newValue)) {
continue;
}
dataObject[propName] = newValue;
if (persistentField) {
if (!settingIndexInNewParent && modified.hasOwnProperty(propName)) {
if (me.isEqual(modified[propName], newValue)) {
delete modified[propName];
me.dirty = false;
for (key in modified) {
if (modified.hasOwnProperty(key)) {
me.dirty = true;
break;
}
}
}
} else
{
me.dirty = true;
modified[propName] = currentValue;
}
}
}
if (commit) {
me.commit();
me.phantom = phantom;
}
if (me.data.depth !== oldDepth) {
childInfo = {
depth: me.data.depth + 1
};
for (i = 0; i < childCount; i++) {
children[i].updateInfo(commit, childInfo);
}
}
},
isLast: function() {
return this.get('isLast');
},
isFirst: function() {
return this.get('isFirst');
},
hasChildNodes: function() {
return !this.isLeaf() && this.childNodes.length > 0;
},
isExpandable: function() {
var me = this;
if (me.get('expandable')) {
return !(me.isLeaf() || (me.isLoaded() && !me.phantom && !me.hasChildNodes()));
}
return false;
},
triggerUIUpdate: function() {
this.callJoined('afterEdit', []);
},
appendChild: function(node, suppressEvents, commit) {
var me = this,
i, ln, index, oldParent, previousSibling,
childInfo = {
isLast: true,
parentId: me.getId(),
depth: (me.data.depth || 0) + 1
},
result,
treeStore = me.getTreeStore(),
bulkUpdate = treeStore && treeStore.bulkUpdate;
Ext.suspendLayouts();
if (Ext.isArray(node)) {
ln = node.length;
result = new Array(ln);
me.callTreeStore('beginFill');
for (i = 0; i < ln; i++) {
result[i] = me.appendChild(node[i], suppressEvents, commit);
}
me.callTreeStore('endFill', [
result
]);
} else {
node = me.createNode(node);
if (suppressEvents !== true && me.fireEventArgs('beforeappend', [
me,
node
]) === false) {
Ext.resumeLayouts(true);
return false;
}
index = me.childNodes.length;
oldParent = node.parentNode;
if (oldParent) {
if (suppressEvents !== true && node.fireEventArgs('beforemove', [
node,
oldParent,
me,
index
]) === false) {
Ext.resumeLayouts(true);
return false;
}
if (oldParent.removeChild(node, false, suppressEvents, oldParent.getTreeStore() === treeStore) === false) {
Ext.resumeLayouts(true);
return false;
}
}
treeStore && treeStore.beginUpdate();
index = me.childNodes.length;
if (index === 0) {
me.setFirstChild(node);
}
me.childNodes[index] = node;
node.parentNode = me;
node.nextSibling = null;
me.setLastChild(node);
previousSibling = me.childNodes[index - 1];
if (previousSibling) {
node.previousSibling = previousSibling;
previousSibling.nextSibling = node;
previousSibling.updateInfo(commit, {
isLast: false
});
if (!bulkUpdate) {
previousSibling.triggerUIUpdate();
}
} else {
node.previousSibling = null;
}
childInfo.isFirst = index === 0;
childInfo.index = index;
node.updateInfo(commit, childInfo);
if (me.isLeaf()) {
me.set('leaf', false);
}
if (!me.isLoaded()) {
if (bulkUpdate) {
me.data.loaded = true;
} else {
me.set('loaded', true);
}
} else if (me.childNodes.length === 1 && !bulkUpdate) {
me.triggerUIUpdate();
}
if (index && me.childNodes[index - 1].isExpanded() && !bulkUpdate) {
me.childNodes[index - 1].cascadeBy(me.triggerUIUpdate);
}
if (treeStore) {
treeStore.registerNode(me, !bulkUpdate);
if (bulkUpdate) {
treeStore.registerNode(node);
}
}
if (suppressEvents !== true) {
me.fireEventArgs('append', [
me,
node,
index
]);
if (oldParent) {
node.fireEventArgs('move', [
node,
oldParent,
me,
index
]);
}
}
me.callTreeStore('onNodeAppend', [
node,
index
]);
result = node;
if (treeStore) {
treeStore.endUpdate();
}
}
Ext.resumeLayouts(true);
return result;
},
getOwnerTree: function() {
var store = this.getTreeStore();
if (store) {
return store.ownerTree;
}
},
getTreeStore: function() {
var root = this;
while (root && !root.treeStore) {
root = root.parentNode;
}
return root && root.treeStore;
},
removeChild: function(node, erase, suppressEvents, isMove) {
var me = this,
index = me.indexOf(node),
i, childCount, previousSibling,
treeStore = me.getTreeStore(),
bulkUpdate = treeStore && treeStore.bulkUpdate,
removeContext;
if (index === -1 || (suppressEvents !== true && me.fireEventArgs('beforeremove', [
me,
node,
!!isMove
]) === false)) {
return false;
}
Ext.suspendLayouts();
treeStore && treeStore.beginUpdate();
Ext.Array.erase(me.childNodes, index, 1);
if (me.firstChild === node) {
me.setFirstChild(node.nextSibling);
}
if (me.lastChild === node) {
me.setLastChild(node.previousSibling);
}
previousSibling = node.previousSibling;
if (previousSibling) {
node.previousSibling.nextSibling = node.nextSibling;
}
if (node.nextSibling) {
node.nextSibling.previousSibling = node.previousSibling;
if (index === 0) {
node.nextSibling.updateInfo(false, {
isFirst: true
});
}
for (i = index , childCount = me.childNodes.length; i < childCount; i++) {
me.childNodes[i].updateInfo(false, {
index: i
});
}
}
else if (previousSibling) {
previousSibling.updateInfo(false, {
isLast: true
});
if (!bulkUpdate) {
if (previousSibling.isExpanded()) {
previousSibling.cascadeBy(me.triggerUIUpdate);
} else
{
previousSibling.triggerUIUpdate();
}
}
}
if (!me.childNodes.length && !bulkUpdate) {
me.triggerUIUpdate();
}
Ext.resumeLayouts(true);
if (suppressEvents !== true) {
removeContext = {
parentNode: node.parentNode,
previousSibling: node.previousSibling,
nextSibling: node.nextSibling
};
me.callTreeStore('beforeNodeRemove', [
[
node
],
!!isMove
]);
node.previousSibling = node.nextSibling = node.parentNode = null;
me.fireEventArgs('remove', [
me,
node,
!!isMove,
removeContext
]);
me.callTreeStore('onNodeRemove', [
[
node
],
!!isMove
]);
}
if (erase) {
node.erase(true);
} else {
node.clear();
}
if (!isMove) {
node.set({
parentId: null,
lastParentId: me.getId()
}, silently);
}
if (treeStore) {
treeStore.endUpdate();
}
return node;
},
copy: function(newId, deep) {
var me = this,
result = me.callParent([
newId
]),
len = me.childNodes ? me.childNodes.length : 0,
i;
if (deep) {
for (i = 0; i < len; i++) {
result.appendChild(me.childNodes[i].copy(undefined, true));
}
}
return result;
},
clear: function(erase) {
var me = this;
me.parentNode = me.previousSibling = me.nextSibling = null;
if (erase) {
me.firstChild = me.lastChild = me.childNodes = null;
}
},
drop: function() {
var me = this,
childNodes = me.childNodes,
parentNode = me.parentNode,
len = childNodes ? childNodes.length : 0,
i, node, treeStore;
me.callParent();
if (parentNode) {
treeStore = me.getTreeStore();
parentNode.removeChild(me);
}
else if (me.get('root')) {
treeStore = me.getTreeStore();
treeStore.setRoot(null);
}
treeStore && treeStore.beginUpdate();
for (i = 0; i < len; i++) {
node = childNodes[i];
node.clear();
node.drop();
}
treeStore && treeStore.endUpdate();
},
erase: function(options) {
var me = this,
childNodes = me.childNodes,
len = childNodes && childNodes.length,
i, node;
me.remove();
me.clear(true);
me.callParent([
options
]);
for (i = 0; i < len; i++) {
node = childNodes[i];
node.parentNode = null;
node.erase(options);
}
},
insertBefore: function(node, refNode, suppressEvents) {
var me = this,
index = me.indexOf(refNode),
oldParent = node.parentNode,
refIndex = index,
childCount, previousSibling, i,
treeStore = me.getTreeStore(),
bulkUpdate = treeStore && treeStore.bulkUpdate;
if (!refNode) {
return me.appendChild(node);
}
if (node === refNode) {
return false;
}
node = me.createNode(node);
if (suppressEvents !== true && me.fireEventArgs('beforeinsert', [
me,
node,
refNode
]) === false) {
return false;
}
if (oldParent === me && me.indexOf(node) < index) {
refIndex--;
}
if (oldParent) {
if (suppressEvents !== true && node.fireEventArgs('beforemove', [
node,
oldParent,
me,
index,
refNode
]) === false) {
return false;
}
if (oldParent.removeChild(node, false, suppressEvents, oldParent.getTreeStore() === treeStore) === false) {
return false;
}
}
treeStore && treeStore.beginUpdate();
if (refIndex === 0) {
me.setFirstChild(node);
}
Ext.Array.splice(me.childNodes, refIndex, 0, node);
node.parentNode = me;
node.nextSibling = refNode;
refNode.previousSibling = node;
previousSibling = me.childNodes[refIndex - 1];
if (previousSibling) {
node.previousSibling = previousSibling;
previousSibling.nextSibling = node;
} else {
node.previousSibling = null;
}
node.updateInfo(false, {
parentId: me.getId(),
index: refIndex,
isFirst: refIndex === 0,
isLast: false,
depth: (me.data.depth || 0) + 1
});
for (i = refIndex + 1 , childCount = me.childNodes.length; i < childCount; i++) {
me.childNodes[i].updateInfo(false, {
index: i
});
}
if (!me.isLoaded()) {
if (bulkUpdate) {
me.data.loaded = true;
} else {
me.set('loaded', true);
}
}
else if (me.childNodes.length === 1 && !bulkUpdate) {
me.triggerUIUpdate();
}
if (treeStore) {
treeStore.registerNode(me, !bulkUpdate);
}
if (suppressEvents !== true) {
me.fireEventArgs('insert', [
me,
node,
refNode
]);
if (oldParent) {
node.fireEventArgs('move', [
node,
oldParent,
me,
refIndex,
refNode
]);
}
}
me.callTreeStore('onNodeInsert', [
node,
refIndex
]);
if (treeStore) {
treeStore.endUpdate();
}
return node;
},
insertChild: function(index, node) {
var sibling = this.childNodes[index];
if (sibling) {
return this.insertBefore(node, sibling);
} else {
return this.appendChild(node);
}
},
isLastVisible: function() {
var me = this,
result = me.data.isLast,
next = me.nextSibling;
if (!result && me.getTreeStore().isFiltered()) {
while (next) {
if (next.data.visible) {
return false;
}
next = next.nextSibling;
}
return true;
}
return result;
},
remove: function(erase, suppressEvents) {
var me = this,
parentNode = me.parentNode;
if (parentNode) {
parentNode.removeChild(me, erase, suppressEvents);
} else if (erase) {
me.erase(true);
}
return me;
},
removeAll: function(erase, suppressEvents, fromParent) {
var me = this,
childNodes = me.childNodes,
len = childNodes.length,
node, treeStore, i;
if (!len) {
return;
}
if (!fromParent) {
treeStore = me.getTreeStore();
if (treeStore) {
treeStore.beginUpdate();
treeStore.suspendEvent('remove');
me.callTreeStore('beforeNodeRemove', [
childNodes,
false
]);
}
}
for (i = 0; i < len; ++i) {
node = childNodes[i];
node.previousSibling = node.nextSibling = node.parentNode = null;
me.fireEventArgs('remove', [
me,
node,
false
]);
if (erase) {
node.erase(true);
} else
{
node.removeAll(false, suppressEvents, true);
}
}
if (!fromParent && treeStore) {
treeStore.resumeEvent('remove');
me.callTreeStore('onNodeRemove', [
childNodes,
false
]);
treeStore.endUpdate();
}
me.firstChild = me.lastChild = null;
childNodes.length = 0;
if (!fromParent) {
me.triggerUIUpdate();
}
return me;
},
getChildAt: function(index) {
return this.childNodes[index];
},
replaceChild: function(newChild, oldChild, suppressEvents) {
var s = oldChild ? oldChild.nextSibling : null;
this.removeChild(oldChild, false, suppressEvents);
this.insertBefore(newChild, s, suppressEvents);
return oldChild;
},
indexOf: function(child) {
return Ext.Array.indexOf(this.childNodes, child);
},
indexOfId: function(id) {
var childNodes = this.childNodes,
len = childNodes.length,
i = 0;
for (; i < len; ++i) {
if (childNodes[i].getId() === id) {
return i;
}
}
return -1;
},
getPath: function(field, separator) {
field = field || this.idProperty;
separator = separator || '/';
var path = [
this.get(field)
],
parent = this.parentNode;
while (parent) {
path.unshift(parent.get(field));
parent = parent.parentNode;
}
return separator + path.join(separator);
},
getDepth: function() {
return this.get('depth');
},
bubble: function(fn, scope, args) {
var p = this;
while (p) {
if (fn.apply(scope || p, args || [
p
]) === false) {
break;
}
p = p.parentNode;
}
},
cascade: function() {
if (Ext.isDefined(Ext.global.console)) {
Ext.global.console.warn('Ext.data.Node: cascade has been deprecated. Please use cascadeBy instead.');
}
return this.cascadeBy.apply(this, arguments);
},
cascadeBy: function(before, scope, args, after) {
var me = this;
if (arguments.length === 1 && !Ext.isFunction(before)) {
after = before.after;
scope = before.scope;
args = before.args;
before = before.before;
}
if (!before || before.apply(scope || me, args || [
me
]) !== false) {
var childNodes = me.childNodes,
length = childNodes.length,
i;
for (i = 0; i < length; i++) {
childNodes[i].cascadeBy.call(childNodes[i], before, scope, args, after);
}
if (after) {
after.apply(scope || me, args || [
me
]);
}
}
},
eachChild: function(fn, scope, args) {
var childNodes = this.childNodes,
length = childNodes.length,
i;
for (i = 0; i < length; i++) {
if (fn.apply(scope || this, args || [
childNodes[i]
]) === false) {
break;
}
}
},
findChild: function(attribute, value, deep) {
return this.findChildBy(function() {
return this.get(attribute) == value;
}, null, deep);
},
findChildBy: function(fn, scope, deep) {
var cs = this.childNodes,
len = cs.length,
i = 0,
n, res;
for (; i < len; i++) {
n = cs[i];
if (fn.call(scope || n, n) === true) {
return n;
} else if (deep) {
res = n.findChildBy(fn, scope, deep);
if (res !== null) {
return res;
}
}
}
return null;
},
contains: function(node) {
return node.isAncestor(this);
},
isAncestor: function(node) {
var p = this.parentNode;
while (p) {
if (p === node) {
return true;
}
p = p.parentNode;
}
return false;
},
sort: function(sortFn, recursive, suppressEvent) {
var me = this,
childNodes = me.childNodes,
ln = childNodes.length,
i, n,
info = {
isFirst: true
};
if (ln > 0) {
if (!sortFn) {
sortFn = me.getTreeStore().getSortFn();
}
Ext.Array.sort(childNodes, sortFn);
me.setFirstChild(childNodes[0]);
me.setLastChild(childNodes[ln - 1]);
for (i = 0; i < ln; i++) {
n = childNodes[i];
n.previousSibling = childNodes[i - 1];
n.nextSibling = childNodes[i + 1];
info.isLast = (i === ln - 1);
info.index = i;
n.updateInfo(false, info);
info.isFirst = false;
if (recursive && !n.isLeaf()) {
n.sort(sortFn, true, true);
}
}
if (suppressEvent !== true) {
me.fireEventArgs('sort', [
me,
childNodes
]);
me.callTreeStore('onNodeSort', [
childNodes
]);
}
}
},
isExpanded: function() {
return this.get('expanded');
},
isLoaded: function() {
return this.get('loaded');
},
isBranchLoaded: function() {
var isBranchLoaded = !this.isLeaf() && this.isLoaded();
if (isBranchLoaded) {
this.cascadeBy(function(node) {
if (!node.isLeaf()) {
isBranchLoaded = isBranchLoaded || node.isBranchLoaded();
}
return isBranchLoaded;
});
}
return isBranchLoaded;
},
isLoading: function() {
return this.get('loading');
},
isRoot: function() {
return !this.parentNode;
},
isVisible: function() {
var parent = this.parentNode;
while (parent) {
if (!parent.isExpanded()) {
return false;
}
parent = parent.parentNode;
}
return true;
},
expand: function(recursive, callback, scope) {
var me = this,
treeStore, resumeAddEvent;
if (!me.isLeaf()) {
if (me.isLoading()) {
me.on('expand', function() {
me.expand(recursive, callback, scope);
}, me, {
single: true
});
} else {
if (!me.isExpanded()) {
if (me.fireEventArgs('beforeexpand', [
me
]) !== false) {
if (recursive) {
if (me.parentNode && me.parentNode.isSynchronousRecursiveExpand) {
me.isSynchronousRecursiveExpand = true;
} else {
treeStore = me.getTreeStore();
if (treeStore.getProxy().isSynchronous || me.isBranchLoaded()) {
me.isSynchronousRecursiveExpand = true;
treeStore.suspendEvent('add');
resumeAddEvent = true;
}
}
}
me.callTreeStore('onBeforeNodeExpand', [
me.onChildNodesAvailable,
me,
[
recursive,
callback,
scope
]
]);
if (resumeAddEvent) {
treeStore.resumeEvent('add');
treeStore.fireEvent('refresh', treeStore);
}
me.isSynchronousRecursiveExpand = false;
}
} else if (recursive) {
me.expandChildren(true, callback, scope);
} else {
Ext.callback(callback, scope || me, [
me.childNodes
]);
}
}
} else {
Ext.callback(callback, scope || me);
}
},
onChildNodesAvailable: function(records, recursive, callback, scope) {
var me = this,
treeStore = me.getTreeStore(),
bulkUpdate = treeStore && treeStore.bulkUpdate,
ancestor, i, collapsedAncestors;
Ext.suspendLayouts();
for (ancestor = me.parentNode; ancestor; ancestor = ancestor.parentNode) {
if (!ancestor.isExpanded()) {
(collapsedAncestors || (collapsedAncestors = [])).unshift(ancestor);
}
}
if (bulkUpdate) {
me.data.expanded = true;
} else {
me.set('expanded', true);
}
if (collapsedAncestors) {
for (i = 1; i < collapsedAncestors.length; i++) {
ancestor = collapsedAncestors[i];
if (bulkUpdate) {
ancestor.data.expanded = true;
} else {
ancestor.set('expanded', true);
}
}
collapsedAncestors[0].expand();
for (i = 1; i < collapsedAncestors.length; i++) {
ancestor = collapsedAncestors[i];
ancestor.fireEventArgs('expand', [
ancestor,
ancestor.childNodes
]);
}
} else {
me.callTreeStore('onNodeExpand', [
records,
false
]);
}
me.fireEventArgs('expand', [
me,
records
]);
if (recursive) {
me.expandChildren(true, callback, scope);
} else {
Ext.callback(callback, scope || me, [
me.childNodes
]);
}
Ext.resumeLayouts(true);
},
expandChildren: function(recursive, callback, scope,
singleExpand) {
var me = this,
origCallback, i, allNodes, expandNodes, ln, node, treeStore;
if (Ext.isBoolean(callback)) {
origCallback = callback;
callback = scope;
scope = singleExpand;
singleExpand = origCallback;
}
if (singleExpand === undefined) {
treeStore = me.getTreeStore();
singleExpand = treeStore && treeStore.singleExpand;
}
allNodes = me.childNodes;
expandNodes = [];
ln = singleExpand ? Math.min(allNodes.length, 1) : allNodes.length;
for (i = 0; i < ln; ++i) {
node = allNodes[i];
if (!node.isLeaf()) {
expandNodes[expandNodes.length] = node;
}
}
ln = expandNodes.length;
for (i = 0; i < ln; ++i) {
expandNodes[i].expand(recursive);
}
if (callback) {
Ext.callback(callback, scope || me, [
me.childNodes
]);
}
},
collapse: function(recursive, callback, scope) {
var me = this,
expanded = me.isExpanded(),
treeStore = me.getTreeStore(),
bulkUpdate = treeStore && treeStore.bulkUpdate,
len = me.childNodes.length,
i, collapseChildren;
if (!me.isLeaf() && ((!expanded && recursive) || me.fireEventArgs('beforecollapse', [
me
]) !== false)) {
Ext.suspendLayouts();
if (me.isExpanded()) {
if (recursive) {
collapseChildren = function() {
for (i = 0; i < len; i++) {
me.childNodes[i].setCollapsed(true);
}
};
if (callback) {
callback = Ext.Function.createSequence(collapseChildren, Ext.Function.bind(callback, scope, [
me.childNodes
]));
} else {
callback = collapseChildren;
}
} else if (callback) {
callback = Ext.Function.bind(callback, scope, [
me.childNodes
]);
}
if (bulkUpdate) {
me.data.expanded = false;
} else {
me.set('expanded', false);
}
me.callTreeStore('onNodeCollapse', [
me.childNodes,
callback,
scope
]);
me.fireEventArgs('collapse', [
me,
me.childNodes
]);
callback = null;
}
else if (recursive) {
for (i = 0; i < len; i++) {
me.childNodes[i].setCollapsed(true);
}
}
Ext.resumeLayouts(true);
}
Ext.callback(callback, scope || me, [
me.childNodes
]);
},
setCollapsed: function(recursive) {
var me = this,
len = me.childNodes.length,
i;
if (!me.isLeaf() && me.fireEventArgs('beforecollapse', [
me
]) !== false) {
me.data.expanded = false;
me.fireEventArgs('collapse', [
me,
me.childNodes
]);
if (recursive) {
for (i = 0; i < len; i++) {
me.childNodes[i].setCollapsed(true);
}
}
}
},
collapseChildren: function(recursive, callback, scope) {
var me = this,
i,
allNodes = me.childNodes,
ln = allNodes.length,
collapseNodes = [],
node;
for (i = 0; i < ln; ++i) {
node = allNodes[i];
if (!node.isLeaf() && node.isLoaded() && node.isExpanded()) {
collapseNodes.push(node);
}
}
ln = collapseNodes.length;
if (ln) {
for (i = 0; i < ln; ++i) {
node = collapseNodes[i];
if (i === ln - 1) {
node.collapse(recursive, callback, scope);
} else {
node.collapse(recursive);
}
}
} else {
Ext.callback(callback, scope);
}
},
fireEvent: function(eventName) {
return this.fireEventArgs(eventName, Ext.Array.slice(arguments, 1));
},
fireEventArgs: function(eventName, args) {
var fireEventArgs = Ext.mixin.Observable.prototype.fireEventArgs,
result, eventSource, topNode;
if (bubbledEvents[eventName]) {
for (eventSource = this; result !== false && eventSource; eventSource = (topNode = eventSource).parentNode) {
if (eventSource.hasListeners && eventSource.hasListeners[eventName]) {
result = fireEventArgs.call(eventSource, eventName, args);
}
}
if (result !== false) {
eventSource = topNode.getTreeStore();
if (eventSource && eventSource.hasListeners && eventSource.hasListeners[eventName = 'node' + eventName]) {
result = eventSource.fireEventArgs(eventName, args);
}
}
return result;
} else
{
return fireEventArgs.apply(this, arguments);
}
},
serialize: function(writerParam) {
var writer = writerParam || new Ext.data.writer.Json({
writeAllFields: true
}),
result = writer.getRecordData(this),
childNodes = this.childNodes,
len = childNodes.length,
children, i;
if (len > 0) {
result.children = children = [];
for (i = 0; i < len; i++) {
children.push(childNodes[i].serialize(writer));
}
}
return result;
},
callTreeStore: function(funcName, args) {
var me = this,
target = me.getTreeStore(),
fn = target && target[funcName];
if (target && fn) {
args = args || [];
if (args[0] !== me) {
args.unshift(me);
}
fn.apply(target, args);
}
},
privates: {
join: function(store) {
if (store.isTreeStore) {
if (this.isRoot()) {
this.treeStore = this.store = store;
}
} else
{
this.callParent([
store
]);
}
},
callJoined: function(funcName, args) {
this.callParent([
funcName,
args
]);
this.callTreeStore(funcName, args);
}
}
};
}
}
});
Ext.define('Ext.data.NodeStore', {
extend: 'Ext.data.Store',
alias: 'store.node',
requires: [
'Ext.data.NodeInterface'
],
isNodeStore: true,
config: {
node: null,
recursive: false,
rootVisible: false,
folderSort: false
},
isExpandingOrCollapsing: 0,
getTotalCount: function() {
return this.getCount();
},
afterEdit: function(record, modifiedFields) {
if (this.getNode() && modifiedFields) {
if (Ext.Array.indexOf(modifiedFields, 'loaded') !== -1) {
return this.add(this.retrieveChildNodes(record));
}
if (Ext.Array.indexOf(modifiedFields, 'expanded') !== -1) {
return this.filter();
}
if (Ext.Array.indexOf(modifiedFields, 'sorted') !== -1) {
return this.sort();
}
}
this.callParent(arguments);
},
afterReject: function(record) {
var me = this;
if (me.contains(record)) {
me.onUpdate(record, Ext.data.Model.REJECT, null);
me.fireEvent('update', me, record, Ext.data.Model.REJECT, null);
}
},
afterCommit: function(record, modifiedFieldNames) {
var me = this;
if (!modifiedFieldNames) {
modifiedFieldNames = null;
}
if (me.contains(record)) {
me.onUpdate(record, Ext.data.Model.COMMIT, modifiedFieldNames);
me.fireEvent('update', me, record, Ext.data.Model.COMMIT, modifiedFieldNames);
}
},
onNodeAppend: function(parent, node) {
this.add([
node
].concat(this.retrieveChildNodes(node)));
},
onNodeInsert: function(parent, node) {
this.add([
node
].concat(this.retrieveChildNodes(node)));
},
onNodeRemove: function(parent, node) {
this.remove([
node
].concat(this.retrieveChildNodes(node)));
},
onNodeExpand: function(parent, records) {
this.loadRecords(records);
},
applyNode: function(node) {
if (node) {
Ext.data.NodeInterface.decorate(node);
}
return node;
},
updateNode: function(node, oldNode) {
var me = this,
data;
if (oldNode && !oldNode.isDestroyed) {
oldNode.un({
append: 'onNodeAppend',
insert: 'onNodeInsert',
remove: 'onNodeRemove',
load: 'onNodeLoad',
scope: me
});
oldNode.unjoin(me);
}
if (node) {
node.on({
scope: me,
append: 'onNodeAppend',
insert: 'onNodeInsert',
remove: 'onNodeRemove',
load: 'onNodeLoad'
});
node.join(me);
data = [];
if (node.childNodes.length) {
data = data.concat(me.retrieveChildNodes(node));
}
if (me.getRootVisible()) {
data.push(node);
} else if (node.isLoaded() || node.isLoading()) {
node.set('expanded', true);
}
me.getData().clear();
me.fireEvent('clear', me);
me.suspendEvents();
me.add(data);
me.resumeEvents();
if (data.length === 0) {
me.loaded = node.loaded = true;
}
me.fireEvent('refresh', me, me.data);
}
},
retrieveChildNodes: function(root) {
var node = this.getNode(),
recursive = this.getRecursive(),
added = [],
child = root;
if (!root.childNodes.length || (!recursive && root !== node)) {
return added;
}
if (!recursive) {
return root.childNodes;
}
while (child) {
if (child._added) {
delete child._added;
if (child === root) {
break;
} else {
child = child.nextSibling || child.parentNode;
}
} else {
if (child !== root) {
added.push(child);
}
if (child.firstChild) {
child._added = true;
child = child.firstChild;
} else {
child = child.nextSibling || child.parentNode;
}
}
}
return added;
},
isVisible: function(node) {
var parent = node.parentNode;
if (!this.getRecursive() && parent !== this.getNode()) {
return false;
}
while (parent) {
if (!parent.isExpanded()) {
return false;
}
if (parent === this.getNode()) {
break;
}
parent = parent.parentNode;
}
return true;
}
});
Ext.define('Ext.data.Request', {
config: {
action: undefined,
params: undefined,
method: 'GET',
url: null,
operation: null,
proxy: null,
disableCaching: false,
headers: {},
callbackKey: null,
rawRequest: null,
jsonData: undefined,
xmlData: undefined,
withCredentials: false,
username: null,
password: null,
binary: false,
callback: null,
scope: null,
timeout: 30000,
records: null,
directFn: null,
args: null,
useDefaultXhrHeader: null
},
constructor: function(config) {
this.initConfig(config);
},
getParam: function(key) {
var params = this.getParams(),
val;
if (params) {
return params[key];
}
return val;
},
setParam: function(key, value) {
var params = this.getParams() || {};
params[key] = value;
this.setParams(params);
}
});
Ext.define('Ext.mixin.Queryable', {
mixinId: 'queryable',
isQueryable: true,
query: function(selector) {
selector = selector || '*';
return Ext.ComponentQuery.query(selector, this.getQueryRoot());
},
queryBy: function(fn, scope) {
var out = [],
items = this.getQueryRoot().getRefItems(true),
i = 0,
len = items.length,
item;
for (; i < len; ++i) {
item = items[i];
if (fn.call(scope || item, item) !== false) {
out.push(item);
}
}
return out;
},
queryById: function(id) {
return this.down(Ext.makeIdSelector(id));
},
child: function(selector) {
var children = this.getQueryRoot().getRefItems();
if (selector && selector.isComponent) {
return this.matchById(children, selector.getItemId());
}
if (selector) {
children = Ext.ComponentQuery.query(selector, children);
}
if (children.length) {
return children[0];
}
return null;
},
down: function(selector) {
if (selector && selector.isComponent) {
return this.matchById(this.getRefItems(true), selector.getItemId());
}
selector = selector || '';
return this.query(selector)[0] || null;
},
visitPreOrder: function(selector, fn, scope, extraArgs) {
Ext.ComponentQuery._visit(true, selector, this.getQueryRoot(), fn, scope, extraArgs);
},
visitPostOrder: function(selector, fn, scope, extraArgs) {
Ext.ComponentQuery._visit(false, selector, this.getQueryRoot(), fn, scope, extraArgs);
},
getRefItems: function() {
return [];
},
getQueryRoot: function() {
return this;
},
privates: {
matchById: function(items, id) {
var len = items.length,
i, item;
for (i = 0; i < len; ++i) {
item = items[i];
if (item.getItemId() === id) {
return item;
}
}
return null;
}
}
});
Ext.define('Ext.data.TreeModel', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.NodeInterface'
],
mixins: [
'Ext.mixin.Queryable'
],
getRefItems: function() {
return this.childNodes;
},
getRefOwner: function() {
return this.parentNode;
}
}, function() {
Ext.data.NodeInterface.decorate(this);
});
Ext.define('Ext.data.TreeStore', {
extend: 'Ext.data.NodeStore',
alias: 'store.tree',
requires: [
'Ext.util.Sorter',
'Ext.data.TreeModel',
'Ext.data.NodeInterface'
],
isTreeStore: true,
config: {
root: null,
rootVisible: false,
recursive: true,
defaultRootProperty: 'children',
parentIdProperty: null,
clearOnLoad: true,
clearRemovedOnLoad: true,
nodeParam: 'node',
defaultRootId: 'root',
defaultRootText: 'Root',
folderSort: false
},
lazyFill: false,
fillCount: 0,
bulkUpdate: 0,
_silentOptions: {
silent: true
},
constructor: function(config) {
var me = this;
me.byIdMap = {};
me.callParent([
config
]);
if (Ext.isDefined(me.nodeParameter)) {
if (Ext.isDefined(Ext.global.console)) {
Ext.global.console.warn('Ext.data.TreeStore: nodeParameter has been deprecated. Please use nodeParam instead.');
}
me.nodeParam = me.nodeParameter;
delete me.nodeParameter;
}
},
applyFields: function(fields) {
var me = this;
if (fields) {
if (me.defaultRootProperty !== me.self.prototype.config.defaultRootProperty) {
fields = fields.concat({
name: me.defaultRootProperty,
type: 'auto',
defaultValue: null,
persist: false
});
}
me.setModel(Ext.define(null, {
extend: 'Ext.data.TreeModel',
fields: fields,
proxy: me.getProxy()
}));
me.implicitModel = true;
}
},
onSorterEndUpdate: function() {
var me = this,
sorterCollection = me.getSorters(),
sorters = sorterCollection.getRange(),
rootNode = me.getRoot(),
folderSort = me.getFolderSort();
if (rootNode && (folderSort || sorters.length)) {
if (me.getRemoteSort()) {
if (sorters.length) {
me.attemptLoad({
callback: function() {
me.fireEvent('sort', me, sorters);
}
});
}
} else {
rootNode.sort(this.getSortFn(), true);
me.fireEvent('datachanged', me);
me.fireEvent('refresh', me);
me.fireEvent('sort', me, sorters);
}
} else
{
me.fireEvent('sort', me, sorters);
}
},
updateFolderSort: function(folderSort) {
this.needsFolderSort = folderSort;
this.onSorterEndUpdate();
},
getSortFn: function() {
return this._sortFn || (this._sortFn = this.createSortFn());
},
createSortFn: function() {
var me = this,
sortersSortFn = this.sorters.getSortFn();
return function(node1, node2) {
var node1FolderOrder, node2FolderOrder,
result = 0;
if (me.needsFolderSort) {
node1FolderOrder = node1.data.leaf ? 1 : 0;
node2FolderOrder = node2.data.leaf ? 1 : 0;
result = node1FolderOrder - node2FolderOrder;
}
if (me.needsIndexSort && result === 0) {
result = node1.data.index - node2.data.index;
}
return result || sortersSortFn(node1, node2);
};
},
afterEdit: function(node, modifiedFieldNames) {
var me = this;
if (me.needsLocalFilter()) {
me.doFilter(node);
}
me.callParent([
node,
modifiedFieldNames
]);
},
fireChangeEvent: function(record) {
return !!this.byIdMap[record.id];
},
updateRootVisible: function(rootVisible) {
var rootNode = this.getRoot(),
data;
if (rootNode) {
data = this.getData();
if (rootVisible) {
data.insert(0, rootNode);
} else {
data.remove(rootNode);
}
}
},
updateTrackRemoved: function(trackRemoved) {
this.callParent(arguments);
this.removedNodes = this.removed;
this.removed = null;
},
getRemovedRecords: function() {
return this.removedNodes;
},
onDestroyRecords: function(records, operation, success) {
if (success) {
this.removedNodes.length = 0;
}
},
updateProxy: function(proxy) {
var reader;
if (proxy) {
if (proxy.setIdParam) {
proxy.setIdParam(this.getNodeParam());
}
reader = proxy.getReader();
if (Ext.isEmpty(reader.getRootProperty())) {
reader.setRootProperty(this.getDefaultRootProperty());
}
}
},
setProxy: function(proxy) {
this.changingProxy = true;
this.callParent([
proxy
]);
this.changingProxy = false;
},
applyModel: function(model) {
return this.callParent(arguments) || Ext.data.TreeModel;
},
updateModel: function(model) {
var isNode = model.prototype.isNode;
Ext.data.NodeInterface.decorate(model);
if (!isNode && !this.changingProxy) {
this.getProxy().getReader().buildExtractors(true);
}
},
onFilterEndUpdate: function(filters) {
var me = this,
length = filters.length,
root = me.getRoot(),
childNodes, childNode, filteredNodes, i;
if (!me.getRemoteFilter()) {
if (length) {
me.doFilter(root);
} else {
root.cascadeBy({
after: function(node) {
node.set('visible', true, me._silentOptions);
}
});
}
if (length) {
filteredNodes = [];
childNodes = root.childNodes;
for (i = 0 , length = childNodes.length; i < length; i++) {
childNode = childNodes[i];
if (childNode.get('visible')) {
filteredNodes.push(childNode);
}
}
} else {
filteredNodes = root.childNodes;
}
me.onNodeFilter(root, filteredNodes);
root.fireEvent('filterchange', root, filteredNodes);
me.fireEvent('filterchange', me, filters);
me.suppressNextFilter = true;
me.callParent([
filters
]);
me.suppressNextFilter = false;
} else {
me.callParent([
filters
]);
}
},
onNodeFilter: function(root, childNodes) {
var me = this,
data = me.getData(),
toAdd = [];
if (me.getRootVisible()) {
if (childNodes.length) {
toAdd.push(root);
} else {
root.set('visible', false, me._silentOptions);
}
}
me.handleNodeExpand(root, childNodes, toAdd);
me.suspendEvents();
data.splice(0, data.getCount(), toAdd);
me.resumeEvents();
if (!me.suppressNextFilter) {
me.fireEvent('datachanged', me);
me.fireEvent('refresh', me);
}
},
onBeforeNodeExpand: function(node, callback, scope, args) {
var me = this,
storeReader, nodeProxy, nodeReader, reader, children, callbackArgs;
if (node.isLoaded()) {
callbackArgs = [
node.childNodes
];
if (args) {
callbackArgs.push.apply(callbackArgs, args);
}
Ext.callback(callback, scope || node, callbackArgs);
}
else if (node.isLoading()) {
me.on('load', function() {
callbackArgs = [
node.childNodes
];
if (args) {
callbackArgs.push.apply(callbackArgs, args);
}
Ext.callback(callback, scope || node, callbackArgs);
}, me, {
single: true,
priority: 1001
});
} else
{
storeReader = me.getProxy().getReader();
nodeProxy = node.getProxy();
nodeReader = nodeProxy ? nodeProxy.getReader() : null;
reader = nodeReader && nodeReader.initialConfig.rootProperty ? nodeReader : storeReader;
children = reader.getRoot(node.raw || node.data);
if (children || (node.phantom && !node.isRoot())) {
if (children) {
me.fillNode(node, reader.extractData(children, {
model: node.childType,
recordCreator: me.recordCreator
}));
}
callbackArgs = [
node.childNodes
];
if (args) {
callbackArgs.push.apply(callbackArgs, args);
}
Ext.callback(callback, scope || node, callbackArgs);
} else
{
if (node.isRoot()) {
me.clearLoadTask();
}
me.read({
node: node,
onChildNodesAvailable: function() {
delete me.lastOptions.onChildNodesAvailable;
callbackArgs = [
node.childNodes
];
if (args) {
callbackArgs.push.apply(callbackArgs, args);
}
Ext.callback(callback, scope || node, callbackArgs);
}
});
}
}
},
onNodeExpand: function(parent, records) {
var me = this,
insertIndex = me.indexOf(parent) + 1,
toAdd = [];
me.handleNodeExpand(parent, records, toAdd);
if (!me.refreshCounter && parent.isRoot() && !parent.get('visible')) {
me.loadRecords(toAdd);
} else
{
me.insert(insertIndex, toAdd);
}
},
handleNodeExpand: function(parent, records, toAdd) {
var me = this,
ln = records ? records.length : 0,
i, record;
if (parent !== this.getRoot() && !me.isVisible(parent)) {
return;
}
if (ln) {
for (i = 0; i < ln; i++) {
record = records[i];
if (record.get('visible')) {
toAdd.push(record);
if (record.isExpanded()) {
if (record.isLoaded()) {
me.handleNodeExpand(record, record.childNodes, toAdd);
} else {
record.set('expanded', false);
record.expand();
}
}
}
}
}
},
onNodeCollapse: function(parent, records, callback, scope) {
var me = this,
collapseIndex = me.indexOf(parent) + 1,
lastNodeIndexPlus;
if (!me.recursive && parent !== me.getRoot()) {
return;
}
if (me.needsLocalFilter()) {
records = Ext.Array.filter(records, me.filterVisible);
}
if (records.length && me.data.contains(records[0])) {
lastNodeIndexPlus = me.indexOfNextVisibleNode(parent);
me.removeAt(collapseIndex, lastNodeIndexPlus - collapseIndex);
}
Ext.callback(callback, scope);
},
indexOfNextVisibleNode: function(node) {
var result;
while (node.parentNode) {
for (result = node.nextSibling; result && !result.get('visible'); result = result.nextSibling) {}
if (result) {
return this.indexOf(result);
}
node = node.parentNode;
}
return this.getCount();
},
filterNew: function(item) {
return !item.get('root') && this.callParent([
item
]);
},
filterRejects: function(item) {
return !item.get('root') && this.callParent([
item
]);
},
getNewRecords: function() {
return Ext.Array.filter(Ext.Object.getValues(this.byIdMap), this.filterNew, this);
},
getUpdatedRecords: function() {
return Ext.Array.filter(Ext.Object.getValues(this.byIdMap), this.filterUpdated);
},
beforeNodeRemove: function(parentNode, childNodes) {
if (!Ext.isArray(childNodes)) {
childNodes = [
childNodes
];
}
var me = this,
len = childNodes.length,
i, startNode;
for (i = 0; !startNode && i < len; i++) {
if (childNodes[i].get('visible')) {
startNode = childNodes[i];
}
}
if (startNode) {
me.startRemoveIndex = me.indexOf(childNodes[0]);
me.lastRemoveIndexPlusOne = me.indexOfNextVisibleNode(childNodes[childNodes.length - 1]);
} else {
me.startRemoveIndex = -1;
me.lastRemoveIndexPlusOne = 0;
}
},
afterDrop: Ext.emptyFn,
onNodeRemove: function(parentNode, childNodes, isMove) {
var me = this,
removed = me.removedNodes,
len = childNodes.length,
startRemoveIndex = me.startRemoveIndex,
lastRemoveIndexPlusOne = me.lastRemoveIndexPlusOne,
i;
me.suspendAutoSync();
if (startRemoveIndex !== -1) {
me.removeIsMove = isMove;
me.removeAt(startRemoveIndex, lastRemoveIndexPlusOne - startRemoveIndex);
me.removeIsMove = false;
}
for (i = 0; i < len; i++) {
childNodes[i].cascadeBy(function(node) {
me.unregisterNode(node);
if (removed && !isMove) {
if (!node.phantom && !node.erasing && !me.loading) {
node.removedFrom = me.indexOf(node);
removed.push(node);
me.needsSync = true;
}
}
});
}
me.resumeAutoSync();
},
onNodeAppend: function(parent, node, index) {
this.onNodeInsert(parent, node, index);
},
onNodeInsert: function(parent, node, index) {
var me = this,
data = node.raw || node.data,
refNode, sibling, storeReader, nodeProxy, nodeReader, reader, dataRoot;
if (parent && me.needsLocalFilter()) {
me.doFilter(parent);
}
me.beginUpdate();
if (me.isVisible(node)) {
if (index === 0 || !node.previousSibling) {
refNode = parent;
} else {
for (sibling = node.previousSibling; sibling && !sibling.get('visible'); sibling = sibling.previousSibling) {}
while (sibling.isExpanded() && sibling.lastChild) {
sibling = sibling.lastChild;
}
refNode = sibling;
}
me.insert(me.indexOf(refNode) + 1, node);
if (!node.isLeaf() && node.isExpanded()) {
if (node.isLoaded()) {
me.onNodeExpand(node, node.childNodes);
} else if (!me.fillCount) {
node.set('expanded', false);
node.expand();
}
}
}
me.needsSync = me.needsSync || node.phantom || node.dirty;
if (!node.isLeaf() && !node.isLoaded() && !me.lazyFill) {
storeReader = me.getProxy().getReader();
nodeProxy = node.getProxy();
nodeReader = nodeProxy ? nodeProxy.getReader() : null;
reader = nodeReader && nodeReader.initialConfig.rootProperty ? nodeReader : storeReader;
dataRoot = reader.getRoot(data);
if (dataRoot) {
me.fillNode(node, reader.extractData(dataRoot, {
model: node.childType,
recordCreator: me.recordCreator
}));
}
}
me.endUpdate();
},
registerNode: function(node, includeChildren) {
var me = this,
children, length, i;
me.byIdMap[node.id] = node;
if (includeChildren === true) {
children = node.childNodes;
length = children.length;
for (i = 0; i < length; i++) {
me.registerNode(children[i], true);
}
}
},
unregisterNode: function(node, includeChildren) {
var me = this,
children, length, i;
delete me.byIdMap[node.id];
if (includeChildren === true) {
children = node.childNodes;
length = children.length;
for (i = 0; i < length; i++) {
me.unregisterNode(children[i], true);
}
}
},
onNodeSort: function(node, childNodes) {
var me = this;
me.suspendAutoSync();
if ((me.indexOf(node) !== -1 || (node === me.getRoot() && !me.getRootVisible()) && node.isExpanded())) {
Ext.suspendLayouts();
me.onNodeCollapse(node, childNodes);
me.onNodeExpand(node, childNodes);
Ext.resumeLayouts(true);
}
me.resumeAutoSync(me.autoSync);
},
applyRoot: function(newRoot) {
var me = this,
Model = me.getModel(),
idProperty = Model.prototype.idProperty,
defaultRootId = me.getDefaultRootId();
if (newRoot && !newRoot.isNode) {
newRoot = Ext.apply({
text: me.getDefaultRootText(),
root: true,
isFirst: true,
isLast: true,
depth: 0,
index: 0,
parentId: null,
allowDrag: false
}, newRoot);
if (defaultRootId && newRoot[idProperty] === undefined) {
newRoot[idProperty] = defaultRootId;
}
newRoot = new Model(newRoot);
newRoot.store = newRoot.treeStore = me;
}
return newRoot;
},
updateRoot: function(newRoot, oldRoot) {
var me = this,
oldOwner,
initial = !oldRoot,
toRemove;
me.byIdMap = {};
me.getTrackRemoved();
me.suspendEvent('add', 'remove');
if (oldRoot && oldRoot.isModel) {
if (me.rootVisible) {
toRemove = [
oldRoot
];
} else {
toRemove = oldRoot.childNodes;
}
me.beforeNodeRemove(null, toRemove);
oldRoot.set('root', false);
me.onNodeRemove(null, toRemove);
oldRoot.fireEvent('remove', null, oldRoot, false);
oldRoot.fireEvent('rootchange', null);
oldRoot.clearListeners();
oldRoot.store = oldRoot.treeStore = null;
}
me.getData().clear();
if (newRoot) {
if (newRoot.fireEventArgs('beforeappend', [
null,
newRoot
]) === false) {
newRoot = null;
} else {
oldOwner = newRoot.parentNode;
if (oldOwner) {
if (!oldOwner.removeChild(newRoot, false, false, oldOwner.getTreeStore() === me)) {
return;
}
}
else if ((oldOwner = newRoot.getTreeStore()) && oldOwner !== me && newRoot === oldOwner.getRoot()) {
oldOwner.setRoot(null);
}
newRoot.set('root', true);
newRoot.updateInfo(true, {
isFirst: true,
isLast: true,
depth: 0,
index: 0,
parentId: null
});
me.registerNode(newRoot, true);
newRoot.fireEvent('append', null, newRoot, false);
newRoot.fireEvent('rootchange', newRoot);
me.onNodeAppend(null, newRoot, 0);
newRoot.phantom = true;
}
}
me.fireEvent('rootchange', newRoot, oldRoot);
if (newRoot && (me.getAutoLoad() || newRoot.isExpanded())) {
if (newRoot.isLoaded()) {
me.onNodeExpand(newRoot, newRoot.childNodes);
me.fireEvent('datachanged', me);
me.fireEvent('refresh', me);
} else
{
newRoot.data.expanded = false;
newRoot.expand(false, function() {
me.fireEvent('datachanged', me);
me.fireEvent('refresh', me);
});
}
} else if (!initial) {
me.fireEvent('datachanged', me);
me.fireEvent('refresh', me);
}
me.resumeEvent('add', 'remove');
return newRoot;
},
getNodeById: function(id) {
return this.byIdMap[id] || null;
},
findNode: function(property, value, startsWith, endsWith, ignoreCase) {
if (Ext.isEmpty(value, false)) {
return null;
}
if (value === this.model.idProperty && arguments.length < 3) {
return this.byIdMap[value];
}
var regex = Ext.String.createRegex(value, startsWith, endsWith, ignoreCase),
result = null;
Ext.Object.eachValue(this.byIdMap, function(node) {
if (node && regex.test(node.get(property))) {
result = node;
return false;
}
});
return result;
},
load: function(options) {
options = options || {};
options.params = options.params || {};
var me = this,
node = options.node || me.getRoot(),
callback = options.callback,
scope = options.scope,
clearOnLoad = me.getClearOnLoad(),
isReload = node && node.isRoot() && node.isLoaded() && clearOnLoad,
operation, doClear;
if (!node) {
me.setRoot({
expanded: true
});
return;
}
if (node.data.expanded && !isReload) {
node.data.loaded = false;
if (clearOnLoad) {
node.data.expanded = false;
}
options.callback = function(loadedNodes, operation, success) {
if (!clearOnLoad) {
node.collapse();
}
node.expand();
Ext.callback(callback, scope, [
loadedNodes,
operation,
success
]);
};
}
options.id = node.getId();
options = Ext.apply({
filters: me.getFilters().items,
sorters: me.getSorters().items,
node: options.node || node,
internalScope: me,
internalCallback: me.onProxyLoad
}, options);
me.lastOptions = Ext.apply({}, options);
options.isReload = isReload;
operation = me.createOperation('read', options);
if (me.fireEvent('beforeload', me, operation) !== false) {
me.loading = true;
me.clearLoadTask();
if (isReload) {
if (me.getClearRemovedOnLoad()) {
me.removedNodes.length = 0;
}
me.unregisterNode(node, true);
node.childNodes.length = 0;
doClear = true;
}
else if (clearOnLoad) {
if (me.getTrackRemoved() && me.getClearRemovedOnLoad()) {
me.clearRemoved(node);
}
node.removeAll(false);
}
if (me.loading && node) {
node.set('loading', true);
}
if (doClear) {
me.clearData(true);
if (me.getRootVisible()) {
me.suspendEvents();
me.add(node);
me.resumeEvents();
}
}
operation.execute();
}
return me;
},
onProxyLoad: function(operation) {
var me = this,
options = operation.initialConfig,
successful = operation.wasSuccessful(),
records = operation.getRecords(),
node = options.node,
isReload = options.isReload,
scope = operation.getScope() || me,
args = [
records,
operation,
successful
];
if (me.isDestroyed) {
return;
}
me.loading = false;
node.set('loading', false);
if (successful) {
++me.loadCount;
if (!me.getClearOnLoad()) {
records = me.cleanRecords(node, records);
}
if (me.getParentIdProperty()) {
records = me.treeify(node, records);
}
if (isReload) {
me.suspendEvent('add', 'update');
}
records = me.fillNode(node, records);
}
if (isReload) {
me.resumeEvent('add', 'update');
me.callObservers('BeforePopulate');
me.fireEvent('datachanged', me);
me.fireEvent('refresh', me);
me.callObservers('AfterPopulate');
} else {
Ext.callback(options.onChildNodesAvailable, scope, args);
}
me.fireEvent('load', me, records, successful, operation, node);
},
clearRemoved: function(node) {
var me = this,
removed = me.removedNodes,
id = node.getId(),
removedLength = removed.length,
i = removedLength,
recordsToClear = {},
newRemoved = [],
removedHash = {},
removedNode, targetNode, targetId;
if (node === me.getRoot()) {
me.removedNodes.length = 0;
return;
}
for (; i--; ) {
removedNode = removed[i];
removedHash[removedNode.getId()] = removedNode;
}
for (i = removedLength; i--; ) {
removedNode = removed[i];
targetNode = removedNode;
while (targetNode && targetNode.getId() !== id) {
targetId = targetNode.get('parentId') || targetNode.get('lastParentId');
targetNode = targetNode.parentNode || me.getNodeById(targetId) || removedHash[targetId];
}
if (targetNode) {
recordsToClear[removedNode.getId()] = removedNode;
}
}
for (i = 0; i < removedLength; i++) {
removedNode = removed[i];
if (!recordsToClear[removedNode.getId()]) {
newRemoved.push(removedNode);
}
}
me.removedNodes = newRemoved;
},
fillNode: function(node, newNodes) {
var me = this,
newNodeCount = newNodes ? newNodes.length : 0,
sorters = me.getSorters(),
needsIndexSort = false,
performLocalSort = me.sortOnLoad && newNodeCount > 1 && !me.getRemoteSort() && me.getFolderSort() || sorters.length,
node1, node2, i, filterFn;
++me.bulkUpdate;
if (newNodeCount) {
if (me.needsLocalFilter()) {
filterFn = me.getFilters().getFilterFn();
newNodes[0].set('visible', filterFn(newNodes[0]));
}
for (i = 1; i < newNodeCount; i++) {
node1 = newNodes[i];
node2 = newNodes[i - 1];
if (filterFn) {
node1.set('visible', filterFn(node1));
}
needsIndexSort = node1.data.index !== node2.data.index;
}
if (performLocalSort) {
me.needsIndexSort = true;
Ext.Array.sort(newNodes, me.getSortFn());
me.needsIndexSort = false;
} else if (needsIndexSort) {
Ext.Array.sort(newNodes, me.sortByIndex);
}
}
if (me.bulkUpdate === 1) {
node.set('loaded', true);
} else {
node.data.loaded = true;
}
if (newNodes.length) {
node.appendChild(newNodes, undefined, true);
}
--me.bulkUpdate;
return newNodes;
},
beginFill: function() {
var me = this;
if (!me.fillCount++) {
me.beginUpdate();
me.suspendEvent('add', 'update');
me.suspendAutoSync();
me.fillArray = [];
}
},
endFill: function(parent, nodes) {
var me = this,
fillArray = me.fillArray,
i, len, index;
fillArray.push(nodes);
if (!--me.fillCount) {
me.resumeAutoSync();
me.resumeEvent('add', 'update');
for (i = 0 , len = fillArray.length; i < len; i++) {
index = me.indexOf(fillArray[i][0]);
if (index !== -1) {
me.fireEvent('add', me, fillArray[i], index);
}
}
me.fillArray = null;
me.endUpdate();
}
},
sortByIndex: function(node1, node2) {
return node1.data.index - node2.data.index;
},
onIdChanged: function(node, oldId, newId) {
var childNodes = node.childNodes,
len = childNodes && childNodes.length,
i;
this.callParent(arguments);
delete this.byIdMap[oldId];
this.byIdMap[newId] = node;
for (i = 0; i < len; i++) {
childNodes[i].set('parentId', newId);
}
},
treeify: function(parentNode, records) {
var me = this,
loadParentNodeId = parentNode.getId(),
parentIdProperty = me.getParentIdProperty(),
len = records.length,
result = [],
nodeMap = {},
i, node, parentId;
for (i = 0; i < len; i++) {
node = records[i];
nodeMap[node.id] = node;
}
for (i = 0; i < len; i++) {
node = records[i];
parentId = node.data[parentIdProperty];
if (!(parentId || parentId === 0) || parentId === loadParentNodeId) {
result.push(node);
} else {
if (!nodeMap[parentId]) {
Ext.raise('Ext.data.TreeStore, Invalid parentId "' + parentId + '"');
}
nodeMap[parentId].appendChild(node);
}
me.registerNode(node);
}
return result;
},
cleanRecords: function(node, records) {
var nodeHash = {},
childNodes = node.childNodes,
i = 0,
len = childNodes.length,
out = [],
rec;
for (; i < len; ++i) {
nodeHash[childNodes[i].getId()] = true;
}
for (i = 0 , len = records.length; i < len; ++i) {
rec = records[i];
if (!nodeHash[rec.getId()]) {
out.push(rec);
}
}
return out;
},
removeAll: function() {
this.suspendEvents();
this.setRoot(null);
this.resumeEvents();
this.callParent();
},
doSort: function(sorterFn) {
var me = this;
if (me.getRemoteSort()) {
me.load();
} else {
me.tree.sort(sorterFn, true);
me.fireEvent('datachanged', me);
me.fireEvent('refresh', me);
}
me.fireEvent('sort', me, me.sorters.getRange());
},
filterVisible: function(node) {
return node.get('visible');
},
isVisible: function(node) {
var parentNode = node.parentNode,
visible = node.data.visible,
root = this.getRoot();
while (visible && parentNode) {
visible = parentNode.data.expanded && parentNode.data.visible;
parentNode = parentNode.parentNode;
}
return visible && !(node === root && !this.getRootVisible());
},
commitChanges: function() {
var removed = this.removedNodes;
if (removed) {
removed.length = 0;
}
this.callParent();
},
getRootNode: function() {
return this.getRoot();
},
setRootNode: function(root) {
this.setRoot(root);
return this.getRoot();
},
privates: {
recordCreator: function(data, Model) {
return new Model(data);
},
doFilter: function(node) {
var root = this.getRoot(),
filterFn = this.getFilters().getFilterFn();
this.filterNodes(root, node, filterFn);
},
filterNodes: function(root, node, filterFn) {
var match = false,
childNodes = node.childNodes,
len = childNodes && childNodes.length,
i;
if (len) {
for (i = 0; i < len; ++i) {
this.filterNodes(root, childNodes[i], filterFn);
}
}
match = node === root || filterFn(node);
node.set('visible', match, this._silentOptions);
return match;
},
needsLocalFilter: function() {
return !this.getRemoteFilter() && this.getFilters().length;
},
onRemoteFilterSet: function(filters, remoteFilter) {
var data = this.getData();
data.setFilters(null);
if (filters) {
filters.on('endupdate', this.onFilterEndUpdate, this);
}
},
onRemoteSortSet: function(sorters, remoteSort) {
var data = this.getData();
data.setSorters(null);
if (sorters) {
sorters.on('endupdate', this.onSorterEndUpdate, this);
}
}
},
deprecated: {
5: {
properties: {
tree: null
}
}
}
});
Ext.define('Ext.data.Types', {
singleton: true,
requires: [
'Ext.data.SortTypes'
]
}, function(Types) {
var SortTypes = Ext.data.SortTypes;
Ext.apply(Types, {
stripRe: /[\$,%]/g,
AUTO: {
sortType: SortTypes.none,
type: 'auto'
},
STRING: {
convert: function(v) {
var defaultValue = this.getAllowNull() ? null : '';
return (v === undefined || v === null) ? defaultValue : String(v);
},
sortType: SortTypes.asUCString,
type: 'string'
},
INT: {
convert: function(v) {
if (typeof v === 'number') {
return parseInt(v, 10);
}
return v !== undefined && v !== null && v !== '' ? parseInt(String(v).replace(Types.stripRe, ''), 10) : (this.getAllowNull() ? null : 0);
},
sortType: SortTypes.none,
type: 'int'
},
FLOAT: {
convert: function(v) {
if (typeof v === 'number') {
return v;
}
return v !== undefined && v !== null && v !== '' ? parseFloat(String(v).replace(Types.stripRe, ''), 10) : (this.getAllowNull() ? null : 0);
},
sortType: SortTypes.none,
type: 'float'
},
BOOL: {
convert: function(v) {
if (typeof v === 'boolean') {
return v;
}
if (this.getAllowNull() && (v === undefined || v === null || v === '')) {
return null;
}
return v === 'true' || v == 1;
},
sortType: SortTypes.none,
type: 'bool'
},
DATE: {
convert: function(v) {
var df = this.getDateReadFormat() || this.getDateFormat(),
parsed;
if (!v) {
return null;
}
if (v instanceof Date) {
return v;
}
if (df) {
return Ext.Date.parse(v, df);
}
parsed = Date.parse(v);
return parsed ? new Date(parsed) : null;
},
sortType: SortTypes.asDate,
type: 'date'
}
});
Types.BOOLEAN = Types.BOOL;
Types.INTEGER = Types.INT;
Types.NUMBER = Types.FLOAT;
});
Ext.define('Ext.data.Validation', {
extend: 'Ext.data.Model',
isValidation: true,
syncGeneration: 0,
attach: function(record) {
this.record = record;
delete this.data.id;
},
getValidation: function() {
return null;
},
isValid: function() {
var me = this;
if (me.syncGeneration !== me.record.generation) {
me.refresh();
}
return !me.dirty;
},
refresh: function(force) {
var me = this,
data = me.data,
record = me.record,
fields = record.fields,
generation = record.generation,
recordData = record.data,
sep = record.validationSeparator,
values = null,
defaultMessage, currentValue, error, field, item, i, j, jLen, len, msg, val, name;
if (force || me.syncGeneration !== generation) {
me.syncGeneration = generation;
for (i = 0 , len = fields.length; i < len; ++i) {
field = fields[i];
name = field.name;
val = recordData[name];
defaultMessage = field.defaultInvalidMessage;
error = 0;
if (!(name in data)) {
data[name] = currentValue = true;
} else
{
currentValue = data[name];
}
if (field.validate !== Ext.emptyFn) {
msg = field.validate(val, sep);
if (msg !== true) {
error = msg || defaultMessage;
}
}
if (!error) {
error = true;
}
if (error !== currentValue) {
(values || (values = {}))[name] = error;
}
}
if (values) {
me.set(values);
}
}
}
});
Ext.define('Ext.dom.Helper', function() {
var afterbegin = 'afterbegin',
afterend = 'afterend',
beforebegin = 'beforebegin',
beforeend = 'beforeend',
bbValues = [
'BeforeBegin',
'previousSibling'
],
aeValues = [
'AfterEnd',
'nextSibling'
],
bb_ae_PositionHash = {
beforebegin: bbValues,
afterend: aeValues
},
fullPositionHash = {
beforebegin: bbValues,
afterend: aeValues,
afterbegin: [
'AfterBegin',
'firstChild'
],
beforeend: [
'BeforeEnd',
'lastChild'
]
};
return {
singleton: true,
alternateClassName: [
'Ext.DomHelper',
'Ext.core.DomHelper'
],
emptyTags: /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i,
confRe: /^(?:tag|children|cn|html|tpl|tplData)$/i,
endRe: /end/i,
attributeTransform: {
cls: 'class',
htmlFor: 'for'
},
closeTags: {},
detachedDiv: document.createElement('div'),
decamelizeName: function() {
var camelCaseRe = /([a-z])([A-Z])/g,
cache = {};
function decamel(match, p1, p2) {
return p1 + '-' + p2.toLowerCase();
}
return function(s) {
return cache[s] || (cache[s] = s.replace(camelCaseRe, decamel));
};
}(),
generateMarkup: function(spec, buffer) {
var me = this,
specType = typeof spec,
attr, val, tag, i, closeTags;
if (specType === "string" || specType === "number") {
buffer.push(spec);
} else if (Ext.isArray(spec)) {
for (i = 0; i < spec.length; i++) {
if (spec[i]) {
me.generateMarkup(spec[i], buffer);
}
}
} else {
tag = spec.tag || 'div';
buffer.push('<', tag);
for (attr in spec) {
if (spec.hasOwnProperty(attr)) {
val = spec[attr];
if (val !== undefined && !me.confRe.test(attr)) {
if (typeof val === "object") {
buffer.push(' ', attr, '="');
me.generateStyles(val, buffer, true).push('"');
} else {
buffer.push(' ', me.attributeTransform[attr] || attr, '="', val, '"');
}
}
}
}
if (me.emptyTags.test(tag)) {
buffer.push('/>');
} else {
buffer.push('>');
if ((val = spec.tpl)) {
val.applyOut(spec.tplData, buffer);
}
if ((val = spec.html)) {
buffer.push(val);
}
if ((val = spec.cn || spec.children)) {
me.generateMarkup(val, buffer);
}
closeTags = me.closeTags;
buffer.push(closeTags[tag] || (closeTags[tag] = '</' + tag + '>'));
}
}
return buffer;
},
generateStyles: function(styles, buffer, encode) {
var a = buffer || [],
name, val;
for (name in styles) {
if (styles.hasOwnProperty(name)) {
val = styles[name];
name = this.decamelizeName(name);
if (encode && Ext.String.hasHtmlCharacters(val)) {
val = Ext.String.htmlEncode(val);
}
a.push(name, ':', val, ';');
}
}
return buffer || a.join('');
},
markup: function(spec) {
if (typeof spec === "string") {
return spec;
}
var buf = this.generateMarkup(spec, []);
return buf.join('');
},
applyStyles: function(el, styles) {
Ext.fly(el).applyStyles(styles);
},
createContextualFragment: function(html) {
var div = this.detachedDiv,
fragment = document.createDocumentFragment(),
length, childNodes;
div.innerHTML = html;
childNodes = div.childNodes;
length = childNodes.length;
while (length--) {
fragment.appendChild(childNodes[0]);
}
return fragment;
},
createDom: function(o, parentNode) {
var me = this,
markup = me.markup(o),
div = me.detachedDiv,
child;
div.innerHTML = markup;
child = div.firstChild;
return Ext.supports.ChildContentClearedWhenSettingInnerHTML ? child.cloneNode(true) : child;
},
insertHtml: function(where, el, html) {
var me = this,
hashVal, range, rangeEl, setStart, frag;
where = where.toLowerCase();
if (el.insertAdjacentHTML) {
if (me.ieInsertHtml) {
frag = me.ieInsertHtml(where, el, html);
if (frag) {
return frag;
}
}
hashVal = fullPositionHash[where];
if (hashVal) {
el.insertAdjacentHTML(hashVal[0], html);
return el[hashVal[1]];
}
} else
{
if (el.nodeType === 3) {
where = where === afterbegin ? beforebegin : where;
where = where === beforeend ? afterend : where;
}
range = Ext.supports.CreateContextualFragment ? el.ownerDocument.createRange() : undefined;
setStart = 'setStart' + (this.endRe.test(where) ? 'After' : 'Before');
if (bb_ae_PositionHash[where]) {
if (range) {
range[setStart](el);
frag = range.createContextualFragment(html);
} else {
frag = this.createContextualFragment(html);
}
el.parentNode.insertBefore(frag, where === beforebegin ? el : el.nextSibling);
return el[(where === beforebegin ? 'previous' : 'next') + 'Sibling'];
} else {
rangeEl = (where === afterbegin ? 'first' : 'last') + 'Child';
if (el.firstChild) {
if (range) {
try {
range[setStart](el[rangeEl]);
frag = range.createContextualFragment(html);
} catch (e) {
frag = this.createContextualFragment(html);
}
} else {
frag = this.createContextualFragment(html);
}
if (where === afterbegin) {
el.insertBefore(frag, el.firstChild);
} else {
el.appendChild(frag);
}
} else {
el.innerHTML = html;
}
return el[rangeEl];
}
}
Ext.Error.raise({
sourceClass: 'Ext.DomHelper',
sourceMethod: 'insertHtml',
htmlToInsert: html,
targetElement: el,
msg: 'Illegal insertion point reached: "' + where + '"'
});
},
insertBefore: function(el, o, returnElement) {
return this.doInsert(el, o, returnElement, beforebegin);
},
insertAfter: function(el, o, returnElement) {
return this.doInsert(el, o, returnElement, afterend);
},
insertFirst: function(el, o, returnElement) {
return this.doInsert(el, o, returnElement, afterbegin);
},
append: function(el, o, returnElement) {
return this.doInsert(el, o, returnElement, beforeend);
},
overwrite: function(el, html, returnElement) {
var me = this,
newNode;
el = Ext.getDom(el);
html = me.markup(html);
if (me.ieOverwrite) {
newNode = me.ieOverwrite(el, html);
}
if (!newNode) {
el.innerHTML = html;
newNode = el.firstChild;
}
return returnElement ? Ext.get(newNode) : newNode;
},
doInsert: function(el, o, returnElement, where) {
var me = this,
newNode;
el = el.dom || Ext.getDom(el);
if ('innerHTML' in el) {
newNode = me.insertHtml(where, el, me.markup(o));
} else {
newNode = me.createDom(o, null);
if (el.nodeType === 3) {
where = where === afterbegin ? beforebegin : where;
where = where === beforeend ? afterend : where;
}
if (bb_ae_PositionHash[where]) {
el.parentNode.insertBefore(newNode, where === beforebegin ? el : el.nextSibling);
} else if (el.firstChild && where === afterbegin) {
el.insertBefore(newNode, el.firstChild);
} else {
el.appendChild(newNode);
}
}
return returnElement ? Ext.get(newNode) : newNode;
},
createTemplate: function(o) {
var html = this.markup(o);
return new Ext.Template(html);
},
createHtml: function(spec) {
return this.markup(spec);
}
};
});
Ext.define('Ext.overrides.dom.Helper', (function() {
var tableRe = /^(?:table|thead|tbody|tr|td)$/i,
tableElRe = /td|tr|tbody|thead/i,
ts = '<table>',
te = '</table>',
tbs = ts + '<tbody>',
tbe = '</tbody>' + te,
trs = tbs + '<tr>',
tre = '</tr>' + tbe;
return {
override: 'Ext.dom.Helper',
ieInsertHtml: function(where, el, html) {
var frag = null;
if (Ext.isIE9m && tableRe.test(el.tagName)) {
frag = this.insertIntoTable(el.tagName.toLowerCase(), where, el, html);
}
return frag;
},
ieOverwrite: function(el, html) {
if (Ext.isIE9m && tableRe.test(el.tagName)) {
while (el.firstChild) {
el.removeChild(el.firstChild);
}
if (html) {
return this.insertHtml('afterbegin', el, html);
}
}
},
ieTable: function(depth, openingTags, htmlContent, closingTags) {
var i = -1,
el = this.detachedDiv,
ns, nx;
el.innerHTML = [
openingTags,
htmlContent,
closingTags
].join('');
while (++i < depth) {
el = el.firstChild;
}
ns = el.nextSibling;
if (ns) {
ns = el;
el = document.createDocumentFragment();
while (ns) {
nx = ns.nextSibling;
el.appendChild(ns);
ns = nx;
}
}
return el;
},
insertIntoTable: function(tag, where, destinationEl, html) {
var node, before,
bb = where === 'beforebegin',
ab = where === 'afterbegin',
be = where === 'beforeend',
ae = where === 'afterend';
if (tag === 'td' && (ab || be) || !tableElRe.test(tag) && (bb || ae)) {
return null;
}
before = bb ? destinationEl : ae ? destinationEl.nextSibling : ab ? destinationEl.firstChild : null;
if (bb || ae) {
destinationEl = destinationEl.parentNode;
}
if (tag === 'td' || (tag === 'tr' && (be || ab))) {
node = this.ieTable(4, trs, html, tre);
} else if (((tag === 'tbody' || tag === 'thead') && (be || ab)) || (tag === 'tr' && (bb || ae))) {
node = this.ieTable(3, tbs, html, tbe);
} else {
node = this.ieTable(2, ts, html, te);
}
destinationEl.insertBefore(node, before);
return node;
}
};
})());
Ext.define('Ext.dom.Query', function() {
var DQ,
doc = document,
cache, simpleCache, valueCache,
useClassList = !!doc.documentElement.classList,
useElementPointer = !!doc.documentElement.firstElementChild,
useChildrenCollection = (function() {
var d = doc.createElement('div');
d.innerHTML = '<!-- -->text<!-- -->';
return d.children && (d.children.length === 0);
})(),
nonSpace = /\S/,
trimRe = /^\s+|\s+$/g,
tplRe = /\{(\d+)\}/g,
modeRe = /^(\s?[\/>+~]\s?|\s|$)/,
tagTokenRe = /^(#)?([\w\-\*\|\\]+)/,
nthRe = /(\d*)n\+?(\d*)/,
nthRe2 = /\D/,
startIdRe = /^\s*#/,
isIE = window.ActiveXObject ? true : false,
key = 30803,
longHex = /\\([0-9a-fA-F]{6})/g,
shortHex = /\\([0-9a-fA-F]{1,6})\s{0,1}/g,
nonHex = /\\([^0-9a-fA-F]{1})/g,
escapes = /\\/g,
num, hasEscapes,
supportsColonNsSeparator = (function() {
var xmlDoc,
xmlString = '<r><a:b xmlns:a="n"></a:b></r>';
if (window.DOMParser) {
xmlDoc = (new DOMParser()).parseFromString(xmlString, "application/xml");
} else {
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.loadXML(xmlString);
}
return !!xmlDoc.getElementsByTagName('a:b').length;
})(),
longHexToChar = function($0, $1) {
return String.fromCharCode(parseInt($1, 16));
},
shortToLongHex = function($0, $1) {
while ($1.length < 6) {
$1 = '0' + $1;
}
return '\\' + $1;
},
charToLongHex = function($0, $1) {
num = $1.charCodeAt(0).toString(16);
if (num.length === 1) {
num = '0' + num;
}
return '\\0000' + num;
},
unescapeCssSelector = function(selector) {
return (hasEscapes) ? selector.replace(longHex, longHexToChar) : selector;
},
setupEscapes = function(path) {
hasEscapes = (path.indexOf('\\') > -1);
if (hasEscapes) {
path = path.replace(shortHex, shortToLongHex).replace(nonHex, charToLongHex).replace(escapes, '\\\\');
}
return path;
};
eval("var batch = 30803, child, next, prev, byClassName;");
child = useChildrenCollection ? function child(parent, index) {
return parent.children[index];
} : function child(parent, index) {
var i = 0,
n = parent.firstChild;
while (n) {
if (n.nodeType == 1) {
if (++i == index) {
return n;
}
}
n = n.nextSibling;
}
return null;
};
next = useElementPointer ? function(n) {
return n.nextElementSibling;
} : function(n) {
while ((n = n.nextSibling) && n.nodeType != 1){}
return n;
};
prev = useElementPointer ? function(n) {
return n.previousElementSibling;
} : function(n) {
while ((n = n.previousSibling) && n.nodeType != 1){}
return n;
};
function children(parent) {
var n = parent.firstChild,
nodeIndex = -1,
nextNode;
while (n) {
nextNode = n.nextSibling;
if (n.nodeType == 3 && !nonSpace.test(n.nodeValue)) {
parent.removeChild(n);
} else {
n.nodeIndex = ++nodeIndex;
}
n = nextNode;
}
return this;
}
byClassName = useClassList ?
function(nodeSet, cls) {
cls = unescapeCssSelector(cls);
if (!cls) {
return nodeSet;
}
var result = [],
ri = -1,
i, ci, classList;
for (i = 0; ci = nodeSet[i]; i++) {
classList = ci.classList;
if (classList) {
if (classList.contains(cls)) {
result[++ri] = ci;
}
} else if ((' ' + ci.className + ' ').indexOf(cls) !== -1) {
result[++ri] = ci;
}
}
return result;
} : function(nodeSet, cls) {
cls = unescapeCssSelector(cls);
if (!cls) {
return nodeSet;
}
var result = [],
ri = -1,
i, ci;
for (i = 0; ci = nodeSet[i]; i++) {
if ((' ' + ci.className + ' ').indexOf(cls) !== -1) {
result[++ri] = ci;
}
}
return result;
};
function attrValue(n, attr) {
if (!n.tagName && typeof n.length != "undefined") {
n = n[0];
}
if (!n) {
return null;
}
if (attr == "for") {
return n.htmlFor;
}
if (attr == "class" || attr == "className") {
return n.className;
}
return n.getAttribute(attr) || n[attr];
}
function getNodes(ns, mode, tagName) {
var result = [],
ri = -1,
cs, i, ni, j, ci, cn, utag, n, cj;
if (!ns) {
return result;
}
tagName = tagName.replace('|', ':') || "*";
if (typeof ns.getElementsByTagName != "undefined") {
ns = [
ns
];
}
if (!mode) {
tagName = unescapeCssSelector(tagName);
if (!supportsColonNsSeparator && DQ.isXml(ns[0]) && tagName.indexOf(':') !== -1) {
for (i = 0; ni = ns[i]; i++) {
cs = ni.getElementsByTagName(tagName.split(':').pop());
for (j = 0; ci = cs[j]; j++) {
if (ci.tagName === tagName) {
result[++ri] = ci;
}
}
}
} else {
for (i = 0; ni = ns[i]; i++) {
cs = ni.getElementsByTagName(tagName);
for (j = 0; ci = cs[j]; j++) {
result[++ri] = ci;
}
}
}
}
else if (mode == "/" || mode == ">") {
utag = tagName.toUpperCase();
for (i = 0; ni = ns[i]; i++) {
cn = ni.childNodes;
for (j = 0; cj = cn[j]; j++) {
if (cj.nodeName == utag || cj.nodeName == tagName || tagName == '*') {
result[++ri] = cj;
}
}
}
}
else if (mode == "+") {
utag = tagName.toUpperCase();
for (i = 0; n = ns[i]; i++) {
while ((n = n.nextSibling) && n.nodeType != 1){}
if (n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')) {
result[++ri] = n;
}
}
}
else if (mode == "~") {
utag = tagName.toUpperCase();
for (i = 0; n = ns[i]; i++) {
while ((n = n.nextSibling)) {
if (n.nodeName == utag || n.nodeName == tagName || tagName == '*') {
result[++ri] = n;
}
}
}
}
return result;
}
function concat(a, b) {
a.push.apply(a, b);
return a;
}
function byTag(cs, tagName) {
if (cs.tagName || cs === doc) {
cs = [
cs
];
}
if (!tagName) {
return cs;
}
var result = [],
ri = -1,
i, ci;
tagName = tagName.toLowerCase();
for (i = 0; ci = cs[i]; i++) {
if (ci.nodeType == 1 && ci.tagName.toLowerCase() == tagName) {
result[++ri] = ci;
}
}
return result;
}
function byId(cs, id) {
id = unescapeCssSelector(id);
if (cs.tagName || cs === doc) {
cs = [
cs
];
}
if (!id) {
return cs;
}
var result = [],
ri = -1,
i, ci;
for (i = 0; ci = cs[i]; i++) {
if (ci && ci.id == id) {
result[++ri] = ci;
return result;
}
}
return result;
}
function byAttribute(cs, attr, value, op, custom) {
var result = [],
ri = -1,
useGetStyle = custom == "{",
fn = DQ.operators[op],
a, xml, hasXml, i, ci;
value = unescapeCssSelector(value);
for (i = 0; ci = cs[i]; i++) {
if (ci.nodeType === 1) {
if (!hasXml) {
xml = DQ.isXml(ci);
hasXml = true;
}
if (!xml) {
if (useGetStyle) {
a = DQ.getStyle(ci, attr);
} else if (attr == "class" || attr == "className") {
a = ci.className;
} else if (attr == "for") {
a = ci.htmlFor;
} else if (attr == "href") {
a = ci.getAttribute("href", 2);
} else {
a = ci.getAttribute(attr);
}
} else {
a = ci.getAttribute(attr);
}
if ((fn && fn(a, value)) || (!fn && a)) {
result[++ri] = ci;
}
}
}
return result;
}
function byPseudo(cs, name, value) {
value = unescapeCssSelector(value);
return DQ.pseudos[name](cs, value);
}
function nodupIEXml(cs) {
var d = ++key,
r, i, len, c;
cs[0].setAttribute("_nodup", d);
r = [
cs[0]
];
for (i = 1 , len = cs.length; i < len; i++) {
c = cs[i];
if (!c.getAttribute("_nodup") != d) {
c.setAttribute("_nodup", d);
r[r.length] = c;
}
}
for (i = 0 , len = cs.length; i < len; i++) {
cs[i].removeAttribute("_nodup");
}
return r;
}
function nodup(cs) {
if (!cs) {
return [];
}
var len = cs.length,
c, i,
r = cs,
cj,
ri = -1,
d, j;
if (!len || typeof cs.nodeType != "undefined" || len == 1) {
return cs;
}
if (isIE && typeof cs[0].selectSingleNode != "undefined") {
return nodupIEXml(cs);
}
d = ++key;
cs[0]._nodup = d;
for (i = 1; c = cs[i]; i++) {
if (c._nodup != d) {
c._nodup = d;
} else {
r = [];
for (j = 0; j < i; j++) {
r[++ri] = cs[j];
}
for (j = i + 1; cj = cs[j]; j++) {
if (cj._nodup != d) {
cj._nodup = d;
r[++ri] = cj;
}
}
return r;
}
}
return r;
}
function quickDiffIEXml(c1, c2) {
var d = ++key,
r = [],
i, len;
for (i = 0 , len = c1.length; i < len; i++) {
c1[i].setAttribute("_qdiff", d);
}
for (i = 0 , len = c2.length; i < len; i++) {
if (c2[i].getAttribute("_qdiff") != d) {
r[r.length] = c2[i];
}
}
for (i = 0 , len = c1.length; i < len; i++) {
c1[i].removeAttribute("_qdiff");
}
return r;
}
function quickDiff(c1, c2) {
var len1 = c1.length,
d = ++key,
r = [],
i, len;
if (!len1) {
return c2;
}
if (isIE && typeof c1[0].selectSingleNode != "undefined") {
return quickDiffIEXml(c1, c2);
}
for (i = 0; i < len1; i++) {
c1[i]._qdiff = d;
}
for (i = 0 , len = c2.length; i < len; i++) {
if (c2[i]._qdiff != d) {
r[r.length] = c2[i];
}
}
return r;
}
function quickId(ns, mode, root, id) {
if (ns == root) {
id = unescapeCssSelector(id);
var d = root.ownerDocument || root;
return d.getElementById(id);
}
ns = getNodes(ns, mode, "*");
return byId(ns, id);
}
return {
singleton: true,
alternateClassName: [
'Ext.core.DomQuery',
'Ext.DomQuery'
],
requires: [
'Ext.dom.Helper',
'Ext.util.Operators'
],
_init: function() {
DQ = this;
DQ.operators = Ext.Object.chain(Ext.util.Operators);
DQ._cache = cache = new Ext.util.LruCache({
maxSize: 200
});
DQ._valueCache = valueCache = new Ext.util.LruCache({
maxSize: 200
});
DQ._simpleCache = simpleCache = new Ext.util.LruCache({
maxSize: 200
});
},
clearCache: function() {
cache.clear();
valueCache.clear();
simpleCache.clear();
},
getStyle: function(el, name) {
return Ext.fly(el, '_DomQuery').getStyle(name);
},
compile: function(path, type) {
type = type || "select";
var fn = [
"var f = function(root) {\n var mode; ++batch; var n = root || document;\n"
],
lastPath,
matchers = DQ.matchers,
matchersLn = matchers.length,
modeMatch,
lmode = path.match(modeRe),
tokenMatch, matched, j, t, m;
path = setupEscapes(path);
if (lmode && lmode[1]) {
fn[fn.length] = 'mode="' + lmode[1].replace(trimRe, "") + '";';
path = path.replace(lmode[1], "");
}
while (path.substr(0, 1) == "/") {
path = path.substr(1);
}
while (path && lastPath != path) {
lastPath = path;
tokenMatch = path.match(tagTokenRe);
if (type == "select") {
if (tokenMatch) {
if (tokenMatch[1] == "#") {
fn[fn.length] = 'n = quickId(n, mode, root, "' + tokenMatch[2] + '");';
} else {
fn[fn.length] = 'n = getNodes(n, mode, "' + tokenMatch[2] + '");';
}
path = path.replace(tokenMatch[0], "");
} else if (path.substr(0, 1) != '@') {
fn[fn.length] = 'n = getNodes(n, mode, "*");';
}
} else
{
if (tokenMatch) {
if (tokenMatch[1] == "#") {
fn[fn.length] = 'n = byId(n, "' + tokenMatch[2] + '");';
} else {
fn[fn.length] = 'n = byTag(n, "' + tokenMatch[2] + '");';
}
path = path.replace(tokenMatch[0], "");
}
}
while (!(modeMatch = path.match(modeRe))) {
matched = false;
for (j = 0; j < matchersLn; j++) {
t = matchers[j];
m = path.match(t.re);
if (m) {
fn[fn.length] = t.select.replace(tplRe, function(x, i) {
return m[i];
});
path = path.replace(m[0], "");
matched = true;
break;
}
}
if (!matched) {
Ext.Error.raise({
sourceClass: 'Ext.DomQuery',
sourceMethod: 'compile',
msg: 'Error parsing selector. Parsing failed at "' + path + '"'
});
}
}
if (modeMatch[1]) {
fn[fn.length] = 'mode="' + modeMatch[1].replace(trimRe, "") + '";';
path = path.replace(modeMatch[1], "");
}
}
fn[fn.length] = "return nodup(n);\n}";
eval(fn.join(""));
return f;
},
jsSelect: function(path, root, type) {
root = root || doc;
if (typeof root == "string") {
root = doc.getElementById(root);
}
var paths = Ext.splitAndUnescape(path, ","),
results = [],
query, i, len, subPath, result;
for (i = 0 , len = paths.length; i < len; i++) {
subPath = paths[i].replace(trimRe, "");
query = cache.get(subPath);
if (!query) {
query = DQ.compile(subPath, type);
if (!query) {
Ext.Error.raise({
sourceClass: 'Ext.DomQuery',
sourceMethod: 'jsSelect',
msg: subPath + ' is not a valid selector'
});
}
cache.add(subPath, query);
} else {
setupEscapes(subPath);
}
result = query(root);
if (result && result !== doc) {
results = results.concat(result);
}
}
if (paths.length > 1) {
return nodup(results);
}
return results;
},
isXml: function(el) {
var docEl = (el ? el.ownerDocument || el : 0).documentElement;
return docEl ? docEl.nodeName !== "HTML" : false;
},
select: doc.querySelectorAll ? function(path, root, type, single) {
root = root || doc;
if (!DQ.isXml(root)) {
try {
if (root.parentNode && (root.nodeType !== 9) && path.indexOf(',') === -1 && !startIdRe.test(path)) {
path = Ext.makeIdSelector(Ext.id(root)) + ' ' + path;
root = root.parentNode;
}
return single ? [
root.querySelector(path)
] : Ext.Array.toArray(root.querySelectorAll(path));
} catch (e) {}
}
return DQ.jsSelect.call(this, path, root, type);
} : function(path, root, type) {
return DQ.jsSelect.call(this, path, root, type);
},
selectNode: function(path, root) {
return Ext.DomQuery.select(path, root, null, true)[0];
},
selectValue: function(path, root, defaultValue) {
path = path.replace(trimRe, "");
var query = valueCache.get(path),
n, v;
if (!query) {
query = DQ.compile(path, "select");
valueCache.add(path, query);
} else {
setupEscapes(path);
}
n = query(root);
return DQ.getNodeValue(n[0] ? n[0] : n);
},
getNodeValue: function(node, defaultValue) {
if (typeof node.normalize == 'function') {
node.normalize();
}
var v = (node && node.firstChild ? node.firstChild.nodeValue : null);
return ((v === null || v === undefined || v === '') ? defaultValue : v);
},
selectNumber: function(path, root, defaultValue) {
var v = DQ.selectValue(path, root, defaultValue || 0);
return parseFloat(v);
},
is: function(el, ss) {
if (typeof el == "string") {
el = doc.getElementById(el);
}
var isArray = Ext.isArray(el),
result = DQ.filter(isArray ? el : [
el
], ss);
return isArray ? (result.length == el.length) : (result.length > 0);
},
filter: function(els, ss, nonMatches) {
ss = ss.replace(trimRe, "");
var query = simpleCache.get(ss),
result;
if (!query) {
query = DQ.compile(ss, "simple");
simpleCache.add(ss, query);
} else {
setupEscapes(ss);
}
result = query(els);
return nonMatches ? quickDiff(result, els) : result;
},
matchers: [
{
re: /^\.([\w\-\\]+)/,
select: useClassList ? 'n = byClassName(n, "{1}");' : 'n = byClassName(n, " {1} ");'
},
{
re: /^\:([\w\-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
select: 'n = byPseudo(n, "{1}", "{2}");'
},
{
re: /^(?:([\[\{])(?:@)?([\w\-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,
select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
},
{
re: /^#([\w\-\\]+)/,
select: 'n = byId(n, "{1}");'
},
{
re: /^@([\w\-\.]+)/,
select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
}
],
pseudos: {
"first-child": function(c) {
var r = [],
ri = -1,
n, i, ci;
for (i = 0; (ci = n = c[i]); i++) {
while ((n = n.previousSibling) && n.nodeType != 1){}
if (!n) {
r[++ri] = ci;
}
}
return r;
},
"last-child": function(c) {
var r = [],
ri = -1,
n, i, ci;
for (i = 0; (ci = n = c[i]); i++) {
while ((n = n.nextSibling) && n.nodeType != 1){}
if (!n) {
r[++ri] = ci;
}
}
return r;
},
"nth-child": function(c, a) {
var r = [],
ri = -1,
m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a),
f = (m[1] || 1) - 0,
l = m[2] - 0,
i, n, j, cn, pn;
for (i = 0; n = c[i]; i++) {
pn = n.parentNode;
if (batch != pn._batch) {
j = 0;
for (cn = pn.firstChild; cn; cn = cn.nextSibling) {
if (cn.nodeType == 1) {
cn.nodeIndex = ++j;
}
}
pn._batch = batch;
}
if (f == 1) {
if (l === 0 || n.nodeIndex == l) {
r[++ri] = n;
}
} else if ((n.nodeIndex + l) % f === 0) {
r[++ri] = n;
}
}
return r;
},
"only-child": function(c) {
var r = [],
ri = -1,
i, ci;
for (i = 0; ci = c[i]; i++) {
if (!prev(ci) && !next(ci)) {
r[++ri] = ci;
}
}
return r;
},
"empty": function(c) {
var r = [],
ri = -1,
i, ci, cns, j, cn, empty;
for (i = 0; ci = c[i]; i++) {
cns = ci.childNodes;
j = 0;
empty = true;
while (cn = cns[j]) {
++j;
if (cn.nodeType == 1 || cn.nodeType == 3) {
empty = false;
break;
}
}
if (empty) {
r[++ri] = ci;
}
}
return r;
},
"contains": function(c, v) {
var r = [],
ri = -1,
i, ci;
for (i = 0; ci = c[i]; i++) {
if ((ci.textContent || ci.innerText || ci.text || '').indexOf(v) != -1) {
r[++ri] = ci;
}
}
return r;
},
"nodeValue": function(c, v) {
var r = [],
ri = -1,
i, ci;
for (i = 0; ci = c[i]; i++) {
if (ci.firstChild && ci.firstChild.nodeValue == v) {
r[++ri] = ci;
}
}
return r;
},
"checked": function(c) {
var r = [],
ri = -1,
i, ci;
for (i = 0; ci = c[i]; i++) {
if (ci.checked === true) {
r[++ri] = ci;
}
}
return r;
},
"not": function(c, ss) {
return DQ.filter(c, ss, true);
},
"any": function(c, selectors) {
var ss = selectors.split('|'),
r = [],
ri = -1,
s, i, ci, j;
for (i = 0; ci = c[i]; i++) {
for (j = 0; s = ss[j]; j++) {
if (DQ.is(ci, s)) {
r[++ri] = ci;
break;
}
}
}
return r;
},
"odd": function(c) {
return this["nth-child"](c, "odd");
},
"even": function(c) {
return this["nth-child"](c, "even");
},
"nth": function(c, a) {
return c[a - 1] || [];
},
"first": function(c) {
return c[0] || [];
},
"last": function(c) {
return c[c.length - 1] || [];
},
"has": function(c, ss) {
var s = DQ.select,
r = [],
ri = -1,
i, ci;
for (i = 0; ci = c[i]; i++) {
if (s(ss, ci).length > 0) {
r[++ri] = ci;
}
}
return r;
},
"next": function(c, ss) {
var is = DQ.is,
r = [],
ri = -1,
i, ci, n;
for (i = 0; ci = c[i]; i++) {
n = next(ci);
if (n && is(n, ss)) {
r[++ri] = ci;
}
}
return r;
},
"prev": function(c, ss) {
var is = DQ.is,
r = [],
ri = -1,
i, ci, n;
for (i = 0; ci = c[i]; i++) {
n = prev(ci);
if (n && is(n, ss)) {
r[++ri] = ci;
}
}
return r;
},
focusable: function(candidates) {
var len = candidates.length,
results = [],
i = 0,
c;
for (; i < len; i++) {
c = candidates[i];
if (Ext.fly(c, '_DomQuery').isFocusable()) {
results.push(c);
}
}
return results;
},
visible: function(candidates, deep) {
var len = candidates.length,
results = [],
i = 0,
c;
for (; i < len; i++) {
c = candidates[i];
if (Ext.fly(c, '_DomQuery').isVisible(deep)) {
results.push(c);
}
}
return results;
},
isScrolled: function(c) {
var r = [],
ri = -1,
i, ci, s;
for (i = 0; ci = c[i]; i++) {
s = Ext.fly(ci, '_DomQuery').getScroll();
if (s.top > 0 || s.left > 0) {
r[++ri] = ci;
}
}
return r;
}
}
};
}, function() {
this._init();
});
Ext.define('Ext.data.reader.Xml', {
extend: 'Ext.data.reader.Reader',
requires: [
'Ext.dom.Query'
],
alternateClassName: 'Ext.data.XmlReader',
alias: 'reader.xml',
config: {
record: '',
namespace: ''
},
createAccessor: function(expr) {
var me = this;
if (Ext.isEmpty(expr)) {
return Ext.emptyFn;
}
if (Ext.isFunction(expr)) {
return expr;
}
return function(root) {
return me.getNodeValue(Ext.DomQuery.selectNode(expr, root));
};
},
getNodeValue: function(node) {
if (node) {
if (typeof node.normalize === 'function') {
node.normalize();
}
node = node.firstChild;
if (node) {
return node.nodeValue;
}
}
return undefined;
},
getResponseData: function(response) {
var xml = response.responseXML,
error = 'XML data not found in the response';
if (!xml) {
Ext.Logger.warn(error);
return this.createReadError(error);
}
return xml;
},
getData: function(data) {
return data.documentElement || data;
},
getRoot: function(data) {
var nodeName = data.nodeName,
root = this.getRootProperty();
if (!root || (nodeName && nodeName == root)) {
return data;
} else if (Ext.DomQuery.isXml(data)) {
return Ext.DomQuery.selectNode(root, data);
}
},
extractData: function(root, readOptions) {
var recordName = this.getRecord();
if (!recordName) {
Ext.Error.raise('Record is a required parameter');
}
if (recordName !== root.nodeName) {
root = Ext.DomQuery.select(recordName, root);
} else {
root = [
root
];
}
return this.callParent([
root,
readOptions
]);
},
readRecords: function(doc, readOptions,
internalReadOptions) {
if (Ext.isArray(doc)) {
doc = doc[0];
}
return this.callParent([
doc,
readOptions,
internalReadOptions
]);
},
createFieldAccessor: function(field) {
var me = this,
namespace = me.getNamespace(),
selector, result;
selector = field.mapping || ((namespace ? namespace + '|' : '') + field.name);
if (typeof selector === 'function') {
result = function(raw) {
return field.mapping(raw, me);
};
} else {
result = function(raw) {
return me.getNodeValue(Ext.DomQuery.selectNode(selector, raw));
};
}
return result;
},
deprecated: {
'5.1.1': {
properties: {
xmlData: null
}
}
}
});
Ext.define('Ext.data.writer.Xml', {
extend: 'Ext.data.writer.Writer',
alternateClassName: 'Ext.data.XmlWriter',
alias: 'writer.xml',
config: {
documentRoot: 'xmlData',
defaultDocumentRoot: 'xmlData',
header: '',
record: 'record'
},
selectorRe: /[^>\s]+/g,
writeRecords: function(request, data) {
var me = this,
xml = [],
i = 0,
len = data.length,
root = me.getDocumentRoot(),
recordName = me.getRecord(),
record = recordName.match(this.selectorRe),
recLen = record.length,
needsRoot = data.length !== 1 && recLen === 1,
transform;
transform = this.getTransform();
if (transform) {
data = transform(data, request);
}
xml.push(me.getHeader() || '');
if (!root && needsRoot) {
root = me.getDefaultDocumentRoot();
}
if (root) {
xml.push('<', root, '>');
}
for (i = 0; i < recLen - 1; i++) {
xml.push('<', record[i], '>');
}
recordName = record[i];
for (i = 0; i < len; ++i) {
this.objectToElement(recordName, data[i], xml);
}
for (i = recLen - 2; i > -1; i--) {
xml.push('</', 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',
requires: [
'Ext.data.proxy.Ajax',
'Ext.data.reader.Xml',
'Ext.data.writer.Xml'
],
constructor: function(config) {
config = Ext.apply({
proxy: {
type: 'ajax',
reader: 'xml',
writer: 'xml'
}
}, config);
this.callParent([
config
]);
}
});
Ext.define('Ext.data.identifier.Negative', {
extend: 'Ext.data.identifier.Sequential',
alias: 'data.identifier.negative',
config: {
increment: -1,
seed: -1
}
});
Ext.define('Ext.data.identifier.Uuid', {
extend: 'Ext.data.identifier.Generator',
alias: 'data.identifier.uuid',
isUnique: true,
config: {
id: null
},
constructor: function(config) {
this.callParent([
config
]);
this.reconfigure(config);
},
reconfigure: function(config) {
var cls = this.self;
this.generate = (config && config.version === 1) ? cls.createSequential(config.salt, config.timestamp, config.clockSeq) : cls.createRandom();
},
clone: null,
statics: {
createRandom: function() {
var pattern = 'xxxxxxxx-xxxx-4xxx-Rxxx-xMxxxxxxxxxx'.split(''),
hex = '0123456789abcdef'.split(''),
length = pattern.length,
parts = [];
return function() {
for (var r, c,
i = 0; i < length; ++i) {
c = pattern[i];
if (c !== '-' && c !== '4') {
r = Math.random() * 16;
r = (c === 'R') ? (r & 3 | 8) : (r | ((c === 'M') ? 1 : 0));
c = hex[r];
}
parts[i] = c;
}
return parts.join('');
};
},
createSequential: function(salt, time, clockSeq) {
var parts = [],
twoPow32 = Math.pow(2, 32),
saltLo = salt.lo,
saltHi = salt.hi,
timeLo = time.lo,
timeHi = time.hi,
toHex = function(value, length) {
var ret = value.toString(16).toLowerCase();
if (ret.length > length) {
ret = ret.substring(ret.length - length);
}
else if (ret.length < length) {
ret = Ext.String.leftPad(ret, length, '0');
}
return ret;
};
if (typeof salt === 'number') {
saltHi = Math.floor(salt / twoPow32);
saltLo = Math.floor(salt - saltHi * twoPow32);
}
if (typeof time === 'number') {
timeHi = Math.floor(time / twoPow32);
timeLo = Math.floor(time - timeHi * twoPow32);
}
saltHi |= 256;
parts[3] = toHex(128 | ((clockSeq >>> 8) & 63), 2) + toHex(clockSeq & 255, 2);
parts[4] = toHex(saltHi, 4) + toHex(saltLo, 8);
return function() {
parts[0] = toHex(timeLo, 8);
parts[1] = toHex(timeHi & 65535, 4);
parts[2] = toHex(((timeHi >>> 16) & 4095) | (1 << 12), 4);
++timeLo;
if (timeLo >= twoPow32) {
timeLo = 0;
++timeHi;
}
return parts.join('-');
};
}
}
}, function() {
this.Global = new this({
id: 'uuid'
});
});
Ext.define('Ext.data.proxy.WebStorage', {
extend: 'Ext.data.proxy.Client',
alternateClassName: 'Ext.data.WebStorageProxy',
requires: [
'Ext.data.identifier.Sequential'
],
config: {
id: undefined
},
constructor: function(config) {
this.callParent(arguments);
this.cache = {};
if (this.getStorageObject() === undefined) {
Ext.Error.raise("Local Storage is not supported in this browser, please use another type of data proxy");
}
if (this.getId() === undefined) {
Ext.Error.raise("No unique id was provided to the local storage proxy. See Ext.data.proxy.LocalStorage documentation for details");
}
this.initialize();
},
create: function(operation) {
var me = this,
records = operation.getRecords(),
length = records.length,
ids = me.getIds(),
id, record, i, identifier;
if (me.isHierarchical === undefined) {
me.isHierarchical = !!records[0].isNode;
if (me.isHierarchical) {
me.getStorageObject().setItem(me.getTreeKey(), true);
}
}
for (i = 0; i < length; i++) {
record = records[i];
if (record.phantom) {
record.phantom = false;
identifier = record.identifier;
if (identifier && identifier.isUnique) {
id = record.getId();
} else {
id = me.getNextId();
}
} else {
id = record.getId();
}
me.setRecord(record, id);
record.commit();
ids.push(id);
}
me.setIds(ids);
operation.setSuccessful(true);
},
read: function(operation) {
var me = this,
allRecords,
records = [],
success = true,
Model = me.getModel(),
validCount = 0,
recordCreator = operation.getRecordCreator(),
filters, sorters, limit, filterLen, valid, record, ids, length, data, id, i, j;
if (me.isHierarchical) {
records = me.getTreeData();
} else {
ids = me.getIds();
length = ids.length;
id = operation.getId();
if (id) {
data = me.getRecord(id);
if (data !== null) {
record = recordCreator ? recordCreator(data, Model) : new Model(data);
}
if (record) {
records.push(record);
} else {
success = false;
}
} else {
sorters = operation.getSorters();
filters = operation.getFilters();
limit = operation.getLimit();
allRecords = [];
for (i = 0; i < length; i++) {
data = me.getRecord(ids[i]);
record = recordCreator ? recordCreator(data, Model) : new Model(data);
allRecords.push(record);
}
if (sorters) {
Ext.Array.sort(allRecords, Ext.util.Sorter.createComparator(sorters));
}
for (i = operation.getStart() || 0; i < length; i++) {
record = allRecords[i];
valid = true;
if (filters) {
for (j = 0 , filterLen = filters.length; j < filterLen; j++) {
valid = filters[j].filter(record);
}
}
if (valid) {
records.push(record);
validCount++;
}
if (limit && validCount === limit) {
break;
}
}
}
}
if (success) {
operation.setResultSet(new Ext.data.ResultSet({
records: records,
total: records.length,
loaded: true
}));
operation.setSuccessful(true);
} else {
operation.setException('Unable to load records');
}
},
update: function(operation) {
var records = operation.getRecords(),
length = records.length,
ids = this.getIds(),
record, id, i;
for (i = 0; i < length; i++) {
record = records[i];
this.setRecord(record);
record.commit();
id = record.getId();
if (id !== undefined && Ext.Array.indexOf(ids, id) === -1) {
ids.push(id);
}
}
this.setIds(ids);
operation.setSuccessful(true);
},
erase: function(operation) {
var me = this,
records = operation.getRecords(),
ids = me.getIds(),
idLength = ids.length,
newIds = [],
removedHash = {},
i = records.length,
id;
for (; i--; ) {
Ext.apply(removedHash, me.removeRecord(records[i]));
}
for (i = 0; i < idLength; i++) {
id = ids[i];
if (!removedHash[id]) {
newIds.push(id);
}
}
me.setIds(newIds);
operation.setSuccessful(true);
},
getRecord: function(id) {
var me = this,
cache = me.cache,
data = !cache[id] ? Ext.decode(me.getStorageObject().getItem(me.getRecordKey(id))) : cache[id];
if (!data) {
return null;
}
cache[id] = data;
data[me.getModel().prototype.idProperty] = id;
return Ext.merge({}, data);
},
setRecord: function(record, id) {
if (id) {
record.set('id', id, {
commit: true
});
} else {
id = record.getId();
}
var me = this,
rawData = record.getData(),
data = {},
model = me.getModel(),
fields = model.getFields(),
length = fields.length,
i = 0,
field, name, obj, key;
for (; i < length; i++) {
field = fields[i];
name = field.name;
if (field.persist) {
data[name] = rawData[name];
}
}
delete data[model.prototype.idProperty];
if (record.isNode && record.get('depth') === 1) {
delete data.parentId;
}
obj = me.getStorageObject();
key = me.getRecordKey(id);
me.cache[id] = data;
obj.removeItem(key);
obj.setItem(key, Ext.encode(data));
},
removeRecord: function(record) {
var me = this,
id = record.getId(),
records = {},
i, childNodes;
records[id] = record;
me.getStorageObject().removeItem(me.getRecordKey(id));
delete me.cache[id];
if (record.childNodes) {
childNodes = record.childNodes;
for (i = childNodes.length; i--; ) {
Ext.apply(records, me.removeRecord(childNodes[i]));
}
}
return records;
},
getRecordKey: function(id) {
if (id.isModel) {
id = id.getId();
}
return Ext.String.format("{0}-{1}", this.getId(), id);
},
getRecordCounterKey: function() {
return Ext.String.format("{0}-counter", this.getId());
},
getTreeKey: function() {
return Ext.String.format("{0}-tree", this.getId());
},
getIds: function() {
var me = this,
ids = (me.getStorageObject().getItem(me.getId()) || "").split(","),
length = ids.length,
isString = this.getIdField().isStringField,
i;
if (length === 1 && ids[0] === "") {
ids = [];
} else {
for (i = 0; i < length; i++) {
ids[i] = isString ? ids[i] : +ids[i];
}
}
return ids;
},
getIdField: function() {
return this.getModel().prototype.idField;
},
setIds: function(ids) {
var obj = this.getStorageObject(),
str = ids.join(","),
id = this.getId();
obj.removeItem(id);
if (!Ext.isEmpty(str)) {
obj.setItem(id, str);
}
},
getNextId: function() {
var me = this,
obj = me.getStorageObject(),
key = me.getRecordCounterKey(),
isString = me.getIdField().isStringField,
id;
id = me.idGenerator.generate();
obj.setItem(key, id);
if (isString) {
id = id + '';
}
return id;
},
getTreeData: function() {
var me = this,
ids = me.getIds(),
length = ids.length,
records = [],
recordHash = {},
root = [],
i = 0,
Model = me.getModel(),
idProperty = Model.prototype.idProperty,
rootLength, record, parent, parentId, children, id;
for (; i < length; i++) {
id = ids[i];
record = me.getRecord(id);
records.push(record);
recordHash[id] = record;
if (!record.parentId) {
root.push(record);
}
}
rootLength = root.length;
Ext.Array.sort(records, me.sortByParentId);
for (i = rootLength; i < length; i++) {
record = records[i];
parentId = record.parentId;
if (!parent || parent[idProperty] !== parentId) {
parent = recordHash[parentId];
parent.children = children = [];
}
children.push(record);
}
for (i = length; i--; ) {
record = records[i];
if (!record.children && !record.leaf) {
record.loaded = true;
}
}
for (i = rootLength; i--; ) {
record = root[i];
root[i] = new Model(record);
}
return root;
},
sortByParentId: function(node1, node2) {
return (node1.parentId || 0) - (node2.parentId || 0);
},
initialize: function() {
var me = this,
storageObject = me.getStorageObject(),
lastId = +storageObject.getItem(me.getRecordCounterKey()),
id = me.getId();
storageObject.setItem(id, storageObject.getItem(id) || "");
if (storageObject.getItem(me.getTreeKey())) {
me.isHierarchical = true;
}
me.idGenerator = new Ext.data.identifier.Sequential({
seed: lastId ? lastId + 1 : 1
});
},
clear: function() {
var me = this,
obj = me.getStorageObject(),
ids = me.getIds(),
len = ids.length,
i;
for (i = 0; i < len; i++) {
obj.removeItem(me.getRecordKey(ids[i]));
}
obj.removeItem(me.getRecordCounterKey());
obj.removeItem(me.getTreeKey());
obj.removeItem(me.getId());
me.cache = {};
},
getStorageObject: function() {
Ext.Error.raise("The getStorageObject function has not been defined in your Ext.data.proxy.WebStorage subclass");
}
});
Ext.define('Ext.data.proxy.LocalStorage', {
extend: 'Ext.data.proxy.WebStorage',
alias: 'proxy.localstorage',
alternateClassName: 'Ext.data.LocalStorageProxy',
getStorageObject: function() {
return window.localStorage;
}
});
Ext.define('Ext.data.proxy.Rest', {
extend: 'Ext.data.proxy.Ajax',
alternateClassName: 'Ext.data.RestProxy',
alias: 'proxy.rest',
defaultActionMethods: {
create: 'POST',
read: 'GET',
update: 'PUT',
destroy: 'DELETE'
},
slashRe: /\/$/,
periodRe: /\.$/,
config: {
appendId: true,
format: null,
batchActions: false,
actionMethods: {
create: 'POST',
read: 'GET',
update: 'PUT',
destroy: 'DELETE'
}
},
buildUrl: function(request) {
var me = this,
operation = request.getOperation(),
records = operation.getRecords(),
record = records ? records[0] : null,
format = me.getFormat(),
url = me.getUrl(request),
id, params;
if (record && !record.phantom) {
id = record.getId();
} else {
id = operation.getId();
}
if (me.getAppendId() && me.isValidId(id)) {
if (!url.match(me.slashRe)) {
url += '/';
}
url += encodeURIComponent(id);
params = request.getParams();
if (params) {
delete params[me.getIdParam()];
}
}
if (format) {
if (!url.match(me.periodRe)) {
url += '.';
}
url += format;
}
request.setUrl(url);
return me.callParent([
request
]);
},
isValidId: function(id) {
return id || id === 0;
}
});
Ext.define('Ext.data.proxy.SessionStorage', {
extend: 'Ext.data.proxy.WebStorage',
alias: 'proxy.sessionstorage',
alternateClassName: 'Ext.data.SessionStorageProxy',
getStorageObject: function() {
return window.sessionStorage;
}
});
Ext.define('Ext.data.validator.Bound', {
extend: 'Ext.data.validator.Validator',
alias: 'data.validator.bound',
type: 'bound',
config: {
min: undefined,
max: undefined,
emptyMessage: 'Must be present',
minOnlyMessage: null,
maxOnlyMessage: null,
bothOnlyMessage: null
},
constructor: function() {
var me = this;
me.preventConfigure = true;
me.callParent(arguments);
delete me.preventConfigure;
me.configure();
},
setConfig: function() {
var me = this;
me.preventConfigure = true;
me.callParent(arguments);
delete me.preventConfigure;
me.configure();
},
configure: function() {
var me = this,
hasMin, hasMax, min, max;
if (me.preventConfigure) {
return;
}
min = me.getMin();
max = me.getMax();
hasMin = me.hasMin = min !== undefined;
hasMax = me.hasMax = max !== undefined;
if (hasMin && hasMax) {
me._bothMsg = Ext.String.format(me.getBothMessage(), min, max);
} else if (hasMin) {
me._minMsg = Ext.String.format(me.getMinOnlyMessage(), min);
} else if (hasMax) {
me._maxMsg = Ext.String.format(me.getMaxOnlyMessage(), max);
}
},
updateMin: function() {
this.configure();
},
updateMax: function() {
this.configure();
},
updateMinOnlyMessage: function(v) {
this.configure();
},
updateMaxOnlyMessage: function() {
this.configure();
},
updateBothMessage: function() {
this.configure();
},
validate: function(value) {
var me = this,
hasMin = me.hasMin,
hasMax = me.hasMax,
min = me.getMin(),
max = me.getMax(),
msg = this.validateValue(value),
len;
if (msg !== true) {
return msg;
}
value = me.getValue(value);
if (hasMin && hasMax) {
if (value < min || value > max) {
msg = me._bothMsg;
}
} else if (hasMin) {
if (value < min) {
msg = me._minMsg;
}
} else if (hasMax) {
if (value > max) {
msg = me._maxMsg;
}
}
return msg;
},
validateValue: function(value) {
if (value === undefined || value === null) {
return this.getEmptyMessage();
}
return true;
},
getValue: Ext.identityFn
});
Ext.define('Ext.data.validator.Format', {
extend: 'Ext.data.validator.Validator',
alias: 'data.validator.format',
type: 'format',
config: {
message: 'Is in the wrong format',
matcher: undefined
},
constructor: function() {
this.callParent(arguments);
if (!this.getMatcher()) {
Ext.Error.raise('validator.Format must be configured with a matcher');
}
},
validate: function(value) {
var matcher = this.getMatcher(),
result = matcher && matcher.test(value);
return result ? result : this.getMessage();
}
});
Ext.define('Ext.data.validator.Email', {
extend: 'Ext.data.validator.Format',
alias: 'data.validator.email',
type: 'email',
config: {
message: 'Is not a valid email address',
matcher: /^(")?(?:[^\."])(?:(?:[\.])?(?:[\w\-!#$%&'*+\/=?\^_`{|}~]))*\1@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}$/
}
});
Ext.define('Ext.data.validator.List', {
extend: 'Ext.data.validator.Validator',
alias: 'data.validator.list',
type: 'list',
config: {
list: null
},
inclusion: null,
validate: function(value) {
var contains = Ext.Array.contains(this.getList(), value),
inclusion = this.inclusion,
exclusion = !inclusion,
result;
result = (inclusion && contains) || (exclusion && !contains);
return result || this.getMessage();
}
});
Ext.define('Ext.data.validator.Exclusion', {
extend: 'Ext.data.validator.List',
alias: 'data.validator.exclusion',
type: 'exclusion',
config: {
message: 'Is a value that has been excluded'
},
constructor: function() {
this.callParent(arguments);
if (!this.getList()) {
Ext.Error.raise('validator.Exclusion requires a list');
}
},
inclusion: false
});
Ext.define('Ext.data.validator.Inclusion', {
extend: 'Ext.data.validator.List',
alias: 'data.validator.inclusion',
type: 'inclusion',
config: {
message: 'Is not in the list of acceptable values'
},
constructor: function() {
this.callParent(arguments);
if (!this.getList()) {
Ext.Error.raise('validator.Inclusion requires a list');
}
},
inclusion: true
});
Ext.define('Ext.data.validator.Length', {
extend: 'Ext.data.validator.Bound',
alias: 'data.validator.length',
type: 'length',
config: {
minOnlyMessage: 'Length must be at least {0}',
maxOnlyMessage: 'Length must be no more than {0}',
bothMessage: 'Length must be between {0} and {1}'
},
getValue: function(v) {
return String(v).length;
}
});
Ext.define('Ext.data.validator.Presence', {
extend: 'Ext.data.validator.Validator',
alias: 'data.validator.presence',
type: 'presence',
config: {
message: 'Must be present',
allowEmpty: false
},
validate: function(value) {
var valid = !(value === undefined || value === null);
if (valid && !this.getAllowEmpty()) {
valid = !(value === '');
}
return valid ? true : this.getMessage();
}
});
Ext.define('Ext.data.validator.Range', {
extend: 'Ext.data.validator.Bound',
alias: 'data.validator.range',
type: 'range',
config: {
minOnlyMessage: 'Must be must be at least {0}',
maxOnlyMessage: 'Must be no more than than {0}',
bothMessage: 'Must be between {0} and {1}',
nanMessage: 'Must be numeric'
},
validateValue: function(value) {
var msg = this.callParent([
value
]);
if (msg === true && isNaN(value)) {
msg = this.getNanMessage();
}
return msg;
}
});
Ext.define('Ext.direct.Event', {
alias: 'direct.event',
status: true,
constructor: function(config) {
Ext.apply(this, config);
},
getName: function() {
return this.name;
},
getData: function() {
return this.data;
}
});
Ext.define('Ext.direct.RemotingEvent', {
extend: 'Ext.direct.Event',
alias: 'direct.rpc',
getTransaction: function() {
var me = this;
return me.transaction || Ext.direct.Manager.getTransaction(me.tid);
}
});
Ext.define('Ext.direct.ExceptionEvent', {
extend: 'Ext.direct.RemotingEvent',
alias: 'direct.exception',
status: false
});
Ext.define('Ext.direct.JsonProvider', {
extend: 'Ext.direct.Provider',
alias: 'direct.jsonprovider',
uses: [
'Ext.direct.ExceptionEvent',
'Ext.direct.Manager'
],
parseResponse: function(response) {
var text = response && response.responseText;
if (text) {
if (Ext.isObject(text) || Ext.isArray(text)) {
return text;
}
return Ext.decode(text);
}
return null;
},
createEvents: function(response) {
var me = this,
data = null,
events = [],
event, i, len;
try {
data = me.parseResponse(response);
} catch (e) {
event = new Ext.direct.ExceptionEvent({
data: e,
xhr: response,
code: Ext.direct.Manager.exceptions.PARSE,
message: 'Error parsing json response: \n\n ' + e
});
return [
event
];
}
if (Ext.isArray(data)) {
for (i = 0 , len = data.length; i < len; ++i) {
events.push(me.createEvent(data[i]));
}
} else if (Ext.isObject(data)) {
events.push(me.createEvent(data));
}
return events;
},
createEvent: function(response) {
if (typeof response !== 'object' || !('type' in response)) {
return new Ext.direct.ExceptionEvent({
data: response,
code: Ext.direct.Manager.exceptions.DATA,
message: 'Invalid data: event type is not specified'
});
}
return Ext.create('direct.' + response.type, response);
}
});
Ext.define('Ext.direct.PollingProvider', {
extend: 'Ext.direct.JsonProvider',
alias: 'direct.pollingprovider',
requires: [
'Ext.Ajax',
'Ext.util.TaskRunner',
'Ext.direct.ExceptionEvent'
],
type: 'polling',
interval: 3000,
constructor: function(config) {
var me = this;
me.callParent([
config
]);
me.pollTask = Ext.TaskManager.newTask({
run: me.runPoll,
interval: me.interval,
scope: me
});
},
destroy: function() {
this.pollTask = null;
this.callParent();
},
doConnect: function() {
var me = this,
url = me.url,
pollFn = me.pollFn;
if (pollFn && Ext.isString(pollFn)) {
var fnName = pollFn;
me.pollFn = pollFn = Ext.direct.Manager.parseMethod(pollFn);
if (!Ext.isFunction(pollFn)) {
Ext.Error.raise("Cannot resolve Ext.Direct API method " + fnName + " for PollingProvider");
}
} else if (Ext.isFunction(url)) {
Ext.log.warn('Using a function for url is deprecated, use pollFn instead.');
me.pollFn = pollFn = url;
me.url = url = null;
}
if (url || pollFn) {
me.setInterval(me.interval);
me.pollTask.start();
}
},
doDisconnect: function() {
this.pollTask.stop();
},
getInterval: function() {
return this.pollTask.interval;
},
setInterval: function(interval) {
var me = this,
pollTask = me.pollTask;
if (interval < 100) {
Ext.Error.raise("Attempting to configure PollProvider " + me.id + " with interval that is less than 100ms.");
}
me.interval = pollTask.interval = interval;
if (me.isConnected()) {
pollTask.restart(interval);
}
},
runPoll: function() {
var me = this,
url = me.url,
pollFn = me.pollFn,
baseParams = me.baseParams,
args;
if (me.fireEvent('beforepoll', me) !== false) {
if (pollFn) {
args = pollFn.directCfg.method.getArgs({
params: baseParams !== undefined ? baseParams : {},
callback: me.onPollFn,
scope: me
});
pollFn.apply(window, args);
} else {
Ext.Ajax.request({
url: url,
callback: me.onData,
scope: me,
params: baseParams
});
}
me.fireEvent('poll', me);
}
},
onData: function(opt, success, response) {
var me = this,
i, len, events;
if (success) {
events = me.createEvents(response);
for (i = 0 , len = events.length; i < len; ++i) {
me.fireEvent('data', me, events[i]);
}
} else {
events = new Ext.direct.ExceptionEvent({
data: null,
code: Ext.direct.Manager.exceptions.TRANSPORT,
message: 'Unable to connect to the server.',
xhr: response
});
me.fireEvent('data', me, events);
}
},
onPollFn: function(result, event, success, options) {
this.onData(null, success, {
responseText: result
});
},
inheritableStatics: {
checkConfig: function(config) {
return config && config.type === 'polling' && (config.url || config.pollFn);
}
}
});
Ext.define('Ext.direct.RemotingMethod', {
constructor: function(config) {
var me = this,
params = config.params,
len = config.len,
metadataCfg = config.metadata,
metadata = {},
name, pLen, p, param;
me.name = config.name;
if (config.formHandler) {
me.formHandler = config.formHandler;
} else if (Ext.isNumeric(len)) {
me.len = len;
me.ordered = true;
} else {
me.named = true;
me.strict = config.strict !== undefined ? config.strict : true;
me.params = {};
pLen = params && params.length;
for (p = 0; p < pLen; p++) {
param = params[p];
name = Ext.isObject(param) ? param.name : param;
me.params[name] = true;
}
}
if (metadataCfg) {
params = metadataCfg.params;
len = metadataCfg.len;
if (Ext.isNumeric(len)) {
if (len === 0) {
Ext.Error.raise('metadata.len cannot be 0 ' + 'for Ext.Direct method ' + me.name);
}
metadata.ordered = true;
metadata.len = len;
} else if (Ext.isArray(params)) {
metadata.named = true;
metadata.params = {};
for (p = 0 , pLen = params.length; p < pLen; p++) {
param = params[p];
metadata.params[param] = true;
}
metadata.strict = metadataCfg.strict !== undefined ? metadataCfg.strict : true;
} else {
Ext.Error.raise('metadata is neither named nor ordered ' + 'for Ext.Direct method ' + me.name);
}
me.metadata = metadata;
}
},
getArgs: function(config) {
var me = this,
params = config.params,
paramOrder = config.paramOrder,
paramsAsHash = config.paramsAsHash,
metadata = config.metadata,
options = config.options,
args = [],
i, len;
if (me.ordered) {
if (me.len > 0) {
if (paramOrder) {
for (i = 0 , len = paramOrder.length; i < len; i++) {
args.push(params[paramOrder[i]]);
}
} else if (paramsAsHash) {
args.push(params);
}
}
} else {
args.push(params);
}
args.push(config.callback, config.scope || window);
if (options || metadata) {
options = Ext.apply({}, options);
if (metadata) {
options.metadata = metadata;
}
args.push(options);
}
return args;
},
getCallData: function(args) {
var me = this,
data = null,
len = me.len,
params = me.params,
strict = me.strict,
form, callback, scope, name, options, metadata;
if (me.ordered) {
callback = args[len];
scope = args[len + 1];
options = args[len + 2];
if (len !== 0) {
data = args.slice(0, len);
}
} else if (me.formHandler) {
form = args[0];
callback = args[1];
scope = args[2];
options = args[3];
} else {
data = Ext.apply({}, args[0]);
callback = args[1];
scope = args[2];
options = args[3];
if (strict) {
for (name in data) {
if (data.hasOwnProperty(name) && !params[name]) {
delete data[name];
}
}
}
}
if (me.metadata && options && options.metadata) {
if (me.metadata.ordered) {
if (!Ext.isArray(options.metadata)) {
Ext.Error.raise('options.metadata is not an Array ' + 'for Ext.Direct method ' + me.name);
} else if (options.metadata.length < me.metadata.len) {
Ext.Error.raise('Not enough parameters in options.metadata ' + 'for Ext.Direct method ' + me.name);
}
metadata = options.metadata.slice(0, me.metadata.len);
} else {
if (!Ext.isObject(options.metadata)) {
Ext.Error.raise('options.metadata is not an Object ' + 'for Ext.Direct method ' + me.name);
}
metadata = Ext.apply({}, options.metadata);
if (me.metadata.strict) {
for (name in metadata) {
if (metadata.hasOwnProperty(name) && !me.metadata.params[name]) {
delete metadata[name];
}
}
}
for (name in me.metadata.params) {
if (!metadata.hasOwnProperty(name)) {
Ext.Error.raise('Named parameter ' + name + ' is missing ' + 'in options.metadata for Ext.Direct method ' + me.name);
}
}
}
delete options.metadata;
}
return {
form: form,
data: data,
metadata: metadata,
callback: callback,
scope: scope,
options: options
};
}
});
Ext.define('Ext.direct.Transaction', {
alias: 'direct.transaction',
alternateClassName: 'Ext.Direct.Transaction',
statics: {
TRANSACTION_ID: 0
},
constructor: function(config) {
var me = this;
Ext.apply(me, config);
me.id = me.tid = ++me.self.TRANSACTION_ID;
me.retryCount = 0;
},
send: function() {
var me = this;
me.provider.queueTransaction(me);
},
retry: function() {
var me = this;
me.retryCount++;
me.send();
},
getProvider: function() {
return this.provider;
}
});
Ext.define('Ext.direct.RemotingProvider', {
extend: 'Ext.direct.JsonProvider',
alias: 'direct.remotingprovider',
requires: [
'Ext.util.MixedCollection',
'Ext.util.DelayedTask',
'Ext.direct.Transaction',
'Ext.direct.RemotingMethod',
'Ext.direct.Manager'
],
type: 'remoting',
enableBuffer: 10,
maxRetries: 1,
constructor: function(config) {
var me = this;
me.callParent(arguments);
me.namespace = (Ext.isString(me.namespace)) ? Ext.ns(me.namespace) : me.namespace || Ext.global;
me.transactions = new Ext.util.MixedCollection();
me.callBuffer = [];
},
doConnect: function() {
if (!this.apiCreated) {
this.initAPI();
this.apiCreated = true;
}
},
getNamespace: function(root, action) {
var parts, ns, i, len;
root = root || Ext.global;
parts = action.toString().split('.');
for (i = 0 , len = parts.length; i < len; i++) {
ns = parts[i];
root = root[ns];
if (typeof root === 'undefined') {
return root;
}
}
return root;
},
createNamespaces: function(root, action) {
var parts, ns, i, len;
root = root || Ext.global;
parts = action.toString().split('.');
for (i = 0 , len = parts.length; i < len; i++) {
ns = parts[i];
root[ns] = root[ns] || {};
root = root[ns];
}
return root;
},
initAPI: function() {
var me = this,
actions = me.actions,
namespace = me.namespace,
Manager = Ext.direct.Manager,
action, cls, methods, i, len, method, handler;
for (action in actions) {
if (actions.hasOwnProperty(action)) {
if (me.disableNestedActions) {
cls = namespace[action];
if (!cls) {
cls = namespace[action] = {};
}
} else {
cls = me.getNamespace(namespace, action);
if (!cls) {
cls = me.createNamespaces(namespace, action);
}
}
methods = actions[action];
for (i = 0 , len = methods.length; i < len; ++i) {
method = new Ext.direct.RemotingMethod(methods[i]);
cls[method.name] = handler = me.createHandler(action, method);
Manager.registerMethod(handler.$name, handler);
}
}
}
},
createHandler: function(action, method) {
var me = this,
slice = Array.prototype.slice,
handler;
if (!method.formHandler) {
handler = function() {
me.configureRequest(action, method, slice.call(arguments, 0));
};
} else {
handler = function() {
me.configureFormRequest(action, method, slice.call(arguments, 0));
};
}
handler.name = handler.$name = action + '.' + method.name;
handler.$directFn = true;
handler.directCfg = handler.$directCfg = {
action: action,
method: method
};
return handler;
},
connect: function() {
var me = this;
if (!me.url) {
Ext.Error.raise('Error initializing RemotingProvider "' + me.id + '", no url configured.');
}
me.callParent();
},
runCallback: function(transaction, event) {
var success = !!event.status,
funcName = success ? 'success' : 'failure',
callback, options, result;
if (transaction && transaction.callback) {
callback = transaction.callback;
options = transaction.callbackOptions;
result = typeof event.result !== 'undefined' ? event.result : event.data;
if (Ext.isFunction(callback)) {
callback(result, event, success, options);
} else {
Ext.callback(callback[funcName], callback.scope, [
result,
event,
success,
options
]);
Ext.callback(callback.callback, callback.scope, [
result,
event,
success,
options
]);
}
}
},
onData: function(options, success, response) {
var me = this,
i, len, events, event, transaction, transactions;
if (success) {
events = me.createEvents(response);
for (i = 0 , len = events.length; i < len; ++i) {
event = events[i];
transaction = me.getTransaction(event);
me.fireEvent('data', me, event);
if (transaction && me.fireEvent('beforecallback', me, event, transaction) !== false) {
me.runCallback(transaction, event, true);
Ext.direct.Manager.removeTransaction(transaction);
}
}
} else {
transactions = [].concat(options.transaction);
for (i = 0 , len = transactions.length; i < len; ++i) {
transaction = me.getTransaction(transactions[i]);
if (transaction && transaction.retryCount < me.maxRetries) {
transaction.retry();
} else {
event = new Ext.direct.ExceptionEvent({
data: null,
transaction: transaction,
code: Ext.direct.Manager.exceptions.TRANSPORT,
message: 'Unable to connect to the server.',
xhr: response
});
me.fireEvent('data', me, event);
if (transaction && me.fireEvent('beforecallback', me, transaction) !== false) {
me.runCallback(transaction, event, false);
Ext.direct.Manager.removeTransaction(transaction);
}
}
}
}
},
getTransaction: function(options) {
return options && options.tid ? Ext.direct.Manager.getTransaction(options.tid) : null;
},
getPayload: function(transaction) {
var result = {
action: transaction.action,
method: transaction.method,
data: transaction.data,
type: 'rpc',
tid: transaction.id
};
if (transaction.metadata) {
result.metadata = transaction.metadata;
}
return result;
},
sendRequest: function(transaction) {
var me = this,
request, callData, params,
enableUrlEncode = me.enableUrlEncode,
payload, i, len;
request = {
url: me.url,
callback: me.onData,
scope: me,
transaction: transaction,
timeout: me.timeout
};
if (transaction.timeout) {
request.timeout = transaction.timeout;
}
if (Ext.isArray(transaction)) {
callData = [];
for (i = 0 , len = transaction.length; i < len; ++i) {
payload = me.getPayload(transaction[i]);
callData.push(payload);
}
} else {
callData = me.getPayload(transaction);
}
if (enableUrlEncode) {
params = {};
params[Ext.isString(enableUrlEncode) ? enableUrlEncode : 'data'] = Ext.encode(callData);
request.params = params;
} else {
request.jsonData = callData;
}
Ext.Ajax.request(request);
},
queueTransaction: function(transaction) {
var me = this,
enableBuffer = me.enableBuffer;
if (transaction.form) {
me.sendFormRequest(transaction);
return;
}
if (enableBuffer === false || typeof transaction.timeout !== 'undefined') {
me.sendRequest(transaction);
return;
}
me.callBuffer.push(transaction);
if (enableBuffer) {
if (!me.callTask) {
me.callTask = new Ext.util.DelayedTask(me.combineAndSend, me);
}
me.callTask.delay(Ext.isNumber(enableBuffer) ? enableBuffer : 10);
} else {
me.combineAndSend();
}
},
combineAndSend: function() {
var me = this,
buffer = me.callBuffer,
len = buffer.length;
if (len > 0) {
me.sendRequest(len === 1 ? buffer[0] : buffer);
me.callBuffer = [];
}
},
configureTransaction: function(action, method, args, isForm) {
var data, cb, scope, options, params;
data = method.getCallData(args);
cb = data.callback;
scope = data.scope;
options = data.options;
if (cb && !Ext.isFunction(cb)) {
Ext.Error.raise("Callback argument is not a function " + "for Ext.Direct method " + action + "." + method.name);
}
cb = cb && scope ? Ext.Function.bind(cb, scope) : cb;
params = Ext.apply({}, {
provider: this,
args: args,
action: action,
method: method.name,
form: data.form,
data: data.data,
metadata: data.metadata,
callbackOptions: options,
callback: cb,
isForm: isForm
});
if (options && options.timeout != null) {
params.timeout = options.timeout;
}
return new Ext.direct.Transaction(params);
},
configureRequest: function(action, method, args) {
var me = this,
transaction;
transaction = me.configureTransaction(action, method, args);
if (me.fireEvent('beforecall', me, transaction, method) !== false) {
Ext.direct.Manager.addTransaction(transaction);
me.queueTransaction(transaction);
me.fireEvent('call', me, transaction, method);
}
},
configureFormRequest: function(action, method, args) {
var me = this,
transaction, form, isUpload, postParams;
transaction = me.configureTransaction(action, method, args, true);
if (me.fireEvent('beforecall', me, transaction, method) !== false) {
Ext.direct.Manager.addTransaction(transaction);
form = transaction.form;
isUpload = String(form.getAttribute("enctype")).toLowerCase() === 'multipart/form-data';
postParams = {
extTID: transaction.id,
extAction: action,
extMethod: method.name,
extType: 'rpc',
extUpload: String(isUpload)
};
if (transaction.metadata) {
postParams.extMetadata = Ext.JSON.encode(transaction.metadata);
}
Ext.apply(transaction, {
form: form,
isUpload: isUpload,
params: postParams
});
me.sendFormRequest(transaction);
me.fireEvent('call', me, transaction, method);
}
},
sendFormRequest: function(transaction) {
var me = this;
Ext.Ajax.request({
url: me.url,
params: transaction.params,
callback: me.onData,
scope: me,
form: transaction.form,
isUpload: transaction.isUpload,
transaction: transaction
});
},
inheritableStatics: {
checkConfig: function(config) {
return config && config.type === 'remoting' && config.url && Ext.isArray(config.actions);
}
}
});
Ext.define('Ext.dom.GarbageCollector', {
singleton: true,
interval: 30000,
constructor: function() {
var me = this;
me.collect = Ext.Function.bind(me.collect, me);
me.lastTime = Ext.now();
me.resume();
},
collect: function() {
var me = this,
cache = Ext.cache,
eid, dom, el, t, isGarbage, tagName;
var collectedIds = [];
for (eid in cache) {
if (!cache.hasOwnProperty(eid)) {
continue;
}
el = cache[eid];
if (el.skipGarbageCollection) {
continue;
}
dom = el.dom;
if (!dom) {
Ext.Error.raise('Missing DOM node in element garbage collection: ' + eid);
}
try {
isGarbage = Ext.isGarbage(dom);
} catch (e) {
delete cache[eid];
collectedIds.push('#' + el.id);
continue;
}
if (isGarbage) {
if (el && el.dom) {
tagName = el.dom.tagName;
el.collect();
collectedIds.push((tagName ? tagName : '') + '#' + el.id);
}
}
}
if (Ext.isIE9m) {
t = {};
for (eid in cache) {
if (cache.hasOwnProperty(eid)) {
t[eid] = cache[eid];
}
}
Ext.cache = Ext.dom.Element.cache = t;
}
me.lastTime = Ext.now();
return collectedIds;
},
pause: function() {
clearTimeout(this.timerId);
},
resume: function() {
var me = this,
lastTime = me.lastTime;
if (Ext.enableGarbageCollector && (Ext.now() - lastTime > me.interval)) {
me.collect();
}
me.timerId = Ext.interval(me.collect, me.interval);
}
});
Ext.define('Ext.event.gesture.Recognizer', {
requires: [
'Ext.event.publisher.Gesture'
],
mixins: [
'Ext.mixin.Identifiable'
],
priority: 0,
handledEvents: [],
config: {
onRecognized: Ext.emptyFn,
callbackScope: null
},
constructor: function(config) {
this.initConfig(config);
Ext.event.publisher.Gesture.instance.registerRecognizer(this);
},
onStart: Ext.emptyFn,
onEnd: Ext.emptyFn,
onTouchStart: Ext.emptyFn,
onTouchMove: Ext.emptyFn,
onTouchEnd: Ext.emptyFn,
onTouchCancel: Ext.emptyFn,
fail: function() {
return false;
},
fire: function() {
this.getOnRecognized().apply(this.getCallbackScope(), arguments);
},
reset: Ext.emptyFn,
debugHooks: {
$enabled: false,
fail: function(msg) {
Ext.log.info(this.$className + ' Gesture Failed: ' + msg);
return false;
}
}
});
Ext.define('Ext.event.gesture.SingleTouch', {
extend: 'Ext.event.gesture.Recognizer',
inheritableStatics: {
NOT_SINGLE_TOUCH: "Not Single Touch",
TOUCH_MOVED: "Touch Moved",
EVENT_CANCELED: "Event Canceled"
},
onTouchStart: function(e) {
if (e.touches.length > 1) {
return this.fail(this.self.NOT_SINGLE_TOUCH);
}
},
onTouchCancel: function() {
return false;
}
});
Ext.define('Ext.event.gesture.DoubleTap', {
extend: 'Ext.event.gesture.SingleTouch',
priority: 300,
inheritableStatics: {
DIFFERENT_TARGET: 'Different Target'
},
config: {
moveDistance: 8,
tapDistance: 24,
maxDuration: 300
},
handledEvents: [
'singletap',
'doubletap'
],
singleTapTimer: null,
startTime: 0,
lastTapTime: 0,
onTouchStart: function(e) {
var me = this,
lastStartPoint;
if (me.callParent(arguments) === false) {
return false;
}
lastStartPoint = me.lastStartPoint = e.changedTouches[0].point;
me.startPoint = me.startPoint || lastStartPoint;
me.startTime = e.time;
clearTimeout(me.singleTapTimer);
},
onTouchMove: function(e) {
var me = this,
point = e.changedTouches[0].point;
if (Math.abs(point.getDistanceTo(me.lastStartPoint)) >= me.getMoveDistance()) {
me.startPoint = null;
return me.fail(me.self.TOUCH_MOVED);
}
},
onTouchEnd: function(e) {
var me = this,
maxDuration = me.getMaxDuration(),
time = e.time,
target = e.target,
lastTapTime = me.lastTapTime,
lastTarget = me.lastTarget,
point = e.changedTouches[0].point,
duration;
me.lastTapTime = time;
me.lastTarget = target;
if (lastTapTime) {
duration = time - lastTapTime;
if (duration <= maxDuration && Math.abs(point.getDistanceTo(me.startPoint)) <= me.getTapDistance()) {
if (target !== lastTarget) {
return me.fail(me.self.DIFFERENT_TARGET);
}
me.lastTarget = null;
me.lastTapTime = 0;
me.fire('doubletap', e, {
touch: e.changedTouches[0],
duration: duration
});
me.startPoint = null;
return;
}
}
if (time - me.startTime > maxDuration) {
me.fireSingleTap(e);
} else {
me.setSingleTapTimer(e);
}
},
setSingleTapTimer: function(e) {
var me = this;
me.singleTapTimer = Ext.defer(function() {
me.fireSingleTap(e);
}, me.getMaxDuration());
},
fireSingleTap: function(e, touch) {
this.fire('singletap', e, {
touch: touch
});
this.startPoint = null;
},
reset: function() {
var me = this;
me.startTime = me.lastTapTime = 0;
me.lastStartPoint = me.startPoint = me.singleTapTimer = null;
}
}, function(DoubleTap) {
var gestures = Ext.manifest.gestures;
DoubleTap.instance = new DoubleTap(gestures && gestures.doubleTap);
});
Ext.define('Ext.event.gesture.Drag', {
extend: 'Ext.event.gesture.SingleTouch',
priority: 100,
isStarted: false,
startPoint: null,
previousPoint: null,
lastPoint: null,
handledEvents: [
'dragstart',
'drag',
'dragend',
'dragcancel'
],
config: {
minDistance: 8
},
constructor: function() {
this.callParent(arguments);
this.initInfo();
},
initInfo: function() {
this.info = {
touch: null,
previous: {
x: 0,
y: 0
},
x: 0,
y: 0,
delta: {
x: 0,
y: 0
},
absDelta: {
x: 0,
y: 0
},
flick: {
velocity: {
x: 0,
y: 0
}
},
direction: {
x: 0,
y: 0
},
time: 0,
previousTime: {
x: 0,
y: 0
}
};
},
onTouchStart: function(e) {
if (this.callParent(arguments) === false) {
if (this.isStarted && this.lastMoveEvent !== null) {
this.lastMoveEvent.isStopped = false;
this.onTouchEnd(this.lastMoveEvent);
}
return false;
}
this.startTime = e.time;
this.startPoint = e.changedTouches[0].point;
},
tryDragStart: function(e) {
var startPoint = this.startPoint,
touch = e.changedTouches[0],
point = touch.point,
minDistance = this.getMinDistance(),
info = this.info;
if (Math.abs(point.getDistanceTo(startPoint)) >= minDistance) {
this.isStarted = true;
this.previousPoint = this.lastPoint = point;
this.resetInfo('x', e, touch);
this.resetInfo('y', e, touch);
info.time = e.time;
this.fire('dragstart', e, info);
}
},
onTouchMove: function(e) {
if (!this.isStarted) {
this.tryDragStart(e);
}
if (!this.isStarted) {
return;
}
var touch = e.changedTouches[0],
point = touch.point;
if (this.lastPoint) {
this.previousPoint = this.lastPoint;
}
this.lastPoint = point;
this.lastMoveEvent = e;
this.updateInfo('x', e, touch);
this.updateInfo('y', e, touch);
this.info.time = e.time;
this.fire('drag', e, this.info);
},
onAxisDragEnd: function(axis, info) {
var duration = info.time - info.previousTime[axis];
if (duration > 0) {
info.flick.velocity[axis] = (info[axis] - info.previous[axis]) / duration;
}
},
resetInfo: function(axis, e, touch) {
var value = this.lastPoint[axis],
startValue = this.startPoint[axis],
delta = value - startValue,
capAxis = axis.toUpperCase(),
info = this.info;
info.touch = touch;
info.delta[axis] = delta;
info.absDelta[axis] = Math.abs(delta);
info.previousTime[axis] = this.startTime;
info.previous[axis] = startValue;
info[axis] = value;
info.direction[axis] = 0;
info['start' + capAxis] = this.startPoint[axis];
info['previous' + capAxis] = info.previous[axis];
info['page' + capAxis] = info[axis];
info['delta' + capAxis] = info.delta[axis];
info['absDelta' + capAxis] = info.absDelta[axis];
info['previousDelta' + capAxis] = 0;
info.startTime = this.startTime;
},
updateInfo: function(axis, e, touch) {
var me = this,
value = me.lastPoint[axis],
previousValue = me.previousPoint[axis],
startValue = me.startPoint[axis],
delta = value - startValue,
info = me.info,
direction = info.direction,
capAxis = axis.toUpperCase(),
previousFlick = info.previous[axis];
info.touch = touch;
info.delta[axis] = delta;
info.absDelta[axis] = Math.abs(delta);
if (value !== previousFlick && value !== info[axis]) {
info.previous[axis] = info[axis];
info.previousTime[axis] = info.time;
}
info[axis] = value;
if (value > previousValue) {
direction[axis] = 1;
} else if (value < previousValue) {
direction[axis] = -1;
}
info['start' + capAxis] = startValue;
info['previous' + capAxis] = info.previous[axis];
info['page' + capAxis] = info[axis];
info['delta' + capAxis] = info.delta[axis];
info['absDelta' + capAxis] = info.absDelta[axis];
info['previousDelta' + capAxis] = info.previous[axis] - startValue;
info.startTime = me.startTime;
},
onTouchEnd: function(e) {
this.doEnd(e);
},
onTouchCancel: function(e) {
this.doEnd(e, true);
return false;
},
doEnd: function(e, isCancel) {
if (!this.isStarted) {
this.tryDragStart(e);
}
if (this.isStarted) {
var touch = e.changedTouches[0],
point = touch.point,
info = this.info;
this.isStarted = false;
this.lastPoint = point;
this.updateInfo('x', e, touch);
this.updateInfo('y', e, touch);
info.time = e.time;
this.onAxisDragEnd('x', info);
this.onAxisDragEnd('y', info);
this.fire(isCancel ? 'dragcancel' : 'dragend', e, info);
this.startPoint = null;
this.previousPoint = null;
this.lastPoint = null;
this.lastMoveEvent = null;
}
},
reset: function() {
var me = this;
me.isStarted = me.lastPoint = me.startPoint = me.previousPoint = me.lastPoint = me.lastMoveEvent = null;
me.initInfo();
}
}, function(Drag) {
var gestures = Ext.manifest.gestures;
Drag.instance = new Drag(gestures && gestures.drag);
});
Ext.define('Ext.event.gesture.Swipe', {
extend: 'Ext.event.gesture.SingleTouch',
priority: 500,
handledEvents: [
'swipestart',
'swipe',
'swipecancel'
],
inheritableStatics: {
MAX_OFFSET_EXCEEDED: 'Max Offset Exceeded',
MAX_DURATION_EXCEEDED: 'Max Duration Exceeded',
DISTANCE_NOT_ENOUGH: 'Distance Not Enough'
},
config: {
minDistance: 80,
maxOffset: 35,
maxDuration: 1000
},
onTouchStart: function(e) {
if (this.callParent(arguments) === false) {
return false;
}
var touch = e.changedTouches[0];
this.startTime = e.time;
this.isHorizontal = true;
this.isVertical = true;
this.startX = touch.pageX;
this.startY = touch.pageY;
},
onTouchMove: function(e) {
var touch = e.changedTouches[0],
x = touch.pageX,
y = touch.pageY,
deltaX = x - this.startX,
deltaY = y - this.startY,
absDeltaX = Math.abs(x - this.startX),
absDeltaY = Math.abs(y - this.startY),
duration = e.time - this.startTime,
minDistance = this.getMinDistance(),
time = e.time,
direction, distance;
if (time - this.startTime > this.getMaxDuration()) {
return this.fail(this.self.MAX_DURATION_EXCEEDED);
}
if (this.isHorizontal && absDeltaY > this.getMaxOffset()) {
this.isHorizontal = false;
}
if (this.isVertical && absDeltaX > this.getMaxOffset()) {
this.isVertical = false;
}
if (!this.isVertical || !this.isHorizontal) {
if (this.isHorizontal && absDeltaX < minDistance) {
direction = (deltaX < 0) ? 'left' : 'right';
distance = absDeltaX;
} else if (this.isVertical && absDeltaY < minDistance) {
direction = (deltaY < 0) ? 'up' : 'down';
distance = absDeltaY;
}
}
if (direction && !this.started) {
this.started = true;
this.fire('swipestart', e, {
touch: touch,
direction: direction,
distance: distance,
duration: duration
});
}
if (!this.isHorizontal && !this.isVertical) {
return this.fail(this.self.MAX_OFFSET_EXCEEDED);
}
},
onTouchEnd: function(e) {
if (this.onTouchMove(e) === false) {
return false;
}
var touch = e.changedTouches[0],
x = touch.pageX,
y = touch.pageY,
deltaX = x - this.startX,
deltaY = y - this.startY,
absDeltaX = Math.abs(deltaX),
absDeltaY = Math.abs(deltaY),
minDistance = this.getMinDistance(),
duration = e.time - this.startTime,
direction, distance;
if (this.isVertical && absDeltaY < minDistance) {
this.isVertical = false;
}
if (this.isHorizontal && absDeltaX < minDistance) {
this.isHorizontal = false;
}
if (this.isHorizontal) {
direction = (deltaX < 0) ? 'left' : 'right';
distance = absDeltaX;
} else if (this.isVertical) {
direction = (deltaY < 0) ? 'up' : 'down';
distance = absDeltaY;
} else {
return this.fail(this.self.DISTANCE_NOT_ENOUGH);
}
this.started = false;
this.fire('swipe', e, {
touch: touch,
direction: direction,
distance: distance,
duration: duration
});
},
onTouchCancel: function(e) {
this.fire('swipecancel', e);
return false;
},
reset: function() {
var me = this;
me.startTime = me.isHorizontal = me.isVertical = me.startX = me.startY = null;
}
}, function(Swipe) {
var gestures = Ext.manifest.gestures;
Swipe.instance = new Swipe(gestures && gestures.swipe);
});
Ext.define('Ext.event.gesture.EdgeSwipe', {
extend: 'Ext.event.gesture.Swipe',
priority: 800,
handledEvents: [
'edgeswipe',
'edgeswipestart',
'edgeswipeend',
'edgeswipecancel'
],
inheritableStatics: {
NOT_NEAR_EDGE: 'Not Near Edge'
},
config: {
minDistance: 60
},
onTouchStart: function(e) {
if (this.callParent(arguments) === false) {
return false;
}
var touch = e.changedTouches[0];
this.started = false;
this.direction = null;
this.isHorizontal = true;
this.isVertical = true;
this.startX = touch.pageX;
this.startY = touch.pageY;
},
onTouchMove: function(e) {
var touch = e.changedTouches[0],
x = touch.pageX,
y = touch.pageY,
deltaX = x - this.startX,
deltaY = y - this.startY,
absDeltaY = Math.abs(y - this.startY),
absDeltaX = Math.abs(x - this.startX),
minDistance = this.getMinDistance(),
maxOffset = this.getMaxOffset(),
duration = e.time - this.startTime,
elementWidth = Ext.Viewport && Ext.Element.getViewportWidth(),
elementHeight = Ext.Viewport && Ext.Element.getViewportHeight(),
direction, distance;
if (this.isVertical && absDeltaX > maxOffset) {
this.isVertical = false;
}
if (this.isHorizontal && absDeltaY > maxOffset) {
this.isHorizontal = false;
}
if (this.isVertical && this.isHorizontal) {
if (absDeltaY > absDeltaX) {
this.isHorizontal = false;
} else {
this.isVertical = false;
}
}
if (this.isHorizontal) {
direction = (deltaX < 0) ? 'left' : 'right';
distance = deltaX;
} else if (this.isVertical) {
direction = (deltaY < 0) ? 'up' : 'down';
distance = deltaY;
}
direction = this.direction || (this.direction = direction);
if (direction === 'up') {
distance = deltaY * -1;
} else if (direction === 'left') {
distance = deltaX * -1;
}
this.distance = distance;
if (!distance) {
return this.fail(this.self.DISTANCE_NOT_ENOUGH);
}
if (!this.started) {
if (direction === 'right' && this.startX > minDistance) {
return this.fail(this.self.NOT_NEAR_EDGE);
} else if (direction === 'down' && this.startY > minDistance) {
return this.fail(this.self.NOT_NEAR_EDGE);
} else if (direction === 'left' && (elementWidth - this.startX) > minDistance) {
return this.fail(this.self.NOT_NEAR_EDGE);
} else if (direction === 'up' && (elementHeight - this.startY) > minDistance) {
return this.fail(this.self.NOT_NEAR_EDGE);
}
this.started = true;
this.startTime = e.time;
this.fire('edgeswipestart', e, {
touch: touch,
direction: direction,
distance: distance,
duration: duration
});
} else {
this.fire('edgeswipe', e, {
touch: touch,
direction: direction,
distance: distance,
duration: duration
});
}
},
onTouchEnd: function(e) {
var duration;
if (this.onTouchMove(e) !== false) {
duration = e.time - this.startTime;
this.fire('edgeswipeend', e, {
touch: e.changedTouches[0],
direction: this.direction,
distance: this.distance,
duration: duration
});
}
},
onTouchCancel: function(e) {
this.fire('edgeswipecancel', e, {
touch: e.changedTouches[0]
});
return false;
},
reset: function() {
var me = this;
me.started = me.direction = me.isHorizontal = me.isVertical = me.startX = me.startY = me.startTime = me.distance = null;
}
}, function(EdgeSwipe) {
var gestures = Ext.manifest.gestures;
EdgeSwipe.instance = new EdgeSwipe(gestures && gestures.edgeSwipe);
});
Ext.define('Ext.event.gesture.LongPress', {
extend: 'Ext.event.gesture.SingleTouch',
priority: 400,
inheritableStatics: {
DURATION_NOT_ENOUGH: 'Duration Not Enough'
},
config: {
moveDistance: 8,
minDuration: 1000
},
handledEvents: [
'longpress',
'taphold'
],
fireLongPress: function(e) {
this.fire('longpress', e, {
touch: e.changedTouches[0],
duration: this.getMinDuration()
});
this.isLongPress = true;
},
onTouchStart: function(e) {
if (this.callParent(arguments) === false) {
return false;
}
this.startPoint = e.changedTouches[0].point;
this.isLongPress = false;
this.setLongPressTimer(e);
},
setLongPressTimer: function(e) {
var me = this;
me.timer = Ext.defer(function() {
me.fireLongPress(e);
}, me.getMinDuration());
},
onTouchMove: function(e) {
var point = e.changedTouches[0].point;
if (Math.abs(point.getDistanceTo(this.startPoint)) >= this.getMoveDistance()) {
return this.fail(this.self.TOUCH_MOVED);
}
},
onTouchEnd: function() {
if (!this.isLongPress) {
return this.fail(this.self.DURATION_NOT_ENOUGH);
}
},
fail: function() {
clearTimeout(this.timer);
return this.callParent(arguments);
},
reset: function() {
this.isLongPress = this.startPoint = null;
},
fire: function(eventName) {
if (eventName === 'longpress') {
var args = Array.prototype.slice.call(arguments);
args[0] = 'taphold';
this.fire.apply(this, args);
}
return this.callParent(arguments);
}
}, function(LongPress) {
var gestures = Ext.manifest.gestures;
LongPress.instance = new LongPress(gestures && gestures.longPress);
});
Ext.define('Ext.event.gesture.MultiTouch', {
extend: 'Ext.event.gesture.Recognizer',
requiredTouchesCount: 2,
isTracking: false,
isStarted: false,
onTouchStart: function(e) {
var requiredTouchesCount = this.requiredTouchesCount,
touches = e.touches,
touchesCount = touches.length;
if (touchesCount === requiredTouchesCount) {
this.start(e);
} else if (touchesCount > requiredTouchesCount) {
this.end(e);
}
},
onTouchEnd: function(e) {
this.end(e);
},
onTouchCancel: function(e) {
this.end(e, true);
return false;
},
start: function() {
if (!this.isTracking) {
this.isTracking = true;
this.isStarted = false;
}
},
end: function(e, isCancel) {
if (this.isTracking) {
this.isTracking = false;
if (this.isStarted) {
this.isStarted = false;
this[isCancel ? 'fireCancel' : 'fireEnd'](e);
}
}
},
reset: function() {
this.isTracking = this.isStarted = false;
}
});
Ext.define('Ext.event.gesture.Pinch', {
extend: 'Ext.event.gesture.MultiTouch',
priority: 600,
handledEvents: [
'pinchstart',
'pinch',
'pinchend',
'pinchcancel'
],
startDistance: 0,
lastTouches: null,
onTouchMove: function(e) {
if (!this.isTracking) {
return;
}
var touches = e.touches,
firstPoint, secondPoint, distance;
firstPoint = touches[0].point;
secondPoint = touches[1].point;
distance = firstPoint.getDistanceTo(secondPoint);
if (distance === 0) {
return;
}
if (!this.isStarted) {
this.isStarted = true;
this.startDistance = distance;
this.fire('pinchstart', e, {
touches: touches,
distance: distance,
scale: 1
});
} else {
this.fire('pinch', e, {
touches: touches,
distance: distance,
scale: distance / this.startDistance
});
}
},
fireEnd: function(e) {
this.fire('pinchend', e);
},
fireCancel: function(e) {
this.fire('pinchcancel', e);
},
fail: function() {
return this.callParent(arguments);
},
reset: function() {
this.lastTouches = null;
this.startDistance = 0;
this.callParent();
}
}, function(Pinch) {
var gestures = Ext.manifest.gestures;
Pinch.instance = new Pinch(gestures && gestures.pinch);
});
Ext.define('Ext.event.gesture.Rotate', {
extend: 'Ext.event.gesture.MultiTouch',
priority: 700,
handledEvents: [
'rotatestart',
'rotate',
'rotateend',
'rotatecancel'
],
startAngle: 0,
lastTouches: null,
lastAngle: null,
onTouchMove: function(e) {
if (!this.isTracking) {
return;
}
var touches = e.touches,
lastAngle = this.lastAngle,
firstPoint, secondPoint, angle, nextAngle, previousAngle, diff;
firstPoint = touches[0].point;
secondPoint = touches[1].point;
angle = firstPoint.getAngleTo(secondPoint);
if (lastAngle !== null) {
diff = Math.abs(lastAngle - angle);
nextAngle = angle + 360;
previousAngle = angle - 360;
if (Math.abs(nextAngle - lastAngle) < diff) {
angle = nextAngle;
} else if (Math.abs(previousAngle - lastAngle) < diff) {
angle = previousAngle;
}
}
this.lastAngle = angle;
if (!this.isStarted) {
this.isStarted = true;
this.startAngle = angle;
this.fire('rotatestart', e, {
touches: touches,
angle: angle,
rotation: 0
});
} else {
this.fire('rotate', e, {
touches: touches,
angle: angle,
rotation: angle - this.startAngle
});
}
this.lastTouches = Ext.Array.clone(touches);
},
fireEnd: function(e) {
this.lastAngle = null;
this.fire('rotateend', e);
},
fireCancel: function(e) {
this.lastAngle = null;
this.fire('rotatecancel', e);
},
reset: function() {
var me = this;
me.lastTouches = me.lastAngle = me.startAngle = null;
this.callParent();
}
}, function(Rotate) {
var gestures = Ext.manifest.gestures;
Rotate.instance = new Rotate(gestures && gestures.rotate);
});
Ext.define('Ext.event.gesture.Tap', {
extend: 'Ext.event.gesture.SingleTouch',
priority: 200,
handledEvents: [
'tap',
'tapcancel'
],
config: {
moveDistance: 8
},
onTouchStart: function(e) {
if (this.callParent([
e
]) === false) {
return false;
}
this.startPoint = e.changedTouches[0].point;
},
onTouchMove: function(e) {
var touch = e.changedTouches[0],
point = touch.point;
if (Math.abs(point.getDistanceTo(this.startPoint)) >= this.getMoveDistance()) {
this.fire('tapcancel', e, {
touch: touch
});
return this.fail(this.self.TOUCH_MOVED);
}
},
onTouchEnd: function(e) {
this.fire('tap', e, {
touch: e.changedTouches[0]
});
},
onTouchCancel: function(e) {
this.fire('tapcancel', e, {
touch: e.changedTouches[0]
});
return false;
},
reset: function() {
this.startPoint = null;
}
}, function(Tap) {
var gestures = Ext.manifest.gestures;
Tap.instance = new Tap(gestures && gestures.tap);
});
Ext.define('Ext.fx.State', {
isAnimatable: {
'background-color': true,
'background-image': true,
'background-position': true,
'border-bottom-color': true,
'border-bottom-width': true,
'border-color': true,
'border-left-color': true,
'border-left-width': true,
'border-right-color': true,
'border-right-width': true,
'border-spacing': true,
'border-top-color': true,
'border-top-width': true,
'border-width': true,
'bottom': true,
'color': true,
'crop': true,
'font-size': true,
'font-weight': true,
'height': true,
'left': true,
'letter-spacing': true,
'line-height': true,
'margin-bottom': true,
'margin-left': true,
'margin-right': true,
'margin-top': true,
'max-height': true,
'max-width': true,
'min-height': true,
'min-width': true,
'opacity': true,
'outline-color': true,
'outline-offset': true,
'outline-width': true,
'padding-bottom': true,
'padding-left': true,
'padding-right': true,
'padding-top': true,
'right': true,
'text-indent': true,
'text-shadow': true,
'top': true,
'vertical-align': true,
'visibility': true,
'width': true,
'word-spacing': true,
'z-index': true,
'zoom': true,
'transform': true
},
constructor: function(data) {
this.data = {};
this.set(data);
},
setConfig: function(data) {
this.set(data);
return this;
},
setRaw: function(data) {
this.data = data;
return this;
},
clear: function() {
return this.setRaw({});
},
setTransform: function(name, value) {
var data = this.data,
isArray = Ext.isArray(value),
transform = data.transform,
ln, key;
if (!transform) {
transform = data.transform = {
translateX: 0,
translateY: 0,
translateZ: 0,
scaleX: 1,
scaleY: 1,
scaleZ: 1,
rotate: 0,
rotateX: 0,
rotateY: 0,
rotateZ: 0,
skewX: 0,
skewY: 0
};
}
if (typeof name == 'string') {
switch (name) {
case 'translate':
if (isArray) {
ln = value.length;
if (ln == 0) {
break;
}
transform.translateX = value[0];
if (ln == 1) {
break;
}
transform.translateY = value[1];
if (ln == 2) {
break;
}
transform.translateZ = value[2];
} else {
transform.translateX = value;
};
break;
case 'rotate':
if (isArray) {
ln = value.length;
if (ln == 0) {
break;
}
transform.rotateX = value[0];
if (ln == 1) {
break;
}
transform.rotateY = value[1];
if (ln == 2) {
break;
}
transform.rotateZ = value[2];
} else {
transform.rotate = value;
};
break;
case 'scale':
if (isArray) {
ln = value.length;
if (ln == 0) {
break;
}
transform.scaleX = value[0];
if (ln == 1) {
break;
}
transform.scaleY = value[1];
if (ln == 2) {
break;
}
transform.scaleZ = value[2];
} else {
transform.scaleX = value;
transform.scaleY = value;
};
break;
case 'skew':
if (isArray) {
ln = value.length;
if (ln == 0) {
break;
}
transform.skewX = value[0];
if (ln == 1) {
break;
}
transform.skewY = value[1];
} else {
transform.skewX = value;
};
break;
default:
transform[name] = value;
}
} else {
for (key in name) {
if (name.hasOwnProperty(key)) {
value = name[key];
this.setTransform(key, value);
}
}
}
},
set: function(name, value) {
var data = this.data,
key;
if (typeof name != 'string') {
for (key in name) {
value = name[key];
if (key === 'transform') {
this.setTransform(value);
} else {
data[key] = value;
}
}
} else {
if (name === 'transform') {
this.setTransform(value);
} else {
data[name] = value;
}
}
return this;
},
unset: function(name) {
var data = this.data;
if (data.hasOwnProperty(name)) {
delete data[name];
}
return this;
},
getData: function() {
return this.data;
}
});
Ext.define('Ext.fx.animation.Abstract', {
extend: 'Ext.Evented',
isAnimation: true,
requires: [
'Ext.fx.State'
],
config: {
name: '',
element: null,
before: null,
from: {},
to: {},
after: null,
states: {},
duration: 300,
easing: 'linear',
iteration: 1,
direction: 'normal',
delay: 0,
onBeforeStart: null,
onEnd: null,
onBeforeEnd: null,
scope: null,
reverse: null,
preserveEndState: false,
replacePrevious: true
},
STATE_FROM: '0%',
STATE_TO: '100%',
DIRECTION_UP: 'up',
DIRECTION_DOWN: 'down',
DIRECTION_LEFT: 'left',
DIRECTION_RIGHT: 'right',
stateNameRegex: /^(?:[\d\.]+)%$/,
constructor: function() {
this.states = {};
this.callParent(arguments);
return this;
},
applyElement: function(element) {
return Ext.get(element);
},
applyBefore: function(before, current) {
if (before) {
return Ext.factory(before, Ext.fx.State, current);
}
},
applyAfter: function(after, current) {
if (after) {
return Ext.factory(after, Ext.fx.State, current);
}
},
setFrom: function(from) {
return this.setState(this.STATE_FROM, from);
},
setTo: function(to) {
return this.setState(this.STATE_TO, to);
},
getFrom: function() {
return this.getState(this.STATE_FROM);
},
getTo: function() {
return this.getState(this.STATE_TO);
},
setStates: function(states) {
var validNameRegex = this.stateNameRegex,
name;
for (name in states) {
if (validNameRegex.test(name)) {
this.setState(name, states[name]);
}
}
return this;
},
getStates: function() {
return this.states;
},
end: function() {
this.stop();
},
stop: function() {
this.fireEvent('stop', this);
},
destroy: function() {
this.stop();
this.callParent();
},
setState: function(name, state) {
var states = this.getStates(),
stateInstance;
stateInstance = Ext.factory(state, Ext.fx.State, states[name]);
if (stateInstance) {
states[name] = stateInstance;
} else if (name === this.STATE_TO) {
Ext.Logger.error("Setting and invalid '100%' / 'to' state of: " + state);
}
return this;
},
getState: function(name) {
return this.getStates()[name];
},
getData: function() {
var states = this.getStates(),
statesData = {},
before = this.getBefore(),
after = this.getAfter(),
from = states[this.STATE_FROM],
to = states[this.STATE_TO],
fromData = from.getData(),
toData = to.getData(),
data, name, state;
for (name in states) {
if (states.hasOwnProperty(name)) {
state = states[name];
data = state.getData();
statesData[name] = data;
}
}
if (Ext.browser.is.AndroidStock2) {
statesData['0.0001%'] = fromData;
}
return {
before: before ? before.getData() : {},
after: after ? after.getData() : {},
states: statesData,
from: fromData,
to: toData,
duration: this.getDuration(),
iteration: this.getIteration(),
direction: this.getDirection(),
easing: this.getEasing(),
delay: this.getDelay(),
onEnd: this.getOnEnd(),
onBeforeEnd: this.getOnBeforeEnd(),
onBeforeStart: this.getOnBeforeStart(),
scope: this.getScope(),
preserveEndState: this.getPreserveEndState(),
replacePrevious: this.getReplacePrevious()
};
}
});
Ext.define('Ext.fx.animation.Slide', {
extend: 'Ext.fx.animation.Abstract',
alternateClassName: 'Ext.fx.animation.SlideIn',
alias: [
'animation.slide',
'animation.slideIn'
],
config: {
direction: 'left',
out: false,
offset: 0,
easing: 'auto',
containerBox: 'auto',
elementBox: 'auto',
isElementBoxFit: true,
useCssTransform: true
},
reverseDirectionMap: {
up: 'down',
down: 'up',
left: 'right',
right: 'left'
},
applyEasing: function(easing) {
if (easing === 'auto') {
return 'ease-' + ((this.getOut()) ? 'in' : 'out');
}
return easing;
},
getContainerBox: function() {
var box = this._containerBox;
if (box === 'auto') {
box = this.getElement().getParent().getBox();
}
return box;
},
getElementBox: function() {
var box = this._elementBox;
if (this.getIsElementBoxFit()) {
return this.getContainerBox();
}
if (box === 'auto') {
box = this.getElement().getBox();
}
return box;
},
getData: function() {
var elementBox = this.getElementBox(),
containerBox = this.getContainerBox(),
box = elementBox ? elementBox : containerBox,
from = this.getFrom(),
to = this.getTo(),
out = this.getOut(),
offset = this.getOffset(),
direction = this.getDirection(),
useCssTransform = this.getUseCssTransform(),
reverse = this.getReverse(),
translateX = 0,
translateY = 0,
fromX, fromY, toX, toY;
if (reverse) {
direction = this.reverseDirectionMap[direction];
}
switch (direction) {
case this.DIRECTION_UP:
if (out) {
translateY = containerBox.top - box.top - box.height - offset;
} else {
translateY = containerBox.bottom - box.bottom + box.height + offset;
};
break;
case this.DIRECTION_DOWN:
if (out) {
translateY = containerBox.bottom - box.bottom + box.height + offset;
} else {
translateY = containerBox.top - box.height - box.top - offset;
};
break;
case this.DIRECTION_RIGHT:
if (out) {
translateX = containerBox.right - box.right + box.width + offset;
} else {
translateX = containerBox.left - box.left - box.width - offset;
};
break;
case this.DIRECTION_LEFT:
if (out) {
translateX = containerBox.left - box.left - box.width - offset;
} else {
translateX = containerBox.right - box.right + box.width + offset;
};
break;
}
fromX = (out) ? 0 : translateX;
fromY = (out) ? 0 : translateY;
if (useCssTransform) {
from.setTransform({
translateX: fromX,
translateY: fromY
});
} else {
from.set('left', fromX);
from.set('top', fromY);
}
toX = (out) ? translateX : 0;
toY = (out) ? translateY : 0;
if (useCssTransform) {
to.setTransform({
translateX: toX,
translateY: toY
});
} else {
to.set('left', toX);
to.set('top', toY);
}
return this.callParent(arguments);
}
});
Ext.define('Ext.fx.animation.SlideOut', {
extend: 'Ext.fx.animation.Slide',
alias: [
'animation.slideOut'
],
config: {
out: true
}
});
Ext.define('Ext.fx.animation.Fade', {
extend: 'Ext.fx.animation.Abstract',
alternateClassName: 'Ext.fx.animation.FadeIn',
alias: [
'animation.fade',
'animation.fadeIn'
],
config: {
out: false,
before: {
display: null,
opacity: 0
},
after: {
opacity: null
},
reverse: null
},
updateOut: function(newOut) {
var to = this.getTo(),
from = this.getFrom();
if (newOut) {
from.set('opacity', 1);
to.set('opacity', 0);
} else {
from.set('opacity', 0);
to.set('opacity', 1);
}
}
});
Ext.define('Ext.fx.animation.FadeOut', {
extend: 'Ext.fx.animation.Fade',
alias: 'animation.fadeOut',
config: {
out: true,
before: {}
}
});
Ext.define('Ext.fx.animation.Flip', {
extend: 'Ext.fx.animation.Abstract',
alias: 'animation.flip',
config: {
easing: 'ease-in',
direction: 'right',
half: false,
out: null
},
getData: function() {
var from = this.getFrom(),
to = this.getTo(),
direction = this.getDirection(),
out = this.getOut(),
half = this.getHalf(),
rotate = (half) ? 90 : 180,
fromScale = 1,
toScale = 1,
fromRotateX = 0,
fromRotateY = 0,
toRotateX = 0,
toRotateY = 0;
if (out) {
toScale = 0.8;
} else {
fromScale = 0.8;
}
switch (direction) {
case this.DIRECTION_UP:
if (out) {
toRotateX = rotate;
} else {
fromRotateX = -rotate;
};
break;
case this.DIRECTION_DOWN:
if (out) {
toRotateX = -rotate;
} else {
fromRotateX = rotate;
};
break;
case this.DIRECTION_RIGHT:
if (out) {
toRotateY = rotate;
} else {
fromRotateY = -rotate;
};
break;
case this.DIRECTION_LEFT:
if (out) {
toRotateY = -rotate;
} else {
fromRotateY = rotate;
};
break;
}
from.setTransform({
rotateX: fromRotateX,
rotateY: fromRotateY,
scale: fromScale
});
to.setTransform({
rotateX: toRotateX,
rotateY: toRotateY,
scale: toScale
});
return this.callParent(arguments);
}
});
Ext.define('Ext.fx.animation.Pop', {
extend: 'Ext.fx.animation.Abstract',
alias: [
'animation.pop',
'animation.popIn'
],
alternateClassName: 'Ext.fx.animation.PopIn',
config: {
out: false,
before: {
display: null,
opacity: 0
},
after: {
opacity: null
}
},
getData: function() {
var to = this.getTo(),
from = this.getFrom(),
out = this.getOut();
if (out) {
from.set('opacity', 1);
from.setTransform({
scale: 1
});
to.set('opacity', 0);
to.setTransform({
scale: 0
});
} else {
from.set('opacity', 0);
from.setTransform({
scale: 0
});
to.set('opacity', 1);
to.setTransform({
scale: 1
});
}
return this.callParent(arguments);
}
});
Ext.define('Ext.fx.animation.PopOut', {
extend: 'Ext.fx.animation.Pop',
alias: 'animation.popOut',
config: {
out: true,
before: {}
}
});
Ext.define('Ext.fx.Animation', {
requires: [
'Ext.fx.animation.Slide',
'Ext.fx.animation.SlideOut',
'Ext.fx.animation.Fade',
'Ext.fx.animation.FadeOut',
'Ext.fx.animation.Flip',
'Ext.fx.animation.Pop',
'Ext.fx.animation.PopOut'
],
constructor: function(config) {
var defaultClass = Ext.fx.animation.Abstract,
type;
if (typeof config == 'string') {
type = config;
config = {};
} else if (config && config.type) {
type = config.type;
}
if (type) {
if (Ext.browser.is.AndroidStock2) {
if (type == 'pop') {
type = 'fade';
}
if (type == 'popIn') {
type = 'fadeIn';
}
if (type == 'popOut') {
type = 'fadeOut';
}
}
defaultClass = Ext.ClassManager.getByAlias('animation.' + type);
if (!defaultClass) {
Ext.Logger.error("Invalid animation type of: '" + type + "'");
}
}
return Ext.factory(config, defaultClass);
}
});
Ext.define('Ext.fx.runner.Css', {
extend: 'Ext.Evented',
requires: [
'Ext.fx.Animation'
],
prefixedProperties: {
'transform': true,
'transform-origin': true,
'perspective': true,
'transform-style': true,
'transition': true,
'transition-property': true,
'transition-duration': true,
'transition-timing-function': true,
'transition-delay': true,
'animation': true,
'animation-name': true,
'animation-duration': true,
'animation-iteration-count': true,
'animation-direction': true,
'animation-timing-function': true,
'animation-delay': true
},
lengthProperties: {
'top': true,
'right': true,
'bottom': true,
'left': true,
'width': true,
'height': true,
'max-height': true,
'max-width': true,
'min-height': true,
'min-width': true,
'margin-bottom': true,
'margin-left': true,
'margin-right': true,
'margin-top': true,
'padding-bottom': true,
'padding-left': true,
'padding-right': true,
'padding-top': true,
'border-bottom-width': true,
'border-left-width': true,
'border-right-width': true,
'border-spacing': true,
'border-top-width': true,
'border-width': true,
'outline-width': true,
'letter-spacing': true,
'line-height': true,
'text-indent': true,
'word-spacing': true,
'font-size': true,
'translate': true,
'translateX': true,
'translateY': true,
'translateZ': true,
'translate3d': true
},
durationProperties: {
'transition-duration': true,
'transition-delay': true,
'animation-duration': true,
'animation-delay': true
},
angleProperties: {
rotate: true,
rotateX: true,
rotateY: true,
rotateZ: true,
skew: true,
skewX: true,
skewY: true
},
lengthUnitRegex: /([a-z%]*)$/,
DEFAULT_UNIT_LENGTH: 'px',
DEFAULT_UNIT_ANGLE: 'deg',
DEFAULT_UNIT_DURATION: 'ms',
formattedNameCache: {},
constructor: function() {
var supports3dTransform = Ext.feature.has.Css3dTransforms;
if (supports3dTransform) {
this.transformMethods = [
'translateX',
'translateY',
'translateZ',
'rotate',
'rotateX',
'rotateY',
'rotateZ',
'skewX',
'skewY',
'scaleX',
'scaleY',
'scaleZ'
];
} else {
this.transformMethods = [
'translateX',
'translateY',
'rotate',
'skewX',
'skewY',
'scaleX',
'scaleY'
];
}
this.vendorPrefix = Ext.browser.getStyleDashPrefix();
this.ruleStylesCache = {};
this.callParent();
},
getStyleSheet: function() {
var styleSheet = this.styleSheet,
styleElement, styleSheets;
if (!styleSheet) {
styleElement = document.createElement('style');
styleElement.type = 'text/css';
(document.head || document.getElementsByTagName('head')[0]).appendChild(styleElement);
styleSheets = document.styleSheets;
this.styleSheet = styleSheet = styleSheets[styleSheets.length - 1];
}
return styleSheet;
},
applyRules: function(selectors) {
var styleSheet = this.getStyleSheet(),
ruleStylesCache = this.ruleStylesCache,
rules = styleSheet.cssRules,
selector, properties, ruleStyle, ruleStyleCache, rulesLength, name, value;
for (selector in selectors) {
properties = selectors[selector];
ruleStyle = ruleStylesCache[selector];
if (ruleStyle === undefined) {
rulesLength = rules.length;
styleSheet.insertRule(selector + '{}', rulesLength);
ruleStyle = ruleStylesCache[selector] = rules.item(rulesLength).style;
}
ruleStyleCache = ruleStyle.$cache;
if (!ruleStyleCache) {
ruleStyleCache = ruleStyle.$cache = {};
}
for (name in properties) {
value = this.formatValue(properties[name], name);
name = this.formatName(name);
if (ruleStyleCache[name] !== value) {
ruleStyleCache[name] = value;
if (value === null) {
ruleStyle.removeProperty(name);
} else {
ruleStyle.setProperty(name, value, 'important');
}
}
}
}
return this;
},
applyStyles: function(styles) {
var id, element, elementStyle, properties, name, value;
for (id in styles) {
if (styles.hasOwnProperty(id)) {
element = document.getElementById(id);
if (!element) {
return this;
}
elementStyle = element.style;
properties = styles[id];
for (name in properties) {
if (properties.hasOwnProperty(name)) {
value = this.formatValue(properties[name], name);
name = this.formatName(name);
if (value === null) {
elementStyle.removeProperty(name);
} else {
elementStyle.setProperty(name, value, 'important');
}
}
}
}
}
return this;
},
formatName: function(name) {
var cache = this.formattedNameCache,
formattedName = cache[name];
if (!formattedName) {
if ((Ext.os.is.Tizen || !Ext.feature.has.CssTransformNoPrefix) && this.prefixedProperties[name]) {
formattedName = this.vendorPrefix + name;
} else {
formattedName = name;
}
cache[name] = formattedName;
}
return formattedName;
},
formatValue: function(value, name) {
var type = typeof value,
lengthUnit = this.DEFAULT_UNIT_LENGTH,
transformMethods, method, i, ln, transformValues, values, unit;
if (value === null) {
return '';
}
if (type == 'string') {
if (this.lengthProperties[name]) {
unit = value.match(this.lengthUnitRegex)[1];
if (unit.length > 0) {
if (unit !== lengthUnit) {
Ext.Logger.error("Length unit: '" + unit + "' in value: '" + value + "' of property: '" + name + "' is not " + "valid for animation. Only 'px' is allowed");
}
} else {
return value + lengthUnit;
}
}
return value;
} else if (type == 'number') {
if (value == 0) {
return '0';
}
if (this.lengthProperties[name]) {
return value + lengthUnit;
}
if (this.angleProperties[name]) {
return value + this.DEFAULT_UNIT_ANGLE;
}
if (this.durationProperties[name]) {
return value + this.DEFAULT_UNIT_DURATION;
}
} else if (name === 'transform') {
transformMethods = this.transformMethods;
transformValues = [];
for (i = 0 , ln = transformMethods.length; i < ln; i++) {
method = transformMethods[i];
transformValues.push(method + '(' + this.formatValue(value[method], method) + ')');
}
return transformValues.join(' ');
} else if (Ext.isArray(value)) {
values = [];
for (i = 0 , ln = value.length; i < ln; i++) {
values.push(this.formatValue(value[i], name));
}
return (values.length > 0) ? values.join(', ') : 'none';
}
return value;
}
});
Ext.define('Ext.fx.runner.CssTransition', {
extend: 'Ext.fx.runner.Css',
requires: [
'Ext.AnimationQueue'
],
alternateClassName: 'Ext.Animator',
singleton: true,
listenersAttached: false,
constructor: function() {
this.runningAnimationsData = {};
return this.callParent(arguments);
},
attachListeners: function() {
this.listenersAttached = true;
Ext.getWin().on('transitionend', 'onTransitionEnd', this);
},
onTransitionEnd: function(e) {
var target = e.target,
id = target.id;
if (id && this.runningAnimationsData.hasOwnProperty(id)) {
this.refreshRunningAnimationsData(Ext.get(target), [
e.browserEvent.propertyName
]);
}
},
onAnimationEnd: function(element, data, animation, isInterrupted, isReplaced) {
var id = element.getId(),
runningData = this.runningAnimationsData[id],
endRules = {},
endData = {},
runningNameMap, toPropertyNames, i, ln, name;
animation.un('stop', 'onAnimationStop', this);
if (runningData) {
runningNameMap = runningData.nameMap;
}
endRules[id] = endData;
if (data.onBeforeEnd) {
data.onBeforeEnd.call(data.scope || this, element, isInterrupted);
}
animation.fireEvent('animationbeforeend', animation, element, isInterrupted);
this.fireEvent('animationbeforeend', this, animation, element, isInterrupted);
if (isReplaced || (!isInterrupted && !data.preserveEndState)) {
toPropertyNames = data.toPropertyNames;
for (i = 0 , ln = toPropertyNames.length; i < ln; i++) {
name = toPropertyNames[i];
if (runningNameMap && !runningNameMap.hasOwnProperty(name)) {
endData[name] = null;
}
}
}
if (data.after) {
Ext.merge(endData, data.after);
}
this.applyStyles(endRules);
if (data.onEnd) {
data.onEnd.call(data.scope || this, element, isInterrupted);
}
animation.fireEvent('animationend', animation, element, isInterrupted);
this.fireEvent('animationend', this, animation, element, isInterrupted);
Ext.AnimationQueue.stop(Ext.emptyFn, animation);
},
onAllAnimationsEnd: function(element) {
var id = element.getId(),
endRules = {};
delete this.runningAnimationsData[id];
endRules[id] = {
'transition-property': null,
'transition-duration': null,
'transition-timing-function': null,
'transition-delay': null
};
this.applyStyles(endRules);
this.fireEvent('animationallend', this, element);
},
hasRunningAnimations: function(element) {
var id = element.getId(),
runningAnimationsData = this.runningAnimationsData;
return runningAnimationsData.hasOwnProperty(id) && runningAnimationsData[id].sessions.length > 0;
},
refreshRunningAnimationsData: function(element, propertyNames, interrupt, replace) {
var id = element.getId(),
runningAnimationsData = this.runningAnimationsData,
runningData = runningAnimationsData[id];
if (!runningData) {
return;
}
var nameMap = runningData.nameMap,
nameList = runningData.nameList,
sessions = runningData.sessions,
ln, j, subLn, name, i, session, map, list,
hasCompletedSession = false;
interrupt = Boolean(interrupt);
replace = Boolean(replace);
if (!sessions) {
return this;
}
ln = sessions.length;
if (ln === 0) {
return this;
}
if (replace) {
runningData.nameMap = {};
nameList.length = 0;
for (i = 0; i < ln; i++) {
session = sessions[i];
this.onAnimationEnd(element, session.data, session.animation, interrupt, replace);
}
sessions.length = 0;
} else {
for (i = 0; i < ln; i++) {
session = sessions[i];
map = session.map;
list = session.list;
for (j = 0 , subLn = propertyNames.length; j < subLn; j++) {
name = propertyNames[j];
if (map[name]) {
delete map[name];
Ext.Array.remove(list, name);
session.length--;
if (--nameMap[name] == 0) {
delete nameMap[name];
Ext.Array.remove(nameList, name);
}
}
}
if (session.length == 0) {
sessions.splice(i, 1);
i--;
ln--;
hasCompletedSession = true;
this.onAnimationEnd(element, session.data, session.animation, interrupt);
}
}
}
if (!replace && !interrupt && sessions.length == 0 && hasCompletedSession) {
this.onAllAnimationsEnd(element);
}
},
getRunningData: function(id) {
var runningAnimationsData = this.runningAnimationsData;
if (!runningAnimationsData.hasOwnProperty(id)) {
runningAnimationsData[id] = {
nameMap: {},
nameList: [],
sessions: []
};
}
return runningAnimationsData[id];
},
getTestElement: function() {
var testElement = this.testElement,
iframe, iframeDocument, iframeStyle;
if (!testElement) {
iframe = document.createElement('iframe');
iframe.setAttribute('tabindex', -1);
iframeStyle = iframe.style;
iframeStyle.setProperty('visibility', 'hidden', 'important');
iframeStyle.setProperty('width', '0px', 'important');
iframeStyle.setProperty('height', '0px', 'important');
iframeStyle.setProperty('position', 'absolute', 'important');
iframeStyle.setProperty('border', '0px', 'important');
iframeStyle.setProperty('zIndex', '-1000', 'important');
document.body.appendChild(iframe);
iframeDocument = iframe.contentDocument;
iframeDocument.open();
iframeDocument.writeln('</body>');
iframeDocument.close();
this.testElement = testElement = iframeDocument.createElement('div');
testElement.style.setProperty('position', 'absolute', 'important');
iframeDocument.body.appendChild(testElement);
this.testElementComputedStyle = window.getComputedStyle(testElement);
}
return testElement;
},
getCssStyleValue: function(name, value) {
var testElement = this.getTestElement(),
computedStyle = this.testElementComputedStyle,
style = testElement.style;
style.setProperty(name, value);
if (Ext.browser.is.Firefox) {
testElement.offsetHeight;
}
value = computedStyle.getPropertyValue(name);
style.removeProperty(name);
return value;
},
run: function(animations) {
var me = this,
isLengthPropertyMap = this.lengthProperties,
fromData = {},
toData = {},
data = {},
element, elementId, from, to, before, fromPropertyNames, toPropertyNames, doApplyTo, message, runningData, elementData, i, j, ln, animation, propertiesLength, sessionNameMap, computedStyle, formattedName, name, toFormattedValue, computedValue, fromFormattedValue, isLengthProperty, runningNameMap, runningNameList, runningSessions, runningSession;
if (!this.listenersAttached) {
this.attachListeners();
}
animations = Ext.Array.from(animations);
for (i = 0 , ln = animations.length; i < ln; i++) {
animation = animations[i];
animation = Ext.factory(animation, Ext.fx.Animation);
element = animation.getElement();
Ext.AnimationQueue.start(Ext.emptyFn, animation);
computedStyle = window.getComputedStyle(element.dom);
elementId = element.getId();
data = Ext.merge({}, animation.getData());
if (animation.onBeforeStart) {
animation.onBeforeStart.call(animation.scope || this, element);
}
animation.fireEvent('animationstart', animation);
this.fireEvent('animationstart', this, animation);
data[elementId] = data;
before = data.before;
from = data.from;
to = data.to;
data.fromPropertyNames = fromPropertyNames = [];
data.toPropertyNames = toPropertyNames = [];
for (name in to) {
if (to.hasOwnProperty(name)) {
to[name] = toFormattedValue = this.formatValue(to[name], name);
formattedName = this.formatName(name);
isLengthProperty = isLengthPropertyMap.hasOwnProperty(name);
if (!isLengthProperty) {
toFormattedValue = this.getCssStyleValue(formattedName, toFormattedValue);
}
if (from.hasOwnProperty(name)) {
from[name] = fromFormattedValue = this.formatValue(from[name], name);
if (!isLengthProperty) {
fromFormattedValue = this.getCssStyleValue(formattedName, fromFormattedValue);
}
if (toFormattedValue !== fromFormattedValue) {
fromPropertyNames.push(formattedName);
toPropertyNames.push(formattedName);
}
} else {
computedValue = computedStyle.getPropertyValue(formattedName);
if (toFormattedValue !== computedValue) {
toPropertyNames.push(formattedName);
}
}
}
}
propertiesLength = toPropertyNames.length;
if (propertiesLength === 0) {
this.onAnimationEnd(element, data, animation);
continue;
}
runningData = this.getRunningData(elementId);
runningSessions = runningData.sessions;
if (runningSessions.length > 0) {
this.refreshRunningAnimationsData(element, Ext.Array.merge(fromPropertyNames, toPropertyNames), true, data.replacePrevious);
}
runningNameMap = runningData.nameMap;
runningNameList = runningData.nameList;
sessionNameMap = {};
for (j = 0; j < propertiesLength; j++) {
name = toPropertyNames[j];
sessionNameMap[name] = true;
if (!runningNameMap.hasOwnProperty(name)) {
runningNameMap[name] = 1;
runningNameList.push(name);
} else {
runningNameMap[name]++;
}
}
runningSession = {
element: element,
map: sessionNameMap,
list: toPropertyNames.slice(),
length: propertiesLength,
data: data,
animation: animation
};
runningSessions.push(runningSession);
animation.on('stop', 'onAnimationStop', this);
elementData = Ext.apply({}, before);
Ext.apply(elementData, from);
if (runningNameList.length > 0) {
fromPropertyNames = Ext.Array.difference(runningNameList, fromPropertyNames);
toPropertyNames = Ext.Array.merge(fromPropertyNames, toPropertyNames);
elementData['transition-property'] = fromPropertyNames;
}
fromData[elementId] = elementData;
toData[elementId] = Ext.apply({}, to);
toData[elementId]['transition-property'] = toPropertyNames;
toData[elementId]['transition-duration'] = data.duration;
toData[elementId]['transition-timing-function'] = data.easing;
toData[elementId]['transition-delay'] = data.delay;
animation.startTime = Date.now();
}
message = this.$className;
this.applyStyles(fromData);
doApplyTo = function(e) {
if (e.data === message && e.source === window) {
window.removeEventListener('message', doApplyTo, false);
me.applyStyles(toData);
}
};
if (Ext.browser.is.IE) {
Ext.Function.requestAnimationFrame(function() {
window.addEventListener('message', doApplyTo, false);
window.postMessage(message, '*');
});
} else {
window.addEventListener('message', doApplyTo, false);
window.postMessage(message, '*');
}
},
onAnimationStop: function(animation) {
var runningAnimationsData = this.runningAnimationsData,
id, runningData, sessions, i, ln, session;
for (id in runningAnimationsData) {
if (runningAnimationsData.hasOwnProperty(id)) {
runningData = runningAnimationsData[id];
sessions = runningData.sessions;
for (i = 0 , ln = sessions.length; i < ln; i++) {
session = sessions[i];
if (session.animation === animation) {
this.refreshRunningAnimationsData(session.element, session.list.slice(), false);
}
}
}
}
}
});
Ext.define('Ext.fx.Runner', {
requires: [
'Ext.fx.runner.CssTransition'
],
constructor: function() {
return new Ext.fx.runner.CssTransition();
}
});
Ext.define('Ext.fx.animation.Cube', {
extend: 'Ext.fx.animation.Abstract',
alias: 'animation.cube',
config: {
before: {},
after: {},
direction: 'right',
out: false
},
getData: function() {
var to = this.getTo(),
from = this.getFrom(),
before = this.getBefore(),
after = this.getAfter(),
out = this.getOut(),
direction = this.getDirection(),
el = this.getElement(),
elW = el.getWidth(),
elH = el.getHeight(),
origin = out ? '100% 100%' : '0% 0%',
fromOpacity = 1,
toOpacity = 1,
transformFrom = {
rotateY: 0,
translateZ: 0
},
transformTo = {
rotateY: 0,
translateZ: 0
};
if (direction == "left" || direction == "right") {
if (out) {
toOpacity = 0.5;
transformTo.translateZ = elW;
transformTo.rotateY = -90;
} else {
fromOpacity = 0.5;
transformFrom.translateZ = elW;
transformFrom.rotateY = 90;
}
}
before['transform-origin'] = origin;
after['transform-origin'] = null;
to.set('transform', transformTo);
from.set('transform', transformFrom);
from.set('opacity', fromOpacity);
to.set('opacity', toOpacity);
return this.callParent(arguments);
}
});
Ext.define('Ext.fx.animation.Wipe', {
extend: 'Ext.fx.Animation',
alternateClassName: 'Ext.fx.animation.WipeIn',
config: {
easing: 'ease-out',
direction: 'right',
out: false
},
refresh: function() {
var me = this,
el = me.getElement(),
elBox = el.dom.getBoundingClientRect(),
elWidth = elBox.width,
elHeight = elBox.height,
from = me.getFrom(),
to = me.getTo(),
out = me.getOut(),
direction = me.getDirection(),
maskFromX = 0,
maskFromY = 0,
maskToX = 0,
maskToY = 0,
mask, tmp;
switch (direction) {
case 'up':
if (out) {
mask = '-webkit-gradient(linear, left top, left bottom, from(#000), to(transparent), color-stop(33%, #000), color-stop(66%, transparent))';
maskFromY = elHeight * 3 + 'px';
maskToY = elHeight + 'px';
} else {
mask = '-webkit-gradient(linear, left top, left bottom, from(transparent), to(#000), color-stop(66%, #000), color-stop(33%, transparent))';
maskFromY = -elHeight * 2 + 'px';
maskToY = 0;
};
break;
case 'down':
if (out) {
mask = '-webkit-gradient(linear, left top, left bottom, from(transparent), to(#000), color-stop(66%, #000), color-stop(33%, transparent))';
maskFromY = -elHeight * 2 + 'px';
maskToY = 0;
} else {
mask = '-webkit-gradient(linear, left top, left bottom, from(#000), to(transparent), color-stop(33%, #000), color-stop(66%, transparent))';
maskFromY = elHeight * 3 + 'px';
maskToY = elHeight + 'px';
};
break;
case 'right':
if (out) {
mask = '-webkit-gradient(linear, right top, left top, from(#000), to(transparent), color-stop(33%, #000), color-stop(66%, transparent))';
maskFromX = -elWidth * 2 + 'px';
maskToX = 0;
} else {
mask = '-webkit-gradient(linear, right top, left top, from(transparent), to(#000), color-stop(66%, #000), color-stop(33%, transparent))';
maskToX = -elWidth * 2 + 'px';
};
break;
case 'left':
if (out) {
mask = '-webkit-gradient(linear, right top, left top, from(transparent), to(#000), color-stop(66%, #000), color-stop(33%, transparent))';
maskToX = -elWidth * 2 + 'px';
} else {
mask = '-webkit-gradient(linear, right top, left top, from(#000), to(transparent), color-stop(33%, #000), color-stop(66%, transparent))';
maskFromX = -elWidth * 2 + 'px';
maskToX = 0;
};
break;
}
if (!out) {
tmp = maskFromY;
maskFromY = maskToY;
maskToY = tmp;
tmp = maskFromX;
maskFromX = maskToX;
maskToX = tmp;
}
from.set('mask-image', mask);
from.set('mask-size', elWidth * 3 + 'px ' + elHeight * 3 + 'px');
from.set('mask-position-x', maskFromX);
from.set('mask-position-y', maskFromY);
to.set('mask-position-x', maskToX);
to.set('mask-position-y', maskToY);
}
});
Ext.define('Ext.fx.animation.WipeOut', {
extend: 'Ext.fx.animation.Wipe',
config: {
out: true
}
});
Ext.define('Ext.fx.easing.EaseIn', {
extend: 'Ext.fx.easing.Linear',
alias: 'easing.ease-in',
config: {
exponent: 4,
duration: 1500
},
getValue: function() {
var deltaTime = Ext.Date.now() - this.getStartTime(),
duration = this.getDuration(),
startValue = this.getStartValue(),
endValue = this.getEndValue(),
distance = this.distance,
theta = deltaTime / duration,
thetaEnd = Math.pow(theta, this.getExponent()),
currentValue = startValue + (thetaEnd * distance);
if (deltaTime >= duration) {
this.isEnded = true;
return endValue;
}
return currentValue;
}
});
Ext.define('Ext.fx.easing.Easing', {
requires: [
'Ext.fx.easing.Linear'
],
constructor: function(easing) {
return Ext.factory(easing, Ext.fx.easing.Linear, null, 'easing');
}
});
Ext.define('Ext.fx.layout.card.Abstract', {
extend: 'Ext.Evented',
isAnimation: true,
config: {
direction: 'left',
duration: null,
reverse: null,
layout: null
},
updateLayout: function() {
this.enable();
},
enable: function() {
var layout = this.getLayout();
if (layout) {
layout.onBefore('activeitemchange', 'onActiveItemChange', this);
}
},
disable: function() {
var layout = this.getLayout();
if (this.isAnimating) {
this.stopAnimation();
}
if (layout) {
layout.unBefore('activeitemchange', 'onActiveItemChange', this);
}
},
onActiveItemChange: Ext.emptyFn,
destroy: function() {
var layout = this.getLayout();
if (this.isAnimating) {
this.stopAnimation();
}
if (layout) {
layout.unBefore('activeitemchange', 'onActiveItemChange', this);
}
this.setLayout(null);
if (this.observableId) {
this.fireEvent('destroy', this);
this.clearListeners();
this.clearManagedListeners();
}
}
});
Ext.define('Ext.fx.layout.card.Style', {
extend: 'Ext.fx.layout.card.Abstract',
requires: [
'Ext.fx.Animation'
],
config: {
inAnimation: {
before: {
visibility: null
},
preserveEndState: false,
replacePrevious: true
},
outAnimation: {
preserveEndState: false,
replacePrevious: true
}
},
constructor: function(config) {
var inAnimation, outAnimation;
this.callParent([
config
]);
this.endAnimationCounter = 0;
inAnimation = this.getInAnimation();
outAnimation = this.getOutAnimation();
inAnimation.on('animationend', 'incrementEnd', this);
outAnimation.on('animationend', 'incrementEnd', this);
},
updateDirection: function(direction) {
this.getInAnimation().setDirection(direction);
this.getOutAnimation().setDirection(direction);
},
updateDuration: function(duration) {
this.getInAnimation().setDuration(duration);
this.getOutAnimation().setDuration(duration);
},
updateReverse: function(reverse) {
this.getInAnimation().setReverse(reverse);
this.getOutAnimation().setReverse(reverse);
},
incrementEnd: function() {
this.endAnimationCounter++;
if (this.endAnimationCounter > 1) {
this.endAnimationCounter = 0;
this.fireEvent('animationend', this);
}
},
applyInAnimation: function(animation, inAnimation) {
return Ext.factory(animation, Ext.fx.Animation, inAnimation);
},
applyOutAnimation: function(animation, outAnimation) {
return Ext.factory(animation, Ext.fx.Animation, outAnimation);
},
updateInAnimation: function(animation) {
animation.setScope(this);
},
updateOutAnimation: function(animation) {
animation.setScope(this);
},
onActiveItemChange: function(cardLayout, newItem, oldItem, options, controller) {
var inAnimation = this.getInAnimation(),
outAnimation = this.getOutAnimation(),
inElement, outElement;
if (newItem && oldItem && oldItem.isPainted()) {
inElement = newItem.renderElement;
outElement = oldItem.renderElement;
inAnimation.setElement(inElement);
outAnimation.setElement(outElement);
outAnimation.setOnBeforeEnd(function(element, interrupted) {
if (interrupted || Ext.Animator.hasRunningAnimations(element)) {
controller.firingArguments[1] = null;
controller.firingArguments[2] = null;
}
});
outAnimation.setOnEnd(function() {
controller.resume();
});
inElement.dom.style.setProperty('visibility', 'hidden', 'important');
newItem.show();
Ext.Animator.run([
outAnimation,
inAnimation
]);
controller.pause();
}
},
destroy: function() {
Ext.destroy(this.getInAnimation(), this.getOutAnimation());
this.callParent(arguments);
}
});
Ext.define('Ext.fx.layout.card.Slide', {
extend: 'Ext.fx.layout.card.Style',
alias: 'fx.layout.card.slide',
config: {
inAnimation: {
type: 'slide',
easing: 'ease-out'
},
outAnimation: {
type: 'slide',
easing: 'ease-out',
out: true
}
},
updateReverse: function(reverse) {
this.getInAnimation().setReverse(reverse);
this.getOutAnimation().setReverse(reverse);
}
});
Ext.define('Ext.fx.layout.card.Cover', {
extend: 'Ext.fx.layout.card.Style',
alias: 'fx.layout.card.cover',
config: {
reverse: null,
inAnimation: {
before: {
'z-index': 100
},
after: {
'z-index': 0
},
type: 'slide',
easing: 'ease-out'
},
outAnimation: {
easing: 'ease-out',
from: {
opacity: 0.99
},
to: {
opacity: 1
},
out: true
}
},
updateReverse: function(reverse) {
this.getInAnimation().setReverse(reverse);
this.getOutAnimation().setReverse(reverse);
}
});
Ext.define('Ext.fx.layout.card.Reveal', {
extend: 'Ext.fx.layout.card.Style',
alias: 'fx.layout.card.reveal',
config: {
inAnimation: {
easing: 'ease-out',
from: {
opacity: 0.99
},
to: {
opacity: 1
}
},
outAnimation: {
before: {
'z-index': 100
},
after: {
'z-index': 0
},
type: 'slide',
easing: 'ease-out',
out: true
}
},
updateReverse: function(reverse) {
this.getInAnimation().setReverse(reverse);
this.getOutAnimation().setReverse(reverse);
}
});
Ext.define('Ext.fx.layout.card.Fade', {
extend: 'Ext.fx.layout.card.Style',
alias: 'fx.layout.card.fade',
config: {
reverse: null,
inAnimation: {
type: 'fade',
easing: 'ease-out'
},
outAnimation: {
type: 'fade',
easing: 'ease-out',
out: true
}
}
});
Ext.define('Ext.fx.layout.card.Flip', {
extend: 'Ext.fx.layout.card.Style',
alias: 'fx.layout.card.flip',
config: {
duration: 500,
inAnimation: {
type: 'flip',
half: true,
easing: 'ease-out',
before: {
'backface-visibility': 'hidden'
},
after: {
'backface-visibility': null
}
},
outAnimation: {
type: 'flip',
half: true,
easing: 'ease-in',
before: {
'backface-visibility': 'hidden'
},
after: {
'backface-visibility': null
},
out: true
}
},
onActiveItemChange: function(cardLayout, newItem, oldItem, options, controller) {
var parent = newItem.element.getParent();
parent.addCls(Ext.baseCSSPrefix + 'layout-card-perspective');
this.on('animationend', function() {
parent.removeCls(Ext.baseCSSPrefix + 'layout-card-perspective');
}, this, {
single: true
});
this.callParent(arguments);
},
updateDuration: function(duration) {
var halfDuration = duration / 2,
inAnimation = this.getInAnimation(),
outAnimation = this.getOutAnimation();
inAnimation.setDelay(halfDuration);
inAnimation.setDuration(halfDuration);
outAnimation.setDuration(halfDuration);
}
});
Ext.define('Ext.fx.layout.card.Pop', {
extend: 'Ext.fx.layout.card.Style',
alias: 'fx.layout.card.pop',
config: {
duration: 500,
inAnimation: {
type: 'pop',
easing: 'ease-out'
},
outAnimation: {
type: 'pop',
easing: 'ease-in',
out: true
}
},
updateDuration: function(duration) {
var halfDuration = duration / 2,
inAnimation = this.getInAnimation(),
outAnimation = this.getOutAnimation();
inAnimation.setDelay(halfDuration);
inAnimation.setDuration(halfDuration);
outAnimation.setDuration(halfDuration);
}
});
Ext.define('Ext.fx.layout.card.Scroll', {
extend: 'Ext.fx.layout.card.Abstract',
requires: [
'Ext.fx.easing.Linear'
],
alias: 'fx.layout.card.scroll',
config: {
duration: 150
},
constructor: function(config) {
this.initConfig(config);
},
getEasing: function() {
var easing = this.easing;
if (!easing) {
this.easing = easing = new Ext.fx.easing.Linear();
}
return easing;
},
updateDuration: function(duration) {
this.getEasing().setDuration(duration);
},
onActiveItemChange: function(cardLayout, newItem, oldItem, options, controller) {
var direction = this.getDirection(),
easing = this.getEasing(),
containerElement, inElement, outElement, containerWidth, containerHeight, reverse;
if (newItem && oldItem) {
if (this.isAnimating) {
this.stopAnimation();
}
newItem.setWidth('100%');
newItem.setHeight('100%');
containerElement = this.getLayout().container.innerElement;
containerWidth = containerElement.getWidth();
containerHeight = containerElement.getHeight();
inElement = newItem.renderElement;
outElement = oldItem.renderElement;
this.oldItem = oldItem;
this.newItem = newItem;
this.currentEventController = controller;
this.containerElement = containerElement;
this.isReverse = reverse = this.getReverse();
newItem.show();
if (direction == 'right') {
direction = 'left';
this.isReverse = reverse = !reverse;
} else if (direction == 'down') {
direction = 'up';
this.isReverse = reverse = !reverse;
}
if (direction == 'left') {
if (reverse) {
easing.setConfig({
startValue: containerWidth,
endValue: 0
});
containerElement.dom.scrollLeft = containerWidth;
outElement.setLeft(containerWidth);
} else {
easing.setConfig({
startValue: 0,
endValue: containerWidth
});
inElement.setLeft(containerWidth);
}
} else {
if (reverse) {
easing.setConfig({
startValue: containerHeight,
endValue: 0
});
containerElement.dom.scrollTop = containerHeight;
outElement.setTop(containerHeight);
} else {
easing.setConfig({
startValue: 0,
endValue: containerHeight
});
inElement.setTop(containerHeight);
}
}
this.startAnimation();
controller.pause();
}
},
startAnimation: function() {
this.isAnimating = true;
this.getEasing().setStartTime(Date.now());
Ext.AnimationQueue.start(this.doAnimationFrame, this);
},
doAnimationFrame: function() {
var easing = this.getEasing(),
direction = this.getDirection(),
scroll = 'scrollTop',
value;
if (direction == 'left' || direction == 'right') {
scroll = 'scrollLeft';
}
if (easing.isEnded) {
this.stopAnimation();
} else {
value = easing.getValue();
this.containerElement.dom[scroll] = value;
}
},
stopAnimation: function() {
var me = this,
direction = me.getDirection(),
scroll = 'setTop',
oldItem = me.oldItem,
newItem = me.newItem;
if (direction == 'left' || direction == 'right') {
scroll = 'setLeft';
}
me.currentEventController.resume();
if (me.isReverse && oldItem && oldItem.renderElement && oldItem.renderElement.dom) {
oldItem.renderElement[scroll](null);
} else if (newItem && newItem.renderElement && newItem.renderElement.dom) {
newItem.renderElement[scroll](null);
}
Ext.AnimationQueue.stop(this.doAnimationFrame, this);
me.isAnimating = false;
me.fireEvent('animationend', me);
}
});
Ext.define('Ext.fx.layout.Card', {
requires: [
'Ext.fx.layout.card.Slide',
'Ext.fx.layout.card.Cover',
'Ext.fx.layout.card.Reveal',
'Ext.fx.layout.card.Fade',
'Ext.fx.layout.card.Flip',
'Ext.fx.layout.card.Pop',
'Ext.fx.layout.card.Scroll'
],
constructor: function(config) {
var defaultClass = Ext.fx.layout.card.Abstract,
type;
if (!config) {
return null;
}
if (typeof config == 'string') {
type = config;
config = {};
} else if (config.type) {
type = config.type;
}
config.elementBox = false;
if (type) {
if (Ext.browser.is.AndroidStock2) {
if (type != 'fade') {
type = 'scroll';
}
}
defaultClass = Ext.ClassManager.getByAlias('fx.layout.card.' + type);
if (!defaultClass) {
Ext.Logger.error("Unknown card animation type: '" + type + "'");
}
}
return Ext.factory(config, defaultClass);
}
});
Ext.define('Ext.fx.layout.card.Cube', {
extend: 'Ext.fx.layout.card.Style',
alias: 'fx.layout.card.cube',
config: {
reverse: null,
inAnimation: {
type: 'cube'
},
outAnimation: {
type: 'cube',
out: true
}
}
});
Ext.define('Ext.fx.layout.card.ScrollCover', {
extend: 'Ext.fx.layout.card.Scroll',
alias: 'fx.layout.card.scrollcover',
onActiveItemChange: function(cardLayout, inItem, outItem, options, controller) {
var containerElement, containerSize, xy, animConfig, inTranslate, outTranslate;
this.lastController = controller;
this.inItem = inItem;
if (inItem && outItem) {
containerElement = this.getLayout().container.innerElement;
containerSize = containerElement.getSize();
xy = this.calculateXY(containerSize);
animConfig = {
easing: this.getEasing(),
duration: this.getDuration()
};
inItem.renderElement.dom.style.setProperty('visibility', 'hidden', 'important');
inTranslate = inItem.setTranslatable(true).getTranslatable();
outTranslate = outItem.setTranslatable(true).getTranslatable();
outTranslate.translate({
x: 0,
y: 0
});
inTranslate.translate({
x: xy.left,
y: xy.top
});
inTranslate.getWrapper().dom.style.setProperty('z-index', '100', 'important');
inItem.show();
inTranslate.on({
animationstart: 'onInAnimationStart',
animationend: 'onInAnimationEnd',
scope: this
});
inTranslate.translateAnimated({
x: 0,
y: 0
}, animConfig);
controller.pause();
}
},
onInAnimationStart: function() {
this.inItem.renderElement.dom.style.removeProperty('visibility');
},
onInAnimationEnd: function() {
this.inItem.getTranslatable().getWrapper().dom.style.removeProperty('z-index');
this.lastController.resume();
}
});
Ext.define('Ext.fx.layout.card.ScrollReveal', {
extend: 'Ext.fx.layout.card.Scroll',
alias: 'fx.layout.card.scrollreveal',
onActiveItemChange: function(cardLayout, inItem, outItem, options, controller) {
var containerElement, containerSize, xy, animConfig, outTranslate, inTranslate;
this.lastController = controller;
this.outItem = outItem;
this.inItem = inItem;
if (inItem && outItem) {
containerElement = this.getLayout().container.innerElement;
containerSize = containerElement.getSize();
xy = this.calculateXY(containerSize);
animConfig = {
easing: this.getEasing(),
duration: this.getDuration()
};
outTranslate = outItem.setTranslatable(true).getTranslatable();
inTranslate = inItem.setTranslatable(true).getTranslatable();
outTranslate.getWrapper().dom.style.setProperty('z-index', '100', 'important');
outTranslate.translate({
x: 0,
y: 0
});
inTranslate.translate({
x: 0,
y: 0
});
inItem.show();
outTranslate.on({
animationend: 'onOutAnimationEnd',
scope: this
});
outTranslate.translateAnimated({
x: xy.x,
y: xy.y
}, animConfig);
controller.pause();
}
},
onOutAnimationEnd: function() {
this.outItem.getTranslatable().getWrapper().dom.style.removeProperty('z-index');
this.lastController.resume();
}
});
Ext.define('Ext.fx.runner.CssAnimation', {
extend: 'Ext.fx.runner.Css',
constructor: function() {
this.runningAnimationsMap = {};
this.elementEndStates = {};
this.animationElementMap = {};
this.keyframesRulesCache = {};
this.uniqueId = 0;
return this.callParent(arguments);
},
attachListeners: function() {
this.listenersAttached = true;
Ext.getWin().on({
animationstart: 'onAnimationStart',
animationend: 'onAnimationEnd',
scope: this
});
},
onAnimationStart: function(e) {
var name = e.browserEvent.animationName,
elementId = this.animationElementMap[name],
animation = this.runningAnimationsMap[elementId][name],
elementEndStates = this.elementEndStates,
elementEndState = elementEndStates[elementId],
data = {};
if (elementEndState) {
delete elementEndStates[elementId];
data[elementId] = elementEndState;
this.applyStyles(data);
}
if (animation.before) {
data[elementId] = animation.before;
this.applyStyles(data);
}
},
onAnimationEnd: function(e) {
var element = e.target,
name = e.browserEvent.animationName,
animationElementMap = this.animationElementMap,
elementId = animationElementMap[name],
runningAnimationsMap = this.runningAnimationsMap,
runningAnimations = runningAnimationsMap[elementId],
animation = runningAnimations[name];
if (animation.onBeforeEnd) {
animation.onBeforeEnd.call(animation.scope || this, element);
}
if (animation.onEnd) {
animation.onEnd.call(animation.scope || this, element);
}
delete animationElementMap[name];
delete runningAnimations[name];
this.removeKeyframesRule(name);
},
generateAnimationId: function() {
return 'animation-' + (++this.uniqueId);
},
run: function(animations) {
var data = {},
elementEndStates = this.elementEndStates,
animationElementMap = this.animationElementMap,
runningAnimationsMap = this.runningAnimationsMap,
runningAnimations, states, elementId, animationId, i, ln, animation, name, runningAnimation, names, durations, easings, delays, directions, iterations;
if (!this.listenersAttached) {
this.attachListeners();
}
animations = Ext.Array.from(animations);
for (i = 0 , ln = animations.length; i < ln; i++) {
animation = animations[i];
animation = Ext.factory(animation, Ext.fx.Animation);
elementId = animation.getElement().getId();
animationId = animation.getName() || this.generateAnimationId();
animationElementMap[animationId] = elementId;
animation = animation.getData();
states = animation.states;
this.addKeyframesRule(animationId, states);
runningAnimations = runningAnimationsMap[elementId];
if (!runningAnimations) {
runningAnimations = runningAnimationsMap[elementId] = {};
}
runningAnimations[animationId] = animation;
names = [];
durations = [];
easings = [];
delays = [];
directions = [];
iterations = [];
for (name in runningAnimations) {
if (runningAnimations.hasOwnProperty(name)) {
runningAnimation = runningAnimations[name];
names.push(name);
durations.push(runningAnimation.duration);
easings.push(runningAnimation.easing);
delays.push(runningAnimation.delay);
directions.push(runningAnimation.direction);
iterations.push(runningAnimation.iteration);
}
}
data[elementId] = {
'animation-name': names,
'animation-duration': durations,
'animation-timing-function': easings,
'animation-delay': delays,
'animation-direction': directions,
'animation-iteration-count': iterations
};
if (animation.preserveEndState) {
elementEndStates[elementId] = states['100%'];
}
}
this.applyStyles(data);
},
addKeyframesRule: function(name, keyframes) {
var percentage, properties, keyframesRule, styleSheet, rules, styles, rulesLength, key, value;
styleSheet = this.getStyleSheet();
rules = styleSheet.cssRules;
rulesLength = rules.length;
styleSheet.insertRule('@' + this.vendorPrefix + 'keyframes ' + name + '{}', rulesLength);
keyframesRule = rules[rulesLength];
for (percentage in keyframes) {
properties = keyframes[percentage];
rules = keyframesRule.cssRules;
rulesLength = rules.length;
styles = [];
for (key in properties) {
value = this.formatValue(properties[key], key);
key = this.formatName(key);
styles.push(key + ':' + value);
}
keyframesRule.insertRule(percentage + '{' + styles.join(';') + '}', rulesLength);
}
return this;
},
removeKeyframesRule: function(name) {
var styleSheet = this.getStyleSheet(),
rules = styleSheet.cssRules,
i, ln, rule;
for (i = 0 , ln = rules.length; i < ln; i++) {
rule = rules[i];
if (rule.name === name) {
styleSheet.removeRule(i);
break;
}
}
return this;
}
});
Ext.define('Ext.mixin.Hookable', {
extend: 'Ext.Mixin',
mixinConfig: {
id: 'hookable'
},
bind: function(instance, boundMethod, bindingMethod, preventDefault, extraArgs) {
if (!bindingMethod) {
bindingMethod = boundMethod;
}
var boundFn = instance[boundMethod],
fn, binding;
if (boundFn && boundFn.hasOwnProperty('$binding')) {
binding = boundFn.$binding;
if (binding.bindingMethod === bindingMethod && binding.bindingScope === this) {
return this;
}
}
instance[boundMethod] = fn = function() {
var binding = fn.$binding,
scope = binding.bindingScope,
args = Array.prototype.slice.call(arguments);
args.push(arguments);
if (extraArgs) {
args.push.apply(args, extraArgs);
}
if (!binding.preventDefault && scope[binding.bindingMethod].apply(scope, args) !== false) {
return binding.boundFn.apply(this, arguments);
}
};
fn.$binding = {
preventDefault: !!preventDefault,
boundFn: boundFn,
bindingMethod: bindingMethod,
bindingScope: this
};
return this;
},
unbind: function(instance, boundMethod, bindingMethod) {
if (!bindingMethod) {
bindingMethod = boundMethod;
}
var fn = instance[boundMethod],
binding = fn.$binding,
boundFn, currentBinding;
while (binding) {
boundFn = binding.boundFn;
if (binding.bindingMethod === bindingMethod && binding.bindingScope === this) {
if (currentBinding) {
currentBinding.boundFn = boundFn;
} else {
instance[boundMethod] = boundFn;
}
return this;
}
currentBinding = binding;
binding = boundFn.$binding;
}
return this;
}
});
Ext.define('Ext.mixin.Mashup', function(Mashup) {
return {
extend: 'Ext.Mixin',
mixinConfig: {
id: 'mashup',
extended: function(baseClass, derivedClass) {
Mashup.process(derivedClass);
}
},
statics: {
process: function(targetClass) {
var body = targetClass.prototype,
requiredScripts = body.requiredScripts,
hooks = targetClass._classHooks,
onCreated = hooks.onCreated;
if (requiredScripts) {
delete body.requiredScripts;
hooks.onCreated = function() {
var me = this,
args = Ext.Array.slice(arguments);
Ext.Loader.loadScripts({
url: requiredScripts,
cache: true,
onLoad: function() {
hooks.onCreated = onCreated;
hooks.onCreated.call(me, args);
}
});
};
}
}
},
onClassMixedIn: function(targetClass) {
Mashup.process(targetClass);
}
};
});
Ext.define('Ext.mixin.Responsive', function(Responsive) {
return {
extend: 'Ext.Mixin',
requires: [
'Ext.GlobalEvents'
],
mixinConfig: {
id: 'responsive',
after: {
destroy: 'destroy'
}
},
config: {
responsiveConfig: {
$value: undefined,
merge: function(newValue, oldValue, target, mixinClass) {
if (!newValue) {
return oldValue;
}
var ret = oldValue ? Ext.Object.chain(oldValue) : {},
rule;
for (rule in newValue) {
if (!mixinClass || !(rule in ret)) {
ret[rule] = {
fn: null,
config: newValue[rule]
};
}
}
return ret;
}
},
responsiveFormulas: {
$value: 0,
merge: function(newValue, oldValue, target, mixinClass) {
return this.mergeNew(newValue, oldValue, target, mixinClass);
}
}
},
destroy: function() {
Responsive.unregister(this);
this.callParent();
},
privates: {
statics: {
active: false,
all: {},
context: Ext.Object.chain(Ext.platformTags),
count: 0,
nextId: 0,
activate: function() {
Responsive.active = true;
Responsive.updateContext();
Ext.on('resize', Responsive.onResize, Responsive);
},
deactivate: function() {
Responsive.active = false;
Ext.un('resize', Responsive.onResize, Responsive);
},
notify: function() {
var all = Responsive.all,
context = Responsive.context,
globalEvents = Ext.GlobalEvents,
timer = Responsive.timer,
id;
if (timer) {
Responsive.timer = null;
Ext.Function.cancelAnimationFrame(timer);
}
Responsive.updateContext();
Ext.suspendLayouts();
globalEvents.fireEvent('beforeresponsiveupdate', context);
for (id in all) {
all[id].setupResponsiveContext();
}
globalEvents.fireEvent('beginresponsiveupdate', context);
for (id in all) {
all[id].updateResponsiveState();
}
globalEvents.fireEvent('responsiveupdate', context);
Ext.resumeLayouts(true);
},
onResize: function() {
if (!Responsive.timer) {
Responsive.timer = Ext.Function.requestAnimationFrame(Responsive.onTimer);
}
},
onTimer: function() {
Responsive.timer = null;
Responsive.notify();
},
processConfig: function(instance, instanceConfig, name) {
var value = instanceConfig && instanceConfig[name],
config = instance.config,
cfg, configurator;
if (value) {
configurator = instance.getConfigurator();
cfg = configurator.configs[name];
config[name] = cfg.merge(value, config[name], instance);
}
},
register: function(responder) {
var id = responder.$responsiveId;
if (!id) {
responder.$responsiveId = id = ++Responsive.nextId;
Responsive.all[id] = responder;
if (++Responsive.count === 1) {
Responsive.activate();
}
}
},
unregister: function(responder) {
var id = responder.$responsiveId;
if (id in Responsive.all) {
responder.$responsiveId = null;
delete Responsive.all[id];
if (--Responsive.count === 0) {
Responsive.deactivate();
}
}
},
updateContext: function() {
var El = Ext.Element,
width = El.getViewportWidth(),
height = El.getViewportHeight(),
context = Responsive.context;
context.width = width;
context.height = height;
context.tall = width < height;
context.wide = !context.tall;
context.landscape = context.portrait = false;
if (!context.platform) {
context.platform = Ext.platformTags;
}
context[Ext.dom.Element.getOrientation()] = true;
}
},
afterClassMixedIn: function(targetClass) {
var proto = targetClass.prototype,
responsiveConfig = proto.responsiveConfig,
responsiveFormulas = proto.responsiveFormulas,
config;
if (responsiveConfig || responsiveFormulas) {
config = {};
if (responsiveConfig) {
delete proto.responsiveConfig;
config.responsiveConfig = responsiveConfig;
}
if (responsiveFormulas) {
delete proto.responsiveFormulas;
config.responsiveFormulas = responsiveFormulas;
}
targetClass.getConfigurator().add(config);
}
},
applyResponsiveConfig: function(rules) {
for (var rule in rules) {
rules[rule].fn = Ext.createRuleFn(rule);
}
return rules;
},
applyResponsiveFormulas: function(formulas) {
var ret = {},
fn, name;
if (formulas) {
for (name in formulas) {
if (Ext.isString(fn = formulas[name])) {
fn = Ext.createRuleFn(fn);
}
ret[name] = fn;
}
}
return ret;
},
getResponsiveState: function() {
var context = Responsive.context,
rules = this.getResponsiveConfig(),
ret = {},
entry, rule;
if (rules) {
for (rule in rules) {
entry = rules[rule];
if (entry.fn.call(this, context)) {
Ext.merge(ret, entry.config);
}
}
}
return ret;
},
setupResponsiveContext: function() {
var formulas = this.getResponsiveFormulas(),
context = Responsive.context,
name;
if (formulas) {
for (name in formulas) {
context[name] = formulas[name].call(this, context);
}
}
},
transformInstanceConfig: function(instanceConfig) {
var me = this,
ret;
Responsive.register(me);
if (instanceConfig) {
Responsive.processConfig(me, instanceConfig, 'responsiveConfig');
Responsive.processConfig(me, instanceConfig, 'responsiveFormulas');
}
me.setupResponsiveContext();
ret = me.getResponsiveState();
if (instanceConfig) {
ret = Ext.merge({}, instanceConfig, ret);
delete ret.responsiveConfig;
delete ret.responsiveFormulas;
}
return ret;
},
updateResponsiveState: function() {
var config = this.getResponsiveState();
this.setConfig(config);
}
}
};
});
Ext.define('Ext.mixin.Selectable', {
extend: 'Ext.Mixin',
mixinConfig: {
id: 'selectable',
after: {
updateStore: 'updateStore'
}
},
config: {
disableSelection: null,
mode: 'SINGLE',
allowDeselect: false,
lastSelected: null,
lastFocused: null,
deselectOnContainerClick: true
},
modes: {
SINGLE: true,
SIMPLE: true,
MULTI: true
},
selectableEventHooks: {
addrecords: 'onSelectionStoreAdd',
removerecords: 'onSelectionStoreRemove',
updaterecord: 'onSelectionStoreUpdate',
load: 'refreshSelection',
refresh: 'refreshSelection'
},
constructor: function() {
this.selected = new Ext.util.MixedCollection();
this.callParent(arguments);
},
applyMode: function(mode) {
mode = mode ? mode.toUpperCase() : 'SINGLE';
return this.modes[mode] ? mode : 'SINGLE';
},
updateStore: function(newStore, oldStore) {
var me = this,
bindEvents = Ext.apply({}, me.selectableEventHooks, {
scope: me
});
if (oldStore && Ext.isObject(oldStore) && oldStore.isStore) {
if (oldStore.autoDestroy) {
oldStore.destroy();
} else {
oldStore.un(bindEvents);
if (newStore) {
newStore.un('clear', 'onSelectionStoreClear', this);
}
}
}
if (newStore) {
newStore.on(bindEvents);
newStore.onBefore('clear', 'onSelectionStoreClear', this);
me.refreshSelection();
}
},
selectAll: function(silent) {
var me = this,
selections = me.getStore().getRange();
me.select(selections, true, silent);
},
deselectAll: function(supress) {
var me = this,
selections = me.getStore().getRange();
me.deselect(selections, supress);
me.selected.clear();
me.setLastSelected(null);
me.setLastFocused(null);
},
selectWithEvent: function(record) {
var me = this,
isSelected = me.isSelected(record);
switch (me.getMode()) {
case 'MULTI':
case 'SIMPLE':
if (isSelected) {
me.deselect(record);
} else {
me.select(record, true);
};
break;
case 'SINGLE':
if (me.getAllowDeselect() && isSelected) {
me.deselect(record);
} else {
me.select(record, false);
};
break;
}
},
selectRange: function(startRecord, endRecord, keepExisting) {
var me = this,
store = me.getStore(),
records = [],
tmp, i;
if (me.getDisableSelection()) {
return;
}
if (startRecord > endRecord) {
tmp = endRecord;
endRecord = startRecord;
startRecord = tmp;
}
for (i = startRecord; i <= endRecord; i++) {
records.push(store.getAt(i));
}
this.doMultiSelect(records, keepExisting);
},
select: function(records, keepExisting, suppressEvent) {
var me = this,
record;
if (me.getDisableSelection()) {
return;
}
if (typeof records === "number") {
records = [
me.getStore().getAt(records)
];
}
if (!records) {
return;
}
if (me.getMode() == "SINGLE" && records) {
record = records.length ? records[0] : records;
me.doSingleSelect(record, suppressEvent);
} else {
me.doMultiSelect(records, keepExisting, suppressEvent);
}
},
doSingleSelect: function(record, suppressEvent) {
var me = this,
selected = me.selected;
if (me.getDisableSelection()) {
return;
}
if (me.isSelected(record)) {
return;
}
if (selected.getCount() > 0) {
me.deselect(me.getLastSelected(), suppressEvent);
}
selected.add(record);
me.setLastSelected(record);
me.onItemSelect(record, suppressEvent);
me.setLastFocused(record);
if (!suppressEvent) {
me.fireSelectionChange([
record
]);
}
},
doMultiSelect: function(records, keepExisting, suppressEvent) {
if (records === null || this.getDisableSelection()) {
return;
}
records = !Ext.isArray(records) ? [
records
] : records;
var me = this,
selected = me.selected,
ln = records.length,
change = false,
i = 0,
record;
if (!keepExisting && selected.getCount() > 0) {
change = true;
me.deselect(me.getSelection(), true);
}
for (; i < ln; i++) {
record = records[i];
if (keepExisting && me.isSelected(record)) {
continue;
}
change = true;
me.setLastSelected(record);
selected.add(record);
if (!suppressEvent) {
me.setLastFocused(record);
}
me.onItemSelect(record, suppressEvent);
}
if (change && !suppressEvent) {
this.fireSelectionChange(records);
}
},
deselect: function(records, suppressEvent) {
var me = this;
if (me.getDisableSelection()) {
return;
}
records = Ext.isArray(records) ? records : [
records
];
var selected = me.selected,
change = false,
i = 0,
store = me.getStore(),
ln = records.length,
record;
for (; i < ln; i++) {
record = records[i];
if (typeof record === 'number') {
record = store.getAt(record);
}
if (selected.remove(record)) {
if (me.getLastSelected() == record) {
me.setLastSelected(selected.last());
}
change = true;
}
if (record) {
me.onItemDeselect(record, suppressEvent);
}
}
if (change && !suppressEvent) {
me.fireSelectionChange(records);
}
},
updateLastFocused: function(newRecord, oldRecord) {
this.onLastFocusChanged(oldRecord, newRecord);
},
fireSelectionChange: function(records) {
var me = this;
me.fireAction('beforeselectionchange', [
me
], function() {
me.fireAction('selectionchange', [
me,
records
], 'getSelection');
});
},
getSelection: function() {
return this.selected.getRange();
},
isSelected: function(record) {
record = Ext.isNumber(record) ? this.getStore().getAt(record) : record;
return this.selected.indexOf(record) !== -1;
},
hasSelection: function() {
return this.selected.getCount() > 0;
},
refreshSelection: function() {
var me = this,
selections = me.getSelection();
me.deselectAll(true);
if (selections.length) {
me.select(selections, false, true);
}
},
onSelectionStoreRemove: function(store, records) {
var me = this,
selected = me.selected,
ln = records.length,
record, i;
if (me.getDisableSelection()) {
return;
}
for (i = 0; i < ln; i++) {
record = records[i];
if (selected.remove(record)) {
if (me.getLastSelected() == record) {
me.setLastSelected(null);
}
if (me.getLastFocused() == record) {
me.setLastFocused(null);
}
me.fireSelectionChange([
record
]);
}
}
},
onSelectionStoreClear: function(store) {
var records = store.getData().items;
this.onSelectionStoreRemove(store, records);
},
getSelectionCount: function() {
return this.selected.getCount();
},
onSelectionStoreAdd: Ext.emptyFn,
onSelectionStoreUpdate: Ext.emptyFn,
onItemSelect: Ext.emptyFn,
onItemDeselect: Ext.emptyFn,
onLastFocusChanged: Ext.emptyFn,
onEditorKey: Ext.emptyFn
}, function() {});
Ext.define('Ext.mixin.Traversable', {
extend: 'Ext.Mixin',
mixinConfig: {
id: 'traversable'
},
setParent: function(parent) {
this.parent = parent;
return this;
},
hasParent: function() {
return Boolean(this.parent);
},
getParent: function() {
return this.parent;
},
getAncestors: function() {
var ancestors = [],
parent = this.getParent();
while (parent) {
ancestors.push(parent);
parent = parent.getParent();
}
return ancestors;
},
getAncestorIds: function() {
var ancestorIds = [],
parent = this.getParent();
while (parent) {
ancestorIds.push(parent.getId());
parent = parent.getParent();
}
return ancestorIds;
}
});
Ext.define('Ext.perf.Accumulator', function() {
var currentFrame = null,
khrome = Ext.global['chrome'],
formatTpl,
getTimestamp = function() {
getTimestamp = Ext.now;
var interval, toolbox;
if (Ext.isChrome && khrome && khrome.Interval) {
interval = new khrome.Interval();
interval.start();
getTimestamp = function() {
return interval.microseconds() / 1000;
};
} else if (window.ActiveXObject) {
try {
toolbox = new ActiveXObject('SenchaToolbox.Toolbox');
Ext.senchaToolbox = toolbox;
getTimestamp = function() {
return toolbox.milliseconds;
};
} catch (e) {}
}
Ext.perf.getTimestamp = Ext.perf.Accumulator.getTimestamp = getTimestamp;
return getTimestamp();
};
function adjustSet(set, time) {
set.sum += time;
set.min = Math.min(set.min, time);
set.max = Math.max(set.max, time);
}
function leaveFrame(time) {
var totalTime = time ? time : (getTimestamp() - this.time),
me = this,
accum = me.accum;
++accum.count;
if (!--accum.depth) {
adjustSet(accum.total, totalTime);
}
adjustSet(accum.pure, totalTime - me.childTime);
currentFrame = me.parent;
if (currentFrame) {
++currentFrame.accum.childCount;
currentFrame.childTime += totalTime;
}
}
function makeSet() {
return {
min: Number.MAX_VALUE,
max: 0,
sum: 0
};
}
function makeTap(me, fn) {
return function() {
var frame = me.enter(),
ret = fn.apply(this, arguments);
frame.leave();
return ret;
};
}
function setToJSON(count, childCount, calibration, set) {
var data = {
avg: 0,
min: set.min,
max: set.max,
sum: 0
};
if (count) {
calibration = calibration || 0;
data.sum = set.sum - childCount * calibration;
data.avg = data.sum / count;
}
return data;
}
return {
requires: [
'Ext.XTemplate',
'Ext.ClassManager'
],
constructor: function(name) {
var me = this;
me.count = me.childCount = me.depth = me.maxDepth = 0;
me.pure = makeSet();
me.total = makeSet();
me.name = name;
},
statics: {
getTimestamp: getTimestamp
},
format: function(calibration) {
if (!formatTpl) {
formatTpl = new Ext.XTemplate([
'{name} - {count} call(s)',
'<tpl if="count">',
'<tpl if="childCount">',
' ({childCount} children)',
'</tpl>',
'<tpl if="depth - 1">',
' ({depth} deep)',
'</tpl>',
'<tpl for="times">',
', {type}: {[this.time(values.sum)]} msec (',
'avg={[this.time(values.sum / parent.count)]}',
')',
'</tpl>',
'</tpl>'
].join(''), {
time: function(t) {
return Math.round(t * 100) / 100;
}
});
}
var data = this.getData(calibration);
data.name = this.name;
data.pure.type = 'Pure';
data.total.type = 'Total';
data.times = [
data.pure,
data.total
];
return formatTpl.apply(data);
},
getData: function(calibration) {
var me = this;
return {
count: me.count,
childCount: me.childCount,
depth: me.maxDepth,
pure: setToJSON(me.count, me.childCount, calibration, me.pure),
total: setToJSON(me.count, me.childCount, calibration, me.total)
};
},
enter: function() {
var me = this,
frame = {
accum: me,
leave: leaveFrame,
childTime: 0,
parent: currentFrame
};
++me.depth;
if (me.maxDepth < me.depth) {
me.maxDepth = me.depth;
}
currentFrame = frame;
frame.time = getTimestamp();
return frame;
},
monitor: function(fn, scope, args) {
var frame = this.enter();
if (args) {
fn.apply(scope, args);
} else {
fn.call(scope);
}
frame.leave();
},
report: function() {
Ext.log(this.format());
},
tap: function(className, methodName) {
var me = this,
methods = typeof methodName === 'string' ? [
methodName
] : methodName,
klass, statik, i, parts, length, name, src, tapFunc;
tapFunc = function() {
if (typeof className === 'string') {
klass = Ext.global;
parts = className.split('.');
for (i = 0 , length = parts.length; i < length; ++i) {
klass = klass[parts[i]];
}
} else {
klass = className;
}
for (i = 0 , length = methods.length; i < length; ++i) {
name = methods[i];
statik = name.charAt(0) === '!';
if (statik) {
name = name.substring(1);
} else {
statik = !(name in klass.prototype);
}
src = statik ? klass : klass.prototype;
src[name] = makeTap(me, src[name]);
}
};
Ext.ClassManager.onCreated(tapFunc, me, className);
return me;
}
};
}, function() {
Ext.perf.getTimestamp = this.getTimestamp;
});
Ext.define('Ext.perf.Monitor', {
singleton: true,
alternateClassName: 'Ext.Perf',
requires: [
'Ext.perf.Accumulator'
],
constructor: function() {
this.accumulators = [];
this.accumulatorsByName = {};
},
calibrate: function() {
var accum = new Ext.perf.Accumulator('$'),
total = accum.total,
getTimestamp = Ext.perf.Accumulator.getTimestamp,
count = 0,
frame, endTime, startTime;
startTime = getTimestamp();
do {
frame = accum.enter();
frame.leave();
++count;
} while (total.sum < 100);
endTime = getTimestamp();
return (endTime - startTime) / count;
},
get: function(name) {
var me = this,
accum = me.accumulatorsByName[name];
if (!accum) {
me.accumulatorsByName[name] = accum = new Ext.perf.Accumulator(name);
me.accumulators.push(accum);
}
return accum;
},
enter: function(name) {
return this.get(name).enter();
},
monitor: function(name, fn, scope) {
this.get(name).monitor(fn, scope);
},
report: function() {
var me = this,
accumulators = me.accumulators,
calibration = me.calibrate();
accumulators.sort(function(a, b) {
return (a.name < b.name) ? -1 : ((b.name < a.name) ? 1 : 0);
});
me.updateGC();
Ext.log('Calibration: ' + Math.round(calibration * 100) / 100 + ' msec/sample');
Ext.each(accumulators, function(accum) {
Ext.log(accum.format(calibration));
});
},
getData: function(all) {
var ret = {},
accumulators = this.accumulators;
Ext.each(accumulators, function(accum) {
if (all || accum.count) {
ret[accum.name] = accum.getData();
}
});
return ret;
},
reset: function() {
Ext.each(this.accumulators, function(accum) {
var me = accum;
me.count = me.childCount = me.depth = me.maxDepth = 0;
me.pure = {
min: Number.MAX_VALUE,
max: 0,
sum: 0
};
me.total = {
min: Number.MAX_VALUE,
max: 0,
sum: 0
};
});
},
updateGC: function() {
var accumGC = this.accumulatorsByName.GC,
toolbox = Ext.senchaToolbox,
bucket;
if (accumGC) {
accumGC.count = toolbox.garbageCollectionCounter || 0;
if (accumGC.count) {
bucket = accumGC.pure;
accumGC.total.sum = bucket.sum = toolbox.garbageCollectionMilliseconds;
bucket.min = bucket.max = bucket.sum / accumGC.count;
bucket = accumGC.total;
bucket.min = bucket.max = bucket.sum / accumGC.count;
}
}
},
watchGC: function() {
Ext.perf.getTimestamp();
var toolbox = Ext.senchaToolbox;
if (toolbox) {
this.get("GC");
toolbox.watchGarbageCollector(false);
}
},
setup: function(config) {
if (!config) {
config = {
render: {
'Ext.Component': 'render'
},
layout: {
'Ext.layout.Context': 'run'
}
};
}
this.currentConfig = config;
var key, prop, accum, className, methods;
for (key in config) {
if (config.hasOwnProperty(key)) {
prop = config[key];
accum = Ext.Perf.get(key);
for (className in prop) {
if (prop.hasOwnProperty(className)) {
methods = prop[className];
accum.tap(className, methods);
}
}
}
}
this.watchGC();
}
});
Ext.define('Ext.plugin.Abstract', {
alternateClassName: 'Ext.AbstractPlugin',
isPlugin: true,
constructor: function(config) {
if (config) {
this.pluginConfig = config;
this.initConfig(config);
}
},
clonePlugin: function(overrideCfg) {
return new this.self(Ext.apply({}, overrideCfg, this.pluginConfig));
},
setCmp: function(cmp) {
this.cmp = cmp;
},
getCmp: function() {
return this.cmp;
},
init: Ext.emptyFn,
onClassExtended: function(cls, data, hooks) {
var alias = data.alias;
if (alias && !data.ptype) {
if (Ext.isArray(alias)) {
alias = alias[0];
}
cls.prototype.ptype = alias.split('plugin.')[1];
}
},
resolveListenerScope: function(defaultScope) {
var me = this,
cmp = me.getCmp(),
scope;
if (cmp) {
scope = cmp.resolveSatelliteListenerScope(me, defaultScope);
}
return scope || me.mixins.observable.resolveListenerScope.call(me, defaultScope);
}
});
Ext.define('Ext.overrides.plugin.Abstract', {
override: 'Ext.plugin.Abstract',
$configStrict: false,
$configPrefixed: false,
disabled: false,
getState: null,
applyState: null,
enable: function() {
this.disabled = false;
},
disable: function() {
this.disabled = true;
}
});
Ext.define('Ext.plugin.LazyItems', {
extend: 'Ext.plugin.Abstract',
alias: 'plugin.lazyitems',
init: function(comp) {
this.callParent(arguments);
if (this.items) {
if (this.eagerInstantiation) {
this.items = comp.prepareItems(this.items);
}
}
comp.beforeRender = Ext.Function.createInterceptor(comp.beforeRender, this.beforeComponentRender, this);
},
beforeComponentRender: function() {
this.cmp.add(this.items);
delete this.cmp.beforeComponentRender;
}
});
Ext.define('Ext.util.Base64', {
singleton: true,
_str: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
encode: function(input) {
var me = this;
var output = '',
chr1, chr2, chr3, enc1, enc2, enc3, enc4,
i = 0;
input = me._utf8_encode(input);
var len = input.length;
while (i < len) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output + me._str.charAt(enc1) + me._str.charAt(enc2) + me._str.charAt(enc3) + me._str.charAt(enc4);
}
return output;
},
decode: function(input) {
var me = this;
var output = '',
chr1, chr2, chr3, enc1, enc2, enc3, enc4,
i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
var len = input.length;
while (i < len) {
enc1 = me._str.indexOf(input.charAt(i++));
enc2 = me._str.indexOf(input.charAt(i++));
enc3 = me._str.indexOf(input.charAt(i++));
enc4 = me._str.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 !== 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 !== 64) {
output = output + String.fromCharCode(chr3);
}
}
output = me._utf8_decode(output);
return output;
},
_utf8_encode: function(string) {
string = string.replace(/\r\n/g, "\n");
var utftext = '',
n = 0,
len = string.length;
for (; n < len; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
_utf8_decode: function(utftext) {
var string = '',
i = 0,
c = 0,
c3 = 0,
c2 = 0,
len = utftext.length;
while (i < len) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
});
Ext.define('Ext.util.DelimitedValue', {
dateFormat: 'C',
delimiter: '\t',
lineBreak: '\n',
quote: '"',
parseREs: {},
quoteREs: {},
lineBreakRe: /\r?\n/g,
constructor: function(config) {
if (config) {
Ext.apply(this, config);
}
},
decode: function(input, delimiter) {
var me = this,
delim = (delimiter || me.delimiter),
row = [],
result = [
row
],
quote = me.quote,
quoteREs = me.quoteREs,
parseREs = me.parseREs,
parseRE = parseREs[delim] || (parseREs[delim] = new RegExp(
"(\\" + delim + "|\\r?\\n|\\r|^)" +
"(?:\\" + quote + "([^\\" + quote + "]*(?:\\" + quote + "\\" + quote + "[^\\" + quote + "]*)*)\\" + quote + "|" +
"([^\"\\" + delim + "\\r\\n]*))", "gi")),
dblQuoteRE = quoteREs[quote] || (quoteREs[quote] = new RegExp('\\' + quote + '\\' + quote, 'g')),
arrMatches, strMatchedDelimiter, strMatchedValue;
while (arrMatches = parseRE.exec(input)) {
strMatchedDelimiter = arrMatches[1];
if (strMatchedDelimiter.length && strMatchedDelimiter !== delim) {
result.push(row = []);
}
if (arrMatches[2]) {
strMatchedValue = arrMatches[2].replace(dblQuoteRE, '"');
} else {
strMatchedValue = arrMatches[3];
}
row.push(strMatchedValue);
}
return result;
},
encode: function(input, delimiter) {
var me = this,
delim = delimiter || me.delimiter,
dateFormat = me.dateFormat,
quote = me.quote,
twoQuotes = quote + quote,
rowIndex = input.length,
lineBreakRe = me.lineBreakRe,
result = [],
outputRow = [],
col, columnIndex, inputRow;
while (rowIndex-- > 0) {
inputRow = input[rowIndex];
outputRow.length = columnIndex = inputRow.length;
while (columnIndex-- > 0) {
col = inputRow[columnIndex];
if (col == null) {
col = '';
} else if (typeof col === 'string') {
if (col) {
if (col.indexOf(quote) > -1) {
col = quote + col.split(quote).join(twoQuotes) + quote;
} else if (col.indexOf(delim) > -1 || lineBreakRe.test(col)) {
col = quote + col + quote;
}
}
} else if (Ext.isDate(col)) {
col = Ext.Date.format(col, dateFormat);
} else if (col && (isNaN(col) || Ext.isArray(col))) {
Ext.Error.raise('Cannot serialize ' + Ext.typeOf(col) + ' into CSV');
}
outputRow[columnIndex] = col;
}
result[rowIndex] = outputRow.join(delim);
}
return result.join(me.lineBreak);
}
});
Ext.define('Ext.util.CSV', {
extend: 'Ext.util.DelimitedValue',
singleton: true,
delimiter: ','
});
Ext.define('Ext.util.LocalStorage', {
id: null,
destroyed: false,
lazyKeys: true,
prefix: '',
session: false,
_keys: null,
_store: null,
_users: 0,
statics: {
cache: {},
get: function(id) {
var me = this,
cache = me.cache,
config = {
_users: 1
},
instance;
if (Ext.isString(id)) {
config.id = id;
} else {
Ext.apply(config, id);
}
if (!(instance = cache[config.id])) {
instance = new me(config);
} else {
if (instance === true) {
Ext.Error.raise('Creating a shared instance of private local store "' + me.id + '".');
}
++instance._users;
}
return instance;
},
supported: true
},
constructor: function(config) {
var me = this;
Ext.apply(me, config);
if (!me.hasOwnProperty('id')) {
Ext.Error.raise("No id was provided to the local store.");
}
if (me._users) {
Ext.util.LocalStorage.cache[me.id] = me;
} else {
if (Ext.util.LocalStorage.cache[me.id]) {
Ext.Error.raise('Cannot create duplicate instance of local store "' + me.id + '". Use Ext.util.LocalStorage.get() to share instances.');
}
Ext.util.LocalStorage.cache[me.id] = true;
}
me.init();
},
init: function() {
var me = this,
id = me.id;
if (!me.prefix && id) {
me.prefix = id + '-';
}
me._store = (me.session ? window.sessionStorage : window.localStorage);
},
destroy: function() {
var me = this;
if (me._users) {
Ext.log.warn('LocalStorage(id=' + me.id + ') destroyed while in use');
}
delete Ext.util.LocalStorage.cache[me.id];
me._store = me._keys = null;
me.destroyed = true;
me.destroy = Ext.emptyFn;
},
getKeys: function() {
var me = this,
store = me._store,
prefix = me.prefix,
keys = me._keys,
n = prefix.length,
i, key;
if (!keys) {
me._keys = keys = [];
for (i = store.length; i--; ) {
key = store.key(i);
if (key.length > n) {
if (prefix === key.substring(0, n)) {
keys.push(key.substring(n));
}
}
}
}
return keys;
},
release: function() {
if (!--this._users) {
this.destroy();
}
},
save: Ext.emptyFn,
clear: function() {
var me = this,
store = me._store,
prefix = me.prefix,
keys = me._keys || me.getKeys(),
i;
for (i = keys.length; i--; ) {
store.removeItem(prefix + keys[i]);
}
keys.length = 0;
},
key: function(index) {
var keys = this._keys || this.getKeys();
return (0 <= index && index < keys.length) ? keys[index] : null;
},
getItem: function(key) {
var k = this.prefix + key;
return this._store.getItem(k);
},
removeItem: function(key) {
var me = this,
k = me.prefix + key,
store = me._store,
keys = me._keys,
length = store.length;
store.removeItem(k);
if (keys && length !== store.length) {
if (me.lazyKeys) {
me._keys = null;
} else {
Ext.Array.remove(keys, key);
}
}
},
setItem: function(key, value) {
var me = this,
k = me.prefix + key,
store = me._store,
length = store.length,
keys = me._keys;
store.setItem(k, value);
if (keys && length !== store.length) {
keys.push(key);
}
}
}, function() {
var LocalStorage = this;
if ('localStorage' in window) {
return;
}
if (!Ext.isIE) {
LocalStorage.supported = false;
LocalStorage.prototype.init = function() {
Ext.Error.raise("Local storage is not supported on this browser");
};
return;
}
LocalStorage.override({
data: null,
flushDelay: 1,
init: function() {
var me = this,
data = me.data,
el;
me.el = el = document.createElement('div');
el.id = (me.id || (me.id = 'extjs-localstore'));
el.addBehavior('#default#userdata');
Ext.getHead().dom.appendChild(el);
el.load(me.id);
data = el.getAttribute('xdata');
me.data = data = (data ? Ext.decode(data) : {});
me._flushFn = function() {
me._timer = null;
me.save(0);
};
},
destroy: function() {
var me = this,
el = me.el;
if (el) {
if (me._timer) {
me.save();
}
el.parentNode.removeChild(el);
me.data = me.el = null;
me.callParent();
}
},
getKeys: function() {
var me = this,
keys = me._keys;
if (!keys) {
me._keys = keys = Ext.Object.getKeys(me.data);
}
return keys;
},
save: function(delay) {
var me = this;
if (!delay) {
if (me._timer) {
clearTimeout(me._timer);
me._timer = null;
}
me.el.setAttribute('xdata', Ext.encode(me.data));
me.el.save(me.id);
} else if (!me._timer) {
me._timer = Ext.defer(me._flushFn, delay);
}
},
clear: function() {
var me = this;
me.data = {};
me._keys = null;
me.save(me.flushDelay);
},
getItem: function(key) {
var data = this.data;
return (key in data) ? data[key] : null;
},
removeItem: function(key) {
var me = this,
keys = me._keys,
data = me.data;
if (key in data) {
delete data[key];
if (keys) {
if (me.lazyKeys) {
me._keys = null;
} else {
Ext.Array.remove(keys, key);
}
}
me.save(me.flushDelay);
}
},
setItem: function(key, value) {
var me = this,
data = me.data,
keys = me._keys;
if (keys && !(key in data)) {
keys.push(key);
}
data[key] = value;
me.save(me.flushDelay);
}
});
});
Ext.define('Ext.util.TSV', {
extend: 'Ext.util.DelimitedValue',
singleton: true,
delimiter: '\t'
});
Ext.define('Ext.util.TaskManager', {
extend: 'Ext.util.TaskRunner',
alternateClassName: [
'Ext.TaskManager'
],
singleton: true
});
Ext.define('Ext.util.TextMetrics', {
requires: [
'Ext.dom.Element'
],
statics: {
shared: null,
measure: function(el, text, fixedWidth) {
var me = this,
shared = me.shared;
if (!shared) {
shared = me.shared = new me(el, fixedWidth);
}
shared.bind(el);
shared.setFixedWidth(fixedWidth || 'auto');
return shared.getSize(text);
},
destroy: function() {
var me = this;
Ext.destroy(me.shared);
me.shared = null;
}
},
constructor: function(bindTo, fixedWidth) {
var me = this,
measure = Ext.getBody().createChild({
'data-sticky': true,
role: 'presentation',
cls: Ext.baseCSSPrefix + 'textmetrics'
});
me.measure = measure;
if (bindTo) {
me.bind(bindTo);
}
measure.position('absolute');
measure.setLocalXY(-1000, -1000);
measure.hide();
if (fixedWidth) {
measure.setWidth(fixedWidth);
}
},
getSize: function(text) {
var measure = this.measure,
size;
measure.setHtml(text);
size = measure.getSize();
measure.setHtml('');
return size;
},
bind: function(el) {
var me = this;
me.el = Ext.get(el);
me.measure.setStyle(me.el.getStyle([
'font-size',
'font-style',
'font-weight',
'font-family',
'line-height',
'text-transform',
'letter-spacing',
'word-break'
]));
},
setFixedWidth: function(width) {
this.measure.setWidth(width);
},
getWidth: function(text) {
this.measure.dom.style.width = 'auto';
return this.getSize(text).width;
},
getHeight: function(text) {
return this.getSize(text).height;
},
destroy: function() {
var me = this;
me.measure.destroy();
delete me.el;
delete me.measure;
}
}, function() {
Ext.Element.override({
getTextWidth: function(text, min, max) {
return Ext.Number.constrain(Ext.util.TextMetrics.measure(this.dom, Ext.valueFrom(text, this.dom.innerHTML, true)).width, min || 0, max || 1000000);
}
});
});
Ext.define('Ext.Action', {
constructor: function(config) {
this.initialConfig = config;
this.itemId = config.itemId = (config.itemId || config.id || Ext.id());
this.items = [];
},
isAction: true,
setText: function(text) {
this.initialConfig.text = text;
this.callEach('setText', [
text
]);
},
getText: function() {
return this.initialConfig.text;
},
setIconCls: function(cls) {
this.initialConfig.iconCls = cls;
this.callEach('setIconCls', [
cls
]);
},
getIconCls: function() {
return this.initialConfig.iconCls;
},
setDisabled: function(v) {
this.initialConfig.disabled = v;
this.callEach('setDisabled', [
v
]);
},
enable: function() {
this.setDisabled(false);
},
disable: function() {
this.setDisabled(true);
},
isDisabled: function() {
return this.initialConfig.disabled;
},
setHidden: function(v) {
this.initialConfig.hidden = v;
this.callEach('setVisible', [
!v
]);
},
show: function() {
this.setHidden(false);
},
hide: function() {
this.setHidden(true);
},
isHidden: function() {
return this.initialConfig.hidden;
},
setHandler: function(fn, scope) {
this.initialConfig.handler = fn;
this.initialConfig.scope = scope;
this.callEach('setHandler', [
fn,
scope
]);
},
each: function(fn, scope) {
Ext.each(this.items, fn, scope);
},
callEach: function(fnName, args) {
var items = this.items,
i = 0,
len = items.length,
item;
Ext.suspendLayouts();
for (; i < len; i++) {
item = items[i];
item[fnName].apply(item, args);
}
Ext.resumeLayouts(true);
},
addComponent: function(comp) {
this.items.push(comp);
comp.on('destroy', this.removeComponent, this);
},
removeComponent: function(comp) {
Ext.Array.remove(this.items, comp);
},
execute: function() {
this.initialConfig.handler.apply(this.initialConfig.scope || Ext.global, arguments);
}
});
Ext.define('Ext.ElementLoader', {
mixins: {
observable: 'Ext.util.Observable'
},
uses: [
'Ext.data.Connection',
'Ext.Ajax'
],
statics: {
Renderer: {
Html: function(loader, response, active) {
loader.getTarget().setHtml(response.responseText, active.scripts === true);
return true;
}
}
},
url: null,
params: null,
baseParams: null,
autoLoad: false,
target: null,
loadMask: false,
ajaxOptions: null,
scripts: false,
isLoader: true,
constructor: function(config) {
var me = this,
autoLoad;
config = config || {};
Ext.apply(me, config);
me.mixins.observable.constructor.call(me);
me.setTarget(me.target);
if (me.autoLoad) {
autoLoad = me.autoLoad;
if (autoLoad === true) {
autoLoad = null;
}
me.load(autoLoad);
}
},
setTarget: function(target) {
var me = this;
target = Ext.get(target);
if (me.target && me.target !== target) {
me.abort();
}
me.target = target;
},
getTarget: function() {
return this.target || null;
},
abort: function() {
var active = this.active;
if (active !== undefined) {
Ext.Ajax.abort(active.request);
if (active.mask) {
this.removeMask();
}
delete this.active;
}
},
removeMask: function() {
this.target.unmask();
},
addMask: function(mask) {
this.target.mask(mask === true ? null : mask);
},
load: function(options) {
if (!this.target) {
Ext.Error.raise('A valid target is required when loading content');
}
options = Ext.apply({}, options);
var me = this,
mask = Ext.isDefined(options.loadMask) ? options.loadMask : me.loadMask,
params = Ext.apply({}, options.params),
ajaxOptions = Ext.apply({}, options.ajaxOptions),
callback = options.callback || me.callback,
scope = options.scope || me.scope || me,
rendererScope = options.rendererScope || me.rendererScope || me;
Ext.applyIf(ajaxOptions, me.ajaxOptions);
Ext.applyIf(options, ajaxOptions);
Ext.applyIf(params, me.params);
Ext.apply(params, me.baseParams);
Ext.applyIf(options, {
url: me.url
});
if (!options.url) {
Ext.Error.raise('You must specify the URL from which content should be loaded');
}
Ext.apply(options, {
scope: me,
params: params,
callback: me.onComplete
});
if (me.fireEvent('beforeload', me, options) === false) {
return;
}
if (mask) {
me.addMask(mask);
}
me.active = {
options: options,
mask: mask,
scope: scope,
rendererScope: rendererScope,
callback: callback,
success: options.success || me.success,
failure: options.failure || me.failure,
renderer: options.renderer || me.renderer,
scripts: Ext.isDefined(options.scripts) ? options.scripts : me.scripts
};
me.active.request = Ext.Ajax.request(options);
me.setOptions(me.active, options);
},
setOptions: Ext.emptyFn,
onComplete: function(options, success, response) {
var me = this,
active = me.active,
rendererScope, scope;
if (active) {
scope = active.scope;
rendererScope = active.rendererScope;
if (success) {
success = me.getRenderer(active.renderer).call(rendererScope, me, response, active) !== false;
}
if (success) {
Ext.callback(active.success, scope, [
me,
response,
options
]);
me.fireEvent('load', me, response, options);
} else {
Ext.callback(active.failure, scope, [
me,
response,
options
]);
me.fireEvent('exception', me, response, options);
}
Ext.callback(active.callback, scope, [
me,
success,
response,
options
]);
if (active.mask) {
me.removeMask();
}
}
delete me.active;
},
getRenderer: function(renderer) {
if (Ext.isFunction(renderer)) {
return renderer;
}
return this.statics().Renderer.Html;
},
startAutoRefresh: function(interval, options) {
var me = this;
me.stopAutoRefresh();
me.autoRefresh = Ext.interval(function() {
me.load(options);
}, interval);
},
stopAutoRefresh: function() {
clearInterval(this.autoRefresh);
delete this.autoRefresh;
},
isAutoRefreshing: function() {
return Ext.isDefined(this.autoRefresh);
},
destroy: function() {
var me = this;
me.stopAutoRefresh();
delete me.target;
me.abort();
me.clearListeners();
}
});
Ext.define('Ext.ComponentLoader', {
extend: 'Ext.ElementLoader',
statics: {
Renderer: {
Data: function(loader, response, active) {
var success = true;
try {
loader.getTarget().update(Ext.decode(response.responseText));
} catch (e) {
success = false;
}
return success;
},
Component: function(loader, response, active) {
var success = true,
target = loader.getTarget(),
items = [];
if (!target.isContainer) {
Ext.Error.raise({
target: target,
msg: 'Components can only be loaded into a container'
});
}
try {
items = Ext.decode(response.responseText);
} catch (e) {
success = false;
}
if (success) {
target.suspendLayouts();
if (active.removeAll) {
target.removeAll();
}
target.add(items);
target.resumeLayouts(true);
}
return success;
}
}
},
target: null,
loadOnRender: false,
loadMask: false,
renderer: 'html',
setTarget: function(target) {
var me = this;
if (Ext.isString(target)) {
target = Ext.getCmp(target);
}
if (me.target && me.target !== target) {
me.abort();
}
me.target = target;
if (target && me.loadOnRender) {
if (target.rendered) {
me.doLoadOnRender();
} else {
me.mon(target, 'render', me.doLoadOnRender, me);
}
}
},
doLoadOnRender: function() {
var loadOnRender = this.loadOnRender;
this.load(Ext.isObject(loadOnRender) ? loadOnRender : null);
},
removeMask: function() {
this.target.setLoading(false);
},
addMask: function(mask) {
this.target.setLoading(mask);
},
setOptions: function(active, options) {
active.removeAll = Ext.isDefined(options.removeAll) ? options.removeAll : this.removeAll;
},
getRenderer: function(renderer) {
if (Ext.isFunction(renderer)) {
return renderer;
}
var renderers = this.statics().Renderer;
switch (renderer) {
case 'component':
return renderers.Component;
case 'data':
return renderers.Data;
default:
return Ext.ElementLoader.Renderer.Html;
}
}
});
Ext.define('Ext.layout.SizeModel', {
constructor: function(config) {
var me = this,
SizeModel = me.self,
sizeModelsArray = SizeModel.sizeModelsArray,
name;
Ext.apply(me, config);
me[name = me.name] = true;
me.fixed = !(me.auto = me.natural || me.shrinkWrap);
sizeModelsArray[me.ordinal = sizeModelsArray.length] = SizeModel[name] = SizeModel.sizeModels[name] = me;
},
statics: {
sizeModelsArray: [],
sizeModels: {}
},
calculated: false,
configured: false,
constrainedMax: false,
constrainedMin: false,
natural: false,
shrinkWrap: false,
calculatedFromConfigured: false,
calculatedFromNatural: false,
calculatedFromShrinkWrap: false,
names: null
}, function() {
var SizeModel = this,
sizeModelsArray = SizeModel.sizeModelsArray,
i, j, n, pairs, sizeModel;
new SizeModel({
name: 'calculated'
});
new SizeModel({
name: 'configured',
names: {
width: 'width',
height: 'height'
}
});
new SizeModel({
name: 'natural'
});
new SizeModel({
name: 'shrinkWrap'
});
new SizeModel({
name: 'calculatedFromConfigured',
configured: true,
calculatedFrom: true,
names: {
width: 'width',
height: 'height'
}
});
new SizeModel({
name: 'calculatedFromNatural',
natural: true,
calculatedFrom: true
});
new SizeModel({
name: 'calculatedFromShrinkWrap',
shrinkWrap: true,
calculatedFrom: true
});
new SizeModel({
name: 'constrainedMax',
configured: true,
constrained: true,
names: {
width: 'maxWidth',
height: 'maxHeight'
}
});
new SizeModel({
name: 'constrainedMin',
configured: true,
constrained: true,
names: {
width: 'minWidth',
height: 'minHeight'
}
});
new SizeModel({
name: 'constrainedDock',
configured: true,
constrained: true,
constrainedByMin: true,
names: {
width: 'dockConstrainedWidth',
height: 'dockConstrainedHeight'
}
});
for (i = 0 , n = sizeModelsArray.length; i < n; ++i) {
sizeModel = sizeModelsArray[i];
sizeModel.pairsByHeightOrdinal = pairs = [];
for (j = 0; j < n; ++j) {
pairs.push({
width: sizeModel,
height: sizeModelsArray[j]
});
}
}
});
Ext.define('Ext.layout.Layout', {
mixins: [
'Ext.mixin.Factoryable'
],
requires: [
'Ext.XTemplate',
'Ext.layout.SizeModel'
],
uses: [
'Ext.layout.Context'
],
factoryConfig: {
type: 'layout'
},
isLayout: true,
initialized: false,
running: false,
needsItemSize: true,
setsItemSize: true,
autoSizePolicy: {
readsWidth: 1,
readsHeight: 1,
setsWidth: 0,
setsHeight: 0
},
$configPrefixed: false,
$configStrict: false,
constructor: function(config) {
var me = this;
me.id = Ext.id(null, me.type + '-');
me.initConfig(config);
delete me.type;
me.layoutCount = 0;
},
beginLayout: Ext.emptyFn,
beginLayoutCycle: function(ownerContext) {
var me = this,
context = me.context,
changed;
if (me.lastWidthModel !== ownerContext.widthModel) {
if (me.lastWidthModel) {
changed = true;
}
me.lastWidthModel = ownerContext.widthModel;
}
if (me.lastHeightModel !== ownerContext.heightModel) {
if (me.lastWidthModel) {
changed = true;
}
me.lastHeightModel = ownerContext.heightModel;
}
if (changed) {
(context = ownerContext.context).clearTriggers(me, false);
context.clearTriggers(me, true);
me.triggerCount = 0;
}
},
finishedLayout: function(ownerContext) {
this.lastWidthModel = ownerContext.widthModel;
this.lastHeightModel = ownerContext.heightModel;
this.ownerContext = null;
},
redoLayout: Ext.emptyFn,
undoLayout: Ext.emptyFn,
getAnimatePolicy: function() {
return this.animatePolicy;
},
getItemSizePolicy: function(item) {
return this.autoSizePolicy;
},
getScrollerEl: Ext.emptyFn,
isItemBoxParent: function(itemContext) {
return false;
},
isItemLayoutRoot: function(item) {
var sizeModel = item.getSizeModel(),
width = sizeModel.width,
height = sizeModel.height;
if (!item.componentLayout.lastComponentSize && (width.calculated || height.calculated)) {
return false;
}
return !width.shrinkWrap && !height.shrinkWrap;
},
isItemShrinkWrap: function(item) {
return item.shrinkWrap;
},
isRunning: function() {
return !!this.ownerContext;
},
getItemsRenderTree: function(items, renderCfgs) {
var length = items.length,
i, item, itemConfig, result;
if (length) {
result = [];
for (i = 0; i < length; ++i) {
item = items[i];
if (!item.rendered) {
if (renderCfgs && (renderCfgs[item.id] !== undefined)) {
itemConfig = renderCfgs[item.id];
} else {
this.configureItem(item);
itemConfig = item.getRenderTree();
if (renderCfgs) {
renderCfgs[item.id] = itemConfig;
}
}
if (itemConfig) {
result.push(itemConfig);
}
}
}
}
return result;
},
finishRender: Ext.emptyFn,
finishRenderItems: function(target, items) {
var length = items.length,
i, item;
for (i = 0; i < length; i++) {
item = items[i];
if (item.rendering) {
item.finishRender(i);
}
}
},
renderChildren: function() {
var me = this,
items = me.getLayoutItems(),
target = me.getRenderTarget();
me.renderItems(items, target);
},
renderItems: function(items, target) {
var me = this,
ln = items.length,
i = 0,
item;
if (ln) {
Ext.suspendLayouts();
for (; i < ln; i++) {
item = items[i];
if (item && !item.rendered) {
me.renderItem(item, target, i);
} else if (!me.isValidParent(item, target, i)) {
me.moveItem(item, target, i);
} else {
me.configureItem(item);
}
}
Ext.resumeLayouts(true);
}
},
isValidParent: function(item, target, position) {
var targetDom = (target && target.dom) || target,
itemDom = this.getItemLayoutEl(item);
if (itemDom && targetDom) {
if (typeof position === 'number') {
position = this.getPositionOffset(position);
return itemDom === targetDom.childNodes[position];
}
return itemDom.parentNode === targetDom;
}
return false;
},
getItemLayoutEl: function(item) {
var dom = item.el ? item.el.dom : Ext.getDom(item),
parentNode = dom.parentNode,
className;
if (parentNode) {
className = parentNode.className;
if (className && className.indexOf(Ext.baseCSSPrefix + 'resizable-wrap') !== -1) {
dom = dom.parentNode;
}
}
return dom;
},
getPositionOffset: function(position) {
return position;
},
configureItem: function(item) {
item.ownerLayout = this;
},
renderItem: function(item, target, position) {
var me = this;
if (!item.rendered) {
me.configureItem(item);
item.render(target, position);
}
},
moveItem: function(item, target, position) {
target = target.dom || target;
if (typeof position === 'number') {
position = target.childNodes[position];
}
target.insertBefore(item.el.dom, position || null);
item.container = Ext.get(target);
this.configureItem(item);
},
onContentChange: function() {
this.owner.updateLayout();
return true;
},
initLayout: function() {
this.initialized = true;
},
setOwner: function(owner) {
this.owner = owner;
},
getLayoutItems: function() {
return [];
},
onAdd: function(item) {
item.ownerLayout = this;
},
onRemove: Ext.emptyFn,
onDestroy: Ext.emptyFn,
afterRemove: function(item) {
var me = this,
el = item.el,
owner = me.owner,
removeClasses;
if (item.rendered) {
removeClasses = [].concat(me.itemCls || []);
if (owner.itemCls) {
removeClasses = Ext.Array.push(removeClasses, owner.itemCls);
}
if (removeClasses.length) {
el.removeCls(removeClasses);
}
}
delete item.ownerLayout;
},
afterCollapse: function(owner, animated) {
if (animated) {
this.onContentChange(owner);
}
},
afterExpand: function(owner, animated) {
if (animated) {
this.onContentChange(owner);
}
},
destroy: function() {
var me = this,
target;
if (me.targetCls) {
target = me.getTarget();
if (target) {
target.removeCls(me.targetCls);
}
}
me.onDestroy();
},
sortWeightedItems: function(items, reverseProp) {
for (var i = 0,
length = items.length; i < length; ++i) {
items[i].$i = i;
}
Ext.Array.sort(items, function(item1, item2) {
var ret = item2.weight - item1.weight;
if (!ret) {
ret = item1.$i - item2.$i;
if (item1[reverseProp]) {
ret = -ret;
}
}
return ret;
});
for (i = 0; i < length; ++i) {
delete items[i].$i;
}
}
}, function() {
var Layout = this;
Layout.prototype.sizeModels = Layout.sizeModels = Ext.layout.SizeModel.sizeModels;
});
Ext.define('Ext.layout.container.Container', {
extend: 'Ext.layout.Layout',
alias: 'layout.container',
alternateClassName: 'Ext.layout.ContainerLayout',
mixins: [
'Ext.util.ElementContainer'
],
requires: [
'Ext.XTemplate'
],
type: 'container',
beginCollapse: Ext.emptyFn,
beginExpand: Ext.emptyFn,
animatePolicy: null,
activeItemCount: 0,
renderTpl: [
'{%this.renderBody(out,values)%}'
],
usesContainerHeight: true,
usesContainerWidth: true,
usesHeight: true,
usesWidth: true,
constructor: function() {
this.callParent(arguments);
this.mixins.elementCt.constructor.call(this);
},
destroy: function() {
this.callParent();
this.mixins.elementCt.destroy.call(this);
},
beginLayout: function(ownerContext) {
this.callParent(arguments);
ownerContext.targetContext = ownerContext.paddingContext = ownerContext.getEl('getTarget', this);
this.cacheChildItems(ownerContext);
},
beginLayoutCycle: function(ownerContext, firstCycle) {
var me = this;
me.callParent(arguments);
if (firstCycle) {
if (me.usesContainerHeight) {
++ownerContext.consumersContainerHeight;
}
if (me.usesContainerWidth) {
++ownerContext.consumersContainerWidth;
}
}
},
cacheChildItems: function(ownerContext) {
var me = this,
context, childItems, items, length, i;
if (me.needsItemSize || me.setsItemSize) {
context = ownerContext.context;
childItems = ownerContext.childItems = [];
items = ownerContext.visibleItems = me.getVisibleItems();
length = items.length;
for (i = 0; i < length; ++i) {
childItems.push(context.getCmp(items[i]));
}
}
},
cacheElements: function() {
var owner = this.owner;
this.attachChildEls(owner.el, owner);
},
calculate: function(ownerContext) {
var props = ownerContext.props,
el = ownerContext.el;
if (ownerContext.widthModel.shrinkWrap && isNaN(props.width)) {
ownerContext.setContentWidth(el.getWidth());
}
if (ownerContext.heightModel.shrinkWrap && isNaN(props.height)) {
ownerContext.setContentHeight(el.getHeight());
}
},
configureItem: function(item) {
var me = this,
itemCls = me.itemCls,
ownerItemCls = me.owner.itemCls,
needsCopy, addClasses;
item.ownerLayout = me;
if (itemCls) {
if (typeof itemCls === 'string') {
addClasses = [
itemCls
];
} else {
addClasses = itemCls;
needsCopy = !!addClasses;
}
}
if (ownerItemCls) {
if (needsCopy) {
addClasses = Ext.Array.clone(addClasses);
}
addClasses = Ext.Array.push(addClasses || [], ownerItemCls);
}
if (addClasses) {
item.addCls(addClasses);
}
},
doRenderBody: function(out, renderData) {
this.renderItems(out, renderData);
this.renderContent(out, renderData);
},
doRenderContainer: function(out, renderData) {
var me = renderData.$comp.layout,
tpl = me.getRenderTpl(),
data = me.getRenderData();
tpl.applyOut(data, out);
},
doRenderItems: function(out, renderData) {
var me = renderData.$layout,
tree = me.getRenderTree();
if (tree) {
Ext.DomHelper.generateMarkup(tree, out);
}
},
finishRender: function() {
var me = this,
target, items;
me.callParent();
me.cacheElements();
target = me.getRenderTarget();
items = me.getLayoutItems();
me.finishRenderItems(target, items);
},
notifyOwner: function() {
if (!this._hasTargetWarning && this.targetCls && !this.getTarget().hasCls(this.targetCls)) {
this._hasTargetWarning = true;
Ext.log.warn('targetCls is missing. This may mean that getTargetEl() is being overridden but not applyTargetCls(). ' + this.owner.id);
}
this.owner.afterLayout(this);
},
getContainerSize: function(ownerContext, inDom) {
var targetContext = ownerContext.targetContext,
frameInfo = targetContext.getFrameInfo(),
padding = ownerContext.paddingContext.getPaddingInfo(),
got = 0,
needed = 0,
gotWidth, gotHeight, width, height;
if (!ownerContext.widthModel.shrinkWrap) {
++needed;
width = inDom ? targetContext.getDomProp('width') : targetContext.getProp('width');
gotWidth = (typeof width === 'number');
if (gotWidth) {
++got;
width -= frameInfo.width + padding.width;
if (width < 0) {
width = 0;
}
}
}
if (!ownerContext.heightModel.shrinkWrap) {
++needed;
height = inDom ? targetContext.getDomProp('height') : targetContext.getProp('height');
gotHeight = (typeof height === 'number');
if (gotHeight) {
++got;
height -= frameInfo.height + padding.height;
if (height < 0) {
height = 0;
}
}
}
return {
width: width,
height: height,
needed: needed,
got: got,
gotAll: got === needed,
gotWidth: gotWidth,
gotHeight: gotHeight
};
},
getPositionOffset: function(position) {
if (!this.createsInnerCt) {
var offset = this.owner.itemNodeOffset;
if (offset) {
position += offset;
}
}
return position;
},
getLayoutItems: function() {
var owner = this.owner,
items = owner && owner.items;
return (items && items.items) || [];
},
getRenderData: function() {
var comp = this.owner;
return {
$comp: comp,
$layout: this,
ownerId: comp.id
};
},
getRenderedItems: function() {
var me = this,
target = me.getRenderTarget(),
items = me.getLayoutItems(),
ln = items.length,
renderedItems = [],
i, item;
for (i = 0; i < ln; i++) {
item = items[i];
if (item.rendered && me.isValidParent(item, target, i)) {
renderedItems.push(item);
}
}
return renderedItems;
},
getRenderTarget: function() {
return this.owner.getTargetEl();
},
getElementTarget: function() {
return this.getRenderTarget();
},
getRenderTpl: function() {
var me = this,
renderTpl = Ext.XTemplate.getTpl(this, 'renderTpl');
if (!renderTpl.renderContent) {
me.owner.setupRenderTpl(renderTpl);
}
return renderTpl;
},
getRenderTree: function() {
var result,
items = this.owner.items,
itemsGen,
renderCfgs = {};
do {
itemsGen = items.generation;
result = this.getItemsRenderTree(this.getLayoutItems(), renderCfgs);
} while (items.generation !== itemsGen);
return result;
},
renderChildren: function() {
var me = this,
ownerItems = me.owner.items,
target = me.getRenderTarget(),
itemsGen, items;
do {
itemsGen = ownerItems.generation;
items = me.getLayoutItems();
me.renderItems(items, target);
} while (ownerItems.generation !== itemsGen);
},
getScrollbarsNeeded: function(width, height, contentWidth, contentHeight) {
var scrollbarSize = Ext.getScrollbarSize(),
hasWidth = typeof width === 'number',
hasHeight = typeof height === 'number',
needHorz = 0,
needVert = 0;
if (!scrollbarSize.width) {
return 0;
}
if (hasHeight && height < contentHeight) {
needVert = 2;
width -= scrollbarSize.width;
}
if (hasWidth && width < contentWidth) {
needHorz = 1;
if (!needVert && hasHeight) {
height -= scrollbarSize.height;
if (height < contentHeight) {
needVert = 2;
}
}
}
return needVert + needHorz;
},
getTarget: function() {
return this.owner.getTargetEl();
},
getVisibleItems: function() {
var target = this.getRenderTarget(),
items = this.getLayoutItems(),
ln = items.length,
visibleItems = [],
i, item;
for (i = 0; i < ln; i++) {
item = items[i];
if (item.rendered && this.isValidParent(item, target, i) && item.hidden !== true && !item.floated) {
visibleItems.push(item);
}
}
return visibleItems;
},
getMoveAfterIndex: function(after) {
return this.owner.items.indexOf(after) + 1;
},
moveItemBefore: function(item, before) {
var owner = this.owner,
items = owner.items,
index = items.indexOf(item),
toIndex;
if (item === before) {
return item;
}
if (before) {
toIndex = items.indexOf(before);
if (index > -1 && index < toIndex) {
--toIndex;
}
} else {
toIndex = items.length;
}
return owner.insert(toIndex, item);
},
setupRenderTpl: function(renderTpl) {
renderTpl.renderBody = this.doRenderBody;
renderTpl.renderContainer = this.doRenderContainer;
renderTpl.renderItems = this.doRenderItems;
},
getContentTarget: function() {
return this.owner.getDefaultContentTarget();
},
onAdd: function(item) {
if (!item.liquidLayout) {
++this.activeItemCount;
}
this.callParent([
item
]);
},
onRemove: function(item) {
if (!item.liquidLayout) {
--this.activeItemCount;
}
this.callParent([
item
]);
}
});
Ext.define('Ext.layout.container.Auto', {
alias: [
'layout.auto',
'layout.autocontainer'
],
extend: 'Ext.layout.container.Container',
type: 'autocontainer',
childEls: [
'outerCt',
'innerCt'
],
reserveScrollbar: false,
managePadding: true,
manageOverflow: false,
needsItemSize: false,
setsItemSize: false,
lastOverflowAdjust: {
width: 0,
height: 0
},
outerCtCls: Ext.baseCSSPrefix + 'autocontainer-outerCt',
innerCtCls: Ext.baseCSSPrefix + 'autocontainer-innerCt',
renderTpl: [
'<div id="{ownerId}-outerCt" data-ref="outerCt" class="{outerCtCls}" role="presentation">',
'<div id="{ownerId}-innerCt" data-ref="innerCt" style="{%this.renderPadding(out, values)%}" ',
'class="{innerCtCls}" role="presentation">',
'{%this.renderBody(out,values)%}',
'</div>',
'</div>'
],
beginLayout: function(ownerContext) {
this.callParent(arguments);
this.initContextItems(ownerContext);
},
beforeLayoutCycle: function(ownerContext) {
var comp = this.owner,
inheritedState = comp.inheritedState,
inheritedStateInner = comp.inheritedStateInner;
if (!inheritedState || inheritedState.invalid) {
inheritedState = comp.getInherited();
inheritedStateInner = comp.inheritedStateInner;
}
if (ownerContext.widthModel.shrinkWrap) {
inheritedStateInner.inShrinkWrapTable = true;
} else {
delete inheritedStateInner.inShrinkWrapTable;
}
},
beginLayoutCycle: function(ownerContext) {
var me = this,
outerCt = me.outerCt,
lastOuterCtWidth = me.lastOuterCtWidth || '',
lastOuterCtHeight = me.lastOuterCtHeight || '',
lastOuterCtTableLayout = me.lastOuterCtTableLayout || '',
state = ownerContext.state,
overflowXStyle, outerCtWidth, outerCtHeight, outerCtTableLayout, inheritedStateInner;
me.callParent(arguments);
outerCtWidth = outerCtHeight = outerCtTableLayout = '';
if (!ownerContext.widthModel.shrinkWrap) {
outerCtWidth = '100%';
inheritedStateInner = me.owner.inheritedStateInner;
overflowXStyle = me.getOverflowXStyle(ownerContext);
outerCtTableLayout = (inheritedStateInner.inShrinkWrapTable || overflowXStyle === 'auto' || overflowXStyle === 'scroll') ? '' : 'fixed';
}
if (!ownerContext.heightModel.shrinkWrap && !Ext.supports.PercentageHeightOverflowBug) {
outerCtHeight = '100%';
}
if ((outerCtWidth !== lastOuterCtWidth) || me.hasOuterCtPxWidth) {
outerCt.setStyle('width', outerCtWidth);
me.lastOuterCtWidth = outerCtWidth;
me.hasOuterCtPxWidth = false;
}
if (outerCtTableLayout !== lastOuterCtTableLayout) {
outerCt.setStyle('table-layout', outerCtTableLayout);
me.lastOuterCtTableLayout = outerCtTableLayout;
}
if ((outerCtHeight !== lastOuterCtHeight) || me.hasOuterCtPxHeight) {
outerCt.setStyle('height', outerCtHeight);
me.lastOuterCtHeight = outerCtHeight;
me.hasOuterCtPxHeight = false;
}
if (me.hasInnerCtPxHeight) {
me.innerCt.setStyle('height', '');
me.hasInnerCtPxHeight = false;
}
state.overflowAdjust = state.overflowAdjust || me.lastOverflowAdjust;
},
calculate: function(ownerContext) {
var me = this,
state = ownerContext.state,
containerSize = me.getContainerSize(ownerContext, true),
calculatedItems = state.calculatedItems || (state.calculatedItems = me.calculateItems ? me.calculateItems(ownerContext, containerSize) : true);
me.setCtSizeIfNeeded(ownerContext, containerSize);
if (calculatedItems && ownerContext.hasDomProp('containerChildrenSizeDone')) {
me.calculateContentSize(ownerContext);
if (containerSize.gotAll) {
if (me.manageOverflow && !ownerContext.state.secondPass && !me.reserveScrollbar) {
me.calculateOverflow(ownerContext, containerSize);
}
return;
}
}
me.done = false;
},
calculateContentSize: function(ownerContext) {
var me = this,
containerDimensions = ((ownerContext.widthModel.shrinkWrap ? 1 : 0) |
(ownerContext.heightModel.shrinkWrap ? 2 : 0)),
calcWidth = (containerDimensions & 1) || undefined,
calcHeight = (containerDimensions & 2) || undefined,
needed = 0,
props = ownerContext.props;
if (calcWidth) {
if (isNaN(props.contentWidth)) {
++needed;
} else {
calcWidth = undefined;
}
}
if (calcHeight) {
if (isNaN(props.contentHeight)) {
++needed;
} else {
calcHeight = undefined;
}
}
if (needed) {
if (calcWidth && !ownerContext.setContentWidth(me.measureContentWidth(ownerContext))) {
me.done = false;
}
if (calcHeight && !ownerContext.setContentHeight(me.measureContentHeight(ownerContext))) {
me.done = false;
}
}
},
calculateOverflow: function(ownerContext) {
var me = this,
width, height, scrollbarSize, scrollbars, xauto, yauto, targetEl;
xauto = (me.getOverflowXStyle(ownerContext) === 'auto');
yauto = (me.getOverflowYStyle(ownerContext) === 'auto');
if (xauto || yauto) {
scrollbarSize = Ext.getScrollbarSize();
targetEl = ownerContext.overflowContext.el.dom;
scrollbars = 0;
if (targetEl.scrollWidth > targetEl.clientWidth) {
scrollbars |= 1;
}
if (targetEl.scrollHeight > targetEl.clientHeight) {
scrollbars |= 2;
}
width = (yauto && (scrollbars & 2)) ? scrollbarSize.width : 0;
height = (xauto && (scrollbars & 1)) ? scrollbarSize.height : 0;
if (width !== me.lastOverflowAdjust.width || height !== me.lastOverflowAdjust.height) {
me.done = false;
ownerContext.invalidate({
state: {
overflowAdjust: {
width: width,
height: height
},
overflowState: scrollbars,
secondPass: true
}
});
}
}
},
completeLayout: function(ownerContext) {
this.lastOverflowAdjust = ownerContext.state.overflowAdjust;
},
doRenderBody: function(out, renderData) {
var me = renderData.$layout,
XTemplate = Ext.XTemplate,
beforeBodyTpl = me.beforeBodyTpl,
afterBodyTpl = me.afterBodyTpl;
if (beforeBodyTpl) {
XTemplate.getTpl(me, 'beforeBodyTpl').applyOut(renderData, out);
}
this.renderItems(out, renderData);
this.renderContent(out, renderData);
if (afterBodyTpl) {
XTemplate.getTpl(me, 'afterBodyTpl').applyOut(renderData, out);
}
},
doRenderPadding: function(out, renderData) {
var me = renderData.$layout,
owner = renderData.$layout.owner,
padding = owner[owner.contentPaddingProperty];
if (me.managePadding && padding) {
out.push('padding:', owner.unitizeBox(padding));
}
},
finishedLayout: function(ownerContext) {
var innerCt = this.innerCt;
this.callParent(arguments);
if (Ext.isIE8) {
innerCt.repaint();
}
if (Ext.isOpera) {
innerCt.setStyle('position', 'relative');
innerCt.dom.scrollWidth;
innerCt.setStyle('position', '');
}
},
getContainerSize: function(ownerContext, inDom) {
var size = this.callParent(arguments),
overflowAdjust = ownerContext.state.overflowAdjust;
if (overflowAdjust) {
size.width -= overflowAdjust.width;
size.height -= overflowAdjust.height;
}
return size;
},
getRenderData: function() {
var me = this,
data = me.callParent();
data.innerCtCls = me.innerCtCls;
data.outerCtCls = me.outerCtCls;
return data;
},
getRenderTarget: function() {
return this.innerCt;
},
getElementTarget: function() {
return this.innerCt;
},
getOverflowXStyle: function(ownerContext) {
return ownerContext.overflowXStyle || (ownerContext.overflowXStyle = this.owner.scrollFlags.overflowX || ownerContext.overflowContext.getStyle('overflow-x'));
},
getOverflowYStyle: function(ownerContext) {
return ownerContext.overflowYStyle || (ownerContext.overflowYStyle = this.owner.scrollFlags.overflowY || ownerContext.overflowContext.getStyle('overflow-y'));
},
initContextItems: function(ownerContext) {
var me = this,
target = ownerContext.target,
overflowEl = me.owner.getOverflowEl();
ownerContext.outerCtContext = ownerContext.getEl('outerCt', me);
ownerContext.innerCtContext = ownerContext.getEl('innerCt', me);
ownerContext.overflowContext = (overflowEl === ownerContext.el) ? ownerContext : ownerContext.getEl(overflowEl);
if (target[target.contentPaddingProperty] !== undefined) {
ownerContext.paddingContext = ownerContext.innerCtContext;
}
},
initLayout: function() {
var me = this,
scrollbarWidth = Ext.getScrollbarSize().width,
owner = me.owner;
me.callParent();
if (scrollbarWidth && me.manageOverflow && !me.hasOwnProperty('lastOverflowAdjust')) {
if (owner.scrollable || me.reserveScrollbar) {
me.lastOverflowAdjust = {
width: scrollbarWidth,
height: 0
};
}
}
},
measureContentHeight: function(ownerContext) {
var contentHeight = this.outerCt.getHeight(),
target = ownerContext.target;
if (this.managePadding && (target[target.contentPaddingProperty] === undefined)) {
contentHeight += ownerContext.targetContext.getPaddingInfo().height;
}
return contentHeight;
},
measureContentWidth: function(ownerContext) {
var dom, style, old, contentWidth, target;
if (this.chromeCellMeasureBug) {
dom = this.innerCt.dom;
style = dom.style;
old = style.display;
if (old === 'table-cell') {
style.display = '';
dom.offsetWidth;
style.display = old;
}
}
if (Ext.isSafari) {
dom = this.outerCt.dom;
style = dom.style;
style.display = 'table-cell';
dom.offsetWidth;
dom.style.display = '';
}
contentWidth = this.outerCt.getWidth();
target = ownerContext.target;
if (this.managePadding && (target[target.contentPaddingProperty] === undefined)) {
contentWidth += ownerContext.targetContext.getPaddingInfo().width;
}
return contentWidth;
},
setCtSizeIfNeeded: function(ownerContext, containerSize) {
var me = this,
height = containerSize.height,
padding = ownerContext.paddingContext.getPaddingInfo(),
targetEl = me.getTarget(),
overflowXStyle = me.getOverflowXStyle(ownerContext),
canOverflowX = (overflowXStyle === 'auto' || overflowXStyle === 'scroll'),
scrollbarSize = Ext.getScrollbarSize(),
needsOuterHeight, needsInnerHeight;
if (height && !ownerContext.heightModel.shrinkWrap) {
if (Ext.supports.PercentageHeightOverflowBug) {
needsOuterHeight = true;
}
if (Ext.isIE8) {
needsInnerHeight = true;
}
if ((needsOuterHeight || needsInnerHeight) && canOverflowX && (targetEl.dom.scrollWidth > targetEl.dom.clientWidth)) {
height = Math.max(height - scrollbarSize.height, 0);
}
if (needsOuterHeight) {
ownerContext.outerCtContext.setProp('height', height + padding.height);
me.hasOuterCtPxHeight = true;
}
if (needsInnerHeight) {
ownerContext.innerCtContext.setProp('height', height);
me.hasInnerCtPxHeight = true;
}
}
},
setupRenderTpl: function(renderTpl) {
this.callParent(arguments);
renderTpl.renderPadding = this.doRenderPadding;
},
getContentTarget: function() {
return this.innerCt;
},
getScrollerEl: function() {
return this.outerCt;
}
}, function() {
this.prototype.chromeCellMeasureBug = Ext.isChrome && Ext.chromeVersion >= 26;
});
Ext.define('Ext.ZIndexManager', {
alternateClassName: 'Ext.WindowGroup',
requires: [
'Ext.util.SorterCollection',
'Ext.util.FilterCollection',
'Ext.GlobalEvents'
],
statics: {
zBase: 9000,
activeCounter: 0
},
constructor: function(container) {
var me = this;
me.id = Ext.id(null, 'zindex-mgr-');
me.zIndexStack = new Ext.util.Collection({
sorters: {
sorterFn: function(comp1, comp2) {
var ret = (comp1.alwaysOnTop || 0) - (comp2.alwaysOnTop || 0);
if (!ret) {
ret = comp1.getActiveCounter() - comp2.getActiveCounter();
}
return ret;
}
},
filters: {
filterFn: function(comp) {
return comp.isVisible();
}
}
});
me.zIndexStack.addObserver(me);
me.front = null;
me.globalListeners = Ext.GlobalEvents.on({
hide: me.onComponentShowHide,
show: me.onComponentShowHide,
scope: me,
destroyable: true
});
if (container) {
if (container.isContainer) {
container.on('resize', me.onContainerResize, me);
me.zseed = Ext.Number.from(me.rendered ? container.getEl().getStyle('zIndex') : undefined, me.getNextZSeed());
me.targetEl = container.getTargetEl();
me.container = container;
} else
{
Ext.on('resize', me.onContainerResize, me);
me.zseed = me.getNextZSeed();
me.targetEl = Ext.get(container);
}
} else
{
me.zseed = me.getNextZSeed();
Ext.onInternalReady(function() {
Ext.on('resize', me.onContainerResize, me);
me.targetEl = Ext.getBody();
});
}
},
getId: function() {
return this.id;
},
getNextZSeed: function() {
return (Ext.ZIndexManager.zBase += 10000);
},
setBase: function(baseZIndex) {
this.zseed = baseZIndex;
return this.onCollectionSort();
},
onCollectionSort: function() {
var me = this,
oldFront = me.front,
zIndex = me.zseed,
a = me.zIndexStack.getRange(),
len = a.length,
i, comp, topModal, topVisible,
doFocus = false;
for (i = 0; i < len; i++) {
comp = a[i];
zIndex = comp.setZIndex(zIndex);
if (!comp.hidden) {
topVisible = comp;
if (comp.modal) {
topModal = comp;
}
}
}
if (topVisible !== oldFront) {
if (oldFront && !oldFront.destroying) {
oldFront.setActive(false);
}
if (topVisible) {
doFocus = topVisible.modal || ((!oldFront || oldFront.isVisible()) && ((topVisible.focusOnToFront && !topVisible.preventFocusOnActivate))) && topVisible.isFocusable(true);
topVisible.setActive(true, doFocus);
}
}
me.front = topVisible;
if (topModal) {
me.showModalMask(topModal);
} else {
me.hideModalMask();
}
return zIndex;
},
onComponentUpdate: function(comp) {
if (this.zIndexStack.contains(comp)) {
this.zIndexStack.sort();
}
},
onComponentRender: function(comp) {
this.zIndexStack.itemChanged(comp, 'hidden');
},
onComponentShowHide: function(comp) {
var zIndexStack = this.zIndexStack;
if (comp.isFloating() && !this.hidingAll && (zIndexStack.getSource() || zIndexStack).contains(comp)) {
zIndexStack.itemChanged(comp, 'hidden');
zIndexStack.sort();
}
},
register: function(comp) {
var me = this;
if (comp.zIndexManager) {
comp.zIndexManager.unregister(comp);
}
comp.zIndexManager = me;
if (!comp.rendered) {
comp.on('render', me.onComponentRender, me, {
single: true
});
}
me.zIndexStack.add(comp);
},
unregister: function(comp) {
var me = this;
delete comp.zIndexManager;
comp.un('render', me.onComponentRender, me);
me.zIndexStack.remove(comp);
me.onCollectionSort();
},
get: function(id) {
return id.isComponent ? id : this.zIndexStack.get(id);
},
bringToFront: function(comp, preventFocus) {
var me = this,
zIndexStack = me.zIndexStack,
oldFront = zIndexStack.last(),
newFront, preventFocusSetting;
comp = me.get(comp);
if (!comp || zIndexStack.find('alwaysOnTop', true)) {
return false;
}
preventFocusSetting = comp.preventFocusOnActivate;
comp.preventFocusOnActivate = preventFocus;
comp.setActiveCounter(++Ext.ZIndexManager.activeCounter);
comp.preventFocusOnActivate = preventFocusSetting;
newFront = zIndexStack.last();
return (newFront === comp && newFront !== oldFront);
},
sendToBack: function(comp) {
comp = this.get(comp);
if (comp) {
comp.setActiveCounter(0);
}
return comp || null;
},
hideAll: function() {
var all = this.zIndexStack.getRange(),
len = all.length,
i;
this.hidingAll = true;
for (i = 0; i < len; i++) {
all[i].hide();
}
this.hidingAll = false;
},
hide: function() {
var me = this,
activeElement = Ext.Element.getActiveElement(),
all = me.tempHidden = me.zIndexStack.getRange(),
len = all.length,
i, comp;
me.focusRestoreElement = null;
for (i = 0; i < len; i++) {
comp = all[i];
if (comp.el.contains(activeElement)) {
me.focusRestoreElement = activeElement;
}
comp.el.hide();
comp.hidden = true;
}
},
show: function() {
var me = this,
i,
tempHidden = me.tempHidden,
len = tempHidden ? tempHidden.length : 0,
comp;
for (i = 0; i < len; i++) {
comp = tempHidden[i];
comp.el.show();
comp.hidden = false;
comp.setPosition(comp.x, comp.y);
}
me.tempHidden = null;
if (me.focusRestoreElement) {
me.focusRestoreElement.focus();
}
},
getActive: function() {
return this.zIndexStack.last();
},
getBy: function(fn, scope) {
return this.zIndexStack.filterBy(fn, scope).getRange();
},
each: function(fn, scope) {
this.zIndexStack.each(fn, scope);
},
eachBottomUp: function(fn, scope) {
var stack = this.zIndexStack.getRange(),
i,
len = stack.length,
comp;
for (i = 0; i < len; i++) {
comp = stack[i];
if (comp.isComponent && fn.call(scope || comp, comp) === false) {
return;
}
}
},
eachTopDown: function(fn, scope) {
var stack = this.zIndexStack.getRange(),
i, comp;
for (i = stack.length; i-- > 0; ) {
comp = stack[i];
if (comp.isComponent && fn.call(scope || comp, comp) === false) {
return;
}
}
},
destroy: function() {
var me = this,
stack = me.zIndexStack.getRange(),
len = stack.length,
i;
for (i = 0; i < len; i++) {
Ext.destroy(stack[i]);
}
Ext.destroy(me.mask, me.maskShim, me.zIndexStack, me.globalListeners);
me.zIndexStack = me.container = me.targetEl = me.globalListeners = null;
},
privates: {
getMaskBox: function() {
var maskTarget = this.mask.maskTarget;
if (maskTarget.dom === document.body) {
return {
height: Math.max(document.body.scrollHeight, Ext.dom.Element.getDocumentHeight()),
width: Math.max(document.body.scrollWidth, document.documentElement.clientWidth),
x: 0,
y: 0
};
} else {
return maskTarget.getBox();
}
},
hideModalMask: function() {
var mask = this.mask,
maskShim = this.maskShim,
maskTarget, tabbableAttr;
if (mask && mask.isVisible()) {
maskTarget = mask.maskTarget;
tabbableAttr = 'data-savedtabindex-' + maskTarget.getId();
maskTarget.restoreChildrenTabbableState(tabbableAttr);
maskTarget.restoreTabbableState(tabbableAttr);
mask.maskTarget = undefined;
mask.hide();
if (maskShim) {
maskShim.hide();
}
}
},
onContainerResize: function() {
var me = this,
mask = me.mask,
maskShim = me.maskShim,
viewSize;
if (mask && mask.isVisible()) {
mask.hide();
if (maskShim) {
maskShim.hide();
}
viewSize = me.getMaskBox();
if (maskShim) {
maskShim.setSize(viewSize);
maskShim.show();
}
mask.setSize(viewSize);
mask.show();
}
},
onMaskClick: function() {
if (this.front) {
this.front.focus();
}
},
showModalMask: function(comp) {
var me = this,
compEl = comp.el,
zIndex = compEl.getStyle('zIndex') - 4,
maskTarget = comp.floatParent ? comp.floatParent.getTargetEl() : comp.container,
mask = me.mask,
shim = me.maskShim,
viewSize, tabbableAttr, tempTabbableAttr, tabbables;
if (!mask) {
me.mask = mask = Ext.getBody().createChild({
'data-sticky': true,
role: 'presentation',
cls: Ext.baseCSSPrefix + 'mask ' + Ext.baseCSSPrefix + 'border-box',
style: 'height:0;width:0'
});
mask.setVisibilityMode(Ext.Element.DISPLAY);
mask.on('click', me.onMaskClick, me);
} else {
me.hideModalMask();
}
mask.maskTarget = maskTarget;
viewSize = me.getMaskBox();
if (shim) {
shim.setStyle('zIndex', zIndex);
shim.show();
shim.setBox(viewSize);
}
mask.setStyle('zIndex', zIndex);
tabbableAttr = 'data-savedtabindex-' + maskTarget.getId();
tempTabbableAttr = tabbableAttr + '-temp';
tabbables = compEl.findTabbableElements();
if (tabbables.length) {
compEl.saveTabbableState(tempTabbableAttr);
compEl.saveChildrenTabbableState(tempTabbableAttr);
}
maskTarget.saveTabbableState(tabbableAttr);
maskTarget.saveChildrenTabbableState(tabbableAttr);
if (tabbables.length) {
compEl.restoreChildrenTabbableState(tempTabbableAttr);
compEl.restoreTabbableState(tempTabbableAttr);
}
mask.show();
mask.setBox(viewSize);
}
}
}, function() {
Ext.WindowManager = Ext.WindowMgr = new this();
});
Ext.define('Ext.container.Container', {
extend: 'Ext.Component',
xtype: 'container',
alternateClassName: [
'Ext.Container',
'Ext.AbstractContainer'
],
requires: [
'Ext.util.MixedCollection',
'Ext.layout.container.Auto',
'Ext.ZIndexManager'
],
mixins: [
'Ext.mixin.Queryable'
],
renderTpl: '{%this.renderContainer(out,values)%}',
isContainer: true,
autoDestroy: true,
defaultType: 'panel',
detachOnRemove: true,
items: undefined,
layout: 'auto',
suspendLayout: false,
_applyDefaultsOptions: {
defaults: true,
strict: false
},
ariaRole: 'presentation',
baseCls: Ext.baseCSSPrefix + 'container',
layoutCounter: 0,
add: function() {
var me = this,
args = Ext.Array.slice(arguments),
index = (typeof args[0] === 'number') ? args.shift() : -1,
layout = me.getLayout(),
needsLayout = false,
addingArray, items, i, length, item, pos, ret, instanced;
if (args.length === 1 && Ext.isArray(args[0])) {
items = args[0];
addingArray = true;
} else {
items = args;
}
if (me.rendered) {
Ext.suspendLayouts();
}
ret = items = me.prepareItems(items, true);
length = items.length;
if (!addingArray && length === 1) {
ret = items[0];
}
for (i = 0; i < length; i++) {
item = items[i];
if (!item) {
Ext.Error.raise("Cannot add null item to Container with itemId/id: " + me.getItemId());
}
if (item.isDestroyed) {
Ext.Error.raise("Cannot add destroyed item '" + item.getId() + "' to Container '" + me.getId() + "'");
}
pos = (index < 0) ? me.items.length : (index + i);
instanced = !!item.instancedCmp;
delete item.instancedCmp;
if (item.floating) {
me.floatingItems.add(item);
item.onAdded(me, pos, instanced);
delete item.initOwnerCt;
if (me.hasListeners.add) {
me.fireEvent('add', me, item, pos);
}
} else if ((!me.hasListeners.beforeadd || me.fireEvent('beforeadd', me, item, pos) !== false) && me.onBeforeAdd(item) !== false) {
me.items.insert(pos, item);
item.onAdded(me, pos, instanced);
delete item.initOwnerCt;
me.onAdd(item, pos);
layout.onAdd(item, pos);
needsLayout = true;
if (me.hasListeners.add) {
me.fireEvent('add', me, item, pos);
}
}
}
if (needsLayout) {
me.updateLayout();
}
if (me.rendered) {
Ext.resumeLayouts(true);
}
return ret;
},
onAdded: function(container, pos, instanced) {
this.callParent(arguments);
if (instanced) {
Ext.ComponentManager.markReferencesDirty();
}
},
onRemoved: function(destroying) {
var refHolder;
if (!destroying) {
refHolder = this.lookupReferenceHolder();
if (refHolder) {
Ext.ComponentManager.markReferencesDirty();
refHolder.clearReferences();
}
}
this.callParent(arguments);
},
afterComponentLayout: function() {
var floaters = this.floatingItems.items,
floaterCount = floaters.length,
i, floater;
this.callParent(arguments);
for (i = 0; i < floaterCount; i++) {
floater = floaters[i];
if (!floater.rendered && floater.autoShow) {
floater.show();
}
}
},
afterLayout: function(layout) {
var me = this,
scroller = me.getScrollable();
++me.layoutCounter;
if (scroller && me.layoutCounter > 1) {
scroller.refresh();
}
if (me.hasListeners.afterlayout) {
me.fireEvent('afterlayout', me, layout);
}
},
onDestroy: function() {
this.callParent();
this.refs = null;
},
beforeDestroy: function() {
var me = this,
items = me.items,
floatingItems = me.floatingItems,
c;
if (items) {
while ((c = items.first())) {
me.doRemove(c, true);
}
}
if (floatingItems) {
while ((c = floatingItems.first())) {
me.doRemove(c, true);
}
}
Ext.destroy(me.layout);
me.callParent();
},
beforeRender: function() {
var me = this,
layout = me.getLayout(),
targetCls;
me.preventChildDisable = true;
me.callParent();
me.preventChildDisable = false;
if (!layout.initialized) {
layout.initLayout();
}
targetCls = layout.targetCls;
if (targetCls) {
me.applyTargetCls(targetCls);
}
},
cascade: function(fn, scope, origArgs) {
var me = this,
cs = me.items ? me.items.items : [],
len = cs.length,
i = 0,
c,
args = origArgs ? origArgs.concat(me) : [
me
],
componentIndex = args.length - 1;
if (fn.apply(scope || me, args) !== false) {
for (; i < len; i++) {
c = cs[i];
if (c.cascade) {
c.cascade(fn, scope, origArgs);
} else {
args[componentIndex] = c;
fn.apply(scope || c, args);
}
}
}
return this;
},
contains: function(comp, deep) {
var result = false;
if (deep) {
this.cascade(function(c) {
if (c.contains && c.contains(comp)) {
result = true;
return false;
}
});
return result;
} else {
return this.items.contains(comp) || this.floatingItems.contains(comp);
}
},
disable: function(silent,
fromParent) {
var me = this,
wasDisabled = me.disabled,
itemsToDisable, len, i;
me.callParent([
silent,
fromParent
]);
if (!fromParent && !me.preventChildDisable && !wasDisabled) {
itemsToDisable = me.getChildItemsToDisable();
len = itemsToDisable.length;
for (i = 0; i < len; i++) {
itemsToDisable[i].disable(silent, true);
}
}
return me;
},
doLayout: function() {
this.updateLayout();
return this;
},
enable: function(silent,
fromParent) {
var me = this,
wasDisabled = me.disabled,
itemsToDisable, len, i;
me.callParent([
silent,
fromParent
]);
if (wasDisabled) {
itemsToDisable = me.getChildItemsToDisable();
len = itemsToDisable.length;
for (i = 0; i < len; i++) {
itemsToDisable[i].enable(silent, true);
}
}
return me;
},
getChildByElement: function(el, deep) {
var item, itemEl,
i = 0,
it = this.getRefItems(),
ln = it.length;
el = Ext.getDom(el);
for (; i < ln; i++) {
item = it[i];
itemEl = item.getEl();
if (itemEl && ((itemEl.dom === el) || itemEl.contains(el))) {
return (deep && item.getChildByElement) ? item.getChildByElement(el, deep) : item;
}
}
return null;
},
getComponent: function(comp) {
if (Ext.isObject(comp)) {
comp = comp.getItemId();
}
var c = this.items.get(comp);
if (!c && typeof comp !== 'number') {
c = this.floatingItems.get(comp);
}
return c;
},
getFocusEl: function() {
var delegate = this.getDefaultFocus();
if (delegate) {
return delegate;
} else if (this.focusable) {
return this.getTargetEl();
}
return undefined;
},
getLayout: function() {
var me = this,
layout = me.layout;
if (!layout || !layout.isLayout) {
me.setLayout(layout);
}
return me.layout;
},
getRefItems: function(deep) {
var me = this,
items = me.items.items,
len = items.length,
i = 0,
item,
result = [];
for (; i < len; i++) {
item = items[i];
result[result.length] = item;
if (deep && item.getRefItems) {
result.push.apply(result, item.getRefItems(true));
}
}
items = me.floatingItems.items;
len = items.length;
for (i = 0; i < len; i++) {
item = items[i];
result[result.length] = item;
if (deep && item.getRefItems) {
result.push.apply(result, item.getRefItems(true));
}
}
return result;
},
getDefaultFocus: function() {
var defaultFocus = this.defaultFocus,
result;
if (defaultFocus) {
result = this.down(defaultFocus);
}
return result;
},
initComponent: function() {
var me = this;
me.callParent();
me.getLayout();
me.constructing = true;
me.initItems();
if (me.disabled) {
me.disabled = false;
me.disable(true);
}
delete me.constructing;
},
getReferences: function() {
var ComponentManager = Ext.ComponentManager;
if (ComponentManager.referencesDirty) {
ComponentManager.fixReferences();
}
return this.refs || null;
},
lookupReference: function(key) {
var refs = this.getReferences();
return (refs && refs[key]) || null;
},
initItems: function() {
var me = this,
items = me.items;
if (!items || !items.isMixedCollection) {
me.items = new Ext.util.AbstractMixedCollection(false, me.getComponentId);
me.floatingItems = new Ext.util.MixedCollection(false, me.getComponentId);
if (items) {
if (!Ext.isArray(items)) {
items = [
items
];
}
me.add(items);
}
}
},
initInheritedState: function(inheritedState, inheritedStateInner) {
var me = this,
controller = me.controller,
layout = me.layout,
session = me.session,
viewModel = me.viewModel,
reference = me.reference,
referenceHolder = me.referenceHolder;
me.callParent([
inheritedState,
inheritedStateInner
]);
if (me.collapsed) {
inheritedState.collapsed = true;
}
if (controller) {
inheritedState.referenceHolder = controller;
referenceHolder = true;
} else if (referenceHolder) {
inheritedState.referenceHolder = me;
}
if (referenceHolder) {
inheritedState.referencePath = '';
} else if (reference && me.isParentReference) {
inheritedState.referencePath = me.referenceKey + '.';
}
if (session) {
inheritedState.session = session;
}
if (viewModel) {
inheritedState.viewModelPath = '';
} else if (reference && me.isParentReference) {
inheritedState.viewModelPath = me.viewModelKey + '.';
}
if (layout && layout.initInheritedState) {
layout.initInheritedState(inheritedState, inheritedStateInner);
}
},
insert: function(index, component) {
var compIdx;
if (component && component.isComponent) {
compIdx = this.items.indexOf(component);
if (compIdx !== -1) {
return this.move(compIdx, index);
}
}
return this.add(index, component);
},
lookupComponent: function(comp) {
if (!comp.isComponent) {
if (typeof comp === 'string') {
comp = Ext.ComponentManager.get(comp);
} else {
comp = Ext.ComponentManager.create(comp, this.defaultType);
}
}
return comp;
},
move: function(fromIdx, toIdx) {
var me = this,
items = me.items,
item;
if (fromIdx.isComponent) {
fromIdx = items.indexOf(fromIdx);
}
item = items.getAt(fromIdx);
if (fromIdx !== toIdx) {
item = items.removeAt(fromIdx);
if (item === false) {
return false;
}
toIdx = Math.min(toIdx, items.getCount());
items.insert(toIdx, item);
me.onMove(item, fromIdx, toIdx);
if (me.hasListeners.childmove) {
me.fireEvent('childmove', me, item, fromIdx, toIdx);
}
me.updateLayout();
}
return item;
},
moveBefore: function(item, before) {
if (item !== before) {
item = this.layout.moveItemBefore(item, before);
}
return item;
},
moveAfter: function(item, after) {
var layout = this.layout,
index;
if (item !== after) {
index = after ? layout.getMoveAfterIndex(after) : 0;
item = layout.moveItemBefore(item, this.items.getAt(index));
}
return item;
},
nextChild: function(child, selector) {
var me = this,
items = me.items,
childIndex = items.indexOf(child),
i = 0,
len = items.length,
result;
if (childIndex !== -1) {
if (selector) {
for (; i < len; i++) {
result = items.getAt(childIndex + i);
if (!result || Ext.ComponentQuery.is(result, selector)) {
break;
}
}
} else {
result = items.getAt(childIndex + 1);
}
if (!result && me.ownerCt) {
result = me.ownerCt.nextChild(me, selector);
}
}
return result;
},
onAdd: Ext.emptyFn,
onBeforeAdd: function(item) {
var owner = item.ownerCt;
if (owner && owner !== this) {
owner.remove(item, false);
}
},
onMove: Ext.emptyFn,
onRemove: Ext.emptyFn,
onPosition: function() {
this.callParent(arguments);
this.repositionFloatingItems();
},
onResize: function() {
this.callParent(arguments);
this.repositionFloatingItems();
},
prevChild: function(child, selector) {
var me = this,
items = me.items,
childIndex = items.indexOf(child),
i = 0,
len = items.length,
result;
if (childIndex !== -1) {
if (selector) {
for (; i < len; i++) {
result = items.getAt(childIndex - i);
if (!result || Ext.ComponentQuery.is(result, selector)) {
break;
}
}
} else {
result = items.getAt(childIndex - 1);
}
if (!result && me.ownerCt) {
result = me.ownerCt.nextChild(me, selector);
}
}
return result;
},
remove: function(component, autoDestroy) {
var me = this,
c = me.getComponent(component);
if (!arguments.length) {
Ext.log.warn("Ext.container.Container: remove takes an argument of the component to remove. cmp.remove() is incorrect usage.");
}
if (c && (!me.hasListeners.beforeremove || me.fireEvent('beforeremove', me, c) !== false)) {
me.doRemove(c, autoDestroy);
if (me.hasListeners.remove) {
me.fireEvent('remove', me, c);
}
if (!me.destroying && !c.floating) {
me.updateLayout();
}
}
return c;
},
removeAll: function(autoDestroy) {
var me = this,
removeItems = me.items.items.slice().concat(me.floatingItems.items),
items = [],
i = 0,
len = removeItems.length,
item;
Ext.suspendLayouts();
me.removingAll = true;
for (; i < len; i++) {
item = removeItems[i];
me.remove(item, autoDestroy);
if (item.ownerCt !== me) {
items.push(item);
}
}
me.removingAll = false;
Ext.resumeLayouts(!!len);
return items;
},
setLayout: function(layout) {
var me = this,
currentLayout = me.layout,
currentIsLayout = currentLayout && currentLayout.isLayout,
protoLayout, type;
if (typeof layout === 'string') {
layout = {
type: layout
};
}
type = layout.type;
if (currentIsLayout && (!type || (type === currentLayout.type))) {
delete layout.type;
currentLayout.setConfig(layout);
} else {
if (currentIsLayout) {
currentLayout.setOwner(null);
}
protoLayout = me.self.prototype.layout;
if (typeof protoLayout === 'string') {
layout.type = type || protoLayout;
} else {
Ext.merge(Ext.merge({}, protoLayout), layout);
}
layout = this.layout = Ext.Factory.layout(layout);
layout.setOwner(this);
}
if (me.rendered) {
me.updateLayout();
}
},
setActiveItem: function(item) {
return this.getLayout().setActiveItem(item);
},
privates: {
applyDefaults: function(config) {
var me = this,
defaults = me.defaults;
if (defaults) {
if (Ext.isFunction(defaults)) {
defaults = defaults.call(me, config);
}
if (Ext.isString(config)) {
config = Ext.ComponentManager.get(config);
}
if (config.isComponent) {
config.setConfig(defaults, null, me._applyDefaultsOptions);
} else {
config = me.getConfigurator().merge(me, Ext.Object.fork(defaults), config);
}
}
return config;
},
applyReference: function(reference) {
var len;
if (reference && reference.charAt(len = reference.length - 1) === '>') {
this.isParentReference = true;
reference = reference.substring(0, len);
}
if (reference && !this.validIdRe.test(reference)) {
Ext.Error.raise('Invalid reference "' + reference + '" for ' + this.getId() + ' - not a valid identifier');
}
return reference;
},
applyTargetCls: function(targetCls) {
this.layoutTargetCls = targetCls;
},
attachReference: function(component) {
var me = this,
key, refs;
if (me.destroying || me.isDestroyed) {
return;
}
refs = me.refs || (me.refs = {});
key = component.referenceKey;
if (refs[key] && refs[key] !== component) {
Ext.log.warn('Duplicate reference: "' + key + '" on ' + me.id);
}
refs[key] = component;
},
clearReference: function(component) {
var refs = this.refs,
key = component.referenceKey;
if (refs && key) {
component.viewModelKey = component.referenceKey = refs[key] = null;
}
},
clearReferences: function() {
this.refs = null;
},
detachComponent: function(component) {
Ext.getDetachedBody().appendChild(component.getEl());
},
doRemove: function(component, doDestroy) {
doDestroy = doDestroy === true || (doDestroy !== false && this.autoDestroy);
var me = this,
layout = me.layout,
hasLayout = layout && me.rendered,
isDestroying = component.destroying || doDestroy,
floating = component.floating;
if (floating) {
me.floatingItems.remove(component);
} else {
me.items.remove(component);
}
if (hasLayout && !floating) {
if (layout.running) {
Ext.Component.cancelLayout(component, isDestroying);
}
layout.onRemove(component, isDestroying);
}
component.onRemoved(isDestroying);
me.onRemove(component, isDestroying);
if (doDestroy) {
component.destroy();
} else
{
if (hasLayout && !floating) {
layout.afterRemove(component);
}
if (me.detachOnRemove && component.rendered) {
me.detachComponent(component);
}
}
},
finishRenderChildren: function() {
this.callParent();
var layout = this.getLayout();
if (layout) {
layout.finishRender();
}
},
getChildItemsToDisable: function() {
return this.query('[isFormField],[isFocusableContainer],button');
},
getComponentId: function(comp) {
return comp.getItemId && comp.getItemId();
},
getContentTarget: function() {
return this.getLayout().getContentTarget();
},
getDefaultContentTarget: function() {
return this.el;
},
getScrollerEl: function() {
return this.layout.getScrollerEl() || this.callParent();
},
prepareItems: function(items, applyDefaults) {
if (Ext.isArray(items)) {
items = items.slice();
} else {
items = [
items
];
}
var me = this,
i = 0,
len = items.length,
item;
for (; i < len; i++) {
item = items[i];
if (item == null) {
Ext.Array.erase(items, i, 1);
--i;
--len;
} else {
if (applyDefaults) {
item = this.applyDefaults(item);
}
item.initOwnerCt = me;
if (item.isComponent) {
item.instancedCmp = true;
}
items[i] = me.lookupComponent(item);
delete item.initOwnerCt;
}
}
return items;
},
repositionFloatingItems: function() {
var floaters = this.floatingItems.items,
floaterCount = floaters.length,
i, floater;
for (i = 0; i < floaterCount; i++) {
floater = floaters[i];
if (floater.el && !floater.hidden) {
floater.setPosition(floater.x, floater.y);
}
}
},
_noMargin: {
'margin-top': '',
'margin-right': '',
'margin-bottom': '',
'margin-left': ''
},
resetItemMargins: function() {
var items = this.items.items,
i = items.length,
noMargin = this._noMargin,
item;
while (i--) {
item = items[i];
item.margin$ = null;
item.el.setStyle(noMargin);
}
},
setupRenderTpl: function(renderTpl) {
this.callParent(arguments);
this.getLayout().setupRenderTpl(renderTpl);
}
}
});
Ext.define('Ext.layout.container.Editor', {
alias: 'layout.editor',
extend: 'Ext.layout.container.Container',
autoSizeDefault: {
width: 'field',
height: 'field'
},
sizePolicies: {
$: {
$: {
readsWidth: 1,
readsHeight: 1,
setsWidth: 0,
setsHeight: 0
},
boundEl: {
readsWidth: 1,
readsHeight: 0,
setsWidth: 0,
setsHeight: 1
}
},
boundEl: {
$: {
readsWidth: 0,
readsHeight: 1,
setsWidth: 1,
setsHeight: 0
},
boundEl: {
readsWidth: 0,
readsHeight: 0,
setsWidth: 1,
setsHeight: 1
}
}
},
getItemSizePolicy: function(item) {
var me = this,
autoSize = me.owner.autoSize,
key = autoSize && autoSize.width,
policy = me.sizePolicies;
policy = policy[key] || policy.$;
key = autoSize && autoSize.height;
policy = policy[key] || policy.$;
return policy;
},
calculate: function(ownerContext) {
var me = this,
owner = me.owner,
autoSize = owner.autoSize,
fieldWidth, fieldHeight;
if (autoSize === true) {
autoSize = me.autoSizeDefault;
}
if (autoSize) {
fieldWidth = me.getDimension(owner, autoSize.width, 'getWidth', owner.width);
fieldHeight = me.getDimension(owner, autoSize.height, 'getHeight', owner.height);
}
ownerContext.childItems[0].setSize(fieldWidth, fieldHeight);
ownerContext.setWidth(fieldWidth);
ownerContext.setHeight(fieldHeight);
ownerContext.setContentSize(fieldWidth || owner.field.getWidth(), fieldHeight || owner.field.getHeight());
},
getDimension: function(owner, type, getMethod, ownerSize) {
switch (type) {
case 'boundEl':
return owner.boundEl[getMethod]();
case 'field':
return undefined;
default:
return ownerSize;
}
}
});
Ext.define('Ext.Editor', {
extend: 'Ext.container.Container',
xtype: 'editor',
requires: [
'Ext.layout.container.Editor'
],
layout: 'editor',
allowBlur: true,
revertInvalid: true,
value: '',
alignment: 'c-c?',
offsets: [
0,
0
],
shadow: 'frame',
constrain: false,
swallowKeys: true,
completeOnEnter: true,
cancelOnEsc: true,
updateEl: false,
focusOnToFront: false,
baseCls: Ext.baseCSSPrefix + 'editor',
editing: false,
preventDefaultAlign: true,
specialKeyDelay: 1,
initComponent: function() {
var me = this,
field = me.field = Ext.ComponentManager.create(me.field || {}, 'textfield');
field.msgTarget = field.msgTarget || 'qtip';
me.mon(field, {
scope: me,
specialkey: me.onSpecialKey
});
if (field.grow) {
me.mon(field, 'autosize', me.onFieldAutosize, me, {
delay: 1
});
}
me.floating = {
constrain: me.constrain
};
me.items = field;
me.callParent(arguments);
},
onAdded: function(container) {
this.ownerCmp = container;
},
onFieldAutosize: function() {
this.updateLayout();
},
afterRender: function(ct, position) {
var me = this,
field = me.field,
inputEl = field.inputEl;
me.callParent(arguments);
if (inputEl) {
inputEl.dom.name = '';
if (me.swallowKeys) {
inputEl.swallowEvent([
'keypress',
'keydown'
]);
}
}
},
onSpecialKey: function(field, event) {
var me = this,
key = event.getKey(),
complete = me.completeOnEnter && key === event.ENTER,
cancel = me.cancelOnEsc && key === event.ESC,
task = me.specialKeyTask;
if (complete || cancel) {
event.stopEvent();
if (!task) {
me.specialKeyTask = task = new Ext.util.DelayedTask();
}
task.delay(me.specialKeyDelay, complete ? me.completeEdit : me.cancelEdit, me);
if (me.specialKeyDelay === 0) {
task.cancel();
if (complete) {
me.completeEdit();
} else {
me.cancelEdit();
}
}
}
me.fireEvent('specialkey', me, field, event);
},
startEdit: function(el, value) {
var me = this,
field = me.field,
dom, ownerCt, renderTo;
me.completeEdit();
me.boundEl = Ext.get(el);
dom = me.boundEl.dom;
value = Ext.isDefined(value) ? value : Ext.String.trim(dom.textContent || dom.innerText || dom.innerHTML);
if (me.fireEvent('beforestartedit', me, me.boundEl, value) !== false) {
Ext.suspendLayouts();
if (!me.rendered) {
ownerCt = me.ownerCt;
renderTo = me.renderTo || (ownerCt && ownerCt.getEl()) || Ext.getBody();
Ext.fly(renderTo).position();
me.renderTo = renderTo;
}
me.startValue = value;
me.show();
me.realign(true);
field.suspendEvents();
field.setValue(value);
field.resetOriginalValue();
field.resumeEvents();
field.focus(field.selectOnFocus ? true : [
Number.MAX_VALUE
]);
if (field.autoSize) {
field.autoSize();
}
Ext.resumeLayouts(true);
me.toggleBoundEl(false);
me.editing = true;
}
},
realign: function(autoSize) {
var me = this;
if (autoSize === true) {
me.updateLayout();
}
me.alignTo(me.boundEl, me.alignment, me.offsets);
},
completeEdit: function(remainVisible) {
var me = this,
field = me.field,
startValue = me.startValue,
value;
if (!me.editing) {
return;
}
if (field.assertValue) {
field.assertValue();
}
value = me.getValue();
if (!field.isValid()) {
if (me.revertInvalid !== false) {
me.cancelEdit(remainVisible);
}
return;
}
if (me.ignoreNoChange && !field.didValueChange(value, startValue)) {
me.onEditComplete(remainVisible);
return;
}
if (me.fireEvent('beforecomplete', me, value, startValue) !== false) {
value = me.getValue();
if (me.updateEl && me.boundEl) {
me.boundEl.setHtml(value);
}
me.onEditComplete(remainVisible);
me.fireEvent('complete', me, value, startValue);
}
},
onShow: function() {
var me = this;
me.callParent(arguments);
me.fireEvent('startedit', me, me.boundEl, me.startValue);
},
cancelEdit: function(remainVisible) {
var me = this,
startValue = me.startValue,
field = me.field,
value;
if (me.editing) {
if (field) {
value = me.editedValue = me.getValue();
field.suspendEvents();
me.setValue(startValue);
field.resumeEvents();
}
me.onEditComplete(remainVisible);
me.fireEvent('canceledit', me, value, startValue);
delete me.editedValue;
}
},
onEditComplete: function(remainVisible) {
this.editing = false;
if (remainVisible !== true) {
this.hide();
this.toggleBoundEl(true);
}
},
onFocusLeave: function(e) {
var me = this;
if (me.allowBlur === true && me.editing && me.selectSameEditor !== true) {
this.completeEdit();
}
this.callParent([
e
]);
},
onHide: function() {
var me = this,
field = me.field;
if (me.editing) {
me.completeEdit();
} else if (field.collapse) {
field.collapse();
}
me.callParent(arguments);
},
getValue: function() {
return this.field.getValue();
},
setValue: function(value) {
this.field.setValue(value);
},
toggleBoundEl: function(visible) {
if (this.hideEl !== false) {
this.boundEl.setVisible(visible);
}
},
beforeDestroy: function() {
var me = this,
task = me.specialKeyTask;
if (task) {
task.cancel();
}
me.specialKeyTask = me.field = me.boundEl = Ext.destroy(me.field);
me.callParent(arguments);
}
});
Ext.define('Ext.EventManager', {
singleton: true,
mouseLeaveRe: /(mouseout|mouseleave)/,
mouseEnterRe: /(mouseover|mouseenter)/,
addListener: function(element, eventName, fn, scope, options) {
Ext.log.warn("Ext.EventManager is deprecated. " + "Use Ext.dom.Element#addListener to attach an event listener.");
Ext.get(element).addListener(eventName, fn, scope, options);
},
onWindowResize: function(fn, scope, options) {
Ext.log.warn("Ext.EventManager is deprecated. " + "Use Ext.on('resize', fn) to attach a window resize listener.");
Ext.GlobalEvents.on('resize', fn, scope, options);
},
onWindowUnload: function(fn, scope, options) {
Ext.log.warn("Ext.EventManager is deprecated. " + "Use Ext.getWin().on('unload', fn) to attach a window unload listener.");
Ext.getWin().on('unload', fn, scope, options);
},
purgeElement: function(element, eventName) {
Ext.log.warn("Ext.EventManager is deprecated. " + "Call clearListeners() on a Ext.dom.Element to remove all listeners.");
Ext.get(element).clearListeners();
},
removeAll: function(element) {
Ext.log.warn("Ext.EventManager is deprecated. " + "Call clearListeners() on a Ext.dom.Element to remove all listeners.");
Ext.get(element).clearListeners();
},
removeListener: function(element, eventName, fn, scope, options) {
Ext.log.warn("Ext.EventManager is deprecated. " + "Use Ext.dom.Element#removeListener to remove an event listener.");
Ext.get(element).removeListener(eventName, fn, scope, options);
},
removeResizeListener: function(fn, scope) {
Ext.log.warn("Ext.EventManager is deprecated. " + "Use Ext.on('resize', fn) to detach a window resize listener.");
Ext.GlobalEvents.un('resize', fn, scope);
},
removeUnloadListener: function(fn, scope) {
Ext.log.warn("Ext.EventManager is deprecated. " + "Use Ext.getWin().un('unload', fn) to detach a window unload listener.");
Ext.getWin().un('unload', fn, scope);
},
stopEvent: function(event) {
Ext.log.warn("Ext.EventManager.stopEvent() is deprecated. " + "Call stopEvent() directly on the Ext.event.Event instance instead.");
this.stopPropagation(event);
this.preventDefault(event);
},
stopPropagation: function(event) {
Ext.log.warn("Ext.EventManager.stopPropagation() is deprecated. " + "Call stopPropagation() directly on the Ext.event.Event instance instead.");
event = event.browserEvent || event;
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
},
preventDefault: function(event) {
Ext.log.warn("Ext.EventManager.preventDefault() is deprecated. " + "Call preventDefault() directly on the Ext.event.Event instance instead.");
event = event.browserEvent || event;
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
try {
if (event.ctrlKey || event.keyCode > 111 && event.keyCode < 124) {
event.keyCode = -1;
}
} catch (e) {}
}
},
getId: function(element) {
Ext.log.warn("Ext.EventManager.getId() is deprecated. " + "Call Ext.get() to assign ids to elements.");
element = Ext.get(element);
return element.id;
},
getRelatedTarget: function(event) {
Ext.log.warn("Ext.EventManager.getRelatedTarget() is deprecated. " + "Call getRelatedTarget() directly on the Ext.event.Event instance instead.");
event = event.browserEvent || event;
var target = event.relatedTarget;
if (!target) {
if (this.mouseLeaveRe.test(event.type)) {
target = event.toElement;
} else if (this.mouseEnterRe.test(event.type)) {
target = event.fromElement;
}
}
return this.resolveTextNode(target);
},
getPageX: function(event) {
Ext.log.warn("Ext.EventManager.getPageX() is deprecated. " + "Call getX() directly on the Ext.event.Event instance instead.");
return this.getPageXY(event)[0];
},
getPageXY: function(event) {
Ext.log.warn("Ext.EventManager.getPageXY() is deprecated. " + "Call getXY() directly on the Ext.event.Event instance instead.");
event = event.browserEvent || event;
var x = event.pageX,
y = event.pageY,
docEl = document.documentElement,
body = document.body;
if (!x && x !== 0) {
x = event.clientX + (docEl && docEl.scrollLeft || body && body.scrollLeft || 0) - (docEl && docEl.clientLeft || body && body.clientLeft || 0);
y = event.clientY + (docEl && docEl.scrollTop || body && body.scrollTop || 0) - (docEl && docEl.clientTop || body && body.clientTop || 0);
}
return [
x,
y
];
},
getPageY: function(event) {
Ext.log.warn("Ext.EventManager.getPageY() is deprecated. " + "Call getY() directly on the Ext.event.Event instance instead.");
return this.getPageXY(event)[1];
},
getTarget: function(event) {
Ext.log.warn("Ext.EventManager.getTarget() is deprecated. " + "Call getTarget() directly on the Ext.event.Event instance instead.");
event = event.browserEvent || event;
return Ext.EventManager.resolveTextNode(event.target || event.srcElement);
},
resolveTextNode: Ext.isGecko ? function(node) {
if (node) {
var s = HTMLElement.prototype.toString.call(node);
if (s !== '[xpconnect wrapped native prototype]' && s !== '[object XULElement]') {
return node.nodeType === 3 ? node.parentNode : node;
}
}
} : function(node) {
return node && node.nodeType === 3 ? node.parentNode : node;
}
}, function(EventManager) {
EventManager.on = EventManager.addListener;
EventManager.un = EventManager.removeListener;
});
Ext.define('Ext.FocusManager', {
singleton: true,
alternateClassName: [
'Ext.FocusMgr'
],
enabled: true,
enable: Ext.emptyFn,
disable: Ext.emptyFn
});
Ext.define('Ext.Img', {
extend: 'Ext.Component',
alias: [
'widget.image',
'widget.imagecomponent'
],
autoEl: 'img',
baseCls: Ext.baseCSSPrefix + 'img',
src: '',
alt: '',
title: '',
imgCls: '',
ariaRole: 'img',
maskOnDisable: false,
initComponent: function() {
if (this.glyph) {
this.autoEl = 'div';
}
this.callParent();
},
getElConfig: function() {
var me = this,
autoEl = me.autoEl,
config = me.callParent(),
glyphFontFamily = Ext._glyphFontFamily,
glyph = me.glyph,
img, glyphParts;
if (autoEl === 'img' || (Ext.isObject(autoEl) && autoEl.tag === 'img')) {
img = config;
} else if (me.glyph) {
if (typeof glyph === 'string') {
glyphParts = glyph.split('@');
glyph = glyphParts[0];
glyphFontFamily = glyphParts[1] || glyphFontFamily;
}
config.html = '&#' + glyph + ';';
if (glyphFontFamily) {
config.style = config.style || {};
config.style.fontFamily = glyphFontFamily;
}
} else {
config.cn = [
img = {
tag: 'img',
role: me.ariaRole,
id: me.id + '-img'
}
];
}
if (img) {
if (me.imgCls) {
img.cls = (img.cls ? img.cls + ' ' : '') + me.imgCls;
}
img.src = me.src || Ext.BLANK_IMAGE_URL;
}
if (me.alt) {
(img || config).alt = me.alt;
}
if (me.title) {
(img || config).title = me.title;
}
return config;
},
onRender: function() {
var me = this,
autoEl = me.autoEl,
el;
me.callParent(arguments);
el = me.el;
if (autoEl === 'img' || (Ext.isObject(autoEl) && autoEl.tag === 'img')) {
me.imgEl = el;
} else {
me.imgEl = el.getById(me.id + '-img');
}
},
onDestroy: function() {
var me = this,
imgEl = me.imgEl;
if (imgEl && me.el !== imgEl) {
imgEl.destroy();
}
this.imgEl = null;
this.callParent();
},
setSrc: function(src) {
var me = this,
imgEl = me.imgEl;
me.src = src;
if (imgEl) {
imgEl.dom.src = src || Ext.BLANK_IMAGE_URL;
}
},
setGlyph: function(glyph) {
var me = this,
glyphFontFamily = Ext._glyphFontFamily,
old = me.glyph,
el = me.el,
glyphParts;
me.glyph = glyph;
if (me.rendered && glyph !== old) {
if (typeof glyph === 'string') {
glyphParts = glyph.split('@');
glyph = glyphParts[0];
glyphFontFamily = glyphParts[1] || glyphFontFamily;
}
el.dom.innerHTML = '&#' + glyph + ';';
if (glyphFontFamily) {
el.setStyle('font-family', glyphFontFamily);
}
}
}
});
Ext.define('Ext.util.StoreHolder', {
requires: [
'Ext.data.StoreManager'
],
mixinId: 'storeholder',
bindStore: function(store, initial, propertyName) {
propertyName = propertyName || 'store';
var me = this,
oldStore = initial ? null : me[propertyName];
if (store !== oldStore) {
if (oldStore) {
me.onUnbindStore(oldStore, initial, propertyName);
if (me.isComponent && propertyName === 'store' && oldStore.autoDestroy) {
oldStore.destroy();
} else {
me.unbindStoreListeners(oldStore);
}
}
if (store) {
me[propertyName] = store = Ext.data.StoreManager.lookup(store);
me.bindStoreListeners(store);
me.onBindStore(store, initial, propertyName, oldStore);
} else {
me[propertyName] = null;
}
}
return me;
},
getStore: function() {
return this.store;
},
setStore: function(store) {
this.bindStore(store);
},
unbindStoreListeners: function(store) {
var listeners = this.storeListeners;
if (listeners) {
store.un(listeners);
}
},
bindStoreListeners: function(store) {
var listeners = this.getStoreListeners(store);
if (listeners) {
listeners = Ext.apply({}, listeners);
if (!listeners.scope) {
listeners.scope = this;
}
this.storeListeners = listeners;
store.on(listeners);
}
},
getStoreListeners: Ext.emptyFn,
onUnbindStore: Ext.emptyFn,
onBindStore: Ext.emptyFn
});
Ext.define('Ext.LoadMask', {
extend: 'Ext.Component',
alias: 'widget.loadmask',
mixins: [
'Ext.util.StoreHolder'
],
uses: [
'Ext.data.StoreManager'
],
isLoadMask: true,
msg: 'Loading...',
msgCls: Ext.baseCSSPrefix + 'mask-loading',
msgWrapCls: Ext.baseCSSPrefix + 'mask-msg',
useMsg: true,
useTargetEl: false,
cls: Ext.baseCSSPrefix + 'mask',
componentCls: Ext.baseCSSPrefix + 'border-box',
ariaRole: 'status',
focusable: true,
tabIndex: 0,
autoEl: {
tag: 'div',
role: 'status'
},
childEls: [
'msgWrapEl',
'msgEl',
'msgTextEl'
],
renderTpl: [
'<div id="{id}-msgWrapEl" data-ref="msgWrapEl" class="{[values.$comp.msgWrapCls]}">',
'<div id="{id}-msgEl" data-ref="msgEl" class="{[values.$comp.msgCls]} ',
Ext.baseCSSPrefix,
'mask-msg-inner {childElCls}">',
'<div id="{id}-msgTextEl" data-ref="msgTextEl" class="',
Ext.baseCSSPrefix,
'mask-msg-text',
'{childElCls}">{msg}</div>',
'</div>',
'</div>'
],
constructor: function(config) {
var me = this,
comp;
if (arguments.length === 2) {
if (Ext.isDefined(Ext.global.console)) {
Ext.global.console.warn('Ext.LoadMask: LoadMask now uses a standard 1 arg constructor: use the target config');
}
comp = me.target = config;
config = arguments[1];
} else {
comp = config.target;
}
if (config.maskCls) {
Ext.log.warn('Ext.LoadMask property maskCls is deprecated, use msgWrapCls instead');
config.msgWrapCls = config.msgWrapCls || config.maskCls;
}
me.callParent([
config
]);
if (comp.isComponent) {
me.ownerCt = comp;
me.hidden = true;
me.renderTo = me.getMaskTarget();
me.external = me.renderTo === Ext.getBody();
me.bindComponent(comp);
} else
{
if (Ext.isDefined(Ext.global.console)) {
Ext.global.console.warn('Ext.LoadMask: LoadMask for elements has been deprecated, use Ext.dom.Element.mask & Ext.dom.Element.unmask');
}
comp = Ext.get(comp);
me.isElement = true;
me.renderTo = me.target;
}
me.render(me.renderTo);
if (me.store) {
me.bindStore(me.store, true);
}
},
initRenderData: function() {
var result = this.callParent(arguments);
result.msg = this.msg || '';
return result;
},
onRender: function() {
this.callParent(arguments);
this.maskEl = this.el;
},
bindComponent: function(comp) {
var me = this,
listeners = {
scope: this,
resize: me.sizeMask
};
if (me.external) {
listeners.added = me.onComponentAdded;
listeners.removed = me.onComponentRemoved;
if (comp.floating) {
listeners.move = me.sizeMask;
me.activeOwner = comp;
} else if (comp.ownerCt) {
me.onComponentAdded(comp.ownerCt);
}
}
me.mon(comp, listeners);
if (me.external) {
me.mon(Ext.GlobalEvents, {
show: me.onContainerShow,
hide: me.onContainerHide,
expand: me.onContainerExpand,
collapse: me.onContainerCollapse,
scope: me
});
}
},
onComponentAdded: function(owner) {
var me = this;
delete me.activeOwner;
me.floatParent = owner;
if (!owner.floating) {
owner = owner.up('[floating]');
}
if (owner) {
me.activeOwner = owner;
me.mon(owner, 'move', me.sizeMask, me);
me.mon(owner, 'tofront', me.onOwnerToFront, me);
} else {
me.preventBringToFront = true;
}
owner = me.floatParent.ownerCt;
if (me.rendered && me.isVisible() && owner) {
me.floatOwner = owner;
me.mon(owner, 'afterlayout', me.sizeMask, me, {
single: true
});
}
},
onComponentRemoved: function(owner) {
var me = this,
activeOwner = me.activeOwner,
floatOwner = me.floatOwner;
if (activeOwner) {
me.mun(activeOwner, 'move', me.sizeMask, me);
me.mun(activeOwner, 'tofront', me.onOwnerToFront, me);
}
if (floatOwner) {
me.mun(floatOwner, 'afterlayout', me.sizeMask, me);
}
delete me.activeOwner;
delete me.floatOwner;
},
afterRender: function() {
var me = this;
me.callParent(arguments);
if (Ext.isIE) {
me.el.on('mousedown', me.onMouseDown, me);
}
this.el.skipGarbageCollection = true;
},
onMouseDown: function(e) {
var el = this.el;
if (e.within(el)) {
e.preventDefault();
el.focus();
}
},
onOwnerToFront: function(owner, zIndex) {
this.el.setStyle('zIndex', zIndex + 1);
},
onContainerShow: function(container) {
if (!this.isHierarchicallyHidden()) {
this.onComponentShow();
}
},
onContainerHide: function(container) {
if (this.isHierarchicallyHidden()) {
this.onComponentHide();
}
},
onContainerExpand: function(container) {
if (!this.isHierarchicallyHidden()) {
this.onComponentShow();
}
},
onContainerCollapse: function(container) {
if (this.isHierarchicallyHidden()) {
this.onComponentHide();
}
},
onComponentHide: function() {
var me = this;
if (me.rendered && me.isVisible()) {
me.hide();
me.showNext = true;
}
},
onComponentShow: function() {
if (this.showNext) {
this.show();
}
delete this.showNext;
},
sizeMask: function() {
var me = this,
target = me.activeOwner || me.target,
boxTarget = me.external ? me.getOwner().el : me.getMaskTarget();
if (me.rendered && me.isVisible()) {
if (me.external) {
if (!me.isElement && target.floating) {
me.onOwnerToFront(target, target.el.getZIndex());
}
me.el.setSize(boxTarget.getSize()).alignTo(boxTarget, 'tl-tl');
}
me.msgWrapEl.center(me.el);
}
},
bindStore: function(store, initial) {
var me = this;
me.mixins.storeholder.bindStore.apply(me, arguments);
store = me.store;
if (store && store.isLoading()) {
me.onBeforeLoad();
}
},
getStoreListeners: function(store) {
var load = this.onLoad,
beforeLoad = this.onBeforeLoad,
result = {
cachemiss: beforeLoad,
cachefilled: {
fn: load,
buffer: 100
}
};
if (!store.loadsSynchronously()) {
result.beforeload = beforeLoad;
result.load = load;
}
return result;
},
onDisable: function() {
this.callParent(arguments);
if (this.loading) {
this.onLoad();
}
},
getOwner: function() {
return this.ownerCt || this.ownerCmp || this.floatParent;
},
getMaskTarget: function() {
var owner = this.getOwner();
if (this.isElement) {
return this.target;
}
return this.useTargetEl ? owner.getTargetEl() : (owner.getMaskTarget() || Ext.getBody());
},
onBeforeLoad: function() {
var me = this,
owner = me.getOwner(),
origin;
if (!me.disabled) {
me.loading = true;
if (owner.componentLayoutCounter) {
me.maybeShow();
} else {
origin = owner.afterComponentLayout;
owner.afterComponentLayout = function() {
owner.afterComponentLayout = origin;
origin.apply(owner, arguments);
me.maybeShow();
};
}
}
},
maybeShow: function() {
var me = this,
owner = me.getOwner();
if (!owner.isVisible(true)) {
me.showNext = true;
} else if (me.loading && owner.rendered) {
me.show();
}
},
hide: function() {
var me = this,
ownerCt = me.ownerCt;
if (me.isElement) {
ownerCt.unmask();
me.fireEvent('hide', this);
return;
}
ownerCt.enableTabbing();
ownerCt.setMasked(false);
delete me.showNext;
return me.callParent(arguments);
},
show: function() {
var me = this;
if (me.isElement) {
me.ownerCt.mask(this.useMsg ? this.msg : '', this.msgCls);
me.fireEvent('show', this);
return;
}
return me.callParent(arguments);
},
afterShow: function() {
var me = this,
ownerCt = me.ownerCt,
el = me.el;
me.loading = true;
me.callParent(arguments);
if (me.hasOwnProperty('msgWrapCls')) {
el.dom.className = me.msgWrapCls;
}
if (me.useMsg) {
me.msgTextEl.setHtml(me.msg);
} else {
me.msgEl.hide();
}
if (me.shim || Ext.useShims) {
el.enableShim(null, true);
} else {
el.disableShim();
}
ownerCt.disableTabbing();
ownerCt.setMasked(true);
el.restoreTabbableState();
if (ownerCt.containsFocus) {
me.focus();
}
me.sizeMask();
},
onLoad: function() {
this.loading = false;
this.hide();
},
beforeDestroy: function() {
this.ownerCt = null;
this.bindStore(null);
this.callParent();
},
onDestroy: function() {
var me = this;
if (me.isElement) {
me.ownerCt.unmask();
}
me.callParent();
},
privates: {
getFocusEl: function() {
return this.el;
}
}
});
Ext.define('Ext.layout.component.Component', {
extend: 'Ext.layout.Layout',
type: 'component',
isComponentLayout: true,
nullBox: {},
usesContentHeight: true,
usesContentWidth: true,
usesHeight: true,
usesWidth: true,
widthCache: {},
heightCache: {},
beginLayoutCycle: function(ownerContext, firstCycle) {
var me = this,
owner = me.owner,
ownerCtContext = ownerContext.ownerCtContext,
heightModel = ownerContext.heightModel,
widthModel = ownerContext.widthModel,
body = owner.el.dom === document.body,
lastBox = owner.lastBox || me.nullBox,
lastSize = owner.el.lastBox || me.nullBox,
dirty = !body,
isTopLevel = ownerContext.isTopLevel,
ownerLayout, v, width, height;
me.callParent([
ownerContext,
firstCycle
]);
if (firstCycle) {
if (me.usesContentWidth) {
++ownerContext.consumersContentWidth;
}
if (me.usesContentHeight) {
++ownerContext.consumersContentHeight;
}
if (me.usesWidth) {
++ownerContext.consumersWidth;
}
if (me.usesHeight) {
++ownerContext.consumersHeight;
}
if (ownerCtContext && !ownerCtContext.hasRawContent) {
ownerLayout = owner.ownerLayout;
if (ownerLayout) {
if (ownerLayout.usesWidth) {
++ownerContext.consumersWidth;
}
if (ownerLayout.usesHeight) {
++ownerContext.consumersHeight;
}
}
}
}
if (widthModel.configured) {
width = owner[widthModel.names.width];
if (isTopLevel && widthModel.calculatedFrom) {
width = lastBox.width;
}
if (!body) {
dirty = me.setWidthInDom || (firstCycle ? width !== lastSize.width : widthModel.constrained);
}
ownerContext.setWidth(width, dirty);
} else if (isTopLevel) {
if (widthModel.calculated) {
v = lastBox.width;
ownerContext.setWidth(v,
v !== lastSize.width);
}
v = lastBox.x;
ownerContext.setProp('x', v,
v !== lastSize.x);
}
if (heightModel.configured) {
height = owner[heightModel.names.height];
if (isTopLevel && heightModel.calculatedFrom) {
height = lastBox.height;
}
if (!body) {
dirty = firstCycle ? height !== lastSize.height : heightModel.constrained;
}
ownerContext.setHeight(height, dirty);
} else if (isTopLevel) {
if (heightModel.calculated) {
v = lastBox.height;
ownerContext.setHeight(v, v !== lastSize.height);
}
v = lastBox.y;
ownerContext.setProp('y', v,
v !== lastSize.y);
}
},
finishedLayout: function(ownerContext) {
var me = this,
elementChildren = ownerContext.children,
owner = me.owner,
len, i, elContext, lastBox, props;
if (elementChildren) {
len = elementChildren.length;
for (i = 0; i < len; i++) {
elContext = elementChildren[i];
elContext.el.lastBox = elContext.props;
}
}
ownerContext.previousSize = me.lastComponentSize;
me.lastComponentSize = owner.el.lastBox = props = ownerContext.props;
lastBox = owner.lastBox || (owner.lastBox = {});
lastBox.x = props.x;
lastBox.y = props.y;
lastBox.width = props.width;
lastBox.height = props.height;
lastBox.invalid = false;
me.callParent([
ownerContext
]);
},
notifyOwner: function(ownerContext) {
var me = this,
currentSize = me.lastComponentSize,
prevSize = ownerContext.previousSize,
args = [
currentSize.width,
currentSize.height,
undefined,
undefined
];
if (prevSize) {
args[2] = prevSize.width;
args[3] = prevSize.height;
}
me.owner.afterComponentLayout.apply(me.owner, args);
},
getTarget: function() {
return this.owner.el;
},
getRenderTarget: function() {
return this.owner.el;
},
cacheTargetInfo: function(ownerContext) {
var me = this,
targetInfo = me.targetInfo,
target;
if (!targetInfo) {
target = ownerContext.getEl('getTarget', me);
me.targetInfo = targetInfo = {
padding: target.getPaddingInfo(),
border: target.getBorderInfo()
};
}
return targetInfo;
},
measureAutoDimensions: function(ownerContext, dimensions) {
var me = this,
owner = me.owner,
containerLayout = owner.layout,
heightModel = ownerContext.heightModel,
widthModel = ownerContext.widthModel,
boxParent = ownerContext.boxParent,
isBoxParent = ownerContext.isBoxParent,
target = ownerContext.target,
props = ownerContext.props,
isContainer,
ret = {
gotWidth: false,
gotHeight: false,
isContainer: (isContainer = !ownerContext.hasRawContent)
},
hv = dimensions || 3,
zeroWidth, zeroHeight,
needed = 0,
got = 0,
ready, size, temp, key, cache;
if (widthModel.shrinkWrap && ownerContext.consumersContentWidth) {
++needed;
zeroWidth = !(hv & 1);
if (isContainer) {
if (zeroWidth) {
ret.contentWidth = 0;
ret.gotWidth = true;
++got;
} else if ((ret.contentWidth = ownerContext.getProp('contentWidth')) !== undefined) {
ret.gotWidth = true;
++got;
}
} else {
size = props.contentWidth;
if (typeof size === 'number') {
ret.contentWidth = size;
ret.gotWidth = true;
++got;
} else {
if (zeroWidth) {
ready = true;
} else if (!ownerContext.hasDomProp('containerChildrenSizeDone')) {
ready = false;
} else if (isBoxParent || !boxParent || boxParent.widthModel.shrinkWrap) {
ready = true;
} else {
ready = boxParent.hasDomProp('width');
}
if (ready) {
if (zeroWidth) {
temp = 0;
} else if (containerLayout && containerLayout.measureContentWidth) {
temp = containerLayout.measureContentWidth(ownerContext);
} else {
if (target.cacheWidth) {
key = target.xtype + '-' + target.ui;
cache = me.widthCache;
temp = cache[key] || (cache[key] = me.measureContentWidth(ownerContext));
} else {
temp = me.measureContentWidth(ownerContext);
}
}
if (!isNaN(ret.contentWidth = temp)) {
ownerContext.setContentWidth(temp, true);
ret.gotWidth = true;
++got;
}
}
}
}
} else if (widthModel.natural && ownerContext.consumersWidth) {
++needed;
size = props.width;
if (typeof size === 'number') {
ret.width = size;
ret.gotWidth = true;
++got;
} else {
if (isBoxParent || !boxParent) {
ready = true;
} else {
ready = boxParent.hasDomProp('width');
}
if (ready) {
if (!isNaN(ret.width = me.measureOwnerWidth(ownerContext))) {
ownerContext.setWidth(ret.width, false);
ret.gotWidth = true;
++got;
}
}
}
}
if (heightModel.shrinkWrap && ownerContext.consumersContentHeight) {
++needed;
zeroHeight = !(hv & 2);
if (isContainer) {
if (zeroHeight) {
ret.contentHeight = 0;
ret.gotHeight = true;
++got;
} else if ((ret.contentHeight = ownerContext.getProp('contentHeight')) !== undefined) {
ret.gotHeight = true;
++got;
}
} else {
size = props.contentHeight;
if (typeof size === 'number') {
ret.contentHeight = size;
ret.gotHeight = true;
++got;
} else {
if (zeroHeight) {
ready = true;
} else if (!ownerContext.hasDomProp('containerChildrenSizeDone')) {
ready = false;
} else if (owner.noWrap) {
ready = true;
} else if (!widthModel.shrinkWrap) {
ready = (ownerContext.bodyContext || ownerContext).hasDomProp('width');
}
else if (isBoxParent || !boxParent || boxParent.widthModel.shrinkWrap) {
ready = true;
} else {
ready = boxParent.hasDomProp('width');
}
if (ready) {
if (zeroHeight) {
temp = 0;
} else if (containerLayout && containerLayout.measureContentHeight) {
temp = containerLayout.measureContentHeight(ownerContext);
} else {
if (target.cacheHeight) {
key = target.xtype + '-' + target.ui;
cache = me.heightCache;
temp = cache[key] || (cache[key] = me.measureContentHeight(ownerContext));
} else {
temp = me.measureContentHeight(ownerContext);
}
}
if (!isNaN(ret.contentHeight = temp)) {
ownerContext.setContentHeight(temp, true);
ret.gotHeight = true;
++got;
}
}
}
}
} else if (heightModel.natural && ownerContext.consumersHeight) {
++needed;
size = props.height;
if (typeof size === 'number') {
ret.height = size;
ret.gotHeight = true;
++got;
} else {
if (isBoxParent || !boxParent) {
ready = true;
} else {
ready = boxParent.hasDomProp('width');
}
if (ready) {
if (!isNaN(ret.height = me.measureOwnerHeight(ownerContext))) {
ownerContext.setHeight(ret.height, false);
ret.gotHeight = true;
++got;
}
}
}
}
if (boxParent) {
ownerContext.onBoxMeasured();
}
ret.gotAll = got === needed;
return ret;
},
measureContentWidth: function(ownerContext) {
return ownerContext.el.getWidth() - ownerContext.getFrameInfo().width;
},
measureContentHeight: function(ownerContext) {
return ownerContext.el.getHeight() - ownerContext.getFrameInfo().height;
},
measureOwnerHeight: function(ownerContext) {
return ownerContext.el.getHeight();
},
measureOwnerWidth: function(ownerContext) {
return ownerContext.el.getWidth();
}
});
Ext.define('Ext.layout.component.Auto', {
alias: 'layout.autocomponent',
extend: 'Ext.layout.component.Component',
type: 'autocomponent',
setHeightInDom: false,
setWidthInDom: false,
waitForOuterHeightInDom: false,
waitForOuterWidthInDom: false,
beginLayoutCycle: function(ownerContext, firstCycle) {
var me = this,
lastWidthModel = me.lastWidthModel,
lastHeightModel = me.lastHeightModel,
el = me.owner.el;
me.callParent(arguments);
if (lastWidthModel && lastWidthModel.fixed && ownerContext.widthModel.shrinkWrap) {
el.setWidth(null);
}
if (lastHeightModel && lastHeightModel.fixed && ownerContext.heightModel.shrinkWrap) {
el.setHeight(null);
}
},
calculate: function(ownerContext) {
var me = this,
measurement = me.measureAutoDimensions(ownerContext),
heightModel = ownerContext.heightModel,
widthModel = ownerContext.widthModel,
width, height;
if (measurement.gotWidth) {
if (widthModel.shrinkWrap) {
me.publishOwnerWidth(ownerContext, measurement.contentWidth);
} else if (me.publishInnerWidth) {
me.publishInnerWidth(ownerContext, measurement.width);
}
} else if (!widthModel.auto && me.publishInnerWidth) {
width = me.waitForOuterWidthInDom ? ownerContext.getDomProp('width') : ownerContext.getProp('width');
if (width === undefined) {
me.done = false;
} else {
me.publishInnerWidth(ownerContext, width);
}
}
if (measurement.gotHeight) {
if (heightModel.shrinkWrap) {
me.publishOwnerHeight(ownerContext, measurement.contentHeight);
} else if (me.publishInnerHeight) {
me.publishInnerHeight(ownerContext, measurement.height);
}
} else if (!heightModel.auto && me.publishInnerHeight) {
height = me.waitForOuterHeightInDom ? ownerContext.getDomProp('height') : ownerContext.getProp('height');
if (height === undefined) {
me.done = false;
} else {
me.publishInnerHeight(ownerContext, height);
}
}
if (!measurement.gotAll) {
me.done = false;
}
},
calculateOwnerHeightFromContentHeight: function(ownerContext, contentHeight) {
return contentHeight + ownerContext.getFrameInfo().height;
},
calculateOwnerWidthFromContentWidth: function(ownerContext, contentWidth) {
return contentWidth + ownerContext.getFrameInfo().width;
},
publishOwnerHeight: function(ownerContext, contentHeight) {
var me = this,
owner = me.owner,
height = me.calculateOwnerHeightFromContentHeight(ownerContext, contentHeight),
constrainedHeight, dirty, heightModel;
if (isNaN(height)) {
me.done = false;
} else {
constrainedHeight = Ext.Number.constrain(height, owner.minHeight, owner.maxHeight);
if (constrainedHeight === height) {
dirty = me.setHeightInDom;
} else {
heightModel = me.sizeModels[(constrainedHeight < height) ? 'constrainedMax' : 'constrainedMin'];
height = constrainedHeight;
if (ownerContext.heightModel.calculatedFromShrinkWrap) {
ownerContext.heightModel = heightModel;
} else {
ownerContext.invalidate({
heightModel: heightModel
});
}
}
ownerContext.setHeight(height, dirty);
}
},
publishOwnerWidth: function(ownerContext, contentWidth) {
var me = this,
owner = me.owner,
width = me.calculateOwnerWidthFromContentWidth(ownerContext, contentWidth),
constrainedWidth, dirty, widthModel;
if (isNaN(width)) {
me.done = false;
} else {
constrainedWidth = Ext.Number.constrain(width, owner.minWidth, owner.maxWidth);
if (constrainedWidth === width) {
dirty = me.setWidthInDom;
} else {
widthModel = me.sizeModels[(constrainedWidth < width) ? 'constrainedMax' : 'constrainedMin'];
width = constrainedWidth;
if (ownerContext.widthModel.calculatedFromShrinkWrap) {
ownerContext.widthModel = widthModel;
} else {
ownerContext.invalidate({
widthModel: widthModel
});
}
}
ownerContext.setWidth(width, dirty);
}
}
});
Ext.define('Ext.layout.component.ProgressBar', {
alias: [
'layout.progressbar'
],
extend: 'Ext.layout.component.Auto',
type: 'progressbar',
beginLayout: function(ownerContext) {
var me = this,
i, textEls;
me.callParent(arguments);
if (!ownerContext.textEls) {
textEls = me.owner.textEl;
if (textEls.isComposite) {
ownerContext.textEls = [];
textEls = textEls.elements;
for (i = textEls.length; i--; ) {
ownerContext.textEls[i] = ownerContext.getEl(Ext.get(textEls[i]));
}
} else {
ownerContext.textEls = [
ownerContext.getEl('textEl')
];
}
}
},
calculate: function(ownerContext) {
var me = this,
i, textEls, width;
me.callParent(arguments);
if (Ext.isNumber(width = ownerContext.getProp('width'))) {
width -= ownerContext.getBorderInfo().width;
textEls = ownerContext.textEls;
for (i = textEls.length; i--; ) {
textEls[i].setWidth(width);
}
} else {
me.done = false;
}
}
});
Ext.define('Ext.ProgressBar', {
extend: 'Ext.Component',
alias: 'widget.progressbar',
requires: [
'Ext.Template',
'Ext.CompositeElement',
'Ext.TaskManager',
'Ext.layout.component.ProgressBar'
],
uses: [
'Ext.fx.Anim'
],
config: {
value: 0,
textTpl: null
},
baseCls: Ext.baseCSSPrefix + 'progress',
animate: false,
text: '',
waitTimer: null,
childEls: [
'bar'
],
defaultBindProperty: 'value',
renderTpl: [
'<tpl if="internalText">',
'<div class="{baseCls}-text {baseCls}-text-back">{text}</div>',
'</tpl>',
'<div id="{id}-bar" data-ref="bar" class="{baseCls}-bar {baseCls}-bar-{ui}" role="presentation" style="width:{percentage}%">',
'<tpl if="internalText">',
'<div class="{baseCls}-text">',
'<div>{text}</div>',
'</div>',
'</tpl>',
'</div>'
],
componentLayout: 'progressbar',
ariaRole: 'progressbar',
initRenderData: function() {
var me = this,
value = me.value || 0;
return Ext.apply(me.callParent(), {
internalText: !me.hasOwnProperty('textEl'),
text: me.text || '&#160;',
percentage: value * 100
});
},
onRender: function() {
var me = this;
me.callParent(arguments);
if (me.textEl) {
me.textEl = Ext.get(me.textEl);
me.updateText(me.text);
} else
{
me.textEl = me.el.select('.' + me.baseCls + '-text');
}
},
applyValue: function(value) {
return value || 0;
},
updateValue: function(value) {
this.updateProgress(value, Math.round(value * 100) + '%');
},
updateProgress: function(value, text, animate) {
value = value || 0;
var me = this,
oldValue = me.value,
textTpl = me.getTextTpl();
me.value = value || (value = 0);
if (text != null) {
me.updateText(text);
}
else if (textTpl) {
me.updateText(textTpl.apply({
value: value,
percent: value * 100
}));
}
if (me.rendered && !me.isDestroyed) {
if (animate === true || (animate !== false && me.animate)) {
me.bar.stopAnimation();
me.bar.animate(Ext.apply({
from: {
width: (oldValue * 100) + '%'
},
to: {
width: (value * 100) + '%'
}
}, me.animate));
} else {
me.bar.setStyle('width', (value * 100) + '%');
}
}
me.fireEvent('update', me, value, text);
return me;
},
updateText: function(text) {
var me = this;
me.text = text;
if (me.rendered) {
me.textEl.setHtml(me.text);
}
return me;
},
applyTextTpl: function(textTpl) {
if (!textTpl.isTemplate) {
textTpl = new Ext.XTemplate(textTpl);
}
return textTpl;
},
applyText: function(text) {
this.updateText(text);
},
getText: function() {
return this.text;
},
wait: function(o) {
var me = this,
scope;
if (!me.waitTimer) {
scope = me;
o = o || {};
me.updateText(o.text);
me.waitTimer = Ext.TaskManager.start({
run: function(i) {
var inc = o.increment || 10;
i -= 1;
me.updateProgress(((((i + inc) % inc) + 1) * (100 / inc)) * 0.01, null, o.animate);
},
interval: o.interval || 1000,
duration: o.duration,
onStop: function() {
if (o.fn) {
o.fn.apply(o.scope || me);
}
me.reset();
},
scope: scope
});
}
return me;
},
isWaiting: function() {
return this.waitTimer !== null;
},
reset: function(hide) {
var me = this;
me.updateProgress(0);
me.clearTimer();
if (hide === true) {
me.hide();
}
return me;
},
clearTimer: function() {
var me = this;
if (me.waitTimer) {
me.waitTimer.onStop = null;
Ext.TaskManager.stop(me.waitTimer);
me.waitTimer = null;
}
},
onDestroy: function() {
var me = this,
bar = me.bar;
me.clearTimer();
if (me.rendered) {
if (me.textEl.isComposite) {
me.textEl.clear();
}
Ext.destroyMembers(me, 'textEl', 'progressBar');
if (bar && me.animate) {
bar.stopAnimation();
}
}
me.callParent();
}
});
Ext.define('Ext.ProgressBarWidget', {
extend: 'Ext.Widget',
alias: 'widget.progressbarwidget',
requires: [
'Ext.ProgressBar'
],
config: {
text: null,
value: 0,
animate: false,
textTpl: null
},
cachedConfig: {
baseCls: Ext.baseCSSPrefix + 'progress',
textCls: Ext.baseCSSPrefix + 'progress-text',
ui: 'default'
},
template: [
{
reference: 'backgroundEl'
},
{
reference: 'barEl',
children: [
{
reference: 'textEl'
}
]
}
],
defaultBindProperty: 'value',
doSetWidth: function(width) {
var me = this;
me.callParent([
width
]);
width -= me.element.getBorderWidth('lr');
me.backgroundEl.setWidth(width);
me.textEl.setWidth(width);
},
updateUi: function(ui, oldUi) {
var element = this.element,
barEl = this.barEl,
baseCls = this.getBaseCls() + '-';
if (oldUi) {
element.removeCls(baseCls + oldUi);
barEl.removeCls(baseCls + 'bar-' + oldUi);
}
element.addCls(baseCls + ui);
barEl.addCls(baseCls + 'bar-' + ui);
},
updateBaseCls: function(baseCls, oldBaseCls) {
if (oldBaseCls) {
Ext.Error.raise('You cannot configure baseCls - use a subclass');
}
this.element.addCls(baseCls);
this.barEl.addCls(baseCls + '-bar');
},
updateTextCls: function(textCls) {
this.backgroundEl.addCls(textCls + ' ' + textCls + '-back');
this.textEl.addCls(textCls);
},
applyValue: function(value) {
return value || 0;
},
updateValue: function(value, oldValue) {
var me = this,
barEl = me.barEl,
textTpl = me.getTextTpl();
if (textTpl) {
me.setText(textTpl.apply({
value: value,
percent: Math.round(value * 100)
}));
}
if (me.getAnimate()) {
barEl.stopAnimation();
barEl.animate(Ext.apply({
from: {
width: (oldValue * 100) + '%'
},
to: {
width: (value * 100) + '%'
}
}, me.animate));
} else {
barEl.setStyle('width', (value * 100) + '%');
}
},
updateText: function(text) {
this.backgroundEl.setHtml(text);
this.textEl.setHtml(text);
},
applyTextTpl: function(textTpl) {
if (!textTpl.isTemplate) {
textTpl = new Ext.XTemplate(textTpl);
}
return textTpl;
}
});
Ext.define('Ext.panel.Bar', {
extend: 'Ext.container.Container',
vertical: false,
_verticalSides: {
left: 1,
right: 1
},
initComponent: function() {
var me = this,
vertical = me.vertical;
me.dock = me.dock || (vertical ? 'left' : 'top');
me.layout = Ext.apply(vertical ? {
type: 'vbox',
align: 'middle',
alignRoundingMethod: 'ceil'
} : {
type: 'hbox',
align: 'middle',
alignRoundingMethod: 'floor'
}, me.layout);
this.callParent();
},
onAdded: function(container, pos, instanced) {
this.initOrientation();
this.callParent([
container,
pos,
instanced
]);
},
onRemoved: function(destroying) {
this.removeClsWithUI(this.uiCls);
this.callParent([
destroying
]);
},
beforeRender: function() {
var me = this;
if (me.forceOrientation || !me.ownerCt) {
me.initOrientation();
}
me.callParent();
},
setDock: function(dock) {
var me = this,
layout, vertical;
if (dock !== me.dock) {
Ext.suspendLayouts();
me.clearOrientation();
me.callParent([
dock
]);
me.initOrientation();
vertical = me.vertical;
layout = me.layout;
layout.setVertical(vertical);
layout.setAlignRoundingMethod(vertical ? 'ceil' : 'floor');
Ext.resumeLayouts(true);
}
},
privates: {
clearOrientation: function() {
this.removeClsWithUI([
this.vertical ? 'vertical' : 'horizontal',
this.getDockName()
]);
},
getDockName: function() {
return this.dock;
},
initOrientation: function() {
var me = this,
dock = me.dock,
vertical = (me.vertical = (dock ? dock in me._verticalSides : me.vertical));
me.addClsWithUI([
vertical ? 'vertical' : 'horizontal',
me.getDockName()
]);
}
}
});
Ext.define('Ext.panel.Title', {
extend: 'Ext.Component',
xtype: 'title',
isTitle: true,
noWrap: true,
textAlign: 'left',
iconAlign: 'left',
rotation: 0,
text: '&#160;',
beforeRenderConfig: {
textAlign: null,
text: null,
glyph: null,
icon: null,
iconAlign: null,
iconCls: null,
rotation: null
},
autoEl: {
unselectable: 'on'
},
childEls: [
'textEl',
'iconEl',
'iconWrapEl'
],
renderTpl: '<tpl if="iconMarkup && iconBeforeTitle">{iconMarkup}</tpl>' +
'<div id="{id}-textEl" data-ref="textEl" class="{textCls} {textCls}-{ui} {itemCls}{childElCls}" unselectable="on"' + '<tpl if="headerRole">' + ' role="{headerRole}"' + '</tpl>' + '>{text}</div>' + '<tpl if="iconMarkup && !iconBeforeTitle">{iconMarkup}</tpl>',
iconTpl: '<div id="{id}-iconWrapEl" data-ref="iconWrapEl" role="presentation" ' + 'class="{iconWrapCls} {iconWrapCls}-{ui} {iconAlignCls} {itemCls}{childElCls}"' + '<tpl if="iconWrapStyle"> style="{iconWrapStyle}"</tpl>>' + '<div id="{id}-iconEl" data-ref="iconEl" role="presentation" unselectable="on" ' + 'class="{baseIconCls} {baseIconCls}-{ui} {iconCls} {glyphCls}" style="' + '<tpl if="iconUrl">background-image:url({iconUrl});</tpl>' + '<tpl if="glyph && glyphFontFamily">font-family:{glyphFontFamily};</tpl>">' + '<tpl if="glyph">&#{glyph};</tpl><tpl if="iconCls || iconUrl">&#160;</tpl>' + '</div>' + '</div>',
_textAlignClasses: {
left: Ext.baseCSSPrefix + 'title-align-left',
center: Ext.baseCSSPrefix + 'title-align-center',
right: Ext.baseCSSPrefix + 'title-align-right'
},
_iconAlignClasses: {
top: Ext.baseCSSPrefix + 'title-icon-top',
right: Ext.baseCSSPrefix + 'title-icon-right',
bottom: Ext.baseCSSPrefix + 'title-icon-bottom',
left: Ext.baseCSSPrefix + 'title-icon-left'
},
_rotationClasses: {
0: Ext.baseCSSPrefix + 'title-rotate-none',
1: Ext.baseCSSPrefix + 'title-rotate-right',
2: Ext.baseCSSPrefix + 'title-rotate-left'
},
_rotationAngles: {
1: 90,
2: 270
},
baseCls: Ext.baseCSSPrefix + 'title',
_titleSuffix: '-title',
_glyphCls: Ext.baseCSSPrefix + 'title-glyph',
_iconWrapCls: Ext.baseCSSPrefix + 'title-icon-wrap',
_baseIconCls: Ext.baseCSSPrefix + 'title-icon',
_itemCls: Ext.baseCSSPrefix + 'title-item',
_textCls: Ext.baseCSSPrefix + 'title-text',
afterComponentLayout: function() {
var me = this,
rotation = me.getRotation(),
lastBox, lastX, el;
if (rotation && !Ext.isIE8) {
el = me.el;
lastBox = me.lastBox;
lastX = lastBox.x;
el.setStyle(me._getVerticalAdjustDirection(), (lastX + ((rotation === 1) ? lastBox.width : -lastBox.height)) + 'px');
}
this.callParent();
},
onRender: function() {
var me = this,
rotation = me.getRotation(),
el = me.el;
me.callParent();
if (rotation) {
el.setVertical(me._rotationAngles[rotation]);
}
if (Ext.supports.FixedTableWidthBug) {
el._needsTableWidthFix = true;
}
},
applyText: function(text) {
if (!text) {
text = '&#160;';
}
return text;
},
beforeRender: function() {
var me = this;
me.callParent();
me.addCls(me._rotationClasses[me.getRotation()]);
me.addCls(me._textAlignClasses[me.getTextAlign()]);
},
getIconMarkup: function() {
return this.getTpl('iconTpl').apply(this.getIconRenderData());
},
getIconRenderData: function() {
var me = this,
icon = me.getIcon(),
iconCls = me.getIconCls(),
glyph = me.getGlyph(),
glyphFontFamily = Ext._glyphFontFamily,
iconAlign = me.getIconAlign(),
glyphParts;
if (typeof glyph === 'string') {
glyphParts = glyph.split('@');
glyph = glyphParts[0];
glyphFontFamily = glyphParts[1];
}
return {
id: me.id,
ui: me.ui,
itemCls: me._itemCls,
iconUrl: icon,
iconCls: iconCls,
iconWrapCls: me._iconWrapCls,
baseIconCls: me._baseIconCls,
iconAlignCls: me._iconAlignClasses[iconAlign],
glyph: glyph,
glyphCls: glyph ? me._glyphCls : '',
glyphFontFamily: glyphFontFamily
};
},
initRenderData: function() {
var me = this,
iconAlign, renderData;
renderData = Ext.apply({
text: me.getText(),
headerRole: me.headerRole,
id: me.id,
ui: me.ui,
itemCls: me._itemCls,
textCls: me._textCls,
iconMarkup: null,
iconBeforeTitle: null
}, me.callParent());
if (me._hasIcon()) {
iconAlign = me.getIconAlign();
renderData.iconMarkup = me.getIconMarkup();
renderData.iconBeforeTitle = (iconAlign === 'top' || iconAlign === 'left');
}
return renderData;
},
onAdded: function(container, pos, instanced) {
var me = this,
suffix = me._titleSuffix,
baseCls = container.baseCls;
me.addCls([
baseCls + suffix,
baseCls + suffix + '-' + container.ui
]);
me.callParent([
container,
pos,
instanced
]);
},
updateGlyph: function(glyph, oldGlyph) {
glyph = glyph || 0;
var me = this,
glyphCls = me._glyphCls,
iconEl, fontFamily, glyphParts;
me.glyph = glyph;
if (me.rendered) {
me._syncIconVisibility();
iconEl = me.iconEl;
if (typeof glyph === 'string') {
glyphParts = glyph.split('@');
glyph = glyphParts[0];
fontFamily = glyphParts[1] || Ext._glyphFontFamily;
}
if (!glyph) {
iconEl.dom.innerHTML = '';
iconEl.removeCls(glyphCls);
} else if (oldGlyph !== glyph) {
iconEl.dom.innerHTML = '&#' + glyph + ';';
iconEl.addCls(glyphCls);
}
if (fontFamily) {
iconEl.setStyle('font-family', fontFamily);
}
if (me._didIconStateChange(oldGlyph, glyph)) {
me.updateLayout();
}
}
},
updateIcon: function(icon, oldIcon) {
icon = icon || '';
var me = this,
iconEl;
if (me.rendered && icon !== oldIcon) {
me._syncIconVisibility();
iconEl = me.iconEl;
iconEl.setStyle('background-image', icon ? 'url(' + icon + ')' : '');
if (me._didIconStateChange(oldIcon, icon)) {
me.updateLayout();
}
}
},
updateIconAlign: function(align, oldAlign) {
var me = this,
iconWrapEl = me.iconWrapEl,
el, iconAlignClasses;
if (me.iconWrapEl) {
el = me.el;
iconAlignClasses = me._iconAlignClasses;
if (oldAlign) {
iconWrapEl.removeCls(iconAlignClasses[oldAlign]);
}
iconWrapEl.addCls(iconAlignClasses[align]);
if (align === 'top' || align === 'left') {
el.insertFirst(iconWrapEl);
} else {
el.appendChild(iconWrapEl);
}
me.updateLayout();
}
},
updateIconCls: function(cls, oldCls) {
cls = cls || '';
var me = this,
iconEl;
if (me.rendered && oldCls !== cls) {
me._syncIconVisibility();
iconEl = me.iconEl;
if (oldCls) {
iconEl.removeCls(oldCls);
}
iconEl.addCls(cls);
if (me._didIconStateChange(oldCls, cls)) {
me.updateLayout();
}
}
},
updateRotation: function(rotation, oldRotation) {
var me = this,
el, rotationClasses;
if (me.rendered) {
el = me.el;
rotationClasses = me._rotationClasses;
me.removeCls(rotationClasses[oldRotation]);
me.addCls(rotationClasses[rotation]);
el.setHorizontal();
if (rotation) {
el.setVertical(me._rotationAngles[rotation]);
}
el.setStyle({
right: '',
left: '',
top: '',
height: '',
width: ''
});
me.lastBox = null;
me.updateLayout();
}
},
updateText: function(text) {
if (this.rendered) {
this.textEl.setHtml(text);
this.updateLayout();
}
},
updateTextAlign: function(align, oldAlign) {
var me = this,
textAlignClasses = me._textAlignClasses;
if (me.rendered) {
if (oldAlign) {
me.removeCls(textAlignClasses[oldAlign]);
}
me.addCls(textAlignClasses[align]);
me.updateLayout();
}
},
privates: {
_getVerticalAdjustDirection: function() {
return 'left';
},
_didIconStateChange: function(old, current) {
var currentEmpty = Ext.isEmpty(current);
return Ext.isEmpty(old) ? !currentEmpty : currentEmpty;
},
_hasIcon: function() {
return !!(this.getIcon() || this.getIconCls() || this.getGlyph());
},
_syncIconVisibility: function() {
var me = this,
el = me.el,
hasIcon = me._hasIcon(),
iconWrapEl = me.iconWrapEl,
isBefore, iconAlign;
if (hasIcon && !iconWrapEl) {
iconAlign = me.iconAlign;
isBefore = (iconAlign === 'left' || iconAlign === 'top');
el.dom.insertAdjacentHTML(isBefore ? 'afterbegin' : 'beforeend', me.getIconMarkup());
iconWrapEl = me.iconWrapEl = el[isBefore ? 'first' : 'last']();
me.iconEl = iconWrapEl.first();
}
if (iconWrapEl) {
iconWrapEl.setDisplayed(hasIcon);
}
}
}
});
Ext.define('Ext.panel.Tool', {
extend: 'Ext.Component',
uses: [
'Ext.tip.QuickTipManager'
],
xtype: 'tool',
isTool: true,
focusable: true,
baseCls: Ext.baseCSSPrefix + 'tool',
disabledCls: Ext.baseCSSPrefix + 'tool-disabled',
toolPressedCls: Ext.baseCSSPrefix + 'tool-pressed',
toolOverCls: Ext.baseCSSPrefix + 'tool-over',
ariaRole: 'button',
childEls: [
'toolEl'
],
renderTpl: [
'<img id="{id}-toolEl" data-ref="toolEl" src="{blank}" class="{baseCls}-img {baseCls}-{type}' + '{childElCls}" role="presentation"/>'
],
toolOwner: null,
tooltipType: 'qtip',
stopEvent: true,
cacheHeight: true,
cacheWidth: true,
_toolTypes: {
close: 1,
collapse: 1,
down: 1,
expand: 1,
gear: 1,
help: 1,
left: 1,
maximize: 1,
minimize: 1,
minus: 1,
next: 1,
pin: 1,
plus: 1,
prev: 1,
print: 1,
refresh: 1,
restore: 1,
right: 1,
save: 1,
search: 1,
toggle: 1,
unpin: 1,
up: 1
},
initComponent: function() {
var me = this;
if (me.id && me._toolTypes[me.id]) {
Ext.Error.raise('When specifying a tool you should use the type option, the id can conflict now that tool is a Component');
}
me.type = me.type || me.id;
Ext.applyIf(me.renderData, {
baseCls: me.baseCls,
blank: Ext.BLANK_IMAGE_URL,
type: me.type
});
me.tooltip = me.tooltip || me.qtip;
me.callParent();
},
afterRender: function() {
var me = this,
tip;
me.callParent(arguments);
me.el.on({
click: me.onClick,
mousedown: me.onMouseDown,
mouseover: me.onMouseOver,
mouseout: me.onMouseOut,
scope: me
});
tip = me.tooltip;
if (tip) {
me.setTooltip(tip);
}
},
tipAttrs: {
qtip: 'data-qtip'
},
setTooltip: function(tooltip, type) {
var me = this,
oldTip = me.tooltip,
oldType = me.tooltipType,
id = me.id,
el = me.el,
attr;
if (oldTip && Ext.quickTipsActive && Ext.isObject(oldTip)) {
Ext.tip.QuickTipManager.unregister(id);
}
me.tooltip = tooltip;
if (type) {
me.tooltipType = type;
}
if (tooltip) {
if (Ext.quickTipsActive && Ext.isObject(tooltip)) {
Ext.tip.QuickTipManager.register(Ext.apply({
target: id
}, tooltip));
} else if (el) {
if (type && oldType && type !== oldType) {
attr = me.tipAttrs[oldType] || 'title';
el.dom.removeAttribute(attr);
}
attr = me.tipAttrs[type || oldType] || 'title';
el.dom.setAttribute(attr, tooltip);
}
}
},
setType: function(type) {
var me = this,
oldType = me.type;
me.type = type;
if (me.rendered) {
if (oldType) {
me.toolEl.removeCls(me.baseCls + '-' + oldType);
}
me.toolEl.addCls(me.baseCls + '-' + type);
} else {
me.renderData.type = type;
}
return me;
},
onDestroy: function() {
var me = this,
keyMap = me.keyMap;
me.setTooltip(null);
if (keyMap) {
keyMap.destroy();
me.keyMap = null;
}
delete me.toolOwner;
me.callParent();
},
privates: {
getFocusEl: function() {
return this.el;
},
onClick: function(e, target) {
var me = this;
if (me.disabled) {
return false;
}
me.el.removeCls(me.toolPressedCls + ' ' + me.toolOverCls);
if (me.stopEvent !== false) {
e.stopEvent();
}
if (me.handler) {
Ext.callback(me.handler, me.scope, [
e,
target,
me.ownerCt,
me
], 0, me);
} else if (me.callback) {
Ext.callback(me.callback, me.scope, [
me.toolOwner || me.ownerCt,
me,
e
], 0, me);
}
me.fireEvent('click', me, e, me.toolOwner || me.ownerCt);
return true;
},
onMouseDown: function() {
if (this.disabled) {
return false;
}
this.el.addCls(this.toolPressedCls);
},
onMouseOver: function() {
if (this.disabled) {
return false;
}
this.el.addCls(this.toolOverCls);
},
onMouseOut: function() {
this.el.removeCls(this.toolOverCls);
}
}
});
Ext.define('Ext.panel.Header', {
extend: 'Ext.panel.Bar',
requires: [
'Ext.panel.Title',
'Ext.panel.Tool'
],
xtype: 'header',
isHeader: true,
defaultType: 'tool',
indicateDrag: false,
weight: -1,
shrinkWrap: 3,
iconAlign: 'left',
titleAlign: 'left',
titlePosition: 0,
titleRotation: 'default',
beforeRenderConfig: {
glyph: null,
icon: null,
iconCls: null,
iconAlign: null,
title: {
$value: {
ariaRole: 'presentation',
xtype: 'title',
flex: 1
},
merge: function(newValue, oldValue) {
if (typeof newValue === 'string') {
newValue = {
text: newValue
};
}
return Ext.merge(oldValue ? Ext.Object.chain(oldValue) : {}, newValue);
}
},
titleAlign: null,
titlePosition: null,
titleRotation: null
},
headerCls: Ext.baseCSSPrefix + 'header',
initComponent: function() {
var me = this,
items = me.items,
itemPosition = me.itemPosition,
cls = [
me.headerCls
];
me.tools = me.tools || [];
me.items = items = (items ? items.slice() : []);
if (itemPosition !== undefined) {
me._userItems = items.slice();
me.items = items = [];
}
me.indicateDragCls = me.headerCls + '-draggable';
if (me.indicateDrag) {
cls.push(me.indicateDragCls);
}
me.addCls(cls);
me.syncNoBorderCls();
Ext.Array.push(items, me.tools);
me.tools.length = 0;
me.callParent();
me.on({
dblclick: me.onDblClick,
click: me.onClick,
element: 'el',
scope: me
});
},
addTool: function(tool) {
this.add(Ext.ComponentManager.create(tool, 'tool'));
},
afterLayout: function() {
var me = this,
frameBR, frameTR, frameTL, xPos;
if (me.vertical) {
frameTR = me.frameTR;
if (frameTR) {
frameBR = me.frameBR;
frameTL = me.frameTL;
xPos = (me.getWidth() - frameTR.getPadding('r') - ((frameTL) ? frameTL.getPadding('l') : me.el.getBorderWidth('l'))) + 'px';
frameBR.setStyle('background-position-x', xPos);
frameTR.setStyle('background-position-x', xPos);
}
}
this.callParent();
},
applyTitle: function(title, oldTitle) {
var me = this,
isString, configHasRotation;
title = title || '';
isString = typeof title === 'string';
if (isString) {
title = {
text: title
};
}
if (oldTitle) {
Ext.suspendLayouts();
oldTitle.setConfig(title);
Ext.resumeLayouts(true);
title = oldTitle;
} else {
if (isString) {
title.xtype = 'title';
}
title.ui = me.ui;
title.headerRole = me.headerRole;
configHasRotation = ('rotation' in title);
title = Ext.create(title);
if (!configHasRotation && me.vertical && me.titleRotation === 'default') {
title.rotation = 1;
}
}
return title;
},
applyTitlePosition: function(position) {
var max = this.items.getCount();
if (this._titleInItems) {
--max;
}
return Math.max(Math.min(position, max), 0);
},
beforeLayout: function() {
this.callParent();
this.syncBeforeAfterTitleClasses();
},
beforeRender: function() {
var me = this,
itemPosition = me.itemPosition;
me.protoEl.unselectable();
me.callParent();
if (itemPosition !== undefined) {
me.insert(itemPosition, me._userItems);
}
},
getTools: function() {
return this.tools.slice();
},
onAdd: function(component, index) {
var tools = this.tools;
this.callParent([
component,
index
]);
if (component.isTool) {
tools.push(component);
tools[component.type] = component;
}
},
onAdded: function(container, pos, instanced) {
this.syncNoBorderCls();
this.callParent([
container,
pos,
instanced
]);
},
onRemoved: function(container, pos, instanced) {
this.syncNoBorderCls();
this.callParent([
container,
pos,
instanced
]);
},
setDock: function(dock) {
var me = this,
title = me.getTitle(),
rotation = me.getTitleRotation(),
titleRotation = title.getRotation();
Ext.suspendLayouts();
me.callParent([
dock
]);
if (rotation === 'default') {
rotation = (me.vertical ? 1 : 0);
if (rotation !== titleRotation) {
title.setRotation(rotation);
}
if (me.rendered) {
me.resetItemMargins();
}
}
Ext.resumeLayouts(true);
},
updateGlyph: function(glyph) {
this.getTitle().setGlyph(glyph);
},
updateIcon: function(icon) {
this.getTitle().setIcon(icon);
},
updateIconAlign: function(align, oldAlign) {
this.getTitle().setIconAlign(align);
},
updateIconCls: function(cls) {
this.getTitle().setIconCls(cls);
},
updateTitle: function(title, oldTitle) {
if (!oldTitle) {
this.insert(this.getTitlePosition(), title);
this._titleInItems = true;
}
this.titleCmp = title;
},
updateTitleAlign: function(align, oldAlign) {
this.getTitle().setTextAlign(align);
},
updateTitlePosition: function(position) {
this.insert(position, this.getTitle());
},
updateTitleRotation: function(rotation) {
if (rotation === 'default') {
rotation = (this.vertical ? 1 : 0);
}
this.getTitle().setRotation(rotation);
},
privates: {
fireClickEvent: function(type, e) {
var toolCls = '.' + Ext.panel.Tool.prototype.baseCls;
if (!e.getTarget(toolCls)) {
this.fireEvent(type, this, e);
}
},
getFocusEl: function() {
return this.el;
},
getFramingInfoCls: function() {
var me = this,
cls = me.callParent(),
owner = me.ownerCt;
if (!me.expanding && owner && (owner.collapsed || me.isCollapsedExpander)) {
cls += '-' + owner.collapsedCls;
}
return cls + '-' + me.dock;
},
onClick: function(e) {
this.fireClickEvent('click', e);
},
onDblClick: function(e) {
this.fireClickEvent('dblclick', e);
},
syncBeforeAfterTitleClasses: function(force) {
var me = this,
items = me.items,
childItems = items.items,
titlePosition = me.getTitlePosition(),
itemCount = childItems.length,
itemGeneration = items.generation,
syncGen = me.syncBeforeAfterGen,
afterCls, beforeCls, i, item;
if (!force && (syncGen === itemGeneration)) {
return;
}
me.syncBeforeAfterGen = itemGeneration;
for (i = 0; i < itemCount; ++i) {
item = childItems[i];
afterCls = item.afterTitleCls || (item.afterTitleCls = item.baseCls + '-after-title');
beforeCls = item.beforeTitleCls || (item.beforeTitleCls = item.baseCls + '-before-title');
if (!me.title || i < titlePosition) {
if (syncGen) {
item.removeCls(afterCls);
}
item.addCls(beforeCls);
} else if (i > titlePosition) {
if (syncGen) {
item.removeCls(beforeCls);
}
item.addCls(afterCls);
}
}
},
syncNoBorderCls: function() {
var me = this,
ownerCt = this.ownerCt,
noBorderCls = me.headerCls + '-noborder';
if (ownerCt ? (ownerCt.border === false && !ownerCt.frame) : me.border === false) {
me.addCls(noBorderCls);
} else {
me.removeCls(noBorderCls);
}
}
}
});
Ext.define('Ext.layout.container.boxOverflow.None', {
alternateClassName: 'Ext.layout.boxOverflow.None',
alias: [
'box.overflow.none',
'box.overflow.None'
],
mixins: [
'Ext.mixin.Factoryable'
],
factoryConfig: {
defaultType: 'none'
},
isBoxOverflowHandler: true,
$configPrefixed: false,
$configStrict: false,
constructor: function(config) {
this.initConfig(config);
},
handleOverflow: Ext.emptyFn,
clearOverflow: Ext.emptyFn,
beginLayout: Ext.emptyFn,
beginLayoutCycle: Ext.emptyFn,
calculate: function(ownerContext) {
var me = this,
plan = ownerContext.state.boxPlan,
overflow;
if (plan && plan.tooNarrow) {
overflow = me.handleOverflow(ownerContext);
if (overflow) {
if (overflow.reservedSpace) {
me.layout.publishInnerCtSize(ownerContext, overflow.reservedSpace);
}
}
} else
{
me.clearOverflow();
}
},
completeLayout: Ext.emptyFn,
finishedLayout: function(ownerContext) {
var me = this,
owner = me.layout.owner,
hiddens, hiddenCount;
if (owner.hasListeners.overflowchange) {
hiddens = owner.query('>[hidden]');
hiddenCount = hiddens.length;
if (hiddenCount !== me.lastHiddenCount) {
owner.fireEvent('overflowchange', me.lastHiddenCount, hiddenCount, hiddens);
me.lastHiddenCount = hiddenCount;
}
}
},
onRemove: Ext.emptyFn,
getItem: function(item) {
return this.layout.owner.getComponent(item);
},
getOwnerType: function(owner) {
var type;
if (owner.isToolbar) {
type = 'toolbar';
} else if (owner.isTabBar) {
type = 'tab-bar';
} else if (owner.isMenu) {
type = 'menu';
} else if (owner.isBreadcrumb) {
type = 'breadcrumb';
} else {
type = owner.getXType();
}
return type;
},
getPrefixConfig: Ext.emptyFn,
getSuffixConfig: Ext.emptyFn,
getOverflowCls: function() {
return '';
},
setVertical: function() {
var me = this,
layout = me.layout,
innerCt = layout.innerCt;
innerCt.removeCls(me.getOverflowCls(layout.oppositeDirection));
innerCt.addCls(me.getOverflowCls(layout.direction));
}
});
Ext.define('Ext.util.ClickRepeater', {
extend: 'Ext.util.Observable',
constructor: function(el, config) {
var me = this;
me.el = Ext.get(el);
me.el.unselectable();
Ext.apply(me, config);
me.callParent();
if (!me.disabled) {
me.disabled = true;
me.enable();
}
if (me.handler) {
me.on("click", me.handler, me.scope || me);
}
},
interval: 20,
delay: 250,
preventDefault: true,
stopDefault: false,
timer: 0,
enable: function() {
if (this.disabled) {
this.el.on('mousedown', this.handleMouseDown, this);
if (Ext.isIE8) {
this.el.on('dblclick', this.handleDblClick, this);
}
if (this.preventDefault || this.stopDefault) {
this.el.on('click', this.eventOptions, this);
}
}
this.disabled = false;
},
disable: function(
force) {
if (force || !this.disabled) {
clearTimeout(this.timer);
if (this.pressedCls) {
this.el.removeCls(this.pressedCls);
}
Ext.getDoc().un('mouseup', this.handleMouseUp, this);
this.el.clearListeners();
}
this.disabled = true;
},
setDisabled: function(disabled) {
this[disabled ? 'disable' : 'enable']();
},
eventOptions: function(e) {
if (this.preventDefault) {
e.preventDefault();
}
if (this.stopDefault) {
e.stopEvent();
}
},
destroy: function() {
this.disable(true);
this.clearListeners();
},
handleDblClick: function(e) {
clearTimeout(this.timer);
this.fireEvent("mousedown", this, e);
this.fireEvent("click", this, e);
},
handleMouseDown: function(e) {
clearTimeout(this.timer);
if (this.pressedCls) {
this.el.addCls(this.pressedCls);
}
this.mousedownTime = new Date();
Ext.getDoc().on("mouseup", this.handleMouseUp, this);
this.el.on("mouseout", this.handleMouseOut, this);
this.fireEvent("mousedown", this, e);
this.fireEvent("click", this, e);
if (this.accelerate) {
this.delay = 400;
}
this.timer = Ext.defer(this.click, this.delay || this.interval, this, [
e
]);
},
click: function(e) {
this.fireEvent("click", this, e);
this.timer = Ext.defer(this.click, this.accelerate ? this.easeOutExpo(Ext.Date.getElapsed(this.mousedownTime), 400, -390, 12000) : this.interval, this, [
e
]);
},
easeOutExpo: function(t, b, c, d) {
return (t === d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
},
handleMouseOut: function() {
clearTimeout(this.timer);
if (this.pressedCls) {
this.el.removeCls(this.pressedCls);
}
this.el.on("mouseover", this.handleMouseReturn, this);
},
handleMouseReturn: function(e) {
this.el.un("mouseover", this.handleMouseReturn, this);
if (this.pressedCls) {
this.el.addCls(this.pressedCls);
}
this.click(e);
},
handleMouseUp: function(e) {
clearTimeout(this.timer);
this.el.un("mouseover", this.handleMouseReturn, this);
this.el.un("mouseout", this.handleMouseOut, this);
Ext.getDoc().un("mouseup", this.handleMouseUp, this);
if (this.pressedCls) {
this.el.removeCls(this.pressedCls);
}
this.fireEvent("mouseup", this, e);
}
});
Ext.define('Ext.layout.container.boxOverflow.Scroller', {
extend: 'Ext.layout.container.boxOverflow.None',
requires: [
'Ext.util.ClickRepeater',
'Ext.Element'
],
alternateClassName: 'Ext.layout.boxOverflow.Scroller',
alias: [
'box.overflow.scroller',
'box.overflow.Scroller'
],
mixins: {
observable: 'Ext.mixin.Observable'
},
animateScroll: false,
scrollIncrement: 20,
wheelIncrement: 10,
scrollRepeatInterval: 60,
scrollDuration: 400,
scrollerCls: Ext.baseCSSPrefix + 'box-scroller',
beforeSuffix: '-before-scroller',
afterSuffix: '-after-scroller',
constructor: function(config) {
var me = this;
me.mixins.observable.constructor.call(me, config);
me.scrollPosition = 0;
me.scrollSize = 0;
},
getPrefixConfig: function() {
return {
role: 'presentation',
id: this.layout.owner.id + this.beforeSuffix,
cls: this.createScrollerCls('beforeX'),
style: 'display:none'
};
},
getSuffixConfig: function() {
return {
role: 'presentation',
id: this.layout.owner.id + this.afterSuffix,
cls: this.createScrollerCls('afterX'),
style: 'display:none'
};
},
createScrollerCls: function(xName) {
var me = this,
layout = me.layout,
owner = layout.owner,
type = me.getOwnerType(owner),
scrollerCls = me.scrollerCls,
cls = scrollerCls + ' ' + scrollerCls + '-' + layout.names[xName] + ' ' + scrollerCls + '-' + type + ' ' + scrollerCls + '-' + type + '-' + owner.ui;
if (owner.plain) {
cls += ' ' + scrollerCls + '-plain';
}
return cls;
},
getOverflowCls: function(direction) {
return this.scrollerCls + '-body-' + direction;
},
beginLayout: function(ownerContext) {
ownerContext.innerCtScrollPos = this.getScrollPosition();
this.callParent(arguments);
},
finishedLayout: function(ownerContext) {
var me = this,
plan = ownerContext.state.boxPlan,
layout = me.layout,
names = layout.names,
scrollPos = Math.min(me.getMaxScrollPosition(), ownerContext.innerCtScrollPos),
lastProps;
if (plan && plan.tooNarrow) {
lastProps = ownerContext.childItems[ownerContext.childItems.length - 1].props;
me.scrollSize = lastProps[names.x] + lastProps[names.width];
me.updateScrollButtons();
}
layout.innerCt[names.setScrollLeft](scrollPos);
this.callParent([
ownerContext
]);
},
handleOverflow: function(ownerContext) {
var me = this,
names = me.layout.names,
getWidth = names.getWidth,
parallelMargins = names.parallelMargins,
scrollerWidth, targetPaddingWidth, beforeScroller, afterScroller;
me.showScrollers();
beforeScroller = me.getBeforeScroller();
afterScroller = me.getAfterScroller();
scrollerWidth = beforeScroller[getWidth]() + afterScroller[getWidth]() + beforeScroller.getMargin(parallelMargins) + afterScroller.getMargin(parallelMargins);
targetPaddingWidth = ownerContext.targetContext.getPaddingInfo()[names.width];
return {
reservedSpace: Math.max(scrollerWidth - targetPaddingWidth, 0)
};
},
getBeforeScroller: function() {
var me = this;
return me._beforeScroller || (me._beforeScroller = me.createScroller(me.beforeSuffix, 'beforeRepeater', 'scrollLeft'));
},
getAfterScroller: function() {
var me = this;
return me._afterScroller || (me._afterScroller = me.createScroller(me.afterSuffix, 'afterRepeater', 'scrollRight'));
},
createScroller: function(suffix, repeaterName, scrollHandler) {
var me = this,
owner = me.layout.owner,
scrollerCls = me.scrollerCls,
scrollerEl;
scrollerEl = owner.el.getById(owner.id + suffix);
scrollerEl.addClsOnOver(scrollerCls + '-hover');
scrollerEl.addClsOnClick(scrollerCls + '-pressed');
scrollerEl.setVisibilityMode(Ext.Element.DISPLAY);
me[repeaterName] = new Ext.util.ClickRepeater(scrollerEl, {
interval: me.scrollRepeatInterval,
handler: scrollHandler,
scope: me
});
return scrollerEl;
},
createWheelListener: function() {
var me = this;
me.wheelListener = me.layout.innerCt.on('mousewheel', me.onMouseWheel, me, {
destroyable: true
});
},
onMouseWheel: function(e) {
e.stopEvent();
this.scrollBy(this.getWheelDelta(e) * this.wheelIncrement * -1, false);
},
getWheelDelta: function(e) {
return e.getWheelDelta();
},
clearOverflow: function() {
this.hideScrollers();
},
showScrollers: function() {
var me = this;
if (!me.wheelListener) {
me.createWheelListener();
}
me.getBeforeScroller().show();
me.getAfterScroller().show();
me.layout.owner.addClsWithUI(me.layout.direction === 'vertical' ? 'vertical-scroller' : 'scroller');
},
hideScrollers: function() {
var me = this,
beforeScroller = me.getBeforeScroller(),
afterScroller = me.getAfterScroller();
if (beforeScroller) {
beforeScroller.hide();
afterScroller.hide();
me.layout.owner.removeClsWithUI(me.layout.direction === 'vertical' ? 'vertical-scroller' : 'scroller');
}
},
destroy: function() {
Ext.destroyMembers(this, 'beforeRepeater', 'afterRepeater', '_beforeScroller', '_afterScroller', 'wheelListener');
},
scrollBy: function(delta, animate) {
this.scrollTo(this.getScrollPosition() + delta, animate);
},
getScrollAnim: function() {
return {
duration: this.scrollDuration,
callback: this.updateScrollButtons,
scope: this
};
},
updateScrollButtons: function() {
var me = this,
beforeScroller = me.getBeforeScroller(),
afterScroller = me.getAfterScroller(),
disabledCls;
if (!beforeScroller || !afterScroller) {
return;
}
disabledCls = me.scrollerCls + '-disabled';
beforeScroller[me.atExtremeBefore() ? 'addCls' : 'removeCls'](disabledCls);
afterScroller[me.atExtremeAfter() ? 'addCls' : 'removeCls'](disabledCls);
me.scrolling = false;
},
scrollLeft: function() {
this.scrollBy(-this.scrollIncrement, false);
},
scrollRight: function() {
this.scrollBy(this.scrollIncrement, false);
},
getScrollPosition: function() {
var me = this,
layout = me.layout,
result;
if (isNaN(me.scrollPosition)) {
result = layout.innerCt[layout.names.getScrollLeft]();
} else {
result = me.scrollPosition;
}
return result;
},
getMaxScrollPosition: function() {
var me = this,
layout = me.layout,
maxScrollPos = me.scrollSize - layout.innerCt[layout.names.getWidth]();
return (maxScrollPos < 0) ? 0 : maxScrollPos;
},
atExtremeBefore: function() {
return !this.getScrollPosition();
},
atExtremeAfter: function() {
return this.getScrollPosition() >= this.getMaxScrollPosition();
},
setVertical: function() {
var me = this,
beforeScroller = me.getBeforeScroller(),
afterScroller = me.getAfterScroller(),
names = me.layout.names,
scrollerCls = me.scrollerCls;
beforeScroller.removeCls(scrollerCls + '-' + names.beforeY);
afterScroller.removeCls(scrollerCls + '-' + names.afterY);
beforeScroller.addCls(scrollerCls + '-' + names.beforeX);
afterScroller.addCls(scrollerCls + '-' + names.afterX);
this.callParent();
},
scrollTo: function(position, animate) {
var me = this,
layout = me.layout,
names = layout.names,
oldPosition = me.getScrollPosition(),
newPosition = Ext.Number.constrain(position, 0, me.getMaxScrollPosition());
if (newPosition !== oldPosition && !me.scrolling) {
me.scrollPosition = NaN;
if (animate === undefined) {
animate = me.animateScroll;
}
layout.innerCt[names.scrollTo](names.beforeScrollX, newPosition, animate ? me.getScrollAnim() : false);
if (animate) {
me.scrolling = true;
} else {
me.updateScrollButtons();
}
me.fireEvent('scroll', me, newPosition, animate ? me.getScrollAnim() : false);
}
},
scrollToItem: function(item, animate) {
var me = this,
layout = me.layout,
owner = layout.owner,
names = layout.names,
innerCt = layout.innerCt,
visibility, box, newPos;
item = me.getItem(item);
if (item !== undefined) {
if (item === owner.items.first()) {
newPos = 0;
} else if (item === owner.items.last()) {
newPos = me.getMaxScrollPosition();
} else {
visibility = me.getItemVisibility(item);
if (!visibility.fullyVisible) {
box = item.getBox(false, true);
newPos = box[names.x];
if (visibility.hiddenEnd) {
newPos -= (innerCt[names.getWidth]() - box[names.width]);
}
}
}
if (newPos !== undefined) {
me.scrollTo(newPos, animate);
}
}
},
getItemVisibility: function(item) {
var me = this,
box = me.getItem(item).getBox(true, true),
layout = me.layout,
names = layout.names,
itemStart = box[names.x],
itemEnd = itemStart + box[names.width],
scrollStart = me.getScrollPosition(),
scrollEnd = scrollStart + layout.innerCt[names.getWidth]();
return {
hiddenStart: itemStart < scrollStart,
hiddenEnd: itemEnd > scrollEnd,
fullyVisible: itemStart >= scrollStart && itemEnd <= scrollEnd
};
}
});
Ext.define('Ext.dd.DragDropManager', {
singleton: true,
requires: [
'Ext.util.Region'
],
uses: [
'Ext.tip.QuickTipManager'
],
alternateClassName: [
'Ext.dd.DragDropMgr',
'Ext.dd.DDM'
],
ids: {},
handleIds: {},
dragCurrent: null,
dragOvers: {},
deltaX: 0,
deltaY: 0,
preventDefault: true,
stopPropagation: true,
initialized: false,
locked: false,
init: function() {
this.initialized = true;
},
POINT: 0,
INTERSECT: 1,
mode: 0,
notifyOccluded: false,
dragCls: Ext.baseCSSPrefix + 'dd-drag-current',
_execOnAll: function(sMethod, args) {
var ids = this.ids,
i, j, oDD, item;
for (i in ids) {
if (ids.hasOwnProperty(i)) {
item = ids[i];
for (j in item) {
if (item.hasOwnProperty(j)) {
oDD = item[j];
if (!this.isTypeOfDD(oDD)) {
continue;
}
oDD[sMethod].apply(oDD, args);
}
}
}
}
},
addListeners: function() {
var me = this;
me.init();
Ext.getDoc().on({
mouseup: me.handleMouseUp,
mousemove: {
fn: me.handleMouseMove,
capture: false
},
dragstart: me.preventDrag,
drag: me.preventDrag,
dragend: me.preventDrag,
capture: true,
scope: me
});
Ext.getWin().on({
unload: me._onUnload,
resize: me._onResize,
scope: me
});
},
preventDrag: function(e) {
if (this.isMouseDown) {
e.stopPropagation();
}
},
_onResize: function(e) {
this._execOnAll("resetConstraints", []);
},
lock: function() {
this.locked = true;
},
unlock: function() {
this.locked = false;
},
isLocked: function() {
return this.locked;
},
locationCache: {},
useCache: true,
clickPixelThresh: 8,
dragThreshMet: false,
clickTimeout: null,
startX: 0,
startY: 0,
regDragDrop: function(oDD, sGroup) {
if (!this.initialized) {
this.init();
}
if (!this.ids[sGroup]) {
this.ids[sGroup] = {};
}
this.ids[sGroup][oDD.id] = oDD;
},
removeDDFromGroup: function(oDD, sGroup) {
if (!this.ids[sGroup]) {
this.ids[sGroup] = {};
}
var obj = this.ids[sGroup];
if (obj && obj[oDD.id]) {
delete obj[oDD.id];
}
},
_remove: function(oDD, clearGroup) {
var me = this,
ids = me.ids,
groups = oDD.groups,
g;
if (me.clearingAll) {
return;
}
if (me.dragCurrent === oDD) {
me.dragCurrent = null;
}
for (g in groups) {
if (groups.hasOwnProperty(g)) {
if (clearGroup) {
delete ids[g];
} else if (ids[g]) {
delete ids[g][oDD.id];
}
}
}
delete me.handleIds[oDD.id];
},
regHandle: function(sDDId, sHandleId) {
if (!this.handleIds[sDDId]) {
this.handleIds[sDDId] = {};
}
this.handleIds[sDDId][sHandleId] = sHandleId;
},
isDragDrop: function(id) {
return (this.getDDById(id)) ? true : false;
},
getRelated: function(p_oDD, bTargetsOnly) {
var oDDs = [],
i, j, dd;
for (i in p_oDD.groups) {
for (j in this.ids[i]) {
dd = this.ids[i][j];
if (!this.isTypeOfDD(dd)) {
continue;
}
if (!bTargetsOnly || dd.isTarget) {
oDDs[oDDs.length] = dd;
}
}
}
return oDDs;
},
isLegalTarget: function(oDD, oTargetDD) {
var targets = this.getRelated(oDD, true),
i, len;
for (i = 0 , len = targets.length; i < len; ++i) {
if (targets[i].id === oTargetDD.id) {
return true;
}
}
return false;
},
isTypeOfDD: function(oDD) {
return (oDD && oDD.__ygDragDrop);
},
isHandle: function(sDDId, sHandleId) {
return (this.handleIds[sDDId] && this.handleIds[sDDId][sHandleId]);
},
getDDById: function(id, force) {
var i, dd;
for (i in this.ids) {
dd = this.ids[i][id];
if (dd instanceof Ext.dd.DDTarget || force) {
return dd;
}
}
return null;
},
handleMouseDown: function(e, oDD) {
var me = this,
xy, el;
me.isMouseDown = true;
if (Ext.quickTipsActive) {
Ext.tip.QuickTipManager.ddDisable();
}
me.currentPoint = e.getPoint();
if (me.dragCurrent) {
me.handleMouseUp(e);
}
me.mousedownEvent = e;
me.currentTarget = e.getTarget();
me.dragCurrent = oDD;
el = oDD.getEl();
Ext.fly(el).setCapture();
xy = e.getXY();
me.startX = xy[0];
me.startY = xy[1];
me.offsetX = me.offsetY = 0;
me.deltaX = me.startX - el.offsetLeft;
me.deltaY = me.startY - el.offsetTop;
me.dragThreshMet = false;
},
startDrag: function(x, y) {
var me = this,
current = me.dragCurrent,
dragEl;
clearTimeout(me.clickTimeout);
if (current) {
current.b4StartDrag(x, y);
current.startDrag(x, y);
dragEl = current.getDragEl();
if (dragEl) {
Ext.fly(dragEl).addCls(me.dragCls);
}
}
me.dragThreshMet = true;
},
handleMouseUp: function(e) {
var me = this;
me.isMouseDown = false;
if (Ext.quickTipsActive) {
Ext.tip.QuickTipManager.ddEnable();
}
if (!me.dragCurrent) {
return;
}
if (Ext.isIE && document.releaseCapture) {
document.releaseCapture();
}
clearTimeout(me.clickTimeout);
if (me.dragThreshMet) {
me.fireEvents(e, true);
}
me.stopDrag(e);
me.stopEvent(e);
},
stopEvent: function(e) {
if (this.stopPropagation) {
e.stopPropagation();
}
if (this.preventDefault) {
e.preventDefault();
}
},
stopDrag: function(e) {
var me = this,
current = me.dragCurrent,
dragEl;
if (current) {
if (me.dragThreshMet) {
dragEl = current.getDragEl();
if (dragEl) {
Ext.fly(dragEl).removeCls(me.dragCls);
}
current.b4EndDrag(e);
current.endDrag(e);
}
me.dragCurrent.onMouseUp(e);
}
me.dragCurrent = null;
me.dragOvers = {};
},
handleMouseMove: function(e) {
var me = this,
current = me.dragCurrent,
point = me.currentPoint = e.getPoint(),
currentX = point.x,
currentY = point.y,
diffX, diffY;
me.offsetX = currentX - me.startX;
me.offsetY = currentY - me.startY;
if (!current) {
return true;
}
if (!me.dragThreshMet) {
diffX = Math.abs(me.offsetX);
diffY = Math.abs(me.offsetY);
if (diffX > me.clickPixelThresh || diffY > me.clickPixelThresh) {
me.startDrag(me.startX, me.startY);
}
}
if (me.dragThreshMet) {
current.b4Drag(e);
current.onDrag(e);
if (!current.moveOnly) {
me.fireEvents(e, false);
}
}
me.stopEvent(e);
return true;
},
fireEvents: function(e, isDrop) {
var me = this,
isTouch = Ext.supports.Touch,
dragCurrent = me.dragCurrent,
mousePoint = me.currentPoint,
currentX = mousePoint.x,
currentY = mousePoint.y,
allTargets = [],
oldOvers = [],
outEvts = [],
overEvts = [],
dropEvts = [],
enterEvts = [],
zoom = isTouch ? document.documentElement.clientWidth / window.innerWidth : 1,
dragEl, overTarget, overTargetEl, needsSort, i, len, sGroup, overDragEl;
if (!dragCurrent || dragCurrent.isLocked()) {
return;
}
overDragEl = !(dragCurrent.deltaX < 0 || dragCurrent.deltaY < 0);
if (isTouch || (!me.notifyOccluded && (!Ext.supports.CSSPointerEvents || Ext.isIE10m || Ext.isOpera) && overDragEl)) {
dragEl = dragCurrent.getDragEl();
if (overDragEl) {
dragEl.style.visibility = 'hidden';
}
e.target = document.elementFromPoint(currentX / zoom, currentY / zoom);
if (overDragEl) {
dragEl.style.visibility = 'visible';
}
}
for (i in me.dragOvers) {
overTarget = me.dragOvers[i];
delete me.dragOvers[i];
if (!me.isTypeOfDD(overTarget) || overTarget.isDestroyed) {
continue;
}
if (me.notifyOccluded) {
if (!this.isOverTarget(mousePoint, overTarget, me.mode)) {
outEvts.push(overTarget);
}
} else
{
if (!e.within(overTarget.getEl())) {
outEvts.push(overTarget);
}
}
oldOvers[i] = true;
}
for (sGroup in dragCurrent.groups) {
if ("string" !== typeof sGroup) {
continue;
}
for (i in me.ids[sGroup]) {
overTarget = me.ids[sGroup][i];
if (me.isTypeOfDD(overTarget) && (overTargetEl = overTarget.getEl()) && (overTarget.isTarget) && (!overTarget.isLocked()) && (Ext.fly(overTargetEl).isVisible(true)) && ((overTarget !== dragCurrent) || (dragCurrent.ignoreSelf === false))) {
if (me.notifyOccluded) {
if ((overTarget.zIndex = me.getZIndex(overTargetEl)) !== -1) {
needsSort = true;
}
allTargets.push(overTarget);
} else
{
if (e.within(overTarget.getEl())) {
allTargets.push(overTarget);
break;
}
}
}
}
}
if (needsSort) {
Ext.Array.sort(allTargets, me.byZIndex);
}
for (i = 0 , len = allTargets.length; i < len; i++) {
overTarget = allTargets[i];
if (me.isOverTarget(mousePoint, overTarget, me.mode)) {
if (isDrop) {
dropEvts.push(overTarget);
} else
{
if (!oldOvers[overTarget.id]) {
enterEvts.push(overTarget);
} else
{
overEvts.push(overTarget);
}
me.dragOvers[overTarget.id] = overTarget;
}
if (!me.notifyOccluded) {
break;
}
}
}
if (me.mode) {
if (outEvts.length) {
dragCurrent.b4DragOut(e, outEvts);
dragCurrent.onDragOut(e, outEvts);
}
if (enterEvts.length) {
dragCurrent.onDragEnter(e, enterEvts);
}
if (overEvts.length) {
dragCurrent.b4DragOver(e, overEvts);
dragCurrent.onDragOver(e, overEvts);
}
if (dropEvts.length) {
dragCurrent.b4DragDrop(e, dropEvts);
dragCurrent.onDragDrop(e, dropEvts);
}
} else {
for (i = 0 , len = outEvts.length; i < len; ++i) {
dragCurrent.b4DragOut(e, outEvts[i].id);
dragCurrent.onDragOut(e, outEvts[i].id);
}
for (i = 0 , len = enterEvts.length; i < len; ++i) {
dragCurrent.onDragEnter(e, enterEvts[i].id);
}
for (i = 0 , len = overEvts.length; i < len; ++i) {
dragCurrent.b4DragOver(e, overEvts[i].id);
dragCurrent.onDragOver(e, overEvts[i].id);
}
for (i = 0 , len = dropEvts.length; i < len; ++i) {
dragCurrent.b4DragDrop(e, dropEvts[i].id);
dragCurrent.onDragDrop(e, dropEvts[i].id);
}
}
if (isDrop && !dropEvts.length) {
dragCurrent.onInvalidDrop(e);
}
},
getZIndex: function(element) {
var body = document.body,
z,
zIndex = -1;
element = Ext.getDom(element);
while (element !== body) {
if (!isNaN(z = Number(Ext.fly(element).getStyle('zIndex')))) {
zIndex = z;
}
element = element.parentNode;
}
return zIndex;
},
byZIndex: function(d1, d2) {
return d1.zIndex < d2.zIndex;
},
getBestMatch: function(dds) {
var winner = null,
len = dds.length,
i, dd;
if (len === 1) {
winner = dds[0];
} else {
for (i = 0; i < len; ++i) {
dd = dds[i];
if (dd.cursorIsOver) {
winner = dd;
break;
} else
{
if (!winner || winner.overlap.getArea() < dd.overlap.getArea()) {
winner = dd;
}
}
}
}
return winner;
},
refreshCache: function(groups) {
var sGroup, i, oDD, loc;
for (sGroup in groups) {
if ("string" !== typeof sGroup) {
continue;
}
for (i in this.ids[sGroup]) {
oDD = this.ids[sGroup][i];
if (this.isTypeOfDD(oDD)) {
loc = this.getLocation(oDD);
if (loc) {
this.locationCache[oDD.id] = loc;
} else {
delete this.locationCache[oDD.id];
}
}
}
}
},
verifyEl: function(el) {
if (el) {
var parent;
if (Ext.isIE) {
try {
parent = el.offsetParent;
} catch (e) {}
} else {
parent = el.offsetParent;
}
if (parent) {
return true;
}
}
return false;
},
getLocation: function(oDD) {
if (!this.isTypeOfDD(oDD)) {
return null;
}
if (oDD.getRegion) {
return oDD.getRegion();
}
var el = oDD.getEl(),
pos, x1, x2, y1, y2, t, r, b, l;
try {
pos = Ext.fly(el).getXY();
} catch (e) {}
if (!pos) {
return null;
}
x1 = pos[0];
x2 = x1 + el.offsetWidth;
y1 = pos[1];
y2 = y1 + el.offsetHeight;
t = y1 - oDD.padding[0];
r = x2 + oDD.padding[1];
b = y2 + oDD.padding[2];
l = x1 - oDD.padding[3];
return new Ext.util.Region(t, r, b, l);
},
isOverTarget: function(pt, oTarget, intersect) {
var loc = this.locationCache[oTarget.id],
dc, pos, el, curRegion, overlap;
if (!loc || !this.useCache) {
loc = this.getLocation(oTarget);
this.locationCache[oTarget.id] = loc;
}
if (!loc) {
return false;
}
oTarget.cursorIsOver = loc.contains(pt);
dc = this.dragCurrent;
if (!dc || !dc.getTargetCoord || (!intersect && !dc.constrainX && !dc.constrainY)) {
return oTarget.cursorIsOver;
}
oTarget.overlap = null;
pos = dc.getTargetCoord(pt.x, pt.y);
el = dc.getDragEl();
curRegion = new Ext.util.Region(pos.y, pos.x + el.offsetWidth, pos.y + el.offsetHeight, pos.x);
overlap = curRegion.intersect(loc);
if (overlap) {
oTarget.overlap = overlap;
return (intersect) ? true : oTarget.cursorIsOver;
} else {
return false;
}
},
_onUnload: function(e, me) {
Ext.dd.DragDropManager.unregAll();
},
unregAll: function() {
var me = this,
cache = me.elementCache,
i;
if (me.dragCurrent) {
me.stopDrag();
me.dragCurrent = null;
}
me.clearingAll = true;
me._execOnAll("unreg", []);
delete me.clearingAll;
for (i in cache) {
delete cache[i];
}
me.elementCache = {};
me.ids = {};
me.handleIds = {};
},
elementCache: {},
getElWrapper: function(id) {
var oWrapper = this.elementCache[id];
if (!oWrapper || !oWrapper.el) {
oWrapper = this.elementCache[id] = new this.ElementWrapper(Ext.getDom(id));
}
return oWrapper;
},
getElement: function(id) {
return Ext.getDom(id);
},
getCss: function(id) {
var el = Ext.getDom(id);
return (el) ? el.style : null;
},
ElementWrapper: function(el) {
this.el = el || null;
this.id = this.el && el.id;
this.css = this.el && el.style;
},
getPosX: function(el) {
return Ext.fly(el).getX();
},
getPosY: function(el) {
return Ext.fly(el).getY();
},
swapNode: function(n1, n2) {
if (n1.swapNode) {
n1.swapNode(n2);
} else {
var p = n2.parentNode,
s = n2.nextSibling;
if (s === n1) {
p.insertBefore(n1, n2);
} else if (n2 === n1.nextSibling) {
p.insertBefore(n2, n1);
} else {
n1.parentNode.replaceChild(n2, n1);
p.insertBefore(n1, s);
}
}
},
getScroll: function() {
var doc = window.document,
docEl = doc.documentElement,
body = doc.body,
top = 0,
left = 0;
if (docEl && (docEl.scrollTop || docEl.scrollLeft)) {
top = docEl.scrollTop;
left = docEl.scrollLeft;
} else if (body) {
top = body.scrollTop;
left = body.scrollLeft;
}
return {
top: top,
left: left
};
},
getStyle: function(el, styleProp) {
return Ext.fly(el).getStyle(styleProp);
},
getScrollTop: function() {
return this.getScroll().top;
},
getScrollLeft: function() {
return this.getScroll().left;
},
moveToEl: function(moveEl, targetEl) {
var aCoord = Ext.fly(targetEl).getXY();
Ext.fly(moveEl).setXY(aCoord);
},
numericSort: function(a, b) {
return (a - b);
},
handleWasClicked: function(node, id) {
if (this.isHandle(id, node.id)) {
return true;
} else {
var p = node.parentNode;
while (p) {
if (this.isHandle(id, p.id)) {
return true;
} else {
p = p.parentNode;
}
}
}
return false;
}
}, function(DragDropManager) {
Ext.onInternalReady(function() {
DragDropManager.addListeners();
});
});
Ext.define('Ext.resizer.Splitter', {
extend: 'Ext.Component',
requires: [
'Ext.XTemplate'
],
uses: [
'Ext.resizer.SplitterTracker'
],
xtype: 'splitter',
childEls: [
'collapseEl'
],
renderTpl: [
'<tpl if="collapsible===true">',
'<div id="{id}-collapseEl" data-ref="collapseEl" role="presentation" class="',
Ext.baseCSSPrefix,
'collapse-el ',
Ext.baseCSSPrefix,
'layout-split-{collapseDir}{childElCls}">&#160;',
'</div>',
'</tpl>'
],
isSplitter: true,
baseCls: Ext.baseCSSPrefix + 'splitter',
collapsedClsInternal: Ext.baseCSSPrefix + 'splitter-collapsed',
canResize: true,
collapsible: null,
collapseOnDblClick: true,
defaultSplitMin: 40,
defaultSplitMax: 1000,
collapseTarget: 'next',
horizontal: false,
vertical: false,
size: 5,
tracker: null,
ariaRole: 'separator',
focusable: true,
tabIndex: 0,
getTrackerConfig: function() {
return Ext.apply({
xclass: 'Ext.resizer.SplitterTracker',
el: this.el,
splitter: this
}, this.tracker);
},
beforeRender: function() {
var me = this,
target = me.getCollapseTarget(),
collapsible = me.collapsible;
me.callParent();
if (target.collapsed) {
me.addCls(me.collapsedClsInternal);
}
if (!me.canResize) {
me.addCls(me.baseCls + '-noresize');
}
Ext.applyIf(me.renderData, {
collapseDir: me.getCollapseDirection(),
collapsible: (collapsible !== null) ? collapsible : target.collapsible
});
me.protoEl.unselectable();
},
onRender: function() {
var me = this,
collapseEl;
me.callParent(arguments);
if (me.performCollapse !== false) {
if (me.renderData.collapsible) {
me.mon(me.collapseEl, 'click', me.toggleTargetCmp, me);
}
if (me.collapseOnDblClick) {
me.mon(me.el, 'dblclick', me.toggleTargetCmp, me);
}
}
me.getCollapseTarget().on({
collapse: me.onTargetCollapse,
expand: me.onTargetExpand,
beforeexpand: me.onBeforeTargetExpand,
beforecollapse: me.onBeforeTargetCollapse,
scope: me
});
if (me.canResize) {
me.tracker = Ext.create(me.getTrackerConfig());
me.relayEvents(me.tracker, [
'beforedragstart',
'dragstart',
'dragend'
]);
}
collapseEl = me.collapseEl;
if (collapseEl) {
collapseEl.lastCollapseDirCls = me.collapseDirProps[me.collapseDirection].cls;
}
},
getCollapseDirection: function() {
var me = this,
dir = me.collapseDirection,
collapseTarget, idx, items, type;
if (!dir) {
collapseTarget = me.collapseTarget;
if (collapseTarget.isComponent) {
dir = collapseTarget.collapseDirection;
}
if (!dir) {
type = me.ownerCt.layout.type;
if (collapseTarget.isComponent) {
items = me.ownerCt.items;
idx = Number(items.indexOf(collapseTarget) === items.indexOf(me) - 1) << 1 | Number(type === 'hbox');
} else {
idx = Number(me.collapseTarget === 'prev') << 1 | Number(type === 'hbox');
}
dir = [
'bottom',
'right',
'top',
'left'
][idx];
}
me.collapseDirection = dir;
}
me.setOrientation((dir === 'top' || dir === 'bottom') ? 'horizontal' : 'vertical');
return dir;
},
getCollapseTarget: function() {
var me = this;
return me.collapseTarget.isComponent ? me.collapseTarget : me.collapseTarget === 'prev' ? me.previousSibling() : me.nextSibling();
},
setCollapseEl: function(display) {
var el = this.collapseEl;
if (el) {
el.setDisplayed(display);
}
},
onBeforeTargetExpand: function(target) {
this.setCollapseEl('none');
},
onBeforeTargetCollapse: function() {
this.setCollapseEl('none');
},
onTargetCollapse: function(target) {
var me = this;
if (target === me.getCollapseTarget() && target[me.orientation === 'vertical' ? 'collapsedHorizontal' : 'collapsedVertical']()) {
me.el.addCls(me.collapsedClsInternal + ' ' + (me.collapsedCls || ''));
}
me.setCollapseEl('');
},
onTargetExpand: function(target) {
var me = this;
me.el.removeCls(me.collapsedClsInternal + ' ' + (me.collapsedCls || ''));
me.setCollapseEl('');
},
collapseDirProps: {
top: {
cls: Ext.baseCSSPrefix + 'layout-split-top'
},
right: {
cls: Ext.baseCSSPrefix + 'layout-split-right'
},
bottom: {
cls: Ext.baseCSSPrefix + 'layout-split-bottom'
},
left: {
cls: Ext.baseCSSPrefix + 'layout-split-left'
}
},
orientationProps: {
horizontal: {
opposite: 'vertical',
fixedAxis: 'height',
stretchedAxis: 'width'
},
vertical: {
opposite: 'horizontal',
fixedAxis: 'width',
stretchedAxis: 'height'
}
},
applyCollapseDirection: function() {
var me = this,
collapseEl = me.collapseEl,
collapseDirProps = me.collapseDirProps[me.collapseDirection],
cls;
if (collapseEl) {
cls = collapseEl.lastCollapseDirCls;
if (cls) {
collapseEl.removeCls(cls);
}
collapseEl.addCls(collapseEl.lastCollapseDirCls = collapseDirProps.cls);
}
},
applyOrientation: function() {
var me = this,
orientation = me.orientation,
orientationProps = me.orientationProps[orientation],
defaultSize = me.size,
fixedSizeProp = orientationProps.fixedAxis,
stretchSizeProp = orientationProps.stretchedAxis,
cls = me.baseCls + '-';
me[orientation] = true;
me[orientationProps.opposite] = false;
if (!me.hasOwnProperty(fixedSizeProp) || me[fixedSizeProp] === '100%') {
me[fixedSizeProp] = defaultSize;
}
if (!me.hasOwnProperty(stretchSizeProp) || me[stretchSizeProp] === defaultSize) {
me[stretchSizeProp] = '100%';
}
me.removeCls(cls + orientationProps.opposite);
me.addCls(cls + orientation);
},
setOrientation: function(orientation) {
var me = this;
if (me.orientation !== orientation) {
me.orientation = orientation;
me.applyOrientation();
}
},
updateOrientation: function() {
delete this.collapseDirection;
this.getCollapseDirection();
this.applyCollapseDirection();
},
toggleTargetCmp: function(e, t) {
var cmp = this.getCollapseTarget(),
placeholder = cmp.placeholder,
toggle;
if (Ext.isFunction(cmp.expand) && Ext.isFunction(cmp.collapse)) {
if (placeholder && !placeholder.hidden) {
toggle = true;
} else {
toggle = !cmp.hidden;
}
if (toggle) {
if (cmp.collapsed) {
cmp.expand();
} else if (cmp.collapseDirection) {
cmp.collapse();
} else {
cmp.collapse(this.renderData.collapseDir);
}
}
}
},
setSize: function() {
var me = this;
me.callParent(arguments);
if (Ext.isIE && me.el) {
me.el.repaint();
}
},
beforeDestroy: function() {
Ext.destroy(this.tracker);
this.callParent();
}
});
Ext.define('Ext.layout.container.Box', {
extend: 'Ext.layout.container.Container',
alias: 'layout.box',
alternateClassName: 'Ext.layout.BoxLayout',
requires: [
'Ext.layout.container.boxOverflow.None',
'Ext.layout.container.boxOverflow.Scroller',
'Ext.util.Format',
'Ext.dd.DragDropManager',
'Ext.resizer.Splitter'
],
type: 'box',
config: {
align: 'begin',
constrainAlign: false,
enableSplitters: true,
overflowHandler: {
$value: null,
merge: function(newValue, oldValue) {
if (typeof newValue === 'string') {
newValue = {
type: newValue
};
}
return Ext.merge(oldValue ? Ext.Object.chain(oldValue) : {}, newValue);
}
},
padding: 0,
pack: 'start',
stretchMaxPartner: undefined,
vertical: false,
alignRoundingMethod: 'round'
},
itemCls: Ext.baseCSSPrefix + 'box-item',
targetCls: Ext.baseCSSPrefix + 'box-layout-ct',
targetElCls: Ext.baseCSSPrefix + 'box-target',
innerCls: Ext.baseCSSPrefix + 'box-inner',
manageMargins: true,
createsInnerCt: true,
childEls: [
'innerCt',
'targetEl'
],
renderTpl: [
'{%var oc,l=values.$comp.layout,oh=l.overflowHandler;' + 'if (oh && oh.getPrefixConfig!==Ext.emptyFn) {' + 'if(oc=oh.getPrefixConfig())dh.generateMarkup(oc, out)' + '}%}' + '<div id="{ownerId}-innerCt" data-ref="innerCt" role="presentation" class="{[l.innerCls]}' + '{[oh ? (" " + oh.getOverflowCls(l.direction)) : ""]}">' + '<div id="{ownerId}-targetEl" data-ref="targetEl" class="{targetElCls}" role="presentation">' + '{%this.renderBody(out, values)%}' + '</div>' + '</div>' + '{%if (oh && oh.getSuffixConfig!==Ext.emptyFn) {' + 'if(oc=oh.getSuffixConfig())dh.generateMarkup(oc, out)' + '}%}',
{
disableFormats: true,
definitions: 'var dh=Ext.DomHelper;'
}
],
constructor: function(config) {
var me = this,
type;
me.callParent(arguments);
me.setVertical(me.vertical);
me.flexSortFn = me.flexSort.bind(me);
type = typeof me.padding;
if (type === 'string' || type === 'number') {
me.padding = Ext.util.Format.parseBox(me.padding);
me.padding.height = me.padding.top + me.padding.bottom;
me.padding.width = me.padding.left + me.padding.right;
}
},
_beginRe: /^(?:begin|left|top)$/,
_centerRe: /^(?:center|middle)$/,
_endRe: /^(?:end|right|bottom)$/,
_percentageRe: /^\s*(\d+(?:\.\d*)?)\s*[%]\s*$/,
getItemSizePolicy: function(item, ownerSizeModel) {
var me = this,
policy = me.sizePolicy,
align = me.align,
flex = item.flex,
key = align,
names = me.names,
heightName = names.height,
widthName = names.width,
width = item[widthName],
height = item[heightName],
percentageRe = me._percentageRe,
percentageWidth = percentageRe.test(width),
isStretch = (align === 'stretch'),
isStretchMax = (align === 'stretchmax'),
constrain = me.constrainAlign;
if (!ownerSizeModel && (isStretch || flex || percentageWidth || (constrain && !isStretchMax))) {
ownerSizeModel = me.owner.getSizeModel();
}
if (isStretch) {
if (!percentageRe.test(height) && ownerSizeModel[heightName].shrinkWrap) {
key = 'stretchmax';
}
}
else if (!isStretchMax) {
if (percentageRe.test(height)) {
key = 'stretch';
} else if (constrain && !ownerSizeModel[heightName].shrinkWrap) {
key = 'stretchmax';
} else {
key = '';
}
}
if (flex || percentageWidth) {
if (!ownerSizeModel[widthName].shrinkWrap) {
policy = policy.flex;
}
}
return policy[key];
},
flexSort: function(a, b) {
var maxWidthName = this.names.maxWidth,
minWidthName = this.names.minWidth,
infiniteValue = Infinity,
aTarget = a.target,
bTarget = b.target,
aFlex = aTarget.flex,
bFlex = bTarget.flex,
result = 0,
aMin, bMin, aMax, bMax, hasMin, hasMax;
aMax = aTarget[maxWidthName] || infiniteValue;
bMax = bTarget[maxWidthName] || infiniteValue;
aMin = aTarget[minWidthName] || 0;
bMin = bTarget[minWidthName] || 0;
hasMin = isFinite(aMin) || isFinite(bMin);
hasMax = isFinite(aMax) || isFinite(bMax);
if (hasMin || hasMax) {
if (hasMax) {
result = aMax - bMax;
}
if (result === 0 && hasMin) {
result = bMin - aMin;
}
if (result === 0) {
if (hasMax) {
result = bFlex - aFlex;
} else {
result = aFlex - bFlex;
}
}
}
return result;
},
isItemBoxParent: function(itemContext) {
return true;
},
isItemShrinkWrap: function(item) {
return true;
},
roundFlex: function(width) {
return Math.floor(width);
},
beginCollapse: function(child) {
var me = this;
if (me.direction === 'vertical' && child.collapsedVertical()) {
child.collapseMemento.capture([
'flex'
]);
delete child.flex;
} else if (me.direction === 'horizontal' && child.collapsedHorizontal()) {
child.collapseMemento.capture([
'flex'
]);
delete child.flex;
}
},
beginExpand: function(child) {
child.collapseMemento.restore([
'flex'
]);
},
beginLayout: function(ownerContext) {
var me = this,
owner = me.owner,
smp = owner.stretchMaxPartner,
style = me.innerCt.dom.style,
names = me.names,
overflowHandler = me.overflowHandler,
scrollable = owner.getScrollable(),
scrollPos;
ownerContext.boxNames = names;
if (overflowHandler) {
overflowHandler.beginLayout(ownerContext);
}
if (typeof smp === 'string') {
smp = Ext.getCmp(smp) || owner.query(smp)[0];
}
ownerContext.stretchMaxPartner = smp && ownerContext.context.getCmp(smp);
me.callParent(arguments);
ownerContext.innerCtContext = ownerContext.getEl('innerCt', me);
ownerContext.targetElContext = ownerContext.getEl('targetEl', me);
ownerContext.ownerScrollable = scrollable = owner.getScrollable();
if (scrollable) {
ownerContext.scrollRestore = scrollable.getPosition();
}
style.width = '';
style.height = '';
},
beginLayoutCycle: function(ownerContext, firstCycle) {
var me = this,
state = ownerContext.state,
scrollable = ownerContext.ownerScrollable,
align = me.align,
names = ownerContext.boxNames,
pack = me.pack,
centerRe = me._centerRe,
overflowHandler = me.overflowHandler,
canScroll = ownerContext.state.canScroll,
widthModel, heightModel;
if (overflowHandler) {
overflowHandler.beginLayoutCycle(ownerContext, firstCycle);
}
me.callParent(arguments);
ownerContext.parallelSizeModel = widthModel = ownerContext[names.widthModel];
ownerContext.perpendicularSizeModel = heightModel = ownerContext[names.heightModel];
ownerContext.boxOptions = {
align: align = {
stretch: align === 'stretch',
stretchmax: align === 'stretchmax',
center: centerRe.test(align),
bottom: me._endRe.test(align)
},
pack: pack = {
center: centerRe.test(pack),
end: pack === 'end'
}
};
if (scrollable) {
if (!canScroll) {
state.canScroll = {
parallel: !widthModel.shrinkWrap && scrollable[names.getX](),
perpendicular: !heightModel.shrinkWrap && scrollable[names.getY]()
};
}
if (!state.actualScroll) {
state.actualScroll = {
parallel: false,
perpendicular: false
};
}
}
if (align.stretch && heightModel.shrinkWrap) {
align.stretchmax = true;
align.stretch = false;
}
align.nostretch = !(align.stretch || align.stretchmax);
if (widthModel.shrinkWrap) {
pack.center = pack.end = false;
}
me.cacheFlexes(ownerContext);
me.targetEl.setWidth(20000);
},
cacheFlexes: function(ownerContext) {
var me = this,
names = ownerContext.boxNames,
widthModelName = names.widthModel,
heightModelName = names.heightModel,
nostretch = ownerContext.boxOptions.align.nostretch,
totalFlex = 0,
childItems = ownerContext.childItems,
i = childItems.length,
flexedItems = [],
minWidth = 0,
smallestHeight = 0,
smallestWidth = 0,
minWidthName = names.minWidth,
minHeightName = names.minHeight,
percentageRe = me._percentageRe,
percentageWidths = 0,
percentageHeights = 0,
child, childContext, flex, match, heightModel, widthModel, width, height;
while (i--) {
childContext = childItems[i];
child = childContext.target;
widthModel = childContext[widthModelName];
if (widthModel.calculated) {
childContext.flex = flex = child.flex;
if (flex) {
totalFlex += flex;
flexedItems.push(childContext);
minWidth += child[minWidthName] || 0;
} else {
match = percentageRe.exec(child[names.width]);
childContext.percentageParallel = parseFloat(match[1]) / 100;
++percentageWidths;
}
}
if (widthModel.configured) {
width = child[names.width];
} else {
width = child[minWidthName] || 0;
}
smallestWidth += width;
heightModel = childContext[heightModelName];
if (nostretch && heightModel.calculated) {
match = percentageRe.exec(child[names.height]);
childContext.percentagePerpendicular = parseFloat(match[1]) / 100;
++percentageHeights;
}
if (heightModel.configured) {
height = child[names.height];
} else {
height = child[minHeightName] || 0;
}
if (height > smallestHeight) {
smallestHeight = height;
}
}
ownerContext.flexedItems = flexedItems;
ownerContext.flexedMinWidth = minWidth;
ownerContext.smallestWidth = smallestWidth;
ownerContext.smallestHeight = smallestHeight;
ownerContext.totalFlex = totalFlex;
ownerContext.percentageWidths = percentageWidths;
ownerContext.percentageHeights = percentageHeights;
Ext.Array.sort(flexedItems, me.flexSortFn);
},
calculate: function(ownerContext) {
var me = this,
names = ownerContext.boxNames,
state = ownerContext.state,
actualScroll = state.actualScroll,
needsScroll = state.needsScroll,
canScroll = state.canScroll,
plan = state.boxPlan || (state.boxPlan = {}),
overflowHandler = me.overflowHandler;
plan.targetSize = me.getContainerSize(ownerContext);
if (canScroll && !needsScroll) {
state.needsScroll = needsScroll = {
parallel: canScroll.parallel && plan.targetSize[names.width] < ownerContext.smallestWidth,
perpendicular: canScroll.perpendicular && plan.targetSize[names.height] < ownerContext.smallestHeight
};
}
if (!state.parallelDone) {
state.parallelDone = me.calculateParallel(ownerContext, names, plan);
}
if (!state.perpendicularDone) {
state.perpendicularDone = me.calculatePerpendicular(ownerContext, names, plan);
}
if (state.parallelDone && state.perpendicularDone) {
if (canScroll && !state.scrollPass) {
if (needsScroll.parallel !== actualScroll.parallel || needsScroll.perpendicular !== actualScroll.perpendicular) {
ownerContext.invalidate({
state: {
scrollPass: true,
canScroll: canScroll,
needsScroll: actualScroll
}
});
me.done = false;
return;
}
}
me.publishInnerCtSize(ownerContext);
if (me.done && ownerContext.boxOptions.align.stretchmax && !state.stretchMaxDone) {
me.calculateStretchMax(ownerContext, names, plan);
state.stretchMaxDone = true;
}
if (overflowHandler) {
overflowHandler.calculate(ownerContext);
}
} else {
me.done = false;
}
},
calculateParallel: function(ownerContext, names, plan) {
var me = this,
widthShrinkWrap = ownerContext.parallelSizeModel.shrinkWrap,
widthName = names.width,
childItems = ownerContext.childItems,
beforeXName = names.beforeX,
afterXName = names.afterX,
setWidthName = names.setWidth,
childItemsLength = childItems.length,
flexedItems = ownerContext.flexedItems,
flexedItemsLength = flexedItems.length,
pack = ownerContext.boxOptions.pack,
padding = me.padding,
targetSize = plan.targetSize,
containerWidth = targetSize[widthName],
state = ownerContext.state,
needsScroll = state.needsScroll,
canScroll = state.canScroll,
totalMargin = 0,
left = padding[beforeXName],
nonFlexWidth = left + padding[afterXName],
scrollbarSize = Ext.getScrollbarSize(),
scrollbarWidth = scrollbarSize[names.width],
scrollbarHeight = scrollbarSize[names.height],
i, childMargins, remainingWidth, remainingFlex, childContext, flex, flexedWidth, contentWidth, childWidth, percentageSpace, availableSpace;
if (!widthShrinkWrap && !targetSize[names.gotWidth]) {
return false;
}
for (i = 0; i < childItemsLength; ++i) {
childContext = childItems[i];
childMargins = childContext.marginInfo || childContext.getMarginInfo();
totalMargin += childMargins[widthName];
if (!childContext[names.widthModel].calculated) {
childWidth = childContext.getProp(widthName);
nonFlexWidth += childWidth;
if (isNaN(nonFlexWidth)) {
return false;
}
}
}
nonFlexWidth += totalMargin;
if (ownerContext.percentageWidths) {
percentageSpace = containerWidth - totalMargin;
if (isNaN(percentageSpace)) {
return false;
}
for (i = 0; i < childItemsLength; ++i) {
childContext = childItems[i];
if (childContext.percentageParallel) {
childWidth = Math.ceil(percentageSpace * childContext.percentageParallel);
childWidth = childContext.setWidth(childWidth);
nonFlexWidth += childWidth;
}
}
}
if (widthShrinkWrap) {
availableSpace = 0;
plan.tooNarrow = false;
} else {
availableSpace = containerWidth - nonFlexWidth;
if (needsScroll && needsScroll.perpendicular) {
availableSpace -= scrollbarHeight;
}
plan.tooNarrow = availableSpace < ownerContext.flexedMinWidth;
if (plan.tooNarrow && canScroll && canScroll.parallel) {
state.actualScroll.parallel = true;
}
}
contentWidth = nonFlexWidth;
remainingWidth = availableSpace;
remainingFlex = ownerContext.totalFlex;
for (i = 0; i < flexedItemsLength; i++) {
childContext = flexedItems[i];
flex = childContext.flex;
flexedWidth = me.roundFlex((flex / remainingFlex) * remainingWidth);
flexedWidth = childContext[setWidthName](flexedWidth);
contentWidth += flexedWidth;
remainingWidth = Math.max(0, remainingWidth - flexedWidth);
remainingFlex -= flex;
}
if (pack.center) {
left += remainingWidth / 2;
if (left < 0) {
left = 0;
}
} else if (pack.end) {
left += remainingWidth;
}
for (i = 0; i < childItemsLength; ++i) {
childContext = childItems[i];
childMargins = childContext.marginInfo;
left += childMargins[beforeXName];
childContext.setProp(names.x, left);
left += childMargins[afterXName] + childContext.props[widthName];
}
contentWidth += ownerContext.targetContext.getPaddingInfo()[widthName];
ownerContext.state.contentWidth = contentWidth;
if (needsScroll && needsScroll.perpendicular) {
if (widthShrinkWrap) {
contentWidth += scrollbarWidth;
}
ownerContext[names.hasOverflowY] = true;
ownerContext.target.componentLayout[names.setWidthInDom] = true;
ownerContext[names.invalidateScrollY] = Ext.isIE8;
}
ownerContext[names.setContentWidth](contentWidth);
return true;
},
calculatePerpendicular: function(ownerContext, names, plan) {
var me = this,
state = ownerContext.state,
needsScroll = state.needsScroll,
canScroll = state.canScroll,
heightShrinkWrap = ownerContext.perpendicularSizeModel.shrinkWrap,
targetSize = plan.targetSize,
childItems = ownerContext.childItems,
childItemsLength = childItems.length,
mmax = Math.max,
heightName = names.height,
setHeightName = names.setHeight,
beforeYName = names.beforeY,
topPositionName = names.y,
padding = me.padding,
top = padding[beforeYName],
availHeight = targetSize[heightName] - top - padding[names.afterY],
align = ownerContext.boxOptions.align,
isStretch = align.stretch,
isStretchMax = align.stretchmax,
isCenter = align.center,
isBottom = align.bottom,
constrain = me.constrainAlign,
maxHeight = 0,
hasPercentageSizes = 0,
onBeforeInvalidateChild = me.onBeforeConstrainInvalidateChild,
onAfterInvalidateChild = me.onAfterConstrainInvalidateChild,
scrollbarHeight = Ext.getScrollbarSize().height,
childTop, i, childHeight, childMargins, diff, height, childContext, stretchMaxPartner, stretchMaxChildren, shrinkWrapParallelOverflow, percentagePerpendicular;
if (!heightShrinkWrap && !targetSize[names.gotHeight]) {
return false;
}
if (isStretch || ((isCenter || isBottom) && !heightShrinkWrap)) {
if (isNaN(availHeight)) {
return false;
}
}
if (needsScroll && needsScroll.parallel) {
if (heightShrinkWrap) {
shrinkWrapParallelOverflow = true;
} else {
availHeight -= scrollbarHeight;
plan.targetSize[heightName] -= scrollbarHeight;
}
}
if (isStretch) {
height = availHeight;
maxHeight = mmax(height, ownerContext.smallestHeight);
} else {
for (i = 0; i < childItemsLength; i++) {
childContext = childItems[i];
childMargins = (childContext.marginInfo || childContext.getMarginInfo())[heightName];
if (!(percentagePerpendicular = childContext.percentagePerpendicular)) {
childHeight = childContext.getProp(heightName);
} else {
++hasPercentageSizes;
if (heightShrinkWrap) {
continue;
} else {
childHeight = percentagePerpendicular * availHeight - childMargins;
childHeight = childContext[names.setHeight](childHeight);
}
}
if (!heightShrinkWrap && constrain && childContext[names.heightModel].shrinkWrap && childHeight > availHeight) {
childContext.invalidate({
before: onBeforeInvalidateChild,
after: onAfterInvalidateChild,
layout: me,
childHeight: availHeight,
names: names
});
ownerContext.state.parallelDone = false;
}
if (isNaN(maxHeight = mmax(maxHeight, childHeight + childMargins, childContext.target[names.minHeight] || 0))) {
return false;
}
}
}
if (shrinkWrapParallelOverflow) {
maxHeight += scrollbarHeight;
ownerContext[names.hasOverflowX] = true;
ownerContext.target.componentLayout[names.setHeightInDom] = true;
ownerContext[names.invalidateScrollX] = Ext.isIE8;
}
stretchMaxPartner = ownerContext.stretchMaxPartner;
if (stretchMaxPartner) {
ownerContext.setProp('maxChildHeight', maxHeight);
stretchMaxChildren = stretchMaxPartner.childItems;
if (stretchMaxChildren && stretchMaxChildren.length) {
maxHeight = mmax(maxHeight, stretchMaxPartner.getProp('maxChildHeight'));
if (isNaN(maxHeight)) {
return false;
}
}
}
ownerContext[names.setContentHeight](maxHeight + me.padding[heightName] + ownerContext.targetContext.getPaddingInfo()[heightName]);
if (shrinkWrapParallelOverflow) {
maxHeight -= scrollbarHeight;
}
if (maxHeight > targetSize[heightName] && canScroll && canScroll.perpendicular) {
state.actualScroll.perpendicular = true;
}
plan.maxSize = maxHeight;
if (isStretchMax) {
height = maxHeight;
} else if (isCenter || isBottom || hasPercentageSizes) {
if (constrain) {
height = heightShrinkWrap ? maxHeight : availHeight;
} else {
height = heightShrinkWrap ? maxHeight : mmax(availHeight, maxHeight);
}
height -= ownerContext.innerCtContext.getBorderInfo()[heightName];
}
for (i = 0; i < childItemsLength; i++) {
childContext = childItems[i];
childMargins = childContext.marginInfo || childContext.getMarginInfo();
childTop = top + childMargins[beforeYName];
if (isStretch) {
childContext[setHeightName](height - childMargins[heightName]);
} else {
percentagePerpendicular = childContext.percentagePerpendicular;
if (heightShrinkWrap && percentagePerpendicular) {
childMargins = childContext.marginInfo || childContext.getMarginInfo();
childHeight = percentagePerpendicular * height - childMargins[heightName];
childHeight = childContext.setHeight(childHeight);
}
if (isCenter) {
diff = height - childContext.props[heightName];
if (diff > 0) {
childTop = top + Math[me.alignRoundingMethod](diff / 2);
}
} else if (isBottom) {
childTop = mmax(0, height - childTop - childContext.props[heightName]);
}
}
childContext.setProp(topPositionName, childTop);
}
return true;
},
onBeforeConstrainInvalidateChild: function(childContext, options) {
var heightModelName = options.names.heightModel;
if (!childContext[heightModelName].constrainedMin) {
childContext[heightModelName] = Ext.layout.SizeModel.calculated;
}
},
onAfterConstrainInvalidateChild: function(childContext, options) {
var names = options.names;
childContext.setProp(names.beforeY, 0);
if (childContext[names.heightModel].calculated) {
childContext[names.setHeight](options.childHeight);
}
},
calculateStretchMax: function(ownerContext, names, plan) {
var me = this,
heightName = names.height,
widthName = names.width,
childItems = ownerContext.childItems,
length = childItems.length,
height = plan.maxSize,
onBeforeStretchMaxInvalidateChild = me.onBeforeStretchMaxInvalidateChild,
onAfterStretchMaxInvalidateChild = me.onAfterStretchMaxInvalidateChild,
childContext, props, i, childHeight;
for (i = 0; i < length; ++i) {
childContext = childItems[i];
props = childContext.props;
childHeight = height - childContext.getMarginInfo()[heightName];
if (childHeight !== props[heightName] ||
childContext[names.heightModel].constrained) {
childContext.invalidate({
before: onBeforeStretchMaxInvalidateChild,
after: onAfterStretchMaxInvalidateChild,
layout: me,
childWidth: props[widthName],
childHeight: childHeight,
childX: props.x,
childY: props.y,
names: names
});
}
}
},
onBeforeStretchMaxInvalidateChild: function(childContext, options) {
var heightModelName = options.names.heightModel;
if (!childContext[heightModelName].constrainedMax) {
childContext[heightModelName] = Ext.layout.SizeModel.calculated;
}
},
onAfterStretchMaxInvalidateChild: function(childContext, options) {
var names = options.names,
childHeight = options.childHeight,
childWidth = options.childWidth;
childContext.setProp('x', options.childX);
childContext.setProp('y', options.childY);
if (childContext[names.heightModel].calculated) {
childContext[names.setHeight](childHeight);
}
if (childContext[names.widthModel].calculated) {
childContext[names.setWidth](childWidth);
}
},
completeLayout: function(ownerContext) {
var me = this,
names = ownerContext.boxNames,
invalidateScrollX = ownerContext.invalidateScrollX,
invalidateScrollY = ownerContext.invalidateScrollY,
overflowHandler = me.overflowHandler,
scrollRestore = ownerContext.scrollRestore,
dom, el, overflowX, overflowY, styles, scroll, scrollable;
if (overflowHandler) {
overflowHandler.completeLayout(ownerContext);
}
if (invalidateScrollX || invalidateScrollY) {
el = me.getTarget();
dom = el.dom;
styles = dom.style;
if (invalidateScrollX) {
overflowX = el.getStyle('overflowX');
if (overflowX === 'auto') {
overflowX = styles.overflowX;
styles.overflowX = 'scroll';
} else
{
invalidateScrollX = false;
}
}
if (invalidateScrollY) {
overflowY = el.getStyle('overflowY');
if (overflowY === 'auto') {
overflowY = styles.overflowY;
styles.overflowY = 'scroll';
} else
{
invalidateScrollY = false;
}
}
if (invalidateScrollX || invalidateScrollY) {
dom.scrollWidth;
if (invalidateScrollX) {
styles.overflowX = overflowX;
}
if (invalidateScrollY) {
styles.overflowY = overflowY;
}
}
}
if (scrollRestore) {
ownerContext.ownerScrollable.scrollTo(scrollRestore.x, scrollRestore.y);
}
},
finishedLayout: function(ownerContext) {
var overflowHandler = this.overflowHandler;
if (overflowHandler) {
overflowHandler.finishedLayout(ownerContext);
}
this.callParent(arguments);
},
getLayoutItems: function() {
var items = this.callParent(),
n = items.length,
lastVisibleItem, hide, i, item, splitAfter, splitBefore, splitter;
for (i = 0; i < n; ++i) {
if ((item = items[i]).isSplitter) {
continue;
}
splitter = item.splitter;
if (item.hidden) {
if (splitter) {
if (!splitter.hidden) {
splitter.hidden = true;
if (splitter.el) {
splitter.el.hide();
}
}
}
continue;
}
if (splitter) {
splitBefore = splitter.collapseTarget === 'next';
} else {
splitBefore = false;
}
hide = null;
if (lastVisibleItem && splitAfter) {
if (splitAfter.hidden) {
splitAfter.hidden = false;
if (splitAfter.el) {
splitAfter.el.show();
}
}
if (splitBefore) {
hide = true;
}
} else if (splitBefore) {
hide = !lastVisibleItem;
}
if (hide !== null && splitter.hidden !== hide) {
splitter.hidden = hide;
if (splitter.el) {
splitter.el.setVisible(!hide);
}
}
splitAfter = !splitBefore && splitter;
lastVisibleItem = item;
}
if (lastVisibleItem && splitAfter && !splitAfter.hidden) {
splitAfter.hidden = true;
if (splitAfter.el) {
splitAfter.el.hide();
}
}
return items;
},
getScrollerEl: function() {
return this.innerCt;
},
insertSplitter: function(item, index, hidden, splitterCfg) {
var splitter = {
xtype: 'splitter',
id: item.id + '-splitter',
hidden: hidden,
splitterFor: item,
synthetic: true
},
at = index + ((splitterCfg.collapseTarget === 'prev') ? 1 : 0);
splitter[this.names.height] = '100%';
if (splitterCfg) {
Ext.apply(splitter, splitterCfg);
}
item.splitter = this.owner.add(at, splitter);
},
publishInnerCtSize: function(ownerContext, widthOffset) {
widthOffset = widthOffset || 0;
var me = this,
state = ownerContext.state,
names = ownerContext.boxNames,
heightName = names.height,
widthName = names.width,
align = ownerContext.boxOptions.align,
padding = me.padding,
plan = state.boxPlan,
targetSize = plan.targetSize,
height = plan.maxSize,
needsScroll = state.needsScroll,
innerCtContext = ownerContext.innerCtContext,
innerCtWidth, innerCtHeight;
if (ownerContext.parallelSizeModel.shrinkWrap || (plan.tooNarrow && state.canScroll)) {
innerCtWidth = state.contentWidth - ownerContext.targetContext.getPaddingInfo()[widthName];
} else {
innerCtWidth = targetSize[widthName];
if (needsScroll && needsScroll.perpendicular) {
innerCtWidth -= Ext.getScrollbarSize()[widthName];
}
}
innerCtWidth -= widthOffset;
me.owner.tooNarrow = plan.tooNarrow;
if (align.stretch) {
innerCtHeight = height;
} else {
innerCtHeight = plan.maxSize + padding[names.beforeY] + padding[names.afterY] + innerCtContext.getBorderInfo()[heightName];
if (!ownerContext.perpendicularSizeModel.shrinkWrap && (align.center || align.bottom)) {
innerCtHeight = Math.max(targetSize[heightName], innerCtHeight);
}
}
innerCtContext[names.setWidth](innerCtWidth);
innerCtContext[names.setHeight](innerCtHeight);
ownerContext.targetElContext.setWidth(ownerContext.innerCtContext.props.width - (me.vertical ? 0 : (widthOffset || 0)));
if (isNaN(innerCtWidth + innerCtHeight)) {
me.done = false;
}
},
onAdd: function(item, index) {
var me = this,
split = me.enableSplitters && item.split && !item.isButton;
me.callParent(arguments);
if (split) {
if (split === true) {
split = {
collapseTarget: 'next'
};
} else if (Ext.isString(split)) {
split = {
collapseTarget: split === 'before' ? 'next' : 'prev'
};
} else {
split = Ext.apply({
collapseTarget: split.side === 'before' ? 'next' : 'prev'
}, split);
}
me.insertSplitter(item, index, !!item.hidden, split);
}
},
onRemove: function(comp, isDestroying) {
var me = this,
names = me.names,
owner = me.owner,
splitter = comp.splitter,
overflowHandler = me.overflowHandler,
el;
me.callParent(arguments);
if (splitter && owner.contains(splitter)) {
owner.doRemove(splitter, true);
comp.splitter = null;
}
if (overflowHandler) {
overflowHandler.onRemove(comp);
}
if (comp.layoutMarginCap === me.id) {
delete comp.layoutMarginCap;
}
if (!owner.destroying && !isDestroying && comp.rendered) {
el = comp.getEl();
if (el) {
el.setStyle(names.beforeY, '');
el.setStyle(names.beforeX, '');
el.setStyle('margin', '');
}
}
},
applyOverflowHandler: function(overflowHandler, oldOverflowHandler) {
var type;
if (typeof overflowHandler === 'string') {
overflowHandler = {
type: overflowHandler
};
}
type = overflowHandler.type;
if (oldOverflowHandler && oldOverflowHandler.type === overflowHandler.type) {
delete overflowHandler.type;
oldOverflowHandler.setConfig(overflowHandler);
return oldOverflowHandler;
}
overflowHandler.layout = this;
return Ext.Factory.boxOverflow(overflowHandler);
},
getRenderTarget: function() {
return this.targetEl;
},
getElementTarget: function() {
return this.innerCt;
},
calculateChildBox: Ext.deprecated(),
calculateChildBoxes: Ext.deprecated(),
updateChildBoxes: Ext.deprecated(),
destroy: function() {
var me = this;
Ext.destroy(me.innerCt, me.overflowHandler);
me.flexSortFn = me.innerCt = null;
me.callParent(arguments);
},
getRenderData: function() {
var data = this.callParent();
data.targetElCls = this.targetElCls;
return data;
},
updateVertical: function(vertical) {
var me = this,
overflowHandler = me.overflowHandler,
owner = me.owner,
props = me._props;
Ext.apply(me, vertical ? props.vbox : props.hbox);
if (overflowHandler && owner && owner.rendered) {
overflowHandler.setVertical(vertical);
}
},
_props: {
'hbox': {
direction: 'horizontal',
oppositeDirection: 'vertical',
horizontal: true,
vertical: false,
names: {
beforeX: 'left',
beforeScrollX: 'left',
leftCap: 'Left',
afterX: 'right',
width: 'width',
contentWidth: 'contentWidth',
minWidth: 'minWidth',
maxWidth: 'maxWidth',
widthCap: 'Width',
widthModel: 'widthModel',
widthIndex: 0,
x: 'x',
getX: 'getX',
setX: 'setX',
scrollLeft: 'scrollLeft',
overflowX: 'overflowX',
hasOverflowX: 'hasOverflowX',
invalidateScrollX: 'invalidateScrollX',
parallelMargins: 'lr',
center: 'middle',
beforeY: 'top',
afterY: 'bottom',
height: 'height',
contentHeight: 'contentHeight',
minHeight: 'minHeight',
maxHeight: 'maxHeight',
heightCap: 'Height',
heightModel: 'heightModel',
heightIndex: 1,
y: 'y',
getY: 'getY',
setY: 'setY',
overflowY: 'overflowY',
hasOverflowY: 'hasOverflowY',
invalidateScrollY: 'invalidateScrollY',
perpendicularMargins: 'tb',
getWidth: 'getWidth',
getHeight: 'getHeight',
setWidth: 'setWidth',
setHeight: 'setHeight',
gotWidth: 'gotWidth',
gotHeight: 'gotHeight',
setContentWidth: 'setContentWidth',
setContentHeight: 'setContentHeight',
setWidthInDom: 'setWidthInDom',
setHeightInDom: 'setHeightInDom',
getScrollLeft: 'getScrollLeft',
setScrollLeft: 'setScrollLeft',
scrollTo: 'scrollTo'
},
sizePolicy: {
flex: {
'': {
readsWidth: 0,
readsHeight: 1,
setsWidth: 1,
setsHeight: 0
},
stretch: {
readsWidth: 0,
readsHeight: 0,
setsWidth: 1,
setsHeight: 1
},
stretchmax: {
readsWidth: 0,
readsHeight: 1,
setsWidth: 1,
setsHeight: 1
}
},
'': {
readsWidth: 1,
readsHeight: 1,
setsWidth: 0,
setsHeight: 0
},
stretch: {
readsWidth: 1,
readsHeight: 0,
setsWidth: 0,
setsHeight: 1
},
stretchmax: {
readsWidth: 1,
readsHeight: 1,
setsWidth: 0,
setsHeight: 1
}
}
},
'vbox': {
direction: 'vertical',
oppositeDirection: 'horizontal',
horizontal: false,
vertical: true,
names: {
beforeX: 'top',
beforeScrollX: 'top',
leftCap: 'Top',
afterX: 'bottom',
width: 'height',
contentWidth: 'contentHeight',
minWidth: 'minHeight',
maxWidth: 'maxHeight',
widthCap: 'Height',
widthModel: 'heightModel',
widthIndex: 1,
x: 'y',
getX: 'getY',
setX: 'setY',
scrollLeft: 'scrollTop',
overflowX: 'overflowY',
hasOverflowX: 'hasOverflowY',
invalidateScrollX: 'invalidateScrollY',
parallelMargins: 'tb',
center: 'center',
beforeY: 'left',
afterY: 'right',
height: 'width',
contentHeight: 'contentWidth',
minHeight: 'minWidth',
maxHeight: 'maxWidth',
heightCap: 'Width',
heightModel: 'widthModel',
heightIndex: 0,
y: 'x',
getY: 'getX',
setY: 'setX',
overflowY: 'overflowX',
hasOverflowY: 'hasOverflowX',
invalidateScrollY: 'invalidateScrollX',
perpendicularMargins: 'lr',
getWidth: 'getHeight',
getHeight: 'getWidth',
setWidth: 'setHeight',
setHeight: 'setWidth',
gotWidth: 'gotHeight',
gotHeight: 'gotWidth',
setContentWidth: 'setContentHeight',
setContentHeight: 'setContentWidth',
setWidthInDom: 'setHeightInDom',
setHeightInDom: 'setWidthInDom',
getScrollLeft: 'getScrollTop',
setScrollLeft: 'setScrollTop',
scrollTo: 'scrollTo'
},
sizePolicy: {
flex: {
'': {
readsWidth: 1,
readsHeight: 0,
setsWidth: 0,
setsHeight: 1
},
stretch: {
readsWidth: 0,
readsHeight: 0,
setsWidth: 1,
setsHeight: 1
},
stretchmax: {
readsWidth: 1,
readsHeight: 0,
setsWidth: 1,
setsHeight: 1
}
},
'': {
readsWidth: 1,
readsHeight: 1,
setsWidth: 0,
setsHeight: 0
},
stretch: {
readsWidth: 0,
readsHeight: 1,
setsWidth: 1,
setsHeight: 0
},
stretchmax: {
readsWidth: 1,
readsHeight: 1,
setsWidth: 1,
setsHeight: 0
}
}
}
}
});
Ext.define('Ext.layout.container.HBox', {
extend: 'Ext.layout.container.Box',
alias: 'layout.hbox',
alternateClassName: 'Ext.layout.HBoxLayout',
type: 'hbox',
vertical: false
});
Ext.define('Ext.layout.container.VBox', {
extend: 'Ext.layout.container.Box',
alias: 'layout.vbox',
alternateClassName: 'Ext.layout.VBoxLayout',
type: 'vbox',
vertical: true
});
Ext.define('Ext.util.KeyMap', {
alternateClassName: 'Ext.KeyMap',
eventName: 'keydown',
constructor: function(config) {
var me = this;
if ((arguments.length !== 1) || (typeof config === 'string') || config.dom || config.tagName || config === document || config.isComponent) {
me.legacyConstructor.apply(me, arguments);
return;
}
Ext.apply(me, config);
me.bindings = [];
if (!me.target.isComponent) {
me.target = Ext.get(me.target);
}
if (me.binding) {
me.addBinding(me.binding);
} else if (config.key) {
me.addBinding(config);
}
me.enable();
},
legacyConstructor: function(el, binding, eventName) {
var me = this;
Ext.apply(me, {
target: Ext.get(el),
eventName: eventName || me.eventName,
bindings: []
});
if (binding) {
me.addBinding(binding);
}
me.enable();
},
addBinding: function(binding) {
var me = this,
keyCode = binding.key,
i, len;
if (me.processing) {
me.bindings = me.bindings.slice(0);
}
if (Ext.isArray(binding)) {
for (i = 0 , len = binding.length; i < len; i++) {
me.addBinding(binding[i]);
}
return;
}
me.bindings.push(Ext.apply({
keyCode: me.processKeys(keyCode)
}, binding));
},
removeBinding: function(binding) {
var me = this,
bindings = me.bindings,
len = bindings.length,
i, item, keys;
if (me.processing) {
me.bindings = bindings.slice(0);
}
keys = me.processKeys(binding.key);
for (i = 0; i < len; ++i) {
item = bindings[i];
if ((item.fn || item.handler) === (binding.fn || binding.handler) && item.scope === binding.scope) {
if (binding.alt === item.alt && binding.crtl === item.crtl && binding.shift === item.shift) {
if (Ext.Array.equals(item.keyCode, keys)) {
Ext.Array.erase(me.bindings, i, 1);
return;
}
}
}
}
},
processKeys: function(keyCode) {
var processed = false,
key, keys, keyString, len, i;
if (keyCode.test) {
return keyCode;
}
if (Ext.isString(keyCode)) {
keys = [];
keyString = keyCode.toUpperCase();
for (i = 0 , len = keyString.length; i < len; ++i) {
keys.push(keyString.charCodeAt(i));
}
keyCode = keys;
processed = true;
}
if (!Ext.isArray(keyCode)) {
keyCode = [
keyCode
];
}
if (!processed) {
for (i = 0 , len = keyCode.length; i < len; ++i) {
key = keyCode[i];
if (Ext.isString(key)) {
keyCode[i] = key.toUpperCase().charCodeAt(0);
}
}
}
return keyCode;
},
handleTargetEvent: function(event) {
var me = this,
bindings, i, len;
if (me.enabled) {
bindings = me.bindings;
i = 0;
len = bindings.length;
event = me.processEvent.apply(me.processEventScope || me, arguments);
if (event) {
me.lastKeyEvent = event;
if (me.ignoreInputFields && Ext.fly(event.target).isInputField()) {
return;
}
if (!event.getKey) {
return event;
}
me.processing = true;
for (; i < len; ++i) {
me.processBinding(bindings[i], event);
}
me.processing = false;
}
}
},
processEvent: Ext.identityFn,
processBinding: function(binding, event) {
if (this.checkModifiers(binding, event)) {
var key = event.getKey(),
handler = binding.fn || binding.handler,
scope = binding.scope || this,
keyCode = binding.keyCode,
defaultEventAction = binding.defaultEventAction,
i, len;
if (keyCode.test) {
if (keyCode.test(String.fromCharCode(event.getCharCode()))) {
if (handler.call(scope, key, event) !== true && defaultEventAction) {
event[defaultEventAction]();
}
}
}
else if (keyCode.length) {
for (i = 0 , len = keyCode.length; i < len; ++i) {
if (key === keyCode[i]) {
if (handler.call(scope, key, event) !== true && defaultEventAction) {
event[defaultEventAction]();
}
break;
}
}
}
}
},
checkModifiers: function(binding, event) {
var keys = [
'shift',
'ctrl',
'alt'
],
i = 0,
len = keys.length,
val, key;
for (; i < len; ++i) {
key = keys[i];
val = binding[key];
if (!(val === undefined || (val === event[key + 'Key']))) {
return false;
}
}
return true;
},
on: function(key, fn, scope) {
var keyCode, shift, ctrl, alt;
if (Ext.isObject(key) && !Ext.isArray(key)) {
keyCode = key.key;
shift = key.shift;
ctrl = key.ctrl;
alt = key.alt;
} else {
keyCode = key;
}
this.addBinding({
key: keyCode,
shift: shift,
ctrl: ctrl,
alt: alt,
fn: fn,
scope: scope
});
},
un: function(key, fn, scope) {
var keyCode, shift, ctrl, alt;
if (Ext.isObject(key) && !Ext.isArray(key)) {
keyCode = key.key;
shift = key.shift;
ctrl = key.ctrl;
alt = key.alt;
} else {
keyCode = key;
}
this.removeBinding({
key: keyCode,
shift: shift,
ctrl: ctrl,
alt: alt,
fn: fn,
scope: scope
});
},
isEnabled: function() {
return this.enabled;
},
enable: function() {
var me = this;
if (!me.enabled) {
me.target.on(me.eventName, me.handleTargetEvent, me, {
capture: me.capture
});
me.enabled = true;
}
},
disable: function() {
var me = this;
if (me.enabled) {
me.target.removeListener(me.eventName, me.handleTargetEvent, me);
me.enabled = false;
}
},
setDisabled: function(disabled) {
if (disabled) {
this.disable();
} else {
this.enable();
}
},
destroy: function(removeTarget) {
var me = this,
target = me.target;
me.bindings = [];
me.disable();
if (removeTarget) {
target.destroy();
}
delete me.target;
}
});
Ext.define('Ext.util.KeyNav', {
alternateClassName: 'Ext.KeyNav',
requires: [
'Ext.util.KeyMap'
],
disabled: false,
defaultEventAction: false,
forceKeyDown: false,
eventName: 'keypress',
statics: {
keyOptions: {
left: 37,
right: 39,
up: 38,
down: 40,
space: 32,
pageUp: 33,
pageDown: 34,
del: 46,
backspace: 8,
home: 36,
end: 35,
enter: 13,
esc: 27,
tab: 9
}
},
constructor: function(config) {
var me = this;
if (arguments.length === 2) {
me.legacyConstructor.apply(me, arguments);
return;
}
me.doConstruction(config);
},
legacyConstructor: function(el, config) {
this.doConstruction(Ext.apply({
target: el
}, config));
},
doConstruction: function(config) {
var me = this,
keymapCfg = {
target: config.target,
ignoreInputFields: config.ignoreInputFields,
eventName: me.getKeyEvent('forceKeyDown' in config ? config.forceKeyDown : me.forceKeyDown, config.eventName),
capture: config.capture
},
map;
if (me.map) {
me.map.destroy();
}
me.initConfig(config);
if (config.processEvent) {
keymapCfg.processEvent = config.processEvent;
keymapCfg.processEventScope = config.processEventScope || me;
}
if (config.keyMap) {
map = me.map = config.keyMap;
} else
{
map = me.map = new Ext.util.KeyMap(keymapCfg);
me.destroyKeyMap = true;
}
this.addBindings(config);
map.disable();
if (!config.disabled) {
map.enable();
}
},
addBindings: function(bindings) {
var me = this,
keyName, binding,
map = me.map,
keyCodes = Ext.util.KeyNav.keyOptions,
defaultScope = bindings.scope || me;
for (keyName in bindings) {
binding = bindings[keyName];
if (binding && (keyName.length === 1 || (keyName = keyCodes[keyName]) || (!isNaN(keyName = parseInt(keyName, 10))))) {
if (typeof binding === 'function') {
binding = {
handler: binding,
defaultEventAction: (bindings.defaultEventAction !== undefined) ? bindings.defaultEventAction : me.defaultEventAction
};
}
map.addBinding({
key: keyName,
ctrl: binding.ctrl,
shift: binding.shift,
alt: binding.alt,
handler: Ext.Function.bind(me.handleEvent, binding.scope || defaultScope, [
binding.handler || binding.fn,
me
], true),
defaultEventAction: (binding.defaultEventAction !== undefined) ? binding.defaultEventAction : me.defaultEventAction
});
}
}
},
handleEvent: function(keyCode, event, handler, keyNav) {
keyNav.lastKeyEvent = event;
return handler.call(this, event);
},
destroy: function(removeEl) {
if (this.destroyKeyMap) {
this.map.destroy(removeEl);
}
delete this.map;
},
enable: function() {
if (this.map) {
this.map.enable();
this.disabled = false;
}
},
disable: function() {
if (this.map) {
this.map.disable();
}
this.disabled = true;
},
setDisabled: function(disabled) {
this.map.setDisabled(disabled);
this.disabled = disabled;
},
getKeyEvent: function(forceKeyDown, configuredEventName) {
if (forceKeyDown || (Ext.supports.SpecialKeyDownRepeat && !configuredEventName)) {
return 'keydown';
} else {
return configuredEventName || this.eventName;
}
}
});
Ext.define('Ext.util.FocusableContainer', {
extend: 'Ext.Mixin',
requires: [
'Ext.util.KeyNav'
],
mixinConfig: {
id: 'focusablecontainer',
before: {
onAdd: 'onFocusableChildAdd',
onRemove: 'onFocusableChildRemove',
destroy: 'destroyFocusableContainer',
onFocusEnter: 'onFocusEnter'
},
after: {
afterRender: 'initFocusableContainer',
onFocusLeave: 'onFocusLeave'
}
},
isFocusableContainer: true,
enableFocusableContainer: true,
activeChildTabIndex: 0,
inactiveChildTabIndex: -1,
privates: {
initFocusableContainer: function() {
if (this.enableFocusableContainer) {
this.doInitFocusableContainer();
}
},
doInitFocusableContainer: function() {
var me = this,
el;
el = me.getFocusableContainerEl();
me.activateFocusableContainerEl(el);
me.mon(el, 'mousedown', me.onFocusableContainerMousedown, me);
me.focusableKeyNav = me.createFocusableContainerKeyNav(el);
},
createFocusableContainerKeyNav: function(el) {
var me = this;
return new Ext.util.KeyNav(el, {
ignoreInputFields: true,
scope: me,
tab: me.onFocusableContainerTabKey,
enter: me.onFocusableContainerEnterKey,
space: me.onFocusableContainerSpaceKey,
up: me.onFocusableContainerUpKey,
down: me.onFocusableContainerDownKey,
left: me.onFocusableContainerLeftKey,
right: me.onFocusableContainerRightKey
});
},
destroyFocusableContainer: function() {
if (this.enableFocusableContainer) {
this.doDestroyFocusableContainer();
}
},
doDestroyFocusableContainer: function() {
var keyNav = this.focusableKeyNav;
if (keyNav) {
keyNav.destroy();
delete this.focusableKeyNav;
}
},
getFocusables: function() {
return this.items.items;
},
initDefaultFocusable: function(beforeRender) {
var me = this,
activeIndex = me.activeChildTabIndex,
haveFocusable = false,
items, item, i, len, tabIdx;
items = me.getFocusables();
len = items.length;
if (!len) {
return;
}
for (i = 0; i < len; i++) {
item = items[i];
if (item.focusable) {
haveFocusable = true;
tabIdx = item.getTabIndex();
if (tabIdx != null && tabIdx >= activeIndex) {
return item;
}
}
}
if (!haveFocusable) {
return;
}
item = me.findNextFocusableChild(null, true, items, beforeRender);
if (item) {
me.activateFocusable(item);
}
return item;
},
clearFocusables: function() {
var me = this,
items = me.getFocusables(),
len = items.length,
item, i;
for (i = 0; i < len; i++) {
item = items[i];
if (item.focusable) {
me.deactivateFocusable(item);
}
}
},
activateFocusable: function(child,
newTabIndex) {
var activeIndex = newTabIndex != null ? newTabIndex : this.activeChildTabIndex;
child.setTabIndex(activeIndex);
},
deactivateFocusable: function(child,
newTabIndex) {
var inactiveIndex = newTabIndex != null ? newTabIndex : this.inactiveChildTabIndex;
child.setTabIndex(inactiveIndex);
},
onFocusableContainerTabKey: function() {
return true;
},
onFocusableContainerEnterKey: function() {
return true;
},
onFocusableContainerSpaceKey: function() {
return true;
},
onFocusableContainerUpKey: function(e) {
return this.moveChildFocus(e, false);
},
onFocusableContainerLeftKey: function(e) {
return this.moveChildFocus(e, false);
},
onFocusableContainerRightKey: function(e) {
return this.moveChildFocus(e, true);
},
onFocusableContainerDownKey: function(e) {
return this.moveChildFocus(e, true);
},
getFocusableFromEvent: function(e) {
var child = Ext.Component.fromElement(e.getTarget());
if (!child) {
Ext.Error.raise("No focusable child found for keyboard event!");
}
return child;
},
moveChildFocus: function(e, forward) {
var child = this.getFocusableFromEvent(e);
return this.focusChild(child, forward, e);
},
focusChild: function(child, forward) {
var nextChild = this.findNextFocusableChild(child, forward);
if (nextChild) {
nextChild.focus();
}
return nextChild;
},
findNextFocusableChild: function(child, step, items, beforeRender) {
var item, idx, i, len;
items = items || this.getFocusables();
idx = Ext.Array.indexOf(items, child);
step = step === true ? 1 : step === false ? -1 : step;
len = items.length;
i = step > 0 ? (idx < len ? idx + step : 0) : (idx > 0 ? idx + step : len - 1);
for (; ; i += step) {
if (idx < 0 && (i >= len || i < 0)) {
return null;
}
else if (i >= len) {
i = -1;
continue;
}
else if (i < 0) {
i = len;
continue;
}
else if (i === idx) {
return null;
}
item = items[i];
if (!item || !item.focusable) {
continue;
}
if (beforeRender || (item.isFocusable && item.isFocusable())) {
return item;
}
}
return null;
},
getFocusableContainerEl: function() {
return this.el;
},
onFocusableChildAdd: function(child) {
return this.doFocusableChildAdd(child);
},
activateFocusableContainerEl: function(el) {
el = el || this.getFocusableContainerEl();
el.set({
tabindex: this.activeChildTabIndex
});
},
deactivateFocusableContainerEl: function(el) {
el = el || this.getFocusableContainerEl();
el.set({
tabindex: this.inactiveChildTabIndex
});
},
doFocusableChildAdd: function(child) {
if (child.focusable) {
child.focusableContainer = this;
this.deactivateFocusable(child);
}
},
onFocusableChildRemove: function(child) {
return this.doFocusableChildRemove(child);
},
doFocusableChildRemove: function(child) {
if (child === this.lastFocusedChild) {
this.lastFocusedChild = null;
this.activateFocusableContainerEl();
}
delete child.focusableContainer;
},
onFocusableContainerMousedown: function(e, target) {
var targetCmp = Ext.Component.fromElement(target);
this.mousedownTimestamp = targetCmp === this ? Ext.Date.now() : 0;
},
onFocusEnter: function(e) {
var me = this,
target = e.toComponent,
mousedownTimestamp = me.mousedownTimestamp,
epsilon = 50,
child;
me.mousedownTimestamp = 0;
if (target === me) {
if (!mousedownTimestamp || Ext.Date.now() - mousedownTimestamp > epsilon) {
child = me.initDefaultFocusable();
if (child) {
me.deactivateFocusableContainerEl();
child.focus();
}
}
} else {
me.deactivateFocusableContainerEl();
}
return target;
},
onFocusLeave: function(e) {
var me = this,
lastFocused = me.lastFocusedChild;
if (!me.isDestroyed) {
me.clearFocusables();
if (lastFocused) {
me.activateFocusable(lastFocused);
} else {
me.activateFocusableContainerEl();
}
}
},
beforeFocusableChildBlur: Ext.privateFn,
afterFocusableChildBlur: Ext.privateFn,
beforeFocusableChildFocus: function(child) {
var me = this;
me.clearFocusables();
me.activateFocusable(child);
if (child.needArrowKeys) {
me.guardFocusableChild(child);
}
},
guardFocusableChild: function(child) {
var me = this,
index = me.activeChildTabIndex,
guard;
guard = me.findNextFocusableChild(child, -1);
if (guard) {
guard.setTabIndex(index);
}
guard = me.findNextFocusableChild(child, 1);
if (guard) {
guard.setTabIndex(index);
}
},
afterFocusableChildFocus: function(child) {
this.lastFocusedChild = child;
},
onFocusableChildShow: Ext.privateFn,
onFocusableChildHide: Ext.privateFn,
onFocusableChildEnable: Ext.privateFn,
onFocusableChildDisable: Ext.privateFn,
onFocusableChildMasked: Ext.privateFn,
onFocusableChildDestroy: Ext.privateFn,
onFocusableChildUpdate: Ext.privateFn
}
});
Ext.define('Ext.toolbar.Toolbar', {
extend: 'Ext.container.Container',
requires: [
'Ext.layout.container.HBox',
'Ext.layout.container.VBox'
],
uses: [
'Ext.toolbar.Fill',
'Ext.toolbar.Separator'
],
alias: 'widget.toolbar',
alternateClassName: 'Ext.Toolbar',
mixins: [
'Ext.util.FocusableContainer'
],
isToolbar: true,
baseCls: Ext.baseCSSPrefix + 'toolbar',
ariaRole: 'toolbar',
defaultType: 'button',
layout: undefined,
vertical: undefined,
enableOverflow: false,
overflowHandler: null,
defaultButtonUI: 'default-toolbar',
defaultFieldUI: 'default',
defaultFooterButtonUI: 'default',
defaultFooterFieldUI: 'default',
trackMenus: true,
itemCls: Ext.baseCSSPrefix + 'toolbar-item',
statics: {
shortcuts: {
'-': 'tbseparator',
' ': 'tbspacer'
},
shortcutsHV: {
0: {
'->': {
xtype: 'tbfill',
height: 0
}
},
1: {
'->': {
xtype: 'tbfill',
width: 0
}
}
}
},
initComponent: function() {
var me = this,
layout = me.layout,
vertical = me.vertical;
if (vertical === undefined) {
me.vertical = vertical = me.dock === 'right' || me.dock === 'left';
}
me.layout = layout = Ext.applyIf(Ext.isString(layout) ? {
type: layout
} : layout || {}, {
type: vertical ? 'vbox' : 'hbox',
align: vertical ? 'stretchmax' : 'middle'
});
if (me.overflowHandler) {
layout.overflowHandler = me.overflowHandler;
} else if (me.enableOverflow) {
layout.overflowHandler = 'menu';
}
if (vertical) {
me.addClsWithUI('vertical');
}
if (me.ui === 'footer') {
me.ignoreBorderManagement = true;
}
me.callParent();
},
getRefItems: function(deep) {
var me = this,
items = me.callParent(arguments),
layout = me.layout,
handler;
if (deep && (me.enableOverflow || (me.overflowHandler === 'menu'))) {
handler = layout.overflowHandler;
if (handler && handler.menu) {
items = items.concat(handler.menu.getRefItems(deep));
}
}
return items;
},
lookupComponent: function(c) {
var args = arguments,
shortcut, T;
if (typeof c === 'string') {
T = Ext.toolbar.Toolbar;
shortcut = T.shortcutsHV[this.vertical ? 1 : 0][c] || T.shortcuts[c];
if (typeof shortcut === 'string') {
c = {
xtype: shortcut
};
} else if (shortcut) {
c = Ext.apply({}, shortcut);
} else {
c = {
xtype: 'tbtext',
text: c
};
}
this.applyDefaults(c);
args = [
c
];
}
return this.callParent(args);
},
onBeforeAdd: function(component) {
var me = this,
isFooter = me.ui === 'footer',
defaultButtonUI = isFooter ? me.defaultFooterButtonUI : me.defaultButtonUI;
if (component.isSegmentedButton) {
if (component.getDefaultUI() === 'default' && !component.config.hasOwnProperty('defaultUI')) {
component.setDefaultUI(defaultButtonUI);
}
} else if (component.ui === 'default' && !component.hasOwnProperty('ui')) {
if (component.isButton) {
component.ui = defaultButtonUI;
} else if (component.isFormField) {
component.ui = isFooter ? me.defaultFooterFieldUI : me.defaultFieldUI;
}
}
if (component instanceof Ext.toolbar.Separator) {
component.setUI(me.vertical ? 'vertical' : 'horizontal');
}
me.callParent(arguments);
},
onAdd: function(component) {
this.callParent(arguments);
this.trackMenu(component);
},
onRemove: function(c) {
this.callParent(arguments);
this.trackMenu(c, true);
},
privates: {
applyDefaults: function(c) {
if (!Ext.isString(c)) {
c = this.callParent(arguments);
}
return c;
},
trackMenu: function(item, remove) {
var me = this;
if (me.trackMenus && item.menu) {
item[remove ? 'un' : 'on']({
mouseover: me.onButtonOver,
menushow: me.onButtonMenuShow,
menuhide: me.onButtonMenuHide,
scope: me
});
}
},
getChildItemsToDisable: function() {
return this.items.getRange();
},
onButtonOver: function(btn, e) {
var activeMenuBtn = this.activeMenuBtn;
if (activeMenuBtn && activeMenuBtn !== btn) {
activeMenuBtn.hideMenu();
btn.focus();
btn.showMenu(e);
this.activeMenuBtn = btn;
}
},
onButtonMenuShow: function(btn) {
this.activeMenuBtn = btn;
},
onButtonMenuHide: function(btn) {
this.activeMenuBtn = null;
}
}
});
Ext.define('Ext.dd.DragDrop', {
requires: [
'Ext.dd.DragDropManager'
],
constructor: function(id, sGroup, config) {
if (id) {
this.init(id, sGroup, config);
}
},
id: null,
config: null,
dragElId: null,
handleElId: null,
invalidHandleTypes: null,
invalidHandleIds: null,
invalidHandleClasses: null,
startPageX: 0,
startPageY: 0,
groups: null,
locked: false,
lock: function() {
this.locked = true;
},
moveOnly: false,
unlock: function() {
this.locked = false;
},
isTarget: true,
padding: null,
_domRef: null,
__ygDragDrop: true,
constrainX: false,
constrainY: false,
minX: 0,
maxX: 0,
minY: 0,
maxY: 0,
maintainOffset: false,
xTicks: null,
yTicks: null,
primaryButtonOnly: true,
available: false,
hasOuterHandles: false,
triggerEvent: 'mousedown',
b4StartDrag: function(x, y) {},
startDrag: function(x, y) {},
b4Drag: function(e) {},
onDrag: function(e) {},
onDragEnter: function(e, id) {},
b4DragOver: function(e) {},
onDragOver: function(e, id) {},
b4DragOut: function(e) {},
onDragOut: function(e, id) {},
b4DragDrop: function(e) {},
onDragDrop: function(e, id) {},
onInvalidDrop: function(e) {},
b4EndDrag: function(e) {},
endDrag: function(e) {},
b4MouseDown: function(e) {},
onMouseDown: function(e) {},
onMouseUp: function(e) {},
onAvailable: function() {},
defaultPadding: {
left: 0,
right: 0,
top: 0,
bottom: 0
},
constrainTo: function(constrainTo, pad, inContent) {
if (Ext.isNumber(pad)) {
pad = {
left: pad,
right: pad,
top: pad,
bottom: pad
};
}
pad = pad || this.defaultPadding;
var ddBox = Ext.get(this.getEl()).getBox(),
constrainEl = Ext.get(constrainTo),
s = constrainEl.getScroll(),
c,
constrainDom = constrainEl.dom,
xy, topSpace, leftSpace;
if (constrainDom === document.body) {
c = {
x: s.left,
y: s.top,
width: Ext.Element.getViewportWidth(),
height: Ext.Element.getViewportHeight()
};
} else {
xy = constrainEl.getXY();
c = {
x: xy[0],
y: xy[1],
width: constrainDom.clientWidth,
height: constrainDom.clientHeight
};
}
topSpace = ddBox.y - c.y;
leftSpace = ddBox.x - c.x;
this.resetConstraints();
this.setXConstraint(leftSpace - (pad.left || 0),
c.width - leftSpace - ddBox.width - (pad.right || 0),
this.xTickSize);
this.setYConstraint(topSpace - (pad.top || 0),
c.height - topSpace - ddBox.height - (pad.bottom || 0),
this.yTickSize);
},
getEl: function() {
if (!this._domRef) {
this._domRef = Ext.getDom(this.id);
}
return this._domRef;
},
getDragEl: function() {
return Ext.getDom(this.dragElId);
},
init: function(id, sGroup, config) {
var me = this;
me.el = me.el || Ext.get(id);
me.initTarget(id, sGroup, config);
Ext.get(me.id).on(me.triggerEvent, me.handleMouseDown, me);
},
initTarget: function(id, sGroup, config) {
this.config = config || {};
this.DDMInstance = Ext.dd.DragDropManager;
this.groups = {};
if (typeof id !== "string") {
id = Ext.id(id);
}
this.id = id;
this.addToGroup((sGroup) ? sGroup : "default");
this.handleElId = id;
this.setDragElId(id);
this.invalidHandleTypes = {
A: "A"
};
this.invalidHandleIds = {};
this.invalidHandleClasses = [];
this.applyConfig();
this.handleOnAvailable();
},
applyConfig: function() {
this.padding = this.config.padding || [
0,
0,
0,
0
];
this.isTarget = (this.config.isTarget !== false);
this.maintainOffset = (this.config.maintainOffset);
this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);
},
handleOnAvailable: function() {
this.available = true;
this.resetConstraints();
this.onAvailable();
},
setPadding: function(iTop, iRight, iBot, iLeft) {
if (!iRight && 0 !== iRight) {
this.padding = [
iTop,
iTop,
iTop,
iTop
];
} else if (!iBot && 0 !== iBot) {
this.padding = [
iTop,
iRight,
iTop,
iRight
];
} else {
this.padding = [
iTop,
iRight,
iBot,
iLeft
];
}
},
setInitPosition: function(diffX, diffY) {
var el = this.getEl(),
dx, dy, p;
if (!this.DDMInstance.verifyEl(el)) {
return;
}
dx = diffX || 0;
dy = diffY || 0;
p = Ext.fly(el).getXY();
this.initPageX = p[0] - dx;
this.initPageY = p[1] - dy;
this.lastPageX = p[0];
this.lastPageY = p[1];
this.setStartPosition(p);
},
setStartPosition: function(pos) {
var p = pos || Ext.fly(this.getEl()).getXY();
this.deltaSetXY = null;
this.startPageX = p[0];
this.startPageY = p[1];
},
addToGroup: function(sGroup) {
this.groups[sGroup] = true;
this.DDMInstance.regDragDrop(this, sGroup);
},
removeFromGroup: function(sGroup) {
if (this.groups[sGroup]) {
delete this.groups[sGroup];
}
this.DDMInstance.removeDDFromGroup(this, sGroup);
},
setDragElId: function(id) {
this.dragElId = id;
},
setHandleElId: function(id) {
if (typeof id !== "string") {
id = Ext.id(id);
}
this.handleElId = id;
this.DDMInstance.regHandle(this.id, id);
},
setOuterHandleElId: function(id) {
if (typeof id !== "string") {
id = Ext.id(id);
}
Ext.get(id).on(this.triggerEvent, this.handleMouseDown, this);
this.setHandleElId(id);
this.hasOuterHandles = true;
},
unreg: function() {
var me = this,
el;
if (me._domRef) {
el = Ext.fly(me.id);
if (el) {
el.un(me.triggerEvent, me.handleMouseDown, me);
}
}
me._domRef = null;
me.DDMInstance._remove(me, me.autoGroup);
},
destroy: function() {
this.unreg();
this.isDestroyed = true;
},
isLocked: function() {
return (this.DDMInstance.isLocked() || this.locked);
},
handleMouseDown: function(e, oDD) {
var me = this;
if ((me.primaryButtonOnly && e.button) || me.isLocked()) {
return;
}
me.DDMInstance.refreshCache(me.groups);
if (me.hasOuterHandles || me.DDMInstance.isOverTarget(e.getPoint(), me)) {
if (me.clickValidator(e)) {
me.setStartPosition();
me.b4MouseDown(e);
me.onMouseDown(e);
me.DDMInstance.handleMouseDown(e, me);
me.DDMInstance.stopEvent(e);
}
}
},
clickValidator: function(e) {
var target = e.getTarget();
return (this.isValidHandleChild(target) && (this.id === this.handleElId || this.DDMInstance.handleWasClicked(target, this.id)));
},
addInvalidHandleType: function(tagName) {
var type = tagName.toUpperCase();
this.invalidHandleTypes[type] = type;
},
addInvalidHandleId: function(id) {
if (typeof id !== "string") {
id = Ext.id(id);
}
this.invalidHandleIds[id] = id;
},
addInvalidHandleClass: function(cssClass) {
this.invalidHandleClasses.push(cssClass);
},
removeInvalidHandleType: function(tagName) {
var type = tagName.toUpperCase();
delete this.invalidHandleTypes[type];
},
removeInvalidHandleId: function(id) {
if (typeof id !== "string") {
id = Ext.id(id);
}
delete this.invalidHandleIds[id];
},
removeInvalidHandleClass: function(cssClass) {
var invalidHandleClasses = this.invalidHandleClasses,
len = invalidHandleClasses.length,
i;
for (i = 0; i < len; ++i) {
if (invalidHandleClasses[i] === cssClass) {
delete invalidHandleClasses[i];
}
}
},
isValidHandleChild: function(node) {
var valid = true,
nodeName, i, len;
try {
nodeName = node.nodeName.toUpperCase();
} catch (e) {
nodeName = node.nodeName;
}
valid = valid && !this.invalidHandleTypes[nodeName];
valid = valid && !this.invalidHandleIds[node.id];
for (i = 0 , len = this.invalidHandleClasses.length; valid && i < len; ++i) {
valid = !Ext.fly(node).hasCls(this.invalidHandleClasses[i]);
}
return valid;
},
setXTicks: function(iStartX, iTickSize) {
this.xTicks = [];
this.xTickSize = iTickSize;
var tickMap = {},
i;
for (i = this.initPageX; i >= this.minX; i = i - iTickSize) {
if (!tickMap[i]) {
this.xTicks[this.xTicks.length] = i;
tickMap[i] = true;
}
}
for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {
if (!tickMap[i]) {
this.xTicks[this.xTicks.length] = i;
tickMap[i] = true;
}
}
Ext.Array.sort(this.xTicks, this.DDMInstance.numericSort);
},
setYTicks: function(iStartY, iTickSize) {
this.yTicks = [];
this.yTickSize = iTickSize;
var tickMap = {},
i;
for (i = this.initPageY; i >= this.minY; i = i - iTickSize) {
if (!tickMap[i]) {
this.yTicks[this.yTicks.length] = i;
tickMap[i] = true;
}
}
for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {
if (!tickMap[i]) {
this.yTicks[this.yTicks.length] = i;
tickMap[i] = true;
}
}
Ext.Array.sort(this.yTicks, this.DDMInstance.numericSort);
},
setXConstraint: function(iLeft, iRight, iTickSize) {
this.leftConstraint = iLeft;
this.rightConstraint = iRight;
this.minX = this.initPageX - iLeft;
this.maxX = this.initPageX + iRight;
if (iTickSize) {
this.setXTicks(this.initPageX, iTickSize);
}
this.constrainX = true;
},
clearConstraints: function() {
this.constrainX = false;
this.constrainY = false;
this.clearTicks();
},
clearTicks: function() {
this.xTicks = null;
this.yTicks = null;
this.xTickSize = 0;
this.yTickSize = 0;
},
setYConstraint: function(iUp, iDown, iTickSize) {
this.topConstraint = iUp;
this.bottomConstraint = iDown;
this.minY = this.initPageY - iUp;
this.maxY = this.initPageY + iDown;
if (iTickSize) {
this.setYTicks(this.initPageY, iTickSize);
}
this.constrainY = true;
},
resetConstraints: function() {
if (this.initPageX || this.initPageX === 0) {
var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0,
dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;
this.setInitPosition(dx, dy);
} else
{
this.setInitPosition();
}
if (this.constrainX) {
this.setXConstraint(this.leftConstraint, this.rightConstraint, this.xTickSize);
}
if (this.constrainY) {
this.setYConstraint(this.topConstraint, this.bottomConstraint, this.yTickSize);
}
},
getTick: function(val, tickArray) {
if (!tickArray) {
return val;
} else if (tickArray[0] >= val) {
return tickArray[0];
} else {
var i, len, next, diff1, diff2;
for (i = 0 , len = tickArray.length; i < len; ++i) {
next = i + 1;
if (tickArray[next] && tickArray[next] >= val) {
diff1 = val - tickArray[i];
diff2 = tickArray[next] - val;
return (diff2 > diff1) ? tickArray[i] : tickArray[next];
}
}
return tickArray[tickArray.length - 1];
}
},
toString: function() {
return ("DragDrop " + this.id);
}
});
Ext.define('Ext.dd.DD', {
extend: 'Ext.dd.DragDrop',
requires: [
'Ext.dd.DragDropManager'
],
constructor: function(id, sGroup, config) {
if (id) {
this.init(id, sGroup, config);
}
},
scroll: true,
autoOffset: function(iPageX, iPageY) {
var x = iPageX - this.startPageX,
y = iPageY - this.startPageY;
this.setDelta(x, y);
},
setDelta: function(iDeltaX, iDeltaY) {
this.deltaX = iDeltaX;
this.deltaY = iDeltaY;
},
setDragElPos: function(iPageX, iPageY) {
var el = this.getDragEl();
this.alignElWithMouse(el, iPageX, iPageY);
},
alignElWithMouse: function(el, iPageX, iPageY) {
var oCoord = this.getTargetCoord(iPageX, iPageY),
fly = el.dom ? el : Ext.fly(el, '_dd'),
elSize = fly.getSize(),
EL = Ext.Element,
vpSize, aCoord, newLeft, newTop;
if (!this.deltaSetXY) {
vpSize = this.cachedViewportSize = {
width: EL.getDocumentWidth(),
height: EL.getDocumentHeight()
};
aCoord = [
Math.max(0, Math.min(oCoord.x, vpSize.width - elSize.width)),
Math.max(0, Math.min(oCoord.y, vpSize.height - elSize.height))
];
fly.setXY(aCoord);
newLeft = this.getLocalX(fly);
newTop = fly.getLocalY();
this.deltaSetXY = [
newLeft - oCoord.x,
newTop - oCoord.y
];
} else {
vpSize = this.cachedViewportSize;
this.setLocalXY(fly, Math.max(0, Math.min(oCoord.x + this.deltaSetXY[0], vpSize.width - elSize.width)), Math.max(0, Math.min(oCoord.y + this.deltaSetXY[1], vpSize.height - elSize.height)));
}
this.cachePosition(oCoord.x, oCoord.y);
this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
return oCoord;
},
cachePosition: function(iPageX, iPageY) {
if (iPageX) {
this.lastPageX = iPageX;
this.lastPageY = iPageY;
} else {
var aCoord = Ext.fly(this.getEl()).getXY();
this.lastPageX = aCoord[0];
this.lastPageY = aCoord[1];
}
},
autoScroll: function(x, y, h, w) {
if (this.scroll) {
var clientH = Ext.Element.getViewportHeight(),
clientW = Ext.Element.getViewportWidth(),
st = this.DDMInstance.getScrollTop(),
sl = this.DDMInstance.getScrollLeft(),
bot = h + y,
right = w + x,
toBot = (clientH + st - y - this.deltaY),
toRight = (clientW + sl - x - this.deltaX),
thresh = 40,
scrAmt = (document.all) ? 80 : 30;
if (bot > clientH && toBot < thresh) {
window.scrollTo(sl, st + scrAmt);
}
if (y < st && st > 0 && y - st < thresh) {
window.scrollTo(sl, st - scrAmt);
}
if (right > clientW && toRight < thresh) {
window.scrollTo(sl + scrAmt, st);
}
if (x < sl && sl > 0 && x - sl < thresh) {
window.scrollTo(sl - scrAmt, st);
}
}
},
getTargetCoord: function(iPageX, iPageY) {
var x = iPageX - this.deltaX,
y = iPageY - this.deltaY;
if (this.constrainX) {
if (x < this.minX) {
x = this.minX;
}
if (x > this.maxX) {
x = this.maxX;
}
}
if (this.constrainY) {
if (y < this.minY) {
y = this.minY;
}
if (y > this.maxY) {
y = this.maxY;
}
}
x = this.getTick(x, this.xTicks);
y = this.getTick(y, this.yTicks);
return {
x: x,
y: y
};
},
applyConfig: function() {
this.callParent();
this.scroll = (this.config.scroll !== false);
},
b4MouseDown: function(e) {
var xy = e.getXY();
this.autoOffset(xy[0], xy[1]);
},
b4Drag: function(e) {
var xy = e.getXY();
this.setDragElPos(xy[0], xy[1]);
},
toString: function() {
return ("DD " + this.id);
},
getLocalX: function(el) {
return el.getLocalX();
},
setLocalXY: function(el, x, y) {
el.setLocalXY(x, y);
}
});
Ext.define('Ext.dd.DDProxy', {
extend: 'Ext.dd.DD',
statics: {
dragElId: "ygddfdiv"
},
constructor: function(id, sGroup, config) {
if (id) {
this.init(id, sGroup, config);
this.initFrame();
}
},
resizeFrame: true,
centerFrame: false,
createFrame: function() {
var self = this,
body = document.body,
div, s;
if (!body || !body.firstChild) {
Ext.defer(function() {
self.createFrame();
}, 50);
return;
}
div = this.getDragEl();
if (!div) {
div = document.createElement("div");
div.id = this.dragElId;
div.setAttribute('role', 'presentation');
s = div.style;
s.position = "absolute";
s.visibility = "hidden";
s.cursor = "move";
s.border = "2px solid #aaa";
s.zIndex = 999;
body.insertBefore(div, body.firstChild);
}
},
initFrame: function() {
this.createFrame();
},
applyConfig: function() {
this.callParent();
this.resizeFrame = (this.config.resizeFrame !== false);
this.centerFrame = (this.config.centerFrame);
this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId);
},
showFrame: function(iPageX, iPageY) {
var me = this,
dragEl = me.getDragEl(),
s = dragEl.style;
me._resizeProxy();
if (me.centerFrame) {
me.setDelta(Math.round(parseInt(s.width, 10) / 2), Math.round(parseInt(s.height, 10) / 2));
}
me.setDragElPos(iPageX, iPageY);
Ext.fly(dragEl).show();
},
_resizeProxy: function() {
if (this.resizeFrame) {
var el = this.getEl();
Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight);
}
},
b4MouseDown: function(e) {
var xy = e.getXY(),
x = xy[0],
y = xy[1];
this.autoOffset(x, y);
this.setDragElPos(x, y);
},
b4StartDrag: function(x, y) {
this.showFrame(x, y);
},
b4EndDrag: function(e) {
Ext.fly(this.getDragEl()).hide();
},
endDrag: function(e) {
var lel = this.getEl(),
del = this.getDragEl();
del.style.visibility = "";
this.beforeMove();
lel.style.visibility = "hidden";
Ext.dd.DDM.moveToEl(lel, del);
del.style.visibility = "hidden";
lel.style.visibility = "";
this.afterDrag();
},
beforeMove: function() {},
afterDrag: function() {},
toString: function() {
return ("DDProxy " + this.id);
}
});
Ext.define('Ext.dd.StatusProxy', {
extend: 'Ext.Component',
animRepair: false,
childEls: [
'ghost'
],
renderTpl: [
'<div class="' + Ext.baseCSSPrefix + 'dd-drop-icon" role="presentation"></div>' + '<div id="{id}-ghost" data-ref="ghost" class="' + Ext.baseCSSPrefix + 'dd-drag-ghost" role="presentation"></div>'
],
repairCls: Ext.baseCSSPrefix + 'dd-drag-repair',
ariaRole: 'presentation',
constructor: function(config) {
var me = this;
config = config || {};
Ext.apply(me, {
hideMode: 'visibility',
hidden: true,
floating: true,
id: me.id || Ext.id(),
cls: Ext.baseCSSPrefix + 'dd-drag-proxy ' + this.dropNotAllowed,
shadow: config.shadow || false,
renderTo: Ext.getDetachedBody()
});
me.callParent(arguments);
this.dropStatus = this.dropNotAllowed;
},
dropAllowed: Ext.baseCSSPrefix + 'dd-drop-ok',
dropNotAllowed: Ext.baseCSSPrefix + 'dd-drop-nodrop',
setStatus: function(cssClass) {
cssClass = cssClass || this.dropNotAllowed;
if (this.dropStatus !== cssClass) {
this.el.replaceCls(this.dropStatus, cssClass);
this.dropStatus = cssClass;
}
},
reset: function(clearGhost) {
var me = this,
clsPrefix = Ext.baseCSSPrefix + 'dd-drag-proxy ';
me.el.replaceCls(clsPrefix + me.dropAllowed, clsPrefix + me.dropNotAllowed);
me.dropStatus = me.dropNotAllowed;
if (clearGhost) {
me.ghost.setHtml('');
}
},
update: function(html) {
if (typeof html === "string") {
this.ghost.setHtml(html);
} else {
this.ghost.setHtml('');
html.style.margin = "0";
this.ghost.dom.appendChild(html);
}
var el = this.ghost.dom.firstChild;
if (el) {
Ext.fly(el).setStyle('float', 'none');
}
},
getGhost: function() {
return this.ghost;
},
hide: function(clear) {
this.callParent();
if (clear) {
this.reset(true);
}
},
stop: function() {
if (this.anim && this.anim.isAnimated && this.anim.isAnimated()) {
this.anim.stop();
}
},
sync: function() {
this.el.syncUnderlays();
},
repair: function(xy, callback, scope) {
var me = this;
me.callback = callback;
me.scope = scope;
if (xy && me.animRepair !== false) {
me.el.addCls(me.repairCls);
me.el.setUnderlaysVisible(false);
me.anim = me.el.animate({
duration: me.repairDuration || 500,
easing: 'ease-out',
to: {
x: xy[0],
y: xy[1]
},
stopAnimation: true,
callback: me.afterRepair,
scope: me
});
} else {
me.afterRepair();
}
},
afterRepair: function() {
var me = this;
me.hide(true);
me.el.removeCls(me.repairCls);
if (typeof me.callback === "function") {
me.callback.call(me.scope || me);
}
delete me.callback;
delete me.scope;
}
});
Ext.define('Ext.dd.DragSource', {
extend: 'Ext.dd.DDProxy',
requires: [
'Ext.dd.StatusProxy',
'Ext.dd.DragDropManager'
],
dropAllowed: Ext.baseCSSPrefix + 'dd-drop-ok',
dropNotAllowed: Ext.baseCSSPrefix + 'dd-drop-nodrop',
animRepair: true,
repairHighlightColor: 'c3daf9',
constructor: function(el, config) {
this.el = Ext.get(el);
if (!this.dragData) {
this.dragData = {};
}
Ext.apply(this, config);
if (!this.proxy) {
this.proxy = new Ext.dd.StatusProxy({
id: this.el.id + '-drag-status-proxy',
animRepair: this.animRepair
});
}
this.callParent([
this.el.dom,
this.ddGroup || this.group,
{
dragElId: this.proxy.id,
resizeFrame: false,
isTarget: false,
scroll: this.scroll === true
}
]);
this.dragging = false;
},
getDragData: function(e) {
return this.dragData;
},
onDragEnter: function(e, id) {
var target = Ext.dd.DragDropManager.getDDById(id),
status;
this.cachedTarget = target;
if (this.beforeDragEnter(target, e, id) !== false) {
if (target.isNotifyTarget) {
status = target.notifyEnter(this, e, this.dragData);
this.proxy.setStatus(status);
} else {
this.proxy.setStatus(this.dropAllowed);
}
if (this.afterDragEnter) {
this.afterDragEnter(target, e, id);
}
}
},
beforeDragEnter: function(target, e, id) {
return true;
},
onDragOver: function(e, id) {
var target = this.cachedTarget || Ext.dd.DragDropManager.getDDById(id),
status;
if (this.beforeDragOver(target, e, id) !== false) {
if (target.isNotifyTarget) {
status = target.notifyOver(this, e, this.dragData);
this.proxy.setStatus(status);
}
if (this.afterDragOver) {
this.afterDragOver(target, e, id);
}
}
},
beforeDragOver: function(target, e, id) {
return true;
},
onDragOut: function(e, id) {
var target = this.cachedTarget || Ext.dd.DragDropManager.getDDById(id);
if (this.beforeDragOut(target, e, id) !== false) {
if (target.isNotifyTarget) {
target.notifyOut(this, e, this.dragData);
}
this.proxy.reset();
if (this.afterDragOut) {
this.afterDragOut(target, e, id);
}
}
this.cachedTarget = null;
},
beforeDragOut: function(target, e, id) {
return true;
},
onDragDrop: function(e, id) {
var target = this.cachedTarget || Ext.dd.DragDropManager.getDDById(id);
if (this.beforeDragDrop(target, e, id) !== false) {
if (target.isNotifyTarget) {
if (target.notifyDrop(this, e, this.dragData) !== false) {
this.onValidDrop(target, e, id);
} else {
this.onInvalidDrop(target, e, id);
}
} else {
this.onValidDrop(target, e, id);
}
if (this.afterDragDrop) {
this.afterDragDrop(target, e, id);
}
}
delete this.cachedTarget;
},
beforeDragDrop: function(target, e, id) {
return true;
},
onValidDrop: function(target, e, id) {
this.hideProxy();
if (this.afterValidDrop) {
this.afterValidDrop(target, e, id);
}
},
getRepairXY: function(e, data) {
return this.el.getXY();
},
onInvalidDrop: function(target, e, id) {
var me = this;
if (!e) {
e = target;
target = null;
id = e.getTarget().id;
}
if (me.beforeInvalidDrop(target, e, id) !== false) {
if (me.cachedTarget) {
if (me.cachedTarget.isNotifyTarget) {
me.cachedTarget.notifyOut(me, e, me.dragData);
}
me.cacheTarget = null;
}
me.proxy.repair(me.getRepairXY(e, me.dragData), me.afterRepair, me);
if (me.afterInvalidDrop) {
me.afterInvalidDrop(e, id);
}
}
},
afterRepair: function() {
var me = this;
if (Ext.enableFx) {
me.el.highlight(me.repairHighlightColor);
}
me.dragging = false;
},
beforeInvalidDrop: function(target, e, id) {
return true;
},
handleMouseDown: function(e) {
if (this.dragging) {
return;
}
var data = this.getDragData(e);
if (data && this.onBeforeDrag(data, e) !== false) {
this.dragData = data;
this.proxy.stop();
this.callParent(arguments);
}
},
onBeforeDrag: function(data, e) {
return true;
},
onStartDrag: Ext.emptyFn,
alignElWithMouse: function() {
this.proxy.ensureAttachedToBody(true);
return this.callParent(arguments);
},
startDrag: function(x, y) {
this.proxy.reset();
this.proxy.hidden = false;
this.dragging = true;
this.proxy.update("");
this.onInitDrag(x, y);
this.proxy.show();
},
onInitDrag: function(x, y) {
var clone = this.el.dom.cloneNode(true);
clone.id = Ext.id();
this.proxy.update(clone);
this.onStartDrag(x, y);
return true;
},
getProxy: function() {
return this.proxy;
},
hideProxy: function() {
this.proxy.hide();
this.proxy.reset(true);
this.dragging = false;
},
triggerCacheRefresh: function() {
Ext.dd.DDM.refreshCache(this.groups);
},
b4EndDrag: function(e) {},
endDrag: function(e) {
this.onEndDrag(this.dragData, e);
},
onEndDrag: function(data, e) {},
autoOffset: function(x, y) {
this.setDelta(-12, -20);
},
destroy: function() {
this.callParent();
Ext.destroy(this.proxy);
}
});
Ext.define('Ext.panel.Proxy', {
alternateClassName: 'Ext.dd.PanelProxy',
moveOnDrag: true,
constructor: function(panel, config) {
var me = this;
me.panel = panel;
me.id = me.panel.id + '-ddproxy';
Ext.apply(me, config);
},
insertProxy: true,
setStatus: Ext.emptyFn,
reset: Ext.emptyFn,
update: Ext.emptyFn,
stop: Ext.emptyFn,
sync: Ext.emptyFn,
getEl: function() {
return this.ghost.el;
},
getGhost: function() {
return this.ghost;
},
getProxy: function() {
return this.proxy;
},
hide: function() {
var me = this;
if (me.ghost) {
if (me.proxy) {
me.proxy.destroy();
delete me.proxy;
}
me.panel.unghost(null, me.moveOnDrag);
delete me.ghost;
}
},
show: function() {
var me = this,
panelSize;
if (!me.ghost) {
panelSize = me.panel.getSize();
me.panel.el.setVisibilityMode(Ext.Element.DISPLAY);
me.ghost = me.panel.ghost();
if (me.insertProxy) {
me.proxy = me.panel.el.insertSibling({
role: 'presentation',
cls: Ext.baseCSSPrefix + 'panel-dd-spacer'
});
me.proxy.setSize(panelSize);
}
}
},
repair: function(xy, callback, scope) {
this.hide();
Ext.callback(callback, scope || this);
},
moveProxy: function(parentNode, before) {
if (this.proxy) {
parentNode.insertBefore(this.proxy.dom, before);
}
}
});
Ext.define('Ext.panel.DD', {
extend: 'Ext.dd.DragSource',
requires: [
'Ext.panel.Proxy'
],
constructor: function(panel, cfg) {
var me = this;
me.panel = panel;
me.dragData = {
panel: panel
};
me.panelProxy = new Ext.panel.Proxy(panel, cfg);
me.proxy = me.panelProxy.proxy;
me.callParent([
panel.el,
cfg
]);
me.setupEl(panel);
},
setupEl: function(panel) {
var me = this,
header = panel.header,
el = panel.body;
if (header) {
me.setHandleElId(header.id);
el = header.el;
}
if (el) {
el.setStyle('cursor', 'move');
me.scroll = false;
} else {
panel.on('boxready', me.setupEl, me, {
single: true
});
}
},
showFrame: Ext.emptyFn,
startDrag: Ext.emptyFn,
b4StartDrag: function(x, y) {
this.panelProxy.show();
},
b4MouseDown: function(e) {
var xy = e.getXY(),
x = xy[0],
y = xy[1];
this.autoOffset(x, y);
},
onInitDrag: function(x, y) {
this.onStartDrag(x, y);
return true;
},
createFrame: Ext.emptyFn,
getDragEl: function(e) {
var ghost = this.panelProxy.ghost;
if (ghost) {
return ghost.el.dom;
}
},
endDrag: function(e) {
this.panelProxy.hide();
this.panel.saveState();
},
autoOffset: function(x, y) {
x -= this.startPageX;
y -= this.startPageY;
this.setDelta(x, y);
},
onInvalidDrop: function(target, e, id) {
var me = this;
if (me.beforeInvalidDrop(target, e, id) !== false) {
if (me.cachedTarget) {
if (me.cachedTarget.isNotifyTarget) {
me.cachedTarget.notifyOut(me, e, me.dragData);
}
me.cacheTarget = null;
}
if (me.afterInvalidDrop) {
me.afterInvalidDrop(e, id);
}
}
}
});
Ext.define('Ext.layout.component.Dock', {
extend: 'Ext.layout.component.Component',
alias: 'layout.dock',
alternateClassName: 'Ext.layout.component.AbstractDock',
type: 'dock',
horzAxisProps: {
name: 'horz',
oppositeName: 'vert',
dockBegin: 'left',
dockEnd: 'right',
horizontal: true,
marginBegin: 'margin-left',
maxSize: 'maxWidth',
minSize: 'minWidth',
pos: 'x',
setSize: 'setWidth',
shrinkWrapDock: 'shrinkWrapDockWidth',
size: 'width',
sizeModel: 'widthModel'
},
vertAxisProps: {
name: 'vert',
oppositeName: 'horz',
dockBegin: 'top',
dockEnd: 'bottom',
horizontal: false,
marginBegin: 'margin-top',
maxSize: 'maxHeight',
minSize: 'minHeight',
pos: 'y',
setSize: 'setHeight',
shrinkWrapDock: 'shrinkWrapDockHeight',
size: 'height',
sizeModel: 'heightModel'
},
initializedBorders: -1,
horizontalCollapsePolicy: {
width: true,
x: true
},
verticalCollapsePolicy: {
height: true,
y: true
},
finishRender: function() {
var me = this,
target, items;
me.callParent();
target = me.getRenderTarget();
items = me.getDockedItems();
me.finishRenderItems(target, items);
},
isItemBoxParent: function(itemContext) {
return true;
},
isItemShrinkWrap: function(item) {
return true;
},
noBorderClasses: [
Ext.baseCSSPrefix + 'docked-noborder-top',
Ext.baseCSSPrefix + 'docked-noborder-right',
Ext.baseCSSPrefix + 'docked-noborder-bottom',
Ext.baseCSSPrefix + 'docked-noborder-left'
],
noBorderClassesSides: {
top: Ext.baseCSSPrefix + 'docked-noborder-top',
right: Ext.baseCSSPrefix + 'docked-noborder-right',
bottom: Ext.baseCSSPrefix + 'docked-noborder-bottom',
left: Ext.baseCSSPrefix + 'docked-noborder-left'
},
borderWidthProps: {
top: 'border-top-width',
right: 'border-right-width',
bottom: 'border-bottom-width',
left: 'border-left-width'
},
_itemCls: Ext.baseCSSPrefix + 'docked',
handleItemBorders: function() {
var me = this,
owner = me.owner,
borders, docked,
lastItems = me.lastDockedItems,
oldBorders = me.borders,
currentGeneration = owner.dockedItems.generation,
noBorderClassesSides = me.noBorderClassesSides,
borderWidthProps = me.borderWidthProps,
i, ln, item, dock, side,
collapsed = me.collapsed;
if (me.initializedBorders === currentGeneration || (owner.border && !owner.manageBodyBorders) || (owner.collapsed && owner.collapseMode === 'mini')) {
return;
}
me.initializedBorders = currentGeneration;
me.collapsed = false;
me.lastDockedItems = docked = me.getLayoutItems();
me.collapsed = collapsed;
borders = {
top: [],
right: [],
bottom: [],
left: []
};
for (i = 0 , ln = docked.length; i < ln; i++) {
item = docked[i];
dock = item.dock;
if (item.ignoreBorderManagement) {
continue;
}
if (!borders[dock].satisfied) {
borders[dock].push(item);
borders[dock].satisfied = true;
}
if (!borders.top.satisfied && dock !== 'bottom') {
borders.top.push(item);
}
if (!borders.right.satisfied && dock !== 'left') {
borders.right.push(item);
}
if (!borders.bottom.satisfied && dock !== 'top') {
borders.bottom.push(item);
}
if (!borders.left.satisfied && dock !== 'right') {
borders.left.push(item);
}
}
if (lastItems) {
for (i = 0 , ln = lastItems.length; i < ln; i++) {
item = lastItems[i];
if (!item.isDestroyed && !item.ignoreBorderManagement && !owner.manageBodyBorders) {
item.removeCls(me.noBorderClasses);
}
}
}
if (oldBorders) {
for (side in oldBorders) {
if (owner.manageBodyBorders && oldBorders[side].satisfied) {
owner.setBodyStyle(borderWidthProps[side], '');
}
}
}
for (side in borders) {
ln = borders[side].length;
if (!owner.manageBodyBorders) {
for (i = 0; i < ln; i++) {
borders[side][i].addCls(noBorderClassesSides[side]);
}
if ((!borders[side].satisfied && !owner.bodyBorder) || owner.bodyBorder === false) {
owner.addBodyCls(noBorderClassesSides[side]);
} else {
owner.removeBodyCls(noBorderClassesSides[side]);
}
} else if (borders[side].satisfied) {
owner.setBodyStyle(borderWidthProps[side], '1px');
}
}
me.borders = borders;
},
beforeLayoutCycle: function(ownerContext) {
var me = this,
owner = me.owner,
shrinkWrap = me.sizeModels.shrinkWrap,
shrinkWrapDock = owner.shrinkWrapDock,
collapsedHorz, collapsedVert;
if (owner.collapsed) {
if (owner.collapsedVertical()) {
collapsedVert = true;
ownerContext.measureDimensions = 1;
} else {
collapsedHorz = true;
ownerContext.measureDimensions = 2;
}
}
ownerContext.collapsedVert = collapsedVert;
ownerContext.collapsedHorz = collapsedHorz;
if (collapsedVert) {
ownerContext.heightModel = shrinkWrap;
} else if (collapsedHorz) {
ownerContext.widthModel = shrinkWrap;
}
shrinkWrapDock = shrinkWrapDock === true ? 3 : (shrinkWrapDock || 0);
ownerContext.shrinkWrapDockHeight = (shrinkWrapDock & 1) &&
ownerContext.heightModel.shrinkWrap;
ownerContext.shrinkWrapDockWidth = (shrinkWrapDock & 2) &&
ownerContext.widthModel.shrinkWrap;
},
beginLayout: function(ownerContext) {
var me = this,
owner = me.owner,
docked = me.getLayoutItems(),
layoutContext = ownerContext.context,
dockedItemCount = docked.length,
lastCollapsedState = me.lastCollapsedState,
dockedItems, i, item, itemContext, offsets, collapsed, dock;
me.callParent(arguments);
collapsed = owner.getCollapsed();
if (collapsed !== lastCollapsedState && lastCollapsedState !== undefined) {
if (me.owner.collapsed) {
ownerContext.isCollapsingOrExpanding = 1;
owner.addClsWithUI(owner.collapsedCls);
} else {
ownerContext.isCollapsingOrExpanding = 2;
owner.removeClsWithUI(owner.collapsedCls);
ownerContext.lastCollapsedState = me.lastCollapsedState;
}
}
me.lastCollapsedState = collapsed;
ownerContext.dockedItems = dockedItems = [];
for (i = 0; i < dockedItemCount; i++) {
item = docked[i];
if (item.rendered) {
dock = item.dock;
itemContext = layoutContext.getCmp(item);
itemContext.dockedAt = {
x: 0,
y: 0
};
itemContext.offsets = offsets = Ext.Element.parseBox(item.offsets || 0);
itemContext.horizontal = dock === 'top' || dock === 'bottom';
offsets.width = offsets.left + offsets.right;
offsets.height = offsets.top + offsets.bottom;
dockedItems.push(itemContext);
}
}
ownerContext.bodyContext = ownerContext.getEl('body');
},
beginLayoutCycle: function(ownerContext) {
var me = this,
docked = ownerContext.dockedItems,
len = docked.length,
owner = me.owner,
frameBody = owner.frameBody,
lastHeightModel = me.lastHeightModel,
i, item, dock;
me.callParent(arguments);
if (me.owner.manageHeight) {
if (me.lastBodyDisplay) {
owner.body.dom.style.display = me.lastBodyDisplay = '';
}
} else {
if (me.lastBodyDisplay !== 'inline-block') {
owner.body.dom.style.display = me.lastBodyDisplay = 'inline-block';
}
if (lastHeightModel && lastHeightModel.shrinkWrap && !ownerContext.heightModel.shrinkWrap) {
owner.body.dom.style.marginBottom = '';
}
}
if (ownerContext.widthModel.auto) {
if (ownerContext.widthModel.shrinkWrap) {
owner.el.setWidth(null);
}
owner.body.setWidth(null);
if (frameBody) {
frameBody.setWidth(null);
}
}
if (ownerContext.heightModel.auto) {
owner.body.setHeight(null);
if (frameBody) {
frameBody.setHeight(null);
}
}
if (ownerContext.collapsedVert) {
ownerContext.setContentHeight(0);
} else if (ownerContext.collapsedHorz) {
ownerContext.setContentWidth(0);
}
for (i = 0; i < len; i++) {
item = docked[i].target;
dock = item.dock;
if (dock === 'right') {
item.setLocalX(0);
} else if (dock !== 'left') {
continue;
}
}
},
calculate: function(ownerContext) {
var me = this,
measure = me.measureAutoDimensions(ownerContext, ownerContext.measureDimensions),
state = ownerContext.state,
horzDone = state.horzDone,
vertDone = state.vertDone,
bodyContext = ownerContext.bodyContext,
framing, horz, vert, forward, backward;
ownerContext.borderInfo || ownerContext.getBorderInfo();
ownerContext.paddingInfo || ownerContext.getPaddingInfo();
ownerContext.frameInfo || ownerContext.getFrameInfo();
bodyContext.borderInfo || bodyContext.getBorderInfo();
bodyContext.paddingInfo || bodyContext.getPaddingInfo();
if (!ownerContext.frameBorder) {
if (!(framing = ownerContext.framing)) {
ownerContext.frameBorder = ownerContext.borderInfo;
ownerContext.framePadding = ownerContext.paddingInfo;
} else {
ownerContext.frameBorder = framing.border;
ownerContext.framePadding = framing.padding;
}
}
horz = !horzDone && me.createAxis(ownerContext, measure.contentWidth, ownerContext.widthModel, me.horzAxisProps, ownerContext.collapsedHorz);
vert = !vertDone && me.createAxis(ownerContext, measure.contentHeight, ownerContext.heightModel, me.vertAxisProps, ownerContext.collapsedVert);
for (forward = 0 , backward = ownerContext.dockedItems.length; backward--; ++forward) {
if (horz) {
me.dockChild(ownerContext, horz, backward, forward);
}
if (vert) {
me.dockChild(ownerContext, vert, backward, forward);
}
}
if (horz && me.finishAxis(ownerContext, horz)) {
state.horzDone = horzDone = horz;
}
if (vert && me.finishAxis(ownerContext, vert)) {
state.vertDone = vertDone = vert;
}
if (horzDone && vertDone && me.finishConstraints(ownerContext, horzDone, vertDone)) {
me.finishPositions(ownerContext, horzDone, vertDone);
} else {
me.done = false;
}
},
createAxis: function(ownerContext, contentSize, sizeModel, axisProps, collapsedAxis) {
var me = this,
begin = 0,
owner = me.owner,
maxSize = owner[axisProps.maxSize],
minSize = owner[axisProps.minSize] || 0,
dockBegin = axisProps.dockBegin,
dockEnd = axisProps.dockEnd,
posProp = axisProps.pos,
sizeProp = axisProps.size,
hasMaxSize = maxSize != null,
shrinkWrap = sizeModel.shrinkWrap,
bodyContext, framing, padding, end;
if (shrinkWrap) {
if (collapsedAxis) {
end = 0;
} else {
bodyContext = ownerContext.bodyContext;
end = contentSize + bodyContext.borderInfo[sizeProp];
}
} else {
framing = ownerContext.frameBorder;
padding = ownerContext.framePadding;
begin = framing[dockBegin] + padding[dockBegin];
end = ownerContext.getProp(sizeProp) - (framing[dockEnd] + padding[dockEnd]);
}
return {
shrinkWrap: sizeModel.shrinkWrap,
sizeModel: sizeModel,
initialBegin: begin,
begin: begin,
end: end,
collapsed: collapsedAxis,
horizontal: axisProps.horizontal,
ignoreFrameBegin: null,
ignoreFrameEnd: null,
initialSize: end - begin,
maxChildSize: 0,
hasMinMaxConstraints: (minSize || hasMaxSize) && sizeModel.shrinkWrap,
minSize: minSize,
maxSize: hasMaxSize ? maxSize : 1000000000,
bodyPosProp: me.owner.manageHeight ? posProp : axisProps.marginBegin,
dockBegin: dockBegin,
dockEnd: dockEnd,
posProp: posProp,
sizeProp: sizeProp,
setSize: axisProps.setSize,
shrinkWrapDock: ownerContext[axisProps.shrinkWrapDock],
sizeModelName: axisProps.sizeModel,
dockedPixelsEnd: 0
};
},
dockChild: function(ownerContext, axis, backward, forward) {
var me = this,
itemContext = ownerContext.dockedItems[axis.shrinkWrap ? backward : forward],
item = itemContext.target,
dock = item.dock,
sizeProp = axis.sizeProp,
pos, size;
if (item.ignoreParentFrame && ownerContext.isCollapsingOrExpanding) {
itemContext.clearMarginCache();
}
if (!itemContext.marginInfo) {
itemContext.getMarginInfo();
}
if (dock === axis.dockBegin) {
if (axis.shrinkWrap) {
pos = me.dockOutwardBegin(ownerContext, itemContext, item, axis);
} else {
pos = me.dockInwardBegin(ownerContext, itemContext, item, axis);
}
} else if (dock === axis.dockEnd) {
if (axis.shrinkWrap) {
pos = me.dockOutwardEnd(ownerContext, itemContext, item, axis);
} else {
pos = me.dockInwardEnd(ownerContext, itemContext, item, axis);
}
} else {
if (axis.shrinkWrapDock) {
size = itemContext.getProp(sizeProp) + itemContext.marginInfo[sizeProp];
axis.maxChildSize = Math.max(axis.maxChildSize, size);
pos = 0;
} else {
pos = me.dockStretch(ownerContext, itemContext, item, axis);
}
}
itemContext.dockedAt[axis.posProp] = pos;
},
dockInwardBegin: function(ownerContext, itemContext, item, axis) {
var pos = axis.begin,
sizeProp = axis.sizeProp,
ignoreParentFrame = item.ignoreParentFrame,
delta, size, dock;
if (ignoreParentFrame) {
axis.ignoreFrameBegin = itemContext;
dock = item.dock;
delta = ownerContext.frameBorder[dock];
pos -= delta + ownerContext.framePadding[dock];
}
if (!item.overlay) {
size = itemContext.getProp(sizeProp) + itemContext.marginInfo[sizeProp];
axis.begin += size;
if (ignoreParentFrame) {
axis.begin -= delta;
}
}
return pos;
},
dockInwardEnd: function(ownerContext, itemContext, item, axis) {
var sizeProp = axis.sizeProp,
size = itemContext.getProp(sizeProp) + itemContext.marginInfo[sizeProp],
pos = axis.end - size,
frameEnd;
if (!item.overlay) {
axis.end = pos;
}
if (item.ignoreParentFrame) {
axis.ignoreFrameEnd = itemContext;
frameEnd = ownerContext.frameBorder[item.dock];
pos += frameEnd + ownerContext.framePadding[item.dock];
axis.end += frameEnd;
}
return pos;
},
dockOutwardBegin: function(ownerContext, itemContext, item, axis) {
var pos = axis.begin,
sizeProp = axis.sizeProp,
size;
if (axis.collapsed) {
axis.ignoreFrameBegin = axis.ignoreFrameEnd = itemContext;
} else if (item.ignoreParentFrame) {
axis.ignoreFrameBegin = itemContext;
}
if (!item.overlay) {
size = itemContext.getProp(sizeProp) + itemContext.marginInfo[sizeProp];
pos -= size;
axis.begin = pos;
}
return pos;
},
dockOutwardEnd: function(ownerContext, itemContext, item, axis) {
var pos = axis.end,
sizeProp = axis.sizeProp,
size;
size = itemContext.getProp(sizeProp) + itemContext.marginInfo[sizeProp];
if (axis.collapsed) {
axis.ignoreFrameBegin = axis.ignoreFrameEnd = itemContext;
} else if (item.ignoreParentFrame) {
axis.ignoreFrameEnd = itemContext;
}
if (!item.overlay) {
axis.end = pos + size;
axis.dockedPixelsEnd += size;
}
return pos;
},
dockStretch: function(ownerContext, itemContext, item, axis) {
var dock = item.dock,
sizeProp = axis.sizeProp,
horizontal = dock === 'top' || dock === 'bottom',
border = ownerContext.frameBorder,
offsets = itemContext.offsets,
padding = ownerContext.framePadding,
endProp = horizontal ? 'right' : 'bottom',
startProp = horizontal ? 'left' : 'top',
pos = axis.begin + offsets[startProp],
margin, size;
if (item.stretch !== false) {
size = axis.end - pos - offsets[endProp];
if (item.ignoreParentFrame) {
pos -= padding[startProp] + border[startProp];
size += padding[sizeProp] + border[sizeProp];
}
margin = itemContext.marginInfo;
size -= margin[sizeProp];
itemContext[axis.setSize](size);
}
return pos;
},
finishAxis: function(ownerContext, axis) {
if (isNaN(axis.maxChildSize)) {
return false;
}
var axisBegin = axis.begin,
size = axis.end - axisBegin,
collapsed = axis.collapsed,
setSizeMethod = axis.setSize,
beginName = axis.dockBegin,
endName = axis.dockEnd,
padding = ownerContext.framePadding,
border = ownerContext.frameBorder,
borderBegin = border[beginName],
framing = ownerContext.framing,
framingBegin = framing && framing[beginName],
paddingBegin = collapsed ? 0 : padding[beginName],
sizeProp = axis.sizeProp,
ignoreFrameBegin = axis.ignoreFrameBegin,
ignoreFrameEnd = axis.ignoreFrameEnd,
bodyContext = ownerContext.bodyContext,
extraPaddingBegin = Math.max(borderBegin + paddingBegin - framingBegin, 0),
bodyPos, bodySize, delta, dirty;
if (axis.shrinkWrap) {
bodySize = axis.initialSize;
if (framing) {
delta = -axisBegin + borderBegin + paddingBegin;
bodyPos = delta - framingBegin - extraPaddingBegin;
} else {
bodyPos = -axisBegin;
delta = bodyPos + paddingBegin;
}
if (!collapsed) {
size += padding[sizeProp];
}
if (ignoreFrameBegin) {
delta -= borderBegin;
bodyPos -= borderBegin;
ignoreFrameBegin.dockedAt[axis.posProp] -= paddingBegin;
} else {
size += borderBegin;
}
if (collapsed) {}
else if (ignoreFrameEnd) {
ignoreFrameEnd.dockedAt[axis.posProp] += padding[endName];
} else {
size += border[endName];
}
axis.size = size;
if (!axis.horizontal && !this.owner.manageHeight) {
dirty = false;
}
} else {
if (framing) {
delta = 0;
bodyPos = axisBegin - framingBegin - extraPaddingBegin;
} else {
delta = -borderBegin;
bodyPos = axisBegin - paddingBegin - borderBegin;
}
bodySize = size;
}
axis.delta = delta;
bodyContext[setSizeMethod](bodySize, dirty);
bodyContext.setProp(axis.bodyPosProp, bodyPos);
return !isNaN(size);
},
beforeInvalidateShrinkWrapDock: function(itemContext, options) {
var sizeModelName = options.axis.sizeModelName;
if (!itemContext[sizeModelName].constrainedMin) {
itemContext[sizeModelName] = Ext.layout.SizeModel.calculated;
}
},
afterInvalidateShrinkWrapDock: function(itemContext, options) {
var axis = options.axis,
me = options.layout,
pos;
if (itemContext[axis.sizeModelName].calculated) {
pos = me.dockStretch(options.ownerContext, itemContext, itemContext.target, axis);
itemContext.setProp(axis.posProp, axis.delta + pos);
}
},
finishConstraints: function(ownerContext, horz, vert) {
var me = this,
sizeModels = me.sizeModels,
publishWidth = horz.shrinkWrap,
publishHeight = vert.shrinkWrap,
owner = me.owner,
dirty, height, width, heightModel, widthModel, size, minSize, maxSize, maxChildSize, desiredSize;
if (publishWidth) {
size = horz.size;
minSize = horz.collapsed ? 0 : horz.minSize;
maxSize = horz.maxSize;
maxChildSize = horz.maxChildSize;
desiredSize = Math.max(size, maxChildSize);
if (desiredSize > maxSize) {
widthModel = sizeModels.constrainedMax;
width = maxSize;
} else if (desiredSize < minSize) {
widthModel = sizeModels.constrainedMin;
width = minSize;
} else if (size < maxChildSize) {
widthModel = sizeModels.constrainedDock;
owner.dockConstrainedWidth = width = maxChildSize;
} else {
width = size;
}
}
if (publishHeight) {
size = vert.size;
minSize = vert.collapsed ? 0 : vert.minSize;
maxSize = vert.maxSize;
maxChildSize = vert.maxChildSize;
desiredSize = Math.max(size, maxChildSize + size - vert.initialSize);
if (desiredSize > maxSize) {
heightModel = sizeModels.constrainedMax;
height = maxSize;
} else if (desiredSize < minSize) {
heightModel = sizeModels.constrainedMin;
height = minSize;
} else if (size < maxChildSize) {
heightModel = sizeModels.constrainedDock;
owner.dockConstrainedHeight = height = maxChildSize;
} else {
if (!ownerContext.collapsedVert && !owner.manageHeight) {
dirty = false;
ownerContext.bodyContext.setProp('margin-bottom', vert.dockedPixelsEnd);
}
height = size;
}
}
if (widthModel || heightModel) {
if (widthModel && heightModel && widthModel.constrainedMax && heightModel.constrainedByMin) {
ownerContext.invalidate({
widthModel: widthModel
});
return false;
}
if (!ownerContext.widthModel.calculatedFromShrinkWrap && !ownerContext.heightModel.calculatedFromShrinkWrap) {
ownerContext.invalidate({
widthModel: widthModel,
heightModel: heightModel
});
return false;
}
} else
{
me.invalidateAxes(ownerContext, horz, vert);
}
if (publishWidth) {
ownerContext.setWidth(width);
if (widthModel) {
ownerContext.widthModel = widthModel;
}
}
if (publishHeight) {
ownerContext.setHeight(height, dirty);
if (heightModel) {
ownerContext.heightModel = heightModel;
}
}
return true;
},
invalidateAxes: function(ownerContext, horz, vert) {
var before = this.beforeInvalidateShrinkWrapDock,
after = this.afterInvalidateShrinkWrapDock,
horzSize = horz.end - horz.begin,
vertSize = vert.initialSize,
invalidateHorz = horz.shrinkWrapDock && horz.maxChildSize <= horzSize,
invalidateVert = vert.shrinkWrapDock && vert.maxChildSize <= vertSize,
dockedItems, len, i, itemContext, itemSize, isHorz, axis, sizeProp;
if (invalidateHorz || invalidateVert) {
if (invalidateVert) {
vert.begin = vert.initialBegin;
vert.end = vert.begin + vert.initialSize;
}
dockedItems = ownerContext.dockedItems;
for (i = 0 , len = dockedItems.length; i < len; ++i) {
itemContext = dockedItems[i];
isHorz = itemContext.horizontal;
axis = null;
if (invalidateHorz && isHorz) {
sizeProp = horz.sizeProp;
itemSize = horzSize;
axis = horz;
} else if (invalidateVert && !isHorz) {
sizeProp = vert.sizeProp;
itemSize = vertSize;
axis = vert;
}
if (axis) {
itemSize -= itemContext.getMarginInfo()[sizeProp];
if (itemSize !== itemContext.props[sizeProp]) {
itemContext.invalidate({
before: before,
after: after,
axis: axis,
ownerContext: ownerContext,
layout: this
});
}
}
}
}
},
finishPositions: function(ownerContext, horz, vert) {
var dockedItems = ownerContext.dockedItems,
length = dockedItems.length,
deltaX = horz.delta,
deltaY = vert.delta,
index, itemContext;
for (index = 0; index < length; ++index) {
itemContext = dockedItems[index];
itemContext.setProp('x', deltaX + itemContext.dockedAt.x);
itemContext.setProp('y', deltaY + itemContext.dockedAt.y);
}
},
finishedLayout: function(ownerContext) {
var me = this,
target = ownerContext.target;
me.callParent(arguments);
if (!ownerContext.animatePolicy) {
if (ownerContext.isCollapsingOrExpanding === 1) {
target.afterCollapse(false);
} else if (ownerContext.isCollapsingOrExpanding === 2) {
target.afterExpand(false);
}
}
},
getAnimatePolicy: function(ownerContext) {
var me = this,
lastCollapsedState, policy;
if (ownerContext.isCollapsingOrExpanding === 1) {
lastCollapsedState = me.lastCollapsedState;
} else if (ownerContext.isCollapsingOrExpanding === 2) {
lastCollapsedState = ownerContext.lastCollapsedState;
}
if (lastCollapsedState === 'left' || lastCollapsedState === 'right') {
policy = me.horizontalCollapsePolicy;
} else if (lastCollapsedState === 'top' || lastCollapsedState === 'bottom') {
policy = me.verticalCollapsePolicy;
}
return policy;
},
getDockedItems: function(order, beforeBody) {
var me = this,
renderedOnly = (order === 'visual'),
all = renderedOnly ? Ext.ComponentQuery.query('[rendered]', me.owner.dockedItems.items) : me.owner.dockedItems.items,
sort = all && all.length && order !== false,
renderOrder, dock, dockedItems, i, isBefore, length;
if (beforeBody == null) {
dockedItems = sort && !renderedOnly ? all.slice() : all;
} else {
dockedItems = [];
for (i = 0 , length = all.length; i < length; ++i) {
dock = all[i].dock;
isBefore = (dock === 'top' || dock === 'left');
if (beforeBody ? isBefore : !isBefore) {
dockedItems.push(all[i]);
}
}
sort = sort && dockedItems.length;
}
if (sort) {
renderOrder = (order = order || 'render') === 'render';
Ext.Array.sort(dockedItems, function(a, b) {
var aw, bw;
if (renderOrder && ((aw = me.owner.dockOrder[a.dock]) !== (bw = me.owner.dockOrder[b.dock]))) {
if (!(aw + bw)) {
return aw - bw;
}
}
aw = me.getItemWeight(a, order);
bw = me.getItemWeight(b, order);
if ((aw !== undefined) && (bw !== undefined)) {
return aw - bw;
}
return 0;
});
}
return dockedItems || [];
},
getItemWeight: function(item, order) {
var weight = item.weight || this.owner.defaultDockWeights[item.dock];
return weight[order] || weight;
},
getLayoutItems: function() {
var me = this,
items, itemCount, item, i, result;
if (me.owner.collapsed) {
result = me.owner.getCollapsedDockedItems();
} else {
items = me.getDockedItems('visual');
itemCount = items.length;
result = [];
for (i = 0; i < itemCount; i++) {
item = items[i];
if (!item.hidden) {
result.push(item);
}
}
}
return result;
},
measureContentWidth: function(ownerContext) {
var bodyContext = ownerContext.bodyContext;
return bodyContext.el.getWidth() - bodyContext.getBorderInfo().width;
},
measureContentHeight: function(ownerContext) {
var bodyContext = ownerContext.bodyContext;
return bodyContext.el.getHeight() - bodyContext.getBorderInfo().height;
},
redoLayout: function(ownerContext) {
var me = this,
owner = me.owner;
if (ownerContext.isCollapsingOrExpanding === 1) {
if (owner.reExpander) {
owner.reExpander.el.show();
}
owner.addClsWithUI(owner.collapsedCls);
ownerContext.redo(true);
} else if (ownerContext.isCollapsingOrExpanding === 2) {
owner.removeClsWithUI(owner.collapsedCls);
ownerContext.bodyContext.redo();
}
},
renderChildren: function() {
var me = this,
items = me.getDockedItems(),
target = me.getRenderTarget();
me.handleItemBorders();
me.renderItems(items, target);
},
renderItems: function(items, target) {
var me = this,
dockedItemCount = items.length,
itemIndex = 0,
correctPosition = 0,
staticNodeCount = 0,
targetNodes = me.getRenderTarget().dom.childNodes,
targetChildCount = targetNodes.length,
i, j, targetChildNode, item;
for (i = 0 , j = 0; i < targetChildCount; i++) {
targetChildNode = targetNodes[i];
if (targetChildNode.nodeType === 1 && Ext.fly(targetChildNode).hasCls(Ext.baseCSSPrefix + 'resizable-handle')) {
break;
}
for (j = 0; j < dockedItemCount; j++) {
item = items[j];
if (item.rendered && item.el.dom === targetChildNode) {
break;
}
}
if (j === dockedItemCount) {
staticNodeCount++;
}
}
for (; itemIndex < dockedItemCount; itemIndex++ , correctPosition++) {
item = items[itemIndex];
if (itemIndex === correctPosition && (item.dock === 'right' || item.dock === 'bottom')) {
correctPosition += staticNodeCount;
}
if (item && !item.rendered) {
me.renderItem(item, target, correctPosition);
} else if (!me.isValidParent(item, target, correctPosition)) {
me.moveItem(item, target, correctPosition);
}
}
},
undoLayout: function(ownerContext) {
var me = this,
owner = me.owner;
if (ownerContext.isCollapsingOrExpanding === 1) {
if (owner.reExpander) {
owner.reExpander.el.hide();
}
owner.removeClsWithUI(owner.collapsedCls);
ownerContext.undo(true);
} else if (ownerContext.isCollapsingOrExpanding === 2) {
owner.addClsWithUI(owner.collapsedCls);
ownerContext.bodyContext.undo();
}
},
sizePolicy: {
nostretch: {
setsWidth: 0,
setsHeight: 0
},
horz: {
shrinkWrap: {
setsWidth: 1,
setsHeight: 0,
readsWidth: 1
},
stretch: {
setsWidth: 1,
setsHeight: 0
}
},
vert: {
shrinkWrap: {
setsWidth: 0,
setsHeight: 1,
readsHeight: 1
},
stretch: {
setsWidth: 0,
setsHeight: 1
}
},
stretchV: {
setsWidth: 0,
setsHeight: 1
},
autoStretchH: {
readsWidth: 1,
setsWidth: 1,
setsHeight: 0
},
autoStretchV: {
readsHeight: 1,
setsWidth: 0,
setsHeight: 1
}
},
getItemSizePolicy: function(item, ownerSizeModel) {
var me = this,
policy = me.sizePolicy,
shrinkWrapDock = me.owner.shrinkWrapDock,
dock, vertical;
if (item.stretch === false) {
return policy.nostretch;
}
dock = item.dock;
vertical = (dock === 'left' || dock === 'right');
shrinkWrapDock = shrinkWrapDock === true ? 3 : (shrinkWrapDock || 0);
if (vertical) {
policy = policy.vert;
shrinkWrapDock = shrinkWrapDock & 1;
} else
{
policy = policy.horz;
shrinkWrapDock = shrinkWrapDock & 2;
}
if (shrinkWrapDock) {
if (!ownerSizeModel) {
ownerSizeModel = me.owner.getSizeModel();
}
if (ownerSizeModel[vertical ? 'height' : 'width'].shrinkWrap) {
return policy.shrinkWrap;
}
}
return policy.stretch;
},
configureItem: function(item, pos) {
this.callParent(arguments);
item.addCls(this._itemCls);
if (!item.ignoreBorderManagement) {
item.addClsWithUI(this.getDockCls(item.dock));
}
},
getDockCls: function(dock) {
return 'docked-' + dock;
},
afterRemove: function(item) {
var dom;
this.callParent(arguments);
item.removeCls(this._itemCls);
if (!item.ignoreBorderManagement) {
item.removeClsWithUI(this.getDockCls(item.dock));
}
dom = item.el.dom;
if (!item.destroying && dom) {
dom.parentNode.removeChild(dom);
}
this.childrenChanged = true;
},
borderCollapseMap: {},
getBorderCollapseTable: function() {
var me = this,
map = me.borderCollapseMap,
owner = me.owner,
baseCls = owner.baseCls,
ui = owner.ui,
table;
map = map[baseCls] || (map[baseCls] = {});
table = map[ui];
if (!table) {
baseCls += '-' + ui + '-outer-border-';
map[ui] = table = [
0,
baseCls + 'l',
baseCls + 'b',
baseCls + 'bl',
baseCls + 'r',
baseCls + 'rl',
baseCls + 'rb',
baseCls + 'rbl',
baseCls + 't',
baseCls + 'tl',
baseCls + 'tb',
baseCls + 'tbl',
baseCls + 'tr',
baseCls + 'trl',
baseCls + 'trb',
baseCls + 'trbl'
];
}
return table;
}
});
Ext.define('Ext.util.Memento', (function() {
function captureOne(src, target, prop, prefix) {
src[prefix ? prefix + prop : prop] = target[prop];
}
function removeOne(src, target, prop) {
delete src[prop];
}
function restoreOne(src, target, prop, prefix) {
var name = prefix ? prefix + prop : prop,
value = src[name];
if (value || src.hasOwnProperty(name)) {
restoreValue(target, prop, value);
}
}
function restoreValue(target, prop, value) {
if (Ext.isDefined(value)) {
target[prop] = value;
} else {
delete target[prop];
}
}
function doMany(doOne, src, target, props, prefix) {
if (src) {
if (Ext.isArray(props)) {
var p,
pLen = props.length;
for (p = 0; p < pLen; p++) {
doOne(src, target, props[p], prefix);
}
} else {
doOne(src, target, props, prefix);
}
}
}
return {
data: null,
target: null,
constructor: function(target, props) {
this.data = {};
if (target) {
this.target = target;
if (props) {
this.capture(props);
}
}
},
capture: function(props, target, prefix) {
var me = this;
doMany(captureOne, me.data || (me.data = {}), target || me.target, props, prefix);
},
remove: function(props) {
doMany(removeOne, this.data, null, props);
},
restore: function(props, clear, target, prefix) {
doMany(restoreOne, this.data, target || this.target, props, prefix);
if (clear !== false) {
this.remove(props);
}
},
restoreAll: function(clear, target) {
var me = this,
t = target || this.target,
data = me.data,
prop;
clear = clear !== false;
for (prop in data) {
if (data.hasOwnProperty(prop)) {
restoreValue(t, prop, data[prop]);
if (clear) {
delete data[prop];
}
}
}
}
};
}()));
Ext.define('Ext.container.DockingContainer', {
requires: [
'Ext.util.MixedCollection',
'Ext.Element'
],
isDockingContainer: true,
defaultDockWeights: {
top: {
render: 1,
visual: 1
},
left: {
render: 3,
visual: 5
},
right: {
render: 5,
visual: 7
},
bottom: {
render: 7,
visual: 3
}
},
dockOrder: {
top: -1,
left: -1,
right: 1,
bottom: 1
},
horizontalDocks: 0,
addDocked: function(items, pos) {
var me = this,
rendered = me.rendered,
i = 0,
dockedItems = me.dockedItems,
lastIndex = dockedItems.getCount(),
index, instanced, item, length;
items = me.prepareItems(items);
length = items.length;
if (rendered) {
Ext.suspendLayouts();
}
if (pos === undefined) {
pos = lastIndex;
} else {
pos = Math.min(pos, lastIndex);
}
for (; i < length; i++) {
item = items[i];
item.dock = item.dock || 'top';
if (item.dock === 'left' || item.dock === 'right') {
me.horizontalDocks++;
}
index = pos + i;
dockedItems.insert(index, item);
instanced = !!item.instancedCmp;
delete item.instancedCmp;
item.onAdded(me, index, instanced);
delete item.initOwnerCt;
if (me.onDockedAdd !== Ext.emptyFn) {
me.onDockedAdd(item);
}
if (me.hasListeners.dockedadd) {
me.fireEvent('dockedadd', me, item, index);
}
}
if (me.rendered) {
me.updateLayout();
Ext.resumeLayouts(true);
}
return items;
},
destroyDockedItems: function() {
var dockedItems = this.dockedItems,
c;
if (dockedItems) {
while ((c = dockedItems.first())) {
this.removeDocked(c, true);
}
}
},
doRenderDockedItems: function(out, renderData, after) {
var me = renderData.$comp,
layout = me.componentLayout,
items, tree;
if (layout.getDockedItems && !renderData.$skipDockedItems) {
items = layout.getDockedItems('render', !after);
tree = items && layout.getItemsRenderTree(items);
if (tree) {
Ext.DomHelper.generateMarkup(tree, out);
}
}
},
getDockedComponent: function(comp) {
if (Ext.isObject(comp)) {
comp = comp.getItemId();
}
return this.dockedItems.get(comp);
},
getDockedItems: function(selector, beforeBody) {
var dockedItems = this.getComponentLayout().getDockedItems('render', beforeBody);
if (selector && dockedItems.length) {
dockedItems = Ext.ComponentQuery.query(selector, dockedItems);
}
return dockedItems;
},
getDockingRefItems: function(deep, containerItems) {
var selector = deep && '*,* *',
dockedItems = this.getDockedItems(selector, true),
items;
dockedItems.push.apply(dockedItems, containerItems);
items = this.getDockedItems(selector, false);
dockedItems.push.apply(dockedItems, items);
return dockedItems;
},
initDockingItems: function() {
var me = this,
items = me.dockedItems;
if (!items || !items.isMixedCollection) {
me.dockedItems = new Ext.util.AbstractMixedCollection(false, me.getComponentId);
if (items) {
me.addDocked(items);
}
}
},
insertDocked: function(pos, items) {
this.addDocked(items, pos);
},
onDockedAdd: Ext.emptyFn,
onDockedRemove: Ext.emptyFn,
removeDocked: function(item, autoDestroy) {
var me = this,
layout, hasLayout;
autoDestroy = autoDestroy === true || (autoDestroy !== false && me.autoDestroy);
if (!me.dockedItems.contains(item)) {
return item;
}
if (item.dock === 'left' || item.dock === 'right') {
me.horizontalDocks--;
}
layout = me.componentLayout;
hasLayout = layout && me.rendered;
if (hasLayout) {
layout.onRemove(item);
}
me.dockedItems.remove(item);
item.onRemoved(item.destroying || autoDestroy);
me.onDockedRemove(item);
if (autoDestroy) {
item.destroy();
} else if (hasLayout) {
layout.afterRemove(item);
}
if (me.hasListeners.dockedremove) {
me.fireEvent('dockedremove', me, item);
}
if (!me.destroying) {
me.updateLayout();
}
return item;
},
moveDocked: function(item, side) {
var me = this;
if (me.rendered) {
Ext.suspendLayouts();
}
me.removeDocked(item, false);
item.dock = side;
me.addDocked(item);
if (me.rendered) {
if (item.frame) {
Ext.getDetachedBody().appendChild(item.el);
item.updateFrame();
}
Ext.resumeLayouts(true);
}
},
setupDockingRenderTpl: function(renderTpl) {
renderTpl.renderDockedItems = this.doRenderDockedItems;
}
});
Ext.define('Ext.panel.Panel', {
extend: 'Ext.container.Container',
alias: 'widget.panel',
alternateClassName: 'Ext.Panel',
requires: [
'Ext.panel.Header',
'Ext.util.MixedCollection',
'Ext.toolbar.Toolbar',
'Ext.fx.Anim',
'Ext.util.KeyMap',
'Ext.panel.DD',
'Ext.XTemplate',
'Ext.layout.component.Dock',
'Ext.util.Memento'
],
mixins: {
docking: 'Ext.container.DockingContainer'
},
childEls: [
'body'
],
renderTpl: [
'{% this.renderDockedItems(out,values,0); %}',
'<div id="{id}-body" data-ref="body" class="{baseCls}-body<tpl if="bodyCls"> {bodyCls}</tpl>',
' {baseCls}-body-{ui}<tpl if="uiCls">',
'<tpl for="uiCls"> {parent.baseCls}-body-{parent.ui}-{.}</tpl>',
'</tpl>{childElCls}"',
'<tpl if="bodyRole"> role="{bodyRole}"<tpl else> role="presentation"</tpl>',
'<tpl if="bodyStyle"> style="{bodyStyle}"</tpl>>',
'{%this.renderContainer(out,values);%}',
'</div>',
'{% this.renderDockedItems(out,values,1); %}'
],
headerPosition: 'top',
iconAlign: 'left',
titleAlign: 'left',
titleRotation: 'default',
beforeRenderConfig: {
glyph: null,
headerPosition: null,
icon: null,
iconAlign: null,
iconCls: null,
title: null,
titleAlign: null,
titleRotation: null
},
animCollapse: Ext.enableFx,
border: true,
closable: false,
closeAction: 'destroy',
collapsed: false,
collapsedCls: 'collapsed',
collapseFirst: true,
collapsible: undefined,
constrain: false,
constrainHeader: false,
dockedItems: null,
tbar: null,
bbar: null,
fbar: null,
lbar: null,
rbar: null,
buttons: null,
floatable: true,
frame: false,
frameHeader: true,
hideCollapseTool: false,
manageHeight: true,
maskElement: 'el',
minButtonWidth: 75,
preventHeader: false,
shrinkWrapDock: false,
titleCollapse: undefined,
baseCls: Ext.baseCSSPrefix + 'panel',
bodyPosProps: {
x: 'x',
y: 'y'
},
componentLayout: 'dock',
contentPaddingProperty: 'bodyPadding',
emptyArray: [],
isPanel: true,
defaultBindProperty: 'title',
addBodyCls: function(cls) {
var me = this,
body = me.rendered ? me.body : me.getProtoBody();
body.addCls(cls);
return me;
},
addTool: function(tools) {
if (!Ext.isArray(tools)) {
tools = [
tools
];
}
var me = this,
header = me.header,
tLen = tools.length,
curTools = me.tools,
t, tool;
if (!header || !header.isHeader) {
header = null;
if (!curTools) {
me.tools = curTools = [];
}
}
for (t = 0; t < tLen; t++) {
tool = tools[t];
tool.toolOwner = me;
if (header) {
header.addTool(tool);
} else {
curTools.push(tool);
}
}
me.updateHeader();
},
addTools: Ext.emptyFn,
setCollapsible: function(collapsible) {
var me = this,
current = me.collapsible,
collapseTool = me.collapseTool;
me.collapsible = collapsible;
if (collapsible && !current) {
me.updateCollapseTool();
collapseTool = me.collapseTool;
if (collapseTool) {
collapseTool.show();
}
} else if (!collapsible && current) {
if (collapseTool) {
collapseTool.hide();
}
}
},
addUIClsToElement: function(cls) {
var me = this,
result = me.callParent(arguments);
me.addBodyCls([
Ext.baseCSSPrefix + cls,
me.baseCls + '-body-' + cls,
me.baseCls + '-body-' + me.ui + '-' + cls
]);
return result;
},
afterCollapse: function(animated) {
var me = this,
ownerLayout = me.ownerLayout;
me.isCollapsingOrExpanding = 0;
me.updateCollapseTool();
if (animated) {
me.removeCls(Ext.baseCSSPrefix + 'animating-size');
}
if (ownerLayout) {
ownerLayout.afterCollapse(me, animated);
}
me.setHiddenDocked();
me.fireEvent('collapse', me);
},
afterExpand: function(animated) {
var me = this,
ownerLayout = me.ownerLayout;
me.isCollapsingOrExpanding = 0;
me.updateCollapseTool();
if (animated) {
me.removeCls(Ext.baseCSSPrefix + 'animating-size');
}
if (ownerLayout) {
ownerLayout.afterExpand(me, animated);
}
me.fireEvent('expand', me);
me.fireHierarchyEvent('expand');
},
beforeDestroy: function() {
var me = this;
Ext.destroy(me.placeholder, me.ghostPanel, me.dd);
this.destroyDockedItems();
me.callParent();
},
beforeRender: function() {
var me = this,
wasCollapsed;
me.callParent();
me.initTools();
if (!(me.preventHeader || (me.header === false))) {
me.updateHeader();
}
me.afterHeaderInit = true;
if (me.collapsed) {
if (me.isPlaceHolderCollapse()) {
if (!me.hidden) {
me.setHiddenState(true);
me.preventCollapseFire = true;
me.placeholderCollapse();
delete me.preventCollapseFire;
wasCollapsed = me.collapsed;
me.collapsed = false;
}
} else {
me.beginCollapse();
me.addClsWithUI(me.collapsedCls);
}
}
if (wasCollapsed) {
me.collapsed = wasCollapsed;
}
},
getMemento: function(name) {
var me = this;
if (name && typeof name === 'string') {
name += 'Memento';
return me[name] || (me[name] = new Ext.util.Memento(me));
}
},
beginCollapse: function() {
var me = this,
lastBox = me.lastBox,
rendered = me.rendered,
collapseMemento = me.getMemento('collapse'),
sizeModel = me.getSizeModel(),
header = me.header,
reExpander;
collapseMemento.capture([
'height',
'minHeight',
'width',
'minWidth'
]);
if (lastBox) {
collapseMemento.capture(me.restoreDimension(), lastBox, 'last.');
}
if (me.collapsedVertical()) {
if (sizeModel.width.shrinkWrap) {
me.width = rendered ? me.getWidth() : me.width || me.minWidth || 100;
}
delete me.height;
me.minHeight = 0;
} else if (me.collapsedHorizontal()) {
if (sizeModel.height.shrinkWrap) {
me.height = rendered ? me.getHeight() : me.height || me.minHeight || 100;
}
delete me.width;
me.minWidth = 0;
}
if (me.ownerCt) {
me.ownerCt.getLayout().beginCollapse(me);
}
if (!me.isPlaceHolderCollapse() && header !== false) {
if (header === (reExpander = me.getReExpander())) {
header.collapseImmune = true;
header.getInherited().collapseImmune = true;
header.addClsWithUI(me.getHeaderCollapsedClasses(header));
if (header.rendered) {
header.updateFrame();
}
} else if (reExpander.el) {
reExpander.el.show();
reExpander.hidden = false;
}
}
if (me.resizer) {
me.resizer.disable();
}
},
beginDrag: function() {
if (this.floatingDescendants) {
this.floatingDescendants.hide();
}
},
beginExpand: function() {
var me = this,
lastBox = me.lastBox,
collapseMemento = me.getMemento('collapse'),
restoreDimension = me.restoreDimension(),
header = me.header,
reExpander;
if (collapseMemento) {
collapseMemento.restore([
'minHeight',
'minWidth',
restoreDimension
]);
if (lastBox) {
collapseMemento.restore(restoreDimension, true, lastBox, 'last.');
}
}
if (me.ownerCt) {
me.ownerCt.getLayout().beginExpand(me);
}
if (!me.isPlaceHolderCollapse() && header !== false) {
if (header === (reExpander = me.getReExpander())) {
delete header.collapseImmune;
delete header.getInherited().collapseImmune;
header.removeClsWithUI(me.getHeaderCollapsedClasses(header));
if (header.rendered) {
header.expanding = true;
header.updateFrame();
delete header.expanding;
}
} else {
reExpander.hidden = true;
reExpander.el.hide();
}
}
if (me.resizer) {
me.resizer.enable();
}
},
bridgeToolbars: function() {
var me = this,
docked = [],
minButtonWidth = me.minButtonWidth,
fbar, fbarDefaults;
function initToolbar(toolbar, pos, useButtonAlign) {
if (Ext.isArray(toolbar)) {
toolbar = {
xtype: 'toolbar',
items: toolbar
};
} else if (!toolbar.xtype) {
toolbar.xtype = 'toolbar';
}
toolbar.dock = pos;
if (useButtonAlign) {
toolbar.layout = Ext.applyIf(toolbar.layout || {}, {
pack: {
left: 'start',
center: 'center'
}[me.buttonAlign] || 'end'
});
}
return toolbar;
}
if (me.tbar) {
docked.push(initToolbar(me.tbar, 'top'));
me.tbar = null;
}
if (me.bbar) {
docked.push(initToolbar(me.bbar, 'bottom'));
me.bbar = null;
}
if (me.buttons) {
me.fbar = me.buttons;
me.buttons = null;
}
if (me.fbar) {
fbar = initToolbar(me.fbar, 'bottom', true);
fbar.ui = 'footer';
if (minButtonWidth) {
fbarDefaults = fbar.defaults;
fbar.defaults = function(config) {
var defaults = fbarDefaults || {},
isButton = !config.xtype || config.isButton,
cls;
if (!isButton) {
cls = Ext.ClassManager.getByAlias('widget.' + config.xtype);
if (cls) {
isButton = cls.prototype.isButton;
}
}
if (isButton && !('minWidth' in defaults)) {
defaults = Ext.apply({
minWidth: minButtonWidth
}, defaults);
}
return defaults;
};
}
docked.push(fbar);
me.fbar = null;
}
if (me.lbar) {
docked.push(initToolbar(me.lbar, 'left'));
me.lbar = null;
}
if (me.rbar) {
docked.push(initToolbar(me.rbar, 'right'));
me.rbar = null;
}
if (me.dockedItems) {
if (me.dockedItems.isMixedCollection) {
me.addDocked(docked);
} else {
if (!Ext.isArray(me.dockedItems)) {
me.dockedItems = [
me.dockedItems
];
}
me.dockedItems = me.dockedItems.concat(docked);
}
} else {
me.dockedItems = docked;
}
},
close: function() {
if (this.fireEvent('beforeclose', this) !== false) {
this.doClose();
}
},
collapse: function(direction, animate) {
var me = this,
collapseDir = direction || me.collapseDirection,
ownerCt = me.ownerCt,
layout = me.ownerLayout,
rendered = me.rendered;
if (me.isCollapsingOrExpanding) {
return me;
}
if (arguments.length < 2) {
animate = me.animCollapse;
}
if (me.collapsed || me.fireEvent('beforecollapse', me, direction, animate) === false) {
return me;
}
if (layout && layout.onBeforeComponentCollapse) {
if (layout.onBeforeComponentCollapse(me) === false) {
return me;
}
}
if (rendered && ownerCt && me.isPlaceHolderCollapse()) {
return me.placeholderCollapse(direction, animate);
}
me.collapsed = collapseDir;
if (rendered) {
me.beginCollapse();
}
me.getInherited().collapsed = true;
me.fireHierarchyEvent('collapse');
if (rendered) {
me.doCollapseExpand(1, animate);
}
return me;
},
collapsedHorizontal: function() {
var dir = this.getCollapsed();
return dir === 'left' || dir === 'right';
},
collapsedVertical: function() {
var dir = this.getCollapsed();
return dir === 'top' || dir === 'bottom';
},
convertCollapseDir: function(collapseDir) {
return collapseDir.substr(0, 1);
},
createGhost: function(cls) {
var me = this,
header = me.header,
frame = me.frame && !me.alwaysFramed;
return {
xtype: 'panel',
hidden: false,
header: header ? {
titleAlign: header.getTitleAlign()
} : null,
ui: frame ? me.ui.replace(/-framed$/, '') : me.ui,
id: me.id + '-ghost',
renderTo: Ext.getBody(),
resizable: false,
draggable: false,
closable: false,
floating: true,
shadow: false,
frame: frame,
shim: me.shim,
alwaysFramed: me.alwaysFramed,
overlapHeader: me.overlapHeader,
headerPosition: me.getHeaderPosition(),
titleRotation: me.getTitleRotation(),
baseCls: me.baseCls,
getRefOwner: function() {
return me.getRefOwner();
},
cls: me.baseCls + '-ghost ' + (cls || '')
};
},
createReExpander: function(direction, defaults) {
var me = this,
isLeft = direction === 'left',
isRight = direction === 'right',
isVertical = isLeft || isRight,
ownerCt = me.ownerCt,
result = Ext.apply({
hideMode: 'offsets',
title: me.getTitle(),
titleAlign: me.getTitleAlign(),
vertical: isVertical,
textCls: me.headerTextCls,
icon: me.getIcon(),
iconCls: me.getIconCls(),
iconAlign: me.getIconAlign(),
glyph: me.getGlyph(),
baseCls: me.self.prototype.baseCls + '-header',
ui: me.ui,
frame: me.frame && me.frameHeader,
ignoreParentFrame: me.frame || me.overlapHeader,
ignoreBorderManagement: me.frame || me.ignoreHeaderBorderManagement,
indicateDrag: me.draggable,
collapseImmune: true,
headerRole: me.headerRole,
ownerCt: (ownerCt && me.collapseMode === 'placeholder') ? ownerCt : me,
ownerLayout: me.componentLayout,
forceOrientation: true,
margin: me.margin
}, defaults);
if (me.collapseMode === 'mini') {
if (isVertical) {
result.width = 1;
} else {
result.height = 1;
}
}
if (!me.hideCollapseTool) {
if (isLeft || (isRight && me.isPlaceHolderCollapse())) {
result.titlePosition = 1;
}
result.tools = [
{
xtype: 'tool',
type: 'expand-' + me.getOppositeDirection(direction),
uiCls: [
'top'
],
handler: me.toggleCollapse,
scope: me
}
];
}
result = new Ext.panel.Header(result);
result.addClsWithUI(me.getHeaderCollapsedClasses(result));
return result;
},
doClose: function() {
this.fireEvent('close', this);
this[this.closeAction]();
},
doCollapseExpand: function(flags, animate) {
var me = this,
originalAnimCollapse = me.animCollapse,
ownerLayout = me.ownerLayout;
me.animCollapse = animate;
me.isCollapsingOrExpanding = flags;
if (animate) {
me.addCls(Ext.baseCSSPrefix + 'animating-size');
}
if (ownerLayout && !animate) {
ownerLayout.onContentChange(me);
} else {
me.updateLayout({
isRoot: true
});
}
me.animCollapse = originalAnimCollapse;
return me;
},
endDrag: function() {
if (this.floatingDescendants) {
this.floatingDescendants.show();
}
},
expand: function(animate) {
var me = this,
layout = me.ownerLayout,
rendered = me.rendered;
if (me.isCollapsingOrExpanding) {
return me;
}
if (!arguments.length) {
animate = me.animCollapse;
}
if (!me.collapsed && !me.floatedFromCollapse) {
return me;
}
if (me.fireEvent('beforeexpand', me, animate) === false) {
return me;
}
if (layout && layout.onBeforeComponentExpand) {
if (layout.onBeforeComponentExpand(me) === false) {
return me;
}
}
delete me.getInherited().collapsed;
if (rendered && me.isPlaceHolderCollapse()) {
return me.placeholderExpand(animate);
}
me.restoreHiddenDocked();
if (rendered) {
me.beginExpand();
}
me.collapsed = false;
if (me.rendered) {
me.doCollapseExpand(2, animate);
}
return me;
},
findReExpander: function(direction) {
var me = this,
c = Ext.Component,
dockedItems = me.dockedItems.items,
dockedItemCount = dockedItems.length,
comp, i;
if (me.collapseMode === 'mini') {
return;
}
switch (direction) {
case c.DIRECTION_TOP:
case c.DIRECTION_BOTTOM:
for (i = 0; i < dockedItemCount; i++) {
comp = dockedItems[i];
if (!comp.hidden) {
if (comp.isHeader && (!comp.dock || comp.dock === 'top' || comp.dock === 'bottom')) {
return comp;
}
}
};
break;
case c.DIRECTION_LEFT:
case c.DIRECTION_RIGHT:
for (i = 0; i < dockedItemCount; i++) {
comp = dockedItems[i];
if (!comp.hidden) {
if (comp.isHeader && (comp.dock === 'left' || comp.dock === 'right')) {
return comp;
}
}
};
break;
default:
throw ('Panel#findReExpander must be passed a valid collapseDirection');
}
},
floatCollapsedPanel: function() {
var me = this,
placeholder = me.placeholder,
ps = placeholder.getSize(),
floatCls = Ext.baseCSSPrefix + 'border-region-slide-in',
collapsed = me.collapsed,
layoutOwner = me.ownerCt || me,
slideDirection, onBodyMousedown, myBox;
if (me.isSliding) {
return;
}
if (me.el.hasCls(floatCls)) {
me.slideOutFloatedPanel();
return;
}
me.isSliding = true;
placeholder.el.hide();
placeholder.hidden = true;
me.el.show();
me.setHiddenState(false);
me.collapsed = false;
layoutOwner.updateLayout();
placeholder.el.show();
placeholder.hidden = false;
me.el.hide();
me.setHiddenState(true);
me.collapsed = collapsed;
layoutOwner.updateLayout();
myBox = me.getBox(false, true);
me.slideOutTask = me.slideOutTask || new Ext.util.DelayedTask(me.slideOutFloatedPanel, me);
if (Ext.supports.Touch) {
Ext.on('mousedown', onBodyMousedown = function(event) {
if (!event.within(me.el)) {
Ext.un('mousedown', onBodyMousedown);
me.slideOutFloatedPanel();
}
});
}
if (!me.placeholderListener) {
me.placeholderListener = placeholder.on({
resize: me.onPlaceholderResize,
scope: me,
destroyable: true
});
}
placeholder.el.on('mouseleave', me.onMouseLeaveFloated, me);
me.el.on('mouseleave', me.onMouseLeaveFloated, me);
placeholder.el.on('mouseenter', me.onMouseEnterFloated, me);
me.el.on('mouseenter', me.onMouseEnterFloated, me);
me.el.addCls(floatCls);
me.floated = collapsed;
if (me.collapseTool) {
me.collapseTool.el.hide();
}
switch (me.collapsed) {
case 'top':
me.width = ps.width;
me.setLocalXY(myBox.x, myBox.y + ps.height);
break;
case 'right':
me.height = ps.height;
me.setLocalXY(myBox.x - ps.width, myBox.y);
break;
case 'bottom':
me.width = ps.width;
me.setLocalXY(myBox.x, myBox.y - ps.height);
break;
case 'left':
me.height = ps.height;
me.setLocalXY(myBox.x + ps.width, myBox.y);
break;
}
slideDirection = me.convertCollapseDir(me.collapsed);
me.floatedFromCollapse = me.collapsed;
me.collapsed = false;
me.setHiddenState(false);
me.el.slideIn(slideDirection, {
preserveScroll: true,
duration: Ext.Number.from(me.animCollapse, Ext.fx.Anim.prototype.duration),
listeners: {
afteranimate: function() {
me.isSliding = false;
me.fireEvent('float', me);
}
}
});
},
onPlaceholderResize: function(ph, newWidth, newHeight) {
var me = this,
myBox = me.getBox(false, true),
phBox = ph.getBox(false, true);
switch (me.floated) {
case 'top':
me.width = newWidth;
me.setLocalY(phBox.y + phBox.height);
break;
case 'right':
me.height = newHeight;
me.setLocalX(phBox.x - myBox.width);
break;
case 'bottom':
me.width = newWidth;
me.setLocalY(phBox.y - myBox.height);
break;
case 'left':
me.height = newHeight;
me.setLocalX(phBox.x + phBox.width);
break;
}
me.updateLayout({
isRoot: true
});
},
getAnimationProps: function() {
var me = this,
animCollapse = me.animCollapse,
props;
props = me.callParent();
if (typeof animCollapse === 'number') {
props.duration = animCollapse;
}
return props;
},
getCollapsed: function() {
var me = this;
if (me.collapsed === true) {
return me.collapseDirection;
}
return me.collapsed;
},
getCollapsedDockedItems: function() {
var me = this;
return me.header === false || me.collapseMode === 'placeholder' ? me.emptyArray : [
me.getReExpander()
];
},
getComponent: function(comp) {
var component = this.callParent(arguments);
if (component === undefined && !Ext.isNumber(comp)) {
component = this.getDockedComponent(comp);
}
return component;
},
getHeader: function() {
return this.header;
},
getHeaderCollapsedClasses: function(header) {
var me = this,
collapsedCls = me.collapsedCls,
collapsedClasses;
collapsedClasses = [
collapsedCls,
collapsedCls + '-' + header.getDockName()
];
if (me.border && (!me.frame || (me.frame && Ext.supports.CSS3BorderRadius))) {
collapsedClasses.push(collapsedCls + '-border-' + header.getDockName());
}
return collapsedClasses;
},
getKeyMap: function() {
return this.keyMap || (this.keyMap = new Ext.util.KeyMap(Ext.apply({
target: this.el
}, this.keys)));
},
getOppositeDirection: function(d) {
var c = Ext.Component;
switch (d) {
case c.DIRECTION_TOP:
return c.DIRECTION_BOTTOM;
case c.DIRECTION_RIGHT:
return c.DIRECTION_LEFT;
case c.DIRECTION_BOTTOM:
return c.DIRECTION_TOP;
case c.DIRECTION_LEFT:
return c.DIRECTION_RIGHT;
}
},
getPlaceholder: function(direction) {
var me = this,
collapseDir = direction || me.collapseDirection,
listeners = null,
placeholder = me.placeholder,
floatable = me.floatable,
titleCollapse = me.titleCollapse;
if (!placeholder) {
if (floatable || (me.collapsible && titleCollapse)) {
listeners = {
click: {
fn: (!titleCollapse && floatable) ? me.floatCollapsedPanel : me.toggleCollapse,
element: 'el',
scope: me
}
};
}
me.placeholder = placeholder = Ext.widget(me.createReExpander(collapseDir, {
id: me.id + '-placeholder',
listeners: listeners
}));
}
if (!placeholder.placeholderFor) {
if (!placeholder.isComponent) {
me.placeholder = placeholder = me.lookupComponent(placeholder);
}
Ext.applyIf(placeholder, {
margin: me.margin,
placeholderFor: me,
synthetic: true
});
placeholder.addCls([
Ext.baseCSSPrefix + 'region-collapsed-placeholder',
Ext.baseCSSPrefix + 'region-collapsed-' + collapseDir + '-placeholder',
me.collapsedCls
]);
}
return placeholder;
},
getProtoBody: function() {
var me = this,
body = me.protoBody;
if (!body) {
me.protoBody = body = new Ext.util.ProtoElement({
cls: me.bodyCls,
style: me.bodyStyle,
clsProp: 'bodyCls',
styleProp: 'bodyStyle',
styleIsText: true
});
}
return body;
},
getReExpander: function(direction) {
var me = this,
collapseDir = direction || me.collapseDirection,
reExpander = me.reExpander || me.findReExpander(collapseDir);
me.expandDirection = me.getOppositeDirection(collapseDir);
if (!reExpander) {
me.reExpander = reExpander = me.createReExpander(collapseDir, {
dock: collapseDir,
cls: Ext.baseCSSPrefix + 'docked ' + me.baseCls + '-' + me.ui + '-collapsed',
isCollapsedExpander: true
});
me.dockedItems.insert(0, reExpander);
}
return reExpander;
},
getRefItems: function(deep) {
var items = this.callParent(arguments);
return this.getDockingRefItems(deep, items);
},
getState: function() {
var me = this,
state = me.callParent() || {},
collapsed = me.collapsed,
floated = me.floated,
memento;
if (floated) {
me.collapsed = floated;
}
state = me.addPropertyToState(state, 'collapsed');
if (floated) {
me.collapsed = collapsed;
}
if (me.getCollapsed()) {
memento = me.getMemento('collapse').data;
state = me.addPropertyToState(state, 'collapsed', memento);
if (me.collapsedVertical()) {
delete state.height;
if (memento) {
state = me.addPropertyToState(state, 'height', memento.height);
}
} else {
delete state.width;
if (memento) {
state = me.addPropertyToState(state, 'width', memento.width);
}
}
}
return state;
},
applyState: function(state) {
var me = this,
collapseMemento = {},
collapsed;
if (state) {
collapsed = state.collapsed;
if (collapsed) {
collapseMemento = me.getMemento('collapse');
Ext.Object.merge(collapseMemento.data, collapsed);
state.collapsed = true;
}
me.callParent(arguments);
}
},
ghost: function(cls) {
var me = this,
ghostPanel = me.ghostPanel,
box = me.getBox(),
header = me.header,
ghostHeader, tools, icon, iconCls, glyph, i;
if (!ghostPanel) {
me.ghostPanel = ghostPanel = Ext.widget(me.createGhost(cls));
ghostPanel.el.dom.removeAttribute('tabIndex');
} else {
ghostPanel.el.show();
}
ghostPanel.setHiddenState(false);
ghostPanel.floatParent = me.floatParent;
ghostPanel.toFront();
if (header && !me.preventHeader) {
ghostHeader = ghostPanel.header;
ghostHeader.suspendLayouts();
tools = ghostHeader.query('tool');
for (i = tools.length; i--; ) {
ghostHeader.remove(tools[i]);
}
ghostHeader.setTitlePosition(0);
ghostPanel.addTool(me.ghostTools());
ghostPanel.setTitle(me.getTitle());
ghostHeader.setTitlePosition(header.titlePosition);
iconCls = me.getIconCls();
if (iconCls) {
ghostPanel.setIconCls(iconCls);
} else {
icon = me.getIcon();
if (icon) {
ghostPanel.setIcon(icon);
} else {
glyph = me.getGlyph();
if (glyph) {
ghostPanel.setGlyph(glyph);
}
}
}
ghostHeader.addCls(Ext.baseCSSPrefix + 'header-ghost');
ghostHeader.resumeLayouts();
}
ghostPanel.setPagePosition(box.x, box.y);
ghostPanel.setSize(box.width, box.height);
me.el.hide();
return ghostPanel;
},
ghostTools: function() {
var tools = [],
header = this.header,
headerTools = header ? header.query('tool[hidden=false]') : [],
t, tLen, tool;
if (headerTools.length) {
t = 0;
tLen = headerTools.length;
for (; t < tLen; t++) {
tool = headerTools[t];
tools.push({
type: tool.type
});
}
} else {
tools = [
{
type: 'placeholder'
}
];
}
return tools;
},
initBodyBorder: function() {
var me = this;
if (me.frame && me.bodyBorder) {
if (!Ext.isNumber(me.bodyBorder)) {
me.bodyBorder = 1;
}
me.getProtoBody().setStyle('border-width', this.unitizeBox(me.bodyBorder));
}
},
initBodyStyles: function() {
var me = this,
body = me.getProtoBody();
if (me.bodyPadding !== undefined) {
if (me.layout.managePadding) {
body.setStyle('padding', 0);
} else {
body.setStyle('padding', this.unitizeBox((me.bodyPadding === true) ? 5 : me.bodyPadding));
}
}
me.initBodyBorder();
},
initBorderProps: function() {
var me = this;
if (me.frame && me.border && me.bodyBorder === undefined) {
me.bodyBorder = false;
}
if (me.frame && me.border && (me.bodyBorder === false || me.bodyBorder === 0)) {
me.manageBodyBorders = true;
}
},
initComponent: function() {
var me = this;
if (me.collapsible) {
me.addStateEvents([
'expand',
'collapse'
]);
}
if (me.unstyled) {
me.setUI('plain');
}
if (me.frame) {
me.setUI(me.ui + '-framed');
}
me.bridgeToolbars();
me.initBorderProps();
me.callParent();
me.collapseDirection = me.collapseDirection || me.getHeaderPosition() || Ext.Component.DIRECTION_TOP;
me.hiddenOnCollapse = new Ext.dom.CompositeElement();
},
initItems: function() {
this.callParent();
this.initDockingItems();
},
initRenderData: function() {
var me = this,
data = me.callParent();
me.initBodyStyles();
me.protoBody.writeTo(data);
delete me.protoBody;
return data;
},
calculateConstrainedPosition: function(constrainTo, proposedPosition, local, proposedSize) {
var me = this,
header = me.header,
lastBox, fp;
if (me.constrainHeader) {
lastBox = header.lastBox;
if (proposedSize) {
if (!header.vertical) {
proposedSize = [
proposedSize[0],
lastBox ? lastBox.height : proposedSize[1]
];
} else {
proposedSize = [
lastBox ? lastBox.width : proposedSize[0],
proposedSize[1]
];
}
} else if (lastBox) {
proposedSize = [
lastBox.width,
lastBox.height
];
}
fp = me.floatParent;
constrainTo = constrainTo || me.constrainTo || (fp ? fp.getTargetEl() : null) || me.container || me.el.parent();
}
return me.callParent([
constrainTo,
proposedPosition,
local,
proposedSize
]);
},
initTools: function() {
var me = this,
tools = me.tools,
i, tool;
me.tools = [];
for (i = tools && tools.length; i; ) {
--i;
me.tools[i] = tool = tools[i];
tool.toolOwner = me;
}
if (me.collapsible && !(me.hideCollapseTool || me.header === false || me.preventHeader)) {
me.updateCollapseTool();
if (me.collapseFirst) {
me.tools.unshift(me.collapseTool);
}
}
me.addTools();
if (me.pinnable) {
me.initPinnable();
}
if (me.closable) {
me.addClsWithUI('closable');
me.addTool({
xtype: 'tool',
type: 'close',
scope: me,
handler: me.close
});
}
if (me.collapseTool && !me.collapseFirst) {
me.addTool(me.collapseTool);
}
},
isLayoutRoot: function() {
if (this.floatedFromCollapse) {
return true;
}
return this.callParent();
},
isPlaceHolderCollapse: function() {
return this.collapseMode === 'placeholder';
},
isVisible: function(deep) {
var me = this;
if (me.collapsed && me.placeholder) {
return me.placeholder.isVisible(deep);
}
return me.callParent(arguments);
},
onBoxReady: function() {
this.callParent(arguments);
if (this.collapsed) {
this.setHiddenDocked();
}
},
onHide: function(animateTarget, cb, scope) {
var me = this,
dd = me.dd;
if (me.floatedFromCollapse) {
me.slideOutFloatedPanel(true);
}
if (me.draggable && dd) {
dd.endDrag();
}
if (me.collapsed && me.placeholder) {
if (me.splitter) {
Ext.suspendLayouts();
me.splitter.hide();
Ext.resumeLayouts();
}
me.placeholder.hide();
} else {
me.callParent([
animateTarget,
cb,
scope
]);
}
},
onMouseEnterFloated: function(e) {
this.slideOutTask.cancel();
},
onMouseLeaveFloated: function(e) {
this.slideOutTask.delay(500);
},
onRemoved: function(destroying) {
var me = this;
if (me.placeholder && !destroying) {
me.ownerCt.remove(me.placeholder, false);
}
me.callParent(arguments);
},
onShow: function() {
var me = this;
if (me.collapsed && me.isPlaceHolderCollapse()) {
if (me.splitter) {
Ext.suspendLayouts();
me.splitter.show();
Ext.resumeLayouts();
}
me.setHiddenState(true);
me.placeholderCollapse();
} else {
me.callParent(arguments);
}
},
placeholderCollapse: function(direction, animate) {
var me = this,
ownerCt = me.ownerCt,
collapseDir = direction || me.collapseDirection,
floatCls = Ext.baseCSSPrefix + 'border-region-slide-in',
placeholder = me.getPlaceholder(collapseDir),
slideInDirection;
me.isCollapsingOrExpanding = 1;
me.setHiddenState(true);
me.collapsed = collapseDir;
if (placeholder.rendered) {
if (placeholder.el.dom.parentNode !== me.el.dom.parentNode) {
me.el.dom.parentNode.insertBefore(placeholder.el.dom, me.el.dom);
}
placeholder.hidden = false;
placeholder.setHiddenState(false);
placeholder.el.show();
ownerCt.updateLayout();
} else {
ownerCt.insert(ownerCt.items.indexOf(me), placeholder);
}
if (me.rendered) {
me.el.setVisibilityMode(me.placeholderCollapseHideMode);
if (animate) {
me.el.addCls(floatCls);
placeholder.el.hide();
slideInDirection = me.convertCollapseDir(collapseDir);
me.el.slideOut(slideInDirection, {
preserveScroll: true,
duration: Ext.Number.from(animate, Ext.fx.Anim.prototype.duration),
listeners: {
afteranimate: function() {
me.el.removeCls(floatCls);
placeholder.el.show().setStyle('display', 'none').slideIn(slideInDirection, {
easing: 'linear',
duration: 100,
listeners: {
afteranimate: function() {
placeholder.focus();
placeholder.setHiddenState(false);
me.isCollapsingOrExpanding = 0;
me.fireEvent('collapse', me);
}
}
});
}
}
});
} else {
me.el.hide();
placeholder.setHiddenState(false);
me.isCollapsingOrExpanding = 0;
me.fireEvent('collapse', me);
}
} else {
me.isCollapsingOrExpanding = 0;
if (!me.preventCollapseFire) {
me.fireEvent('collapse', me);
}
}
return me;
},
placeholderExpand: function(animate) {
var me = this,
collapseDir = me.collapsed,
floatCls = Ext.baseCSSPrefix + 'border-region-slide-in',
finalPos, floatedPos,
center = me.ownerLayout ? me.ownerLayout.centerRegion : null;
if (Ext.Component.layoutSuspendCount) {
animate = false;
}
if (me.floatedFromCollapse) {
floatedPos = me.getPosition(true);
me.slideOutFloatedPanelBegin();
me.slideOutFloatedPanelEnd();
me.floated = false;
}
if (animate) {
Ext.suspendLayouts();
me.placeholder.hide();
me.el.show();
me.collapsed = false;
me.setHiddenState(false);
if (center && !floatedPos) {
center.hidden = true;
}
Ext.resumeLayouts(true);
center.hidden = false;
me.el.addCls(floatCls);
me.isCollapsingOrExpanding = 2;
if (floatedPos) {
finalPos = me.getXY();
me.setLocalXY(floatedPos[0], floatedPos[1]);
me.setXY([
finalPos[0],
finalPos[1]
], {
duration: Ext.Number.from(animate, Ext.fx.Anim.prototype.duration),
listeners: {
afteranimate: function() {
me.el.removeCls(floatCls);
me.isCollapsingOrExpanding = 0;
me.fireEvent('expand', me);
}
}
});
} else
{
me.el.hide();
me.placeholder.el.show();
me.placeholder.hidden = false;
me.setHiddenState(false);
me.el.slideIn(me.convertCollapseDir(collapseDir), {
preserveScroll: true,
duration: Ext.Number.from(animate, Ext.fx.Anim.prototype.duration),
listeners: {
afteranimate: function() {
me.el.removeCls(floatCls);
me.placeholder.hide();
me.updateLayout();
me.isCollapsingOrExpanding = 0;
me.fireEvent('expand', me);
}
}
});
}
} else {
me.floated = me.collapsed = false;
me.el.removeCls(floatCls);
Ext.suspendLayouts();
me.placeholder.hide();
me.show();
Ext.resumeLayouts(true);
me.fireEvent('expand', me);
}
return me;
},
remove: function(component, autoDestroy) {
if (this.dockedItems.contains(component)) {
this.removeDocked(component, autoDestroy);
} else {
this.callParent([
component,
autoDestroy
]);
}
return component;
},
removeBodyCls: function(cls) {
var me = this,
body = me.rendered ? me.body : me.getProtoBody();
body.removeCls(cls);
return me;
},
removeUIClsFromElement: function(cls) {
var me = this,
result = me.callParent(arguments);
me.removeBodyCls([
Ext.baseCSSPrefix + cls,
me.baseCls + '-body-' + cls,
me.baseCls + '-body-' + me.ui + '-' + cls
]);
return result;
},
restoreDimension: function() {
var dir = this.collapseDirection;
return (dir === 'top' || dir === 'bottom') ? 'height' : 'width';
},
restoreHiddenDocked: function() {
var toShow = this.hiddenOnCollapse;
toShow.setStyle('visibility', '');
toShow.clear();
},
setBodyStyle: function(style, value) {
var me = this,
body = me.rendered ? me.body : me.getProtoBody();
if (Ext.isFunction(style)) {
style = style();
}
if (arguments.length === 1) {
if (Ext.isString(style)) {
style = Ext.Element.parseStyles(style);
}
body.setStyle(style);
} else {
body.setStyle(style, value);
}
return me;
},
setBorder: function(border, targetEl) {
if (targetEl) {
return;
}
var me = this,
header = me.header;
if (!border) {
border = 0;
} else if (border === true) {
border = '1px';
} else {
border = me.unitizeBox(border);
}
if (header) {
if (header.isHeader) {
header.setBorder(border);
} else {
header.border = border;
}
}
if (me.rendered && me.bodyBorder !== false) {
me.body.setStyle('border-width', border);
}
me.updateLayout();
me.border = border;
},
setCollapsed: function(collapsed) {
this[collapsed ? 'collapse' : 'expand']();
},
setGlyph: function(glyph) {
var me = this,
oldGlyph = me.glyph,
header = me.header,
placeholder = me.placeholder;
if (glyph !== oldGlyph) {
me.glyph = glyph;
if (header) {
if (header.isHeader) {
header.setGlyph(glyph);
} else {
header.glyph = glyph;
}
} else if (me.rendered || me.afterHeaderInit) {
me.updateHeader();
}
if (placeholder && placeholder.setGlyph) {
placeholder.setGlyph(glyph);
}
me.fireEvent('glyphchange', me, glyph, oldGlyph);
}
},
setIcon: function(icon) {
var me = this,
oldIcon = me.icon,
header = me.header,
placeholder = me.placeholder;
if (icon !== oldIcon) {
me.icon = icon;
if (header) {
if (header.isHeader) {
header.setIcon(icon);
} else {
header.icon = icon;
}
} else if (me.rendered || me.afterHeaderInit) {
me.updateHeader();
}
if (placeholder && placeholder.setIcon) {
placeholder.setIcon(icon);
}
me.fireEvent('iconchange', me, icon, oldIcon);
}
},
setIconCls: function(iconCls) {
var me = this,
oldIconCls = me.iconCls,
header = me.header,
placeholder = me.placeholder;
if (iconCls !== oldIconCls) {
me.iconCls = iconCls;
if (header) {
if (header.isHeader) {
header.setIconCls(iconCls);
} else {
header.iconCls = iconCls;
}
} else if (me.rendered || me.afterHeaderInit) {
me.updateHeader();
}
if (placeholder && placeholder.setIconCls) {
placeholder.setIconCls(iconCls);
}
me.fireEvent('iconclschange', me, iconCls, oldIconCls);
}
},
setTitle: function(title) {
var me = this,
oldTitle = me.title,
header = me.header,
reExpander = me.reExpander,
placeholder = me.placeholder;
if (title !== oldTitle) {
me.title = title;
if (header) {
if (header.isHeader) {
header.setTitle(title);
}
} else if (me.rendered || me.afterHeaderInit) {
me.updateHeader();
}
if (reExpander) {
reExpander.setTitle(title);
}
if (placeholder && placeholder.setTitle) {
placeholder.setTitle(title);
}
me.fireEvent('titlechange', me, title, oldTitle);
}
},
setHiddenDocked: function() {
var me = this,
toHide = me.hiddenOnCollapse,
items = me.getDockedItems(),
len = items.length,
i = 0,
item, reExpander;
if (me.header !== false) {
reExpander = me.getReExpander();
}
toHide.add(me.body);
for (; i < len; i++) {
item = items[i];
if (item && item !== reExpander && item.el) {
toHide.add(item.el);
}
}
toHide.setStyle('visibility', 'hidden');
},
setUI: function(ui) {
var me = this;
me.callParent(arguments);
if (me.header && me.header.rendered) {
me.header.setUI(ui);
}
},
toggleCollapse: function() {
return (this.collapsed || this.floatedFromCollapse) ? this.expand() : this.collapse();
},
updateCollapseTool: function() {
var me = this,
collapseTool = me.collapseTool;
if (!collapseTool && me.collapsible) {
me.collapseDirection = me.collapseDirection || me.getHeaderPosition() || 'top';
me.collapseTool = me.expandTool = collapseTool = Ext.widget({
xtype: 'tool',
handler: me.toggleCollapse,
scope: me
});
}
if (collapseTool) {
if (me.collapsed && !me.isPlaceHolderCollapse()) {
collapseTool.setType('expand-' + me.getOppositeDirection(me.collapseDirection));
} else {
collapseTool.setType('collapse-' + me.collapseDirection);
}
}
},
updateHeaderPosition: function(position) {
var header = this.header;
if (header && header.isHeader) {
header.setDock(position);
}
},
updateIconAlign: function(align) {
var header = this.header;
if (header && header.isHeader) {
header.setIconAlign(align);
}
},
updateTitleAlign: function(align) {
var header = this.header;
if (header && header.isHeader) {
header.setTitleAlign(align);
}
},
updateTitleRotation: function(rotation) {
var header = this.header;
if (header && header.isHeader) {
header.setTitleRotation(rotation);
}
},
unghost: function(show, matchPosition, focus) {
var me = this,
ghostPanel = me.ghostPanel;
if (!ghostPanel) {
return;
}
if (show !== false) {
me.el.show();
if (matchPosition !== false) {
me.setPagePosition(ghostPanel.getXY());
if (me.hideMode === 'offsets') {
delete me.el.hideModeStyles;
}
}
if (focus) {
me.focus(false, 10);
}
}
ghostPanel.el.hide();
ghostPanel.setHiddenState(true);
},
updateHeader: function(force) {
var me = this,
header = me.header,
title = me.getTitle(),
tools = me.tools,
icon = me.getIcon(),
glyph = me.getGlyph(),
iconCls = me.getIconCls(),
hasIcon = glyph || icon || iconCls,
headerPosition = me.getHeaderPosition(),
vertical = headerPosition === 'left' || headerPosition === 'right';
if (Ext.isObject(header) || (header !== false && (force || (title || hasIcon) || (tools && tools.length) || (me.collapsible && !me.titleCollapse)))) {
if (header && header.isHeader) {
header.show();
} else {
header = me.header = Ext.widget(Ext.merge({
xtype: 'header',
title: title,
titleAlign: me.getTitleAlign(),
vertical: vertical,
dock: me.getHeaderPosition() || 'top',
titleRotation: me.getTitleRotation(),
textCls: me.headerTextCls,
iconCls: iconCls,
iconAlign: me.getIconAlign(),
icon: icon,
glyph: glyph,
baseCls: me.baseCls + '-header',
tools: tools,
ui: me.ui,
id: me.id + '_header',
overCls: me.headerOverCls,
indicateDrag: me.draggable,
frame: (me.frame || me.alwaysFramed) && me.frameHeader,
ignoreParentFrame: me.frame || me.overlapHeader,
ignoreBorderManagement: me.frame || me.ignoreHeaderBorderManagement,
headerRole: me.headerRole,
ownerCt: me,
synthetic: true,
listeners: me.collapsible && me.titleCollapse ? {
click: me.toggleCollapse,
scope: me
} : null
}, me.header));
me.addDocked(header, 0);
}
} else if (header) {
header.hide();
}
},
privates: {
addUIToElement: function() {
var me = this;
me.callParent(arguments);
me.addBodyCls(me.baseCls + '-body-' + me.ui);
},
applyTargetCls: function(targetCls) {
this.getProtoBody().addCls(targetCls);
},
getDefaultContentTarget: function() {
return this.body;
},
getTargetEl: function() {
var me = this;
return me.body || me.protoBody || me.frameBody || me.el;
},
initDraggable: function() {
var me = this;
if (me.simpleDrag) {
me.initSimpleDraggable();
} else
{
me.dd = new Ext.panel.DD(me, Ext.isBoolean(me.draggable) ? null : me.draggable);
}
},
initResizable: function() {
this.callParent(arguments);
if (this.collapsed) {
this.resizer.disable();
}
},
initSimpleDraggable: function() {
var me = this,
ddConfig, dd;
if (!me.header) {
me.updateHeader(true);
}
if (me.header) {
ddConfig = Ext.applyIf({
el: me.el,
delegate: '#' + me.header.id
}, me.draggable);
if (me.constrain || me.constrainHeader) {
ddConfig.constrain = me.constrain;
ddConfig.constrainDelegate = me.constrainHeader;
ddConfig.constrainTo = me.constrainTo || me.container;
}
dd = me.dd = new Ext.util.ComponentDragger(me, ddConfig);
me.relayEvents(dd, [
'dragstart',
'drag',
'dragend'
]);
if (me.maximized) {
dd.disable();
}
}
},
removeUIFromElement: function() {
var me = this;
me.callParent(arguments);
me.removeBodyCls(me.baseCls + '-body-' + me.ui);
},
setupRenderTpl: function(renderTpl) {
this.callParent(arguments);
this.setupDockingRenderTpl(renderTpl);
},
slideOutFloatedPanel: function(preventAnimate) {
var me = this,
compEl = me.el,
collapseDirection,
afterSlideOut = function() {
me.slideOutFloatedPanelEnd();
me.el.removeCls(Ext.baseCSSPrefix + 'border-region-slide-in');
};
if (me.isSliding || me.isDestroyed) {
return;
}
me.isSliding = true;
me.floated = false;
me.slideOutFloatedPanelBegin();
if (preventAnimate) {
compEl.hide();
return afterSlideOut();
}
if (typeof me.collapsed === 'string') {
collapseDirection = me.convertCollapseDir(me.collapsed);
}
compEl.slideOut(collapseDirection, {
preserveScroll: true,
duration: Ext.Number.from(me.animCollapse, Ext.fx.Anim.prototype.duration),
listeners: {
afteranimate: afterSlideOut
}
});
},
slideOutFloatedPanelBegin: function() {
var me = this,
placeholderEl = me.placeholder.el,
el = me.el;
me.collapsed = me.floatedFromCollapse;
me.setHiddenState(true);
me.floatedFromCollapse = null;
placeholderEl.un('mouseleave', me.onMouseLeaveFloated, me);
el.un('mouseleave', me.onMouseLeaveFloated, me);
placeholderEl.un('mouseenter', me.onMouseEnterFloated, me);
el.un('mouseenter', me.onMouseEnterFloated, me);
},
slideOutFloatedPanelEnd: function(suppressEvents) {
var me = this;
if (me.collapseTool) {
me.collapseTool.el.show();
}
me.slideOutTask.cancel();
me.isSliding = false;
if (!suppressEvents) {
me.fireEvent('unfloat', me);
}
}
}
},
function() {
var proto = this.prototype;
proto.animCollapse = Ext.enableFx;
proto.placeholderCollapseHideMode = Ext.Element.VISIBILITY;
});
Ext.define("Ext.form.Labelable", {
extend: 'Ext.Mixin',
requires: [
'Ext.XTemplate',
'Ext.overrides.dom.Element'
],
isLabelable: true,
mixinConfig: {
id: 'labelable',
on: {
beforeRender: 'beforeLabelRender',
onRender: 'onLabelRender'
}
},
config: {
childEls: [
'labelEl',
'bodyEl',
'errorEl',
'errorWrapEl'
]
},
labelableRenderTpl: [
'{beforeLabelTpl}',
'<label id="{id}-labelEl" data-ref="labelEl" class="{labelCls} {labelCls}-{ui} {labelClsExtra} ',
'{childElCls} {unselectableCls}" style="{labelStyle}"<tpl if="inputId">',
' for="{inputId}"</tpl> {labelAttrTpl}>',
'<span class="{labelInnerCls} {labelInnerCls}-{ui}" style="{labelInnerStyle}">',
'{beforeLabelTextTpl}',
'<tpl if="fieldLabel">{fieldLabel}',
'<tpl if="labelSeparator">{labelSeparator}</tpl>',
'</tpl>',
'{afterLabelTextTpl}',
'</span>',
'</label>',
'{afterLabelTpl}',
'<div id="{id}-bodyEl" data-ref="bodyEl" class="{baseBodyCls} {baseBodyCls}-{ui}<tpl if="fieldBodyCls">',
' {fieldBodyCls} {fieldBodyCls}-{ui}</tpl> {growCls} {extraFieldBodyCls}"',
'<tpl if="bodyStyle"> style="{bodyStyle}"</tpl>>',
'{beforeBodyEl}',
'{beforeSubTpl}',
'{[values.$comp.getSubTplMarkup(values)]}',
'{afterSubTpl}',
'{afterBodyEl}',
'</div>',
'<tpl if="renderError">',
'<div id="{id}-errorWrapEl" data-ref="errorWrapEl" class="{errorWrapCls} {errorWrapCls}-{ui}',
' {errorWrapExtraCls}" style="{errorWrapStyle}">',
'<div role="alert" aria-live="polite" id="{id}-errorEl" data-ref="errorEl" ',
'class="{errorMsgCls} {invalidMsgCls} {invalidMsgCls}-{ui}" ',
'data-anchorTarget="{id}-inputEl">',
'</div>',
'</div>',
'</tpl>',
{
disableFormats: true
}
],
activeErrorsTpl: undefined,
htmlActiveErrorsTpl: [
'<tpl if="errors && errors.length">',
'<ul class="{listCls}">',
'<tpl if="Ext.enableAria">',
'<tpl if="fieldLabel"><div>{fieldLabel}</div></tpl>',
'</tpl>',
'<tpl for="errors"><li>{.}</li></tpl>',
'</ul>',
'</tpl>'
],
plaintextActiveErrorsTpl: [
'<tpl if="errors && errors.length">',
'<tpl if="Ext.enableAria">',
'<tpl if="fieldLabel">{fieldLabel}\n</tpl>',
'</tpl>',
'<tpl for="errors"><tpl if="xindex &gt; 1">\n</tpl>{.}</tpl>',
'</tpl>'
],
isFieldLabelable: true,
formItemCls: Ext.baseCSSPrefix + 'form-item',
labelCls: Ext.baseCSSPrefix + 'form-item-label',
topLabelCls: Ext.baseCSSPrefix + 'form-item-label-top',
rightLabelCls: Ext.baseCSSPrefix + 'form-item-label-right',
labelInnerCls: Ext.baseCSSPrefix + 'form-item-label-inner',
topLabelSideErrorCls: Ext.baseCSSPrefix + 'form-item-label-top-side-error',
errorMsgCls: Ext.baseCSSPrefix + 'form-error-msg',
errorWrapCls: Ext.baseCSSPrefix + 'form-error-wrap',
errorWrapSideCls: Ext.baseCSSPrefix + 'form-error-wrap-side',
errorWrapUnderCls: Ext.baseCSSPrefix + 'form-error-wrap-under',
errorWrapUnderSideLabelCls: Ext.baseCSSPrefix + 'form-error-wrap-under-side-label',
baseBodyCls: Ext.baseCSSPrefix + 'form-item-body',
invalidIconCls: Ext.baseCSSPrefix + 'form-invalid-icon',
invalidUnderCls: Ext.baseCSSPrefix + 'form-invalid-under',
noLabelCls: Ext.baseCSSPrefix + 'form-item-no-label',
fieldBodyCls: '',
invalidCls: Ext.baseCSSPrefix + 'form-invalid',
fieldLabel: undefined,
labelAlign: 'left',
labelWidth: 100,
labelPad: 5,
labelSeparator: ':',
hideLabel: false,
hideEmptyLabel: true,
preventMark: false,
autoFitErrors: true,
msgTarget: 'qtip',
msgTargets: {
qtip: 1,
title: 1,
under: 1,
side: 1,
none: 1
},
noWrap: true,
labelableInsertions: [
'beforeBodyEl',
'afterBodyEl',
'beforeLabelTpl',
'afterLabelTpl',
'beforeSubTpl',
'afterSubTpl',
'beforeLabelTextTpl',
'afterLabelTextTpl',
'labelAttrTpl'
],
statics: {
initTip: function() {
var tip = this.tip,
cfg, copy;
if (tip) {
return;
}
cfg = {
id: 'ext-form-error-tip',
sticky: true,
ui: 'form-invalid'
};
if (Ext.supports.Touch) {
cfg.dismissDelay = 0;
cfg.anchor = 'top';
cfg.showDelay = 0;
cfg.listeners = {
beforeshow: function() {
this.minWidth = Ext.fly(this.anchorTarget).getWidth();
}
};
}
tip = this.tip = Ext.create('Ext.tip.QuickTip', cfg);
copy = Ext.apply({}, tip.tagConfig);
copy.attribute = 'errorqtip';
tip.setTagConfig(copy);
},
destroyTip: function() {
this.tip = Ext.destroy(this.tip);
}
},
initLabelable: function() {
var me = this,
padding = me.padding;
if (padding) {
me.padding = undefined;
me.extraMargins = Ext.Element.parseBox(padding);
}
if (Ext.isIE8) {
me.restoreDisplay = Ext.Function.createDelayed(me.doRestoreDisplay, 0, me);
}
if (!me.activeErrorsTpl) {
if (me.msgTarget === 'title') {
me.activeErrorsTpl = me.plaintextActiveErrorsTpl;
} else {
me.activeErrorsTpl = me.htmlActiveErrorsTpl;
}
}
me.addCls([
me.formItemCls,
me.formItemCls + '-' + me.ui
]);
me.lastActiveError = '';
me.enableBubble('errorchange');
},
trimLabelSeparator: function() {
var me = this,
separator = me.labelSeparator,
label = me.fieldLabel || '',
lastChar = label.substr(label.length - 1);
return lastChar === separator ? label.slice(0, -1) : label;
},
getFieldLabel: function() {
return this.trimLabelSeparator();
},
setFieldLabel: function(label) {
label = label || '';
var me = this,
separator = me.labelSeparator,
labelEl = me.labelEl,
errorWrapEl = me.errorWrapEl,
sideLabel = (me.labelAlign !== 'top'),
noLabelCls = me.noLabelCls,
errorWrapUnderSideLabelCls = me.errorWrapUnderSideLabelCls;
me.fieldLabel = label;
if (me.rendered) {
if (Ext.isEmpty(label) && me.hideEmptyLabel) {
me.addCls(noLabelCls);
if (sideLabel && errorWrapEl) {
errorWrapEl.removeCls(errorWrapUnderSideLabelCls);
}
} else {
if (separator) {
label = me.trimLabelSeparator() + separator;
}
labelEl.dom.firstChild.innerHTML = label;
me.removeCls(noLabelCls);
if (sideLabel && errorWrapEl) {
errorWrapEl.addCls(errorWrapUnderSideLabelCls);
}
}
me.updateLayout();
}
},
setHideLabel: function(hideLabel) {
var me = this;
if (hideLabel !== me.hideLabel) {
me.hideLabel = hideLabel;
if (me.rendered) {
me[hideLabel ? 'addCls' : 'removeCls'](me.noLabelCls);
me.updateLayout();
}
}
},
setHideEmptyLabel: function(hideEmptyLabel) {
var me = this,
hide;
if (hideEmptyLabel !== me.hideEmptyLabel) {
me.hideEmptyLabel = hideEmptyLabel;
if (me.rendered && !me.hideLabel) {
hide = hideEmptyLabel && !me.getFieldLabel();
me[hide ? 'addCls' : 'removeCls'](me.noLabelCls);
me.updateLayout();
}
}
},
getInsertionRenderData: function(data, names) {
var i = names.length,
name, value;
while (i--) {
name = names[i];
value = this[name];
if (value) {
if (typeof value !== 'string') {
if (!value.isTemplate) {
value = Ext.XTemplate.getTpl(this, name);
}
value = value.apply(data);
}
}
data[name] = value || '';
}
return data;
},
getLabelableRenderData: function() {
var me = this,
labelAlign = me.labelAlign,
topLabel = (labelAlign === 'top'),
rightLabel = (labelAlign === 'right'),
sideError = (me.msgTarget === 'side'),
underError = (me.msgTarget === 'under'),
errorMsgCls = me.errorMsgCls,
labelPad = me.labelPad,
labelWidth = me.labelWidth,
labelClsExtra = me.labelClsExtra || '',
errorWrapExtraCls = sideError ? me.errorWrapSideCls : me.errorWrapUnderCls,
labelStyle = '',
labelInnerStyle = '',
labelVisible = me.hasVisibleLabel(),
autoFitErrors = me.autoFitErrors,
defaultBodyWidth = me.defaultBodyWidth,
bodyStyle, data;
if (topLabel) {
labelClsExtra += ' ' + me.topLabelCls;
if (labelPad) {
labelInnerStyle = 'padding-bottom:' + labelPad + 'px;';
}
if (sideError && !autoFitErrors) {
labelClsExtra += ' ' + me.topLabelSideErrorCls;
}
} else {
if (rightLabel) {
labelClsExtra += ' ' + me.rightLabelCls;
}
if (labelPad) {
labelStyle += me.getHorizontalPaddingStyle() + labelPad + 'px;';
}
labelStyle += 'width:' + (labelWidth + (labelPad ? labelPad : 0)) + 'px;';
labelInnerStyle = 'width:' + labelWidth + 'px';
}
if (labelVisible) {
if (!topLabel && underError) {
errorWrapExtraCls += ' ' + me.errorWrapUnderSideLabelCls;
}
}
if (defaultBodyWidth) {
bodyStyle = 'min-width:' + defaultBodyWidth + 'px;max-width:' + defaultBodyWidth + 'px;';
}
data = {
id: me.id,
inputId: me.getInputId(),
labelCls: me.labelCls,
labelClsExtra: labelClsExtra,
labelStyle: labelStyle + (me.labelStyle || ''),
labelInnerStyle: labelInnerStyle,
labelInnerCls: me.labelInnerCls,
unselectableCls: Ext.Element.unselectableCls,
bodyStyle: bodyStyle,
baseBodyCls: me.baseBodyCls,
fieldBodyCls: me.fieldBodyCls,
extraFieldBodyCls: me.extraFieldBodyCls,
errorWrapCls: me.errorWrapCls,
errorWrapExtraCls: errorWrapExtraCls,
renderError: sideError || underError,
invalidMsgCls: sideError ? me.invalidIconCls : underError ? me.invalidUnderCls : '',
errorMsgCls: errorMsgCls,
growCls: me.grow ? me.growCls : '',
errorWrapStyle: (sideError && !autoFitErrors) ? 'visibility:hidden' : 'display:none',
fieldLabel: me.getFieldLabel(),
labelSeparator: me.labelSeparator
};
me.getInsertionRenderData(data, me.labelableInsertions);
return data;
},
getHorizontalPaddingStyle: function() {
return 'padding-right:';
},
beforeLabelRender: function() {
var me = this;
me.setFieldDefaults(me.getInherited().fieldDefaults);
if (me.ownerLayout) {
me.addCls(Ext.baseCSSPrefix + me.ownerLayout.type + '-form-item');
}
if (!me.hasVisibleLabel()) {
me.addCls(me.noLabelCls);
}
},
onLabelRender: function() {
var me = this,
style = {},
ExtElement = Ext.Element,
errorWrapEl = me.errorWrapEl,
margins, side;
if (errorWrapEl) {
errorWrapEl.setVisibilityMode((me.msgTarget === 'side' && !me.autoFitErrors) ? ExtElement.VISIBILITY : ExtElement.DISPLAY);
}
if (me.extraMargins) {
margins = me.el.getMargin();
for (side in margins) {
if (margins.hasOwnProperty(side)) {
style['margin-' + side] = (margins[side] + me.extraMargins[side]) + 'px';
}
}
me.el.setStyle(style);
}
},
hasVisibleLabel: function() {
if (this.hideLabel) {
return false;
}
return !(this.hideEmptyLabel && !this.getFieldLabel());
},
getSubTplMarkup: function() {
return '';
},
getInputId: function() {
return '';
},
getActiveError: function() {
return this.activeError || '';
},
hasActiveError: function() {
return !!this.getActiveError();
},
setActiveError: function(msg) {
this.setActiveErrors(msg);
},
getActiveErrors: function() {
return this.activeErrors || [];
},
setActiveErrors: function(errors) {
var me = this,
errorWrapEl = me.errorWrapEl,
msgTarget = me.msgTarget,
isSide = msgTarget === 'side',
isQtip = msgTarget === 'qtip',
activeError, tpl, targetEl;
errors = Ext.Array.from(errors);
tpl = me.getTpl('activeErrorsTpl');
me.activeErrors = errors;
activeError = me.activeError = tpl.apply({
fieldLabel: me.fieldLabel,
errors: errors,
listCls: Ext.baseCSSPrefix + 'list-plain'
});
me.renderActiveError();
if (me.rendered) {
if (isSide) {
me.errorEl.dom.setAttribute('data-errorqtip', activeError);
} else if (isQtip) {
me.getActionEl().dom.setAttribute('data-errorqtip', activeError);
} else if (msgTarget === 'title') {
me.getActionEl().dom.setAttribute('title', activeError);
}
if (isSide || isQtip) {
Ext.form.Labelable.initTip();
}
if (!me.msgTargets[msgTarget]) {
targetEl = Ext.get(msgTarget);
if (targetEl) {
targetEl.dom.innerHTML = activeError;
}
}
}
if (errorWrapEl) {
errorWrapEl.setVisible(errors.length > 0);
if (isSide && me.autoFitErrors) {
me.labelEl.addCls(me.topLabelSideErrorCls);
}
me.updateLayout();
}
},
unsetActiveError: function() {
var me = this,
errorWrapEl = me.errorWrapEl,
msgTarget = me.msgTarget,
targetEl,
restoreDisplay = me.restoreDisplay;
if (me.hasActiveError()) {
delete me.activeError;
delete me.activeErrors;
me.renderActiveError();
if (me.rendered) {
if (msgTarget === 'qtip') {
me.getActionEl().dom.removeAttribute('data-errorqtip');
} else if (msgTarget === 'title') {
me.getActionEl().dom.removeAttribute('title');
}
if (!me.msgTargets[msgTarget]) {
targetEl = Ext.get(msgTarget);
if (targetEl) {
targetEl.dom.innerHTML = '';
}
}
if (errorWrapEl) {
errorWrapEl.hide();
if (msgTarget === 'side' && me.autoFitErrors) {
me.labelEl.removeCls(me.topLabelSideErrorCls);
}
me.updateLayout();
if (restoreDisplay) {
me.el.dom.style.display = 'block';
me.restoreDisplay();
}
}
}
}
},
doRestoreDisplay: function() {
var el = this.el;
if (el && el.dom) {
el.dom.style.display = '';
}
},
renderActiveError: function() {
var me = this,
activeError = me.getActiveError(),
hasError = !!activeError;
if (activeError !== me.lastActiveError) {
me.lastActiveError = activeError;
me.fireEvent('errorchange', me, activeError);
}
if (me.rendered && !me.isDestroyed && !me.preventMark) {
me.toggleInvalidCls(hasError);
if (me.errorEl) {
me.errorEl.dom.innerHTML = activeError;
}
}
},
toggleInvalidCls: function(hasError) {
this.el[hasError ? 'addCls' : 'removeCls'](this.invalidCls);
},
setFieldDefaults: function(defaults) {
var key;
for (key in defaults) {
if (!this.hasOwnProperty(key)) {
this[key] = defaults[key];
}
}
}
}, function() {
if (Ext.supports.Touch) {
this.prototype.msgTarget = 'side';
}
});
Ext.define('Ext.form.field.Field', {
mixinId: 'field',
isFormField: true,
config: {
validation: null,
validationField: null
},
disabled: false,
submitValue: true,
validateOnChange: true,
valuePublishEvent: 'change',
suspendCheckChange: 0,
dirty: false,
initField: function() {
var me = this,
valuePublishEvent = me.valuePublishEvent,
len, i;
me.initValue();
var badNames = [
'tagName',
'nodeName',
'children',
'childNodes'
],
name = this.name;
if (name && Ext.Array.indexOf(badNames, name) > -1) {
Ext.log.warn([
'It is recommended to not use "',
name,
'" as a field name, because it ',
'can cause naming collisions during form submission.'
].join(''));
}
if (Ext.isString(valuePublishEvent)) {
me.on(valuePublishEvent, me.publishValue, me);
} else {
for (i = 0 , len = valuePublishEvent.length; i < len; ++i) {
me.on(valuePublishEvent[i], me.publishValue, me);
}
}
},
initValue: function() {
var me = this;
if ('value' in me) {
me.suspendCheckChange++;
me.setValue(me.value);
me.suspendCheckChange--;
}
me.initialValue = me.originalValue = me.lastValue = me.getValue();
},
getFieldIdentifier: function() {
return this.isEditorComponent ? this.dataIndex : this.name;
},
getName: function() {
return this.name;
},
getValue: function() {
return this.value;
},
setValue: function(value) {
var me = this;
me.value = value;
me.checkChange();
return me;
},
isEqual: function(value1, value2) {
return String(value1) === String(value2);
},
isEqualAsString: function(value1, value2) {
return String(Ext.valueFrom(value1, '')) === String(Ext.valueFrom(value2, ''));
},
getSubmitData: function() {
var me = this,
data = null;
if (!me.disabled && me.submitValue) {
data = {};
data[me.getName()] = '' + me.getValue();
}
return data;
},
getModelData: function(includeEmptyText,
isSubmitting) {
var me = this,
data = null;
if (!me.disabled && (me.submitValue || !isSubmitting)) {
data = {};
data[me.getFieldIdentifier()] = me.getValue();
}
return data;
},
reset: function() {
var me = this;
me.beforeReset();
me.setValue(me.originalValue);
me.clearInvalid();
delete me.wasValid;
},
beforeReset: Ext.emptyFn,
resetOriginalValue: function() {
this.originalValue = this.getValue();
this.checkDirty();
},
checkChange: function() {
var me = this,
newVal, oldVal;
if (!me.suspendCheckChange) {
newVal = me.getValue();
oldVal = me.lastValue;
if (!me.isDestroyed && me.didValueChange(newVal, oldVal)) {
me.lastValue = newVal;
me.fireEvent('change', me, newVal, oldVal);
me.onChange(newVal, oldVal);
}
}
},
didValueChange: function(newVal, oldVal) {
return !this.isEqual(newVal, oldVal);
},
onChange: function(newVal) {
var me = this;
if (me.validateOnChange) {
me.validate();
}
me.checkDirty();
},
publishValue: function() {
var me = this;
if (me.rendered && !me.getErrors().length) {
me.publishState('value', me.getValue());
}
},
isDirty: function() {
var me = this;
return !me.disabled && !me.isEqual(me.getValue(), me.originalValue);
},
checkDirty: function() {
var me = this,
isDirty = me.isDirty();
if (isDirty !== me.wasDirty) {
me.dirty = isDirty;
me.fireEvent('dirtychange', me, isDirty);
me.onDirtyChange(isDirty);
me.wasDirty = isDirty;
}
},
onDirtyChange: Ext.emptyFn,
getErrors: function(value) {
var errors = [],
validationField = this.getValidationField(),
validation = this.getValidation(),
result;
if (validationField) {
result = validationField.validate(value);
if (result !== true) {
errors.push(result);
}
}
if (validation && validation !== true) {
errors.push(validation);
}
return errors;
},
isValid: function() {
var me = this;
return me.disabled || Ext.isEmpty(me.getErrors());
},
validate: function() {
return this.checkValidityChange(this.isValid());
},
checkValidityChange: function(isValid) {
var me = this;
if (isValid !== me.wasValid) {
me.wasValid = isValid;
me.fireEvent('validitychange', me, isValid);
}
return isValid;
},
batchChanges: function(fn) {
try {
this.suspendCheckChange++;
fn();
} catch (pseudo) {
throw pseudo;
} finally {
this.suspendCheckChange--;
}
this.checkChange();
},
isFileUpload: function() {
return false;
},
extractFileInput: function() {
return null;
},
markInvalid: Ext.emptyFn,
clearInvalid: Ext.emptyFn,
updateValidation: function(validation, oldValidation) {
if (oldValidation) {
this.validate();
}
},
privates: {
resetToInitialValue: function() {
var me = this,
originalValue = me.originalValue;
me.originalValue = me.initialValue;
me.reset();
me.originalValue = originalValue;
}
}
});
Ext.define('Ext.form.field.Base', {
extend: 'Ext.Component',
mixins: [
'Ext.form.Labelable',
'Ext.form.field.Field'
],
xtype: 'field',
alternateClassName: [
'Ext.form.Field',
'Ext.form.BaseField'
],
requires: [
'Ext.util.DelayedTask',
'Ext.XTemplate'
],
focusable: true,
shrinkWrap: true,
fieldSubTpl: [
'<input id="{id}" data-ref="inputEl" type="{type}" role="{role}" {inputAttrTpl}',
' size="1"',
'<tpl if="name"> name="{name}"</tpl>',
'<tpl if="value"> value="{[Ext.util.Format.htmlEncode(values.value)]}"</tpl>',
'<tpl if="placeholder"> placeholder="{placeholder}"</tpl>',
'{%if (values.maxLength !== undefined){%} maxlength="{maxLength}"{%}%}',
'<tpl if="readOnly"> readonly="readonly"</tpl>',
'<tpl if="disabled"> disabled="disabled"</tpl>',
'<tpl if="tabIdx != null"> tabindex="{tabIdx}"</tpl>',
'<tpl if="fieldStyle"> style="{fieldStyle}"</tpl>',
' class="{fieldCls} {typeCls} {typeCls}-{ui} {editableCls} {inputCls}" autocomplete="off"/>',
{
disableFormats: true
}
],
defaultBindProperty: 'value',
subTplInsertions: [
'inputAttrTpl'
],
childEls: [
'inputEl'
],
inputType: 'text',
isTextInput: true,
invalidText: 'The value in this field is invalid',
fieldCls: Ext.baseCSSPrefix + 'form-field',
focusCls: 'form-focus',
dirtyCls: Ext.baseCSSPrefix + 'form-dirty',
checkChangeEvents: Ext.isIE && (!document.documentMode || document.documentMode <= 9) ? [
'change',
'propertychange',
'keyup'
] : [
'change',
'input',
'textInput',
'keyup',
'dragdrop'
],
ignoreChangeRe: /data\-errorqtip|style\.|className/,
checkChangeBuffer: 50,
liquidLayout: true,
readOnly: false,
readOnlyCls: Ext.baseCSSPrefix + 'form-readonly',
validateOnBlur: true,
hasFocus: false,
baseCls: Ext.baseCSSPrefix + 'field',
fieldBodyCls: Ext.baseCSSPrefix + 'field-body',
maskOnDisable: false,
stretchInputElFixed: true,
initComponent: function() {
var me = this;
me.callParent();
me.subTplData = me.subTplData || {};
me.initLabelable();
me.initField();
if (!me.name) {
me.name = me.getInputId();
}
if (me.readOnly) {
me.addCls(me.readOnlyCls);
}
me.addCls(Ext.baseCSSPrefix + 'form-type-' + me.inputType);
},
getInputId: function() {
return this.inputId || (this.inputId = this.id + '-inputEl');
},
getSubTplData: function(fieldData) {
var me = this,
type = me.inputType,
inputId = me.getInputId(),
data;
data = Ext.apply({
ui: me.ui,
id: inputId,
cmpId: me.id,
name: me.name || inputId,
disabled: me.disabled,
readOnly: me.readOnly,
value: me.getRawValue(),
type: type,
fieldCls: me.fieldCls,
fieldStyle: me.getFieldStyle(),
childElCls: fieldData.childElCls,
tabIdx: me.tabIndex,
inputCls: me.inputCls,
typeCls: Ext.baseCSSPrefix + 'form-' + (me.isTextInput ? 'text' : type),
role: me.ariaRole
}, me.subTplData);
me.getInsertionRenderData(data, me.subTplInsertions);
return data;
},
getSubTplMarkup: function(fieldData) {
var me = this,
data = me.getSubTplData(fieldData),
preSubTpl = me.getTpl('preSubTpl'),
postSubTpl = me.getTpl('postSubTpl'),
markup = '';
if (preSubTpl) {
markup += preSubTpl.apply(data);
}
markup += me.getTpl('fieldSubTpl').apply(data);
if (postSubTpl) {
markup += postSubTpl.apply(data);
}
return markup;
},
initRenderData: function() {
return Ext.applyIf(this.callParent(), this.getLabelableRenderData());
},
setFieldStyle: function(style) {
var me = this,
inputEl = me.inputEl;
if (inputEl) {
inputEl.applyStyles(style);
}
me.fieldStyle = style;
},
getFieldStyle: function() {
var style = this.fieldStyle;
return Ext.isObject(style) ? Ext.DomHelper.generateStyles(style, null, true) : style || '';
},
onRender: function() {
this.callParent(arguments);
this.mixins.labelable.self.initTip();
this.renderActiveError();
},
onFocusLeave: function(e) {
this.callParent([
e
]);
this.completeEdit();
},
completeEdit: Ext.emptyFn,
isFileUpload: function() {
return this.inputType === 'file';
},
getSubmitData: function() {
var me = this,
data = null,
val;
if (!me.disabled && me.submitValue) {
val = me.getSubmitValue();
if (val !== null) {
data = {};
data[me.getName()] = val;
}
}
return data;
},
getSubmitValue: function() {
return this.processRawValue(this.getRawValue());
},
getRawValue: function() {
var me = this,
v = (me.inputEl ? me.inputEl.getValue() : Ext.valueFrom(me.rawValue, ''));
me.rawValue = v;
return v;
},
setRawValue: function(value) {
var me = this,
rawValue = me.rawValue;
if (!me.transformRawValue.$nullFn) {
value = me.transformRawValue(value);
}
value = Ext.valueFrom(value, '');
if (rawValue === undefined || rawValue !== value || me.valueContainsPlaceholder) {
me.rawValue = value;
if (me.inputEl) {
me.bindChangeEvents(false);
me.inputEl.dom.value = value;
me.bindChangeEvents(true);
}
if (me.rendered && me.reference) {
me.publishState('rawValue', value);
}
}
return value;
},
transformRawValue: Ext.identityFn,
valueToRaw: function(value) {
return '' + Ext.valueFrom(value, '');
},
rawToValue: Ext.identityFn,
processRawValue: Ext.identityFn,
getValue: function() {
var me = this,
val = me.rawToValue(me.processRawValue(me.getRawValue()));
me.value = val;
return val;
},
setValue: function(value) {
var me = this;
me.setRawValue(me.valueToRaw(value));
return me.mixins.field.setValue.call(me, value);
},
onBoxReady: function() {
var me = this;
me.callParent(arguments);
if (me.setReadOnlyOnBoxReady) {
me.setReadOnly(me.readOnly);
}
},
onDisable: function() {
var me = this,
inputEl = me.inputEl;
me.callParent();
if (inputEl) {
inputEl.dom.disabled = true;
if (me.hasActiveError()) {
me.clearInvalid();
me.hadErrorOnDisable = true;
}
}
if (me.wasValid === false) {
me.checkValidityChange(true);
}
},
onEnable: function() {
var me = this,
inputEl = me.inputEl,
mark = me.preventMark,
valid;
me.callParent();
if (inputEl) {
inputEl.dom.disabled = false;
}
if (me.wasValid !== undefined) {
me.forceValidation = true;
me.preventMark = !me.hadErrorOnDisable;
valid = me.isValid();
me.forceValidation = false;
me.preventMark = mark;
me.checkValidityChange(valid);
}
delete me.hadErrorOnDisable;
},
setReadOnly: function(readOnly) {
var me = this,
inputEl = me.inputEl,
old = me.readOnly;
readOnly = !!readOnly;
me[readOnly ? 'addCls' : 'removeCls'](me.readOnlyCls);
me.readOnly = readOnly;
if (inputEl) {
inputEl.dom.readOnly = readOnly;
} else if (me.rendering) {
me.setReadOnlyOnBoxReady = true;
}
if (readOnly !== old) {
me.fireEvent('writeablechange', me, readOnly);
}
},
fireKey: function(e) {
if (e.isSpecialKey()) {
this.fireEvent('specialkey', this, e);
}
},
initEvents: function() {
var me = this,
inputEl = me.inputEl,
onFieldMutation = me.onFieldMutation,
events = me.checkChangeEvents,
len = events.length,
i, event;
if (inputEl) {
me.mon(inputEl, Ext.supports.SpecialKeyDownRepeat ? 'keydown' : 'keypress', me.fireKey, me);
for (i = 0; i < len; ++i) {
event = events[i];
if (event === 'propertychange') {
me.usesPropertychange = true;
}
if (event === 'textInput') {
me.usesTextInput = true;
}
me.mon(inputEl, event, onFieldMutation, me);
}
}
me.callParent();
},
onFieldMutation: function(e) {
var me = this,
task = me.checkChangeTask;
if (!me.readOnly && !(e.type === 'propertychange' && me.ignoreChangeRe.test(e.browserEvent.propertyName))) {
if (!task) {
me.checkChangeTask = task = new Ext.util.DelayedTask(me.doCheckChangeTask, me);
}
if (!me.bindNotifyListener) {
me.bindNotifyListener = Ext.on('beforebindnotify', me.onBeforeNotify, me, {
destroyable: true
});
}
task.delay(me.checkChangeBuffer);
}
},
doCheckChangeTask: function() {
var bindNotifyListener = this.bindNotifyListener;
if (bindNotifyListener) {
bindNotifyListener.destroy();
this.bindNotifyListener = null;
}
this.checkChange();
},
publishValue: function() {
var me = this;
if (me.rendered && !me.getErrors().length) {
me.publishState('value', me.getValue());
}
},
onDirtyChange: function(isDirty) {
var me = this;
me[isDirty ? 'addCls' : 'removeCls'](me.dirtyCls);
if (me.rendered && me.reference) {
me.publishState('dirty', isDirty);
}
},
isValid: function() {
var me = this,
disabled = me.disabled,
validate = me.forceValidation || !disabled;
return validate ? me.validateValue(me.processRawValue(me.getRawValue())) : disabled;
},
validateValue: function(value) {
var me = this,
errors = me.getErrors(value),
isValid = Ext.isEmpty(errors);
if (!me.preventMark) {
if (isValid) {
me.clearInvalid();
} else {
me.markInvalid(errors);
}
}
return isValid;
},
markInvalid: function(errors) {
var me = this,
oldMsg = me.getActiveError(),
active;
me.setActiveErrors(Ext.Array.from(errors));
active = me.getActiveError();
if (oldMsg !== active) {
me.setError(active);
}
},
clearInvalid: function() {
var me = this,
hadError = me.hasActiveError();
delete me.hadErrorOnDisable;
me.unsetActiveError();
if (hadError) {
me.setError('');
}
},
setError: function(error) {
var me = this,
msgTarget = me.msgTarget,
prop;
if (me.rendered) {
if (msgTarget === 'title' || msgTarget === 'qtip') {
prop = msgTarget === 'qtip' ? 'data-errorqtip' : 'title';
me.getActionEl().dom.setAttribute(prop, error || '');
} else {
me.updateLayout();
}
}
},
renderActiveError: function() {
var me = this,
hasError = me.hasActiveError(),
invalidCls = me.invalidCls + '-field';
if (me.inputEl) {
me.inputEl[hasError ? 'addCls' : 'removeCls']([
invalidCls,
invalidCls + '-' + me.ui
]);
}
me.mixins.labelable.renderActiveError.call(me);
},
beforeDestroy: function() {
var me = this,
task = me.checkChangeTask;
if (task) {
task.cancel();
}
me.checkChangeTask = me.bindNotifyListener = Ext.destroy(me.bindNotifyListener);
me.callParent();
},
privates: {
applyBind: function(bind, currentBindings) {
var me = this,
valueBinding = currentBindings && currentBindings.value,
bindings, newValueBind;
bindings = me.callParent([
bind,
currentBindings
]);
newValueBind = bindings.value;
me.hasBindingValue = !!newValueBind;
if (newValueBind !== valueBinding && me.getInherited().modelValidation) {
me.updateValueBinding(bindings);
}
return bindings;
},
applyRenderSelectors: function() {
var me = this;
me.callParent();
if (!me.inputEl) {
me.inputEl = me.el.getById(me.getInputId());
}
},
bindChangeEvents: function(active) {
var method = active ? 'resumeEvent' : 'suspendEvent',
inputEl = this.inputEl;
if (this.usesPropertychange) {
inputEl[method]('propertychange');
}
if (this.usesTextInput) {
inputEl[method]('textInput');
}
},
getActionEl: function() {
return this.inputEl || this.el;
},
getFocusEl: function() {
return this.inputEl;
},
initRenderTpl: function() {
var me = this;
if (!me.hasOwnProperty('renderTpl')) {
me.renderTpl = me.getTpl('labelableRenderTpl');
}
return me.callParent();
},
onBeforeNotify: function() {
this.checkChangeTask.cancel();
this.checkChange();
},
updateValueBinding: function(bindings) {
var me = this,
newBinding = bindings.value,
fieldBinding = bindings.$fieldBinding;
if (fieldBinding) {
fieldBinding.destroy();
bindings.$fieldBinding = null;
}
if (newBinding && newBinding.bindValidationField) {
me.fieldBinding = newBinding.bindValidationField('setValidationField', me);
}
}
},
deprecated: {
"5": {
methods: {
doComponentLayout: function() {
this.bindChangeEvents(false);
this.callParent(arguments);
this.bindChangeEvents(true);
}
}
}
}
});
Ext.define('Ext.form.field.Display', {
extend: 'Ext.form.field.Base',
alias: 'widget.displayfield',
requires: [
'Ext.util.Format',
'Ext.XTemplate'
],
alternateClassName: [
'Ext.form.DisplayField',
'Ext.form.Display'
],
ariaRole: 'textbox',
fieldSubTpl: [
'<div id="{id}" role="{role}" {inputAttrTpl}',
'<tpl if="fieldStyle"> style="{fieldStyle}"</tpl>',
' class="{fieldCls} {fieldCls}-{ui}">{value}</div>',
{
compiled: true,
disableFormats: true
}
],
focusable: false,
readOnly: true,
fieldCls: Ext.baseCSSPrefix + 'form-display-field',
fieldBodyCls: Ext.baseCSSPrefix + 'form-display-field-body',
htmlEncode: false,
noWrap: false,
validateOnChange: false,
initEvents: Ext.emptyFn,
submitValue: false,
getValue: function() {
return this.value;
},
valueToRaw: function(value) {
if (value || value === 0 || value === false) {
return value;
} else {
return '';
}
},
isDirty: function() {
return false;
},
isValid: Ext.returnTrue,
validate: Ext.returnTrue,
getRawValue: function() {
return this.rawValue;
},
setRawValue: function(value) {
var me = this;
value = Ext.valueFrom(value, '');
me.rawValue = value;
if (me.rendered) {
me.inputEl.dom.innerHTML = me.getDisplayValue();
me.updateLayout();
}
return value;
},
getDisplayValue: function() {
var me = this,
value = this.getRawValue(),
display;
if (me.renderer) {
display = me.renderer.call(me.scope || me, value, me);
} else {
display = me.htmlEncode ? Ext.util.Format.htmlEncode(value) : value;
}
return display;
},
getSubTplData: function(fieldData) {
var ret = this.callParent(arguments);
ret.value = this.getDisplayValue();
return ret;
}
});
Ext.define('Ext.layout.container.Fit', {
extend: 'Ext.layout.container.Container',
alternateClassName: 'Ext.layout.FitLayout',
alias: 'layout.fit',
itemCls: Ext.baseCSSPrefix + 'fit-item',
type: 'fit',
manageMargins: true,
sizePolicies: {
0: {
readsWidth: 1,
readsHeight: 1,
setsWidth: 0,
setsHeight: 0
},
1: {
readsWidth: 0,
readsHeight: 1,
setsWidth: 1,
setsHeight: 0
},
2: {
readsWidth: 1,
readsHeight: 0,
setsWidth: 0,
setsHeight: 1
},
3: {
readsWidth: 0,
readsHeight: 0,
setsWidth: 1,
setsHeight: 1
}
},
getItemSizePolicy: function(item, ownerSizeModel) {
var sizeModel = ownerSizeModel || this.owner.getSizeModel(),
mode = (sizeModel.width.shrinkWrap ? 0 : 1) |
(sizeModel.height.shrinkWrap ? 0 : 2);
return this.sizePolicies[mode];
},
beginLayoutCycle: function(ownerContext, firstCycle) {
var me = this,
resetHeight = me.lastHeightModel && me.lastHeightModel.calculated,
resetWidth = me.lastWidthModel && me.lastWidthModel.calculated,
resetSizes = resetWidth || resetHeight,
maxChildMinHeight = 0,
maxChildMinWidth = 0,
c, childItems, i, item, length, margins, minHeight, minWidth, style, undef;
me.callParent(arguments);
if (resetSizes && ownerContext.targetContext.el.dom.tagName.toUpperCase() !== 'TD') {
resetSizes = resetWidth = resetHeight = false;
}
childItems = ownerContext.childItems;
length = childItems.length;
for (i = 0; i < length; ++i) {
item = childItems[i];
if (firstCycle) {
c = item.target;
minHeight = c.minHeight;
minWidth = c.minWidth;
if (minWidth || minHeight) {
margins = item.marginInfo || item.getMarginInfo();
minHeight += margins.height;
minWidth += margins.height;
if (maxChildMinHeight < minHeight) {
maxChildMinHeight = minHeight;
}
if (maxChildMinWidth < minWidth) {
maxChildMinWidth = minWidth;
}
}
}
if (resetSizes) {
style = item.el.dom.style;
if (resetHeight) {
style.height = '';
}
if (resetWidth) {
style.width = '';
}
}
}
if (firstCycle) {
ownerContext.maxChildMinHeight = maxChildMinHeight;
ownerContext.maxChildMinWidth = maxChildMinWidth;
}
c = ownerContext.target;
ownerContext.overflowX = (!ownerContext.widthModel.shrinkWrap && ownerContext.maxChildMinWidth && c.scrollFlags.x) || undef;
ownerContext.overflowY = (!ownerContext.heightModel.shrinkWrap && ownerContext.maxChildMinHeight && c.scrollFlags.y) || undef;
},
calculate: function(ownerContext) {
var me = this,
childItems = ownerContext.childItems,
length = childItems.length,
containerSize = me.getContainerSize(ownerContext),
info = {
length: length,
ownerContext: ownerContext,
targetSize: containerSize
},
shrinkWrapWidth = ownerContext.widthModel.shrinkWrap,
shrinkWrapHeight = ownerContext.heightModel.shrinkWrap,
overflowX = ownerContext.overflowX,
overflowY = ownerContext.overflowY,
scrollbars, scrollbarSize, padding, i, contentWidth, contentHeight;
ownerContext.state.info = info;
if (overflowX || overflowY) {
scrollbars = me.getScrollbarsNeeded(overflowX && containerSize.width, overflowY && containerSize.height, ownerContext.maxChildMinWidth, ownerContext.maxChildMinHeight);
if (scrollbars) {
scrollbarSize = Ext.getScrollbarSize();
if (scrollbars & 1) {
containerSize.height -= scrollbarSize.height;
}
if (scrollbars & 2) {
containerSize.width -= scrollbarSize.width;
}
}
}
if (length > 0) {
for (i = 0; i < length; ++i) {
info.index = i;
me.fitItem(childItems[i], info);
}
} else {
info.contentWidth = info.contentHeight = 0;
}
if (shrinkWrapHeight || shrinkWrapWidth) {
padding = ownerContext.targetContext.getPaddingInfo();
if (shrinkWrapWidth) {
if (overflowY && !containerSize.gotHeight) {
me.done = false;
} else {
contentWidth = info.contentWidth + padding.width;
if (scrollbars & 2) {
contentWidth += scrollbarSize.width;
}
if (!ownerContext.setContentWidth(contentWidth)) {
me.done = false;
}
}
}
if (shrinkWrapHeight) {
if (overflowX && !containerSize.gotWidth) {
me.done = false;
} else {
contentHeight = info.contentHeight + padding.height;
if (scrollbars & 1) {
contentHeight += scrollbarSize.height;
}
if (!ownerContext.setContentHeight(contentHeight)) {
me.done = false;
}
}
}
}
},
fitItem: function(itemContext, info) {
var me = this;
if (itemContext.invalid) {
me.done = false;
return;
}
info.margins = itemContext.getMarginInfo();
info.needed = info.got = 0;
me.fitItemWidth(itemContext, info);
me.fitItemHeight(itemContext, info);
if (info.got !== info.needed) {
me.done = false;
}
},
fitItemWidth: function(itemContext, info) {
var contentWidth, width;
if (info.ownerContext.widthModel.shrinkWrap) {
width = itemContext.getProp('width') + info.margins.width;
contentWidth = info.contentWidth;
if (contentWidth === undefined) {
info.contentWidth = width;
} else {
info.contentWidth = Math.max(contentWidth, width);
}
} else if (itemContext.widthModel.calculated) {
++info.needed;
if (info.targetSize.gotWidth) {
++info.got;
this.setItemWidth(itemContext, info);
} else {
return;
}
}
this.positionItemX(itemContext, info);
},
fitItemHeight: function(itemContext, info) {
var contentHeight, height;
if (info.ownerContext.heightModel.shrinkWrap) {
height = itemContext.getProp('height') + info.margins.height;
contentHeight = info.contentHeight;
if (contentHeight === undefined) {
info.contentHeight = height;
} else {
info.contentHeight = Math.max(contentHeight, height);
}
} else if (itemContext.heightModel.calculated) {
++info.needed;
if (info.targetSize.gotHeight) {
++info.got;
this.setItemHeight(itemContext, info);
} else {
return;
}
}
this.positionItemY(itemContext, info);
},
positionItemX: function(itemContext, info) {
var margins = info.margins;
if (info.index || margins.left) {
itemContext.setProp('x', margins.left);
}
if (margins.width) {
itemContext.setProp('margin-right', margins.width);
}
},
positionItemY: function(itemContext, info) {
var margins = info.margins;
if (info.index || margins.top) {
itemContext.setProp('y', margins.top);
}
if (margins.height) {
itemContext.setProp('margin-bottom', margins.height);
}
},
setItemHeight: function(itemContext, info) {
itemContext.setHeight(info.targetSize.height - info.margins.height);
},
setItemWidth: function(itemContext, info) {
itemContext.setWidth(info.targetSize.width - info.margins.width);
}
});
Ext.define('Ext.panel.Table', {
extend: 'Ext.panel.Panel',
alias: 'widget.tablepanel',
requires: [
'Ext.layout.container.Fit'
],
uses: [
'Ext.selection.RowModel',
'Ext.selection.CellModel',
'Ext.selection.CheckboxModel',
'Ext.grid.plugin.BufferedRenderer',
'Ext.grid.header.Container',
'Ext.grid.locking.Lockable',
'Ext.grid.NavigationModel'
],
extraBaseCls: Ext.baseCSSPrefix + 'grid',
extraBodyCls: Ext.baseCSSPrefix + 'grid-body',
defaultBindProperty: 'store',
layout: 'fit',
ariaRole: 'grid',
config: {
selection: null
},
publishes: [
'selection'
],
twoWayBindable: [
'selection'
],
autoLoad: false,
variableRowHeight: false,
numFromEdge: 2,
trailingBufferZone: 10,
leadingBufferZone: 20,
hasView: false,
viewType: null,
deferRowRender: false,
sortableColumns: true,
multiColumnSort: false,
enableLocking: false,
scrollerOwner: true,
enableColumnMove: true,
sealedColumns: false,
enableColumnResize: true,
rowLines: true,
bufferedRenderer: true,
ownerGrid: null,
colLinesCls: Ext.baseCSSPrefix + 'grid-with-col-lines',
rowLinesCls: Ext.baseCSSPrefix + 'grid-with-row-lines',
noRowLinesCls: Ext.baseCSSPrefix + 'grid-no-row-lines',
hiddenHeaderCtCls: Ext.baseCSSPrefix + 'grid-header-ct-hidden',
hiddenHeaderCls: Ext.baseCSSPrefix + 'grid-header-hidden',
resizeMarkerCls: Ext.baseCSSPrefix + 'grid-resize-marker',
emptyCls: Ext.baseCSSPrefix + 'grid-empty',
focusable: true,
constructor: function(config) {
var me = this,
store;
me.ownerGrid = (config && config.ownerGrid) || me;
me.callParent([
config
]);
store = this.store;
store.trackStateChanges = true;
if (me.autoLoad) {
store.unblockLoad();
store.load();
}
},
initComponent: function() {
if (this.verticalScroller) {
Ext.Error.raise("The verticalScroller config is not supported.");
}
if (!this.viewType) {
Ext.Error.raise("You must specify a viewType config.");
}
if (this.headers) {
Ext.Error.raise("The headers config is not supported. Please specify columns instead.");
}
var me = this,
headerCtCfg = me.columns || me.colModel || [],
view, i, len, bufferedRenderer,
store = me.store = Ext.data.StoreManager.lookup(me.store || 'ext-empty-store'),
columns, viewScroller;
me.enableLocking = me.enableLocking || me.hasLockedColumns(headerCtCfg);
if (me.autoLoad) {
me.store.blockLoad();
}
if (me.plugins) {
me.plugins = me.constructPlugins();
}
if (me.columnLines) {
me.addBodyCls(me.colLinesCls);
}
me.addBodyCls(me.rowLines ? me.rowLinesCls : me.noRowLinesCls);
me.addBodyCls(me.extraBodyCls);
if (me.enableLocking) {
me.self.mixin('lockable', Ext.grid.locking.Lockable);
me.injectLockable();
} else
{
if (headerCtCfg.isRootHeader) {
if (me.hideHeaders) {
headerCtCfg.setHeight(0);
headerCtCfg.hiddenHeaders = true;
}
me.headerCt = headerCtCfg;
me.headerCt.grid = me;
me.headerCt.forceFit = !!me.forceFit;
me.columnManager = headerCtCfg.columnManager;
me.visibleColumnManager = headerCtCfg.visibleColumnManager;
} else
{
if (Ext.isArray(headerCtCfg)) {
headerCtCfg = {
items: headerCtCfg
};
}
Ext.apply(headerCtCfg, {
grid: me,
forceFit: me.forceFit,
sortable: me.sortableColumns,
enableColumnMove: me.enableColumnMove,
enableColumnResize: me.enableColumnResize,
columnLines: me.columnLines,
sealed: me.sealedColumns
});
if (me.hideHeaders) {
headerCtCfg.height = 0;
headerCtCfg.hiddenHeaders = true;
}
if (Ext.isDefined(me.enableColumnHide)) {
headerCtCfg.enableColumnHide = me.enableColumnHide;
}
me.headerCt = new Ext.grid.header.Container(headerCtCfg);
}
me.headerCt.setScrollable({
x: false,
y: false
});
}
me.columns = columns = me.headerCt.getGridColumns();
me.scrollTask = new Ext.util.DelayedTask(me.syncHorizontalScroll, me);
me.cls = (me.cls || '') + (' ' + me.extraBaseCls);
delete me.autoScroll;
bufferedRenderer = me.plugins && Ext.Array.findBy(me.plugins, function(p) {
return p.isBufferedRenderer;
});
if (bufferedRenderer) {
me.bufferedRenderer = bufferedRenderer;
}
if (!me.hasView) {
if (store.isBufferedStore && !store.getRemoteSort()) {
for (i = 0 , len = columns.length; i < len; i++) {
columns[i].sortable = false;
}
}
if (me.hideHeaders) {
me.headerCt.addCls(me.hiddenHeaderCtCls);
me.addCls(me.hiddenHeaderCls);
}
me.relayHeaderCtEvents(me.headerCt);
me.features = me.features || [];
if (!Ext.isArray(me.features)) {
me.features = [
me.features
];
}
me.dockedItems = [].concat(me.dockedItems || []);
me.dockedItems.unshift(me.headerCt);
me.viewConfig = me.viewConfig || {};
view = me.getView();
me.items = [
view
];
me.hasView = true;
if (!me.hideHeaders) {
viewScroller = view.getScrollable();
if (viewScroller) {
me.headerCt.getScrollable().addPartner(viewScroller, 'x');
}
}
me.bindStore(store, true);
me.mon(view, {
viewready: me.onViewReady,
refresh: me.onRestoreHorzScroll,
scope: me
});
}
me.selModel = me.view.getSelectionModel();
if (me.selModel.isRowModel) {
me.selModel.on({
scope: me,
lastselectedchanged: me.updateBindSelection,
selectionchange: me.updateBindSelection
});
}
me.relayEvents(me.view, [
'beforeitemmousedown',
'beforeitemmouseup',
'beforeitemmouseenter',
'beforeitemmouseleave',
'beforeitemclick',
'beforeitemdblclick',
'beforeitemcontextmenu',
'itemmousedown',
'itemmouseup',
'itemmouseenter',
'itemmouseleave',
'itemclick',
'itemdblclick',
'itemcontextmenu',
'beforecellclick',
'cellclick',
'beforecelldblclick',
'celldblclick',
'beforecellcontextmenu',
'cellcontextmenu',
'beforecellmousedown',
'cellmousedown',
'beforecellmouseup',
'cellmouseup',
'beforecellkeydown',
'cellkeydown',
'rowclick',
'rowdblclick',
'rowcontextmenu',
'rowmousedown',
'rowmouseup',
'rowkeydown',
'beforeitemkeydown',
'itemkeydown',
'beforeitemkeyup',
'itemkeyup',
'beforeitemkeypress',
'itemkeypress',
'beforecontainermousedown',
'beforecontainermouseup',
'beforecontainermouseover',
'beforecontainermouseout',
'beforecontainerclick',
'beforecontainerdblclick',
'beforecontainercontextmenu',
'beforecontainerkeydown',
'beforecontainerkeyup',
'beforecontainerkeypress',
'containermouseup',
'containermousedown',
'containermouseover',
'containermouseout',
'containerclick',
'containerdblclick',
'containercontextmenu',
'containerkeydown',
'containerkeyup',
'containerkeypress',
'selectionchange',
'beforeselect',
'select',
'beforedeselect',
'deselect'
]);
me.callParent(arguments);
me.addStateEvents([
'columnresize',
'columnmove',
'columnhide',
'columnshow',
'sortchange',
'filterchange',
'groupchange'
]);
},
beforeRender: function() {
var me = this,
bufferedRenderer = me.bufferedRenderer;
if (!me.lockable) {
if (bufferedRenderer && me.getSizeModel().height.auto) {
if (bufferedRenderer.isBufferedRenderer) {
Ext.Error.raise('Cannot use buffered rendering with auto height');
}
me.bufferedRenderer = bufferedRenderer = false;
}
if (bufferedRenderer && !bufferedRenderer.isBufferedRenderer) {
bufferedRenderer = {
xclass: 'Ext.grid.plugin.BufferedRenderer'
};
Ext.copyTo(bufferedRenderer, me, 'variableRowHeight,numFromEdge,trailingBufferZone,leadingBufferZone,scrollToLoadBuffer');
me.bufferedRenderer = me.addPlugin(bufferedRenderer);
}
}
me.callParent(arguments);
},
getHeaderContainer: function() {
return this.getView().getHeaderCt();
},
getColumns: function() {
return this.getHeaderContainer().getGridColumns();
},
getVisibleColumns: function() {
return this.getHeaderContainer().getVisibleGridColumns();
},
focus: function() {
this.getView().focus();
},
disableColumnHeaders: function() {
this.headerCt.disable();
},
enableColumnHeaders: function() {
this.headerCt.enable();
},
hasLockedColumns: function(columns) {
var i, len, column;
if (columns.isRootHeader) {
columns = columns.items.items;
}
else if (Ext.isObject(columns)) {
columns = columns.items;
}
for (i = 0 , len = columns.length; i < len; i++) {
column = columns[i];
if (!column.processed && column.locked) {
return true;
}
}
},
relayHeaderCtEvents: function(headerCt) {
this.relayEvents(headerCt, [
'columnresize',
'columnmove',
'columnhide',
'columnshow',
'columnschanged',
'sortchange',
'headerclick',
'headercontextmenu',
'headertriggerclick'
]);
},
getState: function() {
var me = this,
state = me.callParent(),
storeState = me.store.getState();
state = me.addPropertyToState(state, 'columns', me.headerCt.getColumnsState());
if (storeState) {
state.storeState = storeState;
}
return state;
},
applyState: function(state) {
var me = this,
sorter = state.sort,
storeState = state.storeState,
store = me.store,
columns = state.columns;
delete state.columns;
me.callParent(arguments);
if (columns) {
me.headerCt.applyColumnsState(columns);
}
if (sorter) {
if (store.getRemoteSort()) {
store.sort({
property: sorter.property,
direction: sorter.direction,
root: sorter.root
}, null, false);
} else {
store.sort(sorter.property, sorter.direction);
}
}
else if (storeState) {
store.applyState(storeState);
}
},
getStore: function() {
return this.store;
},
getView: function() {
var me = this,
scroll, scrollable, viewConfig;
if (!me.view) {
viewConfig = me.viewConfig;
scroll = viewConfig.scroll || me.scroll;
scrollable = me.scrollable;
if (scrollable == null && viewConfig.scrollable == null && scroll !== null) {
if (scroll === true || scroll === 'both') {
scrollable = true;
} else if (scroll === false || scroll === 'none') {
scrollable = false;
} else if (scroll === 'vertical') {
scrollable = {
x: false,
y: true
};
} else if (scroll === 'horizontal') {
scrollable = {
x: true,
y: false
};
}
}
viewConfig = Ext.apply({
grid: me,
ownerGrid: me.ownerGrid,
deferInitialRefresh: me.deferRowRender,
variableRowHeight: me.variableRowHeight,
preserveScrollOnRefresh: true,
trackOver: me.trackMouseOver !== false,
throttledUpdate: me.throttledUpdate === true,
xtype: me.viewType,
store: me.store,
headerCt: me.headerCt,
columnLines: me.columnLines,
rowLines: me.rowLines,
navigationModel: 'grid',
features: me.features,
panel: me,
emptyText: me.emptyText || ''
}, me.viewConfig);
if (scrollable != null) {
viewConfig.scrollable = scrollable;
me.scrollable = null;
}
Ext.create(viewConfig);
if (me.view.emptyText) {
me.view.emptyText = '<div class="' + me.emptyCls + '">' + me.view.emptyText + '</div>';
}
me.view.getComponentLayout().headerCt = me.headerCt;
me.mon(me.view, {
uievent: me.processEvent,
scope: me
});
me.headerCt.view = me.view;
if (me.hasListeners.viewcreated) {
me.fireEvent('viewcreated', me, me.view);
}
}
return me.view;
},
getColumnManager: function() {
return this.columnManager;
},
getVisibleColumnManager: function() {
return this.visibleColumnManager;
},
getTopLevelColumnManager: function() {
return this.ownerGrid.getColumnManager();
},
getTopLevelVisibleColumnManager: function() {
return this.ownerGrid.getVisibleColumnManager();
},
setAutoScroll: Ext.emptyFn,
applyScrollable: function(scrollable) {
if (this.view) {
this.view.setScrollable(scrollable);
}
return scrollable;
},
getScrollable: function() {
return null;
},
processEvent: function(type, view, cell, recordIndex, cellIndex, e, record, row) {
var header = e.position.column;
if (header) {
return header.processEvent.apply(header, arguments);
}
},
ensureVisible: function(record, options) {
this.doEnsureVisible(record, options);
},
scrollByDeltaY: function(yDelta, animate) {
this.getView().scrollBy(0, yDelta, animate);
},
scrollByDeltaX: function(xDelta, animate) {
this.getView().scrollBy(xDelta, 0, animate);
},
afterCollapse: function() {
this.saveScrollPos();
this.callParent(arguments);
},
afterExpand: function() {
this.callParent(arguments);
this.restoreScrollPos();
},
saveScrollPos: Ext.emptyFn,
restoreScrollPos: Ext.emptyFn,
onHeaderResize: function() {
var scroller = this.view.getScrollable(),
size;
if (scroller) {
size = scroller.getSize();
if (size) {
scroller.setSize({
x: this.headerCt.getTableWidth(),
y: size.y
});
}
}
},
onHeaderMove: function(headerCt, header, colsToMove, fromIdx, toIdx) {
var me = this;
if (me.optimizedColumnMove === false) {
me.view.refreshView();
} else
{
me.view.moveColumn(fromIdx, toIdx, colsToMove);
}
me.delayScroll();
},
onHeaderHide: function(headerCt, header, complete) {
var view = this.view;
if (!headerCt.childHideCount && view.refreshCounter) {
view.refreshView();
}
},
onHeaderShow: function(headerCt, header) {
var view = this.view;
if (view.refreshCounter) {
view.refreshView();
}
},
onHeadersChanged: function(headerCt, header) {
var me = this;
if (me.rendered && !me.reconfiguring) {
me.view.refreshView();
me.delayScroll();
}
},
delayScroll: function() {
var target = this.view;
if (target) {
this.scrollTask.delay(10, null, null, [
target
]);
}
},
onViewReady: function() {
this.fireEvent('viewready', this);
},
onRestoreHorzScroll: function() {
var me = this,
x = me.scrollXPos;
if (x) {
me.syncHorizontalScroll(me, true);
}
},
getScrollerOwner: function() {
var rootCmp = this;
if (!this.scrollerOwner) {
rootCmp = this.up('[scrollerOwner]');
}
return rootCmp;
},
getLhsMarker: function() {
var me = this;
return me.lhsMarker || (me.lhsMarker = Ext.DomHelper.append(me.el, {
role: 'presentation',
cls: me.resizeMarkerCls
}, true));
},
getRhsMarker: function() {
var me = this;
return me.rhsMarker || (me.rhsMarker = Ext.DomHelper.append(me.el, {
role: 'presentation',
cls: me.resizeMarkerCls
}, true));
},
getSelection: function() {
return this.getSelectionModel().getSelection();
},
updateSelection: function(selection) {
var me = this,
sm;
if (!me.ignoreNextSelection) {
me.ignoreNextSelection = true;
sm = me.getSelectionModel();
if (selection) {
sm.select(selection);
} else {
sm.deselectAll();
}
me.ignoreNextSelection = false;
}
},
updateBindSelection: function(selModel, selection) {
var me = this,
selected = null;
if (!me.ignoreNextSelection) {
me.ignoreNextSelection = true;
if (selection.length) {
selected = selModel.getLastSelected();
me.hasHadSelection = true;
}
if (me.hasHadSelection) {
me.setSelection(selected);
}
me.ignoreNextSelection = false;
}
},
getNavigationModel: function() {
return this.getView().getNavigationModel();
},
getSelectionModel: function() {
return this.getView().getSelectionModel();
},
getScrollTarget: function() {
var items = this.getScrollerOwner().query('tableview');
return items[items.length - 1];
},
syncHorizontalScroll: function(target, setBody) {
var me = this,
x = me.view.getScrollX(),
scrollTarget;
setBody = setBody === true;
if (me.rendered && (setBody || x !== me.scrollXPos)) {
if (setBody) {
scrollTarget = me.getScrollTarget();
scrollTarget.setScrollX(x);
}
me.headerCt.setScrollX(x);
me.scrollXPos = x;
}
},
onStoreLoad: Ext.emptyFn,
getEditorParent: function() {
return this.body;
},
bindStore: function(store, initial) {
var me = this,
view = me.getView();
if (store) {
me.store = store;
if (view.store !== store) {
view.bindStore(store, false);
}
me.mon(store, {
load: me.onStoreLoad,
scope: me
});
me.storeRelayers = me.relayEvents(store, [
'filterchange',
'groupchange'
]);
} else {
me.unbindStore();
}
},
unbindStore: function() {
var me = this,
store = me.store,
view;
if (store) {
me.store = null;
me.mun(store, {
load: me.onStoreLoad,
scope: me
});
Ext.destroy(me.storeRelayers);
view = me.view;
if (view.store) {
view.bindStore(null);
}
}
},
setColumns: function(columns) {
if (columns.length || this.getColumnManager().getColumns().length) {
this.reconfigure(undefined, columns);
}
},
setStore: function(store) {
this.reconfigure(store);
},
reconfigure: function(store, columns) {
var me = this,
oldStore = me.store,
headerCt = me.headerCt,
lockable = me.lockable,
oldColumns = headerCt ? headerCt.items.getRange() : me.columns,
view = me.getView(),
block, refreshCounter;
if (arguments.length === 1 && Ext.isArray(store)) {
columns = store;
store = null;
}
if (columns) {
columns = Ext.Array.slice(columns);
}
me.reconfiguring = true;
if (store) {
store = Ext.StoreManager.lookup(store);
}
me.fireEvent('beforereconfigure', me, store, columns, oldStore, oldColumns);
Ext.suspendLayouts();
if (lockable) {
me.reconfigureLockable(store, columns);
} else {
block = view.blockRefresh;
view.blockRefresh = true;
if (store && store !== oldStore) {
me.unbindStore();
me.bindStore(store);
}
if (columns) {
delete me.scrollXPos;
headerCt.removeAll();
headerCt.add(columns);
}
view.blockRefresh = block;
refreshCounter = view.refreshCounter;
}
Ext.resumeLayouts(true);
if (lockable) {
me.afterReconfigureLockable();
} else if (view.refreshCounter === refreshCounter) {
view.refreshView();
}
me.fireEvent('reconfigure', me, store, columns, oldStore, oldColumns);
delete me.reconfiguring;
},
beforeDestroy: function() {
var me = this,
task = me.scrollTask;
if (task) {
task.cancel();
me.scrollTask = null;
}
Ext.destroy(me.focusEnterLeaveListeners);
me.callParent();
},
onDestroy: function() {
var me = this;
if (me.lockable) {
me.destroyLockable();
}
me.unbindStore();
me.callParent();
me.columns = me.storeRelayers = me.columnManager = me.visibleColumnManager = null;
},
destroy: function() {
var me = this;
me.callParent();
if (me.isDestroyed) {
me.view = me.selModel = me.headerCt = null;
}
},
privates: {
initFocusableElement: function() {},
doEnsureVisible: function(record, options) {
if (this.lockable) {
return this.ensureLockedVisible(record, options);
}
if (typeof record !== 'number' && !record.isEntity) {
record = this.store.getById(record);
}
var me = this,
callback, scope, animate, highlight, select, doFocus,
view = me.getView(),
domNode = view.getNode(record);
if (!me.rendered || !view.refreshCounter) {
return;
}
if (options) {
callback = options.callback;
scope = options.scope;
animate = options.animate;
highlight = options.highlight;
select = options.select;
doFocus = options.focus;
}
if (domNode) {
view.getScrollable().scrollIntoView(domNode, null, animate, highlight);
if (!record.isEntity) {
record = view.getRecord(domNode);
}
if (select) {
view.getSelectionModel().select(record);
}
if (doFocus) {
view.getNavigationModel().setPosition(record, 0);
}
Ext.callback(callback, scope || me, [
true,
record,
domNode
]);
}
else if (view.bufferedRenderer) {
view.bufferedRenderer.scrollTo(record, {
animate: animate,
highlight: highlight,
select: select,
focus: doFocus,
callback: function(recordIdx, record, domNode) {
Ext.callback(callback, scope || me, [
true,
record,
domNode
]);
}
});
} else {
Ext.callback(callback, scope || me, [
false,
null
]);
}
},
getFocusEl: function() {
return this.getView().getFocusEl();
}
}
});
Ext.define('Ext.selection.Model', {
extend: 'Ext.mixin.Observable',
alternateClassName: 'Ext.AbstractSelectionModel',
mixins: [
'Ext.util.StoreHolder',
'Ext.mixin.Factoryable'
],
alias: 'selection.abstract',
factoryConfig: {
defaultType: 'dataviewmodel'
},
$configPrefixed: false,
$configStrict: false,
config: {
store: null,
selected: {}
},
isSelectionModel: true,
allowDeselect: undefined,
toggleOnClick: true,
selected: null,
pruneRemoved: true,
suspendChange: 0,
ignoreRightMouseSelection: false,
constructor: function(cfg) {
var me = this;
me.modes = {
SINGLE: true,
SIMPLE: true,
MULTI: true
};
me.callParent([
cfg
]);
me.setSelectionMode(me.mode);
if (me.selectionMode !== 'SINGLE') {
me.allowDeselect = true;
}
},
updateStore: function(store, oldStore) {
this.bindStore(store, !oldStore);
},
applySelected: function(selected) {
if (!selected.isCollection) {
selected = new Ext.util.Collection(Ext.apply({
rootProperty: 'data'
}, selected));
}
return selected;
},
onBindStore: function(store, initial) {
var me = this;
me.mixins.storeholder.onBindStore.call(me, [
store,
initial
]);
if (store && !me.preventRefresh) {
me.refresh();
}
},
getStoreListeners: function() {
var me = this;
return {
add: me.onStoreAdd,
clear: me.onStoreClear,
remove: me.onStoreRemove,
update: me.onStoreUpdate,
idchanged: me.onIdChanged,
load: me.onStoreLoad,
refresh: me.onStoreRefresh,
pageadd: me.onPageAdd,
pageremove: me.onPageRemove
};
},
suspendChanges: function() {
++this.suspendChange;
},
resumeChanges: function() {
if (this.suspendChange) {
--this.suspendChange;
}
},
selectAll: function(suppressEvent) {
var me = this,
selections = me.store.getRange(),
start = me.getSelection().length;
me.suspendChanges();
me.doSelect(selections, true, suppressEvent);
me.resumeChanges();
if (!suppressEvent && !me.isDestroyed) {
me.maybeFireSelectionChange(me.getSelection().length !== start);
}
},
deselectAll: function(suppressEvent) {
var me = this,
selections = me.getSelection(),
selIndexes = {},
store = me.store,
start = selections.length,
i, l, rec;
for (i = 0 , l = selections.length; i < l; i++) {
rec = selections[i];
selIndexes[rec.id] = store.indexOf(rec);
}
selections = Ext.Array.sort(selections, function(r1, r2) {
var idx1 = selIndexes[r1.id],
idx2 = selIndexes[r2.id];
return idx1 < idx2 ? -1 : 1;
});
me.suspendChanges();
me.doDeselect(selections, suppressEvent);
me.resumeChanges();
if (!suppressEvent && !me.isDestroyed) {
me.maybeFireSelectionChange(me.getSelection().length !== start);
}
},
getSelectionStart: function() {
return this.selectionStart;
},
setSelectionStart: function(selection) {
this.selectionStart = selection;
},
selectWithEvent: function(record, e) {
var me = this,
isSelected = me.isSelected(record),
shift = e.shiftKey;
switch (me.selectionMode) {
case 'MULTI':
me.selectWithEventMulti(record, e, isSelected);
break;
case 'SIMPLE':
me.selectWithEventSimple(record, e, isSelected);
break;
case 'SINGLE':
me.selectWithEventSingle(record, e, isSelected);
break;
}
if (!shift) {
if (me.isSelected(record)) {
me.selectionStart = record;
} else {
me.selectionStart = null;
}
}
},
vetoSelection: function(e) {
if (e.type !== 'keydown' && e.button !== 0) {
if (this.ignoreRightMouseSelection || this.isSelected(e.record)) {
return true;
}
} else {
return e.type === 'mousedown';
}
},
onNavigate: function(e) {
if (!e.record || this.vetoSelection(e.keyEvent)) {
return;
}
this.onBeforeNavigate(e);
var me = this,
keyEvent = e.keyEvent,
ctrlKey = keyEvent.ctrlKey || e.ctrlKey,
recIdx = e.recordIndex,
record = e.record,
lastFocused = e.previousRecord,
isSelected = me.isSelected(record),
from = (me.selectionStart && me.isSelected(e.previousRecord)) ? me.selectionStart : (me.selectionStart = e.previousRecord),
fromIdx = e.previousRecordIndex,
key = keyEvent.getCharCode(),
isSpace = key === keyEvent.SPACE,
direction = key === keyEvent.UP || key === keyEvent.PAGE_UP ? 'up' : (key === keyEvent.DOWN || key === keyEvent.DOWN ? 'down' : null);
switch (me.selectionMode) {
case 'MULTI':
me.setSelectionStart(e.selectionStart);
if (key === keyEvent.A && ctrlKey) {
me.selected.beginUpdate();
me.selectRange(0, me.store.getCount() - 1);
me.selected.endUpdate();
} else if (isSpace) {
if (keyEvent.shiftKey) {
me.selectRange(from, record, ctrlKey);
} else {
if (isSelected) {
if (me.allowDeselect) {
me.doDeselect(record);
}
} else
{
me.doSelect(record, ctrlKey);
}
}
}
else if (keyEvent.shiftKey && from) {
if (direction === 'up' && fromIdx <= recIdx) {
me.deselectRange(lastFocused, recIdx + 1);
} else if (direction === 'down' && fromIdx >= recIdx) {
me.deselectRange(lastFocused, recIdx - 1);
}
else if (from !== record) {
me.selectRange(from, record, ctrlKey);
}
me.lastSelected = record;
} else if (key) {
if (!ctrlKey) {
me.doSelect(record, false);
}
} else {
me.selectWithEvent(record, keyEvent);
};
break;
case 'SIMPLE':
if (key === keyEvent.A && ctrlKey) {
me.selected.beginUpdate();
me.selectRange(0, me.store.getCount() - 1);
me.selected.endUpdate();
} else if (isSelected) {
me.doDeselect(record);
} else {
me.doSelect(record, true);
};
break;
case 'SINGLE':
if (direction) {
if (!ctrlKey) {
me.doSelect(record, false);
}
} else
{
if (isSelected) {
if (me.allowDeselect) {
me.doDeselect(record);
}
} else {
me.doSelect(record);
}
};
}
if (!keyEvent.shiftKey && !me.isDestroyed) {
if (me.isSelected(record)) {
me.selectionStart = record;
}
}
},
selectRange: function(startRow, endRow, keepExisting) {
var me = this,
store = me.store,
selected = me.selected.items,
result, i, len, toSelect, toDeselect, idx, rec;
if (me.isLocked()) {
return;
}
result = me.normalizeRowRange(startRow, endRow);
startRow = result[0];
endRow = result[1];
toSelect = [];
for (i = startRow; i <= endRow; i++) {
if (!me.isSelected(store.getAt(i))) {
toSelect.push(store.getAt(i));
}
}
if (!keepExisting) {
toDeselect = [];
me.suspendChanges();
for (i = 0 , len = selected.length; i < len; ++i) {
rec = selected[i];
idx = store.indexOf(rec);
if (idx < startRow || idx > endRow) {
toDeselect.push(rec);
}
}
for (i = 0 , len = toDeselect.length; i < len; ++i) {
me.doDeselect(toDeselect[i]);
}
me.resumeChanges();
}
if (!me.isDestroyed) {
if (toSelect.length) {
me.doMultiSelect(toSelect, true);
} else if (toDeselect) {
me.maybeFireSelectionChange(toDeselect.length > 0);
}
}
},
deselectRange: function(startRow, endRow) {
var me = this,
store = me.store,
result, i, toDeselect, record;
if (me.isLocked()) {
return;
}
result = me.normalizeRowRange(startRow, endRow);
startRow = result[0];
endRow = result[1];
toDeselect = [];
for (i = startRow; i <= endRow; i++) {
record = store.getAt(i);
if (me.isSelected(record)) {
toDeselect.push(record);
}
}
if (toDeselect.length) {
me.doDeselect(toDeselect);
}
},
normalizeRowRange: function(startRow, endRow) {
var store = this.store,
tmp;
if (!Ext.isNumber(startRow)) {
startRow = store.indexOf(startRow);
}
startRow = Math.max(0, startRow);
if (!Ext.isNumber(endRow)) {
endRow = store.indexOf(endRow);
}
endRow = Math.min(endRow, store.getCount() - 1);
if (startRow > endRow) {
tmp = endRow;
endRow = startRow;
startRow = tmp;
}
return [
startRow,
endRow
];
},
select: function(records, keepExisting, suppressEvent) {
if (Ext.isDefined(records) && !(Ext.isArray(records) && !records.length)) {
this.doSelect(records, keepExisting, suppressEvent);
}
},
deselect: function(records, suppressEvent) {
this.doDeselect(records, suppressEvent);
},
doSelect: function(records, keepExisting, suppressEvent) {
var me = this,
record;
if (me.locked) {
return;
}
if (typeof records === "number") {
record = me.store.getAt(records);
if (!record) {
return;
}
records = [
record
];
}
if (me.selectionMode === "SINGLE" && records) {
record = records.length ? records[0] : records;
me.doSingleSelect(record, suppressEvent);
} else {
me.doMultiSelect(records, keepExisting, suppressEvent);
}
},
doMultiSelect: function(records, keepExisting, suppressEvent) {
var me = this,
selected = me.selected,
change = false,
result, i, len, record, commit;
if (me.locked) {
return;
}
records = !Ext.isArray(records) ? [
records
] : records;
len = records.length;
if (!keepExisting && selected.getCount() > 0) {
result = me.deselectDuringSelect(records, suppressEvent);
if (me.isDestroyed) {
return;
}
if (result[0]) {
me.maybeFireSelectionChange(result[1] > 0 && !suppressEvent);
return;
} else {
change = result[1] > 0;
}
}
commit = function() {
if (!selected.getCount()) {
me.selectionStart = record;
}
selected.add(record);
change = true;
};
for (i = 0; i < len; i++) {
record = records[i];
if (me.isSelected(record)) {
continue;
}
me.onSelectChange(record, true, suppressEvent, commit);
if (me.isDestroyed) {
return;
}
}
me.lastSelected = record;
me.maybeFireSelectionChange(change && !suppressEvent);
},
deselectDuringSelect: function(toSelect, suppressEvent) {
var me = this,
selected = me.selected.getRange(),
len = selected.length,
changed = 0,
failed = false,
item, i;
me.suspendChanges();
me.deselectingDuringSelect = true;
for (i = 0; i < len; ++i) {
item = selected[i];
if (!Ext.Array.contains(toSelect, item)) {
if (me.doDeselect(item, suppressEvent)) {
++changed;
} else {
failed = true;
}
}
if (me.isDestroyed) {
failed = true;
changed = 0;
break;
}
}
me.deselectingDuringSelect = false;
me.resumeChanges();
return [
failed,
changed
];
},
doDeselect: function(records, suppressEvent) {
var me = this,
selected = me.selected,
i = 0,
len, record,
attempted = 0,
accepted = 0,
commit;
if (me.locked || !me.store) {
return false;
}
if (typeof records === "number") {
record = me.store.getAt(records);
if (!record) {
return false;
}
records = [
record
];
} else if (!Ext.isArray(records)) {
records = [
records
];
}
commit = function() {
++accepted;
selected.remove(record);
if (record === me.selectionStart) {
me.selectionStart = null;
}
};
len = records.length;
me.suspendChanges();
for (; i < len; i++) {
record = records[i];
if (me.isSelected(record)) {
if (me.lastSelected === record) {
me.lastSelected = selected.last();
}
++attempted;
me.onSelectChange(record, false, suppressEvent, commit);
if (me.isDestroyed) {
return false;
}
}
}
me.resumeChanges();
me.maybeFireSelectionChange(accepted > 0 && !suppressEvent);
return accepted === attempted;
},
doSingleSelect: function(record, suppressEvent) {
var me = this,
changed = false,
selected = me.selected,
commit;
if (me.locked) {
return;
}
if (me.isSelected(record)) {
return;
}
commit = function() {
if (selected.getCount()) {
me.suspendChanges();
var result = me.deselectDuringSelect([
record
], suppressEvent);
if (me.isDestroyed) {
return;
}
me.resumeChanges();
if (result[0]) {
return false;
}
}
me.lastSelected = record;
if (!selected.getCount()) {
me.selectionStart = record;
}
selected.add(record);
changed = true;
};
me.onSelectChange(record, true, suppressEvent, commit);
if (changed && !me.isDestroyed) {
me.maybeFireSelectionChange(!suppressEvent);
}
},
maybeFireSelectionChange: function(fireEvent) {
var me = this;
if (fireEvent && !me.suspendChange) {
me.fireEvent('selectionchange', me, me.getSelection());
}
},
getLastSelected: function() {
return this.lastSelected;
},
getSelection: function() {
return this.selected.getRange();
},
getSelectionMode: function() {
return this.selectionMode;
},
setSelectionMode: function(selMode) {
selMode = selMode ? selMode.toUpperCase() : 'SINGLE';
this.selectionMode = this.modes[selMode] ? selMode : 'SINGLE';
},
isLocked: function() {
return this.locked;
},
setLocked: function(locked) {
this.locked = !!locked;
},
isRangeSelected: function(startRow, endRow) {
var me = this,
store = me.store,
i, result;
result = me.normalizeRowRange(startRow, endRow);
startRow = result[0];
endRow = result[1];
for (i = startRow; i <= endRow; i++) {
if (!me.isSelected(store.getAt(i))) {
return false;
}
}
return true;
},
isSelected: function(record) {
record = Ext.isNumber(record) ? this.store.getAt(record) : record;
return this.selected.contains(record);
},
hasSelection: function() {
var selected = this.getSelected();
return !!(selected && selected.getCount());
},
refresh: function() {
var me = this,
store = me.store,
toBeSelected = [],
toBeReAdded = [],
oldSelections = me.getSelection(),
len = oldSelections.length,
selected = me.getSelected(),
change, d, storeData, selection, rec, i;
if (!store || !(selected.isCollection || selected.isRows) || !selected.getCount()) {
return;
}
storeData = store.getData();
if (storeData.getSource) {
d = storeData.getSource();
if (d) {
storeData = d;
}
}
me.refreshing = true;
selected.beginUpdate();
me.suspendChanges();
for (i = 0; i < len; i++) {
selection = oldSelections[i];
rec = storeData.get(selection.getId());
if (rec) {
toBeSelected.push(rec);
}
else if (!me.pruneRemoved) {
toBeReAdded.push(selection);
}
if (me.mode === 'SINGLE' && toBeReAdded.length) {
break;
}
}
if (selected.getCount() !== (toBeSelected.length + toBeReAdded.length)) {
change = true;
}
me.clearSelections();
if (toBeSelected.length) {
me.doSelect(toBeSelected, false, true);
}
if (toBeReAdded.length) {
selected.add(toBeReAdded);
if (!me.lastSelected) {
me.lastSelected = toBeReAdded[toBeReAdded.length - 1];
}
}
me.resumeChanges();
if (change) {
selected.endUpdate();
} else {
selected.updating--;
}
me.refreshing = false;
me.maybeFireSelectionChange(change);
},
clearSelections: function() {
var selected = this.getSelected();
if (selected) {
selected.clear();
}
this.lastSelected = null;
},
onStoreAdd: Ext.emptyFn,
onStoreClear: function() {
if (!this.store.isLoading() && this.hasSelection()) {
this.clearSelections();
this.maybeFireSelectionChange(true);
}
},
onStoreRemove: function(store, records, index, isMove) {
var me = this,
toDeselect = records,
i, len, rec, moveMap;
if (me.selectionStart && Ext.Array.contains(records, me.selectionStart)) {
me.selectionStart = null;
}
if (isMove || me.locked || !me.pruneRemoved) {
return;
}
moveMap = store.isMoving(null, true);
if (moveMap) {
toDeselect = null;
for (i = 0 , len = records.length; i < len; ++i) {
rec = records[i];
if (!moveMap[rec.id]) {
(toDeselect || (toDeselect = [])).push(rec);
}
}
}
if (toDeselect) {
me.deselect(toDeselect);
}
},
onPageRemove: function(pageMap, pageNumber, records) {
this.onStoreRemove(this.store, records);
},
onPageAdd: function(pageMap, pageNumber, records) {
var len = records.length,
i, record;
for (i = 0; i < len; i++) {
record = records[i];
if (this.selected.get(record.id)) {
this.selected.replace(record);
}
}
},
getCount: function() {
return this.selected.getCount();
},
onUpdate: Ext.emptyFn,
destroy: function() {
var me = this;
me.clearListeners();
me.clearSelections();
me.bindStore(null);
me.selected = Ext.destroy(me.selected);
me.callParent();
},
onStoreUpdate: Ext.emptyFn,
onIdChanged: function(store, rec, oldId, newId) {
this.selected.updateKey(rec, oldId);
},
onStoreRefresh: function() {
this.updateSelectedInstances(this.selected);
},
updateSelectedInstances: function(selected) {
var me = this,
store = me.getStore(),
lastSelected = me.lastSelected,
removeCount = 0,
prune = me.pruneRemovedOnRefresh(),
items, length, i, selectedRec, rec, lastSelectedChanged;
if (store.isBufferedStore) {
return;
}
items = selected.getRange();
length = items.length;
if (lastSelected) {
me.lastSelected = store.getById(lastSelected.id);
lastSelectedChanged = me.lastSelected !== lastSelected;
}
me.refreshing = true;
for (i = 0; i < length; ++i) {
selectedRec = items[i];
rec = store.getById(selectedRec.id);
if (rec) {
if (rec !== selectedRec) {
selected.replace(rec);
}
}
else if (prune) {
selected.remove(selectedRec);
++removeCount;
}
}
me.refreshing = false;
me.maybeFireSelectionChange(removeCount > 0);
if (lastSelectedChanged) {
me.fireEvent('lastselectedchanged', me, me.getSelection(), me.lastSelected);
}
},
pruneRemovedOnRefresh: function() {
return this.pruneRemoved;
},
onStoreLoad: Ext.emptyFn,
onSelectChange: function(record, isSelected, suppressEvent, commitFn) {
var me = this,
eventName = isSelected ? 'select' : 'deselect';
if ((suppressEvent || me.fireEvent('before' + eventName, me, record)) !== false && commitFn() !== false) {
if (!suppressEvent) {
me.fireEvent(eventName, me, record);
}
}
},
onEditorKey: Ext.emptyFn,
beforeViewRender: function(view) {
Ext.Array.include(this.views || (this.views = []), view);
},
onHeaderClick: Ext.emptyFn,
resolveListenerScope: function(defaultScope) {
var view = this.view,
scope;
if (view) {
scope = view.resolveSatelliteListenerScope(this, defaultScope);
}
return scope || this.callParent([
defaultScope
]);
},
bindComponent: Ext.emptyFn,
privates: {
onBeforeNavigate: Ext.privateFn,
selectWithEventMulti: function(record, e, isSelected) {
var me = this,
shift = e.shiftKey,
ctrl = e.ctrlKey,
start = shift ? (me.getSelectionStart()) : null,
selected = me.getSelection(),
len = selected.length,
toDeselect, i, item;
if (shift && start) {
me.selectRange(start, record, ctrl);
} else if (ctrl && isSelected) {
if (me.allowDeselect) {
me.doDeselect(record, false);
}
} else if (ctrl) {
me.doSelect(record, true, false);
} else if (isSelected && !shift && !ctrl && len > 1) {
if (me.allowDeselect) {
toDeselect = [];
for (i = 0; i < len; ++i) {
item = selected[i];
if (item !== record) {
toDeselect.push(item);
}
}
me.doDeselect(toDeselect);
}
} else if (!isSelected) {
me.doSelect(record, false);
}
},
selectWithEventSimple: function(record, e, isSelected) {
if (isSelected) {
this.doDeselect(record);
} else {
this.doSelect(record, true);
}
},
selectWithEventSingle: function(record, e, isSelected) {
var me = this,
allowDeselect = me.allowDeselect;
if (allowDeselect && !e.ctrlKey) {
allowDeselect = me.toggleOnClick;
}
if (allowDeselect && isSelected) {
me.doDeselect(record);
} else {
me.doSelect(record, false);
}
}
}
});
Ext.define('Ext.selection.DataViewModel', {
extend: 'Ext.selection.Model',
alias: 'selection.dataviewmodel',
requires: [
'Ext.util.KeyNav'
],
deselectOnContainerClick: true,
bindComponent: function(view) {
var me = this,
viewListeners;
if (me.view !== view) {
if (me.view) {
me.navigationModel = null;
Ext.destroy(me.viewListeners, me.navigationListeners);
}
me.view = view;
if (view) {
viewListeners = me.getViewListeners();
viewListeners.scope = me;
viewListeners.destroyable = true;
me.navigationModel = view.getNavigationModel();
me.viewListeners = view.on(viewListeners);
me.navigationListeners = me.navigationModel.on({
navigate: me.onNavigate,
scope: me,
destroyable: true
});
}
}
},
getViewListeners: function() {
var me = this,
eventListeners = {};
eventListeners[me.view.triggerCtEvent] = me.onContainerClick;
return eventListeners;
},
onUpdate: function(record) {
var view = this.view;
if (view && this.isSelected(record)) {
view.onItemSelect(record);
}
},
onContainerClick: function() {
if (this.deselectOnContainerClick) {
this.deselectAll();
}
},
onSelectChange: function(record, isSelected, suppressEvent, commitFn) {
var me = this,
view = me.view,
eventName = isSelected ? 'select' : 'deselect',
recordIndex = me.store.indexOf(record);
if ((suppressEvent || me.fireEvent('before' + eventName, me, record, recordIndex)) !== false && commitFn() !== false) {
if (view) {
if (isSelected) {
view.onItemSelect(record);
} else {
view.onItemDeselect(record);
}
}
if (!suppressEvent) {
me.fireEvent(eventName, me, record, recordIndex);
}
}
},
destroy: function() {
this.bindComponent();
Ext.destroy(this.keyNav);
this.callParent();
}
});
Ext.define('Ext.view.NavigationModel', {
mixins: [
'Ext.util.Observable',
'Ext.mixin.Factoryable'
],
alias: 'view.navigation.default',
focusCls: Ext.baseCSSPrefix + 'view-item-focused',
constructor: function() {
this.mixins.observable.constructor.call(this);
},
bindComponent: function(view) {
if (this.view !== view) {
this.view = view;
this.bindView(view);
}
},
bindView: function(view) {
var me = this,
dataSource = view.dataSource,
listeners;
me.initKeyNav(view);
if (me.dataSource !== dataSource) {
me.dataSource = dataSource;
listeners = me.getStoreListeners();
listeners.destroyable = true;
me.dataSourceListeners = view.dataSource.on(listeners);
}
listeners = me.getViewListeners();
listeners.destroyable = true;
me.viewListeners = me.viewListeners || [];
me.viewListeners.push(view.on(listeners));
},
getStoreListeners: function() {
var me = this;
return {
clear: me.onStoreClear,
remove: me.onStoreRemove,
scope: me
};
},
getViewListeners: function() {
var me = this;
return {
containermousedown: me.onContainerMouseDown,
itemmousedown: me.onItemMouseDown,
itemclick: me.onItemClick,
itemcontextmenu: me.onItemMouseDown,
scope: me
};
},
initKeyNav: function(view) {
var me = this;
me.keyNav = new Ext.util.KeyNav({
target: view,
ignoreInputFields: true,
eventName: 'itemkeydown',
defaultEventAction: 'stopEvent',
processEvent: me.processViewEvent,
up: me.onKeyUp,
down: me.onKeyDown,
right: me.onKeyRight,
left: me.onKeyLeft,
pageDown: me.onKeyPageDown,
pageUp: me.onKeyPageUp,
home: me.onKeyHome,
end: me.onKeyEnd,
tab: me.onKeyTab,
space: me.onKeySpace,
enter: me.onKeyEnter,
A: {
ctrl: true,
handler: me.onSelectAllKeyPress
},
scope: me
});
},
processViewEvent: function(view, record, node, index, event) {
return event;
},
addKeyBindings: function(binding) {
this.keyNav.addBindings(binding);
},
enable: function() {
this.keyNav.enable();
this.disabled = false;
},
disable: function() {
this.keyNav.disable();
this.disabled = true;
},
onContainerMouseDown: function(view, mousedownEvent) {
if (this.view.containsFocus) {
mousedownEvent.preventDefault();
}
},
onItemMouseDown: function(view, record, item, index, mousedownEvent) {
var parentEvent = mousedownEvent.parentEvent;
if (!parentEvent || parentEvent.type !== 'touchstart') {
this.setPosition(index);
}
},
onItemClick: function(view, record, item, index, clickEvent) {
if (this.record === record) {
this.fireNavigateEvent(clickEvent);
} else {
this.setPosition(index, clickEvent);
}
},
beforeViewRefresh: function() {
this.focusRestorePosition = this.view.dataSource.isBufferedStore ? this.recordIndex : this.record;
},
onViewRefresh: function() {
if (this.focusRestorePosition != null) {
this.setPosition(this.focusRestorePosition);
this.focusRestorePosition = null;
}
},
onStoreClear: function() {
this.setPosition();
},
onStoreRemove: function() {
this.setPosition(this.getRecord(), null, null, true);
},
setPosition: function(recordIndex, keyEvent, suppressEvent, preventNavigation) {
var me = this,
view = me.view,
selModel = view.getSelectionModel(),
dataSource = view.dataSource,
newRecord, newRecordIndex;
if (recordIndex == null || !view.all.getCount()) {
me.record = me.recordIndex = null;
} else {
if (typeof recordIndex === 'number') {
newRecordIndex = Math.max(Math.min(recordIndex, dataSource.getCount() - 1), 0);
newRecord = dataSource.getAt(recordIndex);
}
else if (recordIndex.isEntity) {
newRecord = dataSource.getById(recordIndex.id);
newRecordIndex = dataSource.indexOf(newRecord);
if (newRecordIndex === -1) {
newRecord = dataSource.getAt(0);
newRecordIndex = 0;
}
}
else if (recordIndex.tagName) {
newRecord = view.getRecord(recordIndex);
newRecordIndex = dataSource.indexOf(newRecord);
} else {
newRecord = newRecordIndex = null;
}
}
if (newRecord === me.record) {
me.recordIndex = newRecordIndex;
return me.focusPosition(newRecordIndex);
}
if (me.item) {
me.item.removeCls(me.focusCls);
}
me.previousRecordIndex = me.recordIndex;
me.previousRecord = me.record;
me.previousItem = me.item;
me.recordIndex = newRecordIndex;
me.record = newRecord;
preventNavigation = preventNavigation || me.record === me.lastFocused;
if (newRecord) {
me.focusPosition(me.recordIndex);
} else {
me.item = null;
}
if (!suppressEvent) {
selModel.fireEvent('focuschange', selModel, me.previousRecord, me.record);
}
if (!preventNavigation && keyEvent) {
me.fireNavigateEvent(keyEvent);
}
},
focusPosition: function(recordIndex) {
var me = this;
if (recordIndex != null && recordIndex !== -1) {
if (recordIndex.isEntity) {
recordIndex = me.view.dataSource.indexOf(recordIndex);
}
me.item = me.view.all.item(recordIndex);
if (me.item) {
me.lastFocused = me.record;
me.lastFocusedIndex = me.recordIndex;
me.focusItem(me.item);
} else {
me.record = null;
}
} else {
me.item = null;
}
},
focusItem: function(item) {
item.addCls(this.focusCls);
item.focus();
},
getPosition: function() {
return this.record ? this.recordIndex : null;
},
getRecordIndex: function() {
return this.recordIndex;
},
getItem: function() {
return this.item;
},
getRecord: function() {
return this.record;
},
getLastFocused: function() {
if (this.view.dataSource.indexOf(this.lastFocused) === -1) {
return null;
}
return this.lastFocused;
},
onKeyUp: function(keyEvent) {
var newPosition = this.recordIndex - 1;
if (newPosition < 0) {
newPosition = this.view.all.getCount() - 1;
}
this.setPosition(newPosition, keyEvent);
},
onKeyDown: function(keyEvent) {
var newPosition = this.recordIndex + 1;
if (newPosition > this.view.all.getCount() - 1) {
newPosition = 0;
}
this.setPosition(newPosition, keyEvent);
},
onKeyRight: function(keyEvent) {
var newPosition = this.recordIndex + 1;
if (newPosition > this.view.all.getCount() - 1) {
newPosition = 0;
}
this.setPosition(newPosition, keyEvent);
},
onKeyLeft: function(keyEvent) {
var newPosition = this.recordIndex - 1;
if (newPosition < 0) {
newPosition = this.view.all.getCount() - 1;
}
this.setPosition(newPosition, keyEvent);
},
onKeyPageDown: Ext.emptyFn,
onKeyPageUp: Ext.emptyFn,
onKeyHome: function(keyEvent) {
this.setPosition(0, keyEvent);
},
onKeyEnd: function(keyEvent) {
this.setPosition(this.view.all.getCount() - 1, keyEvent);
},
onKeyTab: function(keyEvent) {
var view = this.view;
view.toggleChildrenTabbability(false);
return true;
},
onKeySpace: function(keyEvent) {
this.fireNavigateEvent(keyEvent);
},
onKeyEnter: function(keyEvent) {
keyEvent.stopEvent();
keyEvent.view.fireEvent('itemclick', keyEvent.view, keyEvent.record, keyEvent.item, keyEvent.recordIndex, keyEvent);
},
onSelectAllKeyPress: function(keyEvent) {
this.fireNavigateEvent(keyEvent);
},
fireNavigateEvent: function(keyEvent) {
var me = this;
me.fireEvent('navigate', {
navigationModel: me,
keyEvent: keyEvent,
previousRecordIndex: me.previousRecordIndex,
previousRecord: me.previousRecord,
previousItem: me.previousItem,
recordIndex: me.recordIndex,
record: me.record,
item: me.item
});
},
destroy: function() {
var me = this;
Ext.destroy(me.dataSourceListeners, me.viewListeners, me.keyNav);
me.keyNav = me.dataSourceListeners = me.viewListeners = me.dataSource = null;
me.callParent();
}
});
Ext.define('Ext.view.AbstractView', {
extend: 'Ext.Component',
requires: [
'Ext.LoadMask',
'Ext.CompositeElementLite',
'Ext.selection.DataViewModel',
'Ext.view.NavigationModel'
],
mixins: [
'Ext.util.StoreHolder'
],
inheritableStatics: {
getRecord: function(node) {
return this.getBoundView(node).getRecord(node);
},
getBoundView: function(node) {
return Ext.getCmp(node.getAttribute('data-boundView'));
}
},
defaultBindProperty: 'store',
renderBuffer: document.createElement('div'),
statics: {
updateDelay: 200,
queueRecordChange: function(view, store, record, operation, modifiedFieldNames) {
var me = this,
changeQueue = me.changeQueue || (me.changeQueue = {}),
recId = record.internalId,
recChange, updated, len, i, fieldName, value, checkForReversion;
recChange = changeQueue[recId] || (changeQueue[recId] = {
operation: operation,
record: record,
data: {},
views: []
});
updated = recChange.data;
Ext.Array.include(recChange.views, view);
if (modifiedFieldNames && (len = modifiedFieldNames.length)) {
for (i = 0; i < len; i++) {
fieldName = modifiedFieldNames[i];
value = record.data[fieldName];
if (updated.hasOwnProperty(fieldName)) {
if (record.isEqual(updated[fieldName], value)) {
delete updated[fieldName];
checkForReversion = true;
}
} else
{
updated[fieldName] = value;
}
}
if (checkForReversion && !Ext.Object.getKeys(updated).length) {
delete changeQueue[recId];
}
} else
{
Ext.apply(updated, record.data);
}
if (!me.flushQueueTask) {
me.flushQueueTask = Ext.util.TaskManager.newTask({
run: Ext.global.requestAnimationFrame ? Ext.Function.createAnimationFrame(me.onFlushTick, me) : Ext.Function.bind(me.onFlushTick, me),
interval: Ext.view.AbstractView.updateDelay,
repeat: 1
});
}
me.flushQueueTask.start();
},
onFlushTick: function() {
Ext.AnimationQueue.start(this.flushChangeQueue, this);
},
flushChangeQueue: function() {
var me = this,
dirtyViews, len, changeQueue, recChange, recId, i, view;
if (Ext.isScrolling) {
me.flushQueueTask.start();
return;
}
changeQueue = me.changeQueue;
this.changeQueue = {};
for (recId in changeQueue) {
recChange = changeQueue[recId];
dirtyViews = recChange.views;
len = dirtyViews.length;
for (i = 0; i < len; i++) {
view = dirtyViews[i];
if (!view.isDestroyed) {
view.handleUpdate(view.dataSource, recChange.record, recChange.operation, Ext.Object.getKeys(recChange.data));
}
}
}
Ext.AnimationQueue.stop(me.flushChangeQueue, me);
}
},
config: {
selection: null,
store: 'ext-empty-store',
navigationModel: {
type: 'default'
},
selectionModel: {
type: 'dataviewmodel'
}
},
publishes: [
'selection'
],
twoWayBindable: [
'selection'
],
throttledUpdate: false,
deferInitialRefresh: false,
itemCls: Ext.baseCSSPrefix + 'dataview-item',
loadingText: 'Loading...',
loadMask: true,
loadingUseMsg: true,
selectedItemCls: Ext.baseCSSPrefix + 'item-selected',
emptyText: "",
deferEmptyText: true,
trackOver: false,
blockRefresh: false,
preserveScrollOnRefresh: false,
ariaRole: 'listbox',
itemAriaRole: 'option',
last: false,
focusable: true,
tabIndex: 0,
triggerEvent: 'itemclick',
triggerCtEvent: 'containerclick',
refreshNeeded: true,
updateSuspendCounter: 0,
addCmpEvents: Ext.emptyFn,
constructor: function(config) {
if (config && config.selModel) {
config.selectionModel = config.selModel;
}
this.callParent([
config
]);
},
initComponent: function() {
var me = this,
isDef = Ext.isDefined,
itemTpl = me.itemTpl,
memberFn = {};
if (itemTpl) {
if (Ext.isArray(itemTpl)) {
itemTpl = itemTpl.join('');
} else if (Ext.isObject(itemTpl)) {
memberFn = Ext.apply(memberFn, itemTpl.initialConfig);
itemTpl = itemTpl.html;
}
if (!me.itemSelector) {
me.itemSelector = '.' + me.itemCls;
}
itemTpl = Ext.String.format('<tpl for="."><div class="{0}" role="{2}">{1}</div></tpl>', me.itemCls, itemTpl, me.itemAriaRole);
me.tpl = new Ext.XTemplate(itemTpl, memberFn);
}
if (!isDef(me.tpl) || !isDef(me.itemSelector)) {
Ext.Error.raise({
sourceClass: 'Ext.view.View',
tpl: me.tpl,
itemSelector: me.itemSelector,
msg: "DataView requires both tpl and itemSelector configurations to be defined."
});
}
me.callParent();
me.tpl = me.getTpl('tpl');
if (isDef(me.overCls) || isDef(me.overClass)) {
if (Ext.isDefined(Ext.global.console)) {
Ext.global.console.warn('Ext.view.View: Using the deprecated overCls or overClass configuration. Use overItemCls instead.');
}
me.overItemCls = me.overCls || me.overClass;
delete me.overCls;
delete me.overClass;
}
if (isDef(me.selectedCls) || isDef(me.selectedClass)) {
if (Ext.isDefined(Ext.global.console)) {
Ext.global.console.warn('Ext.view.View: Using the deprecated selectedCls or selectedClass configuration. Use selectedItemCls instead.');
}
me.selectedItemCls = me.selectedCls || me.selectedClass;
delete me.selectedCls;
delete me.selectedClass;
}
if (me.overItemCls) {
me.trackOver = true;
}
me.addCmpEvents();
me.store = Ext.data.StoreManager.lookup(me.store || 'ext-empty-store');
if (!me.dataSource) {
me.dataSource = me.store;
}
me.getNavigationModel().bindComponent(this);
me.bindStore(me.dataSource, true, 'dataSource');
if (!me.all) {
me.all = new Ext.CompositeElementLite();
}
me.scrollState = {
top: 0,
left: 0
};
me.savedTabIndexAttribute = 'data-savedtabindex-' + me.id;
},
getElConfig: function() {
var result = this.mixins.renderable.getElConfig.call(this);
if (this.focusable) {
result.tabIndex = 0;
}
return result;
},
onRender: function() {
var mask = this.loadMask;
this.callParent(arguments);
if (mask) {
this.createMask(mask);
}
},
beforeLayout: function() {
var me = this;
me.callParent(arguments);
if (me.refreshNeeded && !me.pendingRefresh) {
if (me.refreshCounter) {
me.refresh();
} else {
me.doFirstRefresh(me.dataSource);
}
}
},
onMaskBeforeShow: function() {
var me = this,
loadingHeight = me.loadingHeight;
if (loadingHeight && loadingHeight > me.getHeight()) {
me.hasLoadingHeight = true;
me.oldMinHeight = me.minHeight;
me.minHeight = loadingHeight;
me.updateLayout();
}
},
onMaskHide: function() {
var me = this;
if (!me.destroying && me.hasLoadingHeight) {
me.minHeight = me.oldMinHeight;
me.updateLayout();
delete me.hasLoadingHeight;
}
},
beforeRender: function() {
this.callParent(arguments);
this.getSelectionModel().beforeViewRender(this);
},
afterRender: function() {
this.callParent(arguments);
if (this.focusable) {
this.focusEl = this.el;
}
},
getRefItems: function() {
var mask = this.loadMask,
result = [];
if (mask && mask.isComponent) {
result.push(mask);
}
return result;
},
getSelection: function() {
return this.getSelectionModel().getSelection();
},
updateSelection: function(selection) {
var me = this,
sm;
if (!me.ignoreNextSelection) {
me.ignoreNextSelection = true;
sm = me.getSelectionModel();
if (selection) {
sm.select(selection);
} else {
sm.deselectAll();
}
me.ignoreNextSelection = false;
}
},
updateBindSelection: function(selModel, selection) {
var me = this,
selected = null;
if (!me.ignoreNextSelection) {
me.ignoreNextSelection = true;
if (selection.length) {
selected = selModel.getLastSelected();
me.hasHadSelection = true;
}
if (me.hasHadSelection) {
me.setSelection(selected);
}
me.ignoreNextSelection = false;
}
},
applySelectionModel: function(selModel, oldSelModel) {
var me = this,
mode;
if (oldSelModel) {
oldSelModel.un({
scope: me,
lastselectedchanged: me.updateBindSelection,
selectionchange: me.updateBindSelection
});
Ext.destroy(me.selModelRelayer);
selModel = Ext.Factory.selection(selModel);
} else
{
if (selModel && selModel.isSelectionModel) {
selModel.locked = me.disableSelection;
} else {
if (me.simpleSelect) {
mode = 'SIMPLE';
} else if (me.multiSelect) {
mode = 'MULTI';
} else {
mode = 'SINGLE';
}
if (typeof selModel === 'string') {
selModel = {
type: selModel
};
}
selModel = Ext.Factory.selection(Ext.apply({
allowDeselect: me.allowDeselect || me.multiSelect,
mode: mode,
locked: me.disableSelection
}, selModel));
}
}
me.selModelRelayer = me.relayEvents(selModel, [
'selectionchange',
'beforeselect',
'beforedeselect',
'select',
'deselect',
'focuschange'
]);
selModel.on({
scope: me,
lastselectedchanged: me.updateBindSelection,
selectionchange: me.updateBindSelection
});
return selModel;
},
updateSelectionModel: function(selectionModel) {
this.selModel = selectionModel;
},
applyNavigationModel: function(navigationModel) {
return Ext.Factory.viewNavigation(navigationModel);
},
onFocusEnter: function(e) {
var me = this,
navigationModel = me.getNavigationModel(),
focusPosition;
if (!me.itemFocused && me.all.getCount()) {
focusPosition = navigationModel.getLastFocused();
navigationModel.setPosition(focusPosition || 0, e.event, null, !focusPosition);
me.itemFocused = navigationModel.getPosition() != null;
}
if (me.itemFocused) {
this.el.dom.setAttribute('tabindex', '-1');
}
},
onFocusLeave: function(e) {
var me = this;
if (me.itemFocused) {
me.getNavigationModel().setPosition(null, e.event, null, true);
me.itemFocused = false;
me.el.dom.setAttribute('tabindex', 0);
}
},
onRemoved: function(isDestroying) {
this.callParent([
isDestroying
]);
this.onFocusLeave({});
},
refresh: function() {
var me = this,
items = me.all,
prevItemCount = items.getCount(),
refreshCounter = me.refreshCounter,
targetEl, overflowEl, dom, records,
selModel = me.getSelectionModel(),
navModel = me.getNavigationModel(),
preserveScroll = refreshCounter && items.getCount() && me.preserveScrollOnRefresh && !me.bufferedRenderer,
scrollPos;
if (!me.rendered || me.isDestroyed || me.preventRefresh) {
return;
}
if (!me.hasListeners.beforerefresh || me.fireEvent('beforerefresh', me) !== false) {
me.refreshing = true;
navModel.beforeViewRefresh(me);
targetEl = me.getTargetEl();
records = me.getViewRange();
dom = targetEl.dom;
if (preserveScroll) {
overflowEl = me.getOverflowEl();
scrollPos = overflowEl.getScroll();
}
if (refreshCounter) {
me.clearViewEl();
me.refreshCounter++;
} else {
me.refreshCounter = 1;
}
me.tpl.append(targetEl, me.collectData(records, items.startIndex || 0));
if (records.length < 1) {
me.addEmptyText();
items.clear();
} else {
me.collectNodes(targetEl.dom);
me.updateIndexes(0);
}
navModel.onViewRefresh();
if (me.refreshSelmodelOnRefresh !== false) {
selModel.refresh();
}
me.refreshNeeded = false;
me.refreshSize(items.getCount() !== prevItemCount);
me.fireEvent('refresh', me, records);
if (preserveScroll) {
overflowEl.setScrollLeft(scrollPos.left);
overflowEl.setScrollTop(scrollPos.top);
}
if (!me.viewReady) {
me.viewReady = true;
me.fireEvent('viewready', me);
}
me.refreshing = false;
me.refreshScroll();
}
},
addEmptyText: function() {
var me = this;
if (me.emptyText && !me.getStore().isLoading() && (!me.deferEmptyText || me.refreshCounter > 1)) {
me.emptyEl = Ext.core.DomHelper.insertHtml('beforeEnd', me.getTargetEl().dom, me.emptyText);
}
},
toggleChildrenTabbability: function(enableTabbing) {
var attr = this.savedTabIndexAttribute,
focusEl = this.getTargetEl();
if (enableTabbing) {
focusEl.restoreChildrenTabbableState(attr);
} else {
focusEl.saveChildrenTabbableState(attr);
}
},
collectNodes: function(targetEl) {
var all = this.all;
all.fill(Ext.fly(targetEl).query(this.getItemSelector()), all.startIndex || 0);
if (this.focusable) {
all.set({
tabindex: '-1'
});
}
},
getViewRange: function() {
return this.dataSource.getRange();
},
refreshSize: function(forceLayout) {
var me = this,
sizeModel = me.getSizeModel(),
scroller = me.getScrollable();
if (sizeModel.height.shrinkWrap || sizeModel.width.shrinkWrap || forceLayout) {
me.updateLayout();
}
else if (me.touchScroll && !me.bufferedRenderer) {
if (scroller) {
scroller.refresh();
} else {
me.on({
boxready: me.refreshScroll,
scope: me,
single: true
});
}
}
},
onResize: function() {
var me = this,
scroller = me.getScrollable();
if (scroller && !me._hasScrollListener) {
scroller.on({
scroll: me.onViewScroll,
scope: me,
onFrame: !!Ext.global.requestAnimationFrame
});
me._hasScrollListener = true;
}
this.callParent(arguments);
},
clearViewEl: function() {
var me = this,
targetEl = me.getTargetEl(),
nodeContainerIsTarget = me.getNodeContainer() === targetEl;
me.clearEmptyEl();
me.all.clear(!nodeContainerIsTarget);
if (nodeContainerIsTarget) {
targetEl.dom.innerHTML = '';
}
},
clearEmptyEl: function() {
var emptyEl = this.emptyEl;
if (emptyEl) {
Ext.removeNode(emptyEl);
}
this.emptyEl = null;
},
onViewScroll: function(scroller, x, y) {
this.fireEvent('scroll', this, x, y);
},
saveScrollState: function() {
var me = this,
state = me.scrollState;
if (me.rendered) {
state.left = me.getScrollX();
state.top = me.getScrollY();
}
},
restoreScrollState: function() {
var me = this,
state = me.scrollState;
if (me.rendered) {
me.setScrollX(state.left);
me.setScrollY(state.top);
}
},
prepareData: function(data, index, record) {
var associatedData, attr, hasCopied;
if (record) {
associatedData = record.getAssociatedData();
for (attr in associatedData) {
if (associatedData.hasOwnProperty(attr)) {
if (!hasCopied) {
data = Ext.Object.chain(data);
hasCopied = true;
}
data[attr] = associatedData[attr];
}
}
}
return data;
},
collectData: function(records, startIndex) {
var data = [],
i = 0,
len = records.length,
record;
for (; i < len; i++) {
record = records[i];
data[i] = this.prepareData(record.data, startIndex + i, record);
}
return data;
},
bufferRender: function(records, index) {
var me = this,
div = me.renderBuffer,
result = document.createDocumentFragment(),
nodes, len, i;
me.tpl.overwrite(div, me.collectData(records, index));
nodes = Ext.fly(div).query(me.getItemSelector());
for (i = 0 , len = nodes.length; i < len; i++) {
result.appendChild(nodes[i]);
}
return {
fragment: result,
children: nodes
};
},
nodeContainerSelector: null,
getNodeContainer: function() {
var target = this.getTargetEl(),
selector = this.nodeContainerSelector;
return selector ? target.down(selector, true) : target;
},
getNodeContainerSelector: function() {
return this.nodeContainerSelector;
},
onUpdate: function(store, record, operation, modifiedFieldNames, details) {
var me = this,
isFiltered = details && details.filtered;
if (!isFiltered && me.getNode(record)) {
if (me.throttledUpdate) {
me.statics().queueRecordChange(me, store, record, operation, modifiedFieldNames);
} else {
me.handleUpdate.apply(me, arguments);
}
}
},
handleUpdate: function(store, record) {
var me = this,
index, node,
selModel = me.getSelectionModel();
if (me.viewReady) {
index = me.dataSource.indexOf(record);
if (index > -1) {
if (me.getNode(record)) {
node = me.bufferRender([
record
], index).children[0];
me.all.replaceElement(index, node, true);
me.updateIndexes(index, index);
selModel.onUpdate(record);
me.refreshSizePending = true;
if (selModel.isSelected(record)) {
me.onItemSelect(record);
}
if (me.hasListeners.itemupdate) {
me.fireEvent('itemupdate', record, index, node);
}
return node;
}
}
}
},
onReplace: function(store, startIndex, oldRecords, newRecords) {
var me = this,
endIndex,
all = me.all,
selModel = me.getSelectionModel(),
result, item, i, j, fragment, children;
if (me.rendered) {
result = me.bufferRender(newRecords, startIndex, true);
fragment = result.fragment;
children = result.children;
item = all.item(startIndex);
if (item) {
all.item(startIndex).insertSibling(fragment, 'before', true);
} else {
me.appendNodes(fragment);
}
all.insert(startIndex, children);
startIndex += newRecords.length;
endIndex = startIndex + oldRecords.length - 1;
all.removeRange(startIndex, endIndex, true);
if (me.refreshSelmodelOnRefresh !== false) {
selModel.refresh();
}
me.updateIndexes(startIndex);
if (me.hasListeners.itemremove) {
for (i = oldRecords.length , j = endIndex; i >= 0; --i , --j) {
me.fireEvent('itemremove', oldRecords[i], j, me);
}
}
if (me.hasListeners.itemadd) {
me.fireEvent('itemadd', newRecords, startIndex, children);
}
me.refreshSize();
}
},
onAdd: function(store, records, index) {
var me = this,
nodes,
selModel = me.getSelectionModel();
if (me.rendered) {
if (me.all.getCount() === 0) {
me.refresh();
nodes = me.all.slice();
} else {
nodes = me.doAdd(records, index);
if (me.refreshSelmodelOnRefresh !== false) {
selModel.refresh();
}
me.updateIndexes(index);
me.refreshSizePending = true;
}
if (me.hasListeners.itemadd) {
me.fireEvent('itemadd', records, index, nodes);
}
}
},
appendNodes: function(nodes) {
var all = this.all,
count = all.getCount();
if (this.nodeContainerSelector) {
this.getNodeContainer().appendChild(nodes);
} else {
all.item(count - 1).insertSibling(nodes, 'after');
}
},
doAdd: function(records, index) {
var me = this,
result = me.bufferRender(records, index, true),
fragment = result.fragment,
children = result.children,
all = me.all,
count = all.getCount(),
firstRowIndex = all.startIndex || 0,
lastRowIndex = all.endIndex || count - 1;
if (count === 0 || index > lastRowIndex) {
me.appendNodes(fragment);
} else if (index <= firstRowIndex) {
all.item(firstRowIndex).insertSibling(fragment, 'before', true);
} else {
all.item(index).insertSibling(children, 'before', true);
}
all.insert(index, children);
return children;
},
onRemove: function(ds, records, index) {
var me = this,
rows = me.all,
fireItemRemove = me.hasListeners.itemremove,
currIdx, i, record, nodes, node;
if (rows.getCount()) {
if (me.dataSource.getCount() === 0) {
if (fireItemRemove) {
me.fireEvent('itemremove', records, index, me.getNodes(index, index + records.length - 1));
}
me.refresh();
} else {
if (fireItemRemove) {
nodes = [];
}
for (i = records.length - 1; i >= 0; --i) {
record = records[i];
currIdx = index + i;
if (nodes) {
node = rows.item(currIdx);
nodes[i] = node ? node.dom : undefined;
}
if (rows.item(currIdx)) {
me.doRemove(record, currIdx);
}
}
if (fireItemRemove) {
me.fireEvent('itemremove', records, index, nodes, me);
}
me.updateIndexes(index);
}
me.refreshSizePending = true;
}
},
doRemove: function(record, index) {
this.all.removeElement(index, true);
},
refreshNode: function(record) {
if (Ext.isNumber(record)) {
record = this.store.getAt(record);
}
this.onUpdate(this.dataSource, record);
},
updateIndexes: function(startIndex, endIndex) {
var nodes = this.all.elements,
node,
records = this.getViewRange(),
i,
myId = this.id;
startIndex = startIndex || 0;
endIndex = endIndex || ((endIndex === 0) ? 0 : (nodes.length - 1));
for (i = startIndex; i <= endIndex; i++) {
node = nodes[i];
node.setAttribute('data-recordIndex', i);
node.setAttribute('data-recordId', records[i].internalId);
node.setAttribute('data-boundView', myId);
}
},
bindStore: function(store, initial, propName) {
var me = this,
selModel = me.getSelectionModel();
selModel.preventRefresh = true;
selModel.bindStore(store);
selModel.bindComponent(store ? me : null);
selModel.preventRefresh = false;
me.mixins.storeholder.bindStore.apply(me, arguments);
if (store && me.componentLayoutCounter && !me.preventRefresh) {
me.doFirstRefresh(store, !initial);
}
},
doFirstRefresh: function(store, noDefer) {
var me = this;
if (me.deferInitialRefresh && !noDefer) {
Ext.defer(me.doFirstRefresh, 1, me, [
store,
true
]);
} else {
if (store && !store.isLoading()) {
me.refresh();
}
}
},
onUnbindStore: function(store, initial, propertyName) {
if (propertyName === 'store') {
this.setMaskBind(null);
this.getSelectionModel().bindStore(null);
}
},
onBindStore: function(store, initial, propName) {
var me = this;
me.setMaskBind(store);
if (!initial && propName === 'store') {
me.preventRefresh = true;
me.store = store;
me.bindStore(store, false, 'dataSource');
me.preventRefresh = false;
}
},
setMaskBind: function(store) {
var mask = this.loadMask;
if (this.rendered && mask && store && !mask.bindStore) {
mask = this.createMask();
}
if (mask && mask.bindStore) {
mask.bindStore(store);
}
},
getStoreListeners: function() {
var me = this;
return {
refresh: me.onDataRefresh,
replace: me.onReplace,
add: me.onAdd,
remove: me.onRemove,
update: me.onUpdate,
clear: me.refresh,
beginupdate: me.onBeginUpdate,
endupdate: me.onEndUpdate
};
},
onBeginUpdate: function() {
++this.updateSuspendCounter;
Ext.suspendLayouts();
},
onEndUpdate: function() {
var me = this;
if (me.updateSuspendCounter) {
--me.updateSuspendCounter;
}
Ext.resumeLayouts(true);
if (me.refreshSizePending) {
me.refreshSize(true);
me.refreshSizePending = false;
}
},
onDataRefresh: function() {
this.refreshView();
},
refreshView: function() {
var me = this,
blocked = me.blockRefresh || !me.rendered || me.up('[collapsed],[isCollapsingOrExpanding],[hidden]');
if (blocked) {
me.refreshNeeded = true;
} else {
if (me.bufferedRenderer && me.all.getCount()) {
me.bufferedRenderer.refreshView();
} else {
me.refresh();
}
}
},
findItemByChild: function(node) {
return Ext.fly(node).findParent(this.getItemSelector(), this.getTargetEl());
},
findTargetByEvent: function(e) {
return e.getTarget(this.getItemSelector(), this.getTargetEl());
},
getSelectedNodes: function() {
var nodes = [],
records = this.getSelectionModel().getSelection(),
ln = records.length,
i = 0;
for (; i < ln; i++) {
nodes.push(this.getNode(records[i]));
}
return nodes;
},
getRecords: function(nodes) {
var records = [],
i = 0,
len = nodes.length,
data = this.dataSource.data;
for (; i < len; i++) {
records[records.length] = data.getByKey(nodes[i].getAttribute('data-recordId'));
}
return records;
},
getRecord: function(node) {
return this.dataSource.getByInternalId(Ext.getDom(node).getAttribute('data-recordId'));
},
isSelected: function(node) {
var r = this.getRecord(node);
return this.getSelectionModel().isSelected(r);
},
select: function(records, keepExisting, suppressEvent) {
this.getSelectionModel().select(records, keepExisting, suppressEvent);
},
deselect: function(records, suppressEvent) {
this.getSelectionModel().deselect(records, suppressEvent);
},
getNode: function(nodeInfo) {
var me = this,
out;
if (me.rendered && (nodeInfo || nodeInfo === 0)) {
if (Ext.isString(nodeInfo)) {
out = document.getElementById(nodeInfo);
} else if (nodeInfo.isModel) {
out = me.getNodeByRecord(nodeInfo);
} else if (Ext.isNumber(nodeInfo)) {
out = me.all.elements[nodeInfo];
} else {
if (nodeInfo.target) {
nodeInfo = nodeInfo.target;
}
out = Ext.fly(nodeInfo).findParent(me.itemSelector, me.getTargetEl());
}
}
return out || null;
},
getNodeByRecord: function(record) {
var index = this.store.indexOf(record);
return this.all.elements[index] || null;
},
getNodes: function(start, end) {
var all = this.all;
if (end !== undefined) {
end++;
}
return all.slice(start, end);
},
indexOf: function(node) {
node = this.getNode(node);
if (!node && node !== 0) {
return -1;
}
if (node.getAttribute('data-recordIndex')) {
return Number(node.getAttribute('data-recordIndex'));
}
return this.all.indexOf(node);
},
onDestroy: function() {
var me = this,
count = me.updateSuspendCounter;
me.all.clear();
me.emptyEl = null;
me.callParent();
me.bindStore(null);
Ext.destroy(me.navigationModel, me.selectionModel);
while (count--) {
Ext.resumeLayouts(true);
}
},
onItemSelect: function(record) {
var node = this.getNode(record);
if (node) {
Ext.fly(node).addCls(this.selectedItemCls);
}
},
onItemDeselect: function(record) {
var node = this.getNode(record);
if (node) {
Ext.fly(node).removeCls(this.selectedItemCls);
}
},
getItemSelector: function() {
return this.itemSelector;
},
addItemCls: function(itemInfo, cls) {
var item = this.getNode(itemInfo);
if (item) {
Ext.fly(item).addCls(cls);
}
},
removeItemCls: function(itemInfo, cls) {
var item = this.getNode(itemInfo);
if (item) {
Ext.fly(item).removeCls(cls);
}
},
updateStore: function(store) {
if (!this.isConfiguring) {
delete this.store;
this.bindStore(store);
}
},
privates: {
createMask: function(mask) {
var me = this,
maskStore = me.getStore(),
cfg;
if (maskStore && !maskStore.isEmptyStore && !maskStore.loadsSynchronously()) {
cfg = {
target: me,
msg: me.loadingText,
useMsg: me.loadingUseMsg,
store: maskStore
};
if (me.loadingCls) {
cfg.msgCls = me.loadingCls;
}
if (Ext.isObject(mask)) {
cfg = Ext.apply(cfg, mask);
}
me.loadMask = new Ext.LoadMask(cfg);
me.loadMask.on({
scope: me,
beforeshow: me.onMaskBeforeShow,
hide: me.onMaskHide
});
}
return me.loadMask;
},
getFocusEl: function() {
return this.el;
},
getOverflowEl: function() {
return Ext.Component.prototype.getTargetEl.call(this);
},
getTargetEl: function() {
return this.touchScroll ? this.getScrollerEl() : this.callParent();
}
}
}, function() {
Ext.deprecate('extjs', '4.0', function() {
Ext.view.AbstractView.override({
getSelectionCount: function() {
if (Ext.global.console) {
Ext.global.console.warn("DataView: getSelectionCount will be removed, please interact with the Ext.selection.DataViewModel");
}
return this.selModel.getSelection().length;
},
getSelectedRecords: function() {
if (Ext.global.console) {
Ext.global.console.warn("DataView: getSelectedRecords will be removed, please interact with the Ext.selection.DataViewModel");
}
return this.selModel.getSelection();
},
select: function(records, keepExisting, supressEvents) {
if (Ext.global.console) {
Ext.global.console.warn("DataView: select will be removed, please access select through a DataView's SelectionModel, ie: view.getSelectionModel().select()");
}
var sm = this.getSelectionModel();
return sm.select.apply(sm, arguments);
},
clearSelections: function() {
if (Ext.global.console) {
Ext.global.console.warn("DataView: clearSelections will be removed, please access deselectAll through DataView's SelectionModel, ie: view.getSelectionModel().deselectAll()");
}
var sm = this.getSelectionModel();
return sm.deselectAll();
}
});
});
});
Ext.define('Ext.view.View', {
extend: 'Ext.view.AbstractView',
alternateClassName: 'Ext.DataView',
alias: 'widget.dataview',
inputTagRe: /^textarea$|^input$/i,
keyEventRe: /^key/,
inheritableStatics: {
EventMap: {
longpress: 'LongPress',
mousedown: 'MouseDown',
mouseup: 'MouseUp',
click: 'Click',
dblclick: 'DblClick',
contextmenu: 'ContextMenu',
mouseover: 'MouseOver',
mouseout: 'MouseOut',
mouseenter: 'MouseEnter',
mouseleave: 'MouseLeave',
keydown: 'KeyDown',
keyup: 'KeyUp',
keypress: 'KeyPress',
focus: 'Focus'
},
TouchEventMap: {
touchstart: 'mousedown',
touchend: 'mouseup',
tap: 'click',
doubletap: 'dblclick'
}
},
afterRender: function() {
var me = this;
me.callParent();
me.mon(me.el, {
scope: me,
click: me.handleEvent,
longpress: me.handleEvent,
mousedown: me.handleEvent,
mouseup: me.handleEvent,
dblclick: me.handleEvent,
contextmenu: me.handleEvent,
keydown: me.handleEvent,
keyup: me.handleEvent,
keypress: me.handleEvent,
mouseover: me.handleMouseOver,
mouseout: me.handleMouseOut
});
},
getTargetSelector: function() {
return this.dataRowSelector || this.itemSelector;
},
handleMouseOver: function(e) {
var me = this,
itemSelector = me.getTargetSelector(),
item = e.getTarget(itemSelector);
if (!me.isDestroyed) {
if (item) {
if (me.mouseOverItem !== item && me.el.contains(item)) {
me.mouseOverItem = e.item = item;
e.newType = 'mouseenter';
me.handleEvent(e);
}
} else {
me.handleEvent(e);
}
}
},
handleMouseOut: function(e) {
var itemSelector = this.getTargetSelector(),
item = e.getTarget(itemSelector),
computedRelatedTarget = e.getRelatedTarget(itemSelector),
sourceView;
if ((item === computedRelatedTarget) && !(item === null && computedRelatedTarget === null)) {
return;
}
if (!this.isDestroyed) {
if (item && (sourceView = this.self.getBoundView(item))) {
e.item = item;
e.newType = 'mouseleave';
sourceView.handleEvent(e);
sourceView.mouseOverItem = null;
} else {
this.handleEvent(e);
}
}
},
handleEvent: function(e) {
var me = this,
isKeyEvent = me.keyEventRe.test(e.type),
nm = me.getNavigationModel();
e.view = me;
if (isKeyEvent) {
e.item = nm.getItem();
e.record = nm.getRecord();
}
if (!e.item) {
e.item = e.getTarget(me.itemSelector);
}
if (e.item && !e.record) {
e.record = me.getRecord(e.item);
}
if (me.processUIEvent(e) !== false) {
me.processSpecialEvent(e);
}
if (isKeyEvent && !Ext.fly(e.target).isInputField()) {
if (e.getKey() === e.SPACE || e.isNavKeyPress(true)) {
e.preventDefault();
}
}
},
processItemEvent: Ext.emptyFn,
processContainerEvent: Ext.emptyFn,
processSpecialEvent: Ext.emptyFn,
processUIEvent: function(e) {
if (!Ext.getBody().isAncestor(e.target)) {
return;
}
var me = this,
item = e.item,
self = me.self,
map = self.EventMap,
touchMap = self.TouchEventMap,
index,
record = e.record,
type = e.type,
newType = type;
if (e.newType) {
newType = e.newType;
}
if (item) {
newType = touchMap[newType] || newType;
index = e.recordIndex = me.indexInStore ? me.indexInStore(record) : me.indexOf(item);
if (!record || me.processItemEvent(record, item, index, e) === false) {
return false;
}
if ((me['onBeforeItem' + map[newType]](record, item, index, e) === false) || (me.fireEvent('beforeitem' + newType, me, record, item, index, e) === false) || (me['onItem' + map[newType]](record, item, index, e) === false)) {
return false;
}
me.fireEvent('item' + newType, me, record, item, index, e);
} else {
type = touchMap[type] || type;
if ((me.processContainerEvent(e) === false) || (me['onBeforeContainer' + map[type]](e) === false) || (me.fireEvent('beforecontainer' + type, me, e) === false) || (me['onContainer' + map[type]](e) === false)) {
return false;
}
me.fireEvent('container' + type, me, e);
}
return true;
},
onItemMouseEnter: function(record, item, index, e) {
if (this.trackOver) {
this.highlightItem(item);
}
},
onItemMouseLeave: function(record, item, index, e) {
if (this.trackOver) {
this.clearHighlight();
}
},
onItemMouseDown: Ext.emptyFn,
onItemLongPress: Ext.emptyFn,
onItemMouseUp: Ext.emptyFn,
onItemFocus: Ext.emptyFn,
onItemClick: Ext.emptyFn,
onItemDblClick: Ext.emptyFn,
onItemContextMenu: Ext.emptyFn,
onItemKeyDown: Ext.emptyFn,
onItemKeyUp: Ext.emptyFn,
onItemKeyPress: Ext.emptyFn,
onBeforeItemLongPress: Ext.emptyFn,
onBeforeItemMouseDown: Ext.emptyFn,
onBeforeItemMouseUp: Ext.emptyFn,
onBeforeItemFocus: Ext.emptyFn,
onBeforeItemMouseEnter: Ext.emptyFn,
onBeforeItemMouseLeave: Ext.emptyFn,
onBeforeItemClick: Ext.emptyFn,
onBeforeItemDblClick: Ext.emptyFn,
onBeforeItemContextMenu: Ext.emptyFn,
onBeforeItemKeyDown: Ext.emptyFn,
onBeforeItemKeyUp: Ext.emptyFn,
onBeforeItemKeyPress: Ext.emptyFn,
onContainerMouseDown: Ext.emptyFn,
onContainerLongPress: Ext.emptyFn,
onContainerMouseUp: Ext.emptyFn,
onContainerMouseOver: Ext.emptyFn,
onContainerMouseOut: Ext.emptyFn,
onContainerClick: Ext.emptyFn,
onContainerDblClick: Ext.emptyFn,
onContainerContextMenu: Ext.emptyFn,
onContainerKeyDown: Ext.emptyFn,
onContainerKeyUp: Ext.emptyFn,
onContainerKeyPress: Ext.emptyFn,
onBeforeContainerMouseDown: Ext.emptyFn,
onBeforeContainerLongPress: Ext.emptyFn,
onBeforeContainerMouseUp: Ext.emptyFn,
onBeforeContainerMouseOver: Ext.emptyFn,
onBeforeContainerMouseOut: Ext.emptyFn,
onBeforeContainerClick: Ext.emptyFn,
onBeforeContainerDblClick: Ext.emptyFn,
onBeforeContainerContextMenu: Ext.emptyFn,
onBeforeContainerKeyDown: Ext.emptyFn,
onBeforeContainerKeyUp: Ext.emptyFn,
onBeforeContainerKeyPress: Ext.emptyFn,
setHighlightedItem: function(item) {
var me = this,
highlighted = me.highlightedItem,
overItemCls = me.overItemCls;
if (highlighted !== item) {
if (highlighted) {
Ext.fly(highlighted).removeCls(overItemCls);
if (Ext.isIE8) {
me.repaintBorder(highlighted);
me.repaintBorder(highlighted.nextSibling);
}
if (me.hasListeners.unhighlightitem) {
me.fireEvent('unhighlightitem', me, highlighted);
}
}
me.highlightedItem = item;
if (item) {
Ext.fly(item).addCls(me.overItemCls);
if (Ext.isIE8) {
me.repaintBorder(item.nextSibling);
}
if (me.hasListeners.highlightitem) {
me.fireEvent('highlightitem', me, item);
}
}
}
},
highlightItem: function(item) {
this.setHighlightedItem(item);
},
clearHighlight: function() {
this.setHighlightedItem(undefined);
},
handleUpdate: function(store, record) {
var me = this,
node, newNode, highlighted;
if (me.viewReady) {
node = me.getNode(record);
newNode = me.callParent(arguments);
highlighted = me.highlightedItem;
if (highlighted && highlighted === node) {
delete me.highlightedItem;
if (newNode) {
me.highlightItem(newNode);
}
}
}
},
refresh: function() {
this.clearHighlight();
this.callParent(arguments);
},
focusNode: function(rec) {
var me = this,
node = me.getNode(rec),
el = me.el,
adjustmentY = 0,
adjustmentX = 0,
elRegion = el.getRegion(),
nodeRegion;
elRegion.bottom = elRegion.top + el.dom.clientHeight;
elRegion.right = elRegion.left + el.dom.clientWidth;
if (node) {
nodeRegion = Ext.fly(node).getRegion();
if (nodeRegion.top < elRegion.top) {
adjustmentY = nodeRegion.top - elRegion.top;
}
else if (nodeRegion.bottom > elRegion.bottom) {
adjustmentY = nodeRegion.bottom - elRegion.bottom;
}
if (nodeRegion.left < elRegion.left) {
adjustmentX = nodeRegion.left - elRegion.left;
}
else if (nodeRegion.right > elRegion.right) {
adjustmentX = nodeRegion.right - elRegion.right;
}
if (adjustmentX || adjustmentY) {
me.scrollBy(adjustmentX, adjustmentY, false);
}
Ext.fly(node).set({
tabIndex: -1
});
node.focus();
}
},
bindStore: function(store, initial, propertyName) {
var me = this,
dataSource = me[propertyName],
selModel = me.getSelectionModel();
if (dataSource && dataSource.isFeatureStore && me.rendered) {
selModel.bindStore(dataSource.store);
selModel.bindComponent(me);
if (store.isFeatureStore) {
me.bindStoreListeners(store);
dataSource.bindStore(dataSource.store);
} else {
dataSource.bindStore(store);
}
} else {
me.callParent([
store,
initial,
propertyName
]);
}
},
privates: {
repaintBorder: function(rowIdx) {
var node = this.getNode(rowIdx);
if (node) {
node.className = node.className;
}
}
}
});
Ext.define('Ext.grid.CellContext', {
isCellContext: true,
constructor: function(view) {
this.view = view;
},
isEqual: function(other) {
if (other) {
return this.record === other.record && this.column === other.column;
}
return false;
},
setPosition: function(row, col) {
var me = this;
if (arguments.length === 1) {
if (row.length) {
col = row[0];
col = row[1];
} else
{
if (row.view) {
me.view = row.view;
}
col = row.column;
row = row.row;
}
}
me.setRow(row);
me.setColumn(col);
return me;
},
setAll: function(view, recordIndex, columnIndex, record, columnHeader) {
var me = this;
me.view = view;
me.rowIdx = recordIndex;
me.colIdx = columnIndex;
me.record = record;
me.column = columnHeader;
return me;
},
setRow: function(row) {
var me = this,
dataSource = me.view.dataSource;
if (row !== undefined) {
if (typeof row === 'number') {
me.rowIdx = Math.max(Math.min(row, dataSource.getCount() - 1), 0);
me.record = dataSource.getAt(row);
}
else if (row.isModel) {
me.record = row;
me.rowIdx = dataSource.indexOf(row);
}
else if (row.tagName) {
me.record = me.view.getRecord(row);
me.rowIdx = dataSource.indexOf(me.record);
}
}
},
setColumn: function(col) {
var me = this,
colMgr = me.view.getVisibleColumnManager();
if (col !== undefined) {
if (typeof col === 'number') {
me.colIdx = col;
me.column = colMgr.getHeaderAtIndex(col);
} else if (col.isHeader) {
me.column = col;
me.colIdx = colMgr.indexOf(col);
}
}
},
next: function() {
var me = this,
mgr = me.view.getVisibleColumnManager();
me.colIdx++;
if (me.colIdx === mgr.getColumns().length) {
me.setPosition(Math.min(me.rowIdx + 1, me.view.dataSource.getCount() - 1), me.colIdx);
} else {
me.setColumn(me.colIdx);
}
},
equal: function(other) {
return (other && other.isCellContext && other.view === this.view && other.record === this.record && other.column === this.column);
},
clone: function() {
var me = this,
result = new me.self(me.view);
result.rowIdx = me.rowIdx;
result.colIdx = me.colIdx;
result.record = me.record;
result.column = me.column;
return result;
}
});
Ext.define('Ext.view.TableLayout', {
extend: 'Ext.layout.component.Auto',
alias: 'layout.tableview',
type: 'tableview',
beginLayout: function(ownerContext) {
var me = this,
partner = me.owner.lockingPartner,
context = ownerContext.context;
if (!me.columnFlusherId) {
me.columnFlusherId = me.id + '-columns';
me.rowHeightFlusherId = me.id + '-rows';
}
me.callParent([
ownerContext
]);
if (partner && partner.grid.isVisible()) {
if (!ownerContext.lockingPartnerContext) {
(ownerContext.lockingPartnerContext = context.getCmp(partner)).lockingPartnerContext = ownerContext;
}
ownerContext.rowHeightSynchronizer = me.owner.syncRowHeightBegin();
}
(ownerContext.headerContext = context.getCmp(me.headerCt)).viewContext = ownerContext;
},
beginLayoutCycle: function(ownerContext, firstCycle) {
this.callParent([
ownerContext,
firstCycle
]);
if (ownerContext.syncRowHeights) {
ownerContext.target.syncRowHeightClear(ownerContext.rowHeightSynchronizer);
ownerContext.syncRowHeights = false;
}
},
calculate: function(ownerContext) {
var me = this,
context = ownerContext.context,
lockingPartnerContext = ownerContext.lockingPartnerContext,
headerContext = ownerContext.headerContext,
ownerCtContext = ownerContext.ownerCtContext,
owner = me.owner,
columnsChanged = headerContext.getProp('columnsChanged'),
state = ownerContext.state,
columnFlusher, otherSynchronizer, synchronizer, rowHeightFlusher,
bodyDom = owner.body.dom,
bodyHeight, ctSize, overflowY;
if (!owner.all.getCount() && (!bodyDom || !owner.body.child('table'))) {
ownerContext.setProp('viewOverflowY', false);
me.callParent([
ownerContext
]);
return;
}
if (columnsChanged === undefined) {
me.done = false;
return;
}
if (columnsChanged) {
if (!(columnFlusher = state.columnFlusher)) {
context.queueFlush(state.columnFlusher = columnFlusher = {
ownerContext: ownerContext,
columnsChanged: columnsChanged,
layout: me,
id: me.columnFlusherId,
flush: me.flushColumnWidths
});
}
if (!columnFlusher.flushed) {
me.done = false;
return;
}
}
if (lockingPartnerContext) {
if (!(rowHeightFlusher = state.rowHeightFlusher)) {
if (!(synchronizer = state.rowHeights)) {
state.rowHeights = synchronizer = ownerContext.rowHeightSynchronizer;
me.owner.syncRowHeightMeasure(synchronizer);
ownerContext.setProp('rowHeights', synchronizer);
}
if (!(otherSynchronizer = lockingPartnerContext.getProp('rowHeights'))) {
me.done = false;
return;
}
context.queueFlush(state.rowHeightFlusher = rowHeightFlusher = {
ownerContext: ownerContext,
synchronizer: synchronizer,
otherSynchronizer: otherSynchronizer,
layout: me,
id: me.rowHeightFlusherId,
flush: me.flushRowHeights
});
}
if (!rowHeightFlusher.flushed) {
me.done = false;
return;
}
}
me.callParent([
ownerContext
]);
if (!ownerContext.heightModel.shrinkWrap) {
overflowY = false;
if (!ownerCtContext.heightModel.shrinkWrap) {
ctSize = ownerCtContext.target.layout.getContainerSize(ownerCtContext);
if (!ctSize.gotHeight) {
me.done = false;
return;
}
bodyHeight = bodyDom.offsetHeight;
overflowY = bodyHeight > ctSize.height;
}
ownerContext.setProp('viewOverflowY', overflowY);
}
},
measureContentHeight: function(ownerContext) {
var owner = this.owner,
bodyDom = owner.body.dom,
emptyEl = owner.emptyEl,
bodyHeight = 0;
if (emptyEl) {
bodyHeight += emptyEl.offsetHeight;
}
if (bodyDom) {
bodyHeight += bodyDom.offsetHeight;
}
if (ownerContext.headerContext.state.boxPlan.tooNarrow) {
bodyHeight += Ext.getScrollbarSize().height;
}
return bodyHeight;
},
flushColumnWidths: function() {
var flusher = this,
me = flusher.layout,
ownerContext = flusher.ownerContext,
columnsChanged = flusher.columnsChanged,
owner = ownerContext.target,
len = columnsChanged.length,
column, i, colWidth, lastBox;
if (ownerContext.state.columnFlusher !== flusher) {
return;
}
for (i = 0; i < len; i++) {
if (!(column = columnsChanged[i])) {
continue;
}
colWidth = column.props.width;
owner.body.select(owner.getColumnSizerSelector(column.target)).setWidth(colWidth);
lastBox = column.lastBox;
if (lastBox) {
lastBox.width = colWidth;
}
}
flusher.flushed = true;
if (!me.pending) {
ownerContext.context.queueLayout(me);
}
},
flushRowHeights: function() {
var flusher = this,
me = flusher.layout,
ownerContext = flusher.ownerContext;
if (ownerContext.state.rowHeightFlusher !== flusher) {
return;
}
ownerContext.target.syncRowHeightFinish(flusher.synchronizer, flusher.otherSynchronizer);
flusher.flushed = true;
ownerContext.syncRowHeights = true;
if (!me.pending) {
ownerContext.context.queueLayout(me);
}
},
finishedLayout: function(ownerContext) {
var nodeContainer = Ext.fly(this.owner.getNodeContainer());
this.callParent([
ownerContext
]);
if (nodeContainer) {
nodeContainer.setWidth(ownerContext.headerContext.props.contentWidth);
}
}
});
Ext.define('Ext.grid.locking.RowSynchronizer', {
constructor: function(view, rowEl) {
var me = this,
rowTpl;
me.view = view;
me.rowEl = rowEl;
me.els = {};
me.add('data', view.rowSelector);
for (rowTpl = view.rowTpl; rowTpl; rowTpl = rowTpl.nextTpl) {
if (rowTpl.beginRowSync) {
rowTpl.beginRowSync(me);
}
}
},
add: function(name, selector) {
var el = Ext.fly(this.rowEl).down(selector, true);
if (el) {
this.els[name] = {
el: el
};
}
},
finish: function(other) {
var me = this,
els = me.els,
otherEls = other.els,
otherEl,
growth = 0,
otherGrowth = 0,
delta, name, otherHeight;
for (name in els) {
otherEl = otherEls[name];
otherHeight = otherEl ? otherEl.height : 0;
delta = otherHeight - els[name].height;
if (delta > 0) {
growth += delta;
Ext.fly(els[name].el).setHeight(otherHeight);
} else {
otherGrowth -= delta;
}
}
otherHeight = other.rowHeight + otherGrowth;
if (me.rowHeight + growth < otherHeight) {
Ext.fly(me.rowEl).setHeight(otherHeight);
}
},
measure: function() {
var me = this,
els = me.els,
name;
me.rowHeight = me.rowEl.offsetHeight;
for (name in els) {
els[name].height = els[name].el.offsetHeight;
}
},
reset: function() {
var els = this.els,
name;
this.rowEl.style.height = '';
for (name in els) {
els[name].el.style.height = '';
}
}
});
Ext.define('Ext.view.NodeCache', {
requires: [
'Ext.dom.CompositeElementLite'
],
statics: {
range: document.createRange && document.createRange()
},
constructor: function(view) {
this.view = view;
this.clear();
this.el = new Ext.dom.Fly();
},
clear: function(removeDom) {
var me = this,
elements = me.elements,
range = me.statics().range,
key;
if (me.count && removeDom) {
if (range) {
range.setStartBefore(elements[me.startIndex]);
range.setEndAfter(elements[me.endIndex]);
range.deleteContents();
} else {
for (key in elements) {
Ext.removeNode(elements[key]);
}
}
}
me.elements = {};
me.count = me.startIndex = 0;
me.endIndex = -1;
},
fill: function(newElements, startIndex, fixedNodes) {
fixedNodes = fixedNodes || 0;
var me = this,
elements = me.elements = {},
i,
len = newElements.length - fixedNodes;
if (!startIndex) {
startIndex = 0;
}
for (i = 0; i < len; i++) {
elements[startIndex + i] = newElements[i + fixedNodes];
}
me.startIndex = startIndex;
me.endIndex = startIndex + len - 1;
me.count = len;
return this;
},
insert: function(insertPoint, nodes) {
var me = this,
elements = me.elements,
i,
nodeCount = nodes.length;
if (me.count) {
if (insertPoint > me.endIndex + 1 || insertPoint + nodes.length - 1 < me.startIndex) {
Ext.Error.raise('Discontiguous range would result from inserting ' + nodes.length + ' nodes at ' + insertPoint);
}
if (insertPoint < me.count) {
for (i = me.endIndex + nodeCount; i >= insertPoint + nodeCount; i--) {
elements[i] = elements[i - nodeCount];
elements[i].setAttribute('data-recordIndex', i);
}
}
me.endIndex = me.endIndex + nodeCount;
} else
{
me.startIndex = insertPoint;
me.endIndex = insertPoint + nodeCount - 1;
}
for (i = 0; i < nodeCount; i++ , insertPoint++) {
elements[insertPoint] = nodes[i];
elements[insertPoint].setAttribute('data-recordIndex', insertPoint);
}
me.count += nodeCount;
},
invoke: function(fn, args) {
var me = this,
element, i;
fn = Ext.dom.Element.prototype[fn];
for (i = me.startIndex; i <= me.endIndex; i++) {
element = me.item(i);
if (element) {
fn.apply(element, args);
}
}
return me;
},
item: function(index, asDom) {
var el = this.elements[index],
result = null;
if (el) {
result = asDom ? this.elements[index] : this.el.attach(this.elements[index]);
}
return result;
},
first: function(asDom) {
return this.item(this.startIndex, asDom);
},
last: function(asDom) {
return this.item(this.endIndex, asDom);
},
moveBlock: function(increment) {
var me = this,
elements = me.elements,
node, end, step, i;
if (increment < 0) {
i = me.startIndex - 1;
end = me.endIndex;
step = 1;
} else {
i = me.endIndex + 1;
end = me.startIndex;
step = -1;
}
me.startIndex += increment;
me.endIndex += increment;
do {
i += step;
node = elements[i + increment] = elements[i];
node.setAttribute('data-recordIndex', i + increment);
if (i < me.startIndex || i > me.endIndex) {
delete elements[i];
}
} while (
i !== end);
delete elements[i];
},
getCount: function() {
return this.count;
},
slice: function(start, end) {
var elements = this.elements,
result = [],
i;
if (!end) {
end = this.endIndex;
} else {
end = Math.min(this.endIndex, end - 1);
}
for (i = start || this.startIndex; i <= end; i++) {
result.push(elements[i]);
}
return result;
},
replaceElement: function(el, replacement, domReplace) {
var elements = this.elements,
index = (typeof el === 'number') ? el : this.indexOf(el);
if (index > -1) {
replacement = Ext.getDom(replacement);
if (domReplace) {
el = elements[index];
el.parentNode.insertBefore(replacement, el);
Ext.removeNode(el);
replacement.setAttribute('data-recordIndex', index);
}
this.elements[index] = replacement;
}
return this;
},
indexOf: function(el) {
var elements = this.elements,
index;
el = Ext.getDom(el);
for (index = this.startIndex; index <= this.endIndex; index++) {
if (elements[index] === el) {
return index;
}
}
return -1;
},
removeRange: function(start, end, removeDom) {
var me = this,
elements = me.elements,
el, i, removeCount, fromPos;
if (end == null) {
end = me.endIndex + 1;
} else {
end = Math.min(me.endIndex + 1, end + 1);
}
if (start == null) {
start = me.startIndex;
}
removeCount = end - start;
for (i = start , fromPos = end; i <= me.endIndex; i++ , fromPos++) {
el = elements[i];
if (removeDom && i < end) {
Ext.removeNode(el);
}
if (fromPos <= me.endIndex) {
el = elements[i] = elements[fromPos];
el.setAttribute('data-recordIndex', i);
} else
{
delete elements[i];
}
}
me.count -= removeCount;
me.endIndex -= removeCount;
},
removeElement: function(keys, removeDom) {
var me = this,
inKeys, key,
elements = me.elements,
el, deleteCount,
keyIndex = 0,
index, fromIndex;
if (Ext.isArray(keys)) {
inKeys = keys;
keys = [];
deleteCount = inKeys.length;
for (keyIndex = 0; keyIndex < deleteCount; keyIndex++) {
key = inKeys[keyIndex];
if (typeof key !== 'number') {
key = me.indexOf(key);
}
if (key >= me.startIndex && key <= me.endIndex) {
keys[keys.length] = key;
}
}
Ext.Array.sort(keys);
deleteCount = keys.length;
} else {
if (keys < me.startIndex || keys > me.endIndex) {
return;
}
deleteCount = 1;
keys = [
keys
];
}
for (index = fromIndex = keys[0] , keyIndex = 0; index <= me.endIndex; index++ , fromIndex++) {
if (keyIndex < deleteCount && index === keys[keyIndex]) {
fromIndex++;
keyIndex++;
if (removeDom) {
Ext.removeNode(elements[index]);
}
}
if (fromIndex <= me.endIndex && fromIndex >= me.startIndex) {
el = elements[index] = elements[fromIndex];
el.setAttribute('data-recordIndex', index);
} else {
delete elements[index];
}
}
me.endIndex -= deleteCount;
me.count -= deleteCount;
},
scroll: function(newRecords, direction, removeCount) {
var me = this,
view = me.view,
store = view.store,
elements = me.elements,
recCount = newRecords.length,
nodeContainer = view.getNodeContainer(),
fireItemRemove = view.hasListeners.itemremove,
fireItemAdd = view.hasListeners.itemadd,
range = me.statics().range,
i, el, removeEnd, children, result;
if (!newRecords.length) {
return;
}
if (direction === -1) {
if (removeCount) {
if (range) {
range.setStartBefore(elements[(me.endIndex - removeCount) + 1]);
range.setEndAfter(elements[me.endIndex]);
range.deleteContents();
for (i = (me.endIndex - removeCount) + 1; i <= me.endIndex; i++) {
el = elements[i];
delete elements[i];
if (fireItemRemove) {
view.fireEvent('itemremove', store.getByInternalId(el.getAttribute('data-recordId')), i, el, view);
}
}
} else {
for (i = (me.endIndex - removeCount) + 1; i <= me.endIndex; i++) {
el = elements[i];
delete elements[i];
Ext.removeNode(el);
if (fireItemRemove) {
view.fireEvent('itemremove', store.getByInternalId(el.getAttribute('data-recordId')), i, el, view);
}
}
}
me.endIndex -= removeCount;
}
if (newRecords.length) {
result = view.bufferRender(newRecords, me.startIndex -= recCount);
children = result.children;
for (i = 0; i < recCount; i++) {
elements[me.startIndex + i] = children[i];
}
nodeContainer.insertBefore(result.fragment, nodeContainer.firstChild);
if (fireItemAdd) {
view.fireEvent('itemadd', newRecords, me.startIndex, children);
}
}
} else
{
if (removeCount) {
removeEnd = me.startIndex + removeCount;
if (range) {
range.setStartBefore(elements[me.startIndex]);
range.setEndAfter(elements[removeEnd - 1]);
range.deleteContents();
for (i = me.startIndex; i < removeEnd; i++) {
el = elements[i];
delete elements[i];
if (fireItemRemove) {
view.fireEvent('itemremove', store.getByInternalId(el.getAttribute('data-recordId')), i, el, view);
}
}
} else {
for (i = me.startIndex; i < removeEnd; i++) {
el = elements[i];
delete elements[i];
Ext.removeNode(el);
if (fireItemRemove) {
view.fireEvent('itemremove', store.getByInternalId(el.getAttribute('data-recordId')), i, el, view);
}
}
}
me.startIndex = removeEnd;
}
result = view.bufferRender(newRecords, me.endIndex + 1);
children = result.children;
for (i = 0; i < recCount; i++) {
elements[me.endIndex += 1] = children[i];
}
nodeContainer.appendChild(result.fragment);
if (fireItemAdd) {
view.fireEvent('itemadd', newRecords, me.endIndex + 1, children);
}
}
me.count = me.endIndex - me.startIndex + 1;
return children;
},
sumHeights: function() {
var result = 0,
elements = this.elements,
i;
for (i = this.startIndex; i <= this.endIndex; i++) {
result += elements[i].offsetHeight;
}
return result;
}
}, function() {
Ext.dom.CompositeElementLite.importElementMethods.call(this);
});
Ext.define('Ext.view.Table', {
extend: 'Ext.view.View',
xtype: [
'tableview',
'gridview'
],
alternateClassName: 'Ext.grid.View',
requires: [
'Ext.grid.CellContext',
'Ext.view.TableLayout',
'Ext.grid.locking.RowSynchronizer',
'Ext.view.NodeCache',
'Ext.util.DelayedTask',
'Ext.util.MixedCollection'
],
isTableView: true,
config: {
selectionModel: {
type: 'rowmodel'
}
},
inheritableStatics: {
events: [
"blur",
"focus",
"move",
"resize",
"destroy",
"beforedestroy",
"boxready",
"afterrender",
"render",
"beforerender",
"removed",
"hide",
"beforehide",
"show",
"beforeshow",
"enable",
"disable",
"added",
"deactivate",
"beforedeactivate",
"activate",
"beforeactivate",
"cellkeydown",
"beforecellkeydown",
"cellmouseup",
"beforecellmouseup",
"cellmousedown",
"beforecellmousedown",
"cellcontextmenu",
"beforecellcontextmenu",
"celldblclick",
"beforecelldblclick",
"cellclick",
"beforecellclick",
"refresh",
"itemremove",
"itemadd",
"itemupdate",
"viewready",
"beforerefresh",
"unhighlightitem",
"highlightitem",
"focuschange",
"deselect",
"select",
"beforedeselect",
"beforeselect",
"selectionchange",
"containerkeydown",
"containercontextmenu",
"containerdblclick",
"containerclick",
"containermouseout",
"containermouseover",
"containermouseup",
"containermousedown",
"beforecontainerkeydown",
"beforecontainercontextmenu",
"beforecontainerdblclick",
"beforecontainerclick",
"beforecontainermouseout",
"beforecontainermouseover",
"beforecontainermouseup",
"beforecontainermousedown",
"itemkeydown",
"itemcontextmenu",
"itemdblclick",
"itemclick",
"itemmouseleave",
"itemmouseenter",
"itemmouseup",
"itemmousedown",
"rowclick",
"rowcontextmenu",
"rowdblclick",
"rowkeydown",
"rowmouseup",
"rowmousedown",
"rowkeydown",
"beforeitemkeydown",
"beforeitemcontextmenu",
"beforeitemdblclick",
"beforeitemclick",
"beforeitemmouseleave",
"beforeitemmouseenter",
"beforeitemmouseup",
"beforeitemmousedown",
"statesave",
"beforestatesave",
"staterestore",
"beforestaterestore",
"uievent",
"groupcollapse",
"groupexpand"
]
},
scrollable: true,
componentLayout: 'tableview',
baseCls: Ext.baseCSSPrefix + 'grid-view',
unselectableCls: Ext.baseCSSPrefix + 'unselectable',
firstCls: Ext.baseCSSPrefix + 'grid-cell-first',
lastCls: Ext.baseCSSPrefix + 'grid-cell-last',
itemCls: Ext.baseCSSPrefix + 'grid-item',
selectedItemCls: Ext.baseCSSPrefix + 'grid-item-selected',
selectedCellCls: Ext.baseCSSPrefix + 'grid-cell-selected',
focusedItemCls: Ext.baseCSSPrefix + 'grid-item-focused',
overItemCls: Ext.baseCSSPrefix + 'grid-item-over',
altRowCls: Ext.baseCSSPrefix + 'grid-item-alt',
dirtyCls: Ext.baseCSSPrefix + 'grid-dirty-cell',
rowClsRe: new RegExp('(?:^|\\s*)' + Ext.baseCSSPrefix + 'grid-item-alt(?:\\s+|$)', 'g'),
cellRe: new RegExp(Ext.baseCSSPrefix + 'grid-cell-([^\\s]+)(?:\\s|$)', ''),
positionBody: true,
positionCells: false,
stripeOnUpdate: null,
trackOver: true,
getRowClass: null,
stripeRows: true,
markDirty: true,
ariaRole: 'grid',
tpl: [
'{%',
'view = values.view;',
'if (!(columns = values.columns)) {',
'columns = values.columns = view.ownerCt.getVisibleColumnManager().getColumns();',
'}',
'values.fullWidth = 0;',
'for (i = 0, len = columns.length; i < len; i++) {',
'column = columns[i];',
'values.fullWidth += (column.cellWidth = column.lastBox ? column.lastBox.width : column.width || column.minWidth);',
'}',
'tableCls=values.tableCls=[];',
'%}',
'<div class="' + Ext.baseCSSPrefix + 'grid-item-container" style="width:{fullWidth}px">',
'{[view.renderTHead(values, out, parent)]}',
'{%',
'view.renderRows(values.rows, values.columns, values.viewStartIndex, out);',
'%}',
'{[view.renderTFoot(values, out, parent)]}',
'</div>',
{
definitions: 'var view, tableCls, columns, i, len, column;',
priority: 0
}
],
outerRowTpl: [
'<table id="{rowId}" ',
'data-boundView="{view.id}" ',
'data-recordId="{record.internalId}" ',
'data-recordIndex="{recordIndex}" ',
'class="{[values.itemClasses.join(" ")]}" cellPadding="0" cellSpacing="0" {ariaTableAttr} style="{itemStyle};width:0">',
'{%',
'this.nextTpl.applyOut(values, out, parent)',
'%}',
'</table>',
{
priority: 9999
}
],
rowTpl: [
'{%',
'var dataRowCls = values.recordIndex === -1 ? "" : " ' + Ext.baseCSSPrefix + 'grid-row";',
'%}',
'<tr class="{[values.rowClasses.join(" ")]} {[dataRowCls]}" {rowAttr:attributes} {ariaRowAttr}>',
'<tpl for="columns">' + '{%',
'parent.view.renderCell(values, parent.record, parent.recordIndex, parent.rowIndex, xindex - 1, out, parent)',
'%}',
'</tpl>',
'</tr>',
{
priority: 0
}
],
cellTpl: [
'<td class="{tdCls}" {tdAttr} {[Ext.aria ? "id=\\"" + Ext.id() + "\\"" : ""]} style="width:{column.cellWidth}px;<tpl if="tdStyle">{tdStyle}</tpl>" tabindex="-1" {ariaCellAttr} data-columnid="{[values.column.getItemId()]}">',
'<div {unselectableAttr} class="' + Ext.baseCSSPrefix + 'grid-cell-inner {innerCls}" ',
'style="text-align:{align};<tpl if="style">{style}</tpl>" {ariaCellInnerAttr}>{value}</div>',
'</td>',
{
priority: 0
}
],
refreshSelmodelOnRefresh: false,
tableValues: {},
rowValues: {
itemClasses: [],
rowClasses: []
},
cellValues: {
classes: [
Ext.baseCSSPrefix + 'grid-cell ' + Ext.baseCSSPrefix + 'grid-td'
]
},
constructor: function(config) {
if (config.grid.isTree) {
config.baseCls = Ext.baseCSSPrefix + 'tree-view';
}
this.callParent([
config
]);
},
hasVariableRowHeight: function(fromLockingPartner) {
var me = this;
return me.variableRowHeight || me.store.isGrouped() || me.getVisibleColumnManager().hasVariableRowHeight() ||
(!fromLockingPartner && me.lockingPartner && me.lockingPartner.hasVariableRowHeight(true));
},
initComponent: function() {
var me = this;
if (me.columnLines) {
me.addCls(me.grid.colLinesCls);
}
if (me.rowLines) {
me.addCls(me.grid.rowLinesCls);
}
me.body = new Ext.dom.Fly();
me.body.id = me.id + 'gridBody';
if (!me.trackOver) {
me.overItemCls = null;
}
me.headerCt.view = me;
me.grid.view = me;
me.initFeatures(me.grid);
me.itemSelector = me.getItemSelector();
me.all = new Ext.view.NodeCache(me);
me.callParent();
},
applySelectionModel: function(selModel, oldSelModel) {
var me = this,
grid = me.ownerGrid,
defaultType = selModel.type;
if (!oldSelModel) {
if (!(selModel && selModel.isSelectionModel)) {
selModel = grid.selModel || selModel;
}
}
if (selModel) {
if (selModel.isSelectionModel) {
selModel.allowDeselect = grid.allowDeselect || selModel.selectionMode !== 'SINGLE';
selModel.locked = grid.disableSelection;
} else {
if (typeof selModel === 'string') {
selModel = {
type: selModel
};
} else
{
selModel.type = grid.selType || selModel.selType || selModel.type || defaultType;
}
if (!selModel.mode) {
if (grid.simpleSelect) {
selModel.mode = 'SIMPLE';
} else if (grid.multiSelect) {
selModel.mode = 'MULTI';
}
}
selModel = Ext.Factory.selection(Ext.apply({
allowDeselect: grid.allowDeselect,
locked: grid.disableSelection
}, selModel));
}
}
return selModel;
},
updateSelectionModel: function(selModel, oldSelModel) {
var me = this;
if (oldSelModel) {
oldSelModel.un({
scope: me,
lastselectedchanged: me.updateBindSelection,
selectionchange: me.updateBindSelection
});
Ext.destroy(me.selModelRelayer);
}
me.selModelRelayer = me.relayEvents(selModel, [
'selectionchange',
'beforeselect',
'beforedeselect',
'select',
'deselect',
'focuschange'
]);
selModel.on({
scope: me,
lastselectedchanged: me.updateBindSelection,
selectionchange: me.updateBindSelection
});
me.selModel = selModel;
},
getVisibleColumnManager: function() {
return this.ownerCt.getVisibleColumnManager();
},
getColumnManager: function() {
return this.ownerCt.getColumnManager();
},
getTopLevelVisibleColumnManager: function() {
return this.ownerGrid.getVisibleColumnManager();
},
moveColumn: function(fromIdx, toIdx, colsToMove) {
var me = this,
multiMove = colsToMove > 1,
range = multiMove && document.createRange ? document.createRange() : null,
fragment = multiMove && !range ? document.createDocumentFragment() : null,
destinationCellIdx = toIdx,
colCount = me.getGridColumns().length,
lastIndex = colCount - 1,
doFirstLastClasses = (me.firstCls || me.lastCls) && (toIdx === 0 || toIdx === colCount || fromIdx === 0 || fromIdx === lastIndex),
i, j, rows, len, tr, cells, colGroups;
if (me.rendered && toIdx !== fromIdx) {
rows = me.el.query(me.rowSelector);
if (toIdx > fromIdx && fragment) {
destinationCellIdx -= 1;
}
for (i = 0 , len = rows.length; i < len; i++) {
tr = rows[i];
cells = tr.childNodes;
if (doFirstLastClasses) {
if (cells.length === 1) {
Ext.fly(cells[0]).addCls(me.firstCls);
Ext.fly(cells[0]).addCls(me.lastCls);
continue;
}
if (fromIdx === 0) {
Ext.fly(cells[0]).removeCls(me.firstCls);
Ext.fly(cells[1]).addCls(me.firstCls);
} else if (fromIdx === lastIndex) {
Ext.fly(cells[lastIndex]).removeCls(me.lastCls);
Ext.fly(cells[lastIndex - 1]).addCls(me.lastCls);
}
if (toIdx === 0) {
Ext.fly(cells[0]).removeCls(me.firstCls);
Ext.fly(cells[fromIdx]).addCls(me.firstCls);
} else if (toIdx === colCount) {
Ext.fly(cells[lastIndex]).removeCls(me.lastCls);
Ext.fly(cells[fromIdx]).addCls(me.lastCls);
}
}
if (multiMove) {
if (range) {
range.setStartBefore(cells[fromIdx]);
range.setEndAfter(cells[fromIdx + colsToMove - 1]);
fragment = range.extractContents();
} else {
for (j = 0; j < colsToMove; j++) {
fragment.appendChild(cells[fromIdx]);
}
}
tr.insertBefore(fragment, cells[destinationCellIdx] || null);
} else {
tr.insertBefore(cells[fromIdx], cells[destinationCellIdx] || null);
}
}
colGroups = me.el.query('colgroup');
for (i = 0 , len = colGroups.length; i < len; i++) {
tr = colGroups[i];
if (multiMove) {
if (range) {
range.setStartBefore(tr.childNodes[fromIdx]);
range.setEndAfter(tr.childNodes[fromIdx + colsToMove - 1]);
fragment = range.extractContents();
} else {
for (j = 0; j < colsToMove; j++) {
fragment.appendChild(tr.childNodes[fromIdx]);
}
}
tr.insertBefore(fragment, tr.childNodes[destinationCellIdx] || null);
} else {
tr.insertBefore(tr.childNodes[fromIdx], tr.childNodes[destinationCellIdx] || null);
}
}
}
},
scrollToTop: Ext.emptyFn,
addElListener: function(eventName, fn, scope) {
this.mon(this, eventName, fn, scope, {
element: 'el'
});
},
getGridColumns: function() {
return this.ownerCt.getVisibleColumnManager().getColumns();
},
getHeaderAtIndex: function(index) {
return this.ownerCt.getVisibleColumnManager().getHeaderAtIndex(index);
},
getCell: function(record, column) {
var row = this.getRow(record);
return Ext.fly(row).down(column.getCellSelector());
},
getFeature: function(id) {
var features = this.featuresMC;
if (features) {
return features.get(id);
}
},
findFeature: function(ftype) {
if (this.features) {
return Ext.Array.findBy(this.features, function(feature) {
if (feature.ftype === ftype) {
return true;
}
});
}
},
initFeatures: function(grid) {
var me = this,
i, features, feature, len;
me.tpl = Ext.XTemplate.getTpl(this, 'tpl');
me.rowTpl = Ext.XTemplate.getTpl(this, 'rowTpl');
me.addRowTpl(Ext.XTemplate.getTpl(this, 'outerRowTpl'));
me.cellTpl = Ext.XTemplate.getTpl(this, 'cellTpl');
me.featuresMC = new Ext.util.MixedCollection();
features = me.features = me.constructFeatures();
len = features ? features.length : 0;
for (i = 0; i < len; i++) {
feature = features[i];
feature.view = me;
feature.grid = grid;
me.featuresMC.add(feature);
feature.init(grid);
}
},
renderTHead: function(values, out, parent) {
var headers = values.view.headerFns,
len, i;
if (headers) {
for (i = 0 , len = headers.length; i < len; ++i) {
headers[i].call(this, values, out, parent);
}
}
},
addHeaderFn: function(fn) {
var headers = this.headerFns;
if (!headers) {
headers = this.headerFns = [];
}
headers.push(fn);
},
renderTFoot: function(values, out, parent) {
var footers = values.view.footerFns,
len, i;
if (footers) {
for (i = 0 , len = footers.length; i < len; ++i) {
footers[i].call(this, values, out, parent);
}
}
},
addFooterFn: function(fn) {
var footers = this.footerFns;
if (!footers) {
footers = this.footerFns = [];
}
footers.push(fn);
},
addTpl: function(newTpl) {
return this.insertTpl('tpl', newTpl);
},
addRowTpl: function(newTpl) {
return this.insertTpl('rowTpl', newTpl);
},
addCellTpl: function(newTpl) {
return this.insertTpl('cellTpl', newTpl);
},
insertTpl: function(which, newTpl) {
var me = this,
tpl, prevTpl;
if (newTpl.isTemplate) {
newTpl = Ext.Object.chain(newTpl);
} else
{
newTpl = new Ext.XTemplate('{%this.nextTpl.applyOut(values, out, parent);%}', newTpl);
}
for (tpl = me[which]; newTpl.priority < tpl.priority; tpl = tpl.nextTpl) {
prevTpl = tpl;
}
if (prevTpl) {
prevTpl.nextTpl = newTpl;
} else
{
me[which] = newTpl;
}
newTpl.nextTpl = tpl;
return newTpl;
},
tplApplyOut: function(values, out, parent) {
if (this.before) {
if (this.before(values, out, parent) === false) {
return;
}
}
this.nextTpl.applyOut(values, out, parent);
if (this.after) {
this.after(values, out, parent);
}
},
constructFeatures: function() {
var me = this,
features = me.features,
feature, result,
i = 0,
len;
if (features) {
result = [];
len = features.length;
for (; i < len; i++) {
feature = features[i];
if (!feature.isFeature) {
feature = Ext.create('feature.' + feature.ftype, feature);
}
result[i] = feature;
}
}
return result;
},
beforeRender: function() {
var me = this;
me.callParent();
if (!me.enableTextSelection) {
me.protoEl.unselectable();
}
},
onBindStore: function(store) {
var me = this,
bufferedRenderer = me.bufferedRenderer;
if (bufferedRenderer && bufferedRenderer.store !== store) {
bufferedRenderer.bindStore(store);
}
if (me.all && me.all.getCount()) {
if (bufferedRenderer) {
bufferedRenderer.setBodyTop(0);
}
me.clearViewEl();
}
me.callParent(arguments);
},
getStoreListeners: function() {
var result = this.callParent();
result.beforepageremove = this.beforePageRemove;
return result;
},
beforePageRemove: function(pageMap, pageNumber) {
var rows = this.all,
pageSize = pageMap.getPageSize();
if (rows.startIndex >= (pageNumber - 1) * pageSize && rows.endIndex <= (pageNumber * pageSize - 1)) {
pageMap.get(pageNumber);
return false;
}
},
onViewScroll: function(scroller, x, y) {
if (!this.ignoreScroll) {
this.callParent([
scroller,
x,
y
]);
}
},
createRowElement: function(record, index, updateColumns) {
var me = this,
div = me.renderBuffer,
tplData = me.collectData([
record
], index);
tplData.columns = updateColumns;
me.tpl.overwrite(div, tplData);
return Ext.fly(div).down(me.getNodeContainerSelector(), true).firstChild;
},
bufferRender: function(records, index) {
var me = this,
div = me.renderBuffer,
result,
range = document.createRange ? document.createRange() : null;
me.tpl.overwrite(div, me.collectData(records, index));
div = Ext.fly(div).down(me.getNodeContainerSelector(), true);
if (range) {
range.selectNodeContents(div);
result = range.extractContents();
} else {
result = document.createDocumentFragment();
while (div.firstChild) {
result.appendChild(div.firstChild);
}
}
return {
fragment: result,
children: Ext.Array.toArray(result.childNodes)
};
},
collectData: function(records, startIndex) {
var me = this;
me.rowValues.view = me;
me.tableValues.view = me;
me.tableValues.rows = records;
me.tableValues.columns = null;
me.tableValues.viewStartIndex = startIndex;
me.tableValues.touchScroll = me.touchScroll;
me.tableValues.tableStyle = 'width:' + me.headerCt.getTableWidth() + 'px';
return me.tableValues;
},
collectNodes: function(targetEl) {
this.all.fill(this.getNodeContainer().childNodes, this.all.startIndex);
},
refreshSize: function(forceLayout) {
var me = this,
bodySelector = me.getBodySelector();
if (bodySelector) {
me.body.attach(me.el.down(bodySelector, true));
}
if (!me.hasLoadingHeight) {
Ext.suspendLayouts();
me.callParent(arguments);
if (forceLayout || (me.hasVariableRowHeight() && me.dataSource.getCount())) {
me.grid.updateLayout();
}
Ext.resumeLayouts(true);
}
},
clearViewEl: function(leaveNodeContainer) {
var me = this,
all = me.all,
store = me.getStore(),
i, item, nodeContainer, targetEl;
for (i = all.startIndex; i <= all.endIndex; i++) {
item = all.item(i, true);
me.fireEvent('itemremove', store.getByInternalId(item.getAttribute('data-recordId')), i, item, me);
}
me.callParent();
nodeContainer = Ext.fly(me.getNodeContainer());
if (nodeContainer && !leaveNodeContainer) {
targetEl = me.getTargetEl();
if (targetEl.dom !== nodeContainer.dom) {
nodeContainer.destroy();
}
}
},
getMaskTarget: function() {
return this.ownerCt.body;
},
statics: {
getBoundView: function(node) {
return Ext.getCmp(node.getAttribute('data-boundView'));
}
},
getRecord: function(node) {
var me = this,
recordIndex;
if (me.store.isDestroyed) {
return;
}
if (node.isModel) {
return node;
}
node = me.getNode(node);
if (node) {
if (!me.hasActiveFeature()) {
recordIndex = node.getAttribute('data-recordIndex');
if (recordIndex) {
recordIndex = parseInt(recordIndex, 10);
if (recordIndex > -1) {
return me.store.data.getAt(recordIndex);
}
}
}
return me.dataSource.getByInternalId(node.getAttribute('data-recordId'));
}
},
indexOf: function(node) {
node = this.getNode(node);
if (!node && node !== 0) {
return -1;
}
return this.all.indexOf(node);
},
indexInStore: function(node) {
return node ? this.dataSource.indexOf(this.getRecord(node)) : -1;
},
renderRows: function(rows, columns, viewStartIndex, out) {
var rowValues = this.rowValues,
rowCount = rows.length,
i;
rowValues.view = this;
rowValues.columns = columns;
for (i = 0; i < rowCount; i++ , viewStartIndex++) {
rowValues.itemClasses.length = rowValues.rowClasses.length = 0;
this.renderRow(rows[i], viewStartIndex, out);
}
rowValues.view = rowValues.columns = rowValues.record = null;
},
renderColumnSizer: function(values, out) {
var columns = values.columns || this.getGridColumns(),
len = columns.length,
i, column, width;
out.push('<colgroup role="presentation">');
for (i = 0; i < len; i++) {
column = columns[i];
width = column.cellWidth ? column.cellWidth : Ext.grid.header.Container.prototype.defaultWidth;
out.push('<col role="presentation" class="', Ext.baseCSSPrefix, 'grid-cell-', columns[i].getItemId(), '" style="width:' + width + 'px">');
}
out.push('</colgroup>');
},
renderRow: function(record, rowIdx, out) {
var me = this,
isMetadataRecord = rowIdx === -1,
selModel = me.selectionModel,
rowValues = me.rowValues,
itemClasses = rowValues.itemClasses,
rowClasses = rowValues.rowClasses,
itemCls = me.itemCls,
cls,
rowTpl = me.rowTpl;
rowValues.rowAttr = {};
rowValues.record = record;
rowValues.recordId = record.internalId;
rowValues.recordIndex = me.store.indexOf(record);
rowValues.rowIndex = rowIdx;
rowValues.rowId = me.getRowId(record);
rowValues.itemCls = rowValues.rowCls = '';
if (!rowValues.columns) {
rowValues.columns = me.ownerCt.getVisibleColumnManager().getColumns();
}
itemClasses.length = rowClasses.length = 0;
if (!isMetadataRecord) {
itemClasses[0] = itemCls;
if (!me.ownerCt.disableSelection && selModel.isRowSelected) {
if (selModel.isRowSelected(record)) {
itemClasses.push(me.selectedItemCls);
}
}
if (me.stripeRows && rowIdx % 2 !== 0) {
itemClasses.push(me.altRowCls);
}
if (me.getRowClass) {
cls = me.getRowClass(record, rowIdx, null, me.dataSource);
if (cls) {
rowClasses.push(cls);
}
}
}
if (out) {
rowTpl.applyOut(rowValues, out, me.tableValues);
} else {
return rowTpl.apply(rowValues, me.tableValues);
}
},
renderCell: function(column, record, recordIndex, rowIndex, columnIndex, out) {
var me = this,
fullIndex,
selModel = me.selectionModel,
cellValues = me.cellValues,
classes = cellValues.classes,
fieldValue = record.data[column.dataIndex],
cellTpl = me.cellTpl,
value, clsInsertPoint,
lastFocused = me.navigationModel.getPosition();
cellValues.record = record;
cellValues.column = column;
cellValues.recordIndex = recordIndex;
cellValues.rowIndex = rowIndex;
cellValues.columnIndex = columnIndex;
cellValues.cellIndex = columnIndex;
cellValues.align = column.align;
cellValues.innerCls = column.innerCls;
cellValues.tdCls = cellValues.tdStyle = cellValues.tdAttr = cellValues.style = "";
cellValues.unselectableAttr = me.enableTextSelection ? '' : 'unselectable="on"';
classes[1] = column.getCellId();
clsInsertPoint = 2;
if (column.renderer && column.renderer.call) {
fullIndex = me.ownerCt.columnManager.getHeaderIndex(column);
value = column.renderer.call(column.usingDefaultRenderer ? column : column.scope || me.ownerCt, fieldValue, cellValues, record, recordIndex, fullIndex, me.dataSource, me);
if (cellValues.css) {
record.cssWarning = true;
cellValues.tdCls += ' ' + cellValues.css;
cellValues.css = null;
}
if (cellValues.tdCls) {
classes[clsInsertPoint++] = cellValues.tdCls;
}
} else {
value = fieldValue;
}
cellValues.value = (value == null || value === '') ? column.emptyCellText : value;
if (column.tdCls) {
classes[clsInsertPoint++] = column.tdCls;
}
if (me.markDirty && record.dirty && record.isModified(column.dataIndex)) {
classes[clsInsertPoint++] = me.dirtyCls;
}
if (column.isFirstVisible) {
classes[clsInsertPoint++] = me.firstCls;
}
if (column.isLastVisible) {
classes[clsInsertPoint++] = me.lastCls;
}
if (!me.enableTextSelection) {
classes[clsInsertPoint++] = me.unselectableCls;
}
if (selModel && (selModel.isCellModel || selModel.isSpreadsheetModel) && selModel.isCellSelected(me, recordIndex, column)) {
classes[clsInsertPoint++] = me.selectedCellCls;
}
if (lastFocused && lastFocused.record.id === record.id && lastFocused.column === column) {
classes[clsInsertPoint++] = me.focusedItemCls;
}
classes.length = clsInsertPoint;
cellValues.tdCls = classes.join(' ');
cellTpl.applyOut(cellValues, out);
cellValues.column = null;
},
getRow: function(nodeInfo) {
var fly;
if ((!nodeInfo && nodeInfo !== 0) || !this.rendered) {
return null;
}
if (nodeInfo.target) {
nodeInfo = nodeInfo.target;
}
if (Ext.isString(nodeInfo)) {
return Ext.fly(nodeInfo).down(this.rowSelector, true);
}
if (Ext.isNumber(nodeInfo)) {
fly = this.all.item(nodeInfo);
return fly && fly.down(this.rowSelector, true);
}
if (nodeInfo.isModel) {
return this.getRowByRecord(nodeInfo);
}
fly = Ext.fly(nodeInfo);
if (fly.is(this.itemSelector)) {
return this.getRowFromItem(fly);
}
return fly.findParent(this.rowSelector, this.getTargetEl());
},
getRowId: function(record) {
return this.id + '-record-' + record.internalId;
},
constructRowId: function(internalId) {
return this.id + '-record-' + internalId;
},
getNodeById: function(id) {
id = this.constructRowId(id);
return this.retrieveNode(id, false);
},
getRowById: function(id) {
id = this.constructRowId(id);
return this.retrieveNode(id, true);
},
getNodeByRecord: function(record) {
return this.retrieveNode(this.getRowId(record), false);
},
getRowByRecord: function(record) {
return this.retrieveNode(this.getRowId(record), true);
},
getRowFromItem: function(item) {
var rows = Ext.getDom(item).tBodies[0].childNodes,
len = rows.length,
i;
for (i = 0; i < len; i++) {
if (Ext.fly(rows[i]).is(this.rowSelector)) {
return rows[i];
}
}
},
retrieveNode: function(id, dataRow) {
var result = this.el.getById(id, true);
if (dataRow && result) {
return Ext.fly(result).down(this.rowSelector, true);
}
return result;
},
updateIndexes: Ext.emptyFn,
bodySelector: 'div.' + Ext.baseCSSPrefix + 'grid-item-container',
nodeContainerSelector: 'div.' + Ext.baseCSSPrefix + 'grid-item-container',
itemSelector: 'table.' + Ext.baseCSSPrefix + 'grid-item',
rowSelector: 'tr.' + Ext.baseCSSPrefix + 'grid-row',
cellSelector: 'td.' + Ext.baseCSSPrefix + 'grid-cell',
sizerSelector: '.' + Ext.baseCSSPrefix + 'grid-cell',
innerSelector: 'div.' + Ext.baseCSSPrefix + 'grid-cell-inner',
getBodySelector: function() {
return this.bodySelector;
},
getColumnSizerSelector: function(header) {
var selector = this.sizerSelector + '-' + header.getItemId();
return 'td' + selector + ',col' + selector;
},
getItemSelector: function() {
return this.itemSelector;
},
getCellSelector: function(header) {
return header ? header.getCellSelector() : this.cellSelector;
},
getCellInnerSelector: function(header) {
return this.getCellSelector(header) + ' ' + this.innerSelector;
},
addRowCls: function(rowInfo, cls) {
var row = this.getRow(rowInfo);
if (row) {
Ext.fly(row).addCls(cls);
}
},
removeRowCls: function(rowInfo, cls) {
var row = this.getRow(rowInfo);
if (row) {
Ext.fly(row).removeCls(cls);
}
},
onRowSelect: function(rowIdx) {
var me = this;
me.addItemCls(rowIdx, me.selectedItemCls);
if (Ext.isIE8) {
me.repaintBorder(rowIdx + 1);
}
},
onRowDeselect: function(rowIdx) {
var me = this;
me.removeItemCls(rowIdx, me.selectedItemCls);
if (Ext.isIE8) {
me.repaintBorder(rowIdx + 1);
}
},
onCellSelect: function(position) {
var cell = this.getCellByPosition(position);
if (cell) {
cell.addCls(this.selectedCellCls);
}
},
onCellDeselect: function(position) {
var cell = this.getCellByPosition(position, true);
if (cell) {
Ext.fly(cell).removeCls(this.selectedCellCls);
}
},
getCellInclusive: function(position, returnDom) {
if (position) {
var row = this.getRow(position.row),
header = this.ownerCt.getColumnManager().getHeaderAtIndex(position.column);
if (header && row) {
return Ext.fly(row).down(this.getCellSelector(header), returnDom);
}
}
return false;
},
getCellByPosition: function(position, returnDom) {
if (position) {
var view = position.view || this,
row = view.getRow(position.record || position.row),
header = position.column.isColumn ? position.column : view.getVisibleColumnManager().getHeaderAtIndex(position.column);
if (header && row) {
return Ext.fly(row).down(view.getCellSelector(header), returnDom);
}
}
return false;
},
onFocusEnter: function(e) {
var me = this,
targetView,
navigationModel = me.getNavigationModel(),
lastFocused, focusPosition,
br = me.bufferedRenderer,
firstRecord, focusTarget;
e = e.event;
if (!me.cellFocused && me.all.getCount() && me.dataSource.getCount()) {
focusTarget = e.getTarget();
if (focusTarget && me.el.contains(focusTarget) && focusTarget !== me.el.dom && !Ext.fly(focusTarget).is(me.getCellSelector())) {
if (navigationModel.lastFocused) {
navigationModel.position = navigationModel.lastFocused;
}
me.cellFocused = true;
} else {
lastFocused = focusPosition = me.getLastFocused();
if (!focusPosition) {
targetView = me.isNormalView ? (me.lockingPartner.isVisible() ? me.lockingPartner : me.normalView) : me;
firstRecord = me.dataSource.getAt(br ? br.getFirstVisibleRowIndex() : 0);
if (firstRecord && !firstRecord.isNonData) {
focusPosition = new Ext.grid.CellContext(targetView).setPosition({
row: firstRecord,
column: 0
});
}
}
if (!focusPosition) {
e.stopEvent();
e.getTarget().blur();
return;
}
navigationModel.setPosition(focusPosition, null, e, null, true);
me.cellFocused = !!navigationModel.getPosition();
}
}
if (me.cellFocused) {
me.el.dom.setAttribute('tabindex', '-1');
}
},
onFocusLeave: function(e) {
var me = this;
if (me.cellFocused) {
if (e.toComponent !== me.lockingPartner) {
me.getNavigationModel().setPosition(null, null, e.event, null, true);
}
me.cellFocused = false;
me.focusEl = me.el;
me.focusEl.dom.setAttribute('tabindex', 0);
}
},
onRowFocus: function(rowIdx, highlight, supressFocus) {
var me = this;
if (highlight) {
me.addItemCls(rowIdx, me.focusedItemCls);
if (!supressFocus) {
me.focusRow(rowIdx);
}
} else
{
me.removeItemCls(rowIdx, me.focusedItemCls);
}
if (Ext.isIE8) {
me.repaintBorder(rowIdx + 1);
}
},
focusRow: function(row, delay) {
var me = this,
focusTask = me.getFocusTask();
if (delay) {
focusTask.delay(Ext.isNumber(delay) ? delay : 10, me.focusRow, me, [
row,
false
]);
return;
}
focusTask.cancel();
if (me.isVisible(true)) {
me.getNavigationModel().setPosition(me.getRecord(row));
}
},
focusNode: function(row, delay) {
this.focusRow(row, delay);
},
scrollRowIntoView: function(row, animate) {
row = this.getRow(row);
if (row) {
this.scrollElIntoView(row, false, animate);
}
},
focusCell: function(position, delay) {
var me = this,
cell,
focusTask = me.getFocusTask();
if (delay) {
focusTask.delay(Ext.isNumber(delay) ? delay : 10, me.focusCell, me, [
position,
false
]);
return;
}
focusTask.cancel();
if (me.isVisible(true) && (cell = me.getCellByPosition(position))) {
me.getNavigationModel().setPosition(position);
}
},
getLastFocused: function() {
var me = this,
lastFocused = me.lastFocused;
if (lastFocused && lastFocused.record && lastFocused.column) {
if (me.dataSource.indexOf(lastFocused.record) !== -1 && me.getVisibleColumnManager().indexOf(lastFocused.column) !== -1 && me.getNode(lastFocused.record)) {
return lastFocused;
}
}
},
scrollCellIntoView: function(cell, animate) {
if (cell.isCellContext) {
cell = this.getCellByPosition(cell);
}
if (cell) {
this.scrollElIntoView(cell, null, animate);
}
},
scrollElIntoView: function(el, hscroll, animate) {
var scroller = this.getScrollable();
if (scroller) {
scroller.scrollIntoView(el, hscroll, animate);
}
},
syncRowHeightBegin: function() {
var me = this,
itemEls = me.all,
ln = itemEls.count,
synchronizer = [],
RowSynchronizer = Ext.grid.locking.RowSynchronizer,
i, j, rowSync;
for (i = 0 , j = itemEls.startIndex; i < ln; i++ , j++) {
synchronizer[i] = rowSync = new RowSynchronizer(me, itemEls.elements[j]);
rowSync.reset();
}
return synchronizer;
},
syncRowHeightClear: function(synchronizer) {
var me = this,
itemEls = me.all,
ln = itemEls.count,
i;
for (i = 0; i < ln; i++) {
synchronizer[i].reset();
}
},
syncRowHeightMeasure: function(synchronizer) {
var ln = synchronizer.length,
i;
for (i = 0; i < ln; i++) {
synchronizer[i].measure();
}
},
syncRowHeightFinish: function(synchronizer, otherSynchronizer) {
var ln = synchronizer.length,
bufferedRenderer = this.bufferedRenderer,
i;
for (i = 0; i < ln; i++) {
synchronizer[i].finish(otherSynchronizer[i]);
}
if (bufferedRenderer) {
bufferedRenderer.syncRowHeightsFinish();
}
},
handleUpdate: function(store, record, operation, changedFieldNames) {
operation = operation || Ext.data.Model.EDIT;
var me = this,
rowTpl = me.rowTpl,
markDirty = me.markDirty,
dirtyCls = me.dirtyCls,
clearDirty = operation !== Ext.data.Model.EDIT,
columnsToUpdate = [],
hasVariableRowHeight = me.variableRowHeight,
updateTypeFlags = 0,
ownerCt = me.ownerCt,
cellFly = me.cellFly || (me.self.prototype.cellFly = new Ext.dom.Fly()),
oldItem, oldItemDom, oldDataRow, newItemDom, newAttrs, attLen, attName, attrIndex, overItemCls, columns, column, len, i, cellUpdateFlag, cell, fieldName, value, defaultRenderer, scope, elData, emptyValue;
if (me.viewReady) {
oldItemDom = me.getNodeByRecord(record);
if (oldItemDom) {
overItemCls = me.overItemCls;
columns = me.ownerCt.getVisibleColumnManager().getColumns();
for (i = 0 , len = columns.length; i < len; i++) {
column = columns[i];
if (column.preventUpdate) {
cell = Ext.fly(oldItemDom).down(column.getCellSelector(), true);
if (!clearDirty && markDirty) {
cellFly.attach(cell);
if (record.isModified(column.dataIndex)) {
cellFly.addCls(dirtyCls);
} else {
cellFly.removeCls(dirtyCls);
}
}
} else {
cellUpdateFlag = me.shouldUpdateCell(record, column, changedFieldNames);
if (cellUpdateFlag) {
updateTypeFlags = updateTypeFlags | cellUpdateFlag;
columnsToUpdate[columnsToUpdate.length] = column;
hasVariableRowHeight = hasVariableRowHeight || column.variableRowHeight;
}
}
}
if (me.getRowClass || !me.getRowFromItem(oldItemDom) || (updateTypeFlags & 1) ||
(oldItemDom.tBodies[0].childNodes.length > 1)) {
oldItem = Ext.fly(oldItemDom, '_internal');
elData = oldItemDom._extData;
newItemDom = me.createRowElement(record, me.dataSource.indexOf(record), columnsToUpdate);
if (oldItem.hasCls(overItemCls)) {
Ext.fly(newItemDom).addCls(overItemCls);
}
if (Ext.isIE9m && oldItemDom.mergeAttributes) {
oldItemDom.mergeAttributes(newItemDom, true);
} else {
newAttrs = newItemDom.attributes;
attLen = newAttrs.length;
for (attrIndex = 0; attrIndex < attLen; attrIndex++) {
attName = newAttrs[attrIndex].name;
if (attName !== 'id') {
oldItemDom.setAttribute(attName, newAttrs[attrIndex].value);
}
}
}
if (elData) {
elData.isSynchronized = false;
}
if (columns.length && (oldDataRow = me.getRow(oldItemDom))) {
me.updateColumns(oldDataRow, Ext.fly(newItemDom).down(me.rowSelector, true), columnsToUpdate);
}
while (rowTpl) {
if (rowTpl.syncContent) {
if (rowTpl.syncContent(oldItemDom, newItemDom, changedFieldNames ? columnsToUpdate : null) === false) {
break;
}
}
rowTpl = rowTpl.nextTpl;
}
} else
{
for (i = 0 , len = columnsToUpdate.length; i < len; i++) {
column = columnsToUpdate[i];
fieldName = column.dataIndex;
value = record.get(fieldName);
cell = Ext.fly(oldItemDom).down(column.getCellSelector(), true);
if (!clearDirty && markDirty) {
cellFly.attach(cell);
if (record.isModified(column.dataIndex)) {
cellFly.addCls(dirtyCls);
} else {
cellFly.removeCls(dirtyCls);
}
}
defaultRenderer = column.usingDefaultRenderer;
scope = defaultRenderer ? column : column.scope;
if (column.updater) {
Ext.callback(column.updater, scope, [
cell,
value,
record,
me,
me.dataSource
], 0, column, ownerCt);
} else {
if (column.renderer) {
value = Ext.callback(column.renderer, scope, [
value,
null,
record,
0,
0,
me.dataSource,
me
], 0, column, ownerCt);
}
emptyValue = value == null || value === '';
value = emptyValue ? column.emptyCellText : value;
if (column.producesHTML || emptyValue) {
cell.childNodes[0].innerHTML = value;
} else {
cell.childNodes[0].childNodes[0].data = value;
}
}
if (me.highlightClass) {
Ext.fly(cell).addCls(me.highlightClass);
if (!me.changedCells) {
me.self.prototype.changedCells = [];
me.prototype.clearChangedTask = new Ext.util.DelayedTask(me.clearChangedCells, me.prototype);
me.clearChangedTask.delay(me.unhighlightDelay);
}
me.changedCells.push({
cell: cell,
cls: me.highlightClass,
expires: Ext.Date.now() + 1000
});
}
}
}
if (clearDirty && markDirty && !record.dirty) {
Ext.fly(oldItemDom, '_internal').select('.' + dirtyCls).removeCls(dirtyCls);
}
if (hasVariableRowHeight) {
Ext.suspendLayouts();
}
me.fireEvent('itemupdate', record, me.store.indexOf(record), oldItemDom);
if (hasVariableRowHeight) {
if (me.bufferedRenderer) {
me.bufferedRenderer.refreshSize();
me.ownerGrid.updateLayout();
} else {
me.refreshSize();
}
Ext.resumeLayouts(true);
}
}
}
},
clearChangedCells: function() {
var me = this,
now = Ext.Date.now(),
changedCell;
for (var i = 0,
len = me.changedCells.length; i < len; ) {
changedCell = me.changedCells[i];
if (changedCell.expires <= now) {
Ext.fly(changedCell.cell).removeCls(changedCell.highlightClass);
Ext.Array.erase(me.changedCells, i, 1);
len--;
} else {
break;
}
}
if (len) {
me.clearChangedTask.delay(me.unhighlightDelay);
}
},
updateColumns: function(oldRowDom, newRowDom, columnsToUpdate) {
var me = this,
newAttrs, attLen, attName, attrIndex,
colCount = columnsToUpdate.length,
colIndex, column, oldCell, newCell,
cellSelector = me.getCellSelector();
if (oldRowDom.mergeAttributes) {
oldRowDom.mergeAttributes(newRowDom, true);
} else {
newAttrs = newRowDom.attributes;
attLen = newAttrs.length;
for (attrIndex = 0; attrIndex < attLen; attrIndex++) {
attName = newAttrs[attrIndex].name;
if (attName !== 'id') {
oldRowDom.setAttribute(attName, newAttrs[attrIndex].value);
}
}
}
for (colIndex = 0; colIndex < colCount; colIndex++) {
column = columnsToUpdate[colIndex];
cellSelector = me.getCellSelector(column);
oldCell = Ext.fly(oldRowDom).selectNode(cellSelector);
newCell = Ext.fly(newRowDom).selectNode(cellSelector);
Ext.fly(oldCell).syncContent(newCell);
}
},
shouldUpdateCell: function(record, column, changedFieldNames) {
if (!column.preventUpdate) {
if (column.hasCustomRenderer) {
return 1;
}
if (changedFieldNames) {
var len = changedFieldNames.length,
i, field;
for (i = 0; i < len; ++i) {
field = changedFieldNames[i];
if (field === column.dataIndex || field === record.idProperty) {
return 2;
}
}
} else {
return 2;
}
}
return 0;
},
refresh: function() {
var me = this,
scroller;
me.callParent(arguments);
me.headerCt.setSortState();
if (me.touchScroll && me.el && !me.all.getCount() && me.headerCt && me.headerCt.tooNarrow) {
scroller = me.getScrollable();
if (scroller) {
scroller.setSize({
x: me.headerCt.getTableWidth(),
y: scroller.getSize().y
});
}
}
},
processContainerEvent: function(e) {
var cmp = Ext.Component.fromElement(e.target.parentNode);
if (cmp && cmp.up(this.ownerCt)) {
return false;
}
},
processItemEvent: function(record, item, rowIndex, e) {
var me = this,
self = me.self,
map = self.EventMap,
type = e.type,
features = me.features,
len = features.length,
i, cellIndex, result, feature, column,
navModel = me.getNavigationModel(),
eventPosition = e.position = me.eventPosition || (me.eventPosition = new Ext.grid.CellContext()),
focusPosition, row, cell;
if (Ext.isIE && type === 'mouseup' && !e.within(me.el)) {
return false;
}
if (me.indexInStore(item) !== -1) {
row = eventPosition.rowElement = Ext.fly(item).down(me.rowSelector, true);
if (Ext.String.startsWith(e.type, 'key') && (focusPosition = navModel.getPosition())) {
cell = (cell = navModel.getCell()) && cell.dom;
column = focusPosition.column;
}
if (!cell) {
cell = e.getTarget(me.getCellSelector(), row);
}
type = self.TouchEventMap[type] || type;
if (cell) {
if (!cell.parentNode) {
return false;
}
if (!column) {
column = me.getHeaderByCell(cell);
}
cellIndex = me.ownerCt.getColumnManager().getHeaderIndex(column);
} else {
cellIndex = -1;
}
eventPosition.setAll(me, rowIndex, column ? me.getVisibleColumnManager().getHeaderIndex(column) : -1, record, column);
eventPosition.cellElement = cell;
result = me.fireEvent('uievent', type, me, cell, rowIndex, cellIndex, e, record, row);
if ((result === false || me.callParent(arguments) === false)) {
return false;
}
for (i = 0; i < len; ++i) {
feature = features[i];
if (feature.wrapsItem) {
if (feature.vetoEvent(record, row, rowIndex, e) === false) {
me.processSpecialEvent(e);
e.preventDefault();
return false;
}
}
}
if (cell && type !== 'mouseover' && type !== 'mouseout') {
result = !
((me['onBeforeCell' + map[type]](cell, cellIndex, record, row, rowIndex, e) === false) || (me.fireEvent('beforecell' + type, me, cell, cellIndex, record, row, rowIndex, e) === false) || (me['onCell' + map[type]](cell, cellIndex, record, row, rowIndex, e) === false) || (me.fireEvent('cell' + type, me, cell, cellIndex, record, row, rowIndex, e) === false));
}
if (result !== false) {
result = me.fireEvent('row' + type, me, record, row, rowIndex, e);
}
return result;
} else {
this.processSpecialEvent(e);
e.preventDefault();
return false;
}
},
processSpecialEvent: function(e) {
var me = this,
features = me.features,
ln = features.length,
type = e.type,
i, feature, prefix, featureTarget, beforeArgs, args,
panel = me.ownerCt;
me.callParent(arguments);
if (type === 'mouseover' || type === 'mouseout') {
return;
}
type = me.self.TouchEventMap[type] || type;
for (i = 0; i < ln; i++) {
feature = features[i];
if (feature.hasFeatureEvent) {
featureTarget = e.getTarget(feature.eventSelector, me.getTargetEl());
if (featureTarget) {
prefix = feature.eventPrefix;
beforeArgs = feature.getFireEventArgs('before' + prefix + type, me, featureTarget, e);
args = feature.getFireEventArgs(prefix + type, me, featureTarget, e);
if (
(me.fireEvent.apply(me, beforeArgs) === false) ||
(panel.fireEvent.apply(panel, beforeArgs) === false) ||
(me.fireEvent.apply(me, args) === false) ||
(panel.fireEvent.apply(panel, args) === false)) {
return false;
}
}
}
}
return true;
},
onCellMouseDown: Ext.emptyFn,
onCellLongPress: Ext.emptyFn,
onCellMouseUp: Ext.emptyFn,
onCellClick: Ext.emptyFn,
onCellDblClick: Ext.emptyFn,
onCellContextMenu: Ext.emptyFn,
onCellKeyDown: Ext.emptyFn,
onCellKeyUp: Ext.emptyFn,
onCellKeyPress: Ext.emptyFn,
onBeforeCellMouseDown: Ext.emptyFn,
onBeforeCellLongPress: Ext.emptyFn,
onBeforeCellMouseUp: Ext.emptyFn,
onBeforeCellClick: Ext.emptyFn,
onBeforeCellDblClick: Ext.emptyFn,
onBeforeCellContextMenu: Ext.emptyFn,
onBeforeCellKeyDown: Ext.emptyFn,
onBeforeCellKeyUp: Ext.emptyFn,
onBeforeCellKeyPress: Ext.emptyFn,
expandToFit: function(header) {
this.autoSizeColumn(header);
},
autoSizeColumn: function(header) {
if (Ext.isNumber(header)) {
header = this.getGridColumns()[header];
}
if (header) {
if (header.isGroupHeader) {
header.autoSize();
return;
}
delete header.flex;
header.setWidth(this.getMaxContentWidth(header));
}
},
getMaxContentWidth: function(header) {
var me = this,
cells = me.el.query(header.getCellInnerSelector()),
originalWidth = header.getWidth(),
i = 0,
ln = cells.length,
columnSizer = me.body.select(me.getColumnSizerSelector(header)),
max = Math.max,
widthAdjust = 0,
maxWidth;
if (ln > 0) {
if (Ext.supports.ScrollWidthInlinePaddingBug) {
widthAdjust += me.getCellPaddingAfter(cells[0]);
}
if (me.columnLines) {
widthAdjust += Ext.fly(cells[0].parentNode).getBorderWidth('lr');
}
}
columnSizer.setWidth(1);
header.textEl.setStyle({
"text-overflow": 'clip',
display: 'table-cell'
});
maxWidth = header.textEl.dom.offsetWidth + header.titleEl.getPadding('lr');
header.textEl.setStyle({
"text-overflow": '',
display: ''
});
for (; i < ln; i++) {
maxWidth = max(maxWidth, cells[i].scrollWidth);
}
maxWidth += widthAdjust;
maxWidth = max(maxWidth + 1, 40);
columnSizer.setWidth(originalWidth);
return maxWidth;
},
getPositionByEvent: function(e) {
var me = this,
cellNode = e.getTarget(me.cellSelector),
rowNode = e.getTarget(me.itemSelector),
record = me.getRecord(rowNode),
header = me.getHeaderByCell(cellNode);
return me.getPosition(record, header);
},
getHeaderByCell: function(cell) {
if (cell) {
return this.ownerCt.getVisibleColumnManager().getHeaderById(cell.getAttribute('data-columnId'));
}
return false;
},
walkCells: function(pos, direction, e, preventWrap, verifierFn, scope) {
if (!pos) {
return false;
}
var me = this,
row = typeof pos.row === 'number' ? pos.row : pos.rowIdx,
column = typeof pos.column === 'number' ? pos.column : pos.colIdx,
rowCount = me.dataSource.getCount(),
columns = me.ownerCt.getVisibleColumnManager(),
firstIndex = columns.getHeaderIndex(columns.getFirst()),
lastIndex = columns.getHeaderIndex(columns.getLast()),
newRow = row,
newColumn = column,
activeHeader = columns.getHeaderAtIndex(column);
if (!activeHeader || activeHeader.hidden || !rowCount) {
return false;
}
e = e || {};
direction = direction.toLowerCase();
switch (direction) {
case 'right':
if (column === lastIndex) {
if (preventWrap || row === rowCount - 1) {
return false;
}
if (!e.ctrlKey) {
newRow = me.walkRows(row, 1);
if (newRow !== row) {
newColumn = firstIndex;
}
}
} else
{
if (!e.ctrlKey) {
newColumn = columns.getHeaderIndex(columns.getNextSibling(activeHeader));
} else {
newColumn = lastIndex;
}
};
break;
case 'left':
if (column === firstIndex) {
if (preventWrap || row === 0) {
return false;
}
if (!e.ctrlKey) {
newRow = me.walkRows(row, -1);
if (newRow !== row) {
newColumn = lastIndex;
}
}
} else
{
if (!e.ctrlKey) {
newColumn = columns.getHeaderIndex(columns.getPreviousSibling(activeHeader));
} else {
newColumn = firstIndex;
}
};
break;
case 'up':
if (row === 0) {
return false;
} else
{
if (!e.ctrlKey) {
newRow = me.walkRows(row, -1);
} else {
newRow = me.walkRows(-1, 1);
}
};
break;
case 'down':
if (row === rowCount - 1) {
return false;
} else
{
if (!e.ctrlKey) {
newRow = me.walkRows(row, 1);
} else {
newRow = me.walkRows(rowCount, -1);
}
};
break;
}
if (verifierFn && verifierFn.call(scope || me, {
row: newRow,
column: newColumn
}) !== true) {
return false;
}
newColumn = columns.getHeaderAtIndex(newColumn);
return new Ext.grid.CellContext(me).setPosition(newRow, newColumn);
},
walkRows: function(startRow, distance) {
var me = this,
store = me.dataSource,
moved = 0,
lastValid = startRow,
node,
limit = (distance < 0) ? 0 : (store.isBufferedStore ? store.getTotalCount() : store.getCount()) - 1,
increment = limit ? 1 : -1,
result = startRow;
do {
if (limit ? result >= limit : result <= limit) {
return lastValid || limit;
}
result += increment;
if ((node = Ext.fly(me.getRow(result))) && node.isVisible(true)) {
moved += increment;
lastValid = result;
}
} while (
moved !== distance);
return result;
},
walkRecs: function(startRec, distance) {
var me = this,
store = me.dataSource,
moved = 0,
lastValid = startRec,
node,
limit = (distance < 0) ? 0 : (store.isBufferedStore ? store.getTotalCount() : store.getCount()) - 1,
increment = limit ? 1 : -1,
testIndex = store.indexOf(startRec),
rec;
do {
if (limit ? testIndex >= limit : testIndex <= limit) {
return lastValid;
}
testIndex += increment;
rec = store.getAt(testIndex);
if (!rec.isCollapsedPlaceholder && (node = Ext.fly(me.getNodeByRecord(rec))) && node.isVisible(true)) {
moved += increment;
lastValid = rec;
}
} while (
moved !== distance);
return lastValid;
},
getFirstVisibleRowIndex: function() {
var me = this,
count = (me.dataSource.isBufferedStore ? me.dataSource.getTotalCount() : me.dataSource.getCount()),
result = me.indexOf(me.all.first()) - 1;
do {
result += 1;
if (result === count) {
return;
}
} while (!Ext.fly(me.getRow(result)).isVisible(true));
return result;
},
getLastVisibleRowIndex: function() {
var me = this,
result = me.indexOf(me.all.last());
do {
result -= 1;
if (result === -1) {
return;
}
} while (!Ext.fly(me.getRow(result)).isVisible(true));
return result;
},
getHeaderCt: function() {
return this.headerCt;
},
getPosition: function(record, header) {
return new Ext.grid.CellContext(this).setPosition(record, header);
},
onDestroy: function() {
var me = this,
features = me.featuresMC,
len, i;
if (features) {
for (i = 0 , len = features.getCount(); i < len; ++i) {
features.getAt(i).destroy();
}
}
me.cellFly = me.featuresMC = null;
me.callParent(arguments);
},
onReplace: function(store, startIndex, oldRecords, newRecords) {
var me = this,
bufferedRenderer = me.bufferedRenderer;
if (me.rendered && bufferedRenderer) {
bufferedRenderer.onReplace(store, startIndex, oldRecords, newRecords);
} else {
me.callParent(arguments);
}
me.setPendingStripe(startIndex);
},
onAdd: function(store, records, index) {
var me = this,
bufferedRenderer = me.bufferedRenderer;
if (me.rendered && bufferedRenderer) {
bufferedRenderer.onReplace(store, index, [], records);
} else {
me.callParent(arguments);
}
me.setPendingStripe(index);
},
onRemove: function(store, records, index) {
var me = this,
bufferedRenderer = me.bufferedRenderer;
if (me.rendered && bufferedRenderer) {
bufferedRenderer.onReplace(store, index, records, []);
} else {
me.callParent(arguments);
}
me.setPendingStripe(index);
},
onDataRefresh: function() {
var me = this,
owner = me.ownerCt;
if (owner && owner.isCollapsingOrExpanding === 2) {
owner.on('expand', me.onDataRefresh, me, {
single: true
});
return;
}
me.callParent();
},
getViewRange: function() {
var me = this;
if (me.bufferedRenderer) {
return me.bufferedRenderer.getViewRange();
}
return me.callParent();
},
setPendingStripe: function(index) {
var current = this.stripeOnUpdate;
if (current === null) {
current = index;
} else {
current = Math.min(current, index);
}
this.stripeOnUpdate = current;
},
onEndUpdate: function() {
var me = this,
stripeOnUpdate = me.stripeOnUpdate,
startIndex = me.all.startIndex;
if (me.rendered && (stripeOnUpdate || stripeOnUpdate === 0)) {
if (stripeOnUpdate < startIndex) {
stripeOnUpdate = startIndex;
}
me.doStripeRows(stripeOnUpdate);
me.stripeOnUpdate = null;
}
me.callParent(arguments);
},
doStripeRows: function(startRow, endRow) {
var me = this,
rows, rowsLn, i, row;
if (me.rendered && me.stripeRows) {
rows = me.getNodes(startRow, endRow);
for (i = 0 , rowsLn = rows.length; i < rowsLn; i++) {
row = rows[i];
row.className = row.className.replace(me.rowClsRe, ' ');
startRow++;
if (startRow % 2 === 0) {
row.className += (' ' + me.altRowCls);
}
}
}
},
hasActiveFeature: function() {
return (this.isGrouping && this.store.isGrouped()) || this.isRowWrapped;
},
getCellPaddingAfter: function(cell) {
return Ext.fly(cell).getPadding('r');
},
privates: {
refreshScroll: function() {
var me = this,
bufferedRenderer = me.bufferedRenderer;
if (bufferedRenderer) {
bufferedRenderer.refreshSize();
} else {
me.callParent();
}
}
}
});
Ext.define('Ext.grid.Panel', {
extend: 'Ext.panel.Table',
requires: [
'Ext.view.Table'
],
alias: [
'widget.gridpanel',
'widget.grid'
],
alternateClassName: [
'Ext.list.ListView',
'Ext.ListView',
'Ext.grid.GridPanel'
],
viewType: 'tableview',
lockable: false,
rowLines: true
});
Ext.define('Ext.form.CheckboxManager', {
extend: 'Ext.util.MixedCollection',
singleton: true,
getByName: function(name, formId) {
return this.filterBy(function(item) {
return item.name === name && item.getFormId() === formId;
});
}
});
Ext.define('Ext.form.field.Checkbox', {
extend: 'Ext.form.field.Base',
alias: [
'widget.checkboxfield',
'widget.checkbox'
],
alternateClassName: 'Ext.form.Checkbox',
requires: [
'Ext.XTemplate',
'Ext.form.CheckboxManager'
],
stretchInputElFixed: false,
childEls: [
'boxLabelEl',
'innerWrapEl'
],
fieldSubTpl: [
'<div id="{cmpId}-innerWrapEl" data-ref="innerWrapEl" class="{wrapInnerCls} {noBoxLabelCls}" role="presentation">',
'<tpl if="labelAlignedBefore">',
'{beforeBoxLabelTpl}',
'<label id="{cmpId}-boxLabelEl" data-ref="boxLabelEl" {boxLabelAttrTpl} class="{boxLabelCls} ',
'{boxLabelCls}-{ui} {boxLabelCls}-{boxLabelAlign} {childElCls}" for="{id}">',
'{beforeBoxLabelTextTpl}',
'{boxLabel}',
'{afterBoxLabelTextTpl}',
'</label>',
'{afterBoxLabelTpl}',
'</tpl>',
'<input type="button" id="{id}" data-ref="inputEl" role="{role}" {inputAttrTpl}',
'<tpl if="tabIdx != null"> tabindex="{tabIdx}"</tpl>',
'<tpl if="disabled"> disabled="disabled"</tpl>',
'<tpl if="fieldStyle"> style="{fieldStyle}"</tpl>',
' class="{fieldCls} {typeCls} {typeCls}-{ui} {inputCls} {inputCls}-{ui} {childElCls} {afterLabelCls}" autocomplete="off" hidefocus="true" />',
'<tpl if="!labelAlignedBefore">',
'{beforeBoxLabelTpl}',
'<label id="{cmpId}-boxLabelEl" data-ref="boxLabelEl" {boxLabelAttrTpl} class="{boxLabelCls} ',
'{boxLabelCls}-{ui} {boxLabelCls}-{boxLabelAlign} {childElCls}" for="{id}">',
'{beforeBoxLabelTextTpl}',
'{boxLabel}',
'{afterBoxLabelTextTpl}',
'</label>',
'{afterBoxLabelTpl}',
'</tpl>',
'</div>',
{
disableFormats: true,
compiled: true
}
],
publishes: {
checked: 1
},
subTplInsertions: [
'beforeBoxLabelTpl',
'afterBoxLabelTpl',
'beforeBoxLabelTextTpl',
'afterBoxLabelTextTpl',
'boxLabelAttrTpl',
'inputAttrTpl'
],
isCheckbox: true,
focusCls: 'form-checkbox-focus',
fieldBodyCls: Ext.baseCSSPrefix + 'form-cb-wrap',
checked: false,
checkedCls: Ext.baseCSSPrefix + 'form-cb-checked',
boxLabelCls: Ext.baseCSSPrefix + 'form-cb-label',
boxLabelAlign: 'after',
afterLabelCls: Ext.baseCSSPrefix + 'form-cb-after',
wrapInnerCls: Ext.baseCSSPrefix + 'form-cb-wrap-inner',
noBoxLabelCls: Ext.baseCSSPrefix + 'form-cb-wrap-inner-no-box-label',
inputValue: 'on',
checkChangeEvents: [],
inputType: 'checkbox',
isTextInput: false,
ariaRole: 'checkbox',
onRe: /^on$/i,
inputCls: Ext.baseCSSPrefix + 'form-cb',
initComponent: function() {
var me = this,
value = me.value;
if (value !== undefined) {
me.checked = me.isChecked(value, me.inputValue);
}
me.callParent(arguments);
me.getManager().add(me);
},
initValue: function() {
var me = this,
checked = !!me.checked;
me.originalValue = me.lastValue = checked;
me.setValue(checked);
},
getElConfig: function() {
var me = this;
if (me.isChecked(me.rawValue, me.inputValue)) {
me.addCls(me.checkedCls);
}
return me.callParent();
},
getSubTplData: function(fieldData) {
var me = this,
boxLabel = me.boxLabel,
boxLabelAlign = me.boxLabelAlign,
labelAlignedBefore = boxLabelAlign === 'before';
return Ext.apply(me.callParent(arguments), {
disabled: me.readOnly || me.disabled,
wrapInnerCls: me.wrapInnerCls,
boxLabel: boxLabel,
boxLabelCls: me.boxLabelCls,
boxLabelAlign: boxLabelAlign,
labelAlignedBefore: labelAlignedBefore,
afterLabelCls: labelAlignedBefore ? me.afterLabelCls : '',
noBoxLabelCls: !boxLabel ? me.noBoxLabelCls : '',
role: me.ariaRole
});
},
initEvents: function() {
var me = this;
me.callParent();
me.mon(me.inputEl, 'click', me.onBoxClick, me, {
translate: false
});
},
setBoxLabel: function(boxLabel) {
var me = this;
me.boxLabel = boxLabel;
if (me.rendered) {
me.boxLabelEl.setHtml(boxLabel);
me.innerWrapEl[boxLabel ? 'removeCls' : 'addCls'](me.noBoxLabelCls);
me.updateLayout();
}
},
onBoxClick: function() {
var me = this;
if (!me.disabled && !me.readOnly) {
me.setValue(!me.checked);
}
},
getRawValue: function() {
return this.checked;
},
getValue: function() {
return this.checked;
},
getSubmitValue: function() {
var unchecked = this.uncheckedValue,
uncheckedVal = Ext.isDefined(unchecked) ? unchecked : null;
return this.checked ? this.inputValue : uncheckedVal;
},
isChecked: function(rawValue, inputValue) {
return (rawValue === true || rawValue === 'true' || rawValue === '1' || rawValue === 1 || (((Ext.isString(rawValue) || Ext.isNumber(rawValue)) && inputValue) ? rawValue == inputValue : this.onRe.test(rawValue)));
},
setRawValue: function(value) {
var me = this,
inputEl = me.inputEl,
checked = me.isChecked(value, me.inputValue);
if (inputEl) {
me[checked ? 'addCls' : 'removeCls'](me.checkedCls);
}
me.checked = me.rawValue = checked;
if (!me.duringSetValue) {
me.lastValue = checked;
}
return checked;
},
setValue: function(checked) {
var me = this,
boxes, i, len, box;
if (Ext.isArray(checked)) {
boxes = me.getManager().getByName(me.name, me.getFormId()).items;
len = boxes.length;
for (i = 0; i < len; ++i) {
box = boxes[i];
box.setValue(Ext.Array.contains(checked, box.inputValue));
}
} else {
me.duringSetValue = true;
me.callParent(arguments);
delete me.duringSetValue;
}
return me;
},
valueToRaw: Ext.identityFn,
onChange: function(newVal, oldVal) {
var me = this,
handler = me.handler;
if (handler) {
Ext.callback(handler, me.scope, [
me,
newVal
], 0, me);
}
me.callParent(arguments);
if (me.reference && me.publishState) {
me.publishState('checked', newVal);
}
},
resetOriginalValue: function(
fromBoxInGroup) {
var me = this,
boxes, box, len, i;
if (!fromBoxInGroup) {
boxes = me.getManager().getByName(me.name, me.getFormId()).items;
len = boxes.length;
for (i = 0; i < len; ++i) {
box = boxes[i];
if (box !== me) {
boxes[i].resetOriginalValue(true);
}
}
}
me.callParent();
},
beforeDestroy: function() {
this.callParent();
this.getManager().removeAtKey(this.id);
},
getManager: function() {
return Ext.form.CheckboxManager;
},
onEnable: function() {
var me = this,
inputEl = me.inputEl;
me.callParent();
if (inputEl) {
inputEl.dom.disabled = me.readOnly;
}
},
setReadOnly: function(readOnly) {
var me = this,
inputEl = me.inputEl;
if (inputEl) {
inputEl.dom.disabled = !!readOnly || me.disabled;
}
me.callParent(arguments);
},
getFormId: function() {
var me = this,
form;
if (!me.formId) {
form = me.up('form');
if (form) {
me.formId = form.id;
}
}
return me.formId;
}
});
Ext.define('Ext.app.bindinspector.Util', {
singleton: true,
getChildStub: function(name, parent) {
var val, children;
if (parent) {
children = parent.children;
if (children) {
val = children[name];
}
}
return val || null;
},
valueRenderer: function(v) {
var s;
if (v === undefined) {
return 'undefined';
} else if (v === null) {
return 'null';
} else if (Ext.isString(v)) {
return v;
} else if (Ext.isDate(v)) {
return Ext.Date.format(v, 'c');
} else if (v && v.isModel) {
s = v.entityName;
return Ext.String.format('Model({0}, {1})', s.replace('noconflict.', ''), v.getId());
} else if (v && v.isStore) {
s = v.entityName || 'Anonymous';
return 'Store{' + s.replace('noconflict.', '') + '}';
}
return v;
},
buildBindData: function(bind) {
var out = [],
key, o;
for (key in bind) {
o = bind[key];
out.push({
key: key,
descriptor: o.descriptor,
tokens: o.tokens,
value: o.value,
binding: o
});
}
return out;
}
});
Ext.define('Ext.app.bindinspector.ComponentDetail', {
extend: 'Ext.panel.Panel',
alias: 'widget.bindinspector-componentdetail',
requires: [
'Ext.form.field.Display',
'Ext.grid.Panel',
'Ext.layout.container.VBox',
'Ext.form.field.Checkbox',
'Ext.app.bindinspector.Util'
],
layout: 'border',
activeCls: Ext.baseCSSPrefix + 'bindinspector-stub-active',
descriptorCls: Ext.baseCSSPrefix + 'bindinspector-descriptor',
multipleCls: Ext.baseCSSPrefix + 'bindinspector-mult-val',
directCls: Ext.baseCSSPrefix + 'bindinspector-direct-val',
inheritedCls: Ext.baseCSSPrefix + 'bindinspector-inherited-val',
componentKeyCls: Ext.baseCSSPrefix + 'bindinspector-comp-key',
componentDescCls: Ext.baseCSSPrefix + 'bindinspector-comp-desc',
componentValCls: Ext.baseCSSPrefix + 'bindinspector-comp-val',
lastItemCls: Ext.baseCSSPrefix + 'bindinspector-last-item',
vmPreviewDefault: {
xtype: 'container',
region: 'east',
split: true,
width: '50%',
cls: Ext.baseCSSPrefix + 'bindinspector-prev-default',
padding: 20,
layout: {
type: 'hbox',
align: 'middle',
pack: 'center'
},
items: [
{
xtype: 'component',
flex: 1,
html: 'Select a component with a ViewModel (or inherited ViewModel) from the ComponentList to view the ViewModel details'
}
]
},
initComponent: function() {
var me = this,
comp = me.component || {},
env = me.env,
publishes = comp.publishes,
bindings = comp.bindings,
title = 'Bindings &nbsp;&nbsp;&nbsp;⇒ &nbsp;&nbsp;&nbsp;',
vm = env.getInheritedVM(comp),
bindData, publishesTbar;
me.bindingsPreviewDefault = {
xtype: 'panel',
border: false,
region: 'center',
cls: Ext.baseCSSPrefix + 'bindinspector-prev-default',
bodyPadding: 20,
layout: {
type: 'hbox',
align: 'middle',
pack: 'center'
},
items: [
{
xtype: 'component',
flex: 1,
html: 'Select a component with bindings from the ComponentList to view the bindings details along with the component\'s inherited ViewModel'
}
],
dockedItems: [
{
xtype: 'toolbar',
dock: 'top',
defaultButtonUI: 'default',
items: [
'->',
{
text: 'Open in dedicated tab',
handler: function(btn) {
btn.up('bindinspector-container').onComponentDblclick(null, comp);
}
}
]
}
]
};
if (comp.reference) {
title += '[' + comp.reference + '] &bull; ';
}
bindData = comp.bindData || Ext.app.bindinspector.Util.buildBindData(bindings);
if (publishes) {
publishesTbar = [
{
xtype: 'component',
html: 'Publishes: &nbsp;&nbsp;<span style="color: #5C5C5C;font-size: 14px;line-height: 14px;">' + Ext.Object.getKeys(publishes).join(' &bull; ') + '</span>'
}
];
}
me.bindingsGrid = {
xtype: 'gridpanel',
title: title += comp.id,
header: {
items: [
{
xtype: 'button',
text: 'Open in dedicated tab',
ui: 'default-toolbar',
handler: function(btn) {
btn.up('bindinspector-container').onComponentDblclick(null, comp);
}
}
]
},
region: 'center',
cls: Ext.baseCSSPrefix + 'bindinspector-compdetail-grid',
flex: 1,
hideHeaders: true,
store: {
model: me.BindingModel,
data: bindData
},
columns: [
{
flex: 1,
scope: me,
renderer: me.bindingRenderer
}
],
tbar: publishesTbar,
bbar: [
{
xtype: 'checkboxfield',
itemId: 'highlightToggle',
boxLabel: 'Highlight VM target nodes on binding selection',
checked: true,
listeners: {
scope: me,
change: me.onHighlightChange
}
}
],
viewConfig: {
stripeRows: false,
trackOver: false,
getRowClass: function(record, index, rowParams, store) {
var cls = [];
if (index === store.getCount() - 1) {
cls.push(me.lastItemCls);
}
return cls.join(' ');
}
},
listeners: {
scope: me,
cellclick: me.onCellClick,
selectionchange: me.onSelectionChange
}
};
me.viewModelTree = {
xtype: 'bindinspector-viewmodeldetail',
itemId: 'vm-' + vm.id,
vm: vm,
region: 'east',
split: true,
width: '50%',
height: '50%'
};
me.items = [];
me.items.push(bindings ? me.bindingsGrid : me.bindingsPreviewDefault);
me.items.push(vm ? me.viewModelTree : me.vmPreviewDefault);
me.callParent(arguments);
},
bindingRenderer: function(v, meta, rec) {
var me = this,
binding = rec.get('binding'),
key = rec.get('key'),
descriptor = me.descriptorRenderer(rec.get('descriptor'), meta, rec),
value = Ext.app.bindinspector.Util.valueRenderer(rec.get('value')),
bindingType = 'Direct';
if (Ext.isEmpty(value) || value === 'null') {
value = '<i>No value found</i>';
}
key = '<span class="' + me.componentKeyCls + '">' + key + ': </span>';
descriptor = '<span class="' + me.componentDescCls + '">' + descriptor + '</span>';
value = '<span class="' + me.componentValCls + '">' + value + '</span>';
if (binding.isTemplateBinding) {
bindingType = 'Template';
} else if (binding.isMultiBinding) {
bindingType = 'Multi';
}
bindingType = Ext.util.Format.format('<div data-qtip="Binding Type" data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" class="' + Ext.baseCSSPrefix + 'bindinspector-bind-type">{0}</div>', bindingType);
return key + descriptor + '<br>' + value + bindingType;
},
onHighlightChange: function(field) {
var compDetail = this.down('gridpanel'),
selModel = compDetail.getSelectionModel();
if (!field.checked) {
this.onSelectionChange(selModel, null, true);
} else {
this.onSelectionChange(selModel, selModel.getSelection());
}
},
onSelectionChange: function(selModel, selected, clear) {
var vmDetail = this.down('bindinspector-viewmodeldetail'),
store = vmDetail.getStore(),
tokens, binding, highlight, root, targets, highlighted;
if ((selected && selected.length === 0) || clear === true) {
store.suspendEvents();
vmDetail.getStore().getRootNode().cascadeBy({
before: function(node) {
node.set('highlighted', false);
}
});
store.resumeEvents();
vmDetail.getView().refresh();
return;
}
selected = selected[0];
tokens = selected.get('tokens');
binding = selected.get('binding');
highlight = this.down('#highlightToggle').checked;
store = vmDetail.getStore();
root = store.getRootNode();
targets = [];
if (tokens && highlight) {
if (binding.isTemplateBinding) {
Ext.Array.forEach(tokens, function(token) {
targets.push(root.findChild('name', token[0]));
}, this);
} else if (binding.isMultiBinding) {} else
{
targets.push(root.findChild('name', tokens[0]));
}
}
store.suspendEvents();
root.cascadeBy({
before: function(node) {
highlighted = targets.length === 0;
Ext.Array.forEach(targets, function(target) {
if (node === target || node.isAncestor(target)) {
highlighted = true;
}
});
node.set('highlighted', highlighted || -1);
}
});
store.resumeEvents();
vmDetail.getView().refresh();
vmDetail.getSelectionModel().select(targets[0]);
},
onCellClick: function(view, cell, colIdx, record, row, rowIdx, e) {
var target = e.getTarget('.' + this.activeCls),
path;
if (target) {
path = target.getAttribute('data-path');
this.showPath(path);
}
},
showPath: function(path) {
this.selectPath(this.down('bindinspector-viewmodeldetail'), path);
},
selectPath: function(tab, path) {
var node = tab.getRootNode(),
parts = path.split('.'),
len = parts.length,
i;
for (i = 0; node && i < len; ++i) {
node = this.getChildByKey(node, parts[i]);
}
if (node) {
tab.getSelectionModel().select(node);
}
},
getChildByKey: function(node, key) {
var childNodes = node.childNodes;
if (childNodes) {
return Ext.Array.findBy(childNodes, function(child) {
return child.get('name') === key;
});
}
return null;
},
descriptorRenderer: function(v, meta, rec) {
var binding = rec.get('binding'),
descriptor = rec.get('descriptor'),
tokens = rec.get('tokens');
v = v || '';
if (binding.isTemplateBinding) {
Ext.Array.forEach(tokens, function(token) {
var tokenRe = new RegExp('{' + token.join('\\.') + '}', 'g');
v = v.replace(tokenRe, this.parseTokens(token));
}, this);
} else if (binding.isMultiBinding) {} else
{
return v.replace(descriptor, this.parseTokens(tokens));
}
return Ext.String.htmlEncode(v);
},
parseTokens: function(tokens) {
var me = this,
out = [],
vm = me.env.getInheritedVM(me.component),
currPath = '',
currParent = vm.rootStub,
direct = false,
inherited = false,
addlCls = '',
tip = '',
baseToken = '',
ownerVMs, len, vmPlural;
tokens = tokens || [];
Ext.Array.forEach(tokens, function(token) {
var stub = Ext.app.bindinspector.Util.getChildStub(token, currParent),
cls = '',
value;
if (stub) {
value = stub.value;
if (value !== undefined) {
cls = me.activeCls;
}
} else {}
out.push('<span data-path="' + currPath + token + '" class="stub ' + cls + '">' + token + '</span>');
currPath += token + '.';
currParent = stub;
}, me);
if (tokens[0]) {
baseToken = tokens[0];
ownerVMs = vm.dataMap[tokens[0]].ownerVMs;
len = ownerVMs.length;
Ext.Array.forEach(ownerVMs, function(v) {
if (v.id === vm.id) {
direct = true;
}
if (v.id !== vm.id) {
inherited = true;
}
});
}
if (direct && inherited) {
addlCls += ' ' + me.multipleCls;
vmPlural = len > 1 ? 'VMs' : 'VM';
tip = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="<b>' + baseToken + '</b>&nbsp; provided by this VM and ' + (len - 1) + ' ancestor ' + vmPlural + '"';
} else if (direct) {
addlCls += ' ' + me.directCls;
tip = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="<b>' + baseToken + '</b>&nbsp; is provided by this VM"';
} else if (inherited) {
addlCls += ' ' + me.inheritedCls;
vmPlural = len > 1 ? 'VMs' : 'VM';
tip = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="<b>' + baseToken + '</b>&nbsp; is provided by ' + len + ' ancestor ' + vmPlural + '"';
}
return '<span ' + tip + 'class="' + me.descriptorCls + addlCls + '">{' + out.join('.') + '}</span>';
}
}, function() {
this.prototype.BindingModel = Ext.define(null, {
extend: 'Ext.data.Model',
fields: [
'key',
'descriptor',
'tokens',
'value',
'binding'
]
});
});
Ext.define('Ext.tree.View', {
extend: 'Ext.view.Table',
alias: 'widget.treeview',
config: {
selectionModel: {
type: 'treemodel'
}
},
isTreeView: true,
loadingCls: Ext.baseCSSPrefix + 'grid-tree-loading',
expandedCls: Ext.baseCSSPrefix + 'grid-tree-node-expanded',
leafCls: Ext.baseCSSPrefix + 'grid-tree-node-leaf',
expanderSelector: '.' + Ext.baseCSSPrefix + 'tree-expander',
checkboxSelector: '.' + Ext.baseCSSPrefix + 'tree-checkbox',
expanderIconOverCls: Ext.baseCSSPrefix + 'tree-expander-over',
nodeAnimWrapCls: Ext.baseCSSPrefix + 'tree-animator-wrap',
ariaRole: 'tree',
loadMask: false,
rootVisible: true,
expandDuration: 250,
collapseDuration: 250,
toggleOnDblClick: true,
stripeRows: false,
uiFields: {
checked: 1,
icon: 1,
iconCls: 1
},
rowFields: {
expanded: 1,
loaded: 1,
expandable: 1,
leaf: 1,
loading: 1,
qtip: 1,
qtitle: 1,
cls: 1
},
treeRowTpl: [
'{%',
'this.processRowValues(values);',
'this.nextTpl.applyOut(values, out, parent);',
'%}',
{
priority: 10,
processRowValues: function(rowValues) {
var record = rowValues.record,
view = rowValues.view;
rowValues.rowAttr['data-qtip'] = record.get('qtip') || '';
rowValues.rowAttr['data-qtitle'] = record.get('qtitle') || '';
if (record.isExpanded()) {
rowValues.rowClasses.push(view.expandedCls);
}
if (record.isLeaf()) {
rowValues.rowClasses.push(view.leafCls);
}
if (record.isLoading()) {
rowValues.rowClasses.push(view.loadingCls);
}
}
}
],
initComponent: function() {
var me = this;
if (me.bufferedRenderer) {
me.animate = false;
} else if (me.initialConfig.animate === undefined) {
me.animate = Ext.enableFx;
}
me.store = me.panel.getStore();
me.onRootChange(me.store.getRoot());
me.animQueue = {};
me.animWraps = {};
me.callParent();
me.store.setRootVisible(me.rootVisible);
me.addRowTpl(Ext.XTemplate.getTpl(me, 'treeRowTpl'));
},
onFillComplete: function(treeStore, fillRoot, newNodes) {
var me = this,
store = me.store,
start = store.indexOf(newNodes[0]);
fillRoot.triggerUIUpdate();
if (!newNodes.length || start === -1) {
return;
}
me.onAdd(me.store, newNodes, start);
me.refreshPartner();
},
refreshPartner: function() {
var partner = this.lockingPartner;
if (partner) {
partner.refresh();
}
},
afterRender: function() {
var me = this;
me.callParent();
me.el.on({
scope: me,
delegate: me.expanderSelector,
mouseover: me.onExpanderMouseOver,
mouseout: me.onExpanderMouseOut,
click: {
delegate: me.checkboxSelector,
fn: me.onCheckboxChange,
scope: me
}
});
},
afterComponentLayout: function(width, height, prevWidth, prevHeight) {
var scroller = this.getScrollable();
this.callParent([
width,
height,
prevWidth,
prevHeight
]);
if (scroller && !this.bufferedRenderer) {
scroller.refresh();
}
},
processUIEvent: function(e) {
if (e.getTarget('.' + this.nodeAnimWrapCls, this.el)) {
return false;
}
return this.callParent([
e
]);
},
setRootNode: function(node) {
this.node = node;
},
onCheckboxChange: function(e, t) {
var me = this,
item = e.getTarget(me.getItemSelector(), me.getTargetEl());
if (item) {
me.onCheckChange(me.getRecord(item));
}
},
onCheckChange: function(record) {
var checked = record.get('checked');
if (Ext.isBoolean(checked)) {
checked = !checked;
record.set('checked', checked);
this.fireEvent('checkchange', record, checked);
}
},
getChecked: function() {
var checked = [];
this.node.cascadeBy(function(rec) {
if (rec.get('checked')) {
checked.push(rec);
}
});
return checked;
},
isItemChecked: function(rec) {
return rec.get('checked');
},
createAnimWrap: function(record, index) {
var me = this,
node = me.getNode(record),
tmpEl;
tmpEl = Ext.fly(node).insertSibling({
role: 'presentation',
tag: 'div',
cls: me.nodeAnimWrapCls
}, 'after');
return {
record: record,
node: node,
el: tmpEl,
expanding: false,
collapsing: false,
animateEl: tmpEl,
targetEl: tmpEl
};
},
getAnimWrap: function(parent, bubble) {
if (!this.animate) {
return null;
}
var wraps = this.animWraps,
wrap = wraps[parent.internalId];
if (bubble !== false) {
while (!wrap && parent) {
parent = parent.parentNode;
if (parent) {
wrap = wraps[parent.internalId];
}
}
}
return wrap;
},
doAdd: function(records, index) {
var me = this,
record = records[0],
parent = record.parentNode,
all = me.all,
relativeIndex,
animWrap = me.getAnimWrap(parent),
targetEl, childNodes, len, result, children;
if (!animWrap || !animWrap.expanding) {
return me.callParent([
records,
index
]);
}
result = me.bufferRender(records, index, true);
children = result.children;
parent = animWrap.record;
targetEl = animWrap.targetEl;
childNodes = targetEl.dom.childNodes;
len = childNodes.length;
relativeIndex = index - me.indexInStore(parent) - 1;
if (!len || relativeIndex >= len) {
targetEl.appendChild(result.fragment, true);
} else
{
Ext.fly(childNodes[relativeIndex]).insertSibling(children, 'before', true);
}
all.insert(index, children);
return children;
},
onRemove: function(ds, records, index) {
var me = this,
empty, i;
if (me.viewReady) {
empty = me.store.getCount() === 0;
if (me.bufferedRenderer) {
return me.callParent([
ds,
records,
index
]);
}
if (empty) {
me.refresh();
} else {
for (i = records.length - 1 , index += i; i >= 0; --i , --index) {
me.doRemove(records[i], index);
}
me.refreshSizePending = true;
}
if (me.hasListeners.itemremove) {
for (i = records.length - 1 , index += i; i >= 0; --i , --index) {
me.fireEvent('itemremove', records[i], index, me);
}
}
}
},
doRemove: function(record, index) {
var me = this,
all = me.all,
animWrap = me.getAnimWrap(record),
item = all.item(index),
node = item ? item.dom : null;
if (!node || !animWrap || !animWrap.collapsing) {
return me.callParent([
record,
index
]);
}
animWrap.targetEl.dom.insertBefore(node, animWrap.targetEl.dom.firstChild);
all.removeElement(index);
},
onBeforeExpand: function(parent, records, index) {
var me = this,
animWrap;
if (me.rendered && me.all.getCount() && me.animate) {
if (me.getNode(parent)) {
animWrap = me.getAnimWrap(parent, false);
if (!animWrap) {
animWrap = me.animWraps[parent.internalId] = me.createAnimWrap(parent);
animWrap.animateEl.setHeight(0);
} else if (animWrap.collapsing) {
animWrap.targetEl.select(me.itemSelector).destroy();
}
animWrap.expanding = true;
animWrap.collapsing = false;
}
}
},
onExpand: function(parent) {
var me = this,
queue = me.animQueue,
id = parent.getId(),
node = me.getNode(parent),
index = node ? me.indexOf(node) : -1,
animWrap, animateEl, targetEl;
if (me.singleExpand) {
me.ensureSingleExpand(parent);
}
if (index === -1) {
return;
}
animWrap = me.getAnimWrap(parent, false);
if (!animWrap) {
parent.isExpandingOrCollapsing = false;
me.fireEvent('afteritemexpand', parent, index, node);
return;
}
animateEl = animWrap.animateEl;
targetEl = animWrap.targetEl;
animateEl.stopAnimation();
queue[id] = true;
Ext.on('idle', function() {
animateEl.dom.style.height = '0px';
}, null, {
single: true
});
animateEl.animate({
from: {
height: 0
},
to: {
height: targetEl.dom.scrollHeight
},
duration: me.expandDuration,
listeners: {
afteranimate: function() {
var items = targetEl.dom.childNodes,
activeEl = Ext.Element.getActiveElement();
if (items.length) {
if (!targetEl.contains(activeEl)) {
activeEl = null;
}
animWrap.el.insertSibling(items, 'before', true);
if (activeEl) {
activeEl.focus();
}
}
animWrap.el.destroy();
me.animWraps[animWrap.record.internalId] = queue[id] = null;
}
},
callback: function() {
parent.isExpandingOrCollapsing = false;
if (!me.isDestroyed) {
me.refreshSize(true);
}
me.fireEvent('afteritemexpand', parent, index, node);
}
});
},
onBeforeCollapse: function(parent, records, index, callback, scope) {
var me = this,
animWrap;
if (me.rendered && me.all.getCount()) {
if (me.animate) {
if (parent.isVisible()) {
animWrap = me.getAnimWrap(parent);
if (!animWrap) {
animWrap = me.animWraps[parent.internalId] = me.createAnimWrap(parent, index);
} else if (animWrap.expanding) {
animWrap.targetEl.select(this.itemSelector).destroy();
}
animWrap.expanding = false;
animWrap.collapsing = true;
animWrap.callback = callback;
animWrap.scope = scope;
}
} else {
me.onCollapseCallback = callback;
me.onCollapseScope = scope;
}
}
},
onCollapse: function(parent) {
var me = this,
queue = me.animQueue,
id = parent.getId(),
node = me.getNode(parent),
index = node ? me.indexOf(node) : -1,
animWrap = me.getAnimWrap(parent),
animateEl;
if (!me.all.getCount() || !parent.isVisible()) {
return;
}
if (!animWrap) {
parent.isExpandingOrCollapsing = false;
me.fireEvent('afteritemcollapse', parent, index, node);
Ext.callback(me.onCollapseCallback, me.onCollapseScope);
me.onCollapseCallback = me.onCollapseScope = null;
return;
}
animateEl = animWrap.animateEl;
queue[id] = true;
animateEl.stopAnimation();
animateEl.animate({
to: {
height: 0
},
duration: me.collapseDuration,
listeners: {
afteranimate: function() {
animWrap.el.destroy();
me.animWraps[animWrap.record.internalId] = queue[id] = null;
}
},
callback: function() {
parent.isExpandingOrCollapsing = false;
if (!me.isDestroyed) {
me.refreshSize(true);
}
me.fireEvent('afteritemcollapse', parent, index, node);
Ext.callback(animWrap.callback, animWrap.scope);
animWrap.callback = animWrap.scope = null;
}
});
},
isAnimating: function(node) {
return !!this.animQueue[node.getId()];
},
expand: function(record, deep, callback, scope) {
var me = this,
doAnimate = !!me.animate,
result;
if (!doAnimate || !record.isExpandingOrCollapsing) {
if (!record.isLeaf()) {
record.isExpandingOrCollapsing = doAnimate;
}
Ext.suspendLayouts();
result = record.expand(deep, callback, scope);
Ext.resumeLayouts(true);
return result;
}
},
collapse: function(record, deep, callback, scope) {
var me = this,
doAnimate = !!me.animate;
if (!doAnimate || !record.isExpandingOrCollapsing) {
if (!record.isLeaf()) {
record.isExpandingOrCollapsing = doAnimate;
}
return record.collapse(deep, callback, scope);
}
},
toggle: function(record, deep, callback, scope) {
if (record.isExpanded()) {
this.collapse(record, deep, callback, scope);
} else {
this.expand(record, deep, callback, scope);
}
},
onItemDblClick: function(record, item, index, e) {
var me = this,
editingPlugin = me.editingPlugin;
me.callParent([
record,
item,
index,
e
]);
if (me.toggleOnDblClick && record.isExpandable() && !(editingPlugin && editingPlugin.clicksToEdit === 2)) {
me.toggle(record);
}
},
onBeforeItemMouseDown: function(record, item, index, e) {
if (e.getTarget(this.expanderSelector, item)) {
return false;
}
return this.callParent([
record,
item,
index,
e
]);
},
onItemClick: function(record, item, index, e) {
if (e.getTarget(this.expanderSelector, item) && record.isExpandable()) {
this.toggle(record, e.ctrlKey);
return false;
}
return this.callParent([
record,
item,
index,
e
]);
},
onExpanderMouseOver: function(e, t) {
e.getTarget(this.cellSelector, 10, true).addCls(this.expanderIconOverCls);
},
onExpanderMouseOut: function(e, t) {
e.getTarget(this.cellSelector, 10, true).removeCls(this.expanderIconOverCls);
},
getStoreListeners: function() {
return Ext.apply(this.callParent(), {
rootchange: this.onRootChange,
fillcomplete: this.onFillComplete
});
},
onBindStore: function(store, initial, propName, oldStore) {
var oldRoot = oldStore && oldStore.getRootNode(),
newRoot = store && store.getRootNode();
this.callParent([
store,
initial,
propName,
oldStore
]);
if (newRoot !== oldRoot) {
this.onRootChange(newRoot, oldRoot);
}
},
onRootChange: function(newRoot, oldRoot) {
var me = this;
if (oldRoot) {
me.rootListeners.destroy();
me.rootListeners = null;
}
if (newRoot) {
me.rootListeners = newRoot.on({
beforeexpand: me.onBeforeExpand,
expand: me.onExpand,
beforecollapse: me.onBeforeCollapse,
collapse: me.onCollapse,
destroyable: true,
scope: me
});
}
},
ensureSingleExpand: function(node) {
var parent = node.parentNode;
if (parent) {
parent.eachChild(function(child) {
if (child !== node && child.isExpanded()) {
child.collapse();
}
});
}
},
shouldUpdateCell: function(record, column, changedFieldNames) {
if (column.isTreeColumn && changedFieldNames) {
var i = 0,
len = changedFieldNames.length;
for (; i < len; ++i) {
if (this.rowFields[changedFieldNames[i]]) {
return 1;
}
if (this.uiFields[changedFieldNames[i]]) {
return 2;
}
}
}
return this.callParent([
record,
column,
changedFieldNames
]);
}
});
Ext.define('Ext.selection.RowModel', {
extend: 'Ext.selection.DataViewModel',
alias: 'selection.rowmodel',
requires: [
'Ext.grid.CellContext'
],
enableKeyNav: true,
isRowModel: true,
deselectOnContainerClick: false,
onUpdate: function(record) {
var me = this,
view = me.view,
index;
if (view && me.isSelected(record)) {
index = view.indexOf(record);
view.onRowSelect(index);
if (record === me.lastFocused) {
view.onRowFocus(index, true);
}
}
},
onSelectChange: function(record, isSelected, suppressEvent, commitFn) {
var me = this,
views = me.views || [
me.view
],
viewsLn = views.length,
recordIndex = me.store.indexOf(record),
eventName = isSelected ? 'select' : 'deselect',
i, view;
if ((suppressEvent || me.fireEvent('before' + eventName, me, record, recordIndex)) !== false && commitFn() !== false) {
for (i = 0; i < viewsLn; i++) {
view = views[i];
recordIndex = view.indexOf(record);
if (view.indexOf(record) !== -1) {
if (isSelected) {
view.onRowSelect(recordIndex, suppressEvent);
} else {
view.onRowDeselect(recordIndex, suppressEvent);
}
}
}
if (!suppressEvent) {
me.fireEvent(eventName, me, record, recordIndex);
}
}
},
onEditorTab: function(editingPlugin, e) {
var me = this,
view = editingPlugin.context.view,
record = editingPlugin.getActiveRecord(),
position = editingPlugin.context,
direction = e.shiftKey ? 'left' : 'right',
lastPos;
do {
lastPos = position;
position = view.walkCells(position, direction, e, me.preventWrap);
if (lastPos && lastPos.isEqual(position)) {
return;
}
} while (
position && (!position.column.getEditor(record) || !editingPlugin.startEditByPosition(position)));
},
getCurrentPosition: function() {
var firstSelection = this.selected.getAt(0);
if (firstSelection) {
return new Ext.grid.CellContext(this.view).setPosition(this.store.indexOf(firstSelection), 0);
}
},
selectByPosition: function(position, keepExisting) {
if (!position.isCellContext) {
position = new Ext.grid.CellContext(this.view).setPosition(position.row, position.column);
}
this.select(position.record, keepExisting);
},
selectNext: function(keepExisting, suppressEvent) {
var me = this,
store = me.store,
selection = me.getSelection(),
record = selection[selection.length - 1],
index = me.view.indexOf(record) + 1,
success;
if (index === store.getCount() || index === 0) {
success = false;
} else {
me.doSelect(index, keepExisting, suppressEvent);
success = true;
}
return success;
},
selectPrevious: function(keepExisting, suppressEvent) {
var me = this,
selection = me.getSelection(),
record = selection[0],
index = me.view.indexOf(record) - 1,
success;
if (index < 0) {
success = false;
} else {
me.doSelect(index, keepExisting, suppressEvent);
success = true;
}
return success;
},
isRowSelected: function(record) {
return this.isSelected(record);
},
isCellSelected: function(view, record, columnHeader) {
return this.isSelected(record);
}
});
Ext.define('Ext.selection.TreeModel', {
extend: 'Ext.selection.RowModel',
alias: 'selection.treemodel',
selectOnExpanderClick: false,
constructor: function(config) {
var me = this;
me.callParent([
config
]);
if (me.pruneRemoved) {
me.pruneRemoved = false;
me.pruneRemovedNodes = true;
}
},
getStoreListeners: function() {
var me = this,
result = me.callParent();
result.noderemove = me.onNodeRemove;
return result;
},
onNodeRemove: function(parent, node, isMove) {
if (!isMove) {
var toDeselect = [];
this.gatherSelected(node, toDeselect);
if (toDeselect.length) {
this.deselect(toDeselect);
}
}
},
pruneRemovedOnRefresh: function() {
return this.pruneRemovedNodes;
},
vetoSelection: function(e) {
var view = this.view,
select = this.selectOnExpanderClick,
veto = !select && e.type === 'click' && e.getTarget(view.expanderSelector || (view.lockingPartner && view.lockingPartner.expanderSelector));
return veto || this.callParent([
e
]);
},
privates: {
gatherSelected: function(node, toDeselect) {
var childNodes = node.childNodes,
i, len, child;
if (this.selected.containsKey(node.id)) {
toDeselect.push(node);
}
if (childNodes) {
for (i = 0 , len = childNodes.length; i < len; ++i) {
child = childNodes[i];
this.gatherSelected(child, toDeselect);
}
}
}
}
});
Ext.define('Ext.grid.ColumnLayout', {
extend: 'Ext.layout.container.HBox',
alias: 'layout.gridcolumn',
type: 'gridcolumn',
requires: [
'Ext.panel.Table'
],
firstHeaderCls: Ext.baseCSSPrefix + 'column-header-first',
lastHeaderCls: Ext.baseCSSPrefix + 'column-header-last',
initLayout: function() {
this.callParent();
if (this.scrollbarWidth === undefined) {
this.self.prototype.scrollbarWidth = Ext.getScrollbarSize().width;
}
},
beginLayout: function(ownerContext) {
var me = this,
owner = me.owner,
view = owner.grid ? owner.grid.getView() : null,
firstCls = me.firstHeaderCls,
lastCls = me.lastHeaderCls,
bothCls = [
firstCls,
lastCls
],
items = me.getVisibleItems(),
len = items.length,
i, item;
if (view && view.scrollFlags.x) {
me.viewScrollX = view.getScrollX();
owner.suspendEvent('scroll');
view.suspendEvent('scroll');
}
me.callParent([
ownerContext
]);
for (i = 0; i < len; i++) {
item = items[i];
if (len === 1) {
item.addCls(bothCls);
} else if (i === 0) {
item.addCls(firstCls);
item.removeCls(lastCls);
} else if (i === len - 1) {
item.removeCls(firstCls);
item.addCls(lastCls);
} else {
item.removeCls(bothCls);
}
}
me.scrollbarWidth = 0;
if (owner.isRootHeader) {
me.determineScrollbarWidth(ownerContext);
}
if (!me.scrollbarWidth) {
ownerContext.manageScrollbar = false;
}
},
moveItemBefore: function(item, before) {
var prevOwner = item.ownerCt;
if (item !== before && prevOwner) {
prevOwner.remove(item, false);
}
return this.callParent([
item,
before
]);
},
determineScrollbarWidth: function(ownerContext) {
var me = this,
owner = me.owner,
grid = owner.grid,
vetoReserveScrollbar = owner.reserveScrollbar === false,
reserveScrollbar = grid.reserveScrollbar && !vetoReserveScrollbar,
manageScrollbar = !reserveScrollbar && !vetoReserveScrollbar && grid.view.scrollFlags.y;
ownerContext.manageScrollbar = manageScrollbar;
if (!grid.ownerGrid.collapsed && (reserveScrollbar || manageScrollbar)) {
delete me.scrollbarWidth;
}
},
calculate: function(ownerContext) {
var me = this,
grid = me.owner.grid,
viewContext = ownerContext.viewContext,
state = ownerContext.state,
context = ownerContext.context,
lockingPartnerContext, ownerGrid, columnsChanged, columns, len, i, column, scrollbarAdjustment, viewOverflowY;
me.callParent([
ownerContext
]);
if (grid && state.parallelDone) {
lockingPartnerContext = viewContext.lockingPartnerContext;
ownerGrid = grid.ownerGrid;
if (ownerGrid.forceFit && !state.reflexed) {
if (me.convertWidthsToFlexes(ownerContext)) {
me.cacheFlexes(ownerContext);
me.done = false;
ownerContext.invalidate({
state: {
reflexed: true,
scrollbarAdjustment: me.getScrollbarAdjustment(ownerContext)
}
});
return;
}
}
if ((columnsChanged = state.columnsChanged) === undefined) {
columns = ownerContext.target.getVisibleGridColumns();
columnsChanged = false;
for (i = 0 , len = columns.length; i < len; i++) {
column = context.getCmp(columns[i]);
if (!column.lastBox || column.props.width !== column.lastBox.width) {
(columnsChanged || (columnsChanged = []))[i] = column;
}
}
state.columnsChanged = columnsChanged;
ownerContext.setProp('columnsChanged', columnsChanged);
}
if (ownerContext.manageScrollbar) {
scrollbarAdjustment = me.getScrollbarAdjustment(ownerContext);
if (scrollbarAdjustment) {
viewOverflowY = viewContext.getProp('viewOverflowY');
if (viewOverflowY === undefined) {
me.done = false;
return;
}
if (!viewOverflowY) {
if (lockingPartnerContext) {
lockingPartnerContext.invalidate();
lockingPartnerContext.headerContext.invalidate();
}
viewContext.invalidate();
ownerContext.invalidate({
state: {
scrollbarAdjustment: 0
}
});
}
}
}
}
},
finishedLayout: function(ownerContext) {
var me = this,
owner = me.owner,
view = owner.grid ? owner.grid.getView() : null,
viewScrollX = me.viewScrollX;
me.callParent([
ownerContext
]);
if (view && view.scrollFlags.x) {
if (viewScrollX !== undefined && owner.tooNarrow && owner.componentLayoutCounter) {
owner.setScrollX(viewScrollX);
}
view.resumeEvent('scroll');
owner.resumeEvent('scroll');
}
},
convertWidthsToFlexes: function(ownerContext) {
var me = this,
totalWidth = 0,
calculated = me.sizeModels.calculated,
childItems, len, i, childContext, item;
childItems = ownerContext.childItems;
len = childItems.length;
for (i = 0; i < len; i++) {
childContext = childItems[i];
item = childContext.target;
totalWidth += childContext.props.width;
if (!(item.fixed || item.resizable === false)) {
item.flex = ownerContext.childItems[i].flex = childContext.props.width;
item.width = null;
childContext.widthModel = calculated;
}
}
return totalWidth !== ownerContext.props.width;
},
getScrollbarAdjustment: function(ownerContext) {
var me = this,
state = ownerContext.state,
grid = me.owner.grid,
scrollbarAdjustment = state.scrollbarAdjustment;
if (scrollbarAdjustment === undefined) {
scrollbarAdjustment = 0;
if (grid.reserveScrollbar || (ownerContext.manageScrollbar && !grid.ownerGrid.layout.ownerContext.heightModel.shrinkWrap)) {
scrollbarAdjustment = me.scrollbarWidth;
}
state.scrollbarAdjustment = scrollbarAdjustment;
}
return scrollbarAdjustment;
},
getContainerSize: function(ownerContext) {
var me = this,
got, needed, padding, gotWidth, gotHeight, width, height, result;
if (me.owner.isRootHeader) {
result = me.callParent([
ownerContext
]);
if (result.gotWidth) {
result.width -= me.getScrollbarAdjustment(ownerContext);
}
} else {
padding = ownerContext.paddingContext.getPaddingInfo();
got = needed = 0;
if (!ownerContext.widthModel.shrinkWrap) {
++needed;
width = ownerContext.getProp('innerWidth');
gotWidth = (typeof width === 'number');
if (gotWidth) {
++got;
width -= padding.width;
if (width < 0) {
width = 0;
}
}
}
if (!ownerContext.heightModel.shrinkWrap) {
++needed;
height = ownerContext.getProp('innerHeight');
gotHeight = (typeof height === 'number');
if (gotHeight) {
++got;
height -= padding.height;
if (height < 0) {
height = 0;
}
}
}
return {
width: width,
height: height,
needed: needed,
got: got,
gotAll: got === needed,
gotWidth: gotWidth,
gotHeight: gotHeight
};
}
return result;
},
publishInnerCtSize: function(ownerContext) {
var me = this,
owner = me.owner,
cw = ownerContext.peek('contentWidth'),
adjustment = 0;
if (cw != null && owner.isRootHeader) {
adjustment = -ownerContext.state.scrollbarAdjustment;
}
return me.callParent([
ownerContext,
adjustment
]);
}
});
Ext.define('Ext.dd.DragTracker', {
uses: [
'Ext.util.Region'
],
mixins: {
observable: 'Ext.util.Observable'
},
active: false,
trackOver: false,
tolerance: 5,
autoStart: false,
constructor: function(config) {
var me = this;
Ext.apply(me, config);
me.dragRegion = new Ext.util.Region(0, 0, 0, 0);
if (me.el) {
me.initEl(me.el);
}
me.mixins.observable.constructor.call(me);
if (me.disabled) {
me.disable();
}
},
initEl: function(el) {
var me = this,
delegate = me.delegate;
me.el = el = Ext.get(el);
if (delegate && delegate.isElement) {
me.handle = delegate;
}
me.delegate = me.handle ? undefined : me.delegate;
if (!me.handle) {
me.handle = el;
}
me.handleListeners = {
scope: me,
delegate: me.delegate,
mousedown: me.onMouseDown,
dragstart: me.onDragStart
};
if (!Ext.supports.TouchEvents && (me.trackOver || me.overCls)) {
Ext.apply(me.handleListeners, {
mouseover: me.onMouseOver,
mouseout: me.onMouseOut
});
}
me.mon(me.handle, me.handleListeners);
me.keyNav = new Ext.util.KeyNav({
target: el,
up: me.onResizeKeyDown,
left: me.onResizeKeyDown,
right: me.onResizeKeyDown,
down: me.onResizeKeyDown,
scope: me
});
},
disable: function() {
this.disabled = true;
},
enable: function() {
this.disabled = false;
},
destroy: function() {
var me = this;
me.endDrag({});
me.clearListeners();
me.el = me.handle = null;
},
onMouseOver: function(e, target) {
var me = this,
handleCls, el, i, len, cls;
if (!me.disabled) {
if (e.within(e.target, true, true) || me.delegate) {
handleCls = me.handleCls;
me.mouseIsOut = false;
if (handleCls) {
for (i = 0 , len = me.handleEls.length; i < len; i++) {
el = me.handleEls[i];
cls = el.delegateCls;
if (!cls) {
cls = el.delegateCls = [
handleCls,
'-',
el.region,
'-over'
].join('');
}
el.addCls([
cls,
me.overCls
]);
}
}
me.fireEvent('mouseover', me, e, me.delegate ? e.getTarget(me.delegate, target) : me.handle);
}
}
},
onMouseOut: function(e) {
var me = this,
el, i, len;
if (me.mouseIsDown) {
me.mouseIsOut = true;
} else {
if (me.handleCls) {
for (i = 0 , len = me.handleEls.length; i < len; i++) {
el = me.handleEls[i];
el.removeCls([
el.delegateCls,
me.overCls
]);
}
}
me.fireEvent('mouseout', me, e);
}
},
onMouseDown: function(e, target) {
var me = this;
if (me.disabled || e.dragTracked) {
return;
}
me.dragTarget = me.delegate ? target : me.handle.dom;
me.startXY = me.lastXY = e.getXY();
me.startRegion = Ext.fly(me.dragTarget).getRegion();
if (me.fireEvent('mousedown', me, e) === false || me.fireEvent('beforedragstart', me, e) === false || me.onBeforeStart(e) === false) {
return;
}
me.mouseIsDown = true;
e.dragTracked = true;
me.el.setCapture();
e.stopPropagation();
if (me.preventDefault !== false) {
e.preventDefault();
}
Ext.getDoc().on({
scope: me,
capture: true,
mouseup: me.onMouseUp,
mousemove: me.onMouseMove,
selectstart: me.stopSelect
});
me.dragEnded = false;
if (!me.tolerance) {
me.triggerStart();
} else if (me.autoStart) {
me.timer = Ext.defer(me.triggerStart, me.autoStart === true ? 1000 : me.autoStart, me, [
e
]);
}
},
onMouseMove: function(e, target) {
var me = this,
xy = e.getXY(),
s = me.startXY;
e.stopPropagation();
if (me.preventDefault !== false) {
e.preventDefault();
}
if (me.dragEnded) {
return;
}
me.lastXY = xy;
if (!me.active) {
if (Math.max(Math.abs(s[0] - xy[0]), Math.abs(s[1] - xy[1])) > me.tolerance) {
me.triggerStart(e);
} else {
return;
}
}
if (me.fireEvent('mousemove', me, e) === false) {
me.onMouseUp(e);
} else {
me.onDrag(e);
me.fireEvent('drag', me, e);
}
},
onMouseUp: function(e) {
var me = this;
me.mouseIsDown = false;
if (me.mouseIsOut) {
me.mouseIsOut = false;
me.onMouseOut(e);
}
if (me.preventDefault !== false) {
e.preventDefault();
}
if (Ext.isIE && document.releaseCapture) {
document.releaseCapture();
}
me.fireEvent('mouseup', me, e);
me.endDrag(e);
},
endDrag: function(e) {
var me = this,
wasActive = me.active;
Ext.getDoc().un({
mousemove: me.onMouseMove,
mouseup: me.onMouseUp,
selectstart: me.stopSelect,
capture: true,
scope: me
});
me.clearStart();
me.active = false;
if (wasActive) {
me.dragEnded = true;
me.onEnd(e);
me.fireEvent('dragend', me, e);
}
me._constrainRegion = null;
},
triggerStart: function(e) {
var me = this;
me.clearStart();
me.active = true;
me.onStart(e);
me.fireEvent('dragstart', me, e);
},
clearStart: function() {
var timer = this.timer;
if (timer) {
clearTimeout(timer);
this.timer = null;
}
},
stopSelect: function(e) {
e.stopEvent();
return false;
},
onBeforeStart: function(e) {},
onStart: function(xy) {},
onDrag: function(e) {},
onEnd: function(e) {},
getDragTarget: function() {
return this.dragTarget;
},
getDragCt: function() {
return this.el;
},
getConstrainRegion: function() {
var me = this;
if (me.constrainTo) {
if (me.constrainTo instanceof Ext.util.Region) {
return me.constrainTo;
}
if (!me._constrainRegion) {
me._constrainRegion = Ext.fly(me.constrainTo).getViewRegion();
}
} else {
if (!me._constrainRegion) {
me._constrainRegion = me.getDragCt().getViewRegion();
}
}
return me._constrainRegion;
},
getXY: function(constrain) {
return constrain ? this.constrainModes[constrain](this, this.lastXY) : this.lastXY;
},
getOffset: function(constrain) {
var xy = this.getXY(constrain),
s = this.startXY;
return [
xy[0] - s[0],
xy[1] - s[1]
];
},
onDragStart: function(e) {
e.stopPropagation();
},
constrainModes: {
point: function(me, xy) {
var dr = me.dragRegion,
constrainTo = me.getConstrainRegion();
if (!constrainTo) {
return xy;
}
dr.x = dr.left = dr[0] = dr.right = xy[0];
dr.y = dr.top = dr[1] = dr.bottom = xy[1];
dr.constrainTo(constrainTo);
return [
dr.left,
dr.top
];
},
dragTarget: function(me, xy) {
var s = me.startXY,
dr = me.startRegion.copy(),
constrainTo = me.getConstrainRegion(),
adjust;
if (!constrainTo) {
return xy;
}
dr.translateBy(xy[0] - s[0], xy[1] - s[1]);
if (dr.right > constrainTo.right) {
xy[0] += adjust = (constrainTo.right - dr.right);
dr.left += adjust;
}
if (dr.left < constrainTo.left) {
xy[0] += (constrainTo.left - dr.left);
}
if (dr.bottom > constrainTo.bottom) {
xy[1] += adjust = (constrainTo.bottom - dr.bottom);
dr.top += adjust;
}
if (dr.top < constrainTo.top) {
xy[1] += (constrainTo.top - dr.top);
}
return xy;
}
}
});
Ext.define('Ext.grid.plugin.HeaderResizer', {
extend: 'Ext.plugin.Abstract',
requires: [
'Ext.dd.DragTracker',
'Ext.util.Region'
],
alias: 'plugin.gridheaderresizer',
disabled: false,
config: {
dynamic: false
},
colHeaderCls: Ext.baseCSSPrefix + 'column-header',
minColWidth: 40,
maxColWidth: 1000,
eResizeCursor: 'col-resize',
init: function(headerCt) {
var me = this;
me.headerCt = headerCt;
headerCt.on('render', me.afterHeaderRender, me, {
single: me
});
if (!me.minColWidth) {
me.self.prototype.minColWidth = Ext.grid.column.Column.prototype.minWidth;
}
},
destroy: function() {
var tracker = this.tracker;
if (tracker) {
delete tracker.onBeforeStart;
delete tracker.onStart;
delete tracker.onDrag;
delete tracker.onEnd;
tracker.destroy();
this.tracker = null;
}
},
afterHeaderRender: function() {
var me = this,
headerCt = me.headerCt,
el = headerCt.el;
headerCt.mon(el, 'mousemove', me.onHeaderCtMouseMove, me);
me.markerOwner = me.ownerGrid = me.headerCt.up('tablepanel');
if (me.markerOwner.ownerLockable) {
me.markerOwner = me.markerOwner.ownerLockable;
}
me.tracker = new Ext.dd.DragTracker({
disabled: me.disabled,
onBeforeStart: me.onBeforeStart.bind(me),
onStart: me.onStart.bind(me),
onDrag: me.onDrag.bind(me),
onEnd: me.onEnd.bind(me),
tolerance: 3,
autoStart: 300,
el: el
});
},
onHeaderCtMouseMove: function(e) {
var me = this;
if (me.headerCt.dragging || me.disabled) {
if (me.activeHd) {
me.activeHd.el.dom.style.cursor = '';
delete me.activeHd;
}
} else {
me.findActiveHeader(e);
}
},
findActiveHeader: function(e) {
var me = this,
headerEl = e.getTarget('.' + me.colHeaderCls, 3, true),
ownerGrid = me.ownerGrid,
ownerLockable = ownerGrid.ownerLockable,
overHeader, resizeHeader, headers, header;
if (headerEl) {
overHeader = Ext.getCmp(headerEl.id);
if (overHeader.isAtEndEdge(e)) {
if (me.headerCt.visibleColumnManager.getColumns().length === 1 && me.headerCt.forceFit) {
return;
}
resizeHeader = overHeader;
}
else if (overHeader.isAtStartEdge(e)) {
headers = me.headerCt.visibleColumnManager.getColumns();
header = overHeader.isGroupHeader ? overHeader.getGridColumns()[0] : overHeader;
resizeHeader = headers[Ext.Array.indexOf(headers, header) - 1];
if (!resizeHeader && ownerLockable && !ownerGrid.isLocked) {
headers = ownerLockable.lockedGrid.headerCt.visibleColumnManager.getColumns();
resizeHeader = headers[headers.length - 1];
}
}
if (resizeHeader) {
if (resizeHeader.isGroupHeader) {
headers = resizeHeader.getGridColumns();
resizeHeader = headers[headers.length - 1];
}
if (resizeHeader && !(resizeHeader.fixed || (resizeHeader.resizable === false))) {
me.activeHd = resizeHeader;
overHeader.el.dom.style.cursor = me.eResizeCursor;
if (overHeader.triggerEl) {
overHeader.triggerEl.dom.style.cursor = me.eResizeCursor;
}
}
} else
{
overHeader.el.dom.style.cursor = '';
if (overHeader.triggerEl) {
overHeader.triggerEl.dom.style.cursor = '';
}
me.activeHd = null;
}
}
return me.activeHd;
},
onBeforeStart: function(e) {
var me = this;
me.dragHd = Ext.supports.Touch ? me.findActiveHeader(e) : me.activeHd;
if (!!me.dragHd && !me.headerCt.dragging) {
me.xDelta = me.dragHd.getX() + me.dragHd.getWidth() - me.tracker.getXY()[0];
me.tracker.constrainTo = me.getConstrainRegion();
return true;
} else {
me.headerCt.dragging = false;
return false;
}
},
getConstrainRegion: function() {
var me = this,
dragHdEl = me.dragHd.el,
nextHd,
ownerGrid = me.ownerGrid,
widthModel = ownerGrid.getSizeModel().width,
maxColWidth = widthModel.shrinkWrap ? me.headerCt.getWidth() - me.headerCt.visibleColumnManager.getColumns().length * me.minColWidth : me.maxColWidth,
result;
if (me.headerCt.forceFit) {
nextHd = me.dragHd.nextNode('gridcolumn:not([hidden]):not([isGroupHeader])');
if (nextHd && me.headerInSameGrid(nextHd)) {
maxColWidth = dragHdEl.getWidth() + (nextHd.getWidth() - me.minColWidth);
}
}
else if (ownerGrid.isLocked && widthModel.shrinkWrap) {
maxColWidth = me.dragHd.up('[scrollerOwner]').getTargetEl().getWidth(true) - ownerGrid.getWidth() - (ownerGrid.ownerLockable.normalGrid.visibleColumnManager.getColumns().length * me.minColWidth + Ext.getScrollbarSize().width);
}
result = me.adjustConstrainRegion(dragHdEl.getRegion(), 0, 0, 0, me.minColWidth);
result.right = dragHdEl.getX() + maxColWidth;
return result;
},
onStart: function(e) {
var me = this,
dragHd = me.dragHd,
width = dragHd.el.getWidth(),
headerCt = dragHd.getRootHeaderCt(),
x, y, markerOwner, lhsMarker, rhsMarker, markerHeight;
me.headerCt.dragging = true;
me.origWidth = width;
if (!me.dynamic) {
markerOwner = me.markerOwner;
if (markerOwner.frame && markerOwner.resizable) {
me.gridOverflowSetting = markerOwner.el.dom.style.overflow;
markerOwner.el.dom.style.overflow = 'hidden';
}
x = me.getLeftMarkerX(markerOwner);
lhsMarker = markerOwner.getLhsMarker();
rhsMarker = markerOwner.getRhsMarker();
markerHeight = me.ownerGrid.body.getHeight() + headerCt.getHeight();
y = headerCt.getOffsetsTo(markerOwner)[1] - markerOwner.el.getBorderWidth('t');
lhsMarker.setLocalY(y);
rhsMarker.setLocalY(y);
lhsMarker.setHeight(markerHeight);
rhsMarker.setHeight(markerHeight);
me.setMarkerX(lhsMarker, x);
me.setMarkerX(rhsMarker, x + width);
}
},
onDrag: function(e) {
var me = this;
if (me.dynamic) {
me.doResize();
} else {
me.setMarkerX(me.getMovingMarker(me.markerOwner), me.calculateDragX(me.markerOwner));
}
},
getMovingMarker: function(markerOwner) {
return markerOwner.getRhsMarker();
},
onEnd: function(e) {
var me = this,
markerOwner;
me.headerCt.dragging = false;
if (me.dragHd) {
if (!me.dynamic) {
markerOwner = me.headerCt.up('tablepanel');
if (markerOwner.ownerLockable) {
markerOwner = markerOwner.ownerLockable;
}
if ('gridOverflowSetting' in me) {
markerOwner.el.dom.style.overflow = me.gridOverflowSetting;
}
me.setMarkerX(markerOwner.getLhsMarker(), -9999);
me.setMarkerX(markerOwner.getRhsMarker(), -9999);
}
me.doResize();
}
me.onHeaderCtMouseMove(e);
},
doResize: function() {
var me = this,
dragHd = me.dragHd,
nextHd,
offset = me.tracker.getOffset('point');
if (dragHd && offset[0]) {
if (dragHd.flex) {
delete dragHd.flex;
}
Ext.suspendLayouts();
me.adjustColumnWidth(offset[0] - me.xDelta);
if (me.headerCt.forceFit) {
nextHd = dragHd.nextNode('gridcolumn:not([hidden]):not([isGroupHeader])');
if (nextHd && !me.headerInSameGrid(nextHd)) {
nextHd = null;
}
if (nextHd) {
delete nextHd.flex;
nextHd.setWidth(nextHd.getWidth() - offset[0]);
}
}
Ext.resumeLayouts(true);
}
},
headerInSameGrid: function(header) {
var grid = this.dragHd.up('tablepanel');
return !!header.up(grid);
},
disable: function() {
var tracker = this.tracker;
this.disabled = true;
if (tracker) {
tracker.disable();
}
},
enable: function() {
var tracker = this.tracker;
this.disabled = false;
if (tracker) {
tracker.enable();
}
},
calculateDragX: function(markerOwner) {
return this.tracker.getXY('point')[0] + this.xDelta - markerOwner.getX() - markerOwner.el.getBorderWidth('l');
},
getLeftMarkerX: function(markerOwner) {
return this.dragHd.getX() - markerOwner.getX() - markerOwner.el.getBorderWidth('l') - 1;
},
setMarkerX: function(marker, x) {
marker.setLocalX(x);
},
adjustConstrainRegion: function(region, t, r, b, l) {
return region.adjust(t, r, b, l);
},
adjustColumnWidth: function(offsetX) {
this.dragHd.setWidth(this.origWidth + offsetX);
}
});
Ext.define('Ext.dd.DragZone', {
extend: 'Ext.dd.DragSource',
constructor: function(el, config) {
var me = this,
scroll = me.containerScroll;
me.callParent([
el,
config
]);
if (scroll) {
el = me.scrollEl || el;
el = Ext.get(el);
if (Ext.isObject(scroll)) {
el.ddScrollConfig = scroll;
}
Ext.dd.ScrollManager.register(el);
}
},
getDragData: function(e) {
return Ext.dd.Registry.getHandleFromEvent(e);
},
onInitDrag: function(x, y) {
this.proxy.update(this.dragData.ddel.cloneNode(true));
this.onStartDrag(x, y);
return true;
},
getRepairXY: function(e) {
return Ext.fly(this.dragData.ddel).getXY();
},
destroy: function() {
this.callParent();
if (this.containerScroll) {
Ext.dd.ScrollManager.unregister(this.scrollEl || this.el);
}
}
});
Ext.define('Ext.grid.header.DragZone', {
extend: 'Ext.dd.DragZone',
colHeaderSelector: '.' + Ext.baseCSSPrefix + 'column-header',
colInnerSelector: '.' + Ext.baseCSSPrefix + 'column-header-inner',
maxProxyWidth: 120,
constructor: function(headerCt) {
var me = this;
me.headerCt = headerCt;
me.ddGroup = me.getDDGroup();
me.autoGroup = true;
me.callParent([
headerCt.el
]);
me.proxy.el.addCls(Ext.baseCSSPrefix + 'grid-col-dd');
},
getDDGroup: function() {
return 'header-dd-zone-' + this.headerCt.up('[scrollerOwner]').id;
},
getDragData: function(e) {
if (e.getTarget(this.colInnerSelector)) {
var header = e.getTarget(this.colHeaderSelector),
headerCmp, ddel;
if (header) {
headerCmp = Ext.getCmp(header.id);
if (!this.headerCt.dragging && headerCmp.draggable && !(headerCmp.isAtStartEdge(e) || headerCmp.isAtEndEdge(e))) {
ddel = document.createElement('div');
ddel.role = 'presentation';
ddel.innerHTML = headerCmp.text;
return {
ddel: ddel,
header: headerCmp
};
}
}
}
return false;
},
onBeforeDrag: function() {
return !(this.headerCt.dragging || this.disabled);
},
onInitDrag: function() {
this.headerCt.dragging = true;
this.headerCt.hideMenu();
this.callParent(arguments);
},
onDragDrop: function() {
this.headerCt.dragging = false;
this.callParent(arguments);
},
afterRepair: function() {
this.callParent();
this.headerCt.dragging = false;
},
getRepairXY: function() {
return this.dragData.header.el.getXY();
},
disable: function() {
this.disabled = true;
},
enable: function() {
this.disabled = false;
}
});
Ext.define('Ext.dd.DDTarget', {
extend: 'Ext.dd.DragDrop',
constructor: function(id, sGroup, config) {
if (id) {
this.initTarget(id, sGroup, config);
}
},
getDragEl: Ext.emptyFn,
isValidHandleChild: Ext.emptyFn,
startDrag: Ext.emptyFn,
endDrag: Ext.emptyFn,
onDrag: Ext.emptyFn,
onDragDrop: Ext.emptyFn,
onDragEnter: Ext.emptyFn,
onDragOut: Ext.emptyFn,
onDragOver: Ext.emptyFn,
onInvalidDrop: Ext.emptyFn,
onMouseDown: Ext.emptyFn,
onMouseUp: Ext.emptyFn,
setXConstraint: Ext.emptyFn,
setYConstraint: Ext.emptyFn,
resetConstraints: Ext.emptyFn,
clearConstraints: Ext.emptyFn,
clearTicks: Ext.emptyFn,
setInitPosition: Ext.emptyFn,
setDragElId: Ext.emptyFn,
setHandleElId: Ext.emptyFn,
setOuterHandleElId: Ext.emptyFn,
addInvalidHandleClass: Ext.emptyFn,
addInvalidHandleId: Ext.emptyFn,
addInvalidHandleType: Ext.emptyFn,
removeInvalidHandleClass: Ext.emptyFn,
removeInvalidHandleId: Ext.emptyFn,
removeInvalidHandleType: Ext.emptyFn,
toString: function() {
return ("DDTarget " + this.id);
}
});
Ext.define('Ext.dd.ScrollManager', {
singleton: true,
requires: [
'Ext.dd.DragDropManager'
],
dirTrans: {
up: -1,
left: -1,
down: 1,
right: 1
},
constructor: function() {
var ddm = Ext.dd.DragDropManager;
ddm.fireEvents = Ext.Function.createSequence(ddm.fireEvents, this.onFire, this);
ddm.stopDrag = Ext.Function.createSequence(ddm.stopDrag, this.onStop, this);
this.doScroll = this.doScroll.bind(this);
this.ddmInstance = ddm;
this.els = {};
this.dragEl = null;
this.proc = {};
},
onStop: function(e) {
var sm = Ext.dd.ScrollManager;
sm.dragEl = null;
sm.clearProc();
},
triggerRefresh: function() {
if (this.ddmInstance.dragCurrent) {
this.ddmInstance.refreshCache(this.ddmInstance.dragCurrent.groups);
}
},
doScroll: function() {
var me = this;
if (me.ddmInstance.dragCurrent) {
var proc = me.proc,
procEl = proc.el,
scrollComponent = proc.component,
ddScrollConfig = proc.el.ddScrollConfig,
distance = ddScrollConfig && ddScrollConfig.increment ? ddScrollConfig.increment : me.increment,
animate = ddScrollConfig && 'animate' in ddScrollConfig ? ddScrollConfig.animate : me.animate,
afterScroll = function() {
me.triggerRefresh();
};
if (animate) {
if (animate === true) {
animate = {
callback: afterScroll
};
} else {
animate.callback = animate.callback ? Ext.Function.createSequence(animate.callback, afterScroll) : afterScroll;
}
}
if (scrollComponent) {
distance = distance * me.dirTrans[proc.dir];
if (proc.dir === 'up' || proc.dir === 'down') {
scrollComponent.scrollBy(0, distance, animate);
} else {
scrollComponent.scrollBy(distance, 0, animate);
}
} else {
procEl.scroll(proc.dir, distance, animate);
}
if (!animate) {
afterScroll();
}
}
},
clearProc: function() {
var proc = this.proc;
if (proc.id) {
clearInterval(proc.id);
}
proc.id = 0;
proc.el = null;
proc.dir = "";
},
startProc: function(el, dir) {
var me = this,
proc = me.proc,
group, freq;
me.clearProc();
proc.el = el;
proc.dir = dir;
group = el.ddScrollConfig ? el.ddScrollConfig.ddGroup : undefined;
freq = (el.ddScrollConfig && el.ddScrollConfig.frequency) ? el.ddScrollConfig.frequency : me.frequency;
if (group === undefined || me.ddmInstance.dragCurrent.ddGroup === group) {
proc.id = Ext.interval(me.doScroll, freq);
}
},
onFire: function(e, isDrop) {
var me = this,
pt, proc, els, id, el, elementRegion, configSource;
if (isDrop || !me.ddmInstance.dragCurrent) {
return;
}
if (!me.dragEl || me.dragEl !== me.ddmInstance.dragCurrent) {
me.dragEl = me.ddmInstance.dragCurrent;
me.refreshCache();
}
pt = e.getPoint();
proc = me.proc;
els = me.els;
for (id in els) {
el = els[id];
elementRegion = el._region;
configSource = el.ddScrollConfig || me;
if (elementRegion && elementRegion.contains(pt) && el.isScrollable()) {
if (elementRegion.bottom - pt.y <= configSource.vthresh) {
if (proc.el !== el) {
me.startProc(el, "down");
}
return;
} else if (elementRegion.right - pt.x <= configSource.hthresh) {
if (proc.el !== el) {
me.startProc(el, "right");
}
return;
} else if (pt.y - elementRegion.top <= configSource.vthresh) {
if (proc.el !== el) {
me.startProc(el, "up");
}
return;
} else if (pt.x - elementRegion.left <= configSource.hthresh) {
if (proc.el !== el) {
me.startProc(el, "left");
}
return;
}
}
}
me.clearProc();
},
register: function(el) {
if (Ext.isArray(el)) {
for (var i = 0,
len = el.length; i < len; i++) {
this.register(el[i]);
}
} else {
el = Ext.get(el);
this.els[el.id] = el;
}
},
unregister: function(el) {
if (Ext.isArray(el)) {
for (var i = 0,
len = el.length; i < len; i++) {
this.unregister(el[i]);
}
} else {
el = Ext.get(el);
delete this.els[el.id];
}
},
vthresh: 25 * (window.devicePixelRatio || 1),
hthresh: 25 * (window.devicePixelRatio || 1),
increment: 100,
frequency: 500,
animate: true,
animDuration: 0.4,
ddGroup: undefined,
refreshCache: function() {
var els = this.els,
id;
for (id in els) {
if (typeof els[id] === 'object') {
els[id]._region = els[id].getRegion();
}
}
}
});
Ext.define('Ext.dd.DropTarget', {
extend: 'Ext.dd.DDTarget',
requires: [
'Ext.dd.ScrollManager'
],
constructor: function(el, config) {
this.el = Ext.get(el);
Ext.apply(this, config);
if (this.containerScroll) {
Ext.dd.ScrollManager.register(this.el);
}
this.callParent([
this.el.dom,
this.ddGroup || this.group,
{
isTarget: true
}
]);
},
containerScroll: false,
dropAllowed: Ext.baseCSSPrefix + 'dd-drop-ok',
dropNotAllowed: Ext.baseCSSPrefix + 'dd-drop-nodrop',
isTarget: true,
isNotifyTarget: true,
notifyEnter: function(dd, e, data) {
if (this.overClass) {
this.el.addCls(this.overClass);
}
return this.dropAllowed;
},
notifyOver: function(dd, e, data) {
return this.dropAllowed;
},
notifyOut: function(dd, e, data) {
if (this.overClass) {
this.el.removeCls(this.overClass);
}
},
notifyDrop: function(dd, e, data) {
if (this.overClass) {
this.el.removeCls(this.overClass);
}
return false;
},
destroy: function() {
this.callParent();
if (this.containerScroll) {
Ext.dd.ScrollManager.unregister(this.el);
}
}
});
Ext.define('Ext.dd.Registry', {
singleton: true,
constructor: function() {
this.elements = {};
this.handles = {};
this.autoIdSeed = 0;
},
getId: function(el, autogen) {
if (typeof el === "string") {
return el;
}
var id = el.id;
if (!id && autogen !== false) {
id = "extdd-" + (++this.autoIdSeed);
el.id = id;
}
return id;
},
register: function(el, data) {
data = data || {};
if (typeof el === "string") {
el = document.getElementById(el);
}
data.ddel = el;
this.elements[this.getId(el)] = data;
if (data.isHandle !== false) {
this.handles[data.ddel.id] = data;
}
if (data.handles) {
var hs = data.handles,
i, len;
for (i = 0 , len = hs.length; i < len; i++) {
this.handles[this.getId(hs[i])] = data;
}
}
},
unregister: function(el) {
var id = this.getId(el, false),
data = this.elements[id],
hs, i, len;
if (data) {
delete this.elements[id];
if (data.handles) {
hs = data.handles;
for (i = 0 , len = hs.length; i < len; i++) {
delete this.handles[this.getId(hs[i], false)];
}
}
}
},
getHandle: function(id) {
if (typeof id !== "string") {
id = id.id;
}
return this.handles[id];
},
getHandleFromEvent: function(e) {
var t = e.getTarget();
return t ? this.handles[t.id] : null;
},
getTarget: function(id) {
if (typeof id !== "string") {
id = id.id;
}
return this.elements[id];
},
getTargetFromEvent: function(e) {
var t = e.getTarget();
return t ? this.elements[t.id] || this.handles[t.id] : null;
}
});
Ext.define('Ext.dd.DropZone', {
extend: 'Ext.dd.DropTarget',
requires: [
'Ext.dd.Registry'
],
getTargetFromEvent: function(e) {
return Ext.dd.Registry.getTargetFromEvent(e);
},
onNodeEnter: function(n, dd, e, data) {},
onNodeOver: function(n, dd, e, data) {
return this.dropAllowed;
},
onNodeOut: function(n, dd, e, data) {},
onNodeDrop: function(n, dd, e, data) {
return false;
},
onContainerOver: function(dd, e, data) {
return this.dropNotAllowed;
},
onContainerDrop: function(dd, e, data) {
return false;
},
notifyEnter: function(dd, e, data) {
return this.dropNotAllowed;
},
notifyOver: function(dd, e, data) {
var me = this,
n = me.getTargetFromEvent(e);
if (!n) {
if (me.lastOverNode) {
me.onNodeOut(me.lastOverNode, dd, e, data);
me.lastOverNode = null;
}
return me.onContainerOver(dd, e, data);
}
if (me.lastOverNode !== n) {
if (me.lastOverNode) {
me.onNodeOut(me.lastOverNode, dd, e, data);
}
me.onNodeEnter(n, dd, e, data);
me.lastOverNode = n;
}
return me.onNodeOver(n, dd, e, data);
},
notifyOut: function(dd, e, data) {
if (this.lastOverNode) {
this.onNodeOut(this.lastOverNode, dd, e, data);
this.lastOverNode = null;
}
},
notifyDrop: function(dd, e, data) {
var me = this,
n = me.getTargetFromEvent(e),
result = n ? me.onNodeDrop(n, dd, e, data) : me.onContainerDrop(dd, e, data);
if (me.lastOverNode) {
me.onNodeOut(me.lastOverNode, dd, e, data);
me.lastOverNode = null;
}
return result;
},
triggerCacheRefresh: function() {
Ext.dd.DDM.refreshCache(this.groups);
}
});
Ext.define('Ext.grid.header.DropZone', {
extend: 'Ext.dd.DropZone',
colHeaderCls: Ext.baseCSSPrefix + 'column-header',
proxyOffsets: [
-4,
-9
],
constructor: function(headerCt) {
var me = this;
me.headerCt = headerCt;
me.ddGroup = me.getDDGroup();
me.autoGroup = true;
me.callParent([
headerCt.el
]);
},
destroy: function() {
this.callParent();
Ext.destroy(this.topIndicator, this.bottomIndicator);
},
getDDGroup: function() {
return 'header-dd-zone-' + this.headerCt.up('[scrollerOwner]').id;
},
getTargetFromEvent: function(e) {
return e.getTarget('.' + this.colHeaderCls);
},
getTopIndicator: function() {
if (!this.topIndicator) {
this.topIndicator = Ext.getBody().createChild({
role: 'presentation',
cls: Ext.baseCSSPrefix + "col-move-top",
"data-sticky": true,
html: "&#160;"
});
this.indicatorXOffset = Math.floor((this.topIndicator.dom.offsetWidth + 1) / 2);
}
return this.topIndicator;
},
getBottomIndicator: function() {
if (!this.bottomIndicator) {
this.bottomIndicator = Ext.getBody().createChild({
role: 'presentation',
cls: Ext.baseCSSPrefix + "col-move-bottom",
"data-sticky": true,
html: "&#160;"
});
}
return this.bottomIndicator;
},
getLocation: function(e, t) {
var x = e.getXY()[0],
region = Ext.fly(t).getRegion(),
pos;
if ((region.right - x) <= (region.right - region.left) / 2) {
pos = "after";
} else {
pos = "before";
}
return {
pos: pos,
header: Ext.getCmp(t.id),
node: t
};
},
positionIndicator: function(data, node, e) {
var me = this,
dragHeader = data.header,
dropLocation = me.getLocation(e, node),
targetHeader = dropLocation.header,
pos = dropLocation.pos,
nextHd, prevHd, topIndicator, bottomIndicator, topAnchor, bottomAnchor, topXY, bottomXY, headerCtEl, minX, maxX, allDropZones, ln, i, dropZone;
if (targetHeader === me.lastTargetHeader && pos === me.lastDropPos) {
return;
}
nextHd = dragHeader.nextSibling('gridcolumn:not([hidden])');
prevHd = dragHeader.previousSibling('gridcolumn:not([hidden])');
me.lastTargetHeader = targetHeader;
me.lastDropPos = pos;
if (!targetHeader.draggable && pos === 'before' && targetHeader.getIndex() === 0) {
return false;
}
data.dropLocation = dropLocation;
if ((dragHeader !== targetHeader) && ((pos === "before" && nextHd !== targetHeader) || (pos === "after" && prevHd !== targetHeader)) && !targetHeader.isDescendantOf(dragHeader)) {
allDropZones = Ext.dd.DragDropManager.getRelated(me);
ln = allDropZones.length;
i = 0;
for (; i < ln; i++) {
dropZone = allDropZones[i];
if (dropZone !== me && dropZone.invalidateDrop) {
dropZone.invalidateDrop();
}
}
me.valid = true;
topIndicator = me.getTopIndicator();
bottomIndicator = me.getBottomIndicator();
if (pos === 'before') {
topAnchor = 'bc-tl';
bottomAnchor = 'tc-bl';
} else {
topAnchor = 'bc-tr';
bottomAnchor = 'tc-br';
}
topXY = topIndicator.getAlignToXY(targetHeader.el, topAnchor);
bottomXY = bottomIndicator.getAlignToXY(targetHeader.el, bottomAnchor);
headerCtEl = me.headerCt.el;
minX = headerCtEl.getX() - me.indicatorXOffset;
maxX = headerCtEl.getX() + headerCtEl.getWidth();
topXY[0] = Ext.Number.constrain(topXY[0], minX, maxX);
bottomXY[0] = Ext.Number.constrain(bottomXY[0], minX, maxX);
topIndicator.setXY(topXY);
bottomIndicator.setXY(bottomXY);
topIndicator.show();
bottomIndicator.show();
} else
{
me.invalidateDrop();
}
},
invalidateDrop: function() {
this.valid = false;
this.hideIndicators();
},
onNodeOver: function(node, dragZone, e, data) {
var me = this,
from = data.header,
doPosition, to, fromPanel, toPanel;
if (data.header.el.dom === node) {
doPosition = false;
} else {
data.isLock = data.isUnlock = data.crossPanel = false;
to = me.getLocation(e, node).header;
doPosition = (from.ownerCt === to.ownerCt);
if (!doPosition && (!from.ownerCt.sealed && !to.ownerCt.sealed)) {
doPosition = true;
fromPanel = from.up('tablepanel');
toPanel = to.up('tablepanel');
if (fromPanel !== toPanel) {
data.crossPanel = true;
data.isLock = toPanel.isLocked && !fromPanel.isLocked;
data.isUnlock = !toPanel.isLocked && fromPanel.isLocked;
if ((data.isUnlock && from.lockable === false) || (data.isLock && !from.isLockable())) {
doPosition = false;
}
}
}
}
if (doPosition) {
me.positionIndicator(data, node, e);
} else {
me.valid = false;
}
return me.valid ? me.dropAllowed : me.dropNotAllowed;
},
hideIndicators: function() {
var me = this;
me.getTopIndicator().hide();
me.getBottomIndicator().hide();
me.lastTargetHeader = me.lastDropPos = null;
},
onNodeOut: function() {
this.hideIndicators();
},
getNestedHeader: function(header, first) {
var items = header.items,
pos;
if (header.isGroupHeader && items.length) {
pos = !first ? 'first' : 'last';
header = this.getNestedHeader(items[pos](), first);
}
return header;
},
onNodeDrop: function(node, dragZone, e, data) {
if (!this.valid) {
return;
}
var me = this,
dragHeader = data.header,
dropLocation = data.dropLocation,
dropPosition = dropLocation.pos,
targetHeader = dropLocation.header,
fromCt = dragHeader.ownerCt,
fromCtRoot = fromCt.getRootHeaderCt(),
toCt = targetHeader.ownerCt,
visibleColumnManager = me.headerCt.visibleColumnManager,
visibleFromIdx = visibleColumnManager.getHeaderIndex(dragHeader),
visibleToIdx, colsToMove, moveMethod, scrollerOwner, savedWidth;
if (data.isLock || data.isUnlock) {
scrollerOwner = fromCt.up('[scrollerOwner]');
visibleToIdx = toCt.items.indexOf(targetHeader);
if (dropPosition === 'after') {
visibleToIdx++;
}
if (data.isLock) {
scrollerOwner.lock(dragHeader, visibleToIdx, toCt);
} else {
scrollerOwner.unlock(dragHeader, visibleToIdx, toCt);
}
} else
{
visibleToIdx = dropPosition === 'after' ?
visibleColumnManager.getHeaderIndex(me.getNestedHeader(targetHeader, 1)) + 1 :
visibleColumnManager.getHeaderIndex(me.getNestedHeader(targetHeader, 0));
me.invalidateDrop();
savedWidth = dragHeader.getWidth();
Ext.suspendLayouts();
fromCt.isDDMoveInGrid = toCt.isDDMoveInGrid = !data.crossPanel;
if (dragHeader.isGroupHeader && targetHeader.isGroupHeader) {
dragHeader.setNestedParent(targetHeader);
}
if (dropPosition === 'before') {
targetHeader.insertNestedHeader(dragHeader);
} else {
moveMethod = 'move' + dropPosition.charAt(0).toUpperCase() + dropPosition.substr(1);
toCt[moveMethod](dragHeader, targetHeader);
}
if (visibleToIdx >= 0 && !(targetHeader.isGroupHeader && !targetHeader.items.length) && visibleFromIdx !== visibleToIdx) {
colsToMove = dragHeader.isGroupHeader ? dragHeader.query(':not([hidden]):not([isGroupHeader])').length : 1;
if ((visibleFromIdx <= visibleToIdx) && colsToMove > 1) {
visibleToIdx -= colsToMove;
}
toCt.getRootHeaderCt().grid.view.moveColumn(visibleFromIdx, visibleToIdx, colsToMove);
}
fromCtRoot.fireEvent('columnmove', fromCt, dragHeader, visibleFromIdx, visibleToIdx);
fromCt.isDDMoveInGrid = toCt.isDDMoveInGrid = false;
if (toCt.isGroupHeader && !fromCt.isGroupHeader) {
if (fromCt !== toCt) {
dragHeader.savedFlex = dragHeader.flex;
delete dragHeader.flex;
dragHeader.width = savedWidth;
}
} else if (!fromCt.isGroupHeader) {
if (dragHeader.savedFlex) {
dragHeader.flex = dragHeader.savedFlex;
delete dragHeader.width;
}
}
Ext.resumeLayouts(true);
}
}
});
Ext.define('Ext.grid.plugin.HeaderReorderer', {
extend: 'Ext.plugin.Abstract',
requires: [
'Ext.grid.header.DragZone',
'Ext.grid.header.DropZone'
],
alias: 'plugin.gridheaderreorderer',
init: function(headerCt) {
this.headerCt = headerCt;
headerCt.on({
boxready: this.onHeaderCtRender,
single: true,
scope: this
});
},
destroy: function() {
Ext.destroy(this.dragZone, this.dropZone);
},
onHeaderCtRender: function() {
var me = this;
me.dragZone = new Ext.grid.header.DragZone(me.headerCt);
me.dropZone = new Ext.grid.header.DropZone(me.headerCt);
if (me.disabled) {
me.dragZone.disable();
}
},
enable: function() {
this.disabled = false;
if (this.dragZone) {
this.dragZone.enable();
}
},
disable: function() {
this.disabled = true;
if (this.dragZone) {
this.dragZone.disable();
}
}
});
Ext.define('Ext.grid.header.Container', {
extend: 'Ext.container.Container',
requires: [
'Ext.grid.ColumnLayout',
'Ext.grid.plugin.HeaderResizer',
'Ext.grid.plugin.HeaderReorderer',
'Ext.util.KeyNav'
],
uses: [
'Ext.grid.column.Column',
'Ext.grid.ColumnManager',
'Ext.menu.Menu',
'Ext.menu.CheckItem',
'Ext.menu.Separator'
],
mixins: [
'Ext.util.FocusableContainer'
],
border: true,
alias: 'widget.headercontainer',
baseCls: Ext.baseCSSPrefix + 'grid-header-ct',
dock: 'top',
weight: 100,
defaultType: 'gridcolumn',
detachOnRemove: false,
defaultWidth: 100,
sortAscText: 'Sort Ascending',
sortDescText: 'Sort Descending',
sortClearText: 'Clear Sort',
columnsText: 'Columns',
headerOpenCls: Ext.baseCSSPrefix + 'column-header-open',
menuSortAscCls: Ext.baseCSSPrefix + 'hmenu-sort-asc',
menuSortDescCls: Ext.baseCSSPrefix + 'hmenu-sort-desc',
menuColsIcon: Ext.baseCSSPrefix + 'cols-icon',
ddLock: false,
dragging: false,
sortOnClick: true,
enableFocusableContainer: false,
childHideCount: 0,
sortable: true,
enableColumnHide: true,
initComponent: function() {
var me = this;
me.headerCounter = 0;
me.plugins = me.plugins || [];
me.defaults = me.defaults || {};
if (!me.isColumn) {
if (me.enableColumnResize) {
me.resizer = new Ext.grid.plugin.HeaderResizer();
me.plugins.push(me.resizer);
}
if (me.enableColumnMove) {
me.reorderer = new Ext.grid.plugin.HeaderReorderer();
me.plugins.push(me.reorderer);
}
}
if (me.isColumn && !me.isGroupHeader) {
if (!me.items || me.items.length === 0) {
me.isContainer = me.isFocusableContainer = false;
me.focusable = true;
me.layout = {
type: 'container',
calculate: Ext.emptyFn
};
}
} else
{
me.layout = Ext.apply({
type: 'gridcolumn',
align: 'stretch'
}, me.initialConfig.layout);
me.defaults.columnLines = me.columnLines;
if (!me.isGroupHeader) {
me.isRootHeader = true;
if (!me.hiddenHeaders) {
me.enableFocusableContainer = true;
me.ariaRole = 'row';
}
me.columnManager = new Ext.grid.ColumnManager(false, me);
me.visibleColumnManager = new Ext.grid.ColumnManager(true, me);
if (me.grid) {
me.grid.columnManager = me.columnManager;
me.grid.visibleColumnManager = me.visibleColumnManager;
}
} else {
me.visibleColumnManager = new Ext.grid.ColumnManager(true, me);
me.columnManager = new Ext.grid.ColumnManager(false, me);
}
}
me.menuTask = new Ext.util.DelayedTask(me.updateMenuDisabledState, me);
me.callParent();
},
insertNestedHeader: function(moveHeader) {
var me = this,
fromCt = moveHeader.ownerCt,
toCt = me.ownerCt,
layoutOwner = toCt.layout.owner,
toIndex;
if (fromCt) {
if (me.isGroupHeader && !toCt.isNestedParent) {
toIndex = layoutOwner.items.indexOf(me);
}
fromCt.remove(moveHeader, false);
}
if (toIndex === undefined) {
toIndex = layoutOwner.items.indexOf(me);
}
layoutOwner.insert(toIndex, moveHeader);
},
isNested: function() {
return !!this.getRootHeaderCt().down('[isNestedParent]');
},
isNestedGroupHeader: function() {
var header = this,
items = header.getRefOwner().query('>:not([hidden])');
return (items.length === 1 && items[0] === header);
},
maybeShowNestedGroupHeader: function() {
var items = this.items,
item;
if (items && items.length === 1 && (item = items.getAt(0)) && item.hidden) {
item.show();
}
},
setNestedParent: function(target) {
target.isNestedParent = false;
target.ownerCt.isNestedParent = !!(this.ownerCt.items.length === 1 && target.ownerCt.items.length === 1);
},
initEvents: function() {
var me = this,
onHeaderCtEvent, listeners;
me.callParent();
if (!me.isColumn && !me.isGroupHeader) {
onHeaderCtEvent = me.onHeaderCtEvent;
listeners = {
click: onHeaderCtEvent,
dblclick: onHeaderCtEvent,
contextmenu: onHeaderCtEvent,
mouseover: me.onHeaderCtMouseOver,
mouseout: me.onHeaderCtMouseOut,
scope: me
};
if (Ext.supports.Touch) {
listeners.longpress = me.onHeaderCtLongPress;
}
me.mon(me.el, listeners);
}
},
onHeaderCtEvent: function(e, t) {
var me = this,
headerEl = me.getHeaderElByEvent(e),
header, targetEl, activeHeader;
if (me.longPressFired) {
me.longPressFired = false;
return;
}
if (headerEl && !me.ddLock) {
header = Ext.getCmp(headerEl.id);
if (header) {
targetEl = header[header.clickTargetName];
if ((!header.isGroupHeader && !header.isContainer) || e.within(targetEl)) {
if (e.type === 'click' || e.type === 'tap') {
activeHeader = header.onTitleElClick(e, targetEl, me.sortOnClick);
if (activeHeader) {
me.onHeaderTriggerClick(activeHeader, e, Ext.supports.Touch ? activeHeader.el : activeHeader.triggerEl);
} else {
me.onHeaderClick(header, e, t);
}
} else if (e.type === 'contextmenu') {
me.onHeaderContextMenu(header, e, t);
} else if (e.type === 'dblclick' && header.resizable) {
header.onTitleElDblClick(e, targetEl.dom);
}
}
}
}
},
onHeaderCtMouseOver: function(e, t) {
var headerEl, header, targetEl;
if (!e.within(this.el, true)) {
headerEl = e.getTarget('.' + Ext.grid.column.Column.prototype.baseCls);
header = headerEl && Ext.getCmp(headerEl.id);
if (header) {
targetEl = header[header.clickTargetName];
if (e.within(targetEl)) {
header.onTitleMouseOver(e, targetEl.dom);
}
}
}
},
onHeaderCtMouseOut: function(e, t) {
var headerSelector = '.' + Ext.grid.column.Column.prototype.baseCls,
outHeaderEl = e.getTarget(headerSelector),
inHeaderEl = e.getRelatedTarget(headerSelector),
header, targetEl;
if (outHeaderEl !== inHeaderEl) {
if (outHeaderEl) {
header = Ext.getCmp(outHeaderEl.id);
if (header) {
targetEl = header[header.clickTargetName];
header.onTitleMouseOut(e, targetEl.dom);
}
}
if (inHeaderEl) {
header = Ext.getCmp(inHeaderEl.id);
if (header) {
targetEl = header[header.clickTargetName];
header.onTitleMouseOver(e, targetEl.dom);
}
}
}
},
onHeaderCtLongPress: function(e) {
var me = this,
headerEl = me.getHeaderElByEvent(e),
header = Ext.getCmp(headerEl.id);
if (!header.menuDisabled) {
me.longPressFired = true;
me.showMenuBy(e, headerEl, header);
}
},
getHeaderElByEvent: function(e) {
return e.getTarget('.' + Ext.grid.column.Column.prototype.baseCls);
},
isLayoutRoot: function() {
if (this.hiddenHeaders) {
return false;
}
return this.callParent();
},
getRootHeaderCt: function() {
var me = this;
return me.isRootHeader ? me : me.up('[isRootHeader]');
},
onDestroy: function() {
var me = this;
if (me.menu) {
me.menu.un('hide', me.onMenuHide, me);
}
me.menuTask.cancel();
me.callParent();
Ext.destroy(me.visibleColumnManager, me.columnManager, me.menu);
me.columnManager = me.visibleColumnManager = null;
},
applyColumnsState: function(columns) {
if (!columns || !columns.length) {
return;
}
var me = this,
items = me.items.items,
count = items.length,
i = 0,
length = columns.length,
c, col, columnState, index,
moved = false,
newOrder = [],
stateHash = {},
newCols = [];
for (c = 0; c < length; c++) {
columnState = columns[c];
columnState.index = c;
stateHash[columnState.id] = columnState;
}
for (i = 0; i < count; i++) {
col = items[i];
columnState = stateHash[col.getStateId()];
if (columnState) {
index = columnState.index;
newOrder[index] = col;
if (i !== index) {
moved = true;
}
if (col.applyColumnState) {
col.applyColumnState(columnState);
}
} else
{
newCols.push({
index: i,
column: col
});
}
}
newOrder = Ext.Array.clean(newOrder);
length = newCols.length;
if (length) {
for (i = 0; i < length; i++) {
columnState = newCols[i];
index = columnState.index;
if (index < newOrder.length) {
moved = true;
Ext.Array.splice(newOrder, index, 0, columnState.column);
} else {
newOrder.push(columnState.column);
}
}
}
if (moved) {
me.removeAll(false);
me.add(newOrder);
me.purgeCache();
}
},
getColumnsState: function() {
var me = this,
columns = [],
state;
me.items.each(function(col) {
state = col.getColumnState && col.getColumnState();
if (state) {
columns.push(state);
}
});
return columns;
},
onAdd: function(c) {
var me = this;
if (!c.headerId) {
c.headerId = c.initialConfig.id || Ext.id(null, 'header-');
}
if (c.sortable === undefined) {
c.sortable = me.sortable;
}
if (!c.getStateId()) {
c.stateId = c.initialConfig.id || ('h' + (++me.headerCounter));
}
if (!me._usedIDs) {
me._usedIDs = {};
}
if (me._usedIDs[c.headerId]) {
Ext.log.warn(this.$className + ' attempted to reuse an existing id: ' + c.headerId);
}
me._usedIDs[c.headerId] = true;
me.callParent(arguments);
me.onHeadersChanged(c, me.isDDMoveInGrid);
},
move: function(fromIdx, toIdx) {
var me = this,
items = me.items,
headerToMove;
if (fromIdx.isComponent) {
headerToMove = fromIdx;
fromIdx = items.indexOf(headerToMove);
} else {
headerToMove = items.getAt(fromIdx);
}
headerToMove.visibleFromIdx = me.getRootHeaderCt().visibleColumnManager.indexOf(headerToMove);
me.callParent(arguments);
},
onMove: function(headerToMove, fromIdx, toIdx) {
var me = this,
gridHeaderCt = me.getRootHeaderCt(),
gridVisibleColumnManager = gridHeaderCt.visibleColumnManager,
numColsToMove = 1,
visibleToIdx;
me.onHeadersChanged(headerToMove, true);
visibleToIdx = gridVisibleColumnManager.indexOf(headerToMove);
if (visibleToIdx >= headerToMove.visibleFromIdx) {
visibleToIdx++;
}
me.callParent(arguments);
if (headerToMove.isGroupHeader) {
numColsToMove = headerToMove.visibleColumnManager.getColumns().length;
}
gridHeaderCt.onHeaderMoved(headerToMove, numColsToMove, headerToMove.visibleFromIdx, visibleToIdx);
},
onRemove: function(c) {
var me = this,
ownerCt = me.ownerCt;
me.callParent(arguments);
if (!me._usedIDs) {
me._usedIDs = {};
}
delete me._usedIDs[c.headerId];
if (!me.destroying) {
if (!me.isDDMoveInGrid) {
me.onHeadersChanged(c, false);
}
if (me.isGroupHeader && !me.isNestedParent && ownerCt && !me.items.getCount()) {
if (c.rendered) {
me.detachComponent(c);
}
Ext.suspendLayouts();
ownerCt.remove(me);
Ext.resumeLayouts(true);
}
}
},
onHeadersChanged: function(c, isMove) {
var gridPanel,
gridHeaderCt = this.getRootHeaderCt();
this.purgeHeaderCtCache(this);
if (gridHeaderCt) {
gridHeaderCt.onColumnsChanged();
if (!c.isGroupHeader) {
gridPanel = gridHeaderCt.ownerCt;
if (gridPanel && !isMove) {
gridPanel.onHeadersChanged(gridHeaderCt, c);
}
}
}
},
onHeaderMoved: function(header, colsToMove, fromIdx, toIdx) {
var me = this,
gridSection = me.ownerCt;
if (me.rendered) {
if (gridSection && gridSection.onHeaderMove) {
gridSection.onHeaderMove(me, header, colsToMove, fromIdx, toIdx);
}
me.fireEvent('columnmove', me, header, fromIdx, toIdx);
}
},
onColumnsChanged: function() {
var me = this,
menu = me.menu,
columnItemSeparator, columnItem;
if (me.rendered) {
me.fireEvent('columnschanged', me);
if (menu && (columnItemSeparator = menu.child('#columnItemSeparator'))) {
columnItem = menu.child('#columnItem');
columnItemSeparator.destroy();
columnItem.destroy();
}
}
},
lookupComponent: function(comp) {
var result = this.callParent(arguments);
if (!result.isGroupHeader && result.width === undefined && !result.flex) {
result.width = this.defaultWidth;
}
return result;
},
setSortState: function() {
var store = this.up('[store]').store,
columns = this.visibleColumnManager.getColumns(),
len = columns.length,
i, header, sorter;
for (i = 0; i < len; i++) {
header = columns[i];
sorter = store.getSorters().get(header.getSortParam());
header.setSortState(sorter);
}
},
getHeaderMenu: function() {
var menu = this.getMenu(),
item;
if (menu) {
item = menu.child('#columnItem');
if (item) {
return item.menu;
}
}
return null;
},
onHeaderVisibilityChange: function(header, visible) {
var me = this,
menu = me.getHeaderMenu(),
item;
me.purgeHeaderCtCache(header.ownerCt);
if (menu) {
item = me.getMenuItemForHeader(menu, header);
if (item) {
item.setChecked(visible, true);
}
if (menu.isVisible()) {
me.menuTask.delay(50);
}
}
},
updateMenuDisabledState: function(menu) {
var me = this,
columns = me.query(':not([hidden])'),
i,
len = columns.length,
item, checkItem, method;
if (!menu) {
menu = me.getMenu();
}
for (i = 0; i < len; ++i) {
item = columns[i];
checkItem = me.getMenuItemForHeader(menu, item);
if (checkItem) {
method = item.isHideable() ? 'enable' : 'disable';
if (checkItem.menu) {
method += 'CheckChange';
}
checkItem[method]();
}
}
},
getMenuItemForHeader: function(menu, header) {
return header ? menu.down('menucheckitem[headerId=' + header.id + ']') : null;
},
onHeaderShow: function(header) {
var me = this,
ownerCt = me.ownerCt;
if (!ownerCt) {
return;
}
if (me.forceFit) {
delete me.flex;
}
me.onHeaderVisibilityChange(header, true);
ownerCt.onHeaderShow(me, header);
me.fireEvent('columnshow', me, header);
me.fireEvent('columnschanged', this);
},
onHeaderHide: function(header) {
var me = this,
ownerCt = me.ownerCt;
if (!ownerCt) {
return;
}
me.onHeaderVisibilityChange(header, false);
ownerCt.onHeaderHide(me, header);
me.fireEvent('columnhide', me, header);
me.fireEvent('columnschanged', this);
},
onHeaderResize: function(header, w) {
var me = this,
gridSection = me.ownerCt;
if (gridSection) {
gridSection.onHeaderResize(me, header, w);
}
me.fireEvent('columnresize', me, header, w);
},
onHeaderClick: function(header, e, t) {
var me = this,
selModel = header.getView().getSelectionModel();
header.fireEvent('headerclick', me, header, e, t);
if (me.fireEvent('headerclick', me, header, e, t) !== false) {
if (selModel.onHeaderClick) {
selModel.onHeaderClick(me, header, e);
}
}
},
onHeaderContextMenu: function(header, e, t) {
header.fireEvent('headercontextmenu', this, header, e, t);
this.fireEvent('headercontextmenu', this, header, e, t);
},
onHeaderTriggerClick: function(header, e, t) {
var me = this;
if (header.fireEvent('headertriggerclick', me, header, e, t) !== false && me.fireEvent('headertriggerclick', me, header, e, t) !== false) {
if (header.activeMenu) {
if (e.pointerType) {
header.activeMenu.hide();
} else {
header.activeMenu.focus();
}
} else {
me.showMenuBy(e, t, header);
}
}
},
showMenuBy: function(clickEvent, t, header) {
var menu = this.getMenu(),
ascItem = menu.down('#ascItem'),
descItem = menu.down('#descItem'),
sortableMth;
menu.activeHeader = menu.ownerCmp = header;
header.setMenuActive(menu);
sortableMth = header.sortable ? 'enable' : 'disable';
if (ascItem) {
ascItem[sortableMth]();
}
if (descItem) {
descItem[sortableMth]();
}
menu.autoFocus = !clickEvent || !clickEvent.pointerType;
menu.showBy(t, 'tl-bl?');
if (!menu.isVisible()) {
this.onMenuHide(menu);
}
},
hideMenu: function() {
if (this.menu) {
this.menu.hide();
}
},
onMenuHide: function(menu) {
menu.activeHeader.setMenuActive(false);
},
purgeHeaderCtCache: function(headerCt) {
while (headerCt) {
headerCt.purgeCache();
if (headerCt.isRootHeader) {
return;
}
headerCt = headerCt.ownerCt;
}
},
purgeCache: function() {
var me = this,
visibleColumnManager = me.visibleColumnManager,
columnManager = me.columnManager;
me.gridVisibleColumns = me.gridDataColumns = me.hideableColumns = null;
if (visibleColumnManager) {
visibleColumnManager.invalidate();
columnManager.invalidate();
}
},
getMenu: function() {
var me = this;
if (!me.menu) {
me.menu = new Ext.menu.Menu({
hideOnParentHide: false,
items: me.getMenuItems(),
listeners: {
beforeshow: me.beforeMenuShow,
hide: me.onMenuHide,
scope: me
}
});
me.fireEvent('menucreate', me, me.menu);
}
return me.menu;
},
beforeMenuShow: function(menu) {
var me = this,
columnItem = menu.child('#columnItem'),
hideableColumns, insertPoint;
if (!columnItem) {
hideableColumns = me.enableColumnHide ? me.getColumnMenu(me) : null;
insertPoint = me.sortable ? 2 : 0;
if (hideableColumns && hideableColumns.length) {
menu.insert(insertPoint, [
{
itemId: 'columnItemSeparator',
xtype: 'menuseparator'
},
{
itemId: 'columnItem',
text: me.columnsText,
iconCls: me.menuColsIcon,
menu: {
items: hideableColumns
},
hideOnClick: false
}
]);
}
}
me.updateMenuDisabledState(me.menu);
},
getMenuItems: function() {
var me = this,
menuItems = [],
hideableColumns = me.enableColumnHide ? me.getColumnMenu(me) : null;
if (me.sortable) {
menuItems = [
{
itemId: 'ascItem',
text: me.sortAscText,
iconCls: me.menuSortAscCls,
handler: me.onSortAscClick,
scope: me
},
{
itemId: 'descItem',
text: me.sortDescText,
iconCls: me.menuSortDescCls,
handler: me.onSortDescClick,
scope: me
}
];
}
if (hideableColumns && hideableColumns.length) {
if (me.sortable) {
menuItems.push({
itemId: 'columnItemSeparator',
xtype: 'menuseparator'
});
}
menuItems.push({
itemId: 'columnItem',
text: me.columnsText,
iconCls: me.menuColsIcon,
menu: hideableColumns,
hideOnClick: false
});
}
return menuItems;
},
onSortAscClick: function() {
var menu = this.getMenu(),
activeHeader = menu.activeHeader;
activeHeader.sort('ASC');
},
onSortDescClick: function() {
var menu = this.getMenu(),
activeHeader = menu.activeHeader;
activeHeader.sort('DESC');
},
getColumnMenu: function(headerContainer) {
var menuItems = [],
i = 0,
item,
items = headerContainer.query('>gridcolumn[hideable]'),
itemsLn = items.length,
menuItem;
for (; i < itemsLn; i++) {
item = items[i];
menuItem = new Ext.menu.CheckItem({
text: item.menuText || item.text,
checked: !item.hidden,
hideOnClick: false,
headerId: item.id,
menu: item.isGroupHeader ? this.getColumnMenu(item) : undefined,
checkHandler: this.onColumnCheckChange,
scope: this
});
menuItems.push(menuItem);
}
return menuItems.length ? menuItems : null;
},
onColumnCheckChange: function(checkItem, checked) {
var header = Ext.getCmp(checkItem.headerId),
headerId;
if (header.rendered) {
header[checked ? 'show' : 'hide']();
headerId = header.lastCheckedHeaderId;
if (checked && headerId) {
header.getRootHeaderCt().getMenu().down('[headerId=' + headerId + ']').setChecked(true);
header.lastCheckedHeaderId = null;
}
} else {
header.hidden = !checked;
}
},
getColumnCount: function() {
return this.getGridColumns().length;
},
getTableWidth: function() {
var fullWidth = 0,
headers = this.getVisibleGridColumns(),
headersLn = headers.length,
i;
for (i = 0; i < headersLn; i++) {
fullWidth += headers[i].getCellWidth() || 0;
}
return fullWidth;
},
getVisibleGridColumns: function() {
var me = this,
allColumns, rootHeader, result, len, i, column;
if (me.gridVisibleColumns) {
return me.gridVisibleColumns;
}
allColumns = me.getGridColumns();
rootHeader = me.getRootHeaderCt();
result = [];
len = allColumns.length;
for (i = 0; i < len; i++) {
column = allColumns[i];
if (!column.hidden && !column.isColumnHidden(rootHeader)) {
result[result.length] = column;
}
}
me.gridVisibleColumns = result;
return result;
},
isColumnHidden: function(rootHeader) {
var owner = this.getRefOwner();
while (owner && owner !== rootHeader) {
if (owner.hidden) {
return true;
}
owner = owner.getRefOwner();
}
return false;
},
getGridColumns: function(
inResult, hiddenAncestor) {
if (!inResult && this.gridDataColumns) {
return this.gridDataColumns;
}
var me = this,
result = inResult || [],
items, i, len, item, lastVisibleColumn;
hiddenAncestor = hiddenAncestor || me.hidden;
if (me.items) {
items = me.items.items;
if (items) {
for (i = 0 , len = items.length; i < len; i++) {
item = items[i];
if (item.isGroupHeader) {
item.visibleIndex = result.length;
item.getGridColumns(result, hiddenAncestor);
} else {
item.hiddenAncestor = hiddenAncestor;
result.push(item);
}
}
}
}
if (!inResult) {
me.gridDataColumns = result;
}
if (!inResult && len) {
for (i = 0 , len = result.length; i < len; i++) {
item = result[i];
item.fullColumnIndex = i;
item.isFirstVisible = item.isLastVisible = false;
if (!(item.hidden || item.hiddenAncestor)) {
if (!lastVisibleColumn) {
item.isFirstVisible = true;
}
lastVisibleColumn = item;
}
}
if (lastVisibleColumn) {
lastVisibleColumn.isLastVisible = true;
}
}
return result;
},
getHideableColumns: function() {
var me = this,
result = me.hideableColumns;
if (!result) {
result = me.hideableColumns = me.query('[hideable]');
}
return result;
},
getHeaderIndex: function(header) {
if (!this.columnManager) {
this.columnManager = this.getRootHeaderCt().columnManager;
}
return this.columnManager.getHeaderIndex(header);
},
getHeaderAtIndex: function(index) {
if (!this.columnManager) {
this.columnManager = this.getRootHeaderCt().columnManager;
}
return this.columnManager.getHeaderAtIndex(index);
},
getVisibleHeaderClosestToIndex: function(index) {
if (!this.visibleColumnManager) {
this.visibleColumnManager = this.getRootHeaderCt().visibleColumnManager;
}
return this.visibleColumnManager.getVisibleHeaderClosestToIndex(index);
},
applyForceFit: function(header) {
var me = this,
view = me.view,
minWidth = Ext.grid.plugin.HeaderResizer.prototype.minColWidth,
useMinWidthForFlex = false,
defaultWidth = Ext.grid.header.Container.prototype.defaultWidth,
availFlex = me.el.dom.clientWidth - (view.el.dom.scrollHeight > view.el.dom.clientHeight ? Ext.getScrollbarSize().width : 0),
totalFlex = 0,
items = me.getVisibleGridColumns(),
hidden = header.hidden,
len, i, item, maxAvailFlexOneColumn, myWidth;
function getTotalFlex() {
for (i = 0 , len = items.length; i < len; i++) {
item = items[i];
if (item === header) {
continue;
}
item.flex = item.flex || item.width || item.getWidth();
totalFlex += item.flex;
item.width = null;
}
}
function applyWidth() {
var isCurrentHeader;
for (i = 0 , len = items.length; i < len; i++) {
item = items[i];
isCurrentHeader = (item === header);
if (useMinWidthForFlex && !isCurrentHeader) {
item.flex = minWidth;
item.width = null;
} else if (!isCurrentHeader) {
myWidth = item.flex || defaultWidth;
item.flex = Math.max(Math.ceil((myWidth / totalFlex) * availFlex), minWidth);
item.width = null;
}
item.setWidth(item.width || item.flex);
}
}
Ext.suspendLayouts();
maxAvailFlexOneColumn = (availFlex - ((items.length + 1) * minWidth));
header.flex = null;
if (hidden) {
myWidth = header.width || header.savedWidth;
header.savedWidth = null;
} else {
myWidth = view.getMaxContentWidth(header);
}
if (myWidth > maxAvailFlexOneColumn) {
header.width = maxAvailFlexOneColumn;
useMinWidthForFlex = true;
} else {
header.width = myWidth;
availFlex -= myWidth + defaultWidth;
getTotalFlex();
}
applyWidth();
Ext.resumeLayouts(true);
},
autoSizeColumn: function(header) {
var view = this.view;
if (view) {
view.autoSizeColumn(header);
if (this.forceFit) {
this.applyForceFit(header);
}
}
},
privates: {
beginChildHide: function() {
++this.childHideCount;
},
endChildHide: function() {
--this.childHideCount;
},
getFocusables: function() {
return this.isRootHeader ? this.getVisibleGridColumns() : this.items.items;
},
createFocusableContainerKeyNav: function(el) {
var me = this;
return new Ext.util.KeyNav(el, {
scope: me,
down: me.showHeaderMenu,
left: me.onFocusableContainerLeftKey,
right: me.onFocusableContainerRightKey,
space: me.onHeaderActivate,
enter: me.onHeaderActivate
});
},
showHeaderMenu: function(e) {
var column = this.getFocusableFromEvent(e);
if (column && column.isColumn && column.triggerEl) {
this.onHeaderTriggerClick(column, e, column.triggerEl);
}
},
onHeaderActivate: function(e) {
var column = this.getFocusableFromEvent(e),
view, lastFocused;
if (column && column.isColumn) {
view = column.getView();
if (column.sortable && this.sortOnClick) {
lastFocused = view.getNavigationModel().getLastFocused();
column.toggleSortState();
if (lastFocused) {
view.ownerCt.ensureVisible(lastFocused.record);
}
}
this.onHeaderClick(column, e, column.el);
}
},
onFocusableContainerMousedown: function(e, target) {
var targetCmp = Ext.Component.fromElement(target);
if (targetCmp === this) {
e.preventDefault();
} else {
targetCmp.focus();
}
}
}
});
Ext.define('Ext.grid.ColumnComponentLayout', {
extend: 'Ext.layout.component.Auto',
alias: 'layout.columncomponent',
type: 'columncomponent',
setWidthInDom: true,
_paddingReset: {
paddingTop: '',
paddingBottom: ''
},
columnAutoCls: Ext.baseCSSPrefix + 'column-header-text-container-auto',
beginLayout: function(ownerContext) {
this.callParent(arguments);
ownerContext.titleContext = ownerContext.getEl('titleEl');
},
beginLayoutCycle: function(ownerContext) {
var me = this,
owner = me.owner,
shrinkWrap = ownerContext.widthModel.shrinkWrap;
me.callParent(arguments);
if (shrinkWrap) {
owner.el.setWidth('');
}
owner.textContainerEl[shrinkWrap ? 'addCls' : 'removeCls'](me.columnAutoCls);
owner.titleEl.setStyle(me._paddingReset);
},
publishInnerHeight: function(ownerContext, outerHeight) {
var me = this,
owner = me.owner,
innerHeight;
if (owner.getRootHeaderCt().hiddenHeaders) {
ownerContext.setProp('innerHeight', 0);
return;
}
if (!ownerContext.hasRawContent) {
if (owner.headerWrap && !ownerContext.hasDomProp('width')) {
me.done = false;
return;
}
innerHeight = outerHeight - ownerContext.getBorderInfo().height;
ownerContext.setProp('innerHeight', innerHeight - owner.titleEl.getHeight(), false);
}
},
measureContentHeight: function(ownerContext) {
return ownerContext.el.dom.offsetHeight;
},
publishInnerWidth: function(ownerContext, outerWidth) {
if (!ownerContext.hasRawContent) {
ownerContext.setProp('innerWidth', outerWidth - ownerContext.getBorderInfo().width, false);
}
},
calculateOwnerHeightFromContentHeight: function(ownerContext, contentHeight) {
var result = this.callParent(arguments),
owner = this.owner;
if (!ownerContext.hasRawContent) {
if (!owner.headerWrap || ownerContext.hasDomProp('width')) {
return contentHeight + owner.titleEl.getHeight() + ownerContext.getBorderInfo().height;
}
return null;
}
return result;
},
calculateOwnerWidthFromContentWidth: function(ownerContext, contentWidth) {
var owner = this.owner,
padWidth = ownerContext.getPaddingInfo().width,
triggerOffset = this.getTriggerOffset(owner, ownerContext),
inner;
if (owner.isGroupHeader) {
inner = contentWidth;
} else {
inner = Math.max(contentWidth, owner.textEl.getWidth() + ownerContext.titleContext.getPaddingInfo().width);
}
return inner + padWidth + triggerOffset;
},
getTriggerOffset: function(owner, ownerContext) {
var width = 0;
if (ownerContext.widthModel.shrinkWrap && !owner.menuDisabled) {
if (owner.query('>:not([hidden])').length === 0) {
width = owner.getTriggerElWidth();
}
}
return width;
}
});
Ext.define('Ext.grid.column.Column', {
extend: 'Ext.grid.header.Container',
xtype: 'gridcolumn',
requires: [
'Ext.grid.ColumnComponentLayout',
'Ext.grid.ColumnLayout',
'Ext.app.bind.Template'
],
alternateClassName: 'Ext.grid.Column',
config: {
triggerVisible: false
},
baseCls: Ext.baseCSSPrefix + 'column-header',
hoverCls: Ext.baseCSSPrefix + 'column-header-over',
handleWidth: Ext.supports.Touch ? 10 : 4,
ariaRole: 'columnheader',
enableFocusableContainer: false,
sortState: null,
possibleSortStates: [
'ASC',
'DESC'
],
childEls: [
'titleEl',
'triggerEl',
'textEl',
'textContainerEl'
],
headerWrap: false,
renderTpl: [
'<div id="{id}-titleEl" data-ref="titleEl" {tipMarkup}class="',
Ext.baseCSSPrefix,
'column-header-inner<tpl if="!$comp.isContainer"> ',
Ext.baseCSSPrefix,
'leaf-column-header</tpl>',
'<tpl if="empty"> ',
Ext.baseCSSPrefix,
'column-header-inner-empty</tpl>">',
'<span id="{id}-textContainerEl" data-ref="textContainerEl" class="',
Ext.baseCSSPrefix,
'column-header-text-container">',
'<span class="',
Ext.baseCSSPrefix,
'column-header-text-wrapper">',
'<span id="{id}-textEl" data-ref="textEl" class="',
Ext.baseCSSPrefix,
'column-header-text',
'{childElCls}">',
'{text}',
'</span>',
'</span>',
'</span>',
'<tpl if="!menuDisabled">',
'<div id="{id}-triggerEl" data-ref="triggerEl" role="presentation" class="',
Ext.baseCSSPrefix,
'column-header-trigger',
'{childElCls}" style="{triggerStyle}"></div>',
'</tpl>',
'</div>',
'{%this.renderContainer(out,values)%}'
],
dataIndex: null,
text: '&#160;',
menuText: null,
emptyCellText: '&#160;',
sortable: true,
resizable: true,
hideable: true,
menuDisabled: false,
renderer: false,
align: 'left',
draggable: true,
tooltipType: 'qtip',
initDraggable: Ext.emptyFn,
tdCls: '',
producesHTML: true,
isHeader: true,
isColumn: true,
tabIndex: -1,
ascSortCls: Ext.baseCSSPrefix + 'column-header-sort-ASC',
descSortCls: Ext.baseCSSPrefix + 'column-header-sort-DESC',
componentLayout: 'columncomponent',
groupSubHeaderCls: Ext.baseCSSPrefix + 'group-sub-header',
groupHeaderCls: Ext.baseCSSPrefix + 'group-header',
clickTargetName: 'titleEl',
detachOnRemove: true,
initResizable: Ext.emptyFn,
rendererNames: {
column: 'renderer',
edit: 'editRenderer',
summary: 'summaryRenderer'
},
formatterNames: {
column: 'formatter',
edit: 'editFormatter',
summary: 'summaryFormatter'
},
initComponent: function() {
var me = this;
me.rendererScope = me.initialConfig.scope;
if (me.header != null) {
me.text = me.header;
me.header = null;
}
if (me.cellWrap) {
me.tdCls = (me.tdCls || '') + ' ' + Ext.baseCSSPrefix + 'wrap-cell';
}
if (me.columns != null) {
me.isGroupHeader = true;
if (me.dataIndex) {
Ext.Error.raise('Ext.grid.column.Column: Group header may not accept a dataIndex');
}
if ((me.width && me.width !== Ext.grid.header.Container.prototype.defaultWidth) || me.flex) {
Ext.Error.raise('Ext.grid.column.Column: Group header does not support setting explicit widths or flexs. The group header width is calculated by the sum of its children.');
}
me.items = me.columns;
me.columns = me.flex = me.width = null;
me.cls = (me.cls || '') + ' ' + me.groupHeaderCls;
me.sortable = me.resizable = false;
me.align = 'center';
} else {
if (me.flex) {
me.minWidth = me.minWidth || Ext.grid.plugin.HeaderResizer.prototype.minColWidth;
}
}
me.addCls(Ext.baseCSSPrefix + 'column-header-align-' + me.align);
me.setupRenderer();
me.setupRenderer('edit');
me.setupRenderer('summary');
me.callParent(arguments);
},
bindFormatter: function(format) {
var me = this;
return function(v) {
return format.format(v, format.scope || me.rendererScope || me.resolveListenerScope());
};
},
bindRenderer: function(renderer) {
var me = this;
if (renderer in Ext.util.Format) {
Ext.log.warn('Use "formatter" config instead of "renderer" to use ' + 'Ext.util.Format to format cell values');
}
me.hasCustomRenderer = true;
return function() {
return Ext.callback(renderer, me.rendererScope, arguments, 0, me);
};
},
setupRenderer: function(type) {
type = type || 'column';
var me = this,
format = me[me.formatterNames[type]],
renderer = me[me.rendererNames[type]],
isColumnRenderer = type === 'column',
scoped;
if (!format) {
if (renderer) {
if (typeof renderer === 'string') {
renderer = me[me.rendererNames[type]] = me.bindRenderer(renderer);
}
if (isColumnRenderer) {
me.hasCustomRenderer = renderer.length > 1;
}
}
else if (isColumnRenderer && me.defaultRenderer) {
me.renderer = me.defaultRenderer;
me.usingDefaultRenderer = true;
}
} else {
scoped = format.indexOf('this.') === 0;
if (scoped) {
format = format.substring(5);
}
format = Ext.app.bind.Template.prototype.parseFormat(format);
me[me.formatterNames[type]] = null;
if (scoped) {
format.scope = null;
}
else if (!Ext.util.Format[format.fmt]) {
Ext.Error.raise('Invalid formatter specified: "' + format.fmt + '"');
}
me[me.rendererNames[type]] = me.bindFormatter(format);
}
},
getView: function() {
var rootHeaderCt = this.getRootHeaderCt();
if (rootHeaderCt) {
return rootHeaderCt.view;
}
},
onResize: function(width, height, oldWidth, oldHeight) {
var me = this,
view, bufferedRenderer;
me.callParent(arguments);
if (oldWidth && me.cellWrap) {
view = me.getView();
if (view) {
bufferedRenderer = view.bufferedRenderer;
if (bufferedRenderer) {
bufferedRenderer.onWrappedColumnWidthChange(oldWidth, width);
}
}
}
},
onFocusLeave: function(e) {
this.callParent([
e
]);
if (this.activeMenu) {
this.activeMenu.hide();
}
},
initItems: function() {
var me = this;
me.callParent(arguments);
if (me.isGroupHeader) {
if (me.config.hidden || !me.hasVisibleChildColumns()) {
me.hide();
}
}
},
hasVisibleChildColumns: function() {
var items = this.items.items,
len = items.length,
i, item;
for (i = 0; i < len; ++i) {
item = items[i];
if (item.isColumn && !item.hidden) {
return true;
}
}
return false;
},
onAdd: function(child) {
var me = this;
if (child.isColumn) {
child.isSubHeader = true;
child.addCls(me.groupSubHeaderCls);
}
if (me.isGroupHeader && me.hidden && me.hasVisibleChildColumns()) {
me.show();
}
me.callParent([
child
]);
},
onRemove: function(child) {
var me = this;
if (child.isSubHeader) {
child.isSubHeader = false;
child.removeCls(me.groupSubHeaderCls);
}
me.callParent([
child
]);
if (!(me.isDestroyed || me.destroying) && !me.hasVisibleChildColumns() && !me.ownerCt.isNested()) {
me.hide();
}
},
initRenderData: function() {
var me = this,
tipMarkup = '',
tip = me.tooltip,
text = me.text,
attr = me.tooltipType === 'qtip' ? 'data-qtip' : 'title';
if (!Ext.isEmpty(tip)) {
tipMarkup = attr + '="' + tip + '" ';
}
return Ext.applyIf(me.callParent(arguments), {
text: text,
empty: text === '&#160;' || text === ' ' || text === '',
menuDisabled: me.menuDisabled,
tipMarkup: tipMarkup,
triggerStyle: this.getTriggerVisible() ? 'display:block' : ''
});
},
applyColumnState: function(state) {
var me = this;
me.applyColumnsState(state.columns);
if (state.hidden != null) {
me.hidden = state.hidden;
}
if (state.locked != null) {
me.locked = state.locked;
}
if (state.sortable != null) {
me.sortable = state.sortable;
}
if (state.width != null) {
me.flex = null;
me.width = state.width;
} else if (state.flex != null) {
me.width = null;
me.flex = state.flex;
}
},
getColumnState: function() {
var me = this,
items = me.items.items,
iLen = items ? items.length : 0,
i,
columns = [],
state = {
id: me.stateId || me.getStateId()
};
me.savePropsToState([
'hidden',
'sortable',
'locked',
'flex',
'width'
], state);
if (me.isGroupHeader) {
for (i = 0; i < iLen; i++) {
columns.push(items[i].getColumnState());
}
if (columns.length) {
state.columns = columns;
}
}
if ('width' in state) {
delete state.flex;
}
return state;
},
getStateId: function() {
return (this.stateId = this.stateId || this.headerId);
},
setText: function(text) {
this.text = text;
if (this.rendered) {
this.textEl.setHtml(text);
}
},
getIndex: function() {
return this.isGroupColumn ? false : this.getRootHeaderCt().getHeaderIndex(this);
},
getVisibleIndex: function() {
return this.visibleIndex != null ? this.visibleIndex : this.isGroupColumn ? false : Ext.Array.indexOf(this.getRootHeaderCt().getVisibleGridColumns(), this);
},
beforeRender: function() {
var me = this,
rootHeaderCt = me.getRootHeaderCt();
me.callParent();
if (!me.isSortable() && !me.groupable && !me.lockable && (rootHeaderCt.grid.enableColumnHide === false || !rootHeaderCt.getHideableColumns().length)) {
me.menuDisabled = true;
}
if (me.cellWrap) {
me.variableRowHeight = true;
}
me.protoEl.unselectable();
},
getTriggerElWidth: function() {
var me = this,
triggerEl = me.triggerEl,
width = me.self.triggerElWidth;
if (triggerEl && width === undefined) {
triggerEl.setStyle('display', 'block');
width = me.self.triggerElWidth = triggerEl.getWidth();
triggerEl.setStyle('display', '');
}
return width;
},
afterComponentLayout: function(width, height, oldWidth, oldHeight) {
var me = this,
rootHeaderCt = me.getRootHeaderCt();
me.callParent(arguments);
if (rootHeaderCt && (oldWidth != null || me.flex) && width !== oldWidth) {
rootHeaderCt.onHeaderResize(me, width);
}
},
onDestroy: function() {
var me = this;
Ext.destroy(me.field);
me.field = null;
me.callParent(arguments);
},
onTitleMouseOver: function() {
this.titleEl.addCls(this.hoverCls);
},
onTitleMouseOut: function() {
this.titleEl.removeCls(this.hoverCls);
},
onDownKey: function(e) {
if (this.triggerEl) {
this.onTitleElClick(e, this.triggerEl.dom || this.el.dom);
}
},
onEnterKey: function(e) {
this.onTitleElClick(e, this.el.dom);
},
onTitleElDblClick: function(e) {
var me = this,
prev, leafColumns, headerCt;
if (me.isAtStartEdge(e)) {
prev = me.previousNode('gridcolumn:not([hidden]):not([isGroupHeader])');
if (prev && prev.getRootHeaderCt() === me.getRootHeaderCt()) {
prev.autoSize();
}
}
else if (me.isAtEndEdge(e)) {
if (me.isGroupHeader && e.getPoint().isContainedBy(me.layout.innerCt)) {
leafColumns = me.query('gridcolumn:not([hidden]):not([isGroupHeader])');
me.getRootHeaderCt().autoSizeColumn(leafColumns[leafColumns.length - 1]);
return;
} else {
headerCt = me.getRootHeaderCt();
if (headerCt.visibleColumnManager.getColumns().length === 1 && headerCt.forceFit) {
return;
}
}
me.autoSize();
}
},
autoSize: function() {
var me = this,
leafColumns, numLeaves, i, headerCt;
if (me.isGroupHeader) {
leafColumns = me.query('gridcolumn:not([hidden]):not([isGroupHeader])');
numLeaves = leafColumns.length;
headerCt = me.getRootHeaderCt();
Ext.suspendLayouts();
for (i = 0; i < numLeaves; i++) {
headerCt.autoSizeColumn(leafColumns[i]);
}
Ext.resumeLayouts(true);
return;
}
me.getRootHeaderCt().autoSizeColumn(me);
},
onTitleElClick: function(e, t, sortOnClick) {
var me = this,
activeHeader, prevSibling;
if (Ext.supports.Touch) {
prevSibling = me.previousSibling(':not([hidden])');
if (!me.menuDisabled && me.isAtEndEdge(e, parseInt(me.triggerEl.getStyle('width'), 10))) {
if (!me.menuDisabled) {
activeHeader = me;
}
}
else if (prevSibling && !prevSibling.menuDisabled && me.isAtStartEdge(e)) {
activeHeader = prevSibling;
}
} else {
activeHeader = me.triggerEl && (e.target === me.triggerEl.dom || t === me.triggerEl || e.within(me.triggerEl)) ? me : null;
}
if (sortOnClick !== false && (!activeHeader && !me.isAtStartEdge(e) && !me.isAtEndEdge(e) || e.getKey())) {
me.toggleSortState();
}
return activeHeader;
},
processEvent: function(type, view, cell, recordIndex, cellIndex, e) {
return this.fireEvent.apply(this, arguments);
},
isSortable: function() {
var rootHeader = this.getRootHeaderCt(),
grid = rootHeader ? rootHeader.grid : null,
sortable = this.sortable;
if (grid && grid.sortableColumns === false) {
sortable = false;
}
return sortable;
},
toggleSortState: function() {
if (this.isSortable()) {
this.sort();
}
},
sort: function(direction) {
var me = this,
grid = me.up('tablepanel'),
store = grid.store;
Ext.suspendLayouts();
me.sorting = true;
store.sort(me.getSortParam(), direction, grid.multiColumnSort ? 'multi' : 'replace');
delete me.sorting;
Ext.resumeLayouts(true);
},
getSortParam: function() {
return this.dataIndex;
},
setSortState: function(sorter) {
var me = this,
direction = sorter && sorter.getDirection(),
ascCls = me.ascSortCls,
descCls = me.descSortCls,
rootHeaderCt = me.getRootHeaderCt(),
changed;
switch (direction) {
case 'DESC':
if (!me.hasCls(descCls)) {
me.addCls(descCls);
me.sortState = 'DESC';
changed = true;
};
me.removeCls(ascCls);
break;
case 'ASC':
if (!me.hasCls(ascCls)) {
me.addCls(ascCls);
me.sortState = 'ASC';
changed = true;
};
me.removeCls(descCls);
break;
default:
me.removeCls([
ascCls,
descCls
]);
me.sortState = null;
break;
}
if (changed) {
rootHeaderCt.fireEvent('sortchange', rootHeaderCt, me, direction);
}
},
isHideable: function() {
var result = {
hideCandidate: this,
result: this.hideable
};
if (result.result) {
this.ownerCt.bubble(this.hasOtherMenuEnabledChildren, null, [
result
]);
}
return result.result;
},
hasOtherMenuEnabledChildren: function(result) {
var visibleChildren, count;
if (!this.isXType('headercontainer')) {
result.result = false;
return false;
}
visibleChildren = this.query('>:not([hidden]):not([menuDisabled])');
count = visibleChildren.length;
if (Ext.Array.contains(visibleChildren, result.hideCandidate)) {
count--;
}
if (count) {
return false;
}
result.hideCandidate = this;
},
isLockable: function() {
var result = {
result: this.lockable !== false
};
if (result.result) {
this.ownerCt.bubble(this.hasMultipleVisibleChildren, null, [
result
]);
}
return result.result;
},
isLocked: function() {
return this.locked || !!this.up('[isColumn][locked]', '[isRootHeader]');
},
hasMultipleVisibleChildren: function(result) {
if (!this.isXType('headercontainer')) {
result.result = false;
return false;
}
if (this.query('>:not([hidden])').length > 1) {
return false;
}
},
hide: function() {
var me = this,
rootHeaderCt = me.getRootHeaderCt(),
owner = me.getRefOwner();
if (owner.constructing) {
me.callParent();
return me;
}
if (me.rendered && !me.isVisible()) {
return me;
}
if (rootHeaderCt.forceFit) {
me.visibleSiblingCount = rootHeaderCt.getVisibleGridColumns().length - 1;
if (me.flex) {
me.savedWidth = me.getWidth();
me.flex = null;
}
}
rootHeaderCt.beginChildHide();
Ext.suspendLayouts();
if (owner.isGroupHeader) {
if (me.isNestedGroupHeader()) {
owner.hide();
}
if (me.isSubHeader && !me.isGroupHeader && owner.query('>:not([hidden])').length === 1) {
owner.lastCheckedHeaderId = me.id;
}
}
me.callParent();
rootHeaderCt.endChildHide();
rootHeaderCt.onHeaderHide(me);
Ext.resumeLayouts(true);
return me;
},
show: function() {
var me = this,
rootHeaderCt = me.getRootHeaderCt(),
ownerCt = me.ownerCt;
if (me.isVisible()) {
return me;
}
if (me.rendered) {
if (rootHeaderCt.forceFit) {
rootHeaderCt.applyForceFit(me);
}
}
Ext.suspendLayouts();
if (me.isSubHeader && ownerCt.hidden) {
ownerCt.show(false, true);
}
me.callParent(arguments);
if (me.isGroupHeader) {
me.maybeShowNestedGroupHeader();
}
ownerCt = me.getRootHeaderCt();
if (ownerCt) {
ownerCt.onHeaderShow(me);
}
Ext.resumeLayouts(true);
return me;
},
getCellWidth: function() {
var me = this,
result;
if (me.rendered && me.componentLayout && me.componentLayout.lastComponentSize) {
result = me.componentLayout.lastComponentSize.width;
} else if (me.width) {
result = me.width;
}
else if (!me.isColumn) {
result = me.getTableWidth();
}
return result;
},
getCellId: function() {
return Ext.baseCSSPrefix + 'grid-cell-' + this.getItemId();
},
getCellSelector: function() {
return '.' + this.getCellId();
},
getCellInnerSelector: function() {
return this.getCellSelector() + ' .' + Ext.baseCSSPrefix + 'grid-cell-inner';
},
isAtStartEdge: function(e) {
return (e.getXY()[0] - this.getX() < this.handleWidth);
},
isAtEndEdge: function(e, margin) {
return (this.getX() + this.getWidth() - e.getXY()[0] <= (margin || this.handleWidth));
},
setMenuActive: function(menu) {
this.activeMenu = menu;
this.titleEl[menu ? 'addCls' : 'removeCls'](this.headerOpenCls);
},
deprecated: {
5: {
methods: {
bindRenderer: function(renderer) {
return function(value) {
return Ext.util.Format[renderer](value);
};
}
}
}
}
});
Ext.define('Ext.tree.Column', {
extend: 'Ext.grid.column.Column',
alias: 'widget.treecolumn',
tdCls: Ext.baseCSSPrefix + 'grid-cell-treecolumn',
autoLock: true,
lockable: false,
draggable: false,
hideable: false,
iconCls: Ext.baseCSSPrefix + 'tree-icon',
checkboxCls: Ext.baseCSSPrefix + 'tree-checkbox',
elbowCls: Ext.baseCSSPrefix + 'tree-elbow',
expanderCls: Ext.baseCSSPrefix + 'tree-expander',
textCls: Ext.baseCSSPrefix + 'tree-node-text',
innerCls: Ext.baseCSSPrefix + 'grid-cell-inner-treecolumn',
isTreeColumn: true,
cellTpl: [
'<tpl for="lines">',
'<img src="{parent.blankUrl}" class="{parent.childCls} {parent.elbowCls}-img ',
'{parent.elbowCls}-<tpl if=".">line<tpl else>empty</tpl>" role="presentation"/>',
'</tpl>',
'<img src="{blankUrl}" class="{childCls} {elbowCls}-img {elbowCls}',
'<tpl if="isLast">-end</tpl><tpl if="expandable">-plus {expanderCls}</tpl>" role="presentation"/>',
'<tpl if="checked !== null">',
'<input type="button" {ariaCellCheckboxAttr}',
' class="{childCls} {checkboxCls}<tpl if="checked"> {checkboxCls}-checked</tpl>"/>',
'</tpl>',
'<img src="{blankUrl}" role="presentation" class="{childCls} {baseIconCls} ',
'{baseIconCls}-<tpl if="leaf">leaf<tpl else>parent</tpl> {iconCls}"',
'<tpl if="icon">style="background-image:url({icon})"</tpl>/>',
'<tpl if="href">',
'<a href="{href}" role="link" target="{hrefTarget}" class="{textCls} {childCls}">{value}</a>',
'<tpl else>',
'<span class="{textCls} {childCls}">{value}</span>',
'</tpl>'
],
initComponent: function() {
var me = this;
me.setupRenderer();
me.innerRenderer = me.renderer;
me.renderer = me.treeRenderer;
me.scope = me;
me.callParent();
me.hasCustomRenderer = me.innerRenderer && me.innerRenderer.length > 1;
},
treeRenderer: function(value, metaData, record, rowIdx, colIdx, store, view) {
var me = this,
cls = record.get('cls'),
rendererData;
if (metaData && cls) {
metaData.tdCls += ' ' + cls;
}
rendererData = me.initTemplateRendererData(value, metaData, record, rowIdx, colIdx, store, view);
return me.getTpl('cellTpl').apply(rendererData);
},
initTemplateRendererData: function(value, metaData, record, rowIdx, colIdx, store, view) {
var me = this,
innerRenderer = me.innerRenderer,
data = record.data,
parent = record.parentNode,
rootVisible = view.rootVisible,
lines = [],
parentData;
while (parent && (rootVisible || parent.data.depth > 0)) {
parentData = parent.data;
lines[rootVisible ? parentData.depth : parentData.depth - 1] = parentData.isLast ? 0 : 1;
parent = parent.parentNode;
}
return {
record: record,
baseIconCls: me.iconCls,
iconCls: data.iconCls,
icon: data.icon,
checkboxCls: me.checkboxCls,
checked: data.checked,
elbowCls: me.elbowCls,
expanderCls: me.expanderCls,
textCls: me.textCls,
leaf: data.leaf,
expandable: record.isExpandable(),
isLast: record.isLastVisible(),
blankUrl: Ext.BLANK_IMAGE_URL,
href: data.href,
hrefTarget: data.hrefTarget,
lines: lines,
metaData: metaData,
childCls: me.getChildCls ? me.getChildCls() + ' ' : '',
value: innerRenderer ? innerRenderer.apply(me.rendererScope, arguments) : value
};
}
});
Ext.define('Ext.grid.NavigationModel', {
extend: 'Ext.view.NavigationModel',
alias: 'view.navigation.grid',
focusCls: Ext.baseCSSPrefix + 'grid-item-focused',
getViewListeners: function() {
var me = this;
return {
containermousedown: me.onContainerMouseDown,
cellmousedown: me.onCellMouseDown,
cellclick: me.onCellClick,
itemmousedown: me.onItemMouseDown,
itemclick: me.onItemClick,
itemcontextmenu: me.onItemClick,
scope: me
};
},
initKeyNav: function(view) {
var me = this;
me.position = new Ext.grid.CellContext(view);
me.keyNav = new Ext.util.KeyNav({
target: view,
ignoreInputFields: true,
eventName: 'itemkeydown',
defaultEventAction: 'stopEvent',
processEvent: function(view, record, row, recordIndex, event) {
return event;
},
up: me.onKeyUp,
down: me.onKeyDown,
right: me.onKeyRight,
left: me.onKeyLeft,
pageDown: me.onKeyPageDown,
pageUp: me.onKeyPageUp,
home: me.onKeyHome,
end: me.onKeyEnd,
tab: me.onKeyTab,
space: me.onKeySpace,
enter: me.onKeyEnter,
A: {
ctrl: true,
handler: me.onSelectAllKeyPress
},
scope: me
});
},
onKeyTab: function(keyEvent) {
var view = keyEvent.position.view,
selModel = view.getSelectionModel(),
editingPlugin = view.editingPlugin;
if (editingPlugin && selModel.wasEditing) {
keyEvent.preventDefault();
selModel.onEditorTab(editingPlugin, keyEvent);
} else {
return this.callParent([
keyEvent
]);
}
},
onCellMouseDown: function(view, cell, cellIndex, record, row, recordIndex, mousedownEvent) {
var parentEvent = mousedownEvent.parentEvent,
cmp = Ext.Component.fromElement(mousedownEvent.target, cell);
if (cmp && cmp.isFocusable && cmp.isFocusable()) {
return;
}
if (!parentEvent || parentEvent.type !== 'touchstart') {
this.setPosition(mousedownEvent.position, null, mousedownEvent);
}
},
onCellClick: function(view, cell, cellIndex, record, row, recordIndex, clickEvent) {
var cmp = Ext.Component.fromElement(clickEvent.target, cell);
this.preventCellFocus = cmp && cmp.focusable && cmp.isFocusable();
if (this.position.isEqual(clickEvent.position)) {
this.fireNavigateEvent(clickEvent);
} else {
this.setPosition(clickEvent.position, null, clickEvent);
}
this.preventCellFocus = false;
},
onItemMouseDown: function(view, record, item, index, mousedownEvent) {
var me = this,
x, columns, len, i, column, b,
parentEvent = mousedownEvent.parentEvent;
if (!parentEvent || parentEvent.type !== 'touchstart') {
if (!mousedownEvent.position.cellElement) {
x = mousedownEvent.getX();
columns = view.getVisibleColumnManager().getColumns();
len = columns.length;
for (i = 0; i < len; i++) {
column = columns[i];
b = columns[i].getBox();
if (x >= b.left && x < b.right) {
me.setPosition(record, columns[i], mousedownEvent);
return;
}
}
}
}
},
onItemClick: function(view, record, item, index, clickEvent) {
if (!clickEvent.position.cellElement) {
this.fireNavigateEvent(clickEvent);
}
},
beforeViewRefresh: function(view) {
var position = this.getPosition();
if (position && position.view === view) {
this.focusRestorePosition = position.clone();
} else {
this.focusRestorePosition = null;
}
},
onStoreRemove: function() {
if (this.position) {
this.setPosition(this.getPosition(), null, null, null, true);
}
},
deferSetPosition: function(delay, recordIndex, columnIndex, keyEvent, suppressEvent, preventNavigation) {
var setPositionTask = this.view.getFocusTask();
setPositionTask.delay(delay, this.setPosition, this, [
recordIndex,
columnIndex,
keyEvent,
suppressEvent,
preventNavigation
]);
return setPositionTask;
},
setPosition: function(recordIndex, columnIndex, keyEvent, suppressEvent, preventNavigation) {
var me = this,
view, selModel, dataSource, newRecordIndex, newColumnIndex, newRecord, newColumn,
clearing = recordIndex == null && columnIndex == null,
isClear = me.record == null && me.recordIndex == null && me.item == null;
if (recordIndex && recordIndex.isCellContext) {
view = recordIndex.view;
} else if (keyEvent && keyEvent.view) {
view = keyEvent.view;
} else if (me.lastFocused) {
view = me.lastFocused.view;
} else {
view = me.view;
}
selModel = view.getSelectionModel();
dataSource = view.dataSource;
view.getFocusTask().cancel();
if (view.isDestroyed || !view.refreshCounter || clearing && isClear || !view.all.getCount()) {
return;
}
if (recordIndex && recordIndex.isCellContext) {
newRecord = recordIndex.record;
newRecordIndex = recordIndex.rowIdx;
newColumnIndex = recordIndex.colIdx;
newColumn = recordIndex.column;
if (dataSource.indexOf(newRecord) === -1) {
newRecordIndex = dataSource.indexOfId(newRecord.id);
if (newRecordIndex === -1) {
me.recordIndex = -1;
newRecord = dataSource.getAt(0);
newRecordIndex = 0;
newColumnIndex = 0;
newColumn = view.getVisibleColumnManager().getColumns()[0];
} else {
newRecord = dataSource.getById(newRecord.id);
}
}
} else {
if (clearing) {
newRecord = newRecordIndex = null;
} else {
if (columnIndex == null) {
columnIndex = me.lastFocused ? me.lastFocused.column : 0;
}
if (typeof recordIndex === 'number') {
newRecordIndex = Math.max(Math.min(recordIndex, dataSource.getCount() - 1), 0);
newRecord = dataSource.getAt(recordIndex);
}
else if (recordIndex.isEntity) {
newRecord = recordIndex;
newRecordIndex = dataSource.indexOf(newRecord);
}
else if (recordIndex.tagName) {
newRecord = view.getRecord(recordIndex);
newRecordIndex = dataSource.indexOf(newRecord);
if (newRecordIndex === -1) {
newRecord = null;
}
} else {
if (isClear) {
return;
}
clearing = true;
newRecord = newRecordIndex = null;
}
}
if (newRecord) {
if (newRecordIndex === -1) {
me.recordIndex = -1;
newRecord = dataSource.getAt(0);
newRecordIndex = 0;
columnIndex = null;
}
if (columnIndex == null) {
if (!(newColumn = me.column)) {
newColumnIndex = 0;
newColumn = view.getVisibleColumnManager().getColumns()[0];
}
} else if (typeof columnIndex === 'number') {
newColumn = view.getVisibleColumnManager().getColumns()[columnIndex];
newColumnIndex = columnIndex;
} else {
newColumn = columnIndex;
newColumnIndex = view.getVisibleColumnManager().indexOf(columnIndex);
}
} else {
clearing = true;
newColumn = newColumnIndex = null;
}
}
if (newRecordIndex === me.recordIndex && newColumnIndex === me.columnIndex) {
return me.focusPosition(me.position);
}
if (me.cell) {
me.cell.removeCls(me.focusCls);
}
me.previousRecordIndex = me.recordIndex;
me.previousRecord = me.record;
me.previousItem = me.item;
me.previousCell = me.cell;
me.previousColumn = me.column;
me.previousColumnIndex = me.columnIndex;
me.previousPosition = me.position.clone();
me.selectionStart = selModel.selectionStart;
me.position.setAll(view, me.recordIndex = newRecordIndex, me.columnIndex = newColumnIndex, me.record = newRecord, me.column = newColumn);
if (clearing) {
me.item = me.cell = null;
} else {
me.focusPosition(me.position, preventNavigation);
}
if (!suppressEvent) {
selModel.fireEvent('focuschange', selModel, me.previousRecord, me.record);
view.fireEvent('rowfocus', me.record, me.item, me.recordIndex);
view.fireEvent('cellfocus', me.record, me.cell, me.position);
}
if (keyEvent && !preventNavigation && me.cell !== me.previousCell) {
me.fireNavigateEvent(keyEvent);
}
},
focusPosition: function(position) {
var me = this,
view, row;
me.item = me.cell = null;
if (position && position.record && position.column) {
view = position.view;
if (position.rowElement) {
row = me.item = position.rowElement;
} else {
row = view.getRowByRecord(position.record);
}
if (row) {
me.cell = position.cellElement || Ext.fly(row).down(position.column.getCellSelector(), true);
if (me.cell) {
me.cell = new Ext.dom.Fly(me.cell);
view.lastFocused = me.lastFocused = me.position.clone();
me.focusItem(me.cell);
view.focusEl = me.cell;
} else
{
me.position.setAll();
me.record = me.column = me.recordIndex = me.columnIndex = null;
}
} else
{
row = view.dataSource.indexOf(position.record);
me.position.setAll();
me.record = me.column = me.recordIndex = me.columnIndex = null;
if (row !== -1 && view.bufferedRenderer) {
me.lastKeyEvent = null;
view.bufferedRenderer.scrollTo(row, false, me.afterBufferedScrollTo, me);
}
}
}
},
focusItem: function(item) {
item.addCls(this.focusCls);
if (!this.preventCellFocus) {
item.focus();
}
},
getCell: function() {
return this.cell;
},
getPosition: function() {
var me = this,
position = me.position,
curIndex, view, dataSource;
if (position.record && position.column) {
view = position.view;
dataSource = view.dataSource;
curIndex = dataSource.indexOf(position.record);
if (curIndex === -1) {
curIndex = position.rowIdx;
if (!dataSource.getAt(curIndex)) {
curIndex = -1;
}
}
if (curIndex === -1 || view.getVisibleColumnManager().indexOf(position.column) === -1) {
position.setAll();
me.record = me.column = me.recordIndex = me.columnIndex = null;
} else {
return position;
}
}
return null;
},
getLastFocused: function() {
var me = this,
view,
lastFocused = me.lastFocused;
if (lastFocused && lastFocused.record && lastFocused.column) {
view = lastFocused.view;
if (view.dataSource.indexOf(lastFocused.record) !== -1 && view.getVisibleColumnManager().indexOf(lastFocused.column) !== -1) {
return lastFocused;
}
}
},
onKeyUp: function(keyEvent) {
var newRecord = keyEvent.view.walkRecs(keyEvent.record, -1);
if (newRecord) {
this.setPosition(newRecord, this.columnIndex, keyEvent);
}
},
onKeyDown: function(keyEvent) {
var newRecord = keyEvent.record.isExpandingOrCollapsing ? null : keyEvent.view.walkRecs(keyEvent.record, 1);
if (newRecord) {
this.setPosition(newRecord, this.columnIndex, keyEvent);
}
},
onKeyRight: function(keyEvent) {
var newPosition = this.move('right', keyEvent);
if (newPosition) {
this.setPosition(newPosition, null, keyEvent);
}
},
onKeyLeft: function(keyEvent) {
var newPosition = this.move('left', keyEvent);
if (newPosition) {
this.setPosition(newPosition, null, keyEvent);
}
},
move: function(dir, keyEvent) {
var me = this,
position = me.getPosition();
if (position && position.record) {
return position.view.walkCells(position, dir, null, me.preventWrap);
}
return null;
},
onKeyPageDown: function(keyEvent) {
var me = this,
view = keyEvent.view,
rowsVisible = me.getRowsVisible(),
newIdx, newRecord;
if (rowsVisible) {
if (view.bufferedRenderer) {
newIdx = Math.min(keyEvent.recordIndex + rowsVisible, view.dataSource.getCount() - 1);
me.lastKeyEvent = keyEvent;
view.bufferedRenderer.scrollTo(newIdx, false, me.afterBufferedScrollTo, me);
} else {
newRecord = view.walkRecs(keyEvent.record, rowsVisible);
me.setPosition(newRecord, null, keyEvent);
}
}
},
onKeyPageUp: function(keyEvent) {
var me = this,
view = keyEvent.view,
rowsVisible = me.getRowsVisible(),
newIdx, newRecord;
if (rowsVisible) {
if (view.bufferedRenderer) {
newIdx = Math.max(keyEvent.recordIndex - rowsVisible, 0);
me.lastKeyEvent = keyEvent;
view.bufferedRenderer.scrollTo(newIdx, false, me.afterBufferedScrollTo, me);
} else {
newRecord = view.walkRecs(keyEvent.record, -rowsVisible);
me.setPosition(newRecord, null, keyEvent);
}
}
},
onKeyHome: function(keyEvent) {
var me = this,
view = keyEvent.view;
if (keyEvent.altKey) {
if (view.bufferedRenderer) {
me.lastKeyEvent = keyEvent;
view.bufferedRenderer.scrollTo(0, false, me.afterBufferedScrollTo, me);
} else {
me.setPosition(view.walkRecs(keyEvent.record, -view.dataSource.indexOf(keyEvent.record)), null, keyEvent);
}
} else
{
me.setPosition(keyEvent.record, 0, keyEvent);
}
},
afterBufferedScrollTo: function(newIdx, newRecord) {
this.setPosition(newRecord, null, this.lastKeyEvent, null, !this.lastKeyEvent);
},
onKeyEnd: function(keyEvent) {
var me = this,
view = keyEvent.view;
if (keyEvent.altKey) {
if (view.bufferedRenderer) {
me.lastKeyEvent = keyEvent;
view.bufferedRenderer.scrollTo(view.store.getCount() - 1, false, me.afterBufferedScrollTo, me);
} else {
me.setPosition(view.walkRecs(keyEvent.record, view.dataSource.getCount() - 1 - view.dataSource.indexOf(keyEvent.record)), null, keyEvent);
}
} else
{
me.setPosition(keyEvent.record, keyEvent.view.getVisibleColumnManager().getColumns().length - 1, keyEvent);
}
},
getRowsVisible: function() {
var rowsVisible = false,
view = this.view,
firstRow = view.all.first(),
rowHeight, gridViewHeight;
if (firstRow) {
rowHeight = firstRow.getHeight();
gridViewHeight = view.el.getHeight();
rowsVisible = Math.floor(gridViewHeight / rowHeight);
}
return rowsVisible;
},
fireNavigateEvent: function(keyEvent) {
var me = this;
me.fireEvent('navigate', {
view: me.position.view,
navigationModel: me,
keyEvent: keyEvent || new Ext.event.Event({}),
previousPosition: me.previousPosition,
previousRecordIndex: me.previousRecordIndex,
previousRecord: me.previousRecord,
previousItem: me.previousItem,
previousCell: me.previousCell,
previousColumnIndex: me.previousColumnIndex,
previousColumn: me.previousColumn,
position: me.position,
recordIndex: me.recordIndex,
record: me.record,
selectionStart: me.selectionStart,
item: me.item,
cell: me.cell,
columnIndex: me.columnIndex,
column: me.column
});
}
});
Ext.define('Ext.tree.NavigationModel', {
extend: 'Ext.grid.NavigationModel',
alias: 'view.navigation.tree',
initKeyNav: function(view) {
var me = this,
columns = me.view.ownerGrid.columns;
me.isTreeGrid = columns && columns.length > 1;
me.callParent([
view
]);
me.keyNav.map.addBinding([
{
key: '8',
shift: true,
handler: me.onAsterisk,
scope: me
},
{
key: Ext.event.Event.NUM_MULTIPLY,
handler: me.onAsterisk,
scope: me
}
]);
me.view.grid.on({
columnschanged: me.onColumnsChanged,
scope: me
});
},
onColumnsChanged: function() {
this.isTreeGrid = this.view.ownerGrid.getVisibleColumnManager().getColumns().length > 1;
},
onKeyLeft: function(keyEvent) {
var me = this,
view = keyEvent.view,
record = me.record;
if (me.isTreeGrid && !keyEvent.ctrlKey) {
return me.callParent([
keyEvent
]);
}
if (keyEvent.position.column.isTreeColumn && record.isExpanded()) {
view.collapse(record);
} else
{
record = record.parentNode;
if (record && !(record.isRoot() && !view.rootVisible)) {
me.setPosition(record, null, keyEvent);
}
}
},
onKeyRight: function(keyEvent) {
var me = this,
record = me.record;
if (me.isTreeGrid && !keyEvent.ctrlKey) {
return me.callParent([
keyEvent
]);
}
if (!record.isLeaf()) {
if (keyEvent.position.column.isTreeColumn && !record.isExpanded()) {
keyEvent.view.expand(record);
} else if (record.isExpanded()) {
record = record.childNodes[0];
if (record) {
me.setPosition(record);
}
}
}
},
onKeyEnter: function(keyEvent) {
if (this.record.data.checked != null) {
this.toggleCheck(keyEvent);
} else {
this.callParent([
keyEvent
]);
}
},
onKeySpace: function(keyEvent) {
if (this.record.data.checked != null) {
this.toggleCheck(keyEvent);
} else {
this.callParent([
keyEvent
]);
}
},
toggleCheck: function(keyEvent) {
this.view.onCheckChange(this.record);
},
onAsterisk: function(keyEvent) {
this.view.ownerCt.expandAll();
}
});
Ext.define('Ext.tree.Panel', {
extend: 'Ext.panel.Table',
alias: 'widget.treepanel',
alternateClassName: [
'Ext.tree.TreePanel',
'Ext.TreePanel'
],
requires: [
'Ext.tree.View',
'Ext.selection.TreeModel',
'Ext.tree.Column',
'Ext.data.TreeStore',
'Ext.tree.NavigationModel'
],
viewType: 'treeview',
treeCls: Ext.baseCSSPrefix + 'tree-panel',
rowLines: false,
lines: true,
useArrows: false,
singleExpand: false,
ddConfig: {
enableDrag: true,
enableDrop: true
},
rootVisible: true,
displayField: 'text',
root: null,
normalCfgCopy: [
'displayField',
'root',
'singleExpand',
'useArrows',
'lines',
'rootVisible',
'scroll'
],
lockedCfgCopy: [
'displayField',
'root',
'singleExpand',
'useArrows',
'lines',
'rootVisible'
],
isTree: true,
arrowCls: Ext.baseCSSPrefix + 'tree-arrows',
linesCls: Ext.baseCSSPrefix + 'tree-lines',
noLinesCls: Ext.baseCSSPrefix + 'tree-no-lines',
autoWidthCls: Ext.baseCSSPrefix + 'autowidth-table',
constructor: function(config) {
config = config || {};
if (config.animate === undefined) {
config.animate = Ext.isBoolean(this.animate) ? this.animate : Ext.enableFx;
}
this.enableAnimations = config.animate;
delete config.animate;
this.callParent([
config
]);
},
initComponent: function() {
var me = this,
cls = [
me.treeCls
],
store = me.store,
view;
if (me.useArrows) {
cls.push(me.arrowCls);
me.lines = false;
}
if (me.lines) {
cls.push(me.linesCls);
} else if (!me.useArrows) {
cls.push(me.noLinesCls);
}
if (Ext.isString(store)) {
store = me.store = Ext.StoreMgr.lookup(store);
} else if (!store || !store.isStore) {
store = Ext.apply({
type: 'tree',
root: me.root,
fields: me.fields,
model: me.model,
proxy: 'memory',
folderSort: me.folderSort
}, store);
store = me.store = Ext.StoreMgr.lookup(store);
} else if (me.root) {
store = me.store = Ext.data.StoreManager.lookup(store);
store.setRoot(me.root);
if (me.folderSort !== undefined) {
store.folderSort = me.folderSort;
store.sort();
}
}
store.setRootVisible(me.rootVisible);
if (!store.getRoot()) {
store.setRoot({});
}
me.viewConfig = Ext.apply({
rootVisible: me.rootVisible,
animate: me.enableAnimations,
singleExpand: me.singleExpand,
node: store.getRoot(),
hideHeaders: me.hideHeaders,
navigationModel: 'tree'
}, me.viewConfig);
if (!me.columns) {
if (me.initialConfig.hideHeaders === undefined) {
me.hideHeaders = true;
}
me.addCls(me.autoWidthCls);
me.columns = [
{
xtype: 'treecolumn',
text: 'Name',
flex: 1,
dataIndex: me.displayField
}
];
}
if (me.cls) {
cls.push(me.cls);
}
me.cls = cls.join(' ');
me.callParent();
view = me.getView();
me.relayEvents(view, [
'checkchange',
'afteritemexpand',
'afteritemcollapse'
]);
},
bindStore: function(store, initial) {
var me = this,
root = store.getRoot(),
bufferedRenderer = me.bufferedRenderer;
me.callParent(arguments);
if (bufferedRenderer) {
if (bufferedRenderer.store) {
bufferedRenderer.bindStore(store);
}
}
store.singleExpand = me.singleExpand;
me.storeListeners = me.mon(store, {
destroyable: true,
rootchange: me.onRootChange,
scope: me
});
me.storeRelayers = me.relayEvents(store, [
'beforeload',
'load'
]);
me.rootRelayers = me.mon(root, {
destroyable: true,
append: me.createRelayer('itemappend'),
remove: me.createRelayer('itemremove'),
move: me.createRelayer('itemmove', [
0,
4
]),
insert: me.createRelayer('iteminsert'),
beforeappend: me.createRelayer('beforeitemappend'),
beforeremove: me.createRelayer('beforeitemremove'),
beforemove: me.createRelayer('beforeitemmove'),
beforeinsert: me.createRelayer('beforeiteminsert'),
expand: me.createRelayer('itemexpand', [
0,
1
]),
collapse: me.createRelayer('itemcollapse', [
0,
1
]),
beforeexpand: me.createRelayer('beforeitemexpand', [
0,
1
]),
beforecollapse: me.createRelayer('beforeitemcollapse', [
0,
1
])
});
if (!me.rootVisible && !store.autoLoad && !(root.isExpanded() || root.isLoading())) {
if (root.isLoaded()) {
root.data.expanded = true;
store.onNodeExpand(root, root.childNodes);
}
else if (store.autoLoad !== false) {
root.data.expanded = false;
root.expand();
}
}
store.ownerTree = me;
if (!initial) {
me.view.setRootNode(root);
}
},
unbindStore: function() {
var me = this,
store = me.store;
if (store) {
me.callParent();
Ext.destroy(me.storeListeners, me.storeRelayers, me.rootRelayers);
delete store.ownerTree;
store.singleExpand = null;
}
},
setRootNode: function() {
return this.store.setRoot.apply(this.store, arguments);
},
getRootNode: function() {
return this.store.getRoot();
},
onRootChange: function(root) {
this.view.setRootNode(root);
},
getChecked: function() {
return this.getView().getChecked();
},
isItemChecked: function(rec) {
return rec.get('checked');
},
expandNode: function(record, deep, callback, scope) {
return this.getView().expand(record, deep, callback, scope || this);
},
collapseNode: function(record, deep, callback, scope) {
return this.getView().collapse(record, deep, callback, scope || this);
},
expandAll: function(callback, scope) {
var me = this,
root = me.getRootNode();
if (root) {
Ext.suspendLayouts();
root.expand(true, callback, scope || me);
Ext.resumeLayouts(true);
}
},
collapseAll: function(callback, scope) {
var me = this,
root = me.getRootNode(),
view = me.getView();
if (root) {
Ext.suspendLayouts();
scope = scope || me;
if (view.rootVisible) {
root.collapse(true, callback, scope);
} else {
root.collapseChildren(true, callback, scope);
}
Ext.resumeLayouts(true);
}
},
expandPath: function(path, options) {
var args = arguments,
me = this,
view = me.view,
field = (options && options.field) || me.store.model.idProperty,
select, doFocus,
separator = (options && options.separator) || '/',
callback, scope, current, index, keys, rooted, expander;
if (options && typeof options === 'object') {
field = options.field || me.store.model.idProperty;
separator = options.separator || '/';
callback = options.callback;
scope = options.scope;
select = options.select;
doFocus = options.focus;
} else
{
field = args[1] || me.store.model.idProperty;
separator = args[2] || '/';
callback = args[3];
scope = args[4];
}
if (Ext.isEmpty(path)) {
return Ext.callback(callback, scope || me, [
false,
null
]);
}
keys = path.split(separator);
rooted = !keys[0];
if (rooted) {
current = me.getRootNode();
index = 1;
} else
{
current = me.store.findNode(field, keys[0]);
index = 0;
}
if (!current || (rooted && current.get(field) !== keys[1])) {
return Ext.callback(callback, scope || me, [
false,
current
]);
}
expander = function(newChildren) {
var node = this,
len, i, value;
if (++index === keys.length) {
if (select) {
view.getSelectionModel().select(node);
}
if (doFocus) {
view.getNavigationModel().setPosition(node, 0);
}
return Ext.callback(callback, scope || me, [
true,
node,
view.getNode(node)
]);
}
for (i = 0 , len = newChildren ? newChildren.length : 0; i < len; i++) {
node = newChildren[i];
value = node.get(field);
if (value || value === 0) {
value = value.toString();
}
if (value === keys[index]) {
return node.expand(false, expander);
}
}
node = this;
Ext.callback(callback, scope || me, [
false,
node,
view.getNode(node)
]);
};
current.expand(false, expander);
},
ensureVisible: function(path, options) {
if (path.isEntity) {
return this.callParent([
path,
options
]);
}
var me = this,
field = (options && options.field) || me.store.model.idProperty,
separator = (options && options.separator) || '/',
callback, scope, keys, rooted, last, node, parentNode,
onLastExpanded = function(success, lastExpanded, lastExpandedHtmlNode, targetNode) {
if (!targetNode && success && lastExpanded) {
targetNode = lastExpanded.findChild(field, last);
}
if (targetNode) {
me.doEnsureVisible(targetNode, options);
} else {
Ext.callback(callback, scope || me, [
false,
lastExpanded
]);
}
};
if (options) {
callback = options.callback;
scope = options.scope;
}
keys = path.split(separator);
rooted = !keys[0];
last = keys.pop();
if (keys.length && !(rooted && keys.length === 1)) {
me.expandPath(keys.join(separator), field, separator, onLastExpanded);
} else
{
node = me.store.findNode(field, last);
if (node) {
parentNode = node.parentNode;
if (parentNode && !parentNode.isExpanded()) {
parentNode.expand();
}
onLastExpanded(true, null, null, node);
} else {
Ext.callback(callback, scope || me, [
false,
null
]);
}
}
},
selectPath: function(path, field, separator, callback, scope) {
this.ensureVisible(path, {
field: field,
separator: separator,
select: true,
callback: callback,
scope: scope
});
}
});
Ext.define('Ext.form.field.VTypes', (function() {
var alpha = /^[a-zA-Z_]+$/,
alphanum = /^[a-zA-Z0-9_]+$/,
email = /^(")?(?:[^\."])(?:(?:[\.])?(?:[\w\-!#$%&'*+/=?^_`{|}~]))*\1@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}$/,
url = /(((^https?)|(^ftp)):\/\/((([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*)|(localhost|LOCALHOST))\/?)/i;
return {
singleton: true,
alternateClassName: 'Ext.form.VTypes',
'email': function(value) {
return email.test(value);
},
'emailText': 'This field should be an e-mail address in the format "user@example.com"',
'emailMask': /[\w.\-@'"!#$%&'*+/=?^_`{|}~]/i,
'url': function(value) {
return url.test(value);
},
'urlText': 'This field should be a URL in the format "http:/' + '/www.example.com"',
'alpha': function(value) {
return alpha.test(value);
},
'alphaText': 'This field should only contain letters and _',
'alphaMask': /[a-z_]/i,
'alphanum': function(value) {
return alphanum.test(value);
},
'alphanumText': 'This field should only contain letters, numbers and _',
'alphanumMask': /[a-z0-9_]/i
};
}()));
Ext.define('Ext.form.trigger.Trigger', {
alias: 'trigger.trigger',
requires: [
'Ext.util.ClickRepeater'
],
mixins: [
'Ext.mixin.Factoryable'
],
factoryConfig: {
defaultType: 'trigger'
},
repeatClick: false,
hidden: false,
hideOnReadOnly: undefined,
weight: 0,
preventMouseDown: true,
baseCls: Ext.baseCSSPrefix + 'form-trigger',
focusCls: Ext.baseCSSPrefix + 'form-trigger-focus',
overCls: Ext.baseCSSPrefix + 'form-trigger-over',
clickCls: Ext.baseCSSPrefix + 'form-trigger-click',
validIdRe: Ext.validIdRe,
renderTpl: [
'<div id="{triggerId}" class="{baseCls} {baseCls}-{ui} {cls} {cls}-{ui} {extraCls} ',
'{childElCls}"<tpl if="triggerStyle"> style="{triggerStyle}"</tpl>>',
'{[values.$trigger.renderBody(values)]}',
'</div>'
],
statics: {
weightComparator: function(triggerA, triggerB) {
return triggerA.weight - triggerB.weight;
}
},
constructor: function(config) {
var me = this,
cls;
Ext.apply(me, config);
if (me.compat4Mode) {
cls = me.cls;
me.focusCls = [
me.focusCls,
cls + '-focus'
];
me.overCls = [
me.overCls,
cls + '-over'
];
me.clickCls = [
me.clickCls,
cls + '-click'
];
}
if (!me.validIdRe.test(me.id)) {
Ext.Error.raise('Invalid trigger "id": "' + me.id + '"');
}
},
afterFieldRender: function() {
this.initEvents();
},
destroy: function() {
var me = this,
clickRepeater = me.clickRepeater;
if (clickRepeater) {
clickRepeater.destroy();
}
if (me.el) {
me.el.destroy();
}
me.el = null;
me.isDestroyed = true;
},
getBodyRenderData: Ext.emptyFn,
getEl: function() {
return this.el || null;
},
getStateEl: function() {
return this.el;
},
hide: function() {
var me = this,
el = me.el;
me.hidden = true;
if (el) {
el.hide();
}
},
initEvents: function() {
var me = this,
isFieldEnabled = me.isFieldEnabled,
stateEl = me.getStateEl(),
el = me.el;
stateEl.addClsOnOver(me.overCls, isFieldEnabled, me);
stateEl.addClsOnClick(me.clickCls, isFieldEnabled, me);
if (me.repeatClick) {
me.clickRepeater = new Ext.util.ClickRepeater(el, {
preventDefault: true,
handler: me.onClick,
listeners: {
mousedown: me.onClickRepeaterMouseDown,
scope: me
},
scope: me
});
} else {
me.field.mon(el, {
click: me.onClick,
mousedown: me.onMouseDown,
scope: me
});
}
},
isFieldEnabled: function() {
return !this.field.disabled;
},
isVisible: function() {
var me = this,
field = me.field,
hidden = false;
if (me.hidden || !field || !me.rendered || me.isDestroyed) {
hidden = true;
}
return !hidden;
},
onClick: function() {
var me = this,
args = arguments,
e = me.clickRepeater ? args[1] : args[0],
handler = me.handler,
field = me.field;
if (handler && !field.readOnly && me.isFieldEnabled()) {
Ext.callback(me.handler, me.scope, [
field,
me,
e
], 0, field);
}
},
resolveListenerScope: function(scope) {
return this.field.resolveSatelliteListenerScope(this, scope);
},
onMouseDown: function(e) {
if (e.pointerType !== 'touch' && !this.field.owns(Ext.Element.getActiveElement())) {
this.field.inputEl.focus();
}
if (this.preventMouseDown) {
e.preventDefault();
}
},
onClickRepeaterMouseDown: function(clickRepeater, e) {
if (!e.parentEvent || e.parentEvent.type === 'mousedown') {
this.field.inputEl.focus();
}
e.preventDefault();
},
onFieldBlur: function() {
this.getStateEl().removeCls(this.focusCls);
},
onFieldFocus: function() {
this.getStateEl().addCls(this.focusCls);
},
onFieldRender: function() {
var me = this,
el = me.el = me.field.triggerWrap.selectNode('#' + me.domId, false);
el.setVisibilityMode(Ext.Element.DISPLAY);
me.rendered = true;
},
renderBody: function(renderData) {
var me = this,
bodyTpl = me.bodyTpl;
Ext.apply(renderData, me.getBodyRenderData());
return bodyTpl ? Ext.XTemplate.getTpl(me, 'bodyTpl').apply(renderData) : '';
},
renderTrigger: function(fieldData) {
var me = this,
width = me.width,
triggerStyle = me.hidden ? 'display:none;' : '';
if (width) {
triggerStyle += 'width:' + width;
}
return Ext.XTemplate.getTpl(me, 'renderTpl').apply({
$trigger: me,
fieldData: fieldData,
ui: fieldData.ui,
childElCls: fieldData.childElCls,
triggerId: me.domId = me.field.id + '-trigger-' + me.id,
cls: me.cls,
triggerStyle: triggerStyle,
extraCls: me.extraCls,
baseCls: me.baseCls
});
},
setHidden: function(hidden) {
if (hidden !== this.hidden) {
this[hidden ? 'hide' : 'show']();
}
},
setVisible: function(visible) {
this.setHidden(!visible);
},
show: function() {
var me = this,
el = me.el;
me.hidden = false;
if (el) {
el.show();
}
}
});
Ext.define('Ext.form.field.Text', {
extend: 'Ext.form.field.Base',
alias: 'widget.textfield',
requires: [
'Ext.form.field.VTypes',
'Ext.form.trigger.Trigger',
'Ext.util.TextMetrics'
],
alternateClassName: [
'Ext.form.TextField',
'Ext.form.Text'
],
config: {
hideTrigger: false,
triggers: undefined
},
growMin: 30,
growMax: 800,
growAppend: 'W',
allowBlank: true,
validateBlank: false,
allowOnlyWhitespace: true,
minLength: 0,
maxLength: Number.MAX_VALUE,
minLengthText: 'The minimum length for this field is {0}',
maxLengthText: 'The maximum length for this field is {0}',
blankText: 'This field is required',
regexText: '',
emptyCls: Ext.baseCSSPrefix + 'form-empty-field',
requiredCls: Ext.baseCSSPrefix + 'form-required-field',
valueContainsPlaceholder: false,
ariaRole: 'textbox',
editable: true,
repeatTriggerClick: false,
triggerWrapCls: Ext.baseCSSPrefix + 'form-trigger-wrap',
triggerWrapFocusCls: Ext.baseCSSPrefix + 'form-trigger-wrap-focus',
triggerWrapInvalidCls: Ext.baseCSSPrefix + 'form-trigger-wrap-invalid',
fieldBodyCls: Ext.baseCSSPrefix + 'form-text-field-body',
inputWrapCls: Ext.baseCSSPrefix + 'form-text-wrap',
inputWrapFocusCls: Ext.baseCSSPrefix + 'form-text-wrap-focus',
inputWrapInvalidCls: Ext.baseCSSPrefix + 'form-text-wrap-invalid',
growCls: Ext.baseCSSPrefix + 'form-text-grow',
monitorTab: true,
mimicing: false,
needArrowKeys: true,
childEls: [
'triggerWrap',
'inputWrap'
],
preSubTpl: [
'<div id="{cmpId}-triggerWrap" data-ref="triggerWrap" class="{triggerWrapCls} {triggerWrapCls}-{ui}">',
'<div id={cmpId}-inputWrap data-ref="inputWrap" class="{inputWrapCls} {inputWrapCls}-{ui}">'
],
postSubTpl: [
'</div>',
'<tpl for="triggers">{[values.renderTrigger(parent)]}</tpl>',
'</div>'
],
initComponent: function() {
var me = this,
emptyCls = me.emptyCls;
if (me.allowOnlyWhitespace === false) {
me.allowBlank = false;
}
if (me.size) {
Ext.log.warn('Ext.form.field.Text "size" config was deprecated in Ext 5.0. Please specify a "width" or use a layout instead.');
}
if (me.size) {
me.defaultBodyWidth = me.size * 6.5 + 20;
}
if (!me.onTrigger1Click) {
me.onTrigger1Click = me.onTriggerClick;
}
me.callParent();
if (me.readOnly) {
me.setReadOnly(me.readOnly);
}
me.fieldFocusCls = me.baseCls + '-focus';
me.emptyUICls = emptyCls + ' ' + emptyCls + '-' + me.ui;
me.addStateEvents('change');
},
initEvents: function() {
var me = this,
el = me.inputEl;
me.callParent();
if (me.selectOnFocus || me.emptyText) {
me.mon(el, 'mousedown', me.onMouseDown, me);
}
if (me.maskRe || (me.vtype && me.disableKeyFilter !== true && (me.maskRe = Ext.form.field.VTypes[me.vtype + 'Mask']))) {
me.mon(el, 'keypress', me.filterKeys, me);
}
if (me.enableKeyEvents) {
me.mon(el, {
scope: me,
keyup: me.onKeyUp,
keydown: me.onKeyDown,
keypress: me.onKeyPress
});
}
},
isEqual: function(value1, value2) {
return this.isEqualAsString(value1, value2);
},
onChange: function(newVal, oldVal) {
this.callParent(arguments);
this.autoSize();
},
getSubTplData: function(fieldData) {
var me = this,
value = me.getRawValue(),
isEmpty = me.emptyText && value.length < 1,
maxLength = me.maxLength,
placeholder;
if (me.enforceMaxLength) {
if (maxLength === Number.MAX_VALUE) {
maxLength = undefined;
}
} else {
maxLength = undefined;
}
if (isEmpty) {
if (Ext.supports.Placeholder) {
placeholder = me.emptyText;
} else {
value = me.emptyText;
me.valueContainsPlaceholder = true;
}
}
return Ext.apply(me.callParent(arguments), {
triggerWrapCls: me.triggerWrapCls,
inputWrapCls: me.inputWrapCls,
triggers: me.orderedTriggers,
maxLength: maxLength,
readOnly: !me.editable || me.readOnly,
placeholder: placeholder,
value: value,
fieldCls: me.fieldCls + ((isEmpty && (placeholder || value)) ? ' ' + me.emptyUICls : '') + (me.allowBlank ? '' : ' ' + me.requiredCls)
});
},
onRender: function() {
var me = this,
triggers = me.getTriggers(),
elements = [],
id, triggerEl;
if (Ext.supports.FixedTableWidthBug) {
me.el._needsTableWidthFix = true;
}
me.callParent();
if (triggers) {
this.invokeTriggers('onFieldRender');
for (id in triggers) {
elements.push(triggers[id].el);
}
triggerEl = me.triggerEl = me.triggerCell = new Ext.CompositeElement(elements, true);
}
me.inputCell = me.inputWrap;
},
afterRender: function() {
var me = this;
me.autoSize();
me.callParent();
me.invokeTriggers('afterFieldRender');
},
onMouseDown: function() {
var me = this;
if (!me.hasFocus) {
Ext.getDoc().on('mouseup', Ext.emptyFn, me, {
single: true,
preventDefault: true
});
}
},
applyTriggers: function(triggers) {
var me = this,
hideAllTriggers = me.getHideTrigger(),
readOnly = me.readOnly,
orderedTriggers = me.orderedTriggers = [],
repeatTriggerClick = me.repeatTriggerClick,
id, triggerCfg, trigger, triggerCls, i;
if (me.rendered) {
Ext.Error.raise("Cannot set triggers after field has already been rendered.");
}
if ((me.triggerCls && !triggers) || me.trigger1Cls) {
Ext.log.warn("Ext.form.field.Text: 'triggerCls' and 'trigger<n>Cls'" + " are deprecated. Use 'triggers' instead.");
}
if (!triggers) {
triggers = {};
if (me.triggerCls && !me.trigger1Cls) {
me.trigger1Cls = me.triggerCls;
}
for (i = 1; triggerCls = me['trigger' + i + 'Cls']; i++) {
triggers['trigger' + i] = {
cls: triggerCls,
extraCls: Ext.baseCSSPrefix + 'trigger-index-' + i,
handler: 'onTrigger' + i + 'Click',
compat4Mode: true,
scope: me
};
}
}
for (id in triggers) {
if (triggers.hasOwnProperty(id)) {
triggerCfg = triggers[id];
triggerCfg.field = me;
triggerCfg.id = id;
if ((readOnly && triggerCfg.hideOnReadOnly !== false) || (hideAllTriggers && triggerCfg.hidden !== false)) {
triggerCfg.hidden = true;
}
if (repeatTriggerClick && (triggerCfg.repeatClick !== false)) {
triggerCfg.repeatClick = true;
}
trigger = triggers[id] = Ext.form.trigger.Trigger.create(triggerCfg);
orderedTriggers.push(trigger);
}
}
Ext.Array.sort(orderedTriggers, Ext.form.trigger.Trigger.weightComparator);
return triggers;
},
invokeTriggers: function(methodName, args) {
var me = this,
triggers = me.getTriggers(),
id, trigger;
if (triggers) {
for (id in triggers) {
if (triggers.hasOwnProperty(id)) {
trigger = triggers[id];
trigger[methodName].apply(trigger, args || []);
}
}
}
},
getTrigger: function(id) {
return this.getTriggers()[id];
},
updateHideTrigger: function(hideTrigger) {
this.invokeTriggers(hideTrigger ? 'hide' : 'show');
},
setEditable: function(editable) {
var me = this;
me.editable = editable;
if (me.rendered) {
me.setReadOnlyAttr(!editable || me.readOnly);
}
},
setReadOnly: function(readOnly) {
var me = this,
triggers = me.getTriggers(),
hideTriggers = me.getHideTrigger(),
trigger, id;
readOnly = !!readOnly;
me.callParent([
readOnly
]);
if (me.rendered) {
me.setReadOnlyAttr(readOnly || !me.editable);
}
if (triggers) {
for (id in triggers) {
trigger = triggers[id];
if (trigger.hideOnReadOnly === true || (trigger.hideOnReadOnly !== false && !hideTriggers)) {
trigger.setVisible(!readOnly);
}
}
}
},
setReadOnlyAttr: function(readOnly) {
var me = this,
readOnlyName = 'readonly',
inputEl = me.inputEl.dom;
if (readOnly) {
inputEl.setAttribute(readOnlyName, readOnlyName);
} else {
inputEl.removeAttribute(readOnlyName);
}
},
processRawValue: function(value) {
var me = this,
stripRe = me.stripCharsRe,
newValue;
if (stripRe) {
newValue = value.replace(stripRe, '');
if (newValue !== value) {
me.setRawValue(newValue);
value = newValue;
}
}
return value;
},
onDisable: function() {
this.callParent();
if (Ext.isIE) {
this.inputEl.dom.unselectable = 'on';
}
},
onEnable: function() {
this.callParent();
if (Ext.isIE) {
this.inputEl.dom.unselectable = '';
}
},
onKeyDown: function(e) {
this.fireEvent('keydown', this, e);
},
onKeyUp: function(e) {
this.fireEvent('keyup', this, e);
},
onKeyPress: function(e) {
this.fireEvent('keypress', this, e);
},
reset: function() {
this.callParent();
this.applyEmptyText();
},
applyEmptyText: function() {
var me = this,
emptyText = me.emptyText,
isEmpty;
if (me.rendered && emptyText) {
isEmpty = me.getRawValue().length < 1 && !me.hasFocus;
if (Ext.supports.Placeholder) {
me.inputEl.dom.placeholder = emptyText;
} else if (isEmpty) {
me.setRawValue(emptyText);
me.valueContainsPlaceholder = true;
}
if (isEmpty) {
me.inputEl.addCls(me.emptyUICls);
} else {
me.inputEl.removeCls(me.emptyUICls);
}
me.autoSize();
}
},
afterFirstLayout: function() {
this.callParent();
if (Ext.isIE && this.disabled) {
var el = this.inputEl;
if (el) {
el.dom.unselectable = 'on';
}
}
},
toggleInvalidCls: function(hasError) {
var method = hasError ? 'addCls' : 'removeCls';
this.callParent();
this.triggerWrap[method](this.triggerWrapInvalidCls);
this.inputWrap[method](this.inputWrapInvalidCls);
},
beforeFocus: function() {
var me = this,
inputEl = me.inputEl,
emptyText = me.emptyText,
isEmpty;
me.callParent(arguments);
if ((emptyText && !Ext.supports.Placeholder) && (inputEl.dom.value === me.emptyText && me.valueContainsPlaceholder)) {
me.setRawValue('');
isEmpty = true;
inputEl.removeCls(me.emptyUICls);
me.valueContainsPlaceholder = false;
} else if (Ext.supports.Placeholder) {
inputEl.removeCls(me.emptyUICls);
}
},
onFocus: function(e) {
var me = this;
me.callParent(arguments);
if (me.selectOnFocus) {
me.inputEl.dom.select();
}
if (me.emptyText) {
me.autoSize();
}
me.addCls(me.fieldFocusCls);
me.triggerWrap.addCls(me.triggerWrapFocusCls);
me.inputWrap.addCls(me.inputWrapFocusCls);
me.invokeTriggers('onFieldFocus', [
e
]);
},
onBlur: function(e) {
var me = this;
me.callParent(arguments);
me.removeCls(me.fieldFocusCls);
me.triggerWrap.removeCls(me.triggerWrapFocusCls);
me.inputWrap.removeCls(me.inputWrapFocusCls);
me.invokeTriggers('onFieldBlur', [
e
]);
},
completeEdit: function(e) {
this.callParent([
e
]);
this.applyEmptyText();
},
filterKeys: function(e) {
if ((e.ctrlKey && !e.altKey) || e.isSpecialKey()) {
return;
}
var charCode = String.fromCharCode(e.getCharCode());
if (!this.maskRe.test(charCode)) {
e.stopEvent();
}
},
getState: function() {
return this.addPropertyToState(this.callParent(), 'value');
},
applyState: function(state) {
this.callParent(arguments);
if (state.hasOwnProperty('value')) {
this.setValue(state.value);
}
},
getRawValue: function() {
var me = this,
v = me.callParent();
if (v === me.emptyText && me.valueContainsPlaceholder) {
v = '';
}
return v;
},
setValue: function(value) {
var me = this,
inputEl = me.inputEl;
if (inputEl && me.emptyText && !Ext.isEmpty(value)) {
inputEl.removeCls(me.emptyUICls);
me.valueContainsPlaceholder = false;
}
me.callParent(arguments);
me.applyEmptyText();
return me;
},
getErrors: function(value) {
value = arguments.length ? (value == null ? '' : value) : this.processRawValue(this.getRawValue());
var me = this,
errors = me.callParent([
value
]),
validator = me.validator,
vtype = me.vtype,
vtypes = Ext.form.field.VTypes,
regex = me.regex,
format = Ext.String.format,
msg, trimmed, isBlank;
if (Ext.isFunction(validator)) {
msg = validator.call(me, value);
if (msg !== true) {
errors.push(msg);
}
}
trimmed = me.allowOnlyWhitespace ? value : Ext.String.trim(value);
if (trimmed.length < 1 || (value === me.emptyText && me.valueContainsPlaceholder)) {
if (!me.allowBlank) {
errors.push(me.blankText);
}
if (!me.validateBlank) {
return errors;
}
isBlank = true;
}
if (!isBlank && value.length < me.minLength) {
errors.push(format(me.minLengthText, me.minLength));
}
if (value.length > me.maxLength) {
errors.push(format(me.maxLengthText, me.maxLength));
}
if (vtype) {
if (!vtypes[vtype](value, me)) {
errors.push(me.vtypeText || vtypes[vtype + 'Text']);
}
}
if (regex && !regex.test(value)) {
errors.push(me.regexText || me.invalidText);
}
return errors;
},
selectText: function(start, end) {
var me = this,
v = me.getRawValue(),
len = v.length,
el = me.inputEl.dom,
range;
if (len > 0) {
start = start === undefined ? 0 : Math.min(start, len);
end = end === undefined ? len : Math.min(end, len);
if (el.setSelectionRange) {
el.setSelectionRange(start, end);
} else if (el.createTextRange) {
range = el.createTextRange();
range.moveStart('character', start);
range.moveEnd('character', end - len);
range.select();
}
}
},
getGrowWidth: function() {
return this.inputEl.dom.value;
},
autoSize: function() {
var me = this,
triggers, triggerId, triggerWidth, inputEl, width, value;
if (me.grow && me.rendered && me.getSizeModel().width.auto) {
inputEl = me.inputEl;
triggers = me.getTriggers();
triggerWidth = 0;
value = Ext.util.Format.htmlEncode(me.getGrowWidth() || (me.hasFocus ? '' : me.emptyText) || '');
value += me.growAppend;
for (triggerId in triggers) {
triggerWidth += triggers[triggerId].el.getWidth();
}
width = inputEl.getTextWidth(value) + triggerWidth +
me.inputWrap.getBorderWidth('lr') + me.triggerWrap.getBorderWidth('lr');
width = Math.min(Math.max(width, me.growMin), me.growMax);
me.bodyEl.setWidth(width);
me.updateLayout();
me.fireEvent('autosize', me, width);
}
},
onDestroy: function() {
var me = this;
me.invokeTriggers('destroy');
Ext.destroy(me.triggerRepeater);
me.callParent();
},
onTriggerClick: Ext.emptyFn,
privates: {
getTdType: function() {
return 'textfield';
}
},
deprecated: {
5: {
methods: {
getTriggerWidth: function() {
var triggers = this.getTriggers(),
width = 0,
id;
if (triggers && this.rendered) {
for (id in triggers) {
if (triggers.hasOwnProperty(id)) {
width += triggers[id].el.getWidth();
}
}
}
return width;
}
}
}
}
});
Ext.define('Ext.app.bindinspector.ComponentList', {
alias: 'widget.bindinspector-componentlist',
extend: 'Ext.tree.Panel',
requires: [
'Ext.form.field.Text'
],
rootVisible: false,
title: 'Component Tree',
hideHeaders: true,
bindingsIconCls: Ext.baseCSSPrefix + 'bindings-icon',
vmIconCls: Ext.baseCSSPrefix + 'vm-icon',
missingDataCls: Ext.baseCSSPrefix + 'bindinspector-missing-data',
filterVisibleCls: Ext.baseCSSPrefix + 'bindinspector-filter-visible',
lastItemCls: Ext.baseCSSPrefix + 'bindinspector-last-item',
bindingsIcon: '☍',
vmIcon: '☶',
initComponent: function() {
var me = this,
nodes = [];
me.viewConfig = {
toggleOnDblClick: false,
getRowClass: function(record, index, rowParams, store) {
var cls = [];
if (record.get('filtervisible')) {
cls.push(me.filterVisibleCls);
}
if (record.get('sansData')) {
cls.push(me.missingDataCls);
}
if (index === store.getCount() - 1) {
cls.push(me.lastItemCls);
}
return cls.join(' ');
}
};
Ext.Array.forEach(me.components, function(comp) {
nodes.push(me.buildNode(comp));
}, me);
me.store = {
model: me.Model,
root: {
expanded: true,
children: nodes
}
};
me.columns = [
{
itemId: 'srcVMIndicator',
width: 40,
hidden: true,
renderer: me.srcVMIndicator,
scope: me
},
{
xtype: 'treecolumn',
dataIndex: 'text',
flex: 1
}
];
me.dockedItems = [
{
xtype: 'toolbar',
itemId: 'queryFieldTb',
dock: 'top',
items: [
{
xtype: 'textfield',
reference: 'queryField',
itemId: 'queryField',
emptyText: 'simple search by reference / ID or use a component query...',
flex: 1,
triggers: {
clear: {
cls: Ext.baseCSSPrefix + 'form-clear-trigger',
handler: function(field) {
var tree = field.up('treepanel');
field.reset();
tree.clearComponentFilter();
field.focus();
}
}
},
listeners: {
change: {
fn: me.filterComponentTree,
buffer: 250,
scope: me
},
afterrender: {
fn: function(field) {
var tbEl = field.up('toolbar').getEl();
field.mon(tbEl, 'mouseenter', function() {
var tip = me.bindingsTip,
showAt, x, y;
tip.stopAnimation();
tip.update('<b>Simple Search</b><br>Enter the string matching the reference or ID of the target component<hr><b>Component Query</b><br>Enter a component query string to find any items matching the query');
tip.setTarget(tbEl);
tip.show();
x = tip.getX();
y = tip.getY();
showAt = tip.getAlignToXY(tbEl, 'l-r');
tip.animate({
from: {
opacity: 0,
x: showAt[0] + 20,
y: showAt[1]
},
to: {
opacity: 1,
x: showAt[0] + 10,
y: showAt[1]
}
});
});
},
scope: me
}
}
}
]
},
{
xtype: 'toolbar',
cls: Ext.baseCSSPrefix + 'vm-results-tb',
itemId: 'vmQueryResultsTb',
hidden: true,
dock: 'top',
defaultButtonUI: 'default',
items: [
'->',
{
text: 'Clear VM Filter',
handler: function() {
var tb = this.up('#vmQueryResultsTb'),
componentList = tb.up('bindinspector-componentlist'),
queryTb = componentList.down('#queryFieldTb'),
queryField = queryTb.down('#queryField');
tb.hide();
queryTb.show();
componentList.clearVMSearchIndicators();
queryField.setValue(queryField.lastValue);
componentList.filterComponentTree(null, queryField.lastValue);
}
}
]
}
];
me.callParent();
me.getView().on('itemdblclick', me.onItemDblclick, me);
me.on('select', me.onItemSelect, me);
me.bindingsTip = Ext.create('Ext.tip.ToolTip', {
renderTo: document.body,
anchor: 'left',
cls: Ext.baseCSSPrefix + 'componentlist-tip',
bodyPadding: 12
});
me.getView().on('itemmouseenter', me.showBindingsTip, me);
},
clearVMSearchIndicators: function() {
var indicatedVM = this.indicatedVM;
Ext.suspendLayouts();
if (indicatedVM) {
Ext.Array.forEach(indicatedVM, function(rec) {
rec.set('isSrcVM', false);
});
}
this.down('#srcVMIndicator').hide();
Ext.resumeLayouts(true);
this.indicatedVM = null;
},
srcVMIndicator: function(v, meta, rec) {
var refVM = rec.get('isSrcVM'),
tip = '',
vmDetail, firstTierRec, firstTierName, targetRec;
if (refVM) {
vmDetail = this.up('bindinspector-container').down('bindinspector-viewmodeldetail');
firstTierRec = vmDetail.getFirstTierRec(refVM);
firstTierName = firstTierRec.get('name');
if (firstTierRec !== refVM) {
tip += 'Root data node: &nbsp;<span class=\'' + Ext.baseCSSPrefix + 'binding-tip-descriptor\'>' + firstTierName + '</span><hr>';
}
targetRec = firstTierRec === refVM ? firstTierRec : refVM;
tip += targetRec.get('name') + ':';
tip += '<br>&nbsp;&nbsp;&nbsp;&nbsp;';
tip += '<span class=\'' + Ext.baseCSSPrefix + 'binding-tip-value\'>' + Ext.app.bindinspector.Util.valueRenderer(targetRec.get('value')) + '</span>';
meta.tdCls = Ext.baseCSSPrefix + 'bindindicator-vm-src';
meta.tdAttr = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="' + tip + '"';
}
},
onDestroy: function() {
this.bindingsTip.destroy();
this.callParent();
},
showBindingsTip: function(view, record, item, index, e) {
var me = this,
tip = me.bindingsTip,
sansData = record.get('sansData'),
bindings, bindingText;
tip.stopAnimation();
if (record.get('hasBindings')) {
bindings = me.ownerCt.env.getCmp(record.get('id')).bindings;
bindingText = [];
Ext.Object.each(bindings, function(key, val, o) {
var kv = key + ': ' + '<span class="' + Ext.baseCSSPrefix + 'binding-tip-descriptor">' + val.descriptor + '</span><br>',
bindValue = val.value,
v;
if (Ext.isString(bindValue)) {
v = bindValue;
} else if (Ext.isObject(bindValue)) {
if (bindValue.isStore === true) {
v = 'Store {' + bindValue.entityName + '}';
} else if (bindValue.isModel === true) {
v = 'Model {' + bindValue.entityName + '}';
}
}
kv += '<span class="' + Ext.baseCSSPrefix + 'binding-tip-value">' + v + '</span>';
bindingText.push(kv);
});
bindingText = bindingText.join('<hr>');
if (sansData) {
bindingText += '<hr>';
Ext.Array.forEach(sansData, function(missing) {
bindingText += '<div class="' + Ext.baseCSSPrefix + 'binding-missing-data">Missing data: ' + missing + '</div>';
});
}
tip.update(bindingText);
tip.setTarget(item);
tip.show();
tip.alignTo(item, 'l-r', [
20,
0
]);
tip.animate({
from: {
opacity: 0
},
to: {
opacity: 1,
x: tip.getX() - 10
}
});
}
},
filterComponentTree: function(field, val) {
var tree = this,
field = tree.down('#queryField'),
newVal = val || field.getValue(),
store = tree.store,
queryRe = /[\s>\[\]=()^'"~$@*:+#,]/g,
valIsArray = Ext.isArray(newVal),
ids = valIsArray ? newVal : [],
components = [],
isQuery, len, i;
if (Ext.isString(newVal)) {
isQuery = queryRe.test(Ext.String.trim(newVal));
}
if (newVal.length > 0) {
tree.filteredComponents = [];
if (isQuery) {
try {
components = Ext.ComponentQuery.query(newVal);
} catch (e) {}
len = components.length;
for (i = 0; i < len; i++) {
ids.push(components[i].id);
}
}
store.suspendEvents();
store.filter({
filterFn: function(node) {
var children = node.childNodes,
length = children && children.length,
visible = false,
j;
if (isQuery || valIsArray) {
visible = Ext.Array.contains(ids, node.get('id'));
} else {
visible = node.get('text').indexOf(newVal) > -1;
}
node.set('filtervisible', visible);
if (visible) {
tree.filteredComponents.push(node);
}
for (j = 0; j < length; j++) {
if (children[j].get('visible')) {
visible = true;
}
}
return visible;
},
id: 'queryFilter'
});
store.resumeEvents();
tree.getView().refresh();
} else {
tree.clearComponentFilter();
}
},
clearComponentFilter: function() {
var tree = this,
store = tree.store,
filtered = tree.filteredComponents || [],
len = filtered.length,
i = 0;
for (; i < len; i++) {
filtered[i].set('filtervisible', false);
}
store.clearFilter();
},
buildNode: function(comp) {
var me = this,
ownerCt = me.getRefOwner(),
childItems = comp.items,
viewModel = comp.viewModel,
bindings = comp.bindings,
hasBindings = !!comp.bindings,
suffix = [],
sansData = [],
missing = {},
binding, len, i, o, child, ref, key, bindData;
if (viewModel) {
suffix.push('<span class="' + me.vmIconCls + '">' + me.vmIcon + '</span>');
ownerCt.buildVMDataMap(viewModel);
}
if (hasBindings) {
suffix.push('<span class="' + me.bindingsIconCls + '">' + me.bindingsIcon + '</span>');
for (key in bindings) {
binding = bindings[key];
if (binding.descriptor && Ext.isEmpty(binding.value)) {
sansData.push(missing[key] = binding.descriptor);
}
}
bindData = comp.bindData = Ext.app.bindinspector.Util.buildBindData(bindings);
}
if (sansData.length === 0) {
sansData = undefined;
}
ref = comp.reference ? '<b>[' + comp.reference + ']</b> &bull; ' : '';
o = {
id: comp.id,
text: ref + comp.id + (suffix.length ? (' ' + suffix.join(' ')) : ''),
hasViewModel: !!viewModel,
hasBindings: hasBindings,
hasDeepBindings: hasBindings,
reference: comp.reference,
sansData: sansData,
bindData: bindData,
children: []
};
if (childItems) {
for (i = 0 , len = childItems.length; i < len; ++i) {
child = me.buildNode(childItems[i]);
o.hasDeepBindings = o.hasDeepBindings || child.hasDeepBindings;
if (child.hasDeepBindings) {
o.children.push(child);
}
}
}
if (o.children.length) {
o.expanded = true;
o.leaf = false;
} else {
o.leaf = true;
}
return o;
},
onItemDblclick: function(view, rec) {
this.fireEvent('componentdblclick', this, rec);
},
onItemSelect: function(selModel, rec) {
var node = this.getView().getNode(rec);
this.fireEvent('componentselect', this, rec, node);
}
}, function() {
this.prototype.Model = Ext.define(null, {
extend: 'Ext.data.TreeModel',
fields: [
'hasViewModel',
'hasBindings',
'reference',
'hasDeepBindings',
'reference',
'sansData',
'bindData',
'isSrcVM'
]
});
});
Ext.define('Ext.resizer.BorderSplitter', {
extend: 'Ext.resizer.Splitter',
uses: [
'Ext.resizer.BorderSplitterTracker'
],
alias: 'widget.bordersplitter',
collapseTarget: null,
getTrackerConfig: function() {
var trackerConfig = this.callParent();
trackerConfig.xclass = 'Ext.resizer.BorderSplitterTracker';
return trackerConfig;
},
onTargetCollapse: function(target) {
this.callParent([
target
]);
if (this.performCollapse !== false && target.collapseMode == 'mini') {
target.addCls(target.baseCls + '-' + target.collapsedCls + '-mini');
}
},
onTargetExpand: function(target) {
this.callParent([
target
]);
if (this.performCollapse !== false && target.collapseMode == 'mini') {
target.removeCls(target.baseCls + '-' + target.collapsedCls + '-mini');
}
}
});
Ext.define('Ext.layout.container.Border', {
extend: 'Ext.layout.container.Container',
alias: 'layout.border',
alternateClassName: 'Ext.layout.BorderLayout',
requires: [
'Ext.resizer.BorderSplitter',
'Ext.fx.Anim',
'Ext.layout.container.border.Region'
],
targetCls: Ext.baseCSSPrefix + 'border-layout-ct',
itemCls: [
Ext.baseCSSPrefix + 'border-item',
Ext.baseCSSPrefix + 'box-item'
],
type: 'border',
isBorderLayout: true,
padding: undefined,
percentageRe: /(\d+)%/,
horzPositionProp: 'left',
padOnContainerProp: 'left',
padNotOnContainerProp: 'right',
axisProps: {
horz: {
borderBegin: 'west',
borderEnd: 'east',
horizontal: true,
posProp: 'x',
sizeProp: 'width',
sizePropCap: 'Width'
},
vert: {
borderBegin: 'north',
borderEnd: 'south',
horizontal: false,
posProp: 'y',
sizeProp: 'height',
sizePropCap: 'Height'
}
},
centerRegion: null,
manageMargins: true,
panelCollapseAnimate: true,
panelCollapseMode: 'placeholder',
regionWeights: {
north: 20,
south: 10,
center: 0,
west: -10,
east: -20
},
beginAxis: function(ownerContext, regions, name) {
var me = this,
props = me.axisProps[name],
isVert = !props.horizontal,
sizeProp = props.sizeProp,
totalFlex = 0,
childItems = ownerContext.childItems,
length = childItems.length,
center, i, childContext, centerFlex, comp, region, match, size, type, target, placeholder;
for (i = 0; i < length; ++i) {
childContext = childItems[i];
comp = childContext.target;
childContext.layoutPos = {};
if (comp.region) {
childContext.region = region = comp.region;
childContext.isCenter = comp.isCenter;
childContext.isHorz = comp.isHorz;
childContext.isVert = comp.isVert;
childContext.weight = comp.weight || me.regionWeights[region] || 0;
comp.weight = childContext.weight;
regions[comp.id] = childContext;
if (comp.isCenter) {
center = childContext;
centerFlex = comp.flex;
ownerContext.centerRegion = center;
continue;
}
if (isVert !== childContext.isVert) {
continue;
}
childContext.reverseWeighting = (region === props.borderEnd);
size = comp[sizeProp];
type = typeof size;
if (!comp.collapsed) {
if (type === 'string' && (match = me.percentageRe.exec(size))) {
childContext.percentage = parseInt(match[1], 10);
} else if (comp.flex) {
totalFlex += childContext.flex = comp.flex;
}
}
}
}
if (center) {
target = center.target;
if ((placeholder = target.placeholderFor)) {
if (!centerFlex && isVert === placeholder.collapsedVertical()) {
centerFlex = 0;
center.collapseAxis = name;
}
} else if (target.collapsed && (isVert === target.collapsedVertical())) {
centerFlex = 0;
center.collapseAxis = name;
}
}
if (centerFlex == null) {
centerFlex = 1;
}
totalFlex += centerFlex;
return Ext.apply({
before: isVert ? 'top' : 'left',
totalFlex: totalFlex
}, props);
},
beginLayout: function(ownerContext) {
var me = this,
items = me.getLayoutItems(),
pad = me.padding,
type = typeof pad,
padOnContainer = false,
childContext, item, length, i, regions, collapseTarget, doShow, hidden, region;
if (ownerContext.heightModel.shrinkWrap) {
Ext.Error.raise("Border layout does not currently support shrinkWrap height. " + "Please specify a height on component: " + me.owner.id + ", or use a container layout that sets the component's height.");
}
if (ownerContext.widthModel.shrinkWrap) {
Ext.Error.raise("Border layout does not currently support shrinkWrap width. " + "Please specify a width on component: " + me.owner.id + ", or use a container layout that sets the component's width.");
}
if (pad) {
if (type === 'string' || type === 'number') {
pad = Ext.util.Format.parseBox(pad);
}
} else {
pad = ownerContext.getEl('getTargetEl').getPaddingInfo();
padOnContainer = true;
}
ownerContext.outerPad = pad;
ownerContext.padOnContainer = padOnContainer;
for (i = 0 , length = items.length; i < length; ++i) {
item = items[i];
collapseTarget = me.getSplitterTarget(item);
if (collapseTarget) {
doShow = undefined;
hidden = !!item.hidden;
if (!collapseTarget.split) {
if (collapseTarget.isCollapsingOrExpanding) {
doShow = !!collapseTarget.collapsed;
}
} else if (hidden !== collapseTarget.hidden) {
doShow = !collapseTarget.hidden;
}
if (doShow) {
item.show();
} else if (doShow === false) {
item.hide();
}
}
}
me.callParent(arguments);
items = ownerContext.childItems;
length = items.length;
regions = {};
ownerContext.borderAxisHorz = me.beginAxis(ownerContext, regions, 'horz');
ownerContext.borderAxisVert = me.beginAxis(ownerContext, regions, 'vert');
for (i = 0; i < length; ++i) {
childContext = items[i];
collapseTarget = me.getSplitterTarget(childContext.target);
if (collapseTarget) {
region = regions[collapseTarget.id];
if (!region) {
region = ownerContext.getEl(collapseTarget.el, me);
region.region = collapseTarget.region;
}
childContext.collapseTarget = collapseTarget = region;
childContext.weight = collapseTarget.weight;
childContext.reverseWeighting = collapseTarget.reverseWeighting;
collapseTarget.splitter = childContext;
childContext.isHorz = collapseTarget.isHorz;
childContext.isVert = collapseTarget.isVert;
}
}
me.sortWeightedItems(items, 'reverseWeighting');
me.setupSplitterNeighbors(items);
},
calculate: function(ownerContext) {
var me = this,
containerSize = me.getContainerSize(ownerContext),
childItems = ownerContext.childItems,
length = childItems.length,
horz = ownerContext.borderAxisHorz,
vert = ownerContext.borderAxisVert,
pad = ownerContext.outerPad,
padOnContainer = ownerContext.padOnContainer,
i, childContext, childMargins, size, horzPercentTotal, vertPercentTotal;
horz.begin = pad[me.padOnContainerProp];
vert.begin = pad.top;
horzPercentTotal = horz.end = horz.flexSpace = containerSize.width + (padOnContainer ? pad[me.padOnContainerProp] : -pad[me.padNotOnContainerProp]);
vertPercentTotal = vert.end = vert.flexSpace = containerSize.height + (padOnContainer ? pad.top : -pad.bottom);
for (i = 0; i < length; ++i) {
childContext = childItems[i];
childMargins = childContext.getMarginInfo();
if (childContext.isHorz || childContext.isCenter) {
horz.addUnflexed(childMargins.width);
horzPercentTotal -= childMargins.width;
}
if (childContext.isVert || childContext.isCenter) {
vert.addUnflexed(childMargins.height);
vertPercentTotal -= childMargins.height;
}
if (!childContext.flex && !childContext.percentage) {
if (childContext.isHorz || (childContext.isCenter && childContext.collapseAxis === 'horz')) {
size = childContext.getProp('width');
horz.addUnflexed(size);
if (childContext.collapseTarget) {
horzPercentTotal -= size;
}
} else if (childContext.isVert || (childContext.isCenter && childContext.collapseAxis === 'vert')) {
size = childContext.getProp('height');
vert.addUnflexed(size);
if (childContext.collapseTarget) {
vertPercentTotal -= size;
}
}
}
}
for (i = 0; i < length; ++i) {
childContext = childItems[i];
childMargins = childContext.getMarginInfo();
if (childContext.percentage) {
if (childContext.isHorz) {
size = Math.ceil(horzPercentTotal * childContext.percentage / 100);
size = childContext.setWidth(size);
horz.addUnflexed(size);
} else if (childContext.isVert) {
size = Math.ceil(vertPercentTotal * childContext.percentage / 100);
size = childContext.setHeight(size);
vert.addUnflexed(size);
}
}
}
for (i = 0; i < length; ++i) {
childContext = childItems[i];
if (!childContext.isCenter) {
me.calculateChildAxis(childContext, horz);
me.calculateChildAxis(childContext, vert);
}
}
if (me.finishAxis(ownerContext, vert) + me.finishAxis(ownerContext, horz) < 2) {
me.done = false;
} else {
me.finishPositions(childItems);
}
},
calculateChildAxis: function(childContext, axis) {
var collapseTarget = childContext.collapseTarget,
setSizeMethod = 'set' + axis.sizePropCap,
sizeProp = axis.sizeProp,
childMarginSize = childContext.getMarginInfo()[sizeProp],
region, isBegin, flex, pos, size;
if (collapseTarget) {
region = collapseTarget.region;
} else {
region = childContext.region;
flex = childContext.flex;
}
isBegin = region === axis.borderBegin;
if (!isBegin && region !== axis.borderEnd) {
childContext[setSizeMethod](axis.end - axis.begin - childMarginSize);
pos = axis.begin;
} else {
if (flex) {
size = Math.ceil(axis.flexSpace * (flex / axis.totalFlex));
size = childContext[setSizeMethod](size);
} else if (childContext.percentage) {
size = childContext.peek(sizeProp);
} else {
size = childContext.getProp(sizeProp);
}
size += childMarginSize;
if (isBegin) {
pos = axis.begin;
axis.begin += size;
} else {
axis.end = pos = axis.end - size;
}
}
childContext.layoutPos[axis.posProp] = pos;
},
eachItem: function(region, fn, scope) {
var me = this,
items = me.getLayoutItems(),
i = 0,
item;
if (Ext.isFunction(region)) {
fn = region;
scope = fn;
}
for (i; i < items.length; i++) {
item = items[i];
if (!region || item.region === region) {
if (fn.call(scope, item) === false) {
break;
}
}
}
},
finishAxis: function(ownerContext, axis) {
var size = axis.end - axis.begin,
center = ownerContext.centerRegion;
if (center) {
center['set' + axis.sizePropCap](size - center.getMarginInfo()[axis.sizeProp]);
center.layoutPos[axis.posProp] = axis.begin;
}
return Ext.isNumber(size) ? 1 : 0;
},
finishPositions: function(childItems) {
var length = childItems.length,
index, childContext,
marginProp = this.horzPositionProp;
for (index = 0; index < length; ++index) {
childContext = childItems[index];
childContext.setProp('x', childContext.layoutPos.x + childContext.marginInfo[marginProp]);
childContext.setProp('y', childContext.layoutPos.y + childContext.marginInfo.top);
}
},
getLayoutItems: function() {
var owner = this.owner,
ownerItems = (owner && owner.items && owner.items.items) || [],
length = ownerItems.length,
items = [],
i = 0,
ownerItem, placeholderFor;
for (; i < length; i++) {
ownerItem = ownerItems[i];
placeholderFor = ownerItem.placeholderFor;
if (ownerItem.hidden || ((!ownerItem.floated || ownerItem.isCollapsingOrExpanding === 2) && !(placeholderFor && placeholderFor.isCollapsingOrExpanding === 2))) {
items.push(ownerItem);
}
}
return items;
},
getPlaceholder: function(comp) {
return comp.getPlaceholder && comp.getPlaceholder();
},
getMaxWeight: function(region) {
return this.getMinMaxWeight(region);
},
getMinWeight: function(region) {
return this.getMinMaxWeight(region, true);
},
getMinMaxWeight: function(region, min) {
var me = this,
weight = null;
me.eachItem(region, function(item) {
if (item.hasOwnProperty('weight')) {
if (weight === null) {
weight = item.weight;
return;
}
if ((min && item.weight < weight) || item.weight > weight) {
weight = item.weight;
}
}
}, this);
return weight;
},
getSplitterTarget: function(splitter) {
var collapseTarget = splitter.collapseTarget;
if (collapseTarget && collapseTarget.collapsed) {
return collapseTarget.placeholder || collapseTarget;
}
return collapseTarget;
},
isItemBoxParent: function(itemContext) {
return true;
},
isItemShrinkWrap: function(item) {
return true;
},
insertSplitter: function(item, index, hidden, splitterCfg) {
var region = item.region,
splitter = Ext.apply({
xtype: 'bordersplitter',
collapseTarget: item,
id: item.id + '-splitter',
hidden: hidden,
canResize: item.splitterResize !== false,
splitterFor: item,
synthetic: true
},
splitterCfg),
at = index + ((region === 'south' || region === 'east') ? 0 : 1);
if (item.collapseMode === 'mini') {
splitter.collapsedCls = item.collapsedCls;
}
item.splitter = this.owner.add(at, splitter);
},
getMoveAfterIndex: function(after) {
var index = this.callParent(arguments);
if (after.splitter) {
index++;
}
return index;
},
moveItemBefore: function(item, before) {
var beforeRegion;
if (before && before.splitter) {
beforeRegion = before.region;
if (beforeRegion === 'south' || beforeRegion === 'east') {
before = before.splitter;
}
}
return this.callParent([
item,
before
]);
},
onAdd: function(item, index) {
var me = this,
placeholderFor = item.placeholderFor,
region = item.region,
isCenter, split, hidden, cfg;
me.callParent(arguments);
if (region) {
Ext.apply(item, me.regionFlags[region]);
if (item.initBorderRegion) {
item.initBorderRegion();
}
isCenter = region === 'center';
if (isCenter) {
if (me.centerRegion) {
Ext.Error.raise("Cannot have multiple center regions in a BorderLayout.");
}
me.centerRegion = item;
} else {
split = item.split;
hidden = !!item.hidden;
if (typeof split === 'object') {
cfg = split;
split = true;
}
if ((item.isHorz || item.isVert) && (split || item.collapseMode === 'mini')) {
me.insertSplitter(item, index, hidden || !split, cfg);
}
}
if (!isCenter && !item.hasOwnProperty('collapseMode')) {
item.collapseMode = me.panelCollapseMode;
}
if (!item.hasOwnProperty('animCollapse')) {
if (item.collapseMode !== 'placeholder') {
item.animCollapse = false;
} else {
item.animCollapse = me.panelCollapseAnimate;
}
}
} else if (placeholderFor) {
Ext.apply(item, me.regionFlags[placeholderFor.region]);
item.region = placeholderFor.region;
item.weight = placeholderFor.weight;
}
},
onDestroy: function() {
this.centerRegion = null;
this.callParent();
},
onRemove: function(comp, isDestroying) {
var me = this,
region = comp.region,
splitter = comp.splitter,
owner = me.owner,
destroying = owner.destroying,
el;
if (region) {
if (comp.isCenter) {
me.centerRegion = null;
}
delete comp.isCenter;
delete comp.isHorz;
delete comp.isVert;
if (splitter && !owner.destroying) {
owner.doRemove(splitter, true);
}
delete comp.splitter;
}
me.callParent(arguments);
if (!destroying && !isDestroying && comp.rendered) {
el = comp.getEl();
if (el) {
el.setStyle('top', '');
el.setStyle(me.horzPositionProp, '');
}
}
},
regionMeta: {
center: {
splitterDelta: 0
},
north: {
splitterDelta: 1
},
south: {
splitterDelta: -1
},
west: {
splitterDelta: 1
},
east: {
splitterDelta: -1
}
},
regionFlags: {
center: {
isCenter: true,
isHorz: false,
isVert: false
},
north: {
isCenter: false,
isHorz: false,
isVert: true,
collapseDirection: 'top'
},
south: {
isCenter: false,
isHorz: false,
isVert: true,
collapseDirection: 'bottom'
},
west: {
isCenter: false,
isHorz: true,
isVert: false,
collapseDirection: 'left'
},
east: {
isCenter: false,
isHorz: true,
isVert: false,
collapseDirection: 'right'
}
},
setupSplitterNeighbors: function(items) {
var edgeRegions = {},
length = items.length,
touchedRegions = this.touchedRegions,
i, j, center, count, edge, comp, region, splitter, touched;
for (i = 0; i < length; ++i) {
comp = items[i].target;
region = comp.region;
if (comp.isCenter) {
center = comp;
} else if (region) {
touched = touchedRegions[region];
for (j = 0 , count = touched.length; j < count; ++j) {
edge = edgeRegions[touched[j]];
if (edge) {
edge.neighbors.push(comp);
}
}
if (comp.placeholderFor) {
splitter = comp.placeholderFor.splitter;
} else {
splitter = comp.splitter;
}
if (splitter) {
splitter.neighbors = [];
}
edgeRegions[region] = splitter;
}
}
if (center) {
touched = touchedRegions.center;
for (j = 0 , count = touched.length; j < count; ++j) {
edge = edgeRegions[touched[j]];
if (edge) {
edge.neighbors.push(center);
}
}
}
},
touchedRegions: {
center: [
'north',
'south',
'east',
'west'
],
north: [
'north',
'east',
'west'
],
south: [
'south',
'east',
'west'
],
east: [
'east',
'north',
'south'
],
west: [
'west',
'north',
'south'
]
},
sizePolicies: {
vert: {
readsWidth: 0,
readsHeight: 1,
setsWidth: 1,
setsHeight: 0
},
horz: {
readsWidth: 1,
readsHeight: 0,
setsWidth: 0,
setsHeight: 1
},
flexAll: {
readsWidth: 0,
readsHeight: 0,
setsWidth: 1,
setsHeight: 1
}
},
getItemSizePolicy: function(item) {
var me = this,
policies = this.sizePolicies,
collapseTarget, size, policy, placeholderFor;
if (item.isCenter) {
placeholderFor = item.placeholderFor;
if (placeholderFor) {
if (placeholderFor.collapsedVertical()) {
return policies.vert;
}
return policies.horz;
}
if (item.collapsed) {
if (item.collapsedVertical()) {
return policies.vert;
}
return policies.horz;
}
return policies.flexAll;
}
collapseTarget = item.collapseTarget;
if (collapseTarget) {
return collapseTarget.isVert ? policies.vert : policies.horz;
}
if (item.region) {
if (item.isVert) {
size = item.height;
policy = policies.vert;
} else {
size = item.width;
policy = policies.horz;
}
if (item.flex || (typeof size === 'string' && me.percentageRe.test(size))) {
return policies.flexAll;
}
return policy;
}
return me.autoSizePolicy;
}
}, function() {
var methods = {
addUnflexed: function(px) {
this.flexSpace = Math.max(this.flexSpace - px, 0);
}
},
props = this.prototype.axisProps;
Ext.apply(props.horz, methods);
Ext.apply(props.vert, methods);
});
Ext.define('Ext.layout.container.Card', {
extend: 'Ext.layout.container.Fit',
alternateClassName: 'Ext.layout.CardLayout',
alias: 'layout.card',
type: 'card',
hideInactive: true,
deferredRender: false,
scrollableCache: (Ext.isGecko ? {} : null),
getRenderTree: function() {
var me = this,
activeItem = me.getActiveItem();
if (activeItem) {
if (activeItem.hasListeners.beforeactivate && activeItem.fireEvent('beforeactivate', activeItem) === false) {
activeItem = me.activeItem = me.owner.activeItem = null;
}
else if (activeItem.hasListeners.activate) {
activeItem.on({
boxready: function() {
activeItem.fireEvent('activate', activeItem);
},
single: true
});
}
if (me.deferredRender) {
if (activeItem) {
return me.getItemsRenderTree([
activeItem
]);
}
} else {
return me.callParent(arguments);
}
}
},
renderChildren: function() {
var me = this,
active = me.getActiveItem();
if (!me.deferredRender) {
me.callParent();
} else if (active) {
me.renderItems([
active
], me.getRenderTarget());
}
},
isValidParent: function(item, target, position) {
var itemEl = item.el ? item.el.dom : Ext.getDom(item);
return (itemEl && itemEl.parentNode === (target.dom || target)) || false;
},
getActiveItem: function() {
var me = this,
item = me.activeItem === undefined ? (me.owner && me.owner.activeItem) : me.activeItem,
result = me.parseActiveItem(item);
if (result && me.owner.items.indexOf(result) !== -1) {
me.activeItem = result;
}
return result == null ? null : (me.activeItem || me.owner.activeItem);
},
parseActiveItem: function(item) {
var activeItem;
if (item && item.isComponent) {
activeItem = item;
} else if (typeof item === 'number' || item === undefined) {
activeItem = this.getLayoutItems()[item || 0];
} else if (item === null) {
activeItem = null;
} else {
activeItem = this.owner.getComponent(item);
}
return activeItem;
},
configureItem: function(item) {
item.setHiddenState(item !== this.getActiveItem());
this.callParent(arguments);
},
onRemove: function(component) {
this.callParent([
component
]);
if (component === this.activeItem) {
this.activeItem = undefined;
}
},
getAnimation: function(newCard, owner) {
var newAnim = (newCard || {}).cardSwitchAnimation;
if (newAnim === false) {
return false;
}
return newAnim || owner.cardSwitchAnimation;
},
getNext: function() {
var wrap = arguments[0],
items = this.getLayoutItems(),
index = Ext.Array.indexOf(items, this.activeItem);
return items[index + 1] || (wrap ? items[0] : false);
},
next: function() {
var anim = arguments[0],
wrap = arguments[1];
return this.setActiveItem(this.getNext(wrap), anim);
},
getPrev: function() {
var wrap = arguments[0],
items = this.getLayoutItems(),
index = Ext.Array.indexOf(items, this.activeItem);
return items[index - 1] || (wrap ? items[items.length - 1] : false);
},
prev: function() {
var anim = arguments[0],
wrap = arguments[1];
return this.setActiveItem(this.getPrev(wrap), anim);
},
setActiveItem: function(newCard) {
var me = this,
scrollableCache = me.scrollableCache,
owner = me.owner,
oldCard = me.activeItem,
rendered = owner.rendered,
newIndex, focusNewCard, oldCardScrollable, cached, currentPosition;
newCard = me.parseActiveItem(newCard);
newIndex = owner.items.indexOf(newCard);
if (newIndex === -1) {
newIndex = owner.items.items.length;
Ext.suspendLayouts();
newCard = owner.add(newCard);
Ext.resumeLayouts();
}
if (newCard && oldCard !== newCard) {
if (newCard.fireEvent('beforeactivate', newCard, oldCard) === false) {
return false;
}
if (oldCard && oldCard.fireEvent('beforedeactivate', oldCard, newCard) === false) {
return false;
}
if (rendered) {
Ext.suspendLayouts();
if (!newCard.rendered) {
me.renderItem(newCard, me.getRenderTarget(), owner.items.length);
}
if (oldCard) {
if (me.hideInactive) {
focusNewCard = oldCard.el.contains(Ext.Element.getActiveElement());
if (scrollableCache && (oldCardScrollable = oldCard.scrollable)) {
scrollableCache[oldCard.id] = {
position: oldCardScrollable.getPosition()
};
oldCardScrollable.scrollTo(0, 0);
}
oldCard.hide();
if (oldCard.hidden) {
oldCard.hiddenByLayout = true;
oldCard.fireEvent('deactivate', oldCard, newCard);
} else
{
return false;
}
}
}
if (newCard.hidden) {
newCard.show();
}
if (newCard.hidden) {
me.activeItem = newCard = null;
} else {
me.activeItem = newCard;
if (focusNewCard) {
if (!newCard.defaultFocus) {
newCard.defaultFocus = ':focusable';
}
newCard.focus();
}
}
Ext.resumeLayouts(true);
if (scrollableCache && (cached = scrollableCache[newCard.id])) {
currentPosition = cached.position;
newCard.scrollable.scrollTo(currentPosition.x, currentPosition.y);
}
} else {
me.activeItem = newCard;
}
newCard.fireEvent('activate', newCard, oldCard);
return me.activeItem;
}
return false;
}
});
Ext.define('Ext.dom.ButtonElement', {
extend: 'Ext.dom.Element',
setSize: function(width, height, animate) {
var me = this,
component = me.component;
me.callParent([
width,
height,
animate
]);
component.btnWrap.setStyle('table-layout', (!width || width === 'auto') ? '' : 'fixed');
component.btnEl.setStyle('height', (!height || height === 'auto') ? '' : 'auto');
return me;
},
setStyle: function(prop, value) {
var me = this,
component = me.component,
width, height;
me.callParent([
prop,
value
]);
if (prop) {
if (prop === 'width' || (typeof prop !== 'string' && 'width' in prop)) {
width = value || prop.width;
component.btnWrap.setStyle('table-layout', (!width || width === 'auto') ? '' : 'fixed');
}
if (prop === 'height' || (typeof prop !== 'string' && 'height' in prop)) {
height = value || prop.height;
component.btnEl.setStyle('height', (!height || height === 'auto') ? '' : 'auto');
}
}
return me;
},
setHeight: function(height, animate) {
this.callParent([
height,
animate
]);
this.component.btnEl.setStyle('height', (!height || height === 'auto') ? '' : 'auto');
return this;
},
setWidth: function(width, animate) {
this.callParent([
width,
animate
]);
this.component.btnWrap.setStyle('table-layout', (!width || width === 'auto') ? '' : 'fixed');
return this;
}
});
Ext.define('Ext.button.Manager', {
singleton: true,
alternateClassName: 'Ext.ButtonToggleManager',
groups: {},
pressedButton: null,
buttonSelector: '.' + Ext.baseCSSPrefix + 'btn',
init: function() {
var me = this;
if (!me.initialized) {
Ext.getDoc().on({
keydown: me.onDocumentKeyDown,
mouseup: me.onDocumentMouseUp,
scope: me
});
me.initialized = true;
}
},
onDocumentKeyDown: function(e) {
var k = e.getKey(),
btn;
if (k === e.SPACE || k === e.ENTER) {
btn = e.getTarget(this.buttonSelector);
if (btn) {
Ext.getCmp(btn.id).onClick(e);
}
}
},
onButtonMousedown: function(button, e) {
var pressed = this.pressedButton;
if (pressed) {
pressed.onMouseUp(e);
}
this.pressedButton = button;
},
onDocumentMouseUp: function(e) {
var pressed = this.pressedButton;
if (pressed) {
pressed.onMouseUp(e);
this.pressedButton = null;
}
},
toggleGroup: function(btn, state) {
if (state) {
var g = this.groups[btn.toggleGroup],
length = g.length,
i;
for (i = 0; i < length; i++) {
if (g[i] !== btn) {
g[i].toggle(false);
}
}
}
},
register: function(btn) {
var me = this,
groups = this.groups,
group = groups[btn.toggleGroup];
me.init();
if (!btn.toggleGroup) {
return;
}
if (!group) {
group = groups[btn.toggleGroup] = [];
}
group.push(btn);
btn.on('toggle', me.toggleGroup, me);
},
unregister: function(btn) {
if (!btn.toggleGroup) {
return;
}
var me = this,
group = me.groups[btn.toggleGroup];
if (group) {
Ext.Array.remove(group, btn);
btn.un('toggle', me.toggleGroup, me);
}
},
getPressed: function(groupName) {
var group = this.groups[groupName],
i = 0,
len;
if (group) {
for (len = group.length; i < len; i++) {
if (group[i].pressed === true) {
return group[i];
}
}
}
return null;
}
});
Ext.define('Ext.menu.Manager', {
singleton: true,
alternateClassName: 'Ext.menu.MenuMgr',
uses: [
'Ext.menu.Menu'
],
groups: {},
visible: [],
constructor: function() {
var me = this;
me.onShow = function() {
delete me.onShow;
Ext.on('mousedown', me.checkActiveMenus, me);
return me.onShow.apply(me, arguments);
};
},
checkActiveMenus: function(e) {
var allMenus = this.visible,
len = allMenus.length,
i, menu;
if (len) {
allMenus = allMenus.slice();
for (i = 0; i < len; ++i) {
menu = allMenus[i];
if (!menu.owns(e)) {
menu.hide();
}
}
}
},
onShow: function(menu) {
if (menu.floating) {
Ext.Array.include(this.visible, menu);
}
},
onHide: function(menu) {
if (menu.floating) {
Ext.Array.remove(this.visible, menu);
}
},
hideAll: function() {
var allMenus = this.visible,
len = allMenus.length,
result = false,
i;
if (len) {
allMenus = allMenus.slice();
for (i = 0; i < len; i++) {
allMenus[i].hide();
result = true;
}
}
return result;
},
get: function(menu, config) {
var result;
if (typeof menu === 'string') {
result = Ext.getCmp(menu);
if (result instanceof Ext.menu.Menu) {
menu = result;
}
} else if (Ext.isArray(menu)) {
config = Ext.apply({
items: menu
}, config);
menu = new Ext.menu.Menu(config);
} else if (!menu.isComponent) {
config = Ext.apply({}, menu, config);
menu = Ext.ComponentManager.create(config, 'menu');
}
return menu;
},
registerCheckable: function(menuItem) {
var groups = this.groups,
groupId = menuItem.group;
if (groupId) {
if (!groups[groupId]) {
groups[groupId] = [];
}
groups[groupId].push(menuItem);
}
},
unregisterCheckable: function(menuItem) {
var groups = this.groups,
groupId = menuItem.group;
if (groupId) {
Ext.Array.remove(groups[groupId], menuItem);
}
},
onCheckChange: function(menuItem, state) {
var groups = this.groups,
groupId = menuItem.group,
i = 0,
group, ln, curr;
if (groupId && state) {
group = groups[groupId];
ln = group.length;
for (; i < ln; i++) {
curr = group[i];
if (curr !== menuItem) {
curr.setChecked(false);
}
}
}
}
});
Ext.define('Ext.button.Button', {
alias: 'widget.button',
extend: 'Ext.Component',
requires: [
'Ext.dom.ButtonElement',
'Ext.button.Manager',
'Ext.menu.Manager',
'Ext.util.ClickRepeater',
'Ext.util.TextMetrics',
'Ext.util.KeyMap'
],
mixins: [
'Ext.mixin.Queryable'
],
alternateClassName: 'Ext.Button',
config: {
iconAlign: 'left',
text: null,
textAlign: 'center',
arrowVisible: true
},
isButton: true,
_syncFrameHeight: true,
liquidLayout: true,
hidden: false,
disabled: false,
pressed: false,
tabIndex: 0,
enableToggle: false,
menuAlign: 'tl-bl?',
showEmptyMenu: false,
clickEvent: 'click',
preventDefault: true,
handleMouseEvents: true,
tooltipType: 'qtip',
baseCls: Ext.baseCSSPrefix + 'btn',
hrefTarget: '_blank',
destroyMenu: true,
focusable: true,
ariaRole: 'button',
defaultBindProperty: 'text',
childEls: [
'btnEl',
'btnWrap',
'btnInnerEl',
'btnIconEl'
],
publishes: {
pressed: 1
},
_btnWrapCls: Ext.baseCSSPrefix + 'btn-wrap',
_btnCls: Ext.baseCSSPrefix + 'btn-button',
_baseIconCls: Ext.baseCSSPrefix + 'btn-icon-el',
_glyphCls: Ext.baseCSSPrefix + 'btn-glyph',
_innerCls: Ext.baseCSSPrefix + 'btn-inner',
_textCls: Ext.baseCSSPrefix + 'btn-text',
_noTextCls: Ext.baseCSSPrefix + 'btn-no-text',
_hasIconCls: Ext.baseCSSPrefix + 'btn-icon',
_pressedCls: Ext.baseCSSPrefix + 'btn-pressed',
overCls: Ext.baseCSSPrefix + 'btn-over',
_disabledCls: Ext.baseCSSPrefix + 'btn-disabled',
_menuActiveCls: Ext.baseCSSPrefix + 'btn-menu-active',
_operaArrowCls: Ext.baseCSSPrefix + 'opera12m-btn-arrow',
renderTpl: '<span id="{id}-btnWrap" data-ref="btnWrap" role="presentation" unselectable="on" style="{btnWrapStyle}" ' + 'class="{btnWrapCls} {btnWrapCls}-{ui} {splitCls}{childElCls}">' + '<span id="{id}-btnEl" data-ref="btnEl" role="presentation" unselectable="on" style="{btnElStyle}" ' + 'class="{btnCls} {btnCls}-{ui} {textCls} {noTextCls} {hasIconCls} ' + '{iconAlignCls} {textAlignCls} {btnElAutoHeightCls}{childElCls}">' + '<tpl if="iconBeforeText">{[values.$comp.renderIcon(values)]}</tpl>' + '<span id="{id}-btnInnerEl" data-ref="btnInnerEl" unselectable="on" ' + 'class="{innerCls} {innerCls}-{ui}{childElCls}">{text}</span>' + '<tpl if="!iconBeforeText">{[values.$comp.renderIcon(values)]}</tpl>' + '</span>' + '</span>' + '{[values.$comp.getAfterMarkup ? values.$comp.getAfterMarkup(values) : ""]}' +
'<tpl if="closable">' + '<span id="{id}-closeEl" data-ref="closeEl" class="{baseCls}-close-btn">' + '<tpl if="closeText">' + ' {closeText}' + '</tpl>' + '</span>' + '</tpl>',
iconTpl: '<span id="{id}-btnIconEl" data-ref="btnIconEl" role="presentation" unselectable="on" class="{baseIconCls} ' + '{baseIconCls}-{ui} {iconCls} {glyphCls}{childElCls}" style="' + '<tpl if="iconUrl">background-image:url({iconUrl});</tpl>' + '<tpl if="glyph && glyphFontFamily">font-family:{glyphFontFamily};</tpl>">' + '<tpl if="glyph">&#{glyph};</tpl><tpl if="iconCls || iconUrl">&#160;</tpl>' + '</span>',
scale: 'small',
allowedScales: [
'small',
'medium',
'large'
],
arrowAlign: 'right',
arrowCls: 'arrow',
maskOnDisable: false,
shrinkWrap: 3,
frame: true,
autoEl: {
tag: 'a',
hidefocus: 'on',
unselectable: 'on'
},
hasFrameTable: function() {
return this.href && this.frameTable;
},
frameTableListener: function() {
if (!this.disabled) {
this.doNavigate();
}
},
doNavigate: function() {
if (this.hrefTarget === '_blank') {
window.open(this.getHref(), this.hrefTarget);
} else {
location.href = this.getHref();
}
},
_triggerRegion: {},
initComponent: function() {
var me = this;
me.addCls(Ext.baseCSSPrefix + 'unselectable');
if (Ext.isOpera12m && (me.split || me.menu) && me.getArrowVisible()) {
me.addCls(me._operaArrowCls + '-' + me.arrowAlign);
}
me.callParent();
if (me.menu) {
me.split = true;
me.setMenu(me.menu,
false, true);
}
if (me.url) {
me.href = me.url;
}
me.configuredWithPreventDefault = me.hasOwnProperty('preventDefault');
if (me.href && !me.configuredWithPreventDefault) {
me.preventDefault = false;
}
if (Ext.isString(me.toggleGroup) && me.toggleGroup !== '') {
me.enableToggle = true;
}
if (me.html && !me.text) {
me.text = me.html;
delete me.html;
}
},
getElConfig: function() {
var me = this,
config = me.callParent(),
href = me.getHref(),
hrefTarget = me.hrefTarget;
if (config.tag === 'a') {
if (!me.disabled) {
config.tabIndex = me.tabIndex;
}
if (href) {
if (!me.disabled) {
config.href = href;
if (hrefTarget) {
config.target = hrefTarget;
}
}
}
}
return config;
},
beforeRender: function() {
this.callParent();
if (this.pressed) {
this.addCls(this._pressedCls);
}
},
initRenderData: function() {
return Ext.apply(this.callParent(), this.getTemplateArgs());
},
getMenu: function() {
return this.menu || null;
},
setMenu: function(menu, destroyMenu,
initial) {
var me = this,
oldMenu = me.menu,
instanced;
if (oldMenu && !initial) {
if (destroyMenu !== false && me.destroyMenu) {
oldMenu.destroy();
}
oldMenu.ownerCmp = null;
}
if (menu) {
instanced = menu.isMenu;
menu = Ext.menu.Manager.get(menu, {
ownerCmp: me
});
menu.setOwnerCmp(me, instanced);
menu.menuClickBuffer = 250;
me.mon(menu, {
scope: me,
show: me.onMenuShow,
hide: me.onMenuHide
});
if (!oldMenu && me.getArrowVisible()) {
me.split = true;
if (me.rendered) {
me._addSplitCls();
me.updateLayout();
}
}
me.menu = menu;
} else {
if (me.rendered) {
me._removeSplitCls();
me.updateLayout();
}
me.split = false;
me.menu = null;
}
},
onRender: function() {
var me = this,
addOnclick, btn, btnListeners;
me.callParent(arguments);
btn = me.el;
if (me.tooltip) {
me.setTooltip(me.tooltip, true);
}
if (me.handleMouseEvents) {
btnListeners = {
scope: me,
mouseover: me.onMouseOver,
mouseout: me.onMouseOut,
mousedown: me.onMouseDown
};
if (me.split) {
btnListeners.mousemove = me.onMouseMove;
}
} else {
btnListeners = {
scope: me
};
}
if (Ext.supports.Touch) {
btnListeners.touchstart = me.onTouchStart;
}
if (me.menu) {
me.keyMap = new Ext.util.KeyMap({
target: me.el,
key: Ext.event.Event.prototype.DOWN,
handler: me.onDownKey,
scope: me
});
}
if (me.repeat) {
me.mon(new Ext.util.ClickRepeater(btn, Ext.isObject(me.repeat) ? me.repeat : {}), 'click', me.onRepeatClick, me);
} else {
if (btnListeners[me.clickEvent]) {
addOnclick = true;
} else {
btnListeners[me.clickEvent] = me.onClick;
}
}
me.mon(btn, btnListeners);
if (me.hasFrameTable()) {
me.mon(me.frameTable, 'click', me.frameTableListener, me);
}
if (addOnclick) {
me.mon(btn, me.clickEvent, me.onClick, me);
}
Ext.button.Manager.register(me);
},
onFocusLeave: function(e) {
this.callParent([
e
]);
if (this.menu) {
this.menu.hide();
}
},
getTemplateArgs: function() {
var me = this,
btnCls = me._btnCls,
baseIconCls = me._baseIconCls,
iconAlign = me.getIconAlign(),
glyph = me.glyph,
glyphFontFamily = Ext._glyphFontFamily,
text = me.text,
hasIcon = me._hasIcon(),
hasIconCls = me._hasIconCls,
glyphParts;
if (typeof glyph === 'string') {
glyphParts = glyph.split('@');
glyph = glyphParts[0];
glyphFontFamily = glyphParts[1];
}
return {
innerCls: me._innerCls,
splitCls: me.getArrowVisible() ? me.getSplitCls() : '',
iconUrl: me.icon,
iconCls: me.iconCls,
glyph: glyph,
glyphCls: glyph ? me._glyphCls : '',
glyphFontFamily: glyphFontFamily,
text: text || '&#160;',
closeText: me.closeText,
textCls: text ? me._textCls : '',
noTextCls: text ? '' : me._noTextCls,
hasIconCls: hasIcon ? hasIconCls : '',
btnWrapCls: me._btnWrapCls,
btnWrapStyle: me.width ? 'table-layout:fixed;' : '',
btnElStyle: me.height ? 'height:auto;' : '',
btnCls: btnCls,
baseIconCls: baseIconCls,
iconBeforeText: iconAlign === 'left' || iconAlign === 'top',
iconAlignCls: hasIcon ? (hasIconCls + '-' + iconAlign) : '',
textAlignCls: btnCls + '-' + me.getTextAlign()
};
},
renderIcon: function(values) {
return this.getTpl('iconTpl').apply(values);
},
setHref: function(href) {
var me = this,
hrefTarget = me.hrefTarget,
dom;
me.href = href;
if (!me.configuredWithPreventDefault) {
me.preventDefault = !href;
}
if (me.rendered) {
dom = me.el.dom;
if (!href || me.disabled) {
dom.removeAttribute('href');
dom.removeAttribute('hrefTarget');
} else {
dom.href = me.getHref();
if (hrefTarget) {
dom.target = hrefTarget;
}
}
}
},
getHref: function() {
var me = this,
href = me.href;
return href ? Ext.urlAppend(href, Ext.Object.toQueryString(Ext.apply({}, me.params, me.baseParams))) : false;
},
setParams: function(params) {
var me = this,
dom;
me.params = params;
if (me.rendered) {
dom = me.el.dom;
if (me.disabled) {
dom.removeAttribute('href');
} else {
dom.href = me.getHref() || '';
}
}
},
getSplitCls: function() {
var me = this;
return me.split ? (me.baseCls + '-' + me.arrowCls) + ' ' + (me.baseCls + '-' + me.arrowCls + '-' + me.arrowAlign) : '';
},
setIcon: function(icon) {
icon = icon || '';
var me = this,
btnIconEl = me.btnIconEl,
oldIcon = me.icon || '';
me.icon = icon;
if (icon !== oldIcon) {
if (btnIconEl) {
btnIconEl.setStyle('background-image', icon ? 'url(' + icon + ')' : '');
me._syncHasIconCls();
if (me.didIconStateChange(oldIcon, icon)) {
me.updateLayout();
}
}
me.fireEvent('iconchange', me, oldIcon, icon);
}
return me;
},
setIconCls: function(cls) {
cls = cls || '';
var me = this,
btnIconEl = me.btnIconEl,
oldCls = me.iconCls || '';
me.iconCls = cls;
if (oldCls !== cls) {
if (btnIconEl) {
btnIconEl.removeCls(oldCls);
btnIconEl.addCls(cls);
me._syncHasIconCls();
if (me.didIconStateChange(oldCls, cls)) {
me.updateLayout();
}
}
me.fireEvent('iconchange', me, oldCls, cls);
}
return me;
},
setGlyph: function(glyph) {
glyph = glyph || 0;
var me = this,
btnIconEl = me.btnIconEl,
oldGlyph = me.glyph,
glyphCls = me._glyphCls,
fontFamily, glyphParts;
me.glyph = glyph;
if (btnIconEl) {
if (typeof glyph === 'string') {
glyphParts = glyph.split('@');
glyph = glyphParts[0];
fontFamily = glyphParts[1] || Ext._glyphFontFamily;
}
if (!glyph) {
btnIconEl.dom.innerHTML = '';
btnIconEl.removeCls(glyphCls);
} else if (oldGlyph !== glyph) {
btnIconEl.dom.innerHTML = '&#' + glyph + ';';
btnIconEl.addCls(glyphCls);
}
if (fontFamily) {
btnIconEl.setStyle('font-family', fontFamily);
}
me._syncHasIconCls();
if (me.didIconStateChange(oldGlyph, glyph)) {
me.updateLayout();
}
}
me.fireEvent('glyphchange', me, me.glyph, oldGlyph);
return me;
},
setTooltip: function(tooltip, initial) {
var me = this;
if (me.rendered) {
if (!initial || !tooltip) {
me.clearTip();
}
if (tooltip) {
if (Ext.quickTipsActive && Ext.isObject(tooltip)) {
Ext.tip.QuickTipManager.register(Ext.apply({
target: me.el.id
}, tooltip));
me.tooltip = tooltip;
} else {
me.el.dom.setAttribute(me.getTipAttr(), tooltip);
}
}
} else {
me.tooltip = tooltip;
}
return me;
},
updateIconAlign: function(align, oldAlign) {
var me = this,
btnEl, btnIconEl, hasIconCls;
if (me.rendered) {
btnEl = me.btnEl;
btnIconEl = me.btnIconEl;
hasIconCls = me._hasIconCls;
if (oldAlign) {
btnEl.removeCls(hasIconCls + '-' + oldAlign);
}
btnEl.addCls(hasIconCls + '-' + align);
if (align === 'top' || align === 'left') {
btnEl.insertFirst(btnIconEl);
} else {
btnEl.appendChild(btnIconEl);
}
me.updateLayout();
}
},
updateTextAlign: function(align, oldAlign) {
var me = this,
btnEl = me.btnEl,
btnCls = me._btnCls;
if (me.rendered) {
btnEl.removeCls(btnCls + '-' + oldAlign);
btnEl.addCls(btnCls + '-' + align);
}
},
getTipAttr: function() {
return this.tooltipType === 'qtip' ? 'data-qtip' : 'title';
},
getRefItems: function(deep) {
var menu = this.menu,
items;
if (menu) {
items = menu.getRefItems(deep);
items.unshift(menu);
}
return items || [];
},
clearTip: function() {
var me = this,
el = me.el;
if (Ext.quickTipsActive && Ext.isObject(me.tooltip)) {
Ext.tip.QuickTipManager.unregister(el);
} else {
el.dom.removeAttribute(me.getTipAttr());
}
},
beforeDestroy: function() {
var me = this;
if (me.rendered) {
me.clearTip();
}
Ext.destroy(me.repeater);
me.callParent();
},
onDestroy: function() {
var me = this,
menu = me.menu;
if (me.rendered) {
Ext.destroy(me.keyMap);
delete me.keyMap;
}
if (menu && me.destroyMenu) {
me.menu = Ext.destroy(menu);
}
Ext.button.Manager.unregister(me);
me.callParent();
},
setHandler: function(handler, scope) {
this.handler = handler;
if (arguments.length > 1) {
this.scope = scope;
}
return this;
},
updateText: function(text, oldText) {
text = text == null ? '' : String(text);
oldText = oldText || '';
var me = this,
btnInnerEl = me.btnInnerEl,
btnEl = me.btnEl;
if (me.rendered) {
btnInnerEl.setHtml(text || '&#160;');
btnEl[text ? 'addCls' : 'removeCls'](me._textCls);
btnEl[text ? 'removeCls' : 'addCls'](me._noTextCls);
me.updateLayout();
}
me.fireEvent('textchange', me, oldText, text);
},
didIconStateChange: function(old, current) {
var currentEmpty = Ext.isEmpty(current);
return Ext.isEmpty(old) ? !currentEmpty : currentEmpty;
},
setPressed: function(pressed) {
return this.toggle(pressed !== false);
},
toggle: function(state, suppressEvent) {
var me = this;
state = state === undefined ? !me.pressed : !!state;
if (state !== me.pressed) {
me[state ? 'addCls' : 'removeCls'](me._pressedCls);
me.pressed = state;
if (!suppressEvent) {
me.fireEvent('toggle', me, state);
Ext.callback(me.toggleHandler, me.scope, [
me,
state
], 0, me);
if (me.reference && me.publishState) {
me.publishState('pressed', state);
}
}
}
return me;
},
maybeShowMenu: function(e) {
if (this.menu) {
this.showMenu(e);
}
},
showMenu: function(
clickEvent) {
var me = this,
menu = me.menu,
isPointerEvent = !clickEvent || clickEvent.pointerType;
if (menu && me.rendered) {
if (me.tooltip && Ext.quickTipsActive && me.getTipAttr() !== 'title') {
Ext.tip.QuickTipManager.getQuickTip().cancelShow(me.el);
}
if (menu.isVisible()) {
if (isPointerEvent) {
menu.hide();
} else {
menu.focus();
}
} else if (!clickEvent || me.showEmptyMenu || menu.items.getCount() > 0) {
menu.autoFocus = !isPointerEvent;
menu.showBy(me.el, me.menuAlign);
}
}
return me;
},
hideMenu: function() {
if (this.hasVisibleMenu()) {
this.menu.hide();
}
return this;
},
hasVisibleMenu: function() {
var menu = this.menu;
return menu && menu.rendered && menu.isVisible();
},
onRepeatClick: function(repeat, e) {
this.onClick(e);
},
onTouchStart: function(e) {
this.doPreventDefault(e);
},
onClick: function(e) {
var me = this;
me.doPreventDefault(e);
if (e.type !== 'keydown' && e.button) {
return;
}
if (!me.disabled) {
me.doToggle();
me.maybeShowMenu(e);
me.fireHandler(e);
}
},
doPreventDefault: function(e) {
if (e && (this.preventDefault || (this.disabled && this.getHref()))) {
e.preventDefault();
}
},
fireHandler: function(e) {
var me = this;
if (me.fireEvent('click', me, e) !== false && !me.isDestroyed) {
Ext.callback(me.handler, me.scope, [
me,
e
], 0, me);
}
},
doToggle: function() {
var me = this;
if (me.enableToggle && (me.allowDepress !== false || !me.pressed)) {
me.toggle();
}
},
onMouseOver: function(e) {
var me = this;
if (!me.disabled && !e.within(me.el, true, true)) {
me.onMouseEnter(e);
}
},
onMouseOut: function(e) {
var me = this;
if (!e.within(me.el, true, true)) {
if (me.overMenuTrigger) {
me.onMenuTriggerOut(e);
}
me.onMouseLeave(e);
}
},
onMouseMove: function(e) {
var me = this,
over = me.overMenuTrigger;
if (me.split) {
if (me.isWithinTrigger(e)) {
if (!over) {
me.onMenuTriggerOver(e);
}
} else if (over) {
me.onMenuTriggerOut(e);
}
}
},
isWithinTrigger: function(e) {
var me = this,
el = me.el,
overPosition, triggerRegion;
overPosition = (me.arrowAlign === 'right') ? e.getX() - me.getX() : e.getY() - el.getY();
triggerRegion = me.getTriggerRegion();
return overPosition > triggerRegion.begin && overPosition < triggerRegion.end;
},
getTriggerRegion: function() {
var me = this,
region = me._triggerRegion,
isRight = me.arrowAlign === 'right',
getEnd = isRight ? 'getRight' : 'getBottom',
btnSize = isRight ? me.getWidth() : me.getHeight();
region.begin = btnSize - (me.el[getEnd]() - me.btnEl[getEnd]());
region.end = btnSize;
return region;
},
onMouseEnter: function(e) {
this.fireEvent('mouseover', this, e);
},
onMouseLeave: function(e) {
this.fireEvent('mouseout', this, e);
},
onMenuTriggerOver: function(e) {
var me = this,
arrowTip = me.arrowTooltip;
me.overMenuTrigger = true;
if (me.split && arrowTip) {
me.btnWrap.dom.setAttribute(me.getTipAttr(), arrowTip);
}
me.fireEvent('menutriggerover', me, me.menu, e);
},
onMenuTriggerOut: function(e) {
var me = this;
delete me.overMenuTrigger;
if (me.split && me.arrowTooltip) {
me.btnWrap.dom.setAttribute(me.getTipAttr(), '');
}
me.fireEvent('menutriggerout', me, me.menu, e);
},
enable: function(silent) {
var me = this,
href = me.href,
hrefTarget = me.hrefTarget,
dom;
me.callParent(arguments);
me.removeCls(me._disabledCls);
if (me.rendered) {
dom = me.el.dom;
dom.setAttribute('tabindex', me.tabIndex);
if (href) {
dom.href = href;
}
if (hrefTarget) {
dom.target = hrefTarget;
}
}
return me;
},
disable: function(silent) {
var me = this,
dom;
me.callParent(arguments);
me.addCls(me._disabledCls);
me.removeCls(me.overCls);
if (me.rendered) {
dom = me.el.dom;
dom.removeAttribute('tabindex');
if (me.href) {
dom.removeAttribute('href');
}
if (me.hrefTarget) {
dom.removeAttribute('target');
}
}
return me;
},
setScale: function(scale) {
var me = this,
ui = me.ui.replace('-' + me.scale, '');
if (!Ext.Array.contains(me.allowedScales, scale)) {
throw ('#setScale: scale must be an allowed scale (' + me.allowedScales.join(', ') + ')');
}
me.scale = scale;
me.setUI(ui);
},
setUI: function(ui) {
var me = this;
if (me.scale && !ui.match(me.scale)) {
ui = ui + '-' + me.scale;
}
me.callParent([
ui
]);
},
onMouseDown: function(e) {
var me = this;
if (Ext.isIE || e.pointerType === 'touch') {
Ext.defer(function() {
if (!e.defaultPrevented) {
var focusEl = me.getFocusEl();
if (focusEl) {
focusEl.focus();
}
}
}, 1);
}
if (!me.disabled && e.button === 0) {
Ext.button.Manager.onButtonMousedown(me, e);
me.addCls(me._pressedCls);
}
},
onMouseUp: function(e) {
var me = this;
if (!me.isDestroyed && e.button === 0) {
if (!me.pressed) {
me.removeCls(me._pressedCls);
}
}
},
onMenuShow: function() {
var me = this;
me.addCls(me._menuActiveCls);
me.fireEvent('menushow', me, me.menu);
},
onMenuHide: function(e) {
var me = this;
me.removeCls(me._menuActiveCls);
me.fireEvent('menuhide', me, me.menu);
},
onDownKey: function(k, e) {
var me = this;
if (me.menu && !me.disabled) {
me.showMenu(e);
e.stopEvent();
return false;
}
},
updateArrowVisible: function(visible) {
var me = this;
if (me.rendered) {
if (visible) {
if (me.menu || me.isSplitButton) {
me.split = true;
me._addSplitCls();
}
} else {
me._removeSplitCls();
me.split = false;
}
}
return visible;
},
privates: {
addOverCls: function() {
if (!this.disabled) {
this.addCls(this.overCls);
}
},
_addSplitCls: function() {
var me = this;
me.btnWrap.addCls(me.getSplitCls());
if (Ext.isOpera12m) {
me.addCls(me._operaArrowCls + '-' + me.arrowAlign);
}
},
getFocusEl: function() {
return this.el;
},
getTdCls: function() {
return Ext.baseCSSPrefix + 'button-' + this.ui + '-' + this.scale + '-cell';
},
removeOverCls: function() {
this.removeCls(this.overCls);
},
_removeSplitCls: function() {
var me = this;
me.btnWrap.removeCls(me.getSplitCls());
if (Ext.isOpera12m) {
me.removeCls(me._operaArrowCls + '-' + me.arrowAlign);
}
},
_syncHasIconCls: function() {
var me = this,
btnEl = me.btnEl,
hasIconCls = me._hasIconCls;
if (btnEl) {
btnEl[me._hasIcon() ? 'addCls' : 'removeCls']([
hasIconCls,
hasIconCls + '-' + me.iconAlign
]);
}
},
_hasIcon: function() {
return !!(this.icon || this.iconCls || this.glyph);
},
wrapPrimaryEl: function(dom) {
this.el = new Ext.dom.ButtonElement(dom);
this.callParent([
dom
]);
}
}
});
Ext.define('Ext.tab.Tab', {
extend: 'Ext.button.Button',
alias: 'widget.tab',
requires: [
'Ext.util.KeyNav'
],
isTab: true,
tabIndex: -1,
baseCls: Ext.baseCSSPrefix + 'tab',
closeElOverCls: Ext.baseCSSPrefix + 'tab-close-btn-over',
closeElPressedCls: Ext.baseCSSPrefix + 'tab-close-btn-pressed',
config: {
rotation: 'default',
tabPosition: 'top'
},
closable: true,
closeText: 'Close Tab',
active: false,
childEls: [
'closeEl'
],
scale: false,
ariaRole: 'tab',
_btnWrapCls: Ext.baseCSSPrefix + 'tab-wrap',
_btnCls: Ext.baseCSSPrefix + 'tab-button',
_baseIconCls: Ext.baseCSSPrefix + 'tab-icon-el',
_glyphCls: Ext.baseCSSPrefix + 'tab-glyph',
_innerCls: Ext.baseCSSPrefix + 'tab-inner',
_textCls: Ext.baseCSSPrefix + 'tab-text',
_noTextCls: Ext.baseCSSPrefix + 'tab-no-text',
_hasIconCls: Ext.baseCSSPrefix + 'tab-icon',
_activeCls: Ext.baseCSSPrefix + 'tab-active',
_closableCls: Ext.baseCSSPrefix + 'tab-closable',
overCls: Ext.baseCSSPrefix + 'tab-over',
_pressedCls: Ext.baseCSSPrefix + 'tab-pressed',
_disabledCls: Ext.baseCSSPrefix + 'tab-disabled',
_rotateClasses: {
1: Ext.baseCSSPrefix + 'tab-rotate-right',
2: Ext.baseCSSPrefix + 'tab-rotate-left'
},
_positions: {
top: {
'default': 'top',
0: 'top',
1: 'left',
2: 'right'
},
right: {
'default': 'top',
0: 'right',
1: 'top',
2: 'bottom'
},
bottom: {
'default': 'bottom',
0: 'bottom',
1: 'right',
2: 'left'
},
left: {
'default': 'top',
0: 'left',
1: 'bottom',
2: 'top'
}
},
_defaultRotations: {
top: 0,
right: 1,
bottom: 0,
left: 2
},
initComponent: function() {
var me = this;
if (me.card) {
me.setCard(me.card);
}
me.callParent(arguments);
},
getActualRotation: function() {
var rotation = this.getRotation();
return (rotation !== 'default') ? rotation : this._defaultRotations[this.getTabPosition()];
},
updateRotation: function() {
this.syncRotationAndPosition();
},
updateTabPosition: function() {
this.syncRotationAndPosition();
},
syncRotationAndPosition: function() {
var me = this,
rotateClasses = me._rotateClasses,
position = me.getTabPosition(),
rotation = me.getActualRotation(),
oldRotateCls = me._rotateCls,
rotateCls = me._rotateCls = rotateClasses[rotation],
oldPositionCls = me._positionCls,
positionCls = me._positionCls = me._positions[position][rotation];
if (oldRotateCls !== rotateCls) {
if (oldRotateCls) {
me.removeCls(oldRotateCls);
}
if (rotateCls) {
me.addCls(rotateCls);
}
}
if (oldPositionCls !== positionCls) {
if (oldPositionCls) {
me.removeClsWithUI(oldPositionCls);
}
if (positionCls) {
me.addClsWithUI(positionCls);
}
if (me.rendered) {
me.updateFrame();
}
}
if (me.rendered) {
me.setElOrientation();
}
},
onAdded: function(container, pos, instanced) {
this.callParent([
container,
pos,
instanced
]);
this.syncRotationAndPosition();
},
getTemplateArgs: function() {
var me = this,
result = me.callParent();
result.closable = me.closable;
result.closeText = me.closeText;
return result;
},
beforeRender: function() {
var me = this,
tabBar = me.up('tabbar'),
tabPanel = me.up('tabpanel');
me.callParent();
if (me.active) {
me.addCls(me._activeCls);
}
me.syncClosableCls();
if (!me.minWidth) {
me.minWidth = (tabBar) ? tabBar.minTabWidth : me.minWidth;
if (!me.minWidth && tabPanel) {
me.minWidth = tabPanel.minTabWidth;
}
if (me.minWidth && me.iconCls) {
me.minWidth += 25;
}
}
if (!me.maxWidth) {
me.maxWidth = (tabBar) ? tabBar.maxTabWidth : me.maxWidth;
if (!me.maxWidth && tabPanel) {
me.maxWidth = tabPanel.maxTabWidth;
}
}
},
onRender: function() {
var me = this;
me.setElOrientation();
me.callParent(arguments);
if (me.closable) {
me.closeEl.addClsOnOver(me.closeElOverCls);
me.closeEl.addClsOnClick(me.closeElPressedCls);
}
me.initKeyNav();
},
initKeyNav: function() {
var me = this;
me.keyNav = new Ext.util.KeyNav(me.el, {
enter: me.onEnterKey,
del: me.onDeleteKey,
scope: me
});
},
setElOrientation: function() {
var me = this,
rotation = me.getActualRotation(),
el = me.el;
if (rotation) {
el.setVertical(rotation === 1 ? 90 : 270);
} else {
el.setHorizontal();
}
},
enable: function(silent) {
var me = this;
me.callParent(arguments);
me.removeCls(me._disabledCls);
return me;
},
disable: function(silent) {
var me = this;
me.callParent(arguments);
me.addCls(me._disabledCls);
return me;
},
onDestroy: function() {
var me = this;
Ext.destroy(me.keyNav);
delete me.keyNav;
me.callParent(arguments);
},
setClosable: function(closable) {
var me = this;
closable = (!arguments.length || !!closable);
if (me.closable !== closable) {
me.closable = closable;
if (me.card) {
me.card.closable = closable;
}
me.syncClosableCls();
if (me.rendered) {
me.syncClosableElements();
me.updateLayout();
}
}
},
syncClosableElements: function() {
var me = this,
closeEl = me.closeEl;
if (me.closable) {
if (!closeEl) {
closeEl = me.closeEl = me.btnWrap.insertSibling({
tag: 'a',
role: 'presentation',
cls: me.baseCls + '-close-btn',
href: '#',
title: me.closeText
}, 'after');
}
closeEl.addClsOnOver(me.closeElOverCls);
closeEl.addClsOnClick(me.closeElPressedCls);
} else if (closeEl) {
closeEl.destroy();
delete me.closeEl;
}
},
syncClosableCls: function() {
var me = this,
closableCls = me._closableCls;
if (me.closable) {
me.addCls(closableCls);
} else {
me.removeCls(closableCls);
}
},
setCard: function(card) {
var me = this;
me.card = card;
if (card.iconAlign) {
me.setIconAlign(card.iconAlign);
}
if (card.textAlign) {
me.setTextAlign(card.textAlign);
}
me.setText(me.title || card.title);
me.setIconCls(me.iconCls || card.iconCls);
me.setIcon(me.icon || card.icon);
me.setGlyph(me.glyph || card.glyph);
},
onCloseClick: function() {
var me = this;
if (me.fireEvent('beforeclose', me) !== false) {
if (me.tabBar) {
if (me.tabBar.closeTab(me) === false) {
return;
}
} else {
me.fireClose();
}
}
},
fireClose: function() {
this.fireEvent('close', this);
},
onEnterKey: function(e) {
var me = this;
if (me.tabBar) {
me.tabBar.onClick(e, me.el);
}
},
onDeleteKey: function(e) {
if (this.closable) {
this.onCloseClick();
}
},
beforeClick: function(isCloseClick) {
if (!isCloseClick) {
this.focus();
}
},
activate: function(supressEvent) {
var me = this;
me.active = true;
me.addCls(me._activeCls);
if (supressEvent !== true) {
me.fireEvent('activate', me);
}
},
deactivate: function(supressEvent) {
var me = this;
me.active = false;
me.removeCls(me._activeCls);
if (supressEvent !== true) {
me.fireEvent('deactivate', me);
}
},
privates: {
getFramingInfoCls: function() {
return this.baseCls + '-' + this.ui + '-' + this._positionCls;
},
wrapPrimaryEl: function(dom) {
Ext.Button.superclass.wrapPrimaryEl.call(this, dom);
}
}
});
Ext.define('Ext.layout.component.Body', {
alias: [
'layout.body'
],
extend: 'Ext.layout.component.Auto',
type: 'body',
beginLayout: function(ownerContext) {
this.callParent(arguments);
ownerContext.bodyContext = ownerContext.getEl('body');
},
beginLayoutCycle: function(ownerContext, firstCycle) {
var me = this,
lastWidthModel = me.lastWidthModel,
lastHeightModel = me.lastHeightModel,
body = me.owner.body;
me.callParent(arguments);
if (lastWidthModel && lastWidthModel.fixed && ownerContext.widthModel.shrinkWrap) {
body.setWidth(null);
}
if (lastHeightModel && lastHeightModel.fixed && ownerContext.heightModel.shrinkWrap) {
body.setHeight(null);
}
},
calculateOwnerHeightFromContentHeight: function(ownerContext, contentHeight) {
var height = this.callParent(arguments);
if (ownerContext.targetContext !== ownerContext) {
height += ownerContext.getPaddingInfo().height;
}
return height;
},
calculateOwnerWidthFromContentWidth: function(ownerContext, contentWidth) {
var width = this.callParent(arguments);
if (ownerContext.targetContext !== ownerContext) {
width += ownerContext.getPaddingInfo().width;
}
return width;
},
measureContentWidth: function(ownerContext) {
return ownerContext.bodyContext.setWidth(ownerContext.bodyContext.el.dom.offsetWidth, false);
},
measureContentHeight: function(ownerContext) {
return ownerContext.bodyContext.setHeight(ownerContext.bodyContext.el.dom.offsetHeight, false);
},
publishInnerHeight: function(ownerContext, height) {
var innerHeight = height - ownerContext.getFrameInfo().height,
targetContext = ownerContext.targetContext;
if (targetContext !== ownerContext) {
innerHeight -= ownerContext.getPaddingInfo().height;
}
return ownerContext.bodyContext.setHeight(innerHeight, !ownerContext.heightModel.natural);
},
publishInnerWidth: function(ownerContext, width) {
var innerWidth = width - ownerContext.getFrameInfo().width,
targetContext = ownerContext.targetContext;
if (targetContext !== ownerContext) {
innerWidth -= ownerContext.getPaddingInfo().width;
}
ownerContext.bodyContext.setWidth(innerWidth, !ownerContext.widthModel.natural);
}
});
Ext.define('Ext.tab.Bar', {
extend: 'Ext.panel.Bar',
xtype: 'tabbar',
baseCls: Ext.baseCSSPrefix + 'tab-bar',
requires: [
'Ext.tab.Tab',
'Ext.util.Point',
'Ext.layout.component.Body'
],
mixins: [
'Ext.util.FocusableContainer'
],
componentLayout: 'body',
isTabBar: true,
config: {
tabRotation: 'default',
tabStretchMax: true,
activateOnFocus: true
},
defaultType: 'tab',
plain: false,
ensureActiveVisibleOnChange: true,
ariaRole: 'tablist',
childEls: [
'body',
'strip'
],
_stripCls: Ext.baseCSSPrefix + 'tab-bar-strip',
_baseBodyCls: Ext.baseCSSPrefix + 'tab-bar-body',
renderTpl: '<div id="{id}-body" data-ref="body" role="presentation" class="{baseBodyCls} {baseBodyCls}-{ui} ' + '{bodyCls} {bodyTargetCls}{childElCls}"<tpl if="bodyStyle"> style="{bodyStyle}"</tpl>>' + '{%this.renderContainer(out,values)%}' + '</div>' + '<div id="{id}-strip" data-ref="strip" role="presentation" class="{stripCls} {stripCls}-{ui}{childElCls}"></div>',
_reverseDockNames: {
left: 'right',
right: 'left'
},
_layoutAlign: {
top: 'end',
right: 'begin',
bottom: 'begin',
left: 'end'
},
initComponent: function() {
var me = this,
initialLayout = me.initialConfig.layout,
initialAlign = initialLayout && initialLayout.align,
initialOverflowHandler = initialLayout && initialLayout.overflowHandler;
if (me.plain) {
me.addCls(me.baseCls + '-plain');
}
me.callParent();
me.setLayout({
align: initialAlign || (me.getTabStretchMax() ? 'stretchmax' : me._layoutAlign[me.dock]),
overflowHandler: initialOverflowHandler || 'scroller'
});
me.on({
click: me.onClick,
element: 'el',
scope: me
});
},
ensureTabVisible: function(tab) {
var me = this,
tabPanel = me.tabPanel,
overflowHandler = me.layout.overflowHandler;
if (me.rendered && overflowHandler && me.tooNarrow && overflowHandler.scrollToItem) {
if (tab || tab === 0) {
if (!tab.isTab) {
if (Ext.isNumber(tab)) {
tab = this.items.getAt(tab);
} else if (tab.isComponent && tabPanel && tabPanel.items.contains(tab)) {
tab = tab.tab;
}
}
}
if (!tab) {
tab = me.activeTab;
}
if (tab) {
overflowHandler.scrollToItem(tab);
}
}
},
initRenderData: function() {
var me = this;
return Ext.apply(me.callParent(), {
bodyCls: me.bodyCls,
baseBodyCls: me._baseBodyCls,
bodyTargetCls: me.bodyTargetCls,
stripCls: me._stripCls,
dock: me.dock
});
},
setDock: function(dock) {
var me = this,
items = me.items,
ownerCt = me.ownerCt,
item, i, ln;
items = items && items.items;
if (items) {
for (i = 0 , ln = items.length; i < ln; i++) {
item = items[i];
if (item.isTab) {
item.setTabPosition(dock);
}
}
}
if (me.rendered) {
me.resetItemMargins();
if (ownerCt && ownerCt.isHeader) {
ownerCt.resetItemMargins();
}
me.needsScroll = true;
}
me.callParent([
dock
]);
},
updateTabRotation: function(tabRotation) {
var me = this,
items = me.items,
i, ln, item;
items = items && items.items;
if (items) {
for (i = 0 , ln = items.length; i < ln; i++) {
item = items[i];
if (item.isTab) {
item.setRotation(tabRotation);
}
}
}
if (me.rendered) {
me.resetItemMargins();
me.needsScroll = true;
me.updateLayout();
}
},
onRender: function() {
var me = this;
me.callParent();
if (Ext.isIE8 && me.vertical) {
me.el.on({
mousemove: me.onMouseMove,
scope: me
});
}
},
afterLayout: function() {
this.adjustTabPositions();
this.callParent(arguments);
},
onAdd: function(tab, pos) {
var fn = this.onTabContentChange;
if (this.ensureActiveVisibleOnChange) {
tab.barListeners = tab.on({
scope: this,
destroyable: true,
glyphchange: fn,
iconchange: fn,
textchange: fn
});
}
this.callParent([
tab,
pos
]);
},
onAdded: function(container, pos, instanced) {
if (container.isHeader) {
this.addCls(container.baseCls + '-' + container.ui + '-tab-bar');
}
this.callParent([
container,
pos,
instanced
]);
},
onRemove: function(tab, destroying) {
var me = this;
if (me.ensureActiveVisibleOnChange) {
if (!destroying) {
tab.barListeners.destroy();
}
tab.barListeners = null;
}
if (tab === me.previousTab) {
me.previousTab = null;
}
me.callParent([
tab,
destroying
]);
},
onRemoved: function(destroying) {
var ownerCt = this.ownerCt;
if (ownerCt.isHeader) {
this.removeCls(ownerCt.baseCls + '-' + ownerCt.ui + '-tab-bar');
}
this.callParent([
destroying
]);
},
onTabContentChange: function(tab) {
if (tab === this.activeTab) {
this.ensureTabVisible(tab);
}
},
afterComponentLayout: function(width) {
var me = this,
needsScroll = me.needsScroll,
overflowHandler = me.layout.overflowHandler;
me.callParent(arguments);
if (overflowHandler && needsScroll && me.tooNarrow && overflowHandler.scrollToItem) {
overflowHandler.scrollToItem(me.activeTab);
}
delete me.needsScroll;
},
onMouseMove: function(e) {
var me = this,
overTab = me._overTab,
tabInfo, tab;
if (e.getTarget('.' + Ext.baseCSSPrefix + 'box-scroller')) {
return;
}
tabInfo = me.getTabInfoFromPoint(e.getXY());
tab = tabInfo.tab;
if (tab !== overTab) {
if (overTab && overTab.rendered) {
overTab.onMouseLeave(e);
me._overTab = null;
}
if (tab) {
tab.onMouseEnter(e);
me._overTab = tab;
if (!tab.disabled) {
me.el.setStyle('cursor', 'pointer');
}
} else {
me.el.setStyle('cursor', 'default');
}
}
},
onMouseLeave: function(e) {
var overTab = this._overTab;
if (overTab && overTab.rendered) {
overTab.onMouseLeave(e);
}
},
getTabInfoFromPoint: function(xy) {
var me = this,
tabs = me.items.items,
length = tabs.length,
innerCt = me.layout.innerCt,
innerCtXY = innerCt.getXY(),
point = new Ext.util.Point(xy[0], xy[1]),
i = 0,
lastBox, tabRegion, closeEl, close, closeXY, closeX, closeY, closeWidth, closeHeight, tabX, tabY, tabWidth, tabHeight, closeRegion, isTabReversed, direction, tab;
for (; i < length; i++) {
tab = tabs[i];
lastBox = tab.lastBox;
if (!lastBox || !tab.isTab) {
continue;
}
tabX = innerCtXY[0] + lastBox.x;
tabY = innerCtXY[1] - innerCt.dom.scrollTop + lastBox.y;
tabWidth = lastBox.width;
tabHeight = lastBox.height;
tabRegion = new Ext.util.Region(tabY, tabX + tabWidth, tabY + tabHeight, tabX);
if (tabRegion.contains(point)) {
closeEl = tab.closeEl;
if (closeEl) {
if (me._isTabReversed === undefined) {
me._isTabReversed = isTabReversed =
(tab.btnWrap.dom.currentStyle.filter.indexOf('rotation=2') !== -1);
}
direction = isTabReversed ? this._reverseDockNames[me.dock] : me.dock;
closeWidth = closeEl.getWidth();
closeHeight = closeEl.getHeight();
closeXY = me.getCloseXY(closeEl, tabX, tabY, tabWidth, tabHeight, closeWidth, closeHeight, direction);
closeX = closeXY[0];
closeY = closeXY[1];
closeRegion = new Ext.util.Region(closeY, closeX + closeWidth, closeY + closeHeight, closeX);
close = closeRegion.contains(point);
}
break;
}
}
return {
tab: tab,
close: close
};
},
getCloseXY: function(closeEl, tabX, tabY, tabWidth, tabHeight, closeWidth, closeHeight, direction) {
var closeXY = closeEl.getXY(),
closeX, closeY;
if (direction === 'right') {
closeX = tabX + tabWidth - ((closeXY[1] - tabY) + closeHeight);
closeY = tabY + (closeXY[0] - tabX);
} else {
closeX = tabX + (closeXY[1] - tabY);
closeY = tabY + tabX + tabHeight - closeXY[0] - closeWidth;
}
return [
closeX,
closeY
];
},
closeTab: function(toClose) {
var me = this,
card = toClose.card,
tabPanel = me.tabPanel,
toActivate;
if (card && card.fireEvent('beforeclose', card) === false) {
return false;
}
toActivate = me.findNextActivatable(toClose);
Ext.suspendLayouts();
if (tabPanel && card) {
delete toClose.ownerCt;
card.fireEvent('close', card);
tabPanel.remove(card);
if (!tabPanel.getComponent(card)) {
toClose.fireClose();
me.remove(toClose);
} else {
toClose.ownerCt = me;
Ext.resumeLayouts(true);
return false;
}
}
if (toActivate) {
if (tabPanel) {
tabPanel.setActiveTab(toActivate.card);
} else {
me.setActiveTab(toActivate);
}
toActivate.focus();
}
Ext.resumeLayouts(true);
},
findNextActivatable: function(toClose) {
var me = this;
if (toClose.active && me.items.getCount() > 1) {
return (me.previousTab && me.previousTab !== toClose && !me.previousTab.disabled) ? me.previousTab : (toClose.next('tab[disabled=false]') || toClose.prev('tab[disabled=false]'));
}
},
setActiveTab: function(tab, initial) {
var me = this;
if (!tab.disabled && tab !== me.activeTab) {
if (me.activeTab) {
if (me.activeTab.isDestroyed) {
me.previousTab = null;
} else {
me.previousTab = me.activeTab;
me.activeTab.deactivate();
me.deactivateFocusable(me.activeTab);
}
}
tab.activate();
me.activateFocusable(tab);
me.activeTab = tab;
me.needsScroll = true;
if (!initial) {
me.fireEvent('change', me, tab, tab.card);
me.updateLayout();
}
}
},
privates: {
adjustTabPositions: function() {
var me = this,
items = me.items.items,
i = items.length,
tab, lastBox, el, rotation, prop;
if (!Ext.isIE8) {
prop = me._getTabAdjustProp();
while (i--) {
tab = items[i];
el = tab.el;
lastBox = tab.lastBox;
rotation = tab.isTab ? tab.getActualRotation() : 0;
if (rotation === 1 && tab.isVisible()) {
el.setStyle(prop, (lastBox.x + lastBox.width) + 'px');
} else if (rotation === 2 && tab.isVisible()) {
el.setStyle(prop, (lastBox.x - lastBox.height) + 'px');
}
}
}
},
applyTargetCls: function(targetCls) {
this.bodyTargetCls = targetCls;
},
_getTabAdjustProp: function() {
return 'left';
},
getTargetEl: function() {
return this.body || this.frameBody || this.el;
},
onClick: function(e, target) {
var me = this,
tabEl, tab, isCloseClick, tabInfo;
if (e.getTarget('.' + Ext.baseCSSPrefix + 'box-scroller')) {
return;
}
if (Ext.isIE8 && me.vertical) {
tabInfo = me.getTabInfoFromPoint(e.getXY());
tab = tabInfo.tab;
isCloseClick = tabInfo.close;
} else {
tabEl = e.getTarget('.' + Ext.tab.Tab.prototype.baseCls);
tab = tabEl && Ext.getCmp(tabEl.id);
isCloseClick = tab && tab.closeEl && (target === tab.closeEl.dom);
}
if (isCloseClick) {
e.preventDefault();
}
if (tab && tab.isDisabled && !tab.isDisabled()) {
tab.beforeClick(isCloseClick);
if (tab.closable && isCloseClick) {
tab.onCloseClick();
} else {
me.doActivateTab(tab);
}
}
},
doActivateTab: function(tab) {
var tabPanel = this.tabPanel;
if (tabPanel) {
if (!tab.disabled) {
tabPanel.setActiveTab(tab.card);
}
} else {
this.setActiveTab(tab);
}
},
onFocusableContainerFocus: function(e) {
var me = this,
mixin = me.mixins.focusablecontainer,
child;
child = mixin.onFocusableContainerFocus.call(me, e);
if (child && child.isTab) {
me.doActivateTab(child);
}
},
onFocusableContainerFocusEnter: function(e) {
var me = this,
mixin = me.mixins.focusablecontainer,
child;
child = mixin.onFocusableContainerFocusEnter.call(me, e);
if (child && child.isTab) {
me.doActivateTab(child);
}
},
focusChild: function(child, forward) {
var me = this,
mixin = me.mixins.focusablecontainer,
nextChild;
nextChild = mixin.focusChild.call(me, child, forward);
if (me.activateOnFocus && nextChild && nextChild.isTab) {
me.doActivateTab(nextChild);
}
}
}
});
Ext.define('Ext.tab.Panel', {
extend: 'Ext.panel.Panel',
alias: 'widget.tabpanel',
alternateClassName: [
'Ext.TabPanel'
],
requires: [
'Ext.layout.container.Card',
'Ext.tab.Bar'
],
config: {
tabBar: undefined,
tabPosition: 'top',
tabRotation: 'default',
tabStretchMax: true
},
removePanelHeader: true,
plain: false,
itemCls: Ext.baseCSSPrefix + 'tabpanel-child',
minTabWidth: undefined,
maxTabWidth: undefined,
deferredRender: true,
_defaultTabRotation: {
top: 0,
right: 1,
bottom: 0,
left: 2
},
initComponent: function() {
var me = this,
activeTab = me.activeTab !== null ? (me.activeTab || 0) : null,
dockedItems = me.dockedItems,
header = me.header,
tabBarHeaderPosition = me.tabBarHeaderPosition,
tabBar = me.getTabBar(),
headerItems;
me.layout = new Ext.layout.container.Card(Ext.apply({
owner: me,
deferredRender: me.deferredRender,
itemCls: me.itemCls,
activeItem: activeTab
}, me.layout));
if (tabBarHeaderPosition != null) {
header = me.header = Ext.apply({}, header);
headerItems = header.items = (header.items ? header.items.slice() : []);
header.itemPosition = tabBarHeaderPosition;
headerItems.push(tabBar);
header.hasTabBar = true;
} else {
dockedItems = [].concat(me.dockedItems || []);
dockedItems.push(tabBar);
me.dockedItems = dockedItems;
}
me.callParent(arguments);
activeTab = me.activeTab = me.getComponent(activeTab);
if (activeTab) {
tabBar.setActiveTab(activeTab.tab, true);
}
},
onRender: function() {
var items = this.items.items,
len = items.length,
i;
this.callParent(arguments);
for (i = 0; i < len; ++i) {
items[i].getBind();
}
},
setActiveTab: function(card) {
var me = this,
previous;
if (!Ext.isObject(card) || card.isComponent) {
card = me.getComponent(card);
}
previous = me.getActiveTab();
if (card) {
Ext.suspendLayouts();
if (!card.isComponent) {
card = me.add(card);
}
if (previous === card || me.fireEvent('beforetabchange', me, card, previous) === false) {
Ext.resumeLayouts(true);
return previous;
}
me.activeTab = card;
me.layout.setActiveItem(card);
card = me.activeTab = me.layout.getActiveItem();
if (card && card !== previous) {
me.tabBar.setActiveTab(card.tab);
Ext.resumeLayouts(true);
if (previous !== card) {
me.fireEvent('tabchange', me, card, previous);
}
} else
{
Ext.resumeLayouts(true);
}
return card;
}
return previous;
},
setActiveItem: function(item) {
return this.setActiveTab(item);
},
getActiveTab: function() {
var me = this,
result = me.getComponent(me.activeTab);
if (result && me.items.indexOf(result) !== -1) {
me.activeTab = result;
} else {
me.activeTab = undefined;
}
return me.activeTab;
},
applyTabBar: function(tabBar) {
var me = this,
dock = (me.tabBarHeaderPosition != null) ? me.getHeaderPosition() : me.getTabPosition();
return new Ext.tab.Bar(Ext.apply({
ui: me.ui,
dock: dock,
tabRotation: me.getTabRotation(),
vertical: (dock === 'left' || dock === 'right'),
plain: me.plain,
tabStretchMax: me.getTabStretchMax(),
tabPanel: me
}, tabBar));
},
updateHeaderPosition: function(headerPosition, oldHeaderPosition) {
var tabBar = this.getTabBar();
if (tabBar && (this.tabBarHeaderPosition != null)) {
tabBar.setDock(headerPosition);
}
this.callParent([
headerPosition,
oldHeaderPosition
]);
},
updateTabPosition: function(tabPosition) {
var tabBar = this.getTabBar();
if (tabBar && (this.tabBarHeaderPosition == null)) {
tabBar.setDock(tabPosition);
}
},
updateTabRotation: function(tabRotation) {
var tabBar = this.getTabBar();
if (tabBar) {
tabBar.setTabRotation(tabRotation);
}
},
onAdd: function(item, index) {
var me = this,
cfg = Ext.apply({}, item.tabConfig),
tabBar = me.getTabBar(),
defaultConfig = {
xtype: 'tab',
title: item.title,
icon: item.icon,
iconCls: item.iconCls,
glyph: item.glyph,
ui: tabBar.ui,
card: item,
disabled: item.disabled,
closable: item.closable,
hidden: item.hidden && !item.hiddenByLayout,
tooltip: item.tooltip,
tabBar: tabBar,
tabPosition: tabBar.dock,
rotation: tabBar.getTabRotation()
};
if (item.closeText !== undefined) {
defaultConfig.closeText = item.closeText;
}
cfg = Ext.applyIf(cfg, defaultConfig);
item.tab = me.tabBar.insert(index, cfg);
item.on({
scope: me,
enable: me.onItemEnable,
disable: me.onItemDisable,
beforeshow: me.onItemBeforeShow,
iconchange: me.onItemIconChange,
iconclschange: me.onItemIconClsChange,
glyphchange: me.onItemGlyphChange,
titlechange: me.onItemTitleChange
});
if (item.isPanel) {
if (me.removePanelHeader) {
if (item.rendered) {
if (item.header) {
item.header.hide();
}
} else {
item.header = false;
}
}
if (item.isPanel && me.border) {
item.setBorder(false);
}
}
if (me.rendered) {
item.getBind();
}
if (me.rendered && me.loader && me.activeTab === undefined && me.layout.activeItem !== null) {
me.setActiveTab(0);
}
},
onMove: function(item, fromIdx, toIdx) {
var tabBar = this.getTabBar();
this.callParent([
item,
fromIdx,
toIdx
]);
if (tabBar.items.indexOf(item.tab) !== toIdx) {
tabBar.move(item.tab, toIdx);
}
},
onItemEnable: function(item) {
item.tab.enable();
},
onItemDisable: function(item) {
item.tab.disable();
},
onItemBeforeShow: function(item) {
if (item !== this.activeTab) {
this.setActiveTab(item);
return false;
}
},
onItemGlyphChange: function(item, newGlyph) {
item.tab.setGlyph(newGlyph);
},
onItemIconChange: function(item, newIcon) {
item.tab.setIcon(newIcon);
},
onItemIconClsChange: function(item, newIconCls) {
item.tab.setIconCls(newIconCls);
},
onItemTitleChange: function(item, newTitle) {
item.tab.setText(newTitle);
},
onRemove: function(item, destroying) {
var me = this;
item.un({
scope: me,
enable: me.onItemEnable,
disable: me.onItemDisable,
beforeshow: me.onItemBeforeShow,
iconchange: me.onItemIconChange,
iconclschange: me.onItemIconClsChange,
glyphchange: me.onItemGlyphChange,
titlechange: me.onItemTitleChange
});
if (item.tab && !me.destroying && item.tab.ownerCt === me.tabBar) {
me.tabBar.remove(item.tab);
}
},
privates: {
doRemove: function(item, autoDestroy) {
var me = this,
toActivate;
if (me.removingAll || me.destroying || me.items.getCount() === 1) {
me.activeTab = null;
}
else if (item.tab && (toActivate = me.tabBar.items.indexOf(me.tabBar.findNextActivatable(item.tab))) !== -1) {
me.setActiveTab(toActivate);
}
this.callParent(arguments);
if (item.tab) {
delete item.tab.card;
delete item.tab;
}
}
}
});
Ext.define('Ext.app.bindinspector.Environment', {
requires: [
'Ext.util.Collection'
],
getCmp: function(id) {
return this.components.get(id);
},
getVM: function(id) {
return this.viewModels.get(id);
},
getInheritedVM: function(comp) {
var vm = comp.viewModel,
parent = comp.parent;
if (vm) {
return vm;
}
if (parent) {
return this.getInheritedVM(this.getCmp(parent));
}
return null;
},
captureSnapshot: function() {
var all = Ext.ComponentManager.getAll(),
len = all.length,
components = [],
i, comp;
this.models = {};
for (i = 0; i < len; ++i) {
comp = all[i];
if (comp.afterRender && this.isRootComponent(comp)) {
components.push(this.buildComponent(comp));
}
}
return {
isBindData: true,
version: Ext.getVersion().version,
models: this.models,
components: components
};
},
serializeModel: function(Model) {
var models = this.models,
name = Model.entityName;
if (!models[name]) {
models[name] = Ext.Array.map(Model.getFields(), function(field) {
return {
name: field.getName(),
type: field.getType()
};
});
}
},
isRootComponent: function(c) {
var owner = c.getRefOwner();
if (owner || c.isBindInspector || c === Ext.MessageBox || c.is('quicktip')) {
return false;
}
return true;
},
buildComponent: function(comp) {
var childItems = comp.getRefItems ? comp.getRefItems() : null,
viewModel = comp.getViewModel(),
bind = comp.getBind(),
id = comp.id,
len, i, o, child;
if (bind) {
bind = this.buildBind(bind);
}
o = {
id: id,
xtype: comp.getXType(),
publishes: comp.getPublishes(),
viewModel: viewModel ? this.buildViewModel(viewModel, comp) : null,
bindings: bind || null,
reference: comp.reference || null,
items: []
};
if (childItems) {
for (i = 0 , len = childItems.length; i < len; ++i) {
if (childItems[i].afterRender) {
child = this.buildComponent(childItems[i]);
child.parent = id;
o.items.push(child);
}
}
}
return o;
},
buildBind: function(bind) {
var out = {},
key, o, bindInfo, name, stub;
for (key in bind) {
o = bind[key];
stub = o.stub;
bindInfo = {
id: o.id,
value: this.serializeValue(o.getRawValue()),
stub: stub ? {
id: stub.id,
name: stub.name
} : null
};
if (o.isTemplateBinding) {
bindInfo.isTemplateBinding = true;
bindInfo.tokens = [];
Ext.Array.forEach(o.tokens, function(token) {
bindInfo.tokens.push(token.split('.'));
}, this);
bindInfo.descriptor = o.tpl.text;
} else if (o.isMultiBinding) {
bindInfo.isMultiBinding = true;
} else
{
if (stub) {
name = this.buildStubName(stub);
bindInfo.tokens = name.split('.');
bindInfo.descriptor = '{' + name + '}';
}
}
out[key] = bindInfo;
}
return out;
},
buildStubName: function(stub) {
var parent = stub.parent,
name = '';
if (parent && !parent.isRootStub) {
name = this.buildStubName(parent) + '.';
}
return name + stub.name;
},
buildViewModel: function(vm, comp) {
var parent = vm.getParent();
return {
id: vm.getId(),
view: comp.id,
parent: parent ? parent.getId() : null,
data: this.serializeValue(vm.getData(), true),
rootStub: this.buildStub(vm.getRoot())
};
},
buildStub: function(stub, isLinkChild) {
var o = {},
children = stub.children,
isLink = stub.isLinkStub,
outChildren = {},
key, hasAny, child, sameTarget;
if (!stub.isRootStub) {
o.name = stub.name;
o.parent = stub.parent ? stub.parent.id : null;
o.isLoading = stub.isLoading();
o.bindCount = (stub.bindings && stub.bindings.length) || 0;
o.cumulativeBindCount = o.bindCount;
o.value = this.serializeValue(stub.getRawValue());
if (isLink) {
sameTarget = stub.target === stub.owner;
o.linkInfo = {
sameTarget: sameTarget,
descriptor: stub.linkDescriptor,
value: this.serializeValue(stub.binding.getValue())
};
isLinkChild = true;
}
} else {
o.name = '';
o.isLoading = false;
o.bindCount = o.cumulativeBindCount = 0;
}
if (children) {
for (key in children) {
hasAny = true;
child = this.buildStub(children[key], isLinkChild);
outChildren[key] = child;
o.cumulativeBindCount += child.cumulativeBindCount;
}
}
if (hasAny) {
o.children = outChildren;
}
return o;
},
createModel: function(entityName, data) {
var Model = Ext.app.bindinspector.noconflict[entityName];
return new Model(data);
},
unpackSnapshot: function(data) {
this.components = new Ext.util.Collection();
this.viewModels = new Ext.util.Collection();
Ext.Object.each(data.models, function(key, fields) {
Ext.define('Ext.app.bindinspector.noconflict.' + key, {
extend: 'Ext.app.bindinspector.noconflict.BaseModel',
fields: fields
});
});
Ext.Array.forEach(data.components, function(comp) {
this.unpackComponent(comp, this.components, this.viewModels);
}, this);
this.rootComponents = data.components;
},
unpackComponent: function(comp, allComponents, allViewModels) {
var vm = comp.viewModel,
items = comp.items,
bindings = comp.bindings,
len, i, parentVM, parentData, data, key, binding;
allComponents.add(comp);
if (bindings) {
for (key in bindings) {
binding = bindings[key];
binding.value = this.deserializeValue(binding.value);
}
}
if (vm) {
allViewModels.add(vm);
parentVM = this.getVM(vm.parent);
if (parentVM) {
parentData = Ext.Object.chain(parentVM.data);
}
data = this.deserializeValue(vm.data);
if (parentData) {
data = Ext.apply(parentData, data);
}
vm.data = data;
this.deserializeStub(vm.rootStub);
}
if (items) {
for (i = 0 , len = items.length; i < len; ++i) {
this.unpackComponent(items[i], allComponents, allViewModels);
}
}
},
serializeValue: function(value, checkHasOwn) {
var info = {},
type, key, item, childInfo, model;
if (value && value.constructor === Object) {
type = 'object';
info.value = {};
for (key in value) {
if (!(checkHasOwn && !value.hasOwnProperty(key))) {
childInfo = this.serializeValue(value[key], checkHasOwn);
item = {
type: childInfo.type,
value: childInfo.value
};
if (childInfo.entityName) {
item.entityName = childInfo.entityName;
}
info.value[key] = item;
}
}
} else if (value && value.isModel) {
type = 'model';
info.entityName = value.entityName;
this.serializeModel(value.self);
info.value = this.serializeValue(value.data);
} else if (value && value.isStore) {
type = 'store';
model = value.getModel();
info.entityName = model.entityName;
if (model.entityName) {
this.serializeModel(model);
}
} else if (Ext.isDate(value)) {
type = 'date';
info.value = Ext.Date.format(value, 'c');
} else if (Ext.isArray(value)) {
type = 'array';
info.value = [];
Ext.Array.forEach(value, function(item) {
info.value.push(this.serializeValue(item));
}, this);
} else {
type = Ext.typeOf(value);
info.value = value;
}
info.type = type;
return info;
},
deserializeValue: function(info) {
var type = info.type,
raw = info.value,
out, key;
if (type === 'null') {
out = null;
} else if (type === 'undefined') {
out = undefined;
} else if (type === 'string' || type === 'boolean' || type === 'number') {
out = raw;
} else if (type === 'date') {
out = Ext.Date.parse(raw, 'c');
} else if (type === 'object') {
out = {};
for (key in raw) {
out[key] = this.deserializeValue(raw[key]);
}
} else if (type === 'model') {
out = this.createModel(info.entityName, this.deserializeValue(raw));
} else if (type === 'store') {
out = {
isStore: true,
entityName: info.entityName
};
} else if (type === 'array') {
out = [];
Ext.Array.forEach(raw, function(item) {
out.push(this.deserializeValue(item));
}, this);
}
return out;
},
deserializeStub: function(stub) {
var children = stub.children,
linkInfo = stub.linkInfo,
key;
if (stub.value) {
stub.value = this.deserializeValue(stub.value);
}
if (linkInfo) {
linkInfo.value = this.deserializeValue(linkInfo.value);
}
if (children) {
for (key in children) {
this.deserializeStub(children[key]);
}
}
}
});
Ext.define('Ext.app.bindinspector.ViewModelDetail', {
extend: 'Ext.tree.Panel',
alias: 'widget.bindinspector-viewmodeldetail',
rootVisible: false,
cls: Ext.baseCSSPrefix + 'bindinspector-viewmodeldetail',
inheritedCls: Ext.baseCSSPrefix + 'bindinspector-inherited',
notInheritedCls: Ext.baseCSSPrefix + 'bindinspector-not-inherited',
highlightedCls: Ext.baseCSSPrefix + 'bindinspector-highlighted',
unhighlightedCls: Ext.baseCSSPrefix + 'bindinspector-unhighlighted',
lastItemCls: Ext.baseCSSPrefix + 'bindinspector-last-item',
initComponent: function() {
var me = this,
vm = me.vm,
title = 'VM &nbsp;&nbsp;&nbsp;⇒ &nbsp;&nbsp;&nbsp;',
env = me.up('bindinspector-container').env,
comp = env.getCmp(vm.view);
if (comp.reference) {
title += '[' + comp.reference + '] &bull; ';
}
me.title = title += comp.id;
me.viewConfig = {
getRowClass: function(record, index, rowParams, store) {
var data = record.get('hasData'),
stub = record.get('hasStub'),
cls = [],
highlighted = record.get('highlighted');
if (record.get('inherited')) {
cls.push(me.inheritedCls);
} else {
cls.push(me.notInheritedCls);
}
if (highlighted === true) {
cls.push(me.highlightedCls);
} else if (highlighted === -1) {
cls.push(me.unhighlightedCls);
}
if (index === store.getCount() - 1) {
cls.push(me.lastItemCls);
}
if (data && (!stub || record.get('cumulativeBindCount') === 0)) {
cls.push(me.dataOnlyCls);
}
return cls.join(' ');
}
};
me.store = {
model: me.Model,
root: {
text: 'Root',
expanded: true,
children: me.setupData(vm, vm.data, vm.rootStub)
}
};
me.columns = [
{
width: 40,
tdCls: Ext.baseCSSPrefix + 'bindinspector-indicator-col',
align: 'center',
scope: me,
renderer: me.renderIndicator
},
{
flex: 1,
xtype: 'treecolumn',
dataIndex: 'name',
text: 'Name',
scope: me,
renderer: me.renderName
},
{
flex: 1,
dataIndex: 'value',
text: 'Value',
scope: me,
renderer: Ext.app.bindinspector.Util.valueRenderer
},
{
text: 'Bind #',
width: 64,
align: 'center',
renderer: me.renderBindCount,
scope: me
},
{
width: 40,
isSearch: true,
renderer: me.dataSrcConsumerRenderer,
scope: me
}
];
me.callParent();
me.on('cellclick', me.onSearchCellClick, me);
},
dataOnlyNode: 'This item contains data but has nothing requesting the value',
stubOnlyNode: 'This item has the value requested but no data backing it',
dataPointLoading: 'Data point is loading (at the time the app snapshot was captured)',
dataPointLoadingCls: Ext.baseCSSPrefix + 'bindinspector-isloading',
zeroBindingCls: Ext.baseCSSPrefix + 'bi-zero-bind-count',
dataOnlyCls: Ext.baseCSSPrefix + 'bindinspector-data-only',
stubOnlyCls: Ext.baseCSSPrefix + 'bindinspector-stub-only',
onSearchCellClick: function(view, td, cellIndex, rec, tr, rowIndex, e) {
if (view.getHeaderCt().getHeaderAtIndex(cellIndex).isSearch) {
this.up('bindinspector-container').fireEvent('vmSearchClick', rec);
}
},
getFirstTierRec: function(rec) {
var isFirstTier = rec.parentNode.isRoot(),
firstTier;
if (!isFirstTier) {
rec.bubble(function(ni) {
if (ni.parentNode.isRoot()) {
firstTier = ni;
return false;
}
});
}
return isFirstTier ? rec : firstTier;
},
dataSrcConsumerRenderer: function(v, meta, rec) {
var firstTier = this.getFirstTierRec(rec),
firstTierName = firstTier.get('name');
meta.tdCls = Ext.baseCSSPrefix + 'bindinspector-data-search-cell';
meta.tdAttr = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="Click to indicate within the Component List all ViewModels with a data property of &nbsp;<b>' + firstTierName + '</b>"';
},
renderIndicator: function(v, meta, rec) {
var ownerVMs = rec.get('ownerVMs'),
len = ownerVMs.length,
direct = false,
inherited = false,
val = '',
firstTier = this.getFirstTierRec(rec),
isFirstTier = firstTier === rec,
firstTierName = firstTier.get('name'),
vmPlural;
Ext.Array.forEach(ownerVMs, function(vm) {
if (vm.id === vm.thisVM) {
direct = true;
}
if (vm.id !== vm.thisVM) {
inherited = true;
}
});
if (direct && inherited) {
val = Ext.util.Format.format('<span style="color:#DB7851;">{0}</span>', isFirstTier ? '◓' : '-');
vmPlural = len > 1 ? 'VMs' : 'VM';
meta.tdAttr = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="<b>' + firstTierName + '</b>&nbsp; provided by this VM and ' + (len - 1) + ' ancestor ' + vmPlural + '"';
} else if (direct) {
val = isFirstTier ? '●' : '';
meta.tdAttr = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="<b>' + firstTierName + '</b>&nbsp; is provided by this VM"';
} else if (inherited) {
val = isFirstTier ? '○' : '';
vmPlural = len > 1 ? 'VMs' : 'VM';
meta.tdAttr = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="<b>' + firstTierName + '</b>&nbsp; is provided by ' + len + ' ancestor ' + vmPlural + '"';
}
return val;
},
renderBindCount: function(v, meta, rec) {
var len = rec.get('children').length,
bindCount = rec.get('bindCount') || 0,
total, bindingsText;
v = bindCount;
if (v === 0) {
v = '<span class="' + this.zeroBindingCls + '">' + v + '</span>';
}
if (len) {
total = rec.get('cumulativeBindCount') || '?';
if (total === 0 || total === '?') {
v += ' / <span class="' + this.zeroBindingCls + '">' + total + '</span>';
} else {
v += ' / ' + total;
}
}
bindingsText = 'Bindings Count = <b>' + bindCount + '</b>';
if (total && total !== 0 && total !== '?') {
bindingsText += '<br>Cumulative Bindings Count = <b>' + total + '</b>';
}
meta.tdAttr = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="' + bindingsText + '"';
return v;
},
renderName: function(v, meta, rec) {
var me = this,
data = rec.get('hasData'),
stub = rec.get('hasStub'),
tip = '';
if (rec.get('isLoading')) {
meta.tdCls = me.dataPointLoadingCls;
tip += me.dataPointLoading;
} else if (data && (!stub || rec.get('cumulativeBindCount') === 0)) {
tip += me.dataOnlyNode;
} else if (stub && !data) {
meta.tdCls = me.stubOnlyCls;
tip += me.stubOnlyNode;
}
if (tip !== '') {
meta.tdAttr = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="' + tip + '"';
}
return v;
},
setupData: function(vm, data, stub, inherited, ownerVMs) {
var merged = {},
out = [],
dataMap = vm.dataMap,
dm = [],
item, children, stubChild, key, stopDigging, linkInfo;
if (data && Ext.isObject(data)) {
if (data.isModel) {
data = data.data;
stopDigging = true;
} else if (data.isStore) {
stopDigging = true;
data = null;
}
if (data) {
for (key in data) {
if (!ownerVMs) {
dm = dataMap[key] ? dataMap[key].ownerVMs : [];
}
item = {
name: key,
value: data[key],
inherited: Ext.isDefined(inherited) ? inherited : !data.hasOwnProperty(key),
ownerVMs: Ext.isDefined(ownerVMs) ? ownerVMs : [],
hasData: true
};
Ext.Array.forEach(dm, function(v) {
item.ownerVMs.push({
id: v.id,
view: v.view,
thisVM: vm.id
});
});
stubChild = Ext.app.bindinspector.Util.getChildStub(key, stub);
if (stubChild) {
item.hasStub = true;
item.isLoading = stubChild.isLoading;
item.iconCls = stubChild.isLoading ? this.dataPointLoadingCls : '';
item.bindCount = stubChild.bindCount;
item.cumulativeBindCount = stubChild.cumulativeBindCount;
item.stub = stubChild;
}
merged[key] = item;
}
}
}
if (stub) {
children = stub.children;
for (key in children) {
stubChild = children[key];
item = merged[key];
if (!item) {
item = {
name: key,
value: stubChild.value || undefined,
inherited: inherited || false,
ownerVMs: ownerVMs || [],
hasData: false,
hasStub: true,
isLoading: stubChild.isLoading,
iconCls: stubChild.isLoading ? this.dataPointLoadingCls : '',
bindCount: stubChild.bindCount,
cumulativeBindCount: stubChild.cumulativeBindCount,
stub: stubChild
};
linkInfo = stubChild.linkInfo;
if (linkInfo && linkInfo.sameTarget) {
item.value = linkInfo.value;
item.hasData = item.value !== undefined;
}
merged[key] = item;
}
}
}
for (key in merged) {
item = merged[key];
item.children = this.setupData(vm, item.value, item.stub, item.inherited, item.ownerVMs);
delete item.stub;
if (item.children && item.children.length) {
item.expanded = true;
item.leaf = false;
} else {
item.leaf = true;
}
out.push(merged[key]);
}
return out;
}
}, function() {
this.prototype.Model = Ext.define(null, {
extend: 'Ext.data.TreeModel',
fields: [
'name',
'value',
'inherited',
'hasData',
'hasStub',
'isLoading',
'bindCount',
'cumulativeBindCount',
'highlighted'
]
});
});
Ext.define('Ext.app.bindinspector.noconflict.BaseModel', {
extend: 'Ext.data.Model',
schema: {
id: 'Ext_app_bindinspector',
namespace: 'Ext.app.bindinspector'
}
});
Ext.define('Ext.app.bindinspector.Container', {
extend: 'Ext.container.Container',
alias: 'widget.bindinspector-container',
requires: [
'Ext.layout.container.Border',
'Ext.tab.Panel',
'Ext.app.bindinspector.ComponentDetail',
'Ext.app.bindinspector.ComponentList',
'Ext.app.bindinspector.Environment',
'Ext.app.bindinspector.Util',
'Ext.app.bindinspector.ViewModelDetail',
'Ext.app.bindinspector.noconflict.BaseModel'
],
isBindInspector: true,
referenceHolder: true,
layout: 'border',
cls: Ext.baseCSSPrefix + 'bindinspector-container',
componentPreviewDefault: {
xtype: 'container',
cls: Ext.baseCSSPrefix + 'bindinspector-prev-default',
padding: 20,
layout: {
type: 'hbox',
align: 'middle',
pack: 'center'
},
items: [
{
xtype: 'component',
flex: 1,
html: 'Select a component with bindings from the ComponentList to view the bindings details along with the component\'s inherited ViewModel'
}
]
},
initComponent: function() {
var me = this;
Ext.data.schema.Schema.get('Ext_app_bindinspector').clear();
me.items = [
{
xtype: 'bindinspector-componentlist',
reference: 'componentList',
region: 'west',
width: 400,
split: true,
collapsible: true,
components: me.env.rootComponents,
listeners: {
scope: me,
componentdblclick: me.onComponentDblclick,
componentselect: me.onComponentSelect
}
},
{
xtype: 'tabpanel',
region: 'center',
reference: 'tabs',
items: [
{
title: 'Preview',
reference: 'preview',
layout: 'fit',
items: [
me.componentPreviewDefault
]
}
],
listeners: {
add: function() {
this.getTabBar().setVisible(this.items.getCount() > 1);
},
remove: function() {
this.getTabBar().setVisible(this.items.getCount() > 1);
}
}
}
];
me.callParent();
me.on('vmSearchClick', me.onVMSearchClick, me);
},
onVMSearchClick: function(rec) {
var componentList = this.lookupReference('componentList'),
store = componentList.getStore(),
ownerVMs = rec.get('ownerVMs'),
sourceVMs = [],
bindCount = rec.get('bindCount'),
names = [],
consumerNodes = [],
query = [],
source, descriptor;
store.suspendEvents();
componentList.clearVMSearchIndicators();
Ext.Array.forEach(ownerVMs, function(vm) {
source = store.getById(vm.view);
source.set('isSrcVM', rec);
sourceVMs.push(source);
});
store.resumeEvents();
componentList.getView().refresh();
componentList.indicatedVM = sourceVMs;
if (bindCount > 0) {
rec.bubble(function(node) {
var nodeName = node.get('name');
if (nodeName) {
names.push(nodeName);
}
});
descriptor = names.reverse().join('.');
componentList.getStore().getRootNode().cascadeBy(function(node) {
if (node.get('hasBindings')) {
Ext.Array.forEach(node.get('bindData'), function(binding) {
var tokenStr = [];
if (binding.tokens) {
Ext.Array.forEach(binding.tokens, function(token) {
if (Ext.isArray(token)) {
Ext.Array.forEach(token, function(t) {
tokenStr.push(t);
});
} else {
tokenStr.push(token);
}
});
}
if (tokenStr.join('.') === descriptor) {
consumerNodes.push(node);
}
});
}
});
}
Ext.Array.forEach(consumerNodes.concat(sourceVMs), function(node) {
query.push(node.getId());
});
componentList.expand();
componentList.filterComponentTree(null, query);
Ext.Array.forEach(sourceVMs, function(src) {
if (!Ext.Array.contains(consumerNodes)) {
src.set('filtervisible', false);
}
});
componentList.down('#srcVMIndicator').show();
componentList.down('#queryFieldTb').hide();
componentList.down('#vmQueryResultsTb').show();
},
onComponentSelect: function(tree, rec, node) {
var me = this,
id = rec.getId(),
preview = me.lookupReference('preview');
if (preview.referringID !== id) {
Ext.suspendLayouts();
preview.removeAll();
preview.add({
xtype: 'bindinspector-componentdetail',
env: me.env,
component: me.env.getCmp(id)
});
Ext.resumeLayouts(true);
preview.referringID = id;
}
preview.show();
},
onComponentDblclick: function(tree, rec, node) {
var id = rec.id,
tabId = 'bindtab-' + id,
tabs = this.lookupReference('tabs'),
tab = tabs.items.get(tabId),
component, reference;
if (!tab) {
component = this.env.getCmp(id);
reference = component.reference;
tab = tabs.add({
xtype: 'bindinspector-componentdetail',
env: this.env,
itemId: tabId,
title: reference ? '[' + reference + '] ' + id : id,
closable: true,
component: component
});
}
tabs.setActiveTab(tab);
},
buildVMDataMap: function(vm) {
var env = this.env,
currVM = vm,
dataMap = vm.dataMap,
viewModels = [],
data, isDirect;
if (!dataMap) {
dataMap = vm.dataMap = {};
while (currVM) {
viewModels.push(currVM);
currVM = env.getVM(currVM.parent);
}
Ext.Array.forEach(viewModels, function(item) {
var key;
data = item.data;
if (data && Ext.isObject(data)) {
for (key in data) {
isDirect = data.hasOwnProperty(key);
if (!dataMap[key]) {
dataMap[key] = {
isDirect: isDirect
};
}
dataMap[key].ownerVMs = dataMap[key].ownerVMs || [];
if (isDirect) {
dataMap[key].ownerVMs.push(item);
}
}
}
});
}
return vm;
}
});
Ext.define('Ext.util.ComponentDragger', {
extend: 'Ext.dd.DragTracker',
autoStart: 500,
constructor: function(comp, config) {
this.comp = comp;
this.initialConstrainTo = config.constrainTo;
this.callParent([
config
]);
},
onStart: function(e) {
var me = this,
comp = me.comp;
me.startPosition = comp.getXY();
if (comp.ghost && !comp.liveDrag) {
me.proxy = comp.ghost();
me.dragTarget = me.proxy.header.el;
}
if (me.constrain || me.constrainDelegate) {
me.constrainTo = me.calculateConstrainRegion();
}
if (comp.beginDrag) {
comp.beginDrag();
}
},
calculateConstrainRegion: function() {
var me = this,
comp = me.comp,
constrainTo = me.initialConstrainTo,
constraintInsets = comp.constraintInsets,
constrainEl, delegateRegion, elRegion,
dragEl = me.proxy ? me.proxy.el : comp.el,
shadow = dragEl.shadow,
shadowSize = (shadow && !me.constrainDelegate && comp.constrainShadow && !shadow.disabled) ? shadow.getShadowSize() : 0;
if (!(constrainTo instanceof Ext.util.Region)) {
constrainEl = Ext.fly(constrainTo);
constrainTo = constrainEl.getConstrainRegion();
} else {
constrainTo = constrainTo.copy();
}
if (constraintInsets) {
constraintInsets = Ext.isObject(constraintInsets) ? constraintInsets : Ext.Element.parseBox(constraintInsets);
constrainTo.adjust(constraintInsets.top, constraintInsets.right, constraintInsets.bottom, constraintInsets.length);
}
if (shadowSize) {
constrainTo.adjust(shadowSize[0], -shadowSize[1], -shadowSize[2], shadowSize[3]);
}
if (!me.constrainDelegate) {
delegateRegion = Ext.fly(me.dragTarget).getRegion();
elRegion = dragEl.getRegion();
constrainTo.adjust(delegateRegion.top - elRegion.top, delegateRegion.right - elRegion.right, delegateRegion.bottom - elRegion.bottom, delegateRegion.left - elRegion.left);
}
return constrainTo;
},
onDrag: function(e) {
var me = this,
comp = (me.proxy && !me.comp.liveDrag) ? me.proxy : me.comp,
offset = me.getOffset(me.constrain || me.constrainDelegate ? 'dragTarget' : null);
comp.setPagePosition(me.startPosition[0] + offset[0], me.startPosition[1] + offset[1]);
},
onEnd: function(e) {
var comp = this.comp;
if (comp.isDestroyed || comp.destroying) {
return;
}
if (this.proxy && !comp.liveDrag) {
comp.unghost();
}
if (comp.endDrag) {
comp.endDrag();
}
}
});
Ext.define('Ext.window.Window', {
extend: 'Ext.panel.Panel',
alternateClassName: 'Ext.Window',
requires: [
'Ext.util.ComponentDragger',
'Ext.util.Region'
],
alias: 'widget.window',
baseCls: Ext.baseCSSPrefix + 'window',
resizable: true,
draggable: true,
constrain: false,
constrainHeader: false,
plain: false,
minimizable: false,
maximizable: false,
minHeight: 50,
minWidth: 50,
expandOnShow: true,
collapsible: false,
closable: true,
hidden: true,
autoRender: true,
hideMode: 'offsets',
floating: true,
itemCls: Ext.baseCSSPrefix + 'window-item',
overlapHeader: true,
ignoreHeaderBorderManagement: true,
alwaysFramed: true,
isRootCfg: {
isRoot: true
},
isWindow: true,
ariaRole: 'dialog',
initComponent: function() {
var me = this;
me.frame = false;
me.callParent();
if (me.plain) {
me.addClsWithUI('plain');
}
me.addStateEvents([
'maximize',
'restore',
'resize',
'dragend'
]);
},
getElConfig: function() {
var me = this,
elConfig;
elConfig = me.callParent();
elConfig.tabIndex = -1;
return elConfig;
},
getFocusEl: function() {
var me = this;
return Ext.enableFocusManager ? me.el : (me.getDefaultFocus() || me.el);
},
getState: function() {
var me = this,
state = me.callParent() || {},
maximized = !!me.maximized,
ghostBox = me.ghostBox,
pos;
state.maximized = maximized;
if (maximized) {
pos = me.restorePos;
} else if (ghostBox) {
pos = [
ghostBox.x,
ghostBox.y
];
} else {
pos = me.getPosition();
}
Ext.apply(state, {
size: maximized ? me.restoreSize : me.getSize(),
pos: pos
});
return state;
},
applyState: function(state) {
var me = this;
if (state) {
me.maximized = state.maximized;
if (me.maximized) {
me.hasSavedRestore = true;
me.restoreSize = state.size;
me.restorePos = state.pos;
} else {
Ext.apply(me, {
width: state.size.width,
height: state.size.height,
x: state.pos[0],
y: state.pos[1]
});
}
}
},
onRender: function(ct, position) {
var me = this;
me.callParent(arguments);
if (me.header) {
me.header.on({
scope: me,
click: me.onHeaderClick
});
}
if (me.maximizable) {
me.header.on({
scope: me,
dblclick: me.toggleMaximize
});
}
},
afterRender: function() {
var me = this,
header = me.header,
keyMap;
if (me.maximized) {
me.maximized = false;
me.maximize();
if (header) {
header.removeCls(header.indicateDragCls);
}
}
me.callParent();
if (me.closable) {
keyMap = me.getKeyMap();
keyMap.on(27, me.onEsc, me);
} else {
keyMap = me.keyMap;
}
if (keyMap && me.hidden) {
keyMap.disable();
}
},
onEsc: function(k, e) {
var mgr = Ext['FocusManager'];
if (!Ext.enableFocusManager || mgr.focusedCmp === this) {
e.stopEvent();
this.close();
}
},
beforeDestroy: function() {
var me = this;
if (me.rendered) {
Ext.un('resize', me.onWindowResize, me);
delete me.animateTarget;
me.hide();
Ext.destroy(me.keyMap);
}
me.callParent();
},
addTools: function() {
var me = this,
tools = [];
me.callParent();
if (me.minimizable) {
tools.push({
type: 'minimize',
handler: 'minimize',
scope: me
});
}
if (me.maximizable) {
tools.push({
type: me.maximized ? 'restore' : 'maximize',
handler: 'toggleMaximize',
scope: me
});
}
if (tools.length) {
me.addTool(tools);
}
},
onShow: function() {
var me = this;
me.callParent(arguments);
if (me.expandOnShow) {
me.expand(false);
}
me.syncMonitorWindowResize();
if (me.keyMap) {
me.keyMap.enable();
}
},
doClose: function() {
var me = this;
if (me.hidden) {
me.fireEvent('close', me);
if (me.closeAction === 'destroy') {
me.destroy();
}
} else {
me.hide(me.animateTarget, me.doClose, me);
}
},
afterHide: function() {
var me = this;
me.syncMonitorWindowResize();
if (me.keyMap) {
me.keyMap.disable();
}
me.callParent(arguments);
},
onWindowResize: function() {
var me = this,
sizeModel;
if (!me.isDestroyed) {
if (me.maximized) {
me.fitContainer();
} else {
sizeModel = me.getSizeModel();
if (sizeModel.width.natural || sizeModel.height.natural) {
me.updateLayout();
}
me.doConstrain();
}
}
},
minimize: function() {
this.fireEvent('minimize', this);
return this;
},
resumeHeaderLayout: function(changed) {
this.header.resumeLayouts(changed ? this.isRootCfg : null);
},
afterCollapse: function() {
var me = this,
header = me.header,
tools = me.tools;
if (header && me.maximizable) {
header.suspendLayouts();
tools.maximize.hide();
this.resumeHeaderLayout(true);
}
if (me.resizer) {
me.resizer.disable();
}
me.callParent(arguments);
},
afterExpand: function() {
var me = this,
header = me.header,
tools = me.tools,
changed;
if (header) {
header.suspendLayouts();
if (me.maximizable) {
tools.maximize.show();
changed = true;
}
this.resumeHeaderLayout(changed);
}
if (me.resizer) {
me.resizer.enable();
}
me.callParent(arguments);
},
maximize: function(animate) {
var me = this,
header = me.header,
tools = me.tools,
width = me.width,
height = me.height,
restore, changed;
if (!me.maximized) {
me.expand(false);
if (!me.hasSavedRestore) {
restore = me.restoreSize = {
width: width ? width : null,
height: height ? height : null
};
me.restorePos = me.getPosition();
}
if (header) {
header.suspendLayouts();
if (tools.maximize) {
tools.maximize.setType('restore');
}
if (me.collapseTool) {
me.collapseTool.hide();
changed = true;
}
me.resumeHeaderLayout(changed);
}
me.el.disableShadow();
if (me.dd) {
me.dd.disable();
if (header) {
header.removeCls(header.indicateDragCls);
}
}
if (me.resizer) {
me.resizer.disable();
}
me.el.addCls(Ext.baseCSSPrefix + 'window-maximized');
me.container.addCls(Ext.baseCSSPrefix + 'window-maximized-ct');
me.syncMonitorWindowResize();
me.fitContainer(animate = (animate || !!me.animateTarget) ? {
callback: function() {
me.maximized = true;
me.fireEvent('maximize', me);
}
} : null);
if (!animate) {
me.maximized = true;
me.fireEvent('maximize', me);
}
}
return me;
},
restore: function(animate) {
var me = this,
tools = me.tools,
header = me.header,
newBox = me.restoreSize,
changed;
if (me.maximized) {
me.hasSavedRestore = null;
me.removeCls(Ext.baseCSSPrefix + 'window-maximized');
if (header) {
header.suspendLayouts();
if (tools.maximize) {
tools.maximize.setType('maximize');
}
if (me.collapseTool) {
me.collapseTool.show();
changed = true;
}
me.resumeHeaderLayout(changed);
}
newBox.x = me.restorePos[0];
newBox.y = me.restorePos[1];
me.setBox(newBox, animate = (animate || !!me.animateTarget) ? {
callback: function() {
me.el.enableShadow(null, true);
me.maximized = false;
me.fireEvent('restore', me);
}
} : null);
me.restorePos = me.restoreSize = null;
if (me.dd) {
me.dd.enable();
if (header) {
header.addCls(header.indicateDragCls);
}
}
if (me.resizer) {
me.resizer.enable();
}
me.container.removeCls(Ext.baseCSSPrefix + 'window-maximized-ct');
me.syncMonitorWindowResize();
if (!animate) {
me.el.enableShadow(null, true);
me.maximized = false;
me.fireEvent('restore', me);
}
}
return me;
},
syncMonitorWindowResize: function() {
var me = this,
currentlyMonitoring = me._monitoringResize,
yes = me.monitorResize || me.constrain || me.constrainHeader || me.maximized,
veto = me.hidden || me.destroying || me.isDestroyed;
if (yes && !veto) {
if (!currentlyMonitoring) {
Ext.on('resize', me.onWindowResize, me, {
buffer: 1
});
me._monitoringResize = true;
}
} else if (currentlyMonitoring) {
Ext.un('resize', me.onWindowResize, me);
me._monitoringResize = false;
}
},
toggleMaximize: function() {
return this[this.maximized ? 'restore' : 'maximize']();
},
createGhost: function() {
var ghost = this.callParent(arguments);
ghost.xtype = 'window';
return ghost;
},
getDefaultFocus: function() {
var me = this,
result,
defaultComp = me.defaultButton || me.defaultFocus,
selector;
if (defaultComp !== undefined) {
if (Ext.isNumber(defaultComp)) {
result = me.query('button')[defaultComp];
}
else if (Ext.isString(defaultComp)) {
selector = defaultComp;
if (Ext.validIdRe.test(selector)) {
result = me.down(Ext.makeIdSelector(selector));
}
if (!result) {
result = me.down(selector);
}
}
else if (defaultComp.focus) {
result = defaultComp;
}
}
return result;
},
privates: {
initDraggable: function() {
this.initSimpleDraggable();
},
onHeaderClick: function(header, e) {
var delegate;
if (header.el.contains(e.getTarget())) {
delegate = this.getDefaultFocus();
if (delegate) {
delegate.focus();
}
}
},
initResizable: function() {
this.callParent(arguments);
if (this.maximized) {
this.resizer.disable();
}
}
}
});
Ext.define('Ext.tip.Tip', {
extend: 'Ext.panel.Panel',
alias: 'widget.tip',
alternateClassName: 'Ext.Tip',
minWidth: 40,
maxWidth: 500,
shadow: "sides",
defaultAlign: "tl-bl?",
constrainPosition: true,
autoRender: true,
hidden: true,
baseCls: Ext.baseCSSPrefix + 'tip',
focusOnToFront: false,
closeAction: 'hide',
alwaysFramed: true,
frameHeader: false,
initComponent: function() {
var me = this;
me.floating = Ext.apply({}, {
shadow: me.shadow,
constrain: me.constrainPosition
}, me.self.prototype.floating);
me.callParent(arguments);
me.constrain = me.constrain || me.constrainPosition;
},
showAt: function(xy) {
var me = this;
this.callParent(arguments);
if (me.isVisible()) {
me.setPagePosition(xy[0], xy[1]);
if (me.constrainPosition || me.constrain) {
me.doConstrain();
}
me.toFront(true);
}
},
privates: {
initDraggable: function() {
var me = this;
me.draggable = {
el: me.getDragEl(),
delegate: me.header.el,
constrain: me,
constrainTo: me.el.dom.parentNode
};
Ext.Component.prototype.initDraggable.call(me);
}
},
ghost: undefined,
unghost: undefined
});
Ext.define('Ext.tip.ToolTip', {
extend: 'Ext.tip.Tip',
alias: 'widget.tooltip',
alternateClassName: 'Ext.ToolTip',
autoHide: true,
showDelay: 500,
hideDelay: 200,
dismissDelay: 5000,
trackMouse: false,
anchorToTarget: true,
anchorOffset: 0,
targetCounter: 0,
quickShowInterval: 250,
hideAction: 'hide',
fadeOutDuration: 1000,
ariaRole: 'tooltip',
initComponent: function() {
var me = this;
me.callParent(arguments);
me.lastActive = new Date();
me.setTarget(me.target);
me.origAnchor = me.anchor;
},
onRender: function(ct, position) {
var me = this;
me.callParent(arguments);
me.anchorCls = Ext.baseCSSPrefix + 'tip-anchor-' + me.getAnchorPosition();
if (me.sticky) {
me.el.dom.setAttribute('data-sticky', true);
}
me.anchorEl = me.el.createChild({
role: 'presentation',
cls: Ext.baseCSSPrefix + 'tip-anchor ' + me.anchorCls
});
},
setTarget: function(target) {
var me = this,
t = Ext.get(target),
tg;
if (me.target) {
tg = Ext.get(me.target);
if (Ext.supports.Touch) {
me.mun(tg, 'tap', me.onTargetOver, me);
} else {
me.mun(tg, {
mouseover: me.onTargetOver,
mouseout: me.onTargetOut,
mousemove: me.onMouseMove,
scope: me
});
}
}
me.target = t;
if (t) {
if (Ext.supports.Touch) {
me.mon(t, {
tap: me.onTargetOver,
scope: me
});
} else {
me.mon(t, {
mouseover: me.onTargetOver,
mouseout: me.onTargetOut,
mousemove: me.onMouseMove,
scope: me
});
}
}
if (me.anchor) {
me.anchorTarget = me.target;
}
},
onMouseMove: function(e) {
var me = this,
t, xy;
if (!me.target || me.target.contains(e.target)) {
t = me.delegate ? e.getTarget(me.delegate) : (me.triggerElement = true);
if (t) {
me.targetXY = e.getXY();
if (t === me.triggerElement) {
if (!me.hidden && me.trackMouse) {
xy = me.getTargetXY();
if (me.constrainPosition) {
xy = me.el.adjustForConstraints(xy, me.el.parent());
}
me.setPagePosition(xy);
}
} else {
me.hide();
me.lastActive = new Date(0);
me.onTargetOver(e);
}
} else if ((!me.closable && me.isVisible()) && me.autoHide !== false) {
me.delayHide();
}
}
},
getTargetXY: function() {
var me = this,
mouseOffset, offsets, xy, dw, dh, de, bd, scrollX, scrollY, axy, sz, constrainPosition;
if (me.delegate) {
me.anchorTarget = me.triggerElement;
}
if (me.anchor) {
me.targetCounter++;
offsets = me.getOffsets();
xy = (me.anchorToTarget && !me.trackMouse) ? me.getAlignToXY(me.anchorTarget, me.getAnchorAlign()) : me.targetXY;
dw = Ext.Element.getViewportWidth() - 5;
dh = Ext.Element.getViewportHeight() - 5;
de = document.documentElement;
bd = document.body;
scrollX = (de.scrollLeft || bd.scrollLeft || 0) + 5;
scrollY = (de.scrollTop || bd.scrollTop || 0) + 5;
axy = [
xy[0] + offsets[0],
xy[1] + offsets[1]
];
sz = me.getSize();
constrainPosition = me.constrainPosition;
me.anchorEl.removeCls(me.anchorCls);
if (me.targetCounter < 2 && constrainPosition) {
if (axy[0] < scrollX) {
if (me.anchorToTarget) {
me.defaultAlign = 'l-r';
if (me.mouseOffset) {
me.mouseOffset[0] *= -1;
}
}
me.anchor = 'left';
return me.getTargetXY();
}
if (axy[0] + sz.width > dw) {
if (me.anchorToTarget) {
me.defaultAlign = 'r-l';
if (me.mouseOffset) {
me.mouseOffset[0] *= -1;
}
}
me.anchor = 'right';
return me.getTargetXY();
}
if (axy[1] < scrollY) {
if (me.anchorToTarget) {
me.defaultAlign = 't-b';
if (me.mouseOffset) {
me.mouseOffset[1] *= -1;
}
}
me.anchor = 'top';
return me.getTargetXY();
}
if (axy[1] + sz.height > dh) {
if (me.anchorToTarget) {
me.defaultAlign = 'b-t';
if (me.mouseOffset) {
me.mouseOffset[1] *= -1;
}
}
me.anchor = 'bottom';
return me.getTargetXY();
}
}
me.anchorCls = Ext.baseCSSPrefix + 'tip-anchor-' + me.getAnchorPosition();
me.anchorEl.addCls(me.anchorCls);
me.targetCounter = 0;
return axy;
} else {
mouseOffset = me.getMouseOffset();
return (me.targetXY) ? [
me.targetXY[0] + mouseOffset[0],
me.targetXY[1] + mouseOffset[1]
] : mouseOffset;
}
},
calculateConstrainedPosition: function(constrainTo) {
var me = this,
visible, result, floatParentBox;
if (!constrainTo && me.isContainedFloater()) {
visible = me.isVisible();
if (!visible) {
me.el.show();
}
result = me.getTargetXY();
if (!visible) {
me.el.hide();
}
floatParentBox = me.floatParent.getTargetEl().getViewRegion();
result[0] -= floatParentBox.left;
result[1] -= floatParentBox.top;
} else {
result = me.callOverridden(arguments);
}
return result;
},
getMouseOffset: function() {
var me = this,
offset = me.anchor ? [
0,
0
] : [
15,
18
];
if (me.mouseOffset) {
offset[0] += me.mouseOffset[0];
offset[1] += me.mouseOffset[1];
}
return offset;
},
fadeOut: function() {
var me = this;
me.el.fadeOut({
duration: me.fadeOutDuration,
callback: function() {
me.hide();
me.el.setOpacity('');
}
});
},
getAnchorPosition: function() {
var me = this,
m;
if (me.anchor) {
me.tipAnchor = me.anchor.charAt(0);
} else {
m = me.defaultAlign.match(/^([a-z]+)-([a-z]+)(\?)?$/);
if (!m) {
Ext.Error.raise('The AnchorTip.defaultAlign value "' + me.defaultAlign + '" is invalid.');
}
me.tipAnchor = m[1].charAt(0);
}
switch (me.tipAnchor) {
case 't':
return 'top';
case 'b':
return 'bottom';
case 'r':
return 'right';
}
return 'left';
},
getAnchorAlign: function() {
switch (this.anchor) {
case 'top':
return 'tl-bl';
case 'left':
return 'tl-tr';
case 'right':
return 'tr-tl';
default:
return 'bl-tl';
}
},
getOffsets: function() {
var me = this,
mouseOffset, offsets,
ap = me.getAnchorPosition().charAt(0);
if (me.anchorToTarget && !me.trackMouse) {
switch (ap) {
case 't':
offsets = [
0,
9
];
break;
case 'b':
offsets = [
0,
-13
];
break;
case 'r':
offsets = [
-13,
0
];
break;
default:
offsets = [
9,
0
];
break;
}
} else {
switch (ap) {
case 't':
offsets = [
-15 - me.anchorOffset,
30
];
break;
case 'b':
offsets = [
-19 - me.anchorOffset,
-13 - me.el.dom.offsetHeight
];
break;
case 'r':
offsets = [
-15 - me.el.dom.offsetWidth,
-13 - me.anchorOffset
];
break;
default:
offsets = [
25,
-13 - me.anchorOffset
];
break;
}
}
mouseOffset = me.getMouseOffset();
offsets[0] += mouseOffset[0];
offsets[1] += mouseOffset[1];
return offsets;
},
onTargetOver: function(e) {
var me = this,
delegate = me.delegate,
t;
if (me.disabled || e.within(me.target.dom, true)) {
return;
}
t = delegate ? e.getTarget(delegate) : true;
if (t) {
me.triggerElement = t;
me.triggerEvent = e;
me.clearTimer('hide');
me.targetXY = e.getXY();
me.delayShow();
}
},
delayShow: function(trackMouse) {
var me = this,
xy = me.el && (trackMouse === false || !me.trackMouse) && me.getTargetXY();
if (me.hidden && !me.showTimer) {
if (Ext.Date.getElapsed(me.lastActive) < me.quickShowInterval) {
me.show();
} else {
me.showTimer = Ext.defer(me.showFromDelay, me.showDelay, me, [
xy
]);
}
} else if (!me.hidden && me.autoHide !== false) {
me.show(xy);
}
},
showFromDelay: function(xy) {
var me = this;
if (me.disabled) {
return;
}
me.fromDelayShow = true;
me.show(xy);
delete me.fromDelayShow;
},
onShowVeto: function() {
this.callParent();
delete this.triggerElement;
this.clearTimer('show');
},
onTargetOut: function(e) {
var me = this,
triggerEl = me.triggerElement,
target = triggerEl === true ? me.target : triggerEl;
if (me.disabled || !triggerEl || e.within(target, true)) {
return;
}
if (me.showTimer) {
me.clearTimer('show');
me.triggerElement = null;
}
if (me.autoHide !== false) {
me.delayHide();
}
},
delayHide: function() {
var me = this;
if (!me.hidden && !me.hideTimer) {
me.hideTimer = Ext.defer(me[me.hideAction], me.hideDelay, me);
}
},
hide: function() {
var me = this;
me.clearTimer('dismiss');
me.lastActive = new Date();
if (me.anchorEl) {
me.anchorEl.hide();
}
me.callParent(arguments);
delete me.triggerElement;
},
show: function(xy) {
var me = this;
this.callParent();
if (this.hidden === false) {
if (me.anchor) {
me.anchor = me.origAnchor;
}
if (!me.calledFromShowAt) {
me.showAt(xy || me.getTargetXY());
}
}
},
showAt: function(xy) {
var me = this;
me.lastActive = new Date();
me.clearTimers();
me.calledFromShowAt = true;
if (!me.isVisible()) {
this.callParent(arguments);
}
if (me.isVisible()) {
me.setPagePosition(xy[0], xy[1]);
if (me.constrainPosition || me.constrain) {
me.doConstrain();
}
me.toFront(true);
me.el.syncUnderlays();
if (me.dismissDelay && me.autoHide !== false) {
me.dismissTimer = Ext.defer(me.hide, me.dismissDelay, me);
}
}
delete me.calledFromShowAt;
},
syncAnchor: function() {
var me = this,
anchorPos, targetPos, offset;
switch (me.tipAnchor.charAt(0)) {
case 't':
anchorPos = 'b';
targetPos = 'tl';
offset = [
20 + me.anchorOffset,
1
];
break;
case 'r':
anchorPos = 'l';
targetPos = 'tr';
offset = [
-1,
12 + me.anchorOffset
];
break;
case 'b':
anchorPos = 't';
targetPos = 'bl';
offset = [
20 + me.anchorOffset,
-1
];
break;
default:
anchorPos = 'r';
targetPos = 'tl';
offset = [
1,
12 + me.anchorOffset
];
break;
}
me.anchorEl.alignTo(me.el, anchorPos + '-' + targetPos, offset);
me.anchorEl.setStyle('z-index', parseInt(me.el.getZIndex(), 10) || 0 + 1).setVisibilityMode(Ext.Element.DISPLAY);
},
afterSetPosition: function(x, y) {
var me = this;
me.callParent(arguments);
if (me.anchor) {
me.syncAnchor();
if (!me.anchorEl.isVisible()) {
me.anchorEl.show();
}
} else {
me.anchorEl.hide();
}
},
_timerNames: {},
clearTimer: function(name) {
var me = this,
names = me._timerNames,
propName = names[name] || (names[name] = name + 'Timer'),
timer = me[propName];
if (timer) {
clearTimeout(timer);
me[propName] = null;
}
},
clearTimers: function() {
var me = this;
me.clearTimer('show');
me.clearTimer('dismiss');
me.clearTimer('hide');
},
onShow: function() {
var me = this;
me.callParent();
me.mon(Ext.getDoc(), 'mousedown', me.onDocMouseDown, me);
},
onHide: function() {
var me = this;
me.callParent();
me.mun(Ext.getDoc(), 'mousedown', me.onDocMouseDown, me);
},
onDocMouseDown: function(e) {
var me = this;
if (!me.closable && !e.within(me.el.dom)) {
me.disable();
Ext.defer(me.doEnable, 100, me);
}
},
doEnable: function() {
if (!this.isDestroyed) {
this.enable();
}
},
onDisable: function() {
this.callParent();
this.clearTimers();
this.hide();
},
beforeDestroy: function() {
var me = this;
me.clearTimers();
Ext.destroy(me.anchorEl);
delete me.anchorEl;
delete me.target;
delete me.anchorTarget;
delete me.triggerElement;
me.callParent();
},
onDestroy: function() {
Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
this.callParent();
}
});
Ext.define('Ext.tip.QuickTip', {
extend: 'Ext.tip.ToolTip',
alias: 'widget.quicktip',
alternateClassName: 'Ext.QuickTip',
interceptTitles: false,
title: '&#160;',
tagConfig: {
namespace: 'data-',
attribute: 'qtip',
width: 'qwidth',
target: 'target',
title: 'qtitle',
hide: 'hide',
cls: 'qclass',
align: 'qalign',
anchor: 'anchor',
showDelay: 'qshowDelay',
hideAction: 'hideAction',
anchorTarget: 'anchorTarget'
},
shrinkWrapDock: true,
initComponent: function() {
var me = this;
me.target = me.target || Ext.getDoc();
me.targets = me.targets || {};
me.callParent();
},
setTagConfig: function(cfg) {
this.tagConfig = Ext.apply({}, cfg);
delete this.tagConfig.attr;
},
text: null,
register: function(config) {
var configs = Ext.isArray(config) ? config : arguments,
i = 0,
len = configs.length,
target, j, targetLen;
for (; i < len; i++) {
config = configs[i];
target = config.target;
if (target) {
if (Ext.isArray(target)) {
for (j = 0 , targetLen = target.length; j < targetLen; j++) {
this.targets[Ext.id(target[j])] = config;
}
} else {
this.targets[Ext.id(target)] = config;
}
}
}
},
unregister: function(el) {
delete this.targets[Ext.id(el)];
},
cancelShow: function(el) {
var me = this,
activeTarget = me.activeTarget;
el = Ext.get(el).dom;
if (me.isVisible()) {
if (activeTarget && activeTarget.el === el) {
me.hide();
}
} else if (activeTarget && activeTarget.el === el) {
me.clearTimer('show');
}
},
getTipCfg: function(target, event) {
var titleText = target.title,
cfg = this.tagConfig,
attr = cfg.attr || (cfg.attr = cfg.namespace + cfg.attribute),
text;
if (this.interceptTitles && titleText && Ext.isString(titleText)) {
target.setAttribute(attr, titleText);
target.removeAttribute('title');
return {
text: titleText
};
} else {
target = Ext.fly(target).findParent(function(dom) {
return (text = dom.getAttribute(attr));
});
if (target) {
return {
target: target,
text: text
};
}
}
},
onTargetOver: function(event) {
this.doTargetOver(event.getTarget(this.delegate), null, event);
},
doTargetOver: function(target, xy, event) {
var me = this,
hasShowDelay, hideAction, delay, elTarget, cfg, ns, tipConfig, autoHide, targets, targetEl, value, key;
if (me.disabled) {
return;
}
if (typeof target === 'string') {
target = Ext.getDom(target);
}
me.targetXY = xy || (event ? event.getXY() : Ext.fly(target).getXY());
if (!target || target.nodeType !== 1 || target === document.documentElement || target === document.body) {
return;
}
if (me.activeTarget && ((target === me.activeTarget.el) || Ext.fly(me.activeTarget.el).contains(target))) {
if (me.targetTextEmpty()) {
me.onShowVeto();
delete me.activeTarget;
} else {
me.clearTimer('hide');
me.show();
}
return;
}
if (target) {
targets = me.targets;
for (key in targets) {
if (targets.hasOwnProperty(key)) {
value = targets[key];
targetEl = Ext.fly(value.target);
if (targetEl && (targetEl.dom === target || targetEl.contains(target))) {
elTarget = targetEl.dom;
break;
}
}
}
if (elTarget) {
me.activeTarget = me.targets[elTarget.id];
me.activeTarget.el = target;
me.anchor = me.activeTarget.anchor;
if (me.anchor) {
me.anchorTarget = target;
}
hasShowDelay = parseInt(me.activeTarget.showDelay, 10);
if (hasShowDelay) {
delay = me.showDelay;
me.showDelay = hasShowDelay;
}
me.delayShow();
if (hasShowDelay) {
me.showDelay = delay;
}
if (!(hideAction = me.activeTarget.hideAction)) {
delete me.hideAction;
} else {
me.hideAction = hideAction;
}
return;
}
}
elTarget = Ext.fly(target, '_quicktip-target');
cfg = me.tagConfig;
ns = cfg.namespace;
tipConfig = me.getTipCfg(target, event);
if (tipConfig) {
if (tipConfig.target) {
target = tipConfig.target;
elTarget = Ext.fly(target, '_quicktip-target');
}
autoHide = elTarget.getAttribute(ns + cfg.hide);
me.activeTarget = {
el: target,
text: tipConfig.text,
width: +elTarget.getAttribute(ns + cfg.width) || null,
autoHide: autoHide !== "user" && autoHide !== 'false',
title: elTarget.getAttribute(ns + cfg.title),
cls: elTarget.getAttribute(ns + cfg.cls),
align: elTarget.getAttribute(ns + cfg.align),
showDelay: parseInt(elTarget.getAttribute(ns + cfg.showDelay) || 0, 10),
hideAction: elTarget.getAttribute(ns + cfg.hideAction),
anchorTarget: elTarget.getAttribute(ns + cfg.anchorTarget)
};
if (!me.initialConfig.hasOwnProperty('anchor')) {
me.anchor = elTarget.getAttribute(ns + cfg.anchor);
}
if (me.anchor && !me.initialConfig.hasOwnProperty('anchorTarget')) {
me.anchorTarget = me.activeTarget.anchorTarget || target;
}
hasShowDelay = parseInt(me.activeTarget.showDelay, 10);
if (hasShowDelay) {
delay = me.showDelay;
me.showDelay = hasShowDelay;
}
me.delayShow();
if (hasShowDelay) {
me.showDelay = delay;
}
}
},
onTargetOut: function(e) {
var me = this,
active = me.activeTarget,
hasHideDelay, delay;
if (active && e.within(me.activeTarget.el) && !me.getTipCfg(e.getTarget(), e)) {
return;
}
me.clearTimer('show');
delete me.activeTarget;
if (me.autoHide !== false) {
hasHideDelay = active && parseInt(active.hideDelay, 10);
if (hasHideDelay) {
delay = me.hideDelay;
me.hideDelay = hasHideDelay;
}
me.delayHide();
if (hasHideDelay) {
me.hideDelay = delay;
}
}
},
targetTextEmpty: function() {
var me = this,
target = me.activeTarget,
cfg = me.tagConfig,
el, text;
if (target) {
el = target.el;
if (el) {
text = el.getAttribute(cfg.namespace + cfg.attribute);
if (!text && !me.targets[Ext.id(target.target)]) {
return true;
}
}
}
return false;
},
show: function() {
var me = this,
fromDelay = me.fromDelayShow;
if (fromDelay && me.targetTextEmpty()) {
me.onShowVeto();
delete me.activeTarget;
return;
}
me.callParent(arguments);
},
showAt: function(xy) {
var me = this,
target = me.activeTarget,
header = me.header,
dismiss, cls;
if (target) {
if (!me.rendered) {
me.render(Ext.getBody());
me.activeTarget = target;
}
me.suspendLayouts();
if (target.title) {
me.setTitle(target.title);
header.show();
} else if (header) {
header.hide();
}
me.update(target.text);
me.autoHide = target.autoHide;
dismiss = target.dismissDelay;
me.dismissDelay = Ext.isNumber(dismiss) ? dismiss : me.dismissDelay;
if (target.mouseOffset) {
xy[0] += target.mouseOffset[0];
xy[1] += target.mouseOffset[1];
}
cls = me.lastCls;
if (cls) {
me.removeCls(cls);
delete me.lastCls;
}
cls = target.cls;
if (cls) {
me.addCls(cls);
me.lastCls = cls;
}
me.setWidth(target.width);
if (me.anchor) {
me.constrainPosition = false;
} else if (target.align) {
xy = me.getAlignToXY(target.el, target.align);
me.constrainPosition = false;
} else {
me.constrainPosition = true;
}
me.resumeLayouts(true);
}
me.callParent([
xy
]);
},
hide: function() {
delete this.activeTarget;
this.callParent();
}
});
Ext.define('Ext.tip.QuickTipManager', {
requires: [
'Ext.tip.QuickTip'
],
singleton: true,
alternateClassName: 'Ext.QuickTips',
disabled: false,
init: function(autoRender, config) {
var me = this;
if (!me.tip) {
if (!Ext.isReady) {
Ext.onInternalReady(function() {
Ext.tip.QuickTipManager.init(autoRender, config);
});
return false;
}
var tipConfig = Ext.apply({
sticky: true,
disabled: me.disabled,
id: 'ext-quicktips-tip'
}, config),
className = tipConfig.className,
xtype = tipConfig.xtype;
if (className) {
delete tipConfig.className;
} else if (xtype) {
className = 'widget.' + xtype;
delete tipConfig.xtype;
}
if (autoRender !== false) {
tipConfig.renderTo = document.body;
if (tipConfig.renderTo.tagName.toUpperCase() !== 'BODY') {
Ext.Error.raise({
sourceClass: 'Ext.tip.QuickTipManager',
sourceMethod: 'init',
msg: 'Cannot init QuickTipManager: no document body'
});
}
}
me.tip = Ext.create(className || 'Ext.tip.QuickTip', tipConfig);
Ext.quickTipsActive = true;
}
},
destroy: function() {
Ext.destroy(this.tip);
this.tip = undefined;
},
ddDisable: function() {
var me = this,
tip = me.tip;
if (tip && !me.disabled) {
tip.disable();
}
},
ddEnable: function() {
var me = this,
tip = me.tip;
if (tip && !me.disabled) {
tip.enable();
}
},
enable: function() {
var me = this,
tip = me.tip;
if (tip) {
tip.enable();
}
me.disabled = false;
},
disable: function() {
var me = this,
tip = me.tip;
if (tip) {
tip.disable();
}
me.disabled = true;
},
isEnabled: function() {
var tip = this.tip;
return tip !== undefined && !tip.disabled;
},
getQuickTip: function() {
return this.tip;
},
register: function() {
var tip = this.tip;
tip.register.apply(tip, arguments);
},
unregister: function() {
var tip = this.tip;
tip.unregister.apply(tip, arguments);
},
tips: function() {
var tip = this.tip;
tip.register.apply(tip, arguments);
}
});
Ext.define('Ext.app.bindinspector.Inspector', {
extend: 'Ext.window.Window',
requires: [
'Ext.app.bindinspector.Container',
'Ext.layout.container.Fit',
'Ext.tip.QuickTipManager'
],
title: 'Bind Inspector',
layout: 'fit',
autoShow: true,
maximized: true,
maximizable: true,
width: 960,
height: 575,
initComponent: function() {
var snapshot = (new Ext.app.bindinspector.Environment()).captureSnapshot(),
env = new Ext.app.bindinspector.Environment();
env.unpackSnapshot(snapshot);
this.items = {
xtype: 'bindinspector-container',
env: env
};
this.callParent();
},
afterRender: function() {
this.callParent(arguments);
Ext.tip.QuickTipManager.init();
}
});
Ext.define('Ext.button.Split', {
alias: 'widget.splitbutton',
extend: 'Ext.button.Button',
alternateClassName: 'Ext.SplitButton',
isSplitButton: true,
arrowCls: 'split',
split: true,
setArrowHandler: function(handler, scope) {
this.arrowHandler = handler;
this.scope = scope;
},
onClick: function(e) {
var me = this;
me.doPreventDefault(e);
if (!me.disabled) {
if (me.isWithinTrigger(e)) {
e.preventDefault();
me.maybeShowMenu(e);
me.fireEvent("arrowclick", me, e);
if (me.arrowHandler) {
me.arrowHandler.call(me.scope || me, me, e);
}
} else {
me.doToggle();
me.fireHandler(e);
}
}
}
});
Ext.define('Ext.button.Cycle', {
alias: 'widget.cycle',
extend: 'Ext.button.Split',
alternateClassName: 'Ext.CycleButton',
getButtonText: function(item) {
var me = this,
text = '';
if (item && me.showText === true) {
if (me.prependText) {
text += me.prependText;
}
text += item.text;
return text;
}
return me.text;
},
setActiveItem: function(item, suppressEvent) {
var me = this,
changeHandler = me.changeHandler,
forceIcon = me.forceIcon,
forceGlyph = me.forceGlyph;
me.settingActive = true;
if (!Ext.isObject(item)) {
item = me.menu.getComponent(item);
}
if (item) {
me.setText(me.getButtonText(item));
me.setIconCls(forceIcon ? forceIcon : item.iconCls);
me.setGlyph(forceGlyph ? forceGlyph : item.glyph);
me.activeItem = item;
if (!item.checked) {
item.setChecked(true, false);
}
if (!suppressEvent) {
if (changeHandler) {
Ext.callback(changeHandler, me.scope, [
me,
item
], 0, me);
}
me.fireEvent('change', me, item);
}
}
me.settingActive = false;
},
getActiveItem: function() {
return this.activeItem;
},
initComponent: function() {
var me = this,
checked = 0,
items, i, iLen, item;
items = (me.menu.items || []).concat(me.items || []);
me.menu = Ext.applyIf({
cls: Ext.baseCSSPrefix + 'cycle-menu',
items: []
}, me.menu);
iLen = items.length;
for (i = 0; i < iLen; i++) {
item = items[i];
item = Ext.applyIf({
group: me.id,
itemIndex: i,
checkHandler: me.checkHandler,
scope: me,
checked: item.checked || false
}, item);
me.menu.items.push(item);
if (item.checked) {
checked = i;
}
}
me.itemCount = me.menu.items.length;
me.callParent(arguments);
me.on('click', me.toggleSelected, me);
me.setActiveItem(checked, true);
},
checkHandler: function(item, pressed) {
if (pressed && !this.settingActive) {
this.setActiveItem(item);
}
},
toggleSelected: function() {
var me = this,
m = me.menu,
checkItem;
checkItem = me.activeItem.next(':not([disabled])') || m.items.getAt(0);
checkItem.setChecked(true);
}
});
Ext.define('Ext.button.Segmented', {
extend: 'Ext.container.Container',
xtype: 'segmentedbutton',
requires: [
'Ext.button.Button'
],
config: {
allowDepress: false,
allowMultiple: false,
allowToggle: true,
vertical: false,
defaultUI: 'default'
},
beforeRenderConfig: {
value: undefined
},
defaultBindProperty: 'value',
publishes: [
'value'
],
twoWayBindable: [
'value'
],
layout: 'segmentedbutton',
defaultType: 'button',
maskOnDisable: false,
isSegmentedButton: true,
baseCls: Ext.baseCSSPrefix + 'segmented-button',
itemCls: Ext.baseCSSPrefix + 'segmented-button-item',
_firstCls: Ext.baseCSSPrefix + 'segmented-button-first',
_lastCls: Ext.baseCSSPrefix + 'segmented-button-last',
_middleCls: Ext.baseCSSPrefix + 'segmented-button-middle',
applyValue: function(value, oldValue) {
var me = this,
allowMultiple = me.getAllowMultiple(),
buttonValue, button, values, oldValues, items, i, ln;
values = (value instanceof Array) ? value : (value == null) ? [] : [
value
];
oldValues = (oldValue instanceof Array) ? oldValue : (oldValue == null) ? [] : [
oldValue
];
me._isApplyingValue = true;
if (!me.rendered) {
items = me.items.items;
for (i = 0 , ln = items.length; i < ln; i++) {
button = items[i];
if (button.pressed) {
buttonValue = button.value;
if (buttonValue == null) {
buttonValue = me.items.indexOf(button);
}
if (!Ext.Array.contains(values, buttonValue)) {
values.push(buttonValue);
}
}
}
}
ln = values.length;
if (ln > 1 && !allowMultiple) {
Ext.Error.raise('Cannot set multiple values when allowMultiple is false');
}
for (i = 0; i < ln; i++) {
value = values[i];
button = me._lookupButtonByValue(value);
if (button) {
buttonValue = button.value;
if ((buttonValue != null) && buttonValue !== value) {
values[i] = buttonValue;
}
if (!button.pressed) {
button.setPressed(true);
}
} else {
Ext.Error.raise("Invalid value '" + value + "' for segmented button: '" + me.id + "'");
}
}
value = allowMultiple ? values : ln ? values[0] : null;
for (i = 0 , ln = oldValues.length; i < ln; i++) {
oldValue = oldValues[i];
if (!Ext.Array.contains(values, oldValue)) {
me._lookupButtonByValue(oldValue).setPressed(false);
}
}
me._isApplyingValue = false;
return value;
},
beforeRender: function() {
var me = this;
me.addCls(me.baseCls + me._getClsSuffix());
me._syncItemClasses(true);
me.callParent();
},
onAdd: function(item) {
var me = this,
syncItemClasses = '_syncItemClasses';
var items = me.items.items,
ln = items.length,
i = 0,
value, defaultUI;
if (item.ui === 'default' && !item.hasOwnProperty('ui')) {
defaultUI = me.getDefaultUI();
if (defaultUI !== 'default') {
item.ui = defaultUI;
}
}
for (; i < ln; i++) {
if (items[i] !== item) {
value = items[i].value;
if (value != null && value === item.value) {
Ext.Error.raise("Segmented button '" + me.id + "' cannot contain multiple items with value: '" + value + "'");
}
}
}
me.mon(item, {
hide: syncItemClasses,
show: syncItemClasses,
toggle: '_onItemToggle',
scope: me
});
if (me.getAllowToggle()) {
item.enableToggle = true;
if (!me.getAllowMultiple()) {
item.toggleGroup = me.getId();
item.allowDepress = me.getAllowDepress();
}
}
item.addCls(me.itemCls + me._getClsSuffix());
me._syncItemClasses();
me.callParent([
item
]);
},
onRemove: function(item) {
var me = this;
item.removeCls(me.itemCls + me._getClsSuffix());
me._syncItemClasses();
me.callParent([
item
]);
},
beforeLayout: function() {
if (Ext.isChrome) {
this.el.dom.offsetWidth;
}
this.callParent();
},
updateDefaultUI: function(defaultUI) {
var items = this.items,
item, i, ln;
if (this.rendered) {
Ext.Error.raise("Changing the ui config of a segmented button after render is not supported.");
} else if (items) {
if (items.items) {
items = items.items;
}
for (i = 0 , ln = items.length; i < ln; i++) {
item = items[i];
if (item.ui === 'default' && defaultUI !== 'default' && !item.hasOwnProperty('ui')) {
items[i].ui = defaultUI;
}
}
}
},
updateAllowDepress: function(newAllowDepress, oldAllowDepress) {
if (this.rendered && (newAllowDepress !== oldAllowDepress)) {
Ext.Error.raise("Changing the allowDepress config of a segmented button after render is not supported.");
}
},
updateAllowMultiple: function(newAllowMultiple, oldAllowMultiple) {
if (this.rendered && (newAllowMultiple !== oldAllowMultiple)) {
Ext.Error.raise("Changing the allowMultiple config of a segmented button after render is not supported.");
}
},
updateAllowToggle: function(newAllowToggle, oldAllowToggle) {
if (this.rendered && (newAllowToggle !== oldAllowToggle)) {
Ext.Error.raise("Changing the allowToggle config of a segmented button after render is not supported.");
}
},
updateVertical: function(newVertical, oldVertical) {
if (this.rendered && (newVertical !== oldVertical)) {
Ext.Error.raise("Changing the orientation of a segmented button after render is not supported.");
}
},
privates: {
_getClsSuffix: function() {
return this.getVertical() ? '-vertical' : '-horizontal';
},
_getFirstCls: function() {
return this._firstCls;
},
_getLastCls: function() {
return this._lastCls;
},
_lookupButtonByValue: function(value) {
var items = this.items.items,
ln = items.length,
i = 0,
button = null,
buttonValue, btn;
for (; i < ln; i++) {
btn = items[i];
buttonValue = btn.value;
if ((buttonValue != null) && buttonValue === value) {
button = btn;
break;
}
}
if (!button && typeof value === 'number') {
button = items[value];
}
return button;
},
_onItemToggle: function(button, pressed) {
if (this._isApplyingValue) {
return;
}
var me = this,
Array = Ext.Array,
allowMultiple = me.allowMultiple,
buttonValue = (button.value != null) ? button.value : me.items.indexOf(button),
value = me.getValue(),
valueIndex;
if (allowMultiple) {
valueIndex = Array.indexOf(value, buttonValue);
}
if (pressed) {
if (allowMultiple) {
if (valueIndex === -1) {
value.push(buttonValue);
}
} else {
value = buttonValue;
}
} else {
if (allowMultiple) {
if (valueIndex > -1) {
value.splice(valueIndex, 1);
}
} else if (value === buttonValue) {
value = null;
}
}
me.setValue(value);
me.fireEvent('toggle', me, button, pressed);
},
_syncItemClasses: function(force) {
var me = this,
firstCls, middleCls, lastCls, items, ln, visibleItems, item, i;
if (!force && !me.rendered) {
return;
}
firstCls = me._getFirstCls();
middleCls = me._middleCls;
lastCls = me._getLastCls();
items = me.items.items;
ln = items.length;
visibleItems = [];
for (i = 0; i < ln; i++) {
item = items[i];
if (!item.hidden) {
visibleItems.push(item);
}
}
ln = visibleItems.length;
for (i = 0; i < ln; i++) {
visibleItems[i].removeCls([
firstCls,
middleCls,
lastCls
]);
}
if (ln > 1) {
visibleItems[0].addCls(firstCls);
for (i = 1; i < ln - 1; i++) {
visibleItems[i].addCls(middleCls);
}
visibleItems[ln - 1].addCls(lastCls);
}
}
}
});
Ext.define('Ext.layout.container.Table', {
alias: [
'layout.table'
],
extend: 'Ext.layout.container.Container',
alternateClassName: 'Ext.layout.TableLayout',
type: 'table',
createsInnerCt: true,
targetCls: Ext.baseCSSPrefix + 'table-layout-ct',
tableCls: Ext.baseCSSPrefix + 'table-layout',
cellCls: Ext.baseCSSPrefix + 'table-layout-cell',
childEls: [
'table',
'tbody'
],
tableAttrs: null,
getItemSizePolicy: function(item) {
return this.autoSizePolicy;
},
initInheritedState: function(inheritedState, inheritedStateInner) {
inheritedStateInner.inShrinkWrapTable = true;
},
getLayoutItems: function() {
var me = this,
result = [],
items = me.callParent(),
item,
len = items.length,
i;
for (i = 0; i < len; i++) {
item = items[i];
if (!item.hidden) {
result.push(item);
}
}
return result;
},
getHiddenItems: function() {
var result = [],
items = this.owner.items.items,
len = items.length,
i = 0,
item;
for (; i < len; ++i) {
item = items[i];
if (item.rendered && item.hidden) {
result.push(item);
}
}
return result;
},
renderChildren: function() {
var me = this,
items = me.getLayoutItems(),
tbody = me.tbody.dom,
rows = tbody.rows,
len = items.length,
hiddenItems = me.getHiddenItems(),
cells, curCell, rowIdx, cellIdx, item, trEl, tdEl, i, cellId, oldId;
cells = me.calculateCells(items);
for (i = 0; i < len; i++) {
curCell = cells[i];
rowIdx = curCell.rowIdx;
cellIdx = curCell.cellIdx;
item = items[i];
cellId = item.cellId || '';
trEl = rows[rowIdx];
if (!trEl) {
trEl = tbody.insertRow(rowIdx);
if (me.trAttrs) {
trEl.set(me.trAttrs);
}
}
tdEl = Ext.get(trEl.cells[cellIdx] || trEl.insertCell(cellIdx));
if (!item.rendered) {
me.renderItem(item, tdEl, 0);
} else if (!me.isValidParent(item, tdEl, rowIdx, cellIdx, tbody)) {
me.moveItem(item, tdEl, 0);
}
if (me.tdAttrs) {
tdEl.set(me.tdAttrs);
}
if (item.tdAttrs) {
tdEl.set(item.tdAttrs);
}
oldId = tdEl.getAttribute('data-cellId');
if ((oldId || cellId) && oldId !== cellId) {
tdEl.setId(cellId || Ext.id());
}
tdEl.set({
colSpan: item.colspan || 1,
rowSpan: item.rowspan || 1,
'data-cellId': cellId,
cls: me.cellCls + ' ' + (item.cellCls || '')
});
if (!cells[i + 1] || cells[i + 1].rowIdx !== rowIdx) {
cellIdx++;
while (trEl.cells[cellIdx]) {
trEl.deleteCell(cellIdx);
}
}
}
rowIdx++;
while (tbody.rows[rowIdx]) {
tbody.deleteRow(rowIdx);
}
for (i = 0 , len = hiddenItems.length; i < len; ++i) {
me.ensureInDocument(hiddenItems[i].getEl());
}
},
ensureInDocument: function(el) {
var dom = el.dom.parentNode;
while (dom) {
if (dom.tagName.toUpperCase() === 'BODY') {
return;
}
dom = dom.parentNode;
}
Ext.getDetachedBody().appendChild(el);
},
calculate: function(ownerContext) {
if (!ownerContext.hasDomProp('containerChildrenSizeDone')) {
this.done = false;
} else {
var targetContext = ownerContext.targetContext,
widthShrinkWrap = ownerContext.widthModel.shrinkWrap,
heightShrinkWrap = ownerContext.heightModel.shrinkWrap,
shrinkWrap = heightShrinkWrap || widthShrinkWrap,
table = shrinkWrap && this.table.dom,
targetPadding = shrinkWrap && targetContext.getPaddingInfo();
if (widthShrinkWrap) {
ownerContext.setContentWidth(table.offsetWidth + targetPadding.width, true);
}
if (heightShrinkWrap) {
ownerContext.setContentHeight(table.offsetHeight + targetPadding.height, true);
}
}
},
calculateCells: function(items) {
var cells = [],
rowIdx = 0,
colIdx = 0,
cellIdx = 0,
totalCols = this.columns || Infinity,
rowspans = [],
i = 0,
j,
len = items.length,
item;
for (; i < len; i++) {
item = items[i];
while (colIdx >= totalCols || rowspans[colIdx] > 0) {
if (colIdx >= totalCols) {
colIdx = 0;
cellIdx = 0;
rowIdx++;
for (j = 0; j < totalCols; j++) {
if (rowspans[j] > 0) {
rowspans[j]--;
}
}
} else {
colIdx++;
}
}
cells.push({
rowIdx: rowIdx,
cellIdx: cellIdx
});
for (j = item.colspan || 1; j; --j) {
rowspans[colIdx] = item.rowspan || 1;
++colIdx;
}
++cellIdx;
}
return cells;
},
getRenderTree: function() {
var me = this,
items = me.getLayoutItems(),
rows = [],
result = Ext.apply({
tag: 'table',
id: me.owner.id + '-table',
"data-ref": 'table',
role: 'presentation',
cls: me.tableCls,
cellspacing: 0,
cellpadding: 0,
cn: {
tag: 'tbody',
id: me.owner.id + '-tbody',
"data-ref": 'tbody',
role: 'presentation',
cn: rows
}
}, me.tableAttrs),
tdAttrs = me.tdAttrs,
len = items.length,
i, cells, item, curCell, tr, rowIdx, cellIdx, cell, cellId, props;
cells = me.calculateCells(items);
for (i = 0; i < len; i++) {
item = items[i];
curCell = cells[i];
rowIdx = curCell.rowIdx;
cellIdx = curCell.cellIdx;
cellId = item.cellId || '';
tr = rows[rowIdx];
if (!tr) {
tr = rows[rowIdx] = {
tag: 'tr',
role: 'presentation',
cn: []
};
if (me.trAttrs) {
Ext.apply(tr, me.trAttrs);
}
}
cell = tr.cn[cellIdx] = {
tag: 'td',
role: 'presentation'
};
if (tdAttrs) {
Ext.apply(cell, tdAttrs);
}
props = {
colSpan: item.colspan || 1,
rowSpan: item.rowspan || 1,
'data-cellId': cellId,
cls: me.cellCls + ' ' + (item.cellCls || '')
};
if (cellId) {
props.id = cellId;
}
Ext.apply(cell, props);
me.configureItem(item);
cell.cn = item.getRenderTree();
}
return result;
},
isValidParent: function(item, target, rowIdx, cellIdx) {
if (arguments.length === 3) {
return this.table.isAncestor(item.el);
}
return item.el.dom.parentNode === this.tbody.dom.rows[rowIdx].cells[cellIdx];
}
});
Ext.define('Ext.container.ButtonGroup', {
extend: 'Ext.panel.Panel',
alias: 'widget.buttongroup',
alternateClassName: 'Ext.ButtonGroup',
requires: [
'Ext.layout.container.Table'
],
baseCls: Ext.baseCSSPrefix + 'btn-group',
layout: {
type: 'table'
},
defaultType: 'button',
frame: true,
frameHeader: false,
titleAlign: 'center',
noTitleCls: 'notitle',
ariaRole: 'group',
initComponent: function() {
var me = this,
cols = me.columns;
if (cols) {
me.layout = Ext.apply({}, {
columns: cols
}, me.layout);
}
if (!me.title) {
me.addClsWithUI(me.noTitleCls);
}
me.callParent(arguments);
},
onBeforeAdd: function(component) {
if (component.isButton) {
if (this.defaultButtonUI && component.ui === 'default' && !component.hasOwnProperty('ui')) {
component.ui = this.defaultButtonUI;
} else {
component.ui = component.ui + '-toolbar';
}
}
this.callParent(arguments);
},
privates: {
applyDefaults: function(c) {
if (!Ext.isString(c)) {
c = this.callParent(arguments);
}
return c;
}
}
});
Ext.define('Ext.container.Monitor', {
target: null,
selector: '',
scope: null,
addHandler: null,
removeHandler: null,
invalidateHandler: null,
disabled: 0,
constructor: function(config) {
Ext.apply(this, config);
},
bind: function(target) {
var me = this;
me.target = target;
target.on('beforedestroy', me.disable, me);
me.onContainerAdd(target);
},
unbind: function() {
var me = this,
target = me.target;
if (target) {
target.un('beforedestroy', me.disable, me);
}
me.items = null;
},
disable: function() {
++this.disabled;
},
enable: function() {
if (this.disabled > 0) {
--this.disabled;
}
},
handleAdd: function(ct, comp) {
if (!this.disabled) {
if (comp.is(this.selector)) {
this.onItemAdd(comp.ownerCt, comp);
}
if (comp.isQueryable) {
this.onContainerAdd(comp);
}
}
},
onItemAdd: function(ct, comp) {
var me = this,
items = me.items,
handler = me.addHandler;
if (!me.disabled) {
if (handler) {
handler.call(me.scope || comp, comp);
}
if (items) {
items.add(comp);
}
}
},
onItemRemove: function(ct, comp) {
var me = this,
items = me.items,
handler = me.removeHandler;
if (!me.disabled) {
if (handler) {
handler.call(me.scope || comp, comp);
}
if (items) {
items.remove(comp);
}
}
},
onContainerAdd: function(ct, preventChildren) {
var me = this,
items, len,
handleAdd = me.handleAdd,
handleRemove = me.handleRemove,
i, comp;
if (ct.isContainer) {
ct.on('add', handleAdd, me);
ct.on('dockedadd', handleAdd, me);
ct.on('remove', handleRemove, me);
ct.on('dockedremove', handleRemove, me);
}
if (preventChildren !== true) {
items = ct.query(me.selector);
for (i = 0 , len = items.length; i < len; ++i) {
comp = items[i];
me.onItemAdd(comp.ownerCt, comp);
}
}
items = ct.query('>container');
for (i = 0 , len = items.length; i < len; ++i) {
me.onContainerAdd(items[i], true);
}
},
handleRemove: function(ct, comp) {
var me = this;
if (!me.disabled) {
if (comp.is(me.selector)) {
me.onItemRemove(ct, comp);
}
if (comp.isQueryable) {
me.onContainerRemove(ct, comp);
}
}
},
onContainerRemove: function(ct, comp) {
var me = this,
items, i, len, item;
if (!comp.isDestroyed && !comp.destroying && comp.isContainer) {
me.removeCtListeners(comp);
items = comp.query(me.selector);
for (i = 0 , len = items.length; i < len; ++i) {
item = items[i];
me.onItemRemove(item.ownerCt, item);
}
items = comp.query('container');
for (i = 0 , len = items.length; i < len; ++i) {
me.removeCtListeners(items[i]);
}
} else {
me.invalidateItems(true);
}
},
removeCtListeners: function(comp) {
var me = this;
comp.un('add', me.handleAdd, me);
comp.un('dockedadd', me.handleAdd, me);
comp.un('remove', me.handleRemove, me);
comp.un('dockedremove', me.handleRemove, me);
},
getItems: function() {
var me = this,
items = me.items;
if (!items) {
items = me.items = new Ext.util.MixedCollection();
items.addAll(me.target.query(me.selector));
}
return items;
},
invalidateItems: function(triggerHandler) {
var me = this,
handler = me.invalidateHandler;
if (triggerHandler && handler) {
handler.call(me.scope || me, me);
}
me.items = null;
}
});
Ext.define('Ext.plugin.Responsive', {
extend: 'Ext.mixin.Responsive',
alias: 'plugin.responsive',
pluginId: 'responsive',
isPlugin: true,
constructor: function(config) {
var me = this,
cmp = config.cmp,
c = Ext.apply({
responsiveConfig: cmp.responsiveConfig,
responsiveFormulas: cmp.responsiveFormulas
}, config);
delete c.cmp;
me.cmp = cmp;
if (!cmp) {
Ext.Error.raise('Responsive plugin must be constructed by Component');
}
me.initConfig(c);
if (me.transformed) {
cmp.setConfig(me.transformed);
me.transformed = null;
}
},
init: Ext.emptyFn,
privates: {
transformInstanceConfig: function(config) {
var transformed = this.callParent([
config
]);
if (transformed.ptype) {
transformed = Ext.apply({}, transformed);
delete transformed.ptype;
}
this.transformed = transformed;
var ret = Ext.apply({}, config);
delete ret.ptype;
delete ret.responsiveConfig;
delete ret.responsiveFormulas;
return ret;
},
updateResponsiveState: function() {
var config = this.getResponsiveState();
this.cmp.setConfig(config);
}
}
});
Ext.define('Ext.plugin.Viewport', {
extend: 'Ext.plugin.Responsive',
alias: 'plugin.viewport',
setCmp: function(cmp) {
this.cmp = cmp;
if (cmp && !cmp.isViewport) {
this.decorate(cmp);
if (cmp.renderConfigs) {
cmp.flushRenderConfigs();
}
cmp.setupViewport();
}
},
statics: {
decorate: function(target) {
Ext.applyIf(target.prototype || target, {
ariaRole: 'application',
viewportCls: Ext.baseCSSPrefix + 'viewport'
});
Ext.override(target, {
isViewport: true,
preserveElOnDestroy: true,
initComponent: function() {
this.callParent();
this.setupViewport();
},
getSizeModel: function() {
var configured = Ext.layout.SizeModel.configured;
return configured.pairsByHeightOrdinal[configured.ordinal];
},
handleViewportResize: function() {
var me = this,
Element = Ext.dom.Element,
width = Element.getViewportWidth(),
height = Element.getViewportHeight();
if (width !== me.width || height !== me.height) {
me.setSize(width, height);
}
},
setupViewport: function() {
var me = this,
el = document.body;
if (!el.id) {
el.id = me.id;
}
el.setAttribute(Ext.Component.componentIdAttribute, me.id);
el = me.el = Ext.getBody();
Ext.fly(document.documentElement).addCls(me.viewportCls);
el.setHeight = el.setWidth = Ext.emptyFn;
el.dom.scroll = 'no';
me.allowDomMove = false;
me.renderTo = el;
if (Ext.supports.Touch) {
me.addMeta('apple-mobile-web-app-capable', 'yes');
}
Ext.getScrollbarSize();
me.width = me.height = undefined;
me.initialViewportHeight = Ext.Element.getViewportHeight();
me.initialViewportWidth = Ext.Element.getViewportWidth();
},
afterLayout: function(layout) {
if (Ext.supports.Touch) {
document.body.scrollTop = 0;
}
this.callParent([
layout
]);
},
onRender: function() {
var me = this;
me.callParent(arguments);
me.width = me.initialViewportWidth;
me.height = me.initialViewportHeight;
me.initialViewportWidth = me.initialViewportHeight = null;
if (Ext.supports.TouchEvents) {
me.mon(Ext.getDoc(), {
touchmove: function(e) {
e.preventDefault();
},
translate: false,
delegated: false
});
}
},
initInheritedState: function(inheritedState, inheritedStateInner) {
var me = this,
root = Ext.rootInheritedState;
if (inheritedState !== root) {
me.initInheritedState(me.inheritedState = root, me.inheritedStateInner = Ext.Object.chain(root));
} else {
me.callParent([
inheritedState,
inheritedStateInner
]);
}
},
beforeDestroy: function() {
var me = this,
root = Ext.rootInheritedState,
key;
for (key in root) {
if (key !== 'rtl') {
delete root[key];
}
}
me.removeUIFromElement();
me.el.removeCls(me.baseCls);
Ext.fly(document.body.parentNode).removeCls(me.viewportCls);
me.callParent();
},
addMeta: function(name, content) {
var meta = document.createElement('meta');
meta.setAttribute('name', name);
meta.setAttribute('content', content);
Ext.getHead().appendChild(meta);
},
privates: {
applyTargetCls: function(targetCls) {
this.el.addCls(targetCls);
},
disableTabbing: function() {
var el = this.el;
if (el) {
el.saveChildrenTabbableState();
}
},
enableTabbing: function() {
var el = this.el;
if (el) {
el.restoreChildrenTabbableState();
}
},
getOverflowEl: function() {
return Ext.get(document.documentElement);
}
}
});
}
},
privates: {
updateResponsiveState: function() {
this.cmp.handleViewportResize();
this.callParent();
}
}
}, function(Viewport) {
Viewport.prototype.decorate = Viewport.decorate;
});
Ext.define('Ext.container.Viewport', {
extend: 'Ext.container.Container',
requires: [
'Ext.plugin.Viewport'
],
mixins: [
'Ext.mixin.Responsive'
],
alias: 'widget.viewport',
alternateClassName: 'Ext.Viewport',
privates: {
updateResponsiveState: function() {
this.handleViewportResize();
this.mixins.responsive.updateResponsiveState.call(this);
}
}
}, function() {
Ext.plugin.Viewport.decorate(this);
});
Ext.define('Ext.layout.container.Anchor', {
alias: 'layout.anchor',
extend: 'Ext.layout.container.Auto',
alternateClassName: 'Ext.layout.AnchorLayout',
type: 'anchor',
defaultAnchor: '100%',
parseAnchorRE: /^(r|right|b|bottom)$/i,
manageOverflow: true,
setsItemSize: true,
beginLayoutCycle: function(ownerContext) {
var me = this,
dimensions = 0,
anchorSpec, childContext, childItems, i, length;
me.callParent(arguments);
childItems = ownerContext.childItems;
length = childItems.length;
for (i = 0; i < length; ++i) {
childContext = childItems[i];
anchorSpec = childContext.target.anchorSpec;
if (anchorSpec) {
if (childContext.widthModel.calculated && anchorSpec.right) {
dimensions |= 1;
}
if (childContext.heightModel.calculated && anchorSpec.bottom) {
dimensions |= 2;
}
if (dimensions === 3) {
break;
}
}
}
ownerContext.anchorDimensions = dimensions;
me.sanityCheck(ownerContext);
},
calculateItems: function(ownerContext, containerSize) {
var me = this,
childItems = ownerContext.childItems,
length = childItems.length,
gotHeight = containerSize.gotHeight,
gotWidth = containerSize.gotWidth,
ownerHeight = containerSize.height,
ownerWidth = containerSize.width,
knownDimensions = (gotWidth ? 1 : 0) | (gotHeight ? 2 : 0),
anchorDimensions = ownerContext.anchorDimensions,
anchorSpec, childContext, childMargins, height, i, width;
if (!anchorDimensions) {
return true;
}
for (i = 0; i < length; i++) {
childContext = childItems[i];
childMargins = childContext.getMarginInfo();
anchorSpec = childContext.target.anchorSpec;
if (gotWidth && childContext.widthModel.calculated) {
width = anchorSpec.right(ownerWidth) - childMargins.width;
width = me.adjustWidthAnchor(width, childContext);
childContext.setWidth(width);
}
if (gotHeight && childContext.heightModel.calculated) {
height = anchorSpec.bottom(ownerHeight) - childMargins.height;
height = me.adjustHeightAnchor(height, childContext);
childContext.setHeight(height);
}
}
return (knownDimensions & anchorDimensions) === anchorDimensions;
},
sanityCheck: function(ownerContext) {
var shrinkWrapWidth = ownerContext.widthModel.shrinkWrap,
shrinkWrapHeight = ownerContext.heightModel.shrinkWrap,
children = ownerContext.childItems,
anchorSpec, comp, childContext, i, length;
for (i = 0 , length = children.length; i < length; ++i) {
childContext = children[i];
comp = childContext.target;
anchorSpec = comp.anchorSpec;
if (anchorSpec) {
if (childContext.widthModel.calculated && anchorSpec.right) {
if (shrinkWrapWidth) {
Ext.log({
level: 'warn',
msg: 'Right anchor on ' + comp.id + ' in shrinkWrap width container'
});
}
}
if (childContext.heightModel.calculated && anchorSpec.bottom) {
if (shrinkWrapHeight) {
Ext.log({
level: 'warn',
msg: 'Bottom anchor on ' + comp.id + ' in shrinkWrap height container'
});
}
}
}
}
},
anchorFactory: {
offset: function(delta) {
return function(v) {
return v + delta;
};
},
ratio: function(ratio) {
return function(v) {
return Math.floor(v * ratio);
};
},
standard: function(diff) {
return function(v) {
return v - diff;
};
}
},
parseAnchor: function(a, start, cstart) {
if (a && a !== 'none') {
var factory = this.anchorFactory,
delta;
if (this.parseAnchorRE.test(a)) {
return factory.standard(cstart - start);
}
if (a.indexOf('%') !== -1) {
return factory.ratio(parseFloat(a.replace('%', '')) * 0.01);
}
delta = parseInt(a, 10);
if (!isNaN(delta)) {
return factory.offset(delta);
}
}
return null;
},
adjustWidthAnchor: function(value, childContext) {
return value;
},
adjustHeightAnchor: function(value, childContext) {
return value;
},
configureItem: function(item) {
var me = this,
owner = me.owner,
anchor = item.anchor,
anchorsArray, anchorWidth, anchorHeight;
me.callParent(arguments);
if (!item.anchor && item.items && !Ext.isNumber(item.width)) {
item.anchor = anchor = me.defaultAnchor;
}
if (owner.anchorSize) {
if (typeof owner.anchorSize === 'number') {
anchorWidth = owner.anchorSize;
} else {
anchorWidth = owner.anchorSize.width;
anchorHeight = owner.anchorSize.height;
}
} else {
anchorWidth = owner.initialConfig.width;
anchorHeight = owner.initialConfig.height;
}
if (anchor) {
anchorsArray = anchor.split(' ');
item.anchorSpec = {
right: me.parseAnchor(anchorsArray[0], item.initialConfig.width, anchorWidth),
bottom: me.parseAnchor(anchorsArray[1], item.initialConfig.height, anchorHeight)
};
}
},
sizePolicy: {
$: {
readsWidth: 1,
readsHeight: 1,
setsWidth: 0,
setsHeight: 0
},
b: {
readsWidth: 1,
readsHeight: 0,
setsWidth: 0,
setsHeight: 1
},
r: {
$: {
readsWidth: 0,
readsHeight: 1,
setsWidth: 1,
setsHeight: 0
},
b: {
readsWidth: 0,
readsHeight: 0,
setsWidth: 1,
setsHeight: 1
}
}
},
getItemSizePolicy: function(item) {
var anchorSpec = item.anchorSpec,
key = '$',
policy = this.sizePolicy,
sizeModel;
if (anchorSpec) {
sizeModel = this.owner.getSizeModel();
if (anchorSpec.right && !sizeModel.width.shrinkWrap) {
policy = policy.r;
}
if (anchorSpec.bottom && !sizeModel.height.shrinkWrap) {
key = 'b';
}
}
return policy[key];
}
});
Ext.define('Ext.dashboard.Panel', {
extend: 'Ext.panel.Panel',
xtype: 'dashboard-panel',
cls: Ext.baseCSSPrefix + 'dashboard-panel',
anchor: '100%',
layout: 'fit',
frame: true,
closable: true,
collapsible: true,
animCollapse: true,
titleCollapse: true,
stateful: true,
draggable: {
moveOnDrag: false
},
animateClose: true,
loadMask: true,
loadMessage: 'Loading...',
minHeight: 90,
resizable: true,
resizeHandles: 's',
doClose: function() {
var me = this;
if (me.animateClose) {
if (!me.closing) {
me.closing = true;
me.el.animate({
opacity: 0,
callback: me.finishClose,
scope: me
});
}
} else {
me.finishClose();
}
},
finishClose: function() {
var me = this,
closeAction = me.closeAction;
me.closing = false;
me.fireEvent('close', me);
Ext.suspendLayouts();
me[closeAction]();
Ext.resumeLayouts(true);
if (closeAction === 'hide') {
me.el.setOpacity(1);
}
},
afterRender: function() {
this.callParent();
if (this.loading) {
this.onViewBeforeLoad();
}
},
getLoadMask: function() {
var me = this,
loadMask = me.rendered && me.loadMask,
config;
if (loadMask && !loadMask.isComponent) {
config = {
target: me
};
if (loadMask === true) {
loadMask = config;
} else {
Ext.apply(config, loadMask);
}
me.loadMask = loadMask = Ext.ComponentManager.create(config, 'loadmask');
}
return loadMask || null;
},
onAdd: function(view) {
this.callParent(arguments);
view.on({
beforeload: 'onViewBeforeLoad',
load: 'onViewLoaded',
scope: this
});
},
onViewBeforeLoad: function() {
this.loading = true;
var loadMask = this.getLoadMask();
if (loadMask) {
loadMask.show();
}
},
onViewLoaded: function() {
this.loading = false;
var loadMask = this.getLoadMask();
if (loadMask) {
loadMask.hide();
}
var view = this.items.getAt(0);
if (view.getTitle) {
var title = view.getTitle();
if (title) {
this.setTitle(title);
}
}
},
setBox: function(box) {
this.setSize(box.width, box.height);
},
getState: function() {
var me = this,
state = me.callParent() || {};
if (!state.collapsed) {
me.addPropertyToState(state, 'height', me.rendered ? me.getHeight() : me.height || me.minHeight || 100);
}
return state;
}
});
Ext.define('Ext.dashboard.Column', {
extend: 'Ext.container.Container',
xtype: 'dashboard-column',
requires: [
'Ext.layout.container.Anchor',
'Ext.dashboard.Panel'
],
layout: 'anchor',
isDashboardColumn: true,
defaultType: 'dashboard-panel',
cls: Ext.baseCSSPrefix + 'dashboard-column',
synthetic: true,
onRemove: function(dashPanel, isDestroying) {
var me = this,
ownerCt = me.ownerCt,
remainingSiblings, numRemaining,
totalColumnWidth = 0,
i;
if (ownerCt && me.items.getCount() === 0) {
remainingSiblings = Ext.Array.filter(ownerCt.query('>' + me.xtype + '[rowIndex=' + me.rowIndex + ']'), function(c) {
return c !== me;
});
numRemaining = remainingSiblings.length;
if (!me.destroying && !me.isDestroyed) {
ownerCt.remove(me);
if (numRemaining === 1) {
remainingSiblings[0].columnWidth = 1;
} else
{
for (i = 0; i < numRemaining; i++) {
totalColumnWidth += remainingSiblings[i].columnWidth || 0;
}
for (i = 0; i < numRemaining; i++) {
remainingSiblings[i].columnWidth = remainingSiblings[i].columnWidth / totalColumnWidth;
}
}
if (isDestroying) {
ownerCt.updateLayout();
}
}
}
}
});
Ext.define('Ext.layout.container.Column', {
extend: 'Ext.layout.container.Auto',
alias: [
'layout.column'
],
alternateClassName: 'Ext.layout.ColumnLayout',
type: 'column',
itemCls: Ext.baseCSSPrefix + 'column',
targetCls: Ext.baseCSSPrefix + 'column-layout-ct',
clearSide: 'left',
columnWidthSizePolicy: {
readsWidth: 0,
readsHeight: 1,
setsWidth: 1,
setsHeight: 0
},
createsInnerCt: true,
manageOverflow: true,
setsItemSize: true,
needsItemSize: true,
isItemShrinkWrap: function(item) {
return true;
},
getItemSizePolicy: function(item, ownerSizeModel) {
if (item.columnWidth) {
if (!ownerSizeModel) {
ownerSizeModel = this.owner.getSizeModel();
}
if (!ownerSizeModel.width.shrinkWrap) {
return this.columnWidthSizePolicy;
}
}
return this.autoSizePolicy;
},
calculateItems: function(ownerContext, containerSize) {
var me = this,
columnCount = me.columnCount,
targetContext = ownerContext.targetContext,
items = ownerContext.childItems,
len = items.length,
contentWidth = 0,
gotWidth = containerSize.gotWidth,
blocked, availableWidth, i, itemContext, itemMarginWidth, itemWidth;
if (gotWidth === false) {
targetContext.domBlock(me, 'width');
blocked = true;
} else if (gotWidth) {
availableWidth = containerSize.width;
} else {
return true;
}
for (i = 0; i < len; ++i) {
itemContext = items[i];
if (columnCount) {
if (i % columnCount) {
itemContext.setProp('clear', null);
} else {
itemContext.setProp('clear', me.clearSide);
}
}
itemMarginWidth = itemContext.getMarginInfo().width;
if (!itemContext.widthModel.calculated) {
itemWidth = itemContext.getProp('width');
if (typeof itemWidth !== 'number') {
itemContext.block(me, 'width');
blocked = true;
}
contentWidth += itemWidth + itemMarginWidth;
}
}
if (!blocked) {
availableWidth = (availableWidth < contentWidth) ? 0 : availableWidth - contentWidth;
for (i = 0; i < len; ++i) {
itemContext = items[i];
if (itemContext.widthModel.calculated) {
itemMarginWidth = itemContext.marginInfo.width;
itemWidth = itemContext.target.columnWidth;
itemWidth = Math.floor(itemWidth * availableWidth) - itemMarginWidth;
itemWidth = itemContext.setWidth(itemWidth);
contentWidth += itemWidth + itemMarginWidth;
}
}
ownerContext.setContentWidth(contentWidth + ownerContext.paddingContext.getPaddingInfo().width);
}
return !blocked;
}
});
Ext.define('Ext.resizer.SplitterTracker', {
extend: 'Ext.dd.DragTracker',
requires: [
'Ext.util.Region'
],
enabled: true,
overlayCls: Ext.baseCSSPrefix + 'resizable-overlay',
createDragOverlay: function() {
var overlay,
El = Ext.dom.Element;
overlay = this.overlay = Ext.getBody().createChild({
role: 'presentation',
cls: this.overlayCls,
html: '&#160;'
});
overlay.unselectable();
overlay.setSize(El.getDocumentWidth(), El.getDocumentHeight());
overlay.show();
},
getPrevCmp: function() {
var splitter = this.getSplitter();
return splitter.previousSibling(':not([hidden])');
},
getNextCmp: function() {
var splitter = this.getSplitter();
return splitter.nextSibling(':not([hidden])');
},
onBeforeStart: function(e) {
var me = this,
prevCmp = me.getPrevCmp(),
nextCmp = me.getNextCmp(),
collapseEl = me.getSplitter().collapseEl,
target = e.getTarget(),
box;
if (!prevCmp || !nextCmp) {
return false;
}
if (collapseEl && target === collapseEl.dom) {
return false;
}
if (nextCmp.collapsed || prevCmp.collapsed) {
return false;
}
me.prevBox = prevCmp.getEl().getBox();
me.nextBox = nextCmp.getEl().getBox();
me.constrainTo = box = me.calculateConstrainRegion();
if (!box) {
return false;
}
return box;
},
onStart: function(e) {
var splitter = this.getSplitter();
this.createDragOverlay();
splitter.addCls(splitter.baseCls + '-active');
},
onResizeKeyDown: function(e) {
var me = this,
splitter = me.getSplitter(),
key = e.getKey(),
incrIdx = splitter.orientation === 'vertical' ? 0 : 1,
incr = key === e.UP || key === e.LEFT ? -1 : 1,
easing;
if (!me.active && me.onBeforeStart(e)) {
Ext.fly(e.target).on('keyup', me.onResizeKeyUp, me);
me.triggerStart(e);
me.onMouseDown(e);
me.startXY = splitter.getXY();
me.lastKeyDownXY = Ext.Array.slice(me.startXY);
easing = me.easing = new Ext.fx.easing.Linear();
easing.setStartTime(Ext.Date.now());
easing.setStartValue(1);
easing.setEndValue(4);
easing.setDuration(2000);
}
if (me.active) {
me.lastKeyDownXY[incrIdx] = Math.round(me.lastKeyDownXY[incrIdx] + (incr * me.easing.getValue()));
me.lastXY = me.lastKeyDownXY;
splitter.setXY(me.getXY('dragTarget'));
}
},
onResizeKeyUp: function(e) {
this.onMouseUp(e);
},
calculateConstrainRegion: function() {
var me = this,
splitter = me.getSplitter(),
splitWidth = splitter.getWidth(),
defaultMin = splitter.defaultSplitMin,
orient = splitter.orientation,
prevBox = me.prevBox,
prevCmp = me.getPrevCmp(),
nextBox = me.nextBox,
nextCmp = me.getNextCmp(),
prevConstrainRegion, nextConstrainRegion, constrainOptions;
if (orient === 'vertical') {
constrainOptions = {
prevCmp: prevCmp,
nextCmp: nextCmp,
prevBox: prevBox,
nextBox: nextBox,
defaultMin: defaultMin,
splitWidth: splitWidth
};
prevConstrainRegion = new Ext.util.Region(prevBox.y, me.getVertPrevConstrainRight(constrainOptions), prevBox.bottom, me.getVertPrevConstrainLeft(constrainOptions));
nextConstrainRegion = new Ext.util.Region(nextBox.y, me.getVertNextConstrainRight(constrainOptions), nextBox.bottom, me.getVertNextConstrainLeft(constrainOptions));
} else {
prevConstrainRegion = new Ext.util.Region(prevBox.y + (prevCmp.minHeight || defaultMin), prevBox.right,
(prevCmp.maxHeight ? prevBox.y + prevCmp.maxHeight : nextBox.bottom - (nextCmp.minHeight || defaultMin)) + splitWidth, prevBox.x);
nextConstrainRegion = new Ext.util.Region(
(nextCmp.maxHeight ? nextBox.bottom - nextCmp.maxHeight : prevBox.y + (prevCmp.minHeight || defaultMin)) - splitWidth, nextBox.right, nextBox.bottom - (nextCmp.minHeight || defaultMin), nextBox.x);
}
return prevConstrainRegion.intersect(nextConstrainRegion);
},
performResize: function(e, offset) {
var me = this,
splitter = me.getSplitter(),
orient = splitter.orientation,
prevCmp = me.getPrevCmp(),
nextCmp = me.getNextCmp(),
owner = splitter.ownerCt,
flexedSiblings = owner.query('>[flex]'),
len = flexedSiblings.length,
vertical = orient === 'vertical',
i = 0,
dimension = vertical ? 'width' : 'height',
totalFlex = 0,
item, size;
for (; i < len; i++) {
item = flexedSiblings[i];
size = vertical ? item.getWidth() : item.getHeight();
totalFlex += size;
item.flex = size;
}
offset = vertical ? offset[0] : offset[1];
if (prevCmp) {
size = me.prevBox[dimension] + offset;
if (prevCmp.flex) {
prevCmp.flex = size;
} else {
prevCmp[dimension] = size;
}
}
if (nextCmp) {
size = me.nextBox[dimension] - offset;
if (nextCmp.flex) {
nextCmp.flex = size;
} else {
nextCmp[dimension] = size;
}
}
owner.updateLayout();
},
endDrag: function() {
var me = this;
if (me.overlay) {
me.overlay.destroy();
delete me.overlay;
}
me.callParent(arguments);
},
onEnd: function(e) {
var me = this,
splitter = me.getSplitter();
splitter.removeCls(splitter.baseCls + '-active');
me.performResize(e, me.getResizeOffset());
},
onDrag: function(e) {
var me = this,
offset = me.getOffset('dragTarget'),
splitter = me.getSplitter(),
splitEl = splitter.getEl(),
orient = splitter.orientation;
if (orient === "vertical") {
splitEl.setX(me.startRegion.left + offset[0]);
} else {
splitEl.setY(me.startRegion.top + offset[1]);
}
},
getSplitter: function() {
return this.splitter;
},
getVertPrevConstrainRight: function(o) {
return (o.prevCmp.maxWidth ? o.prevBox.x + o.prevCmp.maxWidth : o.nextBox.right - (o.nextCmp.minWidth || o.defaultMin)) + o.splitWidth;
},
getVertPrevConstrainLeft: function(o) {
return o.prevBox.x + (o.prevCmp.minWidth || o.defaultMin);
},
getVertNextConstrainRight: function(o) {
return o.nextBox.right - (o.nextCmp.minWidth || o.defaultMin);
},
getVertNextConstrainLeft: function(o) {
return (o.nextCmp.maxWidth ? o.nextBox.right - o.nextCmp.maxWidth : o.prevBox.x + (o.prevBox.minWidth || o.defaultMin)) - o.splitWidth;
},
getResizeOffset: function() {
return this.getOffset('dragTarget');
}
});
Ext.define('Ext.layout.container.ColumnSplitterTracker', {
extend: 'Ext.resizer.SplitterTracker',
onStart: function(e) {
Ext.apply(this.getSplitter().el.dom.style, {
top: 0,
left: 0
});
this.callParent(arguments);
},
endDrag: function() {
var me = this;
me.callParent(arguments);
me.getSplitter().el.dom.style.left = 0;
},
performResize: function(e, offset) {
var me = this,
prevCmp = me.getPrevCmp(),
nextCmp = me.getNextCmp(),
splitter = me.getSplitter(),
owner = splitter.ownerCt,
delta = offset[0],
prevWidth, nextWidth, ratio;
if (prevCmp && nextCmp) {
prevCmp.width = prevWidth = me.prevBox.width + delta;
nextCmp.width = nextWidth = me.nextBox.width - delta;
ratio = (prevCmp.columnWidth + nextCmp.columnWidth) / (prevWidth + nextWidth);
prevCmp.columnWidth = prevWidth * ratio;
nextCmp.columnWidth = nextWidth * ratio;
}
owner.updateLayout();
}
});
Ext.define('Ext.layout.container.ColumnSplitter', {
extend: 'Ext.resizer.Splitter',
xtype: 'columnsplitter',
requires: [
'Ext.layout.container.ColumnSplitterTracker'
],
isSplitter: true,
synthetic: true,
cls: Ext.baseCSSPrefix + 'splitter-vertical',
orientation: 'vertical',
collapseDirection: 'left',
trackerClass: 'Ext.layout.container.ColumnSplitterTracker',
width: 7,
height: 1,
getTrackerConfig: function() {
var tracker = this.callParent();
tracker.xclass = this.trackerClass;
return tracker;
}
});
Ext.define('Ext.layout.container.Dashboard', {
extend: 'Ext.layout.container.Column',
alias: 'layout.dashboard',
requires: [
'Ext.layout.container.ColumnSplitter'
],
type: 'dashboard',
firstColumnCls: Ext.baseCSSPrefix + 'dashboard-column-first',
lastColumnCls: Ext.baseCSSPrefix + 'dashboard-column-last',
getSplitterConfig: function() {
return {
xtype: 'columnsplitter'
};
},
getColumns: function(items) {
var array = Ext.Array;
return array.filter(array.from(items), function(item) {
return item.target && item.target.isSplitter !== true;
});
},
beginLayout: function(ownerContext) {
var me = this;
me.callParent([
ownerContext
]);
var childItems = ownerContext.childItems,
rows = (ownerContext.rows = []),
length = childItems.length,
totalWidth = 2,
columnTargets = 0,
lastRow = 0,
maxColumns = me.owner.getMaxColumns(),
child, i, prev, row, splitter, target, width;
for (i = 0; i < length; ++i) {
target = (child = childItems[i]).target;
splitter = target && target.isSplitter;
columnTargets += (splitter ? 0 : 1);
width = splitter ? 0 : target.columnWidth || 1;
if (totalWidth + width > 1 || (maxColumns && (columnTargets > maxColumns))) {
if (prev) {
prev.orphan = 1;
prev.el.setHeight(0);
}
totalWidth = 0;
columnTargets = 1;
if (rows.length) {
lastRow = rows.length - 1;
me.syncFirstLast(me.getColumns(rows[lastRow].items));
}
rows.push(row = {
index: rows.length,
items: [],
maxHeight: 0
});
}
totalWidth += width;
row.items.push(child);
child.row = row;
target.rowIndex = row.index;
if (splitter) {
child.el.setHeight(1);
}
prev = child;
}
if (rows.length) {
me.syncFirstLast(me.getColumns(rows[rows.length - 1].items));
}
},
beforeLayoutCycle: function(ownerContext) {
var me = this,
items = me.owner.items;
if (me.splitterGen !== items.generation) {
me.syncSplitters();
me.splitterGen = items.generation;
}
me.callParent(arguments);
},
finishedLayout: function(ownerContext) {
var items = ownerContext.childItems,
len = items.length,
box, child, i, target, row;
this.callParent([
ownerContext
]);
for (i = 0; i < len; i += 2) {
target = (child = items[i]).target;
box = target.lastBox;
row = child.row;
row.maxHeight = Math.max(row.maxHeight, box.height);
target.width = box.width;
}
for (i = 1; i < len; i += 2) {
target = (child = items[i]).target;
if (!child.orphan) {
target.el.setHeight(child.row.maxHeight);
}
}
},
syncSplitters: function() {
var me = this,
owner = me.owner,
items = owner.items.items,
index = items.length,
ok = true,
shouldBeSplitter = false,
item, splitter;
while (index-- > 0) {
item = items[index];
if (shouldBeSplitter) {
if (item.isSplitter) {
shouldBeSplitter = false;
} else {
if (ok) {
ok = false;
owner.suspendLayouts();
}
splitter = owner.add(index + 1, me.getSplitterConfig());
}
} else {
if (item.isSplitter) {
if (ok) {
ok = false;
owner.suspendLayouts();
}
owner.remove(item);
} else {
shouldBeSplitter = true;
}
}
}
while (items.length && (item = items[0]).isSplitter) {
if (ok) {
ok = false;
owner.suspendLayouts();
}
owner.remove(item);
}
if (!ok) {
owner.resumeLayouts();
}
},
syncFirstLast: function(items) {
var me = this,
firstCls = me.firstColumnCls,
lastCls = me.lastColumnCls,
len,
firstAndLast = [
firstCls,
lastCls
],
i, item, last;
items = Ext.Array.from(items);
len = items.length;
for (i = 0; i < len; ++i) {
item = items[i].target;
last = (i === len - 1);
if (!i) {
if (last) {
item.addCls(firstAndLast);
} else {
item.addCls(firstCls);
item.removeCls(lastCls);
}
} else if (last) {
item.addCls(lastCls);
item.removeCls(firstCls);
} else {
item.removeCls(firstAndLast);
}
}
}
});
Ext.define('Ext.dashboard.DropZone', {
extend: 'Ext.dd.DropTarget',
ddScrollConfig: {
vthresh: 75,
hthresh: -1,
animate: true,
increment: 200
},
containerScroll: true,
overClass: Ext.baseCSSPrefix + 'dashboard-dd-over',
constructor: function(dashboard, cfg) {
this.dashboard = dashboard;
dashboard.body.ddScrollConfig = this.ddScrollConfig;
this.callParent([
dashboard.body,
cfg
]);
},
getOverEvent: function(dd, e, data) {
var dashboard = this.dashboard,
dbody = dashboard.body,
items = dashboard.items.items,
bodyBox = dbody.getBox(),
count = items.length,
xy = e.getXY(),
x = xy[0] - bodyBox.x + dbody.getScrollLeft(),
y = xy[1] - bodyBox.y + dbody.getScrollTop(),
over = {
columnIndex: 0,
column: null,
dashboard: dashboard,
above: null,
extensible: false,
beforeAfter: 0,
data: data,
panel: data.panel,
rawEvent: e,
source: dd,
status: this.dropAllowed
},
t, ht, i, k, item, w, childCount, childItems, childItem;
for (i = 0; i < count; i += 2) {
item = items[i];
w = item.lastBox.width;
if (items[i + 1]) {
w += items[i + 1].lastBox.width;
}
if (e.within(item.el)) {
over.columnIndex = i;
over.column = item;
over.extensible = this.isRowExtensible(item.rowIndex);
t = Math.min(80, w * 0.2);
over.beforeAfter = t = (over.extensible && ((x < t) ? -1 : ((x > w - t) ? 1 : 0)));
if (!t || !over.extensible) {
childItems = item.items.items;
for (k = 0 , childCount = childItems.length; k < childCount; ++k) {
childItem = childItems[k];
ht = childItem.el.getHeight();
if (y < ht / 2) {
over.above = childItem;
break;
}
y -= ht;
}
}
break;
}
x -= w;
}
return over;
},
notifyOver: function(dd, e, data) {
var me = this,
dashboard = me.dashboard,
over = me.getOverEvent(dd, e, data),
colEl = over.column && over.column.el,
proxy = dd.proxy,
proxyProxy,
aboveItem = over.above,
colWidth,
width = 0,
padding,
hasListeners = dashboard.hasListeners;
data.lastOver = over;
if ((!hasListeners.validatedrop || dashboard.fireEvent('validatedrop', over) !== false) && (!hasListeners.beforedragover || dashboard.fireEvent('beforedragover', over) !== false)) {
proxyProxy = dd.panelProxy.getProxy();
proxy.getProxy().setWidth('auto');
if (colEl) {
width = colWidth = colEl.getWidth();
if (over.beforeAfter) {
dd.panelProxy.moveProxy(colEl.dom, colEl.dom.firstChild);
width = colWidth / 2;
proxyProxy.setWidth(width);
} else {
if (aboveItem) {
dd.panelProxy.moveProxy(aboveItem.el.dom.parentNode, aboveItem.el.dom);
} else {
dd.panelProxy.moveProxy(colEl.dom, null);
}
proxyProxy.setWidth('auto');
}
if (width) {}
proxyProxy.setStyle({
'float': 'none',
'clear': 'none',
'margin-left': (over.beforeAfter > 0) ? (colWidth - width - colEl.getPadding('lr')) + 'px' : '',
'margin-top': '7px'
});
} else {
padding = dashboard.body.getPadding('lr');
proxyProxy.setStyle({
'float': 'left',
'clear': 'left',
'margin': '0 7px 0 7px'
});
proxyProxy.setWidth(dashboard.body.getWidth() - padding);
dd.panelProxy.moveProxy(dashboard.body.dom.firstChild.firstChild, null);
}
this.scrollPos = dashboard.body.getScroll();
if (hasListeners.dragover) {
dashboard.fireEvent('dragover', over);
}
}
return over.status;
},
isRowExtensible: function(rowIndex) {
var me = this,
dashboard = me.dashboard,
maxColumns = dashboard.getMaxColumns() || 1;
return Ext.Array.from(dashboard.query('>dashboard-column[rowIndex=' + rowIndex + ']')).length < maxColumns;
},
notifyDrop: function(dd, e, data) {
this.callParent(arguments);
var dashboard = this.dashboard,
over = data.lastOver,
panel = over.panel,
fromCt = panel.ownerCt,
toCt = over.column,
side = toCt ? over.beforeAfter : 1,
currentIndex = fromCt.items.indexOf(panel),
newIndex = toCt ? (over.above ? toCt.items.indexOf(over.above) : toCt.items.getCount()) : 0,
colIndex, newCol,
hasListeners = dashboard.hasListeners;
if (fromCt === toCt) {
if (fromCt.items.getCount() === 1) {
return;
}
if (!side) {
if (currentIndex < newIndex) {
--newIndex;
}
if (currentIndex === newIndex) {
return;
}
}
}
if ((hasListeners.validatedrop && dashboard.fireEvent('validatedrop', over) === false) || (hasListeners.beforedrop && dashboard.fireEvent('beforedrop', over) === false)) {
return;
}
Ext.suspendLayouts();
panel.isMoving = true;
if (side) {
colIndex = dashboard.items.indexOf(toCt);
if (colIndex < 0) {
colIndex = dashboard.items.getCount();
} else if (side > 0) {
++colIndex;
}
newCol = dashboard.createColumn();
if (toCt) {
newCol.columnWidth = toCt.columnWidth = toCt.columnWidth / 2;
delete toCt.width;
} else {
newCol.columnWidth = 1;
}
toCt = dashboard.insert(colIndex, newCol);
newIndex = 0;
}
panel.el.dom.style.display = '';
toCt.insert(newIndex, panel);
panel.isMoving = false;
toCt.updateLayout();
Ext.resumeLayouts(true);
if (hasListeners.drop) {
dashboard.fireEvent('drop', over);
}
}
});
Ext.define('Ext.dashboard.Part', {
mixins: [
'Ext.mixin.Factoryable',
'Ext.mixin.Identifiable'
],
requires: [
'Ext.util.ObjectTemplate'
],
alias: 'part.part',
factoryConfig: {
type: 'part'
},
isPart: true,
_lastId: 0,
config: {
id: null,
dashboard: null,
viewTemplate: {
collapsed: '{collapsed}',
columnIndex: '{columnIndex}',
id: '{id}',
title: '{title}',
height: '{height}'
}
},
viewTemplateOptions: {
excludeProperties: {
bind: 1
}
},
valueRe: /^[{][a-z]*[}]$/i,
constructor: function(config) {
this.initConfig(config);
},
applyViewTemplate: function(template) {
if (!Ext.isObject(template)) {
Ext.Error.raise('The viewTemplate for ' + this.$className + ' is not an Object');
}
return Ext.util.ObjectTemplate.create(template, this.viewTemplateOptions);
},
displayForm: function(instance, currentConfig, callback, scope) {
callback.call(scope || this, {});
},
createView: function(config) {
var me = this,
template = me.getViewTemplate(),
ret = template.apply(config);
ret.dashboard = me.getDashboard();
ret.part = me;
ret._partConfig = config;
return ret;
}
});
Ext.define('Ext.dashboard.Dashboard', {
extend: 'Ext.panel.Panel',
xtype: 'dashboard',
requires: [
'Ext.layout.container.Dashboard',
'Ext.dashboard.DropZone',
'Ext.dashboard.Column',
'Ext.dashboard.Part'
],
isDashboard: true,
cls: Ext.baseCSSPrefix + 'dashboard',
bodyCls: Ext.baseCSSPrefix + 'dashboard-body',
defaultType: 'dashboard-column',
scrollable: true,
layout: null,
stateful: false,
idSeed: 1,
config: {
parts: null
},
renderConfig: {
maxColumns: 4
},
initComponent: function() {
var me = this;
if (!me.layout) {
me.layout = {
type: 'dashboard'
};
}
me.callParent();
},
applyParts: function(parts, collection) {
if (!collection) {
collection = new Ext.util.Collection({
decoder: Ext.Factory.part
});
}
var id, part;
for (id in parts) {
part = parts[id];
if (Ext.isString(part)) {
part = {
type: part
};
}
part.id = id;
part.dashboard = this;
collection.add(part);
}
return collection;
},
getPart: function(type) {
var parts = this.getParts();
return parts.getByKey(type);
},
addNew: function(type, columnIndex, beforeAfter) {
var me = this,
part = me.getPart(type);
part.displayForm(null, null, function(config) {
config.type = type;
me.addView(config, columnIndex, beforeAfter);
});
},
addView: function(instance, columnIndex, beforeAfter) {
var me = this,
items = me.query('dashboard-column'),
count = items.length,
index = columnIndex || 0,
view = instance.id ? instance : me.createView(instance),
columnWidths = me.columnWidths,
column;
if (!count) {
column = me.add(0, me.createColumn({
columnWidth: (Ext.isArray(columnWidths) ? columnWidths[0] : 1)
}));
items = [
column
];
count = 1;
}
if (index >= count) {
index = count - 1;
beforeAfter = 1;
}
if (!beforeAfter) {
column = items[index];
if (column) {
return column.add(view);
}
}
if (beforeAfter > 0) {
++index;
}
column = me.createColumn();
if (columnWidths) {
column.columnWidth = columnWidths[index] || (columnWidths[index] = 1);
}
if (!column.items) {
column.items = [];
}
column.items.push(view);
column = me.add(column);
return column.items.first();
},
createColumn: function(config) {
var cycle = this.cycleLayout;
return Ext.apply({
items: [],
bubbleEvents: [
'add',
'remove',
'childmove',
'resize'
],
listeners: {
remove: this.onRemoveItem,
expand: cycle,
collapse: cycle,
scope: this
}
}, config);
},
createView: function(config) {
var me = this,
type = config.type,
part = me.getPart(type),
view = part.createView(config);
if (!view.id) {
view.id = me.id + '_' + type + (me.idSeed++);
}
view.bubbleEvents = Ext.Array.from(view.bubbleEvents).concat([
'expand',
'collapse'
]);
view.stateful = me.stateful;
return view;
},
initEvents: function() {
this.callParent();
this.dd = new Ext.dashboard.DropZone(this, this.dropConfig);
},
cycleLayout: function() {
this.updateLayout();
},
beforeDestroy: function() {
if (this.dd) {
Ext.destroy(this.dd);
}
this.callParent();
},
applyState: function(state) {
delete state.items;
var me = this;
me.callParent([
state
]);
var columnWidths = state.columnWidths,
items = me.items.items,
length = items.length,
i, n;
if (columnWidths) {
n = columnWidths.length;
me.columnWidths = [];
for (i = 0; i < length; ++i) {
me.columnWidths.push(items[i].columnWidth = (i < n) ? columnWidths[i] : (1 / length));
}
}
},
getState: function() {
var me = this,
columnWidths = [],
items = me.items.items,
state = me.callParent() || {},
length = items.length,
i, item;
for (i = 0; i < length; ++i) {
if (!(item = items[i]).isSplitter) {
columnWidths.push(item.columnWidth);
}
}
state.columnWidths = columnWidths;
state.idSeed = me.idSeed;
state.items = me.serializeItems();
me.columnWidths = columnWidths;
return state;
},
initItems: function() {
var me = this,
defaultContent = me.defaultContent,
state;
if (me.stateful) {
state = Ext.state.Manager.get(me.getStateId());
defaultContent = (state && state.items) || defaultContent;
}
if (!me.items && defaultContent) {
me.items = me.deserializeItems(defaultContent);
}
me.callParent();
},
deserializeItems: function(serialized) {
var me = this,
length = serialized.length,
columns = [],
columnWidths = me.columnWidths,
maxColumns = me.getMaxColumns(),
column, columnIndex, columnWidth, i, item, partConfig;
for (i = 0; i < length; ++i) {
partConfig = serialized[i];
columnIndex = Math.min(partConfig.columnIndex || 0, maxColumns - 1);
delete partConfig.columnIndex;
if (!(column = columns[columnIndex])) {
columns[columnIndex] = column = me.createColumn();
columnWidth = columnWidths && columnWidths[columnIndex];
if (columnWidth) {
column.columnWidth = columnWidth;
}
}
item = me.createView(partConfig);
column.items.push(item);
}
for (i = 0 , length = columns.length; i < length; ++i) {
column = columns[i];
if (!column.columnWidth) {
column.columnWidth = 1 / length;
}
}
return columns;
},
serializeItem: function(item) {
return Ext.apply({
type: item.part.id,
id: item.id,
columnIndex: item.columnIndex
}, item._partConfig);
},
serializeItems: function() {
var me = this,
items = me.items.items,
length = items.length,
ret = [],
columnIndex = 0,
child, childItems, i, item, j, k;
for (i = 0; i < length; ++i) {
item = items[i];
if (!item.isSplitter) {
childItems = item.items.items;
for (j = 0 , k = childItems.length; j < k; ++j) {
child = childItems[j];
child.columnIndex = columnIndex;
ret.push(me.serializeItem(child));
}
++columnIndex;
}
}
return ret;
},
onRemoveItem: function(column, item) {
if (item.stateful && !item.isMoving) {
Ext.state.Manager.clear(item.getStateId());
}
}
});
Ext.define('Ext.dom.Layer', {
extend: 'Ext.Element',
alternateClassName: 'Ext.Layer',
isLayer: true,
constructor: function(config, existingEl) {
config = config || {};
var me = this,
dh = Ext.DomHelper,
cp = config.parentEl,
pel = cp ? Ext.getDom(cp) : document.body,
hm = config.hideMode,
cls = Ext.baseCSSPrefix + (config.fixed ? 'fixed-layer' : 'layer'),
dom, id, element, shadowConfig;
if (existingEl) {
dom = Ext.getDom(existingEl);
if (!dom.parentNode) {
pel.appendChild(dom);
}
}
if (!dom) {
dom = dh.append(pel, config.dh || {
tag: 'div',
cls: cls
});
}
if (config.id) {
dom.id = config.id;
}
id = dom.id;
if (id) {
element = Ext.cache[id];
if (element) {
delete Ext.cache[id];
element.dom = null;
}
}
this.callParent([
dom
]);
if (existingEl) {
me.addCls(cls);
}
if (config.preventSync) {
me.preventSync = true;
}
if (config.cls) {
me.addCls(config.cls);
}
me.constrain = config.constrain !== false;
if (hm) {
me.setVisibilityMode(Ext.Element[hm.toUpperCase()]);
} else if (config.useDisplay) {
me.setVisibilityMode(Ext.Element.DISPLAY);
} else {
me.setVisibilityMode(Ext.Element.VISIBILITY);
}
if (config.shadow) {
me.shadowOffset = config.shadowOffset || 4;
shadowConfig = {
offset: me.shadowOffset,
fixed: config.fixed
};
if (config.shadow !== true) {
shadowConfig.mode = config.shadow;
}
me.enableShadow(shadowConfig);
} else {
me.shadowOffset = 0;
}
if (config.shim) {
me.enableShim({
fixed: config.fixed
});
}
if (config.hidden === true) {
me.hide();
} else if (config.hidden === false) {
me.show();
}
}
});
Ext.define('Ext.event.publisher.MouseEnterLeave', {
extend: 'Ext.event.publisher.Dom',
type: 'mouseEnterLeave'
}, function(MouseEnterLeave) {
var eventMap = {
mouseover: 'mouseenter',
mouseout: 'mouseleave'
};
if (!Ext.supports.MouseEnterLeave) {
MouseEnterLeave.override({
handledDomEvents: [
'mouseover',
'mouseout'
],
handledEvents: [
'mouseenter',
'mouseleave'
],
doDelegatedEvent: function(e) {
var target, relatedTarget, id, el, type, event;
e = this.callParent([
e
]);
target = e.getTarget();
relatedTarget = e.getRelatedTarget();
if (relatedTarget && Ext.fly(target).contains(relatedTarget)) {
return;
}
id = target.id;
if (id) {
el = Ext.cache[id];
if (el) {
type = eventMap[e.type];
e = e.chain({
type: type
});
if (el.hasListeners[type]) {
event = el.events[type];
if (event) {
event = event.directs;
if (event) {
e.setCurrentTarget(el.dom);
event.fire(e, e.target);
}
}
}
}
}
}
});
}
MouseEnterLeave.instance = new MouseEnterLeave();
});
Ext.define('Ext.flash.Component', {
extend: 'Ext.Component',
alternateClassName: 'Ext.FlashComponent',
alias: 'widget.flash',
flashVersion: '9.0.115',
backgroundColor: '#ffffff',
wmode: 'opaque',
swfWidth: '100%',
swfHeight: '100%',
expressInstall: false,
renderTpl: [
'<div id="{swfId}" role="presentation"></div>'
],
initComponent: function() {
if (!('swfobject' in window)) {
Ext.Error.raise('The SWFObject library is not loaded. Ext.flash.Component requires SWFObject version 2.2 or later: http://code.google.com/p/swfobject/');
}
if (!this.url) {
Ext.Error.raise('The "url" config is required for Ext.flash.Component');
}
this.callParent();
},
beforeRender: function() {
this.callParent();
Ext.applyIf(this.renderData, {
swfId: this.getSwfId()
});
},
afterRender: function() {
var me = this,
flashParams = Ext.apply({}, me.flashParams),
flashVars = Ext.apply({}, me.flashVars);
me.callParent();
flashParams = Ext.apply({
allowScriptAccess: 'always',
bgcolor: me.backgroundColor,
wmode: me.wmode
}, flashParams);
flashVars = Ext.apply({
allowedDomain: document.location.hostname
}, flashVars);
new swfobject.embedSWF(
me.url, me.getSwfId(), me.swfWidth, me.swfHeight, me.flashVersion, me.expressInstall ? me.statics.EXPRESS_INSTALL_URL : undefined, flashVars, flashParams, me.flashAttributes, me.swfCallback.bind(me));
},
swfCallback: function(e) {
var me = this;
if (e.success) {
me.swf = Ext.get(e.ref);
me.onSuccess();
me.fireEvent('success', me);
} else {
me.onFailure();
me.fireEvent('failure', me);
}
},
getSwfId: function() {
return this.swfId || (this.swfId = "extswf" + this.getAutoId());
},
onSuccess: function() {
this.swf.setStyle('visibility', 'inherit');
},
onFailure: Ext.emptyFn,
beforeDestroy: function() {
var me = this,
swf = me.swf;
if (swf) {
swfobject.removeSWF(me.getSwfId());
Ext.destroy(swf);
delete me.swf;
}
me.callParent();
},
statics: {
EXPRESS_INSTALL_URL: 'http:/' + '/swfobject.googlecode.com/svn/trunk/swfobject/expressInstall.swf'
}
});
Ext.define('Ext.form.action.Action', {
alternateClassName: 'Ext.form.Action',
submitEmptyText: true,
constructor: function(config) {
if (config) {
Ext.apply(this, config);
}
var params = config.params;
if (Ext.isString(params)) {
this.params = Ext.Object.fromQueryString(params);
}
},
run: Ext.emptyFn,
onFailure: function(response) {
var form = this.form,
formActive = form && !form.destroying && !form.isDestroyed;
this.response = response;
this.failureType = Ext.form.action.Action.CONNECT_FAILURE;
if (formActive) {
form.afterAction(this, false);
}
},
processResponse: function(response) {
this.response = response;
if (!response.responseText && !response.responseXML) {
return true;
}
return (this.result = this.handleResponse(response));
},
getUrl: function() {
return this.url || this.form.url;
},
getMethod: function() {
return (this.method || this.form.method || 'POST').toUpperCase();
},
getParams: function() {
return Ext.apply({}, this.params, this.form.baseParams);
},
createCallback: function() {
var me = this,
undef,
form = me.form;
return {
success: me.onSuccess,
failure: me.onFailure,
scope: me,
timeout: (this.timeout * 1000) || (form.timeout * 1000),
upload: form.fileUpload ? me.onSuccess : undef
};
},
statics: {
CLIENT_INVALID: 'client',
SERVER_INVALID: 'server',
CONNECT_FAILURE: 'connect',
LOAD_FAILURE: 'load'
}
});
Ext.define('Ext.form.action.Load', {
extend: 'Ext.form.action.Action',
requires: [
'Ext.data.Connection'
],
alternateClassName: 'Ext.form.Action.Load',
alias: 'formaction.load',
type: 'load',
run: function() {
Ext.Ajax.request(Ext.apply(this.createCallback(), {
method: this.getMethod(),
url: this.getUrl(),
headers: this.headers,
params: this.getParams()
}));
},
onSuccess: function(response) {
var result = this.processResponse(response),
form = this.form,
formActive = form && !form.destroying && !form.isDestroyed;
if (result === true || !result.success || !result.data) {
this.failureType = Ext.form.action.Action.LOAD_FAILURE;
if (formActive) {
form.afterAction(this, false);
}
return;
}
if (formActive) {
form.clearInvalid();
form.setValues(result.data);
form.afterAction(this, true);
}
},
handleResponse: function(response) {
var reader = this.form.reader,
rs, data;
if (reader) {
rs = reader.read(response);
data = rs.records && rs.records[0] ? rs.records[0].data : null;
return {
success: rs.success,
data: data
};
}
return Ext.decode(response.responseText);
}
});
Ext.define('Ext.form.action.Submit', {
extend: 'Ext.form.action.Action',
alternateClassName: 'Ext.form.Action.Submit',
alias: 'formaction.submit',
type: 'submit',
run: function() {
var me = this,
form = me.form;
if (me.clientValidation === false || form.isValid()) {
me.doSubmit();
} else {
me.failureType = Ext.form.action.Action.CLIENT_INVALID;
form.afterAction(me, false);
}
},
doSubmit: function() {
var me = this,
ajaxOptions = Ext.apply(me.createCallback(), {
url: me.getUrl(),
method: me.getMethod(),
headers: me.headers
}),
form = me.form,
jsonSubmit = me.jsonSubmit || form.jsonSubmit,
paramsProp = jsonSubmit ? 'jsonData' : 'params',
formInfo;
if (form.hasUpload()) {
formInfo = me.buildForm();
ajaxOptions.form = formInfo.formEl;
ajaxOptions.isUpload = true;
} else {
ajaxOptions[paramsProp] = me.getParams(jsonSubmit);
}
Ext.Ajax.request(ajaxOptions);
if (formInfo) {
me.cleanup(formInfo);
}
},
cleanup: function(formInfo) {
var formEl = formInfo.formEl,
uploadEls = formInfo.uploadEls,
uploadFields = formInfo.uploadFields,
len = uploadFields.length,
i, field;
for (i = 0; i < len; ++i) {
field = uploadFields[i];
if (!field.clearOnSubmit) {
field.restoreInput(uploadEls[i]);
}
}
if (formEl) {
Ext.removeNode(formEl);
}
},
getParams: function(useModelValues) {
var falseVal = false,
configParams = this.callParent(),
fieldParams = this.form.getValues(falseVal, falseVal, this.submitEmptyText !== falseVal, useModelValues,
true);
return Ext.apply({}, fieldParams, configParams);
},
buildForm: function() {
var me = this,
fieldsSpec = [],
formSpec, formEl,
basicForm = me.form,
params = me.getParams(),
uploadFields = [],
uploadEls = [],
fields = basicForm.getFields().items,
i,
len = fields.length,
field, key, value, v, vLen, el;
for (i = 0; i < len; ++i) {
field = fields[i];
if (field.isFileUpload()) {
uploadFields.push(field);
}
}
for (key in params) {
if (params.hasOwnProperty(key)) {
value = params[key];
if (Ext.isArray(value)) {
vLen = value.length;
for (v = 0; v < vLen; v++) {
fieldsSpec.push(me.getFieldConfig(key, value[v]));
}
} else {
fieldsSpec.push(me.getFieldConfig(key, value));
}
}
}
formSpec = {
tag: 'form',
role: 'presentation',
action: me.getUrl(),
method: me.getMethod(),
target: me.target ? (Ext.isString(me.target) ? me.target : Ext.fly(me.target).dom.name) : '_self',
style: 'display:none',
cn: fieldsSpec
};
if (!formSpec.target) {
Ext.Error.raise('Invalid form target.');
}
if (uploadFields.length) {
formSpec.encoding = formSpec.enctype = 'multipart/form-data';
}
formEl = Ext.DomHelper.append(Ext.getBody(), formSpec);
len = uploadFields.length;
for (i = 0; i < len; ++i) {
el = uploadFields[i].extractFileInput();
formEl.appendChild(el);
uploadEls.push(el);
}
return {
formEl: formEl,
uploadFields: uploadFields,
uploadEls: uploadEls
};
},
getFieldConfig: function(name, value) {
return {
tag: 'input',
type: 'hidden',
name: name,
value: Ext.String.htmlEncode(value)
};
},
onSuccess: function(response) {
var form = this.form,
formActive = form && !form.destroying && !form.isDestroyed,
success = true,
result = this.processResponse(response);
if (result !== true && !result.success) {
if (result.errors && formActive) {
form.markInvalid(result.errors);
}
this.failureType = Ext.form.action.Action.SERVER_INVALID;
success = false;
}
if (formActive) {
form.afterAction(this, success);
}
},
handleResponse: function(response) {
var form = this.form,
errorReader = form.errorReader,
rs, errors, i, len, records, result;
if (errorReader) {
rs = errorReader.read(response);
records = rs.records;
errors = [];
if (records) {
for (i = 0 , len = records.length; i < len; i++) {
errors[i] = records[i].data;
}
}
if (errors.length < 1) {
errors = null;
}
result = {
success: rs.success,
errors: errors
};
} else {
try {
result = Ext.decode(response.responseText);
} catch (e) {
result = {
success: false,
errors: []
};
}
}
return result;
}
});
Ext.define('Ext.form.field.TextArea', {
extend: 'Ext.form.field.Text',
alias: [
'widget.textareafield',
'widget.textarea'
],
alternateClassName: 'Ext.form.TextArea',
requires: [
'Ext.XTemplate',
'Ext.util.DelayedTask'
],
fieldSubTpl: [
'<textarea id="{id}" role="{role}" {inputAttrTpl}',
'<tpl if="name"> name="{name}"</tpl>',
'<tpl if="placeholder"> placeholder="{placeholder}"</tpl>',
'<tpl if="maxLength !== undefined"> maxlength="{maxLength}"</tpl>',
'<tpl if="readOnly"> readonly="readonly"</tpl>',
'<tpl if="disabled"> disabled="disabled"</tpl>',
'<tpl if="tabIdx != null"> tabindex="{tabIdx}"</tpl>',
' class="{fieldCls} {typeCls} {typeCls}-{ui} {inputCls}" ',
'<tpl if="fieldStyle"> style="{fieldStyle}"</tpl>',
' autocomplete="off">\n',
'<tpl if="value">{[Ext.util.Format.htmlEncode(values.value)]}</tpl>',
'</textarea>',
{
disableFormats: true
}
],
growMin: 60,
growMax: 1000,
growAppend: '\n-',
enterIsSpecial: false,
preventScrollbars: false,
returnRe: /\r/g,
inputCls: Ext.baseCSSPrefix + 'form-textarea',
extraFieldBodyCls: Ext.baseCSSPrefix + 'form-textarea-body',
constructor: function(config) {
this.callParent([
config
]);
if (this.cols) {
Ext.log.warn('Ext.form.field.TextArea "cols" config was removed in Ext 5.0. Please specify a "width" or use a layout instead.');
}
if (this.rows) {
Ext.log.warn('Ext.form.field.TextArea "rows" config was removed in Ext 5.0. Please specify a "height" or use a layout instead.');
}
},
getSubTplData: function(fieldData) {
var me = this,
fieldStyle = me.getFieldStyle(),
ret = me.callParent(arguments);
if (me.grow) {
if (me.preventScrollbars) {
ret.fieldStyle = (fieldStyle || '') + ';overflow:hidden;height:' + me.growMin + 'px';
}
}
return ret;
},
afterRender: function() {
var me = this;
me.callParent(arguments);
me.needsMaxCheck = me.enforceMaxLength && me.maxLength !== Number.MAX_VALUE && !Ext.supports.TextAreaMaxLength;
if (me.needsMaxCheck) {
me.inputEl.on('paste', me.onPaste, me);
}
},
transformRawValue: function(value) {
return this.stripReturns(value);
},
getValue: function() {
return this.stripReturns(this.callParent());
},
valueToRaw: function(value) {
value = this.stripReturns(value);
return this.callParent([
value
]);
},
stripReturns: function(value) {
if (value && typeof value === 'string') {
value = value.replace(this.returnRe, '');
}
return value;
},
onPaste: function() {
var me = this;
if (!me.pasteTask) {
me.pasteTask = new Ext.util.DelayedTask(me.pasteCheck, me);
}
me.pasteTask.delay(1);
},
pasteCheck: function() {
var me = this,
value = me.getValue(),
max = me.maxLength;
if (value.length > max) {
value = value.substr(0, max);
me.setValue(value);
}
},
fireKey: function(e) {
var me = this,
key = e.getKey(),
value;
if (e.isSpecialKey() && (me.enterIsSpecial || (key !== e.ENTER || e.hasModifier()))) {
me.fireEvent('specialkey', me, e);
}
if (me.needsMaxCheck && key !== e.BACKSPACE && key !== e.DELETE && !e.isNavKeyPress() && !me.isCutCopyPasteSelectAll(e, key)) {
value = me.getValue();
if (value.length >= me.maxLength) {
e.stopEvent();
}
}
},
isCutCopyPasteSelectAll: function(e, key) {
if (e.ctrlKey) {
return key === e.A || key === e.C || key === e.V || key === e.X;
}
return false;
},
autoSize: function() {
var me = this,
inputEl, height, curWidth, value;
if (me.grow && me.rendered && me.getSizeModel().height.auto) {
inputEl = me.inputEl;
curWidth = inputEl.getWidth(true);
value = Ext.util.Format.htmlEncode(inputEl.dom.value) || '&#160;';
value += me.growAppend;
value = value.replace(/\n/g, '<br/>');
height = Ext.util.TextMetrics.measure(inputEl, value, curWidth).height + inputEl.getPadding('tb') +
me.inputWrap.getBorderWidth('tb') + me.triggerWrap.getBorderWidth('tb');
height = Math.min(Math.max(height, me.growMin), me.growMax);
me.bodyEl.setHeight(height);
me.updateLayout();
me.fireEvent('autosize', me, height);
}
},
beforeDestroy: function() {
var task = this.pasteTask;
if (task) {
task.cancel();
this.pasteTask = null;
}
this.callParent();
}
});
Ext.define('Ext.window.MessageBox', {
extend: 'Ext.window.Window',
requires: [
'Ext.toolbar.Toolbar',
'Ext.form.field.Text',
'Ext.form.field.TextArea',
'Ext.button.Button',
'Ext.layout.container.Anchor',
'Ext.layout.container.HBox',
'Ext.ProgressBar'
],
alias: 'widget.messagebox',
OK: 1,
YES: 2,
NO: 4,
CANCEL: 8,
OKCANCEL: 9,
YESNO: 6,
YESNOCANCEL: 14,
INFO: Ext.baseCSSPrefix + 'message-box-info',
WARNING: Ext.baseCSSPrefix + 'message-box-warning',
QUESTION: Ext.baseCSSPrefix + 'message-box-question',
ERROR: Ext.baseCSSPrefix + 'message-box-error',
hideMode: 'offsets',
closeAction: 'hide',
resizable: false,
scrollable: true,
title: '&#160;',
defaultMinWidth: 250,
defaultMaxWidth: 600,
defaultMinHeight: 110,
defaultMaxHeight: 500,
minWidth: null,
maxWidth: null,
minHeight: null,
maxHeight: null,
constrain: true,
cls: [
Ext.baseCSSPrefix + 'message-box',
Ext.baseCSSPrefix + 'hidden-offsets'
],
layout: {
type: 'vbox',
align: 'stretch'
},
shrinkWrapDock: true,
defaultTextHeight: 75,
minProgressWidth: 250,
minPromptWidth: 250,
buttonText: {
ok: 'OK',
yes: 'Yes',
no: 'No',
cancel: 'Cancel'
},
buttonIds: [
'ok',
'yes',
'no',
'cancel'
],
titleText: {
confirm: 'Confirm',
prompt: 'Prompt',
wait: 'Loading...',
alert: 'Attention'
},
baseIconCls: Ext.baseCSSPrefix + 'message-box-icon',
ariaRole: 'alertdialog',
makeButton: function(btnIdx) {
var btnId = this.buttonIds[btnIdx];
return new Ext.button.Button({
handler: this.btnCallback,
itemId: btnId,
scope: this,
text: this.buttonText[btnId],
minWidth: 75
});
},
btnCallback: function(btn, event) {
var me = this,
value, field;
if (event && event.type === 'keydown' && !event.isSpecialKey()) {
event.getTarget(null, null, true).on({
keyup: function(e) {
me.btnCallback(btn, e);
},
single: true
});
return;
}
if (me.cfg.prompt || me.cfg.multiline) {
if (me.cfg.multiline) {
field = me.textArea;
} else {
field = me.textField;
}
value = field.getValue();
field.reset();
}
me.hide();
me.userCallback(btn.itemId, value, me.cfg);
},
hide: function() {
var me = this,
cls = me.cfg ? me.cfg.cls : '';
me.progressBar.reset();
if (cls) {
me.removeCls(cls);
}
me.callParent(arguments);
},
constructor: function(cfg) {
var me = this;
me.callParent(arguments);
me.minWidth = me.defaultMinWidth = (me.minWidth || me.defaultMinWidth);
me.maxWidth = me.defaultMaxWidth = (me.maxWidth || me.defaultMaxWidth);
me.minHeight = me.defaultMinHeight = (me.minHeight || me.defaultMinHeight);
me.maxHeight = me.defaultMaxHeight = (me.maxHeight || me.defaultMaxHeight);
},
initComponent: function(cfg) {
var me = this,
baseId = me.id,
i, button;
me.title = me.title || '&#160;';
me.iconCls = me.iconCls || '';
me.topContainer = new Ext.container.Container({
layout: 'hbox',
padding: 10,
style: {
overflow: 'hidden'
},
items: [
me.iconComponent = new Ext.Component({
cls: me.baseIconCls
}),
me.promptContainer = new Ext.container.Container({
flex: 1,
layout: {
type: 'vbox',
align: 'stretch'
},
items: [
me.msg = new Ext.Component({
id: baseId + '-msg',
cls: me.baseCls + '-text'
}),
me.textField = new Ext.form.field.Text({
id: baseId + '-textfield',
enableKeyEvents: true,
listeners: {
keydown: me.onPromptKey,
scope: me
}
}),
me.textArea = new Ext.form.field.TextArea({
id: baseId + '-textarea',
height: 75
})
]
})
]
});
me.progressBar = new Ext.ProgressBar({
id: baseId + '-progressbar',
margin: '0 10 10 10'
});
me.items = [
me.topContainer,
me.progressBar
];
me.msgButtons = [];
for (i = 0; i < 4; i++) {
button = me.makeButton(i);
me.msgButtons[button.itemId] = button;
me.msgButtons.push(button);
}
me.bottomTb = new Ext.toolbar.Toolbar({
id: baseId + '-toolbar',
ui: 'footer',
dock: 'bottom',
layout: {
pack: 'center'
},
items: [
me.msgButtons[0],
me.msgButtons[1],
me.msgButtons[2],
me.msgButtons[3]
]
});
me.dockedItems = [
me.bottomTb
];
me.on('close', me.onClose, me);
me.callParent();
},
onClose: function() {
var btn = this.header.child('[type=close]');
btn.itemId = 'cancel';
this.btnCallback(btn);
delete btn.itemId;
},
onPromptKey: function(textField, e) {
var me = this;
if (e.keyCode === e.RETURN || e.keyCode === 10) {
if (me.msgButtons.ok.isVisible()) {
me.msgButtons.ok.handler.call(me, me.msgButtons.ok);
} else if (me.msgButtons.yes.isVisible()) {
me.msgButtons.yes.handler.call(me, me.msgButtons.yes);
}
}
},
reconfigure: function(cfg) {
var me = this,
buttons = 0,
hideToolbar = true,
oldButtonText = me.buttonText,
resizer = me.resizer,
header = me.header,
headerCfg = header && !header.isHeader,
message = cfg && (cfg.message || cfg.msg),
resizeTracker, width, height, i, textArea, textField, msg, progressBar, msgButtons, wait;
me.updateButtonText();
me.cfg = cfg = cfg || {};
wait = cfg.wait;
if (cfg.width) {
width = cfg.width;
}
if (cfg.height) {
height = cfg.height;
}
me.minWidth = cfg.minWidth || me.defaultMinWidth;
me.maxWidth = cfg.maxWidth || me.defaultMaxWidth;
me.minHeight = cfg.minHeight || me.defaultMinHeight;
me.maxHeight = cfg.maxHeight || me.defaultMaxHeight;
if (resizer) {
resizeTracker = resizer.resizeTracker;
resizer.minWidth = resizeTracker.minWidth = me.minWidth;
resizer.maxWidth = resizeTracker.maxWidth = me.maxWidth;
resizer.minHeight = resizeTracker.minHeight = me.minHeight;
resizer.maxHeight = resizeTracker.maxHeight = me.maxHeight;
}
delete me.defaultFocus;
if (cfg.defaultFocus) {
me.defaultFocus = cfg.defaultFocus;
}
me.animateTarget = cfg.animateTarget || undefined;
me.modal = cfg.modal !== false;
me.setTitle(cfg.title || (headerCfg && header.title) || me.title);
me.setIconCls(cfg.iconCls || (headerCfg && header.iconCls) || me.iconCls);
if (Ext.isObject(cfg.buttons)) {
me.buttonText = cfg.buttons;
buttons = 0;
} else {
me.buttonText = cfg.buttonText || me.buttonText;
buttons = Ext.isNumber(cfg.buttons) ? cfg.buttons : 0;
}
buttons = buttons | me.updateButtonText();
me.buttonText = oldButtonText;
Ext.suspendLayouts();
me.width = me.height = null;
if (width || height) {
if (width) {
me.setWidth(width);
}
if (height) {
me.setHeight(height);
}
}
me.hidden = false;
if (!me.rendered) {
me.render(Ext.getBody());
}
me.closable = cfg.closable !== false && !wait;
header = me.header;
if (header) {
header.child('[type=close]').setVisible(me.closable);
if (!cfg.title && !me.closable && !cfg.iconCls) {
header.hide();
} else {
header.show();
}
}
me.liveDrag = !cfg.proxyDrag;
me.userCallback = Ext.Function.bindCallback(cfg.callback || cfg.fn || Ext.emptyFn, cfg.scope || Ext.global);
me.setIcon(cfg.icon);
msg = me.msg;
if (message) {
msg.setHtml(message);
msg.show();
} else {
msg.hide();
}
textArea = me.textArea;
textField = me.textField;
if (cfg.prompt || cfg.multiline) {
me.multiline = cfg.multiline;
if (cfg.multiline) {
textArea.setValue(cfg.value);
textArea.setHeight(cfg.defaultTextHeight || me.defaultTextHeight);
textArea.show();
textField.hide();
me.defaultFocus = textArea;
} else {
textField.setValue(cfg.value);
textArea.hide();
textField.show();
me.defaultFocus = textField;
}
} else {
textArea.hide();
textField.hide();
}
progressBar = me.progressBar;
if (cfg.progress || wait) {
progressBar.show();
me.updateProgress(0, cfg.progressText);
if (wait) {
progressBar.wait(wait === true ? cfg.waitConfig : wait);
}
} else {
progressBar.hide();
}
msgButtons = me.msgButtons;
for (i = 0; i < 4; i++) {
if (buttons & Math.pow(2, i)) {
if (!me.defaultFocus) {
me.defaultFocus = msgButtons[i];
}
msgButtons[i].show();
hideToolbar = false;
} else {
msgButtons[i].hide();
}
}
if (hideToolbar) {
me.bottomTb.hide();
} else {
me.bottomTb.show();
}
Ext.resumeLayouts(true);
},
updateButtonText: function() {
var me = this,
buttonText = me.buttonText,
buttons = 0,
btnId, btn;
for (btnId in buttonText) {
if (buttonText.hasOwnProperty(btnId)) {
btn = me.msgButtons[btnId];
if (btn) {
if (me.cfg && me.cfg.buttonText) {
buttons = buttons | Math.pow(2, Ext.Array.indexOf(me.buttonIds, btnId));
}
if (btn.text !== buttonText[btnId]) {
btn.setText(buttonText[btnId]);
}
}
}
}
return buttons;
},
show: function(cfg) {
var me = this,
visibleFocusables;
cfg = cfg || {};
if (Ext.Component.layoutSuspendCount) {
Ext.on({
resumelayouts: function() {
me.show(cfg);
},
single: true
});
return me;
}
me.reconfigure(cfg);
if (cfg.cls) {
me.addCls(cfg.cls);
}
visibleFocusables = me.query('textfield:not([hidden]),textarea:not([hidden]),button:not([hidden])');
me.preventFocusOnActivate = !visibleFocusables.length;
me.hidden = true;
me.callParent();
return me;
},
onShow: function() {
this.callParent(arguments);
this.center();
},
updateText: function(text) {
this.msg.setHtml(text);
},
setIcon: function(icon, width, height) {
var me = this,
iconCmp = me.iconComponent,
cls = me.messageIconCls;
if (cls) {
iconCmp.removeCls(cls);
}
if (icon) {
iconCmp.show();
if (width || height) {
iconCmp.setSize(width || iconCmp.getWidth(), height || iconCmp.getHeight());
}
iconCmp.addCls(Ext.baseCSSPrefix + 'dlg-icon');
iconCmp.addCls(me.messageIconCls = icon);
} else {
iconCmp.removeCls(Ext.baseCSSPrefix + 'dlg-icon');
iconCmp.hide();
}
return me;
},
updateProgress: function(value, progressText, message) {
this.progressBar.updateProgress(value, progressText);
if (message) {
this.updateText(message);
}
return this;
},
onEsc: function() {
if (this.closable !== false) {
this.callParent(arguments);
}
},
confirm: function(cfg, message, fn, scope) {
if (Ext.isString(cfg)) {
cfg = {
title: cfg,
icon: this.QUESTION,
message: message,
buttons: this.YESNO,
callback: fn,
scope: scope
};
}
return this.show(cfg);
},
prompt: function(title, message, fn, scope, multiline, value) {
if (Ext.isString(title)) {
title = {
prompt: true,
title: title,
minWidth: this.minPromptWidth,
message: message,
buttons: this.OKCANCEL,
callback: fn,
scope: scope,
multiline: multiline,
value: value
};
}
return this.show(title);
},
wait: function(message, title, config) {
if (Ext.isString(message)) {
message = {
title: title,
message: message,
closable: false,
wait: true,
modal: true,
minWidth: this.minProgressWidth,
waitConfig: config
};
}
return this.show(message);
},
alert: function(title, message, fn, scope) {
if (Ext.isString(title)) {
title = {
title: title,
message: message,
buttons: this.OK,
fn: fn,
scope: scope,
minWidth: this.minWidth
};
}
return this.show(title);
},
progress: function(title, message, progressText) {
if (Ext.isString(title)) {
title = {
title: title,
message: message,
progress: true,
progressText: progressText
};
}
return this.show(title);
}
}, function(MessageBox) {
Ext.onInternalReady(function() {
Ext.MessageBox = Ext.Msg = new MessageBox();
});
});
Ext.define('Ext.form.Basic', {
extend: 'Ext.util.Observable',
alternateClassName: 'Ext.form.BasicForm',
requires: [
'Ext.util.MixedCollection',
'Ext.form.action.Load',
'Ext.form.action.Submit',
'Ext.window.MessageBox',
'Ext.data.ErrorCollection',
'Ext.util.DelayedTask'
],
taskDelay: 10,
constructor: function(owner, config) {
var me = this,
reader;
me.owner = owner;
me.fieldMonitors = {
validitychange: me.checkValidityDelay,
enable: me.checkValidityDelay,
disable: me.checkValidityDelay,
dirtychange: me.checkDirtyDelay,
errorchange: me.checkErrorDelay,
scope: me
};
me.checkValidityTask = new Ext.util.DelayedTask(me.checkValidity, me);
me.checkDirtyTask = new Ext.util.DelayedTask(me.checkDirty, me);
me.checkErrorTask = new Ext.util.DelayedTask(me.checkError, me);
me.monitor = new Ext.container.Monitor({
selector: '[isFormField]:not([excludeForm])',
scope: me,
addHandler: me.onFieldAdd,
removeHandler: me.onFieldRemove,
invalidateHandler: me.onMonitorInvalidate
});
me.monitor.bind(owner);
Ext.apply(me, config);
if (Ext.isString(me.paramOrder)) {
me.paramOrder = me.paramOrder.split(/[\s,|]/);
}
reader = me.reader;
if (reader && !reader.isReader) {
if (typeof reader === 'string') {
reader = {
type: reader
};
}
me.reader = Ext.createByAlias('reader.' + reader.type, reader);
}
reader = me.errorReader;
if (reader && !reader.isReader) {
if (typeof reader === 'string') {
reader = {
type: reader
};
}
me.errorReader = Ext.createByAlias('reader.' + reader.type, reader);
}
me.callParent();
},
initialize: function() {
this.initialized = true;
this.onValidityChange(!this.hasInvalidField());
},
timeout: 30,
paramsAsHash: false,
waitTitle: 'Please Wait...',
trackResetOnLoad: false,
wasDirty: false,
destroy: function() {
var me = this,
mon = me.monitor;
if (mon) {
mon.unbind();
me.monitor = null;
}
me.clearListeners();
me.checkValidityTask.cancel();
me.checkDirtyTask.cancel();
me.checkErrorTask.cancel();
me.checkValidityTask = me.checkDirtyTask = me.checkErrorTask = null;
me.isDestroyed = true;
},
onFieldAdd: function(field) {
field.on(this.fieldMonitors);
this.onMonitorInvalidate();
},
onFieldRemove: function(field) {
field.un(this.fieldMonitors);
this.onMonitorInvalidate();
},
onMonitorInvalidate: function() {
if (this.initialized) {
this.checkValidityDelay();
}
},
getFields: function() {
return this.monitor.getItems();
},
getBoundItems: function() {
var boundItems = this._boundItems;
if (!boundItems || boundItems.getCount() === 0) {
boundItems = this._boundItems = new Ext.util.MixedCollection();
boundItems.addAll(this.owner.query('[formBind]'));
}
return boundItems;
},
hasInvalidField: function() {
return !!this.getFields().findBy(function(field) {
var preventMark = field.preventMark,
isValid;
field.preventMark = true;
isValid = field.isValid();
field.preventMark = preventMark;
return !isValid;
});
},
isValid: function() {
var me = this,
invalid;
Ext.suspendLayouts();
invalid = me.getFields().filterBy(function(field) {
return !field.validate();
});
Ext.resumeLayouts(true);
return invalid.length < 1;
},
checkValidity: function() {
var me = this,
valid;
if (me.isDestroyed) {
return;
}
valid = !me.hasInvalidField();
if (valid !== me.wasValid) {
me.onValidityChange(valid);
me.fireEvent('validitychange', me, valid);
me.wasValid = valid;
}
},
checkValidityDelay: function() {
var timer = this.taskDelay;
if (timer) {
this.checkValidityTask.delay(timer);
} else {
this.checkValidity();
}
},
checkError: function() {
this.fireEvent('errorchange', this);
},
checkErrorDelay: function() {
var timer = this.taskDelay;
if (timer) {
this.checkErrorTask.delay(timer);
} else {
this.checkError();
}
},
onValidityChange: function(valid) {
var boundItems = this.getBoundItems(),
items, i, iLen, cmp;
if (boundItems) {
items = boundItems.items;
iLen = items.length;
for (i = 0; i < iLen; i++) {
cmp = items[i];
if (cmp.disabled === valid) {
cmp.setDisabled(!valid);
}
}
}
},
isDirty: function() {
return !!this.getFields().findBy(function(f) {
return f.isDirty();
});
},
checkDirtyDelay: function() {
var timer = this.taskDelay;
if (timer) {
this.checkDirtyTask.delay(timer);
} else {
this.checkDirty();
}
},
checkDirty: function() {
var me = this,
dirty;
if (me.isDestroyed) {
return;
}
dirty = this.isDirty();
if (dirty !== this.wasDirty) {
this.fireEvent('dirtychange', this, dirty);
this.wasDirty = dirty;
}
},
hasUpload: function() {
return !!this.getFields().findBy(function(f) {
return f.isFileUpload();
});
},
doAction: function(action, options) {
if (Ext.isString(action)) {
action = Ext.ClassManager.instantiateByAlias('formaction.' + action, Ext.apply({}, options, {
form: this
}));
}
if (this.fireEvent('beforeaction', this, action) !== false) {
this.beforeAction(action);
Ext.defer(action.run, 100, action);
}
return this;
},
submit: function(options) {
options = options || {};
var me = this,
action;
if (options.standardSubmit || me.standardSubmit) {
action = 'standardsubmit';
} else {
action = me.api ? 'directsubmit' : 'submit';
}
return me.doAction(action, options);
},
load: function(options) {
return this.doAction(this.api ? 'directload' : 'load', options);
},
updateRecord: function(record) {
record = record || this._record;
if (!record) {
Ext.Error.raise("A record is required.");
return this;
}
var fields = record.self.fields,
values = this.getFieldValues(),
obj = {},
i = 0,
len = fields.length,
name;
for (; i < len; ++i) {
name = fields[i].name;
if (values.hasOwnProperty(name)) {
obj[name] = values[name];
}
}
record.beginEdit();
record.set(obj);
record.endEdit();
return this;
},
loadRecord: function(record) {
this._record = record;
return this.setValues(record.getData());
},
getRecord: function() {
return this._record;
},
beforeAction: function(action) {
var me = this,
waitMsg = action.waitMsg,
maskCls = Ext.baseCSSPrefix + 'mask-loading',
fields = me.getFields().items,
f,
fLen = fields.length,
field, waitMsgTarget;
for (f = 0; f < fLen; f++) {
field = fields[f];
if (field.isFormField && field.syncValue) {
field.syncValue();
}
}
if (waitMsg) {
waitMsgTarget = me.waitMsgTarget;
if (waitMsgTarget === true) {
me.owner.el.mask(waitMsg, maskCls);
} else if (waitMsgTarget) {
waitMsgTarget = me.waitMsgTarget = Ext.get(waitMsgTarget);
waitMsgTarget.mask(waitMsg, maskCls);
} else {
me.floatingAncestor = me.owner.up('[floating]');
if (me.floatingAncestor) {
me.savePreventFocusOnActivate = me.floatingAncestor.preventFocusOnActivate;
me.floatingAncestor.preventFocusOnActivate = true;
}
Ext.MessageBox.wait(waitMsg, action.waitTitle || me.waitTitle);
}
}
},
afterAction: function(action, success) {
var me = this;
if (action.waitMsg) {
var messageBox = Ext.MessageBox,
waitMsgTarget = me.waitMsgTarget;
if (waitMsgTarget === true) {
me.owner.el.unmask();
} else if (waitMsgTarget) {
waitMsgTarget.unmask();
} else {
messageBox.hide();
}
}
if (me.floatingAncestor) {
me.floatingAncestor.preventFocusOnActivate = me.savePreventFocusOnActivate;
}
if (success) {
if (action.reset) {
me.reset();
}
Ext.callback(action.success, action.scope || action, [
me,
action
]);
me.fireEvent('actioncomplete', me, action);
} else {
Ext.callback(action.failure, action.scope || action, [
me,
action
]);
me.fireEvent('actionfailed', me, action);
}
},
findField: function(id) {
return this.getFields().findBy(function(f) {
return f.id === id || f.name === id || f.dataIndex === id;
});
},
markInvalid: function(errors) {
var me = this,
e, eLen, error, value, key;
function mark(fieldId, msg) {
var field = me.findField(fieldId);
if (field) {
field.markInvalid(msg);
}
}
if (Ext.isArray(errors)) {
eLen = errors.length;
for (e = 0; e < eLen; e++) {
error = errors[e];
mark(error.id || error.field, error.msg || error.message);
}
} else if (errors instanceof Ext.data.ErrorCollection) {
eLen = errors.items.length;
for (e = 0; e < eLen; e++) {
error = errors.items[e];
mark(error.field, error.message);
}
} else {
for (key in errors) {
if (errors.hasOwnProperty(key)) {
value = errors[key];
mark(key, value, errors);
}
}
}
return this;
},
setValues: function(values) {
var me = this,
v, vLen, val;
function setVal(fieldId, val) {
var field = me.findField(fieldId);
if (field) {
field.setValue(val);
if (me.trackResetOnLoad) {
field.resetOriginalValue();
}
}
}
Ext.suspendLayouts();
if (Ext.isArray(values)) {
vLen = values.length;
for (v = 0; v < vLen; v++) {
val = values[v];
setVal(val.id, val.value);
}
} else {
Ext.iterate(values, setVal);
}
Ext.resumeLayouts(true);
return this;
},
getValues: function(asString, dirtyOnly, includeEmptyText, useDataValues, isSubmitting) {
var values = {},
fields = this.getFields().items,
fLen = fields.length,
isArray = Ext.isArray,
field, data, val, bucket, name, f;
for (f = 0; f < fLen; f++) {
field = fields[f];
if (!dirtyOnly || field.isDirty()) {
data = field[useDataValues ? 'getModelData' : 'getSubmitData'](includeEmptyText, isSubmitting);
if (Ext.isObject(data)) {
for (name in data) {
if (data.hasOwnProperty(name)) {
val = data[name];
if (includeEmptyText && val === '') {
val = field.emptyText || '';
}
if (!field.isRadio) {
if (values.hasOwnProperty(name)) {
bucket = values[name];
if (!isArray(bucket)) {
bucket = values[name] = [
bucket
];
}
if (isArray(val)) {
values[name] = bucket.concat(val);
} else {
bucket.push(val);
}
} else {
values[name] = val;
}
} else {
values[name] = values[name] || val;
}
}
}
}
}
}
if (asString) {
values = Ext.Object.toQueryString(values);
}
return values;
},
getFieldValues: function(dirtyOnly) {
return this.getValues(false, dirtyOnly, false, true);
},
clearInvalid: function() {
Ext.suspendLayouts();
var me = this,
fields = me.getFields().items,
f,
fLen = fields.length;
for (f = 0; f < fLen; f++) {
fields[f].clearInvalid();
}
Ext.resumeLayouts(true);
return me;
},
reset: function(resetRecord) {
Ext.suspendLayouts();
var me = this,
fields = me.getFields().items,
f,
fLen = fields.length;
for (f = 0; f < fLen; f++) {
fields[f].reset();
}
Ext.resumeLayouts(true);
if (resetRecord === true) {
delete me._record;
}
return me;
},
applyToFields: function(obj) {
var fields = this.getFields().items,
f,
fLen = fields.length;
for (f = 0; f < fLen; f++) {
Ext.apply(fields[f], obj);
}
return this;
},
applyIfToFields: function(obj) {
var fields = this.getFields().items,
f,
fLen = fields.length;
for (f = 0; f < fLen; f++) {
Ext.applyIf(fields[f], obj);
}
return this;
}
});
Ext.define('Ext.form.FieldAncestor', {
extend: 'Ext.Mixin',
requires: [
'Ext.container.Monitor'
],
mixinConfig: {
id: 'fieldAncestor',
after: {
initInheritedState: 'initFieldInheritedState'
},
before: {
destroy: 'onBeforeDestroy'
}
},
initFieldAncestor: function() {
var me = this;
me.monitor = new Ext.container.Monitor({
scope: me,
selector: '[isFormField]:not([excludeForm])',
addHandler: me.onChildFieldAdd,
removeHandler: me.onChildFieldRemove
});
me.initFieldDefaults();
},
initMonitor: function() {
this.monitor.bind(this);
},
initFieldInheritedState: function(inheritedState) {
var inheritedFieldDefaults = inheritedState.fieldDefaults,
fieldDefaults = this.fieldDefaults;
if (fieldDefaults) {
if (inheritedFieldDefaults) {
inheritedState.fieldDefaults = Ext.apply(Ext.Object.chain(inheritedFieldDefaults), fieldDefaults);
} else {
inheritedState.fieldDefaults = fieldDefaults;
}
}
},
onChildFieldAdd: function(field) {
var me = this;
me.mon(field, 'errorchange', me.handleFieldErrorChange, me);
me.mon(field, 'validitychange', me.handleFieldValidityChange, me);
},
onChildFieldRemove: function(field) {
var me = this;
me.mun(field, 'errorchange', me.handleFieldErrorChange, me);
me.mun(field, 'validitychange', me.handleFieldValidityChange, me);
},
initFieldDefaults: function() {
if (!this.fieldDefaults) {
this.fieldDefaults = {};
}
},
handleFieldValidityChange: function(field, isValid) {
var me = this;
if (field !== me) {
me.fireEvent('fieldvaliditychange', me, field, isValid);
me.onFieldValidityChange(field, isValid);
}
},
handleFieldErrorChange: function(labelable, activeError) {
var me = this;
if (labelable !== me) {
me.fireEvent('fielderrorchange', me, labelable, activeError);
me.onFieldErrorChange(labelable, activeError);
}
},
onFieldValidityChange: Ext.emptyFn,
onFieldErrorChange: Ext.emptyFn,
onBeforeDestroy: function() {
this.monitor.unbind();
}
});
Ext.define('Ext.layout.component.field.FieldContainer', {
extend: 'Ext.layout.component.Auto',
alias: 'layout.fieldcontainer',
type: 'fieldcontainer',
waitForOuterHeightInDom: true,
waitForOuterWidthInDom: true,
beginLayout: function(ownerContext) {
var containerEl = this.owner.containerEl;
this.callParent(arguments);
ownerContext.hasRawContent = true;
containerEl.setStyle('width', '');
containerEl.setStyle('height', '');
ownerContext.containerElContext = ownerContext.getEl('containerEl');
},
measureContentHeight: function(ownerContext) {
return ownerContext.hasDomProp('containerLayoutDone') ? this.callParent(arguments) : NaN;
},
measureContentWidth: function(ownerContext) {
return ownerContext.hasDomProp('containerLayoutDone') ? this.callParent(arguments) : NaN;
},
publishInnerHeight: function(ownerContext, height) {
var owner = this.owner;
if (owner.labelAlign === 'top' && owner.hasVisibleLabel()) {
height -= owner.labelEl.getHeight();
}
if (owner.msgTarget === 'under' && owner.hasActiveError()) {
height -= owner.errorWrapEl.getHeight();
}
height -= owner.bodyEl.getPadding('tb');
ownerContext.containerElContext.setHeight(height);
},
publishInnerWidth: function(ownerContext, width) {
var owner = this.owner;
if (owner.labelAlign !== 'top' && owner.hasVisibleLabel()) {
width -= (owner.labelWidth + (owner.labelPad || 0));
}
if (owner.msgTarget === 'side' && owner.hasActiveError()) {
width -= owner.errorWrapEl.getWidth();
}
width -= owner.bodyEl.getPadding('lr');
ownerContext.containerElContext.setWidth(width);
}
});
Ext.define('Ext.form.FieldContainer', {
extend: 'Ext.container.Container',
mixins: {
labelable: 'Ext.form.Labelable',
fieldAncestor: 'Ext.form.FieldAncestor'
},
requires: 'Ext.layout.component.field.FieldContainer',
alias: 'widget.fieldcontainer',
componentLayout: 'fieldcontainer',
componentCls: Ext.baseCSSPrefix + 'form-fieldcontainer',
shrinkWrap: true,
childEls: [
'containerEl'
],
combineLabels: false,
labelConnector: ', ',
combineErrors: false,
maskOnDisable: false,
invalidCls: '',
fieldSubTpl: [
'<div id="{id}-containerEl" data-ref="containerEl" class="{containerElCls}" role="presentation">',
'{%this.renderContainer(out,values)%}',
'</div>'
],
initComponent: function() {
var me = this;
me.initLabelable();
me.initFieldAncestor();
me.callParent();
me.initMonitor();
},
onAdd: function(labelItem) {
var me = this;
if (labelItem.isLabelable && Ext.isGecko && me.layout.type === 'absolute' && !me.hideLabel && me.labelAlign !== 'top') {
labelItem.x += (me.labelWidth + me.labelPad);
}
me.callParent(arguments);
if (labelItem.isLabelable && me.combineLabels) {
labelItem.oldHideLabel = labelItem.hideLabel;
labelItem.hideLabel = true;
}
me.updateLabel();
},
onRemove: function(labelItem, isDestroying) {
var me = this;
me.callParent(arguments);
if (!isDestroying) {
if (labelItem.isLabelable && me.combineLabels) {
labelItem.hideLabel = labelItem.oldHideLabel;
}
me.updateLabel();
}
},
initRenderData: function() {
var me = this,
data = me.callParent();
data.containerElCls = me.containerElCls;
return Ext.applyIf(data, me.getLabelableRenderData());
},
getFieldLabel: function() {
var label = this.fieldLabel || '';
if (!label && this.combineLabels) {
label = Ext.Array.map(this.query('[isFieldLabelable]'), function(field) {
return field.getFieldLabel();
}).join(this.labelConnector);
}
return label;
},
getSubTplData: function() {
var ret = this.initRenderData();
Ext.apply(ret, this.subTplData);
return ret;
},
getSubTplMarkup: function(fieldData) {
var me = this,
tpl = me.getTpl('fieldSubTpl'),
html;
if (!tpl.renderContent) {
me.setupRenderTpl(tpl);
}
html = tpl.apply(me.getSubTplData(fieldData));
return html;
},
updateLabel: function() {
var me = this,
label = me.labelEl;
if (label) {
me.setFieldLabel(me.getFieldLabel());
}
},
onFieldErrorChange: function() {
if (this.combineErrors) {
var me = this,
oldError = me.getActiveError(),
invalidFields = Ext.Array.filter(me.query('[isFormField]'), function(field) {
return field.hasActiveError();
}),
newErrors = me.getCombinedErrors(invalidFields);
if (newErrors) {
me.setActiveErrors(newErrors);
} else {
me.unsetActiveError();
}
if (oldError !== me.getActiveError()) {
me.updateLayout();
}
}
},
getCombinedErrors: function(invalidFields) {
var errors = [],
f,
fLen = invalidFields.length,
field, activeErrors, a, aLen, error, label;
for (f = 0; f < fLen; f++) {
field = invalidFields[f];
activeErrors = field.getActiveErrors();
aLen = activeErrors.length;
for (a = 0; a < aLen; a++) {
error = activeErrors[a];
label = field.getFieldLabel();
errors.push((label ? label + ': ' : '') + error);
}
}
return errors;
},
privates: {
applyTargetCls: function(targetCls) {
var containerElCls = this.containerElCls;
this.containerElCls = containerElCls ? containerElCls + ' ' + targetCls : targetCls;
},
getTargetEl: function() {
return this.containerEl;
},
initRenderTpl: function() {
var me = this;
if (!me.hasOwnProperty('renderTpl')) {
me.renderTpl = me.getTpl('labelableRenderTpl');
}
return me.callParent();
}
}
});
Ext.define('Ext.layout.container.CheckboxGroup', {
extend: 'Ext.layout.container.Container',
alias: [
'layout.checkboxgroup'
],
autoFlex: true,
type: 'checkboxgroup',
createsInnerCt: true,
childEls: [
'innerCt'
],
renderTpl: [
'<table id="{ownerId}-innerCt" data-ref="innerCt" class="' + Ext.baseCSSPrefix + 'table-plain" cellpadding="0"',
'role="presentation" style="{tableStyle}"><tr role="presentation">',
'<tpl for="columns">',
'<td class="{parent.colCls}" valign="top" style="{style}" role="presentation">',
'{% this.renderColumn(out,parent,xindex-1) %}',
'</td>',
'</tpl>',
'</tr></table>'
],
lastOwnerItemsGeneration: null,
beginLayout: function(ownerContext) {
var me = this,
columns, numCols, i, width, cwidth,
totalFlex = 0,
flexedCols = 0,
autoFlex = me.autoFlex,
innerCtStyle = me.innerCt.dom.style;
me.callParent(arguments);
columns = me.columnNodes;
ownerContext.innerCtContext = ownerContext.getEl('innerCt', me);
if (!ownerContext.widthModel.shrinkWrap) {
numCols = columns.length;
if (me.columnsArray) {
for (i = 0; i < numCols; i++) {
width = me.owner.columns[i];
if (width < 1) {
totalFlex += width;
flexedCols++;
}
}
for (i = 0; i < numCols; i++) {
width = me.owner.columns[i];
if (width < 1) {
cwidth = ((width / totalFlex) * 100) + '%';
} else {
cwidth = width + 'px';
}
columns[i].style.width = cwidth;
}
} else
{
for (i = 0; i < numCols; i++) {
cwidth = autoFlex ? (1 / numCols * 100) + '%' : '';
columns[i].style.width = cwidth;
flexedCols++;
}
}
if (!flexedCols) {
innerCtStyle.tableLayout = 'fixed';
innerCtStyle.width = '';
}
else if (flexedCols < numCols) {
innerCtStyle.tableLayout = 'fixed';
innerCtStyle.width = '100%';
} else
{
innerCtStyle.tableLayout = 'auto';
if (autoFlex) {
innerCtStyle.width = '100%';
} else {
innerCtStyle.width = '';
}
}
} else {
innerCtStyle.tableLayout = 'auto';
innerCtStyle.width = '';
}
},
cacheElements: function() {
var me = this;
me.callParent();
me.rowEl = me.innerCt.down('tr');
me.columnNodes = me.rowEl.dom.childNodes;
},
calculate: function(ownerContext) {
var me = this,
targetContext, widthShrinkWrap, heightShrinkWrap, shrinkWrap, table, targetPadding;
if (!ownerContext.getDomProp('containerChildrenSizeDone')) {
me.done = false;
} else {
targetContext = ownerContext.innerCtContext;
widthShrinkWrap = ownerContext.widthModel.shrinkWrap;
heightShrinkWrap = ownerContext.heightModel.shrinkWrap;
shrinkWrap = heightShrinkWrap || widthShrinkWrap;
table = targetContext.el.dom;
targetPadding = shrinkWrap && targetContext.getPaddingInfo();
if (widthShrinkWrap) {
ownerContext.setContentWidth(table.offsetWidth + targetPadding.width, true);
}
if (heightShrinkWrap) {
ownerContext.setContentHeight(table.offsetHeight + targetPadding.height, true);
}
}
},
doRenderColumn: function(out, renderData, columnIndex) {
var me = renderData.$layout,
owner = me.owner,
columnCount = renderData.columnCount,
items = owner.items.items,
itemCount = items.length,
item, itemIndex, rowCount, increment, tree;
if (owner.vertical) {
rowCount = Math.ceil(itemCount / columnCount);
itemIndex = columnIndex * rowCount;
itemCount = Math.min(itemCount, itemIndex + rowCount);
increment = 1;
} else {
itemIndex = columnIndex;
increment = columnCount;
}
for (; itemIndex < itemCount; itemIndex += increment) {
item = items[itemIndex];
me.configureItem(item);
tree = item.getRenderTree();
Ext.DomHelper.generateMarkup(tree, out);
}
},
getColumnCount: function() {
var me = this,
owner = me.owner,
ownerColumns = owner.columns;
if (me.columnsArray) {
return ownerColumns.length;
}
if (Ext.isNumber(ownerColumns)) {
return ownerColumns;
}
return owner.items.length;
},
getItemSizePolicy: function(item) {
return this.autoSizePolicy;
},
getRenderData: function() {
var me = this,
data = me.callParent(),
owner = me.owner,
i,
columns = me.getColumnCount(),
width, column, cwidth,
autoFlex = me.autoFlex,
totalFlex = 0,
flexedCols = 0;
if (me.columnsArray) {
for (i = 0; i < columns; i++) {
width = me.owner.columns[i];
if (width < 1) {
totalFlex += width;
flexedCols++;
}
}
}
data.colCls = owner.groupCls;
data.columnCount = columns;
data.columns = [];
for (i = 0; i < columns; i++) {
column = (data.columns[i] = {});
if (me.columnsArray) {
width = me.owner.columns[i];
if (width < 1) {
cwidth = ((width / totalFlex) * 100) + '%';
} else {
cwidth = width + 'px';
}
column.style = 'width:' + cwidth;
} else {
column.style = 'width:' + (1 / columns * 100) + '%';
flexedCols++;
}
}
data.tableStyle = !flexedCols ? 'table-layout:fixed;' : (flexedCols < columns) ? 'table-layout:fixed;width:100%' : (autoFlex) ? 'table-layout:auto;width:100%' : 'table-layout:auto;';
return data;
},
initLayout: function() {
var me = this,
owner = me.owner;
me.columnsArray = Ext.isArray(owner.columns);
me.autoColumns = !owner.columns || owner.columns === 'auto';
me.vertical = owner.vertical;
me.callParent();
},
isValidParent: Ext.returnTrue,
setupRenderTpl: function(renderTpl) {
this.callParent(arguments);
renderTpl.renderColumn = this.doRenderColumn;
},
renderChildren: function() {
var me = this,
generation = me.owner.items.generation;
if (me.lastOwnerItemsGeneration !== generation) {
me.lastOwnerItemsGeneration = generation;
me.renderItems(me.getLayoutItems());
}
},
renderItems: function(items) {
var me = this,
itemCount = items.length,
i, item, rowCount, columnCount, rowIndex, columnIndex;
if (itemCount) {
Ext.suspendLayouts();
if (me.autoColumns) {
me.addMissingColumns(itemCount);
}
columnCount = me.columnNodes.length;
rowCount = Math.ceil(itemCount / columnCount);
for (i = 0; i < itemCount; i++) {
item = items[i];
rowIndex = me.getRenderRowIndex(i, rowCount, columnCount);
columnIndex = me.getRenderColumnIndex(i, rowCount, columnCount);
if (!item.rendered) {
me.renderItem(item, rowIndex, columnIndex);
} else if (!me.isItemAtPosition(item, rowIndex, columnIndex)) {
me.moveItem(item, rowIndex, columnIndex);
}
}
if (me.autoColumns) {
me.removeExceedingColumns(itemCount);
}
Ext.resumeLayouts(true);
}
},
isItemAtPosition: function(item, rowIndex, columnIndex) {
return item.el.dom === this.getNodeAt(rowIndex, columnIndex);
},
getRenderColumnIndex: function(itemIndex, rowCount, columnCount) {
if (this.vertical) {
return Math.floor(itemIndex / rowCount);
} else {
return itemIndex % columnCount;
}
},
getRenderRowIndex: function(itemIndex, rowCount, columnCount) {
var me = this;
if (me.vertical) {
return itemIndex % rowCount;
} else {
return Math.floor(itemIndex / columnCount);
}
},
getNodeAt: function(rowIndex, columnIndex) {
return this.columnNodes[columnIndex].childNodes[rowIndex];
},
addMissingColumns: function(itemsCount) {
var me = this,
existingColumnsCount = me.columnNodes.length,
missingColumnsCount, row, cls, i;
if (existingColumnsCount < itemsCount) {
missingColumnsCount = itemsCount - existingColumnsCount;
row = me.rowEl;
cls = me.owner.groupCls;
for (i = 0; i < missingColumnsCount; i++) {
row.createChild({
cls: cls,
tag: 'td',
vAlign: 'top',
role: 'presentation'
});
}
}
},
removeExceedingColumns: function(itemsCount) {
var me = this,
existingColumnsCount = me.columnNodes.length,
exceedingColumnsCount, row, i;
if (existingColumnsCount > itemsCount) {
exceedingColumnsCount = existingColumnsCount - itemsCount;
row = me.rowEl;
for (i = 0; i < exceedingColumnsCount; i++) {
row.last().destroy();
}
}
},
renderItem: function(item, rowIndex, columnIndex) {
var me = this;
me.configureItem(item);
item.render(Ext.get(me.columnNodes[columnIndex]), rowIndex);
},
moveItem: function(item, rowIndex, columnIndex) {
var me = this,
column = me.columnNodes[columnIndex],
targetNode = column.childNodes[rowIndex];
column.insertBefore(item.el.dom, targetNode || null);
}
});
Ext.define('Ext.form.CheckboxGroup', {
extend: 'Ext.form.FieldContainer',
mixins: {
field: 'Ext.form.field.Field'
},
alias: 'widget.checkboxgroup',
requires: [
'Ext.layout.container.CheckboxGroup',
'Ext.form.field.Checkbox',
'Ext.form.field.Base'
],
columns: 'auto',
vertical: false,
allowBlank: true,
blankText: "You must select at least one item in this group",
defaultType: 'checkboxfield',
groupCls: Ext.baseCSSPrefix + 'form-check-group',
extraFieldBodyCls: Ext.baseCSSPrefix + 'form-checkboxgroup-body',
layout: 'checkboxgroup',
componentCls: Ext.baseCSSPrefix + 'form-checkboxgroup',
ariaRole: 'group',
initComponent: function() {
var me = this;
me.callParent();
me.initField();
},
initValue: function() {
var me = this,
valueCfg = me.value;
me.originalValue = me.lastValue = valueCfg || me.getValue();
if (valueCfg) {
me.setValue(valueCfg);
}
},
onAdd: function(field) {
var me = this,
items, len, i;
if (field.isCheckbox) {
me.mon(field, 'change', me.checkChange, me);
} else if (field.isContainer) {
items = field.items.items;
for (i = 0 , len = items.length; i < len; i++) {
me.onAdd(items[i]);
}
}
me.callParent(arguments);
},
onRemove: function(item) {
var me = this,
items, len, i;
if (item.isCheckbox) {
me.mun(item, 'change', me.checkChange, me);
} else if (item.isContainer) {
items = item.items.items;
for (i = 0 , len = items.length; i < len; i++) {
me.onRemove(items[i]);
}
}
me.callParent(arguments);
},
isEqual: function(value1, value2) {
var toQueryString = Ext.Object.toQueryString;
return toQueryString(value1) === toQueryString(value2);
},
getErrors: function() {
var errors = [];
if (!this.allowBlank && Ext.isEmpty(this.getChecked())) {
errors.push(this.blankText);
}
return errors;
},
getBoxes: function(query) {
return this.query('[isCheckbox]' + (query || ''));
},
eachBox: function(fn, scope) {
Ext.Array.forEach(this.getBoxes(), fn, scope || this);
},
getChecked: function() {
return this.getBoxes('[checked]');
},
isDirty: function() {
var boxes = this.getBoxes(),
b,
bLen = boxes.length;
for (b = 0; b < bLen; b++) {
if (boxes[b].isDirty()) {
return true;
}
}
},
setReadOnly: function(readOnly) {
var boxes = this.getBoxes(),
b,
bLen = boxes.length;
for (b = 0; b < bLen; b++) {
boxes[b].setReadOnly(readOnly);
}
this.readOnly = readOnly;
},
reset: function() {
var me = this,
hadError = me.hasActiveError(),
preventMark = me.preventMark;
me.preventMark = true;
me.batchChanges(function() {
var boxes = me.getBoxes(),
b,
bLen = boxes.length;
for (b = 0; b < bLen; b++) {
boxes[b].reset();
}
});
me.preventMark = preventMark;
me.unsetActiveError();
if (hadError) {
me.updateLayout();
}
},
resetOriginalValue: function() {
var me = this,
boxes = me.getBoxes(),
b,
bLen = boxes.length;
for (b = 0; b < bLen; b++) {
boxes[b].resetOriginalValue();
}
me.originalValue = me.getValue();
me.checkDirty();
},
setValue: function(value) {
var me = this,
boxes = me.getBoxes(),
b,
bLen = boxes.length,
box, name, cbValue;
me.batchChanges(function() {
Ext.suspendLayouts();
for (b = 0; b < bLen; b++) {
box = boxes[b];
name = box.getName();
cbValue = false;
if (value) {
if (Ext.isArray(value[name])) {
cbValue = Ext.Array.contains(value[name], box.inputValue);
} else {
cbValue = value[name];
}
}
box.setValue(cbValue);
}
Ext.resumeLayouts(true);
});
return me;
},
getValue: function() {
var values = {},
boxes = this.getBoxes(),
b,
bLen = boxes.length,
box, name, inputValue, bucket;
for (b = 0; b < bLen; b++) {
box = boxes[b];
name = box.getName();
inputValue = box.inputValue;
if (box.getValue()) {
if (values.hasOwnProperty(name)) {
bucket = values[name];
if (!Ext.isArray(bucket)) {
bucket = values[name] = [
bucket
];
}
bucket.push(inputValue);
} else {
values[name] = inputValue;
}
}
}
return values;
},
getSubmitData: function() {
return null;
},
getModelData: function() {
return null;
},
validate: function() {
var me = this,
errors, isValid, wasValid;
if (me.disabled) {
isValid = true;
} else {
errors = me.getErrors();
isValid = Ext.isEmpty(errors);
wasValid = me.wasValid;
if (isValid) {
me.unsetActiveError();
} else {
me.setActiveError(errors);
}
}
if (isValid !== wasValid) {
me.wasValid = isValid;
me.fireEvent('validitychange', me, isValid);
me.updateLayout();
}
return isValid;
}
}, function() {
this.borrow(Ext.form.field.Base, [
'markInvalid',
'clearInvalid',
'setError'
]);
});
Ext.define('Ext.form.FieldSet', {
extend: 'Ext.container.Container',
mixins: {
fieldAncestor: 'Ext.form.FieldAncestor'
},
alias: 'widget.fieldset',
uses: [
'Ext.form.field.Checkbox',
'Ext.panel.Tool',
'Ext.layout.container.Anchor',
'Ext.layout.component.FieldSet'
],
focusable: true,
checkboxUI: 'default',
collapsed: false,
toggleOnTitleClick: true,
baseCls: Ext.baseCSSPrefix + 'fieldset',
layout: 'anchor',
componentLayout: 'fieldset',
ariaRole: null,
autoEl: 'fieldset',
childEls: [
'body'
],
renderTpl: [
'{%this.renderLegend(out,values);%}',
'<div id="{id}-body" data-ref="body" class="{baseCls}-body {baseCls}-body-{ui} {bodyTargetCls}" ',
'role="presentation"<tpl if="bodyStyle"> style="{bodyStyle}"</tpl>>',
'{%this.renderContainer(out,values);%}',
'</div>'
],
stateEvents: [
'collapse',
'expand'
],
maskOnDisable: false,
beforeDestroy: function() {
var me = this,
legend = me.legend;
if (legend) {
delete legend.ownerCt;
legend.destroy();
me.legend = null;
}
me.callParent();
},
initComponent: function() {
var me = this,
baseCls = me.baseCls;
me.initFieldAncestor();
me.callParent();
me.layout.managePadding = me.layout.manageOverflow = false;
if (me.collapsed) {
me.addCls(baseCls + '-collapsed');
me.collapse();
}
if (me.title || me.checkboxToggle || me.collapsible) {
me.addTitleClasses();
me.legend = Ext.widget(me.createLegendCt());
}
me.initMonitor();
},
initRenderData: function() {
var me = this,
data = me.callParent();
data.bodyTargetCls = me.bodyTargetCls;
me.protoBody.writeTo(data);
delete me.protoBody;
return data;
},
getState: function() {
var state = this.callParent();
state = this.addPropertyToState(state, 'collapsed');
return state;
},
afterCollapse: Ext.emptyFn,
afterExpand: Ext.emptyFn,
collapsedHorizontal: function() {
return true;
},
collapsedVertical: function() {
return true;
},
createLegendCt: function() {
var me = this,
items = [],
legend = {
xtype: 'container',
baseCls: me.baseCls + '-header',
layout: 'container',
ui: me.ui,
id: me.id + '-legend',
autoEl: 'legend',
ariaRole: null,
ariaLabelledBy: '.' + me.baseCls + '-header-text',
items: items,
ownerCt: me,
shrinkWrap: true,
ownerLayout: me.componentLayout
};
if (me.checkboxToggle) {
items.push(me.createCheckboxCmp());
} else if (me.collapsible) {
items.push(me.createToggleCmp());
}
items.push(me.createTitleCmp());
return legend;
},
createTitleCmp: function() {
var me = this,
cfg = {
xtype: 'component',
html: me.title,
ui: me.ui,
cls: me.baseCls + '-header-text',
id: me.id + '-legendTitle'
};
if (me.collapsible && me.toggleOnTitleClick) {
cfg.listeners = {
click: {
element: 'el',
scope: me,
fn: me.toggle
}
};
cfg.cls += ' ' + me.baseCls + '-header-text-collapsible';
}
return (me.titleCmp = Ext.widget(cfg));
},
createCheckboxCmp: function() {
var me = this,
suffix = '-checkbox',
cls = me.baseCls + '-header' + suffix;
cls += ' ' + cls + '-' + me.ui;
me.checkboxCmp = Ext.widget({
xtype: 'checkbox',
hideEmptyLabel: true,
name: me.checkboxName || me.id + suffix,
cls: cls,
id: me.id + '-legendChk',
ui: me.checkboxUI,
checked: !me.collapsed,
msgTarget: 'none',
listeners: {
change: me.onCheckChange,
scope: me
}
});
return me.checkboxCmp;
},
createToggleCmp: function() {
var me = this;
me.toggleCmp = Ext.widget({
xtype: 'tool',
cacheHeight: false,
cls: me.baseCls + '-header-tool-' + me.ui,
type: 'toggle',
handler: me.toggle,
id: me.id + '-legendToggle',
scope: me
});
return me.toggleCmp;
},
doRenderLegend: function(out, renderData) {
var me = renderData.$comp,
legend = me.legend,
tree;
if (legend) {
legend.ownerLayout.configureItem(legend);
tree = legend.getRenderTree();
Ext.DomHelper.generateMarkup(tree, out);
}
},
getCollapsed: function() {
return this.collapsed ? 'top' : false;
},
getCollapsedDockedItems: function() {
var legend = this.legend;
return legend ? [
legend
] : [];
},
setTitle: function(title) {
var me = this,
legend = me.legend;
me.title = title;
if (me.rendered) {
if (!legend) {
me.legend = legend = Ext.widget(me.createLegendCt());
me.addTitleClasses();
legend.ownerLayout.configureItem(legend);
legend.render(me.el, 0);
}
me.titleCmp.update(title);
} else if (legend) {
me.titleCmp.update(title);
} else {
me.addTitleClasses();
me.legend = Ext.widget(me.createLegendCt());
}
return me;
},
addTitleClasses: function() {
var me = this,
title = me.title,
baseCls = me.baseCls;
if (title) {
me.addCls(baseCls + '-with-title');
}
if (title || me.checkboxToggle || me.collapsible) {
me.addCls(baseCls + '-with-legend');
}
},
expand: function() {
return this.setExpanded(true);
},
collapse: function() {
return this.setExpanded(false);
},
setExpanded: function(expanded) {
var me = this,
checkboxCmp = me.checkboxCmp,
operation = expanded ? 'expand' : 'collapse';
if (!me.rendered || me.fireEvent('before' + operation, me) !== false) {
expanded = !!expanded;
if (checkboxCmp) {
checkboxCmp.setValue(expanded);
}
if (expanded) {
me.removeCls(me.baseCls + '-collapsed');
} else {
me.addCls(me.baseCls + '-collapsed');
}
me.collapsed = !expanded;
if (expanded) {
delete me.getInherited().collapsed;
} else {
me.getInherited().collapsed = true;
}
if (me.rendered) {
me.updateLayout({
isRoot: false
});
me.fireEvent(operation, me);
}
}
return me;
},
getRefItems: function(deep) {
var refItems = this.callParent(arguments),
legend = this.legend;
if (legend) {
refItems.unshift(legend);
if (deep) {
refItems.unshift.apply(refItems, legend.getRefItems(true));
}
}
return refItems;
},
toggle: function() {
this.setExpanded(!!this.collapsed);
},
privates: {
applyTargetCls: function(targetCls) {
this.bodyTargetCls = targetCls;
},
finishRender: function() {
var legend = this.legend;
this.callParent();
if (legend) {
legend.finishRender();
}
},
getProtoBody: function() {
var me = this,
body = me.protoBody;
if (!body) {
me.protoBody = body = new Ext.util.ProtoElement({
styleProp: 'bodyStyle',
styleIsText: true
});
}
return body;
},
getDefaultContentTarget: function() {
return this.body;
},
getTargetEl: function() {
return this.body || this.frameBody || this.el;
},
initPadding: function(targetEl) {
var me = this,
body = me.getProtoBody(),
padding = me.padding,
bodyPadding;
if (padding !== undefined) {
if (Ext.isIE8) {
padding = me.parseBox(padding);
bodyPadding = Ext.Element.parseBox(0);
bodyPadding.top = padding.top;
padding.top = 0;
body.setStyle('padding', me.unitizeBox(bodyPadding));
}
targetEl.setStyle('padding', me.unitizeBox(padding));
}
},
onCheckChange: function(cmp, checked) {
this.setExpanded(checked);
},
setupRenderTpl: function(renderTpl) {
this.callParent(arguments);
renderTpl.renderLegend = this.doRenderLegend;
}
}
});
Ext.define('Ext.form.Label', {
extend: 'Ext.Component',
alias: 'widget.label',
requires: [
'Ext.util.Format'
],
autoEl: 'label',
maskOnDisable: false,
getElConfig: function() {
var me = this;
me.html = me.text ? Ext.util.Format.htmlEncode(me.text) : (me.html || '');
return Ext.apply(me.callParent(), {
htmlFor: me.forId || ''
});
},
setText: function(text, encode) {
var me = this;
encode = encode !== false;
if (encode) {
me.text = text;
delete me.html;
} else {
me.html = text;
delete me.text;
}
if (me.rendered) {
me.el.dom.innerHTML = encode !== false ? Ext.util.Format.htmlEncode(text) : text;
me.updateLayout();
}
return me;
}
});
Ext.define('Ext.form.Panel', {
extend: 'Ext.panel.Panel',
mixins: {
fieldAncestor: 'Ext.form.FieldAncestor'
},
alias: 'widget.form',
alternateClassName: [
'Ext.FormPanel',
'Ext.form.FormPanel'
],
requires: [
'Ext.form.Basic',
'Ext.util.TaskRunner'
],
layout: 'anchor',
ariaRole: 'form',
basicFormConfigs: [
'api',
'baseParams',
'errorReader',
'jsonSubmit',
'method',
'paramOrder',
'paramsAsHash',
'reader',
'standardSubmit',
'timeout',
'trackResetOnLoad',
'url',
'waitMsgTarget',
'waitTitle'
],
initComponent: function() {
var me = this;
if (me.frame) {
me.border = false;
}
me.initFieldAncestor();
me.callParent();
me.relayEvents(me.form, [
'beforeaction',
'actionfailed',
'actioncomplete',
'validitychange',
'dirtychange'
]);
if (me.pollForChanges) {
me.startPolling(me.pollInterval || 500);
}
},
initItems: function() {
this.callParent();
this.initMonitor();
this.form = this.createForm();
},
afterFirstLayout: function() {
this.callParent(arguments);
this.form.initialize();
},
createForm: function() {
var cfg = {},
props = this.basicFormConfigs,
len = props.length,
i = 0,
prop;
for (; i < len; ++i) {
prop = props[i];
cfg[prop] = this[prop];
}
return new Ext.form.Basic(this, cfg);
},
getForm: function() {
return this.form;
},
loadRecord: function(record) {
return this.getForm().loadRecord(record);
},
getRecord: function() {
return this.getForm().getRecord();
},
updateRecord: function(record) {
return this.getForm().updateRecord(record);
},
getValues: function(asString, dirtyOnly, includeEmptyText, useDataValues) {
return this.getForm().getValues(asString, dirtyOnly, includeEmptyText, useDataValues);
},
isDirty: function() {
return this.form.isDirty();
},
isValid: function() {
return this.form.isValid();
},
reset: function() {
this.form.reset();
},
hasInvalidField: function() {
return this.form.hasInvalidField();
},
beforeDestroy: function() {
this.stopPolling();
this.form.destroy();
this.callParent();
},
load: function(options) {
this.form.load(options);
},
submit: function(options) {
this.form.submit(options);
},
startPolling: function(interval) {
this.stopPolling();
var task = new Ext.util.TaskRunner(interval);
task.start({
interval: 0,
run: this.checkChange,
scope: this
});
this.pollTask = task;
},
stopPolling: function() {
var task = this.pollTask;
if (task) {
task.stopAll();
delete this.pollTask;
}
},
checkChange: function() {
var fields = this.form.getFields().items,
f,
fLen = fields.length;
for (f = 0; f < fLen; f++) {
fields[f].checkChange();
}
}
});
Ext.define('Ext.form.RadioManager', {
extend: 'Ext.util.MixedCollection',
singleton: true,
getByName: function(name, formId) {
return this.filterBy(function(item) {
return item.name === name && item.getFormId() === formId;
});
},
getWithValue: function(name, value, formId) {
return this.filterBy(function(item) {
return item.name === name && item.inputValue == value &&
item.getFormId() === formId;
});
},
getChecked: function(name, formId) {
return this.findBy(function(item) {
return item.name === name && item.checked && item.getFormId() === formId;
});
}
});
Ext.define('Ext.form.field.Radio', {
extend: 'Ext.form.field.Checkbox',
alias: [
'widget.radiofield',
'widget.radio'
],
alternateClassName: 'Ext.form.Radio',
requires: [
'Ext.form.RadioManager'
],
isRadio: true,
inputType: 'radio',
ariaRole: 'radio',
tabIndex: 0,
formId: null,
getGroupValue: function() {
var selected = this.getManager().getChecked(this.name, this.getFormId());
return selected ? selected.inputValue : null;
},
onBoxClick: function() {
var me = this;
if (!me.disabled && !me.readOnly) {
this.setValue(true);
}
},
onRemoved: function() {
this.callParent(arguments);
this.formId = null;
},
setValue: function(value) {
var me = this,
active;
if (Ext.isBoolean(value)) {
me.callParent(arguments);
} else {
active = me.getManager().getWithValue(me.name, value, me.getFormId()).getAt(0);
if (active) {
active.setValue(true);
}
}
return me;
},
getSubmitValue: function() {
return this.checked ? this.inputValue : null;
},
getModelData: function() {
var o = this.callParent(arguments);
if (o) {
o[this.getName()] = this.getSubmitValue();
}
return o;
},
onChange: function(newVal, oldVal) {
var me = this,
r, rLen, radio, radios;
me.callParent(arguments);
if (newVal) {
radios = me.getManager().getByName(me.name, me.getFormId()).items;
rLen = radios.length;
for (r = 0; r < rLen; r++) {
radio = radios[r];
if (radio !== me) {
radio.setValue(false);
}
}
}
},
getManager: function() {
return Ext.form.RadioManager;
}
});
Ext.define('Ext.form.RadioGroup', {
extend: 'Ext.form.CheckboxGroup',
alias: 'widget.radiogroup',
requires: [
'Ext.form.field.Radio'
],
mixins: [
'Ext.util.FocusableContainer'
],
allowBlank: true,
blankText: 'You must select one item in this group',
defaultType: 'radiofield',
groupCls: Ext.baseCSSPrefix + 'form-radio-group',
ariaRole: 'radiogroup',
getBoxes: function(query, root) {
return (root || this).query('[isRadio]' + (query || ''));
},
checkChange: function() {
var value = this.getValue(),
key = Ext.Object.getKeys(value)[0];
if (Ext.isArray(value[key])) {
return;
}
this.callParent(arguments);
},
setValue: function(value) {
var cbValue, first, formId, radios, i, len, name;
if (Ext.isObject(value)) {
Ext.suspendLayouts();
first = this.items.first();
formId = first ? first.getFormId() : null;
for (name in value) {
cbValue = value[name];
radios = Ext.form.RadioManager.getWithValue(name, cbValue, formId).items;
len = radios.length;
for (i = 0; i < len; ++i) {
radios[i].setValue(true);
}
}
Ext.resumeLayouts(true);
}
return this;
},
privates: {
getFocusables: function() {
return this.getBoxes();
},
initDefaultFocusable: function(beforeRender) {
var me = this,
checked, item;
checked = me.getChecked();
if (checked.length > 1) {
Ext.log.error("RadioGroup " + me.id + " has more than one checked button");
}
if (checked.length) {
item = checked[0];
} else {
item = me.findNextFocusableChild(null, true, null, beforeRender);
}
if (item) {
me.activateFocusable(item);
}
return item;
},
onFocusableContainerFocusLeave: function() {
this.clearFocusables();
this.initDefaultFocusable();
},
doFocusableChildAdd: function(child) {
var me = this,
mixin = me.mixins.focusablecontainer,
boxes, i, len;
boxes = child.isContainer ? me.getBoxes('', child) : [
child
];
for (i = 0 , len = boxes.length; i < len; i++) {
mixin.doFocusableChildAdd.call(me, boxes[i]);
}
},
doFocusableChildRemove: function(child) {
var me = this,
mixin = me.mixins.focusablecontainer,
boxes, i, len;
boxes = child.isContainer ? me.getBoxes('', child) : [
child
];
for (i = 0 , len = boxes.length; i < len; i++) {
mixin.doFocusableChildRemove.call(me, boxes[i]);
}
},
focusChild: function(radio, forward, e) {
var nextRadio = this.mixins.focusablecontainer.focusChild.apply(this, arguments);
if (!e.ctrlKey) {
nextRadio.setValue(true);
}
}
}
});
Ext.define('Ext.form.action.DirectAction', {
extend: 'Ext.Mixin',
mixinConfig: {
id: 'directaction'
},
resolveMethod: function(type) {
var me = this,
form = me.form,
api = form.api,
fn;
if (!api) {
Ext.Error.raise("Cannot resolve Ext.Direct API method for " + type + " action; form " + form.id + " has no api object defined");
}
fn = api[type];
if (typeof fn !== 'function') {
var fnName = fn;
api[type] = fn = Ext.direct.Manager.parseMethod(fn);
if (!Ext.isFunction(fn)) {
Ext.Error.raise("Cannot resolve Ext.Direct API method " + fnName + " for " + type + " action");
}
}
return fn;
}
});
Ext.define('Ext.form.action.DirectLoad', {
extend: 'Ext.form.action.Load',
alternateClassName: 'Ext.form.Action.DirectLoad',
alias: 'formaction.directload',
requires: [
'Ext.direct.Manager'
],
mixins: [
'Ext.form.action.DirectAction'
],
type: 'directload',
run: function() {
var me = this,
form = me.form,
metadata = me.metadata || form.metadata,
timeout = me.timeout || form.timeout,
args, fn;
fn = me.resolveMethod('load');
args = fn.directCfg.method.getArgs({
params: me.getParams(),
paramOrder: form.paramOrder,
paramsAsHash: form.paramsAsHash,
options: timeout != null ? {
timeout: timeout * 1000
} : null,
metadata: metadata,
callback: me.onComplete,
scope: me
});
fn.apply(window, args);
},
processResponse: function(result) {
return (this.result = result);
},
onComplete: function(data) {
if (data) {
this.onSuccess(data);
} else {
this.onFailure(null);
}
}
});
Ext.define('Ext.form.action.DirectSubmit', {
extend: 'Ext.form.action.Submit',
alternateClassName: 'Ext.form.Action.DirectSubmit',
alias: 'formaction.directsubmit',
requires: [
'Ext.direct.Manager'
],
mixins: [
'Ext.form.action.DirectAction'
],
type: 'directsubmit',
doSubmit: function() {
var me = this,
form = me.form,
metadata = me.metadata || form.metadata,
timeout = me.timeout || form.timeout,
fn, formInfo, args;
fn = me.resolveMethod('submit');
formInfo = me.buildForm();
args = fn.directCfg.method.getArgs({
params: formInfo.formEl,
options: timeout != null ? {
timeout: timeout * 1000
} : null,
metadata: metadata,
callback: me.onComplete,
scope: me
});
fn.apply(window, args);
me.cleanup(formInfo);
},
processResponse: function(result) {
return (this.result = result);
},
onComplete: function(data) {
if (data) {
this.onSuccess(data);
} else {
this.onFailure(null);
}
}
});
Ext.define('Ext.form.action.StandardSubmit', {
extend: 'Ext.form.action.Submit',
alias: 'formaction.standardsubmit',
doSubmit: function() {
var formInfo = this.buildForm();
formInfo.formEl.submit();
this.cleanup(formInfo);
}
});
Ext.define('Ext.form.field.Picker', {
extend: 'Ext.form.field.Text',
alias: 'widget.pickerfield',
alternateClassName: 'Ext.form.Picker',
requires: [
'Ext.util.KeyNav'
],
config: {
triggers: {
picker: {
handler: 'onTriggerClick',
scope: 'this'
}
}
},
isPickerField: true,
matchFieldWidth: true,
pickerAlign: 'tl-bl?',
openCls: Ext.baseCSSPrefix + 'pickerfield-open',
isExpanded: false,
editable: true,
applyTriggers: function(triggers) {
var me = this,
picker = triggers.picker;
if (!picker.cls) {
picker.cls = me.triggerCls;
}
return me.callParent([
triggers
]);
},
initEvents: function() {
var me = this;
me.callParent();
me.keyNav = new Ext.util.KeyNav(me.inputEl, {
down: me.onDownArrow,
esc: {
handler: me.onEsc,
scope: me,
defaultEventAction: false
},
scope: me,
forceKeyDown: true
});
if (!me.editable) {
me.mon(me.inputEl, 'click', me.onTriggerClick, me);
}
if (Ext.isGecko) {
me.inputEl.dom.setAttribute('autocomplete', 'off');
}
},
onEsc: function(e) {
if (Ext.isIE) {
e.preventDefault();
}
if (this.isExpanded) {
this.collapse();
e.stopEvent();
}
},
onDownArrow: function(e) {
if (!this.isExpanded) {
e.stopEvent();
this.onTriggerClick();
}
},
expand: function() {
var me = this,
bodyEl, picker, doc, collapseIf;
if (me.rendered && !me.isExpanded && !me.isDestroyed) {
bodyEl = me.bodyEl;
picker = me.getPicker();
doc = Ext.getDoc();
collapseIf = me.collapseIf;
picker.setMaxHeight(picker.initialConfig.maxHeight);
if (me.matchFieldWidth) {
picker.width = me.bodyEl.getWidth();
}
picker.show();
me.isExpanded = true;
me.alignPicker();
bodyEl.addCls(me.openCls);
me.hideListeners = doc.on({
mousewheel: me.collapseIf,
touchstart: me.collapseIf,
scope: me,
delegated: false,
destroyable: true
});
Ext.on('resize', me.alignPicker, me, {
buffer: 1
});
me.fireEvent('expand', me);
me.onExpand();
}
},
onExpand: Ext.emptyFn,
alignPicker: function() {
if (!this.isDestroyed) {
var picker = this.getPicker();
if (picker.isVisible() && picker.isFloating()) {
this.doAlign();
}
}
},
doAlign: function() {
var me = this,
picker = me.picker,
aboveSfx = '-above',
isAbove;
me.picker.alignTo(me.triggerWrap, me.pickerAlign, me.pickerOffset);
isAbove = picker.el.getY() < me.inputEl.getY();
me.bodyEl[isAbove ? 'addCls' : 'removeCls'](me.openCls + aboveSfx);
picker[isAbove ? 'addCls' : 'removeCls'](picker.baseCls + aboveSfx);
},
collapse: function() {
var me = this;
if (me.isExpanded && !me.isDestroyed && !me.destroying) {
var openCls = me.openCls,
picker = me.picker,
aboveSfx = '-above';
picker.hide();
me.isExpanded = false;
me.bodyEl.removeCls([
openCls,
openCls + aboveSfx
]);
picker.el.removeCls(picker.baseCls + aboveSfx);
me.hideListeners.destroy();
Ext.un('resize', me.alignPicker, me);
me.fireEvent('collapse', me);
me.onCollapse();
}
},
onCollapse: Ext.emptyFn,
collapseIf: function(e) {
var me = this;
if (!me.isDestroyed && !e.within(me.bodyEl, false, true) && !me.owns(e.target) && !Ext.fly(e.target).isFocusable()) {
me.collapse();
}
},
getPicker: function() {
var me = this,
picker = me.picker;
if (!picker) {
me.creatingPicker = true;
me.picker = picker = me.createPicker();
picker.ownerCmp = me;
delete me.creatingPicker;
}
return me.picker;
},
onFocusLeave: function(e) {
var me = this;
me.collapse();
me.callParent([
e
]);
},
getRefItems: function() {
var result = [];
if (this.picker) {
result[0] = this.picker;
}
return result;
},
createPicker: Ext.emptyFn,
onTriggerClick: function(e) {
var me = this;
if (!me.readOnly && !me.disabled) {
if (me.isExpanded) {
me.collapse();
} else {
me.expand();
}
}
},
beforeDestroy: function() {
var me = this,
picker = me.picker;
me.callParent();
Ext.un('resize', me.alignPicker, me);
Ext.destroy(me.keyNav, picker);
if (picker) {
me.picker = picker.pickerField = null;
}
}
});
Ext.define('Ext.view.BoundListKeyNav', {
extend: 'Ext.view.NavigationModel',
alias: 'view.navigation.boundlist',
navigateOnSpace: true,
initKeyNav: function(view) {
var me = this,
field = view.pickerField;
if (!me.keyNav) {
me.callParent([
view
]);
me.keyNav.map.addBinding({
key: Ext.event.Event.ESC,
fn: me.onKeyEsc,
scope: me
});
}
if (!field) {
return;
}
if (!field.rendered) {
field.on('render', Ext.Function.bind(me.initKeyNav, me, [
view
], 0), me, {
single: true
});
return;
}
me.fieldKeyNav = new Ext.util.KeyNav({
disabled: true,
target: field.inputEl,
forceKeyDown: true,
up: me.onKeyUp,
down: me.onKeyDown,
right: me.onKeyRight,
left: me.onKeyLeft,
pageDown: me.onKeyPageDown,
pageUp: me.onKeyPageUp,
home: me.onKeyHome,
end: me.onKeyEnd,
tab: me.onKeyTab,
space: me.onKeySpace,
enter: me.onKeyEnter,
A: {
ctrl: true,
handler: me.onSelectAllKeyPress
},
scope: me
});
},
processViewEvent: function(view, record, node, index, event) {
if (event.within(view.listWrap)) {
return event;
}
if (event.getKey() === event.ESC) {
if (Ext.fly(event.target).isInputField()) {
event.target = event.target.parentNode;
}
return event;
}
},
enable: function() {
this.fieldKeyNav.enable();
this.callParent();
},
disable: function() {
this.fieldKeyNav.disable();
this.callParent();
},
onItemMouseDown: function(view, record, item, index, event) {
this.callParent([
view,
record,
item,
index,
event
]);
event.preventDefault();
},
onKeyUp: function() {
var me = this,
boundList = me.view,
allItems = boundList.all,
oldItem = boundList.highlightedItem,
oldItemIdx = oldItem ? boundList.indexOf(oldItem) : -1,
newItemIdx = oldItemIdx > 0 ? oldItemIdx - 1 : allItems.getCount() - 1;
me.setPosition(newItemIdx);
},
onKeyDown: function() {
var me = this,
boundList = me.view,
allItems = boundList.all,
oldItem = boundList.highlightedItem,
oldItemIdx = oldItem ? boundList.indexOf(oldItem) : -1,
newItemIdx = oldItemIdx < allItems.getCount() - 1 ? oldItemIdx + 1 : 0;
me.setPosition(newItemIdx);
},
onKeyLeft: Ext.returnTrue,
onKeyRight: Ext.returnTrue,
onKeyTab: function(e) {
var view = this.view,
field = view.pickerField;
if (view.isVisible()) {
if (field.selectOnTab) {
this.selectHighlighted(e);
}
if (field.collapse) {
field.collapse();
}
}
return true;
},
onKeyEnter: function(e) {
var view = this.view,
selModel = view.getSelectionModel(),
field = view.pickerField,
count = selModel.getCount();
e.stopEvent();
this.selectHighlighted(e);
if (!field.multiSelect && count === selModel.getCount() && field.collapse) {
field.collapse();
}
},
onKeySpace: function() {
if (this.navigateOnSpace) {
this.callParent(arguments);
}
return true;
},
onKeyEsc: function() {
if (this.view.pickerField) {
this.view.pickerField.collapse();
}
},
focusItem: function(item) {
var me = this,
boundList = me.view;
if (typeof item === 'number') {
item = boundList.all.item(item);
}
if (item) {
item = item.dom;
boundList.highlightItem(item);
boundList.getScrollable().scrollIntoView(item, false);
}
},
selectHighlighted: function(e) {
var me = this,
boundList = me.view,
selModel = boundList.getSelectionModel(),
highlightedRec,
highlightedPosition = me.recordIndex;
if (boundList.all.getCount()) {
highlightedRec = me.getRecord();
if (highlightedRec) {
if (e.getKey() === e.ENTER || !selModel.isSelected(highlightedRec)) {
selModel.selectWithEvent(highlightedRec, e);
if (!boundList.store.data.contains(highlightedRec)) {
me.setPosition(Math.min(highlightedPosition, boundList.store.getCount() - 1));
}
}
}
}
},
destroy: function() {
Ext.destroy(this.fieldKeyNav);
this.callParent();
}
});
Ext.define('Ext.layout.component.BoundList', {
extend: 'Ext.layout.component.Auto',
alias: 'layout.boundlist',
type: 'component',
beginLayout: function(ownerContext) {
var me = this,
owner = me.owner,
toolbar = owner.pagingToolbar;
me.scrollPos = owner.listWrap.getScroll();
me.callParent(arguments);
if (owner.floating) {
ownerContext.savedXY = owner.getXY();
owner.setXY([
0,
-9999
]);
}
if (toolbar) {
ownerContext.toolbarContext = ownerContext.context.getCmp(toolbar);
}
ownerContext.listContext = ownerContext.getEl('listWrap');
},
beginLayoutCycle: function(ownerContext) {
var owner = this.owner;
this.callParent(arguments);
if (ownerContext.heightModel.auto) {
owner.el.setHeight('auto');
owner.listWrap.setHeight('auto');
}
},
getLayoutItems: function() {
var toolbar = this.owner.pagingToolbar;
return toolbar ? [
toolbar
] : [];
},
isValidParent: function() {
return true;
},
finishedLayout: function(ownerContext) {
var me = this,
xy = ownerContext.savedXY,
owner = me.owner,
listWrap = owner.listWrap,
scrollPos = me.scrollPos;
me.callParent(arguments);
if (xy) {
me.owner.setXY(xy);
}
listWrap.setScrollLeft(scrollPos.left);
listWrap.setScrollTop(scrollPos.top);
},
measureContentWidth: function(ownerContext) {
return this.owner.listWrap.getWidth();
},
measureContentHeight: function(ownerContext) {
return this.owner.listWrap.getHeight();
},
publishInnerHeight: function(ownerContext, height) {
var toolbar = ownerContext.toolbarContext,
toolbarHeight = 0;
if (toolbar) {
toolbarHeight = toolbar.getProp('height');
}
if (toolbarHeight === undefined) {
this.done = false;
} else {
ownerContext.listContext.setHeight(height - ownerContext.getFrameInfo().height - toolbarHeight);
}
},
calculateOwnerHeightFromContentHeight: function(ownerContext) {
var height = this.callParent(arguments),
toolbar = ownerContext.toolbarContext;
if (toolbar) {
height += toolbar.getProp('height');
}
return height;
}
});
Ext.define('Ext.toolbar.Item', {
extend: 'Ext.Component',
requires: [
'Ext.toolbar.Toolbar'
],
alias: 'widget.tbitem',
alternateClassName: 'Ext.Toolbar.Item',
enable: Ext.emptyFn,
disable: Ext.emptyFn,
focus: Ext.emptyFn
});
Ext.define('Ext.toolbar.TextItem', {
extend: 'Ext.toolbar.Item',
requires: [
'Ext.toolbar.Toolbar',
'Ext.XTemplate'
],
alias: 'widget.tbtext',
alternateClassName: 'Ext.Toolbar.TextItem',
text: '',
baseCls: Ext.baseCSSPrefix + 'toolbar-text',
ariaRole: null,
beforeRender: function() {
var text = this.text;
this.callParent();
if (text) {
this.html = text;
}
},
setText: function(text) {
this.update(text);
}
});
Ext.define('Ext.form.trigger.Spinner', {
extend: 'Ext.form.trigger.Trigger',
alias: 'trigger.spinner',
cls: Ext.baseCSSPrefix + 'form-trigger-spinner',
spinnerCls: Ext.baseCSSPrefix + 'form-spinner',
spinnerUpCls: Ext.baseCSSPrefix + 'form-spinner-up',
spinnerDownCls: Ext.baseCSSPrefix + 'form-spinner-down',
focusCls: Ext.baseCSSPrefix + 'form-spinner-focus',
overCls: Ext.baseCSSPrefix + 'form-spinner-over',
clickCls: Ext.baseCSSPrefix + 'form-spinner-click',
focusFieldOnClick: true,
vertical: true,
bodyTpl: '<tpl if="vertical">' + '<div class="{spinnerCls} {spinnerCls}-{ui} {spinnerUpCls} {spinnerUpCls}-{ui}' + ' {childElCls} {upDisabledCls}"></div>' + '</tpl>' + '<div class="{spinnerCls} {spinnerCls}-{ui} {spinnerDownCls} {spinnerDownCls}-{ui}' + ' {childElCls} {downDisabledCls}"></div>' + '<tpl if="!vertical">' + '<div class="{spinnerCls} {spinnerCls}-{ui} {spinnerUpCls} {spinnerUpCls}-{ui}' + ' {childElCls} {upDisabledCls}"></div>' + '</tpl>',
destroy: function() {
var me = this;
if (me.spinnerEl) {
me.spinnerEl.destroy();
me.spinnerEl = me.upEl = me.downEl = null;
}
me.callParent();
},
getBodyRenderData: function() {
var me = this;
return {
vertical: me.vertical,
upDisabledCls: me.upEnabled ? '' : (me.spinnerUpCls + '-disabled'),
downDisabledCls: me.downEnabled ? '' : (me.spinnerDownCls + '-disabled'),
spinnerCls: me.spinnerCls,
spinnerUpCls: me.spinnerUpCls,
spinnerDownCls: me.spinnerDownCls
};
},
getStateEl: function() {
return this.spinnerEl;
},
onClick: function() {
var me = this,
args = arguments,
e = me.clickRepeater ? args[1] : args[0],
field = me.field;
if (!field.readOnly && !field.disabled) {
if (me.upEl.contains(e.target)) {
Ext.callback(me.upHandler, me.scope, [
field,
me,
e
], 0, field);
} else if (me.downEl.contains(e.target)) {
Ext.callback(me.downHandler, me.scope, [
field,
me,
e
], 0, field);
}
}
field.inputEl.focus();
},
onFieldRender: function() {
var me = this,
vertical = me.vertical,
spinnerEl, elements;
me.callParent();
spinnerEl = me.spinnerEl = me.el.select('.' + me.spinnerCls, true);
elements = spinnerEl.elements;
me.upEl = vertical ? elements[0] : elements[1];
me.downEl = vertical ? elements[1] : elements[0];
},
setUpEnabled: function(enabled) {
this.upEl[enabled ? 'removeCls' : 'addCls'](this.spinnerUpCls + '-disabled');
},
setDownEnabled: function(enabled) {
this.downEl[enabled ? 'removeCls' : 'addCls'](this.spinnerDownCls + '-disabled');
}
});
Ext.define('Ext.form.field.Spinner', {
extend: 'Ext.form.field.Text',
alias: 'widget.spinnerfield',
alternateClassName: 'Ext.form.Spinner',
requires: [
'Ext.form.trigger.Spinner',
'Ext.util.KeyNav'
],
config: {
triggers: {
spinner: {
type: 'spinner',
upHandler: 'onSpinnerUpClick',
downHandler: 'onSpinnerDownClick',
scope: 'this'
}
}
},
spinUpEnabled: true,
spinDownEnabled: true,
keyNavEnabled: true,
mouseWheelEnabled: true,
repeatTriggerClick: true,
onSpinUp: Ext.emptyFn,
onSpinDown: Ext.emptyFn,
ariaRole: 'spinbutton',
applyTriggers: function(triggers) {
var me = this,
spinnerTrigger = triggers.spinner;
spinnerTrigger.upEnabled = me.spinUpEnabled;
spinnerTrigger.downEnabled = me.spinDownEnabled;
return me.callParent([
triggers
]);
},
onRender: function() {
var me = this,
spinnerTrigger = me.getTrigger('spinner');
me.callParent();
if (me.keyNavEnabled) {
me.spinnerKeyNav = new Ext.util.KeyNav(me.inputEl, {
scope: me,
up: me.spinUp,
down: me.spinDown
});
}
if (me.mouseWheelEnabled) {
me.mon(me.bodyEl, 'mousewheel', me.onMouseWheel, me);
}
me.spinUpEl = spinnerTrigger.upEl;
me.spinDownEl = spinnerTrigger.downEl;
},
onSpinnerUpClick: function() {
this.spinUp();
},
onSpinnerDownClick: function() {
this.spinDown();
},
spinUp: function() {
var me = this;
if (me.spinUpEnabled && !me.disabled) {
me.fireEvent('spin', me, 'up');
me.fireEvent('spinup', me);
me.onSpinUp();
}
},
spinDown: function() {
var me = this;
if (me.spinDownEnabled && !me.disabled) {
me.fireEvent('spin', me, 'down');
me.fireEvent('spindown', me);
me.onSpinDown();
}
},
setSpinUpEnabled: function(enabled) {
var me = this,
wasEnabled = me.spinUpEnabled;
me.spinUpEnabled = enabled;
if (wasEnabled !== enabled && me.rendered) {
me.getTrigger('spinner').setUpEnabled(enabled);
}
},
setSpinDownEnabled: function(enabled) {
var me = this,
wasEnabled = me.spinDownEnabled;
me.spinDownEnabled = enabled;
if (wasEnabled !== enabled && me.rendered) {
me.getTrigger('spinner').setDownEnabled(enabled);
}
},
onMouseWheel: function(e) {
var me = this,
delta;
if (me.hasFocus) {
delta = e.getWheelDelta();
if (delta > 0) {
me.spinUp();
} else if (delta < 0) {
me.spinDown();
}
e.stopEvent();
}
},
onDestroy: function() {
Ext.destroyMembers(this, 'spinnerKeyNav');
this.callParent();
}
});
Ext.define('Ext.form.field.Number', {
extend: 'Ext.form.field.Spinner',
alias: 'widget.numberfield',
alternateClassName: [
'Ext.form.NumberField',
'Ext.form.Number'
],
allowExponential: true,
allowDecimals: true,
decimalSeparator: null,
submitLocaleSeparator: true,
decimalPrecision: 2,
minValue: Number.NEGATIVE_INFINITY,
maxValue: Number.MAX_VALUE,
step: 1,
minText: 'The minimum value for this field is {0}',
maxText: 'The maximum value for this field is {0}',
nanText: '{0} is not a valid number',
negativeText: 'The value cannot be negative',
baseChars: '0123456789',
autoStripChars: false,
initComponent: function() {
var me = this;
if (me.decimalSeparator === null) {
me.decimalSeparator = Ext.util.Format.decimalSeparator;
}
me.callParent();
me.setMinValue(me.minValue);
me.setMaxValue(me.maxValue);
},
setValue: function(value) {
var me = this,
bind, valueBind;
if (me.hasFocus) {
bind = me.getBind();
valueBind = bind && bind.value;
if (valueBind && valueBind.syncing && value === me.value) {
return me;
}
}
return me.callParent([
value
]);
},
getErrors: function(value) {
value = arguments.length > 0 ? value : this.processRawValue(this.getRawValue());
var me = this,
errors = me.callParent([
value
]),
format = Ext.String.format,
num;
if (value.length < 1) {
return errors;
}
value = String(value).replace(me.decimalSeparator, '.');
if (isNaN(value)) {
errors.push(format(me.nanText, value));
}
num = me.parseValue(value);
if (me.minValue === 0 && num < 0) {
errors.push(this.negativeText);
} else if (num < me.minValue) {
errors.push(format(me.minText, me.minValue));
}
if (num > me.maxValue) {
errors.push(format(me.maxText, me.maxValue));
}
return errors;
},
rawToValue: function(rawValue) {
var value = this.fixPrecision(this.parseValue(rawValue));
if (value === null) {
value = rawValue || null;
}
return value;
},
valueToRaw: function(value) {
var me = this,
decimalSeparator = me.decimalSeparator;
value = me.parseValue(value);
value = me.fixPrecision(value);
value = Ext.isNumber(value) ? value : parseFloat(String(value).replace(decimalSeparator, '.'));
value = isNaN(value) ? '' : String(value).replace('.', decimalSeparator);
return value;
},
getSubmitValue: function() {
var me = this,
value = me.callParent();
if (!me.submitLocaleSeparator) {
value = value.replace(me.decimalSeparator, '.');
}
return value;
},
onChange: function() {
this.toggleSpinners();
this.callParent(arguments);
},
toggleSpinners: function() {
var me = this,
value = me.getValue(),
valueIsNull = value === null,
enabled;
if (me.spinUpEnabled || me.spinUpDisabledByToggle) {
enabled = valueIsNull || value < me.maxValue;
me.setSpinUpEnabled(enabled, true);
}
if (me.spinDownEnabled || me.spinDownDisabledByToggle) {
enabled = valueIsNull || value > me.minValue;
me.setSpinDownEnabled(enabled, true);
}
},
setMinValue: function(value) {
var me = this,
allowed;
me.minValue = Ext.Number.from(value, Number.NEGATIVE_INFINITY);
me.toggleSpinners();
if (me.disableKeyFilter !== true) {
allowed = me.baseChars + '';
if (me.allowExponential) {
allowed += me.decimalSeparator + 'e+-';
} else {
if (me.allowDecimals) {
allowed += me.decimalSeparator;
}
if (me.minValue < 0) {
allowed += '-';
}
}
allowed = Ext.String.escapeRegex(allowed);
me.maskRe = new RegExp('[' + allowed + ']');
if (me.autoStripChars) {
me.stripCharsRe = new RegExp('[^' + allowed + ']', 'gi');
}
}
},
setMaxValue: function(value) {
this.maxValue = Ext.Number.from(value, Number.MAX_VALUE);
this.toggleSpinners();
},
parseValue: function(value) {
value = parseFloat(String(value).replace(this.decimalSeparator, '.'));
return isNaN(value) ? null : value;
},
fixPrecision: function(value) {
var me = this,
nan = isNaN(value),
precision = me.decimalPrecision;
if (nan || !value) {
return nan ? '' : value;
} else if (!me.allowDecimals || precision <= 0) {
precision = 0;
}
return parseFloat(Ext.Number.toFixed(parseFloat(value), precision));
},
onBlur: function(e) {
var me = this,
v = me.rawToValue(me.getRawValue());
if (!Ext.isEmpty(v)) {
me.setValue(v);
}
me.callParent([
e
]);
},
setSpinUpEnabled: function(enabled,
internal) {
this.callParent(arguments);
if (!internal) {
delete this.spinUpDisabledByToggle;
} else {
this.spinUpDisabledByToggle = !enabled;
}
},
onSpinUp: function() {
var me = this;
if (!me.readOnly) {
me.setSpinValue(Ext.Number.constrain(me.getValue() + me.step, me.minValue, me.maxValue));
}
},
setSpinDownEnabled: function(enabled,
internal) {
this.callParent(arguments);
if (!internal) {
delete this.spinDownDisabledByToggle;
} else {
this.spinDownDisabledByToggle = !enabled;
}
},
onSpinDown: function() {
var me = this;
if (!me.readOnly) {
me.setSpinValue(Ext.Number.constrain(me.getValue() - me.step, me.minValue, me.maxValue));
}
},
setSpinValue: function(value) {
var me = this;
if (me.enforceMaxLength) {
if (me.fixPrecision(value).toString().length > me.maxLength) {
return;
}
}
me.setValue(value);
}
});
Ext.define('Ext.toolbar.Paging', {
extend: 'Ext.toolbar.Toolbar',
xtype: 'pagingtoolbar',
alternateClassName: 'Ext.PagingToolbar',
requires: [
'Ext.toolbar.TextItem',
'Ext.form.field.Number'
],
mixins: [
'Ext.util.StoreHolder'
],
displayInfo: false,
prependButtons: false,
displayMsg: 'Displaying {0} - {1} of {2}',
emptyMsg: 'No data to display',
beforePageText: 'Page',
afterPageText: 'of {0}',
firstText: 'First Page',
prevText: 'Previous Page',
nextText: 'Next Page',
lastText: 'Last Page',
refreshText: 'Refresh',
inputItemWidth: 30,
emptyPageData: {
total: 0,
currentPage: 0,
pageCount: 0,
toRecord: 0,
fromRecord: 0
},
defaultBindProperty: 'store',
getPagingItems: function() {
var me = this,
inputListeners = {
scope: me,
blur: me.onPagingBlur
};
inputListeners[Ext.supports.SpecialKeyDownRepeat ? 'keydown' : 'keypress'] = me.onPagingKeyDown;
return [
{
itemId: 'first',
tooltip: me.firstText,
overflowText: me.firstText,
iconCls: Ext.baseCSSPrefix + 'tbar-page-first',
disabled: true,
handler: me.moveFirst,
scope: me
},
{
itemId: 'prev',
tooltip: me.prevText,
overflowText: me.prevText,
iconCls: Ext.baseCSSPrefix + 'tbar-page-prev',
disabled: true,
handler: me.movePrevious,
scope: me
},
'-',
me.beforePageText,
{
xtype: 'numberfield',
itemId: 'inputItem',
name: 'inputItem',
cls: Ext.baseCSSPrefix + 'tbar-page-number',
allowDecimals: false,
minValue: 1,
hideTrigger: true,
enableKeyEvents: true,
keyNavEnabled: false,
selectOnFocus: true,
submitValue: false,
isFormField: false,
width: me.inputItemWidth,
margin: '-1 2 3 2',
listeners: inputListeners
},
{
xtype: 'tbtext',
itemId: 'afterTextItem',
text: Ext.String.format(me.afterPageText, 1)
},
'-',
{
itemId: 'next',
tooltip: me.nextText,
overflowText: me.nextText,
iconCls: Ext.baseCSSPrefix + 'tbar-page-next',
disabled: true,
handler: me.moveNext,
scope: me
},
{
itemId: 'last',
tooltip: me.lastText,
overflowText: me.lastText,
iconCls: Ext.baseCSSPrefix + 'tbar-page-last',
disabled: true,
handler: me.moveLast,
scope: me
},
'-',
{
itemId: 'refresh',
tooltip: me.refreshText,
overflowText: me.refreshText,
iconCls: Ext.baseCSSPrefix + 'tbar-loading',
disabled: me.store.isLoading(),
handler: me.doRefresh,
scope: me
}
];
},
initComponent: function() {
var me = this,
userItems = me.items || me.buttons || [],
pagingItems;
me.bindStore(me.store || 'ext-empty-store', true);
pagingItems = me.getPagingItems();
if (me.prependButtons) {
me.items = userItems.concat(pagingItems);
} else {
me.items = pagingItems.concat(userItems);
}
delete me.buttons;
if (me.displayInfo) {
me.items.push('->');
me.items.push({
xtype: 'tbtext',
itemId: 'displayItem'
});
}
me.callParent();
},
beforeRender: function() {
this.callParent(arguments);
this.updateBarInfo();
},
updateBarInfo: function() {
var me = this;
if (!me.store.isLoading()) {
me.calledInternal = true;
me.onLoad();
me.calledInternal = false;
}
},
updateInfo: function() {
var me = this,
displayItem = me.child('#displayItem'),
store = me.store,
pageData = me.getPageData(),
count, msg;
if (displayItem) {
count = store.getCount();
if (count === 0) {
msg = me.emptyMsg;
} else {
msg = Ext.String.format(me.displayMsg, pageData.fromRecord, pageData.toRecord, pageData.total);
}
displayItem.setText(msg);
}
},
onLoad: function() {
var me = this,
pageData, currPage, pageCount, afterText, count, isEmpty, item;
count = me.store.getCount();
isEmpty = count === 0;
if (!isEmpty) {
pageData = me.getPageData();
currPage = pageData.currentPage;
pageCount = pageData.pageCount;
if (currPage > pageCount) {
if (pageCount > 0) {
me.store.loadPage(pageCount);
} else
{
me.getInputItem().reset();
}
return;
}
afterText = Ext.String.format(me.afterPageText, isNaN(pageCount) ? 1 : pageCount);
} else {
currPage = 0;
pageCount = 0;
afterText = Ext.String.format(me.afterPageText, 0);
}
Ext.suspendLayouts();
item = me.child('#afterTextItem');
if (item) {
item.setText(afterText);
}
item = me.getInputItem();
if (item) {
item.setDisabled(isEmpty).setValue(currPage);
}
me.setChildDisabled('#first', currPage === 1 || isEmpty);
me.setChildDisabled('#prev', currPage === 1 || isEmpty);
me.setChildDisabled('#next', currPage === pageCount || isEmpty);
me.setChildDisabled('#last', currPage === pageCount || isEmpty);
me.setChildDisabled('#refresh', false);
me.updateInfo();
Ext.resumeLayouts(true);
if (!me.calledInternal) {
me.fireEvent('change', me, pageData || me.emptyPageData);
}
},
setChildDisabled: function(selector, disabled) {
var item = this.child(selector);
if (item) {
item.setDisabled(disabled);
}
},
getPageData: function() {
var store = this.store,
totalCount = store.getTotalCount();
return {
total: totalCount,
currentPage: store.currentPage,
pageCount: Math.ceil(totalCount / store.pageSize),
fromRecord: ((store.currentPage - 1) * store.pageSize) + 1,
toRecord: Math.min(store.currentPage * store.pageSize, totalCount)
};
},
onLoadError: function() {
this.setChildDisabled('#refresh', false);
},
getInputItem: function() {
return this.child('#inputItem');
},
readPageFromInput: function(pageData) {
var inputItem = this.getInputItem(),
pageNum = false,
v;
if (inputItem) {
v = inputItem.getValue();
pageNum = parseInt(v, 10);
if (!v || isNaN(pageNum)) {
inputItem.setValue(pageData.currentPage);
return false;
}
}
return pageNum;
},
onPagingBlur: function(e) {
var inputItem = this.getInputItem(),
curPage;
if (inputItem) {
curPage = this.getPageData().currentPage;
inputItem.setValue(curPage);
}
},
onPagingKeyDown: function(field, e) {
this.processKeyEvent(field, e);
},
processKeyEvent: function(field, e) {
var me = this,
key = e.getKey(),
pageData = me.getPageData(),
increment = e.shiftKey ? 10 : 1,
pageNum;
if (key === e.RETURN) {
e.stopEvent();
pageNum = me.readPageFromInput(pageData);
if (pageNum !== false) {
pageNum = Math.min(Math.max(1, pageNum), pageData.pageCount);
if (pageNum !== pageData.currentPage && me.fireEvent('beforechange', me, pageNum) !== false) {
me.store.loadPage(pageNum);
}
}
} else if (key === e.HOME || key === e.END) {
e.stopEvent();
pageNum = key === e.HOME ? 1 : pageData.pageCount;
field.setValue(pageNum);
} else if (key === e.UP || key === e.PAGE_UP || key === e.DOWN || key === e.PAGE_DOWN) {
e.stopEvent();
pageNum = me.readPageFromInput(pageData);
if (pageNum) {
if (key === e.DOWN || key === e.PAGE_DOWN) {
increment *= -1;
}
pageNum += increment;
if (pageNum >= 1 && pageNum <= pageData.pageCount) {
field.setValue(pageNum);
}
}
}
},
beforeLoad: function() {
this.setChildDisabled('#refresh', true);
},
moveFirst: function() {
if (this.fireEvent('beforechange', this, 1) !== false) {
this.store.loadPage(1);
return true;
}
return false;
},
movePrevious: function() {
var me = this,
store = me.store,
prev = store.currentPage - 1;
if (prev > 0) {
if (me.fireEvent('beforechange', me, prev) !== false) {
store.previousPage();
return true;
}
}
return false;
},
moveNext: function() {
var me = this,
store = me.store,
total = me.getPageData().pageCount,
next = store.currentPage + 1;
if (next <= total) {
if (me.fireEvent('beforechange', me, next) !== false) {
store.nextPage();
return true;
}
}
return false;
},
moveLast: function() {
var me = this,
last = me.getPageData().pageCount;
if (me.fireEvent('beforechange', me, last) !== false) {
me.store.loadPage(last);
return true;
}
return false;
},
doRefresh: function() {
var me = this,
store = me.store,
current = store.currentPage;
if (me.fireEvent('beforechange', me, current) !== false) {
store.loadPage(current);
return true;
}
return false;
},
getStoreListeners: function() {
return {
beforeload: this.beforeLoad,
load: this.onLoad,
exception: this.onLoadError
};
},
onBindStore: function() {
if (this.rendered) {
this.updateBarInfo();
}
},
onDestroy: function() {
this.bindStore(null);
this.callParent();
}
});
Ext.define('Ext.view.BoundList', {
extend: 'Ext.view.View',
alias: 'widget.boundlist',
alternateClassName: 'Ext.BoundList',
requires: [
'Ext.view.BoundListKeyNav',
'Ext.layout.component.BoundList',
'Ext.toolbar.Paging'
],
mixins: [
'Ext.mixin.Queryable'
],
pageSize: 0,
baseCls: Ext.baseCSSPrefix + 'boundlist',
itemCls: Ext.baseCSSPrefix + 'boundlist-item',
listItemCls: '',
shadow: false,
trackOver: true,
preserveScrollOnRefresh: true,
enableInitialSelection: false,
refreshSelmodelOnRefresh: true,
componentLayout: 'boundlist',
navigationModel: 'boundlist',
scrollable: true,
childEls: [
'listWrap',
'listEl'
],
renderTpl: [
'<div id="{id}-listWrap" data-ref="listWrap" role="presentation" class="{baseCls}-list-ct ',
Ext.dom.Element.unselectableCls,
'">',
'<ul id="{id}-listEl" data-ref="listEl" class="' + Ext.baseCSSPrefix + 'list-plain">',
'</ul>',
'</div>',
'{%',
'var pagingToolbar=values.$comp.pagingToolbar;',
'if (pagingToolbar) {',
'Ext.DomHelper.generateMarkup(pagingToolbar.getRenderTree(), out);',
'}',
'%}',
{
disableFormats: true
}
],
focusOnToFront: false,
initComponent: function() {
var me = this,
baseCls = me.baseCls,
itemCls = me.itemCls;
me.selectedItemCls = baseCls + '-selected';
if (me.trackOver) {
me.overItemCls = baseCls + '-item-over';
}
me.itemSelector = "." + itemCls;
me.scrollerSelector = 'ul.' + Ext.baseCSSPrefix + 'list-plain';
if (me.floating) {
me.addCls(baseCls + '-floating');
}
if (!me.tpl) {
me.tpl = new Ext.XTemplate('<tpl for=".">', '<li role="option" unselectable="on" class="' + itemCls + '">' + me.getInnerTpl(me.displayField) + '</li>', '</tpl>');
} else if (!me.tpl.isTemplate) {
me.tpl = new Ext.XTemplate(me.tpl);
}
if (me.pageSize) {
me.pagingToolbar = me.createPagingToolbar();
}
me.callParent();
},
getRefOwner: function() {
return this.pickerField || this.callParent();
},
getRefItems: function() {
var result = this.callParent(),
toolbar = this.pagingToolbar;
if (toolbar) {
result.push(toolbar);
}
return result;
},
createPagingToolbar: function() {
return Ext.widget('pagingtoolbar', {
id: this.id + '-paging-toolbar',
pageSize: this.pageSize,
store: this.dataSource,
border: false,
ownerCt: this,
ownerLayout: this.getComponentLayout()
});
},
getNodeContainer: function() {
return this.listEl;
},
refresh: function() {
var me = this,
tpl = me.tpl;
tpl.field = me.pickerField;
tpl.store = me.store;
me.callParent();
tpl.field = tpl.store = null;
},
bindStore: function(store, initial) {
var toolbar = this.pagingToolbar;
this.callParent(arguments);
if (toolbar) {
toolbar.bindStore(store, initial);
}
},
getInnerTpl: function(displayField) {
return '{' + displayField + '}';
},
onShow: function() {
this.callParent();
if (Ext.Element.getActiveElement() !== this.pickerField.inputEl.dom) {
this.focus();
}
},
onHide: function() {
var inputEl = this.pickerField.inputEl.dom;
if (Ext.Element.getActiveElement() !== inputEl && (!Ext.EventObject || Ext.EventObject.pointerType !== 'touch')) {
inputEl.focus();
}
this.callParent(arguments);
},
afterComponentLayout: function(width, height, oldWidth, oldHeight) {
var picker = this.pickerField;
this.callParent(arguments);
if (picker && picker.alignPicker) {
picker.alignPicker();
}
},
onItemClick: function(record) {
var me = this,
pickerField = me.pickerField,
valueField = pickerField.valueField,
selected = me.getSelectionModel().getSelection();
if (!pickerField.multiSelect && selected.length) {
selected = selected[0];
if (selected && pickerField.isEqual(record.get(valueField), selected.get(valueField)) && pickerField.collapse) {
pickerField.collapse();
}
}
},
onContainerClick: function(e) {
if (this.pagingToolbar && this.pagingToolbar.rendered && e.within(this.pagingToolbar.el)) {
return false;
}
},
onDestroy: function() {
this.callParent();
Ext.destroyMembers(this, 'pagingToolbar', 'listWrap', 'listEl');
},
privates: {
getTargetEl: function() {
return this.listEl;
},
getOverflowEl: function() {
return this.listWrap;
},
finishRenderChildren: function() {
var toolbar = this.pagingToolbar;
this.callParent(arguments);
if (toolbar) {
toolbar.finishRender();
}
}
}
});
Ext.define('Ext.form.field.ComboBox', {
extend: 'Ext.form.field.Picker',
requires: [
'Ext.util.DelayedTask',
'Ext.view.BoundList',
'Ext.data.StoreManager'
],
alternateClassName: 'Ext.form.ComboBox',
alias: [
'widget.combobox',
'widget.combo'
],
mixins: [
'Ext.util.StoreHolder'
],
config: {
filters: null,
selection: null,
valueNotFoundText: null,
displayTpl: false,
delimiter: ', ',
displayField: 'text'
},
publishes: [
'selection'
],
twoWayBindable: [
'selection'
],
triggerCls: Ext.baseCSSPrefix + 'form-arrow-trigger',
hiddenName: '',
collapseOnSelect: false,
hiddenDataCls: Ext.baseCSSPrefix + 'hidden-display ' + Ext.baseCSSPrefix + 'form-data-hidden',
ariaRole: 'combobox',
childEls: {
'hiddenDataEl': true
},
filtered: false,
afterRender: function() {
var me = this;
me.callParent(arguments);
me.setHiddenValue(me.value);
},
multiSelect: false,
triggerAction: 'all',
allQuery: '',
queryParam: 'query',
queryMode: 'remote',
queryCaching: true,
autoLoadOnValue: false,
pageSize: 0,
anyMatch: false,
caseSensitive: false,
autoSelect: true,
typeAhead: false,
typeAheadDelay: 250,
selectOnTab: true,
forceSelection: false,
growToLongestValue: true,
clearFilterOnBlur: true,
defaultListConfig: {
loadingHeight: 70,
minWidth: 70,
maxHeight: 300,
shadow: 'sides'
},
transformInPlace: true,
clearValueOnEmpty: true,
getGrowWidth: function() {
var me = this,
value = me.inputEl.dom.value,
field, store, dataLn, currentLongestLength, i, item, itemLn;
if (me.growToLongestValue) {
field = me.displayField;
store = me.store;
dataLn = store.data.length;
currentLongestLength = 0;
for (i = 0; i < dataLn; i++) {
item = store.getAt(i).data[field];
itemLn = item.length;
if (itemLn > currentLongestLength) {
currentLongestLength = itemLn;
value = item;
}
}
}
return value;
},
initComponent: function() {
var me = this,
isDefined = Ext.isDefined,
store = me.store,
transform = me.transform,
transformSelect, isLocalMode;
if (me.typeAhead && me.multiSelect) {
Ext.Error.raise('typeAhead and multiSelect are mutually exclusive options -- please remove one of them.');
}
if (me.typeAhead && !me.editable) {
Ext.Error.raise('If typeAhead is enabled the combo must be editable: true -- please change one of those settings.');
}
if (me.selectOnFocus && !me.editable) {
Ext.Error.raise('If selectOnFocus is enabled the combo must be editable: true -- please change one of those settings.');
}
if ('pinList' in me) {
me.collapseOnSelect = !me.pinList;
}
if (transform) {
transformSelect = Ext.getDom(transform);
if (transformSelect) {
if (!me.store) {
store = Ext.Array.map(Ext.Array.from(transformSelect.options), function(option) {
return [
option.value,
option.text
];
});
}
if (!me.name) {
me.name = transformSelect.name;
}
if (!('value' in me)) {
me.value = transformSelect.value;
}
}
}
me.bindStore(store || 'ext-empty-store', true, true);
isLocalMode = me.queryMode === 'local';
if (!isDefined(me.queryDelay)) {
me.queryDelay = isLocalMode ? 10 : 500;
}
if (!isDefined(me.minChars)) {
me.minChars = isLocalMode ? 0 : 4;
}
me.callParent();
me.doQueryTask = new Ext.util.DelayedTask(me.doRawQuery, me);
if (transformSelect) {
if (me.transformInPlace) {
me.render(transformSelect.parentNode, transformSelect);
delete me.renderTo;
}
Ext.removeNode(transformSelect);
}
},
getSubTplMarkup: function(fieldData) {
var me = this,
hiddenDataElMarkup = '',
markup = me.callParent(arguments);
if (me.hiddenName) {
hiddenDataElMarkup = '<div id="' + fieldData.id + '-hiddenDataEl" data-ref="hiddenDataEl" class="' + me.hiddenDataCls + '" role="presentation"></div>';
}
return hiddenDataElMarkup + markup;
},
applyDisplayTpl: function(displayTpl) {
var me = this;
if (!displayTpl) {
displayTpl = new Ext.XTemplate('<tpl for=".">' + '{[typeof values === "string" ? values : values["' + me.getDisplayField() + '"]]}' + '<tpl if="xindex < xcount">' + me.getDelimiter() + '</tpl>' + '</tpl>');
} else if (!displayTpl.isTemplate) {
displayTpl = new Ext.XTemplate(displayTpl);
}
return displayTpl;
},
applyFilters: function(filters, collection) {
var me = this;
if (filters === null || filters.isFilterCollection) {
return filters;
}
if (filters) {
if (!collection) {
collection = this.getFilters();
}
collection.beginUpdate();
collection.splice(0, collection.length, filters);
collection.each(function(filter) {
filter.ownerId = me.id;
});
collection.endUpdate();
}
return collection;
},
applyValueNotFoundText: function(v) {
var me = this,
valueNotFoundRecord = me.valueNotFoundRecord || (me.valueNotFoundRecord = new Ext.data.Model());
valueNotFoundRecord.set(me.displayField, v);
if (me.valueField && me.displayField !== me.valueField) {
valueNotFoundRecord.set(me.valueField, v);
}
return v;
},
getFilters: function(autoCreate) {
var ret = this.filters;
if (!ret && autoCreate !== false) {
ret = new Ext.util.FilterCollection();
this.setFilters(ret);
}
return ret;
},
updateFilters: function(newFilters, oldFilters) {
var me = this;
if (oldFilters) {
oldFilters.un('endupdate', 'onEndUpdateFilters', me);
}
if (newFilters) {
newFilters.on('endupdate', 'onEndUpdateFilters', me);
}
me.onEndUpdateFilters(newFilters);
},
onEndUpdateFilters: function(filters) {
var me = this,
was = me.filtered,
is = !!filters && (filters.length > 0),
old, storeFilters;
if (was || is) {
me.filtered = is;
old = [];
storeFilters = me.store.getFilters();
storeFilters.each(function(filter) {
if (filter.ownerId === me.id && !filters.contains(filter)) {
old.push(filter);
}
});
storeFilters.splice(0, old, filters.items);
}
},
completeEdit: function(e) {
var me = this,
filter = me.queryFilter;
this.callParent([
e
]);
me.doQueryTask.cancel();
me.assertValue();
if (filter && me.queryMode === 'local' && me.clearFilterOnBlur) {
me.getStore().getFilters().remove(filter);
}
},
onFocus: function(e) {
var me = this;
me.callParent([
e
]);
if (me.triggerAction !== 'all' && me.queryFilter && me.queryMode === 'local' && me.clearFilterOnBlur) {
delete me.lastQuery;
me.doRawQuery();
}
},
assertValue: function() {
var me = this,
value = me.getRawValue(),
displayValue = me.getDisplayValue(),
lastRecords = me.lastSelectedRecords,
rec;
if (me.forceSelection) {
if (me.multiSelect) {
if (value !== displayValue) {
me.setRawValue(displayValue);
}
} else {
rec = me.findRecordByDisplay(value);
if (rec) {
if (me.getDisplayValue([
me.getRecordDisplayData(rec)
]) !== displayValue) {
me.select(rec, true);
}
} else if (lastRecords) {
me.setValue(lastRecords);
} else {
me.setRawValue('');
}
}
}
me.collapse();
},
onTypeAhead: function() {
var me = this,
displayField = me.displayField,
record = me.store.findRecord(displayField, me.getRawValue()),
boundList = me.getPicker(),
newValue, len, selStart;
if (record) {
newValue = record.get(displayField);
len = newValue.length;
selStart = me.getRawValue().length;
boundList.highlightItem(boundList.getNode(record));
if (selStart !== 0 && selStart !== len) {
me.setRawValue(newValue);
me.selectText(selStart, newValue.length);
}
}
},
resetToDefault: Ext.emptyFn,
beforeReset: function() {
var filter = this.queryFilter;
this.callParent();
if (filter) {
this.getStore().getFilters().remove(filter);
}
},
onUnbindStore: function() {
var me = this,
picker = me.picker,
filter = me.queryFilter;
if (filter && !me.store.isDestroyed) {
me.changingFilters = true;
me.getStore().removeFilter(filter, true);
me.changingFilters = false;
}
me.pickerSelectionModel.destroy();
if (picker) {
picker.bindStore(null);
}
},
onBindStore: function(store, initial) {
var me = this,
picker = me.picker,
extraKeySpec, valueCollectionConfig;
if (store) {
if (store.autoCreated) {
me.queryMode = 'local';
me.valueField = me.displayField = 'field1';
if (!store.expanded) {
me.displayField = 'field2';
}
me.setDisplayTpl(null);
}
if (!Ext.isDefined(me.valueField)) {
me.valueField = me.displayField;
}
extraKeySpec = {
byValue: {
rootProperty: 'data',
unique: false
}
};
extraKeySpec.byValue.property = me.valueField;
store.setExtraKeys(extraKeySpec);
if (me.displayField === me.valueField) {
store.byText = store.byValue;
} else {
extraKeySpec.byText = {
rootProperty: 'data',
unique: false
};
extraKeySpec.byText.property = me.displayField;
store.setExtraKeys(extraKeySpec);
}
valueCollectionConfig = {
rootProperty: 'data',
extraKeys: {
byInternalId: {
property: 'internalId'
},
byValue: {
property: me.valueField,
rootProperty: 'data'
}
},
listeners: {
beginupdate: me.onValueCollectionBeginUpdate,
endupdate: me.onValueCollectionEndUpdate,
scope: me
}
};
me.valueCollection = new Ext.util.Collection(valueCollectionConfig);
me.pickerSelectionModel = new Ext.selection.DataViewModel({
mode: me.multiSelect ? 'SIMPLE' : 'SINGLE',
deselectOnContainerClick: false,
enableInitialSelection: false,
pruneRemoved: false,
selected: me.valueCollection,
store: store,
listeners: {
scope: me,
lastselectedchanged: me.updateBindSelection
}
});
if (!initial) {
me.resetToDefault();
}
if (picker) {
picker.setSelectionModel(me.pickerSelectionModel);
if (picker.getStore() !== store) {
picker.bindStore(store);
}
}
}
},
bindStore: function(store, preventFilter,
initial) {
var me = this,
filter = me.queryFilter;
me.mixins.storeholder.bindStore.call(me, store, initial);
store = me.getStore();
if (store && filter && !preventFilter) {
store.getFilters().add(filter);
}
if (!initial && store && !store.isEmptyStore) {
me.setValueOnData();
}
},
getStoreListeners: function(store) {
if (!store.isEmptyStore) {
var me = this,
result = {
datachanged: me.onDataChanged,
load: me.onLoad,
exception: me.onException,
update: me.onStoreUpdate,
remove: me.checkValueOnChange
};
if (!store.getRemoteFilter()) {
result.filterchange = me.checkValueOnChange;
}
return result;
}
},
onDataChanged: function() {
if (this.grow && this.growToLongestValue) {
this.autoSize();
}
},
checkValueOnChange: function() {
var me = this,
store = me.getStore();
if (!me.destroying && store.isLoaded()) {
if (me.multiSelect) {} else
{
if (me.forceSelection && !me.changingFilters && !me.findRecordByValue(me.value)) {
me.setValue(null);
}
}
}
},
onStoreUpdate: function(store, record) {
this.updateValue();
},
onException: function() {
this.collapse();
},
onLoad: function(store, records, success) {
var me = this,
needsValueUpdating = !me.valueCollection.byValue.get(me.value);
if (success && needsValueUpdating && !(store.lastOptions && 'rawQuery' in store.lastOptions)) {
me.setValueOnData();
}
me.checkValueOnChange();
},
setValueOnData: function() {
var me = this;
me.setValue(me.value);
if (me.isExpanded && me.getStore().getCount()) {
me.doAutoSelect();
}
},
doRawQuery: function() {
var me = this,
rawValue = me.inputEl.dom.value;
if (me.multiSelect) {
rawValue = rawValue.split(me.delimiter).pop();
}
me.doQuery(rawValue, false, true);
},
doQuery: function(queryString, forceAll, rawQuery) {
var me = this,
queryPlan = me.beforeQuery({
query: queryString || '',
rawQuery: rawQuery,
forceAll: forceAll,
combo: me,
cancel: false
});
if (queryPlan !== false && !queryPlan.cancel) {
if (me.queryCaching && queryPlan.query === me.lastQuery) {
me.expand();
} else
{
me.lastQuery = queryPlan.query;
if (me.queryMode === 'local') {
me.doLocalQuery(queryPlan);
} else {
me.doRemoteQuery(queryPlan);
}
}
}
return true;
},
beforeQuery: function(queryPlan) {
var me = this;
if (me.fireEvent('beforequery', queryPlan) === false) {
queryPlan.cancel = true;
}
else if (!queryPlan.cancel) {
if (queryPlan.query.length < me.minChars && !queryPlan.forceAll) {
queryPlan.cancel = true;
}
}
return queryPlan;
},
doLocalQuery: function(queryPlan) {
var me = this,
queryString = queryPlan.query,
store = me.getStore(),
filter = me.queryFilter;
me.queryFilter = null;
me.changingFilters = true;
if (filter) {
store.removeFilter(filter, true);
}
if (queryString) {
filter = me.queryFilter = new Ext.util.Filter({
id: me.id + '-filter',
anyMatch: me.anyMatch,
caseSensitive: me.caseSensitive,
root: 'data',
property: me.displayField,
value: me.enableRegEx ? new RegExp(queryString) : queryString
});
store.addFilter(filter, true);
}
me.changingFilters = false;
if (me.store.getCount() || me.getPicker().emptyText) {
me.getPicker().refresh();
me.expand();
} else {
me.collapse();
}
me.afterQuery(queryPlan);
},
doRemoteQuery: function(queryPlan) {
var me = this,
loadCallback = function() {
if (!me.isDestroyed) {
me.afterQuery(queryPlan);
}
};
me.expand();
if (me.pageSize) {
me.loadPage(1, {
rawQuery: queryPlan.rawQuery,
callback: loadCallback
});
} else {
me.store.load({
params: me.getParams(queryPlan.query),
rawQuery: queryPlan.rawQuery,
callback: loadCallback
});
}
},
afterQuery: function(queryPlan) {
var me = this;
if (me.store.getCount()) {
if (me.typeAhead) {
me.doTypeAhead();
}
if (queryPlan.rawQuery) {
if (me.picker && !me.picker.getSelectionModel().hasSelection()) {
me.doAutoSelect();
}
} else {
me.doAutoSelect();
}
}
me.checkChange();
},
loadPage: function(pageNum, options) {
this.store.loadPage(pageNum, Ext.apply({
params: this.getParams(this.lastQuery)
}, options));
},
onPageChange: function(toolbar, newPage) {
this.loadPage(newPage);
return false;
},
getParams: function(queryString) {
var params = {},
param = this.queryParam;
if (param) {
params[param] = queryString;
}
return params;
},
doAutoSelect: function() {
var me = this,
picker = me.picker;
if (picker && me.autoSelect && me.store.getCount() > 0) {
picker.getNavigationModel().setPosition(me.picker.getSelectionModel().lastSelected || 0);
}
},
doTypeAhead: function() {
var me = this,
Event = Ext.event.Event;
if (!me.typeAheadTask) {
me.typeAheadTask = new Ext.util.DelayedTask(me.onTypeAhead, me);
}
if (me.lastKey !== Event.BACKSPACE && me.lastKey !== Event.DELETE) {
me.typeAheadTask.delay(me.typeAheadDelay);
}
},
onTriggerClick: function() {
var me = this;
if (!me.readOnly && !me.disabled) {
if (me.isExpanded) {
me.collapse();
} else {
if (me.triggerAction === 'all') {
me.doQuery(me.allQuery, true);
} else if (me.triggerAction === 'last') {
me.doQuery(me.lastQuery, true);
} else {
me.doQuery(me.getRawValue(), false, true);
}
}
}
},
onFieldMutation: function(e) {
var me = this,
key = e.getKey(),
isDelete = key === e.BACKSPACE || key === e.DELETE,
rawValue = me.inputEl.dom.value,
len = rawValue.length;
if (!me.readOnly && (rawValue !== me.lastMutatedValue || isDelete) && key !== e.TAB) {
me.lastMutatedValue = rawValue;
me.lastKey = key;
if (len && (e.type !== 'keyup' || (!e.isSpecialKey() || isDelete))) {
me.doQueryTask.delay(me.queryDelay);
} else {
if (!len && (!key || isDelete)) {
if (!me.multiSelect) {
me.value = null;
me.displayTplData = undefined;
}
if (me.clearValueOnEmpty) {
me.valueCollection.removeAll();
}
me.collapse();
if (me.queryFilter) {
me.changingFilters = true;
me.store.removeFilter(me.queryFilter, true);
me.changingFilters = false;
}
}
me.callParent([
e
]);
}
}
},
onDestroy: function() {
var me = this;
me.doQueryTask.cancel();
if (me.typeAheadTask) {
me.typeAheadTask.cancel();
me.typeAheadTask = null;
}
me.bindStore(null);
me.valueCollection = Ext.destroy(me.valueCollection);
me.callParent();
},
onAdded: function() {
var me = this;
me.callParent(arguments);
if (me.picker) {
me.picker.ownerCt = me.up('[floating]');
me.picker.registerWithOwnerCt();
}
},
createPicker: function() {
var me = this,
picker,
pickerCfg = Ext.apply({
xtype: 'boundlist',
pickerField: me,
selectionModel: me.pickerSelectionModel,
floating: true,
hidden: true,
store: me.getPickerStore(),
displayField: me.displayField,
preserveScrollOnRefresh: true,
pageSize: me.pageSize,
tpl: me.tpl
}, me.listConfig, me.defaultListConfig);
picker = me.picker = Ext.widget(pickerCfg);
if (me.pageSize) {
picker.pagingToolbar.on('beforechange', me.onPageChange, me);
}
if (!picker.initialConfig.maxHeight) {
picker.on({
beforeshow: me.onBeforePickerShow,
scope: me
});
}
picker.getSelectionModel().on({
beforeselect: me.onBeforeSelect,
beforedeselect: me.onBeforeDeselect,
scope: me
});
picker.getNavigationModel().navigateOnSpace = false;
return picker;
},
getPickerStore: function() {
return this.store;
},
onBeforePickerShow: function(picker) {
var me = this,
heightAbove = me.getPosition()[1] - Ext.getBody().getScroll().top,
heightBelow = Ext.Element.getViewportHeight() - heightAbove - me.getHeight();
picker.maxHeight = Math.max(heightAbove, heightBelow) - 5;
},
onBeforeSelect: function(list, record, recordIndex) {
return this.fireEvent('beforeselect', this, record, recordIndex);
},
onBeforeDeselect: function(list, record, recordIndex) {
return this.fireEvent('beforedeselect', this, record, recordIndex);
},
getSelection: function() {
var selModel = this.getPicker().getSelectionModel(),
selection = selModel.getSelection();
return selection.length ? selModel.getLastSelected() : null;
},
updateSelection: function(selection) {
var me = this,
sm;
if (!me.ignoreNextSelection) {
me.ignoreNextSelection = true;
sm = me.getPicker().getSelectionModel();
if (selection) {
sm.select(selection);
me.hasHadSelection = true;
} else {
sm.deselectAll();
}
me.ignoreNextSelection = false;
}
},
updateBindSelection: function(selModel, selection) {
var me = this,
selected = null;
if (!me.ignoreNextSelection) {
me.ignoreNextSelection = true;
if (selection.length) {
selected = selModel.getLastSelected();
me.hasHadSelection = true;
}
if (me.hasHadSelection) {
me.setSelection(selected);
}
me.ignoreNextSelection = false;
}
},
onValueCollectionBeginUpdate: Ext.emptyFn,
onValueCollectionEndUpdate: function() {
var me = this,
store = me.store,
selectedRecords = me.valueCollection.getRange(),
selectedRecord = selectedRecords[0],
selectionCount = selectedRecords.length;
me.updateBindSelection(me.pickerSelectionModel, selectedRecords);
if (me.isSelectionUpdating()) {
return;
}
Ext.suspendLayouts();
me.lastSelection = selectedRecords;
if (selectionCount) {
me.lastSelectedRecords = selectedRecords;
}
me.updateValue();
if (selectionCount && ((!me.multiSelect && store.contains(selectedRecord)) || me.collapseOnSelect || !store.getCount())) {
me.updatingValue = true;
me.collapse();
me.updatingValue = false;
}
Ext.resumeLayouts(true);
if (selectionCount && !me.suspendCheckChange) {
if (!me.multiSelect) {
selectedRecords = selectedRecord;
}
me.fireEvent('select', me, selectedRecords);
}
},
isSelectionUpdating: function() {
var selModel = this.pickerSelectionModel;
return selModel.deselectingDuringSelect || selModel.refreshing;
},
onExpand: function() {
var keyNav = this.getPicker().getNavigationModel();
if (keyNav) {
keyNav.enable();
}
this.doAutoSelect();
},
onCollapse: function() {
var keyNav = this.getPicker().getNavigationModel();
if (keyNav) {
keyNav.disable();
}
if (this.updatingValue) {
this.doQueryTask.cancel();
}
},
select: function(r,
assert) {
var me = this,
picker = me.picker,
fireSelect;
if (r && r.isModel && assert === true && picker) {
fireSelect = !picker.getSelectionModel().isSelected(r);
}
if (!fireSelect) {
me.suspendEvent('select');
}
me.setValue(r);
me.resumeEvent('select');
},
findRecord: function(field, value) {
var ds = this.store,
idx = ds.findExact(field, value);
return idx !== -1 ? ds.getAt(idx) : false;
},
getSelectedRecord: function() {
return this.findRecordByValue(this.value) || null;
},
findRecordByValue: function(value) {
var result = this.store.byValue.get(value),
ret = false;
if (result) {
ret = result[0] || result;
}
return ret;
},
findRecordByDisplay: function(value) {
var result = this.store.byText.get(value),
ret = false;
if (result) {
ret = result[0] || result;
}
return ret;
},
addValue: function(value) {
if (value != null) {
return this.doSetValue(value, true);
}
},
setValue: function(value) {
var me = this;
if (value != null) {
return me.doSetValue(value);
} else
{
me.suspendEvent('select');
me.valueCollection.beginUpdate();
me.pickerSelectionModel.deselectAll();
me.valueCollection.endUpdate();
me.lastSelectedRecords = null;
me.resumeEvent('select');
}
},
setRawValue: function(rawValue) {
this.callParent([
rawValue
]);
this.lastMutatedValue = rawValue;
},
doSetValue: function(value,
add) {
var me = this,
store = me.getStore(),
Model = store.getModel(),
matchedRecords = [],
valueArray = [],
autoLoadOnValue = me.autoLoadOnValue,
isLoaded = store.getCount() > 0 || store.isLoaded(),
pendingLoad = store.hasPendingLoad(),
unloaded = autoLoadOnValue && !isLoaded && !pendingLoad,
forceSelection = me.forceSelection,
selModel = me.pickerSelectionModel,
displayIsValue = me.displayField === me.valueField,
isEmptyStore = store.isEmptyStore,
lastSelection = me.lastSelection,
i, len, record, dataObj, valueChanged, key;
if (add && !me.multiSelect) {
Ext.Error.raise('Cannot add values to non multiSelect ComboBox');
}
if (pendingLoad || unloaded || !isLoaded || isEmptyStore) {
if (!value.isModel) {
if (add) {
me.value = Ext.Array.from(me.value).concat(value);
} else {
me.value = value;
}
me.setHiddenValue(me.value);
me.setRawValue(displayIsValue ? value : '');
}
if (unloaded && !isEmptyStore) {
store.load();
}
if (!value.isModel || isEmptyStore) {
return me;
}
}
value = add ? Ext.Array.from(me.value).concat(value) : Ext.Array.from(value);
for (i = 0 , len = value.length; i < len; i++) {
record = value[i];
if (!record || !record.isModel) {
record = me.findRecordByValue(key = record);
if (!record) {
record = me.valueCollection.find(me.valueField, key);
}
}
if (!record) {
if (!forceSelection) {
if (!record && value[i]) {
dataObj = {};
dataObj[me.displayField] = value[i];
if (me.valueField && me.displayField !== me.valueField) {
dataObj[me.valueField] = value[i];
}
record = new Model(dataObj);
}
}
else if (me.valueNotFoundRecord) {
record = me.valueNotFoundRecord;
}
}
if (record) {
matchedRecords.push(record);
valueArray.push(record.get(me.valueField));
}
}
if (lastSelection) {
len = lastSelection.length;
if (len === matchedRecords.length) {
for (i = 0; !valueChanged && i < len; i++) {
if (Ext.Array.indexOf(me.lastSelection, matchedRecords[i]) === -1) {
valueChanged = true;
}
}
} else {
valueChanged = true;
}
} else {
valueChanged = matchedRecords.length;
}
if (valueChanged) {
me.suspendEvent('select');
me.valueCollection.beginUpdate();
if (matchedRecords.length) {
selModel.select(matchedRecords, false);
} else {
selModel.deselectAll();
}
me.valueCollection.endUpdate();
me.resumeEvent('select');
} else {
me.updateValue();
}
return me;
},
updateValue: function() {
var me = this,
selectedRecords = me.valueCollection.getRange(),
len = selectedRecords.length,
valueArray = [],
displayTplData = me.displayTplData || (me.displayTplData = []),
inputEl = me.inputEl,
i, record;
displayTplData.length = 0;
for (i = 0; i < len; i++) {
record = selectedRecords[i];
displayTplData.push(me.getRecordDisplayData(record));
if (record !== me.valueNotFoundRecord) {
valueArray.push(record.get(me.valueField));
}
}
me.setHiddenValue(valueArray);
me.value = me.multiSelect ? valueArray : valueArray[0];
if (!Ext.isDefined(me.value)) {
me.value = undefined;
}
me.displayTplData = displayTplData;
if (inputEl && me.emptyText && !Ext.isEmpty(me.value)) {
inputEl.removeCls(me.emptyCls);
}
me.setRawValue(me.getDisplayValue());
me.checkChange();
me.applyEmptyText();
},
setHiddenValue: function(values) {
var me = this,
name = me.hiddenName,
i, dom, childNodes, input, valueCount, childrenCount;
if (!me.hiddenDataEl || !name) {
return;
}
values = Ext.Array.from(values);
dom = me.hiddenDataEl.dom;
childNodes = dom.childNodes;
input = childNodes[0];
valueCount = values.length;
childrenCount = childNodes.length;
if (!input && valueCount > 0) {
me.hiddenDataEl.setHtml(Ext.DomHelper.markup({
tag: 'input',
type: 'hidden',
name: name
}));
childrenCount = 1;
input = dom.firstChild;
}
while (childrenCount > valueCount) {
dom.removeChild(childNodes[0]);
--childrenCount;
}
while (childrenCount < valueCount) {
dom.appendChild(input.cloneNode(true));
++childrenCount;
}
for (i = 0; i < valueCount; i++) {
childNodes[i].value = values[i];
}
},
getDisplayValue: function(tplData) {
tplData = tplData || this.displayTplData;
return this.getDisplayTpl().apply(tplData);
},
getRecordDisplayData: function(record) {
return record.data;
},
getValue: function() {
var me = this,
store = me.getStore(),
picker = me.picker,
rawValue = me.getRawValue(),
value = me.value;
if (!store.isEmptyStore && me.getDisplayValue() !== rawValue) {
me.displayTplData = undefined;
if (picker) {
me.valueCollection.suspendEvents();
picker.getSelectionModel().deselectAll();
me.valueCollection.resumeEvents();
me.lastSelection = null;
}
if (store.isLoaded() && (me.multiSelect || me.forceSelection)) {
value = me.value = undefined;
} else {
value = me.value = rawValue;
}
}
me.value = value == null ? null : value;
return me.value;
},
getSubmitValue: function() {
var value = this.getValue();
if (Ext.isEmpty(value)) {
value = '';
}
return value;
},
isEqual: function(v1, v2) {
var fromArray = Ext.Array.from,
i, len;
v1 = fromArray(v1);
v2 = fromArray(v2);
len = v1.length;
if (len !== v2.length) {
return false;
}
for (i = 0; i < len; i++) {
if (v2[i] !== v1[i]) {
return false;
}
}
return true;
},
clearValue: function() {
this.setValue(null);
},
onEditorTab: function(e) {
var keyNav = this.getPicker().getNavigationModel();
if (this.selectOnTab && keyNav && this.isExpanded) {
keyNav.selectHighlighted(e);
}
}
});
Ext.define('Ext.picker.Month', {
extend: 'Ext.Component',
requires: [
'Ext.XTemplate',
'Ext.util.ClickRepeater',
'Ext.Date',
'Ext.button.Button'
],
alias: 'widget.monthpicker',
alternateClassName: 'Ext.MonthPicker',
isMonthPicker: true,
focusable: true,
childEls: [
'bodyEl',
'prevEl',
'nextEl',
'monthEl',
'yearEl'
],
renderTpl: [
'<div id="{id}-bodyEl" data-ref="bodyEl" class="{baseCls}-body">',
'<div id="{id}-monthEl" data-ref="monthEl" class="{baseCls}-months">',
'<tpl for="months">',
'<div class="{parent.baseCls}-item {parent.baseCls}-month">',
'<a style="{parent.monthStyle}" role="button" hidefocus="on" class="{parent.baseCls}-item-inner">{.}</a>',
'</div>',
'</tpl>',
'</div>',
'<div id="{id}-yearEl" data-ref="yearEl" class="{baseCls}-years">',
'<div class="{baseCls}-yearnav">',
'<div class="{baseCls}-yearnav-button-ct">',
'<a id="{id}-prevEl" data-ref="prevEl" class="{baseCls}-yearnav-button {baseCls}-yearnav-prev" hidefocus="on" role="button"></a>',
'</div>',
'<div class="{baseCls}-yearnav-button-ct">',
'<a id="{id}-nextEl" data-ref="nextEl" class="{baseCls}-yearnav-button {baseCls}-yearnav-next" hidefocus="on" role="button"></a>',
'</div>',
'</div>',
'<tpl for="years">',
'<div class="{parent.baseCls}-item {parent.baseCls}-year">',
'<a hidefocus="on" class="{parent.baseCls}-item-inner" role="button">{.}</a>',
'</div>',
'</tpl>',
'</div>',
'<div class="' + Ext.baseCSSPrefix + 'clear"></div>',
'<tpl if="showButtons">',
'<div class="{baseCls}-buttons">{%',
'var me=values.$comp, okBtn=me.okBtn, cancelBtn=me.cancelBtn;',
'okBtn.ownerLayout = cancelBtn.ownerLayout = me.componentLayout;',
'okBtn.ownerCt = cancelBtn.ownerCt = me;',
'Ext.DomHelper.generateMarkup(okBtn.getRenderTree(), out);',
'Ext.DomHelper.generateMarkup(cancelBtn.getRenderTree(), out);',
'%}</div>',
'</tpl>',
'</div>'
],
okText: 'OK',
cancelText: 'Cancel',
baseCls: Ext.baseCSSPrefix + 'monthpicker',
showButtons: true,
measureWidth: 35,
measureMaxHeight: 20,
smallCls: Ext.baseCSSPrefix + 'monthpicker-small',
totalYears: 10,
yearOffset: 5,
monthOffset: 6,
initComponent: function() {
var me = this;
me.selectedCls = me.baseCls + '-selected';
if (me.small) {
me.addCls(me.smallCls);
}
me.setValue(me.value);
me.activeYear = me.getYear(new Date().getFullYear() - 4, -4);
if (me.showButtons) {
me.okBtn = new Ext.button.Button({
text: me.okText,
handler: me.onOkClick,
scope: me
});
me.cancelBtn = new Ext.button.Button({
text: me.cancelText,
handler: me.onCancelClick,
scope: me
});
}
this.callParent();
},
beforeRender: function() {
var me = this,
i = 0,
months = [],
shortName = Ext.Date.getShortMonthName,
monthLen = me.monthOffset,
margin = me.monthMargin,
style = '';
if (me.padding && !me.width) {
me.cacheWidth();
}
me.callParent();
for (; i < monthLen; ++i) {
months.push(shortName(i), shortName(i + monthLen));
}
if (Ext.isDefined(margin)) {
style = 'margin: 0 ' + margin + 'px;';
}
Ext.apply(me.renderData, {
months: months,
years: me.getYears(),
showButtons: me.showButtons,
monthStyle: style
});
},
cacheWidth: function() {
var me = this,
padding = me.parseBox(me.padding),
widthEl = Ext.getBody().createChild({
cls: me.baseCls + ' ' + me.borderBoxCls,
style: 'position:absolute;top:-1000px;left:-1000px;',
html: '&nbsp;'
});
me.self.prototype.width = widthEl.getWidth() + padding.left + padding.right;
widthEl.destroy();
},
afterRender: function() {
var me = this,
body = me.bodyEl;
me.callParent();
me.mon(body, 'click', me.onBodyClick, me);
me.mon(body, 'dblclick', me.onBodyClick, me);
me.years = body.select('.' + me.baseCls + '-year a');
me.months = body.select('.' + me.baseCls + '-month a');
me.backRepeater = new Ext.util.ClickRepeater(me.prevEl, {
handler: Ext.Function.bind(me.adjustYear, me, [
-me.totalYears
])
});
me.prevEl.addClsOnOver(me.baseCls + '-yearnav-prev-over');
me.nextRepeater = new Ext.util.ClickRepeater(me.nextEl, {
handler: Ext.Function.bind(me.adjustYear, me, [
me.totalYears
])
});
me.nextEl.addClsOnOver(me.baseCls + '-yearnav-next-over');
me.updateBody();
if (!Ext.isDefined(me.monthMargin)) {
Ext.picker.Month.prototype.monthMargin = me.calculateMonthMargin();
}
},
calculateMonthMargin: function() {
var me = this,
months = me.months,
first = months.first(),
itemMargin = first.getMargin('l');
while (itemMargin && me.getLargest() > me.measureMaxHeight) {
--itemMargin;
months.setStyle('margin', '0 ' + itemMargin + 'px');
}
return itemMargin;
},
getLargest: function(months) {
var largest = 0;
this.months.each(function(item) {
var h = item.getHeight();
if (h > largest) {
largest = h;
}
});
return largest;
},
setValue: function(value) {
var me = this,
active = me.activeYear,
year;
if (!value) {
me.value = [
null,
null
];
} else if (Ext.isDate(value)) {
me.value = [
value.getMonth(),
value.getFullYear()
];
} else {
me.value = [
value[0],
value[1]
];
}
if (me.rendered) {
year = me.value[1];
if (year !== null) {
if ((year < active || year > active + me.yearOffset)) {
me.activeYear = year - me.yearOffset + 1;
}
}
me.updateBody();
}
return me;
},
getValue: function() {
return this.value;
},
hasSelection: function() {
var value = this.value;
return value[0] !== null && value[1] !== null;
},
getYears: function() {
var me = this,
offset = me.yearOffset,
start = me.activeYear,
end = start + offset,
i = start,
years = [];
for (; i < end; ++i) {
years.push(i, i + offset);
}
return years;
},
updateBody: function() {
var me = this,
years = me.years,
months = me.months,
yearNumbers = me.getYears(),
cls = me.selectedCls,
value = me.getYear(null),
month = me.value[0],
monthOffset = me.monthOffset,
year, yearItems, y, yLen, el;
if (me.rendered) {
years.removeCls(cls);
months.removeCls(cls);
yearItems = years.elements;
yLen = yearItems.length;
for (y = 0; y < yLen; y++) {
el = Ext.fly(yearItems[y]);
year = yearNumbers[y];
el.dom.innerHTML = year;
if (year === value) {
el.addCls(cls);
}
}
if (month !== null) {
if (month < monthOffset) {
month = month * 2;
} else {
month = (month - monthOffset) * 2 + 1;
}
months.item(month).addCls(cls);
}
}
},
getYear: function(defaultValue, offset) {
var year = this.value[1];
offset = offset || 0;
return year === null ? defaultValue : year + offset;
},
onBodyClick: function(e, t) {
var me = this,
isDouble = e.type === 'dblclick';
if (e.getTarget('.' + me.baseCls + '-month')) {
e.stopEvent();
me.onMonthClick(t, isDouble);
} else if (e.getTarget('.' + me.baseCls + '-year')) {
e.stopEvent();
me.onYearClick(t, isDouble);
}
},
adjustYear: function(offset) {
if (typeof offset !== 'number') {
offset = this.totalYears;
}
this.activeYear += offset;
this.updateBody();
},
onOkClick: function() {
this.fireEvent('okclick', this, this.value);
},
onCancelClick: function() {
this.fireEvent('cancelclick', this);
},
onMonthClick: function(target, isDouble) {
var me = this;
me.value[0] = me.resolveOffset(me.months.indexOf(target), me.monthOffset);
me.updateBody();
me.fireEvent('month' + (isDouble ? 'dbl' : '') + 'click', me, me.value);
me.fireEvent('select', me, me.value);
},
onYearClick: function(target, isDouble) {
var me = this;
me.value[1] = me.activeYear + me.resolveOffset(me.years.indexOf(target), me.yearOffset);
me.updateBody();
me.fireEvent('year' + (isDouble ? 'dbl' : '') + 'click', me, me.value);
me.fireEvent('select', me, me.value);
},
resolveOffset: function(index, offset) {
if (index % 2 === 0) {
return (index / 2);
} else {
return offset + Math.floor(index / 2);
}
},
beforeDestroy: function() {
var me = this;
me.years = me.months = null;
Ext.destroyMembers(me, 'backRepeater', 'nextRepeater', 'okBtn', 'cancelBtn');
me.callParent();
},
onDestroy: function() {
Ext.destroyMembers(this, 'okBtn', 'cancelBtn');
this.callParent();
},
privates: {
finishRenderChildren: function() {
var me = this;
this.callParent(arguments);
if (this.showButtons) {
me.okBtn.finishRender();
me.cancelBtn.finishRender();
}
}
}
});
Ext.define('Ext.picker.Date', {
extend: 'Ext.Component',
requires: [
'Ext.XTemplate',
'Ext.button.Button',
'Ext.button.Split',
'Ext.util.ClickRepeater',
'Ext.util.KeyNav',
'Ext.fx.Manager',
'Ext.picker.Month'
],
alias: 'widget.datepicker',
alternateClassName: 'Ext.DatePicker',
isDatePicker: true,
focusable: true,
childEls: [
'innerEl',
'eventEl',
'prevEl',
'nextEl',
'middleBtnEl',
'footerEl'
],
border: true,
renderTpl: [
'<div id="{id}-innerEl" data-ref="innerEl">',
'<div class="{baseCls}-header">',
'<div id="{id}-prevEl" data-ref="prevEl" class="{baseCls}-prev {baseCls}-arrow" role="button" title="{prevText}"></div>',
'<div id="{id}-middleBtnEl" data-ref="middleBtnEl" class="{baseCls}-month" role="heading">{%this.renderMonthBtn(values, out)%}</div>',
'<div id="{id}-nextEl" data-ref="nextEl" class="{baseCls}-next {baseCls}-arrow" role="button" title="{nextText}"></div>',
'</div>',
'<table role="grid" id="{id}-eventEl" data-ref="eventEl" class="{baseCls}-inner" {%',
'if (values.$comp.focusable) {out.push("tabindex=\\"0\\"");}',
'%} cellspacing="0">',
'<thead><tr role="row">',
'<tpl for="dayNames">',
'<th role="columnheader" class="{parent.baseCls}-column-header" aria-label="{.}">',
'<div role="presentation" class="{parent.baseCls}-column-header-inner">{.:this.firstInitial}</div>',
'</th>',
'</tpl>',
'</tr></thead>',
'<tbody><tr role="row">',
'<tpl for="days">',
'{#:this.isEndOfWeek}',
'<td role="gridcell">',
'<div hidefocus="on" class="{parent.baseCls}-date"></div>',
'</td>',
'</tpl>',
'</tr></tbody>',
'</table>',
'<tpl if="showToday">',
'<div id="{id}-footerEl" data-ref="footerEl" role="presentation" class="{baseCls}-footer">{%this.renderTodayBtn(values, out)%}</div>',
'</tpl>',
'</div>',
{
firstInitial: function(value) {
return Ext.picker.Date.prototype.getDayInitial(value);
},
isEndOfWeek: function(value) {
value--;
var end = value % 7 === 0 && value !== 0;
return end ? '</tr><tr role="row">' : '';
},
renderTodayBtn: function(values, out) {
Ext.DomHelper.generateMarkup(values.$comp.todayBtn.getRenderTree(), out);
},
renderMonthBtn: function(values, out) {
Ext.DomHelper.generateMarkup(values.$comp.monthBtn.getRenderTree(), out);
}
}
],
todayText: 'Today',
ariaTitle: 'Date Picker: {0}',
ariaTitleDateFormat: 'F d',
todayTip: '{0} (Spacebar)',
minText: 'This date is before the minimum date',
maxText: 'This date is after the maximum date',
disabledDaysText: 'Disabled',
disabledDatesText: 'Disabled',
nextText: 'Next Month (Control+Right)',
prevText: 'Previous Month (Control+Left)',
monthYearText: 'Choose a month (Control+Up/Down to move years)',
monthYearFormat: 'F Y',
startDay: 0,
showToday: true,
disableAnim: false,
baseCls: Ext.baseCSSPrefix + 'datepicker',
longDayFormat: 'F d, Y',
initHour: 12,
numDays: 42,
initComponent: function() {
var me = this,
clearTime = Ext.Date.clearTime;
me.selectedCls = me.baseCls + '-selected';
me.disabledCellCls = me.baseCls + '-disabled';
me.prevCls = me.baseCls + '-prevday';
me.activeCls = me.baseCls + '-active';
me.cellCls = me.baseCls + '-cell';
me.nextCls = me.baseCls + '-prevday';
me.todayCls = me.baseCls + '-today';
if (!me.format) {
me.format = Ext.Date.defaultFormat;
}
if (!me.dayNames) {
me.dayNames = Ext.Date.dayNames;
}
me.dayNames = me.dayNames.slice(me.startDay).concat(me.dayNames.slice(0, me.startDay));
me.callParent();
me.value = me.value ? clearTime(me.value, true) : clearTime(new Date());
me.initDisabledDays();
},
getRefOwner: function() {
return this.pickerField || this.callParent();
},
getRefItems: function() {
var results = [],
monthBtn = this.monthBtn,
todayBtn = this.todayBtn;
if (monthBtn) {
results.push(monthBtn);
}
if (todayBtn) {
results.push(todayBtn);
}
return results;
},
beforeRender: function() {
var me = this,
days = new Array(me.numDays),
today = Ext.Date.format(new Date(), me.format);
if (me.padding && !me.width) {
me.cacheWidth();
}
me.monthBtn = new Ext.button.Split({
ownerCt: me,
ownerLayout: me.getComponentLayout(),
text: '',
tooltip: me.monthYearText,
listeners: {
click: me.doShowMonthPicker,
arrowclick: me.doShowMonthPicker,
scope: me
}
});
if (me.showToday) {
me.todayBtn = new Ext.button.Button({
ownerCt: me,
ownerLayout: me.getComponentLayout(),
text: Ext.String.format(me.todayText, today),
tooltip: Ext.String.format(me.todayTip, today),
tooltipType: 'title',
handler: me.selectToday,
scope: me
});
}
me.callParent();
Ext.applyIf(me, {
renderData: {}
});
Ext.apply(me.renderData, {
dayNames: me.dayNames,
showToday: me.showToday,
prevText: me.prevText,
nextText: me.nextText,
days: days
});
me.protoEl.unselectable();
},
cacheWidth: function() {
var me = this,
padding = me.parseBox(me.padding),
widthEl = Ext.getBody().createChild({
cls: me.baseCls + ' ' + me.borderBoxCls,
style: 'position:absolute;top:-1000px;left:-1000px;'
});
me.self.prototype.width = widthEl.getWidth() + padding.left + padding.right;
widthEl.destroy();
},
onRender: function(container, position) {
var me = this;
me.callParent(arguments);
me.cells = me.eventEl.select('tbody td');
me.textNodes = me.eventEl.query('tbody td div');
me.eventEl.set({
'aria-labelledby': me.monthBtn.id
});
me.mon(me.eventEl, {
scope: me,
mousewheel: me.handleMouseWheel,
click: {
fn: me.handleDateClick,
delegate: 'div.' + me.baseCls + '-date'
}
});
},
initEvents: function() {
var me = this,
pickerField = me.pickerField,
eDate = Ext.Date,
day = eDate.DAY;
me.callParent();
if (!me.focusable) {
me.el.on({
mousedown: me.onMouseDown
});
}
me.prevRepeater = new Ext.util.ClickRepeater(me.prevEl, {
handler: me.showPrevMonth,
scope: me,
preventDefault: true,
stopDefault: true
});
me.nextRepeater = new Ext.util.ClickRepeater(me.nextEl, {
handler: me.showNextMonth,
scope: me,
preventDefault: true,
stopDefault: true
});
me.keyNav = new Ext.util.KeyNav(pickerField ? pickerField.inputEl : me.eventEl, Ext.apply({
scope: me,
capture: true,
left: function(e) {
if (e.ctrlKey) {
me.showPrevMonth();
} else {
me.update(eDate.add(me.activeDate, day, -1));
}
},
right: function(e) {
if (e.ctrlKey) {
me.showNextMonth();
} else {
me.update(eDate.add(me.activeDate, day, 1));
}
},
up: function(e) {
if (e.ctrlKey) {
me.showNextYear();
} else {
me.update(eDate.add(me.activeDate, day, -7));
}
},
down: function(e) {
if (e.ctrlKey) {
me.showPrevYear();
} else {
me.update(eDate.add(me.activeDate, day, 7));
}
},
pageUp: function(e) {
if (e.ctrlKey) {
me.showPrevYear();
} else {
me.showPrevMonth();
}
},
pageDown: function(e) {
if (e.ctrlKey) {
me.showNextYear();
} else {
me.showNextMonth();
}
},
tab: function(e) {
me.handleTabClick(e);
return true;
},
enter: function(e) {
me.handleDateClick(e, me.activeCell.firstChild);
},
space: function() {
me.setValue(new Date(me.activeCell.firstChild.dateValue));
var startValue = me.startValue,
value = me.value,
pickerValue;
if (pickerField) {
pickerValue = pickerField.getValue();
if (pickerValue && startValue && pickerValue.getTime() === value.getTime()) {
pickerField.setValue(startValue);
} else {
pickerField.setValue(value);
}
}
},
home: function(e) {
me.update(eDate.getFirstDateOfMonth(me.activeDate));
},
end: function(e) {
me.update(eDate.getLastDateOfMonth(me.activeDate));
}
}, me.keyNavConfig));
if (me.disabled) {
me.syncDisabled(true);
}
me.update(me.value);
},
onMouseDown: function(e) {
e.preventDefault();
},
handleTabClick: function(e) {
var me = this,
t = me.getSelectedDate(me.activeDate),
handler = me.handler;
if (!me.disabled && t.dateValue && !Ext.fly(t.parentNode).hasCls(me.disabledCellCls)) {
me.setValue(new Date(t.dateValue));
me.fireEvent('select', me, me.value);
if (handler) {
handler.call(me.scope || me, me, me.value);
}
me.onSelect();
}
},
getSelectedDate: function(date) {
var me = this,
t = date.getTime(),
cells = me.cells,
cls = me.selectedCls,
cellItems = cells.elements,
cLen = cellItems.length,
cell, c;
cells.removeCls(cls);
for (c = 0; c < cLen; c++) {
cell = cellItems[c].firstChild;
if (cell.dateValue === t) {
return cell;
}
}
return null;
},
initDisabledDays: function() {
var me = this,
dd = me.disabledDates,
re = '(?:',
len, d, dLen, dI;
if (!me.disabledDatesRE && dd) {
len = dd.length - 1;
dLen = dd.length;
for (d = 0; d < dLen; d++) {
dI = dd[d];
re += Ext.isDate(dI) ? '^' + Ext.String.escapeRegex(Ext.Date.dateFormat(dI, me.format)) + '$' : dI;
if (d !== len) {
re += '|';
}
}
me.disabledDatesRE = new RegExp(re + ')');
}
},
setDisabledDates: function(dd) {
var me = this;
if (Ext.isArray(dd)) {
me.disabledDates = dd;
me.disabledDatesRE = null;
} else {
me.disabledDatesRE = dd;
}
me.initDisabledDays();
me.update(me.value, true);
return me;
},
setDisabledDays: function(dd) {
this.disabledDays = dd;
return this.update(this.value, true);
},
setMinDate: function(dt) {
this.minDate = dt;
return this.update(this.value, true);
},
setMaxDate: function(dt) {
this.maxDate = dt;
return this.update(this.value, true);
},
setValue: function(value) {
this.value = Ext.Date.clearTime(value || new Date(), true);
return this.update(this.value);
},
getValue: function() {
return this.value;
},
getDayInitial: function(value) {
return value.substr(0, 1);
},
onEnable: function() {
var me = this;
me.callParent();
me.syncDisabled(false);
me.update(me.activeDate);
},
onShow: function() {
var me = this;
me.callParent();
me.syncDisabled(false);
if (me.pickerField) {
me.startValue = me.pickerField.getValue();
}
},
onHide: function() {
this.callParent();
this.syncDisabled(true);
},
onDisable: function() {
this.callParent();
this.syncDisabled(true);
},
getActive: function() {
return this.activeDate || this.value;
},
runAnimation: function(isHide) {
var picker = this.monthPicker,
options = {
duration: 200,
callback: function() {
picker.setVisible(!isHide);
}
};
if (isHide) {
picker.el.slideOut('t', options);
} else {
picker.el.slideIn('t', options);
}
},
hideMonthPicker: function(animate) {
var me = this,
picker = me.monthPicker;
if (picker && picker.isVisible()) {
if (me.shouldAnimate(animate)) {
me.runAnimation(true);
} else {
picker.hide();
}
}
return me;
},
doShowMonthPicker: function() {
this.showMonthPicker();
},
doHideMonthPicker: function() {
this.hideMonthPicker();
},
showMonthPicker: function(animate) {
var me = this,
el = me.el,
picker;
if (me.rendered && !me.disabled) {
picker = me.createMonthPicker();
if (!picker.isVisible()) {
picker.setValue(me.getActive());
picker.setSize(el.getSize());
picker.floatParent = null;
picker.setPosition(-el.getBorderWidth('l'), -el.getBorderWidth('t'));
if (me.shouldAnimate(animate)) {
me.runAnimation(false);
} else {
picker.show();
}
}
}
return me;
},
shouldAnimate: function(animate) {
return Ext.isDefined(animate) ? animate : !this.disableAnim;
},
createMonthPicker: function() {
var me = this,
picker = me.monthPicker;
if (!picker) {
me.monthPicker = picker = new Ext.picker.Month({
renderTo: me.el,
ownerCmp: me,
floating: true,
padding: me.padding,
shadow: false,
small: me.showToday === false,
listeners: {
scope: me,
cancelclick: me.onCancelClick,
okclick: me.onOkClick,
yeardblclick: me.onOkClick,
monthdblclick: me.onOkClick
}
});
if (!me.disableAnim) {
picker.el.setStyle('display', 'none');
}
picker.hide();
me.on('beforehide', me.doHideMonthPicker, me);
}
return picker;
},
onOkClick: function(picker, value) {
var me = this,
month = value[0],
year = value[1],
date = new Date(year, month, me.getActive().getDate());
if (date.getMonth() !== month) {
date = Ext.Date.getLastDateOfMonth(new Date(year, month, 1));
}
me.setValue(date);
me.hideMonthPicker();
},
onCancelClick: function() {
this.selectedUpdate(this.activeDate);
this.hideMonthPicker();
},
showPrevMonth: function(e) {
return this.setValue(Ext.Date.add(this.activeDate, Ext.Date.MONTH, -1));
},
showNextMonth: function(e) {
return this.setValue(Ext.Date.add(this.activeDate, Ext.Date.MONTH, 1));
},
showPrevYear: function() {
return this.setValue(Ext.Date.add(this.activeDate, Ext.Date.YEAR, -1));
},
showNextYear: function() {
return this.setValue(Ext.Date.add(this.activeDate, Ext.Date.YEAR, 1));
},
handleMouseWheel: function(e) {
e.stopEvent();
if (!this.disabled) {
var delta = e.getWheelDelta();
if (delta > 0) {
this.showPrevMonth();
} else if (delta < 0) {
this.showNextMonth();
}
}
},
handleDateClick: function(e, t) {
var me = this,
handler = me.handler;
e.stopEvent();
if (!me.disabled && t.dateValue && !Ext.fly(t.parentNode).hasCls(me.disabledCellCls)) {
me.setValue(new Date(t.dateValue));
me.fireEvent('select', me, me.value);
if (handler) {
handler.call(me.scope || me, me, me.value);
}
me.onSelect();
}
},
onSelect: function() {
if (this.hideOnSelect) {
this.hide();
}
},
selectToday: function() {
var me = this,
btn = me.todayBtn,
handler = me.handler;
if (btn && !btn.disabled) {
me.setValue(Ext.Date.clearTime(new Date()));
me.fireEvent('select', me, me.value);
if (handler) {
handler.call(me.scope || me, me, me.value);
}
me.onSelect();
}
return me;
},
selectedUpdate: function(date) {
var me = this,
t = date.getTime(),
cells = me.cells,
cls = me.selectedCls,
c,
cLen = cells.getCount(),
cell;
cell = me.activeCell;
if (cell) {
Ext.fly(cell).removeCls(cls);
cell.setAttribute('aria-selected', false);
}
for (c = 0; c < cLen; c++) {
cell = cells.item(c);
if (me.textNodes[c].dateValue === t) {
me.activeCell = cell.dom;
me.eventEl.dom.setAttribute('aria-activedescendant', cell.dom.id);
cell.dom.setAttribute('aria-selected', true);
cell.addCls(cls);
me.fireEvent('highlightitem', me, cell);
break;
}
}
},
fullUpdate: function(date) {
var me = this,
cells = me.cells.elements,
textNodes = me.textNodes,
disabledCls = me.disabledCellCls,
eDate = Ext.Date,
i = 0,
extraDays = 0,
newDate = +eDate.clearTime(date, true),
today = +eDate.clearTime(new Date()),
min = me.minDate ? eDate.clearTime(me.minDate, true) : Number.NEGATIVE_INFINITY,
max = me.maxDate ? eDate.clearTime(me.maxDate, true) : Number.POSITIVE_INFINITY,
ddMatch = me.disabledDatesRE,
ddText = me.disabledDatesText,
ddays = me.disabledDays ? me.disabledDays.join('') : false,
ddaysText = me.disabledDaysText,
format = me.format,
days = eDate.getDaysInMonth(date),
firstOfMonth = eDate.getFirstDateOfMonth(date),
startingPos = firstOfMonth.getDay() - me.startDay,
previousMonth = eDate.add(date, eDate.MONTH, -1),
ariaTitleDateFormat = me.ariaTitleDateFormat,
prevStart, current, disableToday, tempDate, setCellClass, html, cls, formatValue, value;
if (startingPos < 0) {
startingPos += 7;
}
days += startingPos;
prevStart = eDate.getDaysInMonth(previousMonth) - startingPos;
current = new Date(previousMonth.getFullYear(), previousMonth.getMonth(), prevStart, me.initHour);
if (me.showToday) {
tempDate = eDate.clearTime(new Date());
disableToday = (tempDate < min || tempDate > max || (ddMatch && format && ddMatch.test(eDate.dateFormat(tempDate, format))) || (ddays && ddays.indexOf(tempDate.getDay()) !== -1));
if (!me.disabled) {
me.todayBtn.setDisabled(disableToday);
}
}
setCellClass = function(cellIndex, cls) {
var cell = cells[cellIndex];
value = +eDate.clearTime(current, true);
cell.setAttribute('aria-label', eDate.format(current, ariaTitleDateFormat));
cell.firstChild.dateValue = value;
if (value === today) {
cls += ' ' + me.todayCls;
cell.firstChild.title = me.todayText;
me.todayElSpan = Ext.DomHelper.append(cell.firstChild, {
tag: 'span',
cls: Ext.baseCSSPrefix + 'hidden-clip',
html: me.todayText
}, true);
}
if (value === newDate) {
me.activeCell = cell;
me.eventEl.dom.setAttribute('aria-activedescendant', cell.id);
cell.setAttribute('aria-selected', true);
cls += ' ' + me.selectedCls;
me.fireEvent('highlightitem', me, cell);
} else {
cell.setAttribute('aria-selected', false);
}
if (value < min) {
cls += ' ' + disabledCls;
cell.setAttribute('aria-label', me.minText);
} else if (value > max) {
cls += ' ' + disabledCls;
cell.setAttribute('aria-label', me.maxText);
} else if (ddays && ddays.indexOf(current.getDay()) !== -1) {
cell.setAttribute('aria-label', ddaysText);
cls += ' ' + disabledCls;
} else if (ddMatch && format) {
formatValue = eDate.dateFormat(current, format);
if (ddMatch.test(formatValue)) {
cell.setAttribute('aria-label', ddText.replace('%0', formatValue));
cls += ' ' + disabledCls;
}
}
cell.className = cls + ' ' + me.cellCls;
};
for (; i < me.numDays; ++i) {
if (i < startingPos) {
html = (++prevStart);
cls = me.prevCls;
} else if (i >= days) {
html = (++extraDays);
cls = me.nextCls;
} else {
html = i - startingPos + 1;
cls = me.activeCls;
}
textNodes[i].innerHTML = html;
current.setDate(current.getDate() + 1);
setCellClass(i, cls);
}
me.monthBtn.setText(Ext.Date.format(date, me.monthYearFormat));
},
update: function(date, forceRefresh) {
var me = this,
active = me.activeDate;
if (me.rendered) {
me.activeDate = date;
if (!forceRefresh && active && me.el && active.getMonth() === date.getMonth() && active.getFullYear() === date.getFullYear()) {
me.selectedUpdate(date, active);
} else {
me.fullUpdate(date, active);
}
}
return me;
},
beforeDestroy: function() {
var me = this;
if (me.rendered) {
Ext.destroy(me.keyNav, me.monthPicker, me.monthBtn, me.nextRepeater, me.prevRepeater, me.todayBtn, me.todayElSpan);
delete me.textNodes;
delete me.cells.elements;
}
me.callParent();
},
privates: {
finishRenderChildren: function() {
var me = this;
me.callParent();
me.monthBtn.finishRender();
if (me.showToday) {
me.todayBtn.finishRender();
}
},
getFocusEl: function() {
return this.eventEl;
},
syncDisabled: function(disabled) {
var me = this,
keyNav = me.keyNav;
if (keyNav) {
keyNav.setDisabled(disabled);
me.prevRepeater.setDisabled(disabled);
me.nextRepeater.setDisabled(disabled);
if (me.todayBtn) {
me.todayBtn.setDisabled(disabled);
}
}
}
}
});
Ext.define('Ext.form.field.Date', {
extend: 'Ext.form.field.Picker',
alias: 'widget.datefield',
requires: [
'Ext.picker.Date'
],
alternateClassName: [
'Ext.form.DateField',
'Ext.form.Date'
],
format: "m/d/Y",
altFormats: "m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d|n-j|n/j",
disabledDaysText: "Disabled",
disabledDatesText: "Disabled",
minText: "The date in this field must be equal to or after {0}",
maxText: "The date in this field must be equal to or before {0}",
invalidText: "{0} is not a valid date - it must be in the format {1}",
triggerCls: Ext.baseCSSPrefix + 'form-date-trigger',
showToday: true,
useStrict: undefined,
initTime: '12',
initTimeFormat: 'H',
matchFieldWidth: false,
startDay: 0,
valuePublishEvent: [
'select',
'blur'
],
initComponent: function() {
var me = this,
isString = Ext.isString,
min, max;
min = me.minValue;
max = me.maxValue;
if (isString(min)) {
me.minValue = me.parseDate(min);
}
if (isString(max)) {
me.maxValue = me.parseDate(max);
}
me.disabledDatesRE = null;
me.initDisabledDays();
me.callParent();
},
initValue: function() {
var me = this,
value = me.value;
if (Ext.isString(value)) {
me.value = me.rawToValue(value);
}
me.callParent();
},
initDisabledDays: function() {
if (this.disabledDates) {
var dd = this.disabledDates,
len = dd.length - 1,
re = "(?:",
d,
dLen = dd.length,
date;
for (d = 0; d < dLen; d++) {
date = dd[d];
re += Ext.isDate(date) ? '^' + Ext.String.escapeRegex(date.dateFormat(this.format)) + '$' : date;
if (d !== len) {
re += '|';
}
}
this.disabledDatesRE = new RegExp(re + ')');
}
},
setDisabledDates: function(disabledDates) {
var me = this,
picker = me.picker;
me.disabledDates = disabledDates;
me.initDisabledDays();
if (picker) {
picker.setDisabledDates(me.disabledDatesRE);
}
},
setDisabledDays: function(disabledDays) {
var picker = this.picker;
this.disabledDays = disabledDays;
if (picker) {
picker.setDisabledDays(disabledDays);
}
},
setMinValue: function(value) {
var me = this,
picker = me.picker,
minValue = (Ext.isString(value) ? me.parseDate(value) : value);
me.minValue = minValue;
if (picker) {
picker.minText = Ext.String.format(me.minText, me.formatDate(me.minValue));
picker.setMinDate(minValue);
}
},
setMaxValue: function(value) {
var me = this,
picker = me.picker,
maxValue = (Ext.isString(value) ? me.parseDate(value) : value);
me.maxValue = maxValue;
if (picker) {
picker.maxText = Ext.String.format(me.maxText, me.formatDate(me.maxValue));
picker.setMaxDate(maxValue);
}
},
getErrors: function(value) {
value = arguments.length > 0 ? value : this.formatDate(this.processRawValue(this.getRawValue()));
var me = this,
format = Ext.String.format,
clearTime = Ext.Date.clearTime,
errors = me.callParent([
value
]),
disabledDays = me.disabledDays,
disabledDatesRE = me.disabledDatesRE,
minValue = me.minValue,
maxValue = me.maxValue,
len = disabledDays ? disabledDays.length : 0,
i = 0,
svalue, fvalue, day, time;
if (value === null || value.length < 1) {
return errors;
}
svalue = value;
value = me.parseDate(value);
if (!value) {
errors.push(format(me.invalidText, svalue, Ext.Date.unescapeFormat(me.format)));
return errors;
}
time = value.getTime();
if (minValue && time < clearTime(minValue).getTime()) {
errors.push(format(me.minText, me.formatDate(minValue)));
}
if (maxValue && time > clearTime(maxValue).getTime()) {
errors.push(format(me.maxText, me.formatDate(maxValue)));
}
if (disabledDays) {
day = value.getDay();
for (; i < len; i++) {
if (day === disabledDays[i]) {
errors.push(me.disabledDaysText);
break;
}
}
}
fvalue = me.formatDate(value);
if (disabledDatesRE && disabledDatesRE.test(fvalue)) {
errors.push(format(me.disabledDatesText, fvalue));
}
return errors;
},
rawToValue: function(rawValue) {
return this.parseDate(rawValue) || rawValue || null;
},
valueToRaw: function(value) {
return this.formatDate(this.parseDate(value));
},
safeParse: function(value, format) {
var me = this,
utilDate = Ext.Date,
result = null,
strict = me.useStrict,
parsedDate;
if (utilDate.formatContainsHourInfo(format)) {
result = utilDate.parse(value, format, strict);
} else {
parsedDate = utilDate.parse(value + ' ' + me.initTime, format + ' ' + me.initTimeFormat, strict);
if (parsedDate) {
result = utilDate.clearTime(parsedDate);
}
}
return result;
},
getSubmitValue: function() {
var format = this.submitFormat || this.format,
value = this.getValue();
return value ? Ext.Date.format(value, format) : '';
},
parseDate: function(value) {
if (!value || Ext.isDate(value)) {
return value;
}
var me = this,
val = me.safeParse(value, me.format),
altFormats = me.altFormats,
altFormatsArray = me.altFormatsArray,
i = 0,
len;
if (!val && altFormats) {
altFormatsArray = altFormatsArray || altFormats.split('|');
len = altFormatsArray.length;
for (; i < len && !val; ++i) {
val = me.safeParse(value, altFormatsArray[i]);
}
}
return val;
},
formatDate: function(date) {
return Ext.isDate(date) ? Ext.Date.dateFormat(date, this.format) : date;
},
createPicker: function() {
var me = this,
format = Ext.String.format;
return new Ext.picker.Date({
pickerField: me,
floating: true,
focusable: false,
hidden: true,
minDate: me.minValue,
maxDate: me.maxValue,
disabledDatesRE: me.disabledDatesRE,
disabledDatesText: me.disabledDatesText,
disabledDays: me.disabledDays,
disabledDaysText: me.disabledDaysText,
format: me.format,
showToday: me.showToday,
startDay: me.startDay,
minText: format(me.minText, me.formatDate(me.minValue)),
maxText: format(me.maxText, me.formatDate(me.maxValue)),
listeners: {
scope: me,
select: me.onSelect
},
keyNavConfig: {
esc: function() {
me.collapse();
}
}
});
},
onSelect: function(m, d) {
var me = this;
me.setValue(d);
me.fireEvent('select', me, d);
me.collapse();
},
onExpand: function() {
var value = this.getValue();
this.picker.setValue(Ext.isDate(value) ? value : new Date());
},
onBlur: function(e) {
var me = this,
v = me.rawToValue(me.getRawValue());
if (Ext.isDate(v)) {
me.setValue(v);
}
me.callParent([
e
]);
}
});
Ext.define('Ext.form.field.FileButton', {
extend: 'Ext.button.Button',
alias: 'widget.filebutton',
childEls: [
'fileInputEl'
],
inputCls: Ext.baseCSSPrefix + 'form-file-input',
cls: Ext.baseCSSPrefix + 'form-file-btn',
preventDefault: false,
tabIndex: null,
autoEl: {
tag: 'div',
unselectable: 'on'
},
afterTpl: [
'<input id="{id}-fileInputEl" data-ref="fileInputEl" class="{childElCls} {inputCls}" ',
'type="file" size="1" name="{inputName}" role="{role}" ',
'<tpl if="tabIndex != null">tabindex="{tabIndex}"</tpl>',
'>'
],
getAfterMarkup: function(values) {
return this.getTpl('afterTpl').apply(values);
},
getTemplateArgs: function() {
var args = this.callParent();
args.inputCls = this.inputCls;
args.inputName = this.inputName;
args.tabIndex = this.ownerCt.tabIndex;
return args;
},
afterRender: function() {
var me = this;
me.callParent(arguments);
me.fileInputEl.on({
scope: me,
change: me.fireChange,
focus: me.onFileFocus,
blur: me.onFileBlur
});
},
fireChange: function(e) {
this.fireEvent('change', this, e, this.fileInputEl.dom.value);
},
createFileInput: function(isTemporary) {
var me = this,
fileInputEl = me.fileInputEl = me.el.createChild({
name: me.inputName,
id: !isTemporary ? me.id + '-fileInputEl' : undefined,
cls: me.inputCls,
tag: 'input',
type: 'file',
size: 1,
role: 'button'
});
fileInputEl.dom.setAttribute(Ext.Component.componentIdAttribute, me.id);
fileInputEl.on({
scope: me,
change: me.fireChange,
focus: me.onFileFocus,
blur: me.onFileBlur
});
},
onFileFocus: function(e) {
var ownerCt = this.ownerCt;
if (!this.hasFocus) {
this.onFocus(e);
}
if (ownerCt && !ownerCt.hasFocus) {
ownerCt.onFocus(e);
}
},
onFileBlur: function(e) {
var ownerCt = this.ownerCt;
if (this.hasFocus) {
this.onBlur(e);
}
if (ownerCt && ownerCt.hasFocus) {
ownerCt.onBlur(e);
}
},
reset: function(remove) {
var me = this;
if (remove) {
me.fileInputEl.destroy();
}
me.createFileInput(!remove);
},
restoreInput: function(el) {
var me = this;
me.fileInputEl.destroy();
el = Ext.get(el);
me.el.appendChild(el);
me.fileInputEl = el;
},
onDisable: function() {
this.callParent();
this.fileInputEl.dom.disabled = true;
},
onEnable: function() {
this.callParent();
this.fileInputEl.dom.disabled = false;
},
privates: {
getFocusEl: function() {
return this.fileInputEl;
},
getFocusClsEl: function() {
return this.el;
}
}
});
Ext.define('Ext.form.trigger.Component', {
extend: 'Ext.form.trigger.Trigger',
alias: 'trigger.component',
cls: Ext.baseCSSPrefix + 'form-trigger-cmp',
onFieldRender: function() {
var me = this,
component = me.component;
me.callParent();
if (!component.isComponent && !component.isWidget) {
component = Ext.widget(component);
}
me.component = component;
component.render(me.el);
},
destroy: function() {
var component = this.component;
if (component.isComponent || component.isWidget) {
component.destroy();
}
this.component = null;
this.callParent();
}
});
Ext.define('Ext.form.field.File', {
extend: 'Ext.form.field.Text',
alias: [
'widget.filefield',
'widget.fileuploadfield'
],
alternateClassName: [
'Ext.form.FileUploadField',
'Ext.ux.form.FileUploadField',
'Ext.form.File'
],
requires: [
'Ext.form.field.FileButton',
'Ext.form.trigger.Component'
],
needArrowKeys: false,
triggers: {
filebutton: {
type: 'component',
hideOnReadOnly: false,
preventMouseDown: false
}
},
buttonText: 'Browse...',
buttonOnly: false,
buttonMargin: 3,
clearOnSubmit: true,
extraFieldBodyCls: Ext.baseCSSPrefix + 'form-file-wrap',
inputCls: Ext.baseCSSPrefix + 'form-text-file',
readOnly: true,
editable: false,
submitValue: false,
triggerNoEditCls: '',
childEls: [
'browseButtonWrap'
],
applyTriggers: function(triggers) {
var me = this,
triggerCfg = (triggers || {}).filebutton;
if (triggerCfg) {
triggerCfg.component = Ext.apply({
xtype: 'filebutton',
ownerCt: me,
id: me.id + '-button',
ui: me.ui,
disabled: me.disabled,
text: me.buttonText,
style: me.buttonOnly ? '' : me.getButtonMarginProp() + me.buttonMargin + 'px',
inputName: me.getName(),
listeners: {
scope: me,
change: me.onFileChange
}
}, me.buttonConfig);
return me.callParent([
triggers
]);
} else {
Ext.Error.raise(me.$className + ' requires a valid trigger config containing "filebutton" specification');
}
},
getSubTplData: function(fieldData) {
var data = this.callParent([
fieldData
]);
data.tabIdx = -1;
return data;
},
onRender: function() {
var me = this,
inputEl, button, buttonEl, trigger;
me.callParent(arguments);
inputEl = me.inputEl;
inputEl.dom.name = '';
inputEl.on('focus', me.focus, me);
trigger = me.getTrigger('filebutton');
button = me.button = trigger.component;
me.fileInputEl = button.fileInputEl;
buttonEl = button.el;
if (me.buttonOnly) {
me.inputWrap.setDisplayed(false);
me.shrinkWrap = 3;
}
trigger.el.setWidth(buttonEl.getWidth() + buttonEl.getMargin('lr'));
if (Ext.isIE) {
me.button.getEl().repaint();
}
},
getTriggerMarkup: function() {
return '<td id="' + this.id + '-browseButtonWrap" data-ref="browseButtonWrap" role="presentation"></td>';
},
onFileChange: function(button, e, value) {
this.duringFileSelect = true;
Ext.form.field.File.superclass.setValue.call(this, value);
delete this.duringFileSelect;
},
didValueChange: function() {
return !!this.duringFileSelect;
},
setValue: Ext.emptyFn,
reset: function() {
var me = this,
clear = me.clearOnSubmit;
if (me.rendered) {
me.button.reset(clear);
me.fileInputEl = me.button.fileInputEl;
if (clear) {
me.inputEl.dom.value = '';
Ext.form.field.File.superclass.setValue.call(this, null);
}
}
me.callParent();
},
onShow: function() {
this.callParent();
this.button.updateLayout();
},
onDisable: function() {
this.callParent();
this.button.disable();
},
onEnable: function() {
this.callParent();
this.button.enable();
},
isFileUpload: Ext.returnTrue,
extractFileInput: function() {
var me = this,
fileInput;
if (me.rendered) {
fileInput = me.button.fileInputEl.dom;
me.reset();
} else {
fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.className = Ext.baseCSSPrefix + 'hidden-display';
fileInput.name = me.getName();
}
return fileInput;
},
restoreInput: function(el) {
if (this.rendered) {
var button = this.button;
button.restoreInput(el);
this.fileInputEl = button.fileInputEl;
}
},
onDestroy: function() {
this.fileInputEl = this.button = null;
this.callParent();
},
getButtonMarginProp: function() {
return 'margin-left:';
},
privates: {
getFocusEl: function() {
return this.button;
},
getFocusClsEl: Ext.privateFn
}
});
Ext.define('Ext.form.field.Hidden', {
extend: 'Ext.form.field.Base',
alias: [
'widget.hiddenfield',
'widget.hidden'
],
alternateClassName: 'Ext.form.Hidden',
focusable: false,
inputType: 'hidden',
isTextInput: false,
hideLabel: true,
hidden: true,
ariaRole: 'presentation',
initComponent: function() {
this.formItemCls += '-hidden';
this.callParent();
},
isEqual: function(value1, value2) {
return this.isEqualAsString(value1, value2);
},
initEvents: Ext.emptyFn,
setSize: Ext.emptyFn,
setWidth: Ext.emptyFn,
setHeight: Ext.emptyFn,
setPosition: Ext.emptyFn,
setPagePosition: Ext.emptyFn,
markInvalid: Ext.emptyFn,
clearInvalid: Ext.emptyFn
});
Ext.define('Ext.picker.Color', {
extend: 'Ext.Component',
requires: 'Ext.XTemplate',
alias: 'widget.colorpicker',
alternateClassName: 'Ext.ColorPalette',
focusable: true,
componentCls: Ext.baseCSSPrefix + 'color-picker',
selectedCls: Ext.baseCSSPrefix + 'color-picker-selected',
itemCls: Ext.baseCSSPrefix + 'color-picker-item',
value: null,
clickEvent: 'click',
allowReselect: false,
colors: [
'000000',
'993300',
'333300',
'003300',
'003366',
'000080',
'333399',
'333333',
'800000',
'FF6600',
'808000',
'008000',
'008080',
'0000FF',
'666699',
'808080',
'FF0000',
'FF9900',
'99CC00',
'339966',
'33CCCC',
'3366FF',
'800080',
'969696',
'FF00FF',
'FFCC00',
'FFFF00',
'00FF00',
'00FFFF',
'00CCFF',
'993366',
'C0C0C0',
'FF99CC',
'FFCC99',
'FFFF99',
'CCFFCC',
'CCFFFF',
'99CCFF',
'CC99FF',
'FFFFFF'
],
colorRe: /(?:^|\s)color-(.{6})(?:\s|$)/,
renderTpl: [
'<tpl for="colors">',
'<a href="#" role="button" class="color-{.} {parent.itemCls}" hidefocus="on">',
'<span class="{parent.itemCls}-inner" style="background:#{.}">&#160;</span>',
'</a>',
'</tpl>'
],
initComponent: function() {
var me = this;
me.callParent(arguments);
if (me.handler) {
me.on('select', me.handler, me.scope, true);
}
},
initRenderData: function() {
var me = this;
return Ext.apply(me.callParent(), {
itemCls: me.itemCls,
colors: me.colors
});
},
onRender: function() {
var me = this,
clickEvent = me.clickEvent;
me.callParent(arguments);
me.mon(me.el, clickEvent, me.handleClick, me, {
delegate: 'a'
});
if (clickEvent !== 'click') {
me.mon(me.el, 'click', Ext.emptyFn, me, {
delegate: 'a',
stopEvent: true
});
}
},
afterRender: function() {
var me = this,
value;
me.callParent(arguments);
if (me.value) {
value = me.value;
me.value = null;
me.select(value, true);
}
},
handleClick: function(event) {
var me = this,
color;
event.stopEvent();
if (!me.disabled) {
color = event.currentTarget.className.match(me.colorRe)[1];
me.select(color.toUpperCase());
}
},
select: function(color, suppressEvent) {
var me = this,
selectedCls = me.selectedCls,
value = me.value,
el, item;
color = color.replace('#', '');
if (!me.rendered) {
me.value = color;
return;
}
if (color !== value || me.allowReselect) {
el = me.el;
if (me.value) {
item = el.down('a.color-' + value, true);
Ext.fly(item).removeCls(selectedCls);
}
item = el.down('a.color-' + color, true);
Ext.fly(item).addCls(selectedCls);
me.value = color;
if (suppressEvent !== true) {
me.fireEvent('select', me, color);
}
}
},
clear: function() {
var me = this,
value = me.value,
el;
if (value && me.rendered) {
el = me.el.down('a.color-' + value, true);
Ext.fly(el).removeCls(me.selectedCls);
}
me.value = null;
},
getValue: function() {
return this.value || null;
}
});
Ext.define('Ext.layout.component.field.HtmlEditor', {
extend: 'Ext.layout.component.field.FieldContainer',
alias: [
'layout.htmleditor'
],
type: 'htmleditor',
naturalHeight: 150,
naturalWidth: 300,
beginLayout: function(ownerContext) {
var owner = this.owner,
dom;
if (Ext.isGecko) {
dom = owner.textareaEl.dom;
this.lastValue = dom.value;
dom.value = '';
}
this.callParent(arguments);
ownerContext.toolbarContext = ownerContext.context.getCmp(owner.toolbar);
ownerContext.inputCmpContext = ownerContext.context.getCmp(owner.inputCmp);
ownerContext.bodyCellContext = ownerContext.getEl('bodyEl');
ownerContext.textAreaContext = ownerContext.getEl('textareaEl');
ownerContext.iframeContext = ownerContext.getEl('iframeEl');
},
beginLayoutCycle: function(ownerContext) {
var me = this,
widthModel = ownerContext.widthModel,
heightModel = ownerContext.heightModel,
owner = me.owner,
iframeEl = owner.iframeEl,
textareaEl = owner.textareaEl,
height = (heightModel.natural || heightModel.shrinkWrap) ? me.naturalHeight : '';
me.callParent(arguments);
if (widthModel.shrinkWrap) {
iframeEl.setStyle('width', '');
textareaEl.setStyle('width', '');
} else if (widthModel.natural) {
ownerContext.bodyCellContext.setWidth(me.naturalWidth);
}
iframeEl.setStyle('height', height);
textareaEl.setStyle('height', height);
},
finishedLayout: function() {
var owner = this.owner;
this.callParent(arguments);
if (Ext.isGecko) {
owner.textareaEl.dom.value = this.lastValue;
}
}
});
Ext.define('Ext.toolbar.Separator', {
extend: 'Ext.toolbar.Item',
requires: [
'Ext.toolbar.Toolbar'
],
alias: 'widget.tbseparator',
alternateClassName: 'Ext.Toolbar.Separator',
baseCls: Ext.baseCSSPrefix + 'toolbar-separator',
ariaRole: 'separator'
});
Ext.define('Ext.layout.container.boxOverflow.Menu', {
extend: 'Ext.layout.container.boxOverflow.None',
requires: [
'Ext.toolbar.Separator',
'Ext.button.Button'
],
alternateClassName: 'Ext.layout.boxOverflow.Menu',
alias: [
'box.overflow.menu',
'box.overflow.Menu'
],
noItemsMenuText: '<div class="' + Ext.baseCSSPrefix + 'toolbar-no-items" role="menuitem">(None)</div>',
menuCls: Ext.baseCSSPrefix + 'box-menu',
constructor: function(config) {
var me = this;
me.callParent([
config
]);
me.menuItems = [];
},
beginLayout: function(ownerContext) {
this.callParent([
ownerContext
]);
this.clearOverflow(ownerContext);
},
beginLayoutCycle: function(ownerContext, firstCycle) {
this.callParent([
ownerContext,
firstCycle
]);
if (!firstCycle) {
this.clearOverflow(ownerContext);
this.layout.cacheChildItems(ownerContext);
}
},
onRemove: function(comp) {
Ext.Array.remove(this.menuItems, comp);
},
clearItem: function(comp) {
var menu = comp.menu;
if (comp.isButton && menu) {
comp.setMenu(menu, false);
}
},
getSuffixConfig: function() {
var me = this,
layout = me.layout,
owner = layout.owner,
oid = owner.id;
me.menu = new Ext.menu.Menu({
listeners: {
scope: me,
beforeshow: me.beforeMenuShow
}
});
me.menuTrigger = new Ext.button.Button({
id: oid + '-menu-trigger',
cls: me.menuCls + '-after ' + Ext.baseCSSPrefix + 'toolbar-item',
plain: owner.usePlainButtons,
ownerCt: owner,
ownerLayout: layout,
iconCls: Ext.baseCSSPrefix + me.getOwnerType(owner) + '-more-icon',
ui: owner.defaultButtonUI || 'default',
menu: me.menu,
showEmptyMenu: true,
getSplitCls: function() {
return '';
}
});
return me.menuTrigger.getRenderTree();
},
getOverflowCls: function(direction) {
return this.menuCls + '-body-' + direction;
},
handleOverflow: function(ownerContext) {
var me = this,
layout = me.layout;
me.showTrigger(ownerContext);
if (layout.direction !== 'vertical') {
me.menuTrigger.setLocalY((ownerContext.state.boxPlan.maxSize - me.menuTrigger[layout.names.getHeight]()) / 2);
}
return {
reservedSpace: me.triggerTotalWidth
};
},
captureChildElements: function() {
var me = this,
menuTrigger = me.menuTrigger,
names = me.layout.names;
if (menuTrigger.rendering) {
menuTrigger.finishRender();
me.triggerTotalWidth = menuTrigger[names.getWidth]() + menuTrigger.el.getMargin(names.parallelMargins);
}
},
clearOverflow: function(ownerContext) {
var me = this,
items = me.menuItems,
length = items.length,
owner = me.layout.owner,
asLayoutRoot = owner._asLayoutRoot,
item, i;
owner.suspendLayouts();
me.captureChildElements();
me.hideTrigger();
owner.resumeLayouts();
for (i = 0; i < length; i++) {
item = items[i];
item.suspendLayouts();
item.show();
me.clearItem(item);
item.resumeLayouts(asLayoutRoot);
}
items.length = 0;
},
showTrigger: function(ownerContext) {
var me = this,
layout = me.layout,
owner = layout.owner,
names = layout.names,
startProp = names.x,
sizeProp = names.width,
plan = ownerContext.state.boxPlan,
available = plan.targetSize[sizeProp],
childItems = ownerContext.childItems,
menuTrigger = me.menuTrigger,
menuItems = me.menuItems,
childContext, comp, i, props, len;
menuTrigger.suspendLayouts();
menuTrigger.show();
menuTrigger.resumeLayouts(me._asLayoutRoot);
available -= me.triggerTotalWidth;
owner.suspendLayouts();
for (i = 0 , len = menuItems.length; i < len; ++i) {
me.clearItem(menuItems[i]);
}
menuItems.length = 0;
for (i = 0 , len = childItems.length; i < len; i++) {
childContext = childItems[i];
props = childContext.props;
if (props[startProp] + props[sizeProp] > available) {
comp = childContext.target;
me.menuItems.push(comp);
comp.hide();
}
}
owner.resumeLayouts();
},
hideTrigger: function() {
var menuTrigger = this.menuTrigger;
if (menuTrigger) {
menuTrigger.hide();
}
},
beforeMenuShow: function(menu) {
var me = this,
items = me.menuItems,
i = 0,
len = items.length,
item, prev,
needsSep = function(group, prev) {
return group.isXType('buttongroup') && !(prev instanceof Ext.toolbar.Separator);
};
menu.suspendLayouts();
menu.removeAll(false);
for (; i < len; i++) {
item = items[i];
if (!i && (item instanceof Ext.toolbar.Separator)) {
continue;
}
if (prev && (needsSep(item, prev) || needsSep(prev, item))) {
menu.add('-');
}
me.addComponentToMenu(menu, item);
prev = item;
}
if (menu.items.length < 1) {
menu.add(me.noItemsMenuText);
}
menu.resumeLayouts();
},
createMenuConfig: function(component, hideOnClick) {
var config = Ext.apply({}, component.initialConfig),
group = component.toggleGroup;
Ext.copyTo(config, component, [
'iconCls',
'icon',
'itemId',
'disabled',
'handler',
'scope',
'menu',
'tabIndex'
]);
Ext.applyIf(config, {
text: component.overflowText || component.text,
hideOnClick: hideOnClick,
destroyMenu: false,
listeners: null
});
if (component.isFormField) {
config.value = component.getValue();
config.listeners = {
change: function(c, newVal, oldVal) {
component.setValue(newVal);
}
};
}
else if (group || component.enableToggle) {
Ext.apply(config, {
hideOnClick: false,
group: group,
checked: component.pressed,
handler: function(item, e) {
component.onClick(e);
}
});
}
if (component.isButton && !component.changeListenersAdded) {
component.on({
textchange: this.onButtonAttrChange,
iconchange: this.onButtonAttrChange,
toggle: this.onButtonToggle
});
component.changeListenersAdded = true;
}
delete config.margin;
delete config.ownerCt;
delete config.xtype;
delete config.id;
delete config.itemId;
return config;
},
onButtonAttrChange: function(btn) {
var clone = btn.overflowClone;
clone.suspendLayouts();
clone.setText(btn.text);
clone.setIcon(btn.icon);
clone.setIconCls(btn.iconCls);
clone.resumeLayouts(true);
},
onButtonToggle: function(btn, state) {
if (btn.overflowClone.checked !== state) {
btn.overflowClone.setChecked(state);
}
},
addComponentToMenu: function(menu, component) {
var me = this,
i, items, iLen;
if (component instanceof Ext.toolbar.Fill) {
return;
}
else if (component instanceof Ext.toolbar.Separator) {
menu.add('-');
} else if (component.overflowClone) {
menu.add(component.overflowClone);
}
else if (component.isComponent) {
if (component.isXType('splitbutton')) {
component.overflowClone = menu.add(me.createMenuConfig(component, true));
} else if (component.isXType('button')) {
component.overflowClone = menu.add(me.createMenuConfig(component, !component.menu));
} else if (component.isXType('buttongroup')) {
items = component.items.items;
iLen = items.length;
for (i = 0; i < iLen; i++) {
me.addComponentToMenu(menu, items[i]);
}
} else {
component.overflowClone = menu.add(Ext.create(Ext.getClassName(component), me.createMenuConfig(component)));
}
}
},
destroy: function() {
var trigger = this.menuTrigger;
if (trigger && !this.layout.owner.items.contains(trigger)) {
delete trigger.ownerCt;
}
Ext.destroy(this.menu, trigger);
}
});
Ext.define('Ext.form.field.HtmlEditor', {
extend: 'Ext.form.FieldContainer',
mixins: {
field: 'Ext.form.field.Field'
},
alias: 'widget.htmleditor',
alternateClassName: 'Ext.form.HtmlEditor',
requires: [
'Ext.tip.QuickTipManager',
'Ext.picker.Color',
'Ext.layout.container.VBox',
'Ext.toolbar.Item',
'Ext.toolbar.Toolbar',
'Ext.util.Format',
'Ext.layout.component.field.HtmlEditor',
'Ext.util.TaskManager',
'Ext.layout.container.boxOverflow.Menu'
],
focusable: true,
componentLayout: 'htmleditor',
textareaCls: Ext.baseCSSPrefix + 'htmleditor-textarea',
componentTpl: [
'{beforeTextAreaTpl}',
'<textarea id="{id}-textareaEl" data-ref="textareaEl" name="{name}" tabindex="-1" {inputAttrTpl}',
' class="{textareaCls}" autocomplete="off">',
'{[Ext.util.Format.htmlEncode(values.value)]}',
'</textarea>',
'{afterTextAreaTpl}',
'{beforeIFrameTpl}',
'<iframe id="{id}-iframeEl" data-ref="iframeEl" name="{iframeName}" frameBorder="0" {iframeAttrTpl}',
' src="{iframeSrc}" class="{iframeCls}"></iframe>',
'{afterIFrameTpl}',
{
disableFormats: true
}
],
stretchInputElFixed: true,
subTplInsertions: [
'beforeTextAreaTpl',
'afterTextAreaTpl',
'beforeIFrameTpl',
'afterIFrameTpl',
'iframeAttrTpl',
'inputAttrTpl'
],
enableFormat: true,
enableFontSize: true,
enableColors: true,
enableAlignments: true,
enableLists: true,
enableSourceEdit: true,
enableLinks: true,
enableFont: true,
createLinkText: 'Please enter the URL for the link:',
defaultLinkValue: 'http:/' + '/',
fontFamilies: [
'Arial',
'Courier New',
'Tahoma',
'Times New Roman',
'Verdana'
],
defaultValue: Ext.isOpera ? '&#160;' : '&#8203;',
extraFieldBodyCls: Ext.baseCSSPrefix + 'html-editor-wrap',
defaultButtonUI: 'default-toolbar',
initialized: false,
activated: false,
sourceEditMode: false,
iframePad: 3,
hideMode: 'offsets',
maskOnDisable: true,
containerElCls: Ext.baseCSSPrefix + 'html-editor-container',
reStripQuotes: /^['"]*|['"]*$/g,
textAlignRE: /text-align:(.*?);/i,
safariNonsenseRE: /\sclass="(?:Apple-style-span|Apple-tab-span|khtml-block-placeholder)"/gi,
nonDigitsRE: /\D/g,
initComponent: function() {
var me = this;
me.items = [
me.createToolbar(),
me.createInputCmp()
];
me.layout = {
type: 'vbox',
align: 'stretch'
};
if (me.value == null) {
me.value = '';
}
me.callParent(arguments);
me.initField();
},
createInputCmp: function() {
this.inputCmp = Ext.widget(this.getInputCmpCfg());
return this.inputCmp;
},
getInputCmpCfg: function() {
var me = this,
id = me.id + '-inputCmp',
data = {
id: id,
name: me.name,
textareaCls: me.textareaCls + ' ' + Ext.baseCSSPrefix + 'hidden',
value: me.value,
iframeName: Ext.id(),
iframeSrc: Ext.SSL_SECURE_URL,
iframeCls: Ext.baseCSSPrefix + 'htmleditor-iframe'
};
me.getInsertionRenderData(data, me.subTplInsertions);
return {
flex: 1,
xtype: 'component',
tpl: me.getTpl('componentTpl'),
childEls: [
'iframeEl',
'textareaEl'
],
id: id,
cls: Ext.baseCSSPrefix + 'html-editor-input',
data: data
};
},
createToolbar: function() {
this.toolbar = Ext.widget(this.getToolbarCfg());
return this.toolbar;
},
getToolbarCfg: function() {
var me = this,
items = [],
i,
tipsEnabled = Ext.quickTipsActive && Ext.tip.QuickTipManager.isEnabled(),
baseCSSPrefix = Ext.baseCSSPrefix,
fontSelectItem, undef;
function btn(id, toggle, handler) {
return {
itemId: id,
cls: baseCSSPrefix + 'btn-icon',
iconCls: baseCSSPrefix + 'edit-' + id,
enableToggle: toggle !== false,
scope: me,
handler: handler || me.relayBtnCmd,
clickEvent: 'mousedown',
tooltip: tipsEnabled ? me.buttonTips[id] || undef : undef,
overflowText: me.buttonTips[id].title || undef,
tabIndex: -1
};
}
if (me.enableFont && !Ext.isSafari2) {
fontSelectItem = Ext.widget('component', {
itemId: 'fontSelect',
renderTpl: [
'<select id="{id}-selectEl" data-ref="selectEl" class="' + baseCSSPrefix + 'font-select">',
'</select>'
],
childEls: [
'selectEl'
],
afterRender: function() {
me.fontSelect = this.selectEl;
Ext.Component.prototype.afterRender.apply(this, arguments);
},
onDisable: function() {
var selectEl = this.selectEl;
if (selectEl) {
selectEl.dom.disabled = true;
}
Ext.Component.prototype.onDisable.apply(this, arguments);
},
onEnable: function() {
var selectEl = this.selectEl;
if (selectEl) {
selectEl.dom.disabled = false;
}
Ext.Component.prototype.onEnable.apply(this, arguments);
},
listeners: {
change: function() {
me.win.focus();
me.relayCmd('fontName', me.fontSelect.dom.value);
me.deferFocus();
},
element: 'selectEl'
}
});
items.push(fontSelectItem, '-');
}
if (me.enableFormat) {
items.push(btn('bold'), btn('italic'), btn('underline'));
}
if (me.enableFontSize) {
items.push('-', btn('increasefontsize', false, me.adjustFont), btn('decreasefontsize', false, me.adjustFont));
}
if (me.enableColors) {
items.push('-', {
itemId: 'forecolor',
cls: baseCSSPrefix + 'btn-icon',
iconCls: baseCSSPrefix + 'edit-forecolor',
overflowText: me.buttonTips.forecolor.title,
tooltip: tipsEnabled ? me.buttonTips.forecolor || undef : undef,
tabIndex: -1,
menu: Ext.widget('menu', {
plain: true,
items: [
{
xtype: 'colorpicker',
allowReselect: true,
focus: Ext.emptyFn,
value: '000000',
plain: true,
clickEvent: 'mousedown',
handler: function(cp, color) {
me.relayCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#' + color : color);
this.up('menu').hide();
}
}
]
})
}, {
itemId: 'backcolor',
cls: baseCSSPrefix + 'btn-icon',
iconCls: baseCSSPrefix + 'edit-backcolor',
overflowText: me.buttonTips.backcolor.title,
tooltip: tipsEnabled ? me.buttonTips.backcolor || undef : undef,
tabIndex: -1,
menu: Ext.widget('menu', {
plain: true,
items: [
{
xtype: 'colorpicker',
focus: Ext.emptyFn,
value: 'FFFFFF',
plain: true,
allowReselect: true,
clickEvent: 'mousedown',
handler: function(cp, color) {
if (Ext.isGecko) {
me.execCmd('useCSS', false);
me.execCmd('hilitecolor', '#' + color);
me.execCmd('useCSS', true);
me.deferFocus();
} else {
me.relayCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE || Ext.isOpera ? '#' + color : color);
}
this.up('menu').hide();
}
}
]
})
});
}
if (me.enableAlignments) {
items.push('-', btn('justifyleft'), btn('justifycenter'), btn('justifyright'));
}
if (!Ext.isSafari2) {
if (me.enableLinks) {
items.push('-', btn('createlink', false, me.createLink));
}
if (me.enableLists) {
items.push('-', btn('insertorderedlist'), btn('insertunorderedlist'));
}
if (me.enableSourceEdit) {
items.push('-', btn('sourceedit', true, function() {
me.toggleSourceEdit(!me.sourceEditMode);
}));
}
}
for (i = 0; i < items.length; i++) {
if (items[i].itemId !== 'sourceedit') {
items[i].disabled = true;
}
}
return {
xtype: 'toolbar',
defaultButtonUI: me.defaultButtonUI,
cls: Ext.baseCSSPrefix + 'html-editor-tb',
enableOverflow: true,
items: items,
listeners: {
click: function(e) {
e.preventDefault();
},
element: 'el'
}
};
},
getMaskTarget: function() {
return Ext.isGecko ? this.inputCmp.el : this.bodyEl;
},
setReadOnly: function(readOnly) {
var me = this,
textareaEl = me.textareaEl,
iframeEl = me.iframeEl,
body;
me.readOnly = readOnly;
if (textareaEl) {
textareaEl.dom.readOnly = readOnly;
}
if (me.initialized) {
body = me.getEditorBody();
if (Ext.isIE) {
iframeEl.setDisplayed(false);
body.contentEditable = !readOnly;
iframeEl.setDisplayed(true);
} else {
me.setDesignMode(!readOnly);
}
if (body) {
body.style.cursor = readOnly ? 'default' : 'text';
}
me.disableItems(readOnly);
}
},
getDocMarkup: function() {
var me = this,
h = me.iframeEl.getHeight() - me.iframePad * 2;
return Ext.String.format('<!DOCTYPE html>' + '<html><head><style type="text/css">' + (Ext.isOpera ? 'p{margin:0;}' : '') + 'body{border:0;margin:0;padding:{0}px;direction:' + (me.rtl ? 'rtl;' : 'ltr;') + (Ext.isIE8 ? Ext.emptyString : 'min-') + 'height:{1}px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;cursor:text;background-color:white;' + (Ext.isIE ? '' : 'font-size:12px;font-family:{2}') + '}</style></head><body></body></html>', me.iframePad, h, me.defaultFont);
},
getEditorBody: function() {
var doc = this.getDoc();
return doc.body || doc.documentElement;
},
getDoc: function() {
return this.iframeEl.dom.contentDocument || this.getWin().document;
},
getWin: function() {
return this.iframeEl.dom.contentWindow || window.frames[this.iframeEl.dom.name];
},
initDefaultFont: function() {
var me = this,
selIdx = 0,
fonts, font, select, option, i, len, lower;
if (!me.defaultFont) {
font = me.textareaEl.getStyle('font-family');
font = Ext.String.capitalize(font.split(',')[0]);
fonts = Ext.Array.clone(me.fontFamilies);
Ext.Array.include(fonts, font);
fonts.sort();
me.defaultFont = font;
select = me.down('#fontSelect').selectEl.dom;
for (i = 0 , len = fonts.length; i < len; ++i) {
font = fonts[i];
lower = font.toLowerCase();
option = new Option(font, lower);
if (font === me.defaultFont) {
selIdx = i;
}
option.style.fontFamily = lower;
if (Ext.isIE) {
select.add(option);
} else {
select.options.add(option);
}
}
select.options[selIdx].selected = true;
}
},
isEqual: function(value1, value2) {
return this.isEqualAsString(value1, value2);
},
afterRender: function() {
var me = this,
inputCmp = me.inputCmp;
me.callParent(arguments);
me.iframeEl = inputCmp.iframeEl;
me.textareaEl = inputCmp.textareaEl;
me.inputEl = me.iframeEl;
if (me.enableFont) {
me.initDefaultFont();
}
me.monitorTask = Ext.TaskManager.start({
run: me.checkDesignMode,
scope: me,
interval: 100
});
},
initFrameDoc: function() {
var me = this,
doc, task;
Ext.TaskManager.stop(me.monitorTask);
doc = me.getDoc();
me.win = me.getWin();
doc.open();
doc.write(me.getDocMarkup());
doc.close();
task = {
run: function() {
var doc = me.getDoc();
if (doc.body || doc.readyState === 'complete') {
Ext.TaskManager.stop(task);
me.setDesignMode(true);
Ext.defer(me.initEditor, 10, me);
}
},
interval: 10,
duration: 10000,
scope: me
};
Ext.TaskManager.start(task);
},
checkDesignMode: function() {
var me = this,
doc = me.getDoc();
if (doc && (!doc.editorInitialized || me.getDesignMode() !== 'on')) {
me.initFrameDoc();
}
},
setDesignMode: function(mode) {
var me = this,
doc = me.getDoc();
if (doc) {
if (me.readOnly) {
mode = false;
}
doc.designMode = (/on|true/i).test(String(mode).toLowerCase()) ? 'on' : 'off';
}
},
getDesignMode: function() {
var doc = this.getDoc();
return !doc ? '' : String(doc.designMode).toLowerCase();
},
disableItems: function(disabled) {
var items = this.getToolbar().items.items,
i,
iLen = items.length,
item;
for (i = 0; i < iLen; i++) {
item = items[i];
if (item.getItemId() !== 'sourceedit') {
item.setDisabled(disabled);
}
}
},
toggleSourceEdit: function(sourceEditMode) {
var me = this,
iframe = me.iframeEl,
textarea = me.textareaEl,
hiddenCls = Ext.baseCSSPrefix + 'hidden',
btn = me.getToolbar().getComponent('sourceedit');
if (!Ext.isBoolean(sourceEditMode)) {
sourceEditMode = !me.sourceEditMode;
}
me.sourceEditMode = sourceEditMode;
if (btn.pressed !== sourceEditMode) {
btn.toggle(sourceEditMode);
}
if (sourceEditMode) {
me.disableItems(true);
me.syncValue();
iframe.addCls(hiddenCls);
textarea.removeCls(hiddenCls);
textarea.dom.removeAttribute('tabindex');
textarea.focus();
me.inputEl = textarea;
} else {
if (me.initialized) {
me.disableItems(me.readOnly);
}
me.pushValue();
iframe.removeCls(hiddenCls);
textarea.addCls(hiddenCls);
textarea.dom.setAttribute('tabindex', -1);
me.deferFocus();
me.inputEl = iframe;
}
me.fireEvent('editmodechange', me, sourceEditMode);
me.updateLayout();
},
createLink: function() {
var url = prompt(this.createLinkText, this.defaultLinkValue);
if (url && url !== 'http:/' + '/') {
this.relayCmd('createlink', url);
}
},
clearInvalid: Ext.emptyFn,
setValue: function(value) {
var me = this,
textarea = me.textareaEl;
if (value === null || value === undefined) {
value = '';
}
if (me.value !== value) {
if (textarea) {
textarea.dom.value = value;
}
me.pushValue();
if (!me.rendered && me.inputCmp) {
me.inputCmp.data.value = value;
}
me.mixins.field.setValue.call(me, value);
}
return me;
},
cleanHtml: function(html) {
html = String(html);
if (Ext.isWebKit) {
html = html.replace(this.safariNonsenseRE, '');
}
if (html.charCodeAt(0) === parseInt(this.defaultValue.replace(this.nonDigitsRE, ''), 10)) {
html = html.substring(1);
}
return html;
},
syncValue: function() {
var me = this,
body, changed, html, bodyStyle, match, textElDom;
if (me.initialized) {
body = me.getEditorBody();
html = body.innerHTML;
textElDom = me.textareaEl.dom;
if (Ext.isWebKit) {
bodyStyle = body.getAttribute('style');
match = bodyStyle.match(me.textAlignRE);
if (match && match[1]) {
html = '<div style="' + match[0] + '">' + html + '</div>';
}
}
html = me.cleanHtml(html);
if (me.fireEvent('beforesync', me, html) !== false) {
if (Ext.isGecko && textElDom.value === '' && html === '<br>') {
html = '';
}
if (textElDom.value !== html) {
textElDom.value = html;
changed = true;
}
me.fireEvent('sync', me, html);
if (changed) {
me.checkChange();
}
}
}
},
getValue: function() {
var me = this,
value;
if (!me.sourceEditMode) {
me.syncValue();
}
value = me.rendered ? me.textareaEl.dom.value : me.value;
me.value = value;
return value;
},
pushValue: function() {
var me = this,
v;
if (me.initialized) {
v = me.textareaEl.dom.value || '';
if (!me.activated && v.length < 1) {
v = me.defaultValue;
}
if (me.fireEvent('beforepush', me, v) !== false) {
me.getEditorBody().innerHTML = v;
if (Ext.isGecko) {
me.setDesignMode(false);
me.setDesignMode(true);
}
me.fireEvent('push', me, v);
}
}
},
focus: function(selectText, delay) {
var me = this,
value, focusEl;
if (delay) {
if (!me.focusTask) {
me.focusTask = new Ext.util.DelayedTask(me.focus);
}
me.focusTask.delay(Ext.isNumber(delay) ? delay : 10, null, me, [
selectText,
false
]);
} else {
if (selectText) {
if (me.textareaEl && me.textareaEl.dom) {
value = me.textareaEl.dom.value;
}
if (value && value.length) {
me.execCmd('selectall', true);
}
}
focusEl = me.getFocusEl();
if (focusEl && focusEl.focus) {
focusEl.focus();
}
}
return me;
},
initEditor: function() {
var me = this,
dbody, ss, doc, docEl, fn;
if (me.destroying || me.isDestroyed) {
return;
}
dbody = me.getEditorBody();
if (!dbody) {
setTimeout(function() {
me.initEditor();
}, 10);
return;
}
ss = me.textareaEl.getStyle([
'font-size',
'font-family',
'background-image',
'background-repeat',
'background-color',
'color'
]);
ss['background-attachment'] = 'fixed';
dbody.bgProperties = 'fixed';
Ext.DomHelper.applyStyles(dbody, ss);
doc = me.getDoc();
docEl = Ext.get(doc);
if (docEl) {
try {
docEl.clearListeners();
} catch (e) {}
fn = me.onEditorEvent.bind(me);
docEl.on({
mousedown: fn,
dblclick: fn,
click: fn,
keyup: fn,
delegated: false,
buffer: 100
});
fn = me.onRelayedEvent;
docEl.on({
mousedown: fn,
mousemove: fn,
mouseup: fn,
click: fn,
dblclick: fn,
delegated: false,
scope: me
});
if (Ext.isGecko) {
docEl.on('keypress', me.applyCommand, me);
}
if (me.fixKeys) {
docEl.on('keydown', me.fixKeys, me, {
delegated: false
});
}
if (me.fixKeysAfter) {
docEl.on('keyup', me.fixKeysAfter, me, {
delegated: false
});
}
if (Ext.isIE9) {
Ext.get(doc.documentElement).on('focus', me.focus, me);
}
if (Ext.isIE8) {
docEl.on('focusout', function() {
me.savedSelection = doc.selection.type !== 'None' ? doc.selection.createRange() : null;
}, me);
docEl.on('focusin', function() {
if (me.savedSelection) {
me.savedSelection.select();
}
}, me);
}
Ext.getWin().on('beforeunload', me.beforeDestroy, me);
doc.editorInitialized = true;
me.initialized = true;
me.pushValue();
me.setReadOnly(me.readOnly);
me.fireEvent('initialize', me);
}
},
beforeDestroy: function() {
var me = this,
monitorTask = me.monitorTask,
doc, prop;
if (monitorTask) {
Ext.TaskManager.stop(monitorTask);
}
if (me.rendered) {
Ext.getWin().un(me.beforeDestroy, me);
doc = me.getDoc();
if (doc) {
Ext.get(doc).destroy();
if (doc.hasOwnProperty) {
for (prop in doc) {
try {
if (doc.hasOwnProperty(prop)) {
delete doc[prop];
}
} catch (e) {}
}
}
}
delete me.iframeEl;
delete me.textareaEl;
delete me.toolbar;
delete me.inputCmp;
}
me.callParent();
},
onRelayedEvent: function(event) {
var iframeEl = this.iframeEl,
iframeXY = Ext.fly(iframeEl).getTrueXY(),
originalEventXY = event.getXY(),
eventXY = event.getXY();
event.xy = [
iframeXY[0] + eventXY[0],
iframeXY[1] + eventXY[1]
];
event.injectEvent(iframeEl);
event.xy = originalEventXY;
},
onFirstFocus: function() {
var me = this,
selection, range;
me.activated = true;
me.disableItems(me.readOnly);
if (Ext.isGecko) {
me.win.focus();
selection = me.win.getSelection();
if (selection.focusNode && !me.getValue().length) {
range = selection.getRangeAt(0);
range.selectNodeContents(me.getEditorBody());
range.collapse(true);
me.deferFocus();
}
try {
me.execCmd('useCSS', true);
me.execCmd('styleWithCSS', false);
} catch (e) {}
}
me.fireEvent('activate', me);
},
adjustFont: function(btn) {
var adjust = btn.getItemId() === 'increasefontsize' ? 1 : -1,
size = this.getDoc().queryCommandValue('FontSize') || '2',
isPxSize = Ext.isString(size) && size.indexOf('px') !== -1,
isSafari;
size = parseInt(size, 10);
if (isPxSize) {
if (size <= 10) {
size = 1 + adjust;
} else if (size <= 13) {
size = 2 + adjust;
} else if (size <= 16) {
size = 3 + adjust;
} else if (size <= 18) {
size = 4 + adjust;
} else if (size <= 24) {
size = 5 + adjust;
} else {
size = 6 + adjust;
}
size = Ext.Number.constrain(size, 1, 6);
} else {
isSafari = Ext.isSafari;
if (isSafari) {
adjust *= 2;
}
size = Math.max(1, size + adjust) + (isSafari ? 'px' : 0);
}
this.relayCmd('FontSize', size);
},
onEditorEvent: function() {
this.updateToolbar();
},
updateToolbar: function() {
var me = this,
i, l, btns, doc, name, queriedName, fontSelect, toolbarSubmenus;
if (me.readOnly) {
return;
}
if (!me.activated) {
me.onFirstFocus();
return;
}
btns = me.getToolbar().items.map;
doc = me.getDoc();
if (me.enableFont && !Ext.isSafari2) {
queriedName = doc.queryCommandValue('fontName');
name = (queriedName ? queriedName.split(",")[0].replace(me.reStripQuotes, '') : me.defaultFont).toLowerCase();
fontSelect = me.fontSelect.dom;
if (name !== fontSelect.value || name !== queriedName) {
fontSelect.value = name;
}
}
function updateButtons() {
var state;
for (i = 0 , l = arguments.length , name; i < l; i++) {
name = arguments[i];
try {
state = doc.queryCommandState(name);
} catch (e) {
state = false;
}
btns[name].toggle(state);
}
}
if (me.enableFormat) {
updateButtons('bold', 'italic', 'underline');
}
if (me.enableAlignments) {
updateButtons('justifyleft', 'justifycenter', 'justifyright');
}
if (!Ext.isSafari2 && me.enableLists) {
updateButtons('insertorderedlist', 'insertunorderedlist');
}
toolbarSubmenus = me.toolbar.query('menu');
for (i = 0; i < toolbarSubmenus.length; i++) {
toolbarSubmenus[i].hide();
}
me.syncValue();
},
relayBtnCmd: function(btn) {
this.relayCmd(btn.getItemId());
},
relayCmd: function(cmd, value) {
Ext.defer(function() {
var me = this;
if (!this.isDestroyed) {
me.win.focus();
me.execCmd(cmd, value);
me.updateToolbar();
}
}, 10, this);
},
execCmd: function(cmd, value) {
var me = this,
doc = me.getDoc();
doc.execCommand(cmd, false, (value === undefined ? null : value));
me.syncValue();
},
applyCommand: function(e) {
if (e.ctrlKey) {
var me = this,
c = e.getCharCode(),
cmd;
if (c > 0) {
c = String.fromCharCode(c);
switch (c) {
case 'b':
cmd = 'bold';
break;
case 'i':
cmd = 'italic';
break;
case 'u':
cmd = 'underline';
break;
}
if (cmd) {
me.win.focus();
me.execCmd(cmd);
me.deferFocus();
e.preventDefault();
}
}
}
},
insertAtCursor: function(text) {
var me = this,
win = me.getWin(),
doc = me.getDoc(),
sel, range, el, frag, node, lastNode, firstNode;
if (me.activated) {
win.focus();
if (win.getSelection) {
sel = win.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
el = doc.createElement("div");
el.innerHTML = text;
frag = doc.createDocumentFragment();
while ((node = el.firstChild)) {
lastNode = frag.appendChild(node);
}
firstNode = frag.firstChild;
range.insertNode(frag);
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
} else if (doc.selection && sel.type !== 'Control') {
sel = doc.selection;
range = sel.createRange();
range.collapse(true);
sel.createRange().pasteHTML(text);
}
me.deferFocus();
}
},
fixKeys: (function() {
var tag;
if (Ext.isIE) {
return function(e) {
var me = this,
k = e.getKey(),
doc = me.getDoc(),
readOnly = me.readOnly,
range, target;
if (k === e.TAB) {
e.stopEvent();
if (!readOnly) {
range = doc.selection.createRange();
if (range) {
if (range.collapse) {
range.collapse(true);
range.pasteHTML('&#160;&#160;&#160;&#160;');
}
me.deferFocus();
}
}
} else if (k === e.ENTER) {
if (!readOnly) {
if (Ext.isIE10m) {
range = doc.selection.createRange();
if (range) {
target = range.parentElement();
if (!target || target.tagName.toLowerCase() !== 'li') {
e.stopEvent();
range.pasteHTML('<br />');
range.collapse(false);
range.select();
}
}
} else {
range = doc.getSelection().getRangeAt(0);
if (range && range.commonAncestorContainer.parentNode.tagName.toLowerCase() !== 'li') {
e.stopEvent();
tag = doc.createElement('div');
range.insertNode(tag);
}
}
}
}
};
}
if (Ext.isOpera) {
return function(e) {
var me = this,
k = e.getKey(),
readOnly = me.readOnly;
if (k === e.TAB) {
e.stopEvent();
if (!readOnly) {
me.win.focus();
me.execCmd('InsertHTML', '&#160;&#160;&#160;&#160;');
me.deferFocus();
}
}
};
}
return null;
}()),
fixKeysAfter: (function() {
if (Ext.isIE) {
return function(e) {
var me = this,
k = e.getKey(),
doc = me.getDoc(),
readOnly = me.readOnly,
innerHTML;
if (!readOnly && (k === e.BACKSPACE || k === e.DELETE)) {
innerHTML = doc.body.innerHTML;
if (innerHTML === '<p>&nbsp;</p>' || innerHTML === '<P>&nbsp;</P>') {
doc.body.innerHTML = '';
}
}
};
}
return null;
}()),
getToolbar: function() {
return this.toolbar;
},
buttonTips: {
bold: {
title: 'Bold (Ctrl+B)',
text: 'Make the selected text bold.',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
italic: {
title: 'Italic (Ctrl+I)',
text: 'Make the selected text italic.',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
underline: {
title: 'Underline (Ctrl+U)',
text: 'Underline the selected text.',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
increasefontsize: {
title: 'Grow Text',
text: 'Increase the font size.',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
decreasefontsize: {
title: 'Shrink Text',
text: 'Decrease the font size.',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
backcolor: {
title: 'Text Highlight Color',
text: 'Change the background color of the selected text.',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
forecolor: {
title: 'Font Color',
text: 'Change the color of the selected text.',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
justifyleft: {
title: 'Align Text Left',
text: 'Align text to the left.',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
justifycenter: {
title: 'Center Text',
text: 'Center text in the editor.',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
justifyright: {
title: 'Align Text Right',
text: 'Align text to the right.',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
insertunorderedlist: {
title: 'Bullet List',
text: 'Start a bulleted list.',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
insertorderedlist: {
title: 'Numbered List',
text: 'Start a numbered list.',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
createlink: {
title: 'Hyperlink',
text: 'Make the selected text a hyperlink.',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
sourceedit: {
title: 'Source Edit',
text: 'Switch to source editing mode.',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
}
},
privates: {
deferFocus: function() {
this.focus(false, true);
},
getFocusEl: function() {
return this.sourceEditMode ? this.textareaEl : this.iframeEl;
}
}
});
Ext.define('Ext.form.field.Tag', {
extend: 'Ext.form.field.ComboBox',
requires: [
'Ext.selection.Model',
'Ext.data.Store',
'Ext.data.ChainedStore'
],
xtype: 'tagfield',
noWrap: false,
multiSelect: true,
delimiter: ',',
tipTpl: undefined,
forceSelection: true,
createNewOnEnter: false,
createNewOnBlur: false,
encodeSubmitValue: false,
triggerOnClick: true,
stacked: false,
filterPickList: false,
grow: true,
growMin: false,
growMax: false,
selectOnFocus: true,
fieldSubTpl: [
'<div id="{cmpId}-listWrapper" data-ref="listWrapper" class="' + Ext.baseCSSPrefix + 'tagfield {fieldCls} {typeCls} {typeCls}-{ui}" style="{wrapperStyle}">',
'<ul id="{cmpId}-itemList" data-ref="itemList" class="' + Ext.baseCSSPrefix + 'tagfield-list{itemListCls}">',
'<li id="{cmpId}-inputElCt" data-ref="inputElCt" class="' + Ext.baseCSSPrefix + 'tagfield-input">',
'<div id="{cmpId}-emptyEl" data-ref="emptyEl" class="{emptyCls}">{emptyText}</div>',
'<input id="{cmpId}-inputEl" data-ref="inputEl" type="{type}" ',
'<tpl if="name">name="{name}" </tpl>',
'<tpl if="value"> value="{[Ext.util.Format.htmlEncode(values.value)]}"</tpl>',
'<tpl if="size">size="{size}" </tpl>',
'<tpl if="tabIdx != null">tabindex="{tabIdx}" </tpl>',
'<tpl if="disabled"> disabled="disabled"</tpl>',
'class="' + Ext.baseCSSPrefix + 'tagfield-input-field {inputElCls}" autocomplete="off">',
'</li>',
'</ul>',
'</div>',
{
disableFormats: true
}
],
extraFieldBodyCls: Ext.baseCSSPrefix + 'tagfield-body',
childEls: [
'listWrapper',
'itemList',
'inputEl',
'inputElCt',
'emptyEl'
],
emptyInputCls: Ext.baseCSSPrefix + 'tagfield-emptyinput',
clearValueOnEmpty: false,
tagItemCls: Ext.baseCSSPrefix + 'tagfield-item',
tagItemTextCls: Ext.baseCSSPrefix + 'tagfield-item-text',
tagItemCloseCls: Ext.baseCSSPrefix + 'tagfield-item-close',
tagItemSelector: '.' + Ext.baseCSSPrefix + 'tagfield-item',
tagItemCloseSelector: '.' + Ext.baseCSSPrefix + 'tagfield-item-close',
tagSelectedCls: Ext.baseCSSPrefix + 'tagfield-item-selected',
initComponent: function() {
var me = this,
typeAhead = me.typeAhead,
delimiter = me.delimiter;
if (typeAhead && !me.editable) {
Ext.Error.raise('If typeAhead is enabled the combo must be editable: true -- please change one of those settings.');
}
if (me.createNewOnEnter || me.createNewOnBlur) {
me.forceSelection = false;
}
me.typeAhead = false;
if (me.value == null) {
me.value = [];
}
me.selectionModel = new Ext.selection.Model({
mode: 'MULTI',
onSelectChange: function(record, isSelected, suppressEvent, commitFn) {
commitFn();
},
listeners: {
scope: me,
selectionchange: me.onSelectionChange,
focuschange: me.onFocusChange
}
});
me.callParent();
me.typeAhead = typeAhead;
if (delimiter && me.multiSelect) {
me.delimiterRegexp = new RegExp(Ext.String.escapeRegex(delimiter));
}
},
initEvents: function() {
var me = this,
inputEl = me.inputEl;
me.callParent(arguments);
if (!me.enableKeyEvents) {
inputEl.on('keydown', me.onKeyDown, me);
inputEl.on('keyup', me.onKeyUp, me);
}
me.listWrapper.on('click', me.onItemListClick, me);
},
isValid: function() {
var me = this,
disabled = me.disabled,
validate = me.forceValidation || !disabled;
return validate ? me.validateValue(me.getValue()) : disabled;
},
onBindStore: function(store) {
var me = this;
me.callParent([
store
]);
if (store) {
me.valueStore = new Ext.data.Store({
model: store.getModel(),
useModelWarning: false
});
me.selectionModel.bindStore(me.valueStore);
if (me.filterPickList) {
me.listFilter = new Ext.util.Filter({
scope: me,
filterFn: me.filterPicked
});
me.changingFilters = true;
store.filter(me.listFilter);
me.changingFilters = false;
}
}
},
filterPicked: function(rec) {
return !this.valueCollection.contains(rec);
},
onUnbindStore: function(store) {
var me = this,
valueStore = me.valueStore,
picker = me.picker;
if (picker) {
picker.bindStore(null);
}
if (valueStore) {
valueStore.destroy();
me.valueStore = null;
}
if (me.filterPickList && !store.isDestroyed) {
me.changingFilters = true;
store.removeFilter(me.listFilter);
me.changingFilters = false;
}
me.callParent(arguments);
},
onValueCollectionEndUpdate: function() {
var me = this,
pickedRecords = me.valueCollection.items,
valueStore = me.valueStore;
if (me.isSelectionUpdating()) {
return;
}
if (me.filterPickList) {
me.changingFilters = true;
me.store.filter(me.listFilter);
me.changingFilters = false;
}
me.callParent();
Ext.suspendLayouts();
if (valueStore) {
valueStore.suspendEvents();
valueStore.loadRecords(pickedRecords);
valueStore.resumeEvents();
}
Ext.resumeLayouts(true);
me.alignPicker();
},
checkValueOnDataChange: Ext.emptyFn,
onSelectionChange: function(selModel, selectedRecs) {
this.applyMultiselectItemMarkup();
this.fireEvent('valueselectionchange', this, selectedRecs);
},
onFocusChange: function(selectionModel, oldFocused, newFocused) {
this.fireEvent('valuefocuschange', this, oldFocused, newFocused);
},
onDestroy: function() {
this.selectionModel = Ext.destroy(this.selectionModel);
this.callParent(arguments);
},
getSubTplData: function(fieldData) {
var me = this,
data = me.callParent(arguments),
emptyText = me.emptyText,
emptyInputCls = me.emptyInputCls,
isEmpty = emptyText && data.value.length < 1,
growMin = me.growMin,
growMax = me.growMax,
wrapperStyle = '';
data.value = '';
data.emptyText = isEmpty ? emptyText : '';
data.emptyCls = isEmpty ? me.emptyCls : emptyInputCls;
data.inputElCls = isEmpty ? emptyInputCls : '';
data.itemListCls = '';
if (me.grow) {
if (Ext.isNumber(growMin) && growMin > 0) {
wrapperStyle += 'min-height:' + growMin + 'px;';
}
if (Ext.isNumber(growMax) && growMax > 0) {
wrapperStyle += 'max-height:' + growMax + 'px;';
}
}
data.wrapperStyle = wrapperStyle;
if (me.stacked === true) {
data.itemListCls += ' ' + Ext.baseCSSPrefix + 'tagfield-stacked';
}
if (!me.multiSelect) {
data.itemListCls += ' ' + Ext.baseCSSPrefix + 'tagfield-singleselect';
}
return data;
},
afterRender: function() {
var me = this,
inputEl = me.inputEl;
if (Ext.supports.Placeholder && inputEl && me.emptyText) {
inputEl.dom.removeAttribute('placeholder');
}
me.applyMultiselectItemMarkup();
me.callParent(arguments);
},
findRecord: function(field, value) {
var matches = this.getStore().queryRecords(field, value);
return matches.length ? matches[0] : false;
},
getCursorPosition: function() {
var cursorPos;
if (document.selection) {
cursorPos = document.selection.createRange();
cursorPos.collapse(true);
cursorPos.moveStart('character', -this.inputEl.dom.value.length);
cursorPos = cursorPos.text.length;
} else {
cursorPos = this.inputEl.dom.selectionStart;
}
return cursorPos;
},
hasSelectedText: function() {
var inputEl = this.inputEl.dom,
sel, range;
if (document.selection) {
sel = document.selection;
range = sel.createRange();
return (range.parentElement() === inputEl);
} else {
return inputEl.selectionStart !== inputEl.selectionEnd;
}
},
onKeyDown: function(e) {
var me = this,
key = e.getKey(),
inputEl = me.inputEl,
rawValue = inputEl.dom.value,
valueCollection = me.valueCollection,
selModel = me.selectionModel,
stopEvent = false,
lastSelectionIndex;
if (me.readOnly || me.disabled || !me.editable) {
return;
}
if (valueCollection.getCount() > 0 && (rawValue === '' || (me.getCursorPosition() === 0 && !me.hasSelectedText()))) {
lastSelectionIndex = (selModel.getCount() > 0) ? valueCollection.indexOf(selModel.getLastSelected()) : -1;
if (key === e.BACKSPACE || key === e.DELETE) {
if (lastSelectionIndex > -1) {
if (selModel.getCount() > 1) {
lastSelectionIndex = -1;
}
valueCollection.remove(selModel.getSelection());
} else {
valueCollection.remove(valueCollection.last());
}
selModel.clearSelections();
if (lastSelectionIndex > 0) {
selModel.select(lastSelectionIndex - 1);
} else if (valueCollection.getCount()) {
selModel.select(valueCollection.last());
}
stopEvent = true;
} else if (key === e.RIGHT || key === e.LEFT) {
if (lastSelectionIndex === -1 && key === e.LEFT) {
selModel.select(valueCollection.last());
stopEvent = true;
} else if (lastSelectionIndex > -1) {
if (key === e.RIGHT) {
if (lastSelectionIndex < (valueCollection.getCount() - 1)) {
selModel.select(lastSelectionIndex + 1, e.shiftKey);
stopEvent = true;
} else if (!e.shiftKey) {
selModel.deselectAll();
stopEvent = true;
}
} else if (key === e.LEFT && (lastSelectionIndex > 0)) {
selModel.select(lastSelectionIndex - 1, e.shiftKey);
stopEvent = true;
}
}
} else if (key === e.A && e.ctrlKey) {
selModel.selectAll();
stopEvent = e.A;
}
}
if (stopEvent) {
me.preventKeyUpEvent = stopEvent;
e.stopEvent();
return;
}
if (me.isExpanded && key === e.ENTER && me.picker.highlightedItem) {
me.preventKeyUpEvent = true;
}
if (me.enableKeyEvents) {
me.callParent(arguments);
}
if (!e.isSpecialKey() && !e.hasModifier()) {
selModel.deselectAll();
}
},
onKeyUp: function(e, t) {
var me = this,
inputEl = me.inputEl,
rawValue = inputEl.dom.value,
preventKeyUpEvent = me.preventKeyUpEvent;
if (me.preventKeyUpEvent) {
e.stopEvent();
if (preventKeyUpEvent === true || e.getKey() === preventKeyUpEvent) {
delete me.preventKeyUpEvent;
}
return;
}
if (me.multiSelect && me.delimiterRegexp && me.delimiterRegexp.test(rawValue) || (me.createNewOnEnter && e.getKey() === e.ENTER)) {
rawValue = Ext.Array.clean(rawValue.split(me.delimiterRegexp));
inputEl.dom.value = '';
me.setValue(me.valueStore.getRange().concat(rawValue));
inputEl.focus();
}
me.callParent([
e,
t
]);
},
onTypeAhead: function() {
var me = this,
displayField = me.displayField,
inputElDom = me.inputEl.dom,
boundList = me.getPicker(),
record = me.getStore().findRecord(displayField, inputElDom.value),
newValue, len, selStart;
if (record) {
newValue = record.get(displayField);
len = newValue.length;
selStart = inputElDom.value.length;
boundList.highlightItem(boundList.getNode(record));
if (selStart !== 0 && selStart !== len) {
inputElDom.value = newValue;
me.selectText(selStart, newValue.length);
}
}
},
onItemListClick: function(e) {
var me = this,
selectionModel = me.selectionModel,
itemEl = e.getTarget(me.tagItemSelector),
closeEl = itemEl ? e.getTarget(me.tagItemCloseSelector) : false;
if (me.readOnly || me.disabled) {
return;
}
e.stopPropagation();
if (itemEl) {
if (closeEl) {
me.removeByListItemNode(itemEl);
if (me.valueStore.getCount() > 0) {
me.fireEvent('select', me, me.valueStore.getRange());
}
} else {
me.toggleSelectionByListItemNode(itemEl, e.shiftKey);
}
if (!Ext.supports.TouchEvents) {
me.inputEl.focus();
}
} else {
if (selectionModel.getCount() > 0) {
selectionModel.deselectAll();
}
me.inputEl.focus();
if (me.triggerOnClick) {
me.onTriggerClick();
}
}
},
getMultiSelectItemMarkup: function() {
var me = this,
cssPrefix = Ext.baseCSSPrefix,
valueField = me.valueField;
if (!me.multiSelectItemTpl) {
if (!me.labelTpl) {
me.labelTpl = '{' + me.displayField + '}';
}
me.labelTpl = me.getTpl('labelTpl');
if (me.tipTpl) {
me.tipTpl = me.getTpl('tipTpl');
}
me.multiSelectItemTpl = new Ext.XTemplate([
'<tpl for=".">',
'<li data-selectionIndex="{[xindex - 1]}" data-recordId="{internalId}" class="' + me.tagItemCls,
'<tpl if="this.isSelected(values)">',
' ' + me.tagSelectedCls,
'</tpl>',
'{%',
'values = values.data;',
'%}',
me.tipTpl ? '" data-qtip="{[this.getTip(values)]}">' : '">',
'<div class="' + me.tagItemTextCls + '">{[this.getItemLabel(values)]}</div>',
'<div class="' + me.tagItemCloseCls + '"></div>',
'</li>',
'</tpl>',
{
isSelected: function(rec) {
return me.selectionModel.isSelected(rec);
},
getItemLabel: function(values) {
return Ext.String.htmlEncode(me.labelTpl.apply(values));
},
getTip: function(values) {
return Ext.String.htmlEncode(me.tipTpl.apply(values));
},
strict: true
}
]);
}
if (!me.multiSelectItemTpl.isTemplate) {
me.multiSelectItemTpl = this.getTpl('multiSelectItemTpl');
}
return me.multiSelectItemTpl.apply(me.valueCollection.getRange());
},
applyMultiselectItemMarkup: function() {
var me = this,
itemList = me.itemList;
if (itemList) {
itemList.select('.' + Ext.baseCSSPrefix + 'tagfield-item').destroy();
me.inputElCt.insertHtml('beforeBegin', me.getMultiSelectItemMarkup());
me.autoSize();
}
},
getRecordByListItemNode: function(itemEl) {
return this.valueCollection.items[Number(itemEl.getAttribute('data-selectionIndex'))];
},
toggleSelectionByListItemNode: function(itemEl, keepExisting) {
var me = this,
rec = me.getRecordByListItemNode(itemEl),
selModel = me.selectionModel;
if (rec) {
if (selModel.isSelected(rec)) {
selModel.deselect(rec);
} else {
selModel.select(rec, keepExisting);
}
}
},
removeByListItemNode: function(itemEl) {
var me = this,
rec = me.getRecordByListItemNode(itemEl);
if (rec) {
me.pickerSelectionModel.deselect(rec);
}
},
getDisplayValue: function() {
return this.getRawValue();
},
getRawValue: function() {
var me = this,
records = me.getValueRecords(),
values = [],
i, len;
for (i = 0 , len = records.length; i < len; i++) {
values.push(records[i].data[me.displayField]);
}
return values.join(',');
},
setRawValue: function(value) {
return;
},
removeValue: function(value) {
var me = this,
valueCollection = me.valueCollection,
len, i, item,
toRemove = [];
if (value) {
value = Ext.Array.from(value);
for (i = 0 , len = value.length; i < len; ++i) {
item = value[i];
if (!item.isModel) {
item = valueCollection.byValue.get(item);
}
if (item) {
toRemove.push(item);
}
}
me.valueCollection.beginUpdate();
me.pickerSelectionModel.deselect(toRemove);
me.valueCollection.endUpdate();
}
},
setValue: function(value,
add, skipLoad) {
var me = this,
valueStore = me.valueStore,
valueField = me.valueField,
unknownValues = [],
store = me.store,
record, len, i, valueRecord, cls, params;
if (Ext.isEmpty(value)) {
value = null;
}
if (Ext.isString(value) && me.multiSelect) {
value = value.split(me.delimiter);
}
value = Ext.Array.from(value, true);
for (i = 0 , len = value.length; i < len; i++) {
record = value[i];
if (!record || !record.isModel) {
valueRecord = valueStore.findExact(valueField, record);
if (valueRecord > -1) {
value[i] = valueStore.getAt(valueRecord);
} else {
valueRecord = me.findRecord(valueField, record);
if (!valueRecord) {
if (me.forceSelection) {
unknownValues.push(record);
} else {
valueRecord = {};
valueRecord[me.valueField] = record;
valueRecord[me.displayField] = record;
cls = me.valueStore.getModel();
valueRecord = new cls(valueRecord);
}
}
if (valueRecord) {
value[i] = valueRecord;
}
}
}
}
if (!store.isEmptyStore && skipLoad !== true && unknownValues.length > 0 && me.queryMode === 'remote') {
params = {};
params[me.valueParam || me.valueField] = unknownValues.join(me.delimiter);
store.load({
params: params,
callback: function() {
if (me.itemList) {
me.itemList.unmask();
}
me.setValue(value, add, true);
me.autoSize();
me.lastQuery = false;
}
});
return false;
}
if (!me.multiSelect && value.length > 0) {
for (i = value.length - 1; i >= 0; i--) {
if (value[i].isModel) {
value = value[i];
break;
}
}
if (Ext.isArray(value)) {
value = value[value.length - 1];
}
}
return me.callParent([
value,
add
]);
},
updateValue: function() {
var me = this,
valueArray = me.valueCollection.getRange(),
len = valueArray.length,
i;
for (i = 0; i < len; i++) {
valueArray[i] = valueArray[i].get(me.valueField);
}
me.setHiddenValue(valueArray);
me.value = me.multiSelect ? valueArray : valueArray[0];
if (!Ext.isDefined(me.value)) {
me.value = undefined;
}
me.applyMultiselectItemMarkup();
me.checkChange();
},
getValueRecords: function() {
return this.valueCollection.getRange();
},
getSubmitData: function() {
var me = this,
val = me.callParent(arguments);
if (me.multiSelect && me.encodeSubmitValue && val && val[me.name]) {
val[me.name] = Ext.encode(val[me.name]);
}
return val;
},
assertValue: function() {
var me = this,
rawValue = me.inputEl.dom.value,
rec = !Ext.isEmpty(rawValue) ? me.findRecordByDisplay(rawValue) : false,
value = false;
if (!rec && !me.forceSelection && me.createNewOnBlur && !Ext.isEmpty(rawValue)) {
value = rawValue;
} else if (rec) {
value = rec;
}
if (value) {
me.addValue(value);
}
me.inputEl.dom.value = '';
me.collapse();
},
isEqual: function(v1, v2) {
var fromArray = Ext.Array.from,
valueField = this.valueField,
i, len, t1, t2;
v1 = fromArray(v1);
v2 = fromArray(v2);
len = v1.length;
if (len !== v2.length) {
return false;
}
for (i = 0; i < len; i++) {
t1 = v1[i].isModel ? v1[i].get(valueField) : v1[i];
t2 = v2[i].isModel ? v2[i].get(valueField) : v2[i];
if (t1 !== t2) {
return false;
}
}
return true;
},
applyEmptyText: function() {
var me = this,
emptyText = me.emptyText,
emptyEl = me.emptyEl,
inputEl = me.inputEl,
listWrapper = me.listWrapper,
emptyCls = me.emptyCls,
emptyInputCls = me.emptyInputCls,
isEmpty;
if (me.rendered && emptyText) {
isEmpty = Ext.isEmpty(me.value) && !me.hasFocus;
if (isEmpty) {
inputEl.dom.value = '';
emptyEl.setHtml(emptyText);
emptyEl.addCls(emptyCls);
emptyEl.removeCls(emptyInputCls);
listWrapper.addCls(emptyCls);
inputEl.addCls(emptyInputCls);
} else {
emptyEl.addCls(emptyInputCls);
emptyEl.removeCls(emptyCls);
listWrapper.removeCls(emptyCls);
inputEl.removeCls(emptyInputCls);
}
me.autoSize();
}
},
preFocus: function() {
var me = this,
inputEl = me.inputEl,
isEmpty = inputEl.dom.value === '';
me.emptyEl.addCls(me.emptyInputCls);
me.emptyEl.removeCls(me.emptyCls);
me.listWrapper.removeCls(me.emptyCls);
me.inputEl.removeCls(me.emptyInputCls);
if (me.selectOnFocus || isEmpty) {
inputEl.dom.select();
}
},
onFocus: function() {
var me = this,
focusCls = me.focusCls,
itemList = me.itemList;
if (focusCls && itemList) {
itemList.addCls(focusCls);
}
me.callParent(arguments);
},
onBlur: function() {
var me = this,
focusCls = me.focusCls,
itemList = me.itemList;
if (focusCls && itemList) {
itemList.removeCls(focusCls);
}
me.callParent(arguments);
},
renderActiveError: function() {
var me = this,
invalidCls = me.invalidCls,
itemList = me.itemList,
hasError = me.hasActiveError();
if (invalidCls && itemList) {
itemList[hasError ? 'addCls' : 'removeCls'](me.invalidCls + '-field');
}
me.callParent(arguments);
},
autoSize: function() {
var me = this;
if (me.grow && me.rendered) {
me.autoSizing = true;
me.updateLayout();
}
return me;
},
afterComponentLayout: function() {
var me = this,
height;
if (me.autoSizing) {
height = me.getHeight();
if (height !== me.lastInputHeight) {
if (me.isExpanded) {
me.alignPicker();
}
me.fireEvent('autosize', me, height);
me.lastInputHeight = height;
me.autoSizing = false;
}
}
}
});
Ext.define('Ext.picker.Time', {
extend: 'Ext.view.BoundList',
alias: 'widget.timepicker',
requires: [
'Ext.data.Store',
'Ext.Date'
],
config: {
store: true
},
statics: {
createStore: function(format, increment) {
var dateUtil = Ext.Date,
clearTime = dateUtil.clearTime,
initDate = this.prototype.initDate,
times = [],
min = clearTime(new Date(initDate[0], initDate[1], initDate[2])),
max = dateUtil.add(clearTime(new Date(initDate[0], initDate[1], initDate[2])), 'mi', (24 * 60) - 1);
while (min <= max) {
times.push({
disp: dateUtil.dateFormat(min, format),
date: min
});
min = dateUtil.add(min, 'mi', increment);
}
return new Ext.data.Store({
model: Ext.picker.Time.prototype.modelType,
data: times
});
}
},
increment: 15,
format: "g:i A",
displayField: 'disp',
initDate: [
2008,
0,
1
],
componentCls: Ext.baseCSSPrefix + 'timepicker',
loadMask: false,
initComponent: function() {
var me = this,
dateUtil = Ext.Date,
clearTime = dateUtil.clearTime,
initDate = me.initDate;
me.absMin = clearTime(new Date(initDate[0], initDate[1], initDate[2]));
me.absMax = dateUtil.add(clearTime(new Date(initDate[0], initDate[1], initDate[2])), 'mi', (24 * 60) - 1);
me.updateList();
me.callParent();
},
applyStore: function(store, oldStore) {
if (store === true) {
store = Ext.picker.Time.createStore(this.format, this.increment);
}
return store;
},
setMinValue: function(value) {
this.minValue = value;
this.updateList();
},
setMaxValue: function(value) {
this.maxValue = value;
this.updateList();
},
normalizeDate: function(date) {
var initDate = this.initDate;
date.setFullYear(initDate[0], initDate[1], initDate[2]);
return date;
},
updateList: function() {
var me = this,
min = me.normalizeDate(me.minValue || me.absMin),
max = me.normalizeDate(me.maxValue || me.absMax),
filters = me.getStore().getFilters(),
filter = me.rangeFilter;
filters.beginUpdate();
if (filter) {
filters.remove(filter);
}
filter = me.rangeFilter = new Ext.util.Filter({
filterFn: function(record) {
var date = record.get('date');
return date >= min && date <= max;
}
});
filters.add(filter);
filters.endUpdate();
}
}, function() {
this.prototype.modelType = Ext.define(null, {
extend: 'Ext.data.Model',
fields: [
'disp',
'date'
]
});
});
Ext.define('Ext.form.field.Time', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.timefield',
requires: [
'Ext.form.field.Date',
'Ext.picker.Time',
'Ext.view.BoundListKeyNav',
'Ext.Date'
],
alternateClassName: [
'Ext.form.TimeField',
'Ext.form.Time'
],
triggerCls: Ext.baseCSSPrefix + 'form-time-trigger',
minText: "The time in this field must be equal to or after {0}",
maxText: "The time in this field must be equal to or before {0}",
invalidText: "{0} is not a valid time",
format: "g:i A",
altFormats: "g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|gi a|hi a|giA|hiA|gi A|hi A",
increment: 15,
pickerMaxHeight: 300,
selectOnTab: true,
snapToIncrement: false,
valuePublishEvent: [
'select',
'blur'
],
initDate: '1/1/2008',
initDateParts: [
2008,
0,
1
],
initDateFormat: 'j/n/Y',
queryMode: 'local',
displayField: 'disp',
valueField: 'date',
initComponent: function() {
var me = this,
min = me.minValue,
max = me.maxValue;
if (min) {
me.setMinValue(min);
}
if (max) {
me.setMaxValue(max);
}
me.displayTpl = new Ext.XTemplate('<tpl for=".">' + '{[typeof values === "string" ? values : this.formatDate(values["' + me.displayField + '"])]}' + '<tpl if="xindex < xcount">' + me.delimiter + '</tpl>' + '</tpl>', {
formatDate: me.formatDate.bind(me)
});
me.store = Ext.picker.Time.createStore(me.format, me.increment);
me.callParent();
me.getPicker();
},
isEqual: function(v1, v2) {
var fromArray = Ext.Array.from,
isEqual = Ext.Date.isEqual,
i, len;
v1 = fromArray(v1);
v2 = fromArray(v2);
len = v1.length;
if (len !== v2.length) {
return false;
}
for (i = 0; i < len; i++) {
if (!isEqual(v2[i], v1[i])) {
return false;
}
}
return true;
},
setMinValue: function(value) {
var me = this,
picker = me.picker;
me.setLimit(value, true);
if (picker) {
picker.setMinValue(me.minValue);
}
},
setMaxValue: function(value) {
var me = this,
picker = me.picker;
me.setLimit(value, false);
if (picker) {
picker.setMaxValue(me.maxValue);
}
},
setLimit: function(value, isMin) {
var me = this,
d, val;
if (Ext.isString(value)) {
d = me.parseDate(value);
} else if (Ext.isDate(value)) {
d = value;
}
if (d) {
val = me.getInitDate();
val.setHours(d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
} else
{
val = null;
}
me[isMin ? 'minValue' : 'maxValue'] = val;
},
getInitDate: function(hours, minutes, seconds) {
var parts = this.initDateParts;
return new Date(parts[0], parts[1], parts[2], hours || 0, minutes || 0, seconds || 0, 0);
},
valueToRaw: function(value) {
return this.formatDate(this.parseDate(value));
},
getErrors: function(value) {
value = arguments.length > 0 ? value : this.getRawValue();
var me = this,
format = Ext.String.format,
errors = me.callParent([
value
]),
minValue = me.minValue,
maxValue = me.maxValue,
data = me.displayTplData,
raw = me.getRawValue(),
i, len, date, item;
if (data && data.length > 0) {
for (i = 0 , len = data.length; i < len; i++) {
item = data[i];
item = item.date || item.disp;
date = me.parseDate(item);
if (!date) {
errors.push(format(me.invalidText, item, Ext.Date.unescapeFormat(me.format)));
continue;
}
if (minValue && date < minValue) {
errors.push(format(me.minText, me.formatDate(minValue)));
}
if (maxValue && date > maxValue) {
errors.push(format(me.maxText, me.formatDate(maxValue)));
}
}
} else if (raw.length && !me.parseDate(raw)) {
errors.push(format(me.invalidText, raw, Ext.Date.unescapeFormat(me.format)));
}
return errors;
},
formatDate: function(items) {
var formatted = [],
i, len;
items = Ext.Array.from(items);
for (i = 0 , len = items.length; i < len; i++) {
formatted.push(Ext.form.field.Date.prototype.formatDate.call(this, items[i]));
}
return formatted.join(this.delimiter);
},
parseDate: function(value) {
var me = this,
val = value,
altFormats = me.altFormats,
altFormatsArray = me.altFormatsArray,
i = 0,
len;
if (value && !Ext.isDate(value)) {
val = me.safeParse(value, me.format);
if (!val && altFormats) {
altFormatsArray = altFormatsArray || altFormats.split('|');
len = altFormatsArray.length;
for (; i < len && !val; ++i) {
val = me.safeParse(value, altFormatsArray[i]);
}
}
}
if (val && me.snapToIncrement) {
val = new Date(Ext.Number.snap(val.getTime(), me.increment * 60 * 1000));
}
return val;
},
safeParse: function(value, format) {
var me = this,
utilDate = Ext.Date,
parsedDate,
result = null;
if (utilDate.formatContainsDateInfo(format)) {
result = utilDate.parse(value, format);
} else {
parsedDate = utilDate.parse(me.initDate + ' ' + value, me.initDateFormat + ' ' + format);
if (parsedDate) {
result = parsedDate;
}
}
return result;
},
getSubmitValue: function() {
var me = this,
format = me.submitFormat || me.format,
value = me.getValue();
return value ? Ext.Date.format(value, format) : null;
},
createPicker: function() {
var me = this;
me.listConfig = Ext.apply({
xtype: 'timepicker',
pickerField: me,
cls: undefined,
minValue: me.minValue,
maxValue: me.maxValue,
increment: me.increment,
format: me.format,
maxHeight: me.pickerMaxHeight
}, me.listConfig);
return me.callParent();
},
completeEdit: function() {
var me = this,
val = me.getValue();
me.callParent(arguments);
if (me.validateValue(val)) {
me.setValue(val);
}
},
findRecordByValue: function(value) {
if (typeof value === 'string') {
value = this.parseDate(value);
}
return this.callParent([
value
]);
},
rawToValue: function(item) {
var me = this,
items, values, i, len;
if (me.multiSelect) {
values = [];
items = Ext.Array.from(item);
for (i = 0 , len = items.length; i < len; i++) {
values.push(me.parseDate(items[i]));
}
return values;
}
return me.parseDate(item);
},
setValue: function(v) {
var me = this;
if (me.creatingPicker) {
return;
}
me.getPicker();
if (Ext.isDate(v)) {
v = me.getInitDate(v.getHours(), v.getMinutes(), v.getSeconds());
}
return me.callParent([
v
]);
},
getValue: function() {
return this.rawToValue(this.callParent(arguments));
}
});
Ext.define('Ext.form.field.Trigger', {
extend: 'Ext.form.field.Text',
alias: [
'widget.triggerfield',
'widget.trigger'
],
requires: [
'Ext.dom.Helper',
'Ext.util.ClickRepeater'
],
alternateClassName: [
'Ext.form.TriggerField',
'Ext.form.TwinTriggerField',
'Ext.form.Trigger'
],
triggerCls: Ext.baseCSSPrefix + 'form-arrow-trigger',
inheritableStatics: {
warnDeprecated: function() {
Ext.log.warn('Ext.form.field.Trigger is deprecated. Use Ext.form.field.Text instead.');
}
},
onClassExtended: function() {
this.warnDeprecated();
},
constructor: function(config) {
this.self.warnDeprecated();
this.callParent([
config
]);
}
});
Ext.define('Ext.grid.CellEditor', {
extend: 'Ext.Editor',
alignment: 'l-l?',
hideEl: false,
cls: Ext.baseCSSPrefix + 'small-editor ' + Ext.baseCSSPrefix + 'grid-editor ' + Ext.baseCSSPrefix + 'grid-cell-editor',
treeNodeSelector: '.' + Ext.baseCSSPrefix + 'tree-node-text',
shim: false,
shadow: false,
constructor: function(config) {
var field;
this.y = 0;
config = Ext.apply({}, config);
field = config.field;
if (field) {
field.monitorTab = false;
}
this.callParent([
config
]);
},
setGrid: function(grid) {
var me = this,
oldGrid = me.grid,
view, viewListeners;
if (grid !== oldGrid) {
viewListeners = {
beforerefresh: me.beforeViewRefresh,
refresh: me.onViewRefresh,
scope: me
};
if (oldGrid) {
oldGrid.getView().un(viewListeners);
}
view = grid.getView();
me.renderTo = view.getTargetEl().dom;
me.grid = grid;
view.on(viewListeners);
}
},
afterFirstLayout: function(width, height) {
delete this.y;
this.callParent([
width,
height
]);
},
beforeViewRefresh: function() {
var me = this,
dom = me.el && me.el.dom;
if (dom) {
if (me.editing && !(me.field.column && me.field.column.sorting)) {
me.grid.view.cellFocused = false;
me.wasAllowBlur = me.allowBlur;
me.allowBlur = false;
}
if (dom.parentNode) {
dom.parentNode.removeChild(dom);
}
}
},
onViewRefresh: function() {
var me = this,
dom = me.el && me.el.dom,
sorting;
if (dom) {
sorting = me.field.column && me.field.column.sorting;
if (me.editing && !sorting) {
me.allowBlur = me.wasAllowBlur;
me.renderTo.appendChild(dom);
me.grid.view.cellFocused = true;
me.field.focus();
} else if (!sorting) {
Ext.getDetachedBody().dom.appendChild(dom);
}
if (me.editing && sorting) {
me.completeEdit();
}
}
},
startEdit: function(boundEl, value) {
this.context = this.editingPlugin.context;
this.callParent([
boundEl,
value
]);
},
onShow: function() {
var me = this,
innerCell = me.boundEl.first();
if (me.el.dom.parentNode !== me.renderTo) {
me.renderTo.appendChild(me.el.dom);
}
if (innerCell) {
if (me.isForTree) {
innerCell = innerCell.child(me.treeNodeSelector);
}
innerCell.hide();
}
me.callParent(arguments);
},
onEditComplete: function(remainVisible) {
if (remainVisible) {
this.restoreCell();
}
this.callParent(arguments);
},
onHide: function() {
this.restoreCell();
this.callParent(arguments);
},
restoreCell: function() {
var me = this,
innerCell = me.boundEl.first();
if (innerCell) {
if (me.isForTree) {
innerCell = innerCell.child(me.treeNodeSelector);
}
innerCell.show();
}
},
afterRender: function() {
var me = this,
field = me.field;
me.callParent(arguments);
if (field.isCheckbox) {
field.mon(field.inputEl, {
mousedown: me.onCheckBoxMouseDown,
click: me.onCheckBoxClick,
scope: me
});
}
},
onCheckBoxMouseDown: function() {
this.completeEdit = Ext.emptyFn;
},
onCheckBoxClick: function() {
delete this.completeEdit;
this.field.focus(false, 10);
},
realign: function(autoSize) {
var me = this,
boundEl = me.boundEl,
innerCell = boundEl.first(),
innerCellTextNode = innerCell.dom.firstChild,
width = boundEl.getWidth(),
offsets = Ext.Array.clone(me.offsets),
grid = me.grid,
xOffset,
v = '',
isEmpty = !innerCellTextNode || (innerCellTextNode.nodeType === 3 && !(Ext.String.trim(v = innerCellTextNode.data).length));
if (me.isForTree) {
xOffset = me.getTreeNodeOffset(innerCell);
width -= Math.abs(xOffset);
offsets[0] += xOffset;
}
if (grid.columnLines) {
width -= boundEl.getBorderWidth('rl');
}
if (autoSize === true) {
me.field.setWidth(width);
}
if (isEmpty) {
innerCell.dom.innerHTML = 'X';
}
me.alignTo(innerCell, me.alignment, offsets);
if (isEmpty) {
innerCell.dom.firstChild.data = v;
}
},
getTreeNodeOffset: function(innerCell) {
return innerCell.child(this.treeNodeSelector).getOffsetsTo(innerCell)[0];
},
onEditorTab: function(e) {
var field = this.field;
if (field.onEditorTab) {
field.onEditorTab(e);
}
},
onFocusLeave: function(e) {
this.previousFocus = null;
this.callParent([
e
]);
this.selectSameEditor = false;
}
});
Ext.define('Ext.grid.ColumnManager', {
alternateClassName: [
'Ext.grid.ColumnModel'
],
columns: null,
constructor: function(visibleOnly, headerCt, secondHeaderCt) {
if (!headerCt.isRootHeader && !headerCt.isGroupHeader) {
Ext.Error.raise('ColumnManager must be passed an instantiated HeaderContainer or group header');
}
this.headerCt = headerCt;
if (secondHeaderCt) {
if (!headerCt.isRootHeader && !headerCt.isGroupHeader) {
Ext.Error.raise('ColumnManager must be passed an instantiated HeaderContainer or group header');
}
this.secondHeaderCt = secondHeaderCt;
}
this.visibleOnly = !!visibleOnly;
},
getColumns: function() {
if (!this.columns) {
this.cacheColumns();
}
return this.columns;
},
hasVariableRowHeight: function() {
var me = this,
columns = me.getColumns(),
len = columns.length,
i;
if (me.variableRowHeight == null) {
me.variableRowHeight = false;
for (i = 0; !me.variableRowHeight && i < len; i++) {
me.variableRowHeight = !!columns[i].variableRowHeight;
}
}
return me.variableRowHeight;
},
getHeaderIndex: function(header) {
if (header.isGroupHeader) {
header = this.getHeaderColumns(header)[0];
}
return Ext.Array.indexOf(this.getColumns(), header);
},
getHeaderAtIndex: function(index) {
var columns = this.getColumns(),
col = columns[index];
return col || null;
},
getPreviousSibling: function(header) {
var index = this.getHeaderIndex(header),
col = null;
if (index > 0) {
col = this.getColumns()[index - 1];
}
return col;
},
getNextSibling: function(header) {
var index = this.getHeaderIndex(header),
col;
if (index !== -1) {
col = this.getColumns()[index + 1];
}
return col || null;
},
getFirst: function() {
var columns = this.getColumns();
return columns.length > 0 ? columns[0] : null;
},
getLast: function() {
var columns = this.getColumns(),
len = columns.length;
return len > 0 ? columns[len - 1] : null;
},
getHeaderByDataIndex: function(dataIndex) {
var columns = this.getColumns(),
len = columns.length,
i, header;
for (i = 0; i < len; ++i) {
header = columns[i];
if (header.dataIndex === dataIndex) {
return header;
}
}
return null;
},
getHeaderById: function(id) {
var columns = this.getColumns(),
len = columns.length,
i, header;
for (i = 0; i < len; ++i) {
header = columns[i];
if (header.getItemId() === id) {
return header;
}
}
return null;
},
getVisibleHeaderClosestToIndex: function(index) {
var result = this.getHeaderAtIndex(index);
if (result && result.hidden) {
result = result.next(':not([hidden])') || result.prev(':not([hidden])');
}
return result;
},
cacheColumns: function() {
var columns = this.getHeaderColumns(this.headerCt),
second = this.secondHeaderCt;
if (second) {
columns = columns.concat(this.getHeaderColumns(second));
}
this.columns = columns;
},
getHeaderColumns: function(header) {
var result = this.visibleOnly ? header.getVisibleGridColumns() : header.getGridColumns();
return Ext.Array.clone(result);
},
invalidate: function() {
var root = this.rootColumns;
this.columns = this.variableRowHeight = null;
if (root) {
root.invalidate();
}
},
destroy: function() {
this.columns = this.rootColumns = null;
}
}, function() {
this.createAlias('indexOf', 'getHeaderIndex');
});
Ext.define('Ext.grid.RowEditorButtons', {
extend: 'Ext.container.Container',
alias: 'widget.roweditorbuttons',
frame: true,
shrinkWrap: true,
position: 'bottom',
constructor: function(config) {
var me = this,
rowEditor = config.rowEditor,
cssPrefix = Ext.baseCSSPrefix,
plugin = rowEditor.editingPlugin;
config = Ext.apply({
baseCls: cssPrefix + 'grid-row-editor-buttons',
defaults: {
xtype: 'button',
ui: rowEditor.buttonUI,
scope: plugin,
flex: 1,
minWidth: Ext.panel.Panel.prototype.minButtonWidth
},
items: [
{
cls: cssPrefix + 'row-editor-update-button',
itemId: 'update',
handler: plugin.completeEdit,
text: rowEditor.saveBtnText,
disabled: rowEditor.updateButtonDisabled
},
{
cls: cssPrefix + 'row-editor-cancel-button',
itemId: 'cancel',
handler: plugin.cancelEdit,
text: rowEditor.cancelBtnText
}
]
}, config);
me.callParent([
config
]);
me.addClsWithUI(me.position);
},
setButtonPosition: function(position) {
var me = this,
rowEditor = this.rowEditor,
rowEditorHeight = rowEditor.getHeight(),
rowEditorBody = rowEditor.body,
bottom = '',
top = '';
me.removeClsWithUI(me.position);
me.position = position;
me.addClsWithUI(position);
if (position === 'top') {
bottom = (rowEditorHeight - rowEditorBody.getBorderWidth('t')) + 'px';
} else {
top = (rowEditorHeight - rowEditorBody.getBorderWidth('b')) + 'px';
}
me.el.setStyle({
top: top,
bottom: bottom
});
},
privates: {
getFramingInfoCls: function() {
return this.baseCls + '-' + this.ui + '-' + this.position;
},
getFrameInfo: function() {
var frameInfo = this.callParent();
frameInfo.top = true;
return frameInfo;
}
}
});
Ext.define('Ext.grid.RowEditor', {
extend: 'Ext.form.Panel',
alias: 'widget.roweditor',
requires: [
'Ext.tip.ToolTip',
'Ext.util.KeyNav',
'Ext.grid.RowEditorButtons'
],
saveBtnText: 'Update',
cancelBtnText: 'Cancel',
errorsText: 'Errors',
dirtyText: 'You need to commit or cancel your changes',
lastScrollLeft: 0,
lastScrollTop: 0,
border: false,
_wrapCls: Ext.baseCSSPrefix + 'grid-row-editor-wrap',
errorCls: Ext.baseCSSPrefix + 'grid-row-editor-errors-item',
buttonUI: 'default',
hideMode: 'offsets',
initComponent: function() {
var me = this,
grid = me.editingPlugin.grid,
Container = Ext.container.Container,
form, normalCt, lockedCt;
me.cls = Ext.baseCSSPrefix + 'grid-editor ' + Ext.baseCSSPrefix + 'grid-row-editor';
me.layout = {
type: 'hbox',
align: 'middle'
};
me.lockable = grid.lockable;
if (me.lockable) {
me.items = [
lockedCt = me.lockedColumnContainer = new Container({
id: grid.id + '-locked-editor-cells',
scrollable: {
x: false,
y: false
},
layout: {
type: 'hbox',
align: 'middle'
},
margin: '0 1 0 0'
}),
normalCt = me.normalColumnContainer = new Container({
scrollable: {
x: false,
y: false
},
flex: 1,
id: grid.id + '-normal-editor-cells',
layout: {
type: 'hbox',
align: 'middle'
}
})
];
lockedCt.getScrollable().addPartner(grid.lockedGrid.view.getScrollable(), 'x');
normalCt.getScrollable().addPartner(grid.normalGrid.view.getScrollable(), 'x');
} else {
me.setScrollable({
x: false,
y: false
});
me.getScrollable().addPartner(grid.view.getScrollable(), 'x');
me.lockedColumnContainer = me.normalColumnContainer = me;
}
me.callParent();
if (me.fields) {
me.addFieldsForColumn(me.fields, true);
me.insertColumnEditor(me.fields);
delete me.fields;
}
me.mon(Ext.GlobalEvents, {
scope: me,
show: me.repositionIfVisible
});
form = me.getForm();
form.trackResetOnLoad = true;
form.on('validitychange', me.onValidityChange, me);
form.on('errorchange', me.onErrorChange, me);
},
onGridResize: function() {
var me = this,
clientWidth = me.getClientWidth(),
grid = me.editingPlugin.grid,
gridBody = grid.body,
btns = me.getFloatingButtons();
me.wrapEl.setLocalX(gridBody.getOffsetsTo(grid)[0] + gridBody.getBorderWidth('l') - grid.el.getBorderWidth('l'));
me.setWidth(clientWidth);
btns.setLocalX((clientWidth - btns.getWidth()) / 2);
if (me.lockable) {
me.lockedColumnContainer.setWidth(grid.lockedGrid.view.el.dom.clientWidth);
}
},
syncAllFieldWidths: function() {
var me = this,
editors = me.query('[isEditorComponent]'),
len = editors.length,
column, i;
for (i = 0; i < len; ++i) {
column = editors[i].column;
if (column.isVisible()) {
me.onColumnShow(column);
}
}
},
syncFieldWidth: function(column) {
var field = column.getEditor(),
width;
field._marginWidth = (field._marginWidth || field.el.getMargin('lr'));
width = column.getWidth() - field._marginWidth;
field.setWidth(width);
if (field.xtype === 'displayfield') {
field.inputWidth = width;
}
},
onValidityChange: function(form, valid) {
this.updateButton(valid);
this.isValid = valid;
},
onErrorChange: function() {
var me = this,
valid;
if (me.errorSummary && me.isVisible()) {
valid = me.getForm().isValid();
me[valid ? 'hideToolTip' : 'showToolTip']();
}
},
updateButton: function(valid) {
var buttons = this.floatingButtons;
if (buttons) {
buttons.child('#update').setDisabled(!valid);
} else {
this.updateButtonDisabled = !valid;
}
},
afterRender: function() {
var me = this,
plugin = me.editingPlugin,
grid = plugin.grid,
view = grid.lockable ? grid.normalGrid.view : grid.view;
me.callParent(arguments);
me.scrollingView = view;
me.scrollingViewEl = view.el;
view.on('scroll', me.onViewScroll, me);
me.mon(me.el, {
click: Ext.emptyFn,
stopPropagation: true
});
me.mon(grid, 'resize', me.onGridResize, me);
if (me.lockable) {
grid.lockedGrid.view.on('resize', 'onGridResize', me);
}
me.el.swallowEvent([
'keypress',
'keydown'
]);
me.initKeyNav();
me.mon(plugin.view, {
beforerefresh: me.onBeforeViewRefresh,
refresh: me.onViewRefresh,
itemremove: me.onViewItemRemove,
scope: me
});
me.preventReposition = true;
me.syncAllFieldWidths();
delete me.preventReposition;
},
initKeyNav: function() {
var me = this,
plugin = me.editingPlugin;
me.keyNav = new Ext.util.KeyNav(me.el, {
enter: plugin.onEnterKey,
esc: plugin.onEscKey,
scope: plugin
});
},
onBeforeViewRefresh: function(view) {
var me = this,
viewDom = view.el.dom;
if (me.el.dom.parentNode === viewDom) {
viewDom.removeChild(me.el.dom);
}
},
onViewRefresh: function(view) {
var me = this,
context = me.context,
row;
if (context && (row = view.getRow(context.record))) {
context.row = row;
me.reposition();
if (me.tooltip && me.tooltip.isVisible()) {
me.tooltip.setTarget(context.row);
}
} else {
me.editingPlugin.cancelEdit();
}
},
onViewItemRemove: function(record, index, item, view) {
if (!view.refreshing) {
var context = this.context;
if (context && record === context.record) {
this.editingPlugin.cancelEdit();
}
}
},
onViewScroll: function() {
var me = this,
viewEl = me.editingPlugin.view.el,
scrollingView = me.scrollingView,
scrollTop = scrollingView.getScrollY(),
scrollLeft = scrollingView.getScrollX(),
scrollTopChanged = scrollTop !== me.lastScrollTop,
row;
me.lastScrollTop = scrollTop;
me.lastScrollLeft = scrollLeft;
if (me.isVisible()) {
row = Ext.getDom(me.context.row);
if (row && viewEl.contains(row)) {
if (scrollTopChanged) {
me.context.row = row;
me.reposition(null, true);
if ((me.tooltip && me.tooltip.isVisible()) || me.hiddenTip) {
me.repositionTip();
}
me.syncEditorClip();
}
} else
{
me.setLocalY(-400);
}
}
},
onColumnResize: function(column, width) {
var me = this;
if (me.rendered && !me.editingPlugin.reconfiguring) {
me.onGridResize();
me.onViewScroll();
if (!column.isGroupHeader) {
me.syncFieldWidth(column);
me.repositionIfVisible();
}
}
},
onColumnHide: function(column) {
if (!this.editingPlugin.reconfiguring && !column.isGroupHeader) {
column.getEditor().hide();
this.repositionIfVisible();
}
},
onColumnShow: function(column) {
var me = this;
if (me.rendered && !me.editingPlugin.reconfiguring && !column.isGroupHeader && column.getEditor) {
column.getEditor().show();
me.syncFieldWidth(column);
if (!me.preventReposition) {
this.repositionIfVisible();
}
}
},
onColumnMove: function(column, fromIdx, toIdx) {
var me = this,
locked = column.isLocked(),
fieldContainer = locked ? me.lockedColumnContainer : me.normalColumnContainer,
columns, i, len, after, offset;
if (column.isGroupHeader) {
Ext.suspendLayouts();
after = toIdx > fromIdx;
offset = after ? 1 : 0;
columns = column.getGridColumns();
for (i = 0 , len = columns.length; i < len; ++i) {
column = columns[i];
toIdx = column.getIndex();
if (after) {
++offset;
}
me.setColumnEditor(column, toIdx + offset, fieldContainer);
}
Ext.resumeLayouts(true);
} else {
me.setColumnEditor(column, column.getIndex(), fieldContainer);
}
},
setColumnEditor: function(column, idx, fieldContainer) {
this.addFieldsForColumn(column);
fieldContainer.insert(idx, column.getEditor());
},
onColumnAdd: function(column) {
if (column.isGroupHeader) {
column = column.getGridColumns();
}
this.addFieldsForColumn(column);
this.insertColumnEditor(column);
this.preventReposition = false;
},
insertColumnEditor: function(column) {
var me = this,
fieldContainer, len, i;
if (Ext.isArray(column)) {
for (i = 0 , len = column.length; i < len; i++) {
me.insertColumnEditor(column[i]);
}
return;
}
if (!column.getEditor) {
return;
}
fieldContainer = column.isLocked() ? me.lockedColumnContainer : me.normalColumnContainer;
fieldContainer.insert(column.getIndex(), column.getEditor());
me.needsSyncFieldWidths = true;
},
destroyColumnEditor: function(column) {
var field;
if (column.hasEditor() && (field = column.getEditor())) {
field.destroy();
}
},
getFloatingButtons: function() {
var me = this,
btns = me.floatingButtons;
if (!btns) {
me.floatingButtons = btns = new Ext.grid.RowEditorButtons({
rowEditor: me
});
}
return btns;
},
repositionIfVisible: function(c) {
var me = this,
view = me.view;
if (c && (c === me || !c.el.isAncestor(view.el))) {
return;
}
if (me.isVisible() && view.isVisible(true)) {
me.reposition();
}
},
isLayoutChild: function(ownerCandidate) {
return false;
},
getRefOwner: function() {
return this.editingPlugin.grid;
},
getRefItems: function(deep) {
var me = this,
result;
if (me.lockable) {
result = [
me.lockedColumnContainer
];
result.push.apply(result, me.lockedColumnContainer.getRefItems(deep));
result.push(me.normalColumnContainer);
result.push.apply(result, me.normalColumnContainer.getRefItems(deep));
} else {
result = me.callParent(arguments);
}
result.push.apply(result, me.getFloatingButtons().getRefItems(deep));
return result;
},
reposition: function(animateConfig, fromScrollHandler) {
var me = this,
context = me.context,
row = context && context.row,
yOffset = 0,
wrapEl = me.wrapEl,
rowTop, localY, deltaY, afterPosition;
if (row && Ext.isElement(row)) {
deltaY = me.syncButtonPosition(me.getScrollDelta());
if (!me.editingPlugin.grid.rowLines) {
yOffset = -parseInt(Ext.fly(row).first().getStyle('border-bottom-width'), 10);
}
rowTop = me.calculateLocalRowTop(row);
localY = me.calculateEditorTop(rowTop) + yOffset;
if (!fromScrollHandler) {
afterPosition = function() {
if (deltaY) {
me.scrollingViewEl.scrollBy(0, deltaY, true);
}
me.focusColumnField(context.column);
};
}
me.syncEditorClip();
if (animateConfig) {
wrapEl.animate(Ext.applyIf({
to: {
top: localY
},
duration: animateConfig.duration || 125,
callback: afterPosition
}, animateConfig));
} else {
wrapEl.setLocalY(localY);
if (afterPosition) {
afterPosition();
}
}
}
},
getScrollDelta: function() {
var me = this,
scrollingViewDom = me.scrollingViewEl.dom,
context = me.context,
body = me.body,
deltaY = 0;
if (context) {
deltaY = Ext.fly(context.row).getOffsetsTo(scrollingViewDom)[1];
if (deltaY < 0) {
deltaY -= body.getBorderPadding().beforeY;
} else if (deltaY > 0) {
deltaY = Math.max(deltaY + me.getHeight() + me.floatingButtons.getHeight() - scrollingViewDom.clientHeight - body.getBorderWidth('b'), 0);
if (deltaY > 0) {
deltaY -= body.getBorderPadding().afterY;
}
}
}
return deltaY;
},
calculateLocalRowTop: function(row) {
var grid = this.editingPlugin.grid;
return Ext.fly(row).getOffsetsTo(grid)[1] - grid.el.getBorderWidth('t') + this.lastScrollTop;
},
calculateEditorTop: function(rowTop) {
return rowTop - this.body.getBorderPadding().beforeY - this.lastScrollTop;
},
getClientWidth: function() {
var me = this,
grid = me.editingPlugin.grid,
result;
if (me.lockable) {
result = grid.lockedGrid.getWidth() + grid.normalGrid.view.el.dom.clientWidth;
} else {
result = grid.view.el.dom.clientWidth;
}
return result;
},
getEditor: function(fieldInfo) {
var me = this;
if (Ext.isNumber(fieldInfo)) {
return me.query('[isEditorComponent]')[fieldInfo];
} else if (fieldInfo.isHeader && !fieldInfo.isGroupHeader) {
return fieldInfo.getEditor();
}
},
addFieldsForColumn: function(column, initial) {
var me = this,
i, length, field;
if (Ext.isArray(column)) {
for (i = 0 , length = column.length; i < length; i++) {
me.addFieldsForColumn(column[i], initial);
}
return;
}
if (column.getEditor) {
field = column.getEditor(null, me.getDefaultFieldCfg());
if (column.align === 'right') {
field.fieldStyle = 'text-align:right';
}
if (column.xtype === 'actioncolumn') {
field.fieldCls += ' ' + Ext.baseCSSPrefix + 'form-action-col-field';
}
if (me.isVisible() && me.context) {
if (field.is('displayfield')) {
me.renderColumnData(field, me.context.record, column);
} else {
field.suspendEvents();
field.setValue(me.context.record.get(column.dataIndex));
field.resumeEvents();
}
}
if (column.hidden) {
me.onColumnHide(column);
} else if (column.rendered && !initial) {
me.onColumnShow(column);
}
}
},
getDefaultFieldCfg: function() {
return {
xtype: 'displayfield',
getModelData: function() {
return null;
}
};
},
loadRecord: function(record) {
var me = this,
form = me.getForm(),
fields = form.getFields(),
items = fields.items,
length = items.length,
i, displayFields, isValid, item;
for (i = 0; i < length; i++) {
item = items[i];
item.suspendEvents();
item.resetToInitialValue();
}
form.loadRecord(record);
for (i = 0; i < length; i++) {
items[i].resumeEvents();
}
if (form.hasInvalidField() === form.wasValid) {
delete form.wasValid;
}
isValid = form.isValid();
if (me.errorSummary) {
if (isValid) {
me.hideToolTip();
} else {
me.showToolTip();
}
}
me.updateButton(isValid);
displayFields = me.query('>displayfield');
length = displayFields.length;
for (i = 0; i < length; i++) {
me.renderColumnData(displayFields[i], record);
}
},
renderColumnData: function(field, record, activeColumn) {
var me = this,
grid = me.editingPlugin.grid,
headerCt = grid.headerCt,
view = me.scrollingView,
store = view.dataSource,
column = activeColumn || field.column,
value = record.get(column.dataIndex),
renderer = column.editRenderer || column.renderer,
metaData, rowIdx, colIdx,
scope = (column.usingDefaultRenderer && !column.scope) ? column : column.scope;
if (renderer) {
metaData = {
tdCls: '',
style: ''
};
rowIdx = store.indexOf(record);
colIdx = headerCt.getHeaderIndex(column);
value = renderer.call(scope || headerCt.ownerCt, value, metaData, record, rowIdx, colIdx, store, view);
}
field.setRawValue(value);
},
beforeEdit: function() {
var me = this,
scrollDelta;
if (me.isVisible() && me.errorSummary && !me.autoCancel && me.isDirty()) {
scrollDelta = me.getScrollDelta();
if (scrollDelta) {
me.scrollingViewEl.scrollBy(0, scrollDelta, true);
}
me.showToolTip();
return false;
}
},
startEdit: function(record, columnHeader) {
var me = this,
editingPlugin = me.editingPlugin,
grid = editingPlugin.grid,
context = me.context = editingPlugin.context,
alreadyVisible = me.isVisible(),
wrapEl = me.wrapEl;
Ext.suspendLayouts();
if (!me.rendered) {
me.width = me.getClientWidth();
me.render(grid.el, grid.el.dom.firstChild);
wrapEl = me.wrapEl = me.el.wrap();
wrapEl.setVisibilityMode(3);
wrapEl.addCls(me._wrapCls);
me.getFloatingButtons().render(wrapEl);
me.onViewScroll();
}
context.grid.getSelectionModel().selectByPosition({
row: record,
column: columnHeader
});
me.onGridResize();
me.loadRecord(record);
Ext.resumeLayouts(alreadyVisible);
if (alreadyVisible) {
me.reposition(true);
} else {
grid.ensureVisible(record);
me.show();
}
},
syncButtonPosition: function(scrollDelta) {
var me = this,
floatingButtons = me.getFloatingButtons(),
scrollingView = me.scrollingView,
overflow = me.getScrollDelta() - (scrollingView.getScrollable().getSize().y - scrollingView.getScrollY() - me.scrollingViewEl.dom.clientHeight);
if (overflow > 0) {
if (!me._buttonsOnTop) {
floatingButtons.setButtonPosition('top');
me._buttonsOnTop = true;
}
scrollDelta = 0;
} else if (me._buttonsOnTop !== false) {
floatingButtons.setButtonPosition('bottom');
me._buttonsOnTop = false;
}
return scrollDelta;
},
syncEditorClip: function() {
var me = this,
overflow = me.getScrollDelta(),
el = me.el,
floatingButtons = me.floatingButtons,
btnEl = floatingButtons.el,
max = Math.max,
body, btnHeight, editorHeight;
if (overflow) {
me.isOverflowing = true;
body = me.body;
btnHeight = floatingButtons.getHeight();
editorHeight = me.getHeight();
max = Math.max;
if (overflow > 0) {
if (me._buttonsOnTop) {
overflow -= (btnHeight - body.getBorderWidth('b'));
me.clipBottom(el, max(editorHeight - overflow), 0);
overflow -= (editorHeight - body.getBorderWidth('t'));
if (overflow > 0) {
me.clipBottom(btnEl, max(btnHeight - overflow, 0));
} else {
me.clearClip(btnEl);
}
} else {
me.clipBottom(btnEl, max(btnHeight - overflow, 0));
overflow -= (btnHeight - body.getBorderWidth('b'));
if (overflow > 0) {
me.clipBottom(el, max(editorHeight - overflow, 0));
} else {
me.clearClip(el);
}
}
} else if (overflow < 0) {
overflow = Math.abs(overflow);
me.clipTop(el, overflow);
overflow -= (editorHeight - body.getBorderWidth('b'));
if (overflow > 0) {
me.clipTop(btnEl, overflow);
} else {
me.clearClip(btnEl);
}
}
} else if (me.isOverflowing) {
me.clearClip(btnEl);
me.clearClip(el);
me.isOverflowing = false;
}
},
focusColumnField: function(column) {
var field, didFocus;
if (column && !column.isDestroyed) {
if (column.isVisible()) {
field = this.getEditor(column);
if (field && field.isFocusable(true)) {
didFocus = true;
field.focus();
}
}
if (!didFocus) {
this.focusColumnField(column.next());
}
}
},
cancelEdit: function() {
var me = this,
form = me.getForm(),
fields = form.getFields(),
items = fields.items,
length = items.length,
i;
me.hide();
form.clearInvalid();
for (i = 0; i < length; i++) {
items[i].suspendEvents();
}
form.reset();
for (i = 0; i < length; i++) {
items[i].resumeEvents();
}
},
completeEdit: function() {
var me = this,
form = me.getForm();
if (!form.isValid()) {
return false;
}
form.updateRecord(me.context.record);
me.hide();
return true;
},
onShow: function() {
var me = this;
me.wrapEl.show();
me.previousFocus = Ext.Element.getActiveElement();
me.callParent(arguments);
if (me.needsSyncFieldWidths) {
me.suspendLayouts();
me.syncAllFieldWidths();
me.resumeLayouts(true);
}
delete me.needsSyncFieldWidths;
me.reposition();
},
onHide: function() {
var me = this;
if (me.el.contains(Ext.Element.getActiveElement())) {
if (me.context) {
me.context.view.grid.focus();
me.context = null;
} else {
me.previousFocus.focus();
}
}
me.wrapEl.hide();
me.callParent(arguments);
if (me.tooltip) {
me.hideToolTip();
}
},
onResize: function(width, height) {
this.wrapEl.setSize(width, height);
},
isDirty: function() {
return this.getForm().isDirty();
},
getToolTip: function() {
var me = this,
tip = me.tooltip,
grid = me.editingPlugin.grid;
if (!tip) {
me.tooltip = tip = new Ext.tip.ToolTip({
cls: Ext.baseCSSPrefix + 'grid-row-editor-errors',
title: me.errorsText,
autoHide: false,
closable: true,
closeAction: 'disable',
anchor: 'left',
anchorToTarget: true,
constrainPosition: true,
constrainTo: document.body
});
grid.add(tip);
me.mon(grid, {
afterlayout: me.onGridLayout,
scope: me
});
}
return tip;
},
hideToolTip: function() {
var me = this,
tip = me.getToolTip();
if (tip.rendered) {
tip.disable();
}
me.hiddenTip = false;
},
showToolTip: function() {
var me = this,
tip = me.getToolTip();
tip.update(me.getErrors());
me.repositionTip();
tip.enable();
},
onGridLayout: function() {
if (this.tooltip && this.tooltip.isVisible()) {
this.repositionTip();
}
},
repositionTip: function() {
var me = this,
tip = me.getToolTip(),
context = me.context,
row = Ext.get(context.row),
viewEl = me.scrollingViewEl,
viewHeight = viewEl.dom.clientHeight,
viewTop = viewEl.getY(),
viewBottom = viewTop + viewHeight,
rowHeight = row.getHeight(),
rowTop = row.getY(),
rowBottom = rowTop + rowHeight;
if (rowBottom > viewTop && rowTop < viewBottom) {
tip.anchorTarget = viewEl;
tip.mouseOffset = [
0,
row.getOffsetsTo(viewEl)[1]
];
tip.show();
me.hiddenTip = false;
} else {
tip.hide();
me.hiddenTip = true;
}
},
getErrors: function() {
var me = this,
errors = [],
fields = me.query('>[isFormField]'),
length = fields.length,
i, fieldErrors, field;
for (i = 0; i < length; i++) {
field = fields[i];
fieldErrors = field.getErrors();
if (fieldErrors.length) {
errors.push(me.createErrorListItem(fieldErrors[0], field.column.text));
}
}
if (!errors.length && !me.autoCancel && me.isDirty()) {
errors[0] = me.createErrorListItem(me.dirtyText);
}
return '<ul class="' + Ext.baseCSSPrefix + 'list-plain">' + errors.join('') + '</ul>';
},
createErrorListItem: function(e, name) {
e = name ? name + ': ' + e : e;
return '<li class="' + this.errorCls + '">' + e + '</li>';
},
beforeDestroy: function() {
Ext.destroy(this.floatingButtons, this.tooltip);
this.callParent();
},
clipBottom: function(el, value) {
el.setStyle('clip', 'rect(0 auto ' + value + 'px 0)');
},
clipTop: function(el, value) {
el.setStyle('clip', 'rect(' + value + 'px, auto, auto, 0)');
},
clearClip: function(el) {
el.setStyle('clip', Ext.isIE8 ? 'rect(-1000px auto 1000px auto)' : 'auto');
}
});
Ext.define('Ext.grid.Scroller', {
constructor: Ext.deprecated()
});
Ext.define('Ext.view.DropZone', {
extend: 'Ext.dd.DropZone',
indicatorCls: Ext.baseCSSPrefix + 'grid-drop-indicator',
indicatorHtml: [
'<div class="',
Ext.baseCSSPrefix,
'grid-drop-indicator-left" role="presentation"></div>',
'<div class="' + Ext.baseCSSPrefix + 'grid-drop-indicator-right" role="presentation"></div>'
].join(''),
constructor: function(config) {
var me = this;
Ext.apply(me, config);
if (!me.ddGroup) {
me.ddGroup = 'view-dd-zone-' + me.view.id;
}
me.callParent([
me.view.el
]);
},
fireViewEvent: function() {
var me = this,
result;
me.lock();
result = me.view.fireEvent.apply(me.view, arguments);
me.unlock();
return result;
},
getTargetFromEvent: function(e) {
var node = e.getTarget(this.view.getItemSelector()),
mouseY, nodeList, testNode, i, len, box;
if (!node) {
mouseY = e.getY();
for (i = 0 , nodeList = this.view.getNodes() , len = nodeList.length; i < len; i++) {
testNode = nodeList[i];
box = Ext.fly(testNode).getBox();
if (mouseY <= box.bottom) {
return testNode;
}
}
}
return node;
},
getIndicator: function() {
var me = this;
if (!me.indicator) {
me.indicator = new Ext.Component({
ariaRole: 'presentation',
html: me.indicatorHtml,
cls: me.indicatorCls,
ownerCt: me.view,
floating: true,
shadow: false
});
}
return me.indicator;
},
getPosition: function(e, node) {
var y = e.getXY()[1],
region = Ext.fly(node).getRegion(),
pos;
if ((region.bottom - y) >= (region.bottom - region.top) / 2) {
pos = "before";
} else {
pos = "after";
}
return pos;
},
containsRecordAtOffset: function(records, record, offset) {
if (!record) {
return false;
}
var view = this.view,
recordIndex = view.indexOf(record),
nodeBefore = view.getNode(recordIndex + offset),
recordBefore = nodeBefore ? view.getRecord(nodeBefore) : null;
return recordBefore && Ext.Array.contains(records, recordBefore);
},
positionIndicator: function(node, data, e) {
var me = this,
view = me.view,
pos = me.getPosition(e, node),
overRecord = view.getRecord(node),
draggingRecords = data.records,
indicatorY;
if (!Ext.Array.contains(draggingRecords, overRecord) && (pos === 'before' && !me.containsRecordAtOffset(draggingRecords, overRecord, -1) || pos === 'after' && !me.containsRecordAtOffset(draggingRecords, overRecord, 1))) {
me.valid = true;
if (me.overRecord !== overRecord || me.currentPosition !== pos) {
indicatorY = Ext.fly(node).getY() - view.el.getY() - 1;
if (pos === 'after') {
indicatorY += Ext.fly(node).getHeight();
}
if (view.touchScroll === 2) {
indicatorY += view.getScrollY();
}
me.getIndicator().setWidth(Ext.fly(view.el).getWidth()).showAt(0, indicatorY);
me.overRecord = overRecord;
me.currentPosition = pos;
}
} else {
me.invalidateDrop();
}
},
invalidateDrop: function() {
if (this.valid) {
this.valid = false;
this.getIndicator().hide();
}
},
onNodeOver: function(node, dragZone, e, data) {
var me = this;
if (!Ext.Array.contains(data.records, me.view.getRecord(node))) {
me.positionIndicator(node, data, e);
}
return me.valid ? me.dropAllowed : me.dropNotAllowed;
},
notifyOut: function(node, dragZone, e, data) {
var me = this;
me.callParent(arguments);
me.overRecord = me.currentPosition = null;
me.valid = false;
if (me.indicator) {
me.indicator.hide();
}
},
onContainerOver: function(dd, e, data) {
var me = this,
view = me.view,
count = view.dataSource.getCount();
if (count) {
me.positionIndicator(view.all.last(), data, e);
} else
{
me.overRecord = me.currentPosition = null;
me.getIndicator().setWidth(Ext.fly(view.el).getWidth()).showAt(0, 0);
me.valid = true;
}
return me.dropAllowed;
},
onContainerDrop: function(dd, e, data) {
return this.onNodeDrop(dd, null, e, data);
},
onNodeDrop: function(targetNode, dragZone, e, data) {
var me = this,
dropHandled = false,
dropHandlers = {
wait: false,
processDrop: function() {
me.invalidateDrop();
me.handleNodeDrop(data, me.overRecord, me.currentPosition);
dropHandled = true;
me.fireViewEvent('drop', targetNode, data, me.overRecord, me.currentPosition);
},
cancelDrop: function() {
me.invalidateDrop();
dropHandled = true;
}
},
performOperation = false;
if (me.valid) {
performOperation = me.fireViewEvent('beforedrop', targetNode, data, me.overRecord, me.currentPosition, dropHandlers);
if (dropHandlers.wait) {
return;
}
if (performOperation !== false) {
if (!dropHandled) {
dropHandlers.processDrop();
}
}
}
return performOperation;
},
destroy: function() {
Ext.destroy(this.indicator);
delete this.indicator;
this.callParent();
}
});
Ext.define('Ext.grid.ViewDropZone', {
extend: 'Ext.view.DropZone',
indicatorHtml: '<div class="' + Ext.baseCSSPrefix + 'grid-drop-indicator-left" role="presentation"></div><div class="' + Ext.baseCSSPrefix + 'grid-drop-indicator-right" role="presentation"></div>',
indicatorCls: Ext.baseCSSPrefix + 'grid-drop-indicator',
handleNodeDrop: function(data, record, position) {
var view = this.view,
store = view.getStore(),
index, records, i, len;
if (data.copy) {
records = data.records;
data.records = [];
for (i = 0 , len = records.length; i < len; i++) {
data.records.push(records[i].copy());
}
} else {
data.view.store.remove(data.records, data.view === view);
}
if (record && position) {
index = store.indexOf(record);
if (position !== 'before') {
index++;
}
store.insert(index, data.records);
} else
{
store.add(data.records);
}
view.getSelectionModel().select(data.records);
view.getNavigationModel().setPosition(data.records[0]);
}
});
Ext.define('Ext.grid.column.Action', {
extend: 'Ext.grid.column.Column',
alias: [
'widget.actioncolumn'
],
alternateClassName: 'Ext.grid.ActionColumn',
stopSelection: true,
actionIdRe: new RegExp(Ext.baseCSSPrefix + 'action-col-(\\d+)'),
altText: '',
menuText: '<i>Actions</i>',
sortable: false,
innerCls: Ext.baseCSSPrefix + 'grid-cell-inner-action-col',
actionIconCls: Ext.baseCSSPrefix + 'action-col-icon',
constructor: function(config) {
var me = this,
cfg = Ext.apply({}, config),
items = cfg.items || me.items || [
me
],
hasGetClass, i, len;
me.origRenderer = cfg.renderer || me.renderer;
me.origScope = cfg.scope || me.scope;
me.renderer = me.scope = cfg.renderer = cfg.scope = null;
cfg.items = null;
me.callParent([
cfg
]);
me.items = items;
for (i = 0 , len = items.length; i < len; ++i) {
if (items[i].getClass) {
hasGetClass = true;
break;
}
}
if (me.origRenderer || hasGetClass) {
me.hasCustomRenderer = true;
}
},
initComponent: function() {
var me = this;
me.callParent();
if (me.sortable && !me.dataIndex) {
me.sortable = false;
}
},
defaultRenderer: function(v, cellValues, record, rowIdx, colIdx, store, view) {
var me = this,
prefix = Ext.baseCSSPrefix,
scope = me.origScope || me,
items = me.items,
len = items.length,
i = 0,
item, ret, disabled, tooltip;
ret = Ext.isFunction(me.origRenderer) ? me.origRenderer.apply(scope, arguments) || '' : '';
cellValues.tdCls += ' ' + Ext.baseCSSPrefix + 'action-col-cell';
for (; i < len; i++) {
item = items[i];
disabled = item.disabled || (item.isDisabled ? item.isDisabled.call(item.scope || scope, view, rowIdx, colIdx, item, record) : false);
tooltip = disabled ? null : (item.tooltip || (item.getTip ? item.getTip.apply(item.scope || scope, arguments) : null));
if (!item.hasActionConfiguration) {
item.stopSelection = me.stopSelection;
item.disable = Ext.Function.bind(me.disableAction, me, [
i
], 0);
item.enable = Ext.Function.bind(me.enableAction, me, [
i
], 0);
item.hasActionConfiguration = true;
}
ret += '<img role="button" alt="' + (item.altText || me.altText) + '" src="' + (item.icon || Ext.BLANK_IMAGE_URL) + '" class="' + me.actionIconCls + ' ' + prefix + 'action-col-' + String(i) + ' ' + (disabled ? prefix + 'item-disabled' : ' ') + (Ext.isFunction(item.getClass) ? item.getClass.apply(item.scope || scope, arguments) : (item.iconCls || me.iconCls || '')) + '"' + (tooltip ? ' data-qtip="' + tooltip + '"' : '') + ' />';
}
return ret;
},
updater: function(cell, value, record, view, dataSource) {
var cellValues = {};
cell.firstChild.innerHTML = this.defaultRenderer(value, cellValues, record, null, null, dataSource, view);
Ext.fly(cell).addCls(cellValues.tdCls);
},
enableAction: function(index, silent) {
var me = this;
if (!index) {
index = 0;
} else if (!Ext.isNumber(index)) {
index = Ext.Array.indexOf(me.items, index);
}
me.items[index].disabled = false;
me.up('tablepanel').el.select('.' + Ext.baseCSSPrefix + 'action-col-' + index).removeCls(me.disabledCls);
if (!silent) {
me.fireEvent('enable', me);
}
},
disableAction: function(index, silent) {
var me = this;
if (!index) {
index = 0;
} else if (!Ext.isNumber(index)) {
index = Ext.Array.indexOf(me.items, index);
}
me.items[index].disabled = true;
me.up('tablepanel').el.select('.' + Ext.baseCSSPrefix + 'action-col-' + index).addCls(me.disabledCls);
if (!silent) {
me.fireEvent('disable', me);
}
},
beforeDestroy: function() {
this.renderer = this.items = null;
return this.callParent(arguments);
},
processEvent: function(type, view, cell, recordIndex, cellIndex, e, record, row) {
var me = this,
target = e.getTarget(),
key = type === 'keydown' && e.getKey(),
match, item, disabled;
if (key && !Ext.fly(target).findParent(view.getCellSelector())) {
target = Ext.fly(cell).down('.' + Ext.baseCSSPrefix + 'action-col-icon', true);
}
if (target && (match = target.className.match(me.actionIdRe))) {
item = me.items[parseInt(match[1], 10)];
disabled = item.disabled || (item.isDisabled ? item.isDisabled.call(item.scope || me.origScope || me, view, recordIndex, cellIndex, item, record) : false);
if (item && !disabled) {
if (type === 'mousedown') {
if (item.stopSelection) {
e.preventDefault();
}
return false;
}
if (type === 'click' || (key === e.ENTER || key === e.SPACE)) {
Ext.callback(item.handler || me.handler, item.scope || me.origScope, [
view,
recordIndex,
cellIndex,
item,
e,
record,
row
], undefined, me);
if (item.stopSelection !== false) {
return false;
}
}
}
}
return me.callParent(arguments);
},
cascade: function(fn, scope) {
fn.call(scope || this, this);
},
getRefItems: function() {
return [];
},
privates: {
getFocusables: function() {
return [];
}
}
});
Ext.define('Ext.grid.column.Boolean', {
extend: 'Ext.grid.column.Column',
alias: [
'widget.booleancolumn'
],
alternateClassName: 'Ext.grid.BooleanColumn',
trueText: 'true',
falseText: 'false',
undefinedText: '&#160;',
defaultFilterType: 'boolean',
producesHTML: false,
defaultRenderer: function(value) {
if (value === undefined) {
return this.undefinedText;
}
if (!value || value === 'false') {
return this.falseText;
}
return this.trueText;
},
updater: function(cell, value) {
cell.firstChild.innerHTML = Ext.grid.column.Boolean.prototype.defaultRenderer.call(this, value);
}
});
Ext.define('Ext.grid.column.Check', {
extend: 'Ext.grid.column.Column',
alternateClassName: [
'Ext.ux.CheckColumn',
'Ext.grid.column.CheckColumn'
],
alias: 'widget.checkcolumn',
align: 'center',
stopSelection: true,
tdCls: Ext.baseCSSPrefix + 'grid-cell-checkcolumn',
innerCls: Ext.baseCSSPrefix + 'grid-cell-inner-checkcolumn',
clickTargetName: 'el',
defaultFilterType: 'boolean',
constructor: function() {
this.scope = this;
this.callParent(arguments);
},
processEvent: function(type, view, cell, recordIndex, cellIndex, e, record, row) {
var me = this,
key = type === 'keydown' && e.getKey(),
mousedown = type === 'mousedown',
disabled = me.disabled,
ret = false,
checked;
if (!disabled && (mousedown || (key === e.ENTER || key === e.SPACE))) {
checked = !me.isRecordChecked(record);
if (me.fireEvent('beforecheckchange', me, recordIndex, checked) !== false) {
me.setRecordCheck(record, checked, cell, row, e);
me.fireEvent('checkchange', me, recordIndex, checked);
if (mousedown) {
e.stopEvent();
}
if (!me.stopSelection) {
view.selModel.selectByPosition({
row: recordIndex,
column: cellIndex
});
}
}
} else if (!disabled && type === 'click') {
ret = false;
} else {
ret = me.callParent(arguments);
}
return ret;
},
onEnable: function() {
this.callParent(arguments);
this._setDisabled(false);
},
onDisable: function() {
this._setDisabled(true);
},
_setDisabled: function(disabled) {
var me = this,
cls = me.disabledCls,
items;
items = me.up('tablepanel').el.select(me.getCellSelector());
if (disabled) {
items.addCls(cls);
} else {
items.removeCls(cls);
}
},
defaultRenderer: function(value, cellValues) {
var cssPrefix = Ext.baseCSSPrefix,
cls = cssPrefix + 'grid-checkcolumn';
if (this.disabled) {
cellValues.tdCls += ' ' + this.disabledCls;
}
if (value) {
cls += ' ' + cssPrefix + 'grid-checkcolumn-checked';
}
return '<img class="' + cls + '" src="' + Ext.BLANK_IMAGE_URL + '"/>';
},
isRecordChecked: function(record) {
var prop = this.property;
if (prop) {
return record[prop];
}
return record.get(this.dataIndex);
},
setRecordCheck: function(record, checked, cell, row, e) {
var me = this,
prop = me.property;
if (prop) {
record[prop] = checked;
me.updater(cell, checked);
} else {
record.set(me.dataIndex, checked);
}
},
updater: function(cell, value) {
var cellValues = {},
tdCls;
cell.firstChild.innerHTML = this.defaultRenderer(value, cellValues);
tdCls = cellValues.tdCls;
if (tdCls) {
Ext.fly(cell).addCls(tdCls);
}
}
});
Ext.define('Ext.grid.column.Date', {
extend: 'Ext.grid.column.Column',
alias: [
'widget.datecolumn'
],
requires: [
'Ext.Date'
],
alternateClassName: 'Ext.grid.DateColumn',
isDateColumn: true,
defaultFilterType: 'date',
producesHTML: false,
initComponent: function() {
if (!this.format) {
this.format = Ext.Date.defaultFormat;
}
this.callParent(arguments);
},
defaultRenderer: function(value) {
return Ext.util.Format.date(value, this.format);
},
updater: function(cell, value) {
cell.firstChild.innerHTML = Ext.grid.column.Date.prototype.defaultRenderer.call(this, value);
}
});
Ext.define('Ext.grid.column.Number', {
extend: 'Ext.grid.column.Column',
alias: [
'widget.numbercolumn'
],
requires: [
'Ext.util.Format'
],
alternateClassName: 'Ext.grid.NumberColumn',
defaultFilterType: 'number',
format: '0,000.00',
producesHTML: false,
defaultRenderer: function(value) {
return Ext.util.Format.number(value, this.format);
},
updater: function(cell, value) {
cell.firstChild.innerHTML = Ext.grid.column.Number.prototype.defaultRenderer.call(this, value);
}
});
Ext.define('Ext.grid.column.RowNumberer', {
extend: 'Ext.grid.column.Column',
alternateClassName: 'Ext.grid.RowNumberer',
alias: 'widget.rownumberer',
text: "&#160;",
width: 23,
sortable: false,
draggable: false,
autoLock: true,
lockable: false,
align: 'right',
producesHTML: false,
constructor: function(config) {
var me = this;
me.width = me.width;
me.callParent(arguments);
me.sortable = false;
me.scope = me;
},
resizable: false,
hideable: false,
menuDisabled: true,
dataIndex: '',
cls: Ext.baseCSSPrefix + 'row-numberer',
tdCls: Ext.baseCSSPrefix + 'grid-cell-row-numberer ' + Ext.baseCSSPrefix + 'grid-cell-special',
innerCls: Ext.baseCSSPrefix + 'grid-cell-inner-row-numberer',
rowspan: undefined,
defaultRenderer: function(value, metaData, record, rowIdx, colIdx, dataSource, view) {
var rowspan = this.rowspan,
page = dataSource.currentPage,
result = view.store.indexOf(record);
if (metaData && rowspan) {
metaData.tdAttr = 'rowspan="' + rowspan + '"';
}
if (page > 1) {
result += (page - 1) * dataSource.pageSize;
}
return result + 1;
},
updater: function(cell, value, record, view, dataSource) {
cell.firstChild.innerHTML = this.defaultRenderer(value, null, record, null, null, dataSource, view);
}
});
Ext.define('Ext.grid.column.Template', {
extend: 'Ext.grid.column.Column',
alias: [
'widget.templatecolumn'
],
requires: [
'Ext.XTemplate'
],
alternateClassName: 'Ext.grid.TemplateColumn',
initComponent: function() {
var me = this;
me.tpl = (!Ext.isPrimitive(me.tpl) && me.tpl.compile) ? me.tpl : new Ext.XTemplate(me.tpl);
me.hasCustomRenderer = true;
me.callParent(arguments);
},
defaultRenderer: function(value, meta, record) {
var data = Ext.apply({}, record.data, record.getAssociatedData());
return this.tpl.apply(data);
},
updater: function(cell, value) {
cell.firstChild.innerHTML = Ext.grid.column.CheckColumn.prototype.defaultRenderer.call(this, value);
}
});
Ext.define('Ext.grid.column.Widget', {
extend: 'Ext.grid.column.Column',
alias: 'widget.widgetcolumn',
config: {
defaultWidgetUI: {}
},
sortable: false,
onWidgetAttach: null,
stopSelection: true,
preventUpdate: true,
initComponent: function() {
var me = this,
widget;
me.callParent(arguments);
widget = me.widget;
if (!widget || widget.isComponent) {
Ext.Error.raise('column.Widget requires a widget configuration.');
}
me.widget = widget = Ext.apply({}, widget);
if (!widget.ui) {
widget.ui = me.getDefaultWidgetUI()[widget.xtype] || 'default';
}
me.isFixedSize = Ext.isNumber(widget.width);
},
processEvent: function(type, view, cell, recordIndex, cellIndex, e, record, row) {
var selector = view.innerSelector,
target;
if (this.stopSelection && type === 'click') {
target = e.getTarget(selector);
if (target && target !== e.target) {
return false;
}
}
},
beforeRender: function() {
var me = this,
tdCls = me.tdCls,
widget;
me.listenerScopeFn = function(defaultScope) {
if (defaultScope === 'this') {
return this;
}
return me.resolveListenerScope(defaultScope);
};
me.liveWidgets = {};
me.cachedStyles = {};
me.freeWidgetStack = [
widget = me.getFreeWidget()
];
tdCls = tdCls ? tdCls + ' ' : '';
me.tdCls = tdCls + widget.getTdCls();
me.setupViewListeners(me.getView());
me.callParent();
},
afterRender: function() {
var view = this.getView();
this.callParent();
if (view && view.viewReady && !view.ownerGrid.reconfiguring) {
this.onViewRefresh(view, view.getViewRange());
}
},
defaultRenderer: Ext.emptyFn,
updater: function(cell, value, record) {
this.updateWidget(record);
},
onResize: function(newWidth) {
var me = this,
liveWidgets = me.liveWidgets,
view = me.getView(),
id, cell;
if (!me.isFixedSize && me.rendered && view && view.viewReady) {
cell = view.getEl().down(me.getCellInnerSelector());
if (cell) {
newWidth -= parseInt(me.getCachedStyle(cell, 'padding-left'), 10) + parseInt(me.getCachedStyle(cell, 'padding-right'), 10);
for (id in liveWidgets) {
liveWidgets[id].setWidth(newWidth);
}
}
}
},
onAdded: function() {
var me = this,
view;
me.callParent(arguments);
view = me.getView();
if (view) {
me.setupViewListeners(view);
if (view && view.viewReady && me.rendered && view.getEl().down(me.getCellSelector())) {
me.onViewRefresh(view, view.getViewRange());
}
}
},
onRemoved: function(isDestroying) {
var me = this,
liveWidgets = me.liveWidgets,
viewListeners = me.viewListeners,
id;
if (me.rendered) {
me.viewListeners = viewListeners && Ext.destroy(viewListeners);
if (!isDestroying) {
for (id in liveWidgets) {
liveWidgets[id].detachFromBody();
}
}
}
me.callParent(arguments);
},
onDestroy: function() {
var me = this,
oldWidgetMap = me.liveWidgets,
freeWidgetStack = me.freeWidgetStack,
id, widget, i, len;
if (me.rendered) {
for (id in oldWidgetMap) {
widget = oldWidgetMap[id];
widget.$widgetRecord = widget.$widgetColumn = null;
delete widget.getWidgetRecord;
delete widget.getWidgetColumn;
widget.destroy();
}
for (i = 0 , len = freeWidgetStack.length; i < len; ++i) {
freeWidgetStack[i].destroy();
}
}
me.freeWidgetStack = me.liveWidgets = null;
me.callParent();
},
getWidget: function(record) {
var liveWidgets = this.liveWidgets,
widget;
if (record && liveWidgets) {
widget = liveWidgets[record.internalId];
}
return widget || null;
},
privates: {
getCachedStyle: function(el, style) {
var cachedStyles = this.cachedStyles;
return cachedStyles[style] || (cachedStyles[style] = Ext.fly(el).getStyle(style));
},
getFreeWidget: function() {
var me = this,
result = me.freeWidgetStack ? me.freeWidgetStack.pop() : null;
if (!result) {
result = Ext.widget(me.widget);
result.resolveListenerScope = me.listenerScopeFn;
result.getWidgetRecord = me.widgetRecordDecorator;
result.getWidgetColumn = me.widgetColumnDecorator;
result.dataIndex = me.dataIndex;
result.measurer = me;
result.ownerCmp = me;
result.isLayoutChild = me.returnFalse;
}
return result;
},
onBeforeRefresh: function() {
var liveWidgets = this.liveWidgets,
id;
for (id in liveWidgets) {
liveWidgets[id].detachFromBody();
}
},
onItemAdd: function(records, index, items) {
var me = this,
view = me.getView(),
hasAttach = !!me.onWidgetAttach,
dataIndex = me.dataIndex,
isFixedSize = me.isFixedSize,
len = records.length,
i, record, row, cell, widget, el, width;
if (me.isVisible(true)) {
for (i = 0; i < len; i++) {
record = records[i];
if (record.isNonData) {
continue;
}
row = view.getRowFromItem(items[i]);
if (row) {
cell = row.cells[me.getVisibleIndex()].firstChild;
if (!isFixedSize && !width) {
width = me.lastBox.width - parseInt(me.getCachedStyle(cell, 'padding-left'), 10) - parseInt(me.getCachedStyle(cell, 'padding-right'), 10);
}
widget = me.liveWidgets[record.internalId] = me.getFreeWidget();
widget.$widgetColumn = me;
widget.$widgetRecord = record;
Ext.fly(cell).empty();
if (widget.defaultBindProperty && dataIndex) {
widget.setConfig(widget.defaultBindProperty, record.get(dataIndex));
}
if (hasAttach) {
Ext.callback(me.onWidgetAttach, me.scope, [
me,
widget,
record
], 0, me);
}
el = widget.el || widget.element;
if (el) {
cell.appendChild(el.dom);
if (!isFixedSize) {
widget.setWidth(width);
}
widget.reattachToBody();
} else {
if (!isFixedSize) {
widget.width = width;
}
widget.render(cell);
}
}
}
}
},
onItemRemove: function(records, index, items) {
var me = this,
liveWidgets = me.liveWidgets,
widget, item, id, len, i;
if (me.rendered) {
items = Ext.Array.from(items);
len = items.length;
for (i = 0; i < len; i++) {
item = items[i];
id = item.getAttribute('data-recordId');
if (id && (widget = liveWidgets[id])) {
delete liveWidgets[id];
me.freeWidgetStack.unshift(widget);
widget.$widgetRecord = widget.$widgetColumn = null;
widget.detachFromBody();
}
}
}
},
onItemUpdate: function(record, recordIndex, oldItemDom) {
this.updateWidget(record);
},
onViewRefresh: function(view, records) {
var me = this,
rows = view.all,
hasAttach = !!me.onWidgetAttach,
oldWidgetMap = me.liveWidgets,
dataIndex = me.dataIndex,
isFixedSize = me.isFixedSize,
cell, widget, el, width, recordId, itemIndex, recordIndex, record, id, lastBox, dom;
if (me.isVisible(true)) {
me.liveWidgets = {};
Ext.suspendLayouts();
for (itemIndex = rows.startIndex , recordIndex = 0; itemIndex <= rows.endIndex; itemIndex++ , recordIndex++) {
record = records[recordIndex];
if (record.isNonData) {
continue;
}
recordId = record.internalId;
cell = view.getRow(rows.item(itemIndex)).cells[me.getVisibleIndex()].firstChild;
widget = me.liveWidgets[recordId] = oldWidgetMap[recordId] || me.getFreeWidget();
widget.$widgetRecord = record;
widget.$widgetColumn = me;
delete oldWidgetMap[recordId];
lastBox = me.lastBox;
if (lastBox && !isFixedSize && width === undefined) {
width = lastBox.width - parseInt(me.getCachedStyle(cell, 'padding-left'), 10) - parseInt(me.getCachedStyle(cell, 'padding-right'), 10);
}
if (widget.defaultBindProperty && dataIndex) {
widget.setConfig(widget.defaultBindProperty, records[recordIndex].get(dataIndex));
}
if (hasAttach) {
Ext.callback(me.onWidgetAttach, me.scope, [
me,
widget,
record
], 0, me);
}
el = widget.el || widget.element;
if (el) {
dom = el.dom;
if (dom.parentNode !== cell) {
Ext.fly(cell).empty();
cell.appendChild(el.dom);
}
if (!isFixedSize) {
widget.setWidth(width);
}
widget.reattachToBody();
} else {
if (!isFixedSize) {
widget.width = width;
}
Ext.fly(cell).empty();
widget.render(cell);
}
}
Ext.resumeLayouts(true);
for (id in oldWidgetMap) {
widget = oldWidgetMap[id];
widget.$widgetRecord = widget.$widgetColumn = null;
me.freeWidgetStack.unshift(widget);
widget.detachFromBody();
}
}
},
returnFalse: function() {
return false;
},
setupViewListeners: function(view) {
var me = this;
me.viewListeners = view.on({
refresh: me.onViewRefresh,
itemupdate: me.onItemUpdate,
itemadd: me.onItemAdd,
itemremove: me.onItemRemove,
scope: me,
destroyable: true
});
if (Ext.isIE8) {
view.on('beforerefresh', me.onBeforeRefresh, me);
}
},
updateWidget: function(record) {
var dataIndex = this.dataIndex,
widget;
if (this.rendered) {
widget = this.liveWidgets[record.internalId];
if (widget && widget.defaultBindProperty && dataIndex) {
widget.setConfig(widget.defaultBindProperty, record.get(dataIndex));
}
}
},
widgetRecordDecorator: function() {
return this.$widgetRecord;
},
widgetColumnDecorator: function() {
return this.$widgetColumn;
}
}
});
Ext.define('Ext.grid.feature.Feature', {
extend: 'Ext.util.Observable',
alias: 'feature.feature',
wrapsItem: false,
isFeature: true,
disabled: false,
hasFeatureEvent: true,
eventPrefix: null,
eventSelector: null,
view: null,
grid: null,
constructor: function(config) {
this.initialConfig = config;
this.callParent(arguments);
},
clone: function() {
return new this.self(this.initialConfig);
},
init: Ext.emptyFn,
destroy: function() {
this.clearListeners();
},
getFireEventArgs: function(eventName, view, featureTarget, e) {
return [
eventName,
view,
featureTarget,
e
];
},
vetoEvent: Ext.emptyFn,
enable: function() {
this.disabled = false;
},
disable: function() {
this.disabled = true;
}
});
Ext.define('Ext.grid.feature.AbstractSummary', {
extend: 'Ext.grid.feature.Feature',
alias: 'feature.abstractsummary',
summaryRowCls: Ext.baseCSSPrefix + 'grid-row-summary',
summaryRowSelector: '.' + Ext.baseCSSPrefix + 'grid-row-summary',
readDataOptions: {
recordCreator: Ext.identityFn
},
summaryRowTpl: {
fn: function(out, values, parent) {
if (values.record.isSummary && this.summaryFeature.showSummaryRow) {
this.summaryFeature.outputSummaryRecord(values.record, values, out, parent);
} else {
this.nextTpl.applyOut(values, out, parent);
}
},
priority: 1000
},
showSummaryRow: true,
init: function() {
var me = this;
me.view.summaryFeature = me;
me.rowTpl = me.view.self.prototype.rowTpl;
me.view.addRowTpl(me.summaryRowTpl).summaryFeature = me;
me.summaryData = {};
me.groupInfo = {};
if (!me.summaryTableCls) {
me.summaryTableCls = Ext.baseCSSPrefix + 'grid-item';
}
},
toggleSummaryRow: function(visible,
fromLockingPartner) {
var me = this,
prev = me.showSummaryRow,
doRefresh;
visible = visible != null ? !!visible : !me.showSummaryRow;
me.showSummaryRow = visible;
if (visible && visible !== prev) {
me.updateNext = true;
}
if (me.lockingPartner) {
if (!fromLockingPartner) {
me.lockingPartner.toggleSummaryRow(visible, true);
doRefresh = true;
}
} else {
doRefresh = true;
}
if (doRefresh) {
me.grid.ownerGrid.getView().refresh();
}
},
createRenderer: function(column, record) {
var me = this,
ownerGroup = record.ownerGroup,
summaryData = ownerGroup ? me.summaryData[ownerGroup] : me.summaryData,
dataIndex = column.dataIndex || column.getItemId();
return function(value, metaData) {
return column.summaryRenderer ? column.summaryRenderer(record.data[dataIndex], summaryData, dataIndex, metaData) :
record.data[dataIndex];
};
},
outputSummaryRecord: function(summaryRecord, contextValues, out) {
var view = contextValues.view,
savedRowValues = view.rowValues,
columns = contextValues.columns || view.headerCt.getVisibleGridColumns(),
colCount = columns.length,
i, column,
values = {
view: view,
record: summaryRecord,
rowStyle: '',
rowClasses: [
this.summaryRowCls
],
itemClasses: [],
recordIndex: -1,
rowId: view.getRowId(summaryRecord),
columns: columns
};
for (i = 0; i < colCount; i++) {
column = columns[i];
column.savedRenderer = column.renderer;
if (column.summaryType || column.summaryRenderer) {
column.renderer = this.createRenderer(column, summaryRecord);
} else {
column.renderer = Ext.emptyFn;
}
}
view.rowValues = values;
view.self.prototype.rowTpl.applyOut(values, out, parent);
view.rowValues = savedRowValues;
for (i = 0; i < colCount; i++) {
column = columns[i];
column.renderer = column.savedRenderer;
column.savedRenderer = null;
}
},
getSummary: function(store, type, field, group) {
var isGrouped = !!group,
item = isGrouped ? group : store;
if (type) {
if (Ext.isFunction(type)) {
if (isGrouped) {
return item.aggregate(field, type);
} else {
return item.aggregate(type, null, false, [
field
]);
}
}
switch (type) {
case 'count':
return item.count(field);
case 'min':
return item.min(field);
case 'max':
return item.max(field);
case 'sum':
return item.sum(field);
case 'average':
return item.average(field);
default:
return '';
}
}
},
generateSummaryData: function(groupField) {
var me = this,
reader = me.view.store.getProxy().getReader(),
convertedSummaryRow = {},
remoteData = {},
i, len, root, summaryRows;
root = reader.getRootProperty();
reader.setRootProperty(me.remoteRoot);
reader.buildExtractors(true);
summaryRows = reader.getRoot(reader.rawData);
if (summaryRows) {
if (!Ext.isArray(summaryRows)) {
summaryRows = [
summaryRows
];
}
len = summaryRows.length;
for (i = 0; i < len; ++i) {
convertedSummaryRow = reader.extractRecordData(summaryRows[i], me.readDataOptions);
if (groupField) {
remoteData[convertedSummaryRow[groupField]] = convertedSummaryRow;
}
}
}
reader.setRootProperty(root);
reader.buildExtractors(true);
return groupField ? remoteData : convertedSummaryRow;
},
setSummaryData: function(record, colId, summaryValue, groupName) {
var summaryData = this.summaryData;
if (groupName) {
if (!summaryData[groupName]) {
summaryData[groupName] = {};
}
summaryData[groupName][colId] = summaryValue;
} else {
summaryData[colId] = summaryValue;
}
}
});
Ext.define('Ext.grid.feature.GroupStore', {
extend: 'Ext.util.Observable',
isStore: true,
defaultViewSize: 100,
isFeatureStore: true,
badGrouperKey: '[object Object]',
constructor: function(groupingFeature, store) {
var me = this;
me.callParent();
me.groupingFeature = groupingFeature;
me.bindStore(store);
},
bindStore: function(store) {
var me = this;
if (!store || me.store !== store) {
Ext.destroy(me.storeListeners);
me.store = null;
}
if (store) {
me.storeListeners = store.on({
groupchange: me.onGroupChange,
remove: me.onRemove,
add: me.onAdd,
idchanged: me.onIdChanged,
update: me.onUpdate,
refresh: me.onRefresh,
clear: me.onClear,
scope: me,
destroyable: true
});
me.store = store;
me.processStore(store);
}
},
processStore: function(store) {
var me = this,
groupingFeature = me.groupingFeature,
collapseAll = groupingFeature.startCollapsed,
data = me.data,
ExtArray = Ext.Array,
indexOf = ExtArray.indexOf,
splice = ExtArray.splice,
groups = store.getGroups(),
groupCount = groups ? groups.length : 0,
groupField = store.getGroupField(),
groupNames = groups && ExtArray.unique(Ext.Object.getValues(groups.itemGroupKeys)),
isCollapsed = false,
oldMetaGroupCache = groupingFeature.getCache(),
metaGroup, metaGroupCache, i, len, featureGrouper, group, groupName, groupPlaceholder, key, modelData, Model;
groupingFeature.invalidateCache();
metaGroupCache = groupingFeature.getCache();
if (data) {
data.clear();
} else {
data = me.data = new Ext.util.Collection({
rootProperty: 'data',
extraKeys: {
byInternalId: {
property: 'internalId',
rootProperty: ''
}
}
});
}
if (store.getCount()) {
groupingFeature.startCollapsed = false;
if (groupCount > 0) {
Model = store.getModel();
for (i = 0; i < groupCount; i++) {
group = groups.getAt(i);
key = group.getGroupKey();
if (me.badGrouperKey === key && (featureGrouper = groupingFeature.getGrouper(groupField))) {
groupingFeature.startCollapsed = collapseAll;
store.group(featureGrouper);
return;
}
metaGroup = metaGroupCache[key] = oldMetaGroupCache[key] || groupingFeature.getMetaGroup(key);
metaGroup.raw = group.getAt(0).get(groupField);
splice(groupNames, indexOf(groupNames, key), 1);
isCollapsed = metaGroup.isCollapsed = collapseAll || metaGroup.isCollapsed;
if (isCollapsed) {
modelData = {};
modelData[groupField] = key;
metaGroup.placeholder = groupPlaceholder = new Model(modelData);
groupPlaceholder.isNonData = groupPlaceholder.isCollapsedPlaceholder = true;
groupPlaceholder.group = group;
data.add(groupPlaceholder);
} else
{
data.insert(me.data.length, group.items);
}
}
if (groupNames.length) {
for (i = 0 , len = groupNames.length; i < len; i++) {
groupName = groupNames[i];
metaGroupCache[groupName] = oldMetaGroupCache[groupName];
}
}
oldMetaGroupCache = null;
} else {
data.add(store.getRange());
}
}
},
isCollapsed: function(name) {
return this.groupingFeature.getCache()[name].isCollapsed;
},
isLoading: function() {
return false;
},
getData: function() {
return this.data;
},
getCount: function() {
return this.data.getCount();
},
getTotalCount: function() {
return this.data.getCount();
},
rangeCached: function(start, end) {
return end < this.getCount();
},
getRange: function(start, end, options) {
var result = this.data.getRange(start, Ext.isNumber(end) ? end + 1 : end);
if (options && options.callback) {
options.callback.call(options.scope || this, result, start, end, options);
}
return result;
},
getAt: function(index) {
return this.data.getAt(index);
},
getById: function(id) {
return this.store.getById(id);
},
getByInternalId: function(internalId) {
return this.store.getByInternalId(internalId) || this.data.byInternalId.get(internalId);
},
expandGroup: function(group) {
var me = this,
groupingFeature = me.groupingFeature,
metaGroup, placeholder, startIdx, items;
if (typeof group === 'string') {
group = groupingFeature.getGroup(group);
}
if (group) {
items = group.items;
metaGroup = groupingFeature.getMetaGroup(group);
placeholder = metaGroup.placeholder;
}
if (items.length && (startIdx = me.data.indexOf(placeholder)) !== -1) {
metaGroup.isCollapsed = false;
me.isExpandingOrCollapsing = 1;
me.data.removeAt(startIdx);
me.data.insert(startIdx, group.items);
me.fireEvent('replace', me, startIdx, [
placeholder
], group.items);
me.fireEvent('groupexpand', me, group);
me.isExpandingOrCollapsing = 0;
}
},
collapseGroup: function(group) {
var me = this,
groupingFeature = me.groupingFeature,
startIdx, placeholder, len, items;
if (typeof group === 'string') {
group = groupingFeature.getGroup(group);
}
if (group) {
items = group.items;
}
if (items && (len = items.length) && (startIdx = me.data.indexOf(items[0])) !== -1) {
groupingFeature.getMetaGroup(group).isCollapsed = true;
me.isExpandingOrCollapsing = 2;
me.data.removeAt(startIdx, len);
me.data.insert(startIdx, placeholder = me.getGroupPlaceholder(group));
me.fireEvent('replace', me, startIdx, items, [
placeholder
]);
me.fireEvent('groupcollapse', me, group);
me.isExpandingOrCollapsing = 0;
}
},
getGroupPlaceholder: function(group) {
var metaGroup = this.groupingFeature.getMetaGroup(group);
if (!metaGroup.placeholder) {
var store = this.store,
Model = store.getModel(),
modelData = {},
key = group.getGroupKey(),
groupPlaceholder;
modelData[store.getGroupField()] = key;
groupPlaceholder = metaGroup.placeholder = new Model(modelData);
groupPlaceholder.isNonData = groupPlaceholder.isCollapsedPlaceholder = true;
groupPlaceholder.group = group;
}
return metaGroup.placeholder;
},
indexOf: function(record) {
if (!record.isCollapsedPlaceholder) {
return this.data.indexOf(record);
}
return -1;
},
indexOfId: function(id) {
return this.data.indexOfKey(id);
},
indexOfTotal: function(record) {
return this.store.indexOf(record);
},
onRefresh: function(store) {
this.processStore(this.store);
this.fireEvent('refresh', this);
},
onRemove: function(store, records, index, isMove) {
var me = this;
if (store.isMoving()) {
return;
}
me.processStore(me.store);
me.fireEvent('refresh', me);
},
onClear: function(store, records, startIndex) {
var me = this;
me.processStore(me.store);
me.fireEvent('clear', me);
},
onAdd: function(store, records, startIndex) {
var me = this;
me.processStore(me.store);
me.fireEvent('replace', me, me.indexOf(records[0]), [], records);
},
onIdChanged: function(store, rec, oldId, newId) {
this.data.updateKey(rec, oldId);
},
onUpdate: function(store, record, operation, modifiedFieldNames) {
var me = this,
groupingFeature = me.groupingFeature,
group, metaGroup, firstRec, lastRec, items;
if (store.isGrouped()) {
group = record.group = groupingFeature.getGroup(record);
metaGroup = groupingFeature.getMetaGroup(record);
if (modifiedFieldNames && Ext.Array.contains(modifiedFieldNames, groupingFeature.getGroupField())) {
return me.onRefresh(me.store);
}
if (metaGroup.isCollapsed) {
me.fireEvent('update', me, metaGroup.placeholder);
} else
{
Ext.suspendLayouts();
me.fireEvent('update', me, record, operation, modifiedFieldNames);
items = group.items;
firstRec = items[0];
lastRec = items[items.length - 1];
if (firstRec !== record) {
firstRec.group = group;
me.fireEvent('update', me, firstRec, 'edit', modifiedFieldNames);
delete firstRec.group;
}
if (lastRec !== record && lastRec !== firstRec && groupingFeature.showSummaryRow) {
lastRec.group = group;
me.fireEvent('update', me, lastRec, 'edit', modifiedFieldNames);
delete lastRec.group;
}
Ext.resumeLayouts(true);
}
delete record.group;
} else {
me.fireEvent('update', me, record, operation, modifiedFieldNames);
}
},
onGroupChange: function(store, grouper) {
if (!grouper) {
this.processStore(store);
}
this.fireEvent('groupchange', store, grouper);
},
destroy: function() {
var me = this;
me.bindStore(null);
me.clearListeners();
Ext.destroyMembers(me, 'data', 'groupingFeature');
}
});
Ext.define('Ext.grid.feature.Grouping', {
extend: 'Ext.grid.feature.Feature',
mixins: {
summary: 'Ext.grid.feature.AbstractSummary'
},
requires: [
'Ext.grid.feature.GroupStore'
],
alias: 'feature.grouping',
eventPrefix: 'group',
eventSelector: '.' + Ext.baseCSSPrefix + 'grid-group-hd',
refreshData: {},
wrapsItem: true,
groupHeaderTpl: '{columnName}: {name}',
depthToIndent: 17,
collapsedCls: Ext.baseCSSPrefix + 'grid-group-collapsed',
hdCollapsedCls: Ext.baseCSSPrefix + 'grid-group-hd-collapsed',
hdNotCollapsibleCls: Ext.baseCSSPrefix + 'grid-group-hd-not-collapsible',
collapsibleCls: Ext.baseCSSPrefix + 'grid-group-hd-collapsible',
ctCls: Ext.baseCSSPrefix + 'group-hd-container',
groupByText: 'Group by this field',
showGroupsText: 'Show in groups',
hideGroupedHeader: false,
startCollapsed: false,
enableGroupingMenu: true,
enableNoGroups: true,
collapsible: true,
groupers: null,
expandTip: 'Click to expand. CTRL key collapses all others',
collapseTip: 'Click to collapse. CTRL/click collapses all others',
showSummaryRow: false,
outerTpl: [
'{%',
'if (!(this.groupingFeature.disabled || values.rows.length === 1 && values.rows[0].isSummary)) {',
'this.groupingFeature.setup(values.rows, values.view.rowValues);',
'}',
'this.nextTpl.applyOut(values, out, parent);',
'if (!(this.groupingFeature.disabled || values.rows.length === 1 && values.rows[0].isSummary)) {',
'this.groupingFeature.cleanup(values.rows, values.view.rowValues);',
'}',
'%}',
{
priority: 200
}
],
groupRowTpl: [
'{%',
'var me = this.groupingFeature,',
'colspan = "colspan=" + values.columns.length;',
'if (me.disabled || parent.rows.length === 1 && parent.rows[0].isSummary) {',
'values.needsWrap = false;',
'} else {',
'me.setupRowData(values.record, values.rowIndex, values);',
'}',
'%}',
'<tpl if="needsWrap">',
'<tpl if="isFirstRow">',
'{% values.view.renderColumnSizer(values, out); %}',
'<tr data-boundView="{view.id}" data-recordId="{record.internalId:htmlEncode}" data-recordIndex="{[values.isCollapsedGroup ? -1 : values.recordIndex]}" class="{groupHeaderCls}">',
'<td class="{[me.ctCls]}" {[colspan]}>',
'{%',
'var groupTitleStyle = (!values.view.lockingPartner || (values.view.ownerCt === values.view.ownerCt.ownerLockable.lockedGrid) || (values.view.lockingPartner.headerCt.getVisibleGridColumns().length === 0)) ? "" : "visibility:hidden";',
'%}',
'<div data-groupname="{groupName:htmlEncode}" class="',
Ext.baseCSSPrefix,
'grid-group-hd {collapsibleCls}" nottabindex="0" hidefocus="on" {ariaCellInnerAttr}>',
'<div class="',
Ext.baseCSSPrefix,
'grid-group-title" style="{[groupTitleStyle]}" {ariaGroupTitleAttr}>',
'{[values.groupHeaderTpl.apply(values.metaGroupCache, parent) || "&#160;"]}',
'</div>',
'</div>',
'</td>',
'</tr>',
'</tpl>',
'<tpl if="!isCollapsedGroup">',
'{%',
'values.itemClasses.length = 0;',
'this.nextTpl.applyOut(values, out, parent);',
'%}',
'</tpl>',
'<tpl if="summaryRecord">',
'{%me.outputSummaryRecord(values.summaryRecord, values, out, parent);%}',
'</tpl>',
'<tpl else>',
'{%this.nextTpl.applyOut(values, out, parent);%}',
'</tpl>',
{
priority: 200,
beginRowSync: function(rowSync) {
var owner = this.owner;
rowSync.add('header', owner.eventSelector);
rowSync.add('summary', owner.summaryRowSelector);
},
syncContent: function(destRow, sourceRow, columnsToUpdate) {
destRow = Ext.fly(destRow, 'syncDest');
sourceRow = Ext.fly(sourceRow, 'sycSrc');
var owner = this.owner,
destHd = destRow.down(owner.eventSelector, true),
sourceHd = sourceRow.down(owner.eventSelector, true),
destSummaryRow = destRow.down(owner.summaryRowSelector, true),
sourceSummaryRow = sourceRow.down(owner.summaryRowSelector, true);
if (destHd && sourceHd) {
Ext.fly(destHd).syncContent(sourceHd);
}
if (destSummaryRow && sourceSummaryRow) {
if (columnsToUpdate) {
this.groupingFeature.view.updateColumns(destSummaryRow, sourceSummaryRow, columnsToUpdate);
} else
{
Ext.fly(destSummaryRow).syncContent(sourceSummaryRow);
}
}
}
}
],
init: function(grid) {
var me = this,
view = me.view,
store = me.getGridStore(),
lockPartner, dataSource;
view.isGrouping = store.isGrouped();
me.mixins.summary.init.call(me);
me.callParent([
grid
]);
view.headerCt.on({
columnhide: me.onColumnHideShow,
columnshow: me.onColumnHideShow,
columnmove: me.onColumnMove,
scope: me
});
view.addTpl(Ext.XTemplate.getTpl(me, 'outerTpl')).groupingFeature = me;
view.addRowTpl(Ext.XTemplate.getTpl(me, 'groupRowTpl')).groupingFeature = me;
view.preserveScrollOnRefresh = true;
if (store.isBufferedStore) {
me.collapsible = false;
} else
{
lockPartner = me.lockingPartner;
if (lockPartner && lockPartner.dataSource) {
me.dataSource = view.dataSource = dataSource = lockPartner.dataSource;
} else {
me.dataSource = view.dataSource = dataSource = new Ext.grid.feature.GroupStore(me, store);
}
}
grid = grid.ownerLockable || grid;
grid.on('beforereconfigure', me.beforeReconfigure, me);
view.on({
afterrender: me.afterViewRender,
scope: me,
single: true
});
if (dataSource) {
dataSource.on('groupchange', me.onGroupChange, me);
} else {
me.setupStoreListeners(store);
}
},
getGridStore: function() {
return this.view.getStore();
},
indexOf: function(record) {
return this.dataSource.indexOf(record);
},
isInCollapsedGroup: function(record) {
var me = this,
store = me.getGridStore(),
result = false,
metaGroup;
if (store.isGrouped() && (metaGroup = me.getMetaGroup(record))) {
result = !!(metaGroup && metaGroup.isCollapsed);
}
return result;
},
createCache: function() {
var metaGroupCache = this.metaGroupCache = {},
lockingPartner = this.lockingPartner;
if (lockingPartner) {
lockingPartner.metaGroupCache = metaGroupCache;
}
return metaGroupCache;
},
getCache: function() {
return this.metaGroupCache || this.createCache();
},
invalidateCache: function() {
var lockingPartner = this.lockingPartner;
this.metaGroupCache = null;
if (lockingPartner) {
lockingPartner.metaGroupCache = null;
}
},
vetoEvent: function(record, row, rowIndex, e) {
if (e.type !== 'mouseover' && e.type !== 'mouseout' && e.type !== 'mouseenter' && e.type !== 'mouseleave' && e.getTarget(this.eventSelector)) {
return false;
}
},
enable: function() {
var me = this,
view = me.view,
store = me.getGridStore(),
currentGroupedHeader = me.hideGroupedHeader && me.getGroupedHeader(),
groupToggleMenuItem;
view.isGrouping = true;
if (view.lockingPartner) {
view.lockingPartner.isGrouping = true;
}
me.callParent();
if (me.lastGrouper) {
store.group(me.lastGrouper);
me.lastGrouper = null;
}
if (currentGroupedHeader) {
currentGroupedHeader.hide();
}
groupToggleMenuItem = me.view.headerCt.getMenu().down('#groupToggleMenuItem');
if (groupToggleMenuItem) {
groupToggleMenuItem.setChecked(true, true);
}
},
disable: function() {
var me = this,
view = me.view,
store = me.getGridStore(),
currentGroupedHeader = me.hideGroupedHeader && me.getGroupedHeader(),
lastGrouper = store.getGrouper(),
groupToggleMenuItem;
view.isGrouping = false;
if (view.lockingPartner) {
view.lockingPartner.isGrouping = false;
}
me.callParent();
if (lastGrouper) {
me.lastGrouper = lastGrouper;
store.clearGrouping();
}
if (currentGroupedHeader) {
currentGroupedHeader.show();
}
groupToggleMenuItem = me.view.headerCt.getMenu().down('#groupToggleMenuItem');
if (groupToggleMenuItem) {
groupToggleMenuItem.setChecked(false, true);
groupToggleMenuItem.disable();
}
},
afterViewRender: function() {
var me = this,
view = me.view;
view.on({
scope: me,
groupclick: me.onGroupClick
});
if (me.enableGroupingMenu) {
me.injectGroupingMenu();
}
me.pruneGroupedHeader();
me.lastGrouper = me.getGridStore().getGrouper();
if (me.disabled) {
me.disable();
}
},
injectGroupingMenu: function() {
var me = this,
headerCt = me.view.headerCt;
headerCt.showMenuBy = me.showMenuBy;
headerCt.getMenuItems = me.getMenuItems();
},
onColumnHideShow: function(headerOwnerCt, header) {
var me = this,
view = me.view,
headerCt = view.headerCt,
menu = headerCt.getMenu(),
activeHeader = menu.activeHeader,
groupMenuItem = menu.down('#groupMenuItem'),
groupMenuMeth,
colCount = me.grid.getVisibleColumnManager().getColumns().length,
items, len, i;
if (activeHeader && groupMenuItem) {
groupMenuMeth = activeHeader.groupable === false || !activeHeader.dataIndex || me.view.headerCt.getVisibleGridColumns().length < 2 ? 'disable' : 'enable';
groupMenuItem[groupMenuMeth]();
}
if (view.rendered && colCount) {
items = view.el.query('.' + me.ctCls);
for (i = 0 , len = items.length; i < len; ++i) {
items[i].colSpan = colCount;
}
}
},
onColumnMove: function() {
var me = this,
view = me.view,
groupName, groupNames, group, firstRec, lastRec, metaGroup;
if (view.getStore().isGrouped()) {
groupNames = me.getCache().map;
Ext.suspendLayouts();
for (groupName in groupNames) {
group = me.getGroup(groupName);
firstRec = group.first();
lastRec = group.last();
metaGroup = me.getMetaGroup(groupName);
if (metaGroup.isCollapsed) {
firstRec = lastRec = me.dataSource.getGroupPlaceholder(groupName);
}
view.refreshNode(firstRec);
if (me.showSummaryRow && lastRec !== firstRec) {
view.refreshNode(lastRec);
}
}
Ext.resumeLayouts(true);
}
},
showMenuBy: function(clickEvent, t, header) {
var me = this,
menu = me.getMenu(),
groupMenuItem = menu.down('#groupMenuItem'),
groupMenuMeth = header.groupable === false || !header.dataIndex || me.view.headerCt.getVisibleGridColumns().length < 2 ? 'disable' : 'enable',
groupToggleMenuItem = menu.down('#groupToggleMenuItem'),
isGrouped = me.grid.getStore().isGrouped();
groupMenuItem[groupMenuMeth]();
if (groupToggleMenuItem) {
groupToggleMenuItem.setChecked(isGrouped, true);
groupToggleMenuItem[isGrouped ? 'enable' : 'disable']();
}
Ext.grid.header.Container.prototype.showMenuBy.apply(me, arguments);
},
getMenuItems: function() {
var me = this,
groupByText = me.groupByText,
disabled = me.disabled || !me.getGroupField(),
showGroupsText = me.showGroupsText,
enableNoGroups = me.enableNoGroups,
getMenuItems = me.view.headerCt.getMenuItems;
return function() {
var o = getMenuItems.call(this);
o.push('-', {
iconCls: Ext.baseCSSPrefix + 'group-by-icon',
itemId: 'groupMenuItem',
text: groupByText,
handler: me.onGroupMenuItemClick,
scope: me
});
if (enableNoGroups) {
o.push({
itemId: 'groupToggleMenuItem',
text: showGroupsText,
checked: !disabled,
checkHandler: me.onGroupToggleMenuItemClick,
scope: me
});
}
return o;
};
},
onGroupMenuItemClick: function(menuItem, e) {
var me = this,
menu = menuItem.parentMenu,
hdr = menu.activeHeader,
view = me.view,
store = me.getGridStore();
if (me.disabled) {
me.lastGrouper = null;
me.block();
me.enable();
me.unblock();
}
view.isGrouping = true;
store.group(me.getGrouper(hdr.dataIndex) || hdr.dataIndex);
me.pruneGroupedHeader();
},
block: function(fromPartner) {
var me = this;
me.blockRefresh = me.view.blockRefresh = true;
if (me.lockingPartner && !fromPartner) {
me.lockingPartner.block(true);
}
},
unblock: function(fromPartner) {
var me = this;
me.blockRefresh = me.view.blockRefresh = false;
if (me.lockingPartner && !fromPartner) {
me.lockingPartner.unblock(true);
}
},
onGroupToggleMenuItemClick: function(menuItem, checked) {
this[checked ? 'enable' : 'disable']();
},
pruneGroupedHeader: function() {
var me = this,
header = me.getGroupedHeader();
if (me.hideGroupedHeader && header) {
Ext.suspendLayouts();
if (me.prunedHeader && me.prunedHeader !== header) {
me.prunedHeader.show();
}
me.prunedHeader = header;
if (header.rendered) {
header.hide();
}
Ext.resumeLayouts(true);
}
},
getHeaderNode: function(groupName) {
var el = this.view.getEl(),
nodes, i, len, node;
if (el) {
groupName = Ext.htmlEncode(groupName);
nodes = el.query(this.eventSelector);
for (i = 0 , len = nodes.length; i < len; ++i) {
node = nodes[i];
if (node.getAttribute('data-groupName') === groupName) {
return node;
}
}
}
},
getGroup: function(name) {
var store = this.getGridStore(),
value = name,
group;
if (store.isGrouped()) {
if (name.isModel) {
name = name.get(store.getGroupField());
}
if (typeof name !== 'string') {
name = store.getGrouper().getGroupString(value);
}
group = store.getGroups().getByKey(name);
}
return group;
},
getGrouper: function(dataIndex) {
var groupers = this.groupers;
if (!groupers) {
return null;
}
return Ext.Array.findBy(groupers, function(grouper) {
return grouper.property === dataIndex;
});
},
getGroupField: function() {
return this.getGridStore().getGroupField();
},
getMetaGroup: function(group) {
var metaGroupCache = this.metaGroupCache || this.createCache(),
key, metaGroup;
if (group.isModel) {
group = this.getGroup(group);
}
if (group) {
key = (typeof group === 'string') ? group : group.getGroupKey();
metaGroup = metaGroupCache[key];
if (!metaGroup) {
metaGroup = metaGroupCache[key] = {
isCollapsed: false,
lastGroup: null,
lastGroupGeneration: null,
lastFilterGeneration: null,
aggregateRecord: new Ext.data.Model()
};
if (!metaGroupCache.map) {
metaGroupCache.map = {};
}
metaGroupCache.map[key] = true;
}
}
return metaGroup;
},
isExpanded: function(groupName) {
return !this.getMetaGroup(groupName).isCollapsed;
},
expand: function(groupName, focus) {
this.doCollapseExpand(false, groupName, focus);
},
expandAll: function() {
var me = this,
metaGroupCache = me.getCache(),
lockingPartner = me.lockingPartner,
groupName;
for (groupName in metaGroupCache) {
if (metaGroupCache.hasOwnProperty(groupName)) {
metaGroupCache[groupName].isCollapsed = false;
}
}
Ext.suspendLayouts();
me.dataSource.onRefresh();
Ext.resumeLayouts(true);
for (groupName in metaGroupCache) {
if (metaGroupCache.hasOwnProperty(groupName)) {
me.afterCollapseExpand(false, groupName);
if (lockingPartner) {
lockingPartner.afterCollapseExpand(false, groupName);
}
}
}
},
collapse: function(groupName, focus) {
this.doCollapseExpand(true, groupName, focus);
},
isAllCollapsed: function() {
var me = this,
metaGroupCache = me.getCache(),
groupName;
for (groupName in metaGroupCache) {
if (metaGroupCache.hasOwnProperty(groupName)) {
if (!metaGroupCache[groupName].isCollapsed) {
return false;
}
}
}
return true;
},
isAllExpanded: function() {
var me = this,
metaGroupCache = me.getCache(),
groupName;
for (groupName in metaGroupCache) {
if (metaGroupCache.hasOwnProperty(groupName)) {
if (metaGroupCache[groupName].isCollapsed) {
return false;
}
}
}
return true;
},
collapseAll: function() {
var me = this,
metaGroupCache = me.getCache(),
groupName,
lockingPartner = me.lockingPartner;
for (groupName in metaGroupCache) {
if (metaGroupCache.hasOwnProperty(groupName)) {
metaGroupCache[groupName].isCollapsed = true;
}
}
Ext.suspendLayouts();
me.dataSource.onRefresh();
if (lockingPartner && !lockingPartner.isAllCollapsed()) {
lockingPartner.collapseAll();
}
Ext.resumeLayouts(true);
for (groupName in metaGroupCache) {
if (metaGroupCache.hasOwnProperty(groupName)) {
me.afterCollapseExpand(true, groupName);
if (lockingPartner) {
lockingPartner.afterCollapseExpand(true, groupName);
}
}
}
},
doCollapseExpand: function(collapsed, groupName, focus) {
var me = this,
lockingPartner = me.lockingPartner,
group = me.getGroup(groupName);
if (me.getMetaGroup(group).isCollapsed !== collapsed) {
Ext.suspendLayouts();
if (collapsed) {
me.dataSource.collapseGroup(group);
} else {
me.dataSource.expandGroup(group);
}
Ext.resumeLayouts(true);
me.afterCollapseExpand(collapsed, groupName, focus);
if (lockingPartner) {
lockingPartner.afterCollapseExpand(collapsed, groupName, false);
}
}
},
afterCollapseExpand: function(collapsed, groupName, focus) {
var me = this,
view = me.view,
bufferedRenderer = view.bufferedRenderer,
header;
header = me.getHeaderNode(groupName);
view.fireEvent(collapsed ? 'groupcollapse' : 'groupexpand', view, header, groupName);
if (focus) {
if (header) {
view.scrollElIntoView(Ext.fly(header).up(view.getItemSelector()), false, true);
}
else if (bufferedRenderer) {
bufferedRenderer.scrollTo(me.getGroup(groupName).getAt(0));
}
}
},
onGroupChange: function(store, grouper) {
if (!grouper) {
this.view.ownerGrid.getView().refresh();
} else {
this.lastGrouper = grouper;
}
},
getMenuItem: function(dataIndex) {
var view = this.view,
header = view.headerCt.down('gridcolumn[dataIndex=' + dataIndex + ']'),
menu = view.headerCt.getMenu();
return header ? menu.down('menuitem[headerId=' + header.id + ']') : null;
},
onGroupKey: function(keyCode, event) {
var me = this,
groupName = me.getGroupName(event.target);
if (groupName) {
me.onGroupClick(me.view, event.target, groupName, event);
}
},
onGroupClick: function(view, rowElement, groupName, e) {
var me = this,
metaGroupCache = me.getCache(),
groupNames = metaGroupCache.map,
groupIsCollapsed = !me.isExpanded(groupName),
g;
if (me.collapsible) {
if (e.ctrlKey) {
Ext.suspendLayouts();
for (g in groupNames) {
if (g === groupName) {
if (groupIsCollapsed) {
me.expand(groupName);
}
} else if (!metaGroupCache[g].isCollapsed) {
me.doCollapseExpand(true, g, false);
}
}
Ext.resumeLayouts(true);
return;
}
if (groupIsCollapsed) {
me.expand(groupName);
} else {
me.collapse(groupName);
}
}
},
setupRowData: function(record, idx, rowValues) {
var me = this,
recordIndex = rowValues.recordIndex,
data = me.refreshData,
metaGroupCache = me.getCache(),
header = data.header,
groupField = data.groupField,
store = me.getGridStore(),
dataSource = me.view.dataSource,
column = me.grid.columnManager.getHeaderByDataIndex(groupField),
hasRenderer = !!(column && column.renderer),
grouper, groupName, prev, next, items;
rowValues.isCollapsedGroup = false;
rowValues.summaryRecord = rowValues.groupHeaderCls = null;
if (data.doGrouping) {
grouper = store.getGrouper();
if (record.isCollapsedPlaceholder) {
groupName = record.group.getGroupKey();
items = record.group.items;
rowValues.isFirstRow = rowValues.isLastRow = true;
rowValues.groupHeaderCls = me.hdCollapsedCls;
rowValues.isCollapsedGroup = rowValues.needsWrap = true;
rowValues.groupName = groupName;
rowValues.metaGroupCache = metaGroupCache;
metaGroupCache.groupField = groupField;
metaGroupCache.name = metaGroupCache.renderedGroupValue = hasRenderer ? column.renderer(metaGroupCache[groupName].raw, {}, record) : groupName;
metaGroupCache.groupValue = items[0].get(groupField);
metaGroupCache.columnName = header ? header.text : groupField;
rowValues.collapsibleCls = me.collapsible ? me.collapsibleCls : me.hdNotCollapsibleCls;
metaGroupCache.rows = metaGroupCache.children = items;
if (me.showSummaryRow) {
rowValues.summaryRecord = data.summaryData[groupName];
}
return;
}
groupName = grouper.getGroupString(record);
if (record.group) {
items = record.group.items;
rowValues.isFirstRow = record === items[0];
rowValues.isLastRow = record === items[items.length - 1];
} else {
rowValues.isFirstRow = recordIndex === 0;
if (!rowValues.isFirstRow) {
prev = store.getAt(recordIndex - 1);
if (prev) {
rowValues.isFirstRow = !prev.isEqual(grouper.getGroupString(prev), groupName);
}
}
rowValues.isLastRow = recordIndex === (store.isBufferedStore ? store.getTotalCount() : store.getCount()) - 1;
if (!rowValues.isLastRow) {
next = store.getAt(recordIndex + 1);
if (next) {
rowValues.isLastRow = !next.isEqual(grouper.getGroupString(next), groupName);
}
}
}
if (rowValues.isFirstRow) {
metaGroupCache.groupField = groupField;
metaGroupCache.name = metaGroupCache.renderedGroupValue = hasRenderer ? column.renderer(metaGroupCache[groupName].raw, {}, record) : groupName;
metaGroupCache.groupValue = record.get(groupField);
metaGroupCache.columnName = header ? header.text : groupField;
rowValues.collapsibleCls = me.collapsible ? me.collapsibleCls : me.hdNotCollapsibleCls;
rowValues.groupName = groupName;
if (!me.isExpanded(groupName)) {
rowValues.itemClasses.push(me.hdCollapsedCls);
rowValues.isCollapsedGroup = true;
}
if (dataSource.isBufferedStore) {
metaGroupCache.rows = metaGroupCache.children = [];
} else {
metaGroupCache.rows = metaGroupCache.children = me.getRecordGroup(record).items;
}
rowValues.metaGroupCache = metaGroupCache;
}
if (rowValues.isLastRow) {
if (me.showSummaryRow) {
rowValues.summaryRecord = data.summaryData[groupName];
rowValues.itemClasses.push(Ext.baseCSSPrefix + 'grid-group-last');
}
}
rowValues.needsWrap = (rowValues.isFirstRow || rowValues.summaryRecord);
}
},
setup: function(rows, rowValues) {
var me = this,
data = me.refreshData,
view = rowValues.view,
isGrouping = view.isGrouping = !me.disabled && me.getGridStore().isGrouped(),
bufferedRenderer = view.bufferedRenderer;
me.skippedRows = 0;
if (bufferedRenderer) {
bufferedRenderer.variableRowHeight = view.bufferedRenderer.variableRowHeight || isGrouping;
}
data.groupField = me.getGroupField();
data.header = me.getGroupedHeader(data.groupField);
data.doGrouping = isGrouping;
rowValues.groupHeaderTpl = Ext.XTemplate.getTpl(me, 'groupHeaderTpl');
if (isGrouping && me.showSummaryRow) {
data.summaryData = me.generateSummaryData();
}
},
cleanup: function(rows, rowValues) {
var data = this.refreshData;
rowValues.metaGroupCache = rowValues.groupHeaderTpl = rowValues.isFirstRow = null;
data.groupField = data.header = null;
},
getAggregateRecord: function(metaGroup, forceNew) {
var rec;
if (forceNew === true || !metaGroup.aggregateRecord) {
rec = new Ext.data.Model();
metaGroup.aggregateRecord = rec;
rec.isNonData = rec.isSummary = true;
}
return metaGroup.aggregateRecord;
},
generateSummaryData: function() {
var me = this,
store = me.getGridStore(),
filters = store.getFilters(),
groups = store.getGroups().items,
reader = store.getProxy().getReader(),
groupField = me.getGroupField(),
lockingPartner = me.lockingPartner,
updateNext = me.updateNext,
data = {},
ownerCt = me.view.ownerCt,
i, len, group, metaGroup, record, hasRemote, remoteData;
if (me.remoteRoot && reader.rawData) {
hasRemote = true;
remoteData = me.mixins.summary.generateSummaryData.call(me, groupField);
}
for (i = 0 , len = groups.length; i < len; ++i) {
group = groups[i];
metaGroup = me.getMetaGroup(group);
if (updateNext || hasRemote || store.updating || me.didGroupChange(group, metaGroup, filters)) {
record = me.populateRecord(group, metaGroup, remoteData);
if (!lockingPartner || (ownerCt === ownerCt.ownerLockable.normalGrid)) {
metaGroup.lastGroup = group;
metaGroup.lastGroupGeneration = group.generation;
metaGroup.lastFilterGeneration = filters.generation;
}
} else {
record = me.getAggregateRecord(metaGroup);
}
data[group.getGroupKey()] = record;
}
me.updateNext = false;
return data;
},
getGroupName: function(element) {
var me = this,
view = me.view,
eventSelector = me.eventSelector,
targetEl, row;
targetEl = Ext.fly(element).findParent(eventSelector);
if (!targetEl) {
row = Ext.fly(element).findParent(view.itemSelector);
if (row) {
targetEl = row.down(eventSelector, true);
}
}
if (targetEl) {
return Ext.htmlDecode(targetEl.getAttribute('data-groupname'));
}
},
getRecordGroup: function(record) {
var store = this.getGridStore(),
grouper = store.getGrouper();
if (grouper) {
return store.getGroups().getByKey(grouper.getGroupString(record));
}
},
getGroupedHeader: function(groupField) {
var me = this,
headerCt = me.view.headerCt,
partner = me.lockingPartner,
selector, header;
groupField = groupField || me.getGroupField();
if (groupField) {
selector = '[dataIndex=' + groupField + ']';
header = headerCt.down(selector);
if (!header && partner) {
header = partner.view.headerCt.down(selector);
}
}
return header || null;
},
getFireEventArgs: function(type, view, targetEl, e) {
return [
type,
view,
targetEl,
this.getGroupName(targetEl),
e
];
},
destroy: function() {
var me = this,
dataSource = me.dataSource;
me.storeListeners = Ext.destroy(me.storeListeners);
me.view = me.prunedHeader = me.grid = me.dataSource = me.groupers = null;
me.invalidateCache();
me.callParent();
if (dataSource) {
dataSource.bindStore(null);
Ext.destroy(dataSource);
}
},
beforeReconfigure: function(grid, store, columns, oldStore, oldColumns) {
var me = this,
view = me.view,
dataSource = me.dataSource,
bufferedStore;
if (store && store !== oldStore) {
bufferedStore = store.isBufferedStore;
if (!dataSource) {
Ext.destroy(me.storeListeners);
me.setupStoreListeners(store);
}
if (bufferedStore !== oldStore.isBufferedStore) {
Ext.Error.raise('Cannot reconfigure grouping switching between buffered and non-buffered stores');
}
view.isGrouping = !!store.getGrouper();
dataSource.bindStore(store);
}
},
populateRecord: function(group, metaGroup, remoteData) {
var me = this,
view = me.grid.ownerLockable ? me.grid.ownerLockable.view : me.view,
store = me.getGridStore(),
record = me.getAggregateRecord(metaGroup),
columns = view.headerCt.getGridColumns(),
len = columns.length,
groupName = group.getGroupKey(),
groupData, field, i, column, fieldName, summaryValue;
record.beginEdit();
if (remoteData) {
groupData = remoteData[groupName];
for (field in groupData) {
if (groupData.hasOwnProperty(field)) {
if (field !== record.idProperty) {
record.set(field, groupData[field]);
}
}
}
}
for (i = 0; i < len; ++i) {
column = columns[i];
fieldName = column.dataIndex || column.getItemId();
if (!remoteData) {
summaryValue = me.getSummary(store, column.summaryType, fieldName, group);
record.set(fieldName, summaryValue);
} else {
summaryValue = record.get(column.dataIndex);
}
me.setSummaryData(record, column.getItemId(), summaryValue, groupName);
}
record.ownerGroup = groupName;
record.endEdit(true);
record.commit();
return record;
},
privates: {
didGroupChange: function(group, metaGroup, filters) {
var ret = true;
if (group === metaGroup.lastGroup) {
ret = metaGroup.lastGroupGeneration !== group.generation || metaGroup.lastFilterGeneration !== filters.generation;
}
return ret;
},
setupStoreListeners: function(store) {
var me = this;
me.storeListeners = store.on({
groupchange: me.onGroupChange,
scope: me,
destroyable: true
});
}
}
});
Ext.define('Ext.grid.feature.GroupingSummary', {
extend: 'Ext.grid.feature.Grouping',
alias: 'feature.groupingsummary',
showSummaryRow: true,
vetoEvent: function(record, row, rowIndex, e) {
var result = this.callParent(arguments);
if (result !== false && e.getTarget(this.summaryRowSelector)) {
result = false;
}
return result;
}
});
Ext.define('Ext.grid.feature.RowBody', {
extend: 'Ext.grid.feature.Feature',
alias: 'feature.rowbody',
rowBodyCls: Ext.baseCSSPrefix + 'grid-row-body',
rowBodyHiddenCls: Ext.baseCSSPrefix + 'grid-row-body-hidden',
rowBodyTdSelector: 'td.' + Ext.baseCSSPrefix + 'grid-cell-rowbody',
eventPrefix: 'rowbody',
eventSelector: 'tr.' + Ext.baseCSSPrefix + 'grid-rowbody-tr',
colSpanDecrement: 0,
bodyBefore: false,
outerTpl: {
fn: function(out, values, parent) {
var view = values.view,
rowValues = view.rowValues;
this.rowBody.setup(values.rows, rowValues);
this.nextTpl.applyOut(values, out, parent);
this.rowBody.cleanup(values.rows, rowValues);
},
priority: 100
},
extraRowTpl: [
'{%',
'if(this.rowBody.bodyBefore) {',
'values.view.renderColumnSizer(values, out);',
'} else {',
'this.nextTpl.applyOut(values, out, parent);',
'}',
'values.view.rowBodyFeature.setupRowData(values.record, values.recordIndex, values);',
'%}',
'<tr class="' + Ext.baseCSSPrefix + 'grid-rowbody-tr {rowBodyCls}" {ariaRowAttr}>',
'<td class="' + Ext.baseCSSPrefix + 'grid-td ' + Ext.baseCSSPrefix + 'grid-cell-rowbody" colspan="{rowBodyColspan}" {ariaCellAttr}>',
'<div class="' + Ext.baseCSSPrefix + 'grid-rowbody {rowBodyDivCls}" {ariaCellInnerAttr}>{rowBody}</div>',
'</td>',
'</tr>',
'{%',
'if(this.rowBody.bodyBefore) {',
'this.nextTpl.applyOut(values, out, parent);',
'}',
'%}',
{
priority: 100,
beginRowSync: function(rowSync) {
rowSync.add('rowBody', this.owner.eventSelector);
},
syncContent: function(destRow, sourceRow, columnsToUpdate) {
var owner = this.owner,
destRowBody = Ext.fly(destRow).down(owner.eventSelector, true),
sourceRowBody;
if (destRowBody && (sourceRowBody = Ext.fly(sourceRow).down(owner.eventSelector, true))) {
Ext.fly(destRowBody).syncContent(sourceRowBody);
}
}
}
],
init: function(grid) {
var me = this,
view = me.view = grid.getView();
grid.variableRowHeight = view.variableRowHeight = true;
view.rowBodyFeature = me;
grid.mon(view, {
element: 'el',
click: me.onClick,
scope: me
});
view.headerCt.on({
columnschanged: me.onColumnsChanged,
scope: me
});
view.addTpl(me.outerTpl).rowBody = me;
view.addRowTpl(Ext.XTemplate.getTpl(this, 'extraRowTpl')).rowBody = me;
me.callParent(arguments);
},
onClick: function(e) {
var me = this,
tableRow = e.getTarget(me.eventSelector);
if (tableRow && Ext.fly(tableRow = (tableRow.previousSibling || tableRow.nextSibling)).is(me.view.rowSelector)) {
e.target = tableRow;
me.view.handleEvent(e);
}
},
getSelectedRow: function(view, rowIndex) {
var selectedRow = view.getNode(rowIndex);
if (selectedRow) {
return Ext.fly(selectedRow).down(this.eventSelector);
}
return null;
},
onColumnsChanged: function(headerCt) {
var items = this.view.el.query(this.rowBodyTdSelector),
colspan = headerCt.getVisibleGridColumns().length,
len = items.length,
i;
for (i = 0; i < len; ++i) {
items[i].setAttribute('colSpan', colspan);
}
},
setupRowData: function(record, rowIndex, rowValues) {
if (this.getAdditionalData) {
Ext.apply(rowValues, this.getAdditionalData(record.data, rowIndex, record, rowValues));
}
},
setup: function(rows, rowValues) {
rowValues.rowBodyCls = this.rowBodyCls;
rowValues.rowBodyColspan = this.view.headerCt.visibleColumnManager.getColumns().length - this.colSpanDecrement;
},
cleanup: function(rows, rowValues) {
rowValues.rowBodyCls = rowValues.rowBodyColspan = rowValues.rowBody = null;
}
});
Ext.define('Ext.grid.feature.Summary', {
extend: 'Ext.grid.feature.AbstractSummary',
alias: 'feature.summary',
dock: undefined,
dockedSummaryCls: Ext.baseCSSPrefix + 'docked-summary',
panelBodyCls: Ext.baseCSSPrefix + 'summary-',
hasFeatureEvent: false,
fullSummaryTpl: [
'{%',
'var me = this.summaryFeature,',
' record = me.summaryRecord,',
' view = values.view,',
' bufferedRenderer = view.bufferedRenderer;',
'this.nextTpl.applyOut(values, out, parent);',
'if (!me.disabled && me.showSummaryRow && view.store.isLast(values.record)) {',
'if (bufferedRenderer) {',
' bufferedRenderer.variableRowHeight = true;',
'}',
'me.outputSummaryRecord((record && record.isModel) ? record : me.createSummaryRecord(view), values, out, parent);',
'}',
'%}',
{
priority: 300,
beginRowSync: function(rowSync) {
rowSync.add('fullSummary', this.summaryRowSelector);
},
syncContent: function(destRow, sourceRow, columnsToUpdate) {
destRow = Ext.fly(destRow, 'syncDest');
sourceRow = Ext.fly(sourceRow, 'sycSrc');
var owner = this.owner,
selector = owner.summaryRowSelector,
destSummaryRow = destRow.down(selector, true),
sourceSummaryRow = sourceRow.down(selector, true);
if (destSummaryRow && sourceSummaryRow) {
if (columnsToUpdate) {
this.summaryFeature.view.updateColumns(destSummaryRow, sourceSummaryRow, columnsToUpdate);
} else
{
Ext.fly(destSummaryRow).syncContent(sourceSummaryRow);
}
}
}
}
],
init: function(grid) {
var me = this,
view = me.view,
dock = me.dock;
me.callParent(arguments);
if (dock) {
grid.headerCt.on({
add: me.onStoreUpdate,
afterlayout: me.onStoreUpdate,
scope: me
});
grid.on({
beforerender: function() {
var tableCls = [
me.summaryTableCls
];
if (view.columnLines) {
tableCls[tableCls.length] = view.ownerCt.colLinesCls;
}
me.summaryBar = grid.addDocked({
childEls: [
'innerCt',
'item'
],
renderTpl: [
'<div id="{id}-innerCt" data-ref="innerCt" role="presentation">',
'<table id="{id}-item" data-ref="item" cellPadding="0" cellSpacing="0" class="' + tableCls.join(' ') + '">',
'<tr class="' + me.summaryRowCls + '"></tr>',
'</table>',
'</div>'
],
scrollable: {
x: false,
y: false
},
hidden: !me.showSummaryRow,
itemId: 'summaryBar',
cls: [
me.dockedSummaryCls,
me.dockedSummaryCls + '-' + dock
],
xtype: 'component',
dock: dock,
weight: 10000000
})[0];
},
afterrender: function() {
grid.body.addCls(me.panelBodyCls + dock);
view.on('scroll', me.onViewScroll, me);
me.onStoreUpdate();
},
single: true
});
grid.headerCt.afterComponentLayout = Ext.Function.createSequence(grid.headerCt.afterComponentLayout, function() {
var width = this.getTableWidth(),
innerCt = me.summaryBar.innerCt;
me.summaryBar.item.setWidth(width);
if (this.tooNarrow) {
width += Ext.getScrollbarSize().width;
}
innerCt.setWidth(width);
});
} else {
if (grid.bufferedRenderer) {
me.wrapsItem = true;
view.addRowTpl(Ext.XTemplate.getTpl(me, 'fullSummaryTpl')).summaryFeature = me;
view.on('refresh', me.onViewRefresh, me);
} else {
me.wrapsItem = false;
me.view.addFooterFn(me.renderSummaryRow);
}
}
grid.on({
beforereconfigure: me.onBeforeReconfigure,
columnmove: me.onStoreUpdate,
scope: me
});
me.bindStore(grid, grid.getStore());
},
onBeforeReconfigure: function(grid, store) {
this.summaryRecord = null;
if (store) {
this.bindStore(grid, store);
}
},
bindStore: function(grid, store) {
var me = this;
Ext.destroy(me.storeListeners);
me.storeListeners = store.on({
scope: me,
destroyable: true,
update: me.onStoreUpdate,
datachanged: me.onStoreUpdate
});
},
renderSummaryRow: function(values, out, parent) {
var view = values.view,
me = view.findFeature('summary'),
record, rows;
if (!me.disabled && me.showSummaryRow) {
record = me.summaryRecord;
out.push('<table cellpadding="0" cellspacing="0" class="' + me.summaryItemCls + '" style="table-layout: fixed; width: 100%;">');
me.outputSummaryRecord((record && record.isModel) ? record : me.createSummaryRecord(view), values, out, parent);
out.push('</table>');
}
},
toggleSummaryRow: function(visible,
fromLockingPartner) {
var me = this,
bar = me.summaryBar;
me.callParent([
visible,
fromLockingPartner
]);
if (bar) {
bar.setVisible(me.showSummaryRow);
me.onViewScroll();
}
},
getSummaryBar: function() {
return this.summaryBar;
},
vetoEvent: function(record, row, rowIndex, e) {
return !e.getTarget(this.summaryRowSelector);
},
onViewScroll: function() {
this.summaryBar.setScrollX(this.view.getScrollX());
},
onViewRefresh: function(view) {
var me = this,
record, row;
if (!me.disabled && me.showSummaryRow && !view.all.getCount()) {
record = me.createSummaryRecord(view);
row = Ext.fly(view.getNodeContainer()).createChild({
tag: 'table',
cellpadding: 0,
cellspacing: 0,
cls: me.summaryItemCls,
style: 'table-layout: fixed; width: 100%'
}, false, true);
row.appendChild(Ext.fly(view.createRowElement(record, -1)).down(me.summaryRowSelector, true));
}
},
createSummaryRecord: function(view) {
var me = this,
columns = view.headerCt.getVisibleGridColumns(),
remoteRoot = me.remoteRoot,
summaryRecord = me.summaryRecord,
colCount = columns.length,
i, column, dataIndex, summaryValue, modelData;
if (!summaryRecord) {
modelData = {
id: view.id + '-summary-record'
};
summaryRecord = me.summaryRecord = new Ext.data.Model(modelData);
}
summaryRecord.beginEdit();
if (remoteRoot && view.store.proxy.reader.rawData) {
summaryRecord.set(me.generateSummaryData());
} else if (!remoteRoot) {
for (i = 0; i < colCount; i++) {
column = columns[i];
dataIndex = column.dataIndex || column.getItemId();
summaryValue = me.getSummary(view.store, column.summaryType, dataIndex);
summaryRecord.set(dataIndex, summaryValue);
me.setSummaryData(summaryRecord, column.getItemId(), summaryValue);
}
}
summaryRecord.endEdit(true);
summaryRecord.commit(true);
summaryRecord.isSummary = true;
return summaryRecord;
},
onStoreUpdate: function() {
var me = this,
view = me.view,
selector = me.summaryRowSelector,
dock = me.dock,
record, newRowDom, oldRowDom, p;
if (!view.rendered) {
return;
}
record = me.createSummaryRecord(view);
newRowDom = Ext.fly(view.createRowElement(record, -1)).down(selector, true);
if (!newRowDom) {
return;
}
if (dock) {
p = me.summaryBar.item.dom.firstChild;
oldRowDom = p.firstChild;
} else
{
oldRowDom = me.view.el.down(selector, true);
p = oldRowDom ? oldRowDom.parentNode : null;
}
if (p) {
p.insertBefore(newRowDom, oldRowDom);
p.removeChild(oldRowDom);
}
if (dock) {
me.onColumnHeaderLayout();
}
},
onColumnHeaderLayout: function() {
var view = this.view,
columns = view.headerCt.getVisibleGridColumns(),
column,
len = columns.length,
i,
summaryEl = this.summaryBar.el,
el;
for (i = 0; i < len; i++) {
column = columns[i];
el = summaryEl.down(view.getCellSelector(column), true);
if (el) {
Ext.fly(el).setWidth(column.width || (column.lastBox ? column.lastBox.width : 100));
}
}
},
destroy: function() {
var me = this;
me.summaryRecord = me.storeListeners = Ext.destroy(me.storeListeners);
me.callParent();
}
});
Ext.define('Ext.menu.Item', {
extend: 'Ext.Component',
alias: 'widget.menuitem',
alternateClassName: 'Ext.menu.TextItem',
isMenuItem: true,
mixins: [
'Ext.mixin.Queryable'
],
activated: false,
activeCls: Ext.baseCSSPrefix + 'menu-item-active',
ariaRole: 'menuitem',
clickHideDelay: 0,
destroyMenu: true,
disabledCls: Ext.baseCSSPrefix + 'menu-item-disabled',
hideOnClick: true,
menuAlign: 'tl-tr?',
menuExpandDelay: 200,
menuHideDelay: 200,
tooltipType: 'qtip',
focusable: true,
baseCls: Ext.baseCSSPrefix + 'menu-item',
arrowCls: Ext.baseCSSPrefix + 'menu-item-arrow',
baseIconCls: Ext.baseCSSPrefix + 'menu-item-icon',
textCls: Ext.baseCSSPrefix + 'menu-item-text',
indentCls: Ext.baseCSSPrefix + 'menu-item-indent',
indentNoSeparatorCls: Ext.baseCSSPrefix + 'menu-item-indent-no-separator',
indentRightIconCls: Ext.baseCSSPrefix + 'menu-item-indent-right-icon',
indentRightArrowCls: Ext.baseCSSPrefix + 'menu-item-indent-right-arrow',
linkCls: Ext.baseCSSPrefix + 'menu-item-link',
linkHrefCls: Ext.baseCSSPrefix + 'menu-item-link-href',
childEls: [
'itemEl',
'iconEl',
'textEl',
'arrowEl'
],
renderTpl: '<tpl if="plain">' + '{text}' + '<tpl else>' + '<a id="{id}-itemEl" data-ref="itemEl"' + ' class="{linkCls}<tpl if="hasHref"> {linkHrefCls}</tpl>{childElCls}"' + ' href="{href}" role="menuitem" ' + '<tpl if="hrefTarget"> target="{hrefTarget}"</tpl>' + ' hidefocus="true"' +
' unselectable="on"' + '<tpl if="tabIndex != null">' + ' tabindex="{tabIndex}"' + '</tpl>' + '>' + '<span id="{id}-textEl" data-ref="textEl" class="{textCls} {textCls}-{ui} {indentCls}{childElCls}" unselectable="on">{text}</span>' + '<tpl if="hasIcon">' + '<div role="presentation" id="{id}-iconEl" data-ref="iconEl" class="{baseIconCls}-{ui} {baseIconCls}' + '{[values.rightIcon ? "-right" : ""]} {iconCls}' + '{childElCls} {glyphCls}" style="<tpl if="icon">background-image:url({icon});</tpl>' + '<tpl if="glyph && glyphFontFamily">font-family:{glyphFontFamily};</tpl>">' + '<tpl if="glyph">&#{glyph};</tpl>' + '</div>' + '</tpl>' + '<tpl if="showCheckbox">' + '<div role="presentation" id="{id}-checkEl" data-ref="checkEl" class="{baseIconCls}-{ui} {baseIconCls}' + '{[(values.hasIcon && !values.rightIcon) ? "-right" : ""]} ' + '{groupCls} {checkboxCls}{childElCls}">' + '</div>' + '</tpl>' + '<tpl if="hasMenu">' + '<div role="presentation" id="{id}-arrowEl" data-ref="arrowEl" class="{arrowCls} {arrowCls}-{ui}{childElCls}"></div>' + '</tpl>' + '</a>' + '</tpl>',
maskOnDisable: false,
iconAlign: 'left',
canFocus: function() {
var me = this;
return me.focusable && me.rendered && me.canActivate !== false && !me.destroying && !me.isDestroyed && me.isVisible(true);
},
onFocus: function(e) {
var me = this;
me.callParent([
e
]);
if (!me.disabled) {
if (!me.plain) {
me.addCls(me.activeCls);
}
me.activated = true;
if (me.hasListeners.activate) {
me.fireEvent('activate', me);
}
}
},
onFocusLeave: function(e) {
var me = this;
me.callParent([
e
]);
if (me.activated) {
if (!me.plain) {
me.removeCls(me.activeCls);
}
me.doHideMenu();
me.activated = false;
if (me.hasListeners.deactivate) {
me.fireEvent('deactivate', me);
}
}
},
doHideMenu: function() {
var menu = this.menu;
this.cancelDeferExpand();
if (menu && menu.isVisible()) {
menu.hide();
}
},
deferHideParentMenus: function() {
var topMenu = this.getRefOwner();
if (topMenu.floating) {
topMenu.bubble(function(parent) {
if (!parent.floating && !parent.isMenuItem) {
return false;
}
if (parent.isMenu) {
topMenu = parent;
}
});
topMenu.hide();
}
},
expandMenu: function(event, delay) {
var me = this;
if (me.activated && me.menu) {
me.hideOnClick = false;
me.cancelDeferHide();
delay = delay == null ? me.menuExpandDelay : delay;
if (delay === 0) {
me.doExpandMenu(event);
} else {
me.cancelDeferExpand();
me.expandMenuTimer = Ext.defer(me.doExpandMenu, delay, me, [
event
]);
}
}
},
doExpandMenu: function(clickEvent) {
var me = this,
menu = me.menu;
if (!menu.isVisible()) {
me.parentMenu.activeChild = menu;
menu.ownerCmp = me;
menu.parentMenu = me.parentMenu;
menu.constrainTo = document.body;
menu.autoFocus = !clickEvent || !clickEvent.pointerType;
menu.showBy(me, me.menuAlign);
}
},
getRefItems: function(deep) {
var menu = this.menu,
items;
if (menu) {
items = menu.getRefItems(deep);
items.unshift(menu);
}
return items || [];
},
getValue: function() {
return this.value;
},
hideMenu: function(delay) {
var me = this;
if (me.menu) {
me.cancelDeferExpand();
me.hideMenuTimer = Ext.defer(me.doHideMenu, Ext.isNumber(delay) ? delay : me.menuHideDelay, me);
}
},
initComponent: function() {
var me = this,
cls = me.cls ? [
me.cls
] : [],
menu;
if (me.hasOwnProperty('canActivate')) {
me.focusable = me.canActivate;
}
if (me.plain) {
cls.push(Ext.baseCSSPrefix + 'menu-item-plain');
}
if (cls.length) {
me.cls = cls.join(' ');
}
if (me.menu) {
menu = me.menu;
me.menu = null;
me.setMenu(menu);
}
me.callParent(arguments);
},
onClick: function(e) {
var me = this,
clickHideDelay = me.clickHideDelay,
browserEvent = e.browserEvent,
clickResult, preventDefault;
if (!me.href || me.disabled) {
e.stopEvent();
if (me.disabled) {
return false;
}
}
if (me.disabled || me.handlingClick) {
return;
}
if (me.hideOnClick) {
if (!clickHideDelay) {
me.deferHideParentMenus();
} else {
me.deferHideParentMenusTimer = Ext.defer(me.deferHideParentMenus, clickHideDelay, me);
}
}
clickResult = me.fireEvent('click', me, e);
if (me.isDestroyed) {
return;
}
if (clickResult !== false && me.handler) {
Ext.callback(me.handler, me.scope, [
me,
e
], 0, me);
}
if (Ext.isIE9m) {
preventDefault = browserEvent.returnValue === false ? true : false;
} else {
preventDefault = !!browserEvent.defaultPrevented;
}
if (me.href && e.type !== 'click' && !preventDefault) {
me.handlingClick = true;
me.itemEl.dom.click();
me.handlingClick = false;
}
if (!me.hideOnClick) {
me.focus();
}
return clickResult;
},
onRemoved: function() {
var me = this;
if (me.activated && me.parentMenu.activeItem === me) {
me.parentMenu.deactivateActiveItem();
}
me.callParent(arguments);
me.parentMenu = me.ownerCmp = null;
},
beforeDestroy: function() {
var me = this;
if (me.rendered) {
me.clearTip();
}
me.callParent();
},
onDestroy: function() {
var me = this;
me.cancelDeferExpand();
me.cancelDeferHide();
clearTimeout(me.deferHideParentMenusTimer);
me.setMenu(null);
me.callParent(arguments);
},
beforeRender: function() {
var me = this,
glyph = me.glyph,
glyphFontFamily = Ext._glyphFontFamily,
hasIcon = !!(me.icon || me.iconCls || glyph),
hasMenu = !!me.menu,
rightIcon = ((me.iconAlign === 'right') && !hasMenu),
isCheckItem = me.isMenuCheckItem,
indentCls = [],
ownerCt = me.ownerCt,
isOwnerPlain = ownerCt.plain,
glyphParts;
me.callParent();
if (hasIcon) {
if (hasMenu && me.showCheckbox) {
hasIcon = false;
}
}
if (typeof glyph === 'string') {
glyphParts = glyph.split('@');
glyph = glyphParts[0];
glyphFontFamily = glyphParts[1];
}
if (!isOwnerPlain || (hasIcon && !rightIcon) || isCheckItem) {
if (ownerCt.showSeparator && !isOwnerPlain) {
indentCls.push(me.indentCls);
} else {
indentCls.push(me.indentNoSeparatorCls);
}
}
if (hasMenu) {
indentCls.push(me.indentRightArrowCls);
} else if (hasIcon && (rightIcon || isCheckItem)) {
indentCls.push(me.indentRightIconCls);
}
Ext.applyIf(me.renderData, {
hasHref: !!me.href,
href: me.href || '#',
hrefTarget: me.hrefTarget,
icon: me.icon,
iconCls: me.iconCls,
glyph: glyph,
glyphCls: glyph ? Ext.baseCSSPrefix + 'menu-item-glyph' : undefined,
glyphFontFamily: glyphFontFamily,
hasIcon: hasIcon,
hasMenu: hasMenu,
indent: !isOwnerPlain || hasIcon || isCheckItem,
isCheckItem: isCheckItem,
rightIcon: rightIcon,
plain: me.plain,
text: me.text,
arrowCls: me.arrowCls,
baseIconCls: me.baseIconCls,
textCls: me.textCls,
indentCls: indentCls.join(' '),
linkCls: me.linkCls,
linkHrefCls: me.linkHrefCls,
groupCls: me.group ? me.groupCls : '',
tabIndex: me.tabIndex
});
},
onRender: function() {
var me = this;
me.callParent(arguments);
if (me.tooltip) {
me.setTooltip(me.tooltip, true);
}
},
getMenu: function() {
return this.menu || null;
},
setMenu: function(menu, destroyMenu) {
var me = this,
oldMenu = me.menu,
arrowEl = me.arrowEl,
instanced;
if (oldMenu) {
oldMenu.ownerCmp = oldMenu.parentMenu = null;
if (destroyMenu === true || (destroyMenu !== false && me.destroyMenu)) {
Ext.destroy(oldMenu);
}
}
if (menu) {
instanced = menu.isMenu;
menu = me.menu = Ext.menu.Manager.get(menu, {
ownerCmp: me,
focusOnToFront: false
});
menu.setOwnerCmp(me, instanced);
} else {
menu = me.menu = null;
}
if (menu && me.rendered && !me.destroying && arrowEl) {
arrowEl[menu ? 'addCls' : 'removeCls'](me.arrowCls);
}
},
setHandler: function(fn, scope) {
this.handler = fn || null;
this.scope = scope;
},
setIcon: function(icon) {
var iconEl = this.iconEl,
oldIcon = this.icon;
if (iconEl) {
iconEl.src = icon || Ext.BLANK_IMAGE_URL;
}
this.icon = icon;
this.fireEvent('iconchange', this, oldIcon, icon);
},
setIconCls: function(iconCls) {
var me = this,
iconEl = me.iconEl,
oldCls = me.iconCls;
if (iconEl) {
if (me.iconCls) {
iconEl.removeCls(me.iconCls);
}
if (iconCls) {
iconEl.addCls(iconCls);
}
}
me.iconCls = iconCls;
me.fireEvent('iconchange', me, oldCls, iconCls);
},
setText: function(text) {
var me = this,
el = me.textEl || me.el,
oldText = me.text;
me.text = text;
if (me.rendered) {
el.setHtml(text || '');
me.updateLayout();
}
me.fireEvent('textchange', me, oldText, text);
},
getTipAttr: function() {
return this.tooltipType === 'qtip' ? 'data-qtip' : 'title';
},
clearTip: function() {
if (Ext.quickTipsActive && Ext.isObject(this.tooltip)) {
Ext.tip.QuickTipManager.unregister(this.itemEl);
}
},
setTooltip: function(tooltip, initial) {
var me = this;
if (me.rendered) {
if (!initial) {
me.clearTip();
}
if (Ext.quickTipsActive && Ext.isObject(tooltip)) {
Ext.tip.QuickTipManager.register(Ext.apply({
target: me.itemEl.id
}, tooltip));
me.tooltip = tooltip;
} else {
me.itemEl.dom.setAttribute(me.getTipAttr(), tooltip);
}
} else {
me.tooltip = tooltip;
}
return me;
},
privates: {
cancelDeferExpand: function() {
window.clearTimeout(this.expandMenuTimer);
},
cancelDeferHide: function() {
window.clearTimeout(this.hideMenuTimer);
},
getFocusEl: function() {
return this.itemEl;
}
}
});
Ext.define('Ext.menu.CheckItem', {
extend: 'Ext.menu.Item',
alias: 'widget.menucheckitem',
checkedCls: Ext.baseCSSPrefix + 'menu-item-checked',
uncheckedCls: Ext.baseCSSPrefix + 'menu-item-unchecked',
groupCls: Ext.baseCSSPrefix + 'menu-group-icon',
hideOnClick: false,
checkChangeDisabled: false,
ariaRole: 'menuitemcheckbox',
childEls: [
'checkEl'
],
showCheckbox: true,
isMenuCheckItem: true,
checkboxCls: Ext.baseCSSPrefix + 'menu-item-checkbox',
initComponent: function() {
var me = this;
me.checked = !!me.checked;
me.callParent(arguments);
if (me.group) {
Ext.menu.Manager.registerCheckable(me);
if (me.initialConfig.hideOnClick !== false) {
me.hideOnClick = true;
}
}
},
beforeRender: function() {
var me = this;
me.callParent();
Ext.apply(me.renderData, {
checkboxCls: me.checkboxCls,
showCheckbox: me.showCheckbox
});
},
afterRender: function() {
var me = this;
me.callParent();
me.checked = !me.checked;
me.setChecked(!me.checked, true);
if (me.checkChangeDisabled) {
me.disableCheckChange();
}
},
disableCheckChange: function() {
var me = this,
checkEl = me.checkEl;
if (checkEl) {
checkEl.addCls(me.disabledCls);
}
if (Ext.isIE8 && me.rendered) {
me.el.repaint();
}
me.checkChangeDisabled = true;
},
enableCheckChange: function() {
var me = this,
checkEl = me.checkEl;
if (checkEl) {
checkEl.removeCls(me.disabledCls);
}
me.checkChangeDisabled = false;
},
onClick: function(e) {
var me = this;
if (!me.disabled && !me.checkChangeDisabled && !(me.checked && me.group)) {
me.setChecked(!me.checked);
if (e.type === 'keydown' && me.menu) {
return false;
}
}
this.callParent([
e
]);
},
onDestroy: function() {
Ext.menu.Manager.unregisterCheckable(this);
this.callParent(arguments);
},
setChecked: function(checked, suppressEvents) {
var me = this,
checkedCls = me.checkedCls,
uncheckedCls = me.uncheckedCls,
el = me.el;
if (me.checked !== checked && (suppressEvents || me.fireEvent('beforecheckchange', me, checked) !== false)) {
if (el) {
if (checked) {
el.addCls(checkedCls);
el.removeCls(uncheckedCls);
} else {
el.addCls(uncheckedCls);
el.removeCls(checkedCls);
}
}
me.checked = checked;
Ext.menu.Manager.onCheckChange(me, checked);
if (!suppressEvents) {
Ext.callback(me.checkHandler, me.scope || me, [
me,
checked
]);
me.fireEvent('checkchange', me, checked);
}
}
}
});
Ext.define('Ext.menu.Separator', {
extend: 'Ext.menu.Item',
alias: 'widget.menuseparator',
focusable: false,
canActivate: false,
hideOnClick: false,
plain: true,
separatorCls: Ext.baseCSSPrefix + 'menu-item-separator',
text: '&#160;',
ariaRole: 'separator',
beforeRender: function(ct, pos) {
var me = this;
me.callParent();
me.addCls(me.separatorCls);
}
});
Ext.define('Ext.menu.Menu', {
extend: 'Ext.panel.Panel',
alias: 'widget.menu',
requires: [
'Ext.layout.container.VBox',
'Ext.menu.CheckItem',
'Ext.menu.Item',
'Ext.menu.Manager',
'Ext.menu.Separator'
],
mixins: [
'Ext.util.FocusableContainer'
],
enableKeyNav: true,
allowOtherMenus: false,
ariaRole: 'menu',
floating: true,
constrain: true,
hidden: true,
hideMode: 'visibility',
ignoreParentClicks: false,
isMenu: true,
showSeparator: true,
minWidth: undefined,
defaultMinWidth: 120,
defaultAlign: 'tl-bl?',
focusOnToFront: false,
bringParentToFront: false,
defaultFocus: ':focusable',
menuClickBuffer: 0,
baseCls: Ext.baseCSSPrefix + 'menu',
_iconSeparatorCls: Ext.baseCSSPrefix + 'menu-icon-separator',
_itemCmpCls: Ext.baseCSSPrefix + 'menu-item-cmp',
layout: {
type: 'vbox',
align: 'stretchmax',
overflowHandler: 'Scroller'
},
initComponent: function() {
var me = this,
cls = [
Ext.baseCSSPrefix + 'menu'
],
bodyCls = me.bodyCls ? [
me.bodyCls
] : [],
isFloating = me.floating !== false,
listeners = {
element: 'el',
click: me.onClick,
mouseover: me.onMouseOver,
scope: me
};
if (Ext.supports.Touch) {
listeners.pointerdown = me.onMouseOver;
}
me.on(listeners);
me.on({
beforeshow: me.onBeforeShow,
scope: me
});
if (me.plain) {
cls.push(Ext.baseCSSPrefix + 'menu-plain');
}
me.cls = cls.join(' ');
bodyCls.push(Ext.baseCSSPrefix + 'menu-body', Ext.dom.Element.unselectableCls);
me.bodyCls = bodyCls.join(' ');
if (isFloating) {
if (me.minWidth === undefined) {
me.minWidth = me.defaultMinWidth;
}
} else {
me.hidden = !!me.initialConfig.hidden;
me.constrain = false;
}
me.callParent(arguments);
Ext.override(me.getLayout(), {
configureItem: me.configureItem
});
},
initFloatConstrain: Ext.emptyFn,
getInherited: function() {
var result = this.callParent();
result.hidden = this.hidden;
return result;
},
beforeRender: function() {
this.callParent(arguments);
if (!this.getSizeModel().width.shrinkWrap) {
this.layout.align = 'stretch';
}
},
onBoxReady: function() {
var me = this,
iconSeparatorCls = me._iconSeparatorCls;
me.focusableKeyNav.map.processEvent = function(e) {
if (e.keyCode === e.ESC) {
e.target = me.el.dom;
}
return e;
};
me.focusableKeyNav.map.addBinding([
{
key: 27,
handler: me.onEscapeKey,
scope: me
},
{
key: /[\w]/,
handler: me.onShortcutKey,
scope: me,
shift: false,
ctrl: false,
alt: false
}
]);
me.callParent(arguments);
if (me.showSeparator) {
me.iconSepEl = me.body.insertFirst({
role: 'presentation',
cls: iconSeparatorCls + ' ' + iconSeparatorCls + '-' + me.ui,
html: '&#160;'
});
}
if (Ext.supports.MSPointerEvents || Ext.supports.PointerEvents) {
me.el.on({
scope: me,
click: me.preventClick,
translate: false
});
}
me.mouseMonitor = me.el.monitorMouseLeave(100, me.onMouseLeave, me);
},
onFocusLeave: function(e) {
var me = this;
me.callParent([
e
]);
me.mixins.focusablecontainer.onFocusLeave.call(me, e);
if (me.floating) {
me.hide();
}
},
canActivateItem: function(item) {
return item && item.isFocusable();
},
deactivateActiveItem: function() {
var me = this,
activeItem = me.lastFocusedChild;
if (activeItem) {
activeItem.blur();
}
},
getItemFromEvent: function(e) {
var me = this,
renderTarget = me.layout.getRenderTarget().dom,
toEl = e.getTarget();
while (toEl.parentNode !== renderTarget) {
toEl = toEl.parentNode;
if (!toEl) {
return;
}
}
return Ext.getCmp(toEl.id);
},
lookupComponent: function(cmp) {
var me = this;
if (typeof cmp === 'string') {
cmp = me.lookupItemFromString(cmp);
} else if (Ext.isObject(cmp)) {
cmp = me.lookupItemFromObject(cmp);
}
if (!cmp.dock) {
cmp.minWidth = cmp.minWidth || me.minWidth;
}
return cmp;
},
lookupItemFromObject: function(cmp) {
var me = this;
if (!cmp.isComponent) {
if (!cmp.xtype) {
cmp = Ext.create('Ext.menu.' + (Ext.isBoolean(cmp.checked) ? 'Check' : '') + 'Item', cmp);
} else {
cmp = Ext.ComponentManager.create(cmp, cmp.xtype);
}
}
if (cmp.isMenuItem) {
cmp.parentMenu = me;
}
return cmp;
},
lookupItemFromString: function(cmp) {
return (cmp === 'separator' || cmp === '-') ? new Ext.menu.Separator() : new Ext.menu.Item({
canActivate: false,
hideOnClick: false,
plain: true,
text: cmp
});
},
configureItem: function(cmp) {
var me = this.owner,
prefix = Ext.baseCSSPrefix,
ui = me.ui,
cls, cmpCls;
if (cmp.isMenuItem) {
cmp.setUI(ui);
} else if (me.items.getCount() > 1 && !cmp.rendered && !cmp.dock) {
cmpCls = me._itemCmpCls;
cls = [
cmpCls + ' ' + cmpCls + '-' + ui
];
if (!me.plain && (cmp.indent !== false || cmp.iconCls === 'no-icon')) {
cls.push(prefix + 'menu-item-indent-' + ui);
}
if (cmp.rendered) {
cmp.el.addCls(cls);
} else {
cmp.cls = (cmp.cls || '') + ' ' + cls.join(' ');
}
cmp.$extraMenuCls = cls;
}
this.callParent(arguments);
},
onRemove: function(cmp) {
this.callParent([
cmp
]);
if (!cmp.isDestroyed && cmp.$extraMenuCls) {
cmp.el.removeCls(cmp.$extraMenuCls);
}
},
onClick: function(e) {
var me = this,
type = e.type,
item, clickResult,
iskeyEvent = type === 'keydown';
if (me.disabled) {
e.stopEvent();
return;
}
item = me.getItemFromEvent(e);
if (item && item.isMenuItem) {
if (!item.menu || !me.ignoreParentClicks) {
clickResult = item.onClick(e);
} else {
e.stopEvent();
}
if (item.menu && clickResult !== false && iskeyEvent) {
item.expandMenu(e, 0);
}
}
if (!item || item.disabled) {
item = undefined;
}
me.fireEvent('click', me, item, e);
},
onDestroy: function() {
var me = this;
me.parentMenu = me.ownerCmp = null;
if (me.rendered) {
me.el.un(me.mouseMonitor);
Ext.destroy(me.iconSepEl);
}
me.callParent(arguments);
},
onMouseLeave: function(e) {
if (this.disabled) {
return;
}
this.fireEvent('mouseleave', this, e);
},
onMouseOver: function(e) {
var me = this,
fromEl = e.getRelatedTarget(),
mouseEnter = !me.el.contains(fromEl),
item = me.getItemFromEvent(e),
parentMenu = me.parentMenu,
ownerCmp = me.ownerCmp;
if (mouseEnter && parentMenu) {
parentMenu.setActiveItem(ownerCmp);
ownerCmp.cancelDeferHide();
parentMenu.mouseMonitor.mouseenter();
}
if (me.disabled) {
return;
}
if (item) {
if (!item.containsFocus) {
item.focus();
}
if (item.expandMenu) {
item.expandMenu(e);
}
}
if (mouseEnter) {
me.fireEvent('mouseenter', me, e);
}
me.fireEvent('mouseover', me, item, e);
},
setActiveItem: function(item) {
var me = this;
if (item && (item !== me.lastFocusedChild)) {
me.focusChild(item, 1);
}
},
onEscapeKey: function() {
if (this.floating) {
this.hide();
}
},
onShortcutKey: function(keyCode, e) {
var shortcutChar = String.fromCharCode(e.getCharCode()),
items = this.query('>[text]'),
len = items.length,
item = this.lastFocusedChild,
focusIndex = Ext.Array.indexOf(items, item),
i = focusIndex;
for (; ; ) {
if (++i === len) {
i = 0;
}
item = items[i];
if (i === focusIndex) {
return;
}
if (item.text && item.text[0].toUpperCase() === shortcutChar) {
item.focus();
return;
}
}
},
onFocusableContainerTabKey: function(e) {
if (this.floating) {
this.hide();
}
},
onFocusableContainerEnterKey: function(e) {
this.onClick(e);
},
onFocusableContainerSpaceKey: function(e) {
this.onClick(e);
},
onFocusableContainerLeftKey: function(e) {
if (this.parentMenu) {
this.ownerCmp.focus();
this.hide();
}
},
onFocusableContainerRightKey: function(e) {
var me = this,
focusItem = me.lastFocusedChild;
if (focusItem && focusItem.expandMenu) {
focusItem.expandMenu(e, 0);
}
},
onBeforeShow: function() {
if (Ext.Date.getElapsed(this.lastHide) < this.menuClickBuffer) {
return false;
}
},
beforeShow: function() {
var me = this,
activeEl, viewHeight;
if (me.floating) {
if (!me.hasFloatMenuParent() && !me.allowOtherMenus) {
Ext.menu.Manager.hideAll();
}
activeEl = Ext.Element.getActiveElement();
me.focusAnchor = activeEl === document.body ? null : activeEl;
me.savedMaxHeight = me.maxHeight;
viewHeight = me.container.getViewSize().height;
me.maxHeight = Math.min(me.maxHeight || viewHeight, viewHeight);
}
me.callParent(arguments);
},
afterShow: function() {
var me = this;
me.callParent(arguments);
Ext.menu.Manager.onShow(me);
if (me.floating && me.autoFocus) {
me.maxHeight = me.savedMaxHeight;
me.focus();
}
},
onHide: function(animateTarget, cb, scope) {
var me = this,
focusTarget;
if (me.el.contains(Ext.Element.getActiveElement())) {
focusTarget = me.focusAnchor || me.ownerCmp || me.up(':focusable');
if (focusTarget) {
me.previousFocus = focusTarget;
}
}
me.callParent([
animateTarget,
cb,
scope
]);
me.lastHide = Ext.Date.now();
Ext.menu.Manager.onHide(me);
},
preventClick: function(e) {
var item = this.getItemFromEvent(e);
if (item && !item.href) {
e.preventDefault();
}
},
privates: {
hasFloatMenuParent: function() {
return this.parentMenu || this.up('menu[floating=true]');
},
setOwnerCmp: function(comp, instanced) {
var me = this;
me.parentMenu = comp.isMenuItem ? comp : null;
me.ownerCmp = comp;
me.registerWithOwnerCt();
delete me.hierarchicallyHidden;
if (me.inheritedState && instanced) {
me.invalidateInheritedState();
}
if (me.reference) {
me.fixReference();
}
if (instanced) {
Ext.ComponentManager.markReferencesDirty();
}
}
}
});
Ext.define('Ext.grid.filters.filter.Base', {
mixins: [
'Ext.mixin.Factoryable'
],
factoryConfig: {
type: 'grid.filter'
},
$configPrefixed: false,
$configStrict: false,
config: {
itemDefaults: null,
menuDefaults: {
xtype: 'menu'
},
updateBuffer: 500
},
active: false,
type: 'string',
dataIndex: null,
menu: null,
isGridFilter: true,
defaultRoot: 'data',
filterIdPrefix: Ext.baseCSSPrefix + 'gridfilter',
constructor: function(config) {
var me = this,
column;
me.initConfig(config);
column = me.column;
column.on('destroy', me.destroy, me);
me.dataIndex = me.dataIndex || column.dataIndex;
me.task = new Ext.util.DelayedTask(me.setValue, me);
},
destroy: function() {
this.grid = this.menu = Ext.destroy(this.menu);
},
addStoreFilter: function(filter) {
this.getGridStore().getFilters().add(filter);
},
createFilter: function(config, key) {
return new Ext.util.Filter(this.getFilterConfig(config, key));
},
getFilterConfig: function(config, key) {
config.id = this.getBaseIdPrefix();
if (!config.property) {
config.property = this.dataIndex;
}
if (!config.root) {
config.root = this.defaultRoot;
}
if (key) {
config.id += '-' + key;
}
return config;
},
createMenu: function() {
this.menu = Ext.widget(this.getMenuConfig());
},
getActiveState: function(config, value) {
var active = config.active;
return (active !== undefined) ? active : value !== undefined;
},
getBaseIdPrefix: function() {
return this.filterIdPrefix + '-' + this.dataIndex;
},
getMenuConfig: function() {
return Ext.apply({}, this.getMenuDefaults());
},
getGridStore: function() {
return this.grid.getStore();
},
getStoreFilter: function(key) {
var id = this.getBaseIdPrefix();
if (key) {
id += '-' + key;
}
return this.getGridStore().getFilters().get(id);
},
onValueChange: function(field, e) {
var me = this,
updateBuffer = me.updateBuffer;
if (!field.isFormField) {
Ext.Error.raise('`field` should be a form field instance.');
}
if (field.isValid()) {
if (e.getKey() === e.RETURN) {
me.menu.hide();
return;
}
if (updateBuffer) {
me.task.delay(updateBuffer, null, null, [
me.getValue(field)
]);
} else {
me.setValue(me.getValue(field));
}
}
},
preprocess: Ext.emptyFn,
removeStoreFilter: function(filter) {
this.getGridStore().getFilters().remove(filter);
},
getValue: Ext.emptyFn,
setActive: function(active) {
var me = this,
menuItem = me.owner.activeFilterMenuItem,
filterCollection;
if (me.active !== active) {
me.active = active;
me.preventDefault = true;
filterCollection = me.getGridStore().getFilters();
filterCollection.beginUpdate();
if (active) {
me.activate();
} else {
me.deactivate();
}
filterCollection.endUpdate();
me.preventDefault = false;
if (menuItem && menuItem.activeFilter === me) {
menuItem.setChecked(active);
}
me.setColumnActive(active);
}
},
setColumnActive: function(active) {
this.column[active ? 'addCls' : 'removeCls'](this.owner.filterCls);
},
showMenu: function(menuItem) {
var me = this;
if (!me.menu) {
me.createMenu();
}
menuItem.activeFilter = me;
menuItem.setMenu(me.menu, false);
menuItem.setChecked(me.active);
menuItem.setDisabled(me.disabled === true);
me.activate(
true);
},
updateStoreFilter: function() {
this.getGridStore().getFilters().notify('endupdate');
}
});
Ext.define('Ext.grid.filters.filter.SingleFilter', {
extend: 'Ext.grid.filters.filter.Base',
constructor: function(config) {
var me = this,
filter, value;
me.callParent([
config
]);
value = me.value;
filter = me.getStoreFilter();
if (filter) {
me.active = true;
} else {
if (me.grid.stateful && me.getGridStore().saveStatefulFilters) {
value = undefined;
}
me.active = me.getActiveState(config, value);
filter = me.createFilter({
operator: me.operator,
value: value
});
if (me.active) {
me.addStoreFilter(filter);
}
}
if (me.active) {
me.setColumnActive(true);
}
me.filter = filter;
},
activate: function(showingMenu) {
if (showingMenu) {
this.activateMenu();
} else {
this.addStoreFilter(this.filter);
}
},
deactivate: function() {
this.removeStoreFilter(this.filter);
},
getValue: function(field) {
return field.getValue();
},
onFilterRemove: function() {
if (!this.menu || this.active) {
this.active = false;
}
}
});
Ext.define('Ext.grid.filters.filter.Boolean', {
extend: 'Ext.grid.filters.filter.SingleFilter',
alias: 'grid.filter.boolean',
type: 'boolean',
operator: '=',
defaultValue: false,
yesText: 'Yes',
noText: 'No',
updateBuffer: 0,
createMenu: function(config) {
var me = this,
gId = Ext.id(),
listeners = {
scope: me,
click: me.onClick
},
itemDefaults = me.getItemDefaults();
me.callParent(arguments);
me.menu.add([
Ext.apply({
text: me.yesText,
filterKey: 1,
group: gId,
checked: !!me.defaultValue,
listeners: listeners
}, itemDefaults),
Ext.apply({
text: me.noText,
filterKey: 0,
group: gId,
checked: !me.defaultValue,
listeners: listeners
}, itemDefaults)
]);
},
onClick: function(field) {
this.setValue(!!field.filterKey);
},
setValue: function(value) {
var me = this;
me.filter.setValue(value);
if (value !== undefined && me.active) {
me.value = value;
me.updateStoreFilter();
} else {
me.setActive(true);
}
},
activateMenu: Ext.emptyFn
});
Ext.define('Ext.grid.filters.filter.TriFilter', {
extend: 'Ext.grid.filters.filter.Base',
menuItems: [
'lt',
'gt',
'-',
'eq'
],
constructor: function(config) {
var me = this,
stateful = false,
filter = {},
filterGt, filterLt, filterEq, value, operator;
me.callParent([
config
]);
value = me.value;
filterLt = me.getStoreFilter('lt');
filterGt = me.getStoreFilter('gt');
filterEq = me.getStoreFilter('eq');
if (filterLt || filterGt || filterEq) {
stateful = me.active = true;
if (filterLt) {
me.onStateRestore(filterLt);
}
if (filterGt) {
me.onStateRestore(filterGt);
}
if (filterEq) {
me.onStateRestore(filterEq);
}
} else {
if (me.grid.stateful && me.getGridStore().saveStatefulFilters) {
value = undefined;
}
me.active = me.getActiveState(config, value);
}
filter.lt = filterLt || me.createFilter({
operator: 'lt',
value: (!stateful && value && value.lt) || null
}, 'lt');
filter.gt = filterGt || me.createFilter({
operator: 'gt',
value: (!stateful && value && value.gt) || null
}, 'gt');
filter.eq = filterEq || me.createFilter({
operator: 'eq',
value: (!stateful && value && value.eq) || null
}, 'eq');
me.filter = filter;
if (me.active) {
me.setColumnActive(true);
if (!stateful) {
for (operator in value) {
me.addStoreFilter(me.filter[operator]);
}
}
}
},
activate: function(showingMenu) {
var me = this,
filters = me.filter,
fields = me.fields,
filter, field, operator, value, isRootMenuItem;
if (me.preventFilterRemoval) {
return;
}
for (operator in filters) {
filter = filters[operator];
field = fields[operator];
value = filter.getValue();
if (value) {
field.setValue(value);
if (isRootMenuItem === undefined) {
isRootMenuItem = me.owner.activeFilterMenuItem === field.up('menuitem');
}
if (!isRootMenuItem) {
field.up('menuitem').setChecked(true,
true);
}
if (!showingMenu) {
me.addStoreFilter(filter);
}
}
}
},
deactivate: function() {
var me = this,
filters = me.filter,
f, filter;
if (!me.countActiveFilters() || me.preventFilterRemoval) {
return;
}
me.preventFilterRemoval = true;
for (f in filters) {
filter = filters[f];
if (filter.getValue()) {
me.removeStoreFilter(filter);
}
}
me.preventFilterRemoval = false;
},
countActiveFilters: function() {
var filters = this.filter,
filterCollection = this.getGridStore().getFilters(),
prefix = this.getBaseIdPrefix(),
i = 0,
filter;
if (filterCollection.length) {
for (filter in filters) {
if (filterCollection.get(prefix + '-' + filter)) {
i++;
}
}
}
return i;
},
onFilterRemove: function(operator) {
var me = this,
value;
if (!me.menu && me.countActiveFilters()) {
me.active = false;
} else if (me.menu) {
value = {};
value[operator] = null;
me.setValue(value);
}
},
onStateRestore: Ext.emptyFn,
setValue: function(value) {
var me = this,
filters = me.filter,
add = [],
remove = [],
active = false,
filterCollection = me.getGridStore().getFilters(),
field, filter, v, i, len, rLen, aLen;
if (me.preventFilterRemoval) {
return;
}
me.preventFilterRemoval = true;
if ('eq' in value) {
v = filters.lt.getValue();
if (v || v === 0) {
remove.push(filters.lt);
}
v = filters.gt.getValue();
if (v || v === 0) {
remove.push(filters.gt);
}
v = value.eq;
if (v || v === 0) {
add.push(filters.eq);
filters.eq.setValue(v);
} else {
remove.push(filters.eq);
}
} else {
v = filters.eq.getValue();
if (v || v === 0) {
remove.push(filters.eq);
}
if ('lt' in value) {
v = value.lt;
if (v || v === 0) {
add.push(filters.lt);
filters.lt.setValue(v);
} else {
remove.push(filters.lt);
}
}
if ('gt' in value) {
v = value.gt;
if (v || v === 0) {
add.push(filters.gt);
filters.gt.setValue(v);
} else {
remove.push(filters.gt);
}
}
}
rLen = remove.length;
aLen = add.length;
active = !!(me.countActiveFilters() + aLen - rLen);
if (rLen || aLen || active !== me.active) {
filterCollection.beginUpdate();
if (rLen) {
for (i = 0; i < rLen; i++) {
filter = remove[i];
me.fields[filter.getOperator()].setValue(null);
filter.setValue(null);
me.removeStoreFilter(filter);
}
}
if (aLen) {
for (i = 0; i < aLen; i++) {
me.addStoreFilter(add[i]);
}
}
me.setActive(active);
filterCollection.endUpdate();
}
me.preventFilterRemoval = false;
}
});
Ext.define('Ext.grid.filters.filter.Date', {
extend: 'Ext.grid.filters.filter.TriFilter',
alias: 'grid.filter.date',
uses: [
'Ext.picker.Date',
'Ext.menu.Menu'
],
type: 'date',
config: {
fields: {
lt: {
text: 'Before'
},
gt: {
text: 'After'
},
eq: {
text: 'On'
}
},
pickerDefaults: {
xtype: 'datepicker',
border: 0
},
updateBuffer: 0,
dateFormat: undefined
},
itemDefaults: {
xtype: 'menucheckitem',
selectOnFocus: true,
width: 125,
menu: {
layout: 'auto',
plain: true
}
},
applyDateFormat: function(dateFormat) {
return dateFormat || Ext.Date.defaultFormat;
},
createMenu: function(config) {
var me = this,
listeners = {
scope: me,
checkchange: me.onCheckChange
},
menuItems = me.menuItems,
fields, itemDefaults, pickerCfg, i, len, key, item, cfg, field;
me.callParent(arguments);
itemDefaults = me.getItemDefaults();
fields = me.getFields();
pickerCfg = Ext.apply({
minDate: me.minDate,
maxDate: me.maxDate,
format: me.dateFormat,
listeners: {
scope: me,
select: me.onMenuSelect
}
}, me.getPickerDefaults());
me.fields = {};
for (i = 0 , len = menuItems.length; i < len; i++) {
key = menuItems[i];
if (key !== '-') {
cfg = {
menu: {
items: [
Ext.apply({
itemId: key
}, pickerCfg)
]
}
};
if (itemDefaults) {
Ext.merge(cfg, itemDefaults);
}
if (fields) {
Ext.merge(cfg, fields[key]);
}
item = me.menu.add(cfg);
field = me.fields[key] = item.down('datepicker');
field.filter = me.filter[key];
field.filterKey = key;
item.on(listeners);
} else {
me.menu.add(key);
}
}
},
getPicker: function(item) {
return this.fields[item];
},
onCheckChange: function(field, checked) {
var filter = field.down('datepicker').filter,
v;
if (!checked && filter.getValue()) {
v = {};
v[filter.getOperator()] = null;
this.setValue(v);
}
},
onFilterRemove: function(operator) {
var v = {};
v[operator] = null;
this.setValue(v);
this.fields[operator].up('menuitem').setChecked(false,
true);
},
onStateRestore: function(filter) {
filter.setSerializer(this.getSerializer());
filter.setConvert(this.convertDateOnly);
},
getFilterConfig: function(config, key) {
config = this.callParent([
config,
key
]);
config.serializer = this.getSerializer();
config.convert = this.convertDateOnly;
return config;
},
convertDateOnly: function(v) {
var result = null;
if (v) {
result = Ext.Date.clearTime(v, true).getTime();
}
return result;
},
getSerializer: function() {
var me = this;
return function(data) {
var value = data.value;
if (value) {
data.value = Ext.Date.format(value, me.getDateFormat());
}
};
},
onMenuSelect: function(picker, date) {
var fields = this.fields,
field = fields[picker.itemId],
gt = fields.gt,
lt = fields.lt,
eq = fields.eq,
v = {};
field.up('menuitem').setChecked(true,
true);
if (field === eq) {
lt.up('menuitem').setChecked(false, true);
gt.up('menuitem').setChecked(false, true);
} else {
eq.up('menuitem').setChecked(false, true);
if (field === gt && (+lt.value < +date)) {
lt.up('menuitem').setChecked(false, true);
v.lt = null;
} else if (field === lt && (+gt.value > +date)) {
gt.up('menuitem').setChecked(false, true);
v.gt = null;
}
}
v[field.filterKey] = date;
this.setValue(v);
picker.up('menu').hide();
}
});
Ext.define('Ext.grid.filters.filter.List', {
extend: 'Ext.grid.filters.filter.SingleFilter',
alias: 'grid.filter.list',
type: 'list',
operator: 'in',
itemDefaults: {
checked: false,
hideOnClick: false
},
idField: 'id',
labelField: 'text',
labelIndex: null,
loadingText: 'Loading...',
loadOnShow: true,
single: false,
plain: true,
constructor: function(config) {
var me = this,
options, store;
me.callParent([
config
]);
if (me.itemDefaults.checked) {
Ext.Error.raise('The itemDefaults.checked config is not supported, use the value config instead.');
}
options = me.options;
store = me.store;
if (!options && !store) {
me.getGridStore().on({
scope: me,
add: me.onDataChanged,
refresh: me.onDataChanged,
remove: me.onDataChanged,
update: me.onDataChanged
});
}
me.labelIndex = me.labelIndex || me.column.dataIndex;
},
destroy: function() {
var me = this,
store = me.store,
autoStore = me.autoStore;
if (store) {
if (autoStore || store.autoDestroy) {
store.destroy();
} else {
store.un('load', me.bindMenuStore, me);
}
me.store = null;
}
if (autoStore) {
me.getGridStore().un({
scope: me,
add: me.onDataChanged,
refresh: me.onDataChanged,
remove: me.onDataChanged,
update: me.onDataChanged
});
}
me.callParent();
},
activateMenu: function() {
var me = this,
value = me.filter.getValue(),
items, i, len, checkItem;
if (!value || !value.length) {
return;
}
items = me.menu.items;
for (i = 0 , len = items.length; i < len; i++) {
checkItem = items.getAt(i);
if (Ext.Array.indexOf(value, checkItem.value) > -1) {
checkItem.setChecked(true,
true);
}
}
},
bindMenuStore: function(options) {
var me = this;
if (me.grid.isDestroyed || me.preventFilterRemoval) {
return;
}
me.createListStore(options);
me.createMenuItems(me.store);
me.loaded = true;
},
createListStore: function(options) {
var me = this,
store = me.store,
isStore = options.isStore,
idField = me.idField,
labelField = me.labelField,
optionsStore = false,
storeData, o, i, len, value;
if (isStore) {
if (options !== me.getGridStore()) {
optionsStore = true;
store = me.store = options;
} else {
me.autoStore = true;
storeData = me.getOptionsFromStore(options);
}
} else {
storeData = [];
for (i = 0 , len = options.length; i < len; i++) {
value = options[i];
switch (Ext.typeOf(value)) {
case 'array':
storeData.push(value);
break;
case 'object':
storeData.push(value);
break;
default:
if (value != null) {
o = {};
o[idField] = value;
o[labelField] = value;
storeData.push(o);
};
}
}
}
if (!optionsStore) {
if (store) {
store.destroy();
}
store = me.store = new Ext.data.Store({
fields: [
idField,
labelField
],
data: storeData
});
me.loaded = true;
}
me.setStoreFilter(store);
},
createMenu: function(config) {
var me = this,
gridStore = me.getGridStore(),
store = me.store,
options = me.options,
menu;
if (store) {
me.store = store = Ext.StoreManager.lookup(store);
}
me.callParent([
config
]);
menu = me.menu;
if (store) {
if (!store.getCount()) {
menu.add({
text: me.loadingText,
iconCls: Ext.baseCSSPrefix + 'mask-msg-text'
});
menu.on('show', me.show, me);
store.on('load', me.bindMenuStore, me, {
single: true
});
} else {
me.createMenuItems(store);
}
}
else if (options) {
me.bindMenuStore(options);
}
else if (gridStore.getCount() || gridStore.data.filtered) {
me.bindMenuStore(gridStore);
} else
{
gridStore.on('load', me.bindMenuStore, me, {
single: true
});
}
},
createMenuItems: function(store) {
var me = this,
menu = me.menu,
len = store.getCount(),
contains = Ext.Array.contains,
listeners, itemDefaults, record, gid, idValue, idField, labelValue, labelField, i, item, processed;
if (len && menu) {
listeners = {
checkchange: me.onCheckChange,
scope: me
};
itemDefaults = me.getItemDefaults();
menu.suspendLayouts();
menu.removeAll(true);
gid = me.single ? Ext.id() : null;
idField = me.idField;
labelField = me.labelField;
processed = [];
for (i = 0; i < len; i++) {
record = store.getAt(i);
idValue = record.get(idField);
labelValue = record.get(labelField);
if (labelValue == null || contains(processed, idValue)) {
continue;
}
processed.push(labelValue);
item = menu.add(Ext.apply({
text: labelValue,
group: gid,
value: idValue,
listeners: listeners
}, itemDefaults));
}
menu.resumeLayouts(true);
}
},
getFilterConfig: function(config, key) {
config.value = config.value || [];
return this.callParent([
config,
key
]);
},
getOptionsFromStore: function(store) {
var me = this,
data = store.getData(),
map = {},
ret = [],
dataIndex = me.dataIndex,
labelIndex = me.labelIndex,
items, i, length, recData, idValue, labelValue;
if (store.isFiltered()) {
data = data.getSource();
}
items = data.items;
length = items.length;
for (i = 0; i < length; ++i) {
recData = items[i].data;
idValue = recData[dataIndex];
labelValue = recData[labelIndex];
if (labelValue === undefined) {
labelValue = idValue;
}
if (!map[idValue]) {
map[idValue] = 1;
ret.push([
idValue,
labelValue
]);
}
}
return ret;
},
onCheckChange: function() {
var me = this,
updateBuffer = me.updateBuffer;
if (updateBuffer) {
me.task.delay(updateBuffer, null, null);
} else {
me.setValue();
}
},
onDataChanged: function(store) {
if (!this.preventDefault) {
this.bindMenuStore(store);
}
},
setStoreFilter: function(options) {
var me = this,
value = me.value,
filter = me.filter;
if (value) {
if (!Ext.isArray(value)) {
value = [
value
];
}
filter.setValue(value);
}
if (me.active) {
me.preventFilterRemoval = true;
me.addStoreFilter(filter);
me.preventFilterRemoval = false;
}
},
setValue: function() {
var me = this,
items = me.menu.items,
value = [],
i, len, checkItem;
me.preventDefault = true;
for (i = 0 , len = items.length; i < len; i++) {
checkItem = items.getAt(i);
if (checkItem.checked) {
value.push(checkItem.value);
}
}
me.filter.setValue(value);
len = value.length;
if (len && me.active) {
me.updateStoreFilter();
} else {
me.setActive(!!len);
}
me.preventDefault = false;
},
show: function() {
var store = this.store;
if (this.loadOnShow && !this.loaded && !store.hasPendingLoad()) {
store.load();
}
}
});
Ext.define('Ext.grid.filters.filter.Number', {
extend: 'Ext.grid.filters.filter.TriFilter',
alias: [
'grid.filter.number',
'grid.filter.numeric'
],
uses: [
'Ext.form.field.Number'
],
type: 'number',
config: {
fields: {
gt: {
iconCls: Ext.baseCSSPrefix + 'grid-filters-gt',
margin: '0 0 3px 0'
},
lt: {
iconCls: Ext.baseCSSPrefix + 'grid-filters-lt',
margin: '0 0 3px 0'
},
eq: {
iconCls: Ext.baseCSSPrefix + 'grid-filters-eq',
margin: 0
}
}
},
emptyText: 'Enter Number...',
itemDefaults: {
xtype: 'numberfield',
enableKeyEvents: true,
hideEmptyLabel: false,
labelSeparator: '',
labelWidth: 29,
selectOnFocus: false
},
menuDefaults: {
bodyPadding: 3,
showSeparator: false
},
createMenu: function() {
var me = this,
listeners = {
scope: me,
keyup: me.onValueChange,
spin: {
fn: me.onInputSpin,
buffer: 200
},
el: {
click: me.stopFn
}
},
itemDefaults = me.getItemDefaults(),
menuItems = me.menuItems,
fields = me.getFields(),
field, i, len, key, item, cfg;
me.callParent();
me.fields = {};
for (i = 0 , len = menuItems.length; i < len; i++) {
key = menuItems[i];
if (key !== '-') {
field = fields[key];
cfg = {
labelClsExtra: Ext.baseCSSPrefix + 'grid-filters-icon ' + field.iconCls
};
if (itemDefaults) {
Ext.merge(cfg, itemDefaults);
}
Ext.merge(cfg, field);
cfg.emptyText = cfg.emptyText || me.emptyText;
delete cfg.iconCls;
me.fields[key] = item = me.menu.add(cfg);
item.filter = me.filter[key];
item.filterKey = key;
item.on(listeners);
} else {
me.menu.add(key);
}
}
},
getValue: function(field) {
var value = {};
value[field.filterKey] = field.getValue();
return value;
},
onInputSpin: function(field, direction) {
var value = {};
value[field.filterKey] = field.getValue();
this.setValue(value);
},
stopFn: function(e) {
e.stopPropagation();
}
});
Ext.define('Ext.grid.filters.filter.String', {
extend: 'Ext.grid.filters.filter.SingleFilter',
alias: 'grid.filter.string',
type: 'string',
operator: 'like',
emptyText: 'Enter Filter Text...',
itemDefaults: {
xtype: 'textfield',
enableKeyEvents: true,
hideEmptyLabel: false,
iconCls: Ext.baseCSSPrefix + 'grid-filters-find',
labelSeparator: '',
labelWidth: 29,
margin: 0,
selectOnFocus: true
},
menuDefaults: {
bodyPadding: 3,
showSeparator: false
},
createMenu: function() {
var me = this,
config;
me.callParent();
config = Ext.apply({}, me.getItemDefaults());
if (config.iconCls && !('labelClsExtra' in config)) {
config.labelClsExtra = Ext.baseCSSPrefix + 'grid-filters-icon ' + config.iconCls;
}
delete config.iconCls;
config.emptyText = config.emptyText || me.emptyText;
me.inputItem = me.menu.add(config);
me.inputItem.on({
scope: me,
keyup: me.onValueChange,
el: {
click: function(e) {
e.stopPropagation();
}
}
});
},
setValue: function(value) {
var me = this;
if (me.inputItem) {
me.inputItem.setValue(value);
}
me.filter.setValue(value);
if (value && me.active) {
me.value = value;
me.updateStoreFilter();
} else {
me.setActive(!!value);
}
},
activateMenu: function() {
this.inputItem.setValue(this.filter.getValue());
}
});
Ext.define('Ext.grid.filters.Filters', {
extend: 'Ext.plugin.Abstract',
requires: [
'Ext.grid.filters.filter.*'
],
mixins: [
'Ext.util.StoreHolder'
],
alias: 'plugin.gridfilters',
pluginId: 'gridfilters',
defaultFilterTypes: {
'boolean': 'boolean',
'int': 'number',
date: 'date',
number: 'number'
},
filterCls: Ext.baseCSSPrefix + 'grid-filters-filtered-column',
menuFilterText: 'Filters',
showMenu: true,
stateId: undefined,
init: function(grid) {
var me = this,
store, headerCt;
Ext.Assert.falsey(me.grid);
me.grid = grid;
grid.filters = me;
if (me.grid.normalGrid) {
me.isLocked = true;
}
grid.clearFilters = me.clearFilters.bind(me);
store = grid.store;
headerCt = grid.headerCt;
headerCt.on({
scope: me,
add: me.onAdd,
menucreate: me.onMenuCreate
});
grid.on({
scope: me,
destroy: me.onGridDestroy,
reconfigure: me.onReconfigure
});
me.bindStore(store);
if (grid.stateful) {
store.statefulFilters = true;
}
me.initColumns();
},
initColumns: function() {
var grid = this.grid,
store = grid.getStore(),
columns = grid.columnManager.getColumns(),
len = columns.length,
i, column, filter, filterCollection;
for (i = 0; i < len; i++) {
column = columns[i];
filter = column.filter;
if (filter && !filter.isGridFilter) {
if (!filterCollection) {
filterCollection = store.getFilters();
filterCollection.beginUpdate();
}
this.createColumnFilter(column);
}
}
if (filterCollection) {
filterCollection.endUpdate();
}
},
createColumnFilter: function(column) {
var me = this,
columnFilter = column.filter,
filter = {
column: column,
grid: me.grid,
owner: me
},
field, model, type;
if (Ext.isString(columnFilter)) {
filter.type = columnFilter;
} else {
Ext.apply(filter, columnFilter);
}
if (!filter.type) {
model = me.store.getModel();
field = model && model.getField(column.dataIndex);
type = field && field.type;
filter.type = (type && me.defaultFilterTypes[type]) || column.defaultFilterType || 'string';
}
column.filter = Ext.Factory.gridFilter(filter);
},
onAdd: function(headerCt, column, index) {
var filter = column.filter;
if (filter && !filter.isGridFilter) {
this.createColumnFilter(column);
}
},
onMenuCreate: function(headerCt, menu) {
menu.on({
beforeshow: this.onMenuBeforeShow,
scope: this
});
},
onMenuBeforeShow: function(menu) {
var me = this,
menuItem, filter, parentTable, parentTableId;
if (me.showMenu) {
if (!me.filterMenuItem) {
me.filterMenuItem = {};
}
parentTable = menu.up('tablepanel');
parentTableId = parentTable.id;
menuItem = me.filterMenuItem[parentTableId];
if (!menuItem || menuItem.isDestroyed) {
menuItem = me.createMenuItem(menu, parentTableId);
}
me.activeFilterMenuItem = menuItem;
filter = me.getMenuFilter(parentTable.headerCt);
if (filter) {
filter.showMenu(menuItem);
}
menuItem.setVisible(!!filter);
me.sep.setVisible(!!filter);
}
},
createMenuItem: function(menu, parentTableId) {
var me = this,
item;
me.sep = menu.add('-');
item = menu.add({
checked: false,
itemId: 'filters',
text: me.menuFilterText,
listeners: {
scope: me,
checkchange: me.onCheckChange
}
});
return (me.filterMenuItem[parentTableId] = item);
},
onGridDestroy: function() {
var me = this,
filterMenuItem = me.filterMenuItem,
item;
me.bindStore(null);
me.sep = Ext.destroy(me.sep);
for (item in filterMenuItem) {
filterMenuItem[item].destroy();
}
me.grid = null;
},
onUnbindStore: function(store) {
store.getFilters().un('remove', this.onFilterRemove, this);
},
onBindStore: function(store, initial, propName) {
this.local = !store.getRemoteFilter();
store.getFilters().on('remove', this.onFilterRemove, this);
},
onFilterRemove: function(filterCollection, list) {
var len = list.items.length,
columnManager = this.grid.columnManager,
i, item, header, filter;
for (i = 0; i < len; i++) {
item = list.items[i];
header = columnManager.getHeaderByDataIndex(item.getProperty());
if (header) {
filter = header.filter;
if (!filter || !filter.menu || item.getId().indexOf(filter.getBaseIdPrefix()) === -1) {
continue;
}
if (!filter.preventFilterRemoval) {
filter.onFilterRemove(item.getOperator());
}
}
}
},
getMenuFilter: function(headerCt) {
return headerCt.getMenu().activeHeader.filter;
},
onCheckChange: function(item, value) {
var parentTable = this.isLocked ? item.up('tablepanel') : this.grid,
filter = this.getMenuFilter(parentTable.headerCt);
filter.setActive(value);
},
getHeaders: function() {
return this.grid.view.headerCt.columnManager.getColumns();
},
isStateful: function() {
return this.grid.stateful;
},
addFilter: function(filters) {
var me = this,
grid = me.grid,
store = me.store,
hasNewColumns = false,
suppressNextFilter = true,
dataIndex, column, i, len, filter, columnFilter;
if (!Ext.isArray(filters)) {
filters = [
filters
];
}
for (i = 0 , len = filters.length; i < len; i++) {
filter = filters[i];
dataIndex = filter.dataIndex;
column = grid.columnManager.getHeaderByDataIndex(dataIndex);
if (column) {
hasNewColumns = true;
if (filter.value) {
suppressNextFilter = false;
}
columnFilter = column.filter;
if (columnFilter && columnFilter.isGridFilter) {
columnFilter.deactivate();
columnFilter.destroy();
if (me.activeFilterMenuItem) {
me.activeFilterMenuItem.menu = null;
}
}
column.filter = filter;
}
}
if (hasNewColumns) {
store.suppressNextFilter = suppressNextFilter;
me.initColumns();
store.suppressNextFilter = false;
}
},
addFilters: function(filters) {
if (filters) {
this.addFilter(filters);
}
},
clearFilters: function() {
var grid = this.grid,
columns = grid.columnManager.getColumns(),
store = grid.store,
column, filter, i, len, filterCollection;
for (i = 0 , len = columns.length; i < len; i++) {
column = columns[i];
filter = column.filter;
if (filter && filter.isGridFilter) {
if (!filterCollection) {
filterCollection = store.getFilters();
filterCollection.beginUpdate();
}
filter.setActive(false);
}
}
if (filterCollection) {
filterCollection.endUpdate();
}
},
onReconfigure: function(grid, store, columns, oldStore) {
var filterMenuItem = this.filterMenuItem,
key;
for (key in filterMenuItem) {
filterMenuItem[key].setMenu(null);
}
if (store && oldStore !== store) {
this.bindStore(store);
}
}
});
Ext.define('Ext.grid.locking.HeaderContainer', {
extend: 'Ext.grid.header.Container',
requires: [
'Ext.grid.ColumnManager'
],
headerCtRelayEvents: [
"blur",
"focus",
"move",
"resize",
"destroy",
"beforedestroy",
"boxready",
"afterrender",
"render",
"beforerender",
"removed",
"hide",
"beforehide",
"show",
"beforeshow",
"enable",
"disable",
"added",
"deactivate",
"beforedeactivate",
"activate",
"beforeactivate",
"remove",
"add",
"beforeremove",
"beforeadd",
"afterlayout",
"menucreate",
"sortchange",
"columnschanged",
"columnshow",
"columnhide",
"columnmove",
"headertriggerclick",
"headercontextmenu",
"headerclick",
"columnresize",
"statesave",
"beforestatesave",
"staterestore",
"beforestaterestore"
],
constructor: function(lockable) {
var me = this,
lockedGrid = lockable.lockedGrid,
normalGrid = lockable.normalGrid;
me.lockable = lockable;
me.callParent();
lockedGrid.visibleColumnManager.rootColumns = normalGrid.visibleColumnManager.rootColumns = lockable.visibleColumnManager = me.visibleColumnManager = new Ext.grid.ColumnManager(true, lockedGrid.headerCt, normalGrid.headerCt);
lockedGrid.columnManager.rootColumns = normalGrid.columnManager.rootColumns = lockable.columnManager = me.columnManager = new Ext.grid.ColumnManager(false, lockedGrid.headerCt, normalGrid.headerCt);
me.relayEvents(lockedGrid.headerCt, me.headerCtRelayEvents);
me.relayEvents(normalGrid.headerCt, me.headerCtRelayEvents);
},
getRefItems: function() {
return this.lockable.lockedGrid.headerCt.getRefItems().concat(this.lockable.normalGrid.headerCt.getRefItems());
},
getGridColumns: function() {
return this.lockable.lockedGrid.headerCt.getGridColumns().concat(this.lockable.normalGrid.headerCt.getGridColumns());
},
getColumnsState: function() {
var me = this,
locked = me.lockable.lockedGrid.headerCt.getColumnsState(),
normal = me.lockable.normalGrid.headerCt.getColumnsState();
return locked.concat(normal);
},
applyColumnsState: function(columns) {
var me = this,
lockedGrid = me.lockable.lockedGrid,
lockedHeaderCt = lockedGrid.headerCt,
normalHeaderCt = me.lockable.normalGrid.headerCt,
lockedCols = Ext.Array.toValueMap(lockedHeaderCt.items.items, 'stateId'),
normalCols = Ext.Array.toValueMap(normalHeaderCt.items.items, 'stateId'),
locked = [],
normal = [],
lockedWidth = 1,
length = columns.length,
i, existing, lockedDefault, col;
for (i = 0; i < length; i++) {
col = columns[i];
lockedDefault = lockedCols[col.id];
existing = lockedDefault || normalCols[col.id];
if (existing) {
if (existing.applyColumnState) {
existing.applyColumnState(col);
}
if (existing.locked === undefined) {
existing.locked = !!lockedDefault;
}
if (existing.locked) {
locked.push(existing);
if (!existing.hidden && typeof existing.width === 'number') {
lockedWidth += existing.width;
}
} else {
normal.push(existing);
}
}
}
if (locked.length + normal.length === lockedHeaderCt.items.getCount() + normalHeaderCt.items.getCount()) {
lockedHeaderCt.removeAll(false);
normalHeaderCt.removeAll(false);
lockedHeaderCt.add(locked);
normalHeaderCt.add(normal);
lockedGrid.setWidth(lockedWidth);
}
},
disable: function() {
var topGrid = this.lockable;
topGrid.lockedGrid.headerCt.disable();
topGrid.normalGrid.headerCt.disable();
},
enable: function() {
var topGrid = this.lockable;
topGrid.lockedGrid.headerCt.enable();
topGrid.normalGrid.headerCt.enable();
}
});
Ext.define('Ext.grid.locking.View', {
alternateClassName: 'Ext.grid.LockingView',
requires: [
'Ext.view.AbstractView',
'Ext.view.Table'
],
mixins: [
'Ext.util.Observable',
'Ext.util.StoreHolder',
'Ext.util.Focusable'
],
isLockingView: true,
loadMask: true,
eventRelayRe: /^(beforeitem|beforecontainer|item|container|cell|refresh)/,
constructor: function(config) {
var me = this,
lockedView, normalView;
me.ownerGrid = config.ownerGrid;
me.ownerGrid.view = me;
me.navigationModel = config.locked.xtype === 'treepanel' ? new Ext.tree.NavigationModel(me) : new Ext.grid.NavigationModel(me);
config.locked.viewConfig.bindStore = Ext.emptyFn;
config.normal.viewConfig.bindStore = me.subViewBindStore;
config.normal.viewConfig.isNormalView = config.locked.viewConfig.isLockedView = true;
config.locked.viewConfig.beforeLayout = config.normal.viewConfig.beforeLayout = me.beforeLayout;
config.locked.viewConfig.navigationModel = config.normal.viewConfig.navigationModel = me.navigationModel;
me.lockedGrid = me.ownerGrid.lockedGrid = Ext.ComponentManager.create(config.locked);
me.lockedView = lockedView = me.lockedGrid.getView();
if (me.ownerGrid.shrinkWrapLocked) {
me.lockedGrid.width += (Ext.num(lockedView.getSelectionModel().headerWidth, 0) + (me.lockedGrid.getVisibleColumnManager().getColumns().length ? 1 : 0));
}
me.selModel = config.normal.viewConfig.selModel = lockedView.getSelectionModel();
if (me.lockedGrid.isTree) {
me.lockedView.animate = false;
config.normal.store = lockedView.store;
config.normal.viewConfig.stripeRows = me.lockedView.stripeRows;
config.normal.rowLines = me.lockedGrid.rowLines;
}
me.normalGrid = me.ownerGrid.normalGrid = Ext.ComponentManager.create(config.normal);
lockedView.lockingPartner = normalView = me.normalView = me.normalGrid.getView();
normalView.lockingPartner = lockedView;
me.loadMask = (config.loadMask !== undefined) ? config.loadMask : me.loadMask;
me.mixins.observable.constructor.call(me);
me.relayEvents(lockedView, Ext.view.Table.events);
me.relayEvents(normalView, Ext.view.Table.events);
normalView.on({
scope: me,
itemmouseleave: me.onItemMouseLeave,
itemmouseenter: me.onItemMouseEnter
});
lockedView.on({
scope: me,
itemmouseleave: me.onItemMouseLeave,
itemmouseenter: me.onItemMouseEnter
});
me.ownerGrid.on({
render: me.onPanelRender,
scope: me
});
me.loadingText = normalView.loadingText;
me.loadingCls = normalView.loadingCls;
me.loadingUseMsg = normalView.loadingUseMsg;
me.itemSelector = me.getItemSelector();
me.all = normalView.all;
me.bindStore(normalView.dataSource, true, 'dataSource');
},
subViewBindStore: function(dataSource) {
var me = this,
selModel = me.getSelectionModel();
if (dataSource !== null && !me.ownerGrid.reconfiguring) {
dataSource = me.store;
}
selModel.bindStore(dataSource);
selModel.bindComponent(me);
},
beforeLayout: function() {
var me = this.ownerCt.ownerLockable.view,
lockedView = me.lockedGrid.view,
normalView = me.normalGrid.view;
if (!me.relayingOperation) {
if (me.lockedGrid.isVisible()) {
if (lockedView.refreshNeeded) {
lockedView.doFirstRefresh(lockedView.dataSource);
}
}
if (normalView.refreshNeeded) {
normalView.doFirstRefresh(normalView.dataSource);
}
}
},
onPanelRender: function() {
var me = this,
mask = me.loadMask,
cfg = {
target: me.ownerGrid,
msg: me.loadingText,
msgCls: me.loadingCls,
useMsg: me.loadingUseMsg,
store: me.ownerGrid.store
};
me.el = me.ownerGrid.getTargetEl();
me.rendered = true;
me.initFocusableEvents();
me.fireEvent('render', me);
if (mask) {
if (Ext.isObject(mask)) {
cfg = Ext.apply(cfg, mask);
}
me.loadMask = new Ext.LoadMask(cfg);
}
},
getRefOwner: function() {
return this.ownerGrid;
},
getVisibleColumnManager: function() {
return this.ownerGrid.getVisibleColumnManager();
},
getTopLevelVisibleColumnManager: function() {
return this.ownerGrid.getVisibleColumnManager();
},
getGridColumns: function() {
return this.getVisibleColumnManager().getColumns();
},
getEl: function(column) {
return this.getViewForColumn(column).getEl();
},
getCellSelector: function() {
return this.normalView.getCellSelector();
},
getItemSelector: function() {
return this.normalView.getItemSelector();
},
getViewForColumn: function(column) {
var view = this.lockedView,
inLocked;
view.headerCt.cascade(function(col) {
if (col === column) {
inLocked = true;
return false;
}
});
return inLocked ? view : this.normalView;
},
onItemMouseEnter: function(view, record) {
var me = this,
locked = me.lockedView,
other = me.normalView,
item;
if (view.trackOver) {
if (view !== locked) {
other = locked;
}
item = other.getNode(record);
other.highlightItem(item);
}
},
onItemMouseLeave: function(view, record) {
var me = this,
locked = me.lockedView,
other = me.normalView;
if (view.trackOver) {
if (view !== locked) {
other = locked;
}
other.clearHighlight();
}
},
relayFn: function(name, args) {
args = args || [];
var me = this,
view = me.lockedView;
me.relayingOperation = true;
view[name].apply(view, args);
view = me.normalView;
view[name].apply(view, args);
me.relayingOperation = false;
},
getSelectionModel: function() {
return this.normalView.getSelectionModel();
},
getNavigationModel: function() {
return this.navigationModel;
},
getStore: function() {
return this.ownerGrid.store;
},
onBindStore: function(store, initial, propName) {
var me = this,
lockedView = me.lockedView,
normalView = me.normalView;
if (normalView.componentLayoutCounter && !(lockedView.blockRefresh && normalView.blockRefresh)) {
Ext.suspendLayouts();
lockedView.doFirstRefresh(store);
normalView.doFirstRefresh(store);
Ext.resumeLayouts(true);
}
},
getStoreListeners: function() {
var me = this;
return {
refresh: me.onDataRefresh,
replace: me.onReplace,
add: me.onAdd,
remove: me.onRemove,
update: me.onUpdate,
clear: me.refresh,
beginupdate: me.onBeginUpdate,
endupdate: me.onEndUpdate
};
},
onBeginUpdate: function() {
Ext.suspendLayouts();
this.relayFn('onBeginUpdate', arguments);
Ext.resumeLayouts(true);
},
onEndUpdate: function() {
Ext.suspendLayouts();
this.relayFn('onEndUpdate', arguments);
Ext.resumeLayouts(true);
},
onDataRefresh: function() {
Ext.suspendLayouts();
this.relayFn('onDataRefresh', arguments);
Ext.resumeLayouts(true);
},
onReplace: function() {
Ext.suspendLayouts();
this.relayFn('onReplace', arguments);
Ext.resumeLayouts(true);
},
onAdd: function() {
Ext.suspendLayouts();
this.relayFn('onAdd', arguments);
Ext.resumeLayouts(true);
},
onRemove: function() {
Ext.suspendLayouts();
this.relayFn('onRemove', arguments);
Ext.resumeLayouts(true);
},
onUpdate: function() {
var normalView = this.normalGrid.view;
Ext.suspendLayouts();
this.relayFn('onUpdate', arguments);
if (normalView.hasVariableRowHeight() && normalView.bufferedRenderer) {
Ext.on({
afterlayout: normalView.bufferedRenderer.refreshSize,
scope: normalView.bufferedRenderer,
single: true
});
}
Ext.resumeLayouts(true);
},
refresh: function() {
Ext.suspendLayouts();
this.relayFn('refresh', arguments);
Ext.resumeLayouts(true);
},
getNode: function(nodeInfo) {
return this.normalView.getNode(nodeInfo);
},
getRow: function(nodeInfo) {
return this.normalView.getRow(nodeInfo);
},
getCell: function(record, column) {
var view = this.getViewForColumn(column),
row = view.getRow(record);
return Ext.fly(row).down(column.getCellSelector());
},
indexOf: function(record) {
var result = this.lockedView.indexOf(record);
if (!result) {
result = this.normalView.indexOf(record);
}
return result;
},
focus: function() {
var target = this.ownerGrid.down('>tablepanel:not(hidden)>tableview');
if (target) {
target.focus();
}
},
focusRow: function(row) {
var view,
lastFocused = this.getNavigationModel().lastFocused;
view = lastFocused ? lastFocused.view : this.normalView;
view.focusRow(row);
},
focusCell: function(position) {
position.view.focusCell(position);
},
onRowFocus: function() {
this.relayFn('onRowFocus', arguments);
},
isVisible: function(deep) {
return this.ownerGrid.isVisible(deep);
},
getFocusEl: function() {
var view,
lastFocused = this.getNavigationModel().lastFocused;
view = lastFocused ? lastFocused.view : this.normalView;
return view.getFocusEl();
},
getCellInclusive: function(pos, returnDom) {
var col = pos.column,
lockedSize = this.lockedGrid.getColumnManager().getColumns().length;
if (col >= lockedSize) {
pos = Ext.apply({}, pos);
pos.column -= lockedSize;
return this.normalView.getCellInclusive(pos, returnDom);
} else {
return this.lockedView.getCellInclusive(pos, returnDom);
}
},
getHeaderByCell: function(cell) {
if (cell) {
return this.getVisibleColumnManager().getHeaderById(cell.getAttribute('data-columnId'));
}
return false;
},
onRowSelect: function() {
this.relayFn('onRowSelect', arguments);
},
onRowDeselect: function() {
this.relayFn('onRowDeselect', arguments);
},
onCellSelect: function(cellContext) {
cellContext.column.getView().onCellSelect({
record: cellContext.record,
column: cellContext.column
});
},
onCellDeselect: function(cellContext) {
cellContext.column.getView().onCellDeselect({
record: cellContext.record,
column: cellContext.column
});
},
getCellByPosition: function(pos, returnDom) {
var me = this,
view = pos.view,
col = pos.column;
if (view === me) {
view = col.getView();
}
return view.getCellByPosition(pos, returnDom);
},
getRecord: function(node) {
var result = this.lockedView.getRecord(node);
if (!result) {
result = this.normalView.getRecord(node);
}
return result;
},
scrollBy: function() {
var normal = this.normalView;
normal.scrollBy.apply(normal, arguments);
},
ensureVisible: function() {
var normal = this.normalView;
normal.ensureVisible.apply(normal, arguments);
},
disable: function() {
this.relayFn('disable', arguments);
},
enable: function() {
this.relayFn('enable', arguments);
},
addElListener: function() {
this.relayFn('addElListener', arguments);
},
refreshNode: function() {
this.relayFn('refreshNode', arguments);
},
addRowCls: function() {
this.relayFn('addRowCls', arguments);
},
removeRowCls: function() {
this.relayFn('removeRowCls', arguments);
},
destroy: function() {
var me = this;
me.bindStore(null, false, 'dataSource');
me.isDestroyed = true;
me.clearListeners();
Ext.destroy(me.loadMask, me.navigationModel, me.selModel);
}
}, function() {
this.borrow(Ext.Component, [
'up'
]);
this.borrow(Ext.view.AbstractView, [
'doFirstRefresh',
'applyFirstRefresh'
]);
this.borrow(Ext.view.Table, [
'cellSelector',
'selectedCellCls',
'selectedItemCls'
]);
});
Ext.define('Ext.grid.locking.Lockable', {
alternateClassName: 'Ext.grid.Lockable',
requires: [
'Ext.grid.locking.View',
'Ext.grid.header.Container',
'Ext.grid.locking.HeaderContainer',
'Ext.view.Table'
],
syncRowHeight: true,
headerCounter: 0,
scrollDelta: 40,
lockedGridCls: Ext.baseCSSPrefix + 'grid-inner-locked',
normalGridCls: Ext.baseCSSPrefix + 'grid-inner-normal',
unlockText: 'Unlock',
lockText: 'Lock',
bothCfgCopy: [
'invalidateScrollerOnRefresh',
'hideHeaders',
'enableColumnHide',
'enableColumnMove',
'enableColumnResize',
'sortableColumns',
'multiColumnSort',
'columnLines',
'rowLines',
'variableRowHeight',
'numFromEdge',
'trailingBufferZone',
'leadingBufferZone',
'scrollToLoadBuffer'
],
normalCfgCopy: [
'verticalScroller',
'verticalScrollDock',
'verticalScrollerType',
'scroll'
],
lockedCfgCopy: [],
determineXTypeToCreate: function(lockedSide) {
var me = this,
typeToCreate, xtypes, xtypesLn, xtype, superxtype;
if (me.subGridXType) {
typeToCreate = me.subGridXType;
} else {
if (!lockedSide) {
return 'gridpanel';
}
xtypes = this.getXTypes().split('/');
xtypesLn = xtypes.length;
xtype = xtypes[xtypesLn - 1];
superxtype = xtypes[xtypesLn - 2];
if (superxtype !== 'tablepanel') {
typeToCreate = superxtype;
} else {
typeToCreate = xtype;
}
}
return typeToCreate;
},
injectLockable: function() {
this.focusable = false;
this.lockable = true;
this.hasView = true;
var me = this,
scrollbarSize = Ext.getScrollbarSize(),
scrollbarWidth = scrollbarSize.width,
store = me.store = Ext.StoreManager.lookup(me.store),
lockedViewConfig = me.lockedViewConfig,
normalViewConfig = me.normalViewConfig,
Obj = Ext.Object,
allFeatures,
allPlugins, lockedGrid, normalGrid, i, columns, lockedHeaderCt, normalHeaderCt, listeners,
viewConfig = me.viewConfig,
loadMaskCfg = viewConfig && viewConfig.loadMask,
loadMask = (loadMaskCfg !== undefined) ? loadMaskCfg : me.loadMask,
bufferedRenderer = me.bufferedRenderer,
clipVertLockedScrollbar = scrollbarWidth > 0 && Ext.supports.touchScroll !== 2;
allFeatures = me.constructLockableFeatures();
me.features = null;
allPlugins = me.constructLockablePlugins();
me.plugins = allPlugins.topPlugins;
lockedGrid = {
id: me.id + '-locked',
isLocked: true,
bufferedRenderer: bufferedRenderer,
ownerGrid: me,
ownerLockable: me,
xtype: me.determineXTypeToCreate(true),
store: store,
reserveScrollbar: clipVertLockedScrollbar,
scrollable: {
indicators: {
x: true,
y: false
}
},
scrollerOwner: false,
animate: false,
border: false,
cls: me.lockedGridCls,
isLayoutRoot: function() {
return this.floatedFromCollapse || me.normalGrid.floatedFromCollapse;
},
features: allFeatures.lockedFeatures,
plugins: allPlugins.lockedPlugins
};
normalGrid = {
id: me.id + '-normal',
isLocked: false,
bufferedRenderer: bufferedRenderer,
ownerGrid: me,
ownerLockable: me,
xtype: me.determineXTypeToCreate(),
store: store,
reserveScrollbar: me.reserveScrollbar,
scrollerOwner: false,
border: false,
cls: me.normalGridCls,
isLayoutRoot: function() {
return this.floatedFromCollapse || me.lockedGrid.floatedFromCollapse;
},
features: allFeatures.normalFeatures,
plugins: allPlugins.normalPlugins
};
me.addCls(Ext.baseCSSPrefix + 'grid-locked');
Ext.copyTo(normalGrid, me, me.bothCfgCopy, true);
Ext.copyTo(lockedGrid, me, me.bothCfgCopy, true);
Ext.copyTo(normalGrid, me, me.normalCfgCopy, true);
Ext.copyTo(lockedGrid, me, me.lockedCfgCopy, true);
Ext.apply(normalGrid, me.normalGridConfig);
Ext.apply(lockedGrid, me.lockedGridConfig);
for (i = 0; i < me.normalCfgCopy.length; i++) {
delete me[me.normalCfgCopy[i]];
}
for (i = 0; i < me.lockedCfgCopy.length; i++) {
delete me[me.lockedCfgCopy[i]];
}
me.addStateEvents([
'lockcolumn',
'unlockcolumn'
]);
columns = me.processColumns(me.columns || [], lockedGrid);
lockedGrid.columns = columns.locked;
if (!lockedGrid.columns.items.length) {
lockedGrid.hidden = true;
}
normalGrid.columns = columns.normal;
if (!normalGrid.columns.items.length) {
normalGrid.hidden = true;
}
normalGrid.flex = 1;
lockedGrid.viewConfig = lockedViewConfig = (lockedViewConfig ? Obj.chain(lockedViewConfig) : {});
normalGrid.viewConfig = normalViewConfig = (normalViewConfig ? Obj.chain(normalViewConfig) : {});
lockedViewConfig.loadingUseMsg = false;
lockedViewConfig.loadMask = false;
if (clipVertLockedScrollbar) {
lockedViewConfig.margin = '0 -' + scrollbarWidth + ' 0 0';
}
normalViewConfig.loadMask = false;
if (viewConfig && viewConfig.id) {
Ext.log.warn('id specified on Lockable viewConfig, it will be shared between both views: "' + viewConfig.id + '"');
}
Ext.applyIf(lockedViewConfig, viewConfig);
Ext.applyIf(normalViewConfig, viewConfig);
if (!me.initialConfig.layout) {
me.layout = {
type: 'hbox',
align: 'stretch'
};
}
me.getLayout();
if (me.layout.type === 'border') {
if (me.split) {
lockedGrid.split = true;
}
if (!lockedGrid.region) {
lockedGrid.region = 'west';
}
if (!normalGrid.region) {
normalGrid.region = 'center';
}
me.addCls(Ext.baseCSSPrefix + 'grid-locked-split');
}
if (!(me.layout instanceof Ext.layout.container.Box)) {
me.split = false;
}
me.view = new Ext.grid.locking.View({
loadMask: loadMask,
locked: lockedGrid,
normal: normalGrid,
ownerGrid: me
});
lockedGrid = me.lockedGrid;
normalGrid = me.normalGrid;
normalGrid.getView().getScrollable().addPartner(lockedGrid.getView().getScrollable(), 'y');
if (scrollbarSize.height && Ext.supports.touchScroll !== 2) {
lockedGrid.on({
afterlayout: me.afterLockedViewLayout,
scope: me
});
lockedGrid.getView().getOverflowStyle();
}
lockedHeaderCt = lockedGrid.headerCt;
normalHeaderCt = normalGrid.headerCt;
if (clipVertLockedScrollbar) {
lockedHeaderCt.reserveScrollbar = false;
}
me.headerCt = me.view.headerCt = new Ext.grid.locking.HeaderContainer(me);
lockedHeaderCt.lockedCt = true;
lockedHeaderCt.lockableInjected = true;
normalHeaderCt.lockableInjected = true;
lockedHeaderCt.on({
add: me.delaySyncLockedWidth,
remove: me.delaySyncLockedWidth,
columnshow: me.delaySyncLockedWidth,
columnhide: me.delaySyncLockedWidth,
sortchange: me.onLockedHeaderSortChange,
columnresize: me.delaySyncLockedWidth,
scope: me
});
normalHeaderCt.on({
add: me.delaySyncLockedWidth,
remove: me.delaySyncLockedWidth,
columnshow: me.delaySyncLockedWidth,
columnhide: me.delaySyncLockedWidth,
sortchange: me.onNormalHeaderSortChange,
scope: me
});
me.modifyHeaderCt();
me.items = [
lockedGrid
];
if (me.split) {
me.addCls(Ext.baseCSSPrefix + 'grid-locked-split');
me.items[1] = {
xtype: 'splitter'
};
}
me.items.push(normalGrid);
me.relayHeaderCtEvents(lockedHeaderCt);
me.relayHeaderCtEvents(normalHeaderCt);
me.storeRelayers = me.relayEvents(store, [
'filterchange',
'groupchange'
]);
me.gridRelayers = me.relayEvents(normalGrid, [
'viewready'
]);
},
getLockingViewConfig: function() {
return {
xclass: 'Ext.grid.locking.View',
locked: this.lockedGrid,
normal: this.normalGrid,
panel: this
};
},
processColumns: function(columns, lockedGrid) {
var me = this,
i, len, column,
cp = new Ext.grid.header.Container(),
lockedHeaders = [],
normalHeaders = [],
lockedHeaderCt = {
itemId: 'lockedHeaderCt',
stretchMaxPartner: '^^>>#normalHeaderCt',
items: lockedHeaders
},
normalHeaderCt = {
itemId: 'normalHeaderCt',
stretchMaxPartner: '^^>>#lockedHeaderCt',
items: normalHeaders
},
result = {
lockedWidth: lockedGrid.width || 0,
locked: lockedHeaderCt,
normal: normalHeaderCt
},
shrinkWrapLocked = !(lockedGrid.width || lockedGrid.flex),
copy;
if (!me.hasOwnProperty('shrinkWrapLocked')) {
me.shrinkWrapLocked = shrinkWrapLocked;
}
if (Ext.isObject(columns)) {
Ext.applyIf(lockedHeaderCt, columns);
Ext.applyIf(normalHeaderCt, columns);
copy = Ext.apply({}, columns);
delete copy.items;
Ext.apply(cp, copy);
columns = columns.items;
}
cp.constructing = true;
for (i = 0 , len = columns.length; i < len; ++i) {
column = columns[i];
if (!column.isComponent) {
column = cp.applyDefaults(column);
column.initOwnerCt = cp;
column = cp.lookupComponent(column);
delete column.initOwnerCt;
}
column.processed = true;
if (column.locked || column.autoLock) {
if (shrinkWrapLocked && !column.hidden) {
result.lockedWidth += me.getColumnWidth(column) || cp.defaultWidth;
}
lockedHeaders.push(column);
} else {
normalHeaders.push(column);
}
if (!column.headerId) {
column.headerId = (column.initialConfig || column).id || ('h' + (++me.headerCounter));
}
}
me.fireEvent('processcolumns', me, lockedHeaders, normalHeaders);
cp.destroy();
if (shrinkWrapLocked) {
lockedGrid.width = result.lockedWidth;
}
return result;
},
getColumnWidth: function(column) {
var result = column.width || 0,
subcols, len, i;
if (column.flex) {
Ext.Error.raise("Locked columns in an unsized locked side do NOT support a flex width. You must set a width on the " + column.text + "column.");
}
if (!result && column.isGroupHeader) {
subcols = column.items.items;
len = subcols.length;
for (i = 0; i < len; i++) {
result += this.getColumnWidth(subcols[i]);
}
}
return result;
},
afterLockedViewLayout: function() {
var me = this,
lockedGrid = me.lockedGrid,
normalGrid = me.normalGrid,
lockedView = lockedGrid.getView(),
normalView = normalGrid.getView(),
spacerHeight = Ext.getScrollbarSize().height,
lockedViewHorizScrollBar = (lockedView.scrollFlags.x && lockedGrid.headerCt.tooNarrow ? spacerHeight : 0),
normalViewHorizScrollBar = (normalView.scrollFlags.x && normalGrid.headerCt.tooNarrow ? spacerHeight : 0),
normalScroller = normalView.getScrollable(),
lockedScroller = lockedView.getScrollable();
if (lockedViewHorizScrollBar !== normalViewHorizScrollBar) {
if (lockedViewHorizScrollBar) {
normalScroller.setX('scroll');
lockedScroller.setX(true);
} else {
lockedScroller.setX('scroll');
normalScroller.setX(true);
}
} else {
lockedScroller.setX(normalViewHorizScrollBar ? 'scroll' : true);
normalScroller.setX(true);
}
},
ensureLockedVisible: function() {
this.lockedGrid.ensureVisible.apply(this.lockedGrid, arguments);
this.normalGrid.ensureVisible.apply(this.normalGrid, arguments);
},
onLockedViewMouseWheel: function(e) {
var me = this,
deltaY = -me.scrollDelta * e.getWheelDeltas().y,
lockedView = me.lockedGrid.getView(),
lockedViewElDom = lockedView.el.dom,
scrollTop, verticalCanScrollDown, verticalCanScrollUp;
if (!me.ignoreMousewheel) {
if (lockedViewElDom) {
scrollTop = lockedView.getScrollY();
verticalCanScrollDown = scrollTop !== lockedViewElDom.scrollHeight - lockedViewElDom.clientHeight;
verticalCanScrollUp = scrollTop !== 0;
}
if ((deltaY < 0 && verticalCanScrollUp) || (deltaY > 0 && verticalCanScrollDown)) {
e.stopEvent();
scrollTop += deltaY;
lockedView.setScrollY(scrollTop);
me.normalGrid.getView().setScrollY(scrollTop);
me.onNormalViewScroll();
}
}
},
onLockedViewScroll: function() {
var me = this,
lockedView = me.lockedGrid.getView(),
normalView = me.normalGrid.getView(),
lockedScrollTop = lockedView.getScrollY(),
normalScrollTop = normalView.getScrollY(),
normalTable, lockedTable;
if (normalScrollTop !== lockedScrollTop) {
normalView.setScrollY(lockedScrollTop);
if (normalView.bufferedRenderer) {
lockedTable = lockedView.body.dom;
normalTable = normalView.body.dom;
normalTable.style.position = 'absolute';
normalTable.style.top = lockedTable.style.top;
}
}
},
onNormalViewScroll: function() {
var me = this,
lockedView = me.lockedGrid.getView(),
normalView = me.normalGrid.getView(),
lockedScrollTop = lockedView.getScrollY(),
normalScrollTop = normalView.getScrollY(),
lockedRowContainer;
if (normalScrollTop !== lockedScrollTop) {
lockedView.setScrollY(normalScrollTop);
if (normalView.bufferedRenderer) {
lockedRowContainer = lockedView.body;
if (lockedRowContainer.dom) {
lockedRowContainer.dom.style.position = 'absolute';
lockedRowContainer.translate(null, normalView.bufferedRenderer.bodyTop);
}
}
}
},
syncRowHeights: function() {
if (!this.isDestroyed) {
var me = this,
normalView = me.normalGrid.getView(),
lockedView = me.lockedGrid.getView(),
normalSync = normalView.syncRowHeightBegin(),
lockedSync = lockedView.syncRowHeightBegin(),
scrollTop;
normalView.syncRowHeightMeasure(normalSync);
lockedView.syncRowHeightMeasure(lockedSync);
normalView.syncRowHeightFinish(normalSync, lockedSync);
lockedView.syncRowHeightFinish(lockedSync, normalSync);
scrollTop = normalView.getScrollY();
lockedView.setScrollY(scrollTop);
}
},
modifyHeaderCt: function() {
var me = this;
me.lockedGrid.headerCt.getMenuItems = me.getMenuItems(me.lockedGrid.headerCt.getMenuItems, true);
me.normalGrid.headerCt.getMenuItems = me.getMenuItems(me.normalGrid.headerCt.getMenuItems, false);
me.lockedGrid.headerCt.showMenuBy = Ext.Function.createInterceptor(me.lockedGrid.headerCt.showMenuBy, me.showMenuBy);
me.normalGrid.headerCt.showMenuBy = Ext.Function.createInterceptor(me.normalGrid.headerCt.showMenuBy, me.showMenuBy);
},
onUnlockMenuClick: function() {
this.unlock();
},
onLockMenuClick: function() {
this.lock();
},
showMenuBy: function(clickEvent, t, header) {
var menu = this.getMenu(),
unlockItem = menu.down('#unlockItem'),
lockItem = menu.down('#lockItem'),
sep = unlockItem.prev();
if (header.lockable === false) {
sep.hide();
unlockItem.hide();
lockItem.hide();
} else {
sep.show();
unlockItem.show();
lockItem.show();
if (!unlockItem.initialConfig.disabled) {
unlockItem.setDisabled(header.lockable === false);
}
if (!lockItem.initialConfig.disabled) {
lockItem.setDisabled(!header.isLockable());
}
}
},
getMenuItems: function(getMenuItems, locked) {
var me = this,
unlockText = me.unlockText,
lockText = me.lockText,
unlockCls = Ext.baseCSSPrefix + 'hmenu-unlock',
lockCls = Ext.baseCSSPrefix + 'hmenu-lock',
unlockHandler = me.onUnlockMenuClick.bind(me),
lockHandler = me.onLockMenuClick.bind(me);
return function() {
var o = getMenuItems.call(this);
o.push('-', {
itemId: 'unlockItem',
iconCls: unlockCls,
text: unlockText,
handler: unlockHandler,
disabled: !locked
});
o.push({
itemId: 'lockItem',
iconCls: lockCls,
text: lockText,
handler: lockHandler,
disabled: locked
});
return o;
};
},
syncTaskDelay: 1,
delaySyncLockedWidth: function() {
var me = this,
task = me.syncLockedWidthTask;
if (!task) {
task = me.syncLockedWidthTask = new Ext.util.DelayedTask(me.syncLockedWidth, me);
}
if (me.syncTaskDelay === 0) {
me.syncLockedWidth();
} else {
task.delay(1);
}
},
syncLockedWidth: function() {
var me = this,
rendered = me.rendered,
locked = me.lockedGrid,
lockedView = locked.view,
normal = me.normalGrid,
lockedColCount = locked.getVisibleColumnManager().getColumns().length,
normalColCount = normal.getVisibleColumnManager().getColumns().length,
task = me.syncLockedWidthTask;
if (task) {
task.cancel();
}
Ext.suspendLayouts();
if (normalColCount) {
normal.show();
if (lockedColCount) {
if (rendered && me.shrinkWrapLocked && !locked.headerCt.forceFit) {
delete locked.flex;
locked.setWidth(locked.headerCt.getTableWidth() + locked.el.getBorderWidth('lr'));
}
locked.addCls(me.lockedGridCls);
locked.show();
if (me.split) {
me.child('splitter').show();
}
} else {
if (rendered) {
locked.getView().clearViewEl(true);
}
locked.hide();
if (me.split) {
me.child('splitter').hide();
}
}
if (Ext.supports.touchScroll !== 2 && Ext.Component.pendingLayouts) {
lockedView.getScrollable().setX(true);
}
if (rendered) {
me.ignoreMousewheel = lockedView.scrollFlags.y;
}
} else
{
normal.hide();
if (rendered) {
lockedView.getEl().setStyle('border-bottom-width', '0');
}
locked.flex = 1;
delete locked.width;
locked.removeCls(me.lockedGridCls);
locked.show();
me.ignoreMousewheel = true;
}
Ext.resumeLayouts(true);
return [
lockedColCount,
normalColCount
];
},
onLockedHeaderSortChange: Ext.emptyFn,
onNormalHeaderSortChange: Ext.emptyFn,
lock: function(activeHd, toIdx, toCt) {
var me = this,
normalGrid = me.normalGrid,
lockedGrid = me.lockedGrid,
normalView = normalGrid.view,
lockedView = lockedGrid.view,
normalHCt = normalGrid.headerCt,
refreshFlags, ownerCt, hadFocus;
activeHd = activeHd || normalHCt.getMenu().activeHeader;
hadFocus = activeHd.hasFocus;
toCt = toCt || lockedGrid.headerCt;
ownerCt = activeHd.ownerCt;
if (!activeHd.isLockable()) {
return;
}
if (activeHd.flex) {
activeHd.width = activeHd.getWidth();
activeHd.flex = null;
}
Ext.suspendLayouts();
if (lockedGrid.hidden) {
lockedGrid.show();
}
normalView.blockRefresh = lockedView.blockRefresh = true;
ownerCt.remove(activeHd, false);
activeHd.locked = true;
if (Ext.isDefined(toIdx)) {
toCt.insert(toIdx, activeHd);
} else {
toCt.add(activeHd);
}
normalView.blockRefresh = lockedView.blockRefresh = false;
refreshFlags = me.syncLockedWidth();
if (refreshFlags[0]) {
lockedGrid.getView().refreshView();
}
if (refreshFlags[1]) {
normalGrid.getView().refreshView();
}
Ext.resumeLayouts(true);
if (hadFocus) {
activeHd.focus();
}
me.fireEvent('lockcolumn', me, activeHd);
},
unlock: function(activeHd, toIdx, toCt) {
var me = this,
normalGrid = me.normalGrid,
lockedGrid = me.lockedGrid,
normalView = normalGrid.view,
lockedView = lockedGrid.view,
lockedHCt = lockedGrid.headerCt,
refreshFlags, hadFocus;
if (!Ext.isDefined(toIdx)) {
toIdx = 0;
}
activeHd = activeHd || lockedHCt.getMenu().activeHeader;
hadFocus = activeHd.hasFocus;
toCt = toCt || normalGrid.headerCt;
Ext.suspendLayouts();
normalView.blockRefresh = lockedView.blockRefresh = true;
activeHd.ownerCt.remove(activeHd, false);
activeHd.locked = false;
toCt.insert(toIdx, activeHd);
normalView.blockRefresh = lockedView.blockRefresh = false;
refreshFlags = me.syncLockedWidth();
if (refreshFlags[0]) {
lockedGrid.getView().refreshView();
}
if (refreshFlags[1]) {
normalGrid.getView().refreshView();
}
Ext.resumeLayouts(true);
if (hadFocus) {
activeHd.focus();
}
me.fireEvent('unlockcolumn', me, activeHd);
},
reconfigureLockable: function(store, columns) {
var me = this,
oldStore = me.store,
lockedGrid = me.lockedGrid,
normalGrid = me.normalGrid,
view;
if (store && store !== oldStore) {
store = Ext.data.StoreManager.lookup(store);
me.store = store;
lockedGrid.view.blockRefresh = normalGrid.view.blockRefresh = true;
lockedGrid.bindStore(store);
view = lockedGrid.view;
view.store = store;
if (!view.dataSource.isFeatureStore) {
view.dataSource = store;
}
if (view.bufferedRenderer) {
view.bufferedRenderer.bindStore(store);
}
normalGrid.bindStore(store);
view = normalGrid.view;
view.store = store;
if (!view.dataSource.isFeatureStore) {
view.dataSource = store;
}
if (view.bufferedRenderer) {
view.bufferedRenderer.bindStore(store);
}
me.view.store = store;
me.view.bindStore(normalGrid.view.dataSource, false, 'dataSource');
lockedGrid.view.blockRefresh = normalGrid.view.blockRefresh = false;
}
if (columns) {
lockedGrid.reconfiguring = normalGrid.reconfiguring = true;
lockedGrid.headerCt.removeAll();
normalGrid.headerCt.removeAll();
columns = me.processColumns(columns, lockedGrid);
lockedGrid.headerCt.add(columns.locked.items);
normalGrid.headerCt.add(columns.normal.items);
lockedGrid.reconfiguring = normalGrid.reconfiguring = false;
me.syncLockedWidth();
}
me.refreshCounter = lockedGrid.view.refreshCounter;
},
afterReconfigureLockable: function() {
var lockedView = this.lockedGrid.getView();
if (this.refreshCounter === lockedView.refreshCounter) {
this.view.refresh();
}
},
constructLockableFeatures: function() {
var features = this.features,
feature, featureClone, lockedFeatures, normalFeatures,
i = 0,
len;
if (features) {
if (!Ext.isArray(features)) {
features = [
features
];
}
lockedFeatures = [];
normalFeatures = [];
len = features.length;
for (; i < len; i++) {
feature = features[i];
if (!feature.isFeature) {
feature = Ext.create('feature.' + feature.ftype, feature);
}
switch (feature.lockableScope) {
case 'locked':
lockedFeatures.push(feature);
break;
case 'normal':
normalFeatures.push(feature);
break;
default:
feature.lockableScope = 'both';
lockedFeatures.push(feature);
normalFeatures.push(featureClone = feature.clone());
featureClone.lockingPartner = feature;
feature.lockingPartner = featureClone;
}
}
}
return {
normalFeatures: normalFeatures,
lockedFeatures: lockedFeatures
};
},
constructLockablePlugins: function() {
var plugins = this.plugins,
plugin, normalPlugin, lockedPlugin, topPlugins, lockedPlugins, normalPlugins,
i = 0,
len, lockableScope, pluginCls;
if (plugins) {
if (!Ext.isArray(plugins)) {
plugins = [
plugins
];
}
topPlugins = [];
lockedPlugins = [];
normalPlugins = [];
len = plugins.length;
for (; i < len; i++) {
plugin = plugins[i];
if (plugin.init) {
lockableScope = plugin.lockableScope;
} else
{
pluginCls = plugin.ptype ? Ext.ClassManager.getByAlias(('plugin.' + plugin.ptype)) : Ext.ClassManager.get(plugin.xclass);
lockableScope = pluginCls.prototype.lockableScope;
}
switch (lockableScope) {
case 'both':
lockedPlugins.push(lockedPlugin = plugin.clonePlugin());
normalPlugins.push(normalPlugin = plugin.clonePlugin());
lockedPlugin.lockingPartner = normalPlugin;
normalPlugin.lockingPartner = lockedPlugin;
Ext.destroy(plugin);
break;
case 'locked':
lockedPlugins.push(plugin);
break;
case 'normal':
normalPlugins.push(plugin);
break;
default:
topPlugins.push(plugin);
}
}
}
return {
topPlugins: topPlugins,
normalPlugins: normalPlugins,
lockedPlugins: lockedPlugins
};
},
destroyLockable: function() {
var me = this,
task = me.syncLockedWidthTask;
if (task) {
task.cancel();
me.syncLockedWidthTask = null;
}
Ext.destroy(me.view, me.headerCt);
}
}, function() {
this.borrow(Ext.Component, [
'constructPlugin'
]);
});
Ext.define('Ext.grid.plugin.BufferedRenderer', {
extend: 'Ext.AbstractPlugin',
alias: 'plugin.bufferedrenderer',
isBufferedRenderer: true,
lockableScope: 'both',
numFromEdge: 2,
trailingBufferZone: 10,
leadingBufferZone: 20,
synchronousRender: true,
scrollToLoadBuffer: 200,
viewSize: 100,
rowHeight: 21,
position: 0,
lastScrollDirection: 1,
bodyTop: 0,
scrollHeight: 0,
loadId: 0,
init: function(grid) {
var me = this,
view = grid.view,
viewListeners = {
scroll: me.onViewScroll,
resize: me.onViewResize,
refresh: me.onViewRefresh,
columnschanged: me.checkVariableRowHeight,
boxready: me.onViewBoxReady,
scope: me,
destroyable: true
},
initialConfig = view.initialConfig;
if (grid.isTree || (grid.ownerLockable && grid.ownerLockable.isTree)) {
view.blockRefresh = false;
if (initialConfig && initialConfig.loadMask === undefined) {
view.loadMask = true;
}
}
if (view.positionBody) {
viewListeners.refresh = me.onViewRefresh;
}
me.grid = grid;
me.view = view;
me.isRTL = view.getInherited().rtl;
view.bufferedRenderer = me;
view.preserveScrollOnRefresh = true;
view.animate = false;
me.bindStore(view.dataSource);
if (view.hasOwnProperty('rowHeight')) {
me.rowHeight = view.rowHeight;
}
me.position = 0;
me.gridListeners = grid.on({
reconfigure: 'onReconfigure',
scope: me,
destroyable: true
});
me.viewListeners = view.on(viewListeners);
},
checkVariableRowHeight: function() {
var me = this,
grid = me.grid;
me.variableRowHeight = me.view.hasVariableRowHeight();
if (grid.ownerLockable) {
grid.ownerLockable.syncRowHeight = me.variableRowHeight;
}
},
bindStore: function(store) {
var me = this,
view = me.view,
dataSource = view.dataSource,
hasFeatureStore = dataSource && dataSource.isFeatureStore;
if (hasFeatureStore === store.isFeatureStore) {
if (me.store) {
me.unbindStore();
}
me.storeListeners = store.on({
scope: me,
groupchange: me.onStoreGroupChange,
clear: me.onStoreClear,
beforeload: me.onBeforeStoreLoad,
load: me.onStoreLoad,
destroyable: true
});
me.store = store;
}
if (me.view.componentLayout.layoutCount) {
delete me.viewSize;
if (store.isBufferedStore) {
store.setViewSize(me.viewSize);
}
me.onViewResize(me.view, 0, me.view.getHeight());
}
},
onReconfigure: function(grid, store) {
if (store && store !== this.store) {
this.bindStore(store);
}
},
unbindStore: function() {
this.storeListeners.destroy();
this.store = null;
},
onBeforeStoreLoad: function() {
var view = this.view;
if (view && view.rendered) {
view.el.dom.style.pointerEvents = 'none';
}
this.disable();
},
onStoreLoad: function() {
var view = this.view;
if (view && view.rendered) {
view.el.dom.style.pointerEvents = '';
}
this.enable();
},
onStoreClear: function() {
var me = this,
view = me.view;
if (view.rendered && !me.store.isDestroyed) {
if (me.scrollTop !== 0) {
me.bodyTop = me.scrollTop = me.position = me.scrollHeight = 0;
me.view.setScrollY(0);
}
me.lastScrollDirection = me.scrollOffset = null;
if (!view.hasOwnProperty('rowHeight')) {
delete me.rowHeight;
}
}
},
onStoreGroupChange: function(store) {
this.refreshSize();
},
onViewBoxReady: function(view) {
this.refreshScroller(view, this.scrollHeight);
},
onViewRefresh: function(view, records) {
var me = this,
rows = view.all,
height;
me.checkVariableRowHeight();
if (!view.componentLayoutCounter && (view.headerCt.down('{flex}') || me.variableRowHeight)) {
view.on({
boxready: Ext.Function.pass(me.onViewRefresh, [
view,
records
], me),
single: true
});
return;
}
if (!view.hasOwnProperty('rowHeight') && rows.getCount()) {
delete me.rowHeight;
}
me.refreshSize();
if (me.refreshing) {
return;
}
if (me.scrollTop !== view.getScrollY()) {
me.onViewScroll();
} else {
if (!me.hasOwnProperty('bodyTop')) {
me.bodyTop = rows.startIndex * me.rowHeight;
view.setScrollY(me.bodyTop);
}
me.setBodyTop(me.bodyTop);
height = view.getHeight();
if (rows.getCount() && height > 0) {
me.onViewResize(view, null, height);
if (records && (rows.getCount() !== records.length)) {
records.length = 0;
records.push.apply(records, me.store.getRange(rows.startIndex, rows.endIndex));
}
}
}
},
refreshSize: function() {
var me = this,
view = me.view,
nodeCache = view.all,
newScrollHeight = me.getScrollHeight();
if (nodeCache.count && nodeCache.endIndex === (me.store.getCount()) - 1) {
newScrollHeight = me.scrollHeight = me.bodyTop + view.body.dom.offsetHeight;
}
else if (newScrollHeight !== me.scrollHeight) {
me.scrollHeight = newScrollHeight;
}
me.stretchView(view, newScrollHeight);
},
onViewResize: function(view, width, height, oldWidth, oldHeight) {
var me = this,
newViewSize;
if (!oldHeight || height !== oldHeight) {
newViewSize = Math.ceil(height / me.rowHeight) + me.trailingBufferZone + me.leadingBufferZone;
me.viewSize = me.setViewSize(newViewSize);
me.viewClientHeight = view.el.dom.clientHeight;
}
if (view.touchScroll === 2) {
view.getScrollable().setElementSize(null);
}
},
onWrappedColumnWidthChange: function(oldWidth, newWidth) {
var me = this,
view = me.view;
if (me.store.getCount() && me.bodyTop) {
me.refreshSize();
me.setViewSize(Math.ceil(view.getHeight() / me.rowHeight) + me.trailingBufferZone + me.leadingBufferZone);
if (me.viewSize >= me.store.getCount()) {
me.setBodyTop(0);
}
else if (newWidth > oldWidth && me.bodyTop + view.body.dom.offsetHeight - 1 > me.scrollHeight) {
me.setBodyTop(Math.max(0, me.scrollHeight - view.body.dom.offsetHeight));
}
else if (me.bodyTop > me.scrollTop || me.bodyTop + view.body.dom.offsetHeight < me.scrollTop + view.getHeight(true)) {
me.setBodyTop(me.scrollTop - me.trailingBufferZone * me.rowHeight);
}
}
},
stretchView: function(view, scrollRange) {
var me = this,
recordCount = me.store.getCount(),
el, stretcherSpec;
if (me.scrollTop > scrollRange) {
me.position = me.scrollTop = scrollRange - view.body.dom.offsetHeight;
view.setScrollY(me.scrollTop);
}
if (me.bodyTop > scrollRange) {
view.body.translate(null, me.bodyTop = me.position);
}
if (view.touchScroll) {
if (view.getScrollable()) {
me.refreshScroller(view, scrollRange);
} else if (!me.pendingScrollerRefresh) {
view.on({
boxready: function() {
me.refreshScroller(view, scrollRange);
me.pendingScrollerRefresh = false;
},
single: true
});
me.pendingScrollerRefresh = true;
}
}
if (!Ext.supports.touchScroll || Ext.supports.touchScroll === 1) {
if (!me.stretcher) {
el = view.getTargetEl();
if (view.refreshCounter) {
view.fixedNodes++;
}
stretcherSpec = {
role: 'presentation',
style: {
width: '1px',
height: '1px',
'marginTop': (scrollRange - 1) + 'px',
position: 'absolute'
}
};
stretcherSpec.style[me.isRTL ? 'right' : 'left'] = 0;
me.stretcher = el.createChild(stretcherSpec, el.dom.firstChild);
}
if (me.hasOwnProperty('viewSize') && recordCount <= me.viewSize) {
me.stretcher.dom.style.display = 'none';
} else {
me.stretcher.dom.style.marginTop = (scrollRange - 1) + 'px';
me.stretcher.dom.style.display = '';
}
}
},
refreshScroller: function(view, scrollRange) {
var scroller = view.getScrollable();
if (scroller) {
scroller.setSize({
x: view.headerCt.getTableWidth(),
y: scrollRange
});
}
},
setViewSize: function(viewSize, fromLockingPartner) {
var me = this,
store = me.store,
view = me.view,
rows = view.all,
elCount = rows.getCount(),
start, end,
lockingPartner = me.view.lockingPartner && me.view.lockingPartner.bufferedRenderer,
diff = elCount - viewSize,
i, j, records, oldRows, newRows, storeCount;
if (lockingPartner && !fromLockingPartner && lockingPartner.view.componentLayoutCounter) {
if (lockingPartner.viewSize > viewSize) {
viewSize = lockingPartner.viewSize;
} else {
lockingPartner.setViewSize(viewSize, true);
}
}
diff = elCount - viewSize;
if (diff) {
me.scrollTop = view.getScrollY();
me.viewSize = viewSize;
if (store.isBufferedStore) {
store.setViewSize(viewSize);
}
if (elCount) {
storeCount = store.getCount();
start = rows.startIndex;
end = Math.min(start + viewSize - 1, storeCount - 1);
if (!(start === rows.startIndex && end === rows.endIndex)) {
if (lockingPartner) {
lockingPartner.disable();
}
if (diff < 0) {
if (storeCount > elCount) {
store.getRange(rows.endIndex + 1, end, {
callback: function(records, start) {
newRows = view.doAdd(records, start);
view.fireEvent('itemadd', records, start, newRows);
}
});
}
} else
{
start = rows.endIndex - (diff - 1);
end = rows.endIndex;
oldRows = rows.slice(start, end + 1);
rows.removeRange(start, end, true);
if (view.hasListeners.itemremove) {
records = store.getRange(start, end);
for (i = end , j = records.length - 1; j >= 0; --i , --j) {
view.fireEvent('itemremove', records[j], i, oldRows[j]);
}
}
}
if (lockingPartner) {
lockingPartner.enable();
}
}
}
}
return viewSize;
},
getViewRange: function() {
var me = this,
rows = me.view.all,
store = me.store,
startIndex = 0;
if (rows.getCount()) {
startIndex = rows.startIndex;
}
else if (store.isBufferedStore) {
if (!store.currentPage) {
store.currentPage = 1;
}
startIndex = rows.startIndex = (store.currentPage - 1) * (store.pageSize || 1);
store.currentPage = 1;
}
if (store.data.getCount()) {
return store.getRange(startIndex, startIndex + (me.viewSize || store.defaultViewSize) - 1);
} else {
return [];
}
},
onReplace: function(store, startIndex, oldRecords, newRecords) {
var me = this,
view = me.view,
rows = view.all,
oldStartIndex,
renderedSize = rows.getCount(),
lastAffectedIndex = startIndex + oldRecords.length - 1,
recordIncrement = newRecords.length - oldRecords.length,
scrollIncrement = recordIncrement * me.rowHeight;
if (startIndex >= rows.startIndex + me.viewSize) {
me.refreshSize();
return;
}
if (renderedSize && lastAffectedIndex < rows.startIndex) {
rows.moveBlock(recordIncrement);
me.refreshSize();
oldStartIndex = rows.startIndex;
if (recordIncrement > 0) {
me.doNotMirror = true;
me.handleViewScroll(-1);
me.doNotMirror = false;
}
if (rows.startIndex === oldStartIndex) {
if (rows.startIndex) {
me.setBodyTop(me.bodyTop += scrollIncrement);
view.suspendEvent('scroll');
view.scrollBy(0, scrollIncrement);
view.resumeEvent('scroll');
me.position = me.scrollTop = view.getScrollY();
}
} else
{
view.suspendEvent('scroll');
view.scrollBy(0, (oldStartIndex - rows.startIndex) * me.rowHeight);
view.resumeEvent('scroll');
}
view.refreshSize(rows.getCount() !== renderedSize);
return;
}
if (renderedSize && startIndex > rows.endIndex) {
me.refreshSize();
if (recordIncrement > 0) {
me.onRangeFetched(null, rows.startIndex, Math.min(store.getCount(), rows.startIndex + me.viewSize) - 1, null, true);
}
view.refreshSize(rows.getCount() !== renderedSize);
return;
}
if (startIndex < rows.startIndex && lastAffectedIndex < rows.endIndex) {
me.refreshView(rows.startIndex - oldRecords.length + newRecords.length);
return;
}
if (startIndex < rows.startIndex && lastAffectedIndex <= rows.endIndex && scrollIncrement) {
view.suspendEvent('scroll');
view.setScrollY(me.position = me.scrollTop += scrollIncrement);
view.resumeEvent('scroll');
}
me.refreshView();
},
scrollTo: function(recordIdx, options) {
var args = arguments,
me = this,
view = me.view,
lockingPartner = view.lockingPartner && view.lockingPartner.grid.isVisible() && view.lockingPartner.bufferedRenderer,
viewDom = view.el.dom,
store = me.store,
total = store.getCount(),
startIdx, endIdx, targetRow, tableTop, groupingFeature, metaGroup, record, direction,
scrollDecrement = 0,
doSelect, doFocus, animate, highlight, callback, scope;
if (options && typeof options === 'object') {
doSelect = options.select;
doFocus = options.focus;
highlight = options.highlight;
animate = options.animate;
callback = options.callback;
scope = options.scope;
} else
{
doSelect = args[1];
callback = args[2];
scope = args[3];
}
if ((groupingFeature = view.dataSource.groupingFeature) && (groupingFeature.collapsible)) {
if (recordIdx.isEntity) {
record = recordIdx;
} else {
record = view.store.getAt(Math.min(Math.max(recordIdx, 0), view.store.getCount() - 1));
}
metaGroup = groupingFeature.getMetaGroup(record);
if (metaGroup && metaGroup.isCollapsed) {
groupingFeature.expand(groupingFeature.getGroup(record).getGroupKey());
total = store.getCount();
}
recordIdx = groupingFeature.indexOf(record);
} else {
if (recordIdx.isEntity) {
record = recordIdx;
recordIdx = store.indexOf(record);
if (recordIdx === -1) {
Ext.Error.raise('Unknown record passed to BufferedRenderer#scrollTo');
return;
}
} else {
recordIdx = Math.min(Math.max(recordIdx, 0), total - 1);
record = store.getAt(recordIdx);
}
}
if (record && (targetRow = view.getNode(record))) {
view.getScrollable().scrollIntoView(targetRow, null, animate, highlight);
me.onViewScroll();
if (doSelect) {
view.selModel.select(record);
}
if (doFocus) {
view.getNavigationModel().setPosition(record, 0);
}
if (callback) {
callback.call(scope || me, recordIdx, record, targetRow);
}
return;
}
if (recordIdx < view.all.startIndex) {
direction = -1;
startIdx = Math.max(Math.min(recordIdx - (Math.floor((me.leadingBufferZone + me.trailingBufferZone) / 2)), total - me.viewSize + 1), 0);
endIdx = Math.min(startIdx + me.viewSize - 1, total - 1);
} else
{
direction = 1;
endIdx = Math.min(recordIdx + (Math.floor((me.leadingBufferZone + me.trailingBufferZone) / 2)), total - 1);
startIdx = Math.max(endIdx - (me.viewSize - 1), 0);
}
tableTop = Math.max(startIdx * me.rowHeight, 0);
store.getRange(startIdx, endIdx, {
callback: function(range, start, end) {
var scroller = view.getScrollable();
me.renderRange(start, end, true, true);
record = store.data.getRange(recordIdx, recordIdx + 1)[0];
targetRow = view.getNode(record);
view.body.translate(null, me.bodyTop = tableTop);
if (direction === 1) {
me.refreshSize();
}
if (lockingPartner) {
lockingPartner.renderRange(start, end, true, true);
me.syncRowHeights();
lockingPartner.view.body.translate(null, lockingPartner.bodyTop = tableTop);
if (direction === 1) {
lockingPartner.refreshSize();
}
}
if (!targetRow) {
return;
}
if (direction === 1) {
scrollDecrement = viewDom.clientHeight - targetRow.offsetHeight;
}
me.position = me.scrollTop = Math.min(Math.max(0, tableTop - view.body.getOffsetsTo(targetRow)[1]) - scrollDecrement, scroller.getSize().y - viewDom.clientHeight);
if (lockingPartner) {
lockingPartner.position = lockingPartner.scrollTop = me.scrollTop;
}
scroller.scrollIntoView(targetRow, null, animate, highlight);
if (doSelect) {
view.selModel.select(record);
}
if (doFocus) {
view.getNavigationModel().setPosition(record, 0);
}
if (callback) {
callback.call(scope || me, recordIdx, record, targetRow);
}
}
});
},
onViewScroll: function() {
var me = this,
store = me.store,
totalCount = (store.getCount()),
vscrollDistance, scrollDirection,
scrollTop = me.scrollTop = me.view.getScrollY();
if (!(me.disabled || totalCount < me.viewSize)) {
vscrollDistance = scrollTop - me.position;
scrollDirection = vscrollDistance > 0 ? 1 : -1;
if (Math.abs(vscrollDistance) >= 20 || (scrollDirection !== me.lastScrollDirection)) {
me.lastScrollDirection = scrollDirection;
me.handleViewScroll(me.lastScrollDirection);
}
}
},
handleViewScroll: function(direction) {
var me = this,
rows = me.view.all,
store = me.store,
viewSize = me.viewSize,
lastItemIndex = (store.getCount()) - 1,
requestStart, requestEnd;
if (direction === -1) {
if (rows.startIndex) {
if (me.topOfViewCloseToEdge()) {
requestStart = Math.max(0, me.getLastVisibleRowIndex() + me.trailingBufferZone - viewSize);
}
}
} else
{
if (rows.endIndex < lastItemIndex) {
if (me.bottomOfViewCloseToEdge()) {
requestStart = Math.max(0, me.getFirstVisibleRowIndex() - me.trailingBufferZone);
}
}
}
if (requestStart == null) {
me.loadId++;
} else
{
requestEnd = Math.min(requestStart + viewSize - 1, lastItemIndex);
if (me.variableRowHeight && requestEnd === rows.endIndex && requestEnd < lastItemIndex) {
requestEnd++;
me.viewSize = viewSize++;
if (store.isBufferedStore) {
store.setViewSize(me.viewSize);
}
}
if (requestStart !== rows.startIndex || requestEnd !== rows.endIndex) {
me.renderRange(requestStart, requestEnd);
return true;
}
}
},
bottomOfViewCloseToEdge: function() {
var me = this;
if (me.variableRowHeight) {
return me.bodyTop + me.view.body.dom.offsetHeight < me.scrollTop + me.view.lastBox.height + (me.numFromEdge * me.rowHeight);
} else {
return (me.view.all.endIndex - me.getLastVisibleRowIndex()) < me.numFromEdge;
}
},
topOfViewCloseToEdge: function() {
var me = this;
if (me.variableRowHeight) {
return me.bodyTop > me.scrollTop - (me.numFromEdge * me.rowHeight);
} else {
return (me.getFirstVisibleRowIndex() - me.view.all.startIndex) < me.numFromEdge;
}
},
refreshView: function(startIndex) {
var me = this,
viewSize = me.viewSize,
rows = me.view.all,
store = me.store,
storeCount = store.getCount(),
maxIndex = storeCount - 1,
endIndex;
if (storeCount < viewSize) {
startIndex = 0;
endIndex = maxIndex;
} else {
startIndex = Math.max(0, Math.min(startIndex == null ? rows.startIndex : startIndex, maxIndex - (viewSize - me.leadingBufferZone) + 1));
endIndex = Math.min(startIndex + viewSize - 1, maxIndex);
if (endIndex - startIndex + 1 > viewSize) {
startIndex = endIndex - viewSize + 1;
}
}
store.getRange(startIndex, endIndex, {
callback: me.doRefreshView,
scope: me
});
},
doRefreshView: function(range, startIndex, endIndex, options) {
var me = this,
view = me.view,
navModel = view.getNavigationModel(),
focusPosition = navModel.getPosition(),
rows = view.all,
previousStartIndex = rows.startIndex,
previousEndIndex = rows.endIndex,
previousFirstItem, previousLastItem,
prevRowCount = rows.getCount(),
newNodes,
viewMoved = startIndex !== rows.startIndex,
calculatedTop, scrollIncrement;
if (view.refreshCounter) {
if (focusPosition && focusPosition.view === view) {
if (focusPosition.rowIdx < startIndex || focusPosition.rowIdx > endIndex) {
focusPosition = null;
} else {
focusPosition = focusPosition.clone();
}
navModel.setPosition();
} else {
focusPosition = null;
}
view.refreshing = me.refreshing = true;
view.clearViewEl(true);
view.refreshCounter++;
if (range.length) {
newNodes = view.doAdd(range, startIndex);
if (viewMoved) {
previousFirstItem = rows.item(previousStartIndex, true);
previousLastItem = rows.item(previousEndIndex, true);
if (previousFirstItem) {
scrollIncrement = -previousFirstItem.offsetTop;
} else if (previousLastItem) {
scrollIncrement = previousLastItem.offsetTop + previousLastItem.offsetHeight;
}
if (scrollIncrement) {
me.setBodyTop(me.bodyTop += scrollIncrement);
view.suspendEvent('scroll');
view.setScrollY(me.position = me.scrollTop = me.bodyTop ? me.scrollTop + scrollIncrement : 0);
view.resumeEvent('scroll');
} else
{
me.setBodyTop(me.bodyTop = calculatedTop = startIndex * me.rowHeight);
view.suspendEvent('scroll');
view.setScrollY(me.position = me.scrollTop = Math.max(calculatedTop - me.rowHeight * (calculatedTop < me.bodyTop ? me.leadingBufferZone : me.trailingBufferZone , 0)));
view.resumeEvent('scroll');
}
}
} else {
view.addEmptyText();
}
me.refreshSize();
view.refreshSize(rows.getCount() !== prevRowCount);
view.fireEvent('refresh', view, range);
if (focusPosition) {
view.cellFocused = true;
navModel.setPosition(focusPosition, null, null, null, true);
}
view.headerCt.setSortState();
view.refreshNeeded = view.refreshing = me.refreshing = false;
} else {
view.refresh();
}
},
renderRange: function(start, end, forceSynchronous, fromLockingPartner) {
var me = this,
rows = me.view.all,
store = me.store;
if (!(start === rows.startIndex && end === rows.endIndex)) {
if (store.rangeCached(start, end)) {
me.cancelLoad();
if (me.synchronousRender || forceSynchronous) {
me.onRangeFetched(null, start, end, null, fromLockingPartner);
} else {
if (!me.renderTask) {
me.renderTask = new Ext.util.DelayedTask(me.onRangeFetched, me, null, false);
}
me.renderTask.delay(1, null, null, [
null,
start,
end,
null,
fromLockingPartner
]);
}
} else
{
me.attemptLoad(start, end);
}
}
},
onRangeFetched: function(range, start, end, options, fromLockingPartner) {
var me = this,
view = me.view,
oldStart,
rows = view.all,
removeCount,
increment = 0,
calculatedTop, newTop,
lockingPartner = (view.lockingPartner && !fromLockingPartner && !me.doNotMirror) && view.lockingPartner.bufferedRenderer,
newRows, partnerNewRows, topAdditionSize, topBufferZone, i,
variableRowHeight = me.variableRowHeight;
if (view.isDestroyed) {
return;
}
if (range) {
me.scrollTop = me.view.getScrollY();
} else {
range = me.store.getRange(start, end);
if (!range) {
return;
}
}
calculatedTop = start * me.rowHeight;
if (start < rows.startIndex && end > rows.endIndex) {
topAdditionSize = rows.startIndex - start;
view.clearViewEl(true);
newRows = view.doAdd(range, start);
view.fireEvent('itemadd', range, start, newRows);
for (i = 0; i < topAdditionSize; i++) {
increment -= newRows[i].offsetHeight;
}
newTop = me.bodyTop + increment;
} else {
if (me.teleported || start > rows.endIndex || end < rows.startIndex) {
newTop = calculatedTop;
if (variableRowHeight) {
topBufferZone = me.scrollTop < me.position ? me.leadingBufferZone : me.trailingBufferZone;
if (start > topBufferZone) {
newTop = me.scrollTop - me.rowHeight * topBufferZone;
}
}
view.clearViewEl(true);
me.teleported = false;
}
if (!rows.getCount()) {
newRows = view.doAdd(range, start);
view.fireEvent('itemadd', range, start, newRows);
}
else if (end > rows.endIndex) {
removeCount = Math.max(start - rows.startIndex, 0);
if (variableRowHeight) {
increment = rows.item(rows.startIndex + removeCount, true).offsetTop;
}
newRows = rows.scroll(Ext.Array.slice(range, rows.endIndex + 1 - start), 1, removeCount, start, end);
if (variableRowHeight) {
newTop = me.bodyTop + increment;
} else {
newTop = calculatedTop;
}
} else
{
removeCount = Math.max(rows.endIndex - end, 0);
oldStart = rows.startIndex;
newRows = rows.scroll(Ext.Array.slice(range, 0, rows.startIndex - start), -1, removeCount, start, end);
if (variableRowHeight) {
newTop = me.bodyTop - rows.item(oldStart, true).offsetTop;
if (!rows.startIndex) {
if (newTop) {
view.setScrollY(me.position = (me.scrollTop -= newTop));
newTop = 0;
}
}
else if (newTop < 0) {
increment = rows.startIndex * me.rowHeight;
view.setScrollY(me.position = (me.scrollTop += increment));
newTop = me.bodyTop + increment;
}
} else {
newTop = calculatedTop;
}
}
me.position = me.scrollTop;
}
newTop = Math.max(Math.floor(newTop), 0);
if (view.positionBody) {
me.setBodyTop(newTop);
}
if (newRows && lockingPartner && !lockingPartner.disabled) {
lockingPartner.scrollTop = lockingPartner.position = me.scrollTop;
partnerNewRows = lockingPartner.onRangeFetched(null, start, end, options, true);
if (lockingPartner.bodyTop !== newTop) {
lockingPartner.setBodyTop(newTop);
}
lockingPartner.view.setScrollY(me.scrollTop);
if (variableRowHeight && view.ownerGrid.syncRowHeights) {
me.syncRowHeights(newRows, partnerNewRows);
}
}
return newRows;
},
syncRowHeights: function(itemEls, partnerItemEls) {
var me = this,
ln = 0,
otherLn = 1,
mySynchronizer = [],
otherSynchronizer = [],
RowSynchronizer = Ext.grid.locking.RowSynchronizer,
i, rowSync;
if (itemEls && partnerItemEls) {
ln = itemEls.length;
otherLn = partnerItemEls.length;
}
if (ln !== otherLn) {
itemEls = me.view.all.slice();
partnerItemEls = me.view.lockingPartner.all.slice();
ln = otherLn = itemEls.length;
}
for (i = 0; i < ln; i++) {
mySynchronizer[i] = rowSync = new RowSynchronizer(me.view, itemEls[i]);
rowSync.measure();
}
for (i = 0; i < otherLn; i++) {
otherSynchronizer[i] = rowSync = new RowSynchronizer(me.view.lockingPartner, partnerItemEls[i]);
rowSync.measure();
}
for (i = 0; i < ln; i++) {
mySynchronizer[i].finish(otherSynchronizer[i]);
otherSynchronizer[i].finish(mySynchronizer[i]);
}
me.syncRowHeightsFinish();
},
syncRowHeightsFinish: function() {
var me = this,
view = me.view,
lockingPartner = view.lockingPartner.bufferedRenderer;
delete me.rowHeight;
me.refreshSize();
if (lockingPartner.rowHeight !== me.rowHeight) {
delete lockingPartner.rowHeight;
lockingPartner.refreshSize();
}
},
setBodyTop: function(bodyTop) {
var me = this,
view = me.view,
store = me.store,
body = view.body;
body.translate((me.isRTL && Ext.supports.xOriginBug && view.scrollFlags.y) ? Ext.getScrollbarSize().width : null, me.bodyTop = bodyTop);
if (me.variableRowHeight) {
if (view.all.endIndex === (store.getCount()) - 1) {
me.stretchView(view, me.scrollHeight = me.bodyTop + body.dom.offsetHeight - 1);
}
else if (me.bodyTop + body.dom.offsetHeight - 1 > me.scrollHeight) {
me.stretchView(view, me.scrollHeight += ((store.getCount()) - view.all.endIndex) * me.rowHeight);
}
}
},
getFirstVisibleRowIndex: function(startRow, endRow, viewportTop, viewportBottom) {
var me = this,
view = me.view,
rows = view.all,
elements = rows.elements,
clientHeight = me.viewClientHeight,
target, targetTop,
bodyTop = me.bodyTop;
if (rows.getCount() && me.variableRowHeight) {
if (!arguments.length) {
startRow = rows.startIndex;
endRow = rows.endIndex;
viewportTop = me.scrollTop;
viewportBottom = viewportTop + clientHeight;
if (bodyTop > viewportBottom || bodyTop + view.body.dom.offsetHeight < viewportTop) {
me.teleported = true;
return Math.floor(me.scrollTop / me.rowHeight);
}
target = startRow + Math.min(me.numFromEdge + ((me.lastScrollDirection === -1) ? me.leadingBufferZone : me.trailingBufferZone), Math.floor((endRow - startRow) / 2));
} else {
target = startRow + Math.floor((endRow - startRow) / 2);
}
targetTop = bodyTop + elements[target].offsetTop;
if (targetTop + elements[target].offsetHeight <= viewportTop) {
return me.getFirstVisibleRowIndex(target + 1, endRow, viewportTop, viewportBottom);
}
if (targetTop <= viewportTop) {
return target;
}
else if (target !== startRow) {
return me.getFirstVisibleRowIndex(startRow, target - 1, viewportTop, viewportBottom);
}
}
return Math.floor(me.scrollTop / me.rowHeight);
},
getLastVisibleRowIndex: function(startRow, endRow, viewportTop, viewportBottom) {
var me = this,
view = me.view,
rows = view.all,
elements = rows.elements,
clientHeight = me.viewClientHeight,
target, targetTop, targetBottom,
bodyTop = me.bodyTop;
if (rows.getCount() && me.variableRowHeight) {
if (!arguments.length) {
startRow = rows.startIndex;
endRow = rows.endIndex;
viewportTop = me.scrollTop;
viewportBottom = viewportTop + clientHeight;
if (bodyTop > viewportBottom || bodyTop + view.body.dom.offsetHeight < viewportTop) {
me.teleported = true;
return Math.floor(me.scrollTop / me.rowHeight) + Math.ceil(clientHeight / me.rowHeight);
}
target = endRow - Math.min(me.numFromEdge + ((me.lastScrollDirection === 1) ? me.leadingBufferZone : me.trailingBufferZone), Math.floor((endRow - startRow) / 2));
} else {
target = startRow + Math.floor((endRow - startRow) / 2);
}
targetTop = bodyTop + elements[target].offsetTop;
if (targetTop > viewportBottom) {
return me.getLastVisibleRowIndex(startRow, target - 1, viewportTop, viewportBottom);
}
targetBottom = targetTop + elements[target].offsetHeight;
if (targetBottom >= viewportBottom) {
return target;
}
else if (target !== endRow) {
return me.getLastVisibleRowIndex(target + 1, endRow, viewportTop, viewportBottom);
}
}
return me.getFirstVisibleRowIndex() + Math.ceil(clientHeight / me.rowHeight);
},
getScrollHeight: function(calculatedOnly) {
var me = this,
view = me.view,
rows = view.all,
store = me.store,
recCount = store.getCount(),
rowCount, scrollHeight;
if (!recCount) {
return 0;
}
if (!me.hasOwnProperty('rowHeight')) {
rowCount = rows.getCount();
if (rowCount) {
me.rowHeight = me.variableRowHeight ? Math.floor(view.body.dom.clientHeight / rowCount) : rows.first(true).offsetHeight;
}
}
scrollHeight = Math.floor(recCount * me.rowHeight);
if (!calculatedOnly) {
if (scrollHeight && (rows.endIndex === recCount - 1)) {
scrollHeight = Math.max(scrollHeight, me.bodyTop + view.body.dom.offsetHeight - 1);
}
}
return me.scrollHeight = scrollHeight;
},
attemptLoad: function(start, end) {
var me = this;
if (me.scrollToLoadBuffer) {
if (!me.loadTask) {
me.loadTask = new Ext.util.DelayedTask(me.doAttemptLoad, me, []);
}
me.loadTask.delay(me.scrollToLoadBuffer, me.doAttemptLoad, me, [
start,
end
]);
} else {
me.doAttemptLoad(start, end);
}
},
cancelLoad: function() {
if (this.loadTask) {
this.loadTask.cancel();
}
},
doAttemptLoad: function(start, end) {
var me = this;
this.store.getRange(start, end, {
loadId: ++me.loadId,
callback: function(range, start, end, options) {
if (options.loadId === me.loadId) {
this.onRangeFetched(range, start, end, options);
}
},
scope: this,
fireEvent: false
});
},
destroy: function() {
var me = this,
view = me.view;
me.cancelLoad();
if (view && view.el) {
view.un('scroll', me.onViewScroll, me);
}
Ext.destroy(me.viewListeners, me.storeListeners, me.gridListeners, me.stretcher);
}
}, function(cls) {
if (Ext.supports.Touch) {
cls.prototype.leadingBufferZone = cls.prototype.trailingBufferZone = 2;
cls.prototype.numFromEdge = 1;
}
});
Ext.define('Ext.grid.plugin.Editing', {
extend: 'Ext.plugin.Abstract',
alias: 'editing.editing',
requires: [
'Ext.grid.column.Column',
'Ext.util.KeyNav',
'Ext.form.field.Base',
'Ext.view.Table'
],
mixins: {
observable: 'Ext.util.Observable'
},
clicksToEdit: 2,
triggerEvent: undefined,
relayedEvents: [
'beforeedit',
'edit',
'validateedit',
'canceledit'
],
defaultFieldUI: 'default',
defaultFieldXType: 'textfield',
editStyle: '',
constructor: function(config) {
var me = this;
me.callParent([
config
]);
me.mixins.observable.constructor.call(me);
me.on("edit", function(editor, e) {
me.fireEvent("afteredit", editor, e);
});
},
init: function(grid) {
var me = this;
me.grid = grid;
me.view = grid.view;
me.initEvents();
if (grid.rendered) {
me.setup();
} else {
me.mon(grid, {
beforereconfigure: me.onBeforeReconfigure,
reconfigure: me.onReconfigure,
scope: me,
beforerender: {
fn: me.onBeforeRender,
single: true,
scope: me
}
});
}
grid.relayEvents(me, me.relayedEvents);
if (me.grid.ownerLockable) {
me.grid.ownerLockable.relayEvents(me, me.relayedEvents);
}
grid.isEditable = true;
grid.editingPlugin = grid.view.editingPlugin = me;
},
onBeforeReconfigure: function() {
this.reconfiguring = true;
},
onReconfigure: function() {
this.setup();
delete this.reconfiguring;
},
onBeforeRender: function() {
this.setup();
},
setup: function() {
this.initFieldAccessors(this.grid.getTopLevelColumnManager().getColumns());
},
destroy: function() {
var me = this,
grid = me.grid;
Ext.destroy(me.keyNav);
me.clearListeners();
if (grid) {
grid.editingPlugin = grid.view.editingPlugin = me.grid = me.view = me.editor = me.keyNav = null;
}
},
getEditStyle: function() {
return this.editStyle;
},
initFieldAccessors: function(columns) {
if (columns.isGroupHeader) {
columns = columns.getGridColumns();
}
else if (!Ext.isArray(columns)) {
columns = [
columns
];
}
var me = this,
c,
cLen = columns.length,
getEditor = function(record, defaultField) {
return me.getColumnField(this, defaultField);
},
hasEditor = function() {
return me.hasColumnField(this);
},
setEditor = function(field) {
me.setColumnField(this, field);
},
column;
for (c = 0; c < cLen; c++) {
column = columns[c];
if (!column.getEditor) {
column.getEditor = getEditor;
}
if (!column.hasEditor) {
column.hasEditor = hasEditor;
}
if (!column.setEditor) {
column.setEditor = setEditor;
}
}
},
removeFieldAccessors: function(columns) {
if (columns.isGroupHeader) {
columns = columns.getGridColumns();
}
else if (!Ext.isArray(columns)) {
columns = [
columns
];
}
var c,
cLen = columns.length,
column;
for (c = 0; c < cLen; c++) {
column = columns[c];
column.getEditor = column.hasEditor = column.setEditor = column.field = column.editor = null;
}
},
getColumnField: function(columnHeader, defaultField) {
var me = this,
field = columnHeader.field;
if (!(field && field.isFormField)) {
field = columnHeader.field = me.createColumnField(columnHeader, defaultField);
}
if (field && field.ui === 'default' && !field.hasOwnProperty('ui')) {
field.ui = me.defaultFieldUI;
}
return field;
},
hasColumnField: function(columnHeader) {
return !!(columnHeader.field && columnHeader.field.isComponent);
},
setColumnField: function(columnHeader, field) {
columnHeader.field = field;
columnHeader.field = this.createColumnField(columnHeader);
},
createColumnField: function(column, defaultField) {
var field = column.field,
dataIndex;
if (!field && column.editor) {
field = column.editor;
column.editor = null;
}
if (!field && defaultField) {
field = defaultField;
}
if (field) {
dataIndex = column.dataIndex;
if (field.isComponent) {
field.column = column;
} else {
if (Ext.isString(field)) {
field = {
name: dataIndex,
xtype: field,
column: column
};
} else {
field = Ext.apply({
name: dataIndex,
column: column
}, field);
}
field = Ext.ComponentManager.create(field, this.defaultFieldXType);
}
field.dataIndex = dataIndex;
field.isEditorComponent = true;
column.field = field;
}
return field;
},
initEvents: function() {
var me = this;
me.initEditTriggers();
me.initCancelTriggers();
},
initCancelTriggers: Ext.emptyFn,
initEditTriggers: function() {
var me = this,
view = me.view;
if (me.triggerEvent === 'cellfocus') {
me.mon(view, 'cellfocus', me.onCellFocus, me);
} else if (me.triggerEvent === 'rowfocus') {
me.mon(view, 'rowfocus', me.onRowFocus, me);
} else {
if (view.getSelectionModel().isCellModel) {
view.onCellFocus = me.beforeViewCellFocus.bind(me);
}
me.mon(view, me.triggerEvent || ('cell' + (me.clicksToEdit === 1 ? 'click' : 'dblclick')), me.onCellClick, me);
}
me.initAddRemoveHeaderEvents();
me.view.getNavigationModel().addKeyBindings({
enter: me.onEnterKey,
esc: me.onEscKey,
scope: me
});
},
beforeViewCellFocus: function(position) {
if (this.view.selModel.keyNavigation || !this.editing || !this.isCellEditable || !this.isCellEditable(position.row, position.columnHeader)) {
this.view.focusCell.apply(this.view, arguments);
}
},
onRowFocus: function(record, row, rowIdx) {
this.startEdit(row, 0);
},
onCellFocus: function(record, cell, position) {
this.startEdit(position.row, position.column);
},
onCellClick: function(view, cell, colIdx, record, row, rowIdx, e) {
var expanderSelector = view.expanderSelector,
columnHeader = view.ownerCt.getColumnManager().getHeaderAtIndex(colIdx),
editor = columnHeader.getEditor(record);
if (this.shouldStartEdit(editor) && (!expanderSelector || !e.getTarget(expanderSelector))) {
this.startEdit(record, columnHeader);
}
},
initAddRemoveHeaderEvents: function() {
var me = this,
headerCt = me.grid.headerCt;
me.mon(headerCt, {
scope: me,
add: me.onColumnAdd,
columnmove: me.onColumnMove,
beforedestroy: me.beforeGridHeaderDestroy
});
},
onColumnAdd: function(ct, column) {
this.initFieldAccessors(column);
},
onColumnMove: Ext.emptyFn,
onEnterKey: function(e) {
var me = this,
grid = me.grid,
navModel, record, pos, column, targetComponent;
if (me.editing) {
targetComponent = Ext.getCmp(e.getTarget().getAttribute('componentId'));
if (!(targetComponent && targetComponent.isPickerField && targetComponent.isExpanded)) {
me.completeEdit();
}
} else if (e.view === me.view) {
navModel = grid.getView().getNavigationModel();
pos = navModel.getPosition();
if (pos) {
record = pos.record;
column = pos.column;
}
if (record && column) {
me.startEdit(record, column);
}
}
},
onEscKey: function(e) {
if (this.editing) {
var targetComponent = Ext.getCmp(e.getTarget().getAttribute('componentId'));
if (!(targetComponent && targetComponent.isPickerField && targetComponent.isExpanded)) {
return this.cancelEdit();
}
}
},
beforeEdit: Ext.emptyFn,
shouldStartEdit: function(editor) {
return !!editor;
},
startEdit: function(record, columnHeader) {
var me = this,
context,
layoutView = me.grid.lockable ? me.grid : me.view;
if (!layoutView.componentLayoutCounter) {
layoutView.on({
boxready: Ext.Function.bind(me.startEdit, me, [
record,
columnHeader
]),
single: true
});
return false;
}
if (me.disabled || me.grid.collapsed || !me.grid.view.isVisible(true)) {
return false;
}
context = me.getEditingContext(record, columnHeader);
if (context == null) {
return false;
}
if (!me.preventBeforeCheck) {
if (me.beforeEdit(context) === false || me.fireEvent('beforeedit', me, context) === false || context.cancel) {
return false;
}
}
return context;
},
getEditingContext: function(record, columnHeader) {
var me = this,
grid = me.grid,
colMgr = grid.visibleColumnManager,
view, gridRow, rowIdx, colIdx, result;
if (Ext.isNumber(columnHeader)) {
columnHeader = colMgr.getHeaderAtIndex(columnHeader);
}
if (!columnHeader) {
return;
}
if (columnHeader.hidden) {
columnHeader = columnHeader.next(':not([hidden])') || columnHeader.prev(':not([hidden])');
}
view = columnHeader.getRootHeaderCt().view;
gridRow = view.getRow(record);
if (!gridRow) {
return;
}
colIdx = colMgr.getHeaderIndex(columnHeader);
if (Ext.isNumber(record)) {
rowIdx = record;
record = view.getRecord(gridRow);
} else {
rowIdx = view.indexOf(gridRow);
}
if (!record) {
return;
}
result = new Ext.grid.CellContext(view).setAll(view, rowIdx, colIdx, record, columnHeader);
result.grid = grid;
result.store = view.dataSource;
result.field = columnHeader.dataIndex;
result.value = result.originalValue = record.get(columnHeader.dataIndex);
result.row = gridRow;
result.node = view.getNode(record);
return result;
},
cancelEdit: function() {
var me = this;
me.editing = false;
me.fireEvent('canceledit', me, me.context);
},
completeEdit: function() {
var me = this;
if (me.editing && me.validateEdit()) {
me.fireEvent('edit', me, me.context);
}
me.context = null;
me.editing = false;
},
validateEdit: function() {
var me = this,
context = me.context;
return me.fireEvent('validateedit', me, context) !== false && !context.cancel;
}
});
Ext.define('Ext.grid.plugin.CellEditing', {
alias: 'plugin.cellediting',
extend: 'Ext.grid.plugin.Editing',
requires: [
'Ext.grid.CellEditor',
'Ext.util.DelayedTask'
],
lockableScope: 'both',
init: function(grid) {
var me = this,
lockingPartner = me.lockingPartner;
me.callParent(arguments);
if (lockingPartner) {
if (lockingPartner.editors) {
me.editors = lockingPartner.editors;
} else {
me.editors = lockingPartner.editors = new Ext.util.MixedCollection(false, function(editor) {
return editor.editorId;
});
}
} else {
me.editors = new Ext.util.MixedCollection(false, function(editor) {
return editor.editorId;
});
}
},
beforeGridHeaderDestroy: function(headerCt) {
var me = this,
columns = me.grid.getColumnManager().getColumns(),
len = columns.length,
i, column, editor;
for (i = 0; i < len; i++) {
column = columns[i];
editor = me.editors.getByKey(column.getItemId());
if (!editor) {
editor = column.editor || column.field;
}
Ext.destroy(editor);
me.removeFieldAccessors(column);
}
},
onReconfigure: function(grid, store, columns) {
if (columns) {
this.editors.clear();
}
this.callParent();
},
destroy: function() {
var me = this;
if (me.editors) {
me.editors.each(Ext.destroy, Ext);
me.editors.clear();
}
me.callParent(arguments);
},
initCancelTriggers: function() {
var me = this,
grid = me.grid;
me.mon(grid, {
columnresize: me.cancelEdit,
columnmove: me.cancelEdit,
scope: me
});
},
isCellEditable: function(record, columnHeader) {
var me = this,
context = me.getEditingContext(record, columnHeader);
if (me.grid.view.isVisible(true) && context) {
columnHeader = context.column;
record = context.record;
if (columnHeader && me.getEditor(record, columnHeader)) {
return true;
}
}
},
startEdit: function(record, columnHeader,
context) {
var me = this,
useCurrentActiveEditor, isFieldEditable, currentActiveEditor, newEditor;
if (!context) {
me.preventBeforeCheck = true;
context = me.callParent(arguments);
delete me.preventBeforeCheck;
if (context === false) {
return false;
}
}
if (context && context.view.isVisible(true)) {
record = context.record;
columnHeader = context.column;
isFieldEditable = (columnHeader && columnHeader.getEditor(record)) && !(me.beforeEdit(context) === false || me.fireEvent('beforeedit', me, context) === false || context.cancel);
if (isFieldEditable) {
currentActiveEditor = me.getActiveEditor();
newEditor = me.getEditor(record, columnHeader);
if (currentActiveEditor) {
useCurrentActiveEditor = newEditor === currentActiveEditor;
me.completeEdit(!!newEditor);
if (me.editing) {
return false;
}
}
} else {
return false;
}
me.context = context;
context.view.scrollCellIntoView(context.view.getCell(record, columnHeader));
if (newEditor) {
if (useCurrentActiveEditor) {
newEditor.editing = false;
if (Ext.isIE) {
newEditor.selectSameEditor = true;
}
}
me.showEditor(newEditor, context, context.value);
if (currentActiveEditor && !useCurrentActiveEditor) {
currentActiveEditor.hide();
}
return true;
}
return false;
}
},
showEditor: function(ed, context, value) {
var me = this,
record = context.record,
view = context.view,
columnHeader = context.column,
sm = view.getSelectionModel(),
selectMode;
if (!columnHeader.up(me.view.ownerCt)) {
return me.lockingPartner.showEditor(ed, me.lockingPartner.getEditingContext(record, columnHeader), value);
}
me.setEditingContext(context);
selectMode = sm.getSelectionMode();
if (!sm.isCellSelected(view, record, columnHeader) && (selectMode !== 'MULTI' || !sm.getSelection().length || (sm.getSelection().length === 1 && sm.isSelected(record)))) {
sm.selectByPosition({
row: record,
column: columnHeader,
view: view
}, selectMode === 'MULTI');
}
if (!view.cellFocused) {
view.getNavigationModel().setPosition(context, null, null, null, true);
}
view.getNavigationModel().setPosition();
ed.startEdit(view.getCell(record, columnHeader), value, context);
if (ed.editing) {
me.setActiveEditor(ed);
me.setActiveRecord(record);
me.setActiveColumn(columnHeader);
me.editing = true;
me.scroll = view.el.getScroll();
} else
{
view.getNavigationModel().setPosition(context, null, null, null, true);
}
},
completeEdit: function(remainVisible) {
var activeEd = this.getActiveEditor();
if (activeEd) {
activeEd.completeEdit(remainVisible);
}
},
setEditingContext: function(context) {
this.context = context;
if (this.lockingPartner) {
this.lockingPartner.context = context;
}
},
setActiveEditor: function(ed) {
this.activeEditor = ed;
if (this.lockingPartner) {
this.lockingPartner.activeEditor = ed;
}
},
getActiveEditor: function() {
return this.activeEditor;
},
setActiveColumn: function(column) {
this.activeColumn = column;
if (this.lockingPartner) {
this.lockingPartner.activeColumn = column;
}
},
getActiveColumn: function() {
return this.activeColumn;
},
setActiveRecord: function(record) {
this.activeRecord = record;
if (this.lockingPartner) {
this.lockingPartner.activeRecord = record;
}
},
getActiveRecord: function() {
return this.activeRecord;
},
getEditor: function(record, column) {
var me = this,
editors = me.editors,
editorId = column.getItemId(),
editor = editors.getByKey(editorId),
editorOwner = me.grid.ownerLockable || me.grid;
if (!editor) {
editor = column.getEditor(record);
if (!editor) {
return false;
}
if (editor instanceof Ext.grid.CellEditor) {
editor.floating = true;
} else
{
editor = new Ext.grid.CellEditor({
floating: true,
editorId: editorId,
field: editor
});
}
editor.field.excludeForm = true;
if (editor.ownerCt !== editorOwner) {
editorOwner.add(editor);
editor.on({
scope: me,
specialkey: me.onSpecialKey,
complete: me.onEditComplete,
canceledit: me.cancelEdit
});
column.on('removed', me.onColumnRemoved, me);
}
editors.add(editor);
}
if (column.isTreeColumn) {
editor.isForTree = column.isTreeColumn;
editor.addCls(Ext.baseCSSPrefix + 'tree-cell-editor');
}
editor.setGrid(me.grid);
editor.editingPlugin = me;
return editor;
},
onColumnRemoved: function(column) {
var me = this,
context = me.context,
editor,
editorOwner = me.grid.ownerLockable || me.grid;
if (context && context.column === column) {
me.cancelEdit();
}
column.un('removed', me.onColumnRemoved, me);
if (column.getEditor && (editor = column.getEditor()) && editor.ownerCt === editorOwner) {
editorOwner.remove(editor);
editor.un({
scope: me,
specialkey: me.onSpecialKey,
complete: me.onEditComplete,
canceledit: me.cancelEdit
});
}
},
setColumnField: function(column, field) {
var ed = this.editors.getByKey(column.getItemId());
Ext.destroy(ed, column.field);
this.editors.removeAtKey(column.getItemId());
this.callParent(arguments);
},
getCell: function(record, column) {
return this.grid.getView().getCell(record, column);
},
onSpecialKey: function(ed, field, e) {
var sm;
if (e.getKey() === e.TAB) {
e.stopEvent();
e.position = this.context;
if (ed) {
ed.onEditorTab(e);
}
sm = ed.getRefOwner().getSelectionModel();
return sm.onEditorTab(ed.editingPlugin, e);
}
},
onEditComplete: function(ed, value, startValue) {
var me = this,
activeColumn = me.getActiveColumn(),
context = me.context,
view, record;
if (activeColumn) {
view = context.view;
record = context.record;
me.setActiveEditor(null);
me.setActiveColumn(null);
me.setActiveRecord(null);
context.value = value;
if (!me.validateEdit()) {
me.editing = false;
return;
}
if (!record.isEqual(value, startValue)) {
record.set(activeColumn.dataIndex, value);
context.rowIdx = view.indexOf(record);
}
me.fireEvent('edit', me, context);
me.editing = false;
}
},
cancelEdit: function() {
var me = this,
context = me.context,
view, sm, record, preserveCurrentSelection,
activeEd = me.getActiveEditor();
if (activeEd) {
me.setActiveEditor(null);
me.setActiveColumn(null);
me.setActiveRecord(null);
view = context.view;
sm = view.getSelectionModel();
preserveCurrentSelection = sm.getSelectionMode() === 'MULTI' && (sm.getSelection().length > 1 || !sm.isSelected(record));
if (activeEd.field) {
me.context.value = ('editedValue' in activeEd) ? activeEd.editedValue : activeEd.getValue();
activeEd.cancelEdit();
}
context.view.getNavigationModel().deferSetPosition(100, context, null, null, null, preserveCurrentSelection);
me.callParent(arguments);
return;
}
return true;
},
startEditByPosition: function(position) {
var me = this,
cm = me.grid.getColumnManager(),
index;
if (!position.isCellContext) {
position.column = me.grid.getColumnManager().getColumns()[position.column];
position.record = me.view.dataSource.getAt(position.row);
}
index = cm.getHeaderIndex(position.column);
position.column = cm.getVisibleHeaderClosestToIndex(index);
return me.startEdit(position.record, position.column);
}
});
Ext.define('Ext.plugin.AbstractClipboard', {
extend: 'Ext.plugin.Abstract',
requires: [
'Ext.util.KeyMap'
],
cachedConfig: {
formats: {
text: {
get: 'getTextData',
put: 'putTextData'
}
}
},
config: {
memory: null,
source: 'system',
system: 'text'
},
destroy: function() {
var me = this,
keyMap = me.keyMap,
shared = me.shared;
if (keyMap) {
me.keyMap = Ext.destroy(keyMap);
if (!--shared.counter) {
shared.textArea = Ext.destroy(shared.textArea);
}
} else {
me.renderListener = Ext.destroy(me.renderListener);
}
me.callParent();
},
init: function(comp) {
var me = this;
if (comp.rendered) {
this.finishInit(comp);
} else {
me.renderListener = comp.on({
render: function() {
me.renderListener = null;
me.finishInit(comp);
},
destroyable: true,
single: true
});
}
},
privates: {
shared: {
counter: 0,
data: null,
textArea: null
},
applyMemory: function(value) {
value = this.applySource(value);
if (value) {
for (var i = value.length; i-- > 0; ) {
if (value[i] === 'system') {
Ext.Error.raise('Invalid clipboard format "' + value[i] + '"');
}
}
}
return value;
},
applySource: function(value) {
if (value) {
if (Ext.isString(value)) {
value = [
value
];
} else if (value.length === 0) {
value = null;
}
}
if (value) {
var formats = this.getFormats();
for (var i = value.length; i-- > 0; ) {
if (value[i] !== 'system' && !formats[value[i]]) {
Ext.Error.raise('Invalid clipboard format "' + value[i] + '"');
}
}
}
return value || null;
},
applySystem: function(value) {
var formats = this.getFormats();
if (!formats[value]) {
Ext.Error.raise('Invalid clipboard format "' + value + '"');
}
return value;
},
doCutCopy: function(event, erase) {
var me = this,
formats = me.allFormats || me.syncFormats(),
data = me.getData(erase, formats),
memory = me.getMemory(),
system = me.getSystem(),
sys;
me.shared.data = memory && data;
if (system) {
sys = data[system];
if (formats[system] < 3) {
delete data[system];
}
me.setClipboardData(sys);
}
},
doPaste: function(format, data) {
var formats = this.getFormats();
this[formats[format].put](data, format);
},
finishInit: function(comp) {
var me = this;
me.keyMap = new Ext.util.KeyMap({
target: comp.el,
binding: [
{
ctrl: true,
key: 'x',
fn: me.onCut,
scope: me
},
{
ctrl: true,
key: 'c',
fn: me.onCopy,
scope: me
},
{
ctrl: true,
key: 'v',
fn: me.onPaste,
scope: me
}
]
});
++me.shared.counter;
comp.on({
destroy: 'destroy',
scope: me
});
},
getData: function(erase, format) {
var me = this,
formats = me.getFormats(),
data, i, name, names;
if (Ext.isString(format)) {
if (!formats[format]) {
Ext.Error.raise('Invalid clipboard format "' + format + '"');
}
data = me[formats[format].get](format, erase);
} else {
data = {};
names = [];
if (format) {
for (name in format) {
if (!formats[name]) {
Ext.Error.raise('Invalid clipboard format "' + name + '"');
}
names.push(name);
}
} else {
names = Ext.Object.getAllKeys(formats);
}
for (i = names.length; i-- > 0; ) {
data[name] = me[formats[name].get](name, erase && !i);
}
}
return data;
},
getHiddenTextArea: function() {
var shared = this.shared,
ret = shared.textArea;
if (!ret) {
shared.textArea = ret = Ext.getBody().createChild({
tag: 'textarea',
tabIndex: -1,
style: {
position: 'absolute',
top: '-1000px',
width: '1px'
}
});
}
return ret;
},
onCopy: function(event) {
this.doCutCopy(event, false);
},
onCut: function(event) {
this.doCutCopy(event, true);
},
onPaste: function() {
var me = this,
sharedData = me.shared.data,
source = me.getSource(),
i, n, s;
if (source) {
for (i = 0 , n = source.length; i < n; ++i) {
s = source[i];
if (s === 'system') {
s = me.getSystem();
me.pasteClipboardData(s);
break;
} else if (sharedData && (s in sharedData)) {
me.doPaste(s, sharedData[s]);
break;
}
}
}
},
pasteClipboardData: function(format) {
var me = this,
clippy = window.clipboardData,
area, focusEl;
if (clippy && clippy.getData) {
me.doPaste(format, clippy.getData("text"));
} else {
focusEl = Ext.Element.getActiveElement();
area = me.getHiddenTextArea().dom;
area.value = '';
area.focus();
Ext.defer(function() {
if (focusEl) {
focusEl.focus();
}
me.doPaste(format, area.value);
area.value = '';
}, 100, me);
}
},
setClipboardData: function(data) {
var clippy = window.clipboardData;
if (clippy && clippy.setData) {
clippy.setData("text", data);
} else {
var me = this,
area = me.getHiddenTextArea().dom,
focusEl = Ext.Element.getActiveElement();
area.value = data;
area.focus();
area.select();
Ext.defer(function() {
area.value = '';
if (focusEl) {
focusEl.focus();
}
}, 50);
}
},
syncFormats: function() {
var me = this,
map = {},
memory = me.getMemory(),
system = me.getSystem(),
i, s;
if (system) {
map[system] = 1;
}
if (memory) {
for (i = memory.length; i-- > 0; ) {
s = memory[i];
map[s] = map[s] ? 3 : 2;
}
}
return me.allFormats = map;
},
updateMemory: function() {
this.allFormats = null;
},
updateSystem: function() {
this.allFormats = null;
}
}
});
Ext.define('Ext.grid.plugin.Clipboard', {
extend: 'Ext.plugin.AbstractClipboard',
alias: 'plugin.clipboard',
requires: [
'Ext.util.Format',
'Ext.util.TSV'
],
formats: {
cell: {
get: 'getCells'
},
html: {
get: 'getCellData'
},
raw: {
get: 'getCellData'
}
},
getCellData: function(format, erase) {
var cmp = this.getCmp(),
selModel = cmp.getSelectionModel(),
ret = [],
isRaw = format === 'raw',
isText = format === 'text',
viewNode, cell, data, dataIndex, lastRecord, record, row, view;
selModel.getSelected().eachCell(function(cellContext) {
view = cellContext.column.getView();
record = cellContext.record;
if (lastRecord !== record) {
lastRecord = record;
ret.push(row = []);
}
dataIndex = cellContext.column.dataIndex;
if (isRaw) {
data = record.data[dataIndex];
} else {
viewNode = view.all.item(cellContext.rowIdx);
if (!viewNode) {
viewNode = Ext.fly(view.createRowElement(record, cellContext.rowIdx));
}
cell = viewNode.down(cellContext.column.getCellInnerSelector());
data = cell.dom.innerHTML;
if (isText) {
data = Ext.util.Format.stripTags(data);
}
}
row.push(data);
if (erase && dataIndex) {
record.set(dataIndex, null);
}
});
return Ext.util.TSV.encode(ret);
},
getCells: function(format, erase) {
var cmp = this.getCmp(),
selModel = cmp.getSelectionModel(),
ret = [],
dataIndex, lastRecord, record, row;
selModel.getSelected().eachCell(function(cellContext) {
record = cellContext.record;
if (lastRecord !== record) {
lastRecord = record;
ret.push(row = {
model: record.self,
fields: []
});
}
dataIndex = cellContext.column.dataIndex;
row.fields.push({
name: dataIndex,
value: record.data[dataIndex]
});
if (erase && dataIndex) {
record.set(dataIndex, null);
}
});
return ret;
},
getTextData: function(format, erase) {
return this.getCellData(format, erase);
},
putCellData: function(data, format) {
var values = Ext.util.TSV.decode(data),
row,
recCount = values.length,
colCount = recCount ? values[0].length : 0,
sourceRowIdx, sourceColIdx,
view = this.getCmp().getView(),
maxRowIdx = view.dataSource.getCount() - 1,
maxColIdx = view.getVisibleColumnManager().getColumns().length - 1,
navModel = view.getNavigationModel(),
destination = navModel.getPosition(),
dataIndex, destinationStartColumn,
dataObject = {};
if (destination) {
destination = new Ext.grid.CellContext(view).setPosition(destination.record, destination.column);
} else {
destination = new Ext.grid.CellContext(view).setPosition(0, 0);
}
destinationStartColumn = destination.colIdx;
for (sourceRowIdx = 0; sourceRowIdx < recCount; sourceRowIdx++) {
row = values[sourceRowIdx];
for (sourceColIdx = 0; sourceColIdx < colCount; sourceColIdx++) {
dataIndex = destination.column.dataIndex;
if (dataIndex) {
switch (format) {
case 'raw':
dataObject[dataIndex] = row[sourceColIdx];
break;
case 'text':
dataObject[dataIndex] = row[sourceColIdx];
break;
case 'html':
break;
}
}
if (destination.colIdx === maxColIdx) {
break;
}
destination.setColumn(destination.colIdx + 1);
}
destination.record.set(dataObject);
if (destination.rowIdx === maxRowIdx) {
break;
}
destination.setPosition(destination.rowIdx + 1, destinationStartColumn);
}
},
putTextData: function(data, format) {
this.putCellData(data, format);
}
});
Ext.define('Ext.grid.plugin.DragDrop', {
extend: 'Ext.plugin.Abstract',
alias: 'plugin.gridviewdragdrop',
uses: [
'Ext.view.DragZone',
'Ext.grid.ViewDropZone'
],
dragText: '{0} selected row{1}',
ddGroup: "GridDD",
enableDrop: true,
enableDrag: true,
containerScroll: false,
init: function(view) {
view.on('render', this.onViewRender, this, {
single: true
});
},
destroy: function() {
Ext.destroy(this.dragZone, this.dropZone);
},
enable: function() {
var me = this;
if (me.dragZone) {
me.dragZone.unlock();
}
if (me.dropZone) {
me.dropZone.unlock();
}
me.callParent();
},
disable: function() {
var me = this;
if (me.dragZone) {
me.dragZone.lock();
}
if (me.dropZone) {
me.dropZone.lock();
}
me.callParent();
},
onViewRender: function(view) {
var me = this,
scrollEl;
if (me.enableDrag) {
if (me.containerScroll) {
scrollEl = view.getEl();
}
me.dragZone = new Ext.view.DragZone(Ext.apply({
view: view,
ddGroup: me.dragGroup || me.ddGroup,
dragText: me.dragText,
containerScroll: me.containerScroll,
scrollEl: scrollEl
}, me.dragZone));
}
if (me.enableDrop) {
me.dropZone = new Ext.grid.ViewDropZone(Ext.apply({
view: view,
ddGroup: me.dropGroup || me.ddGroup
}, me.dropZone));
}
}
});
Ext.define('Ext.grid.plugin.RowEditing', {
extend: 'Ext.grid.plugin.Editing',
alias: 'plugin.rowediting',
requires: [
'Ext.grid.RowEditor'
],
lockableScope: 'top',
editStyle: 'row',
autoCancel: true,
errorSummary: true,
constructor: function() {
var me = this;
me.callParent(arguments);
if (!me.clicksToMoveEditor) {
me.clicksToMoveEditor = me.clicksToEdit;
}
me.autoCancel = !!me.autoCancel;
},
destroy: function() {
Ext.destroy(this.editor);
this.callParent(arguments);
},
onBeforeReconfigure: function() {
this.callParent(arguments);
this.cancelEdit();
},
onReconfigure: function(grid, store, columns) {
var ed = this.editor;
this.callParent(arguments);
if (columns && ed && ed.rendered) {
ed.needsSyncFieldWidths = true;
}
},
shouldStartEdit: function(editor) {
return true;
},
startEdit: function(record, columnHeader) {
var me = this,
editor = me.getEditor(),
context;
if (Ext.isEmpty(columnHeader)) {
columnHeader = me.grid.getTopLevelVisibleColumnManager().getHeaderAtIndex(0);
}
if (editor.beforeEdit() !== false) {
context = me.callParent([
record,
columnHeader
]);
if (context) {
me.context = context;
if (me.lockingPartner) {
me.lockingPartner.cancelEdit();
}
editor.startEdit(context.record, context.column, context);
me.editing = true;
return true;
}
}
return false;
},
cancelEdit: function() {
var me = this;
if (me.editing) {
me.getContextFieldValues();
me.getEditor().cancelEdit();
me.callParent(arguments);
return;
}
return true;
},
completeEdit: function() {
var me = this;
if (me.editing && me.validateEdit()) {
me.editing = false;
me.fireEvent('edit', me, me.context);
}
},
validateEdit: function() {
this.getContextFieldValues();
return this.callParent(arguments) && this.getEditor().completeEdit();
},
getEditor: function() {
var me = this;
if (!me.editor) {
me.editor = me.initEditor();
}
return me.editor;
},
getContextFieldValues: function() {
var editor = this.editor,
context = this.context,
record = context.record,
newValues = {},
originalValues = {},
editors = editor.query('>[isFormField]'),
len = editors.length,
i, name, item;
for (i = 0; i < len; i++) {
item = editors[i];
name = item.dataIndex;
newValues[name] = item.getValue();
originalValues[name] = record.get(name);
}
Ext.apply(context, {
newValues: newValues,
originalValues: originalValues
});
},
initEditor: function() {
return new Ext.grid.RowEditor(this.initEditorConfig());
},
initEditorConfig: function() {
var me = this,
grid = me.grid,
view = me.view,
headerCt = grid.headerCt,
btns = [
'saveBtnText',
'cancelBtnText',
'errorsText',
'dirtyText'
],
b,
bLen = btns.length,
cfg = {
autoCancel: me.autoCancel,
errorSummary: me.errorSummary,
fields: headerCt.getGridColumns(),
hidden: true,
view: view,
editingPlugin: me
},
item;
for (b = 0; b < bLen; b++) {
item = btns[b];
if (Ext.isDefined(me[item])) {
cfg[item] = me[item];
}
}
return cfg;
},
initEditTriggers: function() {
var me = this,
view = me.view,
moveEditorEvent = me.clicksToMoveEditor === 1 ? 'click' : 'dblclick';
me.callParent(arguments);
if (me.clicksToMoveEditor !== me.clicksToEdit) {
me.mon(view, 'cell' + moveEditorEvent, me.moveEditorByClick, me);
}
view.on({
render: function() {
me.mon(me.grid.headerCt, {
scope: me,
columnresize: me.onColumnResize,
columnhide: me.onColumnHide,
columnshow: me.onColumnShow
});
},
single: true
});
},
moveEditorByClick: function() {
var me = this;
if (me.editing) {
me.superclass.onCellClick.apply(me, arguments);
}
},
onColumnAdd: function(ct, column) {
if (column.isHeader) {
var me = this,
editor;
me.initFieldAccessors(column);
editor = me.editor;
if (editor) {
editor.onColumnAdd(column);
}
}
},
beforeGridHeaderDestroy: function(headerCt) {
var columns = this.grid.getColumnManager().getColumns(),
len = columns.length,
i, column, field;
for (i = 0; i < len; i++) {
column = columns[i];
if (column.hasEditor) {
if (column.hasEditor() && (field = column.getEditor())) {
field.destroy();
}
this.removeFieldAccessors(column);
}
}
},
onColumnResize: function(ct, column, width) {
if (column.isHeader) {
var me = this,
editor = me.getEditor();
if (editor) {
editor.onColumnResize(column, width);
}
}
},
onColumnHide: function(ct, column) {
var me = this,
editor = me.getEditor();
if (editor) {
editor.onColumnHide(column);
}
},
onColumnShow: function(ct, column) {
var me = this,
editor = me.getEditor();
if (editor) {
editor.onColumnShow(column);
}
},
onColumnMove: function(ct, column, fromIdx, toIdx) {
var me = this,
editor = me.getEditor();
me.initFieldAccessors(column);
if (editor) {
editor.onColumnMove(column, fromIdx, toIdx);
}
},
setColumnField: function(column, field) {
var me = this,
editor = me.getEditor();
if (editor) {
editor.destroyColumnEditor(column);
}
me.callParent(arguments);
if (editor) {
editor.insertColumnEditor(column);
}
},
createColumnField: function(column, defaultField) {
var editor = this.editor,
def;
if (editor) {
def = editor.getDefaultFieldCfg();
}
return this.callParent([
column,
defaultField || def
]);
}
});
Ext.define('Ext.grid.plugin.RowExpander', {
extend: 'Ext.plugin.Abstract',
lockableScope: 'normal',
requires: [
'Ext.grid.feature.RowBody'
],
alias: 'plugin.rowexpander',
columnWidth: 24,
rowBodyTpl: null,
lockedTpl: null,
expandOnEnter: true,
expandOnDblClick: true,
selectRowOnExpand: false,
headerWidth: 24,
bodyBefore: false,
rowBodyTrSelector: '.' + Ext.baseCSSPrefix + 'grid-rowbody-tr',
rowBodyHiddenCls: Ext.baseCSSPrefix + 'grid-row-body-hidden',
rowCollapsedCls: Ext.baseCSSPrefix + 'grid-row-collapsed',
addCollapsedCls: {
fn: function(out, values, parent) {
var me = this.rowExpander;
if (!me.recordsExpanded[values.record.internalId]) {
values.itemClasses.push(me.rowCollapsedCls);
}
this.nextTpl.applyOut(values, out, parent);
},
syncRowHeights: function(lockedItem, normalItem) {
this.rowExpander.syncRowHeights(lockedItem, normalItem);
},
priority: 20000
},
setCmp: function(grid) {
var me = this,
features;
me.callParent(arguments);
me.recordsExpanded = {};
if (!me.rowBodyTpl) {
Ext.Error.raise("The 'rowBodyTpl' config is required and is not defined.");
}
me.rowBodyTpl = Ext.XTemplate.getTpl(me, 'rowBodyTpl');
features = me.getFeatureConfig(grid);
if (grid.features) {
grid.features = Ext.Array.push(features, grid.features);
} else {
grid.features = features;
}
},
getFeatureConfig: function(grid) {
var me = this,
features = [],
featuresCfg = {
ftype: 'rowbody',
rowExpander: me,
bodyBefore: me.bodyBefore,
recordsExpanded: me.recordsExpanded,
rowBodyHiddenCls: me.rowBodyHiddenCls,
rowCollapsedCls: me.rowCollapsedCls,
setupRowData: me.getRowBodyFeatureData,
setup: me.setup
};
features.push(Ext.apply({
lockableScope: 'normal',
getRowBodyContents: me.getRowBodyContentsFn(me.rowBodyTpl)
}, featuresCfg));
if (grid.enableLocking) {
features.push(Ext.apply({
lockableScope: 'locked',
getRowBodyContents: me.lockedTpl ? me.getRowBodyContentsFn(me.lockedTpl) : function() {
return '';
}
}, featuresCfg));
}
return features;
},
getRowBodyContentsFn: function(rowBodyTpl) {
var me = this;
return function(rowValues) {
rowBodyTpl.owner = me;
return rowBodyTpl.applyTemplate(rowValues.record.getData());
};
},
init: function(grid) {
if (grid.lockable) {
grid = grid.normalGrid;
}
var me = this,
ownerLockable = grid.ownerLockable,
view, lockedView;
me.callParent(arguments);
me.grid = grid;
view = me.view = grid.getView();
me.bindView(view);
view.addRowTpl(me.addCollapsedCls).rowExpander = me;
if (ownerLockable) {
me.addExpander(ownerLockable.lockedGrid.headerCt.items.getCount() ? ownerLockable.lockedGrid : grid);
lockedView = ownerLockable.lockedGrid.getView();
me.bindView(lockedView);
lockedView.addRowTpl(me.addCollapsedCls).rowExpander = me;
ownerLockable.syncRowHeight = true;
ownerLockable.mon(ownerLockable, {
processcolumns: me.onLockableProcessColumns,
lockcolumn: me.onColumnLock,
unlockcolumn: me.onColumnUnlock,
scope: me
});
me.viewListeners = view.on({
itemadd: Ext.Function.createAnimationFrame(ownerLockable.syncRowHeights, ownerLockable)
});
} else {
me.addExpander(grid);
grid.on('beforereconfigure', me.beforeReconfigure, me);
}
},
beforeReconfigure: function(grid, store, columns, oldStore, oldColumns) {
var me = this;
if (me.viewListeners) {
me.viewListeners.destroy();
}
if (columns) {
me.expanderColumn = new Ext.grid.Column(me.getHeaderConfig());
columns.unshift(me.expanderColumn);
}
},
onLockableProcessColumns: function(lockable, lockedHeaders, normalHeaders) {
this.addExpander(lockedHeaders.length ? lockable.lockedGrid : lockable.normalGrid);
},
addExpander: function(expanderGrid) {
var me = this,
expanderHeader = me.getHeaderConfig();
if (expanderGrid.isLocked && expanderGrid.ownerLockable.shrinkWrapLocked) {
expanderGrid.width += expanderHeader.width;
me.grid = expanderGrid;
}
me.expanderColumn = expanderGrid.headerCt.insert(0, expanderHeader);
expanderGrid.getSelectionModel().injectCheckbox = 1;
},
getRowBodyFeatureData: function(record, idx, rowValues) {
var me = this;
me.self.prototype.setupRowData.apply(me, arguments);
rowValues.rowBody = me.getRowBodyContents(rowValues);
rowValues.rowBodyCls = me.recordsExpanded[record.internalId] ? '' : me.rowBodyHiddenCls;
},
setup: function(rows, rowValues) {
var me = this,
lockable = me.grid.ownerLockable;
me.self.prototype.setup.apply(me, arguments);
if (lockable && Ext.Array.indexOf(me.grid.columnManager.getColumns(), me.rowExpander.expanderColumn) !== -1) {
rowValues.rowBodyColspan -= 1;
}
},
bindView: function(view) {
if (this.expandOnEnter) {
view.on('itemkeydown', this.onKeyDown, this);
}
if (this.expandOnDblClick) {
view.on('itemdblclick', this.onDblClick, this);
}
},
onKeyDown: function(view, record, row, rowIdx, e) {
if (e.getKey() === e.ENTER) {
var ds = view.store,
sels = view.getSelectionModel().getSelection(),
ln = sels.length,
i = 0;
for (; i < ln; i++) {
rowIdx = ds.indexOf(sels[i]);
this.toggleRow(rowIdx, sels[i]);
}
}
},
onDblClick: function(view, record, row, rowIdx, e) {
this.toggleRow(rowIdx, record);
},
toggleRow: function(rowIdx, record) {
var me = this,
view = me.view,
bufferedRenderer = view.bufferedRenderer,
scroller = view.getScrollable(),
fireView = view,
rowNode = view.getNode(rowIdx),
normalRow = Ext.fly(rowNode),
lockedRow,
nextBd = normalRow.down(me.rowBodyTrSelector, true),
wasCollapsed = normalRow.hasCls(me.rowCollapsedCls),
addOrRemoveCls = wasCollapsed ? 'removeCls' : 'addCls',
rowSpan = wasCollapsed ? 2 : 1,
ownerLockable = me.grid.ownerLockable,
expanderCell;
normalRow[addOrRemoveCls](me.rowCollapsedCls);
Ext.fly(nextBd)[addOrRemoveCls](me.rowBodyHiddenCls);
me.recordsExpanded[record.internalId] = wasCollapsed;
if (me.grid.ownerLockable) {
fireView = ownerLockable.getView();
if (ownerLockable.lockedGrid.isVisible()) {
view = ownerLockable.view.lockedGrid.view;
lockedRow = Ext.fly(view.getNode(rowIdx));
if (lockedRow) {
lockedRow[addOrRemoveCls](me.rowCollapsedCls);
nextBd = lockedRow.down(me.rowBodyTrSelector, true);
Ext.fly(nextBd)[addOrRemoveCls](me.rowBodyHiddenCls);
}
}
}
if (me.expanderColumn) {
expanderCell = Ext.fly(view.getRow(rowIdx)).down(me.expanderColumn.getCellSelector(), true);
if (expanderCell) {
expanderCell.rowSpan = rowSpan;
}
}
fireView.fireEvent(wasCollapsed ? 'expandbody' : 'collapsebody', rowNode, record, nextBd);
if (view.getSizeModel().height.shrinkWrap || ownerLockable) {
view.refreshSize(true);
}
if (scroller) {
if (bufferedRenderer) {
bufferedRenderer.refreshSize();
} else {
scroller.refresh(true);
}
}
},
syncRowHeights: function(lockedItem, normalItem) {
var me = this,
lockedBd = Ext.fly(lockedItem).down(me.rowBodyTrSelector),
normalBd = Ext.fly(normalItem).down(me.rowBodyTrSelector),
lockedHeight, normalHeight;
if (normalBd.isVisible()) {
if ((lockedHeight = lockedBd.getHeight()) !== (normalHeight = normalBd.getHeight())) {
if (lockedHeight > normalHeight) {
normalBd.setHeight(lockedHeight);
} else {
lockedBd.setHeight(normalHeight);
}
}
} else
{
lockedBd.dom.style.height = normalBd.dom.style.height = '';
}
},
onColumnUnlock: function(lockable, column) {
var me = this,
lockedColumns;
lockable = me.grid.ownerLockable;
lockedColumns = lockable.lockedGrid.visibleColumnManager.getColumns();
if (lockedColumns.length === 1) {
if (lockedColumns[0] === me.expanderColumn) {
lockable.unlock(me.expanderColumn);
me.grid = lockable.normalGrid;
} else {
lockable.lock(me.expanderColumn, 0);
}
}
},
onColumnLock: function(lockable, column) {
var me = this,
lockedColumns, lockedGrid;
lockable = me.grid.ownerLockable;
lockedColumns = lockable.lockedGrid.visibleColumnManager.getColumns();
if (lockedColumns.length === 1) {
me.grid = lockedGrid = lockable.lockedGrid;
lockedGrid.headerCt.insert(0, me.expanderColumn);
}
},
getHeaderConfig: function() {
var me = this,
lockable = me.grid.ownerLockable;
return {
width: me.headerWidth,
lockable: false,
autoLock: true,
sortable: false,
resizable: false,
draggable: false,
hideable: false,
menuDisabled: true,
tdCls: Ext.baseCSSPrefix + 'grid-cell-special',
innerCls: Ext.baseCSSPrefix + 'grid-cell-inner-row-expander',
renderer: function() {
return '<div class="' + Ext.baseCSSPrefix + 'grid-row-expander" role="presentation"></div>';
},
processEvent: function(type, view, cell, rowIndex, cellIndex, e, record) {
if (e.getTarget('.' + Ext.baseCSSPrefix + 'grid-row-expander')) {
if (type === "click") {
me.toggleRow(rowIndex, record);
return me.selectRowOnExpand;
}
}
},
isLocked: function() {
return lockable && (lockable.lockedGrid.isVisible() || this.locked);
},
editRenderer: function() {
return '&#160;';
}
};
}
});
Ext.define('Ext.grid.property.Grid', {
extend: 'Ext.grid.Panel',
alias: 'widget.propertygrid',
alternateClassName: 'Ext.grid.PropertyGrid',
uses: [
'Ext.grid.plugin.CellEditing',
'Ext.grid.property.Store',
'Ext.grid.property.HeaderContainer',
'Ext.XTemplate',
'Ext.grid.CellEditor',
'Ext.form.field.Date',
'Ext.form.field.Text',
'Ext.form.field.Number',
'Ext.form.field.ComboBox'
],
valueField: 'value',
nameField: 'name',
inferTypes: true,
enableColumnMove: false,
columnLines: true,
stripeRows: false,
trackMouseOver: false,
clicksToEdit: 1,
enableHdMenu: false,
gridCls: Ext.baseCSSPrefix + 'property-grid',
initComponent: function() {
var me = this;
me.source = me.source || {};
me.addCls(me.gridCls);
me.plugins = me.plugins || [];
me.plugins.push(new Ext.grid.plugin.CellEditing({
clicksToEdit: me.clicksToEdit,
startEdit: function(record, column) {
return this.self.prototype.startEdit.call(this, record, me.valueColumn);
}
}));
me.selModel = {
type: 'cellmodel',
onCellSelect: function(position) {
position.column = me.valueColumn;
position.colIdx = me.valueColumn.getVisibleIndex();
return this.self.prototype.onCellSelect.call(this, position);
}
};
me.sourceConfig = Ext.apply({}, me.sourceConfig);
if (!me.store) {
me.propStore = me.store = new Ext.grid.property.Store(me, me.source);
}
me.configure(me.sourceConfig);
if (me.sortableColumns) {
me.store.sort('name', 'ASC');
}
me.columns = new Ext.grid.property.HeaderContainer(me, me.store);
me.callParent();
me.getView().walkCells = this.walkCells;
me.editors = {
'date': new Ext.grid.CellEditor({
field: new Ext.form.field.Date({
selectOnFocus: true
})
}),
'string': new Ext.grid.CellEditor({
field: new Ext.form.field.Text({
selectOnFocus: true
})
}),
'number': new Ext.grid.CellEditor({
field: new Ext.form.field.Number({
selectOnFocus: true
})
}),
'boolean': new Ext.grid.CellEditor({
field: new Ext.form.field.ComboBox({
editable: false,
store: [
[
true,
me.headerCt.trueText
],
[
false,
me.headerCt.falseText
]
]
})
})
};
me.store.on('update', me.onUpdate, me);
},
configure: function(config) {
var me = this,
store = me.store,
i = 0,
len = me.store.getCount(),
nameField = me.nameField,
valueField = me.valueField,
name, value, rec, type;
me.configureLegacy(config);
if (me.inferTypes) {
for (; i < len; ++i) {
rec = store.getAt(i);
name = rec.get(nameField);
if (!me.getConfigProp(name, 'type')) {
value = rec.get(valueField);
if (Ext.isDate(value)) {
type = 'date';
} else if (Ext.isNumber(value)) {
type = 'number';
} else if (Ext.isBoolean(value)) {
type = 'boolean';
} else {
type = 'string';
}
me.setConfigProp(name, 'type', type);
}
}
}
},
getConfigProp: function(fieldName, key, defaultValue) {
var config = this.sourceConfig[fieldName],
out;
if (config) {
out = config[key];
}
return out || defaultValue;
},
setConfigProp: function(fieldName, key, value) {
var sourceCfg = this.sourceConfig,
o = sourceCfg[fieldName];
if (!o) {
o = sourceCfg[fieldName] = {
__copied: true
};
} else if (!o.__copied) {
o = Ext.apply({
__copied: true
}, o);
sourceCfg[fieldName] = o;
}
o[key] = value;
return value;
},
configureLegacy: function(config) {
var me = this;
me.copyLegacyObject(config, me.customRenderers, 'renderer');
me.copyLegacyObject(config, me.customEditors, 'editor');
me.copyLegacyObject(config, me.propertyNames, 'displayName');
if (me.customRenderers || me.customEditors || me.propertyNames) {
if (Ext.global.console && Ext.global.console.warn) {
Ext.global.console.warn(this.$className, 'customRenderers, customEditors & propertyNames have been consolidated into a new config, see "sourceConfig". These configurations will be deprecated.');
}
}
},
copyLegacyObject: function(config, o, keyName) {
var key;
for (key in o) {
if (o.hasOwnProperty(key)) {
if (!config[key]) {
config[key] = {};
}
config[key][keyName] = o[key];
}
}
},
onUpdate: function(store, record, operation) {
var me = this,
v, oldValue;
if (me.rendered && operation === Ext.data.Model.EDIT) {
v = record.get(me.valueField);
oldValue = record.modified.value;
if (me.fireEvent('beforepropertychange', me.source, record.getId(), v, oldValue) !== false) {
if (me.source) {
me.source[record.getId()] = v;
}
record.commit();
me.fireEvent('propertychange', me.source, record.getId(), v, oldValue);
} else {
record.reject();
}
}
},
walkCells: function(pos, direction, e, preventWrap, verifierFn, scope) {
var me = this,
valueColumn = me.ownerCt.valueColumn;
if (direction === 'left') {
direction = 'up';
} else if (direction === 'right') {
direction = 'down';
}
pos = Ext.view.Table.prototype.walkCells.call(me, pos, direction, e, preventWrap, verifierFn, scope);
pos.column = valueColumn;
pos.colIdx = valueColumn.getVisibleIndex();
return pos;
},
getCellEditor: function(record, column) {
var me = this,
propName = record.get(me.nameField),
val = record.get(me.valueField),
editor = me.getConfigProp(propName, 'editor'),
type = me.getConfigProp(propName, 'type'),
editors = me.editors;
if (editor) {
if (!(editor instanceof Ext.grid.CellEditor)) {
if (!(editor instanceof Ext.form.field.Base)) {
editor = Ext.ComponentManager.create(editor, 'textfield');
}
editor = me.setConfigProp(propName, 'editor', new Ext.grid.CellEditor({
field: editor
}));
}
} else if (type) {
switch (type) {
case 'date':
editor = editors.date;
break;
case 'number':
editor = editors.number;
break;
case 'boolean':
editor = me.editors['boolean'];
break;
default:
editor = editors.string;
}
} else if (Ext.isDate(val)) {
editor = editors.date;
} else if (Ext.isNumber(val)) {
editor = editors.number;
} else if (Ext.isBoolean(val)) {
editor = editors['boolean'];
} else
{
editor = editors.string;
}
editor.editorId = propName;
editor.field.column = me.valueColumn;
return editor;
},
beforeDestroy: function() {
var me = this;
me.callParent();
me.destroyEditors(me.editors);
me.destroyEditors(me.customEditors);
delete me.source;
},
destroyEditors: function(editors) {
for (var ed in editors) {
if (editors.hasOwnProperty(ed)) {
Ext.destroy(editors[ed]);
}
}
},
setSource: function(source, sourceConfig) {
var me = this;
me.source = source;
if (sourceConfig !== undefined) {
me.sourceConfig = Ext.apply({}, sourceConfig);
me.configure(me.sourceConfig);
}
me.propStore.setSource(source);
},
getSource: function() {
return this.propStore.getSource();
},
getProperty: function(prop) {
return this.propStore.getProperty(prop);
},
setProperty: function(prop, value, create) {
this.propStore.setValue(prop, value, create);
},
removeProperty: function(prop) {
this.propStore.remove(prop);
}
});
Ext.define('Ext.grid.property.HeaderContainer', {
extend: 'Ext.grid.header.Container',
alternateClassName: 'Ext.grid.PropertyColumnModel',
nameWidth: 115,
nameText: 'Name',
valueText: 'Value',
dateFormat: 'm/j/Y',
trueText: 'true',
falseText: 'false',
nameColumnCls: Ext.baseCSSPrefix + 'grid-property-name',
nameColumnInnerCls: Ext.baseCSSPrefix + 'grid-cell-inner-property-name',
constructor: function(grid, store) {
var me = this;
me.grid = grid;
me.store = store;
me.callParent([
{
isRootHeader: true,
enableColumnResize: Ext.isDefined(grid.enableColumnResize) ? grid.enableColumnResize : me.enableColumnResize,
enableColumnMove: Ext.isDefined(grid.enableColumnMove) ? grid.enableColumnMove : me.enableColumnMove,
items: [
{
header: me.nameText,
width: grid.nameColumnWidth || me.nameWidth,
sortable: grid.sortableColumns,
dataIndex: grid.nameField,
scope: me,
renderer: me.renderProp,
itemId: grid.nameField,
menuDisabled: true,
tdCls: me.nameColumnCls,
innerCls: me.nameColumnInnerCls
},
{
header: me.valueText,
scope: me,
renderer: me.renderCell,
getEditor: me.getCellEditor.bind(me),
sortable: grid.sortableColumns,
flex: 1,
fixed: true,
dataIndex: grid.valueField,
itemId: grid.valueField,
menuDisabled: true
}
]
}
]);
me.grid.valueColumn = me.items.getAt(1);
},
getCellEditor: function(record) {
return this.grid.getCellEditor(record, this);
},
renderProp: function(v) {
return this.getPropertyName(v);
},
renderCell: function(val, meta, rec) {
var me = this,
grid = me.grid,
renderer = grid.getConfigProp(rec.get(grid.nameField), 'renderer'),
result = val;
if (renderer) {
return renderer.apply(me, arguments);
}
if (Ext.isDate(val)) {
result = me.renderDate(val);
} else if (Ext.isBoolean(val)) {
result = me.renderBool(val);
}
return Ext.util.Format.htmlEncode(result);
},
renderDate: Ext.util.Format.date,
renderBool: function(bVal) {
return this[bVal ? 'trueText' : 'falseText'];
},
getPropertyName: function(name) {
return this.grid.getConfigProp(name, 'displayName', name);
}
});
Ext.define('Ext.grid.property.Property', {
extend: 'Ext.data.Model',
alternateClassName: 'Ext.PropGridProperty',
fields: [
{
name: 'name',
type: 'string'
},
{
name: 'value'
}
],
idProperty: 'name',
constructor: function(data, value) {
if (!Ext.isObject(data)) {
data = {
name: data,
value: value
};
}
this.callParent([
data
]);
}
});
Ext.define('Ext.grid.property.Reader', {
extend: 'Ext.data.reader.Reader',
successProperty: null,
totalProperty: null,
messageProperty: null,
read: function(dataObject) {
return this.readRecords(dataObject);
},
readRecords: function(dataObject) {
var Model = this.getModel(),
result = {
records: [],
success: true
},
val, propName;
for (propName in dataObject) {
if (dataObject.hasOwnProperty(propName)) {
val = dataObject[propName];
if (this.isEditableValue(val)) {
result.records.push(new Model({
name: propName,
value: val
}));
}
}
}
result.total = result.count = result.records.length;
return new Ext.data.ResultSet(result);
},
isEditableValue: function(val) {
return Ext.isPrimitive(val) || Ext.isDate(val) || val === null;
}
});
Ext.define('Ext.grid.property.Store', {
extend: 'Ext.data.Store',
alternateClassName: 'Ext.grid.PropertyStore',
remoteSort: true,
requires: [
'Ext.grid.property.Reader',
'Ext.data.proxy.Memory',
'Ext.grid.property.Property'
],
constructor: function(grid, source) {
var me = this;
me.grid = grid;
me.source = source;
me.callParent([
{
data: source,
model: Ext.grid.property.Property,
proxy: me.getProxy()
}
]);
},
getProxy: function() {
var proxy = this.proxy;
if (!proxy) {
proxy = this.proxy = new Ext.data.proxy.Memory({
model: Ext.grid.property.Property,
reader: this.getReader()
});
}
return proxy;
},
getReader: function() {
var reader = this.reader;
if (!reader) {
reader = this.reader = new Ext.grid.property.Reader({
model: Ext.grid.property.Property
});
}
return reader;
},
setSource: function(dataObject) {
var me = this;
me.source = dataObject;
me.suspendEvents();
me.removeAll();
me.getProxy().setData(dataObject);
me.load();
me.resumeEvents();
me.fireEvent('datachanged', me);
me.fireEvent('refresh', me);
},
getProperty: function(row) {
var rec = Ext.isNumber(row) ? this.getAt(row) : this.getById(row),
ret = null;
if (rec) {
ret = rec.get('value');
}
return ret;
},
setValue: function(prop, value, create) {
var me = this,
rec = me.getRec(prop);
if (rec) {
rec.set('value', value);
me.source[prop] = value;
} else if (create) {
me.source[prop] = value;
rec = new Ext.grid.property.Property({
name: prop,
value: value
}, prop);
me.add(rec);
}
},
remove: function(prop) {
var rec = this.getRec(prop);
if (rec) {
this.callParent([
rec
]);
delete this.source[prop];
}
},
getRec: function(prop) {
return this.getById(prop);
},
getSource: function() {
return this.source;
},
onDestroy: function() {
Ext.destroy(this.reader, this.proxy);
this.callParent();
}
});
Ext.define('Ext.grid.selection.Selection', {
constructor: function(view) {
if (!view || !(view.isTableView || view.isLockingView)) {
Ext.Error.raise('Selection must be created for a given TableView or LockingView');
}
this.view = view.ownerGrid.view;
}
});
Ext.define('Ext.grid.selection.Cells', {
extend: 'Ext.grid.selection.Selection',
type: 'cells',
isCells: true,
clone: function() {
var me = this,
result = new me.self(me.view);
if (me.startCell) {
result.startCell = me.startCell.clone();
result.endCell = me.endCell.clone();
}
return result;
},
contains: function(cellContext) {
var range;
if (!cellContext || !cellContext.isCellContext) {
return false;
}
if (this.startCell) {
range = this.getRowRange();
if (cellContext.rowIdx >= range[0] && cellContext.rowIdx <= range[1]) {
range = this.getColumnRange();
return (cellContext.colIdx >= range[0] && cellContext.colIdx <= range[1]);
}
}
return false;
},
eachRow: function(fn, scope) {
var me = this,
rowRange = me.getRowRange(),
context = new Ext.grid.CellContext(me.view),
rowIdx;
for (rowIdx = rowRange[0]; rowIdx <= rowRange[1]; rowIdx++) {
context.setRow(rowIdx);
if (fn.call(scope || me, context.record) === false) {
return;
}
}
},
eachColumn: function(fn, scope) {
var me = this,
colRange = me.getColumnRange(),
context = new Ext.grid.CellContext(me.view),
colIdx;
for (colIdx = colRange[0]; colIdx <= colRange[1]; colIdx++) {
context.setColumn(colIdx);
if (fn.call(scope || me, context.column, colIdx) === false) {
return;
}
}
},
eachCell: function(fn, scope) {
var me = this,
rowRange = me.getRowRange(),
colRange = me.getColumnRange(),
context = new Ext.grid.CellContext(me.view),
rowIdx, colIdx;
for (rowIdx = rowRange[0]; rowIdx <= rowRange[1]; rowIdx++) {
context.setRow(rowIdx);
for (colIdx = colRange[0]; colIdx <= colRange[1]; colIdx++) {
context.setColumn(colIdx);
if (fn.call(scope || me, context, colIdx, rowIdx) === false) {
return;
}
}
}
},
getFirstRowIndex: function() {
return this.startCell ? Math.min(this.startCell.rowIdx, this.endCell.rowIdx) : 0;
},
getLastRowIndex: function() {
return this.startCell ? Math.max(this.startCell.rowIdx, this.endCell.rowIdx) : -1;
},
getFirstColumnIndex: function() {
return this.startCell ? Math.min(this.startCell.colIdx, this.endCell.colIdx) : 0;
},
getLastColumnIndex: function() {
return this.startCell ? Math.max(this.startCell.colIdx, this.endCell.colIdx) : -1;
},
privates: {
clear: function() {
var me = this,
view = me.view;
me.eachCell(function(cellContext) {
view.onCellDeselect(cellContext);
});
me.startCell = me.endCell = null;
},
setRangeStart: function(startCell) {
this.startCell = (this.endCell = startCell.clone()).clone();
this.view.onCellSelect(startCell);
},
setRangeEnd: function(endCell) {
var me = this,
range, lastRange, rowStart, rowEnd, colStart, colEnd, rowIdx, colIdx,
view = me.view,
rows = view.all,
cell = new Ext.grid.CellContext(view),
maxColIdx = view.getVisibleColumnManager().getColumns().length - 1;
me.endCell = endCell.clone();
range = me.getRange();
lastRange = me.lastRange || range;
rowStart = Math.max(Math.min(range[0][1], lastRange[0][1]), rows.startIndex);
rowEnd = Math.min(Math.max(range[1][1], lastRange[1][1]), rows.endIndex);
colStart = Math.min(range[0][0], lastRange[0][0]);
colEnd = Math.min(Math.max(range[1][0], lastRange[1][0]), maxColIdx);
for (rowIdx = rowStart; rowIdx <= rowEnd; rowIdx++) {
for (colIdx = colStart; colIdx <= colEnd; colIdx++) {
cell.setPosition(rowIdx, colIdx);
if (rowIdx < range[0][1] || rowIdx > range[1][1] || colIdx < range[0][0] || colIdx > range[1][0]) {
view.onCellDeselect(cell);
} else {
view.onCellSelect(cell);
}
}
}
me.lastRange = range;
},
getRange: function() {
return [
[
this.getFirstColumnIndex(),
this.getFirstRowIndex()
],
[
this.getLastColumnIndex(),
this.getLastRowIndex()
]
];
},
getRangeSize: function() {
return this.getCount();
},
getCount: function() {
var range = this.getRange();
return (range[1][0] - range[0][0] + 1) * (range[1][1] - range[0][1] + 1);
},
selectAll: function() {
var me = this,
view = me.view;
me.clear();
me.setRangeStart(new Ext.grid.CellContext(view).setPosition(0, 0));
me.setRangeEnd(new Ext.grid.CellContext(view).setPosition(view.dataSource.getCount() - 1, view.getVisibleColumnManager().getColumns().length - 1));
},
isAllSelected: function() {
var start = this.rangeStart,
end = this.rangeEnd;
if (start) {
if (!start.colIdx && !start.rowIdx) {
return end.colIdx === end.view.getVisibleColumnManager().getColumns().length - 1 && end.rowIdx === end.view.dataSource.getCount - 1;
}
}
return false;
},
getColumnRange: function() {
return [
this.getFirstColumnIndex(),
this.getLastColumnIndex()
];
},
getRowRange: function() {
return [
this.getFirstRowIndex(),
this.getLastRowIndex()
];
}
}
});
Ext.define('Ext.grid.selection.Columns', {
extend: 'Ext.grid.selection.Selection',
type: 'columns',
isColumns: true,
clone: function() {
var me = this,
result = new me.self(me.view),
columns = me.selectedColumns;
if (columns) {
result.selectedColumns = Ext.Array.slice(columns);
}
return result;
},
eachRow: function(fn, scope) {
var columns = this.selectedColumns;
if (columns && columns.length) {
this.view.dataSource.each(fn, scope || this);
}
},
eachColumn: function(fn, scope) {
var me = this,
view = me.view,
columns = me.selectedColumns,
len, i,
context = new Ext.grid.CellContext(view);
if (columns) {
len = columns.length;
for (i = 0; i < len; i++) {
context.setColumn(columns[i]);
if (fn.call(scope || me, context.column, context.colIdx) === false) {
return false;
}
}
}
},
eachCell: function(fn, scope) {
var me = this,
view = me.view,
columns = me.selectedColumns,
len, i,
context = new Ext.grid.CellContext(view);
if (columns) {
len = columns.length;
view.dataSource.each(function(record) {
context.setRow(record);
for (i = 0; i < len; i++) {
context.setColumn(columns[i]);
if (fn.call(scope || me, context, context.colIdx, context.rowIdx) === false) {
return false;
}
}
});
}
},
contains: function(column) {
var selectedColumns = this.selectedColumns;
if (column && column.isColumn && selectedColumns && selectedColumns.length) {
return Ext.Array.contains(selectedColumns, column);
}
return false;
},
getCount: function() {
var selectedColumns = this.selectedColumns;
return selectedColumns ? selectedColumns.length : 0;
},
getColumns: function() {
return this.selectedColumns || [];
},
privates: {
add: function(column) {
if (!column.isColumn) {
Ext.Error.raise('Column selection must be passed a grid Column header object');
}
Ext.Array.include((this.selectedColumns || (this.selectedColumns = [])), column);
this.refreshColumns(column);
},
clear: function() {
var me = this,
prevSelection = me.selectedColumns;
if (prevSelection && prevSelection.length) {
me.selectedColumns = [];
me.refreshColumns.apply(me, prevSelection);
}
},
isAllSelected: function() {
var selectedColumns = this.selectedColumns;
return selectedColumns && selectedColumns.length === this.view.ownerGrid.getVisibleColumnManager().getColumns().length;
},
refreshColumns: function(column) {
var me = this,
view = me.view,
rows = view.all,
rowIdx,
columns = arguments,
len = columns.length,
colIdx,
cellContext = new Ext.grid.CellContext(view),
selected = [];
if (view.rendered) {
for (colIdx = 0; colIdx < len; colIdx++) {
selected[colIdx] = me.contains(columns[colIdx]);
}
for (rowIdx = rows.startIndex; rowIdx <= rows.endIndex; rowIdx++) {
cellContext.setRow(rowIdx);
for (colIdx = 0; colIdx < len; colIdx++) {
cellContext.setColumn(columns[colIdx]);
if (selected[colIdx]) {
view.onCellSelect(cellContext);
} else {
view.onCellDeselect(cellContext);
}
}
}
}
},
remove: function(column) {
if (!column.isColumn) {
Ext.Error.raise('Column selection must be passed a grid Column header object');
}
if (this.selectedColumns) {
Ext.Array.remove(this.selectedColumns, column);
this.refreshColumns(column);
}
},
selectAll: function() {
var me = this;
me.clear();
me.selectedColumns = me.view.getVisibleColumnManager().getColumns();
me.refreshColumns.apply(me, me.selectedColumns);
}
}
});
Ext.define('Ext.grid.selection.Rows', {
extend: 'Ext.grid.selection.Selection',
requires: [
'Ext.util.Collection'
],
type: 'rows',
isRows: true,
clone: function() {
var me = this,
result = new me.self(me.view);
if (me.selectedRecords) {
result.selectedRecords = me.selectedRecords.clone();
}
if (me.rangeStart) {
result.setRangeStart(me.rangeStart);
result.setRangeEnd(me.rangeEnd);
}
return result;
},
add: function(record) {
if (!(record.isModel)) {
Ext.Error.raise('Row selection must be passed a record');
}
var selection = this.selectedRecords || (this.selectedRecords = this.createRecordCollection());
if (!selection.byInternalId.get(record.internalId)) {
selection.add(record);
this.view.onRowSelect(record);
}
},
remove: function(record) {
if (!(record.isModel)) {
Ext.Error.raise('Row selection must be passed a record');
}
var me = this;
if (me.selectedRecords && me.selectedRecords.byInternalId.get(record.internalId)) {
me.selectedRecords.remove(record);
me.view.onRowDeselect(record);
me.allSelected = false;
return true;
}
},
contains: function(record) {
if (!record || !record.isModel) {
return false;
}
var me = this,
result = false,
selectedRecords = me.selectedRecords,
recIndex, dragRange;
if (me.allSelected) {
me.add(record);
return true;
}
if (selectedRecords) {
result = !!selectedRecords.byInternalId.get(record.internalId);
}
if (!result && me.rangeStart != null) {
dragRange = me.getRange();
recIndex = me.view.dataSource.indexOf(record);
result = recIndex >= dragRange[0] && recIndex <= dragRange[1];
}
return result;
},
getCount: function() {
var me = this,
selectedRecords = me.selectedRecords,
result = selectedRecords ? selectedRecords.getCount() : 0,
range = me.getRange(),
i,
store = me.view.dataSource;
for (i = range[0]; i <= range[1]; i++) {
if (!selectedRecords || !selectedRecords.byInternalId.get(store.getAt(i).internalId)) {
result++;
}
}
return result;
},
getRecords: function() {
var selectedRecords = this.selectedRecords;
return selectedRecords ? selectedRecords.getRange() : [];
},
selectAll: function() {
var me = this;
me.clear();
me.setRangeStart(0);
me.setRangeEnd(me.view.dataSource.getCount() - 1);
me.addRange();
me.allSelected = true;
},
eachRow: function(fn, scope) {
var selectedRecords = this.selectedRecords;
if (selectedRecords) {
selectedRecords.each(fn, scope || this);
}
},
eachColumn: function(fn, scope) {
var columns = this.view.getVisibleColumnManager().getColumns(),
len = columns.length,
i;
if (this.selectedRecords) {
for (i = 0; i < len; i++) {
if (fn.call(this || scope, columns[i], i) === false) {
return;
}
}
}
},
eachCell: function(fn, scope) {
var me = this,
selection = me.selectedRecords,
view = me.view,
columns = view.ownerGrid.getVisibleColumnManager().getColumns(),
colCount, i, j, context, range, recCount,
abort = false;
if (columns) {
colCount = columns.length;
context = new Ext.grid.CellContext(view);
if (selection) {
selection.each(function(record) {
context.setRow(record);
for (i = 0; i < colCount; i++) {
context.setColumn(columns[i]);
if (fn.call(scope || me, context, context.colIdx, context.rowIdx) === false) {
abort = true;
return false;
}
}
});
}
if (!abort && me.rangeStart != null) {
range = me.getRange();
me.view.dataSource.getRange(range[0], range[1], {
callback: function(records) {
recCount = records.length;
for (i = 0; !abort && i < recCount; i++) {
context.setRow(records[i]);
for (j = 0; !abort && j < colCount; j++) {
context.setColumn(columns[j]);
if (fn.call(scope || me, context, context.colIdx, context.rowIdx) === false) {
abort = true;
}
}
}
}
});
}
}
},
beginUpdate: function() {
var selectedRecords = this.selectedRecords;
if (selectedRecords) {
selectedRecords.beginUpdate();
}
},
endUpdate: function() {
var selectedRecords = this.selectedRecords;
if (selectedRecords) {
selectedRecords.endUpdate();
}
},
destroy: function() {
this.selectedRecords = Ext.destroy(this.selectedRecords);
},
privates: {
clear: function() {
var me = this,
view = me.view;
me.allSelected = false;
if (me.selectedRecords) {
me.eachRow(function(record) {
view.onRowDeselect(record);
});
me.selectedRecords.clear();
}
},
isAllSelected: function() {
return !!this.allSelected;
},
setRangeStart: function(start) {
this.allSelected = false;
this.rangeStart = this.rangeEnd = start;
this.view.onRowSelect(start);
},
setRangeEnd: function(end) {
var me = this,
range, lastRange, rowIdx, row,
view = me.view,
store = view.dataSource,
rows = view.all,
selected = me.selectedRecords,
rec;
me.rangeEnd = end;
range = me.getRange();
lastRange = me.lastRange || range;
for (rowIdx = Math.max(Math.min(range[0], lastRange[0]), rows.startIndex) , end = Math.min(Math.max(range[1], lastRange[1]), rows.endIndex); rowIdx <= end; rowIdx++) {
row = rows.item(rowIdx);
if (rowIdx < range[0] || rowIdx > range[1]) {
if (selected && (rec = selected.byInternalId.get(store.getAt(rowIdx).internalId))) {
selected.remove(rec);
}
view.onRowDeselect(rowIdx);
} else {
view.onRowSelect(rowIdx);
}
}
me.lastRange = range;
},
getRange: function() {
var start = this.rangeStart,
end = this.rangeEnd;
if (start == null) {
return [
0,
-1
];
} else if (start <= end) {
return [
start,
end
];
}
return [
end,
start
];
},
getRangeSize: function() {
var range = this.getRange();
return range[1] - range[0] + 1;
},
createRecordCollection: function() {
var result = new Ext.util.Collection({
rootProperty: 'data',
extraKeys: {
byInternalId: {
rootProperty: false,
property: 'internalId'
}
}
});
return result;
},
addRange: function() {
var me = this,
range, selection;
if (me.rangeStart != null) {
range = me.getRange();
selection = me.selectedRecords || (me.selectedRecords = me.createRecordCollection());
me.view.dataSource.getRange(range[0], range[1], {
callback: function(range) {
selection.add.apply(selection, range);
}
});
me.setRangeStart(me.lastRange = null);
}
}
}
});
Ext.define('Ext.grid.selection.SpreadsheetModel', {
extend: 'Ext.selection.Model',
requires: [
'Ext.grid.selection.Selection',
'Ext.grid.selection.Cells',
'Ext.grid.selection.Rows',
'Ext.grid.selection.Columns'
],
alias: 'selection.spreadsheet',
isSpreadsheetModel: true,
config: {
columnSelect: {
$value: false,
lazy: true
},
cellSelect: {
$value: true,
lazy: true
},
rowSelect: {
$value: true,
lazy: true
},
dragSelect: {
$value: true,
lazy: true
},
selected: null
},
checkboxSelect: false,
checkboxColumnIndex: 0,
showHeaderCheckbox: true,
checkboxHeaderWidth: 24,
rowNumbererHeaderWidth: 46,
columnSelectCls: Ext.baseCSSPrefix + 'ssm-column-select',
rowNumbererHeaderCls: Ext.baseCSSPrefix + 'ssm-row-numberer-hd',
rowNumbererTdCls: Ext.grid.column.RowNumberer.prototype.tdCls + ' ' + Ext.baseCSSPrefix + 'ssm-row-numberer-cell',
checkerOnCls: Ext.baseCSSPrefix + 'grid-hd-checker-on',
tdCls: Ext.baseCSSPrefix + 'grid-cell-special ' + Ext.baseCSSPrefix + 'grid-cell-row-checker',
bindComponent: function(view) {
var me = this,
viewListeners, lockedGrid;
if (me.view !== view) {
if (me.view) {
me.navigationModel = null;
Ext.destroy(me.viewListeners, me.navigationListeners);
}
me.view = view;
if (view) {
me.getCellSelect();
lockedGrid = view.ownerGrid.lockedGrid;
if (lockedGrid) {
me.hasLockedHeader = true;
me.onViewCreated(lockedGrid, lockedGrid.getView());
} else
{
view.grid.on({
viewcreated: me.onViewCreated,
scope: me,
single: true
});
}
me.gridListeners = view.ownerGrid.on({
columnschanged: me.onColumnsChanged,
scope: me,
destroyable: true
});
viewListeners = me.getViewListeners();
viewListeners.scope = me;
viewListeners.destroyable = true;
me.viewListeners = view.on(viewListeners);
me.navigationModel = view.getNavigationModel();
me.navigationListeners = me.navigationModel.on({
navigate: me.onNavigate,
scope: me,
destroyable: true
});
if (me.getColumnSelect()) {
view.ownerGrid.addCls(me.columnSelectCls);
}
}
}
},
getCheckboxHeaderConfig: function() {
var me = this,
showCheck = me.showHeaderCheckbox !== false;
return {
isCheckerHd: showCheck,
text: '&#160;',
clickTargetName: 'el',
width: me.checkboxHeaderWidth,
sortable: false,
draggable: false,
resizable: false,
hideable: false,
menuDisabled: true,
dataIndex: '',
tdCls: me.tdCls,
cls: showCheck ? Ext.baseCSSPrefix + 'column-header-checkbox ' : '',
defaultRenderer: me.checkboxRenderer.bind(me),
editRenderer: '&#160;',
locked: me.hasLockedHeader
};
},
checkboxRenderer: function() {
return '<div class="' + Ext.baseCSSPrefix + 'grid-row-checker" role="presentation">&#160;</div>';
},
onHeaderClick: function(headerCt, header, e) {
var me = this,
sel = me.selected;
if (header === me.numbererColumn || header === me.checkColumn) {
e.stopEvent();
if (!sel || !sel.isAllSelected()) {
me.selectAll(headerCt.view);
} else {
me.deselectAll();
}
me.updateHeaderState();
} else if (me.columnSelect) {
if (me.isColumnSelected(header)) {
me.deselectColumn(header);
} else {
me.selectColumn(header, e.ctrlKey);
}
}
},
updateHeaderState: function() {
var me = this,
store = me.view.dataSource,
storeCount = store.getCount(),
views = me.views,
sel = me.selected,
isChecked = sel && sel.isRows && !store.isBufferedStore && storeCount > 0 && (storeCount === sel.getCount()),
checkHd = me.checkColumn,
cls = me.checkerOnCls;
if (views && views.length) {
if (checkHd) {
if (isChecked) {
checkHd.addCls(cls);
} else {
checkHd.removeCls(cls);
}
}
}
},
onReconfigure: function(grid, store, columns) {
if (columns) {
this.addCheckbox(this.views[0]);
}
},
getCellContext: function(record, column) {
return new Ext.grid.CellContext(this.view.ownerGrid.getView()).setPosition(record, column);
},
select: function(records, keepExisting, suppressEvent) {
var me = this,
sel = me.selected,
view = me.view,
store = view.dataSource,
len, i, record,
changed = false;
if (!sel || !sel.isRows || sel.view !== view) {
me.resetSelection(true);
sel = me.selected = new Ext.grid.selection.Rows(view);
} else if (!keepExisting) {
sel.clear();
}
if (!Ext.isArray(records)) {
records = [
records
];
}
len = records.length;
for (i = 0; i < len; i++) {
record = records[i];
if (typeof record === 'number') {
record = store.getAt(record);
}
if (!sel.contains(record)) {
sel.add(record);
changed = true;
}
}
if (changed) {
me.updateHeaderState();
if (suppressEvent) {
me.fireSelectionChange();
}
}
},
deselect: function(records, suppressEvent) {
var me = this,
sel = me.selected,
store = me.view.dataSource,
len, i, record,
changed = false;
if (sel && sel.isRows) {
if (!Ext.isArray(records)) {
records = [
records
];
}
len = records.length;
for (i = 0; i < len; i++) {
record = records[i];
if (typeof record === 'number') {
record = store.getAt(record);
}
changed = changed || sel.remove(record);
}
}
if (changed) {
me.updateHeaderState();
if (!suppressEvent) {
me.fireSelectionChange();
}
}
},
selectCells: function(rangeStart, rangeEnd, suppressEvent) {
var me = this,
view = me.view.ownerGrid.view,
sel;
rangeStart = rangeStart.isCellContext ? rangeStart.clone() : new Ext.grid.CellContext(view).setPosition(rangeStart);
rangeEnd = rangeEnd.isCellContext ? rangeEnd.clone() : new Ext.grid.CellContext(view).setPosition(rangeEnd);
me.resetSelection(true);
me.selected = sel = new Ext.grid.selection.Cells(rangeStart.view);
sel.setRangeStart(rangeStart);
sel.setRangeEnd(rangeEnd);
if (!suppressEvent) {
me.fireSelectionChange();
}
},
selectAll: function(suppressEvent) {
var me = this,
sel = me.selected,
doSelect,
view = me.view;
if (me.rowSelect) {
if (!sel || !sel.isRows) {
me.resetSelection(true);
me.selected = sel = new Ext.grid.selection.Rows(view);
}
doSelect = true;
} else if (me.cellSelect) {
if (!sel || !sel.isCells) {
me.resetSelection(true);
me.selected = sel = new Ext.grid.selection.Cells(view);
}
doSelect = true;
} else if (me.columnSelect) {
if (!sel || !sel.isColumns) {
me.resetSelection(true);
me.selected = sel = new Ext.grid.selection.Columns(view);
}
doSelect = true;
}
if (doSelect) {
sel.selectAll();
me.updateHeaderState();
if (!suppressEvent) {
me.fireSelectionChange();
}
}
},
deselectAll: function(suppressEvent) {
var sel = this.selected;
if (sel && sel.getCount()) {
sel.clear();
if (!suppressEvent) {
this.fireSelectionChange();
}
}
},
selectRows: function(rows, keepSelection, suppressEvent) {
var me = this,
sel = me.selected,
isSelectingRows = sel && !sel.isRows,
len = rows.length,
i;
if (!keepSelection || isSelectingRows) {
me.resetSelection(true);
}
if (!isSelectingRows) {
me.selected = sel = new Ext.grid.selection.Rows(me.view);
}
for (i = 0; i < len; i++) {
sel.add(rows[i]);
}
if (!suppressEvent) {
me.fireSelectionChange();
}
},
isSelected: function(record) {
return this.isRowSelected(record);
},
selectColumn: function(column, keepSelection, suppressEvent) {
var me = this,
selData = me.selected,
view = column.getView();
if (!selData || !selData.isColumns || selData.view !== view.ownerGrid.view) {
me.resetSelection(true);
me.selected = selData = new Ext.grid.selection.Columns(view);
}
if (!selData.contains(column)) {
if (!keepSelection) {
selData.clear();
}
selData.add(column);
me.updateHeaderState();
if (!suppressEvent) {
me.fireSelectionChange();
}
}
},
deselectColumn: function(column, suppressEvent) {
var me = this,
selData = me.getSelected();
if (selData && selData.isColumns && selData.contains(column)) {
selData.remove(column);
me.updateHeaderState();
if (!suppressEvent) {
me.fireSelectionChange();
}
}
},
getSelection: function() {
var selData = this.selected;
if (selData && selData.isRows) {
return selData.getRecords();
}
return [];
},
destroy: function() {
var me = this,
scrollEls = me.scrollEls;
Ext.destroy(me.gridListeners, me.viewListeners, me.selected, me.navigationListeners);
if (scrollEls) {
Ext.dd.ScrollManager.unregister(scrollEls);
}
me.selected = me.gridListeners = me.viewListeners = me.selectionData = me.navigationListeners = me.scrollEls = null;
me.callParent();
},
privates: {
getViewListeners: function() {
return {
beforerefresh: this.onBeforeViewRefresh,
keyup: {
element: 'el',
fn: this.onViewKeyUp,
scope: this
}
};
},
onViewKeyUp: function(e) {
var sel = this.selected;
if (e.keyCode === e.SHIFT && sel && sel.isRows && sel.getRangeSize()) {
sel.addRange();
}
},
onColumnsChanged: function() {
var selData = this.selected,
rowRange, colCount, colIdx, rowIdx, view, context;
if (selData && selData.isCells) {
view = selData.view;
context = new Ext.grid.CellContext(view);
rowRange = selData.getRowRange();
colCount = view.getVisibleColumnManager().getColumns().length;
for (rowIdx = rowRange[0]; rowIdx <= rowRange[1]; rowIdx++) {
context.setRow(rowIdx);
for (colIdx = 0; colIdx < colCount; colIdx++) {
context.setColumn(colIdx);
view.onCellDeselect(context);
}
}
}
},
onBeforeViewRefresh: function(view) {
var selData = this.selected;
if (view.refreshCounter) {
if (selData && selData.isCells) {
this.resetSelection();
}
}
},
resetSelection: function(suppressEvent) {
var sel = this.selected;
if (sel) {
sel.clear();
if (!suppressEvent) {
this.fireSelectionChange();
}
}
},
onViewCreated: function(grid, view) {
var me = this,
ownerGrid = view.ownerGrid,
headerCt = view.headerCt,
shrinkwrapLocked = ownerGrid.shrinkWrapLocked;
if (!ownerGrid.lockable || view.isLockedView) {
if (me.getRowSelect() && !headerCt.down('rownumberer')) {
me.numbererColumn = headerCt.add(0, {
xtype: 'rownumberer',
width: me.rowNumbererHeaderWidth,
editRenderer: '&#160;',
tdCls: me.rowNumbererTdCls,
cls: me.rowNumbererHeaderCls,
locked: me.hasLockedHeader
});
if (shrinkwrapLocked) {
grid.width += me.numbererColumn.width;
}
}
if (me.checkboxSelect) {
me.addCheckbox(view, true);
me.mon(view.ownerGrid, 'reconfigure', me.onReconfigure, me);
if (shrinkwrapLocked) {
grid.width += me.checkColumn.width;
}
}
}
headerCt.sortOnClick = !me.getColumnSelect();
if (me.getDragSelect()) {
view.on('render', me.onViewRender, me, {
single: true
});
}
},
onViewRender: function(view) {
var me = this,
el = view.getEl();
el.ddScrollConfig = {
vthresh: 50,
hthresh: 50,
frequency: 300,
increment: 100
};
Ext.dd.ScrollManager.register(el);
(me.scrollEls || (me.scrollEls = [])).push(el);
view.on('cellmousedown', me.handleMouseDown, me);
if (view.lockingPartner) {
view.lockingPartner.on('cellmousedown', me.handleMouseDown, me);
}
},
handleMouseDown: function(view, td, cellIndex, record, tr, rowIdx, e) {
var me = this,
sel = me.selected,
header = e.position.column,
isCheckClick, startDragSelect;
if (e.button || e.shiftKey || e.altKey || e.pointerType === 'touch') {
return;
}
if (header) {
isCheckClick = header === me.checkColumn;
if (header === me.numbererColumn || isCheckClick || !me.cellSelect) {
if (me.rowSelect) {
if (sel && sel.isRows) {
if (!e.ctrlKey && !isCheckClick) {
sel.clear();
}
} else {
if (sel) {
sel.clear();
}
sel = me.selected = new Ext.grid.selection.Rows(view);
}
startDragSelect = true;
}
} else {
if (sel) {
sel.clear();
}
if (!sel || !sel.isCells) {
sel = me.selected = new Ext.grid.selection.Cells(view);
}
startDragSelect = true;
}
me.lastOverRecord = me.lastOverColumn = null;
Ext.getBody().on('mouseup', me.onMouseUp, me, {
single: true,
view: sel.view
});
if (startDragSelect) {
sel.view.el.on('mousemove', me.onMouseMove, me, {
view: sel.view
});
}
}
},
onMouseMove: function(e, target, opts) {
var me = this,
view = opts.view,
record, rowIdx,
cell = e.getTarget(view.cellSelector),
header = opts.view.getHeaderByCell(cell),
selData = me.selected,
pos, recChange, colChange;
if (header) {
record = view.getRecord(cell.parentNode);
rowIdx = me.store.indexOf(record);
recChange = record !== me.lastOverRecord;
colChange = header !== me.lastOverColumn;
if (recChange || colChange) {
pos = me.getCellContext(record, header);
}
if (selData.isRows) {
if (recChange) {
if (me.lastOverRecord) {
selData.setRangeEnd(rowIdx);
} else {
selData.setRangeStart(rowIdx);
}
}
} else
{
if (recChange || colChange) {
if (me.lastOverRecord) {
selData.setRangeEnd(pos);
} else {
selData.setRangeStart(pos);
}
}
}
if (recChange || colChange) {
view.getNavigationModel().setPosition(new Ext.grid.CellContext(header.getView()).setPosition(record, header));
}
me.lastOverColumn = header;
me.lastOverRecord = record;
}
},
onMouseUp: function(e, target, opts) {
var me = this,
view = opts.view;
if (view && !view.isDestroyed) {
view.el.un('mousemove', me.onMouseMove, me);
if (me.selected.isRows) {
me.selected.addRange();
}
me.fireSelectionChange();
}
},
addCheckbox: function(view, initial) {
var me = this,
checkbox = me.checkboxColumnIndex,
headerCt = view.headerCt;
if (checkbox !== false) {
if (checkbox === 'first') {
checkbox = 0;
} else if (checkbox === 'last') {
checkbox = headerCt.getColumnCount();
}
me.checkColumn = headerCt.add(checkbox, me.getCheckboxHeaderConfig());
}
if (initial !== true) {
view.refresh();
}
},
onNavigate: function(navigateEvent) {
var me = this,
view = navigateEvent.view.ownerGrid.view,
record = navigateEvent.record,
sel = me.selected,
pos = new Ext.grid.CellContext(view).setPosition(record, navigateEvent.column),
keyEvent = navigateEvent.keyEvent,
keyCode = keyEvent.getKey(),
selectionChanged;
if (keyEvent.ctrlKey && (keyCode === keyEvent.UP || keyCode === keyEvent.LEFT || keyCode === keyEvent.RIGHT || keyCode === keyEvent.DOWN)) {
return;
}
if (sel && sel.isCells && sel.getCount() > 1 && keyEvent.type === 'click') {
return;
}
if (!(me.cellSelect || me.columnSelect || me.rowSelect) || !navigateEvent.record || keyEvent.type === 'mousedown') {
return;
}
if (keyEvent.ctrlKey && keyEvent.keyCode === keyEvent.A) {
if (!sel || sel.getCount() < 2) {
me.selectAll();
} else {
me.deselectAll();
}
me.updateHeaderState();
return;
}
if (keyEvent.shiftKey) {
if (pos.column === me.numbererColumn || pos.column === me.checkColumn || !me.cellSelect || (sel && sel.isRows)) {
if (me.rowSelect) {
if (!sel || !sel.isRows || sel.view !== view) {
me.resetSelection(true);
sel = me.selected = new Ext.grid.selection.Rows(view);
}
if (!sel.getRangeSize()) {
sel.setRangeStart(navigateEvent.previousRecordIndex || 0);
}
sel.setRangeEnd(navigateEvent.recordIndex);
selectionChanged = true;
}
} else
{
if (me.cellSelect) {
if (!sel || !sel.isCells || sel.view !== view) {
me.resetSelection(true);
sel = me.selected = new Ext.grid.selection.Cells(view);
}
if (!sel.getRangeSize()) {
sel.setRangeStart(navigateEvent.previousPosition || me.getCellContext(0, 0));
}
sel.setRangeEnd(pos);
selectionChanged = true;
}
}
} else {
if (pos.column === me.numbererColumn || pos.column === me.checkColumn || !me.cellSelect) {
if (me.rowSelect) {
if (!sel || !sel.isRows || sel.view !== view) {
me.resetSelection(true);
sel = me.selected = new Ext.grid.selection.Rows(view);
}
if (keyEvent.ctrlKey || pos.column === me.checkColumn) {
if (sel.contains(record)) {
sel.remove(record);
} else {
sel.add(record);
}
} else {
sel.clear();
sel.add(record);
}
selectionChanged = true;
}
} else
{
if (me.cellSelect) {
if (!sel || !sel.isCells || sel.view !== view) {
me.resetSelection(true);
me.selected = sel = new Ext.grid.selection.Cells(view);
} else {
sel.clear();
}
sel.setRangeStart(pos);
selectionChanged = true;
}
}
}
if (selectionChanged) {
if (sel.isRows) {
me.updateHeaderState();
}
me.fireSelectionChange();
}
},
isRowSelected: function(record) {
var me = this,
sel = me.selected;
if (sel && sel.isRows) {
record = Ext.isNumber(record) ? me.store.getAt(record) : record;
return sel.contains(record);
} else {
return false;
}
},
isColumnSelected: function(column) {
var me = this,
sel = me.selected;
if (sel && sel.isColumns) {
return sel.contains(column);
} else {
return false;
}
},
isCellSelected: function(view, row, column) {
var me = this,
testPos,
sel = me.selected;
view = view.ownerGrid.view;
if (sel) {
if (sel.isColumns) {
if (typeof column === 'number') {
column = view.getVisibleColumnManager().getColumns()[column];
}
return sel.contains(column);
}
if (sel.isCells) {
testPos = new Ext.grid.CellContext(view).setPosition({
row: row,
column: column
});
return sel.contains(testPos);
}
}
return false;
},
applySelected: function(selected) {
if (selected && !(selected.isRows || selected.isCells || selected.isColumns)) {
Ext.error.raise('SpreadsheelModel#setSelected must be passed an instance of Ext.grid.selection.Selection');
}
return selected;
},
updateSelected: function(selected, oldSelected) {
var view, columns, len, i, cell;
if (oldSelected) {
oldSelected.clear();
}
if (selected && selected.getCount()) {
view = selected.view;
if (selected.isRows) {
selected.eachRow(view.onRowSelect, view);
}
else if (selected.isColumns) {
columns = selected.getColumns();
len = columns.length;
if (len) {
cell = new Ext.grid.CelContext(view);
view.store.each(function(rec) {
cell.setRow(rec);
for (i = 0; i < len; i++) {
cell.setColumn(columns[i]);
view.onCellSelect(cell);
}
});
}
}
else if (selected.isCells) {
selected.eachCell(view.onCellSelect, view);
}
}
},
updateRowSelect: function(rowSelect) {
var me = this,
sel = me.selected,
view = me.view;
if (view && view.rendered) {
if (view.isNormalView) {
view = view.lockingPartner;
}
if (rowSelect) {
if (me.checkColumn) {
me.checkColumn.show();
}
if (me.numbererColumn) {
me.numbererColumn.show();
} else {
me.numbererColumn = view.headerCt.add(0, {
xtype: 'rownumberer',
width: me.rowNumbererHeaderWidth,
editRenderer: '&#160;',
tdCls: me.rowNumbererTdCls,
cls: me.rowNumbererHeaderCls,
locked: me.hasLockedHeader
});
}
} else {
if (me.checkColumn) {
me.checkColumn.hide();
}
if (me.numbererColumn) {
me.numbererColumn.hide();
}
}
if (!rowSelect && sel && sel.isRows) {
sel.clear();
me.fireSelectionChange();
}
}
},
updateColumnSelect: function(columnSelect) {
var me = this,
sel = me.selected,
views = me.views,
len = views ? views.length : 0,
i;
for (i = 0; i < len; i++) {
views[i].headerCt.sortOnClick = !columnSelect;
}
if (!columnSelect && sel && sel.isColumns) {
sel.clear();
me.fireSelectionChange();
}
if (columnSelect) {
me.view.ownerGrid.addCls(me.columnSelectCls);
} else {
me.view.ownerGrid.removeCls(me.columnSelectCls);
}
},
updateCellSelect: function(cellSelect) {
var me = this,
sel = me.selected;
if (!cellSelect && sel && sel.isCells) {
sel.clear();
me.fireSelectionChange();
}
},
fireSelectionChange: function() {
var grid = this.view.ownerGrid;
grid.fireEvent('selectionchange', grid, this.selected);
},
onIdChanged: function(store, rec, oldId, newId) {
var sel = this.selected;
if (sel && sel.isRows && sel.selectedRecords) {
sel.selectedRecords.updateKey(rec, oldId);
}
},
onPageAdd: function(pageMap, pageNumber, records) {
var sel = this.selected,
len = records.length,
i, record,
selected = sel && sel.selectedRecords;
if (selected && sel.isRows) {
for (i = 0; i < len; i++) {
record = records[i];
if (selected.get(record.id)) {
selected.replace(record);
}
}
}
},
refresh: function() {
var sel = this.getSelected();
if (sel && sel.isRows) {
this.callParent();
}
},
onStoreAdd: function() {
var sel = this.getSelected();
if (sel && sel.isRows) {
this.callParent(arguments);
this.updateHeaderState();
}
},
onStoreClear: function() {
this.resetSelection();
},
onStoreLoad: function() {
var sel = this.getSelected();
if (sel && sel.isRows) {
this.callParent(arguments);
this.updateHeaderState();
}
},
onStoreRefresh: function() {
var sel = this.selected;
if (sel && sel.isRows && sel.selectedRecords) {
this.updateSelectedInstances(sel.selectedRecords);
}
this.updateHeaderState();
},
onStoreRemove: function() {
var sel = this.getSelected();
if (sel && sel.isRows) {
this.callParent(arguments);
}
}
}
});
Ext.define('Ext.util.Queue', {
constructor: function() {
this.clear();
},
add: function(obj) {
var me = this,
key = me.getKey(obj);
if (!me.map[key]) {
++me.length;
me.items.push(obj);
me.map[key] = obj;
}
return obj;
},
clear: function() {
var me = this,
items = me.items;
me.items = [];
me.map = {};
me.length = 0;
return items;
},
contains: function(obj) {
var key = this.getKey(obj);
return this.map.hasOwnProperty(key);
},
getCount: function() {
return this.length;
},
getKey: function(obj) {
return obj.id;
},
remove: function(obj) {
var me = this,
key = me.getKey(obj),
items = me.items,
index;
if (me.map[key]) {
index = Ext.Array.indexOf(items, obj);
Ext.Array.erase(items, index, 1);
delete me.map[key];
--me.length;
}
return obj;
}
});
Ext.define('Ext.layout.ContextItem', {
heightModel: null,
widthModel: null,
sizeModel: null,
optOut: false,
ownerSizePolicy: null,
boxChildren: null,
boxParent: null,
children: [],
dirty: null,
dirtyCount: 0,
hasRawContent: true,
isContextItem: true,
isTopLevel: false,
consumersContentHeight: 0,
consumersContentWidth: 0,
consumersContainerHeight: 0,
consumersContainerWidth: 0,
consumersHeight: 0,
consumersWidth: 0,
ownerCtContext: null,
remainingChildDimensions: 0,
props: null,
state: null,
wrapsComponent: false,
constructor: function(config) {
var me = this,
sizeModels = Ext.layout.SizeModel.sizeModels,
configured = sizeModels.configured,
shrinkWrap = sizeModels.shrinkWrap,
el, lastBox, ownerCt, ownerCtContext, props, sizeModel, target, lastWidth, lastHeight, sameWidth, sameHeight, widthModel, heightModel, optOut;
Ext.apply(me, config);
target = me.target;
el = me.el;
me.id = target.id;
me.flushedProps = {};
me.props = props = {};
me.styles = {};
if (!target.isComponent) {
lastBox = el.lastBox;
} else {
me.wrapsComponent = true;
me.framing = target.frameSize || null;
me.isComponentChild = target.ownerLayout && target.ownerLayout.isComponentLayout;
lastBox = target.lastBox;
ownerCt = target.ownerCt;
if (ownerCt && (ownerCtContext = ownerCt.el && me.context.items[ownerCt.el.id])) {
me.ownerCtContext = ownerCtContext;
}
me.sizeModel = sizeModel = target.getSizeModel(ownerCtContext && ownerCtContext.widthModel.pairsByHeightOrdinal[ownerCtContext.heightModel.ordinal]);
me.widthModel = widthModel = sizeModel.width;
me.heightModel = heightModel = sizeModel.height;
if (lastBox && lastBox.invalid === false) {
sameWidth = (target.width === (lastWidth = lastBox.width));
sameHeight = (target.height === (lastHeight = lastBox.height));
if (widthModel === shrinkWrap && heightModel === shrinkWrap) {
optOut = true;
} else if (widthModel === configured && sameWidth) {
optOut = heightModel === shrinkWrap || (heightModel === configured && sameHeight);
}
if (optOut) {
me.optOut = true;
props.width = lastWidth;
props.height = lastHeight;
}
}
}
me.lastBox = lastBox;
},
init: function(full, options) {
var me = this,
oldProps = me.props,
oldDirty = me.dirty,
ownerCtContext = me.ownerCtContext,
ownerLayout = me.target.ownerLayout,
firstTime = !me.state,
ret = full || firstTime,
children, i, n, ownerCt, sizeModel, target,
oldHeightModel = me.heightModel,
oldWidthModel = me.widthModel,
newHeightModel, newWidthModel,
remainingCount = 0;
me.dirty = me.invalid = false;
me.props = {};
me.remainingChildDimensions = 0;
if (me.boxChildren) {
me.boxChildren.length = 0;
}
if (!firstTime) {
me.clearAllBlocks('blocks');
me.clearAllBlocks('domBlocks');
}
if (!me.wrapsComponent) {
return ret;
}
target = me.target;
me.state = {};
if (firstTime) {
if (target.beforeLayout && target.beforeLayout !== Ext.emptyFn) {
target.beforeLayout();
}
if (!ownerCtContext && (ownerCt = target.ownerCt)) {
ownerCtContext = me.context.items[ownerCt.el.id];
}
if (ownerCtContext) {
me.ownerCtContext = ownerCtContext;
me.isBoxParent = ownerLayout && ownerLayout.isItemBoxParent(me);
} else {
me.isTopLevel = true;
}
me.frameBodyContext = me.getEl('frameBody');
} else {
ownerCtContext = me.ownerCtContext;
me.isTopLevel = !ownerCtContext;
children = me.children;
for (i = 0 , n = children.length; i < n; ++i) {
children[i].init(true);
}
}
me.hasRawContent = !(target.isContainer && target.items.items.length > 0);
if (full) {
me.widthModel = me.heightModel = null;
sizeModel = target.getSizeModel(ownerCtContext && ownerCtContext.widthModel.pairsByHeightOrdinal[ownerCtContext.heightModel.ordinal]);
if (firstTime) {
me.sizeModel = sizeModel;
}
me.widthModel = sizeModel.width;
me.heightModel = sizeModel.height;
if (ownerCtContext && !me.isComponentChild) {
if (ownerLayout.needsItemSize || !target.liquidLayout) {
ownerCtContext.remainingChildDimensions += 2;
} else {
if (me.widthModel.calculated) {
++ownerCtContext.remainingChildDimensions;
}
if (me.heightModel.calculated) {
++ownerCtContext.remainingChildDimensions;
}
}
}
} else if (oldProps) {
me.recoverProp('x', oldProps, oldDirty);
me.recoverProp('y', oldProps, oldDirty);
if (me.widthModel.calculated) {
me.recoverProp('width', oldProps, oldDirty);
} else if ('width' in oldProps) {
++remainingCount;
}
if (me.heightModel.calculated) {
me.recoverProp('height', oldProps, oldDirty);
} else if ('height' in oldProps) {
++remainingCount;
}
if (ownerCtContext && !me.isComponentChild) {
ownerCtContext.remainingChildDimensions += remainingCount;
}
}
if (oldProps && ownerLayout && ownerLayout.manageMargins) {
me.recoverProp('margin-top', oldProps, oldDirty);
me.recoverProp('margin-right', oldProps, oldDirty);
me.recoverProp('margin-bottom', oldProps, oldDirty);
me.recoverProp('margin-left', oldProps, oldDirty);
}
if (options) {
newHeightModel = options.heightModel;
newWidthModel = options.widthModel;
if (newWidthModel && newHeightModel && oldWidthModel && oldHeightModel) {
if (oldWidthModel.shrinkWrap && oldHeightModel.shrinkWrap) {
if (newWidthModel.constrainedMax && newHeightModel.constrainedMin) {
newHeightModel = null;
}
}
}
if (newWidthModel) {
me.widthModel = newWidthModel;
}
if (newHeightModel) {
me.heightModel = newHeightModel;
}
if (options.state) {
Ext.apply(me.state, options.state);
}
}
return ret;
},
initContinue: function(full) {
var me = this,
ownerCtContext = me.ownerCtContext,
comp = me.target,
widthModel = me.widthModel,
inheritedState = comp.getInherited(),
boxParent;
if (widthModel.fixed) {
inheritedState.inShrinkWrapTable = false;
} else {
delete inheritedState.inShrinkWrapTable;
}
if (full) {
if (ownerCtContext && widthModel.shrinkWrap) {
boxParent = ownerCtContext.isBoxParent ? ownerCtContext : ownerCtContext.boxParent;
if (boxParent) {
boxParent.addBoxChild(me);
}
} else if (widthModel.natural) {
me.boxParent = ownerCtContext;
}
}
return full;
},
initDone: function(containerLayoutDone) {
var me = this,
props = me.props,
state = me.state;
if (me.remainingChildDimensions === 0) {
props.containerChildrenSizeDone = true;
}
if (containerLayoutDone) {
props.containerLayoutDone = true;
}
if (me.boxChildren && me.boxChildren.length && me.widthModel.shrinkWrap) {
me.el.setWidth(10000);
state.blocks = (state.blocks || 0) + 1;
}
},
initAnimation: function() {
var me = this,
target = me.target,
ownerCtContext = me.ownerCtContext;
if (ownerCtContext && ownerCtContext.isTopLevel) {
me.animatePolicy = target.ownerLayout.getAnimatePolicy(me);
} else if (!ownerCtContext && target.isCollapsingOrExpanding && target.animCollapse) {
me.animatePolicy = target.componentLayout.getAnimatePolicy(me);
}
if (me.animatePolicy) {
me.context.queueAnimation(me);
}
},
addBlock: function(name, layout, propName) {
var me = this,
collection = me[name] || (me[name] = {}),
blockedLayouts = collection[propName] || (collection[propName] = {});
if (!blockedLayouts[layout.id]) {
blockedLayouts[layout.id] = layout;
++layout.blockCount;
++me.context.blockCount;
}
},
addBoxChild: function(boxChildItem) {
var me = this,
children,
widthModel = boxChildItem.widthModel;
boxChildItem.boxParent = this;
boxChildItem.measuresBox = widthModel.shrinkWrap ? boxChildItem.hasRawContent : widthModel.natural;
if (boxChildItem.measuresBox) {
children = me.boxChildren;
if (children) {
children.push(boxChildItem);
} else {
me.boxChildren = [
boxChildItem
];
}
}
},
addPositionStyles: function(styles, props) {
var x = props.x,
y = props.y,
count = 0;
if (x !== undefined) {
styles.left = x + 'px';
++count;
}
if (y !== undefined) {
styles.top = y + 'px';
++count;
}
return count;
},
addTrigger: function(propName, inDom) {
var me = this,
name = inDom ? 'domTriggers' : 'triggers',
collection = me[name] || (me[name] = {}),
context = me.context,
layout = context.currentLayout,
triggers = collection[propName] || (collection[propName] = {});
if (!triggers[layout.id]) {
triggers[layout.id] = layout;
++layout.triggerCount;
triggers = context.triggers[inDom ? 'dom' : 'data'];
(triggers[layout.id] || (triggers[layout.id] = [])).push({
item: this,
prop: propName
});
if (me.props[propName] !== undefined) {
if (!inDom || !(me.dirty && (propName in me.dirty))) {
++layout.firedTriggers;
}
}
}
},
boxChildMeasured: function() {
var me = this,
state = me.state,
count = (state.boxesMeasured = (state.boxesMeasured || 0) + 1);
if (count === me.boxChildren.length) {
state.clearBoxWidth = 1;
++me.context.progressCount;
me.markDirty();
}
},
borderNames: [
'border-top-width',
'border-right-width',
'border-bottom-width',
'border-left-width'
],
marginNames: [
'margin-top',
'margin-right',
'margin-bottom',
'margin-left'
],
paddingNames: [
'padding-top',
'padding-right',
'padding-bottom',
'padding-left'
],
trblNames: [
'top',
'right',
'bottom',
'left'
],
cacheMissHandlers: {
borderInfo: function(me) {
var info = me.getStyles(me.borderNames, me.trblNames);
info.width = info.left + info.right;
info.height = info.top + info.bottom;
return info;
},
marginInfo: function(me) {
var info = me.getStyles(me.marginNames, me.trblNames);
info.width = info.left + info.right;
info.height = info.top + info.bottom;
return info;
},
paddingInfo: function(me) {
var item = me.frameBodyContext || me,
info = item.getStyles(me.paddingNames, me.trblNames);
info.width = info.left + info.right;
info.height = info.top + info.bottom;
return info;
}
},
checkCache: function(entry) {
return this.cacheMissHandlers[entry](this);
},
clearAllBlocks: function(name) {
var collection = this[name],
propName;
if (collection) {
for (propName in collection) {
this.clearBlocks(name, propName);
}
}
},
clearBlocks: function(name, propName) {
var collection = this[name],
blockedLayouts = collection && collection[propName],
context, layout, layoutId;
if (blockedLayouts) {
delete collection[propName];
context = this.context;
for (layoutId in blockedLayouts) {
layout = blockedLayouts[layoutId];
--context.blockCount;
if (!--layout.blockCount && !layout.pending && !layout.done) {
context.queueLayout(layout);
}
}
}
},
block: function(layout, propName) {
this.addBlock('blocks', layout, propName);
},
domBlock: function(layout, propName) {
this.addBlock('domBlocks', layout, propName);
},
fireTriggers: function(name, propName) {
var collection = this[name],
triggers = collection && collection[propName],
context = this.context,
layout, layoutId;
if (triggers) {
for (layoutId in triggers) {
layout = triggers[layoutId];
++layout.firedTriggers;
if (!layout.done && !layout.blockCount && !layout.pending) {
context.queueLayout(layout);
}
}
}
},
flush: function() {
var me = this,
dirty = me.dirty,
state = me.state,
targetEl = me.el;
me.dirtyCount = 0;
if ('attributes' in me) {
targetEl.set(me.attributes);
delete me.attributes;
}
if ('innerHTML' in me) {
targetEl.innerHTML = me.innerHTML;
delete me.innerHTML;
}
if (state && state.clearBoxWidth) {
state.clearBoxWidth = 0;
me.el.setStyle('width', null);
if (!--state.blocks) {
me.context.queueItemLayouts(me);
}
}
if (dirty) {
delete me.dirty;
me.writeProps(dirty, true);
}
},
flushAnimations: function() {
var me = this,
animateFrom = me.previousSize,
target, targetAnim, duration, animateProps, anim, changeCount, j, propsLen, propName, oldValue, newValue;
if (animateFrom) {
target = me.target;
targetAnim = target.getAnimationProps();
duration = targetAnim.duration;
animateProps = Ext.Object.getKeys(me.animatePolicy);
anim = Ext.apply({}, {
from: {},
to: {},
duration: duration || Ext.fx.Anim.prototype.duration
}, targetAnim);
for (changeCount = 0 , j = 0 , propsLen = animateProps.length; j < propsLen; j++) {
propName = animateProps[j];
oldValue = animateFrom[propName];
newValue = me.peek(propName);
if (oldValue !== newValue) {
propName = me.translateProps[propName] || propName;
anim.from[propName] = oldValue;
anim.to[propName] = newValue;
++changeCount;
}
}
if (changeCount) {
if (me.isCollapsingOrExpanding === 1) {
target.componentLayout.undoLayout(me);
} else
{
me.writeProps(anim.from);
}
me.el.animate(anim);
anim = Ext.fx.Manager.getFxQueue(me.el.id)[0];
target.$layoutAnim = anim;
anim.on({
afteranimate: function() {
delete target.$layoutAnim;
if (me.isCollapsingOrExpanding === 1) {
target.componentLayout.redoLayout(me);
target.afterCollapse(true);
} else if (me.isCollapsingOrExpanding === 2) {
target.afterExpand(true);
}
}
});
}
}
},
getBorderInfo: function() {
var me = this,
info = me.borderInfo;
if (!info) {
me.borderInfo = info = me.checkCache('borderInfo');
}
return info;
},
getEl: function(nameOrEl, owner) {
var me = this,
src, el, elContext;
if (nameOrEl) {
if (nameOrEl.dom) {
el = nameOrEl;
} else {
src = me.target;
if (owner) {
src = owner;
}
el = src[nameOrEl];
if (typeof el === 'function') {
el = el.call(src);
if (el === me.el) {
return this;
}
}
}
if (el) {
elContext = me.context.getEl(me, el);
}
}
return elContext || null;
},
getFrameInfo: function() {
var me = this,
info = me.frameInfo,
framing, border;
if (!info) {
framing = me.framing;
border = me.getBorderInfo();
me.frameInfo = info = framing ? {
top: framing.top + border.top,
right: framing.right + border.right,
bottom: framing.bottom + border.bottom,
left: framing.left + border.left,
width: framing.width + border.width,
height: framing.height + border.height
} : border;
}
return info;
},
getMarginInfo: function() {
var me = this,
info = me.marginInfo,
comp, manageMargins, ownerLayout, ownerLayoutId;
if (!info) {
if (!me.wrapsComponent) {
info = me.checkCache('marginInfo');
} else {
comp = me.target;
ownerLayout = comp.ownerLayout;
ownerLayoutId = ownerLayout ? ownerLayout.id : null;
manageMargins = ownerLayout && ownerLayout.manageMargins;
info = comp.margin$;
if (info && info.ownerId !== ownerLayoutId) {
info = null;
}
if (!info) {
info = me.parseMargins(comp, comp.margin) || me.checkCache('marginInfo');
if (manageMargins) {
me.setProp('margin-top', 0);
me.setProp('margin-right', 0);
me.setProp('margin-bottom', 0);
me.setProp('margin-left', 0);
}
info.ownerId = ownerLayoutId;
comp.margin$ = info;
}
info.width = info.left + info.right;
info.height = info.top + info.bottom;
}
me.marginInfo = info;
}
return info;
},
clearMarginCache: function() {
delete this.marginInfo;
delete this.target.margin$;
},
getPaddingInfo: function() {
var me = this,
info = me.paddingInfo;
if (!info) {
me.paddingInfo = info = me.checkCache('paddingInfo');
}
return info;
},
getProp: function(propName) {
var me = this,
result = me.props[propName];
me.addTrigger(propName);
return result;
},
getDomProp: function(propName) {
var me = this,
result = (me.dirty && (propName in me.dirty)) ? undefined : me.props[propName];
me.addTrigger(propName, true);
return result;
},
getStyle: function(styleName) {
var me = this,
styles = me.styles,
info, value;
if (styleName in styles) {
value = styles[styleName];
} else {
info = me.styleInfo[styleName];
value = me.el.getStyle(styleName);
if (info && info.parseInt) {
value = parseInt(value, 10) || 0;
}
styles[styleName] = value;
}
return value;
},
getStyles: function(styleNames, altNames) {
var me = this,
styleCache = me.styles,
values = {},
hits = 0,
n = styleNames.length,
i, missing, missingAltNames, name, info, styleInfo, styles, value;
altNames = altNames || styleNames;
for (i = 0; i < n; ++i) {
name = styleNames[i];
if (name in styleCache) {
values[altNames[i]] = styleCache[name];
++hits;
if (i && hits === 1) {
missing = styleNames.slice(0, i);
missingAltNames = altNames.slice(0, i);
}
} else if (hits) {
(missing || (missing = [])).push(name);
(missingAltNames || (missingAltNames = [])).push(altNames[i]);
}
}
if (hits < n) {
missing = missing || styleNames;
missingAltNames = missingAltNames || altNames;
styleInfo = me.styleInfo;
styles = me.el.getStyle(missing);
for (i = missing.length; i--; ) {
name = missing[i];
info = styleInfo[name];
value = styles[name];
if (info && info.parseInt) {
value = parseInt(value, 10) || 0;
}
values[missingAltNames[i]] = value;
styleCache[name] = value;
}
}
return values;
},
hasProp: function(propName) {
return this.getProp(propName) != null;
},
hasDomProp: function(propName) {
return this.getDomProp(propName) != null;
},
invalidate: function(options) {
this.context.queueInvalidate(this, options);
},
markDirty: function() {
if (++this.dirtyCount === 1) {
this.context.queueFlush(this);
}
},
onBoxMeasured: function() {
var boxParent = this.boxParent,
state = this.state;
if (boxParent && boxParent.widthModel.shrinkWrap && !state.boxMeasured && this.measuresBox) {
state.boxMeasured = 1;
boxParent.boxChildMeasured();
}
},
parseMargins: function(comp, margins) {
if (margins === true) {
margins = 5;
}
var type = typeof margins,
ret;
if (type === 'string' || type === 'number') {
ret = comp.parseBox(margins);
} else if (margins) {
ret = {
top: 0,
right: 0,
bottom: 0,
left: 0
};
if (margins) {
margins = Ext.apply(ret, comp.parseBox(margins));
}
}
return ret;
},
peek: function(propName) {
return this.props[propName];
},
recoverProp: function(propName, oldProps, oldDirty) {
var me = this,
props = me.props,
dirty;
if (propName in oldProps) {
props[propName] = oldProps[propName];
if (oldDirty && propName in oldDirty) {
dirty = me.dirty || (me.dirty = {});
dirty[propName] = oldDirty[propName];
}
}
},
redo: function(deep) {
var me = this,
items, len, i;
me.revertProps(me.props);
if (deep && me.wrapsComponent) {
if (me.childItems) {
for (i = 0 , items = me.childItems , len = items.length; i < len; i++) {
items[i].redo(deep);
}
}
for (i = 0 , items = me.children , len = items.length; i < len; i++) {
items[i].redo();
}
}
},
removeEl: function(nameOrEl, owner) {
var me = this,
src, el;
if (nameOrEl) {
if (nameOrEl.dom) {
el = nameOrEl;
} else {
src = me.target;
if (owner) {
src = owner;
}
el = src[nameOrEl];
if (typeof el === 'function') {
el = el.call(src);
if (el === me.el) {
return this;
}
}
}
if (el) {
me.context.removeEl(me, el);
}
}
},
revertProps: function(props) {
var name,
flushed = this.flushedProps,
reverted = {};
for (name in props) {
if (flushed.hasOwnProperty(name)) {
reverted[name] = props[name];
}
}
this.writeProps(reverted);
},
setAttribute: function(name, value) {
var me = this;
if (!me.attributes) {
me.attributes = {};
}
me.attributes[name] = value;
me.markDirty();
},
setBox: function(box) {
var me = this;
if ('left' in box) {
me.setProp('x', box.left);
}
if ('top' in box) {
me.setProp('y', box.top);
}
me.setSize(box.width, box.height);
},
setContentHeight: function(height, measured) {
if (!measured && this.hasRawContent) {
return 1;
}
return this.setProp('contentHeight', height);
},
setContentWidth: function(width, measured) {
if (!measured && this.hasRawContent) {
return 1;
}
return this.setProp('contentWidth', width);
},
setContentSize: function(width, height, measured) {
return this.setContentWidth(width, measured) + this.setContentHeight(height, measured) === 2;
},
setProp: function(propName, value, dirty) {
var me = this,
valueType = typeof value,
info;
if (valueType === 'undefined' || (valueType === 'number' && isNaN(value))) {
return 0;
}
if (me.props[propName] === value) {
return 1;
}
me.props[propName] = value;
++me.context.progressCount;
if (dirty === false) {
me.fireTriggers('domTriggers', propName);
me.clearBlocks('domBlocks', propName);
} else {
info = me.styleInfo[propName];
if (info) {
if (!me.dirty) {
me.dirty = {};
}
me.dirty[propName] = value;
me.markDirty();
}
}
me.fireTriggers('triggers', propName);
me.clearBlocks('blocks', propName);
return 1;
},
setHeight: function(height, dirty)
{
var me = this,
comp = me.target,
ownerCtContext = me.ownerCtContext,
frameBody, frameInfo, min, oldHeight, rem;
if (height < 0) {
height = 0;
}
if (!me.wrapsComponent) {
if (!me.setProp('height', height, dirty)) {
return NaN;
}
} else {
min = me.collapsedVert ? 0 : (comp.minHeight || 0);
height = Ext.Number.constrain(height, min, comp.maxHeight);
oldHeight = me.props.height;
if (!me.setProp('height', height, dirty)) {
return NaN;
}
if (ownerCtContext && !me.isComponentChild && isNaN(oldHeight)) {
rem = --ownerCtContext.remainingChildDimensions;
if (!rem) {
ownerCtContext.setProp('containerChildrenSizeDone', true);
}
}
frameBody = me.frameBodyContext;
if (frameBody) {
frameInfo = me.getFrameInfo();
frameBody[me.el.vertical ? 'setWidth' : 'setHeight'](height - frameInfo.height, dirty);
}
}
return height;
},
setWidth: function(width, dirty)
{
var me = this,
comp = me.target,
ownerCtContext = me.ownerCtContext,
frameBody, frameInfo, min, oldWidth, rem;
if (width < 0) {
width = 0;
}
if (!me.wrapsComponent) {
if (!me.setProp('width', width, dirty)) {
return NaN;
}
} else {
min = me.collapsedHorz ? 0 : (comp.minWidth || 0);
width = Ext.Number.constrain(width, min, comp.maxWidth);
oldWidth = me.props.width;
if (!me.setProp('width', width, dirty)) {
return NaN;
}
if (ownerCtContext && !me.isComponentChild && isNaN(oldWidth)) {
rem = --ownerCtContext.remainingChildDimensions;
if (!rem) {
ownerCtContext.setProp('containerChildrenSizeDone', true);
}
}
frameBody = me.frameBodyContext;
if (frameBody) {
frameInfo = me.getFrameInfo();
frameBody.setWidth(width - frameInfo.width, dirty);
}
}
return width;
},
setSize: function(width, height, dirty) {
this.setWidth(width, dirty);
this.setHeight(height, dirty);
},
translateProps: {
x: 'left',
y: 'top'
},
undo: function(deep) {
var me = this,
items, len, i;
me.revertProps(me.lastBox);
if (deep && me.wrapsComponent) {
if (me.childItems) {
for (i = 0 , items = me.childItems , len = items.length; i < len; i++) {
items[i].undo(deep);
}
}
for (i = 0 , items = me.children , len = items.length; i < len; i++) {
items[i].undo();
}
}
},
unsetProp: function(propName) {
var dirty = this.dirty;
delete this.props[propName];
if (dirty) {
delete dirty[propName];
}
},
writeProps: function(dirtyProps, flushing) {
if (!(dirtyProps && typeof dirtyProps === 'object')) {
Ext.Logger.warn('writeProps expected dirtyProps to be an object');
return;
}
var me = this,
el = me.el,
styles = {},
styleCount = 0,
styleInfo = me.styleInfo,
info, propName, numericValue,
width = dirtyProps.width,
height = dirtyProps.height,
target = me.target,
hasWidth, hasHeight, isAbsolute, scrollbarSize, style, targetEl;
if ('displayed' in dirtyProps) {
el.setDisplayed(dirtyProps.displayed);
}
for (propName in dirtyProps) {
if (flushing) {
me.fireTriggers('domTriggers', propName);
me.clearBlocks('domBlocks', propName);
me.flushedProps[propName] = 1;
}
info = styleInfo[propName];
if (info && info.dom) {
if (info.suffix && (numericValue = parseInt(dirtyProps[propName], 10))) {
styles[propName] = numericValue + info.suffix;
} else
{
styles[propName] = dirtyProps[propName];
}
++styleCount;
}
}
if ('x' in dirtyProps || 'y' in dirtyProps) {
if (target.isComponent) {
target.setPosition(dirtyProps.x, dirtyProps.y);
} else {
styleCount += me.addPositionStyles(styles, dirtyProps);
}
}
if (me.wrapsComponent && Ext.isIE9) {
if ((hasWidth = width !== undefined && me.hasOverflowY) || (hasHeight = height !== undefined && me.hasOverflowX)) {
isAbsolute = me.isAbsolute;
if (isAbsolute === undefined) {
isAbsolute = false;
targetEl = me.target.getTargetEl();
style = targetEl.getStyle('position');
me.isAbsolute = isAbsolute = (style === 'absolute');
}
if (isAbsolute) {
scrollbarSize = Ext.getScrollbarSize();
if (hasWidth) {
width = parseInt(width, 10) + scrollbarSize.width;
styles.width = width + 'px';
++styleCount;
}
if (hasHeight) {
height = parseInt(height, 10) + scrollbarSize.height;
styles.height = height + 'px';
++styleCount;
}
}
}
}
if (styleCount) {
el.setStyle(styles);
}
},
debugHooks: {
$enabled: false,
addBlock: function(name, layout, propName) {
(layout.blockedBy || (layout.blockedBy = {}))[this.id + '.' + propName + (name.substring(0, 3) === 'dom' ? ':dom' : '')] = 1;
return this.callParent(arguments);
},
addBoxChild: function(boxChildItem) {
var ret = this.callParent(arguments),
boxChildren = this.boxChildren,
boxParents;
if (boxChildren && boxChildren.length === 1) {
boxParents = this.context.boxParents || (this.context.boxParents = new Ext.util.MixedCollection());
boxParents.add(this);
}
return ret;
},
addTrigger: function(propName, inDom) {
var layout = this.context.currentLayout,
triggers;
this.callParent(arguments);
triggers = this.context.triggersByLayoutId;
(triggers[layout.id] || (triggers[layout.id] = {}))[this.id + '.' + propName + (inDom ? ':dom' : '')] = {
item: this,
name: propName
};
},
checkAuthority: function(prop) {
var me = this,
model = me[prop + 'Model'],
layout = me.context.currentLayout,
ok, setBy;
if (layout === me.target.ownerLayout) {
ok = model.calculated;
} else if (layout.isComponentLayout) {
ok = me.isTopLevel || model.auto || model.configured;
}
if (!ok) {
setBy = me.context.getLayoutName(layout);
Ext.log(setBy + ' cannot set ' + prop);
}
},
clearBlocks: function(name, propName) {
var collection = this[name],
blockedLayouts = collection && collection[propName],
key = this.id + '.' + propName + (name.substring(0, 3) === 'dom' ? ':dom' : ''),
layout, layoutId;
if (blockedLayouts) {
for (layoutId in blockedLayouts) {
layout = blockedLayouts[layoutId];
delete layout.blockedBy[key];
}
}
return this.callParent(arguments);
},
getEl: function(el) {
var child = this.callParent(arguments);
if (child && child !== this && child.parent !== this) {
Ext.Error.raise({
msg: 'Got element from wrong component'
});
}
return child;
},
init: function() {
var me = this,
ret;
ret = me.callParent(arguments);
if (me.context.logOn.initItem) {
Ext.log(me.id, ' consumers: content=', me.consumersContentWidth, '/', me.consumersContentHeight, ', container=', me.consumersContainerWidth, '/', me.consumersContainerHeight, ', size=', me.consumersWidth, '/', me.consumersHeight);
}
return ret;
},
invalidate: function() {
if (this.wrapsComponent) {
if (this.context.logOn.invalidate) {
Ext.log('invalidate: ', this.id);
}
} else {
Ext.Error.raise({
msg: 'Cannot invalidate an element contextItem'
});
}
return this.callParent(arguments);
},
setProp: function(propName, value, dirty) {
var me = this,
layout = me.context.currentLayout,
setBy = me.context.getLayoutName(layout),
fullName = me.id + '.' + propName,
setByProps;
if (value !== null) {
setByProps = me.setBy || (me.setBy = {});
if (!setByProps[propName]) {
setByProps[propName] = setBy;
} else if (setByProps[propName] !== setBy) {
Ext.log({
level: 'warn'
}, 'BAD! ', fullName, ' set by ', setByProps[propName], ' and ', setBy);
}
}
if (me.context.logOn.setProp) {
if (typeof value !== 'undefined' && !isNaN(value) && me.props[propName] !== value) {
Ext.log('set ', fullName, ' = ', value, ' (', dirty, ')');
}
}
return this.callParent(arguments);
},
setHeight: function(height, dirty,
force) {
if (!force && this.wrapsComponent) {
this.checkAuthority('height');
}
return this.callParent(arguments);
},
setWidth: function(width, dirty,
force) {
if (!force && this.wrapsComponent) {
this.checkAuthority('width');
}
return this.callParent(arguments);
}
}
},
function() {
var px = {
dom: true,
parseInt: true,
suffix: 'px'
},
isDom = {
dom: true
},
faux = {
dom: false
};
this.prototype.styleInfo = {
containerChildrenSizeDone: faux,
containerLayoutDone: faux,
displayed: faux,
done: faux,
x: faux,
y: faux,
columnsChanged: faux,
rowHeights: faux,
viewOverflowY: faux,
left: px,
top: px,
right: px,
bottom: px,
width: px,
height: px,
'border-top-width': px,
'border-right-width': px,
'border-bottom-width': px,
'border-left-width': px,
'margin-top': px,
'margin-right': px,
'margin-bottom': px,
'margin-left': px,
'padding-top': px,
'padding-right': px,
'padding-bottom': px,
'padding-left': px,
'line-height': isDom,
display: isDom,
clear: isDom
};
});
Ext.define('Ext.layout.Context', {
requires: [
'Ext.perf.Monitor',
'Ext.util.Queue',
'Ext.layout.ContextItem',
'Ext.layout.Layout',
'Ext.fx.Anim',
'Ext.fx.Manager'
],
remainingLayouts: 0,
state: 0,
cycleWatchDog: 200,
constructor: function(config) {
var me = this;
Ext.apply(me, config);
me.items = {};
me.layouts = {};
me.blockCount = 0;
me.cycleCount = 0;
me.flushCount = 0;
me.calcCount = 0;
me.animateQueue = me.newQueue();
me.completionQueue = me.newQueue();
me.finalizeQueue = me.newQueue();
me.finishQueue = me.newQueue();
me.flushQueue = me.newQueue();
me.invalidateData = {};
me.layoutQueue = me.newQueue();
me.invalidQueue = [];
me.triggers = {
data: {},
dom: {}
};
},
callLayout: function(layout, methodName) {
this.currentLayout = layout;
layout[methodName](this.getCmp(layout.owner));
},
cancelComponent: function(comp, isChild, isDestroying) {
var me = this,
components = comp,
isArray = !comp.isComponent,
length = isArray ? components.length : 1,
i, k, klen, items, layout, newQueue, oldQueue, entry, temp, ownerCtContext;
for (i = 0; i < length; ++i) {
if (isArray) {
comp = components[i];
}
if (isDestroying && comp.ownerCt) {
ownerCtContext = this.items[comp.ownerCt.el.id];
if (ownerCtContext) {
Ext.Array.remove(ownerCtContext.childItems, me.getCmp(comp));
}
}
if (!isChild) {
oldQueue = me.invalidQueue;
klen = oldQueue.length;
if (klen) {
me.invalidQueue = newQueue = [];
for (k = 0; k < klen; ++k) {
entry = oldQueue[k];
temp = entry.item.target;
if (temp !== comp && !temp.up(comp)) {
newQueue.push(entry);
}
}
}
}
layout = comp.componentLayout;
me.cancelLayout(layout);
if (layout.getLayoutItems) {
items = layout.getLayoutItems();
if (items.length) {
me.cancelComponent(items, true);
}
}
if (comp.isContainer && !comp.collapsed) {
layout = comp.layout;
me.cancelLayout(layout);
items = layout.getVisibleItems();
if (items.length) {
me.cancelComponent(items, true);
}
}
}
},
cancelLayout: function(layout) {
var me = this;
me.completionQueue.remove(layout);
me.finalizeQueue.remove(layout);
me.finishQueue.remove(layout);
me.layoutQueue.remove(layout);
if (layout.running) {
me.layoutDone(layout);
}
layout.ownerContext = null;
},
clearTriggers: function(layout, inDom) {
var id = layout.id,
collection = this.triggers[inDom ? 'dom' : 'data'],
triggers = collection && collection[id],
length = (triggers && triggers.length) || 0,
i, item, trigger;
for (i = 0; i < length; ++i) {
trigger = triggers[i];
item = trigger.item;
collection = inDom ? item.domTriggers : item.triggers;
delete collection[trigger.prop][id];
}
},
flush: function() {
var me = this,
items = me.flushQueue.clear(),
length = items.length,
i;
if (length) {
++me.flushCount;
for (i = 0; i < length; ++i) {
items[i].flush();
}
}
},
flushAnimations: function() {
var me = this,
items = me.animateQueue.clear(),
len = items.length,
i;
if (len) {
for (i = 0; i < len; i++) {
if (items[i].target.animate !== false) {
items[i].flushAnimations();
}
}
Ext.fx.Manager.runner();
}
},
flushInvalidates: function() {
var me = this,
queue = me.invalidQueue,
length = queue && queue.length,
comp, components, entry, i;
me.invalidQueue = [];
if (length) {
components = [];
for (i = 0; i < length; ++i) {
comp = (entry = queue[i]).item.target;
if (!comp.container.isDetachedBody) {
components.push(comp);
if (entry.options) {
me.invalidateData[comp.id] = entry.options;
}
}
}
me.invalidate(components, null);
}
},
flushLayouts: function(queueName, methodName, dontClear) {
var me = this,
layouts = dontClear ? me[queueName].items : me[queueName].clear(),
length = layouts.length,
i, layout;
if (length) {
for (i = 0; i < length; ++i) {
layout = layouts[i];
if (!layout.running) {
me.callLayout(layout, methodName);
}
}
me.currentLayout = null;
}
},
getCmp: function(cmp) {
return this.getItem(cmp, cmp.el);
},
getEl: function(parent, el) {
var item = this.getItem(el, el);
if (!item.parent) {
item.parent = parent;
if (parent.children.length) {
parent.children.push(item);
} else {
parent.children = [
item
];
}
}
return item;
},
getItem: function(target, el) {
var id = el.id,
items = this.items,
item = items[id] || (items[id] = new Ext.layout.ContextItem({
context: this,
target: target,
el: el
}));
return item;
},
handleFailure: function() {
var layouts = this.layouts,
layout, key;
Ext.failedLayouts = (Ext.failedLayouts || 0) + 1;
for (key in layouts) {
layout = layouts[key];
if (layouts.hasOwnProperty(key)) {
layout.running = false;
layout.ownerContext = null;
}
}
if (Ext.repoDevMode && !this.pageAnalyzerMode) {
Ext.Error.raise('Layout run failed');
} else {
Ext.log.error('Layout run failed');
}
},
invalidate: function(components, full) {
var me = this,
isArray = !components.isComponent,
containerLayoutDone, ownerLayout, firstTime, i, comp, item, items, length, componentLayout, layout, invalidateOptions, token, skipLayout;
for (i = 0 , length = isArray ? components.length : 1; i < length; ++i) {
comp = isArray ? components[i] : components;
if (comp.rendered && !comp.hidden) {
ownerLayout = comp.ownerLayout;
componentLayout = comp.componentLayout;
firstTime = !componentLayout.ownerContext;
skipLayout = false;
if ((!ownerLayout || !ownerLayout.needsItemSize) && comp.liquidLayout) {
skipLayout = true;
}
if (!skipLayout || (ownerLayout && ownerLayout.setsItemSize)) {
item = me.getCmp(comp);
layout = (comp.isContainer && !comp.collapsed) ? comp.layout : null;
invalidateOptions = me.invalidateData[item.id];
delete me.invalidateData[item.id];
token = item.init(full, invalidateOptions);
}
if (skipLayout) {
continue;
}
if (invalidateOptions) {
me.processInvalidate(invalidateOptions, item, 'before');
}
if (componentLayout.beforeLayoutCycle) {
componentLayout.beforeLayoutCycle(item);
}
if (layout && layout.beforeLayoutCycle) {
layout.beforeLayoutCycle(item);
}
token = item.initContinue(token);
containerLayoutDone = true;
if (componentLayout.getLayoutItems) {
componentLayout.renderChildren();
items = componentLayout.getLayoutItems();
if (items.length) {
me.invalidate(items, true);
}
}
if (layout) {
containerLayoutDone = false;
layout.renderChildren();
if (layout.needsItemSize || layout.activeItemCount) {
items = layout.getVisibleItems();
if (items.length) {
me.invalidate(items, true);
}
}
}
item.initDone(containerLayoutDone);
me.resetLayout(componentLayout, item, firstTime);
if (layout) {
me.resetLayout(layout, item, firstTime);
}
item.initAnimation();
if (invalidateOptions) {
me.processInvalidate(invalidateOptions, item, 'after');
}
}
}
me.currentLayout = null;
},
isDescendant: function(ancestor, descendant) {
if (ancestor.isContainer) {
for (var c = descendant.ownerCt; c; c = c.ownerCt) {
if (c === ancestor) {
return true;
}
}
}
return false;
},
layoutDone: function(layout) {
var ownerContext = layout.ownerContext;
layout.running = false;
if (layout.isComponentLayout) {
if (ownerContext.measuresBox) {
ownerContext.onBoxMeasured();
}
ownerContext.setProp('done', true);
} else {
ownerContext.setProp('containerLayoutDone', true);
}
--this.remainingLayouts;
++this.progressCount;
},
newQueue: function() {
return new Ext.util.Queue();
},
processInvalidate: function(options, item, name) {
if (options[name]) {
var me = this,
currentLayout = me.currentLayout;
me.currentLayout = options.layout || null;
options[name](item, options);
me.currentLayout = currentLayout;
}
},
queueAnimation: function(item) {
this.animateQueue.add(item);
},
queueCompletion: function(layout) {
this.completionQueue.add(layout);
},
queueFinalize: function(layout) {
this.finalizeQueue.add(layout);
},
queueFlush: function(item) {
this.flushQueue.add(item);
},
chainFns: function(oldOptions, newOptions, funcName) {
var me = this,
oldLayout = oldOptions.layout,
newLayout = newOptions.layout,
oldFn = oldOptions[funcName],
newFn = newOptions[funcName];
return function(contextItem) {
var prev = me.currentLayout;
if (oldFn) {
me.currentLayout = oldLayout;
oldFn.call(oldOptions.scope || oldOptions, contextItem, oldOptions);
}
me.currentLayout = newLayout;
newFn.call(newOptions.scope || newOptions, contextItem, newOptions);
me.currentLayout = prev;
};
},
purgeInvalidates: function() {
var me = this,
newQueue = [],
oldQueue = me.invalidQueue,
oldLength = oldQueue.length,
oldIndex, newIndex, newEntry, newComp, oldEntry, oldComp, keep;
for (oldIndex = 0; oldIndex < oldLength; ++oldIndex) {
oldEntry = oldQueue[oldIndex];
oldComp = oldEntry.item.target;
keep = true;
for (newIndex = newQueue.length; newIndex--; ) {
newEntry = newQueue[newIndex];
newComp = newEntry.item.target;
if (oldComp.isLayoutChild(newComp)) {
keep = false;
break;
}
if (newComp.isLayoutChild(oldComp)) {
Ext.Array.erase(newQueue, newIndex, 1);
}
}
if (keep) {
newQueue.push(oldEntry);
}
}
me.invalidQueue = newQueue;
},
queueInvalidate: function(item, options) {
var me = this,
newQueue = [],
oldQueue = me.invalidQueue,
index = oldQueue.length,
comp, old, oldComp, oldOptions, oldState;
if (item.isComponent) {
item = me.getCmp(comp = item);
} else {
comp = item.target;
}
item.invalid = true;
while (index--) {
old = oldQueue[index];
oldComp = old.item.target;
if (!comp.isFloating && comp.up(oldComp)) {
return;
}
if (oldComp === comp) {
if (!(oldOptions = old.options)) {
old.options = options;
} else if (options) {
if (options.widthModel) {
oldOptions.widthModel = options.widthModel;
}
if (options.heightModel) {
oldOptions.heightModel = options.heightModel;
}
if (!(oldState = oldOptions.state)) {
oldOptions.state = options.state;
} else if (options.state) {
Ext.apply(oldState, options.state);
}
if (options.before) {
oldOptions.before = me.chainFns(oldOptions, options, 'before');
}
if (options.after) {
oldOptions.after = me.chainFns(oldOptions, options, 'after');
}
}
return;
}
if (!oldComp.isLayoutChild(comp)) {
newQueue.push(old);
}
}
newQueue.push({
item: item,
options: options
});
me.invalidQueue = newQueue;
},
queueItemLayouts: function(item) {
var comp = item.isComponent ? item : item.target,
layout = comp.componentLayout;
if (!layout.pending && !layout.invalid && !layout.done) {
this.queueLayout(layout);
}
layout = comp.layout;
if (layout && !layout.pending && !layout.invalid && !layout.done && !comp.collapsed) {
this.queueLayout(layout);
}
},
queueLayout: function(layout) {
this.layoutQueue.add(layout);
layout.pending = true;
},
removeEl: function(parent, el) {
var id = el.id,
children = parent.children,
items = this.items;
if (children) {
Ext.Array.remove(children, items[id]);
}
delete items[id];
},
resetLayout: function(layout, ownerContext, firstTime) {
var me = this;
me.currentLayout = layout;
layout.done = false;
layout.pending = true;
layout.firedTriggers = 0;
me.layoutQueue.add(layout);
if (firstTime) {
me.layouts[layout.id] = layout;
layout.running = true;
if (layout.finishedLayout) {
me.finishQueue.add(layout);
}
++me.remainingLayouts;
++layout.layoutCount;
layout.ownerContext = ownerContext;
layout.beginCount = 0;
layout.blockCount = 0;
layout.calcCount = 0;
layout.triggerCount = 0;
if (!layout.initialized) {
layout.initLayout();
}
layout.beginLayout(ownerContext);
} else {
++layout.beginCount;
if (!layout.running) {
++me.remainingLayouts;
layout.running = true;
if (layout.isComponentLayout) {
ownerContext.unsetProp('done');
}
me.completionQueue.remove(layout);
me.finalizeQueue.remove(layout);
}
}
layout.beginLayoutCycle(ownerContext, firstTime);
},
run: function() {
var me = this,
flushed = false,
watchDog = me.cycleWatchDog;
me.purgeInvalidates();
me.flushInvalidates();
me.state = 1;
me.totalCount = me.layoutQueue.getCount();
me.flush();
while ((me.remainingLayouts || me.invalidQueue.length) && watchDog--) {
if (me.invalidQueue.length) {
me.flushInvalidates();
}
if (me.runCycle()) {
flushed = false;
}
else if (!flushed) {
me.flush();
flushed = true;
me.flushLayouts('completionQueue', 'completeLayout');
} else if (!me.invalidQueue.length) {
me.state = 2;
break;
}
if (!(me.remainingLayouts || me.invalidQueue.length)) {
me.flush();
me.flushLayouts('completionQueue', 'completeLayout');
me.flushLayouts('finalizeQueue', 'finalizeLayout');
}
}
return me.runComplete();
},
runComplete: function() {
var me = this;
me.state = 2;
if (me.remainingLayouts) {
me.handleFailure();
return false;
}
me.flush();
me.flushLayouts('finishQueue', 'finishedLayout', true);
me.flushLayouts('finishQueue', 'notifyOwner');
me.flush();
me.flushAnimations();
return true;
},
runCycle: function() {
var me = this,
layouts = me.layoutQueue.clear(),
length = layouts.length,
i;
++me.cycleCount;
me.progressCount = 0;
for (i = 0; i < length; ++i) {
me.runLayout(me.currentLayout = layouts[i]);
}
me.currentLayout = null;
return me.progressCount > 0;
},
runLayout: function(layout) {
var me = this,
ownerContext = me.getCmp(layout.owner);
layout.pending = false;
if (ownerContext.state.blocks) {
return;
}
layout.done = true;
++layout.calcCount;
++me.calcCount;
layout.calculate(ownerContext);
if (layout.done) {
me.layoutDone(layout);
if (layout.completeLayout) {
me.queueCompletion(layout);
}
if (layout.finalizeLayout) {
me.queueFinalize(layout);
}
} else if (!layout.pending && !layout.invalid && !(layout.blockCount + layout.triggerCount - layout.firedTriggers)) {
me.queueLayout(layout);
}
},
setItemSize: function(item, width, height) {
var items = item,
len = 1,
contextItem, i;
if (item.isComposite) {
items = item.elements;
len = items.length;
item = items[0];
} else if (!item.dom && !item.el) {
len = items.length;
item = items[0];
}
for (i = 0; i < len; ) {
contextItem = this.get(item);
contextItem.setSize(width, height);
item = items[++i];
}
},
debugHooks: {
$enabled: false,
pageAnalyzerMode: true,
logOn: {
0: 0
},
cancelComponent: function(comp) {
if (this.logOn.cancelComponent) {
Ext.log('cancelCmp: ', comp.id);
}
this.callParent(arguments);
},
cancelLayout: function(layout) {
if (this.logOn.cancelLayout) {
Ext.log('cancelLayout: ', this.getLayoutName(layout));
}
this.callParent(arguments);
},
callLayout: function(layout, methodName) {
var accum = this.accumByType[layout.type],
frame = accum && accum.enter();
this.callParent(arguments);
if (accum) {
frame.leave();
}
},
checkRemainingLayouts: function() {
var me = this,
expected = 0,
key, layout;
for (key in me.layouts) {
layout = me.layouts[key];
if (me.layouts.hasOwnProperty(key) && layout.running) {
++expected;
}
}
if (me.remainingLayouts !== expected) {
Ext.Error.raise({
msg: 'Bookkeeping error me.remainingLayouts'
});
}
},
flush: function() {
if (this.logOn.flush) {
var items = this.flushQueue;
Ext.log('--- Flush ', items && items.getCount());
}
return this.callParent(arguments);
},
flushInvalidates: function() {
if (this.logOn.flushInvalidate) {
Ext.log('>> flushInvalidates');
}
var ret = this.callParent(arguments);
if (this.logOn.flushInvalidate) {
Ext.log('<< flushInvalidates');
}
return ret;
},
getCmp: function(target) {
var ret = this.callParent(arguments);
if (!ret.wrapsComponent) {
Ext.Error.raise({
msg: target.id + ' is not a component'
});
}
return ret;
},
getEl: function(parent, target) {
var ret = this.callParent(arguments);
if (ret && ret.wrapsComponent) {
Ext.Error.raise({
msg: parent.id + '/' + target.id + ' is a component (expected element)'
});
}
return ret;
},
getLayoutName: function(layout) {
return layout.owner.id + '<' + layout.type + '>';
},
layoutDone: function(layout) {
var me = this,
name = me.getLayoutName(layout);
if (me.logOn.layoutDone) {
Ext.log('layoutDone: ', name, ' ( ', me.remainingLayouts, ' running)');
}
if (!layout.running) {
Ext.Error.raise({
msg: name + ' is already done'
});
}
if (!me.remainingLayouts) {
Ext.Error.raise({
msg: name + ' finished but no layouts are running'
});
}
me.callParent(arguments);
},
layoutTreeHasFailures: function(layout, reported) {
var me = this;
function hasFailure(lo) {
var failure = !lo.done,
key, childLayout;
if (lo.done) {
for (key in me.layouts) {
if (me.layouts.hasOwnProperty(key)) {
childLayout = me.layouts[key];
if (childLayout.owner.ownerLayout === lo) {
if (hasFailure(childLayout)) {
failure = true;
}
}
}
}
}
return failure;
}
if (hasFailure(layout)) {
return true;
}
function markReported(lo) {
var key, childLayout;
reported[lo.id] = 1;
for (key in me.layouts) {
if (me.layouts.hasOwnProperty(key)) {
childLayout = me.layouts[key];
if (childLayout.owner.ownerLayout === lo) {
markReported(childLayout);
}
}
}
}
markReported(layout);
return false;
},
queueLayout: function(layout) {
if (layout.done || layout.blockCount || layout.pending) {
Ext.Error.raise({
msg: this.getLayoutName(layout) + ' should not be queued for layout'
});
}
if (this.logOn.queueLayout) {
Ext.log('Queue ', this.getLayoutName(layout));
}
return this.callParent(arguments);
},
reportLayoutResult: function(layout, reported) {
var me = this,
owner = layout.owner,
ownerContext = me.getCmp(owner),
blockedBy = [],
triggeredBy = [],
key, value, i, length, childLayout, item, setBy, info;
reported[layout.id] = 1;
for (key in layout.blockedBy) {
if (layout.blockedBy.hasOwnProperty(key)) {
blockedBy.push(layout.blockedBy[key]);
}
}
blockedBy.sort();
for (key in me.triggersByLayoutId[layout.id]) {
if (me.triggersByLayoutId[layout.id].hasOwnProperty(key)) {
value = me.triggersByLayoutId[layout.id][key];
triggeredBy.push({
name: key,
info: value
});
}
}
triggeredBy.sort(function(a, b) {
return a.name < b.name ? -1 : (b.name < a.name ? 1 : 0);
});
Ext.log({
indent: 1
}, (layout.done ? '++' : '--'), me.getLayoutName(layout), (ownerContext.isBoxParent ? ' [isBoxParent]' : ''), (ownerContext.boxChildren ? ' - boxChildren: ' + ownerContext.state.boxesMeasured + '/' + ownerContext.boxChildren.length : ''), ownerContext.boxParent ? (' - boxParent: ' + ownerContext.boxParent.id) : '', ' - size: ', ownerContext.widthModel.name, '/', ownerContext.heightModel.name);
if (!layout.done || me.reportOnSuccess) {
if (blockedBy.length) {
++Ext.log.indent;
Ext.log({
indent: 1
}, 'blockedBy: count=', layout.blockCount);
length = blockedBy.length;
for (i = 0; i < length; i++) {
Ext.log(blockedBy[i]);
}
Ext.log.indent -= 2;
}
if (triggeredBy.length) {
++Ext.log.indent;
Ext.log({
indent: 1
}, 'triggeredBy: count=' + layout.triggerCount);
length = triggeredBy.length;
for (i = 0; i < length; i++) {
info = value.info || value;
item = info.item;
setBy = (item.setBy && item.setBy[info.name]) || '?';
value = triggeredBy[i];
Ext.log(value.name, ' (', item.props[info.name], ') dirty: ', (item.dirty ? !!item.dirty[info.name] : false), ', setBy: ', setBy);
}
Ext.log.indent -= 2;
}
}
for (key in me.layouts) {
if (me.layouts.hasOwnProperty(key)) {
childLayout = me.layouts[key];
if (!childLayout.done && childLayout.owner.ownerLayout === layout) {
me.reportLayoutResult(childLayout, reported);
}
}
}
for (key in me.layouts) {
if (me.layouts.hasOwnProperty(key)) {
childLayout = me.layouts[key];
if (childLayout.done && childLayout.owner.ownerLayout === layout) {
me.reportLayoutResult(childLayout, reported);
}
}
}
--Ext.log.indent;
},
resetLayout: function(layout) {
var me = this,
type = layout.type,
name = me.getLayoutName(layout),
accum = me.accumByType[type],
frame;
if (me.logOn.resetLayout) {
Ext.log('resetLayout: ', name, ' ( ', me.remainingLayouts, ' running)');
}
if (!me.state) {
if (!accum && me.profileLayoutsByType) {
me.accumByType[type] = accum = Ext.Perf.get('layout_' + layout.type);
}
me.numByType[type] = (me.numByType[type] || 0) + 1;
}
frame = accum && accum.enter();
me.callParent(arguments);
if (accum) {
frame.leave();
}
me.checkRemainingLayouts();
},
round: function(t) {
return Math.round(t * 1000) / 1000;
},
run: function() {
var me = this,
ret, time, key, i, layout, boxParent, children, n, reported, unreported, calcs, total, calcsLength, calc;
me.accumByType = {};
me.calcsByType = {};
me.numByType = {};
me.timesByType = {};
me.triggersByLayoutId = {};
Ext.log.indentSize = 3;
Ext.log('==================== LAYOUT ====================');
time = Ext.perf.getTimestamp();
ret = me.callParent(arguments);
time = Ext.perf.getTimestamp() - time;
if (me.logOn.boxParent && me.boxParents) {
for (key in me.boxParents) {
if (me.boxParents.hasOwnProperty(key)) {
boxParent = me.boxParents[key];
children = boxParent.boxChildren;
n = children.length;
Ext.log('boxParent: ', boxParent.id);
for (i = 0; i < n; ++i) {
Ext.log(' --> ', children[i].id);
}
}
}
}
if (ret) {
Ext.log('----------------- SUCCESS -----------------');
} else {
Ext.log({
level: 'error'
}, '----------------- FAILURE -----------------');
}
for (key in me.layouts) {
if (me.layouts.hasOwnProperty(key)) {
layout = me.layouts[key];
if (layout.running) {
Ext.log.error('Layout left running: ', me.getLayoutName(layout));
}
if (layout.ownerContext) {
Ext.log.error('Layout left connected: ', me.getLayoutName(layout));
}
}
}
if (!ret || me.reportOnSuccess) {
reported = {};
unreported = 0;
for (key in me.layouts) {
if (me.layouts.hasOwnProperty(key)) {
layout = me.layouts[key];
if (me.items[layout.owner.el.id].isTopLevel) {
if (me.reportOnSuccess || me.layoutTreeHasFailures(layout, reported)) {
me.reportLayoutResult(layout, reported);
}
}
}
}
for (key in me.layouts) {
if (me.layouts.hasOwnProperty(key)) {
layout = me.layouts[key];
if (!reported[layout.id]) {
if (!unreported) {
Ext.log('----- Unreported!! -----');
}
++unreported;
me.reportLayoutResult(layout, reported);
}
}
}
}
Ext.log('Cycles: ', me.cycleCount, ', Flushes: ', me.flushCount, ', Calculates: ', me.calcCount, ' in ', me.round(time), ' msec');
Ext.log('Calculates by type:');
calcs = [];
for (key in me.numByType) {
if (me.numByType.hasOwnProperty(key)) {
total = me.numByType[key];
calcs.push({
type: key,
total: total,
calcs: me.calcsByType[key],
multiple: Math.round(me.calcsByType[key] / total * 10) / 10,
calcTime: me.round(me.timesByType[key]),
avgCalcTime: me.round(me.timesByType[key] / me.calcsByType[key])
});
}
}
calcs.sort(function(a, b) {
return b.calcTime - a.calcTime;
});
calcsLength = calcs.length;
for (i = 0; i < calcsLength; i++) {
calc = calcs[i];
Ext.log(calc.type, ': ', calc.total, ' in ', calc.calcs, ' tries (', calc.multiple, 'x) at ', calc.calcTime, ' msec (avg ', calc.avgCalcTime, ' msec)');
}
return ret;
},
runCycle: function() {
if (this.logOn.runCycle) {
Ext.log('>>> Cycle ', this.cycleCount, ' (queue length: ', this.layoutQueue.length, ')');
}
return this.callParent(arguments);
},
runLayout: function(layout) {
var me = this,
type = layout.type,
accum = me.accumByType[type],
frame, ret, time;
if (me.logOn.calculate) {
Ext.log('-- calculate ', this.getLayoutName(layout));
}
frame = accum && accum.enter();
time = Ext.perf.getTimestamp();
ret = me.callParent(arguments);
time = Ext.perf.getTimestamp() - time;
if (accum) {
frame.leave();
}
me.calcsByType[type] = (me.calcsByType[type] || 0) + 1;
me.timesByType[type] = (me.timesByType[type] || 0) + time;
return ret;
}
}
});
Ext.define('Ext.layout.component.FieldSet', {
extend: 'Ext.layout.component.Body',
alias: [
'layout.fieldset'
],
type: 'fieldset',
defaultCollapsedWidth: 100,
beforeLayoutCycle: function(ownerContext) {
if (ownerContext.target.collapsed) {
ownerContext.heightModel = this.sizeModels.shrinkWrap;
}
},
beginLayout: function(ownerContext) {
var legend = this.owner.legend;
this.callParent([
ownerContext
]);
if (legend) {
ownerContext.legendContext = ownerContext.context.getCmp(legend);
}
},
beginLayoutCycle: function(ownerContext) {
var target = ownerContext.target,
lastSize;
this.callParent(arguments);
if (target.collapsed) {
ownerContext.setContentHeight(0);
ownerContext.restoreMinHeight = target.minHeight;
delete target.minHeight;
if (ownerContext.widthModel.shrinkWrap) {
lastSize = this.lastComponentSize;
ownerContext.setContentWidth((lastSize && lastSize.contentWidth) || this.defaultCollapsedWidth);
}
}
},
finishedLayout: function(ownerContext) {
var owner = this.owner,
restore = ownerContext.restoreMinHeight;
this.callParent(arguments);
if (restore) {
owner.minHeight = restore;
}
},
calculateOwnerWidthFromContentWidth: function(ownerContext, contentWidth) {
var legendContext = ownerContext.legendContext;
if (legendContext) {
contentWidth = Math.max(contentWidth, legendContext.getProp('width'));
}
return this.callParent([
ownerContext,
contentWidth
]);
},
calculateOwnerHeightFromContentHeight: function(ownerContext, contentHeight) {
var border = ownerContext.getBorderInfo(),
legendContext = ownerContext.legendContext;
return ownerContext.getProp('contentHeight') + ownerContext.getPaddingInfo().height +
(Ext.isIE8 ? ownerContext.bodyContext.getPaddingInfo().top : 0) + (legendContext ? legendContext.getProp('height') : border.top) + border.bottom;
},
publishInnerHeight: function(ownerContext, height) {
var legendContext = ownerContext.legendContext,
legendHeight = 0;
if (legendContext) {
legendHeight = legendContext.getProp('height');
}
if (legendHeight === undefined) {
this.done = false;
} else {
this.callParent([
ownerContext,
height - legendHeight
]);
}
},
getLayoutItems: function() {
var legend = this.owner.legend;
return legend ? [
legend
] : [];
}
});
Ext.define('Ext.layout.container.Absolute', {
alias: 'layout.absolute',
extend: 'Ext.layout.container.Anchor',
alternateClassName: 'Ext.layout.AbsoluteLayout',
targetCls: Ext.baseCSSPrefix + 'abs-layout-ct',
itemCls: Ext.baseCSSPrefix + 'abs-layout-item',
ignoreOnContentChange: true,
type: 'absolute',
adjustWidthAnchor: function(value, childContext) {
var padding = this.targetPadding,
x = childContext.getStyle('left');
return value - x + padding.left;
},
adjustHeightAnchor: function(value, childContext) {
var padding = this.targetPadding,
y = childContext.getStyle('top');
return value - y + padding.top;
},
isItemLayoutRoot: function(item) {
return this.ignoreOnContentChange || this.callParent(arguments);
},
isItemShrinkWrap: function(item) {
return true;
},
beginLayout: function(ownerContext) {
var me = this,
target = me.getTarget();
me.callParent(arguments);
if (target.dom !== document.body) {
target.position();
}
me.targetPadding = ownerContext.targetContext.getPaddingInfo();
},
isItemBoxParent: function(itemContext) {
return true;
},
onContentChange: function() {
if (this.ignoreOnContentChange) {
return false;
}
return this.callParent(arguments);
},
calculateContentSize: function(ownerContext, dimensions) {
var me = this,
containerDimensions = (dimensions || 0) |
((ownerContext.widthModel.shrinkWrap ? 1 : 0) |
(ownerContext.heightModel.shrinkWrap ? 2 : 0)),
calcWidth = (containerDimensions & 1) || undefined,
calcHeight = (containerDimensions & 2) || undefined,
childItems = ownerContext.childItems,
length = childItems.length,
contentHeight = 0,
contentWidth = 0,
needed = 0,
props = ownerContext.props,
targetPadding, child, childContext, height, i, margins, width;
if (calcWidth) {
if (isNaN(props.contentWidth)) {
++needed;
} else {
calcWidth = undefined;
}
}
if (calcHeight) {
if (isNaN(props.contentHeight)) {
++needed;
} else {
calcHeight = undefined;
}
}
if (needed) {
for (i = 0; i < length; ++i) {
childContext = childItems[i];
child = childContext.target;
height = calcHeight && childContext.getProp('height');
width = calcWidth && childContext.getProp('width');
margins = childContext.getMarginInfo();
height += margins.bottom;
width += margins.right;
contentHeight = Math.max(contentHeight, (child.y || 0) + height);
contentWidth = Math.max(contentWidth, (child.x || 0) + width);
if (isNaN(contentHeight) && isNaN(contentWidth)) {
me.done = false;
return;
}
}
if (calcWidth || calcHeight) {
targetPadding = ownerContext.targetContext.getPaddingInfo();
}
if (calcWidth && !ownerContext.setContentWidth(contentWidth + targetPadding.width)) {
me.done = false;
}
if (calcHeight && !ownerContext.setContentHeight(contentHeight + targetPadding.height)) {
me.done = false;
}
}
}
});
Ext.define('Ext.layout.container.Accordion', {
extend: 'Ext.layout.container.VBox',
alias: 'layout.accordion',
type: 'accordion',
alternateClassName: 'Ext.layout.AccordionLayout',
targetCls: Ext.baseCSSPrefix + 'accordion-layout-ct',
itemCls: [
Ext.baseCSSPrefix + 'box-item',
Ext.baseCSSPrefix + 'accordion-item'
],
align: 'stretch',
enableSplitters: false,
fill: true,
titleCollapse: true,
hideCollapseTool: false,
collapseFirst: undefined,
animate: true,
activeOnTop: false,
multi: false,
panelCollapseMode: 'header',
defaultAnimatePolicy: {
y: true,
height: true
},
constructor: function() {
var me = this;
me.callParent(arguments);
if (me.animate) {
me.animatePolicy = {};
me.animatePolicy[me.names.x] = true;
me.animatePolicy[me.names.width] = true;
} else {
me.animatePolicy = null;
}
},
beforeRenderItems: function(items) {
var me = this,
ln = items.length,
owner = me.owner,
collapseFirst = me.collapseFirst,
hasCollapseFirst = Ext.isDefined(collapseFirst),
expandedItem = me.getExpanded(true)[0],
multi = me.multi,
comp, i;
for (i = 0; i < ln; i++) {
comp = items[i];
if (!comp.rendered) {
if (!multi || comp.collapsible !== false) {
comp.collapsible = true;
}
if (comp.collapsible) {
if (hasCollapseFirst) {
comp.collapseFirst = collapseFirst;
}
if (me.hideCollapseTool) {
comp.hideCollapseTool = me.hideCollapseTool;
comp.titleCollapse = true;
} else if (me.titleCollapse && comp.titleCollapse === undefined) {
comp.titleCollapse = me.titleCollapse;
}
}
comp.hideHeader = comp.width = null;
comp.title = comp.title || '&#160;';
comp.addBodyCls(Ext.baseCSSPrefix + 'accordion-body');
if (!multi) {
if (expandedItem) {
comp.collapsed = expandedItem !== comp;
} else if (comp.hasOwnProperty('collapsed') && comp.collapsed === false) {
expandedItem = comp;
} else {
comp.collapsed = true;
}
owner.mon(comp, 'show', me.onComponentShow, me);
}
comp.headerOverCls = Ext.baseCSSPrefix + 'accordion-hd-over';
}
}
if (!me.processing && !multi) {
if (!expandedItem) {
if (ln) {
items[0].collapsed = false;
}
} else if (me.activeOnTop) {
expandedItem.collapsed = false;
me.configureItem(expandedItem);
if (owner.items.indexOf(expandedItem) > 0) {
owner.insert(0, expandedItem);
}
}
}
},
getItemsRenderTree: function(items) {
this.beforeRenderItems(items);
return this.callParent(arguments);
},
renderItems: function(items, target) {
this.beforeRenderItems(items);
this.callParent(arguments);
},
configureItem: function(item) {
this.callParent(arguments);
item.ignoreHeaderBorderManagement = true;
item.animCollapse = false;
if (this.fill) {
item.flex = 1;
}
},
beginLayout: function(ownerContext) {
this.callParent(arguments);
this.updatePanelClasses(ownerContext);
},
updatePanelClasses: function(ownerContext) {
var children = ownerContext.visibleItems,
ln = children.length,
siblingCollapsed = true,
i, child, header;
for (i = 0; i < ln; i++) {
child = children[i];
header = child.header;
header.addCls(Ext.baseCSSPrefix + 'accordion-hd');
if (siblingCollapsed) {
header.removeCls(Ext.baseCSSPrefix + 'accordion-hd-sibling-expanded');
} else {
header.addCls(Ext.baseCSSPrefix + 'accordion-hd-sibling-expanded');
}
if (i + 1 === ln && child.collapsed) {
header.addCls(Ext.baseCSSPrefix + 'accordion-hd-last-collapsed');
} else {
header.removeCls(Ext.baseCSSPrefix + 'accordion-hd-last-collapsed');
}
siblingCollapsed = child.collapsed;
}
},
onBeforeComponentExpand: function(toExpand) {
var me = this,
owner = me.owner,
multi = me.multi,
moveToTop = !multi && !me.animate && me.activeOnTop,
expanded, previousValue, anim;
if (!me.processing) {
me.processing = true;
previousValue = owner.deferLayouts;
owner.deferLayouts = true;
if (!multi) {
expanded = me.getExpanded()[0];
if (expanded && expanded !== toExpand) {
anim = expanded.$layoutAnim;
if (anim) {
anim.jumpToEnd();
}
expanded.collapse();
}
}
if (moveToTop) {
Ext.suspendLayouts();
owner.insert(0, toExpand);
Ext.resumeLayouts();
}
owner.deferLayouts = previousValue;
me.processing = false;
}
},
onBeforeComponentCollapse: function(comp) {
var me = this,
owner = me.owner,
toExpand, expanded, previousValue;
if (me.owner.items.getCount() === 1) {
return false;
}
if (!me.processing) {
me.processing = true;
previousValue = owner.deferLayouts;
owner.deferLayouts = true;
toExpand = comp.next() || comp.prev();
if (me.multi) {
expanded = me.getExpanded();
if (expanded.length === 1) {
toExpand.expand();
}
} else if (toExpand) {
toExpand.expand();
}
owner.deferLayouts = previousValue;
me.processing = false;
}
},
onComponentShow: function(comp) {
this.onBeforeComponentExpand(comp);
},
onAdd: function(item) {
var me = this;
me.callParent(arguments);
if (item.collapseMode === 'placeholder') {
item.collapseMode = me.panelCollapseMode;
}
item.collapseDirection = item.headerPosition;
if (me.layoutCount && !me.multi && me.owner.items.getCount() > 1) {
me.processing = true;
item.collapse();
me.processing = false;
}
},
onRemove: function(panel, destroying) {
var me = this,
item;
me.callParent(arguments);
if (!me.owner.destroying && !me.multi && !panel.collapsed) {
item = me.owner.items.first();
if (item) {
item.expand();
}
}
},
getExpanded: function(explicitCheck) {
var items = this.owner.items.items,
len = items.length,
i = 0,
out = [],
add, item;
for (; i < len; ++i) {
item = items[i];
if (!item.hidden) {
if (explicitCheck) {
add = item.hasOwnProperty('collapsed') && item.collapsed === false;
} else {
add = !item.collapsed;
}
if (add) {
out.push(item);
}
}
}
return out;
},
afterCollapse: Ext.emptyFn,
afterExpand: Ext.emptyFn
});
Ext.define('Ext.layout.container.Center', {
extend: 'Ext.layout.container.Fit',
alias: [
'layout.center',
'layout.ux.center'
],
alternateClassName: 'Ext.ux.layout.Center',
type: 'center',
percentRe: /^\d+(?:\.\d+)?\%$/,
itemCls: Ext.baseCSSPrefix + 'center-layout-item',
childEls: [
'targetEl'
],
renderTpl: [
'<div id="{ownerId}-targetEl" data-ref="targetEl" class="{targetElCls}" role="presentation">' + '{%this.renderBody(out, values)%}' + '</div>'
],
targetElCls: Ext.baseCSSPrefix + 'center-target',
beginLayout: function(ownerContext) {
var me = this,
percentRe = me.percentRe,
childItems, len, i, itemContext, item, widthModel, heightModel;
me.callParent([
ownerContext
]);
childItems = ownerContext.childItems;
for (i = 0 , len = childItems.length; i < len; ++i) {
itemContext = childItems[i];
item = itemContext.target;
widthModel = itemContext.widthModel;
heightModel = itemContext.heightModel;
if (percentRe.test(item.width)) {
item.getEl().setStyle('width', '');
}
if (percentRe.test(item.height)) {
item.getEl().setStyle('height', '');
}
}
ownerContext.targetElContext = ownerContext.getEl('targetEl', me);
},
beginLayoutCycle: function(ownerContext, firstCycle) {
var targetEl = this.targetEl;
this.callParent([
ownerContext,
firstCycle
]);
targetEl.setStyle('width', '');
targetEl.setStyle('height', '');
},
getRenderData: function() {
var data = this.callParent();
data.targetElCls = this.targetElCls;
return data;
},
getRenderTarget: function() {
return this.targetEl;
},
getItemSizePolicy: function(item, ownerSizeModel) {
var me = this,
sizeModel = ownerSizeModel || me.owner.getSizeModel(),
percentRe = me.percentRe,
mode = ((sizeModel.width.shrinkWrap || !percentRe.test(item.width)) ? 0 : 1) |
((sizeModel.height.shrinkWrap || !percentRe.test(item.height)) ? 0 : 2);
return me.sizePolicies[mode];
},
isItemBoxParent: function(itemContext) {
return true;
},
isItemShrinkWrap: function(item) {
return true;
},
calculate: function(ownerContext) {
var targetElContext = ownerContext.targetElContext,
info;
this.callParent([
ownerContext
]);
info = ownerContext.state.info;
if (ownerContext.widthModel.shrinkWrap) {
targetElContext.setWidth(info.contentWidth);
}
if (ownerContext.heightModel.shrinkWrap) {
targetElContext.setHeight(info.contentHeight);
}
},
getPos: function(itemContext, info, dimension) {
var modelName = dimension + 'Model',
size = itemContext.props[dimension],
pos = 0;
if (!itemContext[modelName].calculated) {
size += info.margins[dimension];
}
if (!info.ownerContext[modelName].shrinkWrap) {
pos = Math.round((info.targetSize[dimension] - size) / 2);
if (isNaN(pos)) {
this.done = false;
}
}
return Math.max(pos, 0);
},
positionItemX: function(itemContext, info) {
var left = this.getPos(itemContext, info, 'width');
itemContext.setProp('x', left);
},
positionItemY: function(itemContext, info) {
var top = this.getPos(itemContext, info, 'height');
itemContext.setProp('y', top);
},
setItemHeight: function(itemContext, info) {
var ratio = parseFloat(itemContext.target.height) / 100;
itemContext.setHeight(Math.round((info.targetSize.height - info.margins.height) * ratio));
},
setItemWidth: function(itemContext, info) {
var ratio = parseFloat(itemContext.target.width) / 100;
itemContext.setWidth(Math.round((info.targetSize.width - info.margins.width) * ratio));
}
});
Ext.define('Ext.layout.container.Form', {
extend: 'Ext.layout.container.Auto',
alternateClassName: 'Ext.layout.FormLayout',
alias: 'layout.form',
type: 'form',
formWrapCls: Ext.baseCSSPrefix + 'form-layout-wrap',
formWrapAutoLabelCls: Ext.baseCSSPrefix + 'form-layout-auto-label',
formWrapSizedLabelCls: Ext.baseCSSPrefix + 'form-layout-sized-label',
formColGroupCls: Ext.baseCSSPrefix + 'form-layout-colgroup',
formColumnCls: Ext.baseCSSPrefix + 'form-layout-column',
formLabelColumnCls: Ext.baseCSSPrefix + 'form-layout-label-column',
childEls: [
'formWrap',
'labelColumn'
],
beforeBodyTpl: '<div id="{ownerId}-formWrap" data-ref="formWrap" class="{formWrapCls}"' + '<tpl if="itemSpacing"> style="border-spacing:{itemSpacing}px"</tpl>>' + '<div class="{formColGroupCls}">' + '<div id="{ownerId}-labelColumn" data-ref="labelColumn" class="{formColumnCls} {formLabelColumnCls}"' + '<tpl if="labelWidth"> style="width:{labelWidth}"</tpl>>' + '</div>' + '<div class="{formColumnCls}"></div>' + '</div>',
afterBodyTpl: '</div>',
getRenderData: function() {
var me = this,
labelWidth = me.labelWidth,
formWrapCls = me.formWrapCls,
data = me.callParent();
if (labelWidth) {
if (typeof labelWidth === 'number') {
labelWidth += 'px';
}
data.labelWidth = labelWidth;
formWrapCls += ' ' + me.formWrapSizedLabelCls;
} else {
formWrapCls += ' ' + me.formWrapAutoLabelCls;
}
data.formWrapCls = formWrapCls;
data.formColGroupCls = me.formColGroupCls;
data.formColumnCls = me.formColumnCls;
data.formLabelColumnCls = me.formLabelColumnCls;
return data;
},
getRenderTarget: function() {
return this.formWrap;
}
});
Ext.define('Ext.layout.container.SegmentedButton', {
extend: 'Ext.layout.container.Container',
alias: 'layout.segmentedbutton',
needsItemSize: false,
setsItemSize: false,
_btnRowCls: Ext.baseCSSPrefix + 'segmented-button-row',
getRenderTree: function() {
var me = this,
result = me.callParent(),
i, ln;
if (me.owner.getVertical()) {
for (i = 0 , ln = result.length; i < ln; i++) {
result[i] = {
cls: me._btnRowCls,
cn: result[i]
};
}
}
return result;
},
getItemLayoutEl: function(item) {
var dom = item.el.dom;
return this.owner.getVertical() ? dom.parentNode : dom;
},
onDestroy: function() {
if (this.rendered) {
var targetEl = this.getRenderTarget(),
row;
while ((row = targetEl.last())) {
row.destroy();
}
}
}
});
Ext.define('Ext.menu.ColorPicker', {
extend: 'Ext.menu.Menu',
alias: 'widget.colormenu',
requires: [
'Ext.picker.Color'
],
hideOnClick: true,
pickerId: null,
initComponent: function() {
var me = this,
cfg = Ext.apply({}, me.initialConfig);
delete cfg.listeners;
Ext.apply(me, {
plain: true,
showSeparator: false,
bodyPadding: 0,
items: Ext.applyIf({
cls: Ext.baseCSSPrefix + 'menu-color-item',
margin: 0,
id: me.pickerId,
xtype: 'colorpicker'
}, cfg)
});
me.callParent(arguments);
me.picker = me.down('colorpicker');
me.relayEvents(me.picker, [
'select'
]);
if (me.hideOnClick) {
me.on('select', me.hidePickerOnSelect, me);
}
},
hidePickerOnSelect: function() {
Ext.menu.Manager.hideAll();
}
});
Ext.define('Ext.menu.DatePicker', {
extend: 'Ext.menu.Menu',
alias: 'widget.datemenu',
requires: [
'Ext.picker.Date'
],
ariaRole: 'dialog',
ariaLabel: 'Date picker',
hideOnClick: true,
pickerId: null,
initComponent: function() {
var me = this,
cfg = Ext.apply({}, me.initialConfig);
delete cfg.listeners;
Ext.apply(me, {
showSeparator: false,
plain: true,
bodyPadding: 0,
items: Ext.applyIf({
cls: Ext.baseCSSPrefix + 'menu-date-item',
margin: 0,
border: false,
id: me.pickerId,
xtype: 'datepicker'
}, cfg)
});
me.callParent(arguments);
me.picker = me.down('datepicker');
me.relayEvents(me.picker, [
'select'
]);
if (me.hideOnClick) {
me.on('select', me.hidePickerOnSelect, me);
}
},
hidePickerOnSelect: function() {
Ext.menu.Manager.hideAll();
}
});
Ext.define('Ext.panel.Pinnable', {
extend: 'Ext.Mixin',
mixinId: 'pinnable',
pinnable: true,
pinnedTip: 'Unpin this item',
unpinnedTip: 'Pin this item',
initPinnable: function() {
var me = this,
pinned = me.isPinned();
me.addTool(me.pinTool = Ext.widget({
xtype: 'tool',
type: pinned ? 'unpin' : 'pin',
callback: 'togglePin',
scope: me,
tooltip: pinned ? me.pinnedTip : me.unpinnedTip
}));
},
isPinned: function() {
return !this.floating;
},
setPinned: function(pinned) {
var me = this,
args;
if (pinned !== me.isPinned()) {
args = [
me,
pinned
];
if (me.fireEventArgs('beforepinchange', args) !== false) {
me.updatePinned(pinned);
me.fireEventArgs('pinchange', args);
}
}
},
togglePin: function() {
this.setPinned(!this.isPinned());
},
updatePinned: function(pinned) {
var me = this,
tool = me.pinTool;
tool.setTooltip(pinned ? me.pinnedTip : me.unpinnedTip);
tool.setType(pinned ? 'unpin' : 'pin');
}
});
Ext.define('Ext.plugin.Manager', {
alternateClassName: [
'Ext.PluginManager',
'Ext.PluginMgr'
],
singleton: true,
typeName: 'ptype',
create: function(config, defaultType, host) {
var result, type;
if (config.init) {
result = config;
} else {
if (host) {
config = Ext.apply({}, config);
config.cmp = host;
} else
{
host = config.cmp;
}
if (config.xclass) {
result = Ext.create(config);
} else {
type = 'plugin.' + (config.ptype || defaultType);
result = Ext.ClassManager.instantiateByAlias(type, config);
}
}
if (result && host && result.setCmp && !result.setCmpCalled) {
result.setCmp(host);
result.setCmpCalled = true;
}
return result;
}
});
Ext.define('Ext.resizer.BorderSplitterTracker', {
extend: 'Ext.resizer.SplitterTracker',
requires: [
'Ext.util.Region'
],
getPrevCmp: null,
getNextCmp: null,
calculateConstrainRegion: function() {
var me = this,
splitter = me.splitter,
collapseTarget = splitter.collapseTarget,
defaultSplitMin = splitter.defaultSplitMin,
sizePropCap = splitter.vertical ? 'Width' : 'Height',
minSizeProp = 'min' + sizePropCap,
maxSizeProp = 'max' + sizePropCap,
getSizeMethod = 'get' + sizePropCap,
neighbors = splitter.neighbors,
length = neighbors.length,
box = collapseTarget.el.getBox(),
left = box.x,
top = box.y,
right = box.right,
bottom = box.bottom,
size = splitter.vertical ? (right - left) : (bottom - top),
i, neighbor, neighborMaxSize, minRange, maxRange, maxGrowth, maxShrink, targetSize;
minRange = (collapseTarget[minSizeProp] || Math.min(size, defaultSplitMin)) - size;
maxRange = collapseTarget[maxSizeProp];
if (!maxRange) {
maxRange = 1000000000;
} else {
maxRange -= size;
}
targetSize = size;
for (i = 0; i < length; ++i) {
neighbor = neighbors[i];
size = neighbor[getSizeMethod]();
neighborMaxSize = neighbor[maxSizeProp];
if (neighborMaxSize === null) {
neighborMaxSize = undefined;
}
maxGrowth = size - neighborMaxSize;
maxShrink = size - (neighbor[minSizeProp] || Math.min(size, defaultSplitMin));
if (!isNaN(maxGrowth)) {
if (minRange < maxGrowth) {
minRange = maxGrowth;
}
}
if (maxRange > maxShrink) {
maxRange = maxShrink;
}
}
if (maxRange - minRange < 2) {
return null;
}
box = new Ext.util.Region(top, right, bottom, left);
me.constraintAdjusters[me.getCollapseDirection()](box, minRange, maxRange, splitter);
me.dragInfo = {
minRange: minRange,
maxRange: maxRange,
targetSize: targetSize
};
return box;
},
constraintAdjusters: {
left: function(box, minRange, maxRange, splitter) {
box[0] = box.x = box.left = box.right + minRange;
box.right += maxRange + splitter.getWidth();
},
top: function(box, minRange, maxRange, splitter) {
box[1] = box.y = box.top = box.bottom + minRange;
box.bottom += maxRange + splitter.getHeight();
},
bottom: function(box, minRange, maxRange, splitter) {
box.bottom = box.top - minRange;
box.top -= maxRange + splitter.getHeight();
},
right: function(box, minRange, maxRange, splitter) {
box.right = box.left - minRange;
box[0] = box.x = box.left = box.x - maxRange + splitter.getWidth();
}
},
onBeforeStart: function(e) {
var me = this,
splitter = me.splitter,
collapseTarget = splitter.collapseTarget,
neighbors = splitter.neighbors,
length = neighbors.length,
i, neighbor;
if (collapseTarget.collapsed) {
return false;
}
for (i = 0; i < length; ++i) {
neighbor = neighbors[i];
if (neighbor.collapsed && neighbor.isHorz === collapseTarget.isHorz) {
return false;
}
}
if (!(me.constrainTo = me.calculateConstrainRegion())) {
return false;
}
return true;
},
performResize: function(e, offset) {
var me = this,
splitter = me.splitter,
collapseDirection = splitter.getCollapseDirection(),
collapseTarget = splitter.collapseTarget,
adjusters = me.splitAdjusters[splitter.vertical ? 'horz' : 'vert'],
delta = offset[adjusters.index],
dragInfo = me.dragInfo,
owner;
if (collapseDirection === 'right' || collapseDirection === 'bottom') {
delta = -delta;
}
delta = Math.min(Math.max(dragInfo.minRange, delta), dragInfo.maxRange);
if (delta) {
(owner = splitter.ownerCt).suspendLayouts();
adjusters.adjustTarget(collapseTarget, dragInfo.targetSize, delta);
owner.resumeLayouts(true);
}
},
splitAdjusters: {
horz: {
index: 0,
adjustTarget: function(target, size, delta) {
target.flex = null;
target.setSize(size + delta);
}
},
vert: {
index: 1,
adjustTarget: function(target, targetSize, delta) {
target.flex = null;
target.setSize(undefined, targetSize + delta);
}
}
},
getCollapseDirection: function() {
return this.splitter.getCollapseDirection();
}
});
Ext.define('Ext.resizer.Handle', {
extend: 'Ext.Component',
handleCls: '',
baseHandleCls: Ext.baseCSSPrefix + 'resizable-handle',
region: '',
ariaRole: 'presentation',
beforeRender: function() {
var me = this;
me.callParent();
me.protoEl.unselectable();
me.addCls(me.baseHandleCls, me.baseHandleCls + '-' + me.region, me.handleCls);
}
});
Ext.define('Ext.resizer.ResizeTracker', {
extend: 'Ext.dd.DragTracker',
dynamic: true,
preserveRatio: false,
constrainTo: null,
proxyCls: Ext.baseCSSPrefix + 'resizable-proxy',
constructor: function(config) {
var me = this,
widthRatio, heightRatio, throttledResizeFn;
if (!config.el) {
if (config.target.isComponent) {
me.el = config.target.getEl();
} else {
me.el = config.target;
}
}
this.callParent(arguments);
if (me.preserveRatio && me.minWidth && me.minHeight) {
widthRatio = me.minWidth / me.el.getWidth();
heightRatio = me.minHeight / me.el.getHeight();
if (heightRatio > widthRatio) {
me.minWidth = me.el.getWidth() * heightRatio;
} else {
me.minHeight = me.el.getHeight() * widthRatio;
}
}
if (me.throttle) {
throttledResizeFn = Ext.Function.createThrottled(function() {
Ext.resizer.ResizeTracker.prototype.resize.apply(me, arguments);
}, me.throttle);
me.resize = function(box, direction, atEnd) {
if (atEnd) {
Ext.resizer.ResizeTracker.prototype.resize.apply(me, arguments);
} else {
throttledResizeFn.apply(null, arguments);
}
};
}
},
onBeforeStart: function(e) {
this.startBox = this.target.getBox();
},
getProxy: function() {
var me = this;
if (!me.dynamic && !me.proxy) {
me.proxy = me.createProxy(me.target || me.el);
me.hideProxy = true;
}
if (me.proxy) {
me.proxy.show();
return me.proxy;
}
},
createProxy: function(target) {
var proxy,
cls = this.proxyCls;
if (target.isComponent) {
proxy = target.getProxy().addCls(cls);
} else {
proxy = target.createProxy({
tag: 'div',
role: 'presentation',
cls: cls,
id: target.id + '-rzproxy'
}, Ext.getBody());
}
proxy.removeCls(Ext.baseCSSPrefix + 'proxy-el');
return proxy;
},
onStart: function(e) {
this.activeResizeHandle = Ext.get(this.getDragTarget().id);
if (!this.dynamic) {
this.resize(this.startBox);
}
},
onDrag: function(e) {
if (this.dynamic || this.proxy) {
this.updateDimensions(e);
}
},
updateDimensions: function(e, atEnd) {
var me = this,
region = me.activeResizeHandle.region,
offset = me.getOffset(me.constrainTo ? 'dragTarget' : null),
box = me.startBox,
ratio,
widthAdjust = 0,
heightAdjust = 0,
snappedWidth, snappedHeight,
adjustX = 0,
adjustY = 0,
dragRatio, oppositeCorner, axis,
newBox, newHeight, newWidth;
region = me.convertRegionName(region);
switch (region) {
case 'south':
heightAdjust = offset[1];
axis = 2;
break;
case 'north':
heightAdjust = -offset[1];
adjustY = -heightAdjust;
axis = 2;
break;
case 'east':
widthAdjust = offset[0];
axis = 1;
break;
case 'west':
widthAdjust = -offset[0];
adjustX = -widthAdjust;
axis = 1;
break;
case 'northeast':
heightAdjust = -offset[1];
adjustY = -heightAdjust;
widthAdjust = offset[0];
oppositeCorner = [
box.x,
box.y + box.height
];
axis = 3;
break;
case 'southeast':
heightAdjust = offset[1];
widthAdjust = offset[0];
oppositeCorner = [
box.x,
box.y
];
axis = 3;
break;
case 'southwest':
widthAdjust = -offset[0];
adjustX = -widthAdjust;
heightAdjust = offset[1];
oppositeCorner = [
box.x + box.width,
box.y
];
axis = 3;
break;
case 'northwest':
heightAdjust = -offset[1];
adjustY = -heightAdjust;
widthAdjust = -offset[0];
adjustX = -widthAdjust;
oppositeCorner = [
box.x + box.width,
box.y + box.height
];
axis = 3;
break;
}
newBox = {
width: box.width + widthAdjust,
height: box.height + heightAdjust,
x: box.x + adjustX,
y: box.y + adjustY
};
snappedWidth = Ext.Number.snap(newBox.width, me.widthIncrement);
snappedHeight = Ext.Number.snap(newBox.height, me.heightIncrement);
if (snappedWidth !== newBox.width || snappedHeight !== newBox.height) {
switch (region) {
case 'northeast':
newBox.y -= snappedHeight - newBox.height;
break;
case 'north':
newBox.y -= snappedHeight - newBox.height;
break;
case 'southwest':
newBox.x -= snappedWidth - newBox.width;
break;
case 'west':
newBox.x -= snappedWidth - newBox.width;
break;
case 'northwest':
newBox.x -= snappedWidth - newBox.width;
newBox.y -= snappedHeight - newBox.height;
}
newBox.width = snappedWidth;
newBox.height = snappedHeight;
}
if (newBox.width < me.minWidth || newBox.width > me.maxWidth) {
newBox.width = Ext.Number.constrain(newBox.width, me.minWidth, me.maxWidth);
if (adjustX) {
newBox.x = box.x + (box.width - newBox.width);
}
} else {
me.lastX = newBox.x;
}
if (newBox.height < me.minHeight || newBox.height > me.maxHeight) {
newBox.height = Ext.Number.constrain(newBox.height, me.minHeight, me.maxHeight);
if (adjustY) {
newBox.y = box.y + (box.height - newBox.height);
}
} else {
me.lastY = newBox.y;
}
if (me.preserveRatio || e.shiftKey) {
ratio = me.startBox.width / me.startBox.height;
newHeight = Math.min(Math.max(me.minHeight, newBox.width / ratio), me.maxHeight);
newWidth = Math.min(Math.max(me.minWidth, newBox.height * ratio), me.maxWidth);
if (axis === 1) {
newBox.height = newHeight;
}
else if (axis === 2) {
newBox.width = newWidth;
} else
{
dragRatio = Math.abs(oppositeCorner[0] - this.lastXY[0]) / Math.abs(oppositeCorner[1] - this.lastXY[1]);
if (dragRatio > ratio) {
newBox.height = newHeight;
} else {
newBox.width = newWidth;
}
if (region === 'northeast') {
newBox.y = box.y - (newBox.height - box.height);
} else if (region === 'northwest') {
newBox.y = box.y - (newBox.height - box.height);
newBox.x = box.x - (newBox.width - box.width);
} else if (region === 'southwest') {
newBox.x = box.x - (newBox.width - box.width);
}
}
}
me.setPosition = newBox.x !== me.startBox.x || newBox.y !== me.startBox.y;
me.resize(newBox, atEnd);
},
resize: function(box, atEnd) {
var me = this,
target,
setPosition = me.setPosition;
if (me.dynamic || (!me.dynamic && atEnd)) {
if (setPosition) {
me.target.setBox(box);
} else {
me.target.setSize(box.width, box.height);
}
}
if (!atEnd) {
target = me.getProxy();
if (target && target !== me.target) {
if (setPosition || me.hideProxy) {
target.setBox(box);
} else {
target.setSize(box.width, box.height);
}
}
}
},
onEnd: function(e) {
this.updateDimensions(e, true);
if (this.proxy && this.hideProxy) {
this.proxy.hide();
}
},
convertRegionName: function(name) {
return name;
}
});
Ext.define('Ext.resizer.Resizer', {
mixins: {
observable: 'Ext.util.Observable'
},
uses: [
'Ext.resizer.ResizeTracker',
'Ext.Component'
],
alternateClassName: 'Ext.Resizable',
handleCls: Ext.baseCSSPrefix + 'resizable-handle',
overCls: Ext.baseCSSPrefix + 'resizable-handle-over',
pinnedCls: Ext.baseCSSPrefix + 'resizable-pinned',
wrapCls: Ext.baseCSSPrefix + 'resizable-wrap',
wrappedCls: Ext.baseCSSPrefix + 'resizable-wrapped',
delimiterRe: /(?:\s*[,;]\s*)|\s+/,
dynamic: true,
handles: 's e se',
height: null,
width: null,
heightIncrement: 0,
widthIncrement: 0,
minHeight: 20,
minWidth: 20,
maxHeight: 10000,
maxWidth: 10000,
pinned: false,
preserveRatio: false,
transparent: false,
possiblePositions: {
n: 'north',
s: 'south',
e: 'east',
w: 'west',
se: 'southeast',
sw: 'southwest',
nw: 'northwest',
ne: 'northeast'
},
ariaRole: 'presentation',
constructor: function(config) {
var me = this,
handles = me.handles,
unselectableCls = Ext.dom.Element.unselectableCls,
handleEls = [],
resizeTarget, handleCls, possibles, tag, len, i, pos, el, box, wrapTarget, positioning, targetBaseCls;
if (Ext.isString(config) || Ext.isElement(config) || config.dom) {
resizeTarget = config;
config = arguments[1] || {};
config.target = resizeTarget;
}
me.mixins.observable.constructor.call(me, config);
resizeTarget = me.target;
if (resizeTarget) {
if (resizeTarget.isComponent) {
resizeTarget.addClsWithUI('resizable');
if (resizeTarget.minWidth) {
me.minWidth = resizeTarget.minWidth;
}
if (resizeTarget.minHeight) {
me.minHeight = resizeTarget.minHeight;
}
if (resizeTarget.maxWidth) {
me.maxWidth = resizeTarget.maxWidth;
}
if (resizeTarget.maxHeight) {
me.maxHeight = resizeTarget.maxHeight;
}
if (resizeTarget.floating) {
if (!me.hasOwnProperty('handles')) {
me.handles = 'n ne e se s sw w nw';
}
}
me.el = resizeTarget.getEl();
} else {
resizeTarget = me.el = me.target = Ext.get(resizeTarget);
}
} else
{
resizeTarget = me.target = me.el = Ext.get(me.el);
}
me.el.addCls(Ext.Component.prototype.borderBoxCls);
if (Ext.isNumber(me.width)) {
me.width = Ext.Number.constrain(me.width, me.minWidth, me.maxWidth);
}
if (Ext.isNumber(me.height)) {
me.height = Ext.Number.constrain(me.height, me.minHeight, me.maxHeight);
}
if (me.width !== null || me.height !== null) {
me.target.setSize(me.width, me.height);
}
tag = me.el.dom.tagName.toUpperCase();
if (tag === 'TEXTAREA' || tag === 'IMG' || tag === 'TABLE') {
me.originalTarget = me.target;
wrapTarget = resizeTarget.isComponent ? resizeTarget.getEl() : resizeTarget;
me.el.addCls(me.wrappedCls);
me.target = me.el = me.el.wrap({
role: 'presentation',
cls: me.wrapCls,
id: me.el.id + '-rzwrap',
style: wrapTarget.getStyle([
'margin-top',
'margin-bottom'
])
});
positioning = wrapTarget.getPositioning();
me.el.setPositioning(positioning);
wrapTarget.clearPositioning();
box = wrapTarget.getBox();
if (positioning.position !== 'absolute') {
box.x = 0;
box.y = 0;
}
me.el.setBox(box);
wrapTarget.setStyle('position', 'absolute');
me.isTargetWrapped = true;
}
me.el.position();
if (me.pinned) {
me.el.addCls(me.pinnedCls);
}
me.resizeTracker = new Ext.resizer.ResizeTracker({
disabled: me.disabled,
target: resizeTarget,
el: me.el,
constrainTo: me.constrainTo,
handleCls: me.handleCls,
overCls: me.overCls,
throttle: me.throttle,
proxy: me.originalTarget ? me.el : null,
dynamic: me.originalTarget ? true : me.dynamic,
originalTarget: me.originalTarget,
delegate: '.' + me.handleCls,
preserveRatio: me.preserveRatio,
heightIncrement: me.heightIncrement,
widthIncrement: me.widthIncrement,
minHeight: me.minHeight,
maxHeight: me.maxHeight,
minWidth: me.minWidth,
maxWidth: me.maxWidth
});
me.resizeTracker.on({
mousedown: me.onBeforeResize,
drag: me.onResize,
dragend: me.onResizeEnd,
scope: me
});
if (me.handles === 'all') {
me.handles = 'n s e w ne nw se sw';
}
handles = me.handles = me.handles.split(me.delimiterRe);
possibles = me.possiblePositions;
len = handles.length;
handleCls = me.handleCls + ' ' + me.handleCls + '-{0}';
if (me.target.isComponent) {
targetBaseCls = me.target.baseCls;
handleCls += ' ' + targetBaseCls + '-handle ' + targetBaseCls + '-handle-{0}';
if (Ext.supports.CSS3BorderRadius) {
handleCls += ' ' + targetBaseCls + '-handle-{0}-br';
}
}
for (i = 0; i < len; i++) {
if (handles[i] && possibles[handles[i]]) {
pos = possibles[handles[i]];
handleEls.push('<div id="', me.el.id, '-', pos, '-handle" class="', Ext.String.format(handleCls, pos), ' ', unselectableCls, '" unselectable="on" role="presentation"', '></div>');
}
}
Ext.DomHelper.append(me.el, handleEls.join(''));
handleEls.length = 0;
for (i = 0; i < len; i++) {
if (handles[i] && possibles[handles[i]]) {
pos = possibles[handles[i]];
el = me[pos] = me.el.getById(me.el.id + '-' + pos + '-handle');
handleEls.push(el);
el.region = pos;
if (me.transparent) {
el.setOpacity(0);
}
}
}
me.resizeTracker.handleEls = handleEls;
},
disable: function() {
this.resizeTracker.disable();
},
enable: function() {
this.resizeTracker.enable();
},
onBeforeResize: function(tracker, e) {
return this.fireResizeEvent('beforeresize', tracker, e);
},
onResize: function(tracker, e) {
return this.fireResizeEvent('resizedrag', tracker, e);
},
onResizeEnd: function(tracker, e) {
return this.fireResizeEvent('resize', tracker, e);
},
fireResizeEvent: function(name, tracker, e) {
var me = this,
box;
if (me.hasListeners[name]) {
box = me.el.getBox();
return me.fireEvent(name, me, box.width, box.height, e);
}
},
resizeTo: function(width, height) {
var me = this;
me.target.setSize(width, height);
me.fireEvent('resize', me, width, height, null);
},
getEl: function() {
return this.el;
},
getTarget: function() {
return this.target;
},
destroy: function() {
var me = this,
i,
handles = me.handles,
len = handles.length,
positions = me.possiblePositions,
handle;
me.resizeTracker.destroy();
if (me.isTargetWrapped) {
me.target.destroy();
}
for (i = 0; i < len; i++) {
if ((handle = me[positions[handles[i]]])) {
handle.destroy();
}
}
}
});
Ext.define('Ext.selection.CellModel', {
extend: 'Ext.selection.DataViewModel',
alias: 'selection.cellmodel',
requires: [
'Ext.grid.CellContext'
],
isCellModel: true,
deselectOnContainerClick: false,
enableKeyNav: true,
preventWrap: false,
bindComponent: function(view) {
var me = this,
grid;
if (me.view && me.gridListeners) {
me.gridListeners.destroy();
}
me.callParent([
view
]);
if (view) {
grid = view.grid || view.ownerCt;
if (grid.optimizedColumnMove !== false) {
me.gridListeners = grid.on({
columnmove: me.onColumnMove,
scope: me,
destroyable: true
});
}
}
},
getViewListeners: function() {
var result = this.callParent();
result.refresh = this.onViewRefresh;
return result;
},
getHeaderCt: function() {
var selection = this.navigationModel.getPosition(),
view = selection ? selection.view : this.primaryView;
return view.headerCt;
},
onNavigate: function(e) {
if (!e.record) {
return;
}
this.setPosition(e.position);
},
selectWithEvent: function(record, e) {
this.select(record);
},
select: function(pos,
keepExisting, suppressEvent) {
var me = this,
row,
oldPos = me.getPosition(),
store = me.view.store;
if (pos || pos === 0) {
if (pos.isModel) {
row = store.indexOf(pos);
if (row !== -1) {
pos = {
row: row,
column: oldPos ? oldPos.column : 0
};
} else {
pos = null;
}
} else if (typeof pos === 'number') {
pos = {
row: pos,
column: 0
};
}
}
if (pos) {
me.selectByPosition(pos, suppressEvent);
} else {
me.deselect();
}
},
getCurrentPosition: function() {
var position = this.selecting ? this.nextSelection : this.selection;
return position ? {
view: position.view,
record: position.record,
row: position.rowIdx,
columnHeader: position.column,
column: position.view.getColumnManager().indexOf(position.column)
} : position;
},
getPosition: function() {
return (this.selecting ? this.nextSelection : this.selection) || null;
},
setCurrentPosition: function(pos, suppressEvent,
preventCheck) {
if (pos && !pos.isCellContext) {
pos = new Ext.grid.CellContext(this.view).setPosition({
row: pos.row,
column: typeof pos.column === 'number' ? this.view.getColumnManager().getColumns()[pos.column] : pos.column
});
}
return this.setPosition(pos, suppressEvent, preventCheck);
},
setPosition: function(pos, suppressEvent,
preventCheck) {
var me = this,
last = me.selection;
if (pos) {
pos = pos.isCellContext ? pos.clone() : new Ext.grid.CellContext(me.view).setPosition(pos);
}
if (!preventCheck && last) {
if (pos && (pos.record === last.record && pos.column === last.column && pos.view === last.view)) {
pos = null;
} else {
me.onCellDeselect(me.selection, suppressEvent);
}
}
if (pos) {
me.nextSelection = pos;
me.selecting = true;
me.onCellSelect(me.nextSelection, suppressEvent);
me.selecting = false;
return (me.selection = pos);
}
return null;
},
isCellSelected: function(view, row, column) {
var me = this,
testPos,
pos = me.getPosition();
if (pos && pos.view === view) {
testPos = new Ext.grid.CellContext(view).setPosition({
row: row,
column: typeof column === 'number' ? view.getColumnManager().getColumns()[column] : column
});
return (testPos.record === pos.record) && (testPos.column === pos.column);
}
},
onStoreRemove: function(store, records, indices) {
var me = this,
pos = me.getPosition();
me.callParent(arguments);
if (pos && store.isMoving(pos.record)) {
return;
}
if (pos && store.getCount() && store.indexOf(pos.record) !== -1) {
pos.setRow(pos.record);
} else {
me.selection = null;
}
},
onStoreClear: function() {
this.callParent(arguments);
this.selection = null;
},
onStoreAdd: function() {
var me = this,
pos = me.getPosition();
me.callParent(arguments);
if (pos) {
pos.setRow(pos.record);
} else {
me.selection = null;
}
},
onCellClick: function(view, cell, cellIndex, record, row, recordIndex, e) {
if (recordIndex !== -1) {
this.setPosition(e.position);
}
},
onCellSelect: function(position, supressEvent) {
if (position && position.rowIdx !== undefined && position.rowIdx > -1) {
this.doSelect(position.record,
false, supressEvent);
}
},
onCellDeselect: function(position, supressEvent) {
if (position && position.rowIdx !== undefined) {
this.doDeselect(position.record, supressEvent);
}
},
onSelectChange: function(record, isSelected, suppressEvent, commitFn) {
var me = this,
pos, eventName, view;
if (isSelected) {
pos = me.nextSelection;
eventName = 'select';
} else {
pos = me.selection;
eventName = 'deselect';
}
view = pos.view || me.primaryView;
if ((suppressEvent || me.fireEvent('before' + eventName, me, record, pos.rowIdx, pos.colIdx)) !== false && commitFn() !== false) {
if (isSelected) {
view.onCellSelect(pos);
} else {
view.onCellDeselect(pos);
delete me.selection;
}
if (!suppressEvent) {
me.fireEvent(eventName, me, record, pos.rowIdx, pos.colIdx);
}
}
},
onEditorTab: function(editingPlugin, e) {
var me = this,
direction = e.shiftKey ? 'left' : 'right',
pos = e.position,
position = pos.view.walkCells(pos, direction, e, me.preventWrap);
if (position) {
if (editingPlugin.startEdit(position.record, position.column)) {
me.wasEditing = false;
} else
{
position.view.getNavigationModel().setPosition(position, null, e);
me.wasEditing = true;
}
}
},
refresh: function() {
var pos = this.getPosition(),
selRowIdx;
if (pos && (selRowIdx = this.store.indexOf(this.selected.last())) !== -1) {
pos.rowIdx = selRowIdx;
}
},
onColumnMove: function(headerCt, header, fromIdx, toIdx) {
var grid = headerCt.up('tablepanel');
if (grid) {
this.onViewRefresh(grid.view);
}
},
onUpdate: function(record) {
var me = this,
pos;
if (me.isSelected(record)) {
pos = me.selecting ? me.nextSelection : me.selection;
me.view.onCellSelect(pos);
}
},
onViewRefresh: function(view) {
var me = this,
pos = me.getPosition(),
newPos,
headerCt = view.headerCt,
record, column;
if (pos && pos.view === view) {
record = pos.record;
column = pos.column;
if (!column.isDescendantOf(headerCt)) {
column = headerCt.queryById(column.id) || headerCt.down('[text="' + column.text + '"]') || headerCt.down('[dataIndex="' + column.dataIndex + '"]');
}
if (pos.record) {
if (column && (view.store.indexOfId(record.getId()) !== -1)) {
newPos = new Ext.grid.CellContext(view).setPosition({
row: record,
column: column
});
me.setPosition(newPos);
}
} else {
me.selection = null;
}
}
},
selectByPosition: function(position, suppressEvent) {
this.setPosition(position, suppressEvent);
}
});
Ext.define('Ext.selection.CheckboxModel', {
alias: 'selection.checkboxmodel',
extend: 'Ext.selection.RowModel',
mode: 'MULTI',
injectCheckbox: 0,
checkOnly: false,
showHeaderCheckbox: undefined,
checkSelector: '.' + Ext.baseCSSPrefix + 'grid-row-checker',
allowDeselect: true,
headerWidth: 24,
checkerOnCls: Ext.baseCSSPrefix + 'grid-hd-checker-on',
tdCls: Ext.baseCSSPrefix + 'grid-cell-special ' + Ext.baseCSSPrefix + 'grid-cell-row-checker',
constructor: function() {
var me = this;
me.callParent(arguments);
if (me.mode === 'SINGLE' && me.showHeaderCheckbox !== true) {
me.showHeaderCheckbox = false;
}
},
beforeViewRender: function(view) {
var me = this,
owner;
me.callParent(arguments);
if (!me.hasLockedHeader() || view.headerCt.lockedCt) {
me.addCheckbox(view, true);
owner = view.ownerCt;
if (view.headerCt.lockedCt) {
owner = owner.ownerCt;
}
me.mon(owner, 'reconfigure', me.onReconfigure, me);
}
},
bindComponent: function(view) {
this.sortable = false;
this.callParent(arguments);
},
hasLockedHeader: function() {
var views = this.views,
vLen = views.length,
v;
for (v = 0; v < vLen; v++) {
if (views[v].headerCt.lockedCt) {
return true;
}
}
return false;
},
addCheckbox: function(view, initial) {
var me = this,
checkbox = me.injectCheckbox,
headerCt = view.headerCt;
if (checkbox !== false) {
if (checkbox === 'first') {
checkbox = 0;
} else if (checkbox === 'last') {
checkbox = headerCt.getColumnCount();
}
Ext.suspendLayouts();
if (view.getStore().isBufferedStore) {
me.showHeaderCheckbox = false;
}
me.column = headerCt.add(checkbox, me.getHeaderConfig());
Ext.resumeLayouts();
}
if (initial !== true) {
view.refresh();
}
},
onReconfigure: function(grid, store, columns) {
if (columns) {
this.addCheckbox(this.views[0]);
}
},
toggleUiHeader: function(isChecked) {
var view = this.views[0],
headerCt = view.headerCt,
checkHd = headerCt.child('gridcolumn[isCheckerHd]'),
cls = this.checkerOnCls;
if (checkHd) {
if (isChecked) {
checkHd.addCls(cls);
} else {
checkHd.removeCls(cls);
}
}
},
onHeaderClick: function(headerCt, header, e) {
if (header === this.column) {
e.stopEvent();
var me = this,
isChecked = header.el.hasCls(Ext.baseCSSPrefix + 'grid-hd-checker-on');
if (isChecked) {
me.deselectAll();
} else {
me.selectAll();
}
}
},
getHeaderConfig: function() {
var me = this,
showCheck = me.showHeaderCheckbox !== false;
return {
xtype: 'gridcolumn',
isCheckerHd: showCheck,
text: '&#160;',
clickTargetName: 'el',
width: me.headerWidth,
sortable: false,
draggable: false,
resizable: false,
hideable: false,
menuDisabled: true,
dataIndex: '',
tdCls: me.tdCls,
cls: showCheck ? Ext.baseCSSPrefix + 'column-header-checkbox ' : '',
defaultRenderer: me.renderer.bind(me),
editRenderer: me.editRenderer || me.renderEmpty,
locked: me.hasLockedHeader()
};
},
renderEmpty: function() {
return '&#160;';
},
refresh: function() {
this.callParent(arguments);
this.updateHeaderState();
},
renderer: function(value, metaData, record, rowIndex, colIndex, store, view) {
return '<div class="' + Ext.baseCSSPrefix + 'grid-row-checker" role="presentation">&#160;</div>';
},
selectByPosition: function(position, keepExisting) {
if (!position.isCellContext) {
position = new Ext.grid.CellContext(this.view).setPosition(position.row, position.column);
}
if (!this.checkOnly || position.column !== this.column) {
this.callParent([
position,
keepExisting
]);
}
},
onSelectChange: function() {
this.callParent(arguments);
if (!this.suspendChange) {
this.updateHeaderState();
}
},
onStoreLoad: function() {
this.callParent(arguments);
this.updateHeaderState();
},
onStoreAdd: function() {
this.callParent(arguments);
this.updateHeaderState();
},
onStoreRemove: function() {
this.callParent(arguments);
this.updateHeaderState();
},
onStoreRefresh: function() {
this.callParent(arguments);
this.updateHeaderState();
},
maybeFireSelectionChange: function(fireEvent) {
if (fireEvent && !this.suspendChange) {
this.updateHeaderState();
}
this.callParent(arguments);
},
resumeChanges: function() {
this.callParent();
if (!this.suspendChange) {
this.updateHeaderState();
}
},
updateHeaderState: function() {
var me = this,
store = me.store,
storeCount = store.getCount(),
views = me.views,
hdSelectStatus = false,
selectedCount = 0,
selected, len, i;
if (!store.isBufferedStore && storeCount > 0) {
selected = me.selected;
hdSelectStatus = true;
for (i = 0 , len = selected.getCount(); i < len; ++i) {
if (store.indexOfId(selected.getAt(i).id) === -1) {
break;
}
++selectedCount;
}
hdSelectStatus = storeCount === selectedCount;
}
if (views && views.length) {
me.toggleUiHeader(hdSelectStatus);
}
},
vetoSelection: function(e) {
var me = this,
column = me.column,
veto, isClick, isSpace;
if (me.checkOnly) {
isClick = e.type === 'click' && e.getTarget(me.checkSelector);
isSpace = e.getKey() === e.SPACE && e.position.column === column;
veto = !(isClick || isSpace);
}
return veto || me.callParent([
e
]);
},
destroy: function() {
this.column = null;
this.callParent();
},
privates: {
onBeforeNavigate: function(metaEvent) {
var e = metaEvent.keyEvent;
if (this.selectionMode !== 'SINGLE') {
metaEvent.ctrlKey = metaEvent.ctrlKey || e.ctrlKey || (e.type === 'click' && !e.shiftKey) || e.getKey() === e.SPACE;
}
},
selectWithEventMulti: function(record, e, isSelected) {
var me = this;
if (!e.shiftKey && !e.ctrlKey && e.getTarget(me.checkSelector)) {
if (isSelected) {
me.doDeselect(record);
} else {
me.doSelect(record, true);
}
} else {
me.callParent([
record,
e,
isSelected
]);
}
}
}
});
Ext.define('Ext.slider.Thumb', {
requires: [
'Ext.dd.DragTracker',
'Ext.util.Format'
],
overCls: Ext.baseCSSPrefix + 'slider-thumb-over',
constructor: function(config) {
var me = this;
Ext.apply(me, config || {}, {
cls: Ext.baseCSSPrefix + 'slider-thumb',
constrain: false
});
me.callParent([
config
]);
},
render: function() {
var me = this;
me.el = me.slider.innerEl.insertFirst(me.getElConfig());
me.onRender();
},
onRender: function() {
if (this.disabled) {
this.disable();
}
this.initEvents();
},
getElConfig: function() {
var me = this,
slider = me.slider,
style = {};
style[slider.vertical ? 'bottom' : slider.horizontalProp] = slider.calculateThumbPosition(slider.normalizeValue(me.value)) + '%';
return {
style: style,
id: this.id,
cls: this.cls,
role: 'presentation'
};
},
move: function(v, animate) {
var me = this,
el = me.el,
slider = me.slider,
styleProp = slider.vertical ? 'bottom' : slider.horizontalProp,
to, from, animCfg;
v += '%';
if (!animate) {
el.dom.style[styleProp] = v;
} else {
to = {};
to[styleProp] = v;
if (!Ext.supports.GetPositionPercentage) {
from = {};
from[styleProp] = el.dom.style[styleProp];
}
animCfg = {
target: el,
duration: 350,
from: from,
to: to,
scope: me,
callback: me.onAnimComplete
};
if (animate !== true) {
Ext.apply(animCfg, animate);
}
me.anim = new Ext.fx.Anim(animCfg);
}
},
onAnimComplete: function() {
this.anim = null;
},
enable: function() {
var el = this.el;
this.disabled = false;
if (el) {
el.removeCls(this.slider.disabledCls);
}
},
disable: function() {
var el = this.el;
this.disabled = true;
if (el) {
el.addCls(this.slider.disabledCls);
}
},
initEvents: function() {
var me = this;
me.tracker = new Ext.dd.DragTracker({
el: me.el,
onBeforeStart: me.onBeforeDragStart.bind(me),
onStart: me.onDragStart.bind(me),
onDrag: me.onDrag.bind(me),
onEnd: me.onDragEnd.bind(me),
tolerance: 3,
autoStart: 300
});
me.el.hover(me.addOverCls, me.removeOverCls, me);
},
addOverCls: function() {
var me = this;
if (!me.disabled) {
me.el.addCls(me.overCls);
}
},
removeOverCls: function() {
this.el.removeCls(this.overCls);
},
onBeforeDragStart: function(e) {
var me = this,
el = me.el,
trackerXY = me.tracker.getXY(),
delta = me.pointerOffset = el.getXY();
if (me.disabled) {
return false;
} else {
delta[0] += Math.floor(el.getWidth() / 2) - trackerXY[0];
delta[1] += Math.floor(el.getHeight() / 2) - trackerXY[1];
me.slider.promoteThumb(me);
return true;
}
},
onDragStart: function(e) {
var me = this,
slider = me.slider;
slider.onDragStart(me, e);
me.el.addCls(Ext.baseCSSPrefix + 'slider-thumb-drag');
me.dragging = me.slider.dragging = true;
me.dragStartValue = me.value;
slider.fireEvent('dragstart', slider, e, me);
},
onDrag: function(e) {
var me = this,
slider = me.slider,
index = me.index,
newValue = me.getValueFromTracker(),
above, below;
if (newValue !== undefined) {
if (me.constrain) {
above = slider.thumbs[index + 1];
below = slider.thumbs[index - 1];
if (below !== undefined && newValue <= below.value) {
newValue = below.value;
}
if (above !== undefined && newValue >= above.value) {
newValue = above.value;
}
}
slider.setValue(index, newValue, false);
slider.fireEvent('drag', slider, e, me);
}
},
getValueFromTracker: function() {
var slider = this.slider,
trackerXY = this.tracker.getXY(),
trackPoint;
trackerXY[0] += this.pointerOffset[0];
trackerXY[1] += this.pointerOffset[1];
trackPoint = slider.getTrackpoint(trackerXY);
if (trackPoint !== undefined) {
return slider.reversePixelValue(trackPoint);
}
},
onDragEnd: function(e) {
var me = this,
slider = me.slider,
value = me.value;
slider.onDragEnd(me, e);
me.el.removeCls(Ext.baseCSSPrefix + 'slider-thumb-drag');
me.dragging = slider.dragging = false;
slider.fireEvent('dragend', slider, e);
if (me.dragStartValue !== value) {
slider.fireEvent('changecomplete', slider, value, me);
}
},
destroy: function() {
var me = this,
anim = this.anim;
if (anim) {
anim.end();
}
me.el = me.tracker = me.anim = Ext.destroy(me.el, me.tracker);
}
});
Ext.define('Ext.slider.Tip', {
extend: 'Ext.tip.Tip',
minWidth: 10,
alias: 'widget.slidertip',
offsets: null,
align: null,
position: '',
defaultVerticalPosition: 'left',
defaultHorizontalPosition: 'top',
isSliderTip: true,
init: function(slider) {
var me = this,
align, offsets;
if (!me.position) {
me.position = slider.vertical ? me.defaultVerticalPosition : me.defaultHorizontalPosition;
}
switch (me.position) {
case 'top':
offsets = [
0,
-10
];
align = 'b-t?';
break;
case 'bottom':
offsets = [
0,
10
];
align = 't-b?';
break;
case 'left':
offsets = [
-10,
0
];
align = 'r-l?';
break;
case 'right':
offsets = [
10,
0
];
align = 'l-r?';
}
if (!me.align) {
me.align = align;
}
if (!me.offsets) {
me.offsets = offsets;
}
slider.on({
scope: me,
dragstart: me.onSlide,
drag: me.onSlide,
dragend: me.hide,
destroy: me.destroy
});
},
onSlide: function(slider, e, thumb) {
var me = this;
me.show();
me.update(me.getText(thumb));
me.el.alignTo(thumb.el, me.align, me.offsets);
},
getText: function(thumb) {
return String(thumb.value);
}
});
Ext.define('Ext.slider.Multi', {
extend: 'Ext.form.field.Base',
alias: 'widget.multislider',
alternateClassName: 'Ext.slider.MultiSlider',
requires: [
'Ext.slider.Thumb',
'Ext.slider.Tip',
'Ext.Number',
'Ext.util.Format',
'Ext.Template'
],
focusable: true,
needArrowKeys: true,
tabIndex: 0,
focusCls: 'slider-focus',
childEls: [
'endEl',
'innerEl'
],
fieldSubTpl: [
'<div id="{id}" role="{role}" {inputAttrTpl} class="' + Ext.baseCSSPrefix + 'slider {fieldCls} {vertical}',
'{childElCls}"',
'<tpl if="tabIdx != null"> tabindex="{tabIdx}"</tpl>',
'<tpl if="isVertical"> aria-orientation="vertical"<tpl else> aria-orientation="horizontal"</tpl>',
'>',
'<div id="{cmpId}-endEl" data-ref="endEl" class="' + Ext.baseCSSPrefix + 'slider-end" role="presentation">',
'<div id="{cmpId}-innerEl" data-ref="innerEl" class="' + Ext.baseCSSPrefix + 'slider-inner" role="presentation">',
'{%this.renderThumbs(out, values)%}',
'</div>',
'</div>',
'</div>',
{
renderThumbs: function(out, values) {
var me = values.$comp,
i = 0,
thumbs = me.thumbs,
len = thumbs.length,
thumb, thumbConfig;
for (; i < len; i++) {
thumb = thumbs[i];
thumbConfig = thumb.getElConfig();
thumbConfig.id = me.id + '-thumb-' + i;
Ext.DomHelper.generateMarkup(thumbConfig, out);
}
},
disableFormats: true
}
],
horizontalProp: 'left',
vertical: false,
minValue: 0,
maxValue: 100,
decimalPrecision: 0,
keyIncrement: 1,
increment: 0,
clickRange: [
5,
15
],
clickToChange: true,
animate: true,
dragging: false,
constrainThumbs: true,
useTips: true,
tipText: null,
ariaRole: 'slider',
defaultBindProperty: 'values',
initValue: function() {
var me = this,
extValueFrom = Ext.valueFrom,
values = extValueFrom(me.values, [
extValueFrom(me.value, extValueFrom(me.minValue, 0))
]),
i = 0,
len = values.length;
me.originalValue = values;
for (; i < len; i++) {
me.addThumb(me.normalizeValue(values[i]));
}
},
initComponent: function() {
var me = this,
tipPlug, hasTip, p, pLen, plugins;
me.thumbs = [];
me.keyIncrement = Math.max(me.increment, me.keyIncrement);
me.extraFieldBodyCls = Ext.baseCSSPrefix + 'slider-ct-' + (me.vertical ? 'vert' : 'horz');
me.callParent();
if (me.useTips) {
if (Ext.isObject(me.useTips)) {
tipPlug = Ext.apply({}, me.useTips);
} else {
tipPlug = me.tipText ? {
getText: me.tipText
} : {};
}
plugins = me.plugins = me.plugins || [];
pLen = plugins.length;
for (p = 0; p < pLen; p++) {
if (plugins[p].isSliderTip) {
hasTip = true;
break;
}
}
if (!hasTip) {
me.plugins.push(new Ext.slider.Tip(tipPlug));
}
}
},
addThumb: function(value) {
var me = this,
thumb = new Ext.slider.Thumb({
ownerCt: me,
value: value,
slider: me,
index: me.thumbs.length,
constrain: me.constrainThumbs,
disabled: !!me.readOnly
});
me.thumbs.push(thumb);
if (me.rendered) {
thumb.render();
}
return thumb;
},
promoteThumb: function(topThumb) {
var thumbs = this.thumbStack || (this.thumbStack = Ext.Array.slice(this.thumbs)),
ln = thumbs.length,
zIndex = 10000,
i;
if (thumbs[0] !== topThumb) {
Ext.Array.remove(thumbs, topThumb);
thumbs.unshift(topThumb);
}
for (i = 0; i < ln; i++) {
thumbs[i].el.setStyle('zIndex', zIndex);
zIndex -= 1000;
}
},
getSubTplData: function(fieldData) {
var me = this;
return Ext.apply(me.callParent(arguments), {
$comp: me,
isVertical: me.vertical,
vertical: me.vertical ? Ext.baseCSSPrefix + 'slider-vert' : Ext.baseCSSPrefix + 'slider-horz',
minValue: me.minValue,
maxValue: me.maxValue,
value: me.value,
tabIdx: me.tabIndex,
childElCls: ''
});
},
onRender: function() {
var me = this,
thumbs = me.thumbs,
len = thumbs.length,
i = 0,
thumb;
me.callParent(arguments);
for (i = 0; i < len; i++) {
thumb = thumbs[i];
thumb.el = me.el.getById(me.id + '-thumb-' + i);
thumb.onRender();
}
},
initEvents: function() {
var me = this;
me.callParent();
me.mon(me.el, {
scope: me,
mousedown: me.onMouseDown,
keydown: me.onKeyDown
});
},
onDragStart: Ext.emptyFn,
onDragEnd: Ext.emptyFn,
getTrackpoint: function(xy) {
var me = this,
vertical = me.vertical,
sliderTrack = me.innerEl,
trackLength, result, positionProperty;
if (vertical) {
positionProperty = 'top';
trackLength = sliderTrack.getHeight();
} else {
positionProperty = me.horizontalProp;
trackLength = sliderTrack.getWidth();
}
xy = me.transformTrackPoints(sliderTrack.translatePoints(xy));
result = Ext.Number.constrain(xy[positionProperty], 0, trackLength);
return vertical ? trackLength - result : result;
},
transformTrackPoints: Ext.identityFn,
checkChange: Ext.emptyFn,
onMouseDown: function(e) {
var me = this,
thumbClicked = false,
i = 0,
thumbs = me.thumbs,
len = thumbs.length,
trackPoint;
if (me.disabled) {
return;
}
for (; !thumbClicked && i < len; i++) {
thumbClicked = thumbClicked || e.target === thumbs[i].el.dom;
}
if (me.clickToChange && !thumbClicked) {
trackPoint = me.getTrackpoint(e.getXY());
if (trackPoint !== undefined) {
me.onClickChange(trackPoint);
}
}
me.focus();
},
onClickChange: function(trackPoint) {
var me = this,
thumb, index;
thumb = me.getNearest(trackPoint);
if (!thumb.disabled) {
index = thumb.index;
me.setValue(index, Ext.util.Format.round(me.reversePixelValue(trackPoint), me.decimalPrecision), undefined, true);
}
},
getNearest: function(trackPoint) {
var me = this,
clickValue = me.reversePixelValue(trackPoint),
nearestDistance = me.getRange() + 5,
nearest = null,
thumbs = me.thumbs,
i = 0,
len = thumbs.length,
thumb, value, dist;
for (; i < len; i++) {
thumb = me.thumbs[i];
value = thumb.value;
dist = Math.abs(value - clickValue);
if (Math.abs(dist) <= nearestDistance) {
nearest = thumb;
nearestDistance = dist;
}
}
return nearest;
},
onKeyDown: function(e) {
var me = this,
k, val;
if (me.disabled || me.thumbs.length !== 1) {
e.preventDefault();
return;
}
k = e.getKey();
switch (k) {
case e.UP:
case e.RIGHT:
e.stopEvent();
val = e.ctrlKey ? me.maxValue : me.getValue(0) + me.keyIncrement;
me.setValue(0, val, undefined, true);
break;
case e.DOWN:
case e.LEFT:
e.stopEvent();
val = e.ctrlKey ? me.minValue : me.getValue(0) - me.keyIncrement;
me.setValue(0, val, undefined, true);
break;
}
},
normalizeValue: function(v) {
var me = this,
snapFn = me.zeroBasedSnapping ? 'snap' : 'snapInRange';
v = Ext.Number[snapFn](v, me.increment, me.minValue, me.maxValue);
v = Ext.util.Format.round(v, me.decimalPrecision);
v = Ext.Number.constrain(v, me.minValue, me.maxValue);
return v;
},
setMinValue: function(val) {
var me = this,
thumbs = me.thumbs,
len = thumbs.length,
thumb, i;
me.minValue = val;
for (i = 0; i < len; ++i) {
thumb = thumbs[i];
if (thumb.value < val) {
me.setValue(i, val, false);
}
}
me.syncThumbs();
},
setMaxValue: function(val) {
var me = this,
thumbs = me.thumbs,
len = thumbs.length,
thumb, i;
me.maxValue = val;
for (i = 0; i < len; ++i) {
thumb = thumbs[i];
if (thumb.value > val) {
me.setValue(i, val, false);
}
}
me.syncThumbs();
},
setValue: function(index, value, animate, changeComplete) {
var me = this,
thumbs = me.thumbs,
thumb, len, i, values;
if (Ext.isArray(index)) {
values = index;
animate = value;
for (i = 0 , len = values.length; i < len; ++i) {
thumb = thumbs[i];
if (thumb) {
me.setValue(i, values[i], animate);
}
}
return me;
}
thumb = me.thumbs[index];
value = me.normalizeValue(value);
if (value !== thumb.value && me.fireEvent('beforechange', me, value, thumb.value, thumb) !== false) {
thumb.value = value;
if (me.rendered) {
if (Ext.isDefined(animate)) {
animate = animate === false ? false : animate;
} else {
animate = me.animate;
}
thumb.move(me.calculateThumbPosition(value), animate);
me.fireEvent('change', me, value, thumb);
me.checkDirty();
if (changeComplete) {
me.fireEvent('changecomplete', me, value, thumb);
}
}
}
return me;
},
calculateThumbPosition: function(v) {
var me = this,
minValue = me.minValue,
pos = (v - minValue) / me.getRange() * 100;
if (isNaN(pos)) {
pos = 0;
}
return pos;
},
getRatio: function() {
var me = this,
innerEl = me.innerEl,
trackLength = me.vertical ? innerEl.getHeight() : innerEl.getWidth(),
valueRange = me.getRange();
return valueRange === 0 ? trackLength : (trackLength / valueRange);
},
getRange: function() {
return this.maxValue - this.minValue;
},
reversePixelValue: function(pos) {
return this.minValue + (pos / this.getRatio());
},
reversePercentageValue: function(pos) {
return this.minValue + this.getRange() * (pos / 100);
},
onDisable: function() {
var me = this,
i = 0,
thumbs = me.thumbs,
len = thumbs.length,
thumb, el, xy;
me.callParent();
for (; i < len; i++) {
thumb = thumbs[i];
el = thumb.el;
thumb.disable();
if (Ext.isIE) {
xy = el.getXY();
el.hide();
me.innerEl.addCls(me.disabledCls).dom.disabled = true;
if (!me.thumbHolder) {
me.thumbHolder = me.endEl.createChild({
role: 'presentation',
cls: Ext.baseCSSPrefix + 'slider-thumb ' + me.disabledCls
});
}
me.thumbHolder.show().setXY(xy);
}
}
},
onEnable: function() {
var me = this,
i = 0,
thumbs = me.thumbs,
len = thumbs.length,
thumb, el;
this.callParent();
for (; i < len; i++) {
thumb = thumbs[i];
el = thumb.el;
thumb.enable();
if (Ext.isIE) {
me.innerEl.removeCls(me.disabledCls).dom.disabled = false;
if (me.thumbHolder) {
me.thumbHolder.hide();
}
el.show();
me.syncThumbs();
}
}
},
syncThumbs: function() {
if (this.rendered) {
var thumbs = this.thumbs,
length = thumbs.length,
i = 0;
for (; i < length; i++) {
thumbs[i].move(this.calculateThumbPosition(thumbs[i].value));
}
}
},
getValue: function(index) {
return Ext.isNumber(index) ? this.thumbs[index].value : this.getValues();
},
getValues: function() {
var values = [],
i = 0,
thumbs = this.thumbs,
len = thumbs.length;
for (; i < len; i++) {
values.push(thumbs[i].value);
}
return values;
},
getSubmitValue: function() {
var me = this;
return (me.disabled || !me.submitValue) ? null : me.getValue();
},
reset: function() {
var me = this,
arr = [].concat(me.originalValue),
a = 0,
aLen = arr.length,
val;
for (; a < aLen; a++) {
val = arr[a];
me.setValue(a, val);
}
me.clearInvalid();
delete me.wasValid;
},
setReadOnly: function(readOnly) {
var me = this,
thumbs = me.thumbs,
len = thumbs.length,
i = 0;
me.callParent(arguments);
readOnly = me.readOnly;
for (; i < len; ++i) {
if (readOnly) {
thumbs[i].disable();
} else {
thumbs[i].enable();
}
}
},
beforeDestroy: function() {
var me = this,
thumbs = me.thumbs,
t = 0,
tLen = thumbs.length,
thumb;
if (me.rendered) {
for (; t < tLen; t++) {
thumb = thumbs[t];
Ext.destroy(thumb);
}
}
me.callParent();
}
});
Ext.define('Ext.slider.Single', {
extend: 'Ext.slider.Multi',
alias: [
'widget.slider',
'widget.sliderfield'
],
alternateClassName: [
'Ext.Slider',
'Ext.form.SliderField',
'Ext.slider.SingleSlider',
'Ext.slider.Slider'
],
defaultBindProperty: 'value',
initComponent: function() {
if (this.publishOnComplete) {
this.valuePublishEvent = 'changecomplete';
}
this.callParent();
},
publishOnComplete: true,
getValue: function() {
return this.callParent([
0
]);
},
setValue: function(value, animate) {
var args = arguments,
len = args.length;
if (len === 1 || (len <= 3 && typeof args[1] !== 'number')) {
args = Ext.toArray(args);
args.unshift(0);
}
return this.callParent(args);
},
getNearest: function() {
return this.thumbs[0];
}
});
Ext.define('Ext.slider.Widget', {
extend: 'Ext.Widget',
alias: 'widget.sliderwidget',
requires: [
'Ext.slider.Multi'
],
cachedConfig: {
vertical: false
},
config: {
clickToChange: true,
ui: 'widget',
value: 0,
minValue: 0,
maxValue: 100,
publishOnComplete: true,
twoWayBindable: {
value: 1
}
},
decimalPrecision: 0,
defaultBindProperty: 'value',
element: {
reference: 'element',
cls: Ext.baseCSSPrefix + 'slider',
listeners: {
mousedown: 'onMouseDown',
dragstart: 'cancelDrag',
drag: 'cancelDrag',
dragend: 'cancelDrag'
},
children: [
{
reference: 'endEl',
cls: Ext.baseCSSPrefix + 'slider-end',
children: [
{
reference: 'innerEl',
cls: Ext.baseCSSPrefix + 'slider-inner'
}
]
}
]
},
thumbCls: Ext.baseCSSPrefix + 'slider-thumb',
horizontalProp: 'left',
animateOnSetValue: undefined,
applyValue: function(value) {
var me = this,
animate = me.animateOnSetValue,
i, len;
if (Ext.isArray(value)) {
value = Ext.Array.from(value);
for (i = 0 , len = value.length; i < len; ++i) {
me.setThumbValue(i, value[i] = me.normalizeValue(value[i]), animate, true);
}
} else {
value = me.normalizeValue(value);
me.setThumbValue(0, value, animate, true);
}
return value;
},
updateVertical: function(vertical, oldVertical) {
this.element.removeCls(Ext.baseCSSPrefix + 'slider-' + (oldVertical ? 'vert' : 'horz'));
this.element.addCls(Ext.baseCSSPrefix + 'slider-' + (vertical ? 'vert' : 'horz'));
},
doSetHeight: function(height) {
this.callParent(arguments);
this.endEl.dom.style.height = this.innerEl.dom.style.height = '100%';
},
cancelDrag: function(e) {
e.stopPropagation();
},
getThumb: function(ordinal) {
var me = this,
thumbConfig,
result = (me.thumbs || (me.thumbs = []))[ordinal];
if (!result) {
thumbConfig = {
cls: me.thumbCls,
style: {}
};
thumbConfig['data-thumbIndex'] = ordinal;
result = me.thumbs[ordinal] = me.innerEl.createChild(thumbConfig);
}
return result;
},
getThumbPositionStyle: function() {
return this.getVertical() ? 'bottom' : (this.rtl && Ext.rtl ? 'right' : 'left');
},
update: function() {
var me = this,
values = me.getValue(),
len = values.length,
i;
for (i = 0; i < len; i++) {
this.thumbs[i].dom.style[me.getThumbPositionStyle()] = me.calculateThumbPosition(values[i]) + '%';
}
},
onMouseDown: function(e) {
var me = this,
thumb,
trackPoint = e.getXY(),
delta;
if (!me.disabled && e.button === 0) {
Ext.getDoc().on({
scope: me,
capture: true,
selectstart: me.stopSelect
});
thumb = e.getTarget('.' + me.thumbCls, null, true);
if (thumb) {
me.animateOnSetValue = false;
me.promoteThumb(thumb);
me.captureMouse(me.onMouseMove, me.onMouseUp, [
thumb
], 1);
delta = me.pointerOffset = thumb.getXY();
delta[0] += Math.floor(thumb.getWidth() / 2) - trackPoint[0];
delta[1] += Math.floor(thumb.getHeight() / 2) - trackPoint[1];
} else {
if (me.getClickToChange()) {
trackPoint = me.getTrackpoint(trackPoint);
if (trackPoint != null) {
me.onClickChange(trackPoint);
}
}
}
}
},
onClickChange: function(trackPoint) {
var me = this,
thumb, index, value;
thumb = me.getNearest(trackPoint);
index = parseInt(thumb.getAttribute('data-thumbIndex'), 10);
value = Ext.util.Format.round(me.reversePixelValue(trackPoint), me.decimalPrecision);
if (index) {
me.setThumbValue(index, value, undefined, true);
} else {
me.setValue(value);
}
},
getNearest: function(trackPoint) {
var me = this,
clickValue = me.reversePixelValue(trackPoint),
nearestDistance = me.getRange() + 5,
nearest = null,
thumbs = me.thumbs,
i = 0,
len = thumbs.length,
thumb, value, dist;
for (; i < len; i++) {
thumb = thumbs[i];
value = me.reversePercentageValue(parseInt(thumb.dom.style[me.getThumbPositionStyle()], 10));
dist = Math.abs(value - clickValue);
if (Math.abs(dist) <= nearestDistance) {
nearest = thumb;
nearestDistance = dist;
}
}
return nearest;
},
promoteThumb: function(topThumb) {
var thumbs = this.thumbStack || (this.thumbStack = Ext.Array.slice(this.thumbs)),
ln = thumbs.length,
zIndex = 10000,
i;
if (thumbs[0] !== topThumb) {
Ext.Array.remove(thumbs, topThumb);
thumbs.unshift(topThumb);
}
for (i = 0; i < ln; i++) {
thumbs[i].el.setStyle('zIndex', zIndex);
zIndex -= 1000;
}
},
doMouseMove: function(e, thumb, changeComplete) {
var me = this,
trackerXY = e.getXY(),
newValue, thumbIndex, trackPoint;
trackerXY[0] += me.pointerOffset[0];
trackerXY[1] += me.pointerOffset[1];
trackPoint = me.getTrackpoint(trackerXY);
if (trackPoint) {
newValue = me.reversePixelValue(trackPoint);
thumbIndex = parseInt(thumb.getAttribute('data-thumbIndex'), 10);
if (thumbIndex || (!changeComplete && me.getPublishOnComplete())) {
me.setThumbValue(thumbIndex, newValue, false, changeComplete);
} else {
me.setValue(newValue);
}
}
},
onMouseMove: function(e, thumb) {
this.doMouseMove(e, thumb, false);
},
onMouseUp: function(e, thumb) {
var me = this;
me.doMouseMove(e, thumb, true);
Ext.getDoc().un({
scope: me,
capture: true,
selectstart: me.stopSelect
});
delete me.animateOnSetValue;
},
stopSelect: function(e) {
e.stopEvent();
return false;
},
setThumbValue: function(index, value, animate, changeComplete) {
var me = this,
thumb, thumbValue, len, i, values;
if (Ext.isArray(index)) {
values = index;
animate = value;
for (i = 0 , len = values.length; i < len; ++i) {
me.setThumbValue(i, values[i], animate, changeComplete);
}
return me;
}
thumb = me.getThumb(index);
thumbValue = me.reversePercentageValue(parseInt(thumb.dom.style[me.getThumbPositionStyle()], 10));
value = me.normalizeValue(value);
if (value !== thumbValue && me.fireEvent('beforechange', me, value, thumbValue, thumb) !== false) {
if (me.element.dom) {
me.element.set({
'aria-valuenow': value,
'aria-valuetext': value
});
me.moveThumb(thumb, me.calculateThumbPosition(value), Ext.isDefined(animate) ? animate !== false : me.animate);
me.fireEvent('change', me, value, thumb);
}
}
return me;
},
getValue: function(index) {
var me = this,
value;
if (Ext.isNumber(index)) {
value = me.thumbs[index].dom.style[me.getThumbPositionStyle()];
value = me.reversePercentageValue(parseInt(value, 10));
} else {
value = me.getValues();
if (value.length === 1) {
value = value[0];
}
}
return value;
},
getValues: function() {
var me = this,
values = [],
i = 0,
thumbs = me.thumbs,
len = thumbs.length;
for (; i < len; i++) {
values.push(me.reversePercentageValue(parseInt(me.thumbs[i].dom.style[me.getThumbPositionStyle()], 10)));
}
return values;
},
moveThumb: function(thumb, v, animate) {
var me = this,
styleProp = me.getThumbPositionStyle(),
to, from;
v += '%';
if (!animate) {
thumb.dom.style[styleProp] = v;
} else {
to = {};
to[styleProp] = v;
if (!Ext.supports.GetPositionPercentage) {
from = {};
from[styleProp] = thumb.dom.style[styleProp];
}
new Ext.fx.Anim({
target: thumb,
duration: 350,
from: from,
to: to
});
}
},
normalizeValue: function(v) {
var me = this,
snapFn = me.zeroBasedSnapping ? 'snap' : 'snapInRange';
v = Ext.Number[snapFn](v, me.increment, me.minValue, me.maxValue);
v = Ext.util.Format.round(v, me.decimalPrecision);
v = Ext.Number.constrain(v, me.minValue, me.maxValue);
return v;
},
getTrackpoint: function(xy) {
var me = this,
vertical = me.getVertical(),
sliderTrack = me.innerEl,
trackLength, result, positionProperty;
if (vertical) {
positionProperty = 'top';
trackLength = sliderTrack.getHeight();
} else {
positionProperty = 'left';
trackLength = sliderTrack.getWidth();
}
xy = me.transformTrackPoints(sliderTrack.translatePoints(xy));
result = Ext.Number.constrain(xy[positionProperty], 0, trackLength);
return vertical ? trackLength - result : result;
},
transformTrackPoints: Ext.identityFn,
calculateThumbPosition: function(v) {
var me = this,
pos = (v - me.getMinValue()) / me.getRange() * 100;
if (isNaN(pos)) {
pos = 0;
}
return pos;
},
getRatio: function() {
var me = this,
innerEl = me.innerEl,
trackLength = me.getVertical() ? innerEl.getHeight() : innerEl.getWidth(),
valueRange = me.getRange();
return valueRange === 0 ? trackLength : (trackLength / valueRange);
},
getRange: function() {
return this.getMaxValue() - this.getMinValue();
},
reversePixelValue: function(pos) {
return this.getMinValue() + (pos / this.getRatio());
},
reversePercentageValue: function(pos) {
return this.getMinValue() + this.getRange() * (pos / 100);
},
captureMouse: function(onMouseMove, onMouseUp, args, appendArgs) {
var me = this,
onMouseupWrap, listeners;
onMouseMove = onMouseMove && Ext.Function.bind(onMouseMove, me, args, appendArgs);
onMouseUp = onMouseUp && Ext.Function.bind(onMouseUp, me, args, appendArgs);
onMouseupWrap = function() {
Ext.getDoc().un(listeners);
if (onMouseUp) {
onMouseUp.apply(me, arguments);
}
};
listeners = {
mousemove: onMouseMove,
mouseup: onMouseupWrap
};
Ext.getDoc().on(listeners);
}
});
Ext.define('Ext.sparkline.Shape', {
constructor: function(target, id, type, args) {
this.target = target;
this.id = id;
this.type = type;
this.args = args;
},
append: function() {
this.target.appendShape(this);
return this;
}
});
Ext.define('Ext.sparkline.CanvasBase', {
requires: [
'Ext.sparkline.Shape'
],
shapeCount: 0,
_pxregex: /(\d+)(px)?\s*$/i,
constructor: function(ownerSparkLine) {
this.owner = ownerSparkLine;
},
setWidth: function(width) {
this.pixelWidth = width;
},
setHeight: function(height) {
this.pixelHeight = height;
},
drawLine: function(x1, y1, x2, y2, lineColor, lineWidth) {
return this.drawShape([
[
x1,
y1
],
[
x2,
y2
]
], lineColor, lineWidth);
},
drawShape: function(path, lineColor, fillColor, lineWidth) {
return this._genShape('Shape', [
path,
lineColor,
fillColor,
lineWidth
]);
},
drawCircle: function(x, y, radius, lineColor, fillColor, lineWidth) {
return this._genShape('Circle', [
x,
y,
radius,
lineColor,
fillColor,
lineWidth
]);
},
drawPieSlice: function(x, y, radius, startAngle, endAngle, lineColor, fillColor) {
return this._genShape('PieSlice', [
x,
y,
radius,
startAngle,
endAngle,
lineColor,
fillColor
]);
},
drawRect: function(x, y, width, height, lineColor, fillColor) {
return this._genShape('Rect', [
x,
y,
width,
height,
lineColor,
fillColor
]);
},
getElement: function() {
return this.el;
},
getLastShapeId: function() {
return this.lastShapeId;
},
reset: function() {
Ext.Error.raise('reset not implemented');
},
_genShape: function(shapetype, shapeargs) {
var id = this.shapeCount++;
shapeargs.unshift(id);
return new Ext.sparkline.Shape(this, id, shapetype, shapeargs);
},
appendShape: function(shape) {
Ext.Error.raise('appendShape not implemented');
},
replaceWithShape: function(shapeid, shape) {
Ext.Error.raise('replaceWithShape not implemented');
},
insertAfterShape: function(shapeid, shape) {
Ext.Error.raise('insertAfterShape not implemented');
},
removeShapeId: function(shapeid) {
Ext.Error.raise('removeShapeId not implemented');
},
getShapeAt: function(x, y) {
Ext.Error.raise('getShapeAt not implemented');
},
render: function() {
Ext.Error.raise('render not implemented');
}
});
Ext.define('Ext.sparkline.CanvasCanvas', {
extend: 'Ext.sparkline.CanvasBase',
statics: {
contextOverrides: (function() {
var ratio = window.devicePixelRatio || 1;
return {
moveTo: function(x, y) {
this.$moveTo(x * ratio, y * ratio);
},
lineTo: function(x, y) {
this.$lineTo(x * ratio, y * ratio);
},
arc: function(x, y, radius, startAngle, endAngle, counterclockwise) {
this.$arc(x * ratio, y * ratio, radius * ratio, startAngle, endAngle, counterclockwise);
},
clearRect: function(x, y, width, height) {
this.$clearRect(x * ratio, y * ratio, width * ratio, height * ratio);
}
};
})()
},
setWidth: function(width) {
this.callParent(arguments);
this.owner.element.dom.width = width * (window.devicePixelRatio || 1);
},
setHeight: function(height) {
this.callParent(arguments);
this.owner.element.dom.height = height * (window.devicePixelRatio || 1);
},
onOwnerUpdate: function() {
var me = this;
me.el = me.owner.element;
me.interact = !me.owner.initialConfig.disableInteraction;
me.shapes = {};
me.shapeseq = [];
me.currentTargetShapeId = me.lastShapeId = null;
},
_getContext: function(lineColor, fillColor, lineWidth) {
var context = this.el.dom.getContext('2d'),
overrides = Ext.sparkline.CanvasCanvas.contextOverrides,
name;
if (!this.context) {
for (name in overrides) {
context['$' + name] = context[name];
}
Ext.apply(context, overrides);
this.context = context;
}
if (lineColor != null) {
context.strokeStyle = lineColor;
}
context.lineWidth = lineWidth || 1;
if (fillColor != null) {
context.fillStyle = fillColor;
}
return context;
},
reset: function() {
var context = this._getContext();
context.clearRect(0, 0, this.pixelWidth, this.pixelHeight);
this.shapes = {};
this.shapeseq = [];
this.currentTargetShapeId = this.lastShapeId = null;
},
_drawShape: function(shapeid, path, lineColor, fillColor, lineWidth) {
var context = this._getContext(lineColor, fillColor, lineWidth),
i, plen;
context.beginPath();
context.moveTo(path[0][0] + 0.5, path[0][1] + 0.5);
for (i = 1 , plen = path.length; i < plen; i++) {
context.lineTo(path[i][0] + 0.5, path[i][1] + 0.5);
}
if (lineColor != null) {
context.stroke();
}
if (fillColor != null) {
context.fill();
}
if (this.targetX != null && this.targetY != null && context.isPointInPath(this.targetX, this.targetY)) {
this.currentTargetShapeId = shapeid;
}
},
_drawCircle: function(shapeid, x, y, radius, lineColor, fillColor, lineWidth) {
var context = this._getContext(lineColor, fillColor, lineWidth);
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI, false);
if (this.targetX != null && this.targetY != null && context.isPointInPath(this.targetX, this.targetY)) {
this.currentTargetShapeId = shapeid;
}
if (lineColor !== undefined) {
context.stroke();
}
if (fillColor !== undefined) {
context.fill();
}
},
_drawPieSlice: function(shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) {
var context = this._getContext(lineColor, fillColor);
context.beginPath();
context.moveTo(x, y);
context.arc(x, y, radius, startAngle, endAngle, false);
context.lineTo(x, y);
context.closePath();
if (lineColor != null) {
context.stroke();
}
if (fillColor) {
context.fill();
}
if (this.targetX !== undefined && this.targetY !== undefined && context.isPointInPath(this.targetX, this.targetY)) {
this.currentTargetShapeId = shapeid;
}
},
_drawRect: function(shapeid, x, y, width, height, lineColor, fillColor) {
return this._drawShape(shapeid, [
[
x,
y
],
[
x + width,
y
],
[
x + width,
y + height
],
[
x,
y + height
],
[
x,
y
]
], lineColor, fillColor);
},
appendShape: function(shape) {
this.shapes[shape.id] = shape;
this.shapeseq.push(shape.id);
this.lastShapeId = shape.id;
return shape.id;
},
replaceWithShape: function(shapeid, shape) {
var shapeseq = this.shapeseq,
i;
this.shapes[shape.id] = shape;
for (i = shapeseq.length; i--; ) {
if (shapeseq[i] == shapeid) {
shapeseq[i] = shape.id;
}
}
delete this.shapes[shapeid];
},
replaceWithShapes: function(shapeids, shapes) {
var shapeseq = this.shapeseq,
shapemap = {},
sid, i, first;
for (i = shapeids.length; i--; ) {
shapemap[shapeids[i]] = true;
}
for (i = shapeseq.length; i--; ) {
sid = shapeseq[i];
if (shapemap[sid]) {
shapeseq.splice(i, 1);
delete this.shapes[sid];
first = i;
}
}
for (i = shapes.length; i--; ) {
shapeseq.splice(first, 0, shapes[i].id);
this.shapes[shapes[i].id] = shapes[i];
}
},
insertAfterShape: function(shapeid, shape) {
var shapeseq = this.shapeseq,
i;
for (i = shapeseq.length; i--; ) {
if (shapeseq[i] === shapeid) {
shapeseq.splice(i + 1, 0, shape.id);
this.shapes[shape.id] = shape;
return;
}
}
},
removeShapeId: function(shapeid) {
var shapeseq = this.shapeseq,
i;
for (i = shapeseq.length; i--; ) {
if (shapeseq[i] === shapeid) {
shapeseq.splice(i, 1);
break;
}
}
delete this.shapes[shapeid];
},
getShapeAt: function(x, y) {
this.targetX = x;
this.targetY = y;
this.render();
return this.currentTargetShapeId;
},
render: function() {
var shapeseq = this.shapeseq,
shapes = this.shapes,
shapeCount = shapeseq.length,
context = this._getContext(),
shapeid, shape, i;
context.clearRect(0, 0, this.pixelWidth, this.pixelHeight);
for (i = 0; i < shapeCount; i++) {
shapeid = shapeseq[i];
shape = shapes[shapeid];
this['_draw' + shape.type].apply(this, shape.args);
}
if (!this.interact) {
this.shapes = {};
this.shapeseq = [];
}
}
});
Ext.define('Ext.sparkline.VmlCanvas', {
extend: 'Ext.sparkline.CanvasBase',
setWidth: function(width) {
var me = this;
me.callParent(arguments);
me.owner.groupEl.dom.coordsize = me.width + ' ' + (me.height || 0);
me.owner.groupEl.dom.style.width = width + 'px';
},
setHeight: function(height) {
var me = this;
me.callParent(arguments);
me.owner.groupEl.dom.coordsize = (me.width || 0) + ' ' + me.height;
me.owner.groupEl.dom.style.height = height + 'px';
},
onOwnerUpdate: function() {
var me = this;
me.group = me.owner.groupEl;
me.el = me.owner.element;
me.prerender = [];
},
_drawShape: function(shapeid, path, lineColor, fillColor, lineWidth) {
var vpath = [],
initial, stroke, fill, closed, plen, i;
for (i = 0 , plen = path.length; i < plen; i++) {
vpath[i] = (path[i][0]) + ',' + (path[i][1]);
}
initial = vpath.splice(0, 1);
lineWidth = lineWidth == null ? 1 : lineWidth;
stroke = lineColor == null ? ' stroked="false" ' : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '" ';
fill = fillColor == null ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" ';
closed = vpath[0] === vpath[vpath.length - 1] ? 'x ' : '';
return [
'<svml:shape coordorigin="0 0" coordsize="',
this.pixelWidth,
' ',
this.pixelHeight,
'" id="jqsshape',
shapeid,
'" ',
stroke,
fill,
' style="position:absolute;height:',
this.pixelHeight,
'px;width:',
this.pixelWidth,
'px" ',
' path="m ',
initial,
' l ',
vpath.join(', '),
' ',
closed,
'e"></svml:shape>'
].join('');
},
_drawCircle: function(shapeid, x, y, radius, lineColor, fillColor, lineWidth) {
var circumference = radius * 2,
stroke, fill;
x -= radius;
y -= radius;
stroke = lineColor == null ? ' stroked="false" ' : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '" ';
fill = fillColor == null ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" ';
return [
'<svml:oval id="jqsshape',
shapeid,
'" ',
stroke,
fill,
' style="position:absolute;top:',
y,
'px; left:',
x,
'px;width:',
circumference,
'px;height:',
circumference,
'px"></svml:oval>'
].join('');
},
_drawPieSlice: function(shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) {
var vpath,
width = this.pixelWidth,
height = this.pixelHeight,
startx, starty, endx, endy,
stroke = lineColor == null ? ' stroked="false" ' : ' strokeWeight="1px" strokeColor="' + lineColor + '" ',
fill = fillColor == null ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" ';
if (startAngle === endAngle) {
return '';
}
if ((endAngle - startAngle) === (2 * Math.PI)) {
startAngle = 0;
endAngle = (2 * Math.PI);
}
startx = x + Math.round(Math.cos(startAngle) * radius);
starty = y + Math.round(Math.sin(startAngle) * radius);
endx = x + Math.round(Math.cos(endAngle) * radius);
endy = y + Math.round(Math.sin(endAngle) * radius);
if (startx === endx && starty === endy) {
if ((endAngle - startAngle) < Math.PI) {
return '';
}
startx = endx = x + radius;
starty = endy = y;
}
if (startx === endx && starty === endy && (endAngle - startAngle) < Math.PI) {
return '';
}
vpath = [
x - radius,
y - radius,
x + radius,
y + radius,
startx,
starty,
endx,
endy
];
return [
'<svml:shape coordorigin="0 0" coordsize="',
width,
' ',
height,
'" id="jqsshape',
shapeid,
'" ',
stroke,
fill,
' style="position:absolute;height:',
height,
'px;width:',
width,
'px" path="m ',
x,
',',
y,
' wa ',
vpath.join(', '),
' x e"></svml:shape>'
].join('');
},
_drawRect: function(shapeid, x, y, width, height, lineColor, fillColor) {
return this._drawShape(shapeid, [
[
x,
y
],
[
x,
y + height
],
[
x + width,
y + height
],
[
x + width,
y
],
[
x,
y
]
], lineColor, fillColor);
},
reset: function() {
Ext.fly(this.group).empty();
},
appendShape: function(shape) {
this.prerender.push(this['_draw' + shape.type].apply(this, shape.args));
this.lastShapeId = shape.id;
return shape.id;
},
replaceWithShape: function(shapeid, shape) {
var existing = this.el.getById('jqsshape' + shapeid, true),
vel = this['_draw' + shape.type].apply(this, shape.args);
existing.outerHTML = vel;
},
replaceWithShapes: function(shapeids, shapes) {
var existing = this.el.getById('jqsshape' + shapeids[0], true),
replace = '',
slen = shapes.length,
i;
for (i = 0; i < slen; i++) {
replace += this['_draw' + shapes[i].type].apply(this, shapes[i].args);
}
existing.outerHTML = replace;
for (i = 1; i < shapeids.length; i++) {
this.el.getById('jqsshape' + shapeids[i]).destroy();
}
},
insertAfterShape: function(shapeid, shape) {
var existing = this.el.getById('jqsshape' + shapeid, true),
vel = this['_draw' + shape.type].apply(this, shape.args);
existing.insertAdjacentHTML('afterEnd', vel);
},
removeShapeId: function(shapeid) {
var existing = this.el.getById('jqsshape' + shapeid, true);
this.group.removeChild(existing);
},
getShapeAt: function(x, y) {
var shapeid = this.el.id.substr(8);
return shapeid;
},
render: function() {
this.group.dom.innerHTML = this.prerender.join('');
}
}, function() {
Ext.onInternalReady(function() {
var doc = document;
if (doc.namespaces && !doc.namespaces.svml) {
doc.namespaces.add("svml", "urn:schemas-microsoft-com:vml", '#default#VML');
}
});
});
Ext.define('Ext.sparkline.Base', {
extend: 'Ext.Widget',
requires: [
'Ext.XTemplate',
'Ext.sparkline.CanvasCanvas',
'Ext.sparkline.VmlCanvas'
],
cachedConfig: {
baseCls: Ext.baseCSSPrefix + 'sparkline',
lineColor: '#157fcc',
fillColor: '#def',
defaultPixelsPerValue: 3,
tagValuesAttribute: 'values',
enableTagOptions: false,
enableHighlight: true,
highlightColor: null,
highlightLighten: 1.4,
tooltipSkipNull: true,
tooltipPrefix: '',
tooltipSuffix: '',
disableTooltips: false,
disableInteraction: false,
tipTpl: null
},
config: {
values: null
},
element: {
tag: 'canvas',
reference: 'element',
style: {
display: 'inline-block',
verticalAlign: 'top'
},
listeners: {
mouseenter: 'onMouseEnter',
mouseleave: 'onMouseLeave',
mousemove: 'onMouseMove'
},
width: 0,
height: 0
},
defaultBindProperty: 'values',
redrawQueue: {},
inheritableStatics: {
sparkLineTipClass: Ext.baseCSSPrefix + 'sparkline-tip-target',
onClassCreated: function(cls) {
var proto = cls.prototype,
configs = cls.getConfigurator().configs,
config;
for (config in configs) {
if (config !== 'tipTpl') {
proto[Ext.Config.get(config).names.apply] = proto.applyConfigChange;
}
}
}
},
constructor: function(config) {
var me = this;
me.canvas = Ext.supports.Canvas ? new Ext.sparkline.CanvasCanvas(me) : new Ext.sparkline.VmlCanvas(me);
if (!me.getDisableTooltips()) {
me.element.cls = Ext.sparkline.Base.sparkLineTipClass;
}
Ext.apply(me, config);
me.callParent([
config
]);
me.el = me.element;
},
all: function(val, arr, ignoreNull) {
var i;
for (i = arr.length; i--; ) {
if (ignoreNull && arr[i] === null) {
continue;
}
if (arr[i] !== val) {
return false;
}
}
return true;
},
applyConfigChange: function(newValue) {
var me = this;
me.redrawQueue[me.getId()] = me;
if (!me.redrawTimer) {
Ext.sparkline.Base.prototype.redrawTimer = Ext.Function.requestAnimationFrame(me.processRedrawQueue);
}
return newValue;
},
applyTipTpl: function(tipTpl) {
if (!tipTpl.isTemplate) {
tipTpl = new Ext.XTemplate(tipTpl);
}
return tipTpl;
},
normalizeValue: function(val) {
var nf;
switch (val) {
case 'undefined':
val = undefined;
break;
case 'null':
val = null;
break;
case 'true':
val = true;
break;
case 'false':
val = false;
break;
default:
nf = parseFloat(val);
if (val == nf) {
val = nf;
};
}
return val;
},
normalizeValues: function(vals) {
var i,
result = [];
for (i = vals.length; i--; ) {
result[i] = this.normalizeValue(vals[i]);
}
return result;
},
doSetWidth: function(width) {
var me = this,
dom = me.element.dom;
me.callParent(arguments);
me.canvas.setWidth(width);
me.width = width;
if (me.height == null) {
me.setHeight(parseInt(me.measurer.getCachedStyle(dom.parentNode, 'line-height'), 10));
} else {
me.redrawQueue[me.getId()] = me;
}
},
doSetHeight: function(height) {
var me = this;
me.callParent(arguments);
me.canvas.setHeight(height);
me.height = height;
me.redrawQueue[me.getId()] = me;
},
updateValues: function(values) {
this.values = values;
},
redraw: function() {
var me = this,
tooltip;
if (me.getValues()) {
tooltip = me.tooltip;
if (tooltip && tooltip.isVisible() && me.currentPageXY && me.el.getRegion().contains(me.currentPageXY)) {
me.tooltip.triggerElement = me.el.dom;
}
me.onUpdate();
me.canvas.onOwnerUpdate();
me.renderGraph();
}
},
onUpdate: Ext.emptyFn,
renderGraph: function() {
var ret = true;
if (this.disabled) {
this.canvas.reset();
ret = false;
}
return ret;
},
onMouseEnter: function(e) {
this.onMouseMove(e);
},
onMouseMove: function(e) {
this.currentPageXY = e.getPoint();
this.redraw();
},
onMouseLeave: function() {
var me = this;
me.currentPageXY = me.targetX = me.targetY = null;
me.redraw();
},
updateDisplay: function() {
var me = this,
offset, tooltip, tooltipHTML, region;
if (me.currentPageXY && me.el.getRegion().contains(me.currentPageXY)) {
offset = me.canvas.el.getXY();
region = me.getRegion(me.currentPageXY[0] - offset[0], me.currentPageXY[1] - offset[1]);
if (region != null && !me.disableHighlight) {
me.renderHighlight(region);
}
me.fireEvent('sparklineregionchange', me);
tooltip = me.tooltip;
if (region != null && tooltip) {
tooltipHTML = me.getRegionTooltip(region);
if (tooltipHTML) {
if (!me.lastTooltipHTML || tooltipHTML[0] !== me.lastTooltipHTML[0] || tooltipHTML[1] !== me.lastTooltipHTML[1]) {
tooltip.setTitle(tooltipHTML[0]);
tooltip.update(tooltipHTML[1]);
me.lastTooltipHTML = tooltipHTML;
}
} else {
tooltip.hide();
}
}
}
},
getRegion: Ext.emptyFn,
getRegionTooltip: function(region) {
var me = this,
header = me.tooltipChartTitle,
entries = [],
tipTpl = me.getTipTpl(),
fields, showFields, showFieldsKey, newFields, fv, formatter, fieldlen, i, j;
fields = me.getRegionFields(region);
formatter = me.tooltipFormatter;
if (formatter) {
return formatter(me, me, fields);
}
if (!tipTpl) {
return '';
}
if (!Ext.isArray(fields)) {
fields = [
fields
];
}
showFields = me.tooltipFormatFieldlist;
showFieldsKey = me.tooltipFormatFieldlistKey;
if (showFields && showFieldsKey) {
newFields = [];
for (i = fields.length; i--; ) {
fv = fields[i][showFieldsKey];
if ((j = Ext.Array.indexOf(fv, showFields)) !== -1) {
newFields[j] = fields[i];
}
}
fields = newFields;
}
fieldlen = fields.length;
for (j = 0; j < fieldlen; j++) {
if (!fields[j].isNull || !me.getTooltipSkipNull()) {
Ext.apply(fields[j], {
prefix: me.getTooltipPrefix(),
suffix: me.getTooltipSuffix()
});
entries.push(tipTpl.apply(fields[j]));
}
}
if (header || entries.length) {
return [
header,
entries.join('<br>')
];
}
return '';
},
getRegionFields: Ext.emptyFn,
calcHighlightColor: function(color) {
var me = this,
highlightColor = me.getHighlightColor(),
lighten = me.getHighlightLighten(),
parse, mult, rgbnew, i;
if (highlightColor) {
return highlightColor;
}
if (lighten) {
parse = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(color) || /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(color);
if (parse) {
rgbnew = [];
mult = color.length === 4 ? 16 : 1;
for (i = 0; i < 3; i++) {
rgbnew[i] = Ext.Number.constrain(Math.round(parseInt(parse[i + 1], 16) * mult * lighten), 0, 255);
}
return 'rgb(' + rgbnew.join(',') + ')';
}
}
return color;
},
destroy: function() {
delete this.redrawQueue[this.getId()];
this.callParent();
}
}, function(SparklineBase) {
var proto = SparklineBase.prototype;
Ext.onInternalReady(function() {
proto.tooltip = new Ext.tip.ToolTip({
id: 'sparklines-tooltip',
target: document.body,
delegate: '.' + SparklineBase.sparkLineTipClass,
showDelay: 0,
dismissDelay: 0,
hideDelay: 400
});
});
SparklineBase.onClassCreated(SparklineBase);
proto.processRedrawQueue = function() {
var redrawQueue = proto.redrawQueue,
id;
for (id in redrawQueue) {
redrawQueue[id].redraw();
}
proto.redrawQueue = {};
proto.redrawTimer = 0;
};
if (!Ext.supports.Canvas) {
SparklineBase.prototype.element = {
tag: 'span',
reference: 'element',
listeners: {
mouseenter: 'onMouseEnter',
mouseleave: 'onMouseLeave',
mousemove: 'onMouseMove'
},
style: {
display: 'inline-block',
position: 'relative',
overflow: 'hidden',
margin: '0px',
padding: '0px',
verticalAlign: 'top',
cursor: 'default'
},
children: [
{
tag: 'svml:group',
reference: 'groupEl',
coordorigin: '0 0',
coordsize: '0 0',
style: 'position:absolute;width:0;height:0;pointer-events:none'
}
]
};
}
});
Ext.define('Ext.sparkline.BarBase', {
extend: 'Ext.sparkline.Base',
renderHighlight: function(region) {
this.renderRegion(region, true);
},
renderGraph: function() {
var me = this,
values = me.values,
canvas = me.canvas,
regionShapes = me.regionShapes || (me.regionShapes = {}),
shapes, ids, i, j;
if (!me.callParent()) {
return;
}
for (i = values.length; i--; ) {
shapes = me.renderRegion(i);
if (shapes) {
if (Ext.isArray(shapes)) {
ids = [];
for (j = shapes.length; j--; ) {
shapes[j].append();
ids.push(shapes[j].id);
}
regionShapes[i] = ids;
} else {
shapes.append();
regionShapes[i] = shapes.id;
}
} else
{
regionShapes[i] = null;
}
}
if (me.currentPageXY) {
me.currentRegion = null;
me.updateDisplay();
}
canvas.render();
}
});
Ext.define('Ext.sparkline.RangeMap', {
constructor: function(map) {
var key, range,
rangelist = [];
for (key in map) {
if (map.hasOwnProperty(key) && typeof key === 'string' && key.indexOf(':') > -1) {
range = key.split(':');
range[0] = range[0].length === 0 ? -Infinity : parseFloat(range[0]);
range[1] = range[1].length === 0 ? Infinity : parseFloat(range[1]);
range[2] = map[key];
rangelist.push(range);
}
}
this.map = map;
this.rangelist = rangelist || false;
},
get: function(value) {
var rangelist = this.rangelist,
i, range, result;
if ((result = this.map[value]) !== undefined) {
return result;
}
if (rangelist) {
for (i = rangelist.length; i--; ) {
range = rangelist[i];
if (range[0] <= value && range[1] >= value) {
return range[2];
}
}
}
}
});
Ext.define('Ext.sparkline.Bar', {
extend: 'Ext.sparkline.BarBase',
requires: [
'Ext.sparkline.RangeMap'
],
alias: 'widget.sparklinebar',
config: {
barColor: '#3366cc',
negBarColor: '#f44',
stackedBarColor: [
'#3366cc',
'#dc3912',
'#ff9900',
'#109618',
'#66aa00',
'#dd4477',
'#0099c6',
'#990099'
],
zeroColor: null,
nullColor: null,
zeroAxis: true,
barWidth: 4,
barSpacing: 1,
chartRangeMin: null,
chartRangeMax: null,
chartRangeClip: false,
colorMap: null,
tipTpl: new Ext.XTemplate('&#9679; {prefix}{value}{suffix}')
},
remove: function(vals, filter) {
var i, vl,
result = [];
for (i = 0 , vl = vals.length; i < vl; i++) {
if (vals[i] !== filter) {
result.push(vals[i]);
}
}
return result;
},
all: function(arr, val, ignoreNull) {
var i;
for (i = arr.length; i--; ) {
if (ignoreNull && arr[i] === null) {
continue;
}
if (arr[i] !== val) {
return false;
}
}
return true;
},
applyColorMap: function(colorMap) {
var me = this;
if (Ext.isArray(colorMap)) {
me.colorMapByIndex = colorMap;
me.colorMapByValue = null;
} else {
me.colorMapByIndex = null;
me.colorMapByValue = colorMap;
if (me.colorMapByValue && me.colorMapByValue.get == null) {
me.colorMapByValue = new Ext.sparkline.RangeMap(colorMap);
}
}
return colorMap;
},
onUpdate: function() {
var me = this,
values = me.values,
barWidth = me.getBarWidth(),
barSpacing = me.getBarSpacing(),
chartRangeMin = me.getChartRangeMin(),
chartRangeMax = me.getChartRangeMax(),
chartRangeClip = me.getChartRangeClip(),
stackMin = Infinity,
stackMax = -Infinity,
isStackString, groupMin, groupMax, stackRanges, numValues, i, vlen, range,
zeroAxis = me.getZeroAxis(),
xAxisOffset, min, max, clipMin, clipMax, stacked, vlist, j, slen, svals, val, yoffset, yMaxCalc,
stackTotals = [],
stackRangesNeg = [];
for (i = 0 , vlen = values.length; i < vlen; i++) {
val = values[i];
isStackString = typeof (val) === 'string' && val.indexOf(':') > -1;
if (isStackString || Ext.isArray(val)) {
stacked = true;
if (isStackString) {
val = values[i] = me.normalizeValues(val.split(':'));
}
val = me.remove(val, null);
groupMin = Math.min.apply(Math, val);
groupMax = Math.max.apply(Math, val);
if (groupMin < stackMin) {
stackMin = groupMin;
}
if (groupMax > stackMax) {
stackMax = groupMax;
}
}
}
me.stacked = stacked;
me.regionShapes = {};
me.totalBarWidth = barWidth + barSpacing;
me.width = (values.length * barWidth) + ((values.length - 1) * barSpacing);
if (chartRangeClip) {
clipMin = chartRangeMin == null ? -Infinity : chartRangeMin;
clipMax = chartRangeMax == null ? Infinity : chartRangeMax;
}
numValues = [];
stackRanges = stacked ? [] : numValues;
for (i = 0 , vlen = values.length; i < vlen; i++) {
if (stacked) {
vlist = values[i];
values[i] = svals = [];
stackTotals[i] = 0;
stackRanges[i] = stackRangesNeg[i] = 0;
for (j = 0 , slen = vlist.length; j < slen; j++) {
val = svals[j] = chartRangeClip ? Ext.Number.constrain(vlist[j], clipMin, clipMax) : vlist[j];
if (val !== null) {
if (val > 0) {
stackTotals[i] += val;
}
if (stackMin < 0 && stackMax > 0) {
if (val < 0) {
stackRangesNeg[i] += Math.abs(val);
} else {
stackRanges[i] += val;
}
} else {
stackRanges[i] += Math.abs(val - (val < 0 ? stackMax : stackMin));
}
numValues.push(val);
}
}
} else {
val = chartRangeClip ? Ext.Number.constrain(values[i], clipMin, clipMax) : values[i];
val = values[i] = me.normalizeValue(val);
if (val !== null) {
numValues.push(val);
}
}
}
me.max = max = Math.max.apply(Math, numValues);
me.min = min = Math.min.apply(Math, numValues);
me.stackMax = stackMax = stacked ? Math.max.apply(Math, stackTotals) : max;
me.stackMin = stackMin = stacked ? Math.min.apply(Math, numValues) : min;
if (chartRangeMin != null && (chartRangeClip || chartRangeMin < min)) {
min = chartRangeMin;
}
if (chartRangeMax != null && (chartRangeClip || chartRangeMax > max)) {
max = chartRangeMax;
}
if (min <= 0 && max >= 0 && zeroAxis) {
xAxisOffset = 0;
} else if (!zeroAxis) {
xAxisOffset = min;
} else if (min > 0) {
xAxisOffset = min;
} else {
xAxisOffset = max;
}
me.xAxisOffset = xAxisOffset;
range = stacked ? (Math.max.apply(Math, stackRanges) + Math.max.apply(Math, stackRangesNeg)) : max - min;
me.canvasHeightEf = (zeroAxis && min < 0) ? me.getHeight() - 2 : me.getHeight() - 1;
if (min < xAxisOffset) {
yMaxCalc = (stacked && max >= 0) ? stackMax : max;
yoffset = (yMaxCalc - xAxisOffset) / range * me.getHeight();
if (yoffset !== Math.ceil(yoffset)) {
me.canvasHeightEf -= 2;
yoffset = Math.ceil(yoffset);
}
} else {
yoffset = me.getHeight();
}
me.yoffset = yoffset;
me.range = range;
},
getRegion: function(x, y) {
var result = Math.floor(x / this.totalBarWidth);
return (result < 0 || result >= this.values.length) ? undefined : result;
},
getRegionFields: function(region) {
var values = Ext.Array.from(this.values[region]),
result = [],
value, i;
for (i = values.length; i--; ) {
value = values[i];
result.push({
isNull: value === null,
value: value,
color: this.calcColor(i, value, region),
offset: region
});
}
return result;
},
calcColor: function(stacknum, value, valuenum) {
var me = this,
colorMapByIndex = me.colorMapByIndex,
colorMapByValue = me.colorMapByValue,
color, newColor,
zeroColor = me.getZeroColor();
if (this.stacked) {
color = me.getStackedBarColor();
} else {
color = (value < 0) ? me.getNegBarColor() : me.getBarColor();
}
if (value === 0 && zeroColor !== undefined) {
color = zeroColor;
}
if (colorMapByValue && (newColor = colorMapByValue.get(value))) {
color = newColor;
} else if (colorMapByIndex && colorMapByIndex.length > valuenum) {
color = colorMapByIndex[valuenum];
}
return Ext.isArray(color) ? color[stacknum % color.length] : color;
},
renderRegion: function(valuenum, highlight) {
var me = this,
vals = me.values[valuenum],
xaxisOffset = me.xAxisOffset,
range = me.range,
stacked = me.stacked,
canvas = me.canvas,
barWidth = me.getBarWidth(),
x = valuenum * me.totalBarWidth,
canvasHeightEf = me.canvasHeightEf,
yoffset = me.yoffset,
y, height, color, isNull, yoffsetNeg, i, valcount, val, minPlotted, allMin,
nullColor = me.getNullColor();
vals = Ext.isArray(vals) ? vals : [
vals
];
valcount = vals.length;
val = vals[0];
isNull = me.all(vals, null);
allMin = me.all(vals, xaxisOffset, true);
if (isNull) {
if (nullColor) {
color = highlight ? nullColor : me.calcHighlightColor(nullColor, me);
y = (yoffset > 0) ? yoffset - 1 : yoffset;
canvas.drawRect(x, y, barWidth - 1, 0, color, color).append();
}
return;
}
yoffsetNeg = yoffset;
for (i = 0; i < valcount; i++) {
val = vals[i];
if (stacked && val === xaxisOffset) {
if (!allMin || minPlotted) {
continue;
}
minPlotted = true;
}
if (range > 0) {
height = Math.floor(canvasHeightEf * ((Math.abs(val - xaxisOffset) / range))) + 1;
} else {
height = 1;
}
if (val < xaxisOffset || (val === xaxisOffset && yoffset === 0)) {
y = yoffsetNeg;
yoffsetNeg += height;
} else {
y = yoffset - height;
yoffset -= height;
}
color = me.calcColor(i, val, valuenum);
if (highlight) {
color = me.calcHighlightColor(color, me);
}
canvas.drawRect(x, y, barWidth - 1, height - 1, color, color).append();
}
}
}, function(cls) {
cls.onClassCreated(cls);
});
Ext.define('Ext.sparkline.Box', {
extend: 'Ext.sparkline.Base',
alias: 'widget.sparklinebox',
config: {
raw: false,
boxLineColor: '#000',
boxFillColor: '#cdf',
whiskerColor: '#000',
outlierLineColor: '#333',
outlierFillColor: '#fff',
medianColor: '#f00',
showOutliers: true,
outlierIQR: 1.5,
spotRadius: 1.5,
target: null,
targetColor: '#4a2',
chartRangeMin: null,
chartRangeMax: null,
tipTpl: new Ext.XTemplate('{field:this.fields}: {value}', {
fields: function(v) {
var fields = {
lq: 'Lower Quartile',
med: 'Median',
uq: 'Upper Quartile',
lo: 'Left Outlier',
ro: 'Right Outlier',
lw: 'Left Whisker',
rw: 'Right Whisker'
};
return fields[v];
}
}),
tooltipFormatFieldlistKey: 'field'
},
quartile: function(values, q) {
var vl;
if (q === 2) {
vl = Math.floor(values.length / 2);
return values.length % 2 ? values[vl] : (values[vl - 1] + values[vl]) / 2;
} else {
if (values.length % 2) {
vl = (values.length * q + q) / 4;
return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl - 1];
} else {
vl = (values.length * q + 2) / 4;
return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl - 1];
}
}
},
applyValues: function(newValues) {
newValues = Ext.Array.map(Ext.Array.from(newValues), Number);
this.disabled = !(newValues && newValues.length);
return newValues;
},
getRegion: function() {
return 1;
},
getRegionFields: function() {
var result = [
{
field: 'lq',
value: this.quartiles[0]
},
{
field: 'med',
value: this.quartiles[1]
},
{
field: 'uq',
value: this.quartiles[2]
}
];
if (this.loutlier !== undefined) {
result.push({
field: 'lo',
value: this.loutlier
});
}
if (this.routlier !== undefined) {
result.push({
field: 'ro',
value: this.routlier
});
}
if (this.lwhisker !== undefined) {
result.push({
field: 'lw',
value: this.lwhisker
});
}
if (this.rwhisker !== undefined) {
result.push({
field: 'rw',
value: this.rwhisker
});
}
return result;
},
renderHighlight: Ext.emptyFn,
renderGraph: function() {
var me = this,
canvas = me.canvas,
values = me.values,
vlen = values.length,
canvasWidth = me.getWidth(),
canvasHeight = me.getHeight(),
chartRangeMin = me.getChartRangeMin(),
chartRangeMax = me.getChartRangeMax(),
minValue = chartRangeMin == null ? Math.min.apply(Math, values) : chartRangeMin,
maxValue = chartRangeMax == null ? Math.max.apply(Math, values) : chartRangeMax,
canvasLeft = 0,
lwhisker, loutlier, iqr, q1, q2, q3, rwhisker, routlier, i, size, unitSize,
spotRadius = me.getSpotRadius(),
outlierLineColor = me.getOutlierLineColor(),
outlierFillColor = me.getOutlierFillColor(),
showOutliers = me.getShowOutliers(),
outlierIQR = me.getOutlierIQR(),
lineColor = me.getLineColor(),
whiskerColor = me.getWhiskerColor(),
targetColor = me.getTargetColor();
if (!me.callParent()) {
return;
}
if (me.raw) {
if (showOutliers && values.length > 5) {
loutlier = values[0];
lwhisker = values[1];
q1 = values[2];
q2 = values[3];
q3 = values[4];
rwhisker = values[5];
routlier = values[6];
} else {
lwhisker = values[0];
q1 = values[1];
q2 = values[2];
q3 = values[3];
rwhisker = values[4];
}
} else {
values.sort(function(a, b) {
return a - b;
});
q1 = me.quartile(values, 1);
q2 = me.quartile(values, 2);
q3 = me.quartile(values, 3);
iqr = q3 - q1;
if (showOutliers) {
lwhisker = rwhisker = null;
for (i = 0; i < vlen; i++) {
if (lwhisker == null && values[i] > q1 - (iqr * outlierIQR)) {
lwhisker = values[i];
}
if (values[i] < q3 + (iqr * outlierIQR)) {
rwhisker = values[i];
}
}
loutlier = values[0];
routlier = values[vlen - 1];
} else {
lwhisker = values[0];
rwhisker = values[vlen - 1];
}
}
me.quartiles = [
q1,
q2,
q3
];
me.lwhisker = lwhisker;
me.rwhisker = rwhisker;
me.loutlier = loutlier;
me.routlier = routlier;
unitSize = canvasWidth / (maxValue - minValue + 1);
if (showOutliers) {
canvasLeft = Math.ceil(spotRadius);
canvasWidth -= 2 * Math.ceil(spotRadius);
unitSize = canvasWidth / (maxValue - minValue + 1);
if (loutlier < lwhisker) {
canvas.drawCircle((loutlier - minValue) * unitSize + canvasLeft, canvasHeight / 2, spotRadius, outlierLineColor, outlierFillColor).append();
}
if (routlier > rwhisker) {
canvas.drawCircle((routlier - minValue) * unitSize + canvasLeft, canvasHeight / 2, spotRadius, outlierLineColor, outlierFillColor).append();
}
}
canvas.drawRect(Math.round((q1 - minValue) * unitSize + canvasLeft), Math.round(canvasHeight * 0.1), Math.round((q3 - q1) * unitSize), Math.round(canvasHeight * 0.8), me.getBoxLineColor(), me.getBoxFillColor()).append();
canvas.drawLine(Math.round((lwhisker - minValue) * unitSize + canvasLeft), Math.round(canvasHeight / 2), Math.round((q1 - minValue) * unitSize + canvasLeft), Math.round(canvasHeight / 2), lineColor).append();
canvas.drawLine(Math.round((lwhisker - minValue) * unitSize + canvasLeft), Math.round(canvasHeight / 4), Math.round((lwhisker - minValue) * unitSize + canvasLeft), Math.round(canvasHeight - canvasHeight / 4), whiskerColor).append();
canvas.drawLine(Math.round((rwhisker - minValue) * unitSize + canvasLeft), Math.round(canvasHeight / 2), Math.round((q3 - minValue) * unitSize + canvasLeft), Math.round(canvasHeight / 2), lineColor).append();
canvas.drawLine(Math.round((rwhisker - minValue) * unitSize + canvasLeft), Math.round(canvasHeight / 4), Math.round((rwhisker - minValue) * unitSize + canvasLeft), Math.round(canvasHeight - canvasHeight / 4), whiskerColor).append();
canvas.drawLine(Math.round((q2 - minValue) * unitSize + canvasLeft), Math.round(canvasHeight * 0.1), Math.round((q2 - minValue) * unitSize + canvasLeft), Math.round(canvasHeight * 0.9), me.getMedianColor()).append();
if (me.target) {
size = Math.ceil(me.spotRadius);
canvas.drawLine(Math.round((me.target - minValue) * unitSize + canvasLeft), Math.round((canvasHeight / 2) - size), Math.round((me.target - minValue) * unitSize + canvasLeft), Math.round((canvasHeight / 2) + size), targetColor).append();
canvas.drawLine(Math.round((me.target - minValue) * unitSize + canvasLeft - size), Math.round(canvasHeight / 2), Math.round((me.target - minValue) * unitSize + canvasLeft + size), Math.round(canvasHeight / 2), targetColor).append();
}
if (me.currentPageXY && me.el.getRegion().contains(me.currentPageXY)) {
me.currentRegion = null;
me.updateDisplay();
}
canvas.render();
}
});
Ext.define('Ext.sparkline.Bullet', {
extend: 'Ext.sparkline.Base',
alias: 'widget.sparklinebullet',
config: {
targetColor: '#f33',
targetWidth: 3,
performanceColor: '#33f',
rangeColors: [
'#d3dafe',
'#a8b6ff',
'#7f94ff'
],
base: null,
tipTpl: new Ext.XTemplate('{fieldkey:this.fields} - {value}', {
fields: function(v) {
if (v === 'r') {
return 'Range';
}
if (v === 'p') {
return 'Performance';
}
if (v === 't') {
return 'Target';
}
}
})
},
applyValues: function(newValues) {
newValues = Ext.Array.map(Ext.Array.from(newValues), this.normalizeValue);
this.disabled = !(newValues && newValues.length);
return newValues;
},
onUpdate: function() {
var me = this,
values = me.values,
min, max, vals,
base = me.getBase();
me.callParent(arguments);
vals = values.slice();
vals[0] = vals[0] === null ? vals[2] : vals[0];
vals[1] = values[1] === null ? vals[2] : vals[1];
min = Math.min.apply(Math, values);
max = Math.max.apply(Math, values);
if (base == null) {
min = min < 0 ? min : 0;
} else {
min = base;
}
me.min = min;
me.max = max;
me.range = max - min;
me.shapes = {};
me.valueShapes = {};
me.regiondata = {};
if (!values.length) {
me.disabled = true;
}
},
getRegion: function(x, y) {
var shapeid = this.canvas.getShapeAt(x, y);
return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined;
},
getRegionFields: function(region) {
return {
fieldkey: region.substr(0, 1),
value: this.values[region.substr(1)],
region: region
};
},
renderHighlight: function(region) {
switch (region.substr(0, 1)) {
case 'r':
this.renderRange(region.substr(1), true).append();
break;
case 'p':
this.renderPerformance(true).append();
break;
case 't':
this.renderTarget(true).append();
break;
}
},
renderRange: function(region, highlight) {
var rangeval = this.values[region],
rangewidth = Math.round(this.getWidth() * ((rangeval - this.min) / this.range)),
color = this.getRangeColors()[region - 2];
if (highlight) {
color = this.calcHighlightColor(color);
}
return this.canvas.drawRect(0, 0, rangewidth - 1, this.getHeight() - 1, color, color);
},
renderPerformance: function(highlight) {
var perfval = this.values[1],
perfwidth = Math.round(this.getWidth() * ((perfval - this.min) / this.range)),
color = this.getPerformanceColor();
if (highlight) {
color = this.calcHighlightColor(color);
}
return this.canvas.drawRect(0, Math.round(this.getHeight() * 0.3), perfwidth - 1, Math.round(this.getHeight() * 0.4) - 1, color, color);
},
renderTarget: function(highlight) {
var targetval = this.values[0],
targetWidth = this.getTargetWidth(),
x = Math.round(this.getWidth() * ((targetval - this.min) / this.range) - (targetWidth / 2)),
targettop = Math.round(this.getHeight() * 0.1),
targetheight = this.getHeight() - (targettop * 2),
color = this.getTargetColor();
if (highlight) {
color = this.calcHighlightColor(color);
}
return this.canvas.drawRect(x, targettop, targetWidth - 1, targetheight - 1, color, color);
},
renderGraph: function() {
var me = this,
vlen = me.values.length,
canvas = me.canvas,
i, shape,
shapes = me.shapes || (me.shapes = {}),
valueShapes = me.valueShapes || (me.valueShapes = {});
if (!me.callParent()) {
return;
}
for (i = 2; i < vlen; i++) {
shape = me.renderRange(i).append();
shapes[shape.id] = 'r' + i;
valueShapes['r' + i] = shape.id;
}
if (me.values[1] !== null) {
shape = me.renderPerformance().append();
shapes[shape.id] = 'p1';
valueShapes.p1 = shape.id;
}
if (me.values[0] !== null) {
shape = this.renderTarget().append();
shapes[shape.id] = 't0';
valueShapes.t0 = shape.id;
}
if (me.currentPageXY && me.el.getRegion().contains(me.currentPageXY)) {
me.updateDisplay();
}
canvas.render();
}
});
Ext.define('Ext.sparkline.Discrete', {
extend: 'Ext.sparkline.BarBase',
alias: 'widget.sparklinediscrete',
config: {
lineHeight: 'auto',
thresholdColor: null,
thresholdValue: 0,
chartRangeMax: null,
chartRangeMin: null,
chartRangeClip: false,
tipTpl: new Ext.XTemplate('{prefix}{value}{suffix}')
},
applyValues: function(newValues) {
newValues = Ext.Array.map(Ext.Array.from(newValues), Number);
this.disabled = !(newValues && newValues.length);
return newValues;
},
onUpdate: function() {
var me = this,
values = me.values,
chartRangeMin = me.getChartRangeMin(),
chartRangeMax = me.getChartRangeMax(),
chartRangeClip = me.getChartRangeClip();
me.callParent(arguments);
me.regionShapes = {};
me.min = Math.min.apply(Math, values);
me.max = Math.max.apply(Math, values);
me.range = me.max - me.min;
me.width = me.getWidth();
me.interval = Math.floor(me.width / values.length);
me.itemWidth = me.width / values.length;
if (chartRangeMin != null && (chartRangeClip || chartRangeMin < me.min)) {
me.min = chartRangeMin;
}
if (chartRangeMax != null && (chartRangeClip || chartRangeMax > me.max)) {
me.max = chartRangeMax;
}
if (me.canvas) {
if (me.getLineHeight() === 'auto') {
me.setLineHeight(Math.round(me.getHeight() * 0.3));
}
}
},
getRegion: function(x, y) {
return Math.floor(x / this.itemWidth);
},
getRegionFields: function(region) {
return {
isNull: this.values[region] === undefined,
value: this.values[region],
offset: region
};
},
renderRegion: function(valuenum, highlight) {
var me = this,
values = me.values,
min = me.min,
max = me.max,
range = me.range,
interval = me.interval,
canvas = me.canvas,
canvasHeight = me.getHeight(),
lineHeight = me.getLineHeight(),
pheight = canvasHeight - lineHeight,
ytop, val, color, x,
thresholdColor = me.getThresholdColor();
val = Ext.Number.constrain(values[valuenum], min, max);
x = valuenum * interval;
ytop = Math.round(pheight - pheight * ((val - min) / range));
color = (thresholdColor && val < me.getThresholdValue()) ? thresholdColor : me.getLineColor();
if (highlight) {
color = me.calcHighlightColor(color);
}
canvas.drawLine(x, ytop, x, ytop + lineHeight, color).append();
}
});
Ext.define('Ext.sparkline.Line', {
extend: 'Ext.sparkline.Base',
requires: [
'Ext.sparkline.RangeMap'
],
alias: 'widget.sparklineline',
config: {
spotColor: '#f80',
highlightSpotColor: '#5f5',
highlightLineColor: '#f22',
spotRadius: 1.5,
minSpotColor: '#f80',
maxSpotColor: '#f80',
lineWidth: 1,
normalRangeMin: null,
normalRangeMax: null,
normalRangeColor: '#ccc',
drawNormalOnTop: false,
chartRangeMin: null,
chartRangeMax: null,
chartRangeMinX: null,
chartRangeMaxX: null,
tipTpl: new Ext.XTemplate('&#9679; {prefix}{y}{suffix}'),
valueSpots: null
},
applyValueSpots: function(valueSpots) {
if (valueSpots && !valueSpots.get) {
valueSpots = new Ext.sparkline.RangeMap(valueSpots);
}
return valueSpots;
},
onUpdate: function() {
this.vertices = [];
this.regionMap = [];
this.xvalues = [];
this.yvalues = [];
this.yminmax = [];
},
getRegion: function(x, y) {
var i,
regionMap = this.regionMap;
for (i = regionMap.length; i--; ) {
if (regionMap[i] !== null && x >= regionMap[i][0] && x <= regionMap[i][1]) {
return regionMap[i][2];
}
}
return undefined;
},
getRegionFields: function(region) {
return {
isNull: this.yvalues[region] === null,
x: this.xvalues[region],
y: this.yvalues[region],
color: this.getLineColor(),
fillColor: this.getFillColor(),
offset: region
};
},
renderHighlight: function(region) {
var me = this,
canvas = me.canvas,
vertex = me.vertices[region],
spotRadius = me.getSpotRadius(),
highlightSpotColor = me.getHighlightSpotColor(),
highlightLineColor = me.getHighlightLineColor();
if (!vertex) {
return;
}
if (spotRadius && highlightSpotColor) {
canvas.drawCircle(vertex[0], vertex[1], spotRadius, null, highlightSpotColor).append();
}
if (highlightLineColor) {
canvas.drawLine(vertex[0], me.canvasTop, vertex[0], me.canvasTop + me.getHeight(), highlightLineColor).append();
}
},
scanValues: function() {
var me = this,
values = me.values,
valcount = values.length,
xvalues = me.xvalues,
yvalues = me.yvalues,
yminmax = me.yminmax,
i, val, isStr, isArray, sp;
for (i = 0; i < valcount; i++) {
val = values[i];
isStr = typeof (values[i]) === 'string';
isArray = typeof (values[i]) === 'object' && values[i] instanceof Array;
sp = isStr && values[i].split(':');
if (isStr && sp.length === 2) {
xvalues.push(Number(sp[0]));
yvalues.push(Number(sp[1]));
yminmax.push(Number(sp[1]));
} else if (isArray) {
xvalues.push(val[0]);
yvalues.push(val[1]);
yminmax.push(val[1]);
} else {
xvalues.push(i);
if (values[i] === null || values[i] === 'null') {
yvalues.push(null);
} else {
yvalues.push(Number(val));
yminmax.push(Number(val));
}
}
}
if (me.xvalues) {
xvalues = me.xvalues;
}
me.maxy = me.maxyorg = Math.max.apply(Math, yminmax);
me.miny = me.minyorg = Math.min.apply(Math, yminmax);
me.maxx = Math.max.apply(Math, xvalues);
me.minx = Math.min.apply(Math, xvalues);
me.xvalues = xvalues;
me.yvalues = yvalues;
me.yminmax = yminmax;
},
processRangeOptions: function() {
var me = this,
normalRangeMin = me.getNormalRangeMin(),
normalRangeMax = me.getNormalRangeMax(),
chartRangeMin = me.getChartRangeMin(),
chartRangeMinX = me.getChartRangeMinX(),
chartRangeMax = me.getChartRangeMax(),
chartRangeMaxX = me.getChartRangeMaxX();
if (normalRangeMin != null) {
if (normalRangeMin < me.miny) {
me.miny = normalRangeMin;
}
if (normalRangeMax > me.maxy) {
me.maxy = normalRangeMax;
}
}
if (chartRangeMin != null && (me.chartRangeClip || chartRangeMin < me.miny)) {
me.miny = chartRangeMin;
}
if (chartRangeMax != null && (me.chartRangeClip || chartRangeMax > me.maxy)) {
this.maxy = chartRangeMax;
}
if (chartRangeMinX != null && (me.chartRangeClipX || chartRangeMinX < me.minx)) {
me.minx = chartRangeMinX;
}
if (chartRangeMaxX != null && (me.chartRangeClipX || chartRangeMaxX > me.maxx)) {
me.maxx = chartRangeMaxX;
}
},
drawNormalRange: function(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey) {
var normalRangeMin = this.getNormalRangeMin(),
normalRangeMax = this.getNormalRangeMax(),
ytop = canvasTop + Math.round(canvasHeight - (canvasHeight * ((normalRangeMax - this.miny) / rangey))),
height = Math.round((canvasHeight * (normalRangeMax - normalRangeMin)) / rangey);
this.canvas.drawRect(canvasLeft, ytop, canvasWidth, height, undefined, this.normalRangeColor).append();
},
renderGraph: function() {
var me = this,
canvas = me.canvas,
canvasWidth = me.getWidth(),
canvasHeight = me.getHeight(),
vertices = me.vertices,
spotRadius = me.getSpotRadius(),
regionMap = me.regionMap,
rangeX, Y, yvallast, canvasTop, canvasLeft, vertex, path, paths, x, y, xNext, xPos, xPosNext, last, next, yValCount, lineShapes, fillShapes, plen,
valueSpots = me.getValueSpots(),
hlSpotsEnabled, color, xValues, yValues, i,
spotColor = me.getSpotColor(),
minSpotColor = me.getMinSpotColor(),
maxSpotColor = me.getMaxSpotColor(),
normalRangeMin = me.getNormalRangeMin(),
drawNormalOnTop = me.getDrawNormalOnTop();
if (!me.callParent()) {
return;
}
me.scanValues();
me.processRangeOptions();
xValues = me.xvalues;
yValues = me.yvalues;
if (!me.yminmax.length || me.yvalues.length < 2) {
return;
}
canvasTop = canvasLeft = 0;
rangeX = me.maxx - me.minx === 0 ? 1 : me.maxx - me.minx;
Y = me.maxy - me.miny === 0 ? 1 : me.maxy - me.miny;
yvallast = me.yvalues.length - 1;
if (spotRadius && (canvasWidth < (spotRadius * 4) || canvasHeight < (spotRadius * 4))) {
spotRadius = 0;
}
if (spotRadius) {
hlSpotsEnabled = me.getHighlightSpotColor() && !me.disableInteraction;
if (hlSpotsEnabled || minSpotColor || (spotColor && yValues[yvallast] === me.miny)) {
canvasHeight -= Math.ceil(spotRadius);
}
if (hlSpotsEnabled || maxSpotColor || (spotColor && yValues[yvallast] === me.maxy)) {
canvasHeight -= Math.ceil(spotRadius);
canvasTop += Math.ceil(spotRadius);
}
if (hlSpotsEnabled || ((minSpotColor || maxSpotColor) && (yValues[0] === me.miny || yValues[0] === me.maxy))) {
canvasLeft += Math.ceil(spotRadius);
canvasWidth -= Math.ceil(spotRadius);
}
if (hlSpotsEnabled || spotColor || (minSpotColor || maxSpotColor && (yValues[yvallast] === me.miny || yValues[yvallast] === me.maxy))) {
canvasWidth -= Math.ceil(spotRadius);
}
}
canvasHeight--;
if (normalRangeMin != null && !drawNormalOnTop) {
me.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, Y);
}
path = [];
paths = [
path
];
last = next = null;
yValCount = yValues.length;
for (i = 0; i < yValCount; i++) {
x = xValues[i];
xNext = xValues[i + 1];
y = yValues[i];
xPos = canvasLeft + Math.round((x - me.minx) * (canvasWidth / rangeX));
xPosNext = i < yValCount - 1 ? canvasLeft + Math.round((xNext - me.minx) * (canvasWidth / rangeX)) : canvasWidth;
next = xPos + ((xPosNext - xPos) / 2);
regionMap[i] = [
last || 0,
next,
i
];
last = next;
if (y === null) {
if (i) {
if (yValues[i - 1] !== null) {
path = [];
paths.push(path);
}
vertices.push(null);
}
} else {
if (y < me.miny) {
y = me.miny;
}
if (y > me.maxy) {
y = me.maxy;
}
if (!path.length) {
path.push([
xPos,
canvasTop + canvasHeight
]);
}
vertex = [
xPos,
canvasTop + Math.round(canvasHeight - (canvasHeight * ((y - this.miny) / Y)))
];
path.push(vertex);
vertices.push(vertex);
}
}
lineShapes = [];
fillShapes = [];
plen = paths.length;
for (i = 0; i < plen; i++) {
path = paths[i];
if (path.length) {
if (me.fillColor) {
path.push([
path[path.length - 1][0],
(canvasTop + canvasHeight)
]);
fillShapes.push(path.slice(0));
path.pop();
}
if (path.length > 2) {
path[0] = [
path[0][0],
path[1][1]
];
}
lineShapes.push(path);
}
}
plen = fillShapes.length;
for (i = 0; i < plen; i++) {
canvas.drawShape(fillShapes[i], me.fillColor, me.fillColor).append();
}
if (normalRangeMin != null && drawNormalOnTop) {
me.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, Y);
}
plen = lineShapes.length;
for (i = 0; i < plen; i++) {
canvas.drawShape(lineShapes[i], me.getLineColor(), null, me.getLineWidth()).append();
}
if (spotRadius && valueSpots) {
if (valueSpots.get == null) {
valueSpots = new Ext.sparkline.RangeMap(valueSpots);
}
for (i = 0; i < yValCount; i++) {
color = valueSpots.get(yValues[i]);
if (color) {
canvas.drawCircle(canvasLeft + Math.round((xValues[i] - me.minx) * (canvasWidth / rangeX)), canvasTop + Math.round(canvasHeight - (canvasHeight * ((yValues[i] - me.miny) / Y))), spotRadius, null, color).append();
}
}
}
if (spotRadius && spotColor && yValues[yvallast] != null) {
canvas.drawCircle(canvasLeft + Math.round((xValues[xValues.length - 1] - me.minx) * (canvasWidth / rangeX)), canvasTop + Math.round(canvasHeight - (canvasHeight * ((yValues[yvallast] - me.miny) / Y))), spotRadius, null, spotColor).append();
}
if (me.maxy !== me.minyorg) {
if (spotRadius && minSpotColor) {
x = xValues[Ext.Array.indexOf(yValues, me.minyorg)];
canvas.drawCircle(canvasLeft + Math.round((x - me.minx) * (canvasWidth / rangeX)), canvasTop + Math.round(canvasHeight - (canvasHeight * ((me.minyorg - me.miny) / Y))), spotRadius, null, minSpotColor).append();
}
if (spotRadius && maxSpotColor) {
x = xValues[Ext.Array.indexOf(yValues, me.maxyorg)];
canvas.drawCircle(canvasLeft + Math.round((x - me.minx) * (canvasWidth / rangeX)), canvasTop + Math.round(canvasHeight - (canvasHeight * ((me.maxyorg - me.miny) / Y))), spotRadius, null, maxSpotColor).append();
}
}
me.canvasTop = canvasTop;
if (me.currentPageXY && me.el.getRegion().contains(me.currentPageXY)) {
me.updateDisplay();
}
canvas.render();
}
});
Ext.define('Ext.sparkline.Pie', {
extend: 'Ext.sparkline.Base',
alias: 'widget.sparklinepie',
config: {
offset: 0,
sliceColors: [
'#3366cc',
'#dc3912',
'#ff9900',
'#109618',
'#66aa00',
'#dd4477',
'#0099c6',
'#990099'
],
borderWidth: 0,
borderColor: '#000',
tipTpl: new Ext.XTemplate('&#9679; {value} ({percent:number("0.0")}%)')
},
applyValues: function(newValues) {
newValues = Ext.Array.map(Ext.Array.from(newValues), Number);
this.disabled = !(newValues && newValues.length);
return newValues;
},
onUpdate: function() {
var me = this,
values = me.values,
total = 0,
i;
me.callParent(arguments);
me.shapes = {};
me.valueShapes = {};
if (values.length > 0) {
for (i = values.length; i--; ) {
total += values[i];
}
}
me.total = total;
me.radius = Math.floor(Math.min(me.getWidth(), me.getHeight()) / 2);
},
getRegion: function(x, y) {
var ratio = window.devicePixelRatio || 1,
shapeid = this.canvas.getShapeAt(x * ratio, y * ratio);
return (shapeid != null && this.shapes[shapeid] != null) ? this.shapes[shapeid] : null;
},
getRegionFields: function(region) {
var sliceColors = this.getSliceColors();
return {
isNull: this.values[region] == null,
value: this.values[region],
percent: this.values[region] / this.total * 100,
color: sliceColors[region % sliceColors.length],
offset: region
};
},
renderHighlight: function(region) {
this.renderSlice(region, true).append();
},
renderSlice: function(valuenum, highlight) {
var me = this,
canvas = me.canvas,
radius = me.radius,
borderWidth = me.getBorderWidth(),
offset = me.getOffset(),
circle = 2 * Math.PI,
values = me.values,
total = me.total,
next = offset ? (2 * Math.PI) * (offset / 360) : 0,
start, end, i, vlen, color,
sliceColors = this.getSliceColors();
vlen = values.length;
for (i = 0; i < vlen; i++) {
start = next;
end = next;
if (total > 0) {
end = next + (circle * (values[i] / total));
}
if (valuenum === i) {
color = sliceColors[i % sliceColors.length];
if (highlight) {
color = me.calcHighlightColor(color);
}
return canvas.drawPieSlice(radius, radius, radius - borderWidth, start, end, null, color);
}
next = end;
}
},
renderGraph: function() {
var me = this,
canvas = me.canvas,
values = me.values,
radius = me.radius,
borderWidth = me.getBorderWidth(),
shape, i,
shapes = me.shapes || (me.shapes = {}),
valueShapes = me.valueShapes || (me.valueShapes = {});
if (!me.callParent()) {
return;
}
if (borderWidth) {
canvas.drawCircle(radius, radius, Math.floor(radius - (borderWidth / 2)), me.getBorderColor(), null, borderWidth).append();
}
for (i = values.length; i--; ) {
if (values[i]) {
shape = me.renderSlice(i).append();
valueShapes[i] = shape.id;
shapes[shape.id] = i;
}
}
if (me.currentPageXY && me.el.getRegion().contains(me.currentPageXY)) {
me.currentRegion = null;
me.updateDisplay();
}
canvas.render();
}
});
Ext.define('Ext.sparkline.TriState', {
extend: 'Ext.sparkline.BarBase',
requires: [
'Ext.sparkline.RangeMap'
],
alias: 'widget.sparklinetristate',
config: {
barWidth: 4,
barSpacing: 1,
posBarColor: '#6f6',
negBarColor: '#f44',
zeroBarColor: '#999',
colorMap: {},
tipTpl: new Ext.XTemplate('&#9679; {value:this.states}', {
states: function(v) {
var value = Number(v);
if (value === -1) {
return 'Loss';
}
if (value === 0) {
return 'Draw';
}
if (value === 1) {
return 'Win';
}
return v;
}
})
},
applyColorMap: function(colorMap) {
var me = this;
if (Ext.isArray(colorMap)) {
me.colorMapByIndex = colorMap;
me.colorMapByValue = null;
} else {
me.colorMapByIndex = null;
me.colorMapByValue = colorMap;
if (me.colorMapByValue && me.colorMapByValue.get == null) {
me.colorMapByValue = new Ext.sparkline.RangeMap(colorMap);
}
}
return colorMap;
},
applyValues: function(newValues) {
newValues = Ext.Array.map(Ext.Array.from(newValues), Number);
this.disabled = !(newValues && newValues.length);
return newValues;
},
onUpdate: function() {
this.totalBarWidth = this.getBarWidth() + this.getBarSpacing();
},
getBarWidth: function() {
var values = this.values;
return this._barWidth || (this.getWidth() - (values.length - 1) * this.getBarSpacing()) / values.length;
},
getRegion: function(x, y) {
return Math.floor(x / this.totalBarWidth);
},
getRegionFields: function(region) {
return {
isNull: this.values[region] == null,
value: this.values[region],
color: this.calcColor(this.values[region], region),
offset: region
};
},
calcColor: function(value, valuenum) {
var me = this,
values = me.values,
colorMapByIndex = me.colorMapByIndex,
colorMapByValue = me.colorMapByValue,
color, newColor;
if (colorMapByValue && (newColor = colorMapByValue.get(value))) {
color = newColor;
} else if (colorMapByIndex && colorMapByIndex.length > valuenum) {
color = colorMapByIndex[valuenum];
} else if (values[valuenum] < 0) {
color = me.getNegBarColor();
} else if (values[valuenum] > 0) {
color = me.getPosBarColor();
} else {
color = me.getZeroBarColor();
}
return color;
},
renderRegion: function(valuenum, highlight) {
var me = this,
values = me.values,
canvas = me.canvas,
canvasHeight, height, halfHeight, x, y, color;
canvasHeight = canvas.pixelHeight;
halfHeight = Math.round(canvasHeight / 2);
x = valuenum * me.totalBarWidth;
if (values[valuenum] < 0) {
y = halfHeight;
height = halfHeight - 1;
} else if (values[valuenum] > 0) {
y = 0;
height = halfHeight - 1;
} else {
y = halfHeight - 1;
height = 2;
}
color = me.calcColor(values[valuenum], valuenum);
if (color == null) {
return;
}
if (highlight) {
color = me.calcHighlightColor(color);
}
canvas.drawRect(x, y, me.getBarWidth() - 1, height - 1, color, color).append();
}
});
Ext.define('Ext.state.CookieProvider', {
extend: 'Ext.state.Provider',
constructor: function(config) {
var me = this;
me.path = "/";
me.expires = new Date(Ext.Date.now() + (1000 * 60 * 60 * 24 * 7));
me.domain = null;
me.secure = false;
me.callParent(arguments);
me.state = me.readCookies();
},
set: function(name, value) {
var me = this;
if (typeof value === "undefined" || value === null) {
me.clear(name);
return;
}
me.setCookie(name, value);
me.callParent(arguments);
},
clear: function(name) {
this.clearCookie(name);
this.callParent(arguments);
},
readCookies: function() {
var cookies = {},
c = document.cookie + ";",
re = /\s?(.*?)=(.*?);/g,
prefix = this.prefix,
len = prefix.length,
matches, name, value;
while ((matches = re.exec(c)) != null) {
name = matches[1];
value = matches[2];
if (name && name.substring(0, len) === prefix) {
cookies[name.substr(len)] = this.decodeValue(value);
}
}
return cookies;
},
setCookie: function(name, value) {
var me = this;
document.cookie = me.prefix + name + "=" + me.encodeValue(value) + ((me.expires == null) ? "" : ("; expires=" + me.expires.toUTCString())) + ((me.path == null) ? "" : ("; path=" + me.path)) + ((me.domain == null) ? "" : ("; domain=" + me.domain)) + (me.secure ? "; secure" : "");
},
clearCookie: function(name) {
var me = this;
document.cookie = me.prefix + name + "=null; expires=Thu, 01-Jan-1970 00:00:01 GMT" + ((me.path == null) ? "" : ("; path=" + me.path)) + ((me.domain == null) ? "" : ("; domain=" + me.domain)) + (me.secure ? "; secure" : "");
}
});
Ext.define('Ext.state.LocalStorageProvider', {
extend: 'Ext.state.Provider',
requires: [
'Ext.util.LocalStorage'
],
alias: 'state.localstorage',
constructor: function() {
var me = this;
me.callParent(arguments);
me.store = me.getStorageObject();
if (me.store) {
me.state = me.readLocalStorage();
} else {
me.state = {};
}
},
readLocalStorage: function() {
var store = this.store,
data = {},
keys = store.getKeys(),
i = keys.length,
key;
while (i--) {
key = keys[i];
data[key] = this.decodeValue(store.getItem(key));
}
return data;
},
set: function(name, value) {
var me = this;
me.clear(name);
if (value != null) {
me.store.setItem(name, me.encodeValue(value));
me.callParent(arguments);
}
},
clear: function(name) {
this.store.removeItem(name);
this.callParent(arguments);
},
getStorageObject: function() {
var prefix = this.prefix,
id = prefix,
n = id.length - 1;
if (id.charAt(n) === '-') {
id = id.substring(0, n);
}
return new Ext.util.LocalStorage({
id: id,
prefix: prefix
});
}
});
Ext.define('Ext.toolbar.Breadcrumb', {
extend: 'Ext.Container',
xtype: 'breadcrumb',
requires: [
'Ext.data.TreeStore',
'Ext.button.Split'
],
mixins: [
'Ext.util.FocusableContainer'
],
isBreadcrumb: true,
baseCls: Ext.baseCSSPrefix + 'breadcrumb',
layout: 'hbox',
config: {
buttonUI: 'plain-toolbar',
displayField: 'text',
overflowHandler: null,
showIcons: null,
showMenuIcons: null,
store: null,
useSplitButtons: true
},
renderConfig: {
selection: 'root'
},
publishes: [
'selection'
],
twoWayBindable: [
'selection'
],
_breadcrumbCls: Ext.baseCSSPrefix + 'breadcrumb',
_btnCls: Ext.baseCSSPrefix + 'breadcrumb-btn',
_folderIconCls: Ext.baseCSSPrefix + 'breadcrumb-icon-folder',
_leafIconCls: Ext.baseCSSPrefix + 'breadcrumb-icon-leaf',
initComponent: function() {
var me = this,
layout = me.layout,
overflowHandler = me.getOverflowHandler();
if (typeof layout === 'string') {
layout = {
type: layout
};
}
if (overflowHandler) {
layout.overflowHandler = overflowHandler;
}
me.layout = layout;
me.defaultButtonUI = me.getButtonUI();
me._buttons = [];
me.addCls([
me._breadcrumbCls,
me._breadcrumbCls + '-' + me.ui
]);
me.callParent();
},
onDestroy: function() {
var me = this;
me._buttons = Ext.destroy(me._buttons);
me.setStore(null);
me.callParent();
},
afterComponentLayout: function() {
var me = this,
overflowHandler = me.layout.overflowHandler;
me.callParent(arguments);
if (overflowHandler && me.tooNarrow && overflowHandler.scrollToItem) {
overflowHandler.scrollToItem(me.getSelection().get('depth'));
}
},
applySelection: function(node) {
var store = this.getStore();
if (store) {
node = (node === 'root') ? this.getStore().getRoot() : node;
} else {
node = null;
}
return node;
},
updateSelection: function(node) {
var me = this,
buttons = me._buttons,
items = [],
itemCount = me.items.getCount(),
needsSync = me._needsSync,
displayField = me.getDisplayField(),
showIcons, glyph, iconCls, icon, newItemCount, currentNode, text, button, id, depth, i;
Ext.suspendLayouts();
if (node) {
currentNode = node;
depth = node.get('depth');
newItemCount = depth + 1;
i = depth;
while (currentNode) {
id = currentNode.getId();
button = buttons[i];
if (!needsSync && button && button._breadcrumbNodeId === id) {
break;
}
text = currentNode.get(displayField);
if (button) {
button.setText(text);
} else {
button = buttons[i] = Ext.create({
xtype: me.getUseSplitButtons() ? 'splitbutton' : 'button',
ui: me.getButtonUI(),
cls: me._btnCls + ' ' + me._btnCls + '-' + me.ui,
text: text,
showEmptyMenu: true,
menu: {
listeners: {
click: '_onMenuClick',
beforeshow: '_onMenuBeforeShow',
scope: this
}
},
handler: '_onButtonClick',
scope: me
});
}
showIcons = this.getShowIcons();
if (showIcons !== false) {
glyph = currentNode.get('glyph');
icon = currentNode.get('icon');
iconCls = currentNode.get('iconCls');
if (glyph) {
button.setGlyph(glyph);
button.setIcon(null);
button.setIconCls(iconCls);
}
else if (icon) {
button.setGlyph(null);
button.setIconCls(null);
button.setIcon(icon);
} else if (iconCls) {
button.setGlyph(null);
button.setIcon(null);
button.setIconCls(iconCls);
} else if (showIcons) {
button.setGlyph(null);
button.setIcon(null);
button.setIconCls((currentNode.isLeaf() ? me._leafIconCls : me._folderIconCls) + '-' + me.ui);
} else {
button.setGlyph(null);
button.setIcon(null);
button.setIconCls(null);
}
}
button.setArrowVisible(currentNode.hasChildNodes());
button._breadcrumbNodeId = currentNode.getId();
currentNode = currentNode.parentNode;
i--;
}
if (newItemCount > itemCount) {
items = buttons.slice(itemCount, depth + 1);
me.add(items);
} else {
for (i = itemCount - 1; i >= newItemCount; i--) {
me.remove(me.items.items[i], false);
}
}
} else {
me.removeAll(false);
}
Ext.resumeLayouts(true);
me.fireEvent('selectionchange', me, node);
me._needsSync = false;
},
applyUseSplitButtons: function(useSplitButtons, oldUseSplitButtons) {
if (this.rendered && useSplitButtons !== oldUseSplitButtons) {
Ext.Error.raise("Cannot reconfigure 'useSplitButtons' config of Ext.toolbar.Breadcrumb after initial render");
}
return useSplitButtons;
},
applyStore: function(store) {
if (store) {
store = Ext.data.StoreManager.lookup(store);
}
return store;
},
updateStore: function(store, oldStore) {
this._needsSync = true;
if (store && !this.isConfiguring) {
this.setSelection(store.getRoot());
}
},
updateOverflowHandler: function(overflowHandler) {
if (overflowHandler === 'menu') {
Ext.Error.raise("Using Menu overflow with breadcrumb is not currently supported.");
}
},
privates: {
_onButtonClick: function(button, e) {
if (this.getUseSplitButtons()) {
this.setSelection(this.getStore().getNodeById(button._breadcrumbNodeId));
}
},
_onMenuClick: function(menu, item, e) {
if (item) {
this.setSelection(this.getStore().getNodeById(item._breadcrumbNodeId));
}
},
_onMenuBeforeShow: function(menu) {
var me = this,
node = me.getStore().getNodeById(menu.ownerCmp._breadcrumbNodeId),
displayField = me.getDisplayField(),
showMenuIcons = me.getShowMenuIcons(),
childNodes, child, glyph, items, i, icon, iconCls, ln, item;
if (node.hasChildNodes()) {
childNodes = node.childNodes;
items = [];
for (i = 0 , ln = childNodes.length; i < ln; i++) {
child = childNodes[i];
item = {
text: child.get(displayField),
_breadcrumbNodeId: child.getId()
};
if (showMenuIcons !== false) {
glyph = child.get('glyph');
icon = child.get('icon');
iconCls = child.get('iconCls');
if (glyph) {
item.glyph = glyph;
item.iconCls = iconCls;
}
else if (icon) {
item.icon = icon;
} else if (iconCls) {
item.iconCls = iconCls;
} else if (showMenuIcons) {
item.iconCls = (child.isLeaf() ? me._leafIconCls : me._folderIconCls) + '-' + me.ui;
}
}
items.push(item);
}
menu.removeAll();
menu.add(items);
} else {
return false;
}
}
}
});
Ext.define('Ext.toolbar.Fill', {
extend: 'Ext.Component',
requires: [
'Ext.toolbar.Toolbar'
],
alias: 'widget.tbfill',
alternateClassName: 'Ext.Toolbar.Fill',
ariaRole: 'presentation',
isFill: true,
flex: 1
});
Ext.define('Ext.toolbar.Spacer', {
extend: 'Ext.Component',
requires: [
'Ext.toolbar.Toolbar'
],
alias: 'widget.tbspacer',
alternateClassName: 'Ext.Toolbar.Spacer',
baseCls: Ext.baseCSSPrefix + 'toolbar-spacer',
ariaRole: 'presentation'
});
Ext.define('Ext.view.DragZone', {
extend: 'Ext.dd.DragZone',
containerScroll: false,
constructor: function(config) {
var me = this,
view, ownerCt, el;
Ext.apply(me, config);
if (!me.ddGroup) {
me.ddGroup = 'view-dd-zone-' + me.view.id;
}
view = me.view;
ownerCt = view.ownerCt;
if (ownerCt) {
el = ownerCt.getTargetEl().dom;
} else {
el = view.el.dom.parentNode;
}
me.callParent([
el
]);
me.ddel = document.createElement('div');
me.ddel.className = Ext.baseCSSPrefix + 'grid-dd-wrap';
},
init: function(id, sGroup, config) {
var me = this,
triggerEvent = Ext.supports.touchScroll ? 'itemlongpress' : 'itemmousedown',
eventSpec = {
scope: me
};
eventSpec[triggerEvent] = me.onItemMouseDown;
me.initTarget(id, sGroup, config);
me.view.mon(me.view, eventSpec);
},
onValidDrop: function(target, e, id) {
this.callParent([
target,
e,
id
]);
target.el.focus();
},
onItemMouseDown: function(view, record, item, index, e) {
if (!this.isPreventDrag(e, record, item, index)) {
if (view.focusRow) {
view.focusRow(record);
}
this.handleMouseDown(e);
}
},
isPreventDrag: function(e, record, item, index) {
return false;
},
getDragData: function(e) {
var view = this.view,
item = e.getTarget(view.getItemSelector());
if (item) {
return {
copy: view.copy || (view.allowCopy && e.ctrlKey),
event: e,
view: view,
ddel: this.ddel,
item: item,
records: view.getSelectionModel().getSelection(),
fromPosition: Ext.fly(item).getXY()
};
}
},
onInitDrag: function(x, y) {
var me = this,
data = me.dragData,
view = data.view,
selectionModel = view.getSelectionModel(),
record = view.getRecord(data.item);
if (!selectionModel.isSelected(record)) {
selectionModel.selectWithEvent(record, me.DDMInstance.mousedownEvent);
}
data.records = selectionModel.getSelection();
Ext.fly(me.ddel).setHtml(me.getDragText());
me.proxy.update(me.ddel);
me.onStartDrag(x, y);
return true;
},
getDragText: function() {
var count = this.dragData.records.length;
return Ext.String.format(this.dragText, count, count === 1 ? '' : 's');
},
getRepairXY: function(e, data) {
return data ? data.fromPosition : false;
}
});
Ext.define('Ext.tree.ViewDragZone', {
extend: 'Ext.view.DragZone',
isPreventDrag: function(e, record) {
return (record.get('allowDrag') === false) || !!e.getTarget(this.view.expanderSelector);
},
getDragText: function() {
var records = this.dragData.records,
count = records.length,
text = records[0].get(this.displayField),
suffix = 's';
if (count === 1 && text) {
return text;
} else if (!text) {
suffix = '';
}
return Ext.String.format(this.dragText, count, suffix);
},
afterRepair: function() {
var me = this,
view = me.view,
selectedRowCls = view.selectedItemCls,
records = me.dragData.records,
r,
rLen = records.length,
fly = Ext.fly,
item;
if (Ext.enableFx && me.repairHighlight) {
for (r = 0; r < rLen; r++) {
item = view.getNode(records[r]);
fly(item.firstChild).highlight(me.repairHighlightColor, {
listeners: {
beforeanimate: function() {
if (view.isSelected(item)) {
fly(item).removeCls(selectedRowCls);
}
},
afteranimate: function() {
if (view.isSelected(item)) {
fly(item).addCls(selectedRowCls);
}
}
}
});
}
}
me.dragging = false;
}
});
Ext.define('Ext.tree.ViewDropZone', {
extend: 'Ext.view.DropZone',
allowParentInserts: false,
allowContainerDrops: false,
appendOnly: false,
expandDelay: 500,
indicatorCls: Ext.baseCSSPrefix + 'tree-ddindicator',
expandNode: function(node) {
var view = this.view;
this.expandProcId = false;
if (!node.isLeaf() && !node.isExpanded()) {
view.expand(node);
this.expandProcId = false;
}
},
queueExpand: function(node) {
this.expandProcId = Ext.Function.defer(this.expandNode, this.expandDelay, this, [
node
]);
},
cancelExpand: function() {
if (this.expandProcId) {
clearTimeout(this.expandProcId);
this.expandProcId = false;
}
},
getPosition: function(e, node) {
var view = this.view,
record = view.getRecord(node),
y = e.getY(),
noAppend = record.isLeaf(),
noBelow = false,
region = Ext.fly(node).getRegion(),
fragment;
if (record.isRoot()) {
return 'append';
}
if (this.appendOnly) {
return noAppend ? false : 'append';
}
if (!this.allowParentInserts) {
noBelow = record.hasChildNodes() && record.isExpanded();
}
fragment = (region.bottom - region.top) / (noAppend ? 2 : 3);
if (y >= region.top && y < (region.top + fragment)) {
return 'before';
} else if (!noBelow && (noAppend || (y >= (region.bottom - fragment) && y <= region.bottom))) {
return 'after';
} else {
return 'append';
}
},
isValidDropPoint: function(node, position, dragZone, e, data) {
if (!node || !data.item) {
return false;
}
var view = this.view,
targetNode = view.getRecord(node),
draggedRecords = data.records,
dataLength = draggedRecords.length,
ln = draggedRecords.length,
i, record;
if (!(targetNode && position && dataLength)) {
return false;
}
for (i = 0; i < ln; i++) {
record = draggedRecords[i];
if (record.isNode && record.contains(targetNode)) {
return false;
}
}
if (position === 'append' && targetNode.get('allowDrop') === false) {
return false;
} else if (position !== 'append' && targetNode.parentNode.get('allowDrop') === false) {
return false;
}
if (Ext.Array.contains(draggedRecords, targetNode)) {
return false;
}
return view.fireEvent('nodedragover', targetNode, position, data, e) !== false;
},
onNodeOver: function(node, dragZone, e, data) {
var position = this.getPosition(e, node),
returnCls = this.dropNotAllowed,
view = this.view,
targetNode = view.getRecord(node),
indicator = this.getIndicator(),
indicatorY = 0;
this.cancelExpand();
if (position === 'append' && !this.expandProcId && !Ext.Array.contains(data.records, targetNode) && !targetNode.isLeaf() && !targetNode.isExpanded()) {
this.queueExpand(targetNode);
}
if (this.isValidDropPoint(node, position, dragZone, e, data)) {
this.valid = true;
this.currentPosition = position;
this.overRecord = targetNode;
indicator.setWidth(Ext.fly(node).getWidth());
indicatorY = Ext.fly(node).getY() - Ext.fly(view.el).getY() - 1;
if (view.touchScroll === 2) {
indicatorY += view.getScrollY();
}
if (position === 'before') {
returnCls = targetNode.isFirst() ? Ext.baseCSSPrefix + 'tree-drop-ok-above' : Ext.baseCSSPrefix + 'tree-drop-ok-between';
indicator.showAt(0, indicatorY);
dragZone.proxy.show();
} else if (position === 'after') {
returnCls = targetNode.isLast() ? Ext.baseCSSPrefix + 'tree-drop-ok-below' : Ext.baseCSSPrefix + 'tree-drop-ok-between';
indicatorY += Ext.fly(node).getHeight();
indicator.showAt(0, indicatorY);
dragZone.proxy.show();
} else {
returnCls = Ext.baseCSSPrefix + 'tree-drop-ok-append';
indicator.hide();
}
} else {
this.valid = false;
}
this.currentCls = returnCls;
return returnCls;
},
onNodeOut: function(n, dd, e, data) {
this.valid = false;
this.getIndicator().hide();
},
onContainerOver: function(dd, e, data) {
return this.allowContainerDrops ? this.dropAllowed : e.getTarget('.' + this.indicatorCls) ? this.currentCls : this.dropNotAllowed;
},
onContainerDrop: function(dragZone, e, data) {
if (this.allowContainerDrops) {
this.valid = true;
this.currentPosition = 'append';
this.overRecord = this.view.store.getRoot();
this.onNodeDrop(this.overRecord, dragZone, e, data);
}
},
notifyOut: function() {
this.callParent(arguments);
this.cancelExpand();
},
handleNodeDrop: function(data, targetNode, position) {
var me = this,
targetView = me.view,
parentNode = targetNode ? targetNode.parentNode : targetView.panel.getRootNode(),
Model = targetView.store.getModel(),
records, i, len, record, insertionMethod, argList, needTargetExpand, transferData;
if (data.copy) {
records = data.records;
data.records = [];
for (i = 0 , len = records.length; i < len; i++) {
record = records[i];
if (record.isNode) {
data.records.push(record.copy());
} else {
data.records.push(new Model(Ext.apply({}, record.data)));
}
}
}
me.cancelExpand();
if (position === 'before') {
insertionMethod = parentNode.insertBefore;
argList = [
null,
targetNode
];
targetNode = parentNode;
} else if (position === 'after') {
if (targetNode.nextSibling) {
insertionMethod = parentNode.insertBefore;
argList = [
null,
targetNode.nextSibling
];
} else {
insertionMethod = parentNode.appendChild;
argList = [
null
];
}
targetNode = parentNode;
} else {
if (!(targetNode.isExpanded() || targetNode.isLoading())) {
needTargetExpand = true;
}
insertionMethod = targetNode.appendChild;
argList = [
null
];
}
transferData = function() {
var color, n;
Ext.suspendLayouts();
for (i = 0 , len = data.records.length; i < len; i++) {
record = data.records[i];
if (!record.isNode) {
if (record.isModel) {
record = new Model(record.data, record.getId());
} else {
record = new Model(record);
}
data.records[i] = record;
}
argList[0] = record;
insertionMethod.apply(targetNode, argList);
targetView.getNavigationModel().setPosition(record);
}
if (me.sortOnDrop) {
targetNode.sort(targetNode.getOwnerTree().store.getSorters().sortFn);
}
Ext.resumeLayouts(true);
if (Ext.enableFx && me.dropHighlight) {
color = me.dropHighlightColor;
for (i = 0; i < len; i++) {
n = targetView.getNode(data.records[i]);
if (n) {
Ext.fly(n).highlight(color);
}
}
}
};
if (needTargetExpand) {
targetNode.expand(false, transferData);
}
else if (targetNode.isLoading()) {
targetNode.on({
expand: transferData,
delay: 1,
single: true
});
} else
{
transferData();
}
}
});
Ext.define('Ext.tree.plugin.TreeViewDragDrop', {
extend: 'Ext.plugin.Abstract',
alias: 'plugin.treeviewdragdrop',
uses: [
'Ext.tree.ViewDragZone',
'Ext.tree.ViewDropZone'
],
dragText: '{0} selected node{1}',
allowParentInserts: false,
allowContainerDrops: false,
appendOnly: false,
ddGroup: "TreeDD",
containerScroll: false,
expandDelay: 1000,
enableDrop: true,
enableDrag: true,
nodeHighlightColor: 'c3daf9',
nodeHighlightOnDrop: Ext.enableFx,
displayField: 'text',
init: function(view) {
view.on('render', this.onViewRender, this, {
single: true
});
},
destroy: function() {
Ext.destroy(this.dragZone, this.dropZone);
},
onViewRender: function(view) {
var me = this,
scrollEl;
if (me.enableDrag) {
if (me.containerScroll) {
scrollEl = view.getEl();
}
me.dragZone = new Ext.tree.ViewDragZone(Ext.apply({
view: view,
ddGroup: me.dragGroup || me.ddGroup,
dragText: me.dragText,
displayField: me.displayField,
repairHighlightColor: me.nodeHighlightColor,
repairHighlight: me.nodeHighlightOnRepair,
scrollEl: scrollEl
}, me.dragZone));
}
if (me.enableDrop) {
me.dropZone = new Ext.tree.ViewDropZone(Ext.apply({
view: view,
ddGroup: me.dropGroup || me.ddGroup,
allowContainerDrops: me.allowContainerDrops,
appendOnly: me.appendOnly,
allowParentInserts: me.allowParentInserts,
expandDelay: me.expandDelay,
dropHighlightColor: me.nodeHighlightColor,
dropHighlight: me.nodeHighlightOnDrop,
sortOnDrop: me.sortOnDrop,
containerScroll: me.containerScroll
}, me.dropZone));
}
}
}, function() {
var proto = this.prototype;
proto.nodeHighlightOnDrop = proto.nodeHighlightOnRepair = Ext.enableFx;
});
Ext.define('Ext.util.CSS', function() {
var CSS,
rules = null,
doc = document,
camelRe = /(-[a-z])/gi,
camelFn = function(m, a) {
return a.charAt(1).toUpperCase();
};
return {
singleton: true,
rules: rules,
initialized: false,
constructor: function() {
CSS = this;
},
createStyleSheet: function(cssText, id) {
var ss,
head = doc.getElementsByTagName('head')[0],
styleEl = doc.createElement('style');
styleEl.setAttribute('type', 'text/css');
if (id) {
styleEl.setAttribute('id', id);
}
ss = styleEl.styleSheet;
if (ss) {
head.appendChild(styleEl);
ss.cssText = cssText;
} else {
styleEl.appendChild(doc.createTextNode(cssText));
head.appendChild(styleEl);
ss = styleEl.sheet;
}
CSS.cacheStyleSheet(ss);
return ss;
},
removeStyleSheet: function(id) {
var existing = doc.getElementById(id);
if (existing) {
existing.parentNode.removeChild(existing);
}
},
swapStyleSheet: function(id, url) {
var ss;
CSS.removeStyleSheet(id);
ss = doc.createElement("link");
ss.setAttribute("rel", "stylesheet");
ss.setAttribute("type", "text/css");
ss.setAttribute("id", id);
ss.setAttribute("href", url);
doc.getElementsByTagName("head")[0].appendChild(ss);
},
cacheStyleSheet: function(ss) {
if (!rules) {
rules = CSS.rules = {};
}
try {
var ssRules = ss.cssRules || ss.rules,
i = ssRules.length - 1,
imports = ss.imports,
len = imports ? imports.length : 0,
rule, j;
for (j = 0; j < len; ++j) {
CSS.cacheStyleSheet(imports[j]);
}
for (; i >= 0; --i) {
rule = ssRules[i];
if (rule.styleSheet) {
CSS.cacheStyleSheet(rule.styleSheet);
}
CSS.cacheRule(rule, ss);
}
} catch (e) {}
},
cacheRule: function(cssRule, styleSheet) {
if (cssRule.styleSheet) {
return CSS.cacheStyleSheet(cssRule.styleSheet);
}
var selectorText = cssRule.selectorText,
selectorCount, j;
if (selectorText) {
selectorText = selectorText.split(',');
selectorCount = selectorText.length;
for (j = 0; j < selectorCount; j++) {
rules[Ext.String.trim(selectorText[j]).toLowerCase()] = {
parentStyleSheet: styleSheet,
cssRule: cssRule
};
}
}
},
getRules: function(refreshCache) {
var result = {},
selector;
if (rules === null || refreshCache) {
CSS.refreshCache();
}
for (selector in rules) {
result[selector] = rules[selector].cssRule;
}
return result;
},
refreshCache: function() {
var ds = doc.styleSheets,
i = 0,
len = ds.length;
rules = CSS.rules = {};
for (; i < len; i++) {
try {
if (!ds[i].disabled) {
CSS.cacheStyleSheet(ds[i]);
}
} catch (e) {}
}
},
getRule: function(selector, refreshCache, rawCache) {
var i, result;
if (!rules || refreshCache) {
CSS.refreshCache();
}
if (!Ext.isArray(selector)) {
result = rules[selector.toLowerCase()];
if (result && !rawCache) {
result = result.cssRule;
}
return result || null;
}
for (i = 0; i < selector.length; i++) {
if (rules[selector[i]]) {
return rawCache ? rules[selector[i].toLowerCase()] : rules[selector[i].toLowerCase()].cssRule;
}
}
return null;
},
createRule: function(styleSheet, selector, cssText) {
var result,
ruleSet = styleSheet.cssRules || styleSheet.rules,
index = ruleSet.length;
if (styleSheet.insertRule) {
styleSheet.insertRule(selector + ' {' + cssText + '}', index);
} else {
styleSheet.addRule(selector, cssText || ' ');
}
CSS.cacheRule(result = ruleSet[index], styleSheet);
return result;
},
updateRule: function(selector, property, value) {
var rule, i, styles;
if (!Ext.isArray(selector)) {
rule = CSS.getRule(selector);
if (rule) {
if (arguments.length === 2) {
styles = Ext.Element.parseStyles(property);
for (property in styles) {
rule.style[property.replace(camelRe, camelFn)] = styles[property];
}
} else {
rule.style[property.replace(camelRe, camelFn)] = value;
}
return true;
}
} else {
for (i = 0; i < selector.length; i++) {
if (CSS.updateRule(selector[i], property, value)) {
return true;
}
}
}
return false;
},
deleteRule: function(selector) {
var rule = CSS.getRule(selector, false, true),
styleSheet, index;
if (rule) {
styleSheet = rule.parentStyleSheet;
index = Ext.Array.indexOf(styleSheet.cssRules || styleSheet.rules, rule.cssRule);
if (styleSheet.deleteRule) {
styleSheet.deleteRule(index);
} else {
styleSheet.removeRule(index);
}
delete rules[selector];
}
}
};
});
Ext.define('Ext.util.Cookies', {
singleton: true,
set: function(name, value) {
var argv = arguments,
argc = arguments.length,
expires = (argc > 2) ? argv[2] : null,
path = (argc > 3) ? argv[3] : '/',
domain = (argc > 4) ? argv[4] : null,
secure = (argc > 5) ? argv[5] : false;
document.cookie = name + "=" + escape(value) + ((expires === null) ? "" : ("; expires=" + expires.toUTCString())) + ((path === null) ? "" : ("; path=" + path)) + ((domain === null) ? "" : ("; domain=" + domain)) + ((secure === true) ? "; secure" : "");
},
get: function(name) {
var parts = document.cookie.split('; '),
len = parts.length,
item, i, ret;
for (i = 0; i < len; ++i) {
item = parts[i].split('=');
if (item[0] === name) {
ret = item[1];
return ret ? unescape(ret) : '';
}
}
return null;
},
clear: function(name, path) {
if (this.get(name)) {
path = path || '/';
document.cookie = name + '=' + '; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=' + path;
}
}
});
Ext.define('Ext.view.MultiSelectorSearch', {
extend: 'Ext.panel.Panel',
xtype: 'multiselector-search',
layout: 'fit',
floating: true,
resizable: true,
minWidth: 200,
minHeight: 200,
border: true,
defaultListenerScope: true,
referenceHolder: true,
searchText: 'Search...',
initComponent: function() {
var me = this,
owner = me.owner,
items = me.makeItems(),
i, item, records, store;
me.dockedItems = me.makeDockedItems();
me.items = items;
store = Ext.data.StoreManager.lookup(me.store);
for (i = items.length; i--; ) {
if ((item = items[i]).xtype === 'grid') {
item.store = store;
item.isSearchGrid = true;
item.selModel = item.selModel || {
type: 'checkboxmodel',
pruneRemoved: false,
listeners: {
selectionchange: 'onSelectionChange'
}
};
Ext.merge(item, me.grid);
if (!item.columns) {
item.hideHeaders = true;
item.columns = [
{
flex: 1,
dataIndex: me.field
}
];
}
break;
}
}
me.callParent();
records = me.getOwnerStore().getRange();
if (!owner.convertSelectionRecord.$nullFn) {
for (i = records.length; i--; ) {
records[i] = owner.convertSelectionRecord(records[i]);
}
}
if (store.isLoading() || (store.loadCount === 0 && !store.getCount())) {
store.on('load', function() {
var len = records.length,
i, record,
toSelect = [];
if (!me.destroyed) {
for (i = 0; i < len; i++) {
record = store.getById(records[i].getId());
if (record) {
toSelect.push(record);
}
}
me.selectRecords(toSelect);
}
}, null, {
single: true
});
} else {
me.selectRecords(records);
}
},
getOwnerStore: function() {
return this.owner.getStore();
},
afterShow: function() {
var searchField = this.lookupReference('searchField');
this.callParent(arguments);
if (searchField) {
searchField.focus();
}
},
getSearchStore: function() {
var searchGrid = this.lookupReference('searchGrid');
return searchGrid.getStore();
},
makeDockedItems: function() {
return [
{
xtype: 'textfield',
reference: 'searchField',
dock: 'top',
hideFieldLabel: true,
emptyText: this.searchText,
triggers: {
clear: {
cls: Ext.baseCSSPrefix + 'form-clear-trigger',
handler: 'onClearSearch',
hidden: true
}
},
listeners: {
change: 'onSearchChange',
buffer: 300
}
}
];
},
makeItems: function() {
return [
{
xtype: 'grid',
reference: 'searchGrid',
trailingBufferZone: 2,
leadingBufferZone: 2,
viewConfig: {
deferEmptyText: false,
emptyText: 'No results.'
}
}
];
},
selectRecords: function(records) {
var searchGrid = this.lookupReference('searchGrid');
return searchGrid.getSelectionModel().select(records);
},
deselectRecords: function(records) {
var searchGrid = this.lookupReference('searchGrid');
return searchGrid.getSelectionModel().deselect(records);
},
search: function(text) {
var me = this,
filter = me.searchFilter,
filters = me.getSearchStore().getFilters();
if (text) {
filters.beginUpdate();
if (filter) {
filter.setValue(text);
} else {
me.searchFilter = filter = new Ext.util.Filter({
id: 'search',
property: me.field,
value: text
});
}
filters.add(filter);
filters.endUpdate();
} else if (filter) {
filters.remove(filter);
}
},
privates: {
onClearSearch: function() {
var searchField = this.lookupReference('searchField');
searchField.setValue(null);
searchField.focus();
},
onSearchChange: function(searchField) {
var value = searchField.getValue(),
trigger = searchField.getTrigger('clear');
trigger.setHidden(!value);
this.search(value);
},
onSelectionChange: function(selModel, selection) {
var owner = this.owner,
store = owner.getStore(),
data = store.data,
remove = 0,
map = {},
add, i, id, record;
for (i = selection.length; i--; ) {
record = selection[i];
id = record.id;
map[id] = record;
if (!data.containsKey(id)) {
(add || (add = [])).push(owner.convertSearchRecord(record));
}
}
for (i = data.length; i--; ) {
record = data.getAt(i);
if (!map[record.id]) {
(remove || (remove = [])).push(record);
}
}
if (add || remove) {
data.splice(data.length, remove, add);
}
}
}
});
Ext.define('Ext.view.MultiSelector', {
extend: 'Ext.grid.Panel',
xtype: 'multiselector',
config: {
search: {
xtype: 'multiselector-search',
width: 200,
height: 200,
store: {
autoLoad: true
}
}
},
fieldName: 'name',
fieldTitle: null,
removeRowText: '✖',
removeRowTip: 'Remove this item',
emptyText: 'Nothing selected',
addToolText: 'Search for items to add',
initComponent: function() {
var me = this,
emptyText = me.emptyText,
store = me.getStore(),
search = me.getSearch(),
fieldTitle = me.fieldTitle,
searchStore, model;
if (!search) {
Ext.Error.raise('The search configuration is required for the multi selector');
}
searchStore = search.store;
if (searchStore.isStore) {
model = searchStore.getModel();
} else {
model = searchStore.model;
}
if (!store) {
me.store = {
model: model
};
}
if (emptyText && !me.viewConfig) {
me.viewConfig = {
deferEmptyText: false,
emptyText: emptyText
};
}
if (!me.columns) {
me.hideHeaders = !fieldTitle;
me.columns = [
{
text: fieldTitle,
dataIndex: me.fieldName,
flex: 1
},
me.makeRemoveRowColumn()
];
}
me.callParent();
},
addTools: function() {
this.addTool({
type: 'plus',
tooltip: this.addToolText,
callback: 'onShowSearch',
scope: this
});
},
convertSearchRecord: Ext.identityFn,
convertSelectionRecord: Ext.identityFn,
makeRemoveRowColumn: function() {
var me = this;
return {
width: 22,
menuDisabled: true,
tdCls: Ext.baseCSSPrefix + 'multiselector-remove',
processEvent: me.processRowEvent.bind(me),
renderer: me.renderRemoveRow,
updater: Ext.emptyFn,
scope: me
};
},
processRowEvent: function(type, view, cell, recordIndex, cellIndex, e, record, row) {
if (e.type !== 'click') {
return;
}
if (Ext.fly(cell).hasCls(Ext.baseCSSPrefix + 'multiselector-remove')) {
this.store.remove(record);
if (this.searchPopup) {
this.searchPopup.deselectRecords(record);
}
}
},
renderRemoveRow: function() {
return '<span data-qtip="' + this.removeRowTip + '" role="button">' + this.removeRowText + '</span>';
},
beforeDestroy: function() {
Ext.un({
mousedown: 'onDismissSearch',
scope: this
});
this.callParent();
},
privates: {
onDismissSearch: function(e) {
var searchPopup = this.searchPopup;
if (searchPopup && !(searchPopup.owns(e.getTarget()) || this.owns(e.getTarget()))) {
Ext.un({
mousedown: 'onDismissSearch',
scope: this
});
searchPopup.hide();
}
},
onShowSearch: function(panel, tool) {
var me = this,
searchPopup = me.searchPopup,
store = me.getStore();
if (!searchPopup) {
searchPopup = Ext.merge({
owner: me,
field: me.fieldName,
floating: true
}, me.getSearch());
me.searchPopup = searchPopup = me.add(searchPopup);
if (store.getCount()) {
searchPopup.selectRecords(store.getRange());
}
}
searchPopup.showBy(me, 'tl-tr?');
Ext.on({
mousedown: 'onDismissSearch',
scope: me
});
}
}
});
Ext.define('Ext.window.Toast', {
extend: 'Ext.window.Window',
xtype: 'toast',
isToast: true,
cls: Ext.baseCSSPrefix + 'toast',
bodyPadding: 10,
autoClose: true,
plain: false,
draggable: false,
resizable: false,
shadow: false,
focus: Ext.emptyFn,
anchor: null,
useXAxis: false,
align: 'br',
animate: true,
spacing: 6,
paddingX: 30,
paddingY: 10,
slideInAnimation: 'easeIn',
slideBackAnimation: 'bounceOut',
slideInDuration: 1500,
slideBackDuration: 1000,
hideDuration: 500,
autoCloseDelay: 3000,
stickOnClick: true,
stickWhileHover: true,
closeOnMouseDown: false,
isHiding: false,
isFading: false,
destroyAfterHide: false,
closeOnMouseOut: false,
xPos: 0,
yPos: 0,
initComponent: function() {
var me = this;
me.updateAlignment(me.align);
me.setAnchor(me.anchor);
me.callParent();
},
onRender: function() {
var me = this;
me.callParent(arguments);
me.el.hover(me.onMouseEnter, me.onMouseLeave, me);
if (me.closeOnMouseDown) {
Ext.getDoc().on('mousedown', me.onDocumentMousedown, me);
}
},
alignmentProps: {
br: {
paddingFactorX: -1,
paddingFactorY: -1,
siblingAlignment: "br-br",
anchorAlign: "tr-br"
},
bl: {
paddingFactorX: 1,
paddingFactorY: -1,
siblingAlignment: "bl-bl",
anchorAlign: "tl-bl"
},
tr: {
paddingFactorX: -1,
paddingFactorY: 1,
siblingAlignment: "tr-tr",
anchorAlign: "br-tr"
},
tl: {
paddingFactorX: 1,
paddingFactorY: 1,
siblingAlignment: "tl-tl",
anchorAlign: "bl-tl"
},
b: {
paddingFactorX: 0,
paddingFactorY: -1,
siblingAlignment: "b-b",
useXAxis: 0,
anchorAlign: "t-b"
},
t: {
paddingFactorX: 0,
paddingFactorY: 1,
siblingAlignment: "t-t",
useXAxis: 0,
anchorAlign: "b-t"
},
l: {
paddingFactorX: 1,
paddingFactorY: 0,
siblingAlignment: "l-l",
useXAxis: 1,
anchorAlign: "r-l"
},
r: {
paddingFactorX: -1,
paddingFactorY: 0,
siblingAlignment: "r-r",
useXAxis: 1,
anchorAlign: "l-r"
},
x: {
br: {
anchorAlign: "bl-br"
},
bl: {
anchorAlign: "br-bl"
},
tr: {
anchorAlign: "tl-tr"
},
tl: {
anchorAlign: "tr-tl"
}
}
},
updateAlignment: function(align) {
var me = this,
alignmentProps = me.alignmentProps,
props = alignmentProps[align],
xprops = alignmentProps.x[align];
if (xprops && me.useXAxis) {
Ext.applyIf(me, xprops);
}
Ext.applyIf(me, props);
},
getXposAlignedToAnchor: function() {
var me = this,
align = me.align,
anchor = me.anchor,
anchorEl = anchor && anchor.el,
el = me.el,
xPos = 0;
if (anchorEl && anchorEl.dom) {
if (!me.useXAxis) {
xPos = el.getLeft();
}
else if (align === 'br' || align === 'tr' || align === 'r') {
xPos += anchorEl.getAnchorXY('r')[0];
xPos -= (el.getWidth() + me.paddingX);
} else {
xPos += anchorEl.getAnchorXY('l')[0];
xPos += me.paddingX;
}
}
return xPos;
},
getYposAlignedToAnchor: function() {
var me = this,
align = me.align,
anchor = me.anchor,
anchorEl = anchor && anchor.el,
el = me.el,
yPos = 0;
if (anchorEl && anchorEl.dom) {
if (me.useXAxis) {
yPos = el.getTop();
}
else if (align === 'br' || align === 'bl' || align === 'b') {
yPos += anchorEl.getAnchorXY('b')[1];
yPos -= (el.getHeight() + me.paddingY);
} else {
yPos += anchorEl.getAnchorXY('t')[1];
yPos += me.paddingY;
}
}
return yPos;
},
getXposAlignedToSibling: function(sibling) {
var me = this,
align = me.align,
el = me.el,
xPos;
if (!me.useXAxis) {
xPos = el.getLeft();
} else if (align === 'tl' || align === 'bl' || align === 'l') {
xPos = (sibling.xPos + sibling.el.getWidth() + sibling.spacing);
} else {
xPos = (sibling.xPos - el.getWidth() - me.spacing);
}
return xPos;
},
getYposAlignedToSibling: function(sibling) {
var me = this,
align = me.align,
el = me.el,
yPos;
if (me.useXAxis) {
yPos = el.getTop();
} else if (align === 'tr' || align === 'tl' || align === 't') {
yPos = (sibling.yPos + sibling.el.getHeight() + sibling.spacing);
} else {
yPos = (sibling.yPos - el.getHeight() - sibling.spacing);
}
return yPos;
},
getToasts: function() {
var anchor = this.anchor,
alignment = this.anchorAlign,
activeToasts = anchor.activeToasts || (anchor.activeToasts = {});
return activeToasts[alignment] || (activeToasts[alignment] = []);
},
setAnchor: function(anchor) {
var me = this,
Toast;
me.anchor = anchor = ((typeof anchor === 'string') ? Ext.getCmp(anchor) : anchor);
if (!anchor) {
Toast = Ext.window.Toast;
me.anchor = Toast.bodyAnchor || (Toast.bodyAnchor = {
el: Ext.getBody()
});
}
},
beforeShow: function() {
var me = this;
if (me.stickOnClick) {
me.body.on('click', function() {
me.cancelAutoClose();
});
}
if (me.autoClose) {
if (!me.closeTask) {
me.closeTask = new Ext.util.DelayedTask(me.doAutoClose, me);
}
me.closeTask.delay(me.autoCloseDelay);
}
me.el.setX(-10000);
me.el.setOpacity(1);
},
afterShow: function() {
var me = this,
el = me.el,
activeToasts, sibling, length, xy;
me.callParent(arguments);
activeToasts = me.getToasts();
length = activeToasts.length;
sibling = length && activeToasts[length - 1];
if (sibling) {
el.alignTo(sibling.el, me.siblingAlignment, [
0,
0
]);
me.xPos = me.getXposAlignedToSibling(sibling);
me.yPos = me.getYposAlignedToSibling(sibling);
} else {
el.alignTo(me.anchor.el, me.anchorAlign, [
(me.paddingX * me.paddingFactorX),
(me.paddingY * me.paddingFactorY)
], false);
me.xPos = me.getXposAlignedToAnchor();
me.yPos = me.getYposAlignedToAnchor();
}
Ext.Array.include(activeToasts, me);
if (me.animate) {
xy = el.getXY();
el.animate({
from: {
x: xy[0],
y: xy[1]
},
to: {
x: me.xPos,
y: me.yPos,
opacity: 1
},
easing: me.slideInAnimation,
duration: me.slideInDuration,
dynamic: true
});
} else {
me.setLocalXY(me.xPos, me.yPos);
}
},
onDocumentMousedown: function(e) {
if (this.isVisible() && !this.owns(e.getTarget())) {
this.hide();
}
},
slideBack: function() {
var me = this,
anchor = me.anchor,
anchorEl = anchor && anchor.el,
el = me.el,
activeToasts = me.getToasts(),
index = Ext.Array.indexOf(activeToasts, me);
if (!me.isHiding && el && el.dom && anchorEl && anchorEl.isVisible()) {
if (index) {
me.xPos = me.getXposAlignedToSibling(activeToasts[index - 1]);
me.yPos = me.getYposAlignedToSibling(activeToasts[index - 1]);
} else {
me.xPos = me.getXposAlignedToAnchor();
me.yPos = me.getYposAlignedToAnchor();
}
me.stopAnimation();
if (me.animate) {
el.animate({
to: {
x: me.xPos,
y: me.yPos
},
easing: me.slideBackAnimation,
duration: me.slideBackDuration,
dynamic: true
});
}
}
},
update: function() {
var me = this;
if (me.isVisible()) {
me.isHiding = true;
me.hide();
}
me.callParent(arguments);
me.show();
},
cancelAutoClose: function() {
var closeTask = this.closeTask;
if (closeTask) {
closeTask.cancel();
}
},
doAutoClose: function() {
var me = this;
if (!(me.stickWhileHover && me.mouseIsOver)) {
me.close();
} else {
me.closeOnMouseOut = true;
}
},
onMouseEnter: function() {
this.mouseIsOver = true;
},
onMouseLeave: function() {
var me = this;
me.mouseIsOver = false;
if (me.closeOnMouseOut) {
me.closeOnMouseOut = false;
me.close();
}
},
removeFromAnchor: function() {
var me = this,
activeToasts, index;
if (me.anchor) {
activeToasts = me.getToasts();
index = Ext.Array.indexOf(activeToasts, me);
if (index !== -1) {
Ext.Array.erase(activeToasts, index, 1);
for (; index < activeToasts.length; index++) {
activeToasts[index].slideBack();
}
}
}
},
getFocusEl: Ext.emptyFn,
hide: function() {
var me = this,
el = me.el;
me.cancelAutoClose();
if (me.isHiding) {
if (!me.isFading) {
me.callParent(arguments);
me.removeFromAnchor();
me.isHiding = false;
}
} else {
me.isHiding = true;
me.isFading = true;
me.cancelAutoClose();
if (el) {
if (me.animate) {
el.fadeOut({
opacity: 0,
easing: 'easeIn',
duration: me.hideDuration,
listeners: {
afteranimate: function() {
me.isFading = false;
me.hide(me.animateTarget, me.doClose, me);
}
}
});
} else {
me.isFading = false;
me.hide(me.animateTarget, me.doClose, me);
}
}
}
return me;
}
}, function(Toast) {
Ext.toast = function(message, title, align, iconCls) {
var config = message,
toast;
if (Ext.isString(message)) {
config = {
title: title,
html: message,
iconCls: iconCls
};
if (align) {
config.align = align;
}
}
toast = new Toast(config);
toast.show();
return toast;
};
});