]> git.proxmox.com Git - extjs.git/blame - extjs/build/ext-modern-all-debug.js
add extjs 6.0.1 sources
[extjs.git] / extjs / build / ext-modern-all-debug.js
CommitLineData
6527f429
DM
1/*\r
2This file is part of Ext JS 6.0.1.250\r
3\r
4Copyright (c) 2011-2015 Sencha Inc\r
5\r
6Contact: http://www.sencha.com/contact\r
7\r
8GNU General Public License Usage\r
9This file may be used under the terms of the GNU General Public License version 3.0 as\r
10published by the Free Software Foundation and appearing in the file LICENSE included in the\r
11packaging of this file.\r
12\r
13Please review the following information to ensure the GNU General Public License version 3.0\r
14requirements will be met: http://www.gnu.org/copyleft/gpl.html.\r
15\r
16If you are unsure which license is appropriate for your use, please contact the sales department\r
17at http://www.sencha.com/contact.\r
18\r
19Version: 6.0.1.250 Build date: 2015-09-02 17:27:43 (22ef9ff0ebf584ff525541be37e753a703cc044b)\r
20\r
21*/\r
22// @tag core
23
24
25var Ext = Ext || {};\r
26
27\r
28Ext.Boot = Ext.Boot || (function(emptyFn) {\r
29 var doc = document,\r
30 _emptyArray = [],\r
31 _config = {\r
32 \r
33 disableCaching: (/[?&](?:cache|disableCacheBuster)\b/i.test(location.search) || !(/http[s]?\:/i.test(location.href)) || /(^|[ ;])ext-cache=1/.test(doc.cookie)) ? false : true,\r
34 \r
35 disableCachingParam: '_dc',\r
36 \r
37 loadDelay: false,\r
38 \r
39 preserveScripts: true,\r
40 \r
41 charset: 'UTF-8'\r
42 },\r
43 _assetConfig = {},\r
44 cssRe = /\.css(?:\?|$)/i,\r
45 resolverEl = doc.createElement('a'),\r
46 isBrowser = typeof window !== 'undefined',\r
47 _environment = {\r
48 browser: isBrowser,\r
49 node: !isBrowser && (typeof require === 'function'),\r
50 phantom: (window && (window._phantom || window.callPhantom)) || /PhantomJS/.test(window.navigator.userAgent)\r
51 },\r
52 _tags = (Ext.platformTags = {}),\r
53
54 _debug = function(message) {},\r
55
56
57 _apply = function(object, config, defaults) {\r
58 if (defaults) {\r
59 _apply(object, defaults);\r
60 }\r
61 if (object && config && typeof config === 'object') {\r
62 for (var i in config) {\r
63 object[i] = config[i];\r
64 }\r
65 }\r
66 return object;\r
67 },\r
68 _merge = function() {\r
69 var lowerCase = false,\r
70 obj = Array.prototype.shift.call(arguments),\r
71 index, i, len, value;\r
72 if (typeof arguments[arguments.length - 1] === 'boolean') {\r
73 lowerCase = Array.prototype.pop.call(arguments);\r
74 }\r
75 len = arguments.length;\r
76 for (index = 0; index < len; index++) {\r
77 value = arguments[index];\r
78 if (typeof value === 'object') {\r
79 for (i in value) {\r
80 obj[lowerCase ? i.toLowerCase() : i] = value[i];\r
81 }\r
82 }\r
83 }\r
84 return obj;\r
85 },\r
86 _getKeys = (typeof Object.keys == 'function') ? function(object) {\r
87 if (!object) {\r
88 return [];\r
89 }\r
90 return Object.keys(object);\r
91 } : function(object) {\r
92 var keys = [],\r
93 property;\r
94 for (property in object) {\r
95 if (object.hasOwnProperty(property)) {\r
96 keys.push(property);\r
97 }\r
98 }\r
99 return keys;\r
100 },\r
101 \r
102 Boot = {\r
103 loading: 0,\r
104 loaded: 0,\r
105 apply: _apply,\r
106 env: _environment,\r
107 config: _config,\r
108 \r
109 assetConfig: _assetConfig,\r
110
111
112 scripts: {},\r
113 \r
114 \r
115 currentFile: null,\r
116 suspendedQueue: [],\r
117 currentRequest: null,\r
118
119
120 syncMode: false,\r
121 \r
122
123 debug: _debug,\r
124
125 \r
126 useElements: true,\r
127 listeners: [],\r
128 Request: Request,\r
129 Entry: Entry,\r
130 allowMultipleBrowsers: false,\r
131 browserNames: {\r
132 ie: 'IE',\r
133 firefox: 'Firefox',\r
134 safari: 'Safari',\r
135 chrome: 'Chrome',\r
136 opera: 'Opera',\r
137 dolfin: 'Dolfin',\r
138 edge: 'Edge',\r
139 webosbrowser: 'webOSBrowser',\r
140 chromeMobile: 'ChromeMobile',\r
141 chromeiOS: 'ChromeiOS',\r
142 silk: 'Silk',\r
143 other: 'Other'\r
144 },\r
145 osNames: {\r
146 ios: 'iOS',\r
147 android: 'Android',\r
148 windowsPhone: 'WindowsPhone',\r
149 webos: 'webOS',\r
150 blackberry: 'BlackBerry',\r
151 rimTablet: 'RIMTablet',\r
152 mac: 'MacOS',\r
153 win: 'Windows',\r
154 tizen: 'Tizen',\r
155 linux: 'Linux',\r
156 bada: 'Bada',\r
157 chromeOS: 'ChromeOS',\r
158 other: 'Other'\r
159 },\r
160 browserPrefixes: {\r
161 ie: 'MSIE ',\r
162 edge: 'Edge/',\r
163 firefox: 'Firefox/',\r
164 chrome: 'Chrome/',\r
165 safari: 'Version/',\r
166 opera: 'OPR/',\r
167 dolfin: 'Dolfin/',\r
168 webosbrowser: 'wOSBrowser/',\r
169 chromeMobile: 'CrMo/',\r
170 chromeiOS: 'CriOS/',\r
171 silk: 'Silk/'\r
172 },\r
173
174
175 browserPriority: [\r
176 'edge',\r
177 'opera',\r
178 'dolfin',\r
179 'webosbrowser',\r
180 'silk',\r
181 'chromeiOS',\r
182 'chromeMobile',\r
183 'ie',\r
184 'firefox',\r
185 'safari',\r
186 'chrome'\r
187 ],\r
188 osPrefixes: {\r
189 tizen: '(Tizen )',\r
190 ios: 'i(?:Pad|Phone|Pod)(?:.*)CPU(?: iPhone)? OS ',\r
191 android: '(Android |HTC_|Silk/)',\r
192
193
194 windowsPhone: 'Windows Phone ',\r
195 blackberry: '(?:BlackBerry|BB)(?:.*)Version/',\r
196 rimTablet: 'RIM Tablet OS ',\r
197 webos: '(?:webOS|hpwOS)/',\r
198 bada: 'Bada/',\r
199 chromeOS: 'CrOS '\r
200 },\r
201 fallbackOSPrefixes: {\r
202 windows: 'win',\r
203 mac: 'mac',\r
204 linux: 'linux'\r
205 },\r
206 devicePrefixes: {\r
207 iPhone: 'iPhone',\r
208 iPod: 'iPod',\r
209 iPad: 'iPad'\r
210 },\r
211 maxIEVersion: 12,\r
212 \r
213 detectPlatformTags: function() {\r
214 var me = this,\r
215 ua = navigator.userAgent,\r
216 isMobile = /Mobile(\/|\s)/.test(ua),\r
217 element = document.createElement('div'),\r
218 isEventSupported = function(name, tag) {\r
219 if (tag === undefined) {\r
220 tag = window;\r
221 }\r
222 var eventName = 'on' + name.toLowerCase(),\r
223 isSupported = (eventName in element);\r
224 if (!isSupported) {\r
225 if (element.setAttribute && element.removeAttribute) {\r
226 element.setAttribute(eventName, '');\r
227 isSupported = typeof element[eventName] === 'function';\r
228 if (typeof element[eventName] !== 'undefined') {\r
229 element[eventName] = undefined;\r
230 }\r
231 element.removeAttribute(eventName);\r
232 }\r
233 }\r
234 return isSupported;\r
235 },\r
236
237 getBrowsers = function() {\r
238 var browsers = {},\r
239 maxIEVersion, prefix, value, key, index, len, match, version, matched;\r
240
241
242
243 len = me.browserPriority.length;\r
244 for (index = 0; index < len; index++) {\r
245 key = me.browserPriority[index];\r
246 if (!matched) {\r
247 value = me.browserPrefixes[key];\r
248 match = ua.match(new RegExp('(' + value + ')([\\w\\._]+)'));\r
249 version = match && match.length > 1 ? parseInt(match[2]) : 0;\r
250 if (version) {\r
251 matched = true;\r
252 }\r
253 } else {\r
254 version = 0;\r
255 }\r
256 browsers[key] = version;\r
257 }\r
258
259 if (browsers.ie) {\r
260 var mode = document.documentMode;\r
261 if (mode >= 8) {\r
262 browsers.ie = mode;\r
263 }\r
264 }\r
265
266 version = browsers.ie || false;\r
267 maxIEVersion = Math.max(version, me.maxIEVersion);\r
268 for (index = 8; index <= maxIEVersion; ++index) {\r
269 prefix = 'ie' + index;\r
270 browsers[prefix + 'm'] = version ? version <= index : 0;\r
271 browsers[prefix] = version ? version === index : 0;\r
272 browsers[prefix + 'p'] = version ? version >= index : 0;\r
273 }\r
274 return browsers;\r
275 },\r
276
277 getOperatingSystems = function() {\r
278 var systems = {},\r
279 value, key, keys, index, len, match, matched, version, activeCount;\r
280 keys = _getKeys(me.osPrefixes);\r
281 len = keys.length;\r
282 for (index = 0 , activeCount = 0; index < len; index++) {\r
283 key = keys[index];\r
284 value = me.osPrefixes[key];\r
285 match = ua.match(new RegExp('(' + value + ')([^\\s;]+)'));\r
286 matched = match ? match[1] : null;\r
287
288
289 if (matched && (matched === 'HTC_' || matched === 'Silk/')) {\r
290 version = 2.3;\r
291 } else {\r
292 version = match && match.length > 1 ? parseFloat(match[match.length - 1]) : 0;\r
293 }\r
294 if (version) {\r
295 activeCount++;\r
296 }\r
297 systems[key] = version;\r
298 }\r
299 keys = _getKeys(me.fallbackOSPrefixes);\r
300
301
302 len = keys.length;\r
303 for (index = 0; index < len; index++) {\r
304 key = keys[index];\r
305
306 if (activeCount === 0) {\r
307 value = me.fallbackOSPrefixes[key];\r
308 match = ua.toLowerCase().match(new RegExp(value));\r
309 systems[key] = match ? true : 0;\r
310 } else {\r
311 systems[key] = 0;\r
312 }\r
313 }\r
314 return systems;\r
315 },\r
316
317 getDevices = function() {\r
318 var devices = {},\r
319 value, key, keys, index, len, match;\r
320 keys = _getKeys(me.devicePrefixes);\r
321 len = keys.length;\r
322 for (index = 0; index < len; index++) {\r
323 key = keys[index];\r
324 value = me.devicePrefixes[key];\r
325 match = ua.match(new RegExp(value));\r
326 devices[key] = match ? true : 0;\r
327 }\r
328 return devices;\r
329 },\r
330 browsers = getBrowsers(),\r
331 systems = getOperatingSystems(),\r
332 devices = getDevices(),\r
333 platformParams = Boot.loadPlatformsParam();\r
334
335
336 _merge(_tags, browsers, systems, devices, platformParams, true);\r
337 _tags.phone = (_tags.iphone || _tags.ipod) || (!_tags.silk && (_tags.android && (_tags.android < 3 || isMobile))) || (_tags.blackberry && isMobile) || (_tags.windowsphone);\r
338 _tags.tablet = !_tags.phone && (_tags.ipad || _tags.android || _tags.silk || _tags.rimtablet || (_tags.ie10 && /; Touch/.test(ua)));\r
339 _tags.touch =
340
341 isEventSupported('touchend') ||
342
343
344 navigator.maxTouchPoints ||
345 navigator.msMaxTouchPoints;\r
346 _tags.desktop = !_tags.phone && !_tags.tablet;\r
347 _tags.cordova = _tags.phonegap = !!(window.PhoneGap || window.Cordova || window.cordova);\r
348 _tags.webview = /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)(?!.*FBAN)/i.test(ua);\r
349 _tags.androidstock = (_tags.android <= 4.3) && (_tags.safari || _tags.silk);\r
350
351 _merge(_tags, platformParams, true);\r
352 },\r
353 \r
354 loadPlatformsParam: function() {\r
355
356 var paramsString = window.location.search.substr(1),\r
357 paramsArray = paramsString.split("&"),\r
358 params = {},\r
359 i,\r
360 platforms = {},\r
361 tmpArray, tmplen, platform, name, enabled;\r
362 for (i = 0; i < paramsArray.length; i++) {\r
363 tmpArray = paramsArray[i].split("=");\r
364 params[tmpArray[0]] = tmpArray[1];\r
365 }\r
366 if (params.platformTags) {\r
367 tmpArray = params.platformTags.split(",");\r
368 for (tmplen = tmpArray.length , i = 0; i < tmplen; i++) {\r
369 platform = tmpArray[i].split(":");\r
370 name = platform[0];\r
371 enabled = true;\r
372 if (platform.length > 1) {\r
373 enabled = platform[1];\r
374 if (enabled === 'false' || enabled === '0') {\r
375 enabled = false;\r
376 }\r
377 }\r
378 platforms[name] = enabled;\r
379 }\r
380 }\r
381 return platforms;\r
382 },\r
383 filterPlatform: function(platform, excludes) {\r
384 platform = _emptyArray.concat(platform || _emptyArray);\r
385 excludes = _emptyArray.concat(excludes || _emptyArray);\r
386 var plen = platform.length,\r
387 elen = excludes.length,\r
388 include = (!plen && elen),\r
389
390 i, tag;\r
391 for (i = 0; i < plen && !include; i++) {\r
392 tag = platform[i];\r
393 include = !!_tags[tag];\r
394 }\r
395 for (i = 0; i < elen && include; i++) {\r
396 tag = excludes[i];\r
397 include = !_tags[tag];\r
398 }\r
399 return include;\r
400 },\r
401 init: function() {\r
402 var scriptEls = doc.getElementsByTagName('script'),\r
403 len = scriptEls.length,\r
404 re = /\/ext(\-[a-z\-]+)?\.js$/,\r
405 entry, script, src, state, baseUrl, key, n, origin;\r
406
407
408
409 for (n = 0; n < len; n++) {\r
410 src = (script = scriptEls[n]).src;\r
411 if (!src) {\r
412 \r
413 continue;\r
414 }\r
415 state = script.readyState || null;\r
416
417 if (!baseUrl) {\r
418 if (re.test(src)) {\r
419 Boot.hasReadyState = ("readyState" in script);\r
420 Boot.hasAsync = ("async" in script) || !Boot.hasReadyState;\r
421 baseUrl = src;\r
422 }\r
423 }\r
424 if (!Boot.scripts[key = Boot.canonicalUrl(src)]) {\r
425
426 _debug("creating entry " + key + " in Boot.init");\r
427
428 entry = new Entry({\r
429 key: key,\r
430 url: src,\r
431 done: state === null ||
432 state === 'loaded' || state === 'complete',\r
433
434 el: script,\r
435 prop: 'src'\r
436 });\r
437 }\r
438 }\r
439 if (!baseUrl) {\r
440 script = scriptEls[scriptEls.length - 1];\r
441 baseUrl = script.src;\r
442 Boot.hasReadyState = ('readyState' in script);\r
443 Boot.hasAsync = ("async" in script) || !Boot.hasReadyState;\r
444 }\r
445 Boot.baseUrl = baseUrl.substring(0, baseUrl.lastIndexOf('/') + 1);\r
446 origin = window.location.origin || window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port : '');\r
447 Boot.origin = origin;\r
448 Boot.detectPlatformTags();\r
449 Ext.filterPlatform = Boot.filterPlatform;\r
450 },\r
451 \r
452 canonicalUrl: function(url) {\r
453
454
455 resolverEl.href = url;\r
456 var ret = resolverEl.href,\r
457 dc = _config.disableCachingParam,\r
458 pos = dc ? ret.indexOf(dc + '=') : -1,\r
459 c, end;\r
460
461
462 if (pos > 0 && ((c = ret.charAt(pos - 1)) === '?' || c === '&')) {\r
463 end = ret.indexOf('&', pos);\r
464 end = (end < 0) ? '' : ret.substring(end);\r
465 if (end && c === '?') {\r
466 ++pos;\r
467
468 end = end.substring(1);\r
469 }\r
470
471 ret = ret.substring(0, pos - 1) + end;\r
472 }\r
473 return ret;\r
474 },\r
475 \r
476 getConfig: function(name) {\r
477 return name ? Boot.config[name] : Boot.config;\r
478 },\r
479 \r
480 setConfig: function(name, value) {\r
481 if (typeof name === 'string') {\r
482 Boot.config[name] = value;\r
483 } else {\r
484 for (var s in name) {\r
485 Boot.setConfig(s, name[s]);\r
486 }\r
487 }\r
488 return Boot;\r
489 },\r
490 getHead: function() {\r
491 return Boot.docHead || (Boot.docHead = doc.head || doc.getElementsByTagName('head')[0]);\r
492 },\r
493 create: function(url, key, cfg) {\r
494 var config = cfg || {};\r
495 config.url = url;\r
496 config.key = key;\r
497 return Boot.scripts[key] = new Entry(config);\r
498 },\r
499 getEntry: function(url, cfg) {\r
500 var key = Boot.canonicalUrl(url),\r
501 entry = Boot.scripts[key];\r
502 if (!entry) {\r
503 entry = Boot.create(url, key, cfg);\r
504 }\r
505 return entry;\r
506 },\r
507 registerContent: function(url, type, content) {\r
508 var cfg = {\r
509 content: content,\r
510 loaded: true,\r
511 css: type === 'css'\r
512 };\r
513 return Boot.getEntry(url, cfg);\r
514 },\r
515 processRequest: function(request, sync) {\r
516 request.loadEntries(sync);\r
517 },\r
518 load: function(request) {\r
519
520 _debug("Boot.load called");\r
521
522 var request = new Request(request);\r
523 if (request.sync || Boot.syncMode) {\r
524 return Boot.loadSync(request);\r
525 }\r
526
527
528 if (Boot.currentRequest) {\r
529
530 _debug("current active request, suspending this request");\r
531
532
533
534
535 request.getEntries();\r
536 Boot.suspendedQueue.push(request);\r
537 } else {\r
538 Boot.currentRequest = request;\r
539 Boot.processRequest(request, false);\r
540 }\r
541 return Boot;\r
542 },\r
543 loadSync: function(request) {\r
544
545 _debug("Boot.loadSync called");\r
546
547 var request = new Request(request);\r
548 Boot.syncMode++;\r
549 Boot.processRequest(request, true);\r
550 Boot.syncMode--;\r
551 return Boot;\r
552 },\r
553 loadBasePrefix: function(request) {\r
554 request = new Request(request);\r
555 request.prependBaseUrl = true;\r
556 return Boot.load(request);\r
557 },\r
558 loadSyncBasePrefix: function(request) {\r
559 request = new Request(request);\r
560 request.prependBaseUrl = true;\r
561 return Boot.loadSync(request);\r
562 },\r
563 requestComplete: function(request) {\r
564 var next;\r
565 if (Boot.currentRequest === request) {\r
566 Boot.currentRequest = null;\r
567 while (Boot.suspendedQueue.length > 0) {\r
568 next = Boot.suspendedQueue.shift();\r
569 if (!next.done) {\r
570
571 _debug("resuming suspended request");\r
572
573 Boot.load(next);\r
574 break;\r
575 }\r
576 }\r
577 }\r
578 if (!Boot.currentRequest && Boot.suspendedQueue.length == 0) {\r
579 Boot.fireListeners();\r
580 }\r
581 },\r
582 isLoading: function() {\r
583 return !Boot.currentRequest && Boot.suspendedQueue.length == 0;\r
584 },\r
585 fireListeners: function() {\r
586 var listener;\r
587 while (Boot.isLoading() && (listener = Boot.listeners.shift())) {\r
588 listener();\r
589 }\r
590 },\r
591 onBootReady: function(listener) {\r
592 if (!Boot.isLoading()) {\r
593 listener();\r
594 } else {\r
595 Boot.listeners.push(listener);\r
596 }\r
597 },\r
598 \r
599 getPathsFromIndexes: function(indexMap, loadOrder) {\r
600 return Request.prototype.getPathsFromIndexes(indexMap, loadOrder);\r
601 },\r
602 createLoadOrderMap: function(loadOrder) {\r
603 return Request.prototype.createLoadOrderMap(loadOrder);\r
604 },\r
605 fetch: function(url, complete, scope, async) {\r
606 async = (async === undefined) ? !!complete : async;\r
607 var xhr = new XMLHttpRequest(),\r
608 result, status, content,\r
609 exception = false,\r
610 readyStateChange = function() {\r
611 if (xhr && xhr.readyState == 4) {\r
612 status = (xhr.status === 1223) ? 204 : (xhr.status === 0 && ((self.location || {}).protocol === 'file:' || (self.location || {}).protocol === 'ionp:')) ? 200 : xhr.status;\r
613 content = xhr.responseText;\r
614 result = {\r
615 content: content,\r
616 status: status,\r
617 exception: exception\r
618 };\r
619 if (complete) {\r
620 complete.call(scope, result);\r
621 }\r
622 xhr = null;\r
623 }\r
624 };\r
625 if (async) {\r
626 xhr.onreadystatechange = readyStateChange;\r
627 }\r
628 try {\r
629
630 _debug("fetching " + url + " " + (async ? "async" : "sync"));\r
631
632 xhr.open('GET', url, async);\r
633 xhr.send(null);\r
634 } catch (err) {\r
635 exception = err;\r
636 readyStateChange();\r
637 return result;\r
638 }\r
639 if (!async) {\r
640 readyStateChange();\r
641 }\r
642 return result;\r
643 },\r
644 notifyAll: function(entry) {\r
645 entry.notifyRequests();\r
646 }\r
647 };\r
648 \r
649 function Request(cfg) {\r
650 if (cfg.$isRequest) {\r
651 return cfg;\r
652 }\r
653 var cfg = cfg.url ? cfg : {\r
654 url: cfg\r
655 },\r
656 url = cfg.url,\r
657 urls = url.charAt ? [\r
658 url\r
659 ] : url,\r
660 charset = cfg.charset || Boot.config.charset;\r
661 _apply(cfg, {\r
662 urls: urls,\r
663 charset: charset\r
664 });\r
665 _apply(this, cfg);\r
666 }\r
667 \r
668 Request.prototype = {\r
669 $isRequest: true,\r
670 \r
671 createLoadOrderMap: function(loadOrder) {\r
672 var len = loadOrder.length,\r
673 loadOrderMap = {},\r
674 i, element;\r
675 for (i = 0; i < len; i++) {\r
676 element = loadOrder[i];\r
677 loadOrderMap[element.path] = element;\r
678 }\r
679 return loadOrderMap;\r
680 },\r
681 \r
682 getLoadIndexes: function(index, indexMap, loadOrder, includeUses, skipLoaded) {\r
683 var item = loadOrder[index],\r
684 len, i, reqs, entry, stop, added, idx, ridx, url;\r
685 if (indexMap[index]) {\r
686
687 return indexMap;\r
688 }\r
689 indexMap[index] = true;\r
690 stop = false;\r
691 while (!stop) {\r
692 added = false;\r
693
694
695 for (idx in indexMap) {\r
696 if (indexMap.hasOwnProperty(idx)) {\r
697 item = loadOrder[idx];\r
698 if (!item) {\r
699 \r
700 continue;\r
701 }\r
702 url = this.prepareUrl(item.path);\r
703 entry = Boot.getEntry(url);\r
704 if (!skipLoaded || !entry || !entry.done) {\r
705 reqs = item.requires;\r
706 if (includeUses && item.uses) {\r
707 reqs = reqs.concat(item.uses);\r
708 }\r
709 for (len = reqs.length , i = 0; i < len; i++) {\r
710 ridx = reqs[i];\r
711
712
713
714
715 if (!indexMap[ridx]) {\r
716 indexMap[ridx] = true;\r
717 added = true;\r
718 }\r
719 }\r
720 }\r
721 }\r
722 }\r
723
724
725 if (!added) {\r
726 stop = true;\r
727 }\r
728 }\r
729 return indexMap;\r
730 },\r
731 getPathsFromIndexes: function(indexMap, loadOrder) {\r
732 var indexes = [],\r
733 paths = [],\r
734 index, len, i;\r
735 for (index in indexMap) {\r
736 if (indexMap.hasOwnProperty(index) && indexMap[index]) {\r
737 indexes.push(index);\r
738 }\r
739 }\r
740 indexes.sort(function(a, b) {\r
741 return a - b;\r
742 });\r
743
744 for (len = indexes.length , i = 0; i < len; i++) {\r
745 paths.push(loadOrder[indexes[i]].path);\r
746 }\r
747 return paths;\r
748 },\r
749 expandUrl: function(url, indexMap, includeUses, skipLoaded) {\r
750 if (typeof url == 'string') {\r
751 url = [\r
752 url\r
753 ];\r
754 }\r
755 var me = this,\r
756 loadOrder = me.loadOrder,\r
757 loadOrderMap = me.loadOrderMap;\r
758 if (loadOrder) {\r
759 loadOrderMap = loadOrderMap || me.createLoadOrderMap(loadOrder);\r
760 me.loadOrderMap = loadOrderMap;\r
761 indexMap = indexMap || {};\r
762 var len = url.length,\r
763 unmapped = [],\r
764 i, item;\r
765 for (i = 0; i < len; i++) {\r
766 item = loadOrderMap[url[i]];\r
767 if (item) {\r
768 me.getLoadIndexes(item.idx, indexMap, loadOrder, includeUses, skipLoaded);\r
769 } else {\r
770 unmapped.push(url[i]);\r
771 }\r
772 }\r
773 return me.getPathsFromIndexes(indexMap, loadOrder).concat(unmapped);\r
774 }\r
775 return url;\r
776 },\r
777 expandUrls: function(urls, includeUses) {\r
778 if (typeof urls == "string") {\r
779 urls = [\r
780 urls\r
781 ];\r
782 }\r
783 var expanded = [],\r
784 expandMap = {},\r
785 tmpExpanded,\r
786 len = urls.length,\r
787 i, t, tlen, tUrl;\r
788 for (i = 0; i < len; i++) {\r
789 tmpExpanded = this.expandUrl(urls[i], {}, includeUses, true);\r
790 for (t = 0 , tlen = tmpExpanded.length; t < tlen; t++) {\r
791 tUrl = tmpExpanded[t];\r
792 if (!expandMap[tUrl]) {\r
793 expandMap[tUrl] = true;\r
794 expanded.push(tUrl);\r
795 }\r
796 }\r
797 }\r
798 if (expanded.length == 0) {\r
799 expanded = urls;\r
800 }\r
801 return expanded;\r
802 },\r
803 expandLoadOrder: function() {\r
804 var me = this,\r
805 urls = me.urls,\r
806 expanded;\r
807 if (!me.expanded) {\r
808 expanded = this.expandUrls(urls, true);\r
809 me.expanded = true;\r
810 } else {\r
811 expanded = urls;\r
812 }\r
813 me.urls = expanded;\r
814
815
816 if (urls.length != expanded.length) {\r
817 me.sequential = true;\r
818 }\r
819 return me;\r
820 },\r
821 getUrls: function() {\r
822 this.expandLoadOrder();\r
823 return this.urls;\r
824 },\r
825 prepareUrl: function(url) {\r
826 if (this.prependBaseUrl) {\r
827 return Boot.baseUrl + url;\r
828 }\r
829 return url;\r
830 },\r
831 getEntries: function() {\r
832 var me = this,\r
833 entries = me.entries,\r
834 i, entry, urls, url;\r
835 if (!entries) {\r
836 entries = [];\r
837 urls = me.getUrls();\r
838 for (i = 0; i < urls.length; i++) {\r
839 url = me.prepareUrl(urls[i]);\r
840 entry = Boot.getEntry(url, {\r
841 buster: me.buster,\r
842 charset: me.charset\r
843 });\r
844 entry.requests.push(me);\r
845 entries.push(entry);\r
846 }\r
847 me.entries = entries;\r
848 }\r
849 return entries;\r
850 },\r
851 loadEntries: function(sync) {\r
852 var me = this,\r
853 entries = me.getEntries(),\r
854 len = entries.length,\r
855 start = me.loadStart || 0,\r
856 continueLoad, entry, i;\r
857 if (sync !== undefined) {\r
858 me.sync = sync;\r
859 }\r
860 me.loaded = me.loaded || 0;\r
861 me.loading = me.loading || len;\r
862 for (i = start; i < len; i++) {\r
863 entry = entries[i];\r
864 if (!entry.loaded) {\r
865 continueLoad = entries[i].load(me.sync);\r
866 } else {\r
867 continueLoad = true;\r
868 }\r
869 if (!continueLoad) {\r
870 me.loadStart = i;\r
871 entry.onDone(function() {\r
872 me.loadEntries(sync);\r
873 });\r
874 break;\r
875 }\r
876 }\r
877 me.processLoadedEntries();\r
878 },\r
879 processLoadedEntries: function() {\r
880 var me = this,\r
881 entries = me.getEntries(),\r
882 len = entries.length,\r
883 start = me.startIndex || 0,\r
884 i, entry;\r
885 if (!me.done) {\r
886 for (i = start; i < len; i++) {\r
887 entry = entries[i];\r
888 if (!entry.loaded) {\r
889 me.startIndex = i;\r
890 return;\r
891 }\r
892 if (!entry.evaluated) {\r
893 entry.evaluate();\r
894 }\r
895 if (entry.error) {\r
896 me.error = true;\r
897 }\r
898 }\r
899 me.notify();\r
900 }\r
901 },\r
902 notify: function() {\r
903 var me = this;\r
904 if (!me.done) {\r
905 var error = me.error,\r
906 fn = me[error ? 'failure' : 'success'],\r
907 delay = ('delay' in me) ? me.delay : (error ? 1 : Boot.config.chainDelay),\r
908 scope = me.scope || me;\r
909 me.done = true;\r
910 if (fn) {\r
911 if (delay === 0 || delay > 0) {\r
912
913 setTimeout(function() {\r
914 fn.call(scope, me);\r
915 }, delay);\r
916 } else {\r
917 fn.call(scope, me);\r
918 }\r
919 }\r
920 me.fireListeners();\r
921 Boot.requestComplete(me);\r
922 }\r
923 },\r
924 onDone: function(listener) {\r
925 var me = this,\r
926 listeners = me.listeners || (me.listeners = []);\r
927 if (me.done) {\r
928 listener(me);\r
929 } else {\r
930 listeners.push(listener);\r
931 }\r
932 },\r
933 fireListeners: function() {\r
934 var listeners = this.listeners,\r
935 listener;\r
936 if (listeners) {\r
937
938 _debug("firing request listeners");\r
939
940 while ((listener = listeners.shift())) {\r
941 listener(this);\r
942 }\r
943 }\r
944 }\r
945 };\r
946 \r
947 function Entry(cfg) {\r
948 if (cfg.$isEntry) {\r
949 return cfg;\r
950 }\r
951
952 _debug("creating entry for " + cfg.url);\r
953
954 var charset = cfg.charset || Boot.config.charset,\r
955 manifest = Ext.manifest,\r
956 loader = manifest && manifest.loader,\r
957 cache = (cfg.cache !== undefined) ? cfg.cache : (loader && loader.cache),\r
958 buster, busterParam;\r
959 if (Boot.config.disableCaching) {\r
960 if (cache === undefined) {\r
961 cache = !Boot.config.disableCaching;\r
962 }\r
963 if (cache === false) {\r
964 buster = +new Date();\r
965 } else if (cache !== true) {\r
966 buster = cache;\r
967 }\r
968 if (buster) {\r
969 busterParam = (loader && loader.cacheParam) || Boot.config.disableCachingParam;\r
970 buster = busterParam + "=" + buster;\r
971 }\r
972 }\r
973 _apply(cfg, {\r
974 charset: charset,\r
975 buster: buster,\r
976 requests: []\r
977 });\r
978 _apply(this, cfg);\r
979 }\r
980 \r
981 Entry.prototype = {\r
982 $isEntry: true,\r
983 done: false,\r
984 evaluated: false,\r
985 loaded: false,\r
986 isCrossDomain: function() {\r
987 var me = this;\r
988 if (me.crossDomain === undefined) {\r
989
990 _debug("checking " + me.getLoadUrl() + " for prefix " + Boot.origin);\r
991
992 me.crossDomain = (me.getLoadUrl().indexOf(Boot.origin) !== 0);\r
993 }\r
994 return me.crossDomain;\r
995 },\r
996 isCss: function() {\r
997 var me = this;\r
998 if (me.css === undefined) {\r
999 if (me.url) {\r
1000 var assetConfig = Boot.assetConfig[me.url];\r
1001 me.css = assetConfig ? assetConfig.type === "css" : cssRe.test(me.url);\r
1002 } else {\r
1003 me.css = false;\r
1004 }\r
1005 }\r
1006 return this.css;\r
1007 },\r
1008 getElement: function(tag) {\r
1009 var me = this,\r
1010 el = me.el;\r
1011 if (!el) {\r
1012
1013 _debug("creating element for " + me.url);\r
1014
1015 if (me.isCss()) {\r
1016 tag = tag || "link";\r
1017 el = doc.createElement(tag);\r
1018 if (tag == "link") {\r
1019 el.rel = 'stylesheet';\r
1020 me.prop = 'href';\r
1021 } else {\r
1022 me.prop = "textContent";\r
1023 }\r
1024 el.type = "text/css";\r
1025 } else {\r
1026 tag = tag || "script";\r
1027 el = doc.createElement(tag);\r
1028 el.type = 'text/javascript';\r
1029 me.prop = 'src';\r
1030 if (me.charset) {\r
1031 el.charset = me.charset;\r
1032 }\r
1033 if (Boot.hasAsync) {\r
1034 el.async = false;\r
1035 }\r
1036 }\r
1037 me.el = el;\r
1038 }\r
1039 return el;\r
1040 },\r
1041 getLoadUrl: function() {\r
1042 var me = this,\r
1043 url = Boot.canonicalUrl(me.url);\r
1044 if (!me.loadUrl) {\r
1045 me.loadUrl = !!me.buster ? (url + (url.indexOf('?') === -1 ? '?' : '&') + me.buster) : url;\r
1046 }\r
1047 return me.loadUrl;\r
1048 },\r
1049 fetch: function(req) {\r
1050 var url = this.getLoadUrl(),\r
1051 async = !!req.async,\r
1052 complete = req.complete;\r
1053 Boot.fetch(url, complete, this, async);\r
1054 },\r
1055 onContentLoaded: function(response) {\r
1056 var me = this,\r
1057 status = response.status,\r
1058 content = response.content,\r
1059 exception = response.exception,\r
1060 url = this.getLoadUrl();\r
1061 me.loaded = true;\r
1062 if ((exception || status === 0) && !_environment.phantom) {\r
1063 me.error =
1064 ("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.") ||
1065 true;\r
1066 me.evaluated = true;\r
1067 } else if ((status >= 200 && status < 300) || status === 304 || _environment.phantom || (status === 0 && content.length > 0)) {\r
1068 me.content = content;\r
1069 } else {\r
1070 me.error =
1071 ("Failed loading synchronously via XHR: '" + url + "'. Please verify that the file exists. XHR status code: " + status) ||
1072 true;\r
1073 me.evaluated = true;\r
1074 }\r
1075 },\r
1076 createLoadElement: function(callback) {\r
1077 var me = this,\r
1078 el = me.getElement(),\r
1079 readyStateChange = function() {\r
1080 if (this.readyState === 'loaded' || this.readyState === 'complete') {\r
1081 if (callback) {\r
1082 callback();\r
1083 }\r
1084 }\r
1085 },\r
1086 errorFn = function() {\r
1087 me.error = true;\r
1088 if (callback) {\r
1089 callback();\r
1090 }\r
1091 };\r
1092 me.preserve = true;\r
1093 el.onerror = errorFn;\r
1094 if (Boot.hasReadyState) {\r
1095 el.onreadystatechange = readyStateChange;\r
1096 } else {\r
1097 el.onload = callback;\r
1098 }\r
1099
1100 el[me.prop] = me.getLoadUrl();\r
1101 },\r
1102 onLoadElementReady: function() {\r
1103 Boot.getHead().appendChild(this.getElement());\r
1104 this.evaluated = true;\r
1105 },\r
1106 inject: function(content, asset) {\r
1107
1108 _debug("injecting content for " + this.url);\r
1109
1110 var me = this,\r
1111 head = Boot.getHead(),\r
1112 url = me.url,\r
1113 key = me.key,\r
1114 base, el, ieMode, basePath;\r
1115 if (me.isCss()) {\r
1116 me.preserve = true;\r
1117 basePath = key.substring(0, key.lastIndexOf("/") + 1);\r
1118 base = doc.createElement('base');\r
1119 base.href = basePath;\r
1120 if (head.firstChild) {\r
1121 head.insertBefore(base, head.firstChild);\r
1122 } else {\r
1123 head.appendChild(base);\r
1124 }\r
1125
1126 base.href = base.href;\r
1127 if (url) {\r
1128 content += "\n/*# sourceURL=" + key + " */";\r
1129 }\r
1130
1131 el = me.getElement("style");\r
1132 ieMode = ('styleSheet' in el);\r
1133 head.appendChild(base);\r
1134 if (ieMode) {\r
1135 head.appendChild(el);\r
1136 el.styleSheet.cssText = content;\r
1137 } else {\r
1138 el.textContent = content;\r
1139 head.appendChild(el);\r
1140 }\r
1141 head.removeChild(base);\r
1142 } else {\r
1143
1144
1145
1146 if (url) {\r
1147 content += "\n//# sourceURL=" + key;\r
1148 }\r
1149 Ext.globalEval(content);\r
1150 }\r
1151 return me;\r
1152 },\r
1153 loadCrossDomain: function() {\r
1154 var me = this,\r
1155 complete = function() {\r
1156 me.loaded = me.evaluated = me.done = true;\r
1157 me.notifyRequests();\r
1158 };\r
1159 me.createLoadElement(function() {\r
1160 complete();\r
1161 });\r
1162 me.evaluateLoadElement();\r
1163
1164
1165
1166 return false;\r
1167 },\r
1168 loadElement: function() {\r
1169 var me = this,\r
1170 complete = function() {\r
1171 me.loaded = me.evaluated = me.done = true;\r
1172 me.notifyRequests();\r
1173 };\r
1174 me.createLoadElement(function() {\r
1175 complete();\r
1176 });\r
1177 me.evaluateLoadElement();\r
1178 return true;\r
1179 },\r
1180 loadSync: function() {\r
1181 var me = this;\r
1182 me.fetch({\r
1183 async: false,\r
1184 complete: function(response) {\r
1185 me.onContentLoaded(response);\r
1186 }\r
1187 });\r
1188 me.evaluate();\r
1189 me.notifyRequests();\r
1190 },\r
1191 load: function(sync) {\r
1192 var me = this;\r
1193 if (!me.loaded) {\r
1194 if (me.loading) {\r
1195
1196
1197
1198
1199
1200
1201
1202 return false;\r
1203 }\r
1204 me.loading = true;\r
1205
1206 if (!sync) {\r
1207
1208
1209 if (me.isCrossDomain()) {\r
1210 return me.loadCrossDomain();\r
1211 }\r
1212
1213
1214
1215 else if (!me.isCss() && Boot.hasReadyState) {\r
1216 me.createLoadElement(function() {\r
1217 me.loaded = true;\r
1218 me.notifyRequests();\r
1219 });\r
1220 } else if (Boot.useElements &&
1221 !(me.isCss() && _environment.phantom)) {\r
1222 return me.loadElement();\r
1223 } else
1224
1225 {\r
1226 me.fetch({\r
1227 async: !sync,\r
1228 complete: function(response) {\r
1229 me.onContentLoaded(response);\r
1230 me.notifyRequests();\r
1231 }\r
1232 });\r
1233 }\r
1234 } else
1235
1236
1237 {\r
1238 me.loadSync();\r
1239 }\r
1240 }\r
1241
1242 return true;\r
1243 },\r
1244 evaluateContent: function() {\r
1245 this.inject(this.content);\r
1246 this.content = null;\r
1247 },\r
1248 evaluateLoadElement: function() {\r
1249 Boot.getHead().appendChild(this.getElement());\r
1250 },\r
1251 evaluate: function() {\r
1252 var me = this;\r
1253 if (!me.evaluated) {\r
1254 if (me.evaluating) {\r
1255 return;\r
1256 }\r
1257 me.evaluating = true;\r
1258 if (me.content !== undefined) {\r
1259 me.evaluateContent();\r
1260 } else if (!me.error) {\r
1261 me.evaluateLoadElement();\r
1262 }\r
1263 me.evaluated = me.done = true;\r
1264 me.cleanup();\r
1265 }\r
1266 },\r
1267 \r
1268 cleanup: function() {\r
1269 var me = this,\r
1270 el = me.el,\r
1271 prop;\r
1272 if (!el) {\r
1273 return;\r
1274 }\r
1275 if (!me.preserve) {\r
1276 me.el = null;\r
1277 el.parentNode.removeChild(el);\r
1278
1279 for (prop in el) {\r
1280 try {\r
1281 if (prop !== me.prop) {\r
1282
1283
1284 el[prop] = null;\r
1285 }\r
1286 delete el[prop];\r
1287 }
1288 catch (cleanEx) {}\r
1289 }\r
1290 }\r
1291
1292
1293
1294
1295 el.onload = el.onerror = el.onreadystatechange = emptyFn;\r
1296 },\r
1297 notifyRequests: function() {\r
1298 var requests = this.requests,\r
1299 len = requests.length,\r
1300 i, request;\r
1301 for (i = 0; i < len; i++) {\r
1302 request = requests[i];\r
1303 request.processLoadedEntries();\r
1304 }\r
1305 if (this.done) {\r
1306 this.fireListeners();\r
1307 }\r
1308 },\r
1309 onDone: function(listener) {\r
1310 var me = this,\r
1311 listeners = me.listeners || (me.listeners = []);\r
1312 if (me.done) {\r
1313 listener(me);\r
1314 } else {\r
1315 listeners.push(listener);\r
1316 }\r
1317 },\r
1318 fireListeners: function() {\r
1319 var listeners = this.listeners,\r
1320 listener;\r
1321 if (listeners && listeners.length > 0) {\r
1322
1323 _debug("firing event listeners for url " + this.url);\r
1324
1325 while ((listener = listeners.shift())) {\r
1326 listener(this);\r
1327 }\r
1328 }\r
1329 }\r
1330 };\r
1331 \r
1332 Ext.disableCacheBuster = function(disable, path) {\r
1333 var date = new Date();\r
1334 date.setTime(date.getTime() + (disable ? 10 * 365 : -1) * 24 * 60 * 60 * 1000);\r
1335 date = date.toGMTString();\r
1336 doc.cookie = 'ext-cache=1; expires=' + date + '; path=' + (path || '/');\r
1337 };\r
1338 Boot.init();\r
1339 return Boot;\r
1340}(
1341
1342function() {}));\r
1343
1344\r
1345Ext.globalEval = Ext.globalEval || (this.execScript ? function(code) {\r
1346 execScript(code);\r
1347} : function($$code) {\r
1348 eval.call(window, $$code);\r
1349});\r
1350
1351\r
1352if (!Function.prototype.bind) {\r
1353 (function() {\r
1354 var slice = Array.prototype.slice,\r
1355
1356
1357 bind = function(me) {\r
1358 var args = slice.call(arguments, 1),\r
1359 method = this;\r
1360 if (args.length) {\r
1361 return function() {\r
1362 var t = arguments;\r
1363
1364 return method.apply(me, t.length ? args.concat(slice.call(t)) : args);\r
1365 };\r
1366 }\r
1367
1368 args = null;\r
1369 return function() {\r
1370 return method.apply(me, arguments);\r
1371 };\r
1372 };\r
1373 Function.prototype.bind = bind;\r
1374 bind.$extjs = true;\r
1375 }());\r
1376}\r
1377
1378
1379
1380Ext.setResourcePath = function(poolName, path) {\r
1381 var manifest = Ext.manifest || (Ext.manifest = {}),\r
1382 paths = manifest.resources || (manifest.resources = {});\r
1383 if (manifest) {\r
1384 if (typeof poolName !== 'string') {\r
1385 Ext.apply(paths, poolName);\r
1386 } else {\r
1387 paths[poolName] = path;\r
1388 }\r
1389 manifest.resources = paths;\r
1390 }\r
1391};\r
1392Ext.getResourcePath = function(path, poolName, packageName) {\r
1393 if (typeof path !== 'string') {\r
1394 poolName = path.pool;\r
1395 packageName = path.packageName;\r
1396 path = path.path;\r
1397 }\r
1398 var manifest = Ext.manifest,\r
1399 paths = manifest && manifest.resources,\r
1400 poolPath = paths[poolName],\r
1401 output = [];\r
1402 if (poolPath == null) {\r
1403 poolPath = paths.path;\r
1404 if (poolPath == null) {\r
1405 poolPath = 'resources';\r
1406 }\r
1407 }\r
1408 if (poolPath) {\r
1409 output.push(poolPath);\r
1410 }\r
1411 if (packageName) {\r
1412 output.push(packageName);\r
1413 }\r
1414 output.push(path);\r
1415 return output.join('/');\r
1416};\r
1417\r
1418
1419\r
1420var Ext = Ext || {};\r
1421
1422
1423(function() {\r
1424 var global = this,\r
1425 objectPrototype = Object.prototype,\r
1426 toString = objectPrototype.toString,\r
1427 enumerables = [\r
1428
1429 'valueOf',\r
1430 'toLocaleString',\r
1431 'toString',\r
1432 'constructor'\r
1433 ],\r
1434 emptyFn = function() {},\r
1435 privateFn = function() {},\r
1436 identityFn = function(o) {\r
1437 return o;\r
1438 },\r
1439
1440
1441 callOverrideParent = function() {\r
1442 var method = callOverrideParent.caller.caller;\r
1443
1444 return method.$owner.prototype[method.$name].apply(this, arguments);\r
1445 },\r
1446 manifest = Ext.manifest || {},\r
1447 i,\r
1448 iterableRe = /\[object\s*(?:Array|Arguments|\w*Collection|\w*List|HTML\s+document\.all\s+class)\]/,\r
1449 MSDateRe = /^\\?\/Date\(([-+])?(\d+)(?:[+-]\d{4})?\)\\?\/$/;\r
1450 Ext.global = global;\r
1451 \r
1452 Ext.now = Date.now || (Date.now = function() {\r
1453 return +new Date();\r
1454 });\r
1455 \r
1456 Ext.ticks = (global.performance && global.performance.now) ? function() {\r
1457 return performance.now();\r
1458 } :
1459 Ext.now;\r
1460 Ext._startTime = Ext.ticks();\r
1461
1462 emptyFn.$nullFn = identityFn.$nullFn = emptyFn.$emptyFn = identityFn.$identityFn = privateFn.$nullFn = true;\r
1463 privateFn.$privacy = 'framework';\r
1464
1465
1466 Ext['suspendLayouts'] = Ext['resumeLayouts'] = emptyFn;\r
1467
1468 for (i in {\r
1469 toString: 1\r
1470 }) {\r
1471 enumerables = null;\r
1472 }\r
1473 \r
1474 Ext.enumerables = enumerables;\r
1475 \r
1476 Ext.apply = function(object, config, defaults) {\r
1477 if (defaults) {\r
1478 Ext.apply(object, defaults);\r
1479 }\r
1480 if (object && config && typeof config === 'object') {\r
1481 var i, j, k;\r
1482 for (i in config) {\r
1483 object[i] = config[i];\r
1484 }\r
1485 if (enumerables) {\r
1486 for (j = enumerables.length; j--; ) {\r
1487 k = enumerables[j];\r
1488 if (config.hasOwnProperty(k)) {\r
1489 object[k] = config[k];\r
1490 }\r
1491 }\r
1492 }\r
1493 }\r
1494 return object;\r
1495 };\r
1496
1497 function addInstanceOverrides(target, owner, overrides) {\r
1498 var name, value;\r
1499 for (name in overrides) {\r
1500 if (overrides.hasOwnProperty(name)) {\r
1501 value = overrides[name];\r
1502 if (typeof value === 'function') {\r
1503
1504 if (owner.$className) {\r
1505 value.name = owner.$className + '#' + name;\r
1506 }\r
1507
1508 value.$name = name;\r
1509 value.$owner = owner;\r
1510 value.$previous = target.hasOwnProperty(name) ? target[name] :
1511 callOverrideParent;\r
1512 }\r
1513
1514 target[name] = value;\r
1515 }\r
1516 }\r
1517 }\r
1518 Ext.buildSettings = Ext.apply({\r
1519 baseCSSPrefix: 'x-'\r
1520 }, Ext.buildSettings || {});\r
1521 Ext.apply(Ext, {\r
1522 \r
1523 idSeed: 0,\r
1524 \r
1525 idPrefix: 'ext-',\r
1526 \r
1527 isSecure: /^https/i.test(window.location.protocol),\r
1528 \r
1529 enableGarbageCollector: false,\r
1530 \r
1531 enableListenerCollection: true,\r
1532 \r
1533 name: Ext.sandboxName || 'Ext',\r
1534 \r
1535 privateFn: privateFn,\r
1536 \r
1537 emptyFn: emptyFn,\r
1538 \r
1539 identityFn: identityFn,\r
1540 \r
1541 frameStartTime: Ext.now(),\r
1542 \r
1543 manifest: manifest,\r
1544
1545 \r
1546 debugConfig: Ext.debugConfig || manifest.debug || {\r
1547 hooks: {\r
1548 '*': true\r
1549 }\r
1550 },\r
1551
1552 \r
1553 enableAria: true,\r
1554 \r
1555 enableAriaButtons: true,\r
1556 \r
1557 enableAriaPanels: true,\r
1558 startsWithHashRe: /^#/,\r
1559 \r
1560 validIdRe: /^[a-z_][a-z0-9\-_]*$/i,\r
1561 \r
1562 BLANK_IMAGE_URL: 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',\r
1563 \r
1564 makeIdSelector: function(id) {\r
1565
1566 if (!Ext.validIdRe.test(id)) {\r
1567 Ext.raise('Invalid id selector: "' + id + '"');\r
1568 }\r
1569
1570 return '#' + id;\r
1571 },\r
1572 \r
1573 id: function(o, prefix) {\r
1574 if (o && o.id) {\r
1575 return o.id;\r
1576 }\r
1577 var id = (prefix || Ext.idPrefix) + (++Ext.idSeed);\r
1578 if (o) {\r
1579 o.id = id;\r
1580 }\r
1581 return id;\r
1582 },\r
1583 \r
1584 returnId: function(o) {\r
1585 return o.getId();\r
1586 },\r
1587 \r
1588 returnTrue: function() {\r
1589 return true;\r
1590 },\r
1591 \r
1592 emptyString: new String(),\r
1593
1594 \r
1595 baseCSSPrefix: Ext.buildSettings.baseCSSPrefix,\r
1596 \r
1597 $eventNameMap: {},\r
1598
1599
1600 $vendorEventRe: /^(Moz.+|MS.+|webkit.+)/,\r
1601
1602 \r
1603 canonicalEventName: function(name) {\r
1604 return Ext.$eventNameMap[name] || (Ext.$eventNameMap[name] = (Ext.$vendorEventRe.test(name) ? name : name.toLowerCase()));\r
1605 },\r
1606 \r
1607 applyIf: function(object, config) {\r
1608 var property;\r
1609 if (object) {\r
1610 for (property in config) {\r
1611 if (object[property] === undefined) {\r
1612 object[property] = config[property];\r
1613 }\r
1614 }\r
1615 }\r
1616 return object;\r
1617 },\r
1618 \r
1619 destroy: function() {\r
1620 var ln = arguments.length,\r
1621 i, arg;\r
1622 for (i = 0; i < ln; i++) {\r
1623 arg = arguments[i];\r
1624 if (arg) {\r
1625 if (Ext.isArray(arg)) {\r
1626 this.destroy.apply(this, arg);\r
1627 } else if (Ext.isFunction(arg.destroy)) {\r
1628 arg.destroy();\r
1629 }\r
1630 }\r
1631 }\r
1632 return null;\r
1633 },\r
1634 \r
1635 destroyMembers: function(object) {\r
1636 for (var ref, name,\r
1637 i = 1,\r
1638 a = arguments,\r
1639 len = a.length; i < len; i++) {\r
1640 ref = object[name = a[i]];\r
1641
1642 if (ref != null) {\r
1643 object[name] = Ext.destroy(ref);\r
1644 }\r
1645 }\r
1646 },\r
1647 \r
1648 override: function(target, overrides) {\r
1649 if (target.$isClass) {\r
1650 target.override(overrides);\r
1651 } else if (typeof target === 'function') {\r
1652 Ext.apply(target.prototype, overrides);\r
1653 } else {\r
1654 var owner = target.self,\r
1655 privates;\r
1656 if (owner && owner.$isClass) {\r
1657
1658 privates = overrides.privates;\r
1659 if (privates) {\r
1660 overrides = Ext.apply({}, overrides);\r
1661 delete overrides.privates;\r
1662 addInstanceOverrides(target, owner, privates);\r
1663 }\r
1664 addInstanceOverrides(target, owner, overrides);\r
1665 } else {\r
1666 Ext.apply(target, overrides);\r
1667 }\r
1668 }\r
1669 return target;\r
1670 },\r
1671 \r
1672 valueFrom: function(value, defaultValue, allowBlank) {\r
1673 return Ext.isEmpty(value, allowBlank) ? defaultValue : value;\r
1674 },\r
1675 \r
1676 isEmpty: function(value, allowEmptyString) {\r
1677 return (value == null) || (!allowEmptyString ? value === '' : false) || (Ext.isArray(value) && value.length === 0);\r
1678 },\r
1679 \r
1680 isArray: ('isArray' in Array) ? Array.isArray : function(value) {\r
1681 return toString.call(value) === '[object Array]';\r
1682 },\r
1683 \r
1684 isDate: function(value) {\r
1685 return toString.call(value) === '[object Date]';\r
1686 },\r
1687 \r
1688 isMSDate: function(value) {\r
1689 if (!Ext.isString(value)) {\r
1690 return false;\r
1691 }\r
1692 return MSDateRe.test(value);\r
1693 },\r
1694 \r
1695 isObject: (toString.call(null) === '[object Object]') ? function(value) {\r
1696
1697 return value !== null && value !== undefined && toString.call(value) === '[object Object]' && value.ownerDocument === undefined;\r
1698 } : function(value) {\r
1699 return toString.call(value) === '[object Object]';\r
1700 },\r
1701 \r
1702 isSimpleObject: function(value) {\r
1703 return value instanceof Object && value.constructor === Object;\r
1704 },\r
1705 \r
1706 isPrimitive: function(value) {\r
1707 var type = typeof value;\r
1708 return type === 'string' || type === 'number' || type === 'boolean';\r
1709 },\r
1710 \r
1711 isFunction:
1712
1713 (typeof document !== 'undefined' && typeof document.getElementsByTagName('body') === 'function') ? function(value) {\r
1714 return !!value && toString.call(value) === '[object Function]';\r
1715 } : function(value) {\r
1716 return !!value && typeof value === 'function';\r
1717 },\r
1718 \r
1719 isNumber: function(value) {\r
1720 return typeof value === 'number' && isFinite(value);\r
1721 },\r
1722 \r
1723 isNumeric: function(value) {\r
1724 return !isNaN(parseFloat(value)) && isFinite(value);\r
1725 },\r
1726 \r
1727 isString: function(value) {\r
1728 return typeof value === 'string';\r
1729 },\r
1730 \r
1731 isBoolean: function(value) {\r
1732 return typeof value === 'boolean';\r
1733 },\r
1734 \r
1735 isElement: function(value) {\r
1736 return value ? value.nodeType === 1 : false;\r
1737 },\r
1738 \r
1739 isTextNode: function(value) {\r
1740 return value ? value.nodeName === "#text" : false;\r
1741 },\r
1742 \r
1743 isDefined: function(value) {\r
1744 return typeof value !== 'undefined';\r
1745 },\r
1746 \r
1747 isIterable: function(value) {\r
1748
1749 if (!value || typeof value.length !== 'number' || typeof value === 'string' || Ext.isFunction(value)) {\r
1750 return false;\r
1751 }\r
1752
1753
1754
1755 if (!value.propertyIsEnumerable) {\r
1756 return !!value.item;\r
1757 }\r
1758
1759
1760 if (value.hasOwnProperty('length') && !value.propertyIsEnumerable('length')) {\r
1761 return true;\r
1762 }\r
1763
1764 return iterableRe.test(toString.call(value));\r
1765 },\r
1766 \r
1767 isDebugEnabled:
1768 function(className, defaultEnabled) {\r
1769 var debugConfig = Ext.debugConfig.hooks;\r
1770 if (debugConfig.hasOwnProperty(className)) {\r
1771 return debugConfig[className];\r
1772 }\r
1773 var enabled = debugConfig['*'],\r
1774 prefixLength = 0;\r
1775 if (defaultEnabled !== undefined) {\r
1776 enabled = defaultEnabled;\r
1777 }\r
1778 if (!className) {\r
1779 return enabled;\r
1780 }\r
1781 for (var prefix in debugConfig) {\r
1782 var value = debugConfig[prefix];\r
1783
1784 if (className.charAt(prefix.length) === '.') {\r
1785 if (className.substring(0, prefix.length) === prefix) {\r
1786 if (prefixLength < prefix.length) {\r
1787 prefixLength = prefix.length;\r
1788 enabled = value;\r
1789 }\r
1790 }\r
1791 }\r
1792 }\r
1793 return enabled;\r
1794 } ||
1795 emptyFn,\r
1796 \r
1797 clone: function(item) {\r
1798 if (item === null || item === undefined) {\r
1799 return item;\r
1800 }\r
1801
1802
1803
1804 if (item.nodeType && item.cloneNode) {\r
1805 return item.cloneNode(true);\r
1806 }\r
1807 var type = toString.call(item),\r
1808 i, j, k, clone, key;\r
1809
1810 if (type === '[object Date]') {\r
1811 return new Date(item.getTime());\r
1812 }\r
1813
1814 if (type === '[object Array]') {\r
1815 i = item.length;\r
1816 clone = [];\r
1817 while (i--) {\r
1818 clone[i] = Ext.clone(item[i]);\r
1819 }\r
1820 }\r
1821
1822 else if (type === '[object Object]' && item.constructor === Object) {\r
1823 clone = {};\r
1824 for (key in item) {\r
1825 clone[key] = Ext.clone(item[key]);\r
1826 }\r
1827 if (enumerables) {\r
1828 for (j = enumerables.length; j--; ) {\r
1829 k = enumerables[j];\r
1830 if (item.hasOwnProperty(k)) {\r
1831 clone[k] = item[k];\r
1832 }\r
1833 }\r
1834 }\r
1835 }\r
1836 return clone || item;\r
1837 },\r
1838 \r
1839 getUniqueGlobalNamespace: function() {\r
1840 var uniqueGlobalNamespace = this.uniqueGlobalNamespace,\r
1841 i;\r
1842 if (uniqueGlobalNamespace === undefined) {\r
1843 i = 0;\r
1844 do {\r
1845 uniqueGlobalNamespace = 'ExtBox' + (++i);\r
1846 } while (global[uniqueGlobalNamespace] !== undefined);\r
1847 global[uniqueGlobalNamespace] = Ext;\r
1848 this.uniqueGlobalNamespace = uniqueGlobalNamespace;\r
1849 }\r
1850 return uniqueGlobalNamespace;\r
1851 },\r
1852 \r
1853 functionFactoryCache: {},\r
1854 cacheableFunctionFactory: function() {\r
1855 var me = this,\r
1856 args = Array.prototype.slice.call(arguments),\r
1857 cache = me.functionFactoryCache,\r
1858 idx, fn, ln;\r
1859 if (Ext.isSandboxed) {\r
1860 ln = args.length;\r
1861 if (ln > 0) {\r
1862 ln--;\r
1863 args[ln] = 'var Ext=window.' + Ext.name + ';' + args[ln];\r
1864 }\r
1865 }\r
1866 idx = args.join('');\r
1867 fn = cache[idx];\r
1868 if (!fn) {\r
1869 fn = Function.prototype.constructor.apply(Function.prototype, args);\r
1870 cache[idx] = fn;\r
1871 }\r
1872 return fn;\r
1873 },\r
1874 functionFactory: function() {\r
1875 var args = Array.prototype.slice.call(arguments),\r
1876 ln;\r
1877 if (Ext.isSandboxed) {\r
1878 ln = args.length;\r
1879 if (ln > 0) {\r
1880 ln--;\r
1881 args[ln] = 'var Ext=window.' + Ext.name + ';' + args[ln];\r
1882 }\r
1883 }\r
1884 return Function.prototype.constructor.apply(Function.prototype, args);\r
1885 },\r
1886 \r
1887 Logger: {\r
1888
1889 log: function(message, priority) {\r
1890 if (message && global.console) {\r
1891 if (!priority || !(priority in global.console)) {\r
1892 priority = 'log';\r
1893 }\r
1894 message = '[' + priority.toUpperCase() + '] ' + message;\r
1895 global.console[priority](message);\r
1896 }\r
1897 },\r
1898 verbose: function(message) {\r
1899 this.log(message, 'verbose');\r
1900 },\r
1901 info: function(message) {\r
1902 this.log(message, 'info');\r
1903 },\r
1904 warn: function(message) {\r
1905 this.log(message, 'warn');\r
1906 },\r
1907 error: function(message) {\r
1908 throw new Error(message);\r
1909 },\r
1910 deprecate: function(message) {\r
1911 this.log(message, 'warn');\r
1912 }\r
1913 } || {\r
1914
1915 verbose: emptyFn,\r
1916 log: emptyFn,\r
1917 info: emptyFn,\r
1918 warn: emptyFn,\r
1919 error: function(message) {\r
1920 throw new Error(message);\r
1921 },\r
1922 deprecate: emptyFn\r
1923 },\r
1924 \r
1925 getElementById: function(id) {\r
1926 return document.getElementById(id);\r
1927 },\r
1928 \r
1929 splitAndUnescape: (function() {\r
1930 var cache = {};\r
1931 return function(origin, delimiter) {\r
1932 if (!origin) {\r
1933 return [];\r
1934 } else if (!delimiter) {\r
1935 return [\r
1936 origin\r
1937 ];\r
1938 }\r
1939 var replaceRe = cache[delimiter] || (cache[delimiter] = new RegExp('\\\\' + delimiter, 'g')),\r
1940 result = [],\r
1941 parts, part;\r
1942 parts = origin.split(delimiter);\r
1943 while ((part = parts.shift()) !== undefined) {\r
1944
1945
1946 while (part.charAt(part.length - 1) === '\\' && parts.length > 0) {\r
1947 part = part + delimiter + parts.shift();\r
1948 }\r
1949
1950 part = part.replace(replaceRe, delimiter);\r
1951 result.push(part);\r
1952 }\r
1953 return result;\r
1954 };\r
1955 })()\r
1956 });\r
1957
1958 Ext.returnTrue.$nullFn = Ext.returnId.$nullFn = true;\r
1959}());\r
1960\r
1961
1962
1963
1964
1965Ext.platformTags.classic = !(Ext.platformTags.modern = Ext.isModern = true);\r
1966\r
1967\r
1968(function() {\r
1969
1970
1971
1972 function toString() {\r
1973 var me = this,\r
1974 cls = me.sourceClass,\r
1975 method = me.sourceMethod,\r
1976 msg = me.msg;\r
1977 if (method) {\r
1978 if (msg) {\r
1979 method += '(): ';\r
1980 method += msg;\r
1981 } else {\r
1982 method += '()';\r
1983 }\r
1984 }\r
1985 if (cls) {\r
1986 method = method ? (cls + '.' + method) : cls;\r
1987 }\r
1988 return method || msg || '';\r
1989 }\r
1990 Ext.Error = function(config) {\r
1991 if (Ext.isString(config)) {\r
1992 config = {\r
1993 msg: config\r
1994 };\r
1995 }\r
1996 var error = new Error();\r
1997 Ext.apply(error, config);\r
1998 error.message = error.message || error.msg;\r
1999
2000
2001 error.toString = toString;\r
2002 return error;\r
2003 };\r
2004 Ext.apply(Ext.Error, {\r
2005 \r
2006 ignore: false,\r
2007 \r
2008 raise: function(err) {\r
2009 err = err || {};\r
2010 if (Ext.isString(err)) {\r
2011 err = {\r
2012 msg: err\r
2013 };\r
2014 }\r
2015 var me = this,\r
2016 method = me.raise.caller,\r
2017 msg, name;\r
2018 if (method === Ext.raise) {\r
2019 method = method.caller;\r
2020 }\r
2021 if (method) {\r
2022 if (!err.sourceMethod && (name = method.$name)) {\r
2023 err.sourceMethod = name;\r
2024 }\r
2025 if (!err.sourceClass && (name = method.$owner) && (name = name.$className)) {\r
2026 err.sourceClass = name;\r
2027 }\r
2028 }\r
2029 if (me.handle(err) !== true) {\r
2030 msg = toString.call(err);\r
2031
2032 Ext.log({\r
2033 msg: msg,\r
2034 level: 'error',\r
2035 dump: err,\r
2036 stack: true\r
2037 });\r
2038
2039 throw new Ext.Error(err);\r
2040 }\r
2041 },\r
2042 \r
2043 handle: function() {\r
2044 return this.ignore;\r
2045 }\r
2046 });\r
2047})();\r
2048\r
2049Ext.deprecated = function(suggestion) {\r
2050
2051 if (!suggestion) {\r
2052 suggestion = '';\r
2053 }\r
2054 function fail() {\r
2055 Ext.raise('The method "' + fail.$owner.$className + '.' + fail.$name + '" has been removed. ' + suggestion);\r
2056 }\r
2057 return fail;\r
2058
2059 return Ext.emptyFn;\r
2060};\r
2061\r
2062Ext.raise = function() {\r
2063 Ext.Error.raise.apply(Ext.Error, arguments);\r
2064};\r
2065\r
2066
2067(function() {\r
2068 if (typeof window === 'undefined') {\r
2069 return;\r
2070 }\r
2071
2072 var last = 0,\r
2073
2074 notify = function() {\r
2075 var cnt = Ext.log && Ext.log.counters,\r
2076 n = cnt && (cnt.error + cnt.warn + cnt.info + cnt.log),\r
2077 msg;\r
2078
2079 if (n && last !== n) {\r
2080 msg = [];\r
2081 if (cnt.error) {\r
2082 msg.push('Errors: ' + cnt.error);\r
2083 }\r
2084 if (cnt.warn) {\r
2085 msg.push('Warnings: ' + cnt.warn);\r
2086 }\r
2087 if (cnt.info) {\r
2088 msg.push('Info: ' + cnt.info);\r
2089 }\r
2090 if (cnt.log) {\r
2091 msg.push('Log: ' + cnt.log);\r
2092 }\r
2093 window.status = '*** ' + msg.join(' -- ');\r
2094 last = n;\r
2095 }\r
2096 };\r
2097
2098
2099 setInterval(notify, 1000);\r
2100}());\r
2101
2102\r
2103\r
2104Ext.Array = (function() {\r
2105
2106
2107
2108
2109 var arrayPrototype = Array.prototype,\r
2110 slice = arrayPrototype.slice,\r
2111 supportsSplice = (function() {\r
2112 var array = [],\r
2113 lengthBefore,\r
2114 j = 20;\r
2115 if (!array.splice) {\r
2116 return false;\r
2117 }\r
2118
2119
2120 while (j--) {\r
2121 array.push("A");\r
2122 }\r
2123 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");\r
2124 lengthBefore = array.length;\r
2125
2126 array.splice(13, 0, "XXX");\r
2127
2128 if (lengthBefore + 1 !== array.length) {\r
2129 return false;\r
2130 }\r
2131
2132 return true;\r
2133 }()),\r
2134 supportsIndexOf = 'indexOf' in arrayPrototype,\r
2135 supportsSliceOnNodeList = true;\r
2136
2137
2138 function stableSort(array, userComparator) {\r
2139 var len = array.length,\r
2140 indices = new Array(len),\r
2141 i;\r
2142
2143 for (i = 0; i < len; i++) {\r
2144 indices[i] = i;\r
2145 }\r
2146
2147 indices.sort(function(index1, index2) {\r
2148 return userComparator(array[index1], array[index2]) || (index1 - index2);\r
2149 });\r
2150
2151 for (i = 0; i < len; i++) {\r
2152 indices[i] = array[indices[i]];\r
2153 }\r
2154
2155 for (i = 0; i < len; i++) {\r
2156 array[i] = indices[i];\r
2157 }\r
2158 return array;\r
2159 }\r
2160 try {\r
2161
2162 if (typeof document !== 'undefined') {\r
2163 slice.call(document.getElementsByTagName('body'));\r
2164 }\r
2165 } catch (e) {\r
2166 supportsSliceOnNodeList = false;\r
2167 }\r
2168 var fixArrayIndex = function(array, index) {\r
2169 return (index < 0) ? Math.max(0, array.length + index) : Math.min(array.length, index);\r
2170 },\r
2171 \r
2172 replaceSim = function(array, index, removeCount, insert) {\r
2173 var add = insert ? insert.length : 0,\r
2174 length = array.length,\r
2175 pos = fixArrayIndex(array, index);\r
2176
2177 if (pos === length) {\r
2178 if (add) {\r
2179 array.push.apply(array, insert);\r
2180 }\r
2181 } else {\r
2182 var remove = Math.min(removeCount, length - pos),\r
2183 tailOldPos = pos + remove,\r
2184 tailNewPos = tailOldPos + add - remove,\r
2185 tailCount = length - tailOldPos,\r
2186 lengthAfterRemove = length - remove,\r
2187 i;\r
2188 if (tailNewPos < tailOldPos) {\r
2189
2190 for (i = 0; i < tailCount; ++i) {\r
2191 array[tailNewPos + i] = array[tailOldPos + i];\r
2192 }\r
2193 } else if (tailNewPos > tailOldPos) {\r
2194
2195 for (i = tailCount; i--; ) {\r
2196 array[tailNewPos + i] = array[tailOldPos + i];\r
2197 }\r
2198 }\r
2199
2200 if (add && pos === lengthAfterRemove) {\r
2201 array.length = lengthAfterRemove;\r
2202
2203 array.push.apply(array, insert);\r
2204 } else {\r
2205 array.length = lengthAfterRemove + add;\r
2206
2207 for (i = 0; i < add; ++i) {\r
2208 array[pos + i] = insert[i];\r
2209 }\r
2210 }\r
2211 }\r
2212 return array;\r
2213 },\r
2214 replaceNative = function(array, index, removeCount, insert) {\r
2215 if (insert && insert.length) {\r
2216
2217 if (index === 0 && !removeCount) {\r
2218 array.unshift.apply(array, insert);\r
2219 }\r
2220
2221 else if (index < array.length) {\r
2222 array.splice.apply(array, [\r
2223 index,\r
2224 removeCount\r
2225 ].concat(insert));\r
2226 } else
2227 {\r
2228 array.push.apply(array, insert);\r
2229 }\r
2230 } else {\r
2231 array.splice(index, removeCount);\r
2232 }\r
2233 return array;\r
2234 },\r
2235 eraseSim = function(array, index, removeCount) {\r
2236 return replaceSim(array, index, removeCount);\r
2237 },\r
2238 eraseNative = function(array, index, removeCount) {\r
2239 array.splice(index, removeCount);\r
2240 return array;\r
2241 },\r
2242 spliceSim = function(array, index, removeCount) {\r
2243 var pos = fixArrayIndex(array, index),\r
2244 removed = array.slice(index, fixArrayIndex(array, pos + removeCount));\r
2245 if (arguments.length < 4) {\r
2246 replaceSim(array, pos, removeCount);\r
2247 } else {\r
2248 replaceSim(array, pos, removeCount, slice.call(arguments, 3));\r
2249 }\r
2250 return removed;\r
2251 },\r
2252 spliceNative = function(array) {\r
2253 return array.splice.apply(array, slice.call(arguments, 1));\r
2254 },\r
2255 erase = supportsSplice ? eraseNative : eraseSim,\r
2256 replace = supportsSplice ? replaceNative : replaceSim,\r
2257 splice = supportsSplice ? spliceNative : spliceSim,\r
2258
2259 ExtArray = {\r
2260 \r
2261 binarySearch: function(array, item, begin, end, compareFn) {\r
2262 var length = array.length,\r
2263 middle, comparison;\r
2264 if (begin instanceof Function) {\r
2265 compareFn = begin;\r
2266 begin = 0;\r
2267 end = length;\r
2268 } else if (end instanceof Function) {\r
2269 compareFn = end;\r
2270 end = length;\r
2271 } else {\r
2272 if (begin === undefined) {\r
2273 begin = 0;\r
2274 }\r
2275 if (end === undefined) {\r
2276 end = length;\r
2277 }\r
2278 compareFn = compareFn || ExtArray.lexicalCompare;\r
2279 }\r
2280 --end;\r
2281 while (begin <= end) {\r
2282 middle = (begin + end) >> 1;\r
2283 comparison = compareFn(item, array[middle]);\r
2284 if (comparison >= 0) {\r
2285 begin = middle + 1;\r
2286 } else if (comparison < 0) {\r
2287 end = middle - 1;\r
2288 }\r
2289 }\r
2290 return begin;\r
2291 },\r
2292 defaultCompare: function(lhs, rhs) {\r
2293 return (lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0);\r
2294 },\r
2295
2296
2297 lexicalCompare: function(lhs, rhs) {\r
2298 lhs = String(lhs);\r
2299 rhs = String(rhs);\r
2300 return (lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0);\r
2301 },\r
2302 \r
2303 each: function(array, fn, scope, reverse) {\r
2304 array = ExtArray.from(array);\r
2305 var i,\r
2306 ln = array.length;\r
2307 if (reverse !== true) {\r
2308 for (i = 0; i < ln; i++) {\r
2309 if (fn.call(scope || array[i], array[i], i, array) === false) {\r
2310 return i;\r
2311 }\r
2312 }\r
2313 } else {\r
2314 for (i = ln - 1; i > -1; i--) {\r
2315 if (fn.call(scope || array[i], array[i], i, array) === false) {\r
2316 return i;\r
2317 }\r
2318 }\r
2319 }\r
2320 return true;\r
2321 },\r
2322 \r
2323 forEach: ('forEach' in arrayPrototype) ? function(array, fn, scope) {\r
2324 return array.forEach(fn, scope);\r
2325 } : function(array, fn, scope) {\r
2326 for (var i = 0,\r
2327 ln = array.length; i < ln; i++) {\r
2328 fn.call(scope, array[i], i, array);\r
2329 }\r
2330 },\r
2331 \r
2332 indexOf: supportsIndexOf ? function(array, item, from) {\r
2333 return arrayPrototype.indexOf.call(array, item, from);\r
2334 } : function(array, item, from) {\r
2335 var i,\r
2336 length = array.length;\r
2337 for (i = (from < 0) ? Math.max(0, length + from) : from || 0; i < length; i++) {\r
2338 if (array[i] === item) {\r
2339 return i;\r
2340 }\r
2341 }\r
2342 return -1;\r
2343 },\r
2344 \r
2345 contains: supportsIndexOf ? function(array, item) {\r
2346 return arrayPrototype.indexOf.call(array, item) !== -1;\r
2347 } : function(array, item) {\r
2348 var i, ln;\r
2349 for (i = 0 , ln = array.length; i < ln; i++) {\r
2350 if (array[i] === item) {\r
2351 return true;\r
2352 }\r
2353 }\r
2354 return false;\r
2355 },\r
2356 \r
2357 toArray: function(iterable, start, end) {\r
2358 if (!iterable || !iterable.length) {\r
2359 return [];\r
2360 }\r
2361 if (typeof iterable === 'string') {\r
2362 iterable = iterable.split('');\r
2363 }\r
2364 if (supportsSliceOnNodeList) {\r
2365 return slice.call(iterable, start || 0, end || iterable.length);\r
2366 }\r
2367 var array = [],\r
2368 i;\r
2369 start = start || 0;\r
2370 end = end ? ((end < 0) ? iterable.length + end : end) : iterable.length;\r
2371 for (i = start; i < end; i++) {\r
2372 array.push(iterable[i]);\r
2373 }\r
2374 return array;\r
2375 },\r
2376 \r
2377 pluck: function(array, propertyName) {\r
2378 var ret = [],\r
2379 i, ln, item;\r
2380 for (i = 0 , ln = array.length; i < ln; i++) {\r
2381 item = array[i];\r
2382 ret.push(item[propertyName]);\r
2383 }\r
2384 return ret;\r
2385 },\r
2386 \r
2387 map: ('map' in arrayPrototype) ? function(array, fn, scope) {\r
2388
2389 Ext.Assert.isFunction(fn, 'Ext.Array.map must have a callback function passed as second argument.');\r
2390
2391 return array.map(fn, scope);\r
2392 } : function(array, fn, scope) {\r
2393
2394 Ext.Assert.isFunction(fn, 'Ext.Array.map must have a callback function passed as second argument.');\r
2395
2396 var results = [],\r
2397 len = array.length,\r
2398 i;\r
2399 for (i = 0; i < len; i++) {\r
2400 results[i] = fn.call(scope, array[i], i, array);\r
2401 }\r
2402 return results;\r
2403 },\r
2404 \r
2405 every: ('every' in arrayPrototype) ? function(array, fn, scope) {\r
2406
2407 Ext.Assert.isFunction(fn, 'Ext.Array.every must have a callback function passed as second argument.');\r
2408
2409 return array.every(fn, scope);\r
2410 } : function(array, fn, scope) {\r
2411
2412 Ext.Assert.isFunction(fn, 'Ext.Array.every must have a callback function passed as second argument.');\r
2413
2414 var i = 0,\r
2415 ln = array.length;\r
2416 for (; i < ln; ++i) {\r
2417 if (!fn.call(scope, array[i], i, array)) {\r
2418 return false;\r
2419 }\r
2420 }\r
2421 return true;\r
2422 },\r
2423 \r
2424 some: ('some' in arrayPrototype) ? function(array, fn, scope) {\r
2425
2426 Ext.Assert.isFunction(fn, 'Ext.Array.some must have a callback function passed as second argument.');\r
2427
2428 return array.some(fn, scope);\r
2429 } : function(array, fn, scope) {\r
2430
2431 Ext.Assert.isFunction(fn, 'Ext.Array.some must have a callback function passed as second argument.');\r
2432
2433 var i = 0,\r
2434 ln = array.length;\r
2435 for (; i < ln; ++i) {\r
2436 if (fn.call(scope, array[i], i, array)) {\r
2437 return true;\r
2438 }\r
2439 }\r
2440 return false;\r
2441 },\r
2442 \r
2443 equals: function(array1, array2) {\r
2444 var len1 = array1.length,\r
2445 len2 = array2.length,\r
2446 i;\r
2447
2448 if (array1 === array2) {\r
2449 return true;\r
2450 }\r
2451 if (len1 !== len2) {\r
2452 return false;\r
2453 }\r
2454 for (i = 0; i < len1; ++i) {\r
2455 if (array1[i] !== array2[i]) {\r
2456 return false;\r
2457 }\r
2458 }\r
2459 return true;\r
2460 },\r
2461 \r
2462 clean: function(array) {\r
2463 var results = [],\r
2464 i = 0,\r
2465 ln = array.length,\r
2466 item;\r
2467 for (; i < ln; i++) {\r
2468 item = array[i];\r
2469 if (!Ext.isEmpty(item)) {\r
2470 results.push(item);\r
2471 }\r
2472 }\r
2473 return results;\r
2474 },\r
2475 \r
2476 unique: function(array) {\r
2477 var clone = [],\r
2478 i = 0,\r
2479 ln = array.length,\r
2480 item;\r
2481 for (; i < ln; i++) {\r
2482 item = array[i];\r
2483 if (ExtArray.indexOf(clone, item) === -1) {\r
2484 clone.push(item);\r
2485 }\r
2486 }\r
2487 return clone;\r
2488 },\r
2489 \r
2490 filter: ('filter' in arrayPrototype) ? function(array, fn, scope) {\r
2491
2492 Ext.Assert.isFunction(fn, 'Ext.Array.filter must have a filter function passed as second argument.');\r
2493
2494 return array.filter(fn, scope);\r
2495 } : function(array, fn, scope) {\r
2496
2497 Ext.Assert.isFunction(fn, 'Ext.Array.filter must have a filter function passed as second argument.');\r
2498
2499 var results = [],\r
2500 i = 0,\r
2501 ln = array.length;\r
2502 for (; i < ln; i++) {\r
2503 if (fn.call(scope, array[i], i, array)) {\r
2504 results.push(array[i]);\r
2505 }\r
2506 }\r
2507 return results;\r
2508 },\r
2509 \r
2510 findBy: function(array, fn, scope) {\r
2511 var i = 0,\r
2512 len = array.length;\r
2513 for (; i < len; i++) {\r
2514 if (fn.call(scope || array, array[i], i)) {\r
2515 return array[i];\r
2516 }\r
2517 }\r
2518 return null;\r
2519 },\r
2520 \r
2521 from: function(value, newReference) {\r
2522 if (value === undefined || value === null) {\r
2523 return [];\r
2524 }\r
2525 if (Ext.isArray(value)) {\r
2526 return (newReference) ? slice.call(value) : value;\r
2527 }\r
2528 var type = typeof value;\r
2529
2530
2531 if (value && value.length !== undefined && type !== 'string' && (type !== 'function' || !value.apply)) {\r
2532 return ExtArray.toArray(value);\r
2533 }\r
2534 return [\r
2535 value\r
2536 ];\r
2537 },\r
2538 \r
2539 remove: function(array, item) {\r
2540 var index = ExtArray.indexOf(array, item);\r
2541 if (index !== -1) {\r
2542 erase(array, index, 1);\r
2543 }\r
2544 return array;\r
2545 },\r
2546 \r
2547 removeAt: function(array, index, count) {\r
2548 var len = array.length;\r
2549 if (index >= 0 && index < len) {\r
2550 count = count || 1;\r
2551 count = Math.min(count, len - index);\r
2552 erase(array, index, count);\r
2553 }\r
2554 return array;\r
2555 },\r
2556 \r
2557 include: function(array, item) {\r
2558 if (!ExtArray.contains(array, item)) {\r
2559 array.push(item);\r
2560 }\r
2561 },\r
2562 \r
2563 clone: function(array) {\r
2564 return slice.call(array);\r
2565 },\r
2566 \r
2567 merge: function() {\r
2568 var args = slice.call(arguments),\r
2569 array = [],\r
2570 i, ln;\r
2571 for (i = 0 , ln = args.length; i < ln; i++) {\r
2572 array = array.concat(args[i]);\r
2573 }\r
2574 return ExtArray.unique(array);\r
2575 },\r
2576 \r
2577 intersect: function() {\r
2578 var intersection = [],\r
2579 arrays = slice.call(arguments),\r
2580 arraysLength, array, arrayLength, minArray, minArrayIndex, minArrayCandidate, minArrayLength, element, elementCandidate, elementCount, i, j, k;\r
2581 if (!arrays.length) {\r
2582 return intersection;\r
2583 }\r
2584
2585 arraysLength = arrays.length;\r
2586 for (i = minArrayIndex = 0; i < arraysLength; i++) {\r
2587 minArrayCandidate = arrays[i];\r
2588 if (!minArray || minArrayCandidate.length < minArray.length) {\r
2589 minArray = minArrayCandidate;\r
2590 minArrayIndex = i;\r
2591 }\r
2592 }\r
2593 minArray = ExtArray.unique(minArray);\r
2594 erase(arrays, minArrayIndex, 1);\r
2595
2596
2597
2598 minArrayLength = minArray.length;\r
2599 arraysLength = arrays.length;\r
2600 for (i = 0; i < minArrayLength; i++) {\r
2601 element = minArray[i];\r
2602 elementCount = 0;\r
2603 for (j = 0; j < arraysLength; j++) {\r
2604 array = arrays[j];\r
2605 arrayLength = array.length;\r
2606 for (k = 0; k < arrayLength; k++) {\r
2607 elementCandidate = array[k];\r
2608 if (element === elementCandidate) {\r
2609 elementCount++;\r
2610 break;\r
2611 }\r
2612 }\r
2613 }\r
2614 if (elementCount === arraysLength) {\r
2615 intersection.push(element);\r
2616 }\r
2617 }\r
2618 return intersection;\r
2619 },\r
2620 \r
2621 difference: function(arrayA, arrayB) {\r
2622 var clone = slice.call(arrayA),\r
2623 ln = clone.length,\r
2624 i, j, lnB;\r
2625 for (i = 0 , lnB = arrayB.length; i < lnB; i++) {\r
2626 for (j = 0; j < ln; j++) {\r
2627 if (clone[j] === arrayB[i]) {\r
2628 erase(clone, j, 1);\r
2629 j--;\r
2630 ln--;\r
2631 }\r
2632 }\r
2633 }\r
2634 return clone;\r
2635 },\r
2636 \r
2637 reduce: Array.prototype.reduce ? function(array, reduceFn, initialValue) {\r
2638 if (arguments.length === 3) {\r
2639 return Array.prototype.reduce.call(array, reduceFn, initialValue);\r
2640 }\r
2641 return Array.prototype.reduce.call(array, reduceFn);\r
2642 } : function(array, reduceFn, initialValue) {\r
2643 array = Object(array);\r
2644
2645 if (!Ext.isFunction(reduceFn)) {\r
2646 Ext.raise('Invalid parameter: expected a function.');\r
2647 }\r
2648
2649 var index = 0,\r
2650 length = array.length >>> 0,\r
2651 reduced = initialValue;\r
2652 if (arguments.length < 3) {\r
2653 while (true) {\r
2654 if (index in array) {\r
2655 reduced = array[index++];\r
2656 break;\r
2657 }\r
2658 if (++index >= length) {\r
2659 throw new TypeError('Reduce of empty array with no initial value');\r
2660 }\r
2661 }\r
2662 }\r
2663 for (; index < length; ++index) {\r
2664 if (index in array) {\r
2665 reduced = reduceFn(reduced, array[index], index, array);\r
2666 }\r
2667 }\r
2668 return reduced;\r
2669 },\r
2670 \r
2671
2672 slice: ([\r
2673 1,\r
2674 2\r
2675 ].slice(1, undefined).length ? function(array, begin, end) {\r
2676 return slice.call(array, begin, end);\r
2677 } : function(array, begin, end) {\r
2678
2679 if (typeof begin === 'undefined') {\r
2680 return slice.call(array);\r
2681 }\r
2682 if (typeof end === 'undefined') {\r
2683 return slice.call(array, begin);\r
2684 }\r
2685 return slice.call(array, begin, end);\r
2686 }),\r
2687 \r
2688 sort: function(array, sortFn) {\r
2689 return stableSort(array, sortFn || ExtArray.lexicalCompare);\r
2690 },\r
2691 \r
2692 flatten: function(array) {\r
2693 var worker = [];\r
2694 function rFlatten(a) {\r
2695 var i, ln, v;\r
2696 for (i = 0 , ln = a.length; i < ln; i++) {\r
2697 v = a[i];\r
2698 if (Ext.isArray(v)) {\r
2699 rFlatten(v);\r
2700 } else {\r
2701 worker.push(v);\r
2702 }\r
2703 }\r
2704 return worker;\r
2705 }\r
2706 return rFlatten(array);\r
2707 },\r
2708 \r
2709 min: function(array, comparisonFn) {\r
2710 var min = array[0],\r
2711 i, ln, item;\r
2712 for (i = 0 , ln = array.length; i < ln; i++) {\r
2713 item = array[i];\r
2714 if (comparisonFn) {\r
2715 if (comparisonFn(min, item) === 1) {\r
2716 min = item;\r
2717 }\r
2718 } else {\r
2719 if (item < min) {\r
2720 min = item;\r
2721 }\r
2722 }\r
2723 }\r
2724 return min;\r
2725 },\r
2726 \r
2727 max: function(array, comparisonFn) {\r
2728 var max = array[0],\r
2729 i, ln, item;\r
2730 for (i = 0 , ln = array.length; i < ln; i++) {\r
2731 item = array[i];\r
2732 if (comparisonFn) {\r
2733 if (comparisonFn(max, item) === -1) {\r
2734 max = item;\r
2735 }\r
2736 } else {\r
2737 if (item > max) {\r
2738 max = item;\r
2739 }\r
2740 }\r
2741 }\r
2742 return max;\r
2743 },\r
2744 \r
2745 mean: function(array) {\r
2746 return array.length > 0 ? ExtArray.sum(array) / array.length : undefined;\r
2747 },\r
2748 \r
2749 sum: function(array) {\r
2750 var sum = 0,\r
2751 i, ln, item;\r
2752 for (i = 0 , ln = array.length; i < ln; i++) {\r
2753 item = array[i];\r
2754 sum += item;\r
2755 }\r
2756 return sum;\r
2757 },\r
2758 \r
2759 toMap: function(array, getKey, scope) {\r
2760 var map = {},\r
2761 i = array.length;\r
2762 if (!getKey) {\r
2763 while (i--) {\r
2764 map[array[i]] = i + 1;\r
2765 }\r
2766 } else if (typeof getKey === 'string') {\r
2767 while (i--) {\r
2768 map[array[i][getKey]] = i + 1;\r
2769 }\r
2770 } else {\r
2771 while (i--) {\r
2772 map[getKey.call(scope, array[i])] = i + 1;\r
2773 }\r
2774 }\r
2775 return map;\r
2776 },\r
2777 \r
2778 toValueMap: function(array, getKey, scope, arrayify) {\r
2779 var map = {},\r
2780 i = array.length,\r
2781 autoArray, alwaysArray, entry, fn, key, value;\r
2782 if (!getKey) {\r
2783 while (i--) {\r
2784 value = array[i];\r
2785 map[value] = value;\r
2786 }\r
2787 } else {\r
2788 if (!(fn = (typeof getKey !== 'string'))) {\r
2789 arrayify = scope;\r
2790 }\r
2791 alwaysArray = arrayify === 1;\r
2792 autoArray = arrayify === 2;\r
2793 while (i--) {\r
2794 value = array[i];\r
2795 key = fn ? getKey.call(scope, value) : value[getKey];\r
2796 if (alwaysArray) {\r
2797 if (key in map) {\r
2798 map[key].push(value);\r
2799 } else {\r
2800 map[key] = [\r
2801 value\r
2802 ];\r
2803 }\r
2804 } else if (autoArray && (key in map)) {\r
2805 if ((entry = map[key]) instanceof Array) {\r
2806 entry.push(value);\r
2807 } else {\r
2808 map[key] = [\r
2809 entry,\r
2810 value\r
2811 ];\r
2812 }\r
2813 } else {\r
2814 map[key] = value;\r
2815 }\r
2816 }\r
2817 }\r
2818 return map;\r
2819 },\r
2820
2821 _replaceSim: replaceSim,\r
2822
2823 _spliceSim: spliceSim,\r
2824
2825 \r
2826 erase: erase,\r
2827 \r
2828 insert: function(array, index, items) {\r
2829 return replace(array, index, 0, items);\r
2830 },\r
2831 move: function(array, fromIdx, toIdx) {\r
2832 if (toIdx === fromIdx) {\r
2833 return;\r
2834 }\r
2835 var item = array[fromIdx],\r
2836 incr = toIdx > fromIdx ? 1 : -1,\r
2837 i;\r
2838 for (i = fromIdx; i != toIdx; i += incr) {\r
2839 array[i] = array[i + incr];\r
2840 }\r
2841 array[toIdx] = item;\r
2842 },\r
2843 \r
2844 replace: replace,\r
2845 \r
2846 splice: splice,\r
2847 \r
2848 push: function(target) {\r
2849 var len = arguments.length,\r
2850 i = 1,\r
2851 newItem;\r
2852 if (target === undefined) {\r
2853 target = [];\r
2854 } else if (!Ext.isArray(target)) {\r
2855 target = [\r
2856 target\r
2857 ];\r
2858 }\r
2859 for (; i < len; i++) {\r
2860 newItem = arguments[i];\r
2861 Array.prototype.push[Ext.isIterable(newItem) ? 'apply' : 'call'](target, newItem);\r
2862 }\r
2863 return target;\r
2864 },\r
2865 \r
2866 numericSortFn: function(a, b) {\r
2867 return a - b;\r
2868 }\r
2869 };\r
2870 \r
2871 Ext.each = ExtArray.each;\r
2872 \r
2873 ExtArray.union = ExtArray.merge;\r
2874 \r
2875 Ext.min = ExtArray.min;\r
2876 \r
2877 Ext.max = ExtArray.max;\r
2878 \r
2879 Ext.sum = ExtArray.sum;\r
2880 \r
2881 Ext.mean = ExtArray.mean;\r
2882 \r
2883 Ext.flatten = ExtArray.flatten;\r
2884 \r
2885 Ext.clean = ExtArray.clean;\r
2886 \r
2887 Ext.unique = ExtArray.unique;\r
2888 \r
2889 Ext.pluck = ExtArray.pluck;\r
2890 \r
2891 Ext.toArray = function() {\r
2892 return ExtArray.toArray.apply(ExtArray, arguments);\r
2893 };\r
2894 return ExtArray;\r
2895}());\r
2896\r
2897
2898
2899
2900
2901\r
2902Ext.Assert = {\r
2903 \r
2904 falsey: function(b, msg) {\r
2905 if (b) {\r
2906 Ext.raise(msg || ('Expected a falsey value but was ' + b));\r
2907 }\r
2908 },\r
2909 \r
2910 falseyProp: function(object, property) {\r
2911 Ext.Assert.truthy(object);\r
2912 var b = object[property];\r
2913 if (b) {\r
2914 if (object.$className) {\r
2915 property = object.$className + '#' + property;\r
2916 }\r
2917 Ext.raise('Expected a falsey value for ' + property + ' but was ' + b);\r
2918 }\r
2919 },\r
2920 \r
2921 truthy: function(b, msg) {\r
2922 if (!b) {\r
2923 Ext.raise(msg || ('Expected a truthy value but was ' + typeof b));\r
2924 }\r
2925 },\r
2926 \r
2927 truthyProp: function(object, property) {\r
2928 Ext.Assert.truthy(object);\r
2929 var b = object[property];\r
2930 if (!b) {\r
2931 if (object.$className) {\r
2932 property = object.$className + '#' + property;\r
2933 }\r
2934 Ext.raise('Expected a truthy value for ' + property + ' but was ' + typeof b);\r
2935 }\r
2936 }\r
2937};\r
2938(function() {\r
2939 function makeAssert(name, kind) {\r
2940 var testFn = Ext[name],\r
2941 def;\r
2942 return function(value, msg) {\r
2943 if (!testFn(value)) {\r
2944 Ext.raise(msg || def || (def = 'Expected value to be ' + kind));\r
2945 }\r
2946 };\r
2947 }\r
2948 function makeAssertProp(name, kind) {\r
2949 var testFn = Ext[name],\r
2950 def;\r
2951 return function(object, prop) {\r
2952 Ext.Assert.truthy(object);\r
2953 if (!testFn(object[prop])) {\r
2954 Ext.raise(def || (def = 'Expected ' + (object.$className ? object.$className + '#' : '') + prop + ' to be ' + kind));\r
2955 }\r
2956 };\r
2957 }\r
2958 function makeNotAssert(name, kind) {\r
2959 var testFn = Ext[name],\r
2960 def;\r
2961 return function(value, msg) {\r
2962 if (testFn(value)) {\r
2963 Ext.raise(msg || def || (def = 'Expected value to NOT be ' + kind));\r
2964 }\r
2965 };\r
2966 }\r
2967 function makeNotAssertProp(name, kind) {\r
2968 var testFn = Ext[name],\r
2969 def;\r
2970 return function(object, prop) {\r
2971 Ext.Assert.truthy(object);\r
2972 if (testFn(object[prop])) {\r
2973 Ext.raise(def || (def = 'Expected ' + (object.$className ? object.$className + '#' : '') + prop + ' to NOT be ' + kind));\r
2974 }\r
2975 };\r
2976 }\r
2977 for (var name in Ext) {\r
2978 if (name.substring(0, 2) == "is" && Ext.isFunction(Ext[name])) {\r
2979 var kind = name.substring(2);\r
2980 Ext.Assert[name] = makeAssert(name, kind);\r
2981 Ext.Assert[name + 'Prop'] = makeAssertProp(name, kind);\r
2982 Ext.Assert['isNot' + kind] = makeNotAssert(name, kind);\r
2983 Ext.Assert['isNot' + kind + 'Prop'] = makeNotAssertProp(name, kind);\r
2984 }\r
2985 }\r
2986}());\r
2987
2988\r
2989\r
2990Ext.String = (function() {\r
2991
2992
2993
2994
2995 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,\r
2996 escapeRe = /('|\\)/g,\r
2997 escapeRegexRe = /([-.*+?\^${}()|\[\]\/\\])/g,\r
2998 basicTrimRe = /^\s+|\s+$/g,\r
2999 whitespaceRe = /\s+/,\r
3000 varReplace = /(^[^a-z]*|[^\w])/gi,\r
3001 charToEntity, entityToChar, charToEntityRegex, entityToCharRegex,\r
3002 htmlEncodeReplaceFn = function(match, capture) {\r
3003 return charToEntity[capture];\r
3004 },\r
3005 htmlDecodeReplaceFn = function(match, capture) {\r
3006 return (capture in entityToChar) ? entityToChar[capture] : String.fromCharCode(parseInt(capture.substr(2), 10));\r
3007 },\r
3008 boundsCheck = function(s, other) {\r
3009 if (s === null || s === undefined || other === null || other === undefined) {\r
3010 return false;\r
3011 }\r
3012 return other.length <= s.length;\r
3013 },\r
3014 ExtString;\r
3015 return ExtString = {\r
3016 \r
3017 insert: function(s, value, index) {\r
3018 if (!s) {\r
3019 return value;\r
3020 }\r
3021 if (!value) {\r
3022 return s;\r
3023 }\r
3024 var len = s.length;\r
3025 if (!index && index !== 0) {\r
3026 index = len;\r
3027 }\r
3028 if (index < 0) {\r
3029 index *= -1;\r
3030 if (index >= len) {\r
3031
3032 index = 0;\r
3033 } else {\r
3034 index = len - index;\r
3035 }\r
3036 }\r
3037 if (index === 0) {\r
3038 s = value + s;\r
3039 } else if (index >= s.length) {\r
3040 s += value;\r
3041 } else {\r
3042 s = s.substr(0, index) + value + s.substr(index);\r
3043 }\r
3044 return s;\r
3045 },\r
3046 \r
3047 startsWith: function(s, start, ignoreCase) {\r
3048 var result = boundsCheck(s, start);\r
3049 if (result) {\r
3050 if (ignoreCase) {\r
3051 s = s.toLowerCase();\r
3052 start = start.toLowerCase();\r
3053 }\r
3054 result = s.lastIndexOf(start, 0) === 0;\r
3055 }\r
3056 return result;\r
3057 },\r
3058 \r
3059 endsWith: function(s, end, ignoreCase) {\r
3060 var result = boundsCheck(s, end);\r
3061 if (result) {\r
3062 if (ignoreCase) {\r
3063 s = s.toLowerCase();\r
3064 end = end.toLowerCase();\r
3065 }\r
3066 result = s.indexOf(end, s.length - end.length) !== -1;\r
3067 }\r
3068 return result;\r
3069 },\r
3070 \r
3071 createVarName: function(s) {\r
3072 return s.replace(varReplace, '');\r
3073 },\r
3074 \r
3075 htmlEncode: function(value) {\r
3076 return (!value) ? value : String(value).replace(charToEntityRegex, htmlEncodeReplaceFn);\r
3077 },\r
3078 \r
3079 htmlDecode: function(value) {\r
3080 return (!value) ? value : String(value).replace(entityToCharRegex, htmlDecodeReplaceFn);\r
3081 },\r
3082 \r
3083 hasHtmlCharacters: function(s) {\r
3084 return charToEntityRegex.test(s);\r
3085 },\r
3086 \r
3087 addCharacterEntities: function(newEntities) {\r
3088 var charKeys = [],\r
3089 entityKeys = [],\r
3090 key, echar;\r
3091 for (key in newEntities) {\r
3092 echar = newEntities[key];\r
3093 entityToChar[key] = echar;\r
3094 charToEntity[echar] = key;\r
3095 charKeys.push(echar);\r
3096 entityKeys.push(key);\r
3097 }\r
3098 charToEntityRegex = new RegExp('(' + charKeys.join('|') + ')', 'g');\r
3099 entityToCharRegex = new RegExp('(' + entityKeys.join('|') + '|&#[0-9]{1,5};' + ')', 'g');\r
3100 },\r
3101 \r
3102 resetCharacterEntities: function() {\r
3103 charToEntity = {};\r
3104 entityToChar = {};\r
3105
3106 this.addCharacterEntities({\r
3107 '&amp;': '&',\r
3108 '&gt;': '>',\r
3109 '&lt;': '<',\r
3110 '&quot;': '"',\r
3111 '&#39;': "'"\r
3112 });\r
3113 },\r
3114 \r
3115 urlAppend: function(url, string) {\r
3116 if (!Ext.isEmpty(string)) {\r
3117 return url + (url.indexOf('?') === -1 ? '?' : '&') + string;\r
3118 }\r
3119 return url;\r
3120 },\r
3121 \r
3122 trim: function(string) {\r
3123 if (string) {\r
3124 string = string.replace(trimRegex, "");\r
3125 }\r
3126 return string || '';\r
3127 },\r
3128 \r
3129 capitalize: function(string) {\r
3130 if (string) {\r
3131 string = string.charAt(0).toUpperCase() + string.substr(1);\r
3132 }\r
3133 return string || '';\r
3134 },\r
3135 \r
3136 uncapitalize: function(string) {\r
3137 if (string) {\r
3138 string = string.charAt(0).toLowerCase() + string.substr(1);\r
3139 }\r
3140 return string || '';\r
3141 },\r
3142 \r
3143 ellipsis: function(value, length, word) {\r
3144 if (value && value.length > length) {\r
3145 if (word) {\r
3146 var vs = value.substr(0, length - 2),\r
3147 index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));\r
3148 if (index !== -1 && index >= (length - 15)) {\r
3149 return vs.substr(0, index) + "...";\r
3150 }\r
3151 }\r
3152 return value.substr(0, length - 3) + "...";\r
3153 }\r
3154 return value;\r
3155 },\r
3156 \r
3157 escapeRegex: function(string) {\r
3158 return string.replace(escapeRegexRe, "\\$1");\r
3159 },\r
3160 \r
3161 createRegex: function(value, startsWith, endsWith, ignoreCase) {\r
3162 var ret = value;\r
3163 if (value != null && !value.exec) {\r
3164
3165 ret = ExtString.escapeRegex(String(value));\r
3166 if (startsWith !== false) {\r
3167 ret = '^' + ret;\r
3168 }\r
3169 if (endsWith !== false) {\r
3170 ret += '$';\r
3171 }\r
3172 ret = new RegExp(ret, (ignoreCase !== false) ? 'i' : '');\r
3173 }\r
3174 return ret;\r
3175 },\r
3176 \r
3177 escape: function(string) {\r
3178 return string.replace(escapeRe, "\\$1");\r
3179 },\r
3180 \r
3181 toggle: function(string, value, other) {\r
3182 return string === value ? other : value;\r
3183 },\r
3184 \r
3185 leftPad: function(string, size, character) {\r
3186 var result = String(string);\r
3187 character = character || " ";\r
3188 while (result.length < size) {\r
3189 result = character + result;\r
3190 }\r
3191 return result;\r
3192 },\r
3193 \r
3194 repeat: function(pattern, count, sep) {\r
3195 if (count < 1) {\r
3196 count = 0;\r
3197 }\r
3198 for (var buf = [],\r
3199 i = count; i--; ) {\r
3200 buf.push(pattern);\r
3201 }\r
3202 return buf.join(sep || '');\r
3203 },\r
3204 \r
3205 splitWords: function(words) {\r
3206 if (words && typeof words == 'string') {\r
3207 return words.replace(basicTrimRe, '').split(whitespaceRe);\r
3208 }\r
3209 return words || [];\r
3210 }\r
3211 };\r
3212}());\r
3213
3214Ext.String.resetCharacterEntities();\r
3215\r
3216Ext.htmlEncode = Ext.String.htmlEncode;\r
3217\r
3218Ext.htmlDecode = Ext.String.htmlDecode;\r
3219\r
3220Ext.urlAppend = Ext.String.urlAppend;\r
3221\r
3222\r
3223Ext.Date = (function() {\r
3224
3225
3226
3227
3228 var utilDate,\r
3229 nativeDate = Date,\r
3230 stripEscapeRe = /(\\.)/g,\r
3231 hourInfoRe = /([gGhHisucUOPZ]|MS)/,\r
3232 dateInfoRe = /([djzmnYycU]|MS)/,\r
3233 slashRe = /\\/gi,\r
3234 numberTokenRe = /\{(\d+)\}/g,\r
3235 MSFormatRe = new RegExp('\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/'),\r
3236 pad = Ext.String.leftPad,\r
3237
3238
3239
3240
3241 code = [\r
3242
3243 "var me = this, dt, y, m, d, h, i, s, ms, o, O, z, zz, u, v, W, year, jan4, week1monday, daysInMonth, dayMatched,",\r
3244 "def = me.defaults,",\r
3245 "from = Ext.Number.from,",\r
3246 "results = String(input).match(me.parseRegexes[{0}]);",\r
3247
3248 "if(results){",\r
3249 "{1}",\r
3250 "if(u != null){",\r
3251
3252 "v = new Date(u * 1000);",\r
3253
3254 "}else{",\r
3255
3256
3257
3258 "dt = me.clearTime(new Date);",\r
3259 "y = from(y, from(def.y, dt.getFullYear()));",\r
3260 "m = from(m, from(def.m - 1, dt.getMonth()));",\r
3261 "dayMatched = d !== undefined;",\r
3262 "d = from(d, from(def.d, dt.getDate()));",\r
3263
3264
3265
3266
3267
3268
3269 "if (!dayMatched) {",\r
3270 "dt.setDate(1);",\r
3271 "dt.setMonth(m);",\r
3272 "dt.setFullYear(y);",\r
3273 "daysInMonth = me.getDaysInMonth(dt);",\r
3274 "if (d > daysInMonth) {",\r
3275 "d = daysInMonth;",\r
3276 "}",\r
3277 "}",\r
3278 "h = from(h, from(def.h, dt.getHours()));",\r
3279 "i = from(i, from(def.i, dt.getMinutes()));",\r
3280 "s = from(s, from(def.s, dt.getSeconds()));",\r
3281 "ms = from(ms, from(def.ms, dt.getMilliseconds()));",\r
3282 "if(z >= 0 && y >= 0){",\r
3283
3284
3285
3286
3287 "v = me.add(new Date(y < 100 ? 100 : y, 0, 1, h, i, s, ms), me.YEAR, y < 100 ? y - 100 : 0);",\r
3288
3289 "v = !strict? v : (strict === true && (z <= 364 || (me.isLeapYear(v) && z <= 365))? me.add(v, me.DAY, z) : null);",\r
3290 "}else if(strict === true && !me.isValid(y, m + 1, d, h, i, s, ms)){",\r
3291
3292 "v = null;",\r
3293
3294 "}else{",\r
3295 "if (W) {",\r
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345 "year = y || (new Date()).getFullYear();",\r
3346 "jan4 = new Date(year, 0, 4, 0, 0, 0);",\r
3347 "d = jan4.getDay();",\r
3348
3349
3350 "week1monday = new Date(jan4.getTime() - ((d === 0 ? 6 : d - 1) * 86400000));",\r
3351
3352
3353
3354
3355 "v = Ext.Date.clearTime(new Date(week1monday.getTime() + ((W - 1) * 604800000 + 43200000)));",\r
3356 "} else {",\r
3357
3358
3359 "v = me.add(new Date(y < 100 ? 100 : y, m, d, h, i, s, ms), me.YEAR, y < 100 ? y - 100 : 0);",\r
3360 "}",\r
3361 "}",\r
3362 "}",\r
3363 "}",\r
3364 "if(v){",\r
3365
3366 "if(zz != null){",\r
3367
3368 "v = me.add(v, me.SECOND, -v.getTimezoneOffset() * 60 - zz);",\r
3369 "}else if(o){",\r
3370
3371 "v = me.add(v, me.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));",\r
3372 "}",\r
3373 "}",\r
3374 "return (v != null) ? v : null;"\r
3375 ].join('\n');\r
3376
3377
3378
3379 if (!Date.prototype.toISOString) {\r
3380 Date.prototype.toISOString = function() {\r
3381 var me = this;\r
3382 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';\r
3383 };\r
3384 }\r
3385 \r
3386 function xf(format) {\r
3387 var args = Array.prototype.slice.call(arguments, 1);\r
3388 return format.replace(numberTokenRe, function(m, i) {\r
3389 return args[i];\r
3390 });\r
3391 }\r
3392 return utilDate = {\r
3393 \r
3394 now: nativeDate.now,\r
3395
3396 \r
3397 toString: function(date) {\r
3398 if (!date) {\r
3399 date = new nativeDate();\r
3400 }\r
3401 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');\r
3402 },\r
3403 \r
3404 getElapsed: function(dateA, dateB) {\r
3405 return Math.abs(dateA - (dateB || utilDate.now()));\r
3406 },\r
3407 \r
3408 useStrict: false,\r
3409 \r
3410 formatCodeToRegex: function(character, currentGroup) {\r
3411
3412 var p = utilDate.parseCodes[character];\r
3413 if (p) {\r
3414 p = typeof p === 'function' ? p() : p;\r
3415 utilDate.parseCodes[character] = p;\r
3416 }\r
3417
3418 return p ? Ext.applyIf({\r
3419 c: p.c ? xf(p.c, currentGroup || "{0}") : p.c\r
3420 }, p) : {\r
3421 g: 0,\r
3422 c: null,\r
3423 s: Ext.String.escapeRegex(character)\r
3424 };\r
3425 },\r
3426
3427 \r
3428 parseFunctions: {\r
3429 "MS": function(input, strict) {\r
3430
3431
3432 var r = (input || '').match(MSFormatRe);\r
3433 return r ? new nativeDate(((r[1] || '') + r[2]) * 1) : null;\r
3434 },\r
3435 "time": function(input, strict) {\r
3436 var num = parseInt(input, 10);\r
3437 if (num || num === 0) {\r
3438 return new nativeDate(num);\r
3439 }\r
3440 return null;\r
3441 },\r
3442 "timestamp": function(input, strict) {\r
3443 var num = parseInt(input, 10);\r
3444 if (num || num === 0) {\r
3445 return new nativeDate(num * 1000);\r
3446 }\r
3447 return null;\r
3448 }\r
3449 },\r
3450 parseRegexes: [],\r
3451 \r
3452 formatFunctions: {\r
3453 "MS": function() {\r
3454
3455 return '\\/Date(' + this.getTime() + ')\\/';\r
3456 },\r
3457 "time": function() {\r
3458 return this.getTime().toString();\r
3459 },\r
3460 "timestamp": function() {\r
3461 return utilDate.format(this, 'U');\r
3462 }\r
3463 },\r
3464 y2kYear: 50,\r
3465 \r
3466 MILLI: "ms",\r
3467 \r
3468 SECOND: "s",\r
3469 \r
3470 MINUTE: "mi",\r
3471 \r
3472 HOUR: "h",\r
3473 \r
3474 DAY: "d",\r
3475 \r
3476 MONTH: "mo",\r
3477 \r
3478 YEAR: "y",\r
3479 \r
3480 defaults: {},\r
3481
3482 \r
3483 dayNames: [\r
3484 "Sunday",\r
3485 "Monday",\r
3486 "Tuesday",\r
3487 "Wednesday",\r
3488 "Thursday",\r
3489 "Friday",\r
3490 "Saturday"\r
3491 ],\r
3492
3493
3494 \r
3495 monthNames: [\r
3496 "January",\r
3497 "February",\r
3498 "March",\r
3499 "April",\r
3500 "May",\r
3501 "June",\r
3502 "July",\r
3503 "August",\r
3504 "September",\r
3505 "October",\r
3506 "November",\r
3507 "December"\r
3508 ],\r
3509
3510
3511 \r
3512 monthNumbers: {\r
3513 January: 0,\r
3514 Jan: 0,\r
3515 February: 1,\r
3516 Feb: 1,\r
3517 March: 2,\r
3518 Mar: 2,\r
3519 April: 3,\r
3520 Apr: 3,\r
3521 May: 4,\r
3522 June: 5,\r
3523 Jun: 5,\r
3524 July: 6,\r
3525 Jul: 6,\r
3526 August: 7,\r
3527 Aug: 7,\r
3528 September: 8,\r
3529 Sep: 8,\r
3530 October: 9,\r
3531 Oct: 9,\r
3532 November: 10,\r
3533 Nov: 10,\r
3534 December: 11,\r
3535 Dec: 11\r
3536 },\r
3537
3538
3539 \r
3540 defaultFormat: "m/d/Y",\r
3541
3542
3543 \r
3544 getShortMonthName: function(month) {\r
3545 return utilDate.monthNames[month].substring(0, 3);\r
3546 },\r
3547
3548
3549 \r
3550 getShortDayName: function(day) {\r
3551 return utilDate.dayNames[day].substring(0, 3);\r
3552 },\r
3553
3554
3555 \r
3556 getMonthNumber: function(name) {\r
3557
3558 return utilDate.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];\r
3559 },\r
3560
3561 \r
3562 formatContainsHourInfo: function(format) {\r
3563 return hourInfoRe.test(format.replace(stripEscapeRe, ''));\r
3564 },\r
3565 \r
3566 formatContainsDateInfo: function(format) {\r
3567 return dateInfoRe.test(format.replace(stripEscapeRe, ''));\r
3568 },\r
3569 \r
3570 unescapeFormat: function(format) {\r
3571
3572
3573
3574 return format.replace(slashRe, '');\r
3575 },\r
3576 \r
3577 formatCodes: {\r
3578 d: "Ext.String.leftPad(m.getDate(), 2, '0')",\r
3579 D: "Ext.Date.getShortDayName(m.getDay())",\r
3580
3581 j: "m.getDate()",\r
3582 l: "Ext.Date.dayNames[m.getDay()]",\r
3583 N: "(m.getDay() ? m.getDay() : 7)",\r
3584 S: "Ext.Date.getSuffix(m)",\r
3585 w: "m.getDay()",\r
3586 z: "Ext.Date.getDayOfYear(m)",\r
3587 W: "Ext.String.leftPad(Ext.Date.getWeekOfYear(m), 2, '0')",\r
3588 F: "Ext.Date.monthNames[m.getMonth()]",\r
3589 m: "Ext.String.leftPad(m.getMonth() + 1, 2, '0')",\r
3590 M: "Ext.Date.getShortMonthName(m.getMonth())",\r
3591
3592 n: "(m.getMonth() + 1)",\r
3593 t: "Ext.Date.getDaysInMonth(m)",\r
3594 L: "(Ext.Date.isLeapYear(m) ? 1 : 0)",\r
3595 o: "(m.getFullYear() + (Ext.Date.getWeekOfYear(m) == 1 && m.getMonth() > 0 ? +1 : (Ext.Date.getWeekOfYear(m) >= 52 && m.getMonth() < 11 ? -1 : 0)))",\r
3596 Y: "Ext.String.leftPad(m.getFullYear(), 4, '0')",\r
3597 y: "('' + m.getFullYear()).substring(2, 4)",\r
3598 a: "(m.getHours() < 12 ? 'am' : 'pm')",\r
3599 A: "(m.getHours() < 12 ? 'AM' : 'PM')",\r
3600 g: "((m.getHours() % 12) ? m.getHours() % 12 : 12)",\r
3601 G: "m.getHours()",\r
3602 h: "Ext.String.leftPad((m.getHours() % 12) ? m.getHours() % 12 : 12, 2, '0')",\r
3603 H: "Ext.String.leftPad(m.getHours(), 2, '0')",\r
3604 i: "Ext.String.leftPad(m.getMinutes(), 2, '0')",\r
3605 s: "Ext.String.leftPad(m.getSeconds(), 2, '0')",\r
3606 u: "Ext.String.leftPad(m.getMilliseconds(), 3, '0')",\r
3607 O: "Ext.Date.getGMTOffset(m)",\r
3608 P: "Ext.Date.getGMTOffset(m, true)",\r
3609 T: "Ext.Date.getTimezone(m)",\r
3610 Z: "(m.getTimezoneOffset() * -60)",\r
3611 c: function() {\r
3612
3613 var c = "Y-m-dTH:i:sP",\r
3614 code = [],\r
3615 i,\r
3616 l = c.length,\r
3617 e;\r
3618 for (i = 0; i < l; ++i) {\r
3619 e = c.charAt(i);\r
3620 code.push(e === "T" ? "'T'" : utilDate.getFormatCode(e));\r
3621 }\r
3622
3623 return code.join(" + ");\r
3624 },\r
3625 C: function() {\r
3626
3627 return 'm.toISOString()';\r
3628 },\r
3629 U: "Math.round(m.getTime() / 1000)"\r
3630 },\r
3631 \r
3632 isValid: function(y, m, d, h, i, s, ms) {\r
3633
3634 h = h || 0;\r
3635 i = i || 0;\r
3636 s = s || 0;\r
3637 ms = ms || 0;\r
3638
3639 var dt = utilDate.add(new nativeDate(y < 100 ? 100 : y, m - 1, d, h, i, s, ms), utilDate.YEAR, y < 100 ? y - 100 : 0);\r
3640 return y === dt.getFullYear() && m === dt.getMonth() + 1 && d === dt.getDate() && h === dt.getHours() && i === dt.getMinutes() && s === dt.getSeconds() && ms === dt.getMilliseconds();\r
3641 },\r
3642 \r
3643 parse: function(input, format, strict) {\r
3644 var p = utilDate.parseFunctions;\r
3645 if (p[format] == null) {\r
3646 utilDate.createParser(format);\r
3647 }\r
3648 return p[format].call(utilDate, input, Ext.isDefined(strict) ? strict : utilDate.useStrict);\r
3649 },\r
3650
3651 parseDate: function(input, format, strict) {\r
3652 return utilDate.parse(input, format, strict);\r
3653 },\r
3654 \r
3655 getFormatCode: function(character) {\r
3656 var f = utilDate.formatCodes[character];\r
3657 if (f) {\r
3658 f = typeof f === 'function' ? f() : f;\r
3659 utilDate.formatCodes[character] = f;\r
3660 }\r
3661
3662
3663 return f || ("'" + Ext.String.escape(character) + "'");\r
3664 },\r
3665 \r
3666 createFormat: function(format) {\r
3667 var code = [],\r
3668 special = false,\r
3669 ch = '',\r
3670 i;\r
3671 for (i = 0; i < format.length; ++i) {\r
3672 ch = format.charAt(i);\r
3673 if (!special && ch === "\\") {\r
3674 special = true;\r
3675 } else if (special) {\r
3676 special = false;\r
3677 code.push("'" + Ext.String.escape(ch) + "'");\r
3678 } else {\r
3679 if (ch === '\n') {\r
3680 code.push("'\\n'");\r
3681 } else {\r
3682 code.push(utilDate.getFormatCode(ch));\r
3683 }\r
3684 }\r
3685 }\r
3686 utilDate.formatFunctions[format] = Ext.functionFactory("var m=this;return " + code.join('+'));\r
3687 },\r
3688 \r
3689 createParser: function(format) {\r
3690 var regexNum = utilDate.parseRegexes.length,\r
3691 currentGroup = 1,\r
3692 calc = [],\r
3693 regex = [],\r
3694 special = false,\r
3695 ch = "",\r
3696 i = 0,\r
3697 len = format.length,\r
3698 atEnd = [],\r
3699 obj;\r
3700 for (; i < len; ++i) {\r
3701 ch = format.charAt(i);\r
3702 if (!special && ch === "\\") {\r
3703 special = true;\r
3704 } else if (special) {\r
3705 special = false;\r
3706 regex.push(Ext.String.escape(ch));\r
3707 } else {\r
3708 obj = utilDate.formatCodeToRegex(ch, currentGroup);\r
3709 currentGroup += obj.g;\r
3710 regex.push(obj.s);\r
3711 if (obj.g && obj.c) {\r
3712 if (obj.calcAtEnd) {\r
3713 atEnd.push(obj.c);\r
3714 } else {\r
3715 calc.push(obj.c);\r
3716 }\r
3717 }\r
3718 }\r
3719 }\r
3720 calc = calc.concat(atEnd);\r
3721 utilDate.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", 'i');\r
3722 utilDate.parseFunctions[format] = Ext.functionFactory("input", "strict", xf(code, regexNum, calc.join('')));\r
3723 },\r
3724 \r
3725 parseCodes: {\r
3726 \r
3727 d: {\r
3728 g: 1,\r
3729 c: "d = parseInt(results[{0}], 10);\n",\r
3730 s: "(3[0-1]|[1-2][0-9]|0[1-9])"\r
3731 },\r
3732
3733 j: {\r
3734 g: 1,\r
3735 c: "d = parseInt(results[{0}], 10);\n",\r
3736 s: "(3[0-1]|[1-2][0-9]|[1-9])"\r
3737 },\r
3738
3739 D: function() {\r
3740 for (var a = [],\r
3741 i = 0; i < 7; a.push(utilDate.getShortDayName(i)) , ++i){}\r
3742
3743 return {\r
3744 g: 0,\r
3745 c: null,\r
3746 s: "(?:" + a.join("|") + ")"\r
3747 };\r
3748 },\r
3749 l: function() {\r
3750 return {\r
3751 g: 0,\r
3752 c: null,\r
3753 s: "(?:" + utilDate.dayNames.join("|") + ")"\r
3754 };\r
3755 },\r
3756 N: {\r
3757 g: 0,\r
3758 c: null,\r
3759 s: "[1-7]"\r
3760 },\r
3761
3762
3763 S: {\r
3764 g: 0,\r
3765 c: null,\r
3766 s: "(?:st|nd|rd|th)"\r
3767 },\r
3768
3769 w: {\r
3770 g: 0,\r
3771 c: null,\r
3772 s: "[0-6]"\r
3773 },\r
3774
3775 z: {\r
3776 g: 1,\r
3777 c: "z = parseInt(results[{0}], 10);\n",\r
3778 s: "(\\d{1,3})"\r
3779 },\r
3780
3781 W: {\r
3782 g: 1,\r
3783 c: "W = parseInt(results[{0}], 10);\n",\r
3784 s: "(\\d{2})"\r
3785 },\r
3786
3787 F: function() {\r
3788 return {\r
3789 g: 1,\r
3790 c: "m = parseInt(me.getMonthNumber(results[{0}]), 10);\n",\r
3791
3792 s: "(" + utilDate.monthNames.join("|") + ")"\r
3793 };\r
3794 },\r
3795 M: function() {\r
3796 for (var a = [],\r
3797 i = 0; i < 12; a.push(utilDate.getShortMonthName(i)) , ++i){}\r
3798
3799 return Ext.applyIf({\r
3800 s: "(" + a.join("|") + ")"\r
3801 }, utilDate.formatCodeToRegex("F"));\r
3802 },\r
3803 m: {\r
3804 g: 1,\r
3805 c: "m = parseInt(results[{0}], 10) - 1;\n",\r
3806 s: "(1[0-2]|0[1-9])"\r
3807 },\r
3808
3809 n: {\r
3810 g: 1,\r
3811 c: "m = parseInt(results[{0}], 10) - 1;\n",\r
3812 s: "(1[0-2]|[1-9])"\r
3813 },\r
3814
3815 t: {\r
3816 g: 0,\r
3817 c: null,\r
3818 s: "(?:\\d{2})"\r
3819 },\r
3820
3821 L: {\r
3822 g: 0,\r
3823 c: null,\r
3824 s: "(?:1|0)"\r
3825 },\r
3826 o: {\r
3827 g: 1,\r
3828 c: "y = parseInt(results[{0}], 10);\n",\r
3829 s: "(\\d{4})"\r
3830 },\r
3831
3832 Y: {\r
3833 g: 1,\r
3834 c: "y = parseInt(results[{0}], 10);\n",\r
3835 s: "(\\d{4})"\r
3836 },\r
3837
3838 y: {\r
3839 g: 1,\r
3840 c: "var ty = parseInt(results[{0}], 10);\n" + "y = ty > me.y2kYear ? 1900 + ty : 2000 + ty;\n",\r
3841
3842 s: "(\\d{2})"\r
3843 },\r
3844 \r
3845
3846 a: {\r
3847 g: 1,\r
3848 c: "if (/(am)/i.test(results[{0}])) {\n" + "if (!h || h == 12) { h = 0; }\n" + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",\r
3849 s: "(am|pm|AM|PM)",\r
3850 calcAtEnd: true\r
3851 },\r
3852
3853
3854 A: {\r
3855 g: 1,\r
3856 c: "if (/(am)/i.test(results[{0}])) {\n" + "if (!h || h == 12) { h = 0; }\n" + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",\r
3857 s: "(AM|PM|am|pm)",\r
3858 calcAtEnd: true\r
3859 },\r
3860
3861 g: {\r
3862 g: 1,\r
3863 c: "h = parseInt(results[{0}], 10);\n",\r
3864 s: "(1[0-2]|[0-9])"\r
3865 },\r
3866
3867 G: {\r
3868 g: 1,\r
3869 c: "h = parseInt(results[{0}], 10);\n",\r
3870 s: "(2[0-3]|1[0-9]|[0-9])"\r
3871 },\r
3872
3873 h: {\r
3874 g: 1,\r
3875 c: "h = parseInt(results[{0}], 10);\n",\r
3876 s: "(1[0-2]|0[1-9])"\r
3877 },\r
3878
3879 H: {\r
3880 g: 1,\r
3881 c: "h = parseInt(results[{0}], 10);\n",\r
3882 s: "(2[0-3]|[0-1][0-9])"\r
3883 },\r
3884
3885 i: {\r
3886 g: 1,\r
3887 c: "i = parseInt(results[{0}], 10);\n",\r
3888 s: "([0-5][0-9])"\r
3889 },\r
3890
3891 s: {\r
3892 g: 1,\r
3893 c: "s = parseInt(results[{0}], 10);\n",\r
3894 s: "([0-5][0-9])"\r
3895 },\r
3896
3897 u: {\r
3898 g: 1,\r
3899 c: "ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n",\r
3900 s: "(\\d+)"\r
3901 },\r
3902
3903 O: {\r
3904 g: 1,\r
3905 c: [\r
3906 "o = results[{0}];",\r
3907 "var sn = o.substring(0,1),",\r
3908
3909 "hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),",\r
3910
3911 "mn = o.substring(3,5) % 60;",\r
3912
3913 "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"\r
3914 ].
3915 join("\n"),\r
3916 s: "([+-]\\d{4})"\r
3917 },\r
3918
3919 P: {\r
3920 g: 1,\r
3921 c: [\r
3922 "o = results[{0}];",\r
3923 "var sn = o.substring(0,1),",\r
3924
3925 "hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),",\r
3926
3927 "mn = o.substring(4,6) % 60;",\r
3928
3929 "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"\r
3930 ].
3931 join("\n"),\r
3932 s: "([+-]\\d{2}:\\d{2})"\r
3933 },\r
3934
3935 T: {\r
3936 g: 0,\r
3937 c: null,\r
3938 s: "[A-Z]{1,5}"\r
3939 },\r
3940
3941 Z: {\r
3942 g: 1,\r
3943 c: "zz = results[{0}] * 1;\n" +
3944 "zz = (-43200 <= zz && zz <= 50400)? zz : null;\n",\r
3945 s: "([+-]?\\d{1,5})"\r
3946 },\r
3947
3948 c: function() {\r
3949 var calc = [],\r
3950 arr = [\r
3951 utilDate.formatCodeToRegex("Y", 1),\r
3952
3953 utilDate.formatCodeToRegex("m", 2),\r
3954
3955 utilDate.formatCodeToRegex("d", 3),\r
3956
3957 utilDate.formatCodeToRegex("H", 4),\r
3958
3959 utilDate.formatCodeToRegex("i", 5),\r
3960
3961 utilDate.formatCodeToRegex("s", 6),\r
3962
3963 {\r
3964 c: "ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"\r
3965 },\r
3966
3967 {\r
3968 c: [\r
3969
3970 "if(results[8]) {",\r
3971
3972 "if(results[8] == 'Z'){",\r
3973 "zz = 0;",\r
3974
3975 "}else if (results[8].indexOf(':') > -1){",\r
3976 utilDate.formatCodeToRegex("P", 8).c,\r
3977
3978 "}else{",\r
3979 utilDate.formatCodeToRegex("O", 8).c,\r
3980
3981 "}",\r
3982 "}"\r
3983 ].join('\n')\r
3984 }\r
3985 ],\r
3986 i, l;\r
3987 for (i = 0 , l = arr.length; i < l; ++i) {\r
3988 calc.push(arr[i].c);\r
3989 }\r
3990 return {\r
3991 g: 1,\r
3992 c: calc.join(""),\r
3993 s: [\r
3994 arr[0].s,\r
3995
3996 "(?:",\r
3997 "-",\r
3998 arr[1].s,\r
3999
4000 "(?:",\r
4001 "-",\r
4002 arr[2].s,\r
4003
4004 "(?:",\r
4005 "(?:T| )?",\r
4006
4007 arr[3].s,\r
4008 ":",\r
4009 arr[4].s,\r
4010
4011 "(?::",\r
4012 arr[5].s,\r
4013 ")?",\r
4014
4015 "(?:(?:\\.|,)(\\d+))?",\r
4016
4017 "(Z|(?:[-+]\\d{2}(?::)?\\d{2}))?",\r
4018
4019 ")?",\r
4020 ")?",\r
4021 ")?"\r
4022 ].join("")\r
4023 };\r
4024 },\r
4025 U: {\r
4026 g: 1,\r
4027 c: "u = parseInt(results[{0}], 10);\n",\r
4028 s: "(-?\\d+)"\r
4029 }\r
4030 },\r
4031
4032
4033 \r
4034 dateFormat: function(date, format) {\r
4035 return utilDate.format(date, format);\r
4036 },\r
4037 \r
4038 isEqual: function(date1, date2) {\r
4039
4040 if (date1 && date2) {\r
4041 return (date1.getTime() === date2.getTime());\r
4042 }\r
4043
4044 return !(date1 || date2);\r
4045 },\r
4046 \r
4047 format: function(date, format) {\r
4048 var formatFunctions = utilDate.formatFunctions;\r
4049 if (!Ext.isDate(date)) {\r
4050 return '';\r
4051 }\r
4052 if (formatFunctions[format] == null) {\r
4053 utilDate.createFormat(format);\r
4054 }\r
4055 return formatFunctions[format].call(date) + '';\r
4056 },\r
4057 \r
4058 getTimezone: function(date) {\r
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071 return date.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,5})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");\r
4072 },\r
4073 \r
4074 getGMTOffset: function(date, colon) {\r
4075 var offset = date.getTimezoneOffset();\r
4076 return (offset > 0 ? "-" : "+") + Ext.String.leftPad(Math.floor(Math.abs(offset) / 60), 2, "0") + (colon ? ":" : "") + Ext.String.leftPad(Math.abs(offset % 60), 2, "0");\r
4077 },\r
4078 \r
4079 getDayOfYear: function(date) {\r
4080 var num = 0,\r
4081 d = utilDate.clone(date),\r
4082 m = date.getMonth(),\r
4083 i;\r
4084 for (i = 0 , d.setDate(1) , d.setMonth(0); i < m; d.setMonth(++i)) {\r
4085 num += utilDate.getDaysInMonth(d);\r
4086 }\r
4087 return num + date.getDate() - 1;\r
4088 },\r
4089 \r
4090 getWeekOfYear: (function() {\r
4091
4092 var ms1d = 86400000,\r
4093
4094 ms7d = 7 * ms1d;\r
4095
4096 return function(date) {\r
4097
4098 var DC3 = nativeDate.UTC(date.getFullYear(), date.getMonth(), date.getDate() + 3) / ms1d,\r
4099
4100 AWN = Math.floor(DC3 / 7),\r
4101
4102 Wyr = new nativeDate(AWN * ms7d).getUTCFullYear();\r
4103 return AWN - Math.floor(nativeDate.UTC(Wyr, 0, 7) / ms7d) + 1;\r
4104 };\r
4105 }()),\r
4106 \r
4107 isLeapYear: function(date) {\r
4108 var year = date.getFullYear();\r
4109 return !!((year & 3) === 0 && (year % 100 || (year % 400 === 0 && year)));\r
4110 },\r
4111 \r
4112 getFirstDayOfMonth: function(date) {\r
4113 var day = (date.getDay() - (date.getDate() - 1)) % 7;\r
4114 return (day < 0) ? (day + 7) : day;\r
4115 },\r
4116 \r
4117 getLastDayOfMonth: function(date) {\r
4118 return utilDate.getLastDateOfMonth(date).getDay();\r
4119 },\r
4120 \r
4121 getFirstDateOfMonth: function(date) {\r
4122 return new nativeDate(date.getFullYear(), date.getMonth(), 1);\r
4123 },\r
4124 \r
4125 getLastDateOfMonth: function(date) {\r
4126 return new nativeDate(date.getFullYear(), date.getMonth(), utilDate.getDaysInMonth(date));\r
4127 },\r
4128 \r
4129 getDaysInMonth: (function() {\r
4130 var daysInMonth = [\r
4131 31,\r
4132 28,\r
4133 31,\r
4134 30,\r
4135 31,\r
4136 30,\r
4137 31,\r
4138 31,\r
4139 30,\r
4140 31,\r
4141 30,\r
4142 31\r
4143 ];\r
4144 return function(date) {\r
4145
4146 var m = date.getMonth();\r
4147 return m === 1 && utilDate.isLeapYear(date) ? 29 : daysInMonth[m];\r
4148 };\r
4149 }()),\r
4150
4151 \r
4152 getSuffix: function(date) {\r
4153 switch (date.getDate()) {\r
4154 case 1:\r
4155 case 21:\r
4156 case 31:\r
4157 return "st";\r
4158 case 2:\r
4159 case 22:\r
4160 return "nd";\r
4161 case 3:\r
4162 case 23:\r
4163 return "rd";\r
4164 default:\r
4165 return "th";\r
4166 }\r
4167 },\r
4168
4169 \r
4170 clone: function(date) {\r
4171 return new nativeDate(date.getTime());\r
4172 },\r
4173 \r
4174 isDST: function(date) {\r
4175
4176
4177 return new nativeDate(date.getFullYear(), 0, 1).getTimezoneOffset() !== date.getTimezoneOffset();\r
4178 },\r
4179 \r
4180 clearTime: function(date, clone) {\r
4181
4182 if (isNaN(date.getTime())) {\r
4183 return date;\r
4184 }\r
4185 if (clone) {\r
4186 return utilDate.clearTime(utilDate.clone(date));\r
4187 }\r
4188
4189 var d = date.getDate(),\r
4190 hr, c;\r
4191
4192 date.setHours(0);\r
4193 date.setMinutes(0);\r
4194 date.setSeconds(0);\r
4195 date.setMilliseconds(0);\r
4196 if (date.getDate() !== d) {\r
4197
4198
4199
4200
4201 for (hr = 1 , c = utilDate.add(date, utilDate.HOUR, hr); c.getDate() !== d; hr++ , c = utilDate.add(date, utilDate.HOUR, hr)){}\r
4202 date.setDate(d);\r
4203 date.setHours(c.getHours());\r
4204 }\r
4205 return date;\r
4206 },\r
4207 \r
4208 add: function(date, interval, value) {\r
4209 var d = utilDate.clone(date),\r
4210 day, decimalValue,\r
4211 base = 0;\r
4212 if (!interval || value === 0) {\r
4213 return d;\r
4214 }\r
4215 decimalValue = value - parseInt(value, 10);\r
4216 value = parseInt(value, 10);\r
4217 if (value) {\r
4218 switch (interval.toLowerCase()) {\r
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237 case utilDate.MILLI:\r
4238 d.setTime(d.getTime() + value);\r
4239 break;\r
4240 case utilDate.SECOND:\r
4241 d.setTime(d.getTime() + value * 1000);\r
4242 break;\r
4243 case utilDate.MINUTE:\r
4244 d.setTime(d.getTime() + value * 60 * 1000);\r
4245 break;\r
4246 case utilDate.HOUR:\r
4247 d.setTime(d.getTime() + value * 60 * 60 * 1000);\r
4248 break;\r
4249 case utilDate.DAY:\r
4250 d.setDate(d.getDate() + value);\r
4251 break;\r
4252 case utilDate.MONTH:\r
4253 day = date.getDate();\r
4254 if (day > 28) {\r
4255 day = Math.min(day, utilDate.getLastDateOfMonth(utilDate.add(utilDate.getFirstDateOfMonth(date), utilDate.MONTH, value)).getDate());\r
4256 };\r
4257 d.setDate(day);\r
4258 d.setMonth(date.getMonth() + value);\r
4259 break;\r
4260 case utilDate.YEAR:\r
4261 day = date.getDate();\r
4262 if (day > 28) {\r
4263 day = Math.min(day, utilDate.getLastDateOfMonth(utilDate.add(utilDate.getFirstDateOfMonth(date), utilDate.YEAR, value)).getDate());\r
4264 };\r
4265 d.setDate(day);\r
4266 d.setFullYear(date.getFullYear() + value);\r
4267 break;\r
4268 }\r
4269 }\r
4270 if (decimalValue) {\r
4271 switch (interval.toLowerCase()) {\r
4272 case utilDate.MILLI:\r
4273 base = 1;\r
4274 break;\r
4275 case utilDate.SECOND:\r
4276 base = 1000;\r
4277 break;\r
4278 case utilDate.MINUTE:\r
4279 base = 1000 * 60;\r
4280 break;\r
4281 case utilDate.HOUR:\r
4282 base = 1000 * 60 * 60;\r
4283 break;\r
4284 case utilDate.DAY:\r
4285 base = 1000 * 60 * 60 * 24;\r
4286 break;\r
4287 case utilDate.MONTH:\r
4288 day = utilDate.getDaysInMonth(d);\r
4289 base = 1000 * 60 * 60 * 24 * day;\r
4290 break;\r
4291 case utilDate.YEAR:\r
4292 day = (utilDate.isLeapYear(d) ? 366 : 365);\r
4293 base = 1000 * 60 * 60 * 24 * day;\r
4294 break;\r
4295 }\r
4296 if (base) {\r
4297 d.setTime(d.getTime() + base * decimalValue);\r
4298 }\r
4299 }\r
4300 return d;\r
4301 },\r
4302 \r
4303 subtract: function(date, interval, value) {\r
4304 return utilDate.add(date, interval, -value);\r
4305 },\r
4306 \r
4307 between: function(date, start, end) {\r
4308 var t = date.getTime();\r
4309 return start.getTime() <= t && t <= end.getTime();\r
4310 },\r
4311
4312 compat: function() {\r
4313 var p,\r
4314 statics = [\r
4315 'useStrict',\r
4316 'formatCodeToRegex',\r
4317 'parseFunctions',\r
4318 'parseRegexes',\r
4319 'formatFunctions',\r
4320 'y2kYear',\r
4321 'MILLI',\r
4322 'SECOND',\r
4323 'MINUTE',\r
4324 'HOUR',\r
4325 'DAY',\r
4326 'MONTH',\r
4327 'YEAR',\r
4328 'defaults',\r
4329 'dayNames',\r
4330 'monthNames',\r
4331 'monthNumbers',\r
4332 'getShortMonthName',\r
4333 'getShortDayName',\r
4334 'getMonthNumber',\r
4335 'formatCodes',\r
4336 'isValid',\r
4337 'parseDate',\r
4338 'getFormatCode',\r
4339 'createFormat',\r
4340 'createParser',\r
4341 'parseCodes'\r
4342 ],\r
4343 proto = [\r
4344 'dateFormat',\r
4345 'format',\r
4346 'getTimezone',\r
4347 'getGMTOffset',\r
4348 'getDayOfYear',\r
4349 'getWeekOfYear',\r
4350 'isLeapYear',\r
4351 'getFirstDayOfMonth',\r
4352 'getLastDayOfMonth',\r
4353 'getDaysInMonth',\r
4354 'getSuffix',\r
4355 'clone',\r
4356 'isDST',\r
4357 'clearTime',\r
4358 'add',\r
4359 'between'\r
4360 ],\r
4361 sLen = statics.length,\r
4362 pLen = proto.length,\r
4363 stat, prot, s;\r
4364
4365 for (s = 0; s < sLen; s++) {\r
4366 stat = statics[s];\r
4367 nativeDate[stat] = utilDate[stat];\r
4368 }\r
4369
4370 for (p = 0; p < pLen; p++) {\r
4371 prot = proto[p];\r
4372 nativeDate.prototype[prot] = function() {\r
4373 var args = Array.prototype.slice.call(arguments);\r
4374 args.unshift(this);\r
4375 return utilDate[prot].apply(utilDate, args);\r
4376 };\r
4377 }\r
4378 },\r
4379 \r
4380 diff: function(min, max, unit) {\r
4381 var est,\r
4382 diff = +max - min;\r
4383 switch (unit) {\r
4384 case utilDate.MILLI:\r
4385 return diff;\r
4386 case utilDate.SECOND:\r
4387 return Math.floor(diff / 1000);\r
4388 case utilDate.MINUTE:\r
4389 return Math.floor(diff / 60000);\r
4390 case utilDate.HOUR:\r
4391 return Math.floor(diff / 3600000);\r
4392 case utilDate.DAY:\r
4393 return Math.floor(diff / 86400000);\r
4394 case 'w':\r
4395 return Math.floor(diff / 604800000);\r
4396 case utilDate.MONTH:\r
4397 est = (max.getFullYear() * 12 + max.getMonth()) - (min.getFullYear() * 12 + min.getMonth());\r
4398 if (utilDate.add(min, unit, est) > max) {\r
4399 return est - 1;\r
4400 };\r
4401 return est;\r
4402 case utilDate.YEAR:\r
4403 est = max.getFullYear() - min.getFullYear();\r
4404 if (utilDate.add(min, unit, est) > max) {\r
4405 return est - 1;\r
4406 } else {\r
4407 return est;\r
4408 };\r
4409 }\r
4410 },\r
4411 \r
4412 align: function(date, unit, step) {\r
4413 var num = new nativeDate(+date);\r
4414 switch (unit.toLowerCase()) {\r
4415 case utilDate.MILLI:\r
4416 return num;\r
4417 case utilDate.SECOND:\r
4418 num.setUTCSeconds(num.getUTCSeconds() - num.getUTCSeconds() % step);\r
4419 num.setUTCMilliseconds(0);\r
4420 return num;\r
4421 case utilDate.MINUTE:\r
4422 num.setUTCMinutes(num.getUTCMinutes() - num.getUTCMinutes() % step);\r
4423 num.setUTCSeconds(0);\r
4424 num.setUTCMilliseconds(0);\r
4425 return num;\r
4426 case utilDate.HOUR:\r
4427 num.setUTCHours(num.getUTCHours() - num.getUTCHours() % step);\r
4428 num.setUTCMinutes(0);\r
4429 num.setUTCSeconds(0);\r
4430 num.setUTCMilliseconds(0);\r
4431 return num;\r
4432 case utilDate.DAY:\r
4433 if (step === 7 || step === 14) {\r
4434 num.setUTCDate(num.getUTCDate() - num.getUTCDay() + 1);\r
4435 };\r
4436 num.setUTCHours(0);\r
4437 num.setUTCMinutes(0);\r
4438 num.setUTCSeconds(0);\r
4439 num.setUTCMilliseconds(0);\r
4440 return num;\r
4441 case utilDate.MONTH:\r
4442 num.setUTCMonth(num.getUTCMonth() - (num.getUTCMonth() - 1) % step, 1);\r
4443 num.setUTCHours(0);\r
4444 num.setUTCMinutes(0);\r
4445 num.setUTCSeconds(0);\r
4446 num.setUTCMilliseconds(0);\r
4447 return num;\r
4448 case utilDate.YEAR:\r
4449 num.setUTCFullYear(num.getUTCFullYear() - num.getUTCFullYear() % step, 1, 1);\r
4450 num.setUTCHours(0);\r
4451 num.setUTCMinutes(0);\r
4452 num.setUTCSeconds(0);\r
4453 num.setUTCMilliseconds(0);\r
4454 return date;\r
4455 }\r
4456 }\r
4457 };\r
4458}());\r
4459\r
4460\r
4461Ext.Function = (function() {\r
4462
4463
4464
4465
4466 var lastTime = 0,\r
4467 animFrameId,\r
4468 animFrameHandlers = [],\r
4469 animFrameNoArgs = [],\r
4470 idSource = 0,\r
4471 animFrameMap = {},\r
4472 win = window,\r
4473 global = Ext.global,\r
4474 hasImmediate = !!(global.setImmediate && global.clearImmediate),\r
4475 requestAnimFrame = win.requestAnimationFrame || win.webkitRequestAnimationFrame || win.mozRequestAnimationFrame || win.oRequestAnimationFrame || function(callback) {\r
4476 var currTime = Ext.now(),\r
4477 timeToCall = Math.max(0, 16 - (currTime - lastTime)),\r
4478 id = win.setTimeout(function() {\r
4479 callback(currTime + timeToCall);\r
4480 }, timeToCall);\r
4481 lastTime = currTime + timeToCall;\r
4482 return id;\r
4483 },\r
4484 fireHandlers = function() {\r
4485 var len = animFrameHandlers.length,\r
4486 id, i, handler;\r
4487 animFrameId = null;\r
4488
4489 for (i = 0; i < len; i++) {\r
4490 handler = animFrameHandlers[i];\r
4491 id = handler[3];\r
4492
4493 if (animFrameMap[id]) {\r
4494 handler[0].apply(handler[1] || global, handler[2] || animFrameNoArgs);\r
4495 delete animFrameMap[id];\r
4496 }\r
4497 }\r
4498
4499
4500 animFrameHandlers = animFrameHandlers.slice(len);\r
4501 },\r
4502 fireElevatedHandlers = function() {\r
4503 Ext.elevateFunction(fireHandlers);\r
4504 },\r
4505 ExtFunction = {\r
4506 \r
4507 flexSetter: function(setter) {\r
4508 return function(name, value) {\r
4509 var k, i;\r
4510 if (name !== null) {\r
4511 if (typeof name !== 'string') {\r
4512 for (k in name) {\r
4513 if (name.hasOwnProperty(k)) {\r
4514 setter.call(this, k, name[k]);\r
4515 }\r
4516 }\r
4517 if (Ext.enumerables) {\r
4518 for (i = Ext.enumerables.length; i--; ) {\r
4519 k = Ext.enumerables[i];\r
4520 if (name.hasOwnProperty(k)) {\r
4521 setter.call(this, k, name[k]);\r
4522 }\r
4523 }\r
4524 }\r
4525 } else {\r
4526 setter.call(this, name, value);\r
4527 }\r
4528 }\r
4529 return this;\r
4530 };\r
4531 },\r
4532 \r
4533 bind: function(fn, scope, args, appendArgs) {\r
4534 if (arguments.length === 2) {\r
4535 return function() {\r
4536 return fn.apply(scope, arguments);\r
4537 };\r
4538 }\r
4539 var method = fn,\r
4540 slice = Array.prototype.slice;\r
4541 return function() {\r
4542 var callArgs = args || arguments;\r
4543 if (appendArgs === true) {\r
4544 callArgs = slice.call(arguments, 0);\r
4545 callArgs = callArgs.concat(args);\r
4546 } else if (typeof appendArgs === 'number') {\r
4547 callArgs = slice.call(arguments, 0);\r
4548
4549 Ext.Array.insert(callArgs, appendArgs, args);\r
4550 }\r
4551 return method.apply(scope || global, callArgs);\r
4552 };\r
4553 },\r
4554 \r
4555 bindCallback: function(callback, scope, args, delay, caller) {\r
4556 return function() {\r
4557 var a = Ext.Array.slice(arguments);\r
4558 return Ext.callback(callback, scope, args ? args.concat(a) : a, delay, caller);\r
4559 };\r
4560 },\r
4561 \r
4562 pass: function(fn, args, scope) {\r
4563 if (!Ext.isArray(args)) {\r
4564 if (Ext.isIterable(args)) {\r
4565 args = Ext.Array.clone(args);\r
4566 } else {\r
4567 args = args !== undefined ? [\r
4568 args\r
4569 ] : [];\r
4570 }\r
4571 }\r
4572 return function() {\r
4573 var fnArgs = args.slice();\r
4574 fnArgs.push.apply(fnArgs, arguments);\r
4575 return fn.apply(scope || this, fnArgs);\r
4576 };\r
4577 },\r
4578 \r
4579 alias: function(object, methodName) {\r
4580 return function() {\r
4581 return object[methodName].apply(object, arguments);\r
4582 };\r
4583 },\r
4584 \r
4585 clone: function(method) {\r
4586 return function() {\r
4587 return method.apply(this, arguments);\r
4588 };\r
4589 },\r
4590 \r
4591 createInterceptor: function(origFn, newFn, scope, returnValue) {\r
4592 if (!Ext.isFunction(newFn)) {\r
4593 return origFn;\r
4594 } else {\r
4595 returnValue = Ext.isDefined(returnValue) ? returnValue : null;\r
4596 return function() {\r
4597 var me = this,\r
4598 args = arguments;\r
4599 return (newFn.apply(scope || me || global, args) !== false) ? origFn.apply(me || global, args) : returnValue;\r
4600 };\r
4601 }\r
4602 },\r
4603 \r
4604 createDelayed: function(fn, delay, scope, args, appendArgs) {\r
4605 if (scope || args) {\r
4606 fn = Ext.Function.bind(fn, scope, args, appendArgs);\r
4607 }\r
4608 return function() {\r
4609 var me = this,\r
4610 args = Array.prototype.slice.call(arguments);\r
4611 setTimeout(function() {\r
4612 if (Ext.elevateFunction) {\r
4613 Ext.elevateFunction(fn, me, args);\r
4614 } else {\r
4615 fn.apply(me, args);\r
4616 }\r
4617 }, delay);\r
4618 };\r
4619 },\r
4620 \r
4621 defer: function(fn, millis, scope, args, appendArgs) {\r
4622 fn = Ext.Function.bind(fn, scope, args, appendArgs);\r
4623 if (millis > 0) {\r
4624 return setTimeout(function() {\r
4625 if (Ext.elevateFunction) {\r
4626 Ext.elevateFunction(fn);\r
4627 } else {\r
4628 fn();\r
4629 }\r
4630 }, millis);\r
4631 }\r
4632 fn();\r
4633 return 0;\r
4634 },\r
4635 \r
4636 interval: function(fn, millis, scope, args, appendArgs) {\r
4637 fn = Ext.Function.bind(fn, scope, args, appendArgs);\r
4638 return setInterval(function() {\r
4639 if (Ext.elevateFunction) {\r
4640 Ext.elevateFunction(fn);\r
4641 } else {\r
4642 fn();\r
4643 }\r
4644 }, millis);\r
4645 },\r
4646 \r
4647 createSequence: function(originalFn, newFn, scope) {\r
4648 if (!newFn) {\r
4649 return originalFn;\r
4650 } else {\r
4651 return function() {\r
4652 var result = originalFn.apply(this, arguments);\r
4653 newFn.apply(scope || this, arguments);\r
4654 return result;\r
4655 };\r
4656 }\r
4657 },\r
4658 \r
4659 createBuffered: function(fn, buffer, scope, args) {\r
4660 var timerId;\r
4661 return function() {\r
4662 var callArgs = args || Array.prototype.slice.call(arguments, 0),\r
4663 me = scope || this;\r
4664 if (timerId) {\r
4665 clearTimeout(timerId);\r
4666 }\r
4667 timerId = setTimeout(function() {\r
4668 if (Ext.elevateFunction) {\r
4669 Ext.elevateFunction(fn, me, callArgs);\r
4670 } else {\r
4671 fn.apply(me, callArgs);\r
4672 }\r
4673 }, buffer);\r
4674 };\r
4675 },\r
4676 \r
4677 createAnimationFrame: function(fn, scope, args, queueStrategy) {\r
4678 var timerId;\r
4679 queueStrategy = queueStrategy || 3;\r
4680 return function() {\r
4681 var callArgs = args || Array.prototype.slice.call(arguments, 0);\r
4682 scope = scope || this;\r
4683 if (queueStrategy === 3 && timerId) {\r
4684 ExtFunction.cancelAnimationFrame(timerId);\r
4685 }\r
4686 if ((queueStrategy & 1) || !timerId) {\r
4687 timerId = ExtFunction.requestAnimationFrame(function() {\r
4688 timerId = null;\r
4689 fn.apply(scope, callArgs);\r
4690 });\r
4691 }\r
4692 };\r
4693 },\r
4694 \r
4695 requestAnimationFrame: function(fn, scope, args) {\r
4696 var id = ++idSource,\r
4697
4698 handler = Array.prototype.slice.call(arguments, 0);\r
4699 handler[3] = id;\r
4700 animFrameMap[id] = 1;\r
4701
4702
4703
4704 animFrameHandlers.push(handler);\r
4705 if (!animFrameId) {\r
4706 animFrameId = requestAnimFrame(Ext.elevateFunction ? fireElevatedHandlers : fireHandlers);\r
4707 }\r
4708 return id;\r
4709 },\r
4710 cancelAnimationFrame: function(id) {\r
4711
4712
4713
4714 delete animFrameMap[id];\r
4715 },\r
4716 \r
4717 createThrottled: function(fn, interval, scope) {\r
4718 var lastCallTime = 0,\r
4719 elapsed, lastArgs, timer,\r
4720 execute = function() {\r
4721 if (Ext.elevateFunction) {\r
4722 Ext.elevateFunction(fn, scope, lastArgs);\r
4723 } else {\r
4724 fn.apply(scope, lastArgs);\r
4725 }\r
4726 lastCallTime = Ext.now();\r
4727 timer = null;\r
4728 };\r
4729 return function() {\r
4730
4731 if (!scope) {\r
4732 scope = this;\r
4733 }\r
4734 elapsed = Ext.now() - lastCallTime;\r
4735 lastArgs = arguments;\r
4736
4737
4738 if (elapsed >= interval) {\r
4739 clearTimeout(timer);\r
4740 execute();\r
4741 }\r
4742
4743 else if (!timer) {\r
4744 timer = Ext.defer(execute, interval - elapsed);\r
4745 }\r
4746 };\r
4747 },\r
4748 \r
4749 createBarrier: function(count, fn, scope) {\r
4750 return function() {\r
4751 if (!--count) {\r
4752 fn.apply(scope, arguments);\r
4753 }\r
4754 };\r
4755 },\r
4756 \r
4757 interceptBefore: function(object, methodName, fn, scope) {\r
4758 var method = object[methodName] || Ext.emptyFn;\r
4759 return (object[methodName] = function() {\r
4760 var ret = fn.apply(scope || this, arguments);\r
4761 method.apply(this, arguments);\r
4762 return ret;\r
4763 });\r
4764 },\r
4765 \r
4766 interceptAfter: function(object, methodName, fn, scope) {\r
4767 var method = object[methodName] || Ext.emptyFn;\r
4768 return (object[methodName] = function() {\r
4769 method.apply(this, arguments);\r
4770 return fn.apply(scope || this, arguments);\r
4771 });\r
4772 },\r
4773 makeCallback: function(callback, scope) {\r
4774
4775 if (!scope[callback]) {\r
4776 if (scope.$className) {\r
4777 Ext.raise('No method "' + callback + '" on ' + scope.$className);\r
4778 }\r
4779 Ext.raise('No method "' + callback + '"');\r
4780 }\r
4781
4782 return function() {\r
4783 return scope[callback].apply(scope, arguments);\r
4784 };\r
4785 },\r
4786 \r
4787 memoize: function(fn, scope, hashFn) {\r
4788 var memo = {},\r
4789 isFunc = hashFn && Ext.isFunction(hashFn);\r
4790 return function(value) {\r
4791 var key = isFunc ? hashFn.apply(scope, arguments) : value;\r
4792 if (!(key in memo)) {\r
4793 memo[key] = fn.apply(scope, arguments);\r
4794 }\r
4795 return memo[key];\r
4796 };\r
4797 }\r
4798 };\r
4799
4800 \r
4801 Ext.asap = hasImmediate ? function(fn, scope, parameters) {\r
4802 if (scope != null || parameters != null) {\r
4803 fn = ExtFunction.bind(fn, scope, parameters);\r
4804 }\r
4805 return setImmediate(function() {\r
4806 if (Ext.elevateFunction) {\r
4807 Ext.elevateFunction(fn);\r
4808 } else {\r
4809 fn();\r
4810 }\r
4811 });\r
4812 } : function(fn, scope, parameters) {\r
4813 if (scope != null || parameters != null) {\r
4814 fn = ExtFunction.bind(fn, scope, parameters);\r
4815 }\r
4816 return setTimeout(function() {\r
4817 if (Ext.elevateFunction) {\r
4818 Ext.elevateFunction(fn);\r
4819 } else {\r
4820 fn();\r
4821 }\r
4822 }, 0, true);\r
4823 } , \r
4824 Ext.asapCancel = hasImmediate ? function(id) {\r
4825 clearImmediate(id);\r
4826 } : function(id) {\r
4827 clearTimeout(id);\r
4828 };\r
4829 \r
4830 Ext.defer = ExtFunction.defer;\r
4831 \r
4832 Ext.interval = ExtFunction.interval;\r
4833 \r
4834 Ext.pass = ExtFunction.pass;\r
4835 \r
4836 Ext.bind = ExtFunction.bind;\r
4837 Ext.deferCallback = ExtFunction.requestAnimationFrame;\r
4838 return ExtFunction;\r
4839})();\r
4840\r
4841\r
4842Ext.Number = (new function() {\r
4843
4844
4845
4846
4847 var ExtNumber = this,\r
4848 isToFixedBroken = (0.9).toFixed() !== '1',\r
4849 math = Math,\r
4850 ClipDefault = {\r
4851 count: false,\r
4852 inclusive: false,\r
4853 wrap: true\r
4854 };\r
4855 Ext.apply(ExtNumber, {\r
4856 Clip: {\r
4857 DEFAULT: ClipDefault,\r
4858 COUNT: Ext.applyIf({\r
4859 count: true\r
4860 }, ClipDefault),\r
4861 INCLUSIVE: Ext.applyIf({\r
4862 inclusive: true\r
4863 }, ClipDefault),\r
4864 NOWRAP: Ext.applyIf({\r
4865 wrap: false\r
4866 }, ClipDefault)\r
4867 },\r
4868 \r
4869 clipIndices: function(length, indices, options) {\r
4870 options = options || ClipDefault;\r
4871 var defaultValue = 0,\r
4872
4873 wrap = options.wrap,\r
4874 begin, end, i;\r
4875 indices = indices || [];\r
4876 for (i = 0; i < 2; ++i) {\r
4877
4878
4879 begin = end;\r
4880
4881 end = indices[i];\r
4882 if (end == null) {\r
4883 end = defaultValue;\r
4884 } else if (i && options.count) {\r
4885 end += begin;\r
4886
4887 end = (end > length) ? length : end;\r
4888 } else {\r
4889 if (wrap) {\r
4890 end = (end < 0) ? (length + end) : end;\r
4891 }\r
4892 if (i && options.inclusive) {\r
4893 ++end;\r
4894 }\r
4895 end = (end < 0) ? 0 : ((end > length) ? length : end);\r
4896 }\r
4897 defaultValue = length;\r
4898 }\r
4899
4900
4901
4902
4903 indices[0] = begin;\r
4904 indices[1] = (end < begin) ? begin : end;\r
4905 return indices;\r
4906 },\r
4907 \r
4908 constrain: function(number, min, max) {\r
4909 var x = parseFloat(number);\r
4910
4911
4912
4913 if (min === null) {\r
4914 min = number;\r
4915 }\r
4916 if (max === null) {\r
4917 max = number;\r
4918 }\r
4919
4920
4921
4922 return (x < min) ? min : ((x > max) ? max : x);\r
4923 },\r
4924 \r
4925 snap: function(value, increment, minValue, maxValue) {\r
4926 var m;\r
4927
4928
4929 if (value === undefined || value < minValue) {\r
4930 return minValue || 0;\r
4931 }\r
4932 if (increment) {\r
4933 m = value % increment;\r
4934 if (m !== 0) {\r
4935 value -= m;\r
4936 if (m * 2 >= increment) {\r
4937 value += increment;\r
4938 } else if (m * 2 < -increment) {\r
4939 value -= increment;\r
4940 }\r
4941 }\r
4942 }\r
4943 return ExtNumber.constrain(value, minValue, maxValue);\r
4944 },\r
4945 \r
4946 snapInRange: function(value, increment, minValue, maxValue) {\r
4947 var tween;\r
4948
4949 minValue = (minValue || 0);\r
4950
4951 if (value === undefined || value < minValue) {\r
4952 return minValue;\r
4953 }\r
4954
4955 if (increment && (tween = ((value - minValue) % increment))) {\r
4956 value -= tween;\r
4957 tween *= 2;\r
4958 if (tween >= increment) {\r
4959 value += increment;\r
4960 }\r
4961 }\r
4962
4963 if (maxValue !== undefined) {\r
4964 if (value > (maxValue = ExtNumber.snapInRange(maxValue, increment, minValue))) {\r
4965 value = maxValue;\r
4966 }\r
4967 }\r
4968 return value;\r
4969 },\r
4970 \r
4971 sign: function(x) {\r
4972 x = +x;\r
4973
4974 if (x === 0 || isNaN(x)) {\r
4975 return x;\r
4976 }\r
4977 return (x > 0) ? 1 : -1;\r
4978 },\r
4979 \r
4980 toFixed: isToFixedBroken ? function(value, precision) {\r
4981 precision = precision || 0;\r
4982 var pow = math.pow(10, precision);\r
4983 return (math.round(value * pow) / pow).toFixed(precision);\r
4984 } : function(value, precision) {\r
4985 return value.toFixed(precision);\r
4986 },\r
4987 \r
4988 from: function(value, defaultValue) {\r
4989 if (isFinite(value)) {\r
4990 value = parseFloat(value);\r
4991 }\r
4992 return !isNaN(value) ? value : defaultValue;\r
4993 },\r
4994 \r
4995 randomInt: function(from, to) {\r
4996 return math.floor(math.random() * (to - from + 1) + from);\r
4997 },\r
4998 \r
4999 correctFloat: function(n) {\r
5000
5001
5002
5003 return parseFloat(n.toPrecision(14));\r
5004 }\r
5005 });\r
5006 \r
5007 Ext.num = function() {\r
5008 return ExtNumber.from.apply(this, arguments);\r
5009 };\r
5010}());\r
5011\r
5012\r
5013(function() {\r
5014
5015 var TemplateClass = function() {},\r
5016 queryRe = /^\?/,\r
5017 keyRe = /(\[):?([^\]]*)\]/g,\r
5018 nameRe = /^([^\[]+)/,\r
5019 plusRe = /\+/g,\r
5020 ExtObject = Ext.Object = {\r
5021
5022
5023
5024
5025 \r
5026 chain: Object.create || function(object) {\r
5027 TemplateClass.prototype = object;\r
5028 var result = new TemplateClass();\r
5029 TemplateClass.prototype = null;\r
5030 return result;\r
5031 },\r
5032 \r
5033 clear: function(object) {\r
5034
5035 for (var key in object) {\r
5036 delete object[key];\r
5037 }\r
5038 return object;\r
5039 },\r
5040 \r
5041 freeze: Object.freeze ? function(obj, deep) {\r
5042 if (obj && typeof obj === 'object' && !Object.isFrozen(obj)) {\r
5043 Object.freeze(obj);\r
5044 if (deep) {\r
5045 for (var name in obj) {\r
5046 ExtObject.freeze(obj[name], deep);\r
5047 }\r
5048 }\r
5049 }\r
5050 return obj;\r
5051 } : Ext.identityFn,\r
5052 \r
5053 toQueryObjects: function(name, value, recursive) {\r
5054 var self = ExtObject.toQueryObjects,\r
5055 objects = [],\r
5056 i, ln;\r
5057 if (Ext.isArray(value)) {\r
5058 for (i = 0 , ln = value.length; i < ln; i++) {\r
5059 if (recursive) {\r
5060 objects = objects.concat(self(name + '[' + i + ']', value[i], true));\r
5061 } else {\r
5062 objects.push({\r
5063 name: name,\r
5064 value: value[i]\r
5065 });\r
5066 }\r
5067 }\r
5068 } else if (Ext.isObject(value)) {\r
5069 for (i in value) {\r
5070 if (value.hasOwnProperty(i)) {\r
5071 if (recursive) {\r
5072 objects = objects.concat(self(name + '[' + i + ']', value[i], true));\r
5073 } else {\r
5074 objects.push({\r
5075 name: name,\r
5076 value: value[i]\r
5077 });\r
5078 }\r
5079 }\r
5080 }\r
5081 } else {\r
5082 objects.push({\r
5083 name: name,\r
5084 value: value\r
5085 });\r
5086 }\r
5087 return objects;\r
5088 },\r
5089 \r
5090 toQueryString: function(object, recursive) {\r
5091 var paramObjects = [],\r
5092 params = [],\r
5093 i, j, ln, paramObject, value;\r
5094 for (i in object) {\r
5095 if (object.hasOwnProperty(i)) {\r
5096 paramObjects = paramObjects.concat(ExtObject.toQueryObjects(i, object[i], recursive));\r
5097 }\r
5098 }\r
5099 for (j = 0 , ln = paramObjects.length; j < ln; j++) {\r
5100 paramObject = paramObjects[j];\r
5101 value = paramObject.value;\r
5102 if (Ext.isEmpty(value)) {\r
5103 value = '';\r
5104 } else if (Ext.isDate(value)) {\r
5105 value = Ext.Date.toString(value);\r
5106 }\r
5107 params.push(encodeURIComponent(paramObject.name) + '=' + encodeURIComponent(String(value)));\r
5108 }\r
5109 return params.join('&');\r
5110 },\r
5111 \r
5112 fromQueryString: function(queryString, recursive) {\r
5113 var parts = queryString.replace(queryRe, '').split('&'),\r
5114 object = {},\r
5115 temp, components, name, value, i, ln, part, j, subLn, matchedKeys, matchedName, keys, key, nextKey;\r
5116 for (i = 0 , ln = parts.length; i < ln; i++) {\r
5117 part = parts[i];\r
5118 if (part.length > 0) {\r
5119 components = part.split('=');\r
5120 name = components[0];\r
5121 name = name.replace(plusRe, '%20');\r
5122 name = decodeURIComponent(name);\r
5123 value = components[1];\r
5124 if (value !== undefined) {\r
5125 value = value.replace(plusRe, '%20');\r
5126 value = decodeURIComponent(value);\r
5127 } else {\r
5128 value = '';\r
5129 }\r
5130 if (!recursive) {\r
5131 if (object.hasOwnProperty(name)) {\r
5132 if (!Ext.isArray(object[name])) {\r
5133 object[name] = [\r
5134 object[name]\r
5135 ];\r
5136 }\r
5137 object[name].push(value);\r
5138 } else {\r
5139 object[name] = value;\r
5140 }\r
5141 } else {\r
5142 matchedKeys = name.match(keyRe);\r
5143 matchedName = name.match(nameRe);\r
5144
5145 if (!matchedName) {\r
5146 throw new Error('[Ext.Object.fromQueryString] Malformed query string given, failed parsing name from "' + part + '"');\r
5147 }\r
5148
5149 name = matchedName[0];\r
5150 keys = [];\r
5151 if (matchedKeys === null) {\r
5152 object[name] = value;\r
5153 \r
5154 continue;\r
5155 }\r
5156 for (j = 0 , subLn = matchedKeys.length; j < subLn; j++) {\r
5157 key = matchedKeys[j];\r
5158 key = (key.length === 2) ? '' : key.substring(1, key.length - 1);\r
5159 keys.push(key);\r
5160 }\r
5161 keys.unshift(name);\r
5162 temp = object;\r
5163 for (j = 0 , subLn = keys.length; j < subLn; j++) {\r
5164 key = keys[j];\r
5165 if (j === subLn - 1) {\r
5166 if (Ext.isArray(temp) && key === '') {\r
5167 temp.push(value);\r
5168 } else {\r
5169 temp[key] = value;\r
5170 }\r
5171 } else {\r
5172 if (temp[key] === undefined || typeof temp[key] === 'string') {\r
5173 nextKey = keys[j + 1];\r
5174 temp[key] = (Ext.isNumeric(nextKey) || nextKey === '') ? [] : {};\r
5175 }\r
5176 temp = temp[key];\r
5177 }\r
5178 }\r
5179 }\r
5180 }\r
5181 }\r
5182 return object;\r
5183 },\r
5184 \r
5185 each: function(object, fn, scope) {\r
5186 var enumerables = Ext.enumerables,\r
5187 i, property;\r
5188 if (object) {\r
5189 scope = scope || object;\r
5190 for (property in object) {\r
5191 if (object.hasOwnProperty(property)) {\r
5192 if (fn.call(scope, property, object[property], object) === false) {\r
5193 return;\r
5194 }\r
5195 }\r
5196 }\r
5197 if (enumerables) {\r
5198 for (i = enumerables.length; i--; ) {\r
5199 if (object.hasOwnProperty(property = enumerables[i])) {\r
5200 if (fn.call(scope, property, object[property], object) === false) {\r
5201 return;\r
5202 }\r
5203 }\r
5204 }\r
5205 }\r
5206 }\r
5207 },\r
5208 \r
5209 eachValue: function(object, fn, scope) {\r
5210 var enumerables = Ext.enumerables,\r
5211 i, property;\r
5212 scope = scope || object;\r
5213 for (property in object) {\r
5214 if (object.hasOwnProperty(property)) {\r
5215 if (fn.call(scope, object[property]) === false) {\r
5216 return;\r
5217 }\r
5218 }\r
5219 }\r
5220 if (enumerables) {\r
5221 for (i = enumerables.length; i--; ) {\r
5222 if (object.hasOwnProperty(property = enumerables[i])) {\r
5223 if (fn.call(scope, object[property]) === false) {\r
5224 return;\r
5225 }\r
5226 }\r
5227 }\r
5228 }\r
5229 },\r
5230 \r
5231 merge: function(destination) {\r
5232 var i = 1,\r
5233 ln = arguments.length,\r
5234 mergeFn = ExtObject.merge,\r
5235 cloneFn = Ext.clone,\r
5236 object, key, value, sourceKey;\r
5237 for (; i < ln; i++) {\r
5238 object = arguments[i];\r
5239 for (key in object) {\r
5240 value = object[key];\r
5241 if (value && value.constructor === Object) {\r
5242 sourceKey = destination[key];\r
5243 if (sourceKey && sourceKey.constructor === Object) {\r
5244 mergeFn(sourceKey, value);\r
5245 } else {\r
5246 destination[key] = cloneFn(value);\r
5247 }\r
5248 } else {\r
5249 destination[key] = value;\r
5250 }\r
5251 }\r
5252 }\r
5253 return destination;\r
5254 },\r
5255 \r
5256 mergeIf: function(destination) {\r
5257 var i = 1,\r
5258 ln = arguments.length,\r
5259 cloneFn = Ext.clone,\r
5260 object, key, value;\r
5261 for (; i < ln; i++) {\r
5262 object = arguments[i];\r
5263 for (key in object) {\r
5264 if (!(key in destination)) {\r
5265 value = object[key];\r
5266 if (value && value.constructor === Object) {\r
5267 destination[key] = cloneFn(value);\r
5268 } else {\r
5269 destination[key] = value;\r
5270 }\r
5271 }\r
5272 }\r
5273 }\r
5274 return destination;\r
5275 },\r
5276 \r
5277 getAllKeys: function(object) {\r
5278 var keys = [],\r
5279 property;\r
5280 for (property in object) {\r
5281 keys.push(property);\r
5282 }\r
5283 return keys;\r
5284 },\r
5285 \r
5286 getKey: function(object, value) {\r
5287 for (var property in object) {\r
5288 if (object.hasOwnProperty(property) && object[property] === value) {\r
5289 return property;\r
5290 }\r
5291 }\r
5292 return null;\r
5293 },\r
5294 \r
5295 getValues: function(object) {\r
5296 var values = [],\r
5297 property;\r
5298 for (property in object) {\r
5299 if (object.hasOwnProperty(property)) {\r
5300 values.push(object[property]);\r
5301 }\r
5302 }\r
5303 return values;\r
5304 },\r
5305 \r
5306 getKeys: (typeof Object.keys == 'function') ? function(object) {\r
5307 if (!object) {\r
5308 return [];\r
5309 }\r
5310 return Object.keys(object);\r
5311 } : function(object) {\r
5312 var keys = [],\r
5313 property;\r
5314 for (property in object) {\r
5315 if (object.hasOwnProperty(property)) {\r
5316 keys.push(property);\r
5317 }\r
5318 }\r
5319 return keys;\r
5320 },\r
5321 \r
5322 getSize: function(object) {\r
5323 var size = 0,\r
5324 property;\r
5325 for (property in object) {\r
5326 if (object.hasOwnProperty(property)) {\r
5327 size++;\r
5328 }\r
5329 }\r
5330 return size;\r
5331 },\r
5332 \r
5333 isEmpty: function(object) {\r
5334 for (var key in object) {\r
5335 if (object.hasOwnProperty(key)) {\r
5336 return false;\r
5337 }\r
5338 }\r
5339 return true;\r
5340 },\r
5341 \r
5342 equals: (function() {\r
5343 var check = function(o1, o2) {\r
5344 var key;\r
5345 for (key in o1) {\r
5346 if (o1.hasOwnProperty(key)) {\r
5347 if (o1[key] !== o2[key]) {\r
5348 return false;\r
5349 }\r
5350 }\r
5351 }\r
5352 return true;\r
5353 };\r
5354 return function(object1, object2) {\r
5355
5356 if (object1 === object2) {\r
5357 return true;\r
5358 }\r
5359 if (object1 && object2) {\r
5360
5361
5362 return check(object1, object2) && check(object2, object1);\r
5363 } else if (!object1 && !object2) {\r
5364 return object1 === object2;\r
5365 } else {\r
5366 return false;\r
5367 }\r
5368 };\r
5369 })(),\r
5370 \r
5371 fork: function(obj) {\r
5372 var ret, key, value;\r
5373 if (obj && obj.constructor === Object) {\r
5374 ret = ExtObject.chain(obj);\r
5375 for (key in obj) {\r
5376 value = obj[key];\r
5377 if (value) {\r
5378 if (value.constructor === Object) {\r
5379 ret[key] = ExtObject.fork(value);\r
5380 } else if (value instanceof Array) {\r
5381 ret[key] = Ext.Array.clone(value);\r
5382 }\r
5383 }\r
5384 }\r
5385 } else {\r
5386 ret = obj;\r
5387 }\r
5388 return ret;\r
5389 },\r
5390 defineProperty: ('defineProperty' in Object) ? Object.defineProperty : function(object, name, descriptor) {\r
5391 if (!Object.prototype.__defineGetter__) {\r
5392 return;\r
5393 }\r
5394 if (descriptor.get) {\r
5395 object.__defineGetter__(name, descriptor.get);\r
5396 }\r
5397 if (descriptor.set) {\r
5398 object.__defineSetter__(name, descriptor.set);\r
5399 }\r
5400 },\r
5401 \r
5402 classify: function(object) {\r
5403 var prototype = object,\r
5404 objectProperties = [],\r
5405 propertyClassesMap = {},\r
5406 objectClass = function() {\r
5407 var i = 0,\r
5408 ln = objectProperties.length,\r
5409 property;\r
5410 for (; i < ln; i++) {\r
5411 property = objectProperties[i];\r
5412 this[property] = new propertyClassesMap[property]();\r
5413 }\r
5414 },\r
5415 key, value;\r
5416 for (key in object) {\r
5417 if (object.hasOwnProperty(key)) {\r
5418 value = object[key];\r
5419 if (value && value.constructor === Object) {\r
5420 objectProperties.push(key);\r
5421 propertyClassesMap[key] = ExtObject.classify(value);\r
5422 }\r
5423 }\r
5424 }\r
5425 objectClass.prototype = prototype;\r
5426 return objectClass;\r
5427 }\r
5428 };\r
5429 \r
5430 Ext.merge = Ext.Object.merge;\r
5431 \r
5432 Ext.mergeIf = Ext.Object.mergeIf;\r
5433}());\r
5434\r
5435\r
5436Ext.apply(Ext, {\r
5437
5438
5439
5440
5441 _namedScopes: {\r
5442 'this': {\r
5443 isThis: 1\r
5444 },\r
5445 controller: {\r
5446 isController: 1\r
5447 },\r
5448
5449
5450 self: {\r
5451 isSelf: 1\r
5452 },\r
5453 'self.controller': {\r
5454 isSelf: 1,\r
5455 isController: 1\r
5456 }\r
5457 },\r
5458 escapeId: (function() {\r
5459 var validIdRe = /^[a-zA-Z_][a-zA-Z0-9_\-]*$/i,\r
5460 escapeRx = /([\W]{1})/g,\r
5461 leadingNumRx = /^(\d)/g,\r
5462 escapeFn = function(match, capture) {\r
5463 return "\\" + capture;\r
5464 },\r
5465 numEscapeFn = function(match, capture) {\r
5466 return '\\00' + capture.charCodeAt(0).toString(16) + ' ';\r
5467 };\r
5468 return function(id) {\r
5469 return validIdRe.test(id) ? id :
5470
5471 id.replace(escapeRx, escapeFn).replace(leadingNumRx, numEscapeFn);\r
5472 };\r
5473 }()),\r
5474 \r
5475 callback: function(callback, scope, args, delay, caller, defaultScope) {\r
5476 if (!callback) {\r
5477 return;\r
5478 }\r
5479 var namedScope = (scope in Ext._namedScopes);\r
5480 if (callback.charAt) {\r
5481
5482 if ((!scope || namedScope) && caller) {\r
5483 scope = caller.resolveListenerScope(namedScope ? scope : defaultScope);\r
5484 }\r
5485
5486 if (!scope || !Ext.isObject(scope)) {\r
5487 Ext.raise('Named method "' + callback + '" requires a scope object');\r
5488 }\r
5489 if (!Ext.isFunction(scope[callback])) {\r
5490 Ext.raise('No method named "' + callback + '" on ' + (scope.$className || 'scope object'));\r
5491 }\r
5492
5493 callback = scope[callback];\r
5494 } else if (namedScope) {\r
5495 scope = defaultScope || caller;\r
5496 } else if (!scope) {\r
5497 scope = caller;\r
5498 }\r
5499 var ret;\r
5500 if (callback && Ext.isFunction(callback)) {\r
5501 scope = scope || Ext.global;\r
5502 if (delay) {\r
5503 Ext.defer(callback, delay, scope, args);\r
5504 } else if (Ext.elevateFunction) {\r
5505 ret = Ext.elevateFunction(callback, scope, args);\r
5506 } else if (args) {\r
5507 ret = callback.apply(scope, args);\r
5508 } else {\r
5509 ret = callback.call(scope);\r
5510 }\r
5511 }\r
5512 return ret;\r
5513 },\r
5514 \r
5515 coerce: function(from, to) {\r
5516 var fromType = Ext.typeOf(from),\r
5517 toType = Ext.typeOf(to),\r
5518 isString = typeof from === 'string';\r
5519 if (fromType !== toType) {\r
5520 switch (toType) {\r
5521 case 'string':\r
5522 return String(from);\r
5523 case 'number':\r
5524 return Number(from);\r
5525 case 'boolean':\r
5526 return isString && (!from || from === 'false') ? false : Boolean(from);\r
5527 case 'null':\r
5528 return isString && (!from || from === 'null') ? null : from;\r
5529 case 'undefined':\r
5530 return isString && (!from || from === 'undefined') ? undefined : from;\r
5531 case 'date':\r
5532 return isString && isNaN(from) ? Ext.Date.parse(from, Ext.Date.defaultFormat) : Date(Number(from));\r
5533 }\r
5534 }\r
5535 return from;\r
5536 },\r
5537 \r
5538 copyTo: function(dest, source, names, usePrototypeKeys) {\r
5539 if (typeof names === 'string') {\r
5540 names = names.split(Ext.propertyNameSplitRe);\r
5541 }\r
5542 for (var name,\r
5543 i = 0,\r
5544 n = names ? names.length : 0; i < n; i++) {\r
5545 name = names[i];\r
5546 if (usePrototypeKeys || source.hasOwnProperty(name)) {\r
5547 dest[name] = source[name];\r
5548 }\r
5549 }\r
5550 return dest;\r
5551 },\r
5552 \r
5553 copy: function(dest, source, names, usePrototypeKeys) {\r
5554 if (typeof names === 'string') {\r
5555 names = names.split(Ext.propertyNameSplitRe);\r
5556 }\r
5557 for (var name,\r
5558 i = 0,\r
5559 n = names ? names.length : 0; i < n; i++) {\r
5560 name = names[i];\r
5561
5562
5563
5564 if (source.hasOwnProperty(name) || (usePrototypeKeys && name in source)) {\r
5565 dest[name] = source[name];\r
5566 }\r
5567 }\r
5568 return dest;\r
5569 },\r
5570 propertyNameSplitRe: /[,;\s]+/,\r
5571 \r
5572 copyToIf: function(destination, source, names) {\r
5573 if (typeof names === 'string') {\r
5574 names = names.split(Ext.propertyNameSplitRe);\r
5575 }\r
5576 for (var name,\r
5577 i = 0,\r
5578 n = names ? names.length : 0; i < n; i++) {\r
5579 name = names[i];\r
5580 if (destination[name] === undefined) {\r
5581 destination[name] = source[name];\r
5582 }\r
5583 }\r
5584 return destination;\r
5585 },\r
5586 \r
5587 copyIf: function(destination, source, names) {\r
5588 if (typeof names === 'string') {\r
5589 names = names.split(Ext.propertyNameSplitRe);\r
5590 }\r
5591 for (var name,\r
5592 i = 0,\r
5593 n = names ? names.length : 0; i < n; i++) {\r
5594 name = names[i];\r
5595
5596 if (!(name in destination) && (name in source)) {\r
5597 destination[name] = source[name];\r
5598 }\r
5599 }\r
5600 return destination;\r
5601 },\r
5602 \r
5603 extend: (function() {\r
5604
5605 var objectConstructor = Object.prototype.constructor,\r
5606 inlineOverrides = function(o) {\r
5607 for (var m in o) {\r
5608 if (!o.hasOwnProperty(m)) {\r
5609 \r
5610 continue;\r
5611 }\r
5612 this[m] = o[m];\r
5613 }\r
5614 };\r
5615 return function(subclass, superclass, overrides) {\r
5616
5617 if (Ext.isObject(superclass)) {\r
5618 overrides = superclass;\r
5619 superclass = subclass;\r
5620 subclass = overrides.constructor !== objectConstructor ? overrides.constructor : function() {\r
5621 superclass.apply(this, arguments);\r
5622 };\r
5623 }\r
5624
5625 if (!superclass) {\r
5626 Ext.raise({\r
5627 sourceClass: 'Ext',\r
5628 sourceMethod: 'extend',\r
5629 msg: 'Attempting to extend from a class which has not been loaded on the page.'\r
5630 });\r
5631 }\r
5632
5633
5634 var F = function() {},\r
5635 subclassProto,\r
5636 superclassProto = superclass.prototype;\r
5637 F.prototype = superclassProto;\r
5638 subclassProto = subclass.prototype = new F();\r
5639 subclassProto.constructor = subclass;\r
5640 subclass.superclass = superclassProto;\r
5641 if (superclassProto.constructor === objectConstructor) {\r
5642 superclassProto.constructor = superclass;\r
5643 }\r
5644 subclass.override = function(overrides) {\r
5645 Ext.override(subclass, overrides);\r
5646 };\r
5647 subclassProto.override = inlineOverrides;\r
5648 subclassProto.proto = subclassProto;\r
5649 subclass.override(overrides);\r
5650 subclass.extend = function(o) {\r
5651 return Ext.extend(subclass, o);\r
5652 };\r
5653 return subclass;\r
5654 };\r
5655 }()),\r
5656 \r
5657 iterate: function(object, fn, scope) {\r
5658 if (Ext.isEmpty(object)) {\r
5659 return;\r
5660 }\r
5661 if (scope === undefined) {\r
5662 scope = object;\r
5663 }\r
5664 if (Ext.isIterable(object)) {\r
5665 Ext.Array.each.call(Ext.Array, object, fn, scope);\r
5666 } else {\r
5667 Ext.Object.each.call(Ext.Object, object, fn, scope);\r
5668 }\r
5669 },\r
5670 _resourcePoolRe: /^[<]([^<>@:]*)(?:[@]([^<>@:]+))?[>](.+)$/,\r
5671 \r
5672 resolveResource: function(url) {\r
5673 var ret = url,\r
5674 m;\r
5675 if (url && url.charAt(0) === '<') {\r
5676 m = Ext._resourcePoolRe.exec(url);\r
5677 if (m) {\r
5678 ret = Ext.getResourcePath(m[3], m[1], m[2]);\r
5679 }\r
5680 }\r
5681 return ret;\r
5682 },\r
5683 \r
5684 urlEncode: function() {\r
5685 var args = Ext.Array.from(arguments),\r
5686 prefix = '';\r
5687
5688 if (Ext.isString(args[1])) {\r
5689 prefix = args[1] + '&';\r
5690 args[1] = false;\r
5691 }\r
5692 return prefix + Ext.Object.toQueryString.apply(Ext.Object, args);\r
5693 },\r
5694 \r
5695 urlDecode: function() {\r
5696 return Ext.Object.fromQueryString.apply(Ext.Object, arguments);\r
5697 },\r
5698 \r
5699 getScrollbarSize: function(force) {\r
5700
5701 if (!Ext.isDomReady) {\r
5702 Ext.raise("getScrollbarSize called before DomReady");\r
5703 }\r
5704
5705 var scrollbarSize = Ext._scrollbarSize;\r
5706 if (force || !scrollbarSize) {\r
5707 var db = document.body,\r
5708 div = document.createElement('div');\r
5709 div.style.width = div.style.height = '100px';\r
5710 div.style.overflow = 'scroll';\r
5711 div.style.position = 'absolute';\r
5712 db.appendChild(div);\r
5713
5714
5715 Ext._scrollbarSize = scrollbarSize = {\r
5716 width: div.offsetWidth - div.clientWidth,\r
5717 height: div.offsetHeight - div.clientHeight\r
5718 };\r
5719 db.removeChild(div);\r
5720 }\r
5721 return scrollbarSize;\r
5722 },\r
5723 \r
5724 typeOf: (function() {\r
5725 var nonWhitespaceRe = /\S/,\r
5726 toString = Object.prototype.toString,\r
5727 typeofTypes = {\r
5728 number: 1,\r
5729 string: 1,\r
5730 'boolean': 1,\r
5731 'undefined': 1\r
5732 },\r
5733 toStringTypes = {\r
5734 '[object Array]': 'array',\r
5735 '[object Date]': 'date',\r
5736 '[object Boolean]': 'boolean',\r
5737 '[object Number]': 'number',\r
5738 '[object RegExp]': 'regexp'\r
5739 };\r
5740 return function(value) {\r
5741 if (value === null) {\r
5742 return 'null';\r
5743 }\r
5744 var type = typeof value,\r
5745 ret, typeToString;\r
5746 if (typeofTypes[type]) {\r
5747 return type;\r
5748 }\r
5749 ret = toStringTypes[typeToString = toString.call(value)];\r
5750 if (ret) {\r
5751 return ret;\r
5752 }\r
5753 if (type === 'function') {\r
5754 return 'function';\r
5755 }\r
5756 if (type === 'object') {\r
5757 if (value.nodeType !== undefined) {\r
5758 if (value.nodeType === 3) {\r
5759 return nonWhitespaceRe.test(value.nodeValue) ? 'textnode' : 'whitespace';\r
5760 } else {\r
5761 return 'element';\r
5762 }\r
5763 }\r
5764 return 'object';\r
5765 }\r
5766
5767 Ext.raise({\r
5768 sourceClass: 'Ext',\r
5769 sourceMethod: 'typeOf',\r
5770 msg: 'Failed to determine the type of "' + value + '".'\r
5771 });\r
5772
5773 return typeToString;\r
5774 };\r
5775 }()),\r
5776 \r
5777 factory: function(config, classReference, instance, aliasNamespace) {\r
5778 var manager = Ext.ClassManager,\r
5779 newInstance;\r
5780
5781
5782 if (!config || config.isInstance) {\r
5783 if (instance && instance !== config) {\r
5784 instance.destroy();\r
5785 }\r
5786 return config;\r
5787 }\r
5788 if (aliasNamespace) {\r
5789
5790 if (typeof config === 'string') {\r
5791 return manager.instantiateByAlias(aliasNamespace + '.' + config);\r
5792 }\r
5793
5794 else if (Ext.isObject(config) && 'type' in config) {\r
5795 return manager.instantiateByAlias(aliasNamespace + '.' + config.type, config);\r
5796 }\r
5797 }\r
5798 if (config === true) {\r
5799
5800 if (!instance && !classReference) {\r
5801 Ext.raise('[Ext.factory] Cannot determine type of class to create');\r
5802 }\r
5803
5804 return instance || Ext.create(classReference);\r
5805 }\r
5806
5807 if (!Ext.isObject(config)) {\r
5808 Ext.raise("Invalid config, must be a valid config object");\r
5809 }\r
5810
5811 if ('xtype' in config) {\r
5812 newInstance = manager.instantiateByAlias('widget.' + config.xtype, config);\r
5813 } else if ('xclass' in config) {\r
5814 newInstance = Ext.create(config.xclass, config);\r
5815 }\r
5816 if (newInstance) {\r
5817 if (instance) {\r
5818 instance.destroy();\r
5819 }\r
5820 return newInstance;\r
5821 }\r
5822 if (instance) {\r
5823 return instance.setConfig(config);\r
5824 }\r
5825 return Ext.create(classReference, config);\r
5826 },\r
5827 \r
5828 log:
5829 (function() {\r
5830 \r
5831 var primitiveRe = /string|number|boolean/;\r
5832 function dumpObject(object, level, maxLevel, withFunctions) {\r
5833 var member, type, value, name, prefix, suffix,\r
5834 members = [];\r
5835 if (Ext.isArray(object)) {\r
5836 prefix = '[';\r
5837 suffix = ']';\r
5838 } else if (Ext.isObject(object)) {\r
5839 prefix = '{';\r
5840 suffix = '}';\r
5841 }\r
5842 if (!maxLevel) {\r
5843 maxLevel = 3;\r
5844 }\r
5845 if (level > maxLevel) {\r
5846 return prefix + '...' + suffix;\r
5847 }\r
5848 level = level || 1;\r
5849 var spacer = (new Array(level)).join(' ');\r
5850
5851 for (name in object) {\r
5852 if (object.hasOwnProperty(name)) {\r
5853 value = object[name];\r
5854 type = typeof value;\r
5855 if (type === 'function') {\r
5856 if (!withFunctions) {\r
5857 \r
5858 continue;\r
5859 }\r
5860 member = type;\r
5861 } else if (type === 'undefined') {\r
5862 member = type;\r
5863 } else if (value === null || primitiveRe.test(type) || Ext.isDate(value)) {\r
5864 member = Ext.encode(value);\r
5865 } else if (Ext.isArray(value)) {\r
5866 member = dumpObject(value, level + 1, maxLevel, withFunctions);\r
5867 } else if (Ext.isObject(value)) {\r
5868 member = dumpObject(value, level + 1, maxLevel, withFunctions);\r
5869 } else {\r
5870 member = type;\r
5871 }\r
5872 members.push(spacer + name + ': ' + member);\r
5873 }\r
5874 }\r
5875
5876 if (members.length) {\r
5877 return prefix + '\n ' + members.join(',\n ') + '\n' + spacer + suffix;\r
5878 }\r
5879 return prefix + suffix;\r
5880 }\r
5881 function log(message) {\r
5882 var options, dump,\r
5883 con = Ext.global.console,\r
5884 level = 'log',\r
5885 indent = log.indent || 0,\r
5886 prefix, stack, fn, out, max;\r
5887 log.indent = indent;\r
5888 if (typeof message !== 'string') {\r
5889 options = message;\r
5890 message = options.msg || '';\r
5891 level = options.level || level;\r
5892 dump = options.dump;\r
5893 stack = options.stack;\r
5894 prefix = options.prefix;\r
5895 fn = options.fn;\r
5896 if (options.indent) {\r
5897 ++log.indent;\r
5898 } else if (options.outdent) {\r
5899 log.indent = indent = Math.max(indent - 1, 0);\r
5900 }\r
5901 if (dump && !(con && con.dir)) {\r
5902 message += dumpObject(dump);\r
5903 dump = null;\r
5904 }\r
5905 }\r
5906 if (arguments.length > 1) {\r
5907 message += Array.prototype.slice.call(arguments, 1).join('');\r
5908 }\r
5909 if (prefix) {\r
5910 message = prefix + ' - ' + message;\r
5911 }\r
5912 message = indent ? Ext.String.repeat(' ', log.indentSize * indent) + message : message;\r
5913
5914 if (level !== 'log') {\r
5915 message = '[' + level.charAt(0).toUpperCase() + '] ' + message;\r
5916 }\r
5917 if (fn) {\r
5918 message += '\nCaller: ' + fn.toString();\r
5919 }\r
5920
5921
5922
5923 if (con) {\r
5924
5925 if (con[level]) {\r
5926 con[level](message);\r
5927 } else {\r
5928 con.log(message);\r
5929 }\r
5930 if (dump) {\r
5931 con.dir(dump);\r
5932 }\r
5933 if (stack && con.trace) {\r
5934
5935 if (!con.firebug || level !== 'error') {\r
5936 con.trace();\r
5937 }\r
5938 }\r
5939 } else if (Ext.isOpera) {\r
5940 opera.postError(message);\r
5941 } else
5942 {\r
5943 out = log.out;\r
5944 max = log.max;\r
5945 if (out.length >= max) {\r
5946
5947
5948 Ext.Array.erase(out, 0, out.length - 3 * Math.floor(max / 4));\r
5949 }\r
5950
5951 out.push(message);\r
5952 }\r
5953
5954 ++log.count;\r
5955 ++log.counters[level];\r
5956 }\r
5957 function logx(level, args) {\r
5958 if (typeof args[0] === 'string') {\r
5959 args.unshift({});\r
5960 }\r
5961 args[0].level = level;\r
5962 log.apply(this, args);\r
5963 }\r
5964 log.error = function() {\r
5965 logx('error', Array.prototype.slice.call(arguments));\r
5966 };\r
5967 log.info = function() {\r
5968 logx('info', Array.prototype.slice.call(arguments));\r
5969 };\r
5970 log.warn = function() {\r
5971 logx('warn', Array.prototype.slice.call(arguments));\r
5972 };\r
5973 log.count = 0;\r
5974 log.counters = {\r
5975 error: 0,\r
5976 warn: 0,\r
5977 info: 0,\r
5978 log: 0\r
5979 };\r
5980 log.indentSize = 2;\r
5981 log.out = [];\r
5982 log.max = 750;\r
5983 return log;\r
5984 }()) ||
5985 (function() {\r
5986 var nullLog = function() {};\r
5987 nullLog.info = nullLog.warn = nullLog.error = Ext.emptyFn;\r
5988 return nullLog;\r
5989 }())\r
5990});\r
5991\r
5992\r
5993(function() {\r
5994
5995
5996 var
5997 checkVerTemp = [\r
5998 ''\r
5999 ],\r
6000 endOfVersionRe = /([^\d\.])/,\r
6001 notDigitsRe = /[^\d]/g,\r
6002 plusMinusRe = /[\-+]/g,\r
6003 stripRe = /\s/g,\r
6004 underscoreRe = /_/g,\r
6005 toolkitNames = {\r
6006 classic: 1,\r
6007 modern: 1\r
6008 },\r
6009 Version;\r
6010 Ext.Version = Version = function(version, defaultMode) {\r
6011 var me = this,\r
6012 padModes = me.padModes,\r
6013 ch, i, pad, parts, release, releaseStartIndex, ver;\r
6014 if (version.isVersion) {\r
6015 version = version.version;\r
6016 }\r
6017 me.version = ver = String(version).toLowerCase().replace(underscoreRe, '.').replace(plusMinusRe, '');\r
6018 ch = ver.charAt(0);\r
6019 if (ch in padModes) {\r
6020 ver = ver.substring(1);\r
6021 pad = padModes[ch];\r
6022 } else {\r
6023 pad = defaultMode ? padModes[defaultMode] : 0;\r
6024 }\r
6025
6026 me.pad = pad;\r
6027 releaseStartIndex = ver.search(endOfVersionRe);\r
6028 me.shortVersion = ver;\r
6029 if (releaseStartIndex !== -1) {\r
6030 me.release = release = ver.substr(releaseStartIndex, version.length);\r
6031 me.shortVersion = ver.substr(0, releaseStartIndex);\r
6032 release = Version.releaseValueMap[release] || release;\r
6033 }\r
6034 me.releaseValue = release || pad;\r
6035 me.shortVersion = me.shortVersion.replace(notDigitsRe, '');\r
6036 \r
6037 me.parts = parts = ver.split('.');\r
6038 for (i = parts.length; i--; ) {\r
6039 parts[i] = parseInt(parts[i], 10);\r
6040 }\r
6041 if (pad === Infinity) {\r
6042
6043 parts.push(pad);\r
6044 }\r
6045 \r
6046 me.major = parts[0] || pad;\r
6047 \r
6048 me.minor = parts[1] || pad;\r
6049 \r
6050 me.patch = parts[2] || pad;\r
6051 \r
6052 me.build = parts[3] || pad;\r
6053 return me;\r
6054 };\r
6055 Version.prototype = {\r
6056 isVersion: true,\r
6057 padModes: {\r
6058 '~': NaN,\r
6059 '^': Infinity\r
6060 },\r
6061 \r
6062 release: '',\r
6063 \r
6064 compareTo: function(other) {\r
6065
6066
6067 var me = this,\r
6068 lhsPad = me.pad,\r
6069 lhsParts = me.parts,\r
6070 lhsLength = lhsParts.length,\r
6071 rhsVersion = other.isVersion ? other : new Version(other),\r
6072 rhsPad = rhsVersion.pad,\r
6073 rhsParts = rhsVersion.parts,\r
6074 rhsLength = rhsParts.length,\r
6075 length = Math.max(lhsLength, rhsLength),\r
6076 i, lhs, rhs;\r
6077 for (i = 0; i < length; i++) {\r
6078 lhs = (i < lhsLength) ? lhsParts[i] : lhsPad;\r
6079 rhs = (i < rhsLength) ? rhsParts[i] : rhsPad;\r
6080
6081
6082 if (lhs < rhs) {\r
6083 return -1;\r
6084 }\r
6085 if (lhs > rhs) {\r
6086 return 1;\r
6087 }\r
6088 }\r
6089
6090 lhs = me.releaseValue;\r
6091 rhs = rhsVersion.releaseValue;\r
6092 if (lhs < rhs) {\r
6093 return -1;\r
6094 }\r
6095 if (lhs > rhs) {\r
6096 return 1;\r
6097 }\r
6098 return 0;\r
6099 },\r
6100 \r
6101 toString: function() {\r
6102 return this.version;\r
6103 },\r
6104 \r
6105 valueOf: function() {\r
6106 return this.version;\r
6107 },\r
6108 \r
6109 getMajor: function() {\r
6110 return this.major;\r
6111 },\r
6112 \r
6113 getMinor: function() {\r
6114 return this.minor;\r
6115 },\r
6116 \r
6117 getPatch: function() {\r
6118 return this.patch;\r
6119 },\r
6120 \r
6121 getBuild: function() {\r
6122 return this.build;\r
6123 },\r
6124 \r
6125 getRelease: function() {\r
6126 return this.release;\r
6127 },\r
6128 \r
6129 getReleaseValue: function() {\r
6130 return this.releaseValue;\r
6131 },\r
6132 \r
6133 isGreaterThan: function(target) {\r
6134 return this.compareTo(target) > 0;\r
6135 },\r
6136 \r
6137 isGreaterThanOrEqual: function(target) {\r
6138 return this.compareTo(target) >= 0;\r
6139 },\r
6140 \r
6141 isLessThan: function(target) {\r
6142 return this.compareTo(target) < 0;\r
6143 },\r
6144 \r
6145 isLessThanOrEqual: function(target) {\r
6146 return this.compareTo(target) <= 0;\r
6147 },\r
6148 \r
6149 equals: function(target) {\r
6150 return this.compareTo(target) === 0;\r
6151 },\r
6152 \r
6153 match: function(target) {\r
6154 target = String(target);\r
6155 return this.version.substr(0, target.length) === target;\r
6156 },\r
6157 \r
6158 toArray: function() {\r
6159 var me = this;\r
6160 return [\r
6161 me.getMajor(),\r
6162 me.getMinor(),\r
6163 me.getPatch(),\r
6164 me.getBuild(),\r
6165 me.getRelease()\r
6166 ];\r
6167 },\r
6168 \r
6169 getShortVersion: function() {\r
6170 return this.shortVersion;\r
6171 },\r
6172 \r
6173 gt: function(target) {\r
6174 return this.compareTo(target) > 0;\r
6175 },\r
6176 \r
6177 lt: function(target) {\r
6178 return this.compareTo(target) < 0;\r
6179 },\r
6180 \r
6181 gtEq: function(target) {\r
6182 return this.compareTo(target) >= 0;\r
6183 },\r
6184 \r
6185 ltEq: function(target) {\r
6186 return this.compareTo(target) <= 0;\r
6187 }\r
6188 };\r
6189 Ext.apply(Version, {\r
6190 aliases: {\r
6191 from: {\r
6192 extjs: 'ext',\r
6193 core: 'core',\r
6194 touch: 'modern'\r
6195 },\r
6196 to: {\r
6197 ext: [\r
6198 'extjs'\r
6199 ],\r
6200 'core': [\r
6201 'core'\r
6202 ],\r
6203 modern: [\r
6204 'touch'\r
6205 ]\r
6206 }\r
6207 },\r
6208 \r
6209 releaseValueMap: {\r
6210 dev: -6,\r
6211 alpha: -5,\r
6212 a: -5,\r
6213 beta: -4,\r
6214 b: -4,\r
6215 rc: -3,\r
6216 '#': -2,\r
6217 p: -1,\r
6218 pl: -1\r
6219 },\r
6220 \r
6221 getComponentValue: function(value) {\r
6222 return !value ? 0 : (isNaN(value) ? this.releaseValueMap[value] || value : parseInt(value, 10));\r
6223 },\r
6224 \r
6225 compare: function(current, target) {\r
6226 var ver = current.isVersion ? current : new Version(current);\r
6227 return ver.compareTo(target);\r
6228 },\r
6229 set: function(collection, packageName, version) {\r
6230 var aliases = Version.aliases.to[packageName],\r
6231 ver = version.isVersion ? version : new Version(version),\r
6232 i;\r
6233 collection[packageName] = ver;\r
6234 if (aliases) {\r
6235 for (i = aliases.length; i-- > 0; ) {\r
6236 collection[aliases[i]] = ver;\r
6237 }\r
6238 }\r
6239 return ver;\r
6240 }\r
6241 });\r
6242 \r
6243 Ext.apply(Ext, {\r
6244 \r
6245 compatVersions: {},\r
6246 \r
6247 versions: {},\r
6248 \r
6249 lastRegisteredVersion: null,\r
6250 \r
6251 getCompatVersion: function(packageName) {\r
6252 var versions = Ext.compatVersions,\r
6253 compat;\r
6254 if (!packageName) {\r
6255 compat = versions.ext || versions.touch || versions.core;\r
6256 } else {\r
6257 compat = versions[Version.aliases.from[packageName] || packageName];\r
6258 }\r
6259 return compat || Ext.getVersion(packageName);\r
6260 },\r
6261 \r
6262 setCompatVersion: function(packageName, version) {\r
6263 Version.set(Ext.compatVersions, packageName, version);\r
6264 },\r
6265 \r
6266 setVersion: function(packageName, version) {\r
6267 if (packageName in toolkitNames) {\r
6268 Ext.toolkit = packageName;\r
6269 }\r
6270 Ext.lastRegisteredVersion = Version.set(Ext.versions, packageName, version);\r
6271 return this;\r
6272 },\r
6273 \r
6274 getVersion: function(packageName) {\r
6275 var versions = Ext.versions;\r
6276 if (!packageName) {\r
6277 return versions.ext || versions.touch || versions.core;\r
6278 }\r
6279 return versions[Version.aliases.from[packageName] || packageName];\r
6280 },\r
6281 \r
6282 checkVersion: function(specs, matchAll) {\r
6283 var isArray = Ext.isArray(specs),\r
6284 aliases = Version.aliases.from,\r
6285 compat = isArray ? specs : checkVerTemp,\r
6286 length = compat.length,\r
6287 versions = Ext.versions,\r
6288 frameworkVer = versions.ext || versions.touch,\r
6289 i, index, matches, minVer, maxVer, packageName, spec, range, ver;\r
6290 if (!isArray) {\r
6291 checkVerTemp[0] = specs;\r
6292 }\r
6293 for (i = 0; i < length; ++i) {\r
6294 if (!Ext.isString(spec = compat[i])) {\r
6295 matches = Ext.checkVersion(spec.and || spec.or, !spec.or);\r
6296 if (spec.not) {\r
6297 matches = !matches;\r
6298 }\r
6299 } else {\r
6300 if (spec.indexOf(' ') >= 0) {\r
6301 spec = spec.replace(stripRe, '');\r
6302 }\r
6303
6304
6305 index = spec.indexOf('@');\r
6306 if (index < 0) {\r
6307 range = spec;\r
6308 ver = frameworkVer;\r
6309 } else {\r
6310 packageName = spec.substring(0, index);\r
6311 if (!(ver = versions[aliases[packageName] || packageName])) {\r
6312
6313
6314 if (matchAll) {\r
6315 return false;\r
6316 }\r
6317
6318
6319 \r
6320 continue;\r
6321 }\r
6322 range = spec.substring(index + 1);\r
6323 }\r
6324
6325 index = range.indexOf('-');\r
6326 if (index < 0) {\r
6327
6328 if (range.charAt(index = range.length - 1) === '+') {\r
6329 minVer = range.substring(0, index);\r
6330 maxVer = null;\r
6331 } else {\r
6332 minVer = maxVer = range;\r
6333 }\r
6334 } else if (index > 0) {\r
6335
6336 minVer = range.substring(0, index);\r
6337 maxVer = range.substring(index + 1);\r
6338 } else
6339 {\r
6340
6341 minVer = null;\r
6342 maxVer = range.substring(index + 1);\r
6343 }\r
6344 matches = true;\r
6345 if (minVer) {\r
6346 minVer = new Version(minVer, '~');\r
6347
6348 matches = minVer.ltEq(ver);\r
6349 }\r
6350 if (matches && maxVer) {\r
6351 maxVer = new Version(maxVer, '~');\r
6352
6353 matches = maxVer.gtEq(ver);\r
6354 }\r
6355 }\r
6356
6357 if (matches) {\r
6358
6359 if (!matchAll) {\r
6360 return true;\r
6361 }\r
6362 } else if (matchAll) {\r
6363
6364 return false;\r
6365 }\r
6366 }\r
6367
6368
6369
6370
6371 return !!matchAll;\r
6372 },\r
6373 \r
6374 deprecate: function(packageName, since, closure, scope) {\r
6375 if (Version.compare(Ext.getVersion(packageName), since) < 1) {\r
6376 closure.call(scope);\r
6377 }\r
6378 }\r
6379 });\r
6380}());\r
6381
6382
6383(function(manifest) {\r
6384 var packages = (manifest && manifest.packages) || {},\r
6385 compat = manifest && manifest.compatibility,\r
6386 name, pkg;\r
6387 for (name in packages) {\r
6388 pkg = packages[name];\r
6389 Ext.setVersion(name, pkg.version);\r
6390 }\r
6391 if (compat) {\r
6392 if (Ext.isString(compat)) {\r
6393 Ext.setCompatVersion('core', compat);\r
6394 } else {\r
6395 for (name in compat) {\r
6396 Ext.setCompatVersion(name, compat[name]);\r
6397 }\r
6398 }\r
6399 }\r
6400 if (!packages.ext && !packages.touch) {\r
6401 Ext.setVersion('ext', '6.0.1.250');\r
6402 Ext.setVersion('core', '6.0.1.250');\r
6403 }\r
6404})(Ext.manifest);\r
6405\r
6406\r
6407Ext.Config = function(name) {\r
6408
6409
6410 var me = this,\r
6411 capitalizedName = name.charAt(0).toUpperCase() + name.substr(1);\r
6412 \r
6413 me.name = name;\r
6414 \r
6415 me.names = {\r
6416 internal: '_' + name,\r
6417 initializing: 'is' + capitalizedName + 'Initializing',\r
6418 apply: 'apply' + capitalizedName,\r
6419 update: 'update' + capitalizedName,\r
6420 get: 'get' + capitalizedName,\r
6421 set: 'set' + capitalizedName,\r
6422 initGet: 'initGet' + capitalizedName,\r
6423 changeEvent: name.toLowerCase() + 'change'\r
6424 };\r
6425
6426
6427 me.root = me;\r
6428};\r
6429Ext.Config.map = {};\r
6430Ext.Config.get = function(name) {\r
6431 var map = Ext.Config.map,\r
6432 ret = map[name] || (map[name] = new Ext.Config(name));\r
6433 return ret;\r
6434};\r
6435Ext.Config.prototype = {\r
6436 self: Ext.Config,\r
6437 isConfig: true,\r
6438 \r
6439 \r
6440 \r
6441 \r
6442 getGetter: function() {\r
6443 return this.getter || (this.root.getter = this.makeGetter());\r
6444 },\r
6445 getInitGetter: function() {\r
6446 return this.initGetter || (this.root.initGetter = this.makeInitGetter());\r
6447 },\r
6448 getSetter: function() {\r
6449 return this.setter || (this.root.setter = this.makeSetter());\r
6450 },\r
6451 getEventedSetter: function() {\r
6452 return this.eventedSetter || (this.root.eventedSetter = this.makeEventedSetter());\r
6453 },\r
6454 \r
6455 getInternalName: function(target) {\r
6456 return target.$configPrefixed ? this.names.internal : this.name;\r
6457 },\r
6458 mergeNew: function(newValue, oldValue, target, mixinClass) {\r
6459 var ret, key;\r
6460 if (!oldValue) {\r
6461 ret = newValue;\r
6462 } else if (!newValue) {\r
6463 ret = oldValue;\r
6464 } else {\r
6465 ret = Ext.Object.chain(oldValue);\r
6466 for (key in newValue) {\r
6467 if (!mixinClass || !(key in ret)) {\r
6468 ret[key] = newValue[key];\r
6469 }\r
6470 }\r
6471 }\r
6472 return ret;\r
6473 },\r
6474 \r
6475 mergeSets: function(newValue, oldValue, preserveExisting) {\r
6476 var ret = oldValue ? Ext.Object.chain(oldValue) : {},\r
6477 i, val;\r
6478 if (newValue instanceof Array) {\r
6479 for (i = newValue.length; i--; ) {\r
6480 val = newValue[i];\r
6481 if (!preserveExisting || !(val in ret)) {\r
6482 ret[val] = true;\r
6483 }\r
6484 }\r
6485 } else if (newValue) {\r
6486 if (newValue.constructor === Object) {\r
6487 for (i in newValue) {\r
6488 val = newValue[i];\r
6489 if (!preserveExisting || !(i in ret)) {\r
6490 ret[i] = val;\r
6491 }\r
6492 }\r
6493 } else if (!preserveExisting || !(newValue in ret)) {\r
6494 ret[newValue] = true;\r
6495 }\r
6496 }\r
6497 return ret;\r
6498 },\r
6499
6500
6501 makeGetter: function() {\r
6502 var name = this.name,\r
6503 prefixedName = this.names.internal;\r
6504 return function() {\r
6505 var internalName = this.$configPrefixed ? prefixedName : name;\r
6506 return this[internalName];\r
6507 };\r
6508 },\r
6509 makeInitGetter: function() {\r
6510 var name = this.name,\r
6511 names = this.names,\r
6512 setName = names.set,\r
6513 getName = names.get,\r
6514 initializingName = names.initializing;\r
6515 return function() {\r
6516 var me = this;\r
6517 me[initializingName] = true;\r
6518
6519 delete me[getName];\r
6520 me[setName](me.config[name]);\r
6521 delete me[initializingName];\r
6522 return me[getName].apply(me, arguments);\r
6523 };\r
6524 },\r
6525 makeSetter: function() {\r
6526 var name = this.name,\r
6527 names = this.names,\r
6528 prefixedName = names.internal,\r
6529 getName = names.get,\r
6530 applyName = names.apply,\r
6531 updateName = names.update,\r
6532 setter;\r
6533
6534
6535 setter = function(value) {\r
6536 var me = this,\r
6537 internalName = me.$configPrefixed ? prefixedName : name,\r
6538 oldValue = me[internalName];\r
6539
6540 delete me[getName];\r
6541 if (!me[applyName] || (value = me[applyName](value, oldValue)) !== undefined) {\r
6542
6543
6544 if (value !== (oldValue = me[internalName])) {\r
6545 me[internalName] = value;\r
6546 if (me[updateName]) {\r
6547 me[updateName](value, oldValue);\r
6548 }\r
6549 }\r
6550 }\r
6551 return me;\r
6552 };\r
6553 setter.$isDefault = true;\r
6554 return setter;\r
6555 },\r
6556 makeEventedSetter: function() {\r
6557 var name = this.name,\r
6558 names = this.names,\r
6559 prefixedName = names.internal,\r
6560 getName = names.get,\r
6561 applyName = names.apply,\r
6562 updateName = names.update,\r
6563 changeEventName = names.changeEvent,\r
6564 updateFn = function(me, value, oldValue, internalName) {\r
6565 me[internalName] = value;\r
6566 if (me[updateName]) {\r
6567 me[updateName](value, oldValue);\r
6568 }\r
6569 },\r
6570 setter;\r
6571
6572
6573 setter = function(value) {\r
6574 var me = this,\r
6575 internalName = me.$configPrefixed ? prefixedName : name,\r
6576 oldValue = me[internalName];\r
6577
6578 delete me[getName];\r
6579 if (!me[applyName] || (value = me[applyName](value, oldValue)) !== undefined) {\r
6580
6581
6582 if (value !== (oldValue = me[internalName])) {\r
6583 if (me.isConfiguring) {\r
6584 me[internalName] = value;\r
6585 if (me[updateName]) {\r
6586 me[updateName](value, oldValue);\r
6587 }\r
6588 } else {\r
6589 me.fireEventedAction(changeEventName, [\r
6590 me,\r
6591 value,\r
6592 oldValue\r
6593 ], updateFn, me, [\r
6594 me,\r
6595 value,\r
6596 oldValue,\r
6597 internalName\r
6598 ]);\r
6599 }\r
6600 }\r
6601 }\r
6602 return me;\r
6603 };\r
6604 setter.$isDefault = true;\r
6605 return setter;\r
6606 }\r
6607};\r
6608\r
6609\r
6610(function() {\r
6611
6612 var ExtConfig = Ext.Config,\r
6613 configPropMap = ExtConfig.map,\r
6614 ExtObject = Ext.Object;\r
6615 Ext.Configurator = function(cls) {\r
6616
6617
6618
6619 var me = this,\r
6620 prototype = cls.prototype,\r
6621 superCfg = cls.superclass ? cls.superclass.self.$config : null;\r
6622 \r
6623 me.cls = cls;\r
6624 \r
6625 me.superCfg = superCfg;\r
6626 if (superCfg) {\r
6627 \r
6628 me.configs = ExtObject.chain(superCfg.configs);\r
6629 \r
6630 me.cachedConfigs = ExtObject.chain(superCfg.cachedConfigs);\r
6631 \r
6632 me.initMap = ExtObject.chain(superCfg.initMap);\r
6633 \r
6634 me.values = ExtObject.chain(superCfg.values);\r
6635 me.needsFork = superCfg.needsFork;\r
6636
6637
6638
6639
6640 me.deprecations = ExtObject.chain(superCfg.deprecations);\r
6641 } else
6642 {\r
6643 me.configs = {};\r
6644 me.cachedConfigs = {};\r
6645 me.initMap = {};\r
6646 me.values = {};\r
6647
6648 me.deprecations = {};\r
6649 }\r
6650
6651 prototype.config = prototype.defaultConfig = me.values;\r
6652 cls.$config = me;\r
6653 };\r
6654 Ext.Configurator.prototype = {\r
6655 self: Ext.Configurator,\r
6656 needsFork: false,\r
6657 \r
6658 initList: null,\r
6659 \r
6660 add: function(config, mixinClass) {\r
6661 var me = this,\r
6662 Cls = me.cls,\r
6663 configs = me.configs,\r
6664 cachedConfigs = me.cachedConfigs,\r
6665 initMap = me.initMap,\r
6666 prototype = Cls.prototype,\r
6667 mixinConfigs = mixinClass && mixinClass.$config.configs,\r
6668 values = me.values,\r
6669 isObject, meta, isCached, merge, cfg, currentValue, name, names, s, value;\r
6670 for (name in config) {\r
6671 value = config[name];\r
6672 isObject = value && value.constructor === Object;\r
6673 meta = isObject && '$value' in value ? value : null;\r
6674 if (meta) {\r
6675 isCached = !!meta.cached;\r
6676 value = meta.$value;\r
6677 isObject = value && value.constructor === Object;\r
6678 }\r
6679 merge = meta && meta.merge;\r
6680 cfg = configs[name];\r
6681 if (cfg) {\r
6682
6683 if (mixinClass) {\r
6684 merge = cfg.merge;\r
6685 if (!merge) {\r
6686 \r
6687 continue;\r
6688 }\r
6689
6690 meta = null;\r
6691 } else {\r
6692 merge = merge || cfg.merge;\r
6693 }\r
6694
6695
6696
6697 if (!mixinClass && isCached && !cachedConfigs[name]) {\r
6698 Ext.raise('Redefining config as cached: ' + name + ' in class: ' + Cls.$className);\r
6699 }\r
6700
6701
6702
6703
6704 currentValue = values[name];\r
6705 if (merge) {\r
6706 value = merge.call(cfg, value, currentValue, Cls, mixinClass);\r
6707 } else if (isObject) {\r
6708 if (currentValue && currentValue.constructor === Object) {\r
6709
6710
6711
6712
6713
6714 value = ExtObject.merge({}, currentValue, value);\r
6715 }\r
6716 }\r
6717 } else
6718
6719 {\r
6720
6721
6722
6723 if (mixinConfigs) {\r
6724
6725
6726
6727 cfg = mixinConfigs[name];\r
6728 meta = null;\r
6729 } else {\r
6730 cfg = ExtConfig.get(name);\r
6731 }\r
6732 configs[name] = cfg;\r
6733 if (cfg.cached || isCached) {\r
6734 cachedConfigs[name] = true;\r
6735 }\r
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760 names = cfg.names;\r
6761 if (!prototype[s = names.get]) {\r
6762 prototype[s] = cfg.getter || cfg.getGetter();\r
6763 }\r
6764 if (!prototype[s = names.set]) {\r
6765 prototype[s] = (meta && meta.evented) ? (cfg.eventedSetter || cfg.getEventedSetter()) : (cfg.setter || cfg.getSetter());\r
6766 }\r
6767 }\r
6768 if (meta) {\r
6769 if (cfg.owner !== Cls) {\r
6770 configs[name] = cfg = Ext.Object.chain(cfg);\r
6771 cfg.owner = Cls;\r
6772 }\r
6773 Ext.apply(cfg, meta);\r
6774 delete cfg.$value;\r
6775 }\r
6776
6777
6778 if (!me.needsFork && value && (value.constructor === Object || value instanceof Array)) {\r
6779 me.needsFork = true;\r
6780 }\r
6781
6782 if (value !== null) {\r
6783 initMap[name] = true;\r
6784 } else {\r
6785 if (prototype.$configPrefixed) {\r
6786 prototype[configs[name].names.internal] = null;\r
6787 } else {\r
6788 prototype[configs[name].name] = null;\r
6789 }\r
6790 if (name in initMap) {\r
6791
6792 initMap[name] = false;\r
6793 }\r
6794 }\r
6795 values[name] = value;\r
6796 }\r
6797 },\r
6798
6799 addDeprecations: function(configs) {\r
6800 var me = this,\r
6801 deprecations = me.deprecations,\r
6802 className = (me.cls.$className || '') + '#',\r
6803 message, newName, oldName;\r
6804 for (oldName in configs) {\r
6805 newName = configs[oldName];\r
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815 if (!newName) {\r
6816 message = 'This config has been removed.';\r
6817 } else if (!(message = newName.message)) {\r
6818 message = 'This config has been renamed to "' + newName + '"';\r
6819 }\r
6820 deprecations[oldName] = className + oldName + ': ' + message;\r
6821 }\r
6822 },\r
6823
6824 \r
6825 configure: function(instance, instanceConfig) {\r
6826 var me = this,\r
6827 configs = me.configs,\r
6828
6829 deprecations = me.deprecations,\r
6830
6831 initMap = me.initMap,\r
6832 initListMap = me.initListMap,\r
6833 initList = me.initList,\r
6834 prototype = me.cls.prototype,\r
6835 values = me.values,\r
6836 remaining = 0,\r
6837 firstInstance = !initList,\r
6838 cachedInitList, cfg, getter, needsInit, i, internalName, ln, names, name, value, isCached, valuesKey, field;\r
6839 values = me.needsFork ? ExtObject.fork(values) : ExtObject.chain(values);\r
6840
6841 instance.isConfiguring = true;\r
6842 if (firstInstance) {\r
6843
6844
6845 me.initList = initList = [];\r
6846 me.initListMap = initListMap = {};\r
6847 instance.isFirstInstance = true;\r
6848 for (name in initMap) {\r
6849 needsInit = initMap[name];\r
6850 cfg = configs[name];\r
6851 isCached = cfg.cached;\r
6852 if (needsInit) {\r
6853 names = cfg.names;\r
6854 value = values[name];\r
6855 if (!prototype[names.set].$isDefault || prototype[names.apply] || prototype[names.update] || typeof value === 'object') {\r
6856 if (isCached) {\r
6857
6858
6859
6860
6861
6862 (cachedInitList || (cachedInitList = [])).push(cfg);\r
6863 } else {\r
6864
6865
6866 initList.push(cfg);\r
6867 initListMap[name] = true;\r
6868 }\r
6869
6870
6871
6872 instance[names.get] = cfg.initGetter || cfg.getInitGetter();\r
6873 } else {\r
6874
6875
6876 prototype[cfg.getInternalName(prototype)] = value;\r
6877 }\r
6878 } else if (isCached) {\r
6879 prototype[cfg.getInternalName(prototype)] = undefined;\r
6880 }\r
6881 }\r
6882 }\r
6883
6884
6885
6886 ln = cachedInitList && cachedInitList.length;\r
6887 if (ln) {\r
6888
6889
6890
6891
6892 for (i = 0; i < ln; ++i) {\r
6893 internalName = cachedInitList[i].getInternalName(prototype);\r
6894
6895
6896
6897 instance[internalName] = null;\r
6898 }\r
6899 for (i = 0; i < ln; ++i) {\r
6900 names = (cfg = cachedInitList[i]).names;\r
6901 getter = names.get;\r
6902 if (instance.hasOwnProperty(getter)) {\r
6903 instance[names.set](values[cfg.name]);\r
6904 delete instance[getter];\r
6905 }\r
6906 }\r
6907 for (i = 0; i < ln; ++i) {\r
6908 internalName = cachedInitList[i].getInternalName(prototype);\r
6909 prototype[internalName] = instance[internalName];\r
6910 delete instance[internalName];\r
6911 }\r
6912 }\r
6913
6914
6915
6916
6917 if (instanceConfig && instanceConfig.platformConfig) {\r
6918 instanceConfig = me.resolvePlatformConfig(instance, instanceConfig);\r
6919 }\r
6920 if (firstInstance) {\r
6921
6922
6923
6924 if (instance.afterCachedConfig && !instance.afterCachedConfig.$nullFn) {\r
6925 instance.afterCachedConfig(instanceConfig);\r
6926 }\r
6927 }\r
6928
6929
6930
6931 instance.config = values;\r
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946 for (i = 0 , ln = initList.length; i < ln; ++i) {\r
6947 cfg = initList[i];\r
6948 instance[cfg.names.get] = cfg.initGetter || cfg.getInitGetter();\r
6949 }\r
6950
6951 if (instance.transformInstanceConfig) {\r
6952 instanceConfig = instance.transformInstanceConfig(instanceConfig);\r
6953 }\r
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966 if (instanceConfig) {\r
6967 for (name in instanceConfig) {\r
6968 value = instanceConfig[name];\r
6969 cfg = configs[name];\r
6970
6971 if (deprecations[name]) {\r
6972 Ext.log.warn(deprecations[name]);\r
6973 if (!cfg) {\r
6974
6975
6976
6977
6978 \r
6979 continue;\r
6980 }\r
6981 }\r
6982
6983 if (!cfg) {\r
6984
6985 field = instance.self.prototype[name];\r
6986 if (instance.$configStrict && (typeof field === 'function') && !field.$nullFn) {\r
6987
6988 Ext.raise('Cannot override method ' + name + ' on ' + instance.$className + ' instance.');\r
6989 }\r
6990
6991
6992
6993 instance[name] = value;\r
6994 } else {\r
6995
6996
6997 if (!cfg.lazy) {\r
6998 ++remaining;\r
6999 }\r
7000 if (!initListMap[name]) {\r
7001 instance[cfg.names.get] = cfg.initGetter || cfg.getInitGetter();\r
7002 }\r
7003 if (cfg.merge) {\r
7004 value = cfg.merge(value, values[name], instance);\r
7005 } else if (value && value.constructor === Object) {\r
7006 valuesKey = values[name];\r
7007 if (valuesKey && valuesKey.constructor === Object) {\r
7008 value = ExtObject.merge(values[name], value);\r
7009 } else {\r
7010 value = Ext.clone(value);\r
7011 }\r
7012 }\r
7013 }\r
7014 values[name] = value;\r
7015 }\r
7016 }\r
7017
7018 if (instance.beforeInitConfig && !instance.beforeInitConfig.$nullFn) {\r
7019 if (instance.beforeInitConfig(instanceConfig) === false) {\r
7020 return;\r
7021 }\r
7022 }\r
7023 if (instanceConfig) {\r
7024 for (name in instanceConfig) {\r
7025 if (!remaining) {\r
7026
7027
7028 break;\r
7029 }\r
7030
7031
7032
7033 cfg = configs[name];\r
7034 if (cfg && !cfg.lazy) {\r
7035 --remaining;\r
7036
7037 names = cfg.names;\r
7038 getter = names.get;\r
7039
7040
7041
7042
7043 if (instance.hasOwnProperty(getter)) {\r
7044 instance[names.set](values[name]);\r
7045
7046
7047
7048 delete instance[names.get];\r
7049 }\r
7050 }\r
7051 }\r
7052 }\r
7053
7054 for (i = 0 , ln = initList.length; i < ln; ++i) {\r
7055 cfg = initList[i];\r
7056 names = cfg.names;\r
7057 getter = names.get;\r
7058 if (!cfg.lazy && instance.hasOwnProperty(getter)) {\r
7059
7060
7061
7062
7063 instance[names.set](values[cfg.name]);\r
7064 delete instance[getter];\r
7065 }\r
7066 }\r
7067
7068 delete instance.isConfiguring;\r
7069 },\r
7070 getCurrentConfig: function(instance) {\r
7071 var defaultConfig = instance.defaultConfig,\r
7072 config = {},\r
7073 name;\r
7074 for (name in defaultConfig) {\r
7075 config[name] = instance[configPropMap[name].names.get]();\r
7076 }\r
7077 return config;\r
7078 },\r
7079 \r
7080 merge: function(instance, baseConfig, config) {\r
7081
7082
7083 var configs = this.configs,\r
7084 name, value, baseValue, cfg;\r
7085 for (name in config) {\r
7086 value = config[name];\r
7087 cfg = configs[name];\r
7088 if (cfg) {\r
7089 if (cfg.merge) {\r
7090 value = cfg.merge(value, baseConfig[name], instance);\r
7091 } else if (value && value.constructor === Object) {\r
7092 baseValue = baseConfig[name];\r
7093 if (baseValue && baseValue.constructor === Object) {\r
7094 value = Ext.Object.merge(baseValue, value);\r
7095 } else {\r
7096 value = Ext.clone(value);\r
7097 }\r
7098 }\r
7099 }\r
7100 baseConfig[name] = value;\r
7101 }\r
7102 return baseConfig;\r
7103 },\r
7104 \r
7105 reconfigure: function(instance, instanceConfig, options) {\r
7106 var currentConfig = instance.config,\r
7107 configList = [],\r
7108 strict = instance.$configStrict && !(options && options.strict === false),\r
7109 configs = this.configs,\r
7110 defaults = options && options.defaults,\r
7111 cfg, getter, i, len, name, names, prop;\r
7112 for (name in instanceConfig) {\r
7113 if (defaults && instance.hasOwnProperty(name)) {\r
7114 \r
7115 continue;\r
7116 }\r
7117 currentConfig[name] = instanceConfig[name];\r
7118 cfg = configs[name];\r
7119
7120 if (this.deprecations[name]) {\r
7121
7122 Ext.log.warn(this.deprecations[name]);\r
7123 if (!cfg) {\r
7124 \r
7125 continue;\r
7126 }\r
7127 }\r
7128
7129 if (cfg) {\r
7130
7131
7132 instance[cfg.names.get] = cfg.initGetter || cfg.getInitGetter();\r
7133 } else {\r
7134
7135
7136
7137
7138
7139
7140
7141 prop = instance.self.prototype[name];\r
7142 if (strict) {\r
7143 if ((typeof prop === 'function') && !prop.$nullFn) {\r
7144
7145 Ext.Error.raise("Cannot override method " + name + " on " + instance.$className + " instance.");\r
7146
7147 \r
7148 continue;\r
7149 } else
7150 {\r
7151 if (name !== 'type') {\r
7152 Ext.log.warn('No such config "' + name + '" for class ' + instance.$className);\r
7153 }\r
7154 }\r
7155 }\r
7156 }\r
7157
7158 configList.push(name);\r
7159 }\r
7160 for (i = 0 , len = configList.length; i < len; i++) {\r
7161 name = configList[i];\r
7162 cfg = configs[name];\r
7163 if (cfg) {\r
7164 names = cfg.names;\r
7165 getter = names.get;\r
7166 if (instance.hasOwnProperty(getter)) {\r
7167
7168
7169
7170
7171 instance[names.set](instanceConfig[name]);\r
7172 delete instance[getter];\r
7173 }\r
7174 } else {\r
7175 cfg = configPropMap[name] || Ext.Config.get(name);\r
7176 names = cfg.names;\r
7177 if (instance[names.set]) {\r
7178 instance[names.set](instanceConfig[name]);\r
7179 } else {\r
7180
7181 instance[name] = instanceConfig[name];\r
7182 }\r
7183 }\r
7184 }\r
7185 },\r
7186 \r
7187 resolvePlatformConfig: function(instance, instanceConfig) {\r
7188 var platformConfig = instanceConfig && instanceConfig.platformConfig,\r
7189 ret = instanceConfig,\r
7190 i, keys, n;\r
7191 if (platformConfig) {\r
7192 keys = Ext.getPlatformConfigKeys(platformConfig);\r
7193 n = keys.length;\r
7194 if (n) {\r
7195 ret = Ext.merge({}, ret);\r
7196
7197 for (i = 0 , n = keys.length; i < n; ++i) {\r
7198 this.merge(instance, ret, platformConfig[keys[i]]);\r
7199 }\r
7200 }\r
7201 }\r
7202 return ret;\r
7203 }\r
7204 };\r
7205}());\r
7206
7207
7208\r
7209
7210\r
7211Ext.Base = (function(flexSetter) {\r
7212
7213
7214
7215
7216
7217 var noArgs = [],\r
7218 baseStaticMember,\r
7219 baseStaticMembers = [],\r
7220 getConfig = function(name, peek) {\r
7221 var me = this,\r
7222 ret, cfg, getterName;\r
7223 if (name) {\r
7224 cfg = Ext.Config.map[name];\r
7225
7226 if (!cfg) {\r
7227 Ext.Logger.error("Invalid property name for getter: '" + name + "' for '" + me.$className + "'.");\r
7228 }\r
7229
7230 getterName = cfg.names.get;\r
7231 if (peek && me.hasOwnProperty(getterName)) {\r
7232 ret = me.config[name];\r
7233 } else {\r
7234 ret = me[getterName]();\r
7235 }\r
7236 } else {\r
7237 ret = me.getCurrentConfig();\r
7238 }\r
7239 return ret;\r
7240 },\r
7241
7242 makeDeprecatedMethod = function(oldName, newName, msg) {\r
7243 var message = '"' + oldName + '" is deprecated.';\r
7244 if (msg) {\r
7245 message += ' ' + msg;\r
7246 } else if (newName) {\r
7247 message += ' Please use "' + newName + '" instead.';\r
7248 }\r
7249 return function() {\r
7250 Ext.raise(message);\r
7251 };\r
7252 },\r
7253 addDeprecatedProperty = function(object, oldName, newName, message) {\r
7254 if (!message) {\r
7255 message = '"' + oldName + '" is deprecated.';\r
7256 }\r
7257 if (newName) {\r
7258 message += ' Please use "' + newName + '" instead.';\r
7259 }\r
7260 if (message) {\r
7261 Ext.Object.defineProperty(object, oldName, {\r
7262 get: function() {\r
7263 Ext.raise(message);\r
7264 },\r
7265 set: function(value) {\r
7266 Ext.raise(message);\r
7267 },\r
7268 configurable: true\r
7269 });\r
7270 }\r
7271 },\r
7272
7273 makeAliasFn = function(name) {\r
7274 return function() {\r
7275 return this[name].apply(this, arguments);\r
7276 };\r
7277 },\r
7278 Version = Ext.Version,\r
7279 leadingDigitRe = /^\d/,\r
7280 oneMember = {},\r
7281 aliasOneMember = {},\r
7282 Base = function() {},\r
7283 BasePrototype = Base.prototype;\r
7284
7285 Ext.apply(Base, {\r
7286 $className: 'Ext.Base',\r
7287 $isClass: true,\r
7288 \r
7289 create: function() {\r
7290 return Ext.create.apply(Ext, [\r
7291 this\r
7292 ].concat(Array.prototype.slice.call(arguments, 0)));\r
7293 },\r
7294 \r
7295 addDeprecations: function(deprecations) {\r
7296 var me = this,\r
7297 all = [],\r
7298 compatVersion = Ext.getCompatVersion(deprecations.name),\r
7299
7300 configurator = me.getConfigurator(),\r
7301 displayName = (me.$className || '') + '#',\r
7302
7303 deprecate, versionSpec, index, message, target, enabled, existing, fn, names, oldName, newName, member, statics, version;\r
7304 for (versionSpec in deprecations) {\r
7305 if (leadingDigitRe.test(versionSpec)) {\r
7306 version = new Ext.Version(versionSpec);\r
7307 version.deprecations = deprecations[versionSpec];\r
7308 all.push(version);\r
7309 }\r
7310 }\r
7311 all.sort(Version.compare);\r
7312 for (index = all.length; index--; ) {\r
7313 deprecate = (version = all[index]).deprecations;\r
7314 target = me.prototype;\r
7315 statics = deprecate.statics;\r
7316
7317
7318
7319
7320
7321
7322 enabled = compatVersion && compatVersion.lt(version);\r
7323
7324 if (!enabled) {}\r
7325
7326 else if (!enabled) {\r
7327
7328 break;\r
7329 }\r
7330 while (deprecate) {\r
7331 names = deprecate.methods;\r
7332 if (names) {\r
7333 for (oldName in names) {\r
7334 member = names[oldName];\r
7335 fn = null;\r
7336 if (!member) {\r
7337 \r
7338
7339
7340 Ext.Assert.isNotDefinedProp(target, oldName);\r
7341 fn = makeDeprecatedMethod(displayName + oldName);\r
7342 }\r
7343
7344 else if (Ext.isString(member)) {\r
7345 \r
7346
7347
7348 Ext.Assert.isNotDefinedProp(target, oldName);\r
7349 Ext.Assert.isDefinedProp(target, member);\r
7350
7351 if (enabled) {\r
7352
7353
7354 fn = makeAliasFn(member);\r
7355 } else
7356 {\r
7357 fn = makeDeprecatedMethod(displayName + oldName, member);\r
7358 }\r
7359 } else
7360 {\r
7361 \r
7362 message = '';\r
7363 if (member.message || member.fn) {\r
7364
7365 message = member.message;\r
7366
7367 member = member.fn;\r
7368 }\r
7369 existing = target.hasOwnProperty(oldName) && target[oldName];\r
7370 if (enabled && member) {\r
7371 member.$owner = me;\r
7372 member.$name = oldName;\r
7373
7374 member.name = displayName + oldName;\r
7375
7376 if (existing) {\r
7377 member.$previous = existing;\r
7378 }\r
7379 fn = member;\r
7380 }\r
7381
7382 else if (!existing) {\r
7383 fn = makeDeprecatedMethod(displayName + oldName, null, message);\r
7384 }\r
7385 }\r
7386
7387 if (fn) {\r
7388 target[oldName] = fn;\r
7389 }\r
7390 }\r
7391 }\r
7392
7393
7394
7395
7396 names = deprecate.configs;\r
7397 if (names) {\r
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411 configurator.addDeprecations(names);\r
7412 }\r
7413 names = deprecate.properties;\r
7414 if (names && !enabled) {\r
7415
7416
7417
7418 for (oldName in names) {\r
7419 newName = names[oldName];\r
7420 if (Ext.isString(newName)) {\r
7421 addDeprecatedProperty(target, displayName + oldName, newName);\r
7422 } else if (newName && newName.message) {\r
7423 addDeprecatedProperty(target, displayName + oldName, null, newName.message);\r
7424 } else {\r
7425 addDeprecatedProperty(target, displayName + oldName);\r
7426 }\r
7427 }\r
7428 }\r
7429
7430
7431
7432 deprecate = statics;\r
7433 statics = null;\r
7434 target = me;\r
7435 }\r
7436 }\r
7437 },\r
7438 \r
7439 extend: function(parent) {\r
7440 var me = this,\r
7441 parentPrototype = parent.prototype,\r
7442 prototype, i, ln, name, statics;\r
7443 prototype = me.prototype = Ext.Object.chain(parentPrototype);\r
7444 prototype.self = me;\r
7445 me.superclass = prototype.superclass = parentPrototype;\r
7446 if (!parent.$isClass) {\r
7447 for (i in BasePrototype) {\r
7448 if (i in prototype) {\r
7449 prototype[i] = BasePrototype[i];\r
7450 }\r
7451 }\r
7452 }\r
7453
7454
7455 statics = parentPrototype.$inheritableStatics;\r
7456 if (statics) {\r
7457 for (i = 0 , ln = statics.length; i < ln; i++) {\r
7458 name = statics[i];\r
7459 if (!me.hasOwnProperty(name)) {\r
7460 me[name] = parent[name];\r
7461 }\r
7462 }\r
7463 }\r
7464
7465 if (parent.$onExtended) {\r
7466 me.$onExtended = parent.$onExtended.slice();\r
7467 }\r
7468
7469 me.getConfigurator();\r
7470 },\r
7471
7472 \r
7473 $onExtended: [],\r
7474 \r
7475 triggerExtended: function() {\r
7476
7477 Ext.classSystemMonitor && Ext.classSystemMonitor(this, 'Ext.Base#triggerExtended', arguments);\r
7478
7479 var callbacks = this.$onExtended,\r
7480 ln = callbacks.length,\r
7481 i, callback;\r
7482 if (ln > 0) {\r
7483 for (i = 0; i < ln; i++) {\r
7484 callback = callbacks[i];\r
7485 callback.fn.apply(callback.scope || this, arguments);\r
7486 }\r
7487 }\r
7488 },\r
7489 \r
7490 onExtended: function(fn, scope) {\r
7491 this.$onExtended.push({\r
7492 fn: fn,\r
7493 scope: scope\r
7494 });\r
7495 return this;\r
7496 },\r
7497 \r
7498 addStatics: function(members) {\r
7499 this.addMembers(members, true);\r
7500 return this;\r
7501 },\r
7502 \r
7503 addInheritableStatics: function(members) {\r
7504 var inheritableStatics, hasInheritableStatics,\r
7505 prototype = this.prototype,\r
7506 name, member;\r
7507 inheritableStatics = prototype.$inheritableStatics;\r
7508 hasInheritableStatics = prototype.$hasInheritableStatics;\r
7509 if (!inheritableStatics) {\r
7510 inheritableStatics = prototype.$inheritableStatics = [];\r
7511 hasInheritableStatics = prototype.$hasInheritableStatics = {};\r
7512 }\r
7513
7514 var className = Ext.getClassName(this) + '.';\r
7515
7516 for (name in members) {\r
7517 if (members.hasOwnProperty(name)) {\r
7518 member = members[name];\r
7519
7520 if (typeof member == 'function') {\r
7521 member.name = className + name;\r
7522 }\r
7523
7524 this[name] = member;\r
7525 if (!hasInheritableStatics[name]) {\r
7526 hasInheritableStatics[name] = true;\r
7527 inheritableStatics.push(name);\r
7528 }\r
7529 }\r
7530 }\r
7531 return this;\r
7532 },\r
7533 \r
7534 addMembers: function(members, isStatic, privacy) {\r
7535 var me = this,\r
7536
7537 cloneFunction = Ext.Function.clone,\r
7538 target = isStatic ? me : me.prototype,\r
7539 defaultConfig = !isStatic && target.defaultConfig,\r
7540 enumerables = Ext.enumerables,\r
7541 privates = members.privates,\r
7542 configs, i, ln, member, name, subPrivacy, privateStatics;\r
7543
7544 var displayName = (me.$className || '') + '#';\r
7545
7546 if (privates) {\r
7547
7548
7549 delete members.privates;\r
7550 if (!isStatic) {\r
7551 privateStatics = privates.statics;\r
7552 delete privates.statics;\r
7553 }\r
7554
7555 subPrivacy = privates.privacy || privacy || 'framework';\r
7556
7557 me.addMembers(privates, isStatic, subPrivacy);\r
7558 if (privateStatics) {\r
7559 me.addMembers(privateStatics, true, subPrivacy);\r
7560 }\r
7561 }\r
7562 for (name in members) {\r
7563 if (members.hasOwnProperty(name)) {\r
7564 member = members[name];\r
7565
7566 if (privacy === true) {\r
7567 privacy = 'framework';\r
7568 }\r
7569 if (member && member.$nullFn && privacy !== member.$privacy) {\r
7570 Ext.raise('Cannot use stock function for private method ' + (me.$className ? me.$className + '#' : '') + name);\r
7571 }\r
7572
7573 if (typeof member === 'function' && !member.$isClass && !member.$nullFn) {\r
7574 if (member.$owner) {\r
7575 member = cloneFunction(member);\r
7576 }\r
7577 if (target.hasOwnProperty(name)) {\r
7578 member.$previous = target[name];\r
7579 }\r
7580
7581
7582 member.$owner = me;\r
7583 member.$name = name;\r
7584
7585 member.name = displayName + name;\r
7586 var existing = target[name];\r
7587 if (privacy) {\r
7588 member.$privacy = privacy;\r
7589
7590
7591
7592
7593
7594
7595 if (existing && existing.$privacy && existing.$privacy !== privacy) {\r
7596 Ext.privacyViolation(me, existing, member, isStatic);\r
7597 }\r
7598 } else if (existing && existing.$privacy) {\r
7599 Ext.privacyViolation(me, existing, member, isStatic);\r
7600 }\r
7601 }\r
7602
7603
7604
7605 else if (defaultConfig && (name in defaultConfig) && !target.config.hasOwnProperty(name)) {\r
7606
7607
7608 (configs || (configs = {}))[name] = member;\r
7609 \r
7610 continue;\r
7611 }\r
7612 target[name] = member;\r
7613 }\r
7614 }\r
7615 if (configs) {\r
7616
7617 me.addConfig(configs);\r
7618 }\r
7619 if (enumerables) {\r
7620 for (i = 0 , ln = enumerables.length; i < ln; ++i) {\r
7621 if (members.hasOwnProperty(name = enumerables[i])) {\r
7622 member = members[name];\r
7623
7624 if (member && !member.$nullFn) {\r
7625 if (member.$owner) {\r
7626 member = cloneFunction(member);\r
7627 }\r
7628 member.$owner = me;\r
7629 member.$name = name;\r
7630
7631 member.name = displayName + name;\r
7632
7633 if (target.hasOwnProperty(name)) {\r
7634 member.$previous = target[name];\r
7635 }\r
7636 }\r
7637 target[name] = member;\r
7638 }\r
7639 }\r
7640 }\r
7641 return this;\r
7642 },\r
7643 \r
7644 addMember: function(name, member) {\r
7645 oneMember[name] = member;\r
7646 this.addMembers(oneMember);\r
7647 delete oneMember[name];\r
7648 return this;\r
7649 },\r
7650 \r
7651 borrow: function(fromClass, members) {\r
7652
7653 Ext.classSystemMonitor && Ext.classSystemMonitor(this, 'Ext.Base#borrow', arguments);\r
7654
7655 var prototype = fromClass.prototype,\r
7656 membersObj = {},\r
7657 i, ln, name;\r
7658 members = Ext.Array.from(members);\r
7659 for (i = 0 , ln = members.length; i < ln; i++) {\r
7660 name = members[i];\r
7661 membersObj[name] = prototype[name];\r
7662 }\r
7663 return this.addMembers(membersObj);\r
7664 },\r
7665 \r
7666 override: function(members) {\r
7667 var me = this,\r
7668 statics = members.statics,\r
7669 inheritableStatics = members.inheritableStatics,\r
7670 config = members.config,\r
7671 mixins = members.mixins,\r
7672 cachedConfig = members.cachedConfig;\r
7673 if (statics || inheritableStatics || config) {\r
7674 members = Ext.apply({}, members);\r
7675 }\r
7676 if (statics) {\r
7677 me.addMembers(statics, true);\r
7678 delete members.statics;\r
7679 }\r
7680 if (inheritableStatics) {\r
7681 me.addInheritableStatics(inheritableStatics);\r
7682 delete members.inheritableStatics;\r
7683 }\r
7684 if (config) {\r
7685 me.addConfig(config);\r
7686 delete members.config;\r
7687 }\r
7688 if (cachedConfig) {\r
7689 me.addCachedConfig(cachedConfig);\r
7690 delete members.cachedConfig;\r
7691 }\r
7692 delete members.mixins;\r
7693 me.addMembers(members);\r
7694 if (mixins) {\r
7695 me.mixin(mixins);\r
7696 }\r
7697 return me;\r
7698 },\r
7699 \r
7700 callParent: function(args) {\r
7701 var method;\r
7702
7703 return (method = this.callParent.caller) && (method.$previous || ((method = method.$owner ? method : method.caller) && method.$owner.superclass.self[method.$name])).apply(this, args || noArgs);\r
7704 },\r
7705 \r
7706 callSuper: function(args) {\r
7707 var method;\r
7708
7709 return (method = this.callSuper.caller) && ((method = method.$owner ? method : method.caller) && method.$owner.superclass.self[method.$name]).apply(this, args || noArgs);\r
7710 },\r
7711
7712 \r
7713 mixin: function(name, mixinClass) {\r
7714 var me = this,\r
7715 mixin, prototype, key, statics, i, ln, staticName, mixinValue, mixins;\r
7716 if (typeof name !== 'string') {\r
7717 mixins = name;\r
7718 if (mixins instanceof Array) {\r
7719 for (i = 0 , ln = mixins.length; i < ln; i++) {\r
7720 mixin = mixins[i];\r
7721 me.mixin(mixin.prototype.mixinId || mixin.$className, mixin);\r
7722 }\r
7723 } else {\r
7724
7725
7726
7727
7728 for (var mixinName in mixins) {\r
7729 me.mixin(mixinName, mixins[mixinName]);\r
7730 }\r
7731 }\r
7732 return;\r
7733 }\r
7734 mixin = mixinClass.prototype;\r
7735 prototype = me.prototype;\r
7736 if (mixin.onClassMixedIn) {\r
7737 mixin.onClassMixedIn.call(mixinClass, me);\r
7738 }\r
7739 if (!prototype.hasOwnProperty('mixins')) {\r
7740 if ('mixins' in prototype) {\r
7741 prototype.mixins = Ext.Object.chain(prototype.mixins);\r
7742 } else {\r
7743 prototype.mixins = {};\r
7744 }\r
7745 }\r
7746 for (key in mixin) {\r
7747 mixinValue = mixin[key];\r
7748 if (key === 'mixins') {\r
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759 Ext.applyIf(prototype.mixins, mixinValue);\r
7760 } else if (!(key === 'mixinId' || key === 'config') && (prototype[key] === undefined)) {\r
7761 prototype[key] = mixinValue;\r
7762 }\r
7763 }\r
7764
7765
7766 statics = mixin.$inheritableStatics;\r
7767 if (statics) {\r
7768 for (i = 0 , ln = statics.length; i < ln; i++) {\r
7769 staticName = statics[i];\r
7770 if (!me.hasOwnProperty(staticName)) {\r
7771 me[staticName] = mixinClass[staticName];\r
7772 }\r
7773 }\r
7774 }\r
7775
7776
7777 if ('config' in mixin) {\r
7778 me.addConfig(mixin.config, mixinClass);\r
7779 }\r
7780
7781 prototype.mixins[name] = mixin;\r
7782 if (mixin.afterClassMixedIn) {\r
7783 mixin.afterClassMixedIn.call(mixinClass, me);\r
7784 }\r
7785 return me;\r
7786 },\r
7787
7788
7789 \r
7790 addConfig: function(config, mixinClass) {\r
7791 var cfg = this.$config || this.getConfigurator();\r
7792 cfg.add(config, mixinClass);\r
7793 },\r
7794 addCachedConfig: function(config, isMixin) {\r
7795 var cached = {},\r
7796 key;\r
7797 for (key in config) {\r
7798 cached[key] = {\r
7799 cached: true,\r
7800 $value: config[key]\r
7801 };\r
7802 }\r
7803 this.addConfig(cached, isMixin);\r
7804 },\r
7805 \r
7806 getConfigurator: function() {\r
7807
7808 return this.$config || new Ext.Configurator(this);\r
7809 },\r
7810
7811 \r
7812 getName: function() {\r
7813 return Ext.getClassName(this);\r
7814 },\r
7815 \r
7816 createAlias: flexSetter(function(alias, origin) {\r
7817 aliasOneMember[alias] = function() {\r
7818 return this[origin].apply(this, arguments);\r
7819 };\r
7820 this.override(aliasOneMember);\r
7821 delete aliasOneMember[alias];\r
7822 })\r
7823 });\r
7824
7825
7826 for (baseStaticMember in Base) {\r
7827 if (Base.hasOwnProperty(baseStaticMember)) {\r
7828 baseStaticMembers.push(baseStaticMember);\r
7829 }\r
7830 }\r
7831 Base.$staticMembers = baseStaticMembers;\r
7832
7833 Base.getConfigurator();\r
7834
7835
7836 Base.addMembers({\r
7837 \r
7838 $className: 'Ext.Base',\r
7839 \r
7840 isInstance: true,\r
7841 \r
7842 $configPrefixed: true,\r
7843 \r
7844 $configStrict: true,\r
7845 \r
7846 isConfiguring: false,\r
7847 \r
7848 isFirstInstance: false,\r
7849 \r
7850 destroyed: false,\r
7851 \r
7852 statics: function() {\r
7853 var method = this.statics.caller,\r
7854 self = this.self;\r
7855 if (!method) {\r
7856 return self;\r
7857 }\r
7858 return method.$owner;\r
7859 },\r
7860 \r
7861 callParent: function(args) {\r
7862
7863
7864
7865
7866 var method,\r
7867 superMethod = (method = this.callParent.caller) && (method.$previous || ((method = method.$owner ? method : method.caller) && method.$owner.superclass[method.$name]));\r
7868
7869 if (!superMethod) {\r
7870 method = this.callParent.caller;\r
7871 var parentClass, methodName;\r
7872 if (!method.$owner) {\r
7873 if (!method.caller) {\r
7874 throw new Error("Attempting to call a protected method from the public scope, which is not allowed");\r
7875 }\r
7876 method = method.caller;\r
7877 }\r
7878 parentClass = method.$owner.superclass;\r
7879 methodName = method.$name;\r
7880 if (!(methodName in parentClass)) {\r
7881 throw new Error("this.callParent() was called but there's no such method (" + methodName + ") found in the parent class (" + (Ext.getClassName(parentClass) || 'Object') + ")");\r
7882 }\r
7883 }\r
7884
7885 return superMethod.apply(this, args || noArgs);\r
7886 },\r
7887 \r
7888 callSuper: function(args) {\r
7889
7890
7891
7892
7893 var method,\r
7894 superMethod = (method = this.callSuper.caller) && ((method = method.$owner ? method : method.caller) && method.$owner.superclass[method.$name]);\r
7895
7896 if (!superMethod) {\r
7897 method = this.callSuper.caller;\r
7898 var parentClass, methodName;\r
7899 if (!method.$owner) {\r
7900 if (!method.caller) {\r
7901 throw new Error("Attempting to call a protected method from the public scope, which is not allowed");\r
7902 }\r
7903 method = method.caller;\r
7904 }\r
7905 parentClass = method.$owner.superclass;\r
7906 methodName = method.$name;\r
7907 if (!(methodName in parentClass)) {\r
7908 throw new Error("this.callSuper() was called but there's no such method (" + methodName + ") found in the parent class (" + (Ext.getClassName(parentClass) || 'Object') + ")");\r
7909 }\r
7910 }\r
7911
7912 return superMethod.apply(this, args || noArgs);\r
7913 },\r
7914 \r
7915 self: Base,\r
7916
7917 constructor: function() {\r
7918 return this;\r
7919 },\r
7920
7921 getConfigurator: function() {\r
7922 return this.$config || this.self.getConfigurator();\r
7923 },\r
7924 \r
7925 initConfig: function(instanceConfig) {\r
7926 var me = this,\r
7927 cfg = me.getConfigurator();\r
7928 me.initConfig = Ext.emptyFn;\r
7929
7930 me.initialConfig = instanceConfig || {};\r
7931 cfg.configure(me, instanceConfig);\r
7932 return me;\r
7933 },\r
7934 beforeInitConfig: Ext.emptyFn,\r
7935 \r
7936 getConfig: getConfig,\r
7937 \r
7938 setConfig: function(name, value, \r
7939 options) {\r
7940
7941
7942
7943
7944
7945 var me = this,\r
7946 config;\r
7947 if (name) {\r
7948 if (typeof name === 'string') {\r
7949 config = {};\r
7950 config[name] = value;\r
7951 } else {\r
7952 config = name;\r
7953 }\r
7954 me.getConfigurator().reconfigure(me, config, options);\r
7955 }\r
7956 return me;\r
7957 },\r
7958 \r
7959 getCurrentConfig: function() {\r
7960 var cfg = this.getConfigurator();\r
7961 return cfg.getCurrentConfig(this);\r
7962 },\r
7963 \r
7964 hasConfig: function(name) {\r
7965 return name in this.defaultConfig;\r
7966 },\r
7967 \r
7968 getInitialConfig: function(name) {\r
7969 var config = this.config;\r
7970 if (!name) {\r
7971 return config;\r
7972 }\r
7973 return config[name];\r
7974 },\r
7975
7976 $links: null,\r
7977 \r
7978 link: function(name, value) {\r
7979 var me = this,\r
7980 links = me.$links || (me.$links = {});\r
7981 links[name] = true;\r
7982 me[name] = value;\r
7983 return value;\r
7984 },\r
7985 \r
7986 unlink: function(names) {\r
7987 var me = this,\r
7988 i, ln, link, value;\r
7989
7990 if (!Ext.isArray(names)) {\r
7991 Ext.raise('Invalid argument - expected array of strings');\r
7992 }\r
7993
7994 for (i = 0 , ln = names.length; i < ln; i++) {\r
7995 link = names[i];\r
7996 value = me[link];\r
7997 if (value) {\r
7998 if (value.isInstance && !value.destroyed) {\r
7999 value.destroy();\r
8000 } else if (value.parentNode && 'nodeType' in value) {\r
8001 value.parentNode.removeChild(value);\r
8002 }\r
8003 }\r
8004 me[link] = null;\r
8005 }\r
8006 return me;\r
8007 },\r
8008 \r
8009 destroy: function() {\r
8010 var me = this,\r
8011 links = me.$links;\r
8012 me.initialConfig = me.config = null;\r
8013 me.destroy = Ext.emptyFn;\r
8014
8015 me.isDestroyed = me.destroyed = true;\r
8016 if (links) {\r
8017 me.$links = null;\r
8018 me.unlink(Ext.Object.getKeys(links));\r
8019 }\r
8020 }\r
8021 });\r
8022 \r
8023 BasePrototype.callOverridden = BasePrototype.callParent;\r
8024
8025 Ext.privacyViolation = function(cls, existing, member, isStatic) {\r
8026 var name = member.$name,\r
8027 conflictCls = existing.$owner && existing.$owner.$className,\r
8028 s = isStatic ? 'static ' : '',\r
8029 msg = member.$privacy ? 'Private ' + s + member.$privacy + ' method "' + name + '"' : 'Public ' + s + 'method "' + name + '"';\r
8030 if (cls.$className) {\r
8031 msg = cls.$className + ': ' + msg;\r
8032 }\r
8033 if (!existing.$privacy) {\r
8034 msg += conflictCls ? ' hides public method inherited from ' + conflictCls : ' hides inherited public method.';\r
8035 } else {\r
8036 msg += conflictCls ? ' conflicts with private ' + existing.$privacy + ' method declared by ' + conflictCls : ' conflicts with inherited private ' + existing.$privacy + ' method.';\r
8037 }\r
8038 var compat = Ext.getCompatVersion();\r
8039 var ver = Ext.getVersion();\r
8040
8041 if (ver && compat && compat.lt(ver)) {\r
8042 Ext.log.error(msg);\r
8043 } else {\r
8044 Ext.raise(msg);\r
8045 }\r
8046 };\r
8047
8048 return Base;\r
8049}(Ext.Function.flexSetter));\r
8050\r
8051\r
8052(function(Cache, prototype) {\r
8053
8054
8055
8056 (Ext.util || (Ext.util = {})).Cache = Cache = function(config) {\r
8057 var me = this,\r
8058 head;\r
8059 if (config) {\r
8060 Ext.apply(me, config);\r
8061 }\r
8062
8063 me.head = head = {\r
8064
8065 id: (me.seed = 0),\r
8066
8067 key: null,\r
8068 value: null\r
8069 };\r
8070 me.map = {};\r
8071 head.next = head.prev = head;\r
8072 };\r
8073 Cache.prototype = prototype = {\r
8074 \r
8075 maxSize: 100,\r
8076 \r
8077 count: 0,\r
8078 \r
8079 \r
8080 clear: function() {\r
8081 var me = this,\r
8082 head = me.head,\r
8083 entry = head.next;\r
8084 head.next = head.prev = head;\r
8085 if (!me.evict.$nullFn) {\r
8086 for (; entry !== head; entry = entry.next) {\r
8087 me.evict(entry.key, entry.value);\r
8088 }\r
8089 }\r
8090 me.count = 0;\r
8091 },\r
8092 \r
8093 each: function(fn, scope) {\r
8094 scope = scope || this;\r
8095 for (var head = this.head,\r
8096 ent = head.next; ent !== head; ent = ent.next) {\r
8097 if (fn.call(scope, ent.key, ent.value)) {\r
8098 break;\r
8099 }\r
8100 }\r
8101 },\r
8102 \r
8103 get: function(key) {\r
8104 var me = this,\r
8105 head = me.head,\r
8106 map = me.map,\r
8107 entry = map[key];\r
8108 if (entry) {\r
8109 if (entry.prev !== head) {\r
8110
8111
8112 me.unlinkEntry(entry);\r
8113 me.linkEntry(entry);\r
8114 }\r
8115 } else {\r
8116 map[key] = entry = {\r
8117
8118 id: ++me.seed,\r
8119
8120 key: key,\r
8121 value: me.miss.apply(me, arguments)\r
8122 };\r
8123 me.linkEntry(entry);\r
8124 ++me.count;\r
8125 while (me.count > me.maxSize) {\r
8126 me.unlinkEntry(head.prev, true);\r
8127 --me.count;\r
8128 }\r
8129 }\r
8130 return entry.value;\r
8131 },\r
8132
8133
8134 \r
8135 evict: Ext.emptyFn,\r
8136 \r
8137 linkEntry: function(entry) {\r
8138 var head = this.head,\r
8139 first = head.next;\r
8140 entry.next = first;\r
8141 entry.prev = head;\r
8142 head.next = entry;\r
8143 first.prev = entry;\r
8144 },\r
8145 \r
8146 unlinkEntry: function(entry, evicted) {\r
8147 var next = entry.next,\r
8148 prev = entry.prev;\r
8149 prev.next = next;\r
8150 next.prev = prev;\r
8151 if (evicted) {\r
8152 this.evict(entry.key, entry.value);\r
8153 }\r
8154 }\r
8155 };\r
8156 prototype.destroy = prototype.clear;\r
8157}());\r
8158\r
8159\r
8160(function() {\r
8161
8162
8163
8164
8165
8166 var ExtClass,\r
8167 Base = Ext.Base,\r
8168 baseStaticMembers = Base.$staticMembers,\r
8169 ruleKeySortFn = function(a, b) {\r
8170
8171 return (a.length - b.length) || ((a < b) ? -1 : ((a > b) ? 1 : 0));\r
8172 };\r
8173
8174 function makeCtor(className) {\r
8175 function constructor() {\r
8176
8177
8178 return this.constructor.apply(this, arguments) || null;\r
8179 }\r
8180
8181 if (className) {\r
8182 constructor.name = className;\r
8183 }\r
8184
8185 return constructor;\r
8186 }\r
8187 \r
8188 Ext.Class = ExtClass = function(Class, data, onCreated) {\r
8189 if (typeof Class != 'function') {\r
8190 onCreated = data;\r
8191 data = Class;\r
8192 Class = null;\r
8193 }\r
8194 if (!data) {\r
8195 data = {};\r
8196 }\r
8197 Class = ExtClass.create(Class, data);\r
8198 ExtClass.process(Class, data, onCreated);\r
8199 return Class;\r
8200 };\r
8201 Ext.apply(ExtClass, {\r
8202 makeCtor: makeCtor,\r
8203 \r
8204 onBeforeCreated: function(Class, data, hooks) {\r
8205
8206 Ext.classSystemMonitor && Ext.classSystemMonitor(Class, '>> Ext.Class#onBeforeCreated', arguments);\r
8207
8208 Class.addMembers(data);\r
8209 hooks.onCreated.call(Class, Class);\r
8210
8211 Ext.classSystemMonitor && Ext.classSystemMonitor(Class, '<< Ext.Class#onBeforeCreated', arguments);\r
8212 },\r
8213
8214 \r
8215 create: function(Class, data) {\r
8216 var i = baseStaticMembers.length,\r
8217 name;\r
8218 if (!Class) {\r
8219 Class = makeCtor(
8220 data.$className);\r
8221 }\r
8222
8223 while (i--) {\r
8224 name = baseStaticMembers[i];\r
8225 Class[name] = Base[name];\r
8226 }\r
8227 return Class;\r
8228 },\r
8229 \r
8230 process: function(Class, data, onCreated) {\r
8231 var preprocessorStack = data.preprocessors || ExtClass.defaultPreprocessors,\r
8232 registeredPreprocessors = this.preprocessors,\r
8233 hooks = {\r
8234 onBeforeCreated: this.onBeforeCreated\r
8235 },\r
8236 preprocessors = [],\r
8237 preprocessor, preprocessorsProperties, i, ln, j, subLn, preprocessorProperty;\r
8238 delete data.preprocessors;\r
8239 Class._classHooks = hooks;\r
8240 for (i = 0 , ln = preprocessorStack.length; i < ln; i++) {\r
8241 preprocessor = preprocessorStack[i];\r
8242 if (typeof preprocessor == 'string') {\r
8243 preprocessor = registeredPreprocessors[preprocessor];\r
8244 preprocessorsProperties = preprocessor.properties;\r
8245 if (preprocessorsProperties === true) {\r
8246 preprocessors.push(preprocessor.fn);\r
8247 } else if (preprocessorsProperties) {\r
8248 for (j = 0 , subLn = preprocessorsProperties.length; j < subLn; j++) {\r
8249 preprocessorProperty = preprocessorsProperties[j];\r
8250 if (data.hasOwnProperty(preprocessorProperty)) {\r
8251 preprocessors.push(preprocessor.fn);\r
8252 break;\r
8253 }\r
8254 }\r
8255 }\r
8256 } else {\r
8257 preprocessors.push(preprocessor);\r
8258 }\r
8259 }\r
8260 hooks.onCreated = onCreated ? onCreated : Ext.emptyFn;\r
8261 hooks.preprocessors = preprocessors;\r
8262 this.doProcess(Class, data, hooks);\r
8263 },\r
8264 doProcess: function(Class, data, hooks) {\r
8265 var me = this,\r
8266 preprocessors = hooks.preprocessors,\r
8267 preprocessor = preprocessors.shift(),\r
8268 doProcess = me.doProcess;\r
8269 for (; preprocessor; preprocessor = preprocessors.shift()) {\r
8270
8271 if (preprocessor.call(me, Class, data, hooks, doProcess) === false) {\r
8272 return;\r
8273 }\r
8274 }\r
8275 hooks.onBeforeCreated.apply(me, arguments);\r
8276 },\r
8277 \r
8278 preprocessors: {},\r
8279 \r
8280 registerPreprocessor: function(name, fn, properties, position, relativeTo) {\r
8281 if (!position) {\r
8282 position = 'last';\r
8283 }\r
8284 if (!properties) {\r
8285 properties = [\r
8286 name\r
8287 ];\r
8288 }\r
8289 this.preprocessors[name] = {\r
8290 name: name,\r
8291 properties: properties || false,\r
8292 fn: fn\r
8293 };\r
8294 this.setDefaultPreprocessorPosition(name, position, relativeTo);\r
8295 return this;\r
8296 },\r
8297 \r
8298 getPreprocessor: function(name) {\r
8299 return this.preprocessors[name];\r
8300 },\r
8301 \r
8302 getPreprocessors: function() {\r
8303 return this.preprocessors;\r
8304 },\r
8305 \r
8306 defaultPreprocessors: [],\r
8307 \r
8308 getDefaultPreprocessors: function() {\r
8309 return this.defaultPreprocessors;\r
8310 },\r
8311 \r
8312 setDefaultPreprocessors: function(preprocessors) {\r
8313 this.defaultPreprocessors = Ext.Array.from(preprocessors);\r
8314 return this;\r
8315 },\r
8316 \r
8317 setDefaultPreprocessorPosition: function(name, offset, relativeName) {\r
8318 var defaultPreprocessors = this.defaultPreprocessors,\r
8319 index;\r
8320 if (typeof offset == 'string') {\r
8321 if (offset === 'first') {\r
8322 defaultPreprocessors.unshift(name);\r
8323 return this;\r
8324 } else if (offset === 'last') {\r
8325 defaultPreprocessors.push(name);\r
8326 return this;\r
8327 }\r
8328 offset = (offset === 'after') ? 1 : -1;\r
8329 }\r
8330 index = Ext.Array.indexOf(defaultPreprocessors, relativeName);\r
8331 if (index !== -1) {\r
8332 Ext.Array.splice(defaultPreprocessors, Math.max(0, index + offset), 0, name);\r
8333 }\r
8334 return this;\r
8335 }\r
8336 });\r
8337 \r
8338 ExtClass.registerPreprocessor('extend', function(Class, data, hooks) {\r
8339
8340 Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#extendPreProcessor', arguments);\r
8341
8342 var Base = Ext.Base,\r
8343 basePrototype = Base.prototype,\r
8344 extend = data.extend,\r
8345 Parent, parentPrototype, i;\r
8346 delete data.extend;\r
8347 if (extend && extend !== Object) {\r
8348 Parent = extend;\r
8349 } else {\r
8350 Parent = Base;\r
8351 }\r
8352 parentPrototype = Parent.prototype;\r
8353 if (!Parent.$isClass) {\r
8354 for (i in basePrototype) {\r
8355 if (!parentPrototype[i]) {\r
8356 parentPrototype[i] = basePrototype[i];\r
8357 }\r
8358 }\r
8359 }\r
8360 Class.extend(Parent);\r
8361 Class.triggerExtended.apply(Class, arguments);\r
8362 if (data.onClassExtended) {\r
8363 Class.onExtended(data.onClassExtended, Class);\r
8364 delete data.onClassExtended;\r
8365 }\r
8366 }, true);\r
8367
8368 \r
8369 ExtClass.registerPreprocessor('privates', function(Class, data) {\r
8370
8371 Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#privatePreprocessor', arguments);\r
8372
8373 var privates = data.privates,\r
8374 statics = privates.statics,\r
8375 privacy = privates.privacy || true;\r
8376 delete data.privates;\r
8377 delete privates.statics;\r
8378
8379
8380
8381 Class.addMembers(privates, false, privacy);\r
8382 if (statics) {\r
8383 Class.addMembers(statics, true, privacy);\r
8384 }\r
8385 });\r
8386
8387 \r
8388 ExtClass.registerPreprocessor('statics', function(Class, data) {\r
8389
8390 Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#staticsPreprocessor', arguments);\r
8391
8392 Class.addStatics(data.statics);\r
8393 delete data.statics;\r
8394 });\r
8395
8396
8397 \r
8398 ExtClass.registerPreprocessor('inheritableStatics', function(Class, data) {\r
8399
8400 Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#inheritableStaticsPreprocessor', arguments);\r
8401
8402 Class.addInheritableStatics(data.inheritableStatics);\r
8403 delete data.inheritableStatics;\r
8404 });\r
8405
8406 Ext.createRuleFn = function(code) {\r
8407 return new Function('$c', 'with($c) { return (' + code + '); }');\r
8408 };\r
8409 Ext.expressionCache = new Ext.util.Cache({\r
8410 miss: Ext.createRuleFn\r
8411 });\r
8412 Ext.ruleKeySortFn = ruleKeySortFn;\r
8413 Ext.getPlatformConfigKeys = function(platformConfig) {\r
8414 var ret = [],\r
8415 platform, rule;\r
8416 for (platform in platformConfig) {\r
8417 rule = Ext.expressionCache.get(platform);\r
8418 if (rule(Ext.platformTags)) {\r
8419 ret.push(platform);\r
8420 }\r
8421 }\r
8422 ret.sort(ruleKeySortFn);\r
8423 return ret;\r
8424 };\r
8425
8426 \r
8427 ExtClass.registerPreprocessor('platformConfig', function(Class, data, hooks) {\r
8428 var platformConfigs = data.platformConfig,\r
8429 config = data.config,\r
8430 added, classConfigs, configs, configurator, hoisted, keys, name, value, i, ln;\r
8431 delete data.platformConfig;\r
8432
8433 if (platformConfigs instanceof Array) {\r
8434 throw new Error('platformConfigs must be specified as an object.');\r
8435 }\r
8436
8437 configurator = Class.getConfigurator();\r
8438 classConfigs = configurator.configs;\r
8439
8440 keys = Ext.getPlatformConfigKeys(platformConfigs);\r
8441
8442
8443
8444
8445
8446
8447
8448
8449
8450
8451 for (i = 0 , ln = keys.length; i < ln; ++i) {\r
8452 configs = platformConfigs[keys[i]];\r
8453 hoisted = added = null;\r
8454 for (name in configs) {\r
8455 value = configs[name];\r
8456
8457 if (config && name in config) {\r
8458
8459 (added || (added = {}))[name] = value;\r
8460 (hoisted || (hoisted = {}))[name] = config[name];\r
8461 delete config[name];\r
8462 } else if (name in classConfigs) {\r
8463
8464 (added || (added = {}))[name] = value;\r
8465 } else {\r
8466
8467 data[name] = value;\r
8468 }\r
8469 }\r
8470 if (hoisted) {\r
8471 configurator.add(hoisted);\r
8472 }\r
8473 if (added) {\r
8474 configurator.add(added);\r
8475 }\r
8476 }\r
8477 });\r
8478
8479
8480 \r
8481 ExtClass.registerPreprocessor('config', function(Class, data) {\r
8482
8483 if (data.hasOwnProperty('$configPrefixed')) {\r
8484 Class.prototype.$configPrefixed = data.$configPrefixed;\r
8485 }\r
8486 Class.addConfig(data.config);\r
8487
8488
8489
8490 delete data.config;\r
8491 });\r
8492
8493
8494 \r
8495 ExtClass.registerPreprocessor('cachedConfig', function(Class, data) {\r
8496
8497 if (data.hasOwnProperty('$configPrefixed')) {\r
8498 Class.prototype.$configPrefixed = data.$configPrefixed;\r
8499 }\r
8500 Class.addCachedConfig(data.cachedConfig);\r
8501
8502 delete data.cachedConfig;\r
8503 });\r
8504
8505
8506 \r
8507 ExtClass.registerPreprocessor('mixins', function(Class, data, hooks) {\r
8508
8509 Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#mixinsPreprocessor', arguments);\r
8510
8511 var mixins = data.mixins,\r
8512 onCreated = hooks.onCreated;\r
8513 delete data.mixins;\r
8514 hooks.onCreated = function() {\r
8515
8516 Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#mixinsPreprocessor#beforeCreated', arguments);\r
8517
8518
8519
8520 hooks.onCreated = onCreated;\r
8521 Class.mixin(mixins);\r
8522
8523
8524 return hooks.onCreated.apply(this, arguments);\r
8525 };\r
8526 });\r
8527
8528
8529
8530 Ext.extend = function(Class, Parent, members) {\r
8531
8532 Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#extend-backwards-compatible', arguments);\r
8533
8534 if (arguments.length === 2 && Ext.isObject(Parent)) {\r
8535 members = Parent;\r
8536 Parent = Class;\r
8537 Class = null;\r
8538 }\r
8539 var cls;\r
8540 if (!Parent) {\r
8541 throw new Error("[Ext.extend] Attempting to extend from a class which has not been loaded on the page.");\r
8542 }\r
8543 members.extend = Parent;\r
8544 members.preprocessors = [\r
8545 'extend',\r
8546
8547 'statics',\r
8548
8549
8550 'inheritableStatics',\r
8551
8552
8553 'mixins',\r
8554
8555
8556 'platformConfig',\r
8557
8558
8559 'config'\r
8560 ];\r
8561
8562 if (Class) {\r
8563 cls = new ExtClass(Class, members);\r
8564
8565 cls.prototype.constructor = Class;\r
8566 } else {\r
8567 cls = new ExtClass(members);\r
8568 }\r
8569 cls.prototype.override = function(o) {\r
8570 for (var m in o) {\r
8571 if (o.hasOwnProperty(m)) {\r
8572 this[m] = o[m];\r
8573 }\r
8574 }\r
8575 };\r
8576 return cls;\r
8577 };\r
8578}());\r
8579
8580\r
8581\r
8582
8583\r
8584Ext.Inventory = function() {\r
8585
8586
8587
8588 var me = this;\r
8589 me.names = [];\r
8590 me.paths = {};\r
8591 me.alternateToName = {};\r
8592 me.aliasToName = {};\r
8593 me.nameToAliases = {};\r
8594 me.nameToAlternates = {};\r
8595};\r
8596Ext.Inventory.prototype = {\r
8597 _array1: [\r
8598 0\r
8599 ],\r
8600 prefixes: null,\r
8601 dotRe: /\./g,\r
8602 wildcardRe: /\*/g,\r
8603 addAlias: function(className, alias, update) {\r
8604 return this.addMapping(className, alias, this.aliasToName, this.nameToAliases, update);\r
8605 },\r
8606 addAlternate: function(className, alternate) {\r
8607 return this.addMapping(className, alternate, this.alternateToName, this.nameToAlternates);\r
8608 },\r
8609 addMapping: function(className, alternate, toName, nameTo, update) {\r
8610 var name = className.$className || className,\r
8611 mappings = name,\r
8612 array = this._array1,\r
8613 a, aliases, cls, i, length, nameMapping;\r
8614 if (Ext.isString(name)) {\r
8615 mappings = {};\r
8616 mappings[name] = alternate;\r
8617 }\r
8618 for (cls in mappings) {\r
8619 aliases = mappings[cls];\r
8620 if (Ext.isString(aliases)) {\r
8621 array[0] = aliases;\r
8622 aliases = array;\r
8623 }\r
8624 length = aliases.length;\r
8625 nameMapping = nameTo[cls] || (nameTo[cls] = []);\r
8626 for (i = 0; i < length; ++i) {\r
8627 if (!(a = aliases[i])) {\r
8628 \r
8629 continue;\r
8630 }\r
8631 if (toName[a] !== cls) {\r
8632
8633 if (!update && toName[a]) {\r
8634 Ext.log.warn("Overriding existing mapping: '" + a + "' From '" + toName[a] + "' to '" + cls + "'. Is this intentional?");\r
8635 }\r
8636
8637 toName[a] = cls;\r
8638 nameMapping.push(a);\r
8639 }\r
8640 }\r
8641 }\r
8642 },\r
8643 \r
8644 getAliasesByName: function(name) {\r
8645 return this.nameToAliases[name] || null;\r
8646 },\r
8647 getAlternatesByName: function(name) {\r
8648 return this.nameToAlternates[name] || null;\r
8649 },\r
8650 \r
8651 getNameByAlias: function(alias) {\r
8652 return this.aliasToName[alias] || '';\r
8653 },\r
8654 \r
8655 getNameByAlternate: function(alternate) {\r
8656 return this.alternateToName[alternate] || '';\r
8657 },\r
8658 \r
8659 getNamesByExpression: function(expression, exclude, accumulate) {\r
8660 var me = this,\r
8661 aliasToName = me.aliasToName,\r
8662 alternateToName = me.alternateToName,\r
8663 nameToAliases = me.nameToAliases,\r
8664 nameToAlternates = me.nameToAlternates,\r
8665 map = accumulate ? exclude : {},\r
8666 names = [],\r
8667 expressions = Ext.isString(expression) ? [\r
8668 expression\r
8669 ] : expression,\r
8670 length = expressions.length,\r
8671 wildcardRe = me.wildcardRe,\r
8672 expr, i, list, match, n, name, regex;\r
8673 for (i = 0; i < length; ++i) {\r
8674 if ((expr = expressions[i]).indexOf('*') < 0) {\r
8675
8676 if (!(name = aliasToName[expr])) {\r
8677 if (!(name = alternateToName[expr])) {\r
8678 name = expr;\r
8679 }\r
8680 }\r
8681 if (!(name in map) && !(exclude && (name in exclude))) {\r
8682 map[name] = 1;\r
8683 names.push(name);\r
8684 }\r
8685 } else {\r
8686 regex = new RegExp('^' + expr.replace(wildcardRe, '(.*?)') + '$');\r
8687 for (name in nameToAliases) {\r
8688 if (!(name in map) && !(exclude && (name in exclude))) {\r
8689 if (!(match = regex.test(name))) {\r
8690 n = (list = nameToAliases[name]).length;\r
8691 while (!match && n-- > 0) {\r
8692 match = regex.test(list[n]);\r
8693 }\r
8694 list = nameToAlternates[name];\r
8695 if (list && !match) {\r
8696 n = list.length;\r
8697 while (!match && n-- > 0) {\r
8698 match = regex.test(list[n]);\r
8699 }\r
8700 }\r
8701 }\r
8702 if (match) {\r
8703 map[name] = 1;\r
8704 names.push(name);\r
8705 }\r
8706 }\r
8707 }\r
8708 }\r
8709 }\r
8710 return names;\r
8711 },\r
8712 getPath: function(className) {\r
8713 var me = this,\r
8714 paths = me.paths,\r
8715 ret = '',\r
8716 prefix;\r
8717 if (className in paths) {\r
8718 ret = paths[className];\r
8719 } else {\r
8720 prefix = me.getPrefix(className);\r
8721 if (prefix) {\r
8722 className = className.substring(prefix.length + 1);\r
8723 ret = paths[prefix];\r
8724 if (ret) {\r
8725 ret += '/';\r
8726 }\r
8727 }\r
8728 ret += className.replace(me.dotRe, '/') + '.js';\r
8729 }\r
8730 return ret;\r
8731 },\r
8732 getPrefix: function(className) {\r
8733 if (className in this.paths) {\r
8734 return className;\r
8735 }\r
8736 var prefixes = this.getPrefixes(),\r
8737 i = prefixes.length,\r
8738 length, prefix;\r
8739
8740 while (i-- > 0) {\r
8741 length = (prefix = prefixes[i]).length;\r
8742 if (length < className.length && className.charAt(length) === '.' && prefix === className.substring(0, length)) {\r
8743 return prefix;\r
8744 }\r
8745 }\r
8746 return '';\r
8747 },\r
8748 getPrefixes: function() {\r
8749 var me = this,\r
8750 prefixes = me.prefixes;\r
8751 if (!prefixes) {\r
8752 me.prefixes = prefixes = me.names.slice(0);\r
8753 prefixes.sort(me._compareNames);\r
8754 }\r
8755 return prefixes;\r
8756 },\r
8757 removeName: function(name) {\r
8758 var me = this,\r
8759 aliasToName = me.aliasToName,\r
8760 alternateToName = me.alternateToName,\r
8761 nameToAliases = me.nameToAliases,\r
8762 nameToAlternates = me.nameToAlternates,\r
8763 aliases = nameToAliases[name],\r
8764 alternates = nameToAlternates[name],\r
8765 i, a;\r
8766 delete nameToAliases[name];\r
8767 delete nameToAlternates[name];\r
8768 if (aliases) {\r
8769 for (i = aliases.length; i--; ) {\r
8770
8771
8772
8773 if (name === (a = aliases[i])) {\r
8774 delete aliasToName[a];\r
8775 }\r
8776 }\r
8777 }\r
8778 if (alternates) {\r
8779 for (i = alternates.length; i--; ) {\r
8780
8781 if (name === (a = alternates[i])) {\r
8782 delete alternateToName[a];\r
8783 }\r
8784 }\r
8785 }\r
8786 },\r
8787 resolveName: function(name) {\r
8788 var me = this,\r
8789 trueName;\r
8790
8791
8792 if (!(name in me.nameToAliases)) {\r
8793
8794 if (!(trueName = me.aliasToName[name])) {\r
8795
8796
8797 trueName = me.alternateToName[name];\r
8798 }\r
8799 }\r
8800 return trueName || name;\r
8801 },\r
8802 \r
8803 select: function(receiver, scope) {\r
8804 var me = this,\r
8805 excludes = {},\r
8806 ret = {\r
8807 excludes: excludes,\r
8808 exclude: function() {\r
8809 me.getNamesByExpression(arguments, excludes, true);\r
8810 return this;\r
8811 }\r
8812 },\r
8813 name;\r
8814 for (name in receiver) {\r
8815 ret[name] = me.selectMethod(excludes, receiver[name], scope || receiver);\r
8816 }\r
8817 return ret;\r
8818 },\r
8819 selectMethod: function(excludes, fn, scope) {\r
8820 var me = this;\r
8821 return function(include) {\r
8822 var args = Ext.Array.slice(arguments, 1);\r
8823 args.unshift(me.getNamesByExpression(include, excludes));\r
8824 return fn.apply(scope, args);\r
8825 };\r
8826 },\r
8827 \r
8828 setPath: Ext.Function.flexSetter(function(name, path) {\r
8829 var me = this;\r
8830 me.paths[name] = path;\r
8831 me.names.push(name);\r
8832 me.prefixes = null;\r
8833 return me;\r
8834 }),\r
8835 _compareNames: function(lhs, rhs) {\r
8836 var cmp = lhs.length - rhs.length;\r
8837 if (!cmp) {\r
8838 cmp = (lhs < rhs) ? -1 : 1;\r
8839 }\r
8840 return cmp;\r
8841 }\r
8842};\r
8843\r
8844
8845\r
8846Ext.ClassManager = (function(Class, alias, arraySlice, arrayFrom, global) {\r
8847
8848
8849
8850
8851
8852 var makeCtor = Ext.Class.makeCtor,\r
8853 nameLookupStack = [],\r
8854 namespaceCache = {\r
8855 Ext: {\r
8856 name: 'Ext',\r
8857 value: Ext\r
8858 }\r
8859 },\r
8860
8861 \r
8862 Manager = Ext.apply(new Ext.Inventory(), {\r
8863 \r
8864 classes: {},\r
8865 classState: {},\r
8866 \r
8867 \r
8868 existCache: {},\r
8869 \r
8870 instantiators: [],\r
8871 \r
8872 isCreated: function(className) {\r
8873
8874 if (typeof className !== 'string' || className.length < 1) {\r
8875 throw new Error("[Ext.ClassManager] Invalid classname, must be a string and must not be empty");\r
8876 }\r
8877
8878 if (Manager.classes[className] || Manager.existCache[className]) {\r
8879 return true;\r
8880 }\r
8881 if (!Manager.lookupName(className, false)) {\r
8882 return false;\r
8883 }\r
8884 Manager.triggerCreated(className);\r
8885 return true;\r
8886 },\r
8887 \r
8888 createdListeners: [],\r
8889 \r
8890 nameCreatedListeners: {},\r
8891 \r
8892 existsListeners: [],\r
8893 \r
8894 nameExistsListeners: {},\r
8895 \r
8896 overrideMap: {},\r
8897 \r
8898 triggerCreated: function(className, state) {\r
8899 Manager.existCache[className] = state || 1;\r
8900 Manager.classState[className] += 40;\r
8901 Manager.notify(className, Manager.createdListeners, Manager.nameCreatedListeners);\r
8902 },\r
8903 \r
8904 onCreated: function(fn, scope, className) {\r
8905 Manager.addListener(fn, scope, className, Manager.createdListeners, Manager.nameCreatedListeners);\r
8906 },\r
8907 \r
8908 notify: function(className, listeners, nameListeners) {\r
8909 var alternateNames = Manager.getAlternatesByName(className),\r
8910 names = [\r
8911 className\r
8912 ],\r
8913 i, ln, j, subLn, listener, name;\r
8914 for (i = 0 , ln = listeners.length; i < ln; i++) {\r
8915 listener = listeners[i];\r
8916 listener.fn.call(listener.scope, className);\r
8917 }\r
8918 while (names) {\r
8919 for (i = 0 , ln = names.length; i < ln; i++) {\r
8920 name = names[i];\r
8921 listeners = nameListeners[name];\r
8922 if (listeners) {\r
8923 for (j = 0 , subLn = listeners.length; j < subLn; j++) {\r
8924 listener = listeners[j];\r
8925 listener.fn.call(listener.scope, name);\r
8926 }\r
8927 delete nameListeners[name];\r
8928 }\r
8929 }\r
8930 names = alternateNames;\r
8931
8932 alternateNames = null;\r
8933 }\r
8934 },\r
8935
8936 \r
8937 addListener: function(fn, scope, className, listeners, nameListeners) {\r
8938 if (Ext.isArray(className)) {\r
8939 fn = Ext.Function.createBarrier(className.length, fn, scope);\r
8940 for (i = 0; i < className.length; i++) {\r
8941 this.addListener(fn, null, className[i], listeners, nameListeners);\r
8942 }\r
8943 return;\r
8944 }\r
8945 var i,\r
8946 listener = {\r
8947 fn: fn,\r
8948 scope: scope\r
8949 };\r
8950 if (className) {\r
8951 if (this.isCreated(className)) {\r
8952 fn.call(scope, className);\r
8953 return;\r
8954 }\r
8955 if (!nameListeners[className]) {\r
8956 nameListeners[className] = [];\r
8957 }\r
8958 nameListeners[className].push(listener);\r
8959 } else {\r
8960 listeners.push(listener);\r
8961 }\r
8962 },\r
8963 \r
8964 $namespaceCache: namespaceCache,\r
8965 \r
8966 addRootNamespaces: function(namespaces) {\r
8967 for (var name in namespaces) {\r
8968 namespaceCache[name] = {\r
8969 name: name,\r
8970 value: namespaces[name]\r
8971 };\r
8972 }\r
8973 },\r
8974 \r
8975 clearNamespaceCache: function() {\r
8976 nameLookupStack.length = 0;\r
8977 for (var name in namespaceCache) {\r
8978 if (!namespaceCache[name].value) {\r
8979 delete namespaceCache[name];\r
8980 }\r
8981 }\r
8982 },\r
8983 \r
8984 getNamespaceEntry: function(namespace) {\r
8985 if (typeof namespace !== 'string') {\r
8986 return namespace;\r
8987 }\r
8988
8989 var entry = namespaceCache[namespace],\r
8990 i;\r
8991 if (!entry) {\r
8992 i = namespace.lastIndexOf('.');\r
8993 if (i < 0) {\r
8994 entry = {\r
8995 name: namespace\r
8996 };\r
8997 } else {\r
8998 entry = {\r
8999 name: namespace.substring(i + 1),\r
9000 parent: Manager.getNamespaceEntry(namespace.substring(0, i))\r
9001 };\r
9002 }\r
9003 namespaceCache[namespace] = entry;\r
9004 }\r
9005 return entry;\r
9006 },\r
9007 \r
9008 lookupName: function(namespace, autoCreate) {\r
9009 var entry = Manager.getNamespaceEntry(namespace),\r
9010 scope = Ext.global,\r
9011 i = 0,\r
9012 e, parent;\r
9013
9014 for (e = entry; e; e = e.parent) {\r
9015
9016
9017
9018 nameLookupStack[i++] = e;\r
9019 }\r
9020 while (scope && i-- > 0) {\r
9021
9022 e = nameLookupStack[i];\r
9023 parent = scope;\r
9024 scope = e.value || scope[e.name];\r
9025 if (!scope && autoCreate) {\r
9026 parent[e.name] = scope = {};\r
9027 }\r
9028 }\r
9029 return scope;\r
9030 },\r
9031 \r
9032 setNamespace: function(namespace, value) {\r
9033 var entry = Manager.getNamespaceEntry(namespace),\r
9034 scope = Ext.global;\r
9035 if (entry.parent) {\r
9036 scope = Manager.lookupName(entry.parent, true);\r
9037 }\r
9038 scope[entry.name] = value;\r
9039 return value;\r
9040 },\r
9041 \r
9042 setXType: function(cls, xtype) {\r
9043 var className = cls.$className,\r
9044 C = className ? cls : Manager.get(className = cls),\r
9045 proto = C.prototype,\r
9046 xtypes = proto.xtypes,\r
9047 xtypesChain = proto.xtypesChain,\r
9048 xtypesMap = proto.xtypesMap;\r
9049 if (!proto.hasOwnProperty('xtypes')) {\r
9050 proto.xtypes = xtypes = [];\r
9051 proto.xtypesChain = xtypesChain = xtypesChain ? xtypesChain.slice(0) : [];\r
9052 proto.xtypesMap = xtypesMap = Ext.apply({}, xtypesMap);\r
9053 }\r
9054 Manager.addAlias(className, 'widget.' + xtype, true);\r
9055 xtypes.push(xtype);\r
9056 xtypesChain.push(xtype);\r
9057 xtypesMap[xtype] = true;\r
9058 },\r
9059
9060 \r
9061 set: function(name, value) {\r
9062 var targetName = Manager.getName(value);\r
9063 Manager.classes[name] = Manager.setNamespace(name, value);\r
9064 if (targetName && targetName !== name) {\r
9065 Manager.addAlternate(targetName, name);\r
9066 }\r
9067 return Manager;\r
9068 },\r
9069 \r
9070 get: function(name) {\r
9071 return Manager.classes[name] || Manager.lookupName(name, false);\r
9072 },\r
9073 \r
9074 addNameAliasMappings: function(aliases) {\r
9075 Manager.addAlias(aliases);\r
9076 },\r
9077 \r
9078 addNameAlternateMappings: function(alternates) {\r
9079 Manager.addAlternate(alternates);\r
9080 },\r
9081 \r
9082 getByAlias: function(alias) {\r
9083 return Manager.get(Manager.getNameByAlias(alias));\r
9084 },\r
9085 \r
9086 getByConfig: function(config, aliasPrefix) {\r
9087 var xclass = config.xclass,\r
9088 name;\r
9089 if (xclass) {\r
9090 name = xclass;\r
9091 } else {\r
9092 name = config.xtype;\r
9093 if (name) {\r
9094 aliasPrefix = 'widget.';\r
9095 } else {\r
9096 name = config.type;\r
9097 }\r
9098 name = Manager.getNameByAlias(aliasPrefix + name);\r
9099 }\r
9100 return Manager.get(name);\r
9101 },\r
9102 \r
9103 getName: function(object) {\r
9104 return object && object.$className || '';\r
9105 },\r
9106 \r
9107 getClass: function(object) {\r
9108 return object && object.self || null;\r
9109 },\r
9110 \r
9111 create: function(className, data, createdFn) {\r
9112
9113 if (className != null && typeof className !== 'string') {\r
9114 throw new Error("[Ext.define] Invalid class name '" + className + "' specified, must be a non-empty string");\r
9115 }\r
9116
9117 var ctor = makeCtor(className);\r
9118 if (typeof data === 'function') {\r
9119 data = data(ctor);\r
9120 }\r
9121
9122 if (className) {\r
9123 if (Manager.classes[className]) {\r
9124 Ext.log.warn("[Ext.define] Duplicate class name '" + className + "' specified, must be a non-empty string");\r
9125 }\r
9126 ctor.name = className;\r
9127 }\r
9128
9129 data.$className = className;\r
9130 return new Class(ctor, data, function() {\r
9131 var postprocessorStack = data.postprocessors || Manager.defaultPostprocessors,\r
9132 registeredPostprocessors = Manager.postprocessors,\r
9133 postprocessors = [],\r
9134 postprocessor, i, ln, j, subLn, postprocessorProperties, postprocessorProperty;\r
9135 delete data.postprocessors;\r
9136 for (i = 0 , ln = postprocessorStack.length; i < ln; i++) {\r
9137 postprocessor = postprocessorStack[i];\r
9138 if (typeof postprocessor === 'string') {\r
9139 postprocessor = registeredPostprocessors[postprocessor];\r
9140 postprocessorProperties = postprocessor.properties;\r
9141 if (postprocessorProperties === true) {\r
9142 postprocessors.push(postprocessor.fn);\r
9143 } else if (postprocessorProperties) {\r
9144 for (j = 0 , subLn = postprocessorProperties.length; j < subLn; j++) {\r
9145 postprocessorProperty = postprocessorProperties[j];\r
9146 if (data.hasOwnProperty(postprocessorProperty)) {\r
9147 postprocessors.push(postprocessor.fn);\r
9148 break;\r
9149 }\r
9150 }\r
9151 }\r
9152 } else {\r
9153 postprocessors.push(postprocessor);\r
9154 }\r
9155 }\r
9156 data.postprocessors = postprocessors;\r
9157 data.createdFn = createdFn;\r
9158 Manager.processCreate(className, this, data);\r
9159 });\r
9160 },\r
9161 processCreate: function(className, cls, clsData) {\r
9162 var me = this,\r
9163 postprocessor = clsData.postprocessors.shift(),\r
9164 createdFn = clsData.createdFn;\r
9165 if (!postprocessor) {\r
9166
9167 Ext.classSystemMonitor && Ext.classSystemMonitor(className, 'Ext.ClassManager#classCreated', arguments);\r
9168
9169 if (className) {\r
9170 me.set(className, cls);\r
9171 }\r
9172 delete cls._classHooks;\r
9173 if (createdFn) {\r
9174 createdFn.call(cls, cls);\r
9175 }\r
9176 if (className) {\r
9177 me.triggerCreated(className);\r
9178 }\r
9179 return;\r
9180 }\r
9181 if (postprocessor.call(me, className, cls, clsData, me.processCreate) !== false) {\r
9182 me.processCreate(className, cls, clsData);\r
9183 }\r
9184 },\r
9185 createOverride: function(className, data, createdFn) {\r
9186 var me = this,\r
9187 overriddenClassName = data.override,\r
9188 requires = data.requires,\r
9189 uses = data.uses,\r
9190 mixins = data.mixins,\r
9191 mixinsIsArray,\r
9192 compat = 1,\r
9193
9194 depedenciesLoaded,\r
9195 classReady = function() {\r
9196 var cls, dependencies, i, key, temp;\r
9197 if (!depedenciesLoaded) {\r
9198 dependencies = requires ? requires.slice(0) : [];\r
9199 if (mixins) {\r
9200 if (!(mixinsIsArray = mixins instanceof Array)) {\r
9201 for (key in mixins) {\r
9202 if (Ext.isString(cls = mixins[key])) {\r
9203 dependencies.push(cls);\r
9204 }\r
9205 }\r
9206 } else {\r
9207 for (i = 0 , temp = mixins.length; i < temp; ++i) {\r
9208 if (Ext.isString(cls = mixins[i])) {\r
9209 dependencies.push(cls);\r
9210 }\r
9211 }\r
9212 }\r
9213 }\r
9214 depedenciesLoaded = true;\r
9215 if (dependencies.length) {\r
9216
9217
9218
9219 Ext.require(dependencies, classReady);\r
9220 return;\r
9221 }\r
9222 }\r
9223
9224
9225
9226
9227 if (mixinsIsArray) {\r
9228 for (i = 0 , temp = mixins.length; i < temp; ++i) {\r
9229 if (Ext.isString(cls = mixins[i])) {\r
9230 mixins[i] = Ext.ClassManager.get(cls);\r
9231 }\r
9232 }\r
9233 } else if (mixins) {\r
9234 for (key in mixins) {\r
9235 if (Ext.isString(cls = mixins[key])) {\r
9236 mixins[key] = Ext.ClassManager.get(cls);\r
9237 }\r
9238 }\r
9239 }\r
9240
9241
9242 cls = me.get(overriddenClassName);\r
9243
9244 delete data.override;\r
9245 delete data.compatibility;\r
9246 delete data.requires;\r
9247 delete data.uses;\r
9248 Ext.override(cls, data);\r
9249
9250
9251
9252 Ext.Loader.history.push(className);\r
9253 if (uses) {\r
9254
9255
9256 Ext['Loader'].addUsedClasses(uses);\r
9257 }\r
9258
9259 if (createdFn) {\r
9260 createdFn.call(cls, cls);\r
9261 }\r
9262 };\r
9263
9264 Manager.overrideMap[className] = true;\r
9265
9266
9267
9268 if ('compatibility' in data && Ext.isString(compat = data.compatibility)) {\r
9269 compat = Ext.checkVersion(compat);\r
9270 }\r
9271 if (compat) {\r
9272
9273 me.onCreated(classReady, me, overriddenClassName);\r
9274 }\r
9275 me.triggerCreated(className, 2);\r
9276 return me;\r
9277 },\r
9278 \r
9279 instantiateByAlias: function() {\r
9280 var alias = arguments[0],\r
9281 args = arraySlice.call(arguments),\r
9282 className = this.getNameByAlias(alias);\r
9283
9284 if (!className) {\r
9285 throw new Error("[Ext.createByAlias] Unrecognized alias: " + alias);\r
9286 }\r
9287
9288 args[0] = className;\r
9289 return Ext.create.apply(Ext, args);\r
9290 },\r
9291 \r
9292 dynInstantiate: function(name, args) {\r
9293 args = arrayFrom(args, true);\r
9294 args.unshift(name);\r
9295 return Ext.create.apply(Ext, args);\r
9296 },\r
9297 \r
9298 getInstantiator: function(length) {\r
9299 var instantiators = this.instantiators,\r
9300 instantiator, i, args;\r
9301 instantiator = instantiators[length];\r
9302 if (!instantiator) {\r
9303 i = length;\r
9304 args = [];\r
9305 for (i = 0; i < length; i++) {\r
9306 args.push('a[' + i + ']');\r
9307 }\r
9308 instantiator = instantiators[length] = new Function('c', 'a', 'return new c(' + args.join(',') + ')');\r
9309
9310 instantiator.name = "Ext.create" + length;\r
9311 }\r
9312
9313 return instantiator;\r
9314 },\r
9315 \r
9316 postprocessors: {},\r
9317 \r
9318 defaultPostprocessors: [],\r
9319 \r
9320 registerPostprocessor: function(name, fn, properties, position, relativeTo) {\r
9321 if (!position) {\r
9322 position = 'last';\r
9323 }\r
9324 if (!properties) {\r
9325 properties = [\r
9326 name\r
9327 ];\r
9328 }\r
9329 this.postprocessors[name] = {\r
9330 name: name,\r
9331 properties: properties || false,\r
9332 fn: fn\r
9333 };\r
9334 this.setDefaultPostprocessorPosition(name, position, relativeTo);\r
9335 return this;\r
9336 },\r
9337 \r
9338 setDefaultPostprocessors: function(postprocessors) {\r
9339 this.defaultPostprocessors = arrayFrom(postprocessors);\r
9340 return this;\r
9341 },\r
9342 \r
9343 setDefaultPostprocessorPosition: function(name, offset, relativeName) {\r
9344 var defaultPostprocessors = this.defaultPostprocessors,\r
9345 index;\r
9346 if (typeof offset === 'string') {\r
9347 if (offset === 'first') {\r
9348 defaultPostprocessors.unshift(name);\r
9349 return this;\r
9350 } else if (offset === 'last') {\r
9351 defaultPostprocessors.push(name);\r
9352 return this;\r
9353 }\r
9354 offset = (offset === 'after') ? 1 : -1;\r
9355 }\r
9356 index = Ext.Array.indexOf(defaultPostprocessors, relativeName);\r
9357 if (index !== -1) {\r
9358 Ext.Array.splice(defaultPostprocessors, Math.max(0, index + offset), 0, name);\r
9359 }\r
9360 return this;\r
9361 }\r
9362 });\r
9363 \r
9364 \r
9365
9366 \r
9367 Manager.registerPostprocessor('alias', function(name, cls, data) {\r
9368
9369 Ext.classSystemMonitor && Ext.classSystemMonitor(name, 'Ext.ClassManager#aliasPostProcessor', arguments);\r
9370
9371 var aliases = Ext.Array.from(data.alias),\r
9372 i, ln;\r
9373 for (i = 0 , ln = aliases.length; i < ln; i++) {\r
9374 alias = aliases[i];\r
9375 this.addAlias(cls, alias);\r
9376 }\r
9377 }, [\r
9378 'xtype',\r
9379 'alias'\r
9380 ]);\r
9381
9382
9383 \r
9384 Manager.registerPostprocessor('singleton', function(name, cls, data, fn) {\r
9385
9386 Ext.classSystemMonitor && Ext.classSystemMonitor(name, 'Ext.ClassManager#singletonPostProcessor', arguments);\r
9387
9388 if (data.singleton) {\r
9389 fn.call(this, name, new cls(), data);\r
9390 } else {\r
9391 return true;\r
9392 }\r
9393 return false;\r
9394 });\r
9395
9396
9397 \r
9398 Manager.registerPostprocessor('alternateClassName', function(name, cls, data) {\r
9399
9400 Ext.classSystemMonitor && Ext.classSystemMonitor(name, 'Ext.ClassManager#alternateClassNamePostprocessor', arguments);\r
9401
9402 var alternates = data.alternateClassName,\r
9403 i, ln, alternate;\r
9404 if (!(alternates instanceof Array)) {\r
9405 alternates = [\r
9406 alternates\r
9407 ];\r
9408 }\r
9409 for (i = 0 , ln = alternates.length; i < ln; i++) {\r
9410 alternate = alternates[i];\r
9411
9412 if (typeof alternate !== 'string') {\r
9413 throw new Error("[Ext.define] Invalid alternate of: '" + alternate + "' for class: '" + name + "'; must be a valid string");\r
9414 }\r
9415
9416 this.set(alternate, cls);\r
9417 }\r
9418 });\r
9419
9420 \r
9421 Manager.registerPostprocessor('debugHooks', function(name, Class, data) {\r
9422
9423 Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#debugHooks', arguments);\r
9424 if (Ext.isDebugEnabled(Class.$className, data.debugHooks.$enabled)) {\r
9425 delete data.debugHooks.$enabled;\r
9426 Ext.override(Class, data.debugHooks);\r
9427 }\r
9428
9429
9430 var target = Class.isInstance ? Class.self : Class;\r
9431 delete target.prototype.debugHooks;\r
9432 });\r
9433 \r
9434 Manager.registerPostprocessor('deprecated', function(name, Class, data) {\r
9435
9436 Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#deprecated', arguments);\r
9437
9438
9439 var target = Class.isInstance ? Class.self : Class;\r
9440 target.addDeprecations(data.deprecated);\r
9441 delete target.prototype.deprecated;\r
9442 });\r
9443 Ext.apply(Ext, {\r
9444 \r
9445 create: function() {\r
9446 var name = arguments[0],\r
9447 nameType = typeof name,\r
9448 args = arraySlice.call(arguments, 1),\r
9449 cls;\r
9450 if (nameType === 'function') {\r
9451 cls = name;\r
9452 } else {\r
9453 if (nameType !== 'string' && args.length === 0) {\r
9454 args = [\r
9455 name\r
9456 ];\r
9457 if (!(name = name.xclass)) {\r
9458 name = args[0].xtype;\r
9459 if (name) {\r
9460 name = 'widget.' + name;\r
9461 }\r
9462 }\r
9463 }\r
9464
9465 if (typeof name !== 'string' || name.length < 1) {\r
9466 throw new Error("[Ext.create] Invalid class name or alias '" + name + "' specified, must be a non-empty string");\r
9467 }\r
9468
9469 name = Manager.resolveName(name);\r
9470 cls = Manager.get(name);\r
9471 }\r
9472
9473 if (!cls) {\r
9474
9475 Ext.log.warn("[Ext.Loader] Synchronously loading '" + name + "'; consider adding " + "Ext.require('" + name + "') above Ext.onReady");\r
9476
9477 Ext.syncRequire(name);\r
9478 cls = Manager.get(name);\r
9479 }\r
9480
9481 if (!cls) {\r
9482 throw new Error("[Ext.create] Unrecognized class name / alias: " + name);\r
9483 }\r
9484 if (typeof cls !== 'function') {\r
9485 throw new Error("[Ext.create] Singleton '" + name + "' cannot be instantiated.");\r
9486 }\r
9487
9488 return Manager.getInstantiator(args.length)(cls, args);\r
9489 },\r
9490 \r
9491 widget: function(name, config) {\r
9492
9493
9494
9495
9496
9497
9498
9499 var xtype = name,\r
9500 alias, className, T;\r
9501 if (typeof xtype !== 'string') {\r
9502
9503
9504 config = name;\r
9505
9506 xtype = config.xtype;\r
9507 className = config.xclass;\r
9508 } else {\r
9509 config = config || {};\r
9510 }\r
9511 if (config.isComponent) {\r
9512 return config;\r
9513 }\r
9514 if (!className) {\r
9515 alias = 'widget.' + xtype;\r
9516 className = Manager.getNameByAlias(alias);\r
9517 }\r
9518
9519 if (className) {\r
9520 T = Manager.get(className);\r
9521 }\r
9522 if (!T) {\r
9523 return Ext.create(className || alias, config);\r
9524 }\r
9525 return new T(config);\r
9526 },\r
9527 \r
9528 createByAlias: alias(Manager, 'instantiateByAlias'),\r
9529 \r
9530 define: function(className, data, createdFn) {\r
9531
9532 Ext.classSystemMonitor && Ext.classSystemMonitor(className, 'ClassManager#define', arguments);\r
9533
9534 if (data.override) {\r
9535 Manager.classState[className] = 20;\r
9536 return Manager.createOverride.apply(Manager, arguments);\r
9537 }\r
9538 Manager.classState[className] = 10;\r
9539 return Manager.create.apply(Manager, arguments);\r
9540 },\r
9541 \r
9542 undefine: function(className) {\r
9543
9544 Ext.classSystemMonitor && Ext.classSystemMonitor(className, 'Ext.ClassManager#undefine', arguments);\r
9545
9546 var classes = Manager.classes;\r
9547 delete classes[className];\r
9548 delete Manager.existCache[className];\r
9549 delete Manager.classState[className];\r
9550 Manager.removeName(className);\r
9551 var entry = Manager.getNamespaceEntry(className),\r
9552 scope = entry.parent ? Manager.lookupName(entry.parent, false) : Ext.global;\r
9553 if (scope) {\r
9554
9555 try {\r
9556 delete scope[entry.name];\r
9557 } catch (e) {\r
9558 scope[entry.name] = undefined;\r
9559 }\r
9560 }\r
9561 },\r
9562 \r
9563 getClassName: alias(Manager, 'getName'),\r
9564 \r
9565 getDisplayName: function(object) {\r
9566 if (object) {\r
9567 if (object.displayName) {\r
9568 return object.displayName;\r
9569 }\r
9570 if (object.$name && object.$class) {\r
9571 return Ext.getClassName(object.$class) + '#' + object.$name;\r
9572 }\r
9573 if (object.$className) {\r
9574 return object.$className;\r
9575 }\r
9576 }\r
9577 return 'Anonymous';\r
9578 },\r
9579 \r
9580 getClass: alias(Manager, 'getClass'),\r
9581 \r
9582 namespace: function() {\r
9583 var root = global,\r
9584 i;\r
9585 for (i = arguments.length; i-- > 0; ) {\r
9586 root = Manager.lookupName(arguments[i], true);\r
9587 }\r
9588 return root;\r
9589 }\r
9590 });\r
9591 \r
9592 Ext.addRootNamespaces = Manager.addRootNamespaces;\r
9593 \r
9594 Ext.createWidget = Ext.widget;\r
9595 \r
9596 Ext.ns = Ext.namespace;\r
9597 Class.registerPreprocessor('className', function(cls, data) {\r
9598 if ('$className' in data) {\r
9599 cls.$className = data.$className;\r
9600
9601 cls.displayName = cls.$className;\r
9602 }\r
9603
9604
9605 Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.ClassManager#classNamePreprocessor', arguments);\r
9606 },
9607 true, 'first');\r
9608 Class.registerPreprocessor('alias', function(cls, data) {\r
9609
9610 Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.ClassManager#aliasPreprocessor', arguments);\r
9611
9612 var prototype = cls.prototype,\r
9613 xtypes = arrayFrom(data.xtype),\r
9614 aliases = arrayFrom(data.alias),\r
9615 widgetPrefix = 'widget.',\r
9616 widgetPrefixLength = widgetPrefix.length,\r
9617 xtypesChain = Array.prototype.slice.call(prototype.xtypesChain || []),\r
9618 xtypesMap = Ext.merge({}, prototype.xtypesMap || {}),\r
9619 i, ln, alias, xtype;\r
9620 for (i = 0 , ln = aliases.length; i < ln; i++) {\r
9621 alias = aliases[i];\r
9622
9623 if (typeof alias !== 'string' || alias.length < 1) {\r
9624 throw new Error("[Ext.define] Invalid alias of: '" + alias + "' for class: '" + name + "'; must be a valid string");\r
9625 }\r
9626
9627 if (alias.substring(0, widgetPrefixLength) === widgetPrefix) {\r
9628 xtype = alias.substring(widgetPrefixLength);\r
9629 Ext.Array.include(xtypes, xtype);\r
9630 }\r
9631 }\r
9632 cls.xtype = data.xtype = xtypes[0];\r
9633 data.xtypes = xtypes;\r
9634 for (i = 0 , ln = xtypes.length; i < ln; i++) {\r
9635 xtype = xtypes[i];\r
9636 if (!xtypesMap[xtype]) {\r
9637 xtypesMap[xtype] = true;\r
9638 xtypesChain.push(xtype);\r
9639 }\r
9640 }\r
9641 data.xtypesChain = xtypesChain;\r
9642 data.xtypesMap = xtypesMap;\r
9643 Ext.Function.interceptAfter(data, 'onClassCreated', function() {\r
9644
9645 Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.ClassManager#aliasPreprocessor#afterClassCreated', arguments);\r
9646
9647 var mixins = prototype.mixins,\r
9648 key, mixin;\r
9649 for (key in mixins) {\r
9650 if (mixins.hasOwnProperty(key)) {\r
9651 mixin = mixins[key];\r
9652 xtypes = mixin.xtypes;\r
9653 if (xtypes) {\r
9654 for (i = 0 , ln = xtypes.length; i < ln; i++) {\r
9655 xtype = xtypes[i];\r
9656 if (!xtypesMap[xtype]) {\r
9657 xtypesMap[xtype] = true;\r
9658 xtypesChain.push(xtype);\r
9659 }\r
9660 }\r
9661 }\r
9662 }\r
9663 }\r
9664 });\r
9665 for (i = 0 , ln = xtypes.length; i < ln; i++) {\r
9666 xtype = xtypes[i];\r
9667
9668 if (typeof xtype !== 'string' || xtype.length < 1) {\r
9669 throw new Error("[Ext.define] Invalid xtype of: '" + xtype + "' for class: '" + name + "'; must be a valid non-empty string");\r
9670 }\r
9671
9672 Ext.Array.include(aliases, widgetPrefix + xtype);\r
9673 }\r
9674 data.alias = aliases;\r
9675 }, [\r
9676 'xtype',\r
9677 'alias'\r
9678 ]);\r
9679
9680 if (Ext.manifest) {\r
9681 var manifest = Ext.manifest,\r
9682 classes = manifest.classes,\r
9683 paths = manifest.paths,\r
9684 aliases = {},\r
9685 alternates = {},\r
9686 className, obj, name, path, baseUrl;\r
9687 if (paths) {\r
9688
9689
9690
9691 if (manifest.bootRelative) {\r
9692 baseUrl = Ext.Boot.baseUrl;\r
9693 for (path in paths) {\r
9694 if (paths.hasOwnProperty(path)) {\r
9695 paths[path] = baseUrl + paths[path];\r
9696 }\r
9697 }\r
9698 }\r
9699 Manager.setPath(paths);\r
9700 }\r
9701 if (classes) {\r
9702 for (className in classes) {\r
9703 alternates[className] = [];\r
9704 aliases[className] = [];\r
9705 obj = classes[className];\r
9706 if (obj.alias) {\r
9707 aliases[className] = obj.alias;\r
9708 }\r
9709 if (obj.alternates) {\r
9710 alternates[className] = obj.alternates;\r
9711 }\r
9712 }\r
9713 }\r
9714 Manager.addAlias(aliases);\r
9715 Manager.addAlternate(alternates);\r
9716 }\r
9717 return Manager;\r
9718}(Ext.Class, Ext.Function.alias, Array.prototype.slice, Ext.Array.from, Ext.global));\r
9719\r
9720\r
9721(Ext.env || (Ext.env = {})).Browser = function(userAgent, publish) {\r
9722
9723
9724
9725
9726 var me = this,\r
9727 browserPrefixes = Ext.Boot.browserPrefixes,\r
9728 browserNames = Ext.Boot.browserNames,\r
9729 enginePrefixes = me.enginePrefixes,\r
9730 engineNames = me.engineNames,\r
9731 browserMatch = userAgent.match(new RegExp('((?:' + Ext.Object.getValues(browserPrefixes).join(')|(?:') + '))([\\w\\._]+)')),\r
9732 engineMatch = userAgent.match(new RegExp('((?:' + Ext.Object.getValues(enginePrefixes).join(')|(?:') + '))([\\w\\._]+)')),\r
9733 browserName = browserNames.other,\r
9734 engineName = engineNames.other,\r
9735 browserVersion = '',\r
9736 engineVersion = '',\r
9737 majorVer = '',\r
9738 isWebView = false,\r
9739 i, prefix, mode, name, maxIEVersion;\r
9740 \r
9741 me.userAgent = userAgent;\r
9742
9743
9744 if (/Edge\//.test(userAgent)) {\r
9745 browserMatch = userAgent.match(/(Edge\/)([\w.]+)/);\r
9746 }\r
9747 if (browserMatch) {\r
9748 browserName = browserNames[Ext.Object.getKey(browserPrefixes, browserMatch[1])];\r
9749
9750 if (browserName === 'Safari' && /^Opera/.test(userAgent)) {\r
9751
9752 browserName = 'Opera';\r
9753 }\r
9754
9755 browserVersion = new Ext.Version(browserMatch[2]);\r
9756 }\r
9757 if (engineMatch) {\r
9758 engineName = engineNames[Ext.Object.getKey(enginePrefixes, engineMatch[1])];\r
9759 engineVersion = new Ext.Version(engineMatch[2]);\r
9760 }\r
9761 if (engineName === 'Trident' && browserName !== 'IE') {\r
9762 browserName = 'IE';\r
9763 var version = userAgent.match(/.*rv:(\d+.\d+)/);\r
9764 if (version && version.length) {\r
9765 version = version[1];\r
9766 browserVersion = new Ext.Version(version);\r
9767 }\r
9768 }\r
9769 if (browserName && browserVersion) {\r
9770 Ext.setVersion(browserName, browserVersion);\r
9771 }\r
9772 \r
9773 \r
9774 \r
9775 \r
9776 \r
9777 \r
9778 \r
9779 \r
9780 \r
9781 \r
9782 \r
9783 \r
9784 \r
9785 \r
9786 \r
9787 \r
9788 \r
9789 \r
9790 \r
9791 \r
9792 \r
9793 \r
9794 \r
9795 \r
9796 \r
9797 \r
9798 \r
9799
9800
9801 if (userAgent.match(/FB/) && browserName === "Other") {\r
9802 browserName = browserNames.safari;\r
9803 engineName = engineNames.webkit;\r
9804 }\r
9805 if (userAgent.match(/Android.*Chrome/g)) {\r
9806 browserName = 'ChromeMobile';\r
9807 }\r
9808 if (userAgent.match(/OPR/)) {\r
9809 browserName = 'Opera';\r
9810 browserMatch = userAgent.match(/OPR\/(\d+.\d+)/);\r
9811 browserVersion = new Ext.Version(browserMatch[1]);\r
9812 }\r
9813 Ext.apply(this, {\r
9814 engineName: engineName,\r
9815 engineVersion: engineVersion,\r
9816 name: browserName,\r
9817 version: browserVersion\r
9818 });\r
9819 this.setFlag(browserName, true, publish);\r
9820
9821 if (browserVersion) {\r
9822 majorVer = browserVersion.getMajor() || '';\r
9823
9824 if (me.is.IE) {\r
9825 majorVer = parseInt(majorVer, 10);\r
9826 mode = document.documentMode;\r
9827
9828
9829
9830
9831
9832 if (mode === 7 || (majorVer === 7 && mode !== 8 && mode !== 9 && mode !== 10)) {\r
9833 majorVer = 7;\r
9834 } else if (mode === 8 || (majorVer === 8 && mode !== 8 && mode !== 9 && mode !== 10)) {\r
9835 majorVer = 8;\r
9836 } else if (mode === 9 || (majorVer === 9 && mode !== 7 && mode !== 8 && mode !== 10)) {\r
9837 majorVer = 9;\r
9838 } else if (mode === 10 || (majorVer === 10 && mode !== 7 && mode !== 8 && mode !== 9)) {\r
9839 majorVer = 10;\r
9840 } else if (mode === 11 || (majorVer === 11 && mode !== 7 && mode !== 8 && mode !== 9 && mode !== 10)) {\r
9841 majorVer = 11;\r
9842 }\r
9843 maxIEVersion = Math.max(majorVer, Ext.Boot.maxIEVersion);\r
9844 for (i = 7; i <= maxIEVersion; ++i) {\r
9845 prefix = 'isIE' + i;\r
9846 if (majorVer <= i) {\r
9847 Ext[prefix + 'm'] = true;\r
9848 }\r
9849 if (majorVer === i) {\r
9850 Ext[prefix] = true;\r
9851 }\r
9852 if (majorVer >= i) {\r
9853 Ext[prefix + 'p'] = true;\r
9854 }\r
9855 }\r
9856 }\r
9857 if (me.is.Opera && parseInt(majorVer, 10) <= 12) {\r
9858 Ext.isOpera12m = true;\r
9859 }\r
9860
9861 Ext.chromeVersion = Ext.isChrome ? majorVer : 0;\r
9862 Ext.firefoxVersion = Ext.isFirefox ? majorVer : 0;\r
9863 Ext.ieVersion = Ext.isIE ? majorVer : 0;\r
9864 Ext.operaVersion = Ext.isOpera ? majorVer : 0;\r
9865 Ext.safariVersion = Ext.isSafari ? majorVer : 0;\r
9866 Ext.webKitVersion = Ext.isWebKit ? majorVer : 0;\r
9867 this.setFlag(browserName + majorVer, true, publish);\r
9868
9869 this.setFlag(browserName + browserVersion.getShortVersion());\r
9870 }\r
9871 for (i in browserNames) {\r
9872 if (browserNames.hasOwnProperty(i)) {\r
9873 name = browserNames[i];\r
9874 this.setFlag(name, browserName === name);\r
9875 }\r
9876 }\r
9877 this.setFlag(name);\r
9878 if (engineVersion) {\r
9879 this.setFlag(engineName + (engineVersion.getMajor() || ''));\r
9880 this.setFlag(engineName + engineVersion.getShortVersion());\r
9881 }\r
9882 for (i in engineNames) {\r
9883 if (engineNames.hasOwnProperty(i)) {\r
9884 name = engineNames[i];\r
9885 this.setFlag(name, engineName === name, publish);\r
9886 }\r
9887 }\r
9888 this.setFlag('Standalone', !!navigator.standalone);\r
9889 this.setFlag('Ripple', !!document.getElementById("tinyhippos-injected") && !Ext.isEmpty(window.top.ripple));\r
9890 this.setFlag('WebWorks', !!window.blackberry);\r
9891 if (window.PhoneGap !== undefined || window.Cordova !== undefined || window.cordova !== undefined) {\r
9892 isWebView = true;\r
9893 this.setFlag('PhoneGap');\r
9894 this.setFlag('Cordova');\r
9895 }\r
9896
9897 if (/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)(?!.*FBAN)/i.test(userAgent)) {\r
9898 isWebView = true;\r
9899 }\r
9900
9901 this.setFlag('WebView', isWebView);\r
9902 \r
9903 this.isStrict = Ext.isStrict = document.compatMode === "CSS1Compat";\r
9904 \r
9905 this.isSecure = Ext.isSecure;\r
9906
9907 this.identity = browserName + majorVer + (this.isStrict ? 'Strict' : 'Quirks');\r
9908};\r
9909Ext.env.Browser.prototype = {\r
9910 constructor: Ext.env.Browser,\r
9911 engineNames: {\r
9912 webkit: 'WebKit',\r
9913 gecko: 'Gecko',\r
9914 presto: 'Presto',\r
9915 trident: 'Trident',\r
9916 other: 'Other'\r
9917 },\r
9918 enginePrefixes: {\r
9919 webkit: 'AppleWebKit/',\r
9920 gecko: 'Gecko/',\r
9921 presto: 'Presto/',\r
9922 trident: 'Trident/'\r
9923 },\r
9924 styleDashPrefixes: {\r
9925 WebKit: '-webkit-',\r
9926 Gecko: '-moz-',\r
9927 Trident: '-ms-',\r
9928 Presto: '-o-',\r
9929 Other: ''\r
9930 },\r
9931 stylePrefixes: {\r
9932 WebKit: 'Webkit',\r
9933 Gecko: 'Moz',\r
9934 Trident: 'ms',\r
9935 Presto: 'O',\r
9936 Other: ''\r
9937 },\r
9938 propertyPrefixes: {\r
9939 WebKit: 'webkit',\r
9940 Gecko: 'moz',\r
9941 Trident: 'ms',\r
9942 Presto: 'o',\r
9943 Other: ''\r
9944 },\r
9945
9946 \r
9947 is: function(name) {\r
9948 return !!this.is[name];\r
9949 },\r
9950 \r
9951 name: null,\r
9952 \r
9953 version: null,\r
9954 \r
9955 engineName: null,\r
9956 \r
9957 engineVersion: null,\r
9958 setFlag: function(name, value, publish) {\r
9959 if (value === undefined) {\r
9960 value = true;\r
9961 }\r
9962 this.is[name] = value;\r
9963 this.is[name.toLowerCase()] = value;\r
9964 if (publish) {\r
9965 Ext['is' + name] = value;\r
9966 }\r
9967 return this;\r
9968 },\r
9969 getStyleDashPrefix: function() {\r
9970 return this.styleDashPrefixes[this.engineName];\r
9971 },\r
9972 getStylePrefix: function() {\r
9973 return this.stylePrefixes[this.engineName];\r
9974 },\r
9975 getVendorProperyName: function(name) {\r
9976 var prefix = this.propertyPrefixes[this.engineName];\r
9977 if (prefix.length > 0) {\r
9978 return prefix + Ext.String.capitalize(name);\r
9979 }\r
9980 return name;\r
9981 },\r
9982 getPreferredTranslationMethod: function(config) {\r
9983 if (typeof config === 'object' && 'translationMethod' in config && config.translationMethod !== 'auto') {\r
9984 return config.translationMethod;\r
9985 } else {\r
9986 return 'csstransform';\r
9987 }\r
9988 }\r
9989};\r
9990\r
9991(function(userAgent) {\r
9992 Ext.browser = new Ext.env.Browser(userAgent, true);\r
9993 Ext.userAgent = userAgent.toLowerCase();\r
9994 \r
9995 Ext.SSL_SECURE_URL = Ext.isSecure && Ext.isIE ? 'javascript:\'\'' : 'about:blank';\r
9996}(
9997Ext.global.navigator.userAgent));\r
9998\r
9999\r
10000Ext.env.OS = function(userAgent, platform, browserScope) {\r
10001
10002
10003
10004
10005 var me = this,\r
10006 names = Ext.Boot.osNames,\r
10007 prefixes = Ext.Boot.osPrefixes,\r
10008 name,\r
10009 version = '',\r
10010 is = me.is,\r
10011 i, prefix, match, item, match1;\r
10012 browserScope = browserScope || Ext.browser;\r
10013 for (i in prefixes) {\r
10014 if (prefixes.hasOwnProperty(i)) {\r
10015 prefix = prefixes[i];\r
10016 match = userAgent.match(new RegExp('(?:' + prefix + ')([^\\s;]+)'));\r
10017 if (match) {\r
10018 name = names[i];\r
10019 match1 = match[1];\r
10020
10021
10022 if (match1 && match1 === "HTC_") {\r
10023 version = new Ext.Version("2.3");\r
10024 } else if (match1 && match1 === "Silk/") {\r
10025 version = new Ext.Version("2.3");\r
10026 } else {\r
10027 version = new Ext.Version(match[match.length - 1]);\r
10028 }\r
10029 break;\r
10030 }\r
10031 }\r
10032 }\r
10033 if (!name) {\r
10034 name = names[(userAgent.toLowerCase().match(/mac|win|linux/) || [\r
10035 'other'\r
10036 ])[0]];\r
10037 version = new Ext.Version('');\r
10038 }\r
10039 this.name = name;\r
10040 this.version = version;\r
10041 if (platform) {\r
10042 this.setFlag(platform.replace(/ simulator$/i, ''));\r
10043 }\r
10044 this.setFlag(name);\r
10045 if (version) {\r
10046 this.setFlag(name + (version.getMajor() || ''));\r
10047 this.setFlag(name + version.getShortVersion());\r
10048 }\r
10049 for (i in names) {\r
10050 if (names.hasOwnProperty(i)) {\r
10051 item = names[i];\r
10052 if (!is.hasOwnProperty(name)) {\r
10053 this.setFlag(item, (name === item));\r
10054 }\r
10055 }\r
10056 }\r
10057
10058 if (this.name === "iOS" && window.screen.height === 568) {\r
10059 this.setFlag('iPhone5');\r
10060 }\r
10061 if (browserScope.is.Safari || browserScope.is.Silk) {\r
10062
10063 if (this.is.Android2 || this.is.Android3 || browserScope.version.shortVersion === 501) {\r
10064 browserScope.setFlag("AndroidStock");\r
10065 }\r
10066 if (this.is.Android4) {\r
10067 browserScope.setFlag("AndroidStock");\r
10068 browserScope.setFlag("AndroidStock4");\r
10069 }\r
10070 }\r
10071};\r
10072Ext.env.OS.prototype = {\r
10073 constructor: Ext.env.OS,\r
10074 \r
10075 is: function(name) {\r
10076 return !!this[name];\r
10077 },\r
10078 \r
10079 name: null,\r
10080 \r
10081 version: null,\r
10082 setFlag: function(name, value) {\r
10083 if (value === undefined) {\r
10084 value = true;\r
10085 }\r
10086 if (this.flags) {\r
10087 this.flags[name] = value;\r
10088 }\r
10089 this.is[name] = value;\r
10090 this.is[name.toLowerCase()] = value;\r
10091 return this;\r
10092 }\r
10093};\r
10094(function() {\r
10095 var navigation = Ext.global.navigator,\r
10096 userAgent = navigation.userAgent,\r
10097 OS = Ext.env.OS,\r
10098 is = (Ext.is || (Ext.is = {})),\r
10099 osEnv, osName, deviceType;\r
10100 OS.prototype.flags = is;\r
10101 \r
10102 Ext.os = osEnv = new OS(userAgent, navigation.platform);\r
10103 osName = osEnv.name;\r
10104
10105 Ext['is' + osName] = true;\r
10106
10107 Ext.isMac = is.Mac = is.MacOS;\r
10108 var search = window.location.search.match(/deviceType=(Tablet|Phone)/),\r
10109 nativeDeviceType = window.deviceType;\r
10110
10111
10112 if (search && search[1]) {\r
10113 deviceType = search[1];\r
10114 } else if (nativeDeviceType === 'iPhone') {\r
10115 deviceType = 'Phone';\r
10116 } else if (nativeDeviceType === 'iPad') {\r
10117 deviceType = 'Tablet';\r
10118 } else {\r
10119 if (!osEnv.is.Android && !osEnv.is.iOS && !osEnv.is.WindowsPhone && /Windows|Linux|MacOS/.test(osName)) {\r
10120 deviceType = 'Desktop';\r
10121
10122 Ext.browser.is.WebView = !!Ext.browser.is.Ripple;\r
10123 } else if (osEnv.is.iPad || osEnv.is.RIMTablet || osEnv.is.Android3 || Ext.browser.is.Silk || (osEnv.is.Android && userAgent.search(/mobile/i) === -1)) {\r
10124 deviceType = 'Tablet';\r
10125 } else {\r
10126 deviceType = 'Phone';\r
10127 }\r
10128 }\r
10129 \r
10130 osEnv.setFlag(deviceType, true);\r
10131 osEnv.deviceType = deviceType;\r
10132 delete OS.prototype.flags;\r
10133}());\r
10134\r
10135\r
10136Ext.feature = {\r
10137
10138
10139
10140
10141
10142
10143 \r
10144 has: function(name) {\r
10145 return !!this.has[name];\r
10146 },\r
10147 testElements: {},\r
10148 getTestElement: function(tag, createNew) {\r
10149 if (tag === undefined) {\r
10150 tag = 'div';\r
10151 } else if (typeof tag !== 'string') {\r
10152 return tag;\r
10153 }\r
10154 if (createNew) {\r
10155 return document.createElement(tag);\r
10156 }\r
10157 if (!this.testElements[tag]) {\r
10158 this.testElements[tag] = document.createElement(tag);\r
10159 }\r
10160 return this.testElements[tag];\r
10161 },\r
10162 isStyleSupported: function(name, tag) {\r
10163 var elementStyle = this.getTestElement(tag).style,\r
10164 cName = Ext.String.capitalize(name);\r
10165 if (typeof elementStyle[name] !== 'undefined' || typeof elementStyle[Ext.browser.getStylePrefix(name) + cName] !== 'undefined') {\r
10166 return true;\r
10167 }\r
10168 return false;\r
10169 },\r
10170 isStyleSupportedWithoutPrefix: function(name, tag) {\r
10171 var elementStyle = this.getTestElement(tag).style;\r
10172 if (typeof elementStyle[name] !== 'undefined') {\r
10173 return true;\r
10174 }\r
10175 return false;\r
10176 },\r
10177 isEventSupported: function(name, tag) {\r
10178 if (tag === undefined) {\r
10179 tag = window;\r
10180 }\r
10181 var element = this.getTestElement(tag),\r
10182 eventName = 'on' + name.toLowerCase(),\r
10183 isSupported = (eventName in element);\r
10184 if (!isSupported) {\r
10185 if (element.setAttribute && element.removeAttribute) {\r
10186 element.setAttribute(eventName, '');\r
10187 isSupported = typeof element[eventName] === 'function';\r
10188 if (typeof element[eventName] !== 'undefined') {\r
10189 element[eventName] = undefined;\r
10190 }\r
10191 element.removeAttribute(eventName);\r
10192 }\r
10193 }\r
10194 return isSupported;\r
10195 },\r
10196
10197
10198
10199 getStyle: function(element, styleName) {\r
10200 var view = element.ownerDocument.defaultView,\r
10201 style = (view ? view.getComputedStyle(element, null) : element.currentStyle);\r
10202 return (style || element.style)[styleName];\r
10203 },\r
10204 getSupportedPropertyName: function(object, name) {\r
10205 var vendorName = Ext.browser.getVendorProperyName(name);\r
10206 if (vendorName in object) {\r
10207 return vendorName;\r
10208 } else if (name in object) {\r
10209 return name;\r
10210 }\r
10211 return null;\r
10212 },\r
10213 \r
10214 detect: function(isReady) {\r
10215 var me = this,\r
10216 doc = document,\r
10217 toRun = me.toRun || me.tests,\r
10218 n = toRun.length,\r
10219 div = doc.createElement('div'),\r
10220 notRun = [],\r
10221 supports = Ext.supports,\r
10222 has = me.has,\r
10223 name, names, test, vector, value;\r
10224
10225
10226
10227 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>';\r
10228 if (isReady) {\r
10229 doc.body.appendChild(div);\r
10230 }\r
10231
10232 vector = me.preDetected[Ext.browser.identity] || [];\r
10233 while (n--) {\r
10234 test = toRun[n];\r
10235 value = vector[n];\r
10236 name = test.name;\r
10237 names = test.names;\r
10238 if (value === undefined) {\r
10239 if (!isReady && test.ready) {\r
10240
10241 notRun.push(test);\r
10242 \r
10243 continue;\r
10244 }\r
10245 value = test.fn.call(me, doc, div);\r
10246 }\r
10247
10248 if (name) {\r
10249 supports[name] = has[name] = value;\r
10250 } else if (names) {\r
10251 while (names.length) {\r
10252 name = names.pop();\r
10253 supports[name] = has[name] = value;\r
10254 }\r
10255 }\r
10256 }\r
10257 if (isReady) {\r
10258 doc.body.removeChild(div);\r
10259 }\r
10260 me.toRun = notRun;\r
10261 },\r
10262
10263 report: function() {\r
10264 var values = [],\r
10265 len = this.tests.length,\r
10266 i;\r
10267 for (i = 0; i < len; ++i) {\r
10268 values.push(this.has[this.tests[i].name] ? 1 : 0);\r
10269 }\r
10270 Ext.log(Ext.browser.identity + ': [' + values.join(',') + ']');\r
10271 },\r
10272
10273 preDetected: {},\r
10274
10275 \r
10276 tests: [\r
10277 {\r
10278 \r
10279 name: 'CloneNodeCopiesExpando',\r
10280 fn: function() {\r
10281 var el = document.createElement('div');\r
10282 el.expandoProp = {};\r
10283 return el.cloneNode().expandoProp === el.expandoProp;\r
10284 }\r
10285 },\r
10286 {\r
10287 \r
10288 name: 'CSSPointerEvents',\r
10289 fn: function(doc) {\r
10290 return 'pointerEvents' in doc.documentElement.style;\r
10291 }\r
10292 },\r
10293 {\r
10294 \r
10295 name: 'CSS3BoxShadow',\r
10296 fn: function(doc) {\r
10297 return 'boxShadow' in doc.documentElement.style || 'WebkitBoxShadow' in doc.documentElement.style || 'MozBoxShadow' in doc.documentElement.style;\r
10298 }\r
10299 },\r
10300 {\r
10301 name: 'CSS3NegationSelector',\r
10302 fn: function(doc) {\r
10303 try {\r
10304 doc.querySelectorAll("foo:not(bar)");\r
10305 } catch (e) {\r
10306 return false;\r
10307 }\r
10308 return true;\r
10309 }\r
10310 },\r
10311 {\r
10312 \r
10313 name: 'ClassList',\r
10314 fn: function(doc) {\r
10315 return !!doc.documentElement.classList;\r
10316 }\r
10317 },\r
10318 {\r
10319 \r
10320 name: 'Canvas',\r
10321 fn: function() {\r
10322 var element = this.getTestElement('canvas');\r
10323 return !!(element && element.getContext && element.getContext('2d'));\r
10324 }\r
10325 },\r
10326 {\r
10327 \r
10328 name: 'Svg',\r
10329 fn: function(doc) {\r
10330 return !!(doc.createElementNS && !!doc.createElementNS("http:/" + "/www.w3.org/2000/svg", "svg").createSVGRect);\r
10331 }\r
10332 },\r
10333 {\r
10334 \r
10335 name: 'Vml',\r
10336 fn: function() {\r
10337 var element = this.getTestElement(),\r
10338 ret = false;\r
10339 element.innerHTML = "<!--[if vml]><br><![endif]-->";\r
10340 ret = (element.childNodes.length === 1);\r
10341 element.innerHTML = "";\r
10342 return ret;\r
10343 }\r
10344 },\r
10345 {\r
10346 \r
10347 name: 'touchScroll',\r
10348 fn: function() {\r
10349 var touchScroll = 0;\r
10350 if (Ext.os.is.Desktop && (navigator.maxTouchPoints || navigator.msMaxTouchPoints)) {\r
10351 touchScroll = 1;\r
10352 } else if (Ext.supports.Touch) {\r
10353 touchScroll = 2;\r
10354 }\r
10355 return touchScroll;\r
10356 }\r
10357 },\r
10358 {\r
10359 \r
10360 name: 'Touch',\r
10361 fn: function() {\r
10362
10363 var maxTouchPoints = navigator.msMaxTouchPoints || navigator.maxTouchPoints;\r
10364
10365
10366
10367
10368
10369
10370
10371
10372
10373 if (Ext.browser.is.Chrome && Ext.browser.version.isLessThanOrEqual(39)) {\r
10374 return (Ext.supports.TouchEvents && maxTouchPoints !== 1) || maxTouchPoints > 1;\r
10375 } else {\r
10376 return Ext.supports.TouchEvents || maxTouchPoints > 0;\r
10377 }\r
10378 }\r
10379 },\r
10380 {\r
10381 \r
10382 name: 'TouchEvents',\r
10383 fn: function() {\r
10384 return this.isEventSupported('touchend');\r
10385 }\r
10386 },\r
10387 {\r
10388 name: 'PointerEvents',\r
10389 fn: function() {\r
10390 return navigator.pointerEnabled;\r
10391 }\r
10392 },\r
10393 {\r
10394 name: 'MSPointerEvents',\r
10395 fn: function() {\r
10396 return navigator.msPointerEnabled;\r
10397 }\r
10398 },\r
10399 {\r
10400 \r
10401 name: 'Orientation',\r
10402 fn: function() {\r
10403 return ('orientation' in window) && this.isEventSupported('orientationchange');\r
10404 }\r
10405 },\r
10406 {\r
10407 \r
10408 name: 'OrientationChange',\r
10409 fn: function() {\r
10410 return this.isEventSupported('orientationchange');\r
10411 }\r
10412 },\r
10413 {\r
10414 \r
10415 name: 'DeviceMotion',\r
10416 fn: function() {\r
10417 return this.isEventSupported('devicemotion');\r
10418 }\r
10419 },\r
10420 {\r
10421 \r
10422 \r
10423 names: [\r
10424 'Geolocation',\r
10425 'GeoLocation'\r
10426 ],\r
10427 fn: function() {\r
10428 return 'geolocation' in window.navigator;\r
10429 }\r
10430 },\r
10431 {\r
10432 name: 'SqlDatabase',\r
10433 fn: function() {\r
10434 return 'openDatabase' in window;\r
10435 }\r
10436 },\r
10437 {\r
10438 name: 'WebSockets',\r
10439 fn: function() {\r
10440 return 'WebSocket' in window;\r
10441 }\r
10442 },\r
10443 {\r
10444 \r
10445 name: 'Range',\r
10446 fn: function() {\r
10447 return !!document.createRange;\r
10448 }\r
10449 },\r
10450 {\r
10451 \r
10452 name: 'CreateContextualFragment',\r
10453 fn: function() {\r
10454 var range = !!document.createRange ? document.createRange() : false;\r
10455 return range && !!range.createContextualFragment;\r
10456 }\r
10457 },\r
10458 {\r
10459 \r
10460 name: 'History',\r
10461 fn: function() {\r
10462 return ('history' in window && 'pushState' in window.history);\r
10463 }\r
10464 },\r
10465 {\r
10466 \r
10467 name: 'Css3dTransforms',\r
10468 fn: function() {\r
10469
10470 return this.has('CssTransforms') && this.isStyleSupported('perspective');\r
10471 }\r
10472 },\r
10473
10474
10475 {\r
10476
10477 name: 'CssTransforms',\r
10478 fn: function() {\r
10479 return this.isStyleSupported('transform');\r
10480 }\r
10481 },\r
10482 {\r
10483 name: 'CssTransformNoPrefix',\r
10484 fn: function() {\r
10485 return this.isStyleSupportedWithoutPrefix('transform');\r
10486 }\r
10487 },\r
10488 {\r
10489 name: 'CssAnimations',\r
10490 fn: function() {\r
10491 return this.isStyleSupported('animationName');\r
10492 }\r
10493 },\r
10494 {\r
10495 \r
10496 names: [\r
10497 'CssTransitions',\r
10498 'Transitions'\r
10499 ],\r
10500 fn: function() {\r
10501 return this.isStyleSupported('transitionProperty');\r
10502 }\r
10503 },\r
10504 {\r
10505 \r
10506 \r
10507 names: [\r
10508 'Audio',\r
10509 'AudioTag'\r
10510 ],\r
10511 fn: function() {\r
10512 return !!this.getTestElement('audio').canPlayType;\r
10513 }\r
10514 },\r
10515 {\r
10516 \r
10517 name: 'Video',\r
10518 fn: function() {\r
10519 return !!this.getTestElement('video').canPlayType;\r
10520 }\r
10521 },\r
10522 {\r
10523 \r
10524 name: 'LocalStorage',\r
10525 fn: function() {\r
10526 try {\r
10527
10528
10529 if ('localStorage' in window && window['localStorage'] !== null) {\r
10530
10531
10532 localStorage.setItem('sencha-localstorage-test', 'test success');\r
10533
10534 localStorage.removeItem('sencha-localstorage-test');\r
10535 return true;\r
10536 }\r
10537 } catch (e) {}\r
10538
10539 return false;\r
10540 }\r
10541 },\r
10542 {\r
10543 \r
10544 name: 'XHR2',\r
10545 fn: function() {\r
10546 return window.ProgressEvent && window.FormData && window.XMLHttpRequest && ('withCredentials' in new XMLHttpRequest());\r
10547 }\r
10548 },\r
10549 {\r
10550 \r
10551 name: 'XHRUploadProgress',\r
10552 fn: function() {\r
10553 if (window.XMLHttpRequest && !Ext.browser.is.AndroidStock) {\r
10554 var xhr = new XMLHttpRequest();\r
10555 return xhr && ('upload' in xhr) && ('onprogress' in xhr.upload);\r
10556 }\r
10557 return false;\r
10558 }\r
10559 },\r
10560 {\r
10561 \r
10562 name: 'NumericInputPlaceHolder',\r
10563 fn: function() {\r
10564 return !(Ext.browser.is.AndroidStock4 && Ext.os.version.getMinor() < 2);\r
10565 }\r
10566 },\r
10567 \r
10568 {\r
10569 name: 'matchesSelector',\r
10570 fn: function() {\r
10571 var el = document.documentElement,\r
10572 w3 = 'matches',\r
10573 wk = 'webkitMatchesSelector',\r
10574 ms = 'msMatchesSelector',\r
10575 mz = 'mozMatchesSelector';\r
10576 return el[w3] ? w3 : el[wk] ? wk : el[ms] ? ms : el[mz] ? mz : null;\r
10577 }\r
10578 },\r
10579
10580 \r
10581 {\r
10582 name: 'RightMargin',\r
10583 ready: true,\r
10584 fn: function(doc, div) {\r
10585 var view = doc.defaultView;\r
10586 return !(view && view.getComputedStyle(div.firstChild.firstChild, null).marginRight !== '0px');\r
10587 }\r
10588 },\r
10589 \r
10590 {\r
10591 name: 'DisplayChangeInputSelectionBug',\r
10592 fn: function() {\r
10593 var webKitVersion = Ext.webKitVersion;\r
10594
10595 return 0 < webKitVersion && webKitVersion < 533;\r
10596 }\r
10597 },\r
10598 \r
10599 {\r
10600 name: 'DisplayChangeTextAreaSelectionBug',\r
10601 fn: function() {\r
10602 var webKitVersion = Ext.webKitVersion;\r
10603 \r
10604 return 0 < webKitVersion && webKitVersion < 534.24;\r
10605 }\r
10606 },\r
10607 \r
10608 {\r
10609 name: 'TransparentColor',\r
10610 ready: true,\r
10611 fn: function(doc, div, view) {\r
10612 view = doc.defaultView;\r
10613 return !(view && view.getComputedStyle(div.lastChild, null).backgroundColor !== 'transparent');\r
10614 }\r
10615 },\r
10616 \r
10617 {\r
10618 name: 'ComputedStyle',\r
10619 ready: true,\r
10620 fn: function(doc, div, view) {\r
10621 view = doc.defaultView;\r
10622 return view && view.getComputedStyle;\r
10623 }\r
10624 },\r
10625 \r
10626 {\r
10627 name: 'Float',\r
10628 fn: function(doc) {\r
10629 return 'cssFloat' in doc.documentElement.style;\r
10630 }\r
10631 },\r
10632 \r
10633 {\r
10634 name: 'CSS3BorderRadius',\r
10635 ready: true,\r
10636 fn: function(doc) {\r
10637 var domPrefixes = [\r
10638 'borderRadius',\r
10639 'BorderRadius',\r
10640 'MozBorderRadius',\r
10641 'WebkitBorderRadius',\r
10642 'OBorderRadius',\r
10643 'KhtmlBorderRadius'\r
10644 ],\r
10645 pass = false,\r
10646 i;\r
10647 for (i = 0; i < domPrefixes.length; i++) {\r
10648 if (doc.documentElement.style[domPrefixes[i]] !== undefined) {\r
10649 pass = true;\r
10650 }\r
10651 }\r
10652 return pass && !Ext.isIE9;\r
10653 }\r
10654 },\r
10655 \r
10656 {\r
10657 name: 'CSS3LinearGradient',\r
10658 fn: function(doc, div) {\r
10659 var property = 'background-image:',\r
10660 webkit = '-webkit-gradient(linear, left top, right bottom, from(black), to(white))',\r
10661 w3c = 'linear-gradient(left top, black, white)',\r
10662 moz = '-moz-' + w3c,\r
10663 ms = '-ms-' + w3c,\r
10664 opera = '-o-' + w3c,\r
10665 options = [\r
10666 property + webkit,\r
10667 property + w3c,\r
10668 property + moz,\r
10669 property + ms,\r
10670 property + opera\r
10671 ];\r
10672 div.style.cssText = options.join(';');\r
10673 return (("" + div.style.backgroundImage).indexOf('gradient') !== -1) && !Ext.isIE9;\r
10674 }\r
10675 },\r
10676 \r
10677 {\r
10678 name: 'MouseEnterLeave',\r
10679 fn: function(doc) {\r
10680 return ('onmouseenter' in doc.documentElement && 'onmouseleave' in doc.documentElement);\r
10681 }\r
10682 },\r
10683 \r
10684 {\r
10685 name: 'MouseWheel',\r
10686 fn: function(doc) {\r
10687 return ('onmousewheel' in doc.documentElement);\r
10688 }\r
10689 },\r
10690 \r
10691 {\r
10692 name: 'Opacity',\r
10693 fn: function(doc, div) {\r
10694
10695 if (Ext.isIE8) {\r
10696 return false;\r
10697 }\r
10698 div.firstChild.style.cssText = 'opacity:0.73';\r
10699 return div.firstChild.style.opacity == '0.73';\r
10700 }\r
10701 },\r
10702
10703 \r
10704 {\r
10705 name: 'Placeholder',\r
10706 fn: function(doc) {\r
10707 return 'placeholder' in doc.createElement('input');\r
10708 }\r
10709 },\r
10710 \r
10711 {\r
10712 name: 'Direct2DBug',\r
10713 fn: function(doc) {\r
10714 return Ext.isString(doc.documentElement.style.msTransformOrigin) && Ext.isIE9m;\r
10715 }\r
10716 },\r
10717 \r
10718 {\r
10719 name: 'BoundingClientRect',\r
10720 fn: function(doc) {\r
10721 return 'getBoundingClientRect' in doc.documentElement;\r
10722 }\r
10723 },\r
10724 \r
10725 {\r
10726 name: 'RotatedBoundingClientRect',\r
10727 ready: true,\r
10728 fn: function(doc) {\r
10729 var body = doc.body,\r
10730 supports = false,\r
10731 el = doc.createElement('div'),\r
10732 style = el.style;\r
10733 if (el.getBoundingClientRect) {\r
10734
10735
10736
10737 style.position = 'absolute';\r
10738 style.top = "0";\r
10739 style.WebkitTransform = style.MozTransform = style.msTransform = style.OTransform = style.transform = 'rotate(90deg)';\r
10740 style.width = '100px';\r
10741 style.height = '30px';\r
10742 body.appendChild(el);\r
10743 supports = el.getBoundingClientRect().height !== 100;\r
10744 body.removeChild(el);\r
10745 }\r
10746 return supports;\r
10747 }\r
10748 },\r
10749 \r
10750 {\r
10751 name: 'ChildContentClearedWhenSettingInnerHTML',\r
10752 ready: true,\r
10753 fn: function() {\r
10754 var el = this.getTestElement(),\r
10755 child;\r
10756 el.innerHTML = '<div>a</div>';\r
10757 child = el.firstChild;\r
10758 el.innerHTML = '<div>b</div>';\r
10759 return child.innerHTML !== 'a';\r
10760 }\r
10761 },\r
10762 {\r
10763 name: 'IncludePaddingInWidthCalculation',\r
10764 ready: true,\r
10765 fn: function(doc, div) {\r
10766 return div.childNodes[1].firstChild.offsetWidth === 210;\r
10767 }\r
10768 },\r
10769 {\r
10770 name: 'IncludePaddingInHeightCalculation',\r
10771 ready: true,\r
10772 fn: function(doc, div) {\r
10773 return div.childNodes[1].firstChild.offsetHeight === 210;\r
10774 }\r
10775 },\r
10776 \r
10777 {\r
10778 name: 'TextAreaMaxLength',\r
10779 fn: function(doc) {\r
10780 return ('maxlength' in doc.createElement('textarea'));\r
10781 }\r
10782 },\r
10783 \r
10784
10785 {\r
10786 name: 'GetPositionPercentage',\r
10787 ready: true,\r
10788 fn: function(doc, div) {\r
10789 return Ext.feature.getStyle(div.childNodes[2], 'left') === '10%';\r
10790 }\r
10791 },\r
10792 \r
10793 {\r
10794 name: 'PercentageHeightOverflowBug',\r
10795 ready: true,\r
10796 fn: function(doc) {\r
10797 var hasBug = false,\r
10798 style, el;\r
10799 if (Ext.getScrollbarSize().height) {\r
10800
10801 el = this.getTestElement();\r
10802 style = el.style;\r
10803 style.height = '50px';\r
10804 style.width = '50px';\r
10805 style.overflow = 'auto';\r
10806 style.position = 'absolute';\r
10807 el.innerHTML = [\r
10808 '<div style="display:table;height:100%;">',\r
10809
10810
10811
10812 '<div style="width:51px;"></div>',\r
10813 '</div>'\r
10814 ].join('');\r
10815 doc.body.appendChild(el);\r
10816 if (el.firstChild.offsetHeight === 50) {\r
10817 hasBug = true;\r
10818 }\r
10819 doc.body.removeChild(el);\r
10820 }\r
10821 return hasBug;\r
10822 }\r
10823 },\r
10824 \r
10825 {\r
10826 name: 'xOriginBug',\r
10827 ready: true,\r
10828 fn: function(doc, div) {\r
10829 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>';\r
10830 var outerBox = document.getElementById('b1').getBoundingClientRect(),\r
10831 b2 = document.getElementById('b2').getBoundingClientRect(),\r
10832 b3 = document.getElementById('b3').getBoundingClientRect();\r
10833 return (b2.left !== outerBox.left && b3.right !== outerBox.right);\r
10834 }\r
10835 },\r
10836 \r
10837 {\r
10838 name: 'ScrollWidthInlinePaddingBug',\r
10839 ready: true,\r
10840 fn: function(doc) {\r
10841 var hasBug = false,\r
10842 style, el;\r
10843 el = doc.createElement('div');\r
10844 style = el.style;\r
10845 style.height = '50px';\r
10846 style.width = '50px';\r
10847 style.padding = '10px';\r
10848 style.overflow = 'hidden';\r
10849 style.position = 'absolute';\r
10850 el.innerHTML = '<span style="display:inline-block;zoom:1;height:60px;width:60px;"></span>';\r
10851 doc.body.appendChild(el);\r
10852 if (el.scrollWidth === 70) {\r
10853 hasBug = true;\r
10854 }\r
10855 doc.body.removeChild(el);\r
10856 return hasBug;\r
10857 }\r
10858 },\r
10859 \r
10860 {\r
10861 name: 'rtlVertScrollbarOnRight',\r
10862 ready: true,\r
10863 fn: function(doc, div) {\r
10864 div.innerHTML = '<div style="height:100px;width:100px;direction:rtl;overflow:scroll">' + '<div style="width:20px;height:200px;"></div>' + '</div>';\r
10865 var outerBox = div.firstChild,\r
10866 innerBox = outerBox.firstChild;\r
10867 return (innerBox.offsetLeft + innerBox.offsetWidth !== outerBox.offsetLeft + outerBox.offsetWidth);\r
10868 }\r
10869 },\r
10870 \r
10871 {\r
10872 name: 'rtlVertScrollbarOverflowBug',\r
10873 ready: true,\r
10874 fn: function(doc, div) {\r
10875 div.innerHTML = '<div style="height:100px;width:100px;direction:rtl;overflow:auto">' + '<div style="width:95px;height:200px;"></div>' + '</div>';\r
10876
10877
10878
10879 var outerBox = div.firstChild;\r
10880 return outerBox.clientHeight === outerBox.offsetHeight;\r
10881 }\r
10882 },\r
10883 {\r
10884 identity: 'defineProperty',\r
10885 fn: function() {\r
10886 if (Ext.isIE8m) {\r
10887 Ext.Object.defineProperty = Ext.emptyFn;\r
10888 return false;\r
10889 }\r
10890 return true;\r
10891 }\r
10892 },\r
10893 {\r
10894 identify: 'nativeXhr',\r
10895 fn: function() {\r
10896 if (typeof XMLHttpRequest !== 'undefined') {\r
10897 return true;\r
10898 }\r
10899
10900 XMLHttpRequest = function() {\r
10901
10902 try {\r
10903 return new ActiveXObject('MSXML2.XMLHTTP.3.0');\r
10904 }
10905 catch (ex) {\r
10906 return null;\r
10907 }\r
10908 };\r
10909 return false;\r
10910 }\r
10911 },\r
10912 \r
10913 {\r
10914 name: 'SpecialKeyDownRepeat',\r
10915 fn: function() {\r
10916 return Ext.isWebKit ? parseInt(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1], 10) >= 525 : !((Ext.isGecko && !Ext.isWindows) || (Ext.isOpera && Ext.operaVersion < 12));\r
10917 }\r
10918 },\r
10919 \r
10920 {\r
10921 name: 'EmulatedMouseOver',\r
10922 fn: function() {\r
10923
10924 return Ext.os.is.iOS;\r
10925 }\r
10926 },\r
10927 \r
10928 {\r
10929
10930 name: 'Hashchange',\r
10931 fn: function() {\r
10932
10933 var docMode = document.documentMode;\r
10934 return 'onhashchange' in window && (docMode === undefined || docMode > 7);\r
10935 }\r
10936 },\r
10937 \r
10938 {\r
10939 name: 'FixedTableWidthBug',\r
10940 ready: true,\r
10941 fn: function() {\r
10942 if (Ext.isIE8) {\r
10943
10944 return false;\r
10945 }\r
10946 var outer = document.createElement('div'),\r
10947 inner = document.createElement('div'),\r
10948 width;\r
10949 outer.setAttribute('style', 'display:table;table-layout:fixed;');\r
10950 inner.setAttribute('style', 'display:table-cell;min-width:50px;');\r
10951 outer.appendChild(inner);\r
10952 document.body.appendChild(outer);\r
10953
10954 outer.offsetWidth;\r
10955
10956 outer.style.width = '25px';\r
10957 width = outer.offsetWidth;\r
10958 document.body.removeChild(outer);\r
10959 return width === 50;\r
10960 }\r
10961 },\r
10962 \r
10963 {\r
10964 name: 'FocusinFocusoutEvents',\r
10965 fn: function() {\r
10966
10967
10968
10969
10970 return !Ext.isGecko;\r
10971 }\r
10972 },\r
10973 \r
10974 {\r
10975 name: 'AsyncFocusEvents',\r
10976 fn: function() {\r
10977
10978
10979
10980 return Ext.asyncFocus = !!Ext.isIE;\r
10981 }\r
10982 },\r
10983
10984 \r
10985 {\r
10986 name: 'accessibility',\r
10987 ready: true,\r
10988 fn: function(doc) {\r
10989 var body = doc.body,\r
10990 div, img, style, supports, bgImg;\r
10991 function getColor(colorTxt) {\r
10992 var values = [],\r
10993 colorValue = 0,\r
10994 regex, match;\r
10995 if (colorTxt.indexOf('rgb(') !== -1) {\r
10996 values = colorTxt.replace('rgb(', '').replace(')', '').split(', ');\r
10997 } else if (colorTxt.indexOf('#') !== -1) {\r
10998 regex = colorTxt.length === 7 ? /^#(\S\S)(\S\S)(\S\S)$/ : /^#(\S)(\S)(\S)$/;\r
10999 match = colorTxt.match(regex);\r
11000 if (match) {\r
11001 values = [\r
11002 '0x' + match[1],\r
11003 '0x' + match[2],\r
11004 '0x' + match[3]\r
11005 ];\r
11006 }\r
11007 }\r
11008 for (var i = 0; i < values.length; i++) {\r
11009 colorValue += parseInt(values[i]);\r
11010 }\r
11011 return colorValue;\r
11012 }\r
11013 div = doc.createElement('div');\r
11014 img = doc.createElement('img');\r
11015 style = div.style;\r
11016 Ext.apply(style, {\r
11017 width: '2px',\r
11018 position: 'absolute',\r
11019 clip: 'rect(1px,1px,1px,1px)',\r
11020 borderWidth: '1px',\r
11021 borderStyle: 'solid',\r
11022 borderTopTolor: '#f00',\r
11023 borderRightColor: '#ff0',\r
11024 backgroundColor: '#fff',\r
11025 backgroundImage: 'url(' + Ext.BLANK_IMAGE_URL + ')'\r
11026 });\r
11027 img.alt = '';\r
11028 img.src = Ext.BLANK_IMAGE_URL;\r
11029 div.appendChild(img);\r
11030 body.appendChild(div);\r
11031
11032 style = div.currentStyle || div.style;\r
11033 bgImg = style.backgroundImage;\r
11034 supports = {\r
11035
11036
11037
11038
11039 Images: img.offsetWidth === 1 && img.readyState !== 'uninitialized',\r
11040 BackgroundImages: !(bgImg !== null && (bgImg === "none" || bgImg === "url(invalid-url:)")),\r
11041 BorderColors: style.borderTopColor !== style.borderRightColor,\r
11042 LightOnDark: getColor(style.color) - getColor(style.backgroundColor) > 0\r
11043 };\r
11044 Ext.supports.HighContrastMode = !supports.BackgroundImages;\r
11045 body.removeChild(div);\r
11046 div = img = null;\r
11047 return supports;\r
11048 }\r
11049 },\r
11050 0\r
11051 ]\r
11052};\r
11053
11054Ext.feature.tests.pop();\r
11055
11056Ext.supports = {};\r
11057Ext.feature.detect();\r
11058\r
11059\r
11060Ext.env.Ready = {\r
11061
11062
11063
11064
11065 \r
11066 blocks: (location.search || '').indexOf('ext-pauseReadyFire') > 0 ? 1 : 0,\r
11067 \r
11068 bound: 0,\r
11069 \r
11070 delay: 1,\r
11071
11072 \r
11073 events: [],\r
11074
11075 \r
11076 firing: false,\r
11077 \r
11078 generation: 0,\r
11079 \r
11080 listeners: [],\r
11081 \r
11082 nextId: 0,\r
11083 \r
11084 sortGeneration: 0,\r
11085 \r
11086 state: 0,\r
11087 \r
11088 timer: null,\r
11089 \r
11090 bind: function() {\r
11091 var me = Ext.env.Ready,\r
11092 doc = document;\r
11093 if (!me.bound) {\r
11094
11095 if (doc.readyState === 'complete') {\r
11096
11097 me.onReadyEvent({\r
11098 type: doc.readyState || 'body'\r
11099 });\r
11100 } else {\r
11101 me.bound = 1;\r
11102 if (Ext.browser.is.PhoneGap && !Ext.os.is.Desktop) {\r
11103 me.bound = 2;\r
11104 doc.addEventListener('deviceready', me.onReadyEvent, false);\r
11105 }\r
11106 doc.addEventListener('DOMContentLoaded', me.onReadyEvent, false);\r
11107 window.addEventListener('load', me.onReadyEvent, false);\r
11108 }\r
11109 }\r
11110 },\r
11111 block: function() {\r
11112 ++this.blocks;\r
11113 Ext.isReady = false;\r
11114 },\r
11115 \r
11116 fireReady: function() {\r
11117 var me = Ext.env.Ready;\r
11118 if (!me.state) {\r
11119 Ext._readyTime = Ext.ticks();\r
11120 Ext.isDomReady = true;\r
11121 me.state = 1;\r
11122
11123 Ext.feature.detect(true);\r
11124 if (!me.delay) {\r
11125 me.handleReady();\r
11126 } else if (navigator.standalone) {\r
11127
11128
11129
11130
11131 me.timer = Ext.defer(function() {\r
11132 me.timer = null;\r
11133 me.handleReadySoon();\r
11134 }, 1);\r
11135 } else {\r
11136 me.handleReadySoon();\r
11137 }\r
11138 }\r
11139 },\r
11140 \r
11141 handleReady: function() {\r
11142 var me = this;\r
11143 if (me.state === 1) {\r
11144 me.state = 2;\r
11145 Ext._beforeReadyTime = Ext.ticks();\r
11146 me.invokeAll();\r
11147 Ext._afterReadyTime = Ext.ticks();\r
11148 }\r
11149 },\r
11150 \r
11151 handleReadySoon: function(delay) {\r
11152 var me = this;\r
11153 if (!me.timer) {\r
11154 me.timer = Ext.defer(function() {\r
11155 me.timer = null;\r
11156 me.handleReady();\r
11157 }, delay || me.delay);\r
11158 }\r
11159 },\r
11160 \r
11161 invoke: function(listener) {\r
11162 var delay = listener.delay;\r
11163 if (delay) {\r
11164 Ext.defer(listener.fn, delay, listener.scope);\r
11165 } else {\r
11166 if (Ext.elevateFunction) {\r
11167 Ext.elevateFunction(listener.fn, listener.scope);\r
11168 } else {\r
11169 listener.fn.call(listener.scope);\r
11170 }\r
11171 }\r
11172 },\r
11173 \r
11174 invokeAll: function() {\r
11175 if (Ext.elevateFunction) {\r
11176 Ext.elevateFunction(this.doInvokeAll, this);\r
11177 } else {\r
11178 this.doInvokeAll();\r
11179 }\r
11180 },\r
11181 doInvokeAll: function() {\r
11182 var me = this,\r
11183 listeners = me.listeners,\r
11184 listener;\r
11185 if (!me.blocks) {\r
11186
11187 Ext.isReady = true;\r
11188 }\r
11189 me.firing = true;\r
11190
11191
11192 while (listeners.length) {\r
11193 if (me.sortGeneration !== me.generation) {\r
11194 me.sortGeneration = me.generation;\r
11195
11196
11197
11198
11199 listeners.sort(me.sortFn);\r
11200 }\r
11201 listener = listeners.pop();\r
11202 if (me.blocks && !listener.dom) {\r
11203
11204
11205
11206 listeners.push(listener);\r
11207 break;\r
11208 }\r
11209 me.invoke(listener);\r
11210 }\r
11211 me.firing = false;\r
11212 },\r
11213 \r
11214 makeListener: function(fn, scope, options) {\r
11215 var ret = {\r
11216 fn: fn,\r
11217 id: ++this.nextId,\r
11218
11219 scope: scope,\r
11220 dom: false,\r
11221 priority: 0\r
11222 };\r
11223 if (options) {\r
11224 Ext.apply(ret, options);\r
11225 }\r
11226 ret.phase = ret.dom ? 0 : 1;\r
11227
11228 return ret;\r
11229 },\r
11230 \r
11231 on: function(fn, scope, options) {\r
11232 var me = Ext.env.Ready,\r
11233 listener = me.makeListener(fn, scope, options);\r
11234 if (me.state === 2 && !me.firing && (listener.dom || !me.blocks)) {\r
11235
11236
11237
11238
11239
11240
11241
11242 me.invoke(listener);\r
11243 } else {\r
11244 me.listeners.push(listener);\r
11245 ++me.generation;\r
11246 if (!me.bound) {\r
11247
11248
11249
11250 me.bind();\r
11251 }\r
11252 }\r
11253 },\r
11254 \r
11255 onReadyEvent: function(ev) {\r
11256 var me = Ext.env.Ready;\r
11257 if (Ext.elevateFunction) {\r
11258 Ext.elevateFunction(me.doReadyEvent, me, arguments);\r
11259 } else {\r
11260 me.doReadyEvent(ev);\r
11261 }\r
11262 },\r
11263 doReadyEvent: function(ev) {\r
11264 var me = this;\r
11265
11266 if (ev && ev.type) {\r
11267 me.events.push(ev);\r
11268 }\r
11269
11270 if (me.bound > 0) {\r
11271 me.unbind();\r
11272 me.bound = -1;\r
11273 }\r
11274
11275 if (!me.state) {\r
11276 me.fireReady();\r
11277 }\r
11278 },\r
11279 \r
11280 sortFn: function(a, b) {\r
11281 return -((a.phase - b.phase) || (b.priority - a.priority) || (a.id - b.id));\r
11282 },\r
11283 unblock: function() {\r
11284 var me = this;\r
11285 if (me.blocks) {\r
11286 if (!--me.blocks) {\r
11287 if (me.state === 2 && !me.firing) {\r
11288
11289
11290 me.invokeAll();\r
11291 }\r
11292 }\r
11293 }\r
11294 },\r
11295
11296
11297
11298
11299
11300 \r
11301 unbind: function() {\r
11302 var me = this,\r
11303 doc = document;\r
11304 if (me.bound > 1) {\r
11305 doc.removeEventListener('deviceready', me.onReadyEvent, false);\r
11306 }\r
11307 doc.removeEventListener('DOMContentLoaded', me.onReadyEvent, false);\r
11308 window.removeEventListener('load', me.onReadyEvent, false);\r
11309 }\r
11310};\r
11311(function() {\r
11312 var Ready = Ext.env.Ready;\r
11313
11314 \r
11315 if (Ext.isIE9m) {\r
11316 \r
11317 Ext.apply(Ready, {\r
11318 \r
11319 scrollTimer: null,\r
11320 \r
11321 readyStatesRe: /complete/i,\r
11322 \r
11323 pollScroll: function() {\r
11324 var scrollable = true;\r
11325 try {\r
11326 document.documentElement.doScroll('left');\r
11327 } catch (e) {\r
11328 scrollable = false;\r
11329 }\r
11330
11331
11332 if (scrollable && document.body) {\r
11333 Ready.onReadyEvent({\r
11334 type: 'doScroll'\r
11335 });\r
11336 } else {\r
11337
11338
11339
11340 Ready.scrollTimer = Ext.defer(Ready.pollScroll, 20);\r
11341 }\r
11342 return scrollable;\r
11343 },\r
11344 bind: function() {\r
11345 if (Ready.bound) {\r
11346 return;\r
11347 }\r
11348 var doc = document,\r
11349 topContext;\r
11350
11351 try {\r
11352 topContext = window.frameElement === undefined;\r
11353 } catch (e) {}\r
11354
11355
11356 if (!topContext || !doc.documentElement.doScroll) {\r
11357 Ready.pollScroll = Ext.emptyFn;\r
11358 }\r
11359
11360 else if (Ready.pollScroll()) {\r
11361
11362 return;\r
11363 }\r
11364 if (doc.readyState === 'complete') {\r
11365
11366 Ready.onReadyEvent({\r
11367 type: 'already ' + (doc.readyState || 'body')\r
11368 });\r
11369 } else {\r
11370 doc.attachEvent('onreadystatechange', Ready.onReadyStateChange);\r
11371 window.attachEvent('onload', Ready.onReadyEvent);\r
11372 Ready.bound = 1;\r
11373 }\r
11374 },\r
11375 unbind: function() {\r
11376 document.detachEvent('onreadystatechange', Ready.onReadyStateChange);\r
11377 window.detachEvent('onload', Ready.onReadyEvent);\r
11378 if (Ext.isNumber(Ready.scrollTimer)) {\r
11379 clearTimeout(Ready.scrollTimer);\r
11380 Ready.scrollTimer = null;\r
11381 }\r
11382 },\r
11383 \r
11384 onReadyStateChange: function() {\r
11385 var state = document.readyState;\r
11386 if (Ready.readyStatesRe.test(state)) {\r
11387 Ready.onReadyEvent({\r
11388 type: state\r
11389 });\r
11390 }\r
11391 }\r
11392 });\r
11393 }\r
11394
11395 \r
11396 \r
11397 \r
11398 Ext.onDocumentReady = function(fn, scope, options) {\r
11399 var opt = {\r
11400 dom: true\r
11401 };\r
11402 if (options) {\r
11403 Ext.apply(opt, options);\r
11404 }\r
11405 Ready.on(fn, scope, opt);\r
11406 };\r
11407 \r
11408 Ext.onReady = function(fn, scope, options) {\r
11409 Ready.on(fn, scope, options);\r
11410 };\r
11411
11412 Ext.onInternalReady = function(fn, scope, options) {\r
11413 Ready.on(fn, scope, Ext.apply({\r
11414 priority: 1000\r
11415 }, options));\r
11416 };\r
11417 Ready.bind();\r
11418}());\r
11419\r
11420
11421\r
11422Ext.Loader = (new function() {\r
11423
11424
11425
11426
11427
11428
11429
11430
11431 var Loader = this,\r
11432 Manager = Ext.ClassManager,\r
11433
11434 Boot = Ext.Boot,\r
11435 Class = Ext.Class,\r
11436 Ready = Ext.env.Ready,\r
11437 alias = Ext.Function.alias,\r
11438 dependencyProperties = [\r
11439 'extend',\r
11440 'mixins',\r
11441 'requires'\r
11442 ],\r
11443 isInHistory = {},\r
11444 history = [],\r
11445 readyListeners = [],\r
11446 usedClasses = [],\r
11447 _requiresMap = {},\r
11448 _missingQueue = {},\r
11449 _config = {\r
11450 \r
11451 enabled: true,\r
11452 \r
11453 scriptChainDelay: false,\r
11454 \r
11455 disableCaching: true,\r
11456 \r
11457 disableCachingParam: '_dc',\r
11458 \r
11459 paths: Manager.paths,\r
11460 \r
11461 preserveScripts: true,\r
11462 \r
11463 scriptCharset: undefined\r
11464 },\r
11465
11466 delegatedConfigs = {\r
11467 disableCaching: true,\r
11468 disableCachingParam: true,\r
11469 preserveScripts: true,\r
11470 scriptChainDelay: 'loadDelay'\r
11471 };\r
11472 Ext.apply(Loader, {\r
11473 \r
11474 isInHistory: isInHistory,\r
11475 \r
11476 isLoading: false,\r
11477 \r
11478 history: history,\r
11479 \r
11480 config: _config,\r
11481 \r
11482 readyListeners: readyListeners,\r
11483 \r
11484 optionalRequires: usedClasses,\r
11485 \r
11486 requiresMap: _requiresMap,\r
11487 \r
11488 hasFileLoadError: false,\r
11489 \r
11490 scriptsLoading: 0,\r
11491
11492 \r
11493 classesLoading: [],\r
11494
11495 \r
11496 syncModeEnabled: false,\r
11497 \r
11498 missingQueue: _missingQueue,\r
11499 init: function() {\r
11500
11501 var scripts = document.getElementsByTagName('script'),\r
11502 src = scripts[scripts.length - 1].src,\r
11503 path = src.substring(0, src.lastIndexOf('/') + 1),\r
11504 meta = Ext._classPathMetadata,\r
11505 microloader = Ext.Microloader,\r
11506 manifest = Ext.manifest,\r
11507 loadOrder, baseUrl, loadlen, l, loadItem;\r
11508
11509 if (src.indexOf("packages/core/src/") !== -1) {\r
11510 path = path + "../../";\r
11511 } else if (src.indexOf("/core/src/class/") !== -1) {\r
11512 path = path + "../../../";\r
11513 }\r
11514
11515 if (!Manager.getPath("Ext")) {\r
11516 Manager.setPath('Ext', path + 'src');\r
11517 }\r
11518
11519 if (meta) {\r
11520 Ext._classPathMetadata = null;\r
11521 Loader.addClassPathMappings(meta);\r
11522 }\r
11523 if (manifest) {\r
11524 loadOrder = manifest.loadOrder;\r
11525
11526
11527
11528 baseUrl = Ext.Boot.baseUrl;\r
11529 if (loadOrder && manifest.bootRelative) {\r
11530 for (loadlen = loadOrder.length , l = 0; l < loadlen; l++) {\r
11531 loadItem = loadOrder[l];\r
11532 loadItem.path = baseUrl + loadItem.path;\r
11533 }\r
11534 }\r
11535 }\r
11536 if (microloader) {\r
11537 Ready.block();\r
11538 microloader.onMicroloaderReady(function() {\r
11539 Ready.unblock();\r
11540 });\r
11541 }\r
11542 },\r
11543 \r
11544 setConfig: Ext.Function.flexSetter(function(name, value) {\r
11545 if (name === 'paths') {\r
11546 Loader.setPath(value);\r
11547 } else {\r
11548 _config[name] = value;\r
11549 var delegated = delegatedConfigs[name];\r
11550 if (delegated) {\r
11551 Boot.setConfig((delegated === true) ? name : delegated, value);\r
11552 }\r
11553 }\r
11554 return Loader;\r
11555 }),\r
11556 \r
11557 getConfig: function(name) {\r
11558 return name ? _config[name] : _config;\r
11559 },\r
11560 \r
11561 setPath: function() {\r
11562
11563 Manager.setPath.apply(Manager, arguments);\r
11564 return Loader;\r
11565 },\r
11566 \r
11567 addClassPathMappings: function(paths) {\r
11568
11569 Manager.setPath(paths);\r
11570 return Loader;\r
11571 },\r
11572 \r
11573 addBaseUrlClassPathMappings: function(pathConfig) {\r
11574 for (var name in pathConfig) {\r
11575 pathConfig[name] = Boot.baseUrl + pathConfig[name];\r
11576 }\r
11577 Ext.Loader.addClassPathMappings(pathConfig);\r
11578 },\r
11579 \r
11580 getPath: function(className) {\r
11581
11582 return Manager.getPath(className);\r
11583 },\r
11584 require: function(expressions, fn, scope, excludes) {\r
11585 if (excludes) {\r
11586 return Loader.exclude(excludes).require(expressions, fn, scope);\r
11587 }\r
11588 var classNames = Manager.getNamesByExpression(expressions);\r
11589 return Loader.load(classNames, fn, scope);\r
11590 },\r
11591 syncRequire: function() {\r
11592 var wasEnabled = Loader.syncModeEnabled;\r
11593 Loader.syncModeEnabled = true;\r
11594 var ret = Loader.require.apply(Loader, arguments);\r
11595 Loader.syncModeEnabled = wasEnabled;\r
11596 return ret;\r
11597 },\r
11598 exclude: function(excludes) {\r
11599 var selector = Manager.select({\r
11600 require: function(classNames, fn, scope) {\r
11601 return Loader.load(classNames, fn, scope);\r
11602 },\r
11603 syncRequire: function(classNames, fn, scope) {\r
11604 var wasEnabled = Loader.syncModeEnabled;\r
11605 Loader.syncModeEnabled = true;\r
11606 var ret = Loader.load(classNames, fn, scope);\r
11607 Loader.syncModeEnabled = wasEnabled;\r
11608 return ret;\r
11609 }\r
11610 });\r
11611 selector.exclude(excludes);\r
11612 return selector;\r
11613 },\r
11614 load: function(classNames, callback, scope) {\r
11615 if (callback) {\r
11616 if (callback.length) {\r
11617
11618
11619 callback = Loader.makeLoadCallback(classNames, callback);\r
11620 }\r
11621 callback = callback.bind(scope || Ext.global);\r
11622 }\r
11623 var missingClassNames = [],\r
11624 numClasses = classNames.length,\r
11625 className, i, numMissing,\r
11626 urls = [],\r
11627 state = Manager.classState;\r
11628 for (i = 0; i < numClasses; ++i) {\r
11629 className = Manager.resolveName(classNames[i]);\r
11630 if (!Manager.isCreated(className)) {\r
11631 missingClassNames.push(className);\r
11632 _missingQueue[className] = Loader.getPath(className);\r
11633 if (!state[className]) {\r
11634 urls.push(_missingQueue[className]);\r
11635 }\r
11636 }\r
11637 }\r
11638
11639
11640 numMissing = missingClassNames.length;\r
11641 if (numMissing) {\r
11642 Loader.missingCount += numMissing;\r
11643
11644 Ext.Array.push(Loader.classesLoading, missingClassNames);\r
11645
11646 Manager.onCreated(function() {\r
11647
11648 Ext.Array.remove(Loader.classesLoading, missingClassNames);\r
11649 Ext.each(missingClassNames, function(name) {\r
11650 Ext.Array.remove(Loader.classesLoading, name);\r
11651 });\r
11652
11653 if (callback) {\r
11654 Ext.callback(callback, scope, arguments);\r
11655 }\r
11656 Loader.checkReady();\r
11657 }, Loader, missingClassNames);\r
11658 if (!_config.enabled) {\r
11659 Ext.raise("Ext.Loader is not enabled, so dependencies cannot be resolved dynamically. " + "Missing required class" + ((missingClassNames.length > 1) ? "es" : "") + ": " + missingClassNames.join(', '));\r
11660 }\r
11661 if (urls.length) {\r
11662 Loader.loadScripts({\r
11663 url: urls,\r
11664
11665 _classNames: missingClassNames\r
11666 });\r
11667 } else {\r
11668
11669
11670
11671 Loader.checkReady();\r
11672 }\r
11673 } else {\r
11674 if (callback) {\r
11675 callback.call(scope);\r
11676 }\r
11677
11678
11679
11680 Loader.checkReady();\r
11681 }\r
11682 if (Loader.syncModeEnabled) {\r
11683
11684 if (numClasses === 1) {\r
11685 return Manager.get(classNames[0]);\r
11686 }\r
11687 }\r
11688 return Loader;\r
11689 },\r
11690 makeLoadCallback: function(classNames, callback) {\r
11691 return function() {\r
11692 var classes = [],\r
11693 i = classNames.length;\r
11694 while (i-- > 0) {\r
11695 classes[i] = Manager.get(classNames[i]);\r
11696 }\r
11697 return callback.apply(this, classes);\r
11698 };\r
11699 },\r
11700 onLoadFailure: function() {\r
11701 var options = this,\r
11702 onError = options.onError;\r
11703 Loader.hasFileLoadError = true;\r
11704 --Loader.scriptsLoading;\r
11705 if (onError) {\r
11706
11707 onError.call(options.userScope, options);\r
11708 } else
11709 {\r
11710 Ext.log.error("[Ext.Loader] Some requested files failed to load.");\r
11711 }\r
11712
11713 Loader.checkReady();\r
11714 },\r
11715 onLoadSuccess: function() {\r
11716 var options = this,\r
11717 onLoad = options.onLoad;\r
11718 --Loader.scriptsLoading;\r
11719 if (onLoad) {\r
11720
11721 onLoad.call(options.userScope, options);\r
11722 }\r
11723
11724 Loader.checkReady();\r
11725 },\r
11726
11727
11728 reportMissingClasses: function() {\r
11729 if (!Loader.syncModeEnabled && !Loader.scriptsLoading && Loader.isLoading && !Loader.hasFileLoadError) {\r
11730 var missingClasses = [],\r
11731 missingPaths = [];\r
11732 for (var missingClassName in _missingQueue) {\r
11733 missingClasses.push(missingClassName);\r
11734 missingPaths.push(_missingQueue[missingClassName]);\r
11735 }\r
11736 if (missingClasses.length) {\r
11737 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("', '"));\r
11738 }\r
11739 }\r
11740 },\r
11741
11742 \r
11743 onReady: function(fn, scope, withDomReady, options) {\r
11744 if (withDomReady) {\r
11745 Ready.on(fn, scope, options);\r
11746 } else {\r
11747 var listener = Ready.makeListener(fn, scope, options);\r
11748 if (Loader.isLoading) {\r
11749 readyListeners.push(listener);\r
11750 } else {\r
11751 Ready.invoke(listener);\r
11752 }\r
11753 }\r
11754 },\r
11755 \r
11756 addUsedClasses: function(classes) {\r
11757 var cls, i, ln;\r
11758 if (classes) {\r
11759 classes = (typeof classes === 'string') ? [\r
11760 classes\r
11761 ] : classes;\r
11762 for (i = 0 , ln = classes.length; i < ln; i++) {\r
11763 cls = classes[i];\r
11764 if (typeof cls === 'string' && !Ext.Array.contains(usedClasses, cls)) {\r
11765 usedClasses.push(cls);\r
11766 }\r
11767 }\r
11768 }\r
11769 return Loader;\r
11770 },\r
11771 \r
11772 triggerReady: function() {\r
11773 var listener,\r
11774 refClasses = usedClasses;\r
11775 if (Loader.isLoading && refClasses.length) {\r
11776
11777 usedClasses = [];\r
11778
11779
11780 Loader.require(refClasses);\r
11781 } else {\r
11782
11783
11784 Loader.isLoading = false;\r
11785
11786
11787 readyListeners.sort(Ready.sortFn);\r
11788
11789
11790
11791 while (readyListeners.length && !Loader.isLoading) {\r
11792
11793
11794 listener = readyListeners.pop();\r
11795 Ready.invoke(listener);\r
11796 }\r
11797
11798
11799
11800
11801
11802
11803
11804
11805 Ready.unblock();\r
11806 }\r
11807 },\r
11808 \r
11809 historyPush: function(className) {\r
11810 if (className && !isInHistory[className] && !Manager.overrideMap[className]) {\r
11811 isInHistory[className] = true;\r
11812 history.push(className);\r
11813 }\r
11814 return Loader;\r
11815 },\r
11816 \r
11817 loadScripts: function(params) {\r
11818 var manifest = Ext.manifest,\r
11819 loadOrder = manifest && manifest.loadOrder,\r
11820 loadOrderMap = manifest && manifest.loadOrderMap,\r
11821 options;\r
11822 ++Loader.scriptsLoading;\r
11823
11824
11825 if (loadOrder && !loadOrderMap) {\r
11826 manifest.loadOrderMap = loadOrderMap = Boot.createLoadOrderMap(loadOrder);\r
11827 }\r
11828
11829
11830 Loader.checkReady();\r
11831 options = Ext.apply({\r
11832 loadOrder: loadOrder,\r
11833 loadOrderMap: loadOrderMap,\r
11834 charset: _config.scriptCharset,\r
11835 success: Loader.onLoadSuccess,\r
11836 failure: Loader.onLoadFailure,\r
11837 sync: Loader.syncModeEnabled,\r
11838 _classNames: []\r
11839 }, params);\r
11840 options.userScope = options.scope;\r
11841 options.scope = options;\r
11842 Boot.load(options);\r
11843 },\r
11844 \r
11845 loadScriptsSync: function(urls) {\r
11846 var syncwas = Loader.syncModeEnabled;\r
11847 Loader.syncModeEnabled = true;\r
11848 Loader.loadScripts({\r
11849 url: urls\r
11850 });\r
11851 Loader.syncModeEnabled = syncwas;\r
11852 },\r
11853 \r
11854 loadScriptsSyncBasePrefix: function(urls) {\r
11855 var syncwas = Loader.syncModeEnabled;\r
11856 Loader.syncModeEnabled = true;\r
11857 Loader.loadScripts({\r
11858 url: urls,\r
11859 prependBaseUrl: true\r
11860 });\r
11861 Loader.syncModeEnabled = syncwas;\r
11862 },\r
11863 \r
11864 loadScript: function(options) {\r
11865 var isString = typeof options === 'string',\r
11866 isArray = options instanceof Array,\r
11867 isObject = !isArray && !isString,\r
11868 url = isObject ? options.url : options,\r
11869 onError = isObject && options.onError,\r
11870 onLoad = isObject && options.onLoad,\r
11871 scope = isObject && options.scope,\r
11872 request = {\r
11873 url: url,\r
11874 scope: scope,\r
11875 onLoad: onLoad,\r
11876 onError: onError,\r
11877 _classNames: []\r
11878 };\r
11879 Loader.loadScripts(request);\r
11880 },\r
11881 \r
11882 flushMissingQueue: function() {\r
11883 var name, val,\r
11884 missingwas = 0,\r
11885 missing = 0;\r
11886 for (name in _missingQueue) {\r
11887 missingwas++;\r
11888 val = _missingQueue[name];\r
11889 if (Manager.isCreated(name)) {\r
11890 delete _missingQueue[name];\r
11891 } else if (Manager.existCache[name] === 2) {\r
11892 delete _missingQueue[name];\r
11893 } else {\r
11894 ++missing;\r
11895 }\r
11896 }\r
11897 this.missingCount = missing;\r
11898 },\r
11899 \r
11900 checkReady: function() {\r
11901 var wasLoading = Loader.isLoading,\r
11902 isLoading;\r
11903 Loader.flushMissingQueue();\r
11904 isLoading = Loader.missingCount + Loader.scriptsLoading;\r
11905 if (isLoading && !wasLoading) {\r
11906 Ready.block();\r
11907 Loader.isLoading = !!isLoading;\r
11908 } else if (!isLoading && wasLoading) {\r
11909 Loader.triggerReady();\r
11910 }\r
11911
11912 if (!Loader.scriptsLoading && Loader.missingCount) {\r
11913
11914
11915 Ext.defer(function() {\r
11916 if (!Loader.scriptsLoading && Loader.missingCount) {\r
11917 Ext.log.error('[Loader] The following classes failed to load:');\r
11918 for (var name in Loader.missingQueue) {\r
11919 Ext.log.error('[Loader] ' + name + ' from ' + Loader.missingQueue[name]);\r
11920 }\r
11921 }\r
11922 }, 1000);\r
11923 }\r
11924 }\r
11925 });\r
11926
11927 \r
11928 Ext.require = alias(Loader, 'require');\r
11929 \r
11930 Ext.syncRequire = alias(Loader, 'syncRequire');\r
11931 \r
11932 Ext.exclude = alias(Loader, 'exclude');\r
11933
11934 \r
11935 Class.registerPreprocessor('loader', function(cls, data, hooks, continueFn) {\r
11936
11937 Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.Loader#loaderPreprocessor', arguments);\r
11938
11939
11940 var me = this,\r
11941 dependencies = [],\r
11942 dependency,\r
11943 className = Manager.getName(cls),\r
11944 i, j, ln, subLn, value, propertyName, propertyValue, requiredMap;\r
11945 \r
11946 for (i = 0 , ln = dependencyProperties.length; i < ln; i++) {\r
11947 propertyName = dependencyProperties[i];\r
11948 if (data.hasOwnProperty(propertyName)) {\r
11949 propertyValue = data[propertyName];\r
11950 if (typeof propertyValue === 'string') {\r
11951 dependencies.push(propertyValue);\r
11952 } else if (propertyValue instanceof Array) {\r
11953 for (j = 0 , subLn = propertyValue.length; j < subLn; j++) {\r
11954 value = propertyValue[j];\r
11955 if (typeof value === 'string') {\r
11956 dependencies.push(value);\r
11957 }\r
11958 }\r
11959 } else if (typeof propertyValue !== 'function') {\r
11960 for (j in propertyValue) {\r
11961 if (propertyValue.hasOwnProperty(j)) {\r
11962 value = propertyValue[j];\r
11963 if (typeof value === 'string') {\r
11964 dependencies.push(value);\r
11965 }\r
11966 }\r
11967 }\r
11968 }\r
11969 }\r
11970 }\r
11971 if (dependencies.length === 0) {\r
11972 return;\r
11973 }\r
11974 if (className) {\r
11975 _requiresMap[className] = dependencies;\r
11976 }\r
11977
11978 var deadlockPath = [],\r
11979 detectDeadlock;\r
11980 \r
11981 if (className) {\r
11982 requiredMap = Loader.requiredByMap || (Loader.requiredByMap = {});\r
11983 for (i = 0 , ln = dependencies.length; i < ln; i++) {\r
11984 dependency = dependencies[i];\r
11985 (requiredMap[dependency] || (requiredMap[dependency] = [])).push(className);\r
11986 }\r
11987 detectDeadlock = function(cls) {\r
11988 deadlockPath.push(cls);\r
11989 if (_requiresMap[cls]) {\r
11990 if (Ext.Array.contains(_requiresMap[cls], className)) {\r
11991 Ext.raise("Circular requirement detected! '" + className + "' and '" + deadlockPath[1] + "' mutually require each other. Path: " + deadlockPath.join(' -> ') + " -> " + deadlockPath[0]);\r
11992 }\r
11993 for (i = 0 , ln = _requiresMap[cls].length; i < ln; i++) {\r
11994 detectDeadlock(_requiresMap[cls][i]);\r
11995 }\r
11996 }\r
11997 };\r
11998 detectDeadlock(className);\r
11999 }\r
12000
12001 (className ? Loader.exclude(className) : Loader).require(dependencies, function() {\r
12002 for (i = 0 , ln = dependencyProperties.length; i < ln; i++) {\r
12003 propertyName = dependencyProperties[i];\r
12004 if (data.hasOwnProperty(propertyName)) {\r
12005 propertyValue = data[propertyName];\r
12006 if (typeof propertyValue === 'string') {\r
12007 data[propertyName] = Manager.get(propertyValue);\r
12008 } else if (propertyValue instanceof Array) {\r
12009 for (j = 0 , subLn = propertyValue.length; j < subLn; j++) {\r
12010 value = propertyValue[j];\r
12011 if (typeof value === 'string') {\r
12012 data[propertyName][j] = Manager.get(value);\r
12013 }\r
12014 }\r
12015 } else if (typeof propertyValue !== 'function') {\r
12016 for (var k in propertyValue) {\r
12017 if (propertyValue.hasOwnProperty(k)) {\r
12018 value = propertyValue[k];\r
12019 if (typeof value === 'string') {\r
12020 data[propertyName][k] = Manager.get(value);\r
12021 }\r
12022 }\r
12023 }\r
12024 }\r
12025 }\r
12026 }\r
12027 continueFn.call(me, cls, data, hooks);\r
12028 });\r
12029 return false;\r
12030 }, true, 'after', 'className');\r
12031 \r
12032 Manager.registerPostprocessor('uses', function(name, cls, data) {\r
12033
12034 Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.Loader#usesPostprocessor', arguments);\r
12035
12036
12037 var manifest = Ext.manifest,\r
12038 loadOrder = manifest && manifest.loadOrder,\r
12039 classes = manifest && manifest.classes,\r
12040 uses, clazz, item, len, i, indexMap;\r
12041 if (loadOrder) {\r
12042 clazz = classes[name];\r
12043 if (clazz && !isNaN(i = clazz.idx)) {\r
12044 item = loadOrder[i];\r
12045 uses = item.uses;\r
12046 indexMap = {};\r
12047 for (len = uses.length , i = 0; i < len; i++) {\r
12048 indexMap[uses[i]] = true;\r
12049 }\r
12050 uses = Ext.Boot.getPathsFromIndexes(indexMap, loadOrder, true);\r
12051 if (uses.length > 0) {\r
12052 Loader.loadScripts({\r
12053 url: uses,\r
12054 sequential: true\r
12055 });\r
12056 }\r
12057 }\r
12058 }\r
12059 if (data.uses) {\r
12060 uses = data.uses;\r
12061 Loader.addUsedClasses(uses);\r
12062 }\r
12063 });\r
12064 Manager.onCreated(Loader.historyPush);\r
12065
12066 Loader.init();\r
12067}());\r
12068
12069
12070Ext._endTime = Ext.ticks();\r
12071
12072
12073
12074if (Ext._beforereadyhandler) {\r
12075 Ext._beforereadyhandler();\r
12076}\r
12077\r
12078\r
12079Ext.define('Ext.Mixin', function(Mixin) {\r
12080 return {\r
12081 statics: {\r
12082 addHook: function(hookFn, targetClass, methodName, mixinClassPrototype) {\r
12083 var isFunc = Ext.isFunction(hookFn),\r
12084 hook = function() {\r
12085 var a = arguments,\r
12086 fn = isFunc ? hookFn : mixinClassPrototype[hookFn],\r
12087 result = this.callParent(a);\r
12088 fn.apply(this, a);\r
12089 return result;\r
12090 },\r
12091 existingFn = targetClass.hasOwnProperty(methodName) && targetClass[methodName];\r
12092 if (isFunc) {\r
12093 hookFn.$previous = Ext.emptyFn;\r
12094 }\r
12095
12096 hook.$name = methodName;\r
12097 hook.$owner = targetClass.self;\r
12098 if (existingFn) {\r
12099 hook.$previous = existingFn.$previous;\r
12100 existingFn.$previous = hook;\r
12101 } else {\r
12102 targetClass[methodName] = hook;\r
12103 }\r
12104 }\r
12105 },\r
12106 onClassExtended: function(cls, data) {\r
12107 var mixinConfig = data.mixinConfig,\r
12108 hooks = data.xhooks,\r
12109 superclass = cls.superclass,\r
12110 onClassMixedIn = data.onClassMixedIn,\r
12111 parentMixinConfig, befores, afters, extended;\r
12112 if (hooks) {\r
12113
12114 delete data.xhooks;\r
12115 (mixinConfig || (data.mixinConfig = mixinConfig = {})).on = hooks;\r
12116 }\r
12117 if (mixinConfig) {\r
12118 parentMixinConfig = superclass.mixinConfig;\r
12119 if (parentMixinConfig) {\r
12120 data.mixinConfig = mixinConfig = Ext.merge({}, parentMixinConfig, mixinConfig);\r
12121 }\r
12122 data.mixinId = mixinConfig.id;\r
12123
12124 if (mixinConfig.beforeHooks) {\r
12125 Ext.raise('Use of "beforeHooks" is deprecated - use "before" instead');\r
12126 }\r
12127 if (mixinConfig.hooks) {\r
12128 Ext.raise('Use of "hooks" is deprecated - use "after" instead');\r
12129 }\r
12130 if (mixinConfig.afterHooks) {\r
12131 Ext.raise('Use of "afterHooks" is deprecated - use "after" instead');\r
12132 }\r
12133
12134 befores = mixinConfig.before;\r
12135 afters = mixinConfig.after;\r
12136 hooks = mixinConfig.on;\r
12137 extended = mixinConfig.extended;\r
12138 }\r
12139 if (befores || afters || hooks || extended) {\r
12140
12141 data.onClassMixedIn = function(targetClass) {\r
12142 var mixin = this.prototype,\r
12143 targetProto = targetClass.prototype,\r
12144 key;\r
12145 if (befores) {\r
12146 Ext.Object.each(befores, function(key, value) {\r
12147 targetClass.addMember(key, function() {\r
12148 if (mixin[value].apply(this, arguments) !== false) {\r
12149 return this.callParent(arguments);\r
12150 }\r
12151 });\r
12152 });\r
12153 }\r
12154 if (afters) {\r
12155 Ext.Object.each(afters, function(key, value) {\r
12156 targetClass.addMember(key, function() {\r
12157 var ret = this.callParent(arguments);\r
12158 mixin[value].apply(this, arguments);\r
12159 return ret;\r
12160 });\r
12161 });\r
12162 }\r
12163 if (hooks) {\r
12164 for (key in hooks) {\r
12165 Mixin.addHook(hooks[key], targetProto, key, mixin);\r
12166 }\r
12167 }\r
12168 if (extended) {\r
12169 targetClass.onExtended(function() {\r
12170 var args = Ext.Array.slice(arguments, 0);\r
12171 args.unshift(targetClass);\r
12172 return extended.apply(this, args);\r
12173 }, this);\r
12174 }\r
12175 if (onClassMixedIn) {\r
12176 onClassMixedIn.apply(this, arguments);\r
12177 }\r
12178 };\r
12179 }\r
12180 }\r
12181 };\r
12182});\r
12183\r
12184
12185\r
12186Ext.util = Ext.util || {};\r
12187Ext.util.DelayedTask = function(fn, scope, args, cancelOnDelay, fireIdleEvent) {\r
12188
12189
12190 var me = this,\r
12191 delay,\r
12192 call = function() {\r
12193 var globalEvents = Ext.GlobalEvents;\r
12194 clearInterval(me.id);\r
12195 me.id = null;\r
12196 fn.apply(scope, args || []);\r
12197 if (fireIdleEvent !== false && globalEvents.hasListeners.idle) {\r
12198 globalEvents.fireEvent('idle');\r
12199 }\r
12200 };\r
12201 cancelOnDelay = typeof cancelOnDelay === 'boolean' ? cancelOnDelay : true;\r
12202 \r
12203 me.id = null;\r
12204 \r
12205 me.delay = function(newDelay, newFn, newScope, newArgs) {\r
12206 if (cancelOnDelay) {\r
12207 me.cancel();\r
12208 }\r
12209 if (typeof newDelay === 'number') {\r
12210 delay = newDelay;\r
12211 }\r
12212 fn = newFn || fn;\r
12213 scope = newScope || scope;\r
12214 args = newArgs || args;\r
12215 if (!me.id) {\r
12216 me.id = Ext.interval(call, delay);\r
12217 }\r
12218 };\r
12219 \r
12220 me.cancel = function() {\r
12221 if (me.id) {\r
12222 clearInterval(me.id);\r
12223 me.id = null;\r
12224 }\r
12225 };\r
12226};\r
12227\r
12228
12229\r
12230Ext.define('Ext.util.Event', function() {\r
12231 var arraySlice = Array.prototype.slice,\r
12232 arrayInsert = Ext.Array.insert,\r
12233 toArray = Ext.Array.toArray,\r
12234 fireArgs = {};\r
12235 return {\r
12236 \r
12237 isEvent: true,\r
12238
12239 suspended: 0,\r
12240 noOptions: {},\r
12241 constructor: function(observable, name) {\r
12242 this.name = name;\r
12243 this.observable = observable;\r
12244 this.listeners = [];\r
12245 },\r
12246 addListener: function(fn, scope, options, caller, manager) {\r
12247 var me = this,\r
12248 added = false,\r
12249 observable = me.observable,\r
12250 eventName = me.name,\r
12251 listeners, listener, priority, isNegativePriority, highestNegativePriorityIndex, hasNegativePriorityIndex, length, index, i, listenerPriority;\r
12252
12253 if (scope && !Ext._namedScopes[scope] && (typeof fn === 'string') && (typeof scope[fn] !== 'function')) {\r
12254 Ext.raise("No method named '" + fn + "' found on scope object");\r
12255 }\r
12256
12257 if (me.findListener(fn, scope) === -1) {\r
12258 listener = me.createListener(fn, scope, options, caller, manager);\r
12259 if (me.firing) {\r
12260
12261 me.listeners = me.listeners.slice(0);\r
12262 }\r
12263 listeners = me.listeners;\r
12264 index = length = listeners.length;\r
12265 priority = options && options.priority;\r
12266 highestNegativePriorityIndex = me._highestNegativePriorityIndex;\r
12267 hasNegativePriorityIndex = highestNegativePriorityIndex !== undefined;\r
12268 if (priority) {\r
12269
12270
12271 isNegativePriority = (priority < 0);\r
12272 if (!isNegativePriority || hasNegativePriorityIndex) {\r
12273
12274
12275
12276
12277
12278
12279 for (i = (isNegativePriority ? highestNegativePriorityIndex : 0); i < length; i++) {\r
12280
12281 listenerPriority = listeners[i].o ? listeners[i].o.priority || 0 : 0;\r
12282 if (listenerPriority < priority) {\r
12283 index = i;\r
12284 break;\r
12285 }\r
12286 }\r
12287 } else {\r
12288
12289
12290
12291 me._highestNegativePriorityIndex = index;\r
12292 }\r
12293 } else if (hasNegativePriorityIndex) {\r
12294
12295
12296
12297
12298 index = highestNegativePriorityIndex;\r
12299 }\r
12300 if (!isNegativePriority && index <= highestNegativePriorityIndex) {\r
12301 me._highestNegativePriorityIndex++;\r
12302 }\r
12303 if (index === length) {\r
12304 listeners[length] = listener;\r
12305 } else {\r
12306 arrayInsert(listeners, index, [\r
12307 listener\r
12308 ]);\r
12309 }\r
12310 if (observable.isElement) {\r
12311
12312
12313
12314
12315
12316
12317 observable._getPublisher(eventName).subscribe(observable, eventName, options.delegated !== false, options.capture);\r
12318 }\r
12319 added = true;\r
12320 }\r
12321 return added;\r
12322 },\r
12323 createListener: function(fn, scope, o, caller, manager) {\r
12324 var me = this,\r
12325 namedScope = Ext._namedScopes[scope],\r
12326 listener = {\r
12327 fn: fn,\r
12328 scope: scope,\r
12329 ev: me,\r
12330 caller: caller,\r
12331 manager: manager,\r
12332 namedScope: namedScope,\r
12333 defaultScope: namedScope ? (scope || me.observable) : undefined,\r
12334 lateBound: typeof fn === 'string'\r
12335 },\r
12336 handler = fn,\r
12337 wrapped = false,\r
12338 type;\r
12339
12340
12341 if (o) {\r
12342 listener.o = o;\r
12343 if (o.single) {\r
12344 handler = me.createSingle(handler, listener, o, scope);\r
12345 wrapped = true;\r
12346 }\r
12347 if (o.target) {\r
12348 handler = me.createTargeted(handler, listener, o, scope, wrapped);\r
12349 wrapped = true;\r
12350 }\r
12351 if (o.delay) {\r
12352 handler = me.createDelayed(handler, listener, o, scope, wrapped);\r
12353 wrapped = true;\r
12354 }\r
12355 if (o.buffer) {\r
12356 handler = me.createBuffered(handler, listener, o, scope, wrapped);\r
12357 wrapped = true;\r
12358 }\r
12359 if (me.observable.isElement) {\r
12360
12361
12362
12363 type = o.type;\r
12364 if (type) {\r
12365 listener.type = type;\r
12366 }\r
12367 }\r
12368 }\r
12369 listener.fireFn = handler;\r
12370 listener.wrapped = wrapped;\r
12371 return listener;\r
12372 },\r
12373 findListener: function(fn, scope) {\r
12374 var listeners = this.listeners,\r
12375 i = listeners.length,\r
12376 listener;\r
12377 while (i--) {\r
12378 listener = listeners[i];\r
12379 if (listener) {\r
12380
12381 if (listener.fn === fn && listener.scope == scope) {\r
12382 return i;\r
12383 }\r
12384 }\r
12385 }\r
12386 return -1;\r
12387 },\r
12388 removeListener: function(fn, scope, index) {\r
12389 var me = this,\r
12390 removed = false,\r
12391 observable = me.observable,\r
12392 eventName = me.name,\r
12393 listener, highestNegativePriorityIndex, options, k, manager, managedListeners, managedListener, i;\r
12394 index = index || me.findListener(fn, scope);\r
12395 if (index != -1) {\r
12396 listener = me.listeners[index];\r
12397 options = listener.o;\r
12398 highestNegativePriorityIndex = me._highestNegativePriorityIndex;\r
12399 if (me.firing) {\r
12400 me.listeners = me.listeners.slice(0);\r
12401 }\r
12402
12403 if (listener.task) {\r
12404 listener.task.cancel();\r
12405 delete listener.task;\r
12406 }\r
12407
12408 k = listener.tasks && listener.tasks.length;\r
12409 if (k) {\r
12410 while (k--) {\r
12411 listener.tasks[k].cancel();\r
12412 }\r
12413 delete listener.tasks;\r
12414 }\r
12415
12416
12417
12418 me.listeners.splice(index, 1);\r
12419 manager = listener.manager;\r
12420 if (manager) {\r
12421
12422
12423
12424
12425
12426
12427
12428
12429 managedListeners = manager.managedListeners;\r
12430 if (managedListeners) {\r
12431 for (i = managedListeners.length; i--; ) {\r
12432 managedListener = managedListeners[i];\r
12433 if (managedListener.item === me.observable && managedListener.ename === eventName && managedListener.fn === fn && managedListener.scope === scope) {\r
12434 managedListeners.splice(i, 1);\r
12435 }\r
12436 }\r
12437 }\r
12438 }\r
12439
12440
12441 if (highestNegativePriorityIndex) {\r
12442 if (index < highestNegativePriorityIndex) {\r
12443 me._highestNegativePriorityIndex--;\r
12444 } else if (index === highestNegativePriorityIndex && index === me.listeners.length) {\r
12445 delete me._highestNegativePriorityIndex;\r
12446 }\r
12447 }\r
12448 if (observable.isElement) {\r
12449 observable._getPublisher(eventName).unsubscribe(observable, eventName, options.delegated !== false, options.capture);\r
12450 }\r
12451 removed = true;\r
12452 }\r
12453 return removed;\r
12454 },\r
12455
12456 clearListeners: function() {\r
12457 var listeners = this.listeners,\r
12458 i = listeners.length,\r
12459 listener;\r
12460 while (i--) {\r
12461 listener = listeners[i];\r
12462 this.removeListener(listener.fn, listener.scope);\r
12463 }\r
12464 },\r
12465 suspend: function() {\r
12466 ++this.suspended;\r
12467 },\r
12468 resume: function() {\r
12469 if (this.suspended) {\r
12470 --this.suspended;\r
12471 }\r
12472 },\r
12473 isSuspended: function() {\r
12474 return this.suspended > 0;\r
12475 },\r
12476 fireDelegated: function(firingObservable, args) {\r
12477 this.firingObservable = firingObservable;\r
12478 return this.fire.apply(this, args);\r
12479 },\r
12480 fire: function() {\r
12481 var me = this,\r
12482 listeners = me.listeners,\r
12483 count = listeners.length,\r
12484 observable = me.observable,\r
12485 isElement = observable.isElement,\r
12486 isComponent = observable.isComponent,\r
12487 firingObservable = me.firingObservable,\r
12488 options, delegate, fireInfo, i, args, listener, len, delegateEl, currentTarget, type, chained, firingArgs, e, fireFn, fireScope;\r
12489 if (!me.suspended && count > 0) {\r
12490 me.firing = true;\r
12491 args = arguments.length ? arraySlice.call(arguments, 0) : [];\r
12492 len = args.length;\r
12493 if (isElement) {\r
12494 e = args[0];\r
12495 }\r
12496 for (i = 0; i < count; i++) {\r
12497 listener = listeners[i];\r
12498 options = listener.o;\r
12499 if (isElement) {\r
12500 if (currentTarget) {\r
12501
12502
12503 e.setCurrentTarget(currentTarget);\r
12504 }\r
12505
12506
12507
12508
12509 type = listener.type;\r
12510 if (type) {\r
12511
12512
12513
12514
12515 chained = e;\r
12516 e = args[0] = chained.chain({\r
12517 type: type\r
12518 });\r
12519 }\r
12520
12521
12522 Ext.EventObject = e;\r
12523 }\r
12524 firingArgs = args;\r
12525 if (options) {\r
12526 delegate = options.delegate;\r
12527 if (delegate) {\r
12528 if (isElement) {\r
12529
12530
12531 delegateEl = e.getTarget('#' + e.currentTarget.id + ' ' + delegate);\r
12532 if (delegateEl) {\r
12533 args[1] = delegateEl;\r
12534
12535
12536 currentTarget = e.currentTarget;\r
12537 e.setCurrentTarget(delegateEl);\r
12538 } else {\r
12539 \r
12540 continue;\r
12541 }\r
12542 } else if (isComponent && !firingObservable.is('#' + observable.id + ' ' + options.delegate)) {\r
12543 \r
12544 continue;\r
12545 }\r
12546 }\r
12547 if (isElement) {\r
12548 if (options.preventDefault) {\r
12549 e.preventDefault();\r
12550 }\r
12551 if (options.stopPropagation) {\r
12552 e.stopPropagation();\r
12553 }\r
12554 if (options.stopEvent) {\r
12555 e.stopEvent();\r
12556 }\r
12557 }\r
12558 args[len] = options;\r
12559 if (options.args) {\r
12560 firingArgs = options.args.concat(args);\r
12561 }\r
12562 }\r
12563 fireInfo = me.getFireInfo(listener);\r
12564 fireFn = fireInfo.fn;\r
12565 fireScope = fireInfo.scope;\r
12566
12567 fireInfo.fn = fireInfo.scope = null;\r
12568 if (fireFn.apply(fireScope, firingArgs) === false) {\r
12569 Ext.EventObject = null;\r
12570 return (me.firing = false);\r
12571 }\r
12572 if (chained) {\r
12573
12574
12575
12576 e = args[0] = chained;\r
12577 chained = null;\r
12578 }\r
12579
12580
12581 Ext.EventObject = null;\r
12582 }\r
12583 }\r
12584 me.firing = false;\r
12585 return true;\r
12586 },\r
12587 getFireInfo: function(listener, fromWrapped) {\r
12588 var observable = this.observable,\r
12589 fireFn = listener.fireFn,\r
12590 scope = listener.scope,\r
12591 namedScope = listener.namedScope,\r
12592 fn;\r
12593
12594
12595 if (!fromWrapped && listener.wrapped) {\r
12596 fireArgs.fn = fireFn;\r
12597 return fireArgs;\r
12598 }\r
12599 fn = fromWrapped ? listener.fn : fireFn;\r
12600
12601 var name = fn;\r
12602
12603 if (listener.lateBound) {\r
12604
12605 if (!scope || namedScope) {\r
12606
12607
12608
12609
12610 scope = (listener.caller || observable).resolveListenerScope(listener.defaultScope);\r
12611 }\r
12612
12613 if (!scope) {\r
12614 Ext.raise('Unable to dynamically resolve scope for "' + listener.ev.name + '" listener on ' + this.observable.id);\r
12615 }\r
12616 if (!Ext.isFunction(scope[fn])) {\r
12617 Ext.raise('No method named "' + fn + '" on ' + (scope.$className || 'scope object.'));\r
12618 }\r
12619
12620 fn = scope[fn];\r
12621 } else if (namedScope && namedScope.isController) {\r
12622
12623
12624 scope = (listener.caller || observable).resolveListenerScope(listener.defaultScope);\r
12625
12626 if (!scope) {\r
12627 Ext.raise('Unable to dynamically resolve scope for "' + listener.ev.name + '" listener on ' + this.observable.id);\r
12628 }\r
12629 }\r
12630
12631 else if (!scope || namedScope) {\r
12632
12633
12634 scope = observable;\r
12635 }\r
12636
12637
12638
12639 fireArgs.fn = fn;\r
12640 fireArgs.scope = scope;\r
12641
12642 if (!fn) {\r
12643 Ext.raise('Unable to dynamically resolve method "' + name + '" on ' + this.observable.$className);\r
12644 }\r
12645
12646 return fireArgs;\r
12647 },\r
12648 createTargeted: function(handler, listener, o, scope, wrapped) {\r
12649 return function() {\r
12650 if (o.target === arguments[0]) {\r
12651 var fireInfo;\r
12652 if (!wrapped) {\r
12653 fireInfo = listener.ev.getFireInfo(listener, true);\r
12654 handler = fireInfo.fn;\r
12655 scope = fireInfo.scope;\r
12656
12657 fireInfo.fn = fireInfo.scope = null;\r
12658 }\r
12659 return handler.apply(scope, arguments);\r
12660 }\r
12661 };\r
12662 },\r
12663 createBuffered: function(handler, listener, o, scope, wrapped) {\r
12664 listener.task = new Ext.util.DelayedTask();\r
12665 return function() {\r
12666 var fireInfo;\r
12667 if (!wrapped) {\r
12668 fireInfo = listener.ev.getFireInfo(listener, true);\r
12669 handler = fireInfo.fn;\r
12670 scope = fireInfo.scope;\r
12671
12672 fireInfo.fn = fireInfo.scope = null;\r
12673 }\r
12674 listener.task.delay(o.buffer, handler, scope, toArray(arguments));\r
12675 };\r
12676 },\r
12677 createDelayed: function(handler, listener, o, scope, wrapped) {\r
12678 return function() {\r
12679 var task = new Ext.util.DelayedTask(),\r
12680 fireInfo;\r
12681 if (!wrapped) {\r
12682 fireInfo = listener.ev.getFireInfo(listener, true);\r
12683 handler = fireInfo.fn;\r
12684 scope = fireInfo.scope;\r
12685
12686 fireInfo.fn = fireInfo.scope = null;\r
12687 }\r
12688 if (!listener.tasks) {\r
12689 listener.tasks = [];\r
12690 }\r
12691 listener.tasks.push(task);\r
12692 task.delay(o.delay || 10, handler, scope, toArray(arguments));\r
12693 };\r
12694 },\r
12695 createSingle: function(handler, listener, o, scope, wrapped) {\r
12696 return function() {\r
12697 var event = listener.ev,\r
12698 fireInfo;\r
12699 if (event.removeListener(listener.fn, scope) && event.observable) {\r
12700
12701
12702 event.observable.hasListeners[event.name]--;\r
12703 }\r
12704 if (!wrapped) {\r
12705 fireInfo = event.getFireInfo(listener, true);\r
12706 handler = fireInfo.fn;\r
12707 scope = fireInfo.scope;\r
12708
12709 fireInfo.fn = fireInfo.scope = null;\r
12710 }\r
12711 return handler.apply(scope, arguments);\r
12712 };\r
12713 }\r
12714 };\r
12715});\r
12716\r
12717
12718\r
12719Ext.define('Ext.mixin.Identifiable', {\r
12720 statics: {\r
12721 uniqueIds: {}\r
12722 },\r
12723 isIdentifiable: true,\r
12724 mixinId: 'identifiable',\r
12725 idCleanRegex: /\.|[^\w\-]/g,\r
12726 defaultIdPrefix: 'ext-',\r
12727 defaultIdSeparator: '-',\r
12728 getOptimizedId: function() {\r
12729 return this.id;\r
12730 },\r
12731 getUniqueId: function() {\r
12732 var id = this.id,\r
12733 prototype, separator, xtype, uniqueIds, prefix;\r
12734
12735 if (!(id || id === 0)) {\r
12736 prototype = this.self.prototype;\r
12737 separator = this.defaultIdSeparator;\r
12738 uniqueIds = Ext.mixin.Identifiable.uniqueIds;\r
12739 if (!prototype.hasOwnProperty('identifiablePrefix')) {\r
12740 xtype = this.xtype;\r
12741 if (xtype) {\r
12742 prefix = this.defaultIdPrefix + xtype.replace(this.idCleanRegex, separator) + separator;\r
12743 } else if (!(prefix = prototype.$className)) {\r
12744 prefix = this.defaultIdPrefix + 'anonymous' + separator;\r
12745 } else {\r
12746 prefix = prefix.replace(this.idCleanRegex, separator).toLowerCase() + separator;\r
12747 }\r
12748 prototype.identifiablePrefix = prefix;\r
12749 }\r
12750 prefix = this.identifiablePrefix;\r
12751 if (!uniqueIds.hasOwnProperty(prefix)) {\r
12752 uniqueIds[prefix] = 0;\r
12753 }\r
12754
12755
12756
12757 id = this.id = this.id = prefix + (++uniqueIds[prefix]);\r
12758 }\r
12759 this.getUniqueId = this.getOptimizedId;\r
12760 return id;\r
12761 },\r
12762 setId: function(id) {\r
12763
12764 this.id = this.id = id;\r
12765 },\r
12766 \r
12767 getId: function() {\r
12768 var id = this.id;\r
12769 if (!id) {\r
12770 id = this.getUniqueId();\r
12771 }\r
12772 this.getId = this.getOptimizedId;\r
12773 return id;\r
12774 }\r
12775});\r
12776\r
12777
12778\r
12779Ext.define('Ext.mixin.Observable', function(Observable) {\r
12780 var emptyFn = Ext.emptyFn,\r
12781 emptyArray = [],\r
12782 arrayProto = Array.prototype,\r
12783 arraySlice = arrayProto.slice,\r
12784
12785 ListenerRemover = function(observable) {\r
12786
12787 if (observable instanceof ListenerRemover) {\r
12788 return observable;\r
12789 }\r
12790 this.observable = observable;\r
12791
12792
12793 if (arguments[1].isObservable) {\r
12794 this.managedListeners = true;\r
12795 }\r
12796 this.args = arraySlice.call(arguments, 1);\r
12797 };\r
12798 ListenerRemover.prototype.destroy = function() {\r
12799 this.destroy = Ext.emptyFn;\r
12800 var observable = this.observable;\r
12801 observable[this.managedListeners ? 'mun' : 'un'].apply(observable, this.args);\r
12802 };\r
12803 return {\r
12804 extend: Ext.Mixin,\r
12805 mixinConfig: {\r
12806 id: 'observable',\r
12807 after: {\r
12808 destroy: 'clearListeners'\r
12809 }\r
12810 },\r
12811 mixins: [\r
12812 Ext.mixin.Identifiable\r
12813 ],\r
12814 statics: {\r
12815 \r
12816 releaseCapture: function(o) {\r
12817 o.fireEventArgs = this.prototype.fireEventArgs;\r
12818 },\r
12819 \r
12820 capture: function(o, fn, scope) {\r
12821
12822
12823
12824
12825 var newFn = function(eventName, args) {\r
12826 return fn.apply(scope, [\r
12827 eventName\r
12828 ].concat(args));\r
12829 };\r
12830 this.captureArgs(o, newFn, scope);\r
12831 },\r
12832 \r
12833 captureArgs: function(o, fn, scope) {\r
12834 o.fireEventArgs = Ext.Function.createInterceptor(o.fireEventArgs, fn, scope);\r
12835 },\r
12836 \r
12837 observe: function(cls, listeners) {\r
12838 if (cls) {\r
12839 if (!cls.isObservable) {\r
12840 Ext.applyIf(cls, new this());\r
12841 this.captureArgs(cls.prototype, cls.fireEventArgs, cls);\r
12842 }\r
12843 if (Ext.isObject(listeners)) {\r
12844 cls.on(listeners);\r
12845 }\r
12846 }\r
12847 return cls;\r
12848 },\r
12849 \r
12850 prepareClass: function(T, mixin, data) {\r
12851
12852
12853
12854
12855 var listeners = T.listeners = [],\r
12856
12857
12858
12859
12860 target = data || T.prototype,\r
12861 targetListeners = target.listeners,\r
12862 superListeners = mixin ? mixin.listeners : T.superclass.self.listeners,\r
12863 name, scope, namedScope;\r
12864
12865
12866
12867
12868 if (superListeners) {\r
12869 listeners.push(superListeners);\r
12870 }\r
12871 if (targetListeners) {\r
12872
12873
12874
12875
12876
12877
12878
12879
12880
12881 scope = targetListeners.scope;\r
12882 if (!scope) {\r
12883 targetListeners.scope = 'self';\r
12884 } else {\r
12885 namedScope = Ext._namedScopes[scope];\r
12886 if (namedScope && namedScope.isController) {\r
12887 targetListeners.scope = 'self.controller';\r
12888 }\r
12889 }\r
12890 listeners.push(targetListeners);\r
12891
12892
12893
12894
12895
12896 target.listeners = null;\r
12897 }\r
12898 if (!T.HasListeners) {\r
12899
12900
12901
12902 var HasListeners = function() {},\r
12903 SuperHL = T.superclass.HasListeners || (mixin && mixin.HasListeners) || Observable.HasListeners;\r
12904
12905 T.prototype.HasListeners = T.HasListeners = HasListeners;\r
12906
12907
12908 HasListeners.prototype = T.hasListeners = new SuperHL();\r
12909 }\r
12910 }\r
12911 },\r
12912 \r
12913 \r
12914 \r
12915 isObservable: true,\r
12916 \r
12917 eventsSuspended: 0,\r
12918 \r
12919 constructor: function(config) {\r
12920 var me = this,\r
12921 self = me.self,\r
12922 declaredListeners, listeners, bubbleEvents, len, i;\r
12923
12924
12925
12926
12927 if (me.$observableInitialized) {\r
12928 return;\r
12929 }\r
12930 me.$observableInitialized = true;\r
12931 me.hasListeners = new me.HasListeners();\r
12932 me.eventedBeforeEventNames = {};\r
12933 me.events = me.events || {};\r
12934 declaredListeners = self.listeners;\r
12935 if (declaredListeners && !me._addDeclaredListeners(declaredListeners)) {\r
12936
12937
12938
12939 self.listeners = null;\r
12940 }\r
12941 listeners = (config && config.listeners) || me.listeners;\r
12942 if (listeners) {\r
12943 if (listeners instanceof Array) {\r
12944
12945
12946
12947
12948
12949
12950 for (i = 0 , len = listeners.length; i < len; ++i) {\r
12951 me.addListener(listeners[i]);\r
12952 }\r
12953 } else {\r
12954 me.addListener(listeners);\r
12955 }\r
12956 }\r
12957 bubbleEvents = (config && config.bubbleEvents) || me.bubbleEvents;\r
12958 if (bubbleEvents) {\r
12959 me.enableBubble(bubbleEvents);\r
12960 }\r
12961 if (me.$applyConfigs) {\r
12962
12963 if (config) {\r
12964 Ext.apply(me, config);\r
12965 }\r
12966 } else {\r
12967
12968 me.initConfig(config);\r
12969 }\r
12970 if (listeners) {\r
12971
12972
12973
12974 me.listeners = null;\r
12975 }\r
12976 },\r
12977 onClassExtended: function(T, data) {\r
12978 if (!T.HasListeners) {\r
12979
12980
12981 Observable.prepareClass(T, T.prototype.$observableMixedIn ? undefined : data);\r
12982 }\r
12983 },\r
12984 \r
12985 $eventOptions: {\r
12986 scope: 1,\r
12987 delay: 1,\r
12988 buffer: 1,\r
12989 onFrame: 1,\r
12990 single: 1,\r
12991 args: 1,\r
12992 destroyable: 1,\r
12993 priority: 1,\r
12994 order: 1\r
12995 },\r
12996 $orderToPriority: {\r
12997 before: 100,\r
12998 current: 0,\r
12999 after: -100\r
13000 },\r
13001 \r
13002 _addDeclaredListeners: function(listeners) {\r
13003 var me = this;\r
13004 if (listeners instanceof Array) {\r
13005 Ext.each(listeners, me._addDeclaredListeners, me);\r
13006 } else {\r
13007 me._addedDeclaredListeners = true;\r
13008 me.addListener(listeners);\r
13009 }\r
13010 return me._addedDeclaredListeners;\r
13011 },\r
13012 \r
13013 addManagedListener: function(item, ename, fn, scope, options, \r
13014 noDestroy) {\r
13015 var me = this,\r
13016 managedListeners = me.managedListeners = me.managedListeners || [],\r
13017 config, passedOptions;\r
13018 if (typeof ename !== 'string') {\r
13019
13020
13021
13022
13023 passedOptions = arguments.length > 4 ? options : ename;\r
13024 options = ename;\r
13025 for (ename in options) {\r
13026 if (options.hasOwnProperty(ename)) {\r
13027 config = options[ename];\r
13028 if (!item.$eventOptions[ename]) {\r
13029
13030
13031 me.addManagedListener(item, ename, config.fn || config, config.scope || options.scope || scope, config.fn ? config : passedOptions, true);\r
13032 }\r
13033 }\r
13034 }\r
13035 if (options && options.destroyable) {\r
13036 return new ListenerRemover(me, item, options);\r
13037 }\r
13038 } else {\r
13039 if (fn !== emptyFn) {\r
13040 item.doAddListener(ename, fn, scope, options, null, me, me);\r
13041
13042 if (!noDestroy && options && options.destroyable) {\r
13043 return new ListenerRemover(me, item, ename, fn, scope);\r
13044 }\r
13045 }\r
13046 }\r
13047 },\r
13048 \r
13049 removeManagedListener: function(item, ename, fn, scope) {\r
13050 var me = this,\r
13051 options, config, managedListeners, length, i;\r
13052 if (typeof ename !== 'string') {\r
13053 options = ename;\r
13054 for (ename in options) {\r
13055 if (options.hasOwnProperty(ename)) {\r
13056 config = options[ename];\r
13057 if (!item.$eventOptions[ename]) {\r
13058 me.removeManagedListener(item, ename, config.fn || config, config.scope || options.scope || scope);\r
13059 }\r
13060 }\r
13061 }\r
13062 } else {\r
13063 managedListeners = me.managedListeners ? me.managedListeners.slice() : [];\r
13064 ename = Ext.canonicalEventName(ename);\r
13065 for (i = 0 , length = managedListeners.length; i < length; i++) {\r
13066 me.removeManagedListenerItem(false, managedListeners[i], item, ename, fn, scope);\r
13067 }\r
13068 }\r
13069 },\r
13070 \r
13071 fireEvent: function(eventName) {\r
13072 return this.fireEventArgs(eventName, arraySlice.call(arguments, 1));\r
13073 },\r
13074 \r
13075 resolveListenerScope: function(defaultScope) {\r
13076 var namedScope = Ext._namedScopes[defaultScope];\r
13077 if (namedScope) {\r
13078
13079 if (namedScope.isController) {\r
13080 Ext.raise('scope: "controller" can only be specified on classes that derive from Ext.Component or Ext.Widget');\r
13081 }\r
13082
13083 if (namedScope.isSelf || namedScope.isThis) {\r
13084 defaultScope = null;\r
13085 }\r
13086 }\r
13087 return defaultScope || this;\r
13088 },\r
13089 \r
13090 fireEventArgs: function(eventName, args) {\r
13091 eventName = Ext.canonicalEventName(eventName);\r
13092 var me = this,\r
13093
13094 events = me.events,\r
13095 event = events && events[eventName],\r
13096 ret = true;\r
13097
13098
13099 if (me.hasListeners[eventName]) {\r
13100 ret = me.doFireEvent(eventName, args || emptyArray, event ? event.bubble : false);\r
13101 }\r
13102 return ret;\r
13103 },\r
13104 \r
13105 fireAction: function(eventName, args, fn, scope, options, order) {\r
13106
13107 if (typeof fn === 'string' && !scope) {\r
13108 fn = this[fn];\r
13109 }\r
13110
13111 options = options ? Ext.Object.chain(options) : {};\r
13112 options.single = true;\r
13113 options.priority = ((order === 'after') ? -99.5 : 99.5);\r
13114 this.doAddListener(eventName, fn, scope, options);\r
13115 this.fireEventArgs(eventName, args);\r
13116 },\r
13117 $eventedController: {\r
13118 _paused: 1,\r
13119 pause: function() {\r
13120 ++this._paused;\r
13121 },\r
13122 resume: function() {\r
13123 var me = this,\r
13124 fn = me.fn,\r
13125 scope = me.scope,\r
13126 fnArgs = me.fnArgs,\r
13127 owner = me.owner,\r
13128 args, ret;\r
13129 if (!--me._paused) {\r
13130 if (fn) {\r
13131 args = Ext.Array.slice(fnArgs || me.args);\r
13132 if (fnArgs === false) {\r
13133
13134 args.shift();\r
13135 }\r
13136 me.fn = null;\r
13137
13138 args.push(me);\r
13139 if (Ext.isFunction(fn)) {\r
13140 ret = fn.apply(scope, args);\r
13141 } else if (scope && Ext.isString(fn) && Ext.isFunction(scope[fn])) {\r
13142 ret = scope[fn].apply(scope, args);\r
13143 }\r
13144 if (ret === false) {\r
13145 return false;\r
13146 }\r
13147 }\r
13148 if (!me._paused) {\r
13149
13150 return me.owner.fireEventArgs(me.eventName, me.args);\r
13151 }\r
13152 }\r
13153 }\r
13154 },\r
13155 \r
13156 fireEventedAction: function(eventName, args, fn, scope, fnArgs) {\r
13157 var me = this,\r
13158 eventedBeforeEventNames = me.eventedBeforeEventNames,\r
13159 beforeEventName = eventedBeforeEventNames[eventName] || (eventedBeforeEventNames[eventName] = 'before' + eventName),\r
13160 controller = Ext.apply({\r
13161 owner: me,\r
13162 eventName: eventName,\r
13163 fn: fn,\r
13164 scope: scope,\r
13165 fnArgs: fnArgs,\r
13166 args: args\r
13167 }, me.$eventedController),\r
13168 value;\r
13169 args.push(controller);\r
13170 value = me.fireEventArgs(beforeEventName, args);\r
13171 args.pop();\r
13172 if (value === false) {\r
13173 return false;\r
13174 }\r
13175 return controller.resume();\r
13176 },\r
13177 \r
13178 doFireEvent: function(eventName, args, bubbles) {\r
13179 var target = this,\r
13180 queue, event,\r
13181 ret = true;\r
13182 do {\r
13183 if (target.eventsSuspended) {\r
13184 if ((queue = target.eventQueue)) {\r
13185 queue.push([\r
13186 eventName,\r
13187 args\r
13188 ]);\r
13189 }\r
13190 return ret;\r
13191 } else {\r
13192 event = target.events && target.events[eventName];\r
13193 if (event && event !== true) {\r
13194 if ((ret = event.fire.apply(event, args)) === false) {\r
13195 break;\r
13196 }\r
13197 }\r
13198 }\r
13199 } while (
13200
13201 bubbles && (target = target.getBubbleParent()));\r
13202 return ret;\r
13203 },\r
13204 \r
13205 getBubbleParent: function() {\r
13206 var me = this,\r
13207 parent = me.getBubbleTarget && me.getBubbleTarget();\r
13208 if (parent && parent.isObservable) {\r
13209 return parent;\r
13210 }\r
13211 return null;\r
13212 },\r
13213 \r
13214 addListener: function(ename, fn, scope, options, order, \r
13215 caller) {\r
13216 var me = this,\r
13217 namedScopes = Ext._namedScopes,\r
13218 config, namedScope, isClassListener, innerScope, eventOptions;\r
13219
13220 if (typeof ename !== 'string') {\r
13221 options = ename;\r
13222 scope = options.scope;\r
13223 namedScope = scope && namedScopes[scope];\r
13224 isClassListener = namedScope && namedScope.isSelf;\r
13225
13226
13227 eventOptions = ((me.isComponent || me.isWidget) && options.element) ? me.$elementEventOptions : me.$eventOptions;\r
13228 for (ename in options) {\r
13229 config = options[ename];\r
13230 if (!eventOptions[ename]) {\r
13231 \r
13232 innerScope = config.scope;\r
13233
13234
13235
13236
13237
13238 if (innerScope && isClassListener) {\r
13239 namedScope = namedScopes[innerScope];\r
13240 if (namedScope && namedScope.isController) {\r
13241 innerScope = 'self.controller';\r
13242 }\r
13243 }\r
13244 me.doAddListener(ename, config.fn || config, innerScope || scope, config.fn ? config : options, order, caller);\r
13245 }\r
13246 }\r
13247 if (options && options.destroyable) {\r
13248 return new ListenerRemover(me, options);\r
13249 }\r
13250 } else {\r
13251 me.doAddListener(ename, fn, scope, options, order, caller);\r
13252 if (options && options.destroyable) {\r
13253 return new ListenerRemover(me, ename, fn, scope, options);\r
13254 }\r
13255 }\r
13256 return me;\r
13257 },\r
13258 \r
13259 removeListener: function(ename, fn, scope, \r
13260 eventOptions) {\r
13261 var me = this,\r
13262 config, options;\r
13263 if (typeof ename !== 'string') {\r
13264 options = ename;\r
13265
13266
13267 eventOptions = eventOptions || me.$eventOptions;\r
13268 for (ename in options) {\r
13269 if (options.hasOwnProperty(ename)) {\r
13270 config = options[ename];\r
13271 if (!me.$eventOptions[ename]) {\r
13272 me.doRemoveListener(ename, config.fn || config, config.scope || options.scope);\r
13273 }\r
13274 }\r
13275 }\r
13276 } else {\r
13277 me.doRemoveListener(ename, fn, scope);\r
13278 }\r
13279 return me;\r
13280 },\r
13281 \r
13282 onBefore: function(eventName, fn, scope, options) {\r
13283 return this.addListener(eventName, fn, scope, options, 'before');\r
13284 },\r
13285 \r
13286 onAfter: function(eventName, fn, scope, options) {\r
13287 return this.addListener(eventName, fn, scope, options, 'after');\r
13288 },\r
13289 \r
13290 unBefore: function(eventName, fn, scope, options) {\r
13291 return this.removeListener(eventName, fn, scope, options, 'before');\r
13292 },\r
13293 \r
13294 unAfter: function(eventName, fn, scope, options) {\r
13295 return this.removeListener(eventName, fn, scope, options, 'after');\r
13296 },\r
13297 \r
13298 addBeforeListener: function() {\r
13299 return this.onBefore.apply(this, arguments);\r
13300 },\r
13301 \r
13302 addAfterListener: function() {\r
13303 return this.onAfter.apply(this, arguments);\r
13304 },\r
13305 \r
13306 removeBeforeListener: function() {\r
13307 return this.unBefore.apply(this, arguments);\r
13308 },\r
13309 \r
13310 removeAfterListener: function() {\r
13311 return this.unAfter.apply(this, arguments);\r
13312 },\r
13313 \r
13314 clearListeners: function() {\r
13315 var me = this,\r
13316 events = me.events,\r
13317 hasListeners = me.hasListeners,\r
13318 event, key;\r
13319 if (events) {\r
13320 for (key in events) {\r
13321 if (events.hasOwnProperty(key)) {\r
13322 event = events[key];\r
13323 if (event.isEvent) {\r
13324 delete hasListeners[key];\r
13325 event.clearListeners();\r
13326 }\r
13327 }\r
13328 }\r
13329 me.events = null;\r
13330 }\r
13331 me.clearManagedListeners();\r
13332 },\r
13333
13334 purgeListeners: function() {\r
13335 if (Ext.global.console) {\r
13336 Ext.global.console.warn('Observable: purgeListeners has been deprecated. Please use clearListeners.');\r
13337 }\r
13338 return this.clearListeners.apply(this, arguments);\r
13339 },\r
13340
13341 \r
13342 clearManagedListeners: function() {\r
13343 var me = this,\r
13344 managedListeners = me.managedListeners ? me.managedListeners.slice() : [],\r
13345 i = 0,\r
13346 len = managedListeners.length;\r
13347 for (; i < len; i++) {\r
13348 me.removeManagedListenerItem(true, managedListeners[i]);\r
13349 }\r
13350 me.managedListeners = [];\r
13351 },\r
13352 \r
13353 removeManagedListenerItem: function(isClear, managedListener, item, ename, fn, scope) {\r
13354 if (isClear || (managedListener.item === item && managedListener.ename === ename && (!fn || managedListener.fn === fn) && (!scope || managedListener.scope === scope))) {\r
13355
13356 managedListener.item.doRemoveListener(managedListener.ename, managedListener.fn, managedListener.scope, managedListener.options);\r
13357 if (!isClear) {\r
13358 Ext.Array.remove(this.managedListeners, managedListener);\r
13359 }\r
13360 }\r
13361 },\r
13362
13363 purgeManagedListeners: function() {\r
13364 if (Ext.global.console) {\r
13365 Ext.global.console.warn('Observable: purgeManagedListeners has been deprecated. Please use clearManagedListeners.');\r
13366 }\r
13367 return this.clearManagedListeners.apply(this, arguments);\r
13368 },\r
13369
13370 \r
13371 hasListener: function(ename) {\r
13372 ename = Ext.canonicalEventName(ename);\r
13373 return !!this.hasListeners[ename];\r
13374 },\r
13375 \r
13376 isSuspended: function(event) {\r
13377 var suspended = this.eventsSuspended > 0,\r
13378 events = this.events;\r
13379 if (!suspended && event && events) {\r
13380 event = events[event];\r
13381 if (event && event.isEvent) {\r
13382 return event.isSuspended();\r
13383 }\r
13384 }\r
13385 return suspended;\r
13386 },\r
13387 \r
13388 suspendEvents: function(queueSuspended) {\r
13389 ++this.eventsSuspended;\r
13390 if (queueSuspended && !this.eventQueue) {\r
13391 this.eventQueue = [];\r
13392 }\r
13393 },\r
13394 \r
13395 suspendEvent: function() {\r
13396 var me = this,\r
13397 events = me.events,\r
13398 len = arguments.length,\r
13399 i, event, ename;\r
13400 for (i = 0; i < len; i++) {\r
13401 ename = arguments[i];\r
13402 ename = Ext.canonicalEventName(ename);\r
13403 event = events[ename];\r
13404
13405 if (!event || !event.isEvent) {\r
13406 event = me._initEvent(ename);\r
13407 }\r
13408 event.suspend();\r
13409 }\r
13410 },\r
13411 \r
13412 resumeEvent: function() {\r
13413 var events = this.events || 0,\r
13414 len = events && arguments.length,\r
13415 i, event;\r
13416 for (i = 0; i < len; i++) {\r
13417
13418 event = events[arguments[i]];\r
13419 if (event && event.resume) {\r
13420 event.resume();\r
13421 }\r
13422 }\r
13423 },\r
13424 \r
13425 resumeEvents: function(discardQueue) {\r
13426 var me = this,\r
13427 queued = me.eventQueue,\r
13428 qLen, q;\r
13429 if (me.eventsSuspended && !--me.eventsSuspended) {\r
13430 delete me.eventQueue;\r
13431 if (!discardQueue && queued) {\r
13432 qLen = queued.length;\r
13433 for (q = 0; q < qLen; q++) {\r
13434
13435 me.fireEventArgs.apply(me, queued[q]);\r
13436 }\r
13437 }\r
13438 }\r
13439 },\r
13440 \r
13441 relayEvents: function(origin, events, prefix) {\r
13442 var me = this,\r
13443 len = events.length,\r
13444 i = 0,\r
13445 oldName, newName,\r
13446 relayers = {};\r
13447 if (Ext.isObject(events)) {\r
13448 for (i in events) {\r
13449 newName = events[i];\r
13450 relayers[i] = me.createRelayer(newName);\r
13451 }\r
13452 } else {\r
13453 for (; i < len; i++) {\r
13454 oldName = events[i];\r
13455
13456 relayers[oldName] = me.createRelayer(prefix ? prefix + oldName : oldName);\r
13457 }\r
13458 }\r
13459
13460
13461
13462 me.mon(origin, relayers, null, null, undefined);\r
13463
13464 return new ListenerRemover(me, origin, relayers);\r
13465 },\r
13466 \r
13467 createRelayer: function(newName, beginEnd) {\r
13468 var me = this;\r
13469 return function() {\r
13470 return me.fireEventArgs.call(me, newName, beginEnd ? arraySlice.apply(arguments, beginEnd) : arguments);\r
13471 };\r
13472 },\r
13473 \r
13474 enableBubble: function(eventNames) {\r
13475 if (eventNames) {\r
13476 var me = this,\r
13477 names = (typeof eventNames == 'string') ? arguments : eventNames,\r
13478
13479 events = me.events,\r
13480 length = events && names.length,\r
13481 ename, event, i;\r
13482 for (i = 0; i < length; ++i) {\r
13483 ename = names[i];\r
13484 ename = Ext.canonicalEventName(ename);\r
13485 event = events[ename];\r
13486 if (!event || !event.isEvent) {\r
13487 event = me._initEvent(ename);\r
13488 }\r
13489
13490
13491 me.hasListeners._incr_(ename);\r
13492 event.bubble = true;\r
13493 }\r
13494 }\r
13495 },\r
13496 destroy: function() {\r
13497 this.clearListeners();\r
13498 this.callParent();\r
13499 },\r
13500 privates: {\r
13501 doAddListener: function(ename, fn, scope, options, order, caller, manager) {\r
13502 var me = this,\r
13503 event, managedListeners, priority;\r
13504 order = order || (options && options.order);\r
13505 if (order) {\r
13506 priority = (options && options.priority);\r
13507 if (!priority) {\r
13508
13509
13510 options = options ? Ext.Object.chain(options) : {};\r
13511 options.priority = me.$orderToPriority[order];\r
13512 }\r
13513 }\r
13514 ename = Ext.canonicalEventName(ename);\r
13515
13516 if (!fn) {\r
13517 Ext.raise("Cannot add '" + ename + "' listener to " + me.$className + " instance. No function specified.");\r
13518 }\r
13519
13520 if (!manager && (scope && scope.isObservable && (scope !== me))) {\r
13521 manager = scope;\r
13522 }\r
13523 if (manager) {\r
13524
13525
13526 managedListeners = manager.managedListeners = manager.managedListeners || [];\r
13527 managedListeners.push({\r
13528 item: me,\r
13529 ename: ename,\r
13530 fn: fn,\r
13531 scope: scope,\r
13532 options: options\r
13533 });\r
13534 }\r
13535 event = (me.events || (me.events = {}))[ename];\r
13536 if (!event || !event.isEvent) {\r
13537 event = me._initEvent(ename);\r
13538 }\r
13539 if (fn !== emptyFn) {\r
13540 if (event.addListener(fn, scope, options, caller, manager)) {\r
13541
13542
13543 me.hasListeners._incr_(ename);\r
13544 }\r
13545 }\r
13546 },\r
13547 doRemoveListener: function(ename, fn, scope) {\r
13548 var me = this,\r
13549 events = me.events,\r
13550 event;\r
13551 ename = Ext.canonicalEventName(ename);\r
13552 event = events && events[ename];\r
13553
13554 if (!fn) {\r
13555 Ext.raise("Cannot remove '" + ename + "' listener to " + me.$className + " instance. No function specified.");\r
13556 }\r
13557
13558 if (event && event.isEvent) {\r
13559 if (event.removeListener(fn, scope)) {\r
13560 me.hasListeners._decr_(ename);\r
13561 }\r
13562 }\r
13563 },\r
13564 _initEvent: function(eventName) {\r
13565 return (this.events[eventName] = new Ext.util.Event(this, eventName));\r
13566 }\r
13567 },\r
13568 deprecated: {\r
13569 '5.0': {\r
13570 methods: {\r
13571 addEvents: null\r
13572 }\r
13573 }\r
13574 }\r
13575 };\r
13576}, function() {\r
13577 var Observable = this,\r
13578 proto = Observable.prototype,\r
13579 HasListeners = function() {},\r
13580 prepareMixin = function(T) {\r
13581 if (!T.HasListeners) {\r
13582 var proto = T.prototype;\r
13583
13584
13585 proto.$observableMixedIn = 1;\r
13586
13587 Observable.prepareClass(T, this);\r
13588
13589
13590 T.onExtended(function(U, data) {\r
13591
13592 Ext.classSystemMonitor && Ext.classSystemMonitor('extend mixin', arguments);\r
13593
13594 Observable.prepareClass(U, null, data);\r
13595 });\r
13596
13597
13598 if (proto.onClassMixedIn) {\r
13599
13600 Ext.override(T, {\r
13601 onClassMixedIn: function(U) {\r
13602 prepareMixin.call(this, U);\r
13603 this.callParent(arguments);\r
13604 }\r
13605 });\r
13606 } else {\r
13607
13608 proto.onClassMixedIn = function(U) {\r
13609 prepareMixin.call(this, U);\r
13610 };\r
13611 }\r
13612 }\r
13613 superOnClassMixedIn.call(this, T);\r
13614 },\r
13615
13616
13617 superOnClassMixedIn = proto.onClassMixedIn;\r
13618 HasListeners.prototype = {\r
13619
13620 _decr_: function(ev, count) {\r
13621
13622
13623
13624 if (count == null) {\r
13625 count = 1;\r
13626 }\r
13627 if (!(this[ev] -= count)) {\r
13628
13629
13630
13631 delete this[ev];\r
13632 }\r
13633 },\r
13634 _incr_: function(ev) {\r
13635 if (this.hasOwnProperty(ev)) {\r
13636
13637 ++this[ev];\r
13638 } else {\r
13639
13640
13641 this[ev] = 1;\r
13642 }\r
13643 }\r
13644 };\r
13645 proto.HasListeners = Observable.HasListeners = HasListeners;\r
13646 Observable.createAlias({\r
13647 \r
13648 on: 'addListener',\r
13649 \r
13650 un: 'removeListener',\r
13651 \r
13652 mon: 'addManagedListener',\r
13653 \r
13654 mun: 'removeManagedListener',\r
13655 \r
13656 setListeners: 'addListener'\r
13657 });\r
13658
13659 Observable.observeClass = Observable.observe;\r
13660
13661
13662
13663 function getMethodEvent(method) {\r
13664 var e = (this.methodEvents = this.methodEvents || {})[method],\r
13665 returnValue, v, cancel,\r
13666 obj = this,\r
13667 makeCall;\r
13668 if (!e) {\r
13669 this.methodEvents[method] = e = {};\r
13670 e.originalFn = this[method];\r
13671 e.methodName = method;\r
13672 e.before = [];\r
13673 e.after = [];\r
13674 makeCall = function(fn, scope, args) {\r
13675 if ((v = fn.apply(scope || obj, args)) !== undefined) {\r
13676 if (typeof v == 'object') {\r
13677 if (v.returnValue !== undefined) {\r
13678 returnValue = v.returnValue;\r
13679 } else {\r
13680 returnValue = v;\r
13681 }\r
13682 cancel = !!v.cancel;\r
13683 } else if (v === false) {\r
13684 cancel = true;\r
13685 } else {\r
13686 returnValue = v;\r
13687 }\r
13688 }\r
13689 };\r
13690 this[method] = function() {\r
13691 var args = Array.prototype.slice.call(arguments, 0),\r
13692 b, i, len;\r
13693 returnValue = v = undefined;\r
13694 cancel = false;\r
13695 for (i = 0 , len = e.before.length; i < len; i++) {\r
13696 b = e.before[i];\r
13697 makeCall(b.fn, b.scope, args);\r
13698 if (cancel) {\r
13699 return returnValue;\r
13700 }\r
13701 }\r
13702 if ((v = e.originalFn.apply(obj, args)) !== undefined) {\r
13703 returnValue = v;\r
13704 }\r
13705 for (i = 0 , len = e.after.length; i < len; i++) {\r
13706 b = e.after[i];\r
13707 makeCall(b.fn, b.scope, args);\r
13708 if (cancel) {\r
13709 return returnValue;\r
13710 }\r
13711 }\r
13712 return returnValue;\r
13713 };\r
13714 }\r
13715 return e;\r
13716 }\r
13717 Ext.apply(proto, {\r
13718 onClassMixedIn: prepareMixin,\r
13719
13720
13721
13722 beforeMethod: function(method, fn, scope) {\r
13723 getMethodEvent.call(this, method).before.push({\r
13724 fn: fn,\r
13725 scope: scope\r
13726 });\r
13727 },\r
13728
13729 afterMethod: function(method, fn, scope) {\r
13730 getMethodEvent.call(this, method).after.push({\r
13731 fn: fn,\r
13732 scope: scope\r
13733 });\r
13734 },\r
13735 removeMethodListener: function(method, fn, scope) {\r
13736 var e = this.getMethodEvent(method),\r
13737 i, len;\r
13738 for (i = 0 , len = e.before.length; i < len; i++) {\r
13739 if (e.before[i].fn == fn && e.before[i].scope == scope) {\r
13740 Ext.Array.erase(e.before, i, 1);\r
13741 return;\r
13742 }\r
13743 }\r
13744 for (i = 0 , len = e.after.length; i < len; i++) {\r
13745 if (e.after[i].fn == fn && e.after[i].scope == scope) {\r
13746 Ext.Array.erase(e.after, i, 1);\r
13747 return;\r
13748 }\r
13749 }\r
13750 },\r
13751 toggleEventLogging: function(toggle) {\r
13752 Ext.util.Observable[toggle ? 'capture' : 'releaseCapture'](this, function(en) {\r
13753 if (Ext.isDefined(Ext.global.console)) {\r
13754 Ext.global.console.log(en, arguments);\r
13755 }\r
13756 });\r
13757 }\r
13758 });\r
13759});\r
13760\r
13761\r
13762Ext.define('Ext.util.HashMap', {\r
13763 mixins: [\r
13764 Ext.mixin.Observable\r
13765 ],\r
13766 \r
13767 generation: 0,\r
13768 config: {\r
13769 \r
13770 keyFn: null\r
13771 },\r
13772 \r
13773 \r
13774 \r
13775 \r
13776 \r
13777 constructor: function(config) {\r
13778 var me = this,\r
13779 fn;\r
13780
13781 me.mixins.observable.constructor.call(me, config);\r
13782 me.clear(true);\r
13783 fn = me.getKeyFn();\r
13784 if (fn) {\r
13785 me.getKey = fn;\r
13786 }\r
13787 },\r
13788 \r
13789 getCount: function() {\r
13790 return this.length;\r
13791 },\r
13792 \r
13793 getData: function(key, value) {\r
13794
13795 if (value === undefined) {\r
13796 value = key;\r
13797 key = this.getKey(value);\r
13798 }\r
13799 return [\r
13800 key,\r
13801 value\r
13802 ];\r
13803 },\r
13804 \r
13805 getKey: function(o) {\r
13806 return o.id;\r
13807 },\r
13808 \r
13809 add: function(key, value) {\r
13810 var me = this;\r
13811
13812
13813 if (arguments.length === 1) {\r
13814 value = key;\r
13815 key = me.getKey(value);\r
13816 }\r
13817 if (me.containsKey(key)) {\r
13818 return me.replace(key, value);\r
13819 }\r
13820 me.map[key] = value;\r
13821 ++me.length;\r
13822 me.generation++;\r
13823 if (me.hasListeners.add) {\r
13824 me.fireEvent('add', me, key, value);\r
13825 }\r
13826 return value;\r
13827 },\r
13828 \r
13829 replace: function(key, value) {\r
13830 var me = this,\r
13831 map = me.map,\r
13832 old;\r
13833
13834
13835 if (arguments.length === 1) {\r
13836 value = key;\r
13837 key = me.getKey(value);\r
13838 }\r
13839 if (!me.containsKey(key)) {\r
13840 me.add(key, value);\r
13841 }\r
13842 old = map[key];\r
13843 map[key] = value;\r
13844 me.generation++;\r
13845 if (me.hasListeners.replace) {\r
13846 me.fireEvent('replace', me, key, value, old);\r
13847 }\r
13848 return value;\r
13849 },\r
13850 \r
13851 remove: function(o) {\r
13852 var key = this.findKey(o);\r
13853 if (key !== undefined) {\r
13854 return this.removeAtKey(key);\r
13855 }\r
13856 return false;\r
13857 },\r
13858 \r
13859 removeAtKey: function(key) {\r
13860 var me = this,\r
13861 value;\r
13862 if (me.containsKey(key)) {\r
13863 value = me.map[key];\r
13864 delete me.map[key];\r
13865 --me.length;\r
13866 me.generation++;\r
13867 if (me.hasListeners.remove) {\r
13868 me.fireEvent('remove', me, key, value);\r
13869 }\r
13870 return true;\r
13871 }\r
13872 return false;\r
13873 },\r
13874 \r
13875 get: function(key) {\r
13876 var map = this.map;\r
13877 return map.hasOwnProperty(key) ? map[key] : undefined;\r
13878 },\r
13879 \r
13880
13881 \r
13882 clear: function(\r
13883 initial) {\r
13884 var me = this;\r
13885
13886 if (initial || me.generation) {\r
13887 me.map = {};\r
13888 me.length = 0;\r
13889 me.generation = initial ? 0 : me.generation + 1;\r
13890 }\r
13891 if (initial !== true && me.hasListeners.clear) {\r
13892 me.fireEvent('clear', me);\r
13893 }\r
13894 return me;\r
13895 },\r
13896 \r
13897 containsKey: function(key) {\r
13898 var map = this.map;\r
13899 return map.hasOwnProperty(key) && map[key] !== undefined;\r
13900 },\r
13901 \r
13902 contains: function(value) {\r
13903 return this.containsKey(this.findKey(value));\r
13904 },\r
13905 \r
13906 getKeys: function() {\r
13907 return this.getArray(true);\r
13908 },\r
13909 \r
13910 getValues: function() {\r
13911 return this.getArray(false);\r
13912 },\r
13913 \r
13914 getArray: function(isKey) {\r
13915 var arr = [],\r
13916 key,\r
13917 map = this.map;\r
13918 for (key in map) {\r
13919 if (map.hasOwnProperty(key)) {\r
13920 arr.push(isKey ? key : map[key]);\r
13921 }\r
13922 }\r
13923 return arr;\r
13924 },\r
13925 \r
13926 each: function(fn, scope) {\r
13927
13928 var items = Ext.apply({}, this.map),\r
13929 key,\r
13930 length = this.length;\r
13931 scope = scope || this;\r
13932 for (key in items) {\r
13933 if (items.hasOwnProperty(key)) {\r
13934 if (fn.call(scope, key, items[key], length) === false) {\r
13935 break;\r
13936 }\r
13937 }\r
13938 }\r
13939 return this;\r
13940 },\r
13941 \r
13942 clone: function() {\r
13943 var hash = new this.self(this.initialConfig),\r
13944 map = this.map,\r
13945 key;\r
13946 hash.suspendEvents();\r
13947 for (key in map) {\r
13948 if (map.hasOwnProperty(key)) {\r
13949 hash.add(key, map[key]);\r
13950 }\r
13951 }\r
13952 hash.resumeEvents();\r
13953 return hash;\r
13954 },\r
13955 \r
13956 findKey: function(value) {\r
13957 var key,\r
13958 map = this.map;\r
13959 for (key in map) {\r
13960 if (map.hasOwnProperty(key) && map[key] === value) {\r
13961 return key;\r
13962 }\r
13963 }\r
13964 return undefined;\r
13965 },\r
13966 destroy: function() {\r
13967 this.callParent();\r
13968 this.map = null;\r
13969 }\r
13970}, function(HashMap) {\r
13971 var prototype = HashMap.prototype;\r
13972 \r
13973 prototype.removeByKey = prototype.removeAtKey;\r
13974});\r
13975\r
13976\r
13977Ext.define('Ext.AbstractManager', {\r
13978 \r
13979 typeName: 'type',\r
13980 constructor: function(config) {\r
13981 Ext.apply(this, config || {});\r
13982 \r
13983 this.all = new Ext.util.HashMap();\r
13984 this.types = {};\r
13985 },\r
13986 \r
13987 get: function(id) {\r
13988 return this.all.get(id);\r
13989 },\r
13990 \r
13991 register: function(item) {\r
13992
13993 var key = this.all.getKey(item);\r
13994 if (key === undefined) {\r
13995 Ext.raise('Key is undefined. Please ensure the item has a key before registering the item.');\r
13996 }\r
13997 if (this.all.containsKey(key)) {\r
13998 Ext.raise('Registering duplicate id "' + key + '" with ' + this.$className);\r
13999 }\r
14000
14001 this.all.add(item);\r
14002 },\r
14003 \r
14004 unregister: function(item) {\r
14005 this.all.remove(item);\r
14006 },\r
14007 \r
14008 registerType: function(type, cls) {\r
14009 this.types[type] = cls;\r
14010 cls[this.typeName] = type;\r
14011 },\r
14012 \r
14013 isRegistered: function(type) {\r
14014 return this.types[type] !== undefined;\r
14015 },\r
14016 \r
14017 create: function(config, defaultType) {\r
14018 var type = config[this.typeName] || config.type || defaultType,\r
14019 Constructor = this.types[type];\r
14020
14021 if (Constructor === undefined) {\r
14022 Ext.raise("The '" + type + "' type has not been registered with this manager");\r
14023 }\r
14024
14025 return new Constructor(config);\r
14026 },\r
14027 \r
14028 onAvailable: function(id, fn, scope) {\r
14029 var all = this.all,\r
14030 item, callback;\r
14031 if (all.containsKey(id)) {\r
14032 item = all.get(id);\r
14033 fn.call(scope || item, item);\r
14034 } else {\r
14035 callback = function(map, key, item) {\r
14036 if (key == id) {\r
14037 fn.call(scope || item, item);\r
14038 all.un('add', callback);\r
14039 }\r
14040 };\r
14041 all.on('add', callback);\r
14042 }\r
14043 },\r
14044 \r
14045 each: function(fn, scope) {\r
14046 this.all.each(fn, scope || this);\r
14047 },\r
14048 \r
14049 getCount: function() {\r
14050 return this.all.getCount();\r
14051 }\r
14052});\r
14053\r
14054\r
14055\r
14056Ext.define('Ext.promise.Consequence', function(Consequence) {\r
14057 return {\r
14058 \r
14059 promise: null,\r
14060 \r
14061 deferred: null,\r
14062 \r
14063 onFulfilled: null,\r
14064 \r
14065 onRejected: null,\r
14066 \r
14067 onProgress: null,\r
14068 \r
14069 constructor: function(onFulfilled, onRejected, onProgress) {\r
14070 var me = this;\r
14071 me.onFulfilled = onFulfilled;\r
14072 me.onRejected = onRejected;\r
14073 me.onProgress = onProgress;\r
14074 me.deferred = new Ext.promise.Deferred();\r
14075 me.promise = me.deferred.promise;\r
14076 },\r
14077 \r
14078 trigger: function(action, value) {\r
14079 var me = this,\r
14080 deferred = me.deferred;\r
14081 switch (action) {\r
14082 case 'fulfill':\r
14083 me.propagate(value, me.onFulfilled, deferred, deferred.resolve);\r
14084 break;\r
14085 case 'reject':\r
14086 me.propagate(value, me.onRejected, deferred, deferred.reject);\r
14087 break;\r
14088 }\r
14089 },\r
14090 \r
14091 update: function(progress) {\r
14092 if (Ext.isFunction(this.onProgress)) {\r
14093 progress = this.onProgress(progress);\r
14094 }\r
14095 this.deferred.update(progress);\r
14096 },\r
14097 \r
14098 propagate: function(value, callback, deferred, deferredMethod) {\r
14099 if (Ext.isFunction(callback)) {\r
14100 this.schedule(function() {\r
14101 try {\r
14102 deferred.resolve(callback(value));\r
14103 } catch (e) {\r
14104 deferred.reject(e);\r
14105 }\r
14106 });\r
14107 } else {\r
14108 deferredMethod.call(this.deferred, value);\r
14109 }\r
14110 },\r
14111 \r
14112 schedule: function(callback) {\r
14113 var n = Consequence.queueSize++;\r
14114 Consequence.queue[n] = callback;\r
14115 if (!n) {\r
14116
14117 Ext.asap(Consequence.dispatch);\r
14118 }\r
14119 },\r
14120 statics: {\r
14121 \r
14122 queue: new Array(10000),\r
14123 \r
14124 queueSize: 0,\r
14125 \r
14126 dispatch: function() {\r
14127 var queue = Consequence.queue,\r
14128 fn, i;\r
14129
14130 for (i = 0; i < Consequence.queueSize; ++i) {\r
14131 fn = queue[i];\r
14132 queue[i] = null;\r
14133
14134 fn();\r
14135 }\r
14136 Consequence.queueSize = 0;\r
14137 }\r
14138 }\r
14139 };\r
14140});\r
14141\r
14142\r
14143\r
14144Ext.define('Ext.promise.Deferred', {\r
14145 \r
14146 promise: null,\r
14147 \r
14148 consequences: [],\r
14149 \r
14150 completed: false,\r
14151 \r
14152 completionAction: null,\r
14153 \r
14154 completionValue: null,\r
14155 constructor: function() {\r
14156 var me = this;\r
14157 me.promise = new Ext.promise.Promise(me);\r
14158 me.consequences = [];\r
14159 me.completed = false;\r
14160 me.completionAction = null;\r
14161 me.completionValue = null;\r
14162 },\r
14163 \r
14164 then: function(onFulfilled, onRejected, onProgress) {\r
14165 var me = this,\r
14166 consequence = new Ext.promise.Consequence(onFulfilled, onRejected, onProgress);\r
14167 if (me.completed) {\r
14168 consequence.trigger(me.completionAction, me.completionValue);\r
14169 } else {\r
14170 me.consequences.push(consequence);\r
14171 }\r
14172 return consequence.promise;\r
14173 },\r
14174 \r
14175 resolve: function(value) {\r
14176 var me = this,\r
14177 isHandled, thenFn;\r
14178 if (me.completed) {\r
14179 return;\r
14180 }\r
14181 try {\r
14182 if (value === me.promise) {\r
14183 throw new TypeError('A Promise cannot be resolved with itself.');\r
14184 }\r
14185 if ((Ext.isObject(value) || Ext.isFunction(value)) && Ext.isFunction(thenFn = value.then)) {\r
14186 isHandled = false;\r
14187 try {\r
14188 thenFn.call(value, function(value) {\r
14189 if (!isHandled) {\r
14190 isHandled = true;\r
14191 me.resolve(value);\r
14192 }\r
14193 }, function(error) {\r
14194 if (!isHandled) {\r
14195 isHandled = true;\r
14196 me.reject(error);\r
14197 }\r
14198 });\r
14199 } catch (e) {\r
14200 if (!isHandled) {\r
14201 me.reject(e);\r
14202 }\r
14203 }\r
14204 } else {\r
14205 me.complete('fulfill', value);\r
14206 }\r
14207 } catch (e) {\r
14208 me.reject(e);\r
14209 }\r
14210 },\r
14211 \r
14212 reject: function(reason) {\r
14213 if (this.completed) {\r
14214 return;\r
14215 }\r
14216 this.complete('reject', reason);\r
14217 },\r
14218 \r
14219 update: function(progress) {\r
14220 var consequences = this.consequences,\r
14221 consequence, i, len;\r
14222 if (this.completed) {\r
14223 return;\r
14224 }\r
14225 for (i = 0 , len = consequences.length; i < len; i++) {\r
14226 consequence = consequences[i];\r
14227 consequence.update(progress);\r
14228 }\r
14229 },\r
14230 \r
14231 complete: function(action, value) {\r
14232 var me = this,\r
14233 consequences = me.consequences,\r
14234 consequence, i, len;\r
14235 me.completionAction = action;\r
14236 me.completionValue = value;\r
14237 me.completed = true;\r
14238 for (i = 0 , len = consequences.length; i < len; i++) {\r
14239 consequence = consequences[i];\r
14240 consequence.trigger(me.completionAction, me.completionValue);\r
14241 }\r
14242 me.consequences = null;\r
14243 }\r
14244});\r
14245\r
14246\r
14247\r
14248Ext.define('Ext.promise.Promise', function(ExtPromise) {\r
14249 var Deferred;\r
14250 return {\r
14251 statics: {\r
14252 \r
14253 CancellationError: Ext.global.CancellationError || Error,\r
14254 _ready: function() {\r
14255
14256 Deferred = Ext.promise.Deferred;\r
14257 },\r
14258 \r
14259 all: function(promisesOrValues) {\r
14260
14261 if (!(Ext.isArray(promisesOrValues) || ExtPromise.is(promisesOrValues))) {\r
14262 Ext.raise('Invalid parameter: expected an Array or Promise of an Array.');\r
14263 }\r
14264
14265 return ExtPromise.when(promisesOrValues).then(function(promisesOrValues) {\r
14266 var deferred = new Deferred(),\r
14267 remainingToResolve = promisesOrValues.length,\r
14268 results = new Array(remainingToResolve),\r
14269 index, promiseOrValue, resolve, i, len;\r
14270 if (!remainingToResolve) {\r
14271 deferred.resolve(results);\r
14272 } else {\r
14273 resolve = function(item, index) {\r
14274 return ExtPromise.when(item).then(function(value) {\r
14275 results[index] = value;\r
14276 if (!--remainingToResolve) {\r
14277 deferred.resolve(results);\r
14278 }\r
14279 return value;\r
14280 }, function(reason) {\r
14281 return deferred.reject(reason);\r
14282 });\r
14283 };\r
14284 for (index = i = 0 , len = promisesOrValues.length; i < len; index = ++i) {\r
14285 promiseOrValue = promisesOrValues[index];\r
14286 if (index in promisesOrValues) {\r
14287 resolve(promiseOrValue, index);\r
14288 } else {\r
14289 remainingToResolve--;\r
14290 }\r
14291 }\r
14292 }\r
14293 return deferred.promise;\r
14294 });\r
14295 },\r
14296 \r
14297 is: function(value) {\r
14298 return (Ext.isObject(value) || Ext.isFunction(value)) && Ext.isFunction(value.then);\r
14299 },\r
14300 \r
14301 rethrowError: function(error) {\r
14302 Ext.asap(function() {\r
14303 throw error;\r
14304 });\r
14305 },\r
14306 \r
14307 when: function(value) {\r
14308 var deferred = new Ext.promise.Deferred();\r
14309 deferred.resolve(value);\r
14310 return deferred.promise;\r
14311 }\r
14312 },\r
14313 \r
14314 owner: null,\r
14315 \r
14316 constructor: function(owner) {\r
14317 this.owner = owner;\r
14318 },\r
14319 \r
14320 then: function(onFulfilled, onRejected, onProgress, scope) {\r
14321 var ref;\r
14322 if (arguments.length === 1 && Ext.isObject(arguments[0])) {\r
14323 ref = arguments[0];\r
14324 onFulfilled = ref.success;\r
14325 onRejected = ref.failure;\r
14326 onProgress = ref.progress;\r
14327 scope = ref.scope;\r
14328 }\r
14329 if (scope) {\r
14330 if (onFulfilled) {\r
14331 onFulfilled = Ext.Function.bind(onFulfilled, scope);\r
14332 }\r
14333 if (onRejected) {\r
14334 onRejected = Ext.Function.bind(onRejected, scope);\r
14335 }\r
14336 if (onProgress) {\r
14337 onProgress = Ext.Function.bind(onProgress, scope);\r
14338 }\r
14339 }\r
14340 return this.owner.then(onFulfilled, onRejected, onProgress);\r
14341 },\r
14342 \r
14343 otherwise: function(onRejected, scope) {\r
14344 var ref;\r
14345 if (arguments.length === 1 && Ext.isObject(arguments[0])) {\r
14346 ref = arguments[0];\r
14347 onRejected = ref.fn;\r
14348 scope = ref.scope;\r
14349 }\r
14350 if (scope != null) {\r
14351 onRejected = Ext.Function.bind(onRejected, scope);\r
14352 }\r
14353 return this.owner.then(null, onRejected);\r
14354 },\r
14355 \r
14356 always: function(onCompleted, scope) {\r
14357 var ref;\r
14358 if (arguments.length === 1 && Ext.isObject(arguments[0])) {\r
14359 ref = arguments[0];\r
14360 onCompleted = ref.fn;\r
14361 scope = ref.scope;\r
14362 }\r
14363 if (scope != null) {\r
14364 onCompleted = Ext.Function.bind(onCompleted, scope);\r
14365 }\r
14366 return this.owner.then(function(value) {\r
14367 try {\r
14368 onCompleted();\r
14369 } catch (e) {\r
14370 ExtPromise.rethrowError(e);\r
14371 }\r
14372 return value;\r
14373 }, function(reason) {\r
14374 try {\r
14375 onCompleted();\r
14376 } catch (e) {\r
14377 ExtPromise.rethrowError(e);\r
14378 }\r
14379 throw reason;\r
14380 });\r
14381 },\r
14382 \r
14383 done: function() {\r
14384 this.owner.then(null, ExtPromise.rethrowError);\r
14385 },\r
14386 \r
14387 cancel: function(reason) {\r
14388 if (reason == null) {\r
14389 reason = null;\r
14390 }\r
14391 this.owner.reject(new this.self.CancellationError(reason));\r
14392 },\r
14393 \r
14394 log: function(identifier) {\r
14395 if (identifier == null) {\r
14396 identifier = '';\r
14397 }\r
14398 return this._owner.then(function(value) {\r
14399 Ext.log("" + (identifier || 'Promise') + " resolved with value: " + value);\r
14400 return value;\r
14401 }, function(reason) {\r
14402 Ext.log("" + (identifier || 'Promise') + " rejected with reason: " + reason);\r
14403 throw reason;\r
14404 });\r
14405 }\r
14406 };\r
14407}, function(ExtPromise) {\r
14408 ExtPromise._ready();\r
14409});\r
14410\r
14411\r
14412Ext.define('Ext.Promise', function() {\r
14413 var Polyfiller;\r
14414 return {\r
14415 statics: {\r
14416 _ready: function() {\r
14417
14418 Polyfiller = Ext.promise.Promise;\r
14419 },\r
14420 \r
14421 all: function() {\r
14422 return Polyfiller.all.apply(Polyfiller, arguments);\r
14423 },\r
14424 race: function() {\r
14425
14426
14427 Ext.raise("Not implemented");\r
14428 },\r
14429
14430 \r
14431 reject: function(reason) {\r
14432 var deferred = new Ext.promise.Deferred();\r
14433 deferred.reject(reason);\r
14434 return deferred.promise;\r
14435 },\r
14436 \r
14437 resolve: function(value) {\r
14438 var deferred = new Ext.promise.Deferred();\r
14439 deferred.resolve(value);\r
14440 return deferred.promise;\r
14441 }\r
14442 },\r
14443 constructor: function(action) {\r
14444 var deferred = new Ext.promise.Deferred();\r
14445 action(deferred.resolve.bind(deferred), deferred.reject.bind(deferred));\r
14446 return deferred.promise;\r
14447 }\r
14448 };\r
14449}, function(ExtPromise) {\r
14450 var P = Ext.global.Promise;\r
14451 if (P && P.resolve) {\r
14452 Ext.Promise = P;\r
14453 } else {\r
14454 ExtPromise._ready();\r
14455 }\r
14456});\r
14457\r
14458\r
14459\r
14460Ext.define('Ext.Deferred', function(Deferred) {\r
14461 var ExtPromise, when;\r
14462 return {\r
14463 extend: Ext.promise.Deferred,\r
14464 statics: {\r
14465 _ready: function() {\r
14466
14467 ExtPromise = Ext.promise.Promise;\r
14468 when = Ext.Promise.resolve;\r
14469 },\r
14470 \r
14471 all: function() {\r
14472 return ExtPromise.all.apply(ExtPromise, arguments);\r
14473 },\r
14474 \r
14475 any: function(promisesOrValues) {\r
14476
14477 if (!(Ext.isArray(promisesOrValues) || ExtPromise.is(promisesOrValues))) {\r
14478 Ext.raise('Invalid parameter: expected an Array or Promise of an Array.');\r
14479 }\r
14480
14481 return Deferred.some(promisesOrValues, 1).then(function(array) {\r
14482 return array[0];\r
14483 }, function(error) {\r
14484 if (error instanceof Error && error.message === 'Too few Promises were resolved.') {\r
14485 Ext.raise('No Promises were resolved.');\r
14486 } else {\r
14487 throw error;\r
14488 }\r
14489 });\r
14490 },\r
14491 \r
14492 delay: function(promiseOrValue, milliseconds) {\r
14493 var deferred;\r
14494 if (arguments.length === 1) {\r
14495 milliseconds = promiseOrValue;\r
14496 promiseOrValue = undefined;\r
14497 }\r
14498 milliseconds = Math.max(milliseconds, 0);\r
14499 deferred = new Deferred();\r
14500 setTimeout(function() {\r
14501 deferred.resolve(promiseOrValue);\r
14502 }, milliseconds);\r
14503 return deferred.promise;\r
14504 },\r
14505 \r
14506 map: function(promisesOrValues, mapFn) {\r
14507
14508 if (!(Ext.isArray(promisesOrValues) || ExtPromise.is(promisesOrValues))) {\r
14509 Ext.raise('Invalid parameter: expected an Array or Promise of an Array.');\r
14510 }\r
14511 if (!Ext.isFunction(mapFn)) {\r
14512 Ext.raise('Invalid parameter: expected a function.');\r
14513 }\r
14514
14515 return Deferred.resolved(promisesOrValues).then(function(promisesOrValues) {\r
14516 var deferred, index, promiseOrValue, remainingToResolve, resolve, results, i, len;\r
14517 remainingToResolve = promisesOrValues.length;\r
14518 results = new Array(promisesOrValues.length);\r
14519 deferred = new Deferred();\r
14520 if (!remainingToResolve) {\r
14521 deferred.resolve(results);\r
14522 } else {\r
14523 resolve = function(item, index) {\r
14524 return Deferred.resolved(item).then(function(value) {\r
14525 return mapFn(value, index, results);\r
14526 }).then(function(value) {\r
14527 results[index] = value;\r
14528 if (!--remainingToResolve) {\r
14529 deferred.resolve(results);\r
14530 }\r
14531 return value;\r
14532 }, function(reason) {\r
14533 return deferred.reject(reason);\r
14534 });\r
14535 };\r
14536 for (index = i = 0 , len = promisesOrValues.length; i < len; index = ++i) {\r
14537 promiseOrValue = promisesOrValues[index];\r
14538 if (index in promisesOrValues) {\r
14539 resolve(promiseOrValue, index);\r
14540 } else {\r
14541 remainingToResolve--;\r
14542 }\r
14543 }\r
14544 }\r
14545 return deferred.promise;\r
14546 });\r
14547 },\r
14548 \r
14549 memoize: function(fn, scope, hashFn) {\r
14550 var memoizedFn = Ext.Function.memoize(fn, scope, hashFn);\r
14551 return function() {\r
14552 return Deferred.all(Ext.Array.slice(arguments)).then(function(values) {\r
14553 return memoizedFn.apply(scope, values);\r
14554 });\r
14555 };\r
14556 },\r
14557 \r
14558 parallel: function(fns, scope) {\r
14559 if (scope == null) {\r
14560 scope = null;\r
14561 }\r
14562 var args = Ext.Array.slice(arguments, 2);\r
14563 return Deferred.map(fns, function(fn) {\r
14564 if (!Ext.isFunction(fn)) {\r
14565 throw new Error('Invalid parameter: expected a function.');\r
14566 }\r
14567 return fn.apply(scope, args);\r
14568 });\r
14569 },\r
14570 \r
14571 pipeline: function(fns, initialValue, scope) {\r
14572 if (scope == null) {\r
14573 scope = null;\r
14574 }\r
14575 return Deferred.reduce(fns, function(value, fn) {\r
14576 if (!Ext.isFunction(fn)) {\r
14577 throw new Error('Invalid parameter: expected a function.');\r
14578 }\r
14579 return fn.call(scope, value);\r
14580 }, initialValue);\r
14581 },\r
14582 \r
14583 reduce: function(values, reduceFn, initialValue) {\r
14584
14585 if (!(Ext.isArray(values) || ExtPromise.is(values))) {\r
14586 Ext.raise('Invalid parameter: expected an Array or Promise of an Array.');\r
14587 }\r
14588 if (!Ext.isFunction(reduceFn)) {\r
14589 Ext.raise('Invalid parameter: expected a function.');\r
14590 }\r
14591
14592 var initialValueSpecified = arguments.length === 3;\r
14593 return Deferred.resolved(values).then(function(promisesOrValues) {\r
14594 var reduceArguments = [\r
14595 promisesOrValues,\r
14596 function(previousValueOrPromise, currentValueOrPromise, currentIndex) {\r
14597 return Deferred.resolved(previousValueOrPromise).then(function(previousValue) {\r
14598 return Deferred.resolved(currentValueOrPromise).then(function(currentValue) {\r
14599 return reduceFn(previousValue, currentValue, currentIndex, promisesOrValues);\r
14600 });\r
14601 });\r
14602 }\r
14603 ];\r
14604 if (initialValueSpecified) {\r
14605 reduceArguments.push(initialValue);\r
14606 }\r
14607 return Ext.Array.reduce.apply(Ext.Array, reduceArguments);\r
14608 });\r
14609 },\r
14610 \r
14611 rejected: function(reason) {\r
14612 var deferred = new Ext.Deferred();\r
14613 deferred.reject(reason);\r
14614 return deferred.promise;\r
14615 },\r
14616 \r
14617 resolved: function(value) {\r
14618 var deferred = new Ext.Deferred();\r
14619 deferred.resolve(value);\r
14620 return deferred.promise;\r
14621 },\r
14622 \r
14623 sequence: function(fns, scope) {\r
14624 if (scope == null) {\r
14625 scope = null;\r
14626 }\r
14627 var args = Ext.Array.slice(arguments, 2);\r
14628 return Deferred.reduce(fns, function(results, fn) {\r
14629 if (!Ext.isFunction(fn)) {\r
14630 throw new Error('Invalid parameter: expected a function.');\r
14631 }\r
14632 return Deferred.resolved(fn.apply(scope, args)).then(function(result) {\r
14633 results.push(result);\r
14634 return results;\r
14635 });\r
14636 }, []);\r
14637 },\r
14638 \r
14639 some: function(promisesOrValues, howMany) {\r
14640
14641 if (!(Ext.isArray(promisesOrValues) || ExtPromise.is(promisesOrValues))) {\r
14642 Ext.raise('Invalid parameter: expected an Array or Promise of an Array.');\r
14643 }\r
14644 if (!Ext.isNumeric(howMany) || howMany <= 0) {\r
14645 Ext.raise('Invalid parameter: expected a positive integer.');\r
14646 }\r
14647
14648 return Deferred.resolved(promisesOrValues).then(function(promisesOrValues) {\r
14649 var deferred, index, onReject, onResolve, promiseOrValue, remainingToReject, remainingToResolve, values, i, len;\r
14650 values = [];\r
14651 remainingToResolve = howMany;\r
14652 remainingToReject = (promisesOrValues.length - remainingToResolve) + 1;\r
14653 deferred = new Deferred();\r
14654 if (promisesOrValues.length < howMany) {\r
14655 deferred.reject(new Error('Too few Promises were resolved.'));\r
14656 } else {\r
14657 onResolve = function(value) {\r
14658 if (remainingToResolve > 0) {\r
14659 values.push(value);\r
14660 }\r
14661 remainingToResolve--;\r
14662 if (remainingToResolve === 0) {\r
14663 deferred.resolve(values);\r
14664 }\r
14665 return value;\r
14666 };\r
14667 onReject = function(reason) {\r
14668 remainingToReject--;\r
14669 if (remainingToReject === 0) {\r
14670 deferred.reject(new Error('Too few Promises were resolved.'));\r
14671 }\r
14672 return reason;\r
14673 };\r
14674 for (index = i = 0 , len = promisesOrValues.length; i < len; index = ++i) {\r
14675 promiseOrValue = promisesOrValues[index];\r
14676 if (index in promisesOrValues) {\r
14677 Deferred.resolved(promiseOrValue).then(onResolve, onReject);\r
14678 }\r
14679 }\r
14680 }\r
14681 return deferred.promise;\r
14682 });\r
14683 },\r
14684 \r
14685 timeout: function(promiseOrValue, milliseconds) {\r
14686 var deferred = new Deferred(),\r
14687 timeoutId;\r
14688 timeoutId = setTimeout(function() {\r
14689 if (timeoutId) {\r
14690 deferred.reject(new Error('Promise timed out.'));\r
14691 }\r
14692 }, milliseconds);\r
14693 Deferred.resolved(promiseOrValue).then(function(value) {\r
14694 clearTimeout(timeoutId);\r
14695 timeoutId = null;\r
14696 deferred.resolve(value);\r
14697 }, function(reason) {\r
14698 clearTimeout(timeoutId);\r
14699 timeoutId = null;\r
14700 deferred.reject(reason);\r
14701 });\r
14702 return deferred.promise;\r
14703 }\r
14704 }\r
14705 };\r
14706}, function(Deferred) {\r
14707 Deferred._ready();\r
14708});\r
14709\r
14710
14711\r
14712Ext.Factory = function(type) {\r
14713 var me = this;\r
14714 me.aliasPrefix = type + '.';\r
14715 me.cache = {};\r
14716 me.name = type.replace(me.fixNameRe, me.fixNameFn);\r
14717 me.type = type;\r
14718};\r
14719Ext.Factory.prototype = {\r
14720 \r
14721 \r
14722 defaultProperty: 'type',\r
14723 \r
14724 \r
14725 instanceProp: 'isInstance',\r
14726 \r
14727 \r
14728 \r
14729 create: function(config, defaultType) {\r
14730 var me = this,\r
14731 Manager = Ext.ClassManager,\r
14732 cache = me.cache,\r
14733 alias, className, klass, suffix;\r
14734 if (config) {\r
14735 if (config[me.instanceProp]) {\r
14736 return config;\r
14737 }\r
14738 if (typeof config === 'string') {\r
14739 suffix = config;\r
14740 config = {};\r
14741 config[me.defaultProperty] = suffix;\r
14742 }\r
14743 className = config.xclass;\r
14744 suffix = config.type;\r
14745 }\r
14746 if (className) {\r
14747 if (!(klass = Manager.get(className))) {\r
14748 return Manager.instantiate(className, config);\r
14749 }\r
14750 } else {\r
14751 if (!(suffix = suffix || defaultType || me.defaultType)) {\r
14752 klass = me.defaultClass;\r
14753 }\r
14754
14755 if (!suffix && !klass) {\r
14756 Ext.raise('No type specified for ' + me.type + '.create');\r
14757 }\r
14758
14759 if (!klass && !(klass = cache[suffix])) {\r
14760 alias = me.aliasPrefix + suffix;\r
14761 className = Manager.getNameByAlias(alias);\r
14762
14763 if (!(klass = className && Manager.get(className))) {\r
14764 return Manager.instantiateByAlias(alias, config);\r
14765 }\r
14766 cache[suffix] = klass;\r
14767 }\r
14768 }\r
14769 return klass.isInstance ? klass : new klass(config);\r
14770 },\r
14771 fixNameRe: /\.[a-z]/ig,\r
14772 fixNameFn: function(match) {\r
14773 return match.substring(1).toUpperCase();\r
14774 },\r
14775 clearCache: function() {\r
14776 this.cache = {};\r
14777 }\r
14778};\r
14779\r
14780Ext.Factory.define = function(type, config) {\r
14781 var Factory = Ext.Factory,\r
14782 defaultClass, factory, fn;\r
14783 if (type.constructor === Object) {\r
14784 Ext.Object.each(type, Factory.define, Factory);\r
14785 } else {\r
14786 factory = new Ext.Factory(type);\r
14787 if (config) {\r
14788 if (config.constructor === Object) {\r
14789 Ext.apply(factory, config);\r
14790 if (typeof (defaultClass = factory.xclass) === 'string') {\r
14791 factory.defaultClass = Ext.ClassManager.get(defaultClass);\r
14792 }\r
14793 } else {\r
14794 factory.defaultType = config;\r
14795 }\r
14796 }\r
14797 Factory[factory.name] = fn = factory.create.bind(factory);\r
14798 fn.instance = factory;\r
14799 }\r
14800 return fn;\r
14801};\r
14802\r
14803Ext.define('Ext.mixin.Factoryable', {\r
14804 mixinId: 'factoryable',\r
14805 onClassMixedIn: function(targetClass) {\r
14806 var proto = targetClass.prototype,\r
14807 factoryConfig = proto.factoryConfig,\r
14808 alias = proto.alias,\r
14809 config = {},\r
14810 dot, createFn;\r
14811 alias = alias && alias.length && alias[0];\r
14812 if (alias && (dot = alias.lastIndexOf('.')) > 0) {\r
14813 config.type = alias.substring(0, dot);\r
14814 config.defaultType = alias.substring(dot + 1);\r
14815 }\r
14816 if (factoryConfig) {\r
14817 delete proto.factoryConfig;\r
14818 Ext.apply(config, factoryConfig);\r
14819 }\r
14820 createFn = Ext.Factory.define(config.type, config);\r
14821 if (targetClass.create === Ext.Base.create) {\r
14822
14823 targetClass.create = createFn;\r
14824 }\r
14825 }\r
14826});\r
14827\r
14828\r
14829\r
14830Ext.define('Ext.data.request.Base', {\r
14831 mixins: [\r
14832 Ext.mixin.Factoryable\r
14833 ],\r
14834
14835
14836 factoryConfig: {\r
14837 type: 'request',\r
14838 defaultType: 'ajax'\r
14839 },\r
14840
14841 result: null,\r
14842 success: null,\r
14843 timer: null,\r
14844 constructor: function(config) {\r
14845 var me = this;\r
14846
14847
14848
14849
14850 Ext.apply(me, config.options || {}, config.ownerConfig);\r
14851 me.id = ++Ext.data.Connection.requestId;\r
14852 me.owner = config.owner;\r
14853 me.options = config.options;\r
14854 me.requestOptions = config.requestOptions;\r
14855 },\r
14856 \r
14857 start: function() {\r
14858 var me = this,\r
14859 timeout = me.getTimeout();\r
14860 if (timeout && me.async) {\r
14861 me.timer = Ext.defer(me.onTimeout, timeout, me);\r
14862 }\r
14863 },\r
14864 abort: function() {\r
14865 var me = this;\r
14866 me.clearTimer();\r
14867 if (!me.timedout) {\r
14868 me.aborted = true;\r
14869 }\r
14870 me.abort = Ext.emptyFn;\r
14871 },\r
14872 createDeferred: function() {\r
14873 return (this.deferred = new Ext.Deferred());\r
14874 },\r
14875
14876 getDeferred: function() {\r
14877 return this.deferred || this.createDeferred();\r
14878 },\r
14879 getPromise: function() {\r
14880 return this.getDeferred().promise;\r
14881 },\r
14882 then: function() {\r
14883 var promise = this.getPromise();\r
14884 return promise.then.apply(promise, arguments);\r
14885 },\r
14886 \r
14887 onComplete: function() {\r
14888 var me = this,\r
14889 deferred = me.deferred,\r
14890 result = me.result;\r
14891 me.clearTimer();\r
14892 if (deferred) {\r
14893 if (me.success) {\r
14894 deferred.resolve(result);\r
14895 } else {\r
14896 deferred.reject(result);\r
14897 }\r
14898 }\r
14899 },\r
14900 onTimeout: function() {\r
14901 var me = this;\r
14902 me.timedout = true;\r
14903 me.timer = null;\r
14904 me.abort(true);\r
14905 },\r
14906 getTimeout: function() {\r
14907 return this.timeout;\r
14908 },\r
14909 clearTimer: function() {\r
14910 var timer = this.timer;\r
14911 if (timer) {\r
14912 clearTimeout(timer);\r
14913 this.timer = null;\r
14914 }\r
14915 },\r
14916 destroy: function() {\r
14917 var me = this;\r
14918 me.abort();\r
14919 me.owner = me.options = me.requestOptions = me.result = null;\r
14920 me.callParent();\r
14921 },\r
14922 privates: {\r
14923 \r
14924 createException: function() {\r
14925 var me = this,\r
14926 result;\r
14927 result = {\r
14928 request: me,\r
14929 requestId: me.id,\r
14930 status: me.aborted ? -1 : 0,\r
14931 statusText: me.aborted ? 'transaction aborted' : 'communication failure',\r
14932 getResponseHeader: me._getHeader,\r
14933 getAllResponseHeaders: me._getHeaders\r
14934 };\r
14935 if (me.aborted) {\r
14936 result.aborted = true;\r
14937 }\r
14938 if (me.timedout) {\r
14939 result.timedout = true;\r
14940 }\r
14941 return result;\r
14942 },\r
14943 _getHeader: function(name) {\r
14944 var headers = this.headers;\r
14945 return headers && headers[name.toLowerCase()];\r
14946 },\r
14947 _getHeaders: function() {\r
14948 return this.headers;\r
14949 }\r
14950 }\r
14951});\r
14952\r
14953\r
14954Ext.define('Ext.data.flash.BinaryXhr', {\r
14955 statics: {\r
14956 \r
14957 flashPluginActivated: function() {\r
14958 Ext.data.flash.BinaryXhr.flashPluginActive = true;\r
14959 Ext.data.flash.BinaryXhr.flashPlugin = document.getElementById("ext-flash-polyfill");\r
14960 Ext.GlobalEvents.fireEvent("flashready");\r
14961 },\r
14962
14963 \r
14964 flashPluginActive: false,\r
14965 \r
14966 flashPluginInjected: false,\r
14967 \r
14968 connectionIndex: 1,\r
14969 \r
14970 liveConnections: {},\r
14971 \r
14972 flashPlugin: null,\r
14973 \r
14974 onFlashStateChange: function(javascriptId, state, data) {\r
14975 var connection;\r
14976
14977 connection = this.liveConnections[Number(javascriptId)];\r
14978
14979 if (connection) {\r
14980 connection.onFlashStateChange(state, data);\r
14981 } else
14982 {\r
14983 Ext.warn.log("onFlashStateChange for unknown connection ID: " + javascriptId);\r
14984 }\r
14985 },\r
14986
14987 \r
14988 registerConnection: function(conn) {\r
14989 var i = this.connectionIndex;\r
14990 this.conectionIndex = this.connectionIndex + 1;\r
14991 this.liveConnections[i] = conn;\r
14992 return i;\r
14993 },\r
14994 \r
14995 injectFlashPlugin: function() {\r
14996 var me = this,\r
14997 flashLoaderPath, flashObjectPath;\r
14998
14999
15000
15001
15002
15003 me.flashPolyfillEl = Ext.getBody().appendChild({\r
15004 id: 'ext-flash-polyfill',\r
15005 cn: [\r
15006 {\r
15007 tag: 'p',\r
15008 html: 'To view this page ensure that Adobe Flash Player version 11.1.0 or greater is installed.'\r
15009 },\r
15010 {\r
15011 tag: 'a',\r
15012 href: 'http://www.adobe.com/go/getflashplayer',\r
15013 cn: [\r
15014 {\r
15015 tag: 'img',\r
15016 src: window.location.protocol + '//www.adobe.com/images/shared/download_buttons/get_flash_player.gif',\r
15017 alt: 'Get Adobe Flash player'\r
15018 }\r
15019 ]\r
15020 }\r
15021 ]\r
15022 });\r
15023
15024 flashLoaderPath = [\r
15025 Ext.Loader.getPath('Ext.data.Connection'),\r
15026 '../../../plugins/flash/swfobject.js'\r
15027 ].join('/');\r
15028 flashObjectPath = "/plugins/flash/FlashPlugin.swf";\r
15029
15030 flashObjectPath = [\r
15031 Ext.Loader.getPath('Ext.data.Connection'),\r
15032 '../../plugins/flash/FlashPlugin.swf'\r
15033 ].join('/');\r
15034
15035 if (Ext.flashPluginPath) {\r
15036 flashObjectPath = Ext.flashPluginPath;\r
15037 }\r
15038
15039 Ext.Loader.loadScript({\r
15040 url: flashLoaderPath,\r
15041 onLoad: function() {\r
15042
15043 var swfVersionStr = "11.4.0";\r
15044
15045 var xiSwfUrlStr = "playerProductInstall.swf";\r
15046 var flashvars = {};\r
15047 var params = {};\r
15048 params.quality = "high";\r
15049 params.bgcolor = "#ffffff";\r
15050 params.allowscriptaccess = "sameDomain";\r
15051 params.allowfullscreen = "true";\r
15052 var attributes = {};\r
15053 attributes.id = "ext-flash-polyfill";\r
15054 attributes.name = "polyfill";\r
15055 attributes.align = "middle";\r
15056 swfobject.embedSWF(flashObjectPath, "ext-flash-polyfill", "0", "0",
15057 swfVersionStr, xiSwfUrlStr, flashvars, params, attributes);\r
15058 },\r
15059 onError: function() {\r
15060
15061 Ext.raise("Could not load flash-loader file swfobject.js from " + flashLoader);\r
15062 },\r
15063
15064 scope: me\r
15065 });\r
15066 Ext.data.flash.BinaryXhr.flashPluginInjected = true;\r
15067 }\r
15068 },\r
15069 \r
15070 readyState: 0,\r
15071 \r
15072 status: 0,\r
15073 \r
15074 statusText: "",\r
15075 \r
15076 responseBytes: null,\r
15077 \r
15078 javascriptId: null,\r
15079 \r
15080 constructor: function(config) {\r
15081
15082 if (!Ext.data.flash.BinaryXhr.flashPluginInjected) {\r
15083 Ext.data.flash.BinaryXhr.injectFlashPlugin();\r
15084 }\r
15085 var me = this;\r
15086 Ext.apply(me, config);\r
15087 me.requestHeaders = {};\r
15088 },\r
15089 \r
15090 abort: function() {\r
15091 var me = this;\r
15092
15093 if (me.readyState == 4) {\r
15094
15095 Ext.warn.log("Aborting a connection that's completed its transfer: " + this.url);\r
15096
15097 return;\r
15098 }\r
15099
15100 me.aborted = true;\r
15101
15102 if (!Ext.data.flash.BinaryXhr.flashPluginActive) {\r
15103 Ext.GlobalEvents.removeListener("flashready", me.onFlashReady, me);\r
15104 return;\r
15105 }\r
15106
15107 Ext.data.flash.BinaryXhr.flashPlugin.abortRequest(me.javascriptId);\r
15108
15109 delete Ext.data.flash.BinaryXhr.liveConnections[me.javascriptId];\r
15110 },\r
15111 \r
15112 getAllResponseHeaders: function() {\r
15113 var headers = [];\r
15114 Ext.Object.each(this.responseHeaders, function(name, value) {\r
15115 headers.push(name + ': ' + value);\r
15116 });\r
15117 return headers.join('\r\n');\r
15118 },\r
15119 \r
15120 getResponseHeader: function(header) {\r
15121 var headers = this.responseHeaders;\r
15122 return (headers && headers[header]) || null;\r
15123 },\r
15124 \r
15125 open: function(method, url, async, user, password) {\r
15126 var me = this;\r
15127 me.method = method;\r
15128 me.url = url;\r
15129 me.async = async !== false;\r
15130 me.user = user;\r
15131 me.password = password;\r
15132
15133 if (!me.async) {\r
15134 Ext.raise("Binary posts are only supported in async mode: " + url);\r
15135 }\r
15136 if (me.method != "POST") {\r
15137 Ext.log.warn("Binary data can only be sent as a POST request: " + url);\r
15138 }\r
15139 },\r
15140
15141 \r
15142 overrideMimeType: function(mimeType) {\r
15143 this.mimeType = mimeType;\r
15144 },\r
15145 \r
15146 send: function(body) {\r
15147 var me = this;\r
15148 me.body = body;\r
15149 if (!Ext.data.flash.BinaryXhr.flashPluginActive) {\r
15150 Ext.GlobalEvents.addListener("flashready", me.onFlashReady, me);\r
15151 } else {\r
15152 this.onFlashReady();\r
15153 }\r
15154 },\r
15155 \r
15156 onFlashReady: function() {\r
15157 var me = this,\r
15158 req, status;\r
15159 me.javascriptId = Ext.data.flash.BinaryXhr.registerConnection(me);\r
15160
15161 req = {\r
15162 method: me.method,\r
15163
15164 url: me.url,\r
15165 user: me.user,\r
15166 password: me.password,\r
15167 mimeType: me.mimeType,\r
15168 requestHeaders: me.requestHeaders,\r
15169 body: me.body,\r
15170 javascriptId: me.javascriptId\r
15171 };\r
15172 status = Ext.data.flash.BinaryXhr.flashPlugin.postBinary(req);\r
15173 },\r
15174 \r
15175 setReadyState: function(state) {\r
15176 var me = this;\r
15177 if (me.readyState != state) {\r
15178 me.readyState = state;\r
15179 me.onreadystatechange();\r
15180 }\r
15181 },\r
15182 \r
15183 setRequestHeader: function(header, value) {\r
15184 this.requestHeaders[header] = value;\r
15185 },\r
15186 \r
15187 onreadystatechange: Ext.emptyFn,\r
15188 \r
15189 parseData: function(data) {\r
15190 var me = this;\r
15191
15192 this.status = data.status || 0;\r
15193
15194 me.responseHeaders = {};\r
15195 if (me.mimeType) {\r
15196 me.responseHeaders["content-type"] = me.mimeType;\r
15197 }\r
15198 if (data.reason == "complete") {\r
15199
15200 this.responseBytes = data.data;\r
15201 me.responseHeaders["content-length"] = data.data.length;\r
15202 } else if (data.reason == "error" || data.reason == "securityError") {\r
15203 this.statusText = data.text;\r
15204 me.responseHeaders["content-length"] = 0;\r
15205 } else
15206
15207 {\r
15208 Ext.raise("Unkown reason code in data: " + data.reason);\r
15209 }\r
15210 },\r
15211
15212 \r
15213 onFlashStateChange: function(state, data) {\r
15214 var me = this;\r
15215 if (state == 4) {\r
15216
15217 me.parseData(data);\r
15218
15219 delete Ext.data.flash.BinaryXhr.liveConnections[me.javascriptId];\r
15220 }\r
15221 me.setReadyState(state);\r
15222 }\r
15223});\r
15224
15225\r
15226\r
15227Ext.define('Ext.data.request.Ajax', {\r
15228 extend: Ext.data.request.Base,\r
15229 alias: 'request.ajax',\r
15230 statics: {\r
15231 \r
15232 parseStatus: function(status) {\r
15233
15234 status = status == 1223 ? 204 : status;\r
15235 var success = (status >= 200 && status < 300) || status == 304,\r
15236 isException = false;\r
15237 if (!success) {\r
15238 switch (status) {\r
15239 case 12002:\r
15240 case 12029:\r
15241 case 12030:\r
15242 case 12031:\r
15243 case 12152:\r
15244 case 13030:\r
15245 isException = true;\r
15246 break;\r
15247 }\r
15248 }\r
15249 return {\r
15250 success: success,\r
15251 isException: isException\r
15252 };\r
15253 }\r
15254 },\r
15255 start: function(data) {\r
15256 var me = this,\r
15257 options = me.options,\r
15258 requestOptions = me.requestOptions,\r
15259 isXdr = me.isXdr,\r
15260 xhr, headers;\r
15261 xhr = me.xhr = me.openRequest(options, requestOptions, me.async, me.username, me.password);\r
15262
15263 if (!isXdr) {\r
15264 headers = me.setupHeaders(xhr, options, requestOptions.data, requestOptions.params);\r
15265 }\r
15266 if (me.async) {\r
15267 if (!isXdr) {\r
15268 xhr.onreadystatechange = Ext.Function.bind(me.onStateChange, me);\r
15269 }\r
15270 }\r
15271 if (isXdr) {\r
15272 me.processXdrRequest(me, xhr);\r
15273 }\r
15274
15275 me.callParent([\r
15276 data\r
15277 ]);\r
15278
15279 xhr.send(data);\r
15280 if (!me.async) {\r
15281 return me.onComplete();\r
15282 }\r
15283 return me;\r
15284 },\r
15285 \r
15286 abort: function(force) {\r
15287 var me = this,\r
15288 xhr = me.xhr;\r
15289 if (force || me.isLoading()) {\r
15290 \r
15291 try {\r
15292 xhr.onreadystatechange = null;\r
15293 } catch (e) {\r
15294
15295
15296 xhr.onreadystatechange = Ext.emptyFn;\r
15297 }\r
15298 xhr.abort();\r
15299 me.callParent([\r
15300 force\r
15301 ]);\r
15302 me.onComplete();\r
15303 me.cleanup();\r
15304 }\r
15305 },\r
15306 \r
15307 cleanup: function() {\r
15308 this.xhr = null;\r
15309 delete this.xhr;\r
15310 },\r
15311 isLoading: function() {\r
15312 var me = this,\r
15313 xhr = me.xhr,\r
15314 state = xhr && xhr.readyState,\r
15315 C = Ext.data.flash && Ext.data.flash.BinaryXhr;\r
15316 if (!xhr || me.aborted || me.timedout) {\r
15317 return false;\r
15318 }\r
15319
15320
15321 if (C && xhr instanceof C) {\r
15322 return state !== 4;\r
15323 }\r
15324 return state !== 0 && state !== 4;\r
15325 },\r
15326 \r
15327 openRequest: function(options, requestOptions, async, username, password) {\r
15328 var me = this,\r
15329 xhr = me.newRequest(options);\r
15330 if (username) {\r
15331 xhr.open(requestOptions.method, requestOptions.url, async, username, password);\r
15332 } else {\r
15333 if (me.isXdr) {\r
15334 xhr.open(requestOptions.method, requestOptions.url);\r
15335 } else {\r
15336 xhr.open(requestOptions.method, requestOptions.url, async);\r
15337 }\r
15338 }\r
15339 if (options.binary || me.binary) {\r
15340 if (window.Uint8Array) {\r
15341 xhr.responseType = 'arraybuffer';\r
15342 } else if (xhr.overrideMimeType) {\r
15343
15344
15345
15346
15347 xhr.overrideMimeType('text/plain; charset=x-user-defined');\r
15348 }\r
15349
15350 else if (!Ext.isIE) {\r
15351 Ext.log.warn("Your browser does not support loading binary data using Ajax.");\r
15352 }\r
15353 }\r
15354
15355 if (options.withCredentials || me.withCredentials) {\r
15356 xhr.withCredentials = true;\r
15357 }\r
15358 return xhr;\r
15359 },\r
15360 \r
15361 newRequest: function(options) {\r
15362 var me = this,\r
15363 xhr;\r
15364 if (options.binaryData) {\r
15365
15366 if (window.Uint8Array) {\r
15367
15368 xhr = me.getXhrInstance();\r
15369 } else {\r
15370
15371 xhr = new Ext.data.flash.BinaryXhr();\r
15372 }\r
15373 } else if (me.cors && Ext.isIE9m) {\r
15374 xhr = me.getXdrInstance();\r
15375 me.isXdr = true;\r
15376 } else {\r
15377 xhr = me.getXhrInstance();\r
15378 me.isXdr = false;\r
15379 }\r
15380 return xhr;\r
15381 },\r
15382 \r
15383 setupHeaders: function(xhr, options, data, params) {\r
15384 var me = this,\r
15385 headers = Ext.apply({}, options.headers || {}, me.defaultHeaders),\r
15386 contentType = me.defaultPostHeader,\r
15387 jsonData = options.jsonData,\r
15388 xmlData = options.xmlData,\r
15389 type = 'Content-Type',\r
15390 useHeader = me.useDefaultXhrHeader,\r
15391 key, header;\r
15392 if (!headers.hasOwnProperty(type) && (data || params)) {\r
15393 if (data) {\r
15394 if (options.rawData) {\r
15395 contentType = 'text/plain';\r
15396 } else {\r
15397 if (xmlData && Ext.isDefined(xmlData)) {\r
15398 contentType = 'text/xml';\r
15399 } else if (jsonData && Ext.isDefined(jsonData)) {\r
15400 contentType = 'application/json';\r
15401 }\r
15402 }\r
15403 }\r
15404 headers[type] = contentType;\r
15405 }\r
15406 if (useHeader && !headers['X-Requested-With']) {\r
15407 headers['X-Requested-With'] = me.defaultXhrHeader;\r
15408 }\r
15409
15410
15411 if (headers[type] === undefined || headers[type] === null) {\r
15412 delete headers[type];\r
15413 }\r
15414
15415 try {\r
15416 for (key in headers) {\r
15417 if (headers.hasOwnProperty(key)) {\r
15418 header = headers[key];\r
15419 xhr.setRequestHeader(key, header);\r
15420 }\r
15421 }\r
15422 } catch (e) {\r
15423
15424 me.owner.fireEvent('exception', key, header);\r
15425 }\r
15426 return headers;\r
15427 },\r
15428 \r
15429 getXdrInstance: function() {\r
15430 var xdr;\r
15431 if (Ext.ieVersion >= 8) {\r
15432 xdr = new XDomainRequest();\r
15433 } else {\r
15434 Ext.raise({\r
15435 msg: 'Your browser does not support CORS'\r
15436 });\r
15437 }\r
15438 return xdr;\r
15439 },\r
15440 \r
15441 getXhrInstance: (function() {\r
15442 var options = [\r
15443 function() {\r
15444 return new XMLHttpRequest();\r
15445 },\r
15446 function() {\r
15447 return new ActiveXObject('MSXML2.XMLHTTP.3.0');\r
15448 },\r
15449
15450 function() {\r
15451 return new ActiveXObject('MSXML2.XMLHTTP');\r
15452 },\r
15453
15454 function() {\r
15455 return new ActiveXObject('Microsoft.XMLHTTP');\r
15456 }\r
15457 ],\r
15458
15459 i = 0,\r
15460 len = options.length,\r
15461 xhr;\r
15462 for (; i < len; ++i) {\r
15463 try {\r
15464 xhr = options[i];\r
15465 xhr();\r
15466 break;\r
15467 } catch (e) {}\r
15468 }\r
15469 return xhr;\r
15470 }()),\r
15471 processXdrRequest: function(request, xhr) {\r
15472 var me = this;\r
15473
15474 delete request.headers;\r
15475 request.contentType = request.options.contentType || me.defaultXdrContentType;\r
15476 xhr.onload = Ext.Function.bind(me.onStateChange, me, [\r
15477 true\r
15478 ]);\r
15479 xhr.onerror = xhr.ontimeout = Ext.Function.bind(me.onStateChange, me, [\r
15480 false\r
15481 ]);\r
15482 },\r
15483 processXdrResponse: function(response, xhr) {\r
15484
15485 response.getAllResponseHeaders = function() {\r
15486 return [];\r
15487 };\r
15488 response.getResponseHeader = function() {\r
15489 return '';\r
15490 };\r
15491 response.contentType = xhr.contentType || this.defaultXdrContentType;\r
15492 },\r
15493 onStateChange: function(xdrResult) {\r
15494 var me = this,\r
15495 xhr = me.xhr,\r
15496 globalEvents = Ext.GlobalEvents;\r
15497
15498 if ((xhr && xhr.readyState == 4) || me.isXdr) {\r
15499 me.clearTimer();\r
15500 me.onComplete(xdrResult);\r
15501 me.cleanup();\r
15502 if (globalEvents.hasListeners.idle) {\r
15503 globalEvents.fireEvent('idle');\r
15504 }\r
15505 }\r
15506 },\r
15507 \r
15508 onComplete: function(xdrResult) {\r
15509 var me = this,\r
15510 owner = me.owner,\r
15511 options = me.options,\r
15512 xhr = me.xhr,\r
15513 failure = {\r
15514 success: false,\r
15515 isException: false\r
15516 },\r
15517 result, success, response;\r
15518 if (!xhr || me.destroyed) {\r
15519 return me.result = failure;\r
15520 }\r
15521 try {\r
15522 result = Ext.data.request.Ajax.parseStatus(xhr.status);\r
15523 if (result.success) {\r
15524
15525
15526
15527 result.success = xhr.readyState === 4;\r
15528 }\r
15529 } catch (e) {\r
15530
15531
15532 result = failure;\r
15533 }\r
15534 success = me.success = me.isXdr ? xdrResult : result.success;\r
15535 if (success) {\r
15536 response = me.createResponse(xhr);\r
15537 owner.fireEvent('requestcomplete', owner, response, options);\r
15538 Ext.callback(options.success, options.scope, [\r
15539 response,\r
15540 options\r
15541 ]);\r
15542 } else {\r
15543 if (result.isException || me.aborted || me.timedout) {\r
15544 response = me.createException(xhr);\r
15545 } else {\r
15546 response = me.createResponse(xhr);\r
15547 }\r
15548 owner.fireEvent('requestexception', owner, response, options);\r
15549 Ext.callback(options.failure, options.scope, [\r
15550 response,\r
15551 options\r
15552 ]);\r
15553 }\r
15554 me.result = response;\r
15555 Ext.callback(options.callback, options.scope, [\r
15556 options,\r
15557 success,\r
15558 response\r
15559 ]);\r
15560 owner.onRequestComplete(me);\r
15561 me.callParent([\r
15562 xdrResult\r
15563 ]);\r
15564 return response;\r
15565 },\r
15566 \r
15567 createResponse: function(xhr) {\r
15568 var me = this,\r
15569 isXdr = me.isXdr,\r
15570 headers = {},\r
15571 lines = isXdr ? [] : xhr.getAllResponseHeaders().replace(/\r\n/g, '\n').split('\n'),\r
15572 count = lines.length,\r
15573 line, index, key, response, byteArray;\r
15574 while (count--) {\r
15575 line = lines[count];\r
15576 index = line.indexOf(':');\r
15577 if (index >= 0) {\r
15578 key = line.substr(0, index).toLowerCase();\r
15579 if (line.charAt(index + 1) == ' ') {\r
15580 ++index;\r
15581 }\r
15582 headers[key] = line.substr(index + 1);\r
15583 }\r
15584 }\r
15585 response = {\r
15586 request: me,\r
15587 requestId: me.id,\r
15588 status: xhr.status,\r
15589 statusText: xhr.statusText,\r
15590 getResponseHeader: function(header) {\r
15591 return headers[header.toLowerCase()];\r
15592 },\r
15593 getAllResponseHeaders: function() {\r
15594 return headers;\r
15595 }\r
15596 };\r
15597 if (isXdr) {\r
15598 me.processXdrResponse(response, xhr);\r
15599 }\r
15600 if (me.binary) {\r
15601 response.responseBytes = me.getByteArray(xhr);\r
15602 } else {\r
15603
15604
15605
15606
15607 response.responseText = xhr.responseText;\r
15608 response.responseXML = xhr.responseXML;\r
15609 }\r
15610 return response;\r
15611 },\r
15612 destroy: function() {\r
15613 this.xhr = null;\r
15614 this.callParent();\r
15615 },\r
15616 privates: {\r
15617 \r
15618 getByteArray: function(xhr) {\r
15619 var response = xhr.response,\r
15620 responseBody = xhr.responseBody,\r
15621 Cls = Ext.data.flash && Ext.data.flash.BinaryXhr,\r
15622 byteArray, responseText, len, i;\r
15623 if (xhr instanceof Cls) {\r
15624
15625 byteArray = xhr.responseBytes;\r
15626 } else if (window.Uint8Array) {\r
15627
15628
15629
15630 byteArray = response ? new Uint8Array(response) : [];\r
15631 } else if (Ext.isIE9p) {\r
15632
15633
15634
15635
15636 try {\r
15637 byteArray = new VBArray(responseBody).toArray();\r
15638 }
15639 catch (e) {\r
15640
15641
15642
15643
15644 byteArray = [];\r
15645 }\r
15646 } else if (Ext.isIE) {\r
15647
15648
15649
15650
15651
15652 if (!this.self.vbScriptInjected) {\r
15653 this.injectVBScript();\r
15654 }\r
15655 getIEByteArray(xhr.responseBody, byteArray = []);\r
15656 } else
15657 {\r
15658
15659
15660 byteArray = [];\r
15661 responseText = xhr.responseText;\r
15662 len = responseText.length;\r
15663 for (i = 0; i < len; i++) {\r
15664
15665
15666
15667 byteArray.push(responseText.charCodeAt(i) & 255);\r
15668 }\r
15669 }\r
15670 return byteArray;\r
15671 },\r
15672 \r
15673 injectVBScript: function() {\r
15674 var scriptTag = document.createElement('script');\r
15675 scriptTag.type = 'text/vbscript';\r
15676 scriptTag.text = [\r
15677 'Function getIEByteArray(byteArray, out)',\r
15678 'Dim len, i',\r
15679 'len = LenB(byteArray)',\r
15680 'For i = 1 to len',\r
15681 'out.push(AscB(MidB(byteArray, i, 1)))',\r
15682 'Next',\r
15683 'End Function'\r
15684 ].join('\n');\r
15685 Ext.getHead().dom.appendChild(scriptTag);\r
15686 this.self.vbScriptInjected = true;\r
15687 }\r
15688 }\r
15689});\r
15690\r
15691\r
15692Ext.define('Ext.data.request.Form', {\r
15693 extend: Ext.data.request.Base,\r
15694 alias: 'request.form',\r
15695 start: function(data) {\r
15696 var me = this,\r
15697 options = me.options,\r
15698 requestOptions = me.requestOptions;\r
15699
15700 me.callParent([\r
15701 data\r
15702 ]);\r
15703 me.form = me.upload(options.form, requestOptions.url, requestOptions.data, options);\r
15704 return me;\r
15705 },\r
15706 abort: function(force) {\r
15707 var me = this,\r
15708 frame;\r
15709 if (me.isLoading()) {\r
15710 try {\r
15711 frame = me.frame.dom;\r
15712 if (frame.stop) {\r
15713 frame.stop();\r
15714 } else {\r
15715 frame.document.execCommand('Stop');\r
15716 }\r
15717 } catch (e) {}\r
15718 }\r
15719
15720 me.callParent([\r
15721 force\r
15722 ]);\r
15723 me.onComplete();\r
15724 me.cleanup();\r
15725 },\r
15726 \r
15727 cleanup: function() {\r
15728 var me = this,\r
15729 frame = me.frame;\r
15730 if (frame) {\r
15731
15732 frame.un('load', me.onComplete, me);\r
15733 Ext.removeNode(frame);\r
15734 }\r
15735 me.frame = me.form = null;\r
15736 },\r
15737 isLoading: function() {\r
15738 return !!this.frame;\r
15739 },\r
15740 \r
15741 upload: function(form, url, params, options) {\r
15742 form = Ext.getDom(form);\r
15743 options = options || {};\r
15744 var frameDom = document.createElement('iframe'),\r
15745 frame = Ext.get(frameDom),\r
15746 id = frame.id,\r
15747 hiddens = [],\r
15748 encoding = 'multipart/form-data',\r
15749 buf = {\r
15750 target: form.target,\r
15751 method: form.method,\r
15752 encoding: form.encoding,\r
15753 enctype: form.enctype,\r
15754 action: form.action\r
15755 },\r
15756 addField = function(name, value) {\r
15757 hiddenItem = document.createElement('input');\r
15758 Ext.fly(hiddenItem).set({\r
15759 type: 'hidden',\r
15760 value: value,\r
15761 name: name\r
15762 });\r
15763 form.appendChild(hiddenItem);\r
15764 hiddens.push(hiddenItem);\r
15765 },\r
15766 hiddenItem, obj, value, name, vLen, v, hLen, h, request;\r
15767 \r
15768 frame.set({\r
15769 name: id,\r
15770 cls: Ext.baseCSSPrefix + 'hidden-display',\r
15771 src: Ext.SSL_SECURE_URL,\r
15772 tabIndex: -1\r
15773 });\r
15774 document.body.appendChild(frameDom);\r
15775
15776 if (document.frames) {\r
15777 document.frames[id].name = id;\r
15778 }\r
15779 Ext.fly(form).set({\r
15780 target: id,\r
15781 method: 'POST',\r
15782 enctype: encoding,\r
15783 encoding: encoding,\r
15784 action: url || buf.action\r
15785 });\r
15786
15787 if (params) {\r
15788 obj = Ext.Object.fromQueryString(params) || {};\r
15789 for (name in obj) {\r
15790 if (obj.hasOwnProperty(name)) {\r
15791 value = obj[name];\r
15792 if (Ext.isArray(value)) {\r
15793 vLen = value.length;\r
15794 for (v = 0; v < vLen; v++) {\r
15795 addField(name, value[v]);\r
15796 }\r
15797 } else {\r
15798 addField(name, value);\r
15799 }\r
15800 }\r
15801 }\r
15802 }\r
15803 this.frame = frame;\r
15804 frame.on({\r
15805 load: this.onComplete,\r
15806 scope: this,\r
15807
15808 single: !Ext.isOpera\r
15809 });\r
15810 form.submit();\r
15811
15812 Ext.fly(form).set(buf);\r
15813 for (hLen = hiddens.length , h = 0; h < hLen; h++) {\r
15814 Ext.removeNode(hiddens[h]);\r
15815 }\r
15816 return form;\r
15817 },\r
15818 getDoc: function() {\r
15819 var frame = this.frame.dom;\r
15820 return (frame && (frame.contentWindow.document || frame.contentDocument)) || (window.frames[frame.id] || {}).document;\r
15821 },\r
15822 getTimeout: function() {\r
15823
15824
15825
15826 return this.options.timeout;\r
15827 },\r
15828 \r
15829 onComplete: function() {\r
15830 var me = this,\r
15831 frame = me.frame,\r
15832 owner = me.owner,\r
15833 options = me.options,\r
15834 callback, doc, success, contentNode, response;\r
15835
15836 if (!frame) {\r
15837 return;\r
15838 }\r
15839 if (me.aborted || me.timedout) {\r
15840 me.result = response = me.createException();\r
15841 response.responseXML = null;\r
15842 response.responseText = '{success:false,message:"' + Ext.String.trim(response.statusText) + '"}';\r
15843 callback = options.failure;\r
15844 success = false;\r
15845 } else {\r
15846 try {\r
15847 doc = me.getDoc();\r
15848
15849 me.result = response = {\r
15850 responseText: '',\r
15851 responseXML: null\r
15852 };\r
15853
15854
15855 if (doc) {\r
15856
15857 if (Ext.isOpera && doc.location == Ext.SSL_SECURE_URL) {\r
15858 return;\r
15859 }\r
15860 if (doc.body) {\r
15861
15862
15863
15864 if ((contentNode = doc.body.firstChild) && /pre/i.test(contentNode.tagName)) {\r
15865 response.responseText = contentNode.textContent || contentNode.innerText;\r
15866 }\r
15867
15868
15869
15870 else if ((contentNode = doc.getElementsByTagName('textarea')[0])) {\r
15871 response.responseText = contentNode.value;\r
15872 } else
15873
15874 {\r
15875 response.responseText = doc.body.textContent || doc.body.innerText;\r
15876 }\r
15877 }\r
15878
15879
15880 response.responseXML = doc.XMLDocument || doc;\r
15881 callback = options.success;\r
15882 success = true;\r
15883 response.status = 200;\r
15884 } else {\r
15885 Ext.raise("Could not acquire a suitable connection for the file upload service.");\r
15886 }\r
15887 } catch (e) {\r
15888 me.result = response = me.createException();\r
15889
15890 response.status = 400;\r
15891 response.statusText = (e.message || e.description) + '';\r
15892 response.responseText = '{success:false,message:"' + Ext.String.trim(response.statusText) + '"}';\r
15893 response.responseXML = null;\r
15894 callback = options.failure;\r
15895 success = false;\r
15896 }\r
15897 }\r
15898 me.frame = null;\r
15899 me.success = success;\r
15900 owner.fireEvent(success ? 'requestcomplete' : 'requestexception', owner, response, options);\r
15901 Ext.callback(callback, options.scope, [\r
15902 response,\r
15903 options\r
15904 ]);\r
15905 Ext.callback(options.callback, options.scope, [\r
15906 options,\r
15907 success,\r
15908 response\r
15909 ]);\r
15910 owner.onRequestComplete(me);\r
15911
15912 Ext.asap(frame.destroy, frame);\r
15913 me.callParent();\r
15914 },\r
15915 destroy: function() {\r
15916 this.cleanup();\r
15917 this.callParent();\r
15918 }\r
15919});\r
15920\r
15921\r
15922Ext.define('Ext.data.Connection', {\r
15923 mixins: {\r
15924 observable: Ext.mixin.Observable\r
15925 },\r
15926 statics: {\r
15927 requestId: 0\r
15928 },\r
15929 enctypeRe: /multipart\/form-data/i,\r
15930 config: {\r
15931 \r
15932 url: null,\r
15933 \r
15934 async: true,\r
15935 \r
15936 username: '',\r
15937 \r
15938 password: '',\r
15939 \r
15940 disableCaching: true,\r
15941 \r
15942 withCredentials: false,\r
15943 \r
15944 binary: false,\r
15945 \r
15946 cors: false,\r
15947 isXdr: false,\r
15948 defaultXdrContentType: 'text/plain',\r
15949 \r
15950 disableCachingParam: '_dc',\r
15951 \r
15952 timeout: 30000,\r
15953 \r
15954 extraParams: null,\r
15955 \r
15956 autoAbort: false,\r
15957 \r
15958 method: null,\r
15959 \r
15960 defaultHeaders: null,\r
15961 \r
15962 defaultPostHeader: 'application/x-www-form-urlencoded; charset=UTF-8',\r
15963 \r
15964 useDefaultXhrHeader: true,\r
15965 \r
15966 defaultXhrHeader: 'XMLHttpRequest'\r
15967 },\r
15968 \r
15969 \r
15970 \r
15971 constructor: function(config) {\r
15972
15973 this.mixins.observable.constructor.call(this, config);\r
15974 this.requests = {};\r
15975 },\r
15976 \r
15977 request: function(options) {\r
15978 options = options || {};\r
15979 var me = this,\r
15980 requestOptions, request;\r
15981 if (me.fireEvent('beforerequest', me, options) !== false) {\r
15982 requestOptions = me.setOptions(options, options.scope || Ext.global);\r
15983 request = me.createRequest(options, requestOptions);\r
15984 return request.start(requestOptions.data);\r
15985 }\r
15986 Ext.callback(options.callback, options.scope, [\r
15987 options,\r
15988 undefined,\r
15989 undefined\r
15990 ]);\r
15991 return Ext.Deferred.rejected([\r
15992 options,\r
15993 undefined,\r
15994 undefined\r
15995 ]);\r
15996 },\r
15997 createRequest: function(options, requestOptions) {\r
15998 var me = this,\r
15999 type = options.type || requestOptions.type,\r
16000 request;\r
16001
16002 if (!type) {\r
16003 type = me.isFormUpload(options) ? 'form' : 'ajax';\r
16004 }\r
16005
16006 if (options.autoAbort || me.getAutoAbort()) {\r
16007 me.abort();\r
16008 }\r
16009
16010
16011
16012
16013
16014
16015
16016 request = Ext.Factory.request({\r
16017 type: type,\r
16018 owner: me,\r
16019 options: options,\r
16020 requestOptions: requestOptions,\r
16021 ownerConfig: me.getConfig()\r
16022 });\r
16023 me.requests[request.id] = request;\r
16024 me.latestId = request.id;\r
16025 return request;\r
16026 },\r
16027 \r
16028 isFormUpload: function(options) {\r
16029 var form = this.getForm(options);\r
16030 if (form) {\r
16031 return options.isUpload || this.enctypeRe.test(form.getAttribute('enctype'));\r
16032 }\r
16033 return false;\r
16034 },\r
16035 \r
16036 getForm: function(options) {\r
16037 return Ext.getDom(options.form);\r
16038 },\r
16039 \r
16040 setOptions: function(options, scope) {\r
16041 var me = this,\r
16042 params = options.params || {},\r
16043 extraParams = me.getExtraParams(),\r
16044 urlParams = options.urlParams,\r
16045 url = options.url || me.getUrl(),\r
16046 cors = options.cors,\r
16047 jsonData = options.jsonData,\r
16048 method, disableCache, data;\r
16049 if (cors !== undefined) {\r
16050 me.setCors(cors);\r
16051 }\r
16052
16053 if (Ext.isFunction(params)) {\r
16054 params = params.call(scope, options);\r
16055 }\r
16056
16057 if (Ext.isFunction(url)) {\r
16058 url = url.call(scope, options);\r
16059 }\r
16060 url = this.setupUrl(options, url);\r
16061
16062 if (!url) {\r
16063 Ext.raise({\r
16064 options: options,\r
16065 msg: 'No URL specified'\r
16066 });\r
16067 }\r
16068
16069
16070 data = options.rawData || options.binaryData || options.xmlData || jsonData || null;\r
16071 if (jsonData && !Ext.isPrimitive(jsonData)) {\r
16072 data = Ext.encode(data);\r
16073 }\r
16074
16075 if (options.binaryData) {\r
16076
16077 if (!Ext.isArray(options.binaryData)) {\r
16078 Ext.log.warn("Binary submission data must be an array of byte values! Instead got " + typeof (options.binaryData));\r
16079 }\r
16080
16081 if (me.nativeBinaryPostSupport()) {\r
16082 data = (new Uint8Array(options.binaryData));\r
16083 if ((Ext.isChrome && Ext.chromeVersion < 22) || Ext.isSafari || Ext.isGecko) {\r
16084 data = data.buffer;\r
16085 }\r
16086 }\r
16087 }\r
16088
16089
16090 if (Ext.isObject(params)) {\r
16091 params = Ext.Object.toQueryString(params);\r
16092 }\r
16093 if (Ext.isObject(extraParams)) {\r
16094 extraParams = Ext.Object.toQueryString(extraParams);\r
16095 }\r
16096 params = params + ((extraParams) ? ((params) ? '&' : '') + extraParams : '');\r
16097 urlParams = Ext.isObject(urlParams) ? Ext.Object.toQueryString(urlParams) : urlParams;\r
16098 params = this.setupParams(options, params);\r
16099
16100 method = (options.method || me.getMethod() || ((params || data) ? 'POST' : 'GET')).toUpperCase();\r
16101 this.setupMethod(options, method);\r
16102 disableCache = options.disableCaching !== false ? (options.disableCaching || me.getDisableCaching()) : false;\r
16103
16104 if (method === 'GET' && disableCache) {\r
16105 url = Ext.urlAppend(url, (options.disableCachingParam || me.getDisableCachingParam()) + '=' + (new Date().getTime()));\r
16106 }\r
16107
16108 if ((method == 'GET' || data) && params) {\r
16109 url = Ext.urlAppend(url, params);\r
16110 params = null;\r
16111 }\r
16112
16113 if (urlParams) {\r
16114 url = Ext.urlAppend(url, urlParams);\r
16115 }\r
16116 return {\r
16117 url: url,\r
16118 method: method,\r
16119 data: data || params || null\r
16120 };\r
16121 },\r
16122 \r
16123 setupUrl: function(options, url) {\r
16124 var form = this.getForm(options);\r
16125 if (form) {\r
16126 url = url || form.action;\r
16127 }\r
16128 return url;\r
16129 },\r
16130 \r
16131 setupParams: function(options, params) {\r
16132 var form = this.getForm(options),\r
16133 serializedForm;\r
16134 if (form && !this.isFormUpload(options)) {\r
16135 serializedForm = Ext.Element.serializeForm(form);\r
16136 params = params ? (params + '&' + serializedForm) : serializedForm;\r
16137 }\r
16138 return params;\r
16139 },\r
16140 \r
16141 setupMethod: function(options, method) {\r
16142 if (this.isFormUpload(options)) {\r
16143 return 'POST';\r
16144 }\r
16145 return method;\r
16146 },\r
16147 \r
16148 isLoading: function(request) {\r
16149 if (!request) {\r
16150 request = this.getLatest();\r
16151 }\r
16152 return request ? request.isLoading() : false;\r
16153 },\r
16154 \r
16155 abort: function(request) {\r
16156 if (!request) {\r
16157 request = this.getLatest();\r
16158 }\r
16159 if (request && request.isLoading()) {\r
16160 request.abort();\r
16161 }\r
16162 },\r
16163 \r
16164 abortAll: function() {\r
16165 var requests = this.requests,\r
16166 id;\r
16167 for (id in requests) {\r
16168 this.abort(requests[id]);\r
16169 }\r
16170 },\r
16171 \r
16172 getLatest: function() {\r
16173 var id = this.latestId,\r
16174 request;\r
16175 if (id) {\r
16176 request = this.requests[id];\r
16177 }\r
16178 return request || null;\r
16179 },\r
16180 \r
16181 clearTimeout: function(request) {\r
16182 if (!request) {\r
16183 request = this.getLatest();\r
16184 }\r
16185 if (request) {\r
16186 request.clearTimer();\r
16187 }\r
16188 },\r
16189 onRequestComplete: function(request) {\r
16190 delete this.requests[request.id];\r
16191 },\r
16192 \r
16193 nativeBinaryPostSupport: function() {\r
16194 return Ext.isChrome || (Ext.isSafari && Ext.isDefined(window.Uint8Array)) || (Ext.isGecko && Ext.isDefined(window.Uint8Array));\r
16195 }\r
16196});\r
16197\r
16198\r
16199Ext.define('Ext.Ajax', {\r
16200 extend: Ext.data.Connection,\r
16201 singleton: true,\r
16202 \r
16203 \r
16204 \r
16205 \r
16206 \r
16207 \r
16208 \r
16209 \r
16210 \r
16211 \r
16212 \r
16213 \r
16214 \r
16215 autoAbort: false\r
16216});\r
16217\r
16218\r
16219Ext.define('Ext.AnimationQueue', {\r
16220 singleton: true,\r
16221 constructor: function() {\r
16222 var me = this;\r
16223 me.queue = [];\r
16224 me.taskQueue = [];\r
16225 me.runningQueue = [];\r
16226 me.idleQueue = [];\r
16227 me.isRunning = false;\r
16228 me.isIdle = true;\r
16229 me.run = Ext.Function.bind(me.run, me);\r
16230
16231
16232
16233
16234
16235 if (Ext.os.is.iOS) {\r
16236 Ext.interval(me.watch, 500, me);\r
16237 }\r
16238 },\r
16239 \r
16240 start: function(fn, scope, args) {\r
16241 var me = this;\r
16242 me.queue.push(arguments);\r
16243 if (!me.isRunning) {\r
16244 if (me.hasOwnProperty('idleTimer')) {\r
16245 clearTimeout(me.idleTimer);\r
16246 delete me.idleTimer;\r
16247 }\r
16248 if (me.hasOwnProperty('idleQueueTimer')) {\r
16249 clearTimeout(me.idleQueueTimer);\r
16250 delete me.idleQueueTimer;\r
16251 }\r
16252 me.isIdle = false;\r
16253 me.isRunning = true;\r
16254
16255 me.startCountTime = Ext.now();\r
16256 me.count = 0;\r
16257
16258 me.doStart();\r
16259 }\r
16260 },\r
16261 watch: function() {\r
16262 if (this.isRunning && Ext.now() - this.lastRunTime >= 500) {\r
16263 this.run();\r
16264 }\r
16265 },\r
16266 run: function() {\r
16267 var me = this;\r
16268 if (!me.isRunning) {\r
16269 return;\r
16270 }\r
16271 var queue = me.runningQueue,\r
16272 now = Ext.now(),\r
16273 i, ln;\r
16274 me.lastRunTime = now;\r
16275 me.frameStartTime = now;\r
16276 queue.push.apply(queue, me.queue);\r
16277
16278 for (i = 0 , ln = queue.length; i < ln; i++) {\r
16279 me.invoke(queue[i]);\r
16280 }\r
16281 queue.length = 0;\r
16282
16283 var elapse = me.frameStartTime - me.startCountTime,\r
16284 count = ++me.count;\r
16285 if (elapse >= 200) {\r
16286 me.onFpsChanged(count * 1000 / elapse, count, elapse);\r
16287 me.startCountTime = me.frameStartTime;\r
16288 me.count = 0;\r
16289 }\r
16290
16291 me.doIterate();\r
16292 },\r
16293
16294 onFpsChanged: Ext.emptyFn,\r
16295 onStop: Ext.emptyFn,\r
16296
16297 doStart: function() {\r
16298 this.animationFrameId = Ext.Function.requestAnimationFrame(this.run);\r
16299 this.lastRunTime = Ext.now();\r
16300 },\r
16301 doIterate: function() {\r
16302 this.animationFrameId = Ext.Function.requestAnimationFrame(this.run);\r
16303 },\r
16304 doStop: function() {\r
16305 Ext.Function.cancelAnimationFrame(this.animationFrameId);\r
16306 },\r
16307 \r
16308 stop: function(fn, scope, args) {\r
16309 var me = this;\r
16310 if (!me.isRunning) {\r
16311 return;\r
16312 }\r
16313 var queue = me.queue,\r
16314 ln = queue.length,\r
16315 i, item;\r
16316 for (i = 0; i < ln; i++) {\r
16317 item = queue[i];\r
16318 if (item[0] === fn && item[1] === scope && item[2] === args) {\r
16319 queue.splice(i, 1);\r
16320 i--;\r
16321 ln--;\r
16322 }\r
16323 }\r
16324 if (ln === 0) {\r
16325 me.doStop();\r
16326
16327 me.onStop();\r
16328
16329 me.isRunning = false;\r
16330 me.idleTimer = Ext.defer(me.whenIdle, 100, me);\r
16331 }\r
16332 },\r
16333 onIdle: function(fn, scope, args) {\r
16334 var listeners = this.idleQueue,\r
16335 i, ln, listener;\r
16336 for (i = 0 , ln = listeners.length; i < ln; i++) {\r
16337 listener = listeners[i];\r
16338 if (fn === listener[0] && scope === listener[1] && args === listener[2]) {\r
16339 return;\r
16340 }\r
16341 }\r
16342 listeners.push(arguments);\r
16343 if (this.isIdle) {\r
16344 this.processIdleQueue();\r
16345 }\r
16346 },\r
16347 unIdle: function(fn, scope, args) {\r
16348 var listeners = this.idleQueue,\r
16349 i, ln, listener;\r
16350 for (i = 0 , ln = listeners.length; i < ln; i++) {\r
16351 listener = listeners[i];\r
16352 if (fn === listener[0] && scope === listener[1] && args === listener[2]) {\r
16353 listeners.splice(i, 1);\r
16354 return true;\r
16355 }\r
16356 }\r
16357 return false;\r
16358 },\r
16359 queueTask: function(fn, scope, args) {\r
16360 this.taskQueue.push(arguments);\r
16361 this.processTaskQueue();\r
16362 },\r
16363 dequeueTask: function(fn, scope, args) {\r
16364 var listeners = this.taskQueue,\r
16365 i, ln, listener;\r
16366 for (i = 0 , ln = listeners.length; i < ln; i++) {\r
16367 listener = listeners[i];\r
16368 if (fn === listener[0] && scope === listener[1] && args === listener[2]) {\r
16369 listeners.splice(i, 1);\r
16370 i--;\r
16371 ln--;\r
16372 }\r
16373 }\r
16374 },\r
16375 invoke: function(listener) {\r
16376 var fn = listener[0],\r
16377 scope = listener[1],\r
16378 args = listener[2];\r
16379 fn = (typeof fn == 'string' ? scope[fn] : fn);\r
16380 if (Ext.isArray(args)) {\r
16381 fn.apply(scope, args);\r
16382 } else {\r
16383 fn.call(scope, args);\r
16384 }\r
16385 },\r
16386 whenIdle: function() {\r
16387 this.isIdle = true;\r
16388 this.processIdleQueue();\r
16389 },\r
16390 processIdleQueue: function() {\r
16391 if (!this.hasOwnProperty('idleQueueTimer')) {\r
16392 this.idleQueueTimer = Ext.defer(this.processIdleQueueItem, 1, this);\r
16393 }\r
16394 },\r
16395 processIdleQueueItem: function() {\r
16396 delete this.idleQueueTimer;\r
16397 if (!this.isIdle) {\r
16398 return;\r
16399 }\r
16400 var listeners = this.idleQueue,\r
16401 listener;\r
16402 if (listeners.length > 0) {\r
16403 listener = listeners.shift();\r
16404 this.invoke(listener);\r
16405 this.processIdleQueue();\r
16406 }\r
16407 },\r
16408 processTaskQueue: function() {\r
16409 if (!this.hasOwnProperty('taskQueueTimer')) {\r
16410 this.taskQueueTimer = Ext.defer(this.processTaskQueueItem, 15, this);\r
16411 }\r
16412 },\r
16413 processTaskQueueItem: function() {\r
16414 delete this.taskQueueTimer;\r
16415 var listeners = this.taskQueue,\r
16416 listener;\r
16417 if (listeners.length > 0) {\r
16418 listener = listeners.shift();\r
16419 this.invoke(listener);\r
16420 this.processTaskQueue();\r
16421 }\r
16422 },\r
16423
16424 \r
16425 showFps: function() {\r
16426 var styleTpl = {\r
16427 color: 'white',\r
16428 'background-color': 'black',\r
16429 'text-align': 'center',\r
16430 'font-family': 'sans-serif',\r
16431 'font-size': '8px',\r
16432 'font-weight': 'normal',\r
16433 'font-style': 'normal',\r
16434 'line-height': '20px',\r
16435 '-webkit-font-smoothing': 'antialiased',\r
16436 'zIndex': 100000,\r
16437 position: 'absolute'\r
16438 };\r
16439 Ext.getBody().append([\r
16440
16441 {\r
16442 style: Ext.applyIf({\r
16443 bottom: '50px',\r
16444 left: 0,\r
16445 width: '50px',\r
16446 height: '20px'\r
16447 }, styleTpl),\r
16448 html: 'Average'\r
16449 },\r
16450 {\r
16451 style: Ext.applyIf({\r
16452 'background-color': 'red',\r
16453 'font-size': '18px',\r
16454 'line-height': '50px',\r
16455 bottom: 0,\r
16456 left: 0,\r
16457 width: '50px',\r
16458 height: '50px'\r
16459 }, styleTpl),\r
16460 id: '__averageFps',\r
16461 html: '0'\r
16462 },\r
16463
16464 {\r
16465 style: Ext.applyIf({\r
16466 bottom: '50px',\r
16467 left: '50px',\r
16468 width: '50px',\r
16469 height: '20px'\r
16470 }, styleTpl),\r
16471 html: 'Min (Last 1k)'\r
16472 },\r
16473 {\r
16474 style: Ext.applyIf({\r
16475 'background-color': 'orange',\r
16476 'font-size': '18px',\r
16477 'line-height': '50px',\r
16478 bottom: 0,\r
16479 left: '50px',\r
16480 width: '50px',\r
16481 height: '50px'\r
16482 }, styleTpl),\r
16483 id: '__minFps',\r
16484 html: '0'\r
16485 },\r
16486
16487 {\r
16488 style: Ext.applyIf({\r
16489 bottom: '50px',\r
16490 left: '100px',\r
16491 width: '50px',\r
16492 height: '20px'\r
16493 }, styleTpl),\r
16494 html: 'Max (Last 1k)'\r
16495 },\r
16496 {\r
16497 style: Ext.applyIf({\r
16498 'background-color': 'maroon',\r
16499 'font-size': '18px',\r
16500 'line-height': '50px',\r
16501 bottom: 0,\r
16502 left: '100px',\r
16503 width: '50px',\r
16504 height: '50px'\r
16505 }, styleTpl),\r
16506 id: '__maxFps',\r
16507 html: '0'\r
16508 },\r
16509
16510 {\r
16511 style: Ext.applyIf({\r
16512 bottom: '50px',\r
16513 left: '150px',\r
16514 width: '50px',\r
16515 height: '20px'\r
16516 }, styleTpl),\r
16517 html: 'Current'\r
16518 },\r
16519 {\r
16520 style: Ext.applyIf({\r
16521 'background-color': 'green',\r
16522 'font-size': '18px',\r
16523 'line-height': '50px',\r
16524 bottom: 0,\r
16525 left: '150px',\r
16526 width: '50px',\r
16527 height: '50px'\r
16528 }, styleTpl),\r
16529 id: '__currentFps',\r
16530 html: '0'\r
16531 }\r
16532 ]);\r
16533 Ext.AnimationQueue.resetFps();\r
16534 },\r
16535 resetFps: function() {\r
16536 var currentFps = Ext.get('__currentFps'),\r
16537 averageFps = Ext.get('__averageFps'),\r
16538 minFps = Ext.get('__minFps'),\r
16539 maxFps = Ext.get('__maxFps'),\r
16540 min = 1000,\r
16541 max = 0,\r
16542 count = 0,\r
16543 sum = 0;\r
16544 if (!currentFps) {\r
16545 return;\r
16546 }\r
16547 Ext.AnimationQueue.onFpsChanged = function(fps) {\r
16548 count++;\r
16549 if (!(count % 10)) {\r
16550 min = 1000;\r
16551 max = 0;\r
16552 }\r
16553 sum += fps;\r
16554 min = Math.min(min, fps);\r
16555 max = Math.max(max, fps);\r
16556 currentFps.setHtml(Math.round(fps));\r
16557
16558 averageFps.setHtml(Math.round(sum / count));\r
16559 minFps.setHtml(Math.round(min));\r
16560 maxFps.setHtml(Math.round(max));\r
16561 };\r
16562 }\r
16563}, function() {\r
16564 \r
16565 var paramsString = window.location.search.substr(1),\r
16566 paramsArray = paramsString.split("&");\r
16567 if (Ext.Array.contains(paramsArray, "showfps")) {\r
16568 Ext.onReady(Ext.Function.bind(this.showFps, this));\r
16569 }\r
16570});\r
16571
16572\r
16573\r
16574Ext.define('Ext.ComponentManager', {\r
16575 alternateClassName: 'Ext.ComponentMgr',\r
16576 singleton: true,\r
16577 count: 0,\r
16578 typeName: 'xtype',\r
16579 \r
16580 constructor: function(config) {\r
16581 var me = this;\r
16582 Ext.apply(me, config || {});\r
16583 me.all = {};\r
16584 me.references = {};\r
16585 me.onAvailableCallbacks = {};\r
16586 },\r
16587 \r
16588 create: function(config, defaultType) {\r
16589 if (typeof config === 'string') {\r
16590 return Ext.widget(config);\r
16591 }\r
16592 if (config.isComponent) {\r
16593 return config;\r
16594 }\r
16595 if ('xclass' in config) {\r
16596 return Ext.create(config.xclass, config);\r
16597 }\r
16598 return Ext.widget(config.xtype || defaultType, config);\r
16599 },\r
16600 \r
16601 get: function(id) {\r
16602 return this.all[id];\r
16603 },\r
16604 register: function(component) {\r
16605 var me = this,\r
16606 all = me.all,\r
16607 key = component.getId(),\r
16608 onAvailableCallbacks = me.onAvailableCallbacks;\r
16609
16610 if (key === undefined) {\r
16611 Ext.raise('Component id is undefined. Please ensure the component has an id.');\r
16612 }\r
16613 if (key in all) {\r
16614 Ext.raise('Registering duplicate component id "' + key + '"');\r
16615 }\r
16616
16617 all[key] = component;\r
16618 if (component.getReference && component.getReference()) {\r
16619 me.references[key] = component;\r
16620 }\r
16621 ++me.count;\r
16622 if (!me.hasFocusListener) {\r
16623 Ext.on('focus', me.onGlobalFocus, me);\r
16624 me.hasFocusListener = true;\r
16625 }\r
16626 onAvailableCallbacks = onAvailableCallbacks && onAvailableCallbacks[key];\r
16627 if (onAvailableCallbacks && onAvailableCallbacks.length) {\r
16628 me.notifyAvailable(component);\r
16629 }\r
16630 },\r
16631 unregister: function(component) {\r
16632 var id = component.getId();\r
16633 if (component.getReference && component.getReference()) {\r
16634 this.references[id] = null;\r
16635 delete this.references[id];\r
16636 }\r
16637 this.all[id] = null;\r
16638 delete this.all[id];\r
16639 this.count--;\r
16640 },\r
16641 markReferencesDirty: function() {\r
16642 this.referencesDirty = true;\r
16643 },\r
16644 fixReferences: function() {\r
16645 var me = this,\r
16646 references = me.references,\r
16647 key;\r
16648 if (me.referencesDirty) {\r
16649 for (key in references) {\r
16650 if (references.hasOwnProperty(key)) {\r
16651 references[key].fixReference();\r
16652 }\r
16653 }\r
16654 me.referencesDirty = false;\r
16655 }\r
16656 },\r
16657 \r
16658 onAvailable: function(id, fn, scope) {\r
16659 var me = this,\r
16660 callbacks = me.onAvailableCallbacks,\r
16661 all = me.all,\r
16662 item;\r
16663 if (id in all) {\r
16664
16665 item = all[id];\r
16666 fn.call(scope || item, item);\r
16667 } else if (id) {\r
16668
16669 if (!Ext.isArray(callbacks[id])) {\r
16670 callbacks[id] = [];\r
16671 }\r
16672 callbacks[id].push(function(item) {\r
16673 fn.call(scope || item, item);\r
16674 });\r
16675 }\r
16676 },\r
16677 \r
16678 notifyAvailable: function(item) {\r
16679 var callbacks = this.onAvailableCallbacks[item && item.getId()] || [];\r
16680 while (callbacks.length) {\r
16681 (callbacks.shift())(item);\r
16682 }\r
16683 },\r
16684 \r
16685 each: function(fn, scope) {\r
16686 return Ext.Object.each(this.all, fn, scope);\r
16687 },\r
16688 \r
16689 getCount: function() {\r
16690 return this.count;\r
16691 },\r
16692 \r
16693 getAll: function() {\r
16694 return Ext.Object.getValues(this.all);\r
16695 },\r
16696 \r
16697 getActiveComponent: function() {\r
16698 return Ext.Component.fromElement(Ext.dom.Element.getActiveElement());\r
16699 },\r
16700
16701 onGlobalFocus: function(e) {\r
16702 var me = this,\r
16703 toElement = e.toElement,\r
16704 fromElement = e.fromElement,\r
16705 toComponent = Ext.Component.fromElement(toElement),\r
16706 fromComponent = Ext.Component.fromElement(fromElement),\r
16707 commonAncestor, targetComponent;\r
16708
16709 if (toComponent === fromComponent) {\r
16710 return;\r
16711 }\r
16712 commonAncestor = me.getCommonAncestor(fromComponent, toComponent);\r
16713 if (fromComponent && !(fromComponent.destroyed || fromComponent.destroying)) {\r
16714 if (fromComponent.handleBlurEvent) {\r
16715 fromComponent.handleBlurEvent(e);\r
16716 }\r
16717
16718 for (targetComponent = fromComponent; targetComponent && targetComponent !== commonAncestor; targetComponent = targetComponent.getRefOwner()) {\r
16719 if (!(targetComponent.destroyed || targetComponent.destroying)) {\r
16720 targetComponent.onFocusLeave({\r
16721 event: e.event,\r
16722 type: 'focusleave',\r
16723 target: fromElement,\r
16724 relatedTarget: toElement,\r
16725 fromComponent: fromComponent,\r
16726 toComponent: toComponent\r
16727 });\r
16728 }\r
16729 }\r
16730 }\r
16731 if (toComponent && !toComponent.destroyed) {\r
16732 if (toComponent.handleFocusEvent) {\r
16733 toComponent.handleFocusEvent(e);\r
16734 }\r
16735
16736 for (targetComponent = toComponent; targetComponent && targetComponent !== commonAncestor; targetComponent = targetComponent.getRefOwner()) {\r
16737 targetComponent.onFocusEnter({\r
16738 event: e.event,\r
16739 type: 'focusenter',\r
16740 relatedTarget: fromElement,\r
16741 target: toElement,\r
16742 fromComponent: fromComponent,\r
16743 toComponent: toComponent\r
16744 });\r
16745 }\r
16746 }\r
16747 },\r
16748 getCommonAncestor: function(compA, compB) {\r
16749 if (compA === compB) {\r
16750 return compA;\r
16751 }\r
16752 while (compA && !(compA.isAncestor(compB) || compA === compB)) {\r
16753 compA = compA.getRefOwner();\r
16754 }\r
16755 return compA;\r
16756 },\r
16757 privates: {\r
16758 clearAll: function() {\r
16759 this.all = {};\r
16760 this.references = {};\r
16761 this.onAvailableCallbacks = {};\r
16762 },\r
16763 \r
16764 fromElement: function(node, limit, selector) {\r
16765 var target = Ext.getDom(node),\r
16766 cache = this.all,\r
16767 depth = 0,\r
16768 topmost, cmpId, cmp;\r
16769 if (typeof limit !== 'number') {\r
16770 topmost = Ext.getDom(limit);\r
16771 limit = Number.MAX_VALUE;\r
16772 }\r
16773 while (target && target.nodeType === 1 && depth < limit && target !== topmost) {\r
16774 cmpId = target.getAttribute('data-componentid') || target.id;\r
16775 if (cmpId) {\r
16776 cmp = cache[cmpId];\r
16777 if (cmp && (!selector || Ext.ComponentQuery.is(cmp, selector))) {\r
16778 return cmp;\r
16779 }\r
16780
16781 depth++;\r
16782 }\r
16783 target = target.parentNode;\r
16784 }\r
16785 return null;\r
16786 }\r
16787 },\r
16788 deprecated: {\r
16789 5: {\r
16790 methods: {\r
16791 \r
16792 isRegistered: null,\r
16793 \r
16794 registerType: null\r
16795 }\r
16796 }\r
16797 }\r
16798}, function() {\r
16799 \r
16800 Ext.getCmp = function(id) {\r
16801 return Ext.ComponentManager.get(id);\r
16802 };\r
16803});\r
16804\r
16805\r
16806Ext.ns('Ext.util').Operators = {\r
16807
16808 "=": function(a, v) {\r
16809 return a == v;\r
16810 },\r
16811 "!=": function(a, v) {\r
16812 return a != v;\r
16813 },\r
16814 "^=": function(a, v) {\r
16815 return a && a.substr(0, v.length) == v;\r
16816 },\r
16817 "$=": function(a, v) {\r
16818 return a && a.substr(a.length - v.length) == v;\r
16819 },\r
16820 "*=": function(a, v) {\r
16821 return a && a.indexOf(v) !== -1;\r
16822 },\r
16823 "%=": function(a, v) {\r
16824 return (a % v) === 0;\r
16825 },\r
16826 "|=": function(a, v) {\r
16827 return a && (a == v || a.substr(0, v.length + 1) == v + '-');\r
16828 },\r
16829 "~=": function(a, v) {\r
16830 return a && (' ' + a + ' ').indexOf(' ' + v + ' ') != -1;\r
16831 }\r
16832};\r
16833\r
16834\r
16835Ext.define('Ext.util.LruCache', {\r
16836 extend: Ext.util.HashMap,\r
16837 config: {\r
16838 \r
16839 maxSize: null\r
16840 },\r
16841 \r
16842 add: function(key, newValue) {\r
16843 var me = this,\r
16844 entry, last;\r
16845 me.removeAtKey(key);\r
16846 last = me.last;\r
16847 entry = {\r
16848 prev: last,\r
16849 next: null,\r
16850 key: key,\r
16851 value: newValue\r
16852 };\r
16853 if (last) {\r
16854
16855 last.next = entry;\r
16856 } else {\r
16857
16858 me.first = entry;\r
16859 }\r
16860 me.last = entry;\r
16861 me.callParent([\r
16862 key,\r
16863 entry\r
16864 ]);\r
16865 me.prune();\r
16866 return newValue;\r
16867 },\r
16868 \r
16869 insertBefore: function(key, newValue, sibling) {\r
16870 var me = this,\r
16871 existingKey, entry;\r
16872
16873
16874 if (sibling = this.map[this.findKey(sibling)]) {\r
16875 existingKey = me.findKey(newValue);\r
16876
16877 if (existingKey) {\r
16878 me.unlinkEntry(entry = me.map[existingKey]);\r
16879 } else
16880 {\r
16881 entry = {\r
16882 prev: sibling.prev,\r
16883 next: sibling,\r
16884 key: key,\r
16885 value: newValue\r
16886 };\r
16887 }\r
16888 if (sibling.prev) {\r
16889 entry.prev.next = entry;\r
16890 } else {\r
16891 me.first = entry;\r
16892 }\r
16893 entry.next = sibling;\r
16894 sibling.prev = entry;\r
16895 me.prune();\r
16896 return newValue;\r
16897 } else
16898 {\r
16899 return me.add(key, newValue);\r
16900 }\r
16901 },\r
16902 \r
16903 get: function(key) {\r
16904 var entry = this.map[key];\r
16905 if (entry) {\r
16906
16907 if (entry.next) {\r
16908 this.moveToEnd(entry);\r
16909 }\r
16910 return entry.value;\r
16911 }\r
16912 },\r
16913 \r
16914 removeAtKey: function(key) {\r
16915 this.unlinkEntry(this.map[key]);\r
16916 return this.callParent(arguments);\r
16917 },\r
16918 \r
16919 clear: function(\r
16920 initial) {\r
16921 this.first = this.last = null;\r
16922 return this.callParent([\r
16923 initial\r
16924 ]);\r
16925 },\r
16926 \r
16927 unlinkEntry: function(entry) {\r
16928
16929 if (entry) {\r
16930 if (entry.next) {\r
16931 entry.next.prev = entry.prev;\r
16932 } else {\r
16933 this.last = entry.prev;\r
16934 }\r
16935 if (entry.prev) {\r
16936 entry.prev.next = entry.next;\r
16937 } else {\r
16938 this.first = entry.next;\r
16939 }\r
16940 entry.prev = entry.next = null;\r
16941 }\r
16942 },\r
16943 \r
16944 moveToEnd: function(entry) {\r
16945 this.unlinkEntry(entry);\r
16946
16947
16948 if (entry.prev = this.last) {\r
16949 this.last.next = entry;\r
16950 } else
16951 {\r
16952 this.first = entry;\r
16953 }\r
16954 this.last = entry;\r
16955 },\r
16956 \r
16957 getArray: function(isKey) {\r
16958 var arr = [],\r
16959 entry = this.first;\r
16960 while (entry) {\r
16961 arr.push(isKey ? entry.key : entry.value);\r
16962 entry = entry.next;\r
16963 }\r
16964 return arr;\r
16965 },\r
16966 \r
16967 each: function(fn, scope, reverse) {\r
16968 var me = this,\r
16969 entry = reverse ? me.last : me.first,\r
16970 length = me.length;\r
16971 scope = scope || me;\r
16972 while (entry) {\r
16973 if (fn.call(scope, entry.key, entry.value, length) === false) {\r
16974 break;\r
16975 }\r
16976 entry = reverse ? entry.prev : entry.next;\r
16977 }\r
16978 return me;\r
16979 },\r
16980 \r
16981 findKey: function(value) {\r
16982 var key,\r
16983 map = this.map;\r
16984 for (key in map) {\r
16985
16986
16987 if (map.hasOwnProperty(key) && map[key].value === value) {\r
16988 return key;\r
16989 }\r
16990 }\r
16991 return undefined;\r
16992 },\r
16993 \r
16994 clone: function() {\r
16995 var newCache = new this.self(this.initialConfig),\r
16996 map = this.map,\r
16997 key;\r
16998 newCache.suspendEvents();\r
16999 for (key in map) {\r
17000 if (map.hasOwnProperty(key)) {\r
17001 newCache.add(key, map[key].value);\r
17002 }\r
17003 }\r
17004 newCache.resumeEvents();\r
17005 return newCache;\r
17006 },\r
17007 \r
17008 prune: function() {\r
17009 var me = this,\r
17010 max = me.getMaxSize(),\r
17011 purgeCount = max ? (me.length - max) : 0;\r
17012 if (purgeCount > 0) {\r
17013 for (; me.first && purgeCount; purgeCount--) {\r
17014 me.removeAtKey(me.first.key);\r
17015 }\r
17016 }\r
17017 },\r
17018 destroy: function() {\r
17019 this.first = this.last = null;\r
17020 this.callParent();\r
17021 }\r
17022});\r
17023\r
17024\r
17025\r
17026\r
17027\r
17028\r
17029Ext.define('Ext.ComponentQuery', {\r
17030 singleton: true\r
17031}, function() {\r
17032 var cq = this,\r
17033 queryOperators = Ext.util.Operators,\r
17034 nthRe = /(\d*)n\+?(\d*)/,\r
17035 nthRe2 = /\D/,\r
17036 stripLeadingSpaceRe = /^(\s)+/,\r
17037 unescapeRe = /\\(.)/g,\r
17038 regexCache = new Ext.util.LruCache({\r
17039 maxSize: 100\r
17040 }),\r
17041
17042
17043 filterFnPattern = [\r
17044 'var r = [],',\r
17045 'i = 0,',\r
17046 'it = items,',\r
17047 'l = it.length,',\r
17048 'c;',\r
17049 'for (; i < l; i++) {',\r
17050 'c = it[i];',\r
17051 'if (c.{0}) {',\r
17052 'r.push(c);',\r
17053 '}',\r
17054 '}',\r
17055 'return r;'\r
17056 ].join(''),\r
17057 filterItems = function(items, operation) {\r
17058
17059
17060
17061 return operation.method.apply(this, [\r
17062 items\r
17063 ].concat(operation.args));\r
17064 },\r
17065 getItems = function(items, mode) {\r
17066 var result = [],\r
17067 i = 0,\r
17068 length = items.length,\r
17069 candidate,\r
17070 deep = mode !== '>';\r
17071 for (; i < length; i++) {\r
17072 candidate = items[i];\r
17073 if (candidate.getRefItems) {\r
17074 result = result.concat(candidate.getRefItems(deep));\r
17075 }\r
17076 }\r
17077 return result;\r
17078 },\r
17079 getAncestors = function(items) {\r
17080 var result = [],\r
17081 i = 0,\r
17082 length = items.length,\r
17083 candidate;\r
17084 for (; i < length; i++) {\r
17085 candidate = items[i];\r
17086 while (!!(candidate = candidate.getRefOwner())) {\r
17087 result.push(candidate);\r
17088 }\r
17089 }\r
17090 return result;\r
17091 },\r
17092
17093 filterByXType = function(items, xtype, shallow) {\r
17094 if (xtype === '*') {\r
17095 return items.slice();\r
17096 } else {\r
17097 var result = [],\r
17098 i = 0,\r
17099 length = items.length,\r
17100 candidate;\r
17101 for (; i < length; i++) {\r
17102 candidate = items[i];\r
17103 if (candidate.isXType(xtype, shallow)) {\r
17104 result.push(candidate);\r
17105 }\r
17106 }\r
17107 return result;\r
17108 }\r
17109 },\r
17110
17111 filterByAttribute = function(items, property, operator, compareTo) {\r
17112 var result = [],\r
17113 i = 0,\r
17114 length = items.length,\r
17115 mustBeOwnProperty, presenceOnly, candidate, propValue, j, propLen, config;\r
17116
17117 if (property.charAt(0) === '@') {\r
17118 mustBeOwnProperty = true;\r
17119 property = property.substr(1);\r
17120 }\r
17121 if (property.charAt(0) === '?') {\r
17122 mustBeOwnProperty = true;\r
17123 presenceOnly = true;\r
17124 property = property.substr(1);\r
17125 }\r
17126 for (; i < length; i++) {\r
17127 candidate = items[i];\r
17128
17129
17130
17131 config = candidate.getConfigurator && candidate.self.$config.configs[property];\r
17132 if (config) {\r
17133 propValue = candidate[config.names.get]();\r
17134 } else if (mustBeOwnProperty && !candidate.hasOwnProperty(property)) {\r
17135 \r
17136 continue;\r
17137 } else {\r
17138 propValue = candidate[property];\r
17139 }\r
17140 if (presenceOnly) {\r
17141 result.push(candidate);\r
17142 }\r
17143
17144 else if (operator === '~=') {\r
17145 if (propValue) {\r
17146
17147 if (!Ext.isArray(propValue)) {\r
17148 propValue = propValue.split(' ');\r
17149 }\r
17150 for (j = 0 , propLen = propValue.length; j < propLen; j++) {\r
17151 if (queryOperators[operator](Ext.coerce(propValue[j], compareTo), compareTo)) {\r
17152 result.push(candidate);\r
17153 break;\r
17154 }\r
17155 }\r
17156 }\r
17157 } else if (operator === '/=') {\r
17158 if (propValue != null && compareTo.test(propValue)) {\r
17159 result.push(candidate);\r
17160 }\r
17161 } else if (!compareTo ? !!candidate[property] : queryOperators[operator](Ext.coerce(propValue, compareTo), compareTo)) {\r
17162 result.push(candidate);\r
17163 }\r
17164 }\r
17165 return result;\r
17166 },\r
17167
17168 filterById = function(items, id) {\r
17169 var result = [],\r
17170 i = 0,\r
17171 length = items.length,\r
17172 candidate;\r
17173 for (; i < length; i++) {\r
17174 candidate = items[i];\r
17175 if (candidate.getItemId() === id) {\r
17176 result.push(candidate);\r
17177 }\r
17178 }\r
17179 return result;\r
17180 },\r
17181
17182 filterByPseudo = function(items, name, value) {\r
17183 return cq.pseudos[name](items, value);\r
17184 },\r
17185
17186
17187 modeRe = /^(\s?([>\^])\s?|\s|$)/,\r
17188
17189 tokenRe = /^(#)?((?:\\\.|[\w\-])+|\*)(?:\((true|false)\))?/,\r
17190 matchers = [\r
17191 {\r
17192
17193 re: /^\.((?:\\\.|[\w\-])+)(?:\((true|false)\))?/,\r
17194 method: filterByXType,\r
17195 argTransform: function(args) {\r
17196
17197 var selector = args[0];\r
17198 Ext.log.warn('"' + selector + '" ComponentQuery selector style is deprecated,' + ' use "' + selector.replace(/^\./, '') + '" without the leading dot instead');\r
17199
17200 if (args[1] !== undefined) {\r
17201 args[1] = args[1].replace(unescapeRe, '$1');\r
17202 }\r
17203 return args.slice(1);\r
17204 }\r
17205 },\r
17206 {\r
17207
17208
17209
17210
17211
17212
17213
17214
17215 re: /^(?:\[((?:[@?$])?[\w\-]*)\s*(?:([\^$*~%!\/]?=)\s*(['"])?((?:\\\]|.)*?)\3)?(?!\\)\])/,\r
17216 method: filterByAttribute,\r
17217 argTransform: function(args) {\r
17218 var selector = args[0],\r
17219 property = args[1],\r
17220 operator = args[2],\r
17221
17222 compareTo = args[4],\r
17223 compareRe;\r
17224
17225 if (compareTo !== undefined) {\r
17226 compareTo = compareTo.replace(unescapeRe, '$1');\r
17227
17228 var format = Ext.String.format,\r
17229 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})",\r
17230 match;\r
17231 if (match = /^(['"]).*?[^'"]$/.exec(compareTo)) {\r
17232
17233 Ext.log.warn(format(msg, selector, match[1], 'beginning'));\r
17234 } else if (match = /^[^'"].*?(['"])$/.exec(compareTo)) {\r
17235
17236 Ext.log.warn(format(msg, selector, match[1], 'end'));\r
17237 }\r
17238 }\r
17239
17240 if (operator === '/=') {\r
17241 compareRe = regexCache.get(compareTo);\r
17242 if (compareRe) {\r
17243 compareTo = compareRe;\r
17244 } else {\r
17245 compareTo = regexCache.add(compareTo, new RegExp(compareTo));\r
17246 }\r
17247 }\r
17248 return [\r
17249 property,\r
17250 operator,\r
17251 compareTo\r
17252 ];\r
17253 }\r
17254 },\r
17255 {\r
17256
17257 re: /^#((?:\\\.|[\w\-])+)/,\r
17258 method: filterById\r
17259 },\r
17260 {\r
17261
17262 re: /^\:([\w\-]+)(?:\(((?:\{[^\}]+\})|(?:(?!\{)[^\s>\/]*?(?!\})))\))?/,\r
17263 method: filterByPseudo,\r
17264 argTransform: function(args) {\r
17265 if (args[2] !== undefined) {\r
17266 args[2] = args[2].replace(unescapeRe, '$1');\r
17267 }\r
17268 return args.slice(1);\r
17269 }\r
17270 },\r
17271 {\r
17272
17273 re: /^(?:\{([^\}]+)\})/,\r
17274 method: filterFnPattern\r
17275 }\r
17276 ];\r
17277
17278 cq.Query = Ext.extend(Object, {\r
17279 constructor: function(cfg) {\r
17280 cfg = cfg || {};\r
17281 Ext.apply(this, cfg);\r
17282 },\r
17283
17284
17285
17286
17287
17288
17289
17290
17291 execute: function(root) {\r
17292 var operations = this.operations,\r
17293 result = [],\r
17294 op, i, len;\r
17295 for (i = 0 , len = operations.length; i < len; i++) {\r
17296 op = operations[i];\r
17297 result = result.concat(this._execute(root, op));\r
17298 }\r
17299 return result;\r
17300 },\r
17301 _execute: function(root, operations) {\r
17302 var i = 0,\r
17303 length = operations.length,\r
17304 operation, workingItems;\r
17305
17306 if (!root) {\r
17307 workingItems = Ext.ComponentManager.getAll();\r
17308 }\r
17309
17310 else if (Ext.isIterable(root)) {\r
17311 workingItems = root;\r
17312 }\r
17313
17314 else if (root.isMixedCollection) {\r
17315 workingItems = root.items;\r
17316 }\r
17317
17318
17319 for (; i < length; i++) {\r
17320 operation = operations[i];\r
17321
17322
17323
17324
17325
17326
17327 if (operation.mode === '^') {\r
17328 workingItems = getAncestors(workingItems || [\r
17329 root\r
17330 ]);\r
17331 } else if (operation.mode) {\r
17332 workingItems = getItems(workingItems || [\r
17333 root\r
17334 ], operation.mode);\r
17335 } else {\r
17336 workingItems = filterItems(workingItems || getItems([\r
17337 root\r
17338 ]), operation);\r
17339 }\r
17340
17341
17342 if (i === length - 1) {\r
17343 return workingItems;\r
17344 }\r
17345 }\r
17346 return [];\r
17347 },\r
17348 is: function(component) {\r
17349 var operations = this.operations,\r
17350 result = false,\r
17351 len = operations.length,\r
17352 op, i;\r
17353 if (len === 0) {\r
17354 return true;\r
17355 }\r
17356 for (i = 0; i < len; i++) {\r
17357 op = operations[i];\r
17358 result = this._is(component, op);\r
17359 if (result) {\r
17360 return result;\r
17361 }\r
17362 }\r
17363 return false;\r
17364 },\r
17365 _is: function(component, operations) {\r
17366 var len = operations.length,\r
17367 active = [\r
17368 component\r
17369 ],\r
17370 operation, i, j, mode, items, item;\r
17371
17372 for (i = len - 1; i >= 0; --i) {\r
17373 operation = operations[i];\r
17374 mode = operation.mode;\r
17375
17376 if (mode) {\r
17377 if (mode === '^') {\r
17378 active = getItems(active, ' ');\r
17379 } else if (mode === '>') {\r
17380 items = [];\r
17381 for (j = 0 , len = active.length; j < len; ++j) {\r
17382 item = active[j].getRefOwner();\r
17383 if (item) {\r
17384 items.push(item);\r
17385 }\r
17386 }\r
17387 active = items;\r
17388 } else {\r
17389 active = getAncestors(active);\r
17390 }\r
17391
17392 if (active.length === 0) {\r
17393 return false;\r
17394 }\r
17395 } else {\r
17396 active = filterItems(active, operation);\r
17397 if (active.length === 0) {\r
17398 return false;\r
17399 }\r
17400 }\r
17401 }\r
17402 return true;\r
17403 },\r
17404 getMatches: function(components, operations) {\r
17405 var len = operations.length,\r
17406 i;\r
17407 for (i = 0; i < len; ++i) {\r
17408 components = filterItems(components, operations[i]);\r
17409
17410
17411 if (components.length === 0) {\r
17412 break;\r
17413 }\r
17414 }\r
17415 return components;\r
17416 },\r
17417 isMultiMatch: function() {\r
17418 return this.operations.length > 1;\r
17419 }\r
17420 });\r
17421 Ext.apply(cq, {\r
17422 \r
17423 cache: new Ext.util.LruCache({\r
17424 maxSize: 100\r
17425 }),\r
17426 \r
17427 pseudos: {\r
17428 not: function(components, selector) {\r
17429 var i = 0,\r
17430 length = components.length,\r
17431 results = [],\r
17432 index = -1,\r
17433 component;\r
17434 for (; i < length; ++i) {\r
17435 component = components[i];\r
17436 if (!cq.is(component, selector)) {\r
17437 results[++index] = component;\r
17438 }\r
17439 }\r
17440 return results;\r
17441 },\r
17442 first: function(components) {\r
17443 var ret = [];\r
17444 if (components.length > 0) {\r
17445 ret.push(components[0]);\r
17446 }\r
17447 return ret;\r
17448 },\r
17449 last: function(components) {\r
17450 var len = components.length,\r
17451 ret = [];\r
17452 if (len > 0) {\r
17453 ret.push(components[len - 1]);\r
17454 }\r
17455 return ret;\r
17456 },\r
17457 focusable: function(cmps) {\r
17458 var len = cmps.length,\r
17459 results = [],\r
17460 i = 0,\r
17461 c;\r
17462 for (; i < len; i++) {\r
17463 c = cmps[i];\r
17464 if (c.isFocusable && c.isFocusable()) {\r
17465 results.push(c);\r
17466 }\r
17467 }\r
17468 return results;\r
17469 },\r
17470 "nth-child": function(c, a) {\r
17471 var result = [],\r
17472 m = nthRe.exec(a === "even" && "2n" || a === "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a),\r
17473 f = (m[1] || 1) - 0,\r
17474 len = m[2] - 0,\r
17475 i, n, nodeIndex;\r
17476 for (i = 0; n = c[i]; i++) {\r
17477
17478 nodeIndex = i + 1;\r
17479 if (f === 1) {\r
17480 if (len === 0 || nodeIndex === len) {\r
17481 result.push(n);\r
17482 }\r
17483 } else if ((nodeIndex + len) % f === 0) {\r
17484 result.push(n);\r
17485 }\r
17486 }\r
17487 return result;\r
17488 },\r
17489 scrollable: function(cmps) {\r
17490 var len = cmps.length,\r
17491 results = [],\r
17492 i = 0,\r
17493 c;\r
17494 for (; i < len; i++) {\r
17495 c = cmps[i];\r
17496
17497 if (c.scrollable || c._scrollable) {\r
17498 results.push(c);\r
17499 }\r
17500 }\r
17501 return results;\r
17502 }\r
17503 },\r
17504 \r
17505 query: function(selector, root) {\r
17506
17507 if (!selector) {\r
17508 return Ext.ComponentManager.all.getArray();\r
17509 }\r
17510 var results = [],\r
17511 noDupResults = [],\r
17512 dupMatcher = {},\r
17513 query = cq.cache.get(selector),\r
17514 resultsLn, cmp, i;\r
17515 if (!query) {\r
17516 query = cq.cache.add(selector, cq.parse(selector));\r
17517 }\r
17518 results = query.execute(root);\r
17519
17520
17521 if (query.isMultiMatch()) {\r
17522 resultsLn = results.length;\r
17523 for (i = 0; i < resultsLn; i++) {\r
17524 cmp = results[i];\r
17525 if (!dupMatcher[cmp.id]) {\r
17526 noDupResults.push(cmp);\r
17527 dupMatcher[cmp.id] = true;\r
17528 }\r
17529 }\r
17530 results = noDupResults;\r
17531 }\r
17532 return results;\r
17533 },\r
17534 \r
17535 visitPreOrder: function(selector, root, fn, scope, extraArgs) {\r
17536 cq._visit(true, selector, root, fn, scope, extraArgs);\r
17537 },\r
17538 \r
17539 visitPostOrder: function(selector, root, fn, scope, extraArgs) {\r
17540 cq._visit(false, selector, root, fn, scope, extraArgs);\r
17541 },\r
17542 \r
17543 _visit: function(preOrder, selector, root, fn, scope, extraArgs) {\r
17544 var query = cq.cache.get(selector),\r
17545 callArgs = [\r
17546 root\r
17547 ],\r
17548 children,\r
17549 len = 0,\r
17550 i, rootMatch;\r
17551 if (!query) {\r
17552 query = cq.cache.add(selector, cq.parse(selector));\r
17553 }\r
17554 rootMatch = query.is(root);\r
17555 if (root.getRefItems) {\r
17556 children = root.getRefItems();\r
17557 len = children.length;\r
17558 }\r
17559
17560 if (extraArgs) {\r
17561 Ext.Array.push(callArgs, extraArgs);\r
17562 }\r
17563 if (preOrder) {\r
17564 if (rootMatch) {\r
17565 if (fn.apply(scope || root, callArgs) === false) {\r
17566 return false;\r
17567 }\r
17568 }\r
17569 }\r
17570 for (i = 0; i < len; i++) {\r
17571 if (cq._visit.call(cq, preOrder, selector, children[i], fn, scope, extraArgs) === false) {\r
17572 return false;\r
17573 }\r
17574 }\r
17575 if (!preOrder) {\r
17576 if (rootMatch) {\r
17577 if (fn.apply(scope || root, callArgs) === false) {\r
17578 return false;\r
17579 }\r
17580 }\r
17581 }\r
17582 },\r
17583 \r
17584 is: function(component, selector) {\r
17585 if (!selector) {\r
17586 return true;\r
17587 }\r
17588 var query = cq.cache.get(selector);\r
17589 if (!query) {\r
17590 query = cq.cache.add(selector, cq.parse(selector));\r
17591 }\r
17592 return query.is(component);\r
17593 },\r
17594 parse: function(selector) {\r
17595 var operations = [],\r
17596 selectors, sel, i, len;\r
17597 selectors = Ext.splitAndUnescape(selector, ',');\r
17598 for (i = 0 , len = selectors.length; i < len; i++) {\r
17599
17600 sel = Ext.String.trim(selectors[i]);\r
17601
17602
17603
17604
17605 if (sel === '') {\r
17606 Ext.raise('Invalid ComponentQuery selector: ""');\r
17607 }\r
17608
17609 operations.push(cq._parse(sel));\r
17610 }\r
17611
17612
17613 return new cq.Query({\r
17614 operations: operations\r
17615 });\r
17616 },\r
17617 _parse: function(selector) {\r
17618 var operations = [],\r
17619 trim = Ext.String.trim,\r
17620 length = matchers.length,\r
17621 lastSelector, tokenMatch, token, matchedChar, modeMatch, selectorMatch, transform, i, matcher, method, args;\r
17622
17623
17624
17625 while (selector && lastSelector !== selector) {\r
17626 lastSelector = selector;\r
17627
17628 tokenMatch = selector.match(tokenRe);\r
17629 if (tokenMatch) {\r
17630 matchedChar = tokenMatch[1];\r
17631 token = trim(tokenMatch[2]).replace(unescapeRe, '$1');\r
17632
17633 if (matchedChar === '#') {\r
17634 operations.push({\r
17635 method: filterById,\r
17636 args: [\r
17637 token\r
17638 ]\r
17639 });\r
17640 } else
17641
17642 {\r
17643 operations.push({\r
17644 method: filterByXType,\r
17645 args: [\r
17646 token,\r
17647 Boolean(tokenMatch[3])\r
17648 ]\r
17649 });\r
17650 }\r
17651
17652 selector = selector.replace(tokenMatch[0], '').replace(stripLeadingSpaceRe, '$1');\r
17653 }\r
17654
17655
17656
17657 while (!(modeMatch = selector.match(modeRe))) {\r
17658
17659
17660 for (i = 0; selector && i < length; i++) {\r
17661 matcher = matchers[i];\r
17662 selectorMatch = selector.match(matcher.re);\r
17663 method = matcher.method;\r
17664 transform = matcher.argTransform;\r
17665
17666
17667
17668 if (selectorMatch) {\r
17669
17670 if (transform) {\r
17671 args = transform(selectorMatch);\r
17672 } else {\r
17673 args = selectorMatch.slice(1);\r
17674 }\r
17675 operations.push({\r
17676 method: Ext.isString(matcher.method) ?
17677
17678
17679 Ext.functionFactory('items', Ext.String.format.apply(Ext.String, [\r
17680 method\r
17681 ].concat(selectorMatch.slice(1)))) : matcher.method,\r
17682 args: args\r
17683 });\r
17684 selector = selector.replace(selectorMatch[0], '').replace(stripLeadingSpaceRe, '$1');\r
17685 break;\r
17686 }\r
17687
17688
17689 if (i === (length - 1)) {\r
17690 Ext.raise('Invalid ComponentQuery selector: "' + arguments[0] + '"');\r
17691 }\r
17692 }\r
17693 }\r
17694
17695
17696
17697
17698 if (modeMatch[1]) {\r
17699
17700 operations.push({\r
17701 mode: modeMatch[2] || modeMatch[1]\r
17702 });\r
17703
17704 selector = selector.replace(modeMatch[0], '').replace(stripLeadingSpaceRe, '');\r
17705 }\r
17706 }\r
17707 return operations;\r
17708 }\r
17709 });\r
17710 \r
17711 Ext.all = function() {\r
17712 return cq.query.apply(cq, arguments);\r
17713 };\r
17714 \r
17715 Ext.first = function() {\r
17716 var matches = cq.query.apply(cq, arguments);\r
17717 return (matches && matches[0]) || null;\r
17718 };\r
17719});\r
17720\r
17721\r
17722Ext.define('Ext.Evented', {\r
17723 alternateClassName: 'Ext.EventedBase',\r
17724 mixins: [\r
17725 Ext.mixin.Observable\r
17726 ],\r
17727 initialized: false,\r
17728 constructor: function(config) {\r
17729 this.mixins.observable.constructor.call(this, config);\r
17730 this.initialized = true;\r
17731 },\r
17732 onClassExtended: function(cls, data) {\r
17733 if (!data.hasOwnProperty('eventedConfig')) {\r
17734 return;\r
17735 }\r
17736 var config = data.config,\r
17737 eventedConfig = data.eventedConfig,\r
17738 name, cfg;\r
17739 if (config) {\r
17740 Ext.applyIf(config, eventedConfig);\r
17741 } else {\r
17742 cls.addConfig(eventedConfig);\r
17743 }\r
17744 \r
17745
17746 for (name in eventedConfig) {\r
17747 if (eventedConfig.hasOwnProperty(name)) {\r
17748 cfg = Ext.Config.get(name);\r
17749 data[cfg.names.set] = cfg.eventedSetter || cfg.getEventedSetter();\r
17750 }\r
17751 }\r
17752 }\r
17753});\r
17754\r
17755\r
17756Ext.define('Ext.util.Positionable', {\r
17757 mixinId: 'positionable',\r
17758 _positionTopLeft: [\r
17759 'position',\r
17760 'top',\r
17761 'left'\r
17762 ],\r
17763 _alignRe: /^([a-z]+)-([a-z]+)([?!])?$/,\r
17764
17765
17766 afterSetPosition: Ext.emptyFn,\r
17767
17768
17769
17770
17771 \r
17772 getAnchorToXY: function() {\r
17773 Ext.raise("getAnchorToXY is not implemented in " + this.$className);\r
17774 },\r
17775 \r
17776 getBorderPadding: function() {\r
17777 Ext.raise("getBorderPadding is not implemented in " + this.$className);\r
17778 },\r
17779 \r
17780 getLocalX: function() {\r
17781 Ext.raise("getLocalX is not implemented in " + this.$className);\r
17782 },\r
17783 \r
17784 getLocalXY: function() {\r
17785 Ext.raise("getLocalXY is not implemented in " + this.$className);\r
17786 },\r
17787 \r
17788 getLocalY: function() {\r
17789 Ext.raise("getLocalY is not implemented in " + this.$className);\r
17790 },\r
17791 \r
17792 getX: function() {\r
17793 Ext.raise("getX is not implemented in " + this.$className);\r
17794 },\r
17795 \r
17796 getXY: function() {\r
17797 Ext.raise("getXY is not implemented in " + this.$className);\r
17798 },\r
17799 \r
17800 getY: function() {\r
17801 Ext.raise("getY is not implemented in " + this.$className);\r
17802 },\r
17803 \r
17804 setLocalX: function() {\r
17805 Ext.raise("setLocalX is not implemented in " + this.$className);\r
17806 },\r
17807 \r
17808 setLocalXY: function() {\r
17809 Ext.raise("setLocalXY is not implemented in " + this.$className);\r
17810 },\r
17811 \r
17812 setLocalY: function() {\r
17813 Ext.raise("setLocalY is not implemented in " + this.$className);\r
17814 },\r
17815 \r
17816 setX: function() {\r
17817 Ext.raise("setX is not implemented in " + this.$className);\r
17818 },\r
17819 \r
17820 setXY: function() {\r
17821 Ext.raise("setXY is not implemented in " + this.$className);\r
17822 },\r
17823 \r
17824 setY: function() {\r
17825 Ext.raise("setY is not implemented in " + this.$className);\r
17826 },\r
17827
17828
17829
17830
17831
17832 \r
17833 adjustForConstraints: function(xy, parent) {\r
17834 var vector = this.getConstrainVector(parent, xy);\r
17835 if (vector) {\r
17836 xy[0] += vector[0];\r
17837 xy[1] += vector[1];\r
17838 }\r
17839 return xy;\r
17840 },\r
17841 \r
17842 alignTo: function(element, position, offsets, \r
17843 animate) {\r
17844 var me = this,\r
17845 el = me.el;\r
17846 return me.setXY(me.getAlignToXY(element, position, offsets), el.anim && !!animate ? el.anim(animate) : false);\r
17847 },\r
17848 \r
17849 calculateAnchorXY: function(anchor, extraX, extraY, mySize) {\r
17850
17851
17852 var me = this,\r
17853 el = me.el,\r
17854 doc = document,\r
17855 isViewport = (el.dom === doc.body || el.dom === doc),\r
17856 round = Math.round,\r
17857 xy, myWidth, myHeight;\r
17858 anchor = (anchor || "tl").toLowerCase();\r
17859 mySize = mySize || {};\r
17860 myWidth = mySize.width || (isViewport ? Ext.Element.getViewportWidth() : me.getWidth());\r
17861 myHeight = mySize.height || (isViewport ? Ext.Element.getViewportHeight() : me.getHeight());\r
17862
17863
17864 switch (anchor) {\r
17865 case 'tl':\r
17866 xy = [\r
17867 0,\r
17868 0\r
17869 ];\r
17870 break;\r
17871 case 'bl':\r
17872 xy = [\r
17873 0,\r
17874 myHeight\r
17875 ];\r
17876 break;\r
17877 case 'tr':\r
17878 xy = [\r
17879 myWidth,\r
17880 0\r
17881 ];\r
17882 break;\r
17883 case 'c':\r
17884 xy = [\r
17885 round(myWidth * 0.5),\r
17886 round(myHeight * 0.5)\r
17887 ];\r
17888 break;\r
17889 case 't':\r
17890 xy = [\r
17891 round(myWidth * 0.5),\r
17892 0\r
17893 ];\r
17894 break;\r
17895 case 'l':\r
17896 xy = [\r
17897 0,\r
17898 round(myHeight * 0.5)\r
17899 ];\r
17900 break;\r
17901 case 'r':\r
17902 xy = [\r
17903 myWidth,\r
17904 round(myHeight * 0.5)\r
17905 ];\r
17906 break;\r
17907 case 'b':\r
17908 xy = [\r
17909 round(myWidth * 0.5),\r
17910 myHeight\r
17911 ];\r
17912 break;\r
17913 case 'tc':\r
17914 xy = [\r
17915 round(myWidth * 0.5),\r
17916 0\r
17917 ];\r
17918 break;\r
17919 case 'bc':\r
17920 xy = [\r
17921 round(myWidth * 0.5),\r
17922 myHeight\r
17923 ];\r
17924 break;\r
17925 case 'br':\r
17926 xy = [\r
17927 myWidth,\r
17928 myHeight\r
17929 ];\r
17930 }\r
17931 return [\r
17932 xy[0] + extraX,\r
17933 xy[1] + extraY\r
17934 ];\r
17935 },\r
17936 \r
17937 convertPositionSpec: Ext.identityFn,\r
17938 \r
17939 getAlignToXY: function(alignToEl, posSpec, offset) {\r
17940 var me = this,\r
17941 constrainToEl, constrainTo, alignMatch, myPosition, alignToElPosition, myWidth, myHeight, alignToElRegion, swapY, swapX, constrain, align1, align2, p1y, p1x, p2y, p2x, x, y;\r
17942 alignToEl = Ext.get(alignToEl.el || alignToEl);\r
17943 if (!alignToEl || !alignToEl.dom) {\r
17944
17945 Ext.raise({\r
17946 sourceClass: 'Ext.util.Positionable',\r
17947 sourceMethod: 'getAlignToXY',\r
17948 msg: 'Attempted to align an element that doesn\'t exist'\r
17949 });\r
17950 }\r
17951
17952 offset = offset || [\r
17953 0,\r
17954 0\r
17955 ];\r
17956 posSpec = (!posSpec || posSpec === "?" ? "tl-bl?" : (!(/-/).test(posSpec) && posSpec !== "" ? "tl-" + posSpec : posSpec || "tl-bl")).toLowerCase();\r
17957 posSpec = me.convertPositionSpec(posSpec);\r
17958 alignMatch = posSpec.match(me._alignRe);\r
17959
17960 if (!alignMatch) {\r
17961 Ext.raise({\r
17962 sourceClass: 'Ext.util.Positionable',\r
17963 sourceMethod: 'getAlignToXY',\r
17964 el: alignToEl,\r
17965 position: posSpec,\r
17966 offset: offset,\r
17967 msg: 'Attemmpted to align an element with an invalid position: "' + posSpec + '"'\r
17968 });\r
17969 }\r
17970
17971 align1 = alignMatch[1];\r
17972 align2 = alignMatch[2];\r
17973 constrain = !!alignMatch[3];\r
17974
17975
17976 myPosition = me.getAnchorXY(align1, true);\r
17977 alignToElPosition = me.getAnchorToXY(alignToEl, align2, false);\r
17978 x = alignToElPosition[0] - myPosition[0] + offset[0];\r
17979 y = alignToElPosition[1] - myPosition[1] + offset[1];\r
17980
17981 if (constrain) {\r
17982
17983
17984 if (alignMatch[3] === '!') {\r
17985 constrainToEl = alignToEl;\r
17986 } else {\r
17987
17988
17989
17990 constrainToEl = me.constrainTo || me.container || me.el.parent();\r
17991 }\r
17992 constrainToEl = Ext.get(constrainToEl.el || constrainToEl);\r
17993 constrainTo = constrainToEl.getConstrainRegion();\r
17994 constrainTo.right = constrainTo.left + constrainToEl.el.dom.clientWidth;\r
17995 myWidth = me.getWidth();\r
17996 myHeight = me.getHeight();\r
17997 alignToElRegion = alignToEl.getRegion();\r
17998
17999
18000
18001
18002 p1y = align1.charAt(0);\r
18003 p1x = align1.charAt(align1.length - 1);\r
18004 p2y = align2.charAt(0);\r
18005 p2x = align2.charAt(align2.length - 1);\r
18006
18007
18008 swapY = (x < alignToElRegion.right && x + myWidth >= alignToElRegion.left) && ((p1y == "t" && p2y == "b") || (p1y == "b" && p2y == "t"));\r
18009
18010
18011 swapX = (y < alignToElRegion.bottom && y + myHeight >= alignToElRegion.top) && ((p1x == "r" && p2x == "l") || (p1x == "l" && p2x == "r"));\r
18012 if (x + myWidth > constrainTo.right) {\r
18013 if (swapX) {\r
18014 x = alignToElRegion.left - myWidth;\r
18015
18016 swapX = false;\r
18017 } else {\r
18018 x = constrainTo.right - myWidth;\r
18019 }\r
18020 }\r
18021 if (x < constrainTo.left) {\r
18022 x = swapX ? alignToElRegion.right : constrainTo.left;\r
18023 }\r
18024 if (y + myHeight > constrainTo.bottom) {\r
18025 if (swapY) {\r
18026 y = alignToElRegion.top - myHeight;\r
18027
18028 swapY = false;\r
18029 } else {\r
18030 y = constrainTo.bottom - myHeight;\r
18031 }\r
18032 }\r
18033 if (y < constrainTo.top) {\r
18034 y = swapY ? alignToElRegion.bottom : constrainTo.top;\r
18035 }\r
18036 }\r
18037 return [\r
18038 x,\r
18039 y\r
18040 ];\r
18041 },\r
18042 \r
18043 getAnchorXY: function(anchor, local, mySize) {\r
18044 var me = this,\r
18045 myPos = me.getXY(),\r
18046 el = me.el,\r
18047 doc = document,\r
18048 isViewport = el.dom == doc.body || el.dom == doc,\r
18049 scroll = el.getScroll(),\r
18050 extraX = isViewport ? scroll.left : local ? 0 : myPos[0],\r
18051 extraY = isViewport ? scroll.top : local ? 0 : myPos[1];\r
18052 return me.calculateAnchorXY(anchor, extraX, extraY, mySize);\r
18053 },\r
18054 \r
18055 getBox: function(contentBox, local) {\r
18056 var me = this,\r
18057 xy = local ? me.getLocalXY() : me.getXY(),\r
18058 x = xy[0],\r
18059 y = xy[1],\r
18060 w = me.getWidth(),\r
18061 h = me.getHeight(),\r
18062 borderPadding, beforeX, beforeY;\r
18063 if (contentBox) {\r
18064 borderPadding = me.getBorderPadding();\r
18065 beforeX = borderPadding.beforeX;\r
18066 beforeY = borderPadding.beforeY;\r
18067 x += beforeX;\r
18068 y += beforeY;\r
18069 w -= (beforeX + borderPadding.afterX);\r
18070 h -= (beforeY + borderPadding.afterY);\r
18071 }\r
18072 return {\r
18073 x: x,\r
18074 left: x,\r
18075 0: x,\r
18076 y: y,\r
18077 top: y,\r
18078 1: y,\r
18079 width: w,\r
18080 height: h,\r
18081 right: x + w,\r
18082 bottom: y + h\r
18083 };\r
18084 },\r
18085 \r
18086 calculateConstrainedPosition: function(constrainTo, proposedPosition, local, proposedSize) {\r
18087 var me = this,\r
18088 vector,\r
18089 fp = me.floatParent,\r
18090 parentNode = fp ? fp.getTargetEl() : null,\r
18091 parentOffset, borderPadding, proposedConstrainPosition,\r
18092 xy = false,\r
18093 localXY;\r
18094 if (local && fp) {\r
18095 parentOffset = parentNode.getXY();\r
18096 borderPadding = parentNode.getBorderPadding();\r
18097 parentOffset[0] += borderPadding.beforeX;\r
18098 parentOffset[1] += borderPadding.beforeY;\r
18099 if (proposedPosition) {\r
18100 proposedConstrainPosition = [\r
18101 proposedPosition[0] + parentOffset[0],\r
18102 proposedPosition[1] + parentOffset[1]\r
18103 ];\r
18104 }\r
18105 } else {\r
18106 proposedConstrainPosition = proposedPosition;\r
18107 }\r
18108
18109
18110
18111 constrainTo = constrainTo || me.constrainTo || parentNode || me.container || me.el.parent();\r
18112 if (local && proposedConstrainPosition) {\r
18113 proposedConstrainPosition = me.reverseTranslateXY(proposedConstrainPosition);\r
18114 }\r
18115 vector = ((me.constrainHeader && me.header.rendered) ? me.header : me).getConstrainVector(constrainTo, proposedConstrainPosition, proposedSize);\r
18116
18117 if (vector) {\r
18118 xy = proposedPosition || me.getPosition(local);\r
18119 xy[0] += vector[0];\r
18120 xy[1] += vector[1];\r
18121 }\r
18122 return xy;\r
18123 },\r
18124 \r
18125 getConstrainRegion: function() {\r
18126 var me = this,\r
18127 el = me.el,\r
18128 isBody = el.dom.nodeName === 'BODY',\r
18129 dom = el.dom,\r
18130 borders = el.getBorders(),\r
18131 pos = el.getXY(),\r
18132 left = pos[0] + borders.beforeX,\r
18133 top = pos[1] + borders.beforeY,\r
18134 scroll, width, height;\r
18135
18136 if (isBody) {\r
18137 scroll = el.getScroll();\r
18138 left = scroll.left;\r
18139 top = scroll.top;\r
18140 width = Ext.Element.getViewportWidth();\r
18141 height = Ext.Element.getViewportHeight();\r
18142 } else {\r
18143 width = dom.clientWidth;\r
18144 height = dom.clientHeight;\r
18145 }\r
18146 return new Ext.util.Region(top, left + width, top + height, left);\r
18147 },\r
18148 \r
18149 getConstrainVector: function(constrainTo, proposedPosition, proposedSize) {\r
18150 var thisRegion = this.getRegion(),\r
18151 vector = [\r
18152 0,\r
18153 0\r
18154 ],\r
18155 shadowSize = (this.shadow && this.constrainShadow && !this.shadowDisabled) ? this.shadow.getShadowSize() : undefined,\r
18156 overflowed = false,\r
18157 constrainSize,\r
18158 constraintInsets = this.constraintInsets;\r
18159 if (!(constrainTo instanceof Ext.util.Region)) {\r
18160 constrainTo = Ext.get(constrainTo.el || constrainTo);\r
18161
18162
18163 constrainSize = constrainTo.getViewSize();\r
18164 constrainTo = constrainTo.getConstrainRegion();\r
18165 constrainTo.right = constrainTo.left + constrainSize.width;\r
18166 constrainTo.bottom = constrainTo.top + constrainSize.height;\r
18167 }\r
18168
18169 if (constraintInsets) {\r
18170 constraintInsets = Ext.isObject(constraintInsets) ? constraintInsets : Ext.Element.parseBox(constraintInsets);\r
18171 constrainTo.adjust(constraintInsets.top, constraintInsets.right, constraintInsets.bottom, constraintInsets.left);\r
18172 }\r
18173
18174 if (proposedPosition) {\r
18175 thisRegion.translateBy(proposedPosition[0] - thisRegion.x, proposedPosition[1] - thisRegion.y);\r
18176 }\r
18177
18178 if (proposedSize) {\r
18179 thisRegion.right = thisRegion.left + proposedSize[0];\r
18180 thisRegion.bottom = thisRegion.top + proposedSize[1];\r
18181 }\r
18182
18183 if (shadowSize) {\r
18184 constrainTo.adjust(shadowSize[0], -shadowSize[1], -shadowSize[2], shadowSize[3]);\r
18185 }\r
18186
18187 if (thisRegion.right > constrainTo.right) {\r
18188 overflowed = true;\r
18189 vector[0] = (constrainTo.right - thisRegion.right);\r
18190 }\r
18191
18192 if (thisRegion.left + vector[0] < constrainTo.left) {\r
18193 overflowed = true;\r
18194 vector[0] = (constrainTo.left - thisRegion.left);\r
18195 }\r
18196
18197
18198 if (thisRegion.bottom > constrainTo.bottom) {\r
18199 overflowed = true;\r
18200 vector[1] = (constrainTo.bottom - thisRegion.bottom);\r
18201 }\r
18202
18203 if (thisRegion.top + vector[1] < constrainTo.top) {\r
18204 overflowed = true;\r
18205 vector[1] = (constrainTo.top - thisRegion.top);\r
18206 }\r
18207
18208 return overflowed ? vector : false;\r
18209 },\r
18210 \r
18211 getOffsetsTo: function(offsetsTo) {\r
18212 var o = this.getXY(),\r
18213 e = Ext.fly(offsetsTo.el || offsetsTo).getXY();\r
18214 return [\r
18215 o[0] - e[0],\r
18216 o[1] - e[1]\r
18217 ];\r
18218 },\r
18219 \r
18220 getRegion: function() {\r
18221 var box = this.getBox();\r
18222 return new Ext.util.Region(box.top, box.right, box.bottom, box.left);\r
18223 },\r
18224 \r
18225 getClientRegion: function() {\r
18226 var me = this,\r
18227 scrollbarSize,\r
18228 viewContentBox = me.getBox(),\r
18229 myDom = me.dom;\r
18230
18231
18232 scrollbarSize = myDom.offsetWidth - myDom.clientWidth;\r
18233 if (scrollbarSize) {\r
18234 if (me.getStyle('direction') === 'rtl') {\r
18235 viewContentBox.left += scrollbarSize;\r
18236 } else {\r
18237 viewContentBox.right -= scrollbarSize;\r
18238 }\r
18239 }\r
18240
18241
18242 scrollbarSize = myDom.offsetHeight - myDom.clientHeight;\r
18243 if (scrollbarSize) {\r
18244 viewContentBox.bottom -= scrollbarSize;\r
18245 }\r
18246
18247 return new Ext.util.Region(viewContentBox.top, viewContentBox.right, viewContentBox.bottom, viewContentBox.left);\r
18248 },\r
18249 \r
18250 getViewRegion: function() {\r
18251 var me = this,\r
18252 el = me.el,\r
18253 isBody = el.dom.nodeName === 'BODY',\r
18254 borderPadding, scroll, pos, top, left, width, height;\r
18255
18256 if (isBody) {\r
18257 scroll = el.getScroll();\r
18258 left = scroll.left;\r
18259 top = scroll.top;\r
18260 width = Ext.Element.getViewportWidth();\r
18261 height = Ext.Element.getViewportHeight();\r
18262 } else {\r
18263 borderPadding = me.getBorderPadding();\r
18264 pos = me.getXY();\r
18265 left = pos[0] + borderPadding.beforeX;\r
18266 top = pos[1] + borderPadding.beforeY;\r
18267 width = me.getWidth(true);\r
18268 height = me.getHeight(true);\r
18269 }\r
18270 return new Ext.util.Region(top, left + width, top + height, left);\r
18271 },\r
18272 \r
18273 move: function(direction, distance, \r
18274 animate) {\r
18275 var me = this,\r
18276 xy = me.getXY(),\r
18277 x = xy[0],\r
18278 y = xy[1],\r
18279 left = [\r
18280 x - distance,\r
18281 y\r
18282 ],\r
18283 right = [\r
18284 x + distance,\r
18285 y\r
18286 ],\r
18287 top = [\r
18288 x,\r
18289 y - distance\r
18290 ],\r
18291 bottom = [\r
18292 x,\r
18293 y + distance\r
18294 ],\r
18295 hash = {\r
18296 l: left,\r
18297 left: left,\r
18298 r: right,\r
18299 right: right,\r
18300 t: top,\r
18301 top: top,\r
18302 up: top,\r
18303 b: bottom,\r
18304 bottom: bottom,\r
18305 down: bottom\r
18306 };\r
18307 direction = direction.toLowerCase();\r
18308 me.setXY([\r
18309 hash[direction][0],\r
18310 hash[direction][1]\r
18311 ], animate);\r
18312 },\r
18313 \r
18314 setBox: function(box) {\r
18315 var me = this,\r
18316 x, y;\r
18317 if (box.isRegion) {\r
18318 box = {\r
18319 x: box.left,\r
18320 y: box.top,\r
18321 width: box.right - box.left,\r
18322 height: box.bottom - box.top\r
18323 };\r
18324 }\r
18325 me.constrainBox(box);\r
18326 x = box.x;\r
18327 y = box.y;\r
18328
18329
18330 me.setXY([\r
18331 x,\r
18332 y\r
18333 ]);\r
18334 me.setSize(box.width, box.height);\r
18335 me.afterSetPosition(x, y);\r
18336 return me;\r
18337 },\r
18338 \r
18339 constrainBox: function(box) {\r
18340 var me = this,\r
18341 constrainedPos, x, y;\r
18342 if (me.constrain || me.constrainHeader) {\r
18343 x = ('x' in box) ? box.x : box.left;\r
18344 y = ('y' in box) ? box.y : box.top;\r
18345 constrainedPos = me.calculateConstrainedPosition(null, [\r
18346 x,\r
18347 y\r
18348 ], false, [\r
18349 box.width,\r
18350 box.height\r
18351 ]);\r
18352
18353 if (constrainedPos) {\r
18354 box.x = constrainedPos[0];\r
18355 box.y = constrainedPos[1];\r
18356 }\r
18357 }\r
18358 },\r
18359 \r
18360 translatePoints: function(x, y) {\r
18361 var pos = this.translateXY(x, y);\r
18362 return {\r
18363 left: pos.x,\r
18364 top: pos.y\r
18365 };\r
18366 },\r
18367 \r
18368 translateXY: function(x, y) {\r
18369 var me = this,\r
18370 el = me.el,\r
18371 styles = el.getStyle(me._positionTopLeft),\r
18372 relative = styles.position === 'relative',\r
18373 left = parseFloat(styles.left),\r
18374 top = parseFloat(styles.top),\r
18375 xy = me.getXY();\r
18376 if (Ext.isArray(x)) {\r
18377 y = x[1];\r
18378 x = x[0];\r
18379 }\r
18380 if (isNaN(left)) {\r
18381 left = relative ? 0 : el.dom.offsetLeft;\r
18382 }\r
18383 if (isNaN(top)) {\r
18384 top = relative ? 0 : el.dom.offsetTop;\r
18385 }\r
18386 left = (typeof x === 'number') ? x - xy[0] + left : undefined;\r
18387 top = (typeof y === 'number') ? y - xy[1] + top : undefined;\r
18388 return {\r
18389 x: left,\r
18390 y: top\r
18391 };\r
18392 },\r
18393 \r
18394 reverseTranslateXY: function(xy) {\r
18395 var coords = xy,\r
18396 el = this.el,\r
18397 translatedXY = [],\r
18398 dom = el.dom,\r
18399 offsetParent = dom.offsetParent,\r
18400 relative, offsetParentXY, x, y;\r
18401 if (offsetParent) {\r
18402 relative = el.isStyle('position', 'relative') , offsetParentXY = Ext.fly(offsetParent).getXY() , x = xy[0] + offsetParentXY[0] + offsetParent.clientLeft;\r
18403 y = xy[1] + offsetParentXY[1] + offsetParent.clientTop;\r
18404 if (relative) {\r
18405
18406
18407 x += el.getPadding('l');\r
18408 y += el.getPadding('t');\r
18409 }\r
18410 coords = [\r
18411 x,\r
18412 y\r
18413 ];\r
18414 }\r
18415 return coords;\r
18416 }\r
18417});\r
18418\r
18419\r
18420Ext.define('Ext.dom.UnderlayPool', {\r
18421 \r
18422 constructor: function(elementConfig) {\r
18423 this.elementConfig = elementConfig;\r
18424 this.cache = [];\r
18425 },\r
18426 \r
18427 checkOut: function() {\r
18428 var el = this.cache.shift();\r
18429 if (!el) {\r
18430 el = Ext.Element.create(this.elementConfig);\r
18431 el.setVisibilityMode(2);\r
18432
18433
18434 el.dom.setAttribute('data-sticky', true);\r
18435 }\r
18436
18437 return el;\r
18438 },\r
18439 \r
18440 checkIn: function(el) {\r
18441 this.cache.push(el);\r
18442 },\r
18443 \r
18444 reset: function() {\r
18445 var cache = this.cache,\r
18446 i = cache.length;\r
18447 while (i--) {\r
18448 cache[i].destroy();\r
18449 }\r
18450 this.cache = [];\r
18451 }\r
18452});\r
18453\r
18454\r
18455Ext.define('Ext.dom.Underlay', {\r
18456 \r
18457 \r
18458 constructor: function(config) {\r
18459 Ext.apply(this, config);\r
18460 },\r
18461 \r
18462 beforeShow: Ext.emptyFn,\r
18463 \r
18464 getInsertionTarget: function() {\r
18465 return this.target;\r
18466 },\r
18467 \r
18468 getPool: function() {\r
18469 return this.pool || (this.self.prototype.pool = new Ext.dom.UnderlayPool(this.elementConfig));\r
18470 },\r
18471 \r
18472 hide: function() {\r
18473 var me = this,\r
18474 el = me.el;\r
18475 if (el) {\r
18476 el.hide();\r
18477 me.getPool().checkIn(el);\r
18478 me.el = null;\r
18479 me.hidden = true;\r
18480 }\r
18481 },\r
18482 \r
18483 realign: function(x, y, width, height) {\r
18484 var me = this,\r
18485 el = me.el,\r
18486 target = me.target,\r
18487 offsets = me.offsets,\r
18488 max = Math.max;\r
18489 if (el) {\r
18490 if (x == null) {\r
18491 x = target.getX();\r
18492 }\r
18493 if (y == null) {\r
18494 y = target.getY();\r
18495 }\r
18496 if (width == null) {\r
18497 width = target.getWidth();\r
18498 }\r
18499 if (height == null) {\r
18500 height = target.getHeight();\r
18501 }\r
18502 if (offsets) {\r
18503 x = x + offsets.x;\r
18504 y = y + offsets.y;\r
18505 width = max(width + offsets.w, 0);\r
18506 height = max(height + offsets.h, 0);\r
18507 }\r
18508 el.setXY([\r
18509 x,\r
18510 y\r
18511 ]);\r
18512 el.setSize(width, height);\r
18513 }\r
18514 },\r
18515 \r
18516 setZIndex: function(zIndex) {\r
18517 this.zIndex = zIndex;\r
18518 if (this.el) {\r
18519 this.el.setStyle("z-index", zIndex);\r
18520 }\r
18521 },\r
18522 \r
18523 show: function() {\r
18524 var me = this,\r
18525 target = me.target,\r
18526 zIndex = me.zIndex,\r
18527 el = me.el,\r
18528 insertionTarget = me.getInsertionTarget().dom,\r
18529 dom;\r
18530 if (!el) {\r
18531 el = me.el = me.getPool().checkOut();\r
18532 }\r
18533 me.beforeShow();\r
18534 if (zIndex == null) {\r
18535
18536
18537
18538
18539
18540
18541 zIndex = (parseInt(target.getStyle("z-index"), 10));\r
18542 }\r
18543 if (zIndex) {\r
18544 el.setStyle("z-index", zIndex);\r
18545 }\r
18546
18547 el.setStyle('position', me.fixed ? 'fixed' : '');\r
18548 dom = el.dom;\r
18549 if (dom.nextSibling !== insertionTarget) {\r
18550
18551
18552
18553 target.dom.parentNode.insertBefore(dom, insertionTarget);\r
18554 }\r
18555 el.show();\r
18556 me.realign();\r
18557 me.hidden = false;\r
18558 }\r
18559});\r
18560\r
18561\r
18562Ext.define('Ext.dom.Shadow', {\r
18563 extend: Ext.dom.Underlay,\r
18564 alternateClassName: 'Ext.Shadow',\r
18565 \r
18566 mode: 'drop',\r
18567 \r
18568 offset: 4,\r
18569 cls: Ext.baseCSSPrefix + (!Ext.supports.CSS3BoxShadow ? 'ie' : 'css') + '-shadow',\r
18570 \r
18571 constructor: function(config) {\r
18572 var me = this,\r
18573 outerOffsets, offsets, offset, rad;\r
18574 me.callParent([\r
18575 config\r
18576 ]);\r
18577 me.elementConfig = {\r
18578 cls: me.cls,\r
18579 role: 'presentation'\r
18580 };\r
18581 offset = me.offset;\r
18582 rad = Math.floor(offset / 2);\r
18583 me.opacity = 50;\r
18584 switch (me.mode.toLowerCase()) {\r
18585 case "drop":\r
18586 outerOffsets = {\r
18587 x: 0,\r
18588 y: 0,\r
18589 w: offset,\r
18590 h: offset\r
18591 };\r
18592 if (Ext.supports.CSS3BoxShadow) {\r
18593 offsets = {\r
18594 x: offset,\r
18595 y: offset,\r
18596 h: -offset,\r
18597 w: -offset\r
18598 };\r
18599 } else {\r
18600 offsets = {\r
18601 x: -rad,\r
18602 y: -rad,\r
18603 h: -rad,\r
18604 w: -rad\r
18605 };\r
18606 };\r
18607 break;\r
18608 case "sides":\r
18609 outerOffsets = {\r
18610 x: -offset,\r
18611 y: 0,\r
18612 w: offset * 2,\r
18613 h: offset\r
18614 };\r
18615 if (Ext.supports.CSS3BoxShadow) {\r
18616 offsets = {\r
18617 x: 0,\r
18618 y: offset,\r
18619 h: -offset,\r
18620 w: 0\r
18621 };\r
18622 } else {\r
18623 offsets = {\r
18624 x: 1 + rad - 2 * offset,\r
18625 y: -(1 + rad),\r
18626 h: -1,\r
18627 w: rad - 1\r
18628 };\r
18629 };\r
18630 break;\r
18631 case "frame":\r
18632 outerOffsets = {\r
18633 x: -offset,\r
18634 y: -offset,\r
18635 w: offset * 2,\r
18636 h: offset * 2\r
18637 };\r
18638 if (Ext.supports.CSS3BoxShadow) {\r
18639 offsets = {\r
18640 x: 0,\r
18641 y: 0,\r
18642 h: 0,\r
18643 w: 0\r
18644 };\r
18645 } else {\r
18646 offsets = {\r
18647 x: 1 + rad - 2 * offset,\r
18648 y: 1 + rad - 2 * offset,\r
18649 h: offset - rad - 1,\r
18650 w: offset - rad - 1\r
18651 };\r
18652 };\r
18653 break;\r
18654 case "bottom":\r
18655 outerOffsets = {\r
18656 x: -offset,\r
18657 y: 0,\r
18658 w: offset * 2,\r
18659 h: offset\r
18660 };\r
18661 if (Ext.supports.CSS3BoxShadow) {\r
18662 offsets = {\r
18663 x: 0,\r
18664 y: offset,\r
18665 h: -offset,\r
18666 w: 0\r
18667 };\r
18668 } else {\r
18669 offsets = {\r
18670 x: 0,\r
18671 y: offset,\r
18672 h: 0,\r
18673 w: 0\r
18674 };\r
18675 };\r
18676 break;\r
18677 }\r
18678 \r
18679 me.offsets = offsets;\r
18680 \r
18681 me.outerOffsets = outerOffsets;\r
18682 },\r
18683 \r
18684 getShadowSize: function() {\r
18685 var me = this,\r
18686 offset = me.el ? me.offset : 0,\r
18687 result = [\r
18688 offset,\r
18689 offset,\r
18690 offset,\r
18691 offset\r
18692 ],\r
18693 mode = me.mode.toLowerCase();\r
18694
18695 if (me.el && mode !== 'frame') {\r
18696 result[0] = 0;\r
18697 if (mode == 'drop') {\r
18698 result[3] = 0;\r
18699 }\r
18700 }\r
18701 return result;\r
18702 },\r
18703 \r
18704 boxShadowProperty: (function() {\r
18705 var property = 'boxShadow',\r
18706 style = document.documentElement.style;\r
18707 if (!('boxShadow' in style)) {\r
18708 if ('WebkitBoxShadow' in style) {\r
18709
18710 property = 'WebkitBoxShadow';\r
18711 } else if ('MozBoxShadow' in style) {\r
18712
18713 property = 'MozBoxShadow';\r
18714 }\r
18715 }\r
18716 return property;\r
18717 }()),\r
18718 beforeShow: function() {\r
18719 var me = this,\r
18720 style = me.el.dom.style,\r
18721 shim = me.shim;\r
18722 if (Ext.supports.CSS3BoxShadow) {\r
18723 style[me.boxShadowProperty] = '0 0 ' + (me.offset + 2) + 'px #888';\r
18724 } else {\r
18725 style.filter = "progid:DXImageTransform.Microsoft.alpha(opacity=" + me.opacity + ") progid:DXImageTransform.Microsoft.Blur(pixelradius=" + (me.offset) + ")";\r
18726 }\r
18727
18728
18729 if (shim) {\r
18730 shim.realign();\r
18731 }\r
18732 },\r
18733 \r
18734 setOpacity: function(opacity) {\r
18735 var el = this.el;\r
18736 if (el) {\r
18737 if (Ext.isIE && !Ext.supports.CSS3BoxShadow) {\r
18738 opacity = Math.floor(opacity * 100 / 2) / 100;\r
18739 }\r
18740 this.opacity = opacity;\r
18741 el.setOpacity(opacity);\r
18742 }\r
18743 }\r
18744});\r
18745\r
18746\r
18747Ext.define('Ext.dom.Shim', {\r
18748 extend: Ext.dom.Underlay,\r
18749 cls: Ext.baseCSSPrefix + 'shim',\r
18750 constructor: function(config) {\r
18751 this.callParent([\r
18752 config\r
18753 ]);\r
18754 this.elementConfig = {\r
18755 tag: 'iframe',\r
18756 cls: this.cls,\r
18757 role: 'presentation',\r
18758 frameBorder: '0',\r
18759 src: Ext.SSL_SECURE_URL,\r
18760
18761 tabindex: '-1'\r
18762 };\r
18763 },\r
18764 getInsertionTarget: function() {\r
18765
18766
18767 var shadow = this.shadow;\r
18768 return (shadow && shadow.el) || this.target;\r
18769 }\r
18770});\r
18771\r
18772\r
18773Ext.define('Ext.dom.ElementEvent', {\r
18774 extend: Ext.util.Event,\r
18775 addListener: function(fn, scope, options, caller, manager) {\r
18776 var me = this,\r
18777 added = false,\r
18778 name = me.name,\r
18779 captures, directs, directCaptures;\r
18780 options = options || {};\r
18781 if (options.delegated === false || Ext.event.publisher.Dom.instance.directEvents[name]) {\r
18782 if (options.capture) {\r
18783 directCaptures = me.directCaptures || (me.directCaptures = new Ext.util.Event(me.observable, name));\r
18784 added = directCaptures.addListener(fn, scope, options, caller, manager);\r
18785 } else {\r
18786 directs = me.directs || (me.directs = new Ext.util.Event(me.observable, name));\r
18787 added = directs.addListener(fn, scope, options, caller, manager);\r
18788 }\r
18789 } else if (options.capture) {\r
18790 captures = me.captures || (me.captures = new Ext.util.Event(me.observable, name));\r
18791 added = captures.addListener(fn, scope, options, caller, manager);\r
18792 } else {\r
18793 added = me.callParent([\r
18794 fn,\r
18795 scope,\r
18796 options,\r
18797 caller,\r
18798 manager\r
18799 ]);\r
18800 }\r
18801 return added;\r
18802 },\r
18803 removeListener: function(fn, scope) {\r
18804 var me = this,\r
18805 captures = me.captures,\r
18806 directs = me.directs,\r
18807 directCaptures = me.directCaptures,\r
18808 removed = false,\r
18809 index = me.findListener(fn, scope);\r
18810 if (index !== -1) {\r
18811 removed = me.callParent([\r
18812 fn,\r
18813 scope,\r
18814 index\r
18815 ]);\r
18816 } else {\r
18817 if (directs) {\r
18818 index = directs.findListener(fn, scope);\r
18819 }\r
18820 if (index !== -1) {\r
18821 removed = directs.removeListener(fn, scope, index);\r
18822 } else {\r
18823 if (captures) {\r
18824 index = captures.findListener(fn, scope);\r
18825 }\r
18826 if (index !== -1) {\r
18827 removed = captures.removeListener(fn, scope, index);\r
18828 } else if (directCaptures) {\r
18829 index = directCaptures.findListener(fn, scope);\r
18830 if (index !== -1) {\r
18831 removed = directCaptures.removeListener(fn, scope, index);\r
18832 }\r
18833 }\r
18834 }\r
18835 }\r
18836 return removed;\r
18837 },\r
18838 clearListeners: function() {\r
18839 var me = this,\r
18840 directCaptures = me.directCaptures,\r
18841 directs = me.directs,\r
18842 captures = me.captures;\r
18843 if (directCaptures) {\r
18844 directCaptures.clearListeners();\r
18845 }\r
18846 if (directs) {\r
18847 directs.clearListeners();\r
18848 }\r
18849 if (captures) {\r
18850 captures.clearListeners();\r
18851 }\r
18852 me.callParent();\r
18853 },\r
18854 suspend: function() {\r
18855 var me = this,\r
18856 directCaptures = me.directCaptures,\r
18857 directs = me.directs,\r
18858 captures = me.captures;\r
18859 if (directCaptures) {\r
18860 directCaptures.suspend();\r
18861 }\r
18862 if (directs) {\r
18863 directs.suspend();\r
18864 }\r
18865 if (captures) {\r
18866 captures.suspend();\r
18867 }\r
18868 me.callParent();\r
18869 },\r
18870 resume: function() {\r
18871 var me = this,\r
18872 directCaptures = me.directCaptures,\r
18873 directs = me.directs,\r
18874 captures = me.captures;\r
18875 if (directCaptures) {\r
18876 directCaptures.resume();\r
18877 }\r
18878 if (directs) {\r
18879 directs.resume();\r
18880 }\r
18881 if (captures) {\r
18882 captures.resume();\r
18883 }\r
18884 me.callParent();\r
18885 }\r
18886});\r
18887\r
18888\r
18889Ext.define('Ext.event.publisher.Publisher', {\r
18890 \r
18891 handledEvents: [],\r
18892 statics: {\r
18893 \r
18894 publishers: {},\r
18895 \r
18896 publishersByEvent: {}\r
18897 },\r
18898 constructor: function() {\r
18899 var me = this,\r
18900 type = me.type;\r
18901 \r
18902 me.handles = {};\r
18903
18904 if (!type) {\r
18905 Ext.raise("Event publisher '" + me.$className + "' defined without a 'type' property.");\r
18906 }\r
18907 if (me.self.instance) {\r
18908 Ext.raise("Cannot create multiple instances of '" + me.$className + "'. " + "Use '" + me.$className + ".instance' to retrieve the singleton instance.");\r
18909 }\r
18910
18911 me.registerEvents();\r
18912 Ext.event.publisher.Publisher.publishers[type] = me;\r
18913 },\r
18914 \r
18915 registerEvents: function(events) {\r
18916 var me = this,\r
18917 publishersByEvent = Ext.event.publisher.Publisher.publishersByEvent,\r
18918 handledEvents = events || me.handledEvents,\r
18919 ln = handledEvents.length,\r
18920 eventName, i;\r
18921 for (i = 0; i < ln; i++) {\r
18922 eventName = handledEvents[i];\r
18923 me.handles[eventName] = 1;\r
18924 publishersByEvent[eventName] = me;\r
18925 }\r
18926 },\r
18927
18928 subscribe: function() {\r
18929 Ext.raise("Ext.event.publisher.Publisher subclass '" + this.$className + '" has no subscribe method.');\r
18930 },\r
18931 unsubscribe: function() {\r
18932 Ext.raise("Ext.event.publisher.Publisher subclass '" + this.$className + '" has no unsubscribe method.');\r
18933 },\r
18934
18935 fire: function(element, eventName, args) {\r
18936 var event;\r
18937 if (element.hasListeners[eventName]) {\r
18938 event = element.events[eventName];\r
18939 if (event) {\r
18940 event.fire.apply(event, args);\r
18941 }\r
18942 }\r
18943 }\r
18944});\r
18945\r
18946\r
18947Ext.define('Ext.util.Offset', {\r
18948 \r
18949 statics: {\r
18950 fromObject: function(obj) {\r
18951 return new this(obj.x, obj.y);\r
18952 }\r
18953 },\r
18954 \r
18955 constructor: function(x, y) {\r
18956 this.x = (x != null && !isNaN(x)) ? x : 0;\r
18957 this.y = (y != null && !isNaN(y)) ? y : 0;\r
18958 return this;\r
18959 },\r
18960 copy: function() {\r
18961 return new Ext.util.Offset(this.x, this.y);\r
18962 },\r
18963 copyFrom: function(p) {\r
18964 this.x = p.x;\r
18965 this.y = p.y;\r
18966 },\r
18967 toString: function() {\r
18968 return "Offset[" + this.x + "," + this.y + "]";\r
18969 },\r
18970 equals: function(offset) {\r
18971
18972 if (!(offset instanceof this.statics())) {\r
18973 Ext.raise('Offset must be an instance of Ext.util.Offset');\r
18974 }\r
18975
18976 return (this.x == offset.x && this.y == offset.y);\r
18977 },\r
18978 round: function(to) {\r
18979 if (!isNaN(to)) {\r
18980 var factor = Math.pow(10, to);\r
18981 this.x = Math.round(this.x * factor) / factor;\r
18982 this.y = Math.round(this.y * factor) / factor;\r
18983 } else {\r
18984 this.x = Math.round(this.x);\r
18985 this.y = Math.round(this.y);\r
18986 }\r
18987 },\r
18988 isZero: function() {\r
18989 return this.x == 0 && this.y == 0;\r
18990 }\r
18991});\r
18992\r
18993\r
18994Ext.define('Ext.util.Region', {\r
18995 isRegion: true,\r
18996 statics: {\r
18997 \r
18998 getRegion: function(el) {\r
18999 return Ext.fly(el).getRegion();\r
19000 },\r
19001 \r
19002 from: function(o) {\r
19003 return new this(o.top, o.right, o.bottom, o.left);\r
19004 }\r
19005 },\r
19006 \r
19007 \r
19008 constructor: function(top, right, bottom, left) {\r
19009 var me = this;\r
19010 me.y = me.top = me[1] = top;\r
19011 me.right = right;\r
19012 me.bottom = bottom;\r
19013 me.x = me.left = me[0] = left;\r
19014 },\r
19015 \r
19016 contains: function(region) {\r
19017 var me = this;\r
19018 return (region.x >= me.x && region.right <= me.right && region.y >= me.y && region.bottom <= me.bottom);\r
19019 },\r
19020 \r
19021 intersect: function(region) {\r
19022 var me = this,\r
19023 t = Math.max(me.y, region.y),\r
19024 r = Math.min(me.right, region.right),\r
19025 b = Math.min(me.bottom, region.bottom),\r
19026 l = Math.max(me.x, region.x);\r
19027 if (b > t && r > l) {\r
19028 return new this.self(t, r, b, l);\r
19029 } else {\r
19030 return false;\r
19031 }\r
19032 },\r
19033 \r
19034 union: function(region) {\r
19035 var me = this,\r
19036 t = Math.min(me.y, region.y),\r
19037 r = Math.max(me.right, region.right),\r
19038 b = Math.max(me.bottom, region.bottom),\r
19039 l = Math.min(me.x, region.x);\r
19040 return new this.self(t, r, b, l);\r
19041 },\r
19042 \r
19043 constrainTo: function(r) {\r
19044 var me = this,\r
19045 constrain = Ext.Number.constrain;\r
19046 me.top = me.y = constrain(me.top, r.y, r.bottom);\r
19047 me.bottom = constrain(me.bottom, r.y, r.bottom);\r
19048 me.left = me.x = constrain(me.left, r.x, r.right);\r
19049 me.right = constrain(me.right, r.x, r.right);\r
19050 return me;\r
19051 },\r
19052 \r
19053 adjust: function(top, right, bottom, left) {\r
19054 var me = this;\r
19055 me.top = me.y += top;\r
19056 me.left = me.x += left;\r
19057 me.right += right;\r
19058 me.bottom += bottom;\r
19059 return me;\r
19060 },\r
19061 \r
19062 getOutOfBoundOffset: function(axis, p) {\r
19063 if (!Ext.isObject(axis)) {\r
19064 if (axis == 'x') {\r
19065 return this.getOutOfBoundOffsetX(p);\r
19066 } else {\r
19067 return this.getOutOfBoundOffsetY(p);\r
19068 }\r
19069 } else {\r
19070 p = axis;\r
19071 var d = new Ext.util.Offset();\r
19072 d.x = this.getOutOfBoundOffsetX(p.x);\r
19073 d.y = this.getOutOfBoundOffsetY(p.y);\r
19074 return d;\r
19075 }\r
19076 },\r
19077 \r
19078 getOutOfBoundOffsetX: function(p) {\r
19079 if (p <= this.x) {\r
19080 return this.x - p;\r
19081 } else if (p >= this.right) {\r
19082 return this.right - p;\r
19083 }\r
19084 return 0;\r
19085 },\r
19086 \r
19087 getOutOfBoundOffsetY: function(p) {\r
19088 if (p <= this.y) {\r
19089 return this.y - p;\r
19090 } else if (p >= this.bottom) {\r
19091 return this.bottom - p;\r
19092 }\r
19093 return 0;\r
19094 },\r
19095 \r
19096 isOutOfBound: function(axis, p) {\r
19097 if (!Ext.isObject(axis)) {\r
19098 if (axis == 'x') {\r
19099 return this.isOutOfBoundX(p);\r
19100 } else {\r
19101 return this.isOutOfBoundY(p);\r
19102 }\r
19103 } else {\r
19104 p = axis;\r
19105 return (this.isOutOfBoundX(p.x) || this.isOutOfBoundY(p.y));\r
19106 }\r
19107 },\r
19108 \r
19109 isOutOfBoundX: function(p) {\r
19110 return (p < this.x || p > this.right);\r
19111 },\r
19112 \r
19113 isOutOfBoundY: function(p) {\r
19114 return (p < this.y || p > this.bottom);\r
19115 },\r
19116 \r
19117 restrict: function(axis, p, factor) {\r
19118 if (Ext.isObject(axis)) {\r
19119 var newP;\r
19120 factor = p;\r
19121 p = axis;\r
19122 if (p.copy) {\r
19123 newP = p.copy();\r
19124 } else {\r
19125 newP = {\r
19126 x: p.x,\r
19127 y: p.y\r
19128 };\r
19129 }\r
19130 newP.x = this.restrictX(p.x, factor);\r
19131 newP.y = this.restrictY(p.y, factor);\r
19132 return newP;\r
19133 } else {\r
19134 if (axis == 'x') {\r
19135 return this.restrictX(p, factor);\r
19136 } else {\r
19137 return this.restrictY(p, factor);\r
19138 }\r
19139 }\r
19140 },\r
19141 \r
19142 restrictX: function(p, factor) {\r
19143 if (!factor) {\r
19144 factor = 1;\r
19145 }\r
19146 if (p <= this.x) {\r
19147 p -= (p - this.x) * factor;\r
19148 } else if (p >= this.right) {\r
19149 p -= (p - this.right) * factor;\r
19150 }\r
19151 return p;\r
19152 },\r
19153 \r
19154 restrictY: function(p, factor) {\r
19155 if (!factor) {\r
19156 factor = 1;\r
19157 }\r
19158 if (p <= this.y) {\r
19159 p -= (p - this.y) * factor;\r
19160 } else if (p >= this.bottom) {\r
19161 p -= (p - this.bottom) * factor;\r
19162 }\r
19163 return p;\r
19164 },\r
19165 \r
19166 getSize: function() {\r
19167 return {\r
19168 width: this.right - this.x,\r
19169 height: this.bottom - this.y\r
19170 };\r
19171 },\r
19172 \r
19173 copy: function() {\r
19174 return new this.self(this.y, this.right, this.bottom, this.x);\r
19175 },\r
19176 \r
19177 copyFrom: function(p) {\r
19178 var me = this;\r
19179 me.top = me.y = me[1] = p.y;\r
19180 me.right = p.right;\r
19181 me.bottom = p.bottom;\r
19182 me.left = me.x = me[0] = p.x;\r
19183 return this;\r
19184 },\r
19185 \r
19186 toString: function() {\r
19187 return "Region[" + this.top + "," + this.right + "," + this.bottom + "," + this.left + "]";\r
19188 },\r
19189 \r
19190 translateBy: function(x, y) {\r
19191 if (arguments.length == 1) {\r
19192 y = x.y;\r
19193 x = x.x;\r
19194 }\r
19195 var me = this;\r
19196 me.top = me.y += y;\r
19197 me.right += x;\r
19198 me.bottom += y;\r
19199 me.left = me.x += x;\r
19200 return me;\r
19201 },\r
19202 \r
19203 round: function() {\r
19204 var me = this;\r
19205 me.top = me.y = Math.round(me.y);\r
19206 me.right = Math.round(me.right);\r
19207 me.bottom = Math.round(me.bottom);\r
19208 me.left = me.x = Math.round(me.x);\r
19209 return me;\r
19210 },\r
19211 \r
19212 equals: function(region) {\r
19213 return (this.top === region.top && this.right === region.right && this.bottom === region.bottom && this.left === region.left);\r
19214 }\r
19215});\r
19216\r
19217\r
19218Ext.define('Ext.util.Point', {\r
19219 extend: Ext.util.Region,\r
19220 radianToDegreeConstant: 180 / Math.PI,\r
19221 origin: {\r
19222 x: 0,\r
19223 y: 0\r
19224 },\r
19225 statics: {\r
19226 \r
19227 fromEvent: function(e) {\r
19228 var changedTouches = e.changedTouches,\r
19229 touch = (changedTouches && changedTouches.length > 0) ? changedTouches[0] : e;\r
19230 return this.fromTouch(touch);\r
19231 },\r
19232 \r
19233 fromTouch: function(touch) {\r
19234 return new this(touch.pageX, touch.pageY);\r
19235 },\r
19236 \r
19237 from: function(object) {\r
19238 if (!object) {\r
19239 return new this(0, 0);\r
19240 }\r
19241 if (!(object instanceof this)) {\r
19242 return new this(object.x, object.y);\r
19243 }\r
19244 return object;\r
19245 }\r
19246 },\r
19247 \r
19248 constructor: function(x, y) {\r
19249 if (x == null) {\r
19250 x = 0;\r
19251 }\r
19252 if (y == null) {\r
19253 y = 0;\r
19254 }\r
19255 this.callParent([\r
19256 y,\r
19257 x,\r
19258 y,\r
19259 x\r
19260 ]);\r
19261 },\r
19262 \r
19263 clone: function() {\r
19264 return new this.self(this.x, this.y);\r
19265 },\r
19266 \r
19267 copy: function() {\r
19268 return this.clone.apply(this, arguments);\r
19269 },\r
19270 \r
19271 copyFrom: function(point) {\r
19272 this.x = point.x;\r
19273 this.y = point.y;\r
19274 return this;\r
19275 },\r
19276 \r
19277 toString: function() {\r
19278 return "Point[" + this.x + "," + this.y + "]";\r
19279 },\r
19280 \r
19281 equals: function(point) {\r
19282 return (this.x === point.x && this.y === point.y);\r
19283 },\r
19284 \r
19285 isCloseTo: function(point, threshold) {\r
19286 if (typeof threshold == 'number') {\r
19287 return this.getDistanceTo(point) <= threshold;\r
19288 }\r
19289 var x = point.x,\r
19290 y = point.y,\r
19291 thresholdX = threshold.x,\r
19292 thresholdY = threshold.y;\r
19293 return (this.x <= x + thresholdX && this.x >= x - thresholdX && this.y <= y + thresholdY && this.y >= y - thresholdY);\r
19294 },\r
19295 \r
19296 isWithin: function() {\r
19297 return this.isCloseTo.apply(this, arguments);\r
19298 },\r
19299 \r
19300 isContainedBy: function(region) {\r
19301 if (!(region instanceof Ext.util.Region)) {\r
19302 region = Ext.get(region.el || region).getRegion();\r
19303 }\r
19304 return region.contains(this);\r
19305 },\r
19306 \r
19307 roundedEquals: function(point) {\r
19308 if (!point || typeof point !== 'object') {\r
19309 point = this.origin;\r
19310 }\r
19311 return (Math.round(this.x) === Math.round(point.x) && Math.round(this.y) === Math.round(point.y));\r
19312 },\r
19313 getDistanceTo: function(point) {\r
19314 if (!point || typeof point !== 'object') {\r
19315 point = this.origin;\r
19316 }\r
19317 var deltaX = this.x - point.x,\r
19318 deltaY = this.y - point.y;\r
19319 return Math.sqrt(deltaX * deltaX + deltaY * deltaY);\r
19320 },\r
19321 getAngleTo: function(point) {\r
19322 if (!point || typeof point !== 'object') {\r
19323 point = this.origin;\r
19324 }\r
19325 var deltaX = this.x - point.x,\r
19326 deltaY = this.y - point.y;\r
19327 return Math.atan2(deltaY, deltaX) * this.radianToDegreeConstant;\r
19328 }\r
19329}, function() {\r
19330 \r
19331 this.prototype.translate = this.prototype.translateBy;\r
19332});\r
19333\r
19334\r
19335Ext.define('Ext.event.Event', {\r
19336 alternateClassName: 'Ext.EventObjectImpl',\r
19337 \r
19338 \r
19339 \r
19340 \r
19341 \r
19342 \r
19343 \r
19344 \r
19345 \r
19346 \r
19347 \r
19348 isStopped: false,\r
19349 \r
19350 defaultPrevented: false,\r
19351 isEvent: true,\r
19352 statics: {\r
19353 resolveTextNode: function(node) {\r
19354 return (node && node.nodeType === 3) ? node.parentNode : node;\r
19355 },\r
19356 \r
19357 pointerEvents: {\r
19358 pointerdown: 1,\r
19359 pointermove: 1,\r
19360 pointerup: 1,\r
19361 pointercancel: 1,\r
19362 pointerover: 1,\r
19363 pointerout: 1,\r
19364 pointerenter: 1,\r
19365 pointerleave: 1,\r
19366 MSPointerDown: 1,\r
19367 MSPointerMove: 1,\r
19368 MSPointerUp: 1,\r
19369 MSPointerOver: 1,\r
19370 MSPointerOut: 1,\r
19371 MSPointerCancel: 1,\r
19372 MSPointerEnter: 1,\r
19373 MSPointerLeave: 1\r
19374 },\r
19375 \r
19376 mouseEvents: {\r
19377 mousedown: 1,\r
19378 mousemove: 1,\r
19379 mouseup: 1,\r
19380 mouseover: 1,\r
19381 mouseout: 1,\r
19382 mouseenter: 1,\r
19383 mouseleave: 1\r
19384 },\r
19385 \r
19386 clickEvents: {\r
19387 click: 1,\r
19388 dblclick: 1\r
19389 },\r
19390 \r
19391 touchEvents: {\r
19392 touchstart: 1,\r
19393 touchmove: 1,\r
19394 touchend: 1,\r
19395 touchcancel: 1\r
19396 },\r
19397 \r
19398 focusEvents: {\r
19399 focus: 1,\r
19400 blur: 1,\r
19401 focusin: 1,\r
19402 focusout: 1,\r
19403 focusenter: 1,\r
19404 focusleave: 1\r
19405 },\r
19406
19407
19408
19409
19410 pointerTypes: {\r
19411 2: 'touch',\r
19412 3: 'pen',\r
19413 4: 'mouse',\r
19414 touch: 'touch',\r
19415 pen: 'pen',\r
19416 mouse: 'mouse'\r
19417 }\r
19418 },\r
19419 constructor: function(event) {\r
19420 var me = this,\r
19421 self = me.self,\r
19422 resolveTextNode = me.self.resolveTextNode,\r
19423 changedTouches = event.changedTouches,\r
19424
19425
19426
19427 coordinateOwner = changedTouches ? changedTouches[0] : event,\r
19428 type = event.type,\r
19429 pointerType, relatedTarget;\r
19430 me.pageX = coordinateOwner.pageX;\r
19431 me.pageY = coordinateOwner.pageY;\r
19432 me.target = me.delegatedTarget = resolveTextNode(event.target);\r
19433 relatedTarget = event.relatedTarget;\r
19434 if (relatedTarget) {\r
19435 me.relatedTarget = resolveTextNode(relatedTarget);\r
19436 }\r
19437 me.browserEvent = me.event = event;\r
19438 me.type = type;\r
19439
19440
19441 me.button = event.button || 0;\r
19442 me.shiftKey = event.shiftKey;\r
19443
19444 me.ctrlKey = event.ctrlKey || event.metaKey || false;\r
19445 me.altKey = event.altKey;\r
19446 me.charCode = event.charCode;\r
19447 me.keyCode = event.keyCode;\r
19448 me.buttons = event.buttons;\r
19449
19450
19451
19452
19453
19454 if (me.button === 0 && me.buttons === 0) {\r
19455 me.buttons = 1;\r
19456 }\r
19457 if (self.forwardTab !== undefined && self.focusEvents[type]) {\r
19458 me.forwardTab = self.forwardTab;\r
19459 }\r
19460 if (self.mouseEvents[type] || self.clickEvents[type]) {\r
19461 pointerType = 'mouse';\r
19462 } else if (self.pointerEvents[type]) {\r
19463 pointerType = self.pointerTypes[event.pointerType];\r
19464 } else if (self.touchEvents[type]) {\r
19465 pointerType = 'touch';\r
19466 }\r
19467 if (pointerType) {\r
19468 me.pointerType = pointerType;\r
19469 }\r
19470 me.timeStamp = me.time = +(event.timeStamp || new Date());\r
19471 },\r
19472 \r
19473 chain: function(props) {\r
19474 var e = Ext.Object.chain(this);\r
19475 e.parentEvent = this;\r
19476
19477 return Ext.apply(e, props);\r
19478 },\r
19479 \r
19480 correctWheelDelta: function(delta) {\r
19481 var scale = this.WHEEL_SCALE,\r
19482 ret = Math.round(delta / scale);\r
19483 if (!ret && delta) {\r
19484 ret = (delta < 0) ? -1 : 1;\r
19485 }\r
19486
19487 return ret;\r
19488 },\r
19489 \r
19490 getCharCode: function() {\r
19491 return this.charCode || this.keyCode;\r
19492 },\r
19493 \r
19494 getKey: function() {\r
19495 return this.keyCode || this.charCode;\r
19496 },\r
19497 \r
19498 getKeyName: function() {\r
19499 return this.keyCodes[this.keyCode];\r
19500 },\r
19501 \r
19502 getPoint: function() {\r
19503 var xy = this.getXY();\r
19504 return new Ext.util.Point(xy[0], xy[1]);\r
19505 },\r
19506 \r
19507 getRelatedTarget: function(selector, maxDepth, returnEl) {\r
19508 var relatedTarget = this.relatedTarget,\r
19509 target = null;\r
19510 if (relatedTarget) {\r
19511 if (selector) {\r
19512 target = Ext.fly(relatedTarget).findParent(selector, maxDepth, returnEl);\r
19513 } else {\r
19514 target = returnEl ? Ext.get(relatedTarget) : relatedTarget;\r
19515 }\r
19516 }\r
19517 return target;\r
19518 },\r
19519 \r
19520 getTarget: function(selector, maxDepth, returnEl) {\r
19521 return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target);\r
19522 },\r
19523 \r
19524 getTime: function() {\r
19525 return this.time;\r
19526 },\r
19527 \r
19528 getWheelDelta: function() {\r
19529 var deltas = this.getWheelDeltas();\r
19530 return deltas.y;\r
19531 },\r
19532 \r
19533 getWheelDeltas: function() {\r
19534 var me = this,\r
19535 event = me.browserEvent,\r
19536 dx = 0,\r
19537 dy = 0;\r
19538
19539 if (Ext.isDefined(event.wheelDeltaX)) {\r
19540
19541 dx = event.wheelDeltaX;\r
19542 dy = event.wheelDeltaY;\r
19543 } else if (event.wheelDelta) {\r
19544
19545 dy = event.wheelDelta;\r
19546 } else if (event.detail) {\r
19547
19548 dy = -event.detail;\r
19549
19550
19551
19552 if (dy > 100) {\r
19553 dy = 3;\r
19554 } else if (dy < -100) {\r
19555 dy = -3;\r
19556 }\r
19557
19558
19559 if (Ext.isDefined(event.axis) && event.axis === event.HORIZONTAL_AXIS) {\r
19560 dx = dy;\r
19561 dy = 0;\r
19562 }\r
19563 }\r
19564 return {\r
19565 x: me.correctWheelDelta(dx),\r
19566 y: me.correctWheelDelta(dy)\r
19567 };\r
19568 },\r
19569 \r
19570 getX: function() {\r
19571 return this.getXY()[0];\r
19572 },\r
19573 \r
19574 getXY: function() {\r
19575 var me = this,\r
19576 xy = me.xy;\r
19577 if (!xy) {\r
19578 xy = me.xy = [\r
19579 me.pageX,\r
19580 me.pageY\r
19581 ];\r
19582
19583 var x = xy[0],\r
19584 browserEvent, doc, docEl, body;\r
19585
19586 if (!x && x !== 0) {\r
19587 browserEvent = me.browserEvent;\r
19588 doc = document;\r
19589 docEl = doc.documentElement;\r
19590 body = doc.body;\r
19591 xy[0] = browserEvent.clientX + (docEl && docEl.scrollLeft || body && body.scrollLeft || 0) - (docEl && docEl.clientLeft || body && body.clientLeft || 0);\r
19592 xy[1] = browserEvent.clientY + (docEl && docEl.scrollTop || body && body.scrollTop || 0) - (docEl && docEl.clientTop || body && body.clientTop || 0);\r
19593 }\r
19594 }\r
19595
19596 return xy;\r
19597 },\r
19598 \r
19599 getY: function() {\r
19600 return this.getXY()[1];\r
19601 },\r
19602 \r
19603 hasModifier: function() {\r
19604 var me = this;\r
19605 return !!(me.ctrlKey || me.altKey || me.shiftKey || me.metaKey);\r
19606 },\r
19607 \r
19608 isNavKeyPress: function(scrollableOnly) {\r
19609 var me = this,\r
19610 k = me.keyCode,\r
19611 isKeyPress = me.type === 'keypress';\r
19612
19613 return ((!isKeyPress || Ext.isGecko) && k >= 33 && k <= 40) ||
19614 (!scrollableOnly && (k === me.RETURN || k === me.TAB || k === me.ESC));\r
19615 },\r
19616 \r
19617 isSpecialKey: function() {\r
19618 var me = this,\r
19619 k = me.keyCode,\r
19620 isGecko = Ext.isGecko,\r
19621 isKeyPress = me.type === 'keypress';\r
19622
19623 return (isGecko && isKeyPress && me.charCode === 0) || (this.isNavKeyPress()) || (k === me.BACKSPACE) || (k === me.ENTER) || (k >= 16 && k <= 20) ||
19624 ((!isKeyPress || isGecko) && k >= 44 && k <= 46);\r
19625 },\r
19626
19627 makeUnpreventable: function() {\r
19628 this.browserEvent.preventDefault = Ext.emptyFn;\r
19629 },\r
19630 \r
19631 preventDefault: function() {\r
19632 var me = this,\r
19633 parentEvent = me.parentEvent;\r
19634 me.defaultPrevented = true;\r
19635
19636
19637 if (parentEvent) {\r
19638 parentEvent.defaultPrevented = true;\r
19639 }\r
19640 me.browserEvent.preventDefault();\r
19641 return me;\r
19642 },\r
19643 setCurrentTarget: function(target) {\r
19644 this.currentTarget = this.delegatedTarget = target;\r
19645 },\r
19646 \r
19647 stopEvent: function() {\r
19648 return this.preventDefault().stopPropagation();\r
19649 },\r
19650 \r
19651 stopPropagation: function() {\r
19652 var me = this,\r
19653 browserEvent = me.browserEvent,\r
19654 parentEvent = me.parentEvent;\r
19655
19656
19657 me.isStopped = true;\r
19658
19659
19660
19661
19662
19663
19664
19665
19666
19667
19668 if (parentEvent) {\r
19669 parentEvent.isStopped = true;\r
19670 }\r
19671
19672 if (!browserEvent.stopPropagation) {\r
19673
19674 browserEvent.cancelBubble = true;\r
19675 return me;\r
19676 }\r
19677
19678
19679
19680 browserEvent.stopPropagation();\r
19681 return me;\r
19682 },\r
19683 \r
19684 within: function(el, related, allowEl) {\r
19685 var t;\r
19686 if (el) {\r
19687 t = related ? this.getRelatedTarget() : this.getTarget();\r
19688 }\r
19689 return t ? Ext.fly(el).contains(t) || !!(allowEl && t === Ext.getDom(el)) : false;\r
19690 },\r
19691 deprecated: {\r
19692 '4.0': {\r
19693 methods: {\r
19694 \r
19695 getPageX: 'getX',\r
19696 \r
19697 getPageY: 'getY'\r
19698 }\r
19699 }\r
19700 }\r
19701}, function(Event) {\r
19702 var prototype = Event.prototype,\r
19703 constants = {\r
19704 \r
19705 BACKSPACE: 8,\r
19706 \r
19707 TAB: 9,\r
19708 \r
19709 NUM_CENTER: 12,\r
19710 \r
19711 ENTER: 13,\r
19712 \r
19713 RETURN: 13,\r
19714 \r
19715 SHIFT: 16,\r
19716 \r
19717 CTRL: 17,\r
19718 \r
19719 ALT: 18,\r
19720 \r
19721 PAUSE: 19,\r
19722 \r
19723 CAPS_LOCK: 20,\r
19724 \r
19725 ESC: 27,\r
19726 \r
19727 SPACE: 32,\r
19728 \r
19729 PAGE_UP: 33,\r
19730 \r
19731 PAGE_DOWN: 34,\r
19732 \r
19733 END: 35,\r
19734 \r
19735 HOME: 36,\r
19736 \r
19737 LEFT: 37,\r
19738 \r
19739 UP: 38,\r
19740 \r
19741 RIGHT: 39,\r
19742 \r
19743 DOWN: 40,\r
19744 \r
19745 PRINT_SCREEN: 44,\r
19746 \r
19747 INSERT: 45,\r
19748 \r
19749 DELETE: 46,\r
19750 \r
19751 ZERO: 48,\r
19752 \r
19753 ONE: 49,\r
19754 \r
19755 TWO: 50,\r
19756 \r
19757 THREE: 51,\r
19758 \r
19759 FOUR: 52,\r
19760 \r
19761 FIVE: 53,\r
19762 \r
19763 SIX: 54,\r
19764 \r
19765 SEVEN: 55,\r
19766 \r
19767 EIGHT: 56,\r
19768 \r
19769 NINE: 57,\r
19770 \r
19771 A: 65,\r
19772 \r
19773 B: 66,\r
19774 \r
19775 C: 67,\r
19776 \r
19777 D: 68,\r
19778 \r
19779 E: 69,\r
19780 \r
19781 F: 70,\r
19782 \r
19783 G: 71,\r
19784 \r
19785 H: 72,\r
19786 \r
19787 I: 73,\r
19788 \r
19789 J: 74,\r
19790 \r
19791 K: 75,\r
19792 \r
19793 L: 76,\r
19794 \r
19795 M: 77,\r
19796 \r
19797 N: 78,\r
19798 \r
19799 O: 79,\r
19800 \r
19801 P: 80,\r
19802 \r
19803 Q: 81,\r
19804 \r
19805 R: 82,\r
19806 \r
19807 S: 83,\r
19808 \r
19809 T: 84,\r
19810 \r
19811 U: 85,\r
19812 \r
19813 V: 86,\r
19814 \r
19815 W: 87,\r
19816 \r
19817 X: 88,\r
19818 \r
19819 Y: 89,\r
19820 \r
19821 Z: 90,\r
19822 \r
19823 CONTEXT_MENU: 93,\r
19824 \r
19825 NUM_ZERO: 96,\r
19826 \r
19827 NUM_ONE: 97,\r
19828 \r
19829 NUM_TWO: 98,\r
19830 \r
19831 NUM_THREE: 99,\r
19832 \r
19833 NUM_FOUR: 100,\r
19834 \r
19835 NUM_FIVE: 101,\r
19836 \r
19837 NUM_SIX: 102,\r
19838 \r
19839 NUM_SEVEN: 103,\r
19840 \r
19841 NUM_EIGHT: 104,\r
19842 \r
19843 NUM_NINE: 105,\r
19844 \r
19845 NUM_MULTIPLY: 106,\r
19846 \r
19847 NUM_PLUS: 107,\r
19848 \r
19849 NUM_MINUS: 109,\r
19850 \r
19851 NUM_PERIOD: 110,\r
19852 \r
19853 NUM_DIVISION: 111,\r
19854 \r
19855 F1: 112,\r
19856 \r
19857 F2: 113,\r
19858 \r
19859 F3: 114,\r
19860 \r
19861 F4: 115,\r
19862 \r
19863 F5: 116,\r
19864 \r
19865 F6: 117,\r
19866 \r
19867 F7: 118,\r
19868 \r
19869 F8: 119,\r
19870 \r
19871 F9: 120,\r
19872 \r
19873 F10: 121,\r
19874 \r
19875 F11: 122,\r
19876 \r
19877 F12: 123,\r
19878 \r
19879 WHEEL_SCALE: (function() {\r
19880 var scale;\r
19881 if (Ext.isGecko) {\r
19882
19883 scale = 3;\r
19884 } else if (Ext.isMac) {\r
19885
19886
19887
19888 if (Ext.isSafari && Ext.webKitVersion >= 532) {\r
19889
19890
19891
19892
19893
19894
19895 scale = 120;\r
19896 } else {\r
19897
19898
19899 scale = 12;\r
19900 }\r
19901
19902
19903
19904
19905 scale *= 3;\r
19906 } else {\r
19907
19908 scale = 120;\r
19909 }\r
19910 return scale;\r
19911 }())\r
19912 },\r
19913 keyCodes = {},\r
19914 keyName, keyCode;\r
19915 Ext.apply(Event, constants);\r
19916 Ext.apply(prototype, constants);\r
19917
19918 delete constants.WHEEL_SCALE;\r
19919
19920
19921
19922 delete constants.RETURN;\r
19923
19924 for (keyName in constants) {\r
19925 keyCode = constants[keyName];\r
19926 keyCodes[keyCode] = keyName;\r
19927 }\r
19928 prototype.keyCodes = keyCodes;\r
19929 \r
19930 prototype.getTrueXY = prototype.getXY;\r
19931});\r
19932\r
19933\r
19934Ext.define('Ext.event.publisher.Dom', {\r
19935 extend: Ext.event.publisher.Publisher,\r
19936 type: 'dom',\r
19937 \r
19938 handledDomEvents: [],\r
19939 reEnterCount: 0,\r
19940
19941
19942
19943 captureEvents: {\r
19944 animationstart: 1,\r
19945 animationend: 1,\r
19946 resize: 1,\r
19947 focus: 1,\r
19948 blur: 1,\r
19949 scroll: 1\r
19950 },\r
19951
19952
19953 directEvents: {\r
19954 mouseenter: 1,\r
19955 mouseleave: 1,\r
19956 pointerenter: 1,\r
19957 pointerleave: 1,\r
19958 MSPointerEnter: 1,\r
19959 MSPointerLeave: 1,\r
19960 load: 1,\r
19961 unload: 1,\r
19962 beforeunload: 1,\r
19963 error: 1,\r
19964 DOMContentLoaded: 1,\r
19965 DOMFrameContentLoaded: 1,\r
19966 hashchange: 1\r
19967 },\r
19968 \r
19969 blockedPointerEvents: {\r
19970 pointerover: 1,\r
19971 pointerout: 1,\r
19972 pointerenter: 1,\r
19973 pointerleave: 1,\r
19974 MSPointerOver: 1,\r
19975 MSPointerOut: 1,\r
19976 MSPointerEnter: 1,\r
19977 MSPointerLeave: 1\r
19978 },\r
19979 \r
19980 blockedCompatibilityMouseEvents: {\r
19981 mouseenter: 1,\r
19982 mouseleave: 1\r
19983 },\r
19984 constructor: function() {\r
19985 var me = this;\r
19986 me.bubbleSubscribers = {};\r
19987 me.captureSubscribers = {};\r
19988 me.directSubscribers = {};\r
19989 me.directCaptureSubscribers = {};\r
19990
19991
19992
19993 me.delegatedListeners = {};\r
19994 me.initHandlers();\r
19995 Ext.onInternalReady(me.onReady, me);\r
19996 me.callParent();\r
19997 },\r
19998 registerEvents: function() {\r
19999 var me = this,\r
20000 publishersByEvent = Ext.event.publisher.Publisher.publishersByEvent,\r
20001 domEvents = me.handledDomEvents,\r
20002 ln = domEvents.length,\r
20003 i = 0,\r
20004 eventName;\r
20005 for (; i < ln; i++) {\r
20006 eventName = domEvents[i];\r
20007 me.handles[eventName] = 1;\r
20008 publishersByEvent[eventName] = me;\r
20009 }\r
20010 this.callParent();\r
20011 },\r
20012 onReady: function() {\r
20013 var me = this,\r
20014 domEvents = me.handledDomEvents,\r
20015 ln, i;\r
20016 if (domEvents) {\r
20017
20018
20019
20020
20021
20022 for (i = 0 , ln = domEvents.length; i < ln; i++) {\r
20023 me.addDelegatedListener(domEvents[i]);\r
20024 }\r
20025 }\r
20026 Ext.getWin().on('unload', me.destroy, me);\r
20027 },\r
20028 initHandlers: function() {\r
20029 var me = this;\r
20030 me.onDelegatedEvent = Ext.bind(me.onDelegatedEvent, me);\r
20031 me.onDirectEvent = Ext.bind(me.onDirectEvent, me);\r
20032 me.onDirectCaptureEvent = Ext.bind(me.onDirectCaptureEvent, me);\r
20033 },\r
20034 addDelegatedListener: function(eventName) {\r
20035 this.delegatedListeners[eventName] = 1;\r
20036 this.target.addEventListener(eventName, this.onDelegatedEvent, !!this.captureEvents[eventName]);\r
20037 },\r
20038 removeDelegatedListener: function(eventName) {\r
20039 delete this.delegatedListeners[eventName];\r
20040 this.target.removeEventListener(eventName, this.onDelegatedEvent, !!this.captureEvents[eventName]);\r
20041 },\r
20042 addDirectListener: function(eventName, element, capture) {\r
20043 element.dom.addEventListener(eventName, capture ? this.onDirectCaptureEvent : this.onDirectEvent, capture);\r
20044 },\r
20045 removeDirectListener: function(eventName, element, capture) {\r
20046 element.dom.removeEventListener(eventName, capture ? this.onDirectCaptureEvent : this.onDirectEvent, capture);\r
20047 },\r
20048 subscribe: function(element, eventName, delegated, capture) {\r
20049 var me = this,\r
20050 subscribers, id;\r
20051 if (delegated && !me.directEvents[eventName]) {\r
20052
20053 subscribers = capture ? me.captureSubscribers : me.bubbleSubscribers;\r
20054 if (!me.handles[eventName] && !me.delegatedListeners[eventName]) {\r
20055
20056
20057 me.addDelegatedListener(eventName);\r
20058 }\r
20059 if (subscribers[eventName]) {\r
20060 ++subscribers[eventName];\r
20061 } else {\r
20062 subscribers[eventName] = 1;\r
20063 }\r
20064 } else {\r
20065 subscribers = capture ? me.directCaptureSubscribers : me.directSubscribers;\r
20066 id = element.id;\r
20067
20068
20069
20070
20071 subscribers = subscribers[eventName] || (subscribers[eventName] = {});\r
20072 if (subscribers[id]) {\r
20073 ++subscribers[id];\r
20074 } else {\r
20075 subscribers[id] = 1;\r
20076 me.addDirectListener(eventName, element, capture);\r
20077 }\r
20078 }\r
20079 },\r
20080 unsubscribe: function(element, eventName, delegated, capture) {\r
20081 var me = this,\r
20082 captureSubscribers, bubbleSubscribers, subscribers, id;\r
20083 if (delegated && !me.directEvents[eventName]) {\r
20084 captureSubscribers = me.captureSubscribers;\r
20085 bubbleSubscribers = me.bubbleSubscribers;\r
20086 subscribers = capture ? captureSubscribers : bubbleSubscribers;\r
20087 if (subscribers[eventName]) {\r
20088 --subscribers[eventName];\r
20089 }\r
20090 if (!me.handles[eventName] && !bubbleSubscribers[eventName] && !captureSubscribers[eventName]) {\r
20091
20092
20093 this.removeDelegatedListener(eventName);\r
20094 }\r
20095 } else {\r
20096 subscribers = capture ? me.directCaptureSubscribers : me.directSubscribers;\r
20097 id = element.id;\r
20098 subscribers = subscribers[eventName];\r
20099 if (subscribers[id]) {\r
20100 --subscribers[id];\r
20101 }\r
20102 if (!subscribers[id]) {\r
20103
20104
20105 delete subscribers[id];\r
20106 me.removeDirectListener(eventName, element, capture);\r
20107 }\r
20108 }\r
20109 },\r
20110 getPropagatingTargets: function(target) {\r
20111 var currentNode = target,\r
20112 targets = [],\r
20113 parentNode;\r
20114 while (currentNode) {\r
20115 targets.push(currentNode);\r
20116 parentNode = currentNode.parentNode;\r
20117 if (!parentNode) {\r
20118
20119
20120
20121
20122
20123 parentNode = currentNode.defaultView;\r
20124 }\r
20125 currentNode = parentNode;\r
20126 }\r
20127 return targets;\r
20128 },\r
20129 publish: function(eventName, target, e) {\r
20130 var me = this,\r
20131 targets, el, i, ln;\r
20132 if (Ext.isArray(target)) {\r
20133
20134 targets = target;\r
20135 } else if (me.captureEvents[eventName]) {\r
20136 el = Ext.cache[target.id];\r
20137 targets = el ? [\r
20138 el\r
20139 ] : [];\r
20140 } else {\r
20141 targets = me.getPropagatingTargets(target);\r
20142 }\r
20143 ln = targets.length;\r
20144
20145
20146
20147
20148
20149
20150
20151
20152 if (me.captureSubscribers[eventName]) {\r
20153 for (i = ln; i--; ) {\r
20154 el = Ext.cache[targets[i].id];\r
20155 if (el) {\r
20156 me.fire(el, eventName, e, false, true);\r
20157 if (e.isStopped) {\r
20158 break;\r
20159 }\r
20160 }\r
20161 }\r
20162 }\r
20163
20164
20165 if (!e.isStopped && me.bubbleSubscribers[eventName]) {\r
20166 for (i = 0; i < ln; i++) {\r
20167 el = Ext.cache[targets[i].id];\r
20168 if (el) {\r
20169 me.fire(el, eventName, e, false, false);\r
20170 if (e.isStopped) {\r
20171 break;\r
20172 }\r
20173 }\r
20174 }\r
20175 }\r
20176 },\r
20177 fire: function(element, eventName, e, direct, capture) {\r
20178 var event;\r
20179 if (element.hasListeners[eventName]) {\r
20180 event = element.events[eventName];\r
20181 if (event) {\r
20182 if (capture && direct) {\r
20183 event = event.directCaptures;\r
20184 } else if (capture) {\r
20185 event = event.captures;\r
20186 } else if (direct) {\r
20187 event = event.directs;\r
20188 }\r
20189
20190
20191 if (event) {\r
20192 e.setCurrentTarget(element.dom);\r
20193 event.fire(e, e.target);\r
20194 }\r
20195 }\r
20196 }\r
20197 },\r
20198 onDelegatedEvent: function(e) {\r
20199 if (Ext.elevateFunction) {\r
20200
20201
20202 Ext.elevateFunction(this.doDelegatedEvent, this, [\r
20203 e\r
20204 ]);\r
20205 } else {\r
20206 this.doDelegatedEvent(e);\r
20207 }\r
20208 },\r
20209 doDelegatedEvent: function(e, invokeAfter) {\r
20210 var me = this,\r
20211 timeStamp = e.timeStamp;\r
20212 e = new Ext.event.Event(e);\r
20213 if (me.isEventBlocked(e)) {\r
20214 return false;\r
20215 }\r
20216 me.beforeEvent(e);\r
20217 Ext.frameStartTime = timeStamp;\r
20218 me.reEnterCount++;\r
20219 me.publish(e.type, e.target, e);\r
20220 me.reEnterCount--;\r
20221 if (invokeAfter !== false) {\r
20222 me.afterEvent(e);\r
20223 }\r
20224 return e;\r
20225 },\r
20226 \r
20227 onDirectEvent: function(e) {\r
20228 if (Ext.elevateFunction) {\r
20229
20230
20231 Ext.elevateFunction(this.doDirectEvent, this, [\r
20232 e,\r
20233 false\r
20234 ]);\r
20235 } else {\r
20236 this.doDirectEvent(e, false);\r
20237 }\r
20238 },\r
20239
20240
20241 onDirectCaptureEvent: function(e) {\r
20242 if (Ext.elevateFunction) {\r
20243
20244
20245 Ext.elevateFunction(this.doDirectEvent, this, [\r
20246 e,\r
20247 true\r
20248 ]);\r
20249 } else {\r
20250 this.doDirectEvent(e, true);\r
20251 }\r
20252 },\r
20253 doDirectEvent: function(e, capture) {\r
20254 var me = this,\r
20255 currentTarget = e.currentTarget,\r
20256 timeStamp = e.timeStamp,\r
20257 el;\r
20258 e = new Ext.event.Event(e);\r
20259 if (me.isEventBlocked(e)) {\r
20260 return;\r
20261 }\r
20262 me.beforeEvent(e);\r
20263 Ext.frameStartTime = timeStamp;\r
20264 el = Ext.cache[currentTarget.id];\r
20265
20266
20267
20268
20269 if (el) {\r
20270
20271
20272 me.reEnterCount++;\r
20273 me.fire(el, e.type, e, true, capture);\r
20274 me.reEnterCount--;\r
20275 }\r
20276 me.afterEvent(e);\r
20277 },\r
20278 beforeEvent: function(e) {\r
20279 var browserEvent = e.browserEvent,\r
20280
20281
20282 self = Ext.event.publisher.Dom,\r
20283 touches, touch;\r
20284 if (browserEvent.type === 'touchstart') {\r
20285 touches = browserEvent.touches;\r
20286 if (touches.length === 1) {\r
20287
20288
20289 touch = touches[0];\r
20290 self.lastTouchStartX = touch.pageX;\r
20291 self.lastTouchStartY = touch.pageY;\r
20292 }\r
20293 }\r
20294 },\r
20295 afterEvent: function(e) {\r
20296 var browserEvent = e.browserEvent,\r
20297 type = browserEvent.type,\r
20298
20299
20300 self = Ext.event.publisher.Dom,\r
20301 GlobalEvents = Ext.GlobalEvents;\r
20302
20303
20304
20305
20306
20307
20308 if (e.self.pointerEvents[type] && e.pointerType !== 'mouse') {\r
20309
20310
20311
20312
20313
20314 self.lastScreenPointerEventTime = Ext.now();\r
20315 }\r
20316 if (type === 'touchend') {\r
20317
20318
20319
20320 self.lastTouchEndTime = Ext.now();\r
20321 }\r
20322 if (!this.reEnterCount && GlobalEvents.hasListeners.idle && !GlobalEvents.idleEventMask[type]) {\r
20323 GlobalEvents.fireEvent('idle');\r
20324 }\r
20325 },\r
20326 \r
20327 isEventBlocked: function(e) {\r
20328 var me = this,\r
20329 type = e.type,\r
20330
20331
20332 self = Ext.event.publisher.Dom,\r
20333 now = Ext.now();\r
20334
20335
20336
20337
20338
20339 if (Ext.isGecko && e.type === 'click' && e.button === 2) {\r
20340 return true;\r
20341 }\r
20342
20343
20344 return (me.blockedPointerEvents[type] && e.pointerType !== 'mouse') ||
20345
20346
20347
20348
20349 (me.blockedCompatibilityMouseEvents[type] && (now - self.lastScreenPointerEventTime < 1000)) || (Ext.supports.TouchEvents && e.self.mouseEvents[e.type] &&
20350
20351
20352
20353
20354
20355
20356
20357
20358
20359
20360
20361
20362
20363
20364
20365
20366
20367
20368
20369
20370
20371 Math.abs(e.pageX - self.lastTouchStartX) < 15 && Math.abs(e.pageY - self.lastTouchStartY) < 15 &&
20372
20373
20374
20375
20376
20377 (Ext.now() - self.lastTouchEndTime) < 1000);\r
20378 },\r
20379 destroy: function() {\r
20380 var eventName;\r
20381 for (eventName in this.delegatedListeners) {\r
20382 this.removeDelegatedListener(eventName);\r
20383 }\r
20384 this.callParent();\r
20385 },\r
20386 \r
20387 reset: function() {\r
20388
20389
20390 var self = Ext.event.publisher.Dom;\r
20391
20392
20393
20394 self.lastScreenPointerEventTime = self.lastTouchEndTime = self.lastTouchStartX = self.lastTouchStartY = undefined;\r
20395 }\r
20396}, function(Dom) {\r
20397 var doc = document,\r
20398 defaultView = doc.defaultView,\r
20399 prototype = Dom.prototype;\r
20400 if ((Ext.os.is.iOS && Ext.os.version.getMajor() < 5) || Ext.browser.is.AndroidStock || !(defaultView && defaultView.addEventListener)) {\r
20401
20402
20403
20404
20405
20406
20407
20408 prototype.target = doc;\r
20409 } else {\r
20410 \r
20411 prototype.target = defaultView;\r
20412 }\r
20413 Dom.instance = new Dom();\r
20414});\r
20415\r
20416\r
20417Ext.define('Ext.event.publisher.Gesture', {\r
20418 extend: Ext.event.publisher.Dom,\r
20419 type: 'gesture',\r
20420 config: {\r
20421 \r
20422 async: true\r
20423 },\r
20424 isCancelEvent: {\r
20425 touchcancel: 1,\r
20426 pointercancel: 1,\r
20427 MSPointerCancel: 1\r
20428 },\r
20429 handledEvents: [],\r
20430 handledDomEvents: [],\r
20431 constructor: function(config) {\r
20432 var me = this,\r
20433 handledDomEvents = me.handledDomEvents,\r
20434 supports = Ext.supports,\r
20435 supportsTouchEvents = supports.TouchEvents,\r
20436 Fn = Ext.Function,\r
20437 onTouchStart = me.onTouchStart,\r
20438 onTouchMove = me.onTouchMove,\r
20439 onTouchEnd = me.onTouchEnd,\r
20440
20441
20442
20443
20444
20445
20446
20447
20448
20449
20450
20451
20452
20453
20454
20455
20456
20457
20458
20459
20460
20461
20462 asyncTouchStart = Fn.createAnimationFrame(me.onTouchStart, me, null, 1),\r
20463 asyncTouchMove = Fn.createAnimationFrame(me.onTouchMove, me),\r
20464 asyncTouchEnd = Fn.createAnimationFrame(me.onTouchEnd, me, null, 1);\r
20465
20466
20467 me._handlers = {\r
20468 touchstart: onTouchStart,\r
20469 touchmove: onTouchMove,\r
20470 touchend: onTouchEnd,\r
20471 touchcancel: onTouchEnd,\r
20472 pointerdown: onTouchStart,\r
20473 pointermove: onTouchMove,\r
20474 pointerup: onTouchEnd,\r
20475 pointercancel: onTouchEnd,\r
20476 MSPointerDown: onTouchStart,\r
20477 MSPointerMove: onTouchMove,\r
20478 MSPointerUp: onTouchEnd,\r
20479 MSPointerCancel: onTouchEnd,\r
20480 mousedown: onTouchStart,\r
20481 mousemove: onTouchMove,\r
20482 mouseup: onTouchEnd\r
20483 };\r
20484 me._asyncHandlers = {\r
20485 touchstart: asyncTouchStart,\r
20486 touchmove: asyncTouchMove,\r
20487 touchend: asyncTouchEnd,\r
20488 touchcancel: asyncTouchEnd,\r
20489 pointerdown: asyncTouchStart,\r
20490 pointermove: asyncTouchMove,\r
20491 pointerup: asyncTouchEnd,\r
20492 pointercancel: asyncTouchEnd,\r
20493 MSPointerDown: asyncTouchStart,\r
20494 MSPointerMove: asyncTouchMove,\r
20495 MSPointerUp: asyncTouchEnd,\r
20496 MSPointerCancel: asyncTouchEnd,\r
20497 mousedown: asyncTouchStart,\r
20498 mousemove: asyncTouchMove,\r
20499 mouseup: asyncTouchEnd\r
20500 };\r
20501
20502 me.activeTouchesMap = {};\r
20503 me.activeTouches = [];\r
20504 me.changedTouches = [];\r
20505 me.recognizers = [];\r
20506 if (supportsTouchEvents) {\r
20507
20508 me.onTargetTouchMove = me.onTargetTouchMove.bind(me);\r
20509 me.onTargetTouchEnd = me.onTargetTouchEnd.bind(me);\r
20510 }\r
20511 if (supports.PointerEvents) {\r
20512 handledDomEvents.push('pointerdown', 'pointermove', 'pointerup', 'pointercancel');\r
20513 me.mousePointerType = 'mouse';\r
20514 } else if (supports.MSPointerEvents) {\r
20515
20516 handledDomEvents.push('MSPointerDown', 'MSPointerMove', 'MSPointerUp', 'MSPointerCancel');\r
20517 me.mousePointerType = 4;\r
20518 } else if (supportsTouchEvents) {\r
20519 handledDomEvents.push('touchstart', 'touchmove', 'touchend', 'touchcancel');\r
20520 }\r
20521 if (!handledDomEvents.length || (supportsTouchEvents && Ext.isWebKit && Ext.os.is.Desktop)) {\r
20522
20523
20524
20525
20526 handledDomEvents.push('mousedown', 'mousemove', 'mouseup');\r
20527 }\r
20528 me.initConfig(config);\r
20529 return me.callParent();\r
20530 },\r
20531 onReady: function() {\r
20532 this.callParent();\r
20533 Ext.Array.sort(this.recognizers, function(recognizerA, recognizerB) {\r
20534 var a = recognizerA.priority,\r
20535 b = recognizerB.priority;\r
20536 return (a > b) ? 1 : (a < b) ? -1 : 0;\r
20537 });\r
20538 },\r
20539 registerRecognizer: function(recognizer) {\r
20540 var me = this,\r
20541 handledEvents = recognizer.handledEvents,\r
20542 ln = handledEvents.length,\r
20543 i;\r
20544
20545
20546 recognizer.setOnRecognized(me.onRecognized);\r
20547 recognizer.setCallbackScope(me);\r
20548
20549
20550 for (i = 0; i < ln; i++) {\r
20551 me.handledEvents.push(handledEvents[i]);\r
20552 }\r
20553 me.registerEvents(handledEvents);\r
20554 me.recognizers.push(recognizer);\r
20555 },\r
20556 onRecognized: function(eventName, e, info) {\r
20557 var me = this,\r
20558 changedTouches = e.changedTouches,\r
20559 ln = changedTouches.length,\r
20560 targetGroups, targets, i, touch;\r
20561 info = info || {};\r
20562
20563
20564
20565
20566
20567
20568 info.type = eventName;\r
20569
20570
20571
20572
20573
20574
20575
20576
20577
20578
20579 info.target = changedTouches[0].target;\r
20580
20581
20582 info.isStopped = false;\r
20583 e = e.chain(info);\r
20584 if (ln > 1) {\r
20585 targetGroups = [];\r
20586 for (i = 0; i < ln; i++) {\r
20587 touch = changedTouches[i];\r
20588 targetGroups.push(touch.targets);\r
20589 }\r
20590 targets = me.getCommonTargets(targetGroups);\r
20591 } else {\r
20592 targets = changedTouches[0].targets;\r
20593 }\r
20594 me.publish(eventName, targets, e);\r
20595 },\r
20596 getCommonTargets: function(targetGroups) {\r
20597 var firstTargetGroup = targetGroups[0],\r
20598 ln = targetGroups.length;\r
20599 if (ln === 1) {\r
20600 return firstTargetGroup;\r
20601 }\r
20602 var commonTargets = [],\r
20603 i = 1,\r
20604 target, targets, j;\r
20605 while (true) {\r
20606 target = firstTargetGroup[firstTargetGroup.length - i];\r
20607 if (!target) {\r
20608 return commonTargets;\r
20609 }\r
20610 for (j = 1; j < ln; j++) {\r
20611 targets = targetGroups[j];\r
20612 if (targets[targets.length - i] !== target) {\r
20613 return commonTargets;\r
20614 }\r
20615 }\r
20616 commonTargets.unshift(target);\r
20617 i++;\r
20618 }\r
20619 return commonTargets;\r
20620 },\r
20621 invokeRecognizers: function(methodName, e) {\r
20622 var recognizers = this.recognizers,\r
20623 ln = recognizers.length,\r
20624 i, recognizer;\r
20625 if (methodName === 'onStart') {\r
20626 for (i = 0; i < ln; i++) {\r
20627 recognizers[i].isActive = true;\r
20628 }\r
20629 }\r
20630 for (i = 0; i < ln; i++) {\r
20631 recognizer = recognizers[i];\r
20632 if (recognizer.isActive && recognizer[methodName].call(recognizer, e) === false) {\r
20633 recognizer.isActive = false;\r
20634 }\r
20635 }\r
20636 },\r
20637 updateTouches: function(e, isEnd) {\r
20638 var me = this,\r
20639 browserEvent = e.browserEvent,\r
20640
20641
20642
20643
20644 touchSources = browserEvent.changedTouches || [\r
20645 browserEvent\r
20646 ],\r
20647 activeTouches = me.activeTouches,\r
20648 activeTouchesMap = me.activeTouchesMap,\r
20649 changedTouches = [],\r
20650 touchSource, identifier, touch, target, i, ln, x, y;\r
20651 for (i = 0 , ln = touchSources.length; i < ln; i++) {\r
20652 touchSource = touchSources[i];\r
20653 if ('identifier' in touchSource) {\r
20654
20655
20656 identifier = touchSource.identifier;\r
20657 } else if ('pointerId' in touchSource) {\r
20658
20659 identifier = touchSource.pointerId;\r
20660 } else {\r
20661
20662
20663 identifier = 1;\r
20664 }\r
20665 touch = activeTouchesMap[identifier];\r
20666 if (!touch) {\r
20667 target = Ext.event.Event.resolveTextNode(touchSource.target);\r
20668 touch = activeTouchesMap[identifier] = {\r
20669 identifier: identifier,\r
20670 target: target,\r
20671
20672
20673
20674
20675
20676
20677
20678
20679 targets: me.getPropagatingTargets(target)\r
20680 };\r
20681 activeTouches.push(touch);\r
20682 }\r
20683 if (isEnd) {\r
20684 delete activeTouchesMap[identifier];\r
20685 Ext.Array.remove(activeTouches, touch);\r
20686 }\r
20687 x = touchSource.pageX;\r
20688 y = touchSource.pageY;\r
20689 touch.pageX = x;\r
20690 touch.pageY = y;\r
20691
20692 touch.point = new Ext.util.Point(x, y);\r
20693 changedTouches.push(touch);\r
20694 }\r
20695
20696
20697
20698 e.touches = Ext.Array.clone(activeTouches);\r
20699
20700 e.changedTouches = changedTouches;\r
20701 },\r
20702 doDelegatedEvent: function(e) {\r
20703 var me = this;\r
20704
20705
20706 e = me.callParent([\r
20707 e,\r
20708 false\r
20709 ]);\r
20710
20711
20712
20713
20714
20715 if (e) {\r
20716 if (!e.button || e.button < 1) {\r
20717
20718
20719
20720 me.handlers[e.type].call(me, e);\r
20721 }\r
20722
20723
20724
20725 me.afterEvent(e);\r
20726 }\r
20727 },\r
20728 onTouchStart: function(e) {\r
20729 var me = this,\r
20730 target = e.target,\r
20731 touches = e.browserEvent.touches;\r
20732 if (e.browserEvent.type === 'touchstart') {\r
20733
20734
20735
20736
20737
20738
20739 target.addEventListener('touchmove', me.onTargetTouchMove);\r
20740 target.addEventListener('touchend', me.onTargetTouchEnd);\r
20741 target.addEventListener('touchcancel', me.onTargetTouchEnd);\r
20742 }\r
20743
20744
20745
20746 if (touches && touches.length <= me.activeTouches.length) {\r
20747 me.removeGhostTouches(touches);\r
20748 }\r
20749 me.updateTouches(e);\r
20750 if (!me.isStarted) {\r
20751
20752
20753 me.isStarted = true;\r
20754 me.invokeRecognizers('onStart', e);\r
20755
20756
20757
20758 if (Ext.enableGarbageCollector) {\r
20759 Ext.dom.GarbageCollector.pause();\r
20760 }\r
20761 }\r
20762 me.invokeRecognizers('onTouchStart', e);\r
20763 },\r
20764 onTouchMove: function(e) {\r
20765 var me = this,\r
20766 mousePointerType = me.mousePointerType;\r
20767 if (me.isStarted) {\r
20768
20769
20770
20771 if (mousePointerType && e.browserEvent.pointerType === mousePointerType && e.buttons === 0) {\r
20772 e.type = Ext.dom.Element.prototype.eventMap.touchend;\r
20773 e.button = 0;\r
20774 me.onTouchEnd(e);\r
20775 return;\r
20776 }\r
20777 me.updateTouches(e);\r
20778 if (e.changedTouches.length > 0) {\r
20779 me.invokeRecognizers('onTouchMove', e);\r
20780 }\r
20781 }\r
20782 },\r
20783
20784
20785
20786 onTouchEnd: function(e) {\r
20787 var me = this;\r
20788 if (!me.isStarted) {\r
20789 return;\r
20790 }\r
20791 me.updateTouches(e, true);\r
20792 me.invokeRecognizers(me.isCancelEvent[e.type] ? 'onTouchCancel' : 'onTouchEnd', e);\r
20793 if (!me.activeTouches.length) {\r
20794
20795 me.isStarted = false;\r
20796 me.invokeRecognizers('onEnd', e);\r
20797
20798
20799 if (Ext.enableGarbageCollector) {\r
20800 Ext.dom.GarbageCollector.resume();\r
20801 }\r
20802 }\r
20803 },\r
20804 onTargetTouchMove: function(e) {\r
20805 if (Ext.elevateFunction) {\r
20806
20807
20808 Ext.elevateFunction(this.doTargetTouchMove, this, [\r
20809 e\r
20810 ]);\r
20811 } else {\r
20812 this.doTargetTouchMove(e);\r
20813 }\r
20814 },\r
20815 doTargetTouchMove: function(e) {\r
20816
20817
20818 if (!Ext.getBody().contains(e.target)) {\r
20819 this.onTouchMove(new Ext.event.Event(e));\r
20820 }\r
20821 },\r
20822 onTargetTouchEnd: function(e) {\r
20823 if (Ext.elevateFunction) {\r
20824
20825
20826 Ext.elevateFunction(this.doTargetTouchEnd, this, [\r
20827 e\r
20828 ]);\r
20829 } else {\r
20830 this.doTargetTouchEnd(e);\r
20831 }\r
20832 },\r
20833 doTargetTouchEnd: function(e) {\r
20834 var me = this,\r
20835 target = e.target;\r
20836 target.removeEventListener('touchmove', me.onTargetTouchMove);\r
20837 target.removeEventListener('touchend', me.onTargetTouchEnd);\r
20838 target.removeEventListener('touchcancel', me.onTargetTouchEnd);\r
20839
20840
20841
20842
20843
20844
20845
20846
20847
20848
20849
20850
20851 if (!Ext.getBody().contains(target)) {\r
20852 me.onTouchEnd(new Ext.event.Event(e));\r
20853 }\r
20854 },\r
20855 updateAsync: function(async) {\r
20856 this.handlers = async ? this._asyncHandlers : this._handlers;\r
20857 },\r
20858 \r
20859 reset: function() {\r
20860 var me = this,\r
20861 recognizers = me.recognizers,\r
20862 ln = recognizers.length,\r
20863 i, recognizer;\r
20864 me.activeTouchesMap = {};\r
20865 me.activeTouches = [];\r
20866 me.changedTouches = [];\r
20867 me.isStarted = false;\r
20868 for (i = 0; i < ln; i++) {\r
20869 recognizer = recognizers[i];\r
20870 recognizer.reset();\r
20871 recognizer.isActive = false;\r
20872 }\r
20873 this.callParent();\r
20874 },\r
20875 privates: {\r
20876 removeGhostTouches: function(touches) {\r
20877 var ids = {},\r
20878 len = touches.length,\r
20879 activeTouches = this.activeTouches,\r
20880 map = this.activeTouchesMap,\r
20881 i, id, touch;\r
20882
20883 for (i = 0; i < len; ++i) {\r
20884 ids[touches[i].identifier] = true;\r
20885 }\r
20886 i = activeTouches.length;\r
20887 while (i--) {\r
20888 touch = activeTouches[i];\r
20889 id = touch.identifier;\r
20890 if (!touches[id]) {\r
20891 Ext.Array.remove(activeTouches, touch);\r
20892 delete map[id];\r
20893 }\r
20894 }\r
20895 }\r
20896 }\r
20897}, function(Gesture) {\r
20898 Gesture.instance = new Gesture();\r
20899});\r
20900\r
20901\r
20902Ext.define('Ext.mixin.Templatable', {\r
20903 extend: Ext.Mixin,\r
20904 mixinConfig: {\r
20905 id: 'templatable'\r
20906 },\r
20907 referenceAttributeName: 'reference',\r
20908 referenceSelector: '[reference]',\r
20909 getElementConfig: function() {\r
20910 return {\r
20911 reference: 'element'\r
20912 };\r
20913 },\r
20914 getElementTemplate: function() {\r
20915 var elementTemplate = document.createDocumentFragment();\r
20916 elementTemplate.appendChild(Ext.Element.create(this.getElementConfig(), true));\r
20917 return elementTemplate;\r
20918 },\r
20919 initElement: function() {\r
20920 var prototype = this.self.prototype;\r
20921 prototype.elementTemplate = this.getElementTemplate();\r
20922 prototype.initElement = prototype.doInitElement;\r
20923 this.initElement.apply(this, arguments);\r
20924 },\r
20925 linkElement: function(reference, node) {\r
20926 this.link(reference, node);\r
20927 },\r
20928 doInitElement: function() {\r
20929 var referenceAttributeName = this.referenceAttributeName,\r
20930 renderElement, referenceNodes, i, ln, referenceNode, reference;\r
20931 renderElement = this.elementTemplate.cloneNode(true);\r
20932 referenceNodes = renderElement.querySelectorAll(this.referenceSelector);\r
20933 for (i = 0 , ln = referenceNodes.length; i < ln; i++) {\r
20934 referenceNode = referenceNodes[i];\r
20935 reference = referenceNode.getAttribute(referenceAttributeName);\r
20936 referenceNode.removeAttribute(referenceAttributeName);\r
20937 this.linkElement(reference, referenceNode);\r
20938 }\r
20939 }\r
20940});\r
20941\r
20942\r
20943Ext.define('Ext.TaskQueue', {\r
20944 singleton: true,\r
20945 pending: false,\r
20946 mode: true,\r
20947 constructor: function() {\r
20948 this.readQueue = [];\r
20949 this.writeQueue = [];\r
20950 this.run = Ext.Function.bind(this.run, this);\r
20951
20952
20953
20954
20955
20956 if (Ext.os.is.iOS) {\r
20957 Ext.interval(this.watch, 500, this);\r
20958 }\r
20959 },\r
20960 requestRead: function(fn, scope, args) {\r
20961 this.request(true);\r
20962 this.readQueue.push(arguments);\r
20963 },\r
20964 requestWrite: function(fn, scope, args) {\r
20965 this.request(false);\r
20966 this.writeQueue.push(arguments);\r
20967 },\r
20968 request: function(mode) {\r
20969 if (!this.pending) {\r
20970 this.pendingTime = Date.now();\r
20971 this.pending = true;\r
20972 this.mode = mode;\r
20973 if (mode) {\r
20974 Ext.defer(this.run, 1, this);\r
20975 } else {\r
20976 Ext.Function.requestAnimationFrame(this.run);\r
20977 }\r
20978 }\r
20979 },\r
20980 watch: function() {\r
20981 if (this.pending && Date.now() - this.pendingTime >= 500) {\r
20982 this.run();\r
20983 }\r
20984 },\r
20985 run: function() {\r
20986 this.pending = false;\r
20987 var readQueue = this.readQueue,\r
20988 writeQueue = this.writeQueue,\r
20989 request = null,\r
20990 queue;\r
20991 if (this.mode) {\r
20992 queue = readQueue;\r
20993 if (writeQueue.length > 0) {\r
20994 request = false;\r
20995 }\r
20996 } else {\r
20997 queue = writeQueue;\r
20998 if (readQueue.length > 0) {\r
20999 request = true;\r
21000 }\r
21001 }\r
21002 var tasks = queue.slice(),\r
21003 i, ln, task, fn, scope;\r
21004 queue.length = 0;\r
21005 for (i = 0 , ln = tasks.length; i < ln; i++) {\r
21006 task = tasks[i];\r
21007 fn = task[0];\r
21008 scope = task[1];\r
21009 if (typeof fn === 'string') {\r
21010 fn = scope[fn];\r
21011 }\r
21012 if (task.length > 2) {\r
21013 fn.apply(scope, task[2]);\r
21014 } else {\r
21015 fn.call(scope);\r
21016 }\r
21017 }\r
21018 tasks.length = 0;\r
21019 if (request !== null) {\r
21020 this.request(request);\r
21021 }\r
21022 },\r
21023
21024 privates: {\r
21025 flush: function() {\r
21026 while (this.readQueue.length || this.writeQueue.length) {\r
21027 this.run();\r
21028 }\r
21029 }\r
21030 }\r
21031});\r
21032
21033\r
21034\r
21035Ext.define('Ext.util.sizemonitor.Abstract', {\r
21036 mixins: [\r
21037 Ext.mixin.Templatable\r
21038 ],\r
21039 config: {\r
21040 element: null,\r
21041 callback: Ext.emptyFn,\r
21042 scope: null,\r
21043 args: []\r
21044 },\r
21045 width: 0,\r
21046 height: 0,\r
21047 contentWidth: 0,\r
21048 contentHeight: 0,\r
21049 constructor: function(config) {\r
21050 this.refresh = Ext.Function.bind(this.refresh, this);\r
21051 this.info = {\r
21052 width: 0,\r
21053 height: 0,\r
21054 contentWidth: 0,\r
21055 contentHeight: 0,\r
21056 flag: 0\r
21057 };\r
21058 this.initElement();\r
21059 this.initConfig(config);\r
21060 this.bindListeners(true);\r
21061 },\r
21062 bindListeners: Ext.emptyFn,\r
21063 applyElement: function(element) {\r
21064 if (element) {\r
21065 return Ext.get(element);\r
21066 }\r
21067 },\r
21068 updateElement: function(element) {\r
21069 element.append(this.detectorsContainer);\r
21070 element.addCls(Ext.baseCSSPrefix + 'size-monitored');\r
21071 },\r
21072 applyArgs: function(args) {\r
21073 return args.concat([\r
21074 this.info\r
21075 ]);\r
21076 },\r
21077 refreshMonitors: Ext.emptyFn,\r
21078 forceRefresh: function() {\r
21079 Ext.TaskQueue.requestRead('refresh', this);\r
21080 },\r
21081 getContentBounds: function() {\r
21082 return this.detectorsContainer.getBoundingClientRect();\r
21083 },\r
21084 getContentWidth: function() {\r
21085 return this.detectorsContainer.offsetWidth;\r
21086 },\r
21087 getContentHeight: function() {\r
21088 return this.detectorsContainer.offsetHeight;\r
21089 },\r
21090 refreshSize: function() {\r
21091 var element = this.getElement();\r
21092 if (!element || element.destroyed) {\r
21093 return false;\r
21094 }\r
21095 var width = element.getWidth(),\r
21096 height = element.getHeight(),\r
21097 contentWidth = this.getContentWidth(),\r
21098 contentHeight = this.getContentHeight(),\r
21099 currentContentWidth = this.contentWidth,\r
21100 currentContentHeight = this.contentHeight,\r
21101 info = this.info,\r
21102 resized = false,\r
21103 flag;\r
21104 this.width = width;\r
21105 this.height = height;\r
21106 this.contentWidth = contentWidth;\r
21107 this.contentHeight = contentHeight;\r
21108 flag = ((currentContentWidth !== contentWidth ? 1 : 0) + (currentContentHeight !== contentHeight ? 2 : 0));\r
21109 if (flag > 0) {\r
21110 info.width = width;\r
21111 info.height = height;\r
21112 info.contentWidth = contentWidth;\r
21113 info.contentHeight = contentHeight;\r
21114 info.flag = flag;\r
21115 resized = true;\r
21116 this.getCallback().apply(this.getScope(), this.getArgs());\r
21117 }\r
21118 return resized;\r
21119 },\r
21120 refresh: function(force) {\r
21121 if (this.refreshSize() || force) {\r
21122 Ext.TaskQueue.requestWrite('refreshMonitors', this);\r
21123 }\r
21124 },\r
21125 destroy: function() {\r
21126 var me = this,\r
21127 element = me.getElement();\r
21128 me.bindListeners(false);\r
21129 if (element && !element.destroyed) {\r
21130 element.removeCls(Ext.baseCSSPrefix + 'size-monitored');\r
21131 }\r
21132 delete me._element;\r
21133 me.callParent();\r
21134 }\r
21135});\r
21136\r
21137\r
21138Ext.define('Ext.util.sizemonitor.Scroll', {\r
21139 extend: Ext.util.sizemonitor.Abstract,\r
21140 getElementConfig: function() {\r
21141 return {\r
21142 reference: 'detectorsContainer',\r
21143 classList: [\r
21144 Ext.baseCSSPrefix + 'size-monitors',\r
21145 'scroll'\r
21146 ],\r
21147 children: [\r
21148 {\r
21149 reference: 'expandMonitor',\r
21150 className: 'expand'\r
21151 },\r
21152 {\r
21153 reference: 'shrinkMonitor',\r
21154 className: 'shrink'\r
21155 }\r
21156 ]\r
21157 };\r
21158 },\r
21159 constructor: function(config) {\r
21160 this.onScroll = Ext.Function.bind(this.onScroll, this);\r
21161 this.callParent(arguments);\r
21162 },\r
21163 bindListeners: function(bind) {\r
21164 var method = bind ? 'addEventListener' : 'removeEventListener';\r
21165 this.expandMonitor[method]('scroll', this.onScroll, true);\r
21166 this.shrinkMonitor[method]('scroll', this.onScroll, true);\r
21167 },\r
21168 forceRefresh: function() {\r
21169 Ext.TaskQueue.requestRead('refresh', this, [\r
21170 true\r
21171 ]);\r
21172 },\r
21173 onScroll: function() {\r
21174 Ext.TaskQueue.requestRead('refresh', this);\r
21175 },\r
21176 refreshMonitors: function() {\r
21177 var expandMonitor = this.expandMonitor,\r
21178 shrinkMonitor = this.shrinkMonitor,\r
21179 end = 1000000;\r
21180 if (expandMonitor && !expandMonitor.destroyed) {\r
21181 expandMonitor.scrollLeft = end;\r
21182 expandMonitor.scrollTop = end;\r
21183 }\r
21184 if (shrinkMonitor && !shrinkMonitor.destroyed) {\r
21185 shrinkMonitor.scrollLeft = end;\r
21186 shrinkMonitor.scrollTop = end;\r
21187 }\r
21188 }\r
21189});\r
21190\r
21191\r
21192Ext.define('Ext.util.sizemonitor.OverflowChange', {\r
21193 extend: Ext.util.sizemonitor.Abstract,\r
21194 constructor: function(config) {\r
21195 this.onExpand = Ext.Function.bind(this.onExpand, this);\r
21196 this.onShrink = Ext.Function.bind(this.onShrink, this);\r
21197 this.callParent(arguments);\r
21198 },\r
21199 getElementConfig: function() {\r
21200 return {\r
21201 reference: 'detectorsContainer',\r
21202 classList: [\r
21203 Ext.baseCSSPrefix + 'size-monitors',\r
21204 'overflowchanged'\r
21205 ],\r
21206 children: [\r
21207 {\r
21208 reference: 'expandMonitor',\r
21209 className: 'expand',\r
21210 children: [\r
21211 {\r
21212 reference: 'expandHelper'\r
21213 }\r
21214 ]\r
21215 },\r
21216 {\r
21217 reference: 'shrinkMonitor',\r
21218 className: 'shrink',\r
21219 children: [\r
21220 {\r
21221 reference: 'shrinkHelper'\r
21222 }\r
21223 ]\r
21224 }\r
21225 ]\r
21226 };\r
21227 },\r
21228 bindListeners: function(bind) {\r
21229 var method = bind ? 'addEventListener' : 'removeEventListener';\r
21230 this.expandMonitor[method](Ext.browser.is.Firefox ? 'underflow' : 'overflowchanged', this.onExpand, true);\r
21231 this.shrinkMonitor[method](Ext.browser.is.Firefox ? 'overflow' : 'overflowchanged', this.onShrink, true);\r
21232 },\r
21233 onExpand: function(e) {\r
21234 if (Ext.browser.is.Webkit && e.horizontalOverflow && e.verticalOverflow) {\r
21235 return;\r
21236 }\r
21237 Ext.TaskQueue.requestRead('refresh', this);\r
21238 },\r
21239 onShrink: function(e) {\r
21240 if (Ext.browser.is.Webkit && !e.horizontalOverflow && !e.verticalOverflow) {\r
21241 return;\r
21242 }\r
21243 Ext.TaskQueue.requestRead('refresh', this);\r
21244 },\r
21245 refreshMonitors: function() {\r
21246 if (this.destroyed) {\r
21247 return;\r
21248 }\r
21249 var expandHelper = this.expandHelper,\r
21250 shrinkHelper = this.shrinkHelper,\r
21251 contentBounds = this.getContentBounds(),\r
21252 width = contentBounds.width,\r
21253 height = contentBounds.height,\r
21254 style;\r
21255 if (expandHelper && !expandHelper.destroyed) {\r
21256 style = expandHelper.style;\r
21257 style.width = (width + 1) + 'px';\r
21258 style.height = (height + 1) + 'px';\r
21259 }\r
21260 if (shrinkHelper && !shrinkHelper.destroyed) {\r
21261 style = shrinkHelper.style;\r
21262 style.width = width + 'px';\r
21263 style.height = height + 'px';\r
21264 }\r
21265 Ext.TaskQueue.requestRead('refresh', this);\r
21266 }\r
21267});\r
21268\r
21269\r
21270Ext.define('Ext.util.SizeMonitor', {\r
21271 constructor: function(config) {\r
21272 var namespace = Ext.util.sizemonitor;\r
21273 if (Ext.browser.is.Firefox) {\r
21274 return new namespace.OverflowChange(config);\r
21275 } else {\r
21276 return new namespace.Scroll(config);\r
21277 }\r
21278 }\r
21279});\r
21280\r
21281\r
21282Ext.define('Ext.event.publisher.ElementSize', {\r
21283 extend: Ext.event.publisher.Publisher,\r
21284 type: 'size',\r
21285 handledEvents: [\r
21286 'resize'\r
21287 ],\r
21288 constructor: function() {\r
21289 this.monitors = {};\r
21290 this.subscribers = {};\r
21291 this.callParent(arguments);\r
21292 },\r
21293 subscribe: function(element) {\r
21294 var id = element.id,\r
21295 subscribers = this.subscribers,\r
21296 monitors = this.monitors;\r
21297 if (subscribers[id]) {\r
21298 ++subscribers[id];\r
21299 } else {\r
21300 subscribers[id] = 1;\r
21301 monitors[id] = new Ext.util.SizeMonitor({\r
21302 element: element,\r
21303 callback: this.onElementResize,\r
21304 scope: this,\r
21305 args: [\r
21306 element\r
21307 ]\r
21308 });\r
21309 }\r
21310 element.on('painted', 'forceRefresh', monitors[id]);\r
21311 return true;\r
21312 },\r
21313 unsubscribe: function(element) {\r
21314 var id = element.id,\r
21315 subscribers = this.subscribers,\r
21316 monitors = this.monitors,\r
21317 sizeMonitor;\r
21318 if (subscribers[id] && !--subscribers[id]) {\r
21319 delete subscribers[id];\r
21320 sizeMonitor = monitors[id];\r
21321 element.un('painted', 'forceRefresh', sizeMonitor);\r
21322 sizeMonitor.destroy();\r
21323 delete monitors[id];\r
21324 }\r
21325 },\r
21326 onElementResize: function(element, info) {\r
21327 Ext.TaskQueue.requestRead('fire', this, [\r
21328 element,\r
21329 'resize',\r
21330 [\r
21331 element,\r
21332 info\r
21333 ]\r
21334 ]);\r
21335 },\r
21336
21337
21338
21339 privates: {\r
21340 syncRefresh: function(elements) {\r
21341 elements = Ext.Array.from(elements);\r
21342 var len = elements.length,\r
21343 i = 0,\r
21344 el, monitor;\r
21345 for (i = 0; i < len; ++i) {\r
21346 el = elements[i];\r
21347 if (typeof el !== 'string') {\r
21348 el = el.id;\r
21349 }\r
21350 monitor = this.monitors[el];\r
21351 if (monitor) {\r
21352 monitor.forceRefresh();\r
21353 }\r
21354 }\r
21355 Ext.TaskQueue.flush();\r
21356 }\r
21357 }\r
21358},
21359function(ElementSize) {\r
21360 ElementSize.instance = new ElementSize();\r
21361});\r
21362\r
21363\r
21364Ext.define('Ext.util.paintmonitor.Abstract', {\r
21365 config: {\r
21366 element: null,\r
21367 callback: Ext.emptyFn,\r
21368 scope: null,\r
21369 args: []\r
21370 },\r
21371 eventName: '',\r
21372 monitorClass: '',\r
21373 constructor: function(config) {\r
21374 this.onElementPainted = Ext.Function.bind(this.onElementPainted, this);\r
21375 this.initConfig(config);\r
21376 },\r
21377 bindListeners: function(bind) {\r
21378 this.monitorElement[bind ? 'addEventListener' : 'removeEventListener'](this.eventName, this.onElementPainted, true);\r
21379 },\r
21380 applyElement: function(element) {\r
21381 if (element) {\r
21382 return Ext.get(element);\r
21383 }\r
21384 },\r
21385 updateElement: function(element) {\r
21386 this.monitorElement = Ext.Element.create({\r
21387 classList: [\r
21388 Ext.baseCSSPrefix + 'paint-monitor',\r
21389 this.monitorClass\r
21390 ]\r
21391 }, true);\r
21392 element.appendChild(this.monitorElement);\r
21393 element.addCls(Ext.baseCSSPrefix + 'paint-monitored');\r
21394 this.bindListeners(true);\r
21395 },\r
21396 onElementPainted: function() {},\r
21397 destroy: function() {\r
21398 var me = this,\r
21399 monitorElement = me.monitorElement,\r
21400 parentNode = monitorElement.parentNode,\r
21401 element = me.getElement();\r
21402 me.bindListeners(false);\r
21403 delete me.monitorElement;\r
21404 if (element && !element.destroyed) {\r
21405 element.removeCls(Ext.baseCSSPrefix + 'paint-monitored');\r
21406 delete me._element;\r
21407 }\r
21408 if (parentNode) {\r
21409 parentNode.removeChild(monitorElement);\r
21410 }\r
21411 me.callParent();\r
21412 }\r
21413});\r
21414\r
21415\r
21416Ext.define('Ext.util.paintmonitor.CssAnimation', {\r
21417 extend: Ext.util.paintmonitor.Abstract,\r
21418 eventName: Ext.browser.is.WebKit ? 'webkitAnimationEnd' : 'animationend',\r
21419 monitorClass: 'cssanimation',\r
21420 onElementPainted: function(e) {\r
21421 if (e.animationName === Ext.baseCSSPrefix + 'paint-monitor-helper') {\r
21422 this.getCallback().apply(this.getScope(), this.getArgs());\r
21423 }\r
21424 }\r
21425});\r
21426\r
21427\r
21428Ext.define('Ext.util.PaintMonitor', {\r
21429 constructor: function(config) {\r
21430 return new Ext.util.paintmonitor.CssAnimation(config);\r
21431 }\r
21432});\r
21433\r
21434\r
21435Ext.define('Ext.event.publisher.ElementPaint', {\r
21436 extend: Ext.event.publisher.Publisher,\r
21437 type: 'paint',\r
21438 handledEvents: [\r
21439 'painted'\r
21440 ],\r
21441 constructor: function() {\r
21442 this.monitors = {};\r
21443 this.subscribers = {};\r
21444 this.callParent(arguments);\r
21445 },\r
21446 subscribe: function(element) {\r
21447 var me = this,\r
21448 id = element.id,\r
21449 subscribers = me.subscribers;\r
21450 if (subscribers[id]) {\r
21451 ++subscribers[id];\r
21452 } else {\r
21453 subscribers[id] = 1;\r
21454 me.monitors[id] = new Ext.util.PaintMonitor({\r
21455 element: element,\r
21456 callback: me.onElementPainted,\r
21457 scope: me,\r
21458 args: [\r
21459 element\r
21460 ]\r
21461 });\r
21462 }\r
21463 },\r
21464 unsubscribe: function(element) {\r
21465 var id = element.id,\r
21466 subscribers = this.subscribers,\r
21467 monitors = this.monitors;\r
21468 if (subscribers[id] && !--subscribers[id]) {\r
21469 delete subscribers[id];\r
21470 monitors[id].destroy();\r
21471 delete monitors[id];\r
21472 }\r
21473 },\r
21474 onElementPainted: function(element) {\r
21475 Ext.TaskQueue.requestRead('fire', this, [\r
21476 element,\r
21477 'painted',\r
21478 [\r
21479 element\r
21480 ]\r
21481 ]);\r
21482 }\r
21483}, function(ElementPaint) {\r
21484 ElementPaint.instance = new ElementPaint();\r
21485});\r
21486\r
21487\r
21488Ext.define('Ext.dom.Element', function(Element) {\r
21489 var WIN = window,\r
21490 DOC = document,\r
21491 windowId = 'ext-window',\r
21492 documentId = 'ext-document',\r
21493 WIDTH = 'width',\r
21494 HEIGHT = 'height',\r
21495 MIN_WIDTH = 'min-width',\r
21496 MIN_HEIGHT = 'min-height',\r
21497 MAX_WIDTH = 'max-width',\r
21498 MAX_HEIGHT = 'max-height',\r
21499 TOP = 'top',\r
21500 RIGHT = 'right',\r
21501 BOTTOM = 'bottom',\r
21502 LEFT = 'left',\r
21503 VISIBILITY = 'visibility',\r
21504 HIDDEN = 'hidden',\r
21505 DISPLAY = "display",\r
21506 NONE = "none",\r
21507 ZINDEX = "z-index",\r
21508 POSITION = "position",\r
21509 RELATIVE = "relative",\r
21510 STATIC = "static",\r
21511 SEPARATOR = '-',\r
21512 wordsRe = /\w/g,\r
21513 spacesRe = /\s+/,\r
21514 classNameSplitRegex = /[\s]+/,\r
21515 transparentRe = /^(?:transparent|(?:rgba[(](?:\s*\d+\s*[,]){3}\s*0\s*[)]))$/i,\r
21516 adjustDirect2DTableRe = /table-row|table-.*-group/,\r
21517 topRe = /top/i,\r
21518 borders = {\r
21519 t: 'border-top-width',\r
21520 r: 'border-right-width',\r
21521 b: 'border-bottom-width',\r
21522 l: 'border-left-width'\r
21523 },\r
21524 paddings = {\r
21525 t: 'padding-top',\r
21526 r: 'padding-right',\r
21527 b: 'padding-bottom',\r
21528 l: 'padding-left'\r
21529 },\r
21530 margins = {\r
21531 t: 'margin-top',\r
21532 r: 'margin-right',\r
21533 b: 'margin-bottom',\r
21534 l: 'margin-left'\r
21535 },\r
21536 paddingsTLRB = [\r
21537 paddings.l,\r
21538 paddings.r,\r
21539 paddings.t,\r
21540 paddings.b\r
21541 ],\r
21542 bordersTLRB = [\r
21543 borders.l,\r
21544 borders.r,\r
21545 borders.t,\r
21546 borders.b\r
21547 ],\r
21548 numberRe = /\d+$/,\r
21549 unitRe = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,\r
21550 defaultUnit = 'px',\r
21551 camelRe = /(-[a-z])/gi,\r
21552 cssRe = /([a-z0-9\-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi,\r
21553 pxRe = /^\d+(?:\.\d*)?px$/i,\r
21554 propertyCache = {},\r
21555 ORIGINALDISPLAY = 'originalDisplay',\r
21556 camelReplaceFn = function(m, a) {\r
21557 return a.charAt(1).toUpperCase();\r
21558 },\r
21559 clearData = function(node, deep) {\r
21560 var childNodes, i, len;\r
21561
21562
21563 if (node.nodeType === 1) {\r
21564 node._extData = null;\r
21565 if (deep) {\r
21566 childNodes = node.childNodes;\r
21567 for (i = 0 , len = childNodes.length; i < len; ++i) {\r
21568 clearData(childNodes[i], deep);\r
21569 }\r
21570 }\r
21571 }\r
21572 },\r
21573 visibilityCls = Ext.baseCSSPrefix + 'hidden-visibility',\r
21574 displayCls = Ext.baseCSSPrefix + 'hidden-display',\r
21575 offsetsCls = Ext.baseCSSPrefix + 'hidden-offsets',\r
21576 clipCls = Ext.baseCSSPrefix + 'hidden-clip',\r
21577 sizedCls = Ext.baseCSSPrefix + 'sized',\r
21578 unsizedCls = Ext.baseCSSPrefix + 'unsized',\r
21579 stretchedCls = Ext.baseCSSPrefix + 'stretched',\r
21580 noTouchScrollCls = Ext.baseCSSPrefix + 'no-touch-scroll',\r
21581 CREATE_ATTRIBUTES = {\r
21582 style: 'style',\r
21583 className: 'className',\r
21584 cls: 'cls',\r
21585 classList: 'classList',\r
21586 text: 'text',\r
21587 hidden: 'hidden',\r
21588 html: 'html',\r
21589 children: 'children'\r
21590 },\r
21591 lastFocusChange = 0,\r
21592 lastKeyboardClose = 0,\r
21593 editableHasFocus = false,\r
21594 isVirtualKeyboardOpen = false,\r
21595 visFly, scrollFly, caFly;\r
21596 return {\r
21597 alternateClassName: [\r
21598 'Ext.Element'\r
21599 ],\r
21600 mixins: [\r
21601 Ext.util.Positionable,\r
21602 Ext.mixin.Observable\r
21603 ],\r
21604 observableType: 'element',\r
21605 isElement: true,\r
21606 skipGarbageCollection: true,\r
21607 $applyConfigs: true,\r
21608 identifiablePrefix: 'ext-element-',\r
21609 styleHooks: {},\r
21610 validIdRe: Ext.validIdRe,\r
21611 blockedEvents: Ext.supports.EmulatedMouseOver ? {\r
21612
21613
21614
21615
21616
21617 mouseover: 1\r
21618 } : {},\r
21619 longpressEvents: {\r
21620 longpress: 1,\r
21621 taphold: 1\r
21622 },\r
21623 \r
21624
21625 \r
21626 \r
21627 \r
21628 \r
21629 \r
21630 \r
21631 \r
21632 \r
21633 \r
21634 \r
21635
21636 \r
21637 \r
21638 \r
21639
21640 \r
21641 \r
21642 \r
21643 \r
21644 \r
21645 \r
21646 \r
21647
21648 \r
21649 \r
21650 \r
21651 \r
21652 \r
21653 \r
21654 \r
21655
21656 \r
21657 \r
21658 \r
21659
21660 \r
21661 \r
21662 \r
21663 \r
21664 \r
21665 \r
21666 \r
21667 \r
21668 constructor: function(dom) {\r
21669 var me = this,\r
21670 id;\r
21671 if (typeof dom === 'string') {\r
21672 dom = DOC.getElementById(dom);\r
21673 }\r
21674 if (!dom) {\r
21675
21676 Ext.raise("Invalid domNode reference or an id of an existing domNode: " + dom);\r
21677
21678 return null;\r
21679 }\r
21680
21681 if (Ext.cache[dom.id]) {\r
21682 Ext.raise("Element cache already contains an entry for id '" + dom.id + "'. Use Ext.get() to create or retrieve Element instances.");\r
21683 }\r
21684
21685 \r
21686 me.dom = dom;\r
21687 id = dom.id;\r
21688 if (id) {\r
21689 me.id = id;\r
21690 } else {\r
21691 id = dom.id = me.getUniqueId();\r
21692 }\r
21693
21694 if (!me.validIdRe.test(me.id)) {\r
21695 Ext.raise('Invalid Element "id": "' + me.id + '"');\r
21696 }\r
21697
21698
21699
21700
21701 me.el = me;\r
21702 Ext.cache[id] = me;\r
21703 me.mixins.observable.constructor.call(me);\r
21704 },\r
21705 inheritableStatics: {\r
21706 \r
21707 cache: Ext.cache = {},\r
21708 \r
21709 editableSelector: 'input,textarea,[contenteditable="true"]',\r
21710 \r
21711 VISIBILITY: 1,\r
21712 \r
21713 DISPLAY: 2,\r
21714 \r
21715 OFFSETS: 3,\r
21716 \r
21717 CLIP: 4,\r
21718 \r
21719 minKeyboardHeight: 100,\r
21720 unitRe: unitRe,\r
21721 \r
21722 useDelegatedEvents: true,\r
21723 \r
21724 validNodeTypes: {\r
21725 1: 1,\r
21726
21727 9: 1\r
21728 },\r
21729
21730 \r
21731 addUnits: function(size, units) {\r
21732
21733 if (typeof size === 'number') {\r
21734 return size + (units || defaultUnit);\r
21735 }\r
21736
21737
21738
21739
21740
21741 if (size === "" || size === "auto" || size == null) {\r
21742 return size || '';\r
21743 }\r
21744
21745
21746 if (numberRe.test(size)) {\r
21747 return size + (units || defaultUnit);\r
21748 }\r
21749
21750 if (!unitRe.test(size)) {\r
21751
21752 Ext.Logger.warn("Warning, size detected (" + size + ") not a valid property value on Element.addUnits.");\r
21753
21754 return size || '';\r
21755 }\r
21756 return size;\r
21757 },\r
21758 \r
21759 create: function(attributes, domNode) {\r
21760 var me = this,\r
21761 hidden = CREATE_ATTRIBUTES.hidden,\r
21762 element, elementStyle, tag, value, name, i, ln, className;\r
21763 if (!attributes) {\r
21764 attributes = {};\r
21765 }\r
21766 if (attributes.isElement) {\r
21767 return domNode ? attributes.dom : attributes;\r
21768 } else if ('nodeType' in attributes) {\r
21769 return domNode ? attributes : Ext.get(attributes);\r
21770 }\r
21771 if (typeof attributes === 'string') {\r
21772 return DOC.createTextNode(attributes);\r
21773 }\r
21774 tag = attributes.tag;\r
21775 if (!tag) {\r
21776 tag = 'div';\r
21777 }\r
21778 if (attributes.namespace) {\r
21779 element = DOC.createElementNS(attributes.namespace, tag);\r
21780 } else {\r
21781 element = DOC.createElement(tag);\r
21782 }\r
21783 elementStyle = element.style;\r
21784 if (attributes[hidden]) {\r
21785 className = attributes.className;\r
21786 className = (className == null) ? '' : className + ' ';\r
21787 attributes.className = className + displayCls;\r
21788 delete attributes[hidden];\r
21789 }\r
21790 for (name in attributes) {\r
21791 if (name !== 'tag') {\r
21792 value = attributes[name];\r
21793 switch (name) {\r
21794 case CREATE_ATTRIBUTES.style:\r
21795 if (typeof value === 'string') {\r
21796 element.setAttribute(name, value);\r
21797 } else {\r
21798 for (i in value) {\r
21799 if (value.hasOwnProperty(i)) {\r
21800 elementStyle[i] = value[i];\r
21801 }\r
21802 }\r
21803 };\r
21804 break;\r
21805 case CREATE_ATTRIBUTES.className:\r
21806 case CREATE_ATTRIBUTES.cls:\r
21807 element.className = value;\r
21808 break;\r
21809 case CREATE_ATTRIBUTES.classList:\r
21810 element.className = value.join(' ');\r
21811 break;\r
21812 case CREATE_ATTRIBUTES.text:\r
21813 element.textContent = value;\r
21814 break;\r
21815 case CREATE_ATTRIBUTES.html:\r
21816 element.innerHTML = value;\r
21817 break;\r
21818 case CREATE_ATTRIBUTES.children:\r
21819 for (i = 0 , ln = value.length; i < ln; i++) {\r
21820 element.appendChild(me.create(value[i], true));\r
21821 };\r
21822 break;\r
21823 default:\r
21824 if (value != null) {\r
21825
21826 element.setAttribute(name, value);\r
21827 };\r
21828 }\r
21829 }\r
21830 }\r
21831 if (domNode) {\r
21832 return element;\r
21833 } else {\r
21834 return me.get(element);\r
21835 }\r
21836 },\r
21837 \r
21838 detach: function() {\r
21839 var dom = this.dom;\r
21840 if (dom && dom.parentNode && dom.tagName !== 'BODY') {\r
21841 dom.parentNode.removeChild(dom);\r
21842 }\r
21843 return this;\r
21844 },\r
21845 \r
21846 fly: function(dom, named) {\r
21847 return Ext.fly(dom, named);\r
21848 },\r
21849 \r
21850 fromPoint: function(x, y) {\r
21851 return Ext.get(DOC.elementFromPoint(x, y));\r
21852 },\r
21853 \r
21854 get: function(el) {\r
21855 var me = this,\r
21856 cache = Ext.cache,\r
21857 nodeType, dom, id, entry, isDoc, isWin, isValidNodeType;\r
21858 if (!el) {\r
21859 return null;\r
21860 }\r
21861
21862 function warnDuplicate(id) {\r
21863 Ext.raise("DOM element with id " + id + " in Element cache is not the same as element in the DOM. " + "Make sure to clean up Element instances using destroy()");\r
21864 }\r
21865
21866
21867 if (el.isFly) {\r
21868 el = el.dom;\r
21869 }\r
21870 if (typeof el === 'string') {\r
21871 id = el;\r
21872 if (cache.hasOwnProperty(id)) {\r
21873 entry = cache[id];\r
21874 if (entry.skipGarbageCollection || !Ext.isGarbage(entry.dom)) {\r
21875
21876 dom = Ext.getElementById ? Ext.getElementById(id) : DOC.getElementById(id);\r
21877 if (dom && (dom !== entry.dom)) {\r
21878 warnDuplicate(id);\r
21879 }\r
21880
21881 return entry;\r
21882 } else {\r
21883 entry.destroy();\r
21884 }\r
21885 }\r
21886 if (id === windowId) {\r
21887 return Element.get(WIN);\r
21888 } else if (id === documentId) {\r
21889 return Element.get(DOC);\r
21890 }\r
21891
21892
21893 dom = Ext.getElementById ? Ext.getElementById(id) : DOC.getElementById(id);\r
21894 if (dom) {\r
21895 return new Element(dom);\r
21896 }\r
21897 }\r
21898 nodeType = el.nodeType;\r
21899 if (nodeType) {\r
21900 isDoc = (nodeType === 9);\r
21901 isValidNodeType = me.validNodeTypes[nodeType];\r
21902 } else {\r
21903
21904
21905
21906 isWin = (el.window == el);\r
21907 }\r
21908
21909
21910
21911 if (isValidNodeType || isWin) {\r
21912 id = el.id;\r
21913 if (cache.hasOwnProperty(id)) {\r
21914 entry = cache[id];\r
21915 if (entry.skipGarbageCollection || el === entry.dom || !Ext.isGarbage(entry.dom)) {\r
21916
21917 if (el !== entry.dom) {\r
21918 warnDuplicate(id);\r
21919 }\r
21920
21921 return entry;\r
21922 } else {\r
21923 entry.destroy();\r
21924 }\r
21925 }\r
21926 if (el === DOC) {\r
21927 el.id = documentId;\r
21928 }\r
21929
21930 if (el == WIN) {\r
21931 el.id = windowId;\r
21932 }\r
21933 el = new Element(el);\r
21934 if (isWin || isDoc) {\r
21935
21936 el.skipGarbageCollection = true;\r
21937 }\r
21938 return el;\r
21939 }\r
21940 if (el.isElement) {\r
21941 return el;\r
21942 }\r
21943 if (el.isComposite) {\r
21944 return el;\r
21945 }\r
21946
21947
21948 if (Ext.isIterable(el)) {\r
21949 return me.select(el);\r
21950 }\r
21951 return null;\r
21952 },\r
21953 \r
21954 getActiveElement: function(asElement) {\r
21955 var active = DOC.activeElement;\r
21956
21957
21958
21959
21960 if (!active || !active.focus) {\r
21961 active = DOC.body;\r
21962 }\r
21963 return asElement ? Ext.get(active) : active;\r
21964 },\r
21965 \r
21966 getDocumentHeight: function() {\r
21967 return Math.max(!Ext.isStrict ? DOC.body.scrollHeight : DOC.documentElement.scrollHeight, this.getViewportHeight());\r
21968 },\r
21969 \r
21970 getDocumentWidth: function() {\r
21971 return Math.max(!Ext.isStrict ? DOC.body.scrollWidth : DOC.documentElement.scrollWidth, this.getViewportWidth());\r
21972 },\r
21973 \r
21974 getOrientation: function() {\r
21975 if (Ext.supports.OrientationChange) {\r
21976 return (WIN.orientation == 0) ? 'portrait' : 'landscape';\r
21977 }\r
21978 return (WIN.innerHeight > WIN.innerWidth) ? 'portrait' : 'landscape';\r
21979 },\r
21980 \r
21981 getViewportHeight: function() {\r
21982 var viewportHeight = Element._viewportHeight;\r
21983
21984 if (Ext.isIE9m) {\r
21985 return DOC.documentElement.clientHeight;\r
21986 }\r
21987
21988 return (viewportHeight != null) ? viewportHeight : WIN.innerHeight;\r
21989 },\r
21990 \r
21991 getViewportWidth: function() {\r
21992 var viewportWidth = Element._viewportWidth;\r
21993
21994 if (Ext.isIE9m) {\r
21995 return DOC.documentElement.clientWidth;\r
21996 }\r
21997
21998 return (viewportWidth != null) ? viewportWidth : WIN.innerWidth;\r
21999 },\r
22000 \r
22001 getViewSize: function() {\r
22002 return {\r
22003 width: Element.getViewportWidth(),\r
22004 height: Element.getViewportHeight()\r
22005 };\r
22006 },\r
22007 \r
22008 normalize: function(prop) {\r
22009 return propertyCache[prop] || (propertyCache[prop] = prop.replace(camelRe, camelReplaceFn));\r
22010 },\r
22011 \r
22012 _onWindowFocusChange: function(e) {\r
22013
22014
22015
22016
22017 if (Ext.fly(e.target).is(Element.editableSelector)) {\r
22018 lastFocusChange = new Date();\r
22019 editableHasFocus = (e.type === 'focusin' || e.type === 'pointerup');\r
22020 }\r
22021 },\r
22022 \r
22023 _onWindowResize: function() {\r
22024 var windowWidth = window.innerWidth,\r
22025 windowHeight = window.innerHeight,\r
22026 now = new Date(),\r
22027 threshold = 1000,\r
22028 deltaX, deltaY;\r
22029 deltaX = windowWidth - Element._windowWidth;\r
22030 deltaY = windowHeight - Element._windowHeight;\r
22031 Element._windowWidth = windowWidth;\r
22032 Element._windowHeight = windowHeight;\r
22033
22034
22035
22036 if (((now - lastFocusChange) < threshold) || ((now - lastKeyboardClose) < threshold)) {\r
22037
22038
22039
22040
22041 if (deltaX === 0 && (editableHasFocus && (deltaY <= -Element.minKeyboardHeight))) {\r
22042 isVirtualKeyboardOpen = true;\r
22043 return;\r
22044 }\r
22045 }\r
22046 if (isVirtualKeyboardOpen && (deltaX === 0) && (deltaY >= Element.minKeyboardHeight)) {\r
22047 isVirtualKeyboardOpen = false;\r
22048
22049
22050
22051
22052 lastKeyboardClose = new Date();\r
22053 }\r
22054 if (isVirtualKeyboardOpen) {\r
22055 return;\r
22056 }\r
22057
22058
22059
22060 Element._viewportWidth = windowWidth;\r
22061 Element._viewportHeight = windowHeight;\r
22062 },\r
22063 \r
22064 parseBox: function(box) {\r
22065 box = box || 0;\r
22066 var type = typeof box,\r
22067 parts, ln;\r
22068 if (type === 'number') {\r
22069 return {\r
22070 top: box,\r
22071 right: box,\r
22072 bottom: box,\r
22073 left: box\r
22074 };\r
22075 } else if (type !== 'string') {\r
22076
22077 return box;\r
22078 }\r
22079 parts = box.split(' ');\r
22080 ln = parts.length;\r
22081 if (ln === 1) {\r
22082 parts[1] = parts[2] = parts[3] = parts[0];\r
22083 } else if (ln === 2) {\r
22084 parts[2] = parts[0];\r
22085 parts[3] = parts[1];\r
22086 } else if (ln === 3) {\r
22087 parts[3] = parts[1];\r
22088 }\r
22089 return {\r
22090 top: parseFloat(parts[0]) || 0,\r
22091 right: parseFloat(parts[1]) || 0,\r
22092 bottom: parseFloat(parts[2]) || 0,\r
22093 left: parseFloat(parts[3]) || 0\r
22094 };\r
22095 },\r
22096 \r
22097 parseStyles: function(styles) {\r
22098 var out = {},\r
22099 matches;\r
22100 if (styles) {\r
22101
22102
22103
22104
22105 cssRe.lastIndex = 0;\r
22106 while ((matches = cssRe.exec(styles))) {\r
22107 out[matches[1]] = matches[2] || '';\r
22108 }\r
22109 }\r
22110 return out;\r
22111 },\r
22112 \r
22113 select: function(selector, composite, root) {\r
22114 return Ext.fly(root || DOC).select(selector, composite);\r
22115 },\r
22116 \r
22117 query: function(selector, asDom, root) {\r
22118 return Ext.fly(root || DOC).query(selector, asDom);\r
22119 },\r
22120 \r
22121 unitizeBox: function(box, units) {\r
22122 var me = this;\r
22123 box = me.parseBox(box);\r
22124 return me.addUnits(box.top, units) + ' ' + me.addUnits(box.right, units) + ' ' + me.addUnits(box.bottom, units) + ' ' + me.addUnits(box.left, units);\r
22125 },\r
22126 \r
22127 serializeForm: function(form) {\r
22128 var fElements = form.elements || (DOC.forms[form] || Ext.getDom(form)).elements,\r
22129 hasSubmit = false,\r
22130 encoder = encodeURIComponent,\r
22131 data = '',\r
22132 eLen = fElements.length,\r
22133 element, name, type, options, hasValue, e, o, oLen, opt;\r
22134 for (e = 0; e < eLen; e++) {\r
22135 element = fElements[e];\r
22136 name = element.name;\r
22137 type = element.type;\r
22138 options = element.options;\r
22139 if (!element.disabled && name) {\r
22140 if (/select-(one|multiple)/i.test(type)) {\r
22141 oLen = options.length;\r
22142 for (o = 0; o < oLen; o++) {\r
22143 opt = options[o];\r
22144 if (opt.selected) {\r
22145 hasValue = opt.hasAttribute('value');\r
22146 data += Ext.String.format('{0}={1}&', encoder(name), encoder(hasValue ? opt.value : opt.text));\r
22147 }\r
22148 }\r
22149 } else if (!(/file|undefined|reset|button/i.test(type))) {\r
22150 if (!(/radio|checkbox/i.test(type) && !element.checked) && !(type == 'submit' && hasSubmit)) {\r
22151 data += encoder(name) + '=' + encoder(element.value) + '&';\r
22152 hasSubmit = /submit/i.test(type);\r
22153 }\r
22154 }\r
22155 }\r
22156 }\r
22157 return data.substr(0, data.length - 1);\r
22158 },\r
22159 \r
22160 getCommonAncestor: function(nodeA, nodeB, returnDom) {\r
22161 caFly = caFly || new Ext.dom.Fly();\r
22162 caFly.attach(Ext.getDom(nodeA));\r
22163 while (!caFly.isAncestor(nodeB)) {\r
22164 if (caFly.dom.parentNode) {\r
22165 caFly.attach(caFly.dom.parentNode);\r
22166 } else
22167 {\r
22168 caFly.attach(document.body);\r
22169 break;\r
22170 }\r
22171 }\r
22172 return returnDom ? caFly.dom : Ext.get(caFly);\r
22173 }\r
22174 },\r
22175
22176 \r
22177 addCls: function(names, prefix, suffix) {\r
22178 var me = this,\r
22179 elementData = me.getData(),\r
22180 hasNewCls, dom, map, classList, i, ln, name;\r
22181 if (!names) {\r
22182 return me;\r
22183 }\r
22184 if (!elementData.isSynchronized) {\r
22185 me.synchronize();\r
22186 }\r
22187 dom = me.dom;\r
22188 map = elementData.classMap;\r
22189 classList = elementData.classList;\r
22190 prefix = prefix ? prefix + SEPARATOR : '';\r
22191 suffix = suffix ? SEPARATOR + suffix : '';\r
22192 if (typeof names === 'string') {\r
22193 names = names.split(spacesRe);\r
22194 }\r
22195 for (i = 0 , ln = names.length; i < ln; i++) {\r
22196 name = names[i];\r
22197
22198 if (name) {\r
22199 name = prefix + name + suffix;\r
22200 if (!map[name]) {\r
22201 map[name] = true;\r
22202 classList.push(name);\r
22203 hasNewCls = true;\r
22204 }\r
22205 }\r
22206 }\r
22207 if (hasNewCls) {\r
22208 dom.className = classList.join(' ');\r
22209 }\r
22210 return me;\r
22211 },\r
22212 addStyles: function(sides, styles) {\r
22213 var totalSize = 0,\r
22214 sidesArr = (sides || '').match(wordsRe),\r
22215 i,\r
22216 len = sidesArr.length,\r
22217 side,\r
22218 styleSides = [];\r
22219 if (len === 1) {\r
22220 totalSize = Math.abs(parseFloat(this.getStyle(styles[sidesArr[0]])) || 0);\r
22221 } else if (len) {\r
22222 for (i = 0; i < len; i++) {\r
22223 side = sidesArr[i];\r
22224 styleSides.push(styles[side]);\r
22225 }\r
22226
22227 styleSides = this.getStyle(styleSides);\r
22228 for (i = 0; i < len; i++) {\r
22229 side = sidesArr[i];\r
22230 totalSize += parseFloat(styleSides[styles[side]]) || 0;\r
22231 }\r
22232 }\r
22233 return totalSize;\r
22234 },\r
22235 addUnits: function(size, units) {\r
22236 return Element.addUnits(size, units);\r
22237 },\r
22238 \r
22239 adjustDirect2DDimension: function(dimension) {\r
22240 var me = this,\r
22241 dom = me.dom,\r
22242 display = me.getStyle('display'),\r
22243 inlineDisplay = dom.style.display,\r
22244 inlinePosition = dom.style.position,\r
22245 originIndex = dimension === WIDTH ? 0 : 1,\r
22246 currentStyle = dom.currentStyle,\r
22247 floating;\r
22248 if (display === 'inline') {\r
22249 dom.style.display = 'inline-block';\r
22250 }\r
22251 dom.style.position = display.match(adjustDirect2DTableRe) ? 'absolute' : 'static';\r
22252
22253
22254
22255
22256 floating = (parseFloat(currentStyle[dimension]) || parseFloat(currentStyle.msTransformOrigin.split(' ')[originIndex]) * 2) % 1;\r
22257 dom.style.position = inlinePosition;\r
22258 if (display === 'inline') {\r
22259 dom.style.display = inlineDisplay;\r
22260 }\r
22261 return floating;\r
22262 },\r
22263
22264
22265
22266 animate: function(animation) {\r
22267 animation = new Ext.fx.Animation(animation);\r
22268 animation.setElement(this);\r
22269 this._activeAnimation = animation;\r
22270 animation.on({\r
22271 animationend: this._onAnimationEnd\r
22272 });\r
22273 Ext.Animator.run(animation);\r
22274 return animation;\r
22275 },\r
22276 _onAnimationEnd: function() {\r
22277 this._activeAnimation = null;\r
22278 },\r
22279 getActiveAnimation: function() {\r
22280 return this._activeAnimation;\r
22281 },\r
22282 append: function() {\r
22283 this.appendChild.apply(this, arguments);\r
22284 },\r
22285 \r
22286 appendChild: function(el, returnDom) {\r
22287 var me = this,\r
22288 insertEl, eLen, e;\r
22289 if (el.nodeType || el.dom || typeof el === 'string') {\r
22290
22291 el = Ext.getDom(el);\r
22292 me.dom.appendChild(el);\r
22293 return !returnDom ? Ext.get(el) : el;\r
22294 } else if (el.length) {\r
22295
22296 insertEl = Ext.fly(document.createDocumentFragment());\r
22297 eLen = el.length;\r
22298 for (e = 0; e < eLen; e++) {\r
22299 insertEl.appendChild(el[e], returnDom);\r
22300 }\r
22301 me.dom.appendChild(insertEl.dom);\r
22302 return returnDom ? insertEl.dom : insertEl;\r
22303 } else {\r
22304
22305 return me.createChild(el, null, returnDom);\r
22306 }\r
22307 },\r
22308 \r
22309 appendTo: function(el) {\r
22310 Ext.getDom(el).appendChild(this.dom);\r
22311 return this;\r
22312 },\r
22313 \r
22314 applyStyles: function(styles) {\r
22315 if (styles) {\r
22316 if (typeof styles === "function") {\r
22317 styles = styles.call();\r
22318 }\r
22319 if (typeof styles === "string") {\r
22320 styles = Element.parseStyles(styles);\r
22321 }\r
22322 if (typeof styles === "object") {\r
22323 this.setStyle(styles);\r
22324 }\r
22325 }\r
22326 return this;\r
22327 },\r
22328 \r
22329 blur: function() {\r
22330 var me = this,\r
22331 dom = me.dom;\r
22332
22333
22334 if (dom !== DOC.body) {\r
22335 try {\r
22336 dom.blur();\r
22337 } catch (e) {}\r
22338 return me;\r
22339 } else {\r
22340 return me.focus(undefined, dom);\r
22341 }\r
22342 },\r
22343 \r
22344 cacheScrollValues: function() {\r
22345 var me = this,\r
22346 scrollValues = [],\r
22347 scrolledDescendants = [],\r
22348 descendants, descendant, i, len;\r
22349 scrollFly = scrollFly || new Ext.dom.Fly();\r
22350 descendants = me.query('*');\r
22351 for (i = 0 , len = descendants.length; i < len; i++) {\r
22352 descendant = descendants[i];\r
22353
22354
22355 if (descendant.scrollTop > 0 || descendant.scrollLeft !== 0) {\r
22356 scrolledDescendants.push(descendant);\r
22357 scrollValues.push(scrollFly.attach(descendant).getScroll());\r
22358 }\r
22359 }\r
22360 return function() {\r
22361 var scroll, i, len;\r
22362 for (i = 0 , len = scrolledDescendants.length; i < len; i++) {\r
22363 scroll = scrollValues[i];\r
22364 scrollFly.attach(scrolledDescendants[i]);\r
22365 scrollFly.setScrollLeft(scroll.left);\r
22366 scrollFly.setScrollTop(scroll.top);\r
22367 }\r
22368 };\r
22369 },\r
22370 \r
22371 center: function(centerIn) {\r
22372 return this.alignTo(centerIn || DOC, 'c-c');\r
22373 },\r
22374 \r
22375 child: function(selector, returnDom) {\r
22376 var me = this,\r
22377
22378
22379 id = Ext.get(me).id;\r
22380 return me.selectNode(Ext.makeIdSelector(id) + " > " + selector, !!returnDom);\r
22381 },\r
22382 \r
22383 clone: function(deep, returnDom) {\r
22384 var clone = this.dom.cloneNode(deep);\r
22385 if (Ext.supports.CloneNodeCopiesExpando) {\r
22386 clearData(clone, deep);\r
22387 }\r
22388 return returnDom ? clone : Ext.get(clone);\r
22389 },\r
22390 constrainScrollLeft: function(left) {\r
22391 var dom = this.dom;\r
22392 return Math.max(Math.min(left, dom.scrollWidth - dom.clientWidth), 0);\r
22393 },\r
22394 constrainScrollTop: function(top) {\r
22395 var dom = this.dom;\r
22396 return Math.max(Math.min(top, dom.scrollHeight - dom.clientHeight), 0);\r
22397 },\r
22398 \r
22399 createChild: function(config, insertBefore, returnDom) {\r
22400 config = config || {\r
22401 tag: 'div'\r
22402 };\r
22403 if (insertBefore) {\r
22404 return Ext.DomHelper.insertBefore(insertBefore, config, returnDom !== true);\r
22405 } else {\r
22406 return Ext.DomHelper.append(this.dom, config, returnDom !== true);\r
22407 }\r
22408 },\r
22409 \r
22410 contains: function(element) {\r
22411 if (!element) {\r
22412 return false;\r
22413 }\r
22414 var me = this,\r
22415 dom = Ext.getDom(element);\r
22416
22417
22418 return (dom === me.dom) || me.isAncestor(dom);\r
22419 },\r
22420 \r
22421 destroy: function() {\r
22422 var me = this,\r
22423 dom = me.dom;\r
22424
22425 if (me.destroyed) {\r
22426 Ext.Logger.warn("Cannot destroy Element \"" + me.id + "\". Already destroyed.");\r
22427 return;\r
22428 }\r
22429 if (dom) {\r
22430 if (dom === DOC.body) {\r
22431 Ext.raise("Cannot destroy body element.");\r
22432 } else if (dom === DOC) {\r
22433 Ext.raise("Cannot destroy document object.");\r
22434 } else if (dom === WIN) {\r
22435 Ext.raise("Cannot destroy window object");\r
22436 }\r
22437 }\r
22438
22439 if (dom && dom.parentNode) {\r
22440 dom.parentNode.removeChild(dom);\r
22441 }\r
22442 me.collect();\r
22443 if (!me.isFly) {\r
22444
22445
22446 me.callParent();\r
22447 }\r
22448 },\r
22449 detach: function() {\r
22450 var dom = this.dom;\r
22451 if (dom && dom.parentNode && dom.tagName !== 'BODY') {\r
22452 dom.parentNode.removeChild(dom);\r
22453 }\r
22454 return this;\r
22455 },\r
22456 \r
22457 disableShadow: function() {\r
22458 var shadow = this.shadow;\r
22459 if (shadow) {\r
22460 shadow.hide();\r
22461 shadow.disabled = true;\r
22462 }\r
22463 },\r
22464 \r
22465 disableShim: function() {\r
22466 var shim = this.shim;\r
22467 if (shim) {\r
22468 shim.hide();\r
22469 shim.disabled = true;\r
22470 }\r
22471 },\r
22472 \r
22473 disableTouchContextMenu: function() {\r
22474 this._contextMenuListenerRemover = this.on({\r
22475 MSHoldVisual: function(e) {\r
22476
22477 e.preventDefault();\r
22478 },\r
22479 destroyable: true,\r
22480 delegated: false\r
22481 });\r
22482 },\r
22483 \r
22484 disableTouchScroll: function() {\r
22485
22486 this.addCls(noTouchScrollCls);\r
22487
22488
22489
22490 this.on({\r
22491 touchmove: function(e) {\r
22492 e.preventDefault();\r
22493 },\r
22494 translate: false\r
22495 });\r
22496 },\r
22497 \r
22498 doReplaceWith: function(element) {\r
22499 var dom = this.dom;\r
22500 dom.parentNode.replaceChild(Ext.getDom(element), dom);\r
22501 },\r
22502 \r
22503 doScrollIntoView: function(container, hscroll, animate, highlight, getScrollX, scrollTo) {\r
22504 scrollFly = scrollFly || new Ext.dom.Fly();\r
22505 var me = this,\r
22506 dom = me.dom,\r
22507 scrollX = scrollFly.attach(container)[getScrollX](),\r
22508 scrollY = container.scrollTop,\r
22509 position = me.getScrollIntoViewXY(container, scrollX, scrollY),\r
22510 newScrollX = position.x,\r
22511 newScrollY = position.y;\r
22512
22513 if (highlight) {\r
22514 if (animate) {\r
22515 animate = Ext.apply({\r
22516 listeners: {\r
22517 afteranimate: function() {\r
22518 scrollFly.attach(dom).highlight();\r
22519 }\r
22520 }\r
22521 }, animate);\r
22522 } else {\r
22523 scrollFly.attach(dom).highlight();\r
22524 }\r
22525 }\r
22526 if (newScrollY !== scrollY) {\r
22527 scrollFly.attach(container).scrollTo('top', newScrollY, animate);\r
22528 }\r
22529 if (hscroll !== false && (newScrollX !== scrollX)) {\r
22530 scrollFly.attach(container)[scrollTo]('left', newScrollX, animate);\r
22531 }\r
22532 return me;\r
22533 },\r
22534 \r
22535 down: function(selector, returnDom) {\r
22536 return this.selectNode(selector, !!returnDom);\r
22537 },\r
22538 \r
22539 enableShadow: function(options, \r
22540 isVisible) {\r
22541 var me = this,\r
22542 shadow = me.shadow || (me.shadow = new Ext.dom.Shadow(Ext.apply({\r
22543 target: me\r
22544 }, options))),\r
22545 shim = me.shim;\r
22546 if (shim) {\r
22547 shim.offsets = shadow.outerOffsets;\r
22548 shim.shadow = shadow;\r
22549 shadow.shim = shim;\r
22550 }\r
22551
22552
22553 if (isVisible === true || (isVisible !== false && me.isVisible())) {\r
22554
22555
22556 shadow.show();\r
22557 } else {\r
22558 shadow.hide();\r
22559 }\r
22560 shadow.disabled = false;\r
22561 },\r
22562 \r
22563 enableShim: function(options, \r
22564 isVisible) {\r
22565 var me = this,\r
22566 shim = me.shim || (me.shim = new Ext.dom.Shim(Ext.apply({\r
22567 target: me\r
22568 }, options))),\r
22569 shadow = me.shadow;\r
22570 if (shadow) {\r
22571 shim.offsets = shadow.outerOffsets;\r
22572 shim.shadow = shadow;\r
22573 shadow.shim = shim;\r
22574 }\r
22575
22576
22577 if (isVisible === true || (isVisible !== false && me.isVisible())) {\r
22578
22579
22580 shim.show();\r
22581 } else {\r
22582 shim.hide();\r
22583 }\r
22584 shim.disabled = false;\r
22585 },\r
22586 \r
22587 findParent: function(simpleSelector, limit, returnEl) {\r
22588 var me = this,\r
22589 target = me.dom,\r
22590 topmost = DOC.documentElement,\r
22591 depth = 0;\r
22592 if (limit || limit === 0) {\r
22593 if (typeof limit !== 'number') {\r
22594 topmost = Ext.getDom(limit);\r
22595 limit = Number.MAX_VALUE;\r
22596 }\r
22597 } else {\r
22598
22599 limit = 50;\r
22600 }\r
22601 while (target && target.nodeType === 1 && depth < limit && target !== topmost) {\r
22602 if (Ext.fly(target).is(simpleSelector)) {\r
22603 return returnEl ? Ext.get(target) : target;\r
22604 }\r
22605 depth++;\r
22606 target = target.parentNode;\r
22607 }\r
22608 return null;\r
22609 },\r
22610 \r
22611 findParentNode: function(simpleSelector, limit, returnEl) {\r
22612 var p = Ext.fly(this.dom.parentNode);\r
22613 return p ? p.findParent(simpleSelector, limit, returnEl) : null;\r
22614 },\r
22615 \r
22616 first: function(selector, returnDom) {\r
22617 return this.matchNode('nextSibling', 'firstChild', selector, returnDom);\r
22618 },\r
22619 \r
22620 focus: function(defer, \r
22621 dom) {\r
22622 var me = this;\r
22623 dom = dom || me.dom;\r
22624 if (Number(defer)) {\r
22625 Ext.defer(me.focus, defer, me, [\r
22626 null,\r
22627 dom\r
22628 ]);\r
22629 } else {\r
22630 Ext.GlobalEvents.fireEvent('beforefocus', dom);\r
22631 dom.focus();\r
22632 }\r
22633 return me;\r
22634 },\r
22635 \r
22636 collect: function() {\r
22637 var me = this,\r
22638 dom = me.dom,\r
22639 shadow = me.shadow,\r
22640 shim = me.shim;\r
22641 if (!me.isFly) {\r
22642 me.mixins.observable.destroy.call(me);\r
22643 delete Ext.cache[me.id];\r
22644 me.destroyed = true;\r
22645 me.el = null;\r
22646 }\r
22647 if (dom) {\r
22648 dom._extData = me.dom = null;\r
22649 }\r
22650
22651
22652 if (shadow) {\r
22653 shadow.hide();\r
22654 me.shadow = null;\r
22655 }\r
22656 if (shim) {\r
22657 shim.hide();\r
22658 me.shim = null;\r
22659 }\r
22660 },\r
22661 getAnchorToXY: function(el, anchor, local, mySize) {\r
22662 return el.getAnchorXY(anchor, local, mySize);\r
22663 },\r
22664 \r
22665 getAttribute: function(name, namespace) {\r
22666 var dom = this.dom;\r
22667 return namespace ? (dom.getAttributeNS(namespace, name) || dom.getAttribute(namespace + ":" + name)) : (dom.getAttribute(name) || dom[name] || null);\r
22668 },\r
22669 \r
22670 getAttributes: function() {\r
22671 var attributes = this.dom.attributes,\r
22672 result = {},\r
22673 attr, i, len;\r
22674 for (i = 0 , len = attributes.length; i < len; i++) {\r
22675 attr = attributes[i];\r
22676 result[attr.name] = attr.value;\r
22677 }\r
22678 return result;\r
22679 },\r
22680 \r
22681 getBottom: function(local) {\r
22682 return (local ? this.getLocalY() : this.getY()) + this.getHeight();\r
22683 },\r
22684 \r
22685 getById: function(id, asDom) {\r
22686
22687
22688 var dom = DOC.getElementById(id) || this.dom.querySelector(Ext.makeIdSelector(id));\r
22689 return asDom ? dom : (dom ? Ext.get(dom) : null);\r
22690 },\r
22691 getBorderPadding: function() {\r
22692 var paddingWidth = this.getStyle(paddingsTLRB),\r
22693 bordersWidth = this.getStyle(bordersTLRB);\r
22694 return {\r
22695 beforeX: (parseFloat(bordersWidth[borders.l]) || 0) + (parseFloat(paddingWidth[paddings.l]) || 0),\r
22696 afterX: (parseFloat(bordersWidth[borders.r]) || 0) + (parseFloat(paddingWidth[paddings.r]) || 0),\r
22697 beforeY: (parseFloat(bordersWidth[borders.t]) || 0) + (parseFloat(paddingWidth[paddings.t]) || 0),\r
22698 afterY: (parseFloat(bordersWidth[borders.b]) || 0) + (parseFloat(paddingWidth[paddings.b]) || 0)\r
22699 };\r
22700 },\r
22701 \r
22702 getBorders: function() {\r
22703 var bordersWidth = this.getStyle(bordersTLRB);\r
22704 return {\r
22705 beforeX: (parseFloat(bordersWidth[borders.l]) || 0),\r
22706 afterX: (parseFloat(bordersWidth[borders.r]) || 0),\r
22707 beforeY: (parseFloat(bordersWidth[borders.t]) || 0),\r
22708 afterY: (parseFloat(bordersWidth[borders.b]) || 0)\r
22709 };\r
22710 },\r
22711 \r
22712 getBorderWidth: function(side) {\r
22713 return this.addStyles(side, borders);\r
22714 },\r
22715 getData: function(preventCreate) {\r
22716 var dom = this.dom,\r
22717 data;\r
22718 if (dom) {\r
22719 data = dom._extData;\r
22720 if (!data && !preventCreate) {\r
22721 dom._extData = data = {};\r
22722 }\r
22723 }\r
22724 return data;\r
22725 },\r
22726 getFirstChild: function() {\r
22727 return Ext.get(this.dom.firstElementChild);\r
22728 },\r
22729 \r
22730 getHeight: function(contentHeight, preciseHeight) {\r
22731 var me = this,\r
22732 hidden = me.isStyle('display', 'none'),\r
22733 height, floating;\r
22734 if (hidden) {\r
22735 return 0;\r
22736 }\r
22737 height = me.dom.offsetHeight;\r
22738
22739 if (Ext.supports.Direct2DBug) {\r
22740 floating = me.adjustDirect2DDimension(HEIGHT);\r
22741 if (preciseHeight) {\r
22742 height += floating;\r
22743 } else if (floating > 0 && floating < 0.5) {\r
22744 height++;\r
22745 }\r
22746 }\r
22747 if (contentHeight) {\r
22748 height -= me.getBorderWidth("tb") + me.getPadding("tb");\r
22749 }\r
22750 return (height < 0) ? 0 : height;\r
22751 },\r
22752 \r
22753 getHtml: function() {\r
22754 return this.dom ? this.dom.innerHTML : '';\r
22755 },\r
22756 \r
22757 getLeft: function(local) {\r
22758 return local ? this.getLocalX() : this.getX();\r
22759 },\r
22760 getLocalX: function() {\r
22761 var me = this,\r
22762 offsetParent,\r
22763 x = me.getStyle('left');\r
22764 if (!x || x === 'auto') {\r
22765 x = 0;\r
22766 } else if (pxRe.test(x)) {\r
22767 x = parseFloat(x);\r
22768 } else {\r
22769 x = me.getX();\r
22770
22771
22772 offsetParent = me.dom.offsetParent;\r
22773 if (offsetParent) {\r
22774 x -= Ext.fly(offsetParent).getX();\r
22775 }\r
22776 }\r
22777 return x;\r
22778 },\r
22779 getLocalXY: function() {\r
22780 var me = this,\r
22781 offsetParent,\r
22782 style = me.getStyle([\r
22783 'left',\r
22784 'top'\r
22785 ]),\r
22786 x = style.left,\r
22787 y = style.top;\r
22788 if (!x || x === 'auto') {\r
22789 x = 0;\r
22790 } else if (pxRe.test(x)) {\r
22791 x = parseFloat(x);\r
22792 } else {\r
22793 x = me.getX();\r
22794
22795
22796 offsetParent = me.dom.offsetParent;\r
22797 if (offsetParent) {\r
22798 x -= Ext.fly(offsetParent).getX();\r
22799 }\r
22800 }\r
22801 if (!y || y === 'auto') {\r
22802 y = 0;\r
22803 } else if (pxRe.test(y)) {\r
22804 y = parseFloat(y);\r
22805 } else {\r
22806 y = me.getY();\r
22807
22808
22809 offsetParent = me.dom.offsetParent;\r
22810 if (offsetParent) {\r
22811 y -= Ext.fly(offsetParent).getY();\r
22812 }\r
22813 }\r
22814 return [\r
22815 x,\r
22816 y\r
22817 ];\r
22818 },\r
22819 getLocalY: function() {\r
22820 var me = this,\r
22821 offsetParent,\r
22822 y = me.getStyle('top');\r
22823 if (!y || y === 'auto') {\r
22824 y = 0;\r
22825 } else if (pxRe.test(y)) {\r
22826 y = parseFloat(y);\r
22827 } else {\r
22828 y = me.getY();\r
22829
22830
22831 offsetParent = me.dom.offsetParent;\r
22832 if (offsetParent) {\r
22833 y -= Ext.fly(offsetParent).getY();\r
22834 }\r
22835 }\r
22836 return y;\r
22837 },\r
22838 \r
22839 getMargin: (function() {\r
22840 var hash = {\r
22841 t: "top",\r
22842 l: "left",\r
22843 r: "right",\r
22844 b: "bottom"\r
22845 },\r
22846 allMargins = [\r
22847 'margin-top',\r
22848 'margin-left',\r
22849 'margin-right',\r
22850 'margin-bottom'\r
22851 ];\r
22852 return function(side) {\r
22853 var me = this,\r
22854 style, key, o;\r
22855 if (!side) {\r
22856 style = me.getStyle(allMargins);\r
22857 o = {};\r
22858 if (style && typeof style === 'object') {\r
22859 o = {};\r
22860 for (key in margins) {\r
22861 o[key] = o[hash[key]] = parseFloat(style[margins[key]]) || 0;\r
22862 }\r
22863 }\r
22864 } else {\r
22865 o = me.addStyles(side, margins);\r
22866 }\r
22867 return o;\r
22868 };\r
22869 })(),\r
22870 \r
22871 getPadding: function(side) {\r
22872 return this.addStyles(side, paddings);\r
22873 },\r
22874 getParent: function() {\r
22875 return Ext.get(this.dom.parentNode);\r
22876 },\r
22877 \r
22878 getRight: function(local) {\r
22879 return (local ? this.getLocalX() : this.getX()) + this.getWidth();\r
22880 },\r
22881 \r
22882 getScroll: function() {\r
22883 var me = this,\r
22884 dom = me.dom,\r
22885 docElement = DOC.documentElement,\r
22886 left, top,\r
22887 body = document.body;\r
22888 if (dom === DOC || dom === body) {\r
22889
22890
22891
22892
22893
22894
22895
22896
22897 left = docElement.scrollLeft || (body ? body.scrollLeft : 0);\r
22898 top = docElement.scrollTop || (body ? body.scrollTop : 0);\r
22899 } else {\r
22900 left = dom.scrollLeft;\r
22901 top = dom.scrollTop;\r
22902 }\r
22903 return {\r
22904 left: left,\r
22905 top: top\r
22906 };\r
22907 },\r
22908 \r
22909 getScrollIntoViewXY: function(container, scrollX, scrollY) {\r
22910 var dom = this.dom,\r
22911 ct = Ext.getDom(container),\r
22912 offsets = this.getOffsetsTo(ct),\r
22913 width = dom.offsetWidth,\r
22914 height = dom.offsetHeight,\r
22915 left = offsets[0] + scrollX,\r
22916 top = offsets[1] + scrollY,\r
22917 bottom = top + height,\r
22918 right = left + width,\r
22919 viewHeight = ct.clientHeight,\r
22920 viewWidth = ct.clientWidth,\r
22921 viewLeft = scrollX,\r
22922 viewTop = scrollY,\r
22923 viewBottom = viewTop + viewHeight,\r
22924 viewRight = viewLeft + viewWidth;\r
22925 if (height > viewHeight || top < viewTop) {\r
22926 scrollY = top;\r
22927 } else if (bottom > viewBottom) {\r
22928 scrollY = bottom - viewHeight;\r
22929 }\r
22930 if (width > viewWidth || left < viewLeft) {\r
22931 scrollX = left;\r
22932 } else if (right > viewRight) {\r
22933 scrollX = right - viewWidth;\r
22934 }\r
22935 return {\r
22936 x: scrollX,\r
22937 y: scrollY\r
22938 };\r
22939 },\r
22940 \r
22941 getScrollLeft: function() {\r
22942 var dom = this.dom;\r
22943 if (dom === DOC || dom === document.body) {\r
22944 return this.getScroll().left;\r
22945 } else {\r
22946 return dom.scrollLeft;\r
22947 }\r
22948 },\r
22949 \r
22950 getScrollTop: function() {\r
22951 var dom = this.dom;\r
22952 if (dom === DOC || dom === document.body) {\r
22953 return this.getScroll().top;\r
22954 } else {\r
22955 return dom.scrollTop;\r
22956 }\r
22957 },\r
22958 \r
22959 getSize: function(contentSize) {\r
22960 return {\r
22961 width: this.getWidth(contentSize),\r
22962 height: this.getHeight(contentSize)\r
22963 };\r
22964 },\r
22965 \r
22966 getStyle: function(property, inline) {\r
22967 var me = this,\r
22968 dom = me.dom,\r
22969 multiple = typeof property !== 'string',\r
22970 hooks = me.styleHooks,\r
22971 prop = property,\r
22972 props = prop,\r
22973 len = 1,\r
22974 domStyle, camel, values, hook, out, style, i;\r
22975 if (multiple) {\r
22976 values = {};\r
22977 prop = props[0];\r
22978 i = 0;\r
22979 if (!(len = props.length)) {\r
22980 return values;\r
22981 }\r
22982 }\r
22983 if (!dom || dom.documentElement) {\r
22984 return values || '';\r
22985 }\r
22986 domStyle = dom.style;\r
22987 if (inline) {\r
22988 style = domStyle;\r
22989 } else {\r
22990
22991
22992
22993
22994 style = dom.ownerDocument.defaultView.getComputedStyle(dom, null);\r
22995
22996 if (!style) {\r
22997 inline = true;\r
22998 style = domStyle;\r
22999 }\r
23000 }\r
23001 do {\r
23002 hook = hooks[prop];\r
23003 if (!hook) {\r
23004 hooks[prop] = hook = {\r
23005 name: Element.normalize(prop)\r
23006 };\r
23007 }\r
23008 if (hook.get) {\r
23009 out = hook.get(dom, me, inline, style);\r
23010 } else {\r
23011 camel = hook.name;\r
23012 out = style[camel];\r
23013 }\r
23014 if (!multiple) {\r
23015 return out;\r
23016 }\r
23017 values[prop] = out;\r
23018 prop = props[++i];\r
23019 } while (i < len);\r
23020 return values;\r
23021 },\r
23022 getStyleValue: function(name) {\r
23023 return this.dom.style.getPropertyValue(name);\r
23024 },\r
23025 \r
23026 getTop: function(local) {\r
23027 return local ? this.getLocalY() : this.getY();\r
23028 },\r
23029 \r
23030 getValue: function(asNumber) {\r
23031 var value = this.dom.value;\r
23032 return asNumber ? parseInt(value, 10) : value;\r
23033 },\r
23034 \r
23035 getViewSize: function() {\r
23036 var dom = this.dom;\r
23037 if (dom === DOC || dom === DOC.body) {\r
23038 return {\r
23039 width: Element.getViewportWidth(),\r
23040 height: Element.getViewportHeight()\r
23041 };\r
23042 } else {\r
23043 return {\r
23044 width: dom.clientWidth,\r
23045 height: dom.clientHeight\r
23046 };\r
23047 }\r
23048 },\r
23049 getVisibilityMode: function() {\r
23050 var me = this,\r
23051 data = me.getData(),\r
23052 mode = data.visibilityMode;\r
23053 if (mode === undefined) {\r
23054 data.visibilityMode = mode = Element.DISPLAY;\r
23055 }\r
23056 return mode;\r
23057 },\r
23058 \r
23059 getWidth: function(contentWidth, preciseWidth) {\r
23060 var me = this,\r
23061 dom = me.dom,\r
23062 hidden = me.isStyle('display', 'none'),\r
23063 rect, width, floating;\r
23064 if (hidden) {\r
23065 return 0;\r
23066 }\r
23067
23068
23069
23070
23071
23072
23073 if (Ext.supports.BoundingClientRect) {\r
23074 rect = dom.getBoundingClientRect();\r
23075 width = (me.vertical && !Ext.supports.RotatedBoundingClientRect) ? (rect.bottom - rect.top) : (rect.right - rect.left);\r
23076 width = preciseWidth ? width : Math.ceil(width);\r
23077 } else {\r
23078 width = dom.offsetWidth;\r
23079 }\r
23080
23081
23082
23083 if (Ext.supports.Direct2DBug && !me.vertical) {\r
23084
23085 floating = me.adjustDirect2DDimension(WIDTH);\r
23086 if (preciseWidth) {\r
23087 width += floating;\r
23088 }\r
23089
23090
23091
23092 else if (floating > 0 && floating < 0.5) {\r
23093 width++;\r
23094 }\r
23095 }\r
23096 if (contentWidth) {\r
23097 width -= me.getBorderWidth("lr") + me.getPadding("lr");\r
23098 }\r
23099 return (width < 0) ? 0 : width;\r
23100 },\r
23101 \r
23102 getX: function() {\r
23103 return this.getXY()[0];\r
23104 },\r
23105 \r
23106 getXY: function() {\r
23107 var round = Math.round,\r
23108 dom = this.dom,\r
23109 x = 0,\r
23110 y = 0,\r
23111 box, scroll;\r
23112 if (dom !== DOC && dom !== DOC.body) {\r
23113
23114
23115 try {\r
23116 box = dom.getBoundingClientRect();\r
23117 } catch (ex) {\r
23118 box = {\r
23119 left: 0,\r
23120 top: 0\r
23121 };\r
23122 }\r
23123 x = round(box.left);\r
23124 y = round(box.top);\r
23125 scroll = Ext.getDoc().getScroll();\r
23126 x += scroll.left;\r
23127 y += scroll.top;\r
23128 }\r
23129 return [\r
23130 x,\r
23131 y\r
23132 ];\r
23133 },\r
23134 \r
23135 getY: function() {\r
23136 return this.getXY()[1];\r
23137 },\r
23138 \r
23139 getZIndex: function() {\r
23140 return parseInt(this.getStyle('z-index'), 10);\r
23141 },\r
23142 \r
23143 hasCls: function(name) {\r
23144 var elementData = this.getData();\r
23145 if (!elementData.isSynchronized) {\r
23146 this.synchronize();\r
23147 }\r
23148 return elementData.classMap.hasOwnProperty(name);\r
23149 },\r
23150 \r
23151 hide: function() {\r
23152 this.setVisible(false);\r
23153 return this;\r
23154 },\r
23155 \r
23156 insertAfter: function(el) {\r
23157 el = Ext.getDom(el);\r
23158 el.parentNode.insertBefore(this.dom, el.nextSibling);\r
23159 return this;\r
23160 },\r
23161 \r
23162 insertBefore: function(el) {\r
23163 el = Ext.getDom(el);\r
23164 el.parentNode.insertBefore(this.dom, el);\r
23165 return this;\r
23166 },\r
23167 \r
23168 insertFirst: function(el, returnDom) {\r
23169 el = el || {};\r
23170 if (el.nodeType || el.dom || typeof el === 'string') {\r
23171
23172 el = Ext.getDom(el);\r
23173 this.dom.insertBefore(el, this.dom.firstChild);\r
23174 return !returnDom ? Ext.get(el) : el;\r
23175 } else {\r
23176
23177 return this.createChild(el, this.dom.firstChild, returnDom);\r
23178 }\r
23179 },\r
23180 \r
23181 insertHtml: function(where, html, returnEl) {\r
23182 var el = Ext.DomHelper.insertHtml(where, this.dom, html);\r
23183 return returnEl ? Ext.get(el) : el;\r
23184 },\r
23185 \r
23186 insertSibling: function(el, where, returnDom) {\r
23187 var me = this,\r
23188 DomHelper = Ext.DomHelper,\r
23189 isAfter = (where || 'before').toLowerCase() === 'after',\r
23190 rt, insertEl, eLen, e;\r
23191 if (Ext.isIterable(el)) {\r
23192 eLen = el.length;\r
23193 insertEl = Ext.fly(document.createDocumentFragment());\r
23194
23195 if (Ext.isArray(el)) {\r
23196 for (e = 0; e < eLen; e++) {\r
23197 rt = insertEl.appendChild(el[e], returnDom);\r
23198 }\r
23199 } else
23200 {\r
23201 for (e = 0; e < eLen; e++) {\r
23202 insertEl.dom.appendChild(rt = el[0]);\r
23203 }\r
23204 if (returnDom === false) {\r
23205 rt = Ext.get(rt);\r
23206 }\r
23207 }\r
23208
23209 me.dom.parentNode.insertBefore(insertEl.dom, isAfter ? me.dom.nextSibling : me.dom);\r
23210 return rt;\r
23211 }\r
23212 el = el || {};\r
23213 if (el.nodeType || el.dom) {\r
23214 rt = me.dom.parentNode.insertBefore(Ext.getDom(el), isAfter ? me.dom.nextSibling : me.dom);\r
23215 if (!returnDom) {\r
23216 rt = Ext.get(rt);\r
23217 }\r
23218 } else {\r
23219 if (isAfter && !me.dom.nextSibling) {\r
23220 rt = DomHelper.append(me.dom.parentNode, el, !returnDom);\r
23221 } else {\r
23222 rt = DomHelper[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom);\r
23223 }\r
23224 }\r
23225 return rt;\r
23226 },\r
23227 \r
23228 is: function(selector) {\r
23229 var dom = this.dom,\r
23230 is;\r
23231 if (!selector) {\r
23232
23233
23234
23235
23236
23237
23238
23239 is = true;\r
23240 } else if (!dom.tagName) {\r
23241
23242 is = false;\r
23243 } else if (Ext.isFunction(selector)) {\r
23244 is = selector(dom);\r
23245 } else {\r
23246 is = dom[Ext.supports.matchesSelector](selector);\r
23247 }\r
23248 return is;\r
23249 },\r
23250 \r
23251 isAncestor: function(el) {\r
23252 var ret = false,\r
23253 dom = this.dom,\r
23254 child = Ext.getDom(el);\r
23255 if (dom && child) {\r
23256 if (dom.contains) {\r
23257 return dom.contains(child);\r
23258 } else if (dom.compareDocumentPosition) {\r
23259 return !!(dom.compareDocumentPosition(child) & 16);\r
23260 } else {\r
23261 while ((child = child.parentNode)) {\r
23262 ret = child === dom || ret;\r
23263 }\r
23264 }\r
23265 }\r
23266 return ret;\r
23267 },\r
23268 isPainted: (function() {\r
23269 return !Ext.browser.is.IE ? function() {\r
23270 var dom = this.dom;\r
23271 return Boolean(dom && dom.offsetParent);\r
23272 } : function() {\r
23273 var dom = this.dom;\r
23274 return Boolean(dom && (dom.offsetHeight !== 0 && dom.offsetWidth !== 0));\r
23275 };\r
23276 })(),\r
23277 \r
23278 isScrollable: function() {\r
23279 var dom = this.dom;\r
23280 return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth;\r
23281 },\r
23282 \r
23283 isStyle: function(style, val) {\r
23284 return this.getStyle(style) === val;\r
23285 },\r
23286 \r
23287 isVisible: function(deep) {\r
23288 var dom = this.dom,\r
23289 end;\r
23290 if (!dom) {\r
23291 return false;\r
23292 }\r
23293 if (!visFly) {\r
23294 visFly = new Ext.dom.Fly();\r
23295 }\r
23296 for (end = dom.ownerDocument.documentElement; dom !== end; dom = dom.parentNode) {\r
23297
23298
23299 if (!dom || dom.nodeType === 11 || (visFly.attach(dom)).isStyle(VISIBILITY, HIDDEN) || visFly.isStyle(DISPLAY, NONE)) {\r
23300 return false;\r
23301 }\r
23302
23303 if (!deep) {\r
23304 break;\r
23305 }\r
23306 }\r
23307 return true;\r
23308 },\r
23309 \r
23310 last: function(selector, returnDom) {\r
23311 return this.matchNode('previousSibling', 'lastChild', selector, returnDom);\r
23312 },\r
23313 \r
23314 maskIframes: function() {\r
23315 var iframes = document.getElementsByTagName('iframe');\r
23316 Ext.each(iframes, function(iframe) {\r
23317 var iframeParent = Ext.fly(iframe.parentNode),\r
23318 myMask = iframeParent.mask();\r
23319 myMask.setStyle('background-color', 'transparent');\r
23320 });\r
23321 },\r
23322 \r
23323 matchNode: function(dir, start, selector, returnDom) {\r
23324 var dom = this.dom,\r
23325 n;\r
23326 if (!dom) {\r
23327 return null;\r
23328 }\r
23329 n = dom[start];\r
23330 while (n) {\r
23331 if (n.nodeType === 1 && (!selector || Ext.fly(n, '_matchNode').is(selector))) {\r
23332 return !returnDom ? Ext.get(n) : n;\r
23333 }\r
23334 n = n[dir];\r
23335 }\r
23336 return null;\r
23337 },\r
23338 \r
23339 next: function(selector, returnDom) {\r
23340 return this.matchNode('nextSibling', 'nextSibling', selector, returnDom);\r
23341 },\r
23342 \r
23343 parent: function(selector, returnDom) {\r
23344 return this.matchNode('parentNode', 'parentNode', selector, returnDom);\r
23345 },\r
23346 \r
23347 position: function(pos, zIndex, x, y) {\r
23348 var me = this;\r
23349 if (me.dom.tagName !== 'BODY') {\r
23350 if (!pos && me.isStyle(POSITION, STATIC)) {\r
23351 me.setStyle(POSITION, RELATIVE);\r
23352 } else if (pos) {\r
23353 me.setStyle(POSITION, pos);\r
23354 }\r
23355 if (zIndex) {\r
23356 me.setStyle(ZINDEX, zIndex);\r
23357 }\r
23358 if (x || y) {\r
23359 me.setXY([\r
23360 x || false,\r
23361 y || false\r
23362 ]);\r
23363 }\r
23364 }\r
23365 },\r
23366 \r
23367 prev: function(selector, returnDom) {\r
23368 return this.matchNode('previousSibling', 'previousSibling', selector, returnDom);\r
23369 },\r
23370 \r
23371 query: function(selector, asDom, \r
23372 single) {\r
23373 var dom = this.dom,\r
23374 results, len, nlen, node, nodes, i, j;\r
23375 if (!dom) {\r
23376 return null;\r
23377 }\r
23378 asDom = (asDom !== false);\r
23379 selector = selector.split(",");\r
23380 if (!single) {\r
23381
23382
23383 results = [];\r
23384 }\r
23385 for (i = 0 , len = selector.length; i < len; i++) {\r
23386 if (typeof selector[i] === 'string') {\r
23387 if (single) {\r
23388
23389 node = dom.querySelector(selector[i]);\r
23390 return asDom ? node : Ext.get(node);\r
23391 }\r
23392 nodes = dom.querySelectorAll(selector[i]);\r
23393 for (j = 0 , nlen = nodes.length; j < nlen; j++) {\r
23394 results.push(asDom ? nodes[j] : Ext.get(nodes[j]));\r
23395 }\r
23396 }\r
23397 }\r
23398 return results;\r
23399 },\r
23400 \r
23401 radioCls: function(className) {\r
23402 var cn = this.dom.parentNode.childNodes,\r
23403 v;\r
23404 className = Ext.isArray(className) ? className : [\r
23405 className\r
23406 ];\r
23407 for (var i = 0,\r
23408 len = cn.length; i < len; i++) {\r
23409 v = cn[i];\r
23410 if (v && v.nodeType === 1) {\r
23411 Ext.fly(v).removeCls(className);\r
23412 }\r
23413 }\r
23414 return this.addCls(className);\r
23415 },\r
23416 redraw: function() {\r
23417 var dom = this.dom,\r
23418 domStyle = dom.style;\r
23419 domStyle.display = 'none';\r
23420 dom.offsetHeight;\r
23421 domStyle.display = '';\r
23422 },\r
23423 \r
23424 remove: function() {\r
23425 this.destroy();\r
23426 },\r
23427 removeChild: function(element) {\r
23428 this.dom.removeChild(Ext.getDom(element));\r
23429 return this;\r
23430 },\r
23431 \r
23432 removeCls: function(names, prefix, suffix) {\r
23433 var me = this,\r
23434 elementData = me.getData(),\r
23435 hasNewCls, dom, map, classList, i, ln, name;\r
23436 if (!names) {\r
23437 return me;\r
23438 }\r
23439 if (!elementData.isSynchronized) {\r
23440 me.synchronize();\r
23441 }\r
23442 dom = me.dom;\r
23443 map = elementData.classMap;\r
23444 classList = elementData.classList;\r
23445 prefix = prefix ? prefix + SEPARATOR : '';\r
23446 suffix = suffix ? SEPARATOR + suffix : '';\r
23447 if (typeof names === 'string') {\r
23448 names = names.split(spacesRe);\r
23449 }\r
23450 for (i = 0 , ln = names.length; i < ln; i++) {\r
23451 name = names[i];\r
23452 if (name) {\r
23453 name = prefix + name + suffix;\r
23454 if (map[name]) {\r
23455 delete map[name];\r
23456 Ext.Array.remove(classList, name);\r
23457 hasNewCls = true;\r
23458 }\r
23459 }\r
23460 }\r
23461 if (hasNewCls) {\r
23462 dom.className = classList.join(' ');\r
23463 }\r
23464 return me;\r
23465 },\r
23466 \r
23467 repaint: function() {\r
23468 var me = this;\r
23469 me.addCls(Ext.baseCSSPrefix + 'repaint');\r
23470 Ext.defer(function() {\r
23471 if (me.dom) {\r
23472
23473 Ext.fly(me.dom).removeCls(Ext.baseCSSPrefix + 'repaint');\r
23474 }\r
23475 }, 1);\r
23476 return me;\r
23477 },\r
23478 \r
23479 replace: function(el, destroy) {\r
23480 el = Ext.getDom(el);\r
23481 var parentNode = el.parentNode,\r
23482 id = el.id,\r
23483 dom = this.dom;\r
23484
23485 if (!parentNode) {\r
23486 Ext.raise('Cannot replace element "' + id + '". It is not attached to a parent node.');\r
23487 }\r
23488
23489 if (destroy !== false && id && Ext.cache[id]) {\r
23490 parentNode.insertBefore(dom, el);\r
23491 Ext.get(el).destroy();\r
23492 } else {\r
23493 parentNode.replaceChild(dom, el);\r
23494 }\r
23495 return this;\r
23496 },\r
23497 \r
23498 replaceCls: function(oldName, newName, prefix, suffix) {\r
23499 var me = this,\r
23500 dom, map, classList, i, ln, name,\r
23501 elementData = me.getData(),\r
23502 change;\r
23503 if (!oldName && !newName) {\r
23504 return me;\r
23505 }\r
23506 oldName = oldName || [];\r
23507 newName = newName || [];\r
23508 if (!elementData.isSynchronized) {\r
23509 me.synchronize();\r
23510 }\r
23511 if (!suffix) {\r
23512 suffix = '';\r
23513 }\r
23514 dom = me.dom;\r
23515 map = elementData.classMap;\r
23516 classList = elementData.classList;\r
23517 prefix = prefix ? prefix + SEPARATOR : '';\r
23518 suffix = suffix ? SEPARATOR + suffix : '';\r
23519 if (typeof oldName === 'string') {\r
23520 oldName = oldName.split(spacesRe);\r
23521 }\r
23522 if (typeof newName === 'string') {\r
23523 newName = newName.split(spacesRe);\r
23524 }\r
23525 for (i = 0 , ln = oldName.length; i < ln; i++) {\r
23526 name = prefix + oldName[i] + suffix;\r
23527 if (map[name]) {\r
23528 delete map[name];\r
23529 change = true;\r
23530 }\r
23531 }\r
23532 for (i = 0 , ln = newName.length; i < ln; i++) {\r
23533 name = prefix + newName[i] + suffix;\r
23534 if (!map[name]) {\r
23535 map[name] = true;\r
23536 change = true;\r
23537 }\r
23538 }\r
23539 if (change) {\r
23540 elementData.classList = classList = Ext.Object.getKeys(map);\r
23541 dom.className = classList.join(' ');\r
23542 }\r
23543 return me;\r
23544 },\r
23545 \r
23546 replaceWith: function(el) {\r
23547 var me = this,\r
23548 dom = me.dom,\r
23549 parent = dom.parentNode,\r
23550 cache = Ext.cache,\r
23551 newDom;\r
23552 me.clearListeners();\r
23553 if (el.nodeType || el.dom || typeof el === 'string') {\r
23554 el = Ext.get(el);\r
23555 newDom = parent.insertBefore(el.dom, dom);\r
23556 } else {\r
23557
23558 newDom = Ext.DomHelper.insertBefore(dom, el);\r
23559 }\r
23560 parent.removeChild(dom);\r
23561 me.dom = newDom;\r
23562 if (!me.isFly) {\r
23563 delete cache[me.id];\r
23564 cache[me.id = Ext.id(newDom)] = me;\r
23565 }\r
23566 return me;\r
23567 },\r
23568 resolveListenerScope: function(defaultScope) {\r
23569
23570 var component = this.component;\r
23571 return component ? component.resolveListenerScope(defaultScope) : this;\r
23572 },\r
23573 \r
23574 scroll: function(direction, distance, animate) {\r
23575 if (!this.isScrollable()) {\r
23576 return false;\r
23577 }\r
23578
23579
23580 direction = direction.charAt(0);\r
23581 var me = this,\r
23582 dom = me.dom,\r
23583 side = direction === 'r' || direction === 'l' ? 'left' : 'top',\r
23584 scrolled = false,\r
23585 currentScroll, constrainedScroll;\r
23586 if (direction === 'l' || direction === 't' || direction === 'u') {\r
23587 distance = -distance;\r
23588 }\r
23589 if (side === 'left') {\r
23590 currentScroll = dom.scrollLeft;\r
23591 constrainedScroll = me.constrainScrollLeft(currentScroll + distance);\r
23592 } else {\r
23593 currentScroll = dom.scrollTop;\r
23594 constrainedScroll = me.constrainScrollTop(currentScroll + distance);\r
23595 }\r
23596 if (constrainedScroll !== currentScroll) {\r
23597 this.scrollTo(side, constrainedScroll, animate);\r
23598 scrolled = true;\r
23599 }\r
23600 return scrolled;\r
23601 },\r
23602 \r
23603 scrollBy: function(deltaX, deltaY, animate) {\r
23604 var me = this,\r
23605 dom = me.dom;\r
23606
23607 if (deltaX.length) {\r
23608 animate = deltaY;\r
23609 deltaY = deltaX[1];\r
23610 deltaX = deltaX[0];\r
23611 } else if (typeof deltaX != 'number') {\r
23612
23613 animate = deltaY;\r
23614 deltaY = deltaX.y;\r
23615 deltaX = deltaX.x;\r
23616 }\r
23617 if (deltaX) {\r
23618 me.scrollTo('left', me.constrainScrollLeft(dom.scrollLeft + deltaX), animate);\r
23619 }\r
23620 if (deltaY) {\r
23621 me.scrollTo('top', me.constrainScrollTop(dom.scrollTop + deltaY), animate);\r
23622 }\r
23623 return me;\r
23624 },\r
23625 \r
23626 scrollChildIntoView: function(child, hscroll) {\r
23627
23628 Ext.fly(child).scrollIntoView(this, hscroll);\r
23629 },\r
23630 \r
23631 scrollIntoView: function(container, hscroll, animate, highlight) {\r
23632 container = Ext.getDom(container) || Ext.getBody().dom;\r
23633 return this.doScrollIntoView(container, hscroll, animate, highlight, 'getScrollLeft', 'scrollTo');\r
23634 },\r
23635 \r
23636 scrollTo: function(side, value, animate) {\r
23637
23638 var top = topRe.test(side),\r
23639 me = this,\r
23640 prop = top ? 'scrollTop' : 'scrollLeft',\r
23641 dom = me.dom,\r
23642 animCfg;\r
23643 if (!animate || !me.anim) {\r
23644
23645 dom[prop] = value;\r
23646
23647 dom[prop] = value;\r
23648 } else {\r
23649 animCfg = {\r
23650 to: {}\r
23651 };\r
23652 animCfg.to[prop] = value;\r
23653 if (Ext.isObject(animate)) {\r
23654 Ext.applyIf(animCfg, animate);\r
23655 }\r
23656 me.animate(animCfg);\r
23657 }\r
23658 return me;\r
23659 },\r
23660 \r
23661 select: function(selector, composite) {\r
23662 var isElementArray, elements;\r
23663 if (typeof selector === "string") {\r
23664 elements = this.query(selector, !composite);\r
23665 }\r
23666
23667 else if (selector.length === undefined) {\r
23668 Ext.raise("Invalid selector specified: " + selector);\r
23669 } else
23670 {\r
23671
23672
23673 elements = selector;\r
23674 isElementArray = true;\r
23675 }\r
23676
23677
23678
23679
23680
23681
23682 return composite ? new Ext.CompositeElement(elements, !isElementArray) : new Ext.CompositeElementLite(elements, true);\r
23683 },\r
23684 \r
23685 selectNode: function(selector, asDom) {\r
23686 return this.query(selector, asDom, true);\r
23687 },\r
23688 \r
23689 set: function(attributes, useSet) {\r
23690 var me = this,\r
23691 dom = me.dom,\r
23692 attribute, value;\r
23693 for (attribute in attributes) {\r
23694 if (attributes.hasOwnProperty(attribute)) {\r
23695 value = attributes[attribute];\r
23696 if (attribute === 'style') {\r
23697 me.applyStyles(value);\r
23698 } else if (attribute === 'cls') {\r
23699 dom.className = value;\r
23700 } else if (useSet !== false) {\r
23701 if (value === undefined) {\r
23702 dom.removeAttribute(attribute);\r
23703 } else {\r
23704 dom.setAttribute(attribute, value);\r
23705 }\r
23706 } else {\r
23707 dom[attribute] = value;\r
23708 }\r
23709 }\r
23710 }\r
23711 return me;\r
23712 },\r
23713 \r
23714 setBottom: function(bottom) {\r
23715 this.dom.style[BOTTOM] = Element.addUnits(bottom);\r
23716 return this;\r
23717 },\r
23718 \r
23719 setCls: function(className) {\r
23720 var me = this,\r
23721 elementData = me.getData(),\r
23722 i, ln, name, map, classList;\r
23723 if (!elementData.isSynchronized) {\r
23724 me.synchronize();\r
23725 }\r
23726 if (typeof className === 'string') {\r
23727 className = className.split(spacesRe);\r
23728 }\r
23729 elementData.classList = classList = className.slice();\r
23730 elementData.classMap = map = {};\r
23731 for (i = 0 , ln = classList.length; i < ln; i++) {\r
23732 map[classList[i]] = true;\r
23733 }\r
23734 me.dom.className = classList.join(' ');\r
23735 },\r
23736 \r
23737 setDisplayed: function(value) {\r
23738 var me = this;\r
23739 if (typeof value === "boolean") {\r
23740 value = value ? me._getDisplay() : NONE;\r
23741 }\r
23742 me.setStyle(DISPLAY, value);\r
23743 if (me.shadow || me.shim) {\r
23744 me.setUnderlaysVisible(value !== NONE);\r
23745 }\r
23746 return me;\r
23747 },\r
23748 \r
23749 setHeight: function(height) {\r
23750 var me = this;\r
23751 me.dom.style[HEIGHT] = Element.addUnits(height);\r
23752 if (me.shadow || me.shim) {\r
23753 me.syncUnderlays();\r
23754 }\r
23755 return me;\r
23756 },\r
23757 \r
23758 setHtml: function(html) {\r
23759 if (this.dom) {\r
23760 this.dom.innerHTML = html;\r
23761 }\r
23762 return this;\r
23763 },\r
23764 setId: function(id) {\r
23765 var me = this,\r
23766 currentId = me.id,\r
23767 cache = Ext.cache;\r
23768 if (currentId) {\r
23769 delete cache[currentId];\r
23770 }\r
23771 me.dom.id = id;\r
23772 \r
23773 me.id = id;\r
23774 cache[id] = me;\r
23775 return me;\r
23776 },\r
23777 \r
23778 setLeft: function(left) {\r
23779 var me = this;\r
23780 me.dom.style[LEFT] = Element.addUnits(left);\r
23781 if (me.shadow || me.shim) {\r
23782 me.syncUnderlays();\r
23783 }\r
23784 return me;\r
23785 },\r
23786 setLocalX: function(x) {\r
23787 var me = this,\r
23788 style = me.dom.style;\r
23789
23790 style.right = 'auto';\r
23791 style.left = (x === null) ? 'auto' : x + 'px';\r
23792 if (me.shadow || me.shim) {\r
23793 me.syncUnderlays();\r
23794 }\r
23795 return me;\r
23796 },\r
23797 setLocalXY: function(x, y) {\r
23798 var me = this,\r
23799 style = me.dom.style;\r
23800
23801 style.right = 'auto';\r
23802 if (x && x.length) {\r
23803 y = x[1];\r
23804 x = x[0];\r
23805 }\r
23806 if (x === null) {\r
23807 style.left = 'auto';\r
23808 } else if (x !== undefined) {\r
23809 style.left = x + 'px';\r
23810 }\r
23811 if (y === null) {\r
23812 style.top = 'auto';\r
23813 } else if (y !== undefined) {\r
23814 style.top = y + 'px';\r
23815 }\r
23816 if (me.shadow || me.shim) {\r
23817 me.syncUnderlays();\r
23818 }\r
23819 return me;\r
23820 },\r
23821 setLocalY: function(y) {\r
23822 var me = this;\r
23823 me.dom.style.top = (y === null) ? 'auto' : y + 'px';\r
23824 if (me.shadow || me.shim) {\r
23825 me.syncUnderlays();\r
23826 }\r
23827 return me;\r
23828 },\r
23829 setMargin: function(margin) {\r
23830 var me = this,\r
23831 domStyle = me.dom.style;\r
23832 if (margin || margin === 0) {\r
23833 margin = me.self.unitizeBox((margin === true) ? 5 : margin);\r
23834 domStyle.setProperty('margin', margin, 'important');\r
23835 } else {\r
23836 domStyle.removeProperty('margin-top');\r
23837 domStyle.removeProperty('margin-right');\r
23838 domStyle.removeProperty('margin-bottom');\r
23839 domStyle.removeProperty('margin-left');\r
23840 }\r
23841 },\r
23842 \r
23843 setMaxHeight: function(height) {\r
23844 this.dom.style[MAX_HEIGHT] = Element.addUnits(height);\r
23845 return this;\r
23846 },\r
23847 \r
23848 setMaxWidth: function(width) {\r
23849 this.dom.style[MAX_WIDTH] = Element.addUnits(width);\r
23850 return this;\r
23851 },\r
23852 \r
23853 setMinHeight: function(height) {\r
23854 this.dom.style[MIN_HEIGHT] = Element.addUnits(height);\r
23855 return this;\r
23856 },\r
23857 \r
23858 setMinWidth: function(width) {\r
23859 this.dom.style[MIN_WIDTH] = Element.addUnits(width);\r
23860 return this;\r
23861 },\r
23862 \r
23863 setOpacity: function(opacity) {\r
23864 var me = this;\r
23865 if (me.dom) {\r
23866 me.setStyle('opacity', opacity);\r
23867 }\r
23868 return me;\r
23869 },\r
23870 setPadding: function(padding) {\r
23871 var me = this,\r
23872 domStyle = me.dom.style;\r
23873 if (padding || padding === 0) {\r
23874 padding = me.self.unitizeBox((padding === true) ? 5 : padding);\r
23875 domStyle.setProperty('padding', padding, 'important');\r
23876 } else {\r
23877 domStyle.removeProperty('padding-top');\r
23878 domStyle.removeProperty('padding-right');\r
23879 domStyle.removeProperty('padding-bottom');\r
23880 domStyle.removeProperty('padding-left');\r
23881 }\r
23882 },\r
23883 \r
23884 setRight: function(right) {\r
23885 this.dom.style[RIGHT] = Element.addUnits(right);\r
23886 return this;\r
23887 },\r
23888 \r
23889 setScrollLeft: function(left) {\r
23890 this.dom.scrollLeft = left;\r
23891 return this;\r
23892 },\r
23893 \r
23894 setScrollTop: function(top) {\r
23895 this.dom.scrollTop = top;\r
23896 return this;\r
23897 },\r
23898 \r
23899 setSize: function(width, height) {\r
23900 var me = this,\r
23901 style = me.dom.style;\r
23902 if (Ext.isObject(width)) {\r
23903
23904 height = width.height;\r
23905 width = width.width;\r
23906 }\r
23907 style.width = Element.addUnits(width);\r
23908 style.height = Element.addUnits(height);\r
23909 if (me.shadow || me.shim) {\r
23910 me.syncUnderlays();\r
23911 }\r
23912 return me;\r
23913 },\r
23914 setSizeState: function(state) {\r
23915 var me = this,\r
23916 add, remove;\r
23917 if (state === true) {\r
23918 add = sizedCls;\r
23919 remove = [\r
23920 unsizedCls,\r
23921 stretchedCls\r
23922 ];\r
23923 } else if (state === false) {\r
23924 add = unsizedCls;\r
23925 remove = [\r
23926 sizedCls,\r
23927 stretchedCls\r
23928 ];\r
23929 } else if (state === null) {\r
23930 add = stretchedCls;\r
23931 remove = [\r
23932 sizedCls,\r
23933 unsizedCls\r
23934 ];\r
23935 } else {\r
23936 remove = [\r
23937 sizedCls,\r
23938 unsizedCls,\r
23939 stretchedCls\r
23940 ];\r
23941 }\r
23942 if (add) {\r
23943 me.addCls(add);\r
23944 }\r
23945 me.removeCls(remove);\r
23946 return me;\r
23947 },\r
23948 \r
23949 setStyle: function(prop, value) {\r
23950 var me = this,\r
23951 dom = me.dom,\r
23952 hooks = me.styleHooks,\r
23953 style = dom.style,\r
23954 name = prop,\r
23955 hook;\r
23956
23957 if (typeof name === 'string') {\r
23958 hook = hooks[name];\r
23959 if (!hook) {\r
23960 hooks[name] = hook = {\r
23961 name: Element.normalize(name)\r
23962 };\r
23963 }\r
23964 value = (value == null) ? '' : value;\r
23965
23966 if (hook.set) {\r
23967 hook.set(dom, value, me);\r
23968 } else {\r
23969 style[hook.name] = value;\r
23970 }\r
23971 if (hook.afterSet) {\r
23972 hook.afterSet(dom, value, me);\r
23973 }\r
23974 } else {\r
23975 for (name in prop) {\r
23976 if (prop.hasOwnProperty(name)) {\r
23977 hook = hooks[name];\r
23978 if (!hook) {\r
23979 hooks[name] = hook = {\r
23980 name: Element.normalize(name)\r
23981 };\r
23982 }\r
23983 value = prop[name];\r
23984 value = (value == null) ? '' : value;\r
23985
23986 if (hook.set) {\r
23987 hook.set(dom, value, me);\r
23988 } else {\r
23989 style[hook.name] = value;\r
23990 }\r
23991 if (hook.afterSet) {\r
23992 hook.afterSet(dom, value, me);\r
23993 }\r
23994 }\r
23995 }\r
23996 }\r
23997 return me;\r
23998 },\r
23999 setText: function(text) {\r
24000 this.dom.textContent = text;\r
24001 },\r
24002 \r
24003 setTop: function(top) {\r
24004 var me = this;\r
24005 me.dom.style[TOP] = Element.addUnits(top);\r
24006 if (me.shadow || me.shim) {\r
24007 me.syncUnderlays();\r
24008 }\r
24009 return me;\r
24010 },\r
24011 setUnderlaysVisible: function(visible) {\r
24012 var shadow = this.shadow,\r
24013 shim = this.shim;\r
24014 if (shadow && !shadow.disabled) {\r
24015 if (visible) {\r
24016 shadow.show();\r
24017 } else {\r
24018 shadow.hide();\r
24019 }\r
24020 }\r
24021 if (shim && !shim.disabled) {\r
24022 if (visible) {\r
24023 shim.show();\r
24024 } else {\r
24025 shim.hide();\r
24026 }\r
24027 }\r
24028 },\r
24029 \r
24030 setVisibility: function(isVisible) {\r
24031 var domStyle = this.dom.style;\r
24032 if (isVisible) {\r
24033 domStyle.removeProperty('visibility');\r
24034 } else {\r
24035 domStyle.setProperty('visibility', 'hidden', 'important');\r
24036 }\r
24037 },\r
24038 \r
24039 setVisibilityMode: function(mode) {\r
24040
24041 if (mode !== 1 && mode !== 2 && mode !== 3 && mode !== 4) {\r
24042 Ext.raise("visibilityMode must be one of the following: " + "Ext.Element.DISPLAY, Ext.Element.VISIBILITY, Ext.Element.OFFSETS, " + "or Ext.Element.CLIP");\r
24043 }\r
24044
24045 this.getData().visibilityMode = mode;\r
24046 return this;\r
24047 },\r
24048 \r
24049 setVisible: function(visible) {\r
24050 var me = this,\r
24051 mode = me.getVisibilityMode(),\r
24052 addOrRemove = visible ? 'removeCls' : 'addCls';\r
24053 switch (mode) {\r
24054 case Element.DISPLAY:\r
24055 me.removeCls([\r
24056 visibilityCls,\r
24057 offsetsCls,\r
24058 clipCls\r
24059 ]);\r
24060 me[addOrRemove](displayCls);\r
24061 break;\r
24062 case Element.VISIBILITY:\r
24063 me.removeCls([\r
24064 displayCls,\r
24065 offsetsCls,\r
24066 clipCls\r
24067 ]);\r
24068 me[addOrRemove](visibilityCls);\r
24069 break;\r
24070 case Element.OFFSETS:\r
24071 me.removeCls([\r
24072 visibilityCls,\r
24073 displayCls,\r
24074 clipCls\r
24075 ]);\r
24076 me[addOrRemove](offsetsCls);\r
24077 break;\r
24078 case Element.CLIP:\r
24079 me.removeCls([\r
24080 visibilityCls,\r
24081 displayCls,\r
24082 offsetsCls\r
24083 ]);\r
24084 me[addOrRemove](clipCls);\r
24085 break;\r
24086 }\r
24087 if (me.shadow || me.shim) {\r
24088 me.setUnderlaysVisible(visible);\r
24089 }\r
24090 return me;\r
24091 },\r
24092 \r
24093 setWidth: function(width) {\r
24094 var me = this;\r
24095 me.dom.style[WIDTH] = Element.addUnits(width);\r
24096 if (me.shadow || me.shim) {\r
24097 me.syncUnderlays();\r
24098 }\r
24099 return me;\r
24100 },\r
24101 \r
24102 setX: function(x) {\r
24103 return this.setXY([\r
24104 x,\r
24105 false\r
24106 ]);\r
24107 },\r
24108 \r
24109 setXY: function(xy) {\r
24110 var me = this,\r
24111 pts = me.translatePoints(xy),\r
24112 style = me.dom.style,\r
24113 pos;\r
24114 me.position();\r
24115
24116
24117 style.right = 'auto';\r
24118 for (pos in pts) {\r
24119 if (!isNaN(pts[pos])) {\r
24120 style[pos] = pts[pos] + 'px';\r
24121 }\r
24122 }\r
24123 if (me.shadow || me.shim) {\r
24124 me.syncUnderlays();\r
24125 }\r
24126 return me;\r
24127 },\r
24128 \r
24129 setY: function(y) {\r
24130 return this.setXY([\r
24131 false,\r
24132 y\r
24133 ]);\r
24134 },\r
24135 \r
24136 setZIndex: function(zindex) {\r
24137 var me = this;\r
24138 if (me.shadow) {\r
24139 me.shadow.setZIndex(zindex);\r
24140 }\r
24141 if (me.shim) {\r
24142 me.shim.setZIndex(zindex);\r
24143 }\r
24144 return me.setStyle('z-index', zindex);\r
24145 },\r
24146 \r
24147 show: function() {\r
24148 this.setVisible(true);\r
24149 return this;\r
24150 },\r
24151 \r
24152 swapCls: function(firstClass, secondClass, flag, prefix) {\r
24153 if (flag === undefined) {\r
24154 flag = true;\r
24155 }\r
24156 var me = this,\r
24157 addedClass = flag ? firstClass : secondClass,\r
24158 removedClass = flag ? secondClass : firstClass;\r
24159 if (removedClass) {\r
24160 me.removeCls(prefix ? prefix + '-' + removedClass : removedClass);\r
24161 }\r
24162 if (addedClass) {\r
24163 me.addCls(prefix ? prefix + '-' + addedClass : addedClass);\r
24164 }\r
24165 return me;\r
24166 },\r
24167 \r
24168 synchronize: function() {\r
24169 var me = this,\r
24170 dom = me.dom,\r
24171 hasClassMap = {},\r
24172 className = dom.className,\r
24173 classList, i, ln, name,\r
24174 elementData = me.getData();\r
24175 if (className && className.length > 0) {\r
24176 classList = dom.className.split(classNameSplitRegex);\r
24177 for (i = 0 , ln = classList.length; i < ln; i++) {\r
24178 name = classList[i];\r
24179 hasClassMap[name] = true;\r
24180 }\r
24181 } else {\r
24182 classList = [];\r
24183 }\r
24184 elementData.classList = classList;\r
24185 elementData.classMap = hasClassMap;\r
24186 elementData.isSynchronized = true;\r
24187 return me;\r
24188 },\r
24189 \r
24190 syncUnderlays: function() {\r
24191 var me = this,\r
24192 shadow = me.shadow,\r
24193 shim = me.shim,\r
24194 dom = me.dom,\r
24195 xy, x, y, w, h;\r
24196 if (me.isVisible()) {\r
24197 xy = me.getXY();\r
24198 x = xy[0];\r
24199 y = xy[1];\r
24200 w = dom.offsetWidth;\r
24201 h = dom.offsetHeight;\r
24202 if (shadow && !shadow.hidden) {\r
24203 shadow.realign(x, y, w, h);\r
24204 }\r
24205 if (shim && !shim.hidden) {\r
24206 shim.realign(x, y, w, h);\r
24207 }\r
24208 }\r
24209 },\r
24210 \r
24211 toggleCls: function(className, state) {\r
24212 if (typeof state !== 'boolean') {\r
24213 state = !this.hasCls(className);\r
24214 }\r
24215 return state ? this.addCls(className) : this.removeCls(className);\r
24216 },\r
24217 \r
24218 toggle: function() {\r
24219 this.setVisible(!this.isVisible());\r
24220 return this;\r
24221 },\r
24222 translate: function() {\r
24223 var transformStyleName = 'webkitTransform' in DOC.createElement('div').style ? 'webkitTransform' : 'transform';\r
24224 return function(x, y, z) {\r
24225 this.dom.style[transformStyleName] = 'translate3d(' + (x || 0) + 'px, ' + (y || 0) + 'px, ' + (z || 0) + 'px)';\r
24226 };\r
24227 }(),\r
24228 \r
24229 unmaskIframes: function() {\r
24230 var iframes = document.getElementsByTagName('iframe');\r
24231 Ext.each(iframes, function(iframe) {\r
24232 var iframeParent = Ext.fly(iframe.parentNode);\r
24233 iframeParent.unmask();\r
24234 });\r
24235 },\r
24236 \r
24237 unwrap: function() {\r
24238 var dom = this.dom,\r
24239 parentNode = dom.parentNode,\r
24240 grandparentNode,\r
24241 activeElement = Ext.fly(Ext.Element.getActiveElement()),\r
24242 cached, resumeFocus, grannyFly, tabIndex;\r
24243 cached = Ext.cache[activeElement.id];\r
24244
24245
24246
24247 if (cached) {\r
24248 activeElement = cached;\r
24249 }\r
24250 if (this.contains(activeElement)) {\r
24251 if (cached) {\r
24252 cached.suspendFocusEvents();\r
24253 }\r
24254 resumeFocus = true;\r
24255 }\r
24256 if (parentNode) {\r
24257 grandparentNode = parentNode.parentNode;\r
24258
24259 if (resumeFocus) {\r
24260 tabIndex = grandparentNode.getAttribute('tabIndex');\r
24261 grannyFly = Ext.fly(grandparentNode);\r
24262 grannyFly.set({\r
24263 tabIndex: -1\r
24264 });\r
24265 grannyFly.suspendFocusEvents();\r
24266 grannyFly.focus();\r
24267 }\r
24268 grandparentNode.insertBefore(dom, parentNode);\r
24269 grandparentNode.removeChild(parentNode);\r
24270 } else {\r
24271 grandparentNode = document.createDocumentFragment();\r
24272 grandparentNode.appendChild(dom);\r
24273 }\r
24274 if (resumeFocus) {\r
24275 if (cached) {\r
24276 cached.focus();\r
24277 cached.resumeFocusEvents();\r
24278 } else {\r
24279 Ext.fly(activeElement).focus();\r
24280 }\r
24281 if (grannyFly) {\r
24282 grannyFly.resumeFocusEvents();\r
24283 grannyFly.set({\r
24284 tabIndex: tabIndex\r
24285 });\r
24286 }\r
24287 }\r
24288 return this;\r
24289 },\r
24290 \r
24291 up: function(simpleSelector, limit, returnDom) {\r
24292 return this.findParentNode(simpleSelector, limit, !returnDom);\r
24293 },\r
24294 \r
24295 update: function(html) {\r
24296 return this.setHtml(html);\r
24297 },\r
24298 \r
24299 wrap: function(config, returnDom, selector) {\r
24300 var me = this,\r
24301 dom = me.dom,\r
24302 newEl = Ext.DomHelper.insertBefore(dom, config || {\r
24303 tag: "div"\r
24304 }, !returnDom),\r
24305 target = newEl,\r
24306 activeElement = Ext.Element.getActiveElement(),\r
24307 cached, resumeFocus, tabIndex;\r
24308 cached = Ext.cache[activeElement.id];\r
24309
24310
24311
24312 if (cached) {\r
24313 activeElement = cached;\r
24314 }\r
24315 if (selector) {\r
24316 target = newEl.selectNode(selector, returnDom);\r
24317 }\r
24318 if (me.contains(activeElement)) {\r
24319 if (cached) {\r
24320 cached.suspendFocusEvents();\r
24321 }\r
24322
24323
24324
24325
24326
24327
24328
24329
24330
24331
24332
24333
24334
24335
24336 tabIndex = newEl.dom.getAttribute('tabIndex');\r
24337 newEl.set({\r
24338 tabIndex: -1\r
24339 });\r
24340 newEl.suspendFocusEvents();\r
24341 newEl.focus();\r
24342 resumeFocus = true;\r
24343 }\r
24344 target.appendChild(dom);\r
24345 if (resumeFocus) {\r
24346 if (cached) {\r
24347 cached.focus();\r
24348 cached.resumeFocusEvents();\r
24349 } else {\r
24350 Ext.fly(activeElement).focus();\r
24351 }\r
24352 newEl.resumeFocusEvents();\r
24353
24354
24355 newEl.set({\r
24356 tabIndex: tabIndex\r
24357 });\r
24358 }\r
24359 return newEl;\r
24360 },\r
24361 privates: {\r
24362 doAddListener: function(eventName, fn, scope, options, order, caller, manager) {\r
24363 var me = this,\r
24364 observableDoAddListener, additiveEventName, translatedEventName;\r
24365
24366
24367
24368 eventName = Ext.canonicalEventName(eventName);\r
24369
24370
24371 if (!me.blockedEvents[eventName]) {\r
24372 observableDoAddListener = me.mixins.observable.doAddListener;\r
24373 options = options || {};\r
24374 if (me.longpressEvents[eventName]) {\r
24375 me.disableTouchContextMenu();\r
24376 }\r
24377 if (Element.useDelegatedEvents === false) {\r
24378 options.delegated = options.delegated || false;\r
24379 }\r
24380 if (options.translate !== false) {\r
24381
24382
24383 additiveEventName = me.additiveEvents[eventName];\r
24384 if (additiveEventName) {\r
24385
24386
24387
24388
24389 options.type = eventName;\r
24390 eventName = additiveEventName;\r
24391 observableDoAddListener.call(me, eventName, fn, scope, options, order, caller, manager);\r
24392 }\r
24393 translatedEventName = me.eventMap[eventName];\r
24394 if (translatedEventName) {\r
24395
24396 options.type = options.type || eventName;\r
24397 eventName = translatedEventName;\r
24398 }\r
24399 }\r
24400 observableDoAddListener.call(me, eventName, fn, scope, options, order, caller, manager);\r
24401
24402
24403
24404
24405 delete options.type;\r
24406 }\r
24407 },\r
24408 doRemoveListener: function(eventName, fn, scope) {\r
24409 var me = this,\r
24410 observableDoRemoveListener, translatedEventName, additiveEventName, contextMenuListenerRemover;\r
24411
24412
24413 if (!me.blockedEvents[eventName]) {\r
24414 observableDoRemoveListener = me.mixins.observable.doRemoveListener;\r
24415 if (me.longpressEvents[eventName]) {\r
24416 contextMenuListenerRemover = this._contextMenuListenerRemover;\r
24417 if (contextMenuListenerRemover) {\r
24418 contextMenuListenerRemover.destroy();\r
24419 }\r
24420 }\r
24421
24422
24423 additiveEventName = me.additiveEvents[eventName];\r
24424 if (additiveEventName) {\r
24425
24426
24427
24428
24429 eventName = additiveEventName;\r
24430 observableDoRemoveListener.call(me, eventName, fn, scope);\r
24431 }\r
24432 translatedEventName = me.eventMap[eventName];\r
24433 if (translatedEventName) {\r
24434 observableDoRemoveListener.call(me, translatedEventName, fn, scope);\r
24435 }\r
24436
24437
24438 observableDoRemoveListener.call(me, eventName, fn, scope);\r
24439 }\r
24440 },\r
24441 _initEvent: function(eventName) {\r
24442 return (this.events[eventName] = new Ext.dom.ElementEvent(this, eventName));\r
24443 },\r
24444 _getDisplay: function() {\r
24445 var data = this.getData(),\r
24446 display = data[ORIGINALDISPLAY];\r
24447 if (display === undefined) {\r
24448 data[ORIGINALDISPLAY] = display = '';\r
24449 }\r
24450 return display;\r
24451 },\r
24452 \r
24453 _getPublisher: function(eventName) {\r
24454 var Publisher = Ext.event.publisher.Publisher,\r
24455 publisher = Publisher.publishersByEvent[eventName];\r
24456
24457
24458
24459
24460 if (!publisher || (this.dom === window && eventName === 'resize')) {\r
24461 publisher = Publisher.publishers.dom;\r
24462 }\r
24463 return publisher;\r
24464 },\r
24465 isFocusSuspended: function() {\r
24466 return !!this.getData().suspendFocusEvents;\r
24467 },\r
24468 suspendFocusEvents: function() {\r
24469 if (!this.isFly) {\r
24470 this.suspendEvent('focus', 'blur');\r
24471 }\r
24472 this.getData().suspendFocusEvents = true;\r
24473 },\r
24474 resumeFocusEvents: function() {\r
24475 function resumeFn() {\r
24476 var data;\r
24477 if (!this.destroyed) {\r
24478 data = this.getData();\r
24479 if (data) {\r
24480 data.suspendFocusEvents = false;\r
24481 }\r
24482 if (!this.isFly) {\r
24483 this.resumeEvent('focus', 'blur');\r
24484 }\r
24485 }\r
24486 }\r
24487 if (!this.destroyed && this.getData().suspendFocusEvents) {\r
24488 if (Ext.isIE) {\r
24489 Ext.asap(resumeFn, this);\r
24490 } else {\r
24491 resumeFn.call(this);\r
24492 }\r
24493 }\r
24494 }\r
24495 },\r
24496 deprecated: {\r
24497 '5.0': {\r
24498 methods: {\r
24499 \r
24500 cssTranslate: null,\r
24501 \r
24502 getHTML: 'getHtml',\r
24503 \r
24504 getOuterHeight: null,\r
24505 \r
24506 getOuterWidth: null,\r
24507 \r
24508 getPageBox: function(getRegion) {\r
24509 var me = this,\r
24510 dom = me.dom,\r
24511 isDoc = dom.nodeName === 'BODY',\r
24512 w = isDoc ? Element.getViewportWidth() : dom.offsetWidth,\r
24513 h = isDoc ? Element.getViewportHeight() : dom.offsetHeight,\r
24514 xy = me.getXY(),\r
24515 t = xy[1],\r
24516 r = xy[0] + w,\r
24517 b = xy[1] + h,\r
24518 l = xy[0];\r
24519 if (getRegion) {\r
24520 return new Ext.util.Region(t, r, b, l);\r
24521 } else {\r
24522 return {\r
24523 left: l,\r
24524 top: t,\r
24525 width: w,\r
24526 height: h,\r
24527 right: r,\r
24528 bottom: b\r
24529 };\r
24530 }\r
24531 },\r
24532 \r
24533 getScrollParent: null,\r
24534 \r
24535 isDescendent: null,\r
24536 \r
24537 isTransparent: function(prop) {\r
24538 var value = this.getStyle(prop);\r
24539 return value ? transparentRe.test(value) : false;\r
24540 },\r
24541 \r
24542 purgeAllListeners: 'clearListeners',\r
24543 \r
24544 removeAllListeners: 'clearListeners',\r
24545 \r
24546 setHTML: 'setHtml',\r
24547 \r
24548 setTopLeft: null\r
24549 }\r
24550 }\r
24551 }\r
24552 };\r
24553}, function(Element) {\r
24554 var DOC = document,\r
24555 prototype = Element.prototype,\r
24556 supports = Ext.supports,\r
24557 pointerdown = 'pointerdown',\r
24558 pointermove = 'pointermove',\r
24559 pointerup = 'pointerup',\r
24560 pointercancel = 'pointercancel',\r
24561 MSPointerDown = 'MSPointerDown',\r
24562 MSPointerMove = 'MSPointerMove',\r
24563 MSPointerUp = 'MSPointerUp',\r
24564 MSPointerCancel = 'MSPointerCancel',\r
24565 mousedown = 'mousedown',\r
24566 mousemove = 'mousemove',\r
24567 mouseup = 'mouseup',\r
24568 mouseover = 'mouseover',\r
24569 mouseout = 'mouseout',\r
24570 mouseenter = 'mouseenter',\r
24571 mouseleave = 'mouseleave',\r
24572 touchstart = 'touchstart',\r
24573 touchmove = 'touchmove',\r
24574 touchend = 'touchend',\r
24575 touchcancel = 'touchcancel',\r
24576 click = 'click',\r
24577 dblclick = 'dblclick',\r
24578 tap = 'tap',\r
24579 doubletap = 'doubletap',\r
24580 eventMap = prototype.eventMap = {},\r
24581 additiveEvents = prototype.additiveEvents = {},\r
24582 oldId = Ext.id,\r
24583 eventOptions;\r
24584 \r
24585 Ext.id = function(obj, prefix) {\r
24586 var el = Ext.getDom(obj, true),\r
24587 sandboxPrefix, id;\r
24588 if (!el) {\r
24589 id = oldId(obj, prefix);\r
24590 } else if (!(id = el.id)) {\r
24591 id = oldId(null, prefix || Element.prototype.identifiablePrefix);\r
24592 if (Ext.isSandboxed) {\r
24593 sandboxPrefix = Ext.sandboxPrefix || (Ext.sandboxPrefix = Ext.sandboxName.toLowerCase() + '-');\r
24594 id = sandboxPrefix + id;\r
24595 }\r
24596 el.id = id;\r
24597 }\r
24598 return id;\r
24599 };\r
24600 if (supports.PointerEvents) {\r
24601 eventMap[mousedown] = pointerdown;\r
24602 eventMap[mousemove] = pointermove;\r
24603 eventMap[mouseup] = pointerup;\r
24604 eventMap[touchstart] = pointerdown;\r
24605 eventMap[touchmove] = pointermove;\r
24606 eventMap[touchend] = pointerup;\r
24607 eventMap[touchcancel] = pointercancel;\r
24608 eventMap[click] = tap;\r
24609 eventMap[dblclick] = doubletap;\r
24610
24611
24612
24613
24614
24615
24616
24617
24618
24619 eventMap[mouseover] = 'pointerover';\r
24620 eventMap[mouseout] = 'pointerout';\r
24621 eventMap[mouseenter] = 'pointerenter';\r
24622 eventMap[mouseleave] = 'pointerleave';\r
24623 } else if (supports.MSPointerEvents) {\r
24624
24625 eventMap[pointerdown] = MSPointerDown;\r
24626 eventMap[pointermove] = MSPointerMove;\r
24627 eventMap[pointerup] = MSPointerUp;\r
24628 eventMap[pointercancel] = MSPointerCancel;\r
24629 eventMap[mousedown] = MSPointerDown;\r
24630 eventMap[mousemove] = MSPointerMove;\r
24631 eventMap[mouseup] = MSPointerUp;\r
24632 eventMap[touchstart] = MSPointerDown;\r
24633 eventMap[touchmove] = MSPointerMove;\r
24634 eventMap[touchend] = MSPointerUp;\r
24635 eventMap[touchcancel] = MSPointerCancel;\r
24636 eventMap[click] = tap;\r
24637 eventMap[dblclick] = doubletap;\r
24638
24639
24640 eventMap[mouseover] = 'MSPointerOver';\r
24641 eventMap[mouseout] = 'MSPointerOut';\r
24642 } else if (supports.TouchEvents) {\r
24643 eventMap[pointerdown] = touchstart;\r
24644 eventMap[pointermove] = touchmove;\r
24645 eventMap[pointerup] = touchend;\r
24646 eventMap[pointercancel] = touchcancel;\r
24647 eventMap[mousedown] = touchstart;\r
24648 eventMap[mousemove] = touchmove;\r
24649 eventMap[mouseup] = touchend;\r
24650 eventMap[click] = tap;\r
24651 eventMap[dblclick] = doubletap;\r
24652 if (Ext.isWebKit && Ext.os.is.Desktop) {\r
24653
24654
24655
24656
24657
24658
24659
24660
24661
24662
24663
24664 eventMap[touchstart] = mousedown;\r
24665 eventMap[touchmove] = mousemove;\r
24666 eventMap[touchend] = mouseup;\r
24667 eventMap[touchcancel] = mouseup;\r
24668 additiveEvents[mousedown] = mousedown;\r
24669 additiveEvents[mousemove] = mousemove;\r
24670 additiveEvents[mouseup] = mouseup;\r
24671 additiveEvents[touchstart] = touchstart;\r
24672 additiveEvents[touchmove] = touchmove;\r
24673 additiveEvents[touchend] = touchend;\r
24674 additiveEvents[touchcancel] = touchcancel;\r
24675 additiveEvents[pointerdown] = mousedown;\r
24676 additiveEvents[pointermove] = mousemove;\r
24677 additiveEvents[pointerup] = mouseup;\r
24678 additiveEvents[pointercancel] = mouseup;\r
24679 }\r
24680 } else {\r
24681
24682
24683 eventMap[pointerdown] = mousedown;\r
24684 eventMap[pointermove] = mousemove;\r
24685 eventMap[pointerup] = mouseup;\r
24686 eventMap[pointercancel] = mouseup;\r
24687 eventMap[touchstart] = mousedown;\r
24688 eventMap[touchmove] = mousemove;\r
24689 eventMap[touchend] = mouseup;\r
24690 eventMap[touchcancel] = mouseup;\r
24691 }\r
24692 if (Ext.isWebKit) {\r
24693
24694
24695 eventMap.transitionend = Ext.browser.getVendorProperyName('transitionEnd');\r
24696 eventMap.animationstart = Ext.browser.getVendorProperyName('animationStart');\r
24697 eventMap.animationend = Ext.browser.getVendorProperyName('animationEnd');\r
24698 }\r
24699 if (!Ext.supports.MouseWheel && !Ext.isOpera) {\r
24700 eventMap.mousewheel = 'DOMMouseScroll';\r
24701 }\r
24702 eventOptions = prototype.$eventOptions = Ext.Object.chain(prototype.$eventOptions);\r
24703 eventOptions.translate = eventOptions.capture = eventOptions.delegate = eventOptions.delegated = eventOptions.stopEvent = eventOptions.preventDefault = eventOptions.stopPropagation =
24704
24705
24706
24707
24708 eventOptions.element = 1;\r
24709 prototype.styleHooks.opacity = {\r
24710 name: 'opacity',\r
24711 afterSet: function(dom, value, el) {\r
24712 var shadow = el.shadow;\r
24713 if (shadow) {\r
24714 shadow.setOpacity(value);\r
24715 }\r
24716 }\r
24717 };\r
24718 \r
24719 prototype.getTrueXY = prototype.getXY;\r
24720 \r
24721 Ext.select = Element.select;\r
24722 \r
24723 Ext.query = Element.query;\r
24724 Ext.apply(Ext, {\r
24725 \r
24726 get: function(element) {\r
24727 return Element.get(element);\r
24728 },\r
24729 \r
24730 getDom: function(el) {\r
24731 if (!el || !DOC) {\r
24732 return null;\r
24733 }\r
24734
24735 return typeof el === 'string' ? Ext.getElementById(el) : 'dom' in el ? el.dom : el;\r
24736 },\r
24737 \r
24738 getBody: function() {\r
24739 if (!Ext._bodyEl) {\r
24740 if (!DOC.body) {\r
24741 throw new Error("[Ext.getBody] document.body does not yet exist");\r
24742 }\r
24743 Ext._bodyEl = Ext.get(DOC.body);\r
24744 }\r
24745 return Ext._bodyEl;\r
24746 },\r
24747 \r
24748 getHead: function() {\r
24749 if (!Ext._headEl) {\r
24750 Ext._headEl = Ext.get(DOC.head || DOC.getElementsByTagName('head')[0]);\r
24751 }\r
24752 return Ext._headEl;\r
24753 },\r
24754 \r
24755 getDoc: function() {\r
24756 if (!Ext._docEl) {\r
24757 Ext._docEl = Ext.get(DOC);\r
24758 }\r
24759 return Ext._docEl;\r
24760 },\r
24761 \r
24762 getWin: function() {\r
24763 if (!Ext._winEl) {\r
24764 Ext._winEl = Ext.get(window);\r
24765 }\r
24766 return Ext._winEl;\r
24767 },\r
24768 \r
24769 removeNode: function(node) {\r
24770 node = node.dom || node;\r
24771 var id = node && node.id,\r
24772 el = Ext.cache[id],\r
24773 parent;\r
24774 if (el) {\r
24775 el.destroy();\r
24776 } else if (node && (node.nodeType === 3 || node.tagName.toUpperCase() !== 'BODY')) {\r
24777 parent = node.parentNode;\r
24778 if (parent) {\r
24779 parent.removeChild(node);\r
24780 }\r
24781 }\r
24782 }\r
24783 });\r
24784
24785
24786 Ext.isGarbage = function(dom) {\r
24787
24788
24789 return dom &&
24790 dom.nodeType === 1 && dom.tagName !== 'BODY' && dom.tagName !== 'HTML' &&
24791
24792 (!dom.parentNode ||
24793
24794 (!dom.offsetParent &&
24795
24796
24797
24798
24799
24800
24801 ((Ext.isIE8 ? DOC.all[dom.id] : DOC.getElementById(dom.id)) !== dom) &&
24802
24803 !(Ext.detachedBodyEl && Ext.detachedBodyEl.isAncestor(dom))));\r
24804 };\r
24805 if (Ext.os.is.Android || (Ext.os.is.Windows && Ext.supports.Touch)) {\r
24806 Ext.onReady(function() {\r
24807
24808
24809
24810
24811
24812
24813 var win = Ext.getWin();\r
24814 Element._windowWidth = Element._viewportWidth = window.innerWidth;\r
24815 Element._windowHeight = Element._viewportHeight = window.innerHeight;\r
24816 win.on({\r
24817
24818
24819
24820
24821 focusin: '_onWindowFocusChange',\r
24822 focusout: '_onWindowFocusChange',\r
24823
24824
24825
24826
24827
24828
24829
24830 pointerup: '_onWindowFocusChange',\r
24831 capture: true,\r
24832 delegated: false,\r
24833 delay: 1,\r
24834 scope: Element\r
24835 });\r
24836 win.on({\r
24837
24838 resize: '_onWindowResize',\r
24839 priority: 2000,\r
24840 scope: Element\r
24841 });\r
24842 });\r
24843 }\r
24844});\r
24845\r
24846\r
24847Ext.define('Ext.GlobalEvents', {\r
24848 extend: Ext.mixin.Observable,\r
24849 alternateClassName: 'Ext.globalEvents',\r
24850 observableType: 'global',\r
24851 singleton: true,\r
24852 \r
24853 resizeBuffer: 100,\r
24854 \r
24855 \r
24856 \r
24857 \r
24858 \r
24859 \r
24860 \r
24861 \r
24862 \r
24863 \r
24864 \r
24865 \r
24866 \r
24867 \r
24868 idleEventMask: {\r
24869 mousemove: 1,\r
24870 touchmove: 1,\r
24871 pointermove: 1,\r
24872 MSPointerMove: 1,\r
24873 unload: 1\r
24874 },\r
24875 constructor: function() {\r
24876 var me = this;\r
24877 me.callParent();\r
24878 Ext.onInternalReady(function() {\r
24879
24880
24881 me.attachListeners();\r
24882 });\r
24883 },\r
24884 attachListeners: function() {\r
24885 Ext.get(window).on('resize', this.fireResize, this, {\r
24886 buffer: this.resizeBuffer\r
24887 });\r
24888 Ext.getDoc().on('mousedown', this.fireMouseDown, this);\r
24889 },\r
24890 fireMouseDown: function(e) {\r
24891 this.fireEvent('mousedown', e);\r
24892 },\r
24893 fireResize: function() {\r
24894 var me = this,\r
24895 Element = Ext.Element,\r
24896 w = Element.getViewportWidth(),\r
24897 h = Element.getViewportHeight();\r
24898
24899 if (me.curHeight !== h || me.curWidth !== w) {\r
24900 me.curHeight = h;\r
24901 me.curWidth = w;\r
24902 me.fireEvent('resize', w, h);\r
24903 }\r
24904 }\r
24905}, function(GlobalEvents) {\r
24906 \r
24907 Ext.on = function() {\r
24908 return GlobalEvents.addListener.apply(GlobalEvents, arguments);\r
24909 };\r
24910 \r
24911 Ext.un = function() {\r
24912 return GlobalEvents.removeListener.apply(GlobalEvents, arguments);\r
24913 };\r
24914});\r
24915\r
24916\r
24917Ext.USE_NATIVE_JSON = false;\r
24918\r
24919Ext.JSON = (new (function() {\r
24920
24921
24922
24923 var me = this,\r
24924 hasNative = window.JSON && JSON.toString() === '[object JSON]',\r
24925 useHasOwn = !!{}.hasOwnProperty,\r
24926 pad = function(n) {\r
24927 return n < 10 ? "0" + n : n;\r
24928 },\r
24929 doDecode = function(json) {\r
24930 return eval("(" + json + ')');\r
24931 },\r
24932
24933 doEncode = function(o, newline) {\r
24934
24935 if (o === null || o === undefined) {\r
24936 return "null";\r
24937 } else if (Ext.isDate(o)) {\r
24938 return me.encodeDate(o);\r
24939 } else if (Ext.isString(o)) {\r
24940 if (Ext.isMSDate(o)) {\r
24941 return me.encodeMSDate(o);\r
24942 } else {\r
24943 return me.encodeString(o);\r
24944 }\r
24945 } else if (typeof o === "number") {\r
24946
24947 return isFinite(o) ? String(o) : "null";\r
24948 } else if (Ext.isBoolean(o)) {\r
24949 return String(o);\r
24950 }\r
24951
24952
24953 else if (o.toJSON) {\r
24954 return o.toJSON();\r
24955 } else if (Ext.isArray(o)) {\r
24956 return encodeArray(o, newline);\r
24957 } else if (Ext.isObject(o)) {\r
24958 return encodeObject(o, newline);\r
24959 } else if (typeof o === "function") {\r
24960 return "null";\r
24961 }\r
24962 return 'undefined';\r
24963 },\r
24964 m = {\r
24965 "\b": '\\b',\r
24966 "\t": '\\t',\r
24967 "\n": '\\n',\r
24968 "\f": '\\f',\r
24969 "\r": '\\r',\r
24970 '"': '\\"',\r
24971 "\\": '\\\\',\r
24972 '\v': '\\u000b'\r
24973 },\r
24974
24975 charToReplace = /[\\\"\x00-\x1f\x7f-\uffff]/g,\r
24976 encodeString = function(s) {\r
24977 return '"' + s.replace(charToReplace, function(a) {\r
24978 var c = m[a];\r
24979 return typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\r
24980 }) + '"';\r
24981 },\r
24982 encodeMSDate = function(o) {\r
24983 return '"' + o + '"';\r
24984 },\r
24985 encodeArrayPretty = function(o, newline) {\r
24986 var len = o.length,\r
24987 cnewline = newline + ' ',\r
24988 sep = ',' + cnewline,\r
24989 a = [\r
24990 "[",\r
24991 cnewline\r
24992 ],\r
24993
24994 i;\r
24995 for (i = 0; i < len; i += 1) {\r
24996 a.push(me.encodeValue(o[i], cnewline), sep);\r
24997 }\r
24998
24999 a[a.length - 1] = newline + ']';\r
25000 return a.join('');\r
25001 },\r
25002 encodeObjectPretty = function(o, newline) {\r
25003 var cnewline = newline + ' ',\r
25004 sep = ',' + cnewline,\r
25005 a = [\r
25006 "{",\r
25007 cnewline\r
25008 ],\r
25009
25010 i, val;\r
25011 for (i in o) {\r
25012 val = o[i];\r
25013 if (!useHasOwn || o.hasOwnProperty(i)) {\r
25014
25015 if (typeof val === 'function' || val === undefined) {\r
25016 \r
25017 continue;\r
25018 }\r
25019 a.push(me.encodeValue(i) + ': ' + me.encodeValue(val, cnewline), sep);\r
25020 }\r
25021 }\r
25022
25023 a[a.length - 1] = newline + '}';\r
25024 return a.join('');\r
25025 },\r
25026 encodeArray = function(o, newline) {\r
25027 if (newline) {\r
25028 return encodeArrayPretty(o, newline);\r
25029 }\r
25030 var a = [\r
25031 "[",\r
25032 ""\r
25033 ],\r
25034
25035 len = o.length,\r
25036 i;\r
25037 for (i = 0; i < len; i += 1) {\r
25038 a.push(me.encodeValue(o[i]), ',');\r
25039 }\r
25040
25041 a[a.length - 1] = ']';\r
25042 return a.join("");\r
25043 },\r
25044 encodeObject = function(o, newline) {\r
25045 if (newline) {\r
25046 return encodeObjectPretty(o, newline);\r
25047 }\r
25048 var a = [\r
25049 "{",\r
25050 ""\r
25051 ],\r
25052
25053 i, val;\r
25054 for (i in o) {\r
25055 val = o[i];\r
25056 if (!useHasOwn || o.hasOwnProperty(i)) {\r
25057
25058 if (typeof val === 'function' || val === undefined) {\r
25059 \r
25060 continue;\r
25061 }\r
25062 a.push(me.encodeValue(i), ":", me.encodeValue(val), ',');\r
25063 }\r
25064 }\r
25065
25066 a[a.length - 1] = '}';\r
25067 return a.join("");\r
25068 };\r
25069 \r
25070 me.encodeString = encodeString;\r
25071 \r
25072 me.encodeValue = doEncode;\r
25073 \r
25074 me.encodeDate = function(o) {\r
25075 return '"' + o.getFullYear() + "-" + pad(o.getMonth() + 1) + "-" + pad(o.getDate()) + "T" + pad(o.getHours()) + ":" + pad(o.getMinutes()) + ":" + pad(o.getSeconds()) + '"';\r
25076 };\r
25077 \r
25078 me.encode = function(o) {\r
25079
25080 if (hasNative && Ext.USE_NATIVE_JSON) {\r
25081 return JSON.stringify(o);\r
25082 }\r
25083 return me.encodeValue(o);\r
25084 };\r
25085 \r
25086 me.decode = function(json, safe) {\r
25087 try {\r
25088
25089 if (hasNative && Ext.USE_NATIVE_JSON) {\r
25090 return JSON.parse(json);\r
25091 }\r
25092 return doDecode(json);\r
25093 } catch (e) {\r
25094 if (safe) {\r
25095 return null;\r
25096 }\r
25097 Ext.raise({\r
25098 sourceClass: "Ext.JSON",\r
25099 sourceMethod: "decode",\r
25100 msg: "You're trying to decode an invalid JSON String: " + json\r
25101 });\r
25102 }\r
25103 };\r
25104 me.encodeMSDate = encodeMSDate;\r
25105
25106 if (!Ext.util) {\r
25107 Ext.util = {};\r
25108 }\r
25109 Ext.util.JSON = me;\r
25110 \r
25111 Ext.encode = me.encode;\r
25112 \r
25113 Ext.decode = me.decode;\r
25114})());\r
25115\r
25116\r
25117Ext.define('Ext.mixin.Inheritable', {\r
25118 extend: Ext.Mixin,\r
25119 mixinConfig: {\r
25120 id: 'inheritable'\r
25121 },\r
25122 \r
25123 getInherited: function(inner) {\r
25124 var me = this,\r
25125 inheritedState = (inner && me.inheritedStateInner) || me.inheritedState,\r
25126 ownerCt = me.getRefOwner(),\r
25127 isContainer = me.isContainer,\r
25128 parent, inheritedStateInner, getInner, ownerLayout;\r
25129 if (!inheritedState || inheritedState.invalid) {\r
25130
25131
25132
25133
25134 parent = me.getRefOwner();\r
25135 ownerLayout = me.ownerLayout;\r
25136 if (ownerCt) {\r
25137
25138
25139
25140
25141
25142 getInner = ownerLayout ? ownerLayout === ownerCt.layout : true;\r
25143 }\r
25144 me.inheritedState = inheritedState =
25145
25146
25147
25148
25149 Ext.Object.chain(parent ? parent.getInherited(getInner) : Ext.rootInheritedState);\r
25150 if (isContainer) {\r
25151 me.inheritedStateInner = inheritedStateInner = Ext.Object.chain(inheritedState);\r
25152 }\r
25153 me.initInheritedState(inheritedState, inheritedStateInner);\r
25154
25155
25156 inheritedState = (isContainer && inner) ? me.inheritedStateInner : me.inheritedState;\r
25157 }\r
25158 return inheritedState;\r
25159 },\r
25160 \r
25161 getInheritedConfig: function(property, skipThis) {\r
25162 var state = this.inheritedState,\r
25163 old, ret;\r
25164
25165 if (!state || state.invalid) {\r
25166 state = this.getInherited();\r
25167 }\r
25168 ret = state[property];\r
25169 if (skipThis && state.hasOwnProperty(property)) {\r
25170 old = ret;\r
25171 delete state[property];\r
25172 ret = state[property];\r
25173 state[property] = old;\r
25174 }\r
25175 return ret;\r
25176 },\r
25177 \r
25178 resolveListenerScope: function(defaultScope, \r
25179 skipThis) {\r
25180 var me = this,\r
25181 hasSkipThis = (typeof skipThis === 'boolean'),\r
25182 namedScope = Ext._namedScopes[defaultScope],\r
25183 ret;\r
25184 if (!namedScope) {\r
25185
25186
25187
25188
25189 ret = me.getInheritedConfig('defaultListenerScope', hasSkipThis ? skipThis : true) || defaultScope || me;\r
25190 } else if (namedScope.isController) {\r
25191
25192
25193
25194
25195 ret = me.getInheritedConfig('controller', hasSkipThis ? skipThis : !namedScope.isSelf);\r
25196 } else if (namedScope.isSelf) {\r
25197
25198
25199 ret = me.getInheritedConfig('defaultListenerScope', hasSkipThis && skipThis) || me;\r
25200 } else if (namedScope.isThis) {\r
25201
25202
25203 ret = me;\r
25204 }\r
25205 return ret || null;\r
25206 },\r
25207 \r
25208 resolveSatelliteListenerScope: function(satellite, defaultScope) {\r
25209 var me = this,\r
25210 namedScope = Ext._namedScopes[defaultScope],\r
25211 ret;\r
25212
25213
25214
25215
25216
25217
25218
25219 if (!namedScope) {\r
25220 ret = me.getInheritedConfig('defaultListenerScope') || defaultScope || me;\r
25221 } else if (namedScope.isController) {\r
25222 ret = me.getInheritedConfig('controller');\r
25223 } else if (namedScope.isSelf) {\r
25224 ret = me.getInheritedConfig('defaultListenerScope') || satellite;\r
25225 } else if (namedScope.isThis) {\r
25226 ret = satellite;\r
25227 }\r
25228 return ret || null;\r
25229 },\r
25230 \r
25231 lookupReferenceHolder: function(skipThis) {\r
25232 return this.getInheritedConfig('referenceHolder', skipThis !== false) || null;\r
25233 },\r
25234 \r
25235 getRefOwner: function() {\r
25236 var me = this;\r
25237
25238
25239 return me.ownerCt || me.parent || me.$initParent || me.ownerCmp || me.floatParent;\r
25240 },\r
25241 \r
25242 \r
25243 invalidateInheritedState: function() {\r
25244 var inheritedState = this.inheritedState;\r
25245 if (inheritedState) {\r
25246
25247
25248
25249 inheritedState.invalid = true;\r
25250
25251
25252
25253
25254
25255 delete this.inheritedState;\r
25256 }\r
25257 },\r
25258 privates: {\r
25259 \r
25260 fixReference: function() {\r
25261 var me = this,\r
25262 refHolder;\r
25263 if (me.getReference()) {\r
25264 refHolder = me.lookupReferenceHolder();\r
25265 if (refHolder) {\r
25266 refHolder.attachReference(me);\r
25267 }\r
25268 }\r
25269 },\r
25270 \r
25271 onInheritedAdd: function(parent, instanced) {\r
25272 var me = this;\r
25273
25274
25275
25276 if (me.inheritedState && instanced) {\r
25277 me.invalidateInheritedState();\r
25278 }\r
25279 if (me.getReference()) {\r
25280 Ext.ComponentManager.markReferencesDirty();\r
25281 }\r
25282 },\r
25283 \r
25284 onInheritedRemove: function(destroying) {\r
25285 var me = this,\r
25286 refHolder;\r
25287 if (me.getReference()) {\r
25288 refHolder = me.lookupReferenceHolder();\r
25289 if (refHolder) {\r
25290 refHolder.clearReference(me);\r
25291 }\r
25292 }\r
25293 if (me.inheritedState && !destroying) {\r
25294 me.invalidateInheritedState();\r
25295 }\r
25296 }\r
25297 }\r
25298}, function() {\r
25299 \r
25300 Ext.rootInheritedState = {};\r
25301});\r
25302\r
25303\r
25304Ext.define('Ext.mixin.Bindable', {\r
25305 mixinId: 'bindable',\r
25306 config: {\r
25307 \r
25308 bind: {\r
25309 $value: null,\r
25310 lazy: true\r
25311 },\r
25312
25313 \r
25314 controller: null,\r
25315 \r
25316 \r
25317 defaultListenerScope: false,\r
25318 \r
25319 publishes: {\r
25320 $value: null,\r
25321 lazy: true,\r
25322 merge: function(newValue, oldValue) {\r
25323 return this.mergeSets(newValue, oldValue);\r
25324 }\r
25325 },\r
25326 \r
25327 reference: null,\r
25328
25329 \r
25330 session: {\r
25331 $value: null,\r
25332 lazy: true\r
25333 },\r
25334 \r
25335 twoWayBindable: {\r
25336 $value: null,\r
25337 lazy: true,\r
25338 merge: function(newValue, oldValue) {\r
25339 return this.mergeSets(newValue, oldValue);\r
25340 }\r
25341 },\r
25342
25343 \r
25344 viewModel: {\r
25345 $value: null,\r
25346 lazy: true\r
25347 }\r
25348 },\r
25349 \r
25350 defaultBindProperty: null,\r
25351 \r
25352 validRefRe: /^[a-z_][a-z0-9_]*$/i,\r
25353 \r
25354 initInheritedState: function(inheritedState) {\r
25355 var me = this,\r
25356 reference = me.getReference(),\r
25357 controller = me.getController(),\r
25358
25359
25360 viewModel = me.getConfig('viewModel', true),\r
25361 session = me.getConfig('session', true),\r
25362 defaultListenerScope = me.getDefaultListenerScope();\r
25363 if (controller) {\r
25364 inheritedState.controller = controller;\r
25365 }\r
25366 if (defaultListenerScope) {\r
25367 inheritedState.defaultListenerScope = me;\r
25368 } else if (controller) {\r
25369 inheritedState.defaultListenerScope = controller;\r
25370 }\r
25371 if (viewModel) {\r
25372
25373
25374
25375
25376 if (!viewModel.isViewModel) {\r
25377 viewModel = me;\r
25378 }\r
25379 inheritedState.viewModel = viewModel;\r
25380 }\r
25381
25382 if (session) {\r
25383 if (!session.isSession) {\r
25384 session = me;\r
25385 }\r
25386 inheritedState.session = session;\r
25387 }\r
25388 if (reference) {\r
25389 me.referenceKey = (inheritedState.referencePath || '') + reference;\r
25390 me.viewModelKey = (inheritedState.viewModelPath || '') + reference;\r
25391 }\r
25392 },\r
25393 \r
25394 lookupController: function(skipThis) {\r
25395 return this.getInheritedConfig('controller', skipThis) || null;\r
25396 },\r
25397 \r
25398 lookupSession: function(skipThis) {\r
25399
25400 var ret = skipThis ? null : this.getSession();\r
25401
25402 if (!ret) {\r
25403 ret = this.getInheritedConfig('session', skipThis);\r
25404 if (ret && !ret.isSession) {\r
25405 ret = ret.getInherited().session = ret.getSession();\r
25406 }\r
25407 }\r
25408 return ret || null;\r
25409 },\r
25410 \r
25411 lookupViewModel: function(skipThis) {\r
25412 var ret = skipThis ? null : this.getViewModel();\r
25413
25414 if (!ret) {\r
25415 ret = this.getInheritedConfig('viewModel', skipThis);\r
25416
25417
25418
25419 if (ret && !ret.isViewModel) {\r
25420 ret = ret.getInherited().viewModel = ret.getViewModel();\r
25421 }\r
25422 }\r
25423 return ret || null;\r
25424 },\r
25425 \r
25426 publishState: function(property, value) {\r
25427 var me = this,\r
25428 state = me.publishedState,\r
25429 binds = me.getBind(),\r
25430 binding = binds && property && binds[property],\r
25431 count = 0,\r
25432 name, publishes, vm, path;\r
25433 if (binding && !binding.syncing && !binding.isReadOnly()) {\r
25434
25435
25436
25437
25438
25439
25440 if (!(binding.calls === 0 && (value == null || value === me.getInitialConfig()[property]))) {\r
25441 binding.setValue(value);\r
25442 }\r
25443 }\r
25444 if (!(publishes = me.getPublishes())) {\r
25445 return;\r
25446 }\r
25447 if (!(vm = me.lookupViewModel())) {\r
25448 return;\r
25449 }\r
25450
25451
25452 if (!(path = me.viewModelKey)) {\r
25453 return;\r
25454 }\r
25455 if (property && state) {\r
25456 if (!publishes[property]) {\r
25457 return;\r
25458 }\r
25459
25460
25461 if (!(value && value.constructor === Object) && !(value instanceof Array)) {\r
25462 if (state[property] === value) {\r
25463 return;\r
25464 }\r
25465 }\r
25466 path += '.';\r
25467 path += property;\r
25468 } else {\r
25469 state = state || (me.publishedState = {});\r
25470 for (name in publishes) {\r
25471 ++count;\r
25472
25473
25474 if (name === property) {\r
25475 state[name] = value;\r
25476 } else {\r
25477 state[name] = me[name];\r
25478 }\r
25479 }\r
25480 if (!count) {\r
25481
25482 return;\r
25483 }\r
25484 value = state;\r
25485 }\r
25486 vm.set(path, value);\r
25487 },\r
25488
25489 privates: {\r
25490 \r
25491 addBindableUpdater: function(property) {\r
25492 var me = this,\r
25493 configs = me.self.$config.configs,\r
25494 cfg = configs[property],\r
25495 updateName;\r
25496
25497
25498 if (cfg && !me.hasOwnProperty(updateName = cfg.names.update)) {\r
25499 me[updateName] = cfg.bindableUpdater || (cfg.root.bindableUpdater = me.makeBindableUpdater(cfg));\r
25500 }\r
25501 },\r
25502 \r
25503 applyBind: function(binds, currentBindings) {\r
25504 if (!binds) {\r
25505 return binds;\r
25506 }\r
25507 var me = this,\r
25508 viewModel = me.lookupViewModel(),\r
25509 twoWayable = me.getTwoWayBindable(),\r
25510 getBindTemplateScope = me._getBindTemplateScope,\r
25511 b, property, descriptor;\r
25512 if (!currentBindings || typeof currentBindings === 'string') {\r
25513 currentBindings = {};\r
25514 }\r
25515
25516 if (!viewModel) {\r
25517 Ext.raise('Cannot use bind config without a viewModel');\r
25518 }\r
25519
25520 if (Ext.isString(binds)) {\r
25521
25522 if (!me.defaultBindProperty) {\r
25523 Ext.raise(me.$className + ' has no defaultBindProperty - ' + 'Please specify a bind object');\r
25524 }\r
25525
25526 b = binds;\r
25527 binds = {};\r
25528 binds[me.defaultBindProperty] = b;\r
25529 }\r
25530 for (property in binds) {\r
25531 descriptor = binds[property];\r
25532 b = currentBindings[property];\r
25533 if (b && typeof b !== 'string') {\r
25534 b.destroy();\r
25535 b = null;\r
25536 }\r
25537 if (descriptor) {\r
25538 b = viewModel.bind(descriptor, me.onBindNotify, me);\r
25539 b._config = Ext.Config.get(property);\r
25540 b.getTemplateScope = getBindTemplateScope;\r
25541
25542 if (!me[b._config.names.set]) {\r
25543 Ext.raise('Cannot bind ' + property + ' on ' + me.$className + ' - missing a ' + b._config.names.set + ' method.');\r
25544 }\r
25545 }\r
25546
25547 currentBindings[property] = b;\r
25548 if (twoWayable && twoWayable[property] && !b.isReadOnly()) {\r
25549 me.addBindableUpdater(property);\r
25550 }\r
25551 }\r
25552 return currentBindings;\r
25553 },\r
25554 applyController: function(controller) {\r
25555 if (controller) {\r
25556 controller = Ext.Factory.controller(controller);\r
25557 controller.setView(this);\r
25558 }\r
25559 return controller;\r
25560 },\r
25561 applyPublishes: function(all) {\r
25562 if (this.lookupViewModel()) {\r
25563 for (var property in all) {\r
25564 this.addBindableUpdater(property);\r
25565 }\r
25566 }\r
25567 return all;\r
25568 },\r
25569
25570 applyReference: function(reference) {\r
25571 var validIdRe = this.validRefRe || Ext.validIdRe;\r
25572 if (reference && !validIdRe.test(reference)) {\r
25573 Ext.raise('Invalid reference "' + reference + '" for ' + this.getId() + ' - not a valid identifier');\r
25574 }\r
25575 return reference;\r
25576 },\r
25577
25578 \r
25579 applySession: function(session) {\r
25580 if (!session) {\r
25581 return null;\r
25582 }\r
25583 if (!session.isSession) {\r
25584 var parentSession = this.lookupSession(true),\r
25585
25586 config = (session === true) ? {} : session;\r
25587 if (parentSession) {\r
25588 session = parentSession.spawn(config);\r
25589 } else {\r
25590
25591
25592 session = new Ext.data['Session'](config);\r
25593 }\r
25594 }\r
25595 return session;\r
25596 },\r
25597 \r
25598 applyViewModel: function(viewModel) {\r
25599 var me = this,\r
25600 config, session;\r
25601 if (!viewModel) {\r
25602 return null;\r
25603 }\r
25604 if (!viewModel.isViewModel) {\r
25605 config = {\r
25606 parent: me.lookupViewModel(true)\r
25607 };\r
25608
25609 config.session = me.getSession();\r
25610 if (!session && !config.parent) {\r
25611 config.session = me.lookupSession();\r
25612 }\r
25613 if (viewModel) {\r
25614 if (viewModel.constructor === Object) {\r
25615 Ext.apply(config, viewModel);\r
25616 } else if (typeof viewModel === 'string') {\r
25617 config.type = viewModel;\r
25618 }\r
25619 }\r
25620 viewModel = Ext.Factory.viewModel(config);\r
25621 }\r
25622 return viewModel;\r
25623 },\r
25624 _getBindTemplateScope: function() {\r
25625
25626
25627 return this.scope.resolveListenerScope();\r
25628 },\r
25629 destroyBindable: function() {\r
25630 var me = this,\r
25631 viewModel = me.getConfig('viewModel', true),\r
25632 session = me.getConfig('session', true),\r
25633 controller = me.getController();\r
25634 if (viewModel && viewModel.isViewModel) {\r
25635 viewModel.destroy();\r
25636 me.setViewModel(null);\r
25637 }\r
25638 if (session && session.isSession) {\r
25639 if (session.getAutoDestroy()) {\r
25640 session.destroy();\r
25641 }\r
25642 me.setSession(null);\r
25643 }\r
25644 if (controller) {\r
25645 me.setController(null);\r
25646 controller.destroy();\r
25647 }\r
25648 },\r
25649 \r
25650 initBindable: function() {\r
25651 this.initBindable = Ext.emptyFn;\r
25652 this.getBind();\r
25653 this.getPublishes();\r
25654 },\r
25655
25656
25657
25658
25659
25660
25661
25662
25663
25664
25665
25666
25667 \r
25668 makeBindableUpdater: function(cfg) {\r
25669 var updateName = cfg.names.update;\r
25670 return function(newValue, oldValue) {\r
25671 var me = this,\r
25672 updater = me.self.prototype[updateName];\r
25673 if (updater) {\r
25674 updater.call(me, newValue, oldValue);\r
25675 }\r
25676 me.publishState(cfg.name, newValue);\r
25677 };\r
25678 },\r
25679 \r
25680 isSyncing: function(name) {\r
25681 var bindings = this.getBind(),\r
25682 ret = false,\r
25683 binding;\r
25684 if (bindings) {\r
25685 binding = bindings[name];\r
25686 if (binding) {\r
25687 ret = binding.syncing > 0;\r
25688 }\r
25689 }\r
25690 return ret;\r
25691 },\r
25692 onBindNotify: function(value, oldValue, binding) {\r
25693 binding.syncing = (binding.syncing + 1) || 1;\r
25694 this[binding._config.names.set](value);\r
25695 --binding.syncing;\r
25696 },\r
25697 removeBindings: function() {\r
25698 var me = this,\r
25699 bindings, key, binding;\r
25700 if (!me.destroying) {\r
25701 bindings = me.getBind();\r
25702 if (bindings && typeof bindings !== 'string') {\r
25703 for (key in bindings) {\r
25704 binding = bindings[key];\r
25705 binding.destroy();\r
25706 binding._config = binding.getTemplateScope = null;\r
25707 }\r
25708 }\r
25709 }\r
25710 me.setBind(null);\r
25711 },\r
25712 \r
25713 updateSession: function(session) {\r
25714 var state = this.getInherited();\r
25715 if (session) {\r
25716 state.session = session;\r
25717 } else {\r
25718 delete state.session;\r
25719 }\r
25720 },\r
25721 \r
25722 updateViewModel: function(viewModel) {\r
25723 var state = this.getInherited(),\r
25724 controller = this.getController();\r
25725 if (viewModel) {\r
25726 state.viewModel = viewModel;\r
25727 viewModel.setView(this);\r
25728 if (controller) {\r
25729 controller.initViewModel(viewModel);\r
25730 }\r
25731 } else {\r
25732 delete state.viewModel;\r
25733 }\r
25734 }\r
25735 }\r
25736});\r
25737
25738\r
25739\r
25740Ext.define('Ext.mixin.ComponentDelegation', {\r
25741 extend: Ext.Mixin,\r
25742 mixinConfig: {\r
25743 id: 'componentDelegation'\r
25744 },\r
25745 privates: {\r
25746 \r
25747 addDelegatedListener: function(eventName, fn, scope, options, order, caller, manager) {\r
25748 var me = this,\r
25749 delegatedEvents, event, priority;\r
25750
25751
25752
25753
25754 order = order || options.order;\r
25755 if (order) {\r
25756 priority = (options && options.priority);\r
25757 if (!priority) {\r
25758
25759
25760 options = options ? Ext.Object.chain(options) : {};\r
25761 options.priority = me.$orderToPriority[order];\r
25762 }\r
25763 }\r
25764
25765 if (options.target) {\r
25766 Ext.raise("Cannot add '" + eventName + "' listener to component: '" + me.id + "' - 'delegate' and 'target' event options are incompatible.");\r
25767 }\r
25768
25769
25770
25771
25772 delegatedEvents = me.$delegatedEvents || (me.$delegatedEvents = {});\r
25773 event = delegatedEvents[eventName] || (delegatedEvents[eventName] = new Ext.util.Event(me, eventName));\r
25774 if (event.addListener(fn, scope, options, caller, manager)) {\r
25775 me.$hasDelegatedListeners._incr_(eventName);\r
25776 }\r
25777 },\r
25778 \r
25779 clearDelegatedListeners: function() {\r
25780 var me = this,\r
25781 delegatedEvents = me.$delegatedEvents,\r
25782 eventName, event, listenerCount;\r
25783 if (delegatedEvents) {\r
25784 for (eventName in delegatedEvents) {\r
25785 event = delegatedEvents[eventName];\r
25786 listenerCount = event.listeners.length;\r
25787 event.clearListeners();\r
25788 me.$hasDelegatedListeners._decr_(eventName, listenerCount);\r
25789 delete delegatedEvents[eventName];\r
25790 }\r
25791 }\r
25792 },\r
25793 \r
25794 doFireDelegatedEvent: function(eventName, args) {\r
25795 var me = this,\r
25796 ret = true,\r
25797 owner, delegatedEvents, event;\r
25798
25799
25800
25801
25802
25803
25804 if (me.$hasDelegatedListeners[eventName]) {\r
25805 owner = me.getRefOwner();\r
25806 while (owner) {\r
25807 delegatedEvents = owner.$delegatedEvents;\r
25808 if (delegatedEvents) {\r
25809 event = delegatedEvents[eventName];\r
25810 if (event) {\r
25811 ret = event.fireDelegated(me, args);\r
25812 if (ret === false) {\r
25813 break;\r
25814 }\r
25815 }\r
25816 }\r
25817 owner = owner.getRefOwner();\r
25818 }\r
25819 }\r
25820 return ret;\r
25821 },\r
25822 \r
25823 removeDelegatedListener: function(eventName, fn, scope) {\r
25824 var me = this,\r
25825 delegatedEvents = me.$delegatedEvents,\r
25826 event;\r
25827 if (delegatedEvents) {\r
25828 event = delegatedEvents[eventName];\r
25829 if (event && event.removeListener(fn, scope)) {\r
25830 me.$hasDelegatedListeners._decr_(eventName);\r
25831 if (event.listeners.length === 0) {\r
25832 delete delegatedEvents[eventName];\r
25833 }\r
25834 }\r
25835 }\r
25836 }\r
25837 },\r
25838 onClassMixedIn: function(T) {\r
25839
25840
25841
25842
25843
25844
25845
25846
25847 function HasListeners() {}\r
25848 T.prototype.HasListeners = T.HasListeners = HasListeners;\r
25849 HasListeners.prototype = T.hasListeners = new Ext.mixin.ComponentDelegation.HasDelegatedListeners();\r
25850 }\r
25851}, function(ComponentDelegation) {\r
25852
25853
25854
25855
25856
25857
25858
25859
25860
25861
25862
25863
25864
25865
25866
25867
25868
25869
25870 function HasDelegatedListeners() {}\r
25871 ComponentDelegation.HasDelegatedListeners = HasDelegatedListeners;\r
25872 HasDelegatedListeners.prototype = ComponentDelegation.prototype.$hasDelegatedListeners = new Ext.mixin.Observable.HasListeners();\r
25873});\r
25874\r
25875\r
25876Ext.define('Ext.Widget', {\r
25877 extend: Ext.Evented,\r
25878 xtype: 'widget',\r
25879 mixins: [\r
25880 Ext.mixin.Inheritable,\r
25881 Ext.mixin.Bindable,\r
25882 Ext.mixin.ComponentDelegation\r
25883 ],\r
25884 isWidget: true,\r
25885 \r
25886 element: {\r
25887 reference: 'element'\r
25888 },\r
25889 observableType: 'component',\r
25890 cachedConfig: {\r
25891 \r
25892 style: null\r
25893 },\r
25894 config: {\r
25895 \r
25896 userCls: null\r
25897 },\r
25898 eventedConfig: {\r
25899 \r
25900 width: null,\r
25901 \r
25902 height: null\r
25903 },\r
25904 \r
25905 template: [],\r
25906 constructor: function(config) {\r
25907 var me = this,\r
25908 controller;\r
25909 me.initId(config);\r
25910 me.initElement();\r
25911 me.mixins.observable.constructor.call(me, config);\r
25912 Ext.ComponentManager.register(me);\r
25913 controller = me.getController();\r
25914 if (controller) {\r
25915 controller.init(me);\r
25916 }\r
25917 },\r
25918 afterCachedConfig: function() {\r
25919
25920
25921
25922
25923
25924
25925
25926 var me = this,\r
25927 prototype = me.self.prototype,\r
25928 referenceList = me.referenceList,\r
25929 renderElement = me.renderElement,\r
25930 renderTemplate, element, i, ln, reference, elements;\r
25931
25932
25933 prototype.renderTemplate = renderTemplate = document.createDocumentFragment();\r
25934 renderTemplate.appendChild(renderElement.clone(true, true));\r
25935 elements = renderTemplate.querySelectorAll('[id]');\r
25936 for (i = 0 , ln = elements.length; i < ln; i++) {\r
25937 element = elements[i];\r
25938 element.removeAttribute('id');\r
25939 }\r
25940
25941
25942
25943
25944 for (i = 0 , ln = referenceList.length; i < ln; i++) {\r
25945 reference = referenceList[i];\r
25946 me[reference].dom.removeAttribute('reference');\r
25947 }\r
25948 },\r
25949 addCls: function(cls) {\r
25950 this.el.addCls(cls);\r
25951 },\r
25952 applyWidth: function(width) {\r
25953 return this.filterLengthValue(width);\r
25954 },\r
25955 applyHeight: function(height) {\r
25956 return this.filterLengthValue(height);\r
25957 },\r
25958 clearListeners: function() {\r
25959 var me = this;\r
25960 me.mixins.observable.clearListeners.call(me);\r
25961 me.mixins.componentDelegation.clearDelegatedListeners.call(me);\r
25962 },\r
25963 destroy: function() {\r
25964 var me = this,\r
25965 referenceList = me.referenceList,\r
25966 i, ln, reference;\r
25967
25968 for (i = 0 , ln = referenceList.length; i < ln; i++) {\r
25969 reference = referenceList[i];\r
25970 if (me.hasOwnProperty(reference)) {\r
25971 me[reference].destroy();\r
25972 me[reference] = null;\r
25973 }\r
25974 }\r
25975 me.destroyBindable();\r
25976 me.callParent();\r
25977 Ext.ComponentManager.unregister(me);\r
25978 },\r
25979 doFireEvent: function(eventName, args, bubbles) {\r
25980 var me = this,\r
25981 ret = me.mixins.observable.doFireEvent.call(me, eventName, args, bubbles);\r
25982 if (ret !== false) {\r
25983 ret = me.mixins.componentDelegation.doFireDelegatedEvent.call(me, eventName, args);\r
25984 }\r
25985 return ret;\r
25986 },\r
25987 \r
25988 getElementConfig: function() {\r
25989 var me = this,\r
25990 el = me.element;\r
25991 if (!('children' in el)) {\r
25992 el = Ext.apply({\r
25993 children: me.getTemplate()\r
25994 }, el);\r
25995 }\r
25996 return el;\r
25997 },\r
25998 \r
25999 getSize: function() {\r
26000 return {\r
26001 width: this.getWidth(),\r
26002 height: this.getHeight()\r
26003 };\r
26004 },\r
26005 getTemplate: function() {\r
26006 return this.template;\r
26007 },\r
26008 \r
26009 initElement: function() {\r
26010 var me = this,\r
26011 prototype = me.self.prototype,\r
26012 id = me.getId(),\r
26013
26014
26015
26016 referenceList = me.referenceList = me.referenceList = [],\r
26017 cleanAttributes = true,\r
26018 renderTemplate, renderElement, element, referenceNodes, i, ln, referenceNode, reference;\r
26019 if (prototype.hasOwnProperty('renderTemplate')) {\r
26020
26021
26022
26023
26024 renderTemplate = me.renderTemplate.cloneNode(true);\r
26025 renderElement = renderTemplate.firstChild;\r
26026 } else {\r
26027
26028
26029 cleanAttributes = false;\r
26030 renderTemplate = document.createDocumentFragment();\r
26031 renderElement = Ext.Element.create(me.processElementConfig.call(prototype), true);\r
26032 renderTemplate.appendChild(renderElement);\r
26033 }\r
26034 referenceNodes = renderTemplate.querySelectorAll('[reference]');\r
26035 for (i = 0 , ln = referenceNodes.length; i < ln; i++) {\r
26036 referenceNode = referenceNodes[i];\r
26037 reference = referenceNode.getAttribute('reference');\r
26038 if (cleanAttributes) {\r
26039
26040
26041
26042
26043
26044
26045
26046 referenceNode.removeAttribute('reference');\r
26047 }\r
26048 if (reference === 'element') {\r
26049
26050 if (element) {\r
26051
26052 Ext.raise("Duplicate 'element' reference detected in '" + me.$className + "' template.");\r
26053 }\r
26054
26055 referenceNode.id = id;\r
26056
26057
26058 element = me.el = me.addElementReference(reference, referenceNode);\r
26059
26060 element.dom.setAttribute('data-componentid', id);\r
26061 } else {\r
26062 me.addElementReferenceOnDemand(reference, referenceNode);\r
26063 }\r
26064 referenceList.push(reference);\r
26065 }\r
26066
26067 if (!element) {\r
26068 Ext.raise("No 'element' reference found in '" + me.$className + "' template.");\r
26069 }\r
26070
26071 if (renderElement === element.dom) {\r
26072 me.renderElement = element;\r
26073 } else {\r
26074 me.addElementReferenceOnDemand('renderElement', renderElement);\r
26075 }\r
26076 },\r
26077 \r
26078 is: function(selector) {\r
26079 return Ext.ComponentQuery.is(this, selector);\r
26080 },\r
26081 \r
26082 isXType: function(xtype, shallow) {\r
26083 return shallow ? (Ext.Array.indexOf(this.xtypes, xtype) !== -1) : !!this.xtypesMap[xtype];\r
26084 },\r
26085 removeCls: function(cls) {\r
26086 this.el.removeCls(cls);\r
26087 },\r
26088 \r
26089 toggleCls: function(cls, state) {\r
26090 this.element.toggleCls(cls, state);\r
26091 },\r
26092 resolveListenerScope: function(defaultScope, skipThis) {\r
26093
26094 return this.mixins.inheritable.resolveListenerScope.call(this, defaultScope, skipThis);\r
26095 },\r
26096 \r
26097 setSize: function(width, height) {\r
26098 if (width !== undefined) {\r
26099 this.setWidth(width);\r
26100 }\r
26101 if (height !== undefined) {\r
26102 this.setHeight(height);\r
26103 }\r
26104 },\r
26105 \r
26106 applyStyle: function(style, oldStyle) {\r
26107
26108
26109
26110
26111
26112
26113 if (oldStyle && style === oldStyle && Ext.isObject(oldStyle)) {\r
26114 style = Ext.apply({}, style);\r
26115 }\r
26116 return style;\r
26117 },\r
26118 \r
26119 updateStyle: function(style) {\r
26120 this.element.applyStyles(style);\r
26121 },\r
26122 \r
26123 updateWidth: function(width) {\r
26124 this.element.setWidth(width);\r
26125 },\r
26126 \r
26127 updateHeight: function(height) {\r
26128 this.element.setHeight(height);\r
26129 },\r
26130
26131
26132 onFocusEnter: Ext.emptyFn,\r
26133 onFocusLeave: Ext.emptyFn,\r
26134 isAncestor: function() {\r
26135 return false;\r
26136 },\r
26137
26138 privates: {\r
26139 \r
26140 addElementReferenceOnDemand: function(name, domNode) {\r
26141 if (this._elementListeners[name]) {\r
26142
26143
26144
26145 this.addElementReference(name, domNode);\r
26146 } else {\r
26147
26148
26149 Ext.Object.defineProperty(this, name, {\r
26150 get: function() {\r
26151
26152
26153
26154 delete this[name];\r
26155 return this.addElementReference(name, domNode);\r
26156 },\r
26157 configurable: true\r
26158 });\r
26159 }\r
26160 },\r
26161 \r
26162 addElementReference: function(name, domNode) {\r
26163 var me = this,\r
26164 referenceEl = me[name] = Ext.get(domNode),\r
26165 listeners = me._elementListeners[name],\r
26166 eventName, listener;\r
26167 referenceEl.skipGarbageCollection = true;\r
26168 referenceEl.component = me;\r
26169 if (listeners) {\r
26170
26171
26172
26173
26174
26175
26176
26177
26178
26179 listeners = Ext.clone(listeners);\r
26180
26181
26182
26183
26184
26185
26186
26187
26188
26189
26190 for (eventName in listeners) {\r
26191 listener = listeners[eventName];\r
26192 if (typeof listener === 'object') {\r
26193 listener.scope = me;\r
26194 }\r
26195 }\r
26196
26197
26198
26199
26200
26201
26202
26203
26204 listeners.scope = me;\r
26205
26206
26207
26208
26209
26210 referenceEl.on(listeners);\r
26211 }\r
26212 return referenceEl;\r
26213 },\r
26214 detachFromBody: function() {\r
26215
26216 Ext.getDetachedBody().appendChild(this.element);\r
26217 this.isDetached = true;\r
26218 },\r
26219 \r
26220 doAddListener: function(name, fn, scope, options, order, caller, manager) {\r
26221 var me = this,\r
26222 delegate;\r
26223 if (options && 'element' in options) {\r
26224
26225 if (me.referenceList.indexOf(options.element) === -1) {\r
26226 Ext.Logger.error("Adding event listener with an invalid element reference of '" + options.element + "' for this component. Available values are: '" + me.referenceList.join("', '") + "'", me);\r
26227 }\r
26228
26229
26230 me[options.element].doAddListener(name, fn, scope || me, options, order);\r
26231 }\r
26232 if (options) {\r
26233 delegate = options.delegate;\r
26234 if (delegate) {\r
26235 me.mixins.componentDelegation.addDelegatedListener.call(me, name, fn, scope, options, order, caller, manager);\r
26236 return;\r
26237 }\r
26238 }\r
26239 me.callParent([\r
26240 name,\r
26241 fn,\r
26242 scope,\r
26243 options,\r
26244 order,\r
26245 caller,\r
26246 manager\r
26247 ]);\r
26248 },\r
26249 doRemoveListener: function(eventName, fn, scope) {\r
26250 var me = this;\r
26251 me.mixins.observable.doRemoveListener.call(me, eventName, fn, scope);\r
26252 me.mixins.componentDelegation.removeDelegatedListener.call(me, eventName, fn, scope);\r
26253 },\r
26254 filterLengthValue: function(value) {\r
26255 if (value === 'auto' || (!value && value !== 0)) {\r
26256 return null;\r
26257 }\r
26258 return value;\r
26259 },\r
26260 getFocusEl: function() {\r
26261 return this.element;\r
26262 },\r
26263 \r
26264 initElementListeners: function(elementConfig) {\r
26265 var prototype = this,\r
26266 superPrototype = prototype.self.superclass,\r
26267 superElementListeners = superPrototype._elementListeners,\r
26268 reference = elementConfig.reference,\r
26269 children = elementConfig.children,\r
26270 elementListeners, listeners, superListeners, ln, i;\r
26271 if (prototype.hasOwnProperty('_elementListeners')) {\r
26272 elementListeners = prototype._elementListeners;\r
26273 } else {\r
26274 elementListeners = prototype._elementListeners = (superElementListeners ? Ext.Object.chain(superElementListeners) : {});\r
26275 }\r
26276 if (reference) {\r
26277 listeners = elementConfig.listeners;\r
26278 if (listeners) {\r
26279 if (superElementListeners) {\r
26280 superListeners = superElementListeners[reference];\r
26281 if (superListeners) {\r
26282 listeners = Ext.Object.chain(superListeners);\r
26283 Ext.apply(listeners, elementConfig.listeners);\r
26284 }\r
26285 }\r
26286 elementListeners[reference] = listeners;\r
26287
26288
26289
26290 elementConfig.listeners = null;\r
26291 }\r
26292 }\r
26293 if (children) {\r
26294 for (i = 0 , ln = children.length; i < ln; i++) {\r
26295 prototype.initElementListeners(children[i]);\r
26296 }\r
26297 }\r
26298 },\r
26299 initId: function(config) {\r
26300 var me = this,\r
26301 defaultConfig = me.config,\r
26302 id = (config && config.id) || (defaultConfig && defaultConfig.id);\r
26303 if (id) {\r
26304
26305
26306 me.setId(id);\r
26307 me.id = id;\r
26308 } else {\r
26309
26310 me.getId();\r
26311 }\r
26312 },\r
26313 \r
26314 processElementConfig: function() {\r
26315 var prototype = this,\r
26316 superPrototype = prototype.self.superclass,\r
26317 elementConfig;\r
26318 if (prototype.hasOwnProperty('_elementConfig')) {\r
26319 elementConfig = prototype._elementConfig;\r
26320 } else {\r
26321
26322
26323 elementConfig = prototype._elementConfig = prototype.getElementConfig();\r
26324 if (superPrototype.isWidget) {\r
26325
26326
26327 prototype.processElementConfig.call(superPrototype);\r
26328 }\r
26329
26330
26331
26332
26333 prototype.initElementListeners(elementConfig);\r
26334 }\r
26335 return elementConfig;\r
26336 },\r
26337 reattachToBody: function() {\r
26338
26339 this.isDetached = false;\r
26340 },\r
26341 updateUserCls: function(newCls, oldCls) {\r
26342 this.element.replaceCls(oldCls, newCls);\r
26343 }\r
26344 }\r
26345}, function(Widget) {\r
26346 var prototype = Widget.prototype;\r
26347
26348
26349 (prototype.$elementEventOptions = Ext.Object.chain(Ext.Element.prototype.$eventOptions)).element = 1;\r
26350 (prototype.$eventOptions = Ext.Object.chain(prototype.$eventOptions)).delegate = 1;\r
26351});\r
26352\r
26353\r
26354Ext.define('Ext.mixin.Traversable', {\r
26355 extend: Ext.Mixin,\r
26356 mixinConfig: {\r
26357 id: 'traversable'\r
26358 },\r
26359 setParent: function(parent) {\r
26360 this.parent = parent;\r
26361 return this;\r
26362 },\r
26363 \r
26364 hasParent: function() {\r
26365 return Boolean(this.parent);\r
26366 },\r
26367 \r
26368 getParent: function() {\r
26369 return this.parent;\r
26370 },\r
26371 getAncestors: function() {\r
26372 var ancestors = [],\r
26373 parent = this.getParent();\r
26374 while (parent) {\r
26375 ancestors.push(parent);\r
26376 parent = parent.getParent();\r
26377 }\r
26378 return ancestors;\r
26379 },\r
26380 getAncestorIds: function() {\r
26381 var ancestorIds = [],\r
26382 parent = this.getParent();\r
26383 while (parent) {\r
26384 ancestorIds.push(parent.getId());\r
26385 parent = parent.getParent();\r
26386 }\r
26387 return ancestorIds;\r
26388 }\r
26389});\r
26390\r
26391\r
26392Ext.define('Ext.overrides.Widget', {\r
26393 override: 'Ext.Widget',\r
26394 mixins: [\r
26395 Ext.mixin.Traversable\r
26396 ],\r
26397 config: {\r
26398 \r
26399 flex: {\r
26400 evented: true,\r
26401 $value: null\r
26402 },\r
26403 \r
26404 \r
26405 itemId: undefined\r
26406 },\r
26407 constructor: function(config) {\r
26408 this.callParent([\r
26409 config\r
26410 ]);\r
26411 this.initBindable();\r
26412 },\r
26413 applyFlex: function(flex) {\r
26414 if (flex) {\r
26415 flex = Number(flex);\r
26416 if (isNaN(flex)) {\r
26417 flex = null;\r
26418 }\r
26419 } else {\r
26420 flex = null;\r
26421 }\r
26422 return flex;\r
26423 },\r
26424 applyItemId: function(itemId) {\r
26425 return itemId || this.getId();\r
26426 },\r
26427 render: function(container, insertBeforeElement) {\r
26428 this.renderTo(container, insertBeforeElement);\r
26429 },\r
26430 renderTo: function(container, insertBeforeElement) {\r
26431 var dom = this.renderElement.dom,\r
26432 containerDom = Ext.getDom(container),\r
26433 insertBeforeChildDom;\r
26434 if (Ext.isNumber(insertBeforeChildDom)) {\r
26435 insertBeforeElement = containerDom.childNodes[insertBeforeElement];\r
26436 }\r
26437 insertBeforeChildDom = Ext.getDom(insertBeforeElement);\r
26438 if (containerDom) {\r
26439 if (insertBeforeChildDom) {\r
26440 containerDom.insertBefore(dom, insertBeforeChildDom);\r
26441 } else {\r
26442 containerDom.appendChild(dom);\r
26443 }\r
26444 this.setRendered(Boolean(dom.offsetParent));\r
26445 }\r
26446 },\r
26447 destroy: function() {\r
26448 var me = this,\r
26449 parent = me.getParent();\r
26450 if (parent && parent.remove) {\r
26451 parent.remove(me, false);\r
26452 }\r
26453 me.callParent();\r
26454 },\r
26455 isInnerItem: function() {\r
26456 return true;\r
26457 },\r
26458 isCentered: function() {\r
26459 return false;\r
26460 },\r
26461 isDocked: function() {\r
26462 return Boolean(this.getDocked());\r
26463 },\r
26464 isFloating: function() {\r
26465 return false;\r
26466 },\r
26467 getDocked: function() {\r
26468 return this._docked;\r
26469 },\r
26470 \r
26471 onAdded: function(parent, instanced) {\r
26472 var me = this,\r
26473 inheritedState = me.inheritedState,\r
26474 currentParent = me.parent;\r
26475 if (currentParent && currentParent !== parent) {\r
26476 currentParent.remove(me, false);\r
26477 }\r
26478 me.parent = parent;\r
26479 me.onInheritedAdd(parent, instanced);\r
26480 },\r
26481 onRemoved: function(destroying) {\r
26482 if (!destroying) {\r
26483 this.removeBindings();\r
26484 }\r
26485 this.onInheritedRemove(destroying);\r
26486 this.parent = null;\r
26487 },\r
26488 setLayoutSizeFlags: Ext.emptyFn,\r
26489 \r
26490 setRendered: function(rendered) {\r
26491 var wasRendered = this.rendered;\r
26492 if (rendered !== wasRendered) {\r
26493 this.rendered = rendered;\r
26494 return true;\r
26495 }\r
26496 return false;\r
26497 },\r
26498 updateLayout: function() {\r
26499
26500
26501
26502 var parent = this.getParent(),\r
26503 scrollable;\r
26504 if (parent) {\r
26505 scrollable = parent.getScrollable();\r
26506 if (scrollable) {\r
26507 scrollable.refresh();\r
26508 }\r
26509 }\r
26510 }\r
26511});\r
26512\r
26513\r
26514Ext.define('Ext.ProgressBase', {\r
26515 mixinId: 'progressbase',\r
26516 config: {\r
26517 \r
26518 value: 0,\r
26519 \r
26520 textTpl: null\r
26521 },\r
26522 applyTextTpl: function(textTpl) {\r
26523 if (!textTpl.isTemplate) {\r
26524 textTpl = new Ext.XTemplate(textTpl);\r
26525 }\r
26526 return textTpl;\r
26527 },\r
26528 applyValue: function(value) {\r
26529 return value || 0;\r
26530 }\r
26531});\r
26532\r
26533\r
26534Ext.define('Ext.Progress', {\r
26535 extend: Ext.Widget,\r
26536 xtype: [\r
26537 'progress',\r
26538 'progressbarwidget'\r
26539 ],\r
26540 alternateClassName: 'Ext.ProgressBarWidget',\r
26541 mixins: [\r
26542 Ext.ProgressBase\r
26543 ],\r
26544 config: {\r
26545 \r
26546 text: null,\r
26547 \r
26548 animate: false\r
26549 },\r
26550 cachedConfig: {\r
26551 \r
26552 baseCls: Ext.baseCSSPrefix + 'progress',\r
26553 textCls: Ext.baseCSSPrefix + 'progress-text',\r
26554 cls: null,\r
26555 ui: null\r
26556 },\r
26557 template: [\r
26558 {\r
26559 reference: 'backgroundEl'\r
26560 },\r
26561 {\r
26562 reference: 'barEl',\r
26563 children: [\r
26564 {\r
26565 reference: 'textEl'\r
26566 }\r
26567 ]\r
26568 }\r
26569 ],\r
26570 defaultBindProperty: 'value',\r
26571 updateWidth: function(width, oldWidth) {\r
26572 var me = this;\r
26573 me.callParent([\r
26574 width,\r
26575 oldWidth\r
26576 ]);\r
26577 width -= me.element.getBorderWidth('lr');\r
26578 me.backgroundEl.setWidth(width);\r
26579 me.textEl.setWidth(width);\r
26580 },\r
26581 updateCls: function(cls, oldCls) {\r
26582 var el = this.element;\r
26583 if (oldCls) {\r
26584 el.removeCls(oldCls);\r
26585 }\r
26586 if (cls) {\r
26587 el.addCls(cls);\r
26588 }\r
26589 },\r
26590 updateUi: function(ui, oldUi) {\r
26591 var element = this.element,\r
26592 barEl = this.barEl,\r
26593 baseCls = this.getBaseCls() + '-';\r
26594 if (oldUi) {\r
26595 element.removeCls(baseCls + oldUi);\r
26596 barEl.removeCls(baseCls + 'bar-' + oldUi);\r
26597 }\r
26598 element.addCls(baseCls + ui);\r
26599 barEl.addCls(baseCls + 'bar-' + ui);\r
26600 },\r
26601 updateBaseCls: function(baseCls, oldBaseCls) {\r
26602
26603 if (oldBaseCls) {\r
26604 Ext.raise('You cannot configure baseCls - use a subclass');\r
26605 }\r
26606
26607 this.element.addCls(baseCls);\r
26608 this.barEl.addCls(baseCls + '-bar');\r
26609 },\r
26610 updateTextCls: function(textCls) {\r
26611 this.backgroundEl.addCls(textCls + ' ' + textCls + '-back');\r
26612 this.textEl.addCls(textCls);\r
26613 },\r
26614 updateValue: function(value, oldValue) {\r
26615 var me = this,\r
26616 barEl = me.barEl,\r
26617 textTpl = me.getTextTpl();\r
26618 if (textTpl) {\r
26619 me.setText(textTpl.apply({\r
26620 value: value,\r
26621 percent: Math.round(value * 100)\r
26622 }));\r
26623 }\r
26624 if (me.getAnimate()) {\r
26625 barEl.stopAnimation();\r
26626 barEl.animate(Ext.apply({\r
26627 from: {\r
26628 width: (oldValue * 100) + '%'\r
26629 },\r
26630 to: {\r
26631 width: (value * 100) + '%'\r
26632 }\r
26633 }, me.animate));\r
26634 } else {\r
26635 barEl.setStyle('width', (value * 100) + '%');\r
26636 }\r
26637 },\r
26638 updateText: function(text) {\r
26639 this.backgroundEl.setHtml(text);\r
26640 this.textEl.setHtml(text);\r
26641 }\r
26642});\r
26643\r
26644\r
26645Ext.define('Ext.util.Format', function() {\r
26646 var me;\r
26647
26648 return {\r
26649 singleton: true,\r
26650 \r
26651 defaultDateFormat: 'm/d/Y',\r
26652
26653 \r
26654 thousandSeparator: ',',\r
26655
26656
26657 \r
26658 decimalSeparator: '.',\r
26659
26660
26661 \r
26662 currencyPrecision: 2,\r
26663
26664
26665 \r
26666 currencySign: '$',\r
26667
26668 \r
26669 percentSign: '%',\r
26670
26671 \r
26672 currencyAtEnd: false,\r
26673
26674 stripTagsRe: /<\/?[^>]+>/gi,\r
26675 stripScriptsRe: /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,\r
26676 nl2brRe: /\r?\n/g,\r
26677 hashRe: /#+$/,\r
26678 allHashes: /^#+$/,\r
26679
26680 formatPattern: /[\d,\.#]+/,\r
26681
26682 formatCleanRe: /[^\d\.#]/g,\r
26683
26684
26685 I18NFormatCleanRe: null,\r
26686
26687 formatFns: {},\r
26688 constructor: function() {\r
26689 me = this;\r
26690 },\r
26691
26692 \r
26693 undef: function(value) {\r
26694 return value !== undefined ? value : "";\r
26695 },\r
26696 \r
26697 defaultValue: function(value, defaultValue) {\r
26698 return value !== undefined && value !== '' ? value : defaultValue;\r
26699 },\r
26700 \r
26701 substr: 'ab'.substr(-1) != 'b' ? function(value, start, length) {\r
26702 var str = String(value);\r
26703 return (start < 0) ? str.substr(Math.max(str.length + start, 0), length) : str.substr(start, length);\r
26704 } : function(value, start, length) {\r
26705 return String(value).substr(start, length);\r
26706 },\r
26707 \r
26708 lowercase: function(value) {\r
26709 return String(value).toLowerCase();\r
26710 },\r
26711 \r
26712 uppercase: function(value) {\r
26713 return String(value).toUpperCase();\r
26714 },\r
26715 \r
26716 usMoney: function(v) {\r
26717 return me.currency(v, '$', 2);\r
26718 },\r
26719 \r
26720 currency: function(v, currencySign, decimals, end) {\r
26721 var negativeSign = '',\r
26722 format = ",0",\r
26723 i = 0;\r
26724 v = v - 0;\r
26725 if (v < 0) {\r
26726 v = -v;\r
26727 negativeSign = '-';\r
26728 }\r
26729 decimals = Ext.isDefined(decimals) ? decimals : me.currencyPrecision;\r
26730 format += (decimals > 0 ? '.' : '');\r
26731 for (; i < decimals; i++) {\r
26732 format += '0';\r
26733 }\r
26734 v = me.number(v, format);\r
26735 if ((end || me.currencyAtEnd) === true) {\r
26736 return Ext.String.format("{0}{1}{2}", negativeSign, v, currencySign || me.currencySign);\r
26737 } else {\r
26738 return Ext.String.format("{0}{1}{2}", negativeSign, currencySign || me.currencySign, v);\r
26739 }\r
26740 },\r
26741 \r
26742 date: function(v, format) {\r
26743 if (!v) {\r
26744 return "";\r
26745 }\r
26746 if (!Ext.isDate(v)) {\r
26747 v = new Date(Date.parse(v));\r
26748 }\r
26749 return Ext.Date.dateFormat(v, format || Ext.Date.defaultFormat);\r
26750 },\r
26751 \r
26752 dateRenderer: function(format) {\r
26753 return function(v) {\r
26754 return me.date(v, format);\r
26755 };\r
26756 },\r
26757 \r
26758 hex: function(value, digits) {\r
26759 var s = parseInt(value || 0, 10).toString(16);\r
26760 if (digits) {\r
26761 if (digits < 0) {\r
26762 digits = -digits;\r
26763 if (s.length > digits) {\r
26764 s = s.substring(s.length - digits);\r
26765 }\r
26766 }\r
26767 while (s.length < digits) {\r
26768 s = '0' + s;\r
26769 }\r
26770 }\r
26771 return s;\r
26772 },\r
26773 \r
26774 or: function(value, orValue) {\r
26775 return value || orValue;\r
26776 },\r
26777 \r
26778 pick: function(value, firstValue, secondValue) {\r
26779 if (Ext.isNumber(value)) {\r
26780 var ret = arguments[value + 1];\r
26781 if (ret) {\r
26782 return ret;\r
26783 }\r
26784 }\r
26785 return value ? secondValue : firstValue;\r
26786 },\r
26787 \r
26788 stripTags: function(v) {\r
26789 return !v ? v : String(v).replace(me.stripTagsRe, "");\r
26790 },\r
26791 \r
26792 stripScripts: function(v) {\r
26793 return !v ? v : String(v).replace(me.stripScriptsRe, "");\r
26794 },\r
26795 \r
26796 fileSize: (function() {\r
26797 var byteLimit = 1024,\r
26798 kbLimit = 1048576,\r
26799 mbLimit = 1073741824;\r
26800 return function(size) {\r
26801 var out;\r
26802 if (size < byteLimit) {\r
26803 if (size === 1) {\r
26804 out = '1 byte';\r
26805 } else {\r
26806 out = size + ' bytes';\r
26807 }\r
26808 } else if (size < kbLimit) {\r
26809 out = (Math.round(((size * 10) / byteLimit)) / 10) + ' KB';\r
26810 } else if (size < mbLimit) {\r
26811 out = (Math.round(((size * 10) / kbLimit)) / 10) + ' MB';\r
26812 } else {\r
26813 out = (Math.round(((size * 10) / mbLimit)) / 10) + ' GB';\r
26814 }\r
26815 return out;\r
26816 };\r
26817 })(),\r
26818 \r
26819 math: (function() {\r
26820 var fns = {};\r
26821 return function(v, a) {\r
26822 if (!fns[a]) {\r
26823 fns[a] = Ext.functionFactory('v', 'return v ' + a + ';');\r
26824 }\r
26825 return fns[a](v);\r
26826 };\r
26827 }()),\r
26828 \r
26829 round: function(value, precision) {\r
26830 var result = Number(value);\r
26831 if (typeof precision === 'number') {\r
26832 precision = Math.pow(10, precision);\r
26833 result = Math.round(value * precision) / precision;\r
26834 } else if (precision === undefined) {\r
26835 result = Math.round(result);\r
26836 }\r
26837 return result;\r
26838 },\r
26839 \r
26840 number: function(v, formatString) {\r
26841 if (!formatString) {\r
26842 return v;\r
26843 }\r
26844 if (isNaN(v)) {\r
26845 return '';\r
26846 }\r
26847 var formatFn = me.formatFns[formatString];\r
26848
26849
26850 if (!formatFn) {\r
26851 var originalFormatString = formatString,\r
26852 comma = me.thousandSeparator,\r
26853 decimalSeparator = me.decimalSeparator,\r
26854 precision = 0,\r
26855 trimPart = '',\r
26856 hasComma, splitFormat, extraChars, trimTrailingZeroes, code, len;\r
26857
26858
26859
26860
26861 if (formatString.substr(formatString.length - 2) === '/i') {\r
26862
26863
26864 if (!me.I18NFormatCleanRe || me.lastDecimalSeparator !== decimalSeparator) {\r
26865 me.I18NFormatCleanRe = new RegExp('[^\\d\\' + decimalSeparator + '#]', 'g');\r
26866 me.lastDecimalSeparator = decimalSeparator;\r
26867 }\r
26868 formatString = formatString.substr(0, formatString.length - 2);\r
26869 hasComma = formatString.indexOf(comma) !== -1;\r
26870 splitFormat = formatString.replace(me.I18NFormatCleanRe, '').split(decimalSeparator);\r
26871 } else {\r
26872 hasComma = formatString.indexOf(',') !== -1;\r
26873 splitFormat = formatString.replace(me.formatCleanRe, '').split('.');\r
26874 }\r
26875 extraChars = formatString.replace(me.formatPattern, '');\r
26876 if (splitFormat.length > 2) {\r
26877
26878 Ext.raise({\r
26879 sourceClass: "Ext.util.Format",\r
26880 sourceMethod: "number",\r
26881 value: v,\r
26882 formatString: formatString,\r
26883 msg: "Invalid number format, should have no more than 1 decimal"\r
26884 });\r
26885 }\r
26886
26887 else if (splitFormat.length === 2) {\r
26888 precision = splitFormat[1].length;\r
26889
26890 trimTrailingZeroes = splitFormat[1].match(me.hashRe);\r
26891 if (trimTrailingZeroes) {\r
26892 len = trimTrailingZeroes[0].length;\r
26893
26894 trimPart = 'trailingZeroes=new RegExp(Ext.String.escapeRegex(utilFormat.decimalSeparator) + "*0{0,' + len + '}$")';\r
26895 }\r
26896 }\r
26897
26898 code = [\r
26899 '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;',\r
26900 'absVal=Math.abs(v);',\r
26901 'fnum=Ext.Number.toFixed(absVal, ' + precision + ');',\r
26902 trimPart,\r
26903 ';'\r
26904 ];\r
26905 if (hasComma) {\r
26906
26907
26908 if (precision) {\r
26909 code[code.length] = 'parts=fnum.split(".");';\r
26910 code[code.length] = 'fnum=parts[0];';\r
26911 }\r
26912 code[code.length] = 'if(absVal>=1000) {';\r
26913 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);' + '}';\r
26914 if (precision) {\r
26915 code[code.length] = 'fnum += utilFormat.decimalSeparator+parts[1];';\r
26916 }\r
26917 } else if (precision) {\r
26918
26919 code[code.length] = 'if(utilFormat.decimalSeparator!=="."){' + 'parts=fnum.split(".");' + 'fnum=parts[0]+utilFormat.decimalSeparator+parts[1];' + '}';\r
26920 }\r
26921 \r
26922 code[code.length] = 'if(neg&&fnum!=="' + (precision ? '0.' + Ext.String.repeat('0', precision) : '0') + '") { fnum="-"+fnum; }';\r
26923 if (trimTrailingZeroes) {\r
26924 code[code.length] = 'fnum=fnum.replace(trailingZeroes,"");';\r
26925 }\r
26926 code[code.length] = 'return ';\r
26927
26928 if (extraChars) {\r
26929 code[code.length] = 'formatString.replace(formatPattern, fnum);';\r
26930 } else {\r
26931 code[code.length] = 'fnum;';\r
26932 }\r
26933 code[code.length] = '};';\r
26934 formatFn = me.formatFns[originalFormatString] = Ext.functionFactory('Ext', code.join(''))(Ext);\r
26935 }\r
26936 return formatFn(v);\r
26937 },\r
26938 \r
26939 numberRenderer: function(format) {\r
26940 return function(v) {\r
26941 return me.number(v, format);\r
26942 };\r
26943 },\r
26944 \r
26945 percent: function(value, formatString) {\r
26946 return me.number(value * 100, formatString || '0') + me.percentSign;\r
26947 },\r
26948 \r
26949 attributes: function(attributes) {\r
26950 if (typeof attributes === 'object') {\r
26951 var result = [],\r
26952 name;\r
26953 for (name in attributes) {\r
26954 if (attributes.hasOwnProperty(name)) {\r
26955 result.push(name, '="', name === 'style' ? Ext.DomHelper.generateStyles(attributes[name], null, true) : Ext.htmlEncode(attributes[name]), '" ');\r
26956 }\r
26957 }\r
26958 attributes = result.join('');\r
26959 }\r
26960 return attributes || '';\r
26961 },\r
26962 \r
26963 plural: function(v, s, p) {\r
26964 return v + ' ' + (v === 1 ? s : (p ? p : s + 's'));\r
26965 },\r
26966 \r
26967 nl2br: function(v) {\r
26968 return Ext.isEmpty(v) ? '' : v.replace(me.nl2brRe, '<br/>');\r
26969 },\r
26970 \r
26971 capitalize: Ext.String.capitalize,\r
26972 \r
26973 uncapitalize: Ext.String.uncapitalize,\r
26974 \r
26975 ellipsis: Ext.String.ellipsis,\r
26976 \r
26977 escape: Ext.String.escape,\r
26978 \r
26979 escapeRegex: Ext.String.escapeRegex,\r
26980 \r
26981 htmlDecode: Ext.String.htmlDecode,\r
26982 \r
26983 htmlEncode: Ext.String.htmlEncode,\r
26984 \r
26985 leftPad: Ext.String.leftPad,\r
26986 \r
26987 toggle: Ext.String.toggle,\r
26988 \r
26989 trim: Ext.String.trim,\r
26990 \r
26991 parseBox: function(box) {\r
26992 box = box || 0;\r
26993 if (typeof box === 'number') {\r
26994 return {\r
26995 top: box,\r
26996 right: box,\r
26997 bottom: box,\r
26998 left: box\r
26999 };\r
27000 }\r
27001 var parts = box.split(' '),\r
27002 ln = parts.length;\r
27003 if (ln === 1) {\r
27004 parts[1] = parts[2] = parts[3] = parts[0];\r
27005 } else if (ln === 2) {\r
27006 parts[2] = parts[0];\r
27007 parts[3] = parts[1];\r
27008 } else if (ln === 3) {\r
27009 parts[3] = parts[1];\r
27010 }\r
27011 return {\r
27012 top: parseInt(parts[0], 10) || 0,\r
27013 right: parseInt(parts[1], 10) || 0,\r
27014 bottom: parseInt(parts[2], 10) || 0,\r
27015 left: parseInt(parts[3], 10) || 0\r
27016 };\r
27017 }\r
27018 };\r
27019});\r
27020\r
27021\r
27022Ext.define('Ext.Template', {\r
27023 inheritableStatics: {\r
27024 \r
27025 from: function(el, config) {\r
27026 el = Ext.getDom(el);\r
27027 return new this(el.value || el.innerHTML, config || '');\r
27028 }\r
27029 },\r
27030
27031
27032
27033 useEval: Ext.isGecko,\r
27034 \r
27035 \r
27036 constructor: function(html) {\r
27037 var me = this,\r
27038 args = arguments,\r
27039 buffer = [],\r
27040 i,\r
27041 length = args.length,\r
27042 value;\r
27043 me.initialConfig = {};\r
27044
27045
27046
27047 if (length === 1 && Ext.isArray(html)) {\r
27048 args = html;\r
27049 length = args.length;\r
27050 }\r
27051 if (length > 1) {\r
27052 for (i = 0; i < length; i++) {\r
27053 value = args[i];\r
27054 if (typeof value === 'object') {\r
27055 Ext.apply(me.initialConfig, value);\r
27056 Ext.apply(me, value);\r
27057 } else {\r
27058 buffer.push(value);\r
27059 }\r
27060 }\r
27061 } else {\r
27062 buffer.push(html);\r
27063 }\r
27064 \r
27065 me.html = buffer.join('');\r
27066 },\r
27067 \r
27068 isTemplate: true,\r
27069 \r
27070 \r
27071 disableFormats: false,\r
27072 \r
27073 tokenRe: /\{(?:(?:(\d+)|([a-z_][\w\-]*))(?::([a-z_\.]+)(?:\(([^\)]*?)?\))?)?)\}/gi,\r
27074 \r
27075 apply: function(values) {\r
27076 var me = this;\r
27077 if (me.compiled) {\r
27078 if (!me.fn) {\r
27079 me.compile();\r
27080 }\r
27081 return me.fn(values).join('');\r
27082 }\r
27083 return me.evaluate(values);\r
27084 },\r
27085 \r
27086 evaluate: function(values) {\r
27087 var me = this,\r
27088 useFormat = !me.disableFormats,\r
27089 fm = Ext.util.Format,\r
27090 tpl = me;\r
27091 function fn(match, index, name, formatFn, args) {\r
27092
27093
27094 if (name == null || name === '') {\r
27095 name = index;\r
27096 }\r
27097 if (formatFn && useFormat) {\r
27098 if (args) {\r
27099 args = [\r
27100 values[name]\r
27101 ].concat(Ext.functionFactory('return [' + args + '];')());\r
27102 } else {\r
27103 args = [\r
27104 values[name]\r
27105 ];\r
27106 }\r
27107
27108 if (formatFn.substr(0, 5) === "this.") {\r
27109 return tpl[formatFn.substr(5)].apply(tpl, args);\r
27110 }\r
27111
27112 else if (fm[formatFn]) {\r
27113 return fm[formatFn].apply(fm, args);\r
27114 } else
27115 {\r
27116 return match;\r
27117 }\r
27118 } else {\r
27119 return values[name] !== undefined ? values[name] : "";\r
27120 }\r
27121 }\r
27122 return me.html.replace(me.tokenRe, fn);\r
27123 },\r
27124 \r
27125 applyOut: function(values, out) {\r
27126 var me = this;\r
27127 if (me.compiled) {\r
27128 if (!me.fn) {\r
27129 me.compile();\r
27130 }\r
27131 out.push.apply(out, me.fn(values));\r
27132 } else {\r
27133 out.push(me.apply(values));\r
27134 }\r
27135 return out;\r
27136 },\r
27137 \r
27138 applyTemplate: function() {\r
27139 return this.apply.apply(this, arguments);\r
27140 },\r
27141 \r
27142 set: function(html, compile) {\r
27143 var me = this;\r
27144 me.html = html;\r
27145 me.compiled = !!compile;\r
27146 me.fn = null;\r
27147 return me;\r
27148 },\r
27149 compileARe: /\\/g,\r
27150 compileBRe: /(\r\n|\n)/g,\r
27151 compileCRe: /'/g,\r
27152 \r
27153 compile: function() {\r
27154 var me = this,\r
27155 code;\r
27156 code = me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.tokenRe, me.regexReplaceFn.bind(me));\r
27157 code = (this.disableFormats !== true ? 'var fm=Ext.util.Format;' : '') + (me.useEval ? '$=' : 'return') + " function(v){return ['" + code + "'];};";\r
27158 me.fn = me.useEval ? me.evalCompiled(code) : (new Function('Ext', code))(Ext);\r
27159
27160 me.compiled = true;\r
27161 return me;\r
27162 },\r
27163 \r
27164 evalCompiled: function($) {\r
27165
27166
27167
27168
27169 eval($);\r
27170
27171 return $;\r
27172 },\r
27173 regexReplaceFn: function(match, index, name, formatFn, args) {\r
27174
27175
27176
27177 if (index == null || index === '') {\r
27178 index = '"' + name + '"';\r
27179 }\r
27180
27181
27182 else if (this.stringFormat) {\r
27183 index = parseInt(index) + 1;\r
27184 }\r
27185 if (formatFn && this.disableFormats !== true) {\r
27186 args = args ? ',' + args : "";\r
27187
27188 if (formatFn.substr(0, 5) === "this.") {\r
27189 formatFn = formatFn + '(';\r
27190 }\r
27191
27192 else if (Ext.util.Format[formatFn]) {\r
27193 formatFn = "fm." + formatFn + '(';\r
27194 } else
27195 {\r
27196 return match;\r
27197 }\r
27198 return "'," + formatFn + "v[" + index + "]" + args + "),'";\r
27199 } else {\r
27200 return "',v[" + index + "] == undefined ? '' : v[" + index + "],'";\r
27201 }\r
27202 },\r
27203 \r
27204 insertFirst: function(el, values, returnElement) {\r
27205 return this.doInsert('afterBegin', el, values, returnElement);\r
27206 },\r
27207 \r
27208 insertBefore: function(el, values, returnElement) {\r
27209 return this.doInsert('beforeBegin', el, values, returnElement);\r
27210 },\r
27211 \r
27212 insertAfter: function(el, values, returnElement) {\r
27213 return this.doInsert('afterEnd', el, values, returnElement);\r
27214 },\r
27215 \r
27216 append: function(el, values, returnElement) {\r
27217 return this.doInsert('beforeEnd', el, values, returnElement);\r
27218 },\r
27219 doInsert: function(where, el, values, returnElement) {\r
27220 var newNode = Ext.DomHelper.insertHtml(where, Ext.getDom(el), this.apply(values));\r
27221 return returnElement ? Ext.get(newNode) : newNode;\r
27222 },\r
27223 \r
27224 overwrite: function(el, values, returnElement) {\r
27225 var newNode = Ext.DomHelper.overwrite(Ext.getDom(el), this.apply(values));\r
27226 return returnElement ? Ext.get(newNode) : newNode;\r
27227 }\r
27228}, function(Template) {\r
27229 var formatRe = /\{\d+\}/,\r
27230 generateFormatFn = function(format) {\r
27231
27232 if (formatRe.test(format)) {\r
27233 format = new Template(format, formatTplConfig);\r
27234 return function() {\r
27235 return format.apply(arguments);\r
27236 };\r
27237 } else
27238 {\r
27239 return function() {\r
27240 return format;\r
27241 };\r
27242 }\r
27243 },\r
27244
27245
27246
27247 formatTplConfig = {\r
27248 useFormat: false,\r
27249 compiled: true,\r
27250 stringFormat: true\r
27251 },\r
27252 formatFns = {};\r
27253 \r
27254 \r
27255 Ext.String.format = Ext.util.Format.format = function(format) {\r
27256 var formatFn = formatFns[format] || (formatFns[format] = generateFormatFn(format));\r
27257 return formatFn.apply(this, arguments);\r
27258 };\r
27259 Ext.String.formatEncode = function() {\r
27260 return Ext.String.htmlEncode(Ext.String.format.apply(this, arguments));\r
27261 };\r
27262});\r
27263\r
27264\r
27265Ext.define('Ext.util.XTemplateParser', {\r
27266 constructor: function(config) {\r
27267 Ext.apply(this, config);\r
27268 },\r
27269 \r
27270 \r
27271
27272 \r
27273
27274 \r
27275
27276 \r
27277
27278 \r
27279
27280 \r
27281
27282 \r
27283
27284 \r
27285
27286 \r
27287
27288 \r
27289
27290 \r
27291
27292 \r
27293
27294 \r
27295
27296 \r
27297
27298 \r
27299 doTpl: Ext.emptyFn,\r
27300 parse: function(str) {\r
27301 var me = this,\r
27302 len = str.length,\r
27303 aliases = {\r
27304 elseif: 'elif'\r
27305 },\r
27306 topRe = me.topRe,\r
27307 actionsRe = me.actionsRe,\r
27308 index, stack, s, m, t, prev, frame, subMatch, begin, end, actions, prop, expectTplNext;\r
27309 me.level = 0;\r
27310 me.stack = stack = [];\r
27311 for (index = 0; index < len; index = end) {\r
27312 topRe.lastIndex = index;\r
27313 m = topRe.exec(str);\r
27314 if (!m) {\r
27315 me.doText(str.substring(index, len));\r
27316 break;\r
27317 }\r
27318 begin = m.index;\r
27319 end = topRe.lastIndex;\r
27320 if (index < begin) {\r
27321
27322
27323
27324 s = str.substring(index, begin);\r
27325 if (!(expectTplNext && Ext.String.trim(s) === '')) {\r
27326 me.doText(s);\r
27327 }\r
27328 }\r
27329 expectTplNext = false;\r
27330 if (m[1]) {\r
27331 end = str.indexOf('%}', begin + 2);\r
27332 me.doEval(str.substring(begin + 2, end));\r
27333 end += 2;\r
27334 } else if (m[2]) {\r
27335 end = str.indexOf(']}', begin + 2);\r
27336 me.doExpr(str.substring(begin + 2, end));\r
27337 end += 2;\r
27338 } else if (m[3]) {\r
27339
27340 me.doTag(m[3]);\r
27341 } else if (m[4]) {\r
27342
27343 actions = null;\r
27344 while ((subMatch = actionsRe.exec(m[4])) !== null) {\r
27345 s = subMatch[2] || subMatch[3];\r
27346 if (s) {\r
27347 s = Ext.String.htmlDecode(s);\r
27348
27349 t = subMatch[1];\r
27350 t = aliases[t] || t;\r
27351 actions = actions || {};\r
27352 prev = actions[t];\r
27353 if (typeof prev == 'string') {\r
27354 actions[t] = [\r
27355 prev,\r
27356 s\r
27357 ];\r
27358 } else if (prev) {\r
27359 actions[t].push(s);\r
27360 } else {\r
27361 actions[t] = s;\r
27362 }\r
27363 }\r
27364 }\r
27365 if (!actions) {\r
27366 if (me.elseRe.test(m[4])) {\r
27367 me.doElse();\r
27368 } else if (me.defaultRe.test(m[4])) {\r
27369 me.doDefault();\r
27370 } else {\r
27371 me.doTpl();\r
27372 stack.push({\r
27373 type: 'tpl'\r
27374 });\r
27375 }\r
27376 } else if (actions['if']) {\r
27377 me.doIf(actions['if'], actions);\r
27378 stack.push({\r
27379 type: 'if'\r
27380 });\r
27381 } else if (actions['switch']) {\r
27382 me.doSwitch(actions['switch'], actions);\r
27383 stack.push({\r
27384 type: 'switch'\r
27385 });\r
27386 expectTplNext = true;\r
27387 } else if (actions['case']) {\r
27388 me.doCase(actions['case'], actions);\r
27389 } else if (actions['elif']) {\r
27390 me.doElseIf(actions['elif'], actions);\r
27391 } else if (actions['for']) {\r
27392 ++me.level;\r
27393
27394 if (prop = me.propRe.exec(m[4])) {\r
27395 actions.propName = prop[1] || prop[2];\r
27396 }\r
27397 me.doFor(actions['for'], actions);\r
27398 stack.push({\r
27399 type: 'for',\r
27400 actions: actions\r
27401 });\r
27402 } else if (actions['foreach']) {\r
27403 ++me.level;\r
27404
27405 if (prop = me.propRe.exec(m[4])) {\r
27406 actions.propName = prop[1] || prop[2];\r
27407 }\r
27408 me.doForEach(actions['foreach'], actions);\r
27409 stack.push({\r
27410 type: 'foreach',\r
27411 actions: actions\r
27412 });\r
27413 } else if (actions.exec) {\r
27414 me.doExec(actions.exec, actions);\r
27415 stack.push({\r
27416 type: 'exec',\r
27417 actions: actions\r
27418 });\r
27419 }\r
27420 }\r
27421 \r
27422 else if (m[0].length === 5) {\r
27423
27424
27425 stack.push({\r
27426 type: 'tpl'\r
27427 });\r
27428 } else {\r
27429 frame = stack.pop();\r
27430 me.doEnd(frame.type, frame.actions);\r
27431 if (frame.type == 'for' || frame.type == 'foreach') {\r
27432 --me.level;\r
27433 }\r
27434 }\r
27435 }\r
27436 },\r
27437
27438 topRe: /(?:(\{\%)|(\{\[)|\{([^{}]+)\})|(?:<tpl([^>]*)\>)|(?:<\/tpl>)/g,\r
27439 actionsRe: /\s*(elif|elseif|if|for|foreach|exec|switch|case|eval|between)\s*\=\s*(?:(?:"([^"]*)")|(?:'([^']*)'))\s*/g,\r
27440 propRe: /prop=(?:(?:"([^"]*)")|(?:'([^']*)'))/,\r
27441 defaultRe: /^\s*default\s*$/,\r
27442 elseRe: /^\s*else\s*$/\r
27443});\r
27444\r
27445\r
27446Ext.define('Ext.util.XTemplateCompiler', {\r
27447 extend: Ext.util.XTemplateParser,\r
27448
27449
27450
27451 useEval: Ext.isGecko,\r
27452
27453
27454
27455 useIndex: Ext.isIE8m,\r
27456 useFormat: true,\r
27457 propNameRe: /^[\w\d\$]*$/,\r
27458 compile: function(tpl) {\r
27459 var me = this,\r
27460 code = me.generate(tpl);\r
27461
27462
27463
27464
27465 return me.useEval ? me.evalTpl(code) : (new Function('Ext', code))(Ext);\r
27466 },\r
27467 generate: function(tpl) {\r
27468 var me = this,\r
27469
27470 definitions = 'var fm=Ext.util.Format,ts=Object.prototype.toString;',\r
27471 code;\r
27472
27473 me.maxLevel = 0;\r
27474 me.body = [\r
27475 'var c0=values, a0=' + me.createArrayTest(0) + ', p0=parent, n0=xcount, i0=xindex, k0, v;\n'\r
27476 ];\r
27477 if (me.definitions) {\r
27478 if (typeof me.definitions === 'string') {\r
27479 me.definitions = [\r
27480 me.definitions,\r
27481 definitions\r
27482 ];\r
27483 } else {\r
27484 me.definitions.push(definitions);\r
27485 }\r
27486 } else {\r
27487 me.definitions = [\r
27488 definitions\r
27489 ];\r
27490 }\r
27491 me.switches = [];\r
27492 me.parse(tpl);\r
27493 me.definitions.push((me.useEval ? '$=' : 'return') + ' function (' + me.fnArgs + ') {', me.body.join(''), '}');\r
27494 code = me.definitions.join('\n');\r
27495
27496 me.definitions.length = me.body.length = me.switches.length = 0;\r
27497 delete me.definitions;\r
27498 delete me.body;\r
27499 delete me.switches;\r
27500 return code;\r
27501 },\r
27502
27503
27504 doText: function(text) {\r
27505 var me = this,\r
27506 out = me.body;\r
27507 text = text.replace(me.aposRe, "\\'").replace(me.newLineRe, '\\n');\r
27508 if (me.useIndex) {\r
27509 out.push('out[out.length]=\'', text, '\'\n');\r
27510 } else {\r
27511 out.push('out.push(\'', text, '\')\n');\r
27512 }\r
27513 },\r
27514 doExpr: function(expr) {\r
27515 var out = this.body;\r
27516 out.push('if ((v=' + expr + ') != null) out');\r
27517
27518
27519 if (this.useIndex) {\r
27520 out.push('[out.length]=v+\'\'\n');\r
27521 } else {\r
27522 out.push('.push(v+\'\')\n');\r
27523 }\r
27524 },\r
27525 doTag: function(tag) {\r
27526 var expr = this.parseTag(tag);\r
27527 if (expr) {\r
27528 this.doExpr(expr);\r
27529 } else {\r
27530
27531 this.doText('{' + tag + '}');\r
27532 }\r
27533 },\r
27534 doElse: function() {\r
27535 this.body.push('} else {\n');\r
27536 },\r
27537 doEval: function(text) {\r
27538 this.body.push(text, '\n');\r
27539 },\r
27540 doIf: function(action, actions) {\r
27541 var me = this;\r
27542
27543 if (action === '.') {\r
27544 me.body.push('if (values) {\n');\r
27545 } else if (me.propNameRe.test(action)) {\r
27546 me.body.push('if (', me.parseTag(action), ') {\n');\r
27547 } else
27548 {\r
27549 me.body.push('if (', me.addFn(action), me.callFn, ') {\n');\r
27550 }\r
27551 if (actions.exec) {\r
27552 me.doExec(actions.exec);\r
27553 }\r
27554 },\r
27555 doElseIf: function(action, actions) {\r
27556 var me = this;\r
27557
27558 if (action === '.') {\r
27559 me.body.push('else if (values) {\n');\r
27560 } else if (me.propNameRe.test(action)) {\r
27561 me.body.push('} else if (', me.parseTag(action), ') {\n');\r
27562 } else
27563 {\r
27564 me.body.push('} else if (', me.addFn(action), me.callFn, ') {\n');\r
27565 }\r
27566 if (actions.exec) {\r
27567 me.doExec(actions.exec);\r
27568 }\r
27569 },\r
27570 doSwitch: function(action) {\r
27571 var me = this,\r
27572 key;\r
27573
27574 if (action === '.' || action === '#') {\r
27575 key = action === '.' ? 'values' : 'xindex';\r
27576 me.body.push('switch (', key, ') {\n');\r
27577 } else if (me.propNameRe.test(action)) {\r
27578 me.body.push('switch (', me.parseTag(action), ') {\n');\r
27579 } else
27580 {\r
27581 me.body.push('switch (', me.addFn(action), me.callFn, ') {\n');\r
27582 }\r
27583 me.switches.push(0);\r
27584 },\r
27585 doCase: function(action) {\r
27586 var me = this,\r
27587 cases = Ext.isArray(action) ? action : [\r
27588 action\r
27589 ],\r
27590 n = me.switches.length - 1,\r
27591 match, i;\r
27592 if (me.switches[n]) {\r
27593 me.body.push('break;\n');\r
27594 } else {\r
27595 me.switches[n]++;\r
27596 }\r
27597 for (i = 0 , n = cases.length; i < n; ++i) {\r
27598 match = me.intRe.exec(cases[i]);\r
27599 cases[i] = match ? match[1] : ("'" + cases[i].replace(me.aposRe, "\\'") + "'");\r
27600 }\r
27601 me.body.push('case ', cases.join(': case '), ':\n');\r
27602 },\r
27603 doDefault: function() {\r
27604 var me = this,\r
27605 n = me.switches.length - 1;\r
27606 if (me.switches[n]) {\r
27607 me.body.push('break;\n');\r
27608 } else {\r
27609 me.switches[n]++;\r
27610 }\r
27611 me.body.push('default:\n');\r
27612 },\r
27613 doEnd: function(type, actions) {\r
27614 var me = this,\r
27615 L = me.level - 1;\r
27616 if (type == 'for' || type == 'foreach') {\r
27617 \r
27618 if (actions.exec) {\r
27619 me.doExec(actions.exec);\r
27620 }\r
27621 me.body.push('}\n');\r
27622 me.body.push('parent=p', L, ';values=r', L + 1, ';xcount=n' + L + ';xindex=i', L, '+1;xkey=k', L, ';\n');\r
27623 } else if (type == 'if' || type == 'switch') {\r
27624 me.body.push('}\n');\r
27625 }\r
27626 },\r
27627 doFor: function(action, actions) {\r
27628 var me = this,\r
27629 s,\r
27630 L = me.level,\r
27631 up = L - 1,\r
27632 parentAssignment;\r
27633
27634 if (action === '.') {\r
27635 s = 'values';\r
27636 } else if (me.propNameRe.test(action)) {\r
27637 s = me.parseTag(action);\r
27638 } else
27639 {\r
27640 s = me.addFn(action) + me.callFn;\r
27641 }\r
27642 \r
27643
27644 if (me.maxLevel < L) {\r
27645 me.maxLevel = L;\r
27646 me.body.push('var ');\r
27647 }\r
27648 if (action == '.') {\r
27649 parentAssignment = 'c' + L;\r
27650 } else {\r
27651 parentAssignment = 'a' + up + '?c' + up + '[i' + up + ']:c' + up;\r
27652 }\r
27653 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, ']');\r
27654 if (actions.propName) {\r
27655 me.body.push('.', actions.propName);\r
27656 }\r
27657 me.body.push('\n', 'xindex=i', L, '+1\n');\r
27658 if (actions.between) {\r
27659 me.body.push('if(xindex>1){ out.push("', actions.between, '"); } \n');\r
27660 }\r
27661 },\r
27662 doForEach: function(action, actions) {\r
27663 var me = this,\r
27664 s,\r
27665 L = me.level,\r
27666 up = L - 1,\r
27667 parentAssignment;\r
27668
27669 if (action === '.') {\r
27670 s = 'values';\r
27671 } else if (me.propNameRe.test(action)) {\r
27672 s = me.parseTag(action);\r
27673 } else
27674 {\r
27675 s = me.addFn(action) + me.callFn;\r
27676 }\r
27677 \r
27678
27679 if (me.maxLevel < L) {\r
27680 me.maxLevel = L;\r
27681 me.body.push('var ');\r
27682 }\r
27683 if (action == '.') {\r
27684 parentAssignment = 'c' + L;\r
27685 } else {\r
27686 parentAssignment = 'a' + up + '?c' + up + '[i' + up + ']:c' + up;\r
27687 }\r
27688 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, '];');\r
27689 if (actions.propName) {\r
27690 me.body.push('.', actions.propName);\r
27691 }\r
27692 if (actions.between) {\r
27693 me.body.push('if(xindex>1){ out.push("', actions.between, '"); } \n');\r
27694 }\r
27695 },\r
27696 createArrayTest: ('isArray' in Array) ? function(L) {\r
27697 return 'Array.isArray(c' + L + ')';\r
27698 } : function(L) {\r
27699 return 'ts.call(c' + L + ')==="[object Array]"';\r
27700 },\r
27701 doExec: function(action, actions) {\r
27702 var me = this,\r
27703 name = 'f' + me.definitions.length,\r
27704 guards = me.guards[me.strict ? 0 : 1];\r
27705 me.definitions.push('function ' + name + '(' + me.fnArgs + ') {', guards.doTry, ' var $v = values; with($v) {', ' ' + action, ' }', guards.doCatch, '}');\r
27706 me.body.push(name + me.callFn + '\n');\r
27707 },\r
27708
27709
27710 guards: [\r
27711 {\r
27712 doTry: '',\r
27713 doCatch: ''\r
27714 },\r
27715 {\r
27716 doTry: 'try { ',\r
27717 doCatch: ' } catch(e) {\n' +
27718 'Ext.log.warn("XTemplate evaluation exception: " + e.message);\n' +
27719 '}'\r
27720 }\r
27721 ],\r
27722 addFn: function(body) {\r
27723 var me = this,\r
27724 name = 'f' + me.definitions.length,\r
27725 guards = me.guards[me.strict ? 0 : 1];\r
27726 if (body === '.') {\r
27727 me.definitions.push('function ' + name + '(' + me.fnArgs + ') {', ' return values', '}');\r
27728 } else if (body === '..') {\r
27729 me.definitions.push('function ' + name + '(' + me.fnArgs + ') {', ' return parent', '}');\r
27730 } else {\r
27731 me.definitions.push('function ' + name + '(' + me.fnArgs + ') {', guards.doTry, ' var $v = values; with($v) {', ' return(' + body + ')', ' }', guards.doCatch, '}');\r
27732 }\r
27733 return name;\r
27734 },\r
27735 parseTag: function(tag) {\r
27736 var me = this,\r
27737 m = me.tagRe.exec(tag),\r
27738 name, format, args, math, v;\r
27739 if (!m) {\r
27740 return null;\r
27741 }\r
27742 name = m[1];\r
27743 format = m[2];\r
27744 args = m[3];\r
27745 math = m[4];\r
27746
27747 if (name == '.') {\r
27748
27749 if (!me.validTypes) {\r
27750 me.definitions.push('var validTypes={string:1,number:1,boolean:1};');\r
27751 me.validTypes = true;\r
27752 }\r
27753 v = 'validTypes[typeof values] || ts.call(values) === "[object Date]" ? values : ""';\r
27754 }\r
27755
27756 else if (name == '#') {\r
27757 v = 'xindex';\r
27758 }\r
27759
27760 else if (name == '$') {\r
27761 v = 'xkey';\r
27762 } else if (name.substr(0, 7) == "parent.") {\r
27763 v = name;\r
27764 }\r
27765
27766 else if (isNaN(name) && name.indexOf('-') == -1 && name.indexOf('.') != -1) {\r
27767 v = "values." + name;\r
27768 } else
27769
27770 {\r
27771 v = "values['" + name + "']";\r
27772 }\r
27773 if (math) {\r
27774 v = '(' + v + math + ')';\r
27775 }\r
27776 if (format && me.useFormat) {\r
27777 args = args ? ',' + args : "";\r
27778 if (format.substr(0, 5) != "this.") {\r
27779 format = "fm." + format + '(';\r
27780 } else {\r
27781 format += '(';\r
27782 }\r
27783 } else {\r
27784 return v;\r
27785 }\r
27786 return format + v + args + ')';\r
27787 },\r
27788 \r
27789 evalTpl: function($) {\r
27790
27791
27792
27793
27794 eval($);\r
27795 return $;\r
27796 },\r
27797 newLineRe: /\r\n|\r|\n/g,\r
27798 aposRe: /[']/g,\r
27799 intRe: /^\s*(\d+)\s*$/,\r
27800 tagRe: /^([\w-\.\#\$]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\/]\s?[\d\.\+\-\*\/\(\)]+)?$/\r
27801}, function() {\r
27802 var proto = this.prototype;\r
27803 proto.fnArgs = 'out,values,parent,xindex,xcount,xkey';\r
27804 proto.callFn = '.call(this,' + proto.fnArgs + ')';\r
27805});\r
27806\r
27807\r
27808Ext.define('Ext.XTemplate', {\r
27809 extend: Ext.Template,\r
27810 isXTemplate: true,\r
27811 \r
27812 emptyObj: {},\r
27813 \r
27814 \r
27815 \r
27816 fn: null,\r
27817 \r
27818 strict: false,\r
27819 apply: function(values, parent, xindex, xcount) {\r
27820 return this.applyOut(values, [], parent, xindex, xcount).join('');\r
27821 },\r
27822 applyOut: function(values, out, parent, xindex, xcount) {\r
27823 var me = this,\r
27824 compiler;\r
27825 if (!me.fn) {\r
27826 compiler = new Ext.util.XTemplateCompiler({\r
27827 useFormat: me.disableFormats !== true,\r
27828 definitions: me.definitions,\r
27829 strict: me.strict\r
27830 });\r
27831 me.fn = compiler.compile(me.html);\r
27832 }\r
27833
27834 xindex = xindex || 1;\r
27835
27836 xcount = xcount || 1;\r
27837 if (me.strict) {\r
27838 me.fn(out, values, parent || me.emptyObj, xindex, xcount);\r
27839 } else {\r
27840 try {\r
27841 me.fn(out, values, parent || me.emptyObj, xindex, xcount);\r
27842 } catch (e) {\r
27843
27844 Ext.log.warn('XTemplate evaluation exception: ' + e.message);\r
27845 }\r
27846 }\r
27847
27848 return out;\r
27849 },\r
27850 \r
27851 compile: function() {\r
27852 return this;\r
27853 },\r
27854 statics: {\r
27855 \r
27856 getTpl: function(instance, name) {\r
27857 var tpl = instance[name],\r
27858
27859 owner;\r
27860 if (tpl && !tpl.isTemplate) {\r
27861
27862
27863 tpl = Ext.ClassManager.dynInstantiate('Ext.XTemplate', tpl);\r
27864
27865 if (instance.hasOwnProperty(name)) {\r
27866
27867 owner = instance;\r
27868 } else {\r
27869
27870 for (owner = instance.self.prototype; owner && !owner.hasOwnProperty(name); owner = owner.superclass) {}\r
27871 }\r
27872 owner[name] = tpl;\r
27873 tpl.owner = owner;\r
27874 }\r
27875
27876
27877 return tpl || null;\r
27878 }\r
27879 }\r
27880});\r
27881\r
27882\r
27883Ext.define('Ext.app.EventDomain', {\r
27884 statics: {\r
27885 \r
27886 instances: {}\r
27887 },\r
27888 \r
27889 isEventDomain: true,\r
27890 isInstance: false,\r
27891 constructor: function() {\r
27892 var me = this;\r
27893 if (!me.isInstance) {\r
27894 Ext.app.EventDomain.instances[me.type] = me;\r
27895 }\r
27896 me.bus = {};\r
27897 me.monitoredClasses = [];\r
27898 },\r
27899 \r
27900 dispatch: function(target, ev, args) {\r
27901 ev = Ext.canonicalEventName(ev);\r
27902 var me = this,\r
27903 bus = me.bus,\r
27904 selectors = bus[ev],\r
27905 selector, controllers, id, info, events, len, i, event;\r
27906 if (!selectors) {\r
27907 return true;\r
27908 }\r
27909
27910 for (selector in selectors) {\r
27911
27912
27913 if (selectors.hasOwnProperty(selector) && me.match(target, selector, me.controller)) {\r
27914
27915 controllers = selectors[selector];\r
27916 for (id in controllers) {\r
27917 if (controllers.hasOwnProperty(id)) {\r
27918 info = controllers[id];\r
27919 if (info.controller.isActive()) {\r
27920
27921
27922 events = info.list;\r
27923 len = events.length;\r
27924 for (i = 0; i < len; i++) {\r
27925 event = events[i];\r
27926
27927 if (event.fire.apply(event, args) === false) {\r
27928 return false;\r
27929 }\r
27930 }\r
27931 }\r
27932 }\r
27933 }\r
27934 }\r
27935 }\r
27936 return true;\r
27937 },\r
27938 \r
27939 listen: function(selectors, controller) {\r
27940 var me = this,\r
27941 bus = me.bus,\r
27942 idProperty = me.idProperty,\r
27943 monitoredClasses = me.monitoredClasses,\r
27944 monitoredClassesCount = monitoredClasses.length,\r
27945 controllerId = controller.getId(),\r
27946 isComponentDomain = (me.type === 'component'),\r
27947 refMap = isComponentDomain ? controller.getRefMap() : null,\r
27948 i, tree, info, selector, options, listener, scope, event, listeners, ev, classHasListeners;\r
27949 for (selector in selectors) {\r
27950 listeners = selectors[selector];\r
27951 if (isComponentDomain) {\r
27952
27953
27954
27955
27956
27957
27958
27959
27960
27961
27962
27963
27964 selector = refMap[selector] || selector;\r
27965 }\r
27966 if (listeners) {\r
27967 if (idProperty) {\r
27968
27969 if (!/^[*#]/.test(selector)) {\r
27970 Ext.raise('Selectors containing id should begin with #');\r
27971 }\r
27972
27973 selector = selector === '*' ? selector : selector.substring(1);\r
27974 }\r
27975 for (ev in listeners) {\r
27976 options = null;\r
27977 listener = listeners[ev];\r
27978 scope = controller;\r
27979 ev = Ext.canonicalEventName(ev);\r
27980 event = new Ext.util.Event(controller, ev);\r
27981
27982 if (Ext.isObject(listener)) {\r
27983 options = listener;\r
27984 listener = options.fn;\r
27985 scope = options.scope || controller;\r
27986 delete options.fn;\r
27987 delete options.scope;\r
27988 }\r
27989
27990 if ((!options || !options.scope) && typeof listener === 'string') {\r
27991
27992
27993 if (!scope[listener]) {\r
27994 Ext.raise('Cannot resolve "' + listener + '" on controller.');\r
27995 }\r
27996 scope = null;\r
27997 }\r
27998
27999 else if (typeof listener === 'string') {\r
28000 listener = scope[listener];\r
28001 }\r
28002 event.addListener(listener, scope, options);\r
28003 for (i = 0; i < monitoredClassesCount; ++i) {\r
28004 classHasListeners = monitoredClasses[i].hasListeners;\r
28005 if (classHasListeners) {\r
28006
28007 classHasListeners._incr_(ev);\r
28008 }\r
28009 }\r
28010
28011 tree = bus[ev] || (bus[ev] = {});\r
28012 tree = tree[selector] || (tree[selector] = {});\r
28013 info = tree[controllerId] || (tree[controllerId] = {\r
28014 controller: controller,\r
28015 list: []\r
28016 });\r
28017
28018 info.list.push(event);\r
28019 }\r
28020 }\r
28021 }\r
28022 },\r
28023 \r
28024 match: function(target, selector) {\r
28025 var idProperty = this.idProperty;\r
28026 if (idProperty) {\r
28027 return selector === '*' || target[idProperty] === selector;\r
28028 }\r
28029 return false;\r
28030 },\r
28031 \r
28032 monitor: function(observable) {\r
28033 var domain = this,\r
28034 prototype = observable.isInstance ? observable : observable.prototype,\r
28035 doFireEvent = prototype.doFireEvent;\r
28036 domain.monitoredClasses.push(observable);\r
28037 prototype.doFireEvent = function(ev, args) {\r
28038 var ret = doFireEvent.apply(this, arguments);\r
28039 if (ret !== false && !this.isSuspended(ev)) {\r
28040 ret = domain.dispatch(this, ev, args);\r
28041 }\r
28042 return ret;\r
28043 };\r
28044 },\r
28045 \r
28046 unlisten: function(controllerId) {\r
28047 var bus = this.bus,\r
28048 id = controllerId,\r
28049 monitoredClasses = this.monitoredClasses,\r
28050 monitoredClassesCount = monitoredClasses.length,\r
28051 controllers, ev, events, len, item, selector, selectors, i, j, info, classHasListeners;\r
28052 if (controllerId.isController) {\r
28053 id = controllerId.getId();\r
28054 }\r
28055 for (ev in bus) {\r
28056 ev = Ext.canonicalEventName(ev);\r
28057 if (bus.hasOwnProperty(ev) && (selectors = bus[ev])) {\r
28058 for (selector in selectors) {\r
28059 controllers = selectors[selector];\r
28060 info = controllers[id];\r
28061 if (info) {\r
28062 events = info.list;\r
28063 if (events) {\r
28064 for (i = 0 , len = events.length; i < len; ++i) {\r
28065 item = events[i];\r
28066 item.clearListeners();\r
28067 for (j = 0; j < monitoredClassesCount; ++j) {\r
28068 classHasListeners = monitoredClasses[j].hasListeners;\r
28069 if (classHasListeners) {\r
28070
28071
28072 classHasListeners._decr_(item.name);\r
28073 }\r
28074 }\r
28075 }\r
28076 delete controllers[id];\r
28077 }\r
28078 }\r
28079 }\r
28080 }\r
28081 }\r
28082 },\r
28083 destroy: function() {\r
28084 this.monitoredClasses = this.bus = null;\r
28085 this.callParent();\r
28086 }\r
28087});\r
28088\r
28089\r
28090Ext.define('Ext.app.domain.Component', {\r
28091 extend: Ext.app.EventDomain,\r
28092 singleton: true,\r
28093 type: 'component',\r
28094 constructor: function() {\r
28095 this.callParent();\r
28096 this.monitor(Ext.Widget);\r
28097 },\r
28098 dispatch: function(target, ev, args) {\r
28099 var controller = target.lookupController(false),\r
28100
28101 domain, view;\r
28102 while (controller) {\r
28103 domain = controller.compDomain;\r
28104 if (domain) {\r
28105 if (domain.dispatch(target, ev, args) === false) {\r
28106 return false;\r
28107 }\r
28108 }\r
28109 view = controller.getView();\r
28110 controller = view ? view.lookupController(true) : null;\r
28111 }\r
28112 return this.callParent(arguments);\r
28113 },\r
28114 match: function(target, selector) {\r
28115 return target.is(selector);\r
28116 }\r
28117});\r
28118\r
28119\r
28120Ext.define('Ext.app.EventBus', {\r
28121 singleton: true,\r
28122 constructor: function() {\r
28123 var me = this,\r
28124 domains = Ext.app.EventDomain.instances;\r
28125 me.callParent();\r
28126 me.domains = domains;\r
28127 me.bus = domains.component.bus;\r
28128 },\r
28129
28130 \r
28131 control: function(selectors, controller) {\r
28132 return this.domains.component.listen(selectors, controller);\r
28133 },\r
28134 \r
28135 listen: function(to, controller) {\r
28136 var domains = this.domains,\r
28137 domain;\r
28138 for (domain in to) {\r
28139 if (to.hasOwnProperty(domain)) {\r
28140 domains[domain].listen(to[domain], controller);\r
28141 }\r
28142 }\r
28143 },\r
28144 \r
28145 unlisten: function(controllerId) {\r
28146 var domains = Ext.app.EventDomain.instances,\r
28147 domain;\r
28148 for (domain in domains) {\r
28149 domains[domain].unlisten(controllerId);\r
28150 }\r
28151 }\r
28152});\r
28153\r
28154\r
28155Ext.define('Ext.app.domain.Global', {\r
28156 extend: Ext.app.EventDomain,\r
28157 singleton: true,\r
28158 type: 'global',\r
28159 constructor: function() {\r
28160 var me = this;\r
28161 me.callParent();\r
28162 me.monitor(Ext.GlobalEvents);\r
28163 },\r
28164 \r
28165 listen: function(listeners, controller) {\r
28166 this.callParent([\r
28167 {\r
28168 global: listeners\r
28169 },\r
28170 controller\r
28171 ]);\r
28172 },\r
28173 match: Ext.returnTrue\r
28174});\r
28175\r
28176\r
28177Ext.define('Ext.app.BaseController', {\r
28178 mixins: [\r
28179 Ext.mixin.Observable\r
28180 ],\r
28181 isController: true,\r
28182 config: {\r
28183 \r
28184 id: null,\r
28185 \r
28186 control: null,\r
28187 \r
28188 listen: null,\r
28189 \r
28190 routes: null,\r
28191 before: null\r
28192 },\r
28193 \r
28194 constructor: function(config) {\r
28195 var me = this;\r
28196
28197
28198
28199
28200
28201 Ext.apply(me, config);\r
28202
28203
28204 delete me.control;\r
28205 delete me.listen;\r
28206 me.eventbus = Ext.app.EventBus;\r
28207
28208 me.mixins.observable.constructor.call(me, config);\r
28209
28210 me.ensureId();\r
28211 },\r
28212 applyListen: function(listen) {\r
28213 if (Ext.isObject(listen)) {\r
28214 listen = Ext.clone(listen);\r
28215 }\r
28216 return listen;\r
28217 },\r
28218 applyControl: function(control) {\r
28219 if (Ext.isObject(control)) {\r
28220 control = Ext.clone(control);\r
28221 }\r
28222 return control;\r
28223 },\r
28224 \r
28225 updateControl: function(control) {\r
28226 this.ensureId();\r
28227 if (control) {\r
28228 this.control(control);\r
28229 }\r
28230 },\r
28231 \r
28232 updateListen: function(listen) {\r
28233 this.ensureId();\r
28234 if (listen) {\r
28235 this.listen(listen);\r
28236 }\r
28237 },\r
28238 \r
28239 updateRoutes: function(routes) {\r
28240 if (routes) {\r
28241 var me = this,\r
28242 befores = me.getBefore() || {},\r
28243 Router = Ext.app.route.Router,\r
28244 url, config, method;\r
28245 for (url in routes) {\r
28246 config = routes[url];\r
28247 if (Ext.isString(config)) {\r
28248 config = {\r
28249 action: config\r
28250 };\r
28251 }\r
28252 method = config.action;\r
28253 if (!config.before) {\r
28254 config.before = befores[method];\r
28255 }\r
28256
28257 else if (befores[method]) {\r
28258 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.');\r
28259 }\r
28260
28261
28262 Router.connect(url, config, me);\r
28263 }\r
28264 }\r
28265 },\r
28266 isActive: function() {\r
28267 return true;\r
28268 },\r
28269 \r
28270 control: function(selectors, listeners, controller) {\r
28271 var me = this,\r
28272 ctrl = controller,\r
28273 obj;\r
28274 if (Ext.isString(selectors)) {\r
28275 obj = {};\r
28276 obj[selectors] = listeners;\r
28277 } else {\r
28278 obj = selectors;\r
28279 ctrl = listeners;\r
28280 }\r
28281 me.eventbus.control(obj, ctrl || me);\r
28282 },\r
28283 \r
28284 listen: function(to, controller) {\r
28285 this.eventbus.listen(to, controller || this);\r
28286 },\r
28287 destroy: function() {\r
28288 var me = this,\r
28289 bus = me.eventbus;\r
28290 Ext.app.route.Router.disconnectAll(me);\r
28291 if (bus) {\r
28292 bus.unlisten(me);\r
28293 me.eventbus = null;\r
28294 }\r
28295 me.callParent();\r
28296 },\r
28297 \r
28298 redirectTo: function(token, force) {\r
28299 if (token.isModel) {\r
28300 token = token.toUrl();\r
28301 }\r
28302 if (!force) {\r
28303 var currentToken = Ext.util.History.getToken();\r
28304 if (currentToken === token) {\r
28305 return false;\r
28306 }\r
28307 } else {\r
28308 Ext.app.route.Router.onStateChange(token);\r
28309 }\r
28310 Ext.util.History.add(token);\r
28311 return true;\r
28312 }\r
28313});\r
28314\r
28315\r
28316Ext.define('Ext.app.Util', {}, function() {\r
28317 Ext.apply(Ext.app, {\r
28318 namespaces: {\r
28319 Ext: {}\r
28320 },\r
28321 \r
28322 addNamespaces: function(namespace) {\r
28323 var namespaces = Ext.app.namespaces,\r
28324 i, l;\r
28325 if (!Ext.isArray(namespace)) {\r
28326 namespace = [\r
28327 namespace\r
28328 ];\r
28329 }\r
28330 for (i = 0 , l = namespace.length; i < l; i++) {\r
28331 namespaces[namespace[i]] = true;\r
28332 }\r
28333 },\r
28334 \r
28335 clearNamespaces: function() {\r
28336 Ext.app.namespaces = {};\r
28337 },\r
28338 \r
28339 getNamespace: function(className) {\r
28340 var namespaces = Ext.apply({}, Ext.ClassManager.paths, Ext.app.namespaces),\r
28341 deepestPrefix = '',\r
28342 prefix;\r
28343 for (prefix in namespaces) {\r
28344 if (namespaces.hasOwnProperty(prefix) && prefix.length > deepestPrefix.length && (prefix + '.' === className.substring(0, prefix.length + 1))) {\r
28345 deepestPrefix = prefix;\r
28346 }\r
28347 }\r
28348 return deepestPrefix === '' ? undefined : deepestPrefix;\r
28349 },\r
28350 \r
28351 setupPaths: function(appName, appFolder, paths) {\r
28352 var manifestPaths = Ext.manifest,\r
28353 ns;\r
28354
28355 if (appName && appFolder !== null) {\r
28356 manifestPaths = manifestPaths && manifestPaths.paths;\r
28357
28358
28359
28360
28361
28362 if (!manifestPaths || appFolder !== undefined) {\r
28363 Ext.Loader.setPath(appName, (appFolder === undefined) ? 'app' : appFolder);\r
28364 }\r
28365 }\r
28366 if (paths) {\r
28367 for (ns in paths) {\r
28368 if (paths.hasOwnProperty(ns)) {\r
28369 Ext.Loader.setPath(ns, paths[ns]);\r
28370 }\r
28371 }\r
28372 }\r
28373 }\r
28374 });\r
28375 \r
28376 Ext.getNamespace = Ext.app.getNamespace;\r
28377});\r
28378\r
28379\r
28380Ext.define('Ext.util.Filter', {\r
28381 isFilter: true,\r
28382 config: {\r
28383 \r
28384 property: null,\r
28385 \r
28386 value: null,\r
28387 \r
28388 filterFn: null,\r
28389 \r
28390 id: null,\r
28391 \r
28392 anyMatch: false,\r
28393 \r
28394 exactMatch: false,\r
28395 \r
28396 caseSensitive: false,\r
28397 \r
28398 disabled: false,\r
28399 \r
28400 disableOnEmpty: false,\r
28401 \r
28402 operator: null,\r
28403 \r
28404 root: null,\r
28405 \r
28406 serializer: null,\r
28407 \r
28408 convert: null\r
28409 },\r
28410 \r
28411 scope: null,\r
28412
28413
28414 $configStrict: false,\r
28415 statics: {\r
28416 \r
28417 createFilterFn: function(filters) {\r
28418 if (!filters) {\r
28419 return Ext.returnTrue;\r
28420 }\r
28421 return function(candidate) {\r
28422 var items = filters.isCollection ? filters.items : filters,\r
28423 length = items.length,\r
28424 match = true,\r
28425 i, filter;\r
28426 for (i = 0; match && i < length; i++) {\r
28427 filter = items[i];\r
28428
28429 if (!filter.getDisabled()) {\r
28430 match = filter.filter(candidate);\r
28431 }\r
28432 }\r
28433 return match;\r
28434 };\r
28435 },\r
28436 \r
28437 isInvalid: function(cfg) {\r
28438 if (!cfg.filterFn) {\r
28439
28440 if (!cfg.property) {\r
28441 return 'A Filter requires either a property or a filterFn to be set';\r
28442 }\r
28443 if (!cfg.hasOwnProperty('value') && !cfg.operator) {\r
28444 return 'A Filter requires either a property and value, or a filterFn to be set';\r
28445 }\r
28446 }\r
28447 return false;\r
28448 }\r
28449 },\r
28450 \r
28451 constructor: function(config) {\r
28452
28453 var warn = Ext.util.Filter.isInvalid(config);\r
28454 if (warn) {\r
28455 Ext.log.warn(warn);\r
28456 }\r
28457
28458 this.initConfig(config);\r
28459 },\r
28460 preventConvert: {\r
28461 'in': 1,\r
28462 notin: 1\r
28463 },\r
28464 filter: function(item) {\r
28465 var me = this,\r
28466 filterFn = me._filterFn || me.getFilterFn(),\r
28467 convert = me.getConvert(),\r
28468 value = me._value;\r
28469 me._filterValue = value;\r
28470 me.isDateValue = Ext.isDate(value);\r
28471 if (me.isDateValue) {\r
28472 me.dateValue = value.getTime();\r
28473 }\r
28474 if (convert && !me.preventConvert[me.getOperator()]) {\r
28475 me._filterValue = convert.call(me.scope || me, value);\r
28476 }\r
28477 return filterFn.call(me.scope || me, item);\r
28478 },\r
28479 getId: function() {\r
28480 var id = this._id;\r
28481 if (!id) {\r
28482 id = this.getProperty();\r
28483 if (!id) {\r
28484 id = Ext.id(null, 'ext-filter-');\r
28485 }\r
28486 this._id = id;\r
28487 }\r
28488 return id;\r
28489 },\r
28490 getFilterFn: function() {\r
28491 var me = this,\r
28492 filterFn = me._filterFn,\r
28493 operator;\r
28494 if (!filterFn) {\r
28495 operator = me.getOperator();\r
28496 if (operator) {\r
28497 filterFn = me.operatorFns[operator];\r
28498 } else {\r
28499
28500
28501
28502 filterFn = me.createRegexFilter();\r
28503 }\r
28504 me._filterFn = filterFn;\r
28505 }\r
28506 return filterFn;\r
28507 },\r
28508 \r
28509 createRegexFilter: function() {\r
28510 var me = this,\r
28511 anyMatch = !!me.getAnyMatch(),\r
28512 exact = !!me.getExactMatch(),\r
28513 value = me.getValue(),\r
28514 matcher = Ext.String.createRegex(value, !anyMatch,
28515 !anyMatch && exact,
28516 !me.getCaseSensitive());\r
28517 return function(item) {\r
28518 var val = me.getPropertyValue(item);\r
28519 return matcher ? matcher.test(val) : (val == null);\r
28520 };\r
28521 },\r
28522 \r
28523 getPropertyValue: function(item) {\r
28524 var root = this._root,\r
28525 value = (root == null) ? item : item[root];\r
28526 return value[this._property];\r
28527 },\r
28528 \r
28529 getState: function() {\r
28530 var config = this.getInitialConfig(),\r
28531 result = {},\r
28532 name;\r
28533 for (name in config) {\r
28534
28535
28536 if (config.hasOwnProperty(name)) {\r
28537 result[name] = config[name];\r
28538 }\r
28539 }\r
28540 delete result.root;\r
28541 result.value = this.getValue();\r
28542 return result;\r
28543 },\r
28544 getScope: function() {\r
28545 return this.scope;\r
28546 },\r
28547 \r
28548 serialize: function() {\r
28549 var result = this.getState(),\r
28550 serializer = this.getSerializer();\r
28551 delete result.id;\r
28552 delete result.serializer;\r
28553 if (serializer) {\r
28554 serializer.call(this, result);\r
28555 }\r
28556 return result;\r
28557 },\r
28558 updateOperator: function() {\r
28559 this._filterFn = null;\r
28560 },\r
28561 updateValue: function(value) {\r
28562 this._filterFn = null;\r
28563 if (this.getDisableOnEmpty()) {\r
28564 this.setDisabled(Ext.isEmpty(value));\r
28565 }\r
28566 },\r
28567 updateDisableOnEmpty: function(disableOnEmpty) {\r
28568 var disabled = false;\r
28569 if (disableOnEmpty) {\r
28570 disabled = Ext.isEmpty(this.getValue());\r
28571 }\r
28572 this.setDisabled(disabled);\r
28573 },\r
28574 privates: {\r
28575 getCandidateValue: function(candidate, v, preventCoerce) {\r
28576 var me = this,\r
28577 convert = me._convert,\r
28578 result = me.getPropertyValue(candidate);\r
28579 if (convert) {\r
28580 result = convert.call(me.scope || me, result);\r
28581 } else if (!preventCoerce) {\r
28582 result = Ext.coerce(result, v);\r
28583 }\r
28584 return result;\r
28585 }\r
28586 }\r
28587}, function() {\r
28588 var prototype = this.prototype,\r
28589 operatorFns = (prototype.operatorFns = {\r
28590 "<": function(candidate) {\r
28591 var v = this._filterValue;\r
28592 return this.getCandidateValue(candidate, v) < v;\r
28593 },\r
28594 "<=": function(candidate) {\r
28595 var v = this._filterValue;\r
28596 return this.getCandidateValue(candidate, v) <= v;\r
28597 },\r
28598 "=": function(candidate) {\r
28599 var me = this,\r
28600 v = me._filterValue;\r
28601 candidate = me.getCandidateValue(candidate, v);\r
28602 if (me.isDateValue && candidate instanceof Date) {\r
28603 candidate = candidate.getTime();\r
28604 v = me.dateValue;\r
28605 }\r
28606 return candidate == v;\r
28607 },\r
28608 "===": function(candidate) {\r
28609 var me = this,\r
28610 v = me._filterValue;\r
28611 candidate = me.getCandidateValue(candidate, v, true);\r
28612 if (me.isDateValue && candidate instanceof Date) {\r
28613 candidate = candidate.getTime();\r
28614 v = me.dateValue;\r
28615 }\r
28616 return candidate === v;\r
28617 },\r
28618 ">=": function(candidate) {\r
28619 var v = this._filterValue;\r
28620 return this.getCandidateValue(candidate, v) >= v;\r
28621 },\r
28622 ">": function(candidate) {\r
28623 var v = this._filterValue;\r
28624 return this.getCandidateValue(candidate, v) > v;\r
28625 },\r
28626 "!=": function(candidate) {\r
28627 var me = this,\r
28628 v = me._filterValue;\r
28629 candidate = me.getCandidateValue(candidate, v);\r
28630 if (me.isDateValue && candidate instanceof Date) {\r
28631 candidate = candidate.getTime();\r
28632 v = me.dateValue;\r
28633 }\r
28634 return candidate != v;\r
28635 },\r
28636 "!==": function(candidate) {\r
28637 var me = this,\r
28638 v = me._filterValue;\r
28639 candidate = me.getCandidateValue(candidate, v, true);\r
28640 if (me.isDateValue && candidate instanceof Date) {\r
28641 candidate = candidate.getTime();\r
28642 v = me.dateValue;\r
28643 }\r
28644 return candidate !== v;\r
28645 },\r
28646 "in": function(candidate) {\r
28647 var v = this._filterValue;\r
28648 return Ext.Array.contains(v, this.getCandidateValue(candidate, v));\r
28649 },\r
28650 notin: function(candidate) {\r
28651 var v = this._filterValue;\r
28652 return !Ext.Array.contains(v, this.getCandidateValue(candidate, v));\r
28653 },\r
28654 like: function(candidate) {\r
28655 var v = this._filterValue;\r
28656 return v && this.getCandidateValue(candidate, v).toLowerCase().indexOf(v.toLowerCase()) > -1;\r
28657 }\r
28658 });\r
28659
28660 operatorFns['=='] = operatorFns['='];\r
28661 operatorFns.gt = operatorFns['>'];\r
28662 operatorFns.ge = operatorFns['>='];\r
28663 operatorFns.lt = operatorFns['<'];\r
28664 operatorFns.le = operatorFns['<='];\r
28665 operatorFns.eq = operatorFns['='];\r
28666 operatorFns.ne = operatorFns['!='];\r
28667});\r
28668\r
28669\r
28670Ext.define('Ext.util.Observable', {\r
28671 extend: Ext.mixin.Observable,\r
28672
28673
28674 $applyConfigs: true\r
28675}, function(Observable) {\r
28676 var Super = Ext.mixin.Observable;\r
28677 \r
28678 Observable.releaseCapture = Super.releaseCapture;\r
28679 \r
28680 Observable.capture = Super.capture;\r
28681 \r
28682 Observable.captureArgs = Super.captureArgs;\r
28683 \r
28684 Observable.observe = Observable.observeClass = Super.observe;\r
28685});\r
28686\r
28687\r
28688Ext.define('Ext.util.AbstractMixedCollection', {\r
28689 mixins: {\r
28690 observable: Ext.util.Observable\r
28691 },\r
28692 \r
28693 isMixedCollection: true,\r
28694 \r
28695 generation: 0,\r
28696 \r
28697 indexGeneration: 0,\r
28698 constructor: function(allowFunctions, keyFn) {\r
28699 var me = this;\r
28700
28701 if (arguments.length === 1 && Ext.isObject(allowFunctions)) {\r
28702 me.initialConfig = allowFunctions;\r
28703 Ext.apply(me, allowFunctions);\r
28704 } else
28705 {\r
28706 me.allowFunctions = allowFunctions === true;\r
28707 if (keyFn) {\r
28708 me.getKey = keyFn;\r
28709 }\r
28710 me.initialConfig = {\r
28711 allowFunctions: me.allowFunctions,\r
28712 getKey: me.getKey\r
28713 };\r
28714 }\r
28715 me.items = [];\r
28716 me.map = {};\r
28717 me.keys = [];\r
28718 me.indexMap = {};\r
28719 me.length = 0;\r
28720 \r
28721 \r
28722 \r
28723 \r
28724 me.mixins.observable.constructor.call(me);\r
28725 },\r
28726 destroy: function() {\r
28727 var me = this;\r
28728 me.items = me.map = me.keys = me.indexMap = null;\r
28729 me.callParent();\r
28730 },\r
28731 \r
28732 allowFunctions: false,\r
28733 \r
28734 add: function(key, obj) {\r
28735 var len = this.length,\r
28736 out;\r
28737 if (arguments.length === 1) {\r
28738 out = this.insert(len, key);\r
28739 } else {\r
28740 out = this.insert(len, key, obj);\r
28741 }\r
28742 return out;\r
28743 },\r
28744 \r
28745 getKey: function(o) {\r
28746 return o.id;\r
28747 },\r
28748 \r
28749 replace: function(key, o) {\r
28750 var me = this,\r
28751 old, index;\r
28752 if (arguments.length == 1) {\r
28753 o = arguments[0];\r
28754 key = me.getKey(o);\r
28755 }\r
28756 old = me.map[key];\r
28757 if (typeof key == 'undefined' || key === null || typeof old == 'undefined') {\r
28758 return me.add(key, o);\r
28759 }\r
28760 me.generation++;\r
28761 index = me.indexOfKey(key);\r
28762 me.items[index] = o;\r
28763 me.map[key] = o;\r
28764 if (me.hasListeners.replace) {\r
28765 me.fireEvent('replace', key, old, o);\r
28766 }\r
28767 return o;\r
28768 },\r
28769 \r
28770 reorder: function(mapping) {\r
28771 var me = this,\r
28772 items = me.items,\r
28773 index = 0,\r
28774 length = items.length,\r
28775 order = [],\r
28776 remaining = [],\r
28777 oldIndex;\r
28778 me.suspendEvents();\r
28779
28780 for (oldIndex in mapping) {\r
28781 order[mapping[oldIndex]] = items[oldIndex];\r
28782 }\r
28783 for (index = 0; index < length; index++) {\r
28784 if (mapping[index] == undefined) {\r
28785 remaining.push(items[index]);\r
28786 }\r
28787 }\r
28788 for (index = 0; index < length; index++) {\r
28789 if (order[index] == undefined) {\r
28790 order[index] = remaining.shift();\r
28791 }\r
28792 }\r
28793 me.clear();\r
28794 me.addAll(order);\r
28795 me.resumeEvents();\r
28796 },\r
28797 \r
28798 updateKey: function(oldKey, newKey) {\r
28799 var me = this,\r
28800 map = me.map,\r
28801 index = me.indexOfKey(oldKey),\r
28802
28803 indexMap = me.indexMap,\r
28804 item;\r
28805 if (index > -1) {\r
28806 item = map[oldKey];\r
28807 delete map[oldKey];\r
28808 delete indexMap[oldKey];\r
28809 map[newKey] = item;\r
28810 indexMap[newKey] = index;\r
28811 me.keys[index] = newKey;\r
28812
28813
28814 me.indexGeneration = ++me.generation;\r
28815 }\r
28816 },\r
28817 \r
28818 addAll: function(objs) {\r
28819 var me = this,\r
28820 key;\r
28821 if (arguments.length > 1 || Ext.isArray(objs)) {\r
28822 me.insert(me.length, arguments.length > 1 ? arguments : objs);\r
28823 } else {\r
28824 for (key in objs) {\r
28825 if (objs.hasOwnProperty(key)) {\r
28826 if (me.allowFunctions || typeof objs[key] != 'function') {\r
28827 me.add(key, objs[key]);\r
28828 }\r
28829 }\r
28830 }\r
28831 }\r
28832 },\r
28833 \r
28834 each: function(fn, scope) {\r
28835 var items = Ext.Array.push([], this.items),\r
28836
28837 i = 0,\r
28838 len = items.length,\r
28839 item;\r
28840 for (; i < len; i++) {\r
28841 item = items[i];\r
28842 if (fn.call(scope || item, item, i, len) === false) {\r
28843 break;\r
28844 }\r
28845 }\r
28846 },\r
28847 \r
28848 eachKey: function(fn, scope) {\r
28849 var keys = this.keys,\r
28850 items = this.items,\r
28851 i = 0,\r
28852 len = keys.length;\r
28853 for (; i < len; i++) {\r
28854 fn.call(scope || window, keys[i], items[i], i, len);\r
28855 }\r
28856 },\r
28857 \r
28858 findBy: function(fn, scope) {\r
28859 var keys = this.keys,\r
28860 items = this.items,\r
28861 i = 0,\r
28862 len = items.length;\r
28863 for (; i < len; i++) {\r
28864 if (fn.call(scope || window, items[i], keys[i])) {\r
28865 return items[i];\r
28866 }\r
28867 }\r
28868 return null;\r
28869 },\r
28870 \r
28871 insert: function(index, key, obj) {\r
28872 var out;\r
28873 if (Ext.isIterable(key)) {\r
28874 out = this.doInsert(index, key, obj);\r
28875 } else {\r
28876 if (arguments.length > 2) {\r
28877 out = this.doInsert(index, [\r
28878 key\r
28879 ], [\r
28880 obj\r
28881 ]);\r
28882 } else {\r
28883 out = this.doInsert(index, [\r
28884 key\r
28885 ]);\r
28886 }\r
28887 out = out[0];\r
28888 }\r
28889 return out;\r
28890 },\r
28891
28892 doInsert: function(index, keys, objects) {\r
28893 var me = this,\r
28894 itemKey, removeIndex, i,\r
28895 len = keys.length,\r
28896 deDupedLen = len,\r
28897 fireAdd = me.hasListeners.add,\r
28898 syncIndices,\r
28899 newKeys = {},\r
28900 passedDuplicates, oldKeys, oldObjects;\r
28901
28902
28903 if (objects != null) {\r
28904 me.useLinearSearch = true;\r
28905 } else
28906 {\r
28907 objects = keys;\r
28908 keys = new Array(len);\r
28909 for (i = 0; i < len; i++) {\r
28910 keys[i] = this.getKey(objects[i]);\r
28911 }\r
28912 }\r
28913
28914 me.suspendEvents();\r
28915 for (i = 0; i < len; i++) {\r
28916 itemKey = keys[i];\r
28917
28918 removeIndex = me.indexOfKey(itemKey);\r
28919 if (removeIndex !== -1) {\r
28920 if (removeIndex < index) {\r
28921 index--;\r
28922 }\r
28923 me.removeAt(removeIndex);\r
28924 }\r
28925 if (itemKey != null) {\r
28926
28927 if (newKeys[itemKey] != null) {\r
28928 passedDuplicates = true;\r
28929 deDupedLen--;\r
28930 }\r
28931 newKeys[itemKey] = i;\r
28932 }\r
28933 }\r
28934 me.resumeEvents();\r
28935
28936 if (passedDuplicates) {\r
28937 oldKeys = keys;\r
28938 oldObjects = objects;\r
28939 keys = new Array(deDupedLen);\r
28940 objects = new Array(deDupedLen);\r
28941 i = 0;\r
28942
28943
28944 for (itemKey in newKeys) {\r
28945 keys[i] = oldKeys[newKeys[itemKey]];\r
28946 objects[i] = oldObjects[newKeys[itemKey]];\r
28947 i++;\r
28948 }\r
28949 len = deDupedLen;\r
28950 }\r
28951
28952 syncIndices = index === me.length && me.indexGeneration === me.generation;\r
28953
28954 Ext.Array.insert(me.items, index, objects);\r
28955 Ext.Array.insert(me.keys, index, keys);\r
28956 me.length += len;\r
28957 me.generation++;\r
28958 if (syncIndices) {\r
28959 me.indexGeneration = me.generation;\r
28960 }\r
28961 for (i = 0; i < len; i++ , index++) {\r
28962 itemKey = keys[i];\r
28963 if (itemKey != null) {\r
28964 me.map[itemKey] = objects[i];\r
28965
28966 if (syncIndices) {\r
28967 me.indexMap[itemKey] = index;\r
28968 }\r
28969 }\r
28970 if (fireAdd) {\r
28971 me.fireEvent('add', index, objects[i], itemKey);\r
28972 }\r
28973 }\r
28974 return objects;\r
28975 },\r
28976 \r
28977 remove: function(o) {\r
28978 var me = this,\r
28979 removeKey, index;\r
28980
28981
28982
28983
28984
28985 if (!me.useLinearSearch && (removeKey = me.getKey(o))) {\r
28986 index = me.indexOfKey(removeKey);\r
28987 } else
28988 {\r
28989 index = Ext.Array.indexOf(me.items, o);\r
28990 }\r
28991 return (index === -1) ? false : me.removeAt(index);\r
28992 },\r
28993 \r
28994 removeAll: function(items) {\r
28995 var me = this,\r
28996 i;\r
28997 if (items || me.hasListeners.remove) {\r
28998
28999 if (items) {\r
29000 for (i = items.length - 1; i >= 0; --i) {\r
29001 me.remove(items[i]);\r
29002 }\r
29003 } else {\r
29004 while (me.length) {\r
29005 me.removeAt(0);\r
29006 }\r
29007 }\r
29008 } else {\r
29009 me.length = me.items.length = me.keys.length = 0;\r
29010 me.map = {};\r
29011 me.indexMap = {};\r
29012 me.generation++;\r
29013 me.indexGeneration = me.generation;\r
29014 }\r
29015 },\r
29016 \r
29017 removeAt: function(index) {\r
29018 var me = this,\r
29019 o, key;\r
29020 if (index < me.length && index >= 0) {\r
29021 me.length--;\r
29022 o = me.items[index];\r
29023 Ext.Array.erase(me.items, index, 1);\r
29024 key = me.keys[index];\r
29025 if (typeof key != 'undefined') {\r
29026 delete me.map[key];\r
29027 }\r
29028 Ext.Array.erase(me.keys, index, 1);\r
29029 if (me.hasListeners.remove) {\r
29030 me.fireEvent('remove', o, key);\r
29031 }\r
29032 me.generation++;\r
29033 return o;\r
29034 }\r
29035 return false;\r
29036 },\r
29037 \r
29038 removeRange: function(index, removeCount) {\r
29039 var me = this,\r
29040 o, key, i, limit, syncIndices, trimming;\r
29041 if (index < me.length && index >= 0) {\r
29042 if (!removeCount) {\r
29043 removeCount = 1;\r
29044 }\r
29045 limit = Math.min(index + removeCount, me.length);\r
29046 removeCount = limit - index;\r
29047
29048 trimming = limit === me.length;\r
29049 syncIndices = trimming && me.indexGeneration === me.generation;\r
29050
29051 for (i = index; i < limit; i++) {\r
29052 key = me.keys[i];\r
29053 if (key != null) {\r
29054 delete me.map[key];\r
29055 if (syncIndices) {\r
29056 delete me.indexMap[key];\r
29057 }\r
29058 }\r
29059 }\r
29060
29061 o = me.items[i - 1];\r
29062 me.length -= removeCount;\r
29063 me.generation++;\r
29064 if (syncIndices) {\r
29065 me.indexGeneration = me.generation;\r
29066 }\r
29067
29068
29069
29070
29071 if (trimming) {\r
29072 me.items.length = me.keys.length = me.length;\r
29073 } else {\r
29074 me.items.splice(index, removeCount);\r
29075 me.keys.splice(index, removeCount);\r
29076 }\r
29077
29078 return o;\r
29079 }\r
29080 return false;\r
29081 },\r
29082 \r
29083 removeAtKey: function(key) {\r
29084 var me = this,\r
29085 keys = me.keys,\r
29086 i;\r
29087
29088 if (key == null) {\r
29089 for (i = keys.length - 1; i >= 0; i--) {\r
29090 if (keys[i] == null) {\r
29091 me.removeAt(i);\r
29092 }\r
29093 }\r
29094 } else
29095 {\r
29096 return me.removeAt(me.indexOfKey(key));\r
29097 }\r
29098 },\r
29099 \r
29100 getCount: function() {\r
29101 return this.length;\r
29102 },\r
29103 \r
29104 indexOf: function(o) {\r
29105 var me = this,\r
29106 key;\r
29107 if (o != null) {\r
29108
29109
29110
29111
29112
29113 if (!me.useLinearSearch && (key = me.getKey(o))) {\r
29114 return this.indexOfKey(key);\r
29115 }\r
29116
29117 return Ext.Array.indexOf(me.items, o);\r
29118 }\r
29119
29120 return -1;\r
29121 },\r
29122 \r
29123 indexOfKey: function(key) {\r
29124 if (!this.map.hasOwnProperty(key)) {\r
29125 return -1;\r
29126 }\r
29127 if (this.indexGeneration !== this.generation) {\r
29128 this.rebuildIndexMap();\r
29129 }\r
29130 return this.indexMap[key];\r
29131 },\r
29132 rebuildIndexMap: function() {\r
29133 var me = this,\r
29134 indexMap = me.indexMap = {},\r
29135 keys = me.keys,\r
29136 len = keys.length,\r
29137 i;\r
29138 for (i = 0; i < len; i++) {\r
29139 indexMap[keys[i]] = i;\r
29140 }\r
29141 me.indexGeneration = me.generation;\r
29142 },\r
29143 \r
29144 get: function(key) {\r
29145 var me = this,\r
29146 mk = me.map[key],\r
29147 item = mk !== undefined ? mk : (typeof key == 'number') ? me.items[key] : undefined;\r
29148 return typeof item != 'function' || me.allowFunctions ? item : null;\r
29149 },\r
29150
29151 \r
29152 getAt: function(index) {\r
29153 return this.items[index];\r
29154 },\r
29155 \r
29156 getByKey: function(key) {\r
29157 return this.map[key];\r
29158 },\r
29159 \r
29160 contains: function(o) {\r
29161 var me = this,\r
29162 key;\r
29163 if (o != null) {\r
29164
29165
29166
29167
29168
29169 if (!me.useLinearSearch && (key = me.getKey(o))) {\r
29170 return this.map[key] != null;\r
29171 }\r
29172
29173 return Ext.Array.indexOf(this.items, o) !== -1;\r
29174 }\r
29175 return false;\r
29176 },\r
29177 \r
29178 containsKey: function(key) {\r
29179 return this.map.hasOwnProperty(key);\r
29180 },\r
29181 \r
29182 clear: function() {\r
29183 var me = this;\r
29184
29185 if (me.generation) {\r
29186 me.length = 0;\r
29187 me.items = [];\r
29188 me.keys = [];\r
29189 me.map = {};\r
29190 me.indexMap = {};\r
29191 me.generation++;\r
29192 me.indexGeneration = me.generation;\r
29193 }\r
29194 if (me.hasListeners.clear) {\r
29195 me.fireEvent('clear');\r
29196 }\r
29197 },\r
29198 \r
29199 first: function() {\r
29200 return this.items[0];\r
29201 },\r
29202 \r
29203 last: function() {\r
29204 return this.items[this.length - 1];\r
29205 },\r
29206 \r
29207 sum: function(property, root, start, end) {\r
29208 var values = this.extractValues(property, root),\r
29209 length = values.length,\r
29210 sum = 0,\r
29211 i;\r
29212 start = start || 0;\r
29213 end = (end || end === 0) ? end : length - 1;\r
29214 for (i = start; i <= end; i++) {\r
29215 sum += values[i];\r
29216 }\r
29217 return sum;\r
29218 },\r
29219 \r
29220 collect: function(property, root, allowNull) {\r
29221 var values = this.extractValues(property, root),\r
29222 length = values.length,\r
29223 hits = {},\r
29224 unique = [],\r
29225 value, strValue, i;\r
29226 for (i = 0; i < length; i++) {\r
29227 value = values[i];\r
29228 strValue = String(value);\r
29229 if ((allowNull || !Ext.isEmpty(value)) && !hits[strValue]) {\r
29230 hits[strValue] = true;\r
29231 unique.push(value);\r
29232 }\r
29233 }\r
29234 return unique;\r
29235 },\r
29236 \r
29237 extractValues: function(property, root) {\r
29238 var values = this.items;\r
29239 if (root) {\r
29240 values = Ext.Array.pluck(values, root);\r
29241 }\r
29242 return Ext.Array.pluck(values, property);\r
29243 },\r
29244 \r
29245 hasRange: function(start, end) {\r
29246 return (end < this.length);\r
29247 },\r
29248 \r
29249 getRange: function(start, end) {\r
29250 var me = this,\r
29251 items = me.items,\r
29252 range = [],\r
29253 len = items.length,\r
29254 tmp, reverse;\r
29255 if (len < 1) {\r
29256 return range;\r
29257 }\r
29258 if (start > end) {\r
29259 reverse = true;\r
29260 tmp = start;\r
29261 start = end;\r
29262 end = tmp;\r
29263 }\r
29264 if (start < 0) {\r
29265 start = 0;\r
29266 }\r
29267 if (end == null || end >= len) {\r
29268 end = len - 1;\r
29269 }\r
29270 range = items.slice(start, end + 1);\r
29271 if (reverse && range.length) {\r
29272 range.reverse();\r
29273 }\r
29274 return range;\r
29275 },\r
29276 \r
29277 filter: function(property, value, anyMatch, caseSensitive) {\r
29278 var filters = [];\r
29279
29280 if (Ext.isString(property)) {\r
29281 filters.push(new Ext.util.Filter({\r
29282 property: property,\r
29283 value: value,\r
29284 anyMatch: anyMatch,\r
29285 caseSensitive: caseSensitive\r
29286 }));\r
29287 } else if (Ext.isArray(property) || property instanceof Ext.util.Filter) {\r
29288 filters = filters.concat(property);\r
29289 }\r
29290
29291
29292
29293 return this.filterBy(Ext.util.Filter.createFilterFn(filters));\r
29294 },\r
29295 \r
29296 filterBy: function(fn, scope) {\r
29297 var me = this,\r
29298 newMC = new me.self(me.initialConfig),\r
29299 keys = me.keys,\r
29300 items = me.items,\r
29301 length = items.length,\r
29302 i;\r
29303 newMC.getKey = me.getKey;\r
29304 for (i = 0; i < length; i++) {\r
29305 if (fn.call(scope || me, items[i], keys[i])) {\r
29306 newMC.add(keys[i], items[i]);\r
29307 }\r
29308 }\r
29309
29310
29311
29312 newMC.useLinearSearch = me.useLinearSearch;\r
29313 return newMC;\r
29314 },\r
29315 \r
29316 findIndex: function(property, value, start, anyMatch, caseSensitive) {\r
29317 if (Ext.isEmpty(value, false)) {\r
29318 return -1;\r
29319 }\r
29320 value = this.createValueMatcher(value, anyMatch, caseSensitive);\r
29321 return this.findIndexBy(function(o) {\r
29322 return o && value.test(o[property]);\r
29323 }, null, start);\r
29324 },\r
29325 \r
29326 findIndexBy: function(fn, scope, start) {\r
29327 var me = this,\r
29328 keys = me.keys,\r
29329 items = me.items,\r
29330 i = start || 0,\r
29331 len = items.length;\r
29332 for (; i < len; i++) {\r
29333 if (fn.call(scope || me, items[i], keys[i])) {\r
29334 return i;\r
29335 }\r
29336 }\r
29337 return -1;\r
29338 },\r
29339 \r
29340 createValueMatcher: function(value, anyMatch, caseSensitive, exactMatch) {\r
29341 if (!value.exec) {\r
29342
29343 var er = Ext.String.escapeRegex;\r
29344 value = String(value);\r
29345 if (anyMatch === true) {\r
29346 value = er(value);\r
29347 } else {\r
29348 value = '^' + er(value);\r
29349 if (exactMatch === true) {\r
29350 value += '$';\r
29351 }\r
29352 }\r
29353 value = new RegExp(value, caseSensitive ? '' : 'i');\r
29354 }\r
29355 return value;\r
29356 },\r
29357 \r
29358 clone: function() {\r
29359 var me = this,\r
29360 copy = new me.self(me.initialConfig);\r
29361 copy.add(me.keys, me.items);\r
29362
29363
29364
29365 copy.useLinearSearch = me.useLinearSearch;\r
29366 return copy;\r
29367 }\r
29368});\r
29369\r
29370\r
29371Ext.define('Ext.util.Sorter', {\r
29372 isSorter: true,\r
29373 config: {\r
29374 \r
29375 property: null,\r
29376 \r
29377 sorterFn: null,\r
29378 \r
29379 root: null,\r
29380 \r
29381 transform: null,\r
29382 \r
29383 direction: "ASC",\r
29384 \r
29385 id: undefined\r
29386 },\r
29387 statics: {\r
29388 \r
29389 createComparator: function(sorters, nextFn) {\r
29390 nextFn = nextFn || 0;\r
29391 return function(lhs, rhs) {\r
29392 var items = sorters.isCollection ? sorters.items : sorters,\r
29393 n = items.length,\r
29394 comp, i;\r
29395 for (i = 0; i < n; ++i) {\r
29396 comp = items[i].sort(lhs, rhs);\r
29397 if (comp) {\r
29398 return comp;\r
29399 }\r
29400 }\r
29401 return nextFn && nextFn(lhs, rhs);\r
29402 };\r
29403 }\r
29404 },\r
29405 \r
29406 multiplier: 1,\r
29407 constructor: function(config) {\r
29408
29409 if (config && !this.isGrouper) {\r
29410 if (!config.property === !config.sorterFn) {\r
29411
29412 Ext.raise("A Sorter requires either a property or a sorterFn.");\r
29413 }\r
29414 }\r
29415
29416 this.initConfig(config);\r
29417 },\r
29418 getId: function() {\r
29419 var id = this._id;\r
29420 if (!id) {\r
29421 id = this.getProperty();\r
29422 if (!id) {\r
29423 id = Ext.id(null, 'ext-sorter-');\r
29424 }\r
29425 this._id = id;\r
29426 }\r
29427 return id;\r
29428 },\r
29429 sort: function(lhs, rhs) {\r
29430 return this.multiplier * this.sortFn(lhs, rhs);\r
29431 },\r
29432 \r
29433 sortFn: function(item1, item2) {\r
29434 var me = this,\r
29435 transform = me._transform,\r
29436 root = me._root,\r
29437 property = me._property,\r
29438 lhs, rhs;\r
29439 if (root) {\r
29440 item1 = item1[root];\r
29441 item2 = item2[root];\r
29442 }\r
29443 lhs = item1[property];\r
29444 rhs = item2[property];\r
29445 if (transform) {\r
29446 lhs = transform(lhs);\r
29447 rhs = transform(rhs);\r
29448 }\r
29449 return (lhs > rhs) ? 1 : (lhs < rhs ? -1 : 0);\r
29450 },\r
29451 applyDirection: function(direction) {\r
29452 return direction ? direction : 'ASC';\r
29453 },\r
29454 updateDirection: function(direction) {\r
29455 this.multiplier = (direction.toUpperCase() === "DESC") ? -1 : 1;\r
29456 },\r
29457 updateProperty: function(property) {\r
29458 if (property) {\r
29459
29460 delete this.sortFn;\r
29461 }\r
29462 },\r
29463 updateSorterFn: function(sorterFn) {\r
29464
29465 this.sortFn = sorterFn;\r
29466 },\r
29467 \r
29468 toggle: function() {\r
29469 this.setDirection(Ext.String.toggle(this.getDirection(), "ASC", "DESC"));\r
29470 },\r
29471 \r
29472 getState: function() {\r
29473 var me = this,\r
29474 result = {\r
29475 root: me.getRoot(),\r
29476 property: me.getProperty(),\r
29477 direction: me.getDirection()\r
29478 };\r
29479
29480
29481 if (me._id) {\r
29482 result.id = me._id;\r
29483 }\r
29484 return result;\r
29485 },\r
29486 \r
29487 serialize: function() {\r
29488 return {\r
29489 property: this.getProperty(),\r
29490 direction: this.getDirection()\r
29491 };\r
29492 }\r
29493});\r
29494\r
29495\r
29496Ext.define("Ext.util.Sortable", {\r
29497 \r
29498 isSortable: true,\r
29499 $configPrefixed: false,\r
29500 $configStrict: false,\r
29501 config: {\r
29502 \r
29503 sorters: null\r
29504 },\r
29505 \r
29506 defaultSortDirection: "ASC",\r
29507 \r
29508 \r
29509 multiSortLimit: 3,\r
29510 statics: {\r
29511 \r
29512 createComparator: function(sorters) {\r
29513 return sorters && sorters.length ? function(r1, r2) {\r
29514 var result = sorters[0].sort(r1, r2),\r
29515 length = sorters.length,\r
29516 i = 1;\r
29517
29518
29519 for (; !result && i < length; i++) {\r
29520 result = sorters[i].sort.call(sorters[i], r1, r2);\r
29521 }\r
29522 return result;\r
29523 } : function() {\r
29524 return 0;\r
29525 };\r
29526 }\r
29527 },\r
29528 \r
29529 applySorters: function(sorters) {\r
29530 var me = this,\r
29531 sortersCollection = me.getSorters() || new Ext.util.MixedCollection(false, Ext.returnId);\r
29532
29533 if (sorters) {\r
29534 sortersCollection.addAll(me.decodeSorters(sorters));\r
29535 }\r
29536 return sortersCollection;\r
29537 },\r
29538 \r
29539 sort: function(sorters, direction, insertionPosition, doSort) {\r
29540 var me = this,\r
29541 sorter, overFlow,\r
29542 currentSorters = me.getSorters();\r
29543 if (!currentSorters) {\r
29544 me.setSorters(null);\r
29545 currentSorters = me.getSorters();\r
29546 }\r
29547 if (Ext.isArray(sorters)) {\r
29548 doSort = insertionPosition;\r
29549 insertionPosition = direction;\r
29550 } else if (Ext.isObject(sorters)) {\r
29551 sorters = [\r
29552 sorters\r
29553 ];\r
29554 doSort = insertionPosition;\r
29555 insertionPosition = direction;\r
29556 } else if (Ext.isString(sorters)) {\r
29557 sorter = currentSorters.get(sorters);\r
29558 if (!sorter) {\r
29559 sorter = {\r
29560 property: sorters,\r
29561 direction: direction\r
29562 };\r
29563 } else if (direction == null) {\r
29564 sorter.toggle();\r
29565 } else {\r
29566 sorter.setDirection(direction);\r
29567 }\r
29568 sorters = [\r
29569 sorter\r
29570 ];\r
29571 }\r
29572 if (sorters && sorters.length) {\r
29573 sorters = me.decodeSorters(sorters);\r
29574 switch (insertionPosition) {\r
29575
29576
29577
29578
29579 case "multi":\r
29580
29581 currentSorters.insert(0, sorters[0]);\r
29582
29583 overFlow = currentSorters.getCount() - me.multiSortLimit;\r
29584 if (overFlow > 0) {\r
29585 currentSorters.removeRange(me.multiSortLimit, overFlow);\r
29586 };\r
29587 break;\r
29588 case "prepend":\r
29589 currentSorters.insert(0, sorters);\r
29590 break;\r
29591 case "append":\r
29592 currentSorters.addAll(sorters);\r
29593 break;\r
29594 case undefined:\r
29595 case null:\r
29596 case "replace":\r
29597 currentSorters.clear();\r
29598 currentSorters.addAll(sorters);\r
29599 break;\r
29600 default:\r
29601
29602 Ext.raise('Sorter insertion point must be "multi", "prepend", "append" or "replace"');\r
29603 }\r
29604 }\r
29605
29606 if (doSort !== false) {\r
29607 me.fireEvent('beforesort', me, sorters);\r
29608 me.onBeforeSort(sorters);\r
29609 if (me.getSorterCount()) {\r
29610
29611 me.doSort(me.generateComparator());\r
29612 }\r
29613 }\r
29614 return sorters;\r
29615 },\r
29616 \r
29617 getSorterCount: function() {\r
29618 return this.getSorters().items.length;\r
29619 },\r
29620 \r
29621 generateComparator: function() {\r
29622 var sorters = this.getSorters().getRange();\r
29623 return sorters.length ? this.createComparator(sorters) : this.emptyComparator;\r
29624 },\r
29625 emptyComparator: function() {\r
29626 return 0;\r
29627 },\r
29628 onBeforeSort: Ext.emptyFn,\r
29629 \r
29630 decodeSorters: function(sorters) {\r
29631 if (!Ext.isArray(sorters)) {\r
29632 if (sorters === undefined) {\r
29633 sorters = [];\r
29634 } else {\r
29635 sorters = [\r
29636 sorters\r
29637 ];\r
29638 }\r
29639 }\r
29640 var length = sorters.length,\r
29641 Sorter = Ext.util.Sorter,\r
29642 model = this.getModel ? this.getModel() : this.model,\r
29643 field, config, i;\r
29644 for (i = 0; i < length; i++) {\r
29645 config = sorters[i];\r
29646 if (!(config instanceof Sorter)) {\r
29647 if (Ext.isString(config)) {\r
29648 config = {\r
29649 property: config\r
29650 };\r
29651 }\r
29652 Ext.applyIf(config, {\r
29653 root: this.sortRoot,\r
29654 direction: "ASC"\r
29655 });\r
29656
29657 if (config.fn) {\r
29658 config.sorterFn = config.fn;\r
29659 }\r
29660
29661 if (typeof config == 'function') {\r
29662 config = {\r
29663 sorterFn: config\r
29664 };\r
29665 }\r
29666
29667 if (model && !config.transform) {\r
29668 field = model.getField(config.property);\r
29669 config.transform = field && field.sortType !== Ext.identityFn ? field.sortType : undefined;\r
29670 }\r
29671 sorters[i] = new Ext.util.Sorter(config);\r
29672 }\r
29673 }\r
29674 return sorters;\r
29675 },\r
29676 \r
29677 getFirstSorter: function() {\r
29678 var sorters = this.getSorters().items,\r
29679 len = sorters.length,\r
29680 i = 0,\r
29681 sorter;\r
29682 for (; i < len; ++i) {\r
29683 sorter = sorters[i];\r
29684 if (!sorter.isGrouper) {\r
29685 return sorter;\r
29686 }\r
29687 }\r
29688 return null;\r
29689 }\r
29690}, function() {\r
29691
29692 this.prototype.createComparator = this.createComparator;\r
29693});\r
29694\r
29695\r
29696Ext.define('Ext.util.MixedCollection', {\r
29697 extend: Ext.util.AbstractMixedCollection,\r
29698 mixins: {\r
29699 sortable: Ext.util.Sortable\r
29700 },\r
29701 \r
29702 \r
29703 constructor: function() {\r
29704 this.initConfig();\r
29705 this.callParent(arguments);\r
29706 },\r
29707 doSort: function(sorterFn) {\r
29708 this.sortBy(sorterFn);\r
29709 },\r
29710 \r
29711 _sort: function(property, dir, fn) {\r
29712 var me = this,\r
29713 i, len,\r
29714 dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1,\r
29715
29716 c = [],\r
29717 keys = me.keys,\r
29718 items = me.items,\r
29719 o;\r
29720
29721 fn = fn || function(a, b) {\r
29722 return a - b;\r
29723 };\r
29724
29725 for (i = 0 , len = items.length; i < len; i++) {\r
29726 c[c.length] = {\r
29727 key: keys[i],\r
29728 value: items[i],\r
29729 index: i\r
29730 };\r
29731 }\r
29732
29733 Ext.Array.sort(c, function(a, b) {\r
29734 return fn(a[property], b[property]) * dsc ||
29735 (a.index < b.index ? -1 : 1);\r
29736 });\r
29737
29738
29739 for (i = 0 , len = c.length; i < len; i++) {\r
29740 o = c[i];\r
29741 items[i] = o.value;\r
29742 keys[i] = o.key;\r
29743 me.indexMap[o.key] = i;\r
29744 }\r
29745 me.generation++;\r
29746 me.indexGeneration = me.generation;\r
29747 me.fireEvent('sort', me);\r
29748 },\r
29749 \r
29750 sortBy: function(sorterFn) {\r
29751 var me = this,\r
29752 items = me.items,\r
29753 item,\r
29754 keys = me.keys,\r
29755 key,\r
29756 length = items.length,\r
29757 i;\r
29758
29759 for (i = 0; i < length; i++) {\r
29760 items[i].$extCollectionIndex = i;\r
29761 }\r
29762 Ext.Array.sort(items, function(a, b) {\r
29763 return sorterFn(a, b) ||
29764 (a.$extCollectionIndex < b.$extCollectionIndex ? -1 : 1);\r
29765 });\r
29766
29767 for (i = 0; i < length; i++) {\r
29768 item = items[i];\r
29769 key = me.getKey(item);\r
29770 keys[i] = key;\r
29771 me.indexMap[key] = i;\r
29772 delete items.$extCollectionIndex;\r
29773 }\r
29774 me.generation++;\r
29775 me.indexGeneration = me.generation;\r
29776 me.fireEvent('sort', me, items, keys);\r
29777 },\r
29778 \r
29779 findInsertionIndex: function(newItem, sorterFn) {\r
29780 var me = this,\r
29781 items = me.items,\r
29782 start = 0,\r
29783 end = items.length - 1,\r
29784 middle, comparison;\r
29785 if (!sorterFn) {\r
29786 sorterFn = me.generateComparator();\r
29787 }\r
29788 while (start <= end) {\r
29789 middle = (start + end) >> 1;\r
29790 comparison = sorterFn(newItem, items[middle]);\r
29791 if (comparison >= 0) {\r
29792 start = middle + 1;\r
29793 } else if (comparison < 0) {\r
29794 end = middle - 1;\r
29795 }\r
29796 }\r
29797 return start;\r
29798 },\r
29799 \r
29800 reorder: function(mapping) {\r
29801 this.callParent([\r
29802 mapping\r
29803 ]);\r
29804 this.fireEvent('sort', this);\r
29805 },\r
29806 \r
29807 sortByKey: function(dir, fn) {\r
29808 this._sort('key', dir, fn || function(a, b) {\r
29809 var v1 = String(a).toUpperCase(),\r
29810 v2 = String(b).toUpperCase();\r
29811 return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);\r
29812 });\r
29813 }\r
29814});\r
29815\r
29816\r
29817Ext.define('Ext.util.CollectionKey', {\r
29818 mixins: [\r
29819 Ext.mixin.Identifiable\r
29820 ],\r
29821 isCollectionKey: true,\r
29822 observerPriority: -200,\r
29823 config: {\r
29824 collection: null,\r
29825 \r
29826 keyFn: null,\r
29827 \r
29828 property: null,\r
29829 \r
29830 rootProperty: null,\r
29831 unique: true\r
29832 },\r
29833 \r
29834 generation: 0,\r
29835 \r
29836 map: null,\r
29837 \r
29838 mapRebuilds: 0,\r
29839 \r
29840 constructor: function(config) {\r
29841 this.initConfig(config);\r
29842
29843 if (!Ext.isFunction(this.getKey)) {\r
29844 Ext.raise('CollectionKey requires a keyFn or property config');\r
29845 }\r
29846 },\r
29847
29848 \r
29849 get: function(key) {\r
29850 var map = this.map || this.getMap();\r
29851 return map[key] || null;\r
29852 },\r
29853 \r
29854 clear: function() {\r
29855 this.map = null;\r
29856 },\r
29857 getRootProperty: function() {\r
29858 var me = this,\r
29859 root = this.callParent();\r
29860 return root !== null ? root : me.getCollection().getRootProperty();\r
29861 },\r
29862 \r
29863 indexOf: function(key, startAt) {\r
29864 var map = this.map || this.getMap(),\r
29865 item = map[key],\r
29866 collection = this.getCollection(),\r
29867 length = collection.length,\r
29868 i, index, items, n;\r
29869 if (!item) {\r
29870 return -1;\r
29871 }\r
29872 if (startAt === undefined) {\r
29873 startAt = -1;\r
29874 }\r
29875 if (item instanceof Array) {\r
29876 items = item;\r
29877 index = length;\r
29878
29879 for (n = items.length; n-- > 0; ) {\r
29880 i = collection.indexOf(items[n]);\r
29881 if (i < index && i > startAt) {\r
29882 index = i;\r
29883 }\r
29884 }\r
29885 if (index === length) {\r
29886 return -1;\r
29887 }\r
29888 } else {\r
29889 index = collection.indexOf(item);\r
29890 }\r
29891 return (index > startAt) ? index : -1;\r
29892 },\r
29893 \r
29894 updateKey: function(item, oldKey) {\r
29895 var me = this,\r
29896 map = me.map,\r
29897 bucket, index;\r
29898 if (map) {\r
29899 bucket = map[oldKey];\r
29900 if (bucket instanceof Array) {\r
29901 index = Ext.Array.indexOf(bucket, item);\r
29902 if (index >= 0) {\r
29903 if (bucket.length > 2) {\r
29904 bucket.splice(index, 1);\r
29905 } else {\r
29906
29907
29908
29909 map[oldKey] = bucket[1 - index];\r
29910 }\r
29911 }\r
29912 }\r
29913
29914 else if (bucket) {\r
29915
29916 if (me.getUnique() && bucket !== item) {\r
29917 Ext.raise('Incorrect oldKey "' + oldKey + '" for item with newKey "' + me.getKey(item) + '"');\r
29918 }\r
29919
29920 delete map[oldKey];\r
29921 }\r
29922 me.add([\r
29923 item\r
29924 ]);\r
29925 }\r
29926 },\r
29927
29928
29929 onCollectionAdd: function(collection, add) {\r
29930 if (this.map) {\r
29931 this.add(add.items);\r
29932 }\r
29933 },\r
29934 onCollectionItemChange: function(collection, details) {\r
29935 this.map = null;\r
29936 },\r
29937 onCollectionRefresh: function() {\r
29938 this.map = null;\r
29939 },\r
29940 onCollectionRemove: function(collection, remove) {\r
29941 var me = this,\r
29942 map = me.map,\r
29943 items = remove.items,\r
29944 length = items.length,\r
29945 i, item, key;\r
29946 if (map) {\r
29947 if (me.getUnique() && length < collection.length / 2) {\r
29948 for (i = 0; i < length; ++i) {\r
29949 key = me.getKey(item = items[i]);\r
29950 delete map[key];\r
29951 }\r
29952 } else {\r
29953 me.map = null;\r
29954 }\r
29955 }\r
29956 },\r
29957
29958
29959 add: function(items) {\r
29960 var me = this,\r
29961 map = me.map,\r
29962 bucket, i, item, key, length, unique;\r
29963 length = items.length;\r
29964 unique = me.getUnique();\r
29965 for (i = 0; i < length; ++i) {\r
29966 key = me.getKey(item = items[i]);\r
29967 if (unique || !(key in map)) {\r
29968 map[key] = item;\r
29969 } else {\r
29970 if (!((bucket = map[key]) instanceof Array)) {\r
29971 map[key] = bucket = [\r
29972 bucket\r
29973 ];\r
29974 }\r
29975 bucket.push(item);\r
29976 }\r
29977 }\r
29978 },\r
29979 applyKeyFn: function(keyFn) {\r
29980 if (Ext.isString(keyFn)) {\r
29981 this.getKey = function(item) {\r
29982 return item[keyFn]();\r
29983 };\r
29984 } else {\r
29985 this.getKey = keyFn;\r
29986 }\r
29987 },\r
29988 updateProperty: function(property) {\r
29989 var root = this.getRootProperty();\r
29990 this.getKey = function(item) {\r
29991 return (root ? item[root] : item)[property];\r
29992 };\r
29993 },\r
29994 getMap: function() {\r
29995 var me = this,\r
29996 map = me.map;\r
29997 if (!map) {\r
29998 me.map = map = {};\r
29999 me.keysByItemKey = {};\r
30000 ++me.mapRebuilds;\r
30001 me.add(me.getCollection().items);\r
30002 }\r
30003 return map;\r
30004 },\r
30005 updateCollection: function(collection) {\r
30006 collection.addObserver(this);\r
30007 },\r
30008 clone: function() {\r
30009 return new Ext.util.CollectionKey(this.getCurrentConfig());\r
30010 }\r
30011});\r
30012\r
30013\r
30014Ext.define('Ext.util.Grouper', {\r
30015 extend: Ext.util.Sorter,\r
30016 isGrouper: true,\r
30017 config: {\r
30018 \r
30019 groupFn: null,\r
30020 \r
30021 \r
30022 sortProperty: null\r
30023 },\r
30024 constructor: function(config) {\r
30025
30026 if (config) {\r
30027 if (config.getGroupString) {\r
30028 Ext.raise("Cannot set getGroupString - use groupFn instead");\r
30029 }\r
30030 }\r
30031
30032 this.callParent(arguments);\r
30033 },\r
30034 \r
30035 getGroupString: function(item) {\r
30036 var group = this._groupFn(item);\r
30037 return (group != null) ? String(group) : '';\r
30038 },\r
30039 sortFn: function(item1, item2) {\r
30040 var me = this,\r
30041 lhs = me._groupFn(item1),\r
30042 rhs = me._groupFn(item2),\r
30043 property = me._sortProperty,\r
30044
30045 root = me._root,\r
30046 sorterFn = me._sorterFn,\r
30047 transform = me._transform;\r
30048
30049
30050 if (lhs === rhs) {\r
30051 return 0;\r
30052 }\r
30053 if (property || sorterFn) {\r
30054 if (sorterFn) {\r
30055 return sorterFn.call(this, item1, item2);\r
30056 }\r
30057 if (root) {\r
30058 item1 = item1[root];\r
30059 item2 = item2[root];\r
30060 }\r
30061 lhs = item1[property];\r
30062 rhs = item2[property];\r
30063 if (transform) {\r
30064 lhs = transform(lhs);\r
30065 rhs = transform(rhs);\r
30066 }\r
30067 }\r
30068 return (lhs > rhs) ? 1 : (lhs < rhs ? -1 : 0);\r
30069 },\r
30070 standardGroupFn: function(item) {\r
30071 var root = this._root;\r
30072 return (root ? item[root] : item)[this._property];\r
30073 },\r
30074 updateSorterFn: function() {},\r
30075
30076 updateProperty: function() {\r
30077
30078 if (!this.getGroupFn()) {\r
30079 this.setGroupFn(this.standardGroupFn);\r
30080 }\r
30081 }\r
30082});\r
30083\r
30084\r
30085Ext.define('Ext.util.Collection', {\r
30086 mixins: [\r
30087 Ext.mixin.Observable\r
30088 ],\r
30089 \r
30090 isCollection: true,\r
30091 config: {\r
30092 autoFilter: true,\r
30093 autoSort: true,\r
30094 \r
30095 autoGroup: true,\r
30096 \r
30097 decoder: null,\r
30098 \r
30099 extraKeys: null,\r
30100 \r
30101 filters: null,\r
30102 \r
30103 grouper: null,\r
30104 \r
30105 groups: null,\r
30106 \r
30107 rootProperty: null,\r
30108 \r
30109 sorters: null,\r
30110 \r
30111 multiSortLimit: 3,\r
30112 \r
30113 defaultSortDirection: 'ASC',\r
30114 \r
30115 source: null,\r
30116 \r
30117 trackGroups: true\r
30118 },\r
30119 \r
30120 generation: 0,\r
30121 \r
30122 indices: null,\r
30123 \r
30124 indexRebuilds: 0,\r
30125 \r
30126 updating: 0,\r
30127 \r
30128 grouped: false,\r
30129 \r
30130 sorted: false,\r
30131 \r
30132 filtered: false,\r
30133 \r
30134 $endUpdatePriority: 1001,\r
30135 \r
30136 \r
30137 \r
30138 \r
30139 \r
30140 \r
30141 \r
30142 \r
30143 \r
30144 \r
30145 constructor: function(config) {\r
30146 var me = this;\r
30147 \r
30148 me.items = [];\r
30149 \r
30150 me.map = {};\r
30151 \r
30152 me.length = 0;\r
30153 \r
30154 if (config && config.keyFn) {\r
30155 me.getKey = config.keyFn;\r
30156 }\r
30157 me.mixins.observable.constructor.call(me, config);\r
30158 },\r
30159 \r
30160 destroy: function() {\r
30161 var me = this,\r
30162 filters = me._filters,\r
30163 sorters = me._sorters,\r
30164 groups = me._groups;\r
30165 if (filters) {\r
30166 filters.destroy();\r
30167 me._filters = null;\r
30168 }\r
30169 if (sorters) {\r
30170 sorters.destroy();\r
30171 me._sorters = null;\r
30172 }\r
30173 if (groups) {\r
30174 groups.destroy();\r
30175 me._groups = null;\r
30176 }\r
30177 me.setSource(null);\r
30178 me.observers = me.items = me.map = null;\r
30179 me.callParent();\r
30180 },\r
30181 \r
30182 add: function(item) {\r
30183 var me = this,\r
30184 items = me.decodeItems(arguments, 0),\r
30185 ret = items;\r
30186 if (items.length) {\r
30187 me.requestedIndex = me.length;\r
30188 me.splice(me.length, 0, items);\r
30189 delete me.requestedIndex;\r
30190 ret = (items.length === 1) ? items[0] : items;\r
30191 }\r
30192 return ret;\r
30193 },\r
30194 \r
30195 replaceAll: function() {\r
30196 var me = this,\r
30197 ret, items;\r
30198 items = me.decodeItems(arguments, 0);\r
30199 ret = items;\r
30200 if (items.length) {\r
30201 me.splice(0, me.length, items);\r
30202 ret = (items.length === 1) ? items[0] : items;\r
30203 } else {\r
30204 me.removeAll();\r
30205 }\r
30206 return ret;\r
30207 },\r
30208 \r
30209 aggregate: function(property, operation, begin, end, scope) {\r
30210 var me = this,\r
30211 args = Ext.Array.slice(arguments);\r
30212 args.unshift(me.items);\r
30213 return me.aggregateItems.apply(me, args);\r
30214 },\r
30215 \r
30216 aggregateByGroup: function(property, operation, scope) {\r
30217 var groups = this.getGroups();\r
30218 return this.aggregateGroups(groups, property, operation, scope);\r
30219 },\r
30220 \r
30221 aggregateItems: function(items, property, operation, begin, end, scope) {\r
30222 var me = this,\r
30223 range = Ext.Number.clipIndices(items.length, [\r
30224 begin,\r
30225 end\r
30226 ]),\r
30227
30228 subsetRequested = (begin !== 0 && end !== items.length),\r
30229 i, j, rangeLen, root, value, values, valueItems;\r
30230 begin = range[0];\r
30231 end = range[1];\r
30232 if (!Ext.isFunction(operation)) {\r
30233 operation = me._aggregators[operation];\r
30234 return operation.call(me, items, begin, end, property, me.getRootProperty());\r
30235 }\r
30236 root = me.getRootProperty();\r
30237
30238
30239 values = new Array(rangeLen);\r
30240 valueItems = subsetRequested ? new Array(rangeLen) : items;\r
30241
30242 for (i = begin , j = 0; i < end; ++i , j++) {\r
30243 if (subsetRequested) {\r
30244 valueItems[j] = value = items[i];\r
30245 }\r
30246 values[j] = (root ? value[root] : value)[property];\r
30247 }\r
30248 return operation.call(scope || me, items, values, 0);\r
30249 },\r
30250 \r
30251 aggregateGroups: function(groups, property, operation, scope) {\r
30252 var items = groups.items,\r
30253 len = items.length,\r
30254 callDirect = !Ext.isFunction(operation),\r
30255 out = {},\r
30256 i, group, result;\r
30257 for (i = 0; i < len; ++i) {\r
30258 group = items[i];\r
30259 if (!callDirect) {\r
30260 result = this.aggregateItems(group.items, property, operation, null, null, scope);\r
30261 } else {\r
30262 result = group[operation](property);\r
30263 }\r
30264 out[group.getGroupKey()] = result;\r
30265 }\r
30266 return out;\r
30267 },\r
30268 \r
30269 beginUpdate: function() {\r
30270 if (!this.updating++) {\r
30271
30272 this.notify('beginupdate');\r
30273 }\r
30274 },\r
30275 \r
30276 clear: function() {\r
30277 var me = this,\r
30278 generation = me.generation,\r
30279 ret = generation ? me.items : [],\r
30280 extraKeys, indexName;\r
30281 if (generation) {\r
30282 me.items = [];\r
30283 me.length = 0;\r
30284 me.map = {};\r
30285 me.indices = {};\r
30286 me.generation++;\r
30287
30288 extraKeys = me.getExtraKeys();\r
30289 if (extraKeys) {\r
30290 for (indexName in extraKeys) {\r
30291 extraKeys[indexName].clear();\r
30292 }\r
30293 }\r
30294 }\r
30295 return ret;\r
30296 },\r
30297 \r
30298 clone: function() {\r
30299 var me = this,\r
30300 copy = new me.self(me.initialConfig);\r
30301 copy.add(me.items);\r
30302 return copy;\r
30303 },\r
30304 \r
30305 collect: function(property, root, allowNull) {\r
30306 var items = this.items,\r
30307 length = items.length,\r
30308 map = {},\r
30309 ret = [],\r
30310 i, strValue, value;\r
30311 for (i = 0; i < length; ++i) {\r
30312 value = items[i];\r
30313 value = (root ? value[root] : value)[property];\r
30314 strValue = String(value);\r
30315 if ((allowNull || !Ext.isEmpty(value)) && !map[strValue]) {\r
30316 map[strValue] = 1;\r
30317 ret.push(value);\r
30318 }\r
30319 }\r
30320 return ret;\r
30321 },\r
30322 \r
30323 contains: function(item) {\r
30324 var ret = false,\r
30325 key;\r
30326 if (item != null) {\r
30327 key = this.getKey(item);\r
30328 ret = this.map[key] === item;\r
30329 }\r
30330 return ret;\r
30331 },\r
30332 \r
30333 containsKey: function(key) {\r
30334 return key in this.map;\r
30335 },\r
30336 \r
30337 createFiltered: function(property, value, anyMatch, caseSensitive, exactMatch) {\r
30338 var me = this,\r
30339 ret = new me.self(me.initialConfig),\r
30340 root = me.getRootProperty(),\r
30341 items = me.items,\r
30342 length, i, filters, fn, scope;\r
30343 if (Ext.isFunction(property)) {\r
30344 fn = property;\r
30345 scope = value;\r
30346 } else {\r
30347
30348 if (Ext.isString(property)) {\r
30349 filters = [\r
30350 new Ext.util.Filter({\r
30351 property: property,\r
30352 value: value,\r
30353 root: root,\r
30354 anyMatch: anyMatch,\r
30355 caseSensitive: caseSensitive,\r
30356 exactMatch: exactMatch\r
30357 })\r
30358 ];\r
30359 } else if (property instanceof Ext.util.Filter) {\r
30360 filters = [\r
30361 property\r
30362 ];\r
30363 property.setRoot(root);\r
30364 } else if (Ext.isArray(property)) {\r
30365 filters = property.slice(0);\r
30366 for (i = 0 , length = filters.length; i < length; ++i) {\r
30367 filters[i].setRoot(root);\r
30368 }\r
30369 }\r
30370
30371
30372
30373 fn = Ext.util.Filter.createFilterFn(filters);\r
30374 }\r
30375 scope = scope || me;\r
30376 for (i = 0 , length = items.length; i < length; i++) {\r
30377 if (fn.call(scope, items[i])) {\r
30378 ret.add(items[i]);\r
30379 }\r
30380 }\r
30381 return ret;\r
30382 },\r
30383 \r
30384 filterBy: function(fn, scope) {\r
30385 return this.createFiltered(fn, scope);\r
30386 },\r
30387 \r
30388 each: function(fn, scope) {\r
30389 var items = this.items,\r
30390 len = items.length,\r
30391 i, ret;\r
30392 if (len) {\r
30393 scope = scope || this;\r
30394 items = items.slice(0);\r
30395
30396 for (i = 0; i < len; i++) {\r
30397 ret = fn.call(scope, items[i], i, len);\r
30398 if (ret === false) {\r
30399 break;\r
30400 }\r
30401 }\r
30402 }\r
30403 return ret;\r
30404 },\r
30405 \r
30406 eachKey: function(fn, scope) {\r
30407 var me = this,\r
30408 items = me.items,\r
30409 len = items.length,\r
30410 i, item, key, ret;\r
30411 if (len) {\r
30412 scope = scope || me;\r
30413 items = items.slice(0);\r
30414
30415 for (i = 0; i < len; i++) {\r
30416 key = me.getKey(item = items[i]);\r
30417 ret = fn.call(scope, key, item, i, len);\r
30418 if (ret === false) {\r
30419 break;\r
30420 }\r
30421 }\r
30422 }\r
30423 return ret;\r
30424 },\r
30425 \r
30426 endUpdate: function() {\r
30427 if (!--this.updating) {\r
30428 this.notify('endupdate');\r
30429 }\r
30430 },\r
30431 \r
30432 find: function(property, value, start, startsWith, endsWith, ignoreCase) {\r
30433 if (Ext.isEmpty(value, false)) {\r
30434 return null;\r
30435 }\r
30436 var regex = Ext.String.createRegex(value, startsWith, endsWith, ignoreCase),\r
30437 root = this.getRootProperty();\r
30438 return this.findBy(function(item) {\r
30439 return item && regex.test((root ? item[root] : item)[property]);\r
30440 }, null, start);\r
30441 },\r
30442 \r
30443 findBy: function(fn, scope, start) {\r
30444 var me = this,\r
30445 items = me.items,\r
30446 len = items.length,\r
30447 i, item, key;\r
30448 scope = scope || me;\r
30449 for (i = start || 0; i < len; i++) {\r
30450 key = me.getKey(item = items[i]);\r
30451 if (fn.call(scope, item, key)) {\r
30452 return items[i];\r
30453 }\r
30454 }\r
30455 return null;\r
30456 },\r
30457 \r
30458 findIndex: function(property, value, start, startsWith, endsWith, ignoreCase) {\r
30459 var item = this.find(property, value, start, startsWith, endsWith, ignoreCase);\r
30460 return item ? this.indexOf(item) : -1;\r
30461 },\r
30462 \r
30463 findIndexBy: function(fn, scope, start) {\r
30464 var item = this.findBy(fn, scope, start);\r
30465 return item ? this.indexOf(item) : -1;\r
30466 },\r
30467 \r
30468 first: function(grouped) {\r
30469 var groups = grouped ? this.getGroups() : undefined;\r
30470 return groups ? this.aggregateGroups(groups, null, 'first') : this.items[0];\r
30471 },\r
30472 \r
30473 last: function(grouped) {\r
30474 var groups = grouped ? this.getGroups() : undefined;\r
30475 return groups ? this.aggregateGroups(groups, null, 'last') : this.items[this.length - 1];\r
30476 },\r
30477 \r
30478 get: function(key) {\r
30479 return this.map[key];\r
30480 },\r
30481 \r
30482 getAt: function(index) {\r
30483 return this.items[index];\r
30484 },\r
30485 \r
30486 getByKey: function(key) {\r
30487 return this.map[key];\r
30488 },\r
30489 \r
30490 getCount: function() {\r
30491 return this.length;\r
30492 },\r
30493 \r
30494 getKey: function(item) {\r
30495 var id = item.id;\r
30496 return (id === 0 || id) ? id : ((id = item._id) === 0 || id) ? id : item.getId();\r
30497 },\r
30498 \r
30499 getRange: function(begin, end) {\r
30500 var items = this.items,\r
30501 length = items.length,\r
30502 range;\r
30503
30504 if (begin > end) {\r
30505 Ext.raise('Inverted range passed to Collection.getRange: [' + begin + ',' + end + ']');\r
30506 }\r
30507
30508 if (!length) {\r
30509 range = [];\r
30510 } else {\r
30511 range = Ext.Number.clipIndices(length, [\r
30512 begin,\r
30513 end\r
30514 ]);\r
30515 range = items.slice(range[0], range[1]);\r
30516 }\r
30517 return range;\r
30518 },\r
30519 \r
30520 \r
30521 getValues: function(property, root, start, end) {\r
30522 var items = this.items,\r
30523 range = Ext.Number.clipIndices(items.length, [\r
30524 start,\r
30525 end\r
30526 ]),\r
30527 ret = [],\r
30528 i, value;\r
30529 for (i = range[0] , end = range[1]; i < end; ++i) {\r
30530 value = items[i];\r
30531 value = (root ? value[root] : value)[property];\r
30532 ret.push(value);\r
30533 }\r
30534 return ret;\r
30535 },\r
30536 \r
30537 indexOf: function(item) {\r
30538 if (!item) {\r
30539 return -1;\r
30540 }\r
30541 var key = this.getKey(item);\r
30542 return this.indexOfKey(key);\r
30543 },\r
30544 \r
30545 indexOfKey: function(key) {\r
30546 var me = this,\r
30547 indices = me.indices;\r
30548 if (key in me.map) {\r
30549 if (!indices) {\r
30550 indices = me.getIndices();\r
30551 }\r
30552 return indices[key];\r
30553 }\r
30554 return -1;\r
30555 },\r
30556 \r
30557 insert: function(index, item) {\r
30558 var me = this,\r
30559 items = me.decodeItems(arguments, 1),\r
30560 ret = items;\r
30561 if (items.length) {\r
30562 me.requestedIndex = index;\r
30563 me.splice(index, 0, items);\r
30564 delete me.requestedIndex;\r
30565 ret = (items.length === 1) ? items[0] : items;\r
30566 }\r
30567 return ret;\r
30568 },\r
30569 \r
30570 itemChanged: function(item, modified, oldKey, \r
30571 meta) {\r
30572 var me = this,\r
30573 keyChanged = oldKey === 0 || !!oldKey,\r
30574 filtered = me.filtered && me.getAutoFilter(),\r
30575 filterChanged = false,\r
30576 itemMovement = 0,\r
30577 items = me.items,\r
30578 last = me.length - 1,\r
30579 sorted = me.sorted && last > 0 && me.getAutoSort(),\r
30580
30581
30582
30583
30584 source = me.getSource(),\r
30585 toRemove = 0,\r
30586 itemFiltered = false,\r
30587 wasFiltered = false,\r
30588 details, newKey, sortFn, toAdd, index, newIndex;\r
30589
30590 if (source && !source.updating) {\r
30591 source.itemChanged(item, modified, oldKey, meta);\r
30592 } else
30593
30594 {\r
30595 newKey = me.getKey(item);\r
30596 if (filtered) {\r
30597 index = me.indexOfKey(keyChanged ? oldKey : newKey);\r
30598 wasFiltered = (index < 0);\r
30599 itemFiltered = me.isItemFiltered(item);\r
30600 filterChanged = (wasFiltered !== itemFiltered);\r
30601 }\r
30602 if (filterChanged) {\r
30603 if (itemFiltered) {\r
30604 toRemove = [\r
30605 item\r
30606 ];\r
30607 newIndex = -1;\r
30608 } else {\r
30609 toAdd = [\r
30610 item\r
30611 ];\r
30612 newIndex = me.length;\r
30613 }\r
30614 }\r
30615
30616
30617
30618 else if (sorted && !itemFiltered) {\r
30619
30620
30621 if (!filtered) {\r
30622
30623
30624 index = me.indexOfKey(keyChanged ? oldKey : newKey);\r
30625 }\r
30626 sortFn = me.getSortFn();\r
30627 if (index !== -1) {\r
30628 if (index && sortFn(items[index - 1], items[index]) > 0) {\r
30629
30630
30631
30632 itemMovement = -1;\r
30633
30634
30635 newIndex = Ext.Array.binarySearch(items, item, 0, index, sortFn);\r
30636 } else if (index < last && sortFn(items[index], items[index + 1]) > 0) {\r
30637
30638
30639
30640 itemMovement = 1;\r
30641
30642
30643 newIndex = Ext.Array.binarySearch(items, item, index + 1, sortFn);\r
30644 }\r
30645 if (itemMovement) {\r
30646 toAdd = [\r
30647 item\r
30648 ];\r
30649 }\r
30650 }\r
30651 }\r
30652
30653
30654
30655
30656
30657
30658 details = {\r
30659 item: item,\r
30660 key: newKey,\r
30661 index: newIndex,\r
30662 filterChanged: filterChanged,\r
30663 keyChanged: keyChanged,\r
30664 indexChanged: !!itemMovement,\r
30665 filtered: itemFiltered,\r
30666 oldIndex: index,\r
30667 newIndex: newIndex,\r
30668 wasFiltered: wasFiltered,\r
30669 meta: meta\r
30670 };\r
30671 if (keyChanged) {\r
30672 details.oldKey = oldKey;\r
30673 }\r
30674 if (modified) {\r
30675 details.modified = modified;\r
30676 }\r
30677 me.beginUpdate();\r
30678 me.notify('beforeitemchange', [\r
30679 details\r
30680 ]);\r
30681 if (keyChanged) {\r
30682 me.updateKey(item, oldKey);\r
30683 }\r
30684 if (toAdd || toRemove) {\r
30685
30686
30687
30688
30689
30690 me.splice(newIndex, toRemove, toAdd);\r
30691 }\r
30692
30693
30694
30695
30696
30697
30698
30699
30700
30701
30702
30703
30704
30705
30706
30707
30708
30709
30710
30711
30712
30713
30714
30715 if (itemMovement > 0) {\r
30716 details.newIndex--;\r
30717 } else if (itemMovement < 0) {\r
30718 details.oldIndex++;\r
30719 }\r
30720
30721
30722
30723 me.notify(itemFiltered ? 'filtereditemchange' : 'itemchange', [\r
30724 details\r
30725 ]);\r
30726 me.endUpdate();\r
30727 }\r
30728 },\r
30729 \r
30730 remove: function(item) {\r
30731 var me = this,\r
30732 items = me.decodeRemoveItems(arguments, 0),\r
30733 length = me.length;\r
30734 me.splice(0, items);\r
30735 return length - me.length;\r
30736 },\r
30737 \r
30738 removeAll: function() {\r
30739 var me = this,\r
30740 length = me.length;\r
30741 if (me.generation && length) {\r
30742 me.splice(0, length);\r
30743 }\r
30744 return me;\r
30745 },\r
30746 \r
30747 removeAt: function(index, count) {\r
30748 var me = this,\r
30749 length = me.length,\r
30750 Num = Ext.Number,\r
30751 range = Num.clipIndices(length, [\r
30752 index,\r
30753 (count === undefined) ? 1 : count\r
30754 ], Num.Clip.COUNT),\r
30755 n = range[0],\r
30756 removeCount = range[1] - n,\r
30757 item = (removeCount === 1) && me.getAt(n),\r
30758 removed;\r
30759 me.splice(n, removeCount);\r
30760 removed = me.length - length;\r
30761 return (item && removed) ? item : removed;\r
30762 },\r
30763 \r
30764 removeByKey: function(key) {\r
30765 var item = this.getByKey(key);\r
30766 if (!item || !this.remove(item)) {\r
30767 return false;\r
30768 }\r
30769 return item;\r
30770 },\r
30771 \r
30772 replace: function(item) {\r
30773 var index = this.indexOf(item);\r
30774 if (index === -1) {\r
30775 this.add(item);\r
30776 } else {\r
30777 this.insert(index, item);\r
30778 }\r
30779 },\r
30780 \r
30781 splice: function(index, toRemove, toAdd) {\r
30782 var me = this,\r
30783 autoSort = me.sorted && me.getAutoSort(),\r
30784 map = me.map,\r
30785 items = me.items,\r
30786 length = me.length,\r
30787 removeItems = (toRemove instanceof Array) ? me.decodeRemoveItems(toRemove) : null,\r
30788 isRemoveCount = !removeItems,\r
30789 Num = Ext.Number,\r
30790 range = Num.clipIndices(length, [\r
30791 index,\r
30792 isRemoveCount ? toRemove : 0\r
30793 ], Num.Clip.COUNT),\r
30794 begin = range[0],\r
30795 end = range[1],\r
30796
30797 removeCount = end - begin,\r
30798 newItems = me.decodeItems(arguments, 2),\r
30799 newCount = newItems ? newItems.length : 0,\r
30800 addItems, newItemsMap, removeMap,\r
30801 insertAt = begin,\r
30802 indices = me.indices || ((newCount || removeItems) ? me.getIndices() : null),\r
30803 adds = null,\r
30804 removes = removeCount ? [\r
30805 begin\r
30806 ] : null,\r
30807 newKeys = null,\r
30808 source = me.getSource(),\r
30809 chunk, chunkItems, chunks, i, item, itemIndex, k, key, keys, n, duplicates, sorters, end;\r
30810 if (source && !source.updating) {\r
30811
30812
30813
30814
30815 if (isRemoveCount) {\r
30816 removeItems = [];\r
30817 for (i = 0; i < removeCount; ++i) {\r
30818 removeItems.push(items[begin + i]);\r
30819 }\r
30820 }\r
30821 if (begin < length) {\r
30822
30823
30824 i = source.indexOf(items[begin]);\r
30825 } else {\r
30826
30827 i = source.length;\r
30828 }\r
30829 source.splice(i, removeItems, newItems);\r
30830 return me;\r
30831 }\r
30832
30833
30834
30835
30836 if (newCount) {\r
30837 addItems = newItems;\r
30838 newKeys = [];\r
30839 newItemsMap = {};\r
30840
30841
30842
30843
30844 if (autoSort) {\r
30845
30846 sorters = me.getSorters();\r
30847 if (newCount > 1) {\r
30848 if (!addItems.$cloned) {\r
30849 newItems = addItems = addItems.slice(0);\r
30850 }\r
30851 me.sortData(addItems);\r
30852 }\r
30853 }\r
30854 for (i = 0; i < newCount; ++i) {\r
30855 key = me.getKey(item = newItems[i]);\r
30856 if ((k = newItemsMap[key]) !== undefined) {\r
30857
30858
30859
30860 (duplicates || (duplicates = {}))[k] = 1;\r
30861 } else {\r
30862
30863
30864
30865 itemIndex = indices[key];\r
30866 if (itemIndex < begin || end <= itemIndex) {\r
30867 (removes || (removes = [])).push(itemIndex);\r
30868 }\r
30869 }\r
30870
30871 newItemsMap[key] = i;\r
30872
30873 newKeys.push(key);\r
30874 }\r
30875
30876 if (duplicates) {\r
30877 keys = newKeys;\r
30878 addItems = [];\r
30879 newKeys = [];\r
30880 addItems.$cloned = true;\r
30881 for (i = 0; i < newCount; ++i) {\r
30882 if (!duplicates[i]) {\r
30883 item = newItems[i];\r
30884 addItems.push(item);\r
30885 newKeys.push(keys[i]);\r
30886 }\r
30887 }\r
30888 newCount = addItems.length;\r
30889 }\r
30890 adds = {\r
30891
30892
30893
30894 items: addItems,\r
30895 keys: newKeys\r
30896 };\r
30897 }\r
30898
30899 for (i = removeItems ? removeItems.length : 0; i-- > 0; ) {\r
30900 key = me.getKey(removeItems[i]);\r
30901 if ((itemIndex = indices[key]) !== undefined) {\r
30902
30903 (removes || (removes = [])).push(itemIndex);\r
30904 }\r
30905 }\r
30906
30907 if (!adds && !removes) {\r
30908 return me;\r
30909 }\r
30910 me.beginUpdate();\r
30911
30912
30913
30914 if (removes) {\r
30915 chunk = null;\r
30916 chunks = [];\r
30917 removeMap = {};\r
30918 if (removes.length > 1) {\r
30919 removes.sort(Ext.Array.numericSortFn);\r
30920 }\r
30921
30922
30923 for (i = 0 , n = removes.length; i < n; ++i) {\r
30924 key = me.getKey(item = items[itemIndex = removes[i]]);\r
30925 if (!(key in map)) {\r
30926 \r
30927 continue;\r
30928 }\r
30929
30930
30931 delete map[key];\r
30932
30933
30934
30935
30936
30937
30938
30939
30940
30941 if (!chunk || itemIndex > (chunk.at + chunkItems.length)) {\r
30942 chunks.push(chunk = {\r
30943 at: itemIndex,\r
30944 items: (chunkItems = []),\r
30945 keys: (keys = []),\r
30946 map: removeMap,\r
30947 next: chunk,\r
30948 replacement: adds\r
30949 });\r
30950
30951 if (adds) {\r
30952 adds.replaced = chunk;\r
30953 }\r
30954 }\r
30955 chunkItems.push(removeMap[key] = item);\r
30956 keys.push(key);\r
30957 if (itemIndex < insertAt) {\r
30958
30959
30960
30961
30962
30963
30964
30965
30966
30967
30968
30969
30970
30971
30972
30973
30974
30975
30976
30977
30978
30979
30980
30981
30982 --insertAt;\r
30983 }\r
30984 if (removeCount > 1 && itemIndex === begin) {\r
30985
30986
30987
30988
30989
30990
30991 --removeCount;\r
30992
30993 removes[i--] = ++begin;\r
30994 }\r
30995 }\r
30996
30997
30998 if (adds) {\r
30999 adds.at = insertAt;\r
31000 }\r
31001
31002
31003
31004 for (k = chunks.length; k-- > 0; ) {\r
31005 chunk = chunks[k];\r
31006 i = chunk.at;\r
31007 n = chunk.items.length;\r
31008 if (i + n < length) {\r
31009
31010
31011
31012 me.indices = indices = null;\r
31013 }\r
31014 me.length = length -= n;\r
31015
31016
31017
31018
31019 items.splice(i, n);\r
31020 if (indices) {\r
31021 keys = chunk.keys;\r
31022 for (i = 0; i < n; ++i) {\r
31023 delete indices[keys[i]];\r
31024 }\r
31025 }\r
31026 ++me.generation;\r
31027 me.notify('remove', [\r
31028 chunk\r
31029 ]);\r
31030 }\r
31031 }\r
31032
31033 if (adds) {\r
31034 if (autoSort && newCount > 1 && length) {\r
31035 me.spliceMerge(addItems, newKeys);\r
31036 } else {\r
31037 if (autoSort) {\r
31038 if (newCount > 1) {\r
31039
31040 insertAt = 0;\r
31041 me.indices = indices = null;\r
31042 } else {\r
31043
31044
31045 insertAt = sorters.findInsertionIndex(adds.items[0], items, me.getSortFn());\r
31046 }\r
31047 }\r
31048 if (insertAt === length) {\r
31049 end = insertAt;\r
31050
31051
31052 for (i = addItems.length - 1; i >= 0; --i) {\r
31053 items[end + i] = addItems[i];\r
31054 }\r
31055
31056
31057 indices = me.indices;\r
31058 if (indices) {\r
31059 for (i = 0; i < newCount; ++i) {\r
31060 indices[newKeys[i]] = insertAt + i;\r
31061 }\r
31062 }\r
31063 } else {\r
31064
31065 me.indices = null;\r
31066 Ext.Array.insert(items, insertAt, addItems);\r
31067 }\r
31068 for (i = 0; i < newCount; ++i) {\r
31069 map[newKeys[i]] = addItems[i];\r
31070 }\r
31071 me.length += newCount;\r
31072 adds.at = insertAt;\r
31073 adds.atItem = insertAt === 0 ? null : items[insertAt - 1];\r
31074 ++me.generation;\r
31075 me.notify('add', [\r
31076 adds\r
31077 ]);\r
31078 }\r
31079 }\r
31080
31081 me.endUpdate();\r
31082 return me;\r
31083 },\r
31084 \r
31085 update: function(fn, scope) {\r
31086 var me = this;\r
31087 me.beginUpdate();\r
31088 try {\r
31089 return fn.call(scope || me, me);\r
31090 } catch (e) {\r
31091
31092 Ext.log.error(this.$className + ': Unhandled Exception: ', e.description || e.message);\r
31093
31094 throw e;\r
31095 } finally {\r
31096 me.endUpdate();\r
31097 }\r
31098 },\r
31099 \r
31100 updateKey: function(item, oldKey) {\r
31101 var me = this,\r
31102 map = me.map,\r
31103 indices = me.indices,\r
31104 source = me.getSource(),\r
31105 newKey;\r
31106 if (source && !source.updating) {\r
31107
31108
31109 source.updateKey(item, oldKey);\r
31110 } else if ((newKey = me.getKey(item)) !== oldKey) {\r
31111
31112
31113 if (map[oldKey] === item && !(newKey in map)) {\r
31114 delete map[oldKey];\r
31115
31116
31117
31118 me.updating++;\r
31119 me.generation++;\r
31120 map[newKey] = item;\r
31121 if (indices) {\r
31122 indices[newKey] = indices[oldKey];\r
31123 delete indices[oldKey];\r
31124 }\r
31125 me.notify('updatekey', [\r
31126 {\r
31127 item: item,\r
31128 newKey: newKey,\r
31129 oldKey: oldKey\r
31130 }\r
31131 ]);\r
31132 me.updating--;\r
31133 } else
31134 {\r
31135
31136
31137
31138 if (newKey in map && map[newKey] !== item) {\r
31139
31140
31141 Ext.raise('Duplicate newKey "' + newKey + '" for item with oldKey "' + oldKey + '"');\r
31142 }\r
31143 if (oldKey in map && map[oldKey] !== item) {\r
31144
31145
31146
31147 Ext.raise('Incorrect oldKey "' + oldKey + '" for item with newKey "' + newKey + '"');\r
31148 }\r
31149 }\r
31150 }\r
31151 },\r
31152
31153 findInsertIndex: function(item) {\r
31154 var source = this.getSource(),\r
31155 sourceItems = source.items,\r
31156 i = source.indexOf(item) - 1,\r
31157 sourceItem, index;\r
31158 while (i > -1) {\r
31159 sourceItem = sourceItems[i];\r
31160 index = this.indexOf(sourceItem);\r
31161 if (index > -1) {\r
31162 return index + 1;\r
31163 }\r
31164 --i;\r
31165 }\r
31166
31167
31168 return 0;\r
31169 },\r
31170
31171
31172 \r
31173 onCollectionAdd: function(source, details) {\r
31174 var me = this,\r
31175 atItem = details.atItem,\r
31176 items = details.items,\r
31177 requestedIndex = me.requestedIndex,\r
31178 filtered, index, copy, i, item, n;\r
31179
31180 if (!me.sorted) {\r
31181
31182
31183 if (requestedIndex !== undefined) {\r
31184 index = requestedIndex;\r
31185 } else if (atItem) {\r
31186 index = me.indexOf(atItem);\r
31187 if (index === -1) {\r
31188
31189
31190
31191 index = me.findInsertIndex(items[0]);\r
31192 } else {\r
31193
31194 ++index;\r
31195 }\r
31196 } else {\r
31197
31198 index = 0;\r
31199 }\r
31200 }\r
31201 if (me.getAutoFilter() && me.filtered) {\r
31202 for (i = 0 , n = items.length; i < n; ++i) {\r
31203 item = items[i];\r
31204 if (me.isItemFiltered(item)) {\r
31205
31206
31207 if (!copy) {\r
31208 copy = items.slice(0, i);\r
31209 }\r
31210 if (!filtered) {\r
31211 filtered = [];\r
31212 }\r
31213 filtered.push(item);\r
31214 } else if (copy) {\r
31215
31216
31217 copy.push(item);\r
31218 }\r
31219 }\r
31220 }\r
31221 me.splice((index < 0) ? me.length : index, 0, copy || items);\r
31222 if (filtered) {\r
31223
31224
31225 me.notify('filteradd', [\r
31226 filtered\r
31227 ]);\r
31228 }\r
31229 },\r
31230 \r
31231 onCollectionBeforeItemChange: function(source, details) {\r
31232
31233 this.onCollectionUpdateKey = null;\r
31234 },\r
31235 \r
31236 onCollectionBeginUpdate: function() {\r
31237 this.beginUpdate();\r
31238 },\r
31239 \r
31240 onCollectionEndUpdate: function() {\r
31241 this.endUpdate();\r
31242 },\r
31243 \r
31244 onCollectionItemChange: function(source, details) {\r
31245
31246 delete this.onCollectionUpdateKey;\r
31247 this.itemChanged(details.item, details.modified, details.oldKey, details.meta);\r
31248 },\r
31249
31250
31251 onCollectionFilteredItemChange: null,\r
31252 \r
31253 onCollectionRefresh: function(source) {\r
31254 var me = this,\r
31255 map = {},\r
31256 indices = {},\r
31257 i, item, items, key, length;\r
31258 items = source.items;\r
31259 items = me.filtered && me.getAutoFilter() ? Ext.Array.filter(items, me.getFilterFn()) : items.slice(0);\r
31260 if (me.sorted) {\r
31261 me.sortData(items);\r
31262 }\r
31263 me.items = items;\r
31264 me.length = length = items.length;\r
31265 me.map = map;\r
31266 me.indices = indices;\r
31267 for (i = 0; i < length; ++i) {\r
31268 key = me.getKey(item = items[i]);\r
31269 map[key] = item;\r
31270 indices[key] = i;\r
31271 }\r
31272 me.notify('refresh');\r
31273 },\r
31274 \r
31275 onCollectionRemove: function(source, details) {\r
31276 this.splice(0, details.items);\r
31277 },\r
31278 \r
31279
31280
31281
31282 \r
31283 onCollectionUpdateKey: function(source, details) {\r
31284 this.updateKey(details.item, details.oldKey);\r
31285 },\r
31286
31287
31288 \r
31289 \r
31290 \r
31291 \r
31292 \r
31293 \r
31294 \r
31295 \r
31296 \r
31297 \r
31298 \r
31299 \r
31300 \r
31301 \r
31302 \r
31303 \r
31304 \r
31305 \r
31306 _aggregators: {\r
31307 average: function(items, begin, end, property, root) {\r
31308 var n = end - begin;\r
31309 return n && this._aggregators.sum.call(this, items, begin, end, property, root) / n;\r
31310 },\r
31311 bounds: function(items, begin, end, property, root) {\r
31312 for (var value, max, min,\r
31313 i = begin; i < end; ++i) {\r
31314 value = items[i];\r
31315 value = (root ? value[root] : value)[property];\r
31316
31317
31318
31319 if (!(value < max)) {\r
31320
31321 max = value;\r
31322 }\r
31323 if (!(value > min)) {\r
31324
31325 min = value;\r
31326 }\r
31327 }\r
31328 return [\r
31329 min,\r
31330 max\r
31331 ];\r
31332 },\r
31333 count: function(items) {\r
31334 return items.length;\r
31335 },\r
31336 extremes: function(items, begin, end, property, root) {\r
31337 var most = null,\r
31338 least = null,\r
31339 i, item, max, min, value;\r
31340 for (i = begin; i < end; ++i) {\r
31341 item = items[i];\r
31342 value = (root ? item[root] : item)[property];\r
31343
31344 if (!(value < max)) {\r
31345
31346 max = value;\r
31347 most = item;\r
31348 }\r
31349 if (!(value > min)) {\r
31350
31351 min = value;\r
31352 least = item;\r
31353 }\r
31354 }\r
31355 return [\r
31356 least,\r
31357 most\r
31358 ];\r
31359 },\r
31360 max: function(items, begin, end, property, root) {\r
31361 var b = this._aggregators.bounds.call(this, items, begin, end, property, root);\r
31362 return b[1];\r
31363 },\r
31364 maxItem: function(items, begin, end, property, root) {\r
31365 var b = this._aggregators.extremes.call(this, items, begin, end, property, root);\r
31366 return b[1];\r
31367 },\r
31368 min: function(items, begin, end, property, root) {\r
31369 var b = this._aggregators.bounds.call(this, items, begin, end, property, root);\r
31370 return b[0];\r
31371 },\r
31372 minItem: function(items, begin, end, property, root) {\r
31373 var b = this._aggregators.extremes.call(this, items, begin, end, property, root);\r
31374 return b[0];\r
31375 },\r
31376 sum: function(items, begin, end, property, root) {\r
31377 for (var value,\r
31378 sum = 0,\r
31379 i = begin; i < end; ++i) {\r
31380 value = items[i];\r
31381 value = (root ? value[root] : value)[property];\r
31382 sum += value;\r
31383 }\r
31384 return sum;\r
31385 }\r
31386 },\r
31387 _eventToMethodMap: {\r
31388 add: 'onCollectionAdd',\r
31389 beforeitemchange: 'onCollectionBeforeItemChange',\r
31390 beginupdate: 'onCollectionBeginUpdate',\r
31391 endupdate: 'onCollectionEndUpdate',\r
31392 itemchange: 'onCollectionItemChange',\r
31393 filtereditemchange: 'onCollectionFilteredItemChange',\r
31394 refresh: 'onCollectionRefresh',\r
31395 remove: 'onCollectionRemove',\r
31396 beforesort: 'beforeCollectionSort',\r
31397 sort: 'onCollectionSort',\r
31398 filter: 'onCollectionFilter',\r
31399 filteradd: 'onCollectionFilterAdd',\r
31400 updatekey: 'onCollectionUpdateKey'\r
31401 },\r
31402 \r
31403 addObserver: function(observer) {\r
31404 var me = this,\r
31405 observers = me.observers;\r
31406 if (!observers) {\r
31407 me.observers = observers = [];\r
31408 }\r
31409
31410 if (Ext.Array.contains(observers, observer)) {\r
31411 Ext.Error.raise('Observer already added');\r
31412 }\r
31413
31414 observers.push(observer);\r
31415 if (observers.length > 1) {\r
31416
31417
31418 Ext.Array.sort(observers, me.prioritySortFn);\r
31419 }\r
31420 },\r
31421 prioritySortFn: function(o1, o2) {\r
31422 var a = o1.observerPriority || 0,\r
31423 b = o2.observerPriority || 0;\r
31424 return a - b;\r
31425 },\r
31426 applyExtraKeys: function(extraKeys, oldExtraKeys) {\r
31427 var me = this,\r
31428 ret = oldExtraKeys || {},\r
31429 config, name, value;\r
31430 for (name in extraKeys) {\r
31431 value = extraKeys[name];\r
31432 if (!value.isCollectionKey) {\r
31433 config = {\r
31434 collection: me\r
31435 };\r
31436 if (Ext.isString(value)) {\r
31437 config.property = value;\r
31438 } else {\r
31439 config = Ext.apply(config, value);\r
31440 }\r
31441 value = new Ext.util.CollectionKey(config);\r
31442 } else {\r
31443 value.setCollection(me);\r
31444 }\r
31445 ret[name] = me[name] = value;\r
31446 value.name = name;\r
31447 }\r
31448 return ret;\r
31449 },\r
31450 applyGrouper: function(grouper) {\r
31451 if (grouper) {\r
31452 grouper = this.getSorters().decodeSorter(grouper, 'Ext.util.Grouper');\r
31453 }\r
31454 return grouper;\r
31455 },\r
31456 \r
31457 decodeItems: function(args, index) {\r
31458 var me = this,\r
31459 ret = (index === undefined) ? args : args[index],\r
31460 cloned, decoder, i;\r
31461 if (!ret || !ret.$cloned) {\r
31462 cloned = args.length > index + 1 || !Ext.isIterable(ret);\r
31463 if (cloned) {\r
31464 ret = Ext.Array.slice(args, index);\r
31465 if (ret.length === 1 && ret[0] === undefined) {\r
31466 ret.length = 0;\r
31467 }\r
31468 }\r
31469 decoder = me.getDecoder();\r
31470 if (decoder) {\r
31471 if (!cloned) {\r
31472 ret = ret.slice(0);\r
31473 cloned = true;\r
31474 }\r
31475 for (i = ret.length; i-- > 0; ) {\r
31476 if ((ret[i] = decoder.call(me, ret[i])) === false) {\r
31477 ret.splice(i, 1);\r
31478 }\r
31479 }\r
31480 }\r
31481 if (cloned) {\r
31482 ret.$cloned = true;\r
31483 }\r
31484 }\r
31485 return ret;\r
31486 },\r
31487 \r
31488 getIndices: function() {\r
31489 var me = this,\r
31490 indices = me.indices,\r
31491 items = me.items,\r
31492 n = items.length,\r
31493 i, key;\r
31494 if (!indices) {\r
31495 me.indices = indices = {};\r
31496 ++me.indexRebuilds;\r
31497 for (i = 0; i < n; ++i) {\r
31498 key = me.getKey(items[i]);\r
31499 indices[key] = i;\r
31500 }\r
31501 }\r
31502 return indices;\r
31503 },\r
31504 \r
31505 notify: function(eventName, args) {\r
31506 var me = this,\r
31507 observers = me.observers,\r
31508 methodName = me._eventToMethodMap[eventName],\r
31509 added = 0,\r
31510 index, length, method, observer;\r
31511 args = args || [];\r
31512 if (observers && methodName) {\r
31513 for (index = 0 , length = observers.length; index < length; ++index) {\r
31514 method = (observer = observers[index])[methodName];\r
31515 if (method) {\r
31516 if (!added++) {\r
31517
31518 args.unshift(me);\r
31519 }\r
31520
31521 method.apply(observer, args);\r
31522 }\r
31523 }\r
31524 }\r
31525
31526 if (!me.hasListeners) {\r
31527 return;\r
31528 }\r
31529 if (me.hasListeners[eventName]) {\r
31530 if (!added) {\r
31531 args.unshift(me);\r
31532 }\r
31533
31534 me.fireEventArgs(eventName, args);\r
31535 }\r
31536 },\r
31537 \r
31538 getFilterFn: function() {\r
31539 return this.getFilters().getFilterFn();\r
31540 },\r
31541 \r
31542 getFilters: function(autoCreate) {\r
31543 var ret = this._filters;\r
31544 if (!ret && autoCreate !== false) {\r
31545 ret = new Ext.util.FilterCollection();\r
31546 this.setFilters(ret);\r
31547 }\r
31548 return ret;\r
31549 },\r
31550 \r
31551 isItemFiltered: function(item) {\r
31552 return !this.getFilters().filterFn(item);\r
31553 },\r
31554 \r
31555 onFilterChange: function(filters) {\r
31556 var me = this,\r
31557 source = me.getSource(),\r
31558 extraKeys, newKeys, key;\r
31559 if (!source) {\r
31560
31561
31562
31563 extraKeys = me.getExtraKeys();\r
31564 if (extraKeys) {\r
31565 newKeys = {};\r
31566 for (key in extraKeys) {\r
31567 newKeys[key] = extraKeys[key].clone(me);\r
31568 }\r
31569 }\r
31570 source = new Ext.util.Collection({\r
31571 keyFn: me.getKey,\r
31572 extraKeys: newKeys,\r
31573 rootProperty: me.getRootProperty()\r
31574 });\r
31575 if (me.length) {\r
31576 source.add(me.items);\r
31577 }\r
31578 me.setSource(source);\r
31579 me.autoSource = source;\r
31580 } else if (source.length || me.length) {\r
31581
31582 me.onCollectionRefresh(source);\r
31583 }\r
31584 me.notify('filter');\r
31585 },\r
31586
31587
31588 applyFilters: function(filters, collection) {\r
31589 if (filters == null || (filters && filters.isFilterCollection)) {\r
31590 return filters;\r
31591 }\r
31592 if (filters) {\r
31593 if (!collection) {\r
31594 collection = this.getFilters();\r
31595 }\r
31596 collection.splice(0, collection.length, filters);\r
31597 }\r
31598 return collection;\r
31599 },\r
31600 updateFilters: function(newFilters, oldFilters) {\r
31601 var me = this;\r
31602 if (oldFilters) {\r
31603
31604
31605
31606
31607 oldFilters.un('endupdate', 'onEndUpdateFilters', me);\r
31608 }\r
31609 if (newFilters) {\r
31610 newFilters.on({\r
31611 endupdate: 'onEndUpdateFilters',\r
31612 scope: me,\r
31613 priority: me.$endUpdatePriority\r
31614 });\r
31615 newFilters.$filterable = me;\r
31616 }\r
31617 me.onEndUpdateFilters(newFilters);\r
31618 },\r
31619 onEndUpdateFilters: function(filters) {\r
31620 var me = this,\r
31621 was = me.filtered,\r
31622 is = !!filters && (filters.length > 0);\r
31623
31624 if (was || is) {\r
31625 me.filtered = is;\r
31626 me.onFilterChange(filters);\r
31627 }\r
31628 },\r
31629 \r
31630 getSortFn: function() {\r
31631 return this._sortFn || this.createSortFn();\r
31632 },\r
31633 \r
31634 getSorters: function(autoCreate) {\r
31635 var ret = this._sorters;\r
31636 if (!ret && autoCreate !== false) {\r
31637 ret = new Ext.util.SorterCollection();\r
31638 this.setSorters(ret);\r
31639 }\r
31640 return ret;\r
31641 },\r
31642 \r
31643 onSortChange: function() {\r
31644 if (this.sorted) {\r
31645 this.sortItems();\r
31646 }\r
31647 },\r
31648 \r
31649 sort: function(property, direction, mode) {\r
31650 var sorters = this.getSorters();\r
31651 sorters.addSort.apply(sorters, arguments);\r
31652 return this;\r
31653 },\r
31654 \r
31655 sortData: function(data) {\r
31656 Ext.Array.sort(data, this.getSortFn());\r
31657 return data;\r
31658 },\r
31659 \r
31660 sortItems: function(sortFn) {\r
31661 var me = this;\r
31662 if (me.sorted) {\r
31663
31664 if (sortFn) {\r
31665 Ext.raise('Collections with sorters cannot resorted');\r
31666 }\r
31667
31668 sortFn = me.getSortFn();\r
31669 }\r
31670 me.indices = null;\r
31671 me.notify('beforesort', [\r
31672 me.getSorters(false)\r
31673 ]);\r
31674 if (me.length) {\r
31675 Ext.Array.sort(me.items, sortFn);\r
31676 }\r
31677
31678
31679 me.notify('sort');\r
31680 },\r
31681 \r
31682 sortBy: function(sortFn) {\r
31683 return this.sortItems(sortFn);\r
31684 },\r
31685
31686
31687
31688
31689 findInsertionIndex: function(item, items, comparatorFn) {\r
31690 if (!items) {\r
31691 items = this.items;\r
31692 }\r
31693 if (!comparatorFn) {\r
31694 comparatorFn = this.getSortFn();\r
31695 }\r
31696 return Ext.Array.binarySearch(items, item, comparatorFn);\r
31697 },\r
31698 applySorters: function(sorters, collection) {\r
31699 if (sorters == null || (sorters && sorters.isSorterCollection)) {\r
31700 return sorters;\r
31701 }\r
31702 if (sorters) {\r
31703 if (!collection) {\r
31704 collection = this.getSorters();\r
31705 }\r
31706 collection.splice(0, collection.length, sorters);\r
31707 }\r
31708 return collection;\r
31709 },\r
31710 createSortFn: function() {\r
31711 var me = this,\r
31712 grouper = me.getGrouper(),\r
31713 sorters = me.getSorters(false),\r
31714 sorterFn = sorters ? sorters.getSortFn() : null;\r
31715 if (!grouper) {\r
31716 return sorterFn;\r
31717 }\r
31718 return function(lhs, rhs) {\r
31719 var ret = grouper.sort(lhs, rhs);\r
31720 if (!ret && sorterFn) {\r
31721 ret = sorterFn(lhs, rhs);\r
31722 }\r
31723 return ret;\r
31724 };\r
31725 },\r
31726 updateGrouper: function(grouper) {\r
31727 var me = this,\r
31728 groups = me.getGroups(),\r
31729 sorters = me.getSorters(),\r
31730 populate;\r
31731 me.onSorterChange();\r
31732 me.grouped = !!grouper;\r
31733 if (grouper) {\r
31734 if (me.getTrackGroups()) {\r
31735 if (!groups) {\r
31736 groups = new Ext.util.GroupCollection({\r
31737 itemRoot: me.getRootProperty()\r
31738 });\r
31739 groups.$groupable = me;\r
31740 me.setGroups(groups);\r
31741 }\r
31742 groups.setGrouper(grouper);\r
31743 populate = true;\r
31744 }\r
31745 } else {\r
31746 if (groups) {\r
31747 me.removeObserver(groups);\r
31748 groups.destroy();\r
31749 }\r
31750 me.setGroups(null);\r
31751 }\r
31752 if (!sorters.updating) {\r
31753 me.onEndUpdateSorters(sorters);\r
31754 }\r
31755 if (populate) {\r
31756 groups.onCollectionRefresh(me);\r
31757 }\r
31758 },\r
31759 updateSorters: function(newSorters, oldSorters) {\r
31760 var me = this;\r
31761 if (oldSorters) {\r
31762
31763
31764
31765
31766 oldSorters.un('endupdate', 'onEndUpdateSorters', me);\r
31767 }\r
31768 if (newSorters) {\r
31769 newSorters.on({\r
31770 endupdate: 'onEndUpdateSorters',\r
31771 scope: me,\r
31772 priority: me.$endUpdatePriority\r
31773 });\r
31774 newSorters.$sortable = me;\r
31775 }\r
31776 me.onSorterChange();\r
31777 me.onEndUpdateSorters(newSorters);\r
31778 },\r
31779 onSorterChange: function() {\r
31780 this._sortFn = null;\r
31781 },\r
31782 onEndUpdateSorters: function(sorters) {\r
31783 var me = this,\r
31784 was = me.sorted,\r
31785 is = (me.grouped && me.getAutoGroup()) || (sorters && sorters.length > 0);\r
31786 if (was || is) {\r
31787
31788
31789 me.sorted = !!is;\r
31790 me.onSortChange(sorters);\r
31791 }\r
31792 },\r
31793 \r
31794 removeObserver: function(observer) {\r
31795 var observers = this.observers;\r
31796 if (observers) {\r
31797 Ext.Array.remove(observers, observer);\r
31798 }\r
31799 },\r
31800 \r
31801 spliceMerge: function(newItems, newKeys) {\r
31802 var me = this,\r
31803 map = me.map,\r
31804 newLength = newItems.length,\r
31805 oldIndex = 0,\r
31806 oldItems = me.items,\r
31807 oldLength = oldItems.length,\r
31808 adds = [],\r
31809 count = 0,\r
31810 items = [],\r
31811 sortFn = me.getSortFn(),\r
31812
31813 addItems, end, i, newItem, oldItem, newIndex;\r
31814 me.items = items;\r
31815
31816
31817
31818
31819
31820
31821
31822
31823
31824
31825
31826
31827
31828 for (newIndex = 0; newIndex < newLength; newIndex = end) {\r
31829 newItem = newItems[newIndex];\r
31830
31831 for (; oldIndex < oldLength; ++oldIndex) {\r
31832
31833
31834
31835
31836 if (sortFn(newItem, oldItem = oldItems[oldIndex]) < 0) {\r
31837 break;\r
31838 }\r
31839 items.push(oldItem);\r
31840 }\r
31841 if (oldIndex === oldLength) {\r
31842
31843
31844
31845
31846 adds[count++] = {\r
31847 at: items.length,\r
31848 itemAt: items[items.length - 1],\r
31849 items: (addItems = [])\r
31850 };\r
31851 if (count > 1) {\r
31852 adds[count - 2].next = adds[count - 1];\r
31853 }\r
31854 for (; newIndex < newLength; ++newIndex) {\r
31855 addItems.push(newItem = newItems[newIndex]);\r
31856 items.push(newItem);\r
31857 }\r
31858 break;\r
31859 }\r
31860
31861
31862
31863
31864 adds[count++] = {\r
31865 at: items.length,\r
31866 itemAt: items[items.length - 1],\r
31867 items: (addItems = [\r
31868 newItem\r
31869 ])\r
31870 };\r
31871 if (count > 1) {\r
31872 adds[count - 2].next = adds[count - 1];\r
31873 }\r
31874 items.push(newItem);\r
31875 for (end = newIndex + 1; end < newLength; ++end) {\r
31876
31877
31878
31879 if (sortFn(newItem = newItems[end], oldItem) >= 0) {\r
31880 break;\r
31881 }\r
31882 items.push(newItem);\r
31883 addItems.push(newItem);\r
31884 }\r
31885 }\r
31886
31887
31888 for (; oldIndex < oldLength; ++oldIndex) {\r
31889
31890
31891 items.push(oldItems[oldIndex]);\r
31892 }\r
31893 for (i = 0; i < newLength; ++i) {\r
31894 map[newKeys[i]] = newItems[i];\r
31895 }\r
31896 me.length = items.length;\r
31897 ++me.generation;\r
31898 me.indices = null;\r
31899
31900 for (i = 0; i < count; ++i) {\r
31901 me.notify('add', [\r
31902 adds[i]\r
31903 ]);\r
31904 }\r
31905 },\r
31906 getGroups: function() {\r
31907 return this.callParent() || null;\r
31908 },\r
31909 updateAutoGroup: function(autoGroup) {\r
31910 var groups = this.getGroups();\r
31911 if (groups) {\r
31912 groups.setAutoGroup(autoGroup);\r
31913 }\r
31914
31915
31916 this.onEndUpdateSorters(this._sorters);\r
31917 },\r
31918 updateGroups: function(newGroups, oldGroups) {\r
31919 if (oldGroups) {\r
31920 this.removeObserver(oldGroups);\r
31921 }\r
31922 if (newGroups) {\r
31923 this.addObserver(newGroups);\r
31924 }\r
31925 },\r
31926 updateSource: function(newSource, oldSource) {\r
31927 var auto = this.autoSource;\r
31928 if (oldSource) {\r
31929 oldSource.removeObserver(this);\r
31930 if (oldSource === auto) {\r
31931 auto.destroy();\r
31932 this.autoSource = null;\r
31933 }\r
31934 }\r
31935 if (newSource) {\r
31936 newSource.addObserver(this);\r
31937 if (newSource.length || this.length) {\r
31938 this.onCollectionRefresh(newSource);\r
31939 }\r
31940 }\r
31941 }\r
31942}, function() {\r
31943 var prototype = this.prototype;\r
31944
31945 prototype.removeAtKey = prototype.removeByKey;\r
31946 \r
31947 prototype.decodeRemoveItems = prototype.decodeItems;\r
31948 Ext.Object.each(prototype._aggregators, function(name) {\r
31949 prototype[name] = function(property, begin, end) {\r
31950 return this.aggregate(property, name, begin, end);\r
31951 };\r
31952 prototype[name + 'ByGroup'] = function(property) {\r
31953 return this.aggregateByGroup(property, name);\r
31954 };\r
31955 });\r
31956});\r
31957\r
31958\r
31959Ext.define('Ext.util.ObjectTemplate', {\r
31960 isObjectTemplate: true,\r
31961 excludeProperties: {},\r
31962 valueRe: /^[{][a-z\.]+[}]$/i,\r
31963 statics: {\r
31964 \r
31965 create: function(template, options) {\r
31966
31967 if (!Ext.isObject(template)) {\r
31968 Ext.raise('The template is not an Object');\r
31969 }\r
31970
31971 return template.isObjectTemplate ? template : new Ext.util.ObjectTemplate(template, options);\r
31972 }\r
31973 },\r
31974 \r
31975 constructor: function(template, options) {\r
31976 Ext.apply(this, options);\r
31977 this.template = template;\r
31978 },\r
31979 \r
31980 apply: function(context) {\r
31981 var me = this;\r
31982 delete me.apply;\r
31983 me.apply = me.compile(me.template);\r
31984 return me.apply(context);\r
31985 },\r
31986 privates: {\r
31987 \r
31988 compile: function(template) {\r
31989 var me = this,\r
31990 exclude = me.excludeProperties,\r
31991 compiled, i, len, fn;\r
31992
31993 if (Ext.isString(template)) {\r
31994 if (template.indexOf('{') < 0) {\r
31995 fn = function() {\r
31996 return template;\r
31997 };\r
31998 } else if (me.valueRe.test(template)) {\r
31999 template = template.substring(1, template.length - 1).split('.');\r
32000 fn = function(context) {\r
32001 for (var v = context,\r
32002 i = 0; v && i < template.length; ++i) {\r
32003 v = v[template[i]];\r
32004 }\r
32005 return v;\r
32006 };\r
32007 } else {\r
32008 template = new Ext.XTemplate(template);\r
32009 fn = function(context) {\r
32010 return template.apply(context);\r
32011 };\r
32012 }\r
32013 } else if (!template || Ext.isPrimitive(template) || Ext.isFunction(template)) {\r
32014 fn = function() {\r
32015 return template;\r
32016 };\r
32017 } else if (template instanceof Array) {\r
32018 compiled = [];\r
32019 for (i = 0 , len = template.length; i < len; ++i) {\r
32020 compiled[i] = me.compile(template[i]);\r
32021 }\r
32022 fn = function(context) {\r
32023 var ret = [],\r
32024 i;\r
32025 for (i = 0; i < len; ++i) {\r
32026 ret[i] = compiled[i](context);\r
32027 }\r
32028 return ret;\r
32029 };\r
32030 } else {\r
32031 compiled = {};\r
32032 for (i in template) {\r
32033 if (!exclude[i]) {\r
32034 compiled[i] = me.compile(template[i]);\r
32035 }\r
32036 }\r
32037 fn = function(context) {\r
32038 var ret = {},\r
32039 i, v;\r
32040 for (i in template) {\r
32041 v = exclude[i] ? template[i] : compiled[i](context);\r
32042 if (v !== undefined) {\r
32043 ret[i] = v;\r
32044 }\r
32045 }\r
32046 return ret;\r
32047 };\r
32048 }\r
32049 return fn;\r
32050 }\r
32051 }\r
32052});\r
32053\r
32054\r
32055Ext.define('Ext.data.schema.Role', {\r
32056 \r
32057 isRole: true,\r
32058 \r
32059 left: true,\r
32060 \r
32061 owner: false,\r
32062 \r
32063 side: 'left',\r
32064 \r
32065 isMany: false,\r
32066 \r
32067 \r
32068 \r
32069 \r
32070 defaultReaderType: 'json',\r
32071 _internalReadOptions: {\r
32072 recordsOnly: true,\r
32073 asRoot: true\r
32074 },\r
32075 constructor: function(association, config) {\r
32076 var me = this,\r
32077 extra = config.extra;\r
32078 Ext.apply(me, config);\r
32079 if (extra) {\r
32080 delete extra.type;\r
32081 Ext.apply(me, extra);\r
32082 delete me.extra;\r
32083 }\r
32084 me.association = association;\r
32085
32086
32087 if (association.owner === me.side) {\r
32088 association.owner = me;\r
32089 me.owner = true;\r
32090 }\r
32091 },\r
32092 processUpdate: function() {\r
32093 Ext.raise('Only the "many" for an association may be processed. "' + this.role + '" is not valid.');\r
32094 },\r
32095 \r
32096 processLoad: function(store, associatedEntity, records, session) {\r
32097 return records;\r
32098 },\r
32099 \r
32100 checkMembership: Ext.emptyFn,\r
32101 \r
32102 adoptAssociated: function(record, session) {\r
32103 var other = this.getAssociatedItem(record);\r
32104 if (other) {\r
32105 session.adopt(other);\r
32106 }\r
32107 },\r
32108 createAssociationStore: function(session, from, records, isComplete) {\r
32109 var me = this,\r
32110 association = me.association,\r
32111 foreignKeyName = association.getFieldName(),\r
32112 isMany = association.isManyToMany,\r
32113 storeConfig = me.storeConfig,\r
32114 id = from.getId(),\r
32115 config = {\r
32116
32117 asynchronousLoad: false,\r
32118 model: me.cls,\r
32119 role: me,\r
32120 session: session,\r
32121 associatedEntity: from,\r
32122 disableMetaChangeEvent: true,\r
32123 pageSize: null,\r
32124 remoteFilter: true,\r
32125 trackRemoved: !session\r
32126 },\r
32127 store;\r
32128 if (isMany) {\r
32129
32130 config.filters = [\r
32131 {\r
32132 property: me.inverse.field,\r
32133
32134 value: id,\r
32135 exactMatch: true\r
32136 }\r
32137 ];\r
32138 } else if (foreignKeyName) {\r
32139 config.filters = [\r
32140 {\r
32141 property: foreignKeyName,\r
32142
32143 value: id,\r
32144 exactMatch: true\r
32145 }\r
32146 ];\r
32147 config.foreignKeyName = foreignKeyName;\r
32148 }\r
32149 if (storeConfig) {\r
32150 Ext.apply(config, storeConfig);\r
32151 }\r
32152 store = Ext.Factory.store(config);\r
32153 me.onStoreCreate(store, session, id);\r
32154 if (foreignKeyName || (isMany && session)) {\r
32155 store.on({\r
32156 scope: me,\r
32157 add: 'onAddToMany',\r
32158 remove: 'onRemoveFromMany',\r
32159 clear: 'onRemoveFromMany'\r
32160 });\r
32161 }\r
32162 if (records) {\r
32163 store.loadData(records);\r
32164 store.complete = !!isComplete;\r
32165 }\r
32166 return store;\r
32167 },\r
32168 onStoreCreate: Ext.emptyFn,\r
32169 getAssociatedStore: function(inverseRecord, options, scope, records, allowInfer) {\r
32170
32171
32172
32173
32174 var me = this,\r
32175 storeName = me.getStoreName(),\r
32176 store = inverseRecord[storeName],\r
32177 session = inverseRecord.session,\r
32178 load = options && options.reload,\r
32179 source = inverseRecord.$source,\r
32180 isComplete = false,\r
32181 hadSource, args, i, len, raw, rec, sourceStore, hadRecords;\r
32182 if (!store) {\r
32183 if (session) {\r
32184
32185
32186
32187 if (!records && source) {\r
32188 source = source[storeName];\r
32189 if (source && !source.isLoading()) {\r
32190 sourceStore = source;\r
32191 records = [];\r
32192 raw = source.getData().items;\r
32193 for (i = 0 , len = raw.length; i < len; ++i) {\r
32194 rec = raw[i];\r
32195 records.push(session.getRecord(rec.self, rec.id));\r
32196 }\r
32197 isComplete = !!source.complete;\r
32198 hadSource = true;\r
32199 }\r
32200 }\r
32201 if (!hadSource) {\r
32202
32203 hadRecords = !!records;\r
32204 records = me.findRecords(session, inverseRecord, records, allowInfer);\r
32205 if (!hadRecords && (!records || !records.length)) {\r
32206 records = null;\r
32207 }\r
32208 isComplete = hadRecords;\r
32209 }\r
32210 } else {\r
32211 isComplete = !!(records && records.length > 0);\r
32212 }\r
32213 store = me.createAssociationStore(session, inverseRecord, records, isComplete);\r
32214 store.$source = sourceStore;\r
32215 if (!records && (me.autoLoad || options)) {\r
32216 load = true;\r
32217 }\r
32218 inverseRecord[storeName] = store;\r
32219 }\r
32220 if (options) {\r
32221
32222
32223 if (load || store.isLoading()) {\r
32224 store.on('load', function(store, records, success, operation) {\r
32225 args = [\r
32226 store,\r
32227 operation\r
32228 ];\r
32229 scope = scope || options.scope || inverseRecord;\r
32230 if (success) {\r
32231 Ext.callback(options.success, scope, args);\r
32232 } else {\r
32233 Ext.callback(options.failure, scope, args);\r
32234 }\r
32235 args.push(success);\r
32236 Ext.callback(options, scope, args);\r
32237 Ext.callback(options.callback, scope, args);\r
32238 }, null, {\r
32239 single: true\r
32240 });\r
32241 } else {\r
32242
32243 args = [\r
32244 store,\r
32245 null\r
32246 ];\r
32247 scope = scope || options.scope || inverseRecord;\r
32248 Ext.callback(options.success, scope, args);\r
32249 args.push(true);\r
32250 Ext.callback(options, scope, args);\r
32251 Ext.callback(options.callback, scope, args);\r
32252 }\r
32253 }\r
32254 if (load && !store.isLoading()) {\r
32255 store.load();\r
32256 }\r
32257 return store;\r
32258 },\r
32259 \r
32260 getAssociatedItem: function(rec) {\r
32261 var key = this.isMany ? this.getStoreName() : this.getInstanceName();\r
32262 return rec[key] || null;\r
32263 },\r
32264 onDrop: Ext.emptyFn,\r
32265 getReaderRoot: function() {\r
32266 var me = this;\r
32267 return me.associationKey || (me.associationKey = me.association.schema.getNamer().readerRoot(me.role));\r
32268 },\r
32269 getReader: function() {\r
32270 var me = this,\r
32271 reader = me.reader,\r
32272 Model = me.cls,\r
32273 useSimpleAccessors = !me.associationKey,\r
32274 root = this.getReaderRoot();\r
32275 if (reader && !reader.isReader) {\r
32276 if (Ext.isString(reader)) {\r
32277 reader = {\r
32278 type: reader\r
32279 };\r
32280 }\r
32281 Ext.applyIf(reader, {\r
32282 model: Model,\r
32283 rootProperty: root,\r
32284 useSimpleAccessors: useSimpleAccessors,\r
32285 type: me.defaultReaderType\r
32286 });\r
32287 reader = me.reader = Ext.createByAlias('reader.' + reader.type, reader);\r
32288 }\r
32289 return reader;\r
32290 },\r
32291 getInstanceName: function() {\r
32292 var me = this;\r
32293 return me.instanceName || (me.instanceName = me.association.schema.getNamer().instanceName(me.role));\r
32294 },\r
32295 getOldInstanceName: function() {\r
32296 return this.oldInstanceName || (this.oldInstanceName = '$old' + this.getInstanceName());\r
32297 },\r
32298 getStoreName: function() {\r
32299 var me = this;\r
32300 return me.storeName || (me.storeName = me.association.schema.getNamer().storeName(me.role));\r
32301 },\r
32302 constructReader: function(fromReader) {\r
32303 var me = this,\r
32304 reader = me.getReader(),\r
32305 Model = me.cls,\r
32306 useSimpleAccessors = !me.associationKey,\r
32307 root = me.getReaderRoot(),\r
32308 proxyReader, proxy;\r
32309
32310 if (!reader) {\r
32311 proxy = Model.getProxy();\r
32312
32313 if (proxy) {\r
32314 proxyReader = proxy.getReader();\r
32315 reader = new proxyReader.self();\r
32316 reader.copyFrom(proxyReader);\r
32317 reader.setRootProperty(root);\r
32318 } else {\r
32319 reader = new fromReader.self({\r
32320 model: Model,\r
32321 useSimpleAccessors: useSimpleAccessors,\r
32322 rootProperty: root\r
32323 });\r
32324 }\r
32325 me.reader = reader;\r
32326 }\r
32327 return reader;\r
32328 },\r
32329 read: function(record, data, fromReader, readOptions) {\r
32330 var reader = this.constructReader(fromReader),\r
32331 root = reader.getRoot(data);\r
32332 if (root) {\r
32333 return reader.readRecords(root, readOptions, this._internalReadOptions);\r
32334 }\r
32335 },\r
32336 getCallbackOptions: function(options, scope, defaultScope) {\r
32337 if (typeof options === 'function') {\r
32338 options = {\r
32339 callback: options,\r
32340 scope: scope || defaultScope\r
32341 };\r
32342 } else if (options) {\r
32343 options = Ext.apply({}, options);\r
32344 options.scope = scope || options.scope || defaultScope;\r
32345 }\r
32346 return options;\r
32347 },\r
32348 doGetFK: function(leftRecord, options, scope) {\r
32349
32350
32351
32352
32353
32354 var me = this,\r
32355
32356 cls = me.cls,\r
32357
32358 foreignKey = me.association.getFieldName(),\r
32359
32360 instanceName = me.getInstanceName(),\r
32361
32362 rightRecord = leftRecord[instanceName],\r
32363
32364 reload = options && options.reload,\r
32365 done = rightRecord !== undefined && !reload,\r
32366 session = leftRecord.session,\r
32367 foreignKeyId, args;\r
32368 if (!done) {\r
32369
32370 if (session) {\r
32371 foreignKeyId = leftRecord.get(foreignKey);\r
32372 if (foreignKeyId || foreignKeyId === 0) {\r
32373 done = session.peekRecord(cls, foreignKeyId, true) && !reload;\r
32374 rightRecord = session.getRecord(cls, foreignKeyId, false);\r
32375 } else {\r
32376 done = true;\r
32377 leftRecord[instanceName] = rightRecord = null;\r
32378 }\r
32379 } else if (foreignKey) {\r
32380
32381
32382 foreignKeyId = leftRecord.get(foreignKey);\r
32383 if (!foreignKeyId && foreignKeyId !== 0) {\r
32384
32385
32386 done = true;\r
32387 leftRecord[instanceName] = rightRecord = null;\r
32388 } else {\r
32389
32390
32391
32392 if (!rightRecord) {\r
32393
32394 rightRecord = cls.createWithId(foreignKeyId);\r
32395 }\r
32396 }\r
32397 } else
32398 {\r
32399
32400
32401 done = true;\r
32402 }\r
32403 } else if (rightRecord) {\r
32404
32405 done = !rightRecord.isLoading();\r
32406 }\r
32407 if (done) {\r
32408 if (options) {\r
32409 args = [\r
32410 rightRecord,\r
32411 null\r
32412 ];\r
32413 scope = scope || options.scope || leftRecord;\r
32414 Ext.callback(options.success, scope, args);\r
32415 args.push(true);\r
32416 Ext.callback(options, scope, args);\r
32417 Ext.callback(options.callback, scope, args);\r
32418 }\r
32419 } else {\r
32420 leftRecord[instanceName] = rightRecord;\r
32421 options = me.getCallbackOptions(options, scope, leftRecord);\r
32422 rightRecord.load(options);\r
32423 }\r
32424 return rightRecord;\r
32425 },\r
32426 doSetFK: function(leftRecord, rightRecord, options, scope) {\r
32427
32428
32429
32430
32431
32432 var me = this,\r
32433 foreignKey = me.association.getFieldName(),\r
32434
32435 instanceName = me.getInstanceName(),\r
32436
32437 current = leftRecord[instanceName],\r
32438 inverse = me.inverse,\r
32439 inverseSetter = inverse.setterName,\r
32440
32441 session = leftRecord.session,\r
32442 modified, oldInstanceName;\r
32443 if (rightRecord && rightRecord.isEntity) {\r
32444 if (current !== rightRecord) {\r
32445 oldInstanceName = me.getOldInstanceName();\r
32446 leftRecord[oldInstanceName] = current;\r
32447 leftRecord[instanceName] = rightRecord;\r
32448 if (current && current.isEntity) {\r
32449 current[inverse.getInstanceName()] = undefined;\r
32450 }\r
32451 if (foreignKey) {\r
32452 leftRecord.set(foreignKey, rightRecord.getId());\r
32453 }\r
32454 delete leftRecord[oldInstanceName];\r
32455 if (inverseSetter) {\r
32456
32457
32458
32459 rightRecord[inverseSetter](leftRecord);\r
32460 }\r
32461 }\r
32462 } else {\r
32463
32464
32465
32466 if (!foreignKey) {\r
32467 Ext.raise('No foreignKey specified for "' + me.association.left.role + '" by ' + leftRecord.$className);\r
32468 }\r
32469
32470 modified = (leftRecord.changingKey && !inverse.isMany) || leftRecord.set(foreignKey, rightRecord);\r
32471
32472 if (modified && current && current.isEntity && !current.isEqual(current.getId(), rightRecord)) {\r
32473
32474
32475 leftRecord[instanceName] = undefined;\r
32476 if (!inverse.isMany) {\r
32477 current[inverse.getInstanceName()] = undefined;\r
32478 }\r
32479 }\r
32480 }\r
32481 if (options) {\r
32482 if (Ext.isFunction(options)) {\r
32483 options = {\r
32484 callback: options,\r
32485 scope: scope || leftRecord\r
32486 };\r
32487 }\r
32488 return leftRecord.save(options);\r
32489 }\r
32490 }\r
32491});\r
32492\r
32493\r
32494Ext.define('Ext.data.schema.Association', {\r
32495 isOneToOne: false,\r
32496 isManyToOne: false,\r
32497 isManyToMany: false,\r
32498 \r
32499 \r
32500 owner: null,\r
32501 \r
32502 \r
32503 field: null,\r
32504 \r
32505 \r
32506 \r
32507 \r
32508 constructor: function(config) {\r
32509 var me = this,\r
32510 left, right;\r
32511 Ext.apply(me, config);\r
32512 me.left = left = new me.Left(me, me.left);\r
32513 me.right = right = new me.Right(me, me.right);\r
32514 left.inverse = right;\r
32515 right.inverse = left;\r
32516 },\r
32517 hasField: function() {\r
32518 return !!this.field;\r
32519 },\r
32520 getFieldName: function() {\r
32521 var field = this.field;\r
32522 return field ? field.name : '';\r
32523 }\r
32524});\r
32525\r
32526\r
32527Ext.define('Ext.data.schema.OneToOne', {\r
32528 extend: Ext.data.schema.Association,\r
32529 isOneToOne: true,\r
32530 isToOne: true,\r
32531 kind: 'one-to-one',\r
32532 Left: Ext.define(null, {\r
32533 extend: 'Ext.data.schema.Role',\r
32534 onDrop: function(rightRecord, session) {\r
32535 var leftRecord = this.getAssociatedItem(rightRecord);\r
32536 rightRecord[this.getInstanceName()] = null;\r
32537 if (leftRecord) {\r
32538 leftRecord[this.inverse.getInstanceName()] = null;\r
32539 }\r
32540 },\r
32541 createGetter: function() {\r
32542 var me = this;\r
32543 return function() {\r
32544
32545 return me.doGet(this);\r
32546 };\r
32547 },\r
32548 createSetter: function() {\r
32549 var me = this;\r
32550 return function(value) {\r
32551
32552 return me.doSet(this, value);\r
32553 };\r
32554 },\r
32555 doGet: function(rightRecord) {\r
32556
32557
32558
32559
32560
32561
32562 var instanceName = this.getInstanceName(),\r
32563
32564 ret = rightRecord[instanceName],\r
32565 session = rightRecord.session;\r
32566 if (!ret && session) {}\r
32567
32568
32569 return ret || null;\r
32570 },\r
32571 doSet: function(rightRecord, leftRecord) {\r
32572
32573
32574
32575 var instanceName = this.getInstanceName(),\r
32576
32577 ret = rightRecord[instanceName],\r
32578 inverseSetter = this.inverse.setterName;\r
32579
32580 if (ret !== leftRecord) {\r
32581 rightRecord[instanceName] = leftRecord;\r
32582 if (inverseSetter) {\r
32583
32584
32585
32586 leftRecord[inverseSetter](rightRecord);\r
32587 }\r
32588 }\r
32589 return ret;\r
32590 },\r
32591 read: function(rightRecord, node, fromReader, readOptions) {\r
32592 var me = this,\r
32593 leftRecords = me.callParent([\r
32594 rightRecord,\r
32595 node,\r
32596 fromReader,\r
32597 readOptions\r
32598 ]),\r
32599 leftRecord;\r
32600 if (leftRecords) {\r
32601 leftRecord = leftRecords[0];\r
32602 if (leftRecord) {\r
32603 leftRecord[me.inverse.getInstanceName()] = rightRecord;\r
32604 rightRecord[me.getInstanceName()] = leftRecord;\r
32605
32606 delete rightRecord.data[me.role];\r
32607 }\r
32608 }\r
32609 }\r
32610 }),\r
32611 Right: Ext.define(null, {\r
32612 extend: 'Ext.data.schema.Role',\r
32613 left: false,\r
32614 side: 'right',\r
32615 createGetter: function() {\r
32616
32617
32618 var me = this;\r
32619 return function(options, scope) {\r
32620
32621 return me.doGetFK(this, options, scope);\r
32622 };\r
32623 },\r
32624 createSetter: function() {\r
32625 var me = this;\r
32626 return function(value, options, scope) {\r
32627
32628 return me.doSetFK(this, value, options, scope);\r
32629 };\r
32630 },\r
32631 onDrop: function(leftRecord, session) {\r
32632 var me = this,\r
32633 field = me.association.field,\r
32634 rightRecord = me.getAssociatedItem(leftRecord),\r
32635 id;\r
32636 if (me.inverse.owner) {\r
32637 if (session) {\r
32638 id = leftRecord.get(field.name);\r
32639 if (id || id === 0) {\r
32640 rightRecord = session.getEntry(me.cls, id).record;\r
32641 if (rightRecord) {\r
32642 rightRecord.drop();\r
32643 }\r
32644 }\r
32645 } else {\r
32646 if (rightRecord) {\r
32647 rightRecord.drop();\r
32648 }\r
32649 }\r
32650 }\r
32651 if (field) {\r
32652 leftRecord.set(field.name, null);\r
32653 }\r
32654 leftRecord[me.getInstanceName()] = null;\r
32655 if (rightRecord) {\r
32656 rightRecord[me.inverse.getInstanceName()] = null;\r
32657 }\r
32658 },\r
32659 onValueChange: function(leftRecord, session, newValue) {\r
32660
32661 var me = this,\r
32662 rightRecord = leftRecord[me.getOldInstanceName()] || me.getAssociatedItem(leftRecord),\r
32663 hasNewValue = newValue || newValue === 0,\r
32664 instanceName = me.getInstanceName(),\r
32665 cls = me.cls;\r
32666 leftRecord.changingKey = true;\r
32667 me.doSetFK(leftRecord, newValue);\r
32668 if (!hasNewValue) {\r
32669 leftRecord[instanceName] = null;\r
32670 } else if (session && cls) {\r
32671
32672 leftRecord[instanceName] = session.peekRecord(cls, newValue) || undefined;\r
32673 }\r
32674 if (me.inverse.owner && rightRecord) {\r
32675 me.association.schema.queueKeyCheck(rightRecord, me);\r
32676 }\r
32677 leftRecord.changingKey = false;\r
32678 },\r
32679 checkKeyForDrop: function(rightRecord) {\r
32680 var leftRecord = this.inverse.getAssociatedItem(rightRecord);\r
32681 if (!leftRecord) {\r
32682
32683 rightRecord.drop();\r
32684 }\r
32685 },\r
32686 read: function(leftRecord, node, fromReader, readOptions) {\r
32687 var me = this,\r
32688 rightRecords = me.callParent([\r
32689 leftRecord,\r
32690 node,\r
32691 fromReader,\r
32692 readOptions\r
32693 ]),\r
32694 rightRecord, field, fieldName, session, refs, id, oldId, setKey, data;\r
32695 if (rightRecords) {\r
32696 rightRecord = rightRecords[0];\r
32697 field = me.association.field;\r
32698 if (field) {\r
32699 fieldName = field.name;\r
32700 }\r
32701 session = leftRecord.session;\r
32702 data = leftRecord.data;\r
32703 if (rightRecord) {\r
32704 if (session) {\r
32705 refs = session.getRefs(rightRecord, this.inverse, true);\r
32706
32707
32708 setKey = (refs && refs[leftRecord.id]) || (data[fieldName] === undefined);\r
32709 } else {\r
32710 setKey = true;\r
32711 }\r
32712 if (setKey) {\r
32713
32714
32715 if (field) {\r
32716 oldId = data[fieldName];\r
32717 id = rightRecord.id;\r
32718 if (oldId !== id) {\r
32719 data[fieldName] = id;\r
32720 if (session) {\r
32721 session.updateReference(leftRecord, field, id, oldId);\r
32722 }\r
32723 }\r
32724 }\r
32725 rightRecord[me.inverse.getInstanceName()] = leftRecord;\r
32726 leftRecord[me.getInstanceName()] = rightRecord;\r
32727 }\r
32728
32729 delete data[me.role];\r
32730 }\r
32731 }\r
32732 }\r
32733 })\r
32734});\r
32735\r
32736\r
32737Ext.define('Ext.data.schema.ManyToOne', {\r
32738 extend: Ext.data.schema.Association,\r
32739 isManyToOne: true,\r
32740 isToOne: true,\r
32741 kind: 'many-to-one',\r
32742 Left: Ext.define(null, {\r
32743 extend: 'Ext.data.schema.Role',\r
32744 isMany: true,\r
32745 onDrop: function(rightRecord, session) {\r
32746 var me = this,\r
32747 store = me.getAssociatedItem(rightRecord),\r
32748 leftRecords, len, i, refs, id;\r
32749 if (store) {\r
32750
32751 leftRecords = store.removeAll();\r
32752 if (leftRecords && me.inverse.owner) {\r
32753
32754 for (i = 0 , len = leftRecords.length; i < len; ++i) {\r
32755 leftRecords[i].drop();\r
32756 }\r
32757 }\r
32758 store.destroy();\r
32759 rightRecord[me.getStoreName()] = null;\r
32760 } else if (session) {\r
32761 leftRecords = session.getRefs(rightRecord, me);\r
32762 if (leftRecords) {\r
32763 for (id in leftRecords) {\r
32764 leftRecords[id].drop();\r
32765 }\r
32766 }\r
32767 }\r
32768 },\r
32769 processUpdate: function(session, associationData) {\r
32770 var me = this,\r
32771 entityType = me.inverse.cls,\r
32772 items = associationData.R,\r
32773 id, rightRecord, store, leftRecords;\r
32774 if (items) {\r
32775 for (id in items) {\r
32776 rightRecord = session.peekRecord(entityType, id);\r
32777 if (rightRecord) {\r
32778 leftRecords = session.getEntityList(me.cls, items[id]);\r
32779 store = me.getAssociatedItem(rightRecord);\r
32780 if (store) {\r
32781 store.loadData(leftRecords);\r
32782 store.complete = true;\r
32783 } else {\r
32784
32785 rightRecord[me.getterName](null, null, leftRecords);\r
32786 }\r
32787 } else {\r
32788 session.onInvalidAssociationEntity(entityType, id);\r
32789 }\r
32790 }\r
32791 }\r
32792 },\r
32793 findRecords: function(session, rightRecord, leftRecords, allowInfer) {\r
32794 var ret = leftRecords,\r
32795 refs = session.getRefs(rightRecord, this, true),\r
32796 field = this.association.field,\r
32797 fieldName = field.name,\r
32798 leftRecord, id, i, len, seen;\r
32799 if (!rightRecord.phantom) {\r
32800 ret = [];\r
32801 if (refs || allowInfer) {\r
32802 if (leftRecords) {\r
32803 seen = {};\r
32804
32805
32806
32807
32808 for (i = 0 , len = leftRecords.length; i < len; ++i) {\r
32809 leftRecord = leftRecords[i];\r
32810 id = leftRecord.id;\r
32811 if (refs && refs[id]) {\r
32812 ret.push(leftRecord);\r
32813 } else if (allowInfer && leftRecord.data[fieldName] === undefined) {\r
32814 ret.push(leftRecord);\r
32815 leftRecord.data[fieldName] = rightRecord.id;\r
32816 session.updateReference(leftRecord, field, rightRecord.id, undefined);\r
32817 }\r
32818 seen[id] = true;\r
32819 }\r
32820 }\r
32821
32822 if (refs) {\r
32823 for (id in refs) {\r
32824 if (!seen || !seen[id]) {\r
32825 ret.push(refs[id]);\r
32826 }\r
32827 }\r
32828 }\r
32829 }\r
32830 }\r
32831 return ret;\r
32832 },\r
32833 processLoad: function(store, rightRecord, leftRecords, session) {\r
32834 var ret = leftRecords;\r
32835 if (session) {\r
32836
32837 ret = this.findRecords(session, rightRecord, leftRecords, true);\r
32838 }\r
32839 this.onLoadMany(rightRecord, ret, session);\r
32840 return ret;\r
32841 },\r
32842 adoptAssociated: function(rightRecord, session) {\r
32843 var store = this.getAssociatedItem(rightRecord),\r
32844 leftRecords, i, len;\r
32845 if (store) {\r
32846 store.setSession(session);\r
32847 leftRecords = store.getData().items;\r
32848 for (i = 0 , len = leftRecords.length; i < len; ++i) {\r
32849 session.adopt(leftRecords[i]);\r
32850 }\r
32851 }\r
32852 },\r
32853 createGetter: function() {\r
32854 var me = this;\r
32855 return function(options, scope, leftRecords) {\r
32856
32857 return me.getAssociatedStore(this, options, scope, leftRecords, me, true);\r
32858 };\r
32859 },\r
32860 createSetter: null,\r
32861
32862 onAddToMany: function(store, leftRecords) {\r
32863 this.syncFK(leftRecords, store.getAssociatedEntity(), false);\r
32864 },\r
32865 onLoadMany: function(rightRecord, leftRecords, session) {\r
32866 var instanceName = this.inverse.getInstanceName(),\r
32867 id = rightRecord.getId(),\r
32868 field = this.association.field,\r
32869 i, len, leftRecord, oldId, data, name;\r
32870 if (field) {\r
32871 for (i = 0 , len = leftRecords.length; i < len; ++i) {\r
32872 leftRecord = leftRecords[i];\r
32873 leftRecord[instanceName] = rightRecord;\r
32874 if (field) {\r
32875 name = field.name;\r
32876 data = leftRecord.data;\r
32877 oldId = data[name];\r
32878 if (oldId !== id) {\r
32879 data[name] = id;\r
32880 if (session) {\r
32881 session.updateReference(leftRecord, field, id, oldId);\r
32882 }\r
32883 }\r
32884 }\r
32885 }\r
32886 }\r
32887 },\r
32888 onRemoveFromMany: function(store, leftRecords) {\r
32889 this.syncFK(leftRecords, store.getAssociatedEntity(), true);\r
32890 },\r
32891 read: function(rightRecord, node, fromReader, readOptions) {\r
32892 var me = this,\r
32893
32894
32895 instanceName = me.inverse.getInstanceName(),\r
32896 leftRecords = me.callParent([\r
32897 rightRecord,\r
32898 node,\r
32899 fromReader,\r
32900 readOptions\r
32901 ]),\r
32902 store, len, i;\r
32903 if (leftRecords) {\r
32904
32905 store = rightRecord[me.getterName](null, null, leftRecords);\r
32906
32907 delete rightRecord.data[me.role];\r
32908 leftRecords = store.getData().items;\r
32909 for (i = 0 , len = leftRecords.length; i < len; ++i) {\r
32910 leftRecords[i][instanceName] = rightRecord;\r
32911 }\r
32912 }\r
32913 },\r
32914 syncFK: function(leftRecords, rightRecord, clearing) {\r
32915
32916
32917
32918
32919 var foreignKeyName = this.association.getFieldName(),\r
32920 inverse = this.inverse,\r
32921 setter = inverse.setterName,\r
32922
32923 instanceName = inverse.getInstanceName(),\r
32924 i = leftRecords.length,\r
32925 id = rightRecord.getId(),\r
32926 different, leftRecord, val;\r
32927 while (i-- > 0) {\r
32928 leftRecord = leftRecords[i];\r
32929 different = !leftRecord.isEqual(id, leftRecord.get(foreignKeyName));\r
32930 val = clearing ? null : rightRecord;\r
32931 if (different !== clearing) {\r
32932
32933
32934
32935
32936
32937
32938
32939
32940 leftRecord.changingKey = true;\r
32941 leftRecord[setter](val);\r
32942 leftRecord.changingKey = false;\r
32943 } else {\r
32944
32945 leftRecord[instanceName] = val;\r
32946 }\r
32947 }\r
32948 }\r
32949 }),\r
32950 Right: Ext.define(null, {\r
32951 extend: 'Ext.data.schema.Role',\r
32952 left: false,\r
32953 side: 'right',\r
32954 onDrop: function(leftRecord, session) {\r
32955
32956
32957
32958
32959 var field = this.association.field;\r
32960 if (field) {\r
32961 leftRecord.set(field.name, null);\r
32962 }\r
32963 leftRecord[this.getInstanceName()] = null;\r
32964 },\r
32965 createGetter: function() {\r
32966
32967
32968 var me = this;\r
32969 return function(options, scope) {\r
32970
32971 return me.doGetFK(this, options, scope);\r
32972 };\r
32973 },\r
32974 createSetter: function() {\r
32975 var me = this;\r
32976 return function(rightRecord, options, scope) {\r
32977
32978 return me.doSetFK(this, rightRecord, options, scope);\r
32979 };\r
32980 },\r
32981 checkMembership: function(session, leftRecord) {\r
32982 var field = this.association.field,\r
32983 store;\r
32984 store = this.getSessionStore(session, leftRecord.get(field.name));\r
32985
32986 if (store && !store.contains(leftRecord)) {\r
32987 store.add(leftRecord);\r
32988 }\r
32989 },\r
32990 onValueChange: function(leftRecord, session, newValue, oldValue) {\r
32991
32992
32993 var me = this,\r
32994 instanceName = me.getInstanceName(),\r
32995 cls = me.cls,\r
32996 hasNewValue, joined, store, i, len, associated, rightRecord;\r
32997 if (!leftRecord.changingKey) {\r
32998 hasNewValue = newValue || newValue === 0;\r
32999 if (!hasNewValue) {\r
33000 leftRecord[instanceName] = null;\r
33001 }\r
33002 if (session) {\r
33003
33004 store = me.getSessionStore(session, oldValue);\r
33005 if (store) {\r
33006 store.remove(leftRecord);\r
33007 }\r
33008
33009 if (hasNewValue) {\r
33010 store = me.getSessionStore(session, newValue);\r
33011 if (store && !store.isLoading()) {\r
33012 store.add(leftRecord);\r
33013 }\r
33014 if (cls) {\r
33015 rightRecord = session.peekRecord(cls, newValue);\r
33016 }\r
33017
33018 leftRecord[instanceName] = rightRecord || undefined;\r
33019 }\r
33020 } else {\r
33021 joined = leftRecord.joined;\r
33022 if (joined) {\r
33023 for (i = 0 , len = joined.length; i < len; ++i) {\r
33024 store = joined[i];\r
33025 if (store.isStore) {\r
33026 associated = store.getAssociatedEntity();\r
33027 if (associated && associated.self === me.cls && associated.getId() === oldValue) {\r
33028 store.remove(leftRecord);\r
33029 }\r
33030 }\r
33031 }\r
33032 }\r
33033 }\r
33034 }\r
33035 if (me.owner && newValue === null) {\r
33036 me.association.schema.queueKeyCheck(leftRecord, me);\r
33037 }\r
33038 },\r
33039 checkKeyForDrop: function(leftRecord) {\r
33040 var field = this.association.field;\r
33041 if (leftRecord.get(field.name) === null) {\r
33042 leftRecord.drop();\r
33043 }\r
33044 },\r
33045 getSessionStore: function(session, value) {\r
33046
33047 var cls = this.cls,\r
33048 rec;\r
33049 if (cls) {\r
33050 rec = session.peekRecord(cls, value);\r
33051 if (rec) {\r
33052 return this.inverse.getAssociatedItem(rec);\r
33053 }\r
33054 }\r
33055 },\r
33056 read: function(leftRecord, node, fromReader, readOptions) {\r
33057 var rightRecords = this.callParent([\r
33058 leftRecord,\r
33059 node,\r
33060 fromReader,\r
33061 readOptions\r
33062 ]),\r
33063 rightRecord;\r
33064 if (rightRecords) {\r
33065 rightRecord = rightRecords[0];\r
33066 if (rightRecord) {\r
33067 leftRecord[this.getInstanceName()] = rightRecord;\r
33068 delete leftRecord.data[this.role];\r
33069 }\r
33070 }\r
33071 }\r
33072 })\r
33073});\r
33074\r
33075\r
33076Ext.define('Ext.data.schema.ManyToMany', {\r
33077 extend: Ext.data.schema.Association,\r
33078 isManyToMany: true,\r
33079 isToMany: true,\r
33080 kind: 'many-to-many',\r
33081 Left: Ext.define(null, {\r
33082 extend: 'Ext.data.schema.Role',\r
33083 isMany: true,\r
33084 digitRe: /^\d+$/,\r
33085 findRecords: function(session, rightRecord, leftRecords) {\r
33086 var slice = session.getMatrixSlice(this.inverse, rightRecord.id),\r
33087 members = slice.members,\r
33088 ret = [],\r
33089 cls = this.cls,\r
33090 seen, i, len, id, member, leftRecord;\r
33091 if (leftRecords) {\r
33092 seen = {};\r
33093
33094
33095 for (i = 0 , len = leftRecords.length; i < len; ++i) {\r
33096 leftRecord = leftRecords[i];\r
33097 id = leftRecord.id;\r
33098 member = members[id];\r
33099 if (!(member && member[2] === -1)) {\r
33100 ret.push(leftRecord);\r
33101 }\r
33102 seen[id] = true;\r
33103 }\r
33104 }\r
33105
33106 for (id in members) {\r
33107 member = members[id];\r
33108 if (!seen || !seen[id] && (member && member[2] !== -1)) {\r
33109 leftRecord = session.peekRecord(cls, id);\r
33110 if (leftRecord) {\r
33111 ret.push(leftRecord);\r
33112 }\r
33113 }\r
33114 }\r
33115 return ret;\r
33116 },\r
33117 processLoad: function(store, rightRecord, leftRecords, session) {\r
33118 var ret = leftRecords;\r
33119 if (session) {\r
33120 ret = this.findRecords(session, rightRecord, leftRecords);\r
33121 this.onAddToMany(store, ret, true);\r
33122 }\r
33123 return ret;\r
33124 },\r
33125 processUpdate: function(session, associationData) {\r
33126 var me = this,\r
33127 entityType = me.inverse.cls,\r
33128 items = associationData.R,\r
33129 id, rightRecord, store, leftRecords;\r
33130 if (items) {\r
33131 for (id in items) {\r
33132 rightRecord = session.peekRecord(entityType, id);\r
33133 if (rightRecord) {\r
33134 leftRecords = session.getEntityList(me.cls, items[id]);\r
33135 store = me.getAssociatedItem(rightRecord);\r
33136 if (store) {\r
33137 store.loadData(leftRecords);\r
33138 store.complete = true;\r
33139 } else {\r
33140
33141 rightRecord[me.getterName](null, null, leftRecords);\r
33142 }\r
33143 } else {\r
33144 session.onInvalidAssociationEntity(entityType, id);\r
33145 }\r
33146 }\r
33147 }\r
33148 me.processMatrixBlock(session, associationData.C, 1);\r
33149 me.processMatrixBlock(session, associationData.D, -1);\r
33150 },\r
33151 checkMembership: function(session, rightRecord) {\r
33152 var matrix = session.getMatrix(this.association, true),\r
33153 side, entityType, inverse, slice, slices, id, members, member, leftRecord, store;\r
33154 if (!matrix) {\r
33155 return;\r
33156 }\r
33157 side = this.left ? matrix.right : matrix.left;\r
33158 entityType = side.inverse.role.cls;\r
33159 inverse = this.inverse;\r
33160 slices = side.slices;\r
33161 if (slices) {\r
33162 slice = slices[rightRecord.id];\r
33163 if (slice) {\r
33164 members = slice.members;\r
33165 for (id in members) {\r
33166 member = members[id];\r
33167 if (member[2] !== -1) {\r
33168
33169 leftRecord = session.peekRecord(entityType, id);\r
33170 if (leftRecord) {\r
33171 store = inverse.getAssociatedItem(leftRecord);\r
33172 if (store) {\r
33173 store.matrixUpdate = 1;\r
33174 store.add(rightRecord);\r
33175 store.matrixUpdate = 0;\r
33176 }\r
33177 }\r
33178 }\r
33179 }\r
33180 }\r
33181 }\r
33182 },\r
33183 onStoreCreate: function(store, session, id) {\r
33184 var me = this,\r
33185 matrix;\r
33186 if (session) {\r
33187
33188
33189
33190 matrix = session.getMatrixSlice(me.inverse, id);\r
33191 matrix.attach(store);\r
33192 matrix.notify = me.onMatrixUpdate;\r
33193 matrix.scope = me;\r
33194 }\r
33195 },\r
33196 processMatrixBlock: function(session, leftKeys, state) {\r
33197 var inverse = this.inverse,\r
33198 digitRe = this.digitRe,\r
33199 slice, id;\r
33200 if (leftKeys) {\r
33201 for (id in leftKeys) {\r
33202
33203
33204 if (digitRe.test(id)) {\r
33205 id = parseInt(id, 10);\r
33206 }\r
33207 slice = session.getMatrixSlice(inverse, id);\r
33208 slice.update(leftKeys[id], state);\r
33209 }\r
33210 }\r
33211 },\r
33212 createGetter: function() {\r
33213 var me = this;\r
33214 return function(options, scope, leftRecords) {\r
33215
33216 return me.getAssociatedStore(this, options, scope, leftRecords, false);\r
33217 };\r
33218 },\r
33219 \r
33220 onAddToMany: function(store, leftRecords, load) {\r
33221 if (!store.matrixUpdate) {\r
33222 store.matrixUpdate = 1;\r
33223
33224
33225 store.matrix.update(leftRecords, load === true ? 0 : 1);\r
33226 store.matrixUpdate = 0;\r
33227 }\r
33228 },\r
33229 \r
33230 onRemoveFromMany: function(store, records) {\r
33231 if (!store.matrixUpdate) {\r
33232 store.matrixUpdate = 1;\r
33233 store.matrix.update(records, -1);\r
33234 store.matrixUpdate = 0;\r
33235 }\r
33236 },\r
33237 read: function(rightRecord, node, fromReader, readOptions) {\r
33238 var me = this,\r
33239 leftRecords = me.callParent([\r
33240 rightRecord,\r
33241 node,\r
33242 fromReader,\r
33243 readOptions\r
33244 ]);\r
33245 if (leftRecords) {\r
33246
33247 rightRecord[me.getterName](null, null, leftRecords);\r
33248
33249 delete rightRecord.data[me.role];\r
33250 }\r
33251 },\r
33252 onMatrixUpdate: function(matrixSlice, id, state) {\r
33253 var store = matrixSlice.store,\r
33254 index, leftRecord, entry;\r
33255 if (store && !store.loading && !store.matrixUpdate) {\r
33256 store.matrixUpdate = 1;\r
33257 index = store.indexOfId(id);\r
33258 if (state < 0) {\r
33259 if (index >= 0) {\r
33260 store.remove([\r
33261 index\r
33262 ]);\r
33263 }\r
33264 } else if (index < 0) {\r
33265 entry = store.getSession().getEntry(this.type, id);\r
33266 leftRecord = entry && entry.record;\r
33267 if (leftRecord) {\r
33268 store.add(leftRecord);\r
33269 }\r
33270 }\r
33271 store.matrixUpdate = 0;\r
33272 }\r
33273 },\r
33274 adoptAssociated: function(record, session) {\r
33275 var store = this.getAssociatedItem(record),\r
33276 records, i, len;\r
33277 if (store) {\r
33278 store.setSession(session);\r
33279 this.onStoreCreate(store, session, record.getId());\r
33280 records = store.getData().items;\r
33281 for (i = 0 , len = records.length; i < len; ++i) {\r
33282 session.adopt(records[i]);\r
33283 }\r
33284 }\r
33285 }\r
33286 }, function() {\r
33287 var Left = this;\r
33288
33289 Ext.ClassManager.onCreated(function() {\r
33290 Ext.data.schema.ManyToMany.prototype.Right = Ext.define(null, {\r
33291 extend: Left,\r
33292 left: false,\r
33293 side: 'right'\r
33294 });\r
33295 }, null, 'Ext.data.schema.ManyToMany');\r
33296 })\r
33297});\r
33298\r
33299\r
33300Ext.define('Ext.util.Inflector', {\r
33301 \r
33302 singleton: true,\r
33303 \r
33304 \r
33305 plurals: [\r
33306 [\r
33307 (/(quiz)$/i),\r
33308 "$1zes"\r
33309 ],\r
33310 [\r
33311 (/^(ox)$/i),\r
33312 "$1en"\r
33313 ],\r
33314 [\r
33315 (/([m|l])ouse$/i),\r
33316 "$1ice"\r
33317 ],\r
33318 [\r
33319 (/(matr|vert|ind)ix|ex$/i),\r
33320 "$1ices"\r
33321 ],\r
33322 [\r
33323 (/(x|ch|ss|sh)$/i),\r
33324 "$1es"\r
33325 ],\r
33326 [\r
33327 (/([^aeiouy]|qu)y$/i),\r
33328 "$1ies"\r
33329 ],\r
33330 [\r
33331 (/(hive)$/i),\r
33332 "$1s"\r
33333 ],\r
33334 [\r
33335 (/(?:([^f])fe|([lr])f)$/i),\r
33336 "$1$2ves"\r
33337 ],\r
33338 [\r
33339 (/sis$/i),\r
33340 "ses"\r
33341 ],\r
33342 [\r
33343 (/([ti])um$/i),\r
33344 "$1a"\r
33345 ],\r
33346 [\r
33347 (/(buffal|tomat|potat)o$/i),\r
33348 "$1oes"\r
33349 ],\r
33350 [\r
33351 (/(bu)s$/i),\r
33352 "$1ses"\r
33353 ],\r
33354 [\r
33355 (/(alias|status|sex)$/i),\r
33356 "$1es"\r
33357 ],\r
33358 [\r
33359 (/(octop|vir)us$/i),\r
33360 "$1i"\r
33361 ],\r
33362 [\r
33363 (/(ax|test)is$/i),\r
33364 "$1es"\r
33365 ],\r
33366 [\r
33367 (/^(p)erson$/i),\r
33368 "$1eople"\r
33369 ],\r
33370 [\r
33371 (/^(m)an$/i),\r
33372 "$1en"\r
33373 ],\r
33374 [\r
33375 (/(.*)(child)(ren)?$/i),\r
33376 "$1$2ren"\r
33377 ],\r
33378 [\r
33379 (/s$/i),\r
33380 "s"\r
33381 ],\r
33382 [\r
33383 (/$/),\r
33384 "s"\r
33385 ]\r
33386 ],\r
33387 \r
33388 singulars: [\r
33389 [\r
33390 (/(address)$/i),\r
33391 "$1"\r
33392 ],\r
33393 [\r
33394 (/(quiz)zes$/i),\r
33395 "$1"\r
33396 ],\r
33397 [\r
33398 (/(matr)ices$/i),\r
33399 "$1ix"\r
33400 ],\r
33401 [\r
33402 (/(vert|ind)ices$/i),\r
33403 "$1ex"\r
33404 ],\r
33405 [\r
33406 (/^(ox)en/i),\r
33407 "$1"\r
33408 ],\r
33409 [\r
33410 (/(alias|status)es$/i),\r
33411 "$1"\r
33412 ],\r
33413 [\r
33414 (/(octop|vir)i$/i),\r
33415 "$1us"\r
33416 ],\r
33417 [\r
33418 (/(cris|ax|test)es$/i),\r
33419 "$1is"\r
33420 ],\r
33421 [\r
33422 (/(shoe)s$/i),\r
33423 "$1"\r
33424 ],\r
33425 [\r
33426 (/(o)es$/i),\r
33427 "$1"\r
33428 ],\r
33429 [\r
33430 (/(bus)es$/i),\r
33431 "$1"\r
33432 ],\r
33433 [\r
33434 (/([m|l])ice$/i),\r
33435 "$1ouse"\r
33436 ],\r
33437 [\r
33438 (/(x|ch|ss|sh)es$/i),\r
33439 "$1"\r
33440 ],\r
33441 [\r
33442 (/(m)ovies$/i),\r
33443 "$1ovie"\r
33444 ],\r
33445 [\r
33446 (/(s)eries$/i),\r
33447 "$1eries"\r
33448 ],\r
33449 [\r
33450 (/([^aeiouy]|qu)ies$/i),\r
33451 "$1y"\r
33452 ],\r
33453 [\r
33454 (/([lr])ves$/i),\r
33455 "$1f"\r
33456 ],\r
33457 [\r
33458 (/(tive)s$/i),\r
33459 "$1"\r
33460 ],\r
33461 [\r
33462 (/(hive)s$/i),\r
33463 "$1"\r
33464 ],\r
33465 [\r
33466 (/([^f])ves$/i),\r
33467 "$1fe"\r
33468 ],\r
33469 [\r
33470 (/(^analy)ses$/i),\r
33471 "$1sis"\r
33472 ],\r
33473 [\r
33474 (/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i),\r
33475 "$1$2sis"\r
33476 ],\r
33477 [\r
33478 (/([ti])a$/i),\r
33479 "$1um"\r
33480 ],\r
33481 [\r
33482 (/(n)ews$/i),\r
33483 "$1ews"\r
33484 ],\r
33485 [\r
33486 (/(p)eople$/i),\r
33487 "$1erson"\r
33488 ],\r
33489 [\r
33490 (/s$/i),\r
33491 ""\r
33492 ]\r
33493 ],\r
33494 \r
33495 uncountable: [\r
33496 "sheep",\r
33497 "fish",\r
33498 "series",\r
33499 "species",\r
33500 "money",\r
33501 "rice",\r
33502 "information",\r
33503 "equipment",\r
33504 "grass",\r
33505 "mud",\r
33506 "offspring",\r
33507 "deer",\r
33508 "means"\r
33509 ],\r
33510 \r
33511 singular: function(matcher, replacer) {\r
33512 this.singulars.unshift([\r
33513 matcher,\r
33514 replacer\r
33515 ]);\r
33516 },\r
33517 \r
33518 plural: function(matcher, replacer) {\r
33519 this.plurals.unshift([\r
33520 matcher,\r
33521 replacer\r
33522 ]);\r
33523 },\r
33524 \r
33525 clearSingulars: function() {\r
33526 this.singulars = [];\r
33527 },\r
33528 \r
33529 clearPlurals: function() {\r
33530 this.plurals = [];\r
33531 },\r
33532 \r
33533 isTransnumeral: function(word) {\r
33534 return Ext.Array.indexOf(this.uncountable, word) != -1;\r
33535 },\r
33536 \r
33537 pluralize: function(word) {\r
33538 if (this.isTransnumeral(word)) {\r
33539 return word;\r
33540 }\r
33541 var plurals = this.plurals,\r
33542 length = plurals.length,\r
33543 tuple, regex, i;\r
33544 for (i = 0; i < length; i++) {\r
33545 tuple = plurals[i];\r
33546 regex = tuple[0];\r
33547 if (regex == word || (regex.test && regex.test(word))) {\r
33548 return word.replace(regex, tuple[1]);\r
33549 }\r
33550 }\r
33551 return word;\r
33552 },\r
33553 \r
33554 singularize: function(word) {\r
33555 if (this.isTransnumeral(word)) {\r
33556 return word;\r
33557 }\r
33558 var singulars = this.singulars,\r
33559 length = singulars.length,\r
33560 tuple, regex, i;\r
33561 for (i = 0; i < length; i++) {\r
33562 tuple = singulars[i];\r
33563 regex = tuple[0];\r
33564 if (regex == word || (regex.test && regex.test(word))) {\r
33565 return word.replace(regex, tuple[1]);\r
33566 }\r
33567 }\r
33568 return word;\r
33569 },\r
33570 \r
33571 classify: function(word) {\r
33572 return Ext.String.capitalize(this.singularize(word));\r
33573 },\r
33574 \r
33575 ordinalize: function(number) {\r
33576 var parsed = parseInt(number, 10),\r
33577 mod10 = parsed % 10,\r
33578 mod100 = parsed % 100;\r
33579
33580 if (11 <= mod100 && mod100 <= 13) {\r
33581 return number + "th";\r
33582 } else {\r
33583 switch (mod10) {\r
33584 case 1:\r
33585 return number + "st";\r
33586 case 2:\r
33587 return number + "nd";\r
33588 case 3:\r
33589 return number + "rd";\r
33590 default:\r
33591 return number + "th";\r
33592 }\r
33593 }\r
33594 }\r
33595}, function() {\r
33596
33597 var irregulars = {\r
33598 alumnus: 'alumni',\r
33599 cactus: 'cacti',\r
33600 focus: 'foci',\r
33601 nucleus: 'nuclei',\r
33602 radius: 'radii',\r
33603 stimulus: 'stimuli',\r
33604 ellipsis: 'ellipses',\r
33605 paralysis: 'paralyses',\r
33606 oasis: 'oases',\r
33607 appendix: 'appendices',\r
33608 index: 'indexes',\r
33609 beau: 'beaux',\r
33610 bureau: 'bureaux',\r
33611 tableau: 'tableaux',\r
33612 woman: 'women',\r
33613 child: 'children',\r
33614 man: 'men',\r
33615 corpus: 'corpora',\r
33616 criterion: 'criteria',\r
33617 curriculum: 'curricula',\r
33618 genus: 'genera',\r
33619 memorandum: 'memoranda',\r
33620 phenomenon: 'phenomena',\r
33621 foot: 'feet',\r
33622 goose: 'geese',\r
33623 tooth: 'teeth',\r
33624 antenna: 'antennae',\r
33625 formula: 'formulae',\r
33626 nebula: 'nebulae',\r
33627 vertebra: 'vertebrae',\r
33628 vita: 'vitae'\r
33629 },\r
33630 singular;\r
33631 for (singular in irregulars) {\r
33632 if (irregulars.hasOwnProperty(singular)) {\r
33633 this.plural(singular, irregulars[singular]);\r
33634 this.singular(irregulars[singular], singular);\r
33635 }\r
33636 }\r
33637});\r
33638\r
33639\r
33640Ext.define('Ext.data.schema.Namer', {\r
33641 mixins: [\r
33642 Ext.mixin.Factoryable\r
33643 ],\r
33644 alias: 'namer.default',\r
33645
33646 isNamer: true,\r
33647
33648
33649 capitalize: function(name) {\r
33650 return Ext.String.capitalize(name);\r
33651 },\r
33652 \r
33653 fieldRole: function(name) {\r
33654 var match = name.match(this.endsWithIdRe, '');\r
33655 if (match) {\r
33656 name = name.substr(0, name.length - (match[1] || match[2]).length);\r
33657 }\r
33658 return this.apply('uncapitalize', name);\r
33659 },\r
33660 idField: function(name) {\r
33661
33662 return this.apply('uncapitalize,singularize', name) + 'Id';\r
33663 },\r
33664 instanceName: function(roleName) {\r
33665 return this.apply('underscore', roleName);\r
33666 },\r
33667 multiRole: function(name) {\r
33668 return this.apply('undotted,uncapitalize,pluralize', name);\r
33669 },\r
33670 pluralize: function(name) {\r
33671 return Ext.util.Inflector.pluralize(name);\r
33672 },\r
33673 readerRoot: function(roleName) {\r
33674 return this.apply('uncapitalize', roleName);\r
33675 },\r
33676 singularize: function(name) {\r
33677 return Ext.util.Inflector.singularize(name);\r
33678 },\r
33679 storeName: function(roleName) {\r
33680 return this.apply('underscore', roleName);\r
33681 },\r
33682 uncapitalize: function(name) {\r
33683 return Ext.String.uncapitalize(name);\r
33684 },\r
33685 underscore: function(name) {\r
33686 return '_' + name;\r
33687 },\r
33688 uniRole: function(name) {\r
33689 return this.apply('undotted,uncapitalize,singularize', name);\r
33690 },\r
33691 undotted: function(name) {\r
33692 if (name.indexOf('.') < 0) {\r
33693 return name;\r
33694 }\r
33695 var parts = name.split('.'),\r
33696 index = parts.length;\r
33697 while (index-- > 1) {\r
33698 parts[index] = this.apply('capitalize', parts[index]);\r
33699 }\r
33700 return parts.join('');\r
33701 },\r
33702
33703
33704 getterName: function(role) {\r
33705 var name = role.role;\r
33706 if (role && role.isMany) {\r
33707
33708 return name;\r
33709 }\r
33710
33711 return 'get' + this.apply('capitalize', name);\r
33712 },\r
33713 inverseFieldRole: function(leftType, unique, rightRole, rightType) {\r
33714
33715
33716
33717
33718 var me = this,\r
33719 leftRole = me.apply(unique ? 'uniRole' : 'multiRole', leftType),\r
33720 s1 = me.apply('pluralize', rightRole),\r
33721 s2 = me.apply('undotted,pluralize', rightType);\r
33722 if (s1.toLowerCase() !== s2.toLowerCase()) {\r
33723
33724
33725
33726 leftRole = rightRole + me.apply('capitalize', leftRole);\r
33727 }\r
33728 return leftRole;\r
33729 },\r
33730 manyToMany: function(relation, leftType, rightType) {\r
33731 var me = this,\r
33732
33733 ret = me.apply('undotted,capitalize,singularize', leftType) + me.apply('undotted,capitalize,pluralize', rightType);\r
33734 if (relation) {\r
33735 ret = me.apply('capitalize', relation + ret);\r
33736 }\r
33737 return ret;\r
33738 },\r
33739 \r
33740 manyToOne: function(leftType, leftRole, rightType, rightRole) {\r
33741
33742
33743 return this.apply('capitalize,singularize', rightType) + this.apply('capitalize', leftRole);\r
33744 },\r
33745 matrixRole: function(relation, entityType) {\r
33746 var ret = this.apply(relation ? 'multiRole,capitalize' : 'multiRole', entityType);\r
33747 return relation ? relation + ret : ret;\r
33748 },\r
33749 oneToOne: function(leftType, leftRole, rightType, rightRole) {\r
33750 return this.apply('undotted,capitalize,singularize', rightType) + this.apply('capitalize', leftRole);\r
33751 },\r
33752 setterName: function(role) {\r
33753 return 'set' + this.apply('capitalize', role.role);\r
33754 },\r
33755
33756
33757 endsWithIdRe: /(?:(_id)|[^A-Z](Id))$/,\r
33758 cache: {},\r
33759 apply: function(operation, name) {\r
33760 var me = this,\r
33761 cache = me.cache,\r
33762 entry = cache[name] || (cache[name] = {}),\r
33763 ret = entry[operation],\r
33764 i, length, operations;\r
33765 if (!ret) {\r
33766 if (operation.indexOf(',') < 0) {\r
33767 ret = me[operation](name);\r
33768 } else {\r
33769 length = (operations = operation.split(',')).length;\r
33770 ret = name;\r
33771 for (i = 0; i < length; ++i) {\r
33772 ret = me.apply(operations[i], ret);\r
33773 }\r
33774 }\r
33775 entry[operation] = ret;\r
33776 }\r
33777 return ret;\r
33778 }\r
33779});\r
33780\r
33781\r
33782Ext.define('Ext.data.schema.Schema', {\r
33783 mixins: [\r
33784 Ext.mixin.Factoryable\r
33785 ],\r
33786 alias: 'schema.default',\r
33787
33788 aliasPrefix: 'schema.',\r
33789 isSchema: true,\r
33790 \r
33791 type: 'default',\r
33792 statics: {\r
33793 \r
33794 instances: {},\r
33795 \r
33796 get: function(config) {\r
33797 var Schema = this,\r
33798 cache = Schema.instances,\r
33799 id = 'default',\r
33800 isString = config && Ext.isString(config),\r
33801 instance, newConfig;\r
33802 if (config) {\r
33803 if (config.isSchema) {\r
33804 return config;\r
33805 }\r
33806 id = isString ? config : (config.id || id);\r
33807 }\r
33808 if (!(instance = cache[id])) {\r
33809 cache[id] = instance = Schema.create(config);\r
33810 instance.id = id;\r
33811 } else if (config && !isString) {\r
33812
33813 if (id !== 'default') {\r
33814 Ext.raise('Only the default Schema instance can be reconfigured');\r
33815 }\r
33816
33817
33818
33819
33820
33821
33822
33823 newConfig = Ext.merge({}, instance.config);\r
33824 Ext.merge(newConfig, config);\r
33825 instance.setConfig(newConfig);\r
33826 instance.config = newConfig;\r
33827
33828 instance.setConfig = function() {\r
33829 Ext.raise('The schema can only be reconfigured once');\r
33830 };\r
33831 }\r
33832
33833 return instance;\r
33834 },\r
33835 lookupEntity: function(entity) {\r
33836 var ret = null,\r
33837 instances = this.instances,\r
33838 match, name, schema;\r
33839 if (entity) {\r
33840 if (entity.isEntity) {\r
33841 ret = entity.self;\r
33842 }\r
33843
33844 else if (Ext.isFunction(entity)) {\r
33845
33846 ret = entity;\r
33847 } else if (Ext.isString(entity)) {\r
33848 ret = Ext.ClassManager.get(entity);\r
33849
33850 if (ret && (!ret.prototype || !ret.prototype.isEntity)) {\r
33851 ret = null;\r
33852 }\r
33853 if (!ret) {\r
33854 for (name in instances) {\r
33855 schema = instances[name];\r
33856 match = schema.getEntity(entity);\r
33857 if (match) {\r
33858 if (ret) {\r
33859 Ext.raise('Ambiguous entity name "' + entity + '". Defined by schema "' + ret.schema.type + '" and "' + name + '"');\r
33860 }\r
33861 ret = match;\r
33862 }\r
33863 }\r
33864 }\r
33865 if (!ret) {\r
33866 Ext.raise('No such Entity "' + entity + '".');\r
33867 }\r
33868 }\r
33869 }\r
33870 return ret;\r
33871 }\r
33872 },\r
33873 \r
33874 assocCount: 0,\r
33875 \r
33876 entityCount: 0,\r
33877 config: {\r
33878 \r
33879 defaultIdentifier: null,\r
33880 \r
33881 keyCheckDelay: 10,\r
33882 \r
33883 namer: 'default',\r
33884 \r
33885 namespace: null,\r
33886 \r
33887 proxy: {\r
33888 type: 'ajax',\r
33889 url: '{prefix}/{entityName}'\r
33890 },\r
33891 \r
33892 urlPrefix: ''\r
33893 },\r
33894 onClassExtended: function(cls, data) {\r
33895 var alias = data.alias;\r
33896 if (alias && !data.type) {\r
33897 if (!Ext.isString(alias)) {\r
33898 alias = alias[0];\r
33899 }\r
33900 cls.prototype.type = alias.substring(this.prototype.aliasPrefix.length);\r
33901 }\r
33902 },\r
33903 constructor: function(config) {\r
33904 this.initConfig(config);\r
33905 this.clear();\r
33906 },\r
33907
33908
33909
33910 applyDefaultIdentifier: function(identifier) {\r
33911 return identifier && Ext.Factory.dataIdentifier(identifier);\r
33912 },\r
33913 applyNamer: function(namer) {\r
33914 var ret = Ext.data.schema.Namer.create(namer);\r
33915 ret.schema = this;\r
33916 return ret;\r
33917 },\r
33918 applyNamespace: function(namespace) {\r
33919 if (namespace) {\r
33920 var end = namespace.length - 1;\r
33921 if (namespace.charAt(end) !== '.') {\r
33922 namespace += '.';\r
33923 }\r
33924 }\r
33925 return namespace;\r
33926 },\r
33927 applyProxy: function(proxy) {\r
33928 return Ext.util.ObjectTemplate.create(proxy);\r
33929 },\r
33930
33931
33932
33933 eachAssociation: function(fn, scope) {\r
33934 var associations = this.associations,\r
33935 name;\r
33936 for (name in associations) {\r
33937 if (associations.hasOwnProperty(name)) {\r
33938 if (fn.call(scope, name, associations[name]) === false) {\r
33939 break;\r
33940 }\r
33941 }\r
33942 }\r
33943 },\r
33944 eachEntity: function(fn, scope) {\r
33945 var entities = this.entities,\r
33946 name;\r
33947 for (name in entities) {\r
33948 if (entities.hasOwnProperty(name)) {\r
33949 if (fn.call(scope, name, entities[name].cls) === false) {\r
33950 break;\r
33951 }\r
33952 }\r
33953 }\r
33954 },\r
33955 \r
33956 getAssociation: function(name) {\r
33957 var entry = this.associations[name];\r
33958 return entry || null;\r
33959 },\r
33960 \r
33961 getEntity: function(name) {\r
33962 var entry = this.entityClasses[name] || this.entities[name];\r
33963 return (entry && entry.cls) || null;\r
33964 },\r
33965 \r
33966 getEntityName: function(cls) {\r
33967 var ns = this.getNamespace(),\r
33968 index, name;\r
33969 if (typeof cls === 'string') {\r
33970 name = cls;\r
33971 } else {\r
33972 name = cls.$className || null;\r
33973 }\r
33974 if (name) {\r
33975
33976 if (ns) {\r
33977 index = ns.length;\r
33978 if (name.substring(0, index) !== ns) {\r
33979 return name;\r
33980 }\r
33981 }\r
33982 if (index) {\r
33983 name = name.substring(index);\r
33984 }\r
33985 }\r
33986 return name;\r
33987 },\r
33988 \r
33989 hasAssociations: function(name) {\r
33990 name = name.entityName || name;\r
33991 return !!this.associationEntityMap[name];\r
33992 },\r
33993 \r
33994 hasEntity: function(entity) {\r
33995 var name = this.getEntityName(entity);\r
33996 return !!(this.entities[name] || this.entityClasses[name]);\r
33997 },\r
33998
33999
34000 \r
34001 addMatrix: function(entityType, matrixName, relation, left, right) {\r
34002 var me = this,\r
34003 namer = me.getNamer(),\r
34004 associations = me.associations,\r
34005 entities = me.entities,\r
34006 leftType = left.type,\r
34007 rightType = right.type,\r
34008 leftField = left.field || namer.apply('idField', leftType),\r
34009 rightField = right.field || namer.apply('idField', rightType),\r
34010 leftRole = left.role || namer.matrixRole(relation, leftType),\r
34011 rightRole = right.role || namer.matrixRole(relation, rightType),\r
34012 matrix, leftEntry, rightEntry;\r
34013 leftEntry = entities[leftType] || (entities[leftType] = {\r
34014 cls: null,\r
34015 name: leftType,\r
34016 associations: {}\r
34017 });\r
34018 rightEntry = entities[rightType] || (entities[rightType] = {\r
34019 cls: null,\r
34020 name: rightType,\r
34021 associations: {}\r
34022 });\r
34023 ++me.assocCount;\r
34024 associations[matrixName] = matrix = new Ext.data.schema.ManyToMany({\r
34025 name: matrixName,\r
34026 schema: me,\r
34027 definedBy: entityType,\r
34028 left: {\r
34029 cls: leftEntry.cls,\r
34030 type: leftType,\r
34031 role: leftRole,\r
34032 field: leftField,\r
34033 associationKey: left.associationKey\r
34034 },\r
34035 right: {\r
34036 cls: rightEntry.cls,\r
34037 type: rightType,\r
34038 role: rightRole,\r
34039 field: rightField,\r
34040 associationKey: right.associationKey\r
34041 }\r
34042 });\r
34043 leftEntry.associations[matrix.right.role] = matrix.right;\r
34044 rightEntry.associations[matrix.left.role] = matrix.left;\r
34045 if (leftEntry.cls) {\r
34046 me.associationEntityMap[leftEntry.cls.entityName] = true;\r
34047 }\r
34048 if (rightEntry.cls) {\r
34049 me.associationEntityMap[rightEntry.cls.entityName] = true;\r
34050 }\r
34051 me.decorateModel(matrix);\r
34052 },\r
34053 \r
34054 addReference: function(entityType, referenceField, descr, unique) {\r
34055 var me = this,\r
34056 namer = me.getNamer(),\r
34057 entities = me.entities,\r
34058 associations = me.associations,\r
34059 entityName = entityType.entityName,\r
34060 association = descr.association,\r
34061 legacy = !!descr.legacy,\r
34062 child = descr.child,\r
34063 parent = descr.parent,\r
34064 rightRole = descr.role,\r
34065
34066 rightType = descr.type || parent || child,\r
34067 leftVal = descr.inverse,\r
34068 left = Ext.isString(leftVal) ? {\r
34069 role: leftVal\r
34070 } : leftVal,\r
34071 leftRole = left && left.role,\r
34072 entry, T;\r
34073 if (!rightRole) {\r
34074
34075
34076
34077 if (legacy) {\r
34078 rightRole = namer.apply('uncapitalize', rightType);\r
34079 } else {\r
34080 rightRole = namer.apply('fieldRole', referenceField.name);\r
34081 }\r
34082 }\r
34083 if (!leftRole) {\r
34084 leftRole = namer.inverseFieldRole(entityName, unique, rightRole, rightType);\r
34085 }\r
34086 if (!association) {\r
34087 if (unique) {\r
34088 association = namer.oneToOne(entityType, leftRole, rightType, rightRole);\r
34089 } else {\r
34090 association = namer.manyToOne(entityType, leftRole, rightType, rightRole);\r
34091 }\r
34092 }\r
34093
34094 if (association in associations) {\r
34095 Ext.raise('Duplicate association: "' + association + '" declared by ' + entityName + (referenceField ? ('.' + referenceField.name) : '') + ' (collides with ' + associations[association].definedBy.entityName + ')');\r
34096 }\r
34097 if (referenceField && referenceField.definedBy === entities[rightType]) {\r
34098 Ext.raise('ForeignKey reference should not be owned by the target model');\r
34099 }\r
34100
34101
34102
34103 entry = entities[rightType] || (entities[rightType] = {\r
34104 cls: null,\r
34105 name: rightType,\r
34106 associations: {}\r
34107 });\r
34108
34109 T = unique ? Ext.data.schema.OneToOne : Ext.data.schema.ManyToOne;\r
34110 association = new T({\r
34111 name: association,\r
34112
34113 owner: child ? 'left' : (parent ? 'right' : null),\r
34114 definedBy: entityType,\r
34115 schema: me,\r
34116 field: referenceField,\r
34117 nullable: referenceField ? !!referenceField.allowBlank : true,\r
34118 legacy: descr.legacy,\r
34119 left: {\r
34120 cls: entityType,\r
34121 type: entityName,\r
34122 role: leftRole,\r
34123 extra: left\r
34124 },\r
34125 right: {\r
34126 cls: entry.cls,\r
34127 type: rightType,\r
34128 role: rightRole,\r
34129 extra: descr\r
34130 }\r
34131 });\r
34132
34133
34134
34135 entityType.associations[rightRole] = association.right;\r
34136 entry.associations[leftRole] = association.left;\r
34137 if (referenceField) {\r
34138
34139
34140 referenceField.reference = association.right;\r
34141 entityType.references.push(referenceField);\r
34142 }\r
34143 ++me.assocCount;\r
34144 me.associationEntityMap[entityName] = true;\r
34145 if (entry.cls) {\r
34146 me.associationEntityMap[entry.cls.entityName] = true;\r
34147 }\r
34148 associations[association.name] = association;\r
34149 if (association.right.cls) {\r
34150 me.decorateModel(association);\r
34151 }\r
34152 },\r
34153
34154 privates: {\r
34155 \r
34156 addEntity: function(entityType) {\r
34157 var me = this,\r
34158 entities = me.entities,\r
34159 entityName = entityType.entityName,\r
34160 entry = entities[entityName],\r
34161 fields = entityType.fields,\r
34162 associations, field, i, length, name;\r
34163 if (!entry) {\r
34164 entities[entityName] = entry = {\r
34165 name: entityName,\r
34166 associations: {}\r
34167 };\r
34168 }\r
34169
34170 else if (entry.cls) {\r
34171 Ext.raise('Duplicate entity name "' + entityName + '": ' + entry.cls.$className + ' and ' + entityType.$className);\r
34172 } else
34173 {\r
34174 associations = entry.associations;\r
34175 for (name in associations) {\r
34176
34177
34178 associations[name].inverse.cls = entityType;\r
34179 me.associationEntityMap[entityName] = true;\r
34180
34181
34182 me.decorateModel(associations[name].association);\r
34183 }\r
34184 }\r
34185 entry.cls = entityType;\r
34186 entityType.prototype.associations = entityType.associations = entry.associations;\r
34187 me.entityClasses[entityType.$className] = entry;\r
34188 ++me.entityCount;\r
34189 for (i = 0 , length = fields.length; i < length; ++i) {\r
34190 field = fields[i];\r
34191 if (field.reference) {\r
34192 me.addReferenceDescr(entityType, field);\r
34193 }\r
34194 }\r
34195 },\r
34196 \r
34197 addMatrices: function(entityType, matrices) {\r
34198 var me = this,\r
34199 i, length, matrixName;\r
34200 if (Ext.isString(matrices)) {\r
34201 me.addMatrixDescr(entityType, null, matrices);\r
34202 } else if (matrices[0]) {\r
34203
34204 for (i = 0 , length = matrices.length; i < length; ++i) {\r
34205 me.addMatrixDescr(entityType, null, matrices[i]);\r
34206 }\r
34207 } else {\r
34208 for (matrixName in matrices) {\r
34209 me.addMatrixDescr(entityType, matrixName, matrices[matrixName]);\r
34210 }\r
34211 }\r
34212 },\r
34213 \r
34214 addMatrixDescr: function(entityType, matrixName, matrixDef) {\r
34215 var me = this,\r
34216 entityName = entityType.entityName,\r
34217 associations = me.associations,\r
34218 namer = me.getNamer(),\r
34219 left = matrixDef.left,\r
34220 right = matrixDef.right,\r
34221 last, relation;\r
34222 if (Ext.isString(matrixDef)) {\r
34223 if (matrixDef.charAt(0) === '#') {\r
34224
34225 \r
34226 left = {\r
34227 type: entityName\r
34228 };\r
34229
34230 right = {\r
34231 type: matrixDef.substring(1)\r
34232 };\r
34233 }\r
34234
34235 else if (matrixDef.charAt(last = matrixDef.length - 1) === '#') {\r
34236
34237 \r
34238 left = {\r
34239 type: matrixDef.substring(0, last)\r
34240 };\r
34241
34242 right = {\r
34243 type: entityName\r
34244 };\r
34245 }\r
34246
34247 else if (namer.apply('multiRole', entityName) < namer.apply('multiRole', matrixDef)) {\r
34248 \r
34249 left = {\r
34250 type: entityName\r
34251 };\r
34252
34253 right = {\r
34254 type: matrixDef\r
34255 };\r
34256 } else
34257 {\r
34258 \r
34259 left = {\r
34260 type: matrixDef\r
34261 };\r
34262
34263 right = {\r
34264 type: entityName\r
34265 };\r
34266 }\r
34267 } else
34268 {\r
34269
34270 Ext.Assert.isString(matrixDef.type, 'No "type" for manyToMany in ' + entityName);\r
34271
34272 relation = matrixDef.relation;\r
34273 if (left || (!right && namer.apply('multiRole', entityName) < namer.apply('multiRole', matrixDef.type))) {\r
34274 if (!left || left === true) {\r
34275 \r
34276 left = {\r
34277 type: entityName\r
34278 };\r
34279 } else
34280 {\r
34281 \r
34282 left = Ext.apply({\r
34283 type: entityName\r
34284 }, left);\r
34285 }\r
34286
34287 right = matrixDef;\r
34288 } else
34289 {\r
34290 if (!right || right === true) {\r
34291 \r
34292 right = {\r
34293 type: entityName\r
34294 };\r
34295 } else
34296 {\r
34297 \r
34298 right = Ext.apply({\r
34299 type: entityName\r
34300 }, right);\r
34301 }\r
34302
34303 left = matrixDef;\r
34304 }\r
34305 }\r
34306
34307 if (!matrixName) {\r
34308 matrixName = namer.manyToMany(relation, left.type, right.type);\r
34309 }\r
34310 if (!(matrixName in associations)) {\r
34311 me.addMatrix(entityType, matrixName, relation, left, right);\r
34312 } else
34313
34314
34315
34316
34317
34318 {\r
34319 var entry = associations[matrixName],\r
34320 before = [\r
34321 entry.kind,\r
34322 entry.left.type,\r
34323 entry.left.role,\r
34324 entry.left.field,\r
34325 entry.right.type,\r
34326 entry.right.role,\r
34327 entry.right.field\r
34328 ].join('|');\r
34329
34330 delete associations[matrixName];\r
34331 me.addMatrix(entityType, matrixName, relation, left, right);\r
34332 var after = associations[matrixName];\r
34333
34334 associations[matrixName] = entry;\r
34335 entry.left.cls.associations[entry.right.role] = entry.right;\r
34336 entry.right.cls.associations[entry.left.role] = entry.left;\r
34337 --me.assocCount;\r
34338
34339 after = [\r
34340 after.kind,\r
34341 after.left.type,\r
34342 after.left.role,\r
34343 after.left.field,\r
34344 after.right.type,\r
34345 after.right.role,\r
34346 after.right.field\r
34347 ].join('|');\r
34348 if (before != after) {\r
34349 Ext.log.warn(matrixName + '(' + entry.definedBy.entityName + '): ' + before);\r
34350 Ext.log.warn(matrixName + '(' + entityName + '): ' + after);\r
34351 Ext.raise('Conflicting association: "' + matrixName + '" declared by ' + entityName + ' was previously declared by ' + entry.definedBy.entityName);\r
34352 }\r
34353 }\r
34354 },\r
34355
34356 \r
34357 addReferenceDescr: function(entityType, referenceField) {\r
34358 var me = this,\r
34359 descr = referenceField.$reference;\r
34360 if (Ext.isString(descr)) {\r
34361 descr = {\r
34362 type: descr\r
34363 };\r
34364 } else {\r
34365 descr = Ext.apply({}, descr);\r
34366 }\r
34367 if (descr.legacy) {\r
34368 if (descr.single) {\r
34369 me.addLegacySingle(entityType, descr);\r
34370 } else {\r
34371 me.addLegacyHasMany(entityType, descr);\r
34372 }\r
34373 } else {\r
34374 me.addReference(entityType, referenceField, descr, referenceField.unique);\r
34375 }\r
34376 },\r
34377
34378
34379
34380 addPending: function(name, entityType, assoc, type) {\r
34381 var pending = this.pending;\r
34382 if (!pending[name]) {\r
34383 pending[name] = [];\r
34384 }\r
34385 pending[name].push([\r
34386 entityType,\r
34387 assoc,\r
34388 type\r
34389 ]);\r
34390 },\r
34391 addLegacyBelongsTo: function(entityType, assoc) {\r
34392 this.addLegacySingle(entityType, assoc);\r
34393 },\r
34394 addLegacyHasOne: function(entityType, assoc) {\r
34395 this.addLegacySingle(entityType, assoc);\r
34396 },\r
34397 addLegacySingle: function(entityType, assoc) {\r
34398 var foreignKey, name, referenceField;\r
34399 assoc = this.constructLegacyAssociation(entityType, assoc);\r
34400 assoc.single = true;\r
34401 name = assoc.type;\r
34402 foreignKey = assoc.foreignKey || (name.toLowerCase() + '_id');\r
34403 referenceField = entityType.getField(foreignKey);\r
34404 if (referenceField) {\r
34405 referenceField.$reference = assoc;\r
34406 }\r
34407 this.addReference(entityType, referenceField, assoc, true);\r
34408 },\r
34409 addLegacyHasMany: function(entityType, assoc) {\r
34410 var me = this,\r
34411 entities = me.entities,\r
34412 pending = me.pending,\r
34413 associationKey = assoc.associationKey,\r
34414 cls, name, referenceField, target, foreignKey, assocName;\r
34415 assoc = this.constructLegacyAssociation(entityType, assoc);\r
34416 name = assoc.type;\r
34417 target = entities[name];\r
34418 if (target && target.cls) {\r
34419 assoc.type = entityType.entityName;\r
34420 foreignKey = assoc.foreignKey || (assoc.type.toLowerCase() + '_id');\r
34421 cls = target.cls;\r
34422 referenceField = cls.getField(foreignKey);\r
34423 assoc.inverse = assoc || {};\r
34424 assocName = assoc.name;\r
34425 if (assocName || associationKey) {\r
34426 if (assocName) {\r
34427 assoc.inverse.role = assocName;\r
34428 }\r
34429 if (associationKey) {\r
34430 assoc.inverse.associationKey = associationKey;\r
34431 }\r
34432 }\r
34433 if (referenceField) {\r
34434 referenceField.$reference = assoc;\r
34435 }\r
34436
34437 me.addReference(cls, referenceField, assoc, false);\r
34438 } else {\r
34439
34440 if (!pending[name]) {\r
34441 pending[name] = [];\r
34442 }\r
34443 pending[name].push([\r
34444 entityType,\r
34445 assoc\r
34446 ]);\r
34447 }\r
34448 },\r
34449 constructLegacyAssociation: function(entityType, assoc) {\r
34450 if (Ext.isString(assoc)) {\r
34451 assoc = {\r
34452 model: assoc\r
34453 };\r
34454 }\r
34455 assoc.legacy = true;\r
34456 assoc.type = this.getEntityName(assoc.model);\r
34457 var name = assoc.associatedName || assoc.name;\r
34458 if (name) {\r
34459 assoc.role = name;\r
34460 }\r
34461 return assoc;\r
34462 },\r
34463 afterLegacyAssociations: function(cls) {\r
34464 var pending = this.pending,\r
34465 name = cls.entityName,\r
34466 mine = pending[name],\r
34467 i, len;\r
34468 if (mine) {\r
34469 for (i = 0 , len = mine.length; i < len; ++i) {\r
34470 this.addLegacyHasMany.apply(this, mine[i]);\r
34471 }\r
34472 delete pending[name];\r
34473 }\r
34474 },\r
34475 clear: function(clearNamespace) {\r
34476
34477 var me = this,\r
34478 timer = me.timer;\r
34479 delete me.setConfig;\r
34480 if (timer) {\r
34481 window.clearTimeout(timer);\r
34482 me.timer = null;\r
34483 }\r
34484 me.associations = {};\r
34485 me.associationEntityMap = {};\r
34486 me.entities = {};\r
34487 me.entityClasses = {};\r
34488 me.pending = {};\r
34489 me.assocCount = me.entityCount = 0;\r
34490 if (clearNamespace) {\r
34491 me.setNamespace(null);\r
34492 }\r
34493 },\r
34494 constructProxy: function(Model) {\r
34495 var me = this,\r
34496 data = Ext.Object.chain(Model),\r
34497 proxy = me.getProxy();\r
34498 data.schema = me;\r
34499 data.prefix = me.getUrlPrefix();\r
34500 return proxy.apply(data);\r
34501 },\r
34502 applyDecoration: function(role) {\r
34503 var me = this,\r
34504
34505
34506
34507
34508 cls = role.inverse.cls,\r
34509 namer = me.getNamer(),\r
34510 getterName, setterName, proto;\r
34511
34512
34513 if (cls && !role.decorated) {\r
34514 role.decorated = true;\r
34515 proto = cls.prototype;\r
34516 if (!(getterName = role.getterName)) {\r
34517 role.getterName = getterName = namer.getterName(role);\r
34518 }\r
34519 proto[getterName] = role.createGetter();\r
34520
34521 if (role.createSetter) {\r
34522 if (!(setterName = role.setterName)) {\r
34523 role.setterName = setterName = namer.setterName(role);\r
34524 }\r
34525 proto[setterName] = role.createSetter();\r
34526 }\r
34527 }\r
34528 },\r
34529 decorateModel: function(association) {\r
34530 this.applyDecoration(association.left);\r
34531 this.applyDecoration(association.right);\r
34532 },\r
34533 processKeyChecks: function(processAll) {\r
34534 var me = this,\r
34535 keyCheckQueue = me.keyCheckQueue,\r
34536 timer = me.timer,\r
34537 len, i, item;\r
34538 if (timer) {\r
34539 window.clearTimeout(timer);\r
34540 me.timer = null;\r
34541 }\r
34542 if (!keyCheckQueue) {\r
34543 return;\r
34544 }\r
34545
34546
34547
34548
34549 do {\r
34550 keyCheckQueue = me.keyCheckQueue;\r
34551 me.keyCheckQueue = [];\r
34552 for (i = 0 , len = keyCheckQueue.length; i < len; ++i) {\r
34553 item = keyCheckQueue[i];\r
34554 item.role.checkKeyForDrop(item.record);\r
34555 }\r
34556 } while (processAll && me.keyCheckQueue.length);\r
34557 },\r
34558 queueKeyCheck: function(record, role) {\r
34559 var me = this,\r
34560 keyCheckQueue = me.keyCheckQueue,\r
34561 timer = me.timer;\r
34562 if (!keyCheckQueue) {\r
34563 me.keyCheckQueue = keyCheckQueue = [];\r
34564 }\r
34565 keyCheckQueue.push({\r
34566 record: record,\r
34567 role: role\r
34568 });\r
34569 if (!timer) {\r
34570 me.timer = timer = Ext.Function.defer(me.processKeyChecks, me.getKeyCheckDelay(), me);\r
34571 }\r
34572 },\r
34573 rankEntities: function() {\r
34574 var me = this,\r
34575 entities = me.entities,\r
34576 entityNames = Ext.Object.getKeys(entities),\r
34577 length = entityNames.length,\r
34578 entityType, i;\r
34579 me.nextRank = 1;\r
34580
34581 entityNames.sort();\r
34582 for (i = 0; i < length; ++i) {\r
34583 entityType = entities[entityNames[i]].cls;\r
34584 if (!entityType.rank) {\r
34585 me.rankEntity(entityType);\r
34586 }\r
34587 }\r
34588
34589 me.topoStack = null;\r
34590 },\r
34591
34592
34593 rankEntity: function(entityType) {\r
34594 var associations = entityType.associations,\r
34595 associatedType, role, roleName;\r
34596
34597 var topoStack = this.topoStack || (this.topoStack = []),\r
34598 entityName = entityType.entityName;\r
34599 topoStack.push(entityName);\r
34600 if (entityType.rank === 0) {\r
34601 Ext.raise(entityName + " has circular foreign-key references: " + topoStack.join(" --> "));\r
34602 }\r
34603 entityType.rank = 0;\r
34604
34605
34606 for (roleName in associations) {\r
34607 role = associations[roleName];\r
34608
34609
34610
34611
34612
34613 if (!role.left && role.association.field) {\r
34614
34615
34616 associatedType = role.cls;\r
34617 if (!associatedType.rank) {\r
34618 this.rankEntity(associatedType);\r
34619 }\r
34620 }\r
34621 }\r
34622 entityType.rank = this.nextRank++;\r
34623
34624 topoStack.pop();\r
34625 }\r
34626 }\r
34627});\r
34628
34629
34630\r
34631\r
34632Ext.define('Ext.data.AbstractStore', {\r
34633 mixins: [\r
34634 Ext.mixin.Observable,\r
34635 Ext.mixin.Factoryable\r
34636 ],\r
34637 factoryConfig: {\r
34638 defaultType: 'store',\r
34639 type: 'store'\r
34640 },\r
34641 $configPrefixed: false,\r
34642 $configStrict: false,\r
34643 config: {\r
34644 \r
34645 filters: null,\r
34646 \r
34647 autoDestroy: undefined,\r
34648 \r
34649 storeId: null,\r
34650 \r
34651 statefulFilters: false,\r
34652 \r
34653 sorters: null,\r
34654 \r
34655 remoteSort: {\r
34656 lazy: true,\r
34657 $value: false\r
34658 },\r
34659 \r
34660 remoteFilter: {\r
34661 lazy: true,\r
34662 $value: false\r
34663 },\r
34664 \r
34665 groupField: undefined,\r
34666 \r
34667 groupDir: 'ASC',\r
34668 \r
34669 grouper: null,\r
34670 \r
34671 pageSize: 25\r
34672 },\r
34673 \r
34674 currentPage: 1,\r
34675 \r
34676 loading: false,\r
34677 \r
34678 isStore: true,\r
34679 \r
34680 updating: 0,\r
34681
34682 constructor: function(config) {\r
34683 var me = this,\r
34684 storeId;\r
34685 \r
34686 \r
34687 \r
34688 \r
34689 \r
34690 \r
34691 \r
34692 \r
34693 \r
34694 \r
34695 me.isInitializing = true;\r
34696 me.mixins.observable.constructor.call(me, config);\r
34697 me.isInitializing = false;\r
34698 storeId = me.getStoreId();\r
34699 if (!storeId && (config && config.id)) {\r
34700 me.setStoreId(storeId = config.id);\r
34701 }\r
34702 if (storeId) {\r
34703 Ext.data.StoreManager.register(me);\r
34704 }\r
34705 },\r
34706 \r
34707 getCount: function() {\r
34708 return this.getData().getCount();\r
34709 },\r
34710 \r
34711 rangeCached: function(start, end) {\r
34712 return this.getData().getCount() >= Math.max(start, end);\r
34713 },\r
34714 \r
34715 \r
34716 find: function(property, value, startIndex, anyMatch, caseSensitive, exactMatch) {\r
34717
34718
34719
34720
34721
34722 var startsWith = !anyMatch,\r
34723 endsWith = !!(startsWith && exactMatch);\r
34724 return this.getData().findIndex(property, value, startIndex, startsWith, endsWith, !caseSensitive);\r
34725 },\r
34726 \r
34727 findRecord: function() {\r
34728 var me = this,\r
34729 index = me.find.apply(me, arguments);\r
34730 return index !== -1 ? me.getAt(index) : null;\r
34731 },\r
34732 \r
34733 findExact: function(property, value, start) {\r
34734 return this.getData().findIndexBy(function(rec) {\r
34735 return rec.isEqual(rec.get(property), value);\r
34736 }, this, start);\r
34737 },\r
34738 \r
34739 findBy: function(fn, scope, start) {\r
34740 return this.getData().findIndexBy(fn, scope, start);\r
34741 },\r
34742 \r
34743 getAt: function(index) {\r
34744 return this.getData().getAt(index) || null;\r
34745 },\r
34746 \r
34747 getRange: function(start, end, \r
34748 options) {\r
34749
34750 var result = this.getData().getRange(start, Ext.isNumber(end) ? end + 1 : end);\r
34751
34752
34753 if (options && options.callback) {\r
34754 options.callback.call(options.scope || this, result, start, end, options);\r
34755 }\r
34756 return result;\r
34757 },\r
34758 \r
34759 getFilters: function(\r
34760 autoCreate) {\r
34761 var result = this.callParent();\r
34762 if (!result && autoCreate !== false) {\r
34763 this.setFilters([]);\r
34764 result = this.callParent();\r
34765 }\r
34766 return result;\r
34767 },\r
34768 applyFilters: function(filters, filtersCollection) {\r
34769 var created;\r
34770 if (!filtersCollection) {\r
34771 filtersCollection = this.createFiltersCollection();\r
34772 created = true;\r
34773 }\r
34774 filtersCollection.add(filters);\r
34775 if (created) {\r
34776 this.onRemoteFilterSet(filtersCollection, this.getRemoteFilter());\r
34777 }\r
34778 return filtersCollection;\r
34779 },\r
34780 \r
34781 getSorters: function(\r
34782 autoCreate) {\r
34783 var result = this.callParent();\r
34784 if (!result && autoCreate !== false) {\r
34785
34786 this.setSorters([]);\r
34787 result = this.callParent();\r
34788 }\r
34789 return result;\r
34790 },\r
34791 applySorters: function(sorters, sortersCollection) {\r
34792 var created;\r
34793 if (!sortersCollection) {\r
34794 sortersCollection = this.createSortersCollection();\r
34795 created = true;\r
34796 }\r
34797 sortersCollection.add(sorters);\r
34798 if (created) {\r
34799 this.onRemoteSortSet(sortersCollection, this.getRemoteSort());\r
34800 }\r
34801 return sortersCollection;\r
34802 },\r
34803 \r
34804 filter: function(filters, value, supressEvent) {\r
34805 if (Ext.isString(filters)) {\r
34806 filters = {\r
34807 property: filters,\r
34808 value: value\r
34809 };\r
34810 }\r
34811 this.suppressNextFilter = !!supressEvent;\r
34812 this.getFilters().add(filters);\r
34813 this.suppressNextFilter = false;\r
34814 },\r
34815 \r
34816 removeFilter: function(filter, supressEvent) {\r
34817 var me = this,\r
34818 filters = me.getFilters();\r
34819 me.suppressNextFilter = !!supressEvent;\r
34820 if (filter instanceof Ext.util.Filter) {\r
34821 filters.remove(filter);\r
34822 } else {\r
34823 filters.removeByKey(filter);\r
34824 }\r
34825 me.suppressNextFilter = false;\r
34826 },\r
34827 updateRemoteSort: function(remoteSort) {\r
34828
34829
34830 this.onRemoteSortSet(this.getSorters(false), remoteSort);\r
34831 },\r
34832 updateRemoteFilter: function(remoteFilter) {\r
34833 this.onRemoteFilterSet(this.getFilters(false), remoteFilter);\r
34834 },\r
34835 \r
34836 addFilter: function(filters, supressEvent) {\r
34837 this.suppressNextFilter = !!supressEvent;\r
34838 this.getFilters().add(filters);\r
34839 this.suppressNextFilter = false;\r
34840 },\r
34841 \r
34842 filterBy: function(fn, scope) {\r
34843 this.getFilters().add({\r
34844 filterFn: fn,\r
34845 scope: scope || this\r
34846 });\r
34847 },\r
34848 \r
34849 clearFilter: function(supressEvent) {\r
34850 var me = this,\r
34851 filters = me.getFilters(false);\r
34852 if (!filters || filters.getCount() === 0) {\r
34853 return;\r
34854 }\r
34855 me.suppressNextFilter = !!supressEvent;\r
34856 filters.removeAll();\r
34857 me.suppressNextFilter = false;\r
34858 },\r
34859 \r
34860 isFiltered: function() {\r
34861 return this.getFilters().getCount() > 0;\r
34862 },\r
34863 \r
34864 isSorted: function() {\r
34865 var sorters = this.getSorters(false);\r
34866 return !!(sorters && sorters.length > 0) || this.isGrouped();\r
34867 },\r
34868 addFieldTransform: function(sorter) {\r
34869
34870 if (sorter.getTransform()) {\r
34871 return;\r
34872 }\r
34873 var fieldName = sorter.getProperty(),\r
34874 Model = this.getModel(),\r
34875 field, sortType;\r
34876 if (Model) {\r
34877 field = Model.getField(fieldName);\r
34878 sortType = field ? field.getSortType() : null;\r
34879 }\r
34880 if (sortType && sortType !== Ext.identityFn) {\r
34881 sorter.setTransform(sortType);\r
34882 }\r
34883 },\r
34884 \r
34885 beginUpdate: function() {\r
34886 if (!this.updating++) {\r
34887
34888 this.fireEvent('beginupdate');\r
34889 }\r
34890 },\r
34891 \r
34892 endUpdate: function() {\r
34893 if (this.updating && !--this.updating) {\r
34894 this.fireEvent('endupdate');\r
34895 this.onEndUpdate();\r
34896 }\r
34897 },\r
34898 \r
34899 getState: function() {\r
34900 var me = this,\r
34901 sorters = [],\r
34902 filters = me.getFilters(),\r
34903 grouper = me.getGrouper(),\r
34904 filterState, hasState, result;\r
34905
34906 me.getSorters().each(function(s) {\r
34907 sorters[sorters.length] = s.getState();\r
34908 hasState = true;\r
34909 });\r
34910
34911
34912 if (me.statefulFilters && me.saveStatefulFilters) {\r
34913
34914
34915
34916 hasState = true;\r
34917 filterState = [];\r
34918 filters.each(function(f) {\r
34919 filterState[filterState.length] = f.getState();\r
34920 });\r
34921 }\r
34922 if (grouper) {\r
34923 hasState = true;\r
34924 }\r
34925
34926 if (hasState) {\r
34927 result = {};\r
34928 if (sorters.length) {\r
34929 result.sorters = sorters;\r
34930 }\r
34931 if (filterState) {\r
34932 result.filters = filterState;\r
34933 }\r
34934 if (grouper) {\r
34935 result.grouper = grouper.getState();\r
34936 }\r
34937 }\r
34938 return result;\r
34939 },\r
34940 \r
34941 applyState: function(state) {\r
34942 var me = this,\r
34943 stateSorters = state.sorters,\r
34944 stateFilters = state.filters,\r
34945 stateGrouper = state.grouper;\r
34946 if (stateSorters) {\r
34947 me.getSorters().replaceAll(stateSorters);\r
34948 }\r
34949 if (stateFilters) {\r
34950
34951 me.saveStatefulFilters = true;\r
34952 me.getFilters().replaceAll(stateFilters);\r
34953 }\r
34954 if (stateGrouper) {\r
34955 me.setGrouper(stateGrouper);\r
34956 }\r
34957 },\r
34958 \r
34959 \r
34960 hasPendingLoad: Ext.emptyFn,\r
34961 \r
34962 isLoaded: Ext.emptyFn,\r
34963 \r
34964 isLoading: Ext.emptyFn,\r
34965 destroy: function() {\r
34966 var me = this;\r
34967 if (me.getStoreId()) {\r
34968 Ext.data.StoreManager.unregister(me);\r
34969 }\r
34970 me.callParent();\r
34971 me.onDestroy();\r
34972 },\r
34973 \r
34974 sort: function(field, direction, mode) {\r
34975 var me = this;\r
34976 if (arguments.length === 0) {\r
34977 if (me.getRemoteSort()) {\r
34978 me.load();\r
34979 } else {\r
34980 me.forceLocalSort();\r
34981 }\r
34982 } else {\r
34983 me.getSorters().addSort(field, direction, mode);\r
34984 }\r
34985 },\r
34986
34987
34988 onBeforeCollectionSort: function(store, sorters) {\r
34989 if (sorters) {\r
34990 this.fireEvent('beforesort', this, sorters.getRange());\r
34991 }\r
34992 },\r
34993 onSorterEndUpdate: function() {\r
34994 var me = this,\r
34995 sorters;\r
34996
34997 sorters = me.getSorters(false);\r
34998 if (me.settingGroups || !sorters) {\r
34999 return;\r
35000 }\r
35001 sorters = sorters.getRange();\r
35002
35003 if (sorters.length) {\r
35004 if (me.getRemoteSort()) {\r
35005 me.load({\r
35006 callback: function() {\r
35007 me.fireEvent('sort', me, sorters);\r
35008 }\r
35009 });\r
35010 } else {\r
35011 me.fireEvent('datachanged', me);\r
35012 me.fireEvent('refresh', me);\r
35013 me.fireEvent('sort', me, sorters);\r
35014 }\r
35015 } else {\r
35016
35017 me.fireEvent('sort', me, sorters);\r
35018 }\r
35019 },\r
35020 onFilterEndUpdate: function() {\r
35021 var me = this,\r
35022 suppressNext = me.suppressNextFilter;\r
35023 if (me.getRemoteFilter()) {\r
35024
35025 me.getFilters().each(function(filter) {\r
35026 if (filter.getInitialConfig().filterFn) {\r
35027 Ext.raise('Unable to use a filtering function in conjunction with remote filtering.');\r
35028 }\r
35029 });\r
35030
35031 me.currentPage = 1;\r
35032 if (!suppressNext) {\r
35033 me.load();\r
35034 }\r
35035 } else if (!suppressNext) {\r
35036 me.fireEvent('datachanged', me);\r
35037 me.fireEvent('refresh', me);\r
35038 }\r
35039 if (me.trackStateChanges) {\r
35040
35041 me.saveStatefulFilters = true;\r
35042 }\r
35043
35044 me.fireEvent('filterchange', me, me.getFilters().getRange());\r
35045 },\r
35046 updateGroupField: function(field) {\r
35047 if (field) {\r
35048 this.setGrouper({\r
35049 property: field,\r
35050 direction: this.getGroupDir()\r
35051 });\r
35052 } else {\r
35053 this.setGrouper(null);\r
35054 }\r
35055 },\r
35056 \r
35057 \r
35058 getGrouper: function() {\r
35059 return this.getData().getGrouper();\r
35060 },\r
35061 \r
35062 group: function(grouper, direction) {\r
35063 var me = this,\r
35064 sorters = me.getSorters(false),\r
35065 change = grouper || (sorters && sorters.length);\r
35066 if (grouper && typeof grouper === 'string') {\r
35067 grouper = {\r
35068 property: grouper,\r
35069 direction: direction || me.getGroupDir()\r
35070 };\r
35071 }\r
35072 me.settingGroups = true;\r
35073 me.getData().setGrouper(grouper);\r
35074 delete me.settingGroups;\r
35075 if (change) {\r
35076 if (me.getRemoteSort()) {\r
35077 me.load({\r
35078 scope: me,\r
35079 callback: me.fireGroupChange\r
35080 });\r
35081 } else {\r
35082 me.fireEvent('datachanged', me);\r
35083 me.fireEvent('refresh', me);\r
35084 me.fireGroupChange();\r
35085 }\r
35086 } else
35087
35088 {\r
35089 me.fireGroupChange();\r
35090 }\r
35091 },\r
35092 fireGroupChange: function() {\r
35093 if (!this.destroyed) {\r
35094 this.fireEvent('groupchange', this, this.getGrouper());\r
35095 }\r
35096 },\r
35097 \r
35098 clearGrouping: function() {\r
35099 this.group(null);\r
35100 },\r
35101 getGroupField: function() {\r
35102 var grouper = this.getGrouper(),\r
35103 group = '';\r
35104 if (grouper) {\r
35105 group = grouper.getProperty();\r
35106 }\r
35107 return group;\r
35108 },\r
35109 \r
35110 isGrouped: function() {\r
35111 return !!this.getGrouper();\r
35112 },\r
35113 applyGrouper: function(grouper) {\r
35114 this.group(grouper);\r
35115 return this.getData().getGrouper();\r
35116 },\r
35117 \r
35118 getGroups: function() {\r
35119 return this.getData().getGroups();\r
35120 },\r
35121 onEndUpdate: Ext.emptyFn,\r
35122 privates: {\r
35123 loadsSynchronously: Ext.privateFn,\r
35124 onRemoteFilterSet: function(filters, remoteFilter) {\r
35125 if (filters) {\r
35126 filters[remoteFilter ? 'on' : 'un']('endupdate', this.onFilterEndUpdate, this);\r
35127 }\r
35128 },\r
35129
35130
35131
35132
35133
35134 onRemoteSortSet: function(sorters, remoteSort) {\r
35135 var me = this;\r
35136 if (sorters) {\r
35137 sorters[remoteSort ? 'on' : 'un']('endupdate', me.onSorterEndUpdate, me);\r
35138 me.getData()[remoteSort ? 'un' : 'on']('beforesort', me.onBeforeCollectionSort, me);\r
35139 }\r
35140 }\r
35141 },\r
35142 deprecated: {\r
35143 5: {\r
35144 methods: {\r
35145 destroyStore: function() {\r
35146 this.destroy();\r
35147 }\r
35148 }\r
35149 }\r
35150 }\r
35151});\r
35152\r
35153\r
35154Ext.define('Ext.data.Error', {\r
35155 isError: true,\r
35156 $configPrefixed: false,\r
35157
35158 config: {\r
35159 \r
35160 field: null,\r
35161 \r
35162 message: ''\r
35163 },\r
35164 constructor: function(config) {\r
35165 this.initConfig(config);\r
35166 this.msg = this.message;\r
35167 }\r
35168});\r
35169
35170\r
35171\r
35172Ext.define('Ext.data.ErrorCollection', {\r
35173 extend: Ext.util.MixedCollection,\r
35174
35175 alternateClassName: 'Ext.data.Errors',\r
35176 init: function(record) {\r
35177 var me = this,\r
35178 fields = record.fields,\r
35179 data = record.data,\r
35180 before, field, item, i, len, msg, val, name;\r
35181 for (i = 0 , len = fields.length; i < len; ++i) {\r
35182 field = fields[i];\r
35183 name = field.name;\r
35184 val = data[name];\r
35185 if (field.validate && !field.validate.$nullFn) {\r
35186 before = me.length;\r
35187 msg = field.validate(val, null, me, record);\r
35188 if (before === me.length && msg !== true) {\r
35189 me.add(name, msg);\r
35190 }\r
35191 }\r
35192 }\r
35193 return me;\r
35194 },\r
35195 add: function(key, value) {\r
35196 var me = this,\r
35197 defaultMessage = Ext.data.field.Field.defaultInvalidMessage,\r
35198 obj = key,\r
35199
35200 current;\r
35201 if (Ext.isString(key)) {\r
35202 obj = new Ext.data.Error({\r
35203 field: key,\r
35204 message: value || defaultMessage\r
35205 });\r
35206 } else {\r
35207 if (!(obj.isError)) {\r
35208 obj = new Ext.data.Error({\r
35209 field: obj.field || obj.name,\r
35210 message: obj.error || obj.message || obj.msg || defaultMessage\r
35211 });\r
35212 }\r
35213 key = obj.field;\r
35214 }\r
35215 current = me.get(key);\r
35216 if (current) {\r
35217 if (Ext.isArray(current)) {\r
35218 current.push(obj);\r
35219 return current;\r
35220 }\r
35221 me.removeAtKey(key);\r
35222 obj = [\r
35223 current,\r
35224 obj\r
35225 ];\r
35226 obj.field = key;\r
35227
35228
35229 obj = [\r
35230 obj\r
35231 ];\r
35232 }\r
35233 return me.callParent([\r
35234 obj\r
35235 ]);\r
35236 },\r
35237 getKey: function(item) {\r
35238 return item.field;\r
35239 },\r
35240 \r
35241 isValid: function() {\r
35242 return this.length === 0;\r
35243 },\r
35244 \r
35245 getByField: function(fieldName) {\r
35246 var values = this.get(fieldName);\r
35247 if (values && !Ext.isArray(values)) {\r
35248 values = [\r
35249 values\r
35250 ];\r
35251 }\r
35252 return values || [];\r
35253 }\r
35254});\r
35255\r
35256\r
35257Ext.define('Ext.data.operation.Operation', {\r
35258 alternateClassName: 'Ext.data.Operation',\r
35259 isOperation: true,\r
35260 config: {\r
35261 \r
35262 synchronous: false,\r
35263 \r
35264 url: '',\r
35265 \r
35266 params: undefined,\r
35267 \r
35268 callback: undefined,\r
35269 \r
35270 scope: undefined,\r
35271 \r
35272 resultSet: null,\r
35273 \r
35274 response: null,\r
35275 \r
35276 request: null,\r
35277 \r
35278 records: null,\r
35279 \r
35280 id: undefined,\r
35281 \r
35282 proxy: null,\r
35283 \r
35284 batch: null,\r
35285 \r
35286 recordCreator: null,\r
35287
35288
35289
35290 \r
35291 internalCallback: null,\r
35292 \r
35293 internalScope: null\r
35294 },\r
35295 \r
35296 order: 0,\r
35297 \r
35298 foreignKeyDirection: 1,\r
35299 \r
35300 started: false,\r
35301 \r
35302 running: false,\r
35303 \r
35304 complete: false,\r
35305 \r
35306 success: undefined,\r
35307 \r
35308 exception: false,\r
35309 \r
35310 error: undefined,\r
35311 idPrefix: 'ext-operation-',\r
35312 \r
35313 constructor: function(config) {\r
35314
35315
35316
35317
35318
35319
35320 var scope = config && config.scope;\r
35321 this.initConfig(config);\r
35322 if (config) {\r
35323 config.scope = scope;\r
35324 }\r
35325 if (scope) {\r
35326 this.setScope(scope);\r
35327 this.initialConfig.scope = scope;\r
35328 }\r
35329
35330 this._internalId = Ext.id(this, this.idPrefix);\r
35331 },\r
35332 getAction: function() {\r
35333 return this.action;\r
35334 },\r
35335 \r
35336 execute: function() {\r
35337 var me = this,\r
35338 request;\r
35339 delete me.error;\r
35340 delete me.success;\r
35341 me.complete = me.exception = false;\r
35342 me.setStarted();\r
35343 me.request = request = me.doExecute();\r
35344 if (request) {\r
35345 request.setOperation(me);\r
35346 }\r
35347 return request;\r
35348 },\r
35349 doExecute: Ext.emptyFn,\r
35350 \r
35351 abort: function() {\r
35352 var me = this,\r
35353 request = me.request;\r
35354 if (me.running && request) {\r
35355 me.getProxy().abort(request);\r
35356 me.request = null;\r
35357 }\r
35358 },\r
35359 process: function(resultSet, request, response, autoComplete) {\r
35360 var me = this;\r
35361 autoComplete = autoComplete !== false;\r
35362 me.setResponse(response);\r
35363 me.setResultSet(resultSet);\r
35364 if (resultSet.getSuccess()) {\r
35365 me.doProcess(resultSet, request, response);\r
35366 me.setSuccessful(autoComplete);\r
35367 } else if (autoComplete) {\r
35368 me.setException(resultSet.getMessage());\r
35369 }\r
35370 },\r
35371 \r
35372 _commitSetOptions: {\r
35373 convert: true,\r
35374 commit: true\r
35375 },\r
35376 \r
35377 doProcess: function(resultSet, request, response) {\r
35378 var me = this,\r
35379 commitSetOptions = me._commitSetOptions,\r
35380 clientRecords = me.getRecords(),\r
35381 clientLen = clientRecords.length,\r
35382 clientIdProperty = clientRecords[0].clientIdProperty,\r
35383 serverRecords = resultSet.getRecords(),\r
35384
35385 serverLen = serverRecords ? serverRecords.length : 0,\r
35386 clientMap, serverRecord, clientRecord, i;\r
35387 if (serverLen && clientIdProperty) {\r
35388
35389 clientMap = Ext.Array.toValueMap(clientRecords, 'id');\r
35390
35391
35392 for (i = 0; i < serverLen; ++i) {\r
35393 serverRecord = serverRecords[i];\r
35394 clientRecord = clientMap[serverRecord[clientIdProperty]];\r
35395 if (clientRecord) {\r
35396
35397 delete clientMap[clientRecord.id];\r
35398
35399 delete serverRecord[clientIdProperty];\r
35400 clientRecord.set(serverRecord, commitSetOptions);\r
35401 } else
35402
35403 {\r
35404 Ext.log.warn('Ignoring server record: ' + Ext.encode(serverRecord));\r
35405 }\r
35406 }\r
35407
35408
35409 for (i in clientMap) {\r
35410 clientMap[i].commit();\r
35411 }\r
35412 } else {\r
35413
35414
35415
35416 for (i = 0; i < clientLen; ++i) {\r
35417 clientRecord = clientRecords[i];\r
35418 if (serverLen === 0 || !(serverRecord = serverRecords[i])) {\r
35419
35420 clientRecord.commit();\r
35421 } else {\r
35422 clientRecord.set(serverRecord, commitSetOptions);\r
35423 }\r
35424 }\r
35425 }\r
35426 },\r
35427 \r
35428 setStarted: function() {\r
35429 this.started = this.running = true;\r
35430 },\r
35431 \r
35432 setCompleted: function() {\r
35433 var me = this,\r
35434 proxy = me.getProxy();\r
35435 me.complete = true;\r
35436 me.running = false;\r
35437 me.triggerCallbacks();\r
35438 if (proxy) {\r
35439 proxy.completeOperation(me);\r
35440 }\r
35441 },\r
35442 \r
35443 setSuccessful: function(complete) {\r
35444 this.success = true;\r
35445 if (complete) {\r
35446 this.setCompleted();\r
35447 }\r
35448 },\r
35449 \r
35450 setException: function(error) {\r
35451 var me = this;\r
35452 me.exception = true;\r
35453 me.success = me.running = false;\r
35454 me.error = error;\r
35455 me.setCompleted();\r
35456 },\r
35457 triggerCallbacks: function() {\r
35458 var me = this,\r
35459 callback = me.getInternalCallback();\r
35460
35461 if (callback) {\r
35462 callback.call(me.getInternalScope() || me, me);\r
35463 me.setInternalCallback(null);\r
35464 me.setInternalScope(null);\r
35465 }\r
35466
35467 if (callback = me.getCallback()) {\r
35468
35469 callback.call(me.getScope() || me, me.getRecords(), me, me.wasSuccessful());\r
35470 me.setCallback(null);\r
35471 me.setScope(null);\r
35472 }\r
35473 },\r
35474 \r
35475 hasException: function() {\r
35476 return this.exception;\r
35477 },\r
35478 \r
35479 getError: function() {\r
35480 return this.error;\r
35481 },\r
35482 \r
35483 getRecords: function() {\r
35484 var resultSet;\r
35485 return this._records || ((resultSet = this.getResultSet()) ? resultSet.getRecords() : null);\r
35486 },\r
35487 \r
35488 isStarted: function() {\r
35489 return this.started;\r
35490 },\r
35491 \r
35492 isRunning: function() {\r
35493 return this.running;\r
35494 },\r
35495 \r
35496 isComplete: function() {\r
35497 return this.complete;\r
35498 },\r
35499 \r
35500 wasSuccessful: function() {\r
35501 return this.isComplete() && this.success === true;\r
35502 },\r
35503
35504 \r
35505 allowWrite: function() {\r
35506 return true;\r
35507 }\r
35508});\r
35509\r
35510\r
35511Ext.define('Ext.data.operation.Create', {\r
35512 extend: Ext.data.operation.Operation,\r
35513 alias: 'data.operation.create',\r
35514 action: 'create',\r
35515 isCreateOperation: true,\r
35516 order: 10,\r
35517 config: {\r
35518 recordCreator: Ext.identityFn\r
35519 },\r
35520 doExecute: function() {\r
35521 return this.getProxy().create(this);\r
35522 }\r
35523});\r
35524\r
35525\r
35526Ext.define('Ext.data.operation.Destroy', {\r
35527 extend: Ext.data.operation.Operation,\r
35528 alias: 'data.operation.destroy',\r
35529 action: 'destroy',\r
35530 isDestroyOperation: true,\r
35531 order: 30,\r
35532 foreignKeyDirection: -1,\r
35533 doProcess: function() \r
35534 {\r
35535 var clientRecords = this.getRecords(),\r
35536 clientLen = clientRecords.length,\r
35537 i;\r
35538 for (i = 0; i < clientLen; ++i) {\r
35539 clientRecords[i].setErased();\r
35540 }\r
35541 },\r
35542 doExecute: function() {\r
35543 return this.getProxy().erase(this);\r
35544 },\r
35545 getRecordData: function(record, operation) {\r
35546 var data = {},\r
35547 idField = record.idField,\r
35548 nameProperty = this.getNameProperty() || 'name';\r
35549 data[idField[nameProperty]] = record.id;\r
35550 return data;\r
35551 }\r
35552});\r
35553\r
35554\r
35555Ext.define('Ext.data.operation.Read', {\r
35556 extend: Ext.data.operation.Operation,\r
35557 alias: 'data.operation.read',\r
35558 action: 'read',\r
35559 isReadOperation: true,\r
35560 config: {\r
35561 \r
35562 filters: undefined,\r
35563 \r
35564 sorters: undefined,\r
35565 \r
35566 grouper: undefined,\r
35567 \r
35568 start: undefined,\r
35569 \r
35570 limit: undefined,\r
35571 \r
35572 page: undefined,\r
35573 \r
35574 addRecords: false\r
35575 },\r
35576 doExecute: function() {\r
35577 return this.getProxy().read(this);\r
35578 },\r
35579 doProcess: Ext.emptyFn,\r
35580 allowWrite: function() {\r
35581 return false;\r
35582 }\r
35583});\r
35584\r
35585\r
35586Ext.define('Ext.data.operation.Update', {\r
35587 extend: Ext.data.operation.Operation,\r
35588 alias: 'data.operation.update',\r
35589 action: 'update',\r
35590 isUpdateOperation: true,\r
35591 order: 20,\r
35592 config: {\r
35593 recordCreator: Ext.identityFn\r
35594 },\r
35595 doExecute: function() {\r
35596 return this.getProxy().update(this);\r
35597 }\r
35598});\r
35599\r
35600\r
35601Ext.define('Ext.data.SortTypes', {\r
35602 singleton: true,\r
35603 \r
35604 none: Ext.identityFn,\r
35605 \r
35606 stripCommasRe: /,/g,\r
35607 \r
35608 stripTagsRE: /<\/?[^>]+>/gi,\r
35609 \r
35610 asText: function(s) {\r
35611
35612 return (s != null) ? String(s).replace(this.stripTagsRe, '') : '\x00';\r
35613 },\r
35614 \r
35615 asUCText: function(s) {\r
35616
35617 return (s != null) ? String(s).toUpperCase().replace(this.stripTagsRe, '') : '\x00';\r
35618 },\r
35619 \r
35620 asUCString: function(s) {\r
35621
35622 return (s != null) ? String(s).toUpperCase() : '\x00';\r
35623 },\r
35624 \r
35625 asDate: function(s) {\r
35626 if (!s) {\r
35627 return 0;\r
35628 }\r
35629 if (Ext.isDate(s)) {\r
35630 return s.getTime();\r
35631 }\r
35632 return Date.parse(String(s));\r
35633 },\r
35634 \r
35635 asFloat: function(s) {\r
35636 var val = parseFloat(String(s).replace(this.stripCommasRe, ''));\r
35637 return isNaN(val) ? 0 : val;\r
35638 },\r
35639 \r
35640 asInt: function(s) {\r
35641 var val = parseInt(String(s).replace(this.stripCommasRe, ''), 10);\r
35642 return isNaN(val) ? 0 : val;\r
35643 }\r
35644});\r
35645\r
35646\r
35647Ext.define('Ext.data.validator.Validator', {\r
35648 mixins: [\r
35649 Ext.mixin.Factoryable\r
35650 ],\r
35651 alias: 'data.validator.base',\r
35652
35653 isValidator: true,\r
35654 \r
35655 type: 'base',\r
35656 statics: {\r
35657 all: {},\r
35658 register: function(name, cls) {\r
35659 var all = this.all;\r
35660 all[name.toUpperCase()] = all[name.toLowerCase()] = all[name] = cls.prototype;\r
35661 }\r
35662 },\r
35663 onClassExtended: function(cls, data) {\r
35664 if (data.type) {\r
35665 Ext.data.validator.Validator.register(data.type, cls);\r
35666 }\r
35667 },\r
35668 \r
35669 constructor: function(config) {\r
35670 if (typeof config === 'function') {\r
35671 this.fnOnly = true;\r
35672 this.validate = config;\r
35673 } else {\r
35674 this.initConfig(config);\r
35675 }\r
35676 },\r
35677 \r
35678 validate: function() {\r
35679 return true;\r
35680 },\r
35681 \r
35682 clone: function() {\r
35683 var me = this;\r
35684 if (me.fnOnly) {\r
35685 return new Ext.data.validator.Validator(me.validate);\r
35686 }\r
35687 return new me.self(me.getCurrentConfig());\r
35688 }\r
35689}, function() {\r
35690 this.register(this.prototype.type, this);\r
35691});\r
35692\r
35693\r
35694Ext.define('Ext.data.field.Field', {\r
35695 mixins: [\r
35696 Ext.mixin.Factoryable\r
35697 ],\r
35698 alternateClassName: 'Ext.data.Field',\r
35699 alias: 'data.field.auto',\r
35700
35701 aliasPrefix: 'data.field.',\r
35702 type: 'auto',\r
35703 factoryConfig: {\r
35704 defaultProperty: 'name'\r
35705 },\r
35706 isDataField: true,\r
35707 isField: true,\r
35708
35709
35710
35711
35712
35713
35714 \r
35715 allowBlank: true,\r
35716 \r
35717 allowNull: false,\r
35718 \r
35719 \r
35720 \r
35721 critical: false,\r
35722 \r
35723 defaultInvalidMessage: 'This field is invalid',\r
35724 \r
35725 defaultValue: undefined,\r
35726 \r
35727 definedBy: null,\r
35728 \r
35729 depends: null,\r
35730 \r
35731 dependents: null,\r
35732 \r
35733 mapping: null,\r
35734 \r
35735 name: null,\r
35736 \r
35737 ordinal: undefined,\r
35738 \r
35739 persist: null,\r
35740 \r
35741 reference: null,\r
35742 \r
35743 \r
35744 \r
35745 unique: false,\r
35746 \r
35747 \r
35748 rank: null,\r
35749 \r
35750 stripRe: /[\$,%]/g,\r
35751 \r
35752 calculated: false,\r
35753 \r
35754 evil: false,\r
35755 \r
35756 identifier: false,\r
35757 onClassExtended: function(cls, data) {\r
35758 var sortType = data.sortType,\r
35759 proto = cls.prototype,\r
35760 superValidators = proto.validators,\r
35761 validators = data.validators;\r
35762 if (sortType && Ext.isString(sortType)) {\r
35763 proto.sortType = Ext.data.SortTypes[sortType];\r
35764 }\r
35765 if (validators) {\r
35766
35767 if (!Ext.isArray(validators)) {\r
35768 validators = [\r
35769 validators\r
35770 ];\r
35771 }\r
35772 delete data.validators;\r
35773
35774 if (superValidators) {\r
35775 validators = superValidators.concat(validators);\r
35776 }\r
35777 proto.validators = validators;\r
35778 }\r
35779 },\r
35780 argumentNamesRe: /^function\s*\(\s*([^,\)\s]+)/,\r
35781 calculateRe: /[^\.a-z0-9_]([a-z_][a-z_0-9]*)\.([a-z_][a-z_0-9]*)/gi,\r
35782 constructor: function(config) {\r
35783 var me = this,\r
35784 calculateRe = me.calculateRe,\r
35785 calculate, calculated, defaultValue, sortType, depends, map, match, dataProp, str, fld, validators;\r
35786
35787
35788 if (config) {\r
35789 if (Ext.isString(config)) {\r
35790 me.name = config;\r
35791 } else {\r
35792 validators = config.validators;\r
35793 if (validators) {\r
35794 delete config.validators;\r
35795 me.instanceValidators = validators;\r
35796 }\r
35797 Ext.apply(me, config);\r
35798 }\r
35799 }\r
35800 if (!me.allowNull) {\r
35801 me.allowNull = !!me.reference;\r
35802 }\r
35803 calculate = me.calculate;\r
35804 depends = me.depends;\r
35805 if (calculate) {\r
35806 me.convert = me.doCalculate;\r
35807 if (!depends) {\r
35808 if (!(depends = calculate.$depends)) {\r
35809 map = {};\r
35810 str = calculate.toString();\r
35811 calculate.$depends = depends = [];\r
35812 match = me.argumentNamesRe.exec(str);\r
35813 dataProp = match ? match[1] : 'data';\r
35814 while ((match = calculateRe.exec(str))) {\r
35815 if (dataProp === match[1] && !map[fld = match[2]]) {\r
35816 map[fld] = 1;\r
35817 depends.push(fld);\r
35818 }\r
35819 }\r
35820 }\r
35821 me.depends = depends;\r
35822 }\r
35823 }\r
35824 defaultValue = me.defaultValue;\r
35825 if (me.convert) {\r
35826 me.calculated = calculated = me.convert.length > 1;\r
35827 me.evil = calculated && !depends;\r
35828 }\r
35829 if (me.persist === null) {\r
35830 me.persist = !calculate;\r
35831 }\r
35832 sortType = me.sortType;\r
35833 if (!me.sortType) {\r
35834 me.sortType = Ext.data.SortTypes.none;\r
35835 } else if (Ext.isString(sortType)) {\r
35836 me.sortType = Ext.data.SortTypes[sortType];\r
35837 }\r
35838 if (depends && typeof depends === 'string') {\r
35839 me.depends = [\r
35840 depends\r
35841 ];\r
35842 }\r
35843 me.cloneDefaultValue = defaultValue !== undefined && (Ext.isDate(defaultValue) || Ext.isArray(defaultValue) || Ext.isObject(defaultValue));\r
35844 },\r
35845 setModelValidators: function(modelValidators) {\r
35846 this._validators = null;\r
35847 this.modelValidators = modelValidators;\r
35848 },\r
35849 compileValidators: function() {\r
35850 var me = this;\r
35851 me._validators = [];\r
35852 me.constructValidators(me.validators);\r
35853 me.constructValidators(me.modelValidators);\r
35854 me.constructValidators(me.instanceValidators);\r
35855 },\r
35856 constructValidators: function(validators) {\r
35857 if (validators) {\r
35858 if (!(validators instanceof Array)) {\r
35859 validators = [\r
35860 validators\r
35861 ];\r
35862 }\r
35863 var length = validators.length,\r
35864 all = this._validators,\r
35865 i, item;\r
35866 for (i = 0; i < length; ++i) {\r
35867 item = validators[i];\r
35868 if (item.fn) {\r
35869 item = item.fn;\r
35870 }\r
35871 all.push(Ext.Factory.dataValidator(item));\r
35872 }\r
35873 }\r
35874 },\r
35875 \r
35876 collate: function(value1, value2) {\r
35877 var me = this,\r
35878 lhs = value1,\r
35879 rhs = value2;\r
35880 if (me.sortType) {\r
35881 lhs = me.sortType(lhs);\r
35882 rhs = me.sortType(rhs);\r
35883 }\r
35884 return (lhs === rhs) ? 0 : ((lhs < rhs) ? -1 : 1);\r
35885 },\r
35886 \r
35887 compare: function(value1, value2) {\r
35888 return (value1 === value2) ? 0 : ((value1 < value2) ? -1 : 1);\r
35889 },\r
35890 \r
35891 isEqual: function(value1, value2) {\r
35892 return this.compare(value1, value2) === 0;\r
35893 },\r
35894 \r
35895 convert: null,\r
35896 \r
35897 serialize: null,\r
35898 \r
35899 validate: function(value, separator, errors, record) {\r
35900 var me = this,\r
35901 ret = '',\r
35902 result, validator, validators, length, i;\r
35903 if (!me._validators) {\r
35904 me.compileValidators();\r
35905 }\r
35906 validators = me._validators;\r
35907 for (i = 0 , length = validators.length; i < length; ++i) {\r
35908 validator = validators[i];\r
35909 result = validator.validate(value, record);\r
35910 if (result !== true) {\r
35911 result = result || me.defaultInvalidMessage;\r
35912 if (errors) {\r
35913 errors.add(me.name, result);\r
35914 ret = ret || result;\r
35915 } else if (separator) {\r
35916 if (ret) {\r
35917 ret += separator;\r
35918 }\r
35919 ret += result;\r
35920 } else {\r
35921 ret = result;\r
35922 break;\r
35923 }\r
35924 }\r
35925 }\r
35926 return ret || true;\r
35927 },\r
35928 doCalculate: function(v, rec) {\r
35929 return rec ? this.calculate(rec.data) : v;\r
35930 },\r
35931 \r
35932 getName: function() {\r
35933 return this.name;\r
35934 },\r
35935 \r
35936 getAllowBlank: function() {\r
35937 return this.allowBlank;\r
35938 },\r
35939 \r
35940 getAllowNull: function() {\r
35941 return this.allowNull;\r
35942 },\r
35943 \r
35944 getConvert: function() {\r
35945 return this.convert;\r
35946 },\r
35947 \r
35948 getDefaultValue: function() {\r
35949 return this.defaultValue;\r
35950 },\r
35951 \r
35952 getDepends: function() {\r
35953 return this.depends;\r
35954 },\r
35955 \r
35956 getMapping: function() {\r
35957 return this.mapping;\r
35958 },\r
35959 \r
35960 hasMapping: function() {\r
35961 var map = this.mapping;\r
35962 return !!(map || map === 0);\r
35963 },\r
35964 \r
35965 getPersist: function() {\r
35966 return this.persist;\r
35967 },\r
35968 \r
35969 getSortType: function() {\r
35970 return this.sortType;\r
35971 },\r
35972 \r
35973 getType: function() {\r
35974 return 'auto';\r
35975 },\r
35976 deprecated: {\r
35977 5.1: {\r
35978 methods: {\r
35979 \r
35980 getSortDir: function() {\r
35981 return this.sortDir;\r
35982 }\r
35983 }\r
35984 }\r
35985 }\r
35986});\r
35987\r
35988\r
35989Ext.define('Ext.data.field.Boolean', {\r
35990 extend: Ext.data.field.Field,\r
35991 alias: [\r
35992 'data.field.bool',\r
35993 'data.field.boolean'\r
35994 ],\r
35995 isBooleanField: true,\r
35996 \r
35997 trueRe: /^\s*(?:true|yes|on|1)\s*$/i,\r
35998 convert: function(v) {\r
35999 if (typeof v === 'boolean') {\r
36000 return v;\r
36001 }\r
36002 if (this.allowNull && (v === undefined || v === null || v === '')) {\r
36003 return null;\r
36004 }\r
36005 return this.trueRe.test(String(v));\r
36006 },\r
36007 getType: function() {\r
36008 return 'bool';\r
36009 }\r
36010});\r
36011\r
36012\r
36013Ext.define('Ext.data.field.Date', {\r
36014 extend: Ext.data.field.Field,\r
36015 alias: 'data.field.date',\r
36016 sortType: 'asDate',\r
36017 isDateField: true,\r
36018 \r
36019 dateFormat: null,\r
36020 \r
36021 dateReadFormat: null,\r
36022 \r
36023 dateWriteFormat: null,\r
36024 compare: function(lhs, rhs) {\r
36025 var lhsIsDate = lhs instanceof Date,\r
36026 rhsIsDate = rhs instanceof Date,\r
36027 result;\r
36028 if (rhsIsDate && lhsIsDate) {\r
36029 result = lhs.getTime() - rhs.getTime();\r
36030 if (result === 0) {\r
36031 result = 0;\r
36032 } else {\r
36033 result = result < 0 ? -1 : 1;\r
36034 }\r
36035 } else if (lhsIsDate === rhsIsDate) {\r
36036 result = 0;\r
36037 } else {\r
36038 result = lhsIsDate ? 1 : -1;\r
36039 }\r
36040 return result;\r
36041 },\r
36042 convert: function(v) {\r
36043 if (!v) {\r
36044 return null;\r
36045 }\r
36046
36047
36048 if (v instanceof Date) {\r
36049 return v;\r
36050 }\r
36051 var dateFormat = this.dateReadFormat || this.dateFormat,\r
36052 parsed;\r
36053 if (dateFormat) {\r
36054 return Ext.Date.parse(v, dateFormat);\r
36055 }\r
36056 parsed = Date.parse(v);\r
36057 return parsed ? new Date(parsed) : null;\r
36058 },\r
36059 serialize: function(value) {\r
36060 var result = null,\r
36061 format;\r
36062 if (Ext.isDate(value)) {\r
36063 format = this.getDateWriteFormat();\r
36064 result = format ? Ext.Date.format(value, format) : value;\r
36065 }\r
36066 return result;\r
36067 },\r
36068 \r
36069 getDateFormat: function() {\r
36070 return this.dateFormat;\r
36071 },\r
36072 \r
36073 getDateReadFormat: function() {\r
36074 return this.dateReadFormat;\r
36075 },\r
36076 \r
36077 getDateWriteFormat: function() {\r
36078 var me = this;\r
36079 if (me.hasOwnProperty('dateWriteFormat')) {\r
36080 return me.dateWriteFormat;\r
36081 }\r
36082 if (me.hasOwnProperty('dateFormat')) {\r
36083 return me.dateFormat;\r
36084 }\r
36085 return me.dateWriteFormat || me.dateFormat || 'timestamp';\r
36086 },\r
36087 getType: function() {\r
36088 return 'date';\r
36089 }\r
36090});\r
36091\r
36092\r
36093Ext.define('Ext.data.field.Integer', {\r
36094 extend: Ext.data.field.Field,\r
36095 alias: [\r
36096 'data.field.int',\r
36097 'data.field.integer'\r
36098 ],\r
36099 isNumeric: true,\r
36100 isIntegerField: true,\r
36101 numericType: 'int',\r
36102 convert: function(v) {\r
36103
36104
36105
36106 if (typeof v === 'number') {\r
36107 return this.getNumber(v);\r
36108 }\r
36109 var empty = v === undefined || v === null || v === '',\r
36110 allowNull = this.allowNull,\r
36111 out;\r
36112 if (empty) {\r
36113 out = allowNull ? null : 0;\r
36114 } else {\r
36115 out = this.parse(v);\r
36116 if (allowNull && isNaN(out)) {\r
36117 out = null;\r
36118 }\r
36119 }\r
36120 return out;\r
36121 },\r
36122 getNumber: function(v) {\r
36123 return parseInt(v, 10);\r
36124 },\r
36125 getType: function() {\r
36126 return this.numericType;\r
36127 },\r
36128 parse: function(v) {\r
36129 return parseInt(String(v).replace(this.stripRe, ''), 10);\r
36130 },\r
36131 sortType: function(s) {\r
36132
36133 if (s == null) {\r
36134 s = Infinity;\r
36135 }\r
36136 return s;\r
36137 }\r
36138});\r
36139\r
36140\r
36141Ext.define('Ext.data.field.Number', {\r
36142 extend: Ext.data.field.Integer,\r
36143 alias: [\r
36144 'data.field.float',\r
36145 'data.field.number'\r
36146 ],\r
36147 isIntegerField: false,\r
36148 isNumberField: true,\r
36149 numericType: 'float',\r
36150 getNumber: Ext.identityFn,\r
36151 parse: function(v) {\r
36152 return parseFloat(String(v).replace(this.stripRe, ''));\r
36153 }\r
36154});\r
36155\r
36156\r
36157Ext.define('Ext.data.field.String', {\r
36158 extend: Ext.data.field.Field,\r
36159 alias: 'data.field.string',\r
36160 sortType: 'asUCString',\r
36161 isStringField: true,\r
36162 convert: function(v) {\r
36163 var defaultValue = this.allowNull ? null : '';\r
36164 return (v === undefined || v === null) ? defaultValue : String(v);\r
36165 },\r
36166 getType: function() {\r
36167 return 'string';\r
36168 }\r
36169});\r
36170\r
36171\r
36172Ext.define('Ext.data.identifier.Generator', {\r
36173 'abstract': true,\r
36174 mixins: [\r
36175 Ext.mixin.Factoryable\r
36176 ],\r
36177 alias: 'data.identifier.default',\r
36178
36179 factoryConfig: {\r
36180 defaultType: 'sequential'\r
36181 },\r
36182
36183 \r
36184 isGenerator: true,\r
36185 config: {\r
36186 \r
36187 id: null\r
36188 },\r
36189 \r
36190 constructor: function(config) {\r
36191 var me = this,\r
36192 cache, id;\r
36193 me.initConfig(config);\r
36194 id = me.getId();\r
36195 if (id) {\r
36196 cache = (config && config.cache) || Ext.data.identifier.Generator.all;\r
36197 cache[id] = me;\r
36198 }\r
36199 },\r
36200 \r
36201 privates: {\r
36202 \r
36203 clone: function(config) {\r
36204 var cfg = this.getInitialConfig();\r
36205 cfg = config ? Ext.apply({}, config, cfg) : cfg;\r
36206 return new this.self(cfg);\r
36207 },\r
36208 statics: {\r
36209 \r
36210 all: {}\r
36211 }\r
36212 }\r
36213}, function() {\r
36214 var Generator = this,\r
36215 Factory = Ext.Factory,\r
36216 factory = Factory.dataIdentifier;\r
36217
36218
36219 \r
36220 Factory.dataIdentifier = function(config) {\r
36221 var id = Ext.isString(config) ? config : (config && config.id),\r
36222 existing = id && ((config && config.cache) || Generator.all)[id];\r
36223 return existing || factory(config);\r
36224 };\r
36225});\r
36226\r
36227\r
36228Ext.define('Ext.data.identifier.Sequential', {\r
36229 extend: Ext.data.identifier.Generator,\r
36230 alias: 'data.identifier.sequential',\r
36231 config: {\r
36232 \r
36233 increment: 1,\r
36234 \r
36235 prefix: null,\r
36236 \r
36237 seed: 1\r
36238 },\r
36239 \r
36240 generate: function() {\r
36241 var me = this,\r
36242 seed = me._seed,\r
36243 prefix = me._prefix;\r
36244 me._seed += me._increment;\r
36245 return (prefix !== null) ? prefix + seed : seed;\r
36246 }\r
36247});\r
36248\r
36249\r
36250Ext.define('Ext.data.Model', {\r
36251 alternateClassName: 'Ext.data.Record',\r
36252 \r
36253 isEntity: true,\r
36254 \r
36255 isModel: true,\r
36256
36257 validIdRe: null,\r
36258 erasing: false,\r
36259 observableType: 'record',\r
36260 constructor: function(data, session) {\r
36261 var me = this,\r
36262 cls = me.self,\r
36263 identifier = cls.identifier,\r
36264 Model = Ext.data.Model,\r
36265 modelIdentifier = Model.identifier,\r
36266 idProperty = me.idField.name,\r
36267 array, id, initializeFn, internalId, len, i, fields;\r
36268
36269
36270
36271
36272
36273 me.data = me.data = data || (data = {});\r
36274 me.session = session || null;\r
36275 me.internalId = internalId = modelIdentifier.generate();\r
36276
36277 var dataId = data[idProperty];\r
36278 if (session && !session.isSession) {\r
36279 Ext.raise('Bad Model constructor argument 2 - "session" is not a Session');\r
36280 }\r
36281
36282 if ((array = data) instanceof Array) {\r
36283 me.data = data = {};\r
36284 fields = me.getFields();\r
36285 len = Math.min(fields.length, array.length);\r
36286 for (i = 0; i < len; ++i) {\r
36287 data[fields[i].name] = array[i];\r
36288 }\r
36289 }\r
36290 if (!(initializeFn = cls.initializeFn)) {\r
36291 cls.initializeFn = initializeFn = Model.makeInitializeFn(cls);\r
36292 }\r
36293 if (!initializeFn.$nullFn) {\r
36294 cls.initializeFn(me);\r
36295 }\r
36296
36297 if (!(me.id = id = data[idProperty]) && id !== 0) {\r
36298
36299 if (dataId) {\r
36300 Ext.raise('The model ID configured in data ("' + dataId + '") has been rejected by the ' + me.fieldsMap[idProperty].type + ' field converter for the ' + idProperty + ' field');\r
36301 }\r
36302
36303 if (session) {\r
36304 identifier = session.getIdentifier(cls);\r
36305 id = identifier.generate();\r
36306 } else if (modelIdentifier === identifier) {\r
36307 id = internalId;\r
36308 } else {\r
36309 id = identifier.generate();\r
36310 }\r
36311 data[idProperty] = me.id = id;\r
36312 me.phantom = true;\r
36313 }\r
36314 if (session) {\r
36315 session.add(me);\r
36316 }\r
36317 if (me.init && Ext.isFunction(me.init)) {\r
36318 me.init();\r
36319 }\r
36320 },\r
36321 \r
36322 \r
36323 editing: false,\r
36324 \r
36325 dirty: false,\r
36326 \r
36327 session: null,\r
36328 \r
36329 dropped: false,\r
36330 \r
36331 erased: false,\r
36332 \r
36333 clientIdProperty: null,\r
36334 evented: false,\r
36335 \r
36336 phantom: false,\r
36337 \r
36338 idProperty: 'id',\r
36339 \r
36340 manyToMany: null,\r
36341 \r
36342 identifier: null,\r
36343
36344
36345 \r
36346 \r
36347 \r
36348 \r
36349 \r
36350 previousValues: undefined,\r
36351
36352
36353 \r
36354 proxy: undefined,\r
36355 \r
36356 \r
36357 schema: 'default',\r
36358 \r
36359 versionProperty: null,\r
36360 \r
36361 generation: 1,\r
36362 \r
36363 \r
36364 validationSeparator: null,\r
36365 \r
36366 convertOnSet: true,\r
36367
36368 \r
36369 \r
36370 \r
36371 \r
36372 beginEdit: function() {\r
36373 var me = this,\r
36374 modified = me.modified,\r
36375 previousValues = me.previousValues;\r
36376 if (!me.editing) {\r
36377 me.editing = true;\r
36378 me.editMemento = {\r
36379 dirty: me.dirty,\r
36380 data: Ext.apply({}, me.data),\r
36381 generation: me.generation,\r
36382 modified: modified && Ext.apply({}, modified),\r
36383 previousValues: previousValues && Ext.apply({}, previousValues)\r
36384 };\r
36385 }\r
36386 },\r
36387 \r
36388 cancelEdit: function() {\r
36389 var me = this,\r
36390 editMemento = me.editMemento;\r
36391 if (editMemento) {\r
36392 me.editing = false;\r
36393
36394 Ext.apply(me, editMemento);\r
36395 me.editMemento = null;\r
36396 }\r
36397 },\r
36398 \r
36399 endEdit: function(silent, modifiedFieldNames) {\r
36400 var me = this,\r
36401 editMemento = me.editMemento;\r
36402 if (editMemento) {\r
36403 me.editing = false;\r
36404 me.editMemento = null;\r
36405
36406
36407 me.previousValues = editMemento.previousValues;\r
36408 if (!silent) {\r
36409 if (!modifiedFieldNames) {\r
36410 modifiedFieldNames = me.getModifiedFieldNames(editMemento.data);\r
36411 }\r
36412 if (me.dirty || (modifiedFieldNames && modifiedFieldNames.length)) {\r
36413 me.callJoined('afterEdit', [\r
36414 modifiedFieldNames\r
36415 ]);\r
36416 }\r
36417 }\r
36418 }\r
36419 },\r
36420 getField: function(name) {\r
36421 return this.self.getField(name);\r
36422 },\r
36423 \r
36424 getFields: function() {\r
36425 return this.self.getFields();\r
36426 },\r
36427 getFieldsMap: function() {\r
36428 return this.fieldsMap;\r
36429 },\r
36430 \r
36431 getIdProperty: function() {\r
36432 return this.idProperty;\r
36433 },\r
36434 \r
36435 getId: function() {\r
36436 return this.id;\r
36437 },\r
36438 \r
36439 getObservableId: function() {\r
36440 return this.internalId;\r
36441 },\r
36442 \r
36443 setId: function(id, options) {\r
36444 this.set(this.idProperty, id, options);\r
36445 },\r
36446 \r
36447 getPrevious: function(fieldName) {\r
36448 var previousValues = this.previousValues;\r
36449 return previousValues && previousValues[fieldName];\r
36450 },\r
36451 \r
36452 isModified: function(fieldName) {\r
36453 var modified = this.modified;\r
36454 return !!(modified && modified.hasOwnProperty(fieldName));\r
36455 },\r
36456 \r
36457 getModified: function(fieldName) {\r
36458 var out;\r
36459 if (this.isModified(fieldName)) {\r
36460 out = this.modified[fieldName];\r
36461 }\r
36462 return out;\r
36463 },\r
36464 \r
36465 get: function(fieldName) {\r
36466 return this.data[fieldName];\r
36467 },\r
36468
36469
36470
36471 _singleProp: {},\r
36472 _rejectOptions: {\r
36473 convert: false,\r
36474 silent: true\r
36475 },\r
36476 \r
36477 set: function(fieldName, newValue, options) {\r
36478 var me = this,\r
36479 cls = me.self,\r
36480 data = me.data,\r
36481 modified = me.modified,\r
36482 prevVals = me.previousValues,\r
36483 session = me.session,\r
36484 single = Ext.isString(fieldName),\r
36485 opt = (single ? options : newValue),\r
36486 convertOnSet = opt ? opt.convert !== false : me.convertOnSet,\r
36487 fieldsMap = me.fieldsMap,\r
36488 silent = opt && opt.silent,\r
36489 commit = opt && opt.commit,\r
36490 updateRefs = !(opt && opt.refs === false) && session,\r
36491
36492
36493 dirty = !(opt && opt.dirty === false && !commit),\r
36494 modifiedFieldNames = null,\r
36495 currentValue, field, idChanged, key, name, oldId, comparator, dep, dependents, i,\r
36496 dirtyRank = 0,\r
36497 numFields, newId, rankedFields, reference, value, values;\r
36498 if (single) {\r
36499 values = me._singleProp;\r
36500 values[fieldName] = newValue;\r
36501 } else {\r
36502 values = fieldName;\r
36503 }\r
36504 if (!(rankedFields = cls.rankedFields)) {\r
36505
36506
36507 rankedFields = cls.rankFields();\r
36508 }\r
36509 numFields = rankedFields.length;\r
36510 do {\r
36511 for (name in values) {\r
36512 value = values[name];\r
36513 currentValue = data[name];\r
36514 comparator = me;\r
36515 field = fieldsMap[name];\r
36516 if (field) {\r
36517 if (convertOnSet && field.convert) {\r
36518 value = field.convert(value, me);\r
36519 }\r
36520 comparator = field;\r
36521 reference = field.reference;\r
36522 } else {\r
36523 reference = null;\r
36524 }\r
36525 if (comparator.isEqual(currentValue, value)) {\r
36526 \r
36527 continue;\r
36528 }\r
36529 data[name] = value;\r
36530 (modifiedFieldNames || (modifiedFieldNames = [])).push(name);\r
36531 (prevVals || (me.previousValues = prevVals = {}))[name] = currentValue;\r
36532 if (reference && reference.cls) {\r
36533 if (updateRefs) {\r
36534 session.updateReference(me, field, value, currentValue);\r
36535 }\r
36536 reference.onValueChange(me, session, value, currentValue);\r
36537 }\r
36538 i = (dependents = field && field.dependents) && dependents.length;\r
36539 while (i-- > 0) {\r
36540 (dep = dependents[i]).dirty = true;\r
36541 dirtyRank = dirtyRank ? Math.min(dirtyRank, dep.rank) : dep.rank;\r
36542 }\r
36543 if (!field || field.persist) {\r
36544 if (modified && modified.hasOwnProperty(name)) {\r
36545 if (!dirty || comparator.isEqual(modified[name], value)) {\r
36546 delete modified[name];\r
36547 me.dirty = -1;\r
36548 }\r
36549 } else if (dirty) {\r
36550 if (!modified) {\r
36551 me.modified = modified = {};\r
36552 }\r
36553 me.dirty = true;\r
36554 modified[name] = currentValue;\r
36555 }\r
36556 }\r
36557 if (name === me.idField.name) {\r
36558 idChanged = true;\r
36559 oldId = currentValue;\r
36560 newId = value;\r
36561 }\r
36562 }\r
36563 if (!dirtyRank) {\r
36564 break;\r
36565 }\r
36566 field = rankedFields[dirtyRank - 1];\r
36567 field.dirty = false;\r
36568 if (single) {\r
36569 delete values[fieldName];\r
36570 } else {\r
36571 values = me._singleProp;\r
36572 single = true;\r
36573 }\r
36574 fieldName = field.name;\r
36575 values[fieldName] = data[fieldName];\r
36576 convertOnSet = true;\r
36577 for (; dirtyRank < numFields; ++dirtyRank) {\r
36578 if (rankedFields[dirtyRank].dirty) {\r
36579 break;\r
36580 }\r
36581 }\r
36582 if (dirtyRank < numFields) {\r
36583 ++dirtyRank;\r
36584 } else {\r
36585 dirtyRank = 0;\r
36586 }\r
36587 } while (
36588
36589
36590
36591
36592
36593
36594
36595
36596
36597
36598
36599
36600
36601
36602
36603
36604
36605
36606
36607
36608
36609
36610
36611
36612
36613
36614
36615
36616
36617
36618
36619
36620
36621
36622 1);\r
36623 if (me.dirty < 0) {\r
36624
36625
36626 me.dirty = false;\r
36627 for (key in modified) {\r
36628 if (modified.hasOwnProperty(key)) {\r
36629 me.dirty = true;\r
36630 break;\r
36631 }\r
36632 }\r
36633 }\r
36634 if (single) {\r
36635
36636
36637 delete values[fieldName];\r
36638 }\r
36639 ++me.generation;\r
36640 if (idChanged) {\r
36641 me.id = newId;\r
36642 me.callJoined('onIdChanged', [\r
36643 oldId,\r
36644 newId\r
36645 ]);\r
36646 }\r
36647 if (commit) {\r
36648 me.commit(silent, modifiedFieldNames);\r
36649 } else if (!silent && !me.editing && modifiedFieldNames) {\r
36650 me.callJoined('afterEdit', [\r
36651 modifiedFieldNames\r
36652 ]);\r
36653 }\r
36654 return modifiedFieldNames;\r
36655 },\r
36656 \r
36657 reject: function(silent) {\r
36658 var me = this,\r
36659 modified = me.modified;\r
36660
36661 if (me.erased) {\r
36662 Ext.raise('Cannot reject once a record has been erased.');\r
36663 }\r
36664
36665 if (modified) {\r
36666 me.set(modified, me._rejectOptions);\r
36667 }\r
36668 me.dropped = false;\r
36669 me.clearState();\r
36670 if (!silent) {\r
36671 me.callJoined('afterReject');\r
36672 }\r
36673 },\r
36674 \r
36675 commit: function(silent, modifiedFieldNames) {\r
36676 var me = this,\r
36677 versionProperty = me.versionProperty,\r
36678 data = me.data,\r
36679 erased;\r
36680 me.clearState();\r
36681 if (versionProperty && !me.phantom && !isNaN(data[versionProperty])) {\r
36682 ++data[versionProperty];\r
36683 }\r
36684 me.phantom = false;\r
36685 if (me.dropped) {\r
36686 me.erased = erased = true;\r
36687 }\r
36688 if (!silent) {\r
36689 if (erased) {\r
36690 me.callJoined('afterErase');\r
36691 } else {\r
36692 me.callJoined('afterCommit', [\r
36693 modifiedFieldNames\r
36694 ]);\r
36695 }\r
36696 }\r
36697 },\r
36698 clearState: function() {\r
36699 var me = this;\r
36700 me.dirty = me.editing = false;\r
36701 me.editMemento = me.modified = null;\r
36702 },\r
36703 \r
36704 drop: function(cascade) {\r
36705 var me = this,\r
36706 associations = me.associations,\r
36707 session = me.session,\r
36708 roleName;\r
36709 if (me.erased || me.dropped) {\r
36710 return;\r
36711 }\r
36712 me.dropped = true;\r
36713 if (associations && cascade !== false) {\r
36714 for (roleName in associations) {\r
36715 associations[roleName].onDrop(me, session);\r
36716 }\r
36717 }\r
36718 me.callJoined('afterDrop');\r
36719 if (me.phantom) {\r
36720 me.setErased();\r
36721 }\r
36722 },\r
36723 \r
36724 join: function(item) {\r
36725 var me = this,\r
36726 joined = me.joined;\r
36727
36728 if (!joined) {\r
36729 joined = me.joined = [\r
36730 item\r
36731 ];\r
36732 } else if (!joined.length) {\r
36733 joined[0] = item;\r
36734 } else {\r
36735
36736 Ext.Array.include(joined, item);\r
36737 }\r
36738 if (item.isStore && !me.store) {\r
36739 \r
36740 me.store = item;\r
36741 }\r
36742 },\r
36743 \r
36744 unjoin: function(item) {\r
36745 var me = this,\r
36746 joined = me.joined,\r
36747
36748
36749 len = joined && joined.length,\r
36750 store = me.store,\r
36751 i;\r
36752 if (len === 1 && joined[0] === item) {\r
36753 joined.length = 0;\r
36754 } else if (len) {\r
36755 Ext.Array.remove(joined, item);\r
36756 }\r
36757 if (store === item) {\r
36758 store = null;\r
36759 if (joined) {\r
36760 for (i = 0 , len = joined.length; i < len; ++i) {\r
36761 item = joined[i];\r
36762 if (item.isStore) {\r
36763 store = item;\r
36764 break;\r
36765 }\r
36766 }\r
36767 }\r
36768 me.store = store;\r
36769 }\r
36770 },\r
36771 \r
36772 clone: function(session) {\r
36773 var me = this,\r
36774 modified = me.modified,\r
36775 ret = me.copy(me.id, session);\r
36776 if (modified) {\r
36777
36778 ret.modified = Ext.apply({}, modified);\r
36779 }\r
36780 ret.dirty = me.dirty;\r
36781 ret.dropped = me.dropped;\r
36782 ret.phantom = me.phantom;\r
36783 return ret;\r
36784 },\r
36785 \r
36786 copy: function(newId, session) {\r
36787 var me = this,\r
36788 data = Ext.apply({}, me.data),\r
36789 idProperty = me.idProperty,\r
36790 T = me.self;\r
36791 if (newId || newId === 0) {\r
36792 data[idProperty] = newId;\r
36793 } else if (newId === null) {\r
36794 delete data[idProperty];\r
36795 }\r
36796 return new T(data, session);\r
36797 },\r
36798 \r
36799 getProxy: function() {\r
36800 return this.self.getProxy();\r
36801 },\r
36802 \r
36803 getValidation: function(refresh) {\r
36804 var me = this,\r
36805 ret = me.validation;\r
36806 if (!ret) {\r
36807 me.validation = ret = new Ext.data.Validation();\r
36808 ret.attach(me);\r
36809 }\r
36810 if (refresh === true || (refresh !== false && ret.syncGeneration !== me.generation)) {\r
36811 ret.refresh(refresh);\r
36812 }\r
36813 return ret;\r
36814 },\r
36815 \r
36816 validate: function() {\r
36817 return new Ext.data.ErrorCollection().init(this);\r
36818 },\r
36819 \r
36820 isValid: function() {\r
36821 return this.getValidation().isValid();\r
36822 },\r
36823 \r
36824 toUrl: function() {\r
36825 var pieces = this.$className.split('.'),\r
36826 name = pieces[pieces.length - 1].toLowerCase();\r
36827 return name + '/' + this.getId();\r
36828 },\r
36829 \r
36830 erase: function(options) {\r
36831 var me = this;\r
36832 me.erasing = true;\r
36833
36834
36835
36836 me.drop();\r
36837 me.erasing = false;\r
36838 return me.save(options);\r
36839 },\r
36840 setErased: function() {\r
36841 this.erased = true;\r
36842 this.callJoined('afterErase');\r
36843 },\r
36844 \r
36845 getChanges: function() {\r
36846 return this.getData(this._getChangesOptions);\r
36847 },\r
36848 \r
36849 getCriticalFields: function() {\r
36850 var cls = this.self,\r
36851 ret = cls.criticalFields;\r
36852 if (!ret) {\r
36853 cls.rankFields();\r
36854 ret = cls.criticalFields;\r
36855 }\r
36856 return ret;\r
36857 },\r
36858 \r
36859 \r
36860 getAssociatedData: function(result, options) {\r
36861 var me = this,\r
36862 associations = me.associations,\r
36863 deep, i, item, items, itemData, length, record, role, roleName, opts, clear, associated;\r
36864 result = result || {};\r
36865 me.$gathering = 1;\r
36866 if (options) {\r
36867 options = Ext.Object.chain(options);\r
36868 }\r
36869 for (roleName in associations) {\r
36870 role = associations[roleName];\r
36871 item = role.getAssociatedItem(me);\r
36872 if (!item || item.$gathering) {\r
36873 \r
36874 continue;\r
36875 }\r
36876 if (item.isStore) {\r
36877 item.$gathering = 1;\r
36878 items = item.getData().items;\r
36879
36880 length = items.length;\r
36881 itemData = [];\r
36882 for (i = 0; i < length; ++i) {\r
36883
36884
36885
36886
36887 record = items[i];\r
36888 deep = !record.$gathering;\r
36889 record.$gathering = 1;\r
36890 if (options) {\r
36891 associated = options.associated;\r
36892 if (associated === undefined) {\r
36893 options.associated = deep;\r
36894 clear = true;\r
36895 } else if (!deep) {\r
36896 options.associated = false;\r
36897 clear = true;\r
36898 }\r
36899 opts = options;\r
36900 } else {\r
36901 opts = deep ? me._getAssociatedOptions : me._getNotAssociatedOptions;\r
36902 }\r
36903 itemData.push(record.getData(opts));\r
36904 if (clear) {\r
36905 options.associated = associated;\r
36906 clear = false;\r
36907 }\r
36908 delete record.$gathering;\r
36909 }\r
36910 delete item.$gathering;\r
36911 } else {\r
36912 opts = options || me._getAssociatedOptions;\r
36913 if (options && options.associated === undefined) {\r
36914 opts.associated = true;\r
36915 }\r
36916 itemData = item.getData(opts);\r
36917 }\r
36918 result[roleName] = itemData;\r
36919 }\r
36920 delete me.$gathering;\r
36921 return result;\r
36922 },\r
36923 \r
36924 getData: function(options) {\r
36925 var me = this,\r
36926 ret = {},\r
36927 opts = (options === true) ? me._getAssociatedOptions : (options || ret),\r
36928
36929 data = me.data,\r
36930 associated = opts.associated,\r
36931 changes = opts.changes,\r
36932 critical = changes && opts.critical,\r
36933 content = changes ? me.modified : data,\r
36934 fieldsMap = me.fieldsMap,\r
36935 persist = opts.persist,\r
36936 serialize = opts.serialize,\r
36937 criticalFields, field, n, name, value;\r
36938
36939
36940
36941
36942 if (content) {\r
36943
36944 for (name in content) {\r
36945 value = data[name];\r
36946 field = fieldsMap[name];\r
36947 if (field) {\r
36948 if (persist && !field.persist) {\r
36949 \r
36950 continue;\r
36951 }\r
36952 if (serialize && field.serialize) {\r
36953 value = field.serialize(value, me);\r
36954 }\r
36955 }\r
36956 ret[name] = value;\r
36957 }\r
36958 }\r
36959 if (critical) {\r
36960 criticalFields = me.self.criticalFields || me.getCriticalFields();\r
36961 for (n = criticalFields.length; n-- > 0; ) {\r
36962 name = (field = criticalFields[n]).name;\r
36963 if (!(name in ret)) {\r
36964 value = data[name];\r
36965 if (serialize && field.serialize) {\r
36966 value = field.serialize(value, me);\r
36967 }\r
36968 ret[name] = value;\r
36969 }\r
36970 }\r
36971 }\r
36972 if (associated) {\r
36973 me.getAssociatedData(ret, opts);\r
36974 }\r
36975
36976 return ret;\r
36977 },\r
36978 \r
36979 getTransientFields: function() {\r
36980 var cls = this.self,\r
36981 ret = cls.transientFields;\r
36982 if (!ret) {\r
36983 cls.rankFields();\r
36984
36985 ret = cls.transientFields;\r
36986 }\r
36987 return ret;\r
36988 },\r
36989 \r
36990 isLoading: function() {\r
36991 return !!this.loadOperation;\r
36992 },\r
36993 \r
36994 abort: function() {\r
36995 var operation = this.loadOperation;\r
36996 if (operation) {\r
36997 operation.abort();\r
36998 }\r
36999 },\r
37000 \r
37001 load: function(options) {\r
37002 options = Ext.apply({}, options);\r
37003 var me = this,\r
37004 scope = options.scope || me,\r
37005 proxy = me.getProxy(),\r
37006 callback = options.callback,\r
37007 operation = me.loadOperation,\r
37008 id = me.getId(),\r
37009 extras;\r
37010 if (operation) {\r
37011
37012 extras = operation.extraCalls;\r
37013 if (!extras) {\r
37014 extras = operation.extraCalls = [];\r
37015 }\r
37016 extras.push(options);\r
37017 return operation;\r
37018 }\r
37019
37020 var doIdCheck = true;\r
37021 if (me.phantom) {\r
37022 doIdCheck = false;\r
37023 }\r
37024
37025 options.id = id;\r
37026
37027
37028 options.recordCreator = function(data, type, readOptions) {\r
37029
37030
37031
37032 var session = me.session;\r
37033 if (readOptions) {\r
37034 readOptions.recordCreator = session ? session.recordCreator : null;\r
37035 }\r
37036 me.set(data, me._commitOptions);\r
37037
37038
37039 if (doIdCheck && me.getId() !== id) {\r
37040 Ext.raise('Invalid record id returned for ' + id + '@' + me.entityName);\r
37041 }\r
37042
37043 return me;\r
37044 };\r
37045 options.internalCallback = function(operation) {\r
37046 var success = operation.wasSuccessful() && operation.getRecords().length > 0,\r
37047 op = me.loadOperation,\r
37048 extras = op.extraCalls,\r
37049 successFailArgs = [\r
37050 me,\r
37051 operation\r
37052 ],\r
37053 callbackArgs = [\r
37054 me,\r
37055 operation,\r
37056 success\r
37057 ],\r
37058 i, len;\r
37059 me.loadOperation = null;\r
37060 if (success) {\r
37061 Ext.callback(options.success, scope, successFailArgs);\r
37062 } else {\r
37063 Ext.callback(options.failure, scope, successFailArgs);\r
37064 }\r
37065 Ext.callback(callback, scope, callbackArgs);\r
37066
37067
37068
37069 if (extras) {\r
37070 for (i = 0 , len = extras.length; i < len; ++i) {\r
37071 options = extras[i];\r
37072 if (success) {\r
37073 Ext.callback(options.success, scope, successFailArgs);\r
37074 } else {\r
37075 Ext.callback(options.failure, scope, successFailArgs);\r
37076 }\r
37077 Ext.callback(options.callback, scope, callbackArgs);\r
37078 }\r
37079 }\r
37080 me.callJoined('afterLoad');\r
37081 };\r
37082 delete options.callback;\r
37083 me.loadOperation = operation = proxy.createOperation('read', options);\r
37084 operation.execute();\r
37085 return operation;\r
37086 },\r
37087 \r
37088 save: function(options) {\r
37089 options = Ext.apply({}, options);\r
37090 var me = this,\r
37091 phantom = me.phantom,\r
37092 dropped = me.dropped,\r
37093 action = dropped ? 'destroy' : (phantom ? 'create' : 'update'),\r
37094 scope = options.scope || me,\r
37095 callback = options.callback,\r
37096 proxy = me.getProxy(),\r
37097 operation;\r
37098 options.records = [\r
37099 me\r
37100 ];\r
37101 options.internalCallback = function(operation) {\r
37102 var args = [\r
37103 me,\r
37104 operation\r
37105 ],\r
37106 success = operation.wasSuccessful();\r
37107 if (success) {\r
37108 Ext.callback(options.success, scope, args);\r
37109 } else {\r
37110 Ext.callback(options.failure, scope, args);\r
37111 }\r
37112 args.push(success);\r
37113 Ext.callback(callback, scope, args);\r
37114 };\r
37115 delete options.callback;\r
37116 operation = proxy.createOperation(action, options);\r
37117
37118
37119 if (dropped && phantom) {\r
37120
37121 operation.setResultSet(Ext.data.reader.Reader.prototype.nullResultSet);\r
37122 me.setErased();\r
37123 operation.setSuccessful(true);\r
37124 } else {\r
37125 operation.execute();\r
37126 }\r
37127 return operation;\r
37128 },\r
37129
37130
37131 inheritableStatics: {\r
37132 \r
37133 addFields: function(newFields) {\r
37134 this.replaceFields(newFields);\r
37135 },\r
37136 \r
37137 replaceFields: function(newFields, removeFields) {\r
37138 var me = this,\r
37139 proto = me.prototype,\r
37140 Field = Ext.data.field.Field,\r
37141 fields = me.fields,\r
37142 fieldsMap = me.fieldsMap,\r
37143 ordinals = me.fieldOrdinals,\r
37144 field, i, idField, len, name, ordinal;\r
37145 if (removeFields === true) {\r
37146 fields.length = 0;\r
37147 me.fieldsMap = fieldsMap = {};\r
37148 me.fieldOrdinals = ordinals = {};\r
37149 } else if (removeFields) {\r
37150 for (i = removeFields.length; i-- > 0; ) {\r
37151 name = removeFields[i];\r
37152 if (name in ordinals) {\r
37153 delete ordinals[name];\r
37154 delete fieldsMap[name];\r
37155 }\r
37156 }\r
37157 for (i = 0 , len = fields.length; i < len; ++i) {\r
37158 name = (field = fields[i]).name;\r
37159 if (name in ordinals) {\r
37160 ordinals[name] = i;\r
37161 } else {\r
37162
37163 fields.splice(i, 1);\r
37164 --i;\r
37165 --len;\r
37166 }\r
37167 }\r
37168 }\r
37169
37170
37171 for (i = 0 , len = newFields ? newFields.length : 0; i < len; i++) {\r
37172 name = (field = newFields[i]).name;\r
37173 if (!(name in ordinals)) {\r
37174 ordinals[name] = ordinal = fields.length;\r
37175
37176 fields.push(field = Field.create(field));\r
37177 fieldsMap[name] = field;\r
37178 field.ordinal = ordinal;\r
37179 field.definedBy = field.owner = this;\r
37180 }\r
37181 }\r
37182
37183
37184 me.idField = proto.idField = idField = fieldsMap[proto.idProperty];\r
37185 idField.allowNull = idField.critical = idField.identifier = true;\r
37186 idField.defaultValue = null;\r
37187
37188
37189 me.initializeFn = me.rankedFields = me.transientFields = me.criticalFields = null;\r
37190 },\r
37191 \r
37192 removeFields: function(removeFields) {\r
37193 this.replaceFields(null, removeFields);\r
37194 },\r
37195 \r
37196 getIdFromData: function(data) {\r
37197 var T = this,\r
37198 idField = T.idField,\r
37199 id = idField.calculated ? (new T(data)).id : data[idField.name];\r
37200 return id;\r
37201 },\r
37202 \r
37203 createWithId: function(id, data, session) {\r
37204 var d = data,\r
37205 T = this;\r
37206 if (id || id === 0) {\r
37207 d = {};\r
37208 if (data) {\r
37209 Ext.apply(d, data);\r
37210 }\r
37211 d[T.idField.name] = id;\r
37212 }\r
37213 return new T(d, session);\r
37214 },\r
37215 \r
37216 getFields: function() {\r
37217 return this.fields;\r
37218 },\r
37219 \r
37220 getFieldsMap: function() {\r
37221 return this.fieldsMap;\r
37222 },\r
37223 \r
37224 getField: function(name) {\r
37225 return this.fieldsMap[name] || null;\r
37226 },\r
37227 \r
37228 getProxy: function() {\r
37229 var me = this,\r
37230 proxy = me.proxy,\r
37231 defaultProxy = me.defaultProxy,\r
37232 defaults;\r
37233 if (!proxy) {\r
37234
37235 proxy = me.proxyConfig;\r
37236 if (!proxy && defaultProxy) {\r
37237 proxy = defaultProxy;\r
37238 }\r
37239 if (!proxy || !proxy.isProxy) {\r
37240 if (typeof proxy === 'string') {\r
37241 proxy = {\r
37242 type: proxy\r
37243 };\r
37244 }\r
37245
37246
37247 defaults = me.schema.constructProxy(me);\r
37248 proxy = proxy ? Ext.merge(defaults, proxy) : defaults;\r
37249 }\r
37250 proxy = me.setProxy(proxy);\r
37251 }\r
37252 return proxy;\r
37253 },\r
37254 \r
37255 setProxy: function(proxy) {\r
37256 var me = this,\r
37257 model;\r
37258 if (proxy) {\r
37259 if (!proxy.isProxy) {\r
37260 proxy = Ext.Factory.proxy(proxy);\r
37261 } else {\r
37262 model = proxy.getModel();\r
37263 if (model && model !== me) {\r
37264 proxy = proxy.clone();\r
37265 }\r
37266 }\r
37267 proxy.setModel(me);\r
37268 }\r
37269 return (me.prototype.proxy = me.proxy = proxy);\r
37270 },\r
37271 \r
37272 load: function(id, options, session) {\r
37273 var data = {},\r
37274 rec;\r
37275 data[this.prototype.idProperty] = id;\r
37276 rec = new this(data, session);\r
37277 rec.load(options);\r
37278 return rec;\r
37279 }\r
37280 },\r
37281 deprecated: {\r
37282 5: {\r
37283 methods: {\r
37284 hasId: null,\r
37285 markDirty: null,\r
37286 setDirty: null,\r
37287 eachStore: function(callback, scope) {\r
37288 var me = this,\r
37289 stores = me.stores,\r
37290 len = stores.length,\r
37291 i;\r
37292 for (i = 0; i < len; ++i) {\r
37293 callback.call(scope, stores[i]);\r
37294 }\r
37295 },\r
37296 join: function(item) {\r
37297 var me = this,\r
37298 stores = me.stores,\r
37299 joined = me.joined;\r
37300 if (!joined) {\r
37301 joined = me.joined = [\r
37302 item\r
37303 ];\r
37304 } else {\r
37305 joined.push(item);\r
37306 }\r
37307 if (item.isStore) {\r
37308 me.store = me.store || item;\r
37309 if (!stores) {\r
37310 stores = me.stores = [];\r
37311 }\r
37312 stores.push(item);\r
37313 }\r
37314 },\r
37315 unjoin: function(item) {\r
37316 var me = this,\r
37317 stores = me.stores,\r
37318 joined = me.joined;\r
37319 if (joined.length === 1) {\r
37320 joined.length = 0;\r
37321 } else {\r
37322 Ext.Array.remove(joined, item);\r
37323 }\r
37324 if (item.isStore) {\r
37325 Ext.Array.remove(stores, item);\r
37326 me.store = stores[0] || null;\r
37327 }\r
37328 }\r
37329 },\r
37330 properties: {\r
37331 persistenceProperty: null\r
37332 },\r
37333 inheritableStatics: {\r
37334 methods: {\r
37335 setFields: null\r
37336 }\r
37337 }\r
37338 }\r
37339 },\r
37340
37341 privates: {\r
37342 _commitOptions: {\r
37343 commit: true\r
37344 },\r
37345 _getChangesOptions: {\r
37346 changes: true\r
37347 },\r
37348 _getAssociatedOptions: {\r
37349 associated: true\r
37350 },\r
37351 _getNotAssociatedOptions: {\r
37352 associated: false\r
37353 },\r
37354 \r
37355 copyFrom: function(sourceRecord) {\r
37356 var me = this,\r
37357 fields = me.fields,\r
37358 fieldCount = fields.length,\r
37359 modifiedFieldNames = [],\r
37360 field,\r
37361 i = 0,\r
37362 myData, sourceData,\r
37363 idProperty = me.idProperty,\r
37364 name, value;\r
37365 if (sourceRecord) {\r
37366 myData = me.data;\r
37367 sourceData = sourceRecord.data;\r
37368 for (; i < fieldCount; i++) {\r
37369 field = fields[i];\r
37370 name = field.name;\r
37371
37372
37373
37374
37375
37376
37377 if (name !== idProperty) {\r
37378 value = sourceData[name];\r
37379
37380
37381 if (value !== undefined && !me.isEqual(myData[name], value)) {\r
37382 myData[name] = value;\r
37383 modifiedFieldNames.push(name);\r
37384 }\r
37385 }\r
37386 }\r
37387
37388 if (me.phantom && !sourceRecord.phantom) {\r
37389
37390
37391 me.beginEdit();\r
37392 me.setId(sourceRecord.getId());\r
37393 me.endEdit(true);\r
37394 me.commit(true);\r
37395 }\r
37396 }\r
37397 return modifiedFieldNames;\r
37398 },\r
37399 \r
37400 callJoined: function(funcName, args) {\r
37401 var me = this,\r
37402 joined = me.joined,\r
37403 session = me.session,\r
37404 i, len, fn, item;\r
37405 if (!joined && !session) {\r
37406 return;\r
37407 }\r
37408 if (args) {\r
37409 args.unshift(me);\r
37410 } else {\r
37411 args = [\r
37412 me\r
37413 ];\r
37414 }\r
37415 if (joined) {\r
37416 for (i = 0 , len = joined.length; i < len; ++i) {\r
37417 item = joined[i];\r
37418 if (item && (fn = item[funcName])) {\r
37419 fn.apply(item, args);\r
37420 }\r
37421 }\r
37422 }\r
37423 fn = session && session[funcName];\r
37424 if (fn) {\r
37425 fn.apply(session, args);\r
37426 }\r
37427 },\r
37428 \r
37429 setSession: function(session) {\r
37430
37431 if (session) {\r
37432 if (this.session) {\r
37433 Ext.raise('This model already belongs to a session.');\r
37434 }\r
37435 if (!this.id) {\r
37436 Ext.raise('The model must have an id to participate in a session.');\r
37437 }\r
37438 }\r
37439
37440 this.session = session;\r
37441 if (session) {\r
37442 session.add(this);\r
37443 }\r
37444 },\r
37445 \r
37446 getModifiedFieldNames: function(old) {\r
37447 var me = this,\r
37448 data = me.data,\r
37449 modified = [],\r
37450 oldData = old || me.editMemento.data,\r
37451 key;\r
37452 for (key in data) {\r
37453 if (data.hasOwnProperty(key)) {\r
37454 if (!me.isEqual(data[key], oldData[key], key)) {\r
37455 modified.push(key);\r
37456 }\r
37457 }\r
37458 }\r
37459 return modified;\r
37460 },\r
37461 \r
37462 isEqual: function(lhs, rhs, field) {\r
37463 var f;\r
37464 if (field) {\r
37465 f = field.isField ? field : this.fieldsMap[field];\r
37466 if (f) {\r
37467 return f.isEqual(lhs, rhs);\r
37468 }\r
37469 }\r
37470
37471
37472 if (lhs instanceof Date && rhs instanceof Date) {\r
37473 return lhs.getTime() === rhs.getTime();\r
37474 }\r
37475 return lhs === rhs;\r
37476 },\r
37477 statics: {\r
37478 \r
37479 EDIT: 'edit',\r
37480 \r
37481 REJECT: 'reject',\r
37482 \r
37483 COMMIT: 'commit',\r
37484 \r
37485 defaultProxy: 'memory',\r
37486 rankFields: function() {\r
37487 var cls = this,\r
37488 prototype = cls.prototype,\r
37489 fields = cls.fields,\r
37490 length = fields.length,\r
37491 rankedFields = [],\r
37492 criticalFields = [],\r
37493 transientFields = [],\r
37494 evilFields, field, i;\r
37495 cls.rankedFields = prototype.rankedFields = rankedFields;\r
37496 cls.criticalFields = prototype.criticalFields = criticalFields;\r
37497 cls.transientFields = prototype.transientFields = transientFields;\r
37498
37499
37500
37501
37502
37503 for (i = 0; i < length; ++i) {\r
37504 field = fields[i];\r
37505 if (field.critical) {\r
37506 criticalFields.push(field);\r
37507 }\r
37508 if (!field.persist) {\r
37509 transientFields.push(field);\r
37510 }\r
37511 if (field.evil) {\r
37512 (evilFields || (evilFields = [])).push(field);\r
37513 } else if (!field.depends) {\r
37514 rankedFields.push(field);\r
37515 field.rank = rankedFields.length;\r
37516 }\r
37517 }\r
37518
37519 for (i = 0; i < length; ++i) {\r
37520 if (!(field = fields[i]).rank && !field.evil) {\r
37521 cls.topoAdd(field);\r
37522 }\r
37523 }\r
37524 if (evilFields) {\r
37525 for (i = 0 , length = evilFields.length; i < length; ++i) {\r
37526 rankedFields.push(field = evilFields[i]);\r
37527 field.rank = rankedFields.length;\r
37528 }\r
37529 }\r
37530
37531
37532 cls.topoStack = null;\r
37533
37534
37535 return rankedFields;\r
37536 },\r
37537 topoAdd: function(field) {\r
37538 var cls = this,\r
37539 dep = field.depends,\r
37540 dependsLength = dep ? dep.length : 0,\r
37541 rankedFields = cls.rankedFields,\r
37542 i, targetField;\r
37543
37544 var topoStack = cls.topoStack || (cls.topoStack = []);\r
37545 topoStack.push(field.name);\r
37546 if (field.rank === 0) {\r
37547
37548 Ext.raise(cls.$className + " has circular field dependencies: " + topoStack.join(" --> "));\r
37549 }\r
37550 if (topoStack.length && field.evil) {\r
37551 Ext.raise(cls.$className + ": Field " + topoStack[topoStack.length - 1] + " cannot depend on depends-less field " + field.name);\r
37552 }\r
37553 field.rank = 0;\r
37554
37555
37556 for (i = 0; i < dependsLength; ++i) {\r
37557
37558
37559 targetField = cls.fieldsMap[dep[i]];\r
37560
37561 if (!targetField) {\r
37562 Ext.raise(cls.$className + ": Field " + field.name + " depends on undefined field " + dep[i]);\r
37563 }\r
37564
37565 (targetField.dependents || (targetField.dependents = [])).push(field);\r
37566 if (!targetField.rank) {\r
37567
37568 cls.topoAdd(targetField);\r
37569 }\r
37570 }\r
37571 rankedFields.push(field);\r
37572 field.rank = rankedFields.length;\r
37573
37574
37575 topoStack.pop();\r
37576 },\r
37577
37578 initFields: function(data, cls, proto) {\r
37579 var Field = Ext.data.field.Field,\r
37580 fieldDefs = data.fields,\r
37581
37582 fields = [],\r
37583 fieldOrdinals = {},\r
37584 fieldsMap = {},\r
37585 references = [],\r
37586 superFields = proto.fields,\r
37587 versionProperty = data.versionProperty || proto.versionProperty,\r
37588 idProperty = cls.idProperty,\r
37589 idField, field, i, length, name, ordinal, reference, superIdField, superIdFieldName, idDeclared;\r
37590
37591
37592 cls.fields = proto.fields = fields;\r
37593 cls.fieldOrdinals = proto.fieldOrdinals = fieldOrdinals;\r
37594 cls.fieldsMap = proto.fieldsMap = fieldsMap;\r
37595 cls.references = proto.references = references;\r
37596 if (superFields) {\r
37597
37598 for (i = 0 , length = superFields.length; i < length; ++i) {\r
37599 fields[i] = field = Ext.Object.chain(superFields[i]);\r
37600 field.dependents = null;\r
37601
37602 field.owner = cls;\r
37603 fieldOrdinals[name = field.name] = i;\r
37604 fieldsMap[name] = field;\r
37605
37606
37607 field.rank = null;\r
37608 if (field.generated) {\r
37609 superIdField = field;\r
37610 superIdFieldName = field.name;\r
37611 }\r
37612 }\r
37613 }\r
37614
37615 if (fieldDefs) {\r
37616 delete data.fields;\r
37617 for (i = 0 , length = fieldDefs.length; i < length; ++i) {\r
37618 field = fieldDefs[i];\r
37619 reference = field.reference;\r
37620
37621
37622 if (reference && typeof reference !== 'string') {\r
37623
37624 reference = Ext.merge({}, reference);\r
37625 }\r
37626 field.$reference = reference;\r
37627 field = Field.create(fieldDefs[i]);\r
37628 name = field.name;\r
37629 ordinal = fieldOrdinals[name];\r
37630 if (ordinal === undefined) {\r
37631
37632 fieldOrdinals[name] = ordinal = fields.length;\r
37633 }\r
37634
37635 fieldsMap[name] = field;\r
37636 fields[ordinal] = field;\r
37637 field.definedBy = field.owner = cls;\r
37638 field.ordinal = ordinal;\r
37639 if (name === idProperty) {\r
37640 idDeclared = field;\r
37641 }\r
37642 }\r
37643 }\r
37644
37645
37646 idField = fieldsMap[idProperty];\r
37647 if (!idField) {\r
37648 if (superIdField && superIdField.generated) {\r
37649 ordinal = superIdField.ordinal;\r
37650 } else {\r
37651 ordinal = fields.length;\r
37652 }\r
37653 delete fieldsMap[superIdFieldName];\r
37654 delete fieldOrdinals[superIdFieldName];\r
37655 idField = new Field(idProperty);\r
37656 fields[ordinal] = idField;\r
37657 fieldOrdinals[idProperty] = ordinal;\r
37658 fieldsMap[idProperty] = idField;\r
37659 idField.definedBy = cls;\r
37660 idField.ordinal = ordinal;\r
37661 idField.generated = true;\r
37662 } else if (idDeclared && superIdField && superIdField.generated) {\r
37663
37664
37665
37666
37667 Ext.Array.remove(fields, superIdField);\r
37668 delete fieldsMap[superIdFieldName];\r
37669 delete fieldOrdinals[superIdFieldName];\r
37670 fieldsMap[idProperty] = idDeclared;\r
37671 for (i = 0 , length = fields.length; i < length; ++i) {\r
37672 field = fields[i];\r
37673 fields.ordinal = i;\r
37674 fieldOrdinals[field.name] = i;\r
37675 }\r
37676 }\r
37677 idField.allowNull = idField.critical = idField.identifier = true;\r
37678 idField.defaultValue = null;\r
37679 cls.idField = proto.idField = idField;\r
37680 if (versionProperty) {\r
37681 field = fieldsMap[versionProperty];\r
37682 if (!field) {\r
37683 ordinal = fields.length;\r
37684 field = new Field({\r
37685 name: versionProperty,\r
37686 type: 'int'\r
37687 });\r
37688 fields[ordinal] = field;\r
37689 fieldOrdinals[versionProperty] = ordinal;\r
37690 fieldsMap[versionProperty] = field;\r
37691 field.definedBy = cls;\r
37692 field.ordinal = ordinal;\r
37693 field.generated = true;\r
37694 }\r
37695 field.defaultValue = 1;\r
37696 field.critical = true;\r
37697 }\r
37698 },\r
37699
37700
37701 initValidators: function(data, cls, proto) {\r
37702 var superValidators = proto.validators,\r
37703 validators, field, copy, validatorDefs, i, length, fieldValidator, name, validator, item;\r
37704 if (superValidators) {\r
37705 validators = {};\r
37706 for (field in superValidators) {\r
37707 validators[field] = Ext.Array.clone(superValidators[field]);\r
37708 }\r
37709 }\r
37710 validatorDefs = data.validators || data.validations;\r
37711
37712 if (data.validations) {\r
37713 delete data.validations;\r
37714 Ext.log.warn((cls.$className || 'Ext.data.Model') + ': validations has been deprecated. Please use validators instead.');\r
37715 }\r
37716
37717 if (validatorDefs) {\r
37718 delete data.validators;\r
37719 validators = validators || {};\r
37720
37721 if (Ext.isArray(validatorDefs)) {\r
37722 copy = {};\r
37723 for (i = 0 , length = validatorDefs.length; i < length; ++i) {\r
37724 item = validatorDefs[i];\r
37725 name = item.field;\r
37726 if (!copy[name]) {\r
37727 copy[name] = [];\r
37728 }\r
37729
37730 item = item.fn || item;\r
37731 copy[name].push(item);\r
37732 }\r
37733 validatorDefs = copy;\r
37734 }\r
37735 for (name in validatorDefs) {\r
37736 fieldValidator = validatorDefs[name];\r
37737 if (!Ext.isArray(fieldValidator)) {\r
37738 fieldValidator = [\r
37739 fieldValidator\r
37740 ];\r
37741 }\r
37742 validator = validators[name];\r
37743 if (validators[name]) {\r
37744
37745 Ext.Array.push(validator, fieldValidator);\r
37746 } else {\r
37747 validators[name] = fieldValidator;\r
37748 }\r
37749 }\r
37750 }\r
37751 if (validators) {\r
37752 for (name in validators) {\r
37753 field = cls.getField(name);\r
37754 if (field) {\r
37755 field.setModelValidators(validators[name]);\r
37756 }\r
37757 }\r
37758 }\r
37759 cls.validators = proto.validators = validators;\r
37760 },\r
37761 initAssociations: function(schema, data, cls) {\r
37762
37763 var associations = data.associations,\r
37764 belongsTo = data.belongsTo,\r
37765 hasMany = data.hasMany,\r
37766 hasOne = data.hasOne,\r
37767
37768 matrices = data.manyToMany,\r
37769 i, length, assoc;\r
37770
37771 if (data.belongsTo) {\r
37772 Ext.log.warn('Use of "belongsTo" is obsolete' + (cls.$className ? ' in ' + cls.$className : ''));\r
37773 delete data.belongsTo;\r
37774 }\r
37775
37776 delete data.manyToMany;\r
37777 if (matrices) {\r
37778 schema.addMatrices(cls, matrices);\r
37779 }\r
37780
37781 delete data.associations;\r
37782 delete data.belongsTo;\r
37783 delete data.hasMany;\r
37784 delete data.hasOne;\r
37785 if (associations) {\r
37786 associations = Ext.isArray(associations) ? associations : [\r
37787 associations\r
37788 ];\r
37789 for (i = 0 , length = associations.length; i < length; ++i) {\r
37790 assoc = associations[i];\r
37791 switch (assoc.type) {\r
37792 case 'belongsTo':\r
37793 schema.addLegacyBelongsTo(cls, assoc);\r
37794 break;\r
37795 case 'hasMany':\r
37796 schema.addLegacyHasMany(cls, assoc);\r
37797 break;\r
37798 case 'hasOne':\r
37799 schema.addLegacyHasOne(cls, assoc);\r
37800 break;\r
37801
37802 default:\r
37803 Ext.raise('Invalid association type: "' + assoc.type + '"');\r
37804 }\r
37805 }\r
37806 }\r
37807
37808 if (belongsTo) {\r
37809 belongsTo = Ext.isArray(belongsTo) ? belongsTo : [\r
37810 belongsTo\r
37811 ];\r
37812 for (i = 0 , length = belongsTo.length; i < length; ++i) {\r
37813 schema.addLegacyBelongsTo(cls, belongsTo[i]);\r
37814 }\r
37815 }\r
37816 if (hasMany) {\r
37817 hasMany = Ext.isArray(hasMany) ? hasMany : [\r
37818 hasMany\r
37819 ];\r
37820 for (i = 0 , length = hasMany.length; i < length; ++i) {\r
37821 schema.addLegacyHasMany(cls, hasMany[i]);\r
37822 }\r
37823 }\r
37824 if (hasOne) {\r
37825 hasOne = Ext.isArray(hasOne) ? hasOne : [\r
37826 hasOne\r
37827 ];\r
37828 for (i = 0 , length = hasOne.length; i < length; ++i) {\r
37829 schema.addLegacyHasOne(cls, hasOne[i]);\r
37830 }\r
37831 }\r
37832 schema.afterLegacyAssociations(cls);\r
37833 },\r
37834 initIdentifier: function(data, cls, proto) {\r
37835 var identifier = data.identifier || data.idgen,\r
37836 superIdent = proto.identifier || cls.schema._defaultIdentifier,\r
37837 generatorPrefix;\r
37838
37839 if (data.idgen) {\r
37840 Ext.log.warn('Ext.data.Model: idgen has been deprecated. Please use identifier instead.');\r
37841 }\r
37842
37843 if (identifier) {\r
37844 delete data.identifier;\r
37845 delete data.idgen;\r
37846
37847 identifier = Ext.Factory.dataIdentifier(identifier);\r
37848 } else if (superIdent) {\r
37849
37850
37851
37852 if (superIdent.clone && !superIdent.getId()) {\r
37853 identifier = superIdent.clone();\r
37854 } else if (superIdent.isGenerator) {\r
37855 identifier = superIdent;\r
37856 } else {\r
37857 identifier = Ext.Factory.dataIdentifier(superIdent);\r
37858 }\r
37859 }\r
37860 cls.identifier = proto.identifier = identifier;\r
37861 if (!identifier) {\r
37862
37863
37864
37865
37866 generatorPrefix = cls.entityName;\r
37867 if (!generatorPrefix) {\r
37868 generatorPrefix = Ext.id(null, 'extModel');\r
37869 }\r
37870 cls.identifier = Ext.Factory.dataIdentifier({\r
37871 type: 'sequential',\r
37872 prefix: generatorPrefix + '-'\r
37873 });\r
37874 }\r
37875 },\r
37876 findValidator: function(validators, name, cfg) {\r
37877 var type = cfg.type || cfg,\r
37878 field = validators[name],\r
37879 len, i, item;\r
37880 if (field) {\r
37881 for (i = 0 , len = field.length; i < len; ++i) {\r
37882 item = field[i];\r
37883 if (item.type === type) {\r
37884 return item;\r
37885 }\r
37886 }\r
37887 }\r
37888 return null;\r
37889 },\r
37890 \r
37891 makeInitializeFn: function(cls) {\r
37892 var code = [\r
37893 'var '\r
37894 ],\r
37895 body = [\r
37896 '\nreturn function (e) {\n var data = e.data, v;\n'\r
37897 ],\r
37898 fieldVars = [],\r
37899 work = 0,\r
37900 bc, ec,
37901 convert, expr, factory, field, fields, fs, hasDefValue, i, length;\r
37902 if (!(fields = cls.rankedFields)) {\r
37903
37904
37905 fields = cls.rankFields();\r
37906 }\r
37907 for (i = 0 , length = fields.length; i < length; ++i) {\r
37908
37909
37910
37911 field = fields[i];\r
37912 fieldVars[i] = fs = 'f' + i;\r
37913 convert = field.convert;\r
37914 if (i) {\r
37915 code.push(', \n ');\r
37916 }\r
37917 code.push(fs, ' = $fields[' + i + ']');\r
37918
37919
37920 code.push(' /* ', field.name, ' */');\r
37921
37922
37923
37924
37925
37926 if ((hasDefValue = (field.defaultValue !== undefined)) || convert) {\r
37927
37928
37929
37930
37931 expr = 'data["' + field.name + '"]';\r
37932 ++work;\r
37933 bc = ec = '';\r
37934 if (field.cloneDefaultValue) {\r
37935 bc = 'Ext.clone(';\r
37936 ec = ')';\r
37937 }\r
37938 body.push('\n');\r
37939 if (convert && hasDefValue) {\r
37940
37941
37942
37943
37944
37945
37946
37947
37948
37949
37950
37951 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;');\r
37952 } else if (convert) {\r
37953
37954
37955
37956
37957
37958
37959 body.push(' v = ', fs, '.convert(', expr, ',e);\n' + ' if (v !== undefined) {\n' + ' ', expr, ' = v;\n' + ' }\n');\r
37960 } else if (hasDefValue) {\r
37961
37962
37963
37964
37965
37966
37967
37968 body.push(' if (', expr, ' === undefined) {\n' + ' ', expr, ' = ', bc, fs, '.defaultValue', ec, ';\n' + ' }\n');\r
37969 }\r
37970 }\r
37971 }\r
37972 if (!work) {\r
37973
37974 return Ext.emptyFn;\r
37975 }\r
37976 code.push(';\n');\r
37977 code.push.apply(code, body);\r
37978 code.push('}');\r
37979 code = code.join('');\r
37980
37981
37982 factory = new Function('$fields', 'Ext', code);\r
37983 return factory(fields, Ext);\r
37984 }\r
37985 }\r
37986 }\r
37987},
37988
37989function() {\r
37990 var Model = this,\r
37991 proto = Model.prototype,\r
37992 Schema = Ext.data.schema.Schema,\r
37993 defaultSchema;\r
37994 Model.proxyConfig = proto.proxy;\r
37995 delete proto.proxy;\r
37996
37997 Model.fields = [];\r
37998
37999 Model.fieldsMap = proto.fieldsMap = {};\r
38000 Model.schema = proto.schema = Schema.get(proto.schema);\r
38001 proto.idField = new Ext.data.field.Field(proto.idProperty);\r
38002 Model.identifier = new Ext.data.identifier.Sequential();\r
38003 Model.onExtended(function(cls, data) {\r
38004 var proto = cls.prototype,\r
38005 schemaName = data.schema,\r
38006 superCls = proto.superclass.self,\r
38007 schema, entityName, proxy;\r
38008 cls.idProperty = data.idProperty || proto.idProperty;\r
38009 if (schemaName) {\r
38010 delete data.schema;\r
38011 schema = Schema.get(schemaName);\r
38012 } else if (!(schema = proto.schema)) {\r
38013 schema = defaultSchema || (defaultSchema = Schema.get('default'));\r
38014 }\r
38015
38016 cls.rankFields = Model.rankFields;\r
38017 cls.topoAdd = Model.topoAdd;\r
38018
38019
38020 proto.schema = cls.schema = schema;\r
38021
38022
38023 if (!(entityName = data.entityName)) {\r
38024 proto.entityName = entityName = schema.getEntityName(cls);\r
38025
38026 if (!entityName) {\r
38027 if (data.associations) {\r
38028 Ext.raise('Anonymous entities cannot specify "associations"');\r
38029 }\r
38030 if (data.belongsTo) {\r
38031 Ext.raise('Anonymous entities cannot specify "belongsTo"');\r
38032 }\r
38033 if (data.hasMany) {\r
38034 Ext.raise('Anonymous entities cannot specify "hasMany"');\r
38035 }\r
38036 if (data.hasOne) {\r
38037 Ext.raise('Anonymous entities cannot specify "hasOne"');\r
38038 }\r
38039 if (data.matrices) {\r
38040 Ext.raise('Anonymous entities cannot specify "manyToMany"');\r
38041 }\r
38042 }\r
38043 }\r
38044
38045 cls.entityName = entityName;\r
38046 cls.fieldExtractors = {};\r
38047 Model.initIdentifier(data, cls, proto);\r
38048 Model.initFields(data, cls, proto);\r
38049 Model.initValidators(data, cls, proto);\r
38050
38051
38052 cls.fields.items = cls.fields;\r
38053 if (entityName) {\r
38054 schema.addEntity(cls);\r
38055 Model.initAssociations(schema, data, cls);\r
38056 }\r
38057 proxy = data.proxy;\r
38058 if (proxy) {\r
38059 delete data.proxy;\r
38060 } else if (superCls !== Model) {\r
38061 proxy = superCls.proxyConfig || superCls.proxy;\r
38062 }\r
38063 cls.proxyConfig = proxy;\r
38064 });\r
38065});\r
38066\r
38067\r
38068Ext.define('Ext.data.ResultSet', {\r
38069 \r
38070 isResultSet: true,\r
38071 $configPrefixed: false,\r
38072 config: {\r
38073 \r
38074 loaded: true,\r
38075 \r
38076 count: null,\r
38077 \r
38078 total: null,\r
38079 \r
38080 success: false,\r
38081 \r
38082 records: null,\r
38083 \r
38084 message: null\r
38085 },\r
38086 \r
38087 constructor: function(config) {\r
38088 this.initConfig(config);\r
38089 },\r
38090 getCount: function() {\r
38091 var count = this.callParent(),\r
38092 records;\r
38093 if (!count) {\r
38094 records = this.getRecords();\r
38095 if (records) {\r
38096 count = records.length;\r
38097 }\r
38098 }\r
38099 return count;\r
38100 }\r
38101});\r
38102\r
38103\r
38104Ext.define('Ext.data.reader.Reader', {\r
38105 alternateClassName: [\r
38106 'Ext.data.Reader',\r
38107 'Ext.data.DataReader'\r
38108 ],\r
38109 mixins: [\r
38110 Ext.mixin.Observable,\r
38111 Ext.mixin.Factoryable\r
38112 ],\r
38113 alias: 'reader.base',\r
38114 factoryConfig: {\r
38115 defaultType: null\r
38116 },\r
38117 config: {\r
38118 \r
38119 totalProperty: 'total',\r
38120 \r
38121 successProperty: 'success',\r
38122 \r
38123 rootProperty: '',\r
38124 \r
38125 messageProperty: '',\r
38126 \r
38127 typeProperty: '',\r
38128 \r
38129 implicitIncludes: true,\r
38130 \r
38131 readRecordsOnFailure: true,\r
38132 \r
38133 model: null,\r
38134 \r
38135 proxy: null,\r
38136 \r
38137 transform: null,\r
38138 \r
38139 keepRawData: null\r
38140 },\r
38141 \r
38142 \r
38143 \r
38144 isReader: true,\r
38145 \r
38146 \r
38147 constructor: function(config) {\r
38148 if (config && config.hasOwnProperty('root')) {\r
38149 config = Ext.apply({}, config);\r
38150 config.rootProperty = config.root;\r
38151 delete config.root;\r
38152
38153 Ext.log.error('Ext.data.reader.Reader: Using the deprecated "root" configuration. Use "rootProperty" instead.');\r
38154 }\r
38155
38156 var me = this;\r
38157 me.duringInit = 1;\r
38158
38159 me.mixins.observable.constructor.call(me, config);\r
38160 --me.duringInit;\r
38161 me.buildExtractors();\r
38162 },\r
38163 applyModel: function(model) {\r
38164 return Ext.data.schema.Schema.lookupEntity(model);\r
38165 },\r
38166 applyTransform: function(transform) {\r
38167 if (transform) {\r
38168 if (Ext.isFunction(transform)) {\r
38169 transform = {\r
38170 fn: transform\r
38171 };\r
38172 } else if (transform.charAt) {\r
38173
38174 transform = {\r
38175 fn: this[transform]\r
38176 };\r
38177 }\r
38178 return transform.fn.bind(transform.scope || this);\r
38179 }\r
38180 return transform;\r
38181 },\r
38182 forceBuildExtractors: function() {\r
38183 if (!this.duringInit) {\r
38184 this.buildExtractors(true);\r
38185 }\r
38186 },\r
38187 updateTotalProperty: function() {\r
38188 this.forceBuildExtractors();\r
38189 },\r
38190 updateMessageProperty: function() {\r
38191 this.forceBuildExtractors();\r
38192 },\r
38193 updateSuccessProperty: function() {\r
38194 this.forceBuildExtractors();\r
38195 },\r
38196 \r
38197 read: function(response, readOptions) {\r
38198 var data, result;\r
38199 if (response) {\r
38200 if (response.responseText) {\r
38201 result = this.getResponseData(response);\r
38202 if (result && result.__$isError) {\r
38203 return new Ext.data.ResultSet({\r
38204 total: 0,\r
38205 count: 0,\r
38206 records: [],\r
38207 success: false,\r
38208 message: result.msg\r
38209 });\r
38210 } else {\r
38211 data = this.readRecords(result, readOptions);\r
38212 }\r
38213 } else {\r
38214 data = this.readRecords(response, readOptions);\r
38215 }\r
38216 }\r
38217 return data || this.nullResultSet;\r
38218 },\r
38219 \r
38220 getNullResultSet: function() {\r
38221 return this.nullResultSet;\r
38222 },\r
38223 \r
38224 createReadError: function(msg) {\r
38225 return {\r
38226 __$isError: true,\r
38227 msg: msg\r
38228 };\r
38229 },\r
38230 \r
38231 readRecords: function(data, readOptions, \r
38232 internalReadOptions) {\r
38233 var me = this,\r
38234 recordsOnly = internalReadOptions && internalReadOptions.recordsOnly,\r
38235 asRoot = internalReadOptions && internalReadOptions.asRoot,\r
38236 success, recordCount, records, root, total, value, message, transform;\r
38237 transform = this.getTransform();\r
38238 if (transform) {\r
38239 data = transform(data);\r
38240 }\r
38241 me.buildExtractors();\r
38242 if (me.getKeepRawData()) {\r
38243 me.rawData = data;\r
38244 }\r
38245 if (me.hasListeners.rawdata) {\r
38246 me.fireEventArgs('rawdata', [\r
38247 data\r
38248 ]);\r
38249 }\r
38250 data = me.getData(data);\r
38251 success = true;\r
38252 recordCount = 0;\r
38253 records = [];\r
38254 if (me.getSuccessProperty()) {\r
38255 value = me.getSuccess(data);\r
38256 if (value === false || value === 'false') {\r
38257 success = false;\r
38258 }\r
38259 }\r
38260 if (me.getMessageProperty()) {\r
38261 message = me.getMessage(data);\r
38262 }\r
38263
38264 if (success || me.getReadRecordsOnFailure()) {\r
38265
38266
38267 root = (asRoot || Ext.isArray(data)) ? data : me.getRoot(data);\r
38268 if (root) {\r
38269 total = root.length;\r
38270 }\r
38271 if (me.getTotalProperty()) {\r
38272 value = parseInt(me.getTotal(data), 10);\r
38273 if (!isNaN(value)) {\r
38274 total = value;\r
38275 }\r
38276 }\r
38277 if (root) {\r
38278 records = me.extractData(root, readOptions);\r
38279 recordCount = records.length;\r
38280 }\r
38281 }\r
38282 return recordsOnly ? records : new Ext.data.ResultSet({\r
38283 total: total || recordCount,\r
38284 count: recordCount,\r
38285 records: records,\r
38286 success: success,\r
38287 message: message\r
38288 });\r
38289 },\r
38290 \r
38291 extractData: function(root, readOptions) {\r
38292 var me = this,\r
38293 entityType = readOptions && readOptions.model ? Ext.data.schema.Schema.lookupEntity(readOptions.model) : me.getModel(),\r
38294 schema = entityType.schema,\r
38295 includes = schema.hasAssociations(entityType) && me.getImplicitIncludes(),\r
38296 fieldExtractorInfo = me.getFieldExtractorInfo(entityType.fieldExtractors),\r
38297 length = root.length,\r
38298 records = new Array(length),\r
38299 typeProperty = me.getTypeProperty(),\r
38300 reader, node, nodeType, record, i;\r
38301 if (!length && Ext.isObject(root)) {\r
38302 root = [\r
38303 root\r
38304 ];\r
38305 length = 1;\r
38306 }\r
38307 for (i = 0; i < length; i++) {\r
38308 record = root[i];\r
38309 if (!record.isModel) {\r
38310
38311
38312 node = record;\r
38313
38314
38315
38316
38317
38318
38319 if (typeProperty && (nodeType = me.getChildType(schema, node, typeProperty))) {\r
38320 reader = nodeType.getProxy().getReader();\r
38321 record = reader.extractRecord(node, readOptions, nodeType, schema.hasAssociations(nodeType) && reader.getImplicitIncludes(), reader.getFieldExtractorInfo(nodeType.fieldExtractors));\r
38322 } else {\r
38323 record = me.extractRecord(node, readOptions, entityType, includes, fieldExtractorInfo);\r
38324 }\r
38325
38326
38327
38328
38329
38330 if (record.isModel && record.isNode) {\r
38331 record.raw = node;\r
38332 }\r
38333 }\r
38334 if (record.onLoad) {\r
38335 record.onLoad();\r
38336 }\r
38337 records[i] = record;\r
38338 }\r
38339 return records;\r
38340 },\r
38341
38342 getChildType: function(schema, rawNode, typeProperty) {\r
38343 var namespace;\r
38344 switch (typeof typeProperty) {\r
38345 case 'string':\r
38346 return schema.getEntity(rawNode[typeProperty]);\r
38347 case 'object':\r
38348 namespace = typeProperty.namespace;\r
38349 return schema.getEntity((namespace ? namespace + '.' : '') + rawNode[typeProperty.name]);\r
38350 case 'function':\r
38351 return schema.getEntity(typeProperty(rawNode));\r
38352 }\r
38353 },\r
38354 extractRecordData: function(node, readOptions) {\r
38355 var entityType = readOptions && readOptions.model ? Ext.data.schema.Schema.lookupEntity(readOptions.model) : this.getModel(),\r
38356 fieldExtractorInfo = this.getFieldExtractorInfo(entityType.fieldExtractors);\r
38357 return this.extractRecord(node, readOptions, entityType, false, fieldExtractorInfo);\r
38358 },\r
38359 extractRecord: function(node, readOptions, entityType, includes, fieldExtractorInfo) {\r
38360 var me = this,\r
38361 creatorFn = (readOptions && readOptions.recordCreator) || me.defaultRecordCreator,\r
38362 modelData, record;\r
38363
38364
38365
38366 modelData = me.extractModelData(node, fieldExtractorInfo);\r
38367 record = creatorFn.call(me, modelData, entityType || me.getModel(), readOptions);\r
38368 if (includes && record.isModel) {\r
38369 me.readAssociated(record, node, readOptions);\r
38370 }\r
38371 return record;\r
38372 },\r
38373 getFieldExtractorInfo: function(extractors) {\r
38374
38375
38376 if (!extractors) {\r
38377 return;\r
38378 }\r
38379 var type = this.$className,\r
38380 extractor = extractors[type];\r
38381
38382
38383 if (extractor === undefined) {\r
38384 extractors[type] = extractor = this.buildFieldExtractors();\r
38385 }\r
38386 return extractor;\r
38387 },\r
38388 buildFieldExtractors: function() {\r
38389 var fields = this.getFields(),\r
38390 len = fields.length,\r
38391 buffer = [],\r
38392 extractors = [],\r
38393 out = null,\r
38394 cnt = 0,\r
38395 field, name, i, extractor;\r
38396 for (i = 0; i < len; ++i) {\r
38397 field = fields[i];\r
38398 extractor = this.createFieldAccessor(field);\r
38399 if (extractor) {\r
38400 name = field.name;\r
38401
38402 buffer.push('val = extractors[' + cnt + '](raw); if (val !== undefined) { data[\'' + name + '\'] = val; }');\r
38403 extractors.push(extractor);\r
38404 ++cnt;\r
38405 }\r
38406 }\r
38407 if (buffer.length) {\r
38408 out = {\r
38409 extractors: extractors,\r
38410 fn: new Function('raw', 'data', 'extractors', 'var val;' + buffer.join(''))\r
38411 };\r
38412 }\r
38413 return out;\r
38414 },\r
38415 defaultRecordCreator: function(data, Model) {\r
38416 var record = new Model(data);\r
38417
38418
38419 record.phantom = false;\r
38420 return record;\r
38421 },\r
38422 getModelData: function(raw) {\r
38423 return {};\r
38424 },\r
38425 extractModelData: function(raw, fieldExtractorInfo) {\r
38426 var data = this.getModelData(raw),\r
38427 fn;\r
38428
38429 if (fieldExtractorInfo) {\r
38430 fn = fieldExtractorInfo.fn;\r
38431 fn(raw, data, fieldExtractorInfo.extractors);\r
38432 }\r
38433 return data;\r
38434 },\r
38435 \r
38436 readAssociated: function(record, data, readOptions) {\r
38437 var roles = record.associations,\r
38438 key, role;\r
38439 for (key in roles) {\r
38440 if (roles.hasOwnProperty(key)) {\r
38441 role = roles[key];\r
38442
38443 if (role.cls) {\r
38444 role.read(record, data, this, readOptions);\r
38445 }\r
38446 }\r
38447 }\r
38448 },\r
38449 getFields: function() {\r
38450 return this.getModel().fields;\r
38451 },\r
38452 \r
38453 getData: Ext.identityFn,\r
38454 \r
38455 getRoot: Ext.identityFn,\r
38456 \r
38457 getResponseData: function(response) {\r
38458
38459 Ext.raise("getResponseData must be implemented in the Ext.data.reader.Reader subclass");\r
38460 },\r
38461
38462 \r
38463 onMetaChange: function(meta) {\r
38464 var me = this,\r
38465 fields = meta.fields,\r
38466 model, newModel, clientIdProperty, proxy;\r
38467
38468 me.metaData = meta;\r
38469
38470 if (meta.root) {\r
38471 me.setRootProperty(meta.root);\r
38472 }\r
38473 if (meta.totalProperty) {\r
38474 me.setTotalProperty(meta.totalProperty);\r
38475 }\r
38476 if (meta.successProperty) {\r
38477 me.setSuccessProperty(meta.successProperty);\r
38478 }\r
38479 if (meta.messageProperty) {\r
38480 me.setMessageProperty(meta.messageProperty);\r
38481 }\r
38482 clientIdProperty = meta.clientIdProperty;\r
38483 if (fields) {\r
38484 newModel = Ext.define(null, {\r
38485 extend: 'Ext.data.Model',\r
38486 fields: fields,\r
38487 clientIdProperty: clientIdProperty\r
38488 });\r
38489 me.setModel(newModel);\r
38490 proxy = me.getProxy();\r
38491 if (proxy) {\r
38492 proxy.setModel(newModel);\r
38493 }\r
38494 } else if (clientIdProperty) {\r
38495 model = me.getModel();\r
38496 if (model) {\r
38497 model.self.prototype.clientIdProperty = clientIdProperty;\r
38498 }\r
38499 }\r
38500 },\r
38501 \r
38502 buildExtractors: function(force) {\r
38503 var me = this,\r
38504 totalProp, successProp, messageProp;\r
38505 if (force || !me.hasExtractors) {\r
38506 totalProp = me.getTotalProperty();\r
38507 successProp = me.getSuccessProperty();\r
38508 messageProp = me.getMessageProperty();\r
38509
38510 if (totalProp) {\r
38511 me.getTotal = me.getAccessor(totalProp);\r
38512 }\r
38513 if (successProp) {\r
38514 me.getSuccess = me.getAccessor(successProp);\r
38515 }\r
38516 if (messageProp) {\r
38517 me.getMessage = me.getAccessor(messageProp);\r
38518 }\r
38519 me.hasExtractors = true;\r
38520 return true;\r
38521 }\r
38522 },\r
38523 getAccessor: function(prop) {\r
38524 var me = this,\r
38525 cache = me.extractorCache,\r
38526 ret, key;\r
38527 if (typeof prop === 'string') {\r
38528 key = me.getAccessorKey(prop);\r
38529 ret = cache.get(key);\r
38530 if (!ret) {\r
38531 ret = me.createAccessor(prop);\r
38532 cache.add(key, ret);\r
38533 }\r
38534 } else {\r
38535 ret = me.createAccessor(prop);\r
38536 }\r
38537 return ret;\r
38538 },\r
38539 getAccessorKey: function(prop) {\r
38540 return this.$className + prop;\r
38541 },\r
38542 createAccessor: Ext.emptyFn,\r
38543 createFieldAccessor: Ext.emptyFn,\r
38544 destroy: function() {\r
38545 var me = this;\r
38546 me.model = me.getTotal = me.getSuccess = me.getMessage = me.rawData = null;\r
38547
38548 me.onMetaChange = null;\r
38549
38550 me.transform = null;\r
38551 me.callParent();\r
38552 },\r
38553 privates: {\r
38554 copyFrom: function(reader) {\r
38555 var me = this;\r
38556 reader.buildExtractors();\r
38557 me.getTotal = reader.getTotal;\r
38558 me.getSuccess = reader.getSuccess;\r
38559 me.getMessage = reader.getMessage;\r
38560 ++me.duringInit;\r
38561 me.setConfig(reader.getConfig());\r
38562 --me.duringInit;\r
38563 me.hasExtractors = true;\r
38564 }\r
38565 }\r
38566}, function(Cls) {\r
38567 var proto = Cls.prototype;\r
38568 Ext.apply(proto, {\r
38569
38570 nullResultSet: new Ext.data.ResultSet({\r
38571 total: 0,\r
38572 count: 0,\r
38573 records: [],\r
38574 success: true,\r
38575 message: ''\r
38576 })\r
38577 });\r
38578 proto.extractorCache = new Ext.util.LruCache();\r
38579});\r
38580\r
38581\r
38582Ext.define('Ext.data.writer.Writer', {\r
38583 mixins: [\r
38584 Ext.mixin.Factoryable\r
38585 ],\r
38586 alias: 'writer.base',\r
38587 factoryConfig: {\r
38588 defaultType: null\r
38589 },\r
38590 alternateClassName: [\r
38591 'Ext.data.DataWriter',\r
38592 'Ext.data.Writer'\r
38593 ],\r
38594 config: {\r
38595 \r
38596 clientIdProperty: null,\r
38597 \r
38598 allDataOptions: {\r
38599 persist: true\r
38600 },\r
38601 \r
38602 partialDataOptions: {\r
38603 changes: true,\r
38604 critical: true\r
38605 },\r
38606 \r
38607 writeAllFields: false,\r
38608 \r
38609 dateFormat: null,\r
38610 \r
38611 nameProperty: 'name',\r
38612 \r
38613 writeRecordId: true,\r
38614 \r
38615 transform: null\r
38616 },\r
38617 \r
38618 isWriter: true,\r
38619 \r
38620 constructor: function(config) {\r
38621 this.initConfig(config);\r
38622 },\r
38623 applyTransform: function(transform) {\r
38624 if (transform) {\r
38625 if (Ext.isFunction(transform)) {\r
38626 transform = {\r
38627 fn: transform\r
38628 };\r
38629 }\r
38630 return transform.fn.bind(transform.scope || this);\r
38631 }\r
38632 return transform;\r
38633 },\r
38634 \r
38635 write: function(request) {\r
38636 var operation = request.getOperation(),\r
38637 records = operation.getRecords() || [],\r
38638 len = records.length,\r
38639 data = [],\r
38640 i;\r
38641 for (i = 0; i < len; i++) {\r
38642 data.push(this.getRecordData(records[i], operation));\r
38643 }\r
38644 return this.writeRecords(request, data);\r
38645 },\r
38646 \r
38647 writeRecords: Ext.emptyFn,\r
38648 \r
38649 getRecordData: function(record, operation) {\r
38650 var me = this,\r
38651 nameProperty = me.getNameProperty(),\r
38652 mapping = nameProperty !== 'name',\r
38653 idField = record.self.idField,\r
38654 key = idField[nameProperty] || idField.name,\r
38655
38656 value = record.id,\r
38657 writeAll = me.getWriteAllFields(),\r
38658 ret, dateFormat, phantom, options, clientIdProperty, fieldsMap, data, field;\r
38659 if (idField.serialize) {\r
38660 value = idField.serialize(value);\r
38661 }\r
38662 if (!writeAll && operation && operation.isDestroyOperation) {\r
38663 ret = {};\r
38664 ret[key] = value;\r
38665 } else {\r
38666 dateFormat = me.getDateFormat();\r
38667 phantom = record.phantom;\r
38668 options = (phantom || writeAll) ? me.getAllDataOptions() : me.getPartialDataOptions();\r
38669 clientIdProperty = phantom && me.getClientIdProperty();\r
38670 fieldsMap = record.getFieldsMap();\r
38671 options.serialize = false;\r
38672
38673 data = record.getData(options);\r
38674
38675
38676 ret = mapping ? {} : data;\r
38677 if (clientIdProperty) {\r
38678
38679 ret[clientIdProperty] = value;\r
38680
38681 delete data[key];\r
38682 }\r
38683
38684 else if (!me.getWriteRecordId()) {\r
38685 delete data[key];\r
38686 }\r
38687 for (key in data) {\r
38688 value = data[key];\r
38689 if (!(field = fieldsMap[key])) {\r
38690
38691
38692
38693 if (mapping) {\r
38694 ret[key] = value;\r
38695 }\r
38696 } else {\r
38697
38698
38699
38700 if (field.isDateField && dateFormat && Ext.isDate(value)) {\r
38701 value = Ext.Date.format(value, dateFormat);\r
38702 } else if (field.serialize) {\r
38703 value = field.serialize(value, record);\r
38704 }\r
38705 if (mapping) {\r
38706 key = field[nameProperty] || key;\r
38707 }\r
38708 ret[key] = value;\r
38709 }\r
38710 }\r
38711 }\r
38712 return ret;\r
38713 }\r
38714});\r
38715\r
38716\r
38717Ext.define('Ext.data.proxy.Proxy', {\r
38718 mixins: [\r
38719 Ext.mixin.Factoryable,\r
38720 Ext.mixin.Observable\r
38721 ],\r
38722 $configPrefixed: false,\r
38723 alias: 'proxy.proxy',\r
38724
38725 alternateClassName: [\r
38726 'Ext.data.DataProxy',\r
38727 'Ext.data.Proxy'\r
38728 ],\r
38729 config: {\r
38730 \r
38731 batchOrder: 'create,update,destroy',\r
38732 \r
38733 batchActions: true,\r
38734 \r
38735 model: undefined,\r
38736
38737 \r
38738 reader: {\r
38739 type: 'json'\r
38740 },\r
38741
38742 \r
38743 writer: {\r
38744 type: 'json'\r
38745 }\r
38746 },\r
38747 \r
38748 isProxy: true,\r
38749 \r
38750 isSynchronous: false,\r
38751 \r
38752 \r
38753 constructor: function(config) {\r
38754
38755 this.mixins.observable.constructor.call(this, config);\r
38756
38757 this.pendingOperations = {};\r
38758 },\r
38759 applyModel: function(model) {\r
38760 return Ext.data.schema.Schema.lookupEntity(model);\r
38761 },\r
38762 updateModel: function(model) {\r
38763 if (model) {\r
38764 var reader = this.getReader();\r
38765 if (reader && !reader.getModel()) {\r
38766 reader.setModel(model);\r
38767 }\r
38768 }\r
38769 },\r
38770 applyReader: function(reader) {\r
38771
38772
38773
38774
38775 if (this.isSynchronous) {\r
38776 reader = reader || {};\r
38777 reader.keepRawData = true;\r
38778 }\r
38779 return Ext.Factory.reader(reader);\r
38780 },\r
38781 updateReader: function(reader) {\r
38782 if (reader) {\r
38783 var me = this,\r
38784 model = me.getModel();\r
38785 if (!model) {\r
38786 model = reader.getModel();\r
38787 if (model) {\r
38788 me.setModel(model);\r
38789 }\r
38790 } else {\r
38791 reader.setModel(model);\r
38792 }\r
38793
38794 if (reader.onMetaChange) {\r
38795 reader.onMetaChange = Ext.Function.createSequence(reader.onMetaChange, me.onMetaChange, me);\r
38796 }\r
38797 }\r
38798 },\r
38799 applyWriter: function(writer) {\r
38800 var reader = this.getReader();\r
38801 writer = Ext.Factory.writer(writer);\r
38802
38803
38804 if (writer.getRecord && !writer.getRecord() && reader && reader.getRecord) {\r
38805 reader = reader.getRecord();\r
38806 if (reader) {\r
38807 writer.setRecord(reader);\r
38808 }\r
38809 }\r
38810 return writer;\r
38811 },\r
38812 abort: Ext.emptyFn,\r
38813 \r
38814 onMetaChange: function(meta) {\r
38815 this.fireEvent('metachange', this, meta);\r
38816 },\r
38817 \r
38818 create: Ext.emptyFn,\r
38819 \r
38820 read: Ext.emptyFn,\r
38821 \r
38822 update: Ext.emptyFn,\r
38823 \r
38824 erase: Ext.emptyFn,\r
38825 \r
38826 batch: function(options, \r
38827 listeners) {\r
38828 var me = this,\r
38829 useBatch = me.getBatchActions(),\r
38830 batch, records, actions, aLen, action, a, r, rLen, record;\r
38831 if (options.operations === undefined) {\r
38832
38833
38834 options = {\r
38835 operations: options,\r
38836 listeners: listeners\r
38837 };\r
38838 }\r
38839 if (options.batch) {\r
38840 if (Ext.isDefined(options.batch.runOperation)) {\r
38841 batch = Ext.applyIf(options.batch, {\r
38842 proxy: me,\r
38843 listeners: {}\r
38844 });\r
38845 }\r
38846 } else {\r
38847 options.batch = {\r
38848 proxy: me,\r
38849 listeners: options.listeners || {}\r
38850 };\r
38851 }\r
38852 if (!batch) {\r
38853 batch = new Ext.data.Batch(options.batch);\r
38854 }\r
38855 batch.on('complete', Ext.bind(me.onBatchComplete, me, [\r
38856 options\r
38857 ], 0));\r
38858 actions = me.getBatchOrder().split(',');\r
38859 aLen = actions.length;\r
38860 for (a = 0; a < aLen; a++) {\r
38861 action = actions[a];\r
38862 records = options.operations[action];\r
38863 if (records) {\r
38864 if (useBatch) {\r
38865 batch.add(me.createOperation(action, {\r
38866 records: records,\r
38867
38868 params: options.params\r
38869 }));\r
38870 } else {\r
38871 rLen = records.length;\r
38872 for (r = 0; r < rLen; r++) {\r
38873 record = records[r];\r
38874 batch.add(me.createOperation(action, {\r
38875 records: [\r
38876 record\r
38877 ],\r
38878
38879 params: options.params\r
38880 }));\r
38881 }\r
38882 }\r
38883 }\r
38884 }\r
38885 batch.start();\r
38886 return batch;\r
38887 },\r
38888 \r
38889 onBatchComplete: function(batchOptions, batch) {\r
38890 var scope = batchOptions.scope || this;\r
38891 if (batch.hasException()) {\r
38892 if (Ext.isFunction(batchOptions.failure)) {\r
38893 Ext.callback(batchOptions.failure, scope, [\r
38894 batch,\r
38895 batchOptions\r
38896 ]);\r
38897 }\r
38898 } else if (Ext.isFunction(batchOptions.success)) {\r
38899 Ext.callback(batchOptions.success, scope, [\r
38900 batch,\r
38901 batchOptions\r
38902 ]);\r
38903 }\r
38904 if (Ext.isFunction(batchOptions.callback)) {\r
38905 Ext.callback(batchOptions.callback, scope, [\r
38906 batch,\r
38907 batchOptions\r
38908 ]);\r
38909 }\r
38910 },\r
38911 createOperation: function(action, config) {\r
38912 var operation = Ext.createByAlias('data.operation.' + action, config);\r
38913 operation.setProxy(this);\r
38914 this.pendingOperations[operation._internalId] = operation;\r
38915 return operation;\r
38916 },\r
38917 completeOperation: function(operation) {\r
38918 delete this.pendingOperations[operation._internalId];\r
38919 },\r
38920 clone: function() {\r
38921 return new this.self(this.getInitialConfig());\r
38922 },\r
38923 destroy: function() {\r
38924 var ops = this.pendingOperations,\r
38925 opId, op;\r
38926 for (opId in ops) {\r
38927 op = ops[opId];\r
38928 if (op && op.isRunning()) {\r
38929 op.abort();\r
38930 }\r
38931 }\r
38932 this.pendingOperations = null;\r
38933 }\r
38934});\r
38935\r
38936\r
38937Ext.define('Ext.data.proxy.Client', {\r
38938 extend: Ext.data.proxy.Proxy,\r
38939 alternateClassName: 'Ext.data.ClientProxy',\r
38940 \r
38941 isSynchronous: true,\r
38942 \r
38943 clear: function() {\r
38944
38945 Ext.raise("The Ext.data.proxy.Client subclass that you are using has not defined a 'clear' function. See src/data/ClientProxy.js for details.");\r
38946 }\r
38947});\r
38948
38949\r
38950\r
38951Ext.define('Ext.data.proxy.Memory', {\r
38952 extend: Ext.data.proxy.Client,\r
38953 alias: 'proxy.memory',\r
38954 alternateClassName: 'Ext.data.MemoryProxy',\r
38955 isMemoryProxy: true,\r
38956 config: {\r
38957 \r
38958 enablePaging: false,\r
38959 \r
38960 data: {\r
38961 $value: null,\r
38962
38963 merge: function(newValue, currentValue, target, mixinClass) {\r
38964 if (Ext.isArray(newValue)) {\r
38965 return Ext.Array.clone(newValue);\r
38966 } else {\r
38967 return Ext.clone(newValue);\r
38968 }\r
38969 }\r
38970 }\r
38971 },\r
38972 \r
38973 finishOperation: function(operation) {\r
38974 var i = 0,\r
38975 recs = operation.getRecords(),\r
38976 len = recs.length;\r
38977 for (i; i < len; i++) {\r
38978 recs[i].commit();\r
38979 }\r
38980 operation.setSuccessful(true);\r
38981 },\r
38982 \r
38983 create: function(operation) {\r
38984 this.finishOperation(operation);\r
38985 },\r
38986 \r
38987 update: function(operation) {\r
38988 this.finishOperation(operation);\r
38989 },\r
38990 \r
38991 erase: function(operation) {\r
38992 this.finishOperation(operation);\r
38993 },\r
38994 \r
38995 read: function(operation) {\r
38996 var me = this,\r
38997 resultSet = me.getReader().read(me.getData()),\r
38998 records = resultSet.getRecords(),\r
38999 sorters = operation.getSorters(),\r
39000 grouper = operation.getGrouper(),\r
39001 filters = operation.getFilters(),\r
39002 start = operation.getStart(),\r
39003 limit = operation.getLimit();\r
39004
39005 if (operation.process(resultSet, null, null, false) !== false) {\r
39006
39007 if (filters && filters.length) {\r
39008
39009 resultSet.setRecords(records = Ext.Array.filter(records, Ext.util.Filter.createFilterFn(filters)));\r
39010 resultSet.setTotal(records.length);\r
39011 }\r
39012
39013 if (grouper) {\r
39014
39015 sorters = sorters ? sorters.concat(grouper) : sorters;\r
39016 }\r
39017
39018 if (sorters && sorters.length) {\r
39019 resultSet.setRecords(records = Ext.Array.sort(records, Ext.util.Sortable.createComparator(sorters)));\r
39020 }\r
39021
39022
39023 if (me.getEnablePaging() && start !== undefined && limit !== undefined) {\r
39024
39025 if (start >= resultSet.getTotal()) {\r
39026 resultSet.setConfig({\r
39027 success: false,\r
39028 records: [],\r
39029 total: 0\r
39030 });\r
39031 } else
39032 {\r
39033 resultSet.setRecords(Ext.Array.slice(records, start, start + limit));\r
39034 }\r
39035 }\r
39036 operation.setCompleted();\r
39037 }\r
39038 },\r
39039 clear: Ext.emptyFn\r
39040});\r
39041\r
39042\r
39043Ext.define('Ext.data.ProxyStore', {\r
39044 extend: Ext.data.AbstractStore,\r
39045 config: {\r
39046
39047 \r
39048 model: undefined,\r
39049
39050 \r
39051 fields: null,\r
39052
39053 \r
39054 proxy: undefined,\r
39055 \r
39056 autoLoad: undefined,\r
39057 \r
39058 autoSync: false,\r
39059 \r
39060 batchUpdateMode: 'operation',\r
39061 \r
39062 sortOnLoad: true,\r
39063 \r
39064 trackRemoved: true,\r
39065 \r
39066 asynchronousLoad: undefined\r
39067 },\r
39068 onClassExtended: function(cls, data, hooks) {\r
39069 var model = data.model,\r
39070 onBeforeClassCreated;\r
39071 if (typeof model === 'string') {\r
39072 onBeforeClassCreated = hooks.onBeforeCreated;\r
39073 hooks.onBeforeCreated = function() {\r
39074 var me = this,\r
39075 args = arguments;\r
39076 Ext.require(model, function() {\r
39077 onBeforeClassCreated.apply(me, args);\r
39078 });\r
39079 };\r
39080 }\r
39081 },\r
39082 \r
39083 implicitModel: 'Ext.data.Model',\r
39084 \r
39085 \r
39086 autoSyncSuspended: 0,\r
39087
39088 constructor: function(config) {\r
39089 var me = this;\r
39090
39091 var configModel = me.model;\r
39092
39093 \r
39094 \r
39095 \r
39096 \r
39097 \r
39098 \r
39099 me.removed = [];\r
39100 me.callParent(arguments);\r
39101 if (me.getAsynchronousLoad() === false) {\r
39102 me.flushLoad();\r
39103 }\r
39104
39105 if (!me.getModel() && me.useModelWarning !== false && me.getStoreId() !== 'ext-empty-store') {\r
39106
39107 var logMsg = [\r
39108 Ext.getClassName(me) || 'Store',\r
39109 ' created with no model.'\r
39110 ];\r
39111 if (typeof configModel === 'string') {\r
39112 logMsg.push(" The name '", configModel, "'", ' does not correspond to a valid model.');\r
39113 }\r
39114 Ext.log.warn(logMsg.join(''));\r
39115 }\r
39116 },\r
39117
39118 applyAsynchronousLoad: function(asynchronousLoad) {\r
39119
39120
39121 if (asynchronousLoad == null) {\r
39122 asynchronousLoad = !this.loadsSynchronously();\r
39123 }\r
39124 return asynchronousLoad;\r
39125 },\r
39126 updateAutoLoad: function(autoLoad) {\r
39127
39128 this.getData();\r
39129 if (autoLoad) {\r
39130
39131 this.load(Ext.isObject(autoLoad) ? autoLoad : undefined);\r
39132 }\r
39133 },\r
39134 \r
39135 getTotalCount: function() {\r
39136 return this.totalCount || 0;\r
39137 },\r
39138 applyFields: function(fields) {\r
39139 if (fields) {\r
39140 this.createImplicitModel(fields);\r
39141 }\r
39142 },\r
39143 applyModel: function(model) {\r
39144 if (model) {\r
39145 model = Ext.data.schema.Schema.lookupEntity(model);\r
39146 } else
39147 {\r
39148 this.getFields();\r
39149 model = this.getModel() || this.createImplicitModel();\r
39150 }\r
39151 return model;\r
39152 },\r
39153 applyProxy: function(proxy) {\r
39154 var model = this.getModel();\r
39155 if (proxy !== null) {\r
39156 if (proxy) {\r
39157 if (proxy.isProxy) {\r
39158 proxy.setModel(model);\r
39159 } else {\r
39160 if (Ext.isString(proxy)) {\r
39161 proxy = {\r
39162 type: proxy,\r
39163 model: model\r
39164 };\r
39165 } else if (!proxy.model) {\r
39166 proxy = Ext.apply({\r
39167 model: model\r
39168 }, proxy);\r
39169 }\r
39170 proxy = Ext.createByAlias('proxy.' + proxy.type, proxy);\r
39171 proxy.autoCreated = true;\r
39172 }\r
39173 } else if (model) {\r
39174 proxy = model.getProxy();\r
39175 }\r
39176 if (!proxy) {\r
39177 proxy = Ext.createByAlias('proxy.memory');\r
39178 proxy.autoCreated = true;\r
39179 }\r
39180 }\r
39181 return proxy;\r
39182 },\r
39183 applyState: function(state) {\r
39184 var me = this;\r
39185 me.callParent([\r
39186 state\r
39187 ]);\r
39188
39189
39190
39191
39192 if (me.getAutoLoad() || me.isLoaded()) {\r
39193 me.load();\r
39194 }\r
39195 },\r
39196 updateProxy: function(proxy, oldProxy) {\r
39197 this.proxyListeners = Ext.destroy(this.proxyListeners);\r
39198 },\r
39199 updateTrackRemoved: function(track) {\r
39200 this.cleanRemoved();\r
39201 this.removed = track ? [] : null;\r
39202 },\r
39203 \r
39204 onMetaChange: function(proxy, meta) {\r
39205 this.fireEvent('metachange', this, meta);\r
39206 },\r
39207
39208 create: function(data, options) {\r
39209 var me = this,\r
39210 Model = me.getModel(),\r
39211 instance = new Model(data),\r
39212 operation;\r
39213 options = Ext.apply({}, options);\r
39214 if (!options.records) {\r
39215 options.records = [\r
39216 instance\r
39217 ];\r
39218 }\r
39219 options.internalScope = me;\r
39220 options.internalCallback = me.onProxyWrite;\r
39221 operation = me.createOperation('create', options);\r
39222 return operation.execute();\r
39223 },\r
39224 read: function() {\r
39225 return this.load.apply(this, arguments);\r
39226 },\r
39227 update: function(options) {\r
39228 var me = this,\r
39229 operation;\r
39230 options = Ext.apply({}, options);\r
39231 if (!options.records) {\r
39232 options.records = me.getUpdatedRecords();\r
39233 }\r
39234 options.internalScope = me;\r
39235 options.internalCallback = me.onProxyWrite;\r
39236 operation = me.createOperation('update', options);\r
39237 return operation.execute();\r
39238 },\r
39239 \r
39240 onProxyWrite: function(operation) {\r
39241 var me = this,\r
39242 success = operation.wasSuccessful(),\r
39243 records = operation.getRecords();\r
39244 switch (operation.getAction()) {\r
39245 case 'create':\r
39246 me.onCreateRecords(records, operation, success);\r
39247 break;\r
39248 case 'update':\r
39249 me.onUpdateRecords(records, operation, success);\r
39250 break;\r
39251 case 'destroy':\r
39252 me.onDestroyRecords(records, operation, success);\r
39253 break;\r
39254 }\r
39255 if (success) {\r
39256 me.fireEvent('write', me, operation);\r
39257 me.fireEvent('datachanged', me);\r
39258 }\r
39259 },\r
39260
39261 onCreateRecords: Ext.emptyFn,\r
39262
39263 onUpdateRecords: Ext.emptyFn,\r
39264 \r
39265 onDestroyRecords: function(records, operation, success) {\r
39266 if (success) {\r
39267 this.cleanRemoved();\r
39268 }\r
39269 },\r
39270
39271
39272 erase: function(options) {\r
39273 var me = this,\r
39274 operation;\r
39275 options = Ext.apply({}, options);\r
39276 if (!options.records) {\r
39277 options.records = me.getRemovedRecords();\r
39278 }\r
39279 options.internalScope = me;\r
39280 options.internalCallback = me.onProxyWrite;\r
39281 operation = me.createOperation('destroy', options);\r
39282 return operation.execute();\r
39283 },\r
39284 \r
39285 onBatchOperationComplete: function(batch, operation) {\r
39286 return this.onProxyWrite(operation);\r
39287 },\r
39288 \r
39289 onBatchComplete: function(batch, operation) {\r
39290 var me = this,\r
39291 operations = batch.operations,\r
39292 length = operations.length,\r
39293 i;\r
39294 if (me.batchUpdateMode !== 'operation') {\r
39295 me.suspendEvents();\r
39296 for (i = 0; i < length; i++) {\r
39297 me.onProxyWrite(operations[i]);\r
39298 }\r
39299 me.resumeEvents();\r
39300 }\r
39301 me.isSyncing = false;\r
39302 me.fireEvent('datachanged', me);\r
39303 },\r
39304 \r
39305 onBatchException: function(batch, operation) {},\r
39306
39307
39308
39309
39310
39311 \r
39312 filterNew: function(item) {\r
39313
39314 return item.phantom === true && item.isValid();\r
39315 },\r
39316 \r
39317 getNewRecords: function() {\r
39318 return [];\r
39319 },\r
39320 \r
39321 getUpdatedRecords: function() {\r
39322 return [];\r
39323 },\r
39324 \r
39325 getModifiedRecords: function() {\r
39326 return [].concat(this.getNewRecords(), this.getUpdatedRecords());\r
39327 },\r
39328 \r
39329 filterUpdated: function(item) {\r
39330
39331 return item.dirty === true && item.phantom !== true && item.isValid();\r
39332 },\r
39333 \r
39334 getRemovedRecords: function() {\r
39335 var removed = this.getRawRemovedRecords();\r
39336
39337 return removed ? Ext.Array.clone(removed) : removed;\r
39338 },\r
39339 \r
39340 sync: function(options) {\r
39341 var me = this,\r
39342 operations = {},\r
39343 toCreate = me.getNewRecords(),\r
39344 toUpdate = me.getUpdatedRecords(),\r
39345 toDestroy = me.getRemovedRecords(),\r
39346 needsSync = false;\r
39347
39348 if (me.isSyncing) {\r
39349 Ext.log.warn('Sync called while a sync operation is in progress. Consider configuring autoSync as false.');\r
39350 }\r
39351
39352 me.needsSync = false;\r
39353 if (toCreate.length > 0) {\r
39354 operations.create = toCreate;\r
39355 needsSync = true;\r
39356 }\r
39357 if (toUpdate.length > 0) {\r
39358 operations.update = toUpdate;\r
39359 needsSync = true;\r
39360 }\r
39361 if (toDestroy.length > 0) {\r
39362 operations.destroy = toDestroy;\r
39363 needsSync = true;\r
39364 }\r
39365 if (needsSync && me.fireEvent('beforesync', operations) !== false) {\r
39366 me.isSyncing = true;\r
39367 options = options || {};\r
39368 me.proxy.batch(Ext.apply(options, {\r
39369 operations: operations,\r
39370 listeners: me.getBatchListeners()\r
39371 }));\r
39372 }\r
39373 return me;\r
39374 },\r
39375 \r
39376 getBatchListeners: function() {\r
39377 var me = this,\r
39378 listeners = {\r
39379 scope: me,\r
39380 exception: me.onBatchException,\r
39381 complete: me.onBatchComplete\r
39382 };\r
39383 if (me.batchUpdateMode === 'operation') {\r
39384 listeners.operationcomplete = me.onBatchOperationComplete;\r
39385 }\r
39386 return listeners;\r
39387 },\r
39388 \r
39389 save: function() {\r
39390 return this.sync.apply(this, arguments);\r
39391 },\r
39392 \r
39393 load: function(options) {\r
39394 var me = this;\r
39395
39396 if (typeof options === 'function') {\r
39397 options = {\r
39398 callback: options\r
39399 };\r
39400 } else {\r
39401
39402 options = options ? Ext.Object.chain(options) : {};\r
39403 }\r
39404 me.pendingLoadOptions = options;\r
39405
39406
39407 if (me.getAsynchronousLoad()) {\r
39408 if (!me.loadTimer) {\r
39409 me.loadTimer = Ext.asap(me.flushLoad, me);\r
39410 }\r
39411 } else
39412
39413 {\r
39414 me.flushLoad();\r
39415 }\r
39416 return me;\r
39417 },\r
39418 \r
39419 flushLoad: function() {\r
39420 var me = this,\r
39421 options = me.pendingLoadOptions,\r
39422 operation;\r
39423
39424 me.clearLoadTask();\r
39425 if (!options) {\r
39426 return;\r
39427 }\r
39428 me.setLoadOptions(options);\r
39429 if (me.getRemoteSort() && options.sorters) {\r
39430 me.fireEvent('beforesort', me, options.sorters);\r
39431 }\r
39432 operation = Ext.apply({\r
39433 internalScope: me,\r
39434 internalCallback: me.onProxyLoad,\r
39435 scope: me\r
39436 }, options);\r
39437 me.lastOptions = operation;\r
39438 operation = me.createOperation('read', operation);\r
39439 if (me.fireEvent('beforeload', me, operation) !== false) {\r
39440 me.onBeforeLoad(operation);\r
39441 me.loading = true;\r
39442 operation.execute();\r
39443 }\r
39444 },\r
39445 \r
39446 reload: function(options) {\r
39447 var o = Ext.apply({}, options, this.lastOptions);\r
39448 return this.load(o);\r
39449 },\r
39450 onEndUpdate: function() {\r
39451 var me = this;\r
39452 if (me.needsSync && me.autoSync && !me.autoSyncSuspended) {\r
39453 me.sync();\r
39454 }\r
39455 },\r
39456 \r
39457 afterReject: function(record) {\r
39458 var me = this;\r
39459
39460
39461
39462
39463
39464 if (me.contains(record)) {\r
39465 me.onUpdate(record, Ext.data.Model.REJECT, null);\r
39466 me.fireEvent('update', me, record, Ext.data.Model.REJECT, null);\r
39467 }\r
39468 },\r
39469 \r
39470 afterCommit: function(record, modifiedFieldNames) {\r
39471 var me = this;\r
39472 if (!modifiedFieldNames) {\r
39473 modifiedFieldNames = null;\r
39474 }\r
39475 if (me.contains(record)) {\r
39476 me.onUpdate(record, Ext.data.Model.COMMIT, modifiedFieldNames);\r
39477 me.fireEvent('update', me, record, Ext.data.Model.COMMIT, modifiedFieldNames);\r
39478 }\r
39479 },\r
39480 afterErase: function(record) {\r
39481 this.onErase(record);\r
39482 },\r
39483 onErase: Ext.emptyFn,\r
39484 onUpdate: Ext.emptyFn,\r
39485 \r
39486 onDestroy: function() {\r
39487 var me = this,\r
39488 proxy = me.getProxy();\r
39489 me.clearLoadTask();\r
39490 me.getData().destroy();\r
39491 me.data = null;\r
39492 me.setProxy(null);\r
39493 if (proxy.autoCreated) {\r
39494 proxy.destroy();\r
39495 }\r
39496 me.setModel(null);\r
39497 },\r
39498 \r
39499 hasPendingLoad: function() {\r
39500 return !!this.pendingLoadOptions || this.isLoading();\r
39501 },\r
39502 \r
39503 isLoading: function() {\r
39504 return !!this.loading;\r
39505 },\r
39506 \r
39507 isLoaded: function() {\r
39508 return this.loadCount > 0;\r
39509 },\r
39510 \r
39511 suspendAutoSync: function() {\r
39512 ++this.autoSyncSuspended;\r
39513 },\r
39514 \r
39515 resumeAutoSync: function(syncNow) {\r
39516 var me = this;\r
39517
39518 if (!me.autoSyncSuspended) {\r
39519 Ext.log.warn('Mismatched call to resumeAutoSync - auto synchronization is currently not suspended.');\r
39520 }\r
39521
39522 if (me.autoSyncSuspended && !--me.autoSyncSuspended) {\r
39523 if (syncNow) {\r
39524 me.sync();\r
39525 }\r
39526 }\r
39527 },\r
39528 \r
39529 removeAll: Ext.emptyFn,\r
39530
39531
39532
39533 clearData: Ext.emptyFn,\r
39534 privates: {\r
39535 \r
39536 getRawRemovedRecords: function() {\r
39537 return this.removed;\r
39538 },\r
39539 onExtraParamsChanged: function() {},\r
39540 clearLoadTask: function() {\r
39541 Ext.asapCancel(this.loadTimer);\r
39542 this.pendingLoadOptions = this.loadTimer = null;\r
39543 },\r
39544 cleanRemoved: function() {\r
39545
39546
39547
39548
39549 var removed = this.getRawRemovedRecords(),\r
39550 len, i;\r
39551 if (removed) {\r
39552 for (i = 0 , len = removed.length; i < len; ++i) {\r
39553 removed[i].unjoin(this);\r
39554 }\r
39555 removed.length = 0;\r
39556 }\r
39557 },\r
39558 createOperation: function(type, options) {\r
39559 var me = this,\r
39560 proxy = me.getProxy(),\r
39561 listeners;\r
39562 if (!me.proxyListeners) {\r
39563 listeners = {\r
39564 scope: me,\r
39565 destroyable: true,\r
39566 beginprocessresponse: me.beginUpdate,\r
39567 endprocessresponse: me.endUpdate\r
39568 };\r
39569 if (!me.disableMetaChangeEvent) {\r
39570 listeners.metachange = me.onMetaChange;\r
39571 }\r
39572 me.proxyListeners = proxy.on(listeners);\r
39573 }\r
39574 return proxy.createOperation(type, options);\r
39575 },\r
39576 createImplicitModel: function(fields) {\r
39577 var me = this,\r
39578 modelCfg = {\r
39579 extend: me.implicitModel,\r
39580 statics: {\r
39581 defaultProxy: 'memory'\r
39582 }\r
39583 },\r
39584 proxy, model;\r
39585 if (fields) {\r
39586 modelCfg.fields = fields;\r
39587 }\r
39588 model = Ext.define(null, modelCfg);\r
39589 me.setModel(model);\r
39590 proxy = me.getProxy();\r
39591 if (proxy) {\r
39592 model.setProxy(proxy);\r
39593 } else {\r
39594 me.setProxy(model.getProxy());\r
39595 }\r
39596 },\r
39597 loadsSynchronously: function() {\r
39598 return this.getProxy().isSynchronous;\r
39599 },\r
39600 onBeforeLoad: Ext.privateFn,\r
39601 removeFromRemoved: function(record) {\r
39602
39603
39604
39605
39606 var removed = this.getRawRemovedRecords();\r
39607 if (removed) {\r
39608 Ext.Array.remove(removed, record);\r
39609 record.unjoin(this);\r
39610 }\r
39611 },\r
39612 setLoadOptions: function(options) {\r
39613 var me = this,\r
39614 filters, sorters;\r
39615 if (me.getRemoteFilter()) {\r
39616 filters = me.getFilters(false);\r
39617 if (filters && filters.getCount()) {\r
39618 options.filters = filters.getRange();\r
39619 }\r
39620 }\r
39621 if (me.getRemoteSort()) {\r
39622 sorters = me.getSorters(false);\r
39623 if (sorters && sorters.getCount()) {\r
39624 options.sorters = sorters.getRange();\r
39625 }\r
39626 }\r
39627 }\r
39628 }\r
39629});\r
39630\r
39631\r
39632Ext.define('Ext.data.LocalStore', {\r
39633 extend: Ext.Mixin,\r
39634 mixinConfig: {\r
39635 id: 'localstore'\r
39636 },\r
39637 config: {\r
39638 extraKeys: null\r
39639 },\r
39640 applyExtraKeys: function(extraKeys) {\r
39641 var indexName,\r
39642 data = this.getData();\r
39643
39644 data.setExtraKeys(extraKeys);\r
39645
39646 extraKeys = data.getExtraKeys();\r
39647 for (indexName in extraKeys) {\r
39648 this[indexName] = extraKeys[indexName];\r
39649 }\r
39650 },\r
39651 \r
39652 add: function(arg) {\r
39653 return this.insert(this.getCount(), arguments.length === 1 ? arg : arguments);\r
39654 },\r
39655 constructDataCollection: function() {\r
39656 return new Ext.util.Collection({\r
39657 rootProperty: 'data'\r
39658 });\r
39659 },\r
39660 \r
39661 createModel: function(record) {\r
39662 var session = this.getSession(),\r
39663 Model;\r
39664 if (!record.isModel) {\r
39665 Model = this.getModel();\r
39666 record = new Model(record, session);\r
39667 }\r
39668 return record;\r
39669 },\r
39670 createFiltersCollection: function() {\r
39671 return this.getData().getFilters();\r
39672 },\r
39673 createSortersCollection: function() {\r
39674 var sorters = this.getData().getSorters();\r
39675 sorters.setSorterConfigure(this.addFieldTransform, this);\r
39676 return sorters;\r
39677 },\r
39678
39679
39680 onCollectionSort: function() {\r
39681 this.onSorterEndUpdate();\r
39682 },\r
39683
39684
39685 onCollectionFilter: function() {\r
39686 this.onFilterEndUpdate();\r
39687 },\r
39688 notifySorterChange: function() {\r
39689 this.getData().onSorterChange();\r
39690 },\r
39691 forceLocalSort: function() {\r
39692 this.getData().onSortChange();\r
39693 },\r
39694
39695 contains: function(record) {\r
39696 return this.indexOf(record) > -1;\r
39697 },\r
39698 \r
39699 each: function(fn, scope) {\r
39700 var data = this.data.items,\r
39701 len = data.length,\r
39702 record, i;\r
39703 for (i = 0; i < len; ++i) {\r
39704 record = data[i];\r
39705 if (fn.call(scope || record, record, i, len) === false) {\r
39706 break;\r
39707 }\r
39708 }\r
39709 },\r
39710 \r
39711 collect: function(dataIndex, allowNull, bypassFilter) {\r
39712 var me = this,\r
39713 data = me.getData();\r
39714 if (bypassFilter === true && data.filtered) {\r
39715 data = data.getSource();\r
39716 }\r
39717 return data.collect(dataIndex, 'data', allowNull);\r
39718 },\r
39719 \r
39720 getById: function(id) {\r
39721 var data = this.getData();\r
39722 if (data.filtered) {\r
39723 data = data.getSource();\r
39724 }\r
39725 return data.get(id) || null;\r
39726 },\r
39727 \r
39728 getByInternalId: function(internalId) {\r
39729 var data = this.getData(),\r
39730 keyCfg;\r
39731 if (data.filtered) {\r
39732 if (!data.$hasExtraKeys) {\r
39733 keyCfg = this.makeInternalKeyCfg();\r
39734 data.setExtraKeys(keyCfg);\r
39735 data.$hasExtraKeys = true;\r
39736 }\r
39737 data = data.getSource();\r
39738 }\r
39739 if (!data.$hasExtraKeys) {\r
39740 data.setExtraKeys(keyCfg || this.makeInternalKeyCfg());\r
39741 data.$hasExtraKeys = true;\r
39742 }\r
39743 return data.byInternalId.get(internalId) || null;\r
39744 },\r
39745 \r
39746 getDataSource: function() {\r
39747 var data = this.getData();\r
39748 return data.getSource() || data;\r
39749 },\r
39750 \r
39751 indexOf: function(record) {\r
39752 return this.getData().indexOf(record);\r
39753 },\r
39754 \r
39755 indexOfId: function(id) {\r
39756 return this.indexOf(this.getById(id));\r
39757 },\r
39758 \r
39759 insert: function(index, records) {\r
39760 var me = this,\r
39761 len, i;\r
39762 if (records) {\r
39763 if (!Ext.isIterable(records)) {\r
39764 records = [\r
39765 records\r
39766 ];\r
39767 } else {\r
39768 records = Ext.Array.clone(records);\r
39769 }\r
39770 len = records.length;\r
39771 }\r
39772 if (!len) {\r
39773 return [];\r
39774 }\r
39775 for (i = 0; i < len; ++i) {\r
39776 records[i] = me.createModel(records[i]);\r
39777 }\r
39778 me.getData().insert(index, records);\r
39779 return records;\r
39780 },\r
39781 \r
39782 queryBy: function(fn, scope) {\r
39783 var data = this.getData();\r
39784 return (data.getSource() || data).createFiltered(fn, scope);\r
39785 },\r
39786 \r
39787 query: function(property, value, anyMatch, caseSensitive, exactMatch) {\r
39788 var data = this.getData();\r
39789 return (data.getSource() || data).createFiltered(property, value, anyMatch, caseSensitive, exactMatch);\r
39790 },\r
39791 \r
39792 first: function(grouped) {\r
39793 return this.getData().first(grouped) || null;\r
39794 },\r
39795 \r
39796 last: function(grouped) {\r
39797 return this.getData().last(grouped) || null;\r
39798 },\r
39799 \r
39800 sum: function(field, grouped) {\r
39801 var data = this.getData();\r
39802 return (grouped && this.isGrouped()) ? data.sumByGroup(field) : data.sum(field);\r
39803 },\r
39804 \r
39805 count: function(grouped) {\r
39806 var data = this.getData();\r
39807 return (grouped && this.isGrouped()) ? data.countByGroup() : data.count();\r
39808 },\r
39809 \r
39810 min: function(field, grouped) {\r
39811 var data = this.getData();\r
39812 return (grouped && this.isGrouped()) ? data.minByGroup(field) : data.min(field);\r
39813 },\r
39814 \r
39815 max: function(field, grouped) {\r
39816 var data = this.getData();\r
39817 return (grouped && this.isGrouped()) ? data.maxByGroup(field) : data.max(field);\r
39818 },\r
39819 \r
39820 average: function(field, grouped) {\r
39821 var data = this.getData();\r
39822 return (grouped && this.isGrouped()) ? data.averageByGroup(field) : data.average(field);\r
39823 },\r
39824 \r
39825 aggregate: function(fn, scope, grouped, field) {\r
39826 var me = this,\r
39827 groups, len, out, group, i;\r
39828 if (grouped && me.isGrouped()) {\r
39829 groups = me.getGroups().items;\r
39830 len = groups.length;\r
39831 out = {};\r
39832 for (i = 0; i < len; ++i) {\r
39833 group = groups[i];\r
39834 out[group.getGroupKey()] = me.getAggregate(fn, scope || me, group.items, field);\r
39835 }\r
39836 return out;\r
39837 } else {\r
39838 return me.getAggregate(fn, scope, me.getData().items, field);\r
39839 }\r
39840 },\r
39841 getAggregate: function(fn, scope, records, field) {\r
39842 var values = [],\r
39843 len = records.length,\r
39844 i;\r
39845
39846 for (i = 0; i < len; ++i) {\r
39847 values[i] = records[i].get(field);\r
39848 }\r
39849 return fn.call(scope || this, records, values);\r
39850 },\r
39851 addObserver: function(observer) {\r
39852 var observers = this.observers;\r
39853 if (!observers) {\r
39854 this.observers = observers = new Ext.util.Collection();\r
39855 }\r
39856 observers.add(observer);\r
39857 },\r
39858 removeObserver: function(observer) {\r
39859 var observers = this.observers;\r
39860 if (observers) {\r
39861 observers.remove(observer);\r
39862 }\r
39863 },\r
39864 callObservers: function(action, args) {\r
39865 var observers = this.observers,\r
39866 len, items, i, methodName, item;\r
39867 if (observers) {\r
39868 items = observers.items;\r
39869 if (args) {\r
39870 args.unshift(this);\r
39871 } else {\r
39872 args = [\r
39873 this\r
39874 ];\r
39875 }\r
39876 for (i = 0 , len = items.length; i < len; ++i) {\r
39877 item = items[i];\r
39878 methodName = 'onSource' + action;\r
39879 if (item[methodName]) {\r
39880 item[methodName].apply(item, args);\r
39881 }\r
39882 }\r
39883 }\r
39884 },\r
39885 \r
39886 queryRecordsBy: function(fn, scope) {\r
39887 var data = this.getData(),\r
39888 matches = [],\r
39889 len, i, record;\r
39890 data = (data.getSource() || data).items;\r
39891 scope = scope || this;\r
39892 for (i = 0 , len = data.length; i < len; ++i) {\r
39893 record = data[i];\r
39894 if (fn.call(scope, record) === true) {\r
39895 matches.push(record);\r
39896 }\r
39897 }\r
39898 return matches;\r
39899 },\r
39900 \r
39901 queryRecords: function(field, value) {\r
39902 var data = this.getData(),\r
39903 matches = [],\r
39904 len, i, record;\r
39905 data = (data.getSource() || data).items;\r
39906 for (i = 0 , len = data.length; i < len; ++i) {\r
39907 record = data[i];\r
39908 if (record.get(field) === value) {\r
39909 matches.push(record);\r
39910 }\r
39911 }\r
39912 return matches;\r
39913 },\r
39914 privates: {\r
39915 isLast: function(record) {\r
39916 return record === this.last();\r
39917 },\r
39918 makeInternalKeyCfg: function() {\r
39919 return {\r
39920 byInternalId: {\r
39921 property: 'internalId',\r
39922 rootProperty: ''\r
39923 }\r
39924 };\r
39925 }\r
39926 }\r
39927});\r
39928\r
39929\r
39930Ext.define('Ext.data.proxy.Server', {\r
39931 extend: Ext.data.proxy.Proxy,\r
39932 alias: 'proxy.server',\r
39933 alternateClassName: 'Ext.data.ServerProxy',\r
39934 isRemote: true,\r
39935 config: {\r
39936 \r
39937 url: '',\r
39938 \r
39939 pageParam: 'page',\r
39940 \r
39941 startParam: 'start',\r
39942 \r
39943 limitParam: 'limit',\r
39944 \r
39945 groupParam: 'group',\r
39946 \r
39947 groupDirectionParam: 'groupDir',\r
39948 \r
39949 sortParam: 'sort',\r
39950 \r
39951 filterParam: 'filter',\r
39952 \r
39953 directionParam: 'dir',\r
39954 \r
39955 idParam: 'id',\r
39956 \r
39957 simpleSortMode: false,\r
39958 \r
39959 simpleGroupMode: false,\r
39960 \r
39961 noCache: true,\r
39962 \r
39963 cacheString: "_dc",\r
39964 \r
39965 timeout: 30000,\r
39966 \r
39967 api: {\r
39968 create: undefined,\r
39969 read: undefined,\r
39970 update: undefined,\r
39971 destroy: undefined\r
39972 },\r
39973 \r
39974 extraParams: {}\r
39975 },\r
39976 \r
39977
39978 create: function() {\r
39979 return this.doRequest.apply(this, arguments);\r
39980 },\r
39981 read: function() {\r
39982 return this.doRequest.apply(this, arguments);\r
39983 },\r
39984 update: function() {\r
39985 return this.doRequest.apply(this, arguments);\r
39986 },\r
39987 erase: function() {\r
39988 return this.doRequest.apply(this, arguments);\r
39989 },\r
39990 \r
39991 setExtraParam: function(name, value) {\r
39992 var extraParams = this.getExtraParams();\r
39993 extraParams[name] = value;\r
39994 this.fireEvent('extraparamschanged', extraParams);\r
39995 },\r
39996 updateExtraParams: function(newExtraParams, oldExtraParams) {\r
39997 this.fireEvent('extraparamschanged', newExtraParams);\r
39998 },\r
39999 \r
40000 buildRequest: function(operation) {\r
40001 var me = this,\r
40002 initialParams = Ext.apply({}, operation.getParams()),\r
40003
40004 params = Ext.applyIf(initialParams, me.getExtraParams() || {}),\r
40005 request, operationId, idParam;\r
40006
40007 Ext.applyIf(params, me.getParams(operation));\r
40008
40009
40010
40011 operationId = operation.getId();\r
40012 idParam = me.getIdParam();\r
40013 if (operationId !== undefined && params[idParam] === undefined) {\r
40014 params[idParam] = operationId;\r
40015 }\r
40016 request = new Ext.data.Request({\r
40017 params: params,\r
40018 action: operation.getAction(),\r
40019 records: operation.getRecords(),\r
40020 url: operation.getUrl(),\r
40021 operation: operation,\r
40022
40023
40024 proxy: me\r
40025 });\r
40026 request.setUrl(me.buildUrl(request));\r
40027 \r
40028 operation.setRequest(request);\r
40029 return request;\r
40030 },\r
40031 \r
40032 processResponse: function(success, operation, request, response) {\r
40033 var me = this,\r
40034 exception, reader, resultSet;\r
40035
40036
40037
40038
40039
40040
40041
40042 me.fireEvent('beginprocessresponse', me, response, operation);\r
40043 if (success === true) {\r
40044 reader = me.getReader();\r
40045 if (response.status === 204) {\r
40046 resultSet = reader.getNullResultSet();\r
40047 } else {\r
40048 resultSet = reader.read(me.extractResponseData(response), {\r
40049
40050 recordCreator: operation.getRecordCreator()\r
40051 });\r
40052 }\r
40053 operation.process(resultSet, request, response);\r
40054 exception = !operation.wasSuccessful();\r
40055 } else {\r
40056 me.setException(operation, response);\r
40057 exception = true;\r
40058 }\r
40059 if (exception) {\r
40060 me.fireEvent('exception', me, response, operation);\r
40061 }\r
40062 me.afterRequest(request, success);\r
40063
40064
40065
40066 me.fireEvent('endprocessresponse', me, response, operation);\r
40067 },\r
40068 \r
40069 setException: function(operation, response) {\r
40070 operation.setException({\r
40071 status: response.status,\r
40072 statusText: response.statusText,\r
40073 response: response\r
40074 });\r
40075 },\r
40076 \r
40077 extractResponseData: Ext.identityFn,\r
40078 \r
40079 applyEncoding: function(value) {\r
40080 return Ext.encode(value);\r
40081 },\r
40082 \r
40083 encodeSorters: function(sorters, preventArray) {\r
40084 var out = [],\r
40085 length = sorters.length,\r
40086 i;\r
40087 for (i = 0; i < length; i++) {\r
40088 out[i] = sorters[i].serialize();\r
40089 }\r
40090 return this.applyEncoding(preventArray ? out[0] : out);\r
40091 },\r
40092 \r
40093 encodeFilters: function(filters) {\r
40094 var out = [],\r
40095 length = filters.length,\r
40096 i, op;\r
40097 for (i = 0; i < length; i++) {\r
40098 out[i] = filters[i].serialize();\r
40099 }\r
40100 return this.applyEncoding(out);\r
40101 },\r
40102 \r
40103 getParams: function(operation) {\r
40104 if (!operation.isReadOperation) {\r
40105 return {};\r
40106 }\r
40107 var me = this,\r
40108 params = {},\r
40109 grouper = operation.getGrouper(),\r
40110 sorters = operation.getSorters(),\r
40111 filters = operation.getFilters(),\r
40112 page = operation.getPage(),\r
40113 start = operation.getStart(),\r
40114 limit = operation.getLimit(),\r
40115 simpleSortMode = me.getSimpleSortMode(),\r
40116 simpleGroupMode = me.getSimpleGroupMode(),\r
40117 pageParam = me.getPageParam(),\r
40118 startParam = me.getStartParam(),\r
40119 limitParam = me.getLimitParam(),\r
40120 groupParam = me.getGroupParam(),\r
40121 groupDirectionParam = me.getGroupDirectionParam(),\r
40122 sortParam = me.getSortParam(),\r
40123 filterParam = me.getFilterParam(),\r
40124 directionParam = me.getDirectionParam(),\r
40125 hasGroups, index;\r
40126 if (pageParam && page) {\r
40127 params[pageParam] = page;\r
40128 }\r
40129 if (startParam && (start || start === 0)) {\r
40130 params[startParam] = start;\r
40131 }\r
40132 if (limitParam && limit) {\r
40133 params[limitParam] = limit;\r
40134 }\r
40135 hasGroups = groupParam && grouper;\r
40136 if (hasGroups) {\r
40137
40138 if (simpleGroupMode) {\r
40139 params[groupParam] = grouper.getProperty();\r
40140 params[groupDirectionParam] = grouper.getDirection();\r
40141 } else {\r
40142 params[groupParam] = me.encodeSorters([\r
40143 grouper\r
40144 ], true);\r
40145 }\r
40146 }\r
40147 if (sortParam && sorters && sorters.length > 0) {\r
40148 if (simpleSortMode) {\r
40149 index = 0;\r
40150
40151 if (sorters.length > 1 && hasGroups) {\r
40152 index = 1;\r
40153 }\r
40154 params[sortParam] = sorters[index].getProperty();\r
40155 params[directionParam] = sorters[index].getDirection();\r
40156 } else {\r
40157 params[sortParam] = me.encodeSorters(sorters);\r
40158 }\r
40159 }\r
40160 if (filterParam && filters && filters.length > 0) {\r
40161 params[filterParam] = me.encodeFilters(filters);\r
40162 }\r
40163 return params;\r
40164 },\r
40165 \r
40166 buildUrl: function(request) {\r
40167 var me = this,\r
40168 url = me.getUrl(request);\r
40169
40170 if (!url) {\r
40171 Ext.raise("You are using a ServerProxy but have not supplied it with a url.");\r
40172 }\r
40173
40174 if (me.getNoCache()) {\r
40175 url = Ext.urlAppend(url, Ext.String.format("{0}={1}", me.getCacheString(), Ext.Date.now()));\r
40176 }\r
40177 return url;\r
40178 },\r
40179 \r
40180 getUrl: function(request) {\r
40181 var url;\r
40182 if (request) {\r
40183 url = request.getUrl() || this.getApi()[request.getAction()];\r
40184 }\r
40185 return url ? url : this.callParent();\r
40186 },\r
40187 \r
40188 doRequest: function(operation) {\r
40189
40190 Ext.raise("The doRequest function has not been implemented on your Ext.data.proxy.Server subclass. See src/data/ServerProxy.js for details");\r
40191 },\r
40192
40193 \r
40194 afterRequest: Ext.emptyFn,\r
40195 destroy: function() {\r
40196 this.callParent();\r
40197 Ext.destroy(this.getReader(), this.getWriter());\r
40198 this.reader = this.writer = null;\r
40199 }\r
40200});\r
40201\r
40202\r
40203Ext.define('Ext.data.proxy.Ajax', {\r
40204 extend: Ext.data.proxy.Server,\r
40205 alias: 'proxy.ajax',\r
40206 alternateClassName: [\r
40207 'Ext.data.HttpProxy',\r
40208 'Ext.data.AjaxProxy'\r
40209 ],\r
40210 isAjaxProxy: true,\r
40211
40212
40213
40214
40215 defaultActionMethods: {\r
40216 create: 'POST',\r
40217 read: 'GET',\r
40218 update: 'POST',\r
40219 destroy: 'POST'\r
40220 },\r
40221 config: {\r
40222 \r
40223 binary: false,\r
40224 \r
40225 headers: undefined,\r
40226 \r
40227 paramsAsJson: false,\r
40228 \r
40229 withCredentials: false,\r
40230 \r
40231 useDefaultXhrHeader: true,\r
40232 \r
40233 username: null,\r
40234 \r
40235 password: null,\r
40236 \r
40237 actionMethods: {\r
40238 create: 'POST',\r
40239 read: 'GET',\r
40240 update: 'POST',\r
40241 destroy: 'POST'\r
40242 }\r
40243 },\r
40244 doRequest: function(operation) {\r
40245 var me = this,\r
40246 writer = me.getWriter(),\r
40247 request = me.buildRequest(operation),\r
40248 method = me.getMethod(request),\r
40249 jsonData, params;\r
40250 if (writer && operation.allowWrite()) {\r
40251 request = writer.write(request);\r
40252 }\r
40253 request.setConfig({\r
40254 binary: me.getBinary(),\r
40255 headers: me.getHeaders(),\r
40256 timeout: me.getTimeout(),\r
40257 scope: me,\r
40258 callback: me.createRequestCallback(request, operation),\r
40259 method: method,\r
40260 useDefaultXhrHeader: me.getUseDefaultXhrHeader(),\r
40261 disableCaching: false\r
40262 });\r
40263
40264 if (method.toUpperCase() !== 'GET' && me.getParamsAsJson()) {\r
40265 params = request.getParams();\r
40266 if (params) {\r
40267 jsonData = request.getJsonData();\r
40268 if (jsonData) {\r
40269 jsonData = Ext.Object.merge({}, jsonData, params);\r
40270 } else {\r
40271 jsonData = params;\r
40272 }\r
40273 request.setJsonData(jsonData);\r
40274 request.setParams(undefined);\r
40275 }\r
40276 }\r
40277 if (me.getWithCredentials()) {\r
40278 request.setWithCredentials(true);\r
40279 request.setUsername(me.getUsername());\r
40280 request.setPassword(me.getPassword());\r
40281 }\r
40282 return me.sendRequest(request);\r
40283 },\r
40284 \r
40285 sendRequest: function(request) {\r
40286 request.setRawRequest(Ext.Ajax.request(request.getCurrentConfig()));\r
40287 this.lastRequest = request;\r
40288 return request;\r
40289 },\r
40290 \r
40291 abort: function(request) {\r
40292 request = request || this.lastRequest;\r
40293 if (request) {\r
40294 Ext.Ajax.abort(request.getRawRequest());\r
40295 }\r
40296 },\r
40297 \r
40298 getMethod: function(request) {\r
40299 var actions = this.getActionMethods(),\r
40300 action = request.getAction(),\r
40301 method;\r
40302 if (actions) {\r
40303 method = actions[action];\r
40304 }\r
40305 return method || this.defaultActionMethods[action];\r
40306 },\r
40307 \r
40308 createRequestCallback: function(request, operation) {\r
40309 var me = this;\r
40310 return function(options, success, response) {\r
40311 if (request === me.lastRequest) {\r
40312 me.lastRequest = null;\r
40313 }\r
40314 me.processResponse(success, operation, request, response);\r
40315 };\r
40316 },\r
40317 destroy: function() {\r
40318 this.lastRequest = null;\r
40319 this.callParent();\r
40320 }\r
40321});\r
40322\r
40323\r
40324Ext.define('Ext.data.reader.Json', {\r
40325 extend: Ext.data.reader.Reader,\r
40326 alternateClassName: 'Ext.data.JsonReader',\r
40327 alias: 'reader.json',\r
40328 config: {\r
40329 \r
40330 record: null,\r
40331 \r
40332 metaProperty: 'metaData',\r
40333 \r
40334 useSimpleAccessors: false,\r
40335 \r
40336 preserveRawData: false\r
40337 },\r
40338 updateRootProperty: function() {\r
40339 this.forceBuildExtractors();\r
40340 },\r
40341 updateMetaProperty: function() {\r
40342 this.forceBuildExtractors();\r
40343 },\r
40344 \r
40345 readRecords: function(data, readOptions, \r
40346 internalReadOptions) {\r
40347 var me = this,\r
40348 meta;\r
40349
40350 if (me.getMeta) {\r
40351 meta = me.getMeta(data);\r
40352 if (meta) {\r
40353 me.onMetaChange(meta);\r
40354 }\r
40355 } else if (data.metaData) {\r
40356 me.onMetaChange(data.metaData);\r
40357 }\r
40358 return me.callParent([\r
40359 data,\r
40360 readOptions,\r
40361 internalReadOptions\r
40362 ]);\r
40363 },\r
40364 getResponseData: function(response) {\r
40365 var error;\r
40366 try {\r
40367 return Ext.decode(response.responseText);\r
40368 } catch (ex) {\r
40369 error = this.createReadError(ex.message);\r
40370 Ext.Logger.warn('Unable to parse the JSON returned by the server');\r
40371 this.fireEvent('exception', this, response, error);\r
40372 return error;\r
40373 }\r
40374 },\r
40375 buildExtractors: function() {\r
40376 var me = this,\r
40377 metaProp, rootProp;\r
40378
40379 if (me.callParent(arguments)) {\r
40380 metaProp = me.getMetaProperty();\r
40381 rootProp = me.getRootProperty();\r
40382 if (rootProp) {\r
40383 me.getRoot = me.getAccessor(rootProp);\r
40384 } else {\r
40385 me.getRoot = Ext.identityFn;\r
40386 }\r
40387 if (metaProp) {\r
40388 me.getMeta = me.getAccessor(metaProp);\r
40389 }\r
40390 }\r
40391 },\r
40392 \r
40393 extractData: function(root, readOptions) {\r
40394 var recordName = this.getRecord(),\r
40395 data = [],\r
40396 length, i;\r
40397 if (recordName) {\r
40398 length = root.length;\r
40399 if (!length && Ext.isObject(root)) {\r
40400 length = 1;\r
40401 root = [\r
40402 root\r
40403 ];\r
40404 }\r
40405 for (i = 0; i < length; i++) {\r
40406 data[i] = root[i][recordName];\r
40407 }\r
40408 } else {\r
40409 data = root;\r
40410 }\r
40411 return this.callParent([\r
40412 data,\r
40413 readOptions\r
40414 ]);\r
40415 },\r
40416 getModelData: function(raw) {\r
40417 return this.getPreserveRawData() ? Ext.apply({}, raw) : raw;\r
40418 },\r
40419 \r
40420 createAccessor: (function() {\r
40421 var re = /[\[\.]/;\r
40422 return function(expr) {\r
40423 var me = this,\r
40424 simple = me.getUseSimpleAccessors(),\r
40425 operatorIndex, result, current, parts, part, inExpr, isDot, isLeft, isRight, special, c, i, bracketed, len;\r
40426 if (!(expr || expr === 0)) {\r
40427 return;\r
40428 }\r
40429 if (typeof expr === 'function') {\r
40430 return expr;\r
40431 }\r
40432 if (!simple) {\r
40433 operatorIndex = String(expr).search(re);\r
40434 }\r
40435 if (simple === true || operatorIndex < 0) {\r
40436 result = function(raw) {\r
40437 return raw[expr];\r
40438 };\r
40439 } else {\r
40440
40441
40442
40443 current = 'raw';\r
40444 parts = [];\r
40445 part = '';\r
40446 inExpr = 0;\r
40447 len = expr.length;\r
40448
40449
40450
40451 for (i = 0; i <= len; ++i) {\r
40452 c = expr[i];\r
40453 isDot = c === '.';\r
40454 isLeft = c === '[';\r
40455 isRight = c === ']';\r
40456 special = isDot || isLeft || isRight || !c;\r
40457
40458
40459
40460
40461
40462 if (!special || inExpr > 1 || (inExpr && !isRight)) {\r
40463 part += c;\r
40464 } else if (special) {\r
40465 bracketed = false;\r
40466 if (isLeft) {\r
40467 ++inExpr;\r
40468 } else if (isRight) {\r
40469 --inExpr;\r
40470 bracketed = true;\r
40471 }\r
40472 if (part) {\r
40473 if (bracketed) {\r
40474 part = '[' + part + ']';\r
40475 } else {\r
40476 part = '.' + part;\r
40477 }\r
40478 current += part;\r
40479
40480
40481
40482
40483 parts.push('' + current);\r
40484 part = '';\r
40485 }\r
40486 }\r
40487 }\r
40488 result = parts.join(' && ');\r
40489 result = Ext.functionFactory('raw', 'return ' + result);\r
40490 }\r
40491 return result;\r
40492 };\r
40493 }()),\r
40494 \r
40495 createFieldAccessor: function(field) {\r
40496
40497 var me = this,\r
40498 mapping = field.mapping,\r
40499 hasMap = mapping || mapping === 0,\r
40500 map = hasMap ? mapping : field.name;\r
40501 if (hasMap) {\r
40502 if (typeof map === 'function') {\r
40503 return function(raw) {\r
40504 return field.mapping(raw, me);\r
40505 };\r
40506 } else {\r
40507 return me.createAccessor(map);\r
40508 }\r
40509 }\r
40510 },\r
40511 getAccessorKey: function(prop) {\r
40512 var simple = this.getUseSimpleAccessors() ? 'simple' : '';\r
40513 return this.$className + simple + prop;\r
40514 },\r
40515 privates: {\r
40516 copyFrom: function(reader) {\r
40517 this.callParent([\r
40518 reader\r
40519 ]);\r
40520 this.getRoot = reader.getRoot;\r
40521 }\r
40522 }\r
40523});\r
40524\r
40525\r
40526Ext.define('Ext.data.writer.Json', {\r
40527 extend: Ext.data.writer.Writer,\r
40528 alternateClassName: 'Ext.data.JsonWriter',\r
40529 alias: 'writer.json',\r
40530 config: {\r
40531 \r
40532 rootProperty: undefined,\r
40533 \r
40534 encode: false,\r
40535 \r
40536 allowSingle: true,\r
40537 \r
40538 expandData: false\r
40539 },\r
40540
40541 constructor: function(config) {\r
40542 if (config && config.hasOwnProperty('root')) {\r
40543 config = Ext.apply({}, config);\r
40544 config.rootProperty = config.root;\r
40545 delete config.root;\r
40546 Ext.log.warn('Ext.data.writer.Json: Using the deprecated "root" configuration. Use "rootProperty" instead.');\r
40547 }\r
40548 this.callParent([\r
40549 config\r
40550 ]);\r
40551 },\r
40552
40553 \r
40554 getExpandedData: function(data) {\r
40555 var dataLength = data.length,\r
40556 i = 0,\r
40557 item, prop, nameParts, j, tempObj,\r
40558 toObject = function(name, value) {\r
40559 var o = {};\r
40560 o[name] = value;\r
40561 return o;\r
40562 };\r
40563 for (; i < dataLength; i++) {\r
40564 item = data[i];\r
40565 for (prop in item) {\r
40566 if (item.hasOwnProperty(prop)) {\r
40567
40568 nameParts = prop.split('.');\r
40569 j = nameParts.length - 1;\r
40570 if (j > 0) {\r
40571
40572
40573 tempObj = item[prop];\r
40574 for (; j > 0; j--) {\r
40575
40576
40577
40578 tempObj = toObject(nameParts[j], tempObj);\r
40579 }\r
40580
40581
40582
40583 item[nameParts[0]] = item[nameParts[0]] || {};\r
40584
40585
40586 Ext.Object.merge(item[nameParts[0]], tempObj);\r
40587
40588 delete item[prop];\r
40589 }\r
40590 }\r
40591 }\r
40592 }\r
40593 return data;\r
40594 },\r
40595 writeRecords: function(request, data) {\r
40596 var me = this,\r
40597 root = me.getRootProperty(),\r
40598 json, single, transform;\r
40599 if (me.getExpandData()) {\r
40600 data = me.getExpandedData(data);\r
40601 }\r
40602 if (me.getAllowSingle() && data.length === 1) {\r
40603
40604 data = data[0];\r
40605 single = true;\r
40606 }\r
40607 transform = this.getTransform();\r
40608 if (transform) {\r
40609 data = transform(data, request);\r
40610 }\r
40611 if (me.getEncode()) {\r
40612 if (root) {\r
40613
40614 request.setParam(root, Ext.encode(data));\r
40615 } else {\r
40616
40617 Ext.raise('Must specify a root when using encode');\r
40618 }\r
40619 }\r
40620
40621 else if (single || (data && data.length)) {\r
40622
40623 json = request.getJsonData() || {};\r
40624 if (root) {\r
40625 json[root] = data;\r
40626 } else {\r
40627 json = data;\r
40628 }\r
40629 request.setJsonData(json);\r
40630 }\r
40631 return request;\r
40632 }\r
40633});\r
40634\r
40635\r
40636Ext.define('Ext.util.Group', {\r
40637 extend: Ext.util.Collection,\r
40638 config: {\r
40639 groupKey: null\r
40640 },\r
40641
40642
40643
40644
40645 $endUpdatePriority: 2001\r
40646});\r
40647\r
40648\r
40649Ext.define('Ext.util.SorterCollection', {\r
40650 extend: Ext.util.Collection,\r
40651 isSorterCollection: true,\r
40652 \r
40653 $sortable: null,\r
40654 \r
40655 sortFn: null,\r
40656 config: {\r
40657 \r
40658 sorterOptionsFn: null,\r
40659 \r
40660 sorterOptionsScope: null\r
40661 },\r
40662 constructor: function(config) {\r
40663 var me = this;\r
40664 me.sortFn = Ext.util.Sorter.createComparator(me);\r
40665 me.callParent([\r
40666 config\r
40667 ]);\r
40668 me.setDecoder(me.decodeSorter);\r
40669 },\r
40670 addSort: function(property, direction, mode) {\r
40671 var me = this,\r
40672 count, index, limit, options, primary, sorter, sorters;\r
40673 if (!property) {\r
40674
40675 me.beginUpdate();\r
40676 me.endUpdate();\r
40677 } else {\r
40678 options = me.getOptions();\r
40679 if (property instanceof Array) {\r
40680 sorters = property;\r
40681 mode = direction;\r
40682 direction = null;\r
40683 } else if (Ext.isString(property)) {\r
40684 if (!(sorter = me.get(property))) {\r
40685 sorters = [\r
40686 {\r
40687 property: property,\r
40688 direction: direction || options.getDefaultSortDirection()\r
40689 }\r
40690 ];\r
40691 } else {\r
40692 sorters = [\r
40693 sorter\r
40694 ];\r
40695 }\r
40696 } else if (Ext.isFunction(property)) {\r
40697 sorters = [\r
40698 {\r
40699 sorterFn: property,\r
40700 direction: direction || options.getDefaultSortDirection()\r
40701 }\r
40702 ];\r
40703 } else {\r
40704
40705 if (!Ext.isObject(property)) {\r
40706 Ext.raise('Invalid sort descriptor: ' + property);\r
40707 }\r
40708
40709 sorters = [\r
40710 property\r
40711 ];\r
40712 mode = direction;\r
40713 direction = null;\r
40714 }\r
40715
40716 if (mode && !me._sortModes[mode]) {\r
40717 Ext.raise('Sort mode should be "multi", "append", "prepend" or "replace", not "' + mode + '"');\r
40718 }\r
40719
40720 mode = me._sortModes[mode || 'replace'];\r
40721 primary = me.getAt(0);\r
40722 count = me.length;\r
40723 index = mode.append ? count : 0;\r
40724
40725
40726 me.beginUpdate();\r
40727
40728
40729 me.splice(index, mode.replace ? count : 0, sorters);\r
40730 if (mode.multi) {\r
40731 count = me.length;\r
40732 limit = options.getMultiSortLimit();\r
40733 if (count > limit) {\r
40734 me.removeAt(limit, count);\r
40735 }\r
40736 }\r
40737
40738 if (sorter && direction) {\r
40739 sorter.setDirection(direction);\r
40740 } else if (index === 0 && primary && primary === me.getAt(0)) {\r
40741
40742
40743 primary.toggle();\r
40744 }\r
40745 me.endUpdate();\r
40746 }\r
40747 },\r
40748 clear: function() {\r
40749
40750
40751 this.beginUpdate();\r
40752 this.callParent();\r
40753 this.endUpdate(this.items);\r
40754 },\r
40755 \r
40756 getSortFn: function() {\r
40757 return this.sortFn;\r
40758 },\r
40759 \r
40760 getByProperty: function(prop) {\r
40761 var items = this.items,\r
40762 len = items.length,\r
40763 i, item;\r
40764 for (i = 0; i < len; ++i) {\r
40765 item = items[i];\r
40766 if (item.getProperty() === prop) {\r
40767 return item;\r
40768 }\r
40769 }\r
40770 return null;\r
40771 },\r
40772
40773
40774 _sortModes: {\r
40775 append: {\r
40776 append: 1\r
40777 },\r
40778 multi: {\r
40779 multi: 1\r
40780 },\r
40781 prepend: {\r
40782 prepend: 1\r
40783 },\r
40784 replace: {\r
40785 replace: 1\r
40786 }\r
40787 },\r
40788 decodeSorter: function(sorter, xclass) {\r
40789 var me = this,\r
40790 options = me.getOptions(),\r
40791 root = options.getRootProperty(),\r
40792 sorterOptionsFn = me.getSorterOptionsFn(),\r
40793 currentSorter, sorterConfig, type;\r
40794 if (sorter.isSorter) {\r
40795 if (!sorter.getRoot()) {\r
40796 sorter.setRoot(root);\r
40797 }\r
40798 } else {\r
40799 sorterConfig = {\r
40800 direction: options.getDefaultSortDirection(),\r
40801 root: root\r
40802 };\r
40803 type = typeof sorter;\r
40804
40805 if (type === 'string') {\r
40806 currentSorter = me.get(sorter);\r
40807 if (currentSorter) {\r
40808 return currentSorter;\r
40809 }\r
40810 sorterConfig.property = sorter;\r
40811 }\r
40812
40813 else if (type === 'function') {\r
40814 sorterConfig.sorterFn = sorter;\r
40815 } else
40816
40817 {\r
40818
40819
40820 if (!Ext.isObject(sorter)) {\r
40821 Ext.raise('Invalid sorter specified: ' + sorter);\r
40822 }\r
40823
40824 sorterConfig = Ext.apply(sorterConfig, sorter);\r
40825 if (sorterConfig.fn) {\r
40826 sorterConfig.sorterFn = sorterConfig.fn;\r
40827 delete sorterConfig.fn;\r
40828 }\r
40829 }\r
40830
40831 sorter = Ext.create(xclass || 'Ext.util.Sorter', sorterConfig);\r
40832 }\r
40833 if (sorterOptionsFn) {\r
40834 sorterOptionsFn.call(me.getSorterOptionsScope() || me, sorter);\r
40835 }\r
40836 return sorter;\r
40837 },\r
40838 setSorterConfigure: function(fn, scope) {\r
40839 this.setSorterOptionsFn(fn);\r
40840 this.setSorterOptionsScope(scope);\r
40841 },\r
40842 decodeRemoveItems: function(args, index) {\r
40843 var me = this,\r
40844 ret = (index === undefined) ? args : args[index];\r
40845 if (!ret || !ret.$cloned) {\r
40846 if (args.length > index + 1 || !Ext.isIterable(ret)) {\r
40847 ret = Ext.Array.slice(args, index);\r
40848 }\r
40849 var currentSorters = me.items,\r
40850 ln = ret.length,\r
40851 remove = [],\r
40852 i, item, n, sorter, type;\r
40853 for (i = 0; i < ln; i++) {\r
40854 sorter = ret[i];\r
40855 if (sorter && sorter.isSorter) {\r
40856 remove.push(sorter);\r
40857 } else {\r
40858 type = typeof sorter;\r
40859 if (type === 'string') {\r
40860 sorter = me.get(sorter);\r
40861 if (sorter) {\r
40862 remove.push(sorter);\r
40863 }\r
40864 } else if (type === 'function') {\r
40865 for (n = currentSorters.length; n-- > 0; ) {\r
40866 item = currentSorters[n];\r
40867 if (item.getSorterFn() === sorter) {\r
40868 remove.push(item);\r
40869 }\r
40870 }\r
40871 } else
40872 {\r
40873 Ext.raise('Invalid sorter specification: ' + sorter);\r
40874 }\r
40875 }\r
40876 }\r
40877
40878 ret = remove;\r
40879 ret.$cloned = true;\r
40880 }\r
40881 return ret;\r
40882 },\r
40883 getOptions: function() {\r
40884
40885
40886
40887
40888 return this.$sortable || this;\r
40889 }\r
40890});\r
40891\r
40892\r
40893Ext.define('Ext.util.FilterCollection', {\r
40894 extend: Ext.util.Collection,\r
40895 isFilterCollection: true,\r
40896 \r
40897 $filterable: null,\r
40898 \r
40899 filterFn: null,\r
40900 constructor: function(config) {\r
40901 var me = this;\r
40902
40903
40904 me.filterFn = Ext.util.Filter.createFilterFn(me);\r
40905 me.callParent([\r
40906 config\r
40907 ]);\r
40908 me.setDecoder(me.decodeFilter);\r
40909 },\r
40910 \r
40911 filterData: function(data) {\r
40912 return this.filtered ? Ext.Array.filter(data, this.filterFn) : data;\r
40913 },\r
40914 \r
40915 getFilterFn: function() {\r
40916 return this.filterFn;\r
40917 },\r
40918 isItemFiltered: function(item) {\r
40919 return !this.filterFn(item);\r
40920 },\r
40921
40922
40923 decodeFilter: function(filter) {\r
40924 var options = this.getOptions(),\r
40925 filterRoot = options.getRootProperty(),\r
40926 filterConfig;\r
40927 if (filter.isFilter) {\r
40928 if (!filter.getRoot()) {\r
40929 filter.setRoot(filterRoot);\r
40930 }\r
40931 } else {\r
40932 filterConfig = {\r
40933 root: filterRoot\r
40934 };\r
40935 if (Ext.isFunction(filter)) {\r
40936 filterConfig.filterFn = filter;\r
40937 } else
40938
40939 {\r
40940
40941
40942 if (!Ext.isObject(filter)) {\r
40943 Ext.raise('Invalid filter specified: ' + filter);\r
40944 }\r
40945
40946 filterConfig = Ext.apply(filterConfig, filter);\r
40947 if (filterConfig.fn) {\r
40948 filterConfig.filterFn = filterConfig.fn;\r
40949 delete filterConfig.fn;\r
40950 }\r
40951 if (Ext.util.Filter.isInvalid(filterConfig)) {\r
40952 return false;\r
40953 }\r
40954 }\r
40955 filter = new Ext.util.Filter(filterConfig);\r
40956 }\r
40957 return filter;\r
40958 },\r
40959 decodeRemoveItems: function(args, index) {\r
40960 var me = this,\r
40961 ret = (index === undefined) ? args : args[index];\r
40962 if (!ret.$cloned) {\r
40963 if (args.length > index + 1 || !Ext.isIterable(ret)) {\r
40964 ret = Ext.Array.slice(args, index);\r
40965 }\r
40966 var currentFilters = me.items,\r
40967 ln = ret.length,\r
40968 remove = [],\r
40969 filter, i, isFunction, isProp, isString, item, match, n, type;\r
40970 for (i = 0; i < ln; i++) {\r
40971 filter = ret[i];\r
40972 if (filter && filter.isFilter) {\r
40973 remove.push(filter);\r
40974 } else {\r
40975 type = typeof filter;\r
40976 isFunction = type === 'function';\r
40977 isProp = filter.property !== undefined && filter.value !== undefined;\r
40978 isString = type === 'string';\r
40979
40980 if (!isFunction && !isProp && !isString) {\r
40981 Ext.raise('Invalid filter specification: ' + filter);\r
40982 }\r
40983
40984 for (n = currentFilters.length; n-- > 0; ) {\r
40985 item = currentFilters[n];\r
40986 match = false;\r
40987 if (isString) {\r
40988 match = item.getProperty() === filter;\r
40989 } else if (isFunction) {\r
40990 match = item.getFilterFn() === filter;\r
40991 } else if (isProp) {\r
40992 match = item.getProperty() === filter.property && item.getValue() === filter.value;\r
40993 }\r
40994 if (match) {\r
40995 remove.push(item);\r
40996 }\r
40997 }\r
40998 }\r
40999 }\r
41000 ret = remove;\r
41001 ret.$cloned = true;\r
41002 }\r
41003 return ret;\r
41004 },\r
41005 getOptions: function() {\r
41006
41007
41008
41009
41010 return this.$filterable || this;\r
41011 }\r
41012});\r
41013\r
41014\r
41015Ext.define('Ext.util.GroupCollection', {\r
41016 extend: Ext.util.Collection,\r
41017 isGroupCollection: true,\r
41018 config: {\r
41019 grouper: null,\r
41020 itemRoot: null\r
41021 },\r
41022 observerPriority: -100,\r
41023
41024
41025 onCollectionAdd: function(source, details) {\r
41026 this.addItemsToGroups(source, details.items);\r
41027 },\r
41028 onCollectionBeforeItemChange: function(source, details) {\r
41029 this.changeDetails = details;\r
41030 },\r
41031 onCollectionBeginUpdate: function() {\r
41032 this.beginUpdate();\r
41033 },\r
41034 onCollectionEndUpdate: function() {\r
41035 this.endUpdate();\r
41036 },\r
41037 onCollectionItemChange: function(source, details) {\r
41038 var item = details.item;\r
41039
41040
41041
41042 if (!details.indexChanged) {\r
41043 this.syncItemGrouping(source, item, source.getKey(item), details.oldKey, details.oldIndex);\r
41044 }\r
41045 this.changeDetails = null;\r
41046 },\r
41047 onCollectionRefresh: function(source) {\r
41048 this.removeAll();\r
41049 this.addItemsToGroups(source, source.items);\r
41050 },\r
41051 onCollectionRemove: function(source, details) {\r
41052 var me = this,\r
41053 changeDetails = me.changeDetails,\r
41054 entries, entry, group, i, n, removeGroups, item;\r
41055 if (changeDetails) {\r
41056
41057
41058 item = changeDetails.item;\r
41059 group = me.findGroupForItem(item);\r
41060 entries = [];\r
41061 if (group) {\r
41062 entries.push({\r
41063 group: group,\r
41064 items: [\r
41065 item\r
41066 ]\r
41067 });\r
41068 }\r
41069 } else {\r
41070 entries = me.groupItems(source, details.items, false);\r
41071 }\r
41072 for (i = 0 , n = entries.length; i < n; ++i) {\r
41073 group = (entry = entries[i]).group;\r
41074 if (group) {\r
41075 group.remove(entry.items);\r
41076 if (!group.length) {\r
41077 (removeGroups || (removeGroups = [])).push(group);\r
41078 }\r
41079 }\r
41080 }\r
41081 if (removeGroups) {\r
41082 me.remove(removeGroups);\r
41083 }\r
41084 },\r
41085
41086
41087
41088 onCollectionSort: function(source) {\r
41089
41090 var me = this,\r
41091 sorters = source.getSorters(false),\r
41092 items, length, i, group;\r
41093 if (sorters) {\r
41094 items = me.items;\r
41095 length = me.length;\r
41096 for (i = 0; i < length; ++i) {\r
41097 group = items[i];\r
41098 if (group.getSorters() !== sorters) {\r
41099 group.setSorters(sorters);\r
41100 }\r
41101 }\r
41102 }\r
41103 },\r
41104 onCollectionUpdateKey: function(source, details) {\r
41105 var index = details.index,\r
41106 item = details.item;\r
41107 if (!details.indexChanged) {\r
41108 index = source.indexOf(item);\r
41109 this.syncItemGrouping(source, item, details.newKey, details.oldKey, index);\r
41110 }\r
41111 },\r
41112
41113
41114 addItemsToGroups: function(source, items) {\r
41115 this.groupItems(source, items, true);\r
41116 },\r
41117 groupItems: function(source, items, adding) {\r
41118 var me = this,\r
41119 byGroup = {},\r
41120 entries = [],\r
41121 grouper = source.getGrouper(),\r
41122 groupKeys = me.itemGroupKeys,\r
41123 entry, group, groupKey, i, item, itemKey, len, newGroups;\r
41124 for (i = 0 , len = items.length; i < len; ++i) {\r
41125 groupKey = grouper.getGroupString(item = items[i]);\r
41126 itemKey = source.getKey(item);\r
41127 if (adding) {\r
41128 (groupKeys || (me.itemGroupKeys = groupKeys = {}))[itemKey] = groupKey;\r
41129 } else if (groupKeys) {\r
41130 delete groupKeys[itemKey];\r
41131 }\r
41132 if (!(entry = byGroup[groupKey])) {\r
41133 if (!(group = me.getByKey(groupKey)) && adding) {\r
41134 (newGroups || (newGroups = [])).push(group = me.createGroup(source, groupKey));\r
41135 }\r
41136 entries.push(byGroup[groupKey] = entry = {\r
41137 group: group,\r
41138 items: []\r
41139 });\r
41140 }\r
41141 entry.items.push(item);\r
41142 }\r
41143 for (i = 0 , len = entries.length; i < len; ++i) {\r
41144 entry = entries[i];\r
41145 entry.group.add(entry.items);\r
41146 }\r
41147 if (newGroups) {\r
41148 me.add(newGroups);\r
41149 }\r
41150 return entries;\r
41151 },\r
41152 syncItemGrouping: function(source, item, itemKey, oldKey, itemIndex) {\r
41153 var me = this,\r
41154 itemGroupKeys = me.itemGroupKeys || (me.itemGroupKeys = {}),\r
41155 grouper = source.getGrouper(),\r
41156 groupKey = grouper.getGroupString(item),\r
41157 removeGroups = 0,\r
41158 index = -1,\r
41159 addGroups, group, oldGroup, oldGroupKey, firstIndex;\r
41160 if (oldKey) {\r
41161 oldGroupKey = itemGroupKeys[oldKey];\r
41162 delete itemGroupKeys[oldKey];\r
41163 } else {\r
41164 oldGroupKey = itemGroupKeys[itemKey];\r
41165 }\r
41166 itemGroupKeys[itemKey] = groupKey;\r
41167 if (!(group = me.get(groupKey))) {\r
41168 group = me.createGroup(source, groupKey);\r
41169 addGroups = [\r
41170 group\r
41171 ];\r
41172 }\r
41173
41174
41175 if (group.get(itemKey) !== item) {\r
41176 if (group.getCount() > 0 && source.getSorters().getCount() === 0) {\r
41177
41178
41179 firstIndex = source.indexOf(group.items[0]);\r
41180 if (itemIndex < firstIndex) {\r
41181 index = 0;\r
41182 } else {\r
41183 index = itemIndex - firstIndex;\r
41184 }\r
41185 }\r
41186 if (index === -1) {\r
41187 group.add(item);\r
41188 } else {\r
41189 group.insert(index, item);\r
41190 }\r
41191 } else {\r
41192 group.itemChanged(item);\r
41193 }\r
41194 if (groupKey !== oldGroupKey && (oldGroupKey === 0 || oldGroupKey)) {\r
41195 oldGroup = me.get(oldGroupKey);\r
41196 if (oldGroup) {\r
41197 oldGroup.remove(item);\r
41198 if (!oldGroup.length) {\r
41199 removeGroups = [\r
41200 oldGroup\r
41201 ];\r
41202 }\r
41203 }\r
41204 }\r
41205 if (addGroups) {\r
41206 me.splice(0, removeGroups, addGroups);\r
41207 } else if (removeGroups) {\r
41208 me.splice(0, removeGroups);\r
41209 }\r
41210 },\r
41211 createGroup: function(source, key) {\r
41212 var group = new Ext.util.Group({\r
41213 groupKey: key,\r
41214 rootProperty: this.getItemRoot(),\r
41215 sorters: source.getSorters()\r
41216 });\r
41217 return group;\r
41218 },\r
41219 getKey: function(item) {\r
41220 return item.getGroupKey();\r
41221 },\r
41222 createSortFn: function() {\r
41223 var me = this,\r
41224 grouper = me.getGrouper(),\r
41225 sorterFn = me.getSorters().getSortFn();\r
41226 if (!grouper) {\r
41227 return sorterFn;\r
41228 }\r
41229 return function(lhs, rhs) {\r
41230
41231
41232
41233 return grouper.sort(lhs.items[0], rhs.items[0]) || sorterFn(lhs, rhs);\r
41234 };\r
41235 },\r
41236 updateGrouper: function(grouper) {\r
41237 var me = this;\r
41238 me.grouped = !!(grouper && me.$groupable.getAutoGroup());\r
41239 me.onSorterChange();\r
41240 me.onEndUpdateSorters(me.getSorters());\r
41241 },\r
41242 destroy: function() {\r
41243 this.$groupable = null;\r
41244 this.callParent();\r
41245 },\r
41246 privates: {\r
41247 findGroupForItem: function(item) {\r
41248 var items = this.items,\r
41249 len = items.length,\r
41250 i, group;\r
41251 for (i = 0; i < len; ++i) {\r
41252 group = items[i];\r
41253 if (group.contains(item)) {\r
41254 return group;\r
41255 }\r
41256 }\r
41257 }\r
41258 }\r
41259});\r
41260\r
41261\r
41262Ext.define('Ext.data.Store', {\r
41263 extend: Ext.data.ProxyStore,\r
41264 alias: 'store.store',\r
41265 mixins: [\r
41266 Ext.data.LocalStore\r
41267 ],\r
41268 config: {\r
41269 \r
41270 data: 0,\r
41271
41272 \r
41273 clearRemovedOnLoad: true,\r
41274 \r
41275 clearOnPageLoad: true,\r
41276 \r
41277 associatedEntity: null,\r
41278 \r
41279 role: null,\r
41280 \r
41281 session: null\r
41282 },\r
41283 \r
41284 \r
41285 addRecordsOptions: {\r
41286 addRecords: true\r
41287 },\r
41288 \r
41289 loadCount: 0,\r
41290 \r
41291 complete: false,\r
41292 moveMapCount: 0,\r
41293 \r
41294 constructor: function(config) {\r
41295 var me = this,\r
41296 data;\r
41297 if (config) {\r
41298 if (config.buffered) {\r
41299
41300 if (this.self !== Ext.data.Store) {\r
41301 Ext.raise('buffered config not supported on derived Store classes. ' + 'Please derive from Ext.data.BufferedStore.');\r
41302 }\r
41303
41304 return new Ext.data.BufferedStore(config);\r
41305 }\r
41306
41307 if (config.remoteGroup) {\r
41308 Ext.log.warn('Ext.data.Store: remoteGroup has been removed. Use remoteSort instead.');\r
41309 }\r
41310 }\r
41311
41312 \r
41313 \r
41314 \r
41315 \r
41316 me.callParent([\r
41317 config\r
41318 ]);\r
41319 me.getData().addObserver(me);\r
41320
41321 data = me.inlineData;\r
41322 if (data) {\r
41323 delete me.inlineData;\r
41324 me.loadInlineData(data);\r
41325 }\r
41326 },\r
41327 \r
41328 \r
41329 onCollectionBeginUpdate: function() {\r
41330 this.beginUpdate();\r
41331 },\r
41332 onCollectionEndUpdate: function() {\r
41333 this.endUpdate();\r
41334 },\r
41335 applyData: function(data, dataCollection) {\r
41336
41337
41338
41339 var me = this;\r
41340
41341 me.getFields();\r
41342 me.getModel();\r
41343
41344 if (data && data.isCollection) {\r
41345 dataCollection = data;\r
41346 } else {\r
41347 if (!dataCollection) {\r
41348 dataCollection = me.constructDataCollection();\r
41349 }\r
41350 if (data) {\r
41351 if (me.isInitializing) {\r
41352
41353
41354
41355
41356
41357
41358
41359
41360 me.inlineData = data;\r
41361 } else {\r
41362
41363
41364 me.loadData(data);\r
41365 }\r
41366 }\r
41367 }\r
41368 return dataCollection;\r
41369 },\r
41370 loadInlineData: function(data) {\r
41371 var me = this,\r
41372 proxy = me.getProxy();\r
41373 if (proxy && proxy.isMemoryProxy) {\r
41374 proxy.setData(data);\r
41375
41376 me.suspendEvents();\r
41377 me.read();\r
41378 me.resumeEvents();\r
41379 } else {\r
41380
41381 me.removeAll(true);\r
41382
41383
41384
41385 me.suspendEvents();\r
41386 me.loadData(data);\r
41387 me.resumeEvents();\r
41388 }\r
41389 },\r
41390 \r
41391 onCollectionAdd: function(collection, info) {\r
41392 this.onCollectionAddItems(collection, info.items, info);\r
41393 },\r
41394 onCollectionFilterAdd: function(collection, items) {\r
41395 this.onCollectionAddItems(collection, items);\r
41396 },\r
41397 onCollectionAddItems: function(collection, records, info) {\r
41398 var me = this,\r
41399 len = records.length,\r
41400 lastChunk = info ? !info.next : false,\r
41401
41402
41403
41404
41405 removed = me.removed,\r
41406 ignoreAdd = me.ignoreCollectionAdd,\r
41407 session = me.getSession(),\r
41408 replaced = info && info.replaced,\r
41409 i, sync, record, replacedItems;\r
41410 for (i = 0; i < len; ++i) {\r
41411 record = records[i];\r
41412 if (session) {\r
41413 session.adopt(record);\r
41414 }\r
41415
41416
41417 if (!ignoreAdd) {\r
41418 record.join(me);\r
41419 if (removed && removed.length) {\r
41420 Ext.Array.remove(removed, record);\r
41421 }\r
41422 sync = sync || record.phantom || record.dirty;\r
41423 }\r
41424 }\r
41425 if (ignoreAdd) {\r
41426 return;\r
41427 }\r
41428 if (replaced) {\r
41429 replacedItems = [];\r
41430 do {\r
41431 Ext.Array.push(replacedItems, replaced.items);\r
41432 replaced = replaced.next;\r
41433 } while (replaced);\r
41434 me.setMoving(replacedItems, true);\r
41435 }\r
41436 if (info) {\r
41437
41438
41439
41440
41441 if (info.replaced) {\r
41442 if (lastChunk) {\r
41443 me.fireEvent('refresh', me);\r
41444 }\r
41445 } else {\r
41446 me.fireEvent('add', me, records, info.at);\r
41447
41448
41449
41450 if (lastChunk) {\r
41451 me.fireEvent('datachanged', me);\r
41452 }\r
41453 }\r
41454 }\r
41455 if (replacedItems) {\r
41456 me.setMoving(replacedItems, false);\r
41457 }\r
41458
41459 me.needsSync = me.needsSync || sync;\r
41460 },\r
41461
41462 onCollectionFilteredItemChange: function() {\r
41463 this.onCollectionItemChange.apply(this, arguments);\r
41464 },\r
41465 onCollectionItemChange: function(collection, info) {\r
41466 var me = this,\r
41467 record = info.item,\r
41468 modifiedFieldNames = info.modified || null,\r
41469 type = info.meta;\r
41470 if (me.fireChangeEvent(record)) {\r
41471
41472
41473
41474 me.onUpdate(record, type, modifiedFieldNames, info);\r
41475 me.fireEvent('update', me, record, type, modifiedFieldNames, info);\r
41476 }\r
41477 },\r
41478 fireChangeEvent: function(record) {\r
41479 return this.getDataSource().contains(record);\r
41480 },\r
41481 afterChange: function(record, modifiedFieldNames, type) {\r
41482 this.getData().itemChanged(record, modifiedFieldNames || null, undefined, type);\r
41483 },\r
41484 afterCommit: function(record, modifiedFieldNames) {\r
41485 this.afterChange(record, modifiedFieldNames, Ext.data.Model.COMMIT);\r
41486 },\r
41487 afterEdit: function(record, modifiedFieldNames) {\r
41488 this.needsSync = this.needsSync || record.dirty;\r
41489 this.afterChange(record, modifiedFieldNames, Ext.data.Model.EDIT);\r
41490 },\r
41491 afterReject: function(record) {\r
41492 this.afterChange(record, null, Ext.data.Model.REJECT);\r
41493 },\r
41494 afterDrop: function(record) {\r
41495 this.getData().remove(record);\r
41496 },\r
41497 afterErase: function(record) {\r
41498 this.removeFromRemoved(record);\r
41499 },\r
41500 \r
41501 \r
41502 addSorted: function(record) {\r
41503 var me = this,\r
41504 remote = me.getRemoteSort(),\r
41505 data = me.getData(),\r
41506 index;\r
41507 if (remote) {\r
41508 data.setSorters(me.getSorters());\r
41509 }\r
41510 index = data.findInsertionIndex(record);\r
41511 if (remote) {\r
41512 data.setSorters(null);\r
41513 }\r
41514 return me.insert(index, record);\r
41515 },\r
41516 \r
41517 remove: function(records, \r
41518 isMove, silent) {\r
41519 var me = this,\r
41520 data = me.getDataSource(),\r
41521 len, i, toRemove, record;\r
41522 if (records) {\r
41523 if (records.isModel) {\r
41524 if (data.indexOf(records) > -1) {\r
41525 toRemove = [\r
41526 records\r
41527 ];\r
41528 len = 1;\r
41529 } else {\r
41530 len = 0;\r
41531 }\r
41532 } else {\r
41533 toRemove = [];\r
41534 for (i = 0 , len = records.length; i < len; ++i) {\r
41535 record = records[i];\r
41536 if (record && record.isEntity) {\r
41537 if (!data.contains(record)) {\r
41538 \r
41539 continue;\r
41540 }\r
41541 } else if (!(record = data.getAt(record))) {\r
41542
41543 \r
41544 continue;\r
41545 }\r
41546 toRemove.push(record);\r
41547 }\r
41548 len = toRemove.length;\r
41549 }\r
41550 }\r
41551 if (!len) {\r
41552 return [];\r
41553 }\r
41554 me.removeIsMove = isMove === true;\r
41555 me.removeIsSilent = silent;\r
41556 data.remove(toRemove);\r
41557 me.removeIsSilent = false;\r
41558 return toRemove;\r
41559 },\r
41560 onCollectionRemove: function(collection, info) {\r
41561 var me = this,\r
41562
41563
41564
41565
41566 removed = me.removed,\r
41567 records = info.items,\r
41568 len = records.length,\r
41569 index = info.at,\r
41570 replacement = info.replacement,\r
41571 isMove = me.removeIsMove || (replacement && Ext.Array.equals(records, replacement.items)),\r
41572 silent = me.removeIsSilent,\r
41573 lastChunk = !info.next,\r
41574 data = me.getDataSource(),\r
41575 i, record;\r
41576 if (me.ignoreCollectionRemove) {\r
41577 return;\r
41578 }\r
41579 if (replacement) {\r
41580 me.setMoving(replacement.items, true);\r
41581 }\r
41582 for (i = 0; i < len; ++i) {\r
41583 record = records[i];\r
41584
41585
41586 if (!data.contains(record)) {\r
41587
41588
41589 if (removed && !isMove && !record.phantom && !record.erasing) {\r
41590
41591
41592 record.removedFrom = index + i;\r
41593 removed.push(record);\r
41594
41595
41596 me.needsSync = true;\r
41597 } else {\r
41598
41599
41600 record.unjoin(me);\r
41601 }\r
41602 }\r
41603 }\r
41604 if (!silent) {\r
41605
41606
41607
41608
41609
41610
41611
41612
41613
41614 if (!replacement || !replacement.items.length) {\r
41615 me.fireEvent('remove', me, records, index, isMove);\r
41616
41617
41618
41619 if (lastChunk) {\r
41620 me.fireEvent('datachanged', me);\r
41621 }\r
41622 }\r
41623 }\r
41624 if (replacement) {\r
41625 me.setMoving(replacement.items, false);\r
41626 }\r
41627 },\r
41628 onFilterEndUpdate: function() {\r
41629 this.callParent(arguments);\r
41630 this.callObservers('Filter');\r
41631 },\r
41632 \r
41633 removeAt: function(index, count) {\r
41634 var data = this.getData();\r
41635
41636 index = Math.max(index, 0);\r
41637 if (index < data.length) {\r
41638 if (arguments.length === 1) {\r
41639 count = 1;\r
41640 } else if (!count) {\r
41641 return;\r
41642 }\r
41643 data.removeAt(index, count);\r
41644 }\r
41645 },\r
41646 \r
41647 removeAll: function(silent) {\r
41648 var me = this,\r
41649 data = me.getData(),\r
41650 hasClear = me.hasListeners.clear,\r
41651 records = data.getRange();\r
41652
41653 if (data.length) {\r
41654
41655 me.removeIsSilent = true;\r
41656 me.callObservers('BeforeRemoveAll');\r
41657 data.removeAll();\r
41658 me.removeIsSilent = false;\r
41659 if (!silent) {\r
41660 me.fireEvent('clear', me, records);\r
41661 me.fireEvent('datachanged', me);\r
41662 }\r
41663 me.callObservers('AfterRemoveAll', [\r
41664 !!silent\r
41665 ]);\r
41666 }\r
41667 return records;\r
41668 },\r
41669 \r
41670 setRecords: function(records) {\r
41671 var count = this.getCount();\r
41672 ++this.loadCount;\r
41673 if (count) {\r
41674 this.getData().splice(0, count, records);\r
41675 } else {\r
41676 this.add(records);\r
41677 }\r
41678 },\r
41679 \r
41680 splice: function(index, toRemove, toAdd) {\r
41681 return this.getData().splice(index, toRemove, toAdd);\r
41682 },\r
41683 \r
41684 onProxyLoad: function(operation) {\r
41685 var me = this,\r
41686 resultSet = operation.getResultSet(),\r
41687 records = operation.getRecords(),\r
41688 successful = operation.wasSuccessful();\r
41689 if (me.destroyed) {\r
41690 return;\r
41691 }\r
41692 if (resultSet) {\r
41693 me.totalCount = resultSet.getTotal();\r
41694 }\r
41695 if (successful) {\r
41696 records = me.processAssociation(records);\r
41697 me.loadRecords(records, operation.getAddRecords() ? {\r
41698 addRecords: true\r
41699 } : undefined);\r
41700 } else {\r
41701 me.loading = false;\r
41702 }\r
41703 if (me.hasListeners.load) {\r
41704 me.fireEvent('load', me, records, successful, operation);\r
41705 }\r
41706 me.callObservers('AfterLoad', [\r
41707 records,\r
41708 successful,\r
41709 operation\r
41710 ]);\r
41711 },\r
41712
41713 filterDataSource: function(fn) {\r
41714 var source = this.getDataSource(),\r
41715 items = source.items,\r
41716 len = items.length,\r
41717 ret = [],\r
41718 i;\r
41719 for (i = 0; i < len; i++) {\r
41720 if (fn.call(source, items[i])) {\r
41721 ret.push(items[i]);\r
41722 }\r
41723 }\r
41724 return ret;\r
41725 },\r
41726 getNewRecords: function() {\r
41727 return this.filterDataSource(this.filterNew);\r
41728 },\r
41729 getRejectRecords: function() {\r
41730 return this.filterDataSource(this.filterRejects);\r
41731 },\r
41732 getUpdatedRecords: function() {\r
41733 return this.filterDataSource(this.filterUpdated);\r
41734 },\r
41735 \r
41736 loadData: function(data, append) {\r
41737 var me = this,\r
41738 length = data.length,\r
41739 newData = [],\r
41740 i;\r
41741
41742 for (i = 0; i < length; i++) {\r
41743 newData.push(me.createModel(data[i]));\r
41744 }\r
41745 newData = me.processAssociation(newData);\r
41746 me.loadRecords(newData, append ? me.addRecordsOptions : undefined);\r
41747 },\r
41748 \r
41749 loadRawData: function(data, append) {\r
41750 var me = this,\r
41751 session = me.getSession(),\r
41752 result = me.getProxy().getReader().read(data, session ? {\r
41753 recordCreator: session.recordCreator\r
41754 } : undefined),\r
41755 records = result.getRecords(),\r
41756 success = result.getSuccess();\r
41757 if (success) {\r
41758 me.totalCount = result.getTotal();\r
41759 me.loadRecords(records, append ? me.addRecordsOptions : undefined);\r
41760 }\r
41761 return success;\r
41762 },\r
41763 \r
41764 loadRecords: function(records, options) {\r
41765 var me = this,\r
41766 length = records.length,\r
41767 data = me.getData(),\r
41768 addRecords, i, skipSort;\r
41769 if (options) {\r
41770 addRecords = options.addRecords;\r
41771 }\r
41772 if (!me.getRemoteSort() && !me.getSortOnLoad()) {\r
41773 skipSort = true;\r
41774 data.setAutoSort(false);\r
41775 }\r
41776 if (!addRecords) {\r
41777 me.clearData(true);\r
41778 }\r
41779
41780
41781 me.loading = false;\r
41782 me.ignoreCollectionAdd = true;\r
41783 me.callObservers('BeforePopulate');\r
41784 data.add(records);\r
41785 me.ignoreCollectionAdd = false;\r
41786 if (skipSort) {\r
41787 data.setAutoSort(true);\r
41788 }\r
41789 for (i = 0; i < length; i++) {\r
41790 records[i].join(me);\r
41791 }\r
41792 ++me.loadCount;\r
41793 me.complete = true;\r
41794 me.fireEvent('datachanged', me);\r
41795 me.fireEvent('refresh', me);\r
41796 me.callObservers('AfterPopulate');\r
41797 },\r
41798
41799 \r
41800 loadPage: function(page, options) {\r
41801 var me = this,\r
41802 size = me.getPageSize();\r
41803 me.currentPage = page;\r
41804
41805 options = Ext.apply({\r
41806 page: page,\r
41807 start: (page - 1) * size,\r
41808 limit: size,\r
41809 addRecords: !me.getClearOnPageLoad()\r
41810 }, options);\r
41811 me.read(options);\r
41812 },\r
41813 \r
41814 nextPage: function(options) {\r
41815 this.loadPage(this.currentPage + 1, options);\r
41816 },\r
41817 \r
41818 previousPage: function(options) {\r
41819 this.loadPage(this.currentPage - 1, options);\r
41820 },\r
41821 \r
41822 clearData: function(isLoad) {\r
41823 var me = this,\r
41824 removed = me.removed,\r
41825 data = me.getDataSource(),\r
41826 clearRemovedOnLoad = me.getClearRemovedOnLoad(),\r
41827 needsUnjoinCheck = removed && isLoad && !clearRemovedOnLoad,\r
41828 records, record, i, len;\r
41829
41830
41831
41832
41833
41834 if (data) {\r
41835 records = data.items;\r
41836 for (i = 0 , len = records.length; i < len; ++i) {\r
41837 record = records[i];\r
41838 if (needsUnjoinCheck && Ext.Array.contains(removed, record)) {\r
41839 \r
41840 continue;\r
41841 }\r
41842 record.unjoin(me);\r
41843 }\r
41844 me.ignoreCollectionRemove = true;\r
41845 me.callObservers('BeforeClear');\r
41846 data.removeAll();\r
41847 me.ignoreCollectionRemove = false;\r
41848 me.callObservers('AfterClear');\r
41849 }\r
41850 if (removed && (!isLoad || clearRemovedOnLoad)) {\r
41851 removed.length = 0;\r
41852 }\r
41853 },\r
41854 onIdChanged: function(rec, oldId, newId) {\r
41855 this.getData().updateKey(rec, oldId);\r
41856
41857 this.fireEvent('idchanged', this, rec, oldId, newId);\r
41858 },\r
41859 \r
41860 commitChanges: function() {\r
41861 var me = this,\r
41862 recs = me.getModifiedRecords(),\r
41863 len = recs.length,\r
41864 i = 0;\r
41865 Ext.suspendLayouts();\r
41866 me.beginUpdate();\r
41867 for (; i < len; i++) {\r
41868 recs[i].commit();\r
41869 }\r
41870 me.cleanRemoved();\r
41871 me.endUpdate();\r
41872 Ext.resumeLayouts(true);\r
41873 },\r
41874 filterNewOnly: function(item) {\r
41875 return item.phantom === true;\r
41876 },\r
41877 filterRejects: function(item) {\r
41878 return item.phantom || item.dirty;\r
41879 },\r
41880 \r
41881 rejectChanges: function() {\r
41882 var me = this,\r
41883 recs = me.getRejectRecords(),\r
41884 len = recs.length,\r
41885 i, rec, toRemove, sorted, data, currentAutoSort;\r
41886 Ext.suspendLayouts();\r
41887 me.beginUpdate();\r
41888 for (i = 0; i < len; i++) {\r
41889 rec = recs[i];\r
41890 if (rec.phantom) {\r
41891 toRemove = toRemove || [];\r
41892 toRemove.push(rec);\r
41893 } else {\r
41894 rec.reject();\r
41895 }\r
41896 }\r
41897 if (toRemove) {\r
41898 me.remove(toRemove);\r
41899 for (i = 0 , len = toRemove.length; i < len; ++i) {\r
41900 toRemove[i].reject();\r
41901 }\r
41902 }\r
41903
41904 recs = me.getRawRemovedRecords();\r
41905 if (recs) {\r
41906 len = recs.length;\r
41907 sorted = !me.getRemoteSort() && me.isSorted();\r
41908 if (sorted) {\r
41909
41910
41911 data = me.getData();\r
41912 currentAutoSort = data.getAutoSort();\r
41913 data.setAutoSort(false);\r
41914 }\r
41915 for (i = len - 1; i >= 0; i--) {\r
41916 rec = recs[i];\r
41917 rec.reject();\r
41918 if (!sorted) {\r
41919 me.insert(rec.removedFrom || 0, rec);\r
41920 }\r
41921 }\r
41922 if (sorted) {\r
41923
41924 data.setAutoSort(currentAutoSort);\r
41925 me.add(recs);\r
41926 }\r
41927
41928
41929 recs.length = 0;\r
41930 }\r
41931 me.endUpdate();\r
41932 Ext.resumeLayouts(true);\r
41933 },\r
41934 onDestroy: function() {\r
41935 var me = this,\r
41936 task = me.loadTask,\r
41937 data = me.getData(),\r
41938 source = data.getSource();\r
41939
41940 me.clearData();\r
41941 me.callParent();\r
41942 me.setSession(null);\r
41943 me.observers = null;\r
41944 if (task) {\r
41945 task.cancel();\r
41946 me.loadTask = null;\r
41947 }\r
41948 if (source) {\r
41949 source.destroy();\r
41950 }\r
41951 },\r
41952 privates: {\r
41953 \r
41954 fetch: function(options) {\r
41955 options = Ext.apply({}, options);\r
41956 this.setLoadOptions(options);\r
41957 var operation = this.createOperation('read', options);\r
41958 operation.execute();\r
41959 },\r
41960 onBeforeLoad: function(operation) {\r
41961 this.callObservers('BeforeLoad', [\r
41962 operation\r
41963 ]);\r
41964 },\r
41965 onRemoteFilterSet: function(filters, remoteFilter) {\r
41966 if (filters) {\r
41967 this.getData().setFilters(remoteFilter ? null : filters);\r
41968 }\r
41969 this.callParent([\r
41970 filters,\r
41971 remoteFilter\r
41972 ]);\r
41973 },\r
41974 onRemoteSortSet: function(sorters, remoteSort) {\r
41975 var data = this.getData();\r
41976 if (sorters) {\r
41977 data.setSorters(remoteSort ? null : sorters);\r
41978 }\r
41979 data.setAutoGroup(!remoteSort);\r
41980 this.callParent([\r
41981 sorters,\r
41982 remoteSort\r
41983 ]);\r
41984 },\r
41985 \r
41986 isMoving: function(records, getMap) {\r
41987 var map = this.moveMap,\r
41988 moving = 0,\r
41989 len, i;\r
41990 if (map) {\r
41991 if (records) {\r
41992 if (Ext.isArray(records)) {\r
41993 for (i = 0 , len = records.length; i < len; ++i) {\r
41994 moving += map[records[i].id] ? 1 : 0;\r
41995 }\r
41996 } else if (map[records.id]) {\r
41997 ++moving;\r
41998 }\r
41999 } else {\r
42000 moving = getMap ? map : this.moveMapCount;\r
42001 }\r
42002 }\r
42003 return moving;\r
42004 },\r
42005 setLoadOptions: function(options) {\r
42006
42007 var me = this,\r
42008 pageSize = me.getPageSize(),\r
42009 session, grouper;\r
42010 if (me.getRemoteSort() && !options.grouper) {\r
42011 grouper = me.getGrouper();\r
42012 if (grouper) {\r
42013 options.grouper = grouper;\r
42014 }\r
42015 }\r
42016 if (pageSize || 'start' in options || 'limit' in options || 'page' in options) {\r
42017 options.page = options.page != null ? options.page : me.currentPage;\r
42018 options.start = (options.start !== undefined) ? options.start : (options.page - 1) * pageSize;\r
42019 options.limit = options.limit != null ? options.limit : pageSize;\r
42020 me.currentPage = options.page;\r
42021 }\r
42022 options.addRecords = options.addRecords || false;\r
42023 if (!options.recordCreator) {\r
42024 session = me.getSession();\r
42025 if (session) {\r
42026 options.recordCreator = session.recordCreator;\r
42027 }\r
42028 }\r
42029 me.callParent([\r
42030 options\r
42031 ]);\r
42032 },\r
42033 setMoving: function(records, isMoving) {\r
42034 var me = this,\r
42035 map = me.moveMap || (me.moveMap = {}),\r
42036 len = records.length,\r
42037 i, id;\r
42038 for (i = 0; i < len; ++i) {\r
42039 id = records[i].id;\r
42040 if (isMoving) {\r
42041 if (map[id]) {\r
42042 ++map[id];\r
42043 } else {\r
42044 map[id] = 1;\r
42045 ++me.moveMapCount;\r
42046 }\r
42047 } else {\r
42048 if (--map[id] === 0) {\r
42049 delete map[id];\r
42050 --me.moveMapCount;\r
42051 }\r
42052 }\r
42053 }\r
42054 if (me.moveMapCount === 0) {\r
42055 me.moveMap = null;\r
42056 }\r
42057 },\r
42058 processAssociation: function(records) {\r
42059 var me = this,\r
42060 associatedEntity = me.getAssociatedEntity();\r
42061 if (associatedEntity) {\r
42062 records = me.getRole().processLoad(me, associatedEntity, records, me.getSession());\r
42063 }\r
42064 return records;\r
42065 }\r
42066 }\r
42067});\r
42068
42069\r
42070\r
42071\r
42072\r
42073\r
42074\r
42075\r
42076\r
42077\r
42078\r
42079\r
42080\r
42081\r
42082\r
42083\r
42084\r
42085\r
42086\r
42087Ext.define('Ext.data.reader.Array', {\r
42088 extend: Ext.data.reader.Json,\r
42089 alternateClassName: 'Ext.data.ArrayReader',\r
42090 alias: 'reader.array',\r
42091
42092 config: {\r
42093 \r
42094 totalProperty: undefined,\r
42095 \r
42096 successProperty: undefined\r
42097 },\r
42098 \r
42099 createFieldAccessor: function(field) {\r
42100
42101
42102 var oldMap = field.mapping,\r
42103 index = field.hasMapping() ? oldMap : field.ordinal,\r
42104 result;\r
42105
42106 field.mapping = index;\r
42107 result = this.callParent(arguments);\r
42108 field.mapping = oldMap;\r
42109 return result;\r
42110 },\r
42111 getModelData: function(raw) {\r
42112
42113 return {};\r
42114 }\r
42115});\r
42116\r
42117\r
42118Ext.define('Ext.data.ArrayStore', {\r
42119 extend: Ext.data.Store,\r
42120 alias: 'store.array',\r
42121 alternateClassName: [\r
42122 'Ext.data.SimpleStore'\r
42123 ],\r
42124 config: {\r
42125 proxy: {\r
42126 type: 'memory',\r
42127 reader: 'array'\r
42128 }\r
42129 },\r
42130 loadData: function(data, append) {\r
42131 if (this.expandData) {\r
42132 var r = [],\r
42133 i = 0,\r
42134 ln = data.length;\r
42135 for (; i < ln; i++) {\r
42136 r[r.length] = [\r
42137 data[i]\r
42138 ];\r
42139 }\r
42140 data = r;\r
42141 }\r
42142 this.callParent([\r
42143 data,\r
42144 append\r
42145 ]);\r
42146 }\r
42147});\r
42148\r
42149\r
42150Ext.define('Ext.data.StoreManager', {\r
42151 extend: Ext.util.MixedCollection,\r
42152 alternateClassName: [\r
42153 'Ext.StoreMgr',\r
42154 'Ext.data.StoreMgr',\r
42155 'Ext.StoreManager'\r
42156 ],\r
42157 singleton: true,\r
42158 \r
42159 \r
42160 register: function() {\r
42161 for (var i = 0,\r
42162 s; (s = arguments[i]); i++) {\r
42163 this.add(s);\r
42164 }\r
42165 },\r
42166 \r
42167 unregister: function() {\r
42168 for (var i = 0,\r
42169 s; (s = arguments[i]); i++) {\r
42170 this.remove(this.lookup(s));\r
42171 }\r
42172 },\r
42173 \r
42174 lookup: function(store, defaultType) {\r
42175
42176 if (Ext.isArray(store)) {\r
42177 var fields = [\r
42178 'field1'\r
42179 ],\r
42180 expand = !Ext.isArray(store[0]),\r
42181 data = store,\r
42182 i, len;\r
42183 if (expand) {\r
42184 data = [];\r
42185 for (i = 0 , len = store.length; i < len; ++i) {\r
42186 data.push([\r
42187 store[i]\r
42188 ]);\r
42189 }\r
42190 } else {\r
42191 for (i = 2 , len = store[0].length; i <= len; ++i) {\r
42192 fields.push('field' + i);\r
42193 }\r
42194 }\r
42195 return new Ext.data.ArrayStore({\r
42196 data: data,\r
42197 fields: fields,\r
42198 autoDestroy: true,\r
42199 autoCreated: true,\r
42200 expanded: expand\r
42201 });\r
42202 }\r
42203 if (Ext.isString(store)) {\r
42204
42205 return this.get(store);\r
42206 } else {\r
42207
42208 return Ext.Factory.store(store, defaultType);\r
42209 }\r
42210 },\r
42211
42212 getKey: function(o) {\r
42213 return o.storeId;\r
42214 }\r
42215}, function() {\r
42216 \r
42217 Ext.regStore = function(name, config) {\r
42218 var store;\r
42219 if (Ext.isObject(name)) {\r
42220 config = name;\r
42221 } else {\r
42222 if (Ext.data.StoreManager.containsKey(name)) {\r
42223 return Ext.data.StoreManager.lookup(name);\r
42224 }\r
42225 config.storeId = name;\r
42226 }\r
42227 if (config instanceof Ext.data.Store) {\r
42228 store = config;\r
42229 } else {\r
42230 store = new Ext.data.Store(config);\r
42231 }\r
42232 Ext.data.StoreManager.register(store);\r
42233 return store;\r
42234 };\r
42235 \r
42236 Ext.getStore = function(name) {\r
42237 return Ext.data.StoreManager.lookup(name);\r
42238 };\r
42239
42240
42241
42242 var emptyStore = Ext.regStore('ext-empty-store', {\r
42243 proxy: 'memory',\r
42244 useModelWarning: false\r
42245 });\r
42246 emptyStore.isEmptyStore = true;\r
42247
42248 emptyStore.add = emptyStore.remove = emptyStore.insert = emptyStore.loadData = function() {\r
42249 Ext.raise('Cannot modify ext-empty-store');\r
42250 };\r
42251});\r
42252
42253\r
42254\r
42255Ext.define('Ext.app.domain.Store', {\r
42256 extend: Ext.app.EventDomain,\r
42257 singleton: true,\r
42258 type: 'store',\r
42259 prefix: 'store.',\r
42260 idMatchRe: /^\#/,\r
42261 constructor: function() {\r
42262 var me = this;\r
42263 me.callParent();\r
42264 me.monitor(Ext.data.AbstractStore);\r
42265 },\r
42266 match: function(target, selector) {\r
42267 var result = false,\r
42268 alias = target.alias;\r
42269 if (selector === '*') {\r
42270 result = true;\r
42271 } else if (this.idMatchRe.test(selector)) {\r
42272 result = target.getStoreId() === selector.substring(1);\r
42273 } else if (alias) {\r
42274 result = Ext.Array.indexOf(alias, this.prefix + selector) > -1;\r
42275 }\r
42276 return result;\r
42277 }\r
42278});\r
42279\r
42280\r
42281Ext.define('Ext.app.route.Queue', {\r
42282 \r
42283 queue: null,\r
42284 \r
42285 token: null,\r
42286 constructor: function(config) {\r
42287 Ext.apply(this, config);\r
42288
42289 this.queue = new Ext.util.MixedCollection();\r
42290 },\r
42291 \r
42292 queueAction: function(route, args) {\r
42293 this.queue.add({\r
42294 route: route,\r
42295 args: args\r
42296 });\r
42297 },\r
42298 \r
42299 clearQueue: function() {\r
42300 this.queue.removeAll();\r
42301 },\r
42302 \r
42303 runQueue: function() {\r
42304 var queue = this.queue,\r
42305 action = queue.removeAt(0),\r
42306 route;\r
42307 if (action) {\r
42308 route = action && action.route;\r
42309 route.execute(this.token, action.args, this.onActionExecute, this);\r
42310 }\r
42311 },\r
42312 \r
42313 onActionExecute: function(clearQueue) {\r
42314 if (clearQueue) {\r
42315
42316 this.clearQueue();\r
42317 } else {\r
42318
42319 this.runQueue();\r
42320 }\r
42321 }\r
42322});\r
42323\r
42324\r
42325Ext.define('Ext.app.route.Route', {\r
42326 \r
42327 action: null,\r
42328 \r
42329 conditions: null,\r
42330 \r
42331 controller: null,\r
42332 \r
42333 allowInactive: false,\r
42334 \r
42335 url: null,\r
42336 \r
42337 before: null,\r
42338 \r
42339 caseInsensitive: false,\r
42340 \r
42341 matcherRegex: null,\r
42342 \r
42343 paramMatchingRegex: null,\r
42344 \r
42345 paramsInMatchString: null,\r
42346 constructor: function(config) {\r
42347 var me = this,\r
42348 url;\r
42349 Ext.apply(me, config, {\r
42350 conditions: {}\r
42351 });\r
42352 url = me.url;\r
42353 me.paramMatchingRegex = new RegExp(/:([0-9A-Za-z\_]*)/g);\r
42354 me.paramsInMatchString = url.match(me.paramMatchingRegex) || [];\r
42355 me.matcherRegex = me.createMatcherRegex(url);\r
42356 },\r
42357 \r
42358 recognize: function(url) {\r
42359 var me = this,\r
42360 controller = me.controller,\r
42361 matches, args;\r
42362 if ((me.allowInactive || controller.isActive()) && me.recognizes(url)) {\r
42363
42364 matches = me.matchesFor(url);\r
42365
42366 args = url.match(me.matcherRegex);\r
42367
42368 args.shift();\r
42369 return Ext.applyIf(matches, {\r
42370 controller: controller,\r
42371 action: me.action,\r
42372 historyUrl: url,\r
42373 args: args\r
42374 });\r
42375 }\r
42376 return false;\r
42377 },\r
42378 \r
42379 recognizes: function(url) {\r
42380 return this.matcherRegex.test(url);\r
42381 },\r
42382 \r
42383 execute: function(token, argConfig, callback, scope) {\r
42384 var args = argConfig.args || [],\r
42385 before = this.before,\r
42386 controller = this.controller,\r
42387 beforeCallback = this.createCallback(argConfig, callback, scope);\r
42388 if (before) {\r
42389 args.push(beforeCallback);\r
42390 if (Ext.isString(before)) {\r
42391
42392 before = this.before = controller[before];\r
42393 }\r
42394 if (before) {\r
42395 before.apply(controller, args);\r
42396 } else
42397 {\r
42398 Ext.log.warn('The before action: ' + this.before + ' was not found on the controller. The action method will not be executed.');\r
42399 }\r
42400 } else
42401 {\r
42402
42403 beforeCallback.resume();\r
42404 }\r
42405 },\r
42406 \r
42407 matchesFor: function(url) {\r
42408 var params = {},\r
42409 keys = this.paramsInMatchString,\r
42410 values = url.match(this.matcherRegex),\r
42411 i = 0,\r
42412 len = keys.length;\r
42413
42414 values.shift();\r
42415 for (; i < len; i++) {\r
42416 params[keys[i].replace(':', '')] = values[i];\r
42417 }\r
42418 return params;\r
42419 },\r
42420 \r
42421 createMatcherRegex: function(url) {\r
42422
42423
42424
42425 var paramsInMatchString = this.paramsInMatchString,\r
42426 conditions = this.conditions,\r
42427 i = 0,\r
42428 len = paramsInMatchString.length,\r
42429 format = Ext.util.Format.format,\r
42430 modifiers = this.caseInsensitive ? 'i' : '',\r
42431 params, cond, matcher;\r
42432 for (; i < len; i++) {\r
42433 params = paramsInMatchString[i];\r
42434 cond = conditions[params];\r
42435 matcher = format('{0}', cond || '([%a-zA-Z0-9\\-\\_\\s,]+)');\r
42436 url = url.replace(new RegExp(params), matcher);\r
42437 }\r
42438
42439 return new RegExp('^' + url + '$', modifiers);\r
42440 },\r
42441 \r
42442 createCallback: function(args, callback, scope) {\r
42443 var me = this;\r
42444 scope = scope || me;\r
42445 return {\r
42446 resume: function() {\r
42447 var controller = me.controller,\r
42448 action = me.action,\r
42449 resume;\r
42450 if (Ext.isString(action)) {\r
42451
42452 action = controller[action];\r
42453 }\r
42454
42455 args = args && args.args ? args.args : [];\r
42456
42457 resume = args.pop();\r
42458 if (resume && !Ext.isObject(resume)) {\r
42459 args.push(resume);\r
42460 }\r
42461
42462 if (action) {\r
42463 me.action = action;\r
42464
42465 action.apply(controller, args);\r
42466 } else
42467 {\r
42468 Ext.log.warn('The action: ' + me.action + ' was not found on the controller.');\r
42469 }\r
42470
42471 if (callback) {\r
42472 callback.call(scope);\r
42473 }\r
42474 },\r
42475 stop: function(all) {\r
42476 if (callback) {\r
42477 callback.call(scope, all);\r
42478 }\r
42479 }\r
42480 };\r
42481 }\r
42482});\r
42483\r
42484\r
42485Ext.define('Ext.util.History', {\r
42486 singleton: true,\r
42487 alternateClassName: 'Ext.History',\r
42488 mixins: {\r
42489 observable: Ext.util.Observable\r
42490 },\r
42491 \r
42492 useTopWindow: false,\r
42493 \r
42494 \r
42495 \r
42496 constructor: function() {\r
42497 var me = this;\r
42498 me.hiddenField = null;\r
42499 me.ready = false;\r
42500 me.currentToken = null;\r
42501 me.mixins.observable.constructor.call(me);\r
42502 },\r
42503 \r
42504 getHash: function() {\r
42505 return this.win.location.hash.substr(1);\r
42506 },\r
42507 \r
42508 setHash: function(hash) {\r
42509 try {\r
42510 this.win.location.hash = hash;\r
42511 this.currentToken = hash;\r
42512 } catch (e) {}\r
42513 },\r
42514
42515 \r
42516 handleStateChange: function(token) {\r
42517 this.currentToken = token;\r
42518 this.fireEvent('change', token);\r
42519 },\r
42520 \r
42521 startUp: function() {\r
42522 var me = this;\r
42523 me.currentToken = me.getHash();\r
42524 if (Ext.supports.Hashchange) {\r
42525 Ext.get(me.win).on('hashchange', me.onHashChange, me);\r
42526 } else {\r
42527 Ext.TaskManager.start({\r
42528 fireIdleEvent: false,\r
42529 run: me.onHashChange,\r
42530 interval: 50,\r
42531 scope: me\r
42532 });\r
42533 }\r
42534 me.ready = true;\r
42535 me.fireEvent('ready', me);\r
42536 },\r
42537 onHashChange: function() {\r
42538 var me = this,\r
42539 newHash = me.getHash();\r
42540 if (newHash !== me.hash) {\r
42541 me.hash = newHash;\r
42542 me.handleStateChange(newHash);\r
42543 }\r
42544 },\r
42545 \r
42546 init: function(onReady, scope) {\r
42547 var me = this;\r
42548 if (me.ready) {\r
42549 Ext.callback(onReady, scope, [\r
42550 me\r
42551 ]);\r
42552 return;\r
42553 }\r
42554 if (!Ext.isReady) {\r
42555 Ext.onInternalReady(function() {\r
42556 me.init(onReady, scope);\r
42557 });\r
42558 return;\r
42559 }\r
42560 me.win = me.useTopWindow ? window.top : window;\r
42561 me.hash = me.getHash();\r
42562 if (onReady) {\r
42563 me.on('ready', onReady, scope, {\r
42564 single: true\r
42565 });\r
42566 }\r
42567 me.startUp();\r
42568 },\r
42569 \r
42570 add: function(token, preventDuplicates) {\r
42571 var me = this,\r
42572 set = false;\r
42573 if (preventDuplicates === false || me.getToken() !== token) {\r
42574 me.setHash(token);\r
42575 set = true;\r
42576 }\r
42577 return set;\r
42578 },\r
42579 \r
42580 back: function() {\r
42581 var win = this.useTopWindow ? window.top : window;\r
42582 win.history.go(-1);\r
42583 },\r
42584 \r
42585 forward: function() {\r
42586 var win = this.useTopWindow ? window.top : window;\r
42587 win.history.go(1);\r
42588 },\r
42589 \r
42590 getToken: function() {\r
42591 return this.ready ? this.currentToken : this.getHash();\r
42592 }\r
42593});\r
42594\r
42595\r
42596Ext.define('Ext.app.route.Router', {\r
42597 singleton: true,\r
42598 \r
42599 multipleToken: '|',\r
42600 \r
42601 queueRoutes: true,\r
42602 \r
42603 constructor: function() {\r
42604 var History = Ext.util.History;\r
42605 if (!History.ready) {\r
42606 History.init();\r
42607 }\r
42608 History.on('change', this.onStateChange, this);\r
42609 this.clear();\r
42610 },\r
42611 \r
42612 onStateChange: function(token) {\r
42613 var me = this,\r
42614 app = me.application,\r
42615 routes = me.routes,\r
42616 len = routes.length,\r
42617 queueRoutes = me.queueRoutes,\r
42618 tokens = token.split(me.multipleToken),\r
42619 t = 0,\r
42620 length = tokens.length,\r
42621 i, queue, route, args, matched;\r
42622 for (; t < length; t++) {\r
42623 token = tokens[t];\r
42624 matched = false;\r
42625 if (queueRoutes) {\r
42626
42627 queue = new Ext.app.route.Queue({\r
42628 token: token\r
42629 });\r
42630 }\r
42631 for (i = 0; i < len; i++) {\r
42632 route = routes[i];\r
42633 args = route.recognize(token);\r
42634 if (args) {\r
42635 matched = true;\r
42636 if (queueRoutes) {\r
42637 queue.queueAction(route, args);\r
42638 } else {\r
42639 route.execute(token, args);\r
42640 }\r
42641 }\r
42642 }\r
42643 if (queueRoutes) {\r
42644
42645 queue.runQueue();\r
42646 }\r
42647 if (!matched && app) {\r
42648 app.fireEvent('unmatchedroute', token);\r
42649 }\r
42650 }\r
42651 },\r
42652 \r
42653 connect: function(url, action, controller) {\r
42654 var config = {\r
42655 url: url,\r
42656 action: action,\r
42657 controller: controller\r
42658 };\r
42659 if (Ext.isObject(action)) {\r
42660 Ext.merge(config, action);\r
42661 }\r
42662 this.routes.push(new Ext.app.route.Route(config));\r
42663 },\r
42664 \r
42665 disconnectAll: function(controller) {\r
42666 var routes = this.routes,\r
42667 len = routes.length,\r
42668 newRoutes = [],\r
42669 i, route;\r
42670 for (i = 0; i < len; ++i) {\r
42671 route = routes[i];\r
42672 if (route.controller !== controller) {\r
42673 newRoutes.push(route);\r
42674 }\r
42675 }\r
42676 this.routes = newRoutes;\r
42677 },\r
42678 \r
42679 recognize: function(url) {\r
42680 var routes = this.routes || [],\r
42681 i = 0,\r
42682 len = routes.length,\r
42683 route, args;\r
42684 for (; i < len; i++) {\r
42685 route = routes[i];\r
42686 args = route.recognize(url);\r
42687 if (args) {\r
42688
42689 return {\r
42690 route: route,\r
42691 args: args\r
42692 };\r
42693 }\r
42694 }\r
42695 return false;\r
42696 },\r
42697 \r
42698 draw: function(fn) {\r
42699 fn.call(this, this);\r
42700 },\r
42701 \r
42702 clear: function() {\r
42703 this.routes = [];\r
42704 }\r
42705});\r
42706\r
42707\r
42708Ext.define('Ext.app.Controller', {\r
42709 extend: Ext.app.BaseController,\r
42710 statics: {\r
42711 strings: {\r
42712 model: {\r
42713 getter: 'getModel',\r
42714 upper: 'Model'\r
42715 },\r
42716 view: {\r
42717 getter: 'getView',\r
42718 upper: 'View'\r
42719 },\r
42720 controller: {\r
42721 getter: 'getController',\r
42722 upper: 'Controller'\r
42723 },\r
42724 store: {\r
42725 getter: 'getStore',\r
42726 upper: 'Store'\r
42727 },\r
42728 profile: {\r
42729 getter: 'getProfile',\r
42730 upper: 'Profiles'\r
42731 }\r
42732 },\r
42733 controllerRegex: /^(.*)\.controller\./,\r
42734 profileRegex: /^(.*)\.profile\./,\r
42735 createGetter: function(baseGetter, name) {\r
42736 return function() {\r
42737 return this[baseGetter](name);\r
42738 };\r
42739 },\r
42740 getGetterName: function(name, kindUpper) {\r
42741 var fn = 'get',\r
42742 parts = name.split('.'),\r
42743 numParts = parts.length,\r
42744 index;\r
42745
42746 for (index = 0; index < numParts; index++) {\r
42747 fn += Ext.String.capitalize(parts[index]);\r
42748 }\r
42749 fn += kindUpper;\r
42750 return fn;\r
42751 },\r
42752 resolveNamespace: function(cls, data) {\r
42753 var Controller = Ext.app.Controller,\r
42754 namespaceRe = cls.prototype.isProfile ? Controller.profileRegex : Controller.controllerRegex,\r
42755 className, namespace, match;\r
42756 \r
42757 className = Ext.getClassName(cls);\r
42758 namespace = data.$namespace || data.namespace || Ext.app.getNamespace(className) || ((match = namespaceRe.exec(className)) && match[1]);\r
42759
42760 if (!namespace) {\r
42761 Ext.log.warn("Missing namespace for " + className + ", please define it " + "in namespaces property of your Application class.");\r
42762 }\r
42763
42764 return namespace;\r
42765 },\r
42766 \r
42767 processDependencies: function(cls, requires, namespace, kind, names, profileName) {\r
42768 if (!names || !names.length) {\r
42769 return;\r
42770 }\r
42771 var me = this,\r
42772 strings = me.strings[kind],\r
42773 o, absoluteName, shortName, name, j, subLn, getterName, getter;\r
42774 if (!Ext.isArray(names)) {\r
42775 names = [\r
42776 names\r
42777 ];\r
42778 }\r
42779 for (j = 0 , subLn = names.length; j < subLn; j++) {\r
42780 name = names[j];\r
42781 o = me.getFullName(name, kind, namespace, profileName);\r
42782
42783 names[j] = absoluteName = o.absoluteName;\r
42784 shortName = o.shortName;\r
42785 requires.push(absoluteName);\r
42786 getterName = me.getGetterName(shortName, strings.upper);\r
42787 if (!cls[getterName]) {\r
42788 cls[getterName] = getter = me.createGetter(strings.getter, name);\r
42789 }\r
42790
42791 else if (getterName === 'getMainView') {\r
42792 Ext.log.warn('Cannot have a view named \'Main\' - getter conflicts with mainView config.');\r
42793 }\r
42794
42795
42796 if (getter && kind !== 'controller') {\r
42797
42798
42799
42800
42801 getter['Ext.app.getter'] = true;\r
42802 }\r
42803 }\r
42804 },\r
42805 getFullName: function(name, kind, namespace, profileName) {\r
42806 var shortName = name,\r
42807 sep, absoluteName;\r
42808 if ((sep = name.indexOf('@')) > 0) {\r
42809
42810
42811
42812
42813 shortName = name.substring(0, sep);\r
42814
42815 absoluteName = name.substring(sep + 1) + '.' + shortName;\r
42816 }\r
42817
42818
42819
42820
42821
42822
42823
42824
42825
42826
42827
42828
42829
42830
42831
42832
42833 else if (name.indexOf('.') > 0 && (Ext.ClassManager.isCreated(name) || this.hasRegisteredPrefix(name))) {\r
42834 absoluteName = name;\r
42835 } else {\r
42836
42837 if (!namespace) {\r
42838 Ext.log.warn("Cannot find namespace for " + kind + " " + name + ", " + "assuming it is fully qualified class name");\r
42839 }\r
42840
42841 if (namespace) {\r
42842 absoluteName = namespace + '.' + kind + '.' + (profileName ? profileName + '.' + name : name);\r
42843 shortName = name;\r
42844 } else {\r
42845 absoluteName = name;\r
42846 }\r
42847 }\r
42848 return {\r
42849 absoluteName: absoluteName,\r
42850 shortName: shortName\r
42851 };\r
42852 },\r
42853 hasRegisteredPrefix: function(className) {\r
42854 var inventory = Ext.ClassManager,\r
42855 prefix = inventory.getPrefix(className);\r
42856
42857 return prefix && prefix !== className;\r
42858 }\r
42859 },\r
42860
42861 \r
42862 models: null,\r
42863
42864 \r
42865 views: null,\r
42866
42867 \r
42868 stores: null,\r
42869
42870 controllers: null,\r
42871 config: {\r
42872 \r
42873 application: null,\r
42874 \r
42875 refs: null,\r
42876 active: true,\r
42877 \r
42878 moduleClassName: null\r
42879 },\r
42880 onClassExtended: function(cls, data, hooks) {\r
42881 var onBeforeClassCreated = hooks.onBeforeCreated;\r
42882 hooks.onBeforeCreated = function(cls, data) {\r
42883 var Controller = Ext.app.Controller,\r
42884 requires = [],\r
42885 namespace, proto;\r
42886 proto = cls.prototype;\r
42887 namespace = Controller.resolveNamespace(cls, data);\r
42888 if (namespace) {\r
42889 proto.$namespace = namespace;\r
42890 }\r
42891 Controller.processDependencies(proto, requires, namespace, 'model', data.models);\r
42892 Controller.processDependencies(proto, requires, namespace, 'view', data.views);\r
42893 Controller.processDependencies(proto, requires, namespace, 'store', data.stores);\r
42894 Controller.processDependencies(proto, requires, namespace, 'controller', data.controllers);\r
42895 Ext.require(requires, Ext.Function.pass(onBeforeClassCreated, arguments, this));\r
42896 };\r
42897 },\r
42898 \r
42899 constructor: function(config) {\r
42900 this.initAutoGetters();\r
42901 this.callParent(arguments);\r
42902 },\r
42903 \r
42904 normalizeRefs: function(refs) {\r
42905 var me = this,\r
42906 newRefs = [];\r
42907 if (refs) {\r
42908 if (Ext.isObject(refs)) {\r
42909 Ext.Object.each(refs, function(key, value) {\r
42910 if (Ext.isString(value)) {\r
42911 value = {\r
42912 selector: value\r
42913 };\r
42914 }\r
42915 value.ref = key;\r
42916 newRefs.push(value);\r
42917 });\r
42918 } else if (Ext.isArray(refs)) {\r
42919 newRefs = Ext.Array.merge(newRefs, refs);\r
42920 }\r
42921 }\r
42922 refs = me.refs;\r
42923 if (refs) {\r
42924 me.refs = null;\r
42925 refs = me.normalizeRefs(refs);\r
42926 if (refs) {\r
42927 newRefs = Ext.Array.merge(newRefs, refs);\r
42928 }\r
42929 }\r
42930 return newRefs;\r
42931 },\r
42932 \r
42933 getRefMap: function() {\r
42934 var me = this,\r
42935 refMap = me._refMap,\r
42936 refs, ref, ln, i;\r
42937 if (!refMap) {\r
42938 refs = me.getRefs();\r
42939 refMap = me._refMap = {};\r
42940 if (refs) {\r
42941 for (i = 0 , ln = refs.length; i < ln; i++) {\r
42942 ref = refs[i];\r
42943 refMap[ref.ref] = ref.selector;\r
42944 }\r
42945 }\r
42946 }\r
42947 return refMap;\r
42948 },\r
42949 applyRefs: function(refs) {\r
42950 return this.normalizeRefs(Ext.clone(refs));\r
42951 },\r
42952 \r
42953 updateRefs: function(refs) {\r
42954 if (refs) {\r
42955 this.ref(refs);\r
42956 }\r
42957 },\r
42958 initAutoGetters: function() {\r
42959 var proto = this.self.prototype,\r
42960 prop, fn;\r
42961 for (prop in proto) {\r
42962 fn = proto[prop];\r
42963
42964
42965 if (fn && fn['Ext.app.getter']) {\r
42966 fn.call(this);\r
42967 }\r
42968 }\r
42969 },\r
42970 doInit: function(app) {\r
42971 var me = this;\r
42972 if (!me._initialized) {\r
42973 me.init(app);\r
42974 me._initialized = true;\r
42975 }\r
42976 },\r
42977 finishInit: function(app) {\r
42978 var me = this,\r
42979 controllers = me.controllers,\r
42980 controller, i, l;\r
42981 if (me._initialized && controllers && controllers.length) {\r
42982 for (i = 0 , l = controllers.length; i < l; i++) {\r
42983 controller = me.getController(controllers[i]);\r
42984 controller.finishInit(app);\r
42985 }\r
42986 }\r
42987 },\r
42988 \r
42989 init: Ext.emptyFn,\r
42990 \r
42991 onLaunch: Ext.emptyFn,\r
42992 \r
42993 activate: function() {\r
42994 this.setActive(true);\r
42995 },\r
42996 \r
42997 deactivate: function() {\r
42998 this.setActive(false);\r
42999 },\r
43000 \r
43001 isActive: function() {\r
43002 return this.getActive();\r
43003 },\r
43004 ref: function(refs) {\r
43005 var me = this,\r
43006 i = 0,\r
43007 length = refs.length,\r
43008 info, ref, fn;\r
43009 refs = Ext.Array.from(refs);\r
43010 me.references = me.references || [];\r
43011 for (; i < length; i++) {\r
43012 info = refs[i];\r
43013 ref = info.ref;\r
43014 fn = 'get' + Ext.String.capitalize(ref);\r
43015 if (!me[fn]) {\r
43016 me[fn] = Ext.Function.pass(me.getRef, [\r
43017 ref,\r
43018 info\r
43019 ], me);\r
43020 }\r
43021 me.references.push(ref.toLowerCase());\r
43022 }\r
43023 },\r
43024 \r
43025 addRef: function(refs) {\r
43026 this.ref(refs);\r
43027 },\r
43028 getRef: function(ref, info, config) {\r
43029 var me = this,\r
43030 refCache = me.refCache || (me.refCache = {}),\r
43031 cached = refCache[ref];\r
43032 info = info || {};\r
43033 config = config || {};\r
43034 Ext.apply(info, config);\r
43035 if (info.forceCreate) {\r
43036 return Ext.ComponentManager.create(info, 'component');\r
43037 }\r
43038 if (!cached) {\r
43039 if (info.selector) {\r
43040 refCache[ref] = cached = Ext.ComponentQuery.query(info.selector)[0];\r
43041 }\r
43042 if (!cached && info.autoCreate) {\r
43043 refCache[ref] = cached = Ext.ComponentManager.create(info, 'component');\r
43044 }\r
43045 if (cached) {\r
43046 cached.on('beforedestroy', function() {\r
43047 refCache[ref] = null;\r
43048 });\r
43049 }\r
43050 }\r
43051 return cached;\r
43052 },\r
43053 \r
43054 hasRef: function(ref) {\r
43055 var references = this.references;\r
43056 return references && Ext.Array.indexOf(references, ref.toLowerCase()) !== -1;\r
43057 },\r
43058 \r
43059 getController: function(id) {\r
43060 var app = this.getApplication();\r
43061 if (id === this.getId()) {\r
43062 return this;\r
43063 }\r
43064 return app && app.getController(id);\r
43065 },\r
43066 \r
43067 getStore: function(name) {\r
43068 var storeId, store;\r
43069 storeId = (name.indexOf('@') === -1) ? name : name.split('@')[0];\r
43070 store = Ext.StoreManager.get(storeId);\r
43071 if (!store) {\r
43072 name = Ext.app.Controller.getFullName(name, 'store', this.$namespace);\r
43073 if (name) {\r
43074 store = Ext.create(name.absoluteName, {\r
43075
43076
43077 id: storeId\r
43078 });\r
43079 }\r
43080 }\r
43081 return store;\r
43082 },\r
43083 \r
43084 getModel: function(model) {\r
43085 var name = Ext.app.Controller.getFullName(model, 'model', this.$namespace),\r
43086 ret = Ext.ClassManager.get(name.absoluteName);\r
43087 if (!ret) {\r
43088 ret = Ext.data.schema.Schema.lookupEntity(model);\r
43089 }\r
43090 return ret;\r
43091 },\r
43092 \r
43093 getProfile: function(name) {\r
43094 name = Ext.app.Controller.getFullName(name, 'profile', this.$namespace);\r
43095 return name;\r
43096 },\r
43097 \r
43098 getView: function(view) {\r
43099 var name = Ext.app.Controller.getFullName(view, 'view', this.$namespace);\r
43100 return name && Ext.ClassManager.get(name.absoluteName);\r
43101 },\r
43102 ensureId: function() {\r
43103 var id = this.getId();\r
43104 if (!id) {\r
43105 this.setId(this.getModuleClassName(this.$className, 'controller'));\r
43106 }\r
43107 },\r
43108 destroy: function(destroyRefs, \r
43109 fromApp) {\r
43110 var me = this,\r
43111 app = me.application,\r
43112 refCache, ref;\r
43113 if (!fromApp && app) {\r
43114 app.unregister(me);\r
43115 }\r
43116 me.application = null;\r
43117 if (destroyRefs) {\r
43118
43119 refCache = me.refCache;\r
43120 for (ref in refCache) {\r
43121 if (refCache.hasOwnProperty(ref)) {\r
43122 Ext.destroy(refCache[ref]);\r
43123 }\r
43124 }\r
43125 }\r
43126 me.callParent();\r
43127 }\r
43128});\r
43129\r
43130\r
43131Ext.define('Ext.app.Application', {\r
43132 extend: Ext.app.Controller,\r
43133 isApplication: true,\r
43134 \r
43135 \r
43136 \r
43137 scope: undefined,\r
43138 \r
43139 namespaces: [],\r
43140 \r
43141 paths: null,\r
43142 \r
43143
43144 config: {\r
43145 \r
43146 name: '',\r
43147 \r
43148 appProperty: 'app',\r
43149
43150 \r
43151 profiles: [],\r
43152 \r
43153 currentProfile: null,\r
43154
43155 \r
43156 mainView: {\r
43157 $value: null,\r
43158 lazy: true\r
43159 },\r
43160 \r
43161 defaultToken: null,\r
43162 \r
43163 glyphFontFamily: null\r
43164 },\r
43165 onClassExtended: function(cls, data, hooks) {\r
43166 var Controller = Ext.app.Controller,\r
43167 proto = cls.prototype,\r
43168 requires = [],\r
43169 onBeforeClassCreated, paths, namespace, ns;\r
43170
43171
43172 namespace = data.name || cls.superclass.name;\r
43173 if (namespace) {\r
43174 data.$namespace = namespace;\r
43175 Ext.app.addNamespaces(namespace);\r
43176 }\r
43177 if (data.namespaces) {\r
43178 Ext.app.addNamespaces(data.namespaces);\r
43179 }\r
43180 if (data['paths processed']) {\r
43181 delete data['paths processed'];\r
43182 } else {\r
43183 Ext.app.setupPaths(namespace, ('appFolder' in data) ? data.appFolder : cls.superclass.appFolder, data.paths);\r
43184 }\r
43185
43186 Controller.processDependencies(proto, requires, namespace, 'profile', data.profiles);\r
43187
43188
43189 proto.getDependencies(cls, data, requires);\r
43190
43191 if (requires.length) {\r
43192 onBeforeClassCreated = hooks.onBeforeCreated;\r
43193 hooks.onBeforeCreated = function(cls, data) {\r
43194 var args = Ext.Array.clone(arguments);\r
43195 Ext.require(requires, function() {\r
43196 return onBeforeClassCreated.apply(this, args);\r
43197 });\r
43198 };\r
43199 }\r
43200 },\r
43201 getDependencies: Ext.emptyFn,\r
43202 \r
43203 constructor: function(config) {\r
43204 var me = this;\r
43205 Ext.app.route.Router.application = me;\r
43206 me.callParent(arguments);\r
43207
43208 if (Ext.isEmpty(me.getName())) {\r
43209 Ext.raise("[Ext.app.Application] Name property is required");\r
43210 }\r
43211
43212 me.doInit(me);\r
43213 me.initNamespace();\r
43214 Ext.on('appupdate', me.onAppUpdate, me, {\r
43215 single: true\r
43216 });\r
43217
43218 Ext.Loader.setConfig({\r
43219 enabled: true\r
43220 });\r
43221
43222 this.onProfilesReady();\r
43223 },\r
43224 \r
43225 onAppUpdate: Ext.emptyFn,\r
43226 onProfilesReady: function() {\r
43227 var me = this,\r
43228 profiles = me.getProfiles(),\r
43229 length = profiles.length,\r
43230 current, i, instance;\r
43231 for (i = 0; i < length; i++) {\r
43232 instance = Ext.create(profiles[i], {\r
43233 application: me\r
43234 });\r
43235 if (instance.isActive() && !current) {\r
43236 current = instance;\r
43237 me.setCurrentProfile(current);\r
43238 }\r
43239 }\r
43240 if (current) {\r
43241 current.init();\r
43242 }\r
43243 me.initControllers();\r
43244 me.onBeforeLaunch();\r
43245 me.finishInitControllers();\r
43246 },\r
43247 initNamespace: function() {\r
43248 var me = this,\r
43249 appProperty = me.getAppProperty(),\r
43250 ns;\r
43251 ns = Ext.namespace(me.getName());\r
43252 if (ns) {\r
43253 ns.getApplication = function() {\r
43254 return me;\r
43255 };\r
43256 if (appProperty) {\r
43257 if (!ns[appProperty]) {\r
43258 ns[appProperty] = me;\r
43259 }\r
43260
43261 else if (ns[appProperty] !== me) {\r
43262 Ext.log.warn('An existing reference is being overwritten for ' + name + '.' + appProperty + '. See the appProperty config.');\r
43263 }\r
43264 }\r
43265 }\r
43266 },\r
43267
43268 initControllers: function() {\r
43269 var me = this,\r
43270 controllers = Ext.Array.from(me.controllers),\r
43271 profile = me.getCurrentProfile(),\r
43272 i, ln;\r
43273 me.controllers = new Ext.util.MixedCollection();\r
43274 for (i = 0 , ln = controllers.length; i < ln; i++) {\r
43275 me.getController(controllers[i]);\r
43276 }\r
43277
43278
43279 if (profile) {\r
43280 controllers = profile.getControllers();\r
43281 for (i = 0 , ln = controllers.length; i < ln; i++) {\r
43282 me.getController(controllers[i]);\r
43283 }\r
43284 }\r
43285 },\r
43286 finishInitControllers: function() {\r
43287 var me = this,\r
43288 controllers, i, l;\r
43289 controllers = me.controllers.getRange();\r
43290 for (i = 0 , l = controllers.length; i < l; i++) {\r
43291 controllers[i].finishInit(me);\r
43292 }\r
43293 },\r
43294 \r
43295 launch: Ext.emptyFn,\r
43296 \r
43297 onBeforeLaunch: function() {\r
43298 var me = this,\r
43299 History = Ext.util.History,\r
43300 defaultToken = me.getDefaultToken(),\r
43301 currentProfile = me.getCurrentProfile(),\r
43302 controllers, c, cLen, controller, token;\r
43303 me.initMainView();\r
43304 if (currentProfile) {\r
43305 currentProfile.launch();\r
43306 }\r
43307 me.launch.call(me.scope || me);\r
43308 me.launched = true;\r
43309 me.fireEvent('launch', me);\r
43310 controllers = me.controllers.items;\r
43311 cLen = controllers.length;\r
43312 for (c = 0; c < cLen; c++) {\r
43313 controller = controllers[c];\r
43314 controller.onLaunch(me);\r
43315 }\r
43316 if (!History.ready) {\r
43317 History.init();\r
43318 }\r
43319 token = History.getToken();\r
43320 if (token || token === defaultToken) {\r
43321 Ext.app.route.Router.onStateChange(token);\r
43322 } else if (defaultToken) {\r
43323 History.add(defaultToken);\r
43324 }\r
43325
43326
43327 if (Ext.Microloader && Ext.Microloader.appUpdate && Ext.Microloader.appUpdate.updated) {\r
43328 Ext.Microloader.fireAppUpdate();\r
43329 }\r
43330
43331 Ext.defer(Ext.ClassManager.clearNamespaceCache, 2000, Ext.ClassManager);\r
43332 },\r
43333 getModuleClassName: function(name, kind) {\r
43334 return Ext.app.Controller.getFullName(name, kind, this.getName()).absoluteName;\r
43335 },\r
43336 initMainView: function() {\r
43337 var me = this,\r
43338 currentProfile = me.getCurrentProfile(),\r
43339 mainView;\r
43340 if (currentProfile) {\r
43341 mainView = currentProfile.getMainView();\r
43342 }\r
43343 if (mainView) {\r
43344 me.setMainView(mainView);\r
43345 } else {\r
43346
43347 me.getMainView();\r
43348 }\r
43349 },\r
43350 applyMainView: function(value) {\r
43351 var view = this.getView(value);\r
43352 return view.create();\r
43353 },\r
43354 \r
43355 createController: function(name) {\r
43356 return this.getController(name);\r
43357 },\r
43358 \r
43359 destroyController: function(controller) {\r
43360 if (typeof controller === 'string') {\r
43361 controller = this.getController(controller, true);\r
43362 }\r
43363 Ext.destroy(controller);\r
43364 },\r
43365 getController: function(name, \r
43366 preventCreate) {\r
43367 var me = this,\r
43368 controllers = me.controllers,\r
43369 className, controller, len, i, c, all;\r
43370 controller = controllers.get(name);\r
43371
43372
43373
43374
43375 if (!controller) {\r
43376 all = controllers.items;\r
43377 for (i = 0 , len = all.length; i < len; ++i) {\r
43378 c = all[i];\r
43379 className = c.getModuleClassName();\r
43380 if (className && className === name) {\r
43381 controller = c;\r
43382 break;\r
43383 }\r
43384 }\r
43385 }\r
43386 if (!controller && !preventCreate) {\r
43387 className = me.getModuleClassName(name, 'controller');\r
43388 controller = Ext.create(className, {\r
43389 application: me,\r
43390 moduleClassName: name\r
43391 });\r
43392 controllers.add(controller);\r
43393 if (me._initialized) {\r
43394 controller.doInit(me);\r
43395 }\r
43396 }\r
43397 return controller;\r
43398 },\r
43399 \r
43400 unregister: function(controller) {\r
43401 this.controllers.remove(controller);\r
43402 },\r
43403 getApplication: function() {\r
43404 return this;\r
43405 },\r
43406 destroy: function(destroyRefs) {\r
43407 var me = this,\r
43408 controllers = me.controllers,\r
43409 ns = Ext.namespace(me.getName()),\r
43410 appProp = me.getAppProperty();\r
43411 Ext.destroy(me.viewport);\r
43412 if (controllers) {\r
43413 controllers.each(function(controller) {\r
43414 controller.destroy(destroyRefs, true);\r
43415 });\r
43416 }\r
43417 me.controllers = null;\r
43418 me.callParent([\r
43419 destroyRefs,\r
43420 true\r
43421 ]);\r
43422
43423 if (ns && ns[appProp] === me) {\r
43424 delete ns[appProp];\r
43425 }\r
43426 },\r
43427 updateGlyphFontFamily: function(fontFamily) {\r
43428 Ext.setGlyphFontFamily(fontFamily);\r
43429 },\r
43430 \r
43431 applyProfiles: function(profiles) {\r
43432 var me = this;\r
43433 return Ext.Array.map(profiles, function(profile) {\r
43434 return me.getModuleClassName(profile, "profile");\r
43435 });\r
43436 }\r
43437});\r
43438\r
43439
43440
43441
43442
43443
43444
43445\r
43446Ext.application = function(config) {\r
43447 var createApp = function(App) {\r
43448
43449 Ext.onReady(function() {\r
43450 var Viewport = Ext.viewport;\r
43451 Viewport = Viewport && Viewport['Viewport'];\r
43452 if (Viewport && Viewport.setup) {\r
43453 Viewport.setup(App.prototype.config.viewport);\r
43454 }\r
43455 Ext.app.Application.instance = new App();\r
43456 });\r
43457 };\r
43458 if (typeof config === "string") {\r
43459 Ext.require(config, function() {\r
43460 createApp(Ext.ClassManager.get(config));\r
43461 });\r
43462 } else {\r
43463 config = Ext.apply({\r
43464 extend: 'Ext.app.Application'\r
43465 },
43466 config);\r
43467
43468
43469 Ext.app.setupPaths(config.name, config.appFolder, config.paths);\r
43470 config['paths processed'] = true;\r
43471
43472 Ext.define(config.name + ".$application", config, function() {\r
43473 createApp(this);\r
43474 });\r
43475 }\r
43476};\r
43477\r
43478\r
43479Ext.define('Ext.scroll.Scroller', {\r
43480 extend: Ext.Evented,\r
43481 alias: 'scroller.scroller',\r
43482 mixins: [\r
43483 Ext.mixin.Factoryable\r
43484 ],\r
43485 factoryConfig: {\r
43486 defaultType: 'dom'\r
43487 },\r
43488 isScroller: true,\r
43489 _spacerCls: Ext.baseCSSPrefix + 'domscroller-spacer',\r
43490 \r
43491 \r
43492 \r
43493 \r
43494 config: {\r
43495 \r
43496 direction: undefined,\r
43497
43498 \r
43499 directionLock: false,\r
43500 \r
43501 disabled: null,\r
43502 \r
43503 element: undefined,\r
43504 \r
43505 indicators: null,\r
43506 \r
43507 maxPosition: {\r
43508 x: 0,\r
43509 y: 0\r
43510 },\r
43511 \r
43512 maxUserPosition: {\r
43513 x: 0,\r
43514 y: 0\r
43515 },\r
43516 \r
43517 minPosition: {\r
43518 x: 0,\r
43519 y: 0\r
43520 },\r
43521 \r
43522 minUserPosition: {\r
43523 x: 0,\r
43524 y: 0\r
43525 },\r
43526 \r
43527 momentumEasing: null,\r
43528 \r
43529 size: null,\r
43530 \r
43531 slotSnapSize: {\r
43532 x: 0,\r
43533 y: 0\r
43534 },\r
43535 \r
43536 x: true,\r
43537 \r
43538 y: true,\r
43539 spacerXY: null\r
43540 },\r
43541 statics: {\r
43542 \r
43543 create: function(config) {\r
43544 return Ext.Factory.scroller(config, Ext.supports.Touch ? 'touch' : 'dom');\r
43545 }\r
43546 },\r
43547 constructor: function(config) {\r
43548 var me = this;\r
43549 me.position = {\r
43550 x: 0,\r
43551 y: 0\r
43552 };\r
43553 me.callParent([\r
43554 config\r
43555 ]);\r
43556 me.onDomScrollEnd = Ext.Function.createBuffered(me.onDomScrollEnd, 100, me);\r
43557 },\r
43558 destroy: function() {\r
43559 var me = this;\r
43560
43561 me.setX(Ext.emptyString);\r
43562 me.setY(Ext.emptyString);\r
43563
43564 me.setElement(null);\r
43565 me.onDomScrollEnd = me._partners = me.component = null;\r
43566 me.callParent();\r
43567 },\r
43568 \r
43569 addPartner: function(partner, axis) {\r
43570 var me = this,\r
43571 partners = me._partners || (me._partners = {}),\r
43572 otherPartners = partner._partners || (partner._partners = {});\r
43573 partners[partner.getId()] = {\r
43574 scroller: partner,\r
43575 axis: axis\r
43576 };\r
43577 otherPartners[me.getId()] = {\r
43578 scroller: me,\r
43579 axis: axis\r
43580 };\r
43581 },\r
43582 applyElement: function(element, oldElement) {\r
43583 var me = this,\r
43584 el, eventSource;\r
43585
43586 if (oldElement) {\r
43587 me.scrollListener.destroy();\r
43588 }\r
43589 if (element) {\r
43590 if (element.isElement) {\r
43591 el = element;\r
43592 } else {\r
43593 el = Ext.get(element);\r
43594
43595 if (!el && (typeof element === 'string')) {\r
43596 Ext.raise("Cannot create Ext.scroll.Scroller instance. " + "Element with id '" + element + "' not found.");\r
43597 }\r
43598 }\r
43599
43600
43601
43602 if (el.dom === document.body) {\r
43603 el = Ext.get(document.scrollingElement || (Ext.isWebKit ? document.body : document.documentElement));\r
43604
43605
43606 eventSource = Ext.get(Ext.isIE9m ? window : document);\r
43607 } else {\r
43608 eventSource = el;\r
43609 }\r
43610 me.scrollListener = eventSource.on({\r
43611 scroll: me.onDomScroll,\r
43612 scope: me,\r
43613 destroyable: true\r
43614 });\r
43615 return el;\r
43616 }\r
43617 },\r
43618 \r
43619 getClientSize: function() {\r
43620 var dom = this.getElement().dom;\r
43621 return {\r
43622 x: dom.clientWidth,\r
43623 y: dom.clientHeight\r
43624 };\r
43625 },\r
43626 \r
43627 \r
43628 getScrollbarSize: function() {\r
43629 var me = this,\r
43630 width = 0,\r
43631 height = 0,\r
43632 element, dom, x, y, hasXScroll, hasYScroll, scrollbarSize;\r
43633 if (me.isDomScroller || Ext.supports.touchScroll === 1) {\r
43634 element = me.getElement();\r
43635 if (element && !element.destroyed) {\r
43636 x = me.getX();\r
43637 y = me.getY();\r
43638 dom = element.dom;\r
43639 if (x || y) {\r
43640 scrollbarSize = Ext.getScrollbarSize();\r
43641 }\r
43642 if (x === 'scroll') {\r
43643 hasXScroll = true;\r
43644 } else if (x) {\r
43645 hasXScroll = dom.scrollWidth > dom.clientWidth;\r
43646 }\r
43647 if (y === 'scroll') {\r
43648 hasYScroll = true;\r
43649 } else if (y) {\r
43650 hasYScroll = dom.scrollHeight > dom.clientHeight;\r
43651 }\r
43652 if (hasXScroll) {\r
43653 height = scrollbarSize.height;\r
43654 }\r
43655 if (hasYScroll) {\r
43656 width = scrollbarSize.width;\r
43657 }\r
43658 }\r
43659 }\r
43660 return {\r
43661 width: width,\r
43662 height: height\r
43663 };\r
43664 },\r
43665 getPosition: function() {\r
43666
43667
43668 return this.position;\r
43669 },\r
43670
43671 updateDirectionLock: Ext.emptyFn,\r
43672 updateDisabled: Ext.emptyFn,\r
43673 updateIndicators: Ext.emptyFn,\r
43674 updateMaxPosition: Ext.emptyFn,\r
43675 updateMaxUserPosition: Ext.emptyFn,\r
43676 updateMinPosition: Ext.emptyFn,\r
43677 updateMinUserPosition: Ext.emptyFn,\r
43678 updateMomenumEasing: Ext.emptyFn,\r
43679 updateX: Ext.emptyFn,\r
43680 updateY: Ext.emptyFn,\r
43681 onPartnerScrollStart: Ext.emptyFn,\r
43682 onPartnerScrollEnd: Ext.emptyFn,\r
43683 \r
43684 \r
43685 \r
43686 \r
43687 \r
43688 refresh: function() {\r
43689 this.fireEvent('refresh', this);\r
43690 return this;\r
43691 },\r
43692 \r
43693 removePartner: function(partner) {\r
43694 var partners = this._partners,\r
43695 otherPartners = partner._partners;\r
43696 if (partners) {\r
43697 delete partners[partner.getId()];\r
43698 }\r
43699 if (otherPartners) {\r
43700 delete (otherPartners[this.getId()]);\r
43701 }\r
43702 },\r
43703 \r
43704 scrollBy: function(deltaX, deltaY, animate) {\r
43705 var position = this.getPosition();\r
43706 if (deltaX) {\r
43707 if (deltaX.length) {\r
43708
43709 animate = deltaY;\r
43710 deltaY = deltaX[1];\r
43711 deltaX = deltaX[0];\r
43712 } else if (typeof deltaX !== 'number') {\r
43713
43714 animate = deltaY;\r
43715 deltaY = deltaX.y;\r
43716 deltaX = deltaX.x;\r
43717 }\r
43718 }\r
43719 deltaX = (typeof deltaX === 'number') ? deltaX + position.x : null;\r
43720 deltaY = (typeof deltaY === 'number') ? deltaY + position.y : null;\r
43721 return this.doScrollTo(deltaX, deltaY, animate);\r
43722 },\r
43723 \r
43724 scrollIntoView: function(el, hscroll, animate, highlight) {\r
43725 var me = this,\r
43726 position = me.getPosition(),\r
43727 newPosition, newX, newY,\r
43728 myEl = me.getElement();\r
43729
43730 if (el) {\r
43731 newPosition = Ext.fly(el).getScrollIntoViewXY(myEl, position.x, position.y);\r
43732 newX = (hscroll === false) ? position.x : newPosition.x;\r
43733 newY = newPosition.y;\r
43734 if (highlight) {\r
43735 me.on({\r
43736 scrollend: 'doHighlight',\r
43737 scope: me,\r
43738 single: true,\r
43739 args: [\r
43740 el,\r
43741 highlight\r
43742 ]\r
43743 });\r
43744 }\r
43745 me.doScrollTo(newX, newY, animate);\r
43746 }\r
43747 },\r
43748 \r
43749 isInView: function(el) {\r
43750 var me = this,\r
43751 result = {\r
43752 x: false,\r
43753 y: false\r
43754 },\r
43755 elRegion,\r
43756 myEl = me.getElement(),\r
43757 myElRegion;\r
43758 if (el && myEl.contains(el)) {\r
43759 myElRegion = myEl.getRegion();\r
43760 elRegion = Ext.fly(el).getRegion();\r
43761 result.x = elRegion.right > myElRegion.left && elRegion.left < myElRegion.right;\r
43762 result.y = elRegion.bottom > myElRegion.top && elRegion.top < myElRegion.bottom;\r
43763 }\r
43764 return result;\r
43765 },\r
43766 \r
43767 scrollTo: function(x, y, animate) {\r
43768 var maxPosition;\r
43769 if (x) {\r
43770 if (x.length) {\r
43771
43772 animate = y;\r
43773 y = x[1];\r
43774 x = x[0];\r
43775 } else if (typeof x !== 'number') {\r
43776
43777 animate = y;\r
43778 y = x.y;\r
43779 x = x.x;\r
43780 }\r
43781 }\r
43782 if (x < 0 || y < 0) {\r
43783 maxPosition = this.getMaxPosition();\r
43784 if (x < 0) {\r
43785 x += maxPosition.x;\r
43786 }\r
43787 if (y < 0) {\r
43788 y += maxPosition.y;\r
43789 }\r
43790 }\r
43791 this.doScrollTo(x, y, animate);\r
43792 },\r
43793 updateDirection: function(direction) {\r
43794 var me = this,\r
43795 x, y;\r
43796 if (!direction) {\r
43797
43798
43799
43800 x = me.getX();\r
43801 y = me.getY();\r
43802 if (x && y) {\r
43803 direction = (y === 'scroll' && x === 'scroll') ? 'both' : 'auto';\r
43804 } else if (y) {\r
43805 direction = 'vertical';\r
43806 } else if (x) {\r
43807 direction = 'horizontal';\r
43808 }\r
43809
43810
43811 me._direction = direction;\r
43812 } else {\r
43813 if (direction === 'auto') {\r
43814 x = true;\r
43815 y = true;\r
43816 } else if (direction === 'vertical') {\r
43817 x = false;\r
43818 y = true;\r
43819 } else if (direction === 'horizontal') {\r
43820 x = true;\r
43821 y = false;\r
43822 } else if (direction === 'both') {\r
43823 x = 'scroll';\r
43824 y = 'scroll';\r
43825 }\r
43826 me.setX(x);\r
43827 me.setY(y);\r
43828 }\r
43829 },\r
43830 updateSize: function(size) {\r
43831
43832
43833 var me = this,\r
43834 element = me.getElement(),\r
43835 spacer, x, y;\r
43836 if (element) {\r
43837 spacer = me.getSpacer();\r
43838
43839
43840
43841
43842 if (size == null) {\r
43843 spacer.hide();\r
43844 } else {\r
43845 if (typeof size === 'number') {\r
43846 x = size;\r
43847 y = size;\r
43848 } else {\r
43849 x = size.x || 0;\r
43850 y = size.y || 0;\r
43851 }\r
43852
43853 if (x > 0) {\r
43854 x -= 1;\r
43855 }\r
43856 if (y > 0) {\r
43857 y -= 1;\r
43858 }\r
43859 me.setSpacerXY({\r
43860 x: x,\r
43861 y: y\r
43862 });\r
43863 spacer.show();\r
43864 }\r
43865 }\r
43866 },\r
43867 deprecated: {\r
43868 '5': {\r
43869 methods: {\r
43870 \r
43871 getScroller: function() {\r
43872 return this;\r
43873 }\r
43874 }\r
43875 },\r
43876 '5.1.0': {\r
43877 methods: {\r
43878 \r
43879 scrollToTop: function(animate) {\r
43880 return this.scrollTo(0, 0, animate);\r
43881 },\r
43882 \r
43883 scrollToEnd: function(animate) {\r
43884 return this.scrollTo(Infinity, Infinity, animate);\r
43885 }\r
43886 }\r
43887 }\r
43888 },\r
43889 privates: {\r
43890 getSpacer: function() {\r
43891 var me = this,\r
43892 spacer = me._spacer,\r
43893 element;\r
43894
43895
43896
43897
43898 if (!spacer) {\r
43899 element = me.getElement();\r
43900 spacer = me._spacer = element.createChild({\r
43901 cls: me._spacerCls,\r
43902 role: 'presentation'\r
43903 });\r
43904 spacer.setVisibilityMode(2);\r
43905
43906
43907
43908 element.position();\r
43909 }\r
43910 return spacer;\r
43911 },\r
43912 applySpacerXY: function(pos, oldPos) {\r
43913
43914 if (oldPos && pos.x === oldPos.x && pos.y === oldPos.y) {\r
43915 pos = undefined;\r
43916 }\r
43917 return pos;\r
43918 },\r
43919
43920 updateSpacerXY: function(pos) {\r
43921 this.getSpacer().setLocalXY(pos.x, pos.y);\r
43922 },\r
43923
43924 convertX: function(x) {\r
43925 return x;\r
43926 },\r
43927
43928 doHighlight: function(el, highlight) {\r
43929 if (highlight !== true) {\r
43930
43931 Ext.fly(el).highlight(highlight);\r
43932 } else {\r
43933 Ext.fly(el).highlight();\r
43934 }\r
43935 },\r
43936 fireScrollStart: function(x, y) {\r
43937 var me = this,\r
43938 component = me.component;\r
43939 me.invokePartners('onPartnerScrollStart', x, y);\r
43940 if (me.hasListeners.scrollstart) {\r
43941 me.fireEvent('scrollstart', me, x, y);\r
43942 }\r
43943 if (component && component.onScrollStart) {\r
43944 component.onScrollStart(x, y);\r
43945 }\r
43946 Ext.GlobalEvents.fireEvent('scrollstart', me, x, y);\r
43947 },\r
43948 fireScroll: function(x, y) {\r
43949 var me = this,\r
43950 component = me.component;\r
43951 me.invokePartners('onPartnerScroll', x, y);\r
43952 if (me.hasListeners.scroll) {\r
43953 me.fireEvent('scroll', me, x, y);\r
43954 }\r
43955 if (component && component.onScrollMove) {\r
43956 component.onScrollMove(x, y);\r
43957 }\r
43958 Ext.GlobalEvents.fireEvent('scroll', me, x, y);\r
43959 },\r
43960 fireScrollEnd: function(x, y) {\r
43961 var me = this,\r
43962 component = me.component;\r
43963 me.invokePartners('onPartnerScrollEnd', x, y);\r
43964 if (me.hasListeners.scrollend) {\r
43965 me.fireEvent('scrollend', me, x, y);\r
43966 }\r
43967 if (component && component.onScrollEnd) {\r
43968 component.onScrollEnd(x, y);\r
43969 }\r
43970 Ext.GlobalEvents.fireEvent('scrollend', me, x, y);\r
43971 },\r
43972 initXStyle: function() {\r
43973 var element = this.getElement(),\r
43974 x = this.getX();\r
43975
43976 if (element && element.dom) {\r
43977 if (!x) {\r
43978 x = 'hidden';\r
43979 } else if (x === true) {\r
43980 x = 'auto';\r
43981 }\r
43982 element.setStyle('overflow-x', x);\r
43983 }\r
43984 },\r
43985 initYStyle: function() {\r
43986 var element = this.getElement(),\r
43987 y = this.getY();\r
43988
43989 if (element && element.dom) {\r
43990 if (!y) {\r
43991 y = 'hidden';\r
43992 } else if (y === true) {\r
43993 y = 'auto';\r
43994 }\r
43995 element.setStyle('overflow-y', y);\r
43996 }\r
43997 },\r
43998 invokePartners: function(method, x, y) {\r
43999 var me = this,\r
44000 partners = me._partners,\r
44001 partner, id,\r
44002 isEnd = method === 'onPartnerScrollEnd';\r
44003
44004 if (!me.suspendSync & !me.isReflecting) {\r
44005 for (id in partners) {\r
44006 partner = partners[id].scroller;\r
44007 partner.isReflecting = true;\r
44008 partner[method](me, x, y);\r
44009
44010 if (isEnd) {\r
44011 partner.isReflecting = false;\r
44012 }\r
44013 }\r
44014 }\r
44015 },\r
44016 clearReflecting: function() {\r
44017 this.isReflecting = false;\r
44018 },\r
44019 suspendPartnerSync: function() {\r
44020 this.suspendSync = (this.suspendSync || 0) + 1;\r
44021 },\r
44022 resumePartnerSync: function() {\r
44023 if (this.suspendSync) {\r
44024 this.suspendSync--;\r
44025 }\r
44026 },\r
44027 updateDomScrollPosition: function() {\r
44028 var me = this,\r
44029 element = me.getElement(),\r
44030 elScroll,\r
44031 position = me.position;\r
44032 if (element && !element.destroyed) {\r
44033 elScroll = me.getElementScroll(element);\r
44034 position.x = elScroll.left;\r
44035 position.y = elScroll.top;\r
44036 }\r
44037 me.positionDirty = false;\r
44038 return position;\r
44039 },\r
44040
44041 getElementScroll: function(element) {\r
44042 return element.getScroll();\r
44043 },\r
44044
44045
44046
44047
44048
44049
44050
44051
44052
44053 onDomScroll: function() {\r
44054 var me = this,\r
44055 position, x, y, el;\r
44056
44057
44058
44059
44060 if (me.isTouchScroller && Ext.supports.touchScroll === 2) {\r
44061 el = me.getElement().dom;\r
44062 el.scrollTop = el.scrollLeft = 0;\r
44063 return;\r
44064 }\r
44065 position = me.updateDomScrollPosition();\r
44066 x = position.x;\r
44067 y = position.y;\r
44068 if (!me.isScrolling) {\r
44069 me.isScrolling = Ext.isScrolling = true;\r
44070 me.fireScrollStart(x, y);\r
44071 }\r
44072 me.fireScroll(x, y);\r
44073
44074
44075 me.onDomScrollEnd();\r
44076 },\r
44077 onDomScrollEnd: function() {\r
44078 var me = this,\r
44079 position = me.getPosition(),\r
44080 x = position.x,\r
44081 y = position.y;\r
44082 me.isScrolling = Ext.isScrolling = false;\r
44083 me.trackingScrollLeft = x;\r
44084 me.trackingScrollTop = y;\r
44085 me.fireScrollEnd(x, y);\r
44086 },\r
44087 onPartnerScroll: function(partner, x, y) {\r
44088 var axis = partner._partners[this.getId()].axis;\r
44089 if (axis) {\r
44090 if (axis === 'x') {\r
44091 y = null;\r
44092 } else if (axis === 'y') {\r
44093 x = null;\r
44094 }\r
44095 }\r
44096 this.doScrollTo(x, y, false, true);\r
44097 },\r
44098 restoreState: function() {\r
44099 var me = this,\r
44100 el = me.getElement(),\r
44101 dom;\r
44102 if (el) {\r
44103 dom = el.dom;\r
44104
44105
44106 if (me.trackingScrollTop !== undefined) {\r
44107 dom.scrollTop = me.trackingScrollTop;\r
44108 dom.scrollLeft = me.trackingScrollLeft;\r
44109 }\r
44110 }\r
44111 }\r
44112 }\r
44113});\r
44114\r
44115\r
44116Ext.define('Ext.fx.easing.Abstract', {\r
44117 config: {\r
44118 startTime: 0,\r
44119 startValue: 0\r
44120 },\r
44121 isEasing: true,\r
44122 isEnded: false,\r
44123 constructor: function(config) {\r
44124 this.initConfig(config);\r
44125 return this;\r
44126 },\r
44127 applyStartTime: function(startTime) {\r
44128 if (!startTime) {\r
44129 startTime = Ext.Date.now();\r
44130 }\r
44131 return startTime;\r
44132 },\r
44133 updateStartTime: function(startTime) {\r
44134 this.reset();\r
44135 },\r
44136 reset: function() {\r
44137 this.isEnded = false;\r
44138 },\r
44139 getValue: Ext.emptyFn\r
44140});\r
44141\r
44142\r
44143Ext.define('Ext.fx.easing.Momentum', {\r
44144 extend: Ext.fx.easing.Abstract,\r
44145 config: {\r
44146 acceleration: 30,\r
44147 friction: 0,\r
44148 startVelocity: 0\r
44149 },\r
44150 alpha: 0,\r
44151 updateFriction: function(friction) {\r
44152 var theta = Math.log(1 - (friction / 10));\r
44153 this.theta = theta;\r
44154 this.alpha = theta / this.getAcceleration();\r
44155 },\r
44156 updateStartVelocity: function(velocity) {\r
44157 this.velocity = velocity * this.getAcceleration();\r
44158 },\r
44159 updateAcceleration: function(acceleration) {\r
44160 this.velocity = this.getStartVelocity() * acceleration;\r
44161 this.alpha = this.theta / acceleration;\r
44162 },\r
44163 getValue: function() {\r
44164 return this.getStartValue() - this.velocity * (1 - this.getFrictionFactor()) / this.theta;\r
44165 },\r
44166 getFrictionFactor: function() {\r
44167 var deltaTime = Ext.Date.now() - this.getStartTime();\r
44168 return Math.exp(deltaTime * this.alpha);\r
44169 },\r
44170 getVelocity: function() {\r
44171 return this.getFrictionFactor() * this.velocity;\r
44172 }\r
44173});\r
44174\r
44175\r
44176Ext.define('Ext.fx.easing.Bounce', {\r
44177 extend: Ext.fx.easing.Abstract,\r
44178 config: {\r
44179 springTension: 0.3,\r
44180 acceleration: 30,\r
44181 startVelocity: 0\r
44182 },\r
44183 getValue: function() {\r
44184 var deltaTime = Ext.Date.now() - this.getStartTime(),\r
44185 theta = (deltaTime / this.getAcceleration()),\r
44186 powTime = theta * Math.pow(Math.E, -this.getSpringTension() * theta);\r
44187 return this.getStartValue() + (this.getStartVelocity() * powTime);\r
44188 }\r
44189});\r
44190\r
44191\r
44192Ext.define('Ext.fx.easing.BoundMomentum', {\r
44193 extend: Ext.fx.easing.Abstract,\r
44194 config: {\r
44195 \r
44196 momentum: null,\r
44197 \r
44198 bounce: null,\r
44199 minMomentumValue: 0,\r
44200 maxMomentumValue: 0,\r
44201 \r
44202 minVelocity: 0.01,\r
44203 \r
44204 startVelocity: 0\r
44205 },\r
44206 applyMomentum: function(config, currentEasing) {\r
44207 return Ext.factory(config, Ext.fx.easing.Momentum, currentEasing);\r
44208 },\r
44209 applyBounce: function(config, currentEasing) {\r
44210 return Ext.factory(config, Ext.fx.easing.Bounce, currentEasing);\r
44211 },\r
44212 updateStartTime: function(startTime) {\r
44213 this.getMomentum().setStartTime(startTime);\r
44214 this.callParent(arguments);\r
44215 },\r
44216 updateStartVelocity: function(startVelocity) {\r
44217 this.getMomentum().setStartVelocity(startVelocity);\r
44218 },\r
44219 updateStartValue: function(startValue) {\r
44220 this.getMomentum().setStartValue(startValue);\r
44221 },\r
44222 reset: function() {\r
44223 this.lastValue = null;\r
44224 this.isBouncingBack = false;\r
44225 this.isOutOfBound = false;\r
44226 return this.callParent(arguments);\r
44227 },\r
44228 getValue: function() {\r
44229 var momentum = this.getMomentum(),\r
44230 bounce = this.getBounce(),\r
44231 startVelocity = momentum.getStartVelocity(),\r
44232 direction = startVelocity > 0 ? 1 : -1,\r
44233 minValue = this.getMinMomentumValue(),\r
44234 maxValue = this.getMaxMomentumValue(),\r
44235 boundedValue = (direction == 1) ? maxValue : minValue,\r
44236 lastValue = this.lastValue,\r
44237 value, velocity;\r
44238 if (startVelocity === 0) {\r
44239 return this.getStartValue();\r
44240 }\r
44241 if (!this.isOutOfBound) {\r
44242 value = momentum.getValue();\r
44243 velocity = momentum.getVelocity();\r
44244 if (Math.abs(velocity) < this.getMinVelocity()) {\r
44245 this.isEnded = true;\r
44246 }\r
44247 if (value >= minValue && value <= maxValue) {\r
44248 return value;\r
44249 }\r
44250 this.isOutOfBound = true;\r
44251 bounce.setStartTime(Ext.Date.now()).setStartVelocity(velocity).setStartValue(boundedValue);\r
44252 }\r
44253 value = bounce.getValue();\r
44254 if (!this.isEnded) {\r
44255 if (!this.isBouncingBack) {\r
44256 if (lastValue !== null) {\r
44257 if ((direction == 1 && value < lastValue) || (direction == -1 && value > lastValue)) {\r
44258 this.isBouncingBack = true;\r
44259 }\r
44260 }\r
44261 } else {\r
44262 if (Math.round(value) == boundedValue) {\r
44263 this.isEnded = true;\r
44264 }\r
44265 }\r
44266 }\r
44267 this.lastValue = value;\r
44268 return value;\r
44269 }\r
44270});\r
44271\r
44272\r
44273Ext.define('Ext.fx.easing.Linear', {\r
44274 extend: Ext.fx.easing.Abstract,\r
44275 alias: 'easing.linear',\r
44276 config: {\r
44277 duration: 0,\r
44278 endValue: 0\r
44279 },\r
44280 updateStartValue: function(startValue) {\r
44281 this.distance = this.getEndValue() - startValue;\r
44282 },\r
44283 updateEndValue: function(endValue) {\r
44284 this.distance = endValue - this.getStartValue();\r
44285 },\r
44286 getValue: function() {\r
44287 var deltaTime = Ext.Date.now() - this.getStartTime(),\r
44288 duration = this.getDuration();\r
44289 if (deltaTime > duration) {\r
44290 this.isEnded = true;\r
44291 return this.getEndValue();\r
44292 } else {\r
44293 return this.getStartValue() + ((deltaTime / duration) * this.distance);\r
44294 }\r
44295 }\r
44296});\r
44297\r
44298\r
44299Ext.define('Ext.fx.easing.EaseOut', {\r
44300 extend: Ext.fx.easing.Linear,\r
44301 alias: 'easing.ease-out',\r
44302 config: {\r
44303 exponent: 4,\r
44304 duration: 1500\r
44305 },\r
44306 getValue: function() {\r
44307 var deltaTime = Ext.Date.now() - this.getStartTime(),\r
44308 duration = this.getDuration(),\r
44309 startValue = this.getStartValue(),\r
44310 endValue = this.getEndValue(),\r
44311 distance = this.distance,\r
44312 theta = deltaTime / duration,\r
44313 thetaC = 1 - theta,\r
44314 thetaEnd = 1 - Math.pow(thetaC, this.getExponent()),\r
44315 currentValue = startValue + (thetaEnd * distance);\r
44316 if (deltaTime >= duration) {\r
44317 this.isEnded = true;\r
44318 return endValue;\r
44319 }\r
44320 return currentValue;\r
44321 }\r
44322});\r
44323\r
44324\r
44325Ext.define('Ext.util.translatable.Abstract', {\r
44326 extend: Ext.Evented,\r
44327 config: {\r
44328 useWrapper: null,\r
44329 easing: null,\r
44330 easingX: null,\r
44331 easingY: null\r
44332 },\r
44333 \r
44334 \r
44335 \r
44336 \r
44337 x: 0,\r
44338 \r
44339 y: 0,\r
44340 activeEasingX: null,\r
44341 activeEasingY: null,\r
44342 isAnimating: false,\r
44343 isTranslatable: true,\r
44344 constructor: function(config) {\r
44345 this.mixins.observable.constructor.call(this, config);\r
44346
44347
44348
44349 this.position = {\r
44350 x: 0,\r
44351 y: 0\r
44352 };\r
44353 },\r
44354 factoryEasing: function(easing) {\r
44355 return Ext.factory(easing, Ext.fx.easing.Linear, null, 'easing');\r
44356 },\r
44357 applyEasing: function(easing) {\r
44358 if (!this.getEasingX()) {\r
44359 this.setEasingX(this.factoryEasing(easing));\r
44360 }\r
44361 if (!this.getEasingY()) {\r
44362 this.setEasingY(this.factoryEasing(easing));\r
44363 }\r
44364 },\r
44365 applyEasingX: function(easing) {\r
44366 return this.factoryEasing(easing);\r
44367 },\r
44368 applyEasingY: function(easing) {\r
44369 return this.factoryEasing(easing);\r
44370 },\r
44371 doTranslate: Ext.emptyFn,\r
44372 translate: function(x, y, animation) {\r
44373 if (animation) {\r
44374 return this.translateAnimated(x, y, animation);\r
44375 }\r
44376 if (this.isAnimating) {\r
44377 this.stopAnimation();\r
44378 }\r
44379 if (!isNaN(x) && typeof x == 'number') {\r
44380 this.x = x;\r
44381 }\r
44382 if (!isNaN(y) && typeof y == 'number') {\r
44383 this.y = y;\r
44384 }\r
44385 this.doTranslate(x, y);\r
44386 },\r
44387 translateAxis: function(axis, value, animation) {\r
44388 var x, y;\r
44389 if (axis == 'x') {\r
44390 x = value;\r
44391 } else {\r
44392 y = value;\r
44393 }\r
44394 return this.translate(x, y, animation);\r
44395 },\r
44396 \r
44397 getPosition: function() {\r
44398 var me = this,\r
44399 position = me.position;\r
44400 position.x = -me.x;\r
44401 position.y = -me.y;\r
44402 return position;\r
44403 },\r
44404 animate: function(easingX, easingY) {\r
44405 this.activeEasingX = easingX;\r
44406 this.activeEasingY = easingY;\r
44407 this.isAnimating = true;\r
44408 this.lastX = null;\r
44409 this.lastY = null;\r
44410 Ext.AnimationQueue.start(this.doAnimationFrame, this);\r
44411 this.fireEvent('animationstart', this, this.x, this.y);\r
44412 return this;\r
44413 },\r
44414 translateAnimated: function(x, y, animation) {\r
44415 var me = this;\r
44416 if (!Ext.isObject(animation)) {\r
44417 animation = {};\r
44418 }\r
44419 if (me.isAnimating) {\r
44420 me.stopAnimation();\r
44421 }\r
44422
44423 me.callback = animation.callback;\r
44424 me.callbackScope = animation.scope;\r
44425 var now = Ext.Date.now(),\r
44426 easing = animation.easing,\r
44427 easingX = (typeof x == 'number') ? (animation.easingX || easing || me.getEasingX() || true) : null,\r
44428 easingY = (typeof y == 'number') ? (animation.easingY || easing || me.getEasingY() || true) : null;\r
44429 if (easingX) {\r
44430 easingX = me.factoryEasing(easingX);\r
44431 easingX.setStartTime(now);\r
44432 easingX.setStartValue(me.x);\r
44433 easingX.setEndValue(x);\r
44434 if ('duration' in animation) {\r
44435 easingX.setDuration(animation.duration);\r
44436 }\r
44437 }\r
44438 if (easingY) {\r
44439 easingY = me.factoryEasing(easingY);\r
44440 easingY.setStartTime(now);\r
44441 easingY.setStartValue(me.y);\r
44442 easingY.setEndValue(y);\r
44443 if ('duration' in animation) {\r
44444 easingY.setDuration(animation.duration);\r
44445 }\r
44446 }\r
44447 return me.animate(easingX, easingY);\r
44448 },\r
44449 doAnimationFrame: function() {\r
44450 var me = this,\r
44451 easingX = me.activeEasingX,\r
44452 easingY = me.activeEasingY,\r
44453 now = Date.now(),\r
44454 x, y;\r
44455 if (!me.isAnimating) {\r
44456 return;\r
44457 }\r
44458 me.lastRun = now;\r
44459 if (easingX === null && easingY === null) {\r
44460 me.stopAnimation();\r
44461 return;\r
44462 }\r
44463 if (easingX !== null) {\r
44464 me.x = x = Math.round(easingX.getValue());\r
44465 if (easingX.isEnded) {\r
44466 me.activeEasingX = null;\r
44467 me.fireEvent('axisanimationend', me, 'x', x);\r
44468 }\r
44469 } else {\r
44470 x = me.x;\r
44471 }\r
44472 if (easingY !== null) {\r
44473 me.y = y = Math.round(easingY.getValue());\r
44474 if (easingY.isEnded) {\r
44475 me.activeEasingY = null;\r
44476 me.fireEvent('axisanimationend', me, 'y', y);\r
44477 }\r
44478 } else {\r
44479 y = me.y;\r
44480 }\r
44481 if (me.lastX !== x || me.lastY !== y) {\r
44482 me.doTranslate(x, y);\r
44483 me.lastX = x;\r
44484 me.lastY = y;\r
44485 }\r
44486 me.fireEvent('animationframe', me, x, y);\r
44487 },\r
44488 stopAnimation: function() {\r
44489 var me = this;\r
44490 if (!me.isAnimating) {\r
44491 return;\r
44492 }\r
44493 me.activeEasingX = null;\r
44494 me.activeEasingY = null;\r
44495 me.isAnimating = false;\r
44496 Ext.AnimationQueue.stop(me.doAnimationFrame, me);\r
44497 me.fireEvent('animationend', me, me.x, me.y);\r
44498 if (me.callback) {\r
44499 me.callback.call(me.callbackScope);\r
44500 me.callback = null;\r
44501 }\r
44502 },\r
44503 refresh: function() {\r
44504 this.translate(this.x, this.y);\r
44505 },\r
44506 destroy: function() {\r
44507 if (this.isAnimating) {\r
44508 this.stopAnimation();\r
44509 }\r
44510 this.callParent();\r
44511 }\r
44512});\r
44513\r
44514\r
44515Ext.define('Ext.util.translatable.Dom', {\r
44516 extend: Ext.util.translatable.Abstract,\r
44517 config: {\r
44518 element: null\r
44519 },\r
44520 applyElement: function(element) {\r
44521 if (!element) {\r
44522 return;\r
44523 }\r
44524 return Ext.get(element);\r
44525 },\r
44526 updateElement: function() {\r
44527 this.refresh();\r
44528 }\r
44529});\r
44530\r
44531\r
44532Ext.define('Ext.util.translatable.CssTransform', {\r
44533 extend: Ext.util.translatable.Dom,\r
44534 doTranslate: function(x, y) {\r
44535 var element = this.getElement();\r
44536 if (!this.destroyed && !element.destroyed) {\r
44537 element.translate(x, y);\r
44538 }\r
44539 },\r
44540 destroy: function() {\r
44541 var element = this.getElement();\r
44542 if (element && !element.destroyed) {\r
44543 element.dom.style.webkitTransform = null;\r
44544 }\r
44545 this.callParent();\r
44546 }\r
44547});\r
44548\r
44549\r
44550Ext.define('Ext.util.translatable.ScrollPosition', {\r
44551 extend: Ext.util.translatable.Dom,\r
44552 type: 'scrollposition',\r
44553 config: {\r
44554 useWrapper: true\r
44555 },\r
44556 getWrapper: function() {\r
44557 var wrapper = this.wrapper,\r
44558 element = this.getElement(),\r
44559 container;\r
44560 if (!wrapper) {\r
44561 container = element.getParent();\r
44562 if (!container) {\r
44563 return null;\r
44564 }\r
44565 if (container.hasCls(Ext.baseCSSPrefix + 'translatable-hboxfix')) {\r
44566 container = container.getParent();\r
44567 }\r
44568 if (this.getUseWrapper()) {\r
44569 wrapper = element.wrap();\r
44570 } else {\r
44571 wrapper = container;\r
44572 }\r
44573 element.addCls(Ext.baseCSSPrefix + 'translatable');\r
44574 wrapper.addCls(Ext.baseCSSPrefix + 'translatable-container');\r
44575 this.wrapper = wrapper;\r
44576 wrapper.on('painted', function() {\r
44577 if (!this.isAnimating) {\r
44578 this.refresh();\r
44579 }\r
44580 }, this);\r
44581 this.refresh();\r
44582 }\r
44583 return wrapper;\r
44584 },\r
44585 doTranslate: function(x, y) {\r
44586 var wrapper = this.getWrapper(),\r
44587 dom;\r
44588 if (wrapper) {\r
44589 dom = wrapper.dom;\r
44590 if (typeof x == 'number') {\r
44591 dom.scrollLeft = 500000 - x;\r
44592 }\r
44593 if (typeof y == 'number') {\r
44594 dom.scrollTop = 500000 - y;\r
44595 }\r
44596 }\r
44597 },\r
44598 destroy: function() {\r
44599 var me = this,\r
44600 element = me.getElement(),\r
44601 wrapper = me.wrapper;\r
44602 if (wrapper) {\r
44603 if (!element.destroyed) {\r
44604 if (me.getUseWrapper()) {\r
44605 wrapper.doReplaceWith(element);\r
44606 }\r
44607 element.removeCls(Ext.baseCSSPrefix + 'translatable');\r
44608 }\r
44609 if (!wrapper.destroyed) {\r
44610 wrapper.removeCls(Ext.baseCSSPrefix + 'translatable-container');\r
44611 wrapper.un('painted', 'refresh', me);\r
44612 }\r
44613 delete me.wrapper;\r
44614 delete me._element;\r
44615 }\r
44616 me.callParent();\r
44617 }\r
44618});\r
44619\r
44620\r
44621Ext.define('Ext.util.translatable.ScrollParent', {\r
44622 extend: Ext.util.translatable.Dom,\r
44623 isScrollParent: true,\r
44624 applyElement: function(element) {\r
44625 var el = Ext.get(element);\r
44626 if (el) {\r
44627 this.parent = el.parent();\r
44628 }\r
44629 return el;\r
44630 },\r
44631 doTranslate: function(x, y) {\r
44632 var parent = this.parent;\r
44633 parent.setScrollLeft(Math.round(-x));\r
44634 parent.setScrollTop(Math.round(-y));\r
44635 },\r
44636 getPosition: function() {\r
44637 var me = this,\r
44638 position = me.position,\r
44639 parent = me.parent;\r
44640 position.x = parent.getScrollLeft();\r
44641 position.y = parent.getScrollTop();\r
44642 return position;\r
44643 }\r
44644});\r
44645\r
44646\r
44647Ext.define('Ext.util.translatable.CssPosition', {\r
44648 extend: Ext.util.translatable.Dom,\r
44649 doTranslate: function(x, y) {\r
44650 var domStyle = this.getElement().dom.style;\r
44651 if (typeof x == 'number') {\r
44652 domStyle.left = x + 'px';\r
44653 }\r
44654 if (typeof y == 'number') {\r
44655 domStyle.top = y + 'px';\r
44656 }\r
44657 },\r
44658 destroy: function() {\r
44659 var domStyle = this.getElement().dom.style;\r
44660 domStyle.left = null;\r
44661 domStyle.top = null;\r
44662 this.callParent();\r
44663 }\r
44664});\r
44665\r
44666\r
44667Ext.define('Ext.util.Translatable', {\r
44668 constructor: function(config) {\r
44669 var namespace = Ext.util.translatable;\r
44670 switch (Ext.browser.getPreferredTranslationMethod(config)) {\r
44671 case 'scrollposition':\r
44672 return new namespace.ScrollPosition(config);\r
44673 case 'scrollparent':\r
44674 return new namespace.ScrollParent(config);\r
44675 case 'csstransform':\r
44676 return new namespace.CssTransform(config);\r
44677 case 'cssposition':\r
44678 return new namespace.CssPosition(config);\r
44679 }\r
44680 }\r
44681});\r
44682\r
44683\r
44684Ext.define('Ext.scroll.Indicator', {\r
44685 extend: Ext.Widget,\r
44686 xtype: 'scrollindicator',\r
44687 config: {\r
44688 \r
44689 axis: null,\r
44690 \r
44691 hideAnimation: true,\r
44692 \r
44693 hideDelay: 0,\r
44694 \r
44695 scroller: null,\r
44696 \r
44697 minLength: 24\r
44698 },\r
44699 defaultHideAnimation: {\r
44700 to: {\r
44701 opacity: 0\r
44702 },\r
44703 duration: 300\r
44704 },\r
44705 names: {\r
44706 x: {\r
44707 side: 'l',\r
44708 getSize: 'getHeight',\r
44709 setLength: 'setWidth',\r
44710 translate: 'translateX'\r
44711 },\r
44712 y: {\r
44713 side: 't',\r
44714 getSize: 'getWidth',\r
44715 setLength: 'setHeight',\r
44716 translate: 'translateY'\r
44717 }\r
44718 },\r
44719 oppositeAxis: {\r
44720 x: 'y',\r
44721 y: 'x'\r
44722 },\r
44723 cls: Ext.baseCSSPrefix + 'scroll-indicator',\r
44724 applyHideAnimation: function(hideAnimation) {\r
44725 if (hideAnimation) {\r
44726 hideAnimation = Ext.mergeIf({\r
44727 onEnd: this.onHideAnimationEnd,\r
44728 scope: this\r
44729 }, this.defaultHideAnimation, hideAnimation);\r
44730 }\r
44731 return hideAnimation;\r
44732 },\r
44733 constructor: function(config) {\r
44734 var me = this,\r
44735 axis;\r
44736 me.callParent([\r
44737 config\r
44738 ]);\r
44739 axis = me.getAxis();\r
44740 me.names = me.names[axis];\r
44741 me.element.addCls(me.cls + ' ' + me.cls + '-' + axis);\r
44742 },\r
44743 \r
44744 hide: function() {\r
44745 var me = this,\r
44746 delay = me.getHideDelay();\r
44747 if (delay) {\r
44748 me._hideTimer = Ext.defer(me.doHide, delay, me);\r
44749 } else {\r
44750 me.doHide();\r
44751 }\r
44752 },\r
44753 \r
44754 setValue: function(value) {\r
44755 var me = this,\r
44756 el = me.element,\r
44757 names = me.names,\r
44758 axis = me.getAxis(),\r
44759 scroller = me.getScroller(),\r
44760 maxScrollPosition = scroller.getMaxUserPosition()[axis],\r
44761 elementSize = scroller.getElementSize()[axis],\r
44762 baseLength = me.length,\r
44763 minLength = me.getMinLength(),\r
44764 length = baseLength,\r
44765 maxPosition = elementSize - baseLength - me.sizeAdjust,\r
44766 round = Math.round,\r
44767 max = Math.max,\r
44768 position;\r
44769 if (value < 0) {\r
44770 length = round(max(baseLength + (baseLength * value / elementSize), minLength));\r
44771 position = 0;\r
44772 } else if (value > maxScrollPosition) {\r
44773 length = round(max(baseLength - (baseLength * (value - maxScrollPosition) / elementSize), minLength));\r
44774 position = maxPosition + baseLength - length;\r
44775 } else {\r
44776 position = round(value / maxScrollPosition * maxPosition);\r
44777 }\r
44778 me[names.translate](position);\r
44779 el[names.setLength](length);\r
44780 },\r
44781 \r
44782 show: function() {\r
44783 var me = this,\r
44784 el = me.element,\r
44785 anim = el.getActiveAnimation();\r
44786 if (anim) {\r
44787 anim.end();\r
44788 }\r
44789 if (!me._inDom) {\r
44790
44791 me.getScroller().getElement().appendChild(el);\r
44792 me._inDom = true;\r
44793 if (!me.size) {\r
44794 me.cacheStyles();\r
44795 }\r
44796 }\r
44797 me.refreshLength();\r
44798 clearTimeout(me._hideTimer);\r
44799 el.setStyle('opacity', '');\r
44800 },\r
44801 privates: {\r
44802 \r
44803 cacheStyles: function() {\r
44804 var me = this,\r
44805 el = me.element,\r
44806 names = me.names;\r
44807 \r
44808 me.size = el[names.getSize]();\r
44809 \r
44810 me.margin = el.getMargin(names.side);\r
44811 },\r
44812 doHide: function() {\r
44813 var animation = this.getHideAnimation(),\r
44814 el = this.element;\r
44815 if (animation) {\r
44816 el.animate(animation);\r
44817 } else {\r
44818 el.setStyle('opacity', 0);\r
44819 }\r
44820 },\r
44821 \r
44822 hasOpposite: function() {\r
44823 return this.getScroller().isAxisEnabled(this.oppositeAxis[this.getAxis()]);\r
44824 },\r
44825 onHideAnimationEnd: function() {\r
44826
44827
44828 this.element.setStyle('opacity', '0');\r
44829 },\r
44830 refreshLength: function() {\r
44831 var me = this,\r
44832 names = me.names,\r
44833 axis = me.getAxis(),\r
44834 scroller = me.getScroller(),\r
44835 scrollSize = scroller.getSize()[axis],\r
44836 elementSize = scroller.getElementSize()[axis],\r
44837 ratio = elementSize / scrollSize,\r
44838 baseSizeAdjust = me.margin * 2,\r
44839 sizeAdjust = me.hasOpposite() ? (baseSizeAdjust + me.size) : baseSizeAdjust,\r
44840 length = Math.max(Math.round((elementSize - sizeAdjust) * ratio), me.getMinLength());\r
44841 me.sizeAdjust = sizeAdjust;\r
44842 \r
44843 me.length = length;\r
44844 me.element[names.setLength](length);\r
44845 },\r
44846 translateX: function(value) {\r
44847 this.element.translate(value);\r
44848 },\r
44849 translateY: function(value) {\r
44850 this.element.translate(0, value);\r
44851 }\r
44852 }\r
44853});\r
44854\r
44855\r
44856Ext.define('Ext.scroll.TouchScroller', {\r
44857 extend: Ext.scroll.Scroller,\r
44858 alias: 'scroller.touch',\r
44859 isTouchScroller: true,\r
44860 config: {\r
44861 \r
44862 autoRefresh: true,\r
44863 \r
44864 bounceEasing: {\r
44865 duration: 400\r
44866 },\r
44867 \r
44868 elementSize: undefined,\r
44869 indicators: true,\r
44870 \r
44871 fps: 'auto',\r
44872 \r
44873 maxAbsoluteVelocity: 6,\r
44874 \r
44875 momentumEasing: {\r
44876 momentum: {\r
44877 acceleration: 30,\r
44878 friction: 0.5\r
44879 },\r
44880 bounce: {\r
44881 acceleration: 30,\r
44882 springTension: 0.3\r
44883 },\r
44884 minVelocity: 1\r
44885 },\r
44886 \r
44887 outOfBoundRestrictFactor: 0.5,\r
44888 \r
44889 innerElement: null,\r
44890 size: undefined,\r
44891 \r
44892 slotSnapEasing: {\r
44893 duration: 150\r
44894 },\r
44895 \r
44896 slotSnapOffset: {\r
44897 x: 0,\r
44898 y: 0\r
44899 },\r
44900 \r
44901 startMomentumResetTime: 300,\r
44902 \r
44903 translatable: {\r
44904 translationMethod: 'auto',\r
44905 useWrapper: false\r
44906 }\r
44907 },\r
44908 cls: Ext.baseCSSPrefix + 'scroll-container',\r
44909 scrollerCls: Ext.baseCSSPrefix + 'scroll-scroller',\r
44910 dragStartTime: 0,\r
44911 dragEndTime: 0,\r
44912 isDragging: false,\r
44913 isAnimating: false,\r
44914 isMouseEvent: {\r
44915 mousedown: 1,\r
44916 mousemove: 1,\r
44917 mouseup: 1\r
44918 },\r
44919 listenerMap: {\r
44920 touchstart: 'onTouchStart',\r
44921 touchmove: 'onTouchMove',\r
44922 dragstart: 'onDragStart',\r
44923 drag: 'onDrag',\r
44924 dragend: 'onDragEnd'\r
44925 },\r
44926 refreshCounter: 0,\r
44927 constructor: function(config) {\r
44928 var me = this,\r
44929 onEvent = 'onEvent';\r
44930 me.elementListeners = {\r
44931 touchstart: onEvent,\r
44932 touchmove: onEvent,\r
44933 dragstart: onEvent,\r
44934 drag: onEvent,\r
44935 dragend: onEvent,\r
44936 scope: me\r
44937 };\r
44938 me.minPosition = {\r
44939 x: 0,\r
44940 y: 0\r
44941 };\r
44942 me.startPosition = {\r
44943 x: 0,\r
44944 y: 0\r
44945 };\r
44946 me.velocity = {\r
44947 x: 0,\r
44948 y: 0\r
44949 };\r
44950 me.isAxisEnabledFlags = {\r
44951 x: false,\r
44952 y: false\r
44953 };\r
44954 me.flickStartPosition = {\r
44955 x: 0,\r
44956 y: 0\r
44957 };\r
44958 me.flickStartTime = {\r
44959 x: 0,\r
44960 y: 0\r
44961 };\r
44962 me.lastDragPosition = {\r
44963 x: 0,\r
44964 y: 0\r
44965 };\r
44966 me.dragDirection = {\r
44967 x: 0,\r
44968 y: 0\r
44969 };\r
44970 me.callParent([\r
44971 config\r
44972 ]);\r
44973 me.refreshAxes();\r
44974 me.scheduleRefresh = {\r
44975 idle: me.doRefresh,\r
44976 scope: me,\r
44977 single: true,\r
44978 destroyable: true\r
44979 };\r
44980 },\r
44981 applyBounceEasing: function(easing) {\r
44982 var defaultClass = Ext.fx.easing.EaseOut;\r
44983 return {\r
44984 x: Ext.factory(easing, defaultClass),\r
44985 y: Ext.factory(easing, defaultClass)\r
44986 };\r
44987 },\r
44988 applyElementSize: function(size) {\r
44989 var el = this.getElement(),\r
44990 dom, x, y;\r
44991 if (!el) {\r
44992 return null;\r
44993 }\r
44994 dom = el.dom;\r
44995 if (!dom) {\r
44996 return;\r
44997 }\r
44998 if (size == null) {\r
44999
45000 x = dom.clientWidth;\r
45001 y = dom.clientHeight;\r
45002 } else {\r
45003 x = size.x;\r
45004 y = size.y;\r
45005 }\r
45006 return {\r
45007 x: x,\r
45008 y: y\r
45009 };\r
45010 },\r
45011 applyIndicators: function(indicators, oldIndicators) {\r
45012 var me = this,\r
45013 xIndicator, yIndicator, x, y;\r
45014 if (indicators) {\r
45015 if (indicators === true) {\r
45016 xIndicator = yIndicator = {};\r
45017 } else {\r
45018 x = indicators.x;\r
45019 y = indicators.y;\r
45020 if (x || y) {\r
45021
45022
45023
45024 xIndicator = (x == null || x === true) ? {} : x;\r
45025 yIndicator = (x == null || y === true) ? {} : y;\r
45026 } else {\r
45027
45028
45029 xIndicator = yIndicator = indicators;\r
45030 }\r
45031 }\r
45032 if (oldIndicators) {\r
45033 if (xIndicator) {\r
45034 oldIndicators.x.setConfig(xIndicator);\r
45035 } else {\r
45036 oldIndicators.x.destroy();\r
45037 oldIndicators.x = null;\r
45038 }\r
45039 if (yIndicator) {\r
45040 oldIndicators.y.setConfig(yIndicator);\r
45041 } else {\r
45042 oldIndicators.y.destroy();\r
45043 oldIndicators.y = null;\r
45044 }\r
45045 indicators = oldIndicators;\r
45046 } else {\r
45047 indicators = {\r
45048 x: null,\r
45049 y: null\r
45050 };\r
45051 if (xIndicator) {\r
45052 indicators.x = new Ext.scroll.Indicator(Ext.applyIf({\r
45053 axis: 'x',\r
45054 scroller: me\r
45055 }, xIndicator));\r
45056 }\r
45057 if (yIndicator) {\r
45058 indicators.y = new Ext.scroll.Indicator(Ext.applyIf({\r
45059 axis: 'y',\r
45060 scroller: me\r
45061 }, yIndicator));\r
45062 }\r
45063 }\r
45064 } else if (oldIndicators) {\r
45065 if (oldIndicators.x) {\r
45066 oldIndicators.x.destroy();\r
45067 }\r
45068 if (oldIndicators.y) {\r
45069 oldIndicators.y.destroy();\r
45070 }\r
45071 oldIndicators.x = oldIndicators.y = null;\r
45072 }\r
45073 return indicators;\r
45074 },\r
45075 applyMomentumEasing: function(easing) {\r
45076 var defaultClass = Ext.fx.easing.BoundMomentum;\r
45077 return {\r
45078 x: Ext.factory(easing, defaultClass),\r
45079 y: Ext.factory(easing, defaultClass)\r
45080 };\r
45081 },\r
45082 applyInnerElement: function(innerElement) {\r
45083 if (innerElement && !innerElement.isElement) {\r
45084 innerElement = Ext.get(innerElement);\r
45085 }\r
45086
45087 if (this.isConfiguring && !innerElement) {\r
45088 Ext.raise("Cannot create Ext.scroll.TouchScroller instance with null innerElement");\r
45089 }\r
45090
45091 return innerElement;\r
45092 },\r
45093 applyMaxPosition: function(maxPosition, oldMaxPosition) {\r
45094
45095 if (oldMaxPosition && maxPosition.x === oldMaxPosition.x && maxPosition.y === oldMaxPosition.y) {\r
45096 return;\r
45097 }\r
45098 var translatable = this.getTranslatable(),\r
45099 yEasing;\r
45100
45101 if (translatable.isAnimating) {\r
45102
45103 yEasing = translatable.activeEasingY;\r
45104
45105
45106
45107 if (yEasing && yEasing.getStartVelocity && yEasing.getStartVelocity() < 0 && maxPosition.y < oldMaxPosition.y) {\r
45108 yEasing.setMinMomentumValue(-maxPosition.y);\r
45109 }\r
45110 }\r
45111 return maxPosition;\r
45112 },\r
45113 applyMaxUserPosition: function(maxUserPosition, oldMaxUserPosition) {\r
45114
45115 if (oldMaxUserPosition && maxUserPosition.x === oldMaxUserPosition.x && maxUserPosition.y === oldMaxUserPosition.y) {\r
45116 return;\r
45117 }\r
45118 return maxUserPosition;\r
45119 },\r
45120 applySize: function(size) {\r
45121 var el = this.getElement(),\r
45122 dom, scrollerDom, x, y;\r
45123 if (typeof size === 'number') {\r
45124 x = size;\r
45125 y = size;\r
45126 } else if (size) {\r
45127 x = size.x;\r
45128 y = size.y;\r
45129 }\r
45130 if (el && (x == null || y == null)) {\r
45131 dom = el.dom;\r
45132 scrollerDom = this.getInnerElement().dom;\r
45133
45134
45135 if (x == null) {\r
45136 x = Math.max(scrollerDom.scrollWidth, dom.clientWidth);\r
45137 }\r
45138 if (y == null) {\r
45139 y = Math.max(scrollerDom.scrollHeight, dom.clientHeight);\r
45140 }\r
45141 }\r
45142 return {\r
45143 x: x,\r
45144 y: y\r
45145 };\r
45146 },\r
45147 applySlotSnapOffset: function(snapOffset) {\r
45148 if (typeof snapOffset === 'number') {\r
45149 snapOffset = {\r
45150 x: snapOffset,\r
45151 y: snapOffset\r
45152 };\r
45153 }\r
45154 return snapOffset;\r
45155 },\r
45156 applySlotSnapSize: function(snapSize) {\r
45157 if (typeof snapSize === 'number') {\r
45158 snapSize = {\r
45159 x: snapSize,\r
45160 y: snapSize\r
45161 };\r
45162 }\r
45163 return snapSize;\r
45164 },\r
45165 applySlotSnapEasing: function(easing) {\r
45166 var defaultClass = Ext.fx.easing.EaseOut;\r
45167 return {\r
45168 x: Ext.factory(easing, defaultClass),\r
45169 y: Ext.factory(easing, defaultClass)\r
45170 };\r
45171 },\r
45172 applyTranslatable: function(config, translatable) {\r
45173 return Ext.factory(config, Ext.util.Translatable, translatable);\r
45174 },\r
45175 destroy: function() {\r
45176 var me = this,\r
45177 element = me.getElement(),\r
45178 innerElement = me.getInnerElement(),\r
45179 sizeMonitors = me.sizeMonitors;\r
45180 if (sizeMonitors) {\r
45181 sizeMonitors.element.destroy();\r
45182 sizeMonitors.container.destroy();\r
45183 }\r
45184 if (element && !element.destroyed) {\r
45185 element.removeCls(me.cls);\r
45186 }\r
45187 if (innerElement && !innerElement.destroyed) {\r
45188 innerElement.removeCls(me.scrollerCls);\r
45189 }\r
45190 if (me._isWrapped) {\r
45191 if (!element.destroyed) {\r
45192 me.unwrapContent();\r
45193 }\r
45194 innerElement.destroy();\r
45195 }\r
45196 me.setElement(null);\r
45197 me.setInnerElement(null);\r
45198 me.setIndicators(null);\r
45199 Ext.destroy(me.getTranslatable());\r
45200 me.callParent();\r
45201 },\r
45202 refresh: function(immediate, \r
45203 options) {\r
45204 var me = this;\r
45205 ++me.refreshCounter;\r
45206 if (immediate) {\r
45207 me.doRefresh(options);\r
45208 }\r
45209
45210 else if (!me.refreshScheduled) {\r
45211 me.scheduleRefresh.args = [\r
45212 options\r
45213 ];\r
45214 me.refreshScheduled = Ext.on(me.scheduleRefresh);\r
45215 }\r
45216 },\r
45217 updateAutoRefresh: function(autoRefresh) {\r
45218 this.toggleResizeListeners(autoRefresh);\r
45219 },\r
45220 updateBounceEasing: function(easing) {\r
45221 this.getTranslatable().setEasingX(easing.x).setEasingY(easing.y);\r
45222 },\r
45223 updateElementSize: function() {\r
45224 if (!this.isConfiguring) {\r
45225
45226
45227 this.refreshAxes();\r
45228 }\r
45229 },\r
45230 updateDisabled: function(disabled) {\r
45231
45232 if (!this.isConfiguring) {\r
45233 if (disabled) {\r
45234 this.detachListeners();\r
45235 } else {\r
45236 this.attachListeners();\r
45237 }\r
45238 }\r
45239 },\r
45240 updateElement: function(element, oldElement) {\r
45241 var me = this,\r
45242
45243 innerElement = me.getInnerElement(),\r
45244 listeners, autoRefresh;\r
45245 if (!innerElement) {\r
45246
45247
45248
45249 innerElement = element.dom.firstChild;\r
45250 if (!innerElement || innerElement.nodeType !== 1 || !Ext.fly(innerElement).hasCls(me.scrollerCls)) {\r
45251
45252 innerElement = me.wrapContent(element);\r
45253 }\r
45254 me.setInnerElement(innerElement);\r
45255 }\r
45256 element.addCls(me.cls);\r
45257 if (me.isConfiguring) {\r
45258 if (!me.getTranslatable().isScrollParent) {\r
45259
45260 element.dom.style.overflowX = element.dom.style.overflowY = '';\r
45261
45262
45263
45264 listeners = me.elementListeners;\r
45265 listeners.mousewheel = 'onMouseWheel';\r
45266 listeners.scroll = {\r
45267 fn: 'onElementScroll',\r
45268 delegated: false,\r
45269 scope: me\r
45270 };\r
45271 }\r
45272 }\r
45273 if (!me.getDisabled()) {\r
45274 me.attachListeners();\r
45275 }\r
45276 if (!me.isConfiguring) {\r
45277
45278
45279 autoRefresh = me.getAutoRefresh();\r
45280 if (autoRefresh !== false) {\r
45281 me.toggleResizeListeners(autoRefresh);\r
45282 if (autoRefresh) {\r
45283 me.refresh();\r
45284 } else if (autoRefresh === null) {\r
45285
45286 me.setElementSize(null);\r
45287 }\r
45288 }\r
45289 }\r
45290 },\r
45291 updateFps: function(fps) {\r
45292 if (fps !== 'auto') {\r
45293 this.getTranslatable().setFps(fps);\r
45294 }\r
45295 },\r
45296 updateMaxUserPosition: function() {\r
45297 this.snapToBoundary();\r
45298 },\r
45299 updateMinUserPosition: function() {\r
45300 this.snapToBoundary();\r
45301 },\r
45302 updateInnerElement: function(innerElement) {\r
45303 if (innerElement) {\r
45304 innerElement.addCls(this.scrollerCls);\r
45305 }\r
45306 this.getTranslatable().setElement(innerElement);\r
45307 },\r
45308 updateSize: function(size) {\r
45309 if (!this.isConfiguring) {\r
45310
45311 if (Ext.supports.touchScroll === 1) {\r
45312 this.callParent([\r
45313 size\r
45314 ]);\r
45315 }\r
45316
45317
45318 this.refreshAxes();\r
45319 }\r
45320 },\r
45321 updateTranslatable: function(translatable) {\r
45322 translatable.setElement(this.getInnerElement());\r
45323
45324
45325
45326
45327
45328 if (!translatable.isScrollParent) {\r
45329 translatable.on({\r
45330 animationframe: 'onAnimationFrame',\r
45331 animationend: 'onAnimationEnd',\r
45332 scope: this\r
45333 });\r
45334 }\r
45335 },\r
45336 updateX: function() {\r
45337 if (!this.isConfiguring) {\r
45338
45339
45340 this.refreshAxes();\r
45341 }\r
45342 },\r
45343 updateY: function() {\r
45344 if (!this.isConfiguring) {\r
45345
45346
45347 this.refreshAxes();\r
45348 }\r
45349 },\r
45350 privates: {\r
45351 attachListeners: function() {\r
45352 this.getElement().on(this.elementListeners);\r
45353 },\r
45354 constrainX: function(x) {\r
45355 return Math.min(this.getMaxPosition().x, Math.max(x, 0));\r
45356 },\r
45357 constrainY: function(y) {\r
45358 return Math.min(this.getMaxPosition().y, Math.max(y, 0));\r
45359 },\r
45360
45361 convertEasingConfig: function(config) {\r
45362 return config;\r
45363 },\r
45364 detachListeners: function() {\r
45365 this.getElement().un(this.elementListeners);\r
45366 },\r
45367 \r
45368 doRefresh: function(options) {\r
45369 var me = this,\r
45370 size, elementSize;\r
45371 if (me.refreshScheduled) {\r
45372 me.refreshScheduled = me.refreshScheduled.destroy();\r
45373 }\r
45374 if (me.refreshCounter && me.getElement()) {\r
45375 me.stopAnimation();\r
45376 me.getTranslatable().refresh();\r
45377 if (options) {\r
45378
45379
45380 size = options.size;\r
45381 elementSize = options.elementSize;\r
45382 }\r
45383
45384 me.setSize(size);\r
45385 me.setElementSize(elementSize);\r
45386 me.fireEvent('refresh', me);\r
45387 me.refreshCounter = 0;\r
45388 }\r
45389 },\r
45390 doScrollTo: function(x, y, animation, \r
45391 allowOverscroll) {\r
45392 var me = this,\r
45393 isDragging = me.isDragging,\r
45394
45395
45396
45397 DOMScrolling = me.getTranslatable().isScrollParent,\r
45398
45399
45400
45401
45402 fireStartEnd = !me.isReflecting && !DOMScrolling;\r
45403 if (me.destroyed || !me.getElement()) {\r
45404 return me;\r
45405 }\r
45406
45407
45408 allowOverscroll = allowOverscroll || me.isDragging;\r
45409 var translatable = me.getTranslatable(),\r
45410 position = me.position,\r
45411 positionChanged = false,\r
45412 translationX, translationY;\r
45413 if (!isDragging || me.isAxisEnabled('x')) {\r
45414 if (isNaN(x) || typeof x !== 'number') {\r
45415 x = position.x;\r
45416 } else {\r
45417 if (!allowOverscroll) {\r
45418 x = me.constrainX(x);\r
45419 }\r
45420 if (position.x !== x) {\r
45421 position.x = x;\r
45422 positionChanged = true;\r
45423 }\r
45424 }\r
45425 translationX = me.convertX(-x);\r
45426 }\r
45427 if (!isDragging || me.isAxisEnabled('y')) {\r
45428 if (isNaN(y) || typeof y !== 'number') {\r
45429 y = position.y;\r
45430 } else {\r
45431 if (!allowOverscroll) {\r
45432 y = me.constrainY(y);\r
45433 }\r
45434 if (position.y !== y) {\r
45435 position.y = y;\r
45436 positionChanged = true;\r
45437 }\r
45438 }\r
45439 translationY = -y;\r
45440 }\r
45441 if (positionChanged) {\r
45442
45443
45444 if (fireStartEnd) {\r
45445
45446
45447
45448
45449 me.onScrollStart();\r
45450 }\r
45451 if (animation) {\r
45452
45453 translatable.translateAnimated(translationX, translationY, animation);\r
45454 } else {\r
45455
45456
45457 if (!DOMScrolling) {\r
45458 me.onScroll();\r
45459 }\r
45460 translatable.translate(translationX, translationY);\r
45461
45462
45463 if (fireStartEnd) {\r
45464 me.onScrollEnd();\r
45465 }\r
45466 }\r
45467 } else if (animation && animation.callback) {\r
45468 animation.callback();\r
45469 }\r
45470 return me;\r
45471 },\r
45472 \r
45473 getAnimationEasing: function(axis, e) {\r
45474 if (!this.isAxisEnabled(axis)) {\r
45475 return null;\r
45476 }\r
45477 var me = this,\r
45478 currentPosition = me.position[axis],\r
45479 minPosition = me.getMinUserPosition()[axis],\r
45480 maxPosition = me.getMaxUserPosition()[axis],\r
45481 maxAbsVelocity = me.getMaxAbsoluteVelocity(),\r
45482 boundValue = null,\r
45483 dragEndTime = me.dragEndTime,\r
45484 velocity = e.flick.velocity[axis],\r
45485 isX = axis === 'x',\r
45486 easingConfig, easing;\r
45487 if (currentPosition < minPosition) {\r
45488 boundValue = minPosition;\r
45489 } else if (currentPosition > maxPosition) {\r
45490 boundValue = maxPosition;\r
45491 }\r
45492 if (isX) {\r
45493 currentPosition = me.convertX(currentPosition);\r
45494 boundValue = me.convertX(boundValue);\r
45495 }\r
45496
45497 if (boundValue !== null) {\r
45498 easing = me.getBounceEasing()[axis];\r
45499 easing.setConfig({\r
45500 startTime: dragEndTime,\r
45501 startValue: -currentPosition,\r
45502 endValue: -boundValue\r
45503 });\r
45504 return easing;\r
45505 }\r
45506 if (velocity === 0) {\r
45507 return null;\r
45508 }\r
45509 if (velocity < -maxAbsVelocity) {\r
45510 velocity = -maxAbsVelocity;\r
45511 } else if (velocity > maxAbsVelocity) {\r
45512 velocity = maxAbsVelocity;\r
45513 }\r
45514 easing = me.getMomentumEasing()[axis];\r
45515 easingConfig = {\r
45516 startTime: dragEndTime,\r
45517 startValue: -currentPosition,\r
45518 startVelocity: velocity * 1.5,\r
45519 minMomentumValue: -maxPosition,\r
45520 maxMomentumValue: 0\r
45521 };\r
45522 if (isX) {\r
45523 me.convertEasingConfig(easingConfig);\r
45524 }\r
45525 easing.setConfig(easingConfig);\r
45526 return easing;\r
45527 },\r
45528 \r
45529 getSnapPosition: function(axis) {\r
45530 var me = this,\r
45531 snapSize = me.getSlotSnapSize()[axis],\r
45532 snapPosition = null,\r
45533 position, snapOffset, maxPosition, mod;\r
45534 if (snapSize !== 0 && me.isAxisEnabled(axis)) {\r
45535 position = me.position[axis];\r
45536 snapOffset = me.getSlotSnapOffset()[axis];\r
45537 maxPosition = me.getMaxUserPosition()[axis];\r
45538 mod = Math.floor((position - snapOffset) % snapSize);\r
45539 if (mod !== 0) {\r
45540 if (position !== maxPosition) {\r
45541 if (Math.abs(mod) > snapSize / 2) {\r
45542 snapPosition = Math.min(maxPosition, position + ((mod > 0) ? snapSize - mod : mod - snapSize));\r
45543 } else {\r
45544 snapPosition = position - mod;\r
45545 }\r
45546 } else {\r
45547 snapPosition = position - mod;\r
45548 }\r
45549 }\r
45550 }\r
45551 return snapPosition;\r
45552 },\r
45553 hideIndicators: function() {\r
45554 var me = this,\r
45555 indicators = me.getIndicators(),\r
45556 xIndicator, yIndicator;\r
45557 if (indicators) {\r
45558 if (me.isAxisEnabled('x')) {\r
45559 xIndicator = indicators.x;\r
45560 if (xIndicator) {\r
45561 xIndicator.hide();\r
45562 }\r
45563 }\r
45564 if (me.isAxisEnabled('y')) {\r
45565 yIndicator = indicators.y;\r
45566 if (yIndicator) {\r
45567 yIndicator.hide();\r
45568 }\r
45569 }\r
45570 }\r
45571 },\r
45572 \r
45573 isAxisEnabled: function(axis) {\r
45574 this.getX();\r
45575 this.getY();\r
45576 return this.isAxisEnabledFlags[axis];\r
45577 },\r
45578 onAnimationEnd: function() {\r
45579 this.snapToBoundary();\r
45580 this.onScrollEnd();\r
45581 },\r
45582 onAnimationFrame: function(translatable, x, y) {\r
45583 var position = this.position;\r
45584 position.x = this.convertX(-x);\r
45585 position.y = -y;\r
45586 this.onScroll();\r
45587 },\r
45588 onAxisDrag: function(axis, delta) {\r
45589
45590 if (delta && this.isAxisEnabled(axis)) {\r
45591 var me = this,\r
45592 flickStartPosition = me.flickStartPosition,\r
45593 flickStartTime = me.flickStartTime,\r
45594 lastDragPosition = me.lastDragPosition,\r
45595 dragDirection = me.dragDirection,\r
45596 old = me.position[axis],\r
45597 min = me.getMinUserPosition()[axis],\r
45598 max = me.getMaxUserPosition()[axis],\r
45599 start = me.startPosition[axis],\r
45600 last = lastDragPosition[axis],\r
45601 current = start - delta,\r
45602 lastDirection = dragDirection[axis],\r
45603 restrictFactor = me.getOutOfBoundRestrictFactor(),\r
45604 startMomentumResetTime = me.getStartMomentumResetTime(),\r
45605 now = Ext.Date.now(),\r
45606 distance;\r
45607 if (current < min) {\r
45608 current *= restrictFactor;\r
45609 } else if (current > max) {\r
45610 distance = current - max;\r
45611 current = max + distance * restrictFactor;\r
45612 }\r
45613 if (current > last) {\r
45614 dragDirection[axis] = 1;\r
45615 } else if (current < last) {\r
45616 dragDirection[axis] = -1;\r
45617 }\r
45618 if ((lastDirection !== 0 && (dragDirection[axis] !== lastDirection)) || (now - flickStartTime[axis]) > startMomentumResetTime) {\r
45619 flickStartPosition[axis] = old;\r
45620 flickStartTime[axis] = now;\r
45621 }\r
45622 lastDragPosition[axis] = current;\r
45623 return true;\r
45624 }\r
45625 },\r
45626
45627
45628
45629 onDomScroll: function() {\r
45630 var me = this,\r
45631 dom, position;\r
45632 if (me.getTranslatable().isScrollParent) {\r
45633 dom = me.getElement().dom;\r
45634 position = me.position;\r
45635 position.x = dom.scrollLeft;\r
45636 position.y = dom.scrollTop;\r
45637 }\r
45638 me.callParent();\r
45639 },\r
45640 onDrag: function(e) {\r
45641 var me = this,\r
45642 lastDragPosition = me.lastDragPosition;\r
45643 if (!me.isDragging) {\r
45644 return;\r
45645 }\r
45646
45647
45648
45649 if (me.onAxisDrag('x', me.convertX(e.deltaX)) | me.onAxisDrag('y', e.deltaY)) {\r
45650 me.doScrollTo(lastDragPosition.x, lastDragPosition.y);\r
45651 }\r
45652 },\r
45653 onDragEnd: function(e) {\r
45654 var me = this,\r
45655 easingX, easingY;\r
45656 if (!me.isDragging) {\r
45657 return;\r
45658 }\r
45659 me.dragEndTime = Ext.Date.now();\r
45660 me.onDrag(e);\r
45661 me.isDragging = false;\r
45662 easingX = me.getAnimationEasing('x', e);\r
45663 easingY = me.getAnimationEasing('y', e);\r
45664 if (easingX || easingY) {\r
45665 me.getTranslatable().animate(easingX, easingY);\r
45666 } else {\r
45667 me.onScrollEnd();\r
45668 }\r
45669 },\r
45670 onDragStart: function(e) {\r
45671 var me = this,\r
45672 direction = me.getDirection(),\r
45673 absDeltaX = e.absDeltaX,\r
45674 absDeltaY = e.absDeltaY,\r
45675 directionLock = me.getDirectionLock(),\r
45676 startPosition = me.startPosition,\r
45677 flickStartPosition = me.flickStartPosition,\r
45678 flickStartTime = me.flickStartTime,\r
45679 lastDragPosition = me.lastDragPosition,\r
45680 currentPosition = me.position,\r
45681 dragDirection = me.dragDirection,\r
45682 x = currentPosition.x,\r
45683 y = currentPosition.y,\r
45684 now = Ext.Date.now();\r
45685 if (directionLock && direction !== 'both') {\r
45686 if ((direction === 'horizontal' && absDeltaX > absDeltaY) || (direction === 'vertical' && absDeltaY > absDeltaX)) {\r
45687 e.stopPropagation();\r
45688 } else {\r
45689 return;\r
45690 }\r
45691 }\r
45692 lastDragPosition.x = x;\r
45693 lastDragPosition.y = y;\r
45694 flickStartPosition.x = x;\r
45695 flickStartPosition.y = y;\r
45696 startPosition.x = x;\r
45697 startPosition.y = y;\r
45698 flickStartTime.x = now;\r
45699 flickStartTime.y = now;\r
45700 dragDirection.x = 0;\r
45701 dragDirection.y = 0;\r
45702 me.dragStartTime = now;\r
45703 me.isDragging = true;\r
45704
45705
45706
45707 if (!me.isScrolling) {\r
45708 me.onScrollStart();\r
45709 }\r
45710 },\r
45711 onElementResize: function(element, info) {\r
45712 this.refresh(true, {\r
45713 elementSize: {\r
45714 x: info.contentWidth,\r
45715 y: info.contentHeight\r
45716 },\r
45717 size: this.getAutoRefresh() ? null : this.getSize()\r
45718 });\r
45719 },\r
45720 onElementScroll: function(event, targetEl) {\r
45721 targetEl.scrollTop = targetEl.scrollLeft = 0;\r
45722 },\r
45723 onEvent: function(e) {\r
45724
45725
45726 var me = this,\r
45727 browserEvent = e.browserEvent;\r
45728 if ((!me.self.isTouching || me.isTouching) &&
45729
45730
45731
45732
45733
45734
45735 ((!me.getTranslatable().isScrollParent) || (!me.isMouseEvent[browserEvent.type] && browserEvent.pointerType !== 'mouse')) && (me.getY() || me.getX())) {\r
45736 me[me.listenerMap[e.type]](e);\r
45737 }\r
45738 },\r
45739 onInnerElementResize: function(element, info) {\r
45740 this.refresh(true, {\r
45741 size: {\r
45742 x: info.width,\r
45743 y: info.height\r
45744 }\r
45745 });\r
45746 },\r
45747 onMouseWheel: function(e) {\r
45748 var me = this,\r
45749 delta = e.getWheelDeltas(),\r
45750 deltaX = -delta.x,\r
45751 deltaY = -delta.y,\r
45752 position = me.position,\r
45753 maxPosition = me.getMaxUserPosition(),\r
45754 minPosition = me.getMinUserPosition(),\r
45755 max = Math.max,\r
45756 min = Math.min,\r
45757 positionX = max(min(position.x + deltaX, maxPosition.x), minPosition.x),\r
45758 positionY = max(min(position.y + deltaY, maxPosition.y), minPosition.y);\r
45759 deltaX = positionX - position.x;\r
45760 deltaY = positionY - position.y;\r
45761 if (!deltaX && !deltaY) {\r
45762 return;\r
45763 }\r
45764 e.stopEvent();\r
45765 me.onScrollStart();\r
45766 me.scrollBy(deltaX, deltaY);\r
45767 me.onScroll();\r
45768 me.onScrollEnd();\r
45769 },\r
45770 onPartnerScrollEnd: function(x, y) {\r
45771 var me = this;\r
45772
45773
45774
45775
45776
45777
45778
45779 if (!me.getTranslatable().isScrollParent) {\r
45780 me.fireScrollEnd(x, y);\r
45781 }\r
45782 me.callParent([\r
45783 x,\r
45784 y\r
45785 ]);\r
45786 me.isScrolling = false;\r
45787 me.hideIndicators();\r
45788 },\r
45789 onPartnerScrollStart: function(x, y) {\r
45790 var me = this;\r
45791 me.isScrolling = true;\r
45792
45793
45794
45795
45796
45797
45798
45799 if (!me.getTranslatable().isScrollParent) {\r
45800 me.fireScrollStart(x, y);\r
45801 }\r
45802 me.showIndicators();\r
45803 },\r
45804 onScroll: function() {\r
45805 var me = this,\r
45806 position = me.position,\r
45807 x = position.x,\r
45808 y = position.y,\r
45809 indicators = me.getIndicators(),\r
45810 xIndicator, yIndicator;\r
45811 if (indicators) {\r
45812 if (me.isAxisEnabled('x')) {\r
45813 xIndicator = indicators.x;\r
45814 if (xIndicator) {\r
45815 xIndicator.setValue(x);\r
45816 }\r
45817 }\r
45818 if (me.isAxisEnabled('y')) {\r
45819 yIndicator = indicators.y;\r
45820 if (yIndicator) {\r
45821 yIndicator.setValue(y);\r
45822 }\r
45823 }\r
45824 }\r
45825 me.fireScroll(x, y);\r
45826 },\r
45827 onScrollEnd: function() {\r
45828 var me = this,\r
45829 position = me.position;\r
45830 if (me.isScrolling && !me.isTouching && !me.snapToSlot()) {\r
45831 me.hideIndicators();\r
45832 me.isScrolling = Ext.isScrolling = false;\r
45833 me.fireScrollEnd(position.x, position.y);\r
45834 }\r
45835 },\r
45836 onScrollStart: function() {\r
45837 var me = this,\r
45838 position = me.position;\r
45839 if (!me.isScrolling) {\r
45840 me.showIndicators();\r
45841 me.isScrolling = Ext.isScrolling = true;\r
45842 me.fireScrollStart(position.x, position.y);\r
45843 }\r
45844 },\r
45845 onTouchEnd: function() {\r
45846 var me = this;\r
45847 me.isTouching = me.self.isTouching = false;\r
45848 if (!me.isDragging && me.snapToSlot()) {\r
45849 me.onScrollStart();\r
45850 }\r
45851 },\r
45852 onTouchMove: function(e) {\r
45853
45854
45855
45856 e.preventDefault();\r
45857 },\r
45858 onTouchStart: function() {\r
45859 var me = this;\r
45860 me.isTouching = me.self.isTouching = true;\r
45861 Ext.getDoc().on({\r
45862 touchend: 'onTouchEnd',\r
45863 scope: me,\r
45864 single: true\r
45865 });\r
45866 me.stopAnimation();\r
45867 },\r
45868 refreshAxes: function() {\r
45869 var me = this,\r
45870 flags = me.isAxisEnabledFlags,\r
45871 size = me.getSize(),\r
45872 elementSize = me.getElementSize(),\r
45873 indicators = me.getIndicators(),\r
45874 maxX, maxY, x, y, xIndicator, yIndicator;\r
45875 if (!size || !elementSize) {\r
45876 return;\r
45877 }\r
45878 maxX = Math.max(0, size.x - elementSize.x);\r
45879 maxY = Math.max(0, size.y - elementSize.y);\r
45880 x = me.getX();\r
45881 y = me.getY();\r
45882 me.setMaxPosition({\r
45883 x: maxX,\r
45884 y: maxY\r
45885 });\r
45886 if (x === true || x === 'auto') {\r
45887
45888
45889 flags.x = !!maxX;\r
45890 } else if (x === false) {\r
45891 flags.x = false;\r
45892 xIndicator = indicators && indicators.x;\r
45893 if (xIndicator) {\r
45894
45895
45896 xIndicator.hide();\r
45897 }\r
45898 } else if (x === 'scroll') {\r
45899 flags.x = true;\r
45900 }\r
45901 if (y === true || y === 'auto') {\r
45902
45903
45904 flags.y = !!maxY;\r
45905 } else if (y === false) {\r
45906 flags.y = false;\r
45907 yIndicator = indicators && indicators.y;\r
45908 if (yIndicator) {\r
45909
45910
45911 yIndicator.hide();\r
45912 }\r
45913 } else if (y === 'scroll') {\r
45914 flags.y = true;\r
45915 }\r
45916 me.setMaxUserPosition({\r
45917 x: flags.x ? maxX : 0,\r
45918 y: flags.y ? maxY : 0\r
45919 });\r
45920
45921 if (Ext.supports.touchScroll === 1) {\r
45922 me.initXStyle();\r
45923 me.initYStyle();\r
45924 }\r
45925 },\r
45926 showIndicators: function() {\r
45927 var me = this,\r
45928 indicators = me.getIndicators(),\r
45929 xIndicator, yIndicator;\r
45930 if (indicators) {\r
45931 if (me.isAxisEnabled('x')) {\r
45932 xIndicator = indicators.x;\r
45933 if (xIndicator) {\r
45934 xIndicator.show();\r
45935 }\r
45936 }\r
45937 if (me.isAxisEnabled('y')) {\r
45938 yIndicator = indicators.y;\r
45939 if (yIndicator) {\r
45940 yIndicator.show();\r
45941 }\r
45942 }\r
45943 }\r
45944 },\r
45945 snapToBoundary: function() {\r
45946 var me = this,\r
45947 position = me.getPosition();\r
45948
45949 if (me.isConfiguring || !(position.x || position.y)) {\r
45950 return;\r
45951 }\r
45952 var minPosition = me.getMinUserPosition(),\r
45953 maxPosition = me.getMaxUserPosition(),\r
45954 minX = minPosition.x,\r
45955 minY = minPosition.y,\r
45956 maxX = maxPosition.x,\r
45957 maxY = maxPosition.y,\r
45958 x = Math.round(position.x),\r
45959 y = Math.round(position.y);\r
45960 if (x < minX) {\r
45961 x = minX;\r
45962 } else if (x > maxX) {\r
45963 x = maxX;\r
45964 }\r
45965 if (y < minY) {\r
45966 y = minY;\r
45967 } else if (y > maxY) {\r
45968 y = maxY;\r
45969 }\r
45970 me.doScrollTo(x, y);\r
45971 },\r
45972 \r
45973 snapToSlot: function() {\r
45974 var me = this,\r
45975 snapX = me.getSnapPosition('x'),\r
45976 snapY = me.getSnapPosition('y'),\r
45977 easing = me.getSlotSnapEasing();\r
45978 if (snapX !== null || snapY !== null) {\r
45979 me.doScrollTo(snapX, snapY, {\r
45980 easingX: easing.x,\r
45981 easingY: easing.y\r
45982 });\r
45983 return true;\r
45984 }\r
45985 return false;\r
45986 },\r
45987 \r
45988 stopAnimation: function() {\r
45989 this.getTranslatable().stopAnimation();\r
45990 },\r
45991 toggleResizeListeners: function(autoRefresh) {\r
45992 var me = this,\r
45993 element = me.getElement(),\r
45994 method, innerMethod, innerElement;\r
45995 if (element) {\r
45996 innerElement = me.getInnerElement();\r
45997 if (autoRefresh) {\r
45998 method = innerMethod = 'on';\r
45999 } else if (autoRefresh === null) {\r
46000 method = 'on';\r
46001 innerMethod = 'un';\r
46002 } else {\r
46003 method = innerMethod = 'un';\r
46004 }\r
46005 element[method]('resize', 'onElementResize', me);\r
46006 innerElement[innerMethod]('resize', 'onInnerElementResize', me);\r
46007 }\r
46008 },\r
46009 unwrapContent: function() {\r
46010 var innerDom = this.getInnerElement().dom,\r
46011 dom = this.getElement().dom,\r
46012 child;\r
46013 while ((child = innerDom.firstChild)) {\r
46014 dom.insertBefore(child, innerDom);\r
46015 }\r
46016 },\r
46017 \r
46018 wrapContent: function(element) {\r
46019 var wrap = document.createElement('div'),\r
46020 dom = element.dom,\r
46021 child;\r
46022 while (child = dom.lastChild) {\r
46023
46024 wrap.insertBefore(child, wrap.firstChild);\r
46025 }\r
46026 dom.appendChild(wrap);\r
46027 this.setInnerElement(wrap);\r
46028
46029
46030
46031 this._isWrapped = true;\r
46032 return this.getInnerElement();\r
46033 }\r
46034 }\r
46035});\r
46036\r
46037\r
46038Ext.define('Ext.scroll.DomScroller', {\r
46039 extend: Ext.scroll.Scroller,\r
46040 alias: 'scroller.dom',\r
46041 isDomScroller: true,\r
46042 getMaxPosition: function() {\r
46043 var element = this.getElement(),\r
46044 x = 0,\r
46045 y = 0,\r
46046 dom;\r
46047 if (element && !element.destroyed) {\r
46048 dom = element.dom;\r
46049 x = dom.scrollWidth - dom.clientWidth;\r
46050 y = dom.scrollHeight - dom.clientHeight;\r
46051 }\r
46052 return {\r
46053 x: x,\r
46054 y: y\r
46055 };\r
46056 },\r
46057 getMaxUserPosition: function() {\r
46058 var me = this,\r
46059 element = me.getElement(),\r
46060 x = 0,\r
46061 y = 0,\r
46062 dom;\r
46063 if (element && !element.destroyed) {\r
46064 dom = element.dom;\r
46065 if (me.getX()) {\r
46066 x = dom.scrollWidth - dom.clientWidth;\r
46067 }\r
46068 if (me.getY()) {\r
46069 y = dom.scrollHeight - dom.clientHeight;\r
46070 }\r
46071 }\r
46072 return {\r
46073 x: x,\r
46074 y: y\r
46075 };\r
46076 },\r
46077 getPosition: function() {\r
46078 var me = this;\r
46079 if (me.positionDirty) {\r
46080 me.updateDomScrollPosition();\r
46081 }\r
46082 return me.position;\r
46083 },\r
46084 getSize: function() {\r
46085 var element = this.getElement(),\r
46086 size, dom;\r
46087 if (element && !element.destroyed) {\r
46088 dom = element.dom;\r
46089 size = {\r
46090 x: dom.scrollWidth,\r
46091 y: dom.scrollHeight\r
46092 };\r
46093 } else {\r
46094 size = {\r
46095 x: 0,\r
46096 y: 0\r
46097 };\r
46098 }\r
46099 return size;\r
46100 },\r
46101 updateElement: function(element, oldElement) {\r
46102 this.initXStyle();\r
46103 this.initYStyle();\r
46104 },\r
46105 updateX: function(x) {\r
46106 this.initXStyle();\r
46107 },\r
46108 updateY: function(y) {\r
46109 this.initYStyle();\r
46110 },\r
46111 privates: {\r
46112 doScrollTo: function(x, y, animate) {\r
46113
46114
46115 var me = this,\r
46116 element = me.getElement(),\r
46117 maxPosition, dom, to, xInf, yInf, i;\r
46118 if (element && !element.destroyed) {\r
46119 dom = element.dom;\r
46120 xInf = (x === Infinity);\r
46121 yInf = (y === Infinity);\r
46122 if (xInf || yInf) {\r
46123 maxPosition = me.getMaxPosition();\r
46124 if (xInf) {\r
46125 x = maxPosition.x;\r
46126 }\r
46127 if (yInf) {\r
46128 y = maxPosition.y;\r
46129 }\r
46130 }\r
46131 x = me.convertX(x);\r
46132 if (animate) {\r
46133 to = {};\r
46134 if (y != null) {\r
46135 to.scrollTop = y;\r
46136 }\r
46137 if (x != null) {\r
46138 to.scrollLeft = x;\r
46139 }\r
46140 element.animate(Ext.mergeIf({\r
46141 to: {\r
46142 scrollTop: y,\r
46143 scrollLeft: x\r
46144 }\r
46145 }, animate));\r
46146 } else {\r
46147 if (y != null) {\r
46148 dom.scrollTop = y;\r
46149 }\r
46150 if (x != null) {\r
46151 dom.scrollLeft = x;\r
46152
46153
46154 if (Ext.isIE8) {\r
46155 i = dom.scrollLeft;\r
46156 dom.scrollLeft = x;\r
46157 }\r
46158 }\r
46159 }\r
46160
46161
46162 me.positionDirty = true;\r
46163 }\r
46164 },\r
46165
46166 getElementScroll: function(element) {\r
46167 return element.getScroll();\r
46168 },\r
46169 stopAnimation: function() {\r
46170 var anim = this.getElement().getActiveAnimation();\r
46171 if (anim) {\r
46172 anim.end();\r
46173 }\r
46174 }\r
46175 }\r
46176}, function(DomScroller) {\r
46177
46178
46179
46180
46181 Ext.onDocumentReady(function() {\r
46182 DomScroller.document = new DomScroller({\r
46183 x: true,\r
46184 y: true,\r
46185 element: document.body\r
46186 });\r
46187 });\r
46188});\r
46189\r
46190Ext.define('Ext.overrides.scroll.DomScroller', {\r
46191 override: 'Ext.scroll.DomScroller',\r
46192 _scrollerCls: Ext.baseCSSPrefix + 'domscroller',\r
46193 updateElement: function(element, oldElement) {\r
46194 element.addCls(this._scrollerCls);\r
46195 this.callParent([\r
46196 element,\r
46197 oldElement\r
46198 ]);\r
46199 }\r
46200});\r
46201\r
46202\r
46203Ext.define('Ext.behavior.Behavior', {\r
46204 constructor: function(component) {\r
46205 this.component = component;\r
46206 component.on('destroy', 'onComponentDestroy', this);\r
46207 },\r
46208 onComponentDestroy: Ext.emptyFn\r
46209});\r
46210\r
46211\r
46212Ext.define('Ext.behavior.Translatable', {\r
46213 extend: Ext.behavior.Behavior,\r
46214 setConfig: function(config) {\r
46215 var translatable = this.translatable,\r
46216 component = this.component;\r
46217 if (config) {\r
46218 if (!translatable) {\r
46219 this.translatable = translatable = new Ext.util.Translatable(config);\r
46220 translatable.setElement(component.renderElement);\r
46221 translatable.on('destroy', 'onTranslatableDestroy', this);\r
46222 } else if (Ext.isObject(config)) {\r
46223 translatable.setConfig(config);\r
46224 }\r
46225 } else if (translatable) {\r
46226 translatable.destroy();\r
46227 }\r
46228 return this;\r
46229 },\r
46230 getTranslatable: function() {\r
46231 return this.translatable;\r
46232 },\r
46233 onTranslatableDestroy: function() {\r
46234 delete this.translatable;\r
46235 },\r
46236 onComponentDestroy: function() {\r
46237 var translatable = this.translatable;\r
46238 if (translatable) {\r
46239 translatable.destroy();\r
46240 }\r
46241 }\r
46242});\r
46243\r
46244\r
46245Ext.define('Ext.util.Draggable', {\r
46246 isDraggable: true,\r
46247 mixins: [\r
46248 Ext.mixin.Observable\r
46249 ],\r
46250 \r
46251 \r
46252 \r
46253 config: {\r
46254 cls: Ext.baseCSSPrefix + 'draggable',\r
46255 draggingCls: Ext.baseCSSPrefix + 'dragging',\r
46256 element: null,\r
46257 constraint: 'container',\r
46258 disabled: null,\r
46259 \r
46260 direction: 'both',\r
46261 \r
46262 initialOffset: {\r
46263 x: 0,\r
46264 y: 0\r
46265 },\r
46266 translatable: {}\r
46267 },\r
46268 DIRECTION_BOTH: 'both',\r
46269 DIRECTION_VERTICAL: 'vertical',\r
46270 DIRECTION_HORIZONTAL: 'horizontal',\r
46271 defaultConstraint: {\r
46272 min: {\r
46273 x: -Infinity,\r
46274 y: -Infinity\r
46275 },\r
46276 max: {\r
46277 x: Infinity,\r
46278 y: Infinity\r
46279 }\r
46280 },\r
46281 containerWidth: 0,\r
46282 containerHeight: 0,\r
46283 width: 0,\r
46284 height: 0,\r
46285 \r
46286 constructor: function(config) {\r
46287 var element;\r
46288 this.extraConstraint = {};\r
46289 this.initialConfig = config;\r
46290 this.offset = {\r
46291 x: 0,\r
46292 y: 0\r
46293 };\r
46294 this.elementListeners = {\r
46295 dragstart: 'onDragStart',\r
46296 drag: 'onDrag',\r
46297 dragend: 'onDragEnd',\r
46298 resize: 'onElementResize',\r
46299 touchstart: 'onPress',\r
46300 touchend: 'onRelease',\r
46301 scope: this\r
46302 };\r
46303 if (config && config.element) {\r
46304 element = config.element;\r
46305 delete config.element;\r
46306 this.setElement(element);\r
46307 }\r
46308 return this;\r
46309 },\r
46310 applyElement: function(element) {\r
46311 if (!element) {\r
46312 return;\r
46313 }\r
46314 return Ext.get(element);\r
46315 },\r
46316 updateElement: function(element) {\r
46317 element.on(this.elementListeners);\r
46318 this.mixins.observable.constructor.call(this, this.initialConfig);\r
46319 },\r
46320 updateInitialOffset: function(initialOffset) {\r
46321 if (typeof initialOffset == 'number') {\r
46322 initialOffset = {\r
46323 x: initialOffset,\r
46324 y: initialOffset\r
46325 };\r
46326 }\r
46327 var offset = this.offset,\r
46328 x, y;\r
46329 offset.x = x = initialOffset.x;\r
46330 offset.y = y = initialOffset.y;\r
46331 this.getTranslatable().translate(x, y);\r
46332 },\r
46333 updateCls: function(cls) {\r
46334 this.getElement().addCls(cls);\r
46335 },\r
46336 applyTranslatable: function(translatable, currentInstance) {\r
46337 translatable = Ext.factory(translatable, Ext.util.Translatable, currentInstance);\r
46338 if (translatable) {\r
46339 translatable.setElement(this.getElement());\r
46340 }\r
46341 return translatable;\r
46342 },\r
46343 setExtraConstraint: function(constraint) {\r
46344 this.extraConstraint = constraint || {};\r
46345 this.refreshConstraint();\r
46346 return this;\r
46347 },\r
46348 addExtraConstraint: function(constraint) {\r
46349 Ext.merge(this.extraConstraint, constraint);\r
46350 this.refreshConstraint();\r
46351 return this;\r
46352 },\r
46353 applyConstraint: function(newConstraint) {\r
46354 this.currentConstraint = newConstraint;\r
46355 if (!newConstraint) {\r
46356 newConstraint = this.defaultConstraint;\r
46357 }\r
46358 if (newConstraint === 'container') {\r
46359 return Ext.merge(this.getContainerConstraint(), this.extraConstraint);\r
46360 }\r
46361 return Ext.merge({}, this.extraConstraint, newConstraint);\r
46362 },\r
46363 updateConstraint: function() {\r
46364 this.refreshOffset();\r
46365 },\r
46366 getContainerConstraint: function() {\r
46367 var container = this.getContainer(),\r
46368 element = this.getElement();\r
46369 if (!container || !element.dom) {\r
46370 return this.defaultConstraint;\r
46371 }\r
46372 return {\r
46373 min: {\r
46374 x: 0,\r
46375 y: 0\r
46376 },\r
46377 max: {\r
46378 x: this.containerWidth - this.width,\r
46379 y: this.containerHeight - this.height\r
46380 }\r
46381 };\r
46382 },\r
46383 getContainer: function() {\r
46384 var container = this.container;\r
46385 if (!container) {\r
46386 container = this.getElement().getParent();\r
46387 if (container) {\r
46388 this.container = container;\r
46389 container.on({\r
46390 resize: 'onContainerResize',\r
46391 destroy: 'onContainerDestroy',\r
46392 scope: this\r
46393 });\r
46394 }\r
46395 }\r
46396 return container;\r
46397 },\r
46398 onElementResize: function(element, info) {\r
46399 this.width = info.width;\r
46400 this.height = info.height;\r
46401 this.refresh();\r
46402 },\r
46403 onContainerResize: function(container, info) {\r
46404 this.containerWidth = info.width;\r
46405 this.containerHeight = info.height;\r
46406 this.refresh();\r
46407 },\r
46408 onContainerDestroy: function() {\r
46409 delete this.container;\r
46410 delete this.containerSizeMonitor;\r
46411 },\r
46412 detachListeners: function() {\r
46413 this.getElement().un(this.elementListeners);\r
46414 },\r
46415 isAxisEnabled: function(axis) {\r
46416 var direction = this.getDirection();\r
46417 if (axis === 'x') {\r
46418 return (direction === this.DIRECTION_BOTH || direction === this.DIRECTION_HORIZONTAL);\r
46419 }\r
46420 return (direction === this.DIRECTION_BOTH || direction === this.DIRECTION_VERTICAL);\r
46421 },\r
46422 onPress: function(e) {\r
46423 this.fireEvent('touchstart', this, e);\r
46424 },\r
46425 onRelease: function(e) {\r
46426 this.fireEvent('touchend', this, e);\r
46427 },\r
46428 onDragStart: function(e) {\r
46429 var me = this,\r
46430 offset = me.offset;\r
46431 if (me.getDisabled()) {\r
46432 return false;\r
46433 }\r
46434 me.fireEventedAction('dragstart', [\r
46435 me,\r
46436 e,\r
46437 offset.x,\r
46438 offset.y\r
46439 ], me.initDragStart, me);\r
46440 },\r
46441 initDragStart: function(me, e, offsetX, offsetY) {\r
46442 this.dragStartOffset = {\r
46443 x: offsetX,\r
46444 y: offsetY\r
46445 };\r
46446 this.isDragging = true;\r
46447 this.getElement().addCls(this.getDraggingCls());\r
46448 },\r
46449 onDrag: function(e) {\r
46450 if (!this.isDragging) {\r
46451 return;\r
46452 }\r
46453 var startOffset = this.dragStartOffset;\r
46454 this.fireAction('drag', [\r
46455 this,\r
46456 e,\r
46457 startOffset.x + e.deltaX,\r
46458 startOffset.y + e.deltaY\r
46459 ], this.doDrag);\r
46460 },\r
46461 doDrag: function(me, e, offsetX, offsetY) {\r
46462 me.setOffset(offsetX, offsetY);\r
46463 },\r
46464 onDragEnd: function(e) {\r
46465 if (!this.isDragging) {\r
46466 return;\r
46467 }\r
46468 this.onDrag(e);\r
46469 this.isDragging = false;\r
46470 this.getElement().removeCls(this.getDraggingCls());\r
46471 this.fireEvent('dragend', this, e, this.offset.x, this.offset.y);\r
46472 },\r
46473 setOffset: function(x, y, animation) {\r
46474 var currentOffset = this.offset,\r
46475 constraint = this.getConstraint(),\r
46476 minOffset = constraint.min,\r
46477 maxOffset = constraint.max,\r
46478 min = Math.min,\r
46479 max = Math.max;\r
46480 if (this.isAxisEnabled('x') && typeof x == 'number') {\r
46481 x = min(max(x, minOffset.x), maxOffset.x);\r
46482 } else {\r
46483 x = currentOffset.x;\r
46484 }\r
46485 if (this.isAxisEnabled('y') && typeof y == 'number') {\r
46486 y = min(max(y, minOffset.y), maxOffset.y);\r
46487 } else {\r
46488 y = currentOffset.y;\r
46489 }\r
46490 currentOffset.x = x;\r
46491 currentOffset.y = y;\r
46492 this.getTranslatable().translate(x, y, animation);\r
46493 },\r
46494 getOffset: function() {\r
46495 return this.offset;\r
46496 },\r
46497 refreshConstraint: function() {\r
46498 this.setConstraint(this.currentConstraint);\r
46499 },\r
46500 refreshOffset: function() {\r
46501 var offset = this.offset;\r
46502 this.setOffset(offset.x, offset.y);\r
46503 },\r
46504 refresh: function() {\r
46505 this.refreshConstraint();\r
46506 this.getTranslatable().refresh();\r
46507 this.refreshOffset();\r
46508 },\r
46509 \r
46510 enable: function() {\r
46511 return this.setDisabled(false);\r
46512 },\r
46513 \r
46514 disable: function() {\r
46515 return this.setDisabled(true);\r
46516 },\r
46517 destroy: function() {\r
46518 var me = this,\r
46519 translatable = me.getTranslatable();\r
46520 var element = me.getElement();\r
46521 if (element && !element.destroyed) {\r
46522 element.removeCls(me.getCls());\r
46523 }\r
46524 me.detachListeners();\r
46525 if (translatable) {\r
46526 translatable.destroy();\r
46527 }\r
46528 me.callParent();\r
46529 }\r
46530});\r
46531\r
46532\r
46533Ext.define('Ext.behavior.Draggable', {\r
46534 extend: Ext.behavior.Behavior,\r
46535 setConfig: function(config) {\r
46536 var draggable = this.draggable,\r
46537 component = this.component,\r
46538 listeners = this.listeners;\r
46539 if (config) {\r
46540 if (!draggable) {\r
46541 component.setTranslatable(config.translatable);\r
46542 this.draggable = draggable = new Ext.util.Draggable(config);\r
46543 draggable.setTranslatable(component.getTranslatable());\r
46544 draggable.setElement(component.renderElement);\r
46545 draggable.on('destroy', 'onDraggableDestroy', this);\r
46546 if (listeners) {\r
46547 component.on(listeners);\r
46548 }\r
46549 } else if (Ext.isObject(config)) {\r
46550 draggable.setConfig(config);\r
46551 }\r
46552 } else if (draggable) {\r
46553 draggable.destroy();\r
46554 }\r
46555 return this;\r
46556 },\r
46557 getDraggable: function() {\r
46558 return this.draggable;\r
46559 },\r
46560 onDraggableDestroy: function() {\r
46561 delete this.draggable;\r
46562 },\r
46563 onComponentDestroy: function() {\r
46564 var draggable = this.draggable;\r
46565 if (draggable) {\r
46566 draggable.destroy();\r
46567 }\r
46568 }\r
46569});\r
46570\r
46571\r
46572Ext.define('Ext.Component', {\r
46573 extend: Ext.Widget,\r
46574 alternateClassName: 'Ext.lib.Component',\r
46575 mixins: [\r
46576 Ext.mixin.Traversable\r
46577 ],\r
46578 \r
46579 xtype: 'component',\r
46580 cachedConfig: {\r
46581 \r
46582 baseCls: null,\r
46583 \r
46584 cls: null,\r
46585 \r
46586 floatingCls: Ext.baseCSSPrefix + 'floating',\r
46587 \r
46588 hiddenCls: Ext.baseCSSPrefix + 'item-hidden',\r
46589 \r
46590 ui: null,\r
46591 \r
46592 margin: null,\r
46593 \r
46594 padding: null,\r
46595 \r
46596 border: null,\r
46597 \r
46598 styleHtmlCls: Ext.baseCSSPrefix + 'html',\r
46599 \r
46600 styleHtmlContent: null\r
46601 },\r
46602 eventedConfig: {\r
46603 \r
46604 left: null,\r
46605 \r
46606 top: null,\r
46607 \r
46608 right: null,\r
46609 \r
46610 bottom: null,\r
46611 \r
46612 minWidth: null,\r
46613 \r
46614 minHeight: null,\r
46615 \r
46616 maxWidth: null,\r
46617 \r
46618 maxHeight: null,\r
46619 \r
46620 scrollable: null,\r
46621 \r
46622 docked: null,\r
46623 \r
46624 centered: null,\r
46625 \r
46626 hidden: null,\r
46627 \r
46628 disabled: null\r
46629 },\r
46630 config: {\r
46631 \r
46632 html: null,\r
46633 \r
46634 draggable: null,\r
46635 \r
46636 translatable: null,\r
46637 \r
46638 renderTo: null,\r
46639 \r
46640 zIndex: null,\r
46641 \r
46642 tpl: null,\r
46643 \r
46644 enterAnimation: null,\r
46645 \r
46646 exitAnimation: null,\r
46647 \r
46648 showAnimation: null,\r
46649 \r
46650 hideAnimation: null,\r
46651 \r
46652 tplWriteMode: 'overwrite',\r
46653 \r
46654 data: null,\r
46655 \r
46656 disabledCls: Ext.baseCSSPrefix + 'item-disabled',\r
46657 \r
46658 contentEl: null,\r
46659 \r
46660 record: null,\r
46661 \r
46662 plugins: null,\r
46663 \r
46664 useBodyElement: null\r
46665 },\r
46666 \r
46667 \r
46668 \r
46669 \r
46670 \r
46671 \r
46672 \r
46673 \r
46674 \r
46675 \r
46676 \r
46677 \r
46678 \r
46679 \r
46680 \r
46681 defaultBindProperty: 'html',\r
46682 \r
46683 alignmentRegex: /^([a-z]+)-([a-z]+)(\?)?$/,\r
46684 \r
46685 isComponent: true,\r
46686 \r
46687 floating: false,\r
46688 \r
46689 rendered: false,\r
46690 \r
46691 isInner: true,\r
46692 \r
46693 activeAnimation: null,\r
46694 \r
46695 dockPositions: {\r
46696 top: true,\r
46697 right: true,\r
46698 bottom: true,\r
46699 left: true\r
46700 },\r
46701 innerElement: null,\r
46702 element: {\r
46703 reference: 'element',\r
46704 classList: [\r
46705 'x-unsized'\r
46706 ]\r
46707 },\r
46708 widthLayoutSized: false,\r
46709 heightLayoutSized: false,\r
46710 layoutStretched: false,\r
46711 sizeState: false,\r
46712 sizeFlags: 0,\r
46713 LAYOUT_WIDTH: 1,\r
46714 LAYOUT_HEIGHT: 2,\r
46715 LAYOUT_BOTH: 3,\r
46716 LAYOUT_STRETCHED: 4,\r
46717 _scrollableCfg: {\r
46718 x: {\r
46719 x: true,\r
46720 y: false\r
46721 },\r
46722 y: {\r
46723 x: false,\r
46724 y: true\r
46725 },\r
46726 horizontal: {\r
46727 x: true,\r
46728 y: false\r
46729 },\r
46730 vertical: {\r
46731 x: false,\r
46732 y: true\r
46733 },\r
46734 both: {\r
46735 x: true,\r
46736 y: true\r
46737 },\r
46738 'true': {\r
46739 x: true,\r
46740 y: true\r
46741 }\r
46742 },\r
46743 statics: {\r
46744 \r
46745 fromElement: function(node, limit, selector) {\r
46746 return Ext.ComponentManager.fromElement(node, limit, selector);\r
46747 }\r
46748 },\r
46749 initialConfig: null,\r
46750 $initParent: null,\r
46751 \r
46752 constructor: function(config) {\r
46753 var me = this,\r
46754 plugins = config && config.plugins,\r
46755 responsive = 'responsive',\r
46756 i, p;\r
46757 me.onInitializedListeners = [];\r
46758 if (config) {\r
46759 me.initialConfig = config;\r
46760
46761
46762
46763 me.$initParent = config.$initParent;\r
46764 }\r
46765
46766
46767
46768
46769 if (plugins) {\r
46770 plugins = Ext.Array.from(plugins);\r
46771 for (i = plugins.length; i-- > 0; ) {\r
46772 p = plugins[i];\r
46773 if (p === responsive || p.type === responsive) {\r
46774 me.initialConfig = config = Ext.apply({}, config);\r
46775 config.plugins = plugins = plugins.slice(0);\r
46776
46777
46778 plugins[i] = me.createPlugin(p);\r
46779 config = me.initialConfig;\r
46780 break;\r
46781 }\r
46782 }\r
46783 }\r
46784 me.callParent([\r
46785 config\r
46786 ]);\r
46787 me.refreshSizeState = me.doRefreshSizeState;\r
46788 me.refreshFloating = me.doRefreshFloating;\r
46789 if (me.refreshSizeStateOnInitialized) {\r
46790 me.refreshSizeState();\r
46791 }\r
46792 if (me.refreshFloatingOnInitialized) {\r
46793 me.refreshFloating();\r
46794 }\r
46795 me.initialize();\r
46796 me.triggerInitialized();\r
46797 \r
46798 if (me.fullscreen) {\r
46799 me.fireEvent('fullscreen', me);\r
46800 }\r
46801 me.fireEvent('initialize', me);\r
46802 },\r
46803 beforeInitConfig: function(config) {\r
46804 this.beforeInitialize.apply(this, arguments);\r
46805 },\r
46806 \r
46807 beforeInitialize: Ext.emptyFn,\r
46808 \r
46809 initialize: Ext.emptyFn,\r
46810 \r
46811 \r
46812 \r
46813 \r
46814 triggerInitialized: function() {\r
46815 var listeners = this.onInitializedListeners,\r
46816 ln = listeners.length,\r
46817 listener, fn, scope, args, i;\r
46818 if (!this.initialized) {\r
46819 this.initialized = true;\r
46820 if (ln > 0) {\r
46821 for (i = 0; i < ln; i++) {\r
46822 listener = listeners[i];\r
46823 fn = listener.fn;\r
46824 scope = listener.scope;\r
46825 args = listener.args;\r
46826 if (typeof fn == 'string') {\r
46827 scope[fn].apply(scope, args);\r
46828 } else {\r
46829 fn.apply(scope, args);\r
46830 }\r
46831 }\r
46832 listeners.length = 0;\r
46833 }\r
46834 }\r
46835 },\r
46836 \r
46837 onInitialized: function(fn, scope, args) {\r
46838 var listeners = this.onInitializedListeners;\r
46839 if (!scope) {\r
46840 scope = this;\r
46841 }\r
46842 if (this.initialized) {\r
46843 if (typeof fn == 'string') {\r
46844 scope[fn].apply(scope, args);\r
46845 } else {\r
46846 fn.apply(scope, args);\r
46847 }\r
46848 } else {\r
46849 listeners.push({\r
46850 fn: fn,\r
46851 scope: scope,\r
46852 args: args\r
46853 });\r
46854 }\r
46855 },\r
46856 initElement: function() {\r
46857 var me = this;\r
46858 me.callParent();\r
46859 if (!me.innerElement) {\r
46860 me.innerElement = me.element;\r
46861 }\r
46862 if (!me.bodyElement) {\r
46863 me.bodyElement = me.innerElement;\r
46864 }\r
46865 },\r
46866 applyPlugins: function(plugins) {\r
46867 var me = this,\r
46868 config, ln, i, plugin;\r
46869 if (!plugins) {\r
46870 return plugins;\r
46871 }\r
46872 plugins = [].concat(plugins);\r
46873 for (i = 0 , ln = plugins.length; i < ln; i++) {\r
46874 plugins[i] = me.createPlugin(plugins[i]);\r
46875 }\r
46876 return plugins;\r
46877 },\r
46878 createPlugin: function(config) {\r
46879 if (typeof config === 'string') {\r
46880 config = {\r
46881 type: config\r
46882 };\r
46883 }\r
46884 var ret = config;\r
46885 if (!config.isInstance) {\r
46886
46887 config.cmp = this;\r
46888 ret = Ext.factory(config, null, null, 'plugin');\r
46889
46890 delete config.cmp;\r
46891 }\r
46892 if (ret.setCmp) {\r
46893 ret.setCmp(this);\r
46894 }\r
46895 return ret;\r
46896 },\r
46897 updatePlugins: function(newPlugins, oldPlugins) {\r
46898 var ln, i;\r
46899 if (newPlugins) {\r
46900 for (i = 0 , ln = newPlugins.length; i < ln; i++) {\r
46901 newPlugins[i].init(this);\r
46902 }\r
46903 }\r
46904 if (oldPlugins) {\r
46905 for (i = 0 , ln = oldPlugins.length; i < ln; i++) {\r
46906 Ext.destroy(oldPlugins[i]);\r
46907 }\r
46908 }\r
46909 },\r
46910 applyScrollable: function(scrollable, oldScrollable) {\r
46911 var me = this,\r
46912 bodyElement, touchScroll, x, y, scrollableCfg;\r
46913 if (scrollable) {\r
46914 if (scrollable === true || typeof scrollable === 'string') {\r
46915 scrollableCfg = me._scrollableCfg[scrollable];\r
46916
46917 if (!scrollableCfg) {\r
46918 Ext.raise("'" + scrollable + "'is not a valid value for 'scrollable'");\r
46919 }\r
46920
46921 scrollable = scrollableCfg;\r
46922 }\r
46923 if (oldScrollable) {\r
46924 oldScrollable.setConfig(scrollable);\r
46925 scrollable = oldScrollable;\r
46926 } else {\r
46927 touchScroll = Ext.supports.touchScroll;\r
46928 if (touchScroll && !scrollable.translatable) {\r
46929 scrollable.translatable = {\r
46930 translationMethod: (touchScroll === 1) ? 'scrollparent' : 'csstransform'\r
46931 };\r
46932 }\r
46933 if (touchScroll === 1) {\r
46934
46935
46936 scrollable = Ext.Object.chain(scrollable);\r
46937
46938
46939 scrollable.indicators = false;\r
46940 }\r
46941 scrollable = Ext.scroll.Scroller.create(scrollable);\r
46942 scrollable.component = me;\r
46943 me.setUseBodyElement(true);\r
46944 bodyElement = me.bodyElement;\r
46945 if (touchScroll === 2) {\r
46946 scrollable.setInnerElement(me.innerElement);\r
46947 scrollable.setElement(bodyElement);\r
46948 } else {\r
46949 if (touchScroll === 1) {\r
46950
46951
46952
46953
46954
46955 x = scrollable.getX();\r
46956 y = scrollable.getY();\r
46957 bodyElement.setStyle({\r
46958 overflowX: x === true ? 'auto' : !x ? 'hidden' : x,\r
46959 overflowY: y === true ? 'auto' : !y ? 'hidden' : y\r
46960 });\r
46961 bodyElement.disableTouchScroll();\r
46962 }\r
46963 scrollable.setElement(bodyElement);\r
46964 }\r
46965 if (me.isPainted()) {\r
46966 me.onPainted();\r
46967 }\r
46968 me.on('painted', 'onPainted', me);\r
46969 }\r
46970 }\r
46971 return scrollable;\r
46972 },\r
46973 onPainted: function() {\r
46974 var scrollable = this.getScrollable();\r
46975 if (scrollable && scrollable.isTouchScroller && scrollable.getAutoRefresh()) {\r
46976 scrollable.refresh();\r
46977 }\r
46978 },\r
46979 updateRenderTo: function(newContainer) {\r
46980 this.renderTo(newContainer);\r
46981 },\r
46982 updateBorder: function(border) {\r
46983 this.element.setStyle('border-width', border ? '' : '0');\r
46984 },\r
46985 updatePadding: function(padding) {\r
46986 this.innerElement.setPadding(padding);\r
46987 },\r
46988 updateMargin: function(margin) {\r
46989 this.element.setMargin(margin);\r
46990 },\r
46991 updateUi: function(newUi, oldUi) {\r
46992 var baseCls = this.getBaseCls(),\r
46993 element = this.element,\r
46994 currentUi = this.currentUi;\r
46995 if (baseCls) {\r
46996 if (oldUi) {\r
46997 if (currentUi) {\r
46998 element.removeCls(currentUi);\r
46999 } else {\r
47000 element.removeCls(baseCls + '-' + oldUi);\r
47001 }\r
47002 }\r
47003 if (newUi) {\r
47004 element.addCls(newUi, baseCls);\r
47005 this.currentUi = baseCls + '-' + newUi;\r
47006
47007 if (!this.self.prototype.currentUi) {\r
47008 this.self.prototype.currentUi = this.currentUi;\r
47009 }\r
47010 }\r
47011 }\r
47012 },\r
47013 applyBaseCls: function(baseCls) {\r
47014 return baseCls || Ext.baseCSSPrefix + this.xtype;\r
47015 },\r
47016 updateBaseCls: function(newBaseCls, oldBaseCls) {\r
47017 var me = this,\r
47018 ui = me.getUi();\r
47019 if (oldBaseCls) {\r
47020 this.element.removeCls(oldBaseCls);\r
47021 if (ui) {\r
47022 this.element.removeCls(this.currentUi);\r
47023 }\r
47024 }\r
47025 if (newBaseCls) {\r
47026 this.element.addCls(newBaseCls);\r
47027 if (ui) {\r
47028 this.element.addCls(newBaseCls, null, ui);\r
47029 this.currentUi = newBaseCls + '-' + ui;\r
47030 }\r
47031 }\r
47032 },\r
47033 \r
47034 addCls: function(cls, prefix, suffix) {\r
47035 var oldCls = this.getCls(),\r
47036 newCls = (oldCls) ? oldCls.slice() : [],\r
47037 ln, i, cachedCls;\r
47038 prefix = prefix || '';\r
47039 suffix = suffix || '';\r
47040 if (typeof cls == "string") {\r
47041 cls = [\r
47042 cls\r
47043 ];\r
47044 }\r
47045 ln = cls.length;\r
47046
47047
47048
47049 if (!newCls.length && prefix === '' && suffix === '') {\r
47050 newCls = cls;\r
47051 } else {\r
47052 for (i = 0; i < ln; i++) {\r
47053 cachedCls = prefix + cls[i] + suffix;\r
47054 if (newCls.indexOf(cachedCls) == -1) {\r
47055 newCls.push(cachedCls);\r
47056 }\r
47057 }\r
47058 }\r
47059 this.setCls(newCls);\r
47060 },\r
47061 \r
47062 removeCls: function(cls, prefix, suffix) {\r
47063 var oldCls = this.getCls(),\r
47064 newCls = (oldCls) ? oldCls.slice() : [],\r
47065 ln, i;\r
47066 prefix = prefix || '';\r
47067 suffix = suffix || '';\r
47068 if (typeof cls == "string") {\r
47069 newCls = Ext.Array.remove(newCls, prefix + cls + suffix);\r
47070 } else {\r
47071 ln = cls.length;\r
47072 for (i = 0; i < ln; i++) {\r
47073 newCls = Ext.Array.remove(newCls, prefix + cls[i] + suffix);\r
47074 }\r
47075 }\r
47076 this.setCls(newCls);\r
47077 },\r
47078 \r
47079 replaceCls: function(oldCls, newCls, prefix, suffix) {\r
47080
47081
47082 var cls = this.getCls(),\r
47083 array = (cls) ? cls.slice() : [],\r
47084 ln, i, cachedCls;\r
47085 prefix = prefix || '';\r
47086 suffix = suffix || '';\r
47087
47088 if (typeof oldCls == "string") {\r
47089 array = Ext.Array.remove(array, prefix + oldCls + suffix);\r
47090 } else if (oldCls) {\r
47091 ln = oldCls.length;\r
47092 for (i = 0; i < ln; i++) {\r
47093 array = Ext.Array.remove(array, prefix + oldCls[i] + suffix);\r
47094 }\r
47095 }\r
47096
47097 if (typeof newCls == "string") {\r
47098 array.push(prefix + newCls + suffix);\r
47099 } else if (newCls) {\r
47100 ln = newCls.length;\r
47101
47102
47103
47104 if (!array.length && prefix === '' && suffix === '') {\r
47105 array = newCls;\r
47106 } else {\r
47107 for (i = 0; i < ln; i++) {\r
47108 cachedCls = prefix + newCls[i] + suffix;\r
47109 if (array.indexOf(cachedCls) == -1) {\r
47110 array.push(cachedCls);\r
47111 }\r
47112 }\r
47113 }\r
47114 }\r
47115 this.setCls(array);\r
47116 },\r
47117 \r
47118 toggleCls: function(className, \r
47119 state) {\r
47120 var oldCls = this.getCls(),\r
47121 newCls = oldCls ? oldCls.slice() : [];\r
47122 if (typeof state !== 'boolean') {\r
47123 state = newCls.indexOf(className) === -1;\r
47124 }\r
47125 if (state) {\r
47126 Ext.Array.include(newCls, className);\r
47127 } else {\r
47128 Ext.Array.remove(newCls, className);\r
47129 }\r
47130 this.setCls(newCls);\r
47131 return this;\r
47132 },\r
47133 \r
47134 applyCls: function(cls) {\r
47135 if (typeof cls == "string") {\r
47136 cls = [\r
47137 cls\r
47138 ];\r
47139 }\r
47140
47141 if (!cls || !cls.length) {\r
47142 cls = null;\r
47143 }\r
47144 return cls;\r
47145 },\r
47146 \r
47147 updateCls: function(newCls, oldCls) {\r
47148 var el = this.element;\r
47149 if (el && ((newCls && !oldCls) || (!newCls && oldCls) || newCls.length != oldCls.length || Ext.Array.difference(newCls, oldCls).length > 0)) {\r
47150 el.replaceCls(oldCls, newCls);\r
47151 }\r
47152 },\r
47153 \r
47154 updateStyleHtmlCls: function(newHtmlCls, oldHtmlCls) {\r
47155 var innerHtmlElement = this.innerHtmlElement,\r
47156 innerElement = this.innerElement;\r
47157 if (this.getStyleHtmlContent() && oldHtmlCls) {\r
47158 if (innerHtmlElement) {\r
47159 innerHtmlElement.replaceCls(oldHtmlCls, newHtmlCls);\r
47160 } else {\r
47161 innerElement.replaceCls(oldHtmlCls, newHtmlCls);\r
47162 }\r
47163 }\r
47164 },\r
47165 applyStyleHtmlContent: function(config) {\r
47166 return Boolean(config);\r
47167 },\r
47168 updateStyleHtmlContent: function(styleHtmlContent) {\r
47169 var htmlCls = this.getStyleHtmlCls(),\r
47170 innerElement = this.innerElement,\r
47171 innerHtmlElement = this.innerHtmlElement;\r
47172 if (styleHtmlContent) {\r
47173 if (innerHtmlElement) {\r
47174 innerHtmlElement.addCls(htmlCls);\r
47175 } else {\r
47176 innerElement.addCls(htmlCls);\r
47177 }\r
47178 } else {\r
47179 if (innerHtmlElement) {\r
47180 innerHtmlElement.removeCls(htmlCls);\r
47181 } else {\r
47182 innerElement.addCls(htmlCls);\r
47183 }\r
47184 }\r
47185 },\r
47186 applyContentEl: function(contentEl) {\r
47187 if (contentEl) {\r
47188 return Ext.get(contentEl);\r
47189 }\r
47190 },\r
47191 updateContentEl: function(newContentEl, oldContentEl) {\r
47192 if (oldContentEl) {\r
47193 oldContentEl.hide();\r
47194 Ext.getBody().append(oldContentEl);\r
47195 }\r
47196 if (newContentEl) {\r
47197 this.setHtml(newContentEl.dom);\r
47198 newContentEl.show();\r
47199 }\r
47200 },\r
47201 updateUseBodyElement: function(useBodyElement) {\r
47202 if (useBodyElement) {\r
47203 this.link('bodyElement', this.innerElement.wrap({\r
47204 cls: 'x-body'\r
47205 }));\r
47206 }\r
47207 },\r
47208 \r
47209 isCentered: function() {\r
47210 return Boolean(this.getCentered());\r
47211 },\r
47212 isFloating: function() {\r
47213 return this.floating;\r
47214 },\r
47215 isDocked: function() {\r
47216 return Boolean(this.getDocked());\r
47217 },\r
47218 isInnerItem: function() {\r
47219 return this.isInner;\r
47220 },\r
47221 setIsInner: function(isInner) {\r
47222 if (isInner !== this.isInner) {\r
47223 this.isInner = isInner;\r
47224 if (this.initialized) {\r
47225 this.fireEvent('innerstatechange', this, isInner);\r
47226 }\r
47227 }\r
47228 },\r
47229 applyTop: function(top) {\r
47230 return this.filterLengthValue(top);\r
47231 },\r
47232 applyRight: function(right) {\r
47233 return this.filterLengthValue(right);\r
47234 },\r
47235 applyBottom: function(bottom) {\r
47236 return this.filterLengthValue(bottom);\r
47237 },\r
47238 applyLeft: function(left) {\r
47239 return this.filterLengthValue(left);\r
47240 },\r
47241 applyMinWidth: function(width) {\r
47242 return this.filterLengthValue(width);\r
47243 },\r
47244 applyMinHeight: function(height) {\r
47245 return this.filterLengthValue(height);\r
47246 },\r
47247 applyMaxWidth: function(width) {\r
47248 return this.filterLengthValue(width);\r
47249 },\r
47250 applyMaxHeight: function(height) {\r
47251 return this.filterLengthValue(height);\r
47252 },\r
47253 updateTop: function(top) {\r
47254 this.element.setTop(top);\r
47255 this.refreshFloating();\r
47256 },\r
47257 updateRight: function(right) {\r
47258 this.element.setRight(right);\r
47259 this.refreshFloating();\r
47260 },\r
47261 updateBottom: function(bottom) {\r
47262 this.element.setBottom(bottom);\r
47263 this.refreshFloating();\r
47264 },\r
47265 updateLeft: function(left) {\r
47266 this.element.setLeft(left);\r
47267 this.refreshFloating();\r
47268 },\r
47269 updateWidth: function(width) {\r
47270 this.element.setWidth(width);\r
47271 this.refreshSizeState();\r
47272 },\r
47273 updateHeight: function(height) {\r
47274 this.element.setHeight(height);\r
47275 this.refreshSizeState();\r
47276 },\r
47277 updateFlex: Ext.emptyFn,\r
47278 refreshSizeState: function() {\r
47279 this.refreshSizeStateOnInitialized = true;\r
47280 },\r
47281 doRefreshSizeState: function() {\r
47282 var hasWidth = this.getWidth() !== null || this.widthLayoutSized || (this.getLeft() !== null && this.getRight() !== null),\r
47283 hasHeight = this.getHeight() !== null || this.heightLayoutSized || (this.getTop() !== null && this.getBottom() !== null),\r
47284 stretched = this.layoutStretched || this.hasCSSMinHeight || (!hasHeight && this.getMinHeight() !== null),\r
47285 state = hasWidth && hasHeight,\r
47286 flags = (hasWidth && this.LAYOUT_WIDTH) | (hasHeight && this.LAYOUT_HEIGHT) | (stretched && this.LAYOUT_STRETCHED);\r
47287 if (!state && stretched) {\r
47288 state = null;\r
47289 }\r
47290 this.setSizeState(state);\r
47291 this.setSizeFlags(flags);\r
47292 },\r
47293 setLayoutSizeFlags: function(flags) {\r
47294 this.layoutStretched = !!(flags & this.LAYOUT_STRETCHED);\r
47295 this.widthLayoutSized = !!(flags & this.LAYOUT_WIDTH);\r
47296 this.heightLayoutSized = !!(flags & this.LAYOUT_HEIGHT);\r
47297 this.refreshSizeState();\r
47298 },\r
47299 setSizeFlags: function(flags) {\r
47300 var me = this,\r
47301 el = me.element,\r
47302 hasWidth, hasHeight, stretched;\r
47303 if (flags !== this.sizeFlags) {\r
47304 me.sizeFlags = flags;\r
47305 hasWidth = !!(flags & this.LAYOUT_WIDTH);\r
47306 hasHeight = !!(flags & this.LAYOUT_HEIGHT);\r
47307 stretched = !!(flags & this.LAYOUT_STRETCHED);\r
47308 el.toggleCls(Ext.baseCSSPrefix + 'has-width', hasWidth && !stretched && !hasHeight);\r
47309 el.toggleCls(Ext.baseCSSPrefix + 'has-height', hasHeight && !stretched && !hasWidth);\r
47310 if (me.initialized) {\r
47311 me.fireEvent('sizeflagschange', me, flags);\r
47312 }\r
47313 }\r
47314 },\r
47315 getSizeFlags: function() {\r
47316 if (!this.initialized) {\r
47317 this.doRefreshSizeState();\r
47318 }\r
47319 return this.sizeFlags;\r
47320 },\r
47321 setSizeState: function(state) {\r
47322 if (state !== this.sizeState) {\r
47323 this.sizeState = state;\r
47324 this.element.setSizeState(state);\r
47325 if (this.initialized) {\r
47326 this.fireEvent('sizestatechange', this, state);\r
47327 }\r
47328 }\r
47329 },\r
47330 getSizeState: function() {\r
47331 if (!this.initialized) {\r
47332 this.doRefreshSizeState();\r
47333 }\r
47334 return this.sizeState;\r
47335 },\r
47336 updateMinWidth: function(width) {\r
47337 this.element.setMinWidth(width);\r
47338 },\r
47339 updateMinHeight: function(height) {\r
47340 this.element.setMinHeight(height);\r
47341 this.refreshSizeState();\r
47342 },\r
47343 updateMaxWidth: function(width) {\r
47344 this.element.setMaxWidth(width);\r
47345 },\r
47346 updateMaxHeight: function(height) {\r
47347 this.element.setMaxHeight(height);\r
47348 },\r
47349 \r
47350 applyCentered: function(centered) {\r
47351 centered = Boolean(centered);\r
47352 if (centered) {\r
47353 this.refreshInnerState = Ext.emptyFn;\r
47354 if (this.isFloating()) {\r
47355 this.resetFloating();\r
47356 }\r
47357 if (this.isDocked()) {\r
47358 this.setDocked(false);\r
47359 }\r
47360 this.setIsInner(false);\r
47361 delete this.refreshInnerState;\r
47362 }\r
47363 return centered;\r
47364 },\r
47365 updateCentered: function(centered) {\r
47366 this.toggleCls(this.getFloatingCls(), centered);\r
47367 if (!centered) {\r
47368 this.refreshInnerState();\r
47369 }\r
47370 },\r
47371 applyDocked: function(docked) {\r
47372 if (!docked) {\r
47373 return null;\r
47374 }\r
47375
47376 if (!/^(top|right|bottom|left)$/.test(docked)) {\r
47377 Ext.Logger.error("Invalid docking position of '" + docked.position + "', must be either 'top', 'right', 'bottom', " + "'left' or `null` (for no docking)", this);\r
47378 return;\r
47379 }\r
47380
47381 this.refreshInnerState = Ext.emptyFn;\r
47382 if (this.isFloating()) {\r
47383 this.resetFloating();\r
47384 }\r
47385 if (this.isCentered()) {\r
47386 this.setCentered(false);\r
47387 }\r
47388 this.setIsInner(false);\r
47389 delete this.refreshInnerState;\r
47390 return docked;\r
47391 },\r
47392 updateDocked: function(docked, oldDocked) {\r
47393 this.fireEvent('afterdockedchange', this, docked, oldDocked);\r
47394 if (!docked) {\r
47395 this.refreshInnerState();\r
47396 }\r
47397 },\r
47398 \r
47399 resetFloating: function() {\r
47400 this.setTop(null);\r
47401 this.setRight(null);\r
47402 this.setBottom(null);\r
47403 this.setLeft(null);\r
47404 },\r
47405 refreshInnerState: function() {\r
47406 this.setIsInner(!this.isCentered() && !this.isFloating() && !this.isDocked());\r
47407 },\r
47408 refreshFloating: function() {\r
47409 this.refreshFloatingOnInitialized = true;\r
47410 },\r
47411 doRefreshFloating: function() {\r
47412 var me = this,\r
47413 floating = true,\r
47414 floatingCls = this.getFloatingCls();\r
47415 if (me.getTop() === null && me.getBottom() === null && me.getRight() === null && me.getLeft() === null) {\r
47416 floating = false;\r
47417 } else {\r
47418 me.refreshSizeState();\r
47419 }\r
47420 if (floating !== this.floating) {\r
47421 me.floating = floating;\r
47422 if (floating) {\r
47423 me.refreshInnerState = Ext.emptyFn;\r
47424 if (me.isCentered()) {\r
47425 me.setCentered(false);\r
47426 }\r
47427 if (me.isDocked()) {\r
47428 me.setDocked(false);\r
47429 }\r
47430 me.setIsInner(false);\r
47431 delete me.refreshInnerState;\r
47432 }\r
47433 me.element.toggleCls(floatingCls, floating);\r
47434 if (me.initialized) {\r
47435 me.fireEvent('floatingchange', me, floating);\r
47436 }\r
47437 if (!floating) {\r
47438 me.refreshInnerState();\r
47439 }\r
47440 }\r
47441 },\r
47442 \r
47443 updateFloatingCls: function(newFloatingCls, oldFloatingCls) {\r
47444 if (this.isFloating()) {\r
47445 this.replaceCls(oldFloatingCls, newFloatingCls);\r
47446 }\r
47447 },\r
47448 applyDisabled: function(disabled) {\r
47449 return Boolean(disabled);\r
47450 },\r
47451 updateDisabled: function(disabled) {\r
47452 this.element.toggleCls(this.getDisabledCls(), disabled);\r
47453 },\r
47454 updateDisabledCls: function(newDisabledCls, oldDisabledCls) {\r
47455 if (this.isDisabled()) {\r
47456 this.element.replaceCls(oldDisabledCls, newDisabledCls);\r
47457 }\r
47458 },\r
47459 \r
47460 disable: function() {\r
47461 this.setDisabled(true);\r
47462 },\r
47463 \r
47464 enable: function() {\r
47465 this.setDisabled(false);\r
47466 },\r
47467 \r
47468 isDisabled: function() {\r
47469 return this.getDisabled();\r
47470 },\r
47471 applyZIndex: function(zIndex) {\r
47472 if (!zIndex && zIndex !== 0) {\r
47473 zIndex = null;\r
47474 }\r
47475 if (zIndex !== null) {\r
47476 zIndex = Number(zIndex);\r
47477 if (isNaN(zIndex)) {\r
47478 zIndex = null;\r
47479 }\r
47480 }\r
47481 return zIndex;\r
47482 },\r
47483 updateZIndex: function(zIndex) {\r
47484 var element = this.element,\r
47485 domStyle;\r
47486 if (element && !element.destroyed) {\r
47487 domStyle = element.dom.style;\r
47488 if (zIndex !== null) {\r
47489 domStyle.setProperty('z-index', zIndex, 'important');\r
47490 } else {\r
47491 domStyle.removeProperty('z-index');\r
47492 }\r
47493 }\r
47494 },\r
47495 getInnerHtmlElement: function() {\r
47496 var innerHtmlElement = this.innerHtmlElement,\r
47497 styleHtmlCls;\r
47498 if (!innerHtmlElement || !innerHtmlElement.dom || !innerHtmlElement.dom.parentNode) {\r
47499 this.innerHtmlElement = innerHtmlElement = Ext.Element.create({\r
47500 cls: 'x-innerhtml'\r
47501 });\r
47502 if (this.getStyleHtmlContent()) {\r
47503 styleHtmlCls = this.getStyleHtmlCls();\r
47504 this.innerHtmlElement.addCls(styleHtmlCls);\r
47505 this.innerElement.removeCls(styleHtmlCls);\r
47506 }\r
47507 this.innerElement.appendChild(innerHtmlElement);\r
47508 }\r
47509 return innerHtmlElement;\r
47510 },\r
47511 updateHtml: function(html) {\r
47512 if (!this.destroyed) {\r
47513 var innerHtmlElement = this.getInnerHtmlElement();\r
47514 if (Ext.isElement(html)) {\r
47515 innerHtmlElement.setHtml('');\r
47516 innerHtmlElement.append(html);\r
47517 } else {\r
47518 innerHtmlElement.setHtml(html);\r
47519 }\r
47520 }\r
47521 },\r
47522 applyHidden: function(hidden) {\r
47523 return Boolean(hidden);\r
47524 },\r
47525 updateHidden: function(hidden) {\r
47526 var me = this,\r
47527 element = me.renderElement;\r
47528 if (element.destroyed) {\r
47529 return;\r
47530 }\r
47531 if (hidden) {\r
47532 element.hide();\r
47533 } else {\r
47534 element.show();\r
47535 }\r
47536 if (me.element) {\r
47537 me.element.toggleCls(me.getHiddenCls(), hidden);\r
47538 }\r
47539 me.fireEvent(hidden ? 'hide' : 'show', me);\r
47540 },\r
47541 updateHiddenCls: function(newHiddenCls, oldHiddenCls) {\r
47542 if (this.isHidden()) {\r
47543 this.element.replaceCls(oldHiddenCls, newHiddenCls);\r
47544 }\r
47545 },\r
47546 \r
47547 isHidden: function(deep) {\r
47548 var hidden = !!this.getHidden(),\r
47549 owner;\r
47550 if (!hidden && deep) {\r
47551 owner = this.getRefOwner();\r
47552 while (owner) {\r
47553 hidden = !!owner.getHidden();\r
47554 if (hidden) {\r
47555 break;\r
47556 }\r
47557 owner = owner.getRefOwner();\r
47558 }\r
47559 }\r
47560 return hidden;\r
47561 },\r
47562 \r
47563 isVisible: function(deep) {\r
47564 return !this.isHidden(deep);\r
47565 },\r
47566 \r
47567 hide: function(animation) {\r
47568 var me = this,\r
47569 activeAnim = me.activeAnimation;\r
47570 me.setCurrentAlignmentInfo(null);\r
47571 if (activeAnim) {\r
47572 activeAnim.on({\r
47573 animationend: function() {\r
47574 me.hide(animation);\r
47575 },\r
47576 single: true\r
47577 });\r
47578 return me;\r
47579 }\r
47580 if (!me.getHidden()) {\r
47581 if (animation === undefined || (animation && animation.isComponent)) {\r
47582 animation = me.getHideAnimation();\r
47583 }\r
47584 if (animation) {\r
47585 if (animation === true) {\r
47586 animation = 'fadeOut';\r
47587 }\r
47588 me.on({\r
47589 beforehiddenchange: 'animateFn',\r
47590 scope: this,\r
47591 single: true,\r
47592 args: [\r
47593 animation\r
47594 ]\r
47595 });\r
47596 }\r
47597 me.setHidden(true);\r
47598 }\r
47599 return me;\r
47600 },\r
47601 \r
47602 show: function(animation) {\r
47603 if (this.activeAnimation) {\r
47604 this.activeAnimation.on({\r
47605 animationend: function() {\r
47606 this.show(animation);\r
47607 },\r
47608 scope: this,\r
47609 single: true\r
47610 });\r
47611 return this;\r
47612 }\r
47613 var hidden = this.getHidden();\r
47614 if (hidden || hidden === null) {\r
47615 if (animation === true) {\r
47616 animation = 'fadeIn';\r
47617 } else if (animation === undefined || (animation && animation.isComponent)) {\r
47618 animation = this.getShowAnimation();\r
47619 }\r
47620 if (animation) {\r
47621 this.beforeShowAnimation();\r
47622 this.on({\r
47623 beforehiddenchange: 'animateFn',\r
47624 scope: this,\r
47625 single: true,\r
47626 args: [\r
47627 animation\r
47628 ]\r
47629 });\r
47630 }\r
47631 this.setHidden(false);\r
47632 }\r
47633 return this;\r
47634 },\r
47635 beforeShowAnimation: function() {\r
47636 var element = this.element;\r
47637 if (element) {\r
47638 this.renderElement.show();\r
47639 element.removeCls(this.getHiddenCls());\r
47640 }\r
47641 },\r
47642 animateFn: function(animation, component, newState, oldState, controller) {\r
47643 var me = this;\r
47644 if (animation && (!newState || (newState && me.isPainted()))) {\r
47645 me.activeAnimation = new Ext.fx.Animation(animation);\r
47646 me.activeAnimation.setElement(component.element);\r
47647 if (!Ext.isEmpty(newState)) {\r
47648 me.activeAnimation.setOnEnd(function() {\r
47649 me.activeAnimation = null;\r
47650 controller.resume();\r
47651 });\r
47652 controller.pause();\r
47653 }\r
47654 Ext.Animator.run(me.activeAnimation);\r
47655 }\r
47656 },\r
47657 \r
47658 setVisibility: function(isVisible) {\r
47659 this.renderElement.setVisible(isVisible);\r
47660 },\r
47661 \r
47662 isRendered: function() {\r
47663 return this.rendered;\r
47664 },\r
47665 \r
47666 isPainted: function() {\r
47667 return this.renderElement.isPainted();\r
47668 },\r
47669 \r
47670 applyTpl: function(config) {\r
47671 return (Ext.isObject(config) && config.isTemplate) ? config : new Ext.XTemplate(config);\r
47672 },\r
47673 applyData: function(data) {\r
47674 if (Ext.isObject(data)) {\r
47675 return Ext.apply({}, data);\r
47676 } else if (!data) {\r
47677 data = {};\r
47678 }\r
47679 return data;\r
47680 },\r
47681 \r
47682 updateData: function(newData) {\r
47683 var me = this;\r
47684 if (newData) {\r
47685 var tpl = me.getTpl(),\r
47686 tplWriteMode = me.getTplWriteMode();\r
47687 if (tpl) {\r
47688 tpl[tplWriteMode](me.getInnerHtmlElement(), newData);\r
47689 }\r
47690 \r
47691 this.fireEvent('updatedata', me, newData);\r
47692 }\r
47693 },\r
47694 applyRecord: function(config) {\r
47695 if (config && Ext.isObject(config) && config.isModel) {\r
47696 return config;\r
47697 }\r
47698 return null;\r
47699 },\r
47700 updateRecord: function(newRecord, oldRecord) {\r
47701 var me = this;\r
47702 if (oldRecord) {\r
47703 oldRecord.unjoin(me);\r
47704 }\r
47705 if (!newRecord) {\r
47706 me.updateData('');\r
47707 } else {\r
47708 newRecord.join(me);\r
47709 me.updateData(newRecord.getData(true));\r
47710 }\r
47711 },\r
47712 \r
47713 afterEdit: function() {\r
47714 this.updateRecord(this.getRecord());\r
47715 },\r
47716 \r
47717 afterErase: function() {\r
47718 this.setRecord(null);\r
47719 },\r
47720 \r
47721 getXTypes: function() {\r
47722 return this.xtypesChain.join('/');\r
47723 },\r
47724 getDraggableBehavior: function() {\r
47725 var behavior = this.draggableBehavior;\r
47726 if (!behavior) {\r
47727 behavior = this.draggableBehavior = new Ext.behavior.Draggable(this);\r
47728 }\r
47729 return behavior;\r
47730 },\r
47731 applyDraggable: function(config) {\r
47732 this.getDraggableBehavior().setConfig(config);\r
47733 },\r
47734 getDraggable: function() {\r
47735 return this.getDraggableBehavior().getDraggable();\r
47736 },\r
47737 getTranslatableBehavior: function() {\r
47738 var behavior = this.translatableBehavior;\r
47739 if (!behavior) {\r
47740 behavior = this.translatableBehavior = new Ext.behavior.Translatable(this);\r
47741 }\r
47742 return behavior;\r
47743 },\r
47744 applyTranslatable: function(config) {\r
47745 this.getTranslatableBehavior().setConfig(config);\r
47746 },\r
47747 getTranslatable: function() {\r
47748 return this.getTranslatableBehavior().getTranslatable();\r
47749 },\r
47750 translateAxis: function(axis, value, animation) {\r
47751 var x, y;\r
47752 if (axis === 'x') {\r
47753 x = value;\r
47754 } else {\r
47755 y = value;\r
47756 }\r
47757 return this.translate(x, y, animation);\r
47758 },\r
47759 translate: function() {\r
47760 var translatable = this.getTranslatable();\r
47761 if (!translatable) {\r
47762 this.setTranslatable(true);\r
47763 translatable = this.getTranslatable();\r
47764 }\r
47765 translatable.translate.apply(translatable, arguments);\r
47766 },\r
47767 \r
47768 showBy: function(component, alignment) {\r
47769 var me = this,\r
47770 viewport = Ext.Viewport,\r
47771 parent = me.getParent();\r
47772 me.setVisibility(false);\r
47773 if (parent !== viewport) {\r
47774 viewport.add(me);\r
47775 }\r
47776 me.show();\r
47777 me.on({\r
47778 hide: 'onShowByErased',\r
47779 destroy: 'onShowByErased',\r
47780 single: true,\r
47781 scope: me\r
47782 });\r
47783 viewport.on('resize', 'alignTo', me, {\r
47784 args: [\r
47785 component,\r
47786 alignment\r
47787 ]\r
47788 });\r
47789 me.alignTo(component, alignment);\r
47790 me.setVisibility(true);\r
47791 },\r
47792 \r
47793 onShowByErased: function() {\r
47794 Ext.Viewport.un('resize', 'alignTo', this);\r
47795 },\r
47796 \r
47797 getAlignmentInfo: function(component, alignment) {\r
47798 var alignToElement = component.isComponent ? component.renderElement : component,\r
47799 alignToBox = alignToElement.getBox(),\r
47800 element = this.renderElement,\r
47801 box = element.getBox(),\r
47802 stats = {\r
47803 alignToBox: alignToBox,\r
47804 alignment: alignment,\r
47805 top: alignToBox.top,\r
47806 left: alignToBox.left,\r
47807 alignToWidth: alignToBox.width,\r
47808 alignToHeight: alignToBox.height,\r
47809 width: box.width,\r
47810 height: box.height\r
47811 },\r
47812 currentAlignmentInfo = this.getCurrentAlignmentInfo(),\r
47813 isAligned = true;\r
47814 if (!Ext.isEmpty(currentAlignmentInfo)) {\r
47815 Ext.Object.each(stats, function(key, value) {\r
47816 if (!Ext.isObject(value) && currentAlignmentInfo[key] != value) {\r
47817 isAligned = false;\r
47818 return false;\r
47819 }\r
47820 return true;\r
47821 });\r
47822 } else {\r
47823 isAligned = false;\r
47824 }\r
47825 return {\r
47826 isAligned: isAligned,\r
47827 stats: stats\r
47828 };\r
47829 },\r
47830 \r
47831 getCurrentAlignmentInfo: function() {\r
47832 return this.$currentAlignmentInfo;\r
47833 },\r
47834 \r
47835 setCurrentAlignmentInfo: function(alignmentInfo) {\r
47836 this.$currentAlignmentInfo = Ext.isEmpty(alignmentInfo) ? null : Ext.merge({}, alignmentInfo.stats ? alignmentInfo.stats : alignmentInfo);\r
47837 },\r
47838 \r
47839 alignTo: function(component, alignment) {\r
47840 var alignmentInfo = this.getAlignmentInfo(component, alignment);\r
47841 if (alignmentInfo.isAligned) {\r
47842 return;\r
47843 }\r
47844 \r
47845 var alignToBox = alignmentInfo.stats.alignToBox,\r
47846 constrainBox = this.getParent().element.getBox(),\r
47847 alignToHeight = alignmentInfo.stats.alignToHeight,\r
47848 alignToWidth = alignmentInfo.stats.alignToWidth,\r
47849 height = alignmentInfo.stats.height,\r
47850 width = alignmentInfo.stats.width;\r
47851
47852 constrainBox.bottom -= 5;\r
47853 constrainBox.height -= 10;\r
47854 constrainBox.left += 5;\r
47855 constrainBox.right -= 5;\r
47856 constrainBox.top += 5;\r
47857 constrainBox.width -= 10;\r
47858 if (!alignment || alignment === 'auto') {\r
47859 if (constrainBox.bottom - alignToBox.bottom < height) {\r
47860 if (alignToBox.top - constrainBox.top < height) {\r
47861 if (alignToBox.left - constrainBox.left < width) {\r
47862 alignment = 'cl-cr?';\r
47863 } else {\r
47864 alignment = 'cr-cl?';\r
47865 }\r
47866 } else {\r
47867 alignment = 'bc-tc?';\r
47868 }\r
47869 } else {\r
47870 alignment = 'tc-bc?';\r
47871 }\r
47872 }\r
47873 var matches = alignment.match(this.alignmentRegex);\r
47874
47875 if (!matches) {\r
47876 Ext.Logger.error("Invalid alignment value of '" + alignment + "'");\r
47877 }\r
47878
47879 var from = matches[1].split(''),\r
47880 to = matches[2].split(''),\r
47881 constrained = (matches[3] === '?'),\r
47882 fromVertical = from[0],\r
47883 fromHorizontal = from[1] || fromVertical,\r
47884 toVertical = to[0],\r
47885 toHorizontal = to[1] || toVertical,\r
47886 top = alignToBox.top,\r
47887 left = alignToBox.left,\r
47888 halfAlignHeight = alignToHeight / 2,\r
47889 halfAlignWidth = alignToWidth / 2,\r
47890 halfWidth = width / 2,\r
47891 halfHeight = height / 2,\r
47892 maxLeft, maxTop;\r
47893 switch (fromVertical) {\r
47894 case 't':\r
47895 switch (toVertical) {\r
47896 case 'c':\r
47897 top += halfAlignHeight;\r
47898 break;\r
47899 case 'b':\r
47900 top += alignToHeight;\r
47901 };\r
47902 break;\r
47903 case 'b':\r
47904 switch (toVertical) {\r
47905 case 'c':\r
47906 top -= (height - halfAlignHeight);\r
47907 break;\r
47908 case 't':\r
47909 top -= height;\r
47910 break;\r
47911 case 'b':\r
47912 top -= height - alignToHeight;\r
47913 };\r
47914 break;\r
47915 case 'c':\r
47916 switch (toVertical) {\r
47917 case 't':\r
47918 top -= halfHeight;\r
47919 break;\r
47920 case 'c':\r
47921 top -= (halfHeight - halfAlignHeight);\r
47922 break;\r
47923 case 'b':\r
47924 top -= (halfHeight - alignToHeight);\r
47925 };\r
47926 break;\r
47927 }\r
47928 switch (fromHorizontal) {\r
47929 case 'l':\r
47930 switch (toHorizontal) {\r
47931 case 'c':\r
47932 left += halfAlignHeight;\r
47933 break;\r
47934 case 'r':\r
47935 left += alignToWidth;\r
47936 };\r
47937 break;\r
47938 case 'r':\r
47939 switch (toHorizontal) {\r
47940 case 'r':\r
47941 left -= (width - alignToWidth);\r
47942 break;\r
47943 case 'c':\r
47944 left -= (width - halfWidth);\r
47945 break;\r
47946 case 'l':\r
47947 left -= width;\r
47948 };\r
47949 break;\r
47950 case 'c':\r
47951 switch (toHorizontal) {\r
47952 case 'l':\r
47953 left -= halfWidth;\r
47954 break;\r
47955 case 'c':\r
47956 left -= (halfWidth - halfAlignWidth);\r
47957 break;\r
47958 case 'r':\r
47959 left -= (halfWidth - alignToWidth);\r
47960 };\r
47961 break;\r
47962 }\r
47963 if (constrained) {\r
47964 maxLeft = (constrainBox.left + constrainBox.width) - width;\r
47965 maxTop = (constrainBox.top + constrainBox.height) - height;\r
47966 left = Math.max(constrainBox.left, Math.min(maxLeft, left));\r
47967 top = Math.max(constrainBox.top, Math.min(maxTop, top));\r
47968 }\r
47969 this.setLeft(left);\r
47970 this.setTop(top);\r
47971 this.setCurrentAlignmentInfo(alignmentInfo);\r
47972 },\r
47973 \r
47974 up: function(selector) {\r
47975 var result = this.parent;\r
47976 if (selector) {\r
47977 for (; result; result = result.parent) {\r
47978 if (Ext.ComponentQuery.is(result, selector)) {\r
47979 return result;\r
47980 }\r
47981 }\r
47982 }\r
47983 return result;\r
47984 },\r
47985 getBubbleTarget: function() {\r
47986 return this.getParent();\r
47987 },\r
47988 \r
47989 destroy: function() {\r
47990 var me = this;\r
47991
47992 me.isDestroying = me.destroying = true;\r
47993 if (me.hasListeners.destroy) {\r
47994 me.fireEvent('destroy', me);\r
47995 }\r
47996 Ext.destroy(me.getTranslatable(), me.getPlugins(), me.innerHtmlElement, me.scrollerElement, me.getScrollable());\r
47997 me.setRecord(null);\r
47998 me.callParent();\r
47999
48000 me.isDestroying = me.destroying = false;\r
48001 },\r
48002 privates: {\r
48003 doAddListener: function(name, fn, scope, options, order, caller, manager) {\r
48004 if (name == 'painted' || name == 'resize') {\r
48005 this.element.doAddListener(name, fn, scope || this, options, order);\r
48006 }\r
48007 this.callParent([\r
48008 name,\r
48009 fn,\r
48010 scope,\r
48011 options,\r
48012 order,\r
48013 caller,\r
48014 manager\r
48015 ]);\r
48016 },\r
48017 doRemoveListener: function(name, fn, scope) {\r
48018 if (name == 'painted' || name == 'resize') {\r
48019 this.element.doRemoveListener(name, fn, scope);\r
48020 }\r
48021 this.callParent([\r
48022 name,\r
48023 fn,\r
48024 scope\r
48025 ]);\r
48026 }\r
48027 }\r
48028}, function() {\r
48029
48030 var metaTags = document.getElementsByTagName('head')[0].getElementsByTagName('meta'),\r
48031 len = metaTags.length,\r
48032 i, hasViewport;\r
48033 for (i = 0; i < len; i++) {\r
48034 if (metaTags[i].name === 'viewport') {\r
48035 hasViewport = true;\r
48036 }\r
48037 }\r
48038 if (!hasViewport) {\r
48039 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">');\r
48040 }\r
48041});\r
48042
48043\r
48044\r
48045Ext.define('Ext.layout.Abstract', {\r
48046 mixins: [\r
48047 Ext.mixin.Observable\r
48048 ],\r
48049 isLayout: true,\r
48050 constructor: function(config) {\r
48051 this.initialConfig = config;\r
48052 },\r
48053
48054 isCompatible: function(layout) {\r
48055 if (!layout) {\r
48056 return true;\r
48057 }\r
48058 if (layout.isInstance) {\r
48059 return false;\r
48060 }\r
48061 var type = Ext.isString(layout) ? layout : layout.type,\r
48062 alias = this.alias;\r
48063 if (!alias || !type) {\r
48064 return false;\r
48065 }\r
48066 return alias.indexOf('layout.' + type) > -1;\r
48067 },\r
48068
48069 setContainer: function(container) {\r
48070 var me = this;\r
48071 me.container = container;\r
48072 me.mixins.observable.constructor.call(me, me.initialConfig);\r
48073 return me;\r
48074 },\r
48075 onItemAdd: Ext.emptyFn,\r
48076 onItemRemove: Ext.emptyFn,\r
48077 onItemMove: Ext.emptyFn,\r
48078 onItemCenteredChange: Ext.emptyFn,\r
48079 onItemFloatingChange: Ext.emptyFn,\r
48080 onItemDockedChange: Ext.emptyFn,\r
48081 onItemInnerStateChange: Ext.emptyFn\r
48082});\r
48083\r
48084\r
48085Ext.define('Ext.mixin.Hookable', {\r
48086 extend: Ext.Mixin,\r
48087 mixinConfig: {\r
48088 id: 'hookable'\r
48089 },\r
48090 bindHook: function(instance, boundMethod, bindingMethod, preventDefault, extraArgs) {\r
48091 if (!bindingMethod) {\r
48092 bindingMethod = boundMethod;\r
48093 }\r
48094 var boundFn = instance[boundMethod],\r
48095 fn, binding;\r
48096 if (boundFn && boundFn.hasOwnProperty('$binding')) {\r
48097 binding = boundFn.$binding;\r
48098 if (binding.bindingMethod === bindingMethod && binding.bindingScope === this) {\r
48099 return this;\r
48100 }\r
48101 }\r
48102 instance[boundMethod] = fn = function() {\r
48103 var binding = fn.$binding,\r
48104 scope = binding.bindingScope,\r
48105 args = Array.prototype.slice.call(arguments);\r
48106 args.push(arguments);\r
48107 if (extraArgs) {\r
48108 args.push.apply(args, extraArgs);\r
48109 }\r
48110 if (!binding.preventDefault && scope[binding.bindingMethod].apply(scope, args) !== false) {\r
48111 return binding.boundFn.apply(this, arguments);\r
48112 }\r
48113 };\r
48114 fn.$binding = {\r
48115 preventDefault: !!preventDefault,\r
48116 boundFn: boundFn,\r
48117 bindingMethod: bindingMethod,\r
48118 bindingScope: this\r
48119 };\r
48120 return this;\r
48121 },\r
48122 unbindHook: function(instance, boundMethod, bindingMethod) {\r
48123 if (!bindingMethod) {\r
48124 bindingMethod = boundMethod;\r
48125 }\r
48126 var fn = instance[boundMethod],\r
48127 binding = fn.$binding,\r
48128 boundFn, currentBinding;\r
48129 while (binding) {\r
48130 boundFn = binding.boundFn;\r
48131 if (binding.bindingMethod === bindingMethod && binding.bindingScope === this) {\r
48132 if (currentBinding) {\r
48133 currentBinding.boundFn = boundFn;\r
48134 } else {\r
48135 instance[boundMethod] = boundFn;\r
48136 }\r
48137 return this;\r
48138 }\r
48139 currentBinding = binding;\r
48140 binding = boundFn.$binding;\r
48141 }\r
48142 return this;\r
48143 }\r
48144});\r
48145\r
48146\r
48147Ext.define('Ext.util.Wrapper', {\r
48148 mixins: [\r
48149 Ext.mixin.Hookable\r
48150 ],\r
48151 constructor: function(elementConfig, wrappedElement) {\r
48152 var element = this.link('element', Ext.Element.create(elementConfig));\r
48153 if (wrappedElement) {\r
48154 element.insertBefore(wrappedElement);\r
48155 this.wrap(wrappedElement);\r
48156 }\r
48157 },\r
48158 bindSize: function(sizeName) {\r
48159 var wrappedElement = this.wrappedElement,\r
48160 boundMethodName;\r
48161 this.boundSizeName = sizeName;\r
48162 this.boundMethodName = boundMethodName = sizeName === 'width' ? 'setWidth' : 'setHeight';\r
48163 this.bindHook(wrappedElement, boundMethodName, 'onBoundSizeChange');\r
48164 wrappedElement[boundMethodName].call(wrappedElement, wrappedElement.getStyleValue(sizeName));\r
48165 },\r
48166 onBoundSizeChange: function(size, args) {\r
48167 var element = this.element;\r
48168 if (typeof size === 'string' && size.substr(-1) === '%') {\r
48169 args[0] = '100%';\r
48170 } else {\r
48171 size = '';\r
48172 }\r
48173 element[this.boundMethodName].call(element, size);\r
48174 },\r
48175 wrap: function(wrappedElement) {\r
48176 var element = this.element,\r
48177 innerDom;\r
48178 this.wrappedElement = wrappedElement;\r
48179 innerDom = element.dom;\r
48180 while (innerDom.firstElementChild !== null) {\r
48181 innerDom = innerDom.firstElementChild;\r
48182 }\r
48183 innerDom.appendChild(wrappedElement.dom);\r
48184 },\r
48185 destroy: function() {\r
48186 var me = this,\r
48187 element = me.element,\r
48188 dom = element.dom,\r
48189 wrappedElement = me.wrappedElement,\r
48190 boundMethodName = me.boundMethodName,\r
48191 parentNode = dom.parentNode,\r
48192 size;\r
48193 if (boundMethodName) {\r
48194 me.unbindHook(wrappedElement, boundMethodName, 'onBoundSizeChange');\r
48195 size = element.getStyle(me.boundSizeName);\r
48196 if (size) {\r
48197 wrappedElement[boundMethodName].call(wrappedElement, size);\r
48198 }\r
48199 }\r
48200 if (parentNode) {\r
48201 if (!wrappedElement.destroyed) {\r
48202 parentNode.replaceChild(dom.firstElementChild, dom);\r
48203 }\r
48204 delete me.wrappedElement;\r
48205 }\r
48206 me.callParent();\r
48207 }\r
48208});\r
48209\r
48210\r
48211Ext.define('Ext.layout.wrapper.BoxDock', {\r
48212 config: {\r
48213 direction: 'horizontal',\r
48214 element: {\r
48215 className: Ext.baseCSSPrefix + 'dock'\r
48216 },\r
48217 bodyElement: {\r
48218 className: Ext.baseCSSPrefix + 'dock-body'\r
48219 },\r
48220 innerWrapper: null,\r
48221 sizeState: false,\r
48222 container: null\r
48223 },\r
48224 positionMap: {\r
48225 top: 'start',\r
48226 left: 'start',\r
48227 bottom: 'end',\r
48228 right: 'end'\r
48229 },\r
48230 constructor: function(config) {\r
48231 this.items = {\r
48232 start: [],\r
48233 end: []\r
48234 };\r
48235 this.itemsCount = 0;\r
48236 this.initConfig(config);\r
48237 },\r
48238 addItems: function(items) {\r
48239 var i, ln, item;\r
48240 for (i = 0 , ln = items.length; i < ln; i++) {\r
48241 item = items[i];\r
48242 this.addItem(item);\r
48243 }\r
48244 },\r
48245 addItem: function(item) {\r
48246 var docked = item.getDocked(),\r
48247 position = this.positionMap[docked],\r
48248 wrapper = item.$dockWrapper,\r
48249 container = this.getContainer(),\r
48250 index = container.indexOf(item),\r
48251 element = item.element,\r
48252 items = this.items,\r
48253 sideItems = items[position],\r
48254 i, ln, sibling, referenceElement, siblingIndex;\r
48255 if (wrapper) {\r
48256 wrapper.removeItem(item);\r
48257 }\r
48258 item.$dockWrapper = this;\r
48259 item.addCls(Ext.baseCSSPrefix + 'dock-item');\r
48260 item.addCls(Ext.baseCSSPrefix + 'docked-' + docked);\r
48261 for (i = 0 , ln = sideItems.length; i < ln; i++) {\r
48262 sibling = sideItems[i];\r
48263 siblingIndex = container.indexOf(sibling);\r
48264 if (siblingIndex > index) {\r
48265 referenceElement = sibling.element;\r
48266 sideItems.splice(i, 0, item);\r
48267 break;\r
48268 }\r
48269 }\r
48270 if (!referenceElement) {\r
48271 sideItems.push(item);\r
48272 referenceElement = this.getBodyElement();\r
48273 }\r
48274 this.itemsCount++;\r
48275 if (position === 'start') {\r
48276 element.insertBefore(referenceElement);\r
48277 } else {\r
48278 element.insertAfter(referenceElement);\r
48279 }\r
48280 },\r
48281 removeItem: function(item) {\r
48282 var position = item.getDocked(),\r
48283 items = this.items[this.positionMap[position]];\r
48284 Ext.Array.remove(items, item);\r
48285 item.element.detach();\r
48286 delete item.$dockWrapper;\r
48287 item.removeCls(Ext.baseCSSPrefix + 'dock-item');\r
48288 item.removeCls(Ext.baseCSSPrefix + 'docked-' + position);\r
48289 if (--this.itemsCount === 0) {\r
48290 this.destroy();\r
48291 }\r
48292 },\r
48293 getItemsSlice: function(index) {\r
48294 var container = this.getContainer(),\r
48295 items = this.items,\r
48296 slice = [],\r
48297 sideItems, i, ln, item;\r
48298 for (sideItems = items.start , i = 0 , ln = sideItems.length; i < ln; i++) {\r
48299 item = sideItems[i];\r
48300 if (container.indexOf(item) > index) {\r
48301 slice.push(item);\r
48302 }\r
48303 }\r
48304 for (sideItems = items.end , i = 0 , ln = sideItems.length; i < ln; i++) {\r
48305 item = sideItems[i];\r
48306 if (container.indexOf(item) > index) {\r
48307 slice.push(item);\r
48308 }\r
48309 }\r
48310 return slice;\r
48311 },\r
48312 applyElement: function(element) {\r
48313 return Ext.Element.create(element);\r
48314 },\r
48315 updateElement: function(element) {\r
48316 element.addCls(Ext.baseCSSPrefix + 'dock-' + this.getDirection());\r
48317 },\r
48318 applyBodyElement: function(bodyElement) {\r
48319 return Ext.Element.create(bodyElement);\r
48320 },\r
48321 updateBodyElement: function(bodyElement) {\r
48322 this.getElement().append(bodyElement);\r
48323 },\r
48324 updateInnerWrapper: function(innerWrapper, oldInnerWrapper) {\r
48325 var bodyElement = this.getBodyElement();\r
48326 if (oldInnerWrapper && oldInnerWrapper.$outerWrapper === this) {\r
48327 oldInnerWrapper.getElement().detach();\r
48328 delete oldInnerWrapper.$outerWrapper;\r
48329 }\r
48330 if (innerWrapper) {\r
48331 innerWrapper.setSizeState(this.getSizeState());\r
48332 innerWrapper.$outerWrapper = this;\r
48333 bodyElement.append(innerWrapper.getElement());\r
48334 }\r
48335 },\r
48336 updateSizeState: function(state) {\r
48337 var innerWrapper = this.getInnerWrapper();\r
48338 this.getElement().setSizeState(state);\r
48339 if (innerWrapper) {\r
48340 innerWrapper.setSizeState(state);\r
48341 }\r
48342 },\r
48343 destroy: function() {\r
48344 var me = this,\r
48345 innerWrapper = me.getInnerWrapper(),\r
48346 outerWrapper = me.$outerWrapper,\r
48347 innerWrapperElement;\r
48348 if (innerWrapper) {\r
48349 if (outerWrapper) {\r
48350 outerWrapper.setInnerWrapper(innerWrapper);\r
48351 } else {\r
48352 innerWrapperElement = innerWrapper.getElement();\r
48353 if (!innerWrapperElement.destroyed) {\r
48354 innerWrapperElement.replace(me.getElement());\r
48355 }\r
48356 delete innerWrapper.$outerWrapper;\r
48357 }\r
48358 }\r
48359 delete me.$outerWrapper;\r
48360 me.setInnerWrapper(null);\r
48361 me.unlink([\r
48362 '_bodyElement',\r
48363 '_element'\r
48364 ]);\r
48365 me.callParent();\r
48366 }\r
48367});\r
48368\r
48369\r
48370Ext.define('Ext.layout.wrapper.Inner', {\r
48371 config: {\r
48372 sizeState: null,\r
48373 container: null\r
48374 },\r
48375 constructor: function(config) {\r
48376 this.initConfig(config);\r
48377 },\r
48378 getElement: function() {\r
48379 return this.getContainer().bodyElement;\r
48380 },\r
48381 setInnerWrapper: Ext.emptyFn,\r
48382 getInnerWrapper: Ext.emptyFn\r
48383});\r
48384\r
48385\r
48386Ext.define('Ext.layout.Default', {\r
48387 extend: Ext.layout.Abstract,\r
48388 isAuto: true,\r
48389 alias: [\r
48390 'layout.default',\r
48391 'layout.auto'\r
48392 ],\r
48393 config: {\r
48394 \r
48395 animation: null\r
48396 },\r
48397 centerWrapperClass: 'x-center',\r
48398 dockWrapperClass: 'x-dock',\r
48399 positionMap: {\r
48400 top: 'start',\r
48401 left: 'start',\r
48402 middle: 'center',\r
48403 bottom: 'end',\r
48404 right: 'end'\r
48405 },\r
48406 positionDirectionMap: {\r
48407 top: 'vertical',\r
48408 bottom: 'vertical',\r
48409 left: 'horizontal',\r
48410 right: 'horizontal'\r
48411 },\r
48412 setContainer: function(container) {\r
48413 var me = this;\r
48414 me.dockedItems = [];\r
48415 me.callParent([\r
48416 container\r
48417 ]);\r
48418 if (container.initialized) {\r
48419 me.onContainerInitialized();\r
48420 } else {\r
48421 container.onInitialized('onContainerInitialized', me);\r
48422 }\r
48423 },\r
48424 onContainerInitialized: function() {\r
48425 var me = this;\r
48426 me.handleDockedItemBorders();\r
48427 me.container.on({\r
48428 delegate: '> component',\r
48429 beforecenteredchange: 'onItemCenteredChange',\r
48430 beforefloatingchange: 'onItemFloatingChange',\r
48431 afterdockedchange: 'onAfterItemDockedChange',\r
48432
48433 scope: me\r
48434 });\r
48435 },\r
48436 monitorSizeStateChange: function() {\r
48437 this.monitorSizeStateChange = Ext.emptyFn;\r
48438 this.container.on('sizestatechange', 'onContainerSizeStateChange', this);\r
48439 },\r
48440 monitorSizeFlagsChange: function() {\r
48441 this.monitorSizeFlagsChange = Ext.emptyFn;\r
48442 this.container.on('sizeflagschange', 'onContainerSizeFlagsChange', this);\r
48443 },\r
48444 onItemAdd: function(item) {\r
48445 var docked = item.getDocked();\r
48446 if (docked != null) {\r
48447 this.dockItem(item);\r
48448 } else if (item.isCentered()) {\r
48449 this.onItemCenteredChange(item, true);\r
48450 } else if (item.isFloating()) {\r
48451 this.onItemFloatingChange(item, true);\r
48452 } else {\r
48453 this.onItemInnerStateChange(item, true);\r
48454 }\r
48455 },\r
48456 \r
48457 onItemInnerStateChange: function(item, isInner, destroying) {\r
48458 if (isInner) {\r
48459 this.insertInnerItem(item, this.container.innerIndexOf(item));\r
48460 } else {\r
48461 this.removeInnerItem(item);\r
48462 }\r
48463 },\r
48464 insertInnerItem: function(item, index) {\r
48465 var container = this.container,\r
48466 containerDom = container.innerElement.dom,\r
48467 itemDom = item.element.dom,\r
48468 nextSibling = index !== -1 ? container.getInnerAt(index + 1) : null,\r
48469 nextSiblingDom = null,\r
48470 translatable;\r
48471 if (nextSibling) {\r
48472 translatable = nextSibling.getTranslatable();\r
48473 if (translatable && translatable.getUseWrapper()) {\r
48474 nextSiblingDom = translatable.getWrapper().dom;\r
48475 } else {\r
48476 nextSiblingDom = nextSibling ? nextSibling.element.dom : null;\r
48477 }\r
48478 }\r
48479 containerDom.insertBefore(itemDom, nextSiblingDom);\r
48480 return this;\r
48481 },\r
48482 insertBodyItem: function(item) {\r
48483 var container = this.container.setUseBodyElement(true),\r
48484 bodyDom = container.bodyElement.dom;\r
48485 if (item.getZIndex() === null) {\r
48486 item.setZIndex((container.indexOf(item) + 1) * 2);\r
48487 }\r
48488 bodyDom.insertBefore(item.element.dom, bodyDom.firstChild);\r
48489 return this;\r
48490 },\r
48491 removeInnerItem: function(item) {\r
48492 item.element.detach();\r
48493 },\r
48494 removeBodyItem: function(item) {\r
48495 item.setZIndex(null);\r
48496 item.element.detach();\r
48497 },\r
48498 onItemRemove: function(item, index, destroying) {\r
48499 var docked = item.getDocked();\r
48500 if (docked) {\r
48501 this.undockItem(item);\r
48502 } else if (item.isCentered()) {\r
48503 this.onItemCenteredChange(item, false);\r
48504 } else if (item.isFloating()) {\r
48505 this.onItemFloatingChange(item, false);\r
48506 } else {\r
48507 this.onItemInnerStateChange(item, false, destroying);\r
48508 }\r
48509 },\r
48510 onItemMove: function(item, toIndex, fromIndex) {\r
48511 if (item.isCentered() || item.isFloating()) {\r
48512 item.setZIndex((toIndex + 1) * 2);\r
48513 } else if (item.isInnerItem()) {\r
48514 this.insertInnerItem(item, this.container.innerIndexOf(item));\r
48515 } else {\r
48516 this.undockItem(item);\r
48517 this.dockItem(item);\r
48518 }\r
48519 },\r
48520 onItemCenteredChange: function(item, centered) {\r
48521 var wrapperName = '$centerWrapper';\r
48522 if (centered) {\r
48523 this.insertBodyItem(item);\r
48524 item.link(wrapperName, new Ext.util.Wrapper({\r
48525 className: this.centerWrapperClass\r
48526 }, item.element));\r
48527 } else {\r
48528 item.unlink([\r
48529 wrapperName\r
48530 ]);\r
48531 this.removeBodyItem(item);\r
48532 }\r
48533 },\r
48534 onItemFloatingChange: function(item, floating) {\r
48535 if (floating) {\r
48536 this.insertBodyItem(item);\r
48537 } else {\r
48538 this.removeBodyItem(item);\r
48539 }\r
48540 },\r
48541 onAfterItemDockedChange: function(item, docked, oldDocked) {\r
48542
48543
48544 if (item.initialized) {\r
48545 if (oldDocked) {\r
48546 this.undockItem(item);\r
48547 }\r
48548 if (docked) {\r
48549 this.dockItem(item);\r
48550 }\r
48551 }\r
48552 },\r
48553 onContainerSizeStateChange: function() {\r
48554 var dockWrapper = this.getDockWrapper();\r
48555 if (dockWrapper) {\r
48556 dockWrapper.setSizeState(this.container.getSizeState());\r
48557 }\r
48558 },\r
48559 onContainerSizeFlagsChange: function() {\r
48560 var items = this.dockedItems,\r
48561 i, ln, item;\r
48562 for (i = 0 , ln = items.length; i < ln; i++) {\r
48563 item = items[i];\r
48564 this.refreshDockedItemLayoutSizeFlags(item);\r
48565 }\r
48566 },\r
48567 refreshDockedItemLayoutSizeFlags: function(item) {\r
48568 var container = this.container,\r
48569 dockedDirection = this.positionDirectionMap[item.getDocked()],\r
48570 binaryMask = (dockedDirection === 'horizontal') ? container.LAYOUT_HEIGHT : container.LAYOUT_WIDTH,\r
48571 flags = (container.getSizeFlags() & binaryMask);\r
48572 item.setLayoutSizeFlags(flags);\r
48573 },\r
48574 dockItem: function(item) {\r
48575 var me = this,\r
48576 DockClass = Ext.layout.wrapper.BoxDock,\r
48577 dockedItems = me.dockedItems,\r
48578 ln = dockedItems.length,\r
48579 container = me.container,\r
48580 itemIndex = container.indexOf(item),\r
48581 positionDirectionMap = me.positionDirectionMap,\r
48582 direction = positionDirectionMap[item.getDocked()],\r
48583 dockInnerWrapper = me.dockInnerWrapper,\r
48584 referenceDirection, i, dockedItem, index, previousItem, slice, referenceItem, referenceDocked, referenceWrapper, newWrapper, nestedWrapper, oldInnerWrapper;\r
48585 me.monitorSizeStateChange();\r
48586 me.monitorSizeFlagsChange();\r
48587 if (!dockInnerWrapper) {\r
48588 dockInnerWrapper = me.link('dockInnerWrapper', new Ext.layout.wrapper.Inner({\r
48589 container: container\r
48590 }));\r
48591 }\r
48592 if (ln === 0) {\r
48593 dockedItems.push(item);\r
48594 newWrapper = new DockClass({\r
48595 container: container,\r
48596 direction: direction\r
48597 });\r
48598 newWrapper.addItem(item);\r
48599 newWrapper.getElement().replace(dockInnerWrapper.getElement(), false);\r
48600 newWrapper.setInnerWrapper(dockInnerWrapper);\r
48601 container.onInitialized('onContainerSizeStateChange', me);\r
48602 } else {\r
48603 for (i = 0; i < ln; i++) {\r
48604 dockedItem = dockedItems[i];\r
48605 index = container.indexOf(dockedItem);\r
48606 if (index > itemIndex) {\r
48607 referenceItem = previousItem || dockedItems[0];\r
48608 dockedItems.splice(i, 0, item);\r
48609 break;\r
48610 }\r
48611 previousItem = dockedItem;\r
48612 }\r
48613 if (!referenceItem) {\r
48614 referenceItem = dockedItems[ln - 1];\r
48615 dockedItems.push(item);\r
48616 }\r
48617 referenceDocked = referenceItem.getDocked();\r
48618 referenceWrapper = referenceItem.$dockWrapper;\r
48619 referenceDirection = positionDirectionMap[referenceDocked];\r
48620 if (direction === referenceDirection) {\r
48621 referenceWrapper.addItem(item);\r
48622 } else {\r
48623 slice = referenceWrapper.getItemsSlice(itemIndex);\r
48624 newWrapper = new DockClass({\r
48625 container: container,\r
48626 direction: direction\r
48627 });\r
48628 if (slice.length > 0) {\r
48629 if (slice.length === referenceWrapper.itemsCount) {\r
48630 nestedWrapper = referenceWrapper;\r
48631 newWrapper.setSizeState(nestedWrapper.getSizeState());\r
48632 newWrapper.getElement().replace(nestedWrapper.getElement(), false);\r
48633 } else {\r
48634 nestedWrapper = new DockClass({\r
48635 container: container,\r
48636 direction: referenceDirection\r
48637 });\r
48638 nestedWrapper.setInnerWrapper(referenceWrapper.getInnerWrapper());\r
48639 nestedWrapper.addItems(slice);\r
48640 referenceWrapper.setInnerWrapper(newWrapper);\r
48641 }\r
48642 newWrapper.setInnerWrapper(nestedWrapper);\r
48643 } else {\r
48644 oldInnerWrapper = referenceWrapper.getInnerWrapper();\r
48645 referenceWrapper.setInnerWrapper(null);\r
48646 newWrapper.setInnerWrapper(oldInnerWrapper);\r
48647 referenceWrapper.setInnerWrapper(newWrapper);\r
48648 }\r
48649 newWrapper.addItem(item);\r
48650 }\r
48651 }\r
48652 if (container.initialized) {\r
48653 me.handleDockedItemBorders();\r
48654 }\r
48655 container.onInitialized('refreshDockedItemLayoutSizeFlags', me, [\r
48656 item\r
48657 ]);\r
48658 },\r
48659 getDockWrapper: function() {\r
48660 var dockedItems = this.dockedItems;\r
48661 if (dockedItems.length > 0) {\r
48662 return dockedItems[0].$dockWrapper;\r
48663 }\r
48664 return null;\r
48665 },\r
48666 undockItem: function(item) {\r
48667 var me = this,\r
48668 dockedItems = me.dockedItems,\r
48669 lastBorderMask, lastBorderCollapse;\r
48670 if (item.$dockWrapper) {\r
48671 item.$dockWrapper.removeItem(item);\r
48672 }\r
48673 if (me.container.initialized) {\r
48674 lastBorderMask = item.lastBorderMask;\r
48675 lastBorderCollapse = item.lastBorderCollapse;\r
48676 if (lastBorderMask) {\r
48677 item.lastBorderMask = 0;\r
48678 item.removeCls(me.noBorderClassTable[lastBorderMask]);\r
48679 }\r
48680 if (lastBorderCollapse) {\r
48681 item.lastBorderCollapse = 0;\r
48682 item.removeCls(me.getBorderCollapseTable()[lastBorderCollapse]);\r
48683 }\r
48684 me.handleDockedItemBorders();\r
48685 }\r
48686 Ext.Array.remove(dockedItems, item);\r
48687 item.setLayoutSizeFlags(0);\r
48688 },\r
48689 destroy: function() {\r
48690 this.dockedItems = null;\r
48691 this.callParent();\r
48692 },\r
48693 \r
48694 noBorderClassTable: [\r
48695 0,\r
48696
48697 Ext.baseCSSPrefix + 'noborder-l',\r
48698
48699 Ext.baseCSSPrefix + 'noborder-b',\r
48700
48701 Ext.baseCSSPrefix + 'noborder-bl',\r
48702
48703 Ext.baseCSSPrefix + 'noborder-r',\r
48704
48705 Ext.baseCSSPrefix + 'noborder-rl',\r
48706
48707 Ext.baseCSSPrefix + 'noborder-rb',\r
48708
48709 Ext.baseCSSPrefix + 'noborder-rbl',\r
48710
48711 Ext.baseCSSPrefix + 'noborder-t',\r
48712
48713 Ext.baseCSSPrefix + 'noborder-tl',\r
48714
48715 Ext.baseCSSPrefix + 'noborder-tb',\r
48716
48717 Ext.baseCSSPrefix + 'noborder-tbl',\r
48718
48719 Ext.baseCSSPrefix + 'noborder-tr',\r
48720
48721 Ext.baseCSSPrefix + 'noborder-trl',\r
48722
48723 Ext.baseCSSPrefix + 'noborder-trb',\r
48724
48725 Ext.baseCSSPrefix + 'noborder-trbl'\r
48726 ],\r
48727
48728 \r
48729 edgeMasks: {\r
48730 top: 8,\r
48731 right: 4,\r
48732 bottom: 2,\r
48733 left: 1\r
48734 },\r
48735 handleDockedItemBorders: function() {\r
48736 var me = this,\r
48737 edges = 0,\r
48738 maskT = 8,\r
48739 maskR = 4,\r
48740 maskB = 2,\r
48741 maskL = 1,\r
48742 container = me.container,\r
48743 bodyBorder = container.getBoodyBorder && container.getBodyBorder(),\r
48744 containerBorder = container.getBorder(),\r
48745 collapsed = me.collapsed,\r
48746 edgeMasks = me.edgeMasks,\r
48747 noBorderCls = me.noBorderClassTable,\r
48748 dockedItemsGen = container.items.generation,\r
48749 b, borderCls, docked, edgesTouched, i, ln, item, dock, lastValue, mask, addCls, removeCls;\r
48750 if (me.initializedBorders === dockedItemsGen || !container.manageBorders) {\r
48751 return;\r
48752 }\r
48753 addCls = [];\r
48754 removeCls = [];\r
48755 borderCls = me.getBorderCollapseTable();\r
48756 noBorderCls = me.getBorderClassTable ? me.getBorderClassTable() : noBorderCls;\r
48757 me.initializedBorders = dockedItemsGen;\r
48758
48759 me.collapsed = false;\r
48760 docked = container.getDockedItems();\r
48761 me.collapsed = collapsed;\r
48762 for (i = 0 , ln = docked.length; i < ln; i++) {\r
48763 item = docked[i];\r
48764 dock = item.getDocked();\r
48765 mask = edgesTouched = 0;\r
48766 addCls.length = 0;\r
48767 removeCls.length = 0;\r
48768 if (dock !== 'bottom') {\r
48769 if (edges & maskT) {\r
48770
48771 b = item.border;\r
48772 } else {\r
48773 b = containerBorder;\r
48774 if (b !== false) {\r
48775 edgesTouched += maskT;\r
48776 }\r
48777 }\r
48778 if (b === false) {\r
48779 mask += maskT;\r
48780 }\r
48781 }\r
48782 if (dock !== 'left') {\r
48783 if (edges & maskR) {\r
48784
48785 b = item.border;\r
48786 } else {\r
48787 b = containerBorder;\r
48788 if (b !== false) {\r
48789 edgesTouched += maskR;\r
48790 }\r
48791 }\r
48792 if (b === false) {\r
48793 mask += maskR;\r
48794 }\r
48795 }\r
48796 if (dock !== 'top') {\r
48797 if (edges & maskB) {\r
48798
48799 b = item.border;\r
48800 } else {\r
48801 b = containerBorder;\r
48802 if (b !== false) {\r
48803 edgesTouched += maskB;\r
48804 }\r
48805 }\r
48806 if (b === false) {\r
48807 mask += maskB;\r
48808 }\r
48809 }\r
48810 if (dock !== 'right') {\r
48811 if (edges & maskL) {\r
48812
48813 b = item.border;\r
48814 } else {\r
48815 b = containerBorder;\r
48816 if (b !== false) {\r
48817 edgesTouched += maskL;\r
48818 }\r
48819 }\r
48820 if (b === false) {\r
48821 mask += maskL;\r
48822 }\r
48823 }\r
48824 if ((lastValue = item.lastBorderMask) !== mask) {\r
48825 item.lastBorderMask = mask;\r
48826 if (lastValue) {\r
48827 removeCls[0] = noBorderCls[lastValue];\r
48828 }\r
48829 if (mask) {\r
48830 addCls[0] = noBorderCls[mask];\r
48831 }\r
48832 }\r
48833 if ((lastValue = item.lastBorderCollapse) !== edgesTouched) {\r
48834 item.lastBorderCollapse = edgesTouched;\r
48835 if (lastValue) {\r
48836 removeCls[removeCls.length] = borderCls[lastValue];\r
48837 }\r
48838 if (edgesTouched) {\r
48839 addCls[addCls.length] = borderCls[edgesTouched];\r
48840 }\r
48841 }\r
48842 if (removeCls.length) {\r
48843 item.removeCls(removeCls);\r
48844 }\r
48845 if (addCls.length) {\r
48846 item.addCls(addCls);\r
48847 }\r
48848
48849
48850 edges |= edgeMasks[dock];\r
48851 }\r
48852
48853 mask = edgesTouched = 0;\r
48854 addCls.length = 0;\r
48855 removeCls.length = 0;\r
48856 if (edges & maskT) {\r
48857
48858 b = bodyBorder;\r
48859 } else {\r
48860 b = containerBorder;\r
48861 if (b !== false) {\r
48862 edgesTouched += maskT;\r
48863 }\r
48864 }\r
48865 if (b === false) {\r
48866 mask += maskT;\r
48867 }\r
48868 if (edges & maskR) {\r
48869
48870 b = bodyBorder;\r
48871 } else {\r
48872 b = containerBorder;\r
48873 if (b !== false) {\r
48874 edgesTouched += maskR;\r
48875 }\r
48876 }\r
48877 if (b === false) {\r
48878 mask += maskR;\r
48879 }\r
48880 if (edges & maskB) {\r
48881
48882 b = bodyBorder;\r
48883 } else {\r
48884 b = containerBorder;\r
48885 if (b !== false) {\r
48886 edgesTouched += maskB;\r
48887 }\r
48888 }\r
48889 if (b === false) {\r
48890 mask += maskB;\r
48891 }\r
48892 if (edges & maskL) {\r
48893
48894 b = bodyBorder;\r
48895 } else {\r
48896 b = containerBorder;\r
48897 if (b !== false) {\r
48898 edgesTouched += maskL;\r
48899 }\r
48900 }\r
48901 if (b === false) {\r
48902 mask += maskL;\r
48903 }\r
48904 if ((lastValue = me.lastBodyBorderMask) !== mask) {\r
48905 me.lastBodyBorderMask = mask;\r
48906 if (lastValue) {\r
48907 removeCls[0] = noBorderCls[lastValue];\r
48908 }\r
48909 if (mask) {\r
48910 addCls[0] = noBorderCls[mask];\r
48911 }\r
48912 }\r
48913 if ((lastValue = me.lastBodyBorderCollapse) !== edgesTouched) {\r
48914 me.lastBodyBorderCollapse = edgesTouched;\r
48915 if (lastValue) {\r
48916 removeCls[removeCls.length] = borderCls[lastValue];\r
48917 }\r
48918 if (edgesTouched) {\r
48919 addCls[addCls.length] = borderCls[edgesTouched];\r
48920 }\r
48921 }\r
48922 if (removeCls.length && container.removeBodyCls) {\r
48923 container.removeBodyCls(removeCls);\r
48924 }\r
48925 if (addCls.length && container.addBodyCls) {\r
48926 container.addBodyCls(addCls);\r
48927 }\r
48928 },\r
48929 \r
48930 borderCollapseMap: {},\r
48931 \r
48932 \r
48933 getBorderCollapseTable: function() {\r
48934 var me = this,\r
48935 map = me.borderCollapseMap,\r
48936 container = me.container,\r
48937 baseCls = container.getBaseCls(),\r
48938 ui = container.ui,\r
48939 uiCls = (ui ? ('-' + ui) : ''),\r
48940 table;\r
48941 ui = ui || 'default';\r
48942 map = map[baseCls] || (map[baseCls] = {});\r
48943 table = map[ui];\r
48944 if (!table) {\r
48945 baseCls += uiCls + '-outer-border-';\r
48946 map[ui] = table = [\r
48947 0,\r
48948
48949 baseCls + 'l',\r
48950
48951 baseCls + 'b',\r
48952
48953 baseCls + 'bl',\r
48954
48955 baseCls + 'r',\r
48956
48957 baseCls + 'rl',\r
48958
48959 baseCls + 'rb',\r
48960
48961 baseCls + 'rbl',\r
48962
48963 baseCls + 't',\r
48964
48965 baseCls + 'tl',\r
48966
48967 baseCls + 'tb',\r
48968
48969 baseCls + 'tbl',\r
48970
48971 baseCls + 'tr',\r
48972
48973 baseCls + 'trl',\r
48974
48975 baseCls + 'trb',\r
48976
48977 baseCls + 'trbl'\r
48978 ];\r
48979 }\r
48980
48981 return table;\r
48982 }\r
48983});\r
48984\r
48985\r
48986Ext.define('Ext.layout.Box', {\r
48987 extend: Ext.layout.Default,\r
48988 config: {\r
48989 orient: 'horizontal',\r
48990 \r
48991 align: 'start',\r
48992 \r
48993 pack: 'start'\r
48994 },\r
48995 alias: 'layout.tablebox',\r
48996 layoutBaseClass: 'x-layout-tablebox',\r
48997 itemClass: 'x-layout-tablebox-item',\r
48998 setContainer: function(container) {\r
48999 this.callParent([\r
49000 container\r
49001 ]);\r
49002 container.innerElement.addCls(this.layoutBaseClass);\r
49003 container.on('flexchange', 'onItemFlexChange', this, {\r
49004 delegate: '> component'\r
49005 });\r
49006 },\r
49007 onItemInnerStateChange: function(item, isInner) {\r
49008 this.callParent(arguments);\r
49009 item.toggleCls(this.itemClass, isInner);\r
49010 },\r
49011 onItemFlexChange: Ext.emptyFn\r
49012});\r
49013\r
49014\r
49015Ext.define('Ext.fx.layout.card.Abstract', {\r
49016 extend: Ext.Evented,\r
49017 isAnimation: true,\r
49018 config: {\r
49019 direction: 'left',\r
49020 duration: null,\r
49021 reverse: null,\r
49022 layout: null\r
49023 },\r
49024 updateLayout: function(layout) {\r
49025 if (layout) {\r
49026 this.enable();\r
49027 }\r
49028 },\r
49029 enable: function() {\r
49030 var layout = this.getLayout();\r
49031 if (layout) {\r
49032 layout.on('beforeactiveitemchange', 'onActiveItemChange', this);\r
49033 }\r
49034 },\r
49035 disable: function() {\r
49036 var layout = this.getLayout();\r
49037 if (this.isAnimating) {\r
49038 this.stopAnimation();\r
49039 }\r
49040 if (layout) {\r
49041 layout.un('beforeactiveitemchange', 'onActiveItemChange', this);\r
49042 }\r
49043 },\r
49044 onActiveItemChange: Ext.emptyFn,\r
49045 destroy: function() {\r
49046 var me = this,\r
49047 layout = me.getLayout();\r
49048 if (me.isAnimating) {\r
49049 me.stopAnimation();\r
49050 }\r
49051 if (layout) {\r
49052 layout.un('beforeactiveitemchange', 'onActiveItemChange', this);\r
49053 }\r
49054 me.setLayout(null);\r
49055 if (me.observableId) {\r
49056 me.fireEvent('destroy', this);\r
49057 }\r
49058 me.callParent();\r
49059 }\r
49060});\r
49061\r
49062\r
49063Ext.define('Ext.fx.State', {\r
49064 isAnimatable: {\r
49065 'background-color': true,\r
49066 'background-image': true,\r
49067 'background-position': true,\r
49068 'border-bottom-color': true,\r
49069 'border-bottom-width': true,\r
49070 'border-color': true,\r
49071 'border-left-color': true,\r
49072 'border-left-width': true,\r
49073 'border-right-color': true,\r
49074 'border-right-width': true,\r
49075 'border-spacing': true,\r
49076 'border-top-color': true,\r
49077 'border-top-width': true,\r
49078 'border-width': true,\r
49079 'bottom': true,\r
49080 'color': true,\r
49081 'crop': true,\r
49082 'font-size': true,\r
49083 'font-weight': true,\r
49084 'height': true,\r
49085 'left': true,\r
49086 'letter-spacing': true,\r
49087 'line-height': true,\r
49088 'margin-bottom': true,\r
49089 'margin-left': true,\r
49090 'margin-right': true,\r
49091 'margin-top': true,\r
49092 'max-height': true,\r
49093 'max-width': true,\r
49094 'min-height': true,\r
49095 'min-width': true,\r
49096 'opacity': true,\r
49097 'outline-color': true,\r
49098 'outline-offset': true,\r
49099 'outline-width': true,\r
49100 'padding-bottom': true,\r
49101 'padding-left': true,\r
49102 'padding-right': true,\r
49103 'padding-top': true,\r
49104 'right': true,\r
49105 'text-indent': true,\r
49106 'text-shadow': true,\r
49107 'top': true,\r
49108 'vertical-align': true,\r
49109 'visibility': true,\r
49110 'width': true,\r
49111 'word-spacing': true,\r
49112 'z-index': true,\r
49113 'zoom': true,\r
49114 'transform': true\r
49115 },\r
49116 constructor: function(data) {\r
49117 this.data = {};\r
49118 this.set(data);\r
49119 },\r
49120 setConfig: function(data) {\r
49121 this.set(data);\r
49122 return this;\r
49123 },\r
49124 setRaw: function(data) {\r
49125 this.data = data;\r
49126 return this;\r
49127 },\r
49128 clear: function() {\r
49129 return this.setRaw({});\r
49130 },\r
49131 setTransform: function(name, value) {\r
49132 var data = this.data,\r
49133 isArray = Ext.isArray(value),\r
49134 transform = data.transform,\r
49135 ln, key;\r
49136 if (!transform) {\r
49137 transform = data.transform = {\r
49138 translateX: 0,\r
49139 translateY: 0,\r
49140 translateZ: 0,\r
49141 scaleX: 1,\r
49142 scaleY: 1,\r
49143 scaleZ: 1,\r
49144 rotate: 0,\r
49145 rotateX: 0,\r
49146 rotateY: 0,\r
49147 rotateZ: 0,\r
49148 skewX: 0,\r
49149 skewY: 0\r
49150 };\r
49151 }\r
49152 if (typeof name == 'string') {\r
49153 switch (name) {\r
49154 case 'translate':\r
49155 if (isArray) {\r
49156 ln = value.length;\r
49157 if (ln == 0) {\r
49158 break;\r
49159 }\r
49160 transform.translateX = value[0];\r
49161 if (ln == 1) {\r
49162 break;\r
49163 }\r
49164 transform.translateY = value[1];\r
49165 if (ln == 2) {\r
49166 break;\r
49167 }\r
49168 transform.translateZ = value[2];\r
49169 } else {\r
49170 transform.translateX = value;\r
49171 };\r
49172 break;\r
49173 case 'rotate':\r
49174 if (isArray) {\r
49175 ln = value.length;\r
49176 if (ln == 0) {\r
49177 break;\r
49178 }\r
49179 transform.rotateX = value[0];\r
49180 if (ln == 1) {\r
49181 break;\r
49182 }\r
49183 transform.rotateY = value[1];\r
49184 if (ln == 2) {\r
49185 break;\r
49186 }\r
49187 transform.rotateZ = value[2];\r
49188 } else {\r
49189 transform.rotate = value;\r
49190 };\r
49191 break;\r
49192 case 'scale':\r
49193 if (isArray) {\r
49194 ln = value.length;\r
49195 if (ln == 0) {\r
49196 break;\r
49197 }\r
49198 transform.scaleX = value[0];\r
49199 if (ln == 1) {\r
49200 break;\r
49201 }\r
49202 transform.scaleY = value[1];\r
49203 if (ln == 2) {\r
49204 break;\r
49205 }\r
49206 transform.scaleZ = value[2];\r
49207 } else {\r
49208 transform.scaleX = value;\r
49209 transform.scaleY = value;\r
49210 };\r
49211 break;\r
49212 case 'skew':\r
49213 if (isArray) {\r
49214 ln = value.length;\r
49215 if (ln == 0) {\r
49216 break;\r
49217 }\r
49218 transform.skewX = value[0];\r
49219 if (ln == 1) {\r
49220 break;\r
49221 }\r
49222 transform.skewY = value[1];\r
49223 } else {\r
49224 transform.skewX = value;\r
49225 };\r
49226 break;\r
49227 default:\r
49228 transform[name] = value;\r
49229 }\r
49230 } else {\r
49231 for (key in name) {\r
49232 if (name.hasOwnProperty(key)) {\r
49233 value = name[key];\r
49234 this.setTransform(key, value);\r
49235 }\r
49236 }\r
49237 }\r
49238 },\r
49239 set: function(name, value) {\r
49240 var data = this.data,\r
49241 key;\r
49242 if (typeof name != 'string') {\r
49243 for (key in name) {\r
49244 value = name[key];\r
49245 if (key === 'transform') {\r
49246 this.setTransform(value);\r
49247 } else {\r
49248 data[key] = value;\r
49249 }\r
49250 }\r
49251 } else {\r
49252 if (name === 'transform') {\r
49253 this.setTransform(value);\r
49254 } else {\r
49255 data[name] = value;\r
49256 }\r
49257 }\r
49258 return this;\r
49259 },\r
49260 unset: function(name) {\r
49261 var data = this.data;\r
49262 if (data.hasOwnProperty(name)) {\r
49263 delete data[name];\r
49264 }\r
49265 return this;\r
49266 },\r
49267 getData: function() {\r
49268 return this.data;\r
49269 }\r
49270});\r
49271\r
49272\r
49273Ext.define('Ext.fx.animation.Abstract', {\r
49274 extend: Ext.Evented,\r
49275 isAnimation: true,\r
49276 config: {\r
49277 name: '',\r
49278 element: null,\r
49279 \r
49280 before: null,\r
49281 from: {},\r
49282 to: {},\r
49283 after: null,\r
49284 states: {},\r
49285 duration: 300,\r
49286 \r
49287 easing: 'linear',\r
49288 iteration: 1,\r
49289 direction: 'normal',\r
49290 delay: 0,\r
49291 onBeforeStart: null,\r
49292 callback: null,\r
49293 onEnd: null,\r
49294 onBeforeEnd: null,\r
49295 scope: null,\r
49296 reverse: null,\r
49297 preserveEndState: false,\r
49298 replacePrevious: true\r
49299 },\r
49300 STATE_FROM: '0%',\r
49301 STATE_TO: '100%',\r
49302 DIRECTION_UP: 'up',\r
49303 DIRECTION_DOWN: 'down',\r
49304 DIRECTION_LEFT: 'left',\r
49305 DIRECTION_RIGHT: 'right',\r
49306 stateNameRegex: /^(?:[\d\.]+)%$/,\r
49307 constructor: function() {\r
49308 this.states = {};\r
49309 this.callParent(arguments);\r
49310 return this;\r
49311 },\r
49312 applyElement: function(element) {\r
49313 return Ext.get(element);\r
49314 },\r
49315 applyBefore: function(before, current) {\r
49316 if (before) {\r
49317 return Ext.factory(before, Ext.fx.State, current);\r
49318 }\r
49319 },\r
49320 applyAfter: function(after, current) {\r
49321 if (after) {\r
49322 return Ext.factory(after, Ext.fx.State, current);\r
49323 }\r
49324 },\r
49325 setFrom: function(from) {\r
49326 return this.setState(this.STATE_FROM, from);\r
49327 },\r
49328 setTo: function(to) {\r
49329 return this.setState(this.STATE_TO, to);\r
49330 },\r
49331 getFrom: function() {\r
49332 return this.getState(this.STATE_FROM);\r
49333 },\r
49334 getTo: function() {\r
49335 return this.getState(this.STATE_TO);\r
49336 },\r
49337 setStates: function(states) {\r
49338 var validNameRegex = this.stateNameRegex,\r
49339 name;\r
49340 for (name in states) {\r
49341 if (validNameRegex.test(name)) {\r
49342 this.setState(name, states[name]);\r
49343 }\r
49344 }\r
49345 return this;\r
49346 },\r
49347 getStates: function() {\r
49348 return this.states;\r
49349 },\r
49350 updateCallback: function(callback) {\r
49351 if (callback) {\r
49352 this.setOnEnd(callback);\r
49353 }\r
49354 },\r
49355 end: function() {\r
49356
49357
49358 this.stop();\r
49359 },\r
49360 stop: function() {\r
49361 this.fireEvent('stop', this);\r
49362 },\r
49363 destroy: function() {\r
49364 this.stop();\r
49365 this.callParent();\r
49366 },\r
49367 setState: function(name, state) {\r
49368 var states = this.getStates(),\r
49369 stateInstance;\r
49370 stateInstance = Ext.factory(state, Ext.fx.State, states[name]);\r
49371 if (stateInstance) {\r
49372 states[name] = stateInstance;\r
49373 }\r
49374
49375 else if (name === this.STATE_TO) {\r
49376 Ext.Logger.error("Setting and invalid '100%' / 'to' state of: " + state);\r
49377 }\r
49378
49379 return this;\r
49380 },\r
49381 getState: function(name) {\r
49382 return this.getStates()[name];\r
49383 },\r
49384 getData: function() {\r
49385 var me = this,\r
49386 states = me.getStates(),\r
49387 statesData = {},\r
49388 before = me.getBefore(),\r
49389 after = me.getAfter(),\r
49390 from = states[me.STATE_FROM],\r
49391 to = states[me.STATE_TO],\r
49392 fromData = from.getData(),\r
49393 toData = to.getData(),\r
49394 data, name, state;\r
49395 for (name in states) {\r
49396 if (states.hasOwnProperty(name)) {\r
49397 state = states[name];\r
49398 data = state.getData();\r
49399 statesData[name] = data;\r
49400 }\r
49401 }\r
49402 return {\r
49403 before: before ? before.getData() : {},\r
49404 after: after ? after.getData() : {},\r
49405 states: statesData,\r
49406 from: fromData,\r
49407 to: toData,\r
49408 duration: me.getDuration(),\r
49409 iteration: me.getIteration(),\r
49410 direction: me.getDirection(),\r
49411 easing: me.getEasing(),\r
49412 delay: me.getDelay(),\r
49413 onEnd: me.getOnEnd(),\r
49414 onBeforeEnd: me.getOnBeforeEnd(),\r
49415 onBeforeStart: me.getOnBeforeStart(),\r
49416 scope: me.getScope(),\r
49417 preserveEndState: me.getPreserveEndState(),\r
49418 replacePrevious: me.getReplacePrevious()\r
49419 };\r
49420 }\r
49421});\r
49422\r
49423\r
49424Ext.define('Ext.fx.animation.Slide', {\r
49425 extend: Ext.fx.animation.Abstract,\r
49426 alternateClassName: 'Ext.fx.animation.SlideIn',\r
49427 alias: [\r
49428 'animation.slide',\r
49429 'animation.slideIn'\r
49430 ],\r
49431 config: {\r
49432 \r
49433 direction: 'left',\r
49434 \r
49435 out: false,\r
49436 \r
49437 offset: 0,\r
49438 \r
49439 easing: 'auto',\r
49440 containerBox: 'auto',\r
49441 elementBox: 'auto',\r
49442 isElementBoxFit: true,\r
49443 useCssTransform: true\r
49444 },\r
49445 reverseDirectionMap: {\r
49446 up: 'down',\r
49447 down: 'up',\r
49448 left: 'right',\r
49449 right: 'left'\r
49450 },\r
49451 applyEasing: function(easing) {\r
49452 if (easing === 'auto') {\r
49453 return 'ease-' + ((this.getOut()) ? 'in' : 'out');\r
49454 }\r
49455 return easing;\r
49456 },\r
49457 getContainerBox: function() {\r
49458 var box = this._containerBox;\r
49459 if (box === 'auto') {\r
49460 box = this.getElement().getParent().getBox();\r
49461 }\r
49462 return box;\r
49463 },\r
49464 getElementBox: function() {\r
49465 var box = this._elementBox;\r
49466 if (this.getIsElementBoxFit()) {\r
49467 return this.getContainerBox();\r
49468 }\r
49469 if (box === 'auto') {\r
49470 box = this.getElement().getBox();\r
49471 }\r
49472 return box;\r
49473 },\r
49474 getData: function() {\r
49475 var elementBox = this.getElementBox(),\r
49476 containerBox = this.getContainerBox(),\r
49477 box = elementBox ? elementBox : containerBox,\r
49478 from = this.getFrom(),\r
49479 to = this.getTo(),\r
49480 out = this.getOut(),\r
49481 offset = this.getOffset(),\r
49482 direction = this.getDirection(),\r
49483 useCssTransform = this.getUseCssTransform(),\r
49484 reverse = this.getReverse(),\r
49485 translateX = 0,\r
49486 translateY = 0,\r
49487 fromX, fromY, toX, toY;\r
49488 if (reverse) {\r
49489 direction = this.reverseDirectionMap[direction];\r
49490 }\r
49491 switch (direction) {\r
49492 case this.DIRECTION_UP:\r
49493 if (out) {\r
49494 translateY = containerBox.top - box.top - box.height - offset;\r
49495 } else {\r
49496 translateY = containerBox.bottom - box.bottom + box.height + offset;\r
49497 };\r
49498 break;\r
49499 case this.DIRECTION_DOWN:\r
49500 if (out) {\r
49501 translateY = containerBox.bottom - box.bottom + box.height + offset;\r
49502 } else {\r
49503 translateY = containerBox.top - box.height - box.top - offset;\r
49504 };\r
49505 break;\r
49506 case this.DIRECTION_RIGHT:\r
49507 if (out) {\r
49508 translateX = containerBox.right - box.right + box.width + offset;\r
49509 } else {\r
49510 translateX = containerBox.left - box.left - box.width - offset;\r
49511 };\r
49512 break;\r
49513 case this.DIRECTION_LEFT:\r
49514 if (out) {\r
49515 translateX = containerBox.left - box.left - box.width - offset;\r
49516 } else {\r
49517 translateX = containerBox.right - box.right + box.width + offset;\r
49518 };\r
49519 break;\r
49520 }\r
49521 fromX = (out) ? 0 : translateX;\r
49522 fromY = (out) ? 0 : translateY;\r
49523 if (useCssTransform) {\r
49524 from.setTransform({\r
49525 translateX: fromX,\r
49526 translateY: fromY\r
49527 });\r
49528 } else {\r
49529 from.set('left', fromX);\r
49530 from.set('top', fromY);\r
49531 }\r
49532 toX = (out) ? translateX : 0;\r
49533 toY = (out) ? translateY : 0;\r
49534 if (useCssTransform) {\r
49535 to.setTransform({\r
49536 translateX: toX,\r
49537 translateY: toY\r
49538 });\r
49539 } else {\r
49540 to.set('left', toX);\r
49541 to.set('top', toY);\r
49542 }\r
49543 return this.callParent(arguments);\r
49544 }\r
49545});\r
49546\r
49547\r
49548Ext.define('Ext.fx.animation.SlideOut', {\r
49549 extend: Ext.fx.animation.Slide,\r
49550 alias: [\r
49551 'animation.slideOut'\r
49552 ],\r
49553 config: {\r
49554
49555 out: true\r
49556 }\r
49557});\r
49558\r
49559\r
49560Ext.define('Ext.fx.animation.Fade', {\r
49561 extend: Ext.fx.animation.Abstract,\r
49562 alternateClassName: 'Ext.fx.animation.FadeIn',\r
49563 alias: [\r
49564 'animation.fade',\r
49565 'animation.fadeIn'\r
49566 ],\r
49567 config: {\r
49568 \r
49569 out: false,\r
49570 before: {\r
49571 display: null,\r
49572 opacity: 0\r
49573 },\r
49574 after: {\r
49575 opacity: null\r
49576 },\r
49577 reverse: null\r
49578 },\r
49579 updateOut: function(newOut) {\r
49580 var to = this.getTo(),\r
49581 from = this.getFrom();\r
49582 if (newOut) {\r
49583 from.set('opacity', 1);\r
49584 to.set('opacity', 0);\r
49585 } else {\r
49586 from.set('opacity', 0);\r
49587 to.set('opacity', 1);\r
49588 }\r
49589 }\r
49590});\r
49591\r
49592\r
49593Ext.define('Ext.fx.animation.FadeOut', {\r
49594 extend: Ext.fx.animation.Fade,\r
49595 alias: 'animation.fadeOut',\r
49596 config: {\r
49597
49598 out: true,\r
49599 before: {}\r
49600 }\r
49601});\r
49602\r
49603\r
49604Ext.define('Ext.fx.animation.Flip', {\r
49605 extend: Ext.fx.animation.Abstract,\r
49606 alias: 'animation.flip',\r
49607 config: {\r
49608 easing: 'ease-in',\r
49609 \r
49610 direction: 'right',\r
49611 half: false,\r
49612 out: null\r
49613 },\r
49614 getData: function() {\r
49615 var me = this,\r
49616 from = me.getFrom(),\r
49617 to = me.getTo(),\r
49618 direction = me.getDirection(),\r
49619 out = me.getOut(),\r
49620 half = me.getHalf(),\r
49621 rotate = half ? 90 : 180,\r
49622 fromScale = 1,\r
49623 toScale = 1,\r
49624 fromRotateX = 0,\r
49625 fromRotateY = 0,\r
49626 toRotateX = 0,\r
49627 toRotateY = 0;\r
49628 if (out) {\r
49629 toScale = 0.8;\r
49630 } else {\r
49631 fromScale = 0.8;\r
49632 }\r
49633 switch (direction) {\r
49634 case this.DIRECTION_UP:\r
49635 if (out) {\r
49636 toRotateX = rotate;\r
49637 } else {\r
49638 fromRotateX = -rotate;\r
49639 };\r
49640 break;\r
49641 case this.DIRECTION_DOWN:\r
49642 if (out) {\r
49643 toRotateX = -rotate;\r
49644 } else {\r
49645 fromRotateX = rotate;\r
49646 };\r
49647 break;\r
49648 case this.DIRECTION_RIGHT:\r
49649 if (out) {\r
49650 toRotateY = rotate;\r
49651 } else {\r
49652 fromRotateY = -rotate;\r
49653 };\r
49654 break;\r
49655 case this.DIRECTION_LEFT:\r
49656 if (out) {\r
49657 toRotateY = -rotate;\r
49658 } else {\r
49659 fromRotateY = rotate;\r
49660 };\r
49661 break;\r
49662 }\r
49663 from.setTransform({\r
49664 rotateX: fromRotateX,\r
49665 rotateY: fromRotateY,\r
49666 scale: fromScale\r
49667 });\r
49668 to.setTransform({\r
49669 rotateX: toRotateX,\r
49670 rotateY: toRotateY,\r
49671 scale: toScale\r
49672 });\r
49673 return this.callParent();\r
49674 }\r
49675});\r
49676\r
49677\r
49678Ext.define('Ext.fx.animation.Pop', {\r
49679 extend: Ext.fx.animation.Abstract,\r
49680 alias: [\r
49681 'animation.pop',\r
49682 'animation.popIn'\r
49683 ],\r
49684 alternateClassName: 'Ext.fx.animation.PopIn',\r
49685 config: {\r
49686 \r
49687 out: false,\r
49688 before: {\r
49689 display: null,\r
49690 opacity: 0\r
49691 },\r
49692 after: {\r
49693 opacity: null\r
49694 }\r
49695 },\r
49696 getData: function() {\r
49697 var to = this.getTo(),\r
49698 from = this.getFrom(),\r
49699 out = this.getOut();\r
49700 if (out) {\r
49701 from.set('opacity', 1);\r
49702 from.setTransform({\r
49703 scale: 1\r
49704 });\r
49705 to.set('opacity', 0);\r
49706 to.setTransform({\r
49707 scale: 0\r
49708 });\r
49709 } else {\r
49710 from.set('opacity', 0);\r
49711 from.setTransform({\r
49712 scale: 0\r
49713 });\r
49714 to.set('opacity', 1);\r
49715 to.setTransform({\r
49716 scale: 1\r
49717 });\r
49718 }\r
49719 return this.callParent(arguments);\r
49720 }\r
49721});\r
49722\r
49723\r
49724Ext.define('Ext.fx.animation.PopOut', {\r
49725 extend: Ext.fx.animation.Pop,\r
49726 alias: 'animation.popOut',\r
49727 config: {\r
49728
49729 out: true,\r
49730 before: {}\r
49731 }\r
49732});\r
49733\r
49734\r
49735Ext.define('Ext.fx.Animation', {\r
49736 \r
49737 constructor: function(config) {\r
49738 var defaultClass = Ext.fx.animation.Abstract,\r
49739 type;\r
49740 if (typeof config == 'string') {\r
49741 type = config;\r
49742 config = {};\r
49743 } else if (config && config.type) {\r
49744 type = config.type;\r
49745 }\r
49746 if (type) {\r
49747 defaultClass = Ext.ClassManager.getByAlias('animation.' + type);\r
49748
49749 if (!defaultClass) {\r
49750 Ext.Logger.error("Invalid animation type of: '" + type + "'");\r
49751 }\r
49752 }\r
49753
49754 return Ext.factory(config, defaultClass);\r
49755 }\r
49756});\r
49757\r
49758\r
49759Ext.define('Ext.fx.layout.card.Style', {\r
49760 extend: Ext.fx.layout.card.Abstract,\r
49761 config: {\r
49762 inAnimation: {\r
49763 before: {\r
49764 visibility: null\r
49765 },\r
49766 preserveEndState: false,\r
49767 replacePrevious: true\r
49768 },\r
49769 outAnimation: {\r
49770 preserveEndState: false,\r
49771 replacePrevious: true\r
49772 }\r
49773 },\r
49774 constructor: function(config) {\r
49775 var inAnimation, outAnimation;\r
49776 this.callParent([\r
49777 config\r
49778 ]);\r
49779 this.endAnimationCounter = 0;\r
49780 inAnimation = this.getInAnimation();\r
49781 outAnimation = this.getOutAnimation();\r
49782 inAnimation.on('animationend', 'incrementEnd', this);\r
49783 outAnimation.on('animationend', 'incrementEnd', this);\r
49784 },\r
49785 updateDirection: function(direction) {\r
49786 this.getInAnimation().setDirection(direction);\r
49787 this.getOutAnimation().setDirection(direction);\r
49788 },\r
49789 updateDuration: function(duration) {\r
49790 this.getInAnimation().setDuration(duration);\r
49791 this.getOutAnimation().setDuration(duration);\r
49792 },\r
49793 updateReverse: function(reverse) {\r
49794 this.getInAnimation().setReverse(reverse);\r
49795 this.getOutAnimation().setReverse(reverse);\r
49796 },\r
49797 incrementEnd: function() {\r
49798 this.endAnimationCounter++;\r
49799 if (this.endAnimationCounter > 1) {\r
49800 this.endAnimationCounter = 0;\r
49801 this.fireEvent('animationend', this);\r
49802 }\r
49803 },\r
49804 applyInAnimation: function(animation, inAnimation) {\r
49805 return Ext.factory(animation, Ext.fx.Animation, inAnimation);\r
49806 },\r
49807 applyOutAnimation: function(animation, outAnimation) {\r
49808 return Ext.factory(animation, Ext.fx.Animation, outAnimation);\r
49809 },\r
49810 updateInAnimation: function(animation) {\r
49811 animation.setScope(this);\r
49812 },\r
49813 updateOutAnimation: function(animation) {\r
49814 animation.setScope(this);\r
49815 },\r
49816 onActiveItemChange: function(cardLayout, newItem, oldItem, controller) {\r
49817 var inAnimation = this.getInAnimation(),\r
49818 outAnimation = this.getOutAnimation(),\r
49819 inElement, outElement;\r
49820 if (newItem && oldItem && oldItem.isPainted()) {\r
49821 inElement = newItem.renderElement;\r
49822 outElement = oldItem.renderElement;\r
49823 inAnimation.setElement(inElement);\r
49824 outAnimation.setElement(outElement);\r
49825 outAnimation.setOnEnd(function() {\r
49826 controller.resume();\r
49827 });\r
49828 inElement.dom.style.setProperty('visibility', 'hidden', 'important');\r
49829 newItem.show();\r
49830 Ext.Animator.run([\r
49831 outAnimation,\r
49832 inAnimation\r
49833 ]);\r
49834 controller.pause();\r
49835 }\r
49836 },\r
49837 destroy: function() {\r
49838 Ext.destroy(this.getInAnimation(), this.getOutAnimation());\r
49839 this.callParent();\r
49840 }\r
49841});\r
49842\r
49843\r
49844Ext.define('Ext.fx.layout.card.Slide', {\r
49845 extend: Ext.fx.layout.card.Style,\r
49846 alias: 'fx.layout.card.slide',\r
49847 config: {\r
49848 inAnimation: {\r
49849 type: 'slide',\r
49850 easing: 'ease-out'\r
49851 },\r
49852 outAnimation: {\r
49853 type: 'slide',\r
49854 easing: 'ease-out',\r
49855 out: true\r
49856 }\r
49857 },\r
49858 updateReverse: function(reverse) {\r
49859 this.getInAnimation().setReverse(reverse);\r
49860 this.getOutAnimation().setReverse(reverse);\r
49861 }\r
49862});\r
49863\r
49864\r
49865Ext.define('Ext.fx.layout.card.Cover', {\r
49866 extend: Ext.fx.layout.card.Style,\r
49867 alias: 'fx.layout.card.cover',\r
49868 config: {\r
49869 reverse: null,\r
49870 inAnimation: {\r
49871 before: {\r
49872 'z-index': 100\r
49873 },\r
49874 after: {\r
49875 'z-index': 0\r
49876 },\r
49877 type: 'slide',\r
49878 easing: 'ease-out'\r
49879 },\r
49880 outAnimation: {\r
49881 easing: 'ease-out',\r
49882 from: {\r
49883 opacity: 0.99\r
49884 },\r
49885 to: {\r
49886 opacity: 1\r
49887 },\r
49888 out: true\r
49889 }\r
49890 },\r
49891 updateReverse: function(reverse) {\r
49892 this.getInAnimation().setReverse(reverse);\r
49893 this.getOutAnimation().setReverse(reverse);\r
49894 }\r
49895});\r
49896\r
49897\r
49898Ext.define('Ext.fx.layout.card.Reveal', {\r
49899 extend: Ext.fx.layout.card.Style,\r
49900 alias: 'fx.layout.card.reveal',\r
49901 config: {\r
49902 inAnimation: {\r
49903 easing: 'ease-out',\r
49904 from: {\r
49905 opacity: 0.99\r
49906 },\r
49907 to: {\r
49908 opacity: 1\r
49909 }\r
49910 },\r
49911 outAnimation: {\r
49912 before: {\r
49913 'z-index': 100\r
49914 },\r
49915 after: {\r
49916 'z-index': 0\r
49917 },\r
49918 type: 'slide',\r
49919 easing: 'ease-out',\r
49920 out: true\r
49921 }\r
49922 },\r
49923 updateReverse: function(reverse) {\r
49924 this.getInAnimation().setReverse(reverse);\r
49925 this.getOutAnimation().setReverse(reverse);\r
49926 }\r
49927});\r
49928\r
49929\r
49930Ext.define('Ext.fx.layout.card.Fade', {\r
49931 extend: Ext.fx.layout.card.Style,\r
49932 alias: 'fx.layout.card.fade',\r
49933 config: {\r
49934 reverse: null,\r
49935 inAnimation: {\r
49936 type: 'fade',\r
49937 easing: 'ease-out'\r
49938 },\r
49939 outAnimation: {\r
49940 type: 'fade',\r
49941 easing: 'ease-out',\r
49942 out: true\r
49943 }\r
49944 }\r
49945});\r
49946\r
49947\r
49948Ext.define('Ext.fx.layout.card.Flip', {\r
49949 extend: Ext.fx.layout.card.Style,\r
49950 alias: 'fx.layout.card.flip',\r
49951 config: {\r
49952 duration: 500,\r
49953 inAnimation: {\r
49954 type: 'flip',\r
49955 half: true,\r
49956 easing: 'ease-out',\r
49957 before: {\r
49958 'backface-visibility': 'hidden'\r
49959 },\r
49960 after: {\r
49961 'backface-visibility': null\r
49962 }\r
49963 },\r
49964 outAnimation: {\r
49965 type: 'flip',\r
49966 half: true,\r
49967 easing: 'ease-in',\r
49968 before: {\r
49969 'backface-visibility': 'hidden'\r
49970 },\r
49971 after: {\r
49972 'backface-visibility': null\r
49973 },\r
49974 out: true\r
49975 }\r
49976 },\r
49977 onActiveItemChange: function(cardLayout, newItem, oldItem, controller) {\r
49978 var parent = newItem.element.getParent();\r
49979 parent.addCls(Ext.baseCSSPrefix + 'layout-card-perspective');\r
49980 this.on('animationend', function() {\r
49981 parent.removeCls(Ext.baseCSSPrefix + 'layout-card-perspective');\r
49982 }, this, {\r
49983 single: true\r
49984 });\r
49985 this.callParent(arguments);\r
49986 },\r
49987 updateDuration: function(duration) {\r
49988 var halfDuration = duration / 2,\r
49989 inAnimation = this.getInAnimation(),\r
49990 outAnimation = this.getOutAnimation();\r
49991 inAnimation.setDelay(halfDuration);\r
49992 inAnimation.setDuration(halfDuration);\r
49993 outAnimation.setDuration(halfDuration);\r
49994 }\r
49995});\r
49996\r
49997\r
49998Ext.define('Ext.fx.layout.card.Pop', {\r
49999 extend: Ext.fx.layout.card.Style,\r
50000 alias: 'fx.layout.card.pop',\r
50001 config: {\r
50002 duration: 500,\r
50003 inAnimation: {\r
50004 type: 'pop',\r
50005 easing: 'ease-out'\r
50006 },\r
50007 outAnimation: {\r
50008 type: 'pop',\r
50009 easing: 'ease-in',\r
50010 out: true\r
50011 }\r
50012 },\r
50013 updateDuration: function(duration) {\r
50014 var halfDuration = duration / 2,\r
50015 inAnimation = this.getInAnimation(),\r
50016 outAnimation = this.getOutAnimation();\r
50017 inAnimation.setDelay(halfDuration);\r
50018 inAnimation.setDuration(halfDuration);\r
50019 outAnimation.setDuration(halfDuration);\r
50020 }\r
50021});\r
50022\r
50023\r
50024Ext.define('Ext.fx.layout.card.Scroll', {\r
50025 extend: Ext.fx.layout.card.Abstract,\r
50026 alias: 'fx.layout.card.scroll',\r
50027 config: {\r
50028 duration: 150\r
50029 },\r
50030 constructor: function(config) {\r
50031 this.initConfig(config);\r
50032 },\r
50033 getEasing: function() {\r
50034 var easing = this.easing;\r
50035 if (!easing) {\r
50036 this.easing = easing = new Ext.fx.easing.Linear();\r
50037 }\r
50038 return easing;\r
50039 },\r
50040 updateDuration: function(duration) {\r
50041 this.getEasing().setDuration(duration);\r
50042 },\r
50043 onActiveItemChange: function(cardLayout, newItem, oldItem, controller) {\r
50044 var direction = this.getDirection(),\r
50045 easing = this.getEasing(),\r
50046 containerElement, inElement, outElement, containerWidth, containerHeight, reverse;\r
50047 if (newItem && oldItem) {\r
50048 if (this.isAnimating) {\r
50049 this.stopAnimation();\r
50050 }\r
50051 newItem.setWidth('100%');\r
50052 newItem.setHeight('100%');\r
50053 containerElement = this.getLayout().container.innerElement;\r
50054 containerWidth = containerElement.getWidth();\r
50055 containerHeight = containerElement.getHeight();\r
50056 inElement = newItem.renderElement;\r
50057 outElement = oldItem.renderElement;\r
50058 this.oldItem = oldItem;\r
50059 this.newItem = newItem;\r
50060 this.containerElement = containerElement;\r
50061 this.currentEventController = controller;\r
50062 this.isReverse = reverse = this.getReverse();\r
50063 newItem.show();\r
50064 if (direction == 'right') {\r
50065 direction = 'left';\r
50066 this.isReverse = reverse = !reverse;\r
50067 } else if (direction == 'down') {\r
50068 direction = 'up';\r
50069 this.isReverse = reverse = !reverse;\r
50070 }\r
50071 if (direction == 'left') {\r
50072 if (reverse) {\r
50073 easing.setConfig({\r
50074 startValue: containerWidth,\r
50075 endValue: 0\r
50076 });\r
50077 containerElement.dom.scrollLeft = containerWidth;\r
50078 outElement.setLeft(containerWidth);\r
50079 } else {\r
50080 easing.setConfig({\r
50081 startValue: 0,\r
50082 endValue: containerWidth\r
50083 });\r
50084 inElement.setLeft(containerWidth);\r
50085 }\r
50086 } else {\r
50087 if (reverse) {\r
50088 easing.setConfig({\r
50089 startValue: containerHeight,\r
50090 endValue: 0\r
50091 });\r
50092 containerElement.dom.scrollTop = containerHeight;\r
50093 outElement.setTop(containerHeight);\r
50094 } else {\r
50095 easing.setConfig({\r
50096 startValue: 0,\r
50097 endValue: containerHeight\r
50098 });\r
50099 inElement.setTop(containerHeight);\r
50100 }\r
50101 }\r
50102 this.startAnimation();\r
50103 controller.pause();\r
50104 }\r
50105 },\r
50106 startAnimation: function() {\r
50107 this.isAnimating = true;\r
50108 this.getEasing().setStartTime(Date.now());\r
50109 Ext.AnimationQueue.start(this.doAnimationFrame, this);\r
50110 },\r
50111 doAnimationFrame: function() {\r
50112 var easing = this.getEasing(),\r
50113 direction = this.getDirection(),\r
50114 scroll = 'scrollTop',\r
50115 value;\r
50116 if (direction == 'left' || direction == 'right') {\r
50117 scroll = 'scrollLeft';\r
50118 }\r
50119 if (easing.isEnded) {\r
50120 this.stopAnimation();\r
50121 } else {\r
50122 value = easing.getValue();\r
50123 this.containerElement.dom[scroll] = value;\r
50124 }\r
50125 },\r
50126 stopAnimation: function() {\r
50127 var me = this,\r
50128 direction = me.getDirection(),\r
50129 scroll = 'setTop',\r
50130 oldItem = me.oldItem,\r
50131 newItem = me.newItem;\r
50132 if (direction == 'left' || direction == 'right') {\r
50133 scroll = 'setLeft';\r
50134 }\r
50135 me.currentEventController.resume();\r
50136 if (me.isReverse && oldItem && oldItem.renderElement && oldItem.renderElement.dom) {\r
50137 oldItem.renderElement[scroll](null);\r
50138 } else if (newItem && newItem.renderElement && newItem.renderElement.dom) {\r
50139 newItem.renderElement[scroll](null);\r
50140 }\r
50141 Ext.AnimationQueue.stop(this.doAnimationFrame, this);\r
50142 me.isAnimating = false;\r
50143 me.fireEvent('animationend', me);\r
50144 }\r
50145});\r
50146\r
50147\r
50148Ext.define('Ext.fx.layout.Card', {\r
50149 constructor: function(config) {\r
50150 var defaultClass = Ext.fx.layout.card.Abstract,\r
50151 type;\r
50152 if (!config) {\r
50153 return null;\r
50154 }\r
50155 if (typeof config == 'string') {\r
50156 type = config;\r
50157 config = {};\r
50158 } else if (config.type) {\r
50159 type = config.type;\r
50160 }\r
50161 config.elementBox = false;\r
50162 if (type) {\r
50163 defaultClass = Ext.ClassManager.getByAlias('fx.layout.card.' + type);\r
50164
50165 if (!defaultClass) {\r
50166 Ext.Logger.error("Unknown card animation type: '" + type + "'");\r
50167 }\r
50168 }\r
50169
50170 return Ext.factory(config, defaultClass);\r
50171 }\r
50172});\r
50173\r
50174\r
50175Ext.define('Ext.layout.Card', {\r
50176 extend: Ext.layout.Default,\r
50177 alias: 'layout.card',\r
50178 isCard: true,\r
50179 \r
50180 layoutClass: Ext.baseCSSPrefix + 'layout-card',\r
50181 itemClass: Ext.baseCSSPrefix + 'layout-card-item',\r
50182 \r
50183 applyAnimation: function(animation) {\r
50184 return new Ext.fx.layout.Card(animation);\r
50185 },\r
50186 \r
50187 updateAnimation: function(animation, oldAnimation) {\r
50188 if (animation && animation.isAnimation) {\r
50189 animation.setLayout(this);\r
50190 }\r
50191 if (oldAnimation) {\r
50192 oldAnimation.destroy();\r
50193 }\r
50194 },\r
50195 setContainer: function(container) {\r
50196 this.callParent(arguments);\r
50197 container.innerElement.addCls(this.layoutClass);\r
50198 container.onInitialized('onContainerInitialized', this);\r
50199 },\r
50200 onContainerInitialized: function() {\r
50201 var me = this,\r
50202 container = me.container,\r
50203 firstItem = container.getInnerAt(0),\r
50204 activeItem = container.getActiveItem();\r
50205 me.callParent();\r
50206 if (activeItem) {\r
50207 activeItem.show();\r
50208 if (firstItem && firstItem !== activeItem) {\r
50209 firstItem.hide();\r
50210 }\r
50211 }\r
50212 container.on('activeitemchange', 'onContainerActiveItemChange', me);\r
50213 },\r
50214 \r
50215 onContainerActiveItemChange: function(container, newItem, oldItem) {\r
50216 this.fireEventedAction('activeitemchange', [\r
50217 this,\r
50218 newItem,\r
50219 oldItem\r
50220 ], 'doActiveItemChange', this);\r
50221 },\r
50222 onItemInnerStateChange: function(item, isInner, destroying) {\r
50223 this.callParent(arguments);\r
50224 var container = this.container,\r
50225 activeItem = container.getActiveItem();\r
50226 item.toggleCls(this.itemClass, isInner);\r
50227 item.setLayoutSizeFlags(isInner ? container.LAYOUT_BOTH : 0);\r
50228 if (isInner) {\r
50229 if (activeItem !== container.innerIndexOf(item) && activeItem !== item && item !== container.pendingActiveItem) {\r
50230 item.hide();\r
50231 }\r
50232 } else {\r
50233 if (!destroying && !item.destroyed && item.destroying !== true) {\r
50234 item.show();\r
50235 }\r
50236 }\r
50237 },\r
50238 \r
50239 doActiveItemChange: function(me, newActiveItem, oldActiveItem) {\r
50240 if (oldActiveItem) {\r
50241 oldActiveItem.hide();\r
50242 }\r
50243 if (newActiveItem) {\r
50244 newActiveItem.show();\r
50245 }\r
50246 },\r
50247 destroy: function() {\r
50248 this.callParent();\r
50249 Ext.destroy(this.getAnimation());\r
50250 }\r
50251});\r
50252\r
50253\r
50254Ext.define('Ext.layout.Fit', {\r
50255 extend: Ext.layout.Default,\r
50256 isFit: true,\r
50257 alias: 'layout.fit',\r
50258 layoutClass: 'x-layout-fit',\r
50259 itemClass: 'x-layout-fit-item',\r
50260 setContainer: function(container) {\r
50261 this.callParent(arguments);\r
50262 container.innerElement.addCls(this.layoutClass);\r
50263 this.onContainerSizeFlagsChange();\r
50264 this.monitorSizeFlagsChange();\r
50265 },\r
50266 onContainerSizeFlagsChange: function() {\r
50267 var container = this.container,\r
50268 sizeFlags = container.getSizeFlags(),\r
50269 stretched = Boolean(sizeFlags & container.LAYOUT_STRETCHED),\r
50270 innerItems = container.innerItems,\r
50271 i, ln, item;\r
50272 this.callParent();\r
50273 for (i = 0 , ln = innerItems.length; i < ln; i++) {\r
50274 item = innerItems[i];\r
50275 item.setLayoutSizeFlags(sizeFlags);\r
50276 }\r
50277 container.innerElement.toggleCls('x-stretched', stretched);\r
50278 },\r
50279 onItemInnerStateChange: function(item, isInner) {\r
50280 this.callParent(arguments);\r
50281 item.toggleCls(this.itemClass, isInner);\r
50282 item.setLayoutSizeFlags(isInner ? this.container.getSizeFlags() : 0);\r
50283 }\r
50284});\r
50285\r
50286\r
50287Ext.define('Ext.layout.FlexBox', {\r
50288 extend: Ext.layout.Box,\r
50289 alias: 'layout.box',\r
50290 config: {\r
50291 align: 'stretch'\r
50292 },\r
50293 layoutBaseClass: 'x-layout-box',\r
50294 itemClass: 'x-layout-box-item',\r
50295 setContainer: function(container) {\r
50296 this.callParent(arguments);\r
50297 this.monitorSizeFlagsChange();\r
50298 },\r
50299 applyOrient: function(orient) {\r
50300
50301 if (orient !== 'horizontal' && orient !== 'vertical') {\r
50302 Ext.Logger.error("Invalid box orient of: '" + orient + "', must be either 'horizontal' or 'vertical'");\r
50303 }\r
50304
50305 return orient;\r
50306 },\r
50307 updateOrient: function(orient, oldOrient) {\r
50308 var container = this.container,\r
50309 delegation = {\r
50310 delegate: '> component'\r
50311 };\r
50312 if (orient === 'horizontal') {\r
50313 this.sizePropertyName = 'width';\r
50314 } else {\r
50315 this.sizePropertyName = 'height';\r
50316 }\r
50317 container.innerElement.swapCls('x-' + orient, 'x-' + oldOrient);\r
50318 if (oldOrient) {\r
50319 container.un(oldOrient === 'horizontal' ? 'widthchange' : 'heightchange', 'onItemSizeChange', this, delegation);\r
50320 this.redrawContainer();\r
50321 }\r
50322 container.on(orient === 'horizontal' ? 'widthchange' : 'heightchange', 'onItemSizeChange', this, delegation);\r
50323 },\r
50324 onItemInnerStateChange: function(item, isInner) {\r
50325 this.callParent(arguments);\r
50326 var flex, size;\r
50327 item.toggleCls(this.itemClass, isInner);\r
50328 if (isInner) {\r
50329 flex = item.getFlex();\r
50330 size = item.getConfig(this.sizePropertyName);\r
50331 if (flex) {\r
50332 this.doItemFlexChange(item, flex);\r
50333 } else if (size) {\r
50334 this.doItemSizeChange(item, size);\r
50335 }\r
50336 }\r
50337 this.refreshItemSizeState(item);\r
50338 },\r
50339 refreshItemSizeState: function(item) {\r
50340 var isInner = item.isInnerItem(),\r
50341 container = this.container,\r
50342 LAYOUT_HEIGHT = container.LAYOUT_HEIGHT,\r
50343 LAYOUT_WIDTH = container.LAYOUT_WIDTH,\r
50344 dimension = this.sizePropertyName,\r
50345 layoutSizeFlags = 0,\r
50346 containerSizeFlags = container.getSizeFlags();\r
50347 if (isInner) {\r
50348 layoutSizeFlags |= container.LAYOUT_STRETCHED;\r
50349 if (this.getAlign() === 'stretch') {\r
50350 layoutSizeFlags |= containerSizeFlags & (dimension === 'width' ? LAYOUT_HEIGHT : LAYOUT_WIDTH);\r
50351 }\r
50352 if (item.getFlex()) {\r
50353 layoutSizeFlags |= containerSizeFlags & (dimension === 'width' ? LAYOUT_WIDTH : LAYOUT_HEIGHT);\r
50354 }\r
50355 }\r
50356 item.setLayoutSizeFlags(layoutSizeFlags);\r
50357 },\r
50358 refreshAllItemSizedStates: function() {\r
50359 var innerItems = this.container.innerItems,\r
50360 i, ln, item;\r
50361 for (i = 0 , ln = innerItems.length; i < ln; i++) {\r
50362 item = innerItems[i];\r
50363 this.refreshItemSizeState(item);\r
50364 }\r
50365 },\r
50366 onContainerSizeFlagsChange: function() {\r
50367 this.refreshAllItemSizedStates();\r
50368 this.callParent(arguments);\r
50369 },\r
50370 onItemSizeChange: function(item, size) {\r
50371 if (item.isInnerItem()) {\r
50372 this.doItemSizeChange(item, size);\r
50373 }\r
50374 },\r
50375 doItemSizeChange: function(item, size) {\r
50376 if (size) {\r
50377 item.setFlex(null);\r
50378 this.redrawContainer();\r
50379 }\r
50380 },\r
50381 onItemFlexChange: function(item, flex) {\r
50382 if (item.isInnerItem()) {\r
50383 this.doItemFlexChange(item, flex);\r
50384 this.refreshItemSizeState(item);\r
50385 }\r
50386 },\r
50387 doItemFlexChange: function(item, flex) {\r
50388 this.setItemFlex(item, flex);\r
50389 if (flex) {\r
50390 item.setConfig(this.sizePropertyName, null);\r
50391 } else {\r
50392 this.redrawContainer();\r
50393 }\r
50394 },\r
50395 redrawContainer: function() {\r
50396 var container = this.container,\r
50397 renderedTo = container.element.dom.parentNode;\r
50398 if (renderedTo && renderedTo.nodeType !== 11) {\r
50399 container.innerElement.redraw();\r
50400 }\r
50401 },\r
50402 \r
50403 setItemFlex: function(item, flex) {\r
50404 var element = item.element,\r
50405 style = element.dom.style;\r
50406 element.toggleCls(Ext.baseCSSPrefix + 'flexed', !!flex);\r
50407 flex = flex ? String(flex) : '';\r
50408 if (Ext.browser.is.WebKit) {\r
50409 style.setProperty('-webkit-box-flex', flex, null);\r
50410 } else if (Ext.browser.is.IE) {\r
50411 style.setProperty('-ms-flex', flex + ' 0 0px', null);\r
50412 } else {\r
50413 style.setProperty('flex', flex + ' 0 0px', null);\r
50414 }\r
50415 },\r
50416 convertPosition: function(position) {\r
50417 var positionMap = this.positionMap;\r
50418 if (positionMap.hasOwnProperty(position)) {\r
50419 return positionMap[position];\r
50420 }\r
50421 return position;\r
50422 },\r
50423 applyAlign: function(align) {\r
50424 return this.convertPosition(align);\r
50425 },\r
50426 updateAlign: function(align, oldAlign) {\r
50427 var container = this.container;\r
50428 container.innerElement.swapCls(align, oldAlign, true, 'x-align');\r
50429 if (oldAlign !== undefined) {\r
50430 this.refreshAllItemSizedStates();\r
50431 }\r
50432 },\r
50433 applyPack: function(pack) {\r
50434 return this.convertPosition(pack);\r
50435 },\r
50436 updatePack: function(pack, oldPack) {\r
50437 this.container.innerElement.swapCls(pack, oldPack, true, 'x-pack');\r
50438 }\r
50439});\r
50440\r
50441\r
50442Ext.define('Ext.layout.Float', {\r
50443 extend: Ext.layout.Default,\r
50444 alias: 'layout.float',\r
50445 config: {\r
50446 direction: 'left'\r
50447 },\r
50448 layoutClass: 'layout-float',\r
50449 itemClass: 'layout-float-item',\r
50450 setContainer: function(container) {\r
50451 this.callParent(arguments);\r
50452 container.innerElement.addCls(this.layoutClass);\r
50453 },\r
50454 onItemInnerStateChange: function(item, isInner) {\r
50455 this.callParent(arguments);\r
50456 item.toggleCls(this.itemClass, isInner);\r
50457 },\r
50458 updateDirection: function(direction, oldDirection) {\r
50459 var prefix = 'direction-';\r
50460 this.container.innerElement.swapCls(prefix + direction, prefix + oldDirection);\r
50461 }\r
50462});\r
50463\r
50464\r
50465Ext.define('Ext.layout.HBox', {\r
50466 extend: Ext.layout.FlexBox,\r
50467 alias: 'layout.hbox'\r
50468});\r
50469\r
50470\r
50471Ext.define('Ext.layout.VBox', {\r
50472 extend: Ext.layout.FlexBox,\r
50473 alias: 'layout.vbox',\r
50474 config: {\r
50475 orient: 'vertical'\r
50476 }\r
50477});\r
50478\r
50479\r
50480Ext.define('Ext.layout.wrapper.Dock', {\r
50481 config: {\r
50482 direction: 'horizontal',\r
50483 element: {\r
50484 className: 'x-dock'\r
50485 },\r
50486 bodyElement: {\r
50487 className: 'x-dock-body'\r
50488 },\r
50489 innerWrapper: null,\r
50490 sizeState: false,\r
50491 container: null\r
50492 },\r
50493 positionMap: {\r
50494 top: 'start',\r
50495 left: 'start',\r
50496 bottom: 'end',\r
50497 right: 'end'\r
50498 },\r
50499 constructor: function(config) {\r
50500 this.items = {\r
50501 start: [],\r
50502 end: []\r
50503 };\r
50504 this.itemsCount = 0;\r
50505 this.initConfig(config);\r
50506 },\r
50507 addItems: function(items) {\r
50508 var i, ln, item;\r
50509 for (i = 0 , ln = items.length; i < ln; i++) {\r
50510 item = items[i];\r
50511 this.addItem(item);\r
50512 }\r
50513 },\r
50514 addItem: function(item) {\r
50515 var docked = item.getDocked(),\r
50516 position = this.positionMap[docked],\r
50517 wrapper = item.$dockWrapper,\r
50518 container = this.getContainer(),\r
50519 index = container.indexOf(item),\r
50520 items = this.items,\r
50521 sideItems = items[position],\r
50522 itemWrapper, element, i, ln, sibling, referenceElement, siblingIndex;\r
50523 if (wrapper) {\r
50524 wrapper.removeItem(item);\r
50525 }\r
50526 item.$dockWrapper = this;\r
50527 itemWrapper = item.link('$dockItemWrapper', new Ext.util.Wrapper({\r
50528 className: 'x-dock-item'\r
50529 }));\r
50530 item.addCls('x-docked-' + docked);\r
50531 element = itemWrapper.element;\r
50532 for (i = 0 , ln = sideItems.length; i < ln; i++) {\r
50533 sibling = sideItems[i];\r
50534 siblingIndex = container.indexOf(sibling);\r
50535 if (siblingIndex > index) {\r
50536 referenceElement = sibling.element;\r
50537 sideItems.splice(i, 0, item);\r
50538 break;\r
50539 }\r
50540 }\r
50541 if (!referenceElement) {\r
50542 sideItems.push(item);\r
50543 referenceElement = this.getBodyElement();\r
50544 }\r
50545 this.itemsCount++;\r
50546 if (position === 'start') {\r
50547 element.insertBefore(referenceElement);\r
50548 } else {\r
50549 element.insertAfter(referenceElement);\r
50550 }\r
50551 itemWrapper.wrap(item.element);\r
50552 itemWrapper.bindSize(this.getDirection() === 'horizontal' ? 'width' : 'height');\r
50553 },\r
50554 removeItem: function(item) {\r
50555 var position = item.getDocked(),\r
50556 items = this.items[this.positionMap[position]];\r
50557 item.removeCls('x-docked-' + position);\r
50558 Ext.Array.remove(items, item);\r
50559 item.unlink([\r
50560 '$dockItemWrapper'\r
50561 ]);\r
50562 item.element.detach();\r
50563 delete item.$dockWrapper;\r
50564 if (--this.itemsCount === 0) {\r
50565 this.destroy();\r
50566 }\r
50567 },\r
50568 getItemsSlice: function(index) {\r
50569 var container = this.getContainer(),\r
50570 items = this.items,\r
50571 slice = [],\r
50572 sideItems, i, ln, item;\r
50573 for (sideItems = items.start , i = 0 , ln = sideItems.length; i < ln; i++) {\r
50574 item = sideItems[i];\r
50575 if (container.indexOf(item) > index) {\r
50576 slice.push(item);\r
50577 }\r
50578 }\r
50579 for (sideItems = items.end , i = 0 , ln = sideItems.length; i < ln; i++) {\r
50580 item = sideItems[i];\r
50581 if (container.indexOf(item) > index) {\r
50582 slice.push(item);\r
50583 }\r
50584 }\r
50585 return slice;\r
50586 },\r
50587 applyElement: function(element) {\r
50588 return Ext.Element.create(element);\r
50589 },\r
50590 updateElement: function(element) {\r
50591 element.addCls('x-dock-' + this.getDirection());\r
50592 },\r
50593 applyBodyElement: function(bodyElement) {\r
50594 return Ext.Element.create(bodyElement);\r
50595 },\r
50596 updateBodyElement: function(bodyElement) {\r
50597 this.getElement().append(bodyElement);\r
50598 },\r
50599 updateInnerWrapper: function(innerWrapper, oldInnerWrapper) {\r
50600 var innerElement = this.getBodyElement();\r
50601 if (oldInnerWrapper && oldInnerWrapper.$outerWrapper === this) {\r
50602 innerElement.remove(oldInnerWrapper.getElement());\r
50603 delete oldInnerWrapper.$outerWrapper;\r
50604 }\r
50605 if (innerWrapper) {\r
50606 innerWrapper.setSizeState(this.getSizeState());\r
50607 innerWrapper.$outerWrapper = this;\r
50608 innerElement.append(innerWrapper.getElement());\r
50609 }\r
50610 },\r
50611 updateSizeState: function(state) {\r
50612 var innerWrapper = this.getInnerWrapper();\r
50613 this.getElement().setSizeState(state);\r
50614 if (innerWrapper) {\r
50615 innerWrapper.setSizeState(state);\r
50616 }\r
50617 },\r
50618 destroy: function() {\r
50619 var me = this,\r
50620 innerWrapper = me.getInnerWrapper(),\r
50621 outerWrapper = me.$outerWrapper;\r
50622 if (innerWrapper) {\r
50623 if (outerWrapper) {\r
50624 outerWrapper.setInnerWrapper(innerWrapper);\r
50625 } else {\r
50626 innerWrapper.getElement().replace(me.getElement());\r
50627 delete innerWrapper.$outerWrapper;\r
50628 }\r
50629 }\r
50630 delete me.$outerWrapper;\r
50631 me.setInnerWrapper(null);\r
50632 me.unlink([\r
50633 '_bodyElement',\r
50634 '_element'\r
50635 ]);\r
50636 me.callParent();\r
50637 }\r
50638});\r
50639\r
50640\r
50641Ext.define('Ext.util.ItemCollection', {\r
50642 extend: Ext.util.MixedCollection,\r
50643 alternateClassName: 'Ext.ItemCollection',\r
50644 getKey: function(item) {\r
50645 return item.getItemId && item.getItemId();\r
50646 },\r
50647 has: function(item) {\r
50648 return this.map.hasOwnProperty(item.getId());\r
50649 }\r
50650});\r
50651\r
50652\r
50653Ext.define('Ext.util.InputBlocker', {\r
50654 singleton: true,\r
50655 blockInputs: function() {\r
50656 if (Ext.browser.is.ie) {\r
50657 Ext.select('.x-field-text .x-field-input:not(.x-item-disabled) .x-input-el, .x-field-textarea .x-field-input:not(.x-item-disabled) .x-input-el, .x-field-search .x-field-input:not(.x-item-disabled) .x-input-el').each(function(item) {\r
50658 if (item.dom.offsetWidth > 0) {\r
50659 item.dom.setAttribute('disabled', true);\r
50660 item.dom.setAttribute('overlayfix', true);\r
50661 }\r
50662 });\r
50663 }\r
50664 },\r
50665 unblockInputs: function() {\r
50666 if (Ext.browser.is.ie) {\r
50667 Ext.select('[overlayfix]').each(function(item) {\r
50668 item.dom.removeAttribute('disabled');\r
50669 item.dom.removeAttribute('overlayfix');\r
50670 });\r
50671 }\r
50672 }\r
50673});\r
50674\r
50675\r
50676Ext.define('Ext.Mask', {\r
50677 extend: Ext.Component,\r
50678 xtype: 'mask',\r
50679 config: {\r
50680 \r
50681 baseCls: Ext.baseCSSPrefix + 'mask',\r
50682 \r
50683 transparent: false,\r
50684 \r
50685 top: 0,\r
50686 \r
50687 left: 0,\r
50688 \r
50689 right: 0,\r
50690 \r
50691 bottom: 0\r
50692 },\r
50693 \r
50694 initialize: function() {\r
50695 var me = this;\r
50696 me.callParent();\r
50697 me.element.on('tap', 'onTap', me);\r
50698 me.on('hide', 'onHide', me);\r
50699 },\r
50700 onHide: function() {\r
50701 Ext.util.InputBlocker.unblockInputs();\r
50702
50703 if (Ext.browser.is.AndroidStock4 && Ext.os.version.getMinor() === 0) {\r
50704 var firstChild = this.element.getFirstChild();\r
50705 if (firstChild) {\r
50706 firstChild.redraw();\r
50707 }\r
50708 }\r
50709 },\r
50710 onTap: function(e) {\r
50711 this.fireEvent('tap', this, e);\r
50712 },\r
50713 updateTransparent: function(transparent) {\r
50714 this.toggleCls(this.getBaseCls() + '-transparent', transparent);\r
50715 }\r
50716});\r
50717\r
50718\r
50719Ext.define('Ext.mixin.Queryable', {\r
50720 mixinId: 'queryable',\r
50721 isQueryable: true,\r
50722 \r
50723 query: function(selector) {\r
50724 selector = selector || '*';\r
50725 return Ext.ComponentQuery.query(selector, this.getQueryRoot());\r
50726 },\r
50727 \r
50728 queryBy: function(fn, scope) {\r
50729 var out = [],\r
50730 items = this.getQueryRoot().getRefItems(true),\r
50731 i = 0,\r
50732 len = items.length,\r
50733 item;\r
50734 for (; i < len; ++i) {\r
50735 item = items[i];\r
50736 if (fn.call(scope || item, item) !== false) {\r
50737 out.push(item);\r
50738 }\r
50739 }\r
50740 return out;\r
50741 },\r
50742 \r
50743 queryById: function(id) {\r
50744 return this.down(Ext.makeIdSelector(id));\r
50745 },\r
50746 \r
50747 child: function(selector) {\r
50748 var children = this.getQueryRoot().getRefItems();\r
50749 if (selector && selector.isComponent) {\r
50750 return this.matchById(children, selector.getItemId());\r
50751 }\r
50752
50753 if (selector) {\r
50754 children = Ext.ComponentQuery.query(selector, children);\r
50755 }\r
50756
50757 if (children.length) {\r
50758 return children[0];\r
50759 }\r
50760 return null;\r
50761 },\r
50762 \r
50763 down: function(selector) {\r
50764 if (selector && selector.isComponent) {\r
50765 return this.matchById(this.getRefItems(true), selector.getItemId());\r
50766 }\r
50767 selector = selector || '';\r
50768 return this.query(selector)[0] || null;\r
50769 },\r
50770 \r
50771 visitPreOrder: function(selector, fn, scope, extraArgs) {\r
50772 Ext.ComponentQuery._visit(true, selector, this.getQueryRoot(), fn, scope, extraArgs);\r
50773 },\r
50774 \r
50775 visitPostOrder: function(selector, fn, scope, extraArgs) {\r
50776 Ext.ComponentQuery._visit(false, selector, this.getQueryRoot(), fn, scope, extraArgs);\r
50777 },\r
50778 getRefItems: function() {\r
50779 return [];\r
50780 },\r
50781 getQueryRoot: function() {\r
50782 return this;\r
50783 },\r
50784 privates: {\r
50785 matchById: function(items, id) {\r
50786 var len = items.length,\r
50787 i, item;\r
50788 for (i = 0; i < len; ++i) {\r
50789 item = items[i];\r
50790 if (item.getItemId() === id) {\r
50791 return item;\r
50792 }\r
50793 }\r
50794 return null;\r
50795 }\r
50796 }\r
50797});\r
50798\r
50799\r
50800Ext.define('Ext.mixin.Container', {\r
50801 extend: Ext.Mixin,\r
50802 mixinConfig: {\r
50803 id: 'container'\r
50804 },\r
50805 \r
50806 isContainer: true,\r
50807 config: {\r
50808 \r
50809 referenceHolder: false\r
50810 },\r
50811 \r
50812 getReferences: function() {\r
50813 Ext.ComponentManager.fixReferences();\r
50814 return this.refs || null;\r
50815 },\r
50816 \r
50817 lookup: function(key) {\r
50818 var refs = this.getReferences();\r
50819 return (refs && refs[key]) || null;\r
50820 },\r
50821 \r
50822 lookupReference: function(key) {\r
50823 return this.lookup(key);\r
50824 },\r
50825 privates: {\r
50826 \r
50827 attachReference: function(component) {\r
50828 var me = this,\r
50829 key, refs;\r
50830
50831 if (me.destroying || me.destroyed) {\r
50832 return;\r
50833 }\r
50834 refs = me.refs || (me.refs = {});\r
50835 key = component.referenceKey;\r
50836
50837 if (refs[key] && refs[key] !== component) {\r
50838 Ext.log.warn('Duplicate reference: "' + key + '" on ' + me.id);\r
50839 }\r
50840
50841 refs[key] = component;\r
50842 },\r
50843 \r
50844 clearReference: function(component) {\r
50845 var refs = this.refs,\r
50846 key = component.referenceKey;\r
50847 if (refs && key) {\r
50848
50849
50850
50851 component.viewModelKey = component.referenceKey = refs[key] = null;\r
50852 }\r
50853 },\r
50854 containerOnAdded: function(component, instanced) {\r
50855
50856
50857
50858 if (instanced) {\r
50859 Ext.ComponentManager.markReferencesDirty();\r
50860 }\r
50861 },\r
50862 containerOnRemoved: function(destroying) {\r
50863 var refHolder;\r
50864
50865 if (!destroying) {\r
50866 refHolder = this.lookupReferenceHolder();\r
50867 if (refHolder) {\r
50868
50869
50870
50871
50872 Ext.ComponentManager.markReferencesDirty();\r
50873 refHolder.clearReferences();\r
50874 }\r
50875 }\r
50876 },\r
50877 \r
50878 clearReferences: function() {\r
50879 this.refs = null;\r
50880 },\r
50881 initContainerInheritedState: function(inheritedState, inheritedStateInner) {\r
50882 var me = this,\r
50883 controller = me.getController(),\r
50884 session = me.getSession(),\r
50885
50886
50887 viewModel = me.getConfig('viewModel', true),\r
50888 reference = me.getReference(),\r
50889 referenceHolder = me.getReferenceHolder();\r
50890 if (controller) {\r
50891 inheritedState.referenceHolder = controller;\r
50892 referenceHolder = true;\r
50893 } else if (referenceHolder) {\r
50894 inheritedState.referenceHolder = me;\r
50895 }\r
50896 if (referenceHolder) {\r
50897 inheritedState.referencePath = '';\r
50898 } else if (reference && me.isParentReference) {\r
50899 inheritedState.referencePath = me.referenceKey + '.';\r
50900 }\r
50901 if (session) {\r
50902 inheritedState.session = session;\r
50903 }\r
50904 if (viewModel) {\r
50905 inheritedState.viewModelPath = '';\r
50906 } else if (reference && me.isParentReference) {\r
50907 inheritedState.viewModelPath = me.viewModelKey + '.';\r
50908 }\r
50909 },\r
50910 setupReference: function(reference) {\r
50911 var len;\r
50912 if (reference && reference.charAt(len = reference.length - 1) === '>') {\r
50913 this.isParentReference = true;\r
50914 reference = reference.substring(0, len);\r
50915 }\r
50916
50917 if (reference && !Ext.validIdRe.test(reference)) {\r
50918 Ext.Error.raise('Invalid reference "' + reference + '" for ' + this.getId() + ' - not a valid identifier');\r
50919 }\r
50920
50921 return reference;\r
50922 }\r
50923 }\r
50924});\r
50925\r
50926\r
50927Ext.define('Ext.Container', {\r
50928 extend: Ext.Component,\r
50929 alternateClassName: [\r
50930 'Ext.lib.Container',\r
50931 'Ext.container.Container'\r
50932 ],\r
50933 xtype: 'container',\r
50934 mixins: [\r
50935 Ext.mixin.Queryable,\r
50936 Ext.mixin.Container\r
50937 ],\r
50938 \r
50939 \r
50940 \r
50941 \r
50942 \r
50943 \r
50944 eventedConfig: {\r
50945 \r
50946 activeItem: 0\r
50947 },\r
50948 config: {\r
50949 \r
50950 \r
50951 layout: 'default',\r
50952 \r
50953 control: {},\r
50954 \r
50955 defaults: null,\r
50956
50957 \r
50958 items: null,\r
50959 \r
50960 autoDestroy: true,\r
50961 \r
50962 defaultType: null,\r
50963 \r
50964 masked: null,\r
50965 \r
50966 modal: null,\r
50967 \r
50968 hideOnMaskTap: null\r
50969 },\r
50970 \r
50971 manageBorders: false,\r
50972 constructor: function(config) {\r
50973 var me = this;\r
50974 me._items = me.items = new Ext.util.ItemCollection();\r
50975 me.innerItems = [];\r
50976 me.getReferences = me.getFirstReferences;\r
50977 me.onItemAdd = me.onFirstItemAdd;\r
50978 me.callParent(arguments);\r
50979 delete me.getReferences;\r
50980 if (me.manageBorders) {\r
50981 me.element.addCls('x-managed-borders');\r
50982 }\r
50983 },\r
50984 initialize: function() {\r
50985 this.callParent();\r
50986
50987
50988
50989 this.getLayout();\r
50990 },\r
50991 getElementConfig: function() {\r
50992 return {\r
50993 reference: 'element',\r
50994 classList: [\r
50995 'x-container',\r
50996 'x-unsized'\r
50997 ],\r
50998 children: [\r
50999 {\r
51000 reference: 'innerElement',\r
51001 className: 'x-inner'\r
51002 }\r
51003 ]\r
51004 };\r
51005 },\r
51006 \r
51007 applyMasked: function(masked) {\r
51008 var isVisible = true,\r
51009 currentMask;\r
51010 if (masked === false) {\r
51011 masked = true;\r
51012 isVisible = false;\r
51013 }\r
51014 currentMask = Ext.factory(masked, Ext.Mask, this.getMasked());\r
51015 if (currentMask) {\r
51016 this.add(currentMask);\r
51017 currentMask.setHidden(!isVisible);\r
51018 }\r
51019 return currentMask;\r
51020 },\r
51021 \r
51022 mask: function(mask) {\r
51023 this.setMasked(mask || true);\r
51024 },\r
51025 \r
51026 unmask: function() {\r
51027 this.setMasked(false);\r
51028 },\r
51029 initInheritedState: function(inheritedState, inheritedStateInner) {\r
51030 this.callParent([\r
51031 inheritedState,\r
51032 inheritedStateInner\r
51033 ]);\r
51034 this.initContainerInheritedState(inheritedState, inheritedStateInner);\r
51035 },\r
51036 onAdded: function(parent, instanced) {\r
51037 var me = this,\r
51038 modal;\r
51039 me.callParent([\r
51040 parent,\r
51041 instanced\r
51042 ]);\r
51043 me.containerOnAdded(parent, instanced);\r
51044 modal = me.getModal();\r
51045 if (modal) {\r
51046 parent.insertBefore(modal, me);\r
51047 modal.setZIndex(me.getZIndex() - 1);\r
51048 }\r
51049 },\r
51050 onRemoved: function(destroying) {\r
51051 this.containerOnRemoved(destroying);\r
51052 this.callParent([\r
51053 destroying\r
51054 ]);\r
51055 },\r
51056 applyModal: function(modal, currentModal) {\r
51057 var isVisible = true;\r
51058 if (modal === false) {\r
51059 modal = true;\r
51060 isVisible = false;\r
51061 }\r
51062 currentModal = Ext.factory(modal, Ext.Mask, currentModal);\r
51063 if (currentModal) {\r
51064 currentModal.setVisibility(isVisible);\r
51065 }\r
51066 return currentModal;\r
51067 },\r
51068 updateModal: function(modal) {\r
51069 var container = this.getParent();\r
51070 if (container) {\r
51071 if (modal) {\r
51072 container.insertBefore(modal, this);\r
51073 modal.setZIndex(this.getZIndex() - 1);\r
51074 } else {\r
51075 container.remove(modal);\r
51076 }\r
51077 }\r
51078 },\r
51079 updateHideOnMaskTap: function(hide) {\r
51080 var mask = this.getModal();\r
51081 if (mask) {\r
51082 mask[hide ? 'on' : 'un'].call(mask, 'tap', 'hide', this);\r
51083 }\r
51084 },\r
51085 updateZIndex: function(zIndex) {\r
51086 var modal = this.getModal();\r
51087 this.callParent(arguments);\r
51088 if (modal) {\r
51089 modal.setZIndex(zIndex - 1);\r
51090 }\r
51091 },\r
51092 updateBaseCls: function(newBaseCls, oldBaseCls) {\r
51093 var me = this,\r
51094 element = me.element,\r
51095 ui = me.getUi();\r
51096 if (oldBaseCls) {\r
51097 element.removeCls(oldBaseCls);\r
51098 me.innerElement.removeCls(newBaseCls, null, 'inner');\r
51099 if (ui) {\r
51100 element.removeCls(me.currentUi);\r
51101 }\r
51102 }\r
51103 if (newBaseCls) {\r
51104 element.addCls(newBaseCls);\r
51105 me.innerElement.addCls(newBaseCls, null, 'inner');\r
51106 if (ui) {\r
51107 element.addCls(newBaseCls, null, ui);\r
51108 me.currentUi = newBaseCls + '-' + ui;\r
51109 }\r
51110 }\r
51111 },\r
51112 applyItems: function(items, collection) {\r
51113 if (items) {\r
51114 var me = this,\r
51115 activeItem;\r
51116 me.getDefaultType();\r
51117 me.getDefaults();\r
51118 if (me.initialized && collection.length > 0) {\r
51119 me.removeAll();\r
51120 }\r
51121 me.add(items);\r
51122
51123 if (me.initialized) {\r
51124 activeItem = me.initialConfig.activeItem || me.config.activeItem || 0;\r
51125 me.setActiveItem(activeItem);\r
51126 }\r
51127 }\r
51128 },\r
51129 \r
51130 applyControl: function(selectors) {\r
51131 var selector, key, listener, listeners;\r
51132 for (selector in selectors) {\r
51133 listeners = selectors[selector];\r
51134 for (key in listeners) {\r
51135 listener = listeners[key];\r
51136 if (Ext.isObject(listener)) {\r
51137 listener.delegate = selector;\r
51138 }\r
51139 }\r
51140 listeners.delegate = selector;\r
51141 this.addListener(listeners);\r
51142 }\r
51143 return selectors;\r
51144 },\r
51145 \r
51146 onFirstItemAdd: function() {\r
51147 var me = this;\r
51148 delete me.onItemAdd;\r
51149 if (me.innerHtmlElement && !me.getHtml()) {\r
51150 me.innerHtmlElement.destroy();\r
51151 delete me.innerHtmlElement;\r
51152 }\r
51153 me.on('innerstatechange', 'onItemInnerStateChange', me, {\r
51154 delegate: '> component'\r
51155 });\r
51156 return me.onItemAdd.apply(me, arguments);\r
51157 },\r
51158
51159 updateLayout: function(newLayout, oldLayout) {\r
51160
51161 if (!oldLayout || !oldLayout.isLayout) {\r
51162 return;\r
51163 }\r
51164 if (!oldLayout.isCompatible(newLayout)) {\r
51165 Ext.Logger.error('Replacing a layout after one has already been initialized is not supported. ' + this.$className + '#' + this.getId() + ' (' + oldLayout.$className + ' / ' + (Ext.isString(newLayout) ? newLayout : JSON.stringify(newLayout)) + ')');\r
51166 }\r
51167 },\r
51168
51169 getLayout: function() {\r
51170 var layout = this.layout;\r
51171 if (!(layout && layout.isLayout)) {\r
51172 layout = this.link('_layout', this.link('layout', Ext.factory(this._layout || 'default', Ext.layout.Default, null, 'layout')));\r
51173 layout.setContainer(this);\r
51174 }\r
51175 return layout;\r
51176 },\r
51177 updateDefaultType: function(defaultType) {\r
51178
51179 this.defaultItemClass = Ext.ClassManager.getByAlias('widget.' + defaultType);\r
51180
51181 if (!this.defaultItemClass) {\r
51182 Ext.Logger.error("Invalid defaultType of: '" + defaultType + "', must be a valid component xtype");\r
51183 }\r
51184 },\r
51185
51186 \r
51187 factoryItem: function(item) {\r
51188
51189 if (!item) {\r
51190 Ext.Logger.error("Invalid item given: " + item + ", must be either the config object to factory a new item, " + "or an existing component instance");\r
51191 }\r
51192
51193 var me = this,\r
51194 defaults = me.getDefaults(),\r
51195 instance;\r
51196
51197 if (item.isComponent) {\r
51198 instance = item;\r
51199
51200 if (defaults && item.isInnerItem() && !me.has(instance)) {\r
51201 instance.setConfig(defaults, true);\r
51202 }\r
51203 } else
51204 {\r
51205 if (defaults && !item.ignoreDefaults) {\r
51206
51207
51208
51209 if (!(item.hasOwnProperty('left') && item.hasOwnProperty('right') && item.hasOwnProperty('top') && item.hasOwnProperty('bottom') && item.hasOwnProperty('docked') && item.hasOwnProperty('centered'))) {\r
51210 item = Ext.mergeIf({}, item, defaults);\r
51211 }\r
51212 }\r
51213
51214
51215 if (!me.$hasCachedDefaultItemClass) {\r
51216 me.getDefaultType();\r
51217 me.$hasCachedDefaultItemClass = true;\r
51218 }\r
51219 instance = Ext.factory(item, me.defaultItemClass);\r
51220 }\r
51221 return instance;\r
51222 },\r
51223 \r
51224 add: function(newItems) {\r
51225 var me = this,\r
51226 addingArray = true,\r
51227 addedItems = [],\r
51228 i, ln, item, newActiveItem, instanced;\r
51229 if (!Ext.isArray(newItems)) {\r
51230 newItems = [\r
51231 newItems\r
51232 ];\r
51233 addingArray = false;\r
51234 }\r
51235 for (i = 0 , ln = newItems.length; i < ln; i++) {\r
51236 item = newItems[i];\r
51237 instanced = item.isWidget;\r
51238 if (!instanced) {\r
51239 item.$initParent = me;\r
51240 }\r
51241 item = me.factoryItem(item);\r
51242 me.doAdd(item, instanced);\r
51243 delete item.$initParent;\r
51244 if (!newActiveItem && !me.getActiveItem() && me.innerItems.length > 0 && item.isInnerItem()) {\r
51245 newActiveItem = item;\r
51246 }\r
51247 addedItems.push(item);\r
51248 }\r
51249 if (newActiveItem) {\r
51250 me.setActiveItem(newActiveItem);\r
51251 }\r
51252 return addingArray ? addedItems : addedItems[0];\r
51253 },\r
51254 \r
51255 doAdd: function(item, instanced) {\r
51256 var me = this,\r
51257 items = me.getItems(),\r
51258 index;\r
51259 if (!items.has(item)) {\r
51260 index = items.length;\r
51261 items.add(item);\r
51262 if (item.isInnerItem()) {\r
51263 me.insertInner(item);\r
51264 }\r
51265 item.onAdded(me, !!instanced);\r
51266 me.onItemAdd(item, index);\r
51267 }\r
51268 },\r
51269 \r
51270 remove: function(item, destroy) {\r
51271 var me = this,\r
51272 index, innerItems;\r
51273 item = me.getComponent(item);\r
51274 index = me.indexOf(item);\r
51275 innerItems = me.getInnerItems();\r
51276 if (destroy === undefined) {\r
51277 destroy = me.getAutoDestroy();\r
51278 }\r
51279 if (index !== -1) {\r
51280 if (!me.removingAll && innerItems.length > 1 && item === me.getActiveItem()) {\r
51281 me.on({\r
51282 activeitemchange: 'doRemove',\r
51283 scope: me,\r
51284 single: true,\r
51285 order: 'after',\r
51286 args: [\r
51287 item,\r
51288 index,\r
51289 destroy\r
51290 ]\r
51291 });\r
51292 me.doResetActiveItem(innerItems.indexOf(item));\r
51293 } else {\r
51294 me.doRemove(item, index, destroy);\r
51295 if (innerItems.length === 0) {\r
51296 me.setActiveItem(null);\r
51297 }\r
51298 }\r
51299 }\r
51300 return item;\r
51301 },\r
51302 doResetActiveItem: function(innerIndex) {\r
51303 if (innerIndex === 0) {\r
51304 this.setActiveItem(1);\r
51305 } else {\r
51306 this.setActiveItem(0);\r
51307 }\r
51308 },\r
51309 doRemove: function(item, index, destroy) {\r
51310 var me = this;\r
51311 me.items.remove(item);\r
51312 if (item.isInnerItem()) {\r
51313 me.removeInner(item);\r
51314 }\r
51315 me.onItemRemove(item, index, destroy);\r
51316 item.onRemoved(item.destroying || destroy);\r
51317 if (destroy) {\r
51318 item.destroy();\r
51319 }\r
51320 },\r
51321 \r
51322 removeAll: function(destroy, everything) {\r
51323 var items = this.items,\r
51324 removed = [],\r
51325 ln = items.length,\r
51326 i = 0,\r
51327 item;\r
51328 if (typeof destroy != 'boolean') {\r
51329 destroy = this.getAutoDestroy();\r
51330 }\r
51331 everything = Boolean(everything);\r
51332
51333 this.removingAll = true;\r
51334 for (; i < ln; i++) {\r
51335 item = items.getAt(i);\r
51336 if (item && (everything || item.isInnerItem())) {\r
51337 this.doRemove(item, i, destroy);\r
51338 i--;\r
51339 ln--;\r
51340 }\r
51341 removed.push(item);\r
51342 }\r
51343 this.setActiveItem(null);\r
51344 this.removingAll = false;\r
51345 return removed;\r
51346 },\r
51347 \r
51348 getAt: function(index) {\r
51349 return this.items.getAt(index);\r
51350 },\r
51351 getInnerAt: function(index) {\r
51352 return this.innerItems[index];\r
51353 },\r
51354 \r
51355 removeAt: function(index) {\r
51356 var item = this.getAt(index);\r
51357 if (item) {\r
51358 this.remove(item);\r
51359 }\r
51360 return item;\r
51361 },\r
51362 \r
51363 removeInnerAt: function(index) {\r
51364 var item = this.getInnerItems()[index];\r
51365 if (item) {\r
51366 this.remove(item);\r
51367 }\r
51368 return item;\r
51369 },\r
51370 \r
51371 has: function(item) {\r
51372 return this.getItems().indexOf(item) != -1;\r
51373 },\r
51374 \r
51375 hasInnerItem: function(item) {\r
51376 return this.innerItems.indexOf(item) != -1;\r
51377 },\r
51378 \r
51379 indexOf: function(item) {\r
51380 return this.getItems().indexOf(item);\r
51381 },\r
51382 innerIndexOf: function(item) {\r
51383 return this.innerItems.indexOf(item);\r
51384 },\r
51385 \r
51386 insertInner: function(item, index) {\r
51387 var items = this.getItems().items,\r
51388 innerItems = this.innerItems,\r
51389 currentInnerIndex = innerItems.indexOf(item),\r
51390 newInnerIndex = -1,\r
51391 nextSibling;\r
51392 if (currentInnerIndex !== -1) {\r
51393 innerItems.splice(currentInnerIndex, 1);\r
51394 }\r
51395 if (typeof index == 'number') {\r
51396 do {\r
51397 nextSibling = items[++index];\r
51398 } while (nextSibling && !nextSibling.isInnerItem());\r
51399 if (nextSibling) {\r
51400 newInnerIndex = innerItems.indexOf(nextSibling);\r
51401 innerItems.splice(newInnerIndex, 0, item);\r
51402 }\r
51403 }\r
51404 if (newInnerIndex === -1) {\r
51405 innerItems.push(item);\r
51406 newInnerIndex = innerItems.length - 1;\r
51407 }\r
51408 if (currentInnerIndex !== -1) {\r
51409 this.onInnerItemMove(item, newInnerIndex, currentInnerIndex);\r
51410 }\r
51411 return this;\r
51412 },\r
51413 onInnerItemMove: Ext.emptyFn,\r
51414 \r
51415 removeInner: function(item) {\r
51416 Ext.Array.remove(this.innerItems, item);\r
51417 return this;\r
51418 },\r
51419 \r
51420 insert: function(index, item) {\r
51421 var me = this,\r
51422 instanced, i;\r
51423
51424 if (typeof index != 'number') {\r
51425 Ext.Logger.error("Invalid index of '" + index + "', must be a valid number");\r
51426 }\r
51427
51428 if (Ext.isArray(item)) {\r
51429 for (i = item.length - 1; i >= 0; i--) {\r
51430 me.insert(index, item[i]);\r
51431 }\r
51432 return me;\r
51433 }\r
51434 instanced = item.isWidget;\r
51435 if (!instanced) {\r
51436 item.$initParent = me;\r
51437 }\r
51438 item = me.factoryItem(item);\r
51439 me.doInsert(index, item, instanced);\r
51440 delete item.$initParent;\r
51441 return item;\r
51442 },\r
51443 \r
51444 doInsert: function(index, item, instanced) {\r
51445 var me = this,\r
51446 items = me.items,\r
51447 itemsLength = items.length,\r
51448 currentIndex, isInnerItem;\r
51449 isInnerItem = item.isInnerItem();\r
51450 if (index > itemsLength) {\r
51451 index = itemsLength;\r
51452 }\r
51453 if (items[index - 1] === item) {\r
51454 return me;\r
51455 }\r
51456 currentIndex = me.indexOf(item);\r
51457 if (currentIndex !== -1) {\r
51458 items.removeAt(currentIndex);\r
51459 }\r
51460 items.insert(index, item);\r
51461 if (currentIndex === -1) {\r
51462 item.onAdded(me, !!instanced);\r
51463 }\r
51464 if (isInnerItem) {\r
51465 me.insertInner(item, index);\r
51466 }\r
51467 if (currentIndex !== -1) {\r
51468 me.onItemMove(item, index, currentIndex);\r
51469 } else {\r
51470 me.onItemAdd(item, index);\r
51471 }\r
51472 },\r
51473 \r
51474 insertFirst: function(item) {\r
51475 return this.insert(0, item);\r
51476 },\r
51477 \r
51478 insertLast: function(item) {\r
51479 return this.insert(this.getItems().length, item);\r
51480 },\r
51481 \r
51482 insertBefore: function(item, relativeToItem) {\r
51483 var index = this.indexOf(relativeToItem);\r
51484 if (index !== -1) {\r
51485 this.insert(index, item);\r
51486 }\r
51487 return this;\r
51488 },\r
51489 \r
51490 insertAfter: function(item, relativeToItem) {\r
51491 var index = this.indexOf(relativeToItem);\r
51492 if (index !== -1) {\r
51493 this.insert(index + 1, item);\r
51494 }\r
51495 return this;\r
51496 },\r
51497 \r
51498 onItemAdd: function(item, index) {\r
51499 var me = this;\r
51500 me.doItemLayoutAdd(item, index);\r
51501 if (me.initialized) {\r
51502 if (item.hasListeners.added) {\r
51503 item.fireEvent('added', item, me, index);\r
51504 }\r
51505 if (me.hasListeners.add) {\r
51506 me.fireEvent('add', me, item, index);\r
51507 }\r
51508 }\r
51509 },\r
51510 doItemLayoutAdd: function(item, index) {\r
51511 var layout = this.getLayout();\r
51512 if (this.isRendered() && item.setRendered(true)) {\r
51513 item.fireAction('renderedchange', [\r
51514 this,\r
51515 item,\r
51516 true\r
51517 ], 'onItemAdd', layout, {\r
51518 args: [\r
51519 item,\r
51520 index\r
51521 ]\r
51522 });\r
51523 } else {\r
51524 layout.onItemAdd(item, index);\r
51525 }\r
51526 },\r
51527 \r
51528 onItemRemove: function(item, index, destroying) {\r
51529 var me = this;\r
51530 me.doItemLayoutRemove(item, index, destroying);\r
51531 if (item.hasListeners.removed) {\r
51532 item.fireEvent('removed', item, me, index);\r
51533 }\r
51534 if (me.hasListeners.remove) {\r
51535 me.fireEvent('remove', me, item, index);\r
51536 }\r
51537 },\r
51538 doItemLayoutRemove: function(item, index, destroying) {\r
51539 var layout = this.getLayout();\r
51540 if (this.isRendered() && item.setRendered(false)) {\r
51541 item.fireAction('renderedchange', [\r
51542 this,\r
51543 item,\r
51544 false\r
51545 ], 'onItemRemove', layout, {\r
51546 args: [\r
51547 item,\r
51548 index,\r
51549 destroying\r
51550 ]\r
51551 });\r
51552 } else {\r
51553 layout.onItemRemove(item, index, destroying);\r
51554 }\r
51555 },\r
51556 \r
51557 onItemMove: function(item, toIndex, fromIndex) {\r
51558 var me = this;\r
51559 if (item.isDocked()) {\r
51560 item.setDocked(null);\r
51561 }\r
51562 me.doItemLayoutMove(item, toIndex, fromIndex);\r
51563 if (item.hasListeners.moved) {\r
51564 item.fireEvent('moved', item, me, toIndex, fromIndex);\r
51565 }\r
51566 if (me.hasListeners.move) {\r
51567 me.fireEvent('move', me, item, toIndex, fromIndex);\r
51568 }\r
51569 },\r
51570 doItemLayoutMove: function(item, toIndex, fromIndex) {\r
51571 this.getLayout().onItemMove(item, toIndex, fromIndex);\r
51572 },\r
51573 onItemInnerStateChange: function(item, isInner) {\r
51574 var layout = this.getLayout();\r
51575 if (isInner) {\r
51576 this.insertInner(item, this.items.indexOf(item));\r
51577 } else {\r
51578 this.removeInner(item);\r
51579 }\r
51580 layout.onItemInnerStateChange.apply(layout, arguments);\r
51581 },\r
51582 \r
51583 getInnerItems: function() {\r
51584 return this.innerItems;\r
51585 },\r
51586 \r
51587 getDockedItems: function() {\r
51588 var items = this.getItems().items,\r
51589 dockedItems = [],\r
51590 ln = items.length,\r
51591 item, i;\r
51592 for (i = 0; i < ln; i++) {\r
51593 item = items[i];\r
51594 if (item.isDocked()) {\r
51595 dockedItems.push(item);\r
51596 }\r
51597 }\r
51598 return dockedItems;\r
51599 },\r
51600 \r
51601 applyActiveItem: function(activeItem, currentActiveItem) {\r
51602 var me = this,\r
51603 innerItems = me.getInnerItems();\r
51604
51605 me.getItems();\r
51606
51607 if (!activeItem && innerItems.length === 0) {\r
51608 return 0;\r
51609 } else if (typeof activeItem == 'number') {\r
51610 activeItem = Math.max(0, Math.min(activeItem, innerItems.length - 1));\r
51611 activeItem = innerItems[activeItem];\r
51612 if (activeItem) {\r
51613 return activeItem;\r
51614 } else if (currentActiveItem) {\r
51615 return null;\r
51616 }\r
51617 } else if (activeItem) {\r
51618 var item;\r
51619
51620 if (typeof activeItem == 'string') {\r
51621 item = me.child(activeItem);\r
51622 activeItem = {\r
51623 xtype: activeItem\r
51624 };\r
51625 }\r
51626 if (!item || !item.isComponent) {\r
51627 activeItem.$initParent = me;\r
51628 item = me.factoryItem(activeItem);\r
51629 }\r
51630 me.pendingActiveItem = item;\r
51631
51632 if (!item.isInnerItem()) {\r
51633 Ext.Logger.error("Setting activeItem to be a non-inner item");\r
51634 }\r
51635
51636 if (!me.has(item)) {\r
51637 me.add(item);\r
51638 }\r
51639 delete item.$initParent;\r
51640 return item;\r
51641 }\r
51642 },\r
51643 \r
51644 animateActiveItem: function(activeItem, animation) {\r
51645 var layout = this.getLayout(),\r
51646 defaultAnimation;\r
51647 if (this.activeItemAnimation) {\r
51648 this.activeItemAnimation.destroy();\r
51649 }\r
51650 this.activeItemAnimation = animation = new Ext.fx.layout.Card(animation);\r
51651 if (animation && layout.isCard) {\r
51652 animation.setLayout(layout);\r
51653 defaultAnimation = layout.getAnimation();\r
51654 if (defaultAnimation) {\r
51655 defaultAnimation.disable();\r
51656 }\r
51657 animation.on('animationend', function() {\r
51658 if (defaultAnimation) {\r
51659 defaultAnimation.enable();\r
51660 }\r
51661 animation.destroy();\r
51662 }, this);\r
51663 }\r
51664 return this.setActiveItem(activeItem);\r
51665 },\r
51666 \r
51667 updateActiveItem: function(newActiveItem, oldActiveItem) {\r
51668 delete this.pendingActiveItem;\r
51669 if (oldActiveItem) {\r
51670 oldActiveItem.fireEvent('deactivate', oldActiveItem, this, newActiveItem);\r
51671 }\r
51672 if (newActiveItem) {\r
51673 newActiveItem.fireEvent('activate', newActiveItem, this, oldActiveItem);\r
51674 }\r
51675 },\r
51676 show: function() {\r
51677 this.callParent(arguments);\r
51678 var modal = this.getModal();\r
51679 if (modal) {\r
51680 modal.setHidden(false);\r
51681 }\r
51682 return this;\r
51683 },\r
51684 hide: function() {\r
51685 this.callParent(arguments);\r
51686 var modal = this.getModal();\r
51687 if (modal) {\r
51688 modal.setHidden(true);\r
51689 }\r
51690 return this;\r
51691 },\r
51692 updateHidden: function(hidden) {\r
51693 var modal = this.getModal();\r
51694 if (modal && (modal.getHidden() !== hidden)) {\r
51695 modal.setHidden(hidden);\r
51696 }\r
51697 this.callParent(arguments);\r
51698 },\r
51699 \r
51700 setRendered: function(rendered) {\r
51701 if (this.callParent(arguments)) {\r
51702 var items = this.items.items,\r
51703 i, ln;\r
51704 for (i = 0 , ln = items.length; i < ln; i++) {\r
51705 items[i].setRendered(rendered);\r
51706 }\r
51707 return true;\r
51708 }\r
51709 return false;\r
51710 },\r
51711 \r
51712 getRefItems: function(deep) {\r
51713 var items = this.getItems().items.slice(),\r
51714 ln = items.length,\r
51715 i, item;\r
51716 if (deep) {\r
51717 for (i = 0; i < ln; i++) {\r
51718 item = items[i];\r
51719 if (item.getRefItems) {\r
51720 items = items.concat(item.getRefItems(true));\r
51721 }\r
51722 }\r
51723 }\r
51724 return items;\r
51725 },\r
51726 \r
51727 getComponent: function(component) {\r
51728 if (typeof component === 'number') {\r
51729 return this.getItems().getAt(component);\r
51730 }\r
51731 if (Ext.isObject(component)) {\r
51732 component = component.getItemId();\r
51733 }\r
51734 return this.getItems().get(component);\r
51735 },\r
51736 \r
51737 getDockedComponent: function(component) {\r
51738 if (Ext.isObject(component)) {\r
51739 component = component.getItemId();\r
51740 }\r
51741 var dockedItems = this.getDockedItems(),\r
51742 ln = dockedItems.length,\r
51743 item, i;\r
51744 if (Ext.isNumber(component)) {\r
51745 return dockedItems[component];\r
51746 }\r
51747 for (i = 0; i < ln; i++) {\r
51748 item = dockedItems[i];\r
51749 if (item.id == component) {\r
51750 return item;\r
51751 }\r
51752 }\r
51753 return false;\r
51754 },\r
51755 destroy: function() {\r
51756 var me = this,\r
51757 modal = me.getModal();\r
51758 if (modal) {\r
51759 modal.destroy();\r
51760 }\r
51761 me.removeAll(true, true);\r
51762 me.callParent();\r
51763 Ext.destroy(me.items);\r
51764 me.items = null;\r
51765 },\r
51766 privates: {\r
51767 applyReference: function(reference) {\r
51768
51769 return this.setupReference(reference);\r
51770 },\r
51771 \r
51772 getFirstReferences: function() {\r
51773 var me = this;\r
51774 delete me.getReferences;\r
51775 me.getItems();\r
51776
51777 return me.getReferences.apply(me, arguments);\r
51778 }\r
51779 }\r
51780}, function() {\r
51781 this.prototype.defaultItemClass = this;\r
51782});\r
51783\r
51784\r
51785Ext.define('Ext.LoadMask', {\r
51786 extend: Ext.Mask,\r
51787 xtype: 'loadmask',\r
51788 config: {\r
51789 \r
51790 message: 'Loading...',\r
51791 \r
51792 cls: Ext.baseCSSPrefix + 'loading-mask',\r
51793 \r
51794 messageCls: Ext.baseCSSPrefix + 'mask-message',\r
51795 \r
51796 indicator: true\r
51797 },\r
51798 getTemplate: function() {\r
51799 var prefix = Ext.baseCSSPrefix;\r
51800 return [\r
51801 {\r
51802
51803 reference: 'innerElement',\r
51804 cls: prefix + 'mask-inner',\r
51805 children: [\r
51806
51807 {\r
51808 reference: 'indicatorElement',\r
51809 cls: prefix + 'loading-spinner-outer',\r
51810 children: [\r
51811 {\r
51812 cls: prefix + 'loading-spinner',\r
51813 children: [\r
51814 {\r
51815 tag: 'span',\r
51816 cls: prefix + 'loading-top'\r
51817 },\r
51818 {\r
51819 tag: 'span',\r
51820 cls: prefix + 'loading-right'\r
51821 },\r
51822 {\r
51823 tag: 'span',\r
51824 cls: prefix + 'loading-bottom'\r
51825 },\r
51826 {\r
51827 tag: 'span',\r
51828 cls: prefix + 'loading-left'\r
51829 }\r
51830 ]\r
51831 }\r
51832 ]\r
51833 },\r
51834
51835 {\r
51836 reference: 'messageElement'\r
51837 }\r
51838 ]\r
51839 }\r
51840 ];\r
51841 },\r
51842 \r
51843 updateMessage: function(newMessage) {\r
51844 var cls = Ext.baseCSSPrefix + 'has-message';\r
51845 if (newMessage) {\r
51846 this.addCls(cls);\r
51847 } else {\r
51848 this.removeCls(cls);\r
51849 }\r
51850 this.messageElement.setHtml(newMessage);\r
51851 },\r
51852 \r
51853 updateMessageCls: function(newMessageCls, oldMessageCls) {\r
51854 this.messageElement.replaceCls(oldMessageCls, newMessageCls);\r
51855 },\r
51856 \r
51857 updateIndicator: function(newIndicator) {\r
51858 this[newIndicator ? 'removeCls' : 'addCls'](Ext.baseCSSPrefix + 'indicator-hidden');\r
51859 }\r
51860});\r
51861\r
51862\r
51863Ext.define('Ext.viewport.Default', {\r
51864 extend: Ext.Container,\r
51865 xtype: 'viewport',\r
51866 PORTRAIT: 'portrait',\r
51867 LANDSCAPE: 'landscape',\r
51868 \r
51869 \r
51870 \r
51871 config: {\r
51872 \r
51873 autoMaximize: false,\r
51874 \r
51875 autoBlurInput: true,\r
51876 \r
51877 preventPanning: true,\r
51878 \r
51879 preventZooming: false,\r
51880 \r
51881 autoRender: true,\r
51882 \r
51883 layout: 'card',\r
51884 \r
51885 width: '100%',\r
51886 \r
51887 height: '100%',\r
51888 useBodyElement: true,\r
51889 \r
51890 menus: {}\r
51891 },\r
51892 \r
51893 isReady: false,\r
51894 isViewport: true,\r
51895 isMaximizing: false,\r
51896 id: 'ext-viewport',\r
51897 isInputRegex: /^(input|textarea|select|a)$/i,\r
51898 isInteractiveWebComponentRegEx: /^(audio|video)$/i,\r
51899 focusedElement: null,\r
51900 \r
51901 fullscreenItemCls: Ext.baseCSSPrefix + 'fullscreen',\r
51902 constructor: function(config) {\r
51903 var me = this,\r
51904 bind = Ext.Function.bind,\r
51905 Component = Ext.Component,\r
51906 DomScroller = Ext.scroll.DomScroller;\r
51907
51908
51909
51910 if (DomScroller.document) {\r
51911 DomScroller.document = DomScroller.document.destroy();\r
51912 }\r
51913 me.doPreventPanning = bind(me.doPreventPanning, me);\r
51914 me.doPreventZooming = bind(me.doPreventZooming, me);\r
51915 me.doBlurInput = bind(me.doBlurInput, me);\r
51916 me.maximizeOnEvents = [\r
51917 'ready',\r
51918 'orientationchange'\r
51919 ];\r
51920
51921 window.devicePixelRatio = window.devicePixelRatio || 1;\r
51922 me.callParent([\r
51923 config\r
51924 ]);\r
51925 me.orientation = me.determineOrientation();\r
51926 me.windowWidth = me.getWindowWidth();\r
51927 me.windowHeight = me.getWindowHeight();\r
51928 me.windowOuterHeight = me.getWindowOuterHeight();\r
51929 me.stretchHeights = me.stretchHeights || {};\r
51930
51931 if (!Ext.os.is.Android || Ext.browser.is.ChromeMobile) {\r
51932 if (me.supportsOrientation()) {\r
51933 me.addWindowListener('orientationchange', bind(me.onOrientationChange, me));\r
51934 } else {\r
51935 me.addWindowListener('resize', bind(me.onResize, me));\r
51936 }\r
51937 }\r
51938 document.addEventListener('focus', bind(me.onElementFocus, me), true);\r
51939 document.addEventListener('blur', bind(me.onElementBlur, me), true);\r
51940 Ext.onDocumentReady(me.onDomReady, me);\r
51941 if (!Component.on) {\r
51942 Ext.util.Observable.observe(Component);\r
51943 }\r
51944 Component.on('fullscreen', 'onItemFullscreenChange', me);\r
51945 return me;\r
51946 },\r
51947 initialize: function() {\r
51948 var me = this;\r
51949 me.addMeta('apple-mobile-web-app-capable', 'yes');\r
51950 me.addMeta('apple-touch-fullscreen', 'yes');\r
51951 me.callParent();\r
51952 },\r
51953 initInheritedState: function(inheritedState, inheritedStateInner) {\r
51954 var me = this,\r
51955 root = Ext.rootInheritedState;\r
51956 if (inheritedState !== root) {\r
51957
51958
51959 me.initInheritedState(me.inheritedState = root, me.inheritedStateInner = Ext.Object.chain(root));\r
51960 } else {\r
51961 me.callParent([\r
51962 inheritedState,\r
51963 inheritedStateInner\r
51964 ]);\r
51965 }\r
51966 },\r
51967 onAppLaunch: function() {\r
51968 var me = this;\r
51969 if (!me.isReady) {\r
51970 me.onDomReady();\r
51971 }\r
51972 },\r
51973 onDomReady: function() {\r
51974 var me = this;\r
51975 if (me.isReady) {\r
51976 return;\r
51977 }\r
51978 me.isReady = true;\r
51979 me.updateSize();\r
51980 me.onReady();\r
51981 me.fireEvent('ready', me);\r
51982 Ext.GlobalEvents.fireEvent('viewportready', me);\r
51983 },\r
51984 onReady: function() {\r
51985 if (this.getAutoRender()) {\r
51986 this.render();\r
51987 }\r
51988 if (Ext.browser.name === 'ChromeiOS') {\r
51989 this.setHeight('-webkit-calc(100% - ' + ((window.outerHeight - window.innerHeight) / 2) + 'px)');\r
51990 }\r
51991 },\r
51992 onElementFocus: function(e) {\r
51993 this.focusedElement = e.target;\r
51994 },\r
51995 onElementBlur: function() {\r
51996 this.focusedElement = null;\r
51997 },\r
51998 render: function() {\r
51999 if (!this.rendered) {\r
52000 var body = Ext.getBody(),\r
52001 clsPrefix = Ext.baseCSSPrefix,\r
52002 classList = [],\r
52003 osEnv = Ext.os,\r
52004 osName = osEnv.name.toLowerCase(),\r
52005 browserName = Ext.browser.name.toLowerCase(),\r
52006 osMajorVersion = osEnv.version.getMajor(),\r
52007 orientation = this.getOrientation(),\r
52008 theme;\r
52009 this.renderTo(body);\r
52010 classList.push(clsPrefix + osEnv.deviceType.toLowerCase());\r
52011 if (osEnv.is.iPad) {\r
52012 classList.push(clsPrefix + 'ipad');\r
52013 }\r
52014 classList.push(clsPrefix + osName);\r
52015 classList.push(clsPrefix + browserName);\r
52016 if (osMajorVersion) {\r
52017 classList.push(clsPrefix + osName + '-' + osMajorVersion);\r
52018 }\r
52019 if (osEnv.is.BlackBerry) {\r
52020 classList.push(clsPrefix + 'bb');\r
52021 if (Ext.browser.userAgent.match(/Kbd/gi)) {\r
52022 classList.push(clsPrefix + 'bb-keyboard');\r
52023 }\r
52024 }\r
52025 if (Ext.browser.is.WebKit) {\r
52026 classList.push(clsPrefix + 'webkit');\r
52027 }\r
52028 if (Ext.browser.is.Standalone) {\r
52029 classList.push(clsPrefix + 'standalone');\r
52030 }\r
52031 if (Ext.browser.is.AndroidStock) {\r
52032 classList.push(clsPrefix + 'android-stock');\r
52033 }\r
52034 if (Ext.browser.is.GoogleGlass) {\r
52035 classList.push(clsPrefix + 'google-glass');\r
52036 }\r
52037 classList.push(clsPrefix + orientation);\r
52038 body.addCls(classList);\r
52039 theme = Ext.theme;\r
52040 if (theme && theme.getDocCls) {\r
52041
52042 Ext.fly(document.documentElement).addCls(theme.getDocCls());\r
52043 }\r
52044 }\r
52045 },\r
52046 updateAutoBlurInput: function(autoBlurInput) {\r
52047 var touchstart = Ext.feature.has.TouchEvents ? 'touchstart' : 'mousedown';\r
52048 this.toggleWindowListener(autoBlurInput, touchstart, this.doBlurInput, false);\r
52049 },\r
52050 applyAutoMaximize: function(autoMaximize) {\r
52051 return Ext.browser.is.WebView ? false : autoMaximize;\r
52052 },\r
52053 updateAutoMaximize: function(autoMaximize) {\r
52054 var me = this;\r
52055 if (autoMaximize) {\r
52056 me.on('ready', 'doAutoMaximizeOnReady', me, {\r
52057 single: true\r
52058 });\r
52059 me.on('orientationchange', 'doAutoMaximizeOnOrientationChange', me);\r
52060 } else {\r
52061 me.un('ready', 'doAutoMaximizeOnReady', me);\r
52062 me.un('orientationchange', 'doAutoMaximizeOnOrientationChange', me);\r
52063 }\r
52064 },\r
52065 updatePreventPanning: function(preventPanning) {\r
52066 this.toggleWindowListener(preventPanning, 'touchmove', this.doPreventPanning, false);\r
52067 },\r
52068 updatePreventZooming: function(preventZooming) {\r
52069 var touchstart = Ext.feature.has.TouchEvents ? 'touchstart' : 'mousedown';\r
52070 this.toggleWindowListener(preventZooming, touchstart, this.doPreventZooming, false);\r
52071 },\r
52072 doAutoMaximizeOnReady: function() {\r
52073 var me = this;\r
52074 me.isMaximizing = true;\r
52075 me.on('maximize', function() {\r
52076 me.isMaximizing = false;\r
52077 me.updateSize();\r
52078 me.fireEvent('ready', me);\r
52079 }, me, {\r
52080 single: true\r
52081 });\r
52082 me.maximize();\r
52083 },\r
52084 doAutoMaximizeOnOrientationChange: function() {\r
52085 var me = this;\r
52086 me.isMaximizing = true;\r
52087 me.on('maximize', function() {\r
52088 me.isMaximizing = false;\r
52089 me.updateSize();\r
52090 }, me, {\r
52091 single: true\r
52092 });\r
52093 me.maximize();\r
52094 },\r
52095 doBlurInput: function(e) {\r
52096 var target = e.target,\r
52097 focusedElement = this.focusedElement;\r
52098
52099
52100 if (focusedElement && focusedElement.blur && focusedElement.nodeName.toUpperCase() != 'BODY' && !this.isInputRegex.test(target.tagName)) {\r
52101 delete this.focusedElement;\r
52102 focusedElement.blur();\r
52103 }\r
52104 },\r
52105 doPreventPanning: function(e) {\r
52106 var target = e.target,\r
52107 touch;\r
52108
52109
52110
52111
52112 if (this.isInteractiveWebComponentRegEx.test(target.tagName) && e.touches && e.touches.length > 0) {\r
52113 touch = e.touches[0];\r
52114 if (touch && touch.target && this.isInputRegex.test(touch.target.tagName)) {\r
52115 return;\r
52116 }\r
52117 }\r
52118 if (target && target.nodeType === 1 && !this.isInputRegex.test(target.tagName)) {\r
52119 e.preventDefault();\r
52120 }\r
52121 },\r
52122 doPreventZooming: function(e) {\r
52123
52124 if ('button' in e && e.button !== 0) {\r
52125 return;\r
52126 }\r
52127 var target = e.target,\r
52128 inputRe = this.isInputRegex,\r
52129 touch;\r
52130 if (this.isInteractiveWebComponentRegEx.test(target.tagName) && e.touches && e.touches.length > 0) {\r
52131 touch = e.touches[0];\r
52132 if (touch && touch.target && inputRe.test(touch.target.tagName)) {\r
52133 return;\r
52134 }\r
52135 }\r
52136 if (target && target.nodeType === 1 && !inputRe.test(target.tagName)) {\r
52137 e.preventDefault();\r
52138 }\r
52139 },\r
52140 addWindowListener: function(eventName, fn, capturing) {\r
52141 window.addEventListener(eventName, fn, Boolean(capturing));\r
52142 },\r
52143 removeWindowListener: function(eventName, fn, capturing) {\r
52144 window.removeEventListener(eventName, fn, Boolean(capturing));\r
52145 },\r
52146 supportsOrientation: function() {\r
52147 return Ext.feature.has.Orientation;\r
52148 },\r
52149 onResize: function() {\r
52150 var me = this,\r
52151 oldWidth = me.windowWidth,\r
52152 oldHeight = me.windowHeight,\r
52153 width = me.getWindowWidth(),\r
52154 height = me.getWindowHeight(),\r
52155 currentOrientation = me.getOrientation(),\r
52156 newOrientation = me.determineOrientation();\r
52157
52158
52159 if ((oldWidth !== width && oldHeight !== height) && currentOrientation !== newOrientation) {\r
52160 me.fireOrientationChangeEvent(newOrientation, currentOrientation);\r
52161 }\r
52162 },\r
52163 onOrientationChange: function() {\r
52164 var currentOrientation = this.getOrientation(),\r
52165 newOrientation = this.determineOrientation();\r
52166 if (newOrientation !== currentOrientation) {\r
52167 this.fireOrientationChangeEvent(newOrientation, currentOrientation);\r
52168 }\r
52169 },\r
52170 fireOrientationChangeEvent: function(newOrientation, oldOrientation) {\r
52171 var me = this,\r
52172 clsPrefix = Ext.baseCSSPrefix;\r
52173 Ext.getBody().replaceCls(clsPrefix + oldOrientation, clsPrefix + newOrientation);\r
52174 me.orientation = newOrientation;\r
52175 me.updateSize();\r
52176 me.fireEvent('orientationchange', me, newOrientation, me.windowWidth, me.windowHeight);\r
52177 },\r
52178 updateSize: function(width, height) {\r
52179 var me = this;\r
52180 me.windowWidth = width !== undefined ? width : me.getWindowWidth();\r
52181 me.windowHeight = height !== undefined ? height : me.getWindowHeight();\r
52182 return me;\r
52183 },\r
52184 waitUntil: function(condition, onSatisfied, onTimeout, delay, timeoutDuration) {\r
52185 if (!delay) {\r
52186 delay = 50;\r
52187 }\r
52188 if (!timeoutDuration) {\r
52189 timeoutDuration = 2000;\r
52190 }\r
52191 var scope = this,\r
52192 elapse = 0;\r
52193 Ext.defer(function repeat() {\r
52194 elapse += delay;\r
52195 if (condition.call(scope) === true) {\r
52196 if (onSatisfied) {\r
52197 onSatisfied.call(scope);\r
52198 }\r
52199 } else {\r
52200 if (elapse >= timeoutDuration) {\r
52201 if (onTimeout) {\r
52202 onTimeout.call(scope);\r
52203 }\r
52204 } else {\r
52205 Ext.defer(repeat, delay);\r
52206 }\r
52207 }\r
52208 }, delay);\r
52209 },\r
52210 maximize: function() {\r
52211 this.fireMaximizeEvent();\r
52212 },\r
52213 fireMaximizeEvent: function() {\r
52214 this.updateSize();\r
52215 this.fireEvent('maximize', this);\r
52216 },\r
52217 updateHeight: function(height, oldHeight) {\r
52218 Ext.getBody().setHeight(height);\r
52219 this.callParent([\r
52220 height,\r
52221 oldHeight\r
52222 ]);\r
52223 },\r
52224 updateWidth: function(width, oldWidth) {\r
52225 Ext.getBody().setWidth(width);\r
52226 this.callParent([\r
52227 width,\r
52228 oldWidth\r
52229 ]);\r
52230 },\r
52231 scrollToTop: function() {\r
52232 window.scrollTo(0, -1);\r
52233 },\r
52234 \r
52235 getWindowWidth: function() {\r
52236 return window.innerWidth;\r
52237 },\r
52238 \r
52239 getWindowHeight: function() {\r
52240 return window.innerHeight;\r
52241 },\r
52242 getWindowOuterHeight: function() {\r
52243 return window.outerHeight;\r
52244 },\r
52245 getWindowOrientation: function() {\r
52246 return window.orientation;\r
52247 },\r
52248 \r
52249 getOrientation: function() {\r
52250 return this.orientation;\r
52251 },\r
52252 getSize: function() {\r
52253 return {\r
52254 width: this.windowWidth,\r
52255 height: this.windowHeight\r
52256 };\r
52257 },\r
52258 determineOrientation: function() {\r
52259 var me = this,\r
52260 portrait = me.PORTRAIT,\r
52261 landscape = me.LANDSCAPE;\r
52262 if (!Ext.os.is.Android && me.supportsOrientation()) {\r
52263 if (me.getWindowOrientation() % 180 === 0) {\r
52264 return portrait;\r
52265 }\r
52266 return landscape;\r
52267 } else {\r
52268 if (me.getWindowHeight() >= me.getWindowWidth()) {\r
52269 return portrait;\r
52270 }\r
52271 return landscape;\r
52272 }\r
52273 },\r
52274 onItemFullscreenChange: function(item) {\r
52275 item.addCls(this.fullscreenItemCls);\r
52276 this.add(item);\r
52277 },\r
52278 \r
52279 setMenu: function(menu, config) {\r
52280 config = config || {};\r
52281 var me = this,\r
52282 side = config.side,\r
52283 menus;\r
52284
52285 if (Ext.os.is.iOS && !me.hasiOSOrientationFix) {\r
52286 me.hasiOSOrientationFix = true;\r
52287 me.on('orientationchange', function() {\r
52288 window.scrollTo(0, 0);\r
52289 }, me);\r
52290 }\r
52291
52292 if (!menu) {\r
52293 Ext.Logger.error("You must specify a side to dock the menu.");\r
52294 }\r
52295 if (!side) {\r
52296 Ext.Logger.error("You must specify a side to dock the menu.");\r
52297 }\r
52298 if ([\r
52299 'left',\r
52300 'right',\r
52301 'top',\r
52302 'bottom'\r
52303 ].indexOf(side) == -1) {\r
52304 Ext.Logger.error("You must specify a valid side (left, right, top or botom) to dock the menu.");\r
52305 }\r
52306
52307 menus = me.getMenus();\r
52308 if (!menus) {\r
52309 menus = {};\r
52310 }\r
52311 if (!me.addedSwipeListener) {\r
52312 me.attachSwipeListeners();\r
52313 me.addedSwipeListener = true;\r
52314 }\r
52315
52316
52317
52318 if (!menu.isComponent) {\r
52319 if (!menu.xclass && !menu.xtype) {\r
52320 menu = me.getMenuCfg(menu, side);\r
52321 }\r
52322 menu = Ext.create(menu);\r
52323 }\r
52324 menus[side] = menu;\r
52325 menu.$reveal = Boolean(config.reveal);\r
52326 menu.$cover = config.cover !== false && !menu.$reveal;\r
52327 menu.$side = side;\r
52328 me.fixMenuSize(menu, side);\r
52329 if (side == 'left') {\r
52330 menu.setLeft(0);\r
52331 menu.setRight(null);\r
52332 menu.setTop(0);\r
52333 menu.setBottom(0);\r
52334 } else if (side == 'right') {\r
52335 menu.setLeft(null);\r
52336 menu.setRight(0);\r
52337 menu.setTop(0);\r
52338 menu.setBottom(0);\r
52339 } else if (side == 'top') {\r
52340 menu.setLeft(0);\r
52341 menu.setRight(0);\r
52342 menu.setTop(0);\r
52343 menu.setBottom(null);\r
52344 } else if (side == 'bottom') {\r
52345 menu.setLeft(0);\r
52346 menu.setRight(0);\r
52347 menu.setTop(null);\r
52348 menu.setBottom(0);\r
52349 }\r
52350 me.setMenus(menus);\r
52351 return menu;\r
52352 },\r
52353 attachSwipeListeners: function() {\r
52354 var me = this;\r
52355 me.element.on({\r
52356 tap: me.onTap,\r
52357 swipestart: me.onSwipeStart,\r
52358 edgeswipestart: me.onEdgeSwipeStart,\r
52359 edgeswipe: me.onEdgeSwipe,\r
52360 edgeswipeend: me.onEdgeSwipeEnd,\r
52361 scope: me\r
52362 });\r
52363 },\r
52364 getMenuCfg: function(menu, side) {\r
52365 return Ext.apply({\r
52366 xtype: 'menu'\r
52367 }, menu);\r
52368 },\r
52369 \r
52370 removeMenu: function(side) {\r
52371 var menus = this.getMenus() || {},\r
52372 menu = menus[side];\r
52373 if (menu) {\r
52374 this.hideMenu(side);\r
52375 }\r
52376 delete menus[side];\r
52377 this.setMenus(menus);\r
52378 },\r
52379 \r
52380 fixMenuSize: function(menu, side) {\r
52381 if (side == 'top' || side == 'bottom') {\r
52382 menu.setWidth('100%');\r
52383 } else if (side == 'left' || side == 'right') {\r
52384 menu.setHeight('100%');\r
52385 }\r
52386 },\r
52387 \r
52388 showMenu: function(side) {\r
52389 var me = this,\r
52390 menus = me.getMenus(),\r
52391 menu = menus[side],\r
52392 before, after, viewportBefore, viewportAfter, size;\r
52393 if (!menu || menu.isAnimating) {\r
52394 return;\r
52395 }\r
52396 me.hideOtherMenus(side);\r
52397 before = {\r
52398 translateX: 0,\r
52399 translateY: 0\r
52400 };\r
52401 after = {\r
52402 translateX: 0,\r
52403 translateY: 0\r
52404 };\r
52405 viewportBefore = {\r
52406 translateX: 0,\r
52407 translateY: 0\r
52408 };\r
52409 viewportAfter = {\r
52410 translateX: 0,\r
52411 translateY: 0\r
52412 };\r
52413 if (menu.$reveal) {\r
52414 Ext.getBody().insertFirst(menu.element);\r
52415 } else {\r
52416 Ext.Viewport.add(menu);\r
52417 }\r
52418 menu.show();\r
52419 menu.addCls('x-' + side);\r
52420 size = (side == 'left' || side == 'right') ? menu.element.getWidth() : menu.element.getHeight();\r
52421 if (side == 'left') {\r
52422 before.translateX = -size;\r
52423 viewportAfter.translateX = size;\r
52424 } else if (side == 'right') {\r
52425 before.translateX = size;\r
52426 viewportAfter.translateX = -size;\r
52427 } else if (side == 'top') {\r
52428 before.translateY = -size;\r
52429 viewportAfter.translateY = size;\r
52430 } else if (side == 'bottom') {\r
52431 before.translateY = size;\r
52432 viewportAfter.translateY = -size;\r
52433 }\r
52434 if (menu.$reveal) {\r
52435 if (Ext.browser.getPreferredTranslationMethod() != 'scrollposition') {\r
52436 menu.translate(0, 0);\r
52437 }\r
52438 } else {\r
52439 menu.translate(before.translateX, before.translateY);\r
52440 }\r
52441 if (menu.$cover) {\r
52442 menu.getTranslatable().on('animationend', function() {\r
52443 menu.isAnimating = false;\r
52444 }, me, {\r
52445 single: true\r
52446 });\r
52447 menu.translate(after.translateX, after.translateY, {\r
52448 preserveEndState: true,\r
52449 duration: 200\r
52450 });\r
52451 } else {\r
52452 me.translate(viewportBefore.translateX, viewportBefore.translateY);\r
52453 me.getTranslatable().on('animationend', function() {\r
52454 menu.isAnimating = false;\r
52455 }, me, {\r
52456 single: true\r
52457 });\r
52458 me.translate(viewportAfter.translateX, viewportAfter.translateY, {\r
52459 preserveEndState: true,\r
52460 duration: 200\r
52461 });\r
52462 }\r
52463
52464 menu.isAnimating = true;\r
52465 },\r
52466 \r
52467 hideMenu: function(side, animate) {\r
52468 var me = this,\r
52469 menus = this.getMenus(),\r
52470 menu = menus[side],\r
52471 after, viewportAfter, size;\r
52472 animate = animate !== false;\r
52473 if (!menu || (menu.isHidden() || menu.isAnimating)) {\r
52474 return;\r
52475 }\r
52476 after = {\r
52477 translateX: 0,\r
52478 translateY: 0\r
52479 };\r
52480 viewportAfter = {\r
52481 translateX: 0,\r
52482 translateY: 0\r
52483 };\r
52484 size = (side == 'left' || side == 'right') ? menu.element.getWidth() : menu.element.getHeight();\r
52485 if (side == 'left') {\r
52486 after.translateX = -size;\r
52487 } else if (side == 'right') {\r
52488 after.translateX = size;\r
52489 } else if (side == 'top') {\r
52490 after.translateY = -size;\r
52491 } else if (side == 'bottom') {\r
52492 after.translateY = size;\r
52493 }\r
52494 if (menu.$cover) {\r
52495 if (animate) {\r
52496 menu.getTranslatable().on('animationend', function() {\r
52497 menu.isAnimating = false;\r
52498 menu.hide();\r
52499 }, me, {\r
52500 single: true\r
52501 });\r
52502 menu.translate(after.translateX, after.translateY, {\r
52503 preserveEndState: true,\r
52504 duration: 200\r
52505 });\r
52506 } else {\r
52507 menu.translate(after.translateX, after.translateY);\r
52508 menu.hide();\r
52509 }\r
52510 } else {\r
52511 if (animate) {\r
52512 me.getTranslatable().on('animationend', function() {\r
52513 menu.isAnimating = false;\r
52514 menu.hide();\r
52515 }, me, {\r
52516 single: true\r
52517 });\r
52518 me.translate(viewportAfter.translateX, viewportAfter.translateY, {\r
52519 preserveEndState: true,\r
52520 duration: 200\r
52521 });\r
52522 } else {\r
52523 me.translate(viewportAfter.translateX, viewportAfter.translateY);\r
52524 menu.hide();\r
52525 }\r
52526 }\r
52527 },\r
52528 \r
52529 hideAllMenus: function(animation) {\r
52530 var menus = this.getMenus(),\r
52531 side;\r
52532 for (side in menus) {\r
52533 this.hideMenu(side, animation);\r
52534 }\r
52535 },\r
52536 \r
52537 hideOtherMenus: function(side, animation) {\r
52538 var menus = this.getMenus(),\r
52539 menu;\r
52540 for (menu in menus) {\r
52541 if (side !== menu) {\r
52542 this.hideMenu(menu, animation);\r
52543 }\r
52544 }\r
52545 },\r
52546 \r
52547 toggleMenu: function(side) {\r
52548 var menus = this.getMenus(),\r
52549 menu;\r
52550 if (menus[side]) {\r
52551 menu = menus[side];\r
52552 if (menu.isHidden()) {\r
52553 this.showMenu(side);\r
52554 } else {\r
52555 this.hideMenu(side);\r
52556 }\r
52557 }\r
52558 },\r
52559 \r
52560 sideForDirection: function(direction) {\r
52561 if (direction === 'left') {\r
52562 return 'right';\r
52563 } else if (direction === 'right') {\r
52564 return 'left';\r
52565 } else if (direction == 'up') {\r
52566 return 'bottom';\r
52567 } else if (direction == 'down') {\r
52568 return 'top';\r
52569 }\r
52570 },\r
52571 \r
52572 sideForSwipeDirection: function(direction) {\r
52573 if (direction == 'up') {\r
52574 return 'top';\r
52575 } else if (direction == 'down') {\r
52576 return 'bottom';\r
52577 }\r
52578 return direction;\r
52579 },\r
52580 \r
52581 onTap: function(e) {},\r
52582
52583 \r
52584 onSwipeStart: function(e) {\r
52585 var side = this.sideForSwipeDirection(e.direction);\r
52586 this.hideMenu(side);\r
52587 },\r
52588 \r
52589 onEdgeSwipeStart: function(e) {\r
52590 var me = this,\r
52591 side = me.sideForDirection(e.direction),\r
52592 menus = me.getMenus(),\r
52593 menu = menus[side],\r
52594 menuSide, checkMenu, size, after, viewportAfter, transformStyleName, setTransform;\r
52595 if (!menu || !menu.isHidden()) {\r
52596 return;\r
52597 }\r
52598 for (menuSide in menus) {\r
52599 checkMenu = menus[menuSide];\r
52600 if (checkMenu.isHidden() !== false) {\r
52601 return;\r
52602 }\r
52603 }\r
52604 me.$swiping = true;\r
52605 me.hideAllMenus(false);\r
52606
52607 if (menu.$reveal) {\r
52608 Ext.getBody().insertFirst(menu.element);\r
52609 } else {\r
52610 Ext.Viewport.add(menu);\r
52611 }\r
52612 menu.show();\r
52613 size = (side == 'left' || side == 'right') ? menu.element.getWidth() : menu.element.getHeight();\r
52614 after = {\r
52615 translateX: 0,\r
52616 translateY: 0\r
52617 };\r
52618 viewportAfter = {\r
52619 translateX: 0,\r
52620 translateY: 0\r
52621 };\r
52622 if (side == 'left') {\r
52623 after.translateX = -size;\r
52624 } else if (side == 'right') {\r
52625 after.translateX = size;\r
52626 } else if (side == 'top') {\r
52627 after.translateY = -size;\r
52628 } else if (side == 'bottom') {\r
52629 after.translateY = size;\r
52630 }\r
52631 transformStyleName = 'webkitTransform' in document.createElement('div').style ? 'webkitTransform' : 'transform';\r
52632 setTransform = menu.element.dom.style[transformStyleName];\r
52633 if (setTransform) {\r
52634 menu.element.dom.style[transformStyleName] = '';\r
52635 }\r
52636 if (menu.$reveal) {\r
52637 if (Ext.browser.getPreferredTranslationMethod() != 'scrollposition') {\r
52638 menu.translate(0, 0);\r
52639 }\r
52640 } else {\r
52641 menu.translate(after.translateX, after.translateY);\r
52642 }\r
52643 if (!menu.$cover) {\r
52644 if (setTransform) {\r
52645 me.innerElement.dom.style[transformStyleName] = '';\r
52646 }\r
52647 me.translate(viewportAfter.translateX, viewportAfter.translateY);\r
52648 }\r
52649 },\r
52650 \r
52651 onEdgeSwipe: function(e) {\r
52652 var me = this,\r
52653 side = me.sideForDirection(e.direction),\r
52654 menu = me.getMenus()[side],\r
52655 size, after, viewportAfter, movement, viewportMovement;\r
52656 if (!menu || !me.$swiping) {\r
52657 return;\r
52658 }\r
52659 size = (side == 'left' || side == 'right') ? menu.element.getWidth() : menu.element.getHeight();\r
52660 movement = Math.min(e.distance - size, 0);\r
52661 viewportMovement = Math.min(e.distance, size);\r
52662 after = {\r
52663 translateX: 0,\r
52664 translateY: 0\r
52665 };\r
52666 viewportAfter = {\r
52667 translateX: 0,\r
52668 translateY: 0\r
52669 };\r
52670 if (side == 'left') {\r
52671 after.translateX = movement;\r
52672 viewportAfter.translateX = viewportMovement;\r
52673 } else if (side == 'right') {\r
52674 after.translateX = -movement;\r
52675 viewportAfter.translateX = -viewportMovement;\r
52676 } else if (side == 'top') {\r
52677 after.translateY = movement;\r
52678 viewportAfter.translateY = viewportMovement;\r
52679 } else if (side == 'bottom') {\r
52680 after.translateY = -movement;\r
52681 viewportAfter.translateY = -viewportMovement;\r
52682 }\r
52683 if (menu.$cover) {\r
52684 menu.translate(after.translateX, after.translateY);\r
52685 } else {\r
52686 me.translate(viewportAfter.translateX, viewportAfter.translateY);\r
52687 }\r
52688 },\r
52689 \r
52690 onEdgeSwipeEnd: function(e) {\r
52691 var me = this,\r
52692 side = me.sideForDirection(e.direction),\r
52693 menu = me.getMenus()[side],\r
52694 shouldRevert = false,\r
52695 size, velocity, movement, viewportMovement, after, viewportAfter;\r
52696 if (!menu) {\r
52697 return;\r
52698 }\r
52699 size = (side == 'left' || side == 'right') ? menu.element.getWidth() : menu.element.getHeight();\r
52700 velocity = (e.flick) ? e.flick.velocity : 0;\r
52701
52702 if (side == 'right') {\r
52703 if (velocity.x > 0) {\r
52704 shouldRevert = true;\r
52705 }\r
52706 } else if (side == 'left') {\r
52707 if (velocity.x < 0) {\r
52708 shouldRevert = true;\r
52709 }\r
52710 } else if (side == 'top') {\r
52711 if (velocity.y < 0) {\r
52712 shouldRevert = true;\r
52713 }\r
52714 } else if (side == 'bottom') {\r
52715 if (velocity.y > 0) {\r
52716 shouldRevert = true;\r
52717 }\r
52718 }\r
52719 movement = shouldRevert ? size : 0;\r
52720 viewportMovement = shouldRevert ? 0 : -size;\r
52721 after = {\r
52722 translateX: 0,\r
52723 translateY: 0\r
52724 };\r
52725 viewportAfter = {\r
52726 translateX: 0,\r
52727 translateY: 0\r
52728 };\r
52729 if (side == 'left') {\r
52730 after.translateX = -movement;\r
52731 viewportAfter.translateX = -viewportMovement;\r
52732 } else if (side == 'right') {\r
52733 after.translateX = movement;\r
52734 viewportAfter.translateX = viewportMovement;\r
52735 } else if (side == 'top') {\r
52736 after.translateY = -movement;\r
52737 viewportAfter.translateY = -viewportMovement;\r
52738 } else if (side == 'bottom') {\r
52739 after.translateY = movement;\r
52740 viewportAfter.translateY = viewportMovement;\r
52741 }\r
52742
52743 if (menu.$cover) {\r
52744 menu.getTranslatable().on('animationend', function() {\r
52745 if (shouldRevert) {\r
52746 menu.hide();\r
52747 }\r
52748 }, me, {\r
52749 single: true\r
52750 });\r
52751 menu.translate(after.translateX, after.translateY, {\r
52752 preserveEndState: true,\r
52753 duration: 200\r
52754 });\r
52755 } else {\r
52756 me.getTranslatable().on('animationend', function() {\r
52757 if (shouldRevert) {\r
52758 menu.hide();\r
52759 }\r
52760 }, me, {\r
52761 single: true\r
52762 });\r
52763 me.translate(viewportAfter.translateX, viewportAfter.translateY, {\r
52764 preserveEndState: true,\r
52765 duration: 200\r
52766 });\r
52767 }\r
52768 me.$swiping = false;\r
52769 },\r
52770 privates: {\r
52771 addMeta: function(name, content) {\r
52772 var meta = document.createElement('meta');\r
52773 meta.setAttribute('name', name);\r
52774 meta.setAttribute('content', content);\r
52775 Ext.getHead().append(meta);\r
52776 },\r
52777 doAddListener: function(eventName, fn, scope, options, order, caller, manager) {\r
52778 var me = this;\r
52779 if (eventName === 'ready' && me.isReady && !me.isMaximizing) {\r
52780 fn.call(scope);\r
52781 return me;\r
52782 }\r
52783 me.callParent([\r
52784 eventName,\r
52785 fn,\r
52786 scope,\r
52787 options,\r
52788 order,\r
52789 caller,\r
52790 manager\r
52791 ]);\r
52792 },\r
52793 toggleWindowListener: function(on, eventName, fn, capturing) {\r
52794 if (on) {\r
52795 this.addWindowListener(eventName, fn, capturing);\r
52796 } else {\r
52797 this.removeWindowListener(eventName, fn, capturing);\r
52798 }\r
52799 }\r
52800 }\r
52801});\r
52802\r
52803\r
52804Ext.define('Ext.viewport.Ios', {\r
52805 extend: Ext.viewport.Default,\r
52806 isFullscreen: function() {\r
52807 return this.isHomeScreen();\r
52808 },\r
52809 isHomeScreen: function() {\r
52810 return window.navigator.standalone === true;\r
52811 },\r
52812 constructor: function() {\r
52813 this.callParent(arguments);\r
52814 if (this.getAutoMaximize() && !this.isFullscreen()) {\r
52815 this.addWindowListener('touchstart', Ext.Function.bind(this.onTouchStart, this));\r
52816 }\r
52817 },\r
52818 maximize: function() {\r
52819 if (this.isFullscreen()) {\r
52820 return this.callParent();\r
52821 }\r
52822 var stretchHeights = this.stretchHeights,\r
52823 orientation = this.orientation,\r
52824 currentHeight = this.getWindowHeight(),\r
52825 height = stretchHeights[orientation];\r
52826 if (window.scrollY > 0) {\r
52827 this.scrollToTop();\r
52828 if (!height) {\r
52829 stretchHeights[orientation] = height = this.getWindowHeight();\r
52830 }\r
52831 this.setHeight(height);\r
52832 this.fireMaximizeEvent();\r
52833 } else {\r
52834 if (!height) {\r
52835 height = this.getScreenHeight();\r
52836 }\r
52837 this.setHeight(height);\r
52838 this.waitUntil(function() {\r
52839 this.scrollToTop();\r
52840 return currentHeight !== this.getWindowHeight();\r
52841 }, function() {\r
52842 if (!stretchHeights[orientation]) {\r
52843 height = stretchHeights[orientation] = this.getWindowHeight();\r
52844 this.setHeight(height);\r
52845 }\r
52846 this.fireMaximizeEvent();\r
52847 }, function() {\r
52848
52849 Ext.Logger.error("Timeout waiting for window.innerHeight to change", this);\r
52850
52851 height = stretchHeights[orientation] = this.getWindowHeight();\r
52852 this.setHeight(height);\r
52853 this.fireMaximizeEvent();\r
52854 }, 50, 1000);\r
52855 }\r
52856 },\r
52857 getScreenHeight: function() {\r
52858 return window.screen[this.orientation === this.PORTRAIT ? 'height' : 'width'];\r
52859 },\r
52860 onElementFocus: function() {\r
52861 if (this.getAutoMaximize() && !this.isFullscreen()) {\r
52862 clearTimeout(this.scrollToTopTimer);\r
52863 }\r
52864 this.callParent(arguments);\r
52865 },\r
52866 onElementBlur: function() {\r
52867 if (this.getAutoMaximize() && !this.isFullscreen()) {\r
52868 this.scrollToTopTimer = Ext.defer(this.scrollToTop, 500);\r
52869 }\r
52870 this.callParent(arguments);\r
52871 },\r
52872 onTouchStart: function() {\r
52873 if (this.focusedElement === null) {\r
52874 this.scrollToTop();\r
52875 }\r
52876 },\r
52877 scrollToTop: function() {\r
52878 window.scrollTo(0, 0);\r
52879 }\r
52880}, function() {\r
52881 if (!Ext.os.is.iOS) {\r
52882 return;\r
52883 }\r
52884 if (Ext.os.version.lt('3.2')) {\r
52885 this.override({\r
52886 constructor: function() {\r
52887 var stretchHeights = this.stretchHeights = {};\r
52888 stretchHeights[this.PORTRAIT] = 416;\r
52889 stretchHeights[this.LANDSCAPE] = 268;\r
52890 return this.callOverridden(arguments);\r
52891 }\r
52892 });\r
52893 }\r
52894 if (Ext.os.version.lt('5')) {\r
52895 this.override({\r
52896 fieldMaskClsTest: '-field-mask',\r
52897 doPreventZooming: function(e) {\r
52898 var target = e.target;\r
52899 if (target && target.nodeType === 1 && !this.isInputRegex.test(target.tagName) && target.className.indexOf(this.fieldMaskClsTest) == -1) {\r
52900 e.preventDefault();\r
52901 }\r
52902 }\r
52903 });\r
52904 }\r
52905 if (Ext.os.is.iPad) {\r
52906 this.override({\r
52907 isFullscreen: function() {\r
52908 return true;\r
52909 }\r
52910 });\r
52911 }\r
52912 if (Ext.os.version.gtEq('7')) {\r
52913
52914 if (Ext.os.deviceType === 'Tablet' || !Ext.browser.is.Safari || window.navigator.standalone) {\r
52915 this.override({\r
52916 constructor: function() {\r
52917 var stretchHeights = {},\r
52918 stretchWidths = {},\r
52919 orientation = this.determineOrientation(),\r
52920 screenHeight = window.screen.height,\r
52921 screenWidth = window.screen.width,\r
52922 menuHeight = orientation === this.PORTRAIT ? screenHeight - window.innerHeight : screenWidth - window.innerHeight;\r
52923 stretchHeights[this.PORTRAIT] = screenHeight - menuHeight;\r
52924 stretchHeights[this.LANDSCAPE] = screenWidth - menuHeight;\r
52925 stretchWidths[this.PORTRAIT] = screenWidth;\r
52926 stretchWidths[this.LANDSCAPE] = screenHeight;\r
52927 this.stretchHeights = stretchHeights;\r
52928 this.stretchWidths = stretchWidths;\r
52929 this.callOverridden(arguments);\r
52930 this.on('ready', this.setViewportSizeToAbsolute, this);\r
52931 this.on('orientationchange', this.setViewportSizeToAbsolute, this);\r
52932 },\r
52933 getWindowHeight: function() {\r
52934 return this.stretchHeights[this.orientation];\r
52935 },\r
52936 getWindowWidth: function() {\r
52937 return this.stretchWidths[this.orientation];\r
52938 },\r
52939 setViewportSizeToAbsolute: function() {\r
52940 this.setWidth(this.getWindowWidth());\r
52941 this.setHeight(this.getWindowHeight());\r
52942 }\r
52943 });\r
52944 }\r
52945
52946 if (Ext.os.deviceType === 'Tablet') {\r
52947 this.override({\r
52948 constructor: function() {\r
52949 this.callOverridden(arguments);\r
52950 window.addEventListener('scroll', function() {\r
52951 if (window.scrollX !== 0) {\r
52952 window.scrollTo(0, window.scrollY);\r
52953 }\r
52954 }, false);\r
52955 },\r
52956 setViewportSizeToAbsolute: function() {\r
52957 window.scrollTo(0, 0);\r
52958 this.callOverridden(arguments);\r
52959 },\r
52960 onElementBlur: function() {\r
52961 this.callOverridden(arguments);\r
52962 if (window.scrollY !== 0) {\r
52963 window.scrollTo(0, 0);\r
52964 }\r
52965 }\r
52966 });\r
52967 }\r
52968 }\r
52969});\r
52970\r
52971\r
52972Ext.define('Ext.viewport.Android', {\r
52973 extend: Ext.viewport.Default,\r
52974 config: {\r
52975 translatable: {\r
52976 translationMethod: 'csstransform'\r
52977 }\r
52978 },\r
52979 constructor: function() {\r
52980 this.callParent(arguments);\r
52981 this.on({\r
52982 orientationchange: 'hideKeyboardIfNeeded',\r
52983 scope: this,\r
52984
52985 priority: 1001\r
52986 });\r
52987
52988
52989 var me = this;\r
52990 Ext.onReady(function() {\r
52991 Ext.getBody().on('resize', me.onResize, me);\r
52992 });\r
52993 },\r
52994 getWindowWidth: function() {\r
52995 return this.element.getWidth();\r
52996 },\r
52997 getWindowHeight: function() {\r
52998 return this.element.getHeight();\r
52999 },\r
53000 getDummyInput: function() {\r
53001 var input = this.dummyInput,\r
53002 focusedElement = this.focusedElement,\r
53003 box = Ext.fly(focusedElement).getBox();\r
53004 if (!input) {\r
53005 this.dummyInput = input = document.createElement('input');\r
53006 input.style.position = 'absolute';\r
53007 input.style.opacity = '0';\r
53008 input.style.pointerEvents = 'none';\r
53009 document.body.appendChild(input);\r
53010 }\r
53011 input.style.left = box.left + 'px';\r
53012 input.style.top = box.top + 'px';\r
53013 input.style.display = '';\r
53014 return input;\r
53015 },\r
53016 doBlurInput: function(e) {\r
53017 var target = e.target,\r
53018 focusedElement = this.focusedElement,\r
53019 dummy;\r
53020 if (focusedElement && !this.isInputRegex.test(target.tagName)) {\r
53021 dummy = this.getDummyInput();\r
53022 delete this.focusedElement;\r
53023 dummy.focus();\r
53024 Ext.defer(function() {\r
53025 dummy.style.display = 'none';\r
53026 }, 100);\r
53027 }\r
53028 },\r
53029 hideKeyboardIfNeeded: function() {\r
53030 var focusedElement = this.focusedElement;\r
53031 if (focusedElement) {\r
53032 delete this.focusedElement;\r
53033 if (Ext.os.version.lt('4')) {\r
53034 focusedElement.style.display = 'none';\r
53035 } else {\r
53036 focusedElement.blur();\r
53037 }\r
53038 Ext.defer(function() {\r
53039 focusedElement.style.display = '';\r
53040 }, 1000);\r
53041 }\r
53042 },\r
53043 doFireOrientationChangeEvent: function() {\r
53044 this.orientationChanging = true;\r
53045 this.waitUntil(function() {\r
53046 return this.getWindowOuterHeight() !== this.windowOuterHeight;\r
53047 }, function() {\r
53048 this.windowOuterHeight = this.getWindowOuterHeight();\r
53049 this.updateSize();\r
53050 this.orientationChanging = false;\r
53051 }, function() {\r
53052
53053 Ext.Logger.error("Timeout waiting for viewport's outerHeight to change before firing orientationchange", this);\r
53054 });\r
53055
53056 return this;\r
53057 },\r
53058 determineOrientation: function() {\r
53059 return (this.getWindowHeight() >= this.getWindowWidth()) ? this.PORTRAIT : this.LANDSCAPE;\r
53060 },\r
53061 getActualWindowOuterHeight: function() {\r
53062 return Math.round(this.getWindowOuterHeight() / window.devicePixelRatio);\r
53063 },\r
53064 maximize: function() {\r
53065 var stretchHeights = this.stretchHeights,\r
53066 orientation = this.orientation,\r
53067 height;\r
53068 height = stretchHeights[orientation];\r
53069 if (!height) {\r
53070 stretchHeights[orientation] = height = this.getActualWindowOuterHeight();\r
53071 }\r
53072 if (!this.addressBarHeight) {\r
53073 this.addressBarHeight = height - this.getWindowHeight();\r
53074 }\r
53075 this.setHeight(height);\r
53076 var isHeightMaximized = Ext.Function.bind(this.isHeightMaximized, this, [\r
53077 height\r
53078 ]);\r
53079 this.scrollToTop();\r
53080 this.waitUntil(isHeightMaximized, this.fireMaximizeEvent, this.fireMaximizeEvent);\r
53081 },\r
53082 isHeightMaximized: function(height) {\r
53083 this.scrollToTop();\r
53084 return this.getWindowHeight() === height;\r
53085 },\r
53086 supportsOrientation: function() {\r
53087 return false;\r
53088 },\r
53089 onResize: function() {\r
53090 this.waitUntil(function() {\r
53091 var oldWidth = this.windowWidth,\r
53092 oldHeight = this.windowHeight,\r
53093 width = this.getWindowWidth(),\r
53094 height = this.getWindowHeight(),\r
53095 currentOrientation = this.getOrientation(),\r
53096 newOrientation = this.determineOrientation();\r
53097 return ((oldWidth !== width && oldHeight !== height) && currentOrientation !== newOrientation);\r
53098 }, function() {\r
53099 var currentOrientation = this.getOrientation(),\r
53100 newOrientation = this.determineOrientation();\r
53101 this.fireOrientationChangeEvent(newOrientation, currentOrientation);\r
53102 }, Ext.emptyFn, 250);\r
53103 },\r
53104 doPreventZooming: function(e) {\r
53105
53106 if ('button' in e && e.button !== 0) {\r
53107 return;\r
53108 }\r
53109 var target = e.target;\r
53110 if (target && target.nodeType === 1 && !this.isInputRegex.test(target.tagName) && !this.focusedElement) {\r
53111 e.preventDefault();\r
53112 }\r
53113 }\r
53114}, function() {\r
53115 if (!Ext.os.is.Android) {\r
53116 return;\r
53117 }\r
53118 var version = Ext.os.version,\r
53119 userAgent = Ext.browser.userAgent,\r
53120
53121
53122 isBuggy = /(htc|desire|incredible|ADR6300)/i.test(userAgent) && version.lt('2.3');\r
53123 if (isBuggy) {\r
53124 this.override({\r
53125 constructor: function(config) {\r
53126 if (!config) {\r
53127 config = {};\r
53128 }\r
53129 config.autoMaximize = false;\r
53130 this.watchDogTick = Ext.Function.bind(this.watchDogTick, this);\r
53131 Ext.interval(this.watchDogTick, 1000);\r
53132 return this.callParent([\r
53133 config\r
53134 ]);\r
53135 },\r
53136 watchDogTick: function() {\r
53137 this.watchDogLastTick = Ext.Date.now();\r
53138 },\r
53139 doPreventPanning: function() {\r
53140 var now = Ext.Date.now(),\r
53141 lastTick = this.watchDogLastTick,\r
53142 deltaTime = now - lastTick;\r
53143
53144 if (deltaTime >= 2000) {\r
53145 return;\r
53146 }\r
53147 return this.callParent(arguments);\r
53148 },\r
53149 doPreventZooming: function() {\r
53150 var now = Ext.Date.now(),\r
53151 lastTick = this.watchDogLastTick,\r
53152 deltaTime = now - lastTick;\r
53153
53154 if (deltaTime >= 2000) {\r
53155 return;\r
53156 }\r
53157 return this.callParent(arguments);\r
53158 }\r
53159 });\r
53160 }\r
53161 if (version.match('2')) {\r
53162 this.override({\r
53163 onReady: function() {\r
53164 this.addWindowListener('resize', Ext.Function.bind(this.onWindowResize, this));\r
53165 this.callParent(arguments);\r
53166 },\r
53167 scrollToTop: function() {\r
53168 document.body.scrollTop = 100;\r
53169 },\r
53170 onWindowResize: function() {\r
53171 var oldWidth = this.windowWidth,\r
53172 oldHeight = this.windowHeight,\r
53173 width = this.getWindowWidth(),\r
53174 height = this.getWindowHeight();\r
53175 if (this.getAutoMaximize() && !this.isMaximizing && !this.orientationChanging && window.scrollY === 0 && oldWidth === width && height < oldHeight && ((height >= oldHeight - this.addressBarHeight) || !this.focusedElement)) {\r
53176 this.scrollToTop();\r
53177 }\r
53178 }\r
53179 });\r
53180 } else if (version.gtEq('3.1')) {\r
53181 this.override({\r
53182 isHeightMaximized: function(height) {\r
53183 this.scrollToTop();\r
53184 return this.getWindowHeight() === height - 1;\r
53185 }\r
53186 });\r
53187 } else if (version.match('3')) {\r
53188 this.override({\r
53189 isHeightMaximized: function() {\r
53190 this.scrollToTop();\r
53191 return true;\r
53192 }\r
53193 });\r
53194 }\r
53195 if (version.gtEq('4')) {\r
53196 this.override({\r
53197 doBlurInput: Ext.emptyFn\r
53198 });\r
53199 }\r
53200});\r
53201\r
53202\r
53203Ext.define('Ext.viewport.WindowsPhone', {\r
53204 requires: [],\r
53205 alternateClassName: 'Ext.viewport.WP',\r
53206 extend: Ext.viewport.Default,\r
53207
53208
53209
53210
53211
53212 config: {\r
53213 translatable: {\r
53214 translationMethod: 'csstransform'\r
53215 }\r
53216 },\r
53217 initialize: function() {\r
53218
53219 var preventSelection = function(e) {\r
53220 var srcElement = e.srcElement.nodeName.toUpperCase(),\r
53221 selectableElements = [\r
53222 'INPUT',\r
53223 'TEXTAREA'\r
53224 ];\r
53225 if (selectableElements.indexOf(srcElement) == -1) {\r
53226 return false;\r
53227 }\r
53228 };\r
53229 document.body.addEventListener('onselectstart', preventSelection);\r
53230 this.addMeta('msapplication-tap-highlight', 'no');\r
53231 this.callParent();\r
53232 },\r
53233 supportsOrientation: function() {\r
53234 return false;\r
53235 },\r
53236 onResize: function() {\r
53237 this.waitUntil(function() {\r
53238 var oldWidth = this.windowWidth,\r
53239 oldHeight = this.windowHeight,\r
53240 width = this.getWindowWidth(),\r
53241 height = this.getWindowHeight(),\r
53242 currentOrientation = this.getOrientation(),\r
53243 newOrientation = this.determineOrientation();\r
53244 return ((oldWidth !== width && oldHeight !== height) && currentOrientation !== newOrientation);\r
53245 }, function() {\r
53246 var currentOrientation = this.getOrientation(),\r
53247 newOrientation = this.determineOrientation();\r
53248 this.fireOrientationChangeEvent(newOrientation, currentOrientation);\r
53249 }, Ext.emptyFn, 250);\r
53250 }\r
53251});\r
53252\r
53253\r
53254Ext.define('Ext.viewport.Viewport', {\r
53255 singleton: true,\r
53256 setup: function(config) {\r
53257 var osName = Ext.os.name,\r
53258 viewportName;\r
53259 switch (osName) {\r
53260 case 'Android':\r
53261 viewportName = (Ext.browser.name === 'ChromeMobile') ? 'Default' : 'Android';\r
53262 break;\r
53263 case 'iOS':\r
53264 viewportName = 'Ios';\r
53265 break;\r
53266 case 'Windows':\r
53267 viewportName = (Ext.browser.name === 'IE') ? 'WindowsPhone' : 'Default';\r
53268 break;\r
53269 case 'WindowsPhone':\r
53270 viewportName = 'WindowsPhone';\r
53271 break;\r
53272 default:\r
53273 viewportName = 'Default';\r
53274 break;\r
53275 }\r
53276 Ext.Viewport = Ext.create('Ext.viewport.' + viewportName, config);\r
53277 }\r
53278});\r
53279
53280\r
53281\r
53282Ext.define('Ext.overrides.app.Application', {\r
53283 override: 'Ext.app.Application',\r
53284 initMainView: function() {\r
53285 var me = this,\r
53286 viewport, mainView;\r
53287 me.viewport = viewport = Ext.Viewport;\r
53288 me.callParent();\r
53289 mainView = me.getMainView();\r
53290
53291 viewport.onAppLaunch();\r
53292 if (mainView) {\r
53293 viewport.add(mainView);\r
53294 }\r
53295 }\r
53296});\r
53297\r
53298\r
53299Ext.define('Ext.app.Profile', {\r
53300 mixins: [\r
53301 Ext.mixin.Observable\r
53302 ],\r
53303 \r
53304 isProfile: true,\r
53305 \r
53306 \r
53307 config: {\r
53308 \r
53309 mainView: {\r
53310 $value: null,\r
53311 lazy: true\r
53312 },\r
53313 \r
53314 application: null,\r
53315
53316 \r
53317 controllers: [],\r
53318
53319 \r
53320 models: [],\r
53321
53322 \r
53323 views: [],\r
53324
53325 \r
53326 stores: []\r
53327 },\r
53328 \r
53329 constructor: function(config) {\r
53330 this.initConfig(config);\r
53331 this.mixins.observable.constructor.apply(this, arguments);\r
53332 },\r
53333 \r
53334 isActive: function() {\r
53335 return false;\r
53336 },\r
53337 \r
53338 init: function() {\r
53339 var views = this.getViews(),\r
53340 xtype;\r
53341 if (views && !(views instanceof Array)) {\r
53342 for (xtype in views) {\r
53343 Ext.ClassManager.setXType(views[xtype], xtype);\r
53344 }\r
53345 }\r
53346 },\r
53347 \r
53348 launch: Ext.emptyFn,\r
53349 onClassExtended: function(cls, data, hooks) {\r
53350 var onBeforeClassCreated = hooks.onBeforeCreated;\r
53351 hooks.onBeforeCreated = function(cls, data) {\r
53352 var Controller = Ext.app.Controller,\r
53353 className = cls.$className,\r
53354 requires = [],\r
53355 proto = cls.prototype,\r
53356 views = data.views,\r
53357 name, namespace;\r
53358
53359
53360 name = data.name;\r
53361 if (name) {\r
53362 delete data.name;\r
53363 } else {\r
53364 name = className.split('.');\r
53365 name = name[name.length - 1];\r
53366 }\r
53367 cls._name = name;\r
53368 cls._namespace = name = (data.namespace || name).toLowerCase();\r
53369 delete data.namespace;\r
53370 namespace = Controller.resolveNamespace(cls, data);\r
53371 Controller.processDependencies(proto, requires, namespace, 'model', data.models, name);\r
53372 Controller.processDependencies(proto, requires, namespace, 'store', data.stores, name);\r
53373 Controller.processDependencies(proto, requires, namespace, 'controller', data.controllers, name);\r
53374 if (views) {\r
53375 if (views instanceof Array) {\r
53376 Controller.processDependencies(proto, requires, namespace, 'view', views, name);\r
53377 } else {\r
53378 Ext.app.Profile.processViews(className, views, requires);\r
53379 }\r
53380 }\r
53381 Ext.require(requires, Ext.Function.pass(onBeforeClassCreated, arguments, this));\r
53382 };\r
53383 },\r
53384 getName: function() {\r
53385
53386
53387 return this.self._name;\r
53388 },\r
53389 getNamespace: function() {\r
53390
53391
53392 return this.self._namespace;\r
53393 },\r
53394 privates: {\r
53395 statics: {\r
53396 processViews: function(className, views, requires) {\r
53397 var body, cls, s, xtype;\r
53398 for (xtype in views) {\r
53399 cls = views[xtype];\r
53400 if (typeof cls !== 'string') {\r
53401 s = cls.xclass;\r
53402
53403 if (!s) {\r
53404 Ext.raise('Views must specify an xclass');\r
53405 }\r
53406
53407 body = Ext.apply({\r
53408 extend: s\r
53409 }, cls);\r
53410 delete body.xclass;\r
53411
53412 Ext.define(views[xtype] = className + '$' + xtype, body);\r
53413 cls = s;\r
53414 }\r
53415 requires.push(cls);\r
53416 }\r
53417 }\r
53418 }\r
53419 }\r
53420});\r
53421\r
53422\r
53423Ext.define('Ext.app.domain.View', {\r
53424 extend: Ext.app.EventDomain,\r
53425 isInstance: true,\r
53426 constructor: function(controller) {\r
53427 this.callParent(arguments);\r
53428 this.controller = controller;\r
53429 this.monitoredClasses = [\r
53430 Ext.Component\r
53431 ];\r
53432 },\r
53433 match: function(target, selector, controller) {\r
53434 var out = false;\r
53435 if (selector === '#') {\r
53436 out = controller === target.getController();\r
53437 } else {\r
53438 out = target.is(selector);\r
53439 }\r
53440 return out;\r
53441 },\r
53442 destroy: function() {\r
53443 this.controller = null;\r
53444 this.callParent();\r
53445 }\r
53446});\r
53447\r
53448\r
53449Ext.define('Ext.app.ViewController', {\r
53450 extend: Ext.app.BaseController,\r
53451 mixins: [\r
53452 Ext.mixin.Factoryable\r
53453 ],\r
53454 isViewController: true,\r
53455 factoryConfig: {\r
53456
53457 type: 'controller'\r
53458 },\r
53459 config: {\r
53460 closeViewAction: 'destroy'\r
53461 },\r
53462 view: null,\r
53463 constructor: function() {\r
53464 this.compDomain = new Ext.app.domain.View(this);\r
53465 this.callParent(arguments);\r
53466 },\r
53467 \r
53468 beforeInit: Ext.emptyFn,\r
53469 \r
53470 init: Ext.emptyFn,\r
53471 \r
53472 initViewModel: Ext.emptyFn,\r
53473 \r
53474 destroy: function() {\r
53475 var me = this,\r
53476 domain = me.compDomain;\r
53477 if (domain) {\r
53478 domain.unlisten(me);\r
53479 domain.destroy();\r
53480 }\r
53481 me.compDomain = me.view = null;\r
53482 me.callParent();\r
53483 },\r
53484 \r
53485 closeView: function() {\r
53486 var view = this.getView(),\r
53487 action;\r
53488 if (view) {\r
53489 action = this.getCloseViewAction();\r
53490 view[action]();\r
53491 }\r
53492 },\r
53493 control: function(selectors, listeners) {\r
53494 var obj = selectors;\r
53495 if (Ext.isString(selectors)) {\r
53496 obj = {};\r
53497 obj[selectors] = listeners;\r
53498 }\r
53499 this.compDomain.listen(obj, this);\r
53500 },\r
53501 listen: function(to, controller) {\r
53502 var component = to.component;\r
53503 if (component) {\r
53504 to = Ext.apply({}, to);\r
53505 delete to.component;\r
53506 this.control(component);\r
53507 }\r
53508 this.callParent([\r
53509 to,\r
53510 controller\r
53511 ]);\r
53512 },\r
53513 \r
53514 getReferences: function() {\r
53515 var view = this.view;\r
53516 return view && view.getReferences();\r
53517 },\r
53518 \r
53519 getView: function() {\r
53520 return this.view;\r
53521 },\r
53522 \r
53523 lookup: function(key) {\r
53524 var view = this.view;\r
53525 return view && view.lookup(key);\r
53526 },\r
53527 \r
53528 lookupReference: function(key) {\r
53529 return this.lookup(key);\r
53530 },\r
53531 \r
53532 getSession: function() {\r
53533 var view = this.view;\r
53534 return view && view.lookupSession();\r
53535 },\r
53536 \r
53537 getViewModel: function() {\r
53538 var view = this.view;\r
53539 return view && view.lookupViewModel();\r
53540 },\r
53541 \r
53542 getStore: function(name) {\r
53543 var viewModel = this.getViewModel();\r
53544 return viewModel ? viewModel.getStore(name) : null;\r
53545 },\r
53546 \r
53547 fireViewEvent: function(eventName, firstArg) {\r
53548 var view = this.view,\r
53549 result = false,\r
53550 args = arguments;\r
53551 if (view) {\r
53552 if (view !== firstArg) {\r
53553 args = Ext.Array.slice(args);\r
53554 args.splice(1, 0, view);\r
53555 }\r
53556 result = view.fireEvent.apply(view, args);\r
53557 }\r
53558 return result;\r
53559 },\r
53560
53561 privates: {\r
53562 view: null,\r
53563 ensureId: function() {\r
53564 var id = this.getId();\r
53565 if (!id) {\r
53566 this.setId(Ext.id(null, 'controller-'));\r
53567 }\r
53568 },\r
53569 \r
53570 attachReference: function(component) {\r
53571 var view = this.view;\r
53572 if (view) {\r
53573 view.attachReference(component);\r
53574 }\r
53575 },\r
53576 \r
53577 clearReference: function(ref) {\r
53578 var view = this.view;\r
53579 if (view) {\r
53580 view.clearReference(ref);\r
53581 }\r
53582 },\r
53583 \r
53584 clearReferences: function() {\r
53585 var view = this.view;\r
53586 if (view) {\r
53587 view.clearReferences();\r
53588 }\r
53589 },\r
53590 \r
53591 setView: function(view) {\r
53592 this.view = view;\r
53593 if (!this.beforeInit.$nullFn) {\r
53594 this.beforeInit(view);\r
53595 }\r
53596 }\r
53597 }\r
53598});\r
53599\r
53600\r
53601Ext.define('Ext.util.Bag', {\r
53602 isBag: true,\r
53603 constructor: function() {\r
53604 \r
53605 this.items = [];\r
53606 \r
53607 this.map = {};\r
53608 },\r
53609 \r
53610 generation: 0,\r
53611 \r
53612 length: 0,\r
53613 add: function(item) {\r
53614 var me = this,\r
53615 id = me.getKey(item),\r
53616 map = me.map,\r
53617 items = me.items,\r
53618 idx = map[id],\r
53619 old;\r
53620 if (idx === undefined) {\r
53621 items.push(item);\r
53622 map[id] = me.length++;\r
53623 old = item;\r
53624 } else {\r
53625 old = items[idx];\r
53626 items[idx] = item;\r
53627 }\r
53628 ++me.generation;\r
53629 return old;\r
53630 },\r
53631 clear: function() {\r
53632 var me = this,\r
53633 needsClear = me.generation || me.length,\r
53634 ret = needsClear ? me.items : [];\r
53635 if (needsClear) {\r
53636 me.items = [];\r
53637 me.length = 0;\r
53638 me.map = {};\r
53639 ++me.generation;\r
53640 }\r
53641 return ret;\r
53642 },\r
53643 clone: function() {\r
53644 var me = this,\r
53645 ret = new me.self(),\r
53646 len = me.length;\r
53647 if (len) {\r
53648 Ext.apply(ret.map, me.map);\r
53649 ret.items = me.items.slice();\r
53650 ret.length = me.length;\r
53651 }\r
53652 return ret;\r
53653 },\r
53654 contains: function(item) {\r
53655 var ret = false,\r
53656 map = this.map,\r
53657 key;\r
53658 if (item != null) {\r
53659 key = this.getKey(item);\r
53660 if (key in map) {\r
53661 ret = this.items[map[key]] === item;\r
53662 }\r
53663 }\r
53664 return ret;\r
53665 },\r
53666 containsKey: function(key) {\r
53667 return key in this.map;\r
53668 },\r
53669 destroy: function() {\r
53670 this.items = this.map = null;\r
53671 this.callParent();\r
53672 },\r
53673 getAt: function(index) {\r
53674 var out = null;\r
53675 if (index < this.length) {\r
53676 out = this.items[index];\r
53677 }\r
53678 return out;\r
53679 },\r
53680 getByKey: function(key) {\r
53681 var map = this.map,\r
53682 ret = null;\r
53683 if (key in map) {\r
53684 ret = this.items[map[key]];\r
53685 }\r
53686 return ret;\r
53687 },\r
53688 getCount: function() {\r
53689 return this.length;\r
53690 },\r
53691 getKey: function(item) {\r
53692 return item.id || item.getId();\r
53693 },\r
53694 remove: function(item) {\r
53695 var me = this,\r
53696 map = me.map,\r
53697 items = me.items,\r
53698 old = null,\r
53699 idx, id, last;\r
53700 if (me.length) {\r
53701 idx = map[id = me.getKey(item)];\r
53702 if (idx !== undefined) {\r
53703 delete map[id];\r
53704 old = items[idx];\r
53705 last = items.pop();\r
53706 if (idx < --me.length) {\r
53707 items[idx] = last;\r
53708 map[me.getKey(last)] = idx;\r
53709 }\r
53710 ++me.generation;\r
53711 }\r
53712 }\r
53713 return old;\r
53714 },\r
53715 removeByKey: function(key) {\r
53716 var item = this.getByKey(key);\r
53717 if (item) {\r
53718 this.remove(item);\r
53719 }\r
53720 return item || null;\r
53721 },\r
53722 sort: function(fn) {\r
53723 var me = this,\r
53724 items = me.items,\r
53725 n = items.length,\r
53726 item;\r
53727 if (n) {\r
53728 Ext.Array.sort(items, fn);\r
53729 me.map = {};\r
53730 while (n-- > 0) {\r
53731 item = items[n];\r
53732 me.map[me.getKey(item)] = n;\r
53733 }\r
53734 ++me.generation;\r
53735 }\r
53736 }\r
53737});\r
53738\r
53739\r
53740Ext.define('Ext.util.Scheduler', {\r
53741 mixins: [\r
53742 Ext.mixin.Observable\r
53743 ],\r
53744 busyCounter: 0,\r
53745 lastBusyCounter: 0,\r
53746 destroyed: false,\r
53747 firing: null,\r
53748 notifyIndex: -1,\r
53749 nextId: 0,\r
53750 orderedItems: null,\r
53751 passes: 0,\r
53752 scheduledCount: 0,\r
53753 validIdRe: null,\r
53754 config: {\r
53755 \r
53756 cycleLimit: 5,\r
53757 \r
53758 preSort: null,\r
53759 \r
53760 tickDelay: 5\r
53761 },\r
53762 \r
53763 suspendOnNotify: true,\r
53764 constructor: function(config) {\r
53765
53766 if (Ext.util.Scheduler.instances) {\r
53767 Ext.util.Scheduler.instances.push(this);\r
53768 } else {\r
53769 Ext.util.Scheduler.instances = [\r
53770 this\r
53771 ];\r
53772 }\r
53773 this.id = Ext.util.Scheduler.count = (Ext.util.Scheduler.count || 0) + 1;\r
53774
53775 this.mixins.observable.constructor.call(this, config);\r
53776 this.items = new Ext.util.Bag();\r
53777 },\r
53778 destroy: function() {\r
53779 var me = this,\r
53780 timer = me.timer;\r
53781 if (timer) {\r
53782 window.clearTimeout(timer);\r
53783 me.timer = null;\r
53784 }\r
53785 me.items.destroy();\r
53786 me.items = me.orderedItems = null;\r
53787 me.callParent();\r
53788
53789 Ext.Array.remove(Ext.util.Scheduler.instances, this);\r
53790 },\r
53791
53792 \r
53793 add: function(item) {\r
53794 var me = this,\r
53795 items = me.items;\r
53796 if (items === me.firing) {\r
53797 me.items = items = items.clone();\r
53798 }\r
53799 item.id = item.id || ++me.nextId;\r
53800 item.scheduler = me;\r
53801 items.add(item);\r
53802 if (!me.sortMap) {\r
53803
53804
53805 me.orderedItems = null;\r
53806 }\r
53807 },\r
53808 \r
53809 remove: function(item) {\r
53810 var me = this,\r
53811 items = me.items;\r
53812 if (me.destroyed) {\r
53813 return;\r
53814 }\r
53815
53816 if (me.sortMap) {\r
53817 Ext.raise('Items cannot be removed during sort');\r
53818 }\r
53819
53820 if (items === me.firing) {\r
53821 me.items = items = items.clone();\r
53822 }\r
53823 if (item.scheduled) {\r
53824 me.unscheduleItem(item);\r
53825 item.scheduled = false;\r
53826 }\r
53827 items.remove(item);\r
53828 me.orderedItems = null;\r
53829 },\r
53830 \r
53831 sort: function() {\r
53832 var me = this,\r
53833 items = me.items,\r
53834 sortMap = {},\r
53835 preSort = me.getPreSort(),\r
53836 i, item;\r
53837 me.orderedItems = [];\r
53838 me.sortMap = sortMap;\r
53839
53840 me.sortStack = [];\r
53841
53842 if (preSort) {\r
53843 items.sort(preSort);\r
53844 }\r
53845 items = items.items;\r
53846
53847
53848 for (i = 0; i < items.length; ++i) {\r
53849 item = items[i];\r
53850 if (!sortMap[item.id]) {\r
53851 me.sortItem(item);\r
53852 }\r
53853 }\r
53854 me.sortMap = null;\r
53855
53856 me.sortStack = null;\r
53857 },\r
53858
53859 \r
53860 sortItem: function(item) {\r
53861 var me = this,\r
53862 sortMap = me.sortMap,\r
53863 orderedItems = me.orderedItems,\r
53864 itemId;\r
53865 if (!item.scheduler) {\r
53866 me.add(item);\r
53867 }\r
53868 itemId = item.id;\r
53869
53870 if (item.scheduler !== me) {\r
53871 Ext.raise('Item ' + itemId + ' belongs to another Scheduler');\r
53872 }\r
53873 me.sortStack.push(item);\r
53874 if (sortMap[itemId] === 0) {\r
53875 for (var cycle = [],\r
53876 i = 0; i < me.sortStack.length; ++i) {\r
53877 cycle[i] = me.sortStack[i].getFullName();\r
53878 }\r
53879 Ext.raise('Dependency cycle detected: ' + cycle.join('\n --> '));\r
53880 }\r
53881
53882 if (!(itemId in sortMap)) {\r
53883
53884
53885
53886
53887
53888 sortMap[itemId] = 0;\r
53889 if (!item.sort.$nullFn) {\r
53890 item.sort();\r
53891 }\r
53892 sortMap[itemId] = 1;\r
53893 item.order = me.orderedItems.length;\r
53894 orderedItems.push(item);\r
53895 }\r
53896
53897 me.sortStack.pop();\r
53898
53899 return me;\r
53900 },\r
53901 \r
53902 sortItems: function(items) {\r
53903 var me = this,\r
53904 sortItem = me.sortItem;\r
53905 if (items) {\r
53906 if (items instanceof Array) {\r
53907 Ext.each(items, sortItem, me);\r
53908 } else {\r
53909 Ext.Object.eachValue(items, sortItem, me);\r
53910 }\r
53911 }\r
53912 return me;\r
53913 },\r
53914 applyPreSort: function(preSort) {\r
53915 if (typeof preSort === 'function') {\r
53916 return preSort;\r
53917 }\r
53918 var parts = preSort.split(','),\r
53919 direction = [],\r
53920 length = parts.length,\r
53921 c, i, s;\r
53922 for (i = 0; i < length; ++i) {\r
53923 direction[i] = 1;\r
53924 s = parts[i];\r
53925 if ((c = s.charAt(0)) === '-') {\r
53926 direction[i] = -1;\r
53927 } else if (c !== '+') {\r
53928 c = 0;\r
53929 }\r
53930 if (c) {\r
53931 parts[i] = s.substring(1);\r
53932 }\r
53933 }\r
53934 return function(lhs, rhs) {\r
53935 var ret = 0,\r
53936 i, prop, v1, v2;\r
53937 for (i = 0; !ret && i < length; ++i) {\r
53938 prop = parts[i];\r
53939 v1 = lhs[prop];\r
53940 v2 = rhs[prop];\r
53941 ret = direction[i] * ((v1 < v2) ? -1 : ((v2 < v1) ? 1 : 0));\r
53942 }\r
53943 return ret;\r
53944 };\r
53945 },\r
53946
53947
53948
53949 \r
53950 notify: function() {\r
53951 var me = this,\r
53952 timer = me.timer,\r
53953 cyclesLeft = me.getCycleLimit(),\r
53954 globalEvents = Ext.GlobalEvents,\r
53955 suspend = me.suspendOnNotify,\r
53956 busyCounter, i, item, len, queue, firedEvent;\r
53957 if (timer) {\r
53958 window.clearTimeout(timer);\r
53959 me.timer = null;\r
53960 }\r
53961
53962 if (me.firing) {\r
53963 Ext.raise('Notify cannot be called recursively');\r
53964 }\r
53965
53966 if (suspend) {\r
53967 Ext.suspendLayouts();\r
53968 }\r
53969 while (me.scheduledCount) {\r
53970 if (cyclesLeft) {\r
53971 --cyclesLeft;\r
53972 } else {\r
53973 me.firing = null;\r
53974
53975 if (me.onCycleLimitExceeded) {\r
53976 me.onCycleLimitExceeded();\r
53977 }\r
53978
53979 break;\r
53980 }\r
53981 if (!firedEvent) {\r
53982 firedEvent = true;\r
53983 if (globalEvents.hasListeners.beforebindnotify) {\r
53984 globalEvents.fireEvent('beforebindnotify', me);\r
53985 }\r
53986 }\r
53987 ++me.passes;\r
53988
53989
53990 if (!(queue = me.orderedItems)) {\r
53991 me.sort();\r
53992 queue = me.orderedItems;\r
53993 }\r
53994 len = queue.length;\r
53995 if (len) {\r
53996 me.firing = me.items;\r
53997 for (i = 0; i < len; ++i) {\r
53998 item = queue[i];\r
53999 if (item.scheduled) {\r
54000 item.scheduled = false;\r
54001 --me.scheduledCount;\r
54002 me.notifyIndex = i;\r
54003
54004
54005
54006
54007 item.react();\r
54008 if (!me.scheduledCount) {\r
54009 break;\r
54010 }\r
54011 }\r
54012 }\r
54013 }\r
54014 }\r
54015 me.firing = null;\r
54016 me.notifyIndex = -1;\r
54017 if (suspend) {\r
54018 Ext.resumeLayouts(true);\r
54019 }\r
54020
54021
54022 if ((busyCounter = me.busyCounter) !== me.lastBusyCounter) {\r
54023 if (!(me.lastBusyCounter = busyCounter)) {\r
54024
54025
54026 me.fireEvent('idle', me);\r
54027 }\r
54028 }\r
54029 },\r
54030 \r
54031 onTick: function() {\r
54032 this.timer = null;\r
54033 this.notify();\r
54034 },\r
54035 \r
54036 scheduleItem: function(item) {\r
54037 var me = this;\r
54038 ++me.scheduledCount;\r
54039
54040 if (!me.timer && !me.firing) {\r
54041 me.scheduleTick();\r
54042 }\r
54043 },\r
54044 \r
54045 scheduleTick: function() {\r
54046 var me = this;\r
54047 if (!me.destroyed && !me.timer) {\r
54048 me.timer = Ext.Function.defer(me.onTick, me.getTickDelay(), me);\r
54049 }\r
54050 },\r
54051 \r
54052 unscheduleItem: function(item) {\r
54053 if (this.scheduledCount) {\r
54054 --this.scheduledCount;\r
54055 }\r
54056 },\r
54057
54058
54059
54060
54061 \r
54062 adjustBusy: function(adjustment) {\r
54063 var me = this,\r
54064 busyCounter = me.busyCounter + adjustment;\r
54065 me.busyCounter = busyCounter;\r
54066 if (busyCounter) {\r
54067
54068
54069 if (!me.lastBusyCounter) {\r
54070 me.lastBusyCounter = busyCounter;\r
54071 me.fireEvent('busy', me);\r
54072 }\r
54073 } else if (me.lastBusyCounter && !me.timer) {\r
54074
54075
54076 me.scheduleTick();\r
54077 }\r
54078 },\r
54079 \r
54080 isBusy: function() {\r
54081 return !this.isIdle();\r
54082 },\r
54083 \r
54084 isIdle: function() {\r
54085 return !(this.busyCounter + this.lastBusyCounter);\r
54086 },\r
54087
54088 debugHooks: {\r
54089 $enabled: false,\r
54090
54091 onCycleLimitExceeded: function() {\r
54092 Ext.raise('Exceeded cycleLimit ' + this.getCycleLimit());\r
54093 },\r
54094 scheduleItem: function(item) {\r
54095 if (!item) {\r
54096 Ext.raise('scheduleItem: Invalid argument');\r
54097 }\r
54098 Ext.log('Schedule item: ' + item.getFullName() + ' - ' + (this.scheduledCount + 1));\r
54099 if (item.order <= this.notifyIndex) {\r
54100 Ext.log.warn('Suboptimal order: ' + item.order + ' < ' + this.notifyIndex);\r
54101 }\r
54102 this.callParent([\r
54103 item\r
54104 ]);\r
54105 },\r
54106 unscheduleItem: function(item) {\r
54107 if (!this.scheduledCount) {\r
54108 Ext.raise('Invalid scheduleCount');\r
54109 }\r
54110 this.callParent([\r
54111 item\r
54112 ]);\r
54113 Ext.log('Unschedule item: ' + item.getFullName() + ' - ' + this.scheduledCount);\r
54114 }\r
54115 }\r
54116});\r
54117\r
54118\r
54119Ext.define('Ext.data.Batch', {\r
54120 mixins: {\r
54121 observable: Ext.mixin.Observable\r
54122 },\r
54123 config: {\r
54124 \r
54125 pauseOnException: false\r
54126 },\r
54127 \r
54128 current: -1,\r
54129 \r
54130 total: 0,\r
54131 \r
54132 running: false,\r
54133 \r
54134 complete: false,\r
54135 \r
54136 exception: false,\r
54137 \r
54138 constructor: function(config) {\r
54139 var me = this;\r
54140 me.mixins.observable.constructor.call(me, config);\r
54141 \r
54142 \r
54143 \r
54144 \r
54145 me.operations = [];\r
54146 \r
54147 me.exceptions = [];\r
54148 },\r
54149 \r
54150 add: function(operation) {\r
54151 var me = this,\r
54152 i, len;\r
54153 if (Ext.isArray(operation)) {\r
54154 for (i = 0 , len = operation.length; i < len; ++i) {\r
54155 me.add(operation[i]);\r
54156 }\r
54157 } else {\r
54158 me.total++;\r
54159 operation.setBatch(me);\r
54160 me.operations.push(operation);\r
54161 }\r
54162 return me;\r
54163 },\r
54164 \r
54165 sort: function() {\r
54166 this.operations.sort(this.sortFn);\r
54167 },\r
54168 sortFn: function(operation1, operation2) {\r
54169 var ret = operation1.order - operation2.order;\r
54170 if (ret) {\r
54171 return ret;\r
54172 }\r
54173 var entityType1 = operation1.entityType,\r
54174 entityType2 = operation2.entityType,\r
54175 rank;\r
54176
54177
54178 if (!entityType1 || !entityType2) {\r
54179 return 0;\r
54180 }\r
54181
54182
54183 if (!(rank = entityType1.rank)) {\r
54184
54185 entityType1.schema.rankEntities();\r
54186
54187 rank = entityType1.rank;\r
54188 }\r
54189 return (rank - entityType2.rank) * operation1.foreignKeyDirection;\r
54190 },\r
54191 \r
54192 start: function(\r
54193 index) {\r
54194 var me = this;\r
54195 if (!me.operations.length || me.running) {\r
54196 return me;\r
54197 }\r
54198 me.exceptions.length = 0;\r
54199 me.exception = false;\r
54200 me.running = true;\r
54201 return me.runOperation(Ext.isDefined(index) ? index : me.current + 1);\r
54202 },\r
54203 \r
54204 retry: function() {\r
54205 return this.start(this.current);\r
54206 },\r
54207 \r
54208 runNextOperation: function() {\r
54209 var me = this;\r
54210 if (me.running) {\r
54211 me.runOperation(me.current + 1);\r
54212 }\r
54213 return me;\r
54214 },\r
54215 \r
54216 pause: function() {\r
54217 this.running = false;\r
54218 return this;\r
54219 },\r
54220 \r
54221 getOperations: function() {\r
54222 return this.operations;\r
54223 },\r
54224 \r
54225 getExceptions: function() {\r
54226 return this.exceptions;\r
54227 },\r
54228 \r
54229 getCurrent: function() {\r
54230 var out = null,\r
54231 current = this.current;\r
54232 if (!(current === -1 || this.complete)) {\r
54233 out = this.operations[current];\r
54234 }\r
54235 return out;\r
54236 },\r
54237 \r
54238 getTotal: function() {\r
54239 return this.total;\r
54240 },\r
54241 \r
54242 isRunning: function() {\r
54243 return this.running;\r
54244 },\r
54245 \r
54246 isComplete: function() {\r
54247 return this.complete;\r
54248 },\r
54249 \r
54250 hasException: function() {\r
54251 return this.exception;\r
54252 },\r
54253 \r
54254 runOperation: function(index) {\r
54255 var me = this,\r
54256 operations = me.operations,\r
54257 operation = operations[index];\r
54258 if (operation === undefined) {\r
54259 me.running = false;\r
54260 me.complete = true;\r
54261 me.fireEvent('complete', me, operations[operations.length - 1]);\r
54262 } else {\r
54263 me.current = index;\r
54264 operation.setInternalCallback(me.onOperationComplete);\r
54265 operation.setInternalScope(me);\r
54266 operation.execute();\r
54267 }\r
54268 return me;\r
54269 },\r
54270 onOperationComplete: function(operation) {\r
54271 var me = this,\r
54272 exception = operation.hasException();\r
54273 if (exception) {\r
54274 me.exception = true;\r
54275 me.exceptions.push(operation);\r
54276 me.fireEvent('exception', me, operation);\r
54277 }\r
54278 if (exception && me.getPauseOnException()) {\r
54279 me.pause();\r
54280 } else {\r
54281 me.fireEvent('operationcomplete', me, operation);\r
54282 me.runNextOperation();\r
54283 }\r
54284 }\r
54285});\r
54286\r
54287\r
54288Ext.define('Ext.data.matrix.Slice', {\r
54289 constructor: function(side, id) {\r
54290 \r
54291 this.id = id;\r
54292 \r
54293 this.side = side;\r
54294 \r
54295 this.members = {};\r
54296 },\r
54297 attach: function(store) {\r
54298 var me = this;\r
54299
54300 Ext.Assert.falsey(me.store, 'Store is already attached');\r
54301
54302 me.store = store;\r
54303 store.matrix = me;\r
54304 store.on('load', me.onStoreLoad, me, {\r
54305 single: true\r
54306 });\r
54307 },\r
54308 commit: function() {\r
54309 var members = this.members,\r
54310 id;\r
54311 for (id in members) {\r
54312 members[id][2] = 0;\r
54313 }\r
54314 },\r
54315 onStoreLoad: function(store) {\r
54316 this.update(store.getData().items, 0);\r
54317 },\r
54318 update: function(recordsOrIds, state) {\r
54319
54320 if (!(recordsOrIds instanceof Array)) {\r
54321 Ext.raise('Only array of records or record ids are supported');\r
54322 }\r
54323
54324 var me = this,\r
54325 MatrixSlice = Ext.data.matrix.Slice,\r
54326 side = me.side,\r
54327 assocIndex = side.index,\r
54328 length = recordsOrIds.length,\r
54329 id = me.id,\r
54330 members = me.members,\r
54331 otherSide = side.inverse,\r
54332 otherSlices = otherSide.slices,\r
54333 assoc, call, i, item, otherId, otherSlice, record;\r
54334 for (i = 0; i < length; ++i) {\r
54335 call = record = null;\r
54336 item = recordsOrIds[i];\r
54337 otherId = item.isEntity ? (record = item).id : item;\r
54338 assoc = members[otherId];\r
54339
54340
54341 if (state < 0 && assoc && assoc[2] === 1) {\r
54342 delete members[otherId];\r
54343 otherSlice = otherSlices[otherId];\r
54344 if (otherSlice) {\r
54345 delete otherSlice.members[id];\r
54346 }\r
54347 call = 1;\r
54348 } else {\r
54349 if (!assoc) {\r
54350
54351
54352
54353 assoc = [\r
54354 otherId,\r
54355 otherId,\r
54356 state\r
54357 ];\r
54358 assoc[assocIndex] = id;\r
54359 members[otherId] = assoc;\r
54360 otherSlice = otherSlices[otherId];\r
54361 if (!otherSlice) {\r
54362 otherSlices[otherId] = otherSlice = new MatrixSlice(otherSide, otherId);\r
54363 }\r
54364 otherSlice.members[id] = assoc;\r
54365 call = 1;\r
54366 } else if (state !== assoc[2] && state !== 0) {\r
54367
54368 assoc[2] = state;\r
54369 otherSlice = otherSlices[otherId];\r
54370
54371 call = 1;\r
54372 }\r
54373 }\r
54374 if (call) {\r
54375 if (me.notify) {\r
54376 me.notify.call(me.scope, me, otherId, state);\r
54377 }\r
54378 if (otherSlice && otherSlice.notify) {\r
54379 otherSlice.notify.call(otherSlice.scope, otherSlice, id, state);\r
54380 }\r
54381 }\r
54382 }\r
54383 },\r
54384 updateId: function(newId) {\r
54385 var me = this,\r
54386 oldId = me.id,\r
54387 side = me.side,\r
54388 slices = side.slices,\r
54389 slice = slices[oldId],\r
54390 members = slice.members,\r
54391 index = side.index,\r
54392 otherSlices = side.inverse.slices,\r
54393 assoc, otherId, otherMembers;\r
54394 me.id = newId;\r
54395 slices[newId] = slice;\r
54396 delete slices[oldId];\r
54397 for (otherId in members) {\r
54398 assoc = members[otherId];\r
54399 assoc[index] = newId;\r
54400 otherMembers = otherSlices[otherId].members;\r
54401 otherMembers[newId] = otherMembers[oldId];\r
54402 delete otherMembers[oldId];\r
54403 }\r
54404 },\r
54405 destroy: function() {\r
54406 var me = this,\r
54407 store = me.store;\r
54408 if (store) {\r
54409 store.matrix = null;\r
54410 store.un('load', me.onStoreLoad, me);\r
54411 }\r
54412 me.notify = me.scope = me.store = me.side = me.members = null;\r
54413 me.callParent();\r
54414 }\r
54415});\r
54416\r
54417\r
54418Ext.define('Ext.data.matrix.Side', {\r
54419 \r
54420 constructor: function(matrix, index, role) {\r
54421 var me = this;\r
54422 \r
54423 me.matrix = matrix;\r
54424 \r
54425 me.index = index;\r
54426 \r
54427 me.role = role;\r
54428 \r
54429 me.slices = {};\r
54430 },\r
54431 commit: function() {\r
54432 var slices = this.slices,\r
54433 id;\r
54434 for (id in slices) {\r
54435 slices[id].commit();\r
54436 }\r
54437 },\r
54438 get: function(id1, id2) {\r
54439 var me = this,\r
54440 slices = me.slices,\r
54441 slice = slices[id1] || (slices[id1] = new Ext.data.matrix.Slice(me, id1));\r
54442 return (id2 || id2 === 0) ? slice.members[id2] : slice;\r
54443 },\r
54444 update: function(id1, id2, state) {\r
54445 var slice = this.get(id1);\r
54446 return slice.update(id2, state);\r
54447 },\r
54448 updateId: function(oldId, newId) {\r
54449 var slice = this.get(oldId);\r
54450 if (slice) {\r
54451 slice.updateId(newId);\r
54452 }\r
54453 },\r
54454 destroy: function() {\r
54455 var me = this,\r
54456 slices = me.slices,\r
54457 id;\r
54458 for (id in slices) {\r
54459 slices[id].destroy();\r
54460 }\r
54461 me.inverse = me.matrix = me.role = me.slices = null;\r
54462 me.callParent();\r
54463 }\r
54464});\r
54465\r
54466\r
54467Ext.define('Ext.data.matrix.Matrix', {\r
54468 \r
54469 \r
54470 \r
54471 constructor: function(session, matrix) {\r
54472 var me = this,\r
54473 association = matrix.isManyToMany ? matrix : session.getSchema().getAssociation(matrix),\r
54474 Side = Ext.data.matrix.Side,\r
54475 left = new Side(me, 0, association.left),\r
54476 right = new Side(me, 1, association.right);\r
54477
54478 Ext.Assert.truthy(association.isManyToMany, 'Association is not many-to-many');\r
54479
54480 me.association = association;\r
54481 me.session = session;\r
54482 me.left = left;\r
54483 me.right = right;\r
54484 left.inverse = right;\r
54485 right.inverse = left;\r
54486 },\r
54487 commit: function() {\r
54488 this.left.commit();\r
54489 this.right.commit();\r
54490 },\r
54491 update: function(id1, id2, state) {\r
54492 return this.left.update(id1, id2, state);\r
54493 },\r
54494 updateId: function(record, oldId, newId) {\r
54495 var Type = record.self,\r
54496 left = this.left,\r
54497 right = this.right,\r
54498 matchSide;\r
54499
54500 if (Type === left.role.cls) {\r
54501 matchSide = left;\r
54502 }\r
54503 if (Type === right.role.cls) {\r
54504 matchSide = right;\r
54505 }\r
54506 if (matchSide) {\r
54507 matchSide.updateId(oldId, newId);\r
54508 }\r
54509 },\r
54510 destroy: function() {\r
54511 var me = this;\r
54512 me.left.destroy();\r
54513 me.right.destroy();\r
54514 me.association = me.session = me.left = me.right = null;\r
54515 me.callParent();\r
54516 }\r
54517});\r
54518\r
54519\r
54520Ext.define('Ext.data.session.ChangesVisitor', {\r
54521 constructor: function(session) {\r
54522 var me = this,\r
54523 crud;\r
54524 me.session = session;\r
54525 crud = session.getCrudProperties();\r
54526 me.result = null;\r
54527 me.writerOptions = {};\r
54528 \r
54529 me.createKey = crud.create;\r
54530 me.readKey = crud.read;\r
54531 me.updateKey = crud.update;\r
54532 me.dropKey = crud.drop;\r
54533 },\r
54534 onDirtyRecord: function(record) {\r
54535 var me = this,\r
54536 crud = me.crud,\r
54537 created = record.phantom,\r
54538 dropped = record.dropped,\r
54539 updated = !created && !dropped,\r
54540 type = record.$className,\r
54541 prop = (created || dropped) ? 'allDataOptions' : 'partialDataOptions',\r
54542 writerOptions = me.writerOptions,\r
54543 name = record.entityName,\r
54544 options, bucket, entry, result;\r
54545 if (created && dropped) {\r
54546 return false;\r
54547 }\r
54548 crud = created ? me.createKey : (dropped ? me.dropKey : me.updateKey);\r
54549 writerOptions = writerOptions[type] || (writerOptions[type] = {});\r
54550 if (dropped) {\r
54551
54552
54553 if (!(options = writerOptions.drop)) {\r
54554 writerOptions.drop = options = {\r
54555 all: record.getProxy().getWriter().getWriteAllFields()\r
54556 };\r
54557 }\r
54558 if (!options.all) {\r
54559 entry = record.id;\r
54560 }\r
54561 }\r
54562
54563 if (!entry) {\r
54564
54565
54566
54567 if (!(options = writerOptions[prop])) {\r
54568 options = record.getProxy().getWriter().getConfig(prop);\r
54569 writerOptions[prop] = options = Ext.Object.chain(options);\r
54570 me.setupOptions(options);\r
54571 }\r
54572 entry = record.getData(options);\r
54573 }\r
54574
54575
54576
54577
54578
54579
54580
54581
54582
54583 result = me.result || (me.result = {});\r
54584 bucket = result[name] || (result[name] = {});\r
54585 bucket = bucket[crud] || (bucket[crud] = []);\r
54586 bucket.push(entry);\r
54587 },\r
54588 setupOptions: function(options) {\r
54589 options.serialize = true;\r
54590 },\r
54591 onMatrixChange: function(association, id1, id2, state) {\r
54592 var me = this,\r
54593 name = association.left.type,\r
54594
54595 assocName = association.right.role,\r
54596
54597 operation = state < 0 ? me.dropKey : me.createKey,\r
54598 bucket, result;\r
54599
54600
54601
54602
54603
54604
54605
54606
54607
54608
54609 result = me.result || (me.result = {});\r
54610 bucket = result[name] || (result[name] = {});\r
54611
54612 bucket = bucket[assocName] || (bucket[assocName] = {});\r
54613
54614 bucket = bucket[operation] || (bucket[operation] = {});\r
54615
54616 bucket = bucket[id1] || (bucket[id1] = []);\r
54617 bucket.push(id2);\r
54618 }\r
54619});\r
54620\r
54621\r
54622Ext.define('Ext.data.session.ChildChangesVisitor', {\r
54623 extend: Ext.data.session.ChangesVisitor,\r
54624 constructor: function() {\r
54625 this.seen = {};\r
54626 this.callParent(arguments);\r
54627 },\r
54628 setupOptions: function(options) {\r
54629 this.callParent([\r
54630 options\r
54631 ]);\r
54632 options.serialize = false;\r
54633 },\r
54634 onDirtyRecord: function(record) {\r
54635 if (this.callParent(arguments) !== false) {\r
54636
54637
54638 if (!record.$source && (record.dropped || !record.phantom)) {\r
54639 this.readEntity(record);\r
54640 }\r
54641 }\r
54642 },\r
54643 readEntity: function(record) {\r
54644 var me = this,\r
54645 readKey = me.readKey,\r
54646 name = record.entityName,\r
54647 id = record.id,\r
54648 seen = me.seen,\r
54649 seenKey = name + id,\r
54650 result, bucket;\r
54651
54652 if (seen[seenKey]) {\r
54653 return;\r
54654 }\r
54655 seen[seenKey] = true;\r
54656 result = me.result || (me.result = {});\r
54657 bucket = result[name] || (result[name] = {});\r
54658 bucket = bucket[readKey] || (bucket[readKey] = []);\r
54659 bucket.push(Ext.apply({}, record.modified, record.data));\r
54660 }\r
54661});\r
54662\r
54663\r
54664Ext.define('Ext.data.session.BatchVisitor', {\r
54665 map: null,\r
54666 constructor: function(batch) {\r
54667 this.batch = batch;\r
54668 },\r
54669 getBatch: function(sort) {\r
54670 var map = this.map,\r
54671 batch = this.batch,\r
54672 bucket, entity, name, operation, proxy;\r
54673 if (map) {\r
54674 if (!batch) {\r
54675 batch = new Ext.data.Batch();\r
54676 }\r
54677 for (name in map) {\r
54678 bucket = map[name];\r
54679 entity = bucket.entity;\r
54680
54681 proxy = entity.getProxy();\r
54682 delete bucket.entity;\r
54683
54684 for (operation in bucket) {\r
54685 operation = proxy.createOperation(operation, {\r
54686 records: bucket[operation]\r
54687 });\r
54688 operation.entityType = entity;\r
54689 batch.add(operation);\r
54690 }\r
54691 }\r
54692 }\r
54693 if (batch && sort !== false) {\r
54694 batch.sort();\r
54695 }\r
54696 return batch;\r
54697 },\r
54698 onDirtyRecord: function(record) {\r
54699 var me = this,\r
54700 operation = record.phantom ? 'create' : (record.dropped ? 'destroy' : 'update'),\r
54701 name = record.$className,\r
54702 map = (me.map || (me.map = {})),\r
54703 bucket = (map[name] || (map[name] = {\r
54704 entity: record.self\r
54705 }));\r
54706
54707
54708
54709
54710
54711
54712 bucket = bucket[operation] || (bucket[operation] = []);\r
54713 bucket.push(record);\r
54714 }\r
54715});\r
54716\r
54717\r
54718Ext.define('Ext.data.Session', {\r
54719 isSession: true,\r
54720 config: {\r
54721 \r
54722 schema: 'default',\r
54723 \r
54724 parent: null,\r
54725 \r
54726 autoDestroy: true,\r
54727 crudProperties: {\r
54728 create: 'C',\r
54729 read: 'R',\r
54730 update: 'U',\r
54731 drop: 'D'\r
54732 }\r
54733 },\r
54734 destroyed: false,\r
54735 crudOperations: [\r
54736 {\r
54737 type: 'R',\r
54738 entityMethod: 'readEntities'\r
54739 },\r
54740 {\r
54741 type: 'C',\r
54742 entityMethod: 'createEntities'\r
54743 },\r
54744 {\r
54745 type: 'U',\r
54746 entityMethod: 'updateEntities'\r
54747 },\r
54748 {\r
54749 type: 'D',\r
54750 entityMethod: 'dropEntities'\r
54751 }\r
54752 ],\r
54753 crudKeys: {\r
54754 C: 1,\r
54755 R: 1,\r
54756 U: 1,\r
54757 D: 1\r
54758 },\r
54759 constructor: function(config) {\r
54760 var me = this;\r
54761 \r
54762 me.data = {};\r
54763 \r
54764 me.matrices = {};\r
54765 me.identifierCache = {};\r
54766
54767 me.recordCreator = me.recordCreator.bind(me);\r
54768 me.initConfig(config);\r
54769 },\r
54770 destroy: function() {\r
54771 var me = this,\r
54772 matrices = me.matrices,\r
54773 data = me.data,\r
54774 entityName, entities, record, id;\r
54775 for (id in matrices) {\r
54776 matrices[id].destroy();\r
54777 }\r
54778 for (entityName in data) {\r
54779 entities = data[entityName];\r
54780 for (id in entities) {\r
54781 record = entities[id].record;\r
54782 if (record) {\r
54783
54784
54785 record.$source = record.session = null;\r
54786 }\r
54787 }\r
54788 }\r
54789 me.recordCreator = me.matrices = me.data = null;\r
54790 me.setSchema(null);\r
54791 me.callParent();\r
54792 },\r
54793 \r
54794 adopt: function(record) {\r
54795 var me = this,\r
54796 associations = record.associations,\r
54797 roleName;\r
54798
54799 me.checkModelType(record.self);\r
54800 if (record.session && record.session !== me) {\r
54801 Ext.raise('Record already belongs to an existing session');\r
54802 }\r
54803
54804 if (record.session !== me) {\r
54805 record.session = me;\r
54806 me.add(record);\r
54807 if (associations) {\r
54808 for (roleName in associations) {\r
54809 associations[roleName].adoptAssociated(record, me);\r
54810 }\r
54811 }\r
54812 }\r
54813 },\r
54814 \r
54815 commit: function() {\r
54816 var data = this.data,\r
54817 matrices = this.matrices,\r
54818 entityName, entities, id, record;\r
54819 for (entityName in data) {\r
54820 entities = data[entityName];\r
54821 for (id in entities) {\r
54822 record = entities[id].record;\r
54823 if (record) {\r
54824 record.commit();\r
54825 }\r
54826 }\r
54827 }\r
54828 for (id in matrices) {\r
54829 matrices[id].commit();\r
54830 }\r
54831 },\r
54832 \r
54833 createRecord: function(type, data) {\r
54834
54835 this.checkModelType(type);\r
54836
54837 var Model = type.$isClass ? type : this.getSchema().getEntity(type),\r
54838 parent = this.getParent(),\r
54839 id;\r
54840
54841 if (data && parent) {\r
54842 id = Model.getIdFromData(data);\r
54843 if (parent.peekRecord(Model, id)) {\r
54844 Ext.raise('A parent session already contains an entry for ' + Model.entityName + ': ' + id);\r
54845 }\r
54846 }\r
54847
54848 return new Model(data, this);\r
54849 },\r
54850 \r
54851 getChanges: function() {\r
54852 var visitor = new Ext.data.session.ChangesVisitor(this);\r
54853 this.visitData(visitor);\r
54854 return visitor.result;\r
54855 },\r
54856 \r
54857 getChangesForParent: function() {\r
54858 var visitor = new Ext.data.session.ChildChangesVisitor(this);\r
54859 this.visitData(visitor);\r
54860 return visitor.result;\r
54861 },\r
54862 \r
54863 getRecord: function(type, id, autoLoad) {\r
54864 var me = this,\r
54865 wasInstance = type.isModel,\r
54866 record, Model, parent, parentRec;\r
54867 if (wasInstance) {\r
54868 wasInstance = type;\r
54869 id = type.id;\r
54870 type = type.self;\r
54871 }\r
54872 record = me.peekRecord(type, id);\r
54873 if (!record) {\r
54874 Model = type.$isClass ? type : me.getSchema().getEntity(type);\r
54875 parent = me.getParent();\r
54876 if (parent) {\r
54877 parentRec = parent.peekRecord(Model, id);\r
54878 }\r
54879 if (parentRec) {\r
54880 if (parentRec.isLoading()) {\r
54881
54882
54883
54884 wasInstance = false;\r
54885 } else {\r
54886 record = parentRec.copy(undefined, me);\r
54887 record.$source = parentRec;\r
54888 }\r
54889 }\r
54890 if (!record) {\r
54891 if (wasInstance) {\r
54892 record = wasInstance;\r
54893 me.adopt(record);\r
54894 } else {\r
54895 record = Model.createWithId(id, null, me);\r
54896 if (autoLoad !== false) {\r
54897 record.load(Ext.isObject(autoLoad) ? autoLoad : undefined);\r
54898 }\r
54899 }\r
54900 }\r
54901 }\r
54902 return record;\r
54903 },\r
54904 \r
54905 getSaveBatch: function(sort) {\r
54906 var visitor = new Ext.data.session.BatchVisitor();\r
54907 this.visitData(visitor);\r
54908 return visitor.getBatch(sort);\r
54909 },\r
54910 \r
54911 onInvalidAssociationEntity: function(entityType, id) {\r
54912 Ext.raise('Unable to read association entity: ' + this.getModelIdentifier(entityType, id));\r
54913 },\r
54914 \r
54915 onInvalidEntityCreate: function(entityType, id) {\r
54916 Ext.raise('Cannot create, record already not exists: ' + this.getModelIdentifier(entityType, id));\r
54917 },\r
54918 \r
54919 onInvalidEntityDrop: function(entityType, id) {\r
54920 Ext.raise('Cannot drop, record does not exist: ' + this.getModelIdentifier(entityType, id));\r
54921 },\r
54922 \r
54923 onInvalidEntityRead: function(entityType, id) {\r
54924 Ext.raise('Cannot read, record already not exists: ' + this.getModelIdentifier(entityType, id));\r
54925 },\r
54926 \r
54927 onInvalidEntityUpdate: function(entityType, id, dropped) {\r
54928 if (dropped) {\r
54929 Ext.raise('Cannot update, record dropped: ' + this.getModelIdentifier(entityType, id));\r
54930 } else {\r
54931 Ext.raise('Cannot update, record does not exist: ' + this.getModelIdentifier(entityType, id));\r
54932 }\r
54933 },\r
54934 \r
54935 peekRecord: function(type, id, deep) {\r
54936
54937
54938
54939 this.checkModelType(type);\r
54940
54941 var entityType = type.$isClass ? type : this.getSchema().getEntity(type),\r
54942 entityName = entityType.entityName,\r
54943 entry = this.data[entityName],\r
54944 ret, parent;\r
54945 entry = entry && entry[id];\r
54946 ret = entry && entry.record;\r
54947 if (!ret && deep) {\r
54948 parent = this.getParent();\r
54949 ret = parent && parent.peekRecord(type, id, deep);\r
54950 }\r
54951 return ret || null;\r
54952 },\r
54953 \r
54954 save: function() {\r
54955
54956 if (!this.getParent()) {\r
54957 Ext.raise('Cannot commit session, no parent exists');\r
54958 }\r
54959
54960 var visitor = new Ext.data.session.ChildChangesVisitor(this);\r
54961 this.visitData(visitor);\r
54962 this.getParent().update(visitor.result);\r
54963 },\r
54964 \r
54965 spawn: function() {\r
54966 return new this.self({\r
54967 schema: this.getSchema(),\r
54968 parent: this\r
54969 });\r
54970 },\r
54971 \r
54972 update: function(data) {\r
54973 var me = this,\r
54974 schema = me.getSchema(),\r
54975 crudOperations = me.crudOperations,\r
54976 len = crudOperations.length,\r
54977 crudKeys = me.crudKeys,\r
54978 entityName, entityType, entityInfo, i, operation, item, associations, key, role, associationData;\r
54979
54980 me.getSchema().processKeyChecks(true);\r
54981
54982 for (entityName in data) {\r
54983 entityType = schema.getEntity(entityName);\r
54984
54985 if (!entityType) {\r
54986 Ext.raise('Invalid entity type: ' + entityName);\r
54987 }\r
54988
54989 entityInfo = data[entityName];\r
54990 for (i = 0; i < len; ++i) {\r
54991 operation = crudOperations[i];\r
54992 item = entityInfo[operation.type];\r
54993 if (item) {\r
54994 me[operation.entityMethod](entityType, item);\r
54995 }\r
54996 }\r
54997 }\r
54998
54999 for (entityName in data) {\r
55000 entityType = schema.getEntity(entityName);\r
55001 associations = entityType.associations;\r
55002 entityInfo = data[entityName];\r
55003 for (key in entityInfo) {\r
55004
55005 if (crudKeys[key]) {\r
55006 \r
55007 continue;\r
55008 }\r
55009 role = associations[key];\r
55010
55011 if (!role) {\r
55012 Ext.raise('Invalid association key for ' + entityName + ', "' + key + '"');\r
55013 }\r
55014
55015 associationData = entityInfo[role.role];\r
55016 role.processUpdate(me, associationData);\r
55017 }\r
55018 }\r
55019 },\r
55020
55021 privates: {\r
55022 \r
55023 add: function(record) {\r
55024 var me = this,\r
55025 id = record.id,\r
55026 entry = me.getEntry(record.self, id),\r
55027 associations, roleName;\r
55028
55029 if (entry.record) {\r
55030 Ext.raise('Duplicate id ' + record.id + ' for ' + record.entityName);\r
55031 }\r
55032
55033 entry.record = record;\r
55034 me.registerReferences(record);\r
55035 associations = record.associations;\r
55036 for (roleName in associations) {\r
55037 associations[roleName].checkMembership(me, record);\r
55038 }\r
55039 },\r
55040 \r
55041 afterErase: function(record) {\r
55042 this.evict(record);\r
55043 },\r
55044 \r
55045 applySchema: function(schema) {\r
55046 return Ext.data.schema.Schema.get(schema);\r
55047 },\r
55048
55049 \r
55050 checkModelType: function(name) {\r
55051 if (name.$isClass) {\r
55052 name = name.entityName;\r
55053 }\r
55054 if (!name) {\r
55055 Ext.raise('Unable to use anonymous models in a Session');\r
55056 } else if (!this.getSchema().getEntity(name)) {\r
55057 Ext.raise('Unknown entity type ' + name);\r
55058 }\r
55059 },\r
55060
55061 \r
55062 createEntities: function(entityType, items) {\r
55063 var len = items.length,\r
55064 i, data, rec, id;\r
55065 for (i = 0; i < len; ++i) {\r
55066 data = items[i];\r
55067 id = entityType.getIdFromData(data);\r
55068 rec = this.peekRecord(entityType, id);\r
55069 if (!rec) {\r
55070 rec = this.createRecord(entityType, data);\r
55071 } else {\r
55072 this.onInvalidEntityCreate(entityType, id);\r
55073 }\r
55074
55075
55076 rec.phantom = true;\r
55077 }\r
55078 },\r
55079 \r
55080 dropEntities: function(entityType, ids) {\r
55081 var len = ids.length,\r
55082 i, rec, id, extractId;\r
55083 if (len) {\r
55084
55085 extractId = Ext.isObject(ids[0]);\r
55086 }\r
55087 for (i = 0; i < len; ++i) {\r
55088 id = ids[i];\r
55089 if (extractId) {\r
55090 id = entityType.getIdFromData(id);\r
55091 }\r
55092 rec = this.peekRecord(entityType, id);\r
55093 if (rec) {\r
55094 rec.drop();\r
55095 } else {\r
55096 this.onInvalidEntityDrop(entityType, id);\r
55097 }\r
55098 }\r
55099 },\r
55100 \r
55101 evict: function(record) {\r
55102 var entityName = record.entityName,\r
55103 entities = this.data[entityName],\r
55104 id = record.id,\r
55105 entry;\r
55106 if (entities) {\r
55107 delete entities[id];\r
55108 }\r
55109 },\r
55110 \r
55111 getEntityList: function(entityType, ids) {\r
55112 var len = ids.length,\r
55113 i, id, rec, invalid;\r
55114 for (i = 0; i < len; ++i) {\r
55115 id = ids[i];\r
55116 rec = this.peekRecord(entityType, id);\r
55117 if (rec) {\r
55118 ids[i] = rec;\r
55119 } else {\r
55120 invalid = true;\r
55121 ids[i] = null;\r
55122 this.onInvalidAssociationEntity(entityType, id);\r
55123 }\r
55124 }\r
55125 if (invalid) {\r
55126 ids = Ext.Array.clean(ids);\r
55127 }\r
55128 return ids;\r
55129 },\r
55130 \r
55131 getEntry: function(type, id) {\r
55132 if (type.isModel) {\r
55133 id = type.getId();\r
55134 type = type.self;\r
55135 }\r
55136 var entityType = type.$isClass ? type : this.getSchema().getEntity(type),\r
55137 entityName = entityType.entityName,\r
55138 data = this.data,\r
55139 entry;\r
55140 entry = data[entityName] || (data[entityName] = {});\r
55141 entry = entry[id] || (entry[id] = {});\r
55142 return entry;\r
55143 },\r
55144 getRefs: function(record, role, includeParent) {\r
55145 var entry = this.getEntry(record),\r
55146 refs = entry && entry.refs && entry.refs[role.role],\r
55147 parent = includeParent && this.getParent(),\r
55148 parentRefs, id, rec;\r
55149 if (parent) {\r
55150 parentRefs = parent.getRefs(record, role);\r
55151 if (parentRefs) {\r
55152 for (id in parentRefs) {\r
55153 rec = parentRefs[id];\r
55154 if ((!refs || !refs[id])) {\r
55155
55156
55157 this.getRecord(rec.self, rec.id);\r
55158 }\r
55159 }\r
55160
55161 refs = entry && entry.refs && entry.refs[role.role];\r
55162 }\r
55163 }\r
55164 return refs || null;\r
55165 },\r
55166 getIdentifier: function(entityType) {\r
55167 var parent = this.getParent(),\r
55168 cache, identifier, key, ret;\r
55169 if (parent) {\r
55170 ret = parent.getIdentifier(entityType);\r
55171 } else {\r
55172 cache = this.identifierCache;\r
55173 identifier = entityType.identifier;\r
55174 key = identifier.id || entityType.entityName;\r
55175 ret = cache[key];\r
55176 if (!ret) {\r
55177 if (identifier.clone) {\r
55178 ret = identifier.clone({\r
55179 cache: cache\r
55180 });\r
55181 } else {\r
55182 ret = identifier;\r
55183 }\r
55184 cache[key] = ret;\r
55185 }\r
55186 }\r
55187 return ret;\r
55188 },\r
55189 getMatrix: function(matrix, preventCreate) {\r
55190 var name = matrix.isManyToMany ? matrix.name : matrix,\r
55191 matrices = this.matrices,\r
55192 ret;\r
55193 ret = matrices[name];\r
55194 if (!ret && !preventCreate) {\r
55195 ret = matrices[name] = new Ext.data.matrix.Matrix(this, matrix);\r
55196 }\r
55197 return ret || null;\r
55198 },\r
55199 getMatrixSlice: function(role, id) {\r
55200 var matrix = this.getMatrix(role.association),\r
55201 side = matrix[role.side];\r
55202 return side.get(id);\r
55203 },\r
55204 \r
55205 getModelIdentifier: function(entityType, id) {\r
55206 return id + '@' + entityType.entityName;\r
55207 },\r
55208 onIdChanged: function(record, oldId, newId) {\r
55209 var me = this,\r
55210 matrices = me.matrices,\r
55211 entityName = record.entityName,\r
55212 id = record.id,\r
55213 bucket = me.data[entityName],\r
55214 entry = bucket[oldId],\r
55215 associations = record.associations,\r
55216 refs = entry.refs,\r
55217 setNoRefs = me._setNoRefs,\r
55218 association, fieldName, matrix, refId, role, roleName, roleRefs, key;\r
55219
55220 if (bucket[newId]) {\r
55221 Ext.raise('Cannot change ' + entityName + ' id from ' + oldId + ' to ' + newId + ' id already exists');\r
55222 }\r
55223
55224 delete bucket[oldId];\r
55225 bucket[newId] = entry;\r
55226 for (key in matrices) {\r
55227 matrices[key].updateId(record, oldId, newId);\r
55228 }\r
55229 if (refs) {\r
55230 for (roleName in refs) {\r
55231 roleRefs = refs[roleName];\r
55232 role = associations[roleName];\r
55233 association = role.association;\r
55234 if (!association.isManyToMany) {\r
55235 fieldName = association.field.name;\r
55236 for (refId in roleRefs) {\r
55237 roleRefs[refId].set(fieldName, id, setNoRefs);\r
55238 }\r
55239 }\r
55240 }\r
55241 }\r
55242 me.registerReferences(record, oldId);\r
55243 },\r
55244 processManyBlock: function(entityType, role, items, processor) {\r
55245 var me = this,\r
55246 id, record, records, store;\r
55247 if (items) {\r
55248 for (id in items) {\r
55249 record = me.peekRecord(entityType, id);\r
55250 if (record) {\r
55251 records = me.getEntityList(role.cls, items[id]);\r
55252 store = role.getAssociatedItem(record);\r
55253 me[processor](role, store, record, records);\r
55254 } else {\r
55255 me.onInvalidAssociationEntity(entityType, id);\r
55256 }\r
55257 }\r
55258 }\r
55259 },\r
55260 processManyCreate: function(role, store, record, records) {\r
55261 if (store) {\r
55262
55263 store.add(records);\r
55264 } else {\r
55265 record[role.getterName](null, null, records);\r
55266 }\r
55267 },\r
55268 processManyDrop: function(role, store, record, records) {\r
55269 if (store) {\r
55270 store.remove(records);\r
55271 }\r
55272 },\r
55273 processManyRead: function(role, store, record, records) {\r
55274 if (store) {\r
55275 store.setRecords(records);\r
55276 } else {\r
55277
55278 record[role.getterName](null, null, records);\r
55279 }\r
55280 },\r
55281 \r
55282 readEntities: function(entityType, items) {\r
55283 var len = items.length,\r
55284 i, data, rec, id;\r
55285 for (i = 0; i < len; ++i) {\r
55286 data = items[i];\r
55287 id = entityType.getIdFromData(data);\r
55288 rec = this.peekRecord(entityType, id);\r
55289 if (!rec) {\r
55290 rec = this.createRecord(entityType, data);\r
55291 } else {\r
55292 this.onInvalidEntityRead(entityType, id);\r
55293 }\r
55294
55295
55296 rec.phantom = false;\r
55297 }\r
55298 },\r
55299 recordCreator: function(data, Model) {\r
55300 var me = this,\r
55301 id = Model.getIdFromData(data),\r
55302 record = me.peekRecord(Model, id, true);\r
55303
55304 if (!record) {\r
55305
55306
55307
55308
55309 record = new Model(data, me);\r
55310 } else {\r
55311
55312
55313
55314
55315
55316 record = me.getRecord(Model, id);\r
55317 }\r
55318 return record;\r
55319 },\r
55320 registerReferences: function(record, oldId) {\r
55321 var entityName = record.entityName,\r
55322 id = record.id,\r
55323 recordData = record.data,\r
55324 remove = oldId || oldId === 0,\r
55325 entry, i, fk, len, reference, references, refs, roleName;\r
55326
55327 len = (references = record.references).length;\r
55328 for (i = 0; i < len; ++i) {\r
55329 reference = references[i];\r
55330
55331 fk = recordData[reference.name];\r
55332
55333 if (fk || fk === 0) {\r
55334 reference = reference.reference;\r
55335
55336 entityName = reference.type;\r
55337 roleName = reference.inverse.role;\r
55338
55339 entry = this.getEntry(reference.cls, fk);\r
55340 refs = entry.refs || (entry.refs = {});\r
55341 refs = refs[roleName] || (refs[roleName] = {});\r
55342 refs[id] = record;\r
55343 if (remove) {\r
55344 delete refs[oldId];\r
55345 }\r
55346 }\r
55347 }\r
55348 },\r
55349 \r
55350 updateEntities: function(entityType, items) {\r
55351 var len = items.length,\r
55352 i, data, rec, id, modified;\r
55353
55354 if (Ext.isArray(items)) {\r
55355 for (i = 0; i < len; ++i) {\r
55356 data = items[i];\r
55357 id = entityType.getIdFromData(data);\r
55358 rec = this.peekRecord(entityType, id);\r
55359 if (rec) {\r
55360 rec.set(data);\r
55361 } else {\r
55362 this.onInvalidEntityUpdate(entityType, id);\r
55363 }\r
55364 }\r
55365 } else {\r
55366 for (id in items) {\r
55367 data = items[id];\r
55368 rec = this.peekRecord(entityType, id);\r
55369 if (rec && !rec.dropped) {\r
55370 modified = rec.set(data);\r
55371 } else {\r
55372 this.onInvalidEntityUpdate(entityType, id, !!rec);\r
55373 }\r
55374 }\r
55375 }\r
55376 },\r
55377 updateReference: function(record, field, newValue, oldValue) {\r
55378 var reference = field.reference,\r
55379 entityName = reference.type,\r
55380 roleName = reference.inverse.role,\r
55381 id = record.id,\r
55382 entry, refs;\r
55383 if (oldValue || oldValue === 0) {\r
55384
55385 refs = this.getEntry(entityName, oldValue).refs[roleName];\r
55386 delete refs[id];\r
55387 }\r
55388 if (newValue || newValue === 0) {\r
55389 entry = this.getEntry(entityName, newValue);\r
55390 refs = entry.refs || (entry.refs = {});\r
55391 refs = refs[roleName] || (refs[roleName] = {});\r
55392 refs[id] = record;\r
55393 }\r
55394 },\r
55395 \r
55396 visitData: function(visitor) {\r
55397 var me = this,\r
55398 data = me.data,\r
55399 matrices = me.matrices,\r
55400 all, assoc, id, id2, matrix, members, name, record, slice, slices, state;\r
55401
55402 me.getSchema().processKeyChecks(true);\r
55403 for (name in data) {\r
55404 all = data[name];\r
55405
55406 for (id in all) {\r
55407 record = all[id].record;\r
55408 if (record) {\r
55409 if (record.phantom || record.dirty || record.dropped) {\r
55410 if (visitor.onDirtyRecord) {\r
55411 visitor.onDirtyRecord(record);\r
55412 }\r
55413 } else if (visitor.onCleanRecord) {\r
55414 visitor.onCleanRecord(record);\r
55415 }\r
55416 }\r
55417 }\r
55418 }\r
55419 if (visitor.onMatrixChange) {\r
55420 for (name in matrices) {\r
55421 matrix = matrices[name].left;\r
55422
55423 slices = matrix.slices;\r
55424 assoc = matrix.role.association;\r
55425 for (id in slices) {\r
55426 slice = slices[id];\r
55427 members = slice.members;\r
55428 for (id2 in members) {\r
55429 state = (record = members[id2])[2];\r
55430 if (state) {\r
55431 visitor.onMatrixChange(assoc, record[0], record[1], state);\r
55432 }\r
55433 }\r
55434 }\r
55435 }\r
55436 }\r
55437 return visitor;\r
55438 },\r
55439
55440
55441 _setNoRefs: {\r
55442 refs: false\r
55443 }\r
55444 }\r
55445});\r
55446\r
55447\r
55448Ext.define('Ext.util.Schedulable', {\r
55449 'abstract': true,\r
55450 isSchedulable: true,\r
55451 scheduled: false,\r
55452 constructor: function() {\r
55453 this.getScheduler().add(this);\r
55454 },\r
55455 destroy: function() {\r
55456 var me = this,\r
55457 scheduler = me.getScheduler();\r
55458 if (scheduler) {\r
55459 scheduler.remove(me);\r
55460 }\r
55461 me.scheduler = null;\r
55462 me.schedule = me.react = Ext.emptyFn;\r
55463 me.callParent();\r
55464 },\r
55465 getFullName: function() {\r
55466 return this.name || this.id;\r
55467 },\r
55468 privates: {\r
55469 \r
55470 getScheduler: function() {\r
55471 return this.scheduler;\r
55472 },\r
55473 \r
55474 schedule: function() {\r
55475 var me = this,\r
55476 scheduler;\r
55477 if (!me.scheduled) {\r
55478 scheduler = me.getScheduler();\r
55479 if (scheduler) {\r
55480 me.scheduled = true;\r
55481 if (me.onSchedule) {\r
55482 me.onSchedule();\r
55483 }\r
55484 scheduler.scheduleItem(me);\r
55485 }\r
55486 }\r
55487 },\r
55488 \r
55489 unschedule: function() {\r
55490 var me = this,\r
55491 scheduler;\r
55492 if (me.scheduled) {\r
55493 scheduler = me.getScheduler();\r
55494 if (scheduler) {\r
55495 scheduler.unscheduleItem(me);\r
55496 }\r
55497 me.scheduled = false;\r
55498 }\r
55499 },\r
55500 \r
55501
55502 sort: function() {}\r
55503 }\r
55504});\r
55505\r
55506\r
55507Ext.define('Ext.app.bind.BaseBinding', {\r
55508 extend: Ext.util.Schedulable,\r
55509 calls: 0,\r
55510 kind: 20,\r
55511 defaultOptions: {},\r
55512 lastValue: undefined,\r
55513 \r
55514 constructor: function(owner, callback, scope, options) {\r
55515 var me = this;\r
55516 me.options = options;\r
55517 me.owner = owner;\r
55518 me.scope = scope;\r
55519 me.callback = callback;\r
55520
55521 if (!callback) {\r
55522 Ext.raise('Callback is required');\r
55523 }\r
55524
55525
55526 me.lateBound = Ext.isString(callback);\r
55527 if (options && options.deep) {\r
55528 me.deep = true;\r
55529 }\r
55530 me.callParent();\r
55531 },\r
55532 destroy: function() {\r
55533 var me = this,\r
55534 owner = me.owner;\r
55535 me.callParent();\r
55536 if (owner) {\r
55537 owner.onBindDestroy(me);\r
55538 }\r
55539 me.scope = me.callback = me.owner = null;\r
55540 },\r
55541 isReadOnly: function() {\r
55542 return true;\r
55543 },\r
55544 privates: {\r
55545 getScheduler: function() {\r
55546 var owner = this.owner;\r
55547 return owner && owner.getScheduler();\r
55548 },\r
55549 getSession: function() {\r
55550 var owner = this.owner;\r
55551 return owner.isSession ? owner : owner.getSession();\r
55552 },\r
55553 notify: function(value) {\r
55554 var me = this,\r
55555 options = me.options || me.defaultOptions,\r
55556 previous = me.lastValue;\r
55557
55558
55559
55560
55561
55562
55563 if (!me.calls || me.deep || previous !== value || Ext.isArray(value)) {\r
55564 ++me.calls;\r
55565 me.lastValue = value;\r
55566 if (me.lateBound) {\r
55567
55568
55569 me.scope[me.callback](value, previous, me);\r
55570 } else {\r
55571 me.callback.call(me.scope, value, previous, me);\r
55572 }\r
55573 if (options.single) {\r
55574 me.destroy();\r
55575 }\r
55576 }\r
55577 }\r
55578 }\r
55579});\r
55580\r
55581\r
55582Ext.define('Ext.app.bind.Binding', {\r
55583 extend: Ext.app.bind.BaseBinding,\r
55584 \r
55585 constructor: function(stub, callback, scope, options) {\r
55586 var me = this;\r
55587 me.callParent([\r
55588 stub.owner,\r
55589 callback,\r
55590 scope,\r
55591 options\r
55592 ]);\r
55593 me.stub = stub;\r
55594 me.depth = stub.depth;\r
55595
55596
55597
55598 if (!stub.isLoading() && !stub.scheduled) {\r
55599 me.schedule();\r
55600 }\r
55601 },\r
55602 \r
55603 destroy: function(\r
55604 fromParent) {\r
55605 var me = this,\r
55606 stub = me.stub;\r
55607 if (stub && !fromParent) {\r
55608 stub.unbind(me);\r
55609 me.stub = null;\r
55610 }\r
55611 me.callParent();\r
55612 },\r
55613 \r
55614 bindValidation: function(callback, scope) {\r
55615 var stub = this.stub;\r
55616 return stub && stub.bindValidation(callback, scope);\r
55617 },\r
55618 \r
55619 bindValidationField: function(callback, scope) {\r
55620 var stub = this.stub;\r
55621 return stub && stub.bindValidationField(callback, scope);\r
55622 },\r
55623 \r
55624 getFullName: function() {\r
55625 return this.fullName || (this.fullName = '@(' + this.stub.getFullName() + ')');\r
55626 },\r
55627 \r
55628 getValue: function() {\r
55629 var me = this,\r
55630 stub = me.stub,\r
55631 ret = stub && stub.getValue();\r
55632 if (me.transform) {\r
55633 ret = me.transform(ret);\r
55634 }\r
55635 return ret;\r
55636 },\r
55637 \r
55638 isLoading: function() {\r
55639 var stub = this.stub;\r
55640 return stub && stub.isLoading();\r
55641 },\r
55642 \r
55643 isReadOnly: function() {\r
55644 var stub = this.stub,\r
55645 options = this.options;\r
55646 if (!(options && options.twoWay === false)) {\r
55647 if (stub) {\r
55648 return stub.isReadOnly();\r
55649 }\r
55650 }\r
55651 return true;\r
55652 },\r
55653
55654 \r
55655 refresh: function() {},\r
55656
55657 \r
55658 setValue: function(value) {\r
55659
55660 if (this.isReadOnly()) {\r
55661 Ext.raise('Cannot setValue on a readonly binding');\r
55662 }\r
55663
55664 this.stub.set(value);\r
55665 },\r
55666 privates: {\r
55667 getDataObject: function() {\r
55668 var stub = this.stub;\r
55669 return stub && stub.getDataObject();\r
55670 },\r
55671 getRawValue: function() {\r
55672 var me = this,\r
55673 stub = me.stub,\r
55674 ret = stub && stub.getRawValue();\r
55675 if (me.transform) {\r
55676 ret = me.transform(ret);\r
55677 }\r
55678 return ret;\r
55679 },\r
55680 isDescendantOf: function(item) {\r
55681 var stub = this.stub;\r
55682 return stub ? (item === stub) || stub.isDescendantOf(item) : false;\r
55683 },\r
55684 react: function() {\r
55685 this.notify(this.getValue());\r
55686 },\r
55687 schedule: function() {\r
55688
55689
55690 if (!this.stub.scheduled) {\r
55691 this.callParent();\r
55692 }\r
55693 },\r
55694 sort: function() {\r
55695 var stub = this.stub;\r
55696 stub.scheduler.sortItem(stub);\r
55697 }\r
55698 }\r
55699});\r
55700
55701
55702\r
55703\r
55704Ext.define('Ext.app.bind.AbstractStub', {\r
55705 extend: Ext.util.Schedulable,\r
55706 children: null,\r
55707 depth: 0,\r
55708 generation: 1,\r
55709 kind: 10,\r
55710 parent: null,\r
55711 constructor: function(owner, name) {\r
55712 var me = this;\r
55713 \r
55714 me.owner = owner;\r
55715 me.name = name;\r
55716 me.callParent();\r
55717 },\r
55718 destroy: function() {\r
55719 var me = this,\r
55720 children = me.children,\r
55721 bindings = me.bindings,\r
55722 len, i, key;\r
55723 if (bindings) {\r
55724 for (i = 0 , len = bindings.length; i < len; ++i) {\r
55725 bindings[i].destroy(true);\r
55726 }\r
55727 }\r
55728 for (key in children) {\r
55729 children[key].destroy();\r
55730 }\r
55731 me.callParent();\r
55732 me.bindings = me.children = me.owner = null;\r
55733 },\r
55734 add: function(child) {\r
55735 var me = this;\r
55736 (me.children || (me.children = {}))[child.name] = child;\r
55737 child.depth = me.depth + 1;\r
55738 child.parent = me;\r
55739 },\r
55740 getChild: function(path) {\r
55741 var pathArray = Ext.isString(path) ? path.split('.') : path;\r
55742 if (pathArray && pathArray.length) {\r
55743 return this.descend(pathArray, 0);\r
55744 }\r
55745 return this;\r
55746 },\r
55747 getFullName: function() {\r
55748 var me = this,\r
55749 name = me.fullName,\r
55750 parent = me.parent,\r
55751 s;\r
55752 if (!name) {\r
55753 name = me.name || me.id;\r
55754 if (parent && (s = parent.getFullName())) {\r
55755 name = ((s.charAt(s.length - 1) !== ':') ? s + '.' : s) + name;\r
55756 }\r
55757 me.fullName = name;\r
55758 }\r
55759 return name;\r
55760 },\r
55761 getSession: function() {\r
55762 var owner = this.owner;\r
55763 return owner.isSession ? owner : owner.getSession();\r
55764 },\r
55765 bind: function(callback, scope, options) {\r
55766 var me = this,\r
55767 binding = new Ext.app.bind.Binding(me, callback, scope, options),\r
55768 bindings = (me.bindings || (me.bindings = []));\r
55769 binding.depth = me.depth;\r
55770 bindings.push(binding);\r
55771 return binding;\r
55772 },\r
55773 getValue: function() {\r
55774 return this.isLoading() ? null : this.getRawValue();\r
55775 },\r
55776 graft: function(replacement) {\r
55777 var me = this,\r
55778 bindings = me.bindings,\r
55779 name = me.name,\r
55780 i;\r
55781
55782 me.parent = me.bindings = null;\r
55783 me.destroy();\r
55784
55785 replacement.depth = me.depth;\r
55786 replacement.bindings = bindings;\r
55787 replacement.generation = me.generation + 1;\r
55788 replacement.name = name;\r
55789 replacement.id = me.id;\r
55790 replacement.path = me.path;\r
55791
55792 if (bindings) {\r
55793 for (i = bindings.length; i-- > 0; ) {\r
55794 bindings[i].stub = replacement;\r
55795 }\r
55796 }\r
55797 return replacement;\r
55798 },\r
55799 isDescendantOf: function(item) {\r
55800 for (var parent = this; parent = parent.parent; ) {\r
55801 if (parent === item) {\r
55802 return true;\r
55803 }\r
55804 }\r
55805 return false;\r
55806 },\r
55807 onSchedule: function() {\r
55808
55809
55810
55811
55812 for (var i, len, binding, bindings,\r
55813 p = this.parent; p; p = p.parent) {\r
55814 bindings = p.bindings;\r
55815 if (bindings) {\r
55816 for (i = 0 , len = bindings.length; i < len; ++i) {\r
55817 binding = bindings[i];\r
55818 if (binding.deep && !binding.scheduled) {\r
55819 binding.schedule();\r
55820 }\r
55821 }\r
55822 }\r
55823 }\r
55824 },\r
55825 react: function() {\r
55826 var bindings = this.bindings,\r
55827 binding, i, len;\r
55828 if (bindings) {\r
55829 for (i = 0 , len = bindings.length; i < len; ++i) {\r
55830 binding = bindings[i];\r
55831 if (!binding.scheduled) {\r
55832 binding.schedule();\r
55833 }\r
55834 }\r
55835 }\r
55836 },\r
55837 unbind: function(binding) {\r
55838 var bindings = this.bindings;\r
55839 if (bindings && bindings.length) {\r
55840 Ext.Array.remove(bindings, binding);\r
55841 }\r
55842 },\r
55843 privates: {\r
55844 collect: function() {\r
55845 var children = this.children,\r
55846 bindings = this.bindings,\r
55847 totalCount = 0,\r
55848 count = 0,\r
55849 child, key;\r
55850 if (children) {\r
55851 for (key in children) {\r
55852 child = children[key];\r
55853 count = child.collect();\r
55854 if (count === 0) {\r
55855
55856
55857 child.destroy();\r
55858 delete children[key];\r
55859 }\r
55860 totalCount += count;\r
55861 }\r
55862 }\r
55863 if (bindings) {\r
55864 totalCount += bindings.length;\r
55865 }\r
55866 return totalCount;\r
55867 },\r
55868 getScheduler: function() {\r
55869 var owner = this.owner;\r
55870 return owner && owner.getScheduler();\r
55871 },\r
55872 sort: function() {\r
55873 var parent = this.parent;\r
55874 if (parent) {\r
55875
55876
55877
55878
55879 this.scheduler.sortItem(parent);\r
55880 }\r
55881 }\r
55882 }\r
55883});\r
55884
55885
55886\r
55887\r
55888Ext.define('Ext.app.bind.Stub', {\r
55889 extend: Ext.app.bind.AbstractStub,\r
55890 isStub: true,\r
55891 dirty: true,\r
55892 formula: null,\r
55893 validationKey: 'validation',\r
55894 statics: {\r
55895 trackHadValue: function(value, owner, path, stub) {\r
55896 var children = stub && stub.children,\r
55897 child, key, hadValue;\r
55898
55899
55900
55901 hadValue = value !== undefined;\r
55902 if (!owner.hadValue[path]) {\r
55903 owner.hadValue[path] = hadValue;\r
55904 }\r
55905 if (stub) {\r
55906 stub.hadValue = hadValue;\r
55907 }\r
55908 if (value && (value.constructor === Object || value.isModel)) {\r
55909 if (value.isModel) {\r
55910 value = value.data;\r
55911 }\r
55912 for (key in value) {\r
55913 Ext.app.bind.Stub.trackHadValue(value[key], owner, path + '.' + key, children && children[key]);\r
55914 }\r
55915 }\r
55916 }\r
55917 },\r
55918 constructor: function(owner, name, parent) {\r
55919 var me = this,\r
55920 path = name;\r
55921 me.callParent([\r
55922 owner,\r
55923 name\r
55924 ]);\r
55925 me.boundValue = null;\r
55926 if (parent) {\r
55927 parent.add(me);\r
55928 if (!parent.isRootStub) {\r
55929 path = parent.path + '.' + name;\r
55930 }\r
55931 }\r
55932 me.hadValue = owner.hadValue[path];\r
55933 me.path = path;\r
55934 },\r
55935 destroy: function() {\r
55936 var me = this,\r
55937 formula = me.formula,\r
55938 parent = me.parent,\r
55939 storeBinding = me.storeBinding;\r
55940 if (formula) {\r
55941 formula.destroy();\r
55942 }\r
55943 if (storeBinding) {\r
55944 storeBinding.destroy();\r
55945 }\r
55946 me.detachBound();\r
55947 me.parentValue = me.formula = me.storeBinding = null;\r
55948 me.callParent();\r
55949 },\r
55950 bindValidation: function(callback, scope) {\r
55951 var parent = this.parent;\r
55952 return parent && parent.descend([\r
55953 this.validationKey,\r
55954 this.name\r
55955 ]).bind(callback, scope);\r
55956 },\r
55957 bindValidationField: function(callback, scope) {\r
55958 var parent = this.parent,\r
55959 name = this.name,\r
55960 lateBound = typeof callback === 'string',\r
55961 ret;\r
55962 if (parent) {\r
55963 ret = parent.bind(function(value) {\r
55964 var field = null;\r
55965 if (value && value.isModel) {\r
55966 field = value.getField(name);\r
55967 }\r
55968 if (lateBound) {\r
55969 scope[callback](field, null, this);\r
55970 } else {\r
55971 callback.call(scope, field, null, this);\r
55972 }\r
55973 });\r
55974 }\r
55975 return ret || null;\r
55976 },\r
55977 descend: function(path, index) {\r
55978 var me = this,\r
55979 children = me.children || (me.children = {}),\r
55980 pos = index || 0,\r
55981 name = path[pos++],\r
55982 ret;\r
55983 if (!(ret = children[name])) {\r
55984 ret = new Ext.app.bind.Stub(me.owner, name, me);\r
55985 }\r
55986 if (pos < path.length) {\r
55987 ret = ret.descend(path, pos);\r
55988 }\r
55989 return ret;\r
55990 },\r
55991 getChildValue: function(parentData) {\r
55992 var me = this,\r
55993 name = me.name,\r
55994 ret;\r
55995 if (!parentData && !Ext.isString(parentData)) {\r
55996
55997
55998 ret = me.hadValue ? null : undefined;\r
55999 } else {\r
56000 ret = me.inspectValue(parentData);\r
56001 if (!ret) {\r
56002 if (parentData.isEntity) {\r
56003
56004 ret = parentData.data[name];\r
56005 } else {\r
56006 ret = parentData[name];\r
56007 }\r
56008 }\r
56009 }\r
56010 return ret;\r
56011 },\r
56012 getDataObject: function() {\r
56013 var me = this,\r
56014 parentData = me.parent.getDataObject(),\r
56015
56016 name = me.name,\r
56017 ret = parentData ? parentData[name] : null,\r
56018 associations, association;\r
56019 if (!ret && parentData && parentData.isEntity) {\r
56020
56021 associations = parentData.associations;\r
56022 if (associations && name in associations) {\r
56023 ret = parentData[associations[name].getterName]();\r
56024 }\r
56025 }\r
56026 if (!ret || !(ret.$className || Ext.isObject(ret))) {\r
56027 parentData[name] = ret = {};\r
56028
56029 me.hadValue = me.owner.hadValue[me.path] = true;\r
56030
56031
56032 me.invalidate(true, true);\r
56033 }\r
56034 return ret;\r
56035 },\r
56036 getRawValue: function() {\r
56037
56038
56039 return this.getChildValue(this.getParentValue());\r
56040 },\r
56041 graft: function(replacement) {\r
56042 var me = this,\r
56043 parent = me.parent,\r
56044 children = me.children,\r
56045 name = me.name,\r
56046 i;\r
56047 replacement.parent = parent;\r
56048 replacement.children = children;\r
56049 if (parent) {\r
56050 parent.children[name] = replacement;\r
56051 }\r
56052 if (children) {\r
56053 for (i in children) {\r
56054 children[i].parent = replacement;\r
56055 }\r
56056 }\r
56057 me.children = null;\r
56058 return me.callParent([\r
56059 replacement\r
56060 ]);\r
56061 },\r
56062 isLoading: function() {\r
56063 var me = this,\r
56064 parent = me.parent,\r
56065 loading = false,\r
56066 associations, parentValue, value, loadSet;\r
56067 if (parent && !(loading = parent.isLoading())) {\r
56068 parentValue = me.getParentValue();\r
56069 value = me.inspectValue(parentValue);\r
56070
56071 if (value) {\r
56072 loading = value.isLoading();\r
56073 } else {\r
56074 if (parentValue && parentValue.isModel) {\r
56075 associations = parentValue.associations;\r
56076
56077
56078
56079
56080 if (!(associations && me.name in associations)) {\r
56081 loading = false;\r
56082 loadSet = true;\r
56083 }\r
56084 }\r
56085 if (!loadSet) {\r
56086 loading = !me.hadValue && me.getRawValue() === undefined;\r
56087 }\r
56088 }\r
56089 }\r
56090 return loading;\r
56091 },\r
56092 invalidate: function(deep, dirtyOnly) {\r
56093 var me = this,\r
56094 children = me.children,\r
56095 name;\r
56096 me.dirty = true;\r
56097 if (!dirtyOnly && !me.isLoading()) {\r
56098 if (!me.scheduled) {\r
56099
56100 me.schedule();\r
56101 }\r
56102 }\r
56103 if (deep && children) {\r
56104 for (name in children) {\r
56105 children[name].invalidate(deep, dirtyOnly);\r
56106 }\r
56107 }\r
56108 },\r
56109 isReadOnly: function() {\r
56110 var formula = this.formula;\r
56111 return !!(formula && !formula.set);\r
56112 },\r
56113 set: function(value) {\r
56114 var me = this,\r
56115 parent = me.parent,\r
56116 name = me.name,\r
56117 formula = me.formula,\r
56118 parentData, associations, association, formulaStub;\r
56119 if (formula && !formula.settingValue && formula.set) {\r
56120 formula.setValue(value);\r
56121 return;\r
56122 } else if (me.isLinkStub) {\r
56123 formulaStub = me.getLinkFormulaStub();\r
56124 formula = formulaStub ? formulaStub.formula : null;\r
56125 if (formula) {\r
56126
56127 if (formulaStub.isReadOnly()) {\r
56128 Ext.raise('Cannot setValue on a readonly formula');\r
56129 }\r
56130
56131 formula.setValue(value);\r
56132 return;\r
56133 }\r
56134 }\r
56135
56136 parentData = parent.getDataObject();\r
56137 if (parentData.isEntity) {\r
56138 associations = parentData.associations;\r
56139 if (associations && (name in associations)) {\r
56140 association = associations[name];\r
56141 parentData[association.setterName](value);\r
56142
56143 me.invalidate(true);\r
56144 } else {\r
56145
56146 parentData.set(name, value);\r
56147 }\r
56148 }\r
56149
56150
56151 else if ((value && value.constructor === Object) || value !== parentData[name]) {\r
56152 if (!me.setByLink(value)) {\r
56153 if (value === undefined) {\r
56154 delete parentData[name];\r
56155 } else {\r
56156 parentData[name] = value;\r
56157 Ext.app.bind.Stub.trackHadValue(value, me.owner, me.path, me);\r
56158 }\r
56159 me.inspectValue(parentData);\r
56160
56161
56162 me.invalidate(true);\r
56163 }\r
56164 }\r
56165 },\r
56166 onStoreLoad: function() {\r
56167 this.invalidate(true);\r
56168 },\r
56169 afterLoad: function(record) {\r
56170 this.invalidate(true);\r
56171 },\r
56172 afterCommit: function(record) {\r
56173
56174 this.afterEdit(record, null);\r
56175 },\r
56176 afterEdit: function(record, modifiedFieldNames) {\r
56177 var children = this.children,\r
56178 len = modifiedFieldNames && modifiedFieldNames.length,\r
56179 associations = record.associations,\r
56180 key, i, child, scheduled;\r
56181
56182 if (children) {\r
56183 if (len) {\r
56184
56185 for (i = 0; i < len; ++i) {\r
56186 child = children[modifiedFieldNames[i]];\r
56187 if (child) {\r
56188 child.invalidate();\r
56189 }\r
56190 }\r
56191 } else {\r
56192
56193
56194
56195 for (key in children) {\r
56196 if (!(associations && key in associations)) {\r
56197 children[key].invalidate();\r
56198 }\r
56199 }\r
56200 }\r
56201 }\r
56202 this.invalidate();\r
56203 },\r
56204 afterReject: function(record) {\r
56205
56206 this.afterEdit(record, null);\r
56207 },\r
56208 setByLink: function(value) {\r
56209 var me = this,\r
56210 n = 0,\r
56211 i, link, path, stub;\r
56212 for (stub = me; stub; stub = stub.parent) {\r
56213 if (stub.isLinkStub) {\r
56214 link = stub;\r
56215 if (n) {\r
56216 for (path = [] , i = 0 , stub = me; stub !== link; stub = stub.parent) {\r
56217 ++i;\r
56218 path[n - i] = stub.name;\r
56219 }\r
56220 }\r
56221 break;\r
56222 }\r
56223 ++n;\r
56224 }\r
56225 if (!link || !(stub = link.getTargetStub())) {\r
56226 return false;\r
56227 }\r
56228
56229
56230
56231 if (path) {\r
56232 stub = stub.descend(path);\r
56233 }\r
56234 stub.set(value);\r
56235 return true;\r
56236 },\r
56237 setFormula: function(formula) {\r
56238 var me = this,\r
56239 oldFormula = me.formula;\r
56240 if (oldFormula) {\r
56241 oldFormula.destroy();\r
56242 }\r
56243
56244
56245 me.formula = new Ext.app.bind.Formula(me, formula);\r
56246 },\r
56247 react: function() {\r
56248 var me = this,\r
56249 bound = this.boundValue,\r
56250 children = me.children,\r
56251 generation;\r
56252 if (bound) {\r
56253 if (bound.isValidation) {\r
56254 bound.refresh();\r
56255 generation = bound.generation;\r
56256
56257 if (me.lastValidationGeneration === generation) {\r
56258 return;\r
56259 }\r
56260 me.lastValidationGeneration = generation;\r
56261 } else if (bound.isModel) {\r
56262
56263
56264
56265 if (children && children[me.validationKey]) {\r
56266
56267 bound.isValid();\r
56268 }\r
56269 } else if (bound.isStore) {\r
56270
56271 if (bound.isLoading() && !bound.loadCount) {\r
56272 return;\r
56273 }\r
56274 }\r
56275 }\r
56276 this.callParent();\r
56277 },\r
56278 privates: {\r
56279 collect: function() {\r
56280 var me = this,\r
56281 result = me.callParent(),\r
56282 storeBinding = me.storeBinding ? 1 : 0,\r
56283 formula = me.formula ? 1 : 0;\r
56284 return result + storeBinding + formula;\r
56285 },\r
56286 getLinkFormulaStub: function() {\r
56287
56288
56289
56290 var stub = this;\r
56291 while (stub.isLinkStub) {\r
56292 stub = stub.binding.stub;\r
56293 }\r
56294 return stub.formula ? stub : null;\r
56295 },\r
56296 getParentValue: function() {\r
56297 var me = this;\r
56298
56299
56300 if (me.dirty) {\r
56301 me.parentValue = me.parent.getValue();\r
56302 me.dirty = false;\r
56303 }\r
56304 return me.parentValue;\r
56305 },\r
56306 setStore: function(storeBinding) {\r
56307 this.storeBinding = storeBinding;\r
56308 },\r
56309 inspectValue: function(parentData) {\r
56310 var me = this,\r
56311 name = me.name,\r
56312 current = me.boundValue,\r
56313 boundValue = null,\r
56314 associations, raw, changed, associatedEntity;\r
56315 if (parentData && parentData.isEntity) {\r
56316 associations = parentData.associations;\r
56317 if (associations && (name in associations)) {\r
56318 boundValue = parentData[associations[name].getterName]();\r
56319 if (boundValue && boundValue.isStore) {\r
56320 boundValue.$associatedStore = true;\r
56321 }\r
56322 } else if (name === me.validationKey) {\r
56323 boundValue = parentData.getValidation();\r
56324
56325 me.lastValidationGeneration = null;\r
56326 }\r
56327 } else if (parentData) {\r
56328 raw = parentData[name];\r
56329 if (raw && (raw.isModel || raw.isStore)) {\r
56330 boundValue = raw;\r
56331 }\r
56332 }\r
56333
56334
56335 changed = current !== boundValue;\r
56336 if (changed) {\r
56337 if (current) {\r
56338 me.detachBound();\r
56339 }\r
56340 if (boundValue) {\r
56341 if (boundValue.isModel) {\r
56342 boundValue.join(me);\r
56343 } else {\r
56344
56345
56346 associatedEntity = boundValue.associatedEntity;\r
56347 if (associatedEntity && !associatedEntity.phantom && !boundValue.complete && !boundValue.hasPendingLoad()) {\r
56348 boundValue.load();\r
56349 }\r
56350
56351
56352 boundValue.on('load', me.onStoreLoad, me, {\r
56353 single: true\r
56354 });\r
56355 }\r
56356 }\r
56357 me.boundValue = boundValue;\r
56358 }\r
56359 return boundValue;\r
56360 },\r
56361 detachBound: function() {\r
56362 var me = this,\r
56363 current = me.boundValue;\r
56364 if (current) {\r
56365 if (current.isModel) {\r
56366 current.unjoin(me);\r
56367 } else {\r
56368 current.un('load', me.onStoreLoad, me);\r
56369 }\r
56370 }\r
56371 },\r
56372 sort: function() {\r
56373 var me = this,\r
56374 formula = me.formula,\r
56375 scheduler = me.scheduler,\r
56376 storeBinding = me.storeBinding;\r
56377 me.callParent();\r
56378 if (storeBinding) {\r
56379 scheduler.sortItem(storeBinding);\r
56380 }\r
56381 if (formula) {\r
56382
56383
56384
56385 scheduler.sortItem(formula);\r
56386 }\r
56387 }\r
56388 }\r
56389});\r
56390\r
56391\r
56392Ext.define('Ext.app.bind.LinkStub', {\r
56393 extend: Ext.app.bind.Stub,\r
56394 isLinkStub: true,\r
56395 binding: null,\r
56396 destroy: function() {\r
56397 var me = this,\r
56398 binding = me.binding,\r
56399 owner = me.owner;\r
56400 if (binding) {\r
56401 me.binding = null;\r
56402 binding.destroy();\r
56403 if (owner) {\r
56404 delete owner.linkData[me.name];\r
56405 }\r
56406 }\r
56407 me.target = null;\r
56408 me.callParent();\r
56409 },\r
56410 getFullName: function() {\r
56411 var me = this;\r
56412 return me.fullName || (me.fullName = '(' + me.callParent() + ' -> ' + me.binding.getFullName() + ')');\r
56413 },\r
56414 getDataObject: function() {\r
56415 var binding = this.binding;\r
56416 return binding && binding.getDataObject();\r
56417 },\r
56418 getRawValue: function() {\r
56419 var binding = this.binding;\r
56420 return binding && binding.getRawValue();\r
56421 },\r
56422 getValue: function() {\r
56423 var binding = this.binding;\r
56424 return binding && binding.getValue();\r
56425 },\r
56426 getTargetStub: function() {\r
56427 var binding = this.binding;\r
56428 return binding && binding.stub;\r
56429 },\r
56430 isLoading: function() {\r
56431 var binding = this.binding;\r
56432 return binding ? binding.isLoading() : false;\r
56433 },\r
56434 link: function(bindDescriptor, target) {\r
56435 var me = this,\r
56436 binding = me.binding;\r
56437 if (binding) {\r
56438 binding.destroy();\r
56439 }\r
56440 target = me.target = target || me.owner;\r
56441 me.linkDescriptor = bindDescriptor;\r
56442 me.binding = target.bind(bindDescriptor, me.onChange, me);\r
56443 me.binding.deep = true;\r
56444 },\r
56445 onChange: function() {\r
56446 this.invalidate(true);\r
56447 },\r
56448 react: function() {\r
56449 var me = this,\r
56450 linkData = me.owner.linkData;\r
56451 linkData[me.name] = me.getValue();\r
56452 me.callParent();\r
56453 },\r
56454 privates: {\r
56455 collect: function() {\r
56456 var me = this,\r
56457 result = me.callParent(),\r
56458 binding = me.binding ? 1 : 0;\r
56459 return result + binding;\r
56460 },\r
56461 sort: function() {\r
56462 var binding = this.binding;\r
56463 if (binding) {\r
56464
56465
56466 this.scheduler.sortItem(binding);\r
56467 }\r
56468 }\r
56469 }\r
56470});\r
56471\r
56472\r
56473Ext.define('Ext.app.bind.RootStub', {\r
56474 extend: Ext.app.bind.AbstractStub,\r
56475 isRootStub: true,\r
56476 depth: 0,\r
56477 createRootChild: function(name, direct) {\r
56478 var me = this,\r
56479 owner = me.owner,\r
56480 ownerData = owner.getData(),\r
56481 children = me.children,\r
56482 previous = children && children[name],\r
56483 parentStub = previous ? null : me,\r
56484 parentVM, stub;\r
56485 if (direct || ownerData.hasOwnProperty(name) || !(parentVM = owner.getParent())) {\r
56486 stub = new Ext.app.bind.Stub(owner, name, parentStub);\r
56487 } else {\r
56488 stub = new Ext.app.bind.LinkStub(owner, name, previous ? null : parentStub);\r
56489 stub.link('{' + name + '}', parentVM);\r
56490 }\r
56491 if (previous) {\r
56492 previous.graft(stub);\r
56493 }\r
56494 return stub;\r
56495 },\r
56496 createStubChild: function(name) {\r
56497 return this.createRootChild(name, true);\r
56498 },\r
56499 descend: function(path, index) {\r
56500 var me = this,\r
56501 children = me.children,\r
56502 pos = index || 0,\r
56503 name = path[pos++],\r
56504 ret = (children && children[name]) || me.createRootChild(name);\r
56505 if (pos < path.length) {\r
56506 ret = ret.descend(path, pos);\r
56507 }\r
56508 return ret;\r
56509 },\r
56510 getFullName: function() {\r
56511 return this.fullName || (this.fullName = this.owner.id + ':');\r
56512 },\r
56513
56514 getDataObject: function() {\r
56515 return this.owner.data;\r
56516 },\r
56517 getRawValue: function() {\r
56518 return this.owner.data;\r
56519 },\r
56520 getValue: function() {\r
56521 return this.owner.data;\r
56522 },\r
56523 isDescendantOf: function() {\r
56524 return false;\r
56525 },\r
56526 isLoading: function() {\r
56527 return false;\r
56528 },\r
56529 set: function(value) {\r
56530
56531 if (!value || value.constructor !== Object) {\r
56532 Ext.raise('Only an object can be set at the root');\r
56533 }\r
56534
56535 var me = this,\r
56536 children = me.children || (me.children = {}),\r
56537 owner = me.owner,\r
56538 data = owner.data,\r
56539 parentVM = owner.getParent(),\r
56540 linkStub, stub, v, key;\r
56541 for (key in value) {\r
56542
56543 if (key.indexOf('.') >= 0) {\r
56544 Ext.raise('Value names cannot contain dots');\r
56545 }\r
56546
56547 if ((v = value[key]) !== undefined) {\r
56548 if (!(stub = children[key])) {\r
56549 stub = new Ext.app.bind.Stub(owner, key, me);\r
56550 } else if (stub.isLinkStub) {\r
56551 if (!stub.getLinkFormulaStub()) {\r
56552
56553 linkStub = stub;\r
56554 stub = new Ext.app.bind.Stub(owner, key);\r
56555 linkStub.graft(stub);\r
56556 }\r
56557 }\r
56558 stub.set(v);\r
56559 } else if (data.hasOwnProperty(key)) {\r
56560 delete data[key];\r
56561 stub = children[key];\r
56562 if (stub && !stub.isLinkStub && parentVM) {\r
56563 stub = me.createRootChild(key);\r
56564 }\r
56565 stub.invalidate(true);\r
56566 }\r
56567 }\r
56568 },\r
56569 schedule: Ext.emptyFn,\r
56570 unschedule: Ext.emptyFn\r
56571});\r
56572\r
56573\r
56574Ext.define('Ext.app.bind.Multi', {\r
56575 extend: Ext.app.bind.BaseBinding,\r
56576 isMultiBinding: true,\r
56577 missing: 1,\r
56578
56579
56580
56581
56582 deep: true,\r
56583 \r
56584 constructor: function(descriptor, owner, callback, scope, options) {\r
56585 var me = this,\r
56586 trackStatics = options && options.trackStatics;\r
56587 me.callParent([\r
56588 owner,\r
56589 callback,\r
56590 scope,\r
56591 options\r
56592 ]);\r
56593 me.bindings = [];\r
56594 me.literal = descriptor.$literal;\r
56595 if (descriptor.constructor === Object) {\r
56596 if (trackStatics) {\r
56597 me.staticKeys = [];\r
56598 }\r
56599 me.addObject(descriptor, me.lastValue = {}, me.staticKeys);\r
56600 } else {\r
56601 me.addArray(descriptor, me.lastValue = []);\r
56602 }\r
56603
56604
56605
56606 if (!--me.missing && !me.scheduled) {\r
56607 me.schedule();\r
56608 }\r
56609 },\r
56610 destroy: function() {\r
56611 var me = this;\r
56612 me.bindings = Ext.destroy(me.bindings);\r
56613 me.callParent();\r
56614 },\r
56615 add: function(descriptor, data, property) {\r
56616 var me = this,\r
56617 owner = me.owner,\r
56618 bindings = me.bindings,\r
56619 method = me.literal ? (descriptor.reference ? 'bindEntity' : 'bindExpression') : 'bind',\r
56620 binding, depth;\r
56621 ++me.missing;\r
56622 binding = owner[method](descriptor, function(value) {\r
56623 data[property] = value;\r
56624 if (binding.calls === 1) {\r
56625 --me.missing;\r
56626 }\r
56627 if (!me.missing && !me.scheduled) {\r
56628 me.schedule();\r
56629 }\r
56630 },
56631 me, null);\r
56632 depth = binding.depth;\r
56633 if (!bindings.length || depth < me.depth) {\r
56634 me.depth = depth;\r
56635 }\r
56636 bindings.push(binding);\r
56637 return !this.isBindingStatic(binding);\r
56638 },\r
56639 addArray: function(multiBindDescr, array) {\r
56640 var me = this,\r
56641 n = multiBindDescr.length,\r
56642 hasDynamic = false,\r
56643 dynamic, b, i;\r
56644 for (i = 0; i < n; ++i) {\r
56645 b = multiBindDescr[i];\r
56646 if (b && (b.reference || Ext.isString(b))) {\r
56647 dynamic = me.add(b, array, i);\r
56648 } else if (Ext.isArray(b)) {\r
56649 dynamic = me.addArray(b, array[i] = []);\r
56650 } else if (b && b.constructor === Object) {\r
56651 dynamic = me.addObject(b, array[i] = {});\r
56652 } else {\r
56653 array[i] = b;\r
56654 dynamic = false;\r
56655 }\r
56656 hasDynamic = hasDynamic || dynamic;\r
56657 }\r
56658 return hasDynamic;\r
56659 },\r
56660 addObject: function(multiBindDescr, object, staticKeys) {\r
56661 var me = this,\r
56662 hasDynamic = false,\r
56663 dynamic, b, name;\r
56664 for (name in multiBindDescr) {\r
56665 b = multiBindDescr[name];\r
56666 if (b && (b.reference || Ext.isString(b))) {\r
56667 dynamic = me.add(b, object, name);\r
56668 } else if (Ext.isArray(b)) {\r
56669 dynamic = me.addArray(b, object[name] = []);\r
56670 } else if (b && b.constructor === Object) {\r
56671 dynamic = me.addObject(b, object[name] = {});\r
56672 } else {\r
56673 object[name] = b;\r
56674 dynamic = false;\r
56675 }\r
56676 if (staticKeys && !dynamic) {\r
56677 staticKeys.push(name);\r
56678 }\r
56679 hasDynamic = hasDynamic || dynamic;\r
56680 }\r
56681 return hasDynamic;\r
56682 },\r
56683 getFullName: function() {\r
56684 var me = this,\r
56685 fullName = me.fullName,\r
56686 bindings = me.bindings,\r
56687 length = bindings.length,\r
56688 i;\r
56689 if (!fullName) {\r
56690 fullName = '@[';\r
56691 for (i = 0; i < length; ++i) {\r
56692 if (i) {\r
56693 fullName += ',';\r
56694 }\r
56695 fullName += bindings[i].getFullName();\r
56696 }\r
56697 fullName += ']';\r
56698 me.fullName = fullName;\r
56699 }\r
56700 return fullName;\r
56701 },\r
56702 getRawValue: function() {\r
56703 return this.lastValue;\r
56704 },\r
56705 isDescendantOf: function() {\r
56706 return false;\r
56707 },\r
56708 isLoading: function() {\r
56709 for (var bindings = this.bindings,\r
56710 n = bindings.length; n-- > 0; ) {\r
56711 if (bindings[n].isLoading()) {\r
56712 return true;\r
56713 }\r
56714 }\r
56715 return false;\r
56716 },\r
56717 isBindingStatic: function(binding) {\r
56718 return binding.isTemplateBinding && binding.isStatic;\r
56719 },\r
56720 isStatic: function() {\r
56721 var bindings = this.bindings,\r
56722 len = bindings.length,\r
56723 i, binding;\r
56724 for (i = 0; i < len; ++i) {\r
56725 binding = bindings[i];\r
56726 if (!this.isBindingStatic(binding)) {\r
56727 return false;\r
56728 }\r
56729 }\r
56730 return true;\r
56731 },\r
56732 pruneStaticKeys: function() {\r
56733 var value = Ext.apply({}, this.lastValue),\r
56734 keys = this.staticKeys,\r
56735 len = keys.length,\r
56736 i;\r
56737 for (i = 0; i < len; ++i) {\r
56738 delete value[keys[i]];\r
56739 }\r
56740 return value;\r
56741 },\r
56742 react: function() {\r
56743 this.notify(this.lastValue);\r
56744 },\r
56745 refresh: function() {},\r
56746
56747 privates: {\r
56748 sort: function() {\r
56749 this.scheduler.sortItems(this.bindings);\r
56750 }\r
56751 }\r
56752});\r
56753
56754
56755\r
56756\r
56757Ext.define('Ext.app.bind.Formula', {\r
56758 extend: Ext.util.Schedulable,\r
56759 statics: {\r
56760 getFormulaParser: function(name) {\r
56761 var cache = this.formulaCache,\r
56762 parser, s;\r
56763 if (!cache) {\r
56764 cache = this.formulaCache = new Ext.util.LruCache({\r
56765 maxSize: 20\r
56766 });\r
56767 }\r
56768 parser = cache.get(name);\r
56769 if (!parser) {\r
56770
56771 s = '[^\\.a-z0-9_]' + name + '\\(\\s*([\'"])(.*?)\\1\\s*\\)';\r
56772 parser = new RegExp(s, 'gi');\r
56773 cache.add(name, parser);\r
56774 }\r
56775 return parser;\r
56776 }\r
56777 },\r
56778 isFormula: true,\r
56779 calculation: null,\r
56780 explicit: false,\r
56781 \r
56782 \r
56783 \r
56784 set: null,\r
56785 \r
56786 single: false,\r
56787 argumentNamesRe: /^function\s*\(\s*([^,\)\s]+)/,\r
56788 constructor: function(stub, formula) {\r
56789 var me = this,\r
56790 owner = stub.owner,\r
56791 bindTo, expressions, getter, options;\r
56792 me.owner = owner;\r
56793 me.stub = stub;\r
56794 me.callParent();\r
56795 if (formula instanceof Function) {\r
56796 me.get = getter = formula;\r
56797 } else {\r
56798 me.get = getter = formula.get;\r
56799 me.set = formula.set;\r
56800 expressions = formula.bind;\r
56801 if (formula.single) {\r
56802 me.single = formula.single;\r
56803 }\r
56804 if (expressions) {\r
56805 bindTo = expressions.bindTo;\r
56806 if (bindTo) {\r
56807 options = Ext.apply({}, expressions);\r
56808 delete options.bindTo;\r
56809 expressions = bindTo;\r
56810 }\r
56811 }\r
56812 }\r
56813
56814 if (!getter) {\r
56815 Ext.raise('Must specify a getter method for a formula');\r
56816 }\r
56817
56818 if (expressions) {\r
56819 me.explicit = true;\r
56820 } else {\r
56821 expressions = getter.$expressions || me.parseFormula(getter);\r
56822 }\r
56823 me.binding = owner.bind(expressions, me.onChange, me, options);\r
56824 },\r
56825 destroy: function() {\r
56826 var me = this,\r
56827 binding = me.binding,\r
56828 stub = me.stub;\r
56829 if (binding) {\r
56830 binding.destroy();\r
56831 me.binding = null;\r
56832 }\r
56833 if (stub) {\r
56834 stub.formula = null;\r
56835 }\r
56836 me.callParent();\r
56837
56838 me.getterFn = me.owner = null;\r
56839 },\r
56840 getFullName: function() {\r
56841 return this.fullName || (this.fullName = this.stub.getFullName() + '=' + this.callParent() + ')');\r
56842 },\r
56843 getRawValue: function() {\r
56844 return this.calculation;\r
56845 },\r
56846 onChange: function() {\r
56847 if (!this.scheduled) {\r
56848 this.schedule();\r
56849 }\r
56850 },\r
56851 parseFormula: function(formula) {\r
56852 var str = formula.toString(),\r
56853 expressions = {\r
56854 $literal: true\r
56855 },\r
56856 match, getterProp, formulaRe, expr;\r
56857 match = this.argumentNamesRe.exec(str);\r
56858 getterProp = match ? match[1] : 'get';\r
56859 formulaRe = Ext.app.bind.Formula.getFormulaParser(getterProp);\r
56860 while ((match = formulaRe.exec(str))) {\r
56861 expr = match[2];\r
56862 expressions[expr] = expr;\r
56863 }\r
56864 expressions.$literal = true;\r
56865
56866
56867 formula.$expressions = expressions;\r
56868 return expressions;\r
56869 },\r
56870 react: function() {\r
56871 var me = this,\r
56872 owner = me.owner,\r
56873 data = me.binding.lastValue,\r
56874 getterFn = me.getterFn,\r
56875 arg;\r
56876 if (me.explicit) {\r
56877 arg = data;\r
56878 } else {\r
56879 arg = owner.getFormulaFn(data);\r
56880 }\r
56881 me.settingValue = true;\r
56882 me.stub.set(me.calculation = me.get.call(owner, arg));\r
56883 me.settingValue = false;\r
56884 if (me.single) {\r
56885 me.destroy();\r
56886 }\r
56887 },\r
56888 setValue: function(value) {\r
56889 this.set.call(this.stub.owner, value);\r
56890 },\r
56891 privates: {\r
56892 getScheduler: function() {\r
56893 var owner = this.owner;\r
56894 return owner && owner.getScheduler();\r
56895 },\r
56896 sort: function() {\r
56897 var me = this,\r
56898 binding = me.binding;\r
56899
56900 if (!binding.destroyed) {\r
56901 me.scheduler.sortItem(binding);\r
56902 }\r
56903 }\r
56904 }\r
56905});\r
56906
56907
56908\r
56909\r
56910Ext.define('Ext.app.bind.Template', {\r
56911 numberRe: /^(?:\d+(?:\.\d*)?)$/,\r
56912 stringRe: /^(?:["][^"]*["])$/,\r
56913 \r
56914 tokenRe: /\{[!]?(?:(?:(\d+)|([a-z_][\w\-\.]*))(?::([a-z_\.]+)(?:\(([^\)]*?)?\))?)?)\}/gi,\r
56915 formatRe: /^([a-z_]+)(?:\(([^\)]*?)?\))?$/i,\r
56916 \r
56917 buffer: null,\r
56918 \r
56919 slots: null,\r
56920 \r
56921 tokens: null,\r
56922 \r
56923 constructor: function(text) {\r
56924 var me = this,\r
56925 initters = me._initters,\r
56926 name;\r
56927 me.text = text;\r
56928 for (name in initters) {\r
56929 me[name] = initters[name];\r
56930 }\r
56931 },\r
56932 \r
56933 _initters: {\r
56934 apply: function(values, scope) {\r
56935 return this.parse().apply(values, scope);\r
56936 },\r
56937 getTokens: function() {\r
56938 return this.parse().getTokens();\r
56939 }\r
56940 },\r
56941 \r
56942 apply: function(values, scope) {\r
56943 var me = this,\r
56944 slots = me.slots,\r
56945 buffer = me.buffer,\r
56946 length = slots.length,\r
56947
56948 i, slot, value;\r
56949 for (i = 0; i < length; ++i) {\r
56950 slot = slots[i];\r
56951 if (slot) {\r
56952 if ((value = values[slot.pos]) == null) {\r
56953
56954 value = '';\r
56955 }\r
56956 if (slot.not) {\r
56957 value = !value;\r
56958 }\r
56959 if (slot.format) {\r
56960 value = slot.format(value, scope);\r
56961 }\r
56962 buffer[i] = value;\r
56963 }\r
56964 }\r
56965 return buffer.join('');\r
56966 },\r
56967 \r
56968 getTokens: function() {\r
56969 return this.tokens;\r
56970 },\r
56971 \r
56972 parse: function() {\r
56973
56974
56975 var me = this,\r
56976 text = me.text,\r
56977 buffer = [],\r
56978 slots = [],\r
56979 tokens = [],\r
56980 tokenMap = {},\r
56981 last = 0,\r
56982 tokenRe = me.tokenRe,\r
56983 pos = 0,\r
56984 fmt, i, length, match, s, slot, token;\r
56985
56986 for (i in me._initters) {\r
56987 delete me[i];\r
56988 }\r
56989 me.buffer = buffer;\r
56990 me.slots = slots;\r
56991 me.tokens = tokens;\r
56992
56993 while ((match = tokenRe.exec(text))) {\r
56994
56995
56996
56997
56998 length = match.index - last;\r
56999 if (length) {\r
57000 buffer[pos++] = text.substring(last, last + length);\r
57001 last += length;\r
57002 }\r
57003 last += (s = match[0]).length;\r
57004 slot = {\r
57005 fmt: (fmt = match[3] || null),\r
57006 index: match[1] ? parseInt(match[1], 10) : null,\r
57007 not: s.charAt(1) === '!',\r
57008 token: match[2] || null\r
57009 };\r
57010 token = slot.token || String(slot.index);\r
57011 if (token in tokenMap) {\r
57012 slot.pos = tokenMap[token];\r
57013 } else {\r
57014 tokenMap[token] = slot.pos = tokens.length;\r
57015 tokens.push(token);\r
57016 }\r
57017 if (fmt) {\r
57018 if (fmt.substring(0, 5) === 'this.') {\r
57019 slot.fmt = fmt.substring(5);\r
57020 } else {\r
57021
57022 if (!(fmt in Ext.util.Format)) {\r
57023 Ext.raise('Invalid format specified: "' + fmt + '"');\r
57024 }\r
57025
57026 slot.scope = Ext.util.Format;\r
57027 }\r
57028 me.parseArgs(match[4], slot);\r
57029 }\r
57030 slots[pos++] = slot;\r
57031 }\r
57032 if (last < text.length) {\r
57033 buffer[pos++] = text.substring(last);\r
57034 }\r
57035 return me;\r
57036 },\r
57037 parseArgs: function(argsString, slot) {\r
57038 var me = this,\r
57039 numberRe = me.numberRe,\r
57040 stringRe = me.stringRe,\r
57041 arg, args, i, length;\r
57042 if (!argsString) {\r
57043 args = [];\r
57044 } else if (argsString.indexOf(',') < 0) {\r
57045 args = [\r
57046 argsString\r
57047 ];\r
57048 } else {\r
57049 args = argsString.split(',');\r
57050 }\r
57051 slot = slot || {};\r
57052 length = args.length;\r
57053 slot.args = args;\r
57054 for (i = 0; i < length; ++i) {\r
57055 arg = args[i];\r
57056 if (arg === 'true') {\r
57057 args[i] = true;\r
57058 } else if (arg === 'false') {\r
57059 args[i] = false;\r
57060 } else if (arg === 'null') {\r
57061 args[i] = null;\r
57062 } else if (numberRe.test(arg)) {\r
57063 args[i] = parseFloat(arg);\r
57064 } else if (stringRe.test(arg)) {\r
57065 args[i] = arg.substring(1, arg.length - 1);\r
57066 } else {\r
57067 slot.fn = Ext.functionFactory('return [' + argsString + '];');\r
57068 slot.format = me._formatEval;\r
57069 break;\r
57070 }\r
57071 }\r
57072 if (!slot.format) {\r
57073
57074 args.unshift(0);\r
57075 slot.format = me._formatArgs;\r
57076 }\r
57077 return slot;\r
57078 },\r
57079 \r
57080 parseFormat: function(fmt) {\r
57081 var me = this,\r
57082 match = me.formatRe.exec(fmt),\r
57083 slot = {\r
57084 fmt: fmt,\r
57085 scope: Ext.util.Format\r
57086 },\r
57087 args;\r
57088
57089 if (!match) {\r
57090 Ext.raise('Invalid format syntax: "' + slot + '"');\r
57091 }\r
57092
57093 args = match[2];\r
57094 if (args) {\r
57095 slot.fmt = match[1];\r
57096 me.parseArgs(args, slot);\r
57097 } else {\r
57098 slot.args = [\r
57099 0\r
57100 ];\r
57101
57102 slot.format = me._formatArgs;\r
57103 }\r
57104 return slot;\r
57105 },\r
57106 \r
57107 _formatArgs: function(value, scope) {\r
57108
57109 scope = this.scope || scope;\r
57110 this.args[0] = value;\r
57111
57112 return scope[this.fmt].apply(scope, this.args);\r
57113 },\r
57114 \r
57115 _formatEval: function(value, scope) {\r
57116
57117 var args = this.fn();\r
57118
57119 args.unshift(value);\r
57120
57121 scope = this.scope || scope;\r
57122 return scope[this.fmt].apply(scope, args);\r
57123 }\r
57124});\r
57125\r
57126\r
57127Ext.define('Ext.app.bind.TemplateBinding', {\r
57128 extend: Ext.app.bind.BaseBinding,\r
57129 isTemplateBinding: true,\r
57130 lastValue: undefined,\r
57131 value: undefined,\r
57132 constructor: function(template, owner, callback, scope, options) {\r
57133 var me = this,\r
57134 tpl = new Ext.app.bind.Template(template),\r
57135 tokens = tpl.getTokens();\r
57136 me.callParent([\r
57137 owner,\r
57138 callback,\r
57139 scope,\r
57140 options\r
57141 ]);\r
57142 me.tpl = tpl;\r
57143 me.tokens = tokens;\r
57144 tokens.$literal = true;\r
57145
57146 if (tokens.length) {\r
57147 me.multiBinding = new Ext.app.bind.Multi(tokens, owner, me.onBindData, me);\r
57148 } else {\r
57149 me.isStatic = true;\r
57150 me.onData(tpl.text);\r
57151 }\r
57152 },\r
57153 destroy: function() {\r
57154 var me = this;\r
57155 Ext.destroy(me.multiBinding);\r
57156 me.tpl = me.multiBinding = null;\r
57157 me.callParent();\r
57158 },\r
57159 getFullName: function() {\r
57160 var multi = this.multiBinding;\r
57161 return this.fullName || (this.fullName = '$' + (multi ? multi.getFullName() : this.callParent()));\r
57162 },\r
57163 getRawValue: function() {\r
57164 return this.value;\r
57165 },\r
57166 getTemplateScope: function() {\r
57167 return null;\r
57168 },\r
57169 isDescendantOf: function() {\r
57170 return false;\r
57171 },\r
57172 isLoading: function() {\r
57173 var multi = this.multiBinding;\r
57174 return multi ? multi.isLoading() : false;\r
57175 },\r
57176 onBindData: function(data) {\r
57177 this.onData(this.tpl.apply(data, this.getTemplateScope()));\r
57178 },\r
57179 onData: function(value) {\r
57180 var me = this,\r
57181 lastValue = me.value;\r
57182 if (lastValue !== (me.value = value)) {\r
57183 me.lastValue = lastValue;\r
57184 me.schedule();\r
57185 }\r
57186 },\r
57187 react: function() {\r
57188 this.notify(this.value);\r
57189 },\r
57190 refresh: function() {\r
57191 var multi = this.multiBinding;\r
57192 if (multi) {\r
57193 multi.refresh();\r
57194 }\r
57195 },\r
57196 privates: {\r
57197 sort: function() {\r
57198 var multi = this.multiBinding;\r
57199 if (multi) {\r
57200 this.scheduler.sortItem(multi);\r
57201 }\r
57202 }\r
57203 }\r
57204});\r
57205
57206
57207\r
57208\r
57209Ext.define('Ext.data.ChainedStore', {\r
57210 extend: Ext.data.AbstractStore,\r
57211 alias: 'store.chained',\r
57212 config: {\r
57213 \r
57214 source: null,\r
57215 \r
57216 remoteFilter: false,\r
57217 \r
57218 remoteSort: false\r
57219 },\r
57220 mixins: [\r
57221 Ext.data.LocalStore\r
57222 ],\r
57223 constructor: function() {\r
57224 this.callParent(arguments);\r
57225 this.getData().addObserver(this);\r
57226 },\r
57227
57228 updateRemoteFilter: function(remoteFilter, oldRemoteFilter) {\r
57229 if (remoteFilter) {\r
57230 Ext.raise('Remote filtering cannot be used with chained stores.');\r
57231 }\r
57232 this.callParent([\r
57233 remoteFilter,\r
57234 oldRemoteFilter\r
57235 ]);\r
57236 },\r
57237 updateRemoteSort: function(remoteSort, oldRemoteSort) {\r
57238 if (remoteSort) {\r
57239 Ext.raise('Remote sorting cannot be used with chained stores.');\r
57240 }\r
57241 this.callParent([\r
57242 remoteSort,\r
57243 oldRemoteSort\r
57244 ]);\r
57245 },\r
57246
57247 remove: function() {\r
57248 var source = this.getSource();\r
57249 return source.remove.apply(source, arguments);\r
57250 },\r
57251 removeAll: function() {\r
57252 var source = this.getSource();\r
57253 return source.removeAll();\r
57254 },\r
57255 getData: function() {\r
57256 var me = this,\r
57257 data = me.data;\r
57258 if (!data) {\r
57259 me.data = data = me.constructDataCollection();\r
57260 }\r
57261 return data;\r
57262 },\r
57263 getSession: function() {\r
57264 return this.getSource().getSession();\r
57265 },\r
57266 applySource: function(source) {\r
57267 if (source) {\r
57268
57269 var original = source,\r
57270 s;\r
57271
57272 source = Ext.data.StoreManager.lookup(source);\r
57273
57274 if (!source) {\r
57275 s = 'Invalid source {0}specified for Ext.data.ChainedStore';\r
57276 s = Ext.String.format(s, typeof original === 'string' ? '"' + original + '" ' : '');\r
57277 Ext.raise(s);\r
57278 }\r
57279 }\r
57280
57281 return source;\r
57282 },\r
57283 updateSource: function(source, oldSource) {\r
57284 var me = this,\r
57285 data;\r
57286 if (oldSource) {\r
57287 oldSource.removeObserver(me);\r
57288 }\r
57289 if (source) {\r
57290 data = me.getData();\r
57291 data.setSource(source.getData());\r
57292 if (!me.isInitializing) {\r
57293 me.fireEvent('refresh', me);\r
57294 me.fireEvent('datachanged', me);\r
57295 }\r
57296 source.addObserver(me);\r
57297 }\r
57298 },\r
57299 \r
57300 getModel: function() {\r
57301 return this.getSource().getModel();\r
57302 },\r
57303 getProxy: function() {\r
57304 return null;\r
57305 },\r
57306 onCollectionAdd: function(collection, info) {\r
57307 var me = this,\r
57308 records = info.items,\r
57309 lastChunk = !info.next;\r
57310 if (me.ignoreCollectionAdd) {\r
57311 return;\r
57312 }\r
57313 me.fireEvent('add', me, records, info.at);\r
57314
57315
57316
57317 if (lastChunk) {\r
57318 me.fireEvent('datachanged', me);\r
57319 }\r
57320 },\r
57321
57322 onCollectionItemChange: function(collection, info) {\r
57323 var me = this,\r
57324 record = info.item,\r
57325 modifiedFieldNames = info.modified || null,\r
57326 type = info.meta;\r
57327
57328
57329
57330 me.onUpdate(record, type, modifiedFieldNames, info);\r
57331 me.fireEvent('update', me, record, type, modifiedFieldNames, info);\r
57332 },\r
57333 onUpdate: Ext.emptyFn,\r
57334 onCollectionRemove: function(collection, info) {\r
57335 var me = this,\r
57336 records = info.items,\r
57337 lastChunk = !info.next;\r
57338 if (me.ignoreCollectionRemove) {\r
57339 return;\r
57340 }\r
57341 me.fireEvent('remove', me, records, info.at, false);\r
57342
57343
57344
57345 if (lastChunk) {\r
57346 me.fireEvent('datachanged', me);\r
57347 }\r
57348 },\r
57349 onSourceBeforeLoad: function(source, operation) {\r
57350 this.fireEvent('beforeload', this, operation);\r
57351 },\r
57352 onSourceAfterLoad: function(source, records, successful, operation) {\r
57353 this.fireEvent('load', this, records, successful, operation);\r
57354 },\r
57355 onFilterEndUpdate: function() {\r
57356 this.callParent(arguments);\r
57357 this.callObservers('Filter');\r
57358 },\r
57359 onSourceBeforePopulate: function() {\r
57360 this.ignoreCollectionAdd = true;\r
57361 this.callObservers('BeforePopulate');\r
57362 },\r
57363 onSourceAfterPopulate: function() {\r
57364 var me = this;\r
57365 me.ignoreCollectionAdd = false;\r
57366 me.fireEvent('datachanged', me);\r
57367 me.fireEvent('refresh', me);\r
57368 this.callObservers('AfterPopulate');\r
57369 },\r
57370 onSourceBeforeClear: function() {\r
57371 this.ignoreCollectionRemove = true;\r
57372 this.callObservers('BeforeClear');\r
57373 },\r
57374 onSourceAfterClear: function() {\r
57375 this.ignoreCollectionRemove = false;\r
57376 this.callObservers('AfterClear');\r
57377 },\r
57378 onSourceBeforeRemoveAll: function() {\r
57379 this.ignoreCollectionRemove = true;\r
57380 this.callObservers('BeforeRemoveAll');\r
57381 },\r
57382 onSourceAfterRemoveAll: function(source, silent) {\r
57383 var me = this;\r
57384 me.ignoreCollectionRemove = false;\r
57385 if (!silent) {\r
57386 me.fireEvent('clear', me);\r
57387 me.fireEvent('datachanged', me);\r
57388 }\r
57389 this.callObservers('AfterRemoveAll', [\r
57390 silent\r
57391 ]);\r
57392 },\r
57393 onSourceFilter: function() {\r
57394 var me = this;\r
57395 me.fireEvent('refresh', me);\r
57396 me.fireEvent('datachanged', me);\r
57397 },\r
57398 hasPendingLoad: function() {\r
57399 return this.getSource().hasPendingLoad();\r
57400 },\r
57401 isLoaded: function() {\r
57402 return this.getSource().isLoaded();\r
57403 },\r
57404 isLoading: function() {\r
57405 return this.getSource().isLoading();\r
57406 },\r
57407 onDestroy: function() {\r
57408 var me = this;\r
57409 me.observers = null;\r
57410 me.setSource(null);\r
57411 me.getData().destroy(true);\r
57412 me.data = null;\r
57413 },\r
57414 privates: {\r
57415 isMoving: function() {\r
57416 var source = this.getSource();\r
57417 return source.isMoving ? source.isMoving.apply(source, arguments) : false;\r
57418 },\r
57419 loadsSynchronously: function() {\r
57420 return this.getSource().loadsSynchronously();\r
57421 }\r
57422 }\r
57423});\r
57424
57425\r
57426\r
57427\r
57428\r
57429\r
57430\r
57431\r
57432\r
57433\r
57434\r
57435\r
57436\r
57437\r
57438\r
57439\r
57440\r
57441\r
57442\r
57443\r
57444\r
57445Ext.define('Ext.app.ViewModel', {\r
57446 mixins: [\r
57447 Ext.mixin.Factoryable,\r
57448 Ext.mixin.Identifiable\r
57449 ],\r
57450 alias: 'viewmodel.default',\r
57451
57452 isViewModel: true,\r
57453 factoryConfig: {\r
57454 name: 'viewModel'\r
57455 },\r
57456 collectTimeout: 100,\r
57457 expressionRe: /^(?:\{[!]?(?:(\d+)|([a-z_][\w\-\.]*))\})$/i,\r
57458 $configStrict: false,\r
57459
57460 config: {\r
57461 \r
57462 data: true,\r
57463 \r
57464 formulas: {\r
57465 $value: null,\r
57466 merge: function(newValue, currentValue, target, mixinClass) {\r
57467 return this.mergeNew(newValue, currentValue, target, mixinClass);\r
57468 }\r
57469 },\r
57470 \r
57471 links: null,\r
57472 \r
57473 parent: null,\r
57474 \r
57475 root: true,\r
57476 \r
57477 scheduler: null,\r
57478 \r
57479 schema: 'default',\r
57480 \r
57481 session: null,\r
57482
57483 \r
57484 stores: null,\r
57485 \r
57486 view: null\r
57487 },\r
57488 constructor: function(config) {\r
57489 this.hadValue = {};\r
57490
57491 this.bindings = {};\r
57492 \r
57493 this.initConfig(config);\r
57494 },\r
57495 destroy: function() {\r
57496 var me = this,\r
57497 scheduler = me._scheduler,\r
57498 stores = me.storeInfo,\r
57499 parent = me.getParent(),\r
57500 task = me.collectTask,\r
57501 children = me.children,\r
57502 bindings = me.bindings,\r
57503 key, store, autoDestroy;\r
57504 me.destroying = true;\r
57505 if (task) {\r
57506 task.cancel();\r
57507 me.collectTask = null;\r
57508 }\r
57509
57510
57511
57512
57513 if (children) {\r
57514 for (key in children) {\r
57515 children[key].destroy();\r
57516 }\r
57517 }\r
57518 if (stores) {\r
57519 for (key in stores) {\r
57520 store = stores[key];\r
57521 autoDestroy = store.autoDestroy;\r
57522 if (autoDestroy || (!store.$wasInstance && autoDestroy !== false)) {\r
57523 store.destroy();\r
57524 }\r
57525 Ext.destroy(store.$binding);\r
57526 }\r
57527 }\r
57528 if (parent) {\r
57529 parent.unregisterChild(me);\r
57530 }\r
57531 me.getRoot().destroy();\r
57532 for (key in bindings) {\r
57533 bindings[key].destroy();\r
57534 }\r
57535 if (scheduler && scheduler.$owner === me) {\r
57536 scheduler.$owner = null;\r
57537 scheduler.destroy();\r
57538 }\r
57539 me.hadValue = me.children = me.storeInfo = me._session = me._view = me._scheduler = me.bindings = me._root = me._parent = me.formulaFn = me.$formulaData = null;\r
57540 me.destroying = false;\r
57541 me.callParent();\r
57542 },\r
57543 \r
57544 bind: function(descriptor, callback, scope, options) {\r
57545 var me = this,\r
57546 binding, track;\r
57547 scope = scope || me;\r
57548 if (!options && descriptor.bindTo !== undefined && !Ext.isString(descriptor)) {\r
57549 options = descriptor;\r
57550 descriptor = options.bindTo;\r
57551 }\r
57552 if (!Ext.isString(descriptor)) {\r
57553 binding = new Ext.app.bind.Multi(descriptor, me, callback, scope, options);\r
57554 track = true;\r
57555 } else if (me.expressionRe.test(descriptor)) {\r
57556
57557 descriptor = descriptor.substring(1, descriptor.length - 1);\r
57558 binding = me.bindExpression(descriptor, callback, scope, options);\r
57559 } else {\r
57560 binding = new Ext.app.bind.TemplateBinding(descriptor, me, callback, scope, options);\r
57561 track = true;\r
57562 }\r
57563 if (track) {\r
57564 me.bindings[binding.id] = binding;\r
57565 }\r
57566 return binding;\r
57567 },\r
57568 \r
57569 getSession: function() {\r
57570 var me = this,\r
57571 session = me._session,\r
57572 parent;\r
57573 if (!session && (parent = me.getParent())) {\r
57574 me.setSession(session = parent.getSession());\r
57575 }\r
57576 return session || null;\r
57577 },\r
57578 \r
57579 getStore: function(key) {\r
57580 var storeInfo = this.storeInfo,\r
57581 store;\r
57582 if (storeInfo) {\r
57583 store = storeInfo[key];\r
57584 }\r
57585 return store || null;\r
57586 },\r
57587 \r
57588 \r
57589 linkTo: function(key, reference) {\r
57590 var me = this,\r
57591 stub, create, id, modelType, linkStub, rec;\r
57592
57593 if (key.indexOf('.') > -1) {\r
57594 Ext.raise('Links can only be at the top-level: "' + key + '"');\r
57595 }\r
57596
57597 if (reference.isModel) {\r
57598 reference = {\r
57599 type: reference.entityName,\r
57600 id: reference.id\r
57601 };\r
57602 }\r
57603
57604 modelType = reference.type || reference.reference;\r
57605 create = reference.create;\r
57606 if (modelType) {\r
57607
57608 id = reference.id;\r
57609
57610 if (!reference.create && Ext.isEmpty(id)) {\r
57611 Ext.raise('No id specified. To create a phantom model, specify "create: true" as part of the reference.');\r
57612 }\r
57613
57614 if (create) {\r
57615 id = undefined;\r
57616 }\r
57617 rec = me.getRecord(modelType, id);\r
57618 if (Ext.isObject(create)) {\r
57619 rec.set(create);\r
57620 rec.commit();\r
57621 rec.phantom = true;\r
57622 }\r
57623
57624
57625 stub = me.getRoot().createStubChild(key);\r
57626 stub.set(rec);\r
57627 } else {\r
57628 stub = me.getStub(key);\r
57629 if (!stub.isLinkStub) {\r
57630
57631 linkStub = new Ext.app.bind.LinkStub(me, stub.name);\r
57632 stub.graft(linkStub);\r
57633 stub = linkStub;\r
57634 }\r
57635 stub.link(reference);\r
57636 }\r
57637 },\r
57638 \r
57639 notify: function() {\r
57640 this.getScheduler().notify();\r
57641 },\r
57642 \r
57643 get: function(path) {\r
57644 return this.getStub(path).getValue();\r
57645 },\r
57646 \r
57647 set: function(path, value) {\r
57648 var me = this,\r
57649 obj, stub;\r
57650
57651 me.getData();\r
57652 if (value === undefined && path && path.constructor === Object) {\r
57653 stub = me.getRoot();\r
57654 value = path;\r
57655 } else if (path && path.indexOf('.') < 0) {\r
57656 obj = {};\r
57657 obj[path] = value;\r
57658 value = obj;\r
57659 stub = me.getRoot();\r
57660 } else {\r
57661 stub = me.getStub(path);\r
57662 }\r
57663 stub.set(value);\r
57664 },\r
57665
57666 privates: {\r
57667 registerChild: function(child) {\r
57668 var children = this.children;\r
57669 if (!children) {\r
57670 this.children = children = {};\r
57671 }\r
57672 children[child.getId()] = child;\r
57673 },\r
57674 unregisterChild: function(child) {\r
57675 var children = this.children;\r
57676
57677
57678 if (!this.destroying && children) {\r
57679 delete children[child.getId()];\r
57680 }\r
57681 },\r
57682 \r
57683 getRecord: function(type, id) {\r
57684 var session = this.getSession(),\r
57685 Model = type,\r
57686 hasId = id !== undefined,\r
57687 record;\r
57688 if (session) {\r
57689 if (hasId) {\r
57690 record = session.getRecord(type, id);\r
57691 } else {\r
57692 record = session.createRecord(type);\r
57693 }\r
57694 } else {\r
57695 if (!Model.$isClass) {\r
57696 Model = this.getSchema().getEntity(Model);\r
57697
57698 if (!Model) {\r
57699 Ext.raise('Invalid model name: ' + type);\r
57700 }\r
57701 }\r
57702
57703 if (hasId) {\r
57704 record = Model.createWithId(id);\r
57705 record.load();\r
57706 } else {\r
57707 record = new Model();\r
57708 }\r
57709 }\r
57710 return record;\r
57711 },\r
57712 notFn: function(v) {\r
57713 return !v;\r
57714 },\r
57715 bindExpression: function(descriptor, callback, scope, options) {\r
57716 var ch = descriptor.charAt(0),\r
57717 not = (ch === '!'),\r
57718 path = not ? descriptor.substring(1) : descriptor,\r
57719 stub = this.getStub(path),\r
57720 binding;\r
57721 binding = stub.bind(callback, scope, options);\r
57722 if (not) {\r
57723 binding.transform = this.notFn;\r
57724 }\r
57725 return binding;\r
57726 },\r
57727 applyScheduler: function(scheduler) {\r
57728 if (scheduler && !scheduler.isInstance) {\r
57729 scheduler = new Ext.util.Scheduler(scheduler);\r
57730 scheduler.$owner = this;\r
57731 }\r
57732 return scheduler;\r
57733 },\r
57734 getScheduler: function() {\r
57735 var me = this,\r
57736 scheduler = me._scheduler,\r
57737 parent;\r
57738 if (!scheduler) {\r
57739 if (!(parent = me.getParent())) {\r
57740 scheduler = new Ext.util.Scheduler({\r
57741
57742 preSort: 'kind,-depth'\r
57743 });\r
57744 scheduler.$owner = me;\r
57745 } else {\r
57746 scheduler = parent.getScheduler();\r
57747 }\r
57748 me.setScheduler(scheduler);\r
57749 }\r
57750 return scheduler;\r
57751 },\r
57752 \r
57753 getStub: function(bindDescr) {\r
57754 var root = this.getRoot();\r
57755 return bindDescr ? root.getChild(bindDescr) : root;\r
57756 },\r
57757 collect: function() {\r
57758 var me = this,\r
57759 parent = me.getParent(),\r
57760 task = me.collectTask;\r
57761 if (parent) {\r
57762 parent.collect();\r
57763 return;\r
57764 }\r
57765 if (!task) {\r
57766 task = me.collectTask = new Ext.util.DelayedTask(me.doCollect, me);\r
57767 }\r
57768
57769 if (me.collectTimeout === 0) {\r
57770 me.doCollect();\r
57771 } else {\r
57772 task.delay(me.collectTimeout);\r
57773 }\r
57774 },\r
57775 doCollect: function() {\r
57776 var children = this.children,\r
57777 key;\r
57778
57779
57780 if (children) {\r
57781 for (key in children) {\r
57782 children[key].doCollect();\r
57783 }\r
57784 }\r
57785 this.getRoot().collect();\r
57786 },\r
57787 onBindDestroy: function(binding, fromChild) {\r
57788 var me = this,\r
57789 parent;\r
57790 if (me.destroying) {\r
57791 return;\r
57792 }\r
57793 if (!fromChild) {\r
57794 delete me.bindings[binding.id];\r
57795 }\r
57796 parent = me.getParent();\r
57797 if (parent) {\r
57798 parent.onBindDestroy(binding, true);\r
57799 } else {\r
57800 me.collect();\r
57801 }\r
57802 },\r
57803
57804
57805
57806 applyData: function(newData, data) {\r
57807 var me = this,\r
57808 linkData, parent;\r
57809
57810 me.getSession();\r
57811 if (!data) {\r
57812 parent = me.getParent();\r
57813 \r
57814 me.linkData = linkData = parent ? Ext.Object.chain(parent.getData()) : {};\r
57815 \r
57816 me.data = me._data = Ext.Object.chain(linkData);\r
57817 }\r
57818 if (newData && newData.constructor === Object) {\r
57819 me.getRoot().set(newData);\r
57820 }\r
57821 },\r
57822 applyParent: function(parent) {\r
57823 if (parent) {\r
57824 parent.registerChild(this);\r
57825 }\r
57826 return parent;\r
57827 },\r
57828 applyStores: function(stores) {\r
57829 var me = this,\r
57830 root = me.getRoot(),\r
57831 key, cfg, storeBind, stub, listeners, isStatic;\r
57832 me.storeInfo = {};\r
57833 me.listenerScopeFn = function() {\r
57834 return me.getView().getInheritedConfig('defaultListenerScope');\r
57835 };\r
57836 for (key in stores) {\r
57837 cfg = stores[key];\r
57838 if (cfg.isStore) {\r
57839 cfg.$wasInstance = true;\r
57840 me.setupStore(cfg, key);\r
57841 \r
57842 continue;\r
57843 } else if (Ext.isString(cfg)) {\r
57844 cfg = {\r
57845 source: cfg\r
57846 };\r
57847 } else {\r
57848 cfg = Ext.apply({}, cfg);\r
57849 }\r
57850
57851 listeners = cfg.listeners;\r
57852 delete cfg.listeners;\r
57853 storeBind = me.bind(cfg, me.onStoreBind, me, {\r
57854 trackStatics: true\r
57855 });\r
57856 if (storeBind.isStatic()) {\r
57857
57858
57859 storeBind.destroy();\r
57860 me.createStore(key, cfg, listeners);\r
57861 } else {\r
57862 storeBind.$storeKey = key;\r
57863 storeBind.$listeners = listeners;\r
57864 stub = root.createStubChild(key);\r
57865 stub.setStore(storeBind);\r
57866 }\r
57867 }\r
57868 },\r
57869 onStoreBind: function(cfg, oldValue, binding) {\r
57870 var info = this.storeInfo,\r
57871 key = binding.$storeKey,\r
57872 store = info[key],\r
57873 proxy;\r
57874 if (!store) {\r
57875 this.createStore(key, cfg, binding.$listeners, binding);\r
57876 } else {\r
57877 cfg = Ext.merge({}, binding.pruneStaticKeys());\r
57878 proxy = cfg.proxy;\r
57879 delete cfg.type;\r
57880 delete cfg.model;\r
57881 delete cfg.fields;\r
57882 delete cfg.proxy;\r
57883 delete cfg.listeners;\r
57884
57885
57886 if (proxy) {\r
57887 delete proxy.reader;\r
57888 delete proxy.writer;\r
57889 store.getProxy().setConfig(proxy);\r
57890 }\r
57891 store.setConfig(cfg);\r
57892 }\r
57893 },\r
57894 createStore: function(key, cfg, listeners, binding) {\r
57895 var session = this.getSession(),\r
57896 store;\r
57897 cfg = Ext.apply({}, cfg);\r
57898 if (cfg.session) {\r
57899 cfg.session = session;\r
57900 }\r
57901 if (cfg.source) {\r
57902 cfg.type = cfg.type || 'chained';\r
57903 }\r
57904
57905 cfg.listeners = listeners;\r
57906 store = Ext.Factory.store(cfg);\r
57907 store.$binding = binding;\r
57908 this.setupStore(store, key);\r
57909 },\r
57910 setupStore: function(store, key) {\r
57911 store.resolveListenerScope = this.listenerScopeFn;\r
57912 this.storeInfo[key] = store;\r
57913 this.set(key, store);\r
57914 },\r
57915 applyFormulas: function(formulas) {\r
57916 var me = this,\r
57917 root = me.getRoot(),\r
57918 name, stub;\r
57919 me.getData();\r
57920
57921 for (name in formulas) {\r
57922
57923 if (name.indexOf('.') >= 0) {\r
57924 Ext.raise('Formula names cannot contain dots: ' + name);\r
57925 }\r
57926
57927
57928 root.createStubChild(name);\r
57929 stub = me.getStub(name);\r
57930 stub.setFormula(formulas[name]);\r
57931 }\r
57932 return formulas;\r
57933 },\r
57934 applyLinks: function(links) {\r
57935 for (var link in links) {\r
57936 this.linkTo(link, links[link]);\r
57937 }\r
57938 },\r
57939 applySchema: function(schema) {\r
57940 return Ext.data.schema.Schema.get(schema);\r
57941 },\r
57942 applyRoot: function() {\r
57943 var root = new Ext.app.bind.RootStub(this),\r
57944 parent = this.getParent();\r
57945 if (parent) {\r
57946
57947
57948 root.depth = parent.getRoot().depth - 1000;\r
57949 }\r
57950 return root;\r
57951 },\r
57952 getFormulaFn: function(data) {\r
57953 var me = this,\r
57954 fn = me.formulaFn;\r
57955 if (!fn) {\r
57956 fn = me.formulaFn = function(name) {\r
57957
57958
57959 return me.$formulaData[name];\r
57960 };\r
57961 }\r
57962 me.$formulaData = data;\r
57963 return fn;\r
57964 }\r
57965 }\r
57966});\r
57967
57968\r
57969\r
57970Ext.define('Ext.app.domain.Controller', {\r
57971 extend: Ext.app.EventDomain,\r
57972 singleton: true,\r
57973 type: 'controller',\r
57974 prefix: 'controller.',\r
57975 idMatchRe: /^\#/,\r
57976 constructor: function() {\r
57977 var me = this;\r
57978 me.callParent();\r
57979 me.monitor(Ext.app.BaseController);\r
57980 },\r
57981 match: function(target, selector) {\r
57982 var result = false,\r
57983 alias = target.alias;\r
57984 if (selector === '*') {\r
57985 result = true;\r
57986 } else if (selector === '#') {\r
57987 result = !!target.isApplication;\r
57988 } else if (this.idMatchRe.test(selector)) {\r
57989 result = target.getId() === selector.substring(1);\r
57990 } else if (alias) {\r
57991 result = Ext.Array.indexOf(alias, this.prefix + selector) > -1;\r
57992 }\r
57993 return result;\r
57994 }\r
57995});\r
57996\r
57997\r
57998Ext.define('Ext.direct.Manager', {\r
57999 singleton: true,\r
58000 mixins: [\r
58001 Ext.mixin.Observable\r
58002 ],\r
58003 \r
58004 exceptions: {\r
58005 TRANSPORT: 'xhr',\r
58006 PARSE: 'parse',\r
58007 DATA: 'data',\r
58008 LOGIN: 'login',\r
58009 SERVER: 'exception'\r
58010 },\r
58011
58012 providerClasses: {},\r
58013
58014 remotingMethods: {},\r
58015 config: {\r
58016 \r
58017 varName: 'Ext.REMOTING_API'\r
58018 },\r
58019 apiNotFoundError: 'Ext Direct API was not found at {0}',\r
58020 \r
58021 \r
58022 \r
58023 \r
58024 \r
58025 constructor: function() {\r
58026 var me = this;\r
58027 me.mixins.observable.constructor.call(me);\r
58028 me.transactions = new Ext.util.MixedCollection();\r
58029 me.providers = new Ext.util.MixedCollection();\r
58030 },\r
58031 \r
58032 addProvider: function(provider) {\r
58033 var me = this,\r
58034 args = arguments,\r
58035 relayers = me.relayers || (me.relayers = {}),\r
58036 i, len;\r
58037 if (args.length > 1) {\r
58038 for (i = 0 , len = args.length; i < len; ++i) {\r
58039 me.addProvider(args[i]);\r
58040 }\r
58041 return;\r
58042 }\r
58043
58044 if (!provider.isProvider) {\r
58045 provider = Ext.create('direct.' + provider.type + 'provider', provider);\r
58046 }\r
58047 me.providers.add(provider);\r
58048 provider.on('data', me.onProviderData, me);\r
58049 if (provider.relayedEvents) {\r
58050 relayers[provider.id] = me.relayEvents(provider, provider.relayedEvents);\r
58051 }\r
58052 if (!provider.isConnected()) {\r
58053 provider.connect();\r
58054 }\r
58055 return provider;\r
58056 },\r
58057 \r
58058 loadProvider: function(config, callback, scope) {\r
58059 var me = this,\r
58060 classes = me.providerClasses,\r
58061 type, url, varName, provider, i, len;\r
58062 if (Ext.isArray(config)) {\r
58063 for (i = 0 , len = config.length; i < len; i++) {\r
58064 me.loadProvider(config[i], callback, scope);\r
58065 }\r
58066 return;\r
58067 }\r
58068
58069
58070 type = config.type;\r
58071 url = config.url;\r
58072 if (classes[type] && classes[type].checkConfig(config)) {\r
58073 provider = me.addProvider(config);\r
58074 me.fireEventArgs('providerload', [\r
58075 url,\r
58076 provider\r
58077 ]);\r
58078 Ext.callback(callback, scope, [\r
58079 url,\r
58080 provider\r
58081 ]);\r
58082
58083
58084
58085
58086 return;\r
58087 }\r
58088
58089
58090
58091 varName = config.varName || me.getVarName();\r
58092 delete config.varName;\r
58093
58094 if (!url) {\r
58095 Ext.raise("Need API discovery URL to load a Remoting provider!");\r
58096 }\r
58097
58098
58099
58100 delete config.url;\r
58101
58102
58103 Ext.Loader.loadScript({\r
58104 url: url,\r
58105 scope: me,\r
58106 onLoad: function() {\r
58107 this.onApiLoadSuccess({\r
58108 url: url,\r
58109 varName: varName,\r
58110 config: config,\r
58111 callback: callback,\r
58112 scope: scope\r
58113 });\r
58114 },\r
58115 onError: function() {\r
58116 this.onApiLoadFailure({\r
58117 url: url,\r
58118 callback: callback,\r
58119 scope: scope\r
58120 });\r
58121 }\r
58122 });\r
58123 },\r
58124 \r
58125 getProvider: function(id) {\r
58126 return id.isProvider ? id : this.providers.get(id);\r
58127 },\r
58128 \r
58129 removeProvider: function(provider) {\r
58130 var me = this,\r
58131 providers = me.providers,\r
58132 relayers = me.relayers,\r
58133 id;\r
58134 provider = provider.isProvider ? provider : providers.get(provider);\r
58135 if (provider) {\r
58136 provider.un('data', me.onProviderData, me);\r
58137 id = provider.id;\r
58138 if (relayers[id]) {\r
58139 relayers[id].destroy();\r
58140 delete relayers[id];\r
58141 }\r
58142 providers.remove(provider);\r
58143 return provider;\r
58144 }\r
58145 return null;\r
58146 },\r
58147 \r
58148 addTransaction: function(transaction) {\r
58149 this.transactions.add(transaction);\r
58150 return transaction;\r
58151 },\r
58152 \r
58153 removeTransaction: function(transaction) {\r
58154 var me = this;\r
58155 transaction = me.getTransaction(transaction);\r
58156 me.transactions.remove(transaction);\r
58157 return transaction;\r
58158 },\r
58159 \r
58160 getTransaction: function(transaction) {\r
58161 return typeof transaction === 'object' ? transaction : this.transactions.get(transaction);\r
58162 },\r
58163 onProviderData: function(provider, event) {\r
58164 var me = this,\r
58165 i, len;\r
58166 if (Ext.isArray(event)) {\r
58167 for (i = 0 , len = event.length; i < len; ++i) {\r
58168 me.onProviderData(provider, event[i]);\r
58169 }\r
58170 return;\r
58171 }\r
58172 if (event.name && event.name !== 'event' && event.name !== 'exception') {\r
58173 me.fireEvent(event.name, event);\r
58174 } else if (event.status === false) {\r
58175 me.fireEvent('exception', event);\r
58176 }\r
58177 me.fireEvent('event', event, provider);\r
58178 },\r
58179 \r
58180 parseMethod: function(fn) {\r
58181 var current = Ext.global,\r
58182 i = 0,\r
58183 resolved, parts, len;\r
58184 if (Ext.isFunction(fn)) {\r
58185 resolved = fn;\r
58186 } else if (Ext.isString(fn)) {\r
58187 resolved = this.remotingMethods[fn];\r
58188
58189
58190 if (!resolved) {\r
58191 parts = fn.split('.');\r
58192 len = parts.length;\r
58193 while (current && i < len) {\r
58194 current = current[parts[i]];\r
58195 ++i;\r
58196 }\r
58197 resolved = Ext.isFunction(current) ? current : null;\r
58198 }\r
58199 }\r
58200 return resolved || null;\r
58201 },\r
58202 privates: {\r
58203 addProviderClass: function(type, cls) {\r
58204 this.providerClasses[type] = cls;\r
58205 },\r
58206 onApiLoadSuccess: function(options) {\r
58207 var me = this,\r
58208 url = options.url,\r
58209 varName = options.varName,\r
58210 api, provider, error;\r
58211 try {\r
58212
58213
58214 api = Ext.apply(options.config, eval(varName));\r
58215 provider = me.addProvider(api);\r
58216 } catch (e) {\r
58217 error = e + '';\r
58218 }\r
58219 if (error) {\r
58220 me.fireEventArgs('providerloaderror', [\r
58221 url,\r
58222 error\r
58223 ]);\r
58224 Ext.callback(options.callback, options.scope, [\r
58225 url,\r
58226 error\r
58227 ]);\r
58228 } else {\r
58229 me.fireEventArgs('providerload', [\r
58230 url,\r
58231 provider\r
58232 ]);\r
58233 Ext.callback(options.callback, options.scope, [\r
58234 url,\r
58235 provider\r
58236 ]);\r
58237 }\r
58238 },\r
58239 onApiLoadFailure: function(options) {\r
58240 var url = options.url,\r
58241 error;\r
58242 error = Ext.String.format(this.apiNotFoundError, url);\r
58243 this.fireEventArgs('providerloaderror', [\r
58244 url,\r
58245 error\r
58246 ]);\r
58247 Ext.callback(options.callback, options.scope, [\r
58248 url,\r
58249 error\r
58250 ]);\r
58251 },\r
58252 registerMethod: function(name, method) {\r
58253 this.remotingMethods[name] = method;\r
58254 },\r
58255
58256 clearAllMethods: function() {\r
58257 this.remotingMethods = {};\r
58258 }\r
58259 }\r
58260}, function() {\r
58261
58262 Ext.Direct = Ext.direct.Manager;\r
58263});\r
58264\r
58265\r
58266Ext.define('Ext.direct.Provider', {\r
58267 alias: 'direct.provider',\r
58268 mixins: [\r
58269 Ext.mixin.Observable\r
58270 ],\r
58271 isProvider: true,\r
58272 \r
58273 \r
58274 \r
58275 \r
58276 \r
58277 \r
58278 subscribers: 0,\r
58279 constructor: function(config) {\r
58280 var me = this;\r
58281 Ext.apply(me, config);\r
58282 Ext.applyIf(me, {\r
58283 id: Ext.id(null, 'provider-')\r
58284 });\r
58285 me.mixins.observable.constructor.call(me, config);\r
58286 },\r
58287 destroy: function() {\r
58288 var me = this;\r
58289 me.disconnect(true);\r
58290 me.callParent();\r
58291 },\r
58292 \r
58293 isConnected: function() {\r
58294 return this.subscribers > 0;\r
58295 },\r
58296 \r
58297 connect: function() {\r
58298 var me = this;\r
58299 if (me.subscribers === 0) {\r
58300 me.doConnect();\r
58301 me.fireEventArgs('connect', [\r
58302 me\r
58303 ]);\r
58304 }\r
58305 me.subscribers++;\r
58306 },\r
58307 \r
58308 doConnect: Ext.emptyFn,\r
58309 \r
58310 disconnect: function(\r
58311 force) {\r
58312 var me = this;\r
58313 if (me.subscribers > 0) {\r
58314 if (force) {\r
58315 me.subscribers = 0;\r
58316 } else {\r
58317 me.subscribers--;\r
58318 }\r
58319 if (me.subscribers === 0) {\r
58320 me.doDisconnect();\r
58321 me.fireEventArgs('disconnect', [\r
58322 me\r
58323 ]);\r
58324 }\r
58325 }\r
58326 },\r
58327 \r
58328 doDisconnect: Ext.emptyFn,\r
58329 inheritableStatics: {\r
58330 \r
58331 checkConfig: Ext.returnFalse\r
58332 },\r
58333 onClassExtended: function(cls, data, hooks) {\r
58334 if (data.type) {\r
58335 Ext.direct.Manager.addProviderClass(data.type, cls);\r
58336 }\r
58337 }\r
58338});\r
58339\r
58340\r
58341Ext.define('Ext.app.domain.Direct', {\r
58342 extend: Ext.app.EventDomain,\r
58343 singleton: true,\r
58344 type: 'direct',\r
58345 idProperty: 'id',\r
58346 constructor: function() {\r
58347 var me = this;\r
58348 me.callParent();\r
58349 me.monitor(Ext.direct.Provider);\r
58350 }\r
58351});\r
58352\r
58353\r
58354Ext.define('Ext.data.PageMap', {\r
58355 extend: Ext.util.LruCache,\r
58356 config: {\r
58357 store: null,\r
58358 \r
58359 pageSize: 0,\r
58360 \r
58361 rootProperty: ''\r
58362 },\r
58363
58364 clear: function(initial) {\r
58365 var me = this;\r
58366 me.pageMapGeneration = (me.pageMapGeneration || 0) + 1;\r
58367
58368 me.indexMap = {};\r
58369 me.callParent([\r
58370 initial\r
58371 ]);\r
58372 },\r
58373
58374 updatePageSize: function(value, oldValue) {\r
58375 if (oldValue != null) {\r
58376 throw "pageMap page size may not be changed";\r
58377 }\r
58378 },\r
58379
58380 forEach: function(fn, scope) {\r
58381 var me = this,\r
58382 pageNumbers = Ext.Object.getKeys(me.map),\r
58383 pageCount = pageNumbers.length,\r
58384 pageSize = me.getPageSize(),\r
58385 i, j, pageNumber, page, len;\r
58386 for (i = 0; i < pageCount; i++) {\r
58387 pageNumbers[i] = +pageNumbers[i];\r
58388 }\r
58389 Ext.Array.sort(pageNumbers, Ext.Array.numericSortFn);\r
58390 scope = scope || me;\r
58391 for (i = 0; i < pageCount; i++) {\r
58392 pageNumber = pageNumbers[i];\r
58393 page = me.getPage(pageNumber);\r
58394 len = page.length;\r
58395 for (j = 0; j < len; j++) {\r
58396 if (fn.call(scope, page[j], (pageNumber - 1) * pageSize + j) === false) {\r
58397 return;\r
58398 }\r
58399 }\r
58400 }\r
58401 },\r
58402 \r
58403 findBy: function(fn, scope) {\r
58404 var me = this,\r
58405 result = null;\r
58406 scope = scope || me;\r
58407 me.forEach(function(rec, index) {\r
58408 if (fn.call(scope, rec, index)) {\r
58409 result = rec;\r
58410 return false;\r
58411 }\r
58412 });\r
58413 return result;\r
58414 },\r
58415 \r
58416 findIndexBy: function(fn, scope) {\r
58417 var me = this,\r
58418 result = -1;\r
58419 scope = scope || me;\r
58420 me.forEach(function(rec, index) {\r
58421 if (fn.call(scope, rec)) {\r
58422 result = index;\r
58423 return false;\r
58424 }\r
58425 });\r
58426 return result;\r
58427 },\r
58428 find: function(property, value, start, startsWith, endsWith, ignoreCase) {\r
58429 if (Ext.isEmpty(value, false)) {\r
58430 return null;\r
58431 }\r
58432 var regex = Ext.String.createRegex(value, startsWith, endsWith, ignoreCase),\r
58433 root = this.getRootProperty();\r
58434 return this.findBy(function(item) {\r
58435 return item && regex.test((root ? item[root] : item)[property]);\r
58436 }, null, start);\r
58437 },\r
58438 findIndex: function(property, value, start, startsWith, endsWith, ignoreCase) {\r
58439 if (Ext.isEmpty(value, false)) {\r
58440 return null;\r
58441 }\r
58442 var regex = Ext.String.createRegex(value, startsWith, endsWith, ignoreCase),\r
58443 root = this.getRootProperty();\r
58444 return this.findIndexBy(function(item) {\r
58445 return item && regex.test((root ? item[root] : item)[property]);\r
58446 }, null, start);\r
58447 },\r
58448 getPageFromRecordIndex: function(index) {\r
58449 return Math.floor(index / this.getPageSize()) + 1;\r
58450 },\r
58451 addAll: function(records) {\r
58452
58453 if (this.getCount()) {\r
58454 Ext.raise('Cannot addAll to a non-empty PageMap');\r
58455 }\r
58456
58457 this.addPage(1, records);\r
58458 },\r
58459 addPage: function(pageNumber, records) {\r
58460 var me = this,\r
58461 pageSize = me.getPageSize(),\r
58462 lastPage = pageNumber + Math.floor((records.length - 1) / pageSize),\r
58463 storeIndex = (pageNumber - 1) * pageSize,\r
58464 indexMap = me.indexMap,\r
58465 page, i, len, startIdx;\r
58466
58467
58468 for (startIdx = 0; pageNumber <= lastPage; pageNumber++ , startIdx += pageSize) {\r
58469 page = Ext.Array.slice(records, startIdx, startIdx + pageSize);\r
58470
58471 for (i = 0 , len = page.length; i < len; i++) {\r
58472 indexMap[page[i].internalId] = storeIndex++;\r
58473 }\r
58474 me.add(pageNumber, page);\r
58475 me.fireEvent('pageadd', me, pageNumber, page);\r
58476 }\r
58477 },\r
58478 getCount: function() {\r
58479 var result = this.callParent();\r
58480 if (result) {\r
58481 result = (result - 1) * this.getPageSize() + this.last.value.length;\r
58482 }\r
58483 return result;\r
58484 },\r
58485 getByInternalId: function(internalId) {\r
58486 var index = this.indexMap[internalId];\r
58487 if (index != null) {\r
58488 return this.getAt(index);\r
58489 }\r
58490 },\r
58491 indexOf: function(record) {\r
58492 var result = -1;\r
58493 if (record) {\r
58494 result = this.indexMap[record.internalId];\r
58495 if (result == null) {\r
58496 result = -1;\r
58497 }\r
58498 }\r
58499 return result;\r
58500 },\r
58501 insert: function() {\r
58502
58503 Ext.raise('insert operation not suppported into buffered Store');\r
58504 },\r
58505
58506 remove: function() {\r
58507
58508 Ext.raise('remove operation not suppported from buffered Store');\r
58509 },\r
58510
58511 removeAt: function() {\r
58512
58513 Ext.raise('removeAt operation not suppported from buffered Store');\r
58514 },\r
58515
58516 removeAtKey: function(page) {\r
58517
58518 var me = this,\r
58519 thePage = me.getPage(page),\r
58520 len, i, result;\r
58521 if (thePage) {\r
58522 if (me.fireEvent('beforepageremove', me, page, thePage) !== false) {\r
58523 len = thePage.length;\r
58524 for (i = 0; i < len; i++) {\r
58525 delete me.indexMap[thePage[i].internalId];\r
58526 }\r
58527 result = me.callParent(arguments);\r
58528 me.fireEvent('pageremove', me, page, thePage);\r
58529
58530 thePage.length = 0;\r
58531 }\r
58532 }\r
58533 return result;\r
58534 },\r
58535 getPage: function(pageNumber) {\r
58536 return this.get(pageNumber);\r
58537 },\r
58538 hasRange: function(start, end) {\r
58539 var me = this,\r
58540 pageNumber = me.getPageFromRecordIndex(start),\r
58541 endPageNumber = me.getPageFromRecordIndex(end);\r
58542 for (; pageNumber <= endPageNumber; pageNumber++) {\r
58543 if (!me.hasPage(pageNumber)) {\r
58544 return false;\r
58545 }\r
58546 }\r
58547
58548 return (endPageNumber - 1) * me._pageSize + me.getPage(endPageNumber).length > end;\r
58549 },\r
58550 hasPage: function(pageNumber) {\r
58551
58552 return !!this.get(pageNumber);\r
58553 },\r
58554 peekPage: function(pageNumber) {\r
58555 return this.map[pageNumber];\r
58556 },\r
58557 getAt: function(index) {\r
58558 return this.getRange(index, index + 1)[0];\r
58559 },\r
58560 getRange: function(start, end) {\r
58561
58562
58563 end--;\r
58564 if (!this.hasRange(start, end)) {\r
58565 Ext.raise('PageMap asked for range which it does not have');\r
58566 }\r
58567 var me = this,\r
58568 Array = Ext.Array,\r
58569 pageSize = me.getPageSize(),\r
58570 startPageNumber = me.getPageFromRecordIndex(start),\r
58571 endPageNumber = me.getPageFromRecordIndex(end),\r
58572 dataStart = (startPageNumber - 1) * pageSize,\r
58573 dataEnd = (endPageNumber * pageSize) - 1,\r
58574 pageNumber = startPageNumber,\r
58575 result = [],\r
58576 sliceBegin, sliceEnd, doSlice;\r
58577 for (; pageNumber <= endPageNumber; pageNumber++) {\r
58578
58579 if (pageNumber === startPageNumber) {\r
58580 sliceBegin = start - dataStart;\r
58581 doSlice = sliceBegin > 0;\r
58582 } else {\r
58583 sliceBegin = 0;\r
58584 doSlice = false;\r
58585 }\r
58586 if (pageNumber === endPageNumber) {\r
58587 sliceEnd = pageSize - (dataEnd - end);\r
58588 doSlice = doSlice || sliceEnd < pageSize;\r
58589 }\r
58590
58591 if (doSlice) {\r
58592 Array.push(result, Array.slice(me.getPage(pageNumber), sliceBegin, sliceEnd));\r
58593 } else {\r
58594 Array.push(result, me.getPage(pageNumber));\r
58595 }\r
58596 }\r
58597 return result;\r
58598 },\r
58599 destroy: function() {\r
58600 this.callParent();\r
58601 this.indexMap = {};\r
58602 }\r
58603});\r
58604\r
58605\r
58606Ext.define('Ext.data.BufferedStore', {\r
58607 extend: Ext.data.ProxyStore,\r
58608 alias: 'store.buffered',\r
58609 \r
58610 isBufferedStore: true,\r
58611
58612 buffered: true,\r
58613 config: {\r
58614 data: 0,\r
58615 pageSize: 25,\r
58616 remoteSort: true,\r
58617 remoteFilter: true,\r
58618 sortOnLoad: false,\r
58619 \r
58620 purgePageCount: 5,\r
58621 \r
58622 trailingBufferZone: 25,\r
58623 \r
58624 leadingBufferZone: 200,\r
58625 \r
58626 defaultViewSize: 100,\r
58627 \r
58628 viewSize: 0,\r
58629 \r
58630 trackRemoved: false\r
58631 },\r
58632 \r
58633 applyData: function(data) {\r
58634 var dataCollection = this.data || (this.data = this.createDataCollection());\r
58635
58636 if (data && data !== true) {\r
58637 Ext.raise('Cannot load a buffered store with local data - the store is a map of remote data');\r
58638 }\r
58639
58640 return dataCollection;\r
58641 },\r
58642 applyProxy: function(proxy) {\r
58643 proxy = this.callParent([\r
58644 proxy\r
58645 ]);\r
58646
58647
58648 if (proxy && proxy.setEnablePaging) {\r
58649 proxy.setEnablePaging(true);\r
58650 }\r
58651 return proxy;\r
58652 },\r
58653 createFiltersCollection: function() {\r
58654 return new Ext.util.FilterCollection();\r
58655 },\r
58656 createSortersCollection: function() {\r
58657 return new Ext.util.SorterCollection();\r
58658 },\r
58659
58660 updateRemoteFilter: function(remoteFilter, oldRemoteFilter) {\r
58661 if (remoteFilter === false) {\r
58662 Ext.raise('Buffered stores are always remotely filtered.');\r
58663 }\r
58664 this.callParent([\r
58665 remoteFilter,\r
58666 oldRemoteFilter\r
58667 ]);\r
58668 },\r
58669 updateRemoteSort: function(remoteSort, oldRemoteSort) {\r
58670 if (remoteSort === false) {\r
58671 Ext.raise('Buffered stores are always remotely sorted.');\r
58672 }\r
58673 this.callParent([\r
58674 remoteSort,\r
58675 oldRemoteSort\r
58676 ]);\r
58677 },\r
58678 updateTrackRemoved: function(value) {\r
58679 if (value !== false) {\r
58680 Ext.raise('Cannot use trackRemoved with a buffered store.');\r
58681 }\r
58682 this.callParent(arguments);\r
58683 },\r
58684
58685 updateGroupField: function(field) {\r
58686 this.group(field);\r
58687 },\r
58688 getGrouper: function() {\r
58689 return this.grouper;\r
58690 },\r
58691 isGrouped: function() {\r
58692 return !!this.grouper;\r
58693 },\r
58694 createDataCollection: function() {\r
58695 var me = this,\r
58696 result = new Ext.data.PageMap({\r
58697 store: me,\r
58698 rootProperty: 'data',\r
58699 pageSize: me.getPageSize(),\r
58700 maxSize: me.getPurgePageCount(),\r
58701 listeners: {\r
58702
58703
58704 clear: me.onPageMapClear,\r
58705 scope: me\r
58706 }\r
58707 });\r
58708
58709 me.relayEvents(result, [\r
58710 'beforepageremove',\r
58711 'pageadd',\r
58712 'pageremove'\r
58713 ]);\r
58714 me.pageRequests = {};\r
58715 return result;\r
58716 },\r
58717
58718 add: function() {\r
58719 Ext.raise('add method may not be called on a buffered store - the store is a map of remote data');\r
58720 },\r
58721 insert: function() {\r
58722 Ext.raise('insert method may not be called on a buffered store - the store is a map of remote data');\r
58723 },\r
58724
58725 removeAll: function(silent) {\r
58726 var me = this,\r
58727 data = me.getData();\r
58728 if (data) {\r
58729 if (silent) {\r
58730 me.suspendEvent('clear');\r
58731 }\r
58732 data.clear();\r
58733 if (silent) {\r
58734 me.resumeEvent('clear');\r
58735 }\r
58736 }\r
58737 },\r
58738 flushLoad: function() {\r
58739 var me = this,\r
58740 options = me.pendingLoadOptions;\r
58741
58742 me.clearLoadTask();\r
58743 if (!options) {\r
58744 return;\r
58745 }\r
58746
58747 me.getData().clear();\r
58748 options.page = 1;\r
58749 options.start = 0;\r
58750 options.limit = me.getViewSize() || me.getDefaultViewSize();\r
58751
58752
58753 options.loadCallback = options.callback;\r
58754
58755 options.callback = null;\r
58756 return me.loadToPrefetch(options);\r
58757 },\r
58758 reload: function(options) {\r
58759 var me = this,\r
58760 data = me.getData(),\r
58761
58762 lastTotal = Number.MAX_VALUE,\r
58763 startIdx, endIdx, startPage, endPage, i, waitForReload, bufferZone, records;\r
58764 if (!options) {\r
58765 options = {};\r
58766 }\r
58767
58768 if (me.loading || me.fireEvent('beforeload', me, options) === false) {\r
58769 return;\r
58770 }\r
58771 waitForReload = function() {\r
58772 var newCount = me.totalCount,\r
58773 oldRequestSize = endIdx - startIdx;\r
58774
58775
58776 if (endIdx >= newCount) {\r
58777 endIdx = newCount - 1;\r
58778 startIdx = Math.max(endIdx - oldRequestSize, 0);\r
58779 }\r
58780 if (me.rangeCached(startIdx, Math.min(endIdx, me.totalCount))) {\r
58781 me.loading = false;\r
58782 data.un('pageadd', waitForReload);\r
58783 records = data.getRange(startIdx, endIdx + 1);\r
58784 me.fireEvent('load', me, records, true);\r
58785 me.fireEvent('refresh', me);\r
58786 }\r
58787 };\r
58788 bufferZone = Math.ceil((me.getLeadingBufferZone() + me.getTrailingBufferZone()) / 2);\r
58789
58790
58791
58792
58793 if (me.lastRequestStart && me.preserveScrollOnReload) {\r
58794 startIdx = me.lastRequestStart;\r
58795 endIdx = me.lastRequestEnd;\r
58796 lastTotal = me.getTotalCount();\r
58797 } else
58798 {\r
58799 startIdx = options.start || 0;\r
58800 endIdx = startIdx + (options.count || me.getPageSize()) - 1;\r
58801 }\r
58802
58803 data.clear(true);\r
58804
58805 delete me.totalCount;\r
58806
58807 startIdx = Math.max(startIdx - bufferZone, 0);\r
58808 endIdx = Math.min(endIdx + bufferZone, lastTotal);\r
58809 startPage = me.getPageFromRecordIndex(startIdx);\r
58810 endPage = me.getPageFromRecordIndex(endIdx);\r
58811 me.loading = true;\r
58812 options.waitForReload = waitForReload;\r
58813
58814
58815 data.on('pageadd', waitForReload);\r
58816
58817 for (i = startPage; i <= endPage; i++) {\r
58818 me.prefetchPage(i, options);\r
58819 }\r
58820 },\r
58821 filter: function() {\r
58822
58823 if (!this.getRemoteFilter()) {\r
58824 Ext.raise('Local filtering may not be used on a buffered store - the store is a map of remote data');\r
58825 }\r
58826
58827
58828 this.callParent(arguments);\r
58829 },\r
58830 filterBy: function(fn, scope) {\r
58831
58832 Ext.raise('Local filtering may not be used on a buffered store - the store is a map of remote data');\r
58833 },\r
58834
58835 loadData: function(data, append) {\r
58836
58837 Ext.raise('LoadData may not be used on a buffered store - the store is a map of remote data');\r
58838 },\r
58839
58840 loadPage: function(page, options) {\r
58841 var me = this;\r
58842 options = options || {};\r
58843 options.page = me.currentPage = page;\r
58844 options.start = (page - 1) * me.getPageSize();\r
58845 options.limit = me.getViewSize() || me.getDefaultViewSize();\r
58846 options.loadCallback = options.callback;\r
58847
58848 options.callback = null;\r
58849 return me.loadToPrefetch(options);\r
58850 },\r
58851 clearData: function(isLoad) {\r
58852 var me = this,\r
58853 data = me.getData();\r
58854 if (data) {\r
58855 data.clear();\r
58856 }\r
58857 },\r
58858 \r
58859 getCount: function() {\r
58860 return this.totalCount || 0;\r
58861 },\r
58862 getRange: function(start, end, options) {\r
58863 var me = this,\r
58864 maxIndex = me.totalCount - 1,\r
58865 lastRequestStart = me.lastRequestStart,\r
58866 result = [],\r
58867 data = me.getData(),\r
58868 pageAddHandler, requiredStart, requiredEnd, requiredStartPage, requiredEndPage;\r
58869 options = Ext.apply({\r
58870 prefetchStart: start,\r
58871 prefetchEnd: end\r
58872 }, options);\r
58873
58874 end = (end >= me.totalCount) ? maxIndex : end;\r
58875
58876
58877
58878
58879 requiredStart = start === 0 ? 0 : start - 1;\r
58880 requiredEnd = end === maxIndex ? end : end + 1;\r
58881
58882 me.lastRequestStart = start;\r
58883 me.lastRequestEnd = end;\r
58884
58885 if (me.rangeCached(requiredStart, requiredEnd)) {\r
58886 me.onRangeAvailable(options);\r
58887 result = data.getRange(start, end + 1);\r
58888 } else
58889 {\r
58890
58891 me.fireEvent('cachemiss', me, start, end);\r
58892 requiredStartPage = me.getPageFromRecordIndex(requiredStart);\r
58893 requiredEndPage = me.getPageFromRecordIndex(requiredEnd);\r
58894
58895 pageAddHandler = function(pageMap, page, records) {\r
58896 if (page >= requiredStartPage && page <= requiredEndPage && me.rangeCached(requiredStart, requiredEnd)) {\r
58897
58898 me.fireEvent('cachefilled', me, start, end);\r
58899 data.un('pageadd', pageAddHandler);\r
58900 me.onRangeAvailable(options);\r
58901 }\r
58902 };\r
58903 data.on('pageadd', pageAddHandler);\r
58904
58905
58906
58907 me.prefetchRange(start, end);\r
58908 }\r
58909
58910 me.primeCache(start, end, start < lastRequestStart ? -1 : 1);\r
58911 return result;\r
58912 },\r
58913 \r
58914 getById: function(id) {\r
58915 var result = this.data.findBy(function(record) {\r
58916 return record.getId() === id;\r
58917 });\r
58918 return result;\r
58919 },\r
58920 \r
58921 getAt: function(index) {\r
58922 var data = this.getData();\r
58923 if (data.hasRange(index, index)) {\r
58924 return data.getAt(index);\r
58925 }\r
58926 },\r
58927 \r
58928 getByInternalId: function(internalId) {\r
58929 return this.data.getByInternalId(internalId);\r
58930 },\r
58931
58932 contains: function(record) {\r
58933 return this.indexOf(record) > -1;\r
58934 },\r
58935 \r
58936 indexOf: function(record) {\r
58937 return this.getData().indexOf(record);\r
58938 },\r
58939 \r
58940 indexOfId: function(id) {\r
58941 return this.indexOf(this.getById(id));\r
58942 },\r
58943 group: function(grouper, direction) {\r
58944 var me = this,\r
58945 oldGrouper;\r
58946 if (grouper && typeof grouper === 'string') {\r
58947 oldGrouper = me.grouper;\r
58948 if (!oldGrouper) {\r
58949 me.grouper = new Ext.util.Grouper({\r
58950 property: grouper,\r
58951 direction: direction || 'ASC',\r
58952 root: 'data'\r
58953 });\r
58954 } else if (direction === undefined) {\r
58955 oldGrouper.toggle();\r
58956 } else {\r
58957 oldGrouper.setDirection(direction);\r
58958 }\r
58959 } else {\r
58960 me.grouper = grouper ? me.getSorters().decodeSorter(grouper, 'Ext.util.Grouper') : null;\r
58961 }\r
58962 me.getData().clear();\r
58963 me.loadPage(1, {\r
58964 callback: function() {\r
58965 me.fireEvent('groupchange', me, me.getGrouper());\r
58966 }\r
58967 });\r
58968 },\r
58969 \r
58970 getPageFromRecordIndex: function(index) {\r
58971 return Math.floor(index / this.getPageSize()) + 1;\r
58972 },\r
58973 calculatePageCacheSize: function(rangeSizeRequested) {\r
58974 var me = this,\r
58975 purgePageCount = me.getPurgePageCount();\r
58976
58977
58978
58979 return purgePageCount ? Math.max(me.getData().getMaxSize() || 0, Math.ceil((rangeSizeRequested + me.getTrailingBufferZone() + me.getLeadingBufferZone()) / me.getPageSize()) * 2 + purgePageCount) : 0;\r
58980 },\r
58981 loadToPrefetch: function(options) {\r
58982 var me = this,\r
58983 prefetchOptions = options,\r
58984 i, records, dataSetSize,\r
58985
58986 startIdx = options.start,\r
58987 endIdx = options.start + options.limit - 1,\r
58988 rangeSizeRequested = (me.getViewSize() || options.limit),\r
58989
58990 loadEndIdx = Math.min(endIdx, options.start + rangeSizeRequested - 1),\r
58991
58992
58993 startPage = me.getPageFromRecordIndex(Math.max(startIdx - me.getTrailingBufferZone(), 0)),\r
58994 endPage = me.getPageFromRecordIndex(endIdx + me.getLeadingBufferZone()),\r
58995 data = me.getData(),\r
58996 callbackFn = function() {\r
58997
58998 records = records || [];\r
58999 if (options.loadCallback) {\r
59000 options.loadCallback.call(options.scope || me, records, operation, true);\r
59001 }\r
59002 if (options.callback) {\r
59003 options.callback.call(options.scope || me, records, startIdx || 0, endIdx || 0, options);\r
59004 }\r
59005 },\r
59006 fireEventsFn = function() {\r
59007 me.fireEvent('datachanged', me);\r
59008 me.fireEvent('refresh', me);\r
59009 me.fireEvent('load', me, records, true);\r
59010 },\r
59011
59012 waitForRequestedRange = function() {\r
59013 if (me.rangeCached(startIdx, loadEndIdx)) {\r
59014 me.loading = false;\r
59015 records = data.getRange(startIdx, loadEndIdx + 1);\r
59016 data.un('pageadd', waitForRequestedRange);\r
59017
59018 if (me.hasListeners.guaranteedrange) {\r
59019 me.guaranteeRange(startIdx, loadEndIdx, options.callback, options.scope);\r
59020 }\r
59021 callbackFn();\r
59022 fireEventsFn();\r
59023 }\r
59024 },\r
59025 operation;\r
59026
59027 if (isNaN(me.pageSize) || !me.pageSize) {\r
59028 Ext.raise('Buffered store configured without a pageSize', me);\r
59029 }\r
59030
59031
59032
59033 data.setMaxSize(me.calculatePageCacheSize(rangeSizeRequested));\r
59034 if (me.fireEvent('beforeload', me, options) !== false) {\r
59035
59036 delete me.totalCount;\r
59037 me.loading = true;\r
59038
59039
59040 if (options.callback) {\r
59041 prefetchOptions = Ext.apply({}, options);\r
59042 delete prefetchOptions.callback;\r
59043 }\r
59044
59045
59046
59047
59048 me.on('prefetch', function(store, records, successful, op) {\r
59049
59050 operation = op;\r
59051 if (successful) {\r
59052
59053
59054 if ((dataSetSize = me.getTotalCount())) {\r
59055
59056 data.on('pageadd', waitForRequestedRange);\r
59057
59058 loadEndIdx = Math.min(loadEndIdx, dataSetSize - 1);\r
59059
59060 endPage = me.getPageFromRecordIndex(Math.min(loadEndIdx + me.getLeadingBufferZone(), dataSetSize - 1));\r
59061 for (i = startPage + 1; i <= endPage; ++i) {\r
59062 me.prefetchPage(i, prefetchOptions);\r
59063 }\r
59064 } else {\r
59065 callbackFn();\r
59066 fireEventsFn();\r
59067 }\r
59068 } else
59069 {\r
59070 me.loading = false;\r
59071 callbackFn();\r
59072 me.fireEvent('load', me, records, false);\r
59073 }\r
59074 }, null, {\r
59075 single: true\r
59076 });\r
59077 me.prefetchPage(startPage, prefetchOptions);\r
59078 }\r
59079 },\r
59080
59081 \r
59082 prefetch: function(options) {\r
59083 var me = this,\r
59084 pageSize = me.getPageSize(),\r
59085 data = me.getData(),\r
59086 operation, existingPageRequest;\r
59087
59088 if (pageSize) {\r
59089 if (me.lastPageSize && pageSize != me.lastPageSize) {\r
59090 Ext.raise("pageSize cannot be dynamically altered");\r
59091 }\r
59092 if (!data.getPageSize()) {\r
59093 data.setPageSize(pageSize);\r
59094 }\r
59095 } else
59096 {\r
59097 me.pageSize = data.setPageSize(pageSize = options.limit);\r
59098 }\r
59099
59100 me.lastPageSize = pageSize;\r
59101
59102 if (!options.page) {\r
59103 options.page = me.getPageFromRecordIndex(options.start);\r
59104 options.start = (options.page - 1) * pageSize;\r
59105 options.limit = Math.ceil(options.limit / pageSize) * pageSize;\r
59106 }\r
59107
59108
59109
59110 existingPageRequest = me.pageRequests[options.page];\r
59111 if (!existingPageRequest || existingPageRequest.getOperation().pageMapGeneration !== data.pageMapGeneration) {\r
59112
59113 options = Ext.apply({\r
59114 action: 'read',\r
59115 filters: me.getFilters().items,\r
59116 sorters: me.getSorters().items,\r
59117 grouper: me.getGrouper(),\r
59118 internalCallback: me.onProxyPrefetch,\r
59119 internalScope: me\r
59120 }, options);\r
59121 operation = me.createOperation('read', options);\r
59122
59123
59124 operation.pageMapGeneration = data.pageMapGeneration;\r
59125 if (me.fireEvent('beforeprefetch', me, operation) !== false) {\r
59126 me.pageRequests[options.page] = operation.execute();\r
59127 if (me.getProxy().isSynchronous) {\r
59128 delete me.pageRequests[options.page];\r
59129 }\r
59130 }\r
59131 }\r
59132 return me;\r
59133 },\r
59134 \r
59135 onPageMapClear: function() {\r
59136 var me = this,\r
59137 loadingFlag = me.wasLoading,\r
59138 reqs = me.pageRequests,\r
59139 data = me.getData(),\r
59140 page;\r
59141
59142 data.clearListeners();\r
59143
59144 data.on('clear', me.onPageMapClear, me);\r
59145 me.relayEvents(data, [\r
59146 'beforepageremove',\r
59147 'pageadd',\r
59148 'pageremove'\r
59149 ]);\r
59150
59151
59152
59153 me.loading = true;\r
59154 me.totalCount = 0;\r
59155
59156
59157
59158
59159 for (page in reqs) {\r
59160 if (reqs.hasOwnProperty(page)) {\r
59161 reqs[page].getOperation().abort();\r
59162 }\r
59163 }\r
59164
59165 me.fireEvent('clear', me);\r
59166
59167
59168 me.loading = loadingFlag;\r
59169 },\r
59170 \r
59171 prefetchPage: function(page, options) {\r
59172 var me = this,\r
59173 pageSize = me.getPageSize(),\r
59174 start = (page - 1) * pageSize,\r
59175 total = me.totalCount;\r
59176
59177 if (total !== undefined && me.data.getCount() === total) {\r
59178 return;\r
59179 }\r
59180
59181 me.prefetch(Ext.applyIf({\r
59182 page: page,\r
59183 start: start,\r
59184 limit: pageSize\r
59185 }, options));\r
59186 },\r
59187 \r
59188 onProxyPrefetch: function(operation) {\r
59189 if (this.destroyed) {\r
59190 return;\r
59191 }\r
59192 var me = this,\r
59193 resultSet = operation.getResultSet(),\r
59194 records = operation.getRecords(),\r
59195 successful = operation.wasSuccessful(),\r
59196 page = operation.getPage(),\r
59197 waitForReload = operation.waitForReload,\r
59198 oldTotal = me.totalCount,\r
59199 requests = me.pageRequests,\r
59200 key, op;\r
59201
59202
59203 if (operation.pageMapGeneration === me.getData().pageMapGeneration) {\r
59204 if (resultSet) {\r
59205 me.totalCount = resultSet.getTotal();\r
59206 if (me.totalCount !== oldTotal) {\r
59207 me.fireEvent('totalcountchange', me.totalCount);\r
59208 }\r
59209 }\r
59210
59211 if (page !== undefined) {\r
59212 delete me.pageRequests[page];\r
59213 }\r
59214
59215 me.loading = false;\r
59216 me.fireEvent('prefetch', me, records, successful, operation);\r
59217
59218
59219 if (successful) {\r
59220 if (me.totalCount === 0) {\r
59221 if (waitForReload) {\r
59222 for (key in requests) {\r
59223 op = requests[key].getOperation();\r
59224
59225
59226 if (op.waitForReload === waitForReload) {\r
59227 delete op.waitForReload;\r
59228 }\r
59229 }\r
59230 me.getData().un('pageadd', waitForReload);\r
59231 me.fireEvent('load', me, [], true);\r
59232 me.fireEvent('refresh', me);\r
59233 }\r
59234 } else {\r
59235 me.cachePage(records, operation.getPage());\r
59236 }\r
59237 }\r
59238
59239 Ext.callback(operation.getCallback(), operation.getScope() || me, [\r
59240 records,\r
59241 operation,\r
59242 successful\r
59243 ]);\r
59244 }\r
59245 },\r
59246 \r
59247 cachePage: function(records, page) {\r
59248 var me = this,\r
59249 len = records.length,\r
59250 i;\r
59251 if (!Ext.isDefined(me.totalCount)) {\r
59252 me.totalCount = records.length;\r
59253 me.fireEvent('totalcountchange', me.totalCount);\r
59254 }\r
59255
59256 for (i = 0; i < len; i++) {\r
59257 records[i].join(me);\r
59258 }\r
59259 me.getData().addPage(page, records);\r
59260 },\r
59261 \r
59262 rangeCached: function(start, end) {\r
59263 return this.getData().hasRange(start, end);\r
59264 },\r
59265 \r
59266 pageCached: function(page) {\r
59267 return this.getData().hasPage(page);\r
59268 },\r
59269 \r
59270 pagePending: function(page) {\r
59271 return !!this.pageRequests[page];\r
59272 },\r
59273 \r
59274 rangeSatisfied: function(start, end) {\r
59275 return this.rangeCached(start, end);\r
59276 },\r
59277 \r
59278 onRangeAvailable: function(options) {\r
59279 var me = this,\r
59280 totalCount = me.getTotalCount(),\r
59281 start = options.prefetchStart,\r
59282 end = (options.prefetchEnd > totalCount - 1) ? totalCount - 1 : options.prefetchEnd,\r
59283 range;\r
59284 end = Math.max(0, end);\r
59285
59286 if (start > end) {\r
59287 Ext.log({\r
59288 level: 'warn',\r
59289 msg: 'Start (' + start + ') was greater than end (' + end + ') for the range of records requested (' + start + '-' + options.prefetchEnd + ')' + (this.storeId ? ' from store "' + this.storeId + '"' : '')\r
59290 });\r
59291 }\r
59292
59293 range = me.getData().getRange(start, end + 1);\r
59294 if (options.fireEvent !== false) {\r
59295 me.fireEvent('guaranteedrange', range, start, end, options);\r
59296 }\r
59297 if (options.callback) {\r
59298 options.callback.call(options.scope || me, range, start, end, options);\r
59299 }\r
59300 },\r
59301 \r
59302 guaranteeRange: function(start, end, callback, scope, options) {\r
59303 options = Ext.apply({\r
59304 callback: callback,\r
59305 scope: scope\r
59306 }, options);\r
59307 this.getRange(start, end + 1, options);\r
59308 },\r
59309 \r
59310 prefetchRange: function(start, end) {\r
59311 var me = this,\r
59312 startPage, endPage, page,\r
59313 data = me.getData();\r
59314 if (!me.rangeCached(start, end)) {\r
59315 startPage = me.getPageFromRecordIndex(start);\r
59316 endPage = me.getPageFromRecordIndex(end);\r
59317
59318
59319
59320 data.setMaxSize(me.calculatePageCacheSize(end - start + 1));\r
59321
59322 for (page = startPage; page <= endPage; page++) {\r
59323 if (!me.pageCached(page)) {\r
59324 me.prefetchPage(page);\r
59325 }\r
59326 }\r
59327 }\r
59328 },\r
59329 primeCache: function(start, end, direction) {\r
59330 var me = this,\r
59331 leadingBufferZone = me.getLeadingBufferZone(),\r
59332 trailingBufferZone = me.getTrailingBufferZone(),\r
59333 pageSize = me.getPageSize(),\r
59334 totalCount = me.totalCount;\r
59335
59336 if (direction === -1) {\r
59337 start = Math.max(start - leadingBufferZone, 0);\r
59338 end = Math.min(end + trailingBufferZone, totalCount - 1);\r
59339 }\r
59340
59341 else if (direction === 1) {\r
59342 start = Math.max(Math.min(start - trailingBufferZone, totalCount - pageSize), 0);\r
59343 end = Math.min(end + leadingBufferZone, totalCount - 1);\r
59344 } else
59345 {\r
59346 start = Math.min(Math.max(Math.floor(start - ((leadingBufferZone + trailingBufferZone) / 2)), 0), totalCount - me.pageSize);\r
59347 end = Math.min(Math.max(Math.ceil(end + ((leadingBufferZone + trailingBufferZone) / 2)), 0), totalCount - 1);\r
59348 }\r
59349 me.prefetchRange(start, end);\r
59350 },\r
59351 sort: function(field, direction, mode) {\r
59352 if (arguments.length === 0) {\r
59353 this.clearAndLoad();\r
59354 } else {\r
59355 this.getSorters().addSort(field, direction, mode);\r
59356 }\r
59357 },\r
59358 onSorterEndUpdate: function() {\r
59359 var me = this,\r
59360 sorters = me.getSorters().getRange();\r
59361
59362 if (sorters.length) {\r
59363 me.fireEvent('beforesort', me, sorters);\r
59364 me.clearAndLoad({\r
59365 callback: function() {\r
59366 me.fireEvent('sort', me, sorters);\r
59367 }\r
59368 });\r
59369 } else {\r
59370
59371 me.fireEvent('sort', me, sorters);\r
59372 }\r
59373 },\r
59374 clearAndLoad: function(options) {\r
59375 this.getData().clear();\r
59376 this.loadPage(1, options);\r
59377 },\r
59378 privates: {\r
59379 isLast: function(record) {\r
59380 return this.indexOf(record) === this.getTotalCount() - 1;\r
59381 },\r
59382 isMoving: function() {\r
59383 return false;\r
59384 }\r
59385 }\r
59386});\r
59387\r
59388\r
59389Ext.define('Ext.data.proxy.Direct', {\r
59390 \r
59391 extend: Ext.data.proxy.Server,\r
59392 alternateClassName: 'Ext.data.DirectProxy',\r
59393 alias: 'proxy.direct',\r
59394 \r
59395 \r
59396 config: {\r
59397 \r
59398 paramOrder: undefined,\r
59399 \r
59400 paramsAsHash: true,\r
59401 \r
59402 directFn: undefined,\r
59403 \r
59404 api: undefined,\r
59405 \r
59406 metadata: undefined\r
59407 },\r
59408 \r
59409 paramOrderRe: /[\s,|]/,\r
59410 applyParamOrder: function(paramOrder) {\r
59411 if (Ext.isString(paramOrder)) {\r
59412 paramOrder = paramOrder.split(this.paramOrderRe);\r
59413 }\r
59414 return paramOrder;\r
59415 },\r
59416 updateApi: function() {\r
59417 this.methodsResolved = false;\r
59418 },\r
59419 updateDirectFn: function() {\r
59420 this.methodsResolved = false;\r
59421 },\r
59422 resolveMethods: function() {\r
59423 var me = this,\r
59424 fn = me.getDirectFn(),\r
59425 api = me.getApi(),\r
59426 Manager = Ext.direct.Manager,\r
59427 method;\r
59428 if (fn) {\r
59429 me.setDirectFn(method = Manager.parseMethod(fn));\r
59430 if (!Ext.isFunction(method)) {\r
59431 Ext.raise('Cannot resolve directFn ' + fn);\r
59432 }\r
59433 }\r
59434 if (api) {\r
59435 for (fn in api) {\r
59436 if (api.hasOwnProperty(fn)) {\r
59437 method = api[fn];\r
59438 api[fn] = Manager.parseMethod(method);\r
59439 if (!Ext.isFunction(api[fn])) {\r
59440 Ext.raise('Cannot resolve Direct api ' + fn + ' method ' + method);\r
59441 }\r
59442 }\r
59443 }\r
59444 }\r
59445 me.methodsResolved = true;\r
59446 },\r
59447 doRequest: function(operation) {\r
59448 var me = this,\r
59449 writer, request, action, params, args, api, fn, callback;\r
59450 if (!me.methodsResolved) {\r
59451 me.resolveMethods();\r
59452 }\r
59453 request = me.buildRequest(operation);\r
59454 action = request.getAction();\r
59455 api = me.getApi();\r
59456 if (api) {\r
59457 fn = api[action];\r
59458 }\r
59459 fn = fn || me.getDirectFn();\r
59460
59461 if (!fn) {\r
59462 Ext.raise('No Ext Direct function specified for this proxy');\r
59463 }\r
59464
59465 writer = me.getWriter();\r
59466 if (writer && operation.allowWrite()) {\r
59467 request = writer.write(request);\r
59468 }\r
59469
59470
59471
59472
59473
59474
59475
59476
59477 if (action === 'read') {\r
59478 params = request.getParams();\r
59479 } else {\r
59480 params = request.getJsonData();\r
59481 }\r
59482 args = fn.directCfg.method.getArgs({\r
59483 params: params,\r
59484 paramOrder: me.getParamOrder(),\r
59485 paramsAsHash: me.getParamsAsHash(),\r
59486 metadata: me.getMetadata(),\r
59487 callback: me.createRequestCallback(request, operation),\r
59488 scope: me\r
59489 });\r
59490 request.setConfig({\r
59491 args: args,\r
59492 directFn: fn\r
59493 });\r
59494 fn.apply(window, args);\r
59495
59496
59497
59498 return request;\r
59499 },\r
59500 \r
59501 applyEncoding: Ext.identityFn,\r
59502 createRequestCallback: function(request, operation) {\r
59503 var me = this;\r
59504 return function(data, event) {\r
59505 me.processResponse(event.status, operation, request, event);\r
59506 };\r
59507 },\r
59508 \r
59509 extractResponseData: function(response) {\r
59510 return Ext.isDefined(response.result) ? response.result : response.data;\r
59511 },\r
59512 \r
59513 setException: function(operation, response) {\r
59514 operation.setException(response.message);\r
59515 },\r
59516 \r
59517 buildUrl: function() {\r
59518 return '';\r
59519 }\r
59520});\r
59521\r
59522\r
59523Ext.define('Ext.data.DirectStore', {\r
59524 \r
59525 extend: Ext.data.Store,\r
59526 alias: 'store.direct',\r
59527 \r
59528 constructor: function(config) {\r
59529 config = Ext.apply({}, config);\r
59530 if (!config.proxy) {\r
59531 var proxy = {\r
59532 type: 'direct',\r
59533 reader: {\r
59534 type: 'json'\r
59535 }\r
59536 };\r
59537 Ext.copyTo(proxy, config, 'paramOrder,paramsAsHash,directFn,api,simpleSortMode,extraParams');\r
59538 Ext.copyTo(proxy.reader, config, 'totalProperty,root,rootProperty,idProperty');\r
59539 config.proxy = proxy;\r
59540 }\r
59541 this.callParent([\r
59542 config\r
59543 ]);\r
59544 }\r
59545});\r
59546\r
59547\r
59548Ext.define('Ext.data.JsonP', {\r
59549 \r
59550 singleton: true,\r
59551 \r
59552 \r
59553 requestCount: 0,\r
59554 \r
59555 requests: {},\r
59556 \r
59557 timeout: 30000,\r
59558 \r
59559 disableCaching: true,\r
59560 \r
59561 disableCachingParam: '_dc',\r
59562 \r
59563 callbackKey: 'callback',\r
59564 \r
59565 request: function(options) {\r
59566 options = Ext.apply({}, options);\r
59567
59568 if (!options.url) {\r
59569 Ext.raise('A url must be specified for a JSONP request.');\r
59570 }\r
59571
59572 var me = this,\r
59573 disableCaching = Ext.isDefined(options.disableCaching) ? options.disableCaching : me.disableCaching,\r
59574 cacheParam = options.disableCachingParam || me.disableCachingParam,\r
59575 id = ++me.requestCount,\r
59576 callbackName = options.callbackName || 'callback' + id,\r
59577 callbackKey = options.callbackKey || me.callbackKey,\r
59578 timeout = Ext.isDefined(options.timeout) ? options.timeout : me.timeout,\r
59579 params = Ext.apply({}, options.params),\r
59580 url = options.url,\r
59581 name = Ext.name,\r
59582 request, script;\r
59583
59584 if (disableCaching && !params[cacheParam]) {\r
59585 params[cacheParam] = Ext.Date.now();\r
59586 }\r
59587 options.params = params;\r
59588 params[callbackKey] = name + '.data.JsonP.' + callbackName;\r
59589 script = me.createScript(url, params, options);\r
59590 me.requests[id] = request = {\r
59591 url: url,\r
59592 params: params,\r
59593 script: script,\r
59594 id: id,\r
59595 scope: options.scope,\r
59596 success: options.success,\r
59597 failure: options.failure,\r
59598 callback: options.callback,\r
59599 callbackKey: callbackKey,\r
59600 callbackName: callbackName\r
59601 };\r
59602 if (timeout > 0) {\r
59603 request.timeout = Ext.defer(me.handleTimeout, timeout, me, [\r
59604 request\r
59605 ]);\r
59606 }\r
59607 me.setupErrorHandling(request);\r
59608 me[callbackName] = Ext.bind(me.handleResponse, me, [\r
59609 request\r
59610 ], true);\r
59611 me.loadScript(request);\r
59612 return request;\r
59613 },\r
59614 \r
59615 abort: function(request) {\r
59616 var me = this,\r
59617 requests = me.requests,\r
59618 key;\r
59619 if (request) {\r
59620 if (!request.id) {\r
59621 request = requests[request];\r
59622 }\r
59623 me.handleAbort(request);\r
59624 } else {\r
59625 for (key in requests) {\r
59626 if (requests.hasOwnProperty(key)) {\r
59627 me.abort(requests[key]);\r
59628 }\r
59629 }\r
59630 }\r
59631 },\r
59632 \r
59633 setupErrorHandling: function(request) {\r
59634 request.script.onerror = Ext.bind(this.handleError, this, [\r
59635 request\r
59636 ]);\r
59637 },\r
59638 \r
59639 handleAbort: function(request) {\r
59640 request.errorType = 'abort';\r
59641 this.handleResponse(null, request);\r
59642 },\r
59643 \r
59644 handleError: function(request) {\r
59645 request.errorType = 'error';\r
59646 this.handleResponse(null, request);\r
59647 },\r
59648 \r
59649 cleanupErrorHandling: function(request) {\r
59650 request.script.onerror = null;\r
59651 },\r
59652 \r
59653 handleTimeout: function(request) {\r
59654 request.errorType = 'timeout';\r
59655 this.handleResponse(null, request);\r
59656 },\r
59657 \r
59658 handleResponse: function(result, request) {\r
59659 var success = true,\r
59660 globalEvents = Ext.GlobalEvents;\r
59661 if (request.timeout) {\r
59662 clearTimeout(request.timeout);\r
59663 }\r
59664 delete this[request.callbackName];\r
59665 delete this.requests[request.id];\r
59666 this.cleanupErrorHandling(request);\r
59667 Ext.fly(request.script).destroy();\r
59668 if (request.errorType) {\r
59669 success = false;\r
59670 Ext.callback(request.failure, request.scope, [\r
59671 request.errorType\r
59672 ]);\r
59673 } else {\r
59674 Ext.callback(request.success, request.scope, [\r
59675 result\r
59676 ]);\r
59677 }\r
59678 Ext.callback(request.callback, request.scope, [\r
59679 success,\r
59680 result,\r
59681 request.errorType\r
59682 ]);\r
59683 if (globalEvents.hasListeners.idle) {\r
59684 globalEvents.fireEvent('idle');\r
59685 }\r
59686 },\r
59687 \r
59688 createScript: function(url, params, options) {\r
59689 var script = document.createElement('script');\r
59690 script.setAttribute("src", Ext.urlAppend(url, Ext.Object.toQueryString(params)));\r
59691 script.setAttribute("async", true);\r
59692 script.setAttribute("type", "text/javascript");\r
59693 return script;\r
59694 },\r
59695 \r
59696 loadScript: function(request) {\r
59697 Ext.getHead().appendChild(request.script);\r
59698 }\r
59699});\r
59700\r
59701\r
59702Ext.define('Ext.data.proxy.JsonP', {\r
59703 extend: Ext.data.proxy.Server,\r
59704 alternateClassName: 'Ext.data.ScriptTagProxy',\r
59705 alias: [\r
59706 'proxy.jsonp',\r
59707 'proxy.scripttag'\r
59708 ],\r
59709 config: {\r
59710 \r
59711 callbackKey: 'callback',\r
59712 \r
59713 recordParam: 'records',\r
59714 \r
59715 autoAppendParams: true\r
59716 },\r
59717 \r
59718 doRequest: function(operation) {\r
59719
59720 var me = this,\r
59721 request = me.buildRequest(operation),\r
59722 params = request.getParams();\r
59723
59724 request.setConfig({\r
59725 callbackKey: me.callbackKey,\r
59726 timeout: me.timeout,\r
59727 scope: me,\r
59728 disableCaching: false,\r
59729
59730 callback: me.createRequestCallback(request, operation)\r
59731 });\r
59732
59733
59734 if (me.getAutoAppendParams()) {\r
59735 request.setParams({});\r
59736 }\r
59737 request.setRawRequest(Ext.data.JsonP.request(request.getCurrentConfig()));\r
59738
59739 request.setParams(params);\r
59740 me.lastRequest = request;\r
59741 return request;\r
59742 },\r
59743 \r
59744 createRequestCallback: function(request, operation) {\r
59745 var me = this;\r
59746 return function(success, response, errorType) {\r
59747 if (request === me.lastRequest) {\r
59748 me.lastRequest = null;\r
59749 }\r
59750 me.processResponse(success, operation, request, response);\r
59751 };\r
59752 },\r
59753 setException: function(operation, response) {\r
59754 operation.setException(operation.getRequest().getRawRequest().errorType);\r
59755 },\r
59756 \r
59757 buildUrl: function(request) {\r
59758 var me = this,\r
59759 url = me.callParent(arguments),\r
59760 records = request.getRecords(),\r
59761 writer = me.getWriter(),\r
59762 params, filters, filter, i, v;\r
59763
59764
59765 if (writer && request.getOperation().allowWrite()) {\r
59766 request = writer.write(request);\r
59767 }\r
59768
59769 params = request.getParams();\r
59770 filters = params.filters;\r
59771 delete params.filters;\r
59772 if (filters && filters.length) {\r
59773 for (i = 0; i < filters.length; i++) {\r
59774 filter = filters[i];\r
59775 v = filter.getValue();\r
59776 if (v) {\r
59777 params[filter.getProperty()] = v;\r
59778 }\r
59779 }\r
59780 }\r
59781
59782 if (Ext.isArray(records) && records.length > 0 && (!writer || !writer.getEncode())) {\r
59783 params[me.getRecordParam()] = me.encodeRecords(records);\r
59784 }\r
59785
59786
59787 if (me.getAutoAppendParams()) {\r
59788 url = Ext.urlAppend(url, Ext.Object.toQueryString(params));\r
59789 }\r
59790 return url;\r
59791 },\r
59792 \r
59793 abort: function(request) {\r
59794 request = request || this.lastRequest;\r
59795 if (request) {\r
59796 Ext.data.JsonP.abort(request.getRawRequest());\r
59797 }\r
59798 },\r
59799 \r
59800 encodeRecords: function(records) {\r
59801 var encoded = [],\r
59802 i = 0,\r
59803 len = records.length;\r
59804 for (; i < len; i++) {\r
59805 encoded.push(Ext.encode(records[i].getData()));\r
59806 }\r
59807 return encoded;\r
59808 }\r
59809});\r
59810\r
59811\r
59812Ext.define('Ext.data.JsonPStore', {\r
59813 extend: Ext.data.Store,\r
59814 alias: 'store.jsonp',\r
59815 constructor: function(config) {\r
59816 config = Ext.apply({\r
59817 proxy: {\r
59818 type: 'jsonp',\r
59819 reader: 'json'\r
59820 }\r
59821 }, config);\r
59822 this.callParent([\r
59823 config\r
59824 ]);\r
59825 }\r
59826});\r
59827\r
59828\r
59829Ext.define('Ext.data.JsonStore', {\r
59830 extend: Ext.data.Store,\r
59831 alias: 'store.json',\r
59832 constructor: function(config) {\r
59833 config = Ext.apply({\r
59834 proxy: {\r
59835 type: 'ajax',\r
59836 reader: 'json',\r
59837 writer: 'json'\r
59838 }\r
59839 }, config);\r
59840 this.callParent([\r
59841 config\r
59842 ]);\r
59843 }\r
59844});\r
59845\r
59846\r
59847Ext.define('Ext.data.ModelManager', {\r
59848 alternateClassName: 'Ext.ModelMgr',\r
59849 singleton: true,\r
59850 deprecated: {\r
59851 5: {\r
59852 methods: {\r
59853 clear: null,\r
59854 create: function(data, name, id) {\r
59855 var T = name;\r
59856 if (!T.isEntity) {\r
59857 T = this.getModel(name || data.name);\r
59858 }\r
59859 return T.createWithId(id, data);\r
59860 },\r
59861 each: function(fn, scope) {\r
59862 Ext.data.Model.schema.eachEntity(fn, scope);\r
59863 },\r
59864 get: function(name) {\r
59865 return this.getModel(name);\r
59866 },\r
59867 getCount: function() {\r
59868 return Ext.data.Model.schema.entityCount;\r
59869 },\r
59870 \r
59871 getModel: function(id) {\r
59872 return Ext.data.schema.Schema.lookupEntity(id);\r
59873 },\r
59874 isRegistered: function(name) {\r
59875 return !!this.getModel(name);\r
59876 }\r
59877 }\r
59878 }\r
59879 }\r
59880});\r
59881\r
59882\r
59883Ext.define('Ext.data.NodeInterface', {\r
59884 \r
59885 \r
59886 \r
59887 \r
59888 \r
59889 \r
59890 \r
59891 \r
59892 \r
59893 \r
59894 \r
59895 \r
59896 \r
59897 \r
59898 \r
59899 \r
59900 \r
59901 \r
59902 \r
59903 \r
59904 \r
59905 \r
59906 \r
59907 \r
59908 \r
59909 \r
59910 \r
59911 \r
59912 \r
59913 \r
59914 statics: {\r
59915 \r
59916 decorate: function(modelClass) {\r
59917 var model = Ext.data.schema.Schema.lookupEntity(modelClass),\r
59918 proto = model.prototype,\r
59919 idName, idField, idType;\r
59920 if (!model.prototype.isObservable) {\r
59921 model.mixin(Ext.mixin.Observable.prototype.mixinId, Ext.mixin.Observable);\r
59922 }\r
59923 if (proto.isNode) {\r
59924
59925 return;\r
59926 }\r
59927 idName = proto.idProperty;\r
59928 idField = model.getField(idName);\r
59929 idType = idField.type;\r
59930 model.override(this.getPrototypeBody());\r
59931 model.addFields([\r
59932 {\r
59933 name: 'parentId',\r
59934 type: idType,\r
59935 defaultValue: null,\r
59936 allowNull: idField.allowNull\r
59937 },\r
59938 {\r
59939 name: 'index',\r
59940 type: 'int',\r
59941 defaultValue: -1,\r
59942 persist: false,\r
59943 convert: null\r
59944 },\r
59945 {\r
59946 name: 'depth',\r
59947 type: 'int',\r
59948 defaultValue: 0,\r
59949 persist: false,\r
59950 convert: null\r
59951 },\r
59952 {\r
59953 name: 'expanded',\r
59954 type: 'bool',\r
59955 defaultValue: false,\r
59956 persist: false,\r
59957 convert: null\r
59958 },\r
59959 {\r
59960 name: 'expandable',\r
59961 type: 'bool',\r
59962 defaultValue: true,\r
59963 persist: false,\r
59964 convert: null\r
59965 },\r
59966 {\r
59967 name: 'checked',\r
59968 type: 'auto',\r
59969 defaultValue: null,\r
59970 persist: false,\r
59971 convert: null\r
59972 },\r
59973 {\r
59974 name: 'leaf',\r
59975 type: 'bool',\r
59976 defaultValue: false\r
59977 },\r
59978 {\r
59979 name: 'cls',\r
59980 type: 'string',\r
59981 defaultValue: '',\r
59982 persist: false,\r
59983 convert: null\r
59984 },\r
59985 {\r
59986 name: 'iconCls',\r
59987 type: 'string',\r
59988 defaultValue: '',\r
59989 persist: false,\r
59990 convert: null\r
59991 },\r
59992 {\r
59993 name: 'icon',\r
59994 type: 'string',\r
59995 defaultValue: '',\r
59996 persist: false,\r
59997 convert: null\r
59998 },\r
59999 {\r
60000 name: 'root',\r
60001 type: 'boolean',\r
60002 defaultValue: false,\r
60003 persist: false,\r
60004 convert: null\r
60005 },\r
60006 {\r
60007 name: 'isLast',\r
60008 type: 'boolean',\r
60009 defaultValue: false,\r
60010 persist: false,\r
60011 convert: null\r
60012 },\r
60013 {\r
60014 name: 'isFirst',\r
60015 type: 'boolean',\r
60016 defaultValue: false,\r
60017 persist: false,\r
60018 convert: null\r
60019 },\r
60020 {\r
60021 name: 'allowDrop',\r
60022 type: 'boolean',\r
60023 defaultValue: true,\r
60024 persist: false,\r
60025 convert: null\r
60026 },\r
60027 {\r
60028 name: 'allowDrag',\r
60029 type: 'boolean',\r
60030 defaultValue: true,\r
60031 persist: false,\r
60032 convert: null\r
60033 },\r
60034 {\r
60035 name: 'loaded',\r
60036 type: 'boolean',\r
60037 defaultValue: false,\r
60038 persist: false,\r
60039 convert: null\r
60040 },\r
60041 {\r
60042 name: 'loading',\r
60043 type: 'boolean',\r
60044 defaultValue: false,\r
60045 persist: false,\r
60046 convert: null\r
60047 },\r
60048 {\r
60049 name: 'href',\r
60050 type: 'string',\r
60051 defaultValue: '',\r
60052 persist: false,\r
60053 convert: null\r
60054 },\r
60055 {\r
60056 name: 'hrefTarget',\r
60057 type: 'string',\r
60058 defaultValue: '',\r
60059 persist: false,\r
60060 convert: null\r
60061 },\r
60062 {\r
60063 name: 'qtip',\r
60064 type: 'string',\r
60065 defaultValue: '',\r
60066 persist: false,\r
60067 convert: null\r
60068 },\r
60069 {\r
60070 name: 'qtitle',\r
60071 type: 'string',\r
60072 defaultValue: '',\r
60073 persist: false,\r
60074 convert: null\r
60075 },\r
60076 {\r
60077 name: 'qshowDelay',\r
60078 type: 'int',\r
60079 defaultValue: 0,\r
60080 persist: false,\r
60081 convert: null\r
60082 },\r
60083 {\r
60084 name: 'children',\r
60085 type: 'auto',\r
60086 defaultValue: null,\r
60087 persist: false,\r
60088 convert: null\r
60089 },\r
60090 {\r
60091 name: 'visible',\r
60092 type: 'boolean',\r
60093 defaultValue: true,\r
60094 persist: false\r
60095 },\r
60096 {\r
60097 name: 'text',\r
60098 type: 'string',\r
60099 persist: false\r
60100 }\r
60101 ]);\r
60102 },\r
60103 getPrototypeBody: function() {\r
60104 var bubbledEvents = {\r
60105 idchanged: true,\r
60106 append: true,\r
60107 remove: true,\r
60108 move: true,\r
60109 insert: true,\r
60110 beforeappend: true,\r
60111 beforeremove: true,\r
60112 beforemove: true,\r
60113 beforeinsert: true,\r
60114 expand: true,\r
60115 collapse: true,\r
60116 beforeexpand: true,\r
60117 beforecollapse: true,\r
60118 sort: true\r
60119 },\r
60120 silently = {\r
60121 silent: true\r
60122 };\r
60123
60124
60125
60126
60127
60128
60129
60130
60131
60132 return {\r
60133 \r
60134 isNode: true,\r
60135 firstChild: null,\r
60136 lastChild: null,\r
60137 parentNode: null,\r
60138 previousSibling: null,\r
60139 nextSibling: null,\r
60140 constructor: function() {\r
60141 var me = this;\r
60142 me.mixins.observable.constructor.call(me);\r
60143 me.callParent(arguments);\r
60144 me.childNodes = [];\r
60145
60146
60147
60148 \r
60149 \r
60150 \r
60151 \r
60152 \r
60153 \r
60154 \r
60155 \r
60156 \r
60157 \r
60158 \r
60159 \r
60160 \r
60161 return me;\r
60162 },\r
60163 \r
60164 createNode: function(node) {\r
60165 var me = this,\r
60166 childType = me.childType,\r
60167 store, storeReader, nodeProxy, nodeReader, reader, typeProperty,\r
60168 T = me.self;\r
60169
60170 if (!node.isModel) {\r
60171
60172 if (childType) {\r
60173 T = me.schema.getEntity(childType);\r
60174 } else
60175 {\r
60176 store = me.getTreeStore();\r
60177 storeReader = store && store.getProxy().getReader();\r
60178 nodeProxy = me.getProxy();\r
60179 nodeReader = nodeProxy ? nodeProxy.getReader() : null;\r
60180
60181 reader = !storeReader || (nodeReader && nodeReader.initialConfig.typeProperty) ? nodeReader : storeReader;\r
60182 if (reader) {\r
60183 typeProperty = reader.getTypeProperty();\r
60184 if (typeProperty) {\r
60185 T = reader.getChildType(me.schema, node, typeProperty);\r
60186 }\r
60187 }\r
60188 }\r
60189 node = new T(node);\r
60190 }\r
60191
60192
60193
60194 if (!node.childNodes) {\r
60195 node.firstChild = node.lastChild = node.parentNode = node.previousSibling = node.nextSibling = null;\r
60196 node.childNodes = [];\r
60197 }\r
60198 return node;\r
60199 },\r
60200 \r
60201 isLeaf: function() {\r
60202 return this.get('leaf') === true;\r
60203 },\r
60204 \r
60205 setFirstChild: function(node) {\r
60206 this.firstChild = node;\r
60207 },\r
60208 \r
60209 setLastChild: function(node) {\r
60210 this.lastChild = node;\r
60211 },\r
60212 \r
60213 updateInfo: function(commit, info) {\r
60214 var me = this,\r
60215 dataObject = me.data,\r
60216 oldDepth = dataObject.depth,\r
60217 childInfo = {},\r
60218 children = me.childNodes,\r
60219 childCount = children.length,\r
60220 phantom = me.phantom,\r
60221 fields = me.fields,\r
60222 modified = me.modified || (me.modified = {}),\r
60223 propName, newValue, field, currentValue, key,\r
60224 newParentId = info.parentId,\r
60225 settingIndexInNewParent, persistentField, i;\r
60226
60227 if (!info) {\r
60228 Ext.raise('NodeInterface expects update info to be passed');\r
60229 }\r
60230
60231
60232
60233
60234 for (propName in info) {\r
60235 field = fields[me.fieldOrdinals[propName]];\r
60236 newValue = info[propName];\r
60237 persistentField = field && field.persist;\r
60238 currentValue = dataObject[propName];\r
60239
60240
60241
60242
60243
60244 settingIndexInNewParent = persistentField && (propName === 'index') && (currentValue !== -1) && (newParentId && newParentId !== modified.parentId);\r
60245
60246 if (!settingIndexInNewParent && me.isEqual(currentValue, newValue)) {\r
60247 \r
60248 continue;\r
60249 }\r
60250 dataObject[propName] = newValue;\r
60251
60252 if (persistentField) {\r
60253
60254 if (!settingIndexInNewParent && modified.hasOwnProperty(propName)) {\r
60255
60256 if (me.isEqual(modified[propName], newValue)) {\r
60257
60258
60259 delete modified[propName];\r
60260
60261
60262
60263 me.dirty = false;\r
60264 for (key in modified) {\r
60265 if (modified.hasOwnProperty(key)) {\r
60266 me.dirty = true;\r
60267 break;\r
60268 }\r
60269 }\r
60270 }\r
60271 } else
60272 {\r
60273 me.dirty = true;\r
60274 modified[propName] = currentValue;\r
60275 }\r
60276 }\r
60277 }\r
60278 if (commit) {\r
60279 me.commit();\r
60280 me.phantom = phantom;\r
60281 }\r
60282
60283 if (me.data.depth !== oldDepth) {\r
60284 childInfo = {\r
60285 depth: me.data.depth + 1\r
60286 };\r
60287 for (i = 0; i < childCount; i++) {\r
60288 children[i].updateInfo(commit, childInfo);\r
60289 }\r
60290 }\r
60291 },\r
60292 \r
60293 isLast: function() {\r
60294 return this.get('isLast');\r
60295 },\r
60296 \r
60297 isFirst: function() {\r
60298 return this.get('isFirst');\r
60299 },\r
60300 \r
60301 hasChildNodes: function() {\r
60302 return !this.isLeaf() && this.childNodes.length > 0;\r
60303 },\r
60304 \r
60305 isExpandable: function() {\r
60306 var me = this;\r
60307 if (me.get('expandable')) {\r
60308 return !(me.isLeaf() || (me.isLoaded() && !me.phantom && !me.hasChildNodes()));\r
60309 }\r
60310 return false;\r
60311 },\r
60312 triggerUIUpdate: function() {\r
60313
60314
60315
60316 this.callJoined('afterEdit', []);\r
60317 },\r
60318 \r
60319 appendChild: function(node, suppressEvents, commit) {\r
60320 var me = this,\r
60321 i, ln, index, oldParent, previousSibling,\r
60322 childInfo = {\r
60323 isLast: true,\r
60324 parentId: me.getId(),\r
60325 depth: (me.data.depth || 0) + 1\r
60326 },\r
60327 result,\r
60328 treeStore = me.getTreeStore(),\r
60329 bulkUpdate = treeStore && treeStore.bulkUpdate;\r
60330
60331 Ext.suspendLayouts();\r
60332
60333 if (Ext.isArray(node)) {\r
60334 ln = node.length;\r
60335 result = new Array(ln);\r
60336
60337 me.callTreeStore('beginFill');\r
60338 for (i = 0; i < ln; i++) {\r
60339 result[i] = me.appendChild(node[i], suppressEvents, commit);\r
60340 }\r
60341
60342
60343 me.callTreeStore('endFill', [\r
60344 result\r
60345 ]);\r
60346 } else {\r
60347
60348 node = me.createNode(node);\r
60349 if (suppressEvents !== true && me.fireEventArgs('beforeappend', [\r
60350 me,\r
60351 node\r
60352 ]) === false) {\r
60353 Ext.resumeLayouts(true);\r
60354 return false;\r
60355 }\r
60356 index = me.childNodes.length;\r
60357 oldParent = node.parentNode;\r
60358
60359 if (oldParent) {\r
60360 if (suppressEvents !== true && node.fireEventArgs('beforemove', [\r
60361 node,\r
60362 oldParent,\r
60363 me,\r
60364 index\r
60365 ]) === false) {\r
60366 Ext.resumeLayouts(true);\r
60367 return false;\r
60368 }\r
60369
60370 if (oldParent.removeChild(node, false, suppressEvents, oldParent.getTreeStore() === treeStore) === false) {\r
60371 Ext.resumeLayouts(true);\r
60372 return false;\r
60373 }\r
60374 }\r
60375
60376
60377 treeStore && treeStore.beginUpdate();\r
60378 index = me.childNodes.length;\r
60379 if (index === 0) {\r
60380 me.setFirstChild(node);\r
60381 }\r
60382 me.childNodes[index] = node;\r
60383 node.parentNode = me;\r
60384 node.nextSibling = null;\r
60385 me.setLastChild(node);\r
60386 previousSibling = me.childNodes[index - 1];\r
60387 if (previousSibling) {\r
60388 node.previousSibling = previousSibling;\r
60389 previousSibling.nextSibling = node;\r
60390 previousSibling.updateInfo(commit, {\r
60391 isLast: false\r
60392 });\r
60393
60394 if (!bulkUpdate) {\r
60395 previousSibling.triggerUIUpdate();\r
60396 }\r
60397 } else {\r
60398 node.previousSibling = null;\r
60399 }\r
60400
60401 childInfo.isFirst = index === 0;\r
60402 childInfo.index = index;\r
60403 node.updateInfo(commit, childInfo);\r
60404
60405 if (me.isLeaf()) {\r
60406 me.set('leaf', false);\r
60407 }\r
60408
60409 if (!me.isLoaded()) {\r
60410 if (bulkUpdate) {\r
60411 me.data.loaded = true;\r
60412 } else {\r
60413 me.set('loaded', true);\r
60414 }\r
60415 } else if (me.childNodes.length === 1 && !bulkUpdate) {\r
60416 me.triggerUIUpdate();\r
60417 }\r
60418
60419 if (index && me.childNodes[index - 1].isExpanded() && !bulkUpdate) {\r
60420 me.childNodes[index - 1].cascadeBy(me.triggerUIUpdate);\r
60421 }\r
60422
60423
60424
60425
60426
60427
60428 if (treeStore) {\r
60429 treeStore.registerNode(me, !bulkUpdate);\r
60430 if (bulkUpdate) {\r
60431 treeStore.registerNode(node);\r
60432 }\r
60433 }\r
60434
60435
60436
60437 if (suppressEvents !== true) {\r
60438 me.fireEventArgs('append', [\r
60439 me,\r
60440 node,\r
60441 index\r
60442 ]);\r
60443 if (oldParent) {\r
60444 node.fireEventArgs('move', [\r
60445 node,\r
60446 oldParent,\r
60447 me,\r
60448 index\r
60449 ]);\r
60450 }\r
60451 }\r
60452
60453
60454 me.callTreeStore('onNodeAppend', [\r
60455 node,\r
60456 index\r
60457 ]);\r
60458 result = node;\r
60459
60460
60461 if (treeStore) {\r
60462 treeStore.endUpdate();\r
60463 }\r
60464 }\r
60465
60466 Ext.resumeLayouts(true);\r
60467 return result;\r
60468 },\r
60469 \r
60470 getOwnerTree: function() {\r
60471 var store = this.getTreeStore();\r
60472 if (store) {\r
60473 return store.ownerTree;\r
60474 }\r
60475 },\r
60476 \r
60477 getTreeStore: function() {\r
60478 var root = this;\r
60479 while (root && !root.treeStore) {\r
60480 root = root.parentNode;\r
60481 }\r
60482 return root && root.treeStore;\r
60483 },\r
60484 \r
60485 removeChild: function(node, erase, suppressEvents, isMove) {\r
60486 var me = this,\r
60487 index = me.indexOf(node),\r
60488 i, childCount, previousSibling,\r
60489 treeStore = me.getTreeStore(),\r
60490 bulkUpdate = treeStore && treeStore.bulkUpdate,\r
60491 removeContext;\r
60492 if (index === -1 || (suppressEvents !== true && me.fireEventArgs('beforeremove', [\r
60493 me,\r
60494 node,\r
60495 !!isMove\r
60496 ]) === false)) {\r
60497 return false;\r
60498 }\r
60499
60500 Ext.suspendLayouts();\r
60501
60502 treeStore && treeStore.beginUpdate();\r
60503
60504 Ext.Array.erase(me.childNodes, index, 1);\r
60505
60506 if (me.firstChild === node) {\r
60507 me.setFirstChild(node.nextSibling);\r
60508 }\r
60509 if (me.lastChild === node) {\r
60510 me.setLastChild(node.previousSibling);\r
60511 }\r
60512
60513 previousSibling = node.previousSibling;\r
60514 if (previousSibling) {\r
60515 node.previousSibling.nextSibling = node.nextSibling;\r
60516 }\r
60517
60518 if (node.nextSibling) {\r
60519 node.nextSibling.previousSibling = node.previousSibling;\r
60520
60521 if (index === 0) {\r
60522 node.nextSibling.updateInfo(false, {\r
60523 isFirst: true\r
60524 });\r
60525 }\r
60526
60527 for (i = index , childCount = me.childNodes.length; i < childCount; i++) {\r
60528 me.childNodes[i].updateInfo(false, {\r
60529 index: i\r
60530 });\r
60531 }\r
60532 }\r
60533
60534
60535 else if (previousSibling) {\r
60536 previousSibling.updateInfo(false, {\r
60537 isLast: true\r
60538 });\r
60539
60540
60541 if (!bulkUpdate) {\r
60542 if (previousSibling.isExpanded()) {\r
60543 previousSibling.cascadeBy(me.triggerUIUpdate);\r
60544 } else
60545 {\r
60546 previousSibling.triggerUIUpdate();\r
60547 }\r
60548 }\r
60549 }\r
60550
60551
60552 if (!me.childNodes.length && !bulkUpdate) {\r
60553 me.triggerUIUpdate();\r
60554 }\r
60555
60556 Ext.resumeLayouts(true);\r
60557 if (suppressEvents !== true) {\r
60558
60559 removeContext = {\r
60560 parentNode: node.parentNode,\r
60561 previousSibling: node.previousSibling,\r
60562 nextSibling: node.nextSibling\r
60563 };\r
60564
60565 me.callTreeStore('beforeNodeRemove', [\r
60566 [\r
60567 node\r
60568 ],\r
60569 !!isMove\r
60570 ]);\r
60571 node.previousSibling = node.nextSibling = node.parentNode = null;\r
60572 me.fireEventArgs('remove', [\r
60573 me,\r
60574 node,\r
60575 !!isMove,\r
60576 removeContext\r
60577 ]);\r
60578
60579 me.callTreeStore('onNodeRemove', [\r
60580 [\r
60581 node\r
60582 ],\r
60583 !!isMove\r
60584 ]);\r
60585 }\r
60586
60587
60588 if (erase) {\r
60589 node.erase(true);\r
60590 } else {\r
60591 node.clear();\r
60592 }\r
60593
60594
60595
60596
60597
60598
60599 if (!isMove) {\r
60600 node.set({\r
60601 parentId: null,\r
60602 lastParentId: me.getId()\r
60603 }, silently);\r
60604 }\r
60605
60606 if (treeStore) {\r
60607 treeStore.endUpdate();\r
60608 }\r
60609 return node;\r
60610 },\r
60611 \r
60612 copy: function(newId, deep) {\r
60613 var me = this,\r
60614 result = me.callParent([\r
60615 newId\r
60616 ]),\r
60617 len = me.childNodes ? me.childNodes.length : 0,\r
60618 i;\r
60619
60620 if (deep) {\r
60621 for (i = 0; i < len; i++) {\r
60622 result.appendChild(me.childNodes[i].copy(undefined, true));\r
60623 }\r
60624 }\r
60625 return result;\r
60626 },\r
60627 \r
60628 clear: function(erase) {\r
60629 var me = this;\r
60630
60631 me.parentNode = me.previousSibling = me.nextSibling = null;\r
60632 if (erase) {\r
60633 me.firstChild = me.lastChild = me.childNodes = null;\r
60634 }\r
60635 },\r
60636 drop: function() {\r
60637 var me = this,\r
60638 childNodes = me.childNodes,\r
60639 parentNode = me.parentNode,\r
60640 len = childNodes ? childNodes.length : 0,\r
60641 i, node, treeStore;\r
60642
60643
60644
60645 me.callParent();\r
60646
60647 if (parentNode) {\r
60648 treeStore = me.getTreeStore();\r
60649
60650 parentNode.removeChild(me);\r
60651 }\r
60652
60653 else if (me.get('root')) {\r
60654 treeStore = me.getTreeStore();\r
60655 treeStore.setRoot(null);\r
60656 }\r
60657
60658
60659
60660
60661
60662 treeStore && treeStore.beginUpdate();\r
60663
60664
60665 for (i = 0; i < len; i++) {\r
60666 node = childNodes[i];\r
60667
60668 node.clear();\r
60669
60670 node.drop();\r
60671 }\r
60672
60673 treeStore && treeStore.endUpdate();\r
60674 },\r
60675 \r
60676 erase: function(options) {\r
60677 var me = this,\r
60678 childNodes = me.childNodes,\r
60679 len = childNodes && childNodes.length,\r
60680 i, node;\r
60681
60682
60683
60684 me.remove();\r
60685
60686
60687 me.clear(true);\r
60688 me.callParent([\r
60689 options\r
60690 ]);\r
60691 for (i = 0; i < len; i++) {\r
60692 node = childNodes[i];\r
60693
60694
60695 node.parentNode = null;\r
60696 node.erase(options);\r
60697 }\r
60698 },\r
60699 \r
60700 insertBefore: function(node, refNode, suppressEvents) {\r
60701 var me = this,\r
60702 index = me.indexOf(refNode),\r
60703 oldParent = node.parentNode,\r
60704 refIndex = index,\r
60705 childCount, previousSibling, i,\r
60706 treeStore = me.getTreeStore(),\r
60707 bulkUpdate = treeStore && treeStore.bulkUpdate;\r
60708 if (!refNode) {\r
60709
60710 return me.appendChild(node);\r
60711 }\r
60712
60713 if (node === refNode) {\r
60714 return false;\r
60715 }\r
60716
60717 node = me.createNode(node);\r
60718 if (suppressEvents !== true && me.fireEventArgs('beforeinsert', [\r
60719 me,\r
60720 node,\r
60721 refNode\r
60722 ]) === false) {\r
60723 return false;\r
60724 }\r
60725
60726 if (oldParent === me && me.indexOf(node) < index) {\r
60727 refIndex--;\r
60728 }\r
60729
60730 if (oldParent) {\r
60731 if (suppressEvents !== true && node.fireEventArgs('beforemove', [\r
60732 node,\r
60733 oldParent,\r
60734 me,\r
60735 index,\r
60736 refNode\r
60737 ]) === false) {\r
60738 return false;\r
60739 }\r
60740
60741 if (oldParent.removeChild(node, false, suppressEvents, oldParent.getTreeStore() === treeStore) === false) {\r
60742 return false;\r
60743 }\r
60744 }\r
60745
60746
60747
60748
60749 treeStore && treeStore.beginUpdate();\r
60750 if (refIndex === 0) {\r
60751 me.setFirstChild(node);\r
60752 }\r
60753 Ext.Array.splice(me.childNodes, refIndex, 0, node);\r
60754 node.parentNode = me;\r
60755 node.nextSibling = refNode;\r
60756 refNode.previousSibling = node;\r
60757 previousSibling = me.childNodes[refIndex - 1];\r
60758 if (previousSibling) {\r
60759 node.previousSibling = previousSibling;\r
60760 previousSibling.nextSibling = node;\r
60761 } else {\r
60762 node.previousSibling = null;\r
60763 }\r
60764
60765 node.updateInfo(false, {\r
60766 parentId: me.getId(),\r
60767 index: refIndex,\r
60768 isFirst: refIndex === 0,\r
60769 isLast: false,\r
60770 depth: (me.data.depth || 0) + 1\r
60771 });\r
60772
60773 for (i = refIndex + 1 , childCount = me.childNodes.length; i < childCount; i++) {\r
60774 me.childNodes[i].updateInfo(false, {\r
60775 index: i\r
60776 });\r
60777 }\r
60778 if (!me.isLoaded()) {\r
60779 if (bulkUpdate) {\r
60780 me.data.loaded = true;\r
60781 } else {\r
60782 me.set('loaded', true);\r
60783 }\r
60784 }\r
60785
60786 else if (me.childNodes.length === 1 && !bulkUpdate) {\r
60787 me.triggerUIUpdate();\r
60788 }\r
60789
60790
60791
60792 if (treeStore) {\r
60793 treeStore.registerNode(me, !bulkUpdate);\r
60794 }\r
60795
60796
60797
60798 if (suppressEvents !== true) {\r
60799 me.fireEventArgs('insert', [\r
60800 me,\r
60801 node,\r
60802 refNode\r
60803 ]);\r
60804 if (oldParent) {\r
60805 node.fireEventArgs('move', [\r
60806 node,\r
60807 oldParent,\r
60808 me,\r
60809 refIndex,\r
60810 refNode\r
60811 ]);\r
60812 }\r
60813 }\r
60814
60815 me.callTreeStore('onNodeInsert', [\r
60816 node,\r
60817 refIndex\r
60818 ]);\r
60819
60820
60821 if (treeStore) {\r
60822 treeStore.endUpdate();\r
60823 }\r
60824 return node;\r
60825 },\r
60826 \r
60827 insertChild: function(index, node) {\r
60828 var sibling = this.childNodes[index];\r
60829 if (sibling) {\r
60830 return this.insertBefore(node, sibling);\r
60831 } else {\r
60832 return this.appendChild(node);\r
60833 }\r
60834 },\r
60835 \r
60836 isLastVisible: function() {\r
60837 var me = this,\r
60838 result = me.data.isLast,\r
60839 next = me.nextSibling;\r
60840
60841
60842
60843 if (!result && me.getTreeStore().isFiltered()) {\r
60844 while (next) {\r
60845 if (next.data.visible) {\r
60846 return false;\r
60847 }\r
60848 next = next.nextSibling;\r
60849 }\r
60850 return true;\r
60851 }\r
60852 return result;\r
60853 },\r
60854 \r
60855 remove: function(erase, suppressEvents) {\r
60856 var me = this,\r
60857 parentNode = me.parentNode;\r
60858 if (parentNode) {\r
60859 parentNode.removeChild(me, erase, suppressEvents);\r
60860 } else if (erase) {\r
60861
60862 me.erase(true);\r
60863 }\r
60864 return me;\r
60865 },\r
60866 \r
60867 removeAll: function(erase, suppressEvents, fromParent) {\r
60868
60869
60870
60871 var me = this,\r
60872 childNodes = me.childNodes,\r
60873 len = childNodes.length,\r
60874 node, treeStore, i;\r
60875
60876 if (!len) {\r
60877 return;\r
60878 }\r
60879
60880 if (!fromParent) {\r
60881 treeStore = me.getTreeStore();\r
60882
60883 if (treeStore) {\r
60884 treeStore.beginUpdate();\r
60885
60886
60887
60888 treeStore.suspendEvent('remove');\r
60889 me.callTreeStore('beforeNodeRemove', [\r
60890 childNodes,\r
60891 false\r
60892 ]);\r
60893 }\r
60894 }\r
60895 for (i = 0; i < len; ++i) {\r
60896 node = childNodes[i];\r
60897 node.previousSibling = node.nextSibling = node.parentNode = null;\r
60898 me.fireEventArgs('remove', [\r
60899 me,\r
60900 node,\r
60901 false\r
60902 ]);\r
60903 if (erase) {\r
60904 node.erase(true);\r
60905 } else
60906 {\r
60907 node.removeAll(false, suppressEvents, true);\r
60908 }\r
60909 }\r
60910
60911 if (!fromParent && treeStore) {\r
60912 treeStore.resumeEvent('remove');\r
60913 me.callTreeStore('onNodeRemove', [\r
60914 childNodes,\r
60915 false\r
60916 ]);\r
60917
60918 treeStore.endUpdate();\r
60919 }\r
60920 me.firstChild = me.lastChild = null;\r
60921 childNodes.length = 0;\r
60922 if (!fromParent) {\r
60923 me.triggerUIUpdate();\r
60924 }\r
60925 return me;\r
60926 },\r
60927 \r
60928 getChildAt: function(index) {\r
60929 return this.childNodes[index];\r
60930 },\r
60931 \r
60932 replaceChild: function(newChild, oldChild, suppressEvents) {\r
60933 var s = oldChild ? oldChild.nextSibling : null;\r
60934 this.removeChild(oldChild, false, suppressEvents);\r
60935 this.insertBefore(newChild, s, suppressEvents);\r
60936 return oldChild;\r
60937 },\r
60938 \r
60939 indexOf: function(child) {\r
60940 return Ext.Array.indexOf(this.childNodes, child);\r
60941 },\r
60942 \r
60943 indexOfId: function(id) {\r
60944 var childNodes = this.childNodes,\r
60945 len = childNodes.length,\r
60946 i = 0;\r
60947 for (; i < len; ++i) {\r
60948 if (childNodes[i].getId() === id) {\r
60949 return i;\r
60950 }\r
60951 }\r
60952 return -1;\r
60953 },\r
60954 \r
60955 getPath: function(field, separator) {\r
60956 field = field || this.idProperty;\r
60957 separator = separator || '/';\r
60958 var path = [\r
60959 this.get(field)\r
60960 ],\r
60961 parent = this.parentNode;\r
60962 while (parent) {\r
60963 path.unshift(parent.get(field));\r
60964 parent = parent.parentNode;\r
60965 }\r
60966 return separator + path.join(separator);\r
60967 },\r
60968 \r
60969 getDepth: function() {\r
60970 return this.get('depth');\r
60971 },\r
60972 \r
60973 bubble: function(fn, scope, args) {\r
60974 var p = this;\r
60975 while (p) {\r
60976 if (fn.apply(scope || p, args || [\r
60977 p\r
60978 ]) === false) {\r
60979 break;\r
60980 }\r
60981 p = p.parentNode;\r
60982 }\r
60983 },\r
60984 \r
60985 cascadeBy: function(before, scope, args, after) {\r
60986 var me = this;\r
60987 if (arguments.length === 1 && !Ext.isFunction(before)) {\r
60988 after = before.after;\r
60989 scope = before.scope;\r
60990 args = before.args;\r
60991 before = before.before;\r
60992 }\r
60993 if (!before || before.apply(scope || me, args || [\r
60994 me\r
60995 ]) !== false) {\r
60996 var childNodes = me.childNodes,\r
60997 length = childNodes.length,\r
60998 i;\r
60999 for (i = 0; i < length; i++) {\r
61000 childNodes[i].cascadeBy.call(childNodes[i], before, scope, args, after);\r
61001 }\r
61002 if (after) {\r
61003 after.apply(scope || me, args || [\r
61004 me\r
61005 ]);\r
61006 }\r
61007 }\r
61008 },\r
61009 \r
61010 eachChild: function(fn, scope, args) {\r
61011 var childNodes = this.childNodes,\r
61012 length = childNodes.length,\r
61013 i;\r
61014 for (i = 0; i < length; i++) {\r
61015 if (fn.apply(scope || this, args || [\r
61016 childNodes[i]\r
61017 ]) === false) {\r
61018 break;\r
61019 }\r
61020 }\r
61021 },\r
61022 \r
61023 findChild: function(attribute, value, deep) {\r
61024 return this.findChildBy(function() {\r
61025 return this.get(attribute) == value;\r
61026 }, null, deep);\r
61027 },\r
61028 \r
61029 findChildBy: function(fn, scope, deep) {\r
61030 var cs = this.childNodes,\r
61031 len = cs.length,\r
61032 i = 0,\r
61033 n, res;\r
61034 for (; i < len; i++) {\r
61035 n = cs[i];\r
61036 if (fn.call(scope || n, n) === true) {\r
61037 return n;\r
61038 } else if (deep) {\r
61039 res = n.findChildBy(fn, scope, deep);\r
61040 if (res !== null) {\r
61041 return res;\r
61042 }\r
61043 }\r
61044 }\r
61045 return null;\r
61046 },\r
61047 \r
61048 contains: function(node) {\r
61049 return node.isAncestor(this);\r
61050 },\r
61051 \r
61052 isAncestor: function(node) {\r
61053 var p = this.parentNode;\r
61054 while (p) {\r
61055 if (p === node) {\r
61056 return true;\r
61057 }\r
61058 p = p.parentNode;\r
61059 }\r
61060 return false;\r
61061 },\r
61062 \r
61063 sort: function(sortFn, recursive, suppressEvent) {\r
61064 var me = this,\r
61065 childNodes = me.childNodes,\r
61066 ln = childNodes.length,\r
61067 i, n,\r
61068 info = {\r
61069 isFirst: true\r
61070 };\r
61071 if (ln > 0) {\r
61072 if (!sortFn) {\r
61073 sortFn = me.getTreeStore().getSortFn();\r
61074 }\r
61075 Ext.Array.sort(childNodes, sortFn);\r
61076 me.setFirstChild(childNodes[0]);\r
61077 me.setLastChild(childNodes[ln - 1]);\r
61078 for (i = 0; i < ln; i++) {\r
61079 n = childNodes[i];\r
61080 n.previousSibling = childNodes[i - 1];\r
61081 n.nextSibling = childNodes[i + 1];\r
61082
61083 info.isLast = (i === ln - 1);\r
61084 info.index = i;\r
61085 n.updateInfo(false, info);\r
61086 info.isFirst = false;\r
61087 if (recursive && !n.isLeaf()) {\r
61088 n.sort(sortFn, true, true);\r
61089 }\r
61090 }\r
61091
61092 if (suppressEvent !== true) {\r
61093 me.fireEventArgs('sort', [\r
61094 me,\r
61095 childNodes\r
61096 ]);\r
61097
61098 me.callTreeStore('onNodeSort', [\r
61099 childNodes\r
61100 ]);\r
61101 }\r
61102 }\r
61103 },\r
61104 \r
61105 isExpanded: function() {\r
61106 return this.get('expanded');\r
61107 },\r
61108 \r
61109 isLoaded: function() {\r
61110 return this.get('loaded');\r
61111 },\r
61112 \r
61113 isBranchLoaded: function() {\r
61114 var isBranchLoaded = !this.isLeaf() && this.isLoaded();\r
61115 if (isBranchLoaded) {\r
61116 this.cascadeBy(function(node) {\r
61117 if (!node.isLeaf()) {\r
61118 isBranchLoaded = isBranchLoaded || node.isBranchLoaded();\r
61119 }\r
61120 return isBranchLoaded;\r
61121 });\r
61122 }\r
61123 return isBranchLoaded;\r
61124 },\r
61125 \r
61126 isLoading: function() {\r
61127 return this.get('loading');\r
61128 },\r
61129 \r
61130 isRoot: function() {\r
61131 return !this.parentNode;\r
61132 },\r
61133 \r
61134 isVisible: function() {\r
61135 var parent = this.parentNode;\r
61136 while (parent) {\r
61137 if (!parent.isExpanded()) {\r
61138 return false;\r
61139 }\r
61140 parent = parent.parentNode;\r
61141 }\r
61142 return true;\r
61143 },\r
61144 \r
61145 expand: function(recursive, callback, scope) {\r
61146 var me = this,\r
61147 treeStore, resumeAddEvent;\r
61148
61149
61150
61151 if (!me.isLeaf()) {\r
61152
61153 if (me.isLoading()) {\r
61154 me.on('expand', function() {\r
61155 me.expand(recursive, callback, scope);\r
61156 }, me, {\r
61157 single: true\r
61158 });\r
61159 } else {\r
61160
61161 if (!me.isExpanded()) {\r
61162 if (me.fireEventArgs('beforeexpand', [\r
61163 me\r
61164 ]) !== false) {\r
61165
61166
61167
61168
61169
61170
61171
61172
61173
61174
61175 if (recursive) {\r
61176
61177
61178
61179 if (me.parentNode && me.parentNode.isSynchronousRecursiveExpand) {\r
61180 me.isSynchronousRecursiveExpand = true;\r
61181 } else {\r
61182 treeStore = me.getTreeStore();\r
61183 if (treeStore.getProxy().isSynchronous || me.isBranchLoaded()) {\r
61184 me.isSynchronousRecursiveExpand = true;\r
61185 treeStore.suspendEvent('add');\r
61186 resumeAddEvent = true;\r
61187 }\r
61188 }\r
61189 }\r
61190
61191
61192 me.callTreeStore('onBeforeNodeExpand', [\r
61193 me.onChildNodesAvailable,\r
61194 me,\r
61195 [\r
61196 recursive,\r
61197 callback,\r
61198 scope\r
61199 ]\r
61200 ]);\r
61201
61202
61203 if (resumeAddEvent) {\r
61204 treeStore.resumeEvent('add');\r
61205 treeStore.fireEvent('refresh', treeStore);\r
61206 }\r
61207 me.isSynchronousRecursiveExpand = false;\r
61208 }\r
61209 } else if (recursive) {\r
61210
61211 me.expandChildren(true, callback, scope);\r
61212 } else {\r
61213 Ext.callback(callback, scope || me, [\r
61214 me.childNodes\r
61215 ]);\r
61216 }\r
61217 }\r
61218 } else {\r
61219
61220 Ext.callback(callback, scope || me);\r
61221 }\r
61222 },\r
61223
61224 \r
61225 onChildNodesAvailable: function(records, recursive, callback, scope) {\r
61226 var me = this,\r
61227 treeStore = me.getTreeStore(),\r
61228 bulkUpdate = treeStore && treeStore.bulkUpdate,\r
61229 ancestor, i, collapsedAncestors;\r
61230
61231
61232 Ext.suspendLayouts();\r
61233
61234
61235
61236 for (ancestor = me.parentNode; ancestor; ancestor = ancestor.parentNode) {\r
61237 if (!ancestor.isExpanded()) {\r
61238 (collapsedAncestors || (collapsedAncestors = [])).unshift(ancestor);\r
61239 }\r
61240 }\r
61241
61242 if (bulkUpdate) {\r
61243 me.data.expanded = true;\r
61244 } else {\r
61245 me.set('expanded', true);\r
61246 }\r
61247
61248
61249 if (collapsedAncestors) {\r
61250
61251
61252 for (i = 1; i < collapsedAncestors.length; i++) {\r
61253 ancestor = collapsedAncestors[i];\r
61254 if (bulkUpdate) {\r
61255 ancestor.data.expanded = true;\r
61256 } else {\r
61257 ancestor.set('expanded', true);\r
61258 }\r
61259 }\r
61260
61261
61262
61263 collapsedAncestors[0].expand();\r
61264
61265 for (i = 1; i < collapsedAncestors.length; i++) {\r
61266 ancestor = collapsedAncestors[i];\r
61267 ancestor.fireEventArgs('expand', [\r
61268 ancestor,\r
61269 ancestor.childNodes\r
61270 ]);\r
61271 }\r
61272 } else {\r
61273
61274 me.callTreeStore('onNodeExpand', [\r
61275 records,\r
61276 false\r
61277 ]);\r
61278 }\r
61279 me.fireEventArgs('expand', [\r
61280 me,\r
61281 records\r
61282 ]);\r
61283
61284 if (recursive) {\r
61285 me.expandChildren(true, callback, scope);\r
61286 } else {\r
61287 Ext.callback(callback, scope || me, [\r
61288 me.childNodes\r
61289 ]);\r
61290 }\r
61291 Ext.resumeLayouts(true);\r
61292 },\r
61293 \r
61294 expandChildren: function(recursive, callback, scope, \r
61295 singleExpand) {\r
61296 var me = this,\r
61297 origCallback, i, allNodes, expandNodes, ln, node, treeStore;\r
61298
61299
61300
61301
61302 if (Ext.isBoolean(callback)) {\r
61303 origCallback = callback;\r
61304 callback = scope;\r
61305 scope = singleExpand;\r
61306 singleExpand = origCallback;\r
61307 }\r
61308 if (singleExpand === undefined) {\r
61309 treeStore = me.getTreeStore();\r
61310 singleExpand = treeStore && treeStore.singleExpand;\r
61311 }\r
61312 allNodes = me.childNodes;\r
61313 expandNodes = [];\r
61314 ln = singleExpand ? Math.min(allNodes.length, 1) : allNodes.length;\r
61315 for (i = 0; i < ln; ++i) {\r
61316 node = allNodes[i];\r
61317 if (!node.isLeaf()) {\r
61318 expandNodes[expandNodes.length] = node;\r
61319 }\r
61320 }\r
61321 ln = expandNodes.length;\r
61322 for (i = 0; i < ln; ++i) {\r
61323 expandNodes[i].expand(recursive);\r
61324 }\r
61325 if (callback) {\r
61326 Ext.callback(callback, scope || me, [\r
61327 me.childNodes\r
61328 ]);\r
61329 }\r
61330 },\r
61331 \r
61332 collapse: function(recursive, callback, scope) {\r
61333 var me = this,\r
61334 expanded = me.isExpanded(),\r
61335 treeStore = me.getTreeStore(),\r
61336 bulkUpdate = treeStore && treeStore.bulkUpdate,\r
61337 len = me.childNodes.length,\r
61338 i, collapseChildren;\r
61339
61340
61341
61342
61343 if (!me.isLeaf() && ((!expanded && recursive) || me.fireEventArgs('beforecollapse', [\r
61344 me\r
61345 ]) !== false)) {\r
61346
61347
61348 Ext.suspendLayouts();\r
61349
61350 if (me.isExpanded()) {\r
61351
61352
61353
61354
61355
61356 if (recursive) {\r
61357 collapseChildren = function() {\r
61358 for (i = 0; i < len; i++) {\r
61359 me.childNodes[i].setCollapsed(true);\r
61360 }\r
61361 };\r
61362 if (callback) {\r
61363 callback = Ext.Function.createSequence(collapseChildren, Ext.Function.bind(callback, scope, [\r
61364 me.childNodes\r
61365 ]));\r
61366 } else {\r
61367 callback = collapseChildren;\r
61368 }\r
61369 } else if (callback) {\r
61370 callback = Ext.Function.bind(callback, scope, [\r
61371 me.childNodes\r
61372 ]);\r
61373 }\r
61374
61375 if (bulkUpdate) {\r
61376 me.data.expanded = false;\r
61377 } else {\r
61378 me.set('expanded', false);\r
61379 }\r
61380
61381
61382
61383 me.callTreeStore('onNodeCollapse', [\r
61384 me.childNodes,\r
61385 callback,\r
61386 scope\r
61387 ]);\r
61388 me.fireEventArgs('collapse', [\r
61389 me,\r
61390 me.childNodes\r
61391 ]);\r
61392
61393 callback = null;\r
61394 }\r
61395
61396
61397
61398
61399 else if (recursive) {\r
61400 for (i = 0; i < len; i++) {\r
61401 me.childNodes[i].setCollapsed(true);\r
61402 }\r
61403 }\r
61404 Ext.resumeLayouts(true);\r
61405 }\r
61406
61407 Ext.callback(callback, scope || me, [\r
61408 me.childNodes\r
61409 ]);\r
61410 },\r
61411 \r
61412 setCollapsed: function(recursive) {\r
61413 var me = this,\r
61414 len = me.childNodes.length,\r
61415 i;\r
61416
61417 if (!me.isLeaf() && me.fireEventArgs('beforecollapse', [\r
61418 me\r
61419 ]) !== false) {\r
61420
61421 me.data.expanded = false;\r
61422
61423
61424
61425 me.fireEventArgs('collapse', [\r
61426 me,\r
61427 me.childNodes\r
61428 ]);\r
61429 if (recursive) {\r
61430 for (i = 0; i < len; i++) {\r
61431 me.childNodes[i].setCollapsed(true);\r
61432 }\r
61433 }\r
61434 }\r
61435 },\r
61436 \r
61437 collapseChildren: function(recursive, callback, scope) {\r
61438 var me = this,\r
61439 i,\r
61440 allNodes = me.childNodes,\r
61441 ln = allNodes.length,\r
61442 collapseNodes = [],\r
61443 node;\r
61444
61445 for (i = 0; i < ln; ++i) {\r
61446 node = allNodes[i];\r
61447 if (!node.isLeaf() && node.isLoaded() && node.isExpanded()) {\r
61448 collapseNodes.push(node);\r
61449 }\r
61450 }\r
61451 ln = collapseNodes.length;\r
61452 if (ln) {\r
61453
61454
61455 for (i = 0; i < ln; ++i) {\r
61456 node = collapseNodes[i];\r
61457 if (i === ln - 1) {\r
61458 node.collapse(recursive, callback, scope);\r
61459 } else {\r
61460 node.collapse(recursive);\r
61461 }\r
61462 }\r
61463 } else {\r
61464
61465 Ext.callback(callback, scope);\r
61466 }\r
61467 },\r
61468 \r
61469 fireEvent: function(eventName) {\r
61470 return this.fireEventArgs(eventName, Ext.Array.slice(arguments, 1));\r
61471 },\r
61472
61473
61474
61475 fireEventArgs: function(eventName, args) {\r
61476
61477
61478
61479 var fireEventArgs = Ext.mixin.Observable.prototype.fireEventArgs,\r
61480 result, eventSource, topNode;\r
61481
61482 if (bubbledEvents[eventName]) {\r
61483 for (eventSource = this; result !== false && eventSource; eventSource = (topNode = eventSource).parentNode) {\r
61484 if (eventSource.hasListeners && eventSource.hasListeners[eventName]) {\r
61485 result = fireEventArgs.call(eventSource, eventName, args);\r
61486 }\r
61487 }\r
61488
61489
61490 if (result !== false) {\r
61491 eventSource = topNode.getTreeStore();\r
61492 if (eventSource && eventSource.hasListeners && eventSource.hasListeners[eventName = 'node' + eventName]) {\r
61493 result = eventSource.fireEventArgs(eventName, args);\r
61494 }\r
61495 }\r
61496 return result;\r
61497 } else
61498 {\r
61499 return fireEventArgs.apply(this, arguments);\r
61500 }\r
61501 },\r
61502 \r
61503 serialize: function(writerParam) {\r
61504 var writer = writerParam || new Ext.data.writer.Json({\r
61505 writeAllFields: true\r
61506 }),\r
61507 result = writer.getRecordData(this),\r
61508 childNodes = this.childNodes,\r
61509 len = childNodes.length,\r
61510 children, i;\r
61511 if (len > 0) {\r
61512 result.children = children = [];\r
61513 for (i = 0; i < len; i++) {\r
61514 children.push(childNodes[i].serialize(writer));\r
61515 }\r
61516 }\r
61517 return result;\r
61518 },\r
61519
61520 callTreeStore: function(funcName, args) {\r
61521 var me = this,\r
61522 target = me.getTreeStore(),\r
61523 fn = target && target[funcName];\r
61524 if (target && fn) {\r
61525 args = args || [];\r
61526 if (args[0] !== me) {\r
61527 args.unshift(me);\r
61528 }\r
61529 fn.apply(target, args);\r
61530 }\r
61531 },\r
61532
61533 privates: {\r
61534 join: function(store) {\r
61535
61536 if (store.isTreeStore) {\r
61537 if (this.isRoot()) {\r
61538 this.treeStore = this.store = store;\r
61539 }\r
61540 } else
61541
61542 {\r
61543 this.callParent([\r
61544 store\r
61545 ]);\r
61546 }\r
61547 },\r
61548
61549 callJoined: function(funcName, args) {\r
61550 this.callParent([\r
61551 funcName,\r
61552 args\r
61553 ]);\r
61554 this.callTreeStore(funcName, args);\r
61555 }\r
61556 }\r
61557 };\r
61558 }\r
61559 }\r
61560});\r
61561\r
61562\r
61563Ext.define('Ext.data.TreeModel', {\r
61564 extend: Ext.data.Model,\r
61565 mixins: [\r
61566 Ext.mixin.Queryable\r
61567 ],\r
61568 \r
61569 getRefItems: function() {\r
61570 return this.childNodes;\r
61571 },\r
61572 getRefOwner: function() {\r
61573 return this.parentNode;\r
61574 },\r
61575 statics: {\r
61576 defaultProxy: 'memory'\r
61577 }\r
61578}, function() {\r
61579 Ext.data.NodeInterface.decorate(this);\r
61580});\r
61581\r
61582\r
61583Ext.define('Ext.data.NodeStore', {\r
61584 extend: Ext.data.Store,\r
61585 alias: 'store.node',\r
61586 \r
61587 isNodeStore: true,\r
61588 config: {\r
61589 \r
61590 node: null,\r
61591 \r
61592 recursive: false,\r
61593 \r
61594 rootVisible: false,\r
61595 \r
61596 folderSort: false\r
61597 },\r
61598 implicitModel: 'Ext.data.TreeModel',\r
61599
61600
61601
61602 getTotalCount: function() {\r
61603 return this.getCount();\r
61604 },\r
61605 updateFolderSort: function(folderSort) {\r
61606 var data = this.getData();\r
61607 data.setTrackGroups(false);\r
61608 if (folderSort) {\r
61609 data.setGrouper({\r
61610 groupFn: this.folderSortFn\r
61611 });\r
61612 } else {\r
61613 data.setGrouper(null);\r
61614 }\r
61615 },\r
61616 folderSortFn: function(node) {\r
61617 return node.data.leaf ? 1 : 0;\r
61618 },\r
61619 afterReject: function(record) {\r
61620 var me = this;\r
61621
61622
61623
61624
61625
61626 if (me.contains(record)) {\r
61627 me.onUpdate(record, Ext.data.Model.REJECT, null);\r
61628 me.fireEvent('update', me, record, Ext.data.Model.REJECT, null);\r
61629 }\r
61630 },\r
61631 afterCommit: function(record, modifiedFieldNames) {\r
61632 var me = this;\r
61633 if (!modifiedFieldNames) {\r
61634 modifiedFieldNames = null;\r
61635 }\r
61636 if (me.contains(record)) {\r
61637 me.onUpdate(record, Ext.data.Model.COMMIT, modifiedFieldNames);\r
61638 me.fireEvent('update', me, record, Ext.data.Model.COMMIT, modifiedFieldNames);\r
61639 }\r
61640 },\r
61641 onNodeAppend: function(parent, node) {\r
61642 if (parent === this.getNode()) {\r
61643 this.add([\r
61644 node\r
61645 ].concat(this.retrieveChildNodes(node)));\r
61646 }\r
61647 },\r
61648 onNodeInsert: function(parent, node, refNode) {\r
61649 var me = this,\r
61650 idx;\r
61651 if (parent === me.getNode()) {\r
61652 idx = me.indexOf(refNode) || 0;\r
61653 me.insert(0, [\r
61654 node\r
61655 ].concat(me.retrieveChildNodes(node)));\r
61656 }\r
61657 },\r
61658 onNodeRemove: function(parent, node) {\r
61659 if (parent === this.getNode()) {\r
61660 this.remove([\r
61661 node\r
61662 ].concat(this.retrieveChildNodes(node)));\r
61663 }\r
61664 },\r
61665 onNodeExpand: function(parent, records) {\r
61666 if (parent === this.getNode()) {\r
61667 this.loadRecords(records);\r
61668 }\r
61669 },\r
61670 applyNode: function(node) {\r
61671 if (node) {\r
61672 if (!node.isModel) {\r
61673 node = new (this.getModel())(node);\r
61674 }\r
61675 if (!node.isNode) {\r
61676 Ext.data.NodeInterface.decorate(node);\r
61677 }\r
61678 }\r
61679 return node;\r
61680 },\r
61681 updateNode: function(node, oldNode) {\r
61682 var me = this,\r
61683 data;\r
61684 if (oldNode && !oldNode.destroyed) {\r
61685 oldNode.un({\r
61686 append: 'onNodeAppend',\r
61687 insert: 'onNodeInsert',\r
61688 remove: 'onNodeRemove',\r
61689 scope: me\r
61690 });\r
61691 oldNode.unjoin(me);\r
61692 }\r
61693 if (node) {\r
61694 node.on({\r
61695 scope: me,\r
61696 append: 'onNodeAppend',\r
61697 insert: 'onNodeInsert',\r
61698 remove: 'onNodeRemove'\r
61699 });\r
61700 node.join(me);\r
61701 data = [];\r
61702 if (node.childNodes.length) {\r
61703 data = data.concat(me.retrieveChildNodes(node));\r
61704 }\r
61705 if (me.getRootVisible()) {\r
61706 data.push(node);\r
61707 } else if (node.isLoaded() || node.isLoading()) {\r
61708 node.set('expanded', true);\r
61709 }\r
61710 me.getData().clear();\r
61711 me.fireEvent('clear', me);\r
61712 me.suspendEvents();\r
61713 if (me.isInitializing) {\r
61714 me.inlineData = data;\r
61715 } else {\r
61716 me.add(data);\r
61717 }\r
61718 me.resumeEvents();\r
61719 if (data.length === 0) {\r
61720 me.loaded = node.loaded = true;\r
61721 }\r
61722 me.fireEvent('refresh', me, me.data);\r
61723 }\r
61724 },\r
61725 \r
61726 isVisible: function(node) {\r
61727 var parent = node.parentNode;\r
61728 if (!this.getRecursive() && parent !== this.getNode()) {\r
61729 return false;\r
61730 }\r
61731 while (parent) {\r
61732 if (!parent.isExpanded()) {\r
61733 return false;\r
61734 }\r
61735
61736
61737
61738 if (parent === this.getNode()) {\r
61739 break;\r
61740 }\r
61741 parent = parent.parentNode;\r
61742 }\r
61743 return true;\r
61744 },\r
61745 privates: {\r
61746 \r
61747 retrieveChildNodes: function(root) {\r
61748 var node = this.getNode(),\r
61749 recursive = this.getRecursive(),\r
61750 added = [],\r
61751 child = root;\r
61752 if (!root.childNodes.length || (!recursive && root !== node)) {\r
61753 return added;\r
61754 }\r
61755 if (!recursive) {\r
61756 return root.childNodes;\r
61757 }\r
61758 while (child) {\r
61759 if (child._added) {\r
61760 delete child._added;\r
61761 if (child === root) {\r
61762 break;\r
61763 } else {\r
61764 child = child.nextSibling || child.parentNode;\r
61765 }\r
61766 } else {\r
61767 if (child !== root) {\r
61768 added.push(child);\r
61769 }\r
61770 if (child.firstChild) {\r
61771 child._added = true;\r
61772 child = child.firstChild;\r
61773 } else {\r
61774 child = child.nextSibling || child.parentNode;\r
61775 }\r
61776 }\r
61777 }\r
61778 return added;\r
61779 }\r
61780 }\r
61781});\r
61782\r
61783\r
61784Ext.define('Ext.data.Request', {\r
61785 config: {\r
61786 \r
61787 action: undefined,\r
61788 \r
61789 params: undefined,\r
61790 \r
61791 method: 'GET',\r
61792 \r
61793 url: null,\r
61794 \r
61795 operation: null,\r
61796 \r
61797 proxy: null,\r
61798 \r
61799 disableCaching: false,\r
61800 \r
61801 headers: {},\r
61802 \r
61803 callbackKey: null,\r
61804 \r
61805 rawRequest: null,\r
61806 \r
61807 jsonData: undefined,\r
61808 \r
61809 xmlData: undefined,\r
61810 \r
61811 withCredentials: false,\r
61812 \r
61813 username: null,\r
61814 \r
61815 password: null,\r
61816 \r
61817 binary: false,\r
61818 callback: null,\r
61819 scope: null,\r
61820 timeout: 30000,\r
61821 records: null,\r
61822
61823
61824 directFn: null,\r
61825 args: null,\r
61826 useDefaultXhrHeader: null\r
61827 },\r
61828 \r
61829 constructor: function(config) {\r
61830 this.initConfig(config);\r
61831 },\r
61832 \r
61833 getParam: function(key) {\r
61834 var params = this.getParams(),\r
61835 val;\r
61836 if (params) {\r
61837 return params[key];\r
61838 }\r
61839 return val;\r
61840 },\r
61841 \r
61842 setParam: function(key, value) {\r
61843 var params = this.getParams() || {};\r
61844 params[key] = value;\r
61845 this.setParams(params);\r
61846 }\r
61847});\r
61848\r
61849\r
61850Ext.define('Ext.data.TreeStore', {\r
61851 extend: Ext.data.Store,\r
61852 alias: 'store.tree',\r
61853 \r
61854 isTreeStore: true,\r
61855 config: {\r
61856 \r
61857 root: null,\r
61858 \r
61859 rootVisible: false,\r
61860 \r
61861 defaultRootProperty: 'children',\r
61862 \r
61863 parentIdProperty: null,\r
61864 \r
61865 clearOnLoad: true,\r
61866 \r
61867 clearRemovedOnLoad: true,\r
61868 \r
61869 nodeParam: 'node',\r
61870 \r
61871 defaultRootId: 'root',\r
61872 \r
61873 defaultRootText: 'Root',\r
61874 \r
61875 folderSort: false\r
61876 },\r
61877 \r
61878 lazyFill: false,\r
61879 fillCount: 0,\r
61880 bulkUpdate: 0,\r
61881 \r
61882 _silentOptions: {\r
61883 silent: true\r
61884 },\r
61885 implicitModel: 'Ext.data.TreeModel',\r
61886 constructor: function(config) {\r
61887 var me = this;\r
61888 me.byIdMap = {};\r
61889 me.callParent([\r
61890 config\r
61891 ]);\r
61892
61893 \r
61894 \r
61895 \r
61896 \r
61897 \r
61898 \r
61899 \r
61900 \r
61901 \r
61902 \r
61903 \r
61904 \r
61905 \r
61906
61907 if (Ext.isDefined(me.nodeParameter)) {\r
61908 if (Ext.isDefined(Ext.global.console)) {\r
61909 Ext.global.console.warn('Ext.data.TreeStore: nodeParameter has been deprecated. Please use nodeParam instead.');\r
61910 }\r
61911 me.nodeParam = me.nodeParameter;\r
61912 delete me.nodeParameter;\r
61913 }\r
61914 },\r
61915
61916 \r
61917 applyFields: function(fields, oldFields) {\r
61918 var me = this;\r
61919 if (fields) {\r
61920 if (me.defaultRootProperty !== me.self.prototype.config.defaultRootProperty) {\r
61921
61922 fields = fields.concat({\r
61923 name: me.defaultRootProperty,\r
61924 type: 'auto',\r
61925 defaultValue: null,\r
61926 persist: false\r
61927 });\r
61928 }\r
61929 }\r
61930 me.callParent([\r
61931 fields,\r
61932 oldFields\r
61933 ]);\r
61934 },\r
61935
61936 onSorterEndUpdate: function() {\r
61937 var me = this,\r
61938 sorterCollection = me.getSorters(),\r
61939 sorters = sorterCollection.getRange(),\r
61940 rootNode = me.getRoot(),\r
61941 folderSort = me.getFolderSort();\r
61942 me.fireEvent('beforesort', me, sorters);\r
61943
61944 if (rootNode && (folderSort || sorters.length)) {\r
61945 if (me.getRemoteSort()) {\r
61946 if (sorters.length) {\r
61947 me.load({\r
61948 callback: function() {\r
61949 me.fireEvent('sort', me, sorters);\r
61950 }\r
61951 });\r
61952 }\r
61953 } else {\r
61954 rootNode.sort(this.getSortFn(), true);\r
61955
61956 me.fireEvent('datachanged', me);\r
61957 me.fireEvent('refresh', me);\r
61958 me.fireEvent('sort', me, sorters);\r
61959 }\r
61960 } else
61961 {\r
61962 me.fireEvent('sort', me, sorters);\r
61963 }\r
61964 },\r
61965 updateFolderSort: function(folderSort) {\r
61966 this.needsFolderSort = folderSort;\r
61967 this.onSorterEndUpdate();\r
61968 },\r
61969 getSortFn: function() {\r
61970 return this._sortFn || (this._sortFn = this.createSortFn());\r
61971 },\r
61972 createSortFn: function() {\r
61973 var me = this,\r
61974 sortersSortFn = this.sorters.getSortFn();\r
61975 return function(node1, node2) {\r
61976 var node1FolderOrder, node2FolderOrder,\r
61977 result = 0;\r
61978 if (me.needsFolderSort) {\r
61979
61980 node1FolderOrder = node1.data.leaf ? 1 : 0;\r
61981 node2FolderOrder = node2.data.leaf ? 1 : 0;\r
61982 result = node1FolderOrder - node2FolderOrder;\r
61983 }\r
61984 if (me.needsIndexSort && result === 0) {\r
61985 result = node1.data.index - node2.data.index;\r
61986 }\r
61987 return result || sortersSortFn(node1, node2);\r
61988 };\r
61989 },\r
61990 getTotalCount: function() {\r
61991 return this.getCount();\r
61992 },\r
61993 afterEdit: function(node, modifiedFieldNames) {\r
61994 var me = this;\r
61995 if (me.needsLocalFilter()) {\r
61996 me.doFilter(node);\r
61997 }\r
61998 me.callParent([\r
61999 node,\r
62000 modifiedFieldNames\r
62001 ]);\r
62002 },\r
62003 afterReject: function(record) {\r
62004 var me = this;\r
62005
62006
62007
62008
62009
62010 if (me.contains(record)) {\r
62011 me.onUpdate(record, Ext.data.Model.REJECT, null);\r
62012 me.fireEvent('update', me, record, Ext.data.Model.REJECT, null);\r
62013 }\r
62014 },\r
62015 afterCommit: function(record, modifiedFieldNames) {\r
62016 var me = this;\r
62017 if (!modifiedFieldNames) {\r
62018 modifiedFieldNames = null;\r
62019 }\r
62020 if (me.contains(record)) {\r
62021 me.onUpdate(record, Ext.data.Model.COMMIT, modifiedFieldNames);\r
62022 me.fireEvent('update', me, record, Ext.data.Model.COMMIT, modifiedFieldNames);\r
62023 }\r
62024 },\r
62025 fireChangeEvent: function(record) {\r
62026 return !!this.byIdMap[record.id];\r
62027 },\r
62028 updateRootVisible: function(rootVisible) {\r
62029 var rootNode = this.getRoot(),\r
62030 data;\r
62031 if (rootNode) {\r
62032 data = this.getData();\r
62033 if (rootVisible) {\r
62034 data.insert(0, rootNode);\r
62035 } else {\r
62036 data.remove(rootNode);\r
62037 }\r
62038 }\r
62039 },\r
62040 updateTrackRemoved: function(trackRemoved) {\r
62041 this.callParent(arguments);\r
62042 this.removedNodes = this.removed;\r
62043 this.removed = null;\r
62044 },\r
62045 onDestroyRecords: function(records, operation, success) {\r
62046 if (success) {\r
62047 this.removedNodes.length = 0;\r
62048 }\r
62049 },\r
62050 updateProxy: function(proxy) {\r
62051 var reader;\r
62052
62053
62054
62055 if (proxy) {\r
62056 if (proxy.setIdParam) {\r
62057 proxy.setIdParam(this.getNodeParam());\r
62058 }\r
62059
62060 reader = proxy.getReader();\r
62061 if (Ext.isEmpty(reader.getRootProperty())) {\r
62062 reader.setRootProperty(this.getDefaultRootProperty());\r
62063 }\r
62064 }\r
62065 },\r
62066 setProxy: function(proxy) {\r
62067 this.changingProxy = true;\r
62068 this.callParent([\r
62069 proxy\r
62070 ]);\r
62071 this.changingProxy = false;\r
62072 },\r
62073 updateModel: function(model) {\r
62074 var isNode = model.prototype.isNode;\r
62075
62076 Ext.data.NodeInterface.decorate(model);\r
62077
62078
62079 if (!isNode && !this.changingProxy) {\r
62080 this.getProxy().getReader().buildExtractors(true);\r
62081 }\r
62082 },\r
62083 onFilterEndUpdate: function(filters) {\r
62084 var me = this,\r
62085 length = filters.length,\r
62086 root = me.getRoot(),\r
62087 childNodes, childNode, filteredNodes, i;\r
62088 if (!me.getRemoteFilter()) {\r
62089 if (length) {\r
62090 me.doFilter(root);\r
62091 } else {\r
62092 root.cascadeBy({\r
62093 after: function(node) {\r
62094
62095
62096 node.set('visible', true, me._silentOptions);\r
62097 }\r
62098 });\r
62099 }\r
62100 if (length) {\r
62101 filteredNodes = [];\r
62102 childNodes = root.childNodes;\r
62103 for (i = 0 , length = childNodes.length; i < length; i++) {\r
62104 childNode = childNodes[i];\r
62105 if (childNode.get('visible')) {\r
62106 filteredNodes.push(childNode);\r
62107 }\r
62108 }\r
62109 } else {\r
62110 filteredNodes = root.childNodes;\r
62111 }\r
62112 me.onNodeFilter(root, filteredNodes);\r
62113 root.fireEvent('filterchange', root, filteredNodes);\r
62114 me.fireEvent('filterchange', me, filters);\r
62115
62116
62117 me.suppressNextFilter = true;\r
62118 me.callParent([\r
62119 filters\r
62120 ]);\r
62121 me.suppressNextFilter = false;\r
62122 } else {\r
62123 me.callParent([\r
62124 filters\r
62125 ]);\r
62126 }\r
62127 },\r
62128 \r
62129 onNodeFilter: function(root, childNodes) {\r
62130 var me = this,\r
62131 data = me.getData(),\r
62132 toAdd = [];\r
62133
62134 if (me.getRootVisible()) {\r
62135 if (childNodes.length) {\r
62136 toAdd.push(root);\r
62137 } else {\r
62138 root.set('visible', false, me._silentOptions);\r
62139 }\r
62140 }\r
62141 me.handleNodeExpand(root, childNodes, toAdd);\r
62142
62143
62144 me.suspendEvents();\r
62145 data.splice(0, data.getCount(), toAdd);\r
62146 me.resumeEvents();\r
62147 if (!me.suppressNextFilter) {\r
62148 me.fireEvent('datachanged', me);\r
62149 me.fireEvent('refresh', me);\r
62150 }\r
62151 },\r
62152 \r
62153 onBeforeNodeExpand: function(node, callback, scope, args) {\r
62154 var me = this,\r
62155 storeReader, nodeProxy, nodeReader, reader, children, callbackArgs;\r
62156
62157
62158 if (node.isLoaded()) {\r
62159 callbackArgs = [\r
62160 node.childNodes\r
62161 ];\r
62162 if (args) {\r
62163 callbackArgs.push.apply(callbackArgs, args);\r
62164 }\r
62165 Ext.callback(callback, scope || node, callbackArgs);\r
62166 }\r
62167
62168 else if (node.isLoading()) {\r
62169 me.on('load', function() {\r
62170 callbackArgs = [\r
62171 node.childNodes\r
62172 ];\r
62173 if (args) {\r
62174 callbackArgs.push.apply(callbackArgs, args);\r
62175 }\r
62176 Ext.callback(callback, scope || node, callbackArgs);\r
62177 }, me, {\r
62178 single: true,\r
62179 priority: 1001\r
62180 });\r
62181 } else
62182 {\r
62183
62184
62185
62186 storeReader = me.getProxy().getReader();\r
62187 nodeProxy = node.getProxy();\r
62188 nodeReader = nodeProxy ? nodeProxy.getReader() : null;\r
62189
62190 reader = nodeReader && nodeReader.initialConfig.rootProperty ? nodeReader : storeReader;\r
62191
62192
62193
62194 children = reader.getRoot(node.raw || node.data);\r
62195
62196
62197 if (children || (node.phantom && !node.isRoot())) {\r
62198
62199 if (children) {\r
62200 me.fillNode(node, reader.extractData(children, {\r
62201 model: node.childType,\r
62202 recordCreator: me.recordCreator\r
62203 }));\r
62204 }\r
62205 callbackArgs = [\r
62206 node.childNodes\r
62207 ];\r
62208 if (args) {\r
62209 callbackArgs.push.apply(callbackArgs, args);\r
62210 }\r
62211 Ext.callback(callback, scope || node, callbackArgs);\r
62212 } else
62213 {\r
62214 me.read({\r
62215 node: node,\r
62216
62217
62218 onChildNodesAvailable: function() {\r
62219
62220
62221 delete me.lastOptions.onChildNodesAvailable;\r
62222 callbackArgs = [\r
62223 node.childNodes\r
62224 ];\r
62225 if (args) {\r
62226 callbackArgs.push.apply(callbackArgs, args);\r
62227 }\r
62228 Ext.callback(callback, scope || node, callbackArgs);\r
62229 }\r
62230 });\r
62231
62232 me.flushLoad();\r
62233 }\r
62234 }\r
62235 },\r
62236
62237
62238 onNodeExpand: function(parent, records) {\r
62239 var me = this,\r
62240 insertIndex = me.indexOf(parent) + 1,\r
62241 toAdd = [];\r
62242 me.handleNodeExpand(parent, records, toAdd);\r
62243
62244 if (!me.refreshCounter && parent.isRoot() && !parent.get('visible')) {\r
62245 me.loadRecords(toAdd);\r
62246 } else
62247
62248 {\r
62249 me.insert(insertIndex, toAdd);\r
62250 }\r
62251 },\r
62252
62253
62254 handleNodeExpand: function(parent, records, toAdd) {\r
62255 var me = this,\r
62256 ln = records ? records.length : 0,\r
62257 i, record;\r
62258
62259 if (parent !== this.getRoot() && !me.isVisible(parent)) {\r
62260 return;\r
62261 }\r
62262 if (ln) {\r
62263
62264
62265 for (i = 0; i < ln; i++) {\r
62266 record = records[i];\r
62267
62268 if (record.get('visible')) {\r
62269
62270
62271
62272 toAdd.push(record);\r
62273 if (record.isExpanded()) {\r
62274 if (record.isLoaded()) {\r
62275
62276 me.handleNodeExpand(record, record.childNodes, toAdd);\r
62277 } else {\r
62278
62279 record.set('expanded', false);\r
62280 record.expand();\r
62281 }\r
62282 }\r
62283 }\r
62284 }\r
62285 }\r
62286 },\r
62287 \r
62288 onNodeCollapse: function(parent, records, callback, scope) {\r
62289 var me = this,\r
62290 collapseIndex = me.indexOf(parent) + 1,\r
62291 lastNodeIndexPlus;\r
62292
62293 if (me.needsLocalFilter()) {\r
62294 records = Ext.Array.filter(records, me.filterVisible);\r
62295 }\r
62296
62297
62298
62299
62300 if (records.length && me.data.contains(records[0])) {\r
62301
62302 lastNodeIndexPlus = me.indexOfNextVisibleNode(parent);\r
62303
62304 me.removeAt(collapseIndex, lastNodeIndexPlus - collapseIndex);\r
62305 }\r
62306 Ext.callback(callback, scope);\r
62307 },\r
62308 \r
62309 indexOfNextVisibleNode: function(node) {\r
62310 var result;\r
62311 while (node.parentNode) {\r
62312
62313 for (result = node.nextSibling; result && !result.get('visible'); result = result.nextSibling) {}\r
62314
62315
62316 if (result) {\r
62317 return this.indexOf(result);\r
62318 }\r
62319
62320 node = node.parentNode;\r
62321 }\r
62322
62323 return this.getCount();\r
62324 },\r
62325 \r
62326 filterNew: function(item) {\r
62327
62328
62329 return !item.get('root') && this.callParent([\r
62330 item\r
62331 ]);\r
62332 },\r
62333 \r
62334 filterRejects: function(item) {\r
62335
62336
62337 return !item.get('root') && this.callParent([\r
62338 item\r
62339 ]);\r
62340 },\r
62341 getNewRecords: function() {\r
62342 return Ext.Array.filter(Ext.Object.getValues(this.byIdMap), this.filterNew, this);\r
62343 },\r
62344 getUpdatedRecords: function() {\r
62345 return Ext.Array.filter(Ext.Object.getValues(this.byIdMap), this.filterUpdated);\r
62346 },\r
62347
62348
62349
62350
62351
62352
62353
62354
62355
62356
62357
62358
62359
62360
62361
62362
62363
62364
62365
62366 beforeNodeRemove: function(parentNode, childNodes) {\r
62367 if (!Ext.isArray(childNodes)) {\r
62368 childNodes = [\r
62369 childNodes\r
62370 ];\r
62371 }\r
62372 var me = this,\r
62373 len = childNodes.length,\r
62374 i, startNode;\r
62375
62376 for (i = 0; !startNode && i < len; i++) {\r
62377 if (childNodes[i].get('visible')) {\r
62378 startNode = childNodes[i];\r
62379 }\r
62380 }\r
62381
62382 if (startNode) {\r
62383 me.startRemoveIndex = me.indexOf(childNodes[0]);\r
62384 me.lastRemoveIndexPlusOne = me.indexOfNextVisibleNode(childNodes[childNodes.length - 1]);\r
62385 } else {\r
62386 me.startRemoveIndex = -1;\r
62387 me.lastRemoveIndexPlusOne = 0;\r
62388 }\r
62389 },\r
62390
62391
62392
62393
62394
62395 afterDrop: Ext.emptyFn,\r
62396
62397
62398 onNodeRemove: function(parentNode, childNodes, isMove) {\r
62399 var me = this,\r
62400
62401
62402
62403
62404 removed = me.removedNodes,\r
62405 len = childNodes.length,\r
62406 startRemoveIndex = me.startRemoveIndex,\r
62407 lastRemoveIndexPlusOne = me.lastRemoveIndexPlusOne,\r
62408 i;\r
62409
62410
62411 me.suspendAutoSync();\r
62412
62413
62414
62415
62416
62417 if (startRemoveIndex !== -1) {\r
62418 me.removeIsMove = isMove;\r
62419 me.removeAt(startRemoveIndex, lastRemoveIndexPlusOne - startRemoveIndex);\r
62420 me.removeIsMove = false;\r
62421 }\r
62422
62423
62424
62425
62426
62427
62428
62429
62430
62431
62432
62433
62434
62435
62436
62437
62438
62439
62440
62441
62442
62443 for (i = 0; i < len; i++) {\r
62444 childNodes[i].cascadeBy(function(node) {\r
62445
62446 me.unregisterNode(node);\r
62447
62448
62449
62450 if (removed && !isMove) {\r
62451
62452
62453 if (!node.phantom && !node.erasing && !me.loading) {\r
62454
62455
62456 node.removedFrom = me.indexOf(node);\r
62457 removed.push(node);\r
62458
62459
62460 me.needsSync = true;\r
62461 }\r
62462 }\r
62463 });\r
62464 }\r
62465 me.resumeAutoSync();\r
62466 },\r
62467 \r
62468 onNodeAppend: function(parent, node, index) {\r
62469 this.onNodeInsert(parent, node, index);\r
62470 },\r
62471 \r
62472 onNodeInsert: function(parent, node, index) {\r
62473 var me = this,\r
62474 data = node.raw || node.data,\r
62475
62476
62477
62478
62479 removed = me.removedNodes,\r
62480 refNode, sibling, storeReader, nodeProxy, nodeReader, reader, dataRoot;\r
62481 if (parent && me.needsLocalFilter()) {\r
62482 me.doFilter(parent);\r
62483 }\r
62484 me.beginUpdate();\r
62485
62486 if (me.isVisible(node)) {\r
62487 if (index === 0 || !node.previousSibling) {\r
62488 refNode = parent;\r
62489 } else {\r
62490
62491 for (sibling = node.previousSibling; sibling && !sibling.get('visible'); sibling = sibling.previousSibling) {}\r
62492
62493 while (sibling.isExpanded() && sibling.lastChild) {\r
62494 sibling = sibling.lastChild;\r
62495 }\r
62496 refNode = sibling;\r
62497 }\r
62498
62499 me.insert(me.indexOf(refNode) + 1, node);\r
62500 if (!node.isLeaf() && node.isExpanded()) {\r
62501 if (node.isLoaded()) {\r
62502
62503 me.onNodeExpand(node, node.childNodes);\r
62504 } else if (!me.fillCount) {\r
62505
62506
62507
62508
62509 node.set('expanded', false);\r
62510 node.expand();\r
62511 }\r
62512 }\r
62513 }\r
62514
62515 Ext.Array.remove(removed, node);\r
62516
62517 me.needsSync = me.needsSync || node.phantom || node.dirty;\r
62518 if (!node.isLeaf() && !node.isLoaded() && !me.lazyFill) {\r
62519
62520
62521
62522 storeReader = me.getProxy().getReader();\r
62523 nodeProxy = node.getProxy();\r
62524 nodeReader = nodeProxy ? nodeProxy.getReader() : null;\r
62525
62526 reader = nodeReader && nodeReader.initialConfig.rootProperty ? nodeReader : storeReader;\r
62527 dataRoot = reader.getRoot(data);\r
62528 if (dataRoot) {\r
62529 me.fillNode(node, reader.extractData(dataRoot, {\r
62530 model: node.childType,\r
62531 recordCreator: me.recordCreator\r
62532 }));\r
62533 }\r
62534 }\r
62535 me.endUpdate();\r
62536 },\r
62537 \r
62538 registerNode: function(node, includeChildren) {\r
62539 var me = this,\r
62540 children, length, i;\r
62541
62542 me.byIdMap[node.id] = node;\r
62543 if (includeChildren === true) {\r
62544 children = node.childNodes;\r
62545 length = children.length;\r
62546 for (i = 0; i < length; i++) {\r
62547 me.registerNode(children[i], true);\r
62548 }\r
62549 }\r
62550 },\r
62551 \r
62552 unregisterNode: function(node, includeChildren) {\r
62553 var me = this,\r
62554 children, length, i;\r
62555 delete me.byIdMap[node.id];\r
62556 if (includeChildren === true) {\r
62557 children = node.childNodes;\r
62558 length = children.length;\r
62559 for (i = 0; i < length; i++) {\r
62560 me.unregisterNode(children[i], true);\r
62561 }\r
62562 }\r
62563 },\r
62564 onNodeSort: function(node, childNodes) {\r
62565 var me = this;\r
62566
62567
62568 me.suspendAutoSync();\r
62569
62570
62571 if ((me.indexOf(node) !== -1 && node.isExpanded()) || (node === me.getRoot() && !me.getRootVisible())) {\r
62572 Ext.suspendLayouts();\r
62573 me.onNodeCollapse(node, childNodes);\r
62574 me.onNodeExpand(node, childNodes);\r
62575 Ext.resumeLayouts(true);\r
62576 }\r
62577
62578
62579 me.resumeAutoSync(me.autoSync);\r
62580 },\r
62581 applyRoot: function(newRoot) {\r
62582 var me = this,\r
62583 Model = me.getModel(),\r
62584 idProperty = Model.prototype.idProperty,\r
62585 defaultRootId = me.getDefaultRootId();\r
62586
62587
62588
62589 if (newRoot && !newRoot.isNode) {\r
62590
62591 newRoot = Ext.apply({\r
62592 text: me.getDefaultRootText(),\r
62593 root: true,\r
62594 isFirst: true,\r
62595 isLast: true,\r
62596 depth: 0,\r
62597 index: 0,\r
62598 parentId: null,\r
62599 allowDrag: false\r
62600 }, newRoot);\r
62601
62602 if (defaultRootId && newRoot[idProperty] === undefined) {\r
62603 newRoot[idProperty] = defaultRootId;\r
62604 }\r
62605
62606 newRoot = new Model(newRoot);\r
62607 }\r
62608 return newRoot;\r
62609 },\r
62610 updateRoot: function(newRoot, oldRoot) {\r
62611 var me = this,\r
62612 oldOwner,\r
62613 initial = !oldRoot,\r
62614 toRemove;\r
62615
62616 me.byIdMap = {};\r
62617
62618 me.getTrackRemoved();\r
62619
62620
62621 me.suspendEvent('add', 'remove');\r
62622
62623
62624 if (oldRoot && oldRoot.isModel) {\r
62625
62626 if (me.getRootVisible()) {\r
62627 toRemove = [\r
62628 oldRoot\r
62629 ];\r
62630 } else {\r
62631 toRemove = oldRoot.childNodes;\r
62632 }\r
62633 me.beforeNodeRemove(null, toRemove);\r
62634 oldRoot.set('root', false);\r
62635 me.onNodeRemove(null, toRemove);\r
62636 oldRoot.fireEvent('remove', null, oldRoot, false);\r
62637 oldRoot.fireEvent('rootchange', null);\r
62638 oldRoot.clearListeners();\r
62639 oldRoot.store = oldRoot.treeStore = null;\r
62640 }\r
62641 me.getData().clear();\r
62642
62643
62644 if (newRoot) {\r
62645
62646 if (newRoot.fireEventArgs('beforeappend', [\r
62647 null,\r
62648 newRoot\r
62649 ]) === false) {\r
62650 newRoot = null;\r
62651 } else {\r
62652
62653 oldOwner = newRoot.parentNode;\r
62654 if (oldOwner) {\r
62655
62656
62657
62658
62659 if (!oldOwner.removeChild(newRoot, false, false, oldOwner.getTreeStore() === me)) {\r
62660 return;\r
62661 }\r
62662 }\r
62663
62664 else if ((oldOwner = newRoot.getTreeStore()) && oldOwner !== me && newRoot === oldOwner.getRoot()) {\r
62665 oldOwner.setRoot(null);\r
62666 }\r
62667
62668
62669
62670 newRoot.store = newRoot.treeStore = me;\r
62671 newRoot.set('root', true);\r
62672
62673 newRoot.updateInfo(true, {\r
62674 isFirst: true,\r
62675 isLast: true,\r
62676 depth: 0,\r
62677 index: 0,\r
62678 parentId: null\r
62679 });\r
62680
62681
62682 me.registerNode(newRoot, true);\r
62683
62684 newRoot.fireEvent('append', null, newRoot, false);\r
62685 newRoot.fireEvent('rootchange', newRoot);\r
62686
62687 me.onNodeAppend(null, newRoot, 0);\r
62688
62689
62690
62691 newRoot.phantom = true;\r
62692 }\r
62693 }\r
62694 me.fireEvent('rootchange', newRoot, oldRoot);\r
62695
62696 if (newRoot && (me.getAutoLoad() || newRoot.isExpanded())) {\r
62697
62698 if (newRoot.isLoaded()) {\r
62699 me.onNodeExpand(newRoot, newRoot.childNodes);\r
62700 me.fireEvent('datachanged', me);\r
62701 me.fireEvent('refresh', me);\r
62702 } else
62703 {\r
62704 newRoot.data.expanded = false;\r
62705 newRoot.expand(false, function() {\r
62706 me.fireEvent('datachanged', me);\r
62707 me.fireEvent('refresh', me);\r
62708 });\r
62709 }\r
62710 } else if (!initial) {\r
62711 me.fireEvent('datachanged', me);\r
62712 me.fireEvent('refresh', me);\r
62713 }\r
62714
62715 me.resumeEvent('add', 'remove');\r
62716 },\r
62717 \r
62718 \r
62719 getNodeById: function(id) {\r
62720 return this.byIdMap[id] || null;\r
62721 },\r
62722 \r
62723 findNode: function(property, value, startsWith, endsWith, ignoreCase) {\r
62724 if (Ext.isEmpty(value, false)) {\r
62725 return null;\r
62726 }\r
62727
62728 if (value === this.model.idProperty && arguments.length < 3) {\r
62729 return this.byIdMap[value];\r
62730 }\r
62731 var regex = Ext.String.createRegex(value, startsWith, endsWith, ignoreCase),\r
62732 result = null;\r
62733 Ext.Object.eachValue(this.byIdMap, function(node) {\r
62734 if (node && regex.test(node.get(property))) {\r
62735 result = node;\r
62736 return false;\r
62737 }\r
62738 });\r
62739 return result;\r
62740 },\r
62741 \r
62742 load: function(options) {\r
62743 var node = options && options.node;\r
62744
62745
62746 if (!node & !(node = this.getRoot())) {\r
62747 node = this.setRoot({\r
62748 expanded: true\r
62749 });\r
62750 return;\r
62751 }\r
62752
62753 if (node.isLoading()) {\r
62754 return;\r
62755 }\r
62756 return this.callParent([\r
62757 options\r
62758 ]);\r
62759 },\r
62760 \r
62761 flushLoad: function() {\r
62762 var me = this,\r
62763 options = me.pendingLoadOptions,\r
62764 node, callback, scope,\r
62765 clearOnLoad = me.getClearOnLoad(),\r
62766 isReload, operation, doClear;\r
62767
62768 me.clearLoadTask();\r
62769 if (!options) {\r
62770 return;\r
62771 }\r
62772 node = options.node || me.getRoot();\r
62773
62774
62775
62776
62777
62778 isReload = node && node.isRoot() && node.isLoaded() && clearOnLoad;\r
62779 callback = options.callback;\r
62780 scope = options.scope;\r
62781 options.params = options.params || {};\r
62782
62783
62784 if (node.data.expanded && !isReload) {\r
62785 node.data.loaded = false;\r
62786
62787
62788 if (clearOnLoad) {\r
62789 node.data.expanded = false;\r
62790 }\r
62791 options.callback = function(loadedNodes, operation, success) {\r
62792
62793
62794
62795 if (!clearOnLoad) {\r
62796 node.collapse();\r
62797 }\r
62798 node.expand();\r
62799
62800 Ext.callback(callback, scope, [\r
62801 loadedNodes,\r
62802 operation,\r
62803 success\r
62804 ]);\r
62805 };\r
62806 }\r
62807
62808
62809 options.id = node.getId();\r
62810 options = Ext.apply({\r
62811 filters: me.getFilters().items,\r
62812 sorters: me.getSorters().items,\r
62813 node: options.node || node,\r
62814 internalScope: me,\r
62815 internalCallback: me.onProxyLoad\r
62816 }, options);\r
62817 me.lastOptions = Ext.apply({}, options);\r
62818
62819 options.isReload = isReload;\r
62820 operation = me.createOperation('read', options);\r
62821 if (me.fireEvent('beforeload', me, operation) !== false) {\r
62822
62823
62824 me.loading = true;\r
62825
62826 if (isReload) {\r
62827 if (me.getClearRemovedOnLoad()) {\r
62828 me.removedNodes.length = 0;\r
62829 }\r
62830 me.unregisterNode(node, true);\r
62831 node.childNodes.length = 0;\r
62832 doClear = true;\r
62833 }\r
62834
62835 else if (clearOnLoad) {\r
62836 if (me.getTrackRemoved() && me.getClearRemovedOnLoad()) {\r
62837
62838 me.clearRemoved(node);\r
62839 }\r
62840 node.removeAll(false);\r
62841 }\r
62842 if (me.loading && node) {\r
62843 node.set('loading', true);\r
62844 }\r
62845 if (doClear) {\r
62846 me.clearData(true);\r
62847
62848 if (me.getRootVisible()) {\r
62849 me.suspendEvents();\r
62850 me.add(node);\r
62851 me.resumeEvents();\r
62852 }\r
62853 }\r
62854 operation.execute();\r
62855 }\r
62856 return me;\r
62857 },\r
62858 onProxyLoad: function(operation) {\r
62859 var me = this,\r
62860 options = operation.initialConfig,\r
62861 successful = operation.wasSuccessful(),\r
62862 records = operation.getRecords(),\r
62863 node = options.node,\r
62864 isReload = options.isReload,\r
62865 scope = operation.getScope() || me,\r
62866 args = [\r
62867 records,\r
62868 operation,\r
62869 successful\r
62870 ];\r
62871 if (me.destroyed) {\r
62872 return;\r
62873 }\r
62874 me.loading = false;\r
62875 node.set('loading', false);\r
62876 if (successful) {\r
62877 ++me.loadCount;\r
62878 if (!me.getClearOnLoad()) {\r
62879 records = me.cleanRecords(node, records);\r
62880 }\r
62881
62882 if (me.getParentIdProperty()) {\r
62883 records = me.treeify(node, records);\r
62884 }\r
62885 if (isReload) {\r
62886 me.suspendEvent('add', 'update');\r
62887 }\r
62888 records = me.fillNode(node, records);\r
62889 }\r
62890
62891
62892 \r
62893 if (isReload) {\r
62894 me.resumeEvent('add', 'update');\r
62895 me.callObservers('BeforePopulate');\r
62896 me.fireEvent('datachanged', me);\r
62897 me.fireEvent('refresh', me);\r
62898 me.callObservers('AfterPopulate');\r
62899 } else {\r
62900 Ext.callback(options.onChildNodesAvailable, scope, args);\r
62901 }\r
62902 me.fireEvent('load', me, records, successful, operation, node);\r
62903 },\r
62904 \r
62905 clearRemoved: function(node) {\r
62906 var me = this,\r
62907 removed = me.removedNodes,\r
62908 id = node.getId(),\r
62909 removedLength = removed.length,\r
62910 i = removedLength,\r
62911 recordsToClear = {},\r
62912 newRemoved = [],\r
62913 removedHash = {},\r
62914 removedNode, targetNode, targetId;\r
62915 if (node === me.getRoot()) {\r
62916
62917 me.removedNodes.length = 0;\r
62918 return;\r
62919 }\r
62920
62921 for (; i--; ) {\r
62922 removedNode = removed[i];\r
62923 removedHash[removedNode.getId()] = removedNode;\r
62924 }\r
62925 for (i = removedLength; i--; ) {\r
62926 removedNode = removed[i];\r
62927 targetNode = removedNode;\r
62928 while (targetNode && targetNode.getId() !== id) {\r
62929
62930
62931 targetId = targetNode.get('parentId') || targetNode.get('lastParentId');\r
62932 targetNode = targetNode.parentNode || me.getNodeById(targetId) || removedHash[targetId];\r
62933 }\r
62934 if (targetNode) {\r
62935
62936 recordsToClear[removedNode.getId()] = removedNode;\r
62937 }\r
62938 }\r
62939
62940 for (i = 0; i < removedLength; i++) {\r
62941 removedNode = removed[i];\r
62942 if (!recordsToClear[removedNode.getId()]) {\r
62943 newRemoved.push(removedNode);\r
62944 }\r
62945 }\r
62946 me.removedNodes = newRemoved;\r
62947 },\r
62948 \r
62949 fillNode: function(node, newNodes) {\r
62950 var me = this,\r
62951 newNodeCount = newNodes ? newNodes.length : 0;\r
62952
62953 ++me.bulkUpdate;\r
62954 if (newNodeCount) {\r
62955 me.setupNodes(newNodes);\r
62956 }\r
62957 if (me.bulkUpdate === 1) {\r
62958 node.set('loaded', true);\r
62959 } else {\r
62960 node.data.loaded = true;\r
62961 }\r
62962 if (newNodes.length) {\r
62963 node.appendChild(newNodes, undefined, true);\r
62964 }\r
62965 --me.bulkUpdate;\r
62966
62967 return newNodes;\r
62968 },\r
62969 setupNodes: function(newNodes) {\r
62970 var me = this,\r
62971 sorters = me.getSorters(),\r
62972 needsIndexSort = false,\r
62973 newNodeCount = newNodes.length,\r
62974 performLocalSort = me.sortOnLoad && newNodeCount > 1 && !me.getRemoteSort() && me.getFolderSort() || sorters.length,\r
62975 node1, node2, i, filterFn;\r
62976
62977 if (me.needsLocalFilter()) {\r
62978 filterFn = me.getFilters().getFilterFn();\r
62979 newNodes[0].set('visible', filterFn(newNodes[0]));\r
62980 }\r
62981
62982 for (i = 1; i < newNodeCount; i++) {\r
62983 node1 = newNodes[i];\r
62984 node2 = newNodes[i - 1];\r
62985
62986 if (filterFn) {\r
62987 node1.set('visible', filterFn(node1));\r
62988 }\r
62989 needsIndexSort = node1.data.index !== node2.data.index;\r
62990 }\r
62991
62992 if (performLocalSort) {\r
62993
62994 me.needsIndexSort = true;\r
62995 Ext.Array.sort(newNodes, me.getSortFn());\r
62996 me.needsIndexSort = false;\r
62997 } else if (needsIndexSort) {\r
62998 Ext.Array.sort(newNodes, me.sortByIndex);\r
62999 }\r
63000 },\r
63001
63002 beginFill: function() {\r
63003 var me = this;\r
63004 if (!me.fillCount++) {\r
63005
63006 me.beginUpdate();\r
63007 me.suspendEvent('add', 'update');\r
63008 me.suspendAutoSync();\r
63009 me.fillArray = [];\r
63010 }\r
63011 },\r
63012
63013 endFill: function(parent, nodes) {\r
63014 var me = this,\r
63015 fillArray = me.fillArray,\r
63016 i, len, index;\r
63017
63018 fillArray.push(nodes);\r
63019 if (!--me.fillCount) {\r
63020 me.resumeAutoSync();\r
63021 me.resumeEvent('add', 'update');\r
63022
63023
63024
63025 for (i = 0 , len = fillArray.length; i < len; i++) {\r
63026 index = me.indexOf(fillArray[i][0]);\r
63027
63028 if (index !== -1) {\r
63029 me.fireEvent('add', me, fillArray[i], index);\r
63030 }\r
63031 }\r
63032 me.fillArray = null;\r
63033 me.endUpdate();\r
63034 }\r
63035 },\r
63036 \r
63037 sortByIndex: function(node1, node2) {\r
63038 return node1.data.index - node2.data.index;\r
63039 },\r
63040 onIdChanged: function(node, oldId, newId) {\r
63041 var childNodes = node.childNodes,\r
63042 len = childNodes && childNodes.length,\r
63043 i;\r
63044 this.callParent(arguments);\r
63045 delete this.byIdMap[oldId];\r
63046 this.byIdMap[newId] = node;\r
63047
63048 for (i = 0; i < len; i++) {\r
63049 childNodes[i].set('parentId', newId);\r
63050 }\r
63051 },\r
63052 \r
63053 treeify: function(parentNode, records) {\r
63054 var me = this,\r
63055 loadParentNodeId = parentNode.getId(),\r
63056 parentIdProperty = me.getParentIdProperty(),\r
63057 len = records.length,\r
63058 result = [],\r
63059 nodeMap = {},\r
63060 i, node, parentId, parent, id, children;\r
63061
63062 for (i = 0; i < len; i++) {\r
63063 node = records[i];\r
63064 nodeMap[node.id] = node;\r
63065 }\r
63066
63067 for (i = 0; i < len; i++) {\r
63068 node = records[i];\r
63069 parentId = node.data[parentIdProperty];\r
63070 if (!(parentId || parentId === 0) || parentId === loadParentNodeId) {\r
63071 result.push(node);\r
63072 } else {\r
63073
63074 if (!nodeMap[parentId]) {\r
63075 Ext.raise('Ext.data.TreeStore, Invalid parentId "' + parentId + '"');\r
63076 }\r
63077
63078 parent = nodeMap[parentId];\r
63079 parent.$children = parent.$children || [];\r
63080 parent.$children.push(node);\r
63081 }\r
63082 }\r
63083 for (id in nodeMap) {\r
63084 node = nodeMap[id];\r
63085 children = node.$children;\r
63086 if (children) {\r
63087 delete node.$children;\r
63088 me.setupNodes(children);\r
63089 node.appendChild(children);\r
63090 }\r
63091 me.registerNode(node);\r
63092 }\r
63093 me.setupNodes(result);\r
63094 return result;\r
63095 },\r
63096 cleanRecords: function(node, records) {\r
63097 var nodeHash = {},\r
63098 childNodes = node.childNodes,\r
63099 i = 0,\r
63100 len = childNodes.length,\r
63101 out = [],\r
63102 rec;\r
63103
63104 for (; i < len; ++i) {\r
63105 nodeHash[childNodes[i].getId()] = true;\r
63106 }\r
63107 for (i = 0 , len = records.length; i < len; ++i) {\r
63108 rec = records[i];\r
63109 if (!nodeHash[rec.getId()]) {\r
63110 out.push(rec);\r
63111 }\r
63112 }\r
63113 return out;\r
63114 },\r
63115 removeAll: function() {\r
63116 this.suspendEvents();\r
63117 this.setRoot(null);\r
63118 this.resumeEvents();\r
63119 this.callParent();\r
63120 },\r
63121 doSort: function(sorterFn) {\r
63122 var me = this;\r
63123 if (me.getRemoteSort()) {\r
63124
63125 me.load();\r
63126 } else {\r
63127 me.tree.sort(sorterFn, true);\r
63128 me.fireEvent('datachanged', me);\r
63129 me.fireEvent('refresh', me);\r
63130 }\r
63131 me.fireEvent('sort', me, me.sorters.getRange());\r
63132 },\r
63133 filterVisible: function(node) {\r
63134 return node.get('visible');\r
63135 },\r
63136 \r
63137 isVisible: function(node) {\r
63138 var parentNode = node.parentNode,\r
63139 visible = node.data.visible,\r
63140 root = this.getRoot();\r
63141 while (visible && parentNode) {\r
63142 visible = parentNode.data.expanded && parentNode.data.visible;\r
63143 parentNode = parentNode.parentNode;\r
63144 }\r
63145
63146
63147 return visible && !(node === root && !this.getRootVisible());\r
63148 },\r
63149 commitChanges: function() {\r
63150 var removed = this.removedNodes;\r
63151 if (removed) {\r
63152 removed.length = 0;\r
63153 }\r
63154 this.callParent();\r
63155 },\r
63156 \r
63157 getRootNode: function() {\r
63158 return this.getRoot();\r
63159 },\r
63160 \r
63161 setRootNode: function(root) {\r
63162 this.setRoot(root);\r
63163 return this.getRoot();\r
63164 },\r
63165 privates: {\r
63166 \r
63167 getRawRemovedRecords: function() {\r
63168 return this.removedNodes;\r
63169 },\r
63170 \r
63171 recordCreator: function(data, Model) {\r
63172 return new Model(data);\r
63173 },\r
63174 doFilter: function(node) {\r
63175 var root = this.getRoot(),\r
63176 filterFn = this.getFilters().getFilterFn();\r
63177 this.filterNodes(root, node, filterFn);\r
63178 },\r
63179 filterNodes: function(root, node, filterFn) {\r
63180 var match = false,\r
63181 childNodes = node.childNodes,\r
63182 len = childNodes && childNodes.length,\r
63183 i;\r
63184 if (len) {\r
63185 for (i = 0; i < len; ++i) {\r
63186 this.filterNodes(root, childNodes[i], filterFn);\r
63187 }\r
63188 }\r
63189 match = node === root || filterFn(node);\r
63190 node.set('visible', match, this._silentOptions);\r
63191 return match;\r
63192 },\r
63193 needsLocalFilter: function() {\r
63194 return !this.getRemoteFilter() && this.getFilters().length;\r
63195 },\r
63196 onRemoteFilterSet: function(filters, remoteFilter) {\r
63197
63198
63199
63200
63201 var data = this.getData();\r
63202 data.setFilters(null);\r
63203 if (filters) {\r
63204 filters.on('endupdate', this.onFilterEndUpdate, this);\r
63205 }\r
63206 },\r
63207 onRemoteSortSet: function(sorters, remoteSort) {\r
63208
63209
63210
63211
63212 var data = this.getData();\r
63213 data.setSorters(null);\r
63214 if (sorters) {\r
63215 sorters.on('endupdate', this.onSorterEndUpdate, this);\r
63216 }\r
63217 }\r
63218 },\r
63219 deprecated: {\r
63220 5: {\r
63221 properties: {\r
63222 tree: null\r
63223 }\r
63224 }\r
63225 }\r
63226});\r
63227\r
63228\r
63229Ext.define('Ext.data.Types', {\r
63230 singleton: true\r
63231}, function(Types) {\r
63232 var SortTypes = Ext.data.SortTypes;\r
63233 Ext.apply(Types, {\r
63234 \r
63235 stripRe: /[\$,%]/g,\r
63236 \r
63237 AUTO: {\r
63238 sortType: SortTypes.none,\r
63239 type: 'auto'\r
63240 },\r
63241 \r
63242 STRING: {\r
63243 convert: function(v) {\r
63244 var defaultValue = this.getAllowNull() ? null : '';\r
63245 return (v === undefined || v === null) ? defaultValue : String(v);\r
63246 },\r
63247 sortType: SortTypes.asUCString,\r
63248 type: 'string'\r
63249 },\r
63250 \r
63251 INT: {\r
63252 convert: function(v) {\r
63253
63254
63255
63256 if (typeof v === 'number') {\r
63257 return parseInt(v, 10);\r
63258 }\r
63259 return v !== undefined && v !== null && v !== '' ? parseInt(String(v).replace(Types.stripRe, ''), 10) : (this.getAllowNull() ? null : 0);\r
63260 },\r
63261 sortType: SortTypes.none,\r
63262 type: 'int'\r
63263 },\r
63264 \r
63265 FLOAT: {\r
63266 convert: function(v) {\r
63267 if (typeof v === 'number') {\r
63268 return v;\r
63269 }\r
63270 return v !== undefined && v !== null && v !== '' ? parseFloat(String(v).replace(Types.stripRe, ''), 10) : (this.getAllowNull() ? null : 0);\r
63271 },\r
63272 sortType: SortTypes.none,\r
63273 type: 'float'\r
63274 },\r
63275 \r
63276 BOOL: {\r
63277 convert: function(v) {\r
63278 if (typeof v === 'boolean') {\r
63279 return v;\r
63280 }\r
63281 if (this.getAllowNull() && (v === undefined || v === null || v === '')) {\r
63282 return null;\r
63283 }\r
63284 return v === 'true' || v == 1;\r
63285 },\r
63286 sortType: SortTypes.none,\r
63287 type: 'bool'\r
63288 },\r
63289 \r
63290 DATE: {\r
63291 convert: function(v) {\r
63292 var df = this.getDateReadFormat() || this.getDateFormat(),\r
63293 parsed;\r
63294 if (!v) {\r
63295 return null;\r
63296 }\r
63297
63298 if (v instanceof Date) {\r
63299 return v;\r
63300 }\r
63301 if (df) {\r
63302 return Ext.Date.parse(v, df);\r
63303 }\r
63304 parsed = Date.parse(v);\r
63305 return parsed ? new Date(parsed) : null;\r
63306 },\r
63307 sortType: SortTypes.asDate,\r
63308 type: 'date'\r
63309 }\r
63310 });\r
63311 \r
63312 Types.BOOLEAN = Types.BOOL;\r
63313 \r
63314 Types.INTEGER = Types.INT;\r
63315 \r
63316 Types.NUMBER = Types.FLOAT;\r
63317});\r
63318\r
63319\r
63320Ext.define('Ext.data.Validation', {\r
63321 extend: Ext.data.Model,\r
63322 isValidation: true,\r
63323 \r
63324 syncGeneration: 0,\r
63325
63326 \r
63327 attach: function(record) {\r
63328 \r
63329 this.record = record;\r
63330
63331
63332 delete this.data.id;\r
63333 },\r
63334 getValidation: function() {\r
63335 return null;\r
63336 },\r
63337 \r
63338 isValid: function() {\r
63339 var me = this;\r
63340 if (me.syncGeneration !== me.record.generation) {\r
63341 me.refresh();\r
63342 }\r
63343 return !me.dirty;\r
63344 },\r
63345 \r
63346 refresh: function(force) {\r
63347 var me = this,\r
63348 data = me.data,\r
63349 record = me.record,\r
63350 fields = record.fields,\r
63351 generation = record.generation,\r
63352 recordData = record.data,\r
63353 sep = record.validationSeparator,\r
63354 values = null,\r
63355 defaultMessage, currentValue, error, field, item, i, j, jLen, len, msg, val, name;\r
63356 if (force || me.syncGeneration !== generation) {\r
63357 me.syncGeneration = generation;\r
63358 for (i = 0 , len = fields.length; i < len; ++i) {\r
63359 field = fields[i];\r
63360 name = field.name;\r
63361 val = recordData[name];\r
63362 defaultMessage = field.defaultInvalidMessage;\r
63363 error = 0;\r
63364 if (!(name in data)) {\r
63365
63366
63367
63368 data[name] = currentValue = true;\r
63369 } else
63370 {\r
63371 currentValue = data[name];\r
63372 }\r
63373 if (field.validate !== Ext.emptyFn) {\r
63374 msg = field.validate(val, sep, null, record);\r
63375 if (msg !== true) {\r
63376 error = msg || defaultMessage;\r
63377 }\r
63378 }\r
63379 if (!error) {\r
63380 error = true;\r
63381 }\r
63382
63383 if (error !== currentValue) {\r
63384 (values || (values = {}))[name] = error;\r
63385 }\r
63386 }\r
63387 if (values) {\r
63388
63389 me.set(values);\r
63390 }\r
63391 }\r
63392 }\r
63393});\r
63394\r
63395\r
63396Ext.define('Ext.dom.Helper', function() {\r
63397 var afterbegin = 'afterbegin',\r
63398 afterend = 'afterend',\r
63399 beforebegin = 'beforebegin',\r
63400 beforeend = 'beforeend',\r
63401 bbValues = [\r
63402 'BeforeBegin',\r
63403 'previousSibling'\r
63404 ],\r
63405 aeValues = [\r
63406 'AfterEnd',\r
63407 'nextSibling'\r
63408 ],\r
63409 bb_ae_PositionHash = {\r
63410 beforebegin: bbValues,\r
63411 afterend: aeValues\r
63412 },\r
63413 fullPositionHash = {\r
63414 beforebegin: bbValues,\r
63415 afterend: aeValues,\r
63416 afterbegin: [\r
63417 'AfterBegin',\r
63418 'firstChild'\r
63419 ],\r
63420 beforeend: [\r
63421 'BeforeEnd',\r
63422 'lastChild'\r
63423 ]\r
63424 };\r
63425 return {\r
63426 singleton: true,\r
63427 alternateClassName: [\r
63428 'Ext.DomHelper',\r
63429 'Ext.core.DomHelper'\r
63430 ],\r
63431 emptyTags: /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i,\r
63432 confRe: /^(?:tag|children|cn|html|tpl|tplData)$/i,\r
63433 endRe: /end/i,\r
63434
63435 attributeTransform: {\r
63436 cls: 'class',\r
63437 htmlFor: 'for'\r
63438 },\r
63439 closeTags: {},\r
63440 detachedDiv: document.createElement('div'),\r
63441 decamelizeName: function() {\r
63442 var camelCaseRe = /([a-z])([A-Z])/g,\r
63443 cache = {};\r
63444 function decamel(match, p1, p2) {\r
63445 return p1 + '-' + p2.toLowerCase();\r
63446 }\r
63447 return function(s) {\r
63448 return cache[s] || (cache[s] = s.replace(camelCaseRe, decamel));\r
63449 };\r
63450 }(),\r
63451 generateMarkup: function(spec, buffer) {\r
63452 var me = this,\r
63453 specType = typeof spec,\r
63454 attr, val, tag, i, closeTags;\r
63455 if (specType === "string" || specType === "number") {\r
63456 buffer.push(spec);\r
63457 } else if (Ext.isArray(spec)) {\r
63458 for (i = 0; i < spec.length; i++) {\r
63459 if (spec[i]) {\r
63460 me.generateMarkup(spec[i], buffer);\r
63461 }\r
63462 }\r
63463 } else {\r
63464 tag = spec.tag || 'div';\r
63465 buffer.push('<', tag);\r
63466 for (attr in spec) {\r
63467 if (spec.hasOwnProperty(attr)) {\r
63468 val = spec[attr];\r
63469 if (val !== undefined && !me.confRe.test(attr)) {\r
63470 if (typeof val === "object") {\r
63471 buffer.push(' ', attr, '="');\r
63472 me.generateStyles(val, buffer, true).push('"');\r
63473 } else {\r
63474 buffer.push(' ', me.attributeTransform[attr] || attr, '="', val, '"');\r
63475 }\r
63476 }\r
63477 }\r
63478 }\r
63479
63480 if (me.emptyTags.test(tag)) {\r
63481 buffer.push('/>');\r
63482 } else {\r
63483 buffer.push('>');\r
63484
63485 if ((val = spec.tpl)) {\r
63486 val.applyOut(spec.tplData, buffer);\r
63487 }\r
63488 if ((val = spec.html)) {\r
63489 buffer.push(val);\r
63490 }\r
63491 if ((val = spec.cn || spec.children)) {\r
63492 me.generateMarkup(val, buffer);\r
63493 }\r
63494
63495 closeTags = me.closeTags;\r
63496 buffer.push(closeTags[tag] || (closeTags[tag] = '</' + tag + '>'));\r
63497 }\r
63498 }\r
63499 return buffer;\r
63500 },\r
63501 \r
63502 generateStyles: function(styles, buffer, encode) {\r
63503 var a = buffer || [],\r
63504 name, val;\r
63505 for (name in styles) {\r
63506 if (styles.hasOwnProperty(name)) {\r
63507 val = styles[name];\r
63508
63509
63510
63511 name = this.decamelizeName(name);\r
63512 if (encode && Ext.String.hasHtmlCharacters(val)) {\r
63513 val = Ext.String.htmlEncode(val);\r
63514 }\r
63515 a.push(name, ':', val, ';');\r
63516 }\r
63517 }\r
63518 return buffer || a.join('');\r
63519 },\r
63520 \r
63521 markup: function(spec) {\r
63522 if (typeof spec === "string") {\r
63523 return spec;\r
63524 }\r
63525 var buf = this.generateMarkup(spec, []);\r
63526 return buf.join('');\r
63527 },\r
63528 \r
63529 applyStyles: function(el, styles) {\r
63530 Ext.fly(el).applyStyles(styles);\r
63531 },\r
63532 \r
63533 createContextualFragment: function(html) {\r
63534 var div = this.detachedDiv,\r
63535 fragment = document.createDocumentFragment(),\r
63536 length, childNodes;\r
63537 div.innerHTML = html;\r
63538 childNodes = div.childNodes;\r
63539 length = childNodes.length;\r
63540
63541 while (length--) {\r
63542 fragment.appendChild(childNodes[0]);\r
63543 }\r
63544 return fragment;\r
63545 },\r
63546 \r
63547 createDom: function(o, parentNode) {\r
63548 var me = this,\r
63549 markup = me.markup(o),\r
63550 div = me.detachedDiv,\r
63551 child;\r
63552 div.innerHTML = markup;\r
63553 child = div.firstChild;\r
63554
63555
63556
63557
63558
63559
63560
63561
63562
63563 return Ext.supports.ChildContentClearedWhenSettingInnerHTML ? child.cloneNode(true) : child;\r
63564 },\r
63565 \r
63566 insertHtml: function(where, el, html) {\r
63567 var me = this,\r
63568 hashVal, range, rangeEl, setStart, frag;\r
63569 where = where.toLowerCase();\r
63570
63571 if (el.insertAdjacentHTML) {\r
63572 if (me.ieInsertHtml) {\r
63573
63574 frag = me.ieInsertHtml(where, el, html);\r
63575 if (frag) {\r
63576 return frag;\r
63577 }\r
63578 }\r
63579 hashVal = fullPositionHash[where];\r
63580 if (hashVal) {\r
63581 el.insertAdjacentHTML(hashVal[0], html);\r
63582 return el[hashVal[1]];\r
63583 }\r
63584 } else
63585 {\r
63586
63587 if (el.nodeType === 3) {\r
63588 where = where === afterbegin ? beforebegin : where;\r
63589 where = where === beforeend ? afterend : where;\r
63590 }\r
63591 range = Ext.supports.CreateContextualFragment ? el.ownerDocument.createRange() : undefined;\r
63592 setStart = 'setStart' + (this.endRe.test(where) ? 'After' : 'Before');\r
63593 if (bb_ae_PositionHash[where]) {\r
63594 if (range) {\r
63595 range[setStart](el);\r
63596 frag = range.createContextualFragment(html);\r
63597 } else {\r
63598 frag = this.createContextualFragment(html);\r
63599 }\r
63600 el.parentNode.insertBefore(frag, where === beforebegin ? el : el.nextSibling);\r
63601 return el[(where === beforebegin ? 'previous' : 'next') + 'Sibling'];\r
63602 } else {\r
63603 rangeEl = (where === afterbegin ? 'first' : 'last') + 'Child';\r
63604 if (el.firstChild) {\r
63605 if (range) {\r
63606
63607
63608
63609 try {\r
63610 range[setStart](el[rangeEl]);\r
63611 frag = range.createContextualFragment(html);\r
63612 } catch (e) {\r
63613 frag = this.createContextualFragment(html);\r
63614 }\r
63615 } else {\r
63616 frag = this.createContextualFragment(html);\r
63617 }\r
63618 if (where === afterbegin) {\r
63619 el.insertBefore(frag, el.firstChild);\r
63620 } else {\r
63621 el.appendChild(frag);\r
63622 }\r
63623 } else {\r
63624 el.innerHTML = html;\r
63625 }\r
63626 return el[rangeEl];\r
63627 }\r
63628 }\r
63629
63630 Ext.raise({\r
63631 sourceClass: 'Ext.DomHelper',\r
63632 sourceMethod: 'insertHtml',\r
63633 htmlToInsert: html,\r
63634 targetElement: el,\r
63635 msg: 'Illegal insertion point reached: "' + where + '"'\r
63636 });\r
63637 },\r
63638
63639 \r
63640 insertBefore: function(el, o, returnElement) {\r
63641 return this.doInsert(el, o, returnElement, beforebegin);\r
63642 },\r
63643 \r
63644 insertAfter: function(el, o, returnElement) {\r
63645 return this.doInsert(el, o, returnElement, afterend);\r
63646 },\r
63647 \r
63648 insertFirst: function(el, o, returnElement) {\r
63649 return this.doInsert(el, o, returnElement, afterbegin);\r
63650 },\r
63651 \r
63652 append: function(el, o, returnElement) {\r
63653 return this.doInsert(el, o, returnElement, beforeend);\r
63654 },\r
63655 \r
63656 overwrite: function(el, html, returnElement) {\r
63657 var me = this,\r
63658 newNode;\r
63659 el = Ext.getDom(el);\r
63660 html = me.markup(html);\r
63661 if (me.ieOverwrite) {\r
63662
63663 newNode = me.ieOverwrite(el, html);\r
63664 }\r
63665 if (!newNode) {\r
63666 el.innerHTML = html;\r
63667 newNode = el.firstChild;\r
63668 }\r
63669 return returnElement ? Ext.get(newNode) : newNode;\r
63670 },\r
63671 doInsert: function(el, o, returnElement, where) {\r
63672 var me = this,\r
63673 newNode;\r
63674 el = el.dom || Ext.getDom(el);\r
63675 if ('innerHTML' in el) {\r
63676
63677
63678
63679
63680 newNode = me.insertHtml(where, el, me.markup(o));\r
63681 } else {\r
63682
63683 newNode = me.createDom(o, null);\r
63684
63685 if (el.nodeType === 3) {\r
63686 where = where === afterbegin ? beforebegin : where;\r
63687 where = where === beforeend ? afterend : where;\r
63688 }\r
63689 if (bb_ae_PositionHash[where]) {\r
63690 el.parentNode.insertBefore(newNode, where === beforebegin ? el : el.nextSibling);\r
63691 } else if (el.firstChild && where === afterbegin) {\r
63692 el.insertBefore(newNode, el.firstChild);\r
63693 } else {\r
63694 el.appendChild(newNode);\r
63695 }\r
63696 }\r
63697 return returnElement ? Ext.get(newNode) : newNode;\r
63698 },\r
63699 \r
63700 createTemplate: function(o) {\r
63701 var html = this.markup(o);\r
63702 return new Ext.Template(html);\r
63703 },\r
63704 \r
63705 createHtml: function(spec) {\r
63706 return this.markup(spec);\r
63707 }\r
63708 };\r
63709});\r
63710\r
63711\r
63712Ext.define('Ext.dom.Query', function() {\r
63713 var DQ,\r
63714 doc = document,\r
63715 cache, simpleCache, valueCache,\r
63716 useClassList = !!doc.documentElement.classList,\r
63717 useElementPointer = !!doc.documentElement.firstElementChild,\r
63718 useChildrenCollection = (function() {\r
63719 var d = doc.createElement('div');\r
63720 d.innerHTML = '<!-- -->text<!-- -->';\r
63721 return d.children && (d.children.length === 0);\r
63722 })(),\r
63723 nonSpace = /\S/,\r
63724 trimRe = /^\s+|\s+$/g,\r
63725 tplRe = /\{(\d+)\}/g,\r
63726 modeRe = /^(\s?[\/>+~]\s?|\s|$)/,\r
63727 tagTokenRe = /^(#)?([\w\-\*\|\\]+)/,\r
63728 nthRe = /(\d*)n\+?(\d*)/,\r
63729 nthRe2 = /\D/,\r
63730 startIdRe = /^\s*#/,\r
63731
63732
63733
63734 isIE = window.ActiveXObject ? true : false,\r
63735 key = 30803,\r
63736 longHex = /\\([0-9a-fA-F]{6})/g,\r
63737 shortHex = /\\([0-9a-fA-F]{1,6})\s{0,1}/g,\r
63738 nonHex = /\\([^0-9a-fA-F]{1})/g,\r
63739 escapes = /\\/g,\r
63740 num, hasEscapes,\r
63741
63742
63743 supportsColonNsSeparator = (function() {\r
63744 var xmlDoc,\r
63745 xmlString = '<r><a:b xmlns:a="n"></a:b></r>';\r
63746 if (window.DOMParser) {\r
63747 xmlDoc = (new DOMParser()).parseFromString(xmlString, "application/xml");\r
63748 } else {\r
63749 xmlDoc = new ActiveXObject("Microsoft.XMLDOM");\r
63750 xmlDoc.loadXML(xmlString);\r
63751 }\r
63752 return !!xmlDoc.getElementsByTagName('a:b').length;\r
63753 })(),\r
63754
63755
63756 longHexToChar = function($0, $1) {\r
63757 return String.fromCharCode(parseInt($1, 16));\r
63758 },\r
63759
63760 shortToLongHex = function($0, $1) {\r
63761 while ($1.length < 6) {\r
63762 $1 = '0' + $1;\r
63763 }\r
63764 return '\\' + $1;\r
63765 },\r
63766
63767 charToLongHex = function($0, $1) {\r
63768 num = $1.charCodeAt(0).toString(16);\r
63769 if (num.length === 1) {\r
63770 num = '0' + num;\r
63771 }\r
63772 return '\\0000' + num;\r
63773 },\r
63774
63775
63776
63777 unescapeCssSelector = function(selector) {\r
63778 return (hasEscapes) ? selector.replace(longHex, longHexToChar) : selector;\r
63779 },\r
63780
63781 setupEscapes = function(path) {\r
63782 hasEscapes = (path.indexOf('\\') > -1);\r
63783 if (hasEscapes) {\r
63784 path = path.replace(shortHex, shortToLongHex).replace(nonHex, charToLongHex).replace(escapes, '\\\\');\r
63785 }\r
63786
63787 return path;\r
63788 };\r
63789
63790
63791 eval("var batch = 30803, child, next, prev, byClassName;");\r
63792
63793
63794 child = useChildrenCollection ? function child(parent, index) {\r
63795 return parent.children[index];\r
63796 } : function child(parent, index) {\r
63797 var i = 0,\r
63798 n = parent.firstChild;\r
63799 while (n) {\r
63800 if (n.nodeType == 1) {\r
63801 if (++i == index) {\r
63802 return n;\r
63803 }\r
63804 }\r
63805 n = n.nextSibling;\r
63806 }\r
63807 return null;\r
63808 };\r
63809
63810 next = useElementPointer ? function(n) {\r
63811 return n.nextElementSibling;\r
63812 } : function(n) {\r
63813 while ((n = n.nextSibling) && n.nodeType != 1){}\r
63814 return n;\r
63815 };\r
63816
63817 prev = useElementPointer ? function(n) {\r
63818 return n.previousElementSibling;\r
63819 } : function(n) {\r
63820 while ((n = n.previousSibling) && n.nodeType != 1){}\r
63821 return n;\r
63822 };\r
63823
63824
63825 function children(parent) {\r
63826 var n = parent.firstChild,\r
63827 nodeIndex = -1,\r
63828 nextNode;\r
63829 while (n) {\r
63830 nextNode = n.nextSibling;\r
63831
63832 if (n.nodeType == 3 && !nonSpace.test(n.nodeValue)) {\r
63833 parent.removeChild(n);\r
63834 } else {\r
63835
63836 n.nodeIndex = ++nodeIndex;\r
63837 }\r
63838 n = nextNode;\r
63839 }\r
63840 return this;\r
63841 }\r
63842
63843
63844 byClassName = useClassList ?
63845 function(nodeSet, cls) {\r
63846 cls = unescapeCssSelector(cls);\r
63847 if (!cls) {\r
63848 return nodeSet;\r
63849 }\r
63850 var result = [],\r
63851 ri = -1,\r
63852 i, ci, classList;\r
63853 for (i = 0; ci = nodeSet[i]; i++) {\r
63854 classList = ci.classList;\r
63855 if (classList) {\r
63856 if (classList.contains(cls)) {\r
63857 result[++ri] = ci;\r
63858 }\r
63859 } else if ((' ' + ci.className + ' ').indexOf(cls) !== -1) {\r
63860
63861
63862 result[++ri] = ci;\r
63863 }\r
63864 }\r
63865 return result;\r
63866 } : function(nodeSet, cls) {\r
63867 cls = unescapeCssSelector(cls);\r
63868 if (!cls) {\r
63869 return nodeSet;\r
63870 }\r
63871 var result = [],\r
63872 ri = -1,\r
63873 i, ci;\r
63874 for (i = 0; ci = nodeSet[i]; i++) {\r
63875 if ((' ' + ci.className + ' ').indexOf(cls) !== -1) {\r
63876 result[++ri] = ci;\r
63877 }\r
63878 }\r
63879 return result;\r
63880 };\r
63881 function attrValue(n, attr) {\r
63882
63883 if (!n.tagName && typeof n.length != "undefined") {\r
63884 n = n[0];\r
63885 }\r
63886 if (!n) {\r
63887 return null;\r
63888 }\r
63889 if (attr == "for") {\r
63890 return n.htmlFor;\r
63891 }\r
63892 if (attr == "class" || attr == "className") {\r
63893 return n.className;\r
63894 }\r
63895 return n.getAttribute(attr) || n[attr];\r
63896 }\r
63897
63898
63899
63900 function getNodes(ns, mode, tagName) {\r
63901 var result = [],\r
63902 ri = -1,\r
63903 cs, i, ni, j, ci, cn, utag, n, cj;\r
63904 if (!ns) {\r
63905 return result;\r
63906 }\r
63907 tagName = tagName.replace('|', ':') || "*";\r
63908
63909 if (typeof ns.getElementsByTagName != "undefined") {\r
63910 ns = [\r
63911 ns\r
63912 ];\r
63913 }\r
63914
63915
63916 if (!mode) {\r
63917 tagName = unescapeCssSelector(tagName);\r
63918 if (!supportsColonNsSeparator && DQ.isXml(ns[0]) && tagName.indexOf(':') !== -1) {\r
63919
63920
63921
63922
63923
63924
63925 for (i = 0; ni = ns[i]; i++) {\r
63926 cs = ni.getElementsByTagName(tagName.split(':').pop());\r
63927 for (j = 0; ci = cs[j]; j++) {\r
63928 if (ci.tagName === tagName) {\r
63929 result[++ri] = ci;\r
63930 }\r
63931 }\r
63932 }\r
63933 } else {\r
63934 for (i = 0; ni = ns[i]; i++) {\r
63935 cs = ni.getElementsByTagName(tagName);\r
63936 for (j = 0; ci = cs[j]; j++) {\r
63937 result[++ri] = ci;\r
63938 }\r
63939 }\r
63940 }\r
63941 }\r
63942
63943
63944 else if (mode == "/" || mode == ">") {\r
63945 utag = tagName.toUpperCase();\r
63946 for (i = 0; ni = ns[i]; i++) {\r
63947 cn = ni.childNodes;\r
63948 for (j = 0; cj = cn[j]; j++) {\r
63949 if (cj.nodeName == utag || cj.nodeName == tagName || tagName == '*') {\r
63950 result[++ri] = cj;\r
63951 }\r
63952 }\r
63953 }\r
63954 }\r
63955
63956
63957 else if (mode == "+") {\r
63958 utag = tagName.toUpperCase();\r
63959 for (i = 0; n = ns[i]; i++) {\r
63960 while ((n = n.nextSibling) && n.nodeType != 1){}\r
63961 if (n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')) {\r
63962 result[++ri] = n;\r
63963 }\r
63964 }\r
63965 }\r
63966
63967
63968 else if (mode == "~") {\r
63969 utag = tagName.toUpperCase();\r
63970 for (i = 0; n = ns[i]; i++) {\r
63971 while ((n = n.nextSibling)) {\r
63972 if (n.nodeName == utag || n.nodeName == tagName || tagName == '*') {\r
63973 result[++ri] = n;\r
63974 }\r
63975 }\r
63976 }\r
63977 }\r
63978 return result;\r
63979 }\r
63980 function concat(a, b) {\r
63981 a.push.apply(a, b);\r
63982 return a;\r
63983 }\r
63984 function byTag(cs, tagName) {\r
63985 if (cs.tagName || cs === doc) {\r
63986 cs = [\r
63987 cs\r
63988 ];\r
63989 }\r
63990 if (!tagName) {\r
63991 return cs;\r
63992 }\r
63993 var result = [],\r
63994 ri = -1,\r
63995 i, ci;\r
63996 tagName = tagName.toLowerCase();\r
63997 for (i = 0; ci = cs[i]; i++) {\r
63998 if (ci.nodeType == 1 && ci.tagName.toLowerCase() == tagName) {\r
63999 result[++ri] = ci;\r
64000 }\r
64001 }\r
64002 return result;\r
64003 }\r
64004 function byId(cs, id) {\r
64005 id = unescapeCssSelector(id);\r
64006 if (cs.tagName || cs === doc) {\r
64007 cs = [\r
64008 cs\r
64009 ];\r
64010 }\r
64011 if (!id) {\r
64012 return cs;\r
64013 }\r
64014 var result = [],\r
64015 ri = -1,\r
64016 i, ci;\r
64017 for (i = 0; ci = cs[i]; i++) {\r
64018 if (ci && ci.id == id) {\r
64019 result[++ri] = ci;\r
64020 return result;\r
64021 }\r
64022 }\r
64023 return result;\r
64024 }\r
64025
64026
64027 function byAttribute(cs, attr, value, op, custom) {\r
64028 var result = [],\r
64029 ri = -1,\r
64030 useGetStyle = custom == "{",\r
64031 fn = DQ.operators[op],\r
64032 a, xml, hasXml, i, ci;\r
64033 value = unescapeCssSelector(value);\r
64034 for (i = 0; ci = cs[i]; i++) {\r
64035
64036 if (ci.nodeType === 1) {\r
64037
64038 if (!hasXml) {\r
64039 xml = DQ.isXml(ci);\r
64040 hasXml = true;\r
64041 }\r
64042
64043 if (!xml) {\r
64044 if (useGetStyle) {\r
64045 a = DQ.getStyle(ci, attr);\r
64046 } else if (attr == "class" || attr == "className") {\r
64047 a = ci.className;\r
64048 } else if (attr == "for") {\r
64049 a = ci.htmlFor;\r
64050 } else if (attr == "href") {\r
64051
64052
64053 a = ci.getAttribute("href", 2);\r
64054 } else {\r
64055 a = ci.getAttribute(attr);\r
64056 }\r
64057 } else {\r
64058 a = ci.getAttribute(attr);\r
64059 }\r
64060 if ((fn && fn(a, value)) || (!fn && a)) {\r
64061 result[++ri] = ci;\r
64062 }\r
64063 }\r
64064 }\r
64065 return result;\r
64066 }\r
64067 function byPseudo(cs, name, value) {\r
64068 value = unescapeCssSelector(value);\r
64069 return DQ.pseudos[name](cs, value);\r
64070 }\r
64071 function nodupIEXml(cs) {\r
64072 var d = ++key,\r
64073 r, i, len, c;\r
64074 cs[0].setAttribute("_nodup", d);\r
64075 r = [\r
64076 cs[0]\r
64077 ];\r
64078 for (i = 1 , len = cs.length; i < len; i++) {\r
64079 c = cs[i];\r
64080 if (!c.getAttribute("_nodup") != d) {\r
64081 c.setAttribute("_nodup", d);\r
64082 r[r.length] = c;\r
64083 }\r
64084 }\r
64085 for (i = 0 , len = cs.length; i < len; i++) {\r
64086 cs[i].removeAttribute("_nodup");\r
64087 }\r
64088 return r;\r
64089 }\r
64090 function nodup(cs) {\r
64091 if (!cs) {\r
64092 return [];\r
64093 }\r
64094 var len = cs.length,\r
64095 c, i,\r
64096 r = cs,\r
64097 cj,\r
64098 ri = -1,\r
64099 d, j;\r
64100 if (!len || typeof cs.nodeType != "undefined" || len == 1) {\r
64101 return cs;\r
64102 }\r
64103 if (isIE && typeof cs[0].selectSingleNode != "undefined") {\r
64104 return nodupIEXml(cs);\r
64105 }\r
64106 d = ++key;\r
64107 cs[0]._nodup = d;\r
64108 for (i = 1; c = cs[i]; i++) {\r
64109 if (c._nodup != d) {\r
64110 c._nodup = d;\r
64111 } else {\r
64112 r = [];\r
64113 for (j = 0; j < i; j++) {\r
64114 r[++ri] = cs[j];\r
64115 }\r
64116 for (j = i + 1; cj = cs[j]; j++) {\r
64117 if (cj._nodup != d) {\r
64118 cj._nodup = d;\r
64119 r[++ri] = cj;\r
64120 }\r
64121 }\r
64122 return r;\r
64123 }\r
64124 }\r
64125 return r;\r
64126 }\r
64127 function quickDiffIEXml(c1, c2) {\r
64128 var d = ++key,\r
64129 r = [],\r
64130 i, len;\r
64131 for (i = 0 , len = c1.length; i < len; i++) {\r
64132 c1[i].setAttribute("_qdiff", d);\r
64133 }\r
64134 for (i = 0 , len = c2.length; i < len; i++) {\r
64135 if (c2[i].getAttribute("_qdiff") != d) {\r
64136 r[r.length] = c2[i];\r
64137 }\r
64138 }\r
64139 for (i = 0 , len = c1.length; i < len; i++) {\r
64140 c1[i].removeAttribute("_qdiff");\r
64141 }\r
64142 return r;\r
64143 }\r
64144 function quickDiff(c1, c2) {\r
64145 var len1 = c1.length,\r
64146 d = ++key,\r
64147 r = [],\r
64148 i, len;\r
64149 if (!len1) {\r
64150 return c2;\r
64151 }\r
64152 if (isIE && typeof c1[0].selectSingleNode != "undefined") {\r
64153 return quickDiffIEXml(c1, c2);\r
64154 }\r
64155 for (i = 0; i < len1; i++) {\r
64156 c1[i]._qdiff = d;\r
64157 }\r
64158 for (i = 0 , len = c2.length; i < len; i++) {\r
64159 if (c2[i]._qdiff != d) {\r
64160 r[r.length] = c2[i];\r
64161 }\r
64162 }\r
64163 return r;\r
64164 }\r
64165 function quickId(ns, mode, root, id) {\r
64166 if (ns == root) {\r
64167 id = unescapeCssSelector(id);\r
64168 var d = root.ownerDocument || root;\r
64169 return d.getElementById(id);\r
64170 }\r
64171 ns = getNodes(ns, mode, "*");\r
64172 return byId(ns, id);\r
64173 }\r
64174 return {\r
64175 singleton: true,\r
64176 alternateClassName: [\r
64177 'Ext.core.DomQuery',\r
64178 'Ext.DomQuery'\r
64179 ],\r
64180 _init: function() {\r
64181 DQ = this;\r
64182 DQ.operators = Ext.Object.chain(Ext.util.Operators);\r
64183
64184 DQ._cache = cache = new Ext.util.LruCache({\r
64185 maxSize: 200\r
64186 });\r
64187 DQ._valueCache = valueCache = new Ext.util.LruCache({\r
64188 maxSize: 200\r
64189 });\r
64190 DQ._simpleCache = simpleCache = new Ext.util.LruCache({\r
64191 maxSize: 200\r
64192 });\r
64193 },\r
64194 clearCache: function() {\r
64195 cache.clear();\r
64196 valueCache.clear();\r
64197 simpleCache.clear();\r
64198 },\r
64199 getStyle: function(el, name) {\r
64200 return Ext.fly(el, '_DomQuery').getStyle(name);\r
64201 },\r
64202 \r
64203 compile: function(path, type) {\r
64204 type = type || "select";\r
64205
64206 var fn = [\r
64207 "var f = function(root) {\n var mode; ++batch; var n = root || document;\n"\r
64208 ],\r
64209 lastPath,\r
64210 matchers = DQ.matchers,\r
64211 matchersLn = matchers.length,\r
64212 modeMatch,\r
64213
64214 lmode = path.match(modeRe),\r
64215 tokenMatch, matched, j, t, m;\r
64216 path = setupEscapes(path);\r
64217 if (lmode && lmode[1]) {\r
64218 fn[fn.length] = 'mode="' + lmode[1].replace(trimRe, "") + '";';\r
64219 path = path.replace(lmode[1], "");\r
64220 }\r
64221
64222 while (path.substr(0, 1) == "/") {\r
64223 path = path.substr(1);\r
64224 }\r
64225 while (path && lastPath != path) {\r
64226 lastPath = path;\r
64227 tokenMatch = path.match(tagTokenRe);\r
64228 if (type == "select") {\r
64229 if (tokenMatch) {\r
64230
64231 if (tokenMatch[1] == "#") {\r
64232 fn[fn.length] = 'n = quickId(n, mode, root, "' + tokenMatch[2] + '");';\r
64233 } else {\r
64234 fn[fn.length] = 'n = getNodes(n, mode, "' + tokenMatch[2] + '");';\r
64235 }\r
64236 path = path.replace(tokenMatch[0], "");\r
64237 } else if (path.substr(0, 1) != '@') {\r
64238 fn[fn.length] = 'n = getNodes(n, mode, "*");';\r
64239 }\r
64240 } else
64241 {\r
64242 if (tokenMatch) {\r
64243 if (tokenMatch[1] == "#") {\r
64244 fn[fn.length] = 'n = byId(n, "' + tokenMatch[2] + '");';\r
64245 } else {\r
64246 fn[fn.length] = 'n = byTag(n, "' + tokenMatch[2] + '");';\r
64247 }\r
64248 path = path.replace(tokenMatch[0], "");\r
64249 }\r
64250 }\r
64251 while (!(modeMatch = path.match(modeRe))) {\r
64252 matched = false;\r
64253 for (j = 0; j < matchersLn; j++) {\r
64254 t = matchers[j];\r
64255 m = path.match(t.re);\r
64256 if (m) {\r
64257 fn[fn.length] = t.select.replace(tplRe, function(x, i) {\r
64258 return m[i];\r
64259 });\r
64260 path = path.replace(m[0], "");\r
64261 matched = true;\r
64262 break;\r
64263 }\r
64264 }\r
64265
64266 if (!matched) {\r
64267 Ext.raise({\r
64268 sourceClass: 'Ext.DomQuery',\r
64269 sourceMethod: 'compile',\r
64270 msg: 'Error parsing selector. Parsing failed at "' + path + '"'\r
64271 });\r
64272 }\r
64273 }\r
64274 if (modeMatch[1]) {\r
64275 fn[fn.length] = 'mode="' + modeMatch[1].replace(trimRe, "") + '";';\r
64276 path = path.replace(modeMatch[1], "");\r
64277 }\r
64278 }\r
64279
64280 fn[fn.length] = "return nodup(n);\n}";\r
64281
64282 eval(fn.join(""));\r
64283 return f;\r
64284 },\r
64285 \r
64286 jsSelect: function(path, root, type) {\r
64287
64288 root = root || doc;\r
64289 if (typeof root == "string") {\r
64290 root = doc.getElementById(root);\r
64291 }\r
64292 var paths = Ext.splitAndUnescape(path, ","),\r
64293 results = [],\r
64294 query, i, len, subPath, result;\r
64295
64296 for (i = 0 , len = paths.length; i < len; i++) {\r
64297 subPath = paths[i].replace(trimRe, "");\r
64298
64299 query = cache.get(subPath);\r
64300 if (!query) {\r
64301
64302 query = DQ.compile(subPath, type);\r
64303 if (!query) {\r
64304 Ext.raise({\r
64305 sourceClass: 'Ext.DomQuery',\r
64306 sourceMethod: 'jsSelect',\r
64307 msg: subPath + ' is not a valid selector'\r
64308 });\r
64309 }\r
64310 cache.add(subPath, query);\r
64311 } else {\r
64312
64313
64314 setupEscapes(subPath);\r
64315 }\r
64316 result = query(root);\r
64317 if (result && result !== doc) {\r
64318 results = results.concat(result);\r
64319 }\r
64320 }\r
64321
64322
64323 if (paths.length > 1) {\r
64324 return nodup(results);\r
64325 }\r
64326 return results;\r
64327 },\r
64328 isXml: function(el) {\r
64329 var docEl = (el ? el.ownerDocument || el : 0).documentElement;\r
64330 return docEl ? docEl.nodeName !== "HTML" : false;\r
64331 },\r
64332 \r
64333 select: doc.querySelectorAll ? function(path, root, type, single) {\r
64334 root = root || doc;\r
64335 if (!DQ.isXml(root)) {\r
64336 try {\r
64337 \r
64338 if (root.parentNode && (root.nodeType !== 9) && path.indexOf(',') === -1 && !startIdRe.test(path)) {\r
64339 path = Ext.makeIdSelector(Ext.id(root)) + ' ' + path;\r
64340 root = root.parentNode;\r
64341 }\r
64342 return single ? [\r
64343 root.querySelector(path)\r
64344 ] : Ext.Array.toArray(root.querySelectorAll(path));\r
64345 } catch (e) {}\r
64346 }\r
64347 return DQ.jsSelect.call(this, path, root, type);\r
64348 } : function(path, root, type) {\r
64349 return DQ.jsSelect.call(this, path, root, type);\r
64350 },\r
64351 \r
64352 selectNode: function(path, root) {\r
64353 return Ext.DomQuery.select(path, root, null, true)[0];\r
64354 },\r
64355 \r
64356 selectValue: function(path, root, defaultValue) {\r
64357 path = path.replace(trimRe, "");\r
64358 var query = valueCache.get(path),\r
64359 n, v;\r
64360 if (!query) {\r
64361 query = DQ.compile(path, "select");\r
64362 valueCache.add(path, query);\r
64363 } else {\r
64364 setupEscapes(path);\r
64365 }\r
64366 n = query(root);\r
64367 return DQ.getNodeValue(n[0] || n, defaultValue);\r
64368 },\r
64369 \r
64370 getNodeValue: function(node, defaultValue) {\r
64371
64372
64373
64374
64375 if (typeof node.normalize == 'function') {\r
64376 node.normalize();\r
64377 }\r
64378 var firstChild = node && node.firstChild,\r
64379 v = firstChild ? firstChild.nodeValue : null;\r
64380
64381
64382
64383 if (defaultValue !== undefined && (v == null || v === '')) {\r
64384 v = defaultValue;\r
64385 }\r
64386 return v;\r
64387 },\r
64388 \r
64389 selectNumber: function(path, root, defaultValue) {\r
64390 var v = DQ.selectValue(path, root, defaultValue || 0);\r
64391 return parseFloat(v);\r
64392 },\r
64393 \r
64394 is: function(el, ss) {\r
64395 if (typeof el == "string") {\r
64396 el = doc.getElementById(el);\r
64397 }\r
64398 var isArray = Ext.isArray(el),\r
64399 result = DQ.filter(isArray ? el : [\r
64400 el\r
64401 ], ss);\r
64402 return isArray ? (result.length == el.length) : (result.length > 0);\r
64403 },\r
64404 \r
64405 filter: function(els, ss, nonMatches) {\r
64406 ss = ss.replace(trimRe, "");\r
64407 var query = simpleCache.get(ss),\r
64408 result;\r
64409 if (!query) {\r
64410 query = DQ.compile(ss, "simple");\r
64411 simpleCache.add(ss, query);\r
64412 } else {\r
64413 setupEscapes(ss);\r
64414 }\r
64415 result = query(els);\r
64416 return nonMatches ? quickDiff(result, els) : result;\r
64417 },\r
64418 \r
64419 matchers: [\r
64420 {\r
64421 re: /^\.([\w\-\\]+)/,\r
64422 select: useClassList ? 'n = byClassName(n, "{1}");' : 'n = byClassName(n, " {1} ");'\r
64423 },\r
64424 {\r
64425 re: /^\:([\w\-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,\r
64426 select: 'n = byPseudo(n, "{1}", "{2}");'\r
64427 },\r
64428 {\r
64429 re: /^(?:([\[\{])(?:@)?([\w\-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,\r
64430 select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'\r
64431 },\r
64432 {\r
64433 re: /^#([\w\-\\]+)/,\r
64434 select: 'n = byId(n, "{1}");'\r
64435 },\r
64436 {\r
64437 re: /^@([\w\-\.]+)/,\r
64438 select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'\r
64439 }\r
64440 ],\r
64441 \r
64442 \r
64443 pseudos: {\r
64444 "first-child": function(c) {\r
64445 var r = [],\r
64446 ri = -1,\r
64447 n, i, ci;\r
64448 for (i = 0; (ci = n = c[i]); i++) {\r
64449 while ((n = n.previousSibling) && n.nodeType != 1){}\r
64450 if (!n) {\r
64451 r[++ri] = ci;\r
64452 }\r
64453 }\r
64454 return r;\r
64455 },\r
64456 "last-child": function(c) {\r
64457 var r = [],\r
64458 ri = -1,\r
64459 n, i, ci;\r
64460 for (i = 0; (ci = n = c[i]); i++) {\r
64461 while ((n = n.nextSibling) && n.nodeType != 1){}\r
64462 if (!n) {\r
64463 r[++ri] = ci;\r
64464 }\r
64465 }\r
64466 return r;\r
64467 },\r
64468 "nth-child": function(c, a) {\r
64469 var r = [],\r
64470 ri = -1,\r
64471 m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a),\r
64472 f = (m[1] || 1) - 0,\r
64473 l = m[2] - 0,\r
64474 i, n, j, cn, pn;\r
64475 for (i = 0; n = c[i]; i++) {\r
64476 pn = n.parentNode;\r
64477 if (batch != pn._batch) {\r
64478 j = 0;\r
64479 for (cn = pn.firstChild; cn; cn = cn.nextSibling) {\r
64480 if (cn.nodeType == 1) {\r
64481 cn.nodeIndex = ++j;\r
64482 }\r
64483 }\r
64484 pn._batch = batch;\r
64485 }\r
64486 if (f == 1) {\r
64487 if (l === 0 || n.nodeIndex == l) {\r
64488 r[++ri] = n;\r
64489 }\r
64490 } else if ((n.nodeIndex + l) % f === 0) {\r
64491 r[++ri] = n;\r
64492 }\r
64493 }\r
64494 return r;\r
64495 },\r
64496 "only-child": function(c) {\r
64497 var r = [],\r
64498 ri = -1,\r
64499 i, ci;\r
64500 for (i = 0; ci = c[i]; i++) {\r
64501 if (!prev(ci) && !next(ci)) {\r
64502 r[++ri] = ci;\r
64503 }\r
64504 }\r
64505 return r;\r
64506 },\r
64507 "empty": function(c) {\r
64508 var r = [],\r
64509 ri = -1,\r
64510 i, ci, cns, j, cn, empty;\r
64511 for (i = 0; ci = c[i]; i++) {\r
64512 cns = ci.childNodes;\r
64513 j = 0;\r
64514 empty = true;\r
64515 while (cn = cns[j]) {\r
64516 ++j;\r
64517 if (cn.nodeType == 1 || cn.nodeType == 3) {\r
64518 empty = false;\r
64519 break;\r
64520 }\r
64521 }\r
64522 if (empty) {\r
64523 r[++ri] = ci;\r
64524 }\r
64525 }\r
64526 return r;\r
64527 },\r
64528 "contains": function(c, v) {\r
64529 var r = [],\r
64530 ri = -1,\r
64531 i, ci;\r
64532 for (i = 0; ci = c[i]; i++) {\r
64533 if ((ci.textContent || ci.innerText || ci.text || '').indexOf(v) != -1) {\r
64534 r[++ri] = ci;\r
64535 }\r
64536 }\r
64537 return r;\r
64538 },\r
64539 "nodeValue": function(c, v) {\r
64540 var r = [],\r
64541 ri = -1,\r
64542 i, ci;\r
64543 for (i = 0; ci = c[i]; i++) {\r
64544 if (ci.firstChild && ci.firstChild.nodeValue == v) {\r
64545 r[++ri] = ci;\r
64546 }\r
64547 }\r
64548 return r;\r
64549 },\r
64550 "checked": function(c) {\r
64551 var r = [],\r
64552 ri = -1,\r
64553 i, ci;\r
64554 for (i = 0; ci = c[i]; i++) {\r
64555 if (ci.checked === true) {\r
64556 r[++ri] = ci;\r
64557 }\r
64558 }\r
64559 return r;\r
64560 },\r
64561 "not": function(c, ss) {\r
64562 return DQ.filter(c, ss, true);\r
64563 },\r
64564 "any": function(c, selectors) {\r
64565 var ss = selectors.split('|'),\r
64566 r = [],\r
64567 ri = -1,\r
64568 s, i, ci, j;\r
64569 for (i = 0; ci = c[i]; i++) {\r
64570 for (j = 0; s = ss[j]; j++) {\r
64571 if (DQ.is(ci, s)) {\r
64572 r[++ri] = ci;\r
64573 break;\r
64574 }\r
64575 }\r
64576 }\r
64577 return r;\r
64578 },\r
64579 "odd": function(c) {\r
64580 return this["nth-child"](c, "odd");\r
64581 },\r
64582 "even": function(c) {\r
64583 return this["nth-child"](c, "even");\r
64584 },\r
64585 "nth": function(c, a) {\r
64586 return c[a - 1] || [];\r
64587 },\r
64588 "first": function(c) {\r
64589 return c[0] || [];\r
64590 },\r
64591 "last": function(c) {\r
64592 return c[c.length - 1] || [];\r
64593 },\r
64594 "has": function(c, ss) {\r
64595 var s = DQ.select,\r
64596 r = [],\r
64597 ri = -1,\r
64598 i, ci;\r
64599 for (i = 0; ci = c[i]; i++) {\r
64600 if (s(ss, ci).length > 0) {\r
64601 r[++ri] = ci;\r
64602 }\r
64603 }\r
64604 return r;\r
64605 },\r
64606 "next": function(c, ss) {\r
64607 var is = DQ.is,\r
64608 r = [],\r
64609 ri = -1,\r
64610 i, ci, n;\r
64611 for (i = 0; ci = c[i]; i++) {\r
64612 n = next(ci);\r
64613 if (n && is(n, ss)) {\r
64614 r[++ri] = ci;\r
64615 }\r
64616 }\r
64617 return r;\r
64618 },\r
64619 "prev": function(c, ss) {\r
64620 var is = DQ.is,\r
64621 r = [],\r
64622 ri = -1,\r
64623 i, ci, n;\r
64624 for (i = 0; ci = c[i]; i++) {\r
64625 n = prev(ci);\r
64626 if (n && is(n, ss)) {\r
64627 r[++ri] = ci;\r
64628 }\r
64629 }\r
64630 return r;\r
64631 },\r
64632 focusable: function(candidates) {\r
64633 var len = candidates.length,\r
64634 results = [],\r
64635 i = 0,\r
64636 c;\r
64637 for (; i < len; i++) {\r
64638 c = candidates[i];\r
64639 if (Ext.fly(c, '_DomQuery').isFocusable()) {\r
64640 results.push(c);\r
64641 }\r
64642 }\r
64643 return results;\r
64644 },\r
64645 visible: function(candidates, deep) {\r
64646 var len = candidates.length,\r
64647 results = [],\r
64648 i = 0,\r
64649 c;\r
64650 for (; i < len; i++) {\r
64651 c = candidates[i];\r
64652 if (Ext.fly(c, '_DomQuery').isVisible(deep)) {\r
64653 results.push(c);\r
64654 }\r
64655 }\r
64656 return results;\r
64657 },\r
64658 isScrolled: function(c) {\r
64659 var r = [],\r
64660 ri = -1,\r
64661 i, ci, s;\r
64662 for (i = 0; ci = c[i]; i++) {\r
64663 s = Ext.fly(ci, '_DomQuery').getScroll();\r
64664 if (s.top > 0 || s.left > 0) {\r
64665 r[++ri] = ci;\r
64666 }\r
64667 }\r
64668 return r;\r
64669 }\r
64670 }\r
64671 };\r
64672}, function() {\r
64673 this._init();\r
64674});\r
64675\r
64676\r
64677Ext.define('Ext.data.reader.Xml', {\r
64678 extend: Ext.data.reader.Reader,\r
64679 alternateClassName: 'Ext.data.XmlReader',\r
64680 alias: 'reader.xml',\r
64681 config: {\r
64682 \r
64683 record: '',\r
64684 \r
64685 namespace: ''\r
64686 },\r
64687 \r
64688 createAccessor: function(expr) {\r
64689 if (Ext.isEmpty(expr)) {\r
64690 return Ext.emptyFn;\r
64691 }\r
64692 if (Ext.isFunction(expr)) {\r
64693 return expr;\r
64694 }\r
64695 return function(root) {\r
64696 return this.getNodeValue(Ext.DomQuery.selectNode(expr, root));\r
64697 };\r
64698 },\r
64699 getNodeValue: function(node) {\r
64700 if (node) {\r
64701
64702
64703
64704 if (typeof node.normalize === 'function') {\r
64705 node.normalize();\r
64706 }\r
64707 node = node.firstChild;\r
64708 if (node) {\r
64709 return node.nodeValue;\r
64710 }\r
64711 }\r
64712 return undefined;\r
64713 },\r
64714 getResponseData: function(response) {\r
64715 var xml = response.responseXML,\r
64716 error = 'XML data not found in the response';\r
64717 if (!xml) {\r
64718 Ext.Logger.warn(error);\r
64719 return this.createReadError(error);\r
64720 }\r
64721 return xml;\r
64722 },\r
64723 \r
64724 getData: function(data) {\r
64725 return data.documentElement || data;\r
64726 },\r
64727 \r
64728 getRoot: function(data) {\r
64729 var nodeName = data.nodeName,\r
64730 root = this.getRootProperty();\r
64731 if (!root || (nodeName && nodeName == root)) {\r
64732 return data;\r
64733 } else if (Ext.DomQuery.isXml(data)) {\r
64734
64735
64736
64737 return Ext.DomQuery.selectNode(root, data);\r
64738 }\r
64739 },\r
64740 \r
64741 extractData: function(root, readOptions) {\r
64742 var recordName = this.getRecord();\r
64743
64744 if (!recordName) {\r
64745 Ext.raise('Record is a required parameter');\r
64746 }\r
64747
64748 if (recordName !== root.nodeName) {\r
64749 root = Ext.DomQuery.select(recordName, root);\r
64750 } else {\r
64751 root = [\r
64752 root\r
64753 ];\r
64754 }\r
64755 return this.callParent([\r
64756 root,\r
64757 readOptions\r
64758 ]);\r
64759 },\r
64760 \r
64761 readRecords: function(doc, readOptions, \r
64762 internalReadOptions) {\r
64763
64764
64765 if (Ext.isArray(doc)) {\r
64766 doc = doc[0];\r
64767 }\r
64768 return this.callParent([\r
64769 doc,\r
64770 readOptions,\r
64771 internalReadOptions\r
64772 ]);\r
64773 },\r
64774 \r
64775 createFieldAccessor: function(field) {\r
64776 var me = this,\r
64777 namespace = me.getNamespace(),\r
64778 selector, result;\r
64779 selector = field.mapping || ((namespace ? namespace + '|' : '') + field.name);\r
64780 if (typeof selector === 'function') {\r
64781 result = function(raw) {\r
64782 return field.mapping(raw, me);\r
64783 };\r
64784 } else {\r
64785 result = function(raw) {\r
64786 return me.getNodeValue(Ext.DomQuery.selectNode(selector, raw));\r
64787 };\r
64788 }\r
64789 return result;\r
64790 },\r
64791 deprecated: {\r
64792 '5.1.1': {\r
64793 properties: {\r
64794 \r
64795 xmlData: null\r
64796 }\r
64797 }\r
64798 }\r
64799});\r
64800\r
64801\r
64802Ext.define('Ext.data.writer.Xml', {\r
64803 \r
64804 extend: Ext.data.writer.Writer,\r
64805 alternateClassName: 'Ext.data.XmlWriter',\r
64806 alias: 'writer.xml',\r
64807 \r
64808 config: {\r
64809 \r
64810 documentRoot: 'xmlData',\r
64811 \r
64812 defaultDocumentRoot: 'xmlData',\r
64813 \r
64814 header: '',\r
64815 \r
64816 record: 'record'\r
64817 },\r
64818
64819 selectorRe: /[^>\s]+/g,\r
64820 writeRecords: function(request, data) {\r
64821 var me = this,\r
64822 xml = [],\r
64823 i = 0,\r
64824 len = data.length,\r
64825 root = me.getDocumentRoot(),\r
64826 recordName = me.getRecord(),\r
64827
64828 record = recordName.match(this.selectorRe),\r
64829 recLen = record.length,\r
64830
64831
64832 needsRoot = data.length !== 1 && recLen === 1,\r
64833 transform;\r
64834 transform = this.getTransform();\r
64835 if (transform) {\r
64836 data = transform(data, request);\r
64837 }\r
64838
64839 xml.push(me.getHeader() || '');\r
64840 if (!root && needsRoot) {\r
64841 root = me.getDefaultDocumentRoot();\r
64842 }\r
64843
64844 if (root) {\r
64845 xml.push('<', root, '>');\r
64846 }\r
64847
64848 for (i = 0; i < recLen - 1; i++) {\r
64849 xml.push('<', record[i], '>');\r
64850 }\r
64851 recordName = record[i];\r
64852 for (i = 0; i < len; ++i) {\r
64853 this.objectToElement(recordName, data[i], xml);\r
64854 }\r
64855
64856 for (i = recLen - 2; i > -1; i--) {\r
64857 xml.push('</', record[i], '>');\r
64858 }\r
64859 if (root) {\r
64860 xml.push('</', root, '>');\r
64861 }\r
64862 request.setXmlData(xml.join(''));\r
64863 return request;\r
64864 },\r
64865 \r
64866 objectToElement: function(name, o, output) {\r
64867 var key, datum,\r
64868 subOutput = [],\r
64869 subKeys, subKeyLen, i, subObject, subObjects, lastObject, lastKey;\r
64870 if (!output) {\r
64871 output = [];\r
64872 }\r
64873
64874
64875 output.push('<', name);\r
64876 for (key in o) {\r
64877 datum = o[key];\r
64878
64879 if (key[0] === '@') {\r
64880 output.push(' ', key.substr(1), '="', datum, '"');\r
64881 } else
64882 {\r
64883
64884 if (typeof datum === 'object') {\r
64885 this.objectToElement(key, datum, subOutput);\r
64886 } else {\r
64887
64888 subKeys = key.match(this.selectorRe);\r
64889
64890
64891 if ((subKeyLen = subKeys.length) > 1) {\r
64892 subObjects = subObjects || {};\r
64893 for (subObject = subObjects , i = 0; i < subKeyLen; i++) {\r
64894 lastObject = subObject;\r
64895 lastKey = subKeys[i];\r
64896 subObject = subObject[lastKey] || (subObject[lastKey] = {});\r
64897 }\r
64898
64899 lastObject[lastKey] = datum;\r
64900 } else {\r
64901 subOutput.push('<', key, '>', datum, '</', key, '>');\r
64902 }\r
64903 }\r
64904 }\r
64905 }\r
64906 output.push('>');\r
64907 output.push.apply(output, subOutput);\r
64908
64909 if (subObjects) {\r
64910 for (key in subObjects) {\r
64911 datum = subObjects[key];\r
64912 this.objectToElement(key, datum, output);\r
64913 }\r
64914 }\r
64915
64916 output.push('</', name, '>');\r
64917 return output;\r
64918 }\r
64919});\r
64920\r
64921\r
64922Ext.define('Ext.data.XmlStore', {\r
64923 extend: Ext.data.Store,\r
64924 alias: 'store.xml',\r
64925 constructor: function(config) {\r
64926 config = Ext.apply({\r
64927 proxy: {\r
64928 type: 'ajax',\r
64929 reader: 'xml',\r
64930 writer: 'xml'\r
64931 }\r
64932 }, config);\r
64933 this.callParent([\r
64934 config\r
64935 ]);\r
64936 }\r
64937});\r
64938\r
64939\r
64940Ext.define('Ext.data.identifier.Negative', {\r
64941 extend: Ext.data.identifier.Sequential,\r
64942 alias: 'data.identifier.negative',\r
64943 config: {\r
64944 increment: -1,\r
64945 seed: -1\r
64946 }\r
64947});\r
64948\r
64949\r
64950Ext.define('Ext.data.identifier.Uuid', {\r
64951 extend: Ext.data.identifier.Generator,\r
64952 alias: 'data.identifier.uuid',\r
64953 \r
64954 isUnique: true,\r
64955 config: {\r
64956 \r
64957 id: null\r
64958 },\r
64959 \r
64960 \r
64961 \r
64962 \r
64963 constructor: function(config) {\r
64964 this.callParent([\r
64965 config\r
64966 ]);\r
64967 this.reconfigure(config);\r
64968 },\r
64969 \r
64970 reconfigure: function(config) {\r
64971 var cls = this.self;\r
64972 this.generate = (config && config.version === 1) ? cls.createSequential(config.salt, config.timestamp, config.clockSeq) : cls.createRandom();\r
64973 },\r
64974 clone: null,\r
64975 statics: {\r
64976 createRandom: function() {\r
64977 var pattern = 'xxxxxxxx-xxxx-4xxx-Rxxx-xMxxxxxxxxxx'.split(''),\r
64978 hex = '0123456789abcdef'.split(''),\r
64979 length = pattern.length,\r
64980 parts = [];\r
64981 return function() {\r
64982 for (var r, c,\r
64983 i = 0; i < length; ++i) {\r
64984 c = pattern[i];\r
64985 if (c !== '-' && c !== '4') {\r
64986 r = Math.random() * 16;\r
64987 r = (c === 'R') ? (r & 3 | 8) : (r | ((c === 'M') ? 1 : 0));\r
64988 c = hex[r];\r
64989 }\r
64990
64991 parts[i] = c;\r
64992 }\r
64993 return parts.join('');\r
64994 };\r
64995 },\r
64996 createSequential: function(salt, time, clockSeq) {\r
64997 var parts = [],\r
64998 twoPow32 = Math.pow(2, 32),\r
64999 saltLo = salt.lo,\r
65000 saltHi = salt.hi,\r
65001 timeLo = time.lo,\r
65002 timeHi = time.hi,\r
65003 toHex = function(value, length) {\r
65004 var ret = value.toString(16).toLowerCase();\r
65005 if (ret.length > length) {\r
65006 ret = ret.substring(ret.length - length);\r
65007 }\r
65008
65009 else if (ret.length < length) {\r
65010 ret = Ext.String.leftPad(ret, length, '0');\r
65011 }\r
65012 return ret;\r
65013 };\r
65014 if (typeof salt === 'number') {\r
65015 saltHi = Math.floor(salt / twoPow32);\r
65016 saltLo = Math.floor(salt - saltHi * twoPow32);\r
65017 }\r
65018 if (typeof time === 'number') {\r
65019 timeHi = Math.floor(time / twoPow32);\r
65020 timeLo = Math.floor(time - timeHi * twoPow32);\r
65021 }\r
65022
65023
65024 saltHi |= 256;\r
65025 parts[3] = toHex(128 | ((clockSeq >>> 8) & 63), 2) + toHex(clockSeq & 255, 2);\r
65026 parts[4] = toHex(saltHi, 4) + toHex(saltLo, 8);\r
65027 \r
65028 return function() {\r
65029 parts[0] = toHex(timeLo, 8);\r
65030 parts[1] = toHex(timeHi & 65535, 4);\r
65031 parts[2] = toHex(((timeHi >>> 16) & 4095) | (1 << 12), 4);\r
65032
65033 ++timeLo;\r
65034 if (timeLo >= twoPow32) {\r
65035
65036 timeLo = 0;\r
65037 ++timeHi;\r
65038 }\r
65039 return parts.join('-');\r
65040 };\r
65041 }\r
65042 }\r
65043}, function() {\r
65044 this.Global = new this({\r
65045 id: 'uuid'\r
65046 });\r
65047});\r
65048\r
65049\r
65050Ext.define('Ext.data.proxy.WebStorage', {\r
65051 extend: Ext.data.proxy.Client,\r
65052 alternateClassName: 'Ext.data.WebStorageProxy',\r
65053 config: {\r
65054 \r
65055 id: undefined\r
65056 },\r
65057 \r
65058 \r
65059 \r
65060 constructor: function(config) {\r
65061 this.callParent(arguments);\r
65062 \r
65063 this.cache = {};\r
65064
65065 if (this.getStorageObject() === undefined) {\r
65066 Ext.raise("Local Storage is not supported in this browser, please use another type of data proxy");\r
65067 }\r
65068
65069
65070 if (this.getId() === undefined) {\r
65071 Ext.raise("No unique id was provided to the local storage proxy. See Ext.data.proxy.LocalStorage documentation for details");\r
65072 }\r
65073
65074 this.initialize();\r
65075 },\r
65076 \r
65077 create: function(operation) {\r
65078 var me = this,\r
65079 records = operation.getRecords(),\r
65080 length = records.length,\r
65081 ids = me.getIds(),\r
65082 id, record, i, identifier;\r
65083 if (me.isHierarchical === undefined) {\r
65084
65085
65086 me.isHierarchical = !!records[0].isNode;\r
65087 if (me.isHierarchical) {\r
65088 me.getStorageObject().setItem(me.getTreeKey(), true);\r
65089 }\r
65090 }\r
65091 for (i = 0; i < length; i++) {\r
65092 record = records[i];\r
65093 if (record.phantom) {\r
65094 record.phantom = false;\r
65095 identifier = record.identifier;\r
65096 if (identifier && identifier.isUnique) {\r
65097 id = record.getId();\r
65098 } else {\r
65099 id = me.getNextId();\r
65100 }\r
65101 } else {\r
65102 id = record.getId();\r
65103 }\r
65104 me.setRecord(record, id);\r
65105 record.commit();\r
65106 ids.push(id);\r
65107 }\r
65108 me.setIds(ids);\r
65109 operation.setSuccessful(true);\r
65110 },\r
65111 \r
65112 read: function(operation) {\r
65113 var me = this,\r
65114 allRecords,\r
65115 records = [],\r
65116 success = true,\r
65117 Model = me.getModel(),\r
65118 validCount = 0,\r
65119 recordCreator = operation.getRecordCreator(),\r
65120 filters, sorters, limit, filterLen, valid, record, ids, length, data, id, i, j;\r
65121 if (me.isHierarchical) {\r
65122 records = me.getTreeData();\r
65123 } else {\r
65124 ids = me.getIds();\r
65125 length = ids.length;\r
65126 id = operation.getId();\r
65127
65128 if (id) {\r
65129 data = me.getRecord(id);\r
65130 if (data !== null) {\r
65131 record = recordCreator ? recordCreator(data, Model) : new Model(data);\r
65132 }\r
65133 if (record) {\r
65134 records.push(record);\r
65135 } else {\r
65136 success = false;\r
65137 }\r
65138 } else {\r
65139 sorters = operation.getSorters();\r
65140 filters = operation.getFilters();\r
65141 limit = operation.getLimit();\r
65142 allRecords = [];\r
65143
65144
65145
65146 for (i = 0; i < length; i++) {\r
65147 data = me.getRecord(ids[i]);\r
65148 record = recordCreator ? recordCreator(data, Model) : new Model(data);\r
65149 allRecords.push(record);\r
65150 }\r
65151 if (sorters) {\r
65152 Ext.Array.sort(allRecords, Ext.util.Sorter.createComparator(sorters));\r
65153 }\r
65154 for (i = operation.getStart() || 0; i < length; i++) {\r
65155 record = allRecords[i];\r
65156 valid = true;\r
65157 if (filters) {\r
65158 for (j = 0 , filterLen = filters.length; j < filterLen; j++) {\r
65159 valid = filters[j].filter(record);\r
65160 }\r
65161 }\r
65162 if (valid) {\r
65163 records.push(record);\r
65164 validCount++;\r
65165 }\r
65166 if (limit && validCount === limit) {\r
65167 break;\r
65168 }\r
65169 }\r
65170 }\r
65171 }\r
65172 if (success) {\r
65173 operation.setResultSet(new Ext.data.ResultSet({\r
65174 records: records,\r
65175 total: records.length,\r
65176 loaded: true\r
65177 }));\r
65178 operation.setSuccessful(true);\r
65179 } else {\r
65180 operation.setException('Unable to load records');\r
65181 }\r
65182 },\r
65183 \r
65184 update: function(operation) {\r
65185 var records = operation.getRecords(),\r
65186 length = records.length,\r
65187 ids = this.getIds(),\r
65188 record, id, i;\r
65189 for (i = 0; i < length; i++) {\r
65190 record = records[i];\r
65191 this.setRecord(record);\r
65192 record.commit();\r
65193
65194
65195 id = record.getId();\r
65196 if (id !== undefined && Ext.Array.indexOf(ids, id) === -1) {\r
65197 ids.push(id);\r
65198 }\r
65199 }\r
65200 this.setIds(ids);\r
65201 operation.setSuccessful(true);\r
65202 },\r
65203 \r
65204 erase: function(operation) {\r
65205 var me = this,\r
65206 records = operation.getRecords(),\r
65207 ids = me.getIds(),\r
65208 idLength = ids.length,\r
65209 newIds = [],\r
65210 removedHash = {},\r
65211 i = records.length,\r
65212 id;\r
65213 for (; i--; ) {\r
65214 Ext.apply(removedHash, me.removeRecord(records[i]));\r
65215 }\r
65216 for (i = 0; i < idLength; i++) {\r
65217 id = ids[i];\r
65218 if (!removedHash[id]) {\r
65219 newIds.push(id);\r
65220 }\r
65221 }\r
65222 me.setIds(newIds);\r
65223 operation.setSuccessful(true);\r
65224 },\r
65225 \r
65226 getRecord: function(id) {\r
65227 var me = this,\r
65228 cache = me.cache,\r
65229 data = !cache[id] ? Ext.decode(me.getStorageObject().getItem(me.getRecordKey(id))) : cache[id];\r
65230 if (!data) {\r
65231 return null;\r
65232 }\r
65233 cache[id] = data;\r
65234 data[me.getModel().prototype.idProperty] = id;\r
65235
65236
65237 return Ext.merge({}, data);\r
65238 },\r
65239 \r
65240 setRecord: function(record, id) {\r
65241 if (id) {\r
65242 record.set('id', id, {\r
65243 commit: true\r
65244 });\r
65245 } else {\r
65246 id = record.getId();\r
65247 }\r
65248 var me = this,\r
65249 rawData = record.getData(),\r
65250 data = {},\r
65251 model = me.getModel(),\r
65252 fields = model.getFields(),\r
65253 length = fields.length,\r
65254 i = 0,\r
65255 field, name, obj, key;\r
65256 for (; i < length; i++) {\r
65257 field = fields[i];\r
65258 name = field.name;\r
65259 if (field.persist) {\r
65260 data[name] = rawData[name];\r
65261 }\r
65262 }\r
65263
65264 delete data[model.prototype.idProperty];\r
65265
65266 if (record.isNode && record.get('depth') === 1) {\r
65267 delete data.parentId;\r
65268 }\r
65269 obj = me.getStorageObject();\r
65270 key = me.getRecordKey(id);\r
65271
65272 me.cache[id] = data;\r
65273
65274 obj.removeItem(key);\r
65275 obj.setItem(key, Ext.encode(data));\r
65276 },\r
65277 \r
65278 removeRecord: function(record) {\r
65279 var me = this,\r
65280 id = record.getId(),\r
65281 records = {},\r
65282 i, childNodes;\r
65283 records[id] = record;\r
65284 me.getStorageObject().removeItem(me.getRecordKey(id));\r
65285 delete me.cache[id];\r
65286 if (record.childNodes) {\r
65287 childNodes = record.childNodes;\r
65288 for (i = childNodes.length; i--; ) {\r
65289 Ext.apply(records, me.removeRecord(childNodes[i]));\r
65290 }\r
65291 }\r
65292 return records;\r
65293 },\r
65294 \r
65295 getRecordKey: function(id) {\r
65296 if (id.isModel) {\r
65297 id = id.getId();\r
65298 }\r
65299 return Ext.String.format("{0}-{1}", this.getId(), id);\r
65300 },\r
65301 \r
65302 getRecordCounterKey: function() {\r
65303 return Ext.String.format("{0}-counter", this.getId());\r
65304 },\r
65305 \r
65306 getTreeKey: function() {\r
65307 return Ext.String.format("{0}-tree", this.getId());\r
65308 },\r
65309 \r
65310 getIds: function() {\r
65311 var me = this,\r
65312 ids = (me.getStorageObject().getItem(me.getId()) || "").split(","),\r
65313 length = ids.length,\r
65314 isString = this.getIdField().isStringField,\r
65315 i;\r
65316 if (length === 1 && ids[0] === "") {\r
65317 ids = [];\r
65318 } else {\r
65319 for (i = 0; i < length; i++) {\r
65320 ids[i] = isString ? ids[i] : +ids[i];\r
65321 }\r
65322 }\r
65323 return ids;\r
65324 },\r
65325 getIdField: function() {\r
65326 return this.getModel().prototype.idField;\r
65327 },\r
65328 \r
65329 setIds: function(ids) {\r
65330 var obj = this.getStorageObject(),\r
65331 str = ids.join(","),\r
65332 id = this.getId();\r
65333 obj.removeItem(id);\r
65334 if (!Ext.isEmpty(str)) {\r
65335 obj.setItem(id, str);\r
65336 }\r
65337 },\r
65338 \r
65339 getNextId: function() {\r
65340 var me = this,\r
65341 obj = me.getStorageObject(),\r
65342 key = me.getRecordCounterKey(),\r
65343 isString = me.getIdField().isStringField,\r
65344 id;\r
65345 id = me.idGenerator.generate();\r
65346 obj.setItem(key, id);\r
65347 if (isString) {\r
65348 id = id + '';\r
65349 }\r
65350 return id;\r
65351 },\r
65352 \r
65353 getTreeData: function() {\r
65354 var me = this,\r
65355 ids = me.getIds(),\r
65356 length = ids.length,\r
65357 records = [],\r
65358 recordHash = {},\r
65359 root = [],\r
65360 i = 0,\r
65361 Model = me.getModel(),\r
65362 idProperty = Model.prototype.idProperty,\r
65363 rootLength, record, parent, parentId, children, id;\r
65364 for (; i < length; i++) {\r
65365 id = ids[i];\r
65366
65367 record = me.getRecord(id);\r
65368
65369 records.push(record);\r
65370
65371 recordHash[id] = record;\r
65372 if (!record.parentId) {\r
65373
65374 root.push(record);\r
65375 }\r
65376 }\r
65377 rootLength = root.length;\r
65378
65379 Ext.Array.sort(records, me.sortByParentId);\r
65380
65381 for (i = rootLength; i < length; i++) {\r
65382 record = records[i];\r
65383 parentId = record.parentId;\r
65384 if (!parent || parent[idProperty] !== parentId) {\r
65385
65386 parent = recordHash[parentId];\r
65387 parent.children = children = [];\r
65388 }\r
65389
65390 children.push(record);\r
65391 }\r
65392 for (i = length; i--; ) {\r
65393 record = records[i];\r
65394 if (!record.children && !record.leaf) {\r
65395
65396 record.loaded = true;\r
65397 }\r
65398 }\r
65399
65400 for (i = rootLength; i--; ) {\r
65401 record = root[i];\r
65402 root[i] = new Model(record);\r
65403 }\r
65404 return root;\r
65405 },\r
65406 \r
65407 sortByParentId: function(node1, node2) {\r
65408 return (node1.parentId || 0) - (node2.parentId || 0);\r
65409 },\r
65410 \r
65411 initialize: function() {\r
65412 var me = this,\r
65413 storageObject = me.getStorageObject(),\r
65414 lastId = +storageObject.getItem(me.getRecordCounterKey()),\r
65415 id = me.getId();\r
65416 storageObject.setItem(id, storageObject.getItem(id) || "");\r
65417 if (storageObject.getItem(me.getTreeKey())) {\r
65418 me.isHierarchical = true;\r
65419 }\r
65420 me.idGenerator = new Ext.data.identifier.Sequential({\r
65421 seed: lastId ? lastId + 1 : 1\r
65422 });\r
65423 },\r
65424 \r
65425 clear: function() {\r
65426 var me = this,\r
65427 obj = me.getStorageObject(),\r
65428 ids = me.getIds(),\r
65429 len = ids.length,\r
65430 i;\r
65431
65432 for (i = 0; i < len; i++) {\r
65433 obj.removeItem(me.getRecordKey(ids[i]));\r
65434 }\r
65435
65436 obj.removeItem(me.getRecordCounterKey());\r
65437 obj.removeItem(me.getTreeKey());\r
65438 obj.removeItem(me.getId());\r
65439
65440 me.cache = {};\r
65441 },\r
65442 \r
65443 getStorageObject: function() {\r
65444
65445 Ext.raise("The getStorageObject function has not been defined in your Ext.data.proxy.WebStorage subclass");\r
65446 }\r
65447});\r
65448
65449\r
65450\r
65451Ext.define('Ext.data.proxy.LocalStorage', {\r
65452 extend: Ext.data.proxy.WebStorage,\r
65453 alias: 'proxy.localstorage',\r
65454 alternateClassName: 'Ext.data.LocalStorageProxy',\r
65455 getStorageObject: function() {\r
65456 return window.localStorage;\r
65457 }\r
65458});\r
65459\r
65460\r
65461Ext.define('Ext.data.proxy.Rest', {\r
65462 extend: Ext.data.proxy.Ajax,\r
65463 alternateClassName: 'Ext.data.RestProxy',\r
65464 alias: 'proxy.rest',\r
65465 \r
65466 defaultActionMethods: {\r
65467 create: 'POST',\r
65468 read: 'GET',\r
65469 update: 'PUT',\r
65470 destroy: 'DELETE'\r
65471 },\r
65472 slashRe: /\/$/,\r
65473 periodRe: /\.$/,\r
65474 config: {\r
65475 \r
65476 appendId: true,\r
65477 \r
65478 format: null,\r
65479 \r
65480 batchActions: false,\r
65481 \r
65482 actionMethods: {\r
65483 create: 'POST',\r
65484 read: 'GET',\r
65485 update: 'PUT',\r
65486 destroy: 'DELETE'\r
65487 }\r
65488 },\r
65489 \r
65490 buildUrl: function(request) {\r
65491 var me = this,\r
65492 operation = request.getOperation(),\r
65493 records = operation.getRecords(),\r
65494 record = records ? records[0] : null,\r
65495 format = me.getFormat(),\r
65496 url = me.getUrl(request),\r
65497 id, params;\r
65498 if (record && !record.phantom) {\r
65499 id = record.getId();\r
65500 } else {\r
65501 id = operation.getId();\r
65502 }\r
65503 if (me.getAppendId() && me.isValidId(id)) {\r
65504 if (!url.match(me.slashRe)) {\r
65505 url += '/';\r
65506 }\r
65507 url += encodeURIComponent(id);\r
65508 params = request.getParams();\r
65509 if (params) {\r
65510 delete params[me.getIdParam()];\r
65511 }\r
65512 }\r
65513 if (format) {\r
65514 if (!url.match(me.periodRe)) {\r
65515 url += '.';\r
65516 }\r
65517 url += format;\r
65518 }\r
65519 request.setUrl(url);\r
65520 return me.callParent([\r
65521 request\r
65522 ]);\r
65523 },\r
65524 isValidId: function(id) {\r
65525 return id || id === 0;\r
65526 }\r
65527});\r
65528\r
65529\r
65530Ext.define('Ext.data.proxy.SessionStorage', {\r
65531 extend: Ext.data.proxy.WebStorage,\r
65532 alias: 'proxy.sessionstorage',\r
65533 alternateClassName: 'Ext.data.SessionStorageProxy',\r
65534 getStorageObject: function() {\r
65535 return window.sessionStorage;\r
65536 }\r
65537});\r
65538\r
65539\r
65540Ext.define('Ext.data.validator.Bound', {\r
65541 extend: Ext.data.validator.Validator,\r
65542 alias: 'data.validator.bound',\r
65543 type: 'bound',\r
65544 config: {\r
65545 \r
65546 min: undefined,\r
65547 \r
65548 max: undefined,\r
65549 \r
65550 emptyMessage: 'Must be present',\r
65551 \r
65552 minOnlyMessage: null,\r
65553 \r
65554 maxOnlyMessage: null,\r
65555 \r
65556 bothOnlyMessage: null\r
65557 },\r
65558 constructor: function() {\r
65559 var me = this;\r
65560 me.preventConfigure = true;\r
65561 me.callParent(arguments);\r
65562 delete me.preventConfigure;\r
65563 me.configure();\r
65564 },\r
65565 setConfig: function() {\r
65566 var me = this;\r
65567 me.preventConfigure = true;\r
65568 me.callParent(arguments);\r
65569 delete me.preventConfigure;\r
65570 me.configure();\r
65571 },\r
65572 configure: function() {\r
65573 var me = this,\r
65574 hasMin, hasMax, min, max;\r
65575 if (me.preventConfigure) {\r
65576 return;\r
65577 }\r
65578 min = me.getMin();\r
65579 max = me.getMax();\r
65580 hasMin = me.hasMin = min !== undefined;\r
65581 hasMax = me.hasMax = max !== undefined;\r
65582 if (hasMin && hasMax) {\r
65583 me._bothMsg = Ext.String.format(me.getBothMessage(), min, max);\r
65584 } else if (hasMin) {\r
65585 me._minMsg = Ext.String.format(me.getMinOnlyMessage(), min);\r
65586 } else if (hasMax) {\r
65587 me._maxMsg = Ext.String.format(me.getMaxOnlyMessage(), max);\r
65588 }\r
65589 },\r
65590 updateMin: function() {\r
65591 this.configure();\r
65592 },\r
65593 updateMax: function() {\r
65594 this.configure();\r
65595 },\r
65596 updateMinOnlyMessage: function(v) {\r
65597 this.configure();\r
65598 },\r
65599 updateMaxOnlyMessage: function() {\r
65600 this.configure();\r
65601 },\r
65602 updateBothMessage: function() {\r
65603 this.configure();\r
65604 },\r
65605 validate: function(value) {\r
65606 var me = this,\r
65607 hasMin = me.hasMin,\r
65608 hasMax = me.hasMax,\r
65609 min = me.getMin(),\r
65610 max = me.getMax(),\r
65611 msg = this.validateValue(value),\r
65612 len;\r
65613 if (msg !== true) {\r
65614 return msg;\r
65615 }\r
65616 value = me.getValue(value);\r
65617 if (hasMin && hasMax) {\r
65618 if (value < min || value > max) {\r
65619 msg = me._bothMsg;\r
65620 }\r
65621 } else if (hasMin) {\r
65622 if (value < min) {\r
65623 msg = me._minMsg;\r
65624 }\r
65625 } else if (hasMax) {\r
65626 if (value > max) {\r
65627 msg = me._maxMsg;\r
65628 }\r
65629 }\r
65630 return msg;\r
65631 },\r
65632 validateValue: function(value) {\r
65633 if (value === undefined || value === null) {\r
65634 return this.getEmptyMessage();\r
65635 }\r
65636 return true;\r
65637 },\r
65638 getValue: Ext.identityFn\r
65639});\r
65640\r
65641\r
65642Ext.define('Ext.data.validator.Format', {\r
65643 extend: Ext.data.validator.Validator,\r
65644 alias: 'data.validator.format',\r
65645 type: 'format',\r
65646 config: {\r
65647 \r
65648 message: 'Is in the wrong format',\r
65649 \r
65650 matcher: undefined\r
65651 },\r
65652
65653 constructor: function() {\r
65654 this.callParent(arguments);\r
65655 if (!this.getMatcher()) {\r
65656 Ext.raise('validator.Format must be configured with a matcher');\r
65657 }\r
65658 },\r
65659
65660 validate: function(value) {\r
65661 var matcher = this.getMatcher(),\r
65662 result = matcher && matcher.test(value);\r
65663 return result ? result : this.getMessage();\r
65664 }\r
65665});\r
65666\r
65667\r
65668Ext.define('Ext.data.validator.Email', {\r
65669 extend: Ext.data.validator.Format,\r
65670 alias: 'data.validator.email',\r
65671 type: 'email',\r
65672 config: {\r
65673 \r
65674 message: 'Is not a valid email address',\r
65675
65676
65677
65678
65679
65680
65681
65682
65683
65684
65685
65686
65687
65688
65689
65690
65691
65692
65693
65694
65695
65696
65697
65698
65699
65700
65701
65702
65703 \r
65704 matcher: /^(")?(?:[^\."])(?:(?:[\.])?(?:[\w\-!#$%&'*+\/=?\^_`{|}~]))*\1@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}$/\r
65705 }\r
65706});\r
65707\r
65708\r
65709Ext.define('Ext.data.validator.List', {\r
65710 extend: Ext.data.validator.Validator,\r
65711 alias: 'data.validator.list',\r
65712 type: 'list',\r
65713 config: {\r
65714 \r
65715 list: null\r
65716 },\r
65717 inclusion: null,\r
65718 validate: function(value) {\r
65719 var contains = Ext.Array.contains(this.getList(), value),\r
65720 inclusion = this.inclusion,\r
65721 exclusion = !inclusion,\r
65722 result;\r
65723 result = (inclusion && contains) || (exclusion && !contains);\r
65724 return result || this.getMessage();\r
65725 }\r
65726});\r
65727\r
65728\r
65729Ext.define('Ext.data.validator.Exclusion', {\r
65730 extend: Ext.data.validator.List,\r
65731 alias: 'data.validator.exclusion',\r
65732 type: 'exclusion',\r
65733 config: {\r
65734 \r
65735 message: 'Is a value that has been excluded'\r
65736 },\r
65737
65738 constructor: function() {\r
65739 this.callParent(arguments);\r
65740 if (!this.getList()) {\r
65741 Ext.raise('validator.Exclusion requires a list');\r
65742 }\r
65743 },\r
65744
65745 inclusion: false\r
65746});\r
65747\r
65748\r
65749Ext.define('Ext.data.validator.Inclusion', {\r
65750 extend: Ext.data.validator.List,\r
65751 alias: 'data.validator.inclusion',\r
65752 type: 'inclusion',\r
65753 config: {\r
65754 \r
65755 message: 'Is not in the list of acceptable values'\r
65756 },\r
65757
65758 constructor: function() {\r
65759 this.callParent(arguments);\r
65760 if (!this.getList()) {\r
65761 Ext.raise('validator.Inclusion requires a list');\r
65762 }\r
65763 },\r
65764
65765 inclusion: true\r
65766});\r
65767\r
65768\r
65769Ext.define('Ext.data.validator.Length', {\r
65770 extend: Ext.data.validator.Bound,\r
65771 alias: 'data.validator.length',\r
65772 type: 'length',\r
65773 config: {\r
65774 \r
65775 \r
65776 \r
65777 minOnlyMessage: 'Length must be at least {0}',\r
65778 \r
65779 maxOnlyMessage: 'Length must be no more than {0}',\r
65780 \r
65781 bothMessage: 'Length must be between {0} and {1}'\r
65782 },\r
65783 getValue: function(v) {\r
65784 return String(v).length;\r
65785 }\r
65786});\r
65787\r
65788\r
65789Ext.define('Ext.data.validator.Presence', {\r
65790 extend: Ext.data.validator.Validator,\r
65791 alias: 'data.validator.presence',\r
65792 type: 'presence',\r
65793 config: {\r
65794 \r
65795 message: 'Must be present',\r
65796 \r
65797 allowEmpty: false\r
65798 },\r
65799 validate: function(value) {\r
65800 var valid = !(value === undefined || value === null);\r
65801 if (valid && !this.getAllowEmpty()) {\r
65802 valid = !(value === '');\r
65803 }\r
65804 return valid ? true : this.getMessage();\r
65805 }\r
65806});\r
65807\r
65808\r
65809Ext.define('Ext.data.validator.Range', {\r
65810 extend: Ext.data.validator.Bound,\r
65811 alias: 'data.validator.range',\r
65812 type: 'range',\r
65813 config: {\r
65814 \r
65815 \r
65816 \r
65817 minOnlyMessage: 'Must be must be at least {0}',\r
65818 \r
65819 maxOnlyMessage: 'Must be no more than than {0}',\r
65820 \r
65821 bothMessage: 'Must be between {0} and {1}',\r
65822 \r
65823 nanMessage: 'Must be numeric'\r
65824 },\r
65825 validateValue: function(value) {\r
65826 var msg = this.callParent([\r
65827 value\r
65828 ]);\r
65829 if (msg === true && isNaN(value)) {\r
65830 msg = this.getNanMessage();\r
65831 }\r
65832 return msg;\r
65833 }\r
65834});\r
65835\r
65836\r
65837Ext.define('Ext.direct.Event', {\r
65838 alias: 'direct.event',\r
65839 status: true,\r
65840 \r
65841 constructor: function(config) {\r
65842 Ext.apply(this, config);\r
65843 },\r
65844 \r
65845 getName: function() {\r
65846 return this.name;\r
65847 },\r
65848 \r
65849 getData: function() {\r
65850 return this.data;\r
65851 }\r
65852});\r
65853\r
65854\r
65855Ext.define('Ext.direct.RemotingEvent', {\r
65856 extend: Ext.direct.Event,\r
65857 alias: 'direct.rpc',\r
65858 \r
65859 getTransaction: function() {\r
65860 var me = this;\r
65861 return me.transaction || Ext.direct.Manager.getTransaction(me.tid);\r
65862 }\r
65863});\r
65864\r
65865\r
65866Ext.define('Ext.direct.ExceptionEvent', {\r
65867 extend: Ext.direct.RemotingEvent,\r
65868 alias: 'direct.exception',\r
65869 status: false\r
65870});\r
65871\r
65872\r
65873Ext.define('Ext.direct.JsonProvider', {\r
65874 extend: Ext.direct.Provider,\r
65875 alias: 'direct.jsonprovider',\r
65876 \r
65877 parseResponse: function(response) {\r
65878 var text = response && response.responseText;\r
65879 if (text) {\r
65880 if (Ext.isObject(text) || Ext.isArray(text)) {\r
65881 return text;\r
65882 }\r
65883 return Ext.decode(text);\r
65884 }\r
65885 return null;\r
65886 },\r
65887 \r
65888 createEvents: function(response) {\r
65889 var me = this,\r
65890 data = null,\r
65891 events = [],\r
65892 event, i, len;\r
65893 try {\r
65894 data = me.parseResponse(response);\r
65895 } catch (e) {\r
65896 event = new Ext.direct.ExceptionEvent({\r
65897 data: e,\r
65898 xhr: response,\r
65899 code: Ext.direct.Manager.exceptions.PARSE,\r
65900 message: 'Error parsing json response: \n\n ' + e\r
65901 });\r
65902 return [\r
65903 event\r
65904 ];\r
65905 }\r
65906 if (Ext.isArray(data)) {\r
65907 for (i = 0 , len = data.length; i < len; ++i) {\r
65908 events.push(me.createEvent(data[i]));\r
65909 }\r
65910 } else if (Ext.isObject(data)) {\r
65911 events.push(me.createEvent(data));\r
65912 }\r
65913 return events;\r
65914 },\r
65915 \r
65916 createEvent: function(response) {\r
65917 if (typeof response !== 'object' || !('type' in response)) {\r
65918 return new Ext.direct.ExceptionEvent({\r
65919 data: response,\r
65920 code: Ext.direct.Manager.exceptions.DATA,\r
65921 message: 'Invalid data: event type is not specified'\r
65922 });\r
65923 }\r
65924 return Ext.create('direct.' + response.type, response);\r
65925 }\r
65926});\r
65927\r
65928
65929\r
65930Ext.define('Ext.util.TaskRunner', {\r
65931
65932 \r
65933 \r
65934 interval: 10,\r
65935 \r
65936 timerId: null,\r
65937 constructor: function(interval) {\r
65938 var me = this;\r
65939 if (typeof interval == 'number') {\r
65940 me.interval = interval;\r
65941 } else if (interval) {\r
65942 Ext.apply(me, interval);\r
65943 }\r
65944 me.tasks = [];\r
65945 me.timerFn = Ext.Function.bind(me.onTick, me);\r
65946 },\r
65947 \r
65948 newTask: function(config) {\r
65949 var task = new Ext.util.TaskRunner.Task(config);\r
65950 task.manager = this;\r
65951 return task;\r
65952 },\r
65953 \r
65954 start: function(task) {\r
65955 var me = this,\r
65956 now = Ext.Date.now();\r
65957 if (!task.pending) {\r
65958 me.tasks.push(task);\r
65959 task.pending = true;\r
65960 }\r
65961
65962 task.stopped = false;\r
65963
65964 task.taskStartTime = now;\r
65965 task.taskRunTime = task.fireOnStart !== false ? 0 : task.taskStartTime;\r
65966 task.taskRunCount = 0;\r
65967 if (!me.firing) {\r
65968 if (task.fireOnStart !== false) {\r
65969 me.startTimer(0, now);\r
65970 } else {\r
65971 me.startTimer(task.interval, now);\r
65972 }\r
65973 }\r
65974 return task;\r
65975 },\r
65976 \r
65977 stop: function(task) {\r
65978
65979
65980
65981 if (!task.stopped) {\r
65982 task.stopped = true;\r
65983 if (task.onStop) {\r
65984 task.onStop.call(task.scope || task, task);\r
65985 }\r
65986 }\r
65987 return task;\r
65988 },\r
65989 \r
65990 stopAll: function() {\r
65991
65992 Ext.each(this.tasks, this.stop, this);\r
65993 },\r
65994
65995 firing: false,\r
65996 nextExpires: 1.0E99,\r
65997 \r
65998 onTick: function() {\r
65999 var me = this,\r
66000 tasks = me.tasks,\r
66001 now = Ext.Date.now(),\r
66002 nextExpires = 1.0E99,\r
66003 len = tasks.length,\r
66004 globalEvents = Ext.GlobalEvents,\r
66005 expires, newTasks, i, task, rt, remove, fireIdleEvent;\r
66006 me.timerId = null;\r
66007 me.firing = true;\r
66008
66009
66010
66011
66012
66013 for (i = 0; i < len || i < (len = tasks.length); ++i) {\r
66014 task = tasks[i];\r
66015 if (!(remove = task.stopped)) {\r
66016 expires = task.taskRunTime + task.interval;\r
66017 if (expires <= now) {\r
66018 rt = 1;\r
66019
66020
66021 if (task.hasOwnProperty('fireIdleEvent')) {\r
66022 fireIdleEvent = task.fireIdleEvent;\r
66023 } else {\r
66024 fireIdleEvent = me.fireIdleEvent;\r
66025 }\r
66026 try {\r
66027 rt = task.run.apply(task.scope || task, task.args || [\r
66028 ++task.taskRunCount\r
66029 ]);\r
66030 } catch (taskError) {\r
66031 try {\r
66032
66033 Ext.log({\r
66034 fn: task.run,\r
66035 prefix: 'Error while running task',\r
66036 stack: taskError.stack,\r
66037 msg: taskError,\r
66038 level: 'error'\r
66039 });\r
66040
66041 if (task.onError) {\r
66042 rt = task.onError.call(task.scope || task, task, taskError);\r
66043 }\r
66044 } catch (ignore) {}\r
66045 }\r
66046 task.taskRunTime = now;\r
66047 if (rt === false || task.taskRunCount === task.repeat) {\r
66048 me.stop(task);\r
66049 remove = true;\r
66050 } else {\r
66051 remove = task.stopped;\r
66052
66053 expires = now + task.interval;\r
66054 }\r
66055 }\r
66056 if (!remove && task.duration && task.duration <= (now - task.taskStartTime)) {\r
66057 me.stop(task);\r
66058 remove = true;\r
66059 }\r
66060 }\r
66061 if (remove) {\r
66062 task.pending = false;\r
66063
66064
66065
66066
66067
66068
66069 if (!newTasks) {\r
66070 newTasks = tasks.slice(0, i);\r
66071 }\r
66072 } else
66073
66074
66075 {\r
66076 if (newTasks) {\r
66077 newTasks.push(task);\r
66078 }\r
66079
66080 if (nextExpires > expires) {\r
66081 nextExpires = expires;\r
66082 }\r
66083 }\r
66084 }\r
66085
66086 if (newTasks) {\r
66087
66088
66089 me.tasks = newTasks;\r
66090 }\r
66091 me.firing = false;\r
66092
66093 if (me.tasks.length) {\r
66094
66095
66096
66097 me.startTimer(nextExpires - now, Ext.Date.now());\r
66098 }\r
66099
66100 if (fireIdleEvent !== false && globalEvents.hasListeners.idle) {\r
66101 globalEvents.fireEvent('idle');\r
66102 }\r
66103 },\r
66104 \r
66105 startTimer: function(timeout, now) {\r
66106 var me = this,\r
66107 expires = now + timeout,\r
66108 timerId = me.timerId;\r
66109
66110
66111 if (timerId && me.nextExpires - expires > me.interval) {\r
66112 clearTimeout(timerId);\r
66113 timerId = null;\r
66114 }\r
66115 if (!timerId) {\r
66116 if (timeout < me.interval) {\r
66117 timeout = me.interval;\r
66118 }\r
66119 me.timerId = Ext.defer(me.timerFn, timeout);\r
66120 me.nextExpires = expires;\r
66121 }\r
66122 }\r
66123}, function() {\r
66124 var me = this,\r
66125 proto = me.prototype;\r
66126 \r
66127 proto.destroy = proto.stopAll;\r
66128 \r
66129 me.Task = new Ext.Class({\r
66130 isTask: true,\r
66131 \r
66132 stopped: true,\r
66133
66134 fireOnStart: false,\r
66135 constructor: function(config) {\r
66136 Ext.apply(this, config);\r
66137 },\r
66138 \r
66139 restart: function(interval) {\r
66140 if (interval !== undefined) {\r
66141 this.interval = interval;\r
66142 }\r
66143 this.manager.start(this);\r
66144 },\r
66145 \r
66146 start: function(interval) {\r
66147 if (this.stopped) {\r
66148 this.restart(interval);\r
66149 }\r
66150 },\r
66151 \r
66152 stop: function() {\r
66153 this.manager.stop(this);\r
66154 }\r
66155 });\r
66156 proto = me.Task.prototype;\r
66157 \r
66158 proto.destroy = proto.stop;\r
66159});\r
66160\r
66161\r
66162Ext.define('Ext.direct.PollingProvider', {\r
66163 extend: Ext.direct.JsonProvider,\r
66164 alias: 'direct.pollingprovider',\r
66165 type: 'polling',\r
66166 \r
66167 interval: 3000,\r
66168 \r
66169 \r
66170 \r
66171 \r
66172 \r
66173 constructor: function(config) {\r
66174 var me = this;\r
66175 me.callParent([\r
66176 config\r
66177 ]);\r
66178 me.pollTask = Ext.TaskManager.newTask({\r
66179 run: me.runPoll,\r
66180 interval: me.interval,\r
66181 scope: me\r
66182 });\r
66183 },\r
66184 destroy: function() {\r
66185 this.pollTask = null;\r
66186 this.callParent();\r
66187 },\r
66188 doConnect: function() {\r
66189 var me = this,\r
66190 url = me.url,\r
66191 pollFn = me.pollFn;\r
66192
66193
66194
66195
66196 if (pollFn && Ext.isString(pollFn)) {\r
66197
66198 var fnName = pollFn;\r
66199
66200 me.pollFn = pollFn = Ext.direct.Manager.parseMethod(pollFn);\r
66201
66202 if (!Ext.isFunction(pollFn)) {\r
66203 Ext.raise("Cannot resolve Ext Direct API method " + fnName + " for PollingProvider");\r
66204 }\r
66205 }\r
66206
66207 else if (Ext.isFunction(url)) {\r
66208
66209 Ext.log.warn('Using a function for url is deprecated, use pollFn instead.');\r
66210
66211 me.pollFn = pollFn = url;\r
66212 me.url = url = null;\r
66213 }\r
66214 if (url || pollFn) {\r
66215 me.setInterval(me.interval);\r
66216 me.pollTask.start();\r
66217 }\r
66218 },\r
66219 doDisconnect: function() {\r
66220 this.pollTask.stop();\r
66221 },\r
66222 getInterval: function() {\r
66223 return this.pollTask.interval;\r
66224 },\r
66225 setInterval: function(interval) {\r
66226 var me = this,\r
66227 pollTask = me.pollTask;\r
66228
66229 if (interval < 100) {\r
66230 Ext.raise("Attempting to configure PollProvider " + me.id + " with interval that is less than 100ms.");\r
66231 }\r
66232
66233 me.interval = pollTask.interval = interval;\r
66234 if (me.isConnected()) {\r
66235 pollTask.restart(interval);\r
66236 }\r
66237 },\r
66238 \r
66239 runPoll: function() {\r
66240 var me = this,\r
66241 url = me.url,\r
66242 pollFn = me.pollFn,\r
66243 baseParams = me.baseParams,\r
66244 args;\r
66245 if (me.fireEvent('beforepoll', me) !== false) {\r
66246 if (pollFn) {\r
66247 args = pollFn.directCfg.method.getArgs({\r
66248 params: baseParams !== undefined ? baseParams : {},\r
66249 callback: me.onPollFn,\r
66250 scope: me\r
66251 });\r
66252 pollFn.apply(window, args);\r
66253 } else {\r
66254 Ext.Ajax.request({\r
66255 url: url,\r
66256 callback: me.onData,\r
66257 scope: me,\r
66258 params: baseParams\r
66259 });\r
66260 }\r
66261 me.fireEvent('poll', me);\r
66262 }\r
66263 },\r
66264 \r
66265 onData: function(opt, success, response) {\r
66266 var me = this,\r
66267 i, len, events;\r
66268 if (success) {\r
66269 events = me.createEvents(response);\r
66270 for (i = 0 , len = events.length; i < len; ++i) {\r
66271 me.fireEvent('data', me, events[i]);\r
66272 }\r
66273 } else {\r
66274 events = new Ext.direct.ExceptionEvent({\r
66275 data: null,\r
66276 code: Ext.direct.Manager.exceptions.TRANSPORT,\r
66277 message: 'Unable to connect to the server.',\r
66278 xhr: response\r
66279 });\r
66280 me.fireEvent('data', me, events);\r
66281 }\r
66282 },\r
66283 \r
66284 onPollFn: function(result, event, success, options) {\r
66285 this.onData(null, success, {\r
66286 responseText: result\r
66287 });\r
66288 },\r
66289 inheritableStatics: {\r
66290 \r
66291 checkConfig: function(config) {\r
66292
66293 return config && config.type === 'polling' && (config.url || config.pollFn);\r
66294 }\r
66295 }\r
66296});\r
66297\r
66298\r
66299Ext.define('Ext.direct.RemotingMethod', {\r
66300 constructor: function(config) {\r
66301 var me = this,\r
66302 params = config.params,\r
66303 len = config.len,\r
66304 metadataCfg = config.metadata,\r
66305 metadata = {},\r
66306 name, pLen, p, param;\r
66307 me.name = config.name;\r
66308 me.disableBatching = config.batched != null ? !config.batched : false;\r
66309 if (config.formHandler) {\r
66310 me.formHandler = config.formHandler;\r
66311 } else if (Ext.isNumeric(len)) {\r
66312
66313 me.len = len;\r
66314 me.ordered = true;\r
66315 } else {\r
66316 \r
66317 me.named = true;\r
66318 me.strict = config.strict !== undefined ? config.strict : true;\r
66319 me.params = {};\r
66320
66321
66322 pLen = params && params.length;\r
66323 for (p = 0; p < pLen; p++) {\r
66324 param = params[p];\r
66325 name = Ext.isObject(param) ? param.name : param;\r
66326 me.params[name] = true;\r
66327 }\r
66328 }\r
66329 if (metadataCfg) {\r
66330 params = metadataCfg.params;\r
66331 len = metadataCfg.len;\r
66332 if (Ext.isNumeric(len)) {\r
66333
66334 if (len === 0) {\r
66335 Ext.raise('metadata.len cannot be 0 ' + 'for Ext Direct method ' + me.name);\r
66336 }\r
66337
66338 metadata.ordered = true;\r
66339 metadata.len = len;\r
66340 } else if (Ext.isArray(params)) {\r
66341 metadata.named = true;\r
66342 metadata.params = {};\r
66343 for (p = 0 , pLen = params.length; p < pLen; p++) {\r
66344 param = params[p];\r
66345 metadata.params[param] = true;\r
66346 }\r
66347 metadata.strict = metadataCfg.strict !== undefined ? metadataCfg.strict : true;\r
66348 } else
66349 {\r
66350 Ext.raise('metadata is neither named nor ordered ' + 'for Ext Direct method ' + me.name);\r
66351 }\r
66352
66353 me.metadata = metadata;\r
66354 }\r
66355 },\r
66356 \r
66357 getArgs: function(config) {\r
66358 var me = this,\r
66359 params = config.params,\r
66360 paramOrder = config.paramOrder,\r
66361 paramsAsHash = config.paramsAsHash,\r
66362 metadata = config.metadata,\r
66363 options = config.options,\r
66364 args = [],\r
66365 i, len;\r
66366 if (me.ordered) {\r
66367 if (me.len > 0) {\r
66368
66369 if (paramOrder) {\r
66370 for (i = 0 , len = paramOrder.length; i < len; i++) {\r
66371 args.push(params[paramOrder[i]]);\r
66372 }\r
66373 } else if (paramsAsHash) {\r
66374
66375 args.push(params);\r
66376 }\r
66377 }\r
66378 } else {\r
66379 args.push(params);\r
66380 }\r
66381 args.push(config.callback, config.scope || window);\r
66382 if (options || metadata) {\r
66383 options = Ext.apply({}, options);\r
66384 if (metadata) {\r
66385
66386
66387 options.metadata = metadata;\r
66388 }\r
66389 args.push(options);\r
66390 }\r
66391 return args;\r
66392 },\r
66393 \r
66394 getCallData: function(args) {\r
66395 var me = this,\r
66396 data = null,\r
66397 len = me.len,\r
66398 params = me.params,\r
66399 strict = me.strict,\r
66400 form, callback, scope, name, options, metadata;\r
66401
66402
66403
66404 if (me.ordered) {\r
66405 callback = args[len];\r
66406 scope = args[len + 1];\r
66407 options = args[len + 2];\r
66408 if (len !== 0) {\r
66409 data = args.slice(0, len);\r
66410 }\r
66411 } else if (me.formHandler) {\r
66412 form = args[0];\r
66413 callback = args[1];\r
66414 scope = args[2];\r
66415 options = args[3];\r
66416 } else {\r
66417 data = Ext.apply({}, args[0]);\r
66418 callback = args[1];\r
66419 scope = args[2];\r
66420 options = args[3];\r
66421
66422 if (strict) {\r
66423 for (name in data) {\r
66424 if (data.hasOwnProperty(name) && !params[name]) {\r
66425 delete data[name];\r
66426 }\r
66427 }\r
66428 }\r
66429 }\r
66430 if (me.metadata && options && options.metadata) {\r
66431 if (me.metadata.ordered) {\r
66432
66433 if (!Ext.isArray(options.metadata)) {\r
66434 Ext.raise('options.metadata is not an Array ' + 'for Ext Direct method ' + me.name);\r
66435 } else if (options.metadata.length < me.metadata.len) {\r
66436 Ext.raise('Not enough parameters in options.metadata ' + 'for Ext Direct method ' + me.name);\r
66437 }\r
66438
66439 metadata = options.metadata.slice(0, me.metadata.len);\r
66440 } else {\r
66441
66442 if (!Ext.isObject(options.metadata)) {\r
66443 Ext.raise('options.metadata is not an Object ' + 'for Ext Direct method ' + me.name);\r
66444 }\r
66445
66446 metadata = Ext.apply({}, options.metadata);\r
66447 if (me.metadata.strict) {\r
66448 for (name in metadata) {\r
66449 if (metadata.hasOwnProperty(name) && !me.metadata.params[name]) {\r
66450 delete metadata[name];\r
66451 }\r
66452 }\r
66453 }\r
66454
66455 for (name in me.metadata.params) {\r
66456 if (!metadata.hasOwnProperty(name)) {\r
66457 Ext.raise('Named parameter ' + name + ' is missing ' + 'in options.metadata for Ext Direct method ' + me.name);\r
66458 }\r
66459 }\r
66460 }\r
66461
66462 delete options.metadata;\r
66463 }\r
66464 return {\r
66465 form: form,\r
66466 data: data,\r
66467 metadata: metadata,\r
66468 callback: callback,\r
66469 scope: scope,\r
66470 options: options\r
66471 };\r
66472 }\r
66473});\r
66474\r
66475\r
66476Ext.define('Ext.direct.Transaction', {\r
66477 alias: 'direct.transaction',\r
66478 statics: {\r
66479 TRANSACTION_ID: 0\r
66480 },\r
66481 \r
66482 \r
66483 constructor: function(config) {\r
66484 var me = this;\r
66485 Ext.apply(me, config);\r
66486 me.id = me.tid = ++me.self.TRANSACTION_ID;\r
66487 me.retryCount = 0;\r
66488 },\r
66489 send: function() {\r
66490 var me = this;\r
66491 me.provider.queueTransaction(me);\r
66492 },\r
66493 retry: function() {\r
66494 var me = this;\r
66495 me.retryCount++;\r
66496 me.send();\r
66497 },\r
66498 getProvider: function() {\r
66499 return this.provider;\r
66500 }\r
66501});\r
66502\r
66503\r
66504Ext.define('Ext.direct.RemotingProvider', {\r
66505 extend: Ext.direct.JsonProvider,\r
66506 alias: 'direct.remotingprovider',\r
66507 type: 'remoting',\r
66508 \r
66509 \r
66510 \r
66511 \r
66512 \r
66513 \r
66514 enableBuffer: 10,\r
66515 \r
66516 bufferLimit: Number.MAX_VALUE,\r
66517 \r
66518 maxRetries: 1,\r
66519 \r
66520 \r
66521 \r
66522 \r
66523 constructor: function(config) {\r
66524 var me = this;\r
66525 me.callParent(arguments);\r
66526 me.namespace = (Ext.isString(me.namespace)) ? Ext.ns(me.namespace) : me.namespace || Ext.global;\r
66527 me.transactions = new Ext.util.MixedCollection();\r
66528 me.callBuffer = [];\r
66529 },\r
66530 doConnect: function() {\r
66531 if (!this.apiCreated) {\r
66532 this.initAPI();\r
66533 this.apiCreated = true;\r
66534 }\r
66535 },\r
66536 \r
66537 getNamespace: function(root, action) {\r
66538 var parts, ns, i, len;\r
66539 root = root || Ext.global;\r
66540 parts = action.toString().split('.');\r
66541 for (i = 0 , len = parts.length; i < len; i++) {\r
66542 ns = parts[i];\r
66543 root = root[ns];\r
66544 if (typeof root === 'undefined') {\r
66545 return root;\r
66546 }\r
66547 }\r
66548 return root;\r
66549 },\r
66550 \r
66551 createNamespaces: function(root, action) {\r
66552 var parts, ns, i, len;\r
66553 root = root || Ext.global;\r
66554 parts = action.toString().split('.');\r
66555 for (i = 0 , len = parts.length; i < len; i++) {\r
66556 ns = parts[i];\r
66557 root[ns] = root[ns] || {};\r
66558 root = root[ns];\r
66559 }\r
66560 return root;\r
66561 },\r
66562 \r
66563 initAPI: function() {\r
66564 var me = this,\r
66565 actions = me.actions,\r
66566 namespace = me.namespace,\r
66567 Manager = Ext.direct.Manager,\r
66568 action, cls, methods, i, len, method, handler;\r
66569 for (action in actions) {\r
66570 if (actions.hasOwnProperty(action)) {\r
66571 if (me.disableNestedActions) {\r
66572 cls = namespace[action];\r
66573 if (!cls) {\r
66574 cls = namespace[action] = {};\r
66575 }\r
66576 } else {\r
66577 cls = me.getNamespace(namespace, action);\r
66578 if (!cls) {\r
66579 cls = me.createNamespaces(namespace, action);\r
66580 }\r
66581 }\r
66582 methods = actions[action];\r
66583 for (i = 0 , len = methods.length; i < len; ++i) {\r
66584 method = new Ext.direct.RemotingMethod(methods[i]);\r
66585 cls[method.name] = handler = me.createHandler(action, method);\r
66586 Manager.registerMethod(handler.$name, handler);\r
66587 }\r
66588 }\r
66589 }\r
66590 },\r
66591 \r
66592 createHandler: function(action, method) {\r
66593 var me = this,\r
66594 slice = Array.prototype.slice,\r
66595 handler;\r
66596 if (!method.formHandler) {\r
66597 handler = function() {\r
66598 me.configureRequest(action, method, slice.call(arguments, 0));\r
66599 };\r
66600 } else {\r
66601 handler = function() {\r
66602 me.configureFormRequest(action, method, slice.call(arguments, 0));\r
66603 };\r
66604 }\r
66605 handler.name = handler.$name = action + '.' + method.name;\r
66606 handler.$directFn = true;\r
66607 handler.directCfg = handler.$directCfg = {\r
66608 action: action,\r
66609 method: method\r
66610 };\r
66611 return handler;\r
66612 },\r
66613 \r
66614 connect: function() {\r
66615 var me = this;\r
66616
66617 if (!me.url) {\r
66618 Ext.raise('Error initializing RemotingProvider "' + me.id + '", no url configured.');\r
66619 }\r
66620
66621 me.callParent();\r
66622 },\r
66623 \r
66624 runCallback: function(transaction, event) {\r
66625 var success = !!event.status,\r
66626 funcName = success ? 'success' : 'failure',\r
66627 callback, options, result;\r
66628 if (transaction && transaction.callback) {\r
66629 callback = transaction.callback;\r
66630 options = transaction.callbackOptions;\r
66631 result = typeof event.result !== 'undefined' ? event.result : event.data;\r
66632 if (Ext.isFunction(callback)) {\r
66633 callback(result, event, success, options);\r
66634 } else {\r
66635 Ext.callback(callback[funcName], callback.scope, [\r
66636 result,\r
66637 event,\r
66638 success,\r
66639 options\r
66640 ]);\r
66641 Ext.callback(callback.callback, callback.scope, [\r
66642 result,\r
66643 event,\r
66644 success,\r
66645 options\r
66646 ]);\r
66647 }\r
66648 }\r
66649 },\r
66650 \r
66651 onData: function(options, success, response) {\r
66652 var me = this,\r
66653 i, len, events, event, transaction, transactions;\r
66654 if (success) {\r
66655 events = me.createEvents(response);\r
66656 for (i = 0 , len = events.length; i < len; ++i) {\r
66657 event = events[i];\r
66658 transaction = me.getTransaction(event);\r
66659 me.fireEvent('data', me, event);\r
66660 if (transaction && me.fireEvent('beforecallback', me, event, transaction) !== false) {\r
66661 me.runCallback(transaction, event, true);\r
66662 }\r
66663 Ext.direct.Manager.removeTransaction(transaction);\r
66664 }\r
66665 } else {\r
66666 transactions = [].concat(options.transaction);\r
66667 for (i = 0 , len = transactions.length; i < len; ++i) {\r
66668 transaction = me.getTransaction(transactions[i]);\r
66669 if (transaction && transaction.retryCount < me.maxRetries) {\r
66670 transaction.retry();\r
66671 } else {\r
66672 event = new Ext.direct.ExceptionEvent({\r
66673 data: null,\r
66674 transaction: transaction,\r
66675 code: Ext.direct.Manager.exceptions.TRANSPORT,\r
66676 message: 'Unable to connect to the server.',\r
66677 xhr: response\r
66678 });\r
66679 me.fireEvent('data', me, event);\r
66680 if (transaction && me.fireEvent('beforecallback', me, event, transaction) !== false) {\r
66681 me.runCallback(transaction, event, false);\r
66682 }\r
66683 Ext.direct.Manager.removeTransaction(transaction);\r
66684 }\r
66685 }\r
66686 }\r
66687 },\r
66688 \r
66689 getTransaction: function(options) {\r
66690 return options && options.tid ? Ext.direct.Manager.getTransaction(options.tid) : null;\r
66691 },\r
66692 \r
66693 getPayload: function(transaction) {\r
66694 var result = {\r
66695 action: transaction.action,\r
66696 method: transaction.method,\r
66697 data: transaction.data,\r
66698 type: 'rpc',\r
66699 tid: transaction.id\r
66700 };\r
66701 if (transaction.metadata) {\r
66702 result.metadata = transaction.metadata;\r
66703 }\r
66704 return result;\r
66705 },\r
66706 \r
66707 sendRequest: function(transaction) {\r
66708 var me = this,\r
66709 request, callData, params,\r
66710 enableUrlEncode = me.enableUrlEncode,\r
66711 payload, i, len;\r
66712 request = {\r
66713 url: me.url,\r
66714 callback: me.onData,\r
66715 scope: me,\r
66716 transaction: transaction,\r
66717 timeout: me.timeout\r
66718 };\r
66719
66720 if (transaction.timeout) {\r
66721 request.timeout = transaction.timeout;\r
66722 }\r
66723 if (Ext.isArray(transaction)) {\r
66724 callData = [];\r
66725 for (i = 0 , len = transaction.length; i < len; ++i) {\r
66726 payload = me.getPayload(transaction[i]);\r
66727 callData.push(payload);\r
66728 }\r
66729 } else {\r
66730 callData = me.getPayload(transaction);\r
66731 }\r
66732 if (enableUrlEncode) {\r
66733 params = {};\r
66734 params[Ext.isString(enableUrlEncode) ? enableUrlEncode : 'data'] = Ext.encode(callData);\r
66735 request.params = params;\r
66736 } else {\r
66737 request.jsonData = callData;\r
66738 }\r
66739 Ext.Ajax.request(request);\r
66740 },\r
66741 \r
66742 queueTransaction: function(transaction) {\r
66743 var me = this,\r
66744 callBuffer = me.callBuffer,\r
66745 enableBuffer = me.enableBuffer;\r
66746 if (transaction.form) {\r
66747 me.sendFormRequest(transaction);\r
66748 return;\r
66749 }\r
66750 if (enableBuffer === false || transaction.disableBatching || typeof transaction.timeout !== 'undefined') {\r
66751 me.sendRequest(transaction);\r
66752 return;\r
66753 }\r
66754 callBuffer.push(transaction);\r
66755 if (enableBuffer && callBuffer.length < me.bufferLimit) {\r
66756 if (!me.callTask) {\r
66757 me.callTask = new Ext.util.DelayedTask(me.combineAndSend, me);\r
66758 }\r
66759 me.callTask.delay(Ext.isNumber(enableBuffer) ? enableBuffer : 10);\r
66760 } else {\r
66761 me.combineAndSend();\r
66762 }\r
66763 },\r
66764 \r
66765 combineAndSend: function() {\r
66766 var me = this,\r
66767 buffer = me.callBuffer,\r
66768 len = buffer.length;\r
66769 if (len > 0) {\r
66770 me.sendRequest(len === 1 ? buffer[0] : buffer);\r
66771 me.callBuffer = [];\r
66772 }\r
66773 },\r
66774 \r
66775 configureTransaction: function(action, method, args, isForm) {\r
66776 var data, cb, scope, options, params;\r
66777 data = method.getCallData(args);\r
66778 cb = data.callback;\r
66779 scope = data.scope;\r
66780 options = data.options;\r
66781
66782 if (cb && !Ext.isFunction(cb)) {\r
66783 Ext.raise("Callback argument is not a function " + "for Ext Direct method " + action + "." + method.name);\r
66784 }\r
66785
66786
66787
66788 cb = cb && scope ? Ext.Function.bind(cb, scope) : cb;\r
66789 params = Ext.apply({}, {\r
66790 provider: this,\r
66791 args: args,\r
66792 action: action,\r
66793 method: method.name,\r
66794 form: data.form,\r
66795 data: data.data,\r
66796 metadata: data.metadata,\r
66797 callbackOptions: options,\r
66798 callback: cb,\r
66799 isForm: isForm,\r
66800 disableBatching: method.disableBatching\r
66801 });\r
66802 if (options && options.timeout != null) {\r
66803 params.timeout = options.timeout;\r
66804 }\r
66805 return new Ext.direct.Transaction(params);\r
66806 },\r
66807 \r
66808 configureRequest: function(action, method, args) {\r
66809 var me = this,\r
66810 transaction;\r
66811 transaction = me.configureTransaction(action, method, args);\r
66812 if (me.fireEvent('beforecall', me, transaction, method) !== false) {\r
66813 Ext.direct.Manager.addTransaction(transaction);\r
66814 me.queueTransaction(transaction);\r
66815 me.fireEvent('call', me, transaction, method);\r
66816 }\r
66817 },\r
66818 \r
66819 configureFormRequest: function(action, method, args) {\r
66820 var me = this,\r
66821 transaction, form, isUpload, postParams;\r
66822 transaction = me.configureTransaction(action, method, args, true);\r
66823 if (me.fireEvent('beforecall', me, transaction, method) !== false) {\r
66824 Ext.direct.Manager.addTransaction(transaction);\r
66825 form = transaction.form;\r
66826 isUpload = String(form.getAttribute("enctype")).toLowerCase() === 'multipart/form-data';\r
66827 postParams = {\r
66828 extTID: transaction.id,\r
66829 extAction: action,\r
66830 extMethod: method.name,\r
66831 extType: 'rpc',\r
66832 extUpload: String(isUpload)\r
66833 };\r
66834 if (transaction.metadata) {\r
66835 postParams.extMetadata = Ext.JSON.encode(transaction.metadata);\r
66836 }\r
66837 Ext.apply(transaction, {\r
66838 form: form,\r
66839 isUpload: isUpload,\r
66840 params: postParams\r
66841 });\r
66842 me.sendFormRequest(transaction);\r
66843 me.fireEvent('call', me, transaction, method);\r
66844 }\r
66845 },\r
66846 \r
66847 sendFormRequest: function(transaction) {\r
66848 var me = this;\r
66849 Ext.Ajax.request({\r
66850 url: me.url,\r
66851 params: transaction.params,\r
66852 callback: me.onData,\r
66853 scope: me,\r
66854 form: transaction.form,\r
66855 isUpload: transaction.isUpload,\r
66856 transaction: transaction\r
66857 });\r
66858 },\r
66859 inheritableStatics: {\r
66860 \r
66861 checkConfig: function(config) {\r
66862
66863
66864 return config && config.type === 'remoting' && config.url && Ext.isArray(config.actions);\r
66865 }\r
66866 }\r
66867});\r
66868\r
66869\r
66870Ext.define('Ext.dom.Fly', {\r
66871 extend: Ext.dom.Element,\r
66872 alternateClassName: 'Ext.dom.Element.Fly',\r
66873
66874
66875
66876
66877 validNodeTypes: {\r
66878 1: 1,\r
66879
66880 9: 1,\r
66881
66882 11: 1\r
66883 },\r
66884
66885 \r
66886 isFly: true,\r
66887 constructor: function(dom) {\r
66888 this.dom = dom;\r
66889
66890
66891
66892 this.el = this;\r
66893 },\r
66894 attach: function(dom) {\r
66895 var me = this;\r
66896 if (!dom) {\r
66897 return me.detach();\r
66898 }\r
66899 me.dom = dom;\r
66900
66901
66902 if (!Ext.cache[dom.id]) {\r
66903 me.getData().isSynchronized = false;\r
66904 }\r
66905 return me;\r
66906 },\r
66907 detach: function() {\r
66908 this.dom = null;\r
66909 },\r
66910 addListener:
66911 function() {\r
66912 Ext.raise("Cannot use addListener() on Ext.dom.Fly instances. " + "Please use Ext.get() to retrieve an Ext.dom.Element instance instead.");\r
66913 } ||
66914 null,\r
66915 removeListener:
66916 function() {\r
66917 Ext.raise("Cannot use removeListener() on Ext.dom.Fly instances. " + "Please use Ext.get() to retrieve an Ext.dom.Element instance instead.");\r
66918 } ||
66919 null\r
66920}, function(Fly) {\r
66921 var flyweights = {};\r
66922 \r
66923 Fly.cache = flyweights;\r
66924 \r
66925 Ext.fly = function(dom, named) {\r
66926 var fly = null,\r
66927 fn = Ext.fly,\r
66928 nodeType, data;\r
66929
66930 named = named || (fn.caller && fn.caller.$name) || '_global';\r
66931 dom = Ext.getDom(dom);\r
66932 if (dom) {\r
66933 nodeType = dom.nodeType;\r
66934
66935
66936
66937
66938
66939
66940 if (Fly.prototype.validNodeTypes[nodeType] || (!nodeType && (dom.window == dom))) {\r
66941 fly = Ext.cache[dom.id];\r
66942
66943 if (!fly || fly.dom !== dom) {\r
66944 fly = flyweights[named] || (flyweights[named] = new Fly());\r
66945 fly.dom = dom;\r
66946 data = fly.getData(true);\r
66947 if (data) {\r
66948 data.isSynchronized = false;\r
66949 }\r
66950 }\r
66951 }\r
66952 }\r
66953 return fly;\r
66954 };\r
66955});\r
66956\r
66957\r
66958Ext.define('Ext.dom.CompositeElementLite', {\r
66959 alternateClassName: [\r
66960 'Ext.CompositeElementLite'\r
66961 ],\r
66962 \r
66963 isComposite: true,\r
66964 \r
66965 isLite: true,\r
66966
66967
66968
66969 \r
66970 \r
66971 \r
66972 \r
66973 statics: {\r
66974
66975
66976
66977
66978 importElementMethods: function() {\r
66979 var Element = Ext.dom.Element,\r
66980 prototype = this.prototype;\r
66981 Ext.Object.each(Element.prototype, function(name, member) {\r
66982 if (typeof member === 'function' && !prototype[name]) {\r
66983 prototype[name] = function() {\r
66984 return this.invoke(name, arguments);\r
66985 };\r
66986 }\r
66987 });\r
66988 }\r
66989 },\r
66990 constructor: function(elements, \r
66991 skipValidation) {\r
66992 \r
66993 if (skipValidation) {\r
66994
66995
66996
66997
66998 this.elements = elements || [];\r
66999 } else {\r
67000 this.elements = [];\r
67001 this.add(elements);\r
67002 }\r
67003 },\r
67004 \r
67005 getElement: function(el) {\r
67006
67007 var fly = this._fly || (this._fly = new Ext.dom.Fly());\r
67008 return fly.attach(el);\r
67009 },\r
67010 \r
67011 transformElement: function(el) {\r
67012 return Ext.getDom(el);\r
67013 },\r
67014 \r
67015 getCount: function() {\r
67016 return this.elements.length;\r
67017 },\r
67018 \r
67019 add: function(els, root) {\r
67020 var elements = this.elements,\r
67021 i, ln;\r
67022 if (!els) {\r
67023 return this;\r
67024 }\r
67025 if (typeof els == "string") {\r
67026 els = Ext.fly(root || document).query(els);\r
67027 } else if (els.isComposite) {\r
67028 els = els.elements;\r
67029 } else if (!Ext.isIterable(els)) {\r
67030 els = [\r
67031 els\r
67032 ];\r
67033 }\r
67034 for (i = 0 , ln = els.length; i < ln; ++i) {\r
67035 elements.push(this.transformElement(els[i]));\r
67036 }\r
67037 return this;\r
67038 },\r
67039 invoke: function(fn, args) {\r
67040 var me = this,\r
67041 elements = me.elements,\r
67042 ln = elements.length,\r
67043 prototype, element, i;\r
67044 if (i !== 0) {\r
67045
67046
67047 prototype = (me.isLite ? Ext.dom.Fly : Ext.dom.Element).prototype;\r
67048 for (i = 0; i < ln; i++) {\r
67049 element = elements[i];\r
67050 if (element) {\r
67051 prototype[fn].apply(me.getElement(element), args);\r
67052 }\r
67053 }\r
67054 }\r
67055 return me;\r
67056 },\r
67057 \r
67058 item: function(index) {\r
67059 var el = this.elements[index],\r
67060 out = null;\r
67061 if (el) {\r
67062 out = this.getElement(el);\r
67063 }\r
67064 return out;\r
67065 },\r
67066 \r
67067 slice: function(start, end) {\r
67068 return Ext.Array.slice(this.elements, start, end);\r
67069 },\r
67070 \r
67071 each: function(fn, scope) {\r
67072 var me = this,\r
67073 els = me.elements,\r
67074 len = els.length,\r
67075 i, e;\r
67076 for (i = 0; i < len; i++) {\r
67077 e = els[i];\r
67078 if (e) {\r
67079 e = this.getElement(e);\r
67080 if (fn.call(scope || e, e, me, i) === false) {\r
67081 break;\r
67082 }\r
67083 }\r
67084 }\r
67085 return me;\r
67086 },\r
67087 \r
67088 fill: function(els) {\r
67089 var me = this;\r
67090 me.elements = [];\r
67091 me.add(els);\r
67092 return me;\r
67093 },\r
67094 insert: function(index, nodes) {\r
67095 Ext.Array.insert(this.elements, index, nodes);\r
67096 },\r
67097 \r
67098 filter: function(selector) {\r
67099 var me = this,\r
67100 els = me.elements,\r
67101 len = els.length,\r
67102 out = [],\r
67103 i = 0,\r
67104 isFunc = typeof selector == 'function',\r
67105 add, el;\r
67106 for (; i < len; i++) {\r
67107 el = els[i];\r
67108 add = false;\r
67109 if (el) {\r
67110 el = me.getElement(el);\r
67111 if (isFunc) {\r
67112 add = selector.call(el, el, me, i) !== false;\r
67113 } else {\r
67114 add = el.is(selector);\r
67115 }\r
67116 if (add) {\r
67117 out.push(me.transformElement(el));\r
67118 }\r
67119 }\r
67120 }\r
67121 me.elements = out;\r
67122 return me;\r
67123 },\r
67124 \r
67125 indexOf: function(el) {\r
67126 return Ext.Array.indexOf(this.elements, this.transformElement(el));\r
67127 },\r
67128 \r
67129 replaceElement: function(el, replacement, domReplace) {\r
67130 var index = !isNaN(el) ? el : this.indexOf(el),\r
67131 d;\r
67132 if (index > -1) {\r
67133 replacement = Ext.getDom(replacement);\r
67134 if (domReplace) {\r
67135 d = this.elements[index];\r
67136 d.parentNode.insertBefore(replacement, d);\r
67137 Ext.removeNode(d);\r
67138 }\r
67139 Ext.Array.splice(this.elements, index, 1, replacement);\r
67140 }\r
67141 return this;\r
67142 },\r
67143 \r
67144 clear: function(removeDom) {\r
67145 var me = this,\r
67146 els = me.elements,\r
67147 i = els.length - 1;\r
67148 if (removeDom) {\r
67149 for (; i >= 0; i--) {\r
67150 Ext.removeNode(els[i]);\r
67151 }\r
67152 }\r
67153 this.elements = [];\r
67154 },\r
67155 addElements: function(els, root) {\r
67156 if (!els) {\r
67157 return this;\r
67158 }\r
67159 if (typeof els === "string") {\r
67160 els = Ext.dom.Element.selectorFunction(els, root);\r
67161 }\r
67162 var yels = this.elements,\r
67163 eLen = els.length,\r
67164 e;\r
67165 for (e = 0; e < eLen; e++) {\r
67166 yels.push(Ext.get(els[e]));\r
67167 }\r
67168 return this;\r
67169 },\r
67170 \r
67171 first: function() {\r
67172 return this.item(0);\r
67173 },\r
67174 \r
67175 last: function() {\r
67176 return this.item(this.getCount() - 1);\r
67177 },\r
67178 \r
67179 contains: function(el) {\r
67180 return this.indexOf(el) != -1;\r
67181 },\r
67182 \r
67183 removeElement: function(keys, removeDom) {\r
67184 keys = [].concat(keys);\r
67185 var me = this,\r
67186 elements = me.elements,\r
67187 kLen = keys.length,\r
67188 val, el, k;\r
67189 for (k = 0; k < kLen; k++) {\r
67190 val = keys[k];\r
67191 if ((el = (elements[val] || elements[val = me.indexOf(val)]))) {\r
67192 if (removeDom) {\r
67193 if (el.dom) {\r
67194 el.destroy();\r
67195 } else {\r
67196 Ext.removeNode(el);\r
67197 }\r
67198 }\r
67199 Ext.Array.erase(elements, val, 1);\r
67200 }\r
67201 }\r
67202 return me;\r
67203 },\r
67204 destroy: function() {\r
67205
67206 return this.invoke('destroy', arguments);\r
67207 this.callParent();\r
67208 }\r
67209}, function(CompositeElementLite) {\r
67210 var prototype = CompositeElementLite.prototype;\r
67211 CompositeElementLite.importElementMethods();\r
67212 prototype.on = prototype.addListener;\r
67213});\r
67214\r
67215\r
67216Ext.define('Ext.dom.CompositeElement', {\r
67217 alternateClassName: 'Ext.CompositeElement',\r
67218 extend: Ext.dom.CompositeElementLite,\r
67219 isLite: false,\r
67220 \r
67221 getElement: function(el) {\r
67222
67223 return el;\r
67224 },\r
67225 \r
67226 transformElement: function(el) {\r
67227 return Ext.get(el);\r
67228 }\r
67229});\r
67230\r
67231\r
67232Ext.define('Ext.dom.GarbageCollector', {\r
67233 singleton: true,\r
67234 \r
67235 interval: 30000,\r
67236 constructor: function() {\r
67237 var me = this;\r
67238 me.collect = Ext.Function.bind(me.collect, me);\r
67239 me.lastTime = Ext.now();\r
67240 me.resume();\r
67241 },\r
67242 \r
67243 collect: function() {\r
67244 var me = this,\r
67245 cache = Ext.cache,\r
67246 eid, dom, el, t, isGarbage, tagName;\r
67247
67248 var collectedIds = [];\r
67249
67250 for (eid in cache) {\r
67251 if (!cache.hasOwnProperty(eid)) {\r
67252 \r
67253 continue;\r
67254 }\r
67255 el = cache[eid];\r
67256 if (el.skipGarbageCollection) {\r
67257 \r
67258 continue;\r
67259 }\r
67260 dom = el.dom;\r
67261
67262
67263 if (!dom) {\r
67264 Ext.raise('Missing DOM node in element garbage collection: ' + eid);\r
67265 }\r
67266
67267 try {\r
67268
67269
67270
67271
67272
67273 isGarbage = Ext.isGarbage(dom);\r
67274 } catch (e) {\r
67275
67276
67277
67278
67279 delete cache[eid];\r
67280
67281 collectedIds.push('#' + el.id);\r
67282
67283 \r
67284 continue;\r
67285 }\r
67286 if (isGarbage) {\r
67287 if (el && el.dom) {\r
67288
67289 tagName = el.dom.tagName;\r
67290
67291 el.collect();\r
67292
67293 collectedIds.push((tagName ? tagName : '') + '#' + el.id);\r
67294 }\r
67295 }\r
67296 }\r
67297
67298
67299
67300 if (Ext.isIE9m) {\r
67301 t = {};\r
67302 for (eid in cache) {\r
67303 if (cache.hasOwnProperty(eid)) {\r
67304 t[eid] = cache[eid];\r
67305 }\r
67306 }\r
67307 Ext.cache = Ext.dom.Element.cache = t;\r
67308 }\r
67309
67310 me.lastTime = Ext.now();\r
67311
67312 return collectedIds;\r
67313 },\r
67314
67315 \r
67316 pause: function() {\r
67317 clearTimeout(this.timerId);\r
67318 },\r
67319 \r
67320 resume: function() {\r
67321 var me = this,\r
67322 lastTime = me.lastTime;\r
67323 if (Ext.enableGarbageCollector && (Ext.now() - lastTime > me.interval)) {\r
67324 me.collect();\r
67325 }\r
67326 me.timerId = Ext.interval(me.collect, me.interval);\r
67327 }\r
67328});\r
67329\r
67330\r
67331Ext.define('Ext.event.gesture.Recognizer', {\r
67332 mixins: [\r
67333 Ext.mixin.Identifiable\r
67334 ],\r
67335 \r
67336 priority: 0,\r
67337 handledEvents: [],\r
67338 config: {\r
67339 onRecognized: Ext.emptyFn,\r
67340 callbackScope: null\r
67341 },\r
67342 constructor: function(config) {\r
67343 this.initConfig(config);\r
67344 Ext.event.publisher.Gesture.instance.registerRecognizer(this);\r
67345 },\r
67346 onStart: Ext.emptyFn,\r
67347 onEnd: Ext.emptyFn,\r
67348 onTouchStart: Ext.emptyFn,\r
67349 onTouchMove: Ext.emptyFn,\r
67350 onTouchEnd: Ext.emptyFn,\r
67351 onTouchCancel: Ext.emptyFn,\r
67352 fail: function() {\r
67353 return false;\r
67354 },\r
67355 fire: function() {\r
67356 this.getOnRecognized().apply(this.getCallbackScope(), arguments);\r
67357 },\r
67358 reset: Ext.emptyFn,\r
67359 debugHooks: {\r
67360 $enabled: false,\r
67361
67362 fail: function(msg) {\r
67363 Ext.log.info(this.$className + ' Gesture Failed: ' + msg);\r
67364 return false;\r
67365 }\r
67366 }\r
67367});\r
67368\r
67369\r
67370Ext.define('Ext.event.gesture.SingleTouch', {\r
67371 extend: Ext.event.gesture.Recognizer,\r
67372 inheritableStatics: {\r
67373 \r
67374 NOT_SINGLE_TOUCH: "Not Single Touch",\r
67375 \r
67376 TOUCH_MOVED: "Touch Moved",\r
67377 \r
67378 EVENT_CANCELED: "Event Canceled"\r
67379 },\r
67380 onTouchStart: function(e) {\r
67381 if (e.touches.length > 1) {\r
67382 return this.fail(this.self.NOT_SINGLE_TOUCH);\r
67383 }\r
67384 },\r
67385 onTouchCancel: function() {\r
67386 return false;\r
67387 }\r
67388});\r
67389\r
67390\r
67391Ext.define('Ext.event.gesture.DoubleTap', {\r
67392 extend: Ext.event.gesture.SingleTouch,\r
67393 priority: 300,\r
67394 inheritableStatics: {\r
67395 \r
67396 DIFFERENT_TARGET: 'Different Target'\r
67397 },\r
67398 config: {\r
67399 \r
67400 moveDistance: 8,\r
67401 \r
67402 tapDistance: 24,\r
67403 maxDuration: 300\r
67404 },\r
67405 handledEvents: [\r
67406 'singletap',\r
67407 'doubletap'\r
67408 ],\r
67409 \r
67410 \r
67411 singleTapTimer: null,\r
67412 startTime: 0,\r
67413 lastTapTime: 0,\r
67414 onTouchStart: function(e) {\r
67415 var me = this,\r
67416 lastStartPoint;\r
67417 if (me.callParent(arguments) === false) {\r
67418 return false;\r
67419 }\r
67420
67421 lastStartPoint = me.lastStartPoint = e.changedTouches[0].point;\r
67422
67423 me.startPoint = me.startPoint || lastStartPoint;\r
67424 me.startTime = e.time;\r
67425 clearTimeout(me.singleTapTimer);\r
67426 },\r
67427 onTouchMove: function(e) {\r
67428 var me = this,\r
67429 point = e.changedTouches[0].point;\r
67430 if (Math.abs(point.getDistanceTo(me.lastStartPoint)) >= me.getMoveDistance()) {\r
67431 me.startPoint = null;\r
67432 return me.fail(me.self.TOUCH_MOVED);\r
67433 }\r
67434 },\r
67435 onTouchEnd: function(e) {\r
67436 var me = this,\r
67437 maxDuration = me.getMaxDuration(),\r
67438 time = e.time,\r
67439 target = e.target,\r
67440 lastTapTime = me.lastTapTime,\r
67441 lastTarget = me.lastTarget,\r
67442 point = e.changedTouches[0].point,\r
67443 duration;\r
67444 me.lastTapTime = time;\r
67445 me.lastTarget = target;\r
67446 if (lastTapTime) {\r
67447 duration = time - lastTapTime;\r
67448 if (duration <= maxDuration && Math.abs(point.getDistanceTo(me.startPoint)) <= me.getTapDistance()) {\r
67449 if (target !== lastTarget) {\r
67450 return me.fail(me.self.DIFFERENT_TARGET);\r
67451 }\r
67452 me.lastTarget = null;\r
67453 me.lastTapTime = 0;\r
67454 me.fire('doubletap', e, {\r
67455 touch: e.changedTouches[0],\r
67456 duration: duration\r
67457 });\r
67458 me.startPoint = null;\r
67459 return;\r
67460 }\r
67461 }\r
67462 if (time - me.startTime > maxDuration) {\r
67463 me.fireSingleTap(e);\r
67464 } else {\r
67465 me.setSingleTapTimer(e);\r
67466 }\r
67467 },\r
67468 setSingleTapTimer: function(e) {\r
67469 var me = this;\r
67470 me.singleTapTimer = Ext.defer(function() {\r
67471 me.fireSingleTap(e);\r
67472 }, me.getMaxDuration());\r
67473 },\r
67474 fireSingleTap: function(e, touch) {\r
67475 this.fire('singletap', e, {\r
67476 touch: touch\r
67477 });\r
67478 this.startPoint = null;\r
67479 },\r
67480 reset: function() {\r
67481 var me = this;\r
67482 me.startTime = me.lastTapTime = 0;\r
67483 me.lastStartPoint = me.startPoint = me.singleTapTimer = null;\r
67484 }\r
67485}, function(DoubleTap) {\r
67486 var gestures = Ext.manifest.gestures;\r
67487 DoubleTap.instance = new DoubleTap(gestures && gestures.doubleTap);\r
67488});\r
67489\r
67490\r
67491Ext.define('Ext.event.gesture.Drag', {\r
67492 extend: Ext.event.gesture.SingleTouch,\r
67493 priority: 100,\r
67494 isStarted: false,\r
67495 startPoint: null,\r
67496 previousPoint: null,\r
67497 lastPoint: null,\r
67498 handledEvents: [\r
67499 'dragstart',\r
67500 'drag',\r
67501 'dragend',\r
67502 'dragcancel'\r
67503 ],\r
67504 config: {\r
67505 \r
67506 minDistance: 8\r
67507 },\r
67508 constructor: function() {\r
67509 this.callParent(arguments);\r
67510 this.initInfo();\r
67511 },\r
67512 initInfo: function() {\r
67513 this.info = {\r
67514 touch: null,\r
67515 previous: {\r
67516 x: 0,\r
67517 y: 0\r
67518 },\r
67519 x: 0,\r
67520 y: 0,\r
67521 delta: {\r
67522 x: 0,\r
67523 y: 0\r
67524 },\r
67525 absDelta: {\r
67526 x: 0,\r
67527 y: 0\r
67528 },\r
67529 flick: {\r
67530 velocity: {\r
67531 x: 0,\r
67532 y: 0\r
67533 }\r
67534 },\r
67535 direction: {\r
67536 x: 0,\r
67537 y: 0\r
67538 },\r
67539 time: 0,\r
67540 previousTime: {\r
67541 x: 0,\r
67542 y: 0\r
67543 }\r
67544 };\r
67545 },\r
67546 onTouchStart: function(e) {\r
67547 if (this.callParent(arguments) === false) {\r
67548 if (this.isStarted && this.lastMoveEvent !== null) {\r
67549 this.lastMoveEvent.isStopped = false;\r
67550 this.onTouchEnd(this.lastMoveEvent);\r
67551 }\r
67552 return false;\r
67553 }\r
67554 this.startTime = e.time;\r
67555 this.startPoint = e.changedTouches[0].point;\r
67556 },\r
67557 tryDragStart: function(e) {\r
67558 var startPoint = this.startPoint,\r
67559 touch = e.changedTouches[0],\r
67560 point = touch.point,\r
67561 minDistance = this.getMinDistance(),\r
67562 info = this.info;\r
67563 if (Math.abs(point.getDistanceTo(startPoint)) >= minDistance) {\r
67564 this.isStarted = true;\r
67565 this.previousPoint = this.lastPoint = point;\r
67566 this.resetInfo('x', e, touch);\r
67567 this.resetInfo('y', e, touch);\r
67568 info.time = e.time;\r
67569 this.fire('dragstart', e, info);\r
67570 }\r
67571 },\r
67572 onTouchMove: function(e) {\r
67573 if (!this.isStarted) {\r
67574 this.tryDragStart(e);\r
67575 }\r
67576 if (!this.isStarted) {\r
67577 return;\r
67578 }\r
67579 var touch = e.changedTouches[0],\r
67580 point = touch.point;\r
67581 if (this.lastPoint) {\r
67582 this.previousPoint = this.lastPoint;\r
67583 }\r
67584 this.lastPoint = point;\r
67585 this.lastMoveEvent = e;\r
67586 this.updateInfo('x', e, touch);\r
67587 this.updateInfo('y', e, touch);\r
67588 this.info.time = e.time;\r
67589 this.fire('drag', e, this.info);\r
67590 },\r
67591 onAxisDragEnd: function(axis, info) {\r
67592 var duration = info.time - info.previousTime[axis];\r
67593 if (duration > 0) {\r
67594 info.flick.velocity[axis] = (info[axis] - info.previous[axis]) / duration;\r
67595 }\r
67596 },\r
67597 resetInfo: function(axis, e, touch) {\r
67598 var value = this.lastPoint[axis],\r
67599 startValue = this.startPoint[axis],\r
67600 delta = value - startValue,\r
67601 capAxis = axis.toUpperCase(),\r
67602 info = this.info;\r
67603 info.touch = touch;\r
67604 info.delta[axis] = delta;\r
67605 info.absDelta[axis] = Math.abs(delta);\r
67606 info.previousTime[axis] = this.startTime;\r
67607 info.previous[axis] = startValue;\r
67608 info[axis] = value;\r
67609 info.direction[axis] = 0;\r
67610 info['start' + capAxis] = this.startPoint[axis];\r
67611 info['previous' + capAxis] = info.previous[axis];\r
67612 info['page' + capAxis] = info[axis];\r
67613 info['delta' + capAxis] = info.delta[axis];\r
67614 info['absDelta' + capAxis] = info.absDelta[axis];\r
67615 info['previousDelta' + capAxis] = 0;\r
67616 info.startTime = this.startTime;\r
67617 },\r
67618 updateInfo: function(axis, e, touch) {\r
67619 var me = this,\r
67620 value = me.lastPoint[axis],\r
67621 previousValue = me.previousPoint[axis],\r
67622 startValue = me.startPoint[axis],\r
67623 delta = value - startValue,\r
67624 info = me.info,\r
67625 direction = info.direction,\r
67626 capAxis = axis.toUpperCase(),\r
67627 previousFlick = info.previous[axis];\r
67628 info.touch = touch;\r
67629 info.delta[axis] = delta;\r
67630 info.absDelta[axis] = Math.abs(delta);\r
67631 if (value !== previousFlick && value !== info[axis]) {\r
67632 info.previous[axis] = info[axis];\r
67633 info.previousTime[axis] = info.time;\r
67634 }\r
67635 info[axis] = value;\r
67636 if (value > previousValue) {\r
67637 direction[axis] = 1;\r
67638 } else if (value < previousValue) {\r
67639 direction[axis] = -1;\r
67640 }\r
67641 info['start' + capAxis] = startValue;\r
67642 info['previous' + capAxis] = info.previous[axis];\r
67643 info['page' + capAxis] = info[axis];\r
67644 info['delta' + capAxis] = info.delta[axis];\r
67645 info['absDelta' + capAxis] = info.absDelta[axis];\r
67646 info['previousDelta' + capAxis] = info.previous[axis] - startValue;\r
67647 info.startTime = me.startTime;\r
67648 },\r
67649 onTouchEnd: function(e) {\r
67650 this.doEnd(e);\r
67651 },\r
67652 onTouchCancel: function(e) {\r
67653 this.doEnd(e, true);\r
67654 return false;\r
67655 },\r
67656 doEnd: function(e, isCancel) {\r
67657 if (!this.isStarted) {\r
67658 this.tryDragStart(e);\r
67659 }\r
67660 if (this.isStarted) {\r
67661 var touch = e.changedTouches[0],\r
67662 point = touch.point,\r
67663 info = this.info;\r
67664 this.isStarted = false;\r
67665 this.lastPoint = point;\r
67666 this.updateInfo('x', e, touch);\r
67667 this.updateInfo('y', e, touch);\r
67668 info.time = e.time;\r
67669 this.onAxisDragEnd('x', info);\r
67670 this.onAxisDragEnd('y', info);\r
67671 this.fire(isCancel ? 'dragcancel' : 'dragend', e, info);\r
67672 this.startPoint = null;\r
67673 this.previousPoint = null;\r
67674 this.lastPoint = null;\r
67675 this.lastMoveEvent = null;\r
67676 }\r
67677 },\r
67678 reset: function() {\r
67679 var me = this;\r
67680 me.isStarted = me.lastPoint = me.startPoint = me.previousPoint = me.lastPoint = me.lastMoveEvent = null;\r
67681 me.initInfo();\r
67682 }\r
67683}, function(Drag) {\r
67684 var gestures = Ext.manifest.gestures;\r
67685 Drag.instance = new Drag(gestures && gestures.drag);\r
67686});\r
67687\r
67688\r
67689Ext.define('Ext.event.gesture.Swipe', {\r
67690 extend: Ext.event.gesture.SingleTouch,\r
67691 priority: 500,\r
67692 handledEvents: [\r
67693 'swipestart',\r
67694 'swipe',\r
67695 'swipecancel'\r
67696 ],\r
67697 \r
67698 \r
67699 \r
67700 inheritableStatics: {\r
67701 \r
67702 MAX_OFFSET_EXCEEDED: 'Max Offset Exceeded',\r
67703 \r
67704 MAX_DURATION_EXCEEDED: 'Max Duration Exceeded',\r
67705 \r
67706 DISTANCE_NOT_ENOUGH: 'Distance Not Enough'\r
67707 },\r
67708 config: {\r
67709 minDistance: 80,\r
67710 maxOffset: 35,\r
67711 maxDuration: 1000\r
67712 },\r
67713 onTouchStart: function(e) {\r
67714 if (this.callParent(arguments) === false) {\r
67715 return false;\r
67716 }\r
67717 var touch = e.changedTouches[0];\r
67718 this.startTime = e.time;\r
67719 this.isHorizontal = true;\r
67720 this.isVertical = true;\r
67721 this.startX = touch.pageX;\r
67722 this.startY = touch.pageY;\r
67723 },\r
67724 onTouchMove: function(e) {\r
67725 var touch = e.changedTouches[0],\r
67726 x = touch.pageX,\r
67727 y = touch.pageY,\r
67728 deltaX = x - this.startX,\r
67729 deltaY = y - this.startY,\r
67730 absDeltaX = Math.abs(x - this.startX),\r
67731 absDeltaY = Math.abs(y - this.startY),\r
67732 duration = e.time - this.startTime,\r
67733 minDistance = this.getMinDistance(),\r
67734 time = e.time,\r
67735 direction, distance;\r
67736 if (time - this.startTime > this.getMaxDuration()) {\r
67737 return this.fail(this.self.MAX_DURATION_EXCEEDED);\r
67738 }\r
67739 if (this.isHorizontal && absDeltaY > this.getMaxOffset()) {\r
67740 this.isHorizontal = false;\r
67741 }\r
67742 if (this.isVertical && absDeltaX > this.getMaxOffset()) {\r
67743 this.isVertical = false;\r
67744 }\r
67745 if (!this.isVertical || !this.isHorizontal) {\r
67746 if (this.isHorizontal && absDeltaX < minDistance) {\r
67747 direction = (deltaX < 0) ? 'left' : 'right';\r
67748 distance = absDeltaX;\r
67749 } else if (this.isVertical && absDeltaY < minDistance) {\r
67750 direction = (deltaY < 0) ? 'up' : 'down';\r
67751 distance = absDeltaY;\r
67752 }\r
67753 }\r
67754 if (direction && !this.started) {\r
67755 this.started = true;\r
67756 this.fire('swipestart', e, {\r
67757 touch: touch,\r
67758 direction: direction,\r
67759 distance: distance,\r
67760 duration: duration\r
67761 });\r
67762 }\r
67763 if (!this.isHorizontal && !this.isVertical) {\r
67764 return this.fail(this.self.MAX_OFFSET_EXCEEDED);\r
67765 }\r
67766 },\r
67767 onTouchEnd: function(e) {\r
67768 if (this.onTouchMove(e) === false) {\r
67769 return false;\r
67770 }\r
67771 var touch = e.changedTouches[0],\r
67772 x = touch.pageX,\r
67773 y = touch.pageY,\r
67774 deltaX = x - this.startX,\r
67775 deltaY = y - this.startY,\r
67776 absDeltaX = Math.abs(deltaX),\r
67777 absDeltaY = Math.abs(deltaY),\r
67778 minDistance = this.getMinDistance(),\r
67779 duration = e.time - this.startTime,\r
67780 direction, distance;\r
67781 if (this.isVertical && absDeltaY < minDistance) {\r
67782 this.isVertical = false;\r
67783 }\r
67784 if (this.isHorizontal && absDeltaX < minDistance) {\r
67785 this.isHorizontal = false;\r
67786 }\r
67787 if (this.isHorizontal) {\r
67788 direction = (deltaX < 0) ? 'left' : 'right';\r
67789 distance = absDeltaX;\r
67790 } else if (this.isVertical) {\r
67791 direction = (deltaY < 0) ? 'up' : 'down';\r
67792 distance = absDeltaY;\r
67793 } else {\r
67794 return this.fail(this.self.DISTANCE_NOT_ENOUGH);\r
67795 }\r
67796 this.started = false;\r
67797 this.fire('swipe', e, {\r
67798 touch: touch,\r
67799 direction: direction,\r
67800 distance: distance,\r
67801 duration: duration\r
67802 });\r
67803 },\r
67804 onTouchCancel: function(e) {\r
67805 this.fire('swipecancel', e);\r
67806 return false;\r
67807 },\r
67808 reset: function() {\r
67809 var me = this;\r
67810 me.startTime = me.isHorizontal = me.isVertical = me.startX = me.startY = null;\r
67811 }\r
67812}, function(Swipe) {\r
67813 var gestures = Ext.manifest.gestures;\r
67814 Swipe.instance = new Swipe(gestures && gestures.swipe);\r
67815});\r
67816\r
67817\r
67818Ext.define('Ext.event.gesture.EdgeSwipe', {\r
67819 extend: Ext.event.gesture.Swipe,\r
67820 priority: 800,\r
67821 handledEvents: [\r
67822 'edgeswipe',\r
67823 'edgeswipestart',\r
67824 'edgeswipeend',\r
67825 'edgeswipecancel'\r
67826 ],\r
67827 inheritableStatics: {\r
67828 \r
67829 NOT_NEAR_EDGE: 'Not Near Edge'\r
67830 },\r
67831 config: {\r
67832 minDistance: 60\r
67833 },\r
67834 onTouchStart: function(e) {\r
67835 if (this.callParent(arguments) === false) {\r
67836 return false;\r
67837 }\r
67838 var touch = e.changedTouches[0];\r
67839 this.started = false;\r
67840 this.direction = null;\r
67841 this.isHorizontal = true;\r
67842 this.isVertical = true;\r
67843 this.startX = touch.pageX;\r
67844 this.startY = touch.pageY;\r
67845 },\r
67846 onTouchMove: function(e) {\r
67847 var touch = e.changedTouches[0],\r
67848 x = touch.pageX,\r
67849 y = touch.pageY,\r
67850 deltaX = x - this.startX,\r
67851 deltaY = y - this.startY,\r
67852 absDeltaY = Math.abs(y - this.startY),\r
67853 absDeltaX = Math.abs(x - this.startX),\r
67854 minDistance = this.getMinDistance(),\r
67855 maxOffset = this.getMaxOffset(),\r
67856 duration = e.time - this.startTime,\r
67857 elementWidth = Ext.Viewport && Ext.Element.getViewportWidth(),\r
67858 elementHeight = Ext.Viewport && Ext.Element.getViewportHeight(),\r
67859 direction, distance;\r
67860
67861 if (this.isVertical && absDeltaX > maxOffset) {\r
67862 this.isVertical = false;\r
67863 }\r
67864
67865 if (this.isHorizontal && absDeltaY > maxOffset) {\r
67866 this.isHorizontal = false;\r
67867 }\r
67868
67869 if (this.isVertical && this.isHorizontal) {\r
67870 if (absDeltaY > absDeltaX) {\r
67871 this.isHorizontal = false;\r
67872 } else {\r
67873 this.isVertical = false;\r
67874 }\r
67875 }\r
67876
67877 if (this.isHorizontal) {\r
67878 direction = (deltaX < 0) ? 'left' : 'right';\r
67879 distance = deltaX;\r
67880 } else if (this.isVertical) {\r
67881 direction = (deltaY < 0) ? 'up' : 'down';\r
67882 distance = deltaY;\r
67883 }\r
67884 direction = this.direction || (this.direction = direction);\r
67885
67886 if (direction === 'up') {\r
67887 distance = deltaY * -1;\r
67888 } else if (direction === 'left') {\r
67889 distance = deltaX * -1;\r
67890 }\r
67891 this.distance = distance;\r
67892 if (!distance) {\r
67893 return this.fail(this.self.DISTANCE_NOT_ENOUGH);\r
67894 }\r
67895 if (!this.started) {\r
67896
67897 if (direction === 'right' && this.startX > minDistance) {\r
67898 return this.fail(this.self.NOT_NEAR_EDGE);\r
67899 } else if (direction === 'down' && this.startY > minDistance) {\r
67900 return this.fail(this.self.NOT_NEAR_EDGE);\r
67901 } else if (direction === 'left' && (elementWidth - this.startX) > minDistance) {\r
67902 return this.fail(this.self.NOT_NEAR_EDGE);\r
67903 } else if (direction === 'up' && (elementHeight - this.startY) > minDistance) {\r
67904 return this.fail(this.self.NOT_NEAR_EDGE);\r
67905 }\r
67906
67907 this.started = true;\r
67908 this.startTime = e.time;\r
67909 this.fire('edgeswipestart', e, {\r
67910 touch: touch,\r
67911 direction: direction,\r
67912 distance: distance,\r
67913 duration: duration\r
67914 });\r
67915 } else {\r
67916 this.fire('edgeswipe', e, {\r
67917 touch: touch,\r
67918 direction: direction,\r
67919 distance: distance,\r
67920 duration: duration\r
67921 });\r
67922 }\r
67923 },\r
67924 onTouchEnd: function(e) {\r
67925 var duration;\r
67926 if (this.onTouchMove(e) !== false) {\r
67927 duration = e.time - this.startTime;\r
67928 this.fire('edgeswipeend', e, {\r
67929 touch: e.changedTouches[0],\r
67930 direction: this.direction,\r
67931 distance: this.distance,\r
67932 duration: duration\r
67933 });\r
67934 }\r
67935 },\r
67936 onTouchCancel: function(e) {\r
67937 this.fire('edgeswipecancel', e, {\r
67938 touch: e.changedTouches[0]\r
67939 });\r
67940 return false;\r
67941 },\r
67942 reset: function() {\r
67943 var me = this;\r
67944 me.started = me.direction = me.isHorizontal = me.isVertical = me.startX = me.startY = me.startTime = me.distance = null;\r
67945 }\r
67946}, function(EdgeSwipe) {\r
67947 var gestures = Ext.manifest.gestures;\r
67948 EdgeSwipe.instance = new EdgeSwipe(gestures && gestures.edgeSwipe);\r
67949});\r
67950\r
67951\r
67952Ext.define('Ext.event.gesture.LongPress', {\r
67953 extend: Ext.event.gesture.SingleTouch,\r
67954 priority: 400,\r
67955 inheritableStatics: {\r
67956 \r
67957 DURATION_NOT_ENOUGH: 'Duration Not Enough'\r
67958 },\r
67959 config: {\r
67960 moveDistance: 8,\r
67961 minDuration: 1000\r
67962 },\r
67963 handledEvents: [\r
67964 'longpress',\r
67965 'taphold'\r
67966 ],\r
67967 \r
67968 \r
67969 fireLongPress: function(e) {\r
67970 this.fire('longpress', e, {\r
67971 touch: e.changedTouches[0],\r
67972 duration: this.getMinDuration()\r
67973 });\r
67974 this.isLongPress = true;\r
67975 },\r
67976 onTouchStart: function(e) {\r
67977 if (this.callParent(arguments) === false) {\r
67978 return false;\r
67979 }\r
67980 this.startPoint = e.changedTouches[0].point;\r
67981 this.isLongPress = false;\r
67982 this.setLongPressTimer(e);\r
67983 },\r
67984 setLongPressTimer: function(e) {\r
67985 var me = this;\r
67986 me.timer = Ext.defer(function() {\r
67987 me.fireLongPress(e);\r
67988 }, me.getMinDuration());\r
67989 },\r
67990 onTouchMove: function(e) {\r
67991 var point = e.changedTouches[0].point;\r
67992 if (Math.abs(point.getDistanceTo(this.startPoint)) >= this.getMoveDistance()) {\r
67993 return this.fail(this.self.TOUCH_MOVED);\r
67994 }\r
67995 },\r
67996 onTouchEnd: function() {\r
67997 if (!this.isLongPress) {\r
67998 return this.fail(this.self.DURATION_NOT_ENOUGH);\r
67999 }\r
68000 },\r
68001 fail: function() {\r
68002 clearTimeout(this.timer);\r
68003 return this.callParent(arguments);\r
68004 },\r
68005 reset: function() {\r
68006 this.isLongPress = this.startPoint = null;\r
68007 },\r
68008 fire: function(eventName) {\r
68009 if (eventName === 'longpress') {\r
68010 var args = Array.prototype.slice.call(arguments);\r
68011 args[0] = 'taphold';\r
68012 this.fire.apply(this, args);\r
68013 }\r
68014 return this.callParent(arguments);\r
68015 }\r
68016}, function(LongPress) {\r
68017 var gestures = Ext.manifest.gestures;\r
68018 LongPress.instance = new LongPress(gestures && gestures.longPress);\r
68019});\r
68020\r
68021\r
68022Ext.define('Ext.event.gesture.MultiTouch', {\r
68023 extend: Ext.event.gesture.Recognizer,\r
68024 requiredTouchesCount: 2,\r
68025 isTracking: false,\r
68026 isStarted: false,\r
68027 onTouchStart: function(e) {\r
68028 var requiredTouchesCount = this.requiredTouchesCount,\r
68029 touches = e.touches,\r
68030 touchesCount = touches.length;\r
68031 if (touchesCount === requiredTouchesCount) {\r
68032 this.start(e);\r
68033 } else if (touchesCount > requiredTouchesCount) {\r
68034 this.end(e);\r
68035 }\r
68036 },\r
68037 onTouchEnd: function(e) {\r
68038 this.end(e);\r
68039 },\r
68040 onTouchCancel: function(e) {\r
68041 this.end(e, true);\r
68042 return false;\r
68043 },\r
68044 start: function() {\r
68045 if (!this.isTracking) {\r
68046 this.isTracking = true;\r
68047 this.isStarted = false;\r
68048 }\r
68049 },\r
68050 end: function(e, isCancel) {\r
68051 if (this.isTracking) {\r
68052 this.isTracking = false;\r
68053 if (this.isStarted) {\r
68054 this.isStarted = false;\r
68055 this[isCancel ? 'fireCancel' : 'fireEnd'](e);\r
68056 }\r
68057 }\r
68058 },\r
68059 reset: function() {\r
68060 this.isTracking = this.isStarted = false;\r
68061 }\r
68062});\r
68063\r
68064\r
68065Ext.define('Ext.event.gesture.Pinch', {\r
68066 extend: Ext.event.gesture.MultiTouch,\r
68067 priority: 600,\r
68068 handledEvents: [\r
68069 'pinchstart',\r
68070 'pinch',\r
68071 'pinchend',\r
68072 'pinchcancel'\r
68073 ],\r
68074 \r
68075 \r
68076 \r
68077 \r
68078 startDistance: 0,\r
68079 lastTouches: null,\r
68080 onTouchMove: function(e) {\r
68081 if (!this.isTracking) {\r
68082 return;\r
68083 }\r
68084 var touches = e.touches,\r
68085 firstPoint, secondPoint, distance;\r
68086 firstPoint = touches[0].point;\r
68087 secondPoint = touches[1].point;\r
68088 distance = firstPoint.getDistanceTo(secondPoint);\r
68089 if (distance === 0) {\r
68090 return;\r
68091 }\r
68092 if (!this.isStarted) {\r
68093 this.isStarted = true;\r
68094 this.startDistance = distance;\r
68095 this.fire('pinchstart', e, {\r
68096 touches: touches,\r
68097 distance: distance,\r
68098 scale: 1\r
68099 });\r
68100 } else {\r
68101 this.fire('pinch', e, {\r
68102 touches: touches,\r
68103 distance: distance,\r
68104 scale: distance / this.startDistance\r
68105 });\r
68106 }\r
68107 },\r
68108 fireEnd: function(e) {\r
68109 this.fire('pinchend', e);\r
68110 },\r
68111 fireCancel: function(e) {\r
68112 this.fire('pinchcancel', e);\r
68113 },\r
68114 fail: function() {\r
68115 return this.callParent(arguments);\r
68116 },\r
68117 reset: function() {\r
68118 this.lastTouches = null;\r
68119 this.startDistance = 0;\r
68120 this.callParent();\r
68121 }\r
68122}, function(Pinch) {\r
68123 var gestures = Ext.manifest.gestures;\r
68124 Pinch.instance = new Pinch(gestures && gestures.pinch);\r
68125});\r
68126\r
68127\r
68128Ext.define('Ext.event.gesture.Rotate', {\r
68129 extend: Ext.event.gesture.MultiTouch,\r
68130 priority: 700,\r
68131 handledEvents: [\r
68132 'rotatestart',\r
68133 'rotate',\r
68134 'rotateend',\r
68135 'rotatecancel'\r
68136 ],\r
68137 \r
68138 \r
68139 \r
68140 \r
68141 \r
68142 startAngle: 0,\r
68143 lastTouches: null,\r
68144 lastAngle: null,\r
68145 onTouchMove: function(e) {\r
68146 if (!this.isTracking) {\r
68147 return;\r
68148 }\r
68149 var touches = e.touches,\r
68150 lastAngle = this.lastAngle,\r
68151 firstPoint, secondPoint, angle, nextAngle, previousAngle, diff;\r
68152 firstPoint = touches[0].point;\r
68153 secondPoint = touches[1].point;\r
68154 angle = firstPoint.getAngleTo(secondPoint);\r
68155 if (lastAngle !== null) {\r
68156 diff = Math.abs(lastAngle - angle);\r
68157 nextAngle = angle + 360;\r
68158 previousAngle = angle - 360;\r
68159 if (Math.abs(nextAngle - lastAngle) < diff) {\r
68160 angle = nextAngle;\r
68161 } else if (Math.abs(previousAngle - lastAngle) < diff) {\r
68162 angle = previousAngle;\r
68163 }\r
68164 }\r
68165 this.lastAngle = angle;\r
68166 if (!this.isStarted) {\r
68167 this.isStarted = true;\r
68168 this.startAngle = angle;\r
68169 this.fire('rotatestart', e, {\r
68170 touches: touches,\r
68171 angle: angle,\r
68172 rotation: 0\r
68173 });\r
68174 } else {\r
68175 this.fire('rotate', e, {\r
68176 touches: touches,\r
68177 angle: angle,\r
68178 rotation: angle - this.startAngle\r
68179 });\r
68180 }\r
68181 this.lastTouches = Ext.Array.clone(touches);\r
68182 },\r
68183 fireEnd: function(e) {\r
68184 this.lastAngle = null;\r
68185 this.fire('rotateend', e);\r
68186 },\r
68187 fireCancel: function(e) {\r
68188 this.lastAngle = null;\r
68189 this.fire('rotatecancel', e);\r
68190 },\r
68191 reset: function() {\r
68192 var me = this;\r
68193 me.lastTouches = me.lastAngle = me.startAngle = null;\r
68194 this.callParent();\r
68195 }\r
68196}, function(Rotate) {\r
68197 var gestures = Ext.manifest.gestures;\r
68198 Rotate.instance = new Rotate(gestures && gestures.rotate);\r
68199});\r
68200\r
68201\r
68202Ext.define('Ext.event.gesture.Tap', {\r
68203 extend: Ext.event.gesture.SingleTouch,\r
68204 priority: 200,\r
68205 handledEvents: [\r
68206 'tap',\r
68207 'tapcancel'\r
68208 ],\r
68209 config: {\r
68210 \r
68211 moveDistance: 8\r
68212 },\r
68213 onTouchStart: function(e) {\r
68214 if (this.callParent([\r
68215 e\r
68216 ]) === false) {\r
68217 return false;\r
68218 }\r
68219 this.startPoint = e.changedTouches[0].point;\r
68220 },\r
68221 onTouchMove: function(e) {\r
68222 var touch = e.changedTouches[0],\r
68223 point = touch.point;\r
68224 if (Math.abs(point.getDistanceTo(this.startPoint)) >= this.getMoveDistance()) {\r
68225 this.fire('tapcancel', e, {\r
68226 touch: touch\r
68227 });\r
68228 return this.fail(this.self.TOUCH_MOVED);\r
68229 }\r
68230 },\r
68231 onTouchEnd: function(e) {\r
68232 this.fire('tap', e, {\r
68233 touch: e.changedTouches[0]\r
68234 });\r
68235 },\r
68236 onTouchCancel: function(e) {\r
68237 this.fire('tapcancel', e, {\r
68238 touch: e.changedTouches[0]\r
68239 });\r
68240 return false;\r
68241 },\r
68242 reset: function() {\r
68243 this.startPoint = null;\r
68244 }\r
68245}, function(Tap) {\r
68246 var gestures = Ext.manifest.gestures;\r
68247 Tap.instance = new Tap(gestures && gestures.tap);\r
68248});\r
68249\r
68250\r
68251Ext.define('Ext.event.publisher.Focus', {\r
68252 extend: Ext.event.publisher.Dom,\r
68253 type: 'focus',\r
68254 handledEvents: [\r
68255 'focusenter',\r
68256 'focusleave',\r
68257 'focusmove'\r
68258 ],\r
68259
68260
68261 handledDomEvents: [\r
68262 'focusin',\r
68263 'focusout'\r
68264 ],\r
68265 doDelegatedEvent: function(e, invokeAfter) {\r
68266 var me = this,\r
68267 relatedTarget;\r
68268 e = me.callParent([\r
68269 e,\r
68270 false\r
68271 ]);\r
68272 if (e) {\r
68273 if (e.type === 'focusout') {\r
68274
68275
68276 if (e.relatedTarget == null) {\r
68277 me.processFocusIn(e, e.target, document.body, invokeAfter);\r
68278 }\r
68279 } else {\r
68280 relatedTarget = e.relatedTarget;\r
68281
68282
68283 me.processFocusIn(e, (relatedTarget == null || !relatedTarget.tagName) ? document.body : relatedTarget, e.target, invokeAfter);\r
68284 }\r
68285 }\r
68286 },\r
68287 processFocusIn: function(e, fromElement, toElement, invokeAfter) {\r
68288 var me = this,\r
68289 commonAncestor, node,\r
68290 targets = [],\r
68291 event, focusEnterEvent, fromFly, toFly;\r
68292
68293
68294
68295 fromFly = Ext.fly(fromElement);\r
68296 toFly = Ext.fly(toElement);\r
68297
68298
68299 if ((fromFly && fromFly.isFocusSuspended()) || (toFly && toFly.isFocusSuspended())) {\r
68300 return;\r
68301 }\r
68302
68303 for (node = fromElement , commonAncestor = Ext.dom.Element.getCommonAncestor(toElement, fromElement, true); node && node !== commonAncestor; node = node.parentNode) {\r
68304 targets.push(node);\r
68305 }\r
68306
68307 if (targets.length) {\r
68308 event = me.createSyntheticEvent('focusleave', e, fromElement, toElement);\r
68309 me.publish('focusleave', targets, event);\r
68310 if (event.isStopped) {\r
68311 return;\r
68312 }\r
68313 }\r
68314
68315 targets.length = 0;\r
68316 for (node = toElement; node !== commonAncestor; node = node.parentNode) {\r
68317 targets.push(node);\r
68318 }\r
68319
68320 focusEnterEvent = me.createSyntheticEvent('focusenter', e, toElement, fromElement);\r
68321
68322 if (targets.length) {\r
68323 me.publish('focusenter', targets, focusEnterEvent);\r
68324 if (focusEnterEvent.isStopped) {\r
68325 return;\r
68326 }\r
68327 }\r
68328
68329 targets = me.getPropagatingTargets(commonAncestor);\r
68330
68331 if (targets.length) {\r
68332 event = me.createSyntheticEvent('focusmove', e, toElement, fromElement);\r
68333 me.publish('focusmove', targets, event);\r
68334 if (event.isStopped) {\r
68335 return;\r
68336 }\r
68337 }\r
68338 if (invokeAfter) {\r
68339 me.afterEvent(e);\r
68340 }\r
68341 Ext.GlobalEvents.fireEvent('focus', {\r
68342 event: focusEnterEvent,\r
68343 toElement: toElement,\r
68344 fromElement: fromElement\r
68345 });\r
68346 },\r
68347 createSyntheticEvent: function(eventName, browserEvent, target, relatedTarget) {\r
68348 var event = new Ext.event.Event(browserEvent);\r
68349 event.type = eventName;\r
68350 event.relatedTarget = relatedTarget;\r
68351 event.target = target;\r
68352 return event;\r
68353 }\r
68354}, function(Focus) {\r
68355 var focusTimeout;\r
68356 Focus.instance = new Focus();\r
68357
68358
68359 if (!Ext.supports.FocusinFocusoutEvents) {\r
68360
68361
68362 this.override({\r
68363 handledDomEvents: [\r
68364 'focus',\r
68365 'blur'\r
68366 ],\r
68367 doDelegatedEvent: function(e, invokeAfter) {\r
68368 var me = this;\r
68369 e = me.callSuper([\r
68370 e,\r
68371 false\r
68372 ]);\r
68373 if (e) {\r
68374 clearTimeout(focusTimeout);\r
68375 focusTimeout = 0;\r
68376 if (e.type === 'blur') {\r
68377 var blurredEl = e.target === window ? document.body : e.target;\r
68378
68379
68380 focusTimeout = setTimeout(function() {\r
68381 focusTimeout = 0;\r
68382 me.processFocusIn(e, blurredEl, document.body, invokeAfter);\r
68383 Focus.previousActiveElement = null;\r
68384 }, 0);\r
68385 if (e.target === window || e.target === document) {\r
68386 Focus.previousActiveElement = null;\r
68387 } else {\r
68388 Focus.previousActiveElement = e.target;\r
68389 }\r
68390 } else {\r
68391 me.processFocusIn(e, Focus.previousActiveElement || document.body, e.target === window ? document.body : e.target, invokeAfter);\r
68392 }\r
68393 }\r
68394 }\r
68395 });\r
68396 }\r
68397});\r
68398\r
68399\r
68400Ext.define('Ext.fx.runner.Css', {\r
68401 extend: Ext.Evented,\r
68402 prefixedProperties: {\r
68403 'transform': true,\r
68404 'transform-origin': true,\r
68405 'perspective': true,\r
68406 'transform-style': true,\r
68407 'transition': true,\r
68408 'transition-property': true,\r
68409 'transition-duration': true,\r
68410 'transition-timing-function': true,\r
68411 'transition-delay': true,\r
68412 'animation': true,\r
68413 'animation-name': true,\r
68414 'animation-duration': true,\r
68415 'animation-iteration-count': true,\r
68416 'animation-direction': true,\r
68417 'animation-timing-function': true,\r
68418 'animation-delay': true\r
68419 },\r
68420 lengthProperties: {\r
68421 'top': true,\r
68422 'right': true,\r
68423 'bottom': true,\r
68424 'left': true,\r
68425 'width': true,\r
68426 'height': true,\r
68427 'max-height': true,\r
68428 'max-width': true,\r
68429 'min-height': true,\r
68430 'min-width': true,\r
68431 'margin-bottom': true,\r
68432 'margin-left': true,\r
68433 'margin-right': true,\r
68434 'margin-top': true,\r
68435 'padding-bottom': true,\r
68436 'padding-left': true,\r
68437 'padding-right': true,\r
68438 'padding-top': true,\r
68439 'border-bottom-width': true,\r
68440 'border-left-width': true,\r
68441 'border-right-width': true,\r
68442 'border-spacing': true,\r
68443 'border-top-width': true,\r
68444 'border-width': true,\r
68445 'outline-width': true,\r
68446 'letter-spacing': true,\r
68447 'line-height': true,\r
68448 'text-indent': true,\r
68449 'word-spacing': true,\r
68450 'font-size': true,\r
68451 'translate': true,\r
68452 'translateX': true,\r
68453 'translateY': true,\r
68454 'translateZ': true,\r
68455 'translate3d': true\r
68456 },\r
68457 durationProperties: {\r
68458 'transition-duration': true,\r
68459 'transition-delay': true,\r
68460 'animation-duration': true,\r
68461 'animation-delay': true\r
68462 },\r
68463 angleProperties: {\r
68464 rotate: true,\r
68465 rotateX: true,\r
68466 rotateY: true,\r
68467 rotateZ: true,\r
68468 skew: true,\r
68469 skewX: true,\r
68470 skewY: true\r
68471 },\r
68472 lengthUnitRegex: /([a-z%]*)$/,\r
68473 DEFAULT_UNIT_LENGTH: 'px',\r
68474 DEFAULT_UNIT_ANGLE: 'deg',\r
68475 DEFAULT_UNIT_DURATION: 'ms',\r
68476 formattedNameCache: {},\r
68477 transformMethods3d: [\r
68478 'translateX',\r
68479 'translateY',\r
68480 'translateZ',\r
68481 'rotate',\r
68482 'rotateX',\r
68483 'rotateY',\r
68484 'rotateZ',\r
68485 'skewX',\r
68486 'skewY',\r
68487 'scaleX',\r
68488 'scaleY',\r
68489 'scaleZ'\r
68490 ],\r
68491 transformMethodsNo3d: [\r
68492 'translateX',\r
68493 'translateY',\r
68494 'rotate',\r
68495 'skewX',\r
68496 'skewY',\r
68497 'scaleX',\r
68498 'scaleY'\r
68499 ],\r
68500 constructor: function() {\r
68501 var me = this;\r
68502 me.transformMethods = Ext.feature.has.Css3dTransforms ? me.transformMethods3d : me.transformMethodsNo3d;\r
68503 me.vendorPrefix = Ext.browser.getStyleDashPrefix();\r
68504 me.ruleStylesCache = {};\r
68505 me.callParent();\r
68506 },\r
68507 getStyleSheet: function() {\r
68508 var styleSheet = this.styleSheet,\r
68509 styleElement, styleSheets;\r
68510 if (!styleSheet) {\r
68511 styleElement = document.createElement('style');\r
68512 styleElement.type = 'text/css';\r
68513 (document.head || document.getElementsByTagName('head')[0]).appendChild(styleElement);\r
68514 styleSheets = document.styleSheets;\r
68515 this.styleSheet = styleSheet = styleSheets[styleSheets.length - 1];\r
68516 }\r
68517 return styleSheet;\r
68518 },\r
68519 applyRules: function(selectors) {\r
68520 var styleSheet = this.getStyleSheet(),\r
68521 ruleStylesCache = this.ruleStylesCache,\r
68522 rules = styleSheet.cssRules,\r
68523 selector, properties, ruleStyle, ruleStyleCache, rulesLength, name, value;\r
68524 for (selector in selectors) {\r
68525 properties = selectors[selector];\r
68526 ruleStyle = ruleStylesCache[selector];\r
68527 if (ruleStyle === undefined) {\r
68528 rulesLength = rules.length;\r
68529 styleSheet.insertRule(selector + '{}', rulesLength);\r
68530 ruleStyle = ruleStylesCache[selector] = rules.item(rulesLength).style;\r
68531 }\r
68532 ruleStyleCache = ruleStyle.$cache;\r
68533 if (!ruleStyleCache) {\r
68534 ruleStyleCache = ruleStyle.$cache = {};\r
68535 }\r
68536 for (name in properties) {\r
68537 value = this.formatValue(properties[name], name);\r
68538 name = this.formatName(name);\r
68539 if (ruleStyleCache[name] !== value) {\r
68540 ruleStyleCache[name] = value;\r
68541 if (value === null) {\r
68542 ruleStyle.removeProperty(name);\r
68543 } else {\r
68544 ruleStyle.setProperty(name, value, 'important');\r
68545 }\r
68546 }\r
68547 }\r
68548 }\r
68549 return this;\r
68550 },\r
68551 applyStyles: function(styles) {\r
68552 var id, element, elementStyle, properties, name, value;\r
68553 for (id in styles) {\r
68554 if (styles.hasOwnProperty(id)) {\r
68555 element = document.getElementById(id);\r
68556 if (!element) {\r
68557 \r
68558 continue;\r
68559 }\r
68560 elementStyle = element.style;\r
68561 properties = styles[id];\r
68562 for (name in properties) {\r
68563 if (properties.hasOwnProperty(name)) {\r
68564 value = this.formatValue(properties[name], name);\r
68565 name = this.formatName(name);\r
68566 if (value === null) {\r
68567 elementStyle.removeProperty(name);\r
68568 } else {\r
68569 elementStyle.setProperty(name, value, 'important');\r
68570 }\r
68571 }\r
68572 }\r
68573 }\r
68574 }\r
68575 return this;\r
68576 },\r
68577 formatName: function(name) {\r
68578 var cache = this.formattedNameCache,\r
68579 formattedName = cache[name];\r
68580 if (!formattedName) {\r
68581 if ((Ext.os.is.Tizen || !Ext.feature.has.CssTransformNoPrefix) && this.prefixedProperties[name]) {\r
68582 formattedName = this.vendorPrefix + name;\r
68583 } else {\r
68584 formattedName = name;\r
68585 }\r
68586 cache[name] = formattedName;\r
68587 }\r
68588 return formattedName;\r
68589 },\r
68590 formatValue: function(value, name) {\r
68591 var type = typeof value,\r
68592 lengthUnit = this.DEFAULT_UNIT_LENGTH,\r
68593 transformMethods, method, i, ln, transformValues, values, unit;\r
68594 if (value === null) {\r
68595 return '';\r
68596 }\r
68597 if (type == 'string') {\r
68598 if (this.lengthProperties[name]) {\r
68599 unit = value.match(this.lengthUnitRegex)[1];\r
68600 if (unit.length > 0) {\r
68601
68602 if (unit !== lengthUnit) {\r
68603 Ext.Logger.error("Length unit: '" + unit + "' in value: '" + value + "' of property: '" + name + "' is not " + "valid for animation. Only 'px' is allowed");\r
68604 }\r
68605 } else
68606 {\r
68607 return value + lengthUnit;\r
68608 }\r
68609 }\r
68610 return value;\r
68611 } else if (type == 'number') {\r
68612 if (value == 0) {\r
68613 return '0';\r
68614 }\r
68615 if (this.lengthProperties[name]) {\r
68616 return value + lengthUnit;\r
68617 }\r
68618 if (this.angleProperties[name]) {\r
68619 return value + this.DEFAULT_UNIT_ANGLE;\r
68620 }\r
68621 if (this.durationProperties[name]) {\r
68622 return value + this.DEFAULT_UNIT_DURATION;\r
68623 }\r
68624 } else if (name === 'transform') {\r
68625 transformMethods = this.transformMethods;\r
68626 transformValues = [];\r
68627 for (i = 0 , ln = transformMethods.length; i < ln; i++) {\r
68628 method = transformMethods[i];\r
68629 transformValues.push(method + '(' + this.formatValue(value[method], method) + ')');\r
68630 }\r
68631 return transformValues.join(' ');\r
68632 } else if (Ext.isArray(value)) {\r
68633 values = [];\r
68634 for (i = 0 , ln = value.length; i < ln; i++) {\r
68635 values.push(this.formatValue(value[i], name));\r
68636 }\r
68637 return (values.length > 0) ? values.join(', ') : 'none';\r
68638 }\r
68639 return value;\r
68640 }\r
68641});\r
68642\r
68643\r
68644Ext.define('Ext.fx.runner.CssTransition', {\r
68645 extend: Ext.fx.runner.Css,\r
68646 alternateClassName: 'Ext.Animator',\r
68647 singleton: true,\r
68648 listenersAttached: false,\r
68649 constructor: function() {\r
68650 this.runningAnimationsData = {};\r
68651 return this.callParent(arguments);\r
68652 },\r
68653 attachListeners: function() {\r
68654 this.listenersAttached = true;\r
68655 Ext.getWin().on('transitionend', 'onTransitionEnd', this);\r
68656 },\r
68657 onTransitionEnd: function(e) {\r
68658 var target = e.target,\r
68659 id = target.id;\r
68660 if (id && this.runningAnimationsData.hasOwnProperty(id)) {\r
68661 this.refreshRunningAnimationsData(Ext.get(target), [\r
68662 e.browserEvent.propertyName\r
68663 ]);\r
68664 }\r
68665 },\r
68666 onAnimationEnd: function(element, data, animation, isInterrupted, isReplaced) {\r
68667 var id = element.getId(),\r
68668 runningData = this.runningAnimationsData[id],\r
68669 endRules = {},\r
68670 endData = {},\r
68671 runningNameMap, toPropertyNames, i, ln, name;\r
68672 animation.un('stop', 'onAnimationStop', this);\r
68673 if (runningData) {\r
68674 runningNameMap = runningData.nameMap;\r
68675 }\r
68676 endRules[id] = endData;\r
68677 if (data.onBeforeEnd) {\r
68678 data.onBeforeEnd.call(data.scope || this, element, isInterrupted);\r
68679 }\r
68680 animation.fireEvent('animationbeforeend', animation, element, isInterrupted);\r
68681 this.fireEvent('animationbeforeend', this, animation, element, isInterrupted);\r
68682 if (isReplaced || (!isInterrupted && !data.preserveEndState)) {\r
68683 toPropertyNames = data.toPropertyNames;\r
68684 for (i = 0 , ln = toPropertyNames.length; i < ln; i++) {\r
68685 name = toPropertyNames[i];\r
68686 if (runningNameMap && !runningNameMap.hasOwnProperty(name)) {\r
68687 endData[name] = null;\r
68688 }\r
68689 }\r
68690 }\r
68691 if (data.after) {\r
68692 Ext.merge(endData, data.after);\r
68693 }\r
68694 this.applyStyles(endRules);\r
68695 if (data.onEnd) {\r
68696 data.onEnd.call(data.scope || this, element, isInterrupted);\r
68697 }\r
68698 animation.fireEvent('animationend', animation, element, isInterrupted);\r
68699 this.fireEvent('animationend', this, animation, element, isInterrupted);\r
68700 Ext.AnimationQueue.stop(Ext.emptyFn, animation);\r
68701 },\r
68702 onAllAnimationsEnd: function(element) {\r
68703 var id = element.getId(),\r
68704 endRules = {};\r
68705 delete this.runningAnimationsData[id];\r
68706 endRules[id] = {\r
68707 'transition-property': null,\r
68708 'transition-duration': null,\r
68709 'transition-timing-function': null,\r
68710 'transition-delay': null\r
68711 };\r
68712 this.applyStyles(endRules);\r
68713 this.fireEvent('animationallend', this, element);\r
68714 },\r
68715 hasRunningAnimations: function(element) {\r
68716 var id = element.getId(),\r
68717 runningAnimationsData = this.runningAnimationsData;\r
68718 return runningAnimationsData.hasOwnProperty(id) && runningAnimationsData[id].sessions.length > 0;\r
68719 },\r
68720 refreshRunningAnimationsData: function(element, propertyNames, interrupt, replace) {\r
68721 var id = element.getId(),\r
68722 runningAnimationsData = this.runningAnimationsData,\r
68723 runningData = runningAnimationsData[id];\r
68724 if (!runningData) {\r
68725 return;\r
68726 }\r
68727 var nameMap = runningData.nameMap,\r
68728 nameList = runningData.nameList,\r
68729 sessions = runningData.sessions,\r
68730 ln, j, subLn, name, i, session, map, list,\r
68731 hasCompletedSession = false;\r
68732 interrupt = Boolean(interrupt);\r
68733 replace = Boolean(replace);\r
68734 if (!sessions) {\r
68735 return this;\r
68736 }\r
68737 ln = sessions.length;\r
68738 if (ln === 0) {\r
68739 return this;\r
68740 }\r
68741 if (replace) {\r
68742 runningData.nameMap = {};\r
68743 nameList.length = 0;\r
68744 for (i = 0; i < ln; i++) {\r
68745 session = sessions[i];\r
68746 this.onAnimationEnd(element, session.data, session.animation, interrupt, replace);\r
68747 }\r
68748 sessions.length = 0;\r
68749 } else {\r
68750 for (i = 0; i < ln; i++) {\r
68751 session = sessions[i];\r
68752 map = session.map;\r
68753 list = session.list;\r
68754 for (j = 0 , subLn = propertyNames.length; j < subLn; j++) {\r
68755 name = propertyNames[j];\r
68756 if (map[name]) {\r
68757 delete map[name];\r
68758 Ext.Array.remove(list, name);\r
68759 session.length--;\r
68760 if (--nameMap[name] == 0) {\r
68761 delete nameMap[name];\r
68762 Ext.Array.remove(nameList, name);\r
68763 }\r
68764 }\r
68765 }\r
68766 if (session.length == 0) {\r
68767 sessions.splice(i, 1);\r
68768 i--;\r
68769 ln--;\r
68770 hasCompletedSession = true;\r
68771 this.onAnimationEnd(element, session.data, session.animation, interrupt);\r
68772 }\r
68773 }\r
68774 }\r
68775 if (!replace && !interrupt && sessions.length == 0 && hasCompletedSession) {\r
68776 this.onAllAnimationsEnd(element);\r
68777 }\r
68778 },\r
68779 getRunningData: function(id) {\r
68780 var runningAnimationsData = this.runningAnimationsData;\r
68781 if (!runningAnimationsData.hasOwnProperty(id)) {\r
68782 runningAnimationsData[id] = {\r
68783 nameMap: {},\r
68784 nameList: [],\r
68785 sessions: []\r
68786 };\r
68787 }\r
68788 return runningAnimationsData[id];\r
68789 },\r
68790 getTestElement: function() {\r
68791 var testElement = this.testElement,\r
68792 iframe, iframeDocument, iframeStyle;\r
68793 if (!testElement) {\r
68794 iframe = document.createElement('iframe');\r
68795
68796
68797
68798 iframe.setAttribute('data-sticky', true);\r
68799
68800 iframe.setAttribute('tabIndex', -1);\r
68801 iframeStyle = iframe.style;\r
68802 iframeStyle.setProperty('visibility', 'hidden', 'important');\r
68803 iframeStyle.setProperty('width', '0px', 'important');\r
68804 iframeStyle.setProperty('height', '0px', 'important');\r
68805 iframeStyle.setProperty('position', 'absolute', 'important');\r
68806 iframeStyle.setProperty('border', '0px', 'important');\r
68807 iframeStyle.setProperty('zIndex', '-1000', 'important');\r
68808 document.body.appendChild(iframe);\r
68809 iframeDocument = iframe.contentDocument;\r
68810 iframeDocument.open();\r
68811 iframeDocument.writeln('</body>');\r
68812 iframeDocument.close();\r
68813 this.testElement = testElement = iframeDocument.createElement('div');\r
68814 testElement.style.setProperty('position', 'absolute', 'important');\r
68815 iframeDocument.body.appendChild(testElement);\r
68816 this.testElementComputedStyle = window.getComputedStyle(testElement);\r
68817 }\r
68818 return testElement;\r
68819 },\r
68820 getCssStyleValue: function(name, value) {\r
68821 var testElement = this.getTestElement(),\r
68822 computedStyle = this.testElementComputedStyle,\r
68823 style = testElement.style;\r
68824 style.setProperty(name, value);\r
68825 if (Ext.browser.is.Firefox) {\r
68826
68827 testElement.offsetHeight;\r
68828 }\r
68829 value = computedStyle.getPropertyValue(name);\r
68830 style.removeProperty(name);\r
68831 return value;\r
68832 },\r
68833 run: function(animations) {\r
68834 var me = this,\r
68835 isLengthPropertyMap = me.lengthProperties,\r
68836 fromData = {},\r
68837 toData = {},\r
68838 data = {},\r
68839 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;\r
68840 if (!me.listenersAttached) {\r
68841 me.attachListeners();\r
68842 }\r
68843 animations = Ext.Array.from(animations);\r
68844 for (i = 0 , ln = animations.length; i < ln; i++) {\r
68845 animation = animations[i];\r
68846 animation = Ext.factory(animation, Ext.fx.Animation);\r
68847 element = animation.getElement();\r
68848
68849 Ext.AnimationQueue.start(Ext.emptyFn, animation);\r
68850 computedStyle = window.getComputedStyle(element.dom);\r
68851 elementId = element.getId();\r
68852 data = Ext.merge({}, animation.getData());\r
68853 if (animation.onBeforeStart) {\r
68854 animation.onBeforeStart.call(animation.scope || me, element);\r
68855 }\r
68856 animation.fireEvent('animationstart', animation);\r
68857 me.fireEvent('animationstart', me, animation);\r
68858 data[elementId] = data;\r
68859 before = data.before;\r
68860 from = data.from;\r
68861 to = data.to;\r
68862 data.fromPropertyNames = fromPropertyNames = [];\r
68863 data.toPropertyNames = toPropertyNames = [];\r
68864 for (name in to) {\r
68865 if (to.hasOwnProperty(name)) {\r
68866 to[name] = toFormattedValue = me.formatValue(to[name], name);\r
68867 formattedName = me.formatName(name);\r
68868 isLengthProperty = isLengthPropertyMap.hasOwnProperty(name);\r
68869 if (!isLengthProperty) {\r
68870 toFormattedValue = me.getCssStyleValue(formattedName, toFormattedValue);\r
68871 }\r
68872 if (from.hasOwnProperty(name)) {\r
68873 from[name] = fromFormattedValue = me.formatValue(from[name], name);\r
68874 if (!isLengthProperty) {\r
68875 fromFormattedValue = me.getCssStyleValue(formattedName, fromFormattedValue);\r
68876 }\r
68877 if (toFormattedValue !== fromFormattedValue) {\r
68878 fromPropertyNames.push(formattedName);\r
68879 toPropertyNames.push(formattedName);\r
68880 }\r
68881 } else {\r
68882 computedValue = computedStyle.getPropertyValue(formattedName);\r
68883 if (toFormattedValue !== computedValue) {\r
68884 toPropertyNames.push(formattedName);\r
68885 }\r
68886 }\r
68887 }\r
68888 }\r
68889 propertiesLength = toPropertyNames.length;\r
68890 if (propertiesLength === 0) {\r
68891 me.onAnimationEnd(element, data, animation);\r
68892 \r
68893 continue;\r
68894 }\r
68895 runningData = me.getRunningData(elementId);\r
68896 runningSessions = runningData.sessions;\r
68897 if (runningSessions.length > 0) {\r
68898 me.refreshRunningAnimationsData(element, Ext.Array.merge(fromPropertyNames, toPropertyNames), true, data.replacePrevious);\r
68899 }\r
68900 runningNameMap = runningData.nameMap;\r
68901 runningNameList = runningData.nameList;\r
68902 sessionNameMap = {};\r
68903 for (j = 0; j < propertiesLength; j++) {\r
68904 name = toPropertyNames[j];\r
68905 sessionNameMap[name] = true;\r
68906 if (!runningNameMap.hasOwnProperty(name)) {\r
68907 runningNameMap[name] = 1;\r
68908 runningNameList.push(name);\r
68909 } else {\r
68910 runningNameMap[name]++;\r
68911 }\r
68912 }\r
68913 runningSession = {\r
68914 element: element,\r
68915 map: sessionNameMap,\r
68916 list: toPropertyNames.slice(),\r
68917 length: propertiesLength,\r
68918 data: data,\r
68919 animation: animation\r
68920 };\r
68921 runningSessions.push(runningSession);\r
68922 animation.on('stop', 'onAnimationStop', me);\r
68923 elementData = Ext.apply({}, before);\r
68924 Ext.apply(elementData, from);\r
68925 if (runningNameList.length > 0) {\r
68926 fromPropertyNames = Ext.Array.difference(runningNameList, fromPropertyNames);\r
68927 toPropertyNames = Ext.Array.merge(fromPropertyNames, toPropertyNames);\r
68928 elementData['transition-property'] = fromPropertyNames;\r
68929 }\r
68930 fromData[elementId] = elementData;\r
68931 toData[elementId] = Ext.apply({}, to);\r
68932 toData[elementId]['transition-property'] = toPropertyNames;\r
68933 toData[elementId]['transition-duration'] = data.duration;\r
68934 toData[elementId]['transition-timing-function'] = data.easing;\r
68935 toData[elementId]['transition-delay'] = data.delay;\r
68936 animation.startTime = Date.now();\r
68937 }\r
68938 message = me.$className;\r
68939 me.applyStyles(fromData);\r
68940 doApplyTo = function(e) {\r
68941 if (e.data === message && e.source === window) {\r
68942 window.removeEventListener('message', doApplyTo, false);\r
68943 me.applyStyles(toData);\r
68944 }\r
68945 };\r
68946 if (window.requestAnimationFrame) {\r
68947 window.requestAnimationFrame(function() {\r
68948 window.addEventListener('message', doApplyTo, false);\r
68949 window.postMessage(message, '*');\r
68950 });\r
68951 } else {\r
68952 Ext.defer(function() {\r
68953 window.addEventListener('message', doApplyTo, false);\r
68954 window.postMessage(message, '*');\r
68955 }, 1);\r
68956 }\r
68957 },\r
68958 onAnimationStop: function(animation) {\r
68959 var runningAnimationsData = this.runningAnimationsData,\r
68960 id, runningData, sessions, i, ln, session;\r
68961 for (id in runningAnimationsData) {\r
68962 if (runningAnimationsData.hasOwnProperty(id)) {\r
68963 runningData = runningAnimationsData[id];\r
68964 sessions = runningData.sessions;\r
68965 for (i = 0 , ln = sessions.length; i < ln; i++) {\r
68966 session = sessions[i];\r
68967 if (session.animation === animation) {\r
68968 this.refreshRunningAnimationsData(session.element, session.list.slice(), false);\r
68969 }\r
68970 }\r
68971 }\r
68972 }\r
68973 }\r
68974});\r
68975\r
68976\r
68977Ext.define('Ext.fx.Runner', {\r
68978
68979 constructor: function() {\r
68980 return new Ext.fx.runner.CssTransition();\r
68981 }\r
68982});\r
68983\r
68984\r
68985Ext.define('Ext.fx.animation.Cube', {\r
68986 extend: Ext.fx.animation.Abstract,\r
68987 alias: 'animation.cube',\r
68988 config: {\r
68989 \r
68990 before: {},\r
68991
68992 after: {},\r
68993 \r
68994 direction: 'right',\r
68995 out: false\r
68996 },\r
68997
68998
68999
69000
69001
69002
69003
69004
69005
69006
69007
69008
69009
69010
69011
69012
69013
69014
69015
69016
69017
69018
69019
69020
69021
69022
69023
69024
69025
69026
69027
69028
69029
69030
69031
69032
69033
69034
69035
69036
69037
69038
69039
69040
69041
69042
69043
69044
69045
69046
69047
69048
69049
69050
69051
69052
69053
69054
69055
69056
69057
69058
69059
69060
69061
69062
69063
69064
69065
69066
69067
69068
69069
69070
69071
69072
69073
69074
69075
69076
69077
69078 getData: function() {\r
69079 var to = this.getTo(),\r
69080 from = this.getFrom(),\r
69081 before = this.getBefore(),\r
69082 after = this.getAfter(),\r
69083 out = this.getOut(),\r
69084 direction = this.getDirection(),\r
69085 el = this.getElement(),\r
69086 elW = el.getWidth(),\r
69087 elH = el.getHeight(),\r
69088 origin = out ? '100% 100%' : '0% 0%',\r
69089 fromOpacity = 1,\r
69090 toOpacity = 1,\r
69091 transformFrom = {\r
69092 rotateY: 0,\r
69093 translateZ: 0\r
69094 },\r
69095 transformTo = {\r
69096 rotateY: 0,\r
69097 translateZ: 0\r
69098 };\r
69099 if (direction == "left" || direction == "right") {\r
69100 if (out) {\r
69101 toOpacity = 0.5;\r
69102 transformTo.translateZ = elW;\r
69103 transformTo.rotateY = -90;\r
69104 } else {\r
69105 fromOpacity = 0.5;\r
69106 transformFrom.translateZ = elW;\r
69107 transformFrom.rotateY = 90;\r
69108 }\r
69109 }\r
69110 before['transform-origin'] = origin;\r
69111 after['transform-origin'] = null;\r
69112 to.set('transform', transformTo);\r
69113 from.set('transform', transformFrom);\r
69114 from.set('opacity', fromOpacity);\r
69115 to.set('opacity', toOpacity);\r
69116 return this.callParent(arguments);\r
69117 }\r
69118});\r
69119\r
69120\r
69121Ext.define('Ext.fx.animation.Wipe', {\r
69122 extend: Ext.fx.Animation,\r
69123 alternateClassName: 'Ext.fx.animation.WipeIn',\r
69124 config: {\r
69125 \r
69126 easing: 'ease-out',\r
69127 \r
69128 direction: 'right',\r
69129 \r
69130 out: false\r
69131 },\r
69132 refresh: function() {\r
69133 var me = this,\r
69134 el = me.getElement(),\r
69135 elBox = el.dom.getBoundingClientRect(),\r
69136 elWidth = elBox.width,\r
69137 elHeight = elBox.height,\r
69138 from = me.getFrom(),\r
69139 to = me.getTo(),\r
69140 out = me.getOut(),\r
69141 direction = me.getDirection(),\r
69142 maskFromX = 0,\r
69143 maskFromY = 0,\r
69144 maskToX = 0,\r
69145 maskToY = 0,\r
69146 mask, tmp;\r
69147 switch (direction) {\r
69148 case 'up':\r
69149 if (out) {\r
69150 mask = '-webkit-gradient(linear, left top, left bottom, from(#000), to(transparent), color-stop(33%, #000), color-stop(66%, transparent))';\r
69151 maskFromY = elHeight * 3 + 'px';\r
69152 maskToY = elHeight + 'px';\r
69153 } else {\r
69154 mask = '-webkit-gradient(linear, left top, left bottom, from(transparent), to(#000), color-stop(66%, #000), color-stop(33%, transparent))';\r
69155 maskFromY = -elHeight * 2 + 'px';\r
69156 maskToY = 0;\r
69157 };\r
69158 break;\r
69159 case 'down':\r
69160 if (out) {\r
69161 mask = '-webkit-gradient(linear, left top, left bottom, from(transparent), to(#000), color-stop(66%, #000), color-stop(33%, transparent))';\r
69162 maskFromY = -elHeight * 2 + 'px';\r
69163 maskToY = 0;\r
69164 } else {\r
69165 mask = '-webkit-gradient(linear, left top, left bottom, from(#000), to(transparent), color-stop(33%, #000), color-stop(66%, transparent))';\r
69166 maskFromY = elHeight * 3 + 'px';\r
69167 maskToY = elHeight + 'px';\r
69168 };\r
69169 break;\r
69170 case 'right':\r
69171 if (out) {\r
69172 mask = '-webkit-gradient(linear, right top, left top, from(#000), to(transparent), color-stop(33%, #000), color-stop(66%, transparent))';\r
69173 maskFromX = -elWidth * 2 + 'px';\r
69174 maskToX = 0;\r
69175 } else {\r
69176 mask = '-webkit-gradient(linear, right top, left top, from(transparent), to(#000), color-stop(66%, #000), color-stop(33%, transparent))';\r
69177 maskToX = -elWidth * 2 + 'px';\r
69178 };\r
69179 break;\r
69180 case 'left':\r
69181 if (out) {\r
69182 mask = '-webkit-gradient(linear, right top, left top, from(transparent), to(#000), color-stop(66%, #000), color-stop(33%, transparent))';\r
69183 maskToX = -elWidth * 2 + 'px';\r
69184 } else {\r
69185 mask = '-webkit-gradient(linear, right top, left top, from(#000), to(transparent), color-stop(33%, #000), color-stop(66%, transparent))';\r
69186 maskFromX = -elWidth * 2 + 'px';\r
69187 maskToX = 0;\r
69188 };\r
69189 break;\r
69190 }\r
69191 if (!out) {\r
69192 tmp = maskFromY;\r
69193 maskFromY = maskToY;\r
69194 maskToY = tmp;\r
69195 tmp = maskFromX;\r
69196 maskFromX = maskToX;\r
69197 maskToX = tmp;\r
69198 }\r
69199 from.set('mask-image', mask);\r
69200 from.set('mask-size', elWidth * 3 + 'px ' + elHeight * 3 + 'px');\r
69201 from.set('mask-position-x', maskFromX);\r
69202 from.set('mask-position-y', maskFromY);\r
69203 to.set('mask-position-x', maskToX);\r
69204 to.set('mask-position-y', maskToY);\r
69205 }\r
69206});\r
69207
69208\r
69209\r
69210Ext.define('Ext.fx.animation.WipeOut', {\r
69211 extend: Ext.fx.animation.Wipe,\r
69212 config: {\r
69213
69214 out: true\r
69215 }\r
69216});\r
69217\r
69218\r
69219Ext.define('Ext.fx.easing.EaseIn', {\r
69220 extend: Ext.fx.easing.Linear,\r
69221 alias: 'easing.ease-in',\r
69222 config: {\r
69223 exponent: 4,\r
69224 duration: 1500\r
69225 },\r
69226 getValue: function() {\r
69227 var deltaTime = Ext.Date.now() - this.getStartTime(),\r
69228 duration = this.getDuration(),\r
69229 startValue = this.getStartValue(),\r
69230 endValue = this.getEndValue(),\r
69231 distance = this.distance,\r
69232 theta = deltaTime / duration,\r
69233 thetaEnd = Math.pow(theta, this.getExponent()),\r
69234 currentValue = startValue + (thetaEnd * distance);\r
69235 if (deltaTime >= duration) {\r
69236 this.isEnded = true;\r
69237 return endValue;\r
69238 }\r
69239 return currentValue;\r
69240 }\r
69241});\r
69242\r
69243\r
69244Ext.define('Ext.fx.easing.Easing', {\r
69245 constructor: function(easing) {\r
69246 return Ext.factory(easing, Ext.fx.easing.Linear, null, 'easing');\r
69247 }\r
69248});\r
69249\r
69250\r
69251Ext.define('Ext.fx.layout.card.Cube', {\r
69252 extend: Ext.fx.layout.card.Style,\r
69253 alias: 'fx.layout.card.cube',\r
69254 config: {\r
69255 reverse: null,\r
69256 inAnimation: {\r
69257 type: 'cube'\r
69258 },\r
69259 outAnimation: {\r
69260 type: 'cube',\r
69261 out: true\r
69262 }\r
69263 }\r
69264});\r
69265\r
69266\r
69267Ext.define('Ext.fx.layout.card.ScrollCover', {\r
69268 extend: Ext.fx.layout.card.Scroll,\r
69269 alias: 'fx.layout.card.scrollcover',\r
69270 onActiveItemChange: function(cardLayout, inItem, outItem, controller) {\r
69271 var containerElement, containerSize, xy, animConfig, inTranslate, outTranslate;\r
69272 this.currentEventController = controller;\r
69273 this.inItem = inItem;\r
69274 if (inItem && outItem) {\r
69275 containerElement = this.getLayout().container.innerElement;\r
69276 containerSize = containerElement.getSize();\r
69277 xy = this.calculateXY(containerSize);\r
69278 animConfig = {\r
69279 easing: this.getEasing(),\r
69280 duration: this.getDuration()\r
69281 };\r
69282 inItem.renderElement.dom.style.setProperty('visibility', 'hidden', 'important');\r
69283 inTranslate = inItem.setTranslatable(true).getTranslatable();\r
69284 outTranslate = outItem.setTranslatable(true).getTranslatable();\r
69285 outTranslate.translate({\r
69286 x: 0,\r
69287 y: 0\r
69288 });\r
69289 inTranslate.translate({\r
69290 x: xy.left,\r
69291 y: xy.top\r
69292 });\r
69293 inTranslate.getWrapper().dom.style.setProperty('z-index', '100', 'important');\r
69294 inItem.show();\r
69295 inTranslate.on({\r
69296 animationstart: 'onInAnimationStart',\r
69297 animationend: 'onInAnimationEnd',\r
69298 scope: this\r
69299 });\r
69300 inTranslate.translateAnimated({\r
69301 x: 0,\r
69302 y: 0\r
69303 }, animConfig);\r
69304 controller.pause();\r
69305 }\r
69306 },\r
69307 onInAnimationStart: function() {\r
69308 this.inItem.renderElement.dom.style.removeProperty('visibility');\r
69309 },\r
69310 onInAnimationEnd: function() {\r
69311 this.inItem.getTranslatable().getWrapper().dom.style.removeProperty('z-index');\r
69312
69313 this.currentEventController.resume();\r
69314 }\r
69315});\r
69316\r
69317\r
69318Ext.define('Ext.fx.layout.card.ScrollReveal', {\r
69319 extend: Ext.fx.layout.card.Scroll,\r
69320 alias: 'fx.layout.card.scrollreveal',\r
69321 onActiveItemChange: function(cardLayout, inItem, outItem, controller) {\r
69322 var containerElement, containerSize, xy, animConfig, outTranslate, inTranslate;\r
69323 this.currentEventController = controller;\r
69324 this.outItem = outItem;\r
69325 this.inItem = inItem;\r
69326 if (inItem && outItem) {\r
69327 containerElement = this.getLayout().container.innerElement;\r
69328 containerSize = containerElement.getSize();\r
69329 xy = this.calculateXY(containerSize);\r
69330 animConfig = {\r
69331 easing: this.getEasing(),\r
69332 duration: this.getDuration()\r
69333 };\r
69334 outTranslate = outItem.setTranslatable(true).getTranslatable();\r
69335 inTranslate = inItem.setTranslatable(true).getTranslatable();\r
69336 outTranslate.getWrapper().dom.style.setProperty('z-index', '100', 'important');\r
69337 outTranslate.translate({\r
69338 x: 0,\r
69339 y: 0\r
69340 });\r
69341 inTranslate.translate({\r
69342 x: 0,\r
69343 y: 0\r
69344 });\r
69345 inItem.show();\r
69346 outTranslate.on({\r
69347 animationend: 'onOutAnimationEnd',\r
69348 scope: this\r
69349 });\r
69350 outTranslate.translateAnimated({\r
69351 x: xy.x,\r
69352 y: xy.y\r
69353 }, animConfig);\r
69354 controller.pause();\r
69355 }\r
69356 },\r
69357 onOutAnimationEnd: function() {\r
69358 this.outItem.getTranslatable().getWrapper().dom.style.removeProperty('z-index');\r
69359
69360 this.currentEventController.resume();\r
69361 }\r
69362});\r
69363\r
69364\r
69365Ext.define('Ext.fx.runner.CssAnimation', {\r
69366 extend: Ext.fx.runner.Css,\r
69367 constructor: function() {\r
69368 this.runningAnimationsMap = {};\r
69369 this.elementEndStates = {};\r
69370 this.animationElementMap = {};\r
69371 this.keyframesRulesCache = {};\r
69372 this.uniqueId = 0;\r
69373 return this.callParent(arguments);\r
69374 },\r
69375 attachListeners: function() {\r
69376 this.listenersAttached = true;\r
69377 Ext.getWin().on({\r
69378 animationstart: 'onAnimationStart',\r
69379 animationend: 'onAnimationEnd',\r
69380 scope: this\r
69381 });\r
69382 },\r
69383 onAnimationStart: function(e) {\r
69384 var name = e.browserEvent.animationName,\r
69385 elementId = this.animationElementMap[name],\r
69386 animation = this.runningAnimationsMap[elementId][name],\r
69387 elementEndStates = this.elementEndStates,\r
69388 elementEndState = elementEndStates[elementId],\r
69389 data = {};\r
69390
69391 if (elementEndState) {\r
69392 delete elementEndStates[elementId];\r
69393 data[elementId] = elementEndState;\r
69394 this.applyStyles(data);\r
69395 }\r
69396 if (animation.before) {\r
69397 data[elementId] = animation.before;\r
69398 this.applyStyles(data);\r
69399 }\r
69400 },\r
69401 onAnimationEnd: function(e) {\r
69402 var element = e.target,\r
69403 name = e.browserEvent.animationName,\r
69404 animationElementMap = this.animationElementMap,\r
69405 elementId = animationElementMap[name],\r
69406 runningAnimationsMap = this.runningAnimationsMap,\r
69407 runningAnimations = runningAnimationsMap[elementId],\r
69408 animation = runningAnimations[name];\r
69409
69410 if (animation.onBeforeEnd) {\r
69411 animation.onBeforeEnd.call(animation.scope || this, element);\r
69412 }\r
69413 if (animation.onEnd) {\r
69414 animation.onEnd.call(animation.scope || this, element);\r
69415 }\r
69416 delete animationElementMap[name];\r
69417 delete runningAnimations[name];\r
69418 this.removeKeyframesRule(name);\r
69419 },\r
69420 generateAnimationId: function() {\r
69421 return 'animation-' + (++this.uniqueId);\r
69422 },\r
69423 run: function(animations) {\r
69424 var data = {},\r
69425 elementEndStates = this.elementEndStates,\r
69426 animationElementMap = this.animationElementMap,\r
69427 runningAnimationsMap = this.runningAnimationsMap,\r
69428 runningAnimations, states, elementId, animationId, i, ln, animation, name, runningAnimation, names, durations, easings, delays, directions, iterations;\r
69429 if (!this.listenersAttached) {\r
69430 this.attachListeners();\r
69431 }\r
69432 animations = Ext.Array.from(animations);\r
69433 for (i = 0 , ln = animations.length; i < ln; i++) {\r
69434 animation = animations[i];\r
69435 animation = Ext.factory(animation, Ext.fx.Animation);\r
69436 elementId = animation.getElement().getId();\r
69437 animationId = animation.getName() || this.generateAnimationId();\r
69438 animationElementMap[animationId] = elementId;\r
69439 animation = animation.getData();\r
69440 states = animation.states;\r
69441 this.addKeyframesRule(animationId, states);\r
69442 runningAnimations = runningAnimationsMap[elementId];\r
69443 if (!runningAnimations) {\r
69444 runningAnimations = runningAnimationsMap[elementId] = {};\r
69445 }\r
69446 runningAnimations[animationId] = animation;\r
69447 names = [];\r
69448 durations = [];\r
69449 easings = [];\r
69450 delays = [];\r
69451 directions = [];\r
69452 iterations = [];\r
69453 for (name in runningAnimations) {\r
69454 if (runningAnimations.hasOwnProperty(name)) {\r
69455 runningAnimation = runningAnimations[name];\r
69456 names.push(name);\r
69457 durations.push(runningAnimation.duration);\r
69458 easings.push(runningAnimation.easing);\r
69459 delays.push(runningAnimation.delay);\r
69460 directions.push(runningAnimation.direction);\r
69461 iterations.push(runningAnimation.iteration);\r
69462 }\r
69463 }\r
69464 data[elementId] = {\r
69465 'animation-name': names,\r
69466 'animation-duration': durations,\r
69467 'animation-timing-function': easings,\r
69468 'animation-delay': delays,\r
69469 'animation-direction': directions,\r
69470 'animation-iteration-count': iterations\r
69471 };\r
69472
69473 if (animation.preserveEndState) {\r
69474 elementEndStates[elementId] = states['100%'];\r
69475 }\r
69476 }\r
69477 this.applyStyles(data);\r
69478 },\r
69479 addKeyframesRule: function(name, keyframes) {\r
69480 var percentage, properties, keyframesRule, styleSheet, rules, styles, rulesLength, key, value;\r
69481 styleSheet = this.getStyleSheet();\r
69482 rules = styleSheet.cssRules;\r
69483 rulesLength = rules.length;\r
69484 styleSheet.insertRule('@' + this.vendorPrefix + 'keyframes ' + name + '{}', rulesLength);\r
69485 keyframesRule = rules[rulesLength];\r
69486 for (percentage in keyframes) {\r
69487 properties = keyframes[percentage];\r
69488 rules = keyframesRule.cssRules;\r
69489 rulesLength = rules.length;\r
69490 styles = [];\r
69491 for (key in properties) {\r
69492 value = this.formatValue(properties[key], key);\r
69493 key = this.formatName(key);\r
69494 styles.push(key + ':' + value);\r
69495 }\r
69496 keyframesRule.insertRule(percentage + '{' + styles.join(';') + '}', rulesLength);\r
69497 }\r
69498 return this;\r
69499 },\r
69500 removeKeyframesRule: function(name) {\r
69501 var styleSheet = this.getStyleSheet(),\r
69502 rules = styleSheet.cssRules,\r
69503 i, ln, rule;\r
69504 for (i = 0 , ln = rules.length; i < ln; i++) {\r
69505 rule = rules[i];\r
69506 if (rule.name === name) {\r
69507 styleSheet.removeRule(i);\r
69508 break;\r
69509 }\r
69510 }\r
69511 return this;\r
69512 }\r
69513});\r
69514\r
69515\r
69516Ext.define('Ext.list.AbstractTreeItem', {\r
69517 extend: Ext.Widget,\r
69518 isTreeListItem: true,\r
69519 \r
69520 \r
69521 \r
69522 \r
69523 \r
69524 \r
69525 \r
69526 \r
69527 \r
69528 cachedConfig: {\r
69529 \r
69530 expandable: false,\r
69531 \r
69532 expanded: false,\r
69533 \r
69534 floated: false,\r
69535 \r
69536 iconCls: '',\r
69537 \r
69538 leaf: true,\r
69539 \r
69540 loading: false,\r
69541 \r
69542 selected: false,\r
69543 \r
69544 selectedParent: false\r
69545 },\r
69546 config: {\r
69547 \r
69548 iconClsProperty: 'iconCls',\r
69549 indent: null,\r
69550 \r
69551 owner: null,\r
69552 \r
69553 node: null,\r
69554 \r
69555 over: null,\r
69556 \r
69557 parentItem: null,\r
69558 \r
69559 text: {\r
69560 lazy: true,\r
69561 $value: ''\r
69562 },\r
69563 \r
69564 textProperty: 'text'\r
69565 },\r
69566 updateNode: function(node) {\r
69567 if (node) {\r
69568 var me = this,\r
69569 map = me.itemMap,\r
69570 childNodes, owner, len, i, item, child;\r
69571 me.element.dom.setAttribute('data-recordId', node.internalId);\r
69572 if (!map) {\r
69573 childNodes = node.childNodes;\r
69574 owner = me.getOwner();\r
69575 me.itemMap = map = {};\r
69576 for (i = 0 , len = childNodes.length; i < len; ++i) {\r
69577 child = childNodes[i];\r
69578 item = owner.createItem(child, me);\r
69579 map[child.internalId] = item;\r
69580 me.insertItem(item, null);\r
69581 }\r
69582 }\r
69583 me.setExpanded(node.isExpanded());\r
69584 me.doNodeUpdate(node);\r
69585 }\r
69586 },\r
69587 updateSelected: function(selected) {\r
69588 if (!this.isConfiguring) {\r
69589 var parent = this.getParentItem();\r
69590 while (parent && !parent.isRootListItem) {\r
69591 parent.setSelectedParent(selected);\r
69592 parent = parent.getParentItem();\r
69593 }\r
69594 }\r
69595 },\r
69596 \r
69597 collapse: function() {\r
69598 this.getNode().collapse();\r
69599 },\r
69600 \r
69601 expand: function() {\r
69602 this.getNode().expand();\r
69603 },\r
69604 \r
69605 getToolElement: Ext.emptyFn,\r
69606 \r
69607 insertItem: Ext.emptyFn,\r
69608 \r
69609 isExpanded: function() {\r
69610 return this.getExpanded();\r
69611 },\r
69612 \r
69613 isSelectionEvent: Ext.emptyFn,\r
69614 \r
69615 isToggleEvent: Ext.emptyFn,\r
69616 \r
69617 nodeCollapse: function(node, collapsingForExpand) {\r
69618 var me = this,\r
69619 owner = me.getOwner(),\r
69620 animation = me.preventAnimation ? null : owner.getAnimation();\r
69621 me.nodeCollapseBegin(animation, collapsingForExpand);\r
69622 if (!animation) {\r
69623 me.nodeCollapseEnd(collapsingForExpand);\r
69624 }\r
69625 },\r
69626 nodeCollapseBegin: function(animation, collapsingForExpand) {\r
69627 var me = this,\r
69628 owner = me.getOwner();\r
69629 me.setExpanded(false);\r
69630 owner.fireEvent('itemcollapse', owner, me);\r
69631 },\r
69632 nodeCollapseEnd: function(collapsingForExpand) {\r
69633 if (!collapsingForExpand) {\r
69634 this.getOwner().updateLayout();\r
69635 }\r
69636 },\r
69637 \r
69638 nodeExpand: function(node) {\r
69639 var me = this,\r
69640 owner = me.getOwner(),\r
69641 floated = me.getFloated(),\r
69642 animation = !floated && owner.getAnimation();\r
69643 me.nodeExpandBegin(animation);\r
69644 if (!animation) {\r
69645 me.nodeExpandEnd();\r
69646 }\r
69647 },\r
69648 nodeExpandBegin: function(animation) {\r
69649 var me = this,\r
69650 owner = me.getOwner();\r
69651 me.setExpanded(true);\r
69652 owner.fireEvent('itemexpand', owner, me);\r
69653 },\r
69654 nodeExpandEnd: function() {\r
69655 this.getOwner().updateLayout();\r
69656 },\r
69657 \r
69658 nodeInsert: function(node, refNode) {\r
69659 var me = this,\r
69660 owner = me.getOwner(),\r
69661 map = me.itemMap,\r
69662 id = node.internalId,\r
69663 item = owner.getItem(node),\r
69664 refItem = null,\r
69665 oldParent;\r
69666 if (item) {\r
69667 oldParent = item.getParentItem();\r
69668
69669 oldParent.removeItem(item);\r
69670 if (oldParent !== me) {\r
69671 oldParent.doUpdateExpandable();\r
69672 item.setParentItem(me);\r
69673 }\r
69674 } else {\r
69675 item = me.getOwner().createItem(node, me);\r
69676 }\r
69677 map[id] = item;\r
69678 if (refNode) {\r
69679 refItem = map[refNode.internalId];\r
69680 }\r
69681 me.insertItem(item, refItem);\r
69682 me.doUpdateExpandable();\r
69683 owner.fireEvent('iteminsert', owner, me, item, refItem);\r
69684 owner.updateLayout();\r
69685 },\r
69686 \r
69687 nodeRemove: function(node) {\r
69688 var me = this,\r
69689 map = me.itemMap,\r
69690 owner = me.getOwner(),\r
69691 id = node.internalId,\r
69692 item = map[id];\r
69693 if (item) {\r
69694 delete map[id];\r
69695 me.removeItem(item);\r
69696 item.destroy();\r
69697 me.doUpdateExpandable();\r
69698 owner.fireEvent('itemremove', owner, me, item);\r
69699 owner.updateLayout();\r
69700 }\r
69701 },\r
69702 \r
69703 nodeUpdate: function(node, modifiedFieldNames) {\r
69704 this.doNodeUpdate(node);\r
69705 },\r
69706 \r
69707 removeItem: Ext.emptyFn,\r
69708 updateFloated: function(floated) {\r
69709 var me = this,\r
69710 el = me.element,\r
69711 placeholder = me.placeholder,\r
69712 node, wasExpanded;\r
69713 if (floated) {\r
69714 placeholder = el.clone(false, true);\r
69715
69716 placeholder.id += '-placeholder';\r
69717
69718 me.placeholder = Ext.get(placeholder);\r
69719 me.wasExpanded = me.getExpanded();\r
69720 me.setExpanded(true);\r
69721 el.dom.parentNode.insertBefore(placeholder, el.dom);\r
69722 me.floater = me.createFloater();\r
69723 }\r
69724
69725 else if (placeholder) {\r
69726 wasExpanded = me.wasExpanded;\r
69727 node = me.getNode();\r
69728 me.setExpanded(wasExpanded);\r
69729 if (!wasExpanded && node.isExpanded()) {\r
69730
69731
69732 me.preventAnimation = true;\r
69733 node.collapse();\r
69734 me.preventAnimation = false;\r
69735 }\r
69736 me.floater.remove(me, false);\r
69737
69738 placeholder.dom.parentNode.insertBefore(el.dom, placeholder.dom);\r
69739 placeholder.destroy();\r
69740 me.floater.destroy();\r
69741 me.placeholder = me.floater = null;\r
69742 me.floatedByHover = false;\r
69743 }\r
69744 },\r
69745 \r
69746 destroy: function() {\r
69747 var me = this,\r
69748 map = me.itemMap,\r
69749 owner = me.getOwner(),\r
69750 key;\r
69751 if (map) {\r
69752 for (key in map) {\r
69753 map[key].destroy();\r
69754 }\r
69755 me.itemMap = null;\r
69756 }\r
69757 if (owner) {\r
69758 owner.removeItem(me.getNode());\r
69759 }\r
69760 me.setNode(null);\r
69761 me.setParentItem(null);\r
69762 me.setOwner(null);\r
69763 me.callParent();\r
69764 },\r
69765 privates: {\r
69766 \r
69767 doNodeUpdate: function(node) {\r
69768 var me = this,\r
69769 textProperty = this.getTextProperty(),\r
69770 iconClsProperty = this.getIconClsProperty();\r
69771 if (textProperty) {\r
69772 me.setText(node.data[textProperty]);\r
69773 }\r
69774 if (iconClsProperty) {\r
69775 me.setIconCls(node.data[iconClsProperty]);\r
69776 }\r
69777 me.setLoading(node.isLoading());\r
69778 me.setLeaf(node.isLeaf());\r
69779 me.doUpdateExpandable();\r
69780 },\r
69781 doUpdateExpandable: function() {\r
69782 var node = this.getNode();\r
69783 this.setExpandable(node.isExpandable());\r
69784 },\r
69785 \r
69786 onClick: function(e) {\r
69787 var me = this,\r
69788 owner = me.getOwner(),\r
69789 node = me.getNode(),\r
69790 info = {\r
69791 event: e,\r
69792 item: me,\r
69793 node: node,\r
69794 tree: owner,\r
69795 select: node.get('selectable') !== false && me.isSelectionEvent(e),\r
69796 toggle: me.isToggleEvent(e)\r
69797 };\r
69798 \r
69799 if (owner.fireEvent('itemclick', owner, info) !== false) {\r
69800 if (info.toggle) {\r
69801 me.toggleExpanded();\r
69802 }\r
69803 if (info.select) {\r
69804 owner.setSelection(me.getNode());\r
69805 }\r
69806 }\r
69807 },\r
69808 toggleExpanded: function() {\r
69809 if (this.isExpanded()) {\r
69810 this.collapse();\r
69811 } else {\r
69812 this.expand();\r
69813 }\r
69814 },\r
69815 updateIndent: function(value) {\r
69816 var items = this.itemMap,\r
69817 id;\r
69818 for (id in items) {\r
69819 items[id].setIndent(value);\r
69820 }\r
69821 }\r
69822 }\r
69823});\r
69824\r
69825\r
69826Ext.define('Ext.list.RootTreeItem', {\r
69827 extend: Ext.list.AbstractTreeItem,\r
69828 \r
69829 isRootListItem: true,\r
69830 element: {\r
69831 reference: 'element',\r
69832 tag: 'ul',\r
69833 cls: Ext.baseCSSPrefix + 'treelist-root-container'\r
69834 },\r
69835 insertItem: function(item, refItem) {\r
69836 if (refItem) {\r
69837 item.element.insertBefore(refItem.element);\r
69838 } else {\r
69839 this.element.appendChild(item.element);\r
69840 }\r
69841 },\r
69842 isToggleEvent: function(e) {\r
69843 return false;\r
69844 }\r
69845});\r
69846\r
69847\r
69848Ext.define('Ext.list.TreeItem', {\r
69849 extend: Ext.list.AbstractTreeItem,\r
69850 xtype: 'treelistitem',\r
69851 collapsedCls: Ext.baseCSSPrefix + 'treelist-item-collapsed',\r
69852 expandedCls: Ext.baseCSSPrefix + 'treelist-item-expanded',\r
69853 floatedCls: Ext.baseCSSPrefix + 'treelist-item-floated',\r
69854 floatedToolCls: Ext.baseCSSPrefix + 'treelist-item-tool-floated',\r
69855 leafCls: Ext.baseCSSPrefix + 'treelist-item-leaf',\r
69856 expandableCls: Ext.baseCSSPrefix + 'treelist-item-expandable',\r
69857 hideIconCls: Ext.baseCSSPrefix + 'treelist-item-hide-icon',\r
69858 loadingCls: Ext.baseCSSPrefix + 'treelist-item-loading',\r
69859 selectedCls: Ext.baseCSSPrefix + 'treelist-item-selected',\r
69860 selectedParentCls: Ext.baseCSSPrefix + 'treelist-item-selected-parent',\r
69861 withIconCls: Ext.baseCSSPrefix + 'treelist-item-with-icon',\r
69862 hoverCls: Ext.baseCSSPrefix + 'treelist-item-over',\r
69863 rowHoverCls: Ext.baseCSSPrefix + 'treelist-row-over',\r
69864 \r
69865 isTreeListItem: true,\r
69866 config: {\r
69867 \r
69868 rowCls: null\r
69869 },\r
69870 \r
69871 rowClsProperty: 'rowCls',\r
69872 element: {\r
69873 reference: 'element',\r
69874 tag: 'li',\r
69875 cls: Ext.baseCSSPrefix + 'treelist-item',\r
69876 children: [\r
69877 {\r
69878 reference: 'rowElement',\r
69879 cls: Ext.baseCSSPrefix + 'treelist-row',\r
69880 children: [\r
69881 {\r
69882 reference: 'wrapElement',\r
69883 cls: Ext.baseCSSPrefix + 'treelist-item-wrap',\r
69884 children: [\r
69885 {\r
69886 reference: 'iconElement',\r
69887 cls: Ext.baseCSSPrefix + 'treelist-item-icon'\r
69888 },\r
69889 {\r
69890 reference: 'textElement',\r
69891 cls: Ext.baseCSSPrefix + 'treelist-item-text'\r
69892 },\r
69893 {\r
69894 reference: 'expanderElement',\r
69895 cls: Ext.baseCSSPrefix + 'treelist-item-expander'\r
69896 }\r
69897 ]\r
69898 }\r
69899 ]\r
69900 },\r
69901 {\r
69902 reference: 'itemContainer',\r
69903 tag: 'ul',\r
69904 cls: Ext.baseCSSPrefix + 'treelist-container'\r
69905 },\r
69906 {\r
69907 reference: 'toolElement',\r
69908 cls: Ext.baseCSSPrefix + 'treelist-item-tool'\r
69909 }\r
69910 ]\r
69911 },\r
69912 constructor: function(config) {\r
69913 this.callParent([\r
69914 config\r
69915 ]);\r
69916 var toolDom = this.toolElement.dom;\r
69917
69918
69919 toolDom.parentNode.removeChild(toolDom);\r
69920 },\r
69921 getToolElement: function() {\r
69922 return this.toolElement;\r
69923 },\r
69924 insertItem: function(item, refItem) {\r
69925 if (refItem) {\r
69926 item.element.insertBefore(refItem.element);\r
69927 } else {\r
69928 this.itemContainer.appendChild(item.element);\r
69929 }\r
69930 },\r
69931 isSelectionEvent: function(e) {\r
69932 var owner = this.getOwner();\r
69933 return (!this.isToggleEvent(e) || !owner.getExpanderOnly() || owner.getSelectOnExpander());\r
69934 },\r
69935 isToggleEvent: function(e) {\r
69936 var isExpand = false;\r
69937 if (this.getOwner().getExpanderOnly()) {\r
69938 isExpand = e.target === this.expanderElement.dom;\r
69939 } else {\r
69940
69941 isExpand = !this.itemContainer.contains(e.target);\r
69942 }\r
69943 return isExpand;\r
69944 },\r
69945 nodeCollapseBegin: function(animation, collapsingForExpand) {\r
69946 var me = this,\r
69947 itemContainer = me.itemContainer,\r
69948 height;\r
69949 if (me.expanding) {\r
69950 me.stopAnimation(me.expanding);\r
69951 }\r
69952
69953
69954
69955 height = animation && itemContainer.getHeight();\r
69956 me.callParent([\r
69957 animation,\r
69958 collapsingForExpand\r
69959 ]);\r
69960 if (animation) {\r
69961
69962 itemContainer.dom.style.display = 'block';\r
69963 me.collapsingForExpand = collapsingForExpand;\r
69964 me.collapsing = this.runAnimation(Ext.merge({\r
69965 from: {\r
69966 height: height\r
69967 },\r
69968 to: {\r
69969 height: 0\r
69970 },\r
69971 callback: me.nodeCollapseDone,\r
69972 scope: me\r
69973 }, animation));\r
69974 }\r
69975 },\r
69976 nodeCollapseDone: function(animation) {\r
69977 var me = this,\r
69978 itemContainer = me.itemContainer;\r
69979 me.collapsing = null;\r
69980 itemContainer.dom.style.display = '';\r
69981 itemContainer.setHeight(null);\r
69982 me.nodeCollapseEnd(me.collapsingForExpand);\r
69983 },\r
69984 nodeExpandBegin: function(animation) {\r
69985 var me = this,\r
69986 itemContainer = me.itemContainer,\r
69987 height;\r
69988 if (me.collapsing) {\r
69989 me.stopAnimation(me.collapsing);\r
69990 }\r
69991 me.callParent([\r
69992 animation\r
69993 ]);\r
69994 if (animation) {\r
69995
69996 height = itemContainer.getHeight();\r
69997 itemContainer.setHeight(0);\r
69998 me.expanding = me.runAnimation(Ext.merge({\r
69999 to: {\r
70000 height: height\r
70001 },\r
70002 callback: me.nodeExpandDone,\r
70003 scope: me\r
70004 }, animation));\r
70005 }\r
70006 },\r
70007 nodeExpandDone: function() {\r
70008 this.expanding = null;\r
70009 this.itemContainer.setHeight(null);\r
70010 this.nodeExpandEnd();\r
70011 },\r
70012 removeItem: function(item) {\r
70013 this.itemContainer.removeChild(item.element);\r
70014 },\r
70015
70016
70017 updateNode: function(node, oldNode) {\r
70018 this.syncIndent();\r
70019 this.callParent([\r
70020 node,\r
70021 oldNode\r
70022 ]);\r
70023 },\r
70024 updateExpandable: function() {\r
70025 this.updateExpandCls();\r
70026 },\r
70027 updateExpanded: function() {\r
70028 this.updateExpandCls();\r
70029 },\r
70030 updateFloated: function(floated, wasFloated) {\r
70031 var me = this;\r
70032 me.callParent([\r
70033 floated,\r
70034 wasFloated\r
70035 ]);\r
70036 me.element.toggleCls(me.floatedCls, floated);\r
70037 me.toolElement.toggleCls(me.floatedToolCls, floated);\r
70038 },\r
70039 updateIconCls: function(iconCls, oldIconCls) {\r
70040 var me = this,\r
70041 el = me.element;\r
70042 me.doIconCls(me.iconElement, iconCls, oldIconCls);\r
70043 me.doIconCls(me.toolElement, iconCls, oldIconCls);\r
70044 el.toggleCls(me.withIconCls, !!iconCls);\r
70045 el.toggleCls(me.hideIconCls, iconCls === null);\r
70046 },\r
70047 updateLeaf: function(leaf) {\r
70048 this.element.toggleCls(this.leafCls, leaf);\r
70049 },\r
70050 updateLoading: function(loading) {\r
70051 this.element.toggleCls(this.loadingCls, loading);\r
70052 },\r
70053 updateOver: function(over) {\r
70054 var me = this;\r
70055 me.element.toggleCls(me.hoverCls, !!over);\r
70056
70057 me.rowElement.toggleCls(me.rowHoverCls, over > 1);\r
70058 },\r
70059
70060 updateRowCls: function(value, oldValue) {\r
70061 this.rowElement.replaceCls(oldValue, value);\r
70062 },\r
70063 updateSelected: function(selected, oldSelected) {\r
70064 var me = this,\r
70065 cls = me.selectedCls,\r
70066 tool = me.getToolElement();\r
70067 me.callParent([\r
70068 selected,\r
70069 oldSelected\r
70070 ]);\r
70071 me.element.toggleCls(cls, selected);\r
70072 if (tool) {\r
70073 tool.toggleCls(cls, selected);\r
70074 }\r
70075 },\r
70076 updateSelectedParent: function(selectedParent) {\r
70077 var me = this;\r
70078 me.element.toggleCls(me.selectedParentCls, selectedParent);\r
70079 var tool = me.getToolElement();\r
70080 if (tool) {\r
70081 tool.toggleCls(me.selectedCls, selectedParent);\r
70082 }\r
70083 },\r
70084 updateText: function(text) {\r
70085 this.textElement.update(text);\r
70086 },\r
70087
70088
70089 privates: {\r
70090 doNodeUpdate: function(node) {\r
70091 this.callParent([\r
70092 node\r
70093 ]);\r
70094 this.setRowCls(node && node.data[this.rowClsProperty]);\r
70095 },\r
70096 doIconCls: function(element, iconCls, oldIconCls) {\r
70097 if (oldIconCls) {\r
70098 element.removeCls(oldIconCls);\r
70099 }\r
70100 if (iconCls) {\r
70101 element.addCls(iconCls);\r
70102 }\r
70103 },\r
70104 syncIndent: function() {\r
70105 var me = this,\r
70106 indent = me.getIndent(),\r
70107 node = me.getNode(),\r
70108 depth;\r
70109 if (node) {\r
70110 depth = node.data.depth - 1;\r
70111 me.wrapElement.dom.style.marginLeft = (depth * indent) + 'px';\r
70112 }\r
70113 },\r
70114 updateExpandCls: function() {\r
70115 if (!this.updatingExpandCls) {\r
70116 var me = this,\r
70117 expandable = me.getExpandable(),\r
70118 element = me.element,\r
70119 expanded = me.getExpanded(),\r
70120 expandedCls = me.expandedCls,\r
70121 collapsedCls = me.collapsedCls;\r
70122 me.updatingExpandCls = true;\r
70123 element.toggleCls(me.expandableCls, expandable);\r
70124 if (expandable) {\r
70125 element.toggleCls(expandedCls, expanded);\r
70126 element.toggleCls(collapsedCls, !expanded);\r
70127 } else {\r
70128 element.removeCls([\r
70129 expandedCls,\r
70130 collapsedCls\r
70131 ]);\r
70132 }\r
70133 me.updatingExpandCls = false;\r
70134 }\r
70135 },\r
70136 updateIndent: function(value, oldValue) {\r
70137 this.syncIndent();\r
70138 this.callParent([\r
70139 value,\r
70140 oldValue\r
70141 ]);\r
70142 }\r
70143 }\r
70144});\r
70145\r
70146Ext.define('Ext.overrides.list.TreeItem', {\r
70147 override: 'Ext.list.TreeItem',\r
70148 createFloater: function() {\r
70149 var me = this,\r
70150 owner = me.getOwner(),\r
70151 ui = owner.getUi(),\r
70152 cls = Ext.baseCSSPrefix + 'treelist',\r
70153 floater;\r
70154 if (ui) {\r
70155 cls += ' ' + cls + '-' + ui;\r
70156 }\r
70157 me.floater = floater = new Ext.Container({\r
70158 cls: cls + ' ' + Ext.baseCSSPrefix + 'treelist-floater',\r
70159 width: 200,\r
70160 top: 0,\r
70161 listeners: {\r
70162 element: 'element',\r
70163 click: function(e) {\r
70164 return owner.onClick(e);\r
70165 }\r
70166 }\r
70167 });\r
70168 Ext.Viewport.add(floater);\r
70169 floater.add(me);\r
70170 floater.alignTo(me.getToolElement(), 'tl-tr');\r
70171 return floater;\r
70172 },\r
70173 runAnimation: function(animation) {\r
70174 return this.itemContainer.animate(animation);\r
70175 },\r
70176 stopAnimation: function(animation) {\r
70177 animation.end();\r
70178 }\r
70179});\r
70180\r
70181\r
70182Ext.define('Ext.list.Tree', {\r
70183 extend: Ext.Widget,\r
70184 xtype: 'treelist',\r
70185 expanderFirstCls: Ext.baseCSSPrefix + 'treelist-expander-first',\r
70186 expanderOnlyCls: Ext.baseCSSPrefix + 'treelist-expander-only',\r
70187 highlightPathCls: Ext.baseCSSPrefix + 'treelist-highlight-path',\r
70188 microCls: Ext.baseCSSPrefix + 'treelist-micro',\r
70189 uiPrefix: Ext.baseCSSPrefix + 'treelist-',\r
70190 element: {\r
70191 reference: 'element',\r
70192 cls: Ext.baseCSSPrefix + 'treelist ' + Ext.baseCSSPrefix + 'unselectable',\r
70193 listeners: {\r
70194 click: 'onClick',\r
70195 mouseenter: 'onMouseEnter',\r
70196 mouseleave: 'onMouseLeave',\r
70197 mouseover: 'onMouseOver'\r
70198 },\r
70199 children: [\r
70200 {\r
70201 reference: 'toolsElement',\r
70202 cls: Ext.baseCSSPrefix + 'treelist-toolstrip',\r
70203 listeners: {\r
70204 click: 'onToolStripClick',\r
70205 mouseover: 'onToolStripMouseOver'\r
70206 }\r
70207 }\r
70208 ]\r
70209 },\r
70210 cachedConfig: {\r
70211 animation: {\r
70212 duration: 500,\r
70213 easing: 'ease'\r
70214 },\r
70215 expanderFirst: true,\r
70216 \r
70217 expanderOnly: true\r
70218 },\r
70219 config: {\r
70220 \r
70221 defaults: {\r
70222 xtype: 'treelistitem'\r
70223 },\r
70224 highlightPath: null,\r
70225 iconSize: null,\r
70226 indent: null,\r
70227 micro: null,\r
70228 overItem: null,\r
70229 \r
70230 selection: null,\r
70231 \r
70232 selectOnExpander: false,\r
70233 \r
70234 singleExpand: null,\r
70235 \r
70236 store: null,\r
70237 ui: null\r
70238 },\r
70239 twoWayBindable: {\r
70240 selection: 1\r
70241 },\r
70242 publishes: {\r
70243 selection: 1\r
70244 },\r
70245 defaultBindProperty: 'store',\r
70246 constructor: function(config) {\r
70247 this.callParent([\r
70248 config\r
70249 ]);\r
70250
70251
70252 this.publishState('selection', this.getSelection());\r
70253 },\r
70254 beforeLayout: function() {\r
70255
70256 this.syncIconSize();\r
70257 },\r
70258 destroy: function() {\r
70259 var me = this;\r
70260 me.destroying = true;\r
70261
70262 me.unfloatAll();\r
70263 me.activeFloater = null;\r
70264 me.setSelection(null);\r
70265 me.setStore(null);\r
70266 me.callParent();\r
70267 },\r
70268 updateOverItem: function(over, wasOver) {\r
70269 var map = {},\r
70270 state = 2,\r
70271 c, node;\r
70272
70273
70274
70275 for (c = over; c; c = this.getItem(node.parentNode)) {\r
70276 node = c.getNode();\r
70277 map[node.internalId] = true;\r
70278 c.setOver(state);\r
70279 state = 1;\r
70280 }\r
70281 if (wasOver) {\r
70282
70283
70284
70285
70286 for (c = wasOver; c; c = this.getItem(node.parentNode)) {\r
70287 node = c.getNode();\r
70288 if (map[node.internalId]) {\r
70289 break;\r
70290 }\r
70291 c.setOver(0);\r
70292 }\r
70293 }\r
70294 },\r
70295 applySelection: function(selection, oldSelection) {\r
70296 var store = this.getStore();\r
70297 if (!store) {\r
70298 selection = null;\r
70299 }\r
70300 if (selection && selection.get('selectable') === false) {\r
70301 selection = oldSelection;\r
70302 }\r
70303 return selection;\r
70304 },\r
70305 updateSelection: function(selection, oldSelection) {\r
70306 var me = this,\r
70307 item;\r
70308 if (!me.destroying) {\r
70309
70310
70311 item = me.getItem(oldSelection);\r
70312 if (item) {\r
70313 item.setSelected(false);\r
70314 }\r
70315 item = me.getItem(selection);\r
70316 if (item) {\r
70317 item.setSelected(true);\r
70318 }\r
70319 me.fireEvent('selectionchange', me, selection);\r
70320 }\r
70321 },\r
70322 applyStore: function(store) {\r
70323 return store && Ext.StoreManager.lookup(store, 'tree');\r
70324 },\r
70325 updateStore: function(store, oldStore) {\r
70326 var me = this,\r
70327 root;\r
70328 if (oldStore) {\r
70329 if (oldStore.getAutoDestroy()) {\r
70330 oldStore.destroy();\r
70331 } else {\r
70332 me.storeListeners.destroy();\r
70333 }\r
70334 me.removeRoot();\r
70335 me.storeListeners = null;\r
70336 }\r
70337 if (store) {\r
70338 me.storeListeners = store.on({\r
70339 destroyable: true,\r
70340 scope: me,\r
70341 nodeappend: me.onNodeAppend,\r
70342 nodecollapse: me.onNodeCollapse,\r
70343 nodeexpand: me.onNodeExpand,\r
70344 nodeinsert: me.onNodeInsert,\r
70345 noderemove: me.onNodeRemove,\r
70346 rootchange: me.onRootChange,\r
70347 update: me.onNodeUpdate\r
70348 });\r
70349 root = store.getRoot();\r
70350 if (root) {\r
70351 me.createRootItem(root);\r
70352 }\r
70353 }\r
70354 if (!me.destroying) {\r
70355 me.updateLayout();\r
70356 }\r
70357 },\r
70358 updateExpanderFirst: function(expanderFirst) {\r
70359 this.element.toggleCls(this.expanderFirstCls, expanderFirst);\r
70360 },\r
70361 updateExpanderOnly: function(value) {\r
70362 this.element.toggleCls(this.expanderOnlyCls, !value);\r
70363 },\r
70364 updateHighlightPath: function(updatePath) {\r
70365 this.element.toggleCls(this.highlightPathCls, updatePath);\r
70366 },\r
70367 updateMicro: function(micro) {\r
70368 var me = this;\r
70369 if (!micro) {\r
70370 me.unfloatAll();\r
70371 me.activeFloater = null;\r
70372 }\r
70373 me.element.toggleCls(me.microCls, micro);\r
70374 },\r
70375 updateUi: function(ui, oldValue) {\r
70376 var el = this.element,\r
70377 uiPrefix = this.uiPrefix;\r
70378 if (oldValue) {\r
70379 el.removeCls(uiPrefix + oldValue);\r
70380 }\r
70381 if (ui) {\r
70382 el.addCls(uiPrefix + ui);\r
70383 }\r
70384
70385 delete this.iconSize;\r
70386 this.syncIconSize();\r
70387 },\r
70388 \r
70389 getItem: function(node) {\r
70390 var map = this.itemMap,\r
70391 ret;\r
70392 if (node && map) {\r
70393 ret = map[node.internalId];\r
70394 }\r
70395 return ret || null;\r
70396 },\r
70397 \r
70398 getItemConfig: function(node, parent) {\r
70399 return Ext.apply({\r
70400 parentItem: parent.isRootListItem ? null : parent,\r
70401 owner: this,\r
70402 node: node,\r
70403 indent: this.getIndent()\r
70404 }, this.getDefaults());\r
70405 },\r
70406 privates: {\r
70407 checkForOutsideClick: function(e) {\r
70408 var floater = this.activeFloater;\r
70409 if (!floater.element.contains(e.target)) {\r
70410 this.unfloatAll();\r
70411 }\r
70412 },\r
70413 collapsingForExpand: false,\r
70414 \r
70415 createItem: function(node, parent) {\r
70416 var item = Ext.create(this.getItemConfig(node, parent)),\r
70417 toolEl;\r
70418 if (parent.isRootListItem) {\r
70419 toolEl = item.getToolElement();\r
70420 if (toolEl) {\r
70421 this.toolsElement.appendChild(toolEl);\r
70422 toolEl.dom.setAttribute('data-recordId', node.internalId);\r
70423 toolEl.isTool = true;\r
70424 }\r
70425 }\r
70426 return (this.itemMap[node.internalId] = item);\r
70427 },\r
70428
70429 \r
70430 createRootItem: function(root) {\r
70431 var me = this,\r
70432 item;\r
70433 me.itemMap = {};\r
70434 me.rootItem = item = new Ext.list.RootTreeItem({\r
70435 indent: me.getIndent(),\r
70436 node: root,\r
70437 owner: me\r
70438 });\r
70439 me.element.appendChild(item.element);\r
70440 me.itemMap[root.internalId] = item;\r
70441 },\r
70442 floatItem: function(item, byHover) {\r
70443 var me = this,\r
70444 floater;\r
70445 if (item.getFloated()) {\r
70446 return;\r
70447 }\r
70448 me.unfloatAll();\r
70449 me.activeFloater = floater = item;\r
70450 me.floatedByHover = byHover;\r
70451 item.setFloated(true);\r
70452 if (byHover) {\r
70453 item.getToolElement().on('mouseleave', me.checkForMouseLeave, me);\r
70454 floater.element.on('mouseleave', me.checkForMouseLeave, me);\r
70455 } else {\r
70456 Ext.on('mousedown', me.checkForOutsideClick, me);\r
70457 }\r
70458 },\r
70459 \r
70460 onClick: function(e) {\r
70461 var item = e.getTarget('[data-recordId]'),\r
70462 id;\r
70463 if (item) {\r
70464 id = item.getAttribute('data-recordId');\r
70465 item = this.itemMap[id];\r
70466 if (item) {\r
70467 item.onClick(e);\r
70468 }\r
70469 }\r
70470 },\r
70471 onMouseEnter: function(e) {\r
70472 this.onMouseOver(e);\r
70473 },\r
70474 onMouseLeave: function() {\r
70475 this.setOverItem(null);\r
70476 },\r
70477 onMouseOver: function(e) {\r
70478 var comp = Ext.Component.fromElement(e.getTarget());\r
70479 this.setOverItem(comp && comp.isTreeListItem && comp);\r
70480 },\r
70481 checkForMouseLeave: function(e) {\r
70482 var floater = this.activeFloater,\r
70483 relatedTarget = e.getRelatedTarget();\r
70484 if (floater) {\r
70485 if (relatedTarget !== floater.getToolElement().dom && !floater.element.contains(relatedTarget)) {\r
70486 this.unfloatAll();\r
70487 }\r
70488 }\r
70489 },\r
70490 \r
70491 onNodeAppend: function(parentNode, node) {\r
70492
70493 if (parentNode) {\r
70494 var item = this.itemMap[parentNode.internalId];\r
70495 if (item) {\r
70496 item.nodeInsert(node, null);\r
70497 }\r
70498 }\r
70499 },\r
70500 \r
70501 onNodeCollapse: function(node) {\r
70502 var item = this.itemMap[node.internalId];\r
70503 if (item) {\r
70504 item.nodeCollapse(node, this.collapsingForExpand);\r
70505 }\r
70506 },\r
70507 \r
70508 onNodeExpand: function(node) {\r
70509 var me = this,\r
70510 item = me.itemMap[node.internalId],\r
70511 childNodes, len, i, parentNode, child;\r
70512 if (item) {\r
70513 if (!item.isRootItem && me.getSingleExpand()) {\r
70514 me.collapsingForExpand = true;\r
70515 parentNode = (item.getParentItem() || me.rootItem).getNode();\r
70516 childNodes = parentNode.childNodes;\r
70517 for (i = 0 , len = childNodes.length; i < len; ++i) {\r
70518 child = childNodes[i];\r
70519 if (child !== node) {\r
70520 child.collapse();\r
70521 }\r
70522 }\r
70523 me.collapsing = false;\r
70524 }\r
70525 item.nodeExpand(node);\r
70526 }\r
70527 },\r
70528 \r
70529 onNodeInsert: function(parentNode, node, refNode) {\r
70530 var item = this.itemMap[parentNode.internalId];\r
70531 if (item) {\r
70532 item.nodeInsert(node, refNode);\r
70533 }\r
70534 },\r
70535 \r
70536 onNodeRemove: function(parentNode, node, isMove) {\r
70537
70538
70539
70540 if (parentNode && !isMove) {\r
70541 var item = this.itemMap[parentNode.internalId];\r
70542 if (item) {\r
70543 item.nodeRemove(node);\r
70544 }\r
70545 }\r
70546 },\r
70547 \r
70548 onNodeUpdate: function(store, node, type, modifiedFieldNames) {\r
70549 var item = this.itemMap[node.internalId];\r
70550 if (item) {\r
70551 item.nodeUpdate(node, modifiedFieldNames);\r
70552 }\r
70553 },\r
70554 \r
70555 onRootChange: function(root) {\r
70556 this.removeRoot();\r
70557 if (root) {\r
70558 this.createRootItem(root);\r
70559 }\r
70560 this.updateLayout();\r
70561 },\r
70562 \r
70563 removeItem: function(node) {\r
70564 var map = this.itemMap;\r
70565 if (map) {\r
70566 delete map[node.internalId];\r
70567 }\r
70568 },\r
70569 removeRoot: function() {\r
70570 var me = this,\r
70571 rootItem = me.rootItem;\r
70572 if (rootItem) {\r
70573 me.element.removeChild(rootItem.element);\r
70574 me.rootItem = me.itemMap = Ext.destroy(rootItem);\r
70575 }\r
70576 },\r
70577 \r
70578 onToolStripClick: function(e) {\r
70579 var item = e.getTarget('[data-recordId]'),\r
70580 id;\r
70581 if (item) {\r
70582 id = item.getAttribute('data-recordId');\r
70583 item = this.itemMap[id];\r
70584 if (item) {\r
70585 if (item === this.activeFloater) {\r
70586 this.unfloatAll();\r
70587 } else {\r
70588 this.floatItem(item, false);\r
70589 }\r
70590 }\r
70591 }\r
70592 },\r
70593 \r
70594 onToolStripMouseOver: function(e) {\r
70595 var item = e.getTarget('[data-recordId]'),\r
70596 id;\r
70597 if (item) {\r
70598 id = item.getAttribute('data-recordId');\r
70599 item = this.itemMap[id];\r
70600 if (item) {\r
70601 this.floatItem(item, true);\r
70602 }\r
70603 }\r
70604 },\r
70605 syncIconSize: function() {\r
70606 var me = this,\r
70607 size = me.iconSize || (me.iconSize = parseInt(me.element.getStyle('background-position'), 10));\r
70608 me.setIconSize(size);\r
70609 },\r
70610 unfloatAll: function() {\r
70611 var me = this,\r
70612 floater = me.activeFloater;\r
70613 if (floater) {\r
70614 floater.setFloated(false);\r
70615 me.activeFloater = null;\r
70616 if (me.floatedByHover) {\r
70617 floater.element.un('mouseleave', me.checkForMouseLeave, me);\r
70618 } else {\r
70619 Ext.un('mousedown', me.checkForOutsideClick, me);\r
70620 }\r
70621 }\r
70622 },\r
70623 defaultIconSize: 22,\r
70624 updateIconSize: function(value) {\r
70625 this.setIndent(value || this.defaultIconSize);\r
70626 },\r
70627 updateIndent: function(value) {\r
70628 var rootItem = this.rootItem;\r
70629 if (rootItem) {\r
70630 rootItem.setIndent(value);\r
70631 }\r
70632 }\r
70633 }\r
70634});\r
70635\r
70636Ext.define('Ext.overrides.list.Tree', {\r
70637 override: 'Ext.list.Tree',\r
70638 constructor: function(config) {\r
70639 var me = this,\r
70640 el;\r
70641 me.callParent([\r
70642 config\r
70643 ]);\r
70644 el = me.element;\r
70645 if (el.isPainted()) {\r
70646 me.syncIconSize();\r
70647 } else {\r
70648 el.on({\r
70649 scope: me,\r
70650 painted: me.syncIconSize,\r
70651 single: true\r
70652 });\r
70653 }\r
70654 }\r
70655});\r
70656\r
70657\r
70658Ext.define('Ext.mixin.Accessible', {\r
70659 extend: Ext.Mixin,\r
70660 mixinConfig: {\r
70661 id: 'accessible'\r
70662 },\r
70663 \r
70664 \r
70665 \r
70666 config: {\r
70667 \r
70668 ariaAttributes: {\r
70669 $value: null,\r
70670 lazy: true\r
70671 }\r
70672 },\r
70673 \r
70674 \r
70675 privates: {\r
70676 \r
70677 getAriaLabelEl: function(selector) {\r
70678 var ids = [],\r
70679 refHolder, i, len, cmp, result;\r
70680 if (selector) {\r
70681 if (Ext.isFunction(selector)) {\r
70682 return selector.call(this);\r
70683 } else {\r
70684 if (!Ext.isArray(selector)) {\r
70685 selector = [\r
70686 selector\r
70687 ];\r
70688 }\r
70689 refHolder = this.lookupReferenceHolder();\r
70690 if (refHolder) {\r
70691 for (i = 0 , len = selector.length; i < len; i++) {\r
70692 cmp = refHolder.lookupReference(selector[i]);\r
70693 if (cmp) {\r
70694 ids.push(cmp.ariaEl.id);\r
70695 }\r
70696 }\r
70697 }\r
70698 }\r
70699 }\r
70700 return ids.length ? ids.join(' ') : null;\r
70701 }\r
70702 }\r
70703});\r
70704\r
70705\r
70706Ext.define('Ext.mixin.Mashup', function(Mashup) {\r
70707 return {\r
70708 extend: 'Ext.Mixin',\r
70709 mixinConfig: {\r
70710 id: 'mashup',\r
70711 extended: function(baseClass, derivedClass) {\r
70712 Mashup.process(derivedClass);\r
70713 }\r
70714 },\r
70715 statics: {\r
70716 process: function(targetClass) {\r
70717 var body = targetClass.prototype,\r
70718 requiredScripts = body.requiredScripts,\r
70719 hooks = targetClass._classHooks,\r
70720 onCreated = hooks.onCreated;\r
70721 if (requiredScripts) {\r
70722 delete body.requiredScripts;\r
70723 hooks.onCreated = function() {\r
70724 var me = this,\r
70725 args = Ext.Array.slice(arguments);\r
70726 Ext.Loader.loadScripts({\r
70727 url: requiredScripts,\r
70728 cache: true,\r
70729
70730 onLoad: function() {\r
70731 hooks.onCreated = onCreated;\r
70732 hooks.onCreated.call(me, args);\r
70733 }\r
70734 });\r
70735 };\r
70736 }\r
70737 }\r
70738 },\r
70739 onClassMixedIn: function(targetClass) {\r
70740 Mashup.process(targetClass);\r
70741 }\r
70742 };\r
70743});\r
70744\r
70745\r
70746Ext.define('Ext.mixin.Responsive', function(Responsive) {\r
70747 return {\r
70748 extend: Ext.Mixin,\r
70749 mixinConfig: {\r
70750 id: 'responsive',\r
70751 after: {\r
70752 destroy: 'destroy'\r
70753 }\r
70754 },\r
70755 config: {\r
70756 \r
70757 responsiveConfig: {\r
70758 $value: undefined,\r
70759 merge: function(newValue, oldValue, target, mixinClass) {\r
70760 if (!newValue) {\r
70761 return oldValue;\r
70762 }\r
70763 var ret = oldValue ? Ext.Object.chain(oldValue) : {},\r
70764 rule;\r
70765 for (rule in newValue) {\r
70766 if (!mixinClass || !(rule in ret)) {\r
70767 ret[rule] = {\r
70768 fn: null,\r
70769
70770 config: newValue[rule]\r
70771 };\r
70772 }\r
70773 }\r
70774 return ret;\r
70775 }\r
70776 },\r
70777 \r
70778 responsiveFormulas: {\r
70779 $value: 0,\r
70780 merge: function(newValue, oldValue, target, mixinClass) {\r
70781 return this.mergeNew(newValue, oldValue, target, mixinClass);\r
70782 }\r
70783 }\r
70784 },\r
70785 \r
70786 destroy: function() {\r
70787 Responsive.unregister(this);\r
70788 this.callParent();\r
70789 },\r
70790 privates: {\r
70791 statics: {\r
70792 \r
70793 active: false,\r
70794 \r
70795 all: {},\r
70796 \r
70797 context: Ext.Object.chain(Ext.platformTags),\r
70798 \r
70799 count: 0,\r
70800 \r
70801 nextId: 0,\r
70802 \r
70803 activate: function() {\r
70804 Responsive.active = true;\r
70805 Responsive.updateContext();\r
70806 Ext.on('resize', Responsive.onResize, Responsive);\r
70807 },\r
70808 \r
70809 deactivate: function() {\r
70810 Responsive.active = false;\r
70811 Ext.un('resize', Responsive.onResize, Responsive);\r
70812 },\r
70813 \r
70814 notify: function() {\r
70815 var all = Responsive.all,\r
70816 context = Responsive.context,\r
70817 globalEvents = Ext.GlobalEvents,\r
70818 timer = Responsive.timer,\r
70819 id;\r
70820 if (timer) {\r
70821 Responsive.timer = null;\r
70822 Ext.Function.cancelAnimationFrame(timer);\r
70823 }\r
70824 Responsive.updateContext();\r
70825 Ext.suspendLayouts();\r
70826 globalEvents.fireEvent('beforeresponsiveupdate', context);\r
70827 for (id in all) {\r
70828 all[id].setupResponsiveContext();\r
70829 }\r
70830 globalEvents.fireEvent('beginresponsiveupdate', context);\r
70831 for (id in all) {\r
70832 all[id].updateResponsiveState();\r
70833 }\r
70834 globalEvents.fireEvent('responsiveupdate', context);\r
70835 Ext.resumeLayouts(true);\r
70836 },\r
70837 \r
70838 onResize: function() {\r
70839 if (!Responsive.timer) {\r
70840 Responsive.timer = Ext.Function.requestAnimationFrame(Responsive.onTimer);\r
70841 }\r
70842 },\r
70843 \r
70844 onTimer: function() {\r
70845 Responsive.timer = null;\r
70846 Responsive.notify();\r
70847 },\r
70848 \r
70849 processConfig: function(instance, instanceConfig, name) {\r
70850 var value = instanceConfig && instanceConfig[name],\r
70851 config = instance.config,\r
70852 cfg, configurator;\r
70853
70854
70855 if (value) {\r
70856 configurator = instance.getConfigurator();\r
70857 cfg = configurator.configs[name];\r
70858
70859
70860 config[name] = cfg.merge(value, config[name], instance);\r
70861 }\r
70862 },\r
70863 register: function(responder) {\r
70864 var id = responder.$responsiveId;\r
70865 if (!id) {\r
70866 responder.$responsiveId = id = ++Responsive.nextId;\r
70867 Responsive.all[id] = responder;\r
70868 if (++Responsive.count === 1) {\r
70869 Responsive.activate();\r
70870 }\r
70871 }\r
70872 },\r
70873 unregister: function(responder) {\r
70874 var id = responder.$responsiveId;\r
70875 if (id in Responsive.all) {\r
70876 responder.$responsiveId = null;\r
70877 delete Responsive.all[id];\r
70878 if (--Responsive.count === 0) {\r
70879 Responsive.deactivate();\r
70880 }\r
70881 }\r
70882 },\r
70883 \r
70884 updateContext: function() {\r
70885 var El = Ext.Element,\r
70886 width = El.getViewportWidth(),\r
70887 height = El.getViewportHeight(),\r
70888 context = Responsive.context;\r
70889 context.width = width;\r
70890 context.height = height;\r
70891 context.tall = width < height;\r
70892 context.wide = !context.tall;\r
70893 context.landscape = context.portrait = false;\r
70894 if (!context.platform) {\r
70895 context.platform = Ext.platformTags;\r
70896 }\r
70897 context[Ext.dom.Element.getOrientation()] = true;\r
70898 }\r
70899 },\r
70900
70901
70902 \r
70903 afterClassMixedIn: function(targetClass) {\r
70904 var proto = targetClass.prototype,\r
70905 responsiveConfig = proto.responsiveConfig,\r
70906 responsiveFormulas = proto.responsiveFormulas,\r
70907 config;\r
70908 if (responsiveConfig || responsiveFormulas) {\r
70909 config = {};\r
70910 if (responsiveConfig) {\r
70911 delete proto.responsiveConfig;\r
70912 config.responsiveConfig = responsiveConfig;\r
70913 }\r
70914 if (responsiveFormulas) {\r
70915 delete proto.responsiveFormulas;\r
70916 config.responsiveFormulas = responsiveFormulas;\r
70917 }\r
70918 targetClass.getConfigurator().add(config);\r
70919 }\r
70920 },\r
70921
70922
70923
70924
70925 applyResponsiveConfig: function(rules) {\r
70926 for (var rule in rules) {\r
70927 rules[rule].fn = Ext.createRuleFn(rule);\r
70928 }\r
70929 return rules;\r
70930 },\r
70931 applyResponsiveFormulas: function(formulas) {\r
70932 var ret = {},\r
70933 fn, name;\r
70934 if (formulas) {\r
70935 for (name in formulas) {\r
70936 if (Ext.isString(fn = formulas[name])) {\r
70937 fn = Ext.createRuleFn(fn);\r
70938 }\r
70939 ret[name] = fn;\r
70940 }\r
70941 }\r
70942 return ret;\r
70943 },\r
70944 \r
70945 getResponsiveState: function() {\r
70946 var context = Responsive.context,\r
70947 rules = this.getResponsiveConfig(),\r
70948 ret = {},\r
70949 entry, rule;\r
70950 if (rules) {\r
70951 for (rule in rules) {\r
70952 entry = rules[rule];\r
70953 if (entry.fn.call(this, context)) {\r
70954 Ext.merge(ret, entry.config);\r
70955 }\r
70956 }\r
70957 }\r
70958 return ret;\r
70959 },\r
70960 setupResponsiveContext: function() {\r
70961 var formulas = this.getResponsiveFormulas(),\r
70962 context = Responsive.context,\r
70963 name;\r
70964 if (formulas) {\r
70965 for (name in formulas) {\r
70966 context[name] = formulas[name].call(this, context);\r
70967 }\r
70968 }\r
70969 },\r
70970 \r
70971 transformInstanceConfig: function(instanceConfig) {\r
70972 var me = this,\r
70973 ret;\r
70974 Responsive.register(me);\r
70975
70976
70977
70978
70979 if (instanceConfig) {\r
70980 Responsive.processConfig(me, instanceConfig, 'responsiveConfig');\r
70981 Responsive.processConfig(me, instanceConfig, 'responsiveFormulas');\r
70982 }\r
70983
70984
70985 me.setupResponsiveContext();\r
70986
70987
70988 ret = me.getResponsiveState();\r
70989 if (instanceConfig) {\r
70990 ret = Ext.merge({}, instanceConfig, ret);\r
70991
70992 delete ret.responsiveConfig;\r
70993 delete ret.responsiveFormulas;\r
70994 }\r
70995 return ret;\r
70996 },\r
70997 \r
70998 updateResponsiveState: function() {\r
70999 var config = this.getResponsiveState();\r
71000 this.setConfig(config);\r
71001 }\r
71002 }\r
71003 };\r
71004});\r
71005
71006\r
71007\r
71008Ext.define('Ext.mixin.Selectable', {\r
71009 extend: Ext.Mixin,\r
71010 mixinConfig: {\r
71011 id: 'selectable',\r
71012 after: {\r
71013 updateStore: 'updateStore'\r
71014 }\r
71015 },\r
71016 \r
71017 \r
71018 config: {\r
71019 \r
71020 disableSelection: null,\r
71021 \r
71022 mode: 'SINGLE',\r
71023 \r
71024 allowDeselect: false,\r
71025 \r
71026 lastSelected: null,\r
71027 \r
71028 lastFocused: null,\r
71029 \r
71030 deselectOnContainerClick: true,\r
71031 \r
71032 selection: null,\r
71033 twoWayBindable: {\r
71034 selection: 1\r
71035 },\r
71036 publishes: {\r
71037 selection: 1\r
71038 }\r
71039 },\r
71040 modes: {\r
71041 SINGLE: true,\r
71042 SIMPLE: true,\r
71043 MULTI: true\r
71044 },\r
71045 selectableEventHooks: {\r
71046 add: 'onSelectionStoreAdd',\r
71047 remove: 'onSelectionStoreRemove',\r
71048 update: 'onSelectionStoreUpdate',\r
71049 clear: {\r
71050 fn: 'onSelectionStoreClear',\r
71051 priority: 1000\r
71052 },\r
71053 load: 'refreshSelection',\r
71054 refresh: 'refreshSelection'\r
71055 },\r
71056 constructor: function() {\r
71057 this.selected = new Ext.util.MixedCollection();\r
71058 this.callParent(arguments);\r
71059 },\r
71060 initSelectable: function() {\r
71061 this.publishState('selection', this.getSelection());\r
71062 },\r
71063 \r
71064 applyMode: function(mode) {\r
71065 mode = mode ? mode.toUpperCase() : 'SINGLE';\r
71066
71067
71068 return this.modes[mode] ? mode : 'SINGLE';\r
71069 },\r
71070 \r
71071 updateStore: function(newStore, oldStore) {\r
71072 var me = this,\r
71073 bindEvents = Ext.apply({}, me.selectableEventHooks, {\r
71074 scope: me\r
71075 });\r
71076 if (oldStore && Ext.isObject(oldStore) && oldStore.isStore) {\r
71077 if (oldStore.autoDestroy) {\r
71078 oldStore.destroy();\r
71079 } else {\r
71080 oldStore.un(bindEvents);\r
71081 }\r
71082 }\r
71083 if (newStore) {\r
71084 newStore.on(bindEvents);\r
71085 me.refreshSelection();\r
71086 }\r
71087 },\r
71088 \r
71089 selectAll: function(silent) {\r
71090 var me = this,\r
71091 selections = me.getStore().getRange();\r
71092 me.select(selections, true, silent);\r
71093 },\r
71094 \r
71095 deselectAll: function(supress) {\r
71096 var me = this,\r
71097 selections = me.getStore().getRange();\r
71098 me.deselect(selections, supress);\r
71099 me.selected.clear();\r
71100 me.setLastSelected(null);\r
71101 me.setLastFocused(null);\r
71102 },\r
71103 updateSelection: function(selection) {\r
71104 if (this.changingSelection) {\r
71105 return;\r
71106 }\r
71107 if (selection) {\r
71108 this.select(selection);\r
71109 } else {\r
71110 this.deselectAll();\r
71111 }\r
71112 },\r
71113
71114
71115 selectWithEvent: function(record) {\r
71116 var me = this,\r
71117 isSelected = me.isSelected(record);\r
71118 switch (me.getMode()) {\r
71119 case 'MULTI':\r
71120 case 'SIMPLE':\r
71121 if (isSelected) {\r
71122 me.deselect(record);\r
71123 } else {\r
71124 me.select(record, true);\r
71125 };\r
71126 break;\r
71127 case 'SINGLE':\r
71128 if (me.getAllowDeselect() && isSelected) {\r
71129
71130 me.deselect(record);\r
71131 } else {\r
71132
71133 me.select(record, false);\r
71134 };\r
71135 break;\r
71136 }\r
71137 },\r
71138 \r
71139 selectRange: function(startRecord, endRecord, keepExisting) {\r
71140 var me = this,\r
71141 store = me.getStore(),\r
71142 records = [],\r
71143 tmp, i;\r
71144 if (me.getDisableSelection()) {\r
71145 return;\r
71146 }\r
71147
71148 if (startRecord > endRecord) {\r
71149 tmp = endRecord;\r
71150 endRecord = startRecord;\r
71151 startRecord = tmp;\r
71152 }\r
71153 for (i = startRecord; i <= endRecord; i++) {\r
71154 records.push(store.getAt(i));\r
71155 }\r
71156 this.doMultiSelect(records, keepExisting);\r
71157 },\r
71158 \r
71159 select: function(records, keepExisting, suppressEvent) {\r
71160 var me = this,\r
71161 record;\r
71162 if (me.getDisableSelection()) {\r
71163 return;\r
71164 }\r
71165 if (typeof records === "number") {\r
71166 records = [\r
71167 me.getStore().getAt(records)\r
71168 ];\r
71169 }\r
71170 if (!records) {\r
71171 return;\r
71172 }\r
71173 if (me.getMode() == "SINGLE" && records) {\r
71174 record = records.length ? records[0] : records;\r
71175 me.doSingleSelect(record, suppressEvent);\r
71176 } else {\r
71177 me.doMultiSelect(records, keepExisting, suppressEvent);\r
71178 }\r
71179 },\r
71180 \r
71181 doSingleSelect: function(record, suppressEvent) {\r
71182 var me = this,\r
71183 selected = me.selected;\r
71184 if (me.getDisableSelection()) {\r
71185 return;\r
71186 }\r
71187
71188
71189 if (me.isSelected(record)) {\r
71190 return;\r
71191 }\r
71192 if (selected.getCount() > 0) {\r
71193 me.deselect(me.getLastSelected(), suppressEvent);\r
71194 }\r
71195 selected.add(record);\r
71196 me.setLastSelected(record);\r
71197 me.onItemSelect(record, suppressEvent);\r
71198 me.setLastFocused(record);\r
71199 if (!suppressEvent) {\r
71200 me.fireSelectionChange([\r
71201 record\r
71202 ]);\r
71203 }\r
71204 },\r
71205 \r
71206 doMultiSelect: function(records, keepExisting, suppressEvent) {\r
71207 if (records === null || this.getDisableSelection()) {\r
71208 return;\r
71209 }\r
71210 records = !Ext.isArray(records) ? [\r
71211 records\r
71212 ] : records;\r
71213 var me = this,\r
71214 selected = me.selected,\r
71215 ln = records.length,\r
71216 change = false,\r
71217 i = 0,\r
71218 record;\r
71219 if (!keepExisting && selected.getCount() > 0) {\r
71220 change = true;\r
71221 me.deselect(me.getSelections(), true);\r
71222 }\r
71223 for (; i < ln; i++) {\r
71224 record = records[i];\r
71225 if (keepExisting && me.isSelected(record)) {\r
71226 \r
71227 continue;\r
71228 }\r
71229 change = true;\r
71230 me.setLastSelected(record);\r
71231 selected.add(record);\r
71232 if (!suppressEvent) {\r
71233 me.setLastFocused(record);\r
71234 }\r
71235 me.onItemSelect(record, suppressEvent);\r
71236 }\r
71237 if (change && !suppressEvent) {\r
71238 this.fireSelectionChange(records);\r
71239 }\r
71240 },\r
71241 \r
71242 deselect: function(records, suppressEvent) {\r
71243 var me = this;\r
71244 if (me.getDisableSelection()) {\r
71245 return;\r
71246 }\r
71247 records = Ext.isArray(records) ? records : [\r
71248 records\r
71249 ];\r
71250 var selected = me.selected,\r
71251 change = false,\r
71252 i = 0,\r
71253 store = me.getStore(),\r
71254 ln = records.length,\r
71255 record;\r
71256 for (; i < ln; i++) {\r
71257 record = records[i];\r
71258 if (typeof record === 'number') {\r
71259 record = store.getAt(record);\r
71260 }\r
71261 if (selected.remove(record)) {\r
71262 if (me.getLastSelected() == record) {\r
71263 me.setLastSelected(selected.last());\r
71264 }\r
71265 change = true;\r
71266 }\r
71267 if (record) {\r
71268 me.onItemDeselect(record, suppressEvent);\r
71269 }\r
71270 }\r
71271 if (change && !suppressEvent) {\r
71272 me.fireSelectionChange(records);\r
71273 }\r
71274 },\r
71275 \r
71276 updateLastFocused: function(newRecord, oldRecord) {\r
71277 this.onLastFocusChanged(oldRecord, newRecord);\r
71278 },\r
71279 fireSelectionChange: function(records) {\r
71280 var me = this;\r
71281 me.changingSelection = true;\r
71282 me.setSelection(me.getLastSelected() || null);\r
71283 me.changingSelection = false;\r
71284 me.fireAction('selectionchange', [\r
71285 me,\r
71286 records\r
71287 ], 'getSelections');\r
71288 },\r
71289 \r
71290 getSelections: function() {\r
71291 return this.selected.getRange();\r
71292 },\r
71293 \r
71294 isSelected: function(record) {\r
71295 record = Ext.isNumber(record) ? this.getStore().getAt(record) : record;\r
71296 return this.selected.indexOf(record) !== -1;\r
71297 },\r
71298 \r
71299 hasSelection: function() {\r
71300 return this.selected.getCount() > 0;\r
71301 },\r
71302 \r
71303 refreshSelection: function() {\r
71304 var me = this,\r
71305 selections = me.getSelections();\r
71306 me.deselectAll(true);\r
71307 if (selections.length) {\r
71308 me.select(selections, false, true);\r
71309 }\r
71310 },\r
71311
71312
71313
71314 onSelectionStoreRemove: function(store, records) {\r
71315 var me = this,\r
71316 selected = me.selected,\r
71317 ln = records.length,\r
71318 removed, record, i;\r
71319 if (me.getDisableSelection()) {\r
71320 return;\r
71321 }\r
71322 for (i = 0; i < ln; i++) {\r
71323 record = records[i];\r
71324 if (selected.remove(record)) {\r
71325 if (me.getLastSelected() == record) {\r
71326 me.setLastSelected(null);\r
71327 }\r
71328 if (me.getLastFocused() == record) {\r
71329 me.setLastFocused(null);\r
71330 }\r
71331 removed = removed || [];\r
71332 removed.push(record);\r
71333 }\r
71334 }\r
71335 if (removed) {\r
71336 me.fireSelectionChange([\r
71337 removed\r
71338 ]);\r
71339 }\r
71340 },\r
71341 onSelectionStoreClear: function(store) {\r
71342 var records = store.getData().items;\r
71343 this.onSelectionStoreRemove(store, records);\r
71344 },\r
71345 \r
71346 getSelectionCount: function() {\r
71347 return this.selected.getCount();\r
71348 },\r
71349 onSelectionStoreAdd: Ext.emptyFn,\r
71350 onSelectionStoreUpdate: Ext.emptyFn,\r
71351 onItemSelect: Ext.emptyFn,\r
71352 onItemDeselect: Ext.emptyFn,\r
71353 onLastFocusChanged: Ext.emptyFn,\r
71354 onEditorKey: Ext.emptyFn\r
71355}, function() {});\r
71356\r
71357\r
71358\r
71359\r
71360\r
71361\r
71362\r
71363\r
71364\r
71365\r
71366\r
71367Ext.define('Ext.perf.Accumulator', function() {\r
71368 var currentFrame = null,\r
71369 khrome = Ext.global['chrome'],\r
71370
71371 formatTpl,\r
71372
71373
71374 getTimestamp = function() {\r
71375 getTimestamp = Ext.now;\r
71376 var interval, toolbox;\r
71377
71378 if (Ext.isChrome && khrome && khrome.Interval) {\r
71379 interval = new khrome.Interval();\r
71380 interval.start();\r
71381 getTimestamp = function() {\r
71382 return interval.microseconds() / 1000;\r
71383 };\r
71384 } else if (window.ActiveXObject) {\r
71385 try {\r
71386
71387 toolbox = new ActiveXObject('SenchaToolbox.Toolbox');\r
71388
71389 Ext.senchaToolbox = toolbox;\r
71390
71391 getTimestamp = function() {\r
71392 return toolbox.milliseconds;\r
71393 };\r
71394 } catch (e) {}\r
71395 }\r
71396
71397 Ext.perf.getTimestamp = Ext.perf.Accumulator.getTimestamp = getTimestamp;\r
71398 return getTimestamp();\r
71399 };\r
71400 function adjustSet(set, time) {\r
71401 set.sum += time;\r
71402 set.min = Math.min(set.min, time);\r
71403 set.max = Math.max(set.max, time);\r
71404 }\r
71405 function leaveFrame(time) {\r
71406 var totalTime = time ? time : (getTimestamp() - this.time),\r
71407
71408 me = this,\r
71409
71410 accum = me.accum;\r
71411 ++accum.count;\r
71412 if (!--accum.depth) {\r
71413 adjustSet(accum.total, totalTime);\r
71414 }\r
71415 adjustSet(accum.pure, totalTime - me.childTime);\r
71416 currentFrame = me.parent;\r
71417 if (currentFrame) {\r
71418 ++currentFrame.accum.childCount;\r
71419 currentFrame.childTime += totalTime;\r
71420 }\r
71421 }\r
71422 function makeSet() {\r
71423 return {\r
71424 min: Number.MAX_VALUE,\r
71425 max: 0,\r
71426 sum: 0\r
71427 };\r
71428 }\r
71429 function makeTap(me, fn) {\r
71430 return function() {\r
71431 var frame = me.enter(),\r
71432 ret = fn.apply(this, arguments);\r
71433 frame.leave();\r
71434 return ret;\r
71435 };\r
71436 }\r
71437 function setToJSON(count, childCount, calibration, set) {\r
71438 var data = {\r
71439 avg: 0,\r
71440 min: set.min,\r
71441 max: set.max,\r
71442 sum: 0\r
71443 };\r
71444 if (count) {\r
71445 calibration = calibration || 0;\r
71446 data.sum = set.sum - childCount * calibration;\r
71447 data.avg = data.sum / count;\r
71448 }\r
71449
71450
71451 return data;\r
71452 }\r
71453 return {\r
71454 constructor: function(name) {\r
71455 var me = this;\r
71456 me.count = me.childCount = me.depth = me.maxDepth = 0;\r
71457 me.pure = makeSet();\r
71458 me.total = makeSet();\r
71459 me.name = name;\r
71460 },\r
71461 statics: {\r
71462 getTimestamp: getTimestamp\r
71463 },\r
71464 format: function(calibration) {\r
71465 if (!formatTpl) {\r
71466 formatTpl = new Ext.XTemplate([\r
71467 '{name} - {count} call(s)',\r
71468 '<tpl if="count">',\r
71469 '<tpl if="childCount">',\r
71470 ' ({childCount} children)',\r
71471 '</tpl>',\r
71472 '<tpl if="depth - 1">',\r
71473 ' ({depth} deep)',\r
71474 '</tpl>',\r
71475 '<tpl for="times">',\r
71476 ', {type}: {[this.time(values.sum)]} msec (',\r
71477
71478 'avg={[this.time(values.sum / parent.count)]}',\r
71479
71480 ')',\r
71481 '</tpl>',\r
71482 '</tpl>'\r
71483 ].join(''), {\r
71484 time: function(t) {\r
71485 return Math.round(t * 100) / 100;\r
71486 }\r
71487 });\r
71488 }\r
71489 var data = this.getData(calibration);\r
71490 data.name = this.name;\r
71491 data.pure.type = 'Pure';\r
71492 data.total.type = 'Total';\r
71493 data.times = [\r
71494 data.pure,\r
71495 data.total\r
71496 ];\r
71497 return formatTpl.apply(data);\r
71498 },\r
71499 getData: function(calibration) {\r
71500 var me = this;\r
71501 return {\r
71502 count: me.count,\r
71503 childCount: me.childCount,\r
71504 depth: me.maxDepth,\r
71505 pure: setToJSON(me.count, me.childCount, calibration, me.pure),\r
71506 total: setToJSON(me.count, me.childCount, calibration, me.total)\r
71507 };\r
71508 },\r
71509 enter: function() {\r
71510 var me = this,\r
71511 frame = {\r
71512 accum: me,\r
71513 leave: leaveFrame,\r
71514 childTime: 0,\r
71515 parent: currentFrame\r
71516 };\r
71517 ++me.depth;\r
71518 if (me.maxDepth < me.depth) {\r
71519 me.maxDepth = me.depth;\r
71520 }\r
71521 currentFrame = frame;\r
71522 frame.time = getTimestamp();\r
71523
71524 return frame;\r
71525 },\r
71526 monitor: function(fn, scope, args) {\r
71527 var frame = this.enter();\r
71528 if (args) {\r
71529 fn.apply(scope, args);\r
71530 } else {\r
71531 fn.call(scope);\r
71532 }\r
71533 frame.leave();\r
71534 },\r
71535 report: function() {\r
71536 Ext.log(this.format());\r
71537 },\r
71538 tap: function(className, methodName) {\r
71539 var me = this,\r
71540 methods = typeof methodName === 'string' ? [\r
71541 methodName\r
71542 ] : methodName,\r
71543 klass, statik, i, parts, length, name, src, tapFunc;\r
71544 tapFunc = function() {\r
71545 if (typeof className === 'string') {\r
71546 klass = Ext.global;\r
71547 parts = className.split('.');\r
71548 for (i = 0 , length = parts.length; i < length; ++i) {\r
71549 klass = klass[parts[i]];\r
71550 }\r
71551 } else {\r
71552 klass = className;\r
71553 }\r
71554 for (i = 0 , length = methods.length; i < length; ++i) {\r
71555 name = methods[i];\r
71556 statik = name.charAt(0) === '!';\r
71557 if (statik) {\r
71558 name = name.substring(1);\r
71559 } else {\r
71560 statik = !(name in klass.prototype);\r
71561 }\r
71562 src = statik ? klass : klass.prototype;\r
71563 src[name] = makeTap(me, src[name]);\r
71564 }\r
71565 };\r
71566 Ext.ClassManager.onCreated(tapFunc, me, className);\r
71567 return me;\r
71568 }\r
71569 };\r
71570}, function() {\r
71571 Ext.perf.getTimestamp = this.getTimestamp;\r
71572});\r
71573\r
71574\r
71575Ext.define('Ext.perf.Monitor', {\r
71576 singleton: true,\r
71577 alternateClassName: 'Ext.Perf',\r
71578 constructor: function() {\r
71579 this.accumulators = [];\r
71580 this.accumulatorsByName = {};\r
71581 },\r
71582 calibrate: function() {\r
71583 var accum = new Ext.perf.Accumulator('$'),\r
71584 total = accum.total,\r
71585 getTimestamp = Ext.perf.Accumulator.getTimestamp,\r
71586 count = 0,\r
71587 frame, endTime, startTime;\r
71588 startTime = getTimestamp();\r
71589 do {\r
71590 frame = accum.enter();\r
71591 frame.leave();\r
71592 ++count;\r
71593 } while (total.sum < 100);\r
71594 endTime = getTimestamp();\r
71595 return (endTime - startTime) / count;\r
71596 },\r
71597 get: function(name) {\r
71598 var me = this,\r
71599 accum = me.accumulatorsByName[name];\r
71600 if (!accum) {\r
71601 me.accumulatorsByName[name] = accum = new Ext.perf.Accumulator(name);\r
71602 me.accumulators.push(accum);\r
71603 }\r
71604 return accum;\r
71605 },\r
71606 enter: function(name) {\r
71607 return this.get(name).enter();\r
71608 },\r
71609 monitor: function(name, fn, scope) {\r
71610 this.get(name).monitor(fn, scope);\r
71611 },\r
71612 report: function() {\r
71613 var me = this,\r
71614 accumulators = me.accumulators,\r
71615 calibration = me.calibrate();\r
71616 accumulators.sort(function(a, b) {\r
71617 return (a.name < b.name) ? -1 : ((b.name < a.name) ? 1 : 0);\r
71618 });\r
71619 me.updateGC();\r
71620 Ext.log('Calibration: ' + Math.round(calibration * 100) / 100 + ' msec/sample');\r
71621 Ext.each(accumulators, function(accum) {\r
71622 Ext.log(accum.format(calibration));\r
71623 });\r
71624 },\r
71625 getData: function(all) {\r
71626 var ret = {},\r
71627 accumulators = this.accumulators;\r
71628 Ext.each(accumulators, function(accum) {\r
71629 if (all || accum.count) {\r
71630 ret[accum.name] = accum.getData();\r
71631 }\r
71632 });\r
71633 return ret;\r
71634 },\r
71635 reset: function() {\r
71636 Ext.each(this.accumulators, function(accum) {\r
71637 var me = accum;\r
71638 me.count = me.childCount = me.depth = me.maxDepth = 0;\r
71639 me.pure = {\r
71640 min: Number.MAX_VALUE,\r
71641 max: 0,\r
71642 sum: 0\r
71643 };\r
71644 me.total = {\r
71645 min: Number.MAX_VALUE,\r
71646 max: 0,\r
71647 sum: 0\r
71648 };\r
71649 });\r
71650 },\r
71651 updateGC: function() {\r
71652 var accumGC = this.accumulatorsByName.GC,\r
71653 toolbox = Ext.senchaToolbox,\r
71654 bucket;\r
71655 if (accumGC) {\r
71656 accumGC.count = toolbox.garbageCollectionCounter || 0;\r
71657 if (accumGC.count) {\r
71658 bucket = accumGC.pure;\r
71659 accumGC.total.sum = bucket.sum = toolbox.garbageCollectionMilliseconds;\r
71660 bucket.min = bucket.max = bucket.sum / accumGC.count;\r
71661 bucket = accumGC.total;\r
71662 bucket.min = bucket.max = bucket.sum / accumGC.count;\r
71663 }\r
71664 }\r
71665 },\r
71666 watchGC: function() {\r
71667 Ext.perf.getTimestamp();\r
71668
71669 var toolbox = Ext.senchaToolbox;\r
71670 if (toolbox) {\r
71671 this.get("GC");\r
71672 toolbox.watchGarbageCollector(false);\r
71673 }\r
71674 },\r
71675
71676 setup: function(config) {\r
71677 if (!config) {\r
71678 config = {\r
71679 \r
71680 \r
71681
71682
71683
71684
71685
71686
71687 render: {\r
71688 'Ext.Component': 'render'\r
71689 },\r
71690
71691
71692
71693
71694
71695
71696
71697
71698
71699
71700
71701
71702
71703
71704
71705
71706
71707
71708
71709
71710
71711
71712
71713
71714
71715
71716
71717
71718
71719
71720
71721
71722
71723 layout: {\r
71724 'Ext.layout.Context': 'run'\r
71725 }\r
71726 };\r
71727 }\r
71728 this.currentConfig = config;\r
71729 var key, prop, accum, className, methods;\r
71730 for (key in config) {\r
71731 if (config.hasOwnProperty(key)) {\r
71732 prop = config[key];\r
71733 accum = Ext.Perf.get(key);\r
71734 for (className in prop) {\r
71735 if (prop.hasOwnProperty(className)) {\r
71736 methods = prop[className];\r
71737 accum.tap(className, methods);\r
71738 }\r
71739 }\r
71740 }\r
71741 }\r
71742 this.watchGC();\r
71743 },\r
71744
71745 setupLog: function(config) {\r
71746 var className, cls, methods, method, override;\r
71747 for (className in config) {\r
71748 if (config.hasOwnProperty(className)) {\r
71749 cls = Ext.ClassManager.get(className);\r
71750 if (cls) {\r
71751 methods = config[className];\r
71752 override = {};\r
71753 for (method in methods) {\r
71754 override[method] = (function(methodName, idProp) {\r
71755 return function() {\r
71756 var before, diff, id, idHolder, ret;\r
71757 before = +Date.now();\r
71758 ret = this.callParent(arguments);\r
71759 diff = +Date.now() - before;\r
71760 if (window.console && diff > 0) {\r
71761 idHolder = idProp === 'this' ? this : typeof idProp === 'string' ? this[idProp] : typeof idProp === 'number' ? arguments[idProp] : null;\r
71762 if (idHolder) {\r
71763 id = idHolder.id;\r
71764 }\r
71765 if (id != null) {\r
71766 console.log(methodName + ' for ' + id + ': ' + diff + 'ms');\r
71767 } else {\r
71768 console.log(methodName + ' for unknown: ' + diff + 'ms');\r
71769 }\r
71770 if (console.trace) {\r
71771 console.trace();\r
71772 }\r
71773 }\r
71774 return ret;\r
71775 };\r
71776 })(method, methods[method]);\r
71777 }\r
71778 Ext.override(cls, override);\r
71779 }\r
71780 }\r
71781 }\r
71782 }\r
71783});\r
71784\r
71785\r
71786Ext.define('Ext.plugin.Abstract', {\r
71787 alternateClassName: 'Ext.AbstractPlugin',\r
71788 \r
71789 isPlugin: true,\r
71790 \r
71791 constructor: function(config) {\r
71792 if (config) {\r
71793 this.pluginConfig = config;\r
71794 this.initConfig(config);\r
71795 }\r
71796 },\r
71797 \r
71798 clonePlugin: function(overrideCfg) {\r
71799 return new this.self(Ext.apply({}, overrideCfg, this.pluginConfig));\r
71800 },\r
71801 \r
71802 setCmp: function(cmp) {\r
71803 this.cmp = cmp;\r
71804 },\r
71805 \r
71806 getCmp: function() {\r
71807 return this.cmp;\r
71808 },\r
71809 \r
71810 \r
71811 init: Ext.emptyFn,\r
71812 \r
71813 destroy: function() {\r
71814 this.cmp = this.pluginConfig = null;\r
71815 this.callParent();\r
71816 },\r
71817
71818
71819 onClassExtended: function(cls, data, hooks) {\r
71820 var alias = data.alias;\r
71821
71822 if (alias && !data.ptype) {\r
71823 if (Ext.isArray(alias)) {\r
71824 alias = alias[0];\r
71825 }\r
71826 cls.prototype.ptype = alias.split('plugin.')[1];\r
71827 }\r
71828 },\r
71829 resolveListenerScope: function(defaultScope) {\r
71830 var me = this,\r
71831 cmp = me.getCmp(),\r
71832 scope;\r
71833 if (cmp) {\r
71834 scope = cmp.resolveSatelliteListenerScope(me, defaultScope);\r
71835 }\r
71836
71837
71838
71839
71840 return scope || me.mixins.observable.resolveListenerScope.call(me, defaultScope);\r
71841 }\r
71842});\r
71843\r
71844\r
71845Ext.define('Ext.plugin.LazyItems', {\r
71846 extend: Ext.plugin.Abstract,\r
71847 alias: 'plugin.lazyitems',\r
71848 init: function(comp) {\r
71849 this.callParent(arguments);\r
71850 if (this.items) {\r
71851
71852 if (this.eagerInstantiation) {\r
71853 this.items = comp.prepareItems(this.items);\r
71854 }\r
71855 }\r
71856
71857 comp.beforeRender = Ext.Function.createInterceptor(comp.beforeRender, this.beforeComponentRender, this);\r
71858 },\r
71859
71860 beforeComponentRender: function() {\r
71861 this.cmp.add(this.items);\r
71862
71863 this.cmp.beforeComponentRender = null;\r
71864 }\r
71865});\r
71866\r
71867\r
71868\r
71869Ext.define('Ext.util.Base64', {\r
71870 singleton: true,\r
71871 \r
71872 _str: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",\r
71873 \r
71874 encode: function(input) {\r
71875 var me = this;\r
71876 var output = '',\r
71877 chr1, chr2, chr3, enc1, enc2, enc3, enc4,\r
71878 i = 0;\r
71879 input = me._utf8_encode(input);\r
71880 var len = input.length;\r
71881 while (i < len) {\r
71882 chr1 = input.charCodeAt(i++);\r
71883 chr2 = input.charCodeAt(i++);\r
71884 chr3 = input.charCodeAt(i++);\r
71885 enc1 = chr1 >> 2;\r
71886 enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\r
71887 enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\r
71888 enc4 = chr3 & 63;\r
71889 if (isNaN(chr2)) {\r
71890 enc3 = enc4 = 64;\r
71891 } else if (isNaN(chr3)) {\r
71892 enc4 = 64;\r
71893 }\r
71894 output = output + me._str.charAt(enc1) + me._str.charAt(enc2) + me._str.charAt(enc3) + me._str.charAt(enc4);\r
71895 }\r
71896 return output;\r
71897 },\r
71898 \r
71899 decode: function(input) {\r
71900 var me = this;\r
71901 var output = '',\r
71902 chr1, chr2, chr3, enc1, enc2, enc3, enc4,\r
71903 i = 0;\r
71904 input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");\r
71905 var len = input.length;\r
71906 while (i < len) {\r
71907 enc1 = me._str.indexOf(input.charAt(i++));\r
71908 enc2 = me._str.indexOf(input.charAt(i++));\r
71909 enc3 = me._str.indexOf(input.charAt(i++));\r
71910 enc4 = me._str.indexOf(input.charAt(i++));\r
71911 chr1 = (enc1 << 2) | (enc2 >> 4);\r
71912 chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\r
71913 chr3 = ((enc3 & 3) << 6) | enc4;\r
71914 output = output + String.fromCharCode(chr1);\r
71915 if (enc3 !== 64) {\r
71916 output = output + String.fromCharCode(chr2);\r
71917 }\r
71918 if (enc4 !== 64) {\r
71919 output = output + String.fromCharCode(chr3);\r
71920 }\r
71921 }\r
71922 output = me._utf8_decode(output);\r
71923 return output;\r
71924 },\r
71925 \r
71926 _utf8_encode: function(string) {\r
71927 string = string.replace(/\r\n/g, "\n");\r
71928 var utftext = '',\r
71929 n = 0,\r
71930 len = string.length;\r
71931 for (; n < len; n++) {\r
71932 var c = string.charCodeAt(n);\r
71933 if (c < 128) {\r
71934 utftext += String.fromCharCode(c);\r
71935 } else if ((c > 127) && (c < 2048)) {\r
71936 utftext += String.fromCharCode((c >> 6) | 192);\r
71937 utftext += String.fromCharCode((c & 63) | 128);\r
71938 } else {\r
71939 utftext += String.fromCharCode((c >> 12) | 224);\r
71940 utftext += String.fromCharCode(((c >> 6) & 63) | 128);\r
71941 utftext += String.fromCharCode((c & 63) | 128);\r
71942 }\r
71943 }\r
71944 return utftext;\r
71945 },\r
71946 \r
71947 _utf8_decode: function(utftext) {\r
71948 var string = '',\r
71949 i = 0,\r
71950 c = 0,\r
71951 c3 = 0,\r
71952 c2 = 0,\r
71953 len = utftext.length;\r
71954 while (i < len) {\r
71955 c = utftext.charCodeAt(i);\r
71956 if (c < 128) {\r
71957 string += String.fromCharCode(c);\r
71958 i++;\r
71959 } else if ((c > 191) && (c < 224)) {\r
71960 c2 = utftext.charCodeAt(i + 1);\r
71961 string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));\r
71962 i += 2;\r
71963 } else {\r
71964 c2 = utftext.charCodeAt(i + 1);\r
71965 c3 = utftext.charCodeAt(i + 2);\r
71966 string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));\r
71967 i += 3;\r
71968 }\r
71969 }\r
71970 return string;\r
71971 }\r
71972});\r
71973\r
71974\r
71975Ext.define('Ext.util.DelimitedValue', {\r
71976 \r
71977 dateFormat: 'C',\r
71978 \r
71979 delimiter: '\t',\r
71980 \r
71981 lineBreak: '\n',\r
71982 \r
71983 quote: '"',\r
71984 parseREs: {},\r
71985 quoteREs: {},\r
71986 lineBreakRe: /\r?\n/g,\r
71987 constructor: function(config) {\r
71988 if (config) {\r
71989 Ext.apply(this, config);\r
71990 }\r
71991 },\r
71992 \r
71993 decode: function(input, delimiter) {\r
71994 var me = this,\r
71995
71996
71997 delim = (delimiter || me.delimiter),\r
71998 row = [],\r
71999 result = [\r
72000 row\r
72001 ],\r
72002 quote = me.quote,\r
72003 quoteREs = me.quoteREs,\r
72004 parseREs = me.parseREs,\r
72005
72006
72007 parseRE = parseREs[delim] || (parseREs[delim] = new RegExp(
72008 "(\\" + delim + "|\\r?\\n|\\r|^)" +
72009 "(?:\\" + quote + "([^\\" + quote + "]*(?:\\" + quote + "\\" + quote + "[^\\" + quote + "]*)*)\\" + quote + "|" +
72010 "([^\"\\" + delim + "\\r\\n]*))", "gi")),\r
72011 dblQuoteRE = quoteREs[quote] || (quoteREs[quote] = new RegExp('\\' + quote + '\\' + quote, 'g')),\r
72012 arrMatches, strMatchedDelimiter, strMatchedValue;\r
72013
72014
72015 while (arrMatches = parseRE.exec(input)) {\r
72016 strMatchedDelimiter = arrMatches[1];\r
72017
72018
72019
72020
72021 if (strMatchedDelimiter.length && strMatchedDelimiter !== delim) {\r
72022
72023
72024 result.push(row = []);\r
72025 }\r
72026
72027
72028
72029 if (arrMatches[2]) {\r
72030
72031
72032 strMatchedValue = arrMatches[2].replace(dblQuoteRE, '"');\r
72033 } else {\r
72034
72035 strMatchedValue = arrMatches[3];\r
72036 }\r
72037 row.push(strMatchedValue);\r
72038 }\r
72039 return result;\r
72040 },\r
72041 \r
72042 encode: function(input, delimiter) {\r
72043 var me = this,\r
72044 delim = delimiter || me.delimiter,\r
72045 dateFormat = me.dateFormat,\r
72046 quote = me.quote,\r
72047 twoQuotes = quote + quote,\r
72048 rowIndex = input.length,\r
72049 lineBreakRe = me.lineBreakRe,\r
72050 result = [],\r
72051 outputRow = [],\r
72052 col, columnIndex, inputRow;\r
72053 while (rowIndex-- > 0) {\r
72054 inputRow = input[rowIndex];\r
72055 outputRow.length = columnIndex = inputRow.length;\r
72056 while (columnIndex-- > 0) {\r
72057 col = inputRow[columnIndex];\r
72058 if (col == null) {\r
72059
72060 col = '';\r
72061 } else if (typeof col === 'string') {\r
72062 if (col) {\r
72063
72064 if (col.indexOf(quote) > -1) {\r
72065 col = quote + col.split(quote).join(twoQuotes) + quote;\r
72066 } else if (col.indexOf(delim) > -1 || lineBreakRe.test(col)) {\r
72067 col = quote + col + quote;\r
72068 }\r
72069 }\r
72070 } else if (Ext.isDate(col)) {\r
72071 col = Ext.Date.format(col, dateFormat);\r
72072 }\r
72073
72074 else if (col && (isNaN(col) || Ext.isArray(col))) {\r
72075 Ext.raise('Cannot serialize ' + Ext.typeOf(col) + ' into CSV');\r
72076 }\r
72077
72078 outputRow[columnIndex] = col;\r
72079 }\r
72080 result[rowIndex] = outputRow.join(delim);\r
72081 }\r
72082 return result.join(me.lineBreak);\r
72083 }\r
72084});\r
72085\r
72086\r
72087Ext.define('Ext.util.CSV', {\r
72088 extend: Ext.util.DelimitedValue,\r
72089 singleton: true,\r
72090 delimiter: ','\r
72091});\r
72092\r
72093\r
72094Ext.define('Ext.util.LocalStorage', {\r
72095 \r
72096 id: null,\r
72097 \r
72098 destroyed: false,\r
72099 \r
72100 lazyKeys: true,\r
72101 \r
72102 prefix: '',\r
72103 \r
72104 session: false,\r
72105 \r
72106 _keys: null,\r
72107 \r
72108 _store: null,\r
72109 \r
72110 _users: 0,\r
72111 statics: {\r
72112 cache: {},\r
72113 \r
72114 get: function(id) {\r
72115 var me = this,\r
72116 cache = me.cache,\r
72117 config = {\r
72118 _users: 1\r
72119 },\r
72120
72121 instance;\r
72122 if (Ext.isString(id)) {\r
72123 config.id = id;\r
72124 } else {\r
72125 Ext.apply(config, id);\r
72126 }\r
72127 if (!(instance = cache[config.id])) {\r
72128 instance = new me(config);\r
72129 } else {\r
72130
72131 if (instance === true) {\r
72132 Ext.raise('Creating a shared instance of private local store "' + me.id + '".');\r
72133 }\r
72134
72135 ++instance._users;\r
72136 }\r
72137 return instance;\r
72138 },\r
72139 \r
72140 supported: true\r
72141 },\r
72142 constructor: function(config) {\r
72143 var me = this;\r
72144 Ext.apply(me, config);\r
72145
72146 if (!me.hasOwnProperty('id')) {\r
72147 Ext.raise("No id was provided to the local store.");\r
72148 }\r
72149
72150 if (me._users) {\r
72151
72152
72153
72154 Ext.util.LocalStorage.cache[me.id] = me;\r
72155 } else
72156 {\r
72157
72158
72159 if (Ext.util.LocalStorage.cache[me.id]) {\r
72160 Ext.raise('Cannot create duplicate instance of local store "' + me.id + '". Use Ext.util.LocalStorage.get() to share instances.');\r
72161 }\r
72162
72163
72164 Ext.util.LocalStorage.cache[me.id] = true;\r
72165 }\r
72166
72167 me.init();\r
72168 },\r
72169 \r
72170 init: function() {\r
72171 var me = this,\r
72172 id = me.id;\r
72173 if (!me.prefix && id) {\r
72174 me.prefix = id + '-';\r
72175 }\r
72176 me._store = (me.session ? window.sessionStorage : window.localStorage);\r
72177 },\r
72178 \r
72179 destroy: function() {\r
72180 var me = this;\r
72181
72182 if (me._users) {\r
72183 Ext.log.warn('LocalStorage(id=' + me.id + ') destroyed while in use');\r
72184 }\r
72185
72186 delete Ext.util.LocalStorage.cache[me.id];\r
72187 me._store = me._keys = null;\r
72188 me.callParent();\r
72189 },\r
72190 \r
72191 getKeys: function() {\r
72192 var me = this,\r
72193 store = me._store,\r
72194 prefix = me.prefix,\r
72195 keys = me._keys,\r
72196 n = prefix.length,\r
72197 i, key;\r
72198 if (!keys) {\r
72199 me._keys = keys = [];\r
72200 for (i = store.length; i--; ) {\r
72201 key = store.key(i);\r
72202 if (key.length > n) {\r
72203 if (prefix === key.substring(0, n)) {\r
72204 keys.push(key.substring(n));\r
72205 }\r
72206 }\r
72207 }\r
72208 }\r
72209 return keys;\r
72210 },\r
72211 \r
72212 release: function() {\r
72213 if (!--this._users) {\r
72214 this.destroy();\r
72215 }\r
72216 },\r
72217 \r
72218 save: Ext.emptyFn,\r
72219 \r
72220 clear: function() {\r
72221 var me = this,\r
72222 store = me._store,\r
72223 prefix = me.prefix,\r
72224 keys = me._keys || me.getKeys(),\r
72225 i;\r
72226 for (i = keys.length; i--; ) {\r
72227 store.removeItem(prefix + keys[i]);\r
72228 }\r
72229 keys.length = 0;\r
72230 },\r
72231 \r
72232 key: function(index) {\r
72233 var keys = this._keys || this.getKeys();\r
72234 return (0 <= index && index < keys.length) ? keys[index] : null;\r
72235 },\r
72236 \r
72237 getItem: function(key) {\r
72238 var k = this.prefix + key;\r
72239 return this._store.getItem(k);\r
72240 },\r
72241 \r
72242 removeItem: function(key) {\r
72243 var me = this,\r
72244 k = me.prefix + key,\r
72245 store = me._store,\r
72246 keys = me._keys,\r
72247 length = store.length;\r
72248 store.removeItem(k);\r
72249 if (keys && length !== store.length) {\r
72250 if (me.lazyKeys) {\r
72251 me._keys = null;\r
72252 } else {\r
72253 Ext.Array.remove(keys, key);\r
72254 }\r
72255 }\r
72256 },\r
72257 \r
72258 setItem: function(key, value) {\r
72259 var me = this,\r
72260 k = me.prefix + key,\r
72261 store = me._store,\r
72262 length = store.length,\r
72263 keys = me._keys;\r
72264 store.setItem(k, value);\r
72265 if (keys && length !== store.length) {\r
72266
72267 keys.push(key);\r
72268 }\r
72269 }\r
72270}, function() {\r
72271 var LocalStorage = this;\r
72272 if ('localStorage' in window) {\r
72273 return;\r
72274 }\r
72275 if (!Ext.isIE) {\r
72276 LocalStorage.supported = false;\r
72277
72278 LocalStorage.prototype.init = function() {\r
72279 Ext.raise("Local storage is not supported on this browser");\r
72280 };\r
72281
72282 return;\r
72283 }\r
72284
72285
72286
72287
72288 LocalStorage.override({\r
72289 \r
72290 data: null,\r
72291 \r
72292 \r
72293 flushDelay: 1,\r
72294 init: function() {\r
72295 var me = this,\r
72296 data = me.data,\r
72297 el;\r
72298 me.el = el = document.createElement('div');\r
72299 el.id = (me.id || (me.id = 'extjs-localstore'));\r
72300 el.addBehavior('#default#userdata');\r
72301
72302 Ext.getHead().dom.appendChild(el);\r
72303 el.load(me.id);\r
72304 data = el.getAttribute('xdata');\r
72305 me.data = data = (data ? Ext.decode(data) : {});\r
72306 me._flushFn = function() {\r
72307 me._timer = null;\r
72308 me.save(0);\r
72309 };\r
72310 },\r
72311 destroy: function() {\r
72312 var me = this,\r
72313 el = me.el;\r
72314 if (el) {\r
72315
72316 if (me._timer) {\r
72317 me.save();\r
72318 }\r
72319 el.parentNode.removeChild(el);\r
72320 me.data = me.el = null;\r
72321 me.callParent();\r
72322 }\r
72323 },\r
72324 getKeys: function() {\r
72325 var me = this,\r
72326 keys = me._keys;\r
72327 if (!keys) {\r
72328 me._keys = keys = Ext.Object.getKeys(me.data);\r
72329 }\r
72330 return keys;\r
72331 },\r
72332 \r
72333 save: function(delay) {\r
72334 var me = this;\r
72335 if (!delay) {\r
72336 if (me._timer) {\r
72337 clearTimeout(me._timer);\r
72338 me._timer = null;\r
72339 }\r
72340 me.el.setAttribute('xdata', Ext.encode(me.data));\r
72341 me.el.save(me.id);\r
72342 } else if (!me._timer) {\r
72343 me._timer = Ext.defer(me._flushFn, delay);\r
72344 }\r
72345 },\r
72346 clear: function() {\r
72347 var me = this;\r
72348 me.data = {};\r
72349 me._keys = null;\r
72350 me.save(me.flushDelay);\r
72351 },\r
72352 getItem: function(key) {\r
72353 var data = this.data;\r
72354 return (key in data) ? data[key] : null;\r
72355 },\r
72356 removeItem: function(key) {\r
72357 var me = this,\r
72358 keys = me._keys,\r
72359 data = me.data;\r
72360 if (key in data) {\r
72361 delete data[key];\r
72362 if (keys) {\r
72363 if (me.lazyKeys) {\r
72364 me._keys = null;\r
72365 } else {\r
72366 Ext.Array.remove(keys, key);\r
72367 }\r
72368 }\r
72369 me.save(me.flushDelay);\r
72370 }\r
72371 },\r
72372 setItem: function(key, value) {\r
72373 var me = this,\r
72374 data = me.data,\r
72375 keys = me._keys;\r
72376 if (keys && !(key in data)) {\r
72377 keys.push(key);\r
72378 }\r
72379 data[key] = value;\r
72380 me.save(me.flushDelay);\r
72381 }\r
72382 });\r
72383});\r
72384\r
72385\r
72386Ext.define('Ext.util.TSV', {\r
72387 extend: Ext.util.DelimitedValue,\r
72388 singleton: true,\r
72389 delimiter: '\t'\r
72390});\r
72391\r
72392
72393\r
72394Ext.define('Ext.util.TaskManager', {\r
72395 extend: Ext.util.TaskRunner,\r
72396 alternateClassName: [\r
72397 'Ext.TaskManager'\r
72398 ],\r
72399 singleton: true\r
72400});\r
72401\r
72402\r
72403Ext.define('Ext.util.TextMetrics', {\r
72404 statics: {\r
72405 shared: null,\r
72406 \r
72407 measure: function(el, text, fixedWidth) {\r
72408 var me = this,\r
72409 shared = me.shared;\r
72410 if (!shared) {\r
72411 shared = me.shared = new me(el, fixedWidth);\r
72412 }\r
72413 shared.bind(el);\r
72414 shared.setFixedWidth(fixedWidth || 'auto');\r
72415 return shared.getSize(text);\r
72416 },\r
72417 \r
72418 destroy: function() {\r
72419 var me = this;\r
72420 Ext.destroy(me.shared);\r
72421 me.shared = null;\r
72422 }\r
72423 },\r
72424 \r
72425 constructor: function(bindTo, fixedWidth) {\r
72426 var me = this,\r
72427 measure = Ext.getBody().createChild({\r
72428
72429
72430 'data-sticky': true,\r
72431
72432 role: 'presentation',\r
72433 cls: Ext.baseCSSPrefix + 'textmetrics'\r
72434 });\r
72435 measure.setVisibilityMode(1);\r
72436 me.measure = measure;\r
72437 if (bindTo) {\r
72438 me.bind(bindTo);\r
72439 }\r
72440 measure.position('absolute');\r
72441 measure.setLocalXY(-1000, -1000);\r
72442 measure.hide();\r
72443 if (fixedWidth) {\r
72444 measure.setWidth(fixedWidth);\r
72445 }\r
72446 },\r
72447 \r
72448 getSize: function(text) {\r
72449 var measure = this.measure,\r
72450 size;\r
72451 measure.setHtml(text);\r
72452 size = measure.getSize();\r
72453 measure.setHtml('');\r
72454 return size;\r
72455 },\r
72456 \r
72457 bind: function(el) {\r
72458 var me = this;\r
72459 me.el = Ext.get(el);\r
72460 me.measure.setStyle(me.el.getStyle([\r
72461 'font-size',\r
72462 'font-style',\r
72463 'font-weight',\r
72464 'font-family',\r
72465 'line-height',\r
72466 'text-transform',\r
72467 'letter-spacing',\r
72468 'word-break'\r
72469 ]));\r
72470 },\r
72471 \r
72472 setFixedWidth: function(width) {\r
72473 this.measure.setWidth(width);\r
72474 },\r
72475 \r
72476 getWidth: function(text) {\r
72477 this.measure.dom.style.width = 'auto';\r
72478 return this.getSize(text).width;\r
72479 },\r
72480 \r
72481 getHeight: function(text) {\r
72482 return this.getSize(text).height;\r
72483 },\r
72484 \r
72485 destroy: function() {\r
72486 var me = this;\r
72487 me.el = me.measure = Ext.destroy(me.measure);\r
72488 me.callParent();\r
72489 }\r
72490}, function() {\r
72491 Ext.Element.override({\r
72492 \r
72493 getTextWidth: function(text, min, max) {\r
72494 return Ext.Number.constrain(Ext.util.TextMetrics.measure(this.dom, Ext.valueFrom(text, this.dom.innerHTML, true)).width, min || 0, max || 1000000);\r
72495 }\r
72496 });\r
72497});\r
72498\r
72499\r
72500Ext.define('Ext.util.paintmonitor.OverflowChange', {\r
72501 extend: Ext.util.paintmonitor.Abstract,\r
72502 eventName: Ext.browser.is.Firefox ? 'overflow' : 'overflowchanged',\r
72503 monitorClass: 'overflowchange',\r
72504 onElementPainted: function(e) {\r
72505 this.getCallback().apply(this.getScope(), this.getArgs());\r
72506 }\r
72507});\r
72508\r
72509\r
72510Ext.define('Ext.AbstractComponent', {\r
72511 extend: Ext.Widget\r
72512});\r
72513\r
72514\r
72515Ext.define('Ext.util.LineSegment', {\r
72516 \r
72517 constructor: function(point1, point2) {\r
72518 var Point = Ext.util.Point;\r
72519 this.point1 = Point.from(point1);\r
72520 this.point2 = Point.from(point2);\r
72521 },\r
72522 \r
72523 intersects: function(lineSegment) {\r
72524 var point1 = this.point1,\r
72525 point2 = this.point2,\r
72526 point3 = lineSegment.point1,\r
72527 point4 = lineSegment.point2,\r
72528 x1 = point1.x,\r
72529 x2 = point2.x,\r
72530 x3 = point3.x,\r
72531 x4 = point4.x,\r
72532 y1 = point1.y,\r
72533 y2 = point2.y,\r
72534 y3 = point3.y,\r
72535 y4 = point4.y,\r
72536 d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4),\r
72537 xi, yi;\r
72538 if (d == 0) {\r
72539 return null;\r
72540 }\r
72541 xi = ((x3 - x4) * (x1 * y2 - y1 * x2) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d;\r
72542 yi = ((y3 - y4) * (x1 * y2 - y1 * x2) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d;\r
72543 if (xi < Math.min(x1, x2) || xi > Math.max(x1, x2) || xi < Math.min(x3, x4) || xi > Math.max(x3, x4) || yi < Math.min(y1, y2) || yi > Math.max(y1, y2) || yi < Math.min(y3, y4) || yi > Math.max(y3, y4)) {\r
72544 return null;\r
72545 }\r
72546 return new Ext.util.Point(xi, yi);\r
72547 },\r
72548 getLength: function() {\r
72549 return Math.abs(this.point1.getDistanceTo(this.point2));\r
72550 },\r
72551 getAngleToX: function() {\r
72552 var point1 = this.point1,\r
72553 point2 = this.point2,\r
72554 deltaY = point2.y - point1.y,\r
72555 deltaX = point2.x - point1.x;\r
72556 return Math.atan2(deltaY, deltaX);\r
72557 },\r
72558 getInBetweenPoint: function(distance) {\r
72559 var point1 = this.point1,\r
72560 angle = this.getAngleToX(),\r
72561 x = point1.x + Math.cos(angle) * distance,\r
72562 y = point1.y + Math.sin(angle) * distance;\r
72563 return new Ext.util.Point(x, y);\r
72564 },\r
72565 \r
72566 toString: function() {\r
72567 return this.point1.toString() + " " + this.point2.toString();\r
72568 }\r
72569});\r
72570\r
72571\r
72572Ext.define('Ext.Panel', {\r
72573 extend: Ext.Container,\r
72574 xtype: 'panel',\r
72575 alternateClassName: 'Ext.panel.Panel',\r
72576 defaultBindProperty: 'title',\r
72577 isPanel: true,\r
72578 config: {\r
72579 baseCls: Ext.baseCSSPrefix + 'panel',\r
72580 \r
72581 border: false,\r
72582 \r
72583 bodyPadding: null,\r
72584 \r
72585 bodyBorder: null,\r
72586 header: null,\r
72587 icon: null,\r
72588 iconCls: null,\r
72589 title: null,\r
72590 tools: null\r
72591 },\r
72592 manageBorders: true,\r
72593 getElementConfig: function() {\r
72594 return {\r
72595 reference: 'element',\r
72596 classList: [\r
72597 'x-container',\r
72598 'x-unsized'\r
72599 ],\r
72600 children: [\r
72601 {\r
72602 reference: 'innerElement',\r
72603 className: 'x-inner'\r
72604 },\r
72605 {\r
72606 reference: 'tipElement',\r
72607 className: 'x-anchor',\r
72608 hidden: true\r
72609 }\r
72610 ]\r
72611 };\r
72612 },\r
72613 \r
72614 addBodyCls: function(cls) {\r
72615 this.innerElement.addCls(cls);\r
72616 return this;\r
72617 },\r
72618 \r
72619 removeBodyCls: function(cls) {\r
72620 this.innerElement.removeCls(cls);\r
72621 return this;\r
72622 },\r
72623 applyBodyPadding: function(bodyPadding) {\r
72624 if (bodyPadding === true) {\r
72625 bodyPadding = 5;\r
72626 }\r
72627 if (bodyPadding) {\r
72628 bodyPadding = Ext.dom.Element.unitizeBox(bodyPadding);\r
72629 }\r
72630 return bodyPadding;\r
72631 },\r
72632 addTool: function(tool) {\r
72633 var header = this.ensureHeader(),\r
72634
72635 items;\r
72636 if (header) {\r
72637 items = header.createTools(Ext.Array.from(tool), this);\r
72638 if (items && items.length) {\r
72639 items = header.add(items);\r
72640 }\r
72641 }\r
72642 return items;\r
72643 },\r
72644 applyHeader: function(newHeader, oldHeader) {\r
72645 var me = this,\r
72646 header = oldHeader;\r
72647 if (newHeader === false) {\r
72648 if (header) {\r
72649 me.remove(header);\r
72650 header = null;\r
72651 }\r
72652 } else if (newHeader) {\r
72653 if (header) {\r
72654 if (newHeader !== true) {\r
72655 header.setConfig(newHeader);\r
72656 }\r
72657 } else {\r
72658
72659 header = me.add(me.createHeader(newHeader));\r
72660 }\r
72661 }\r
72662 return header || null;\r
72663 },\r
72664 applyTools: function(tools) {\r
72665 var header = this.ensureHeader(),\r
72666
72667 items;\r
72668 if (header) {\r
72669
72670 header.clearTools();\r
72671 items = header.createTools(tools, this);\r
72672 if (items && items.length) {\r
72673 header.add(items);\r
72674 }\r
72675 }\r
72676 },\r
72677
72678 createHeader: function(config) {\r
72679 var me = this,\r
72680 ret = {\r
72681 xtype: 'panelheader',\r
72682 docked: 'top',\r
72683 ui: me.getUi()\r
72684 },\r
72685 icon, title;\r
72686 if (config && config !== true) {\r
72687 Ext.merge(ret, config);\r
72688 }\r
72689 if (me.initialized) {\r
72690
72691
72692
72693 title = me.getTitle();\r
72694 if (title != null) {\r
72695 if (typeof title === 'string') {\r
72696 title = {\r
72697 text: title\r
72698 };\r
72699 }\r
72700 Ext.merge(ret, {\r
72701 title: title\r
72702 });\r
72703 }\r
72704 icon = me.getIconCls();\r
72705 if (icon != null) {\r
72706 ret.iconCls = icon;\r
72707 } else {\r
72708 icon = me.getIcon();\r
72709 if (icon != null) {\r
72710 ret.icon = icon;\r
72711 }\r
72712 }\r
72713 }\r
72714 return ret;\r
72715 },\r
72716 updateBorder: function(border, oldBorder) {\r
72717 this.callParent([\r
72718 border,\r
72719 oldBorder\r
72720 ]);\r
72721 if (this.getBodyBorder() === null) {\r
72722 this.setBodyBorderEnabled(border !== false);\r
72723 }\r
72724 },\r
72725 updateBodyPadding: function(newBodyPadding) {\r
72726 this.innerElement.setStyle('padding', newBodyPadding);\r
72727 },\r
72728 updateBodyBorder: function(bodyBorder) {\r
72729 var border = (bodyBorder === null) ? this.getBorder() : bodyBorder;\r
72730 this.setBodyBorderEnabled(bodyBorder !== false);\r
72731 },\r
72732 updateIcon: function(icon) {\r
72733 var header = this.ensureHeader();\r
72734
72735 if (header) {\r
72736 header.setIcon(icon);\r
72737 }\r
72738 },\r
72739 updateIconCls: function(icon) {\r
72740 var header = this.ensureHeader();\r
72741
72742 if (header) {\r
72743 header.setIconCls(icon);\r
72744 }\r
72745 },\r
72746 updateTitle: function(title) {\r
72747 var header = this.ensureHeader();\r
72748
72749 if (header) {\r
72750 header.setTitle(title);\r
72751 }\r
72752 },\r
72753 updateUi: function(ui, oldUi) {\r
72754 var me = this,\r
72755 suffix = 'x-panel-inner-',\r
72756 innerElement = me.innerElement,\r
72757
72758
72759 header = !me.isConfiguring && me.ensureHeader();\r
72760 if (oldUi) {\r
72761 innerElement.removeCls(suffix + oldUi);\r
72762 }\r
72763 if (ui) {\r
72764 innerElement.addCls(suffix + ui);\r
72765 }\r
72766 if (header) {\r
72767 me.getTitle();\r
72768 header.setUi(ui);\r
72769 }\r
72770 me.callParent([\r
72771 ui,\r
72772 oldUi\r
72773 ]);\r
72774 },\r
72775 alignTo: function(component, alignment) {\r
72776 var alignmentInfo = this.getAlignmentInfo(component, alignment);\r
72777 if (alignmentInfo.isAligned) {\r
72778 return;\r
72779 }\r
72780 \r
72781 var tipElement = this.tipElement;\r
72782 tipElement.hide();\r
72783 if (this.currentTipPosition) {\r
72784 tipElement.removeCls('x-anchor-' + this.currentTipPosition);\r
72785 }\r
72786 this.callParent(arguments);\r
72787 var LineSegment = Ext.util.LineSegment,\r
72788 alignToElement = component.isComponent ? component.renderElement : component,\r
72789 element = this.renderElement,\r
72790 alignToBox = alignToElement.getBox(),\r
72791 box = element.getBox(),\r
72792 left = box.left,\r
72793 top = box.top,\r
72794 right = box.right,\r
72795 bottom = box.bottom,\r
72796 centerX = left + (box.width / 2),\r
72797 centerY = top + (box.height / 2),\r
72798 leftTopPoint = {\r
72799 x: left,\r
72800 y: top\r
72801 },\r
72802 rightTopPoint = {\r
72803 x: right,\r
72804 y: top\r
72805 },\r
72806 leftBottomPoint = {\r
72807 x: left,\r
72808 y: bottom\r
72809 },\r
72810 rightBottomPoint = {\r
72811 x: right,\r
72812 y: bottom\r
72813 },\r
72814 boxCenterPoint = {\r
72815 x: centerX,\r
72816 y: centerY\r
72817 },\r
72818 alignToCenterX = alignToBox.left + (alignToBox.width / 2),\r
72819 alignToCenterY = alignToBox.top + (alignToBox.height / 2),\r
72820 alignToBoxCenterPoint = {\r
72821 x: alignToCenterX,\r
72822 y: alignToCenterY\r
72823 },\r
72824 centerLineSegment = new LineSegment(boxCenterPoint, alignToBoxCenterPoint),\r
72825 offsetLeft = 0,\r
72826 offsetTop = 0,\r
72827 tipSize, tipWidth, tipHeight, tipPosition, tipX, tipY;\r
72828 tipElement.setVisibility(false);\r
72829 tipElement.show();\r
72830 tipSize = tipElement.getSize();\r
72831 tipWidth = tipSize.width;\r
72832 tipHeight = tipSize.height;\r
72833 if (centerLineSegment.intersects(new LineSegment(leftTopPoint, rightTopPoint))) {\r
72834 tipX = Math.min(Math.max(alignToCenterX, left + tipWidth), right - (tipWidth));\r
72835 tipY = top;\r
72836 offsetTop = tipHeight + 10;\r
72837 tipPosition = 'top';\r
72838 } else if (centerLineSegment.intersects(new LineSegment(leftTopPoint, leftBottomPoint))) {\r
72839 tipX = left;\r
72840 tipY = Math.min(Math.max(alignToCenterY + (tipWidth / 2), tipWidth * 1.6), bottom - (tipWidth / 2.2));\r
72841 offsetLeft = tipHeight + 10;\r
72842 tipPosition = 'left';\r
72843 } else if (centerLineSegment.intersects(new LineSegment(leftBottomPoint, rightBottomPoint))) {\r
72844 tipX = Math.min(Math.max(alignToCenterX, left + tipWidth), right - tipWidth);\r
72845 tipY = bottom;\r
72846 offsetTop = -tipHeight - 10;\r
72847 tipPosition = 'bottom';\r
72848 } else if (centerLineSegment.intersects(new LineSegment(rightTopPoint, rightBottomPoint))) {\r
72849 tipX = right;\r
72850 tipY = Math.max(Math.min(alignToCenterY - tipHeight, bottom - tipWidth * 1.3), tipWidth / 2);\r
72851 offsetLeft = -tipHeight - 10;\r
72852 tipPosition = 'right';\r
72853 }\r
72854 if (tipX || tipY) {\r
72855 this.currentTipPosition = tipPosition;\r
72856 tipElement.addCls('x-anchor-' + tipPosition);\r
72857 tipElement.setLeft(tipX - left);\r
72858 tipElement.setTop(tipY - top);\r
72859 tipElement.setVisibility(true);\r
72860 this.setLeft(this.getLeft() + offsetLeft);\r
72861 this.setTop(this.getTop() + offsetTop);\r
72862 }\r
72863 },\r
72864 privates: {\r
72865 ensureHeader: function() {\r
72866 var me = this,\r
72867 header;\r
72868 me.getViewModel();\r
72869 me.getItems();\r
72870 header = me.getHeader();\r
72871 if (!header && header !== false) {\r
72872 me.setHeader(true);\r
72873 header = me.getHeader();\r
72874 }\r
72875 return header;\r
72876 },\r
72877 setBodyBorderEnabled: function(enabled) {\r
72878 this.innerElement.setStyle('border-width', enabled ? '' : '0');\r
72879 }\r
72880 }\r
72881});\r
72882\r
72883\r
72884Ext.define('Ext.Button', {\r
72885 extend: Ext.Component,\r
72886 xtype: 'button',\r
72887 isButton: true,\r
72888 \r
72889 \r
72890 cachedConfig: {\r
72891 \r
72892 pressedCls: Ext.baseCSSPrefix + 'button-pressing',\r
72893 \r
72894 badgeCls: Ext.baseCSSPrefix + 'badge',\r
72895 \r
72896 hasBadgeCls: Ext.baseCSSPrefix + 'hasbadge',\r
72897 \r
72898 labelCls: Ext.baseCSSPrefix + 'button-label',\r
72899 \r
72900 iconCls: null,\r
72901 \r
72902 textAlign: null\r
72903 },\r
72904 config: {\r
72905 \r
72906 badgeText: null,\r
72907 \r
72908 text: null,\r
72909 \r
72910 icon: false,\r
72911 \r
72912 iconAlign: 'left',\r
72913 \r
72914 pressedDelay: 0,\r
72915 \r
72916 handler: null,\r
72917 \r
72918 scope: null,\r
72919 \r
72920 autoEvent: null,\r
72921 \r
72922 ui: null,\r
72923 \r
72924 \r
72925 baseCls: Ext.baseCSSPrefix + 'button'\r
72926 },\r
72927 defaultBindProperty: 'text',\r
72928 template: [\r
72929 {\r
72930 tag: 'span',\r
72931 reference: 'badgeElement',\r
72932 hidden: true\r
72933 },\r
72934 {\r
72935 tag: 'span',\r
72936 className: Ext.baseCSSPrefix + 'button-icon',\r
72937 reference: 'iconElement'\r
72938 },\r
72939 {\r
72940 tag: 'span',\r
72941 reference: 'textElement',\r
72942 hidden: true\r
72943 }\r
72944 ],\r
72945 initialize: function() {\r
72946 this.callParent();\r
72947 this.element.on({\r
72948 scope: this,\r
72949 tap: 'onTap',\r
72950 touchstart: 'onPress',\r
72951 touchend: 'onRelease'\r
72952 });\r
72953 },\r
72954 \r
72955 updateBadgeText: function(badgeText) {\r
72956 var element = this.element,\r
72957 badgeElement = this.badgeElement;\r
72958 if (badgeText) {\r
72959 badgeElement.show();\r
72960 badgeElement.setText(badgeText);\r
72961 } else {\r
72962 badgeElement.hide();\r
72963 }\r
72964 element[(badgeText) ? 'addCls' : 'removeCls'](this.getHasBadgeCls());\r
72965 },\r
72966 \r
72967 updateText: function(text) {\r
72968 var textElement = this.textElement;\r
72969 if (textElement) {\r
72970 if (text) {\r
72971 textElement.show();\r
72972 textElement.setHtml(text);\r
72973 } else {\r
72974 textElement.hide();\r
72975 }\r
72976 this.refreshIconAlign();\r
72977 }\r
72978 },\r
72979 \r
72980 updateHtml: function(html) {\r
72981 var textElement = this.textElement;\r
72982 if (html) {\r
72983 textElement.show();\r
72984 textElement.setHtml(html);\r
72985 } else {\r
72986 textElement.hide();\r
72987 }\r
72988 },\r
72989 \r
72990 updateBadgeCls: function(badgeCls, oldBadgeCls) {\r
72991 this.badgeElement.replaceCls(oldBadgeCls, badgeCls);\r
72992 },\r
72993 \r
72994 updateHasBadgeCls: function(hasBadgeCls, oldHasBadgeCls) {\r
72995 var element = this.element;\r
72996 if (element.hasCls(oldHasBadgeCls)) {\r
72997 element.replaceCls(oldHasBadgeCls, hasBadgeCls);\r
72998 }\r
72999 },\r
73000 \r
73001 updateLabelCls: function(labelCls, oldLabelCls) {\r
73002 this.textElement.replaceCls(oldLabelCls, labelCls);\r
73003 },\r
73004 \r
73005 updatePressedCls: function(pressedCls, oldPressedCls) {\r
73006 var element = this.element;\r
73007 if (element.hasCls(oldPressedCls)) {\r
73008 element.replaceCls(oldPressedCls, pressedCls);\r
73009 }\r
73010 },\r
73011 \r
73012 updateIcon: function(icon) {\r
73013 var me = this,\r
73014 element = me.iconElement;\r
73015 if (icon) {\r
73016 me.showIconElement();\r
73017 element.setStyle('background-image', 'url(' + icon + ')');\r
73018 me.refreshIconAlign();\r
73019 } else {\r
73020 element.setStyle('background-image', '');\r
73021 if (!me.getIconCls()) {\r
73022 me.hideIconElement();\r
73023 }\r
73024 }\r
73025 },\r
73026 \r
73027 updateIconCls: function(iconCls, oldIconCls) {\r
73028 var me = this,\r
73029 element = me.iconElement;\r
73030 if (iconCls) {\r
73031 me.showIconElement();\r
73032 element.replaceCls(oldIconCls, iconCls);\r
73033 me.refreshIconAlign();\r
73034 } else {\r
73035 element.removeCls(oldIconCls);\r
73036 if (!me.getIcon()) {\r
73037 me.hideIconElement();\r
73038 }\r
73039 }\r
73040 },\r
73041 \r
73042 updateIconAlign: function(alignment, oldAlignment) {\r
73043 var element = this.element,\r
73044 baseCls = Ext.baseCSSPrefix + 'iconalign-';\r
73045 if (!this.getText()) {\r
73046 alignment = 'center';\r
73047 }\r
73048 element.removeCls(baseCls + 'center');\r
73049 element.removeCls(baseCls + oldAlignment);\r
73050 if (this.getIcon() || this.getIconCls()) {\r
73051 element.addCls(baseCls + alignment);\r
73052 }\r
73053 },\r
73054 _textAlignCls: {\r
73055 left: Ext.baseCSSPrefix + 'text-align-left',\r
73056 right: Ext.baseCSSPrefix + 'text-align-right',\r
73057 center: ''\r
73058 },\r
73059 updateTextAlign: function(textAlign, oldValue) {\r
73060 var textAlignClasses = this._textAlignCls,\r
73061 add = textAlignClasses[textAlign || 'center'],\r
73062 remove = textAlignClasses[oldValue || 'center'];\r
73063 this.replaceCls(remove, add);\r
73064 },\r
73065 refreshIconAlign: function() {\r
73066 this.updateIconAlign(this.getIconAlign());\r
73067 },\r
73068 applyAutoEvent: function(autoEvent) {\r
73069 var me = this;\r
73070 if (typeof autoEvent == 'string') {\r
73071 autoEvent = {\r
73072 name: autoEvent,\r
73073 scope: me.scope || me\r
73074 };\r
73075 }\r
73076 return autoEvent;\r
73077 },\r
73078 \r
73079 updateAutoEvent: function(autoEvent) {\r
73080 var name = autoEvent.name,\r
73081 scope = autoEvent.scope;\r
73082 this.setHandler(function() {\r
73083 scope.fireEvent(name, scope, this);\r
73084 });\r
73085 this.setScope(scope);\r
73086 },\r
73087 \r
73088 hideIconElement: function() {\r
73089 var el = this.iconElement;\r
73090 el.removeCls(Ext.baseCSSPrefix + 'shown');\r
73091 el.addCls(Ext.baseCSSPrefix + 'hidden');\r
73092 this.element.addCls(Ext.baseCSSPrefix + 'button-no-icon');\r
73093 },\r
73094 \r
73095 showIconElement: function() {\r
73096 var el = this.iconElement;\r
73097 el.addCls(Ext.baseCSSPrefix + 'shown');\r
73098 el.removeCls(Ext.baseCSSPrefix + 'hidden');\r
73099 this.element.removeCls(Ext.baseCSSPrefix + 'button-no-icon');\r
73100 },\r
73101 \r
73102 applyUi: function(config) {\r
73103 if (config && Ext.isString(config)) {\r
73104 var array = config.split('-');\r
73105 if (array && (array[1] == "back" || array[1] == "forward")) {\r
73106 return array;\r
73107 }\r
73108 }\r
73109 return config;\r
73110 },\r
73111 getUi: function() {\r
73112
73113 var ui = this._ui;\r
73114 if (Ext.isArray(ui)) {\r
73115 return ui.join('-');\r
73116 }\r
73117 return ui;\r
73118 },\r
73119 applyPressedDelay: function(delay) {\r
73120 if (Ext.isNumber(delay)) {\r
73121 return delay;\r
73122 }\r
73123 return (delay) ? 100 : 0;\r
73124 },\r
73125 \r
73126 onPress: function() {\r
73127 var me = this,\r
73128 element = me.element,\r
73129 pressedDelay = me.getPressedDelay(),\r
73130 pressedCls = me.getPressedCls();\r
73131 if (!me.getDisabled()) {\r
73132 if (pressedDelay > 0) {\r
73133 me.pressedTimeout = Ext.defer(function() {\r
73134 delete me.pressedTimeout;\r
73135 if (element) {\r
73136 element.addCls(pressedCls);\r
73137 }\r
73138 }, pressedDelay);\r
73139 } else {\r
73140 element.addCls(pressedCls);\r
73141 }\r
73142 }\r
73143 },\r
73144 \r
73145 onRelease: function(e) {\r
73146 this.fireAction('release', [\r
73147 this,\r
73148 e\r
73149 ], 'doRelease');\r
73150 },\r
73151 \r
73152 doRelease: function(me, e) {\r
73153 if (!me.getDisabled()) {\r
73154 if (me.hasOwnProperty('pressedTimeout')) {\r
73155 clearTimeout(me.pressedTimeout);\r
73156 delete me.pressedTimeout;\r
73157 } else {\r
73158 me.element.removeCls(me.getPressedCls());\r
73159 }\r
73160 }\r
73161 },\r
73162 \r
73163 onTap: function(e) {\r
73164 if (this.getDisabled()) {\r
73165 return false;\r
73166 }\r
73167 this.fireAction('tap', [\r
73168 this,\r
73169 e\r
73170 ], 'doTap');\r
73171 },\r
73172 \r
73173 doTap: function(me, e) {\r
73174 var handler = me.getHandler();\r
73175 if (!handler) {\r
73176 return;\r
73177 }\r
73178
73179
73180 if (e && e.preventDefault) {\r
73181 e.preventDefault();\r
73182 }\r
73183 Ext.callback(handler, me.getScope(), [\r
73184 me,\r
73185 e\r
73186 ], 0, me);\r
73187 }\r
73188});\r
73189\r
73190\r
73191Ext.define('Ext.Sheet', {\r
73192 extend: Ext.Panel,\r
73193 xtype: 'sheet',\r
73194 config: {\r
73195 \r
73196 baseCls: Ext.baseCSSPrefix + 'sheet',\r
73197 \r
73198 modal: true,\r
73199 \r
73200 centered: true,\r
73201 \r
73202 stretchX: null,\r
73203 \r
73204 stretchY: null,\r
73205 \r
73206 enter: 'bottom',\r
73207 \r
73208 exit: 'bottom',\r
73209 \r
73210 showAnimation: {\r
73211 type: 'slideIn',\r
73212 duration: 250,\r
73213 easing: 'ease-out'\r
73214 },\r
73215 \r
73216 hideAnimation: {\r
73217 type: 'slideOut',\r
73218 duration: 250,\r
73219 easing: 'ease-in'\r
73220 },\r
73221 \r
73222 border: null\r
73223 },\r
73224 manageBorders: false,\r
73225 isInputRegex: /^(input|textarea|select|a)$/i,\r
73226 beforeInitialize: function() {\r
73227 var me = this;\r
73228
73229
73230 if (Ext.os.is.iOS) {\r
73231 this.element.dom.addEventListener('touchstart', function(e) {\r
73232 if (!me.isInputRegex.test(e.target.tagName)) {\r
73233 e.preventDefault();\r
73234 }\r
73235 }, true);\r
73236 }\r
73237 },\r
73238 applyHideAnimation: function(config) {\r
73239 var exit = this.getExit(),\r
73240 direction = exit;\r
73241 if (exit === null) {\r
73242 return null;\r
73243 }\r
73244 if (config === true) {\r
73245 config = {\r
73246 type: 'slideOut'\r
73247 };\r
73248 }\r
73249 if (Ext.isString(config)) {\r
73250 config = {\r
73251 type: config\r
73252 };\r
73253 }\r
73254 var anim = Ext.factory(config, Ext.fx.Animation);\r
73255 if (anim) {\r
73256 if (exit == 'bottom') {\r
73257 direction = 'down';\r
73258 }\r
73259 if (exit == 'top') {\r
73260 direction = 'up';\r
73261 }\r
73262 anim.setDirection(direction);\r
73263 }\r
73264 return anim;\r
73265 },\r
73266 applyShowAnimation: function(config) {\r
73267 var enter = this.getEnter(),\r
73268 direction = enter;\r
73269 if (enter === null) {\r
73270 return null;\r
73271 }\r
73272 if (config === true) {\r
73273 config = {\r
73274 type: 'slideIn'\r
73275 };\r
73276 }\r
73277 if (Ext.isString(config)) {\r
73278 config = {\r
73279 type: config\r
73280 };\r
73281 }\r
73282 var anim = Ext.factory(config, Ext.fx.Animation);\r
73283 if (anim) {\r
73284 if (enter == 'bottom') {\r
73285 direction = 'down';\r
73286 }\r
73287 if (enter == 'top') {\r
73288 direction = 'up';\r
73289 }\r
73290 anim.setBefore({\r
73291 display: null\r
73292 });\r
73293 anim.setReverse(true);\r
73294 anim.setDirection(direction);\r
73295 }\r
73296 return anim;\r
73297 },\r
73298 updateStretchX: function(newStretchX) {\r
73299 this.getLeft();\r
73300 this.getRight();\r
73301 if (newStretchX) {\r
73302 this.setLeft(0);\r
73303 this.setRight(0);\r
73304 }\r
73305 },\r
73306 updateStretchY: function(newStretchY) {\r
73307 this.getTop();\r
73308 this.getBottom();\r
73309 if (newStretchY) {\r
73310 this.setTop(0);\r
73311 this.setBottom(0);\r
73312 }\r
73313 }\r
73314});\r
73315\r
73316\r
73317Ext.define('Ext.ActionSheet', {\r
73318 extend: Ext.Sheet,\r
73319 alias: 'widget.actionsheet',\r
73320 config: {\r
73321 \r
73322 baseCls: Ext.baseCSSPrefix + 'sheet-action',\r
73323 \r
73324 left: 0,\r
73325 \r
73326 right: 0,\r
73327 \r
73328 bottom: 0,\r
73329
73330 centered: false,\r
73331 \r
73332 height: 'auto',\r
73333 \r
73334 defaultType: 'button'\r
73335 }\r
73336});\r
73337\r
73338\r
73339Ext.define('Ext.Anim', {\r
73340 isAnim: true,\r
73341 \r
73342 disableAnimations: false,\r
73343 defaultConfig: {\r
73344 \r
73345 from: {},\r
73346 \r
73347 to: {},\r
73348 \r
73349 duration: 250,\r
73350 \r
73351 delay: 0,\r
73352 \r
73353 easing: 'ease-in-out',\r
73354 \r
73355 autoClear: true,\r
73356 \r
73357 out: true,\r
73358 \r
73359 direction: null,\r
73360 \r
73361 reverse: false\r
73362 },\r
73363 \r
73364 \r
73365 \r
73366 opposites: {\r
73367 'left': 'right',\r
73368 'right': 'left',\r
73369 'up': 'down',\r
73370 'down': 'up'\r
73371 },\r
73372 \r
73373 constructor: function(config) {\r
73374 config = Ext.apply({}, config || {}, this.defaultConfig);\r
73375 this.config = config;\r
73376 this.callParent([\r
73377 config\r
73378 ]);\r
73379 this.running = [];\r
73380 },\r
73381 initConfig: function(el, runConfig) {\r
73382 var me = this,\r
73383 config = Ext.apply({}, runConfig || {}, me.config);\r
73384 config.el = el = Ext.get(el);\r
73385 if (config.reverse && me.opposites[config.direction]) {\r
73386 config.direction = me.opposites[config.direction];\r
73387 }\r
73388 if (me.config.before) {\r
73389 me.config.before.call(config, el, config);\r
73390 }\r
73391 if (runConfig.before) {\r
73392 runConfig.before.call(config.scope || config, el, config);\r
73393 }\r
73394 return config;\r
73395 },\r
73396 \r
73397 run: function(el, config) {\r
73398 el = Ext.get(el);\r
73399 config = config || {};\r
73400 var me = this,\r
73401 style = el.dom.style,\r
73402 property,\r
73403 after = config.after;\r
73404 if (me.running[el.id]) {\r
73405 me.onTransitionEnd(null, el, {\r
73406 config: config,\r
73407 after: after\r
73408 });\r
73409 }\r
73410 config = this.initConfig(el, config);\r
73411 if (this.disableAnimations) {\r
73412 for (property in config.to) {\r
73413 if (!config.to.hasOwnProperty(property)) {\r
73414 \r
73415 continue;\r
73416 }\r
73417 style[property] = config.to[property];\r
73418 }\r
73419 this.onTransitionEnd(null, el, {\r
73420 config: config,\r
73421 after: after\r
73422 });\r
73423 return me;\r
73424 }\r
73425 el.un('transitionend', me.onTransitionEnd, me);\r
73426 style.webkitTransitionDuration = '0ms';\r
73427 for (property in config.from) {\r
73428 if (!config.from.hasOwnProperty(property)) {\r
73429 \r
73430 continue;\r
73431 }\r
73432 style[property] = config.from[property];\r
73433 }\r
73434 Ext.defer(function() {\r
73435
73436 if (!el.dom) {\r
73437 return;\r
73438 }\r
73439
73440 if (config.is3d === true) {\r
73441 el.parent().setStyle({\r
73442
73443 '-webkit-perspective': '1200',\r
73444 '-webkit-transform-style': 'preserve-3d'\r
73445 });\r
73446 }\r
73447 style.webkitTransitionDuration = config.duration + 'ms';\r
73448 style.webkitTransitionProperty = 'all';\r
73449 style.webkitTransitionTimingFunction = config.easing;\r
73450
73451 el.on('transitionend', me.onTransitionEnd, me, {\r
73452 single: true,\r
73453 config: config,\r
73454 after: after\r
73455 });\r
73456 for (property in config.to) {\r
73457 if (!config.to.hasOwnProperty(property)) {\r
73458 \r
73459 continue;\r
73460 }\r
73461 style[property] = config.to[property];\r
73462 }\r
73463 }, config.delay || 5);\r
73464 me.running[el.id] = config;\r
73465 return me;\r
73466 },\r
73467 onTransitionEnd: function(ev, el, o) {\r
73468 el = Ext.get(el);\r
73469 if (this.running[el.id] === undefined) {\r
73470 return;\r
73471 }\r
73472 var style = el.dom.style,\r
73473 config = o.config,\r
73474 me = this,\r
73475 property;\r
73476 if (config.autoClear) {\r
73477 for (property in config.to) {\r
73478 if (!config.to.hasOwnProperty(property) || config[property] === false) {\r
73479 \r
73480 continue;\r
73481 }\r
73482 style[property] = '';\r
73483 }\r
73484 }\r
73485 style.webkitTransitionDuration = null;\r
73486 style.webkitTransitionProperty = null;\r
73487 style.webkitTransitionTimingFunction = null;\r
73488 if (config.is3d) {\r
73489 el.parent().setStyle({\r
73490 '-webkit-perspective': '',\r
73491 '-webkit-transform-style': ''\r
73492 });\r
73493 }\r
73494 if (me.config.after) {\r
73495 me.config.after.call(config, el, config);\r
73496 }\r
73497 if (o.after) {\r
73498 o.after.call(config.scope || me, el, config);\r
73499 }\r
73500 delete me.running[el.id];\r
73501 }\r
73502}, function() {\r
73503 Ext.Anim.seed = 1000;\r
73504 \r
73505 Ext.Anim.run = function(el, anim, config) {\r
73506 if (el.isComponent) {\r
73507 el = el.element;\r
73508 } else {\r
73509 el = Ext.get(el);\r
73510 }\r
73511 config = config || {};\r
73512 if (anim.isAnim) {\r
73513 anim.run(el, config);\r
73514 } else {\r
73515 if (Ext.isObject(anim)) {\r
73516 if (config.before && anim.before) {\r
73517 config.before = Ext.createInterceptor(config.before, anim.before, anim.scope);\r
73518 }\r
73519 if (config.after && anim.after) {\r
73520 config.after = Ext.createInterceptor(config.after, anim.after, anim.scope);\r
73521 }\r
73522 config = Ext.apply({}, config, anim);\r
73523 anim = anim.type;\r
73524 }\r
73525 if (!Ext.anims[anim]) {\r
73526 throw anim + ' is not a valid animation type.';\r
73527 } else {\r
73528
73529 if (el && el.dom) {\r
73530 Ext.anims[anim].run(el, config);\r
73531 }\r
73532 }\r
73533 }\r
73534 };\r
73535 \r
73536 Ext.anims = {\r
73537 \r
73538 fade: new Ext.Anim({\r
73539 type: 'fade',\r
73540 before: function(el) {\r
73541 var fromOpacity = 1,\r
73542 toOpacity = 1,\r
73543 curZ = el.getStyle('z-index') == 'auto' ? 0 : el.getStyle('z-index'),\r
73544 zIndex = curZ;\r
73545 if (this.out) {\r
73546 toOpacity = 0;\r
73547 } else {\r
73548 zIndex = Math.abs(curZ) + 1;\r
73549 fromOpacity = 0;\r
73550 }\r
73551 this.from = {\r
73552 'opacity': fromOpacity,\r
73553 'z-index': zIndex\r
73554 };\r
73555 this.to = {\r
73556 'opacity': toOpacity,\r
73557 'z-index': zIndex\r
73558 };\r
73559 }\r
73560 }),\r
73561 \r
73562 slide: new Ext.Anim({\r
73563 direction: 'left',\r
73564 cover: false,\r
73565 reveal: false,\r
73566 opacity: false,\r
73567 'z-index': false,\r
73568 before: function(el) {\r
73569 var currentZIndex = el.getStyle('z-index') == 'auto' ? 0 : el.getStyle('z-index'),\r
73570 currentOpacity = el.getStyle('opacity'),\r
73571 zIndex = currentZIndex + 1,\r
73572 out = this.out,\r
73573 direction = this.direction,\r
73574 toX = 0,\r
73575 toY = 0,\r
73576 fromX = 0,\r
73577 fromY = 0,\r
73578 elH = el.getHeight(),\r
73579 elW = el.getWidth();\r
73580 if (direction == 'left' || direction == 'right') {\r
73581 if (out) {\r
73582 toX = -elW;\r
73583 } else {\r
73584 fromX = elW;\r
73585 }\r
73586 } else if (direction == 'up' || direction == 'down') {\r
73587 if (out) {\r
73588 toY = -elH;\r
73589 } else {\r
73590 fromY = elH;\r
73591 }\r
73592 }\r
73593 if (direction == 'right' || direction == 'down') {\r
73594 toY *= -1;\r
73595 toX *= -1;\r
73596 fromY *= -1;\r
73597 fromX *= -1;\r
73598 }\r
73599 if (this.cover && out) {\r
73600 toX = 0;\r
73601 toY = 0;\r
73602 zIndex = currentZIndex;\r
73603 } else if (this.reveal && !out) {\r
73604 fromX = 0;\r
73605 fromY = 0;\r
73606 zIndex = currentZIndex;\r
73607 }\r
73608 this.from = {\r
73609 '-webkit-transform': 'translate3d(' + fromX + 'px, ' + fromY + 'px, 0)',\r
73610 'z-index': zIndex,\r
73611 'opacity': currentOpacity - 0.01\r
73612 };\r
73613 this.to = {\r
73614 '-webkit-transform': 'translate3d(' + toX + 'px, ' + toY + 'px, 0)',\r
73615 'z-index': zIndex,\r
73616 'opacity': currentOpacity\r
73617 };\r
73618 }\r
73619 }),\r
73620 \r
73621 pop: new Ext.Anim({\r
73622 scaleOnExit: true,\r
73623 before: function(el) {\r
73624 var fromScale = 1,\r
73625 toScale = 1,\r
73626 fromOpacity = 1,\r
73627 toOpacity = 1,\r
73628 curZ = el.getStyle('z-index') == 'auto' ? 0 : el.getStyle('z-index'),\r
73629 fromZ = curZ,\r
73630 toZ = curZ;\r
73631 if (!this.out) {\r
73632 fromScale = 0.01;\r
73633 fromZ = curZ + 1;\r
73634 toZ = curZ + 1;\r
73635 fromOpacity = 0;\r
73636 } else {\r
73637 if (this.scaleOnExit) {\r
73638 toScale = 0.01;\r
73639 toOpacity = 0;\r
73640 } else {\r
73641 toOpacity = 0.8;\r
73642 }\r
73643 }\r
73644 this.from = {\r
73645 '-webkit-transform': 'scale(' + fromScale + ')',\r
73646 '-webkit-transform-origin': '50% 50%',\r
73647 'opacity': fromOpacity,\r
73648 'z-index': fromZ\r
73649 };\r
73650 this.to = {\r
73651 '-webkit-transform': 'scale(' + toScale + ')',\r
73652 '-webkit-transform-origin': '50% 50%',\r
73653 'opacity': toOpacity,\r
73654 'z-index': toZ\r
73655 };\r
73656 }\r
73657 }),\r
73658 \r
73659 flip: new Ext.Anim({\r
73660 is3d: true,\r
73661 direction: 'left',\r
73662 before: function(el) {\r
73663 var rotateProp = 'Y',\r
73664 fromScale = 1,\r
73665 toScale = 1,\r
73666 fromRotate = 0,\r
73667 toRotate = 0;\r
73668 if (this.out) {\r
73669 toRotate = -180;\r
73670 toScale = 0.8;\r
73671 } else {\r
73672 fromRotate = 180;\r
73673 fromScale = 0.8;\r
73674 }\r
73675 if (this.direction == 'up' || this.direction == 'down') {\r
73676 rotateProp = 'X';\r
73677 }\r
73678 if (this.direction == 'right' || this.direction == 'left') {\r
73679 toRotate *= -1;\r
73680 fromRotate *= -1;\r
73681 }\r
73682 this.from = {\r
73683 '-webkit-transform': 'rotate' + rotateProp + '(' + fromRotate + 'deg) scale(' + fromScale + ')',\r
73684 '-webkit-backface-visibility': 'hidden'\r
73685 };\r
73686 this.to = {\r
73687 '-webkit-transform': 'rotate' + rotateProp + '(' + toRotate + 'deg) scale(' + toScale + ')',\r
73688 '-webkit-backface-visibility': 'hidden'\r
73689 };\r
73690 }\r
73691 }),\r
73692 \r
73693 cube: new Ext.Anim({\r
73694 is3d: true,\r
73695 direction: 'left',\r
73696 style: 'outer',\r
73697 before: function(el) {\r
73698 var origin = '0% 0%',\r
73699 fromRotate = 0,\r
73700 toRotate = 0,\r
73701 rotateProp = 'Y',\r
73702 fromZ = 0,\r
73703 toZ = 0,\r
73704 elW = el.getWidth(),\r
73705 elH = el.getHeight(),\r
73706 showTranslateZ = true,\r
73707 fromTranslate = ' translateX(0)',\r
73708 toTranslate = '';\r
73709 if (this.direction == 'left' || this.direction == 'right') {\r
73710 if (this.out) {\r
73711 origin = '100% 100%';\r
73712 toZ = elW;\r
73713 toRotate = -90;\r
73714 } else {\r
73715 origin = '0% 0%';\r
73716 fromZ = elW;\r
73717 fromRotate = 90;\r
73718 }\r
73719 } else if (this.direction == 'up' || this.direction == 'down') {\r
73720 rotateProp = 'X';\r
73721 if (this.out) {\r
73722 origin = '100% 100%';\r
73723 toZ = elH;\r
73724 toRotate = 90;\r
73725 } else {\r
73726 origin = '0% 0%';\r
73727 fromZ = elH;\r
73728 fromRotate = -90;\r
73729 }\r
73730 }\r
73731 if (this.direction == 'down' || this.direction == 'right') {\r
73732 fromRotate *= -1;\r
73733 toRotate *= -1;\r
73734 origin = (origin == '0% 0%') ? '100% 100%' : '0% 0%';\r
73735 }\r
73736 if (this.style == 'inner') {\r
73737 fromZ *= -1;\r
73738 toZ *= -1;\r
73739 fromRotate *= -1;\r
73740 toRotate *= -1;\r
73741 if (!this.out) {\r
73742 toTranslate = ' translateX(0px)';\r
73743 origin = '0% 50%';\r
73744 } else {\r
73745 toTranslate = fromTranslate;\r
73746 origin = '100% 50%';\r
73747 }\r
73748 }\r
73749 this.from = {\r
73750 '-webkit-transform': 'rotate' + rotateProp + '(' + fromRotate + 'deg)' + (showTranslateZ ? ' translateZ(' + fromZ + 'px)' : '') + fromTranslate,\r
73751 '-webkit-transform-origin': origin\r
73752 };\r
73753 this.to = {\r
73754 '-webkit-transform': 'rotate' + rotateProp + '(' + toRotate + 'deg) translateZ(' + toZ + 'px)' + toTranslate,\r
73755 '-webkit-transform-origin': origin\r
73756 };\r
73757 },\r
73758 duration: 250\r
73759 }),\r
73760 \r
73761 wipe: new Ext.Anim({\r
73762 before: function(el) {\r
73763 var curZ = el.getStyle('z-index'),\r
73764 zIndex,\r
73765 mask = '';\r
73766 if (!this.out) {\r
73767 zIndex = curZ + 1;\r
73768 mask = '-webkit-gradient(linear, left bottom, right bottom, from(transparent), to(#000), color-stop(66%, #000), color-stop(33%, transparent))';\r
73769 this.from = {\r
73770 '-webkit-mask-image': mask,\r
73771 '-webkit-mask-size': el.getWidth() * 3 + 'px ' + el.getHeight() + 'px',\r
73772 'z-index': zIndex,\r
73773 '-webkit-mask-position-x': 0\r
73774 };\r
73775 this.to = {\r
73776 '-webkit-mask-image': mask,\r
73777 '-webkit-mask-size': el.getWidth() * 3 + 'px ' + el.getHeight() + 'px',\r
73778 'z-index': zIndex,\r
73779 '-webkit-mask-position-x': -el.getWidth() * 2 + 'px'\r
73780 };\r
73781 }\r
73782 },\r
73783 duration: 500\r
73784 })\r
73785 };\r
73786});\r
73787\r
73788\r
73789Ext.define('Ext.Media', {\r
73790 extend: Ext.Component,\r
73791 xtype: 'media',\r
73792 \r
73793 \r
73794 \r
73795 \r
73796 \r
73797 \r
73798 \r
73799 config: {\r
73800 \r
73801 url: '',\r
73802 \r
73803 enableControls: Ext.os.is.Android ? false : true,\r
73804 \r
73805 autoResume: false,\r
73806 \r
73807 autoPause: true,\r
73808 \r
73809 preload: true,\r
73810 \r
73811 loop: false,\r
73812 \r
73813 media: null,\r
73814 \r
73815 volume: 1,\r
73816 \r
73817 muted: false\r
73818 },\r
73819 constructor: function() {\r
73820 this.mediaEvents = {};\r
73821 this.callParent(arguments);\r
73822 },\r
73823 initialize: function() {\r
73824 var me = this;\r
73825 me.callParent();\r
73826 me.on({\r
73827 scope: me,\r
73828 show: me.onActivate,\r
73829 hide: me.onDeactivate\r
73830 });\r
73831 me.addMediaListener({\r
73832 canplay: 'onCanPlay',\r
73833 play: 'onPlay',\r
73834 pause: 'onPause',\r
73835 ended: 'onEnd',\r
73836 volumechange: 'onVolumeChange',\r
73837 timeupdate: 'onTimeUpdate'\r
73838 });\r
73839 },\r
73840 addMediaListener: function(event, fn) {\r
73841 var me = this,\r
73842 dom = me.media.dom,\r
73843 bind = Ext.Function.bind;\r
73844 Ext.Object.each(event, function(e, fn) {\r
73845 fn = bind(me[fn], me);\r
73846 me.mediaEvents[e] = fn;\r
73847 dom.addEventListener(e, fn);\r
73848 });\r
73849 },\r
73850 onPlay: function() {\r
73851 this.fireEvent('play', this);\r
73852 },\r
73853 onCanPlay: function() {\r
73854 this.fireEvent('canplay', this);\r
73855 },\r
73856 onPause: function() {\r
73857 this.fireEvent('pause', this, this.getCurrentTime());\r
73858 },\r
73859 onEnd: function() {\r
73860 this.fireEvent('ended', this, this.getCurrentTime());\r
73861 },\r
73862 onVolumeChange: function() {\r
73863 this.fireEvent('volumechange', this, this.media.dom.volume);\r
73864 },\r
73865 onTimeUpdate: function() {\r
73866 this.fireEvent('timeupdate', this, this.getCurrentTime());\r
73867 },\r
73868 \r
73869 isPlaying: function() {\r
73870 return !Boolean(this.media.dom.paused);\r
73871 },\r
73872 \r
73873 onActivate: function() {\r
73874 var me = this;\r
73875 if (me.getAutoResume() && !me.isPlaying()) {\r
73876 me.play();\r
73877 }\r
73878 },\r
73879 \r
73880 onDeactivate: function() {\r
73881 var me = this;\r
73882 if (me.getAutoPause() && me.isPlaying()) {\r
73883 me.pause();\r
73884 }\r
73885 },\r
73886 \r
73887 updateUrl: function(newUrl) {\r
73888 var dom = this.media.dom;\r
73889
73890
73891 dom.src = newUrl;\r
73892 if ('load' in dom) {\r
73893 dom.load();\r
73894 }\r
73895 if (this.isPlaying()) {\r
73896 this.play();\r
73897 }\r
73898 },\r
73899 \r
73900 updateEnableControls: function(enableControls) {\r
73901 this.media.dom.controls = enableControls ? 'controls' : false;\r
73902 },\r
73903 \r
73904 updateLoop: function(loop) {\r
73905 this.media.dom.loop = loop ? 'loop' : false;\r
73906 },\r
73907 \r
73908 play: function() {\r
73909 var dom = this.media.dom;\r
73910 if ('play' in dom) {\r
73911 dom.play();\r
73912 Ext.defer(function() {\r
73913 dom.play();\r
73914 }, 10);\r
73915 }\r
73916 },\r
73917 \r
73918 pause: function() {\r
73919 var dom = this.media.dom;\r
73920 if ('pause' in dom) {\r
73921 dom.pause();\r
73922 }\r
73923 },\r
73924 \r
73925 toggle: function() {\r
73926 if (this.isPlaying()) {\r
73927 this.pause();\r
73928 } else {\r
73929 this.play();\r
73930 }\r
73931 },\r
73932 \r
73933 stop: function() {\r
73934 var me = this;\r
73935 me.setCurrentTime(0);\r
73936 me.fireEvent('stop', me);\r
73937 me.pause();\r
73938 },\r
73939 \r
73940 updateVolume: function(volume) {\r
73941 this.media.dom.volume = volume;\r
73942 },\r
73943 \r
73944 updateMuted: function(muted) {\r
73945 this.fireEvent('mutedchange', this, muted);\r
73946 this.media.dom.muted = muted;\r
73947 },\r
73948 \r
73949 getCurrentTime: function() {\r
73950 return this.media.dom.currentTime;\r
73951 },\r
73952 \r
73953 setCurrentTime: function(time) {\r
73954 this.media.dom.currentTime = time;\r
73955 return time;\r
73956 },\r
73957 \r
73958 getDuration: function() {\r
73959 return this.media.dom.duration;\r
73960 },\r
73961 destroy: function() {\r
73962 var me = this,\r
73963 dom = me.media.dom,\r
73964 mediaEvents = me.mediaEvents;\r
73965 Ext.Object.each(mediaEvents, function(event, fn) {\r
73966 dom.removeEventListener(event, fn);\r
73967 });\r
73968 me.callParent();\r
73969 }\r
73970});\r
73971\r
73972\r
73973Ext.define('Ext.Audio', {\r
73974 extend: Ext.Media,\r
73975 xtype: 'audio',\r
73976 config: {\r
73977 \r
73978 cls: Ext.baseCSSPrefix + 'audio'\r
73979 },\r
73980 \r
73981 \r
73982 onActivate: function() {\r
73983 var me = this;\r
73984 me.callParent();\r
73985 if (Ext.os.is.Phone) {\r
73986 me.element.show();\r
73987 }\r
73988 },\r
73989 \r
73990 onDeactivate: function() {\r
73991 var me = this;\r
73992 me.callParent();\r
73993 if (Ext.os.is.Phone) {\r
73994 me.element.hide();\r
73995 }\r
73996 },\r
73997 template: [\r
73998 {\r
73999 reference: 'media',\r
74000 preload: 'auto',\r
74001 tag: 'audio',\r
74002 cls: Ext.baseCSSPrefix + 'component'\r
74003 }\r
74004 ]\r
74005});\r
74006\r
74007\r
74008Ext.define('Ext.util.Geolocation', {\r
74009 extend: Ext.Evented,\r
74010 alternateClassName: [\r
74011 'Ext.util.GeoLocation'\r
74012 ],\r
74013 config: {\r
74014 \r
74015 \r
74016 \r
74017 autoUpdate: true,\r
74018 \r
74019 frequency: 10000,\r
74020 \r
74021 latitude: null,\r
74022 \r
74023 longitude: null,\r
74024 \r
74025 accuracy: null,\r
74026 \r
74027 altitude: null,\r
74028 \r
74029 altitudeAccuracy: null,\r
74030 \r
74031 heading: null,\r
74032 \r
74033 speed: null,\r
74034 \r
74035 timestamp: null,\r
74036
74037 \r
74038 allowHighAccuracy: false,\r
74039 \r
74040 timeout: Infinity,\r
74041 \r
74042 maximumAge: 0,\r
74043 \r
74044 provider: undefined\r
74045 },\r
74046 updateMaximumAge: function() {\r
74047 if (this.watchOperation) {\r
74048 this.updateWatchOperation();\r
74049 }\r
74050 },\r
74051 updateTimeout: function() {\r
74052 if (this.watchOperation) {\r
74053 this.updateWatchOperation();\r
74054 }\r
74055 },\r
74056 updateAllowHighAccuracy: function() {\r
74057 if (this.watchOperation) {\r
74058 this.updateWatchOperation();\r
74059 }\r
74060 },\r
74061 applyProvider: function(config) {\r
74062 if (Ext.feature.has.Geolocation) {\r
74063 if (!config) {\r
74064 if (navigator && navigator.geolocation) {\r
74065 config = navigator.geolocation;\r
74066 } else if (window.google) {\r
74067 config = google.gears.factory.create('beta.geolocation');\r
74068 }\r
74069 }\r
74070 } else {\r
74071 this.fireEvent('locationerror', this, false, false, true, 'This device does not support Geolocation.');\r
74072 }\r
74073 return config;\r
74074 },\r
74075 updateAutoUpdate: function(newAutoUpdate, oldAutoUpdate) {\r
74076 var me = this,\r
74077 provider = me.getProvider();\r
74078 if (oldAutoUpdate && provider) {\r
74079 clearInterval(me.watchOperationId);\r
74080 me.watchOperationId = null;\r
74081 }\r
74082 if (newAutoUpdate) {\r
74083 if (!provider) {\r
74084 me.fireEvent('locationerror', me, false, false, true, null);\r
74085 return;\r
74086 }\r
74087 try {\r
74088 me.updateWatchOperation();\r
74089 } catch (e) {\r
74090 me.fireEvent('locationerror', me, false, false, true, e.message);\r
74091 }\r
74092 }\r
74093 },\r
74094 \r
74095 updateWatchOperation: function() {\r
74096 var me = this,\r
74097 provider = me.getProvider();\r
74098
74099 if (me.watchOperationId) {\r
74100 clearInterval(me.watchOperationId);\r
74101 }\r
74102 function pollPosition() {\r
74103 provider.getCurrentPosition(Ext.bind(me.fireUpdate, me), Ext.bind(me.fireError, me), me.parseOptions());\r
74104 }\r
74105 pollPosition();\r
74106 me.watchOperationId = Ext.interval(pollPosition, this.getFrequency());\r
74107 },\r
74108 \r
74109 updateLocation: function(callback, scope, positionOptions) {\r
74110 var me = this,\r
74111 provider = me.getProvider();\r
74112 var failFunction = function(message, error) {\r
74113 if (error) {\r
74114 me.fireError(error);\r
74115 } else {\r
74116 me.fireEvent('locationerror', me, false, false, true, message);\r
74117 }\r
74118 if (callback) {\r
74119 callback.call(scope || me, null, me);\r
74120 }\r
74121 };\r
74122
74123 if (!provider) {\r
74124 failFunction(null);\r
74125 return;\r
74126 }\r
74127 try {\r
74128 provider.getCurrentPosition(
74129 function(position) {\r
74130 me.fireUpdate(position);\r
74131 if (callback) {\r
74132 callback.call(scope || me, me, me);\r
74133 }\r
74134 },
74135
74136 function(error) {\r
74137 failFunction(null, error);\r
74138 }, positionOptions || me.parseOptions());\r
74139 } catch (e) {\r
74140 failFunction(e.message);\r
74141 }\r
74142 },\r
74143 \r
74144 fireUpdate: function(position) {\r
74145 var me = this,\r
74146 coords = position.coords;\r
74147 this.position = position;\r
74148 me.setConfig({\r
74149 timestamp: position.timestamp,\r
74150 latitude: coords.latitude,\r
74151 longitude: coords.longitude,\r
74152 accuracy: coords.accuracy,\r
74153 altitude: coords.altitude,\r
74154 altitudeAccuracy: coords.altitudeAccuracy,\r
74155 heading: coords.heading,\r
74156 speed: coords.speed\r
74157 });\r
74158 me.fireEvent('locationupdate', me);\r
74159 },\r
74160 \r
74161 fireError: function(error) {\r
74162 var errorCode = error.code;\r
74163 this.fireEvent('locationerror', this, errorCode == error.TIMEOUT, errorCode == error.PERMISSION_DENIED, errorCode == error.POSITION_UNAVAILABLE, error.message == undefined ? null : error.message);\r
74164 },\r
74165 \r
74166 parseOptions: function() {\r
74167 var timeout = this.getTimeout(),\r
74168 ret = {\r
74169 maximumAge: this.getMaximumAge(),\r
74170 enableHighAccuracy: this.getAllowHighAccuracy()\r
74171 };\r
74172
74173 if (timeout !== Infinity) {\r
74174 ret.timeout = timeout;\r
74175 }\r
74176 return ret;\r
74177 },\r
74178 destroy: function() {\r
74179 this.setAutoUpdate(false);\r
74180 this.callParent();\r
74181 }\r
74182});\r
74183\r
74184\r
74185Ext.define('Ext.Map', {\r
74186 extend: Ext.Container,\r
74187 xtype: 'map',\r
74188 isMap: true,\r
74189 config: {\r
74190 \r
74191 \r
74192 \r
74193 \r
74194 \r
74195 baseCls: Ext.baseCSSPrefix + 'map',\r
74196 \r
74197 useCurrentLocation: false,\r
74198 \r
74199 map: null,\r
74200 \r
74201 geo: null,\r
74202 \r
74203 mapOptions: {},\r
74204 \r
74205 mapListeners: null\r
74206 },\r
74207 constructor: function() {\r
74208 this.callParent(arguments);\r
74209
74210 if (!(window.google || {}).maps) {\r
74211 this.setHtml('Google Maps API is required');\r
74212 }\r
74213 },\r
74214 initialize: function() {\r
74215 this.callParent();\r
74216 this.initMap();\r
74217 this.on({\r
74218 painted: 'doResize',\r
74219 scope: this\r
74220 });\r
74221 this.innerElement.on('touchstart', 'onTouchStart', this);\r
74222 },\r
74223 initMap: function() {\r
74224 var map = this.getMap();\r
74225 if (!map) {\r
74226 var gm = (window.google || {}).maps;\r
74227 if (!gm) {\r
74228 return null;\r
74229 }\r
74230 \r
74231 var element = this.mapContainer,\r
74232 mapOptions = this.getMapOptions(),\r
74233 event = gm.event,\r
74234 me = this;\r
74235
74236 if (element.dom.firstChild) {\r
74237 Ext.fly(element.dom.firstChild).destroy();\r
74238 }\r
74239 if (Ext.os.is.iPad) {\r
74240 Ext.merge({\r
74241 navigationControlOptions: {\r
74242 style: gm.NavigationControlStyle.ZOOM_PAN\r
74243 }\r
74244 }, mapOptions);\r
74245 }\r
74246 mapOptions.mapTypeId = mapOptions.mapTypeId || gm.MapTypeId.ROADMAP;\r
74247 mapOptions.center = mapOptions.center || new gm.LatLng(37.381592, -122.135672);\r
74248
74249 if (mapOptions.center && mapOptions.center.latitude && !Ext.isFunction(mapOptions.center.lat)) {\r
74250 mapOptions.center = new gm.LatLng(mapOptions.center.latitude, mapOptions.center.longitude);\r
74251 }\r
74252 mapOptions.zoom = mapOptions.zoom || 12;\r
74253 map = new gm.Map(element.dom, mapOptions);\r
74254 this.setMap(map);\r
74255 event.addListener(map, 'zoom_changed', Ext.bind(me.onZoomChange, me));\r
74256 event.addListener(map, 'maptypeid_changed', Ext.bind(me.onTypeChange, me));\r
74257 event.addListener(map, 'center_changed', Ext.bind(me.onCenterChange, me));\r
74258 event.addListenerOnce(map, 'tilesloaded', Ext.bind(me.onTilesLoaded, me));\r
74259 this.addMapListeners();\r
74260 }\r
74261 return this.getMap();\r
74262 },\r
74263
74264 renderMap: function() {\r
74265 this.initMap();\r
74266 },\r
74267 getElementConfig: function() {\r
74268 return {\r
74269 reference: 'element',\r
74270 className: 'x-container',\r
74271 children: [\r
74272 {\r
74273 reference: 'innerElement',\r
74274 className: 'x-inner',\r
74275 children: [\r
74276 {\r
74277 reference: 'mapContainer',\r
74278 className: Ext.baseCSSPrefix + 'map-container'\r
74279 }\r
74280 ]\r
74281 }\r
74282 ]\r
74283 };\r
74284 },\r
74285 onTouchStart: function(e) {\r
74286 e.makeUnpreventable();\r
74287 },\r
74288 applyMapOptions: function(options) {\r
74289 return Ext.merge({}, this.options, options);\r
74290 },\r
74291 updateMapOptions: function(newOptions) {\r
74292 var gm = (window.google || {}).maps,\r
74293 map = this.getMap();\r
74294 if (gm && map) {\r
74295 map.setOptions(newOptions);\r
74296 }\r
74297 },\r
74298 doMapCenter: function() {\r
74299 this.setMapCenter(this.getMapOptions().center);\r
74300 },\r
74301 getMapOptions: function() {\r
74302 return Ext.merge({}, this.options || this.getInitialConfig('mapOptions'));\r
74303 },\r
74304 updateUseCurrentLocation: function(useCurrentLocation) {\r
74305 this.setGeo(useCurrentLocation);\r
74306 if (!useCurrentLocation) {\r
74307 this.setMapCenter();\r
74308 }\r
74309 },\r
74310 applyGeo: function(config) {\r
74311 return Ext.factory(config, Ext.util.Geolocation, this.getGeo());\r
74312 },\r
74313 updateGeo: function(newGeo, oldGeo) {\r
74314 var events = {\r
74315 locationupdate: 'onGeoUpdate',\r
74316 locationerror: 'onGeoError',\r
74317 scope: this\r
74318 };\r
74319 if (oldGeo) {\r
74320 oldGeo.un(events);\r
74321 }\r
74322 if (newGeo) {\r
74323 newGeo.on(events);\r
74324 newGeo.updateLocation();\r
74325 }\r
74326 },\r
74327 doResize: function() {\r
74328 var gm = (window.google || {}).maps,\r
74329 map = this.getMap();\r
74330 if (gm && map) {\r
74331 gm.event.trigger(map, "resize");\r
74332 }\r
74333 },\r
74334 \r
74335 onTilesLoaded: function() {\r
74336 this.fireEvent('maprender', this, this.getMap());\r
74337 },\r
74338 \r
74339 addMapListeners: function() {\r
74340 var gm = (window.google || {}).maps,\r
74341 map = this.getMap(),\r
74342 mapListeners = this.getMapListeners();\r
74343 if (gm) {\r
74344 var event = gm.event,\r
74345 me = this,\r
74346 listener, scope, fn, callbackFn, handle;\r
74347 if (Ext.isSimpleObject(mapListeners)) {\r
74348 for (var eventType in mapListeners) {\r
74349 listener = mapListeners[eventType];\r
74350 if (Ext.isSimpleObject(listener)) {\r
74351 scope = listener.scope;\r
74352 fn = listener.fn;\r
74353 } else if (Ext.isFunction(listener)) {\r
74354 scope = null;\r
74355 fn = listener;\r
74356 }\r
74357 if (fn) {\r
74358 callbackFn = function() {\r
74359 this.fn.apply(this.scope, [\r
74360 me\r
74361 ]);\r
74362 if (this.handle) {\r
74363 event.removeListener(this.handle);\r
74364 delete this.handle;\r
74365 delete this.fn;\r
74366 delete this.scope;\r
74367 }\r
74368 };\r
74369 handle = event.addListener(map, eventType, Ext.bind(callbackFn, callbackFn));\r
74370 callbackFn.fn = fn;\r
74371 callbackFn.scope = scope;\r
74372 if (listener.single === true) {\r
74373 callbackFn.handle = handle;\r
74374 }\r
74375 \r
74376 }\r
74377 }\r
74378 }\r
74379 }\r
74380 },\r
74381 \r
74382 onGeoUpdate: function(geo) {\r
74383 if (geo) {\r
74384 this.setMapCenter(new google.maps.LatLng(geo.getLatitude(), geo.getLongitude()));\r
74385 }\r
74386 },\r
74387 \r
74388 onGeoError: Ext.emptyFn,\r
74389 \r
74390 setMapCenter: function(coordinates) {\r
74391 var me = this,\r
74392 map = me.getMap(),\r
74393 mapOptions = me.getMapOptions(),\r
74394 gm = (window.google || {}).maps;\r
74395 if (gm) {\r
74396 if (!coordinates) {\r
74397 if (map && map.getCenter) {\r
74398 coordinates = map.getCenter();\r
74399 } else if (mapOptions.hasOwnProperty('center')) {\r
74400 coordinates = mapOptions.center;\r
74401 } else {\r
74402 coordinates = new gm.LatLng(37.381592, -122.135672);\r
74403 }\r
74404 }\r
74405
74406 if (coordinates && !(coordinates instanceof gm.LatLng) && 'longitude' in coordinates) {\r
74407 coordinates = new gm.LatLng(coordinates.latitude, coordinates.longitude);\r
74408 }\r
74409 if (!map) {\r
74410 mapOptions.center = mapOptions.center || coordinates;\r
74411 me.renderMap();\r
74412 map = me.getMap();\r
74413 }\r
74414 if (map && coordinates instanceof gm.LatLng) {\r
74415 map.panTo(coordinates);\r
74416 } else {\r
74417 this.options = Ext.apply(this.getMapOptions(), {\r
74418 center: coordinates\r
74419 });\r
74420 }\r
74421 }\r
74422 },\r
74423 \r
74424 onZoomChange: function() {\r
74425 var mapOptions = this.getMapOptions(),\r
74426 map = this.getMap(),\r
74427 zoom;\r
74428 zoom = (map && map.getZoom) ? map.getZoom() : mapOptions.zoom || 10;\r
74429 this.options = Ext.apply(mapOptions, {\r
74430 zoom: zoom\r
74431 });\r
74432 this.fireEvent('zoomchange', this, map, zoom);\r
74433 },\r
74434 \r
74435 onTypeChange: function() {\r
74436 var mapOptions = this.getMapOptions(),\r
74437 map = this.getMap(),\r
74438 mapTypeId;\r
74439 mapTypeId = (map && map.getMapTypeId) ? map.getMapTypeId() : mapOptions.mapTypeId;\r
74440 this.options = Ext.apply(mapOptions, {\r
74441 mapTypeId: mapTypeId\r
74442 });\r
74443 this.fireEvent('typechange', this, map, mapTypeId);\r
74444 },\r
74445 \r
74446 onCenterChange: function() {\r
74447 var mapOptions = this.getMapOptions(),\r
74448 map = this.getMap(),\r
74449 center;\r
74450 center = (map && map.getCenter) ? map.getCenter() : mapOptions.center;\r
74451 this.options = Ext.apply(mapOptions, {\r
74452 center: center\r
74453 });\r
74454 this.fireEvent('centerchange', this, map, center);\r
74455 },\r
74456 \r
74457 destroy: function() {\r
74458 Ext.destroy(this.getGeo());\r
74459 var map = this.getMap();\r
74460 if (map && (window.google || {}).maps) {\r
74461 google.maps.event.clearInstanceListeners(map);\r
74462 }\r
74463 this.callParent();\r
74464 }\r
74465});\r
74466\r
74467\r
74468Ext.define('Ext.BingMap', {\r
74469 extend: Ext.Map,\r
74470 xtype: 'bingmap',\r
74471 \r
74472 initMap: function() {\r
74473 var map = this.getMap();\r
74474 if (!map) {\r
74475 var me = this,\r
74476 element = me.mapContainer,\r
74477 mapOptions = me.getMapOptions(),\r
74478 event;\r
74479 var MM = Microsoft.Maps;\r
74480 var key = "AokX-S2lieXTaXG8pvEw3i2AKYuStBMK8RsUu6BDJ6hrL5AYv0IfQqM9zc-BAA-v";\r
74481
74482 mapOptions = Ext.merge({\r
74483 credentials: key,\r
74484 mapTypeId: "r",\r
74485 zoom: 12\r
74486 }, mapOptions);\r
74487
74488
74489 if (!mapOptions.center) {\r
74490 mapOptions.center = new MM.Location(37.381592, -122.135672);\r
74491 }\r
74492
74493 if (element.dom.firstChild) {\r
74494 Ext.fly(element.dom.firstChild).destroy();\r
74495 }\r
74496 MM.loadModule('Microsoft.Maps.Overlays.Style', {\r
74497 callback: function() {\r
74498 me.setMap(new MM.Map(element.dom, mapOptions));\r
74499 if (mapOptions.callback) {\r
74500 mapOptions.callback();\r
74501 }\r
74502 }\r
74503 });\r
74504 map = me.getMap();\r
74505 }\r
74506
74507
74508
74509
74510
74511
74512 me.fireEvent('maprender', me, map);\r
74513 },\r
74514 setMapCenter: function(coordinates) {\r
74515 var me = this,\r
74516 map = me.getMap(),\r
74517 MM = Microsoft.Maps;\r
74518 if (!me.isPainted()) {\r
74519 me.un('painted', 'setMapCenter', this);\r
74520 me.on('painted', 'setMapCenter', this, {\r
74521 delay: 150,\r
74522 single: true,\r
74523 args: [\r
74524 coordinates\r
74525 ]\r
74526 });\r
74527 return;\r
74528 }\r
74529 coordinates = coordinates || new MM.Location(37.381592, -122.135672);\r
74530 if (coordinates && !(coordinates instanceof MM.Location) && 'longitude' in coordinates) {\r
74531 coordinates = new MM.Location(coordinates.latitude, coordinates.longitude);\r
74532 }\r
74533 if (!map) {\r
74534 me.initMap();\r
74535 map = me.getMap();\r
74536 }\r
74537 if (map && coordinates instanceof MM.Location) {\r
74538 map.updateMapPosition(coordinates);\r
74539 } else {\r
74540 this.options = Ext.apply(this.getMapOptions(), {\r
74541 center: coordinates\r
74542 });\r
74543 }\r
74544 }\r
74545}, function() {});\r
74546\r
74547\r
74548Ext.define('Ext.Decorator', {\r
74549 extend: Ext.Component,\r
74550 isDecorator: true,\r
74551 config: {\r
74552 \r
74553 component: {}\r
74554 },\r
74555 statics: {\r
74556 generateProxySetter: function(name) {\r
74557 return function(value) {\r
74558 var component = this.getComponent();\r
74559 component[name].call(component, value);\r
74560 return this;\r
74561 };\r
74562 },\r
74563 generateProxyGetter: function(name) {\r
74564 return function() {\r
74565 var component = this.getComponent();\r
74566 return component[name].call(component);\r
74567 };\r
74568 }\r
74569 },\r
74570 onClassExtended: function(Class, members) {\r
74571 if (!members.hasOwnProperty('proxyConfig')) {\r
74572 return;\r
74573 }\r
74574 var ExtClass = Ext.Class,\r
74575 proxyConfig = members.proxyConfig,\r
74576 config = members.config;\r
74577 members.config = (config) ? Ext.applyIf(config, proxyConfig) : proxyConfig;\r
74578 var name, nameMap, setName, getName;\r
74579 for (name in proxyConfig) {\r
74580 if (proxyConfig.hasOwnProperty(name)) {\r
74581 nameMap = Ext.Config.get(name).names;\r
74582 setName = nameMap.set;\r
74583 getName = nameMap.get;\r
74584 members[setName] = this.generateProxySetter(setName);\r
74585 members[getName] = this.generateProxyGetter(getName);\r
74586 }\r
74587 }\r
74588 },\r
74589 \r
74590 applyComponent: function(config) {\r
74591 return Ext.factory(config, Ext.Component);\r
74592 },\r
74593 \r
74594 updateComponent: function(newComponent, oldComponent) {\r
74595 var me = this;\r
74596 if (oldComponent) {\r
74597 if (me.isRendered() && oldComponent.setRendered(false)) {\r
74598 oldComponent.fireEventedAction('renderedchange', [\r
74599 me,\r
74600 oldComponent,\r
74601 false\r
74602 ], me.doUnsetComponent, me, false);\r
74603 } else {\r
74604 me.doUnsetComponent(oldComponent);\r
74605 }\r
74606 }\r
74607 if (newComponent) {\r
74608 if (me.isRendered() && newComponent.setRendered(true)) {\r
74609 newComponent.fireEventedAction('renderedchange', [\r
74610 me,\r
74611 newComponent,\r
74612 true\r
74613 ], me.doSetComponent, me, false);\r
74614 } else {\r
74615 me.doSetComponent(newComponent);\r
74616 }\r
74617 }\r
74618 },\r
74619 \r
74620 doUnsetComponent: function(component) {\r
74621 var dom = component.renderElement.dom;\r
74622 if (dom) {\r
74623 component.setLayoutSizeFlags(0);\r
74624 this.innerElement.dom.removeChild(dom);\r
74625 }\r
74626 },\r
74627 \r
74628 doSetComponent: function(component) {\r
74629 var dom = component.renderElement.dom;\r
74630 if (dom) {\r
74631 component.setLayoutSizeFlags(this.getSizeFlags());\r
74632 this.innerElement.dom.appendChild(dom);\r
74633 }\r
74634 },\r
74635 \r
74636 setRendered: function(rendered) {\r
74637 var component;\r
74638 if (this.callParent(arguments)) {\r
74639 component = this.getComponent();\r
74640 if (component) {\r
74641 component.setRendered(rendered);\r
74642 }\r
74643 return true;\r
74644 }\r
74645 return false;\r
74646 },\r
74647 \r
74648 setDisabled: function(disabled) {\r
74649
74650 this.callParent(arguments);\r
74651
74652
74653
74654
74655 this.getComponent().setDisabled(disabled);\r
74656 },\r
74657 destroy: function() {\r
74658 Ext.destroy(this.getComponent());\r
74659 this.callParent();\r
74660 }\r
74661});\r
74662\r
74663\r
74664Ext.define('Ext.Img', {\r
74665 extend: Ext.Component,\r
74666 xtype: [\r
74667 'image',\r
74668 'img'\r
74669 ],\r
74670 alternateClassName: 'Ext.Image',\r
74671 \r
74672 \r
74673 \r
74674 config: {\r
74675 \r
74676 src: null,\r
74677 \r
74678 baseCls: Ext.baseCSSPrefix + 'img',\r
74679 \r
74680 imageCls: Ext.baseCSSPrefix + 'img-image',\r
74681 \r
74682 backgroundCls: Ext.baseCSSPrefix + 'img-background',\r
74683 \r
74684 mode: 'background'\r
74685 },\r
74686 beforeInitialize: function() {\r
74687 var me = this;\r
74688 me.onLoad = Ext.Function.bind(me.onLoad, me);\r
74689 me.onError = Ext.Function.bind(me.onError, me);\r
74690 },\r
74691 initialize: function() {\r
74692 var me = this;\r
74693 me.callParent();\r
74694 me.relayEvents(me.renderElement, '*');\r
74695 me.element.on({\r
74696 tap: 'onTap',\r
74697 scope: me\r
74698 });\r
74699 },\r
74700 hide: function() {\r
74701 this.callParent(arguments);\r
74702 this.hiddenSrc = this.hiddenSrc || this.getSrc();\r
74703 this.setSrc(null);\r
74704 },\r
74705 show: function() {\r
74706 this.callParent(arguments);\r
74707 if (this.hiddenSrc) {\r
74708 this.setSrc(this.hiddenSrc);\r
74709 delete this.hiddenSrc;\r
74710 }\r
74711 },\r
74712 updateMode: function(mode) {\r
74713 var me = this,\r
74714 imageCls = me.getImageCls(),\r
74715 backgroundCls = me.getBackgroundCls();\r
74716 if (mode === 'background') {\r
74717 if (me.imageElement) {\r
74718 me.imageElement.destroy();\r
74719 delete me.imageElement;\r
74720 me.updateSrc(me.getSrc());\r
74721 }\r
74722 me.replaceCls(imageCls, backgroundCls);\r
74723 } else {\r
74724 me.imageElement = me.element.createChild({\r
74725 tag: 'img'\r
74726 });\r
74727 me.replaceCls(backgroundCls, imageCls);\r
74728 }\r
74729 },\r
74730 updateImageCls: function(newCls, oldCls) {\r
74731 this.replaceCls(oldCls, newCls);\r
74732 },\r
74733 updateBackgroundCls: function(newCls, oldCls) {\r
74734 this.replaceCls(oldCls, newCls);\r
74735 },\r
74736 onTap: function(e) {\r
74737 this.fireEvent('tap', this, e);\r
74738 },\r
74739 onAfterRender: function() {\r
74740 this.updateSrc(this.getSrc());\r
74741 },\r
74742 applySrc: function(src) {\r
74743 return src && Ext.resolveResource(src);\r
74744 },\r
74745 \r
74746 updateSrc: function(newSrc) {\r
74747 var me = this,\r
74748 dom;\r
74749 if (me.getMode() === 'background') {\r
74750 dom = this.imageObject || new Image();\r
74751 } else {\r
74752 dom = me.imageElement.dom;\r
74753 }\r
74754 this.imageObject = dom;\r
74755 dom.setAttribute('src', Ext.isString(newSrc) ? newSrc : '');\r
74756 dom.addEventListener('load', me.onLoad, false);\r
74757 dom.addEventListener('error', me.onError, false);\r
74758 },\r
74759 detachListeners: function() {\r
74760 var dom = this.imageObject;\r
74761 if (dom) {\r
74762 dom.removeEventListener('load', this.onLoad, false);\r
74763 dom.removeEventListener('error', this.onError, false);\r
74764 }\r
74765 },\r
74766 onLoad: function(e) {\r
74767 this.detachListeners();\r
74768 if (this.getMode() === 'background') {\r
74769 this.element.dom.style.backgroundImage = 'url("' + this.imageObject.src + '")';\r
74770 }\r
74771 this.fireEvent('load', this, e);\r
74772 },\r
74773 onError: function(e) {\r
74774 this.detachListeners();\r
74775
74776 if (this.getMode() === 'background') {\r
74777 this.element.dom.style.backgroundImage = 'url("' + this.imageObject.src + '")';\r
74778 }\r
74779 this.fireEvent('error', this, e);\r
74780 },\r
74781 updateWidth: function(width) {\r
74782 var sizingElement = (this.getMode() === 'background') ? this.element : this.imageElement;\r
74783 sizingElement.setWidth(width);\r
74784 this.callParent(arguments);\r
74785 },\r
74786 updateHeight: function(height) {\r
74787 var sizingElement = (this.getMode() === 'background') ? this.element : this.imageElement;\r
74788 sizingElement.setHeight(height);\r
74789 this.callParent(arguments);\r
74790 },\r
74791 destroy: function() {\r
74792 var me = this;\r
74793 me.detachListeners();\r
74794 me.imageObject = me.imageElement = Ext.destroy(me.imageObject, me.imageElement);\r
74795 me.callParent();\r
74796 }\r
74797});\r
74798\r
74799\r
74800Ext.define('Ext.Label', {\r
74801 extend: Ext.Component,\r
74802 xtype: 'label',\r
74803 config: {\r
74804 baseCls: Ext.baseCSSPrefix + 'label'\r
74805 }\r
74806});\r
74807\r
74808\r
74809\r
74810Ext.define('Ext.Menu', {\r
74811 extend: Ext.Sheet,\r
74812 xtype: 'menu',\r
74813 config: {\r
74814 \r
74815 baseCls: Ext.baseCSSPrefix + 'menu',\r
74816 \r
74817 left: 0,\r
74818 \r
74819 right: 0,\r
74820 \r
74821 bottom: 0,\r
74822 \r
74823 height: 'auto',\r
74824 \r
74825 width: 'auto',\r
74826 \r
74827 defaultType: 'button',\r
74828 \r
74829 showAnimation: null,\r
74830 \r
74831 hideAnimation: null,\r
74832 \r
74833 centered: false,\r
74834 \r
74835 modal: true,\r
74836 \r
74837 hidden: true,\r
74838 \r
74839 hideOnMaskTap: true,\r
74840 \r
74841 translatable: {\r
74842 translationMethod: null\r
74843 }\r
74844 },\r
74845 constructor: function() {\r
74846 this.config.translatable.translationMethod = 'csstransform';\r
74847 this.callParent(arguments);\r
74848 },\r
74849 updateUi: function(newUi, oldUi) {\r
74850 this.callParent(arguments);\r
74851 if (newUi != oldUi && Ext.theme.is.Blackberry) {\r
74852 if (newUi == 'context') {\r
74853 this.innerElement.swapCls('x-vertical', 'x-horizontal');\r
74854 } else if (newUi == 'application') {\r
74855 this.innerElement.swapCls('x-horizontal', 'x-vertical');\r
74856 }\r
74857 }\r
74858 },\r
74859 updateHideOnMaskTap: function(hide) {\r
74860 var mask = this.getModal();\r
74861 if (mask) {\r
74862 mask[hide ? 'on' : 'un'].call(mask, 'tap', function() {\r
74863 Ext.Viewport.hideMenu(this.$side);\r
74864 }, this);\r
74865 }\r
74866 },\r
74867 \r
74868 updateHidden: function() {\r
74869 if (this.initialized) {\r
74870 this.callParent(arguments);\r
74871 }\r
74872 }\r
74873});\r
74874\r
74875\r
74876Ext.define('Ext.Title', {\r
74877 extend: Ext.Component,\r
74878 xtype: 'title',\r
74879 config: {\r
74880 \r
74881 baseCls: 'x-title',\r
74882 \r
74883 title: ''\r
74884 },\r
74885 \r
74886 updateTitle: function(newTitle) {\r
74887 this.setHtml(newTitle);\r
74888 }\r
74889});\r
74890\r
74891\r
74892Ext.define('Ext.Spacer', {\r
74893 extend: Ext.Component,\r
74894 alias: 'widget.spacer',\r
74895 config: {},\r
74896 \r
74897 \r
74898 \r
74899 constructor: function(config) {\r
74900 config = config || {};\r
74901 if (!config.width) {\r
74902 config.flex = 1;\r
74903 }\r
74904 this.callParent([\r
74905 config\r
74906 ]);\r
74907 }\r
74908});\r
74909\r
74910\r
74911Ext.define('Ext.Toolbar', {\r
74912 extend: Ext.Container,\r
74913 xtype: 'toolbar',\r
74914 \r
74915 isToolbar: true,\r
74916 config: {\r
74917 \r
74918 baseCls: Ext.baseCSSPrefix + 'toolbar',\r
74919 \r
74920 title: null,\r
74921 \r
74922 defaultType: 'button',\r
74923 \r
74924 defaultButtonUI: null,\r
74925 \r
74926 \r
74927 minHeight: null,\r
74928 \r
74929 layout: {\r
74930 type: 'hbox',\r
74931 align: 'center'\r
74932 }\r
74933 },\r
74934 hasCSSMinHeight: true,\r
74935 constructor: function(config) {\r
74936 config = config || {};\r
74937 if (config.docked == "left" || config.docked == "right") {\r
74938 config.layout = {\r
74939 type: 'vbox',\r
74940 align: 'stretch'\r
74941 };\r
74942 }\r
74943 this.callParent([\r
74944 config\r
74945 ]);\r
74946 },\r
74947 \r
74948 applyTitle: function(title) {\r
74949 if (typeof title == 'string') {\r
74950 title = {\r
74951 title: title,\r
74952 centered: Ext.theme.is.Tizen ? false : true\r
74953 };\r
74954 }\r
74955 return Ext.factory(title, Ext.Title, this.getTitle());\r
74956 },\r
74957 \r
74958 updateTitle: function(newTitle, oldTitle) {\r
74959 if (newTitle) {\r
74960 this.add(newTitle);\r
74961 }\r
74962 if (oldTitle) {\r
74963 oldTitle.destroy();\r
74964 }\r
74965 },\r
74966 \r
74967 showTitle: function() {\r
74968 var title = this.getTitle();\r
74969 if (title) {\r
74970 title.show();\r
74971 }\r
74972 },\r
74973 \r
74974 hideTitle: function() {\r
74975 var title = this.getTitle();\r
74976 if (title) {\r
74977 title.hide();\r
74978 }\r
74979 },\r
74980 \r
74981 \r
74982 onItemAdd: function(item, index) {\r
74983 var defaultButtonUI = this.getDefaultButtonUI();\r
74984 if (defaultButtonUI) {\r
74985 if (item.isSegmentedButton) {\r
74986 if (item.getDefaultUI() == null) {\r
74987 item.setDefaultUI(defaultButtonUI);\r
74988 }\r
74989 } else if (item.isButton && (item.getUi() == null)) {\r
74990 item.setUi(defaultButtonUI);\r
74991 }\r
74992 }\r
74993 this.callParent([\r
74994 item,\r
74995 index\r
74996 ]);\r
74997 },\r
74998 factoryItem: function(config) {\r
74999 if (config === '->') {\r
75000 config = {\r
75001 xtype: 'component',\r
75002 flex: 1\r
75003 };\r
75004 }\r
75005 return this.callParent([\r
75006 config\r
75007 ]);\r
75008 }\r
75009});\r
75010\r
75011\r
75012Ext.define('Ext.field.Input', {\r
75013 extend: Ext.Component,\r
75014 xtype: 'input',\r
75015 \r
75016 \r
75017 \r
75018 \r
75019 \r
75020 \r
75021 \r
75022 \r
75023 \r
75024 tag: 'input',\r
75025 cachedConfig: {\r
75026 \r
75027 cls: Ext.baseCSSPrefix + 'form-field',\r
75028 \r
75029 focusCls: Ext.baseCSSPrefix + 'field-focus',\r
75030 \r
75031 maskCls: Ext.baseCSSPrefix + 'field-mask',\r
75032 \r
75033 useMask: 'auto',\r
75034 \r
75035 type: 'text',\r
75036 \r
75037 checked: false\r
75038 },\r
75039 config: {\r
75040 \r
75041 baseCls: Ext.baseCSSPrefix + 'field-input',\r
75042 \r
75043 name: null,\r
75044 \r
75045 value: null,\r
75046 \r
75047 isFocused: false,\r
75048 \r
75049 tabIndex: null,\r
75050 \r
75051 placeHolder: null,\r
75052 \r
75053 minValue: null,\r
75054 \r
75055 maxValue: null,\r
75056 \r
75057 stepValue: null,\r
75058 \r
75059 maxLength: null,\r
75060 \r
75061 autoComplete: null,\r
75062 \r
75063 autoCapitalize: null,\r
75064 \r
75065 autoCorrect: null,\r
75066 \r
75067 readOnly: null,\r
75068 \r
75069 maxRows: null,\r
75070 \r
75071 pattern: null,\r
75072 \r
75073 \r
75074 startValue: false,\r
75075 \r
75076 fastFocus: false\r
75077 },\r
75078 \r
75079 \r
75080 getTemplate: function() {\r
75081 var items = [\r
75082 {\r
75083 reference: 'input',\r
75084 tag: this.tag\r
75085 },\r
75086 {\r
75087 reference: 'mask',\r
75088 classList: [\r
75089 this.config.maskCls\r
75090 ]\r
75091 },\r
75092 {\r
75093 reference: 'clearIcon',\r
75094 cls: 'x-clear-icon'\r
75095 }\r
75096 ];\r
75097 return items;\r
75098 },\r
75099 initElement: function() {\r
75100 var me = this;\r
75101 me.callParent();\r
75102 me.input.on({\r
75103 scope: me,\r
75104 keyup: 'onKeyUp',\r
75105 keydown: 'onKeyDown',\r
75106 focus: 'onFocus',\r
75107 blur: 'onBlur',\r
75108 input: 'onInput',\r
75109 paste: 'onPaste',\r
75110 tap: 'onInputTap'\r
75111 });\r
75112
75113
75114
75115 if (Ext.browser.is.AndroidStock) {\r
75116 me.input.dom.addEventListener("mousedown", function(e) {\r
75117 if (document.activeElement != e.target) {\r
75118 e.preventDefault();\r
75119 }\r
75120 });\r
75121 me.input.dom.addEventListener("touchend", function() {\r
75122 me.focus();\r
75123 });\r
75124 }\r
75125 me.mask.on({\r
75126 scope: me,\r
75127 tap: 'onMaskTap'\r
75128 });\r
75129 if (me.clearIcon) {\r
75130 me.clearIcon.on({\r
75131 tap: 'onClearIconTap',\r
75132 touchstart: 'onClearIconPress',\r
75133 touchend: 'onClearIconRelease',\r
75134 scope: me\r
75135 });\r
75136 }\r
75137
75138 if (Ext.browser.is.ie && Ext.browser.version.major >= 10) {\r
75139 me.input.on({\r
75140 scope: me,\r
75141 keypress: 'onKeyPress'\r
75142 });\r
75143 }\r
75144 },\r
75145 updateFastFocus: function(newValue) {\r
75146
75147 if (newValue) {\r
75148 if (this.getFastFocus() && Ext.os.is.iOS) {\r
75149 this.input.on({\r
75150 scope: this,\r
75151 touchstart: "onTouchStart"\r
75152 });\r
75153 }\r
75154 } else {\r
75155 this.input.un({\r
75156 scope: this,\r
75157 touchstart: "onTouchStart"\r
75158 });\r
75159 }\r
75160 },\r
75161 \r
75162 useManualMaxLength: function() {\r
75163 return Boolean((Ext.os.is.Android && !Ext.browser.is.Chrome));\r
75164 },\r
75165 applyUseMask: function(useMask) {\r
75166 if (useMask === 'auto') {\r
75167 useMask = Ext.os.is.iOS && Ext.os.version.lt('5');\r
75168 }\r
75169 return Boolean(useMask);\r
75170 },\r
75171 \r
75172 updateUseMask: function(newUseMask) {\r
75173 this.mask[newUseMask ? 'show' : 'hide']();\r
75174 },\r
75175 updatePattern: function(pattern) {\r
75176 this.updateFieldAttribute('pattern', pattern);\r
75177 },\r
75178 \r
75179 updateFieldAttribute: function(attribute, newValue) {\r
75180 var input = this.input;\r
75181 if (!Ext.isEmpty(newValue, true)) {\r
75182 input.dom.setAttribute(attribute, newValue);\r
75183 } else {\r
75184 input.dom.removeAttribute(attribute);\r
75185 }\r
75186 },\r
75187 \r
75188 updateCls: function(newCls, oldCls) {\r
75189 this.input.addCls(Ext.baseCSSPrefix + 'input-el');\r
75190 this.input.replaceCls(oldCls, newCls);\r
75191 },\r
75192 \r
75193 updateType: function(newType, oldType) {\r
75194 var prefix = Ext.baseCSSPrefix + 'input-';\r
75195 this.input.replaceCls(prefix + oldType, prefix + newType);\r
75196 this.updateFieldAttribute('type', newType);\r
75197 },\r
75198 \r
75199 updateName: function(newName) {\r
75200 this.updateFieldAttribute('name', newName);\r
75201 },\r
75202 \r
75203 getValue: function() {\r
75204 var input = this.input;\r
75205 if (input) {\r
75206 this._value = input.dom.value;\r
75207 }\r
75208 return this._value;\r
75209 },\r
75210 \r
75211 applyValue: function(value) {\r
75212 return (Ext.isEmpty(value)) ? '' : value;\r
75213 },\r
75214 \r
75215 updateValue: function(newValue) {\r
75216 var input = this.input;\r
75217
75218
75219
75220 if (input && input.dom.value !== newValue) {\r
75221 input.dom.value = newValue;\r
75222 }\r
75223 },\r
75224 setValue: function(newValue) {\r
75225 var oldValue = this._value;\r
75226 this.updateValue(this.applyValue(newValue));\r
75227 newValue = this.getValue();\r
75228 if (String(newValue) != String(oldValue) && this.initialized) {\r
75229 this.onChange(this, newValue, oldValue);\r
75230 }\r
75231 return this;\r
75232 },\r
75233
75234 \r
75235 applyTabIndex: function(tabIndex) {\r
75236 if (tabIndex !== null && typeof tabIndex != 'number') {\r
75237 throw new Error("Ext.field.Field: [applyTabIndex] trying to pass a value which is not a number");\r
75238 }\r
75239 return tabIndex;\r
75240 },\r
75241
75242 \r
75243 updateTabIndex: function(newTabIndex) {\r
75244 this.updateFieldAttribute('tabIndex', newTabIndex);\r
75245 },\r
75246 \r
75247 testAutoFn: function(value) {\r
75248 return [\r
75249 true,\r
75250 'on'\r
75251 ].indexOf(value) !== -1;\r
75252 },\r
75253
75254 applyMaxLength: function(maxLength) {\r
75255 if (maxLength !== null && typeof maxLength != 'number') {\r
75256 throw new Error("Ext.field.Text: [applyMaxLength] trying to pass a value which is not a number");\r
75257 }\r
75258 return maxLength;\r
75259 },\r
75260
75261 \r
75262 updateMaxLength: function(newMaxLength) {\r
75263 if (!this.useManualMaxLength()) {\r
75264 this.updateFieldAttribute('maxlength', newMaxLength);\r
75265 }\r
75266 },\r
75267 \r
75268 updatePlaceHolder: function(newPlaceHolder) {\r
75269 this.updateFieldAttribute('placeholder', newPlaceHolder);\r
75270 },\r
75271 \r
75272 applyAutoComplete: function(autoComplete) {\r
75273 return this.testAutoFn(autoComplete);\r
75274 },\r
75275 \r
75276 updateAutoComplete: function(newAutoComplete) {\r
75277 var value = newAutoComplete ? 'on' : 'off';\r
75278 this.updateFieldAttribute('autocomplete', value);\r
75279 },\r
75280 \r
75281 applyAutoCapitalize: function(autoCapitalize) {\r
75282 return this.testAutoFn(autoCapitalize);\r
75283 },\r
75284 \r
75285 updateAutoCapitalize: function(newAutoCapitalize) {\r
75286 var value = newAutoCapitalize ? 'on' : 'off';\r
75287 this.updateFieldAttribute('autocapitalize', value);\r
75288 },\r
75289 \r
75290 applyAutoCorrect: function(autoCorrect) {\r
75291 return this.testAutoFn(autoCorrect);\r
75292 },\r
75293 \r
75294 updateAutoCorrect: function(newAutoCorrect) {\r
75295 var value = newAutoCorrect ? 'on' : 'off';\r
75296 this.updateFieldAttribute('autocorrect', value);\r
75297 },\r
75298 \r
75299 updateMinValue: function(newMinValue) {\r
75300 this.updateFieldAttribute('min', newMinValue);\r
75301 },\r
75302 \r
75303 updateMaxValue: function(newMaxValue) {\r
75304 this.updateFieldAttribute('max', newMaxValue);\r
75305 },\r
75306 \r
75307 updateStepValue: function(newStepValue) {\r
75308 this.updateFieldAttribute('step', newStepValue);\r
75309 },\r
75310 \r
75311 checkedRe: /^(true|1|on)/i,\r
75312 \r
75313 getChecked: function() {\r
75314 var el = this.input,\r
75315 checked;\r
75316 if (el) {\r
75317 checked = el.dom.checked;\r
75318 this._checked = checked;\r
75319 }\r
75320 return checked;\r
75321 },\r
75322 \r
75323 applyChecked: function(checked) {\r
75324 return !!this.checkedRe.test(String(checked));\r
75325 },\r
75326 setChecked: function(newChecked) {\r
75327 this.updateChecked(this.applyChecked(newChecked));\r
75328 this._checked = newChecked;\r
75329 },\r
75330 \r
75331 updateChecked: function(newChecked) {\r
75332 this.input.dom.checked = newChecked;\r
75333 },\r
75334 \r
75335 updateReadOnly: function(readOnly) {\r
75336 this.updateFieldAttribute('readonly', readOnly ? true : null);\r
75337 },\r
75338
75339 \r
75340 applyMaxRows: function(maxRows) {\r
75341 if (maxRows !== null && typeof maxRows !== 'number') {\r
75342 throw new Error("Ext.field.Input: [applyMaxRows] trying to pass a value which is not a number");\r
75343 }\r
75344 return maxRows;\r
75345 },\r
75346
75347 updateMaxRows: function(newRows) {\r
75348 this.updateFieldAttribute('rows', newRows);\r
75349 },\r
75350 updateDisabled: function(disabled) {\r
75351 this.callParent(arguments);\r
75352 if (Ext.browser.is.Safari && !Ext.os.is.BlackBerry) {\r
75353 this.input.dom.tabIndex = (disabled) ? -1 : 0;\r
75354 }\r
75355 this.input.dom.disabled = (Ext.browser.is.Safari && !Ext.os.is.BlackBerry) ? false : disabled;\r
75356 if (!disabled) {\r
75357 this.blur();\r
75358 }\r
75359 },\r
75360 \r
75361 isDirty: function() {\r
75362 if (this.getDisabled()) {\r
75363 return false;\r
75364 }\r
75365 return String(this.getValue()) !== String(this.originalValue);\r
75366 },\r
75367 \r
75368 reset: function() {\r
75369 this.setValue(this.originalValue);\r
75370 },\r
75371 \r
75372 onInputTap: function(e) {\r
75373 this.fireAction('inputtap', [\r
75374 this,\r
75375 e\r
75376 ], 'doInputTap');\r
75377 },\r
75378 \r
75379 doInputTap: function(me, e) {\r
75380 if (me.getDisabled()) {\r
75381 return false;\r
75382 }\r
75383
75384 if (this.getFastFocus() && Ext.os.is.iOS) {\r
75385 me.focus();\r
75386 }\r
75387 },\r
75388 \r
75389 onMaskTap: function(e) {\r
75390 this.fireAction('masktap', [\r
75391 this,\r
75392 e\r
75393 ], 'doMaskTap');\r
75394 },\r
75395 \r
75396 doMaskTap: function(me, e) {\r
75397 if (me.getDisabled()) {\r
75398 return false;\r
75399 }\r
75400 me.focus();\r
75401 },\r
75402 \r
75403 showMask: function() {\r
75404 if (this.getUseMask()) {\r
75405 this.mask.setStyle('display', 'block');\r
75406 }\r
75407 },\r
75408 \r
75409 hideMask: function() {\r
75410 if (this.getUseMask()) {\r
75411 this.mask.setStyle('display', 'none');\r
75412 }\r
75413 },\r
75414 \r
75415 focus: function() {\r
75416 var me = this,\r
75417 el = me.input;\r
75418 if (el && el.dom.focus) {\r
75419 el.dom.focus();\r
75420 }\r
75421 return me;\r
75422 },\r
75423 \r
75424 blur: function() {\r
75425 var me = this,\r
75426 el = this.input;\r
75427 if (el && el.dom.blur) {\r
75428 el.dom.blur();\r
75429 }\r
75430 return me;\r
75431 },\r
75432 \r
75433 select: function() {\r
75434 var me = this,\r
75435 el = me.input;\r
75436 if (el && el.dom.setSelectionRange) {\r
75437 el.dom.setSelectionRange(0, 9999);\r
75438 }\r
75439 return me;\r
75440 },\r
75441 onFocus: function(e) {\r
75442 this.fireAction('focus', [\r
75443 e\r
75444 ], 'doFocus');\r
75445 },\r
75446 \r
75447 doFocus: function(e) {\r
75448 var me = this;\r
75449 me.hideMask();\r
75450 if (!me.getIsFocused()) {\r
75451 me.setStartValue(me.getValue());\r
75452 }\r
75453 me.setIsFocused(true);\r
75454 },\r
75455 onTouchStart: function(e) {\r
75456
75457 if (document.activeElement != e.target) {\r
75458 e.preventDefault();\r
75459 }\r
75460 },\r
75461 onBlur: function(e) {\r
75462 this.fireAction('blur', [\r
75463 e\r
75464 ], 'doBlur');\r
75465 },\r
75466 \r
75467 doBlur: function(e) {\r
75468 var me = this,\r
75469 value = me.getValue(),\r
75470 startValue = me.getStartValue();\r
75471 me.showMask();\r
75472 me.setIsFocused(false);\r
75473 if (String(value) != String(startValue)) {\r
75474 me.onChange(me, value, startValue);\r
75475 }\r
75476 },\r
75477 \r
75478 onClearIconTap: function(e) {\r
75479 this.fireEvent('clearicontap', this, e);\r
75480
75481
75482 if (Ext.os.is.Android) {\r
75483 this.focus();\r
75484 }\r
75485 },\r
75486 onClearIconPress: function() {\r
75487 this.clearIcon.addCls(Ext.baseCSSPrefix + 'pressing');\r
75488 },\r
75489 onClearIconRelease: function() {\r
75490 this.clearIcon.removeCls(Ext.baseCSSPrefix + 'pressing');\r
75491 },\r
75492 onClick: function(e) {\r
75493 this.fireEvent('click', e);\r
75494 },\r
75495 onChange: function(me, value, startValue) {\r
75496 if (this.useManualMaxLength()) {\r
75497 this.trimValueToMaxLength();\r
75498 }\r
75499 this.fireEvent('change', me, value, startValue);\r
75500 },\r
75501 onPaste: function(e) {\r
75502 if (this.useManualMaxLength()) {\r
75503 this.trimValueToMaxLength();\r
75504 }\r
75505 this.fireEvent('paste', e);\r
75506 },\r
75507 onKeyUp: function(e) {\r
75508 if (this.useManualMaxLength()) {\r
75509 this.trimValueToMaxLength();\r
75510 }\r
75511 this.fireEvent('keyup', e);\r
75512 },\r
75513 onKeyDown: function() {\r
75514
75515
75516 this.ignoreInput = true;\r
75517 },\r
75518 onInput: function(e) {\r
75519 var me = this;\r
75520 me.fireEvent('input', me, me.input.dom.value);\r
75521
75522 if (me.ignoreInput) {\r
75523 me.ignoreInput = false;\r
75524 return;\r
75525 }\r
75526
75527
75528 Ext.defer(function() {\r
75529 if (!me.ignoreInput) {\r
75530 me.fireEvent('keyup', e);\r
75531 me.ignoreInput = false;\r
75532 }\r
75533 }, 10);\r
75534 },\r
75535
75536 onKeyPress: function(e) {\r
75537 if (e.browserEvent.keyCode == 13) {\r
75538 this.fireEvent('keyup', e);\r
75539 }\r
75540 },\r
75541 onMouseDown: function(e) {\r
75542 this.fireEvent('mousedown', e);\r
75543 },\r
75544 trimValueToMaxLength: function() {\r
75545 var maxLength = this.getMaxLength();\r
75546 if (maxLength) {\r
75547 var value = this.getValue();\r
75548 if (value.length > this.getMaxLength()) {\r
75549 this.setValue(value.slice(0, maxLength));\r
75550 }\r
75551 }\r
75552 }\r
75553});\r
75554\r
75555\r
75556Ext.define('Ext.field.Field', {\r
75557 extend: Ext.Decorator,\r
75558 alternateClassName: 'Ext.form.Field',\r
75559 xtype: 'field',\r
75560 \r
75561 isField: true,\r
75562 \r
75563 isFormField: true,\r
75564 config: {\r
75565 \r
75566 baseCls: Ext.baseCSSPrefix + 'field',\r
75567 \r
75568 label: null,\r
75569 \r
75570 labelAlign: 'left',\r
75571 \r
75572 labelWidth: '30%',\r
75573 \r
75574 labelWrap: false,\r
75575 \r
75576 clearIcon: null,\r
75577 \r
75578 required: false,\r
75579 \r
75580 \r
75581 inputType: null,\r
75582 \r
75583 name: null,\r
75584 \r
75585 value: null,\r
75586 \r
75587 tabIndex: null\r
75588 },\r
75589 \r
75590 \r
75591 cachedConfig: {\r
75592 \r
75593 labelCls: null,\r
75594 \r
75595 requiredCls: Ext.baseCSSPrefix + 'field-required',\r
75596 \r
75597 inputCls: null\r
75598 },\r
75599 noWrapCls: Ext.baseCSSPrefix + 'form-label-nowrap',\r
75600 \r
75601 getElementConfig: function() {\r
75602 var prefix = Ext.baseCSSPrefix;\r
75603 return {\r
75604 reference: 'element',\r
75605 className: Ext.baseCSSPrefix + 'container',\r
75606 children: [\r
75607 {\r
75608 reference: 'label',\r
75609 cls: prefix + 'form-label',\r
75610 children: [\r
75611 {\r
75612 reference: 'labelspan',\r
75613 tag: 'span'\r
75614 }\r
75615 ]\r
75616 },\r
75617 {\r
75618 reference: 'innerElement',\r
75619 cls: prefix + 'component-outer'\r
75620 }\r
75621 ]\r
75622 };\r
75623 },\r
75624 \r
75625 updateLabel: function(newLabel, oldLabel) {\r
75626 var renderElement = this.renderElement,\r
75627 prefix = Ext.baseCSSPrefix;\r
75628 if (newLabel) {\r
75629 this.labelspan.setHtml(newLabel);\r
75630 renderElement.addCls(prefix + 'field-labeled');\r
75631 } else {\r
75632 renderElement.removeCls(prefix + 'field-labeled');\r
75633 }\r
75634 },\r
75635 \r
75636 updateLabelAlign: function(newLabelAlign, oldLabelAlign) {\r
75637 var renderElement = this.renderElement,\r
75638 prefix = Ext.baseCSSPrefix;\r
75639 if (newLabelAlign) {\r
75640 renderElement.addCls(prefix + 'label-align-' + newLabelAlign);\r
75641 if (newLabelAlign == "top" || newLabelAlign == "bottom") {\r
75642 this.label.setWidth('100%');\r
75643 } else {\r
75644 this.updateLabelWidth(this.getLabelWidth());\r
75645 }\r
75646 }\r
75647 if (oldLabelAlign) {\r
75648 renderElement.removeCls(prefix + 'label-align-' + oldLabelAlign);\r
75649 }\r
75650 },\r
75651 \r
75652 updateLabelCls: function(newLabelCls, oldLabelCls) {\r
75653 if (newLabelCls) {\r
75654 this.label.addCls(newLabelCls);\r
75655 }\r
75656 if (oldLabelCls) {\r
75657 this.label.removeCls(oldLabelCls);\r
75658 }\r
75659 },\r
75660 \r
75661 updateLabelWidth: function(newLabelWidth) {\r
75662 var labelAlign = this.getLabelAlign();\r
75663 if (newLabelWidth) {\r
75664 if (labelAlign == "top" || labelAlign == "bottom") {\r
75665 this.label.setWidth('100%');\r
75666 } else {\r
75667 this.label.setWidth(newLabelWidth);\r
75668 }\r
75669 }\r
75670 },\r
75671 \r
75672 updateLabelWrap: function(newLabelWrap, oldLabelWrap) {\r
75673 this.toggleCls(this.noWrapCls, !newLabelWrap);\r
75674 },\r
75675 \r
75676 updateRequired: function(newRequired) {\r
75677 this.renderElement.toggleCls(this.getRequiredCls(), newRequired);\r
75678 },\r
75679 \r
75680 updateRequiredCls: function(newRequiredCls, oldRequiredCls) {\r
75681 if (this.getRequired()) {\r
75682 this.renderElement.replaceCls(oldRequiredCls, newRequiredCls);\r
75683 }\r
75684 },\r
75685 \r
75686 initialize: function() {\r
75687 var me = this;\r
75688 me.callParent();\r
75689 me.doInitValue();\r
75690 },\r
75691 \r
75692 doInitValue: function() {\r
75693 \r
75694 this.originalValue = this.getInitialConfig().value;\r
75695 },\r
75696 \r
75697 reset: function() {\r
75698 this.setValue(this.originalValue);\r
75699 return this;\r
75700 },\r
75701 \r
75702 resetOriginalValue: function() {\r
75703 this.originalValue = this.getValue();\r
75704 },\r
75705 \r
75706 isDirty: function() {\r
75707 return false;\r
75708 }\r
75709});\r
75710\r
75711\r
75712Ext.define('Ext.field.Text', {\r
75713 extend: Ext.field.Field,\r
75714 xtype: 'textfield',\r
75715 alternateClassName: 'Ext.form.Text',\r
75716 \r
75717 \r
75718 \r
75719 \r
75720 \r
75721 \r
75722 \r
75723 \r
75724 config: {\r
75725 \r
75726 ui: 'text',\r
75727 \r
75728 clearIcon: true,\r
75729 \r
75730 placeHolder: null,\r
75731 \r
75732 maxLength: null,\r
75733 \r
75734 autoComplete: null,\r
75735 \r
75736 autoCapitalize: null,\r
75737 \r
75738 autoCorrect: null,\r
75739 \r
75740 readOnly: null,\r
75741 \r
75742 component: {\r
75743 xtype: 'input',\r
75744 type: 'text',\r
75745 fastFocus: false\r
75746 },\r
75747 bubbleEvents: [\r
75748 'action'\r
75749 ]\r
75750 },\r
75751 defaultBindProperty: 'value',\r
75752 twoWayBindable: {\r
75753 value: 1\r
75754 },\r
75755 publishes: {\r
75756 value: 1\r
75757 },\r
75758 focusedCls: Ext.baseCSSPrefix + 'field-focused',\r
75759 clearableCls: Ext.baseCSSPrefix + 'field-clearable',\r
75760 emptyCls: Ext.baseCSSPrefix + 'empty',\r
75761 \r
75762 initialize: function() {\r
75763 var me = this;\r
75764 me.callParent();\r
75765 me.getComponent().on({\r
75766 scope: this,\r
75767 keyup: 'onKeyUp',\r
75768 input: 'onInput',\r
75769 focus: 'onFocus',\r
75770 blur: 'onBlur',\r
75771 paste: 'onPaste',\r
75772 mousedown: 'onMouseDown',\r
75773 clearicontap: 'onClearIconTap'\r
75774 });\r
75775
75776 me.originalValue = me.getValue() || "";\r
75777 me.getComponent().originalValue = me.originalValue;\r
75778 me.syncEmptyCls();\r
75779 },\r
75780 syncEmptyCls: function() {\r
75781 var val = this._value,\r
75782 empty = val ? val.length : false;\r
75783 this.toggleCls(this.emptyCls, !empty);\r
75784 },\r
75785 applyValue: function(value) {\r
75786 return Ext.isEmpty(value) ? '' : value;\r
75787 },\r
75788 \r
75789 updateValue: function(value, oldValue) {\r
75790 var me = this,\r
75791 component = me.getComponent(),\r
75792
75793 valueValid = value !== undefined && value !== null && value !== '';\r
75794 if (component) {\r
75795 component.setValue(value);\r
75796 }\r
75797 me.toggleClearIcon(valueValid && me.isDirty());\r
75798 me.syncEmptyCls();\r
75799 if (me.initialized) {\r
75800 me.fireEvent('change', me, value, oldValue);\r
75801 }\r
75802 },\r
75803 \r
75804 updatePlaceHolder: function(newPlaceHolder) {\r
75805 this.getComponent().setPlaceHolder(newPlaceHolder);\r
75806 },\r
75807 \r
75808 updateMaxLength: function(newMaxLength) {\r
75809 this.getComponent().setMaxLength(newMaxLength);\r
75810 },\r
75811 \r
75812 updateAutoComplete: function(newAutoComplete) {\r
75813 this.getComponent().setAutoComplete(newAutoComplete);\r
75814 },\r
75815 \r
75816 updateAutoCapitalize: function(newAutoCapitalize) {\r
75817 this.getComponent().setAutoCapitalize(newAutoCapitalize);\r
75818 },\r
75819 \r
75820 updateAutoCorrect: function(newAutoCorrect) {\r
75821 this.getComponent().setAutoCorrect(newAutoCorrect);\r
75822 },\r
75823 \r
75824 updateReadOnly: function(newReadOnly) {\r
75825 this.toggleClearIcon(!newReadOnly);\r
75826 this.getComponent().setReadOnly(newReadOnly);\r
75827 },\r
75828 \r
75829 updateInputType: function(newInputType) {\r
75830 var component = this.getComponent();\r
75831 if (component) {\r
75832 component.setType(newInputType);\r
75833 }\r
75834 },\r
75835 \r
75836 updateName: function(newName) {\r
75837 var component = this.getComponent();\r
75838 if (component) {\r
75839 component.setName(newName);\r
75840 }\r
75841 },\r
75842 \r
75843 updateTabIndex: function(newTabIndex) {\r
75844 var component = this.getComponent();\r
75845 if (component) {\r
75846 component.setTabIndex(newTabIndex);\r
75847 }\r
75848 },\r
75849 \r
75850 updateInputCls: function(newInputCls, oldInputCls) {\r
75851 var component = this.getComponent();\r
75852 if (component) {\r
75853 component.replaceCls(oldInputCls, newInputCls);\r
75854 }\r
75855 },\r
75856 updateDisabled: function(disabled, oldDisabled) {\r
75857 this.callParent([\r
75858 disabled,\r
75859 oldDisabled\r
75860 ]);\r
75861 var component = this.getComponent();\r
75862 if (component) {\r
75863 component.setDisabled(disabled);\r
75864 }\r
75865 this.toggleClearIcon(!disabled);\r
75866 },\r
75867 \r
75868 showClearIcon: function() {\r
75869 var me = this,\r
75870 value = me.getValue(),\r
75871
75872 valueValid = value !== undefined && value !== null && value !== "";\r
75873 if (me.getClearIcon() && !me.getDisabled() && !me.getReadOnly() && valueValid) {\r
75874 me.element.addCls(me.clearableCls);\r
75875 }\r
75876 return me;\r
75877 },\r
75878 \r
75879 hideClearIcon: function() {\r
75880 if (this.getClearIcon()) {\r
75881 this.element.removeCls(this.clearableCls);\r
75882 }\r
75883 },\r
75884 onKeyUp: function(e) {\r
75885 this.fireAction('keyup', [\r
75886 this,\r
75887 e\r
75888 ], 'doKeyUp');\r
75889 },\r
75890 \r
75891 doKeyUp: function(me, e) {\r
75892
75893 var value = me.getValue(),\r
75894
75895 valueValid = value !== undefined && value !== null && value !== '';\r
75896 me.toggleClearIcon(valueValid);\r
75897 if (e.browserEvent.keyCode === 13) {\r
75898 me.fireAction('action', [\r
75899 me,\r
75900 e\r
75901 ], 'doAction');\r
75902 }\r
75903 },\r
75904 doAction: function() {\r
75905 this.blur();\r
75906 },\r
75907 onClearIconTap: function(input, e) {\r
75908 this.fireAction('clearicontap', [\r
75909 this,\r
75910 input,\r
75911 e\r
75912 ], 'doClearIconTap');\r
75913 },\r
75914 \r
75915 doClearIconTap: function(me, e) {\r
75916 me.setValue('');\r
75917 },\r
75918 onInput: function(component, value) {\r
75919 this.setValue(value);\r
75920 },\r
75921 onFocus: function(e) {\r
75922 var me = this;\r
75923 me.addCls(me.focusedCls);\r
75924 me.isFocused = true;\r
75925 me.fireEvent('focus', me, e);\r
75926 },\r
75927 onBlur: function(e) {\r
75928 var me = this;\r
75929 me.removeCls(me.focusedCls);\r
75930 me.isFocused = false;\r
75931 me.fireEvent('blur', me, e);\r
75932 Ext.defer(function() {\r
75933 me.isFocused = false;\r
75934 }, 50);\r
75935 },\r
75936 onPaste: function(e) {\r
75937 this.fireEvent('paste', this, e);\r
75938 },\r
75939 onMouseDown: function(e) {\r
75940 this.fireEvent('mousedown', this, e);\r
75941 },\r
75942 \r
75943 focus: function() {\r
75944 this.getComponent().focus();\r
75945 return this;\r
75946 },\r
75947 \r
75948 blur: function() {\r
75949 this.getComponent().blur();\r
75950 return this;\r
75951 },\r
75952 \r
75953 select: function() {\r
75954 this.getComponent().select();\r
75955 return this;\r
75956 },\r
75957 resetOriginalValue: function() {\r
75958 var me = this,\r
75959 comp;\r
75960 me.callParent();\r
75961 component = me.getComponent();\r
75962 if (component && component.hasOwnProperty("originalValue")) {\r
75963 me.getComponent().originalValue = me.originalValue;\r
75964 }\r
75965 me.reset();\r
75966 },\r
75967 reset: function() {\r
75968 var me = this;\r
75969 me.getComponent().reset();\r
75970
75971 me.getValue();\r
75972 me.toggleClearIcon(me.isDirty());\r
75973 },\r
75974 isDirty: function() {\r
75975 var component = this.getComponent();\r
75976 if (component) {\r
75977 return component.isDirty();\r
75978 }\r
75979 return false;\r
75980 },\r
75981 privates: {\r
75982 toggleClearIcon: function(state) {\r
75983 if (state) {\r
75984 this.showClearIcon();\r
75985 } else {\r
75986 this.hideClearIcon();\r
75987 }\r
75988 }\r
75989 }\r
75990});\r
75991\r
75992\r
75993Ext.define('Ext.field.TextAreaInput', {\r
75994 extend: Ext.field.Input,\r
75995 xtype: 'textareainput',\r
75996 tag: 'textarea'\r
75997});\r
75998\r
75999\r
76000Ext.define('Ext.field.TextArea', {\r
76001 extend: Ext.field.Text,\r
76002 xtype: 'textareafield',\r
76003 alternateClassName: 'Ext.form.TextArea',\r
76004 config: {\r
76005 \r
76006 ui: 'textarea',\r
76007 \r
76008 autoCapitalize: false,\r
76009 \r
76010 component: {\r
76011 xtype: 'textareainput'\r
76012 },\r
76013 \r
76014 maxRows: null\r
76015 },\r
76016 \r
76017 updateMaxRows: function(newRows) {\r
76018 this.getComponent().setMaxRows(newRows);\r
76019 },\r
76020 updateHeight: function(height, oldHeight) {\r
76021 this.callParent([\r
76022 height,\r
76023 oldHeight\r
76024 ]);\r
76025 this.getComponent().input.setHeight(height);\r
76026 },\r
76027 updateWidth: function(width, oldWidth) {\r
76028 this.callParent([\r
76029 width,\r
76030 oldWidth\r
76031 ]);\r
76032 this.getComponent().input.setWidth(width);\r
76033 },\r
76034 \r
76035 doKeyUp: function(me) {\r
76036
76037 this.toggleClearIcon(this.getValue());\r
76038 }\r
76039});\r
76040\r
76041\r
76042Ext.define('Ext.MessageBox', {\r
76043 extend: Ext.Sheet,\r
76044 xtype: 'messagebox',\r
76045 config: {\r
76046 \r
76047 baseCls: Ext.baseCSSPrefix + 'msgbox',\r
76048 \r
76049 iconCls: null,\r
76050 \r
76051 showAnimation: {\r
76052 type: 'popIn',\r
76053 duration: 250,\r
76054 easing: 'ease-out'\r
76055 },\r
76056 \r
76057 hideAnimation: {\r
76058 type: 'popOut',\r
76059 duration: 250,\r
76060 easing: 'ease-out'\r
76061 },\r
76062 \r
76063 zIndex: 999,\r
76064 \r
76065 defaultTextHeight: 75,\r
76066 \r
76067 title: null,\r
76068 \r
76069 buttons: null,\r
76070 \r
76071 message: null,\r
76072 \r
76073 \r
76074 prompt: null,\r
76075 \r
76076 modal: true,\r
76077 \r
76078 layout: {\r
76079 type: 'vbox',\r
76080 pack: 'center'\r
76081 }\r
76082 },\r
76083 statics: {\r
76084 OK: {\r
76085 text: 'OK',\r
76086 itemId: 'ok',\r
76087 ui: 'action'\r
76088 },\r
76089 YES: {\r
76090 text: 'Yes',\r
76091 itemId: 'yes',\r
76092 ui: 'action'\r
76093 },\r
76094 NO: {\r
76095 text: 'No',\r
76096 itemId: 'no'\r
76097 },\r
76098 CANCEL: {\r
76099 text: 'Cancel',\r
76100 itemId: 'cancel'\r
76101 },\r
76102 INFO: Ext.baseCSSPrefix + 'msgbox-info',\r
76103 WARNING: Ext.baseCSSPrefix + 'msgbox-warning',\r
76104 QUESTION: Ext.baseCSSPrefix + 'msgbox-question',\r
76105 ERROR: Ext.baseCSSPrefix + 'msgbox-error',\r
76106 OKCANCEL: [\r
76107 {\r
76108 text: 'Cancel',\r
76109 itemId: 'cancel'\r
76110 },\r
76111 {\r
76112 text: 'OK',\r
76113 itemId: 'ok',\r
76114 ui: 'action'\r
76115 }\r
76116 ],\r
76117 YESNOCANCEL: [\r
76118 {\r
76119 text: 'Cancel',\r
76120 itemId: 'cancel'\r
76121 },\r
76122 {\r
76123 text: 'No',\r
76124 itemId: 'no'\r
76125 },\r
76126 {\r
76127 text: 'Yes',\r
76128 itemId: 'yes',\r
76129 ui: 'action'\r
76130 }\r
76131 ],\r
76132 YESNO: [\r
76133 {\r
76134 text: 'No',\r
76135 itemId: 'no'\r
76136 },\r
76137 {\r
76138 text: 'Yes',\r
76139 itemId: 'yes',\r
76140 ui: 'action'\r
76141 }\r
76142 ]\r
76143 },\r
76144 \r
76145 constructor: function(config) {\r
76146 config = config || {};\r
76147 if (config.hasOwnProperty('multiline') || config.hasOwnProperty('multiLine')) {\r
76148 config.prompt = config.prompt || {};\r
76149 Ext.applyIf(config.prompt, {\r
76150 multiLine: config.multiline || config.multiLine\r
76151 });\r
76152 delete config.multiline;\r
76153 delete config.multiLine;\r
76154 }\r
76155 this.defaultAllowedConfig = {};\r
76156 var allowedConfigs = [\r
76157 'ui',\r
76158 'showAnimation',\r
76159 'hideAnimation',\r
76160 'title',\r
76161 'message',\r
76162 'prompt',\r
76163 'iconCls',\r
76164 'buttons',\r
76165 'defaultTextHeight'\r
76166 ],\r
76167 ln = allowedConfigs.length,\r
76168 i, allowedConfig;\r
76169 for (i = 0; i < ln; i++) {\r
76170 allowedConfig = allowedConfigs[i];\r
76171 this.defaultAllowedConfig[allowedConfig] = this.defaultConfig[allowedConfig];\r
76172 }\r
76173 this.callParent([\r
76174 config\r
76175 ]);\r
76176 },\r
76177 \r
76178 applyTitle: function(config) {\r
76179 if (typeof config == "string") {\r
76180 config = {\r
76181 title: config\r
76182 };\r
76183 }\r
76184 Ext.applyIf(config, {\r
76185 docked: 'top',\r
76186 ui: Ext.filterPlatform('blackberry') ? 'light' : null,\r
76187 cls: this.getBaseCls() + '-title'\r
76188 });\r
76189 if (Ext.theme.is.Tizen) {\r
76190 Ext.applyIf(config, {\r
76191 centered: false\r
76192 });\r
76193 }\r
76194 return Ext.factory(config, Ext.Toolbar, this.getTitle());\r
76195 },\r
76196 \r
76197 updateTitle: function(newTitle) {\r
76198 if (newTitle) {\r
76199 this.add(newTitle);\r
76200 }\r
76201 },\r
76202 \r
76203 updateButtons: function(newButtons) {\r
76204 var me = this;\r
76205
76206
76207 newButtons = (!newButtons || newButtons.length === 0) ? false : newButtons;\r
76208 if (newButtons) {\r
76209 if (me.buttonsToolbar) {\r
76210 me.buttonsToolbar.show();\r
76211 me.buttonsToolbar.removeAll();\r
76212 me.buttonsToolbar.setItems(newButtons);\r
76213 } else {\r
76214 var layout = {\r
76215 type: 'hbox',\r
76216 pack: 'center'\r
76217 };\r
76218 var isFlexed = Ext.theme.is.MountainView || Ext.theme.is.Blackberry;\r
76219 me.buttonsToolbar = Ext.create('Ext.Toolbar', {\r
76220 docked: 'bottom',\r
76221 defaultType: 'button',\r
76222 defaults: {\r
76223 flex: (isFlexed) ? 1 : undefined,\r
76224 ui: (Ext.theme.is.Blackberry) ? 'action' : undefined\r
76225 },\r
76226 layout: layout,\r
76227 ui: me.getUi(),\r
76228 cls: me.getBaseCls() + '-buttons',\r
76229 items: newButtons\r
76230 });\r
76231 me.add(me.buttonsToolbar);\r
76232 }\r
76233 } else if (me.buttonsToolbar) {\r
76234 me.buttonsToolbar.hide();\r
76235 }\r
76236 },\r
76237 \r
76238 applyMessage: function(config) {\r
76239 config = {\r
76240 html: config,\r
76241 cls: this.getBaseCls() + '-text'\r
76242 };\r
76243 return Ext.factory(config, Ext.Component, this._message);\r
76244 },\r
76245 \r
76246 updateMessage: function(newMessage) {\r
76247 if (newMessage) {\r
76248 this.add(newMessage);\r
76249 }\r
76250 },\r
76251 getMessage: function() {\r
76252 if (this._message) {\r
76253 return this._message.getHtml();\r
76254 }\r
76255 return null;\r
76256 },\r
76257 \r
76258 applyIconCls: function(config) {\r
76259 config = {\r
76260 xtype: 'component',\r
76261 docked: 'left',\r
76262 width: 40,\r
76263 height: 40,\r
76264 baseCls: Ext.baseCSSPrefix + 'icon',\r
76265 hidden: (config) ? false : true,\r
76266 cls: config\r
76267 };\r
76268 return Ext.factory(config, Ext.Component, this._iconCls);\r
76269 },\r
76270 \r
76271 updateIconCls: function(newIconCls, oldIconCls) {\r
76272
76273 this.getTitle();\r
76274 this.getButtons();\r
76275 if (newIconCls) {\r
76276 this.add(newIconCls);\r
76277 } else {\r
76278 this.remove(oldIconCls);\r
76279 }\r
76280 },\r
76281 getIconCls: function() {\r
76282 var icon = this._iconCls,\r
76283 iconCls;\r
76284 if (icon) {\r
76285 iconCls = icon.getCls();\r
76286 return (iconCls) ? iconCls[0] : null;\r
76287 }\r
76288 return null;\r
76289 },\r
76290 \r
76291 applyPrompt: function(prompt) {\r
76292 if (prompt) {\r
76293 var config = {\r
76294 label: false\r
76295 };\r
76296 if (Ext.isObject(prompt)) {\r
76297 Ext.apply(config, prompt);\r
76298 }\r
76299 if (config.multiLine) {\r
76300 config.height = Ext.isNumber(config.multiLine) ? parseFloat(config.multiLine) : this.getDefaultTextHeight();\r
76301 return Ext.factory(config, Ext.field.TextArea, this.getPrompt());\r
76302 } else {\r
76303 return Ext.factory(config, Ext.field.Text, this.getPrompt());\r
76304 }\r
76305 }\r
76306 return prompt;\r
76307 },\r
76308 \r
76309 updatePrompt: function(newPrompt, oldPrompt) {\r
76310 if (newPrompt) {\r
76311 this.add(newPrompt);\r
76312 }\r
76313 if (oldPrompt) {\r
76314 this.remove(oldPrompt);\r
76315 }\r
76316 },\r
76317 \r
76318 onClick: function(button) {\r
76319 if (button) {\r
76320 var config = button.config.userConfig || {},\r
76321 initialConfig = button.getInitialConfig(),\r
76322 prompt = this.getPrompt();\r
76323 if (typeof config.fn == 'function') {\r
76324 button.disable();\r
76325 this.on({\r
76326 hiddenchange: function() {\r
76327 config.fn.call(config.scope || null, initialConfig.itemId || initialConfig.text, prompt ? prompt.getValue() : null, config);\r
76328 button.enable();\r
76329 },\r
76330 single: true,\r
76331 scope: this\r
76332 });\r
76333 }\r
76334 if (config.input) {\r
76335 config.input.dom.blur();\r
76336 }\r
76337 }\r
76338 this.hide();\r
76339 },\r
76340 \r
76341 show: function(initialConfig) {\r
76342 Ext.util.InputBlocker.blockInputs();\r
76343
76344 if (!this.getParent() && Ext.Viewport) {\r
76345 Ext.Viewport.add(this);\r
76346 }\r
76347 if (!initialConfig) {\r
76348 return this.callParent();\r
76349 }\r
76350 var config = Ext.apply({}, initialConfig),\r
76351 buttons = initialConfig.buttons || Ext.MessageBox.OK || [],\r
76352 buttonBarItems = [],\r
76353 userConfig = initialConfig;\r
76354 Ext.each(buttons, function(buttonConfig) {\r
76355 if (!buttonConfig) {\r
76356 return;\r
76357 }\r
76358 buttonBarItems.push(Ext.apply({\r
76359 userConfig: userConfig,\r
76360 scope: this,\r
76361 handler: 'onClick'\r
76362 }, buttonConfig));\r
76363 }, this);\r
76364 config.buttons = buttonBarItems;\r
76365 config.prompt = config.prompt || null;\r
76366 if (config.multiLine) {\r
76367 config.prompt = config.prompt || {};\r
76368 config.prompt.multiLine = config.multiLine;\r
76369 delete config.multiLine;\r
76370 }\r
76371 delete config.value;\r
76372 delete config.fn;\r
76373 delete config.scope;\r
76374 config = Ext.merge({}, this.defaultAllowedConfig, config);\r
76375 this.setConfig(config);\r
76376 var prompt = this.getPrompt();\r
76377 if (prompt) {\r
76378 prompt.setValue(initialConfig.value || '');\r
76379 }\r
76380 this.callParent();\r
76381 return this;\r
76382 },\r
76383 \r
76384 alert: function(title, message, fn, scope) {\r
76385 return this.show({\r
76386 title: title || null,\r
76387 message: message || null,\r
76388 buttons: Ext.MessageBox.OK,\r
76389 prompt: false,\r
76390 fn: function() {\r
76391 if (fn) {\r
76392 Ext.callback(fn, scope, arguments);\r
76393 }\r
76394 },\r
76395 scope: scope\r
76396 });\r
76397 },\r
76398 \r
76399 confirm: function(title, message, fn, scope) {\r
76400 return this.show({\r
76401 title: title || null,\r
76402 message: message || null,\r
76403 buttons: Ext.MessageBox.YESNO,\r
76404 prompt: false,\r
76405 scope: scope,\r
76406 fn: function() {\r
76407 if (fn) {\r
76408 Ext.callback(fn, scope, arguments);\r
76409 }\r
76410 }\r
76411 });\r
76412 },\r
76413 \r
76414 prompt: function(title, message, fn, scope, multiLine, value, prompt) {\r
76415 return this.show({\r
76416 title: title || null,\r
76417 message: message || null,\r
76418 buttons: Ext.MessageBox.OKCANCEL,\r
76419 scope: scope,\r
76420 prompt: prompt || true,\r
76421 multiLine: multiLine,\r
76422 value: value,\r
76423 fn: function() {\r
76424 if (fn) {\r
76425 Ext.callback(fn, scope, arguments);\r
76426 }\r
76427 }\r
76428 });\r
76429 }\r
76430}, function(MessageBox) {\r
76431 Ext.onInternalReady(function() {\r
76432 \r
76433 Ext.Msg = new MessageBox();\r
76434 });\r
76435});\r
76436\r
76437\r
76438Ext.define('Ext.mixin.Progressable', {\r
76439 extend: Ext.Mixin,\r
76440 isProgressable: true,\r
76441 mixinConfig: {\r
76442 id: 'progressable'\r
76443 },\r
76444 config: {\r
76445 \r
76446 minProgressInput: 0,\r
76447 \r
76448 maxProgressInput: 1,\r
76449 \r
76450 minProgressOutput: 0,\r
76451 \r
76452 maxProgressOutput: 100,\r
76453 \r
76454 dynamic: true,\r
76455 \r
76456 state: null\r
76457 },\r
76458 \r
76459 _progressActive: false,\r
76460 _progress: 0,\r
76461 _rawProgress: 0,\r
76462 onStartProgress: Ext.emptyFn,\r
76463 onUpdateProgress: Ext.emptyFn,\r
76464 onEndProgress: Ext.emptyFn,\r
76465 startProgress: function() {\r
76466 if (!this._progressActive) {\r
76467 this._progressActive = true;\r
76468 this.onStartProgress();\r
76469 this.updateProgress(this.getMinProgressInput());\r
76470 }\r
76471 },\r
76472 updateProgress: function(value, state) {\r
76473 if (state && state != this.getState()) {\r
76474 this.setState(state);\r
76475 }\r
76476 \r
76477 if (value > this.getMaxProgressInput()) {\r
76478 value = this.getMaxProgressInput();\r
76479 }\r
76480 \r
76481 if (value < this.getMinProgressInput()) {\r
76482 value = this.getMinProgressInput();\r
76483 }\r
76484 \r
76485 var mappedValue = this.mapValues(value, this.getMinProgressInput(), this.getMaxProgressInput(), this.getMinProgressOutput(), this.getMaxProgressOutput());\r
76486 this._progress = mappedValue;\r
76487 this._rawProgress = value;\r
76488 if (this.getDynamic()) {\r
76489 this.onUpdateProgress(mappedValue);\r
76490 }\r
76491 },\r
76492 endProgress: function() {\r
76493 if (this._progressActive) {\r
76494 this._progressActive = false;\r
76495 this.updateProgress(this.getMaxProgressInput());\r
76496 this.onEndProgress();\r
76497 }\r
76498 },\r
76499 mapValues: function(value, inputMin, inputMax, outputMin, outputMax) {\r
76500 return (value - inputMin) / (inputMax - inputMin) * (outputMax - outputMin) + outputMin;\r
76501 },\r
76502 setProgress: function(value) {\r
76503 this.updateProgress(value);\r
76504 },\r
76505 getProgress: function() {\r
76506 return this._progress;\r
76507 },\r
76508 getRawProgress: function() {\r
76509 return this._rawProgress;\r
76510 }\r
76511});\r
76512\r
76513\r
76514Ext.define('Ext.ProgressIndicator', {\r
76515 extend: Ext.Container,\r
76516 mixins: [\r
76517 Ext.mixin.Progressable\r
76518 ],\r
76519 xtype: 'progressindicator',\r
76520 config: {\r
76521 baseCls: Ext.baseCSSPrefix + 'progressindicator',\r
76522 hidden: true,\r
76523 modal: true,\r
76524 centered: true,\r
76525 \r
76526 loadingText: {\r
76527 any: 'Loading: {percent}%',\r
76528 upload: 'Uploading: {percent}%',\r
76529 download: 'Downloading: {percent}%'\r
76530 },\r
76531 \r
76532 fallbackText: {\r
76533 any: 'Loading',\r
76534 upload: 'Uploading',\r
76535 download: 'Downloading'\r
76536 },\r
76537 \r
76538 monitoredStates: {\r
76539 upload: true,\r
76540 download: true\r
76541 },\r
76542 showAnimation: !Ext.browser.is.AndroidStock ? {\r
76543 type: 'slideIn',\r
76544 direction: "left",\r
76545 duration: 250,\r
76546 easing: 'ease-out'\r
76547 } : null,\r
76548 hideAnimation: !Ext.browser.is.AndroidStock ? {\r
76549 type: 'slideOut',\r
76550 direction: "left",\r
76551 duration: 250,\r
76552 easing: 'ease-in'\r
76553 } : null,\r
76554 \r
76555 minProgressOutput: 0,\r
76556 \r
76557 maxProgressOutput: 1,\r
76558 \r
76559 state: null\r
76560 },\r
76561 constructor: function() {\r
76562 this.emptyTpl = new Ext.XTemplate("");\r
76563 this.callParent(arguments);\r
76564 },\r
76565 getElementConfig: function() {\r
76566 return {\r
76567 reference: 'element',\r
76568 classList: [\r
76569 'x-container',\r
76570 'x-unsized'\r
76571 ],\r
76572 children: [\r
76573 {\r
76574 reference: 'innerElement',\r
76575 className: Ext.baseCSSPrefix + 'progressindicator-inner',\r
76576 children: [\r
76577 {\r
76578 reference: 'progressBarText',\r
76579 className: Ext.baseCSSPrefix + 'progressindicator-text'\r
76580 },\r
76581 {\r
76582 reference: 'progressBar',\r
76583 className: Ext.baseCSSPrefix + 'progressindicator-bar',\r
76584 children: [\r
76585 {\r
76586 reference: 'progressBarFill',\r
76587 className: Ext.baseCSSPrefix + 'progressindicator-bar-fill'\r
76588 }\r
76589 ]\r
76590 }\r
76591 ]\r
76592 }\r
76593 ]\r
76594 };\r
76595 },\r
76596 onStartProgress: function() {\r
76597 if (!this.getParent()) {\r
76598 Ext.Viewport.add(this);\r
76599 }\r
76600 this.show();\r
76601 },\r
76602 onEndProgress: function() {\r
76603 this.hide();\r
76604 },\r
76605 onUpdateProgress: function() {\r
76606 this.updateBar();\r
76607 },\r
76608 getLoadingText: function() {\r
76609 var state = this.getState();\r
76610 if (this._loadingText[state]) {\r
76611 return this._loadingText[state];\r
76612 }\r
76613 if (this._loadingText["any"]) {\r
76614 return this._loadingText["any"];\r
76615 }\r
76616 return this.emptyTpl;\r
76617 },\r
76618 applyLoadingText: function(loadingText) {\r
76619 var tpl = {},\r
76620 property, value;\r
76621 if (Ext.isString(loadingText)) {\r
76622 tpl = {\r
76623 any: new Ext.XTemplate(loadingText)\r
76624 };\r
76625 } else if (loadingText instanceof Ext.XTemplate) {\r
76626 tpl = {\r
76627 any: loadingText\r
76628 };\r
76629 } else {\r
76630 for (property in loadingText) {\r
76631 value = loadingText[property];\r
76632 tpl[property] = new Ext.XTemplate(value);\r
76633 }\r
76634 }\r
76635 if (!tpl.any) {\r
76636 tpl.any = this.emptyTpl;\r
76637 }\r
76638 return tpl;\r
76639 },\r
76640 getFallbackText: function() {\r
76641 var state = this.getState();\r
76642 if (this._fallbackText[state]) {\r
76643 return this._fallbackText[state];\r
76644 }\r
76645 if (this._fallbackText["any"]) {\r
76646 return this._fallbackText["any"];\r
76647 }\r
76648 return "";\r
76649 },\r
76650 applyFallbackText: function(fallbackText) {\r
76651 var obj = {},\r
76652 property, value;\r
76653 if (Ext.isString(fallbackText)) {\r
76654 obj = {\r
76655 any: fallbackText\r
76656 };\r
76657 } else {\r
76658 for (property in fallbackText) {\r
76659 value = fallbackText[property];\r
76660 obj[property] = value;\r
76661 }\r
76662 }\r
76663 if (!obj.any) {\r
76664 obj.any = this.emptyTpl;\r
76665 }\r
76666 return obj;\r
76667 },\r
76668 updateDynamic: function(value) {\r
76669 if (!value) {\r
76670 this.progressBarText.setHtml(this.getFallbackText());\r
76671 this.progressBar.setWidth("100%");\r
76672 } else {\r
76673 this.updateBar();\r
76674 }\r
76675 return value;\r
76676 },\r
76677 updateBar: function() {\r
76678 var state = this.getState();\r
76679 if (this.getMonitoredStates()[state] !== true) {\r
76680 this.progressBarText.setHtml(this.getFallbackText());\r
76681 this.progressBar.setWidth("100%");\r
76682 return;\r
76683 }\r
76684 var percent = this.getProgress() * 100;\r
76685 if (!Ext.isNumber(percent)) {\r
76686 percent = 0;\r
76687 }\r
76688 \r
76689 this.progressBar.setWidth(percent + "%");\r
76690 var loadingText = this.getLoadingText();\r
76691 if (loadingText) {\r
76692 this.progressBarText.setHtml(this.getLoadingText().apply({\r
76693 state: state,\r
76694 percent: Math.ceil(percent) || 0\r
76695 }));\r
76696 } else {\r
76697 this.progressBarText.setHtml('');\r
76698 }\r
76699 }\r
76700});\r
76701\r
76702\r
76703Ext.define('Ext.SegmentedButton', {\r
76704 extend: Ext.Container,\r
76705 xtype: 'segmentedbutton',\r
76706 alternateClassName: 'Ext.button.Segmented',\r
76707 isSegmentedButton: true,\r
76708 config: {\r
76709 \r
76710 baseCls: Ext.baseCSSPrefix + 'segmentedbutton',\r
76711 \r
76712 pressedCls: Ext.baseCSSPrefix + 'button-pressed',\r
76713 \r
76714 allowMultiple: false,\r
76715 \r
76716 allowDepress: false,\r
76717 \r
76718 allowToggle: true,\r
76719 \r
76720 pressedButtons: [],\r
76721 \r
76722 layout: {\r
76723 type: 'hbox',\r
76724 align: 'stretch'\r
76725 },\r
76726 \r
76727 defaultType: 'button',\r
76728 \r
76729 defaultUI: null\r
76730 },\r
76731 \r
76732 initialize: function() {\r
76733 var me = this;\r
76734 me.callParent();\r
76735 me.on({\r
76736 delegate: '> button',\r
76737 scope: me,\r
76738 tap: 'onButtonRelease'\r
76739 });\r
76740 me.onAfter({\r
76741 delegate: '> button',\r
76742 scope: me,\r
76743 hide: 'onButtonHiddenChange',\r
76744 show: 'onButtonHiddenChange'\r
76745 });\r
76746 },\r
76747 updateAllowMultiple: function(allowMultiple) {\r
76748 if (!this.initialized && !this.getInitialConfig().hasOwnProperty('allowDepress') && allowMultiple) {\r
76749 this.setAllowDepress(true);\r
76750 }\r
76751 },\r
76752 \r
76753 applyItems: function() {\r
76754 var me = this,\r
76755 pressedButtons = [],\r
76756 ln, i, item, items;\r
76757
76758 me.callParent(arguments);\r
76759 items = this.getItems();\r
76760 ln = items.length;\r
76761 for (i = 0; i < ln; i++) {\r
76762 item = items.items[i];\r
76763 if (item.getInitialConfig('pressed')) {\r
76764 pressedButtons.push(items.items[i]);\r
76765 }\r
76766 }\r
76767 me.updateFirstAndLastCls(items);\r
76768 me.setPressedButtons(pressedButtons);\r
76769 },\r
76770 \r
76771 onButtonRelease: function(button) {\r
76772 if (!this.getAllowToggle()) {\r
76773 return;\r
76774 }\r
76775 var me = this,\r
76776 pressedButtons = me.getPressedButtons() || [],\r
76777 buttons = [],\r
76778 alreadyPressed;\r
76779 if (!me.getDisabled() && !button.getDisabled()) {\r
76780
76781 if (me.getAllowMultiple()) {\r
76782 buttons = pressedButtons.concat(buttons);\r
76783 }\r
76784 alreadyPressed = (buttons.indexOf(button) !== -1) || (pressedButtons.indexOf(button) !== -1);\r
76785
76786 if (alreadyPressed && me.getAllowDepress()) {\r
76787 Ext.Array.remove(buttons, button);\r
76788 } else if (!alreadyPressed || !me.getAllowDepress()) {\r
76789 buttons.push(button);\r
76790 }\r
76791 me.setPressedButtons(buttons);\r
76792 }\r
76793 },\r
76794 onItemAdd: function() {\r
76795 this.callParent(arguments);\r
76796 this.updateFirstAndLastCls(this.getItems());\r
76797 },\r
76798 onItemRemove: function() {\r
76799 this.callParent(arguments);\r
76800 this.updateFirstAndLastCls(this.getItems());\r
76801 },\r
76802 \r
76803 onButtonHiddenChange: function() {\r
76804 this.updateFirstAndLastCls(this.getItems());\r
76805 },\r
76806 \r
76807 updateFirstAndLastCls: function(items) {\r
76808 var ln = items.length,\r
76809 basePrefix = Ext.baseCSSPrefix,\r
76810 firstCls = basePrefix + 'first',\r
76811 lastCls = basePrefix + 'last',\r
76812 item, i;\r
76813
76814 for (i = 0; i < ln; i++) {\r
76815 item = items.items[i];\r
76816 item.removeCls(firstCls);\r
76817 item.removeCls(lastCls);\r
76818 }\r
76819
76820 for (i = 0; i < ln; i++) {\r
76821 item = items.items[i];\r
76822 if (!item.isHidden()) {\r
76823 item.addCls(firstCls);\r
76824 break;\r
76825 }\r
76826 }\r
76827
76828 for (i = ln - 1; i >= 0; i--) {\r
76829 item = items.items[i];\r
76830 if (!item.isHidden()) {\r
76831 item.addCls(lastCls);\r
76832 break;\r
76833 }\r
76834 }\r
76835 },\r
76836 \r
76837 applyPressedButtons: function(newButtons) {\r
76838 var me = this,\r
76839 array = [],\r
76840 button, ln, i;\r
76841 if (me.getAllowToggle()) {\r
76842 if (Ext.isArray(newButtons)) {\r
76843 ln = newButtons.length;\r
76844 for (i = 0; i < ln; i++) {\r
76845 button = me.getComponent(newButtons[i]);\r
76846 if (button && array.indexOf(button) === -1) {\r
76847 array.push(button);\r
76848 }\r
76849 }\r
76850 } else {\r
76851 button = me.getComponent(newButtons);\r
76852 if (button && array.indexOf(button) === -1) {\r
76853 array.push(button);\r
76854 }\r
76855 }\r
76856 }\r
76857 return array;\r
76858 },\r
76859 \r
76860 updatePressedButtons: function(newButtons, oldButtons) {\r
76861 var me = this,\r
76862 items = me.getItems(),\r
76863 pressedCls = me.getPressedCls(),\r
76864 events = [],\r
76865 item, button, ln, i, e;\r
76866
76867 ln = items.length;\r
76868 if (oldButtons && oldButtons.length) {\r
76869 for (i = 0; i < ln; i++) {\r
76870 item = items.items[i];\r
76871 if (oldButtons.indexOf(item) != -1 && newButtons.indexOf(item) == -1) {\r
76872 item.removeCls([\r
76873 pressedCls,\r
76874 item.getPressedCls()\r
76875 ]);\r
76876 events.push({\r
76877 item: item,\r
76878 toggle: false\r
76879 });\r
76880 }\r
76881 }\r
76882 }\r
76883
76884 ln = newButtons.length;\r
76885 for (i = 0; i < ln; i++) {\r
76886 button = newButtons[i];\r
76887 if (!oldButtons || oldButtons.indexOf(button) == -1) {\r
76888 button.addCls(pressedCls);\r
76889 events.push({\r
76890 item: button,\r
76891 toggle: true\r
76892 });\r
76893 }\r
76894 }\r
76895
76896 ln = events.length;\r
76897 if (ln && oldButtons !== undefined) {\r
76898 Ext.defer(function() {\r
76899 for (i = 0; i < ln; i++) {\r
76900 e = events[i];\r
76901 me.fireEvent('toggle', me, e.item, e.toggle);\r
76902 }\r
76903 }, 50);\r
76904 }\r
76905 },\r
76906 setPressed: function(button, pressed) {\r
76907 var pressedButtons = this.getPressedButtons().slice();\r
76908 if (pressed) {\r
76909 Ext.Array.include(pressedButtons, button);\r
76910 } else {\r
76911 Ext.Array.remove(pressedButtons, button);\r
76912 }\r
76913 this.setPressedButtons(pressedButtons);\r
76914 },\r
76915 \r
76916 isPressed: function(button) {\r
76917 var pressedButtons = this.getPressedButtons();\r
76918 return pressedButtons.indexOf(button) !== -1;\r
76919 },\r
76920 \r
76921 updateDisabled: function(disabled) {\r
76922 var me = this;\r
76923 me.items.each(function(item) {\r
76924 item.setDisabled(disabled);\r
76925 }, me);\r
76926 me.callParent(arguments);\r
76927 },\r
76928 setValue: function(value) {\r
76929 this.setPressedButtons([\r
76930 this.items.getAt(value)\r
76931 ]);\r
76932 },\r
76933 getValue: function() {\r
76934 var buttons = this.getPressedButtons(),\r
76935 out = -1;\r
76936 if (buttons.length) {\r
76937 out = this.items.indexOf(buttons[0]);\r
76938 }\r
76939 return out;\r
76940 },\r
76941 updateDefaultUI: function(defaultUI) {\r
76942 var items = this.items && this.items.items,\r
76943 len = items.length,\r
76944 i, item;\r
76945 for (i = 0; i < len; i++) {\r
76946 item = items[i];\r
76947 if (item.getUi() == null) {\r
76948 item.setUi(defaultUI);\r
76949 }\r
76950 }\r
76951 },\r
76952 doAdd: function(item, instanced) {\r
76953 var defaultUI = this.getDefaultUI();\r
76954 if (defaultUI && (item.getUi() == null)) {\r
76955 item.setUi(defaultUI);\r
76956 }\r
76957 this.callParent([\r
76958 item,\r
76959 instanced\r
76960 ]);\r
76961 }\r
76962});\r
76963\r
76964\r
76965Ext.define('Ext.Sortable', {\r
76966 mixins: {\r
76967 observable: Ext.mixin.Observable\r
76968 },\r
76969 config: {\r
76970 \r
76971 baseCls: Ext.baseCSSPrefix + 'sortable',\r
76972 \r
76973 delay: 0\r
76974 },\r
76975 \r
76976 direction: 'vertical',\r
76977 \r
76978 cancelSelector: null,\r
76979
76980
76981
76982
76983 \r
76984 constrain: window,\r
76985 \r
76986 group: 'base',\r
76987 \r
76988 revert: true,\r
76989 \r
76990 itemSelector: null,\r
76991 \r
76992 handleSelector: null,\r
76993 \r
76994 disabled: false,\r
76995
76996 \r
76997 sorting: false,\r
76998 \r
76999 vertical: false,\r
77000 \r
77001 constructor: function(el, config) {\r
77002 config = config || {};\r
77003 Ext.apply(this, config);\r
77004 this.addEvents(\r
77005 'sortstart', \r
77006 'sortend', \r
77007 'sortchange');\r
77008
77009
77010
77011
77012
77013
77014
77015
77016 this.el = Ext.get(el);\r
77017 this.callParent();\r
77018 this.mixins.observable.constructor.call(this);\r
77019 if (this.direction == 'horizontal') {\r
77020 this.horizontal = true;\r
77021 } else if (this.direction == 'vertical') {\r
77022 this.vertical = true;\r
77023 } else {\r
77024 this.horizontal = this.vertical = true;\r
77025 }\r
77026 this.el.addCls(this.baseCls);\r
77027 this.startEventName = (this.getDelay() > 0) ? 'taphold' : 'tapstart';\r
77028 if (!this.disabled) {\r
77029 this.enable();\r
77030 }\r
77031 },\r
77032 \r
77033 onStart: function(e, t) {\r
77034 if (this.cancelSelector && e.getTarget(this.cancelSelector)) {\r
77035 return;\r
77036 }\r
77037 if (this.handleSelector && !e.getTarget(this.handleSelector)) {\r
77038 return;\r
77039 }\r
77040 if (!this.sorting) {\r
77041 this.onSortStart(e, t);\r
77042 }\r
77043 },\r
77044 \r
77045 onSortStart: function(e, t) {\r
77046 this.sorting = true;\r
77047 var draggable = Ext.create('Ext.util.Draggable', t, {\r
77048 threshold: 0,\r
77049 revert: this.revert,\r
77050 direction: this.direction,\r
77051 constrain: this.constrain === true ? this.el : this.constrain,\r
77052 animationDuration: 100\r
77053 });\r
77054 draggable.on({\r
77055 drag: this.onDrag,\r
77056 dragend: this.onDragEnd,\r
77057 scope: this\r
77058 });\r
77059 this.dragEl = t;\r
77060 this.calculateBoxes();\r
77061 if (!draggable.dragging) {\r
77062 draggable.onStart(e);\r
77063 }\r
77064 this.fireEvent('sortstart', this, e);\r
77065 },\r
77066 \r
77067 calculateBoxes: function() {\r
77068 this.items = [];\r
77069 var els = this.el.select(this.itemSelector, false),\r
77070 ln = els.length,\r
77071 i, item, el, box;\r
77072 for (i = 0; i < ln; i++) {\r
77073 el = els[i];\r
77074 if (el != this.dragEl) {\r
77075 item = Ext.fly(el).getRegion();\r
77076 item.el = el;\r
77077 this.items.push(item);\r
77078 }\r
77079 }\r
77080 },\r
77081 \r
77082 onDrag: function(draggable, e) {\r
77083 var items = this.items,\r
77084 ln = items.length,\r
77085 region = draggable.region,\r
77086 sortChange = false,\r
77087 i, intersect, overlap, item;\r
77088 for (i = 0; i < ln; i++) {\r
77089 item = items[i];\r
77090 intersect = region.intersect(item);\r
77091 if (intersect) {\r
77092 if (this.vertical && Math.abs(intersect.top - intersect.bottom) > (region.bottom - region.top) / 2) {\r
77093 if (region.bottom > item.top && item.top > region.top) {\r
77094 draggable.el.insertAfter(item.el);\r
77095 } else {\r
77096 draggable.el.insertBefore(item.el);\r
77097 }\r
77098 sortChange = true;\r
77099 } else if (this.horizontal && Math.abs(intersect.left - intersect.right) > (region.right - region.left) / 2) {\r
77100 if (region.right > item.left && item.left > region.left) {\r
77101 draggable.el.insertAfter(item.el);\r
77102 } else {\r
77103 draggable.el.insertBefore(item.el);\r
77104 }\r
77105 sortChange = true;\r
77106 }\r
77107 if (sortChange) {\r
77108
77109 draggable.reset();\r
77110
77111
77112 draggable.moveTo(region.left, region.top);\r
77113
77114 this.calculateBoxes();\r
77115 this.fireEvent('sortchange', this, draggable.el, this.el.select(this.itemSelector, false).indexOf(draggable.el.dom));\r
77116 return;\r
77117 }\r
77118 }\r
77119 }\r
77120 },\r
77121 \r
77122 onDragEnd: function(draggable, e) {\r
77123 draggable.destroy();\r
77124 this.sorting = false;\r
77125 this.fireEvent('sortend', this, draggable, e);\r
77126 },\r
77127 \r
77128 enable: function() {\r
77129 this.el.on(this.startEventName, this.onStart, this, {\r
77130 delegate: this.itemSelector,\r
77131 holdThreshold: this.getDelay()\r
77132 });\r
77133 this.disabled = false;\r
77134 },\r
77135 \r
77136 disable: function() {\r
77137 this.el.un(this.startEventName, this.onStart, this);\r
77138 this.disabled = true;\r
77139 },\r
77140 \r
77141 isDisabled: function() {\r
77142 return this.disabled;\r
77143 },\r
77144 \r
77145 isSorting: function() {\r
77146 return this.sorting;\r
77147 },\r
77148 \r
77149 isVertical: function() {\r
77150 return this.vertical;\r
77151 },\r
77152 \r
77153 isHorizontal: function() {\r
77154 return this.horizontal;\r
77155 }\r
77156});\r
77157\r
77158\r
77159Ext.define('Ext.TitleBar', {\r
77160 extend: Ext.Container,\r
77161 xtype: 'titlebar',\r
77162 defaultBindProperty: 'title',\r
77163 \r
77164 isToolbar: true,\r
77165 config: {\r
77166 \r
77167 baseCls: Ext.baseCSSPrefix + 'toolbar',\r
77168 \r
77169 cls: Ext.baseCSSPrefix + 'navigation-bar',\r
77170 \r
77171 ui: 'dark',\r
77172 \r
77173 title: null,\r
77174 \r
77175 titleAlign: 'center',\r
77176 \r
77177 defaultType: 'button',\r
77178 \r
77179 minHeight: null,\r
77180 \r
77181 layout: {\r
77182 type: 'hbox'\r
77183 },\r
77184 \r
77185 items: [],\r
77186 \r
77187 maxButtonWidth: '40%'\r
77188 },\r
77189 hasCSSMinHeight: true,\r
77190 beforeInitialize: function() {\r
77191 this.applyItems = this.applyInitialItems;\r
77192 },\r
77193 initialize: function() {\r
77194 delete this.applyItems;\r
77195 this.add(this.initialItems);\r
77196 delete this.initialItems;\r
77197 this.on({\r
77198 painted: 'refreshTitlePosition',\r
77199 single: true\r
77200 });\r
77201 },\r
77202 applyInitialItems: function(items) {\r
77203 var me = this,\r
77204 titleAlign = me.getTitleAlign(),\r
77205 defaults = me.getDefaults() || {};\r
77206 me.initialItems = items;\r
77207 me.leftBox = me.add({\r
77208 xtype: 'container',\r
77209 style: 'position: relative',\r
77210 layout: {\r
77211 type: 'hbox',\r
77212 align: 'center'\r
77213 },\r
77214 listeners: {\r
77215 resize: 'refreshTitlePosition',\r
77216 scope: me\r
77217 }\r
77218 });\r
77219 me.spacer = me.add({\r
77220 xtype: 'component',\r
77221 style: 'position: relative',\r
77222 flex: 1,\r
77223 listeners: {\r
77224 resize: 'refreshTitlePosition',\r
77225 scope: me\r
77226 }\r
77227 });\r
77228 me.rightBox = me.add({\r
77229 xtype: 'container',\r
77230 style: 'position: relative',\r
77231 layout: {\r
77232 type: 'hbox',\r
77233 align: 'center'\r
77234 },\r
77235 listeners: {\r
77236 resize: 'refreshTitlePosition',\r
77237 scope: me\r
77238 }\r
77239 });\r
77240 switch (titleAlign) {\r
77241 case 'left':\r
77242 me.titleComponent = me.leftBox.add({\r
77243 xtype: 'title',\r
77244 cls: Ext.baseCSSPrefix + 'title-align-left',\r
77245 hidden: defaults.hidden\r
77246 });\r
77247 me.refreshTitlePosition = Ext.emptyFn;\r
77248 break;\r
77249 case 'right':\r
77250 me.titleComponent = me.rightBox.add({\r
77251 xtype: 'title',\r
77252 cls: Ext.baseCSSPrefix + 'title-align-right',\r
77253 hidden: defaults.hidden\r
77254 });\r
77255 me.refreshTitlePosition = Ext.emptyFn;\r
77256 break;\r
77257 default:\r
77258 me.titleComponent = me.add({\r
77259 xtype: 'title',\r
77260 hidden: defaults.hidden,\r
77261 centered: true\r
77262 });\r
77263 break;\r
77264 }\r
77265 me.doAdd = me.doBoxAdd;\r
77266 me.remove = me.doBoxRemove;\r
77267 me.doInsert = me.doBoxInsert;\r
77268 },\r
77269 doBoxAdd: function(item) {\r
77270 if (item.config.align == 'right') {\r
77271 this.rightBox.add(item);\r
77272 } else {\r
77273 this.leftBox.add(item);\r
77274 }\r
77275 },\r
77276 doBoxRemove: function(item, destroy) {\r
77277 if (item.config.align == 'right') {\r
77278 this.rightBox.remove(item, destroy);\r
77279 } else {\r
77280 this.leftBox.remove(item, destroy);\r
77281 }\r
77282 },\r
77283 doBoxInsert: function(index, item) {\r
77284 if (item.config.align == 'right') {\r
77285 this.rightBox.insert(index, item);\r
77286 } else {\r
77287 this.leftBox.insert(index, item);\r
77288 }\r
77289 },\r
77290 calculateMaxButtonWidth: function() {\r
77291 var maxButtonWidth = this.getMaxButtonWidth();\r
77292
77293 if (Ext.isString(maxButtonWidth)) {\r
77294 maxButtonWidth = parseInt(maxButtonWidth.replace('%', ''), 10);\r
77295 }\r
77296 maxButtonWidth = Math.round((this.element.getWidth() / 100) * maxButtonWidth);\r
77297 return maxButtonWidth;\r
77298 },\r
77299 refreshTitlePosition: function() {\r
77300 if (this.destroyed) {\r
77301 return;\r
77302 }\r
77303 var titleElement = this.titleComponent.renderElement;\r
77304 titleElement.setWidth(null);\r
77305 titleElement.setLeft(null);\r
77306
77307 var leftBox = this.leftBox,\r
77308 leftButton = leftBox.down('button'),\r
77309 singleButton = leftBox.getItems().getCount() == 1,\r
77310 leftBoxWidth, maxButtonWidth;\r
77311 if (leftButton && singleButton) {\r
77312 if (leftButton.getWidth() == null) {\r
77313 leftButton.renderElement.setWidth('auto');\r
77314 }\r
77315 leftBoxWidth = leftBox.renderElement.getWidth();\r
77316 maxButtonWidth = this.calculateMaxButtonWidth();\r
77317 if (leftBoxWidth > maxButtonWidth) {\r
77318 leftButton.renderElement.setWidth(maxButtonWidth);\r
77319 }\r
77320 }\r
77321 var spacerBox = this.spacer.renderElement.getBox();\r
77322 if (Ext.browser.is.IE) {\r
77323 titleElement.setWidth(spacerBox.width);\r
77324 }\r
77325 var titleBox = titleElement.getBox(),\r
77326 widthDiff = titleBox.width - spacerBox.width,\r
77327 titleLeft = titleBox.left,\r
77328 titleRight = titleBox.right,\r
77329 halfWidthDiff, leftDiff, rightDiff;\r
77330 if (widthDiff > 0) {\r
77331 halfWidthDiff = widthDiff / 2;\r
77332 titleLeft += halfWidthDiff;\r
77333 titleRight -= halfWidthDiff;\r
77334 titleElement.setWidth(spacerBox.width);\r
77335 }\r
77336 leftDiff = spacerBox.left - titleLeft;\r
77337 rightDiff = titleRight - spacerBox.right;\r
77338 if (leftDiff > 0) {\r
77339 titleElement.setLeft(leftDiff);\r
77340 } else if (rightDiff > 0) {\r
77341 titleElement.setLeft(-rightDiff);\r
77342 }\r
77343 titleElement.repaint();\r
77344 },\r
77345 \r
77346 updateTitle: function(newTitle) {\r
77347
77348 this.getItems();\r
77349 this.titleComponent.setTitle(newTitle);\r
77350 if (this.isPainted()) {\r
77351 this.refreshTitlePosition();\r
77352 }\r
77353 }\r
77354});\r
77355\r
77356\r
77357Ext.define('Ext.Toast', {\r
77358 extend: Ext.Sheet,\r
77359 config: {\r
77360 \r
77361 ui: 'dark',\r
77362 \r
77363 baseCls: Ext.baseCSSPrefix + 'toast',\r
77364 \r
77365 showAnimation: {\r
77366 type: 'popIn',\r
77367 duration: 250,\r
77368 easing: 'ease-out'\r
77369 },\r
77370 \r
77371 hideAnimation: {\r
77372 type: 'popOut',\r
77373 duration: 250,\r
77374 easing: 'ease-out'\r
77375 },\r
77376 \r
77377 zIndex: 999,\r
77378 \r
77379 message: null,\r
77380 \r
77381 timeout: 1000,\r
77382 \r
77383 messageAnimation: true,\r
77384 \r
77385 hideOnMaskTap: true,\r
77386 \r
77387 modal: true,\r
77388 \r
77389 layout: {\r
77390 type: 'vbox',\r
77391 pack: 'center'\r
77392 }\r
77393 },\r
77394 \r
77395 applyMessage: function(config) {\r
77396 config = {\r
77397 html: config,\r
77398 cls: this.getBaseCls() + '-text'\r
77399 };\r
77400 return Ext.factory(config, Ext.Component, this._message);\r
77401 },\r
77402 \r
77403 updateMessage: function(newMessage) {\r
77404 if (newMessage) {\r
77405 this.add(newMessage);\r
77406 }\r
77407 },\r
77408 \r
77409 applyTimeout: function(timeout) {\r
77410 if (this._timeoutID) {\r
77411 clearTimeout(this._timeoutID);\r
77412 if (!Ext.isEmpty(timeout)) {\r
77413 this._timeoutID = setTimeout(Ext.bind(this.onTimeout, this), timeout);\r
77414 }\r
77415 }\r
77416 return timeout;\r
77417 },\r
77418 \r
77419 next: Ext.emptyFn,\r
77420 \r
77421 show: function(config) {\r
77422 var me = this,\r
77423 timeout = config.timeout,\r
77424 msgAnimation = me.getMessageAnimation(),\r
77425 message = me.getMessage();\r
77426 if (me.isRendered() && me.isHidden() === false) {\r
77427 config.timeout = null;\r
77428 message.onAfter({\r
77429 hiddenchange: function() {\r
77430 me.setMessage(config.message);\r
77431 message = me.getMessage();\r
77432 message.onAfter({\r
77433 hiddenchange: function() {\r
77434
77435 this._timeoutID = true;\r
77436 me.setTimeout(timeout);\r
77437 },\r
77438 scope: me,\r
77439 single: true\r
77440 });\r
77441 message.show(msgAnimation);\r
77442 },\r
77443 scope: me,\r
77444 single: true\r
77445 });\r
77446 message.hide(msgAnimation);\r
77447 } else {\r
77448 Ext.util.InputBlocker.blockInputs();\r
77449 me.setConfig(config);\r
77450
77451 if (!me.getParent() && Ext.Viewport) {\r
77452 Ext.Viewport.add(me);\r
77453 }\r
77454 if (!Ext.isEmpty(timeout)) {\r
77455 me._timeoutID = setTimeout(Ext.bind(me.onTimeout, me), timeout);\r
77456 }\r
77457 me.callParent(arguments);\r
77458 }\r
77459 },\r
77460 \r
77461 hide: function(animation) {\r
77462 clearTimeout(this._timeoutID);\r
77463 if (!this.next()) {\r
77464 this.callParent(arguments);\r
77465 }\r
77466 },\r
77467 \r
77468 onTimeout: function() {\r
77469 this.hide();\r
77470 }\r
77471}, function(Toast) {\r
77472 var _queue = [],\r
77473 _isToasting = false;\r
77474 function next() {\r
77475 var config = _queue.shift();\r
77476 if (config) {\r
77477 _isToasting = true;\r
77478 this.show(config);\r
77479 } else {\r
77480 _isToasting = false;\r
77481 }\r
77482 return _isToasting;\r
77483 }\r
77484 function getInstance() {\r
77485 if (!Ext.Toast._instance) {\r
77486 Ext.Toast._instance = Ext.create('Ext.Toast');\r
77487 Ext.Toast._instance.next = next;\r
77488 }\r
77489 return Ext.Toast._instance;\r
77490 }\r
77491 Ext.toast = function(message, timeout) {\r
77492 var toast = getInstance(),\r
77493 config = message;\r
77494 if (Ext.isString(message)) {\r
77495 config = {\r
77496 message: message,\r
77497 timeout: timeout\r
77498 };\r
77499 }\r
77500 if (config.timeout === undefined) {\r
77501 config.timeout = Ext.Toast.prototype.config.timeout;\r
77502 }\r
77503 _queue.push(config);\r
77504 if (!_isToasting) {\r
77505 toast.next();\r
77506 }\r
77507 return toast;\r
77508 };\r
77509});\r
77510\r
77511\r
77512Ext.define('Ext.Video', {\r
77513 extend: Ext.Media,\r
77514 xtype: 'video',\r
77515 config: {\r
77516 \r
77517 \r
77518 posterUrl: null,\r
77519 \r
77520 baseCls: Ext.baseCSSPrefix + 'video',\r
77521 \r
77522 controls: true\r
77523 },\r
77524 template: [\r
77525 {\r
77526 \r
77527 reference: 'ghost',\r
77528 classList: [\r
77529 Ext.baseCSSPrefix + 'video-ghost'\r
77530 ]\r
77531 },\r
77532 {\r
77533 tag: 'video',\r
77534 reference: 'media',\r
77535 classList: [\r
77536 Ext.baseCSSPrefix + 'media'\r
77537 ]\r
77538 }\r
77539 ],\r
77540 initialize: function() {\r
77541 var me = this;\r
77542 me.callParent();\r
77543 me.media.hide();\r
77544 me.ghost.on({\r
77545 tap: 'onGhostTap',\r
77546 scope: me\r
77547 });\r
77548 me.media.on({\r
77549 pause: 'onPause',\r
77550 scope: me\r
77551 });\r
77552 if (Ext.os.is.Android4 || Ext.os.is.iPad) {\r
77553 this.isInlineVideo = true;\r
77554 }\r
77555 },\r
77556 applyUrl: function(url) {\r
77557 return [].concat(url);\r
77558 },\r
77559 updateUrl: function(newUrl) {\r
77560 var me = this,\r
77561 media = me.media,\r
77562 newLn = newUrl.length,\r
77563 existingSources = media.query('source'),\r
77564 oldLn = existingSources.length,\r
77565 i;\r
77566 for (i = 0; i < oldLn; i++) {\r
77567 Ext.fly(existingSources[i]).destroy();\r
77568 }\r
77569 for (i = 0; i < newLn; i++) {\r
77570 media.appendChild(Ext.Element.create({\r
77571 tag: 'source',\r
77572 src: newUrl[i]\r
77573 }));\r
77574 }\r
77575 if (me.isPlaying()) {\r
77576 me.play();\r
77577 }\r
77578 },\r
77579 updateControls: function(value) {\r
77580 this.media.set({\r
77581 controls: value ? true : undefined\r
77582 });\r
77583 },\r
77584 onActivate: function() {\r
77585 this.media.setTop(0);\r
77586 },\r
77587 onDeactivate: function() {\r
77588 this.pause();\r
77589 this.media.setTop(-2000);\r
77590 this.ghost.show();\r
77591 },\r
77592 \r
77593 onGhostTap: function() {\r
77594 var me = this,\r
77595 media = this.media,\r
77596 ghost = this.ghost;\r
77597 media.show();\r
77598
77599
77600 ghost.hide();\r
77601 me.play();\r
77602 },\r
77603 \r
77604 onPause: function() {\r
77605 this.callParent(arguments);\r
77606 if (!this.isInlineVideo) {\r
77607 this.media.setTop(-2000);\r
77608 this.ghost.show();\r
77609 }\r
77610 },\r
77611 \r
77612 onPlay: function() {\r
77613 this.callParent(arguments);\r
77614 this.media.setTop(0);\r
77615 },\r
77616 \r
77617 updatePosterUrl: function(newUrl) {\r
77618 var ghost = this.ghost;\r
77619 if (ghost) {\r
77620 ghost.setStyle('background-image', 'url(' + newUrl + ')');\r
77621 }\r
77622 }\r
77623});\r
77624\r
77625\r
77626\r
77627\r
77628Ext.define('Ext.carousel.Item', {\r
77629 extend: Ext.Decorator,\r
77630 config: {\r
77631 baseCls: Ext.baseCSSPrefix + 'carousel-item',\r
77632 component: null,\r
77633 translatable: true\r
77634 }\r
77635});\r
77636\r
77637\r
77638Ext.define('Ext.carousel.Indicator', {\r
77639 extend: Ext.Component,\r
77640 xtype: 'carouselindicator',\r
77641 config: {\r
77642 \r
77643 baseCls: Ext.baseCSSPrefix + 'carousel-indicator',\r
77644 direction: 'horizontal'\r
77645 },\r
77646 \r
77647 \r
77648 initialize: function() {\r
77649 this.callParent();\r
77650 this.indicators = [];\r
77651 this.element.on({\r
77652 tap: 'onTap',\r
77653 scope: this\r
77654 });\r
77655 },\r
77656 updateDirection: function(newDirection, oldDirection) {\r
77657 var baseCls = this.getBaseCls();\r
77658 this.element.replaceCls(oldDirection, newDirection, baseCls);\r
77659 if (newDirection === 'horizontal') {\r
77660 this.setBottom(0);\r
77661 this.setRight(null);\r
77662 } else {\r
77663 this.setRight(0);\r
77664 this.setBottom(null);\r
77665 }\r
77666 },\r
77667 addIndicator: function() {\r
77668 this.indicators.push(this.element.createChild({\r
77669 tag: 'span'\r
77670 }));\r
77671 },\r
77672 removeIndicator: function() {\r
77673 var indicators = this.indicators;\r
77674 if (indicators.length > 0) {\r
77675 indicators.pop().destroy();\r
77676 }\r
77677 },\r
77678 setActiveIndex: function(index) {\r
77679 var indicators = this.indicators,\r
77680 currentActiveIndex = this.activeIndex,\r
77681 currentActiveItem = indicators[currentActiveIndex],\r
77682 activeItem = indicators[index],\r
77683 baseCls = this.getBaseCls();\r
77684 if (currentActiveItem) {\r
77685 currentActiveItem.removeCls(baseCls, null, 'active');\r
77686 }\r
77687 if (activeItem) {\r
77688 activeItem.addCls(baseCls, null, 'active');\r
77689 }\r
77690 this.activeIndex = index;\r
77691 return this;\r
77692 },\r
77693 \r
77694 onTap: function(e) {\r
77695 var touch = e.touch,\r
77696 box = this.element.getBox(),\r
77697 centerX = box.left + (box.width / 2),\r
77698 centerY = box.top + (box.height / 2),\r
77699 direction = this.getDirection();\r
77700 if ((direction === 'horizontal' && touch.pageX >= centerX) || (direction === 'vertical' && touch.pageY >= centerY)) {\r
77701 this.fireEvent('next', this);\r
77702 } else {\r
77703 this.fireEvent('previous', this);\r
77704 }\r
77705 },\r
77706 destroy: function() {\r
77707 var indicators = this.indicators,\r
77708 i, ln, indicator;\r
77709 for (i = 0 , ln = indicators.length; i < ln; i++) {\r
77710 indicator = indicators[i];\r
77711 indicator.destroy();\r
77712 }\r
77713 indicators.length = 0;\r
77714 this.callParent();\r
77715 }\r
77716});\r
77717\r
77718\r
77719Ext.define('Ext.util.TranslatableGroup', {\r
77720 extend: Ext.util.translatable.Abstract,\r
77721 config: {\r
77722 items: [],\r
77723 activeIndex: 0,\r
77724 itemLength: {\r
77725 x: 0,\r
77726 y: 0\r
77727 }\r
77728 },\r
77729 applyItems: function(items) {\r
77730 return Ext.Array.from(items);\r
77731 },\r
77732 doTranslate: function(x, y) {\r
77733 var items = this.getItems(),\r
77734 activeIndex = this.getActiveIndex(),\r
77735 itemLength = this.getItemLength(),\r
77736 itemLengthX = itemLength.x,\r
77737 itemLengthY = itemLength.y,\r
77738 useX = Ext.isNumber(x),\r
77739 useY = Ext.isNumber(y),\r
77740 offset, i, ln, item, translateX, translateY;\r
77741 for (i = 0 , ln = items.length; i < ln; i++) {\r
77742 item = items[i];\r
77743 if (item) {\r
77744 offset = (i - activeIndex);\r
77745 if (useX) {\r
77746 translateX = x + offset * itemLengthX;\r
77747 }\r
77748 if (useY) {\r
77749 translateY = y + offset * itemLengthY;\r
77750 }\r
77751 item.translate(translateX, translateY);\r
77752 }\r
77753 }\r
77754 }\r
77755});\r
77756\r
77757\r
77758Ext.define('Ext.carousel.Carousel', {\r
77759 extend: Ext.Container,\r
77760 alternateClassName: 'Ext.Carousel',\r
77761 xtype: 'carousel',\r
77762 config: {\r
77763 \r
77764 \r
77765 baseCls: 'x-carousel',\r
77766 \r
77767 direction: 'horizontal',\r
77768 directionLock: false,\r
77769 animation: {\r
77770 duration: 250,\r
77771 easing: {\r
77772 type: 'ease-out'\r
77773 }\r
77774 },\r
77775 \r
77776 \r
77777 indicator: true,\r
77778 \r
77779 ui: 'dark',\r
77780 itemConfig: {},\r
77781 bufferSize: 1,\r
77782 itemLength: null\r
77783 },\r
77784 itemLength: 0,\r
77785 offset: 0,\r
77786 flickStartOffset: 0,\r
77787 flickStartTime: 0,\r
77788 dragDirection: 0,\r
77789 count: 0,\r
77790 painted: false,\r
77791 activeIndex: -1,\r
77792 beforeInitialize: function() {\r
77793 var me = this;\r
77794 me.element.on({\r
77795 resize: 'onSizeChange',\r
77796 dragstart: 'onDragStart',\r
77797 drag: 'onDrag',\r
77798 dragend: 'onDragEnd',\r
77799 scope: me\r
77800 });\r
77801 me.carouselItems = [];\r
77802 me.orderedCarouselItems = [];\r
77803 me.inactiveCarouselItems = [];\r
77804 me.hiddenTranslation = 0;\r
77805 },\r
77806 updateBufferSize: function(size) {\r
77807 var ItemClass = Ext.carousel.Item,\r
77808 total = size * 2 + 1,\r
77809 isRendered = this.isRendered(),\r
77810 innerElement = this.innerElement,\r
77811 items = this.carouselItems,\r
77812 ln = items.length,\r
77813 itemConfig = this.getItemConfig(),\r
77814 itemLength = this.getItemLength(),\r
77815 direction = this.getDirection(),\r
77816 setterName = direction === 'horizontal' ? 'setWidth' : 'setHeight',\r
77817 i, item;\r
77818 for (i = ln; i < total; i++) {\r
77819 item = Ext.factory(itemConfig, ItemClass);\r
77820 if (itemLength) {\r
77821 item[setterName].call(item, itemLength);\r
77822 }\r
77823 item.setLayoutSizeFlags(this.LAYOUT_BOTH);\r
77824 items.push(item);\r
77825 innerElement.append(item.renderElement);\r
77826 if (isRendered && item.setRendered(true)) {\r
77827 item.fireEvent('renderedchange', this, item, true);\r
77828 }\r
77829 }\r
77830 this.getTranslatable().setActiveIndex(size);\r
77831 },\r
77832 setRendered: function(rendered) {\r
77833 var wasRendered = this.rendered;\r
77834 if (rendered !== wasRendered) {\r
77835 this.rendered = rendered;\r
77836 var items = this.items.items,\r
77837 carouselItems = this.carouselItems,\r
77838 i, ln, item;\r
77839 for (i = 0 , ln = items.length; i < ln; i++) {\r
77840 item = items[i];\r
77841 if (!item.isInnerItem()) {\r
77842 item.setRendered(rendered);\r
77843 }\r
77844 }\r
77845 for (i = 0 , ln = carouselItems.length; i < ln; i++) {\r
77846 carouselItems[i].setRendered(rendered);\r
77847 }\r
77848 return true;\r
77849 }\r
77850 return false;\r
77851 },\r
77852 onSizeChange: function() {\r
77853 this.refreshSizing();\r
77854 this.refreshCarouselItems();\r
77855 this.refreshActiveItem();\r
77856 },\r
77857 onItemAdd: function(item, index) {\r
77858 this.callParent(arguments);\r
77859 var innerIndex = this.getInnerItems().indexOf(item),\r
77860 indicator = this.getIndicator();\r
77861 if (indicator && item.isInnerItem()) {\r
77862 indicator.addIndicator();\r
77863 }\r
77864 if (innerIndex <= this.getActiveIndex()) {\r
77865 this.refreshActiveIndex();\r
77866 }\r
77867 if (this.isIndexDirty(innerIndex) && !this.isItemsInitializing) {\r
77868 this.refreshActiveItem();\r
77869 }\r
77870 },\r
77871 doItemLayoutAdd: function(item) {\r
77872 if (item.isInnerItem()) {\r
77873 return;\r
77874 }\r
77875 this.callParent(arguments);\r
77876 },\r
77877 onItemRemove: function(item, index) {\r
77878 this.callParent(arguments);\r
77879 var innerIndex = this.getInnerItems().indexOf(item),\r
77880 indicator = this.getIndicator(),\r
77881 carouselItems = this.carouselItems,\r
77882 i, ln, carouselItem;\r
77883 if (item.isInnerItem() && indicator) {\r
77884 indicator.removeIndicator();\r
77885 }\r
77886 if (innerIndex <= this.getActiveIndex()) {\r
77887 this.refreshActiveIndex();\r
77888 }\r
77889 if (this.isIndexDirty(innerIndex)) {\r
77890 for (i = 0 , ln = carouselItems.length; i < ln; i++) {\r
77891 carouselItem = carouselItems[i];\r
77892 if (carouselItem.getComponent() === item) {\r
77893 carouselItem.setComponent(null);\r
77894 }\r
77895 }\r
77896 this.refreshActiveItem();\r
77897 }\r
77898 },\r
77899 doItemLayoutRemove: function(item) {\r
77900 if (item.isInnerItem()) {\r
77901 return;\r
77902 }\r
77903 this.callParent(arguments);\r
77904 },\r
77905 onInnerItemMove: function(item, toIndex, fromIndex) {\r
77906 if ((this.isIndexDirty(toIndex) || this.isIndexDirty(fromIndex))) {\r
77907 this.refreshActiveItem();\r
77908 }\r
77909 },\r
77910 doItemLayoutMove: function(item) {\r
77911 if (item.isInnerItem()) {\r
77912 return;\r
77913 }\r
77914 this.callParent(arguments);\r
77915 },\r
77916 isIndexDirty: function(index) {\r
77917 var activeIndex = this.getActiveIndex(),\r
77918 bufferSize = this.getBufferSize();\r
77919 return (index >= activeIndex - bufferSize && index <= activeIndex + bufferSize);\r
77920 },\r
77921 getTranslatable: function() {\r
77922 var me = this,\r
77923 translatable = me.translatable;\r
77924 if (!translatable) {\r
77925 me.translatable = translatable = new Ext.util.TranslatableGroup();\r
77926 translatable.setItems(me.orderedCarouselItems);\r
77927 translatable.on('animationend', 'onAnimationEnd', me);\r
77928 }\r
77929 return translatable;\r
77930 },\r
77931 onDragStart: function(e) {\r
77932 var direction = this.getDirection(),\r
77933 absDeltaX = e.absDeltaX,\r
77934 absDeltaY = e.absDeltaY,\r
77935 directionLock = this.getDirectionLock();\r
77936 this.isDragging = true;\r
77937 if (directionLock) {\r
77938 if ((direction === 'horizontal' && absDeltaX > absDeltaY) || (direction === 'vertical' && absDeltaY > absDeltaX)) {\r
77939 e.stopPropagation();\r
77940 } else {\r
77941 this.isDragging = false;\r
77942 return;\r
77943 }\r
77944 }\r
77945 this.getTranslatable().stopAnimation();\r
77946 this.dragStartOffset = this.offset;\r
77947 this.dragDirection = 0;\r
77948 },\r
77949 onDrag: function(e) {\r
77950 if (!this.isDragging) {\r
77951 return;\r
77952 }\r
77953 var startOffset = this.dragStartOffset,\r
77954 direction = this.getDirection(),\r
77955 delta = direction === 'horizontal' ? e.deltaX : e.deltaY,\r
77956 lastOffset = this.offset,\r
77957 flickStartTime = this.flickStartTime,\r
77958 dragDirection = this.dragDirection,\r
77959 now = Ext.Date.now(),\r
77960 currentActiveIndex = this.getActiveIndex(),\r
77961 maxIndex = this.getMaxItemIndex(),\r
77962 lastDragDirection = dragDirection,\r
77963 offset;\r
77964 if ((currentActiveIndex === 0 && delta > 0) || (currentActiveIndex === maxIndex && delta < 0)) {\r
77965 delta *= 0.5;\r
77966 }\r
77967 offset = startOffset + delta;\r
77968 if (offset > lastOffset) {\r
77969 dragDirection = 1;\r
77970 } else if (offset < lastOffset) {\r
77971 dragDirection = -1;\r
77972 }\r
77973 if (dragDirection !== lastDragDirection || (now - flickStartTime) > 300) {\r
77974 this.flickStartOffset = lastOffset;\r
77975 this.flickStartTime = now;\r
77976 }\r
77977 this.dragDirection = dragDirection;\r
77978 this.setOffset(offset);\r
77979 },\r
77980 onDragEnd: function(e) {\r
77981 if (!this.isDragging) {\r
77982 return;\r
77983 }\r
77984 this.onDrag(e);\r
77985 this.isDragging = false;\r
77986 var now = Ext.Date.now(),\r
77987 itemLength = this.itemLength,\r
77988 threshold = itemLength / 2,\r
77989 offset = this.offset,\r
77990 activeIndex = this.getActiveIndex(),\r
77991 maxIndex = this.getMaxItemIndex(),\r
77992 animationDirection = 0,\r
77993 flickDistance = offset - this.flickStartOffset,\r
77994 flickDuration = now - this.flickStartTime,\r
77995 indicator = this.getIndicator(),\r
77996 velocity;\r
77997 if (flickDuration > 0 && Math.abs(flickDistance) >= 10) {\r
77998 velocity = flickDistance / flickDuration;\r
77999 if (Math.abs(velocity) >= 1) {\r
78000 if (velocity < 0 && activeIndex < maxIndex) {\r
78001 animationDirection = -1;\r
78002 } else if (velocity > 0 && activeIndex > 0) {\r
78003 animationDirection = 1;\r
78004 }\r
78005 }\r
78006 }\r
78007 if (animationDirection === 0) {\r
78008 if (activeIndex < maxIndex && offset < -threshold) {\r
78009 animationDirection = -1;\r
78010 } else if (activeIndex > 0 && offset > threshold) {\r
78011 animationDirection = 1;\r
78012 }\r
78013 }\r
78014 if (indicator) {\r
78015 indicator.setActiveIndex(activeIndex - animationDirection);\r
78016 }\r
78017 this.animationDirection = animationDirection;\r
78018 this.setOffsetAnimated(animationDirection * itemLength);\r
78019 },\r
78020 applyAnimation: function(animation) {\r
78021 animation.easing = Ext.factory(animation.easing, Ext.fx.easing.EaseOut);\r
78022 return animation;\r
78023 },\r
78024 updateDirection: function(direction) {\r
78025 var indicator = this.getIndicator();\r
78026 this.currentAxis = (direction === 'horizontal') ? 'x' : 'y';\r
78027 if (indicator) {\r
78028 indicator.setDirection(direction);\r
78029 }\r
78030 },\r
78031 \r
78032 setOffset: function(offset) {\r
78033 this.offset = offset;\r
78034 if (Ext.isNumber(this.itemOffset)) {\r
78035 this.getTranslatable().translateAxis(this.currentAxis, offset + this.itemOffset);\r
78036 }\r
78037 return this;\r
78038 },\r
78039 \r
78040 setOffsetAnimated: function(offset) {\r
78041 var indicator = this.getIndicator();\r
78042 if (indicator) {\r
78043 indicator.setActiveIndex(this.getActiveIndex() - this.animationDirection);\r
78044 }\r
78045 this.offset = offset;\r
78046 this.getTranslatable().translateAxis(this.currentAxis, offset + this.itemOffset, this.getAnimation());\r
78047 return this;\r
78048 },\r
78049 onAnimationEnd: function(translatable) {\r
78050 var currentActiveIndex = this.getActiveIndex(),\r
78051 animationDirection = this.animationDirection,\r
78052 axis = this.currentAxis,\r
78053 currentOffset = translatable[axis],\r
78054 itemLength = this.itemLength,\r
78055 offset;\r
78056 if (animationDirection === -1) {\r
78057 offset = itemLength + currentOffset;\r
78058 } else if (animationDirection === 1) {\r
78059 offset = currentOffset - itemLength;\r
78060 } else {\r
78061 offset = currentOffset;\r
78062 }\r
78063 offset -= this.itemOffset;\r
78064 this.offset = offset;\r
78065 this.setActiveItem(currentActiveIndex - animationDirection);\r
78066 },\r
78067 refresh: function() {\r
78068 this.refreshSizing();\r
78069 this.refreshActiveItem();\r
78070 },\r
78071 refreshSizing: function() {\r
78072 var element = this.element,\r
78073 itemLength = this.getItemLength(),\r
78074 translatableItemLength = {\r
78075 x: 0,\r
78076 y: 0\r
78077 },\r
78078 itemOffset, containerSize;\r
78079 if (this.getDirection() === 'horizontal') {\r
78080 containerSize = element.getWidth();\r
78081 } else {\r
78082 containerSize = element.getHeight();\r
78083 }\r
78084 this.hiddenTranslation = -containerSize;\r
78085 if (itemLength === null) {\r
78086 itemLength = containerSize;\r
78087 itemOffset = 0;\r
78088 } else {\r
78089 itemOffset = (containerSize - itemLength) / 2;\r
78090 }\r
78091 this.itemLength = itemLength;\r
78092 this.itemOffset = itemOffset;\r
78093 translatableItemLength[this.currentAxis] = itemLength;\r
78094 this.getTranslatable().setItemLength(translatableItemLength);\r
78095 },\r
78096 refreshOffset: function() {\r
78097 this.setOffset(this.offset);\r
78098 },\r
78099 refreshActiveItem: function() {\r
78100 this.updateActiveItem(this.getActiveItem());\r
78101 },\r
78102 \r
78103 getActiveIndex: function() {\r
78104 return this.activeIndex;\r
78105 },\r
78106 refreshActiveIndex: function() {\r
78107 this.activeIndex = this.getInnerItemIndex(this.getActiveItem());\r
78108 },\r
78109 refreshCarouselItems: function() {\r
78110 var items = this.carouselItems,\r
78111 i, ln, item;\r
78112 for (i = 0 , ln = items.length; i < ln; i++) {\r
78113 item = items[i];\r
78114 item.getTranslatable().refresh();\r
78115 }\r
78116 this.refreshInactiveCarouselItems();\r
78117 },\r
78118 refreshInactiveCarouselItems: function() {\r
78119 var items = this.inactiveCarouselItems,\r
78120 hiddenTranslation = this.hiddenTranslation,\r
78121 axis = this.currentAxis,\r
78122 i, ln, item;\r
78123 for (i = 0 , ln = items.length; i < ln; i++) {\r
78124 item = items[i];\r
78125 item.translateAxis(axis, hiddenTranslation);\r
78126 }\r
78127 },\r
78128 \r
78129 getMaxItemIndex: function() {\r
78130 return this.innerItems.length - 1;\r
78131 },\r
78132 \r
78133 getInnerItemIndex: function(item) {\r
78134 return this.innerItems.indexOf(item);\r
78135 },\r
78136 \r
78137 getInnerItemAt: function(index) {\r
78138 return this.innerItems[index];\r
78139 },\r
78140 \r
78141 applyActiveItem: function() {\r
78142 var activeItem = this.callParent(arguments),\r
78143 activeIndex;\r
78144 if (activeItem) {\r
78145 activeIndex = this.getInnerItemIndex(activeItem);\r
78146 if (activeIndex !== -1) {\r
78147 this.activeIndex = activeIndex;\r
78148 return activeItem;\r
78149 }\r
78150 }\r
78151 },\r
78152 updateActiveItem: function(activeItem) {\r
78153 var activeIndex = this.getActiveIndex(),\r
78154 maxIndex = this.getMaxItemIndex(),\r
78155 indicator = this.getIndicator(),\r
78156 bufferSize = this.getBufferSize(),\r
78157 carouselItems = this.carouselItems.slice(),\r
78158 orderedCarouselItems = this.orderedCarouselItems,\r
78159 visibleIndexes = {},\r
78160 visibleItems = {},\r
78161 visibleItem, component, id, i, index, ln, carouselItem;\r
78162 if (carouselItems.length === 0) {\r
78163 return;\r
78164 }\r
78165 this.callParent(arguments);\r
78166 orderedCarouselItems.length = 0;\r
78167 if (activeItem) {\r
78168 id = activeItem.getId();\r
78169 visibleItems[id] = activeItem;\r
78170 visibleIndexes[id] = bufferSize;\r
78171 if (activeIndex > 0) {\r
78172 for (i = 1; i <= bufferSize; i++) {\r
78173 index = activeIndex - i;\r
78174 if (index >= 0) {\r
78175 visibleItem = this.getInnerItemAt(index);\r
78176 id = visibleItem.getId();\r
78177 visibleItems[id] = visibleItem;\r
78178 visibleIndexes[id] = bufferSize - i;\r
78179 } else {\r
78180 break;\r
78181 }\r
78182 }\r
78183 }\r
78184 if (activeIndex < maxIndex) {\r
78185 for (i = 1; i <= bufferSize; i++) {\r
78186 index = activeIndex + i;\r
78187 if (index <= maxIndex) {\r
78188 visibleItem = this.getInnerItemAt(index);\r
78189 id = visibleItem.getId();\r
78190 visibleItems[id] = visibleItem;\r
78191 visibleIndexes[id] = bufferSize + i;\r
78192 } else {\r
78193 break;\r
78194 }\r
78195 }\r
78196 }\r
78197 for (i = 0 , ln = carouselItems.length; i < ln; i++) {\r
78198 carouselItem = carouselItems[i];\r
78199 component = carouselItem.getComponent();\r
78200 if (component) {\r
78201 id = component.getId();\r
78202 if (visibleIndexes.hasOwnProperty(id)) {\r
78203 carouselItems.splice(i, 1);\r
78204 i--;\r
78205 ln--;\r
78206 delete visibleItems[id];\r
78207 orderedCarouselItems[visibleIndexes[id]] = carouselItem;\r
78208 }\r
78209 }\r
78210 }\r
78211 for (id in visibleItems) {\r
78212 if (visibleItems.hasOwnProperty(id)) {\r
78213 visibleItem = visibleItems[id];\r
78214 carouselItem = carouselItems.pop();\r
78215 carouselItem.setComponent(visibleItem);\r
78216 orderedCarouselItems[visibleIndexes[id]] = carouselItem;\r
78217 }\r
78218 }\r
78219 }\r
78220 this.inactiveCarouselItems.length = 0;\r
78221 this.inactiveCarouselItems = carouselItems;\r
78222 this.refreshOffset();\r
78223 this.refreshInactiveCarouselItems();\r
78224 if (indicator) {\r
78225 indicator.setActiveIndex(activeIndex);\r
78226 }\r
78227 },\r
78228 \r
78229 next: function() {\r
78230 this.setOffset(0);\r
78231 if (this.activeIndex === this.getMaxItemIndex()) {\r
78232 return this;\r
78233 }\r
78234 this.animationDirection = -1;\r
78235 this.setOffsetAnimated(-this.itemLength);\r
78236 return this;\r
78237 },\r
78238 \r
78239 previous: function() {\r
78240 this.setOffset(0);\r
78241 if (this.activeIndex === 0) {\r
78242 return this;\r
78243 }\r
78244 this.animationDirection = 1;\r
78245 this.setOffsetAnimated(this.itemLength);\r
78246 return this;\r
78247 },\r
78248 \r
78249 applyIndicator: function(indicator, currentIndicator) {\r
78250 return Ext.factory(indicator, Ext.carousel.Indicator, currentIndicator);\r
78251 },\r
78252 \r
78253 updateIndicator: function(indicator) {\r
78254 if (indicator) {\r
78255 this.insertFirst(indicator);\r
78256 indicator.setUi(this.getUi());\r
78257 indicator.on({\r
78258 next: 'next',\r
78259 previous: 'previous',\r
78260 scope: this\r
78261 });\r
78262 }\r
78263 },\r
78264 destroy: function() {\r
78265 var me = this,\r
78266 carouselItems = me.carouselItems.slice();\r
78267 me.carouselItems.length = 0;\r
78268 Ext.destroy(carouselItems, me.getIndicator(), me.translatable);\r
78269 me.callParent();\r
78270 delete me.carouselItems;\r
78271 }\r
78272});\r
78273\r
78274\r
78275Ext.define('Ext.carousel.Infinite', {\r
78276 extend: Ext.carousel.Carousel,\r
78277 config: {\r
78278 indicator: null,\r
78279 maxItemIndex: Infinity,\r
78280 innerItemConfig: {}\r
78281 },\r
78282 applyIndicator: function(indicator) {\r
78283
78284 if (indicator) {\r
78285 Ext.Logger.error("'indicator' in Infinite Carousel implementation is not currently supported", this);\r
78286 }\r
78287
78288 return;\r
78289 },\r
78290 updateBufferSize: function(size) {\r
78291 this.callParent(arguments);\r
78292 var total = size * 2 + 1,\r
78293 ln = this.innerItems.length,\r
78294 innerItemConfig = this.getInnerItemConfig(),\r
78295 i;\r
78296 this.isItemsInitializing = true;\r
78297 for (i = ln; i < total; i++) {\r
78298 this.doAdd(this.factoryItem(innerItemConfig));\r
78299 }\r
78300 this.isItemsInitializing = false;\r
78301 this.rebuildInnerIndexes();\r
78302 this.refreshActiveItem();\r
78303 },\r
78304 updateMaxItemIndex: function(maxIndex, oldMaxIndex) {\r
78305 if (oldMaxIndex !== undefined) {\r
78306 var activeIndex = this.getActiveIndex();\r
78307 if (activeIndex > maxIndex) {\r
78308 this.setActiveItem(maxIndex);\r
78309 } else {\r
78310 this.rebuildInnerIndexes(activeIndex);\r
78311 this.refreshActiveItem();\r
78312 }\r
78313 }\r
78314 },\r
78315 rebuildInnerIndexes: function(activeIndex) {\r
78316 var indexToItem = this.innerIndexToItem,\r
78317 idToIndex = this.innerIdToIndex,\r
78318 items = this.innerItems.slice(),\r
78319 ln = items.length,\r
78320 bufferSize = this.getBufferSize(),\r
78321 maxIndex = this.getMaxItemIndex(),\r
78322 changedIndexes = [],\r
78323 i, oldIndex, index, id, item;\r
78324 if (activeIndex === undefined) {\r
78325 this.innerIndexToItem = indexToItem = {};\r
78326 this.innerIdToIndex = idToIndex = {};\r
78327 for (i = 0; i < ln; i++) {\r
78328 item = items[i];\r
78329 id = item.getId();\r
78330 idToIndex[id] = i;\r
78331 indexToItem[i] = item;\r
78332 this.fireEvent('itemindexchange', this, item, i, -1);\r
78333 }\r
78334 } else {\r
78335 for (i = activeIndex - bufferSize; i <= activeIndex + bufferSize; i++) {\r
78336 if (i >= 0 && i <= maxIndex) {\r
78337 if (indexToItem.hasOwnProperty(i)) {\r
78338 Ext.Array.remove(items, indexToItem[i]);\r
78339 \r
78340 continue;\r
78341 }\r
78342 changedIndexes.push(i);\r
78343 }\r
78344 }\r
78345 for (i = 0 , ln = changedIndexes.length; i < ln; i++) {\r
78346 item = items[i];\r
78347 id = item.getId();\r
78348 index = changedIndexes[i];\r
78349 oldIndex = idToIndex[id];\r
78350 delete indexToItem[oldIndex];\r
78351 idToIndex[id] = index;\r
78352 indexToItem[index] = item;\r
78353 this.fireEvent('itemindexchange', this, item, index, oldIndex);\r
78354 }\r
78355 }\r
78356 },\r
78357 reset: function() {\r
78358 this.rebuildInnerIndexes();\r
78359 this.setActiveItem(0);\r
78360 },\r
78361 refreshItems: function() {\r
78362 var items = this.innerItems,\r
78363 idToIndex = this.innerIdToIndex,\r
78364 index, item, i, ln;\r
78365 for (i = 0 , ln = items.length; i < ln; i++) {\r
78366 item = items[i];\r
78367 index = idToIndex[item.getId()];\r
78368 this.fireEvent('itemindexchange', this, item, index, -1);\r
78369 }\r
78370 },\r
78371 getInnerItemIndex: function(item) {\r
78372 var index = this.innerIdToIndex[item.getId()];\r
78373 return (typeof index == 'number') ? index : -1;\r
78374 },\r
78375 getInnerItemAt: function(index) {\r
78376 return this.innerIndexToItem[index];\r
78377 },\r
78378 applyActiveItem: function(activeItem) {\r
78379 this.getItems();\r
78380 this.getBufferSize();\r
78381 var maxIndex = this.getMaxItemIndex(),\r
78382 currentActiveIndex = this.getActiveIndex();\r
78383 if (typeof activeItem == 'number') {\r
78384 activeItem = Math.max(0, Math.min(activeItem, maxIndex));\r
78385 if (activeItem === currentActiveIndex) {\r
78386 return;\r
78387 }\r
78388 this.activeIndex = activeItem;\r
78389 this.rebuildInnerIndexes(activeItem);\r
78390 activeItem = this.getInnerItemAt(activeItem);\r
78391 }\r
78392 if (activeItem) {\r
78393 return this.callParent([\r
78394 activeItem\r
78395 ]);\r
78396 }\r
78397 }\r
78398});\r
78399\r
78400\r
78401Ext.define('Ext.dataview.component.DataItem', {\r
78402 extend: Ext.Container,\r
78403 xtype: 'dataitem',\r
78404 config: {\r
78405 baseCls: Ext.baseCSSPrefix + 'data-item',\r
78406 defaultType: 'component',\r
78407 \r
78408 record: null,\r
78409 \r
78410 itemCls: null,\r
78411 \r
78412 dataMap: {},\r
78413 \r
78414 dataview: null,\r
78415 width: '100%',\r
78416 items: [\r
78417 {\r
78418 xtype: 'component'\r
78419 }\r
78420 ]\r
78421 },\r
78422 updateBaseCls: function(newBaseCls, oldBaseCls) {\r
78423 var me = this;\r
78424 me.callParent(arguments);\r
78425 },\r
78426 updateItemCls: function(newCls, oldCls) {\r
78427 if (oldCls) {\r
78428 this.removeCls(oldCls);\r
78429 }\r
78430 if (newCls) {\r
78431 this.addCls(newCls);\r
78432 }\r
78433 },\r
78434 doMapData: function(dataMap, data, item) {\r
78435 var componentName, component, setterMap, setterName;\r
78436 for (componentName in dataMap) {\r
78437 setterMap = dataMap[componentName];\r
78438 component = this[componentName]();\r
78439 if (component) {\r
78440 for (setterName in setterMap) {\r
78441 if (data && component[setterName] && data[setterMap[setterName]] !== undefined && data[setterMap[setterName]] !== null) {\r
78442 component[setterName](data[setterMap[setterName]]);\r
78443 }\r
78444 }\r
78445 }\r
78446 }\r
78447 if (item) {\r
78448
78449 item.updateData(data);\r
78450 }\r
78451 },\r
78452 \r
78453 updateRecord: function(newRecord) {\r
78454 if (!newRecord) {\r
78455 return;\r
78456 }\r
78457 this._record = newRecord;\r
78458 var me = this,\r
78459 dataview = me.dataview || this.getDataview(),\r
78460 data = dataview.prepareData(newRecord.getData(true), dataview.getStore().indexOf(newRecord), newRecord),\r
78461 items = me.getItems(),\r
78462 item = items.first(),\r
78463 dataMap = me.getDataMap();\r
78464 if (!item) {\r
78465 return;\r
78466 }\r
78467 if (dataMap) {\r
78468 this.doMapData(dataMap, data, item);\r
78469 }\r
78470 \r
78471 me.fireEvent('updatedata', me, data);\r
78472 }\r
78473});\r
78474\r
78475\r
78476Ext.define('Ext.dataview.component.Container', {\r
78477 extend: Ext.Container,\r
78478 \r
78479 \r
78480 \r
78481 \r
78482 \r
78483 \r
78484 \r
78485 \r
78486 constructor: function() {\r
78487 this.itemCache = [];\r
78488 this.callParent(arguments);\r
78489 },\r
78490 \r
78491 doInitialize: function() {\r
78492 this.innerElement.on({\r
78493 touchstart: 'onItemTouchStart',\r
78494 touchend: 'onItemTouchEnd',\r
78495 tap: 'onItemTap',\r
78496 taphold: 'onItemTapHold',\r
78497 touchmove: 'onItemTouchMove',\r
78498 singletap: 'onItemSingleTap',\r
78499 doubletap: 'onItemDoubleTap',\r
78500 swipe: 'onItemSwipe',\r
78501 delegate: '> .' + Ext.baseCSSPrefix + 'data-item',\r
78502 scope: this\r
78503 });\r
78504 },\r
78505 \r
78506 initialize: function() {\r
78507 this.callParent();\r
78508 this.doInitialize();\r
78509 },\r
78510 onItemTouchStart: function(e) {\r
78511 var me = this,\r
78512 target = e.currentTarget,\r
78513 item = Ext.getCmp(target.id);\r
78514 item.on({\r
78515 touchmove: 'onItemTouchMove',\r
78516 scope: me,\r
78517 single: true\r
78518 });\r
78519 me.fireEvent('itemtouchstart', me, item, me.indexOf(item), e);\r
78520 },\r
78521 onItemTouchMove: function(e) {\r
78522 var me = this,\r
78523 target = e.currentTarget,\r
78524 item = Ext.getCmp(target.id);\r
78525 me.fireEvent('itemtouchmove', me, item, me.indexOf(item), e);\r
78526 },\r
78527 onItemTouchEnd: function(e) {\r
78528 var me = this,\r
78529 target = e.currentTarget,\r
78530 item = Ext.getCmp(target.id);\r
78531 item.un({\r
78532 touchmove: 'onItemTouchMove',\r
78533 scope: me\r
78534 });\r
78535 me.fireEvent('itemtouchend', me, item, me.indexOf(item), e);\r
78536 },\r
78537 onItemTap: function(e) {\r
78538 var me = this,\r
78539 target = e.currentTarget,\r
78540 item = Ext.getCmp(target.id);\r
78541 me.fireEvent('itemtap', me, item, me.indexOf(item), e);\r
78542 },\r
78543 onItemTapHold: function(e) {\r
78544 var me = this,\r
78545 target = e.currentTarget,\r
78546 item = Ext.getCmp(target.id);\r
78547 me.fireEvent('itemtaphold', me, item, me.indexOf(item), e);\r
78548 },\r
78549 onItemSingleTap: function(e) {\r
78550 var me = this,\r
78551 target = e.currentTarget,\r
78552 item = Ext.getCmp(target.id);\r
78553 me.fireEvent('itemsingletap', me, item, me.indexOf(item), e);\r
78554 },\r
78555 onItemDoubleTap: function(e) {\r
78556 var me = this,\r
78557 target = e.currentTarget,\r
78558 item = Ext.getCmp(target.id);\r
78559 me.fireEvent('itemdoubletap', me, item, me.indexOf(item), e);\r
78560 },\r
78561 onItemSwipe: function(e) {\r
78562 var me = this,\r
78563 target = e.currentTarget,\r
78564 item = Ext.getCmp(target.id);\r
78565 me.fireEvent('itemswipe', me, item, me.indexOf(item), e);\r
78566 },\r
78567 moveItemsToCache: function(from, to) {\r
78568 var me = this,\r
78569 dataview = me.dataview,\r
78570 maxItemCache = dataview.getMaxItemCache(),\r
78571 items = me.getViewItems(),\r
78572 itemCache = me.itemCache,\r
78573 cacheLn = itemCache.length,\r
78574 pressedCls = dataview.getPressedCls(),\r
78575 selectedCls = dataview.getSelectedCls(),\r
78576 i = to - from,\r
78577 item;\r
78578 for (; i >= 0; i--) {\r
78579 item = items[from + i];\r
78580 if (cacheLn !== maxItemCache) {\r
78581 me.remove(item, false);\r
78582 item.removeCls([\r
78583 pressedCls,\r
78584 selectedCls\r
78585 ]);\r
78586 itemCache.push(item);\r
78587 cacheLn++;\r
78588 } else {\r
78589 item.destroy();\r
78590 }\r
78591 }\r
78592 if (me.getViewItems().length == 0) {\r
78593 this.dataview.showEmptyText();\r
78594 }\r
78595 },\r
78596 moveItemsFromCache: function(records) {\r
78597 var me = this,\r
78598 dataview = me.dataview,\r
78599 store = dataview.getStore(),\r
78600 ln = records.length,\r
78601 xtype = dataview.getDefaultType(),\r
78602 itemConfig = dataview.getItemConfig(),\r
78603 itemCache = me.itemCache,\r
78604 cacheLn = itemCache.length,\r
78605 items = [],\r
78606 i, item, record;\r
78607 if (ln) {\r
78608 dataview.hideEmptyText();\r
78609 }\r
78610 for (i = 0; i < ln; i++) {\r
78611 records[i]._tmpIndex = store.indexOf(records[i]);\r
78612 }\r
78613 Ext.Array.sort(records, function(record1, record2) {\r
78614 return record1._tmpIndex > record2._tmpIndex ? 1 : -1;\r
78615 });\r
78616 for (i = 0; i < ln; i++) {\r
78617 record = records[i];\r
78618 if (cacheLn) {\r
78619 cacheLn--;\r
78620 item = itemCache.pop();\r
78621 this.updateListItem(record, item);\r
78622 } else {\r
78623 item = me.getDataItemConfig(xtype, record, itemConfig);\r
78624 }\r
78625 item = this.insert(record._tmpIndex, item);\r
78626 delete record._tmpIndex;\r
78627 }\r
78628 return items;\r
78629 },\r
78630 getViewItems: function() {\r
78631 return this.getInnerItems();\r
78632 },\r
78633 updateListItem: function(record, item) {\r
78634 if (item.updateRecord) {\r
78635 if (item.getRecord() === record) {\r
78636 item.updateRecord(record);\r
78637 } else {\r
78638 item.setRecord(record);\r
78639 }\r
78640 }\r
78641 },\r
78642 getDataItemConfig: function(xtype, record, itemConfig) {\r
78643 var dataview = this.dataview,\r
78644 dataItemConfig = {\r
78645 xtype: xtype,\r
78646 record: record,\r
78647 itemCls: dataview.getItemCls(),\r
78648 defaults: itemConfig,\r
78649 dataview: dataview\r
78650 };\r
78651 return Ext.merge(dataItemConfig, itemConfig);\r
78652 },\r
78653 doRemoveItemCls: function(cls) {\r
78654 var items = this.getViewItems(),\r
78655 ln = items.length,\r
78656 i = 0;\r
78657 for (; i < ln; i++) {\r
78658 items[i].removeCls(cls);\r
78659 }\r
78660 },\r
78661 doAddItemCls: function(cls) {\r
78662 var items = this.getViewItems(),\r
78663 ln = items.length,\r
78664 i = 0;\r
78665 for (; i < ln; i++) {\r
78666 items[i].addCls(cls);\r
78667 }\r
78668 },\r
78669 updateAtNewIndex: function(oldIndex, newIndex, record) {\r
78670 this.moveItemsToCache(oldIndex, oldIndex);\r
78671 this.moveItemsFromCache([\r
78672 record\r
78673 ]);\r
78674 },\r
78675 destroy: function() {\r
78676 var me = this,\r
78677 itemCache = me.itemCache,\r
78678 ln = itemCache.length,\r
78679 i = 0;\r
78680 for (; i < ln; i++) {\r
78681 itemCache[i].destroy();\r
78682 }\r
78683 this.callParent();\r
78684 }\r
78685});\r
78686\r
78687\r
78688Ext.define('Ext.dataview.element.Container', {\r
78689 extend: Ext.Component,\r
78690 \r
78691 \r
78692 \r
78693 \r
78694 \r
78695 \r
78696 \r
78697 \r
78698 doInitialize: function() {\r
78699 this.element.on({\r
78700 touchstart: 'onItemTouchStart',\r
78701 touchend: 'onItemTouchEnd',\r
78702 tap: 'onItemTap',\r
78703 taphold: 'onItemTapHold',\r
78704 touchmove: 'onItemTouchMove',\r
78705 singletap: 'onItemSingleTap',\r
78706 doubletap: 'onItemDoubleTap',\r
78707 swipe: 'onItemSwipe',\r
78708 delegate: '> div',\r
78709 scope: this\r
78710 });\r
78711 },\r
78712 \r
78713 initialize: function() {\r
78714 this.callParent();\r
78715 this.doInitialize();\r
78716 },\r
78717 updateBaseCls: function(newBaseCls, oldBaseCls) {\r
78718 var me = this;\r
78719 me.callParent([\r
78720 newBaseCls + '-container',\r
78721 oldBaseCls\r
78722 ]);\r
78723 },\r
78724 onItemTouchStart: function(e) {\r
78725 var me = this,\r
78726 target = e.currentTarget,\r
78727 index = me.getViewItems().indexOf(target);\r
78728 Ext.get(target).on({\r
78729 touchmove: 'onItemTouchMove',\r
78730 scope: me,\r
78731 single: true\r
78732 });\r
78733 me.fireEvent('itemtouchstart', me, Ext.get(target), index, e);\r
78734 },\r
78735 onItemTouchEnd: function(e) {\r
78736 var me = this,\r
78737 target = e.currentTarget,\r
78738 index = me.getViewItems().indexOf(target);\r
78739 Ext.get(target).un({\r
78740 touchmove: 'onItemTouchMove',\r
78741 scope: me\r
78742 });\r
78743 me.fireEvent('itemtouchend', me, Ext.get(target), index, e);\r
78744 },\r
78745 onItemTouchMove: function(e) {\r
78746 var me = this,\r
78747 target = e.currentTarget,\r
78748 index = me.getViewItems().indexOf(target);\r
78749 me.fireEvent('itemtouchmove', me, Ext.get(target), index, e);\r
78750 },\r
78751 onItemTap: function(e) {\r
78752 var me = this,\r
78753 target = e.currentTarget,\r
78754 index = me.getViewItems().indexOf(target);\r
78755 me.fireEvent('itemtap', me, Ext.get(target), index, e);\r
78756 },\r
78757 onItemTapHold: function(e) {\r
78758 var me = this,\r
78759 target = e.currentTarget,\r
78760 index = me.getViewItems().indexOf(target);\r
78761 me.fireEvent('itemtaphold', me, Ext.get(target), index, e);\r
78762 },\r
78763 onItemDoubleTap: function(e) {\r
78764 var me = this,\r
78765 target = e.currentTarget,\r
78766 index = me.getViewItems().indexOf(target);\r
78767 me.fireEvent('itemdoubletap', me, Ext.get(target), index, e);\r
78768 },\r
78769 onItemSingleTap: function(e) {\r
78770 var me = this,\r
78771 target = e.currentTarget,\r
78772 index = me.getViewItems().indexOf(target);\r
78773 me.fireEvent('itemsingletap', me, Ext.get(target), index, e);\r
78774 },\r
78775 onItemSwipe: function(e) {\r
78776 var me = this,\r
78777 target = e.currentTarget,\r
78778 index = me.getViewItems().indexOf(target);\r
78779 me.fireEvent('itemswipe', me, Ext.get(target), index, e);\r
78780 },\r
78781 updateListItem: function(record, item) {\r
78782 var me = this,\r
78783 dataview = me.dataview,\r
78784 store = dataview.getStore(),\r
78785 index = store.indexOf(record),\r
78786 data = dataview.prepareData(record.getData(true), index, record);\r
78787 item.innerHTML = this.renderItemTpl(index, data, store);\r
78788 },\r
78789 addListItem: function(index, record) {\r
78790 var me = this,\r
78791 dataview = me.dataview,\r
78792 store = dataview.getStore(),\r
78793 data = dataview.prepareData(record.getData(true), index, record),\r
78794 element = me.element,\r
78795 childNodes = element.dom.childNodes,\r
78796 ln = childNodes.length,\r
78797 wrapElement;\r
78798 wrapElement = Ext.Element.create(this.getItemElementConfig(index, data, store));\r
78799 if (!ln || index == ln) {\r
78800 wrapElement.appendTo(element);\r
78801 } else {\r
78802 wrapElement.insertBefore(childNodes[index]);\r
78803 }\r
78804 },\r
78805 getItemElementConfig: function(index, data, store) {\r
78806 var dataview = this.dataview,\r
78807 itemCls = dataview.getItemCls(),\r
78808 cls = dataview.getBaseCls() + '-item';\r
78809 if (itemCls) {\r
78810 cls += ' ' + itemCls;\r
78811 }\r
78812 return {\r
78813 cls: cls,\r
78814 html: this.renderItemTpl(index, data, store)\r
78815 };\r
78816 },\r
78817 renderItemTpl: function(index, data, store) {\r
78818 var dataview = this.dataview,\r
78819 itemTpl = dataview.getItemTpl(),\r
78820 parent;\r
78821 store = store || dataview.getStore();\r
78822 parent = store.getData().items;\r
78823 data.xcount = typeof data.xcount === 'number' ? data.xcount : store.getCount();\r
78824 data.xindex = typeof data.xindex === 'number' ? data.xindex : index;\r
78825 return itemTpl.apply(data, parent, index + 1, parent.length);\r
78826 },\r
78827 doRemoveItemCls: function(cls) {\r
78828 var elements = this.getViewItems(),\r
78829 ln = elements.length,\r
78830 i = 0;\r
78831 for (; i < ln; i++) {\r
78832 Ext.fly(elements[i]).removeCls(cls);\r
78833 }\r
78834 },\r
78835 doAddItemCls: function(cls) {\r
78836 var elements = this.getViewItems(),\r
78837 ln = elements.length,\r
78838 i = 0;\r
78839 for (; i < ln; i++) {\r
78840 Ext.fly(elements[i]).addCls(cls);\r
78841 }\r
78842 },\r
78843
78844 moveItemsToCache: function(from, to) {\r
78845 var me = this,\r
78846 items = me.getViewItems(),\r
78847 i = to - from,\r
78848 item;\r
78849 for (; i >= 0; i--) {\r
78850 item = items[from + i];\r
78851 Ext.get(item).destroy();\r
78852 }\r
78853 if (me.getViewItems().length == 0) {\r
78854 this.dataview.showEmptyText();\r
78855 }\r
78856 },\r
78857
78858 moveItemsFromCache: function(records) {\r
78859 var me = this,\r
78860 dataview = me.dataview,\r
78861 store = dataview.getStore(),\r
78862 ln = records.length,\r
78863 i, record;\r
78864 if (ln) {\r
78865 dataview.hideEmptyText();\r
78866 }\r
78867 for (i = 0; i < ln; i++) {\r
78868 records[i]._tmpIndex = store.indexOf(records[i]);\r
78869 }\r
78870 Ext.Array.sort(records, function(record1, record2) {\r
78871 return record1._tmpIndex > record2._tmpIndex ? 1 : -1;\r
78872 });\r
78873 for (i = 0; i < ln; i++) {\r
78874 record = records[i];\r
78875 me.addListItem(record._tmpIndex, record);\r
78876 delete record._tmpIndex;\r
78877 }\r
78878 },\r
78879
78880 getViewItems: function() {\r
78881 return Array.prototype.slice.call(this.element.dom.childNodes);\r
78882 },\r
78883 updateAtNewIndex: function(oldIndex, newIndex, record) {\r
78884 this.moveItemsToCache(oldIndex, oldIndex);\r
78885 this.moveItemsFromCache([\r
78886 record\r
78887 ]);\r
78888 },\r
78889 destroy: function() {\r
78890 var elements = this.getViewItems(),\r
78891 ln = elements.length,\r
78892 i = 0;\r
78893 for (; i < ln; i++) {\r
78894 Ext.get(elements[i]).destroy();\r
78895 }\r
78896 this.callParent();\r
78897 }\r
78898});\r
78899\r
78900\r
78901Ext.define('Ext.dataview.DataView', {\r
78902 extend: Ext.Container,\r
78903 alternateClassName: 'Ext.DataView',\r
78904 mixins: [\r
78905 Ext.mixin.Selectable\r
78906 ],\r
78907 xtype: 'dataview',\r
78908 \r
78909 \r
78910 \r
78911 \r
78912 \r
78913 \r
78914 \r
78915 \r
78916 \r
78917 \r
78918 \r
78919 \r
78920 \r
78921 \r
78922 \r
78923 config: {\r
78924 \r
78925 \r
78926 store: null,\r
78927 \r
78928 data: null,\r
78929 \r
78930 baseCls: Ext.baseCSSPrefix + 'dataview',\r
78931 \r
78932 emptyText: null,\r
78933 \r
78934 deferEmptyText: true,\r
78935 \r
78936 itemTpl: '<div>{text}</div>',\r
78937 \r
78938 pressedCls: 'x-item-pressed',\r
78939 \r
78940 itemCls: null,\r
78941 \r
78942 selectedCls: 'x-item-selected',\r
78943 \r
78944 triggerEvent: 'itemtap',\r
78945 \r
78946 triggerCtEvent: 'tap',\r
78947 \r
78948 deselectOnContainerClick: true,\r
78949 \r
78950 scrollable: true,\r
78951 \r
78952 inline: null,\r
78953 \r
78954 pressedDelay: 100,\r
78955 \r
78956 loadingText: 'Loading...',\r
78957 \r
78958 useComponents: null,\r
78959 \r
78960 itemConfig: {},\r
78961 \r
78962 maxItemCache: 20,\r
78963 \r
78964 defaultType: 'dataitem',\r
78965 \r
78966 scrollToTopOnRefresh: true\r
78967 },\r
78968 defaultBindProperty: 'store',\r
78969 constructor: function(config) {\r
78970 var me = this;\r
78971 me.hasLoadedStore = false;\r
78972 me.mixins.selectable.constructor.apply(me, arguments);\r
78973 me.indexOffset = 0;\r
78974 me.callParent(arguments);\r
78975
78976 var layout = this.getLayout();\r
78977 if (layout && !layout.isAuto) {\r
78978 Ext.Logger.error('The base layout for a DataView must always be an Auto Layout');\r
78979 }\r
78980
78981 me.initSelectable();\r
78982 },\r
78983 updateItemCls: function(newCls, oldCls) {\r
78984 var container = this.container;\r
78985 if (container) {\r
78986 if (oldCls) {\r
78987 container.doRemoveItemCls(oldCls);\r
78988 }\r
78989 if (newCls) {\r
78990 container.doAddItemCls(newCls);\r
78991 }\r
78992 }\r
78993 },\r
78994 storeEventHooks: {\r
78995 beforeload: 'onBeforeLoad',\r
78996 groupchange: 'onStoreGroupChange',\r
78997 load: 'onLoad',\r
78998 refresh: 'refresh',\r
78999 add: 'onStoreAdd',\r
79000 remove: 'onStoreRemove',\r
79001 clear: 'onStoreClear',\r
79002 update: 'onStoreUpdate'\r
79003 },\r
79004 initialize: function() {\r
79005 this.callParent();\r
79006 var me = this,\r
79007 container,\r
79008 triggerEvent = me.getTriggerEvent();\r
79009 me.on(me.getTriggerCtEvent(), me.onContainerTrigger, me);\r
79010 container = me.container = this.add(new Ext.dataview[me.getUseComponents() ? 'component' : 'element'].Container({\r
79011 baseCls: this.getBaseCls()\r
79012 }));\r
79013 container.dataview = me;\r
79014 if (triggerEvent) {\r
79015 me.on(triggerEvent, me.onItemTrigger, me);\r
79016 }\r
79017 container.on({\r
79018 itemtouchstart: 'onItemTouchStart',\r
79019 itemtouchend: 'onItemTouchEnd',\r
79020 itemtap: 'onItemTap',\r
79021 itemtaphold: 'onItemTapHold',\r
79022 itemtouchmove: 'onItemTouchMove',\r
79023 itemsingletap: 'onItemSingleTap',\r
79024 itemdoubletap: 'onItemDoubleTap',\r
79025 itemswipe: 'onItemSwipe',\r
79026 scope: me\r
79027 });\r
79028 if (me.getStore()) {\r
79029 if (me.isPainted()) {\r
79030 me.refresh();\r
79031 } else {\r
79032 me.on({\r
79033 painted: 'refresh',\r
79034 single: true\r
79035 });\r
79036 }\r
79037 }\r
79038 },\r
79039 applyInline: function(config) {\r
79040 if (Ext.isObject(config)) {\r
79041 config = Ext.apply({}, config);\r
79042 }\r
79043 return config;\r
79044 },\r
79045 updateInline: function(newInline, oldInline) {\r
79046 var me = this,\r
79047 baseCls = me.getBaseCls();\r
79048 if (oldInline) {\r
79049 me.removeCls([\r
79050 baseCls + '-inlineblock',\r
79051 baseCls + '-nowrap'\r
79052 ]);\r
79053 }\r
79054 if (newInline) {\r
79055 me.addCls(baseCls + '-inlineblock');\r
79056 if (Ext.isObject(newInline) && newInline.wrap === false) {\r
79057 me.addCls(baseCls + '-nowrap');\r
79058 } else {\r
79059 me.removeCls(baseCls + '-nowrap');\r
79060 }\r
79061 }\r
79062 },\r
79063 \r
79064 prepareData: function(data, index, record) {\r
79065 return data;\r
79066 },\r
79067
79068 onContainerTrigger: function(e) {\r
79069 var me = this;\r
79070 if (e.target != me.element.dom) {\r
79071 return;\r
79072 }\r
79073 if (me.getDeselectOnContainerClick() && me.getStore()) {\r
79074 me.deselectAll();\r
79075 }\r
79076 },\r
79077
79078 onItemTrigger: function(me, index) {\r
79079 if (!this.destroyed) {\r
79080 this.selectWithEvent(this.getStore().getAt(index));\r
79081 }\r
79082 },\r
79083 doAddPressedCls: function(record) {\r
79084 var me = this,\r
79085 item = me.getItemAt(me.getStore().indexOf(record));\r
79086 if (Ext.isElement(item)) {\r
79087 item = Ext.get(item);\r
79088 }\r
79089 if (item) {\r
79090 if (item.isComponent) {\r
79091 item.renderElement.addCls(me.getPressedCls());\r
79092 } else {\r
79093 item.addCls(me.getPressedCls());\r
79094 }\r
79095 }\r
79096 },\r
79097 onItemTouchStart: function(container, target, index, e) {\r
79098 var me = this,\r
79099 store = me.getStore(),\r
79100 record = store && store.getAt(index);\r
79101 me.fireAction('itemtouchstart', [\r
79102 me,\r
79103 index,\r
79104 target,\r
79105 record,\r
79106 e\r
79107 ], 'doItemTouchStart');\r
79108 },\r
79109 doItemTouchStart: function(me, index, target, record) {\r
79110 var pressedDelay = me.getPressedDelay();\r
79111 if (record) {\r
79112 if (pressedDelay > 0) {\r
79113 me.pressedTimeout = Ext.defer(me.doAddPressedCls, pressedDelay, me, [\r
79114 record\r
79115 ]);\r
79116 } else {\r
79117 me.doAddPressedCls(record);\r
79118 }\r
79119 }\r
79120 },\r
79121 onItemTouchEnd: function(container, target, index, e) {\r
79122 var me = this,\r
79123 store = me.getStore(),\r
79124 record = store && store.getAt(index);\r
79125 if (this.hasOwnProperty('pressedTimeout')) {\r
79126 clearTimeout(this.pressedTimeout);\r
79127 delete this.pressedTimeout;\r
79128 }\r
79129 if (record && target) {\r
79130 if (target.isComponent) {\r
79131 target.renderElement.removeCls(me.getPressedCls());\r
79132 } else {\r
79133 target.removeCls(me.getPressedCls());\r
79134 }\r
79135 }\r
79136 me.fireEvent('itemtouchend', me, index, target, record, e);\r
79137 },\r
79138 onItemTouchMove: function(container, target, index, e) {\r
79139 var me = this,\r
79140 store = me.getStore(),\r
79141 record = store && store.getAt(index);\r
79142 if (me.hasOwnProperty('pressedTimeout')) {\r
79143 clearTimeout(me.pressedTimeout);\r
79144 delete me.pressedTimeout;\r
79145 }\r
79146 if (record && target) {\r
79147 if (target.isComponent) {\r
79148 target.renderElement.removeCls(me.getPressedCls());\r
79149 } else {\r
79150 target.removeCls(me.getPressedCls());\r
79151 }\r
79152 }\r
79153 me.fireEvent('itemtouchmove', me, index, target, record, e);\r
79154 },\r
79155 onItemTap: function(container, target, index, e) {\r
79156 var me = this,\r
79157 store = me.getStore(),\r
79158 record = store && store.getAt(index);\r
79159 me.fireEvent('itemtap', me, index, target, record, e);\r
79160 },\r
79161 onItemTapHold: function(container, target, index, e) {\r
79162 var me = this,\r
79163 store = me.getStore(),\r
79164 record = store && store.getAt(index);\r
79165 me.fireEvent('itemtaphold', me, index, target, record, e);\r
79166 },\r
79167 onItemSingleTap: function(container, target, index, e) {\r
79168 var me = this,\r
79169 store = me.getStore(),\r
79170 record = store && store.getAt(index);\r
79171 me.fireEvent('itemsingletap', me, index, target, record, e);\r
79172 },\r
79173 onItemDoubleTap: function(container, target, index, e) {\r
79174 var me = this,\r
79175 store = me.getStore(),\r
79176 record = store && store.getAt(index);\r
79177 me.fireEvent('itemdoubletap', me, index, target, record, e);\r
79178 },\r
79179 onItemSwipe: function(container, target, index, e) {\r
79180 var me = this,\r
79181 store = me.getStore(),\r
79182 record = store && store.getAt(index);\r
79183 me.fireEvent('itemswipe', me, index, target, record, e);\r
79184 },\r
79185
79186 onItemSelect: function(record, suppressEvent) {\r
79187 var me = this;\r
79188 if (suppressEvent) {\r
79189 me.doItemSelect(me, record);\r
79190 } else {\r
79191 me.fireAction('select', [\r
79192 me,\r
79193 record\r
79194 ], 'doItemSelect');\r
79195 }\r
79196 },\r
79197
79198 doItemSelect: function(me, record) {\r
79199 if (me.container && !me.destroyed) {\r
79200 var item = me.getItemAt(me.getStore().indexOf(record));\r
79201 if (Ext.isElement(item)) {\r
79202 item = Ext.get(item);\r
79203 }\r
79204 if (item) {\r
79205 if (item.isComponent) {\r
79206 item.renderElement.removeCls(me.getPressedCls());\r
79207 item.renderElement.addCls(me.getSelectedCls());\r
79208 } else {\r
79209 item.removeCls(me.getPressedCls());\r
79210 item.addCls(me.getSelectedCls());\r
79211 }\r
79212 }\r
79213 }\r
79214 },\r
79215
79216 onItemDeselect: function(record, suppressEvent) {\r
79217 var me = this;\r
79218 if (me.container && !me.destroyed) {\r
79219 if (suppressEvent) {\r
79220 me.doItemDeselect(me, record);\r
79221 } else {\r
79222 me.fireAction('deselect', [\r
79223 me,\r
79224 record,\r
79225 suppressEvent\r
79226 ], 'doItemDeselect');\r
79227 }\r
79228 }\r
79229 },\r
79230 doItemDeselect: function(me, record) {\r
79231 var item = me.getItemAt(me.getStore().indexOf(record));\r
79232 if (Ext.isElement(item)) {\r
79233 item = Ext.get(item);\r
79234 }\r
79235 if (item) {\r
79236 if (item.isComponent) {\r
79237 item.renderElement.removeCls([\r
79238 me.getPressedCls(),\r
79239 me.getSelectedCls()\r
79240 ]);\r
79241 } else {\r
79242 item.removeCls([\r
79243 me.getPressedCls(),\r
79244 me.getSelectedCls()\r
79245 ]);\r
79246 }\r
79247 }\r
79248 },\r
79249 updateData: function(data) {\r
79250 var store = this.getStore();\r
79251 if (!store) {\r
79252 this.setStore(Ext.create('Ext.data.Store', {\r
79253 data: data,\r
79254 autoDestroy: true\r
79255 }));\r
79256 } else {\r
79257 store.add(data);\r
79258 }\r
79259 },\r
79260 applyStore: function(store) {\r
79261 var me = this,\r
79262 bindEvents = Ext.apply({}, me.storeEventHooks, {\r
79263 scope: me\r
79264 }),\r
79265 proxy, reader;\r
79266 if (store) {\r
79267 store = Ext.data.StoreManager.lookup(store);\r
79268 if (store && Ext.isObject(store) && store.isStore) {\r
79269 store.on(bindEvents);\r
79270 proxy = store.getProxy();\r
79271 if (proxy) {\r
79272 reader = proxy.getReader();\r
79273 if (reader) {\r
79274 reader.on('exception', 'handleException', this);\r
79275 }\r
79276 }\r
79277 } else
79278 {\r
79279 Ext.Logger.warn("The specified Store cannot be found", this);\r
79280 }\r
79281 }\r
79282
79283 return store;\r
79284 },\r
79285 \r
79286 handleException: function() {\r
79287 this.setMasked(false);\r
79288 },\r
79289 updateStore: function(newStore, oldStore) {\r
79290 var me = this,\r
79291 bindEvents = Ext.apply({}, me.storeEventHooks, {\r
79292 scope: me\r
79293 }),\r
79294 proxy, reader;\r
79295 if (oldStore && Ext.isObject(oldStore) && oldStore.isStore) {\r
79296 oldStore.un(bindEvents);\r
79297 if (!me.destroyed) {\r
79298 me.onStoreClear();\r
79299 }\r
79300 if (oldStore.getAutoDestroy()) {\r
79301 oldStore.destroy();\r
79302 } else {\r
79303 proxy = oldStore.getProxy();\r
79304 if (proxy) {\r
79305 reader = proxy.getReader();\r
79306 if (reader) {\r
79307 reader.un('exception', 'handleException', this);\r
79308 }\r
79309 }\r
79310 }\r
79311 }\r
79312 if (newStore) {\r
79313 if (newStore.isLoaded()) {\r
79314 this.hasLoadedStore = true;\r
79315 }\r
79316 if (newStore.isLoading()) {\r
79317 me.onBeforeLoad();\r
79318 }\r
79319 if (me.container) {\r
79320 me.refresh();\r
79321 }\r
79322 }\r
79323 },\r
79324 onBeforeLoad: function() {\r
79325 var me = this,\r
79326 loadingText = me.getLoadingText();\r
79327 if (loadingText && me.isPainted()) {\r
79328 me.setMasked({\r
79329 xtype: 'loadmask',\r
79330 message: loadingText\r
79331 });\r
79332 }\r
79333 me.hideEmptyText();\r
79334 },\r
79335 updateEmptyText: function(newEmptyText, oldEmptyText) {\r
79336 var me = this,\r
79337 store;\r
79338 if (oldEmptyText && me.emptyTextCmp) {\r
79339 me.remove(me.emptyTextCmp, true);\r
79340 delete me.emptyTextCmp;\r
79341 }\r
79342 if (newEmptyText) {\r
79343 me.emptyTextCmp = me.add({\r
79344 xtype: 'component',\r
79345 cls: me.getBaseCls() + '-emptytext',\r
79346 html: newEmptyText,\r
79347 hidden: true\r
79348 });\r
79349 store = me.getStore();\r
79350 if (store && me.hasLoadedStore && !store.getCount()) {\r
79351 me.showEmptyText();\r
79352 }\r
79353 }\r
79354 },\r
79355 onLoad: function(store) {\r
79356
79357 this.hasLoadedStore = true;\r
79358 this.setMasked(false);\r
79359 if (!store.getCount()) {\r
79360 this.showEmptyText();\r
79361 }\r
79362 },\r
79363 \r
79364 refresh: function() {\r
79365 var me = this,\r
79366 container = me.container;\r
79367 if (!me.getStore()) {\r
79368 if (!me.hasLoadedStore && !me.getDeferEmptyText()) {\r
79369 me.showEmptyText();\r
79370 }\r
79371 return;\r
79372 }\r
79373 if (me.initialized && container) {\r
79374 me.fireAction('refresh', [\r
79375 me\r
79376 ], 'doRefresh');\r
79377 }\r
79378 },\r
79379 applyItemTpl: function(config) {\r
79380 return (Ext.isObject(config) && config.isTemplate) ? config : new Ext.XTemplate(config);\r
79381 },\r
79382 onAfterRender: function() {\r
79383 var me = this;\r
79384 me.updateStore(me.getStore());\r
79385 },\r
79386 \r
79387 getItemAt: function(index) {\r
79388 return this.getViewItems()[index - this.indexOffset];\r
79389 },\r
79390 \r
79391 getItemIndex: function(item) {\r
79392 var index = this.getViewItems().indexOf(item);\r
79393 return (index === -1) ? index : this.indexOffset + index;\r
79394 },\r
79395 \r
79396 getViewItems: function() {\r
79397 return this.container.getViewItems();\r
79398 },\r
79399 doRefresh: function(me) {\r
79400 var container = me.container,\r
79401 store = me.getStore(),\r
79402 records = store.getRange(),\r
79403 items = me.getViewItems(),\r
79404 recordsLn = records.length,\r
79405 itemsLn = items.length,\r
79406 deltaLn = recordsLn - itemsLn,\r
79407 scroller = me.getScrollable(),\r
79408 i, item;\r
79409 if (this.getScrollToTopOnRefresh() && scroller) {\r
79410 scroller.scrollTo(0, 0);\r
79411 }\r
79412
79413 if (recordsLn < 1) {\r
79414 me.onStoreClear();\r
79415 return;\r
79416 } else {\r
79417 me.hideEmptyText();\r
79418 }\r
79419
79420 if (deltaLn < 0) {\r
79421 container.moveItemsToCache(itemsLn + deltaLn, itemsLn - 1);\r
79422
79423 items = me.getViewItems();\r
79424 itemsLn = items.length;\r
79425 }\r
79426
79427 else if (deltaLn > 0) {\r
79428 container.moveItemsFromCache(store.getRange(itemsLn));\r
79429 }\r
79430
79431 for (i = 0; i < itemsLn; i++) {\r
79432 item = items[i];\r
79433 container.updateListItem(records[i], item);\r
79434 }\r
79435 if (this.hasSelection()) {\r
79436 var selection = this.getSelection(),\r
79437 selectionLn = this.getSelectionCount(),\r
79438 record;\r
79439 for (i = 0; i < selectionLn; i++) {\r
79440 record = selection[i];\r
79441 this.doItemSelect(this, record);\r
79442 }\r
79443 }\r
79444 },\r
79445 showEmptyText: function() {\r
79446 if (this.getEmptyText() && (this.hasLoadedStore || !this.getDeferEmptyText())) {\r
79447 this.emptyTextCmp.show();\r
79448 }\r
79449 },\r
79450 hideEmptyText: function() {\r
79451 if (this.getEmptyText()) {\r
79452 this.emptyTextCmp.hide();\r
79453 }\r
79454 },\r
79455 destroy: function() {\r
79456 var store = this.getStore(),\r
79457 proxy = (store && store.getProxy()),\r
79458 reader = (proxy && proxy.getReader());\r
79459 if (reader) {\r
79460
79461
79462 reader.clearListeners();\r
79463 }\r
79464 this.callParent();\r
79465 this.setStore(null);\r
79466 },\r
79467 onStoreClear: function() {\r
79468 var me = this,\r
79469 container = me.container,\r
79470 items = me.getViewItems();\r
79471 container.moveItemsToCache(0, items.length - 1);\r
79472 this.showEmptyText();\r
79473 },\r
79474 \r
79475 onStoreGroupChange: Ext.emptyFn,\r
79476 \r
79477 onStoreAdd: function(store, records) {\r
79478 if (records) {\r
79479 this.hideEmptyText();\r
79480 this.container.moveItemsFromCache(records);\r
79481 }\r
79482 },\r
79483 \r
79484 onStoreRemove: function(store, records, indices) {\r
79485 var container = this.container,\r
79486 ln = records.length,\r
79487 i;\r
79488 for (i = 0; i < ln; i++) {\r
79489 container.moveItemsToCache(indices[i], indices[i]);\r
79490 }\r
79491 },\r
79492 \r
79493 onStoreUpdate: function(store, record, type, modifiedFieldNames, info) {\r
79494 var me = this,\r
79495 container = me.container,\r
79496 item;\r
79497 if (info.indexChanged) {\r
79498 container.updateAtNewIndex(info.oldIndex, info.newIndex, record);\r
79499 if (me.isSelected(record)) {\r
79500 me.doItemSelect(me, record);\r
79501 }\r
79502 } else {\r
79503 item = me.getViewItems()[me.getStore().indexOf(record)];\r
79504 if (item) {\r
79505
79506 container.updateListItem(record, item);\r
79507 }\r
79508 }\r
79509 }\r
79510});\r
79511\r
79512\r
79513Ext.define('Ext.dataview.IndexBar', {\r
79514 extend: Ext.Component,\r
79515 alternateClassName: 'Ext.IndexBar',\r
79516 \r
79517 config: {\r
79518 baseCls: Ext.baseCSSPrefix + 'indexbar',\r
79519 \r
79520 direction: 'vertical',\r
79521 \r
79522 letters: [\r
79523 'A',\r
79524 'B',\r
79525 'C',\r
79526 'D',\r
79527 'E',\r
79528 'F',\r
79529 'G',\r
79530 'H',\r
79531 'I',\r
79532 'J',\r
79533 'K',\r
79534 'L',\r
79535 'M',\r
79536 'N',\r
79537 'O',\r
79538 'P',\r
79539 'Q',\r
79540 'R',\r
79541 'S',\r
79542 'T',\r
79543 'U',\r
79544 'V',\r
79545 'W',\r
79546 'X',\r
79547 'Y',\r
79548 'Z'\r
79549 ],\r
79550 ui: 'alphabet',\r
79551 \r
79552 listPrefix: null\r
79553 },\r
79554 \r
79555 itemCls: Ext.baseCSSPrefix + '',\r
79556 updateDirection: function(newDirection, oldDirection) {\r
79557 var baseCls = this.getBaseCls();\r
79558 this.element.replaceCls(baseCls + '-' + oldDirection, baseCls + '-' + newDirection);\r
79559 },\r
79560 getElementConfig: function() {\r
79561
79562 if (Ext.theme.is.Blackberry) {\r
79563 return {\r
79564 reference: 'wrapper',\r
79565 classList: [\r
79566 'x-centered',\r
79567 'x-indexbar-wrapper'\r
79568 ],\r
79569 children: [\r
79570 {\r
79571 reference: 'indicator',\r
79572 classList: [\r
79573 'x-indexbar-indicator'\r
79574 ],\r
79575 hidden: true,\r
79576 children: [\r
79577 {\r
79578 reference: 'indicatorInner',\r
79579 classList: [\r
79580 'x-indexbar-indicator-inner'\r
79581 ]\r
79582 }\r
79583 ]\r
79584 },\r
79585 this.callParent()\r
79586 ]\r
79587 };\r
79588 } else {\r
79589 return {\r
79590 reference: 'wrapper',\r
79591 classList: [\r
79592 'x-centered',\r
79593 'x-indexbar-wrapper'\r
79594 ],\r
79595 children: [\r
79596 this.callParent()\r
79597 ]\r
79598 };\r
79599 }\r
79600 },\r
79601 updateLetters: function(letters) {\r
79602 this.innerElement.setHtml('');\r
79603 if (letters) {\r
79604 var ln = letters.length,\r
79605 i;\r
79606 for (i = 0; i < ln; i++) {\r
79607 this.innerElement.createChild({\r
79608 html: letters[i]\r
79609 });\r
79610 }\r
79611 }\r
79612 },\r
79613 updateListPrefix: function(listPrefix) {\r
79614 if (listPrefix && listPrefix.length) {\r
79615 this.innerElement.createChild({\r
79616 html: listPrefix\r
79617 }, 0);\r
79618 }\r
79619 },\r
79620 \r
79621 initialize: function() {\r
79622 this.callParent();\r
79623 this.innerElement.on({\r
79624 touchstart: this.onTouchStart,\r
79625 touchend: this.onTouchEnd,\r
79626 dragend: this.onDragEnd,\r
79627 drag: this.onDrag,\r
79628 scope: this\r
79629 });\r
79630 },\r
79631 onTouchStart: function(e) {\r
79632 e.stopPropagation();\r
79633 this.innerElement.addCls(this.getBaseCls() + '-pressed');\r
79634 this.pageBox = this.innerElement.getBox();\r
79635 this.onDrag(e);\r
79636 },\r
79637 onTouchEnd: function(e) {\r
79638 this.onDragEnd();\r
79639 },\r
79640 \r
79641 onDragEnd: function() {\r
79642 this.innerElement.removeCls(this.getBaseCls() + '-pressed');\r
79643
79644 if (this.indicator) {\r
79645 this.indicator.hide();\r
79646 }\r
79647 },\r
79648 \r
79649 onDrag: function(e) {\r
79650 var point = Ext.util.Point.fromEvent(e),\r
79651 target, isValidTarget,\r
79652 pageBox = this.pageBox;\r
79653 if (!pageBox) {\r
79654 pageBox = this.pageBox = this.el.getBox();\r
79655 }\r
79656 if (this.getDirection() === 'vertical') {\r
79657 if (point.y > pageBox.bottom || point.y < pageBox.top) {\r
79658 return;\r
79659 }\r
79660 target = Ext.Element.fromPoint(pageBox.left + (pageBox.width / 2), point.y);\r
79661 isValidTarget = target.getParent() == this.element;\r
79662
79663 if (this.indicator) {\r
79664 this.indicator.show();\r
79665 var halfIndicatorHeight = this.indicator.getHeight() / 2,\r
79666 y = point.y - this.element.getY();\r
79667 y = Math.min(Math.max(y, halfIndicatorHeight), this.element.getHeight() - halfIndicatorHeight);\r
79668 if (this.indicatorInner && isValidTarget) {\r
79669 this.indicatorInner.setHtml(target.getHtml().toUpperCase());\r
79670 }\r
79671 this.indicator.setTop(y - (halfIndicatorHeight));\r
79672 }\r
79673 } else {\r
79674 if (point.x > pageBox.right || point.x < pageBox.left) {\r
79675 return;\r
79676 }\r
79677 target = Ext.Element.fromPoint(point.x, pageBox.top + (pageBox.height / 2));\r
79678 isValidTarget = target.getParent() == this.element;\r
79679 }\r
79680 if (target && isValidTarget) {\r
79681 this.fireEvent('index', this, target.dom.innerHTML, target);\r
79682 }\r
79683 },\r
79684 destroy: function() {\r
79685 var me = this,\r
79686 elements = Array.prototype.slice.call(me.innerElement.dom.childNodes),\r
79687 ln = elements.length,\r
79688 i = 0;\r
79689 for (; i < ln; i++) {\r
79690 Ext.removeNode(elements[i]);\r
79691 }\r
79692 this.callParent();\r
79693 }\r
79694});\r
79695\r
79696\r
79697Ext.define('Ext.dataview.ListItemHeader', {\r
79698 extend: Ext.Component,\r
79699 xtype: 'listitemheader',\r
79700 config: {\r
79701 \r
79702 baseCls: Ext.baseCSSPrefix + 'list-header'\r
79703 }\r
79704});\r
79705\r
79706\r
79707Ext.define('Ext.dataview.component.ListItem', {\r
79708 extend: Ext.dataview.component.DataItem,\r
79709 xtype: 'listitem',\r
79710 config: {\r
79711 baseCls: Ext.baseCSSPrefix + 'list-item',\r
79712 dataMap: null,\r
79713 body: {\r
79714 xtype: 'component',\r
79715 cls: 'x-list-item-body'\r
79716 },\r
79717 disclosure: {\r
79718 xtype: 'component',\r
79719 cls: 'x-list-disclosure',\r
79720 hidden: true,\r
79721 docked: 'right'\r
79722 },\r
79723 header: {\r
79724 xtype: 'component',\r
79725 cls: 'x-list-header',\r
79726 html: ' '\r
79727 },\r
79728 tpl: null,\r
79729 items: null\r
79730 },\r
79731 applyBody: function(body) {\r
79732 if (body && !body.isComponent) {\r
79733 body = Ext.factory(body, Ext.Component, this.getBody());\r
79734 }\r
79735 return body;\r
79736 },\r
79737 updateBody: function(body, oldBody) {\r
79738 if (body) {\r
79739 this.add(body);\r
79740 } else if (oldBody) {\r
79741 oldBody.destroy();\r
79742 }\r
79743 },\r
79744 applyHeader: function(header) {\r
79745 if (header && !header.isComponent) {\r
79746 header = Ext.factory(header, Ext.Component, this.getHeader());\r
79747 }\r
79748 return header;\r
79749 },\r
79750 updateHeader: function(header, oldHeader) {\r
79751 if (oldHeader) {\r
79752 oldHeader.destroy();\r
79753 }\r
79754 },\r
79755 applyDisclosure: function(disclosure) {\r
79756 if (disclosure && !disclosure.isComponent) {\r
79757 disclosure = Ext.factory(disclosure, Ext.Component, this.getDisclosure());\r
79758 }\r
79759 return disclosure;\r
79760 },\r
79761 updateDisclosure: function(disclosure, oldDisclosure) {\r
79762 if (disclosure) {\r
79763 this.add(disclosure);\r
79764 } else if (oldDisclosure) {\r
79765 oldDisclosure.destroy();\r
79766 }\r
79767 },\r
79768 updateTpl: function(tpl) {\r
79769 this.getBody().setTpl(tpl);\r
79770 },\r
79771 updateRecord: function(record) {\r
79772 var me = this,\r
79773 dataview = me.dataview || this.getDataview(),\r
79774 data = record && dataview.prepareData(record.getData(true), dataview.getStore().indexOf(record), record),\r
79775 dataMap = me.getDataMap(),\r
79776 body = this.getBody(),\r
79777 disclosure = this.getDisclosure();\r
79778 me._record = record;\r
79779 if (dataMap) {\r
79780 me.doMapData(dataMap, data, body);\r
79781 } else if (body) {\r
79782 body.updateData(data || null);\r
79783 }\r
79784 if (disclosure && record && dataview.getOnItemDisclosure()) {\r
79785 var disclosureProperty = dataview.getDisclosureProperty();\r
79786 disclosure[(data.hasOwnProperty(disclosureProperty) && data[disclosureProperty] === false) ? 'hide' : 'show']();\r
79787 }\r
79788 \r
79789 me.fireEvent('updatedata', me, data);\r
79790 },\r
79791 destroy: function() {\r
79792 Ext.destroy(this.getHeader());\r
79793 this.callParent();\r
79794 }\r
79795});\r
79796\r
79797\r
79798Ext.define('Ext.dataview.component.SimpleListItem', {\r
79799 extend: Ext.Component,\r
79800 xtype: 'simplelistitem',\r
79801 config: {\r
79802 baseCls: Ext.baseCSSPrefix + 'list-item',\r
79803 disclosure: {\r
79804 xtype: 'component',\r
79805 cls: 'x-list-disclosure',\r
79806 hidden: true\r
79807 },\r
79808 header: {\r
79809 xtype: 'component',\r
79810 cls: 'x-list-header',\r
79811 html: ' '\r
79812 },\r
79813 \r
79814 dataview: null,\r
79815 \r
79816 record: null\r
79817 },\r
79818 initialize: function() {\r
79819 this.element.addCls(this.getBaseCls() + '-tpl');\r
79820 },\r
79821 applyHeader: function(header) {\r
79822 if (header && !header.isComponent) {\r
79823 header = Ext.factory(header, Ext.Component, this.getHeader());\r
79824 }\r
79825 return header;\r
79826 },\r
79827 updateHeader: function(header, oldHeader) {\r
79828 if (oldHeader) {\r
79829 oldHeader.destroy();\r
79830 }\r
79831 },\r
79832 applyDisclosure: function(disclosure) {\r
79833 if (disclosure && !disclosure.isComponent) {\r
79834 disclosure = Ext.factory(disclosure, Ext.Component, this.getDisclosure());\r
79835 }\r
79836 return disclosure;\r
79837 },\r
79838 updateDisclosure: function(disclosure, oldDisclosure) {\r
79839 if (disclosure) {\r
79840 this.element.appendChild(disclosure.renderElement);\r
79841 } else if (oldDisclosure) {\r
79842 oldDisclosure.destroy();\r
79843 }\r
79844 },\r
79845 updateRecord: function(record) {\r
79846 var me = this,\r
79847 dataview = me.dataview || this.getDataview(),\r
79848 data = record && dataview.prepareData(record.getData(true), dataview.getStore().indexOf(record), record),\r
79849 disclosure = this.getDisclosure();\r
79850 me.updateData(data || null);\r
79851 if (disclosure && record && dataview.getOnItemDisclosure()) {\r
79852 var disclosureProperty = dataview.getDisclosureProperty();\r
79853 disclosure[(data.hasOwnProperty(disclosureProperty) && data[disclosureProperty] === false) ? 'hide' : 'show']();\r
79854 }\r
79855 },\r
79856 destroy: function() {\r
79857 Ext.destroy(this.getHeader(), this.getDisclosure());\r
79858 this.callParent();\r
79859 }\r
79860});\r
79861\r
79862\r
79863Ext.define('Ext.util.PositionMap', {\r
79864 config: {\r
79865 minimumHeight: null\r
79866 },\r
79867 constructor: function(config) {\r
79868 var me = this;\r
79869 me.map = [];\r
79870 me.adjustments = {};\r
79871 me.offset = 0;\r
79872 me.initConfig(config);\r
79873 },\r
79874 populate: function(count, offset) {\r
79875 var me = this,\r
79876 map = me.map = me.map || [],\r
79877 minimumHeight = me.getMinimumHeight(),\r
79878 i, previousIndex, ln;\r
79879 me.adjustments = {\r
79880 indices: [],\r
79881 heights: {}\r
79882 };\r
79883 if (minimumHeight === null) {\r
79884 return;\r
79885 }\r
79886 offset = offset || 0;\r
79887
79888 count++;\r
79889 map.length = count;\r
79890 map[0] = 0;\r
79891 for (i = offset + 1 , ln = count - 1; i <= ln; i++) {\r
79892 previousIndex = i - 1;\r
79893 map[i] = map[previousIndex] + minimumHeight;\r
79894 }\r
79895 me.offset = 0;\r
79896 for (i = 1 , ln = count - 1; i <= ln; i++) {\r
79897 previousIndex = i - 1;\r
79898 this.offset += map[i] - map[previousIndex] - minimumHeight;\r
79899 }\r
79900 },\r
79901 setItemHeight: function(index, height) {\r
79902 height = Math.max(height, this.getMinimumHeight());\r
79903 if (height !== this.getItemHeight(index)) {\r
79904 var adjustments = this.adjustments;\r
79905 adjustments.indices.push(parseInt(index, 10));\r
79906 adjustments.heights[index] = height;\r
79907 }\r
79908 },\r
79909 update: function() {\r
79910 var adjustments = this.adjustments,\r
79911 indices = adjustments.indices,\r
79912 heights = adjustments.heights,\r
79913 map = this.map,\r
79914 ln = indices.length,\r
79915 minimumHeight = this.getMinimumHeight(),\r
79916 difference = 0,\r
79917 i, j, height, index, nextIndex, currentHeight;\r
79918 if (!adjustments.indices.length) {\r
79919 return false;\r
79920 }\r
79921 Ext.Array.sort(indices, function(a, b) {\r
79922 return a - b;\r
79923 });\r
79924 for (i = 0; i < ln; i++) {\r
79925 index = indices[i];\r
79926 nextIndex = indices[i + 1] || map.length - 1;\r
79927 currentHeight = (map[index + 1] !== undefined) ? (map[index + 1] - map[index] + difference) : minimumHeight;\r
79928 height = heights[index];\r
79929 difference += height - currentHeight;\r
79930 for (j = index + 1; j <= nextIndex; j++) {\r
79931 map[j] += difference;\r
79932 }\r
79933 }\r
79934 this.offset += difference;\r
79935 this.adjustments = {\r
79936 indices: [],\r
79937 heights: {}\r
79938 };\r
79939 return true;\r
79940 },\r
79941 getItemHeight: function(index) {\r
79942 return this.map[index + 1] - this.map[index];\r
79943 },\r
79944 getTotalHeight: function() {\r
79945 return ((this.map.length - 1) * this.getMinimumHeight()) + this.offset;\r
79946 },\r
79947 findIndex: function(pos) {\r
79948 return this.map.length ? this.binarySearch(this.map, pos) : 0;\r
79949 },\r
79950 binarySearch: function(sorted, value) {\r
79951 var start = 0,\r
79952 end = sorted.length;\r
79953 if (value < sorted[0]) {\r
79954 return 0;\r
79955 }\r
79956 if (value > sorted[end - 1]) {\r
79957 return end - 1;\r
79958 }\r
79959 while (start + 1 < end) {\r
79960 var mid = (start + end) >> 1,\r
79961 val = sorted[mid];\r
79962 if (val == value) {\r
79963 return mid;\r
79964 } else if (val < value) {\r
79965 start = mid;\r
79966 } else {\r
79967 end = mid;\r
79968 }\r
79969 }\r
79970 return start;\r
79971 }\r
79972});\r
79973\r
79974\r
79975Ext.define('Ext.dataview.List', {\r
79976 alternateClassName: 'Ext.List',\r
79977 extend: Ext.dataview.DataView,\r
79978 xtype: 'list',\r
79979 mixins: [\r
79980 Ext.mixin.Hookable\r
79981 ],\r
79982 \r
79983 config: {\r
79984 \r
79985 container: {\r
79986 lazy: true,\r
79987 $value: {\r
79988 xtype: 'container',\r
79989 scrollable: {}\r
79990 }\r
79991 },\r
79992 \r
79993 layout: 'fit',\r
79994 \r
79995 indexBar: false,\r
79996 icon: null,\r
79997 \r
79998 preventSelectionOnDisclose: true,\r
79999 \r
80000 baseCls: Ext.baseCSSPrefix + 'list',\r
80001 \r
80002 pinHeaders: true,\r
80003 \r
80004 grouped: null,\r
80005 \r
80006 onItemDisclosure: null,\r
80007 \r
80008 disclosureProperty: 'disclosure',\r
80009 \r
80010 \r
80011 \r
80012 \r
80013 defaultType: undefined,\r
80014 \r
80015 itemMap: {},\r
80016 \r
80017 itemHeight: null,\r
80018 \r
80019 variableHeights: false,\r
80020 \r
80021 refreshHeightOnUpdate: true,\r
80022 \r
80023 infinite: false,\r
80024 \r
80025 useSimpleItems: true,\r
80026 \r
80027 scrollable: null,\r
80028 \r
80029 bufferSize: 20,\r
80030 minimumBufferDistance: 5,\r
80031 \r
80032 striped: false\r
80033 },\r
80034 topRenderedIndex: 0,\r
80035 topVisibleIndex: 0,\r
80036 visibleCount: 0,\r
80037
80038 constructor: function(config) {\r
80039 this.callParent([\r
80040 config\r
80041 ]);\r
80042 var layout = this.getLayout();\r
80043 if (layout && !layout.isFit) {\r
80044 Ext.Logger.error('The base layout for a DataView must always be a Fit Layout');\r
80045 }\r
80046 },\r
80047
80048
80049 beforeInitialize: function() {\r
80050 var me = this,\r
80051 container = me.container,\r
80052 baseCls = me.getBaseCls(),\r
80053 scrollViewElement, pinnedHeader;\r
80054 Ext.apply(me, {\r
80055 listItems: [],\r
80056 headerItems: [],\r
80057 updatedItems: [],\r
80058 headerMap: [],\r
80059 recordMap: {},\r
80060 scrollDockItems: {\r
80061 top: [],\r
80062 bottom: []\r
80063 }\r
80064 });\r
80065 me.translationMethod = 'csstransform';\r
80066
80067 if (!container) {\r
80068 container = me.container = me.createContainer();\r
80069 }\r
80070
80071
80072
80073 me.add(container);\r
80074
80075 scrollViewElement = me.scrollViewElement = container.bodyElement;\r
80076 me.scrollElement = container.innerElement;\r
80077
80078
80079 pinnedHeader = me.pinnedHeader = Ext.factory({\r
80080 xtype: 'listitemheader',\r
80081 html: '&nbsp;',\r
80082 translatable: {\r
80083 translationMethod: me.translationMethod\r
80084 },\r
80085 cls: [\r
80086 baseCls + '-header',\r
80087 baseCls + '-header-swap'\r
80088 ]\r
80089 });\r
80090 pinnedHeader.translate(0, -10000);\r
80091 pinnedHeader.$position = -10000;\r
80092 scrollViewElement.insertFirst(pinnedHeader.renderElement);\r
80093 container.getScrollable().on({\r
80094 scroll: 'onScroll',\r
80095 refresh: 'onScrollerRefresh',\r
80096 scope: me\r
80097 });\r
80098 },\r
80099 \r
80100 createContainer: function() {\r
80101 var config = Ext.merge({\r
80102 scrollable: {\r
80103 autoRefresh: this.getInfinite() ? null : true\r
80104 }\r
80105 }, this.getContainer());\r
80106 return Ext.create(config);\r
80107 },\r
80108 getScrollable: function() {\r
80109 return this.container.getScrollable();\r
80110 },\r
80111
80112 initialize: function() {\r
80113 var me = this,\r
80114 container = me.container,\r
80115 scrollViewElement = me.scrollViewElement,\r
80116 indexBar = me.getIndexBar(),\r
80117 triggerEvent = me.getTriggerEvent(),\r
80118 triggerCtEvent = me.getTriggerCtEvent();\r
80119 if (indexBar) {\r
80120 scrollViewElement.appendChild(indexBar.renderElement);\r
80121 }\r
80122 if (triggerEvent) {\r
80123 me.on(triggerEvent, me.onItemTrigger, me);\r
80124 }\r
80125 if (triggerCtEvent) {\r
80126 me.on(triggerCtEvent, me.onContainerTrigger, me);\r
80127 }\r
80128 container.element.on({\r
80129 delegate: '.' + me.getBaseCls() + '-disclosure',\r
80130 tap: 'handleItemDisclosure',\r
80131 scope: me\r
80132 });\r
80133 container.element.on({\r
80134 resize: 'onContainerResize',\r
80135 scope: me\r
80136 });\r
80137
80138 container.innerElement.on({\r
80139 touchstart: 'onItemTouchStart',\r
80140 touchend: 'onItemTouchEnd',\r
80141 tap: 'onItemTap',\r
80142 taphold: 'onItemTapHold',\r
80143 singletap: 'onItemSingleTap',\r
80144 doubletap: 'onItemDoubleTap',\r
80145 swipe: 'onItemSwipe',\r
80146 delegate: '.' + Ext.baseCSSPrefix + 'list-item',\r
80147 scope: me\r
80148 });\r
80149 if (me.getStore()) {\r
80150 if (me.isPainted()) {\r
80151 me.refresh();\r
80152 } else {\r
80153 me.on({\r
80154 painted: 'refresh',\r
80155 single: true\r
80156 });\r
80157 }\r
80158 }\r
80159 },\r
80160 getRefItems: function(deep) {\r
80161 var result = [],\r
80162 candidates = this.callParent([\r
80163 deep\r
80164 ]),\r
80165 len = candidates.length,\r
80166 i, candidate;\r
80167
80168
80169 for (i = 0; i < len; i++) {\r
80170 candidate = candidates[i];\r
80171 if (!candidate.hasOwnProperty('$position') || candidate.$position > -1) {\r
80172 result[result.length] = candidate;\r
80173 }\r
80174 }\r
80175 return result;\r
80176 },\r
80177 onScroll: function(scroller, x, y) {\r
80178 var me = this,\r
80179 pinnedHeader = me.pinnedHeader,\r
80180 store = me.getStore(),\r
80181 storeCount = store && store.getCount(),\r
80182 grouped = me.isGrouping(),\r
80183 infinite = me.getInfinite();\r
80184
80185
80186
80187
80188 if (x) {\r
80189 x = -x;\r
80190 }\r
80191 if (y) {\r
80192 y = -y;\r
80193 }\r
80194 if (!storeCount) {\r
80195 me.showEmptyText();\r
80196 me.showEmptyScrollDock();\r
80197 pinnedHeader.$position = -10000;\r
80198 pinnedHeader.translate(0, -10000);\r
80199 } else if (infinite && me.itemsCount) {\r
80200 me.handleItemUpdates(y);\r
80201 me.handleItemHeights();\r
80202 me.handleItemTransforms();\r
80203 if (!me.onIdleBound) {\r
80204 Ext.AnimationQueue.onIdle(me.onAnimationIdle, me);\r
80205 me.onIdleBound = true;\r
80206 }\r
80207 }\r
80208 if (grouped && me.groups && me.groups.length && me.getPinHeaders()) {\r
80209 me.handlePinnedHeader(y);\r
80210 }\r
80211
80212 me.onScrollBinder(x, y);\r
80213 },\r
80214 onScrollerRefresh: function(scroller) {\r
80215 var position = scroller.getPosition();\r
80216 this.onScroll(scroller, position.x, position.y);\r
80217 },\r
80218 onScrollBinder: function() {},\r
80219 handleItemUpdates: function(y) {\r
80220 var me = this,\r
80221 listItems = me.listItems,\r
80222 itemsCount = listItems.length,\r
80223 info = me.getListItemInfo(),\r
80224 itemMap = me.getItemMap(),\r
80225 bufferSize = me.getBufferSize(),\r
80226 lastIndex = me.getStore().getCount() - 1,\r
80227 minimumBufferDistance = me.getMinimumBufferDistance(),\r
80228 currentTopVisibleIndex = me.topVisibleIndex,\r
80229 topRenderedIndex = me.topRenderedIndex,\r
80230 updateCount, i, item, topVisibleIndex, bufferDistance, itemIndex;\r
80231
80232 me.topVisibleIndex = topVisibleIndex = Math.max(0, itemMap.findIndex(-y) || 0);\r
80233 if (currentTopVisibleIndex !== topVisibleIndex) {\r
80234
80235 if (currentTopVisibleIndex > topVisibleIndex) {\r
80236 bufferDistance = topVisibleIndex - topRenderedIndex;\r
80237 if (bufferDistance < minimumBufferDistance) {\r
80238 updateCount = Math.min(itemsCount, minimumBufferDistance - bufferDistance);\r
80239 if (updateCount == itemsCount) {\r
80240 me.topRenderedIndex = topRenderedIndex = Math.max(0, topVisibleIndex - (bufferSize - minimumBufferDistance));\r
80241
80242 for (i = 0; i < updateCount; i++) {\r
80243 itemIndex = topRenderedIndex + i;\r
80244 item = listItems[i];\r
80245 me.updateListItem(item, itemIndex, info);\r
80246 }\r
80247 } else {\r
80248 for (i = 0; i < updateCount; i++) {\r
80249 itemIndex = topRenderedIndex - i - 1;\r
80250 if (itemIndex < 0) {\r
80251 break;\r
80252 }\r
80253 item = listItems.pop();\r
80254 listItems.unshift(item);\r
80255 me.updateListItem(item, itemIndex, info);\r
80256 me.topRenderedIndex--;\r
80257 }\r
80258 }\r
80259 }\r
80260 } else
80261 {\r
80262 bufferDistance = bufferSize - (topVisibleIndex - topRenderedIndex);\r
80263 if (bufferDistance < minimumBufferDistance) {\r
80264 updateCount = Math.min(itemsCount, minimumBufferDistance - bufferDistance);\r
80265 if (updateCount == itemsCount) {\r
80266 me.topRenderedIndex = topRenderedIndex = Math.min(lastIndex - itemsCount, topVisibleIndex - minimumBufferDistance);\r
80267
80268 for (i = 0; i < updateCount; i++) {\r
80269 itemIndex = topRenderedIndex + i;\r
80270 item = listItems[i];\r
80271 me.updateListItem(item, itemIndex, info);\r
80272 }\r
80273 } else {\r
80274 for (i = 0; i < updateCount; i++) {\r
80275 itemIndex = topRenderedIndex + itemsCount + i;\r
80276 if (itemIndex > lastIndex) {\r
80277 break;\r
80278 }\r
80279 item = listItems.shift();\r
80280 listItems.push(item);\r
80281 me.updateListItem(item, itemIndex, info);\r
80282 me.topRenderedIndex++;\r
80283 }\r
80284 }\r
80285 }\r
80286 }\r
80287 }\r
80288 },\r
80289 onAnimationIdle: function() {\r
80290 var me = this,\r
80291 info = me.getListItemInfo(),\r
80292 bufferSize = me.getBufferSize(),\r
80293 topVisibleIndex = me.topVisibleIndex,\r
80294 topRenderedIndex = me.topRenderedIndex,\r
80295 lastIndex = me.getStore().getCount() - 1,\r
80296 listItems = me.listItems,\r
80297 itemsCount = listItems.length,\r
80298 topBufferDistance, bottomBufferDistance, i, ln, item, itemIndex;\r
80299 topBufferDistance = topVisibleIndex - topRenderedIndex;\r
80300 bottomBufferDistance = topRenderedIndex + bufferSize - topVisibleIndex;\r
80301 if (topBufferDistance < bottomBufferDistance) {\r
80302
80303
80304
80305 if (topVisibleIndex > 0) {\r
80306 ln = bottomBufferDistance - topBufferDistance;\r
80307 for (i = 0; i < ln; i++) {\r
80308 itemIndex = topRenderedIndex - i - 1;\r
80309 if (itemIndex < 0) {\r
80310 break;\r
80311 }\r
80312 item = listItems.pop();\r
80313 listItems.unshift(item);\r
80314 me.updateListItem(item, itemIndex, info);\r
80315 me.topRenderedIndex--;\r
80316 }\r
80317 }\r
80318 } else {\r
80319 ln = topBufferDistance - bottomBufferDistance;\r
80320 for (i = 0; i < ln; i++) {\r
80321 itemIndex = topRenderedIndex + itemsCount + i;\r
80322 if (itemIndex > lastIndex) {\r
80323 break;\r
80324 }\r
80325 item = listItems.shift();\r
80326 listItems.push(item);\r
80327 me.updateListItem(item, itemIndex, info);\r
80328 me.topRenderedIndex++;\r
80329 }\r
80330 }\r
80331 me.handleItemHeights();\r
80332 me.handleItemTransforms();\r
80333 me.onIdleBound = false;\r
80334 },\r
80335 handleItemHeights: function() {\r
80336 var me = this,\r
80337 updatedItems = me.updatedItems,\r
80338 ln = updatedItems.length,\r
80339 itemMap = me.getItemMap(),\r
80340 useSimpleItems = me.getUseSimpleItems(),\r
80341 minimumHeight = itemMap.getMinimumHeight(),\r
80342 headerIndices = me.headerIndices,\r
80343 headerMap = me.headerMap,\r
80344 variableHeights = me.getVariableHeights(),\r
80345 itemIndex, i, j, jln, item, height, scrollDockHeight;\r
80346 for (i = 0; i < ln; i++) {\r
80347 item = updatedItems[i];\r
80348 itemIndex = item.$dataIndex;\r
80349
80350 if (itemIndex !== null) {\r
80351 if (variableHeights) {\r
80352 height = useSimpleItems ? item.element.getHeight() : item.element.getFirstChild().getHeight();\r
80353 height = Math.max(height, minimumHeight);\r
80354 } else {\r
80355 height = minimumHeight;\r
80356 }\r
80357 item.$ownItemHeight = height;\r
80358 jln = me.scrollDockItems.top.length;\r
80359 if (item.isFirst) {\r
80360 me.totalScrollDockTopHeight = 0;\r
80361 for (j = 0; j < jln; j++) {\r
80362 scrollDockHeight = me.scrollDockItems.top[j].$scrollDockHeight;\r
80363 height += scrollDockHeight;\r
80364 me.totalScrollDockTopHeight += scrollDockHeight;\r
80365 }\r
80366 }\r
80367 jln = me.scrollDockItems.bottom.length;\r
80368 if (item.isLast) {\r
80369 for (j = 0; j < jln; j++) {\r
80370 scrollDockHeight = me.scrollDockItems.bottom[j].$scrollDockHeight;\r
80371 height += scrollDockHeight;\r
80372 }\r
80373 }\r
80374 if (headerIndices && headerIndices[itemIndex]) {\r
80375 height += me.headerHeight;\r
80376 }\r
80377 itemMap.setItemHeight(itemIndex, height);\r
80378 item.$height = height;\r
80379 }\r
80380 }\r
80381 itemMap.update();\r
80382 headerMap.length = 0;\r
80383 for (i in headerIndices) {\r
80384 if (headerIndices.hasOwnProperty(i)) {\r
80385 headerMap.push(itemMap.map[i]);\r
80386 }\r
80387 }\r
80388 me.updatedItems.length = 0;\r
80389 me.refreshScroller(true);\r
80390 },\r
80391 handleItemTransforms: function() {\r
80392 var me = this,\r
80393 listItems = me.listItems,\r
80394 itemsCount = listItems.length,\r
80395 itemMap = me.getItemMap(),\r
80396 scrollDockItems = me.scrollDockItems,\r
80397 grouped = me.isGrouping(),\r
80398 item, transY, i, jln, j;\r
80399 for (i = 0; i < itemsCount; i++) {\r
80400 item = listItems[i];\r
80401 transY = itemMap.map[item.$dataIndex];\r
80402 if (!item.$hidden && item.$position !== transY) {\r
80403 item.$position = transY;\r
80404 jln = scrollDockItems.top.length;\r
80405 if (item.isFirst && jln) {\r
80406 for (j = 0; j < jln; j++) {\r
80407 scrollDockItems.top[j].translate(0, transY);\r
80408 transY += scrollDockItems.top[j].$scrollDockHeight;\r
80409 }\r
80410 }\r
80411 if (grouped && me.headerIndices && me.headerIndices[item.$dataIndex]) {\r
80412 item.getHeader().translate(0, transY);\r
80413 transY += me.headerHeight;\r
80414 }\r
80415 item.translate(0, transY);\r
80416 transY += item.$ownItemHeight;\r
80417 jln = scrollDockItems.bottom.length;\r
80418 if (item.isLast && jln) {\r
80419 for (j = 0; j < jln; j++) {\r
80420 scrollDockItems.bottom[j].translate(0, transY);\r
80421 transY += scrollDockItems.bottom[j].$scrollDockHeight;\r
80422 }\r
80423 }\r
80424 }\r
80425 }\r
80426 },\r
80427 handlePinnedHeader: function(y) {\r
80428 var me = this,\r
80429 pinnedHeader = me.pinnedHeader,\r
80430 itemMap = me.getItemMap(),\r
80431 groups = me.groups,\r
80432 headerMap = me.headerMap,\r
80433 headerHeight = me.headerHeight,\r
80434 store = me.getStore(),\r
80435 totalScrollDockTopHeight = me.totalScrollDockTopHeight,\r
80436 record, closestHeader, pushedHeader, transY, headerString;\r
80437 closestHeader = itemMap.binarySearch(headerMap, -y);\r
80438 record = groups.getAt(closestHeader).getAt(0);\r
80439 if (record) {\r
80440 pushedHeader = y + headerMap[closestHeader + 1] - headerHeight;\r
80441
80442 if (y >= 0 || (closestHeader === 0 && totalScrollDockTopHeight + y >= 0) || (closestHeader === 0 && -y <= headerMap[closestHeader])) {\r
80443 transY = -10000;\r
80444 }\r
80445
80446 else if (pushedHeader < 0) {\r
80447 transY = pushedHeader;\r
80448 } else
80449 {\r
80450 transY = Math.max(0, y);\r
80451 }\r
80452 headerString = store.getGrouper().getGroupString(record);\r
80453 if (pinnedHeader.$currentHeader != headerString) {\r
80454 pinnedHeader.setHtml(headerString);\r
80455 pinnedHeader.$currentHeader = headerString;\r
80456 }\r
80457 if (pinnedHeader.$position != transY) {\r
80458 pinnedHeader.translate(0, transY);\r
80459 pinnedHeader.$position = transY;\r
80460 }\r
80461 }\r
80462 },\r
80463 createItem: function(config) {\r
80464 var me = this,\r
80465 container = me.container,\r
80466 listItems = me.listItems,\r
80467 infinite = me.getInfinite(),\r
80468 scrollElement = me.scrollElement,\r
80469 item, header, itemCls;\r
80470 config.$initParent = me;\r
80471 item = Ext.factory(config);\r
80472 delete config.$initParent;\r
80473 item.dataview = me;\r
80474 item.$height = config.minHeight;\r
80475 if (!infinite) {\r
80476 itemCls = me.getBaseCls() + '-item-relative';\r
80477 item.addCls(itemCls);\r
80478 }\r
80479 header = item.getHeader && item.getHeader();\r
80480 if (header) {\r
80481 if (!infinite) {\r
80482 header.addCls(itemCls);\r
80483 } else {\r
80484 header.setTranslatable({\r
80485 translationMethod: this.translationMethod\r
80486 });\r
80487 header.translate(0, -10000);\r
80488 scrollElement.insertFirst(header.renderElement);\r
80489 }\r
80490 }\r
80491 container.doAdd(item);\r
80492 listItems.push(item);\r
80493 return item;\r
80494 },\r
80495 setItemsCount: function(itemsCount, itemConfig) {\r
80496 var me = this,\r
80497 listItems = me.listItems,\r
80498 config = itemConfig || me.getListItemConfig(),\r
80499 difference = itemsCount - listItems.length,\r
80500 i;\r
80501
80502 for (i = 0; i < difference; i++) {\r
80503 me.createItem(config);\r
80504 }\r
80505
80506 for (i = difference; i < 0; i++) {\r
80507 listItems.pop().destroy();\r
80508 }\r
80509 me.itemsCount = itemsCount;\r
80510
80511 me.updateAllListItems();\r
80512
80513 if (Ext.browser.is.AndroidStock && me.container.element && itemsCount === 0 && difference !== 0) {\r
80514 me.container.element.redraw();\r
80515 }\r
80516 return me.listItems;\r
80517 },\r
80518 updateListItem: function(item, index, info) {\r
80519 var me = this,\r
80520 recordMap = me.recordMap,\r
80521 oldRecord = item.getRecord(),\r
80522 store = info.store,\r
80523 record = store.getAt(index),\r
80524 headerIndices = me.headerIndices,\r
80525 footerIndices = me.footerIndices,\r
80526 header = item.getHeader && item.getHeader(),\r
80527 scrollDockItems = me.scrollDockItems,\r
80528 updatedItems = me.updatedItems,\r
80529 infinite = me.getInfinite(),\r
80530 storeCount = store.getCount(),\r
80531 grouper = store.getGrouper(),\r
80532 itemCls = [],\r
80533 headerCls = [],\r
80534 itemRemoveCls = [\r
80535 info.headerCls,\r
80536 info.footerCls,\r
80537 info.firstCls,\r
80538 info.lastCls,\r
80539 info.selectedCls,\r
80540 info.stripeCls\r
80541 ],\r
80542 headerRemoveCls = [\r
80543 info.headerCls,\r
80544 info.footerCls,\r
80545 info.firstCls,\r
80546 info.lastCls\r
80547 ],\r
80548 ln, i, scrollDockItem, viewModel;\r
80549
80550
80551
80552 if (infinite) {\r
80553 item.$position = -10000;\r
80554 }\r
80555
80556 if (!record) {\r
80557 item.setRecord(null);\r
80558 if (oldRecord) {\r
80559 delete recordMap[oldRecord.internalId];\r
80560 }\r
80561 if (infinite) {\r
80562 item.translate(0, -10000);\r
80563 } else {\r
80564 item.hide();\r
80565 }\r
80566 if (header) {\r
80567 if (infinite) {\r
80568 header.translate(0, -10000);\r
80569 } else {\r
80570 header.hide();\r
80571 }\r
80572 }\r
80573 item.$hidden = true;\r
80574 return;\r
80575 } else if (item.$hidden) {\r
80576 if (!infinite) {\r
80577 item.show();\r
80578 }\r
80579 item.$hidden = false;\r
80580 }\r
80581 if (infinite) {\r
80582 updatedItems.push(item);\r
80583 }\r
80584
80585
80586 if (item.isFirst && index !== 0) {\r
80587 ln = scrollDockItems.top.length;\r
80588 for (i = 0; i < ln; i++) {\r
80589 scrollDockItem = scrollDockItems.top[i];\r
80590 if (infinite) {\r
80591 scrollDockItem.translate(0, -10000);\r
80592 }\r
80593 }\r
80594 item.isFirst = false;\r
80595 }\r
80596
80597
80598 if (item.isLast && index !== storeCount - 1) {\r
80599 ln = scrollDockItems.bottom.length;\r
80600 for (i = 0; i < ln; i++) {\r
80601 scrollDockItem = scrollDockItems.bottom[i];\r
80602 if (infinite) {\r
80603 scrollDockItem.translate(0, -10000);\r
80604 }\r
80605 }\r
80606 item.isLast = false;\r
80607 }\r
80608
80609 if (item.$dataIndex !== index) {\r
80610 item.$dataIndex = index;\r
80611 me.fireEvent('itemindexchange', me, record, index, item);\r
80612 }\r
80613
80614 if (oldRecord === record) {\r
80615 item.updateRecord(record);\r
80616 } else {\r
80617 if (oldRecord) {\r
80618 delete recordMap[oldRecord.internalId];\r
80619 }\r
80620 recordMap[record.internalId] = item;\r
80621 item.setRecord(record);\r
80622 viewModel = item.getViewModel();\r
80623 if (viewModel) {\r
80624 viewModel.set('record', record);\r
80625 }\r
80626 }\r
80627 if (me.isSelected(record)) {\r
80628 itemCls.push(info.selectedCls);\r
80629 }\r
80630 if (info.grouped) {\r
80631 if (headerIndices[index]) {\r
80632 itemCls.push(info.headerCls);\r
80633 headerCls.push(info.headerCls);\r
80634 header.setHtml(grouper.getGroupString(record));\r
80635 if (!infinite) {\r
80636 header.renderElement.insertBefore(item.renderElement);\r
80637 }\r
80638 header.show();\r
80639 } else {\r
80640 if (infinite) {\r
80641 header.translate(0, -10000);\r
80642 } else {\r
80643 header.hide();\r
80644 }\r
80645 }\r
80646 if (footerIndices[index]) {\r
80647 itemCls.push(info.footerCls);\r
80648 headerCls.push(info.footerCls);\r
80649 }\r
80650 }\r
80651 if (header && !info.grouped) {\r
80652 if (infinite) {\r
80653 header.translate(0, -10000);\r
80654 } else {\r
80655 header.hide();\r
80656 }\r
80657 }\r
80658 if (index === 0) {\r
80659 item.isFirst = true;\r
80660 itemCls.push(info.firstCls);\r
80661 headerCls.push(info.firstCls);\r
80662 if (!info.grouped) {\r
80663 itemCls.push(info.headerCls);\r
80664 headerCls.push(info.headerCls);\r
80665 }\r
80666 if (!infinite) {\r
80667 for (i = 0 , ln = scrollDockItems.top.length; i < ln; i++) {\r
80668 scrollDockItem = scrollDockItems.top[i];\r
80669 if (info.grouped) {\r
80670 scrollDockItem.renderElement.insertBefore(header.renderElement);\r
80671 } else {\r
80672 scrollDockItem.renderElement.insertBefore(item.renderElement);\r
80673 }\r
80674 }\r
80675 }\r
80676 }\r
80677 if (index === storeCount - 1) {\r
80678 item.isLast = true;\r
80679 itemCls.push(info.lastCls);\r
80680 headerCls.push(info.lastCls);\r
80681 if (!info.grouped) {\r
80682 itemCls.push(info.footerCls);\r
80683 headerCls.push(info.footerCls);\r
80684 }\r
80685 if (!infinite) {\r
80686 for (i = 0 , ln = scrollDockItems.bottom.length; i < ln; i++) {\r
80687 scrollDockItem = scrollDockItems.bottom[i];\r
80688 scrollDockItem.renderElement.insertAfter(item.renderElement);\r
80689 }\r
80690 }\r
80691 }\r
80692 if (info.striped && index % 2 === 1) {\r
80693 itemCls.push(info.stripeCls);\r
80694 }\r
80695 item.renderElement.replaceCls(itemRemoveCls, itemCls);\r
80696 if (header) {\r
80697 header.renderElement.replaceCls(headerRemoveCls, headerCls);\r
80698 }\r
80699 },\r
80700 updateAllListItems: function() {\r
80701 var me = this,\r
80702 store, items, info, topRenderedIndex, i, ln;\r
80703 if (!me.initialized) {\r
80704 return;\r
80705 }\r
80706 store = me.getStore();\r
80707 items = me.listItems;\r
80708 info = me.getListItemInfo();\r
80709 topRenderedIndex = me.topRenderedIndex;\r
80710 if (store) {\r
80711 for (i = 0 , ln = items.length; i < ln; i++) {\r
80712 me.updateListItem(items[i], topRenderedIndex + i, info);\r
80713 }\r
80714 }\r
80715 if (me.isPainted()) {\r
80716 if (me.getInfinite() && store && store.getCount()) {\r
80717 me.handleItemHeights();\r
80718 }\r
80719 me.refreshScroller();\r
80720 }\r
80721 },\r
80722 doRefresh: function() {\r
80723 var me = this,\r
80724 infinite = me.getInfinite(),\r
80725 scroller = me.container.getScrollable(),\r
80726 storeCount = me.getStore().getCount();\r
80727 if (infinite) {\r
80728 me.getItemMap().populate(storeCount, this.topRenderedIndex);\r
80729 }\r
80730 if (me.getGrouped()) {\r
80731 me.refreshHeaderIndices();\r
80732 }\r
80733
80734 if (storeCount) {\r
80735 me.hideScrollDockItems();\r
80736 me.hideEmptyText();\r
80737 if (!infinite) {\r
80738 me.setItemsCount(storeCount);\r
80739 if (me.getScrollToTopOnRefresh()) {\r
80740 scroller.scrollTo(0, 0);\r
80741 }\r
80742 } else {\r
80743 if (me.getScrollToTopOnRefresh()) {\r
80744 me.topRenderedIndex = 0;\r
80745 me.topVisibleIndex = 0;\r
80746 scroller.scrollTo(null, 0);\r
80747 }\r
80748 me.updateAllListItems();\r
80749 }\r
80750 } else {\r
80751 me.onStoreClear();\r
80752 }\r
80753 },\r
80754 updateStore: function(store, oldStore) {\r
80755 var me = this,\r
80756 container = me.container;\r
80757 me.callParent([\r
80758 store,\r
80759 oldStore\r
80760 ]);\r
80761 if (me._fireResizeOnNextLoad && me.hasLoadedStore) {\r
80762 me._fireResizeOnNextLoad = false;\r
80763 me.onContainerResize(container, {\r
80764 height: container.element.getHeight()\r
80765 });\r
80766 }\r
80767 },\r
80768 onLoad: function(store) {\r
80769 var me = this,\r
80770 container = me.container;\r
80771 me.callParent([\r
80772 store\r
80773 ]);\r
80774 if (me._fireResizeOnNextLoad) {\r
80775 me._fireResizeOnNextLoad = false;\r
80776 me.onContainerResize(container, {\r
80777 height: container.element.getHeight()\r
80778 });\r
80779 }\r
80780 },\r
80781 onContainerResize: function(container, size) {\r
80782 var me = this,\r
80783 store = me.getStore(),\r
80784 currentVisibleCount, newVisibleCount, minHeight, listItems, itemMap, itemConfig;\r
80785 if (!me.headerHeight) {\r
80786 me.headerHeight = parseInt(me.pinnedHeader.renderElement.getHeight(), 10);\r
80787 }\r
80788 if (me.getInfinite()) {\r
80789 itemMap = me.getItemMap();\r
80790 minHeight = itemMap.getMinimumHeight();\r
80791 if (!store || (!store.getCount() && !store.isLoaded())) {\r
80792
80793
80794
80795 me._fireResizeOnNextLoad = true;\r
80796 return;\r
80797 }\r
80798 if (!minHeight) {\r
80799 listItems = me.listItems;\r
80800
80801
80802
80803
80804 if (!listItems.length) {\r
80805
80806
80807
80808
80809 itemConfig = me.getListItemConfig();\r
80810 me.createItem(itemConfig);\r
80811 me.updateListItem(listItems[0], 0, me.getListItemInfo());\r
80812 me.visibleCount++;\r
80813 }\r
80814 minHeight = listItems[0].element.getHeight();\r
80815
80816 itemMap.setMinimumHeight(minHeight);\r
80817 me.getItemMap().populate(me.getStore().getCount(), me.topRenderedIndex);\r
80818 }\r
80819 currentVisibleCount = me.visibleCount;\r
80820 newVisibleCount = Math.ceil(size.height / minHeight);\r
80821 if (newVisibleCount != currentVisibleCount) {\r
80822 me.visibleCount = newVisibleCount;\r
80823 me.setItemsCount(newVisibleCount + me.getBufferSize(), itemConfig);\r
80824
80825 me.fireEvent('updatevisiblecount', this, newVisibleCount, currentVisibleCount);\r
80826 }\r
80827 } else if (me.listItems.length && me.getGrouped() && me.getPinHeaders()) {\r
80828
80829
80830 me.updateHeaderMap();\r
80831 }\r
80832 },\r
80833 refreshScroller: function(skipOnRefresh) {\r
80834 var me = this,\r
80835 scroller = me.container.getScrollable(),\r
80836 infinite = me.getInfinite(),\r
80837 height, scrollSize;\r
80838 if (infinite) {\r
80839 height = me.getItemMap().getTotalHeight();\r
80840 scrollSize = scroller.getSize();\r
80841 if (height != scrollSize.y) {\r
80842 scroller.setSize({\r
80843
80844
80845
80846
80847 x: scroller.isTouchScroller ? scrollSize.x : null,\r
80848 y: height\r
80849 });\r
80850 }\r
80851 if (!skipOnRefresh) {\r
80852 me.onScrollerRefresh(scroller);\r
80853 }\r
80854 } else {\r
80855 if (me.getGrouped() && me.getPinHeaders()) {\r
80856 me.updateHeaderMap();\r
80857 }\r
80858 scroller.refresh();\r
80859 }\r
80860 },\r
80861 updateHeaderMap: function() {\r
80862 var me = this,\r
80863 headerMap = me.headerMap,\r
80864 headerIndices = me.headerIndices,\r
80865 header, i;\r
80866 headerMap.length = 0;\r
80867 for (i in headerIndices) {\r
80868 if (headerIndices.hasOwnProperty(i)) {\r
80869 header = me.getItemAt(i).getHeader();\r
80870 headerMap.push(header.renderElement.dom.offsetTop);\r
80871 }\r
80872 }\r
80873 },\r
80874 applyVariableHeights: function(value) {\r
80875 if (!this.getInfinite()) {\r
80876 return true;\r
80877 }\r
80878 return value;\r
80879 },\r
80880 applyDefaultType: function(defaultType) {\r
80881 if (!defaultType) {\r
80882 defaultType = this.getUseSimpleItems() ? 'simplelistitem' : 'listitem';\r
80883 }\r
80884 return defaultType;\r
80885 },\r
80886 applyItemMap: function(itemMap) {\r
80887 return Ext.factory(itemMap, Ext.util.PositionMap, this.getItemMap());\r
80888 },\r
80889 updateItemHeight: function(itemHeight) {\r
80890 this.getItemMap().setMinimumHeight(itemHeight);\r
80891 },\r
80892 applyIndexBar: function(indexBar) {\r
80893 return Ext.factory(indexBar, Ext.dataview.IndexBar, this.getIndexBar());\r
80894 },\r
80895 updatePinHeaders: function(pinnedHeaders) {\r
80896 if (this.isPainted()) {\r
80897 this.pinnedHeader.translate(0, pinnedHeaders ? this.pinnedHeader.$position : -10000);\r
80898 }\r
80899 },\r
80900 updateItemTpl: function(newTpl) {\r
80901 var me = this,\r
80902 listItems = me.listItems,\r
80903 ln = listItems.length || 0,\r
80904 i, listItem;\r
80905 for (i = 0; i < ln; i++) {\r
80906 listItem = listItems[i];\r
80907 listItem.setTpl(newTpl);\r
80908 }\r
80909 me.updateAllListItems();\r
80910 },\r
80911 updateItemCls: function(newCls, oldCls) {\r
80912 var items = this.listItems,\r
80913 ln = items.length,\r
80914 i, item;\r
80915 for (i = 0; i < ln; i++) {\r
80916 item = items[i];\r
80917 item.removeCls(oldCls);\r
80918 item.addCls(newCls);\r
80919 }\r
80920 },\r
80921 updateIndexBar: function(indexBar, oldIndexBar) {\r
80922 var me = this,\r
80923 scrollViewElement = me.scrollViewElement;\r
80924 if (oldIndexBar) {\r
80925 oldIndexBar.un({\r
80926 index: 'onIndex',\r
80927 scope: me\r
80928 });\r
80929 if (!indexBar) {\r
80930 me.element.removeCls(me.getBaseCls() + '-indexed');\r
80931 }\r
80932 if (scrollViewElement) {\r
80933 scrollViewElement.removeChild(oldIndexBar.renderElement);\r
80934 }\r
80935 }\r
80936 if (indexBar) {\r
80937 indexBar.on({\r
80938 index: 'onIndex',\r
80939 scope: me\r
80940 });\r
80941 if (!oldIndexBar) {\r
80942 me.element.addCls(me.getBaseCls() + '-indexed');\r
80943 }\r
80944 if (scrollViewElement) {\r
80945 scrollViewElement.appendChild(indexBar.renderElement);\r
80946 }\r
80947 }\r
80948 },\r
80949 updateGrouped: function(grouped) {\r
80950 if (this.initialized) {\r
80951 this.handleGroupChange();\r
80952 }\r
80953 },\r
80954 onStoreGroupChange: function() {\r
80955 if (this.initialized) {\r
80956 this.handleGroupChange();\r
80957 }\r
80958 },\r
80959 onStoreAdd: function() {\r
80960 this.doRefresh();\r
80961 },\r
80962 onStoreRemove: function() {\r
80963 this.doRefresh();\r
80964 },\r
80965 onStoreUpdate: function(store, record, type, modifiedFieldNames, info) {\r
80966 var me = this,\r
80967 index, item;\r
80968 if (me.getInfinite() || info.indexChanged) {\r
80969 me.doRefresh();\r
80970 } else {\r
80971 index = store.indexOf(record);\r
80972 item = me.listItems[index];\r
80973 if (item) {\r
80974 me.updateListItem(item, index, me.getListItemInfo());\r
80975 }\r
80976 }\r
80977 },\r
80978 onStoreClear: function() {\r
80979 var me = this,\r
80980 scroller = me.container.getScrollable(),\r
80981 infinite = me.getInfinite();\r
80982 if (me.pinnedHeader) {\r
80983 me.pinnedHeader.translate(0, -10000);\r
80984 }\r
80985 me.getItemMap().populate(0, 0);\r
80986 if (!infinite) {\r
80987 me.setItemsCount(0);\r
80988 } else {\r
80989 me.topRenderedIndex = 0;\r
80990 me.topVisibleIndex = 0;\r
80991 me.updateAllListItems();\r
80992 }\r
80993 scroller.scrollTo(null, 0);\r
80994 me.refreshScroller();\r
80995 },\r
80996 showEmptyScrollDock: function() {\r
80997 var me = this,\r
80998 infinite = me.getInfinite(),\r
80999 scrollDockItems = me.scrollDockItems,\r
81000 offset = 0,\r
81001 i, ln, item;\r
81002 for (i = 0 , ln = scrollDockItems.top.length; i < ln; i++) {\r
81003 item = scrollDockItems.top[i];\r
81004 if (infinite) {\r
81005 item.translate(0, offset);\r
81006 offset += item.$scrollDockHeight;\r
81007 } else {\r
81008 this.scrollElement.appendChild(item.renderElement);\r
81009 }\r
81010 }\r
81011 for (i = 0 , ln = scrollDockItems.bottom.length; i < ln; i++) {\r
81012 item = scrollDockItems.bottom[i];\r
81013 if (infinite) {\r
81014 item.translate(0, offset);\r
81015 offset += item.$scrollDockHeight;\r
81016 } else {\r
81017 this.scrollElement.appendChild(item.renderElement);\r
81018 }\r
81019 }\r
81020 },\r
81021 hideScrollDockItems: function() {\r
81022 var me = this,\r
81023 infinite = me.getInfinite(),\r
81024 scrollDockItems = me.scrollDockItems,\r
81025 i, ln, item;\r
81026 if (!infinite) {\r
81027 return;\r
81028 }\r
81029 for (i = 0 , ln = scrollDockItems.top.length; i < ln; i++) {\r
81030 item = scrollDockItems.top[i];\r
81031 item.translate(0, -10000);\r
81032 }\r
81033 for (i = 0 , ln = scrollDockItems.bottom.length; i < ln; i++) {\r
81034 item = scrollDockItems.bottom[i];\r
81035 item.translate(0, -10000);\r
81036 }\r
81037 },\r
81038 \r
81039 getItem: function(record) {\r
81040 var item;\r
81041 if (record) {\r
81042 item = this.recordMap[record.internalId];\r
81043 }\r
81044 return item || null;\r
81045 },\r
81046 \r
81047 getItemAt: function(index) {\r
81048 var listItems = this.listItems,\r
81049 ln = listItems.length,\r
81050 i, listItem;\r
81051 for (i = 0; i < ln; i++) {\r
81052 listItem = listItems[i];\r
81053 if (listItem.$dataIndex == index) {\r
81054 return listItem;\r
81055 }\r
81056 }\r
81057 },\r
81058 \r
81059 getItemIndex: function(item) {\r
81060 return item.$dataIndex;\r
81061 },\r
81062 \r
81063 getViewItems: function() {\r
81064 return this.listItems;\r
81065 },\r
81066 getListItemInfo: function() {\r
81067 var me = this,\r
81068 baseCls = me.getBaseCls();\r
81069 return {\r
81070 store: me.getStore(),\r
81071 grouped: me.isGrouping(),\r
81072 baseCls: baseCls,\r
81073 selectedCls: me.getSelectedCls(),\r
81074 headerCls: baseCls + '-header-wrap',\r
81075 footerCls: baseCls + '-footer-wrap',\r
81076 firstCls: baseCls + '-item-first',\r
81077 lastCls: baseCls + '-item-last',\r
81078 stripeCls: baseCls + '-item-odd',\r
81079 striped: me.getStriped(),\r
81080 itemMap: me.getItemMap(),\r
81081 defaultItemHeight: me.getItemHeight()\r
81082 };\r
81083 },\r
81084 getListItemConfig: function() {\r
81085 var me = this,\r
81086 minimumHeight = me.getItemMap().getMinimumHeight(),\r
81087 config = {\r
81088 xtype: me.getDefaultType(),\r
81089 tpl: me.getItemTpl(),\r
81090 minHeight: minimumHeight,\r
81091 cls: me.getItemCls()\r
81092 };\r
81093 if (me.getInfinite()) {\r
81094 config.translatable = {\r
81095 translationMethod: this.translationMethod\r
81096 };\r
81097 }\r
81098 if (!me.getVariableHeights()) {\r
81099 config.height = minimumHeight;\r
81100 }\r
81101 return Ext.merge(config, me.getItemConfig());\r
81102 },\r
81103 refreshHeaderIndices: function() {\r
81104 var me = this,\r
81105 store = me.getStore(),\r
81106 storeLn = store && store.getCount(),\r
81107 groups = store.getGrouper() ? store.getGroups() : null,\r
81108 grouped = me.getGrouped(),\r
81109 headerIndices = me.headerIndices = {},\r
81110 footerIndices = me.footerIndices = {},\r
81111 i, previousIndex, firstGroupedRecord, storeIndex, groupLn;\r
81112 if (!grouped || !groups) {\r
81113 return footerIndices;\r
81114 }\r
81115 groupLn = groups.length;\r
81116 me.groups = groups;\r
81117 for (i = 0; i < groupLn; i++) {\r
81118 firstGroupedRecord = groups.getAt(i).getAt(0);\r
81119 storeIndex = store.indexOf(firstGroupedRecord);\r
81120 headerIndices[storeIndex] = true;\r
81121 previousIndex = storeIndex - 1;\r
81122 if (previousIndex >= 0) {\r
81123 footerIndices[previousIndex] = true;\r
81124 }\r
81125 }\r
81126 footerIndices[storeLn - 1] = true;\r
81127 return headerIndices;\r
81128 },\r
81129 onIndex: function(indexBar, index) {\r
81130 var me = this,\r
81131 key = index.toLowerCase(),\r
81132 store = me.getStore(),\r
81133 groups = store.getGroups(),\r
81134 ln = groups.length,\r
81135 group, groupKey, i, closest;\r
81136 for (i = 0; i < ln; i++) {\r
81137 group = groups.getAt(i);\r
81138 groupKey = group.getGroupKey().toLowerCase();\r
81139 if (groupKey >= key) {\r
81140 closest = group;\r
81141 break;\r
81142 } else {\r
81143 closest = group;\r
81144 }\r
81145 }\r
81146 if (closest) {\r
81147 this.scrollToRecord(closest.getAt(0));\r
81148 }\r
81149 },\r
81150 \r
81151 scrollToRecord: function(record, animate, overscroll) {\r
81152 var me = this,\r
81153 scroller = me.container.getScrollable(),\r
81154 store = me.getStore(),\r
81155 index = store.indexOf(record),\r
81156 header;\r
81157
81158 scroller.stopAnimation();\r
81159
81160 var elementHeight = scroller.getElement().getHeight(),\r
81161 scrollHeight = scroller.getSize().y,\r
81162 maxOffset = scrollHeight - elementHeight,\r
81163 offset, item;\r
81164 if (me.getInfinite()) {\r
81165 offset = me.getItemMap().map[index];\r
81166 } else {\r
81167 item = me.listItems[index];\r
81168 header = item.getHeader && item.getHeader();\r
81169 if (header && header.isPainted()) {\r
81170 offset = header.renderElement.dom.offsetTop;\r
81171 } else {\r
81172 offset = item.renderElement.dom.offsetTop;\r
81173 }\r
81174 }\r
81175 if (!overscroll) {\r
81176 offset = Math.min(offset, maxOffset);\r
81177 }\r
81178 scroller.scrollTo(0, offset, !!animate);\r
81179 },\r
81180 onItemAdd: function(item) {\r
81181 var me = this,\r
81182 config = item.config;\r
81183 if (config.scrollDock) {\r
81184 if (config.scrollDock == 'bottom') {\r
81185 me.scrollDockItems.bottom.push(item);\r
81186 } else {\r
81187 me.scrollDockItems.top.push(item);\r
81188 }\r
81189 if (me.getInfinite()) {\r
81190 item.on({\r
81191 resize: 'onScrollDockItemResize',\r
81192 scope: this\r
81193 });\r
81194 item.addCls(me.getBaseCls() + '-scrolldockitem');\r
81195 item.setTranslatable({\r
81196 translationMethod: this.translationMethod\r
81197 });\r
81198 item.translate(0, -10000);\r
81199 item.$scrollDockHeight = 0;\r
81200 }\r
81201 me.container.doAdd(item);\r
81202 } else {\r
81203 me.callParent(arguments);\r
81204 }\r
81205 },\r
81206 \r
81207 getScrollDockedItems: function() {\r
81208 return this.scrollDockItems.bottom.slice().concat(this.scrollDockItems.top.slice());\r
81209 },\r
81210 onScrollDockItemResize: function(dockItem, size) {\r
81211 var me = this,\r
81212 items = me.listItems,\r
81213 ln = items.length,\r
81214 i, item;\r
81215 Ext.getCmp(dockItem.id).$scrollDockHeight = size.height;\r
81216 for (i = 0; i < ln; i++) {\r
81217 item = items[i];\r
81218 if (item.isLast) {\r
81219 me.updatedItems.push(item);\r
81220 if (me.isPainted()) {\r
81221 me.refreshScroller();\r
81222 }\r
81223 break;\r
81224 }\r
81225 }\r
81226 },\r
81227 onItemTouchStart: function(e) {\r
81228 this.container.innerElement.on({\r
81229 touchmove: 'onItemTouchMove',\r
81230 delegate: '.' + Ext.baseCSSPrefix + 'list-item',\r
81231 single: true,\r
81232 scope: this\r
81233 });\r
81234 this.callParent(this.parseEvent(e));\r
81235 },\r
81236 onItemTouchMove: function(e) {\r
81237 this.callParent(this.parseEvent(e));\r
81238 },\r
81239 onItemTouchEnd: function(e) {\r
81240 this.container.innerElement.un({\r
81241 touchmove: 'onItemTouchMove',\r
81242 delegate: '.' + Ext.baseCSSPrefix + 'list-item',\r
81243 scope: this\r
81244 });\r
81245 this.callParent(this.parseEvent(e));\r
81246 },\r
81247 onItemTap: function(e) {\r
81248 this.callParent(this.parseEvent(e));\r
81249 },\r
81250 onItemTapHold: function(e) {\r
81251 this.callParent(this.parseEvent(e));\r
81252 },\r
81253 onItemSingleTap: function(e) {\r
81254 this.callParent(this.parseEvent(e));\r
81255 },\r
81256 onItemDoubleTap: function(e) {\r
81257 this.callParent(this.parseEvent(e));\r
81258 },\r
81259 onItemSwipe: function(e) {\r
81260 this.callParent(this.parseEvent(e));\r
81261 },\r
81262 parseEvent: function(e) {\r
81263 var me = this,\r
81264 target = Ext.fly(e.currentTarget).findParent('.' + Ext.baseCSSPrefix + 'list-item', 8),\r
81265 item = Ext.getCmp(target.id);\r
81266 return [\r
81267 me,\r
81268 item,\r
81269 item.$dataIndex,\r
81270 e\r
81271 ];\r
81272 },\r
81273 applyOnItemDisclosure: function(config) {\r
81274 if (Ext.isFunction(config)) {\r
81275 return {\r
81276 scope: this,\r
81277 handler: config\r
81278 };\r
81279 }\r
81280 return config;\r
81281 },\r
81282 handleItemDisclosure: function(e) {\r
81283 var me = this,\r
81284 item = Ext.getCmp(Ext.get(e.currentTarget).up('.x-list-item').id),\r
81285 index = item.$dataIndex,\r
81286 record = me.getStore().getAt(index);\r
81287 me.fireAction('disclose', [\r
81288 me,\r
81289 record,\r
81290 item,\r
81291 index,\r
81292 e\r
81293 ], 'doDisclose');\r
81294 },\r
81295 doDisclose: function(me, record, item, index, e) {\r
81296 var onItemDisclosure = me.getOnItemDisclosure();\r
81297 if (onItemDisclosure && onItemDisclosure.handler) {\r
81298 onItemDisclosure.handler.call(onItemDisclosure.scope || me, record, item, index, e);\r
81299 }\r
81300 },\r
81301
81302 onItemTrigger: function(me, index, target, record, e) {\r
81303 if (!(this.getPreventSelectionOnDisclose() && Ext.fly(e.target).hasCls(this.getBaseCls() + '-disclosure'))) {\r
81304 this.callParent(arguments);\r
81305 }\r
81306 },\r
81307 destroy: function() {\r
81308 var me = this,\r
81309 items = me.listItems,\r
81310 ln = items.length,\r
81311 i;\r
81312 if (me.pinnedHeader) {\r
81313 me.pinnedHeader.destroy();\r
81314 me.pinnedHeader = null;\r
81315 }\r
81316 me.callParent();\r
81317 if (me.onIdleBound) {\r
81318 Ext.AnimationQueue.unIdle(me.onAnimationIdle, me);\r
81319 }\r
81320 for (i = 0; i < ln; i++) {\r
81321 items[i].destroy();\r
81322 }\r
81323 me.recordMap = me.listItems = null;\r
81324 },\r
81325 privates: {\r
81326 handleGroupChange: function() {\r
81327 var me = this,\r
81328 grouped = me.isGrouping(),\r
81329 baseCls = this.getBaseCls(),\r
81330 infinite = me.getInfinite(),\r
81331 pinnedHeader = me.pinnedHeader,\r
81332 cls = baseCls + '-grouped',\r
81333 unCls = baseCls + '-ungrouped';\r
81334 if (pinnedHeader) {\r
81335 pinnedHeader.translate(0, -10000);\r
81336 }\r
81337 if (grouped) {\r
81338 me.addCls(cls);\r
81339 me.removeCls(unCls);\r
81340 } else {\r
81341 me.addCls(unCls);\r
81342 me.removeCls(cls);\r
81343 }\r
81344 if (infinite) {\r
81345 me.refreshHeaderIndices();\r
81346 me.handleItemHeights();\r
81347 }\r
81348 me.updateAllListItems();\r
81349 if (infinite) {\r
81350 me.handleItemTransforms();\r
81351 }\r
81352 },\r
81353 isGrouping: function() {\r
81354 return Boolean(this.getGrouped() && this.getStore().getGrouper());\r
81355 }\r
81356 }\r
81357});\r
81358\r
81359\r
81360Ext.define('Ext.dataview.NestedList', {\r
81361 alternateClassName: 'Ext.NestedList',\r
81362 extend: Ext.Container,\r
81363 xtype: 'nestedlist',\r
81364 config: {\r
81365 \r
81366 baseCls: Ext.baseCSSPrefix + 'nested-list',\r
81367 \r
81368 \r
81369 backText: 'Back',\r
81370 \r
81371 useTitleAsBackText: true,\r
81372 \r
81373 updateTitleText: true,\r
81374 \r
81375 displayField: 'text',\r
81376 \r
81377 loadingText: 'Loading...',\r
81378 \r
81379 emptyText: 'No items available.',\r
81380 \r
81381 onItemDisclosure: false,\r
81382 \r
81383 allowDeselect: false,\r
81384 \r
81385 useToolbar: null,\r
81386 \r
81387 toolbar: {\r
81388 docked: 'top',\r
81389 xtype: 'titlebar',\r
81390 ui: 'light',\r
81391 inline: true\r
81392 },\r
81393 \r
81394 title: '',\r
81395 \r
81396 layout: {\r
81397 type: 'card',\r
81398 animation: {\r
81399 type: 'slide',\r
81400 duration: 250,\r
81401 direction: 'left'\r
81402 }\r
81403 },\r
81404 \r
81405 store: null,\r
81406 \r
81407 detailContainer: undefined,\r
81408 \r
81409 detailCard: null,\r
81410 \r
81411 backButton: {\r
81412 ui: 'back',\r
81413 hidden: true\r
81414 },\r
81415 \r
81416 listConfig: null,\r
81417 \r
81418 useSimpleItems: true,\r
81419 \r
81420 itemHeight: null,\r
81421 \r
81422 variableHeights: false,\r
81423 \r
81424 lastNode: null,\r
81425 \r
81426 lastActiveList: null,\r
81427 ui: null,\r
81428 clearSelectionOnListChange: true\r
81429 },\r
81430 \r
81431 \r
81432 \r
81433 \r
81434 \r
81435 \r
81436 \r
81437 \r
81438 \r
81439 \r
81440 constructor: function(config) {\r
81441 if (Ext.isObject(config)) {\r
81442 if (config.getTitleTextTpl) {\r
81443 this.getTitleTextTpl = config.getTitleTextTpl;\r
81444 }\r
81445 if (config.getItemTextTpl) {\r
81446 this.getItemTextTpl = config.getItemTextTpl;\r
81447 }\r
81448 }\r
81449 this.callParent([\r
81450 config\r
81451 ]);\r
81452 },\r
81453 onItemInteraction: function() {\r
81454 if (this.isGoingTo) {\r
81455 return false;\r
81456 }\r
81457 },\r
81458 applyDetailContainer: function(config) {\r
81459 if (!config) {\r
81460 config = this;\r
81461 }\r
81462 return config;\r
81463 },\r
81464 updateDetailContainer: function(newContainer, oldContainer) {\r
81465 if (newContainer) {\r
81466 newContainer.on('beforeactiveitemchange', 'onBeforeDetailContainerChange', this);\r
81467 newContainer.on('activeitemchange', 'onDetailContainerChange', this);\r
81468 }\r
81469 },\r
81470 onBeforeDetailContainerChange: function() {\r
81471 this.isGoingTo = true;\r
81472 },\r
81473 onDetailContainerChange: function() {\r
81474 this.isGoingTo = false;\r
81475 },\r
81476 \r
81477 onItemTap: function(list, index, target, record, e) {\r
81478 var me = this,\r
81479 store = list.getStore(),\r
81480 node = store.getAt(index);\r
81481 me.fireEvent('itemtap', this, list, index, target, record, e);\r
81482 if (node.isLeaf()) {\r
81483 me.fireEvent('leafitemtap', this, list, index, target, record, e);\r
81484 me.goToLeaf(node);\r
81485 } else {\r
81486 this.goToNode(node);\r
81487 }\r
81488 },\r
81489 onBeforeSelect: function() {\r
81490 this.fireEvent.apply(this, [].concat('beforeselect', this, Array.prototype.slice.call(arguments)));\r
81491 },\r
81492 onContainerTap: function() {\r
81493 this.fireEvent.apply(this, [].concat('containertap', this, Array.prototype.slice.call(arguments)));\r
81494 },\r
81495 onSelectionChange: function() {\r
81496 this.fireEvent.apply(this, [].concat('selectionchange', this, Array.prototype.slice.call(arguments)));\r
81497 },\r
81498 onItemDoubleTap: function() {\r
81499 this.fireEvent.apply(this, [].concat('itemdoubletap', this, Array.prototype.slice.call(arguments)));\r
81500 },\r
81501 onStoreBeforeLoad: function() {\r
81502 var loadingText = this.getLoadingText(),\r
81503 scroller = this.getScrollable();\r
81504 if (loadingText) {\r
81505 this.setMasked({\r
81506 xtype: 'loadmask',\r
81507 message: loadingText\r
81508 });\r
81509
81510 if (scroller) {\r
81511 scroller.setDisabled(true);\r
81512 }\r
81513 }\r
81514 this.fireEvent.apply(this, [].concat('beforeload', this, Array.prototype.slice.call(arguments)));\r
81515 },\r
81516 onStoreLoad: function(store, records, successful, operation, parentNode) {\r
81517 this.setMasked(false);\r
81518 this.fireEvent.apply(this, [].concat('load', this, Array.prototype.slice.call(arguments)));\r
81519 if (store.indexOf(this.getLastNode()) === -1) {\r
81520 this.goToNode(store.getRoot());\r
81521 }\r
81522 },\r
81523 \r
81524 onBackTap: function() {\r
81525 var me = this,\r
81526 node = me.getLastNode(),\r
81527 detailCard = me.getDetailCard(),\r
81528 detailCardActive = detailCard && me.getActiveItem() == detailCard,\r
81529 lastActiveList = me.getLastActiveList();\r
81530 this.fireAction('back', [\r
81531 this,\r
81532 node,\r
81533 lastActiveList,\r
81534 detailCardActive\r
81535 ], 'doBack');\r
81536 },\r
81537 doBack: function(me, node, lastActiveList, detailCardActive) {\r
81538 var layout = me.getLayout(),\r
81539 animation = layout ? layout.getAnimation() : null;\r
81540 if (detailCardActive && lastActiveList) {\r
81541 if (animation) {\r
81542 animation.setReverse(true);\r
81543 }\r
81544 me.setActiveItem(lastActiveList);\r
81545 me.setLastNode(node.parentNode);\r
81546 me.syncToolbar();\r
81547 } else {\r
81548 me.goToNode(node.parentNode);\r
81549 }\r
81550 },\r
81551 updateData: function(data) {\r
81552 if (!this.getStore()) {\r
81553 this.setStore(new Ext.data.TreeStore({\r
81554 root: data\r
81555 }));\r
81556 }\r
81557 },\r
81558 applyStore: function(store) {\r
81559 if (store) {\r
81560 if (Ext.isString(store)) {\r
81561
81562 store = Ext.data.StoreManager.get(store);\r
81563 } else {\r
81564
81565 if (!(store instanceof Ext.data.TreeStore)) {\r
81566 store = Ext.factory(store, Ext.data.TreeStore, null);\r
81567 }\r
81568 }\r
81569
81570 if (!store) {\r
81571 Ext.Logger.warn("The specified Store cannot be found", this);\r
81572 }\r
81573 }\r
81574
81575 return store;\r
81576 },\r
81577 storeListeners: {\r
81578 rootchange: 'onStoreRootChange',\r
81579 load: 'onStoreLoad',\r
81580 beforeload: 'onStoreBeforeLoad'\r
81581 },\r
81582 updateStore: function(newStore, oldStore) {\r
81583 var me = this,\r
81584 listeners = this.storeListeners;\r
81585 listeners.scope = me;\r
81586 if (oldStore && Ext.isObject(oldStore) && oldStore.isStore) {\r
81587 if (oldStore.autoDestroy) {\r
81588 oldStore.destroy();\r
81589 }\r
81590 oldStore.un(listeners);\r
81591 }\r
81592 if (newStore) {\r
81593 newStore.on(listeners);\r
81594 me.goToNode(newStore.getRoot());\r
81595 }\r
81596 },\r
81597 onStoreRootChange: function(store, node) {\r
81598 this.goToNode(node);\r
81599 },\r
81600 applyDetailCard: function(detailCard, oldDetailCard) {\r
81601 return Ext.factory(detailCard, Ext.Component, detailCard === null ? oldDetailCard : undefined);\r
81602 },\r
81603 applyBackButton: function(config) {\r
81604 return Ext.factory(config, Ext.Button, this.getBackButton());\r
81605 },\r
81606 updateBackButton: function(newButton, oldButton) {\r
81607 if (newButton) {\r
81608 var me = this,\r
81609 toolbar;\r
81610 newButton.on('tap', me.onBackTap, me);\r
81611 newButton.setText(me.getBackText());\r
81612 toolbar = me.getToolbar();\r
81613 if (me.$backButtonContainer) {\r
81614 me.$backButtonContainer.insert(0, newButton);\r
81615 } else {\r
81616 toolbar.insert(0, newButton);\r
81617 }\r
81618 } else if (oldButton) {\r
81619 oldButton.destroy();\r
81620 }\r
81621 },\r
81622 applyToolbar: function(config) {\r
81623 if (config && config.splitNavigation) {\r
81624 Ext.apply(config, {\r
81625 docked: 'top',\r
81626 xtype: 'titlebar',\r
81627 ui: 'light'\r
81628 });\r
81629 var containerConfig = (config.splitNavigation === true) ? {} : config.splitNavigation;\r
81630 this.$backButtonContainer = this.add(Ext.apply({\r
81631 xtype: 'toolbar',\r
81632 docked: 'bottom',\r
81633 hidden: true,\r
81634 ui: 'dark'\r
81635 }, containerConfig));\r
81636 }\r
81637 return Ext.factory(config, Ext.TitleBar, this.getToolbar());\r
81638 },\r
81639 updateToolbar: function(newToolbar, oldToolbar) {\r
81640 var me = this;\r
81641 if (newToolbar) {\r
81642 newToolbar.setTitle(me.getTitle());\r
81643 if (!newToolbar.getParent()) {\r
81644 me.add(newToolbar);\r
81645 }\r
81646 } else if (oldToolbar) {\r
81647 oldToolbar.destroy();\r
81648 }\r
81649 },\r
81650 updateUseToolbar: function(newUseToolbar, oldUseToolbar) {\r
81651 if (!newUseToolbar) {\r
81652 this.setToolbar(false);\r
81653 }\r
81654 },\r
81655 updateTitle: function(newTitle) {\r
81656 var me = this,\r
81657 toolbar = me.getToolbar();\r
81658 if (toolbar && me.getUpdateTitleText()) {\r
81659 toolbar.setTitle(newTitle);\r
81660 }\r
81661 },\r
81662 \r
81663 getItemTextTpl: function(node) {\r
81664 return '{' + this.getDisplayField() + '}';\r
81665 },\r
81666 \r
81667 getTitleTextTpl: function(node) {\r
81668 return '{' + this.getDisplayField() + '}';\r
81669 },\r
81670 \r
81671 renderTitleText: function(node, forBackButton) {\r
81672 if (!node.titleTpl) {\r
81673 node.titleTpl = Ext.create('Ext.XTemplate', this.getTitleTextTpl(node));\r
81674 }\r
81675 if (node.isRoot()) {\r
81676 var initialTitle = this.getInitialConfig('title');\r
81677 return (forBackButton && initialTitle === '') ? this.getInitialConfig('backText') : initialTitle;\r
81678 }\r
81679 return node.titleTpl.applyTemplate(node.data);\r
81680 },\r
81681 \r
81682 goToNode: function(node) {\r
81683 if (!node) {\r
81684 return;\r
81685 }\r
81686 var me = this,\r
81687 activeItem = me.getActiveItem(),\r
81688 detailCard = me.getDetailCard(),\r
81689 detailCardActive = detailCard && me.getActiveItem() == detailCard,\r
81690 reverse = me.goToNodeReverseAnimation(node),\r
81691 firstList = me.firstList,\r
81692 secondList = me.secondList,\r
81693 layout = me.getLayout(),\r
81694 animation = layout ? layout.getAnimation() : null,\r
81695 list;\r
81696
81697 if (node.isLeaf()) {\r
81698 throw new Error('goToNode: passed a node which is a leaf.');\r
81699 }\r
81700
81701 if (node === me.getLastNode() && !detailCardActive) {\r
81702 return;\r
81703 }\r
81704 if (detailCardActive) {\r
81705 if (animation) {\r
81706 animation.setReverse(true);\r
81707 }\r
81708 list = me.getLastActiveList();\r
81709 list.getStore().setNode(node);\r
81710 node.expand();\r
81711 me.setActiveItem(list);\r
81712 } else {\r
81713 if (animation) {\r
81714 animation.setReverse(reverse);\r
81715 }\r
81716 if (firstList && secondList) {\r
81717
81718 activeItem = me.getActiveItem();\r
81719 me.setLastActiveList(activeItem);\r
81720 list = (activeItem == firstList) ? secondList : firstList;\r
81721 list.getStore().setNode(node);\r
81722 node.expand();\r
81723 me.setActiveItem(list);\r
81724 if (me.getClearSelectionOnListChange()) {\r
81725 list.deselectAll();\r
81726 }\r
81727 } else if (firstList) {\r
81728
81729 me.setLastActiveList(me.getActiveItem());\r
81730 me.setActiveItem(me.getList(node));\r
81731 me.secondList = me.getActiveItem();\r
81732 } else {\r
81733
81734 me.setActiveItem(me.getList(node));\r
81735 me.firstList = me.getActiveItem();\r
81736 }\r
81737 }\r
81738 me.fireEvent('listchange', me, me.getActiveItem());\r
81739 me.setLastNode(node);\r
81740 me.syncToolbar();\r
81741 },\r
81742 \r
81743 goToLeaf: function(node) {\r
81744 if (!node.isLeaf()) {\r
81745 throw new Error('goToLeaf: passed a node which is not a leaf.');\r
81746 }\r
81747 var me = this,\r
81748 card = me.getDetailCard(),\r
81749 container = me.getDetailContainer(),\r
81750 sharedContainer = container === me,\r
81751 layout = me.getLayout(),\r
81752 animation = layout ? layout.getAnimation() : false,\r
81753 activeItem;\r
81754 if (card) {\r
81755 if (container.getItems().indexOf(card) === -1) {\r
81756 container.add(card);\r
81757 }\r
81758 if (sharedContainer) {\r
81759 activeItem = me.getActiveItem();\r
81760 if (activeItem instanceof Ext.dataview.List) {\r
81761 me.setLastActiveList(activeItem);\r
81762 }\r
81763 me.setLastNode(node);\r
81764 }\r
81765 if (animation) {\r
81766 animation.setReverse(false);\r
81767 }\r
81768 container.setActiveItem(card);\r
81769 me.syncToolbar();\r
81770 }\r
81771 },\r
81772 \r
81773 syncToolbar: function(forceDetail) {\r
81774 var me = this,\r
81775 detailCard = me.getDetailCard(),\r
81776 node = me.getLastNode(),\r
81777 detailActive = forceDetail || (detailCard && (me.getActiveItem() == detailCard)),\r
81778 parentNode = (detailActive) ? node : node.parentNode,\r
81779 backButton = me.getBackButton();\r
81780
81781 if (backButton) {\r
81782 var toolbar = me.getToolbar(),\r
81783 splitNavigation = toolbar.getInitialConfig("splitNavigation");\r
81784 if (splitNavigation) {\r
81785 me.$backButtonContainer[parentNode ? 'show' : 'hide']();\r
81786 }\r
81787 backButton[parentNode ? 'show' : 'hide']();\r
81788 if (parentNode && me.getUseTitleAsBackText()) {\r
81789 backButton.setText(me.renderTitleText(node.parentNode, true));\r
81790 }\r
81791 }\r
81792 if (node) {\r
81793 me.setTitle(me.renderTitleText(node));\r
81794 }\r
81795 },\r
81796 updateBackText: function(newText) {\r
81797 this.getBackButton().setText(newText);\r
81798 },\r
81799 \r
81800 goToNodeReverseAnimation: function(node) {\r
81801 var lastNode = this.getLastNode();\r
81802 if (!lastNode) {\r
81803 return false;\r
81804 }\r
81805 return (!lastNode.contains(node) && lastNode.isAncestor(node)) ? true : false;\r
81806 },\r
81807 \r
81808 getList: function(node) {\r
81809 var me = this,\r
81810 treeStore = new Ext.data.NodeStore({\r
81811 recursive: false,\r
81812 node: node,\r
81813 rootVisible: false,\r
81814 model: me.getStore().getModel(),\r
81815 proxy: 'memory'\r
81816 });\r
81817 node.expand();\r
81818 return Ext.Object.merge({\r
81819 xtype: 'list',\r
81820 useSimpleItems: me.getUseSimpleItems(),\r
81821 pressedDelay: 250,\r
81822 autoDestroy: true,\r
81823 store: treeStore,\r
81824 onItemDisclosure: me.getOnItemDisclosure(),\r
81825 allowDeselect: me.getAllowDeselect(),\r
81826 itemHeight: me.getItemHeight(),\r
81827 variableHeights: me.getVariableHeights(),\r
81828 emptyText: me.getEmptyText(),\r
81829 listeners: [\r
81830 {\r
81831 itemdoubletap: 'onItemDoubleTap',\r
81832 itemtap: 'onItemTap',\r
81833 beforeselectionchange: 'onBeforeSelect',\r
81834 containertap: 'onContainerTap',\r
81835 scope: me\r
81836 },\r
81837 {\r
81838 selectionchange: 'onSelectionChange',\r
81839 itemtouchstart: 'onItemInteraction',\r
81840 itemtap: 'onItemInteraction',\r
81841 order: 'before',\r
81842 scope: me\r
81843 }\r
81844 ],\r
81845 itemTpl: '<span<tpl if="leaf == true"> class="x-list-item-leaf"</tpl>>' + me.getItemTextTpl(node) + '</span>'\r
81846 }, me.getListConfig());\r
81847 }\r
81848});\r
81849\r
81850\r
81851Ext.define('Ext.dataview.element.List', {\r
81852 extend: Ext.dataview.element.Container,\r
81853 updateBaseCls: function(newBaseCls) {\r
81854 var me = this;\r
81855 me.itemClsShortCache = newBaseCls + '-item';\r
81856 me.headerClsShortCache = newBaseCls + '-header';\r
81857 me.headerClsCache = '.' + me.headerClsShortCache;\r
81858 me.headerItemClsShortCache = newBaseCls + '-header-item';\r
81859 me.footerClsShortCache = newBaseCls + '-footer-item';\r
81860 me.footerClsCache = '.' + me.footerClsShortCache;\r
81861 me.labelClsShortCache = newBaseCls + '-item-label';\r
81862 me.labelClsCache = '.' + me.labelClsShortCache;\r
81863 me.disclosureClsShortCache = newBaseCls + '-disclosure';\r
81864 me.disclosureClsCache = '.' + me.disclosureClsShortCache;\r
81865 me.iconClsShortCache = newBaseCls + '-icon';\r
81866 me.iconClsCache = '.' + me.iconClsShortCache;\r
81867 this.callParent(arguments);\r
81868 },\r
81869 hiddenDisplayCache: Ext.baseCSSPrefix + 'hidden-display',\r
81870 getItemElementConfig: function(index, data) {\r
81871 var me = this,\r
81872 dataview = me.dataview,\r
81873 itemCls = dataview.getItemCls(),\r
81874 cls = me.itemClsShortCache,\r
81875 config, iconSrc;\r
81876 if (itemCls) {\r
81877 cls += ' ' + itemCls;\r
81878 }\r
81879 config = {\r
81880 cls: cls,\r
81881 children: [\r
81882 {\r
81883 cls: me.labelClsShortCache,\r
81884 html: me.renderItemTpl(index, data)\r
81885 }\r
81886 ]\r
81887 };\r
81888 if (dataview.getIcon()) {\r
81889 iconSrc = data.iconSrc;\r
81890 config.children.push({\r
81891 cls: me.iconClsShortCache,\r
81892 style: 'background-image: ' + iconSrc ? 'url("' + newSrc + '")' : ''\r
81893 });\r
81894 }\r
81895 if (dataview.getOnItemDisclosure()) {\r
81896 config.children.push({\r
81897 cls: me.disclosureClsShortCache + ' ' + ((data[dataview.getDisclosureProperty()] === false) ? me.hiddenDisplayCache : '')\r
81898 });\r
81899 }\r
81900 return config;\r
81901 },\r
81902 updateListItem: function(record, item) {\r
81903 var me = this,\r
81904 dataview = me.dataview,\r
81905 extItem = Ext.fly(item),\r
81906 innerItem = extItem.down(me.labelClsCache, true),\r
81907 store = databiew.getStore(),\r
81908 index = store.indexOf(record),\r
81909 data = dataview.prepareData(record.getData(true), index, record),\r
81910 disclosureProperty = dataview.getDisclosureProperty(),\r
81911 hasDisclosureProperty = data && data.hasOwnProperty(disclosureProperty),\r
81912 iconSrc = data && data.hasOwnProperty('iconSrc'),\r
81913 disclosureEl, iconEl;\r
81914 innerItem.innerHTML = me.renderItemTpl(index, data, store);\r
81915 if (hasDisclosureProperty) {\r
81916 disclosureEl = extItem.down(me.disclosureClsCache);\r
81917 disclosureEl[data[disclosureProperty] === false ? 'addCls' : 'removeCls'](me.hiddenDisplayCache);\r
81918 }\r
81919 if (dataview.getIcon()) {\r
81920 iconEl = extItem.down(me.iconClsCache, true);\r
81921 iconEl.style.backgroundImage = iconSrc ? 'url("' + iconSrc + '")' : '';\r
81922 }\r
81923 },\r
81924 doRemoveHeaders: function() {\r
81925 var me = this,\r
81926 headerClsShortCache = me.headerItemClsShortCache,\r
81927 existingHeaders = me.element.query(me.headerClsCache),\r
81928 existingHeadersLn = existingHeaders.length,\r
81929 i = 0,\r
81930 item;\r
81931 for (; i < existingHeadersLn; i++) {\r
81932 item = existingHeaders[i];\r
81933 Ext.fly(item.parentNode).removeCls(headerClsShortCache);\r
81934 Ext.get(item).destroy();\r
81935 }\r
81936 },\r
81937 doRemoveFooterCls: function() {\r
81938 var me = this,\r
81939 footerClsShortCache = me.footerClsShortCache,\r
81940 existingFooters = me.element.query(me.footerClsCache),\r
81941 existingFootersLn = existingFooters.length,\r
81942 i = 0;\r
81943 for (; i < existingFootersLn; i++) {\r
81944 Ext.fly(existingFooters[i]).removeCls(footerClsShortCache);\r
81945 }\r
81946 },\r
81947 doAddHeader: function(item, html) {\r
81948 item = Ext.fly(item);\r
81949 if (html) {\r
81950 item.insertFirst(Ext.Element.create({\r
81951 cls: this.headerClsShortCache,\r
81952 html: html\r
81953 }));\r
81954 }\r
81955 item.addCls(this.headerItemClsShortCache);\r
81956 },\r
81957 destroy: function() {\r
81958 this.doRemoveHeaders();\r
81959 this.callParent();\r
81960 }\r
81961});\r
81962\r
81963\r
81964Ext.define('Ext.field.Checkbox', {\r
81965 extend: Ext.field.Field,\r
81966 alternateClassName: 'Ext.form.Checkbox',\r
81967 xtype: 'checkboxfield',\r
81968 qsaLeftRe: /[\[]/g,\r
81969 qsaRightRe: /[\]]/g,\r
81970 isCheckbox: true,\r
81971 defaultBindProperty: 'checked',\r
81972 twoWayBindable: {\r
81973 checked: 1\r
81974 },\r
81975 publishes: {\r
81976 checked: 1\r
81977 },\r
81978 \r
81979 \r
81980 \r
81981 config: {\r
81982 \r
81983 ui: 'checkbox',\r
81984 \r
81985 value: '',\r
81986 \r
81987 checked: false,\r
81988 \r
81989 tabIndex: -1,\r
81990 \r
81991 component: {\r
81992 xtype: 'input',\r
81993 type: 'checkbox',\r
81994 useMask: true,\r
81995 cls: Ext.baseCSSPrefix + 'input-checkbox'\r
81996 }\r
81997 },\r
81998 \r
81999 \r
82000 initialize: function() {\r
82001 var me = this,\r
82002 component = me.getComponent();\r
82003 me.callParent();\r
82004 component.on({\r
82005 scope: me,\r
82006 order: 'before',\r
82007 masktap: 'onMaskTap'\r
82008 });\r
82009 component.doMaskTap = Ext.emptyFn;\r
82010 me.label.on({\r
82011 scope: me,\r
82012 tap: 'onMaskTap'\r
82013 });\r
82014
82015
82016
82017
82018 me.publishState('checked', me.getChecked());\r
82019 },\r
82020 \r
82021 doInitValue: function() {\r
82022 var me = this,\r
82023 initialConfig = me.getInitialConfig();\r
82024
82025 if (initialConfig.hasOwnProperty('value')) {\r
82026 me.originalState = initialConfig.value;\r
82027 }\r
82028 if (initialConfig.hasOwnProperty('checked')) {\r
82029 me.originalState = initialConfig.checked;\r
82030 }\r
82031 me.callParent(arguments);\r
82032 },\r
82033 \r
82034 updateInputType: function(newInputType) {\r
82035 var component = this.getComponent();\r
82036 if (component) {\r
82037 component.setType(newInputType);\r
82038 }\r
82039 },\r
82040 \r
82041 updateName: function(newName) {\r
82042 var component = this.getComponent();\r
82043 if (component) {\r
82044 component.setName(newName);\r
82045 }\r
82046 },\r
82047 \r
82048 getSubmitValue: function() {\r
82049 return (this.getChecked()) ? Ext.isEmpty(this._value) ? true : this._value : null;\r
82050 },\r
82051 updateChecked: function(checked, oldChecked) {\r
82052 var me = this,\r
82053 eventName;\r
82054 me.getComponent().setChecked(checked);\r
82055
82056 if (me.initialized) {\r
82057 eventName = checked ? 'check' : 'uncheck';\r
82058 me.fireEvent(eventName, me);\r
82059 me.fireEvent('change', me, checked, oldChecked);\r
82060 }\r
82061 },\r
82062 \r
82063 onMaskTap: function(component, e) {\r
82064 var me = this,\r
82065 dom = me.getComponent().input.dom;\r
82066 if (me.getDisabled()) {\r
82067 return false;\r
82068 }\r
82069
82070 dom.checked = !dom.checked;\r
82071 me.setChecked(dom.checked);\r
82072
82073 return false;\r
82074 },\r
82075 \r
82076 isChecked: function() {\r
82077 return this.getChecked();\r
82078 },\r
82079 \r
82080 check: function() {\r
82081 return this.setChecked(true);\r
82082 },\r
82083 \r
82084 uncheck: function() {\r
82085 return this.setChecked(false);\r
82086 },\r
82087 getSameGroupFields: function() {\r
82088 var me = this,\r
82089 component = me.up('formpanel') || me.up('fieldset'),\r
82090 name = me.getName(),\r
82091 replaceLeft = me.qsaLeftRe,\r
82092 replaceRight = me.qsaRightRe,\r
82093
82094 baseCls = me.getBaseCls().split(' ').join('.'),\r
82095 components = [],\r
82096 elements, element, i, ln;\r
82097 if (!component) {\r
82098
82099 Ext.Logger.warn('Ext.field.Radio components must always be descendants of an Ext.form.Panel or Ext.form.FieldSet.');\r
82100
82101 component = Ext.Viewport;\r
82102 }\r
82103
82104 name = name.replace(replaceLeft, '\\[');\r
82105 name = name.replace(replaceRight, '\\]');\r
82106 elements = Ext.query('[name=' + name + ']', component.element.dom);\r
82107 ln = elements.length;\r
82108 for (i = 0; i < ln; i++) {\r
82109 element = elements[i];\r
82110 element = Ext.fly(element).up('.' + baseCls);\r
82111 if (element && element.id) {\r
82112 components.push(Ext.getCmp(element.id));\r
82113 }\r
82114 }\r
82115 return components;\r
82116 },\r
82117 \r
82118 getGroupValues: function() {\r
82119 var values = [];\r
82120 this.getSameGroupFields().forEach(function(field) {\r
82121 if (field.getChecked()) {\r
82122 values.push(field.getValue());\r
82123 }\r
82124 });\r
82125 return values;\r
82126 },\r
82127 \r
82128 setGroupValues: function(values) {\r
82129 this.getSameGroupFields().forEach(function(field) {\r
82130 field.setChecked((values.indexOf(field.getValue()) !== -1));\r
82131 });\r
82132 return this;\r
82133 },\r
82134 \r
82135 resetGroupValues: function() {\r
82136 this.getSameGroupFields().forEach(function(field) {\r
82137 field.setChecked(field.originalState);\r
82138 });\r
82139 return this;\r
82140 },\r
82141 reset: function() {\r
82142 this.setChecked(this.originalState);\r
82143 return this;\r
82144 }\r
82145});\r
82146\r
82147\r
82148Ext.define('Ext.field.Picker', {\r
82149 extend: Ext.field.Text,\r
82150 config: {\r
82151 \r
82152 component: {\r
82153 useMask: true\r
82154 },\r
82155 \r
82156 clearIcon: false,\r
82157 \r
82158 usePicker: 'auto',\r
82159 \r
82160 defaultPhonePickerConfig: null,\r
82161 \r
82162 defaultTabletPickerConfig: null,\r
82163 \r
82164 pickerSlotAlign: 'center'\r
82165 },\r
82166 \r
82167 initialize: function() {\r
82168 var me = this,\r
82169 component = me.getComponent();\r
82170 me.callParent();\r
82171 component.on({\r
82172 scope: me,\r
82173 masktap: 'onMaskTap'\r
82174 });\r
82175 component.doMaskTap = Ext.emptyFn;\r
82176 },\r
82177 \r
82178 updateDefaultPhonePickerConfig: function(newConfig) {\r
82179 var phonePicker = this.phonePicker;\r
82180 if (phonePicker) {\r
82181 phonePicker.setConfig(newConfig);\r
82182 }\r
82183 },\r
82184 \r
82185 updateDefaultTabletPickerConfig: function(newConfig) {\r
82186 var tabletPicker = this.tabletPicker;\r
82187 if (tabletPicker) {\r
82188 tabletPicker.setConfig(newConfig);\r
82189 }\r
82190 },\r
82191 \r
82192 applyUsePicker: function(usePicker) {\r
82193 if (usePicker === 'auto') {\r
82194 usePicker = Ext.os.deviceType === 'Phone';\r
82195 }\r
82196 return Boolean(usePicker);\r
82197 },\r
82198 syncEmptyCls: Ext.emptyFn,\r
82199 \r
82200 onMaskTap: function() {\r
82201 if (!this.getDisabled()) {\r
82202 this.onFocus();\r
82203 }\r
82204 return false;\r
82205 },\r
82206 \r
82207 updateDisabled: function(disabled) {\r
82208 var component = this.getComponent();\r
82209 if (component) {\r
82210 component.setDisabled(disabled);\r
82211 }\r
82212 Ext.Component.prototype.updateDisabled.apply(this, arguments);\r
82213 },\r
82214 \r
82215 setDisabled: function() {\r
82216 Ext.Component.prototype.setDisabled.apply(this, arguments);\r
82217 },\r
82218 onFocus: function(e) {\r
82219 if (this.getDisabled()) {\r
82220 return false;\r
82221 }\r
82222 var component = this.getComponent();\r
82223 this.fireEvent('focus', this, e);\r
82224 if (Ext.os.is.Android4) {\r
82225 component.input.dom.focus();\r
82226 }\r
82227 component.input.dom.blur();\r
82228 this.isFocused = true;\r
82229 this.showPicker();\r
82230 },\r
82231 destroy: function() {\r
82232 var me = this;\r
82233 me.callParent();\r
82234 me.tabletPicker = me.phonePicker = Ext.destroy(me.tabletPicker, me.phonePicker);\r
82235 }\r
82236});\r
82237\r
82238\r
82239Ext.define('Ext.picker.Slot', {\r
82240 extend: Ext.dataview.DataView,\r
82241 xtype: 'pickerslot',\r
82242 \r
82243 isSlot: true,\r
82244 config: {\r
82245 \r
82246 title: null,\r
82247 \r
82248 showTitle: true,\r
82249 \r
82250 cls: Ext.baseCSSPrefix + 'picker-slot',\r
82251 \r
82252 name: null,\r
82253 \r
82254 value: null,\r
82255 \r
82256 flex: 1,\r
82257 \r
82258 align: 'left',\r
82259 \r
82260 displayField: 'text',\r
82261 \r
82262 valueField: 'value',\r
82263 \r
82264 itemTpl: null,\r
82265 \r
82266 scrollable: {\r
82267 x: false,\r
82268 indicators: false,\r
82269 momentumEasing: {\r
82270 minVelocity: 2\r
82271 },\r
82272 slotSnapEasing: {\r
82273 duration: 100\r
82274 }\r
82275 },\r
82276 \r
82277 verticallyCenterItems: true\r
82278 },\r
82279 constructor: function() {\r
82280 \r
82281 this.selectedIndex = 0;\r
82282 \r
82283 this.callParent(arguments);\r
82284 },\r
82285 \r
82286 applyTitle: function(title) {\r
82287
82288 if (title) {\r
82289
82290 title = Ext.create('Ext.Component', {\r
82291 cls: Ext.baseCSSPrefix + 'picker-slot-title',\r
82292 docked: 'top',\r
82293 html: title\r
82294 });\r
82295 }\r
82296 return title;\r
82297 },\r
82298 updateTitle: function(newTitle, oldTitle) {\r
82299 if (newTitle) {\r
82300 this.add(newTitle);\r
82301 this.setupBar();\r
82302 }\r
82303 if (oldTitle) {\r
82304 this.remove(oldTitle);\r
82305 }\r
82306 },\r
82307 updateShowTitle: function(showTitle) {\r
82308 var title = this.getTitle(),\r
82309 mode = showTitle ? 'show' : 'hide';\r
82310 if (title) {\r
82311 title.on(mode, this.setupBar, this, {\r
82312 single: true,\r
82313 delay: 50\r
82314 });\r
82315 title[showTitle ? 'show' : 'hide']();\r
82316 }\r
82317 },\r
82318 updateDisplayField: function(newDisplayField) {\r
82319 if (!this.config.itemTpl) {\r
82320 this.setItemTpl('<div class="' + Ext.baseCSSPrefix + 'picker-item {cls} <tpl if="extra">' + Ext.baseCSSPrefix + 'picker-invalid</tpl>">{' + newDisplayField + '}</div>');\r
82321 }\r
82322 },\r
82323 \r
82324 updateAlign: function(newAlign, oldAlign) {\r
82325 var element = this.element;\r
82326 element.addCls(Ext.baseCSSPrefix + 'picker-' + newAlign);\r
82327 element.removeCls(Ext.baseCSSPrefix + 'picker-' + oldAlign);\r
82328 },\r
82329 \r
82330 applyData: function(data) {\r
82331 var parsedData = [],\r
82332 ln = data && data.length,\r
82333 i, item, obj;\r
82334 if (data && Ext.isArray(data) && ln) {\r
82335 for (i = 0; i < ln; i++) {\r
82336 item = data[i];\r
82337 obj = {};\r
82338 if (Ext.isArray(item)) {\r
82339 obj[this.valueField] = item[0];\r
82340 obj[this.displayField] = item[1];\r
82341 } else if (Ext.isString(item)) {\r
82342 obj[this.valueField] = item;\r
82343 obj[this.displayField] = item;\r
82344 } else if (Ext.isObject(item)) {\r
82345 obj = item;\r
82346 }\r
82347 parsedData.push(obj);\r
82348 }\r
82349 }\r
82350 return data;\r
82351 },\r
82352 \r
82353 initialize: function() {\r
82354 this.callParent();\r
82355 var scroller = this.getScrollable();\r
82356 this.on({\r
82357 scope: this,\r
82358 painted: 'onPainted',\r
82359 itemtap: 'doItemTap'\r
82360 });\r
82361 this.element.on({\r
82362 scope: this,\r
82363 touchstart: 'onTouchStart',\r
82364 touchend: 'onTouchEnd'\r
82365 });\r
82366 scroller.on({\r
82367 scope: this,\r
82368 scrollend: 'onScrollEnd'\r
82369 });\r
82370 },\r
82371 \r
82372 onPainted: function() {\r
82373 this.setupBar();\r
82374 },\r
82375 \r
82376 getPicker: function() {\r
82377 if (!this.picker) {\r
82378 this.picker = this.getParent();\r
82379 }\r
82380 return this.picker;\r
82381 },\r
82382 \r
82383 setupBar: function() {\r
82384 if (!this.rendered) {\r
82385
82386 return;\r
82387 }\r
82388 var element = this.element,\r
82389 containerElement = this.container.element,\r
82390 picker = this.getPicker(),\r
82391 bar = picker.bar,\r
82392 value = this.getValue(),\r
82393 showTitle = this.getShowTitle(),\r
82394 title = this.getTitle(),\r
82395 scroller = this.getScrollable(),\r
82396 titleHeight = 0,\r
82397 barHeight, padding;\r
82398 barHeight = bar.dom.getBoundingClientRect().height;\r
82399 if (showTitle && title) {\r
82400 titleHeight = title.element.getHeight();\r
82401 }\r
82402 padding = Math.ceil((element.getHeight() - titleHeight - barHeight) / 2);\r
82403 if (this.getVerticallyCenterItems()) {\r
82404 containerElement.setStyle({\r
82405 padding: padding + 'px 0 ' + padding + 'px'\r
82406 });\r
82407 }\r
82408 scroller.refresh();\r
82409 scroller.setSlotSnapSize(barHeight);\r
82410 this.setValue(value);\r
82411 },\r
82412 \r
82413 doItemTap: function(list, index, item, e) {\r
82414 var me = this;\r
82415 me.selectedIndex = index;\r
82416 me.selectedNode = item;\r
82417 me.scrollToItem(item, true);\r
82418 },\r
82419 \r
82420 scrollToItem: function(item, animated) {\r
82421 var y = item.getY(),\r
82422 parentEl = item.parent(),\r
82423 parentY = parentEl.getY(),\r
82424 scroller = this.getScrollable(),\r
82425 difference;\r
82426 difference = y - parentY;\r
82427 scroller.scrollTo(0, difference, animated);\r
82428 },\r
82429 \r
82430 onTouchStart: function() {\r
82431 this.element.addCls(Ext.baseCSSPrefix + 'scrolling');\r
82432 },\r
82433 \r
82434 onTouchEnd: function() {\r
82435 this.element.removeCls(Ext.baseCSSPrefix + 'scrolling');\r
82436 },\r
82437 \r
82438 onScrollEnd: function(scroller, x, y) {\r
82439 var me = this,\r
82440 index = Math.round(y / me.picker.bar.dom.getBoundingClientRect().height),\r
82441 viewItems = me.getViewItems(),\r
82442 item = viewItems[index];\r
82443 if (item) {\r
82444 me.selectedIndex = index;\r
82445 me.selectedNode = item;\r
82446 me.fireEvent('slotpick', me, me.getValue(), me.selectedNode);\r
82447 }\r
82448 },\r
82449 \r
82450 getValue: function(useDom) {\r
82451 var store = this.getStore(),\r
82452 record, value;\r
82453 if (!store) {\r
82454 return;\r
82455 }\r
82456 if (!this.rendered || !useDom) {\r
82457 return this._value;\r
82458 }\r
82459
82460 if (this._value === false) {\r
82461 return null;\r
82462 }\r
82463 record = store.getAt(this.selectedIndex);\r
82464 value = record ? record.get(this.getValueField()) : null;\r
82465 return value;\r
82466 },\r
82467 \r
82468 setValue: function(value) {\r
82469 return this.doSetValue(value);\r
82470 },\r
82471 \r
82472 setValueAnimated: function(value) {\r
82473 return this.doSetValue(value, true);\r
82474 },\r
82475 doSetValue: function(value, animated) {\r
82476 if (!this.rendered) {\r
82477
82478 this._value = value;\r
82479 return;\r
82480 }\r
82481 var store = this.getStore(),\r
82482 viewItems = this.getViewItems(),\r
82483 valueField = this.getValueField(),\r
82484 index, item;\r
82485 index = store.findExact(valueField, value);\r
82486 if (index == -1) {\r
82487 index = 0;\r
82488 }\r
82489 item = Ext.get(viewItems[index]);\r
82490 this.selectedIndex = index;\r
82491 if (item) {\r
82492 this.scrollToItem(item, (animated) ? {\r
82493 duration: 100\r
82494 } : false);\r
82495 this.select(this.selectedIndex);\r
82496 }\r
82497 this._value = value;\r
82498 }\r
82499});\r
82500\r
82501\r
82502Ext.define('Ext.picker.Picker', {\r
82503 extend: Ext.Sheet,\r
82504 alias: 'widget.picker',\r
82505 alternateClassName: 'Ext.Picker',\r
82506 isPicker: true,\r
82507 \r
82508 \r
82509 \r
82510 config: {\r
82511 \r
82512 baseCls: Ext.baseCSSPrefix + 'picker',\r
82513 \r
82514 doneButton: true,\r
82515 \r
82516 cancelButton: true,\r
82517 \r
82518 useTitles: false,\r
82519 \r
82520 slots: null,\r
82521 \r
82522 value: null,\r
82523 \r
82524 height: 220,\r
82525 \r
82526 layout: {\r
82527 type: 'hbox',\r
82528 align: 'stretch'\r
82529 },\r
82530 \r
82531 centered: false,\r
82532 \r
82533 left: 0,\r
82534 \r
82535 right: 0,\r
82536 \r
82537 bottom: 0,\r
82538 \r
82539 defaultType: 'pickerslot',\r
82540 toolbarPosition: 'top',\r
82541 \r
82542 toolbar: {\r
82543 xtype: 'titlebar'\r
82544 }\r
82545 },\r
82546 initialize: function() {\r
82547 var me = this,\r
82548 clsPrefix = Ext.baseCSSPrefix,\r
82549 innerElement = this.innerElement;\r
82550
82551 this.mask = innerElement.createChild({\r
82552 cls: clsPrefix + 'picker-mask'\r
82553 });\r
82554 this.bar = this.mask.createChild({\r
82555 cls: clsPrefix + 'picker-bar'\r
82556 });\r
82557 me.on({\r
82558 scope: this,\r
82559 delegate: 'pickerslot',\r
82560 slotpick: 'onSlotPick'\r
82561 });\r
82562 },\r
82563 \r
82564 applyToolbar: function(config) {\r
82565 if (config === true) {\r
82566 config = {};\r
82567 }\r
82568 Ext.applyIf(config, {\r
82569 docked: this.getToolbarPosition()\r
82570 });\r
82571 return Ext.factory(config, 'Ext.TitleBar', this.getToolbar());\r
82572 },\r
82573 \r
82574 updateToolbar: function(newToolbar, oldToolbar) {\r
82575 if (newToolbar) {\r
82576 this.add(newToolbar);\r
82577 }\r
82578 if (oldToolbar) {\r
82579 this.remove(oldToolbar);\r
82580 }\r
82581 },\r
82582 \r
82583 applyDoneButton: function(config) {\r
82584 if (config) {\r
82585 if (Ext.isBoolean(config)) {\r
82586 config = {};\r
82587 }\r
82588 if (typeof config == "string") {\r
82589 config = {\r
82590 text: config\r
82591 };\r
82592 }\r
82593 Ext.applyIf(config, {\r
82594 ui: 'action',\r
82595 align: 'right',\r
82596 text: 'Done'\r
82597 });\r
82598 }\r
82599 return Ext.factory(config, 'Ext.Button', this.getDoneButton());\r
82600 },\r
82601 updateDoneButton: function(newDoneButton, oldDoneButton) {\r
82602 var toolbar = this.getToolbar();\r
82603 if (newDoneButton) {\r
82604 toolbar.add(newDoneButton);\r
82605 newDoneButton.on('tap', this.onDoneButtonTap, this);\r
82606 } else if (oldDoneButton) {\r
82607 toolbar.remove(oldDoneButton);\r
82608 }\r
82609 },\r
82610 \r
82611 applyCancelButton: function(config) {\r
82612 if (config) {\r
82613 if (Ext.isBoolean(config)) {\r
82614 config = {};\r
82615 }\r
82616 if (typeof config == "string") {\r
82617 config = {\r
82618 text: config\r
82619 };\r
82620 }\r
82621 Ext.applyIf(config, {\r
82622 align: 'left',\r
82623 text: 'Cancel'\r
82624 });\r
82625 }\r
82626 return Ext.factory(config, 'Ext.Button', this.getCancelButton());\r
82627 },\r
82628 updateCancelButton: function(newCancelButton, oldCancelButton) {\r
82629 var toolbar = this.getToolbar();\r
82630 if (newCancelButton) {\r
82631 toolbar.add(newCancelButton);\r
82632 newCancelButton.on('tap', this.onCancelButtonTap, this);\r
82633 } else if (oldCancelButton) {\r
82634 toolbar.remove(oldCancelButton);\r
82635 }\r
82636 },\r
82637 \r
82638 updateUseTitles: function(useTitles) {\r
82639 var innerItems = this.getInnerItems(),\r
82640 ln = innerItems.length,\r
82641 cls = Ext.baseCSSPrefix + 'use-titles',\r
82642 i, innerItem;\r
82643
82644 if (useTitles) {\r
82645 this.addCls(cls);\r
82646 } else {\r
82647 this.removeCls(cls);\r
82648 }\r
82649
82650 for (i = 0; i < ln; i++) {\r
82651 innerItem = innerItems[i];\r
82652 if (innerItem.isSlot) {\r
82653 innerItem.setShowTitle(useTitles);\r
82654 }\r
82655 }\r
82656 },\r
82657 applySlots: function(slots) {\r
82658
82659 if (slots) {\r
82660 var ln = slots.length,\r
82661 i;\r
82662 for (i = 0; i < ln; i++) {\r
82663 slots[i].picker = this;\r
82664 }\r
82665 }\r
82666 return slots;\r
82667 },\r
82668 \r
82669 updateSlots: function(newSlots) {\r
82670 var bcss = Ext.baseCSSPrefix,\r
82671 innerItems;\r
82672 this.removeAll();\r
82673 if (newSlots) {\r
82674 this.add(newSlots);\r
82675 }\r
82676 innerItems = this.getInnerItems();\r
82677 if (innerItems.length > 0) {\r
82678 innerItems[0].addCls(bcss + 'first');\r
82679 innerItems[innerItems.length - 1].addCls(bcss + 'last');\r
82680 }\r
82681 this.updateUseTitles(this.getUseTitles());\r
82682 },\r
82683 \r
82684 onDoneButtonTap: function() {\r
82685 var oldValue = this._value,\r
82686 newValue = this.getValue(true);\r
82687 if (newValue != oldValue) {\r
82688 this.fireEvent('change', this, newValue);\r
82689 }\r
82690 this.hide();\r
82691 Ext.util.InputBlocker.unblockInputs();\r
82692 },\r
82693 \r
82694 onCancelButtonTap: function() {\r
82695 this.fireEvent('cancel', this);\r
82696 this.hide();\r
82697 Ext.util.InputBlocker.unblockInputs();\r
82698 },\r
82699 \r
82700 onSlotPick: function(slot) {\r
82701 this.fireEvent('pick', this, this.getValue(true), slot);\r
82702 },\r
82703 show: function() {\r
82704 if (this.getParent() === undefined) {\r
82705 Ext.Viewport.add(this);\r
82706 }\r
82707 this.callParent(arguments);\r
82708 if (!this.isHidden()) {\r
82709 this.setValue(this._value);\r
82710 }\r
82711 Ext.util.InputBlocker.blockInputs();\r
82712 },\r
82713 \r
82714 setValue: function(values, animated) {\r
82715 var me = this,\r
82716 slots = me.getInnerItems(),\r
82717 ln = slots.length,\r
82718 key, slot, loopSlot, i, value;\r
82719 if (!values) {\r
82720 values = {};\r
82721 for (i = 0; i < ln; i++) {\r
82722
82723 values[slots[i].config.name] = null;\r
82724 }\r
82725 }\r
82726 for (key in values) {\r
82727 slot = null;\r
82728 value = values[key];\r
82729 for (i = 0; i < slots.length; i++) {\r
82730 loopSlot = slots[i];\r
82731 if (loopSlot.config.name == key) {\r
82732 slot = loopSlot;\r
82733 break;\r
82734 }\r
82735 }\r
82736 if (slot) {\r
82737 if (animated) {\r
82738 slot.setValueAnimated(value);\r
82739 } else {\r
82740 slot.setValue(value);\r
82741 }\r
82742 }\r
82743 }\r
82744 me._values = me._value = values;\r
82745 return me;\r
82746 },\r
82747 setValueAnimated: function(values) {\r
82748 this.setValue(values, true);\r
82749 },\r
82750 \r
82751 getValue: function(useDom) {\r
82752 var values = {},\r
82753 items = this.getItems().items,\r
82754 ln = items.length,\r
82755 item, i;\r
82756 if (useDom) {\r
82757 for (i = 0; i < ln; i++) {\r
82758 item = items[i];\r
82759 if (item && item.isSlot) {\r
82760 values[item.getName()] = item.getValue(useDom);\r
82761 }\r
82762 }\r
82763 this._values = values;\r
82764 }\r
82765 return this._values;\r
82766 },\r
82767 \r
82768 getValues: function() {\r
82769 return this.getValue();\r
82770 },\r
82771 destroy: function() {\r
82772 var me = this;\r
82773 me.callParent();\r
82774 me.mask = me.bar = Ext.destroy(me.mask, me.bar);\r
82775 }\r
82776});\r
82777\r
82778\r
82779Ext.define('Ext.picker.Date', {\r
82780 extend: Ext.picker.Picker,\r
82781 xtype: 'datepicker',\r
82782 alternateClassName: 'Ext.DatePicker',\r
82783 \r
82784 config: {\r
82785 \r
82786 yearFrom: 1980,\r
82787 \r
82788 yearTo: new Date().getFullYear(),\r
82789 \r
82790 monthText: 'Month',\r
82791 \r
82792 dayText: 'Day',\r
82793 \r
82794 yearText: 'Year',\r
82795 \r
82796 slotOrder: [\r
82797 'month',\r
82798 'day',\r
82799 'year'\r
82800 ],\r
82801 \r
82802 \r
82803 \r
82804 doneButton: true\r
82805 },\r
82806 initialize: function() {\r
82807 this.callParent();\r
82808 this.on({\r
82809 scope: this,\r
82810 delegate: '> slot',\r
82811 slotpick: this.onSlotPick\r
82812 });\r
82813 this.on({\r
82814 scope: this,\r
82815 show: this.onSlotPick\r
82816 });\r
82817 },\r
82818 setValue: function(value, animated) {\r
82819 if (Ext.isDate(value)) {\r
82820 value = {\r
82821 day: value.getDate(),\r
82822 month: value.getMonth() + 1,\r
82823 year: value.getFullYear()\r
82824 };\r
82825 }\r
82826 this.callParent([\r
82827 value,\r
82828 animated\r
82829 ]);\r
82830 this.onSlotPick();\r
82831 },\r
82832 getValue: function(useDom) {\r
82833 var values = {},\r
82834 items = this.getItems().items,\r
82835 ln = items.length,\r
82836 daysInMonth, day, month, year, item, i;\r
82837 for (i = 0; i < ln; i++) {\r
82838 item = items[i];\r
82839 if (item instanceof Ext.picker.Slot) {\r
82840 values[item.getName()] = item.getValue(useDom);\r
82841 }\r
82842 }\r
82843
82844 if (values.year === null && values.month === null && values.day === null) {\r
82845 return null;\r
82846 }\r
82847 year = Ext.isNumber(values.year) ? values.year : 1;\r
82848 month = Ext.isNumber(values.month) ? values.month : 1;\r
82849 day = Ext.isNumber(values.day) ? values.day : 1;\r
82850 if (month && year && month && day) {\r
82851 daysInMonth = this.getDaysInMonth(month, year);\r
82852 }\r
82853 day = (daysInMonth) ? Math.min(day, daysInMonth) : day;\r
82854 return new Date(year, month - 1, day);\r
82855 },\r
82856 \r
82857 updateYearFrom: function() {\r
82858 if (this.initialized) {\r
82859 this.createSlots();\r
82860 }\r
82861 },\r
82862 \r
82863 updateYearTo: function() {\r
82864 if (this.initialized) {\r
82865 this.createSlots();\r
82866 }\r
82867 },\r
82868 \r
82869 updateMonthText: function(newMonthText, oldMonthText) {\r
82870 var innerItems = this.getInnerItems,\r
82871 ln = innerItems.length,\r
82872 item, i;\r
82873
82874 if (this.initialized) {\r
82875 for (i = 0; i < ln; i++) {\r
82876 item = innerItems[i];\r
82877 if ((typeof item.title == "string" && item.title == oldMonthText) || (item.title.html == oldMonthText)) {\r
82878 item.setTitle(newMonthText);\r
82879 }\r
82880 }\r
82881 }\r
82882 },\r
82883 \r
82884 updateDayText: function(newDayText, oldDayText) {\r
82885 var innerItems = this.getInnerItems,\r
82886 ln = innerItems.length,\r
82887 item, i;\r
82888
82889 if (this.initialized) {\r
82890 for (i = 0; i < ln; i++) {\r
82891 item = innerItems[i];\r
82892 if ((typeof item.title == "string" && item.title == oldDayText) || (item.title.html == oldDayText)) {\r
82893 item.setTitle(newDayText);\r
82894 }\r
82895 }\r
82896 }\r
82897 },\r
82898 \r
82899 updateYearText: function(yearText) {\r
82900 var innerItems = this.getInnerItems,\r
82901 ln = innerItems.length,\r
82902 item, i;\r
82903
82904 if (this.initialized) {\r
82905 for (i = 0; i < ln; i++) {\r
82906 item = innerItems[i];\r
82907 if (item.title == this.yearText) {\r
82908 item.setTitle(yearText);\r
82909 }\r
82910 }\r
82911 }\r
82912 },\r
82913 \r
82914 constructor: function() {\r
82915 this.callParent(arguments);\r
82916 this.createSlots();\r
82917 },\r
82918 \r
82919 createSlots: function() {\r
82920 var me = this,\r
82921 slotOrder = me.getSlotOrder(),\r
82922 yearsFrom = me.getYearFrom(),\r
82923 yearsTo = me.getYearTo(),\r
82924 years = [],\r
82925 days = [],\r
82926 months = [],\r
82927 reverse = yearsFrom > yearsTo,\r
82928 ln, i, daysInMonth;\r
82929 while (yearsFrom) {\r
82930 years.push({\r
82931 text: yearsFrom,\r
82932 value: yearsFrom\r
82933 });\r
82934 if (yearsFrom === yearsTo) {\r
82935 break;\r
82936 }\r
82937 if (reverse) {\r
82938 yearsFrom--;\r
82939 } else {\r
82940 yearsFrom++;\r
82941 }\r
82942 }\r
82943 daysInMonth = me.getDaysInMonth(1, new Date().getFullYear());\r
82944 for (i = 0; i < daysInMonth; i++) {\r
82945 days.push({\r
82946 text: i + 1,\r
82947 value: i + 1\r
82948 });\r
82949 }\r
82950 for (i = 0 , ln = Ext.Date.monthNames.length; i < ln; i++) {\r
82951 months.push({\r
82952 text: Ext.Date.monthNames[i],\r
82953 value: i + 1\r
82954 });\r
82955 }\r
82956 var slots = [];\r
82957 slotOrder.forEach(function(item) {\r
82958 slots.push(me.createSlot(item, days, months, years));\r
82959 });\r
82960 me.setSlots(slots);\r
82961 },\r
82962 \r
82963 createSlot: function(name, days, months, years) {\r
82964 switch (name) {\r
82965 case 'year':\r
82966 return {\r
82967 name: 'year',\r
82968 align: 'center',\r
82969 data: years,\r
82970 title: this.getYearText(),\r
82971 flex: 3\r
82972 };\r
82973 case 'month':\r
82974 return {\r
82975 name: name,\r
82976 align: 'right',\r
82977 data: months,\r
82978 title: this.getMonthText(),\r
82979 flex: 4\r
82980 };\r
82981 case 'day':\r
82982 return {\r
82983 name: 'day',\r
82984 align: 'center',\r
82985 data: days,\r
82986 title: this.getDayText(),\r
82987 flex: 2\r
82988 };\r
82989 }\r
82990 },\r
82991 onSlotPick: function() {\r
82992 var value = this.getValue(true),\r
82993 slot = this.getDaySlot(),\r
82994 year = value.getFullYear(),\r
82995 month = value.getMonth(),\r
82996 days = [],\r
82997 daysInMonth, i;\r
82998 if (!value || !Ext.isDate(value) || !slot) {\r
82999 return;\r
83000 }\r
83001 this.callParent(arguments);\r
83002
83003 daysInMonth = this.getDaysInMonth(month + 1, year);\r
83004 for (i = 0; i < daysInMonth; i++) {\r
83005 days.push({\r
83006 text: i + 1,\r
83007 value: i + 1\r
83008 });\r
83009 }\r
83010
83011 if (slot.getStore().getCount() == days.length) {\r
83012 return;\r
83013 }\r
83014 slot.getStore().setData(days);\r
83015
83016 var store = slot.getStore(),\r
83017 viewItems = slot.getViewItems(),\r
83018 valueField = slot.getValueField(),\r
83019 index, item;\r
83020 index = store.find(valueField, value.getDate());\r
83021 if (index == -1) {\r
83022 return;\r
83023 }\r
83024 item = Ext.get(viewItems[index]);\r
83025 slot.selectedIndex = index;\r
83026 slot.scrollToItem(item);\r
83027 slot.setValue(slot.getValue(true));\r
83028 },\r
83029 getDaySlot: function() {\r
83030 var innerItems = this.getInnerItems(),\r
83031 ln = innerItems.length,\r
83032 i, slot;\r
83033 if (this.daySlot) {\r
83034 return this.daySlot;\r
83035 }\r
83036 for (i = 0; i < ln; i++) {\r
83037 slot = innerItems[i];\r
83038 if (slot.isSlot && slot.getName() == "day") {\r
83039 this.daySlot = slot;\r
83040 return slot;\r
83041 }\r
83042 }\r
83043 return null;\r
83044 },\r
83045 \r
83046 getDaysInMonth: function(month, year) {\r
83047 var daysInMonth = [\r
83048 31,\r
83049 28,\r
83050 31,\r
83051 30,\r
83052 31,\r
83053 30,\r
83054 31,\r
83055 31,\r
83056 30,\r
83057 31,\r
83058 30,\r
83059 31\r
83060 ];\r
83061 return month == 2 && this.isLeapYear(year) ? 29 : daysInMonth[month - 1];\r
83062 },\r
83063 \r
83064 isLeapYear: function(year) {\r
83065 return !!((year & 3) === 0 && (year % 100 || (year % 400 === 0 && year)));\r
83066 },\r
83067 onDoneButtonTap: function() {\r
83068 var oldValue = this._value,\r
83069 newValue = this.getValue(true),\r
83070 testValue = newValue;\r
83071 if (Ext.isDate(newValue)) {\r
83072 testValue = newValue.toDateString();\r
83073 }\r
83074 if (Ext.isDate(oldValue)) {\r
83075 oldValue = oldValue.toDateString();\r
83076 }\r
83077 if (testValue != oldValue) {\r
83078 this.fireEvent('change', this, newValue);\r
83079 }\r
83080 this.hide();\r
83081 Ext.util.InputBlocker.unblockInputs();\r
83082 }\r
83083});\r
83084\r
83085\r
83086Ext.define('Ext.field.DatePicker', {\r
83087 extend: Ext.field.Picker,\r
83088 alternateClassName: 'Ext.form.DatePicker',\r
83089 xtype: 'datepickerfield',\r
83090 \r
83091 config: {\r
83092 ui: 'select',\r
83093 \r
83094 picker: true,\r
83095 \r
83096 \r
83097 destroyPickerOnHide: false,\r
83098 \r
83099 dateFormat: ''\r
83100 },\r
83101 applyValue: function(value, oldValue) {\r
83102 if (!Ext.isDate(value)) {\r
83103 if (value) {\r
83104 value = Ext.Date.parse(value, this.getDateFormat());\r
83105 } else {\r
83106 value = null;\r
83107 }\r
83108 }\r
83109
83110
83111
83112 if (value && oldValue && value.getTime() === oldValue.getTime()) {\r
83113 value = undefined;\r
83114 }\r
83115 return value;\r
83116 },\r
83117 updateValue: function(value, oldValue) {\r
83118 var me = this,\r
83119 picker = me._picker;\r
83120 if (picker && picker.isPicker) {\r
83121 picker.setValue(value);\r
83122 }\r
83123
83124 if (value !== null) {\r
83125 me.getComponent().setValue(Ext.Date.format(value, me.getDateFormat()));\r
83126 } else {\r
83127 me.getComponent().setValue('');\r
83128 }\r
83129 me.fireEvent('change', me, value, oldValue);\r
83130 },\r
83131 applyDateFormat: function(dateFormat) {\r
83132 return dateFormat || Ext.util.Format.defaultDateFormat;\r
83133 },\r
83134 \r
83135 updateDateFormat: function(newDateFormat) {\r
83136 var value = this.getValue();\r
83137 if (Ext.isDate(value)) {\r
83138 this.getComponent().setValue(Ext.Date.format(value, newDateFormat));\r
83139 }\r
83140 },\r
83141 \r
83142 \r
83143 getFormattedValue: function(format) {\r
83144 var value = this.getValue();\r
83145 return Ext.isDate(value) ? Ext.Date.format(value, format || this.getDateFormat()) : '';\r
83146 },\r
83147 applyPicker: function(picker, pickerInstance) {\r
83148 if (pickerInstance && pickerInstance.isPicker) {\r
83149 picker = pickerInstance.setConfig(picker);\r
83150 }\r
83151 return picker;\r
83152 },\r
83153 getPicker: function() {\r
83154 var picker = this._picker,\r
83155 value = this.getValue();\r
83156 if (picker && !picker.isPicker) {\r
83157 picker = Ext.factory(picker, Ext.picker.Date);\r
83158 if (value !== null) {\r
83159 picker.setValue(value);\r
83160 }\r
83161 }\r
83162 picker.on({\r
83163 scope: this,\r
83164 change: 'onPickerChange',\r
83165 hide: 'onPickerHide'\r
83166 });\r
83167 this._picker = picker;\r
83168 return picker;\r
83169 },\r
83170 \r
83171 onPickerChange: function(picker, value) {\r
83172 var me = this,\r
83173 oldValue = me.getValue();\r
83174 me.setValue(value);\r
83175 me.fireEvent('select', me, value);\r
83176 },\r
83177 \r
83178 onPickerHide: function() {\r
83179 var me = this,\r
83180 picker = me.getPicker();\r
83181 if (me.getDestroyPickerOnHide() && picker) {\r
83182 picker.destroy();\r
83183 me._picker = me.getInitialConfig().picker || true;\r
83184 }\r
83185 },\r
83186 reset: function() {\r
83187 this.setValue(this.originalValue);\r
83188 },\r
83189 onFocus: function(e) {\r
83190 var component = this.getComponent();\r
83191 this.fireEvent('focus', this, e);\r
83192 if (Ext.os.is.Android4) {\r
83193 component.input.dom.focus();\r
83194 }\r
83195 component.input.dom.blur();\r
83196 if (this.getReadOnly()) {\r
83197 return false;\r
83198 }\r
83199 this.isFocused = true;\r
83200 this.getPicker().show();\r
83201 },\r
83202 \r
83203 destroy: function() {\r
83204 var picker = this._picker;\r
83205 if (picker && picker.isPicker) {\r
83206 picker.destroy();\r
83207 }\r
83208 this.callParent();\r
83209 }\r
83210});\r
83211\r
83212\r
83213Ext.define('Ext.field.DatePickerNative', {\r
83214 extend: Ext.field.DatePicker,\r
83215 alternateClassName: 'Ext.form.DatePickerNative',\r
83216 xtype: 'datepickernativefield',\r
83217 initialize: function() {\r
83218 this.callParent();\r
83219 },\r
83220 onFocus: function(e) {\r
83221 var me = this;\r
83222 if (!(navigator.plugins && navigator.plugins.dateTimePicker)) {\r
83223 me.callParent();\r
83224 return;\r
83225 }\r
83226 var success = function(res) {\r
83227 me.setValue(res);\r
83228 };\r
83229 var fail = function(e) {\r
83230 console.log("DateTimePicker: error occurred or cancelled: " + e);\r
83231 };\r
83232 try {\r
83233 var dateTimePickerFunc = me.getName() == 'date' ? navigator.plugins.dateTimePicker.selectDate : navigator.plugins.dateTimePicker.selectTime;\r
83234 dateTimePickerFunc(success, fail, {\r
83235 value: me.getValue()\r
83236 });\r
83237 } catch (ex) {\r
83238 fail(ex);\r
83239 }\r
83240 }\r
83241});\r
83242\r
83243\r
83244Ext.define('Ext.field.Email', {\r
83245 extend: Ext.field.Text,\r
83246 alternateClassName: 'Ext.form.Email',\r
83247 xtype: 'emailfield',\r
83248 config: {\r
83249 \r
83250 component: {\r
83251 type: 'email'\r
83252 },\r
83253 \r
83254 autoCapitalize: false\r
83255 }\r
83256});\r
83257\r
83258\r
83259Ext.define('Ext.field.FileInput', {\r
83260 extend: Ext.field.Input,\r
83261 xtype: 'fileinput',\r
83262 \r
83263 config: {\r
83264 type: "file",\r
83265 accept: null,\r
83266 capture: null,\r
83267 name: null,\r
83268 multiple: false\r
83269 },\r
83270 \r
83271 captureLookup: {\r
83272 video: "camcorder",\r
83273 image: "camera",\r
83274 audio: "microphone"\r
83275 },\r
83276 \r
83277 initialize: function() {\r
83278 var me = this;\r
83279 me.callParent();\r
83280 me.input.on({\r
83281 scope: me,\r
83282 change: 'onInputChange'\r
83283 });\r
83284 },\r
83285 \r
83286 getValue: function() {\r
83287 var input = this.input;\r
83288 if (input) {\r
83289 this._value = input.dom.value;\r
83290 }\r
83291 return this._value;\r
83292 },\r
83293 \r
83294 setValue: function(newValue) {\r
83295 var oldValue = this._value;\r
83296 this._value = newValue;\r
83297 if (String(this._value) != String(oldValue) && this.initialized) {\r
83298 this.onChange(this, this._value, oldValue);\r
83299 }\r
83300 return this;\r
83301 },\r
83302 \r
83303 getFiles: function() {\r
83304 var input = this.input;\r
83305 if (input) {\r
83306 this.$files = input.dom.files;\r
83307 }\r
83308 return this.$files;\r
83309 },\r
83310 \r
83311 onInputChange: function(e) {\r
83312 this.setValue(e.target.value);\r
83313 },\r
83314 \r
83315 onChange: function(me, value, startValue) {\r
83316 this.fireEvent('change', me, value, startValue);\r
83317 },\r
83318 \r
83319 applyName: function(value) {\r
83320 if (this.getMultiple() && value.substr(-2, 2) !== "[]") {\r
83321 value += "[]";\r
83322 } else if ((!this.getMultiple()) && value.substr(-2, 2) === "[]") {\r
83323 value = value.substr(0, value.length - 2);\r
83324 }\r
83325 return value;\r
83326 },\r
83327 \r
83328 applyMultiple: function(value) {\r
83329 this.updateFieldAttribute('multiple', value ? '' : null);\r
83330 return value;\r
83331 },\r
83332 \r
83333 updateMultiple: function() {\r
83334 var name = this.getName();\r
83335 if (!Ext.isEmpty(name)) {\r
83336 this.setName(name);\r
83337 }\r
83338 },\r
83339 \r
83340 applyAccept: function(value) {\r
83341 switch (value) {\r
83342 case "video":\r
83343 case "audio":\r
83344 case "image":\r
83345 value = value + "/*";\r
83346 break;\r
83347 }\r
83348 this.updateFieldAttribute('accept', value);\r
83349 },\r
83350 \r
83351 applyCapture: function(value) {\r
83352 this.updateFieldAttribute('capture', value);\r
83353 return value;\r
83354 }\r
83355});\r
83356\r
83357\r
83358Ext.define('Ext.field.File', {\r
83359 extend: Ext.field.Field,\r
83360 xtype: 'filefield',\r
83361 \r
83362 config: {\r
83363 component: {\r
83364 xtype: 'fileinput',\r
83365 fastFocus: false\r
83366 }\r
83367 },\r
83368 proxyConfig: {\r
83369 name: null,\r
83370 value: null,\r
83371 files: null,\r
83372 \r
83373 multiple: false,\r
83374 \r
83375 accept: null,\r
83376 \r
83377 capture: null\r
83378 },\r
83379 \r
83380 isFile: true,\r
83381 \r
83382 initialize: function() {\r
83383 var me = this;\r
83384 me.callParent();\r
83385 me.getComponent().on({\r
83386 scope: this,\r
83387 change: 'onChange'\r
83388 });\r
83389 },\r
83390 onChange: function(me, value, startValue) {\r
83391 me.fireEvent('change', this, value, startValue);\r
83392 }\r
83393});\r
83394\r
83395\r
83396Ext.define('Ext.field.Hidden', {\r
83397 extend: Ext.field.Text,\r
83398 alternateClassName: 'Ext.form.Hidden',\r
83399 xtype: 'hiddenfield',\r
83400 config: {\r
83401 \r
83402 component: {\r
83403 xtype: 'input',\r
83404 type: 'hidden'\r
83405 },\r
83406 \r
83407 ui: 'hidden',\r
83408 \r
83409 hidden: true,\r
83410 \r
83411 tabIndex: -1\r
83412 }\r
83413});\r
83414\r
83415\r
83416Ext.define('Ext.field.Number', {\r
83417 extend: Ext.field.Text,\r
83418 xtype: 'numberfield',\r
83419 alternateClassName: 'Ext.form.Number',\r
83420 \r
83421 config: {\r
83422 \r
83423 component: {\r
83424 type: 'number'\r
83425 },\r
83426 \r
83427 ui: 'number'\r
83428 },\r
83429 proxyConfig: {\r
83430 \r
83431 minValue: null,\r
83432 \r
83433 maxValue: null,\r
83434 \r
83435 stepValue: null\r
83436 },\r
83437 applyPlaceHolder: function(value) {\r
83438
83439
83440 this._enableNumericPlaceHolderHack = ((!Ext.feature.has.NumericInputPlaceHolder) && (!Ext.isEmpty(value)));\r
83441 return value;\r
83442 },\r
83443 onFocus: function(e) {\r
83444 if (this._enableNumericPlaceHolderHack) {\r
83445 this.getComponent().input.dom.setAttribute("type", "number");\r
83446 }\r
83447 this.callParent(arguments);\r
83448 },\r
83449 onBlur: function(e) {\r
83450 if (this._enableNumericPlaceHolderHack) {\r
83451 this.getComponent().input.dom.setAttribute("type", "text");\r
83452 }\r
83453 this.callParent(arguments);\r
83454 },\r
83455 doInitValue: function() {\r
83456 var value = this.getInitialConfig().value;\r
83457 if (value) {\r
83458 value = this.applyValue(value);\r
83459 }\r
83460 this.originalValue = value;\r
83461 },\r
83462 applyValue: function(value) {\r
83463 var minValue = this.getMinValue(),\r
83464 maxValue = this.getMaxValue();\r
83465 if (Ext.isNumber(minValue) && Ext.isNumber(value)) {\r
83466 value = Math.max(value, minValue);\r
83467 }\r
83468 if (Ext.isNumber(maxValue) && Ext.isNumber(value)) {\r
83469 value = Math.min(value, maxValue);\r
83470 }\r
83471 value = parseFloat(value);\r
83472 return (isNaN(value)) ? '' : value;\r
83473 },\r
83474 getValue: function() {\r
83475 var value = parseFloat(this.callParent(), 10);\r
83476 return (isNaN(value)) ? null : value;\r
83477 },\r
83478 doClearIconTap: function(me, e) {\r
83479 me.getComponent().setValue('');\r
83480 me.getValue();\r
83481 me.hideClearIcon();\r
83482 }\r
83483});\r
83484\r
83485\r
83486Ext.define('Ext.field.Password', {\r
83487 extend: Ext.field.Text,\r
83488 xtype: 'passwordfield',\r
83489 alternateClassName: 'Ext.form.Password',\r
83490 config: {\r
83491 \r
83492 autoCapitalize: false,\r
83493 \r
83494 revealable: false,\r
83495 \r
83496 revealed: false,\r
83497 \r
83498 component: {\r
83499 type: 'password'\r
83500 }\r
83501 },\r
83502 isPassword: true,\r
83503 initialize: function() {\r
83504 this.callParent(arguments);\r
83505 this.addCls(Ext.baseCSSPrefix + 'field-password');\r
83506 },\r
83507 updateRevealable: function(newValue, oldValue) {\r
83508 if (this.$revealIcon) {\r
83509 this.getComponent().element.removeChild(this.$revealIcon);\r
83510 this.$revealIcon = null;\r
83511 }\r
83512 if (newValue === true) {\r
83513 this.$revealIcon = new Ext.Element(Ext.Element.create({\r
83514 cls: 'x-reveal-icon'\r
83515 }, true));\r
83516 this.$revealIcon.on({\r
83517 tap: 'onRevealIconTap',\r
83518 touchstart: 'onRevealIconPress',\r
83519 touchend: 'onRevealIconRelease',\r
83520 scope: this\r
83521 });\r
83522 this.getComponent().element.appendChild(this.$revealIcon);\r
83523 }\r
83524 },\r
83525 updateRevealed: function(newValue, oldValue) {\r
83526 var component = this.getComponent();\r
83527 if (newValue) {\r
83528 this.element.addCls(Ext.baseCSSPrefix + 'revealed');\r
83529 component.setType("text");\r
83530 } else {\r
83531 this.element.removeCls(Ext.baseCSSPrefix + 'revealed');\r
83532 component.setType("password");\r
83533 }\r
83534 },\r
83535 \r
83536 updateValue: function(value, oldValue) {\r
83537 this.toggleRevealIcon(this.isValidTextValue(value));\r
83538 this.callParent([\r
83539 value,\r
83540 oldValue\r
83541 ]);\r
83542 },\r
83543 doKeyUp: function(me, e) {\r
83544 var value = me.getValue(),\r
83545 valid = me.isValidTextValue(me.getValue());\r
83546 me.toggleClearIcon(valid);\r
83547 if (e.browserEvent.keyCode === 13) {\r
83548 me.fireAction('action', [\r
83549 me,\r
83550 e\r
83551 ], 'doAction');\r
83552 }\r
83553 me.toggleRevealIcon(valid);\r
83554 },\r
83555 \r
83556 showRevealIcon: function() {\r
83557 var me = this,\r
83558 value = me.getValue(),\r
83559
83560 valueValid = value !== undefined && value !== null && value !== "";\r
83561 if (me.getRevealable() && !me.getDisabled() && valueValid) {\r
83562 me.element.addCls(Ext.baseCSSPrefix + 'field-revealable');\r
83563 }\r
83564 return me;\r
83565 },\r
83566 \r
83567 hideRevealIcon: function() {\r
83568 if (this.getRevealable()) {\r
83569 this.element.removeCls(Ext.baseCSSPrefix + 'field-revealable');\r
83570 }\r
83571 },\r
83572 onRevealIconTap: function(e) {\r
83573 this.fireAction('revealicontap', [\r
83574 this,\r
83575 e\r
83576 ], 'doRevealIconTap');\r
83577 },\r
83578 \r
83579 doRevealIconTap: function(me, e) {\r
83580 me.setRevealed(!this.getRevealed());\r
83581 },\r
83582 onRevealIconPress: function() {\r
83583 this.$revealIcon.addCls(Ext.baseCSSPrefix + 'pressing');\r
83584 },\r
83585 onRevealIconRelease: function() {\r
83586 this.$revealIcon.removeCls(Ext.baseCSSPrefix + 'pressing');\r
83587 },\r
83588 privates: {\r
83589 isValidTextValue: function(value) {\r
83590
83591 return (value !== undefined && value !== null && value !== '');\r
83592 },\r
83593 toggleRevealIcon: function(state) {\r
83594 if (state) {\r
83595 this.showRevealIcon();\r
83596 } else {\r
83597 this.hideRevealIcon();\r
83598 }\r
83599 }\r
83600 }\r
83601});\r
83602\r
83603\r
83604Ext.define('Ext.field.Radio', {\r
83605 extend: Ext.field.Checkbox,\r
83606 xtype: 'radiofield',\r
83607 alternateClassName: 'Ext.form.Radio',\r
83608 isRadio: true,\r
83609 config: {\r
83610 \r
83611 ui: 'radio',\r
83612 \r
83613 component: {\r
83614 type: 'radio',\r
83615 cls: Ext.baseCSSPrefix + 'input-radio'\r
83616 }\r
83617 },\r
83618 getValue: function() {\r
83619 return this._value === undefined ? null : this._value;\r
83620 },\r
83621 setValue: function(value) {\r
83622 this._value = value;\r
83623 return this;\r
83624 },\r
83625 getSubmitValue: function() {\r
83626 var value = this._value;\r
83627 if (value === undefined || value === null) {\r
83628 value = true;\r
83629 }\r
83630 return (this.getChecked()) ? value : null;\r
83631 },\r
83632 updateChecked: function(checked, oldChecked) {\r
83633 var me = this;\r
83634 me.callParent([\r
83635 checked,\r
83636 oldChecked\r
83637 ]);\r
83638 if (me.initialized && checked) {\r
83639 me.refreshGroupValues(me);\r
83640 }\r
83641 },\r
83642 \r
83643 onMaskTap: function(component, e) {\r
83644 var me = this,\r
83645 dom = me.getComponent().input.dom;\r
83646 if (me.getDisabled()) {\r
83647 return false;\r
83648 }\r
83649 me.setChecked(true);\r
83650
83651 return false;\r
83652 },\r
83653 \r
83654 getGroupValue: function() {\r
83655 var fields = this.getSameGroupFields(),\r
83656 ln = fields.length,\r
83657 i = 0,\r
83658 field;\r
83659 for (; i < ln; i++) {\r
83660 field = fields[i];\r
83661 if (field.getChecked()) {\r
83662 return field.getValue();\r
83663 }\r
83664 }\r
83665 return null;\r
83666 },\r
83667 \r
83668 setGroupValue: function(value) {\r
83669 var fields = this.getSameGroupFields(),\r
83670 ln = fields.length,\r
83671 i = 0,\r
83672 field;\r
83673 for (; i < ln; i++) {\r
83674 field = fields[i];\r
83675 if (field.getValue() === value) {\r
83676 field.setChecked(true);\r
83677 return field;\r
83678 }\r
83679 }\r
83680 },\r
83681 \r
83682 refreshGroupValues: function(trigger) {\r
83683 var fields = this.getSameGroupFields(),\r
83684 ln = fields.length,\r
83685 i = 0,\r
83686 field;\r
83687 for (; i < ln; i++) {\r
83688 field = fields[i];\r
83689 if (field !== trigger) {\r
83690 field.setChecked(false);\r
83691 }\r
83692 }\r
83693 }\r
83694});\r
83695\r
83696\r
83697Ext.define('Ext.field.Search', {\r
83698 extend: Ext.field.Text,\r
83699 xtype: 'searchfield',\r
83700 alternateClassName: 'Ext.form.Search',\r
83701 config: {\r
83702 \r
83703 component: {\r
83704 type: 'search'\r
83705 },\r
83706 \r
83707 ui: 'search'\r
83708 }\r
83709});\r
83710\r
83711\r
83712Ext.define('Ext.field.Select', {\r
83713 extend: Ext.field.Picker,\r
83714 xtype: 'selectfield',\r
83715 alternateClassName: 'Ext.form.Select',\r
83716 \r
83717 \r
83718 config: {\r
83719 \r
83720 ui: 'select',\r
83721 \r
83722 \r
83723 valueField: 'value',\r
83724 \r
83725 displayField: 'text',\r
83726 \r
83727 store: null,\r
83728 \r
83729 options: null,\r
83730 \r
83731 hiddenName: null,\r
83732 \r
83733 autoSelect: true,\r
83734 \r
83735 name: 'picker',\r
83736 \r
83737 selection: null\r
83738 },\r
83739 twoWayBindable: {\r
83740 selection: 1\r
83741 },\r
83742 publishes: {\r
83743 selection: 1\r
83744 },\r
83745 \r
83746 applyValue: function(value) {\r
83747 var me = this,\r
83748 record = value,\r
83749 index, store;\r
83750
83751
83752 me.getOptions();\r
83753 store = me.getStore();\r
83754 if ((value || value === 0) && !value.isModel && store) {\r
83755 index = store.find(me.getValueField(), value, null, null, null, true);\r
83756 if (index === -1) {\r
83757 index = store.find(me.getDisplayField(), value, null, null, null, true);\r
83758 }\r
83759 record = store.getAt(index);\r
83760 }\r
83761 return record;\r
83762 },\r
83763 updateValue: function(value, oldValue) {\r
83764 var me = this,\r
83765 component = me.getComponent(),\r
83766 displayValue = '';\r
83767 if (value === null || (value && value.isModel)) {\r
83768 me.settingSelection = true;\r
83769 me.setSelection(value);\r
83770 me.settingSelection = false;\r
83771 if (value) {\r
83772 displayValue = value.get(me.getDisplayField());\r
83773 }\r
83774 }\r
83775 if (component) {\r
83776 component.setValue(displayValue);\r
83777 }\r
83778 if (me.initialized) {\r
83779 me.fireEvent('change', me, value, oldValue);\r
83780 }\r
83781 },\r
83782 \r
83783 getValue: function() {\r
83784 var selection = this.getSelection();\r
83785 return selection ? selection.get(this.getValueField()) : null;\r
83786 },\r
83787 applySelection: function(selection) {\r
83788 return selection || null;\r
83789 },\r
83790 updateSelection: function(selection) {\r
83791 if (!this.settingSelection) {\r
83792 this.setValue(selection ? selection.get(this.getValueField()) : null);\r
83793 }\r
83794 },\r
83795 \r
83796 getPhonePicker: function() {\r
83797 var me = this,\r
83798 phonePicker = me.phonePicker,\r
83799 config;\r
83800 if (!phonePicker) {\r
83801 config = me.getDefaultPhonePickerConfig();\r
83802 me.phonePicker = phonePicker = Ext.create('Ext.picker.Picker', Ext.apply({\r
83803 slots: [\r
83804 {\r
83805 align: me.getPickerSlotAlign(),\r
83806 name: me.getName(),\r
83807 valueField: me.getValueField(),\r
83808 displayField: me.getDisplayField(),\r
83809 value: me.getValue(),\r
83810 store: me.getStore()\r
83811 }\r
83812 ],\r
83813 listeners: {\r
83814 change: me.onPickerChange,\r
83815 scope: me\r
83816 }\r
83817 }, config));\r
83818 }\r
83819 return phonePicker;\r
83820 },\r
83821 \r
83822 getTabletPicker: function() {\r
83823 var me = this,\r
83824 tabletPicker = me.tabletPicker,\r
83825 config;\r
83826 if (!tabletPicker) {\r
83827 config = me.getDefaultTabletPickerConfig();\r
83828 me.tabletPicker = tabletPicker = Ext.create('Ext.Panel', Ext.apply({\r
83829 left: 0,\r
83830 top: 0,\r
83831 modal: true,\r
83832 cls: Ext.baseCSSPrefix + 'select-overlay',\r
83833 layout: 'fit',\r
83834 hideOnMaskTap: true,\r
83835 width: Ext.os.is.Phone ? '14em' : '18em',\r
83836 height: (Ext.os.is.BlackBerry && Ext.os.version.getMajor() === 10) ? '12em' : (Ext.os.is.Phone ? '12.5em' : '22em'),\r
83837 items: {\r
83838 xtype: 'list',\r
83839 store: me.getStore(),\r
83840 itemTpl: '<span class="x-list-label">{' + me.getDisplayField() + ':htmlEncode}</span>',\r
83841 listeners: {\r
83842 select: me.onListSelect,\r
83843 itemtap: me.onListTap,\r
83844 scope: me\r
83845 }\r
83846 }\r
83847 }, config));\r
83848 }\r
83849 return tabletPicker;\r
83850 },\r
83851 \r
83852 showPicker: function() {\r
83853 var me = this,\r
83854 store = me.getStore(),\r
83855 value = me.getValue(),\r
83856 picker, name, pickerValue, list, index, record;\r
83857
83858 if (!store || store.getCount() === 0) {\r
83859 return;\r
83860 }\r
83861 if (me.getReadOnly()) {\r
83862 return;\r
83863 }\r
83864 me.isFocused = true;\r
83865 if (me.getUsePicker()) {\r
83866 picker = me.getPhonePicker();\r
83867 name = me.getName();\r
83868 pickerValue = {};\r
83869 pickerValue[name] = value;\r
83870 picker.setValue(pickerValue);\r
83871 if (!picker.getParent()) {\r
83872 Ext.Viewport.add(picker);\r
83873 }\r
83874 picker.show();\r
83875 } else {\r
83876 picker = me.getTabletPicker();\r
83877 list = picker.down('list');\r
83878 if (!picker.getParent()) {\r
83879 Ext.Viewport.add(picker);\r
83880 }\r
83881 picker.showBy(me.getComponent(), null);\r
83882 if (value || me.getAutoSelect()) {\r
83883 store = list.getStore();\r
83884 index = store.find(me.getValueField(), value, null, null, null, true);\r
83885 record = store.getAt(index);\r
83886 if (record) {\r
83887 list.select(record, null, true);\r
83888 }\r
83889 }\r
83890 }\r
83891 },\r
83892 \r
83893 onListSelect: function(item, record) {\r
83894 var me = this;\r
83895 if (record) {\r
83896 me.setValue(record);\r
83897 }\r
83898 },\r
83899 onListTap: function() {\r
83900 this.tabletPicker.hide({\r
83901 type: 'fade',\r
83902 out: true,\r
83903 scope: this\r
83904 });\r
83905 },\r
83906 \r
83907 onPickerChange: function(picker, value) {\r
83908 var me = this,\r
83909 newValue = value[me.getName()],\r
83910 store = me.getStore(),\r
83911 index = store.find(me.getValueField(), newValue, null, null, null, true),\r
83912 record = store.getAt(index);\r
83913 me.setValue(record);\r
83914 },\r
83915 \r
83916 updateOptions: function(newOptions) {\r
83917 var store = this.getStore();\r
83918 if (!store) {\r
83919 this.setStore(true);\r
83920 store = this._store;\r
83921 }\r
83922 if (!newOptions) {\r
83923 store.clearData();\r
83924 } else {\r
83925 store.setData(newOptions);\r
83926 this.onStoreDataChanged(store);\r
83927 }\r
83928 return this;\r
83929 },\r
83930 applyStore: function(store) {\r
83931 if (store === true) {\r
83932 store = Ext.create('Ext.data.Store', {\r
83933 fields: [\r
83934 this.getValueField(),\r
83935 this.getDisplayField()\r
83936 ],\r
83937 autoDestroy: true\r
83938 });\r
83939 }\r
83940 if (store) {\r
83941 store = Ext.data.StoreManager.lookup(store);\r
83942 }\r
83943 return store;\r
83944 },\r
83945 updateStore: function(store, oldStore) {\r
83946 var me = this,\r
83947 tabletPicker = me.tabletPicker,\r
83948 phonePicker = me.phonePicker;\r
83949 if (oldStore && oldStore.getAutoDestroy()) {\r
83950 oldStore.destroy();\r
83951 }\r
83952 if (store) {\r
83953 store.on({\r
83954 scope: this,\r
83955 add: 'onStoreDataChanged',\r
83956 remove: 'onStoreDataChanged',\r
83957 update: 'onStoreDataChanged',\r
83958 refresh: 'onStoreDataChanged'\r
83959 });\r
83960 me.onStoreDataChanged(store);\r
83961 }\r
83962 if (me.getUsePicker() && phonePicker) {\r
83963 phonePicker.down('pickerslot').setStore(store);\r
83964 } else if (tabletPicker) {\r
83965 tabletPicker.down('dataview').setStore(store);\r
83966 }\r
83967 },\r
83968 \r
83969 onStoreDataChanged: function(store) {\r
83970 var initialConfig = this.getInitialConfig(),\r
83971 value = this.getValue();\r
83972 if (value || value === 0) {\r
83973 this.setValue(value);\r
83974 }\r
83975 if (this.getValue() === null) {\r
83976 if (initialConfig.hasOwnProperty('value')) {\r
83977 this.setValue(initialConfig.value);\r
83978 }\r
83979 if (this.getValue() === null && this.getAutoSelect()) {\r
83980 if (store.getCount() > 0) {\r
83981 this.setValue(store.getAt(0));\r
83982 }\r
83983 }\r
83984 }\r
83985 },\r
83986 \r
83987 reset: function() {\r
83988 var me = this,\r
83989 record, store, usePicker, picker;\r
83990 if (me.getAutoSelect()) {\r
83991 store = me.getStore();\r
83992 record = me.originalValue ? me.originalValue : store.getAt(0);\r
83993 } else {\r
83994 usePicker = me.getUsePicker();\r
83995 picker = usePicker ? me.phonePicker : me.tabletPicker;\r
83996 if (picker) {\r
83997 picker = picker.child(usePicker ? 'pickerslot' : 'dataview');\r
83998 picker.deselectAll();\r
83999 }\r
84000 record = null;\r
84001 }\r
84002 me.setValue(record);\r
84003 return me;\r
84004 },\r
84005 destroy: function() {\r
84006 var store = this.getStore();\r
84007 if (store && store.getAutoDestroy()) {\r
84008 store.destroy();\r
84009 }\r
84010 this.callParent();\r
84011 }\r
84012});\r
84013\r
84014\r
84015Ext.define('Ext.slider.Thumb', {\r
84016 extend: Ext.Component,\r
84017 xtype: 'thumb',\r
84018 config: {\r
84019 \r
84020 baseCls: Ext.baseCSSPrefix + 'thumb',\r
84021 \r
84022 pressedCls: Ext.baseCSSPrefix + 'thumb-pressing',\r
84023 \r
84024 draggable: {\r
84025 direction: 'horizontal'\r
84026 }\r
84027 },\r
84028
84029
84030 platformConfig: {\r
84031 ie10: {\r
84032 draggable: {\r
84033 translatable: {\r
84034 translationMethod: 'csstransform'\r
84035 }\r
84036 }\r
84037 }\r
84038 },\r
84039 elementWidth: 0,\r
84040 initialize: function() {\r
84041 var me = this;\r
84042 me.callParent();\r
84043 me.getDraggable().onBefore({\r
84044 beforedragstart: 'onBeforeDragStart',\r
84045 dragstart: 'onDragStart',\r
84046 drag: 'onDrag',\r
84047 dragend: 'onDragEnd',\r
84048 scope: this\r
84049 });\r
84050 me.getDraggable().on({\r
84051 touchstart: 'onPress',\r
84052 touchend: 'onRelease',\r
84053 scope: me\r
84054 });\r
84055 me.element.on('resize', 'onElementResize', me);\r
84056 },\r
84057 \r
84058 updatePressedCls: function(pressedCls, oldPressedCls) {\r
84059 var element = this.element;\r
84060 if (element.hasCls(oldPressedCls)) {\r
84061 element.replaceCls(oldPressedCls, pressedCls);\r
84062 }\r
84063 },\r
84064 \r
84065 onPress: function() {\r
84066 var me = this,\r
84067 element = me.element,\r
84068 pressedCls = me.getPressedCls();\r
84069 if (!me.getDisabled()) {\r
84070 element.addCls(pressedCls);\r
84071 }\r
84072 },\r
84073 \r
84074 onRelease: function(e) {\r
84075 this.fireAction('release', [\r
84076 this,\r
84077 e\r
84078 ], 'doRelease');\r
84079 },\r
84080 \r
84081 doRelease: function(me, e) {\r
84082 if (!me.getDisabled()) {\r
84083 me.element.removeCls(me.getPressedCls());\r
84084 }\r
84085 },\r
84086 onBeforeDragStart: function(draggable, e, x, y) {\r
84087 if (this.isDisabled()) {\r
84088 return false;\r
84089 }\r
84090 return this.fireEvent('beforedragstart', this, e, x, y);\r
84091 },\r
84092 onDragStart: function(draggable, e, x, y) {\r
84093 this.fireEvent('dragstart', this, e, x, y);\r
84094 },\r
84095 onDrag: function(draggable, e, x, y) {\r
84096 if (this.isDisabled()) {\r
84097 return false;\r
84098 }\r
84099 this.fireEvent('drag', this, e, x, y);\r
84100 },\r
84101 onDragEnd: function(draggable, e, x, y) {\r
84102 if (this.isDisabled()) {\r
84103 return false;\r
84104 }\r
84105 this.fireEvent('dragend', this, e, x, y);\r
84106 },\r
84107 onElementResize: function(element, info) {\r
84108 this.elementWidth = info.width;\r
84109 },\r
84110 getElementWidth: function() {\r
84111 return this.elementWidth;\r
84112 }\r
84113});\r
84114\r
84115\r
84116Ext.define('Ext.slider.Slider', {\r
84117 extend: Ext.Container,\r
84118 xtype: 'slider',\r
84119 \r
84120 \r
84121 \r
84122 \r
84123 config: {\r
84124 baseCls: 'x-slider',\r
84125 \r
84126 thumbConfig: {\r
84127 draggable: {\r
84128 translatable: {\r
84129 easingX: {\r
84130 duration: 300,\r
84131 type: 'ease-out'\r
84132 }\r
84133 }\r
84134 }\r
84135 },\r
84136 \r
84137 increment: 1,\r
84138 \r
84139 value: 0,\r
84140 \r
84141 minValue: 0,\r
84142 \r
84143 maxValue: 100,\r
84144 \r
84145 allowThumbsOverlapping: false,\r
84146 \r
84147 animation: true,\r
84148 \r
84149 readOnly: false\r
84150 },\r
84151 \r
84152 elementWidth: 0,\r
84153 offsetValueRatio: 0,\r
84154 activeThumb: null,\r
84155 constructor: function(config) {\r
84156 config = config || {};\r
84157 if (config.hasOwnProperty('values')) {\r
84158 config.value = config.values;\r
84159 }\r
84160 this.callParent([\r
84161 config\r
84162 ]);\r
84163 },\r
84164 \r
84165 initialize: function() {\r
84166 var element = this.element,\r
84167 thumb;\r
84168 this.callParent();\r
84169 element.on({\r
84170 scope: this,\r
84171 tap: 'onTap',\r
84172 resize: 'onResize'\r
84173 });\r
84174 this.on({\r
84175 scope: this,\r
84176 delegate: '> thumb',\r
84177 tap: 'onTap',\r
84178 beforedragstart: 'onThumbBeforeDragStart',\r
84179 dragstart: 'onThumbDragStart',\r
84180 drag: 'onThumbDrag',\r
84181 dragend: 'onThumbDragEnd'\r
84182 });\r
84183 thumb = this.getThumb(0);\r
84184 if (thumb) {\r
84185 thumb.on('resize', 'onThumbResize', this);\r
84186 }\r
84187 },\r
84188 \r
84189 factoryThumb: function() {\r
84190 return Ext.factory(this.getThumbConfig(), Ext.slider.Thumb);\r
84191 },\r
84192 \r
84193 getThumbs: function() {\r
84194 return this.innerItems;\r
84195 },\r
84196 \r
84197 getThumb: function(index) {\r
84198 if (typeof index != 'number') {\r
84199 index = 0;\r
84200 }\r
84201 return this.innerItems[index];\r
84202 },\r
84203 refreshOffsetValueRatio: function() {\r
84204 var me = this,\r
84205 valueRange = me.getMaxValue() - me.getMinValue(),\r
84206 trackWidth = me.elementWidth - me.thumbWidth;\r
84207 me.offsetValueRatio = valueRange === 0 ? 0 : trackWidth / valueRange;\r
84208 },\r
84209 onThumbResize: function() {\r
84210 var thumb = this.getThumb(0);\r
84211 if (thumb) {\r
84212 this.thumbWidth = thumb.getElementWidth();\r
84213 }\r
84214 this.refresh();\r
84215 },\r
84216 onResize: function(element, info) {\r
84217 this.elementWidth = info.width;\r
84218 this.refresh();\r
84219 },\r
84220 refresh: function() {\r
84221 this.refreshing = true;\r
84222 this.refreshValue();\r
84223 this.refreshing = false;\r
84224 },\r
84225 setActiveThumb: function(thumb) {\r
84226 var oldActiveThumb = this.activeThumb;\r
84227 if (oldActiveThumb && oldActiveThumb !== thumb) {\r
84228 oldActiveThumb.setZIndex(null);\r
84229 }\r
84230 this.activeThumb = thumb;\r
84231 thumb.setZIndex(2);\r
84232 return this;\r
84233 },\r
84234 onThumbBeforeDragStart: function(thumb, e) {\r
84235 if (this.offsetValueRatio === 0 || e.absDeltaX <= e.absDeltaY || this.getReadOnly()) {\r
84236 return false;\r
84237 }\r
84238 },\r
84239 onThumbDragStart: function(thumb, e) {\r
84240 var me = this;\r
84241 me.refreshAllThumbConstraints();\r
84242 e.stopPropagation();\r
84243 if (me.getAllowThumbsOverlapping()) {\r
84244 me.setActiveThumb(thumb);\r
84245 }\r
84246 me.dragStartValue = me.getValue()[me.getThumbIndex(thumb)];\r
84247 me.fireEvent('dragstart', me, thumb, me.dragStartValue, e);\r
84248 },\r
84249 onThumbDrag: function(thumb, e, offsetX) {\r
84250 var me = this,\r
84251 index = me.getThumbIndex(thumb),\r
84252 offsetValueRatio = me.offsetValueRatio,\r
84253 constrainedValue = me.constrainValue(me.getMinValue() + offsetX / offsetValueRatio);\r
84254 e.stopPropagation();\r
84255 me.setIndexValue(index, constrainedValue);\r
84256 me.fireEvent('drag', me, thumb, me.getValue(), e);\r
84257 return false;\r
84258 },\r
84259 setIndexValue: function(index, value, animation) {\r
84260 var me = this,\r
84261 thumb = me.getThumb(index),\r
84262 values = me.getValue(),\r
84263 minValue = me.getMinValue(),\r
84264 offsetValueRatio = me.offsetValueRatio,\r
84265 increment = me.getIncrement(),\r
84266 draggable = thumb.getDraggable();\r
84267 draggable.setOffset((value - minValue) * offsetValueRatio, null, animation);\r
84268 values[index] = minValue + Math.round((draggable.offset.x / offsetValueRatio) / increment) * increment;\r
84269 },\r
84270 onThumbDragEnd: function(thumb, e) {\r
84271 var me = this,\r
84272 index = me.getThumbIndex(thumb),\r
84273 newValue = me.getValue()[index],\r
84274 oldValue = me.dragStartValue;\r
84275 me.snapThumbPosition(thumb, newValue);\r
84276 me.fireEvent('dragend', me, thumb, me.getValue(), e);\r
84277 if (oldValue !== newValue) {\r
84278 me.fireEvent('change', me, thumb, newValue, oldValue);\r
84279 }\r
84280 },\r
84281 getThumbIndex: function(thumb) {\r
84282 return this.getThumbs().indexOf(thumb);\r
84283 },\r
84284 refreshThumbConstraints: function(thumb) {\r
84285 var allowThumbsOverlapping = this.getAllowThumbsOverlapping(),\r
84286 offsetX = thumb.getDraggable().getOffset().x,\r
84287 thumbs = this.getThumbs(),\r
84288 index = this.getThumbIndex(thumb),\r
84289 previousThumb = thumbs[index - 1],\r
84290 nextThumb = thumbs[index + 1],\r
84291 thumbWidth = this.thumbWidth;\r
84292 if (previousThumb) {\r
84293 previousThumb.getDraggable().addExtraConstraint({\r
84294 max: {\r
84295 x: offsetX - ((allowThumbsOverlapping) ? 0 : thumbWidth)\r
84296 }\r
84297 });\r
84298 }\r
84299 if (nextThumb) {\r
84300 nextThumb.getDraggable().addExtraConstraint({\r
84301 min: {\r
84302 x: offsetX + ((allowThumbsOverlapping) ? 0 : thumbWidth)\r
84303 }\r
84304 });\r
84305 }\r
84306 },\r
84307 \r
84308 onTap: function(e) {\r
84309 var me = this,\r
84310 element = me.element,\r
84311 minDistance = Infinity,\r
84312 i, absDistance, testValue, closestIndex, oldValue, thumb, ln, values, value, offset, elementX, targetElement, touchPointX;\r
84313 if (me.offsetValueRatio === 0 || me.isDisabled() || me.getReadOnly()) {\r
84314 return;\r
84315 }\r
84316 targetElement = Ext.get(e.target);\r
84317 if (!targetElement || (Ext.browser.engineName == 'WebKit' && targetElement.hasCls('x-thumb'))) {\r
84318 return;\r
84319 }\r
84320 touchPointX = e.touch.point.x;\r
84321 elementX = element.getX();\r
84322 offset = touchPointX - elementX - (me.thumbWidth / 2);\r
84323 value = me.constrainValue(me.getMinValue() + offset / me.offsetValueRatio);\r
84324 values = me.getValue();\r
84325 ln = values.length;\r
84326 if (ln === 1) {\r
84327 closestIndex = 0;\r
84328 } else {\r
84329 for (i = 0; i < ln; i++) {\r
84330 testValue = values[i];\r
84331 absDistance = Math.abs(testValue - value);\r
84332 if (absDistance < minDistance) {\r
84333 minDistance = absDistance;\r
84334 closestIndex = i;\r
84335 }\r
84336 }\r
84337 }\r
84338 oldValue = values[closestIndex];\r
84339 thumb = me.getThumb(closestIndex);\r
84340 me.setIndexValue(closestIndex, value, me.getAnimation());\r
84341 me.refreshThumbConstraints(thumb);\r
84342 if (oldValue !== value) {\r
84343 me.fireEvent('change', me, thumb, value, oldValue);\r
84344 }\r
84345 },\r
84346 \r
84347 updateThumbs: function(newThumbs) {\r
84348 this.add(newThumbs);\r
84349 },\r
84350 applyValue: function(value, oldValue) {\r
84351 var values = Ext.Array.from(value || 0),\r
84352 filteredValues = [],\r
84353 previousFilteredValue = this.getMinValue(),\r
84354 filteredValue, i, ln;\r
84355 for (i = 0 , ln = values.length; i < ln; i++) {\r
84356 filteredValue = this.constrainValue(values[i]);\r
84357 if (filteredValue < previousFilteredValue) {\r
84358
84359 Ext.Logger.warn("Invalid values of '" + Ext.encode(values) + "', values at smaller indexes must " + "be smaller than or equal to values at greater indexes");\r
84360
84361 filteredValue = previousFilteredValue;\r
84362 }\r
84363 filteredValues.push(filteredValue);\r
84364 previousFilteredValue = filteredValue;\r
84365 }\r
84366 if (!this.refreshing && oldValue) {\r
84367 if (Ext.Array.equals(value, oldValue)) {\r
84368 filteredValues = undefined;\r
84369 }\r
84370 }\r
84371 return filteredValues;\r
84372 },\r
84373 \r
84374 updateValue: function(newValue, oldValue) {\r
84375 var me = this,\r
84376 thumbs = me.getThumbs(),\r
84377 len = newValue.length,\r
84378 i;\r
84379 me.setThumbsCount(len);\r
84380 for (i = 0; i < len; i++) {\r
84381 me.snapThumbPosition(thumbs[i], newValue[i]);\r
84382 }\r
84383 },\r
84384 \r
84385 refreshValue: function() {\r
84386 this.refreshOffsetValueRatio();\r
84387 this.setValue(this.getValue());\r
84388 },\r
84389 \r
84390 constrainValue: function(value) {\r
84391 var me = this,\r
84392 minValue = me.getMinValue(),\r
84393 maxValue = me.getMaxValue(),\r
84394 increment = me.getIncrement(),\r
84395 remainder;\r
84396 value = parseFloat(value);\r
84397 if (isNaN(value)) {\r
84398 value = minValue;\r
84399 }\r
84400 remainder = (value - minValue) % increment;\r
84401 value -= remainder;\r
84402 if (Math.abs(remainder) >= (increment / 2)) {\r
84403 value += (remainder > 0) ? increment : -increment;\r
84404 }\r
84405 value = Math.max(minValue, value);\r
84406 value = Math.min(maxValue, value);\r
84407 return value;\r
84408 },\r
84409 setThumbsCount: function(count) {\r
84410 var thumbs = this.getThumbs(),\r
84411 thumbsCount = thumbs.length,\r
84412 i, ln, thumb;\r
84413 if (thumbsCount > count) {\r
84414 for (i = 0 , ln = thumbsCount - count; i < ln; i++) {\r
84415 thumb = thumbs[thumbs.length - 1];\r
84416 thumb.destroy();\r
84417 }\r
84418 } else if (thumbsCount < count) {\r
84419 for (i = 0 , ln = count - thumbsCount; i < ln; i++) {\r
84420 this.add(this.factoryThumb());\r
84421 }\r
84422 }\r
84423 return this;\r
84424 },\r
84425 \r
84426 setValues: function(value) {\r
84427 this.setValue(value);\r
84428 },\r
84429 \r
84430 getValues: function() {\r
84431 return this.getValue();\r
84432 },\r
84433 \r
84434 applyIncrement: function(increment) {\r
84435 if (increment === 0) {\r
84436 increment = 1;\r
84437 }\r
84438 return Math.abs(increment);\r
84439 },\r
84440 \r
84441 updateAllowThumbsOverlapping: function(newValue, oldValue) {\r
84442 if (typeof oldValue != 'undefined') {\r
84443 this.refreshValue();\r
84444 }\r
84445 },\r
84446 \r
84447 updateMinValue: function(newValue, oldValue) {\r
84448 if (typeof oldValue != 'undefined') {\r
84449 this.refreshValue();\r
84450 }\r
84451 },\r
84452 \r
84453 updateMaxValue: function(newValue, oldValue) {\r
84454 if (typeof oldValue != 'undefined') {\r
84455 this.refreshValue();\r
84456 }\r
84457 },\r
84458 \r
84459 updateIncrement: function(newValue, oldValue) {\r
84460 if (typeof oldValue != 'undefined') {\r
84461 this.refreshValue();\r
84462 }\r
84463 },\r
84464 updateDisabled: function(disabled) {\r
84465 this.callParent(arguments);\r
84466 var items = this.getItems().items,\r
84467 ln = items.length,\r
84468 i;\r
84469 for (i = 0; i < ln; i++) {\r
84470 items[i].setDisabled(disabled);\r
84471 }\r
84472 },\r
84473 privates: {\r
84474 refreshAllThumbConstraints: function() {\r
84475 var thumbs = this.getThumbs(),\r
84476 len = thumbs.length,\r
84477 i;\r
84478 for (i = 0; i < len; i++) {\r
84479 this.refreshThumbConstraints(thumbs[i]);\r
84480 }\r
84481 },\r
84482 snapThumbPosition: function(thumb, value) {\r
84483 var ratio = this.offsetValueRatio,\r
84484 offset;\r
84485 if (isFinite(ratio)) {\r
84486 offset = Ext.Number.correctFloat((value - this.getMinValue()) * ratio);\r
84487 thumb.getDraggable().setExtraConstraint(null).setOffset(offset);\r
84488 }\r
84489 }\r
84490 }\r
84491});\r
84492\r
84493\r
84494Ext.define('Ext.field.Slider', {\r
84495 extend: Ext.field.Field,\r
84496 xtype: 'sliderfield',\r
84497 alternateClassName: 'Ext.form.Slider',\r
84498 \r
84499 \r
84500 \r
84501 \r
84502 \r
84503 config: {\r
84504 \r
84505 cls: Ext.baseCSSPrefix + 'slider-field',\r
84506 \r
84507 liveUpdate: false,\r
84508 \r
84509 tabIndex: -1,\r
84510 \r
84511 readOnly: false,\r
84512 \r
84513 value: 0\r
84514 },\r
84515 proxyConfig: {\r
84516 \r
84517 increment: 1,\r
84518 \r
84519 minValue: 0,\r
84520 \r
84521 maxValue: 100\r
84522 },\r
84523 defaultBindProperty: 'values',\r
84524 twoWayBindable: {\r
84525 values: 1,\r
84526 value: 1\r
84527 },\r
84528 \r
84529 constructor: function(config) {\r
84530 config = config || {};\r
84531 if (config.hasOwnProperty('values')) {\r
84532 config.value = config.values;\r
84533 }\r
84534 this.callParent([\r
84535 config\r
84536 ]);\r
84537 this.updateMultipleState();\r
84538 },\r
84539 \r
84540 initialize: function() {\r
84541 this.callParent();\r
84542 this.getComponent().on({\r
84543 scope: this,\r
84544 change: 'onSliderChange',\r
84545 dragstart: 'onSliderDragStart',\r
84546 drag: 'onSliderDrag',\r
84547 dragend: 'onSliderDragEnd'\r
84548 });\r
84549 },\r
84550 \r
84551 applyComponent: function(config) {\r
84552 return Ext.factory(config, Ext.slider.Slider);\r
84553 },\r
84554 \r
84555 updateComponent: function(component, oldComponent) {\r
84556 this.callParent([\r
84557 component,\r
84558 oldComponent\r
84559 ]);\r
84560 component.setMinValue(this.getMinValue());\r
84561 component.setMaxValue(this.getMaxValue());\r
84562 },\r
84563 applyValue: function(value) {\r
84564 var ret = value;\r
84565
84566
84567 if (this.dragging && this.isSyncing('value')) {\r
84568 ret = undefined;\r
84569 }\r
84570 return ret;\r
84571 },\r
84572 updateValue: function(value, oldValue) {\r
84573 var me = this;\r
84574 if (!me.dragging) {\r
84575 me.setComponentValue(value);\r
84576 }\r
84577 if (me.initialized) {\r
84578 me.fireEvent('change', me, value, oldValue);\r
84579 }\r
84580 },\r
84581 setComponentValue: function(value) {\r
84582 this.getComponent().setValue(value);\r
84583 },\r
84584 onSliderChange: function(slider, thumb, newValue, oldValue) {\r
84585 this.setValue(slider.getValue());\r
84586 this.fireEvent('dragchange', this, slider, thumb, newValue, oldValue);\r
84587 },\r
84588 onSliderDragStart: function(slider, thumb, startValue, e) {\r
84589 this.dragging = true;\r
84590 this.fireEvent('dragstart', this, slider, thumb, startValue, e);\r
84591 },\r
84592 onSliderDrag: function(slider, thumb, value, e) {\r
84593 var me = this;\r
84594 if (me.getLiveUpdate()) {\r
84595 me.setValue(slider.getValue());\r
84596 }\r
84597 me.fireEvent('drag', me, slider, thumb, value, e);\r
84598 },\r
84599 onSliderDragEnd: function(slider, thumb, startValue, e) {\r
84600 this.dragging = false;\r
84601 this.fireEvent('dragend', this, slider, thumb, startValue, e);\r
84602 },\r
84603 \r
84604 setValues: function(value) {\r
84605 this.setValue(value);\r
84606 this.updateMultipleState();\r
84607 },\r
84608 \r
84609 getValues: function() {\r
84610 return this.getValue();\r
84611 },\r
84612 reset: function() {\r
84613 var config = this.config,\r
84614 initialValue = (this.config.hasOwnProperty('values')) ? config.values : config.value;\r
84615 this.setValue(initialValue);\r
84616 },\r
84617 updateDisabled: function(disabled) {\r
84618 this.callParent(arguments);\r
84619 this.getComponent().setDisabled(disabled);\r
84620 },\r
84621 updateReadOnly: function(newValue) {\r
84622 this.getComponent().setReadOnly(newValue);\r
84623 },\r
84624 isDirty: function() {\r
84625 if (this.getDisabled()) {\r
84626 return false;\r
84627 }\r
84628 return this.getValue() !== this.originalValue;\r
84629 },\r
84630 updateMultipleState: function() {\r
84631 var value = this.getValue();\r
84632 if (value && value.length > 1) {\r
84633 this.addCls(Ext.baseCSSPrefix + 'slider-multiple');\r
84634 }\r
84635 }\r
84636});\r
84637\r
84638\r
84639Ext.define('Ext.field.SingleSlider', {\r
84640 extend: Ext.field.Slider,\r
84641 xtype: 'singlesliderfield',\r
84642 \r
84643 \r
84644 \r
84645 \r
84646 \r
84647 \r
84648 defaultBindProperty: 'value',\r
84649 publishes: {\r
84650 value: 1\r
84651 },\r
84652 initialize: function() {\r
84653 this.callParent();\r
84654 this.publishState('value', this.getValue());\r
84655 },\r
84656 applyValue: function(value, oldValue) {\r
84657 value = this.callParent([\r
84658 value,\r
84659 oldValue\r
84660 ]);\r
84661 if (value && Ext.isArray(value)) {\r
84662 value = value[0];\r
84663 }\r
84664 return value;\r
84665 },\r
84666 getValue: function() {\r
84667 var value = this.callParent();\r
84668 if (value && Ext.isArray(value)) {\r
84669 value = value[0];\r
84670 }\r
84671 return value;\r
84672 },\r
84673 onSliderChange: function(slider, thumb, newValue, oldValue) {\r
84674 this.setValue(newValue);\r
84675 this.fireEvent('dragchange', this, slider, newValue, oldValue);\r
84676 },\r
84677 onSliderDragStart: function(slider, thumb, startValue, e) {\r
84678 this.fireEvent('dragstart', this, slider, startValue, e);\r
84679 },\r
84680 onSliderDrag: function(slider, thumb, value, e) {\r
84681 var me = this;\r
84682 if (me.getLiveUpdate()) {\r
84683 me.setValue(value);\r
84684 }\r
84685 me.fireEvent('drag', me, slider, value, e);\r
84686 },\r
84687 onSliderDragEnd: function(slider, thumb, startValue, e) {\r
84688 this.fireEvent('dragend', this, slider, startValue, e);\r
84689 }\r
84690});\r
84691\r
84692\r
84693Ext.define('Ext.util.TapRepeater', {\r
84694 mixins: {\r
84695 observable: Ext.mixin.Observable\r
84696 },\r
84697 \r
84698 \r
84699 \r
84700 config: {\r
84701 el: null,\r
84702 accelerate: true,\r
84703 interval: 10,\r
84704 delay: 250,\r
84705 preventDefault: true,\r
84706 stopDefault: false,\r
84707 timer: 0,\r
84708 pressCls: null\r
84709 },\r
84710 \r
84711 constructor: function(config) {\r
84712 var me = this;\r
84713
84714 for (var configName in config) {\r
84715 if (me.self.prototype.config && !(configName in me.self.prototype.config)) {\r
84716 me[configName] = config[configName];\r
84717 Ext.Logger.warn('Applied config as instance property: "' + configName + '"', me);\r
84718 }\r
84719 }\r
84720
84721 me.mixins.observable.constructor.call(me, config);\r
84722 },\r
84723 updateEl: function(newEl, oldEl) {\r
84724 var eventCfg = {\r
84725 touchstart: 'onTouchStart',\r
84726 touchend: 'onTouchEnd',\r
84727 tap: 'eventOptions',\r
84728 scope: this\r
84729 };\r
84730 if (oldEl) {\r
84731 oldEl.un(eventCfg);\r
84732 }\r
84733 newEl.on(eventCfg);\r
84734 },\r
84735 \r
84736 eventOptions: function(e) {\r
84737 if (this.getPreventDefault()) {\r
84738 e.preventDefault();\r
84739 }\r
84740 if (this.getStopDefault()) {\r
84741 e.stopEvent();\r
84742 }\r
84743 },\r
84744 destroy: function() {\r
84745 this.el = Ext.destroy(this.el);\r
84746 this.callParent();\r
84747 },\r
84748 \r
84749 onTouchStart: function(e) {\r
84750 var me = this,\r
84751 pressCls = me.getPressCls();\r
84752 clearTimeout(me.getTimer());\r
84753 if (pressCls) {\r
84754 me.getEl().addCls(pressCls);\r
84755 }\r
84756 me.tapStartTime = new Date();\r
84757 me.fireEvent('touchstart', me, e);\r
84758 me.fireEvent('tap', me, e);\r
84759
84760 if (me.getAccelerate()) {\r
84761 me.delay = 400;\r
84762 }\r
84763 me.setTimer(Ext.defer(me.tap, me.getDelay() || me.getInterval(), me, [\r
84764 e\r
84765 ]));\r
84766 },\r
84767 \r
84768 tap: function(e) {\r
84769 var me = this;\r
84770 me.fireEvent('tap', me, e);\r
84771 me.setTimer(Ext.defer(me.tap, me.getAccelerate() ? me.easeOutExpo(Ext.Date.getElapsed(me.tapStartTime), 400, -390, 12000) : me.getInterval(), me, [\r
84772 e\r
84773 ]));\r
84774 },\r
84775 \r
84776 easeOutExpo: function(t, b, c, d) {\r
84777 return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;\r
84778 },\r
84779 \r
84780 onTouchEnd: function(e) {\r
84781 var me = this;\r
84782 clearTimeout(me.getTimer());\r
84783 me.getEl().removeCls(me.getPressCls());\r
84784 me.fireEvent('touchend', me, e);\r
84785 }\r
84786});\r
84787\r
84788\r
84789Ext.define('Ext.field.Spinner', {\r
84790 extend: Ext.field.Number,\r
84791 xtype: 'spinnerfield',\r
84792 alternateClassName: 'Ext.form.Spinner',\r
84793 \r
84794 \r
84795 \r
84796 \r
84797 \r
84798 config: {\r
84799 \r
84800 cls: Ext.baseCSSPrefix + 'spinner',\r
84801 \r
84802 minValue: Number.NEGATIVE_INFINITY,\r
84803 \r
84804 maxValue: Number.MAX_VALUE,\r
84805 \r
84806 stepValue: 0.1,\r
84807 \r
84808 accelerateOnTapHold: true,\r
84809 \r
84810 cycle: false,\r
84811 \r
84812 clearIcon: false,\r
84813 \r
84814 defaultValue: 0,\r
84815 \r
84816 tabIndex: -1,\r
84817 \r
84818 groupButtons: true,\r
84819 \r
84820 component: {\r
84821 disabled: true\r
84822 },\r
84823 \r
84824 value: undefined\r
84825 },\r
84826 platformConfig: {\r
84827 android: {\r
84828 component: {\r
84829 disabled: false,\r
84830 readOnly: true\r
84831 }\r
84832 }\r
84833 },\r
84834 syncEmptyCls: Ext.emptyFn,\r
84835 \r
84836 updateComponent: function(newComponent) {\r
84837 var me = this,\r
84838 cls = me.getCls();\r
84839 me.callParent(arguments);\r
84840 if (newComponent) {\r
84841 me.spinDownButton = Ext.Element.create({\r
84842 cls: cls + '-button ' + cls + '-button-down'\r
84843 });\r
84844 me.spinUpButton = Ext.Element.create({\r
84845 cls: cls + '-button ' + cls + '-button-up'\r
84846 });\r
84847 me.downRepeater = me.createRepeater(me.spinDownButton, me.onSpinDown);\r
84848 me.upRepeater = me.createRepeater(me.spinUpButton, me.onSpinUp);\r
84849 }\r
84850 },\r
84851 updateGroupButtons: function(newGroupButtons, oldGroupButtons) {\r
84852 var me = this,\r
84853 innerElement = me.innerElement,\r
84854 cls = me.getBaseCls() + '-grouped-buttons';\r
84855 me.getComponent();\r
84856 if (newGroupButtons != oldGroupButtons) {\r
84857 if (newGroupButtons) {\r
84858 me.addCls(cls);\r
84859 innerElement.appendChild(me.spinDownButton);\r
84860 innerElement.appendChild(me.spinUpButton);\r
84861 } else {\r
84862 me.removeCls(cls);\r
84863 innerElement.insertFirst(me.spinDownButton);\r
84864 innerElement.appendChild(me.spinUpButton);\r
84865 }\r
84866 }\r
84867 },\r
84868 applyValue: function(value) {\r
84869 value = parseFloat(value);\r
84870 if (isNaN(value) || value === null) {\r
84871 value = this.getDefaultValue();\r
84872 }\r
84873
84874 value = Math.round(value * 10) / 10;\r
84875 return this.callParent([\r
84876 value\r
84877 ]);\r
84878 },\r
84879 \r
84880 createRepeater: function(el, fn) {\r
84881 var me = this,\r
84882 repeater = Ext.create('Ext.util.TapRepeater', {\r
84883 el: el,\r
84884 accelerate: me.getAccelerateOnTapHold()\r
84885 });\r
84886 repeater.on({\r
84887 tap: fn,\r
84888 touchstart: 'onTouchStart',\r
84889 touchend: 'onTouchEnd',\r
84890 scope: me\r
84891 });\r
84892 return repeater;\r
84893 },\r
84894 \r
84895 onSpinDown: function() {\r
84896 if (!this.getDisabled() && !this.getReadOnly()) {\r
84897 this.spin(true);\r
84898 }\r
84899 },\r
84900 \r
84901 onSpinUp: function() {\r
84902 if (!this.getDisabled() && !this.getReadOnly()) {\r
84903 this.spin(false);\r
84904 }\r
84905 },\r
84906 \r
84907 onTouchStart: function(repeater) {\r
84908 if (!this.getDisabled() && !this.getReadOnly()) {\r
84909 repeater.getEl().addCls(Ext.baseCSSPrefix + 'button-pressed');\r
84910 }\r
84911 },\r
84912 \r
84913 onTouchEnd: function(repeater) {\r
84914 repeater.getEl().removeCls(Ext.baseCSSPrefix + 'button-pressed');\r
84915 },\r
84916 \r
84917 spin: function(down) {\r
84918 var me = this,\r
84919 originalValue = me.getValue(),\r
84920 stepValue = me.getStepValue(),\r
84921 direction = down ? 'down' : 'up',\r
84922 minValue = me.getMinValue(),\r
84923 maxValue = me.getMaxValue(),\r
84924 value;\r
84925 if (down) {\r
84926 value = originalValue - stepValue;\r
84927 } else {\r
84928 value = originalValue + stepValue;\r
84929 }\r
84930
84931 if (me.getCycle()) {\r
84932 if (originalValue == minValue && value < minValue) {\r
84933 value = maxValue;\r
84934 }\r
84935 if (originalValue == maxValue && value > maxValue) {\r
84936 value = minValue;\r
84937 }\r
84938 }\r
84939 me.setValue(value);\r
84940 value = me.getValue();\r
84941 me.fireEvent('spin', me, value, direction);\r
84942 me.fireEvent('spin' + direction, me, value);\r
84943 },\r
84944 \r
84945 updateDisabled: function(disabled) {\r
84946 Ext.Component.prototype.updateDisabled.apply(this, arguments);\r
84947 },\r
84948 \r
84949 setDisabled: function() {\r
84950 Ext.Component.prototype.setDisabled.apply(this, arguments);\r
84951 },\r
84952 reset: function() {\r
84953 this.setValue(this.getDefaultValue());\r
84954 },\r
84955
84956
84957
84958
84959
84960
84961
84962 \r
84963 destroy: function() {\r
84964 var me = this;\r
84965 Ext.destroy(me.downRepeater, me.upRepeater, me.spinDownButton, me.spinUpButton);\r
84966 me.downRepeater = me.upRepeater = me.spinDownButton = me.spinUpButton = null;\r
84967 me.callParent();\r
84968 }\r
84969});\r
84970\r
84971\r
84972Ext.define('Ext.slider.Toggle', {\r
84973 extend: Ext.slider.Slider,\r
84974 config: {\r
84975 \r
84976 baseCls: 'x-toggle',\r
84977 \r
84978 minValueCls: 'x-toggle-off',\r
84979 \r
84980 maxValueCls: 'x-toggle-on'\r
84981 },\r
84982 initialize: function() {\r
84983 this.callParent();\r
84984 this.on({\r
84985 change: 'onChange'\r
84986 });\r
84987 },\r
84988 applyMinValue: function() {\r
84989 return 0;\r
84990 },\r
84991 applyMaxValue: function() {\r
84992 return 1;\r
84993 },\r
84994 applyIncrement: function() {\r
84995 return 1;\r
84996 },\r
84997 updateMinValueCls: function(newCls, oldCls) {\r
84998 var element = this.element;\r
84999 if (oldCls && element.hasCls(oldCls)) {\r
85000 element.replaceCls(oldCls, newCls);\r
85001 }\r
85002 },\r
85003 updateMaxValueCls: function(newCls, oldCls) {\r
85004 var element = this.element;\r
85005 if (oldCls && element.hasCls(oldCls)) {\r
85006 element.replaceCls(oldCls, newCls);\r
85007 }\r
85008 },\r
85009 setValue: function(newValue, oldValue) {\r
85010 this.callParent(arguments);\r
85011 this.onChange(this, this.getThumbs()[0], newValue, oldValue);\r
85012 },\r
85013 setIndexValue: function(index, value, animation) {\r
85014 var oldValue = this.getValue()[index];\r
85015 this.callParent(arguments);\r
85016 var thumb = this.getThumb(index),\r
85017 newValue = this.getValue()[index];\r
85018 if (oldValue !== newValue) {\r
85019 this.fireEvent('change', this, thumb, newValue, oldValue);\r
85020 }\r
85021 },\r
85022 onChange: function(me, thumb, newValue, oldValue) {\r
85023 var isOn = newValue > 0,\r
85024 onCls = me.getMaxValueCls(),\r
85025 offCls = me.getMinValueCls(),\r
85026 element = this.element;\r
85027 element.addCls(isOn ? onCls : offCls);\r
85028 element.removeCls(isOn ? offCls : onCls);\r
85029 },\r
85030 toggle: function() {\r
85031 var value = this.getValue();\r
85032 this.setValue((value == 1) ? 0 : 1);\r
85033 return this;\r
85034 },\r
85035 onTap: function() {\r
85036 if (this.isDisabled() || this.getReadOnly()) {\r
85037 return;\r
85038 }\r
85039 var oldValue = this.getValue(),\r
85040 newValue = (oldValue == 1) ? 0 : 1,\r
85041 thumb = this.getThumb(0);\r
85042 this.setIndexValue(0, newValue, this.getAnimation());\r
85043 this.refreshThumbConstraints(thumb);\r
85044 }\r
85045});\r
85046\r
85047\r
85048Ext.define('Ext.field.Toggle', {\r
85049 extend: Ext.field.SingleSlider,\r
85050 xtype: 'togglefield',\r
85051 alternateClassName: 'Ext.form.Toggle',\r
85052 \r
85053 config: {\r
85054 \r
85055 cls: 'x-toggle-field',\r
85056 \r
85057 labelAlign: 'left',\r
85058 \r
85059 activeLabel: null,\r
85060 \r
85061 inactiveLabel: null,\r
85062 \r
85063 value: false\r
85064 },\r
85065 \r
85066 \r
85067 \r
85068 \r
85069 proxyConfig: {\r
85070 \r
85071 minValueCls: Ext.baseCSSPrefix + 'toggle-off',\r
85072 \r
85073 maxValueCls: Ext.baseCSSPrefix + 'toggle-on'\r
85074 },\r
85075 \r
85076 applyComponent: function(config) {\r
85077 return Ext.factory(config, Ext.slider.Toggle);\r
85078 },\r
85079 \r
85080 updateActiveLabel: function(newActiveLabel, oldActiveLabel) {\r
85081 this.getComponent().element.dom.setAttribute('data-activelabel', newActiveLabel);\r
85082 },\r
85083 \r
85084 updateInactiveLabel: function(newInactiveLabel, oldInactiveLabel) {\r
85085 this.getComponent().element.dom.setAttribute('data-inactivelabel', newInactiveLabel);\r
85086 },\r
85087 applyValue: function(value) {\r
85088 if (typeof value !== 'boolean') {\r
85089 value = value !== 0;\r
85090 }\r
85091 return value;\r
85092 },\r
85093 updateValue: function(value, oldValue) {\r
85094 var me = this,\r
85095 active = me.getActiveLabel(),\r
85096 inactive = me.getInactiveLabel();\r
85097 if (active || inactive) {\r
85098 me.setLabel(value ? active : inactive);\r
85099 }\r
85100 me.callParent([\r
85101 value,\r
85102 oldValue\r
85103 ]);\r
85104 },\r
85105 setComponentValue: function(value) {\r
85106 this.getComponent().setValue(value ? 1 : 0);\r
85107 },\r
85108 \r
85109 toggle: function() {\r
85110
85111 this.setValue(!this.getValue());\r
85112 return this;\r
85113 }\r
85114});\r
85115\r
85116\r
85117Ext.define('Ext.field.Url', {\r
85118 extend: Ext.field.Text,\r
85119 xtype: 'urlfield',\r
85120 alternateClassName: 'Ext.form.Url',\r
85121 config: {\r
85122 \r
85123 autoCapitalize: false,\r
85124 \r
85125 component: {\r
85126 type: 'url'\r
85127 }\r
85128 }\r
85129});\r
85130\r
85131\r
85132Ext.define('Ext.form.FieldSet', {\r
85133 extend: Ext.Container,\r
85134 alias: 'widget.fieldset',\r
85135 config: {\r
85136 \r
85137 baseCls: Ext.baseCSSPrefix + 'form-fieldset',\r
85138 \r
85139 title: null,\r
85140 \r
85141 instructions: null\r
85142 },\r
85143 \r
85144 applyTitle: function(title) {\r
85145 if (typeof title == 'string') {\r
85146 title = {\r
85147 title: title\r
85148 };\r
85149 }\r
85150 Ext.applyIf(title, {\r
85151 docked: 'top',\r
85152 baseCls: this.getBaseCls() + '-title'\r
85153 });\r
85154 return Ext.factory(title, Ext.Title, this._title);\r
85155 },\r
85156 \r
85157 updateTitle: function(newTitle, oldTitle) {\r
85158 if (newTitle) {\r
85159 this.add(newTitle);\r
85160 }\r
85161 if (oldTitle) {\r
85162 this.remove(oldTitle);\r
85163 }\r
85164 },\r
85165 \r
85166 getTitle: function() {\r
85167 var title = this._title;\r
85168 if (title && title instanceof Ext.Title) {\r
85169 return title.getTitle();\r
85170 }\r
85171 return title;\r
85172 },\r
85173 \r
85174 applyInstructions: function(instructions) {\r
85175 if (typeof instructions == 'string') {\r
85176 instructions = {\r
85177 title: instructions\r
85178 };\r
85179 }\r
85180 Ext.applyIf(instructions, {\r
85181 docked: 'bottom',\r
85182 baseCls: this.getBaseCls() + '-instructions'\r
85183 });\r
85184 return Ext.factory(instructions, Ext.Title, this._instructions);\r
85185 },\r
85186 \r
85187 updateInstructions: function(newInstructions, oldInstructions) {\r
85188 if (newInstructions) {\r
85189 this.add(newInstructions);\r
85190 }\r
85191 if (oldInstructions) {\r
85192 this.remove(oldInstructions);\r
85193 }\r
85194 },\r
85195 \r
85196 getInstructions: function() {\r
85197 var instructions = this._instructions;\r
85198 if (instructions && instructions instanceof Ext.Title) {\r
85199 return instructions.getTitle();\r
85200 }\r
85201 return instructions;\r
85202 },\r
85203 \r
85204 updateDisabled: function(newDisabled) {\r
85205 this.getFieldsAsArray().forEach(function(field) {\r
85206 field.setDisabled(newDisabled);\r
85207 });\r
85208 return this;\r
85209 },\r
85210 \r
85211 getFieldsAsArray: function() {\r
85212 var fields = [],\r
85213 getFieldsFrom = function(item) {\r
85214 if (item.isField) {\r
85215 fields.push(item);\r
85216 }\r
85217 if (item.isContainer) {\r
85218 item.getItems().each(getFieldsFrom);\r
85219 }\r
85220 };\r
85221 this.getItems().each(getFieldsFrom);\r
85222 return fields;\r
85223 }\r
85224});\r
85225\r
85226\r
85227Ext.define('Ext.form.Panel', {\r
85228 alternateClassName: 'Ext.form.FormPanel',\r
85229 extend: Ext.Panel,\r
85230 xtype: 'formpanel',\r
85231 \r
85232 \r
85233 \r
85234 config: {\r
85235 \r
85236 baseCls: Ext.baseCSSPrefix + 'form',\r
85237 \r
85238 standardSubmit: false,\r
85239 \r
85240 url: null,\r
85241 \r
85242 enctype: null,\r
85243 \r
85244 baseParams: null,\r
85245 \r
85246 submitOnAction: false,\r
85247 \r
85248 record: null,\r
85249 \r
85250 method: 'post',\r
85251 \r
85252 scrollable: true,\r
85253 \r
85254 trackResetOnLoad: false,\r
85255 \r
85256 api: null,\r
85257 \r
85258 paramOrder: null,\r
85259 \r
85260 paramsAsHash: null,\r
85261 \r
85262 timeout: 30,\r
85263 \r
85264 multipartDetection: true,\r
85265 \r
85266 enableSubmissionForm: true\r
85267 },\r
85268 getElementConfig: function() {\r
85269 var config = this.callParent();\r
85270 config.tag = "form";\r
85271
85272 config.children.push({\r
85273 tag: 'input',\r
85274 type: 'submit',\r
85275 style: 'visibility: hidden; width: 0; height: 0; position: absolute; right: 0; bottom: 0;'\r
85276 });\r
85277 return config;\r
85278 },\r
85279 \r
85280 initialize: function() {\r
85281 var me = this;\r
85282 me.callParent();\r
85283 me.element.on({\r
85284 submit: 'onSubmit',\r
85285 scope: me\r
85286 });\r
85287 },\r
85288 applyEnctype: function(newValue) {\r
85289 var form = this.element.dom || null;\r
85290 if (form) {\r
85291 if (newValue) {\r
85292 form.setAttribute("enctype", newValue);\r
85293 } else {\r
85294 form.setAttribute("enctype");\r
85295 }\r
85296 }\r
85297 },\r
85298 updateRecord: function(newRecord) {\r
85299 var fields, values, name;\r
85300 if (newRecord) {\r
85301 values = this.getValues();\r
85302 for (name in values) {\r
85303 if (values.hasOwnProperty(name) && newRecord.getField(name)) {\r
85304 newRecord.set(name, values[name]);\r
85305 }\r
85306 }\r
85307 }\r
85308 return this;\r
85309 },\r
85310 \r
85311 setRecord: function(record) {\r
85312 var me = this;\r
85313 if (record && record.data) {\r
85314 me.setValues(record.data);\r
85315 }\r
85316 me._record = record;\r
85317 return this;\r
85318 },\r
85319 \r
85320 onSubmit: function(e) {\r
85321 var me = this;\r
85322 if (e && !me.getStandardSubmit()) {\r
85323 e.stopEvent();\r
85324 } else {\r
85325 this.submit(null, e);\r
85326 }\r
85327 },\r
85328 updateSubmitOnAction: function(newSubmitOnAction) {\r
85329 if (newSubmitOnAction) {\r
85330 this.on({\r
85331 action: 'onFieldAction',\r
85332 scope: this\r
85333 });\r
85334 } else {\r
85335 this.un({\r
85336 action: 'onFieldAction',\r
85337 scope: this\r
85338 });\r
85339 }\r
85340 },\r
85341 \r
85342 onFieldAction: function(field) {\r
85343 if (this.getSubmitOnAction()) {\r
85344 field.blur();\r
85345 this.submit();\r
85346 }\r
85347 },\r
85348 \r
85349 submit: function(options, e) {\r
85350 options = options || {};\r
85351 var me = this,\r
85352 formValues = me.getValues(me.getStandardSubmit() || !options.submitDisabled),\r
85353 form = me.element.dom || {};\r
85354 if (this.getEnableSubmissionForm()) {\r
85355 form = this.createSubmissionForm(form, formValues);\r
85356 }\r
85357 options = Ext.apply({\r
85358 url: me.getUrl() || form.action,\r
85359 submit: false,\r
85360 form: form,\r
85361 method: me.getMethod() || form.method || 'post',\r
85362 autoAbort: false,\r
85363 params: null,\r
85364 waitMsg: null,\r
85365 headers: null,\r
85366 success: null,\r
85367 failure: null\r
85368 }, options || {});\r
85369 return me.fireAction('beforesubmit', [\r
85370 me,\r
85371 formValues,\r
85372 options,\r
85373 e\r
85374 ], 'doBeforeSubmit', null, null, 'after');\r
85375 },\r
85376 createSubmissionForm: function(form, values) {\r
85377 var fields = this.getFields(),\r
85378 name, input, field, fileinputElement, inputComponent;\r
85379 if (form.nodeType === 1) {\r
85380 form = form.cloneNode(false);\r
85381 for (name in values) {\r
85382 input = document.createElement("input");\r
85383 input.setAttribute("type", "text");\r
85384 input.setAttribute("name", name);\r
85385 input.setAttribute("value", values[name]);\r
85386 form.appendChild(input);\r
85387 }\r
85388 }\r
85389 for (name in fields) {\r
85390 if (fields.hasOwnProperty(name)) {\r
85391 field = fields[name];\r
85392 if (field.isFile) {\r
85393 if (!form.$fileswap) {\r
85394 form.$fileswap = [];\r
85395 }\r
85396 \r
85397 inputComponent = field.getComponent().input;\r
85398 fileinputElement = inputComponent.dom;\r
85399 input = fileinputElement.cloneNode(true);\r
85400 fileinputElement.parentNode.insertBefore(input, fileinputElement.nextSibling);\r
85401 form.appendChild(fileinputElement);\r
85402 form.$fileswap.push({\r
85403 original: fileinputElement,\r
85404 placeholder: input\r
85405 });\r
85406 } else if (field.isPassword) {\r
85407 if (field.getComponent().getType !== "password") {\r
85408 field.setRevealed(false);\r
85409 }\r
85410 }\r
85411 }\r
85412 }\r
85413 return form;\r
85414 },\r
85415 doBeforeSubmit: function(me, formValues, options) {\r
85416 var form = options.form || {},\r
85417 multipartDetected = false;\r
85418 if (this.getMultipartDetection() === true) {\r
85419 this.getFieldsAsArray().forEach(function(field) {\r
85420 if (field.isFile === true) {\r
85421 multipartDetected = true;\r
85422 return false;\r
85423 }\r
85424 });\r
85425 if (multipartDetected) {\r
85426 form.setAttribute("enctype", "multipart/form-data");\r
85427 }\r
85428 }\r
85429 if (options.enctype) {\r
85430 form.setAttribute("enctype", options.enctype);\r
85431 }\r
85432 if (me.getStandardSubmit()) {\r
85433 if (options.url && Ext.isEmpty(form.action)) {\r
85434 form.action = options.url;\r
85435 }\r
85436
85437
85438 var fields = this.query('spinnerfield'),\r
85439 ln = fields.length,\r
85440 i, field;\r
85441 for (i = 0; i < ln; i++) {\r
85442 field = fields[i];\r
85443 if (!field.getDisabled()) {\r
85444 field.getComponent().setDisabled(false);\r
85445 }\r
85446 }\r
85447 form.method = (options.method || form.method).toLowerCase();\r
85448 form.submit();\r
85449 } else {\r
85450 var api = me.getApi(),\r
85451 url = options.url || me.getUrl(),\r
85452 scope = options.scope || me,\r
85453 waitMsg = options.waitMsg,\r
85454 failureFn = function(response, responseText) {\r
85455 if (Ext.isFunction(options.failure)) {\r
85456 options.failure.call(scope, me, response, responseText);\r
85457 }\r
85458 me.fireEvent('exception', me, response);\r
85459 },\r
85460 successFn = function(response, responseText) {\r
85461 if (Ext.isFunction(options.success)) {\r
85462 options.success.call(options.scope || me, me, response, responseText);\r
85463 }\r
85464 me.fireEvent('submit', me, response);\r
85465 },\r
85466 submit;\r
85467 if (options.waitMsg) {\r
85468 if (typeof waitMsg === 'string') {\r
85469 waitMsg = {\r
85470 xtype: 'loadmask',\r
85471 message: waitMsg\r
85472 };\r
85473 }\r
85474 me.setMasked(waitMsg);\r
85475 }\r
85476 if (api) {\r
85477 submit = api.submit;\r
85478 if (typeof submit === 'string') {\r
85479 submit = Ext.direct.Manager.parseMethod(submit);\r
85480 if (submit) {\r
85481 api.submit = submit;\r
85482 }\r
85483 }\r
85484 if (submit) {\r
85485 return submit(this.element, function(data, response, success) {\r
85486 me.setMasked(false);\r
85487 if (success) {\r
85488 if (data.success) {\r
85489 successFn(response, data);\r
85490 } else {\r
85491 failureFn(response, data);\r
85492 }\r
85493 } else {\r
85494 failureFn(response, data);\r
85495 }\r
85496 }, this);\r
85497 }\r
85498 } else {\r
85499 var request = Ext.merge({}, {\r
85500 url: url,\r
85501 timeout: this.getTimeout() * 1000,\r
85502 form: form,\r
85503 scope: me\r
85504 }, options);\r
85505 delete request.success;\r
85506 delete request.failure;\r
85507 request.params = Ext.merge(me.getBaseParams() || {}, options.params);\r
85508 request.header = Ext.apply({\r
85509 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'\r
85510 }, options.headers || {});\r
85511 request.callback = function(callbackOptions, success, response) {\r
85512 var me = this,\r
85513 responseText = response.responseText,\r
85514 responseXML = response.responseXML,\r
85515 statusResult = Ext.data.request.Ajax.parseStatus(response.status, response);\r
85516 if (form.$fileswap) {\r
85517 var original, placeholder;\r
85518 Ext.each(form.$fileswap, function(item) {\r
85519 original = item.original;\r
85520 placeholder = item.placeholder;\r
85521 placeholder.parentNode.insertBefore(original, placeholder.nextSibling);\r
85522 placeholder.parentNode.removeChild(placeholder);\r
85523 });\r
85524 form.$fileswap = null;\r
85525 delete form.$fileswap;\r
85526 }\r
85527 me.setMasked(false);\r
85528 if (response.success === false) {\r
85529 success = false;\r
85530 }\r
85531 \r
85532 if (success) {\r
85533 if (statusResult && responseText && responseText.length === 0) {\r
85534 success = true;\r
85535 } else {\r
85536 if (!Ext.isEmpty(response.responseBytes)) {\r
85537 success = statusResult.success;\r
85538 } else {\r
85539 if (Ext.isString(responseText) && response.request.options.responseType === "text") {\r
85540 response.success = true;\r
85541 } else if (Ext.isString(responseText)) {\r
85542 try {\r
85543 response = Ext.decode(responseText);\r
85544 } catch (e) {\r
85545 response.success = false;\r
85546 response.error = e;\r
85547 response.message = e.message;\r
85548 }\r
85549 } else if (Ext.isSimpleObject(responseText)) {\r
85550 response = responseText;\r
85551 Ext.applyIf(response, {\r
85552 success: true\r
85553 });\r
85554 }\r
85555 if (!Ext.isEmpty(responseXML)) {\r
85556 response.success = true;\r
85557 }\r
85558 success = !!response.success;\r
85559 }\r
85560 }\r
85561 if (success) {\r
85562 successFn(response, responseText);\r
85563 } else {\r
85564 failureFn(response, responseText);\r
85565 }\r
85566 } else {\r
85567 failureFn(response, responseText);\r
85568 }\r
85569 };\r
85570 if (Ext.feature.has.XHR2 && request.xhr2) {\r
85571 delete request.form;\r
85572 var formData = new FormData(form);\r
85573 if (request.params) {\r
85574 Ext.iterate(request.params, function(name, value) {\r
85575 if (Ext.isArray(value)) {\r
85576 Ext.each(value, function(v) {\r
85577 formData.append(name, v);\r
85578 });\r
85579 } else {\r
85580 formData.append(name, value);\r
85581 }\r
85582 });\r
85583 delete request.params;\r
85584 }\r
85585 request.data = formData;\r
85586 }\r
85587 return Ext.Ajax.request(request);\r
85588 }\r
85589 }\r
85590 },\r
85591 \r
85592 load: function(options) {\r
85593 options = options || {};\r
85594 var me = this,\r
85595 api = me.getApi(),\r
85596 url = me.getUrl() || options.url,\r
85597 waitMsg = options.waitMsg,\r
85598 successFn = function(response, data) {\r
85599 me.setValues(data.data);\r
85600 if (Ext.isFunction(options.success)) {\r
85601 options.success.call(options.scope || me, me, response, data);\r
85602 }\r
85603 me.fireEvent('load', me, response);\r
85604 },\r
85605 failureFn = function(response, data) {\r
85606 if (Ext.isFunction(options.failure)) {\r
85607 options.failure.call(scope, me, response, data);\r
85608 }\r
85609 me.fireEvent('exception', me, response);\r
85610 },\r
85611 load, method, args;\r
85612 if (options.waitMsg) {\r
85613 if (typeof waitMsg === 'string') {\r
85614 waitMsg = {\r
85615 xtype: 'loadmask',\r
85616 message: waitMsg\r
85617 };\r
85618 }\r
85619 me.setMasked(waitMsg);\r
85620 }\r
85621 if (api) {\r
85622 load = api.load;\r
85623 if (typeof load === 'string') {\r
85624 load = Ext.direct.Manager.parseMethod(load);\r
85625 if (load) {\r
85626 api.load = load;\r
85627 }\r
85628 }\r
85629 if (load) {\r
85630 method = load.directCfg.method;\r
85631 args = method.getArgs(me.getParams(options.params), me.getParamOrder(), me.getParamsAsHash());\r
85632 args.push(function(data, response, success) {\r
85633 me.setMasked(false);\r
85634 if (success) {\r
85635 successFn(response, data);\r
85636 } else {\r
85637 failureFn(response, data);\r
85638 }\r
85639 }, me);\r
85640 return load.apply(window, args);\r
85641 }\r
85642 } else if (url) {\r
85643 return Ext.Ajax.request({\r
85644 url: url,\r
85645 timeout: (options.timeout || this.getTimeout()) * 1000,\r
85646 method: options.method || 'GET',\r
85647 autoAbort: options.autoAbort,\r
85648 headers: Ext.apply({\r
85649 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'\r
85650 }, options.headers || {}),\r
85651 callback: function(callbackOptions, success, response) {\r
85652 var responseText = response.responseText,\r
85653 statusResult = Ext.data.request.Ajax.parseStatus(response.status, response);\r
85654 me.setMasked(false);\r
85655 if (success) {\r
85656 if (statusResult && responseText.length === 0) {\r
85657 success = true;\r
85658 } else {\r
85659 response = Ext.decode(responseText);\r
85660 success = !!response.success;\r
85661 }\r
85662 if (success) {\r
85663 successFn(response, responseText);\r
85664 } else {\r
85665 failureFn(response, responseText);\r
85666 }\r
85667 } else {\r
85668 failureFn(response, responseText);\r
85669 }\r
85670 }\r
85671 });\r
85672 }\r
85673 },\r
85674 \r
85675 getParams: function(params) {\r
85676 return Ext.apply({}, params, this.getBaseParams());\r
85677 },\r
85678 \r
85679 setValues: function(values) {\r
85680 var fields = this.getFields(),\r
85681 me = this,\r
85682 name, field, value, ln, i, f;\r
85683 values = values || {};\r
85684 for (name in values) {\r
85685 if (values.hasOwnProperty(name)) {\r
85686 field = fields[name];\r
85687 value = values[name];\r
85688 if (field) {\r
85689
85690 if (Ext.isArray(field)) {\r
85691 ln = field.length;\r
85692
85693 for (i = 0; i < ln; i++) {\r
85694 f = field[i];\r
85695 if (f.isRadio) {\r
85696
85697 f.setGroupValue(value);\r
85698 break;\r
85699 } else if (f.isCheckbox) {\r
85700 if (Ext.isArray(value)) {\r
85701 f.setChecked((value.indexOf(f._value) != -1));\r
85702 } else {\r
85703 f.setChecked((value == f._value));\r
85704 }\r
85705 } else {\r
85706
85707
85708 if (Ext.isArray(value)) {\r
85709 f.setValue(value[i]);\r
85710 }\r
85711 }\r
85712 }\r
85713 } else {\r
85714 if (field.isRadio || field.isCheckbox) {\r
85715
85716 field.setChecked(value);\r
85717 } else {\r
85718
85719 field.setValue(value);\r
85720 }\r
85721 }\r
85722 if (me.getTrackResetOnLoad()) {\r
85723 field.resetOriginalValue();\r
85724 }\r
85725 }\r
85726 }\r
85727 }\r
85728 return this;\r
85729 },\r
85730 \r
85731 getValues: function(enabled, all) {\r
85732 var fields = this.getFields(),\r
85733 values = {},\r
85734 isArray = Ext.isArray,\r
85735 field, value, addValue, bucket, name, ln, i;\r
85736
85737
85738 addValue = function(field, name) {\r
85739 if (!all && (!name || name === 'null') || field.isFile) {\r
85740 return;\r
85741 }\r
85742 if (field.isCheckbox) {\r
85743 value = field.getSubmitValue();\r
85744 } else {\r
85745 value = field.getValue();\r
85746 }\r
85747 if (!(enabled && field.getDisabled())) {\r
85748
85749
85750 if (field.isRadio) {\r
85751 if (field.isChecked()) {\r
85752 values[name] = value;\r
85753 }\r
85754 } else {\r
85755
85756 bucket = values[name];\r
85757 if (!Ext.isEmpty(bucket)) {\r
85758
85759
85760 if (!isArray(bucket)) {\r
85761 bucket = values[name] = [\r
85762 bucket\r
85763 ];\r
85764 }\r
85765
85766 if (isArray(value)) {\r
85767
85768 bucket = values[name] = bucket.concat(value);\r
85769 } else {\r
85770
85771 bucket.push(value);\r
85772 }\r
85773 } else {\r
85774 values[name] = value;\r
85775 }\r
85776 }\r
85777 }\r
85778 };\r
85779
85780 for (name in fields) {\r
85781 if (fields.hasOwnProperty(name)) {\r
85782 field = fields[name];\r
85783 if (isArray(field)) {\r
85784 ln = field.length;\r
85785 for (i = 0; i < ln; i++) {\r
85786 addValue(field[i], name);\r
85787 }\r
85788 } else {\r
85789 addValue(field, name);\r
85790 }\r
85791 }\r
85792 }\r
85793 return values;\r
85794 },\r
85795 \r
85796 reset: function() {\r
85797 this.getFieldsAsArray().forEach(function(field) {\r
85798 field.reset();\r
85799 });\r
85800 return this;\r
85801 },\r
85802 \r
85803 updateDisabled: function(newDisabled) {\r
85804 this.getFieldsAsArray().forEach(function(field) {\r
85805 field.setDisabled(newDisabled);\r
85806 });\r
85807 return this;\r
85808 },\r
85809 \r
85810 getFieldsAsArray: function() {\r
85811 var fields = [],\r
85812 getFieldsFrom = function(item) {\r
85813 if (item.isField) {\r
85814 fields.push(item);\r
85815 }\r
85816 if (item.isContainer) {\r
85817 item.getItems().each(getFieldsFrom);\r
85818 }\r
85819 };\r
85820 this.getItems().each(getFieldsFrom);\r
85821 return fields;\r
85822 },\r
85823 \r
85824 getFields: function(byName) {\r
85825 var fields = {},\r
85826 itemName;\r
85827 var getFieldsFrom = function(item) {\r
85828 if (item.isField) {\r
85829 itemName = item.getName();\r
85830 if ((byName && itemName == byName) || typeof byName == 'undefined') {\r
85831 if (fields.hasOwnProperty(itemName)) {\r
85832 if (!Ext.isArray(fields[itemName])) {\r
85833 fields[itemName] = [\r
85834 fields[itemName]\r
85835 ];\r
85836 }\r
85837 fields[itemName].push(item);\r
85838 } else {\r
85839 fields[itemName] = item;\r
85840 }\r
85841 }\r
85842 }\r
85843 if (item.isContainer) {\r
85844 item.items.each(getFieldsFrom);\r
85845 }\r
85846 };\r
85847 this.getItems().each(getFieldsFrom);\r
85848 return (byName) ? (fields[byName] || []) : fields;\r
85849 },\r
85850 \r
85851 getFieldsArray: function() {\r
85852 var fields = [];\r
85853 var getFieldsFrom = function(item) {\r
85854 if (item.isField) {\r
85855 fields.push(item);\r
85856 }\r
85857 if (item.isContainer) {\r
85858 item.items.each(getFieldsFrom);\r
85859 }\r
85860 };\r
85861 this.items.each(getFieldsFrom);\r
85862 return fields;\r
85863 },\r
85864 getFieldsFromItem: Ext.emptyFn,\r
85865 \r
85866 showMask: function(cfg, target) {\r
85867
85868 Ext.Logger.warn('showMask is now deprecated. Please use Ext.form.Panel#setMasked instead');\r
85869
85870 cfg = Ext.isObject(cfg) ? cfg.message : cfg;\r
85871 if (cfg) {\r
85872 this.setMasked({\r
85873 xtype: 'loadmask',\r
85874 message: cfg\r
85875 });\r
85876 } else {\r
85877 this.setMasked(true);\r
85878 }\r
85879 return this;\r
85880 },\r
85881 \r
85882 hideMask: function() {\r
85883 this.setMasked(false);\r
85884 return this;\r
85885 },\r
85886 \r
85887 getFocusedField: function() {\r
85888 var fields = this.getFieldsArray(),\r
85889 ln = fields.length,\r
85890 field, i;\r
85891 for (i = 0; i < ln; i++) {\r
85892 field = fields[i];\r
85893 if (field.isFocused) {\r
85894 return field;\r
85895 }\r
85896 }\r
85897 return null;\r
85898 },\r
85899 \r
85900 getNextField: function() {\r
85901 var fields = this.getFieldsArray(),\r
85902 focusedField = this.getFocusedField(),\r
85903 index;\r
85904 if (focusedField) {\r
85905 index = fields.indexOf(focusedField);\r
85906 if (index !== fields.length - 1) {\r
85907 index++;\r
85908 return fields[index];\r
85909 }\r
85910 }\r
85911 return false;\r
85912 },\r
85913 \r
85914 focusNextField: function() {\r
85915 var field = this.getNextField();\r
85916 if (field) {\r
85917 field.focus();\r
85918 return field;\r
85919 }\r
85920 return false;\r
85921 },\r
85922 \r
85923 getPreviousField: function() {\r
85924 var fields = this.getFieldsArray(),\r
85925 focusedField = this.getFocusedField(),\r
85926 index;\r
85927 if (focusedField) {\r
85928 index = fields.indexOf(focusedField);\r
85929 if (index !== 0) {\r
85930 index--;\r
85931 return fields[index];\r
85932 }\r
85933 }\r
85934 return false;\r
85935 },\r
85936 \r
85937 focusPreviousField: function() {\r
85938 var field = this.getPreviousField();\r
85939 if (field) {\r
85940 field.focus();\r
85941 return field;\r
85942 }\r
85943 return false;\r
85944 }\r
85945});\r
85946\r
85947\r
85948Ext.define('Ext.grid.cell.Base', {\r
85949 extend: Ext.Widget,\r
85950 cachedConfig: {\r
85951 \r
85952 align: 'left',\r
85953 \r
85954 cls: null,\r
85955 \r
85956 hidden: false,\r
85957 \r
85958 innerCls: null\r
85959 },\r
85960 config: {\r
85961 \r
85962 column: null,\r
85963 \r
85964 record: null,\r
85965 \r
85966 value: null\r
85967 },\r
85968 element: {\r
85969 reference: 'element',\r
85970 cls: Ext.baseCSSPrefix + 'grid-cell',\r
85971 children: [\r
85972 {\r
85973 reference: 'innerElement',\r
85974 cls: Ext.baseCSSPrefix + 'grid-cell-inner'\r
85975 }\r
85976 ]\r
85977 },\r
85978 defaultBindProperty: 'value',\r
85979 hiddenCls: Ext.baseCSSPrefix + 'grid-cell-hidden',\r
85980 getComputedWidth: function() {\r
85981 return this.getHidden() ? 0 : this.getWidth();\r
85982 },\r
85983 updateAlign: function(align, oldAlign) {\r
85984 var prefix = Ext.baseCSSPrefix + 'grid-cell-align-';\r
85985 this.element.replaceCls(prefix + oldAlign, prefix + align);\r
85986 },\r
85987 updateCls: function(cls, oldCls) {\r
85988 this.element.replaceCls(oldCls, cls);\r
85989 },\r
85990 updateInnerCls: function(cellCls, oldCellCls) {\r
85991 if (cellCls || oldCellCls) {\r
85992 this.innerElement.replaceCls(oldCellCls, cellCls);\r
85993 }\r
85994 },\r
85995 updateColumn: function(column) {\r
85996 this.dataIndex = column ? column.getDataIndex() : null;\r
85997 },\r
85998 applyHidden: function(hidden) {\r
85999 return Boolean(hidden);\r
86000 },\r
86001 updateHidden: function(hidden) {\r
86002 this.element.toggleCls(this.hiddenCls, hidden);\r
86003 },\r
86004 updateRecord: function(record) {\r
86005 var dataIndex = this.dataIndex;\r
86006 if (record && dataIndex) {\r
86007 this.setValue(record.get(dataIndex));\r
86008 }\r
86009 },\r
86010 destroy: function() {\r
86011 this.setColumn(null);\r
86012 this.setRecord(null);\r
86013 this.callParent();\r
86014 }\r
86015});\r
86016\r
86017\r
86018Ext.define('Ext.grid.cell.Text', {\r
86019 extend: Ext.grid.cell.Base,\r
86020 xtype: 'textcell',\r
86021 config: {\r
86022 \r
86023 encodeHtml: true,\r
86024 \r
86025 rawValue: null\r
86026 },\r
86027 updateRawValue: function(rawValue) {\r
86028 var dom = this.innerElement.dom;\r
86029 if (this.getEncodeHtml()) {\r
86030 dom.textContent = rawValue;\r
86031 } else {\r
86032 dom.innerHTML = rawValue;\r
86033 }\r
86034 },\r
86035 updateValue: function() {\r
86036 this.writeValue();\r
86037 },\r
86038 writeValue: function() {\r
86039 this.setRawValue(this.getValue());\r
86040 }\r
86041});\r
86042\r
86043\r
86044Ext.define('Ext.grid.cell.Cell', {\r
86045 extend: Ext.grid.cell.Text,\r
86046 xtype: 'gridcell',\r
86047 updateRecord: function(record, oldRecord) {\r
86048 var me = this,\r
86049 column = me.getColumn(),\r
86050 dataIndex, tpl, renderer, raw, scope, setRaw, value;\r
86051 if (record && column) {\r
86052 tpl = column.getTpl();\r
86053 renderer = column.getRenderer();\r
86054 if (tpl) {\r
86055 raw = tpl.apply(record.getData(true));\r
86056 setRaw = true;\r
86057 } else if (renderer) {\r
86058 dataIndex = me.dataIndex;\r
86059 value = dataIndex ? record.get(dataIndex) : undefined;\r
86060 scope = column.getScope();\r
86061 if (typeof renderer === 'function') {\r
86062 raw = renderer.call(scope || column, value, record, dataIndex, me, column);\r
86063 } else {\r
86064 raw = Ext.callback(renderer, scope, [\r
86065 value,\r
86066 record,\r
86067 dataIndex,\r
86068 me,\r
86069 column\r
86070 ], 0, me);\r
86071 }\r
86072 setRaw = true;\r
86073 }\r
86074 if (setRaw) {\r
86075 me.setRawValue(raw);\r
86076 return;\r
86077 }\r
86078 }\r
86079 me.callParent([\r
86080 record,\r
86081 oldRecord\r
86082 ]);\r
86083 }\r
86084});\r
86085\r
86086\r
86087Ext.define('Ext.grid.Row', {\r
86088 extend: Ext.Component,\r
86089 xtype: 'gridrow',\r
86090 mixins: [\r
86091 Ext.mixin.Queryable\r
86092 ],\r
86093 config: {\r
86094 baseCls: Ext.baseCSSPrefix + 'grid-row',\r
86095 header: {\r
86096 xtype: 'component',\r
86097 cls: 'x-grid-header',\r
86098 html: ' '\r
86099 },\r
86100 grid: null\r
86101 },\r
86102 constructor: function(config) {\r
86103 this.cells = [];\r
86104 this.columnMap = {};\r
86105 this.callParent([\r
86106 config\r
86107 ]);\r
86108 },\r
86109 applyHeader: function(header) {\r
86110 if (header && !header.isComponent) {\r
86111 header = Ext.factory(header, Ext.Component, this.getHeader());\r
86112 }\r
86113 return header;\r
86114 },\r
86115 updateHeader: function(header, oldHeader) {\r
86116 if (oldHeader) {\r
86117 oldHeader.destroy();\r
86118 }\r
86119 },\r
86120 updateGrid: function(grid) {\r
86121 var me = this,\r
86122 i, columns, ln;\r
86123 if (grid) {\r
86124 columns = grid.getColumns();\r
86125 for (i = 0 , ln = columns.length; i < ln; i++) {\r
86126 me.addColumn(columns[i]);\r
86127 }\r
86128 }\r
86129 },\r
86130 addColumn: function(column) {\r
86131 this.insertColumn(this.cells.length, column);\r
86132 },\r
86133 getRefItems: function() {\r
86134 return this.cells;\r
86135 },\r
86136 insertColumn: function(index, column) {\r
86137 var me = this,\r
86138 cells = me.cells,\r
86139 cell = me.createCell(column);\r
86140 if (index === cells.length) {\r
86141 me.element.appendChild(cell.element);\r
86142 cells.push(cell);\r
86143 } else {\r
86144 cell.element.insertBefore(cells[index].element);\r
86145 cells.splice(index, 0, cell);\r
86146 }\r
86147 me.columnMap[column.getId()] = cell;\r
86148 },\r
86149 moveColumn: function(column, fromIdx, toIdx) {\r
86150 var cells = this.cells,\r
86151 cell = cells[fromIdx];\r
86152 Ext.Array.move(cells, fromIdx, toIdx);\r
86153 if (toIdx === cells.length - 1) {\r
86154 this.element.appendChild(cell.element);\r
86155 } else {\r
86156 cell.element.insertBefore(cells[toIdx + 1].element);\r
86157 }\r
86158 },\r
86159 removeColumn: function(column) {\r
86160 var me = this,\r
86161 columnMap = me.columnMap,\r
86162 columnId = column.getId(),\r
86163 cell = columnMap[columnId];\r
86164 if (cell) {\r
86165 Ext.Array.remove(me.cells, cell);\r
86166 delete columnMap[columnId];\r
86167 cell.destroy();\r
86168 }\r
86169 },\r
86170 updateRecord: function(record) {\r
86171 if (!record) {\r
86172 return;\r
86173 }\r
86174 var cells = this.cells,\r
86175 len = cells.length,\r
86176 i, cell;\r
86177 for (i = 0; i < len; ++i) {\r
86178 cell = cells[i];\r
86179 if (cell.getRecord() === record) {\r
86180 cell.updateRecord(record);\r
86181 } else {\r
86182 cell.setRecord(record);\r
86183 }\r
86184 }\r
86185 },\r
86186 setColumnWidth: function(column, width) {\r
86187 var cell = this.getCellByColumn(column);\r
86188 if (cell) {\r
86189 cell.setWidth(width);\r
86190 }\r
86191 },\r
86192 showColumn: function(column) {\r
86193 this.setCellHidden(column, false);\r
86194 },\r
86195 hideColumn: function(column) {\r
86196 this.setCellHidden(column, true);\r
86197 },\r
86198 getCellByColumn: function(column) {\r
86199 return this.columnMap[column.getId()];\r
86200 },\r
86201 getColumnByCell: function(cell) {\r
86202 return cell.getColumn();\r
86203 },\r
86204 destroy: function() {\r
86205 var me = this;\r
86206 me.cells = Ext.destroy(me.cells, me.getHeader());\r
86207 me.setRecord(null);\r
86208 me.callParent();\r
86209 },\r
86210 privates: {\r
86211 createCell: function(column) {\r
86212 var cell = this.getCellCfg(column);\r
86213 cell.$initParent = this;\r
86214 cell = Ext.create(cell);\r
86215 delete cell.$initParent;\r
86216 return cell;\r
86217 },\r
86218 getCellCfg: function(column) {\r
86219 return Ext.apply({\r
86220 parent: this,\r
86221 column: column,\r
86222 record: this.getRecord(),\r
86223 hidden: column.getHidden(),\r
86224 width: column.getComputedWidth()\r
86225 }, column.getCell());\r
86226 },\r
86227 setCellHidden: function(column, hidden) {\r
86228 var cell = this.getCellByColumn(column);\r
86229 if (cell) {\r
86230 cell.setHidden(hidden);\r
86231 }\r
86232 }\r
86233 }\r
86234});\r
86235\r
86236\r
86237Ext.define('Ext.grid.column.Column', {\r
86238 extend: Ext.Component,\r
86239 alternateClassName: 'Ext.grid.column.Template',\r
86240 xtype: [\r
86241 'column',\r
86242 'templatecolumn'\r
86243 ],\r
86244 config: {\r
86245 \r
86246 align: 'left',\r
86247 \r
86248 cell: {\r
86249 xtype: 'gridcell'\r
86250 },\r
86251 \r
86252 dataIndex: null,\r
86253 \r
86254 text: '&nbsp;',\r
86255 \r
86256 sortable: true,\r
86257 \r
86258 groupable: true,\r
86259 \r
86260 resizable: true,\r
86261 \r
86262 hideable: true,\r
86263 \r
86264 renderer: false,\r
86265 \r
86266 scope: null,\r
86267 \r
86268 editable: false,\r
86269 \r
86270 editor: null,\r
86271 \r
86272 defaultEditor: {\r
86273 xtype: 'textfield',\r
86274 required: true\r
86275 },\r
86276 \r
86277 ignore: false,\r
86278 \r
86279 summaryType: null,\r
86280 \r
86281 summaryRenderer: null,\r
86282 minWidth: 40,\r
86283 baseCls: Ext.baseCSSPrefix + 'grid-column',\r
86284 sortedCls: Ext.baseCSSPrefix + 'column-sorted',\r
86285 sortDirection: null,\r
86286 \r
86287 tpl: null,\r
86288 \r
86289 computedWidth: null\r
86290 },\r
86291 applyTpl: function(tpl) {\r
86292 if (!tpl || !tpl.isXTemplate) {\r
86293 tpl = new Ext.XTemplate(tpl);\r
86294 }\r
86295 return tpl;\r
86296 },\r
86297 updateAlign: function(align, oldAlign) {\r
86298 var prefix = Ext.baseCSSPrefix + 'grid-column-align-';\r
86299 if (oldAlign) {\r
86300 this.removeCls(prefix + align);\r
86301 }\r
86302 if (align) {\r
86303 this.addCls(prefix + align);\r
86304 }\r
86305 },\r
86306 initialize: function() {\r
86307 this.callParent();\r
86308 this.element.on({\r
86309 tap: 'onColumnTap',\r
86310 longpress: 'onColumnLongPress',\r
86311 scope: this\r
86312 });\r
86313 },\r
86314 onColumnTap: function(e) {\r
86315 this.fireEvent('tap', this, e);\r
86316 },\r
86317 onColumnLongPress: function(e) {\r
86318 this.fireEvent('longpress', this, e);\r
86319 },\r
86320 updateText: function(text) {\r
86321 this.setHtml(text || '&#160;');\r
86322 },\r
86323 updateWidth: function(width, oldWidth) {\r
86324 this.callParent([\r
86325 width,\r
86326 oldWidth\r
86327 ]);\r
86328
86329
86330 if (width !== null) {\r
86331 this.setComputedWidth(width);\r
86332 }\r
86333 },\r
86334 updateFlex: function(flex, oldFlex) {\r
86335 var me = this,\r
86336 listener = me.resizeListener;\r
86337 me.callParent([\r
86338 flex,\r
86339 oldFlex\r
86340 ]);\r
86341 if (!flex) {\r
86342 me.resizeListener = Ext.destroy(listener);\r
86343 } else if (!listener) {\r
86344 me.resizeListener = me.on('resize', me.onFlexResize, me, {\r
86345 destroyable: true\r
86346 });\r
86347 }\r
86348 },\r
86349 onFlexResize: function() {\r
86350 this.setComputedWidth(this.element.getWidth(false, true));\r
86351 },\r
86352 getComputedWidth: function() {\r
86353 return this.isVisible(true) ? this.callParent() : 0;\r
86354 },\r
86355 updateComputedWidth: function(computedWidth, oldComputedWidth) {\r
86356 this.fireEvent('columnresize', this, computedWidth, oldComputedWidth);\r
86357 },\r
86358 updateDataIndex: function(dataIndex) {\r
86359 var editor = this.getEditor();\r
86360 if (editor) {\r
86361 editor.name = dataIndex;\r
86362 } else {\r
86363 this.getDefaultEditor().name = dataIndex;\r
86364 }\r
86365 },\r
86366 updateSortDirection: function(direction, oldDirection) {\r
86367 if (!this.getSortable()) {\r
86368 return;\r
86369 }\r
86370 var sortedCls = this.getSortedCls();\r
86371 if (oldDirection) {\r
86372 this.element.removeCls(sortedCls + '-' + oldDirection.toLowerCase());\r
86373 }\r
86374 if (direction) {\r
86375 this.element.addCls(sortedCls + '-' + direction.toLowerCase());\r
86376 }\r
86377 this.fireEvent('sort', this, direction, oldDirection);\r
86378 },\r
86379 destroy: function() {\r
86380 this.resizeListener = Ext.destroy(this.resizeListener);\r
86381 this.callParent();\r
86382 }\r
86383});\r
86384\r
86385\r
86386Ext.define('Ext.grid.cell.Date', {\r
86387 extend: Ext.grid.cell.Text,\r
86388 xtype: 'datecell',\r
86389 config: {\r
86390 \r
86391 format: ''\r
86392 },\r
86393 updateColumn: function(column, oldColumn) {\r
86394 this.callParent([\r
86395 column,\r
86396 oldColumn\r
86397 ]);\r
86398 if (column) {\r
86399 var format = column.getFormat();\r
86400 if (format !== null) {\r
86401 this.setFormat(format);\r
86402 }\r
86403 }\r
86404 },\r
86405 applyFormat: function(format) {\r
86406 return format || Ext.Date.defaultFormat;\r
86407 },\r
86408 updateFormat: function(format) {\r
86409 if (!this.isConfiguring) {\r
86410 this.writeValue();\r
86411 }\r
86412 },\r
86413 writeValue: function() {\r
86414 var value = this.getValue();\r
86415 this.setRawValue(value ? Ext.Date.format(value, this.getFormat()) : null);\r
86416 }\r
86417});\r
86418\r
86419\r
86420Ext.define('Ext.grid.column.Date', {\r
86421 extend: Ext.grid.column.Column,\r
86422 xtype: 'datecolumn',\r
86423 config: {\r
86424 \r
86425 format: null,\r
86426 cell: {\r
86427 xtype: 'datecell'\r
86428 }\r
86429 }\r
86430});\r
86431\r
86432\r
86433Ext.define('Ext.grid.HeaderContainer', {\r
86434 extend: Ext.Container,\r
86435 xtype: 'headercontainer',\r
86436 config: {\r
86437 baseCls: Ext.baseCSSPrefix + 'grid-header-container',\r
86438 docked: 'top',\r
86439 defaultType: 'column',\r
86440 layout: {\r
86441 type: 'hbox',\r
86442 align: 'stretch'\r
86443 },\r
86444 \r
86445 sortable: true,\r
86446 scrollable: {\r
86447 autoRefresh: null,\r
86448 x: false,\r
86449 y: false\r
86450 },\r
86451 grid: null\r
86452 },\r
86453 initialize: function() {\r
86454 var me = this;\r
86455 me.columns = [];\r
86456 me.callParent();\r
86457 me.on({\r
86458 tap: 'onHeaderTap',\r
86459 columnresize: 'onColumnResize',\r
86460 show: 'onColumnShow',\r
86461 hide: 'onColumnHide',\r
86462 sort: 'onColumnSort',\r
86463 scope: me,\r
86464 delegate: 'column'\r
86465 });\r
86466 me.on({\r
86467 show: 'onGroupShow',\r
86468 hide: 'onGroupHide',\r
86469 add: 'onColumnAdd',\r
86470 move: 'onColumnMove',\r
86471 remove: 'onColumnRemove',\r
86472 scope: me,\r
86473 delegate: 'gridheadergroup'\r
86474 });\r
86475 me.on({\r
86476 add: 'onColumnAdd',\r
86477 move: 'onColumnMove',\r
86478 remove: 'onColumnRemove',\r
86479 scope: me\r
86480 });\r
86481 },\r
86482 factoryItem: function(item) {\r
86483
86484 if (item.columns) {\r
86485 return Ext.factory(item, Ext.grid.HeaderGroup);\r
86486 }\r
86487 return this.callParent([\r
86488 item\r
86489 ]);\r
86490 },\r
86491 getColumns: function() {\r
86492 return this.columns;\r
86493 },\r
86494 getAbsoluteColumnIndex: function(column) {\r
86495 var items = this.getInnerItems(),\r
86496 ln = items.length,\r
86497 index = 0,\r
86498 innerIndex, i, item;\r
86499 for (i = 0; i < ln; i++) {\r
86500 item = items[i];\r
86501 if (item === column) {\r
86502 return index;\r
86503 } else if (item.isHeaderGroup) {\r
86504 innerIndex = item.innerIndexOf(column);\r
86505 if (innerIndex !== -1) {\r
86506 index += innerIndex;\r
86507 return index;\r
86508 } else {\r
86509 index += item.getInnerItems().length;\r
86510 }\r
86511 } else {\r
86512 index += 1;\r
86513 }\r
86514 }\r
86515 },\r
86516 onColumnAdd: function(parent, column) {\r
86517 var me = this,\r
86518 columns = me.columns,\r
86519 columnIndex = me.getAbsoluteColumnIndex(column),\r
86520 groupColumns, ln, i;\r
86521 if (column.isHeaderGroup) {\r
86522 groupColumns = column.getItems().items;\r
86523 for (i = 0 , ln = groupColumns.length; i < ln; i++) {\r
86524 columns.splice(columnIndex + i, 0, groupColumns[i]);\r
86525 me.fireEvent('columnadd', me, groupColumns[i], column);\r
86526 }\r
86527 } else {\r
86528 columns.splice(columnIndex, 0, column);\r
86529 me.fireEvent('columnadd', me, column, null);\r
86530 }\r
86531 },\r
86532 onColumnMove: function(parent, column) {\r
86533 var me = this,\r
86534 columns = me.columns,\r
86535 columnIndex = me.getAbsoluteColumnIndex(column),\r
86536 groupColumns, ln, i, groupColumn, after, oldIndex, fromIdx, toIdx;\r
86537 if (column.isHeaderGroup) {\r
86538 groupColumns = column.getItems().items;\r
86539 for (i = 0 , ln = groupColumns.length; i < ln; i++) {\r
86540 groupColumn = groupColumns[i];\r
86541 if (i === 0) {\r
86542 oldIndex = columns.indexOf(groupColumn);\r
86543 after = oldIndex - columnIndex < 0;\r
86544 }\r
86545
86546 if (after) {\r
86547
86548
86549
86550
86551
86552
86553 toIdx = columnIndex + ln - 1;\r
86554 fromIdx = oldIndex;\r
86555 } else {\r
86556
86557
86558
86559
86560
86561
86562 fromIdx = oldIndex + i;\r
86563 toIdx = columnIndex + i;\r
86564 }\r
86565 Ext.Array.move(columns, fromIdx, toIdx);\r
86566 me.fireEvent('columnmove', me, groupColumn, column, fromIdx, toIdx);\r
86567 }\r
86568 } else {\r
86569 fromIdx = columns.indexOf(column);\r
86570 toIdx = columnIndex;\r
86571 Ext.Array.move(columns, fromIdx, toIdx);\r
86572 me.fireEvent('columnmove', me, column, null, fromIdx, toIdx);\r
86573 }\r
86574 },\r
86575 onColumnRemove: function(parent, column) {\r
86576 if (column.isHeaderGroup) {\r
86577 var columns = column.getItems().items,\r
86578 ln = columns.length,\r
86579 i;\r
86580 for (i = 0; i < ln; i++) {\r
86581 Ext.Array.remove(this.columns, columns[i]);\r
86582 this.fireEvent('columnremove', this, columns[i]);\r
86583 }\r
86584 } else {\r
86585 Ext.Array.remove(this.columns, column);\r
86586 this.fireEvent('columnremove', this, column);\r
86587 }\r
86588 },\r
86589 onHeaderTap: function(column) {\r
86590 if (this.getSortable() && !column.getIgnore() && column.getSortable()) {\r
86591 var sortDirection = column.getSortDirection() || 'DESC',\r
86592 newDirection = (sortDirection === 'DESC') ? 'ASC' : 'DESC';\r
86593 column.setSortDirection(newDirection);\r
86594 }\r
86595 this.fireEvent('columntap', this, column);\r
86596 },\r
86597 onColumnShow: function(column) {\r
86598 this.fireEvent('columnshow', this, column);\r
86599 },\r
86600 onColumnHide: function(column) {\r
86601 this.fireEvent('columnhide', this, column);\r
86602 },\r
86603 onGroupShow: function(group) {\r
86604 var columns = group.getInnerItems(),\r
86605 ln = columns.length,\r
86606 i, column;\r
86607 for (i = 0; i < ln; i++) {\r
86608 column = columns[i];\r
86609 if (!column.isHidden()) {\r
86610 this.fireEvent('columnshow', this, column);\r
86611 }\r
86612 }\r
86613 },\r
86614 onGroupHide: function(group) {\r
86615 var columns = group.getInnerItems(),\r
86616 ln = columns.length,\r
86617 i, column;\r
86618 for (i = 0; i < ln; i++) {\r
86619 column = columns[i];\r
86620 this.fireEvent('columnhide', this, column);\r
86621 }\r
86622 },\r
86623 onColumnResize: function(column, width, oldWidth) {\r
86624 this.fireEvent('columnresize', this, column, width, oldWidth);\r
86625 },\r
86626 onColumnSort: function(column, direction, newDirection) {\r
86627 if (direction !== null) {\r
86628 this.fireEvent('columnsort', this, column, direction, newDirection);\r
86629 }\r
86630 },\r
86631 scrollTo: function(x) {\r
86632 this.getScrollable().scrollTo(x);\r
86633 },\r
86634 setTotalWidth: function(totalWidth) {\r
86635 var scrollable = this.getScrollable(),\r
86636 innerElement;\r
86637 if (scrollable && scrollable.isTouchScroller) {\r
86638 innerElement = scrollable.getInnerElement();\r
86639 if (innerElement) {\r
86640 innerElement.setWidth(totalWidth);\r
86641 scrollable.setSize({\r
86642 x: totalWidth,\r
86643 y: scrollable.getSize().y\r
86644 });\r
86645 }\r
86646 }\r
86647 },\r
86648 destroy: function() {\r
86649 var me = this,\r
86650 task = me.spacerTask;\r
86651 if (task) {\r
86652 task.cancel();\r
86653 me.spacerTask = null;\r
86654 }\r
86655 me.setGrid(null);\r
86656 me.callParent();\r
86657 },\r
86658 privates: {\r
86659 updateSpacer: function() {\r
86660 var me = this,\r
86661 task = me.spacerTask;\r
86662 if (!task) {\r
86663 me.spacerTask = task = new Ext.util.DelayedTask(me.doUpdateSpacer, me);\r
86664 }\r
86665 task.delay(1);\r
86666 },\r
86667 doUpdateSpacer: function() {\r
86668 var scrollable = this.getGrid().getScrollable();\r
86669 this.element.setStyle('padding-right', scrollable.getScrollbarSize().width + 'px');\r
86670 }\r
86671 }\r
86672});\r
86673\r
86674\r
86675Ext.define('Ext.grid.HeaderGroup', {\r
86676 extend: Ext.Container,\r
86677 alias: 'widget.gridheadergroup',\r
86678 isHeaderGroup: true,\r
86679 config: {\r
86680 \r
86681 text: '&nbsp;',\r
86682 \r
86683 columns: null,\r
86684
86685
86686 items: undefined,\r
86687 defaultType: 'column',\r
86688 baseCls: Ext.baseCSSPrefix + 'grid-headergroup',\r
86689 \r
86690 hidden: true,\r
86691 layout: {\r
86692 type: 'hbox',\r
86693 align: 'stretch'\r
86694 }\r
86695 },\r
86696 getElementConfig: function() {\r
86697 return {\r
86698 reference: 'element',\r
86699 classList: [\r
86700 'x-container',\r
86701 'x-unsized'\r
86702 ],\r
86703 children: [\r
86704 {\r
86705 reference: 'textElement',\r
86706 className: 'x-grid-headergroup-text'\r
86707 },\r
86708 {\r
86709 reference: 'innerElement',\r
86710 className: 'x-inner'\r
86711 }\r
86712 ]\r
86713 };\r
86714 },\r
86715 applyItems: function(items, collection) {\r
86716 if (!items) {\r
86717 items = this.getColumns();\r
86718 }\r
86719 this.callParent([\r
86720 items,\r
86721 collection\r
86722 ]);\r
86723 },\r
86724 updateText: function(text) {\r
86725 this.textElement.setHtml(text);\r
86726 },\r
86727 initialize: function() {\r
86728 var me = this;\r
86729 me.on({\r
86730 add: 'doVisibilityCheck',\r
86731 remove: 'doVisibilityCheck',\r
86732 show: 'onColumnShow',\r
86733 hide: 'onColumnHide',\r
86734 delegate: '> column',\r
86735 scope: 'this'\r
86736 });\r
86737 me.on({\r
86738 show: 'onShow',\r
86739 scope: 'this'\r
86740 });\r
86741 me.callParent();\r
86742 me.doVisibilityCheck();\r
86743 },\r
86744 onColumnShow: function(column) {\r
86745 if (this.getVisibleCount() === this.getInnerItems().length) {\r
86746 this.show();\r
86747 }\r
86748 },\r
86749 onColumnHide: function(column) {\r
86750 if (this.getVisibleCount() === 0) {\r
86751 this.hide();\r
86752 }\r
86753 },\r
86754 onShow: function() {\r
86755 var toShow;\r
86756
86757 if (!this.getVisibleCount()) {\r
86758 toShow = this.getComponent(0);\r
86759 if (toShow) {\r
86760 toShow.show();\r
86761 }\r
86762 }\r
86763 },\r
86764 doVisibilityCheck: function() {\r
86765 var me = this,\r
86766 columns = me.getInnerItems(),\r
86767 ln = columns.length,\r
86768 i, column;\r
86769 for (i = 0; i < ln; i++) {\r
86770 column = columns[i];\r
86771 if (!column.isHidden()) {\r
86772 if (me.isHidden()) {\r
86773 if (me.initialized) {\r
86774 me.show();\r
86775 } else {\r
86776 me.setHidden(false);\r
86777 }\r
86778 }\r
86779 return;\r
86780 }\r
86781 }\r
86782 me.hide();\r
86783 },\r
86784 destroy: function() {\r
86785 this.setColumns(null);\r
86786 this.callParent();\r
86787 },\r
86788 privates: {\r
86789 getVisibleCount: function() {\r
86790 var columns = this.getInnerItems(),\r
86791 len = columns.length,\r
86792 count = 0,\r
86793 i;\r
86794 for (i = 0; i < len; ++i) {\r
86795 count += columns[i].isHidden() ? 0 : 1;\r
86796 }\r
86797 return count;\r
86798 }\r
86799 }\r
86800});\r
86801\r
86802\r
86803Ext.define('Ext.grid.Grid', {\r
86804 extend: Ext.dataview.List,\r
86805 xtype: 'grid',\r
86806 config: {\r
86807 defaultType: 'gridrow',\r
86808 \r
86809 infinite: true,\r
86810 \r
86811 columns: null,\r
86812 \r
86813 baseCls: Ext.baseCSSPrefix + 'grid',\r
86814 \r
86815 variableHeights: false,\r
86816 headerContainer: {\r
86817 xtype: 'headercontainer'\r
86818 },\r
86819 \r
86820 hideHeaders: false,\r
86821 \r
86822 striped: true,\r
86823 itemCls: Ext.baseCSSPrefix + 'list-item',\r
86824 scrollToTopOnRefresh: false,\r
86825 titleBar: {\r
86826 xtype: 'titlebar',\r
86827 docked: 'top'\r
86828 },\r
86829 \r
86830 title: ''\r
86831 },\r
86832 \r
86833 \r
86834 \r
86835 \r
86836 \r
86837 \r
86838 \r
86839 initialize: function() {\r
86840 var me = this,\r
86841 titleBar = me.getTitleBar(),\r
86842 headerContainer = me.getHeaderContainer(),\r
86843 scrollable = me.getScrollable(),\r
86844 container;\r
86845 me.callParent();\r
86846 if (scrollable) {\r
86847 headerContainer.getScrollable().addPartner(scrollable, 'x');\r
86848 }\r
86849 container = me.container;\r
86850 if (titleBar) {\r
86851 container.add(me.getTitleBar());\r
86852 }\r
86853 container.add(headerContainer);\r
86854 me.scrollElement.addCls(Ext.baseCSSPrefix + 'grid-scrollelement');\r
86855 },\r
86856 applyTitleBar: function(titleBar) {\r
86857 if (titleBar && !titleBar.isComponent) {\r
86858 titleBar = Ext.factory(titleBar, Ext.TitleBar);\r
86859 }\r
86860 return titleBar;\r
86861 },\r
86862 updateTitle: function(title) {\r
86863 var titleBar = this.getTitleBar();\r
86864 if (titleBar) {\r
86865 if (title) {\r
86866 titleBar.setTitle(title);\r
86867 } else {\r
86868 titleBar.hide();\r
86869 }\r
86870 }\r
86871 },\r
86872 applyHeaderContainer: function(headerContainer) {\r
86873 if (headerContainer && !headerContainer.isComponent) {\r
86874 headerContainer = Ext.factory(headerContainer, Ext.grid.HeaderContainer);\r
86875 }\r
86876 return headerContainer;\r
86877 },\r
86878 updateHeaderContainer: function(headerContainer, oldHeaderContainer) {\r
86879 var me = this;\r
86880 if (oldHeaderContainer) {\r
86881 oldHeaderContainer.un({\r
86882 columnsort: 'onColumnSort',\r
86883 columnresize: 'onColumnResize',\r
86884 columnshow: 'onColumnShow',\r
86885 columnhide: 'onColumnHide',\r
86886 columnadd: 'onColumnAdd',\r
86887 columnmove: 'onColumnMove',\r
86888 columnremove: 'onColumnRemove',\r
86889 scope: me\r
86890 });\r
86891 }\r
86892 if (headerContainer) {\r
86893 headerContainer.on({\r
86894 columnsort: 'onColumnSort',\r
86895 columnresize: 'onColumnResize',\r
86896 columnshow: 'onColumnShow',\r
86897 columnhide: 'onColumnHide',\r
86898 columnadd: 'onColumnAdd',\r
86899 columnmove: 'onColumnMove',\r
86900 columnremove: 'onColumnRemove',\r
86901 scope: me\r
86902 });\r
86903 headerContainer.setGrid(me);\r
86904 }\r
86905 },\r
86906 updateHideHeaders: function(hideHeaders) {\r
86907 var ct = this.getHeaderContainer(),\r
86908 oldCtHeight = this.oldCtHeight || null;\r
86909
86910 if (!hideHeaders && ct.getHeight() !== 0) {\r
86911 return;\r
86912 }\r
86913
86914
86915 if (hideHeaders) {\r
86916 this.oldCtHeight = ct.getHeight();\r
86917 }\r
86918 ct.setHeight(hideHeaders ? 0 : oldCtHeight);\r
86919 },\r
86920 addColumn: function(column) {\r
86921 return this.getHeaderContainer().add(column);\r
86922 },\r
86923 removeColumn: function(column) {\r
86924 return this.getHeaderContainer().remove(column);\r
86925 },\r
86926 insertColumn: function(index, column) {\r
86927 return this.getHeaderContainer().insert(index, column);\r
86928 },\r
86929 onColumnAdd: function(container, column) {\r
86930 var me = this,\r
86931 items, ln, columnIndex, i, row;\r
86932 if (me.initialized && !me.destroying) {\r
86933 items = this.listItems;\r
86934 ln = items.length;\r
86935 columnIndex = container.getColumns().indexOf(column);\r
86936 for (i = 0; i < ln; i++) {\r
86937 row = items[i];\r
86938 row.insertColumn(columnIndex, column);\r
86939 }\r
86940 me.updateTotalColumnWidth();\r
86941 me.fireEvent('columnadd', me, column, columnIndex);\r
86942 }\r
86943 },\r
86944 onColumnMove: function(container, column, group, fromIdx, toIdx) {\r
86945 var me = this,\r
86946 items, ln, i, row;\r
86947 if (me.initialized && !me.destroying) {\r
86948 items = me.listItems;\r
86949 ln = items.length;\r
86950 for (i = 0; i < ln; i++) {\r
86951 row = items[i];\r
86952 row.moveColumn(column, fromIdx, toIdx);\r
86953 }\r
86954 me.fireEvent('columnmove', me, column, fromIdx, toIdx);\r
86955 }\r
86956 },\r
86957 onColumnRemove: function(container, column) {\r
86958 var me = this,\r
86959 items, ln, i, row;\r
86960 if (me.initialized && !me.destroying) {\r
86961 items = me.listItems;\r
86962 ln = items.length;\r
86963 for (i = 0; i < ln; i++) {\r
86964 row = items[i];\r
86965 row.removeColumn(column);\r
86966 }\r
86967 me.updateTotalColumnWidth();\r
86968 me.fireEvent('columnremove', me, column);\r
86969 }\r
86970 },\r
86971 updateColumns: function(columns) {\r
86972 if (columns && columns.length) {\r
86973 var ln = columns.length,\r
86974 i;\r
86975 for (i = 0; i < ln; i++) {\r
86976 this.addColumn(columns[i]);\r
86977 }\r
86978 this.updateTotalColumnWidth();\r
86979 }\r
86980 },\r
86981 getColumns: function() {\r
86982 return this.getHeaderContainer().getColumns();\r
86983 },\r
86984 onColumnResize: function(container, column, width, oldWidth) {\r
86985 var me = this,\r
86986 items = me.listItems,\r
86987 ln = items.length,\r
86988 i, row;\r
86989 if (!me.destroying) {\r
86990 for (i = 0; i < ln; i++) {\r
86991 row = items[i];\r
86992 row.setColumnWidth(column, width);\r
86993 }\r
86994 if (me.initialized) {\r
86995 me.updateTotalColumnWidth();\r
86996
86997 if (oldWidth !== null && !column.getHidden()) {\r
86998 me.fireEvent('columnresize', me, column, width);\r
86999 }\r
87000 }\r
87001 }\r
87002 },\r
87003 onColumnShow: function(container, column) {\r
87004 var me = this,\r
87005 items, ln, i, row, w;\r
87006 if (me.initialized && !me.destroying) {\r
87007 items = me.listItems;\r
87008 ln = items.length;\r
87009 me.updateTotalColumnWidth();\r
87010 if (!column.getFlex()) {\r
87011 w = column.getWidth();\r
87012 }\r
87013 for (i = 0; i < ln; i++) {\r
87014 row = items[i];\r
87015 row.showColumn(column);\r
87016
87017
87018 if (w !== undefined) {\r
87019 row.setColumnWidth(column, w);\r
87020 }\r
87021 }\r
87022 me.fireEvent('columnshow', me, column);\r
87023 }\r
87024 },\r
87025 onColumnHide: function(container, column) {\r
87026 var me = this,\r
87027 items, ln, i, row;\r
87028 if (me.initialized && !me.destroying) {\r
87029 items = me.listItems;\r
87030 ln = items.length;\r
87031 me.updateTotalColumnWidth();\r
87032 for (i = 0; i < ln; i++) {\r
87033 row = items[i];\r
87034 row.hideColumn(column);\r
87035 }\r
87036 me.fireEvent('columnhide', me, column);\r
87037 }\r
87038 },\r
87039 onColumnSort: function(container, column, direction) {\r
87040 var me = this,\r
87041 sorted = me.sortedColumn;\r
87042 if (sorted && sorted !== column) {\r
87043 sorted.setSortDirection(null);\r
87044 }\r
87045 me.sortedColumn = column;\r
87046 me.getStore().sort(column.getDataIndex(), direction);\r
87047 me.fireEvent('columnsort', me, column, direction);\r
87048 },\r
87049 refreshScroller: function(skipOnRefresh) {\r
87050 this.callParent([\r
87051 skipOnRefresh\r
87052 ]);\r
87053 this.getHeaderContainer().updateSpacer();\r
87054 },\r
87055 getTotalColumnWidth: function() {\r
87056 var me = this,\r
87057 columns = me.getColumns(),\r
87058 ln = columns.length,\r
87059 totalWidth = 0,\r
87060 i, column, parent;\r
87061 for (i = 0; i < ln; i++) {\r
87062 column = columns[i];\r
87063 parent = column.getParent();\r
87064 if (!column.isHidden() && (!parent.isHeaderGroup || !parent.isHidden())) {\r
87065 totalWidth += column.getComputedWidth();\r
87066 }\r
87067 }\r
87068 return totalWidth;\r
87069 },\r
87070 updateTotalColumnWidth: function() {\r
87071 var me = this,\r
87072 scroller = me.getScrollable(),\r
87073 totalWidth = this.getTotalColumnWidth(),\r
87074 header = me.getHeaderContainer();\r
87075 me.scrollElement.setWidth(totalWidth);\r
87076 header.setTotalWidth(totalWidth);\r
87077 header.updateSpacer();\r
87078 scroller.setSize({\r
87079 x: totalWidth,\r
87080 y: scroller.getSize().y\r
87081 });\r
87082 },\r
87083 createItem: function(config) {\r
87084 config.grid = this;\r
87085 return this.callParent([\r
87086 config\r
87087 ]);\r
87088 },\r
87089 destroy: function() {\r
87090 this.destroying = true;\r
87091 this.callParent();\r
87092 this.destroying = false;\r
87093 }\r
87094});\r
87095\r
87096\r
87097Ext.define('Ext.grid.cell.Boolean', {\r
87098 extend: Ext.grid.cell.Text,\r
87099 xtype: 'booleancell',\r
87100 config: {\r
87101 \r
87102 falseText: 'False',\r
87103 \r
87104 trueText: 'True',\r
87105 \r
87106 undefinedText: ''\r
87107 },\r
87108 updateColumn: function(column, oldColumn) {\r
87109 this.callParent([\r
87110 column,\r
87111 oldColumn\r
87112 ]);\r
87113 if (column) {\r
87114 var text = column.getFalseText();\r
87115 if (text !== null) {\r
87116 this.setFalseText(text);\r
87117 }\r
87118 text = column.getTrueText();\r
87119 if (text !== null) {\r
87120 this.setTrueText(text);\r
87121 }\r
87122 text = column.getUndefinedText();\r
87123 if (text !== null) {\r
87124 this.setUndefinedText(text);\r
87125 }\r
87126 }\r
87127 },\r
87128 updateFalseText: function() {\r
87129 if (!this.isConfiguring) {\r
87130 this.writeValue();\r
87131 }\r
87132 },\r
87133 updateTrueText: function() {\r
87134 if (!this.isConfiguring) {\r
87135 this.writeValue();\r
87136 }\r
87137 },\r
87138 updateUndefinedText: function() {\r
87139 if (!this.isConfiguring) {\r
87140 this.writeValue();\r
87141 }\r
87142 },\r
87143 writeValue: function() {\r
87144 var me = this,\r
87145 value = me.getValue();\r
87146 if (value === undefined) {\r
87147 value = me.getUndefinedText();\r
87148 } else if (!value || value === 'false') {\r
87149 value = me.getFalseText();\r
87150 } else {\r
87151 value = me.getTrueText();\r
87152 }\r
87153 me.setRawValue(value);\r
87154 }\r
87155});\r
87156\r
87157\r
87158Ext.define('Ext.grid.cell.Number', {\r
87159 extend: Ext.grid.cell.Text,\r
87160 xtype: 'numbercell',\r
87161 config: {\r
87162 \r
87163 format: '0,000.00'\r
87164 },\r
87165 updateColumn: function(column, oldColumn) {\r
87166 this.callParent([\r
87167 column,\r
87168 oldColumn\r
87169 ]);\r
87170 if (column) {\r
87171 var format = column.getFormat();\r
87172 if (format !== null) {\r
87173 this.setFormat(format);\r
87174 }\r
87175 }\r
87176 },\r
87177 updateFormat: function(format) {\r
87178 if (!this.isConfiguring) {\r
87179 this.writeValue();\r
87180 }\r
87181 },\r
87182 writeValue: function() {\r
87183 var value = this.getValue(),\r
87184 hasValue = value || value === 0;\r
87185 this.setRawValue(hasValue ? Ext.util.Format.number(value, this.getFormat()) : null);\r
87186 }\r
87187});\r
87188\r
87189\r
87190Ext.define('Ext.grid.cell.Widget', {\r
87191 extend: Ext.grid.cell.Base,\r
87192 xtype: 'widgetcell',\r
87193 config: {\r
87194 \r
87195 widget: null\r
87196 },\r
87197 applyWidget: function(widget) {\r
87198 if (widget) {\r
87199 var parent = this.getParent();\r
87200 if (parent && !parent.isSpecialRow) {\r
87201 widget = Ext.apply({\r
87202 parent: this\r
87203 }, widget);\r
87204 widget = Ext.widget(widget);\r
87205 } else {\r
87206 widget = undefined;\r
87207 }\r
87208 }\r
87209 return widget;\r
87210 },\r
87211 updateWidget: function(widget, oldWidget) {\r
87212 if (oldWidget) {\r
87213 oldWidget.destroy();\r
87214 }\r
87215 if (widget) {\r
87216 this.innerElement.appendChild(widget.element);\r
87217 }\r
87218 },\r
87219 updateValue: function(value) {\r
87220 var widget = this.getWidget(),\r
87221 defaultBindProperty;\r
87222 if (widget) {\r
87223 defaultBindProperty = widget.defaultBindProperty;\r
87224 if (defaultBindProperty) {\r
87225 widget.setConfig(defaultBindProperty, value);\r
87226 }\r
87227 }\r
87228 },\r
87229 destroy: function() {\r
87230 this.setWidget(null);\r
87231 this.callParent();\r
87232 }\r
87233});\r
87234\r
87235\r
87236Ext.define('Ext.grid.column.Boolean', {\r
87237 extend: Ext.grid.column.Column,\r
87238 xtype: 'booleancolumn',\r
87239 config: {\r
87240 \r
87241 trueText: null,\r
87242 \r
87243 falseText: null,\r
87244 \r
87245 undefinedText: null,\r
87246 defaultEditor: {\r
87247 xtype: 'checkboxfield'\r
87248 },\r
87249 cell: {\r
87250 xtype: 'booleancell'\r
87251 }\r
87252 }\r
87253});\r
87254\r
87255\r
87256Ext.define('Ext.grid.column.Number', {\r
87257 extend: Ext.grid.column.Column,\r
87258 xtype: 'numbercolumn',\r
87259 config: {\r
87260 \r
87261 format: null,\r
87262 defaultEditor: {\r
87263 xtype: 'numberfield'\r
87264 },\r
87265 cell: {\r
87266 xtype: 'numbercell'\r
87267 }\r
87268 }\r
87269});\r
87270\r
87271\r
87272Ext.define('Ext.grid.plugin.ColumnResizing', {\r
87273 extend: Ext.Component,\r
87274 alias: 'plugin.gridcolumnresizing',\r
87275 config: {\r
87276 grid: null\r
87277 },\r
87278 init: function(grid) {\r
87279 this.setGrid(grid);\r
87280 },\r
87281 updateGrid: function(grid, oldGrid) {\r
87282 if (oldGrid) {\r
87283 oldGrid.getHeaderContainer().renderElement.un({\r
87284 pinchstart: 'onContainerPinchStart',\r
87285 pinch: 'onContainerPinch',\r
87286 pinchend: 'onContainerPinchEnd',\r
87287 scope: this\r
87288 });\r
87289 }\r
87290 if (grid) {\r
87291 grid.getHeaderContainer().renderElement.on({\r
87292 pinchstart: 'onContainerPinchStart',\r
87293 pinch: 'onContainerPinch',\r
87294 pinchend: 'onContainerPinchEnd',\r
87295 scope: this\r
87296 });\r
87297 }\r
87298 },\r
87299 onContainerPinchStart: function(e) {\r
87300 var target = e.getTarget('.' + Ext.baseCSSPrefix + 'grid-column'),\r
87301 column;\r
87302 if (target) {\r
87303 column = Ext.getCmp(target.id);\r
87304 if (column && column.getResizable()) {\r
87305 this.startColumnWidth = column.getWidth();\r
87306 this.resizeColumn = column;\r
87307 this.startDistance = e.distance;\r
87308 column.renderElement.addCls(Ext.baseCSSPrefix + 'grid-column-resizing');\r
87309 } else {\r
87310 e.preventDefault();\r
87311 }\r
87312 }\r
87313 },\r
87314 onContainerPinch: function(e) {\r
87315 var column = this.resizeColumn,\r
87316 resizeAmount = e.distance - this.startDistance;\r
87317 if (column) {\r
87318 this.currentColumnWidth = Math.ceil(this.startColumnWidth + resizeAmount);\r
87319 column.renderElement.setWidth(this.currentColumnWidth);\r
87320 }\r
87321 },\r
87322 onContainerPinchEnd: function() {\r
87323 var column = this.resizeColumn;\r
87324 if (column) {\r
87325 column.setWidth(this.currentColumnWidth + 1);\r
87326 column.renderElement.removeCls(Ext.baseCSSPrefix + 'grid-column-resizing');\r
87327 delete this.resizeColumn;\r
87328 }\r
87329 }\r
87330});\r
87331\r
87332\r
87333Ext.define('Ext.grid.plugin.Editable', {\r
87334 extend: Ext.Component,\r
87335 alias: 'plugin.grideditable',\r
87336 config: {\r
87337 \r
87338 grid: null,\r
87339 \r
87340 triggerEvent: 'doubletap',\r
87341 \r
87342 formConfig: null,\r
87343 \r
87344 defaultFormConfig: {\r
87345 xtype: 'formpanel',\r
87346 modal: true,\r
87347 scrollable: true,\r
87348 items: {\r
87349 xtype: 'fieldset'\r
87350 }\r
87351 },\r
87352 \r
87353 toolbarConfig: {\r
87354 xtype: 'titlebar',\r
87355 docked: 'top',\r
87356 items: [\r
87357 {\r
87358 xtype: 'button',\r
87359 ui: 'decline',\r
87360 text: 'Cancel',\r
87361 align: 'left',\r
87362 action: 'cancel'\r
87363 },\r
87364 {\r
87365 xtype: 'button',\r
87366 ui: 'confirm',\r
87367 text: 'Submit',\r
87368 align: 'right',\r
87369 action: 'submit'\r
87370 }\r
87371 ]\r
87372 },\r
87373 \r
87374 enableDeleteButton: true\r
87375 },\r
87376 init: function(grid) {\r
87377 this.setGrid(grid);\r
87378 },\r
87379 updateGrid: function(grid, oldGrid) {\r
87380 var triggerEvent = this.getTriggerEvent();\r
87381 if (oldGrid) {\r
87382 oldGrid.renderElement.un(triggerEvent, 'onTrigger', this);\r
87383 }\r
87384 if (grid) {\r
87385 grid.renderElement.on(triggerEvent, 'onTrigger', this);\r
87386 }\r
87387 },\r
87388 onCancelTap: function() {\r
87389 this.sheet.hide();\r
87390 },\r
87391 onSubmitTap: function() {\r
87392 this.form.getRecord().set(this.form.getValues());\r
87393 this.sheet.hide();\r
87394 },\r
87395 onSheetHide: function() {\r
87396 this.sheet.destroy();\r
87397 this.form = null;\r
87398 this.sheet = null;\r
87399 },\r
87400 getRecordByTriggerEvent: function(e) {\r
87401 var rowEl = e.getTarget('.' + Ext.baseCSSPrefix + 'grid-row'),\r
87402 row;\r
87403 if (rowEl) {\r
87404 row = Ext.getCmp(rowEl.id);\r
87405 if (row) {\r
87406 return row.getRecord();\r
87407 }\r
87408 }\r
87409 return null;\r
87410 },\r
87411 getEditorFields: function(columns) {\r
87412 var fields = [],\r
87413 ln = columns.length,\r
87414 i, column, editor;\r
87415 for (i = 0; i < ln; i++) {\r
87416 column = columns[i];\r
87417 if (column.getEditable()) {\r
87418 editor = Ext.apply({}, column.getEditor() || column.getDefaultEditor());\r
87419 editor.label = column.getText();\r
87420 fields.push(editor);\r
87421 }\r
87422 }\r
87423 return fields;\r
87424 },\r
87425 onTrigger: function(e) {\r
87426 var me = this,\r
87427 grid = me.getGrid(),\r
87428 formConfig = me.getFormConfig(),\r
87429 toolbarConfig = me.getToolbarConfig(),\r
87430 record = me.getRecordByTriggerEvent(e),\r
87431 fields, form, sheet, toolbar;\r
87432 if (record) {\r
87433 if (formConfig) {\r
87434 this.form = form = Ext.factory(formConfig, Ext.form.Panel);\r
87435 } else {\r
87436 this.form = form = Ext.factory(me.getDefaultFormConfig());\r
87437 fields = me.getEditorFields(grid.getColumns());\r
87438 form.down('fieldset').setItems(fields);\r
87439 }\r
87440 form.setRecord(record);\r
87441 toolbar = Ext.factory(toolbarConfig, Ext.form.TitleBar);\r
87442 toolbar.down('button[action=cancel]').on('tap', 'onCancelTap', this);\r
87443 toolbar.down('button[action=submit]').on('tap', 'onSubmitTap', this);\r
87444 this.sheet = sheet = grid.add({\r
87445 xtype: 'sheet',\r
87446 items: [\r
87447 toolbar,\r
87448 form\r
87449 ],\r
87450 hideOnMaskTap: true,\r
87451 enter: 'right',\r
87452 exit: 'right',\r
87453 right: 0,\r
87454 width: 320,\r
87455 layout: 'fit',\r
87456 stretchY: true,\r
87457 hidden: true\r
87458 });\r
87459 if (me.getEnableDeleteButton()) {\r
87460 form.add({\r
87461 xtype: 'button',\r
87462 text: 'Delete',\r
87463 ui: 'decline',\r
87464 margin: 10,\r
87465 handler: function() {\r
87466 grid.getStore().remove(record);\r
87467 sheet.hide();\r
87468 }\r
87469 });\r
87470 }\r
87471 sheet.on('hide', 'onSheetHide', this);\r
87472 sheet.show();\r
87473 }\r
87474 }\r
87475});\r
87476\r
87477\r
87478Ext.define('Ext.grid.plugin.MultiSelection', {\r
87479 extend: Ext.Component,\r
87480 alias: 'plugin.gridmultiselection',\r
87481 config: {\r
87482 \r
87483 grid: null,\r
87484 \r
87485 selectionColumn: {\r
87486 width: 60,\r
87487 xtype: 'column',\r
87488 cls: Ext.baseCSSPrefix + 'grid-multiselection-column',\r
87489 cell: {\r
87490 cls: Ext.baseCSSPrefix + 'grid-multiselection-cell'\r
87491 },\r
87492 ignore: true,\r
87493 hidden: true\r
87494 },\r
87495 \r
87496 useTriggerButton: true,\r
87497 \r
87498 triggerText: 'Select',\r
87499 \r
87500 cancelText: 'Cancel',\r
87501 \r
87502 deleteText: 'Delete'\r
87503 },\r
87504 init: function(grid) {\r
87505 this.setGrid(grid);\r
87506 var titleBar = grid.getTitleBar();\r
87507 if (this.getUseTriggerButton() && titleBar) {\r
87508 this.triggerButton = titleBar.add({\r
87509 align: 'right',\r
87510 xtype: 'button',\r
87511 text: this.getTriggerText()\r
87512 });\r
87513 this.triggerButton.on({\r
87514 tap: 'onTriggerButtonTap',\r
87515 scope: this\r
87516 });\r
87517 }\r
87518 grid.getHeaderContainer().on({\r
87519 columntap: 'onColumnTap',\r
87520 scope: this\r
87521 });\r
87522 },\r
87523 onTriggerButtonTap: function() {\r
87524 if (this.getSelectionColumn().isHidden()) {\r
87525 this.enterSelectionMode();\r
87526 } else {\r
87527 this.deleteSelectedRecords();\r
87528 this.getGrid().deselectAll();\r
87529 }\r
87530 },\r
87531 onColumnTap: function(container, column) {\r
87532 var grid = this.getGrid();\r
87533 if (column === this.getSelectionColumn()) {\r
87534 if (grid.getSelectionCount() === grid.getStore().getCount()) {\r
87535 grid.deselectAll();\r
87536 } else {\r
87537 grid.selectAll();\r
87538 }\r
87539 }\r
87540 },\r
87541 enterSelectionMode: function() {\r
87542 this.triggerButton.setText(this.getDeleteText());\r
87543 this.triggerButton.setUi('decline');\r
87544 this.cancelButton = this.getGrid().getTitleBar().add({\r
87545 align: 'right',\r
87546 xtype: 'button',\r
87547 ui: 'action',\r
87548 text: this.getCancelText(),\r
87549 scope: this\r
87550 });\r
87551 this.cancelButton.on({\r
87552 tap: 'exitSelectionMode',\r
87553 scope: this\r
87554 });\r
87555 this.getSelectionColumn().show();\r
87556 this.getGrid().setMode('MULTI');\r
87557 },\r
87558 exitSelectionMode: function() {\r
87559 this.cancelButton.destroy();\r
87560 this.triggerButton.setText(this.getTriggerText());\r
87561 this.triggerButton.setUi(null);\r
87562 this.getSelectionColumn().hide();\r
87563 this.getGrid().setMode('SINGLE');\r
87564 this.getGrid().deselectAll();\r
87565 },\r
87566 deleteSelectedRecords: function() {\r
87567 this.getGrid().getStore().remove(this.getGrid().getSelection());\r
87568 },\r
87569 applySelectionColumn: function(column) {\r
87570 if (column && !column.isComponent) {\r
87571 column = Ext.factory(column, Ext.grid.Column);\r
87572 }\r
87573 return column;\r
87574 },\r
87575 updateSelectionColumn: function(column, oldColumn) {\r
87576 var grid = this.getGrid();\r
87577 if (grid) {\r
87578 if (oldColumn) {\r
87579 grid.removeColumn(oldColumn);\r
87580 }\r
87581 if (column) {\r
87582 grid.insertColumn(0, column);\r
87583 }\r
87584 }\r
87585 },\r
87586 onGridSelectionChange: function() {\r
87587 var grid = this.getGrid(),\r
87588 column = this.getSelectionColumn();\r
87589 if (grid.getSelectionCount() === grid.getStore().getCount()) {\r
87590 column.addCls(Ext.baseCSSPrefix + 'grid-multiselection-allselected');\r
87591 } else {\r
87592 column.removeCls(Ext.baseCSSPrefix + 'grid-multiselection-allselected');\r
87593 }\r
87594 },\r
87595 updateGrid: function(grid, oldGrid) {\r
87596 var delegateCls = '.' + Ext.baseCSSPrefix + 'grid-multiselectioncell';\r
87597 if (oldGrid) {\r
87598 oldGrid.removeColumn(this.getSelectionColumn());\r
87599 oldGrid.un({\r
87600 selectionchange: 'onGridSelectionChange',\r
87601 scope: this\r
87602 });\r
87603 }\r
87604 if (grid) {\r
87605 grid.insertColumn(0, this.getSelectionColumn());\r
87606 grid.on({\r
87607 selectionchange: 'onGridSelectionChange',\r
87608 scope: this\r
87609 });\r
87610 }\r
87611 }\r
87612});\r
87613\r
87614\r
87615Ext.define('Ext.grid.plugin.PagingToolbar', {\r
87616 extend: Ext.Component,\r
87617 alias: 'plugin.gridpagingtoolbar',\r
87618 mixins: [\r
87619 Ext.mixin.Hookable\r
87620 ],\r
87621 config: {\r
87622 grid: null,\r
87623 currentPage: 1,\r
87624 totalPages: 0,\r
87625 pageSize: 0,\r
87626 totalCount: 0,\r
87627 toolbar: {\r
87628 xtype: 'toolbar',\r
87629 docked: 'bottom',\r
87630 ui: 'gray',\r
87631 cls: Ext.baseCSSPrefix + 'grid-pagingtoolbar',\r
87632 items: [\r
87633 {\r
87634 xtype: 'button',\r
87635 ui: 'plain',\r
87636 iconCls: Ext.baseCSSPrefix + 'grid-pagingtoolbar-prev',\r
87637 action: 'previouspage'\r
87638 },\r
87639 {\r
87640 xtype: 'component',\r
87641 role: 'currentpage',\r
87642 width: 20,\r
87643 cls: Ext.baseCSSPrefix + 'grid-pagingtoolbar-currentpage'\r
87644 },\r
87645 {\r
87646 xtype: 'component',\r
87647 role: 'totalpages',\r
87648 width: 50,\r
87649 tpl: '&nbsp;/ {totalPages}'\r
87650 },\r
87651 {\r
87652 xtype: 'singlesliderfield',\r
87653 value: 1,\r
87654 flex: 1,\r
87655 minValue: 1,\r
87656 role: 'pageslider'\r
87657 },\r
87658 {\r
87659 xtype: 'button',\r
87660 ui: 'plain',\r
87661 iconCls: Ext.baseCSSPrefix + 'grid-pagingtoolbar-next',\r
87662 action: 'nextpage'\r
87663 }\r
87664 ]\r
87665 }\r
87666 },\r
87667 init: function(grid) {\r
87668 var me = this;\r
87669 me.setGrid(grid);\r
87670 grid.container.add(me.getToolbar());\r
87671 if (grid.getStore().getCount()) {\r
87672 me.updatePageInfo(me.getCurrentPage());\r
87673 }\r
87674 },\r
87675 updateGrid: function(grid, oldGrid) {\r
87676 var me = this;\r
87677 if (oldGrid) {\r
87678 oldGrid.un({\r
87679 updatevisiblecount: 'onUpdateVisibleCount',\r
87680 scope: me\r
87681 });\r
87682 oldGrid.getStore().un({\r
87683 add: 'onTotalCountChange',\r
87684 remove: 'onTotalCountChange',\r
87685 refresh: 'onTotalCountChange',\r
87686 scope: me\r
87687 });\r
87688 me.unbindHook(grid, 'onScrollBinder', 'checkPageChange');\r
87689 }\r
87690 if (grid) {\r
87691 grid.on({\r
87692 updatevisiblecount: 'onUpdateVisibleCount',\r
87693 scope: me\r
87694 });\r
87695 grid.getStore().on({\r
87696 add: 'onTotalCountChange',\r
87697 remove: 'onTotalCountChange',\r
87698 refresh: 'onTotalCountChange',\r
87699 clear: 'onTotalCountChange',\r
87700 scope: me\r
87701 });\r
87702 me.bindHook(grid, 'onScrollBinder', 'checkPageChange');\r
87703 }\r
87704 },\r
87705 checkPageChange: function() {\r
87706 var me = this,\r
87707 grid = me.getGrid(),\r
87708 pageSize = me.getPageSize(),\r
87709 currentPage = me.getCurrentPage(),\r
87710 totalCount = me.getTotalCount(),\r
87711 topVisibleIndex = grid.topVisibleIndex,\r
87712 newPage = Math.floor(grid.topVisibleIndex / pageSize) + 1;\r
87713 if (topVisibleIndex && newPage !== currentPage) {\r
87714 me.preventGridScroll = true;\r
87715 me.setCurrentPage(newPage);\r
87716 me.preventGridScroll = false;\r
87717 }\r
87718 },\r
87719 applyToolbar: function(toolbar) {\r
87720 if (toolbar && !toolbar.isComponent) {\r
87721 toolbar = Ext.factory(toolbar, Ext.Toolbar);\r
87722 }\r
87723 return toolbar;\r
87724 },\r
87725 updateToolbar: function(toolbar) {\r
87726 var me = this;\r
87727 if (toolbar) {\r
87728 me.currentPage = toolbar.down('component[role=currentpage]');\r
87729 me.totalPages = toolbar.down('component[role=totalpages]');\r
87730 me.pageSlider = toolbar.down('sliderfield[role=pageslider]');\r
87731 me.nextPageButton = toolbar.down('button[action=nextpage]');\r
87732 me.previousPageButton = toolbar.down('button[action=previouspage]');\r
87733 me.pageSlider.on({\r
87734 change: 'onPageChange',\r
87735 drag: 'onPageSliderDrag',\r
87736 scope: me\r
87737 });\r
87738 me.nextPageButton.on({\r
87739 tap: 'onNextPageTap',\r
87740 scope: me\r
87741 });\r
87742 me.previousPageButton.on({\r
87743 tap: 'onPreviousPageTap',\r
87744 scope: me\r
87745 });\r
87746 me.currentPage.element.createChild({\r
87747 tag: 'span'\r
87748 });\r
87749 }\r
87750 },\r
87751 onPageChange: function(field, value) {\r
87752 this.setCurrentPage(value);\r
87753 },\r
87754 onPageSliderDrag: function(field, slider, value) {\r
87755 this.setCurrentPage(value);\r
87756 },\r
87757 onNextPageTap: function() {\r
87758 var nextPage = this.getCurrentPage() + 1;\r
87759 if (nextPage <= this.getTotalPages()) {\r
87760 this.setCurrentPage(nextPage);\r
87761 }\r
87762 },\r
87763 onPreviousPageTap: function() {\r
87764 var previousPage = this.getCurrentPage() - 1;\r
87765 if (previousPage > 0) {\r
87766 this.setCurrentPage(previousPage);\r
87767 }\r
87768 },\r
87769 onTotalCountChange: function(store) {\r
87770 this.setTotalCount(store.getCount());\r
87771 },\r
87772 onUpdateVisibleCount: function(grid, visibleCount) {\r
87773 visibleCount -= 1;\r
87774 var store = grid.getStore(),\r
87775 totalCount = store.getCount(),\r
87776 totalPages = Math.ceil(totalCount / visibleCount);\r
87777 this.setTotalPages(totalPages);\r
87778 this.setPageSize(visibleCount);\r
87779 },\r
87780 updateTotalPages: function(totalPages) {\r
87781 var me = this;\r
87782
87783 me.getToolbar();\r
87784 me.totalPages.setData({\r
87785 totalPages: totalPages\r
87786 });\r
87787 me.pageSlider.setMaxValue(totalPages || 1);\r
87788 me.updatePageInfo(me.getCurrentPage());\r
87789 },\r
87790 updateCurrentPage: function(currentPage) {\r
87791 this.updatePageInfo(currentPage);\r
87792 },\r
87793 updateTotalCount: function(totalCount) {\r
87794 var totalPages;\r
87795 if (totalCount !== null && totalCount !== undefined) {\r
87796 if (totalCount === 0) {\r
87797 totalPages = 1;\r
87798 } else {\r
87799 totalPages = Math.ceil(totalCount / this.getPageSize());\r
87800 }\r
87801 this.setTotalPages(totalPages);\r
87802 }\r
87803 },\r
87804 updatePageButtons: function() {\r
87805 var me = this,\r
87806 currentPage = me.getCurrentPage();\r
87807 me.previousPageButton.setDisabled(currentPage === me.getTotalPages());\r
87808 me.nextPageButton.enable(currentPage === 1);\r
87809 },\r
87810 getPageTopRecord: function(page) {\r
87811 var grid = this.getGrid(),\r
87812 store = grid && grid.getStore(),\r
87813 pageSize = this.getPageSize(),\r
87814 pageTopRecordIndex = (page - 1) * pageSize,\r
87815 pageTopRecord = store && store.getAt(pageTopRecordIndex);\r
87816 return pageTopRecord;\r
87817 },\r
87818 privates: {\r
87819 updatePageInfo: function(currentPage) {\r
87820 var me = this,\r
87821 grid = me.getGrid(),\r
87822 pageTopRecord;\r
87823
87824 me.getToolbar();\r
87825
87826
87827 me.currentPage.element.dom.lastChild.innerHTML = currentPage;\r
87828 me.pageSlider.setValue(currentPage);\r
87829 pageTopRecord = me.getPageTopRecord(currentPage);\r
87830 if (grid && !me.preventGridScroll && pageTopRecord) {\r
87831 grid.scrollToRecord(pageTopRecord);\r
87832 }\r
87833 me.updatePageButtons();\r
87834 }\r
87835 }\r
87836});\r
87837\r
87838\r
87839Ext.define('Ext.grid.plugin.SummaryRow', {\r
87840 extend: Ext.grid.Row,\r
87841 alias: 'plugin.gridsummaryrow',\r
87842 mixins: [\r
87843 Ext.mixin.Hookable\r
87844 ],\r
87845 isSpecialRow: true,\r
87846 config: {\r
87847 grid: null,\r
87848 cls: Ext.baseCSSPrefix + 'grid-summaryrow',\r
87849 emptyText: '',\r
87850 emptyCls: Ext.baseCSSPrefix + 'grid-summaryrow-empty',\r
87851 docked: 'top',\r
87852 translatable: {\r
87853 translationMethod: 'csstransform'\r
87854 }\r
87855 },\r
87856 init: function(grid) {\r
87857 this.setGrid(grid);\r
87858 },\r
87859 updateGrid: function(grid, oldGrid) {\r
87860 var me = this,\r
87861 columns, len, headerContainer, i;\r
87862 me.storeListeners = Ext.destroy(me.storeListeners);\r
87863 if (grid) {\r
87864 columns = grid.getColumns();\r
87865 len = columns.length;\r
87866 headerContainer = grid.getHeaderContainer();\r
87867 me.storeListeners = grid.getStore().onAfter({\r
87868 destroyable: true,\r
87869 scope: me,\r
87870 add: 'doUpdateSummary',\r
87871 remove: 'doUpdateSummary',\r
87872 update: 'doUpdateSummary',\r
87873 refresh: 'doUpdateSummary',\r
87874 clear: 'doUpdateSummary'\r
87875 });\r
87876 grid.getHeaderContainer().on({\r
87877 columnadd: 'onColumnAdd',\r
87878 columnmove: 'onColumnMove',\r
87879 columnremove: 'onColumnRemove',\r
87880 columnshow: 'onColumnShow',\r
87881 columnhide: 'onColumnHide',\r
87882 columnresize: 'onColumnResize',\r
87883 scope: me\r
87884 });\r
87885 if (grid.initialized) {\r
87886 grid.container.insertAfter(me, headerContainer);\r
87887 } else {\r
87888 grid.on('initialize', function() {\r
87889 grid.container.insertAfter(me, headerContainer);\r
87890 }, me, {\r
87891 single: true\r
87892 });\r
87893 }\r
87894 grid.addCls(Ext.baseCSSPrefix + 'grid-hassummaryrow');\r
87895 for (i = 0; i < len; i++) {\r
87896 me.onColumnAdd(headerContainer, columns[i]);\r
87897 }\r
87898 me.bindHook(grid, 'onScrollBinder', 'onGridScroll');\r
87899 }\r
87900 },\r
87901 onGridScroll: function(x) {\r
87902 if (this.currentX !== x) {\r
87903 this.translate(x);\r
87904 this.currentX = x;\r
87905 }\r
87906 },\r
87907 onColumnAdd: function(container, column) {\r
87908 this.insertColumn(container.getColumns().indexOf(column), column);\r
87909 this.updateRowWidth();\r
87910 },\r
87911 onColumnMove: function(container, column, header, fromIdx, toIdx) {\r
87912 this.moveColumn(column, fromIdx, toIdx);\r
87913 },\r
87914 onColumnRemove: function(container, column) {\r
87915 this.removeColumn(column);\r
87916 this.updateRowWidth();\r
87917 },\r
87918 onColumnShow: function(container, column) {\r
87919 this.showColumn(column);\r
87920 this.updateRowWidth();\r
87921 },\r
87922 onColumnHide: function(container, column) {\r
87923 this.hideColumn(column);\r
87924 this.updateRowWidth();\r
87925 },\r
87926 onColumnResize: function(container, column, width) {\r
87927 this.setColumnWidth(column, width);\r
87928 this.updateRowWidth();\r
87929 },\r
87930 updateRowWidth: function() {\r
87931 this.setWidth(this.getGrid().getTotalColumnWidth());\r
87932 },\r
87933 doUpdateSummary: function() {\r
87934 var me = this,\r
87935 grid = me.getGrid(),\r
87936 store = grid.getStore(),\r
87937 columns = grid.getColumns(),\r
87938 ln = columns.length,\r
87939 emptyText = me.getEmptyText(),\r
87940 emptyCls = me.getEmptyCls(),\r
87941 i, column, type, renderer, cell, value, field;\r
87942 for (i = 0; i < ln; i++) {\r
87943 column = columns[i];\r
87944 type = column.getSummaryType();\r
87945 cell = me.getCellByColumn(column);\r
87946 if (!column.getIgnore() && type !== null) {\r
87947 field = column.getDataIndex();\r
87948 renderer = column.getSummaryRenderer();\r
87949 if (Ext.isFunction(type)) {\r
87950 value = type.call(store, store.data.items.slice(), field);\r
87951 } else {\r
87952 switch (type) {\r
87953 case 'sum':\r
87954 case 'average':\r
87955 case 'min':\r
87956 case 'max':\r
87957 value = store[type](column.getDataIndex());\r
87958 break;\r
87959 case 'count':\r
87960 value = store.getCount();\r
87961 break;\r
87962 default:\r
87963 value = Ext.callback(type, null, [\r
87964 store.data.items.slice(),\r
87965 field,\r
87966 store\r
87967 ], 0, me);\r
87968 break;\r
87969 }\r
87970 }\r
87971 if (renderer !== null) {\r
87972 type = typeof renderer;\r
87973 if (type === 'function') {\r
87974 value = renderer.call(store, value, store, field, cell);\r
87975 } else if (type === 'string') {\r
87976 value = Ext.callback(renderer, null, [\r
87977 value,\r
87978 store,\r
87979 field,\r
87980 cell\r
87981 ], 0, me);\r
87982 }\r
87983 }\r
87984 cell.element.removeCls(emptyCls);\r
87985 cell.setValue(value);\r
87986 } else {\r
87987 cell.element.addCls(emptyCls);\r
87988 cell.setValue(emptyText);\r
87989 }\r
87990 }\r
87991 },\r
87992 destroy: function() {\r
87993 this.setGrid(null);\r
87994 this.callParent();\r
87995 },\r
87996 privates: {\r
87997
87998 applyViewModel: function() {\r
87999 return undefined;\r
88000 },\r
88001
88002 getCellCfg: function(column) {\r
88003 var cfg = Ext.apply({}, this.callParent([\r
88004 column\r
88005 ]));\r
88006 delete cfg.bind;\r
88007 return cfg;\r
88008 }\r
88009 }\r
88010});\r
88011\r
88012\r
88013Ext.define('Ext.plugin.SortableList', {\r
88014 extend: Ext.Component,\r
88015 alias: 'plugin.sortablelist',\r
88016 mixins: [\r
88017 Ext.mixin.Hookable\r
88018 ],\r
88019 config: {\r
88020 list: null,\r
88021 handleSelector: '.' + Ext.baseCSSPrefix + 'list-sortablehandle'\r
88022 },\r
88023 init: function(list) {\r
88024 this.setList(list);\r
88025 },\r
88026 updateList: function(list) {\r
88027 if (list) {\r
88028 if (list.initialized) {\r
88029 this.attachListeners();\r
88030 } else {\r
88031 list.on({\r
88032 initialize: 'attachListeners',\r
88033 scope: this,\r
88034 single: true\r
88035 });\r
88036 }\r
88037 }\r
88038 },\r
88039 attachListeners: function() {\r
88040 var list = this.getList(),\r
88041 scrollerElement = list.getScrollable().getElement();\r
88042 this.scrollerElement = scrollerElement;\r
88043 scrollerElement.onBefore({\r
88044 dragstart: 'onScrollerDragStart',\r
88045 scope: this\r
88046 });\r
88047 },\r
88048 onScrollerDragStart: function(e, target) {\r
88049 if (Ext.DomQuery.is(target, this.getHandleSelector())) {\r
88050 if (!this.animating) {\r
88051 this.onDragStart(e, target);\r
88052 }\r
88053 return false;\r
88054 }\r
88055 },\r
88056 onDragStart: function(e) {\r
88057 var row = Ext.getCmp(e.getTarget('.' + Ext.baseCSSPrefix + 'list-item').id),\r
88058 list = this.getList(),\r
88059 store = list.getStore();\r
88060 this.scrollerElement.on({\r
88061 drag: 'onDrag',\r
88062 dragend: 'onDragEnd',\r
88063 scope: this\r
88064 });\r
88065 this.positionMap = list.getItemMap();\r
88066 this.listStore = store;\r
88067 this.previousIndexDistance = 0;\r
88068 this.dragRow = row;\r
88069 this.dragRecord = row.getRecord();\r
88070 this.dragRowIndex = this.currentDragRowIndex = row.$dataIndex;\r
88071 this.dragRowHeight = this.positionMap.getItemHeight(this.dragRowIndex);\r
88072 if (list.getInfinite()) {\r
88073 this.startTranslate = this.positionMap.map[this.dragRowIndex];\r
88074 } else {\r
88075 row.translate(0, 0);\r
88076 this.startTranslate = 0;\r
88077 }\r
88078 row.addCls(Ext.baseCSSPrefix + 'list-item-dragging');\r
88079 },\r
88080 onDrag: function(e) {\r
88081 var list = this.getList(),\r
88082 listItems = list.listItems,\r
88083 store = list.getStore(),\r
88084 collection = list.getStore().data,\r
88085 dragRow = this.dragRow,\r
88086 dragRecordKey = dragRow.id,\r
88087 listItemInfo = list.getListItemInfo(),\r
88088 positionMap = this.positionMap,\r
88089 distance = 0,\r
88090 i, item, ln, targetItem, targetIndex, itemIndex, swapIndex, swapPosition, record, swapKey, draggingUp;\r
88091 this.dragRowPosition = this.startTranslate + e.deltaY;\r
88092 dragRow.translate(0, this.dragRowPosition);\r
88093 targetIndex = positionMap.findIndex(this.dragRowPosition + (this.dragRowHeight / 2));\r
88094 targetItem = list.getItemAt(targetIndex);\r
88095 if (targetItem) {\r
88096 distance = targetIndex - this.currentDragRowIndex;\r
88097 if (distance !== 0) {\r
88098 draggingUp = distance < 0;\r
88099 for (i = 0 , ln = Math.abs(distance); i < ln; i++) {\r
88100 if (draggingUp) {\r
88101 swapIndex = this.currentDragRowIndex - i;\r
88102 item = list.getItemAt(swapIndex - 1);\r
88103 } else {\r
88104 swapIndex = this.currentDragRowIndex + i;\r
88105 item = list.getItemAt(swapIndex + 1);\r
88106 }\r
88107 swapPosition = positionMap.map[swapIndex];\r
88108 item.translate(0, swapPosition);\r
88109 record = item.getRecord();\r
88110 swapKey = record.id;\r
88111 Ext.Array.remove(collection.items, record);\r
88112 collection.items.splice(swapIndex, 0, record);\r
88113 collection.indices[dragRecordKey] = collection.indices[swapKey];\r
88114 collection.indices[swapKey] = swapIndex;\r
88115 list.updateListItem(item, swapIndex, listItemInfo);\r
88116 item.$position = swapPosition;\r
88117 }\r
88118 itemIndex = listItems.indexOf(dragRow);\r
88119 Ext.Array.remove(listItems, dragRow);\r
88120 listItems.splice(itemIndex + distance, 0, dragRow);\r
88121 dragRow.$dataIndex = targetIndex;\r
88122 dragRow.$position = positionMap.map[targetIndex];\r
88123 this.currentDragRowIndex = targetIndex;\r
88124 }\r
88125 }\r
88126 },\r
88127 onDragEnd: function() {\r
88128 var me = this,\r
88129 row = me.dragRow,\r
88130 list = me.getList(),\r
88131 listItemInfo = list.getListItemInfo(),\r
88132 position = row.$position;\r
88133 me.scrollerElement.un({\r
88134 drag: 'onDrag',\r
88135 dragend: 'onDragEnd',\r
88136 scope: me\r
88137 });\r
88138 me.animating = true;\r
88139 row.getTranslatable().on('animationend', function() {\r
88140 row.removeCls(Ext.baseCSSPrefix + 'list-item-dragging');\r
88141 var currentIdx = this.currentDragRowIndex,\r
88142 dragIdx = this.dragRowIndex;\r
88143 if (currentIdx !== dragIdx) {\r
88144 list.updateListItem(row, row.$dataIndex, listItemInfo);\r
88145 row.$position = position;\r
88146 list.fireEvent('dragsort', list, row, currentIdx, dragIdx);\r
88147 }\r
88148 me.animating = false;\r
88149 }, me, {\r
88150 single: true\r
88151 });\r
88152 row.translate(0, position, {\r
88153 duration: 100\r
88154 });\r
88155 }\r
88156});\r
88157\r
88158\r
88159Ext.define('Ext.grid.plugin.ViewOptions', {\r
88160 extend: Ext.Component,\r
88161 alias: 'plugin.gridviewoptions',\r
88162 config: {\r
88163 \r
88164 grid: null,\r
88165 \r
88166 sheetWidth: 320,\r
88167 \r
88168 sheet: {\r
88169 baseCls: Ext.baseCSSPrefix + 'grid-viewoptions',\r
88170 xtype: 'sheet',\r
88171 items: [\r
88172 {\r
88173 docked: 'top',\r
88174 xtype: 'titlebar',\r
88175 title: 'Customize',\r
88176 items: {\r
88177 xtype: 'button',\r
88178 text: 'Done',\r
88179 ui: 'action',\r
88180 align: 'right',\r
88181 role: 'donebutton'\r
88182 }\r
88183 }\r
88184 ],\r
88185 hideOnMaskTap: false,\r
88186 enter: 'right',\r
88187 exit: 'right',\r
88188 modal: false,\r
88189 translatable: {\r
88190 translationMethod: 'csstransform'\r
88191 },\r
88192 right: 0,\r
88193 layout: 'fit',\r
88194 stretchY: true\r
88195 },\r
88196 \r
88197 columnList: {\r
88198 xtype: 'nestedlist',\r
88199 title: 'Column',\r
88200 listConfig: {\r
88201 plugins: [\r
88202 {\r
88203 type: 'sortablelist',\r
88204 handleSelector: '.' + Ext.baseCSSPrefix + 'column-options-sortablehandle'\r
88205 }\r
88206 ],\r
88207 mode: 'MULTI',\r
88208 infinite: true,\r
88209 itemTpl: [\r
88210 '<div class="' + Ext.baseCSSPrefix + 'column-options-itemwrap<tpl if="hidden"> {hiddenCls}</tpl>',\r
88211 '<tpl if="grouped"> {groupedCls}</tpl>">',\r
88212 '<div class="' + Ext.baseCSSPrefix + 'column-options-sortablehandle"></div>',\r
88213 '<tpl if="header">',\r
88214 '<div class="' + Ext.baseCSSPrefix + 'column-options-folder"></div>',\r
88215 '<tpl else>',\r
88216 '<div class="' + Ext.baseCSSPrefix + 'column-options-leaf"></div>',\r
88217 '</tpl>',\r
88218 '<div class="' + Ext.baseCSSPrefix + 'column-options-text">{text}</div>',\r
88219 '<tpl if="groupable && dataIndex">',\r
88220 '<div class="' + Ext.baseCSSPrefix + 'column-options-groupindicator"></div>',\r
88221 '</tpl>',\r
88222 '<div class="' + Ext.baseCSSPrefix + 'column-options-visibleindicator"></div>',\r
88223 '</div>'\r
88224 ],\r
88225 triggerEvent: null,\r
88226 bufferSize: 1,\r
88227 minimumBufferSize: 1\r
88228 },\r
88229 store: {\r
88230 type: 'tree',\r
88231 fields: [\r
88232 'id',\r
88233 'text',\r
88234 'dataIndex',\r
88235 'header',\r
88236 'hidden',\r
88237 'hiddenCls',\r
88238 'grouped',\r
88239 'groupedCls',\r
88240 'groupable'\r
88241 ],\r
88242 root: {\r
88243 text: 'Columns'\r
88244 }\r
88245 },\r
88246 clearSelectionOnListChange: false\r
88247 },\r
88248 \r
88249 visibleIndicatorSelector: '.' + Ext.baseCSSPrefix + 'column-options-visibleindicator',\r
88250 \r
88251 groupIndicatorSelector: '.' + Ext.baseCSSPrefix + 'column-options-groupindicator'\r
88252 },\r
88253 \r
88254 _hiddenColumnCls: Ext.baseCSSPrefix + 'column-options-hidden',\r
88255 \r
88256 _groupedColumnCls: Ext.baseCSSPrefix + 'column-options-grouped',\r
88257 \r
88258 sheetVisible: false,\r
88259 init: function(grid) {\r
88260 this.setGrid(grid);\r
88261 },\r
88262 updateGrid: function(grid, oldGrid) {\r
88263 if (oldGrid) {\r
88264 oldGrid.getHeaderContainer().renderElement.un({\r
88265 dragstart: 'onDragStart',\r
88266 drag: 'onDrag',\r
88267 dragend: 'onDragEnd',\r
88268 longpress: 'onHeaderLongPress',\r
88269 scope: this\r
88270 });\r
88271 oldGrid.getHeaderContainer().un({\r
88272 columnadd: 'onColumnAdd',\r
88273 columnmove: 'onColumnMove',\r
88274 columnremove: 'onColumnRemove',\r
88275 scope: this\r
88276 });\r
88277 }\r
88278 if (grid) {\r
88279 grid.getHeaderContainer().renderElement.on({\r
88280 dragstart: 'onDragStart',\r
88281 drag: 'onDrag',\r
88282 dragend: 'onDragEnd',\r
88283 longpress: 'onHeaderLongPress',\r
88284 scope: this\r
88285 });\r
88286 grid.getHeaderContainer().on({\r
88287 columnadd: 'onColumnAdd',\r
88288 columnmove: 'onColumnMove',\r
88289 columnremove: 'onColumnRemove',\r
88290 columnhide: 'onColumnHide',\r
88291 columnshow: 'onColumnShow',\r
88292 scope: this\r
88293 });\r
88294 }\r
88295 },\r
88296 applySheet: function(sheet) {\r
88297 if (sheet && !sheet.isComponent) {\r
88298 sheet = Ext.factory(sheet, Ext.Sheet);\r
88299 }\r
88300 return sheet;\r
88301 },\r
88302 applyColumnList: function(list) {\r
88303 if (list && !list.isComponent) {\r
88304 list = Ext.factory(list, Ext.Container);\r
88305 }\r
88306 return list;\r
88307 },\r
88308 updateColumnList: function(list) {\r
88309 if (list) {\r
88310 list.on({\r
88311 listchange: 'onListChange',\r
88312 scope: this\r
88313 });\r
88314 list.on({\r
88315 dragsort: 'onColumnReorder',\r
88316 delegate: '> list',\r
88317 scope: this\r
88318 });\r
88319 this.attachTapListeners();\r
88320 }\r
88321 },\r
88322 updateSheet: function(sheet) {\r
88323 var sheetWidth = this.getSheetWidth();\r
88324 sheet.setWidth(sheetWidth);\r
88325 sheet.translate(sheetWidth);\r
88326 sheet.add(this.getColumnList());\r
88327 },\r
88328 onDoneButtonTap: function() {\r
88329 this.hideViewOptions();\r
88330 },\r
88331 onColumnReorder: function(list, row, newIndex) {\r
88332 var column = Ext.getCmp(row.getRecord().get('id')),\r
88333 parent = column.getParent(),\r
88334 siblings = parent.getInnerItems(),\r
88335 i, ln, sibling;\r
88336 for (i = 0 , ln = newIndex; i < ln; i++) {\r
88337 sibling = siblings[i];\r
88338 if (!sibling.isHeaderGroup && sibling.getIgnore()) {\r
88339 newIndex += 1;\r
88340 }\r
88341 }\r
88342 this.isMoving = true;\r
88343 parent.insert(newIndex, column);\r
88344 this.isMoving = false;\r
88345 },\r
88346 attachTapListeners: function() {\r
88347 var activeList = this.getColumnList().getActiveItem();\r
88348 if (!activeList.hasAttachedTapListeners) {\r
88349 activeList.onBefore({\r
88350 itemtap: 'onListItemTap',\r
88351 scope: this\r
88352 });\r
88353 activeList.hasAttachedTapListeners = true;\r
88354 }\r
88355 },\r
88356 onListChange: function(nestedList, list) {\r
88357 var store = list.getStore(),\r
88358 activeNode = store.getNode(),\r
88359 records = activeNode.childNodes,\r
88360 ln = records.length,\r
88361 i, column, record;\r
88362 for (i = 0; i < ln; i++) {\r
88363 record = records[i];\r
88364 column = Ext.getCmp(record.getId());\r
88365 record.set('hidden', column.isHidden());\r
88366 }\r
88367 this.attachTapListeners();\r
88368 },\r
88369 onListItemTap: function(list, index, row, record, e) {\r
88370 var me = this,\r
88371 handled = false;\r
88372 if (Ext.fly(e.target).is(me.getVisibleIndicatorSelector())) {\r
88373 me.onVisibleIndicatorTap(row, record, index);\r
88374 handled = true;\r
88375 } else if (Ext.fly(e.target).is(me.getGroupIndicatorSelector())) {\r
88376 me.onGroupIndicatorTap(row, record, index);\r
88377 handled = true;\r
88378 }\r
88379 return !handled;\r
88380 },\r
88381 onVisibleIndicatorTap: function(row, record) {\r
88382 var hidden = !record.get('hidden'),\r
88383 column = Ext.getCmp(record.get('id'));\r
88384 if (hidden) {\r
88385 column.hide();\r
88386 record.set('hidden', true);\r
88387 } else {\r
88388 column.show();\r
88389 record.set('hidden', false);\r
88390 }\r
88391 },\r
88392 onGroupIndicatorTap: function(row, record) {\r
88393 var me = this,\r
88394 grouped = !record.get('grouped'),\r
88395 store = me.getGrid().getStore(),\r
88396 groupedRecord = me._groupedRecord;\r
88397 if (groupedRecord) {\r
88398 groupedRecord.set('grouped', false);\r
88399 }\r
88400 if (grouped) {\r
88401 store.setGrouper({\r
88402 property: record.get('dataIndex')\r
88403 });\r
88404 me._groupedRecord = record;\r
88405 record.set('grouped', true);\r
88406 } else {\r
88407 store.setGrouper(null);\r
88408 me._groupedRecord = null;\r
88409 record.set('grouped', false);\r
88410 }\r
88411 },\r
88412 onColumnHide: function(headerContainer, column) {\r
88413 var nestedList = this.getColumnList(),\r
88414 activeList = nestedList.getActiveItem(),\r
88415 store = activeList.getStore(),\r
88416 record = store.getById(column.getId());\r
88417 if (record) {\r
88418 record.set('hidden', true);\r
88419 }\r
88420 },\r
88421 onColumnShow: function(headerContainer, column) {\r
88422 var nestedList = this.getColumnList(),\r
88423 activeList = nestedList.getActiveItem(),\r
88424 store = activeList.getStore(),\r
88425 record = store.getById(column.getId());\r
88426 if (record) {\r
88427 record.set('hidden', false);\r
88428 }\r
88429 },\r
88430 onColumnAdd: function(headerContainer, column, header) {\r
88431 if (column.getIgnore() || this.isMoving) {\r
88432 return;\r
88433 }\r
88434 var me = this,\r
88435 nestedList = me.getColumnList(),\r
88436 store = nestedList.getStore(),\r
88437 parentNode = store.getRoot(),\r
88438 hiddenCls = me._hiddenColumnCls,\r
88439 grid = me.getGrid(),\r
88440 isGridGrouped = grid.getGrouped(),\r
88441 grouper = grid.getStore().getGrouper(),\r
88442 dataIndex = column.getDataIndex(),\r
88443 data = {\r
88444 id: column.getId(),\r
88445 text: column.getText(),\r
88446 groupable: isGridGrouped && column.getGroupable(),\r
88447 hidden: column.isHidden(),\r
88448 hiddenCls: hiddenCls,\r
88449 grouped: !!(isGridGrouped && grouper && grouper.getProperty() === dataIndex),\r
88450 groupedCls: me._groupedColumnCls,\r
88451 dataIndex: column.getDataIndex(),\r
88452 leaf: true\r
88453 },\r
88454 idx, headerNode;\r
88455 if (header) {\r
88456 headerNode = parentNode.findChild('id', header.getId());\r
88457 if (!headerNode) {\r
88458 idx = header.getParent().indexOf(header);\r
88459 headerNode = parentNode.insertChild(idx, {\r
88460 groupable: false,\r
88461 header: true,\r
88462 hidden: header.isHidden(),\r
88463 hiddenCls: hiddenCls,\r
88464 id: header.getId(),\r
88465 text: header.getText()\r
88466 });\r
88467 }\r
88468 idx = header.indexOf(column);\r
88469 parentNode = headerNode;\r
88470 } else {\r
88471 idx = headerContainer.indexOf(column);\r
88472 }\r
88473 parentNode.insertChild(idx, data);\r
88474 },\r
88475 onColumnMove: function(headerContainer, column, header) {\r
88476 this.onColumnRemove(headerContainer, column);\r
88477 this.onColumnAdd(headerContainer, column, header);\r
88478 },\r
88479 onColumnRemove: function(headerContainer, column) {\r
88480 if (column.getIgnore() || this.isMoving) {\r
88481 return;\r
88482 }\r
88483 var root = this.getColumnList().getStore().getRoot(),\r
88484 record = root.findChild('id', column.getId(), true);\r
88485 if (record) {\r
88486 record.parentNode.removeChild(record, true);\r
88487 }\r
88488 },\r
88489 onDragStart: function() {\r
88490 var sheetWidth = this.getSheetWidth(),\r
88491 sheet = this.getSheet();\r
88492 if (!this.sheetVisible) {\r
88493 sheet.translate(sheetWidth);\r
88494 this.startTranslate = sheetWidth;\r
88495 } else {\r
88496 sheet.translate(0);\r
88497 this.startTranslate = 0;\r
88498 }\r
88499 },\r
88500 onDrag: function(e) {\r
88501 this.getSheet().translate(Math.max(this.startTranslate + e.deltaX, 0));\r
88502 },\r
88503 onDragEnd: function(e) {\r
88504 var me = this;\r
88505 if (e.flick.velocity.x > 0.1) {\r
88506 me.hideViewOptions();\r
88507 } else {\r
88508 me.showViewOptions();\r
88509 }\r
88510 },\r
88511 onHeaderLongPress: function(e) {\r
88512 if (!this.sheetVisible) {\r
88513 this.showViewOptions();\r
88514 }\r
88515 },\r
88516 hideViewOptions: function() {\r
88517 var sheet = this.getSheet();\r
88518 this.getGrid().getHeaderContainer().setSortable(true);\r
88519 sheet.translate(this.getSheetWidth(), 0, {\r
88520 duration: 100\r
88521 });\r
88522 sheet.getTranslatable().on('animationend', function() {\r
88523 if (sheet.getModal()) {\r
88524 sheet.getModal().destroy();\r
88525 sheet.setModal(null);\r
88526 }\r
88527 sheet.hide(null);\r
88528 }, this, {\r
88529 single: true\r
88530 });\r
88531 this.sheetVisible = false;\r
88532 },\r
88533 showViewOptions: function() {\r
88534 var me = this,\r
88535 sheet = me.getSheet(),\r
88536 modal = null;\r
88537 me.setup();\r
88538 if (!me.sheetVisible) {\r
88539
88540
88541
88542 me.getGrid().getHeaderContainer().setSortable(false);\r
88543 me.updateListInfo();\r
88544 sheet.show();\r
88545 sheet.translate(0, 0, {\r
88546 duration: 100\r
88547 });\r
88548 sheet.getTranslatable().on('animationend', function() {\r
88549 sheet.setModal(true);\r
88550 modal = sheet.getModal();\r
88551 modal.element.onBefore({\r
88552 tap: 'hideViewOptions',\r
88553 dragstart: 'onDragStart',\r
88554 drag: 'onDrag',\r
88555 dragend: 'onDragEnd',\r
88556 scope: me\r
88557 });\r
88558 }, me, {\r
88559 single: true\r
88560 });\r
88561 me.sheetVisible = true;\r
88562 }\r
88563 },\r
88564 privates: {\r
88565 setup: function() {\r
88566 var me = this,\r
88567 sheet;\r
88568 if (me.doneSetup) {\r
88569 return;\r
88570 }\r
88571 me.doneSetup = true;\r
88572 sheet = me.getSheet();\r
88573 me.getGrid().add(sheet);\r
88574 sheet.translate(me.getSheetWidth());\r
88575 sheet.down('button[role=donebutton]').on({\r
88576 tap: 'onDoneButtonTap',\r
88577 scope: me\r
88578 });\r
88579 },\r
88580 updateListInfo: function() {\r
88581 var grid = this.getGrid(),\r
88582 store = grid.getStore(),\r
88583 grouper = store.getGrouper(),\r
88584 grouperProp = grouper && grouper.getProperty(),\r
88585 headerContainer = grid.getHeaderContainer();\r
88586 this.getColumnList().getStore().getRoot().cascadeBy(function(node) {\r
88587 var dataIndex = node.get('dataIndex');\r
88588 node.set('grouped', dataIndex && dataIndex === grouperProp);\r
88589 });\r
88590 }\r
88591 }\r
88592});\r
88593\r
88594\r
88595Ext.define('Ext.navigation.Bar', {\r
88596 extend: Ext.TitleBar,\r
88597 \r
88598 isToolbar: true,\r
88599 config: {\r
88600 \r
88601 baseCls: Ext.baseCSSPrefix + 'toolbar',\r
88602 \r
88603 cls: Ext.baseCSSPrefix + 'navigation-bar',\r
88604 \r
88605 ui: 'dark',\r
88606 \r
88607 title: null,\r
88608 \r
88609 defaultType: 'button',\r
88610 \r
88611 layout: {\r
88612 type: 'hbox'\r
88613 },\r
88614 \r
88615 \r
88616 defaultBackButtonText: 'Back',\r
88617 \r
88618 animation: {\r
88619 duration: 300\r
88620 },\r
88621 \r
88622 useTitleForBackButtonText: null,\r
88623 \r
88624 view: null,\r
88625 \r
88626 android2Transforms: false,\r
88627 \r
88628 backButton: {\r
88629 align: 'left',\r
88630 ui: 'back',\r
88631 hidden: true\r
88632 }\r
88633 },\r
88634 \r
88635 constructor: function(config) {\r
88636 config = config || {};\r
88637 if (!config.items) {\r
88638 config.items = [];\r
88639 }\r
88640 this.backButtonStack = [];\r
88641 this.activeAnimations = [];\r
88642 this.callParent([\r
88643 config\r
88644 ]);\r
88645 },\r
88646 \r
88647 applyBackButton: function(config) {\r
88648 return Ext.factory(config, Ext.Button, this.getBackButton());\r
88649 },\r
88650 \r
88651 updateBackButton: function(newBackButton, oldBackButton) {\r
88652 if (oldBackButton) {\r
88653 this.remove(oldBackButton);\r
88654 }\r
88655 if (newBackButton) {\r
88656 this.add(newBackButton);\r
88657 newBackButton.on({\r
88658 scope: this,\r
88659 tap: this.onBackButtonTap\r
88660 });\r
88661 }\r
88662 },\r
88663 onBackButtonTap: function() {\r
88664 this.fireEvent('back', this);\r
88665 },\r
88666 \r
88667 updateView: function(newView) {\r
88668 var me = this,\r
88669 backButton, innerItems, i, backButtonText, item, title, titleText;\r
88670
88671 me.getItems();\r
88672 backButton = me.getBackButton();\r
88673 if (newView) {\r
88674
88675 innerItems = newView.getInnerItems();\r
88676 for (i = 0; i < innerItems.length; i++) {\r
88677 item = innerItems[i];\r
88678 title = (item.getTitle) ? item.getTitle() : item.config.title;\r
88679 me.backButtonStack.push(title || '&nbsp;');\r
88680 }\r
88681 titleText = me.getTitleText();\r
88682 if (titleText === undefined) {\r
88683 titleText = '';\r
88684 }\r
88685 me.setTitle(titleText);\r
88686 backButtonText = me.getBackButtonText();\r
88687 if (backButtonText) {\r
88688 backButton.setText(backButtonText);\r
88689 backButton.show();\r
88690 }\r
88691 }\r
88692 },\r
88693 \r
88694 onViewAdd: function(view, item) {\r
88695 var me = this,\r
88696 backButtonStack = me.backButtonStack,\r
88697 hasPrevious, title;\r
88698 me.endAnimation();\r
88699 title = (item.getTitle) ? item.getTitle() : item.config.title;\r
88700 backButtonStack.push(title || '&nbsp;');\r
88701 hasPrevious = backButtonStack.length > 1;\r
88702 me.doChangeView(view, hasPrevious, false);\r
88703 },\r
88704 \r
88705 onViewRemove: function(view) {\r
88706 var me = this,\r
88707 backButtonStack = me.backButtonStack,\r
88708 hasPrevious;\r
88709 me.endAnimation();\r
88710 backButtonStack.pop();\r
88711 hasPrevious = backButtonStack.length > 1;\r
88712 me.doChangeView(view, hasPrevious, true);\r
88713 },\r
88714 \r
88715 doChangeView: function(view, hasPrevious, reverse) {\r
88716 var me = this,\r
88717 leftBox = me.leftBox,\r
88718 leftBoxElement = leftBox.element,\r
88719 titleComponent = me.titleComponent,\r
88720 titleElement = titleComponent.element,\r
88721 backButton = me.getBackButton(),\r
88722 titleText = me.getTitleText(),\r
88723 backButtonText = me.getBackButtonText(),\r
88724 animation = me.getAnimation() && view.getLayout().getAnimation(),\r
88725 animated = animation && animation.isAnimation && view.isPainted(),\r
88726 properties, leftGhost, titleGhost, leftProps, titleProps;\r
88727 if (animated) {\r
88728 leftGhost = me.createProxy(leftBox.element);\r
88729 leftBoxElement.setStyle('opacity', '0');\r
88730 backButton.setText(backButtonText);\r
88731 backButton[hasPrevious ? 'show' : 'hide']();\r
88732 titleGhost = me.createProxy(titleComponent.element.getParent());\r
88733 titleElement.setStyle('opacity', '0');\r
88734 me.setTitle(titleText);\r
88735 properties = me.measureView(leftGhost, titleGhost, reverse);\r
88736 leftProps = properties.left;\r
88737 titleProps = properties.title;\r
88738 me.isAnimating = true;\r
88739 me.animate(leftBoxElement, leftProps.element);\r
88740 me.animate(titleElement, titleProps.element, function() {\r
88741 titleElement.setLeft(properties.titleLeft);\r
88742 me.isAnimating = false;\r
88743 me.refreshTitlePosition();\r
88744 });\r
88745 me.animate(leftGhost.ghost, leftProps.ghost);\r
88746 me.animate(titleGhost.ghost, titleProps.ghost, function() {\r
88747 leftGhost.ghost.destroy();\r
88748 titleGhost.ghost.destroy();\r
88749 });\r
88750 } else {\r
88751 if (hasPrevious) {\r
88752 backButton.setText(backButtonText);\r
88753 backButton.show();\r
88754 } else {\r
88755 backButton.hide();\r
88756 }\r
88757 me.setTitle(titleText);\r
88758 }\r
88759 },\r
88760 \r
88761 measureView: function(oldLeft, oldTitle, reverse) {\r
88762 var me = this,\r
88763 barElement = me.element,\r
88764 newLeftElement = me.leftBox.element,\r
88765 titleElement = me.titleComponent.element,\r
88766 minOffset = Math.min(barElement.getWidth() / 3, 200),\r
88767 newLeftWidth = newLeftElement.getWidth(),\r
88768 barX = barElement.getX(),\r
88769 barWidth = barElement.getWidth(),\r
88770 titleX = titleElement.getX(),\r
88771 titleLeft = titleElement.getLeft(true),\r
88772 titleWidth = titleElement.getWidth(),\r
88773 oldLeftX = oldLeft.x,\r
88774 oldLeftWidth = oldLeft.width,\r
88775 oldLeftLeft = oldLeft.left,\r
88776 newOffset, oldOffset, leftAnims, titleAnims, omega, theta;\r
88777 theta = barX - oldLeftX - oldLeftWidth;\r
88778 if (reverse) {\r
88779 newOffset = theta;\r
88780 oldOffset = Math.min(titleX - oldLeftWidth, minOffset);\r
88781 } else {\r
88782 oldOffset = theta;\r
88783 newOffset = Math.min(titleX - barX, minOffset);\r
88784 }\r
88785 leftAnims = {\r
88786 element: {\r
88787 from: {\r
88788 transform: {\r
88789 translateX: newOffset\r
88790 },\r
88791 opacity: 0\r
88792 },\r
88793 to: {\r
88794 transform: {\r
88795 translateX: 0\r
88796 },\r
88797 opacity: 1\r
88798 }\r
88799 },\r
88800 ghost: {\r
88801 to: {\r
88802 transform: {\r
88803 translateX: oldOffset\r
88804 },\r
88805 opacity: 0\r
88806 }\r
88807 }\r
88808 };\r
88809 theta = barX - titleX + newLeftWidth;\r
88810 if ((oldLeftLeft + titleWidth) > titleX) {\r
88811 omega = barX - titleX - titleWidth;\r
88812 }\r
88813 if (reverse) {\r
88814 titleElement.setLeft(0);\r
88815 oldOffset = barX + barWidth - titleX - titleWidth;\r
88816 if (omega !== undefined) {\r
88817 newOffset = omega;\r
88818 } else {\r
88819 newOffset = theta;\r
88820 }\r
88821 } else {\r
88822 newOffset = barX + barWidth - titleX - titleWidth;\r
88823 if (omega !== undefined) {\r
88824 oldOffset = omega;\r
88825 } else {\r
88826 oldOffset = theta;\r
88827 }\r
88828 newOffset = Math.max(titleLeft, newOffset);\r
88829 }\r
88830 titleAnims = {\r
88831 element: {\r
88832 from: {\r
88833 transform: {\r
88834 translateX: newOffset\r
88835 },\r
88836 opacity: 0\r
88837 },\r
88838 to: {\r
88839 transform: {\r
88840 translateX: titleLeft\r
88841 },\r
88842 opacity: 1\r
88843 }\r
88844 },\r
88845 ghost: {\r
88846 to: {\r
88847 transform: {\r
88848 translateX: oldOffset\r
88849 },\r
88850 opacity: 0\r
88851 }\r
88852 }\r
88853 };\r
88854 return {\r
88855 left: leftAnims,\r
88856 title: titleAnims,\r
88857 titleLeft: titleLeft\r
88858 };\r
88859 },\r
88860 \r
88861 animate: function(element, config, callback) {\r
88862 var me = this,\r
88863 animation;\r
88864
88865 element.setLeft(0);\r
88866 config = Ext.apply(config, {\r
88867 element: element,\r
88868 easing: 'ease-in-out',\r
88869 duration: me.getAnimation().duration || 250,\r
88870 preserveEndState: true\r
88871 });\r
88872 animation = new Ext.fx.Animation(config);\r
88873 animation.on('animationend', function() {\r
88874 if (callback) {\r
88875 callback.call(me);\r
88876 }\r
88877 }, me);\r
88878 Ext.Animator.run(animation);\r
88879 me.activeAnimations.push(animation);\r
88880 },\r
88881 endAnimation: function() {\r
88882 var activeAnimations = this.activeAnimations,\r
88883 animation, i, ln;\r
88884 if (activeAnimations) {\r
88885 ln = activeAnimations.length;\r
88886 for (i = 0; i < ln; i++) {\r
88887 animation = activeAnimations[i];\r
88888 if (animation.isAnimating) {\r
88889 animation.stopAnimation();\r
88890 } else {\r
88891 animation.destroy();\r
88892 }\r
88893 }\r
88894 this.activeAnimations = [];\r
88895 }\r
88896 },\r
88897 refreshTitlePosition: function() {\r
88898 if (!this.isAnimating) {\r
88899 this.callParent();\r
88900 }\r
88901 },\r
88902 \r
88903 getBackButtonText: function() {\r
88904 var text = this.backButtonStack[this.backButtonStack.length - 2],\r
88905 useTitleForBackButtonText = this.getUseTitleForBackButtonText();\r
88906 if (!useTitleForBackButtonText) {\r
88907 if (text) {\r
88908 text = this.getDefaultBackButtonText();\r
88909 }\r
88910 }\r
88911 return text;\r
88912 },\r
88913 \r
88914 getTitleText: function() {\r
88915 return this.backButtonStack[this.backButtonStack.length - 1];\r
88916 },\r
88917 \r
88918 beforePop: function(count) {\r
88919 count--;\r
88920 for (var i = 0; i < count; i++) {\r
88921 this.backButtonStack.pop();\r
88922 }\r
88923 },\r
88924 \r
88925 updateHidden: function(hidden) {\r
88926 if (!hidden) {\r
88927 this.element.setStyle({\r
88928 position: 'relative',\r
88929 top: 'auto',\r
88930 left: 'auto',\r
88931 width: 'auto'\r
88932 });\r
88933 } else {\r
88934 this.element.setStyle({\r
88935 position: 'absolute',\r
88936 top: '-1000px',\r
88937 left: '-1000px',\r
88938 width: this.element.getWidth() + 'px'\r
88939 });\r
88940 }\r
88941 },\r
88942 \r
88943 createProxy: function(element) {\r
88944 var ghost, x, y, left, width;\r
88945 ghost = element.dom.cloneNode(true);\r
88946 ghost.id = element.id + '-proxy';\r
88947
88948 element.getParent().dom.appendChild(ghost);\r
88949
88950 ghost = Ext.get(ghost);\r
88951 x = element.getX();\r
88952 y = element.getY();\r
88953 left = element.getLeft(true);\r
88954 width = element.getWidth();\r
88955 ghost.setStyle('position', 'absolute');\r
88956 ghost.setX(x);\r
88957 ghost.setY(y);\r
88958 ghost.setHeight(element.getHeight());\r
88959 ghost.setWidth(width);\r
88960 return {\r
88961 x: x,\r
88962 y: y,\r
88963 left: left,\r
88964 width: width,\r
88965 ghost: ghost\r
88966 };\r
88967 }\r
88968});\r
88969\r
88970\r
88971Ext.define('Ext.navigation.View', {\r
88972 extend: Ext.Container,\r
88973 alternateClassName: 'Ext.NavigationView',\r
88974 xtype: 'navigationview',\r
88975 config: {\r
88976 \r
88977 baseCls: Ext.baseCSSPrefix + 'navigationview',\r
88978 \r
88979 navigationBar: {\r
88980 docked: 'top'\r
88981 },\r
88982 \r
88983 defaultBackButtonText: 'Back',\r
88984 \r
88985 useTitleForBackButtonText: false,\r
88986 \r
88987 \r
88988 layout: {\r
88989 type: 'card',\r
88990 animation: {\r
88991 duration: 300,\r
88992 easing: 'ease-out',\r
88993 type: 'slide',\r
88994 direction: 'left'\r
88995 }\r
88996 }\r
88997 },\r
88998 \r
88999 \r
89000 \r
89001 \r
89002 initialize: function() {\r
89003 var me = this,\r
89004 navBar = me.getNavigationBar();\r
89005
89006 if (navBar) {\r
89007 navBar.on({\r
89008 back: me.onBackButtonTap,\r
89009 scope: me\r
89010 });\r
89011 me.relayEvents(navBar, 'rightbuttontap');\r
89012 me.relayEvents(me, {\r
89013 add: 'push',\r
89014 remove: 'pop'\r
89015 });\r
89016 }\r
89017
89018 var layout = me.getLayout();\r
89019 if (layout && !layout.isCard) {\r
89020 Ext.Logger.error('The base layout for a NavigationView must always be a Card Layout');\r
89021 }\r
89022 },\r
89023
89024 \r
89025 applyLayout: function(config) {\r
89026 config = config || {};\r
89027 return config;\r
89028 },\r
89029 \r
89030 onBackButtonTap: function() {\r
89031 this.pop();\r
89032 this.fireEvent('back', this);\r
89033 },\r
89034 \r
89035 push: function(view) {\r
89036 return this.add(view);\r
89037 },\r
89038 \r
89039 pop: function(count) {\r
89040 if (this.beforePop(count)) {\r
89041 return this.doPop();\r
89042 }\r
89043 },\r
89044 \r
89045 beforePop: function(count) {\r
89046 var me = this,\r
89047 innerItems = me.getInnerItems(),\r
89048 last, i, ln, toRemove;\r
89049 if (Ext.isString(count) || Ext.isObject(count)) {\r
89050 last = innerItems.length - 1;\r
89051 for (i = last; i >= 0; i--) {\r
89052 if ((Ext.isString(count) && Ext.ComponentQuery.is(innerItems[i], count)) || (Ext.isObject(count) && count == innerItems[i])) {\r
89053 count = last - i;\r
89054 break;\r
89055 }\r
89056 }\r
89057 if (!Ext.isNumber(count)) {\r
89058 return false;\r
89059 }\r
89060 }\r
89061 ln = innerItems.length;\r
89062
89063 if (!Ext.isNumber(count) || count < 1) {\r
89064 count = 1;\r
89065 }\r
89066
89067 count = Math.min(count, ln - 1);\r
89068 if (count) {\r
89069
89070 me.getNavigationBar().beforePop(count);\r
89071
89072 toRemove = innerItems.splice(-count, count - 1);\r
89073 for (i = 0; i < toRemove.length; i++) {\r
89074 this.remove(toRemove[i]);\r
89075 }\r
89076 return true;\r
89077 }\r
89078 return false;\r
89079 },\r
89080 \r
89081 doPop: function() {\r
89082 var me = this,\r
89083 innerItems = this.getInnerItems();\r
89084
89085 me.remove(innerItems[innerItems.length - 1]);\r
89086
89087 if (innerItems.length < 3 && this.$backButton) {\r
89088 this.$backButton.hide();\r
89089 }\r
89090
89091 if (this.$titleContainer) {\r
89092
89093 if (!this.$titleContainer.setTitle) {\r
89094 Ext.Logger.error([\r
89095 'You have selected to display a title in a component that does not ',\r
89096 'support titles in NavigationView. Please remove the `title` configuration from your ',\r
89097 'NavigationView item, or change it to a component that has a `setTitle` method.'\r
89098 ].join(''));\r
89099 }\r
89100
89101 var item = innerItems[innerItems.length - 2];\r
89102 this.$titleContainer.setTitle((item.getTitle) ? item.getTitle() : item.config.title);\r
89103 }\r
89104 return this.getActiveItem();\r
89105 },\r
89106 \r
89107 getPreviousItem: function() {\r
89108 var innerItems = this.getInnerItems();\r
89109 return innerItems[innerItems.length - 2];\r
89110 },\r
89111 \r
89112 updateUseTitleForBackButtonText: function(useTitleForBackButtonText) {\r
89113 var navigationBar = this.getNavigationBar();\r
89114 if (navigationBar) {\r
89115 navigationBar.setUseTitleForBackButtonText(useTitleForBackButtonText);\r
89116 }\r
89117 },\r
89118 \r
89119 updateDefaultBackButtonText: function(defaultBackButtonText) {\r
89120 var navigationBar = this.getNavigationBar();\r
89121 if (navigationBar) {\r
89122 navigationBar.setDefaultBackButtonText(defaultBackButtonText);\r
89123 }\r
89124 },\r
89125 \r
89126 onBackButtonContainerAdd: function(toolbar, item) {\r
89127 item.on({\r
89128 scope: this,\r
89129 show: this.refreshBackButtonContainer,\r
89130 hide: this.refreshBackButtonContainer\r
89131 });\r
89132 this.refreshBackButtonContainer();\r
89133 },\r
89134 \r
89135 onBackButtonContainerRemove: function(toolbar, item) {\r
89136 item.un({\r
89137 scope: this,\r
89138 show: this.refreshBackButtonContainer,\r
89139 hide: this.refreshBackButtonContainer\r
89140 });\r
89141 this.refreshBackButtonContainer();\r
89142 },\r
89143 \r
89144 refreshBackButtonContainer: function() {\r
89145 if (!this.$backButtonContainer) {\r
89146 return;\r
89147 }\r
89148 var i = 0,\r
89149 backButtonContainer = this.$backButtonContainer,\r
89150 items = backButtonContainer.items,\r
89151 item;\r
89152 for (; i < items.length; i++) {\r
89153 item = items.get(i);\r
89154 if (!item.isHidden()) {\r
89155 this.$backButtonContainer.show();\r
89156 return;\r
89157 }\r
89158 }\r
89159 this.$backButtonContainer.hide();\r
89160 },\r
89161 \r
89162 applyNavigationBar: function(config) {\r
89163 var me = this;\r
89164 if (!config) {\r
89165 config = {\r
89166 hidden: true,\r
89167 docked: 'top'\r
89168 };\r
89169 }\r
89170
89171
89172 me.getItems();\r
89173 if (config.title) {\r
89174 delete config.title;\r
89175
89176 Ext.Logger.warn("Ext.navigation.View: The 'navigationBar' configuration does not accept a 'title' property. You " + "set the title of the navigationBar by giving this navigation view's children a 'title' property.");\r
89177 }\r
89178
89179 config.view = me;\r
89180 config.useTitleForBackButtonText = me.getUseTitleForBackButtonText();\r
89181
89182 if (config.splitNavigation) {\r
89183 me.$titleContainer = me.add({\r
89184 docked: 'top',\r
89185 xtype: 'titlebar',\r
89186 ui: 'light',\r
89187 title: me.$currentTitle || ''\r
89188 });\r
89189 var containerConfig = (config.splitNavigation === true) ? {} : config.splitNavigation;\r
89190 me.$backButtonContainer = me.add({\r
89191 xtype: 'toolbar',\r
89192 docked: 'bottom',\r
89193 hidden: true\r
89194 });\r
89195
89196
89197 me.$backButtonContainer.on({\r
89198 scope: me,\r
89199 add: me.onBackButtonContainerAdd,\r
89200 remove: me.onBackButtonContainerRemove\r
89201 });\r
89202 me.$backButton = me.$backButtonContainer.add({\r
89203 xtype: 'button',\r
89204 text: 'Back',\r
89205 hidden: true,\r
89206 ui: 'back'\r
89207 });\r
89208
89209 if (config.items) {\r
89210 me.$backButtonContainer.add(config.items);\r
89211 }\r
89212
89213 if (containerConfig.items) {\r
89214 me.$titleContainer.add(containerConfig.items);\r
89215 }\r
89216 me.$backButton.on({\r
89217 scope: me,\r
89218 tap: me.onBackButtonTap\r
89219 });\r
89220 config = {\r
89221 hidden: true,\r
89222 docked: 'top'\r
89223 };\r
89224 }\r
89225 return Ext.factory(config, Ext.navigation.Bar, this.getNavigationBar());\r
89226 },\r
89227 \r
89228 updateNavigationBar: function(newNavigationBar, oldNavigationBar) {\r
89229 if (oldNavigationBar) {\r
89230 this.remove(oldNavigationBar, true);\r
89231 }\r
89232 if (newNavigationBar) {\r
89233 this.add(newNavigationBar);\r
89234 }\r
89235 },\r
89236 \r
89237 applyActiveItem: function(activeItem, currentActiveItem) {\r
89238 var me = this,\r
89239 innerItems = me.getInnerItems();\r
89240
89241 me.getItems();\r
89242
89243 if (!me.initialized) {\r
89244 activeItem = innerItems.length - 1;\r
89245 }\r
89246 return this.callParent([\r
89247 activeItem,\r
89248 currentActiveItem\r
89249 ]);\r
89250 },\r
89251 doResetActiveItem: function(innerIndex) {\r
89252 var me = this,\r
89253 innerItems = me.getInnerItems(),\r
89254 animation = me.getLayout().getAnimation();\r
89255 if (innerIndex > 0) {\r
89256 if (animation && animation.isAnimation) {\r
89257 animation.setReverse(true);\r
89258 }\r
89259 me.setActiveItem(innerIndex - 1);\r
89260 me.getNavigationBar().onViewRemove(me, innerItems[innerIndex], innerIndex);\r
89261 }\r
89262 },\r
89263 \r
89264 doRemove: function() {\r
89265 var animation = this.getLayout().getAnimation();\r
89266 if (animation && animation.isAnimation) {\r
89267 animation.setReverse(false);\r
89268 }\r
89269 this.callParent(arguments);\r
89270 },\r
89271 \r
89272 onItemAdd: function(item, index) {\r
89273 var me = this,\r
89274 initialized = me.initialized,\r
89275 navigationBar;\r
89276
89277 if (item && item.getDocked() && item.config.title === true) {\r
89278 me.$titleContainer = item;\r
89279 }\r
89280 me.doItemLayoutAdd(item, index);\r
89281 if (initialized && item.isInnerItem()) {\r
89282 me.setActiveItem(item);\r
89283 navigationBar = this.getNavigationBar();\r
89284 if (navigationBar) {\r
89285 this.getNavigationBar().onViewAdd(me, item, index);\r
89286 }\r
89287
89288 if (me.$backButtonContainer) {\r
89289 me.$backButton.show();\r
89290 }\r
89291 }\r
89292 if (item && item.isInnerItem()) {\r
89293
89294 me.updateTitleContainerTitle((item.getTitle) ? item.getTitle() : item.config.title);\r
89295 }\r
89296 if (initialized) {\r
89297 me.fireEvent('add', me, item, index);\r
89298 }\r
89299 },\r
89300 \r
89301 updateTitleContainerTitle: function(title) {\r
89302 if (this.$titleContainer) {\r
89303
89304 if (!this.$titleContainer.setTitle) {\r
89305 Ext.Logger.error([\r
89306 'You have selected to display a title in a component that does not ',\r
89307 'support titles in NavigationView. Please remove the `title` configuration from your ',\r
89308 'NavigationView item, or change it to a component that has a `setTitle` method.'\r
89309 ].join(''));\r
89310 }\r
89311
89312 this.$titleContainer.setTitle(title);\r
89313 } else {\r
89314 this.$currentTitle = title;\r
89315 }\r
89316 },\r
89317 \r
89318 reset: function() {\r
89319 return this.pop(this.getInnerItems().length);\r
89320 }\r
89321});\r
89322\r
89323\r
89324Ext.define('Ext.panel.Header', {\r
89325 extend: Ext.Container,\r
89326 xtype: 'panelheader',\r
89327 \r
89328 isPanelHeader: true,\r
89329 baseCls: Ext.baseCSSPrefix + 'panel-header',\r
89330 config: {\r
89331 \r
89332 glyph: null,\r
89333 \r
89334 icon: null,\r
89335 \r
89336 iconAlign: null,\r
89337 \r
89338 iconCls: null,\r
89339 \r
89340 title: null,\r
89341 \r
89342 titleAlign: null,\r
89343 layout: {\r
89344 type: 'hbox',\r
89345 align: 'center'\r
89346 }\r
89347 },\r
89348 add: function(item) {\r
89349 var me = this,\r
89350 isArray = Ext.isArray(item),\r
89351 array = isArray ? item.slice(0) : [\r
89352 item\r
89353 ],\r
89354
89355 items = me.getItems(),\r
89356 length = items.length,\r
89357 n = array.length,\r
89358 c, i, n, pos;\r
89359 for (i = 0; i < n; ++i) {\r
89360
89361
89362 array[i] = me.factoryItem(array[i]);\r
89363 }\r
89364 Ext.Array.sort(array, me.sortByWeight);\r
89365 if (length) {\r
89366 items = items.items;\r
89367
89368 pos = 0;\r
89369
89370
89371
89372
89373 for (i = 0; i < n; ++i) {\r
89374 c = array[i];\r
89375 for (; pos < length; ++pos) {\r
89376 if (me.sortByWeight(c, items[pos]) < 0) {\r
89377 break;\r
89378 }\r
89379 }\r
89380 me.insert(pos, c);\r
89381 ++pos;\r
89382 ++length;\r
89383 }\r
89384 } else {\r
89385 me.callParent([\r
89386 array\r
89387 ]);\r
89388 }\r
89389 return isArray ? array : item;\r
89390 },\r
89391 applyTitle: function(newTitle, oldTitle) {\r
89392 var title = oldTitle;\r
89393 if (title) {\r
89394 if (!newTitle || typeof newTitle === 'string') {\r
89395 title.setText(newTitle || '');\r
89396 } else if (newTitle) {\r
89397 title.setConfig(newTitle);\r
89398 }\r
89399 } else {\r
89400 title = Ext.create(this.createTitle(newTitle));\r
89401 }\r
89402 return title;\r
89403 },\r
89404 createTitle: function(config) {\r
89405 var ret = {\r
89406 xtype: 'paneltitle',\r
89407 flex: 1\r
89408 };\r
89409 if (config) {\r
89410 if (typeof config === 'string') {\r
89411 config = {\r
89412 text: config\r
89413 };\r
89414 }\r
89415 Ext.merge(ret, config);\r
89416 }\r
89417 return ret;\r
89418 },\r
89419 createTools: function(tools, toolOwner) {\r
89420 var n = tools && tools.length,\r
89421 ret = n && [],\r
89422 c, i;\r
89423 toolOwner = toolOwner || null;\r
89424 for (i = 0; i < n; ++i) {\r
89425 c = tools[i];\r
89426 if (typeof c === 'string') {\r
89427 c = {\r
89428 xtype: 'paneltool',\r
89429 type: c,\r
89430 toolOwner: toolOwner\r
89431 };\r
89432 } else if (c.isInstance) {\r
89433 if (toolOwner) {\r
89434 c.setToolOwner(toolOwner);\r
89435 }\r
89436 } else {\r
89437 c = Ext.apply({\r
89438 xtype: 'paneltool',\r
89439 toolOwner: toolOwner\r
89440 }, c);\r
89441 }\r
89442 ret[i] = c;\r
89443 }\r
89444 return ret;\r
89445 },\r
89446 updateGlyph: function(glyph) {\r
89447 this.ensureTitle().setGlyph(glyph);\r
89448 },\r
89449 updateIcon: function(icon) {\r
89450 this.ensureTitle().setIcon(icon);\r
89451 },\r
89452 updateIconAlign: function(align, oldAlign) {\r
89453 this.ensureTitle().setIconAlign(align);\r
89454 },\r
89455 updateIconCls: function(cls) {\r
89456 this.ensureTitle().setIconCls(cls);\r
89457 },\r
89458 updateTitle: function(title, oldTitle) {\r
89459 if (oldTitle) {\r
89460 oldTitle.setConfig(title);\r
89461 } else {\r
89462 this.add(title);\r
89463 }\r
89464 },\r
89465 updateTitleAlign: function(align, oldAlign) {\r
89466 this.ensureTitle().setTextAlign(align);\r
89467 },\r
89468 updateUi: function(ui, oldValue) {\r
89469 this.callParent([\r
89470 ui,\r
89471 oldValue\r
89472 ]);\r
89473 this.ensureTitle().setUi(ui);\r
89474 },\r
89475 privates: {\r
89476 clearTools: function() {\r
89477 var items = this.getItems().items,\r
89478 c, i;\r
89479 for (i = items.length; i-- > 0; ) {\r
89480 c = items[i];\r
89481 if (c.isPanelTool) {\r
89482 this.remove(c);\r
89483 }\r
89484 }\r
89485 },\r
89486 ensureTitle: function() {\r
89487 var me = this,\r
89488 title = me.getTitle();\r
89489 if (!title) {\r
89490 me.setTitle('');\r
89491 title = me.getTitle();\r
89492 }\r
89493 return title;\r
89494 },\r
89495 sortByWeight: function(item1, item2) {\r
89496 return (item1.weight || 0) - (item2.weight || 0);\r
89497 }\r
89498 }\r
89499});\r
89500\r
89501\r
89502Ext.define('Ext.panel.Title', {\r
89503 extend: Ext.Component,\r
89504 xtype: 'paneltitle',\r
89505 isPanelTitle: true,\r
89506
89507
89508
89509 _textAlign: 'left',\r
89510 _iconAlign: 'left',\r
89511 _text: '&#160;',\r
89512 cachedConfig: {\r
89513 \r
89514 textAlign: null,\r
89515 \r
89516 text: null,\r
89517 \r
89518 glyph: null,\r
89519 \r
89520 icon: null,\r
89521 \r
89522 iconAlign: null,\r
89523 \r
89524 iconCls: null\r
89525 },\r
89526 weight: -10,\r
89527 element: {\r
89528 unselectable: 'on',\r
89529 reference: 'element',\r
89530 cls: Ext.baseCSSPrefix + 'panel-title-align-left',\r
89531 children: [\r
89532 {\r
89533 reference: 'iconElement',\r
89534 style: 'display:none',\r
89535 cls: Ext.baseCSSPrefix + 'panel-title-icon ' + Ext.baseCSSPrefix + 'panel-title-icon-left'\r
89536 },\r
89537 {\r
89538 reference: 'textElement',\r
89539 cls: Ext.baseCSSPrefix + 'panel-title-text'\r
89540 }\r
89541 ]\r
89542 },\r
89543 _textAlignClasses: {\r
89544 left: Ext.baseCSSPrefix + 'panel-title-align-left',\r
89545 center: Ext.baseCSSPrefix + 'panel-title-align-center',\r
89546 right: Ext.baseCSSPrefix + 'panel-title-align-right'\r
89547 },\r
89548 _iconAlignClasses: {\r
89549 top: Ext.baseCSSPrefix + 'panel-title-icon-top',\r
89550 right: Ext.baseCSSPrefix + 'panel-title-icon-right',\r
89551 bottom: Ext.baseCSSPrefix + 'panel-title-icon-bottom',\r
89552 left: Ext.baseCSSPrefix + 'panel-title-icon-left'\r
89553 },\r
89554 baseCls: Ext.baseCSSPrefix + 'panel-title',\r
89555 _titleSuffix: '-title',\r
89556 _glyphCls: Ext.baseCSSPrefix + 'panel-title-glyph',\r
89557 _verticalCls: Ext.baseCSSPrefix + 'panel-title-vertical',\r
89558 applyText: function(text) {\r
89559 return text || '&#160;';\r
89560 },\r
89561 updateGlyph: function(glyph, oldGlyph) {\r
89562 glyph = glyph || 0;\r
89563 var me = this,\r
89564 glyphCls = me._glyphCls,\r
89565 iconEl = me.iconElement,\r
89566 fontFamily, glyphParts;\r
89567 me.glyph = glyph;\r
89568 me._syncIconVisibility();\r
89569 if (typeof glyph === 'string') {\r
89570 glyphParts = glyph.split('@');\r
89571 glyph = glyphParts[0];\r
89572 fontFamily = glyphParts[1] || Ext._glyphFontFamily;\r
89573 }\r
89574 if (!glyph) {\r
89575 iconEl.dom.innerHTML = '';\r
89576 iconEl.removeCls(glyphCls);\r
89577 } else {\r
89578 iconEl.dom.innerHTML = '&#' + glyph + ';';\r
89579 iconEl.addCls(glyphCls);\r
89580 }\r
89581 if (fontFamily) {\r
89582 iconEl.setStyle('font-family', fontFamily);\r
89583 }\r
89584 },\r
89585 updateIcon: function(icon, oldIcon) {\r
89586 var me = this,\r
89587 iconEl;\r
89588 me._syncIconVisibility();\r
89589 iconEl = me.iconElement;\r
89590 iconEl.setStyle('background-image', icon ? 'url(' + icon + ')' : '');\r
89591 },\r
89592 updateIconAlign: function(align, oldAlign) {\r
89593 var me = this,\r
89594 iconEl = me.iconElement,\r
89595 iconAlignClasses = me._iconAlignClasses,\r
89596 el = me.el;\r
89597 if (oldAlign) {\r
89598 iconEl.removeCls(iconAlignClasses[oldAlign]);\r
89599 }\r
89600 iconEl.addCls(iconAlignClasses[align]);\r
89601
89602
89603 if (align === 'top' || align === 'left') {\r
89604 el.insertFirst(iconEl);\r
89605 } else {\r
89606 el.appendChild(iconEl);\r
89607 }\r
89608 if (align === 'top' || align === 'bottom') {\r
89609 el.addCls(me._verticalCls);\r
89610 } else {\r
89611 el.removeCls(me._verticalCls);\r
89612 }\r
89613 },\r
89614 updateIconCls: function(cls, oldCls) {\r
89615 var iconEl = this.iconElement;\r
89616 this._syncIconVisibility();\r
89617 if (oldCls) {\r
89618 iconEl.removeCls(oldCls);\r
89619 }\r
89620 if (cls) {\r
89621 iconEl.addCls(cls);\r
89622 }\r
89623 },\r
89624 updateText: function(text) {\r
89625 this.textElement.setHtml(text);\r
89626 },\r
89627 updateTextAlign: function(align, oldAlign) {\r
89628 var me = this,\r
89629 textAlignClasses = me._textAlignClasses;\r
89630 if (oldAlign) {\r
89631 me.removeCls(textAlignClasses[oldAlign]);\r
89632 }\r
89633 me.addCls(textAlignClasses[align]);\r
89634 },\r
89635 privates: {\r
89636 _getVerticalAdjustDirection: function() {\r
89637
89638 return 'left';\r
89639 },\r
89640 _hasIcon: function() {\r
89641 return !!(this.getIcon() || this.getIconCls() || this.getGlyph());\r
89642 },\r
89643 _syncIconVisibility: function() {\r
89644 this.iconElement.setDisplayed(this._hasIcon());\r
89645 }\r
89646 }\r
89647});\r
89648\r
89649\r
89650Ext.define('Ext.panel.Tool', {\r
89651 extend: Ext.Component,\r
89652 xtype: [\r
89653 'paneltool',\r
89654 'tool'\r
89655 ],\r
89656
89657 \r
89658 isPanelTool: true,\r
89659 baseCls: Ext.baseCSSPrefix + 'tool',\r
89660 disabledCls: Ext.baseCSSPrefix + 'tool-disabled',\r
89661 toolPressedCls: Ext.baseCSSPrefix + 'tool-pressed',\r
89662 toolOverCls: Ext.baseCSSPrefix + 'tool-over',\r
89663 element: {\r
89664 reference: 'element',\r
89665 listeners: {\r
89666 click: 'onClick',\r
89667 mousedown: 'onMouseDown',\r
89668 mouseover: 'onMouseOver',\r
89669 mouseout: 'onMouseOut'\r
89670 },\r
89671 children: [\r
89672 {\r
89673 reference: 'toolElement'\r
89674 }\r
89675 ]\r
89676 },\r
89677 \r
89678 handler: null,\r
89679 \r
89680 scope: null,\r
89681 \r
89682 toolOwner: null,\r
89683 config: {\r
89684 \r
89685 iconCls: null,\r
89686 \r
89687 type: null\r
89688 },\r
89689 \r
89690 stopEvent: true,\r
89691
89692
89693
89694
89695
89696
89697
89698
89699 weight: 10,\r
89700 updateIconCls: function(iconCls, oldValue) {\r
89701 var toolEl = this.toolElement;\r
89702 toolEl.replaceCls(oldValue, iconCls);\r
89703 },\r
89704 updateType: function(type, oldType) {\r
89705 var baseCls = this.getBaseCls(),\r
89706 toolEl = this.toolElement;\r
89707 toolEl.replaceCls(oldType && (baseCls + '-' + oldType), type && (baseCls + '-' + type));\r
89708 },\r
89709 privates: {\r
89710
89711 _toolTypes: {\r
89712 close: 1,\r
89713 collapse: 1,\r
89714 down: 1,\r
89715 expand: 1,\r
89716 gear: 1,\r
89717 help: 1,\r
89718 left: 1,\r
89719 maximize: 1,\r
89720 minimize: 1,\r
89721 minus: 1,\r
89722
89723 next: 1,\r
89724 pin: 1,\r
89725 plus: 1,\r
89726 prev: 1,\r
89727 print: 1,\r
89728 refresh: 1,\r
89729
89730 restore: 1,\r
89731 right: 1,\r
89732 save: 1,\r
89733 search: 1,\r
89734 toggle: 1,\r
89735 unpin: 1,\r
89736 up: 1\r
89737 },\r
89738
89739 \r
89740 onClick: function(e, target) {\r
89741 var me = this,\r
89742 handler = me.handler || me.callback;\r
89743
89744 if (me.disabled) {\r
89745 return false;\r
89746 }\r
89747
89748 if (e.type !== 'keydown') {\r
89749 me.el.removeCls(me.toolPressedCls + ' ' + me.toolOverCls);\r
89750 }\r
89751 if (me.stopEvent !== false) {\r
89752 e.stopEvent();\r
89753 }\r
89754 if (handler) {\r
89755 Ext.callback(handler, me.scope, [\r
89756 me.toolOwner || me.parent,\r
89757 me,\r
89758 e\r
89759 ], 0, me);\r
89760 }\r
89761 \r
89762 me.fireEvent('click', me, e, me.toolOwner || me.ownerCt);\r
89763 return true;\r
89764 },\r
89765 \r
89766 onMouseDown: function(e) {\r
89767
89768
89769
89770 e.preventDefault();\r
89771 if (this.disabled) {\r
89772 return false;\r
89773 }\r
89774 this.el.addCls(this.toolPressedCls);\r
89775 },\r
89776 \r
89777 onMouseOver: function() {\r
89778 if (this.disabled) {\r
89779 return false;\r
89780 }\r
89781 this.el.addCls(this.toolOverCls);\r
89782 },\r
89783 \r
89784 onMouseOut: function() {\r
89785 this.el.removeCls(this.toolOverCls);\r
89786 }\r
89787 }\r
89788});\r
89789\r
89790\r
89791Ext.define('Ext.plugin.ListPaging', {\r
89792 extend: Ext.Component,\r
89793 alias: 'plugin.listpaging',\r
89794 config: {\r
89795 \r
89796 autoPaging: false,\r
89797 \r
89798 loadMoreText: 'Load More...',\r
89799 \r
89800 noMoreRecordsText: 'No More Records',\r
89801 \r
89802 loadTpl: [\r
89803 '<div class="{cssPrefix}loading-spinner" style="font-size: 180%; margin: 10px auto;">',\r
89804 '<span class="{cssPrefix}loading-top"></span>',\r
89805 '<span class="{cssPrefix}loading-right"></span>',\r
89806 '<span class="{cssPrefix}loading-bottom"></span>',\r
89807 '<span class="{cssPrefix}loading-left"></span>',\r
89808 '</div>',\r
89809 '<div class="{cssPrefix}list-paging-msg">{message}</div>'\r
89810 ].join(''),\r
89811 \r
89812 loadMoreCmp: {\r
89813 xtype: 'component',\r
89814 baseCls: Ext.baseCSSPrefix + 'list-paging',\r
89815 scrollDock: 'bottom',\r
89816 hidden: true\r
89817 },\r
89818 \r
89819 loadMoreCmpAdded: false,\r
89820 \r
89821 loadingCls: Ext.baseCSSPrefix + 'loading',\r
89822 \r
89823 list: null,\r
89824 \r
89825 scroller: null,\r
89826 \r
89827 loading: false\r
89828 },\r
89829 \r
89830 init: function(list) {\r
89831 var scroller = list.getScrollable(),\r
89832 store = list.getStore();\r
89833 this.setList(list);\r
89834 this.setScroller(scroller);\r
89835 this.bindStore(list.getStore());\r
89836 this.addLoadMoreCmp();\r
89837
89838 list.updateStore = Ext.Function.createInterceptor(list.updateStore, this.bindStore, this);\r
89839 if (this.getAutoPaging()) {\r
89840 scroller.on({\r
89841 scrollend: this.onScrollEnd,\r
89842 scope: this\r
89843 });\r
89844 }\r
89845 },\r
89846 \r
89847 bindStore: function(newStore, oldStore) {\r
89848 if (oldStore) {\r
89849 oldStore.un({\r
89850 beforeload: this.onStoreBeforeLoad,\r
89851 load: this.onStoreLoad,\r
89852 filter: this.onFilter,\r
89853 scope: this\r
89854 });\r
89855 }\r
89856 if (newStore) {\r
89857 newStore.on({\r
89858 beforeload: this.onStoreBeforeLoad,\r
89859 load: this.onStoreLoad,\r
89860 filter: this.onFilter,\r
89861 scope: this\r
89862 });\r
89863 }\r
89864 },\r
89865 \r
89866 disableDataViewMask: function() {\r
89867 var list = this.getList();\r
89868 this._listMask = list.getLoadingText();\r
89869 list.setLoadingText(null);\r
89870 },\r
89871 enableDataViewMask: function() {\r
89872 if (this._listMask) {\r
89873 var list = this.getList();\r
89874 list.setLoadingText(this._listMask);\r
89875 delete this._listMask;\r
89876 }\r
89877 },\r
89878 \r
89879 applyLoadTpl: function(config) {\r
89880 return (Ext.isObject(config) && config.isTemplate) ? config : new Ext.XTemplate(config);\r
89881 },\r
89882 \r
89883 applyLoadMoreCmp: function(config) {\r
89884 config = Ext.merge(config, {\r
89885 html: this.getLoadTpl().apply({\r
89886 cssPrefix: Ext.baseCSSPrefix,\r
89887 message: this.getLoadMoreText()\r
89888 }),\r
89889 scrollDock: 'bottom',\r
89890 listeners: {\r
89891 tap: {\r
89892 fn: this.loadNextPage,\r
89893 scope: this,\r
89894 element: 'element'\r
89895 }\r
89896 }\r
89897 });\r
89898 return Ext.factory(config, Ext.Component, this.getLoadMoreCmp());\r
89899 },\r
89900 \r
89901 onScrollEnd: function(scroller, x, y) {\r
89902 var list = this.getList();\r
89903 if (!this.getLoading() && y >= scroller.getMaxUserPosition().y) {\r
89904 this.currentScrollToTopOnRefresh = list.getScrollToTopOnRefresh();\r
89905 list.setScrollToTopOnRefresh(false);\r
89906 this.loadNextPage();\r
89907 }\r
89908 },\r
89909 \r
89910 updateLoading: function(isLoading) {\r
89911 var loadMoreCmp = this.getLoadMoreCmp(),\r
89912 loadMoreCls = this.getLoadingCls();\r
89913 if (isLoading) {\r
89914 loadMoreCmp.addCls(loadMoreCls);\r
89915 } else {\r
89916 loadMoreCmp.removeCls(loadMoreCls);\r
89917 }\r
89918 },\r
89919 \r
89920 onStoreBeforeLoad: function(store) {\r
89921 if (store.getCount() === 0) {\r
89922 this.getLoadMoreCmp().hide();\r
89923 }\r
89924 },\r
89925 \r
89926 onStoreLoad: function(store) {\r
89927 var loadCmp = this.getLoadMoreCmp(),\r
89928 template = this.getLoadTpl(),\r
89929 message = this.storeFullyLoaded() ? this.getNoMoreRecordsText() : this.getLoadMoreText();\r
89930 if (store.getCount()) {\r
89931 loadCmp.show();\r
89932 }\r
89933 this.setLoading(false);\r
89934
89935 loadCmp.setHtml(template.apply({\r
89936 cssPrefix: Ext.baseCSSPrefix,\r
89937 message: message\r
89938 }));\r
89939 if (this.currentScrollToTopOnRefresh !== undefined) {\r
89940 this.getList().setScrollToTopOnRefresh(this.currentScrollToTopOnRefresh);\r
89941 delete this.currentScrollToTopOnRefresh;\r
89942 }\r
89943 this.enableDataViewMask();\r
89944 },\r
89945 onFilter: function(store) {\r
89946 if (store.getCount() === 0) {\r
89947 this.getLoadMoreCmp().hide();\r
89948 } else {\r
89949 this.getLoadMoreCmp().show();\r
89950 }\r
89951 },\r
89952 \r
89953 addLoadMoreCmp: function() {\r
89954 var list = this.getList(),\r
89955 cmp = this.getLoadMoreCmp();\r
89956 if (!this.getLoadMoreCmpAdded()) {\r
89957 list.add(cmp);\r
89958 \r
89959 list.fireEvent('loadmorecmpadded', this, list);\r
89960 this.setLoadMoreCmpAdded(true);\r
89961 }\r
89962 return cmp;\r
89963 },\r
89964 \r
89965 storeFullyLoaded: function() {\r
89966 var store = this.getList().getStore(),\r
89967 total = store.getTotalCount();\r
89968 return total !== null ? store.getTotalCount() <= (store.currentPage * store.getPageSize()) : false;\r
89969 },\r
89970 \r
89971 loadNextPage: function() {\r
89972 var me = this;\r
89973 if (!me.storeFullyLoaded()) {\r
89974 me.disableDataViewMask();\r
89975 me.setLoading(true);\r
89976 me.getList().getStore().nextPage({\r
89977 addRecords: true\r
89978 });\r
89979 }\r
89980 }\r
89981});\r
89982\r
89983\r
89984Ext.define('Ext.plugin.PullRefresh', {\r
89985 extend: Ext.Component,\r
89986 alias: 'plugin.pullrefresh',\r
89987 config: {\r
89988 width: '100%',\r
89989 \r
89990 list: null,\r
89991 \r
89992 pullText: 'Pull down to refresh...',\r
89993 \r
89994 releaseText: 'Release to refresh...',\r
89995 \r
89996 loadingText: 'Loading...',\r
89997 \r
89998 loadedText: 'Loaded.',\r
89999 \r
90000 lastUpdatedText: 'Last Updated:&nbsp;',\r
90001 \r
90002 scrollerAutoRefresh: false,\r
90003 \r
90004 autoSnapBack: true,\r
90005 \r
90006 snappingAnimationDuration: 300,\r
90007 \r
90008 lastUpdatedDateFormat: 'm/d/Y h:iA',\r
90009 \r
90010 overpullSnapBackDuration: 300,\r
90011 \r
90012 pullTpl: [\r
90013 '<div class="' + Ext.baseCSSPrefix + 'list-pullrefresh-arrow"></div>',\r
90014 '<div class="' + Ext.baseCSSPrefix + 'loading-spinner">',\r
90015 '<span class="' + Ext.baseCSSPrefix + 'loading-top"></span>',\r
90016 '<span class="' + Ext.baseCSSPrefix + 'loading-right"></span>',\r
90017 '<span class="' + Ext.baseCSSPrefix + 'loading-bottom"></span>',\r
90018 '<span class="' + Ext.baseCSSPrefix + 'loading-left"></span>',\r
90019 '</div>',\r
90020 '<div class="' + Ext.baseCSSPrefix + 'list-pullrefresh-wrap">',\r
90021 '<h3 class="' + Ext.baseCSSPrefix + 'list-pullrefresh-message">{message}</h3>',\r
90022 '<div class="' + Ext.baseCSSPrefix + 'list-pullrefresh-updated">{updated}</div>',\r
90023 '</div>'\r
90024 ].join(''),\r
90025 translatable: true\r
90026 },\r
90027 \r
90028 $state: 'pull',\r
90029 refreshCls: Ext.baseCSSPrefix + 'list-pullrefresh',\r
90030 \r
90031 getState: function() {\r
90032 return this.$state;\r
90033 },\r
90034 \r
90035 setState: function(value) {\r
90036 this.$state = value;\r
90037 this.updateView();\r
90038 },\r
90039 \r
90040 $isSnappingBack: false,\r
90041 \r
90042 getIsSnappingBack: function() {\r
90043 return this.$isSnappingBack;\r
90044 },\r
90045 \r
90046 setIsSnappingBack: function(value) {\r
90047 this.$isSnappingBack = value;\r
90048 },\r
90049 \r
90050 init: function(list) {\r
90051 this.setList(list);\r
90052 this.initScrollable();\r
90053 },\r
90054 getElementConfig: function() {\r
90055 return {\r
90056 reference: 'element',\r
90057 classList: [\r
90058 'x-unsized'\r
90059 ],\r
90060 children: [\r
90061 {\r
90062 reference: 'innerElement',\r
90063 className: this.refreshCls\r
90064 }\r
90065 ]\r
90066 };\r
90067 },\r
90068 \r
90069 initScrollable: function() {\r
90070 var me = this,\r
90071 list = me.getList(),\r
90072 scroller = list.getScrollable();\r
90073 if (!scroller || !scroller.isTouchScroller) {\r
90074 return;\r
90075 }\r
90076 scroller.setAutoRefresh(me.getScrollerAutoRefresh());\r
90077 me.lastUpdated = new Date();\r
90078 list.insert(0, me);\r
90079 scroller.on({\r
90080 scroll: me.onScrollChange,\r
90081 scope: me\r
90082 });\r
90083 me.updateView();\r
90084 },\r
90085 \r
90086 applyPullTpl: function(config) {\r
90087 if (config instanceof Ext.XTemplate) {\r
90088 return config;\r
90089 } else {\r
90090 return new Ext.XTemplate(config);\r
90091 }\r
90092 },\r
90093 \r
90094 updateList: function(newList, oldList) {\r
90095 var me = this;\r
90096 if (newList) {\r
90097 newList.on({\r
90098 order: 'after',\r
90099 scrollablechange: me.initScrollable,\r
90100 scope: me\r
90101 });\r
90102 }\r
90103 if (oldList) {\r
90104 oldList.un({\r
90105 order: 'after',\r
90106 scrollablechange: me.initScrollable,\r
90107 scope: me\r
90108 });\r
90109 }\r
90110 },\r
90111 \r
90112 getPullHeight: function() {\r
90113 return this.innerElement.getHeight();\r
90114 },\r
90115 \r
90116 fetchLatest: function() {\r
90117 this.getList().getStore().fetch({\r
90118 page: 1,\r
90119 start: 0,\r
90120 callback: this.onLatestFetched,\r
90121 scope: this\r
90122 });\r
90123 },\r
90124 \r
90125 onLatestFetched: function(newRecords) {\r
90126 var me = this,\r
90127 store = me.getList().getStore(),\r
90128 oldRecords = store.getData(),\r
90129 length = newRecords.length,\r
90130 toInsert = [],\r
90131 newRecord, oldRecord, i;\r
90132 for (i = 0; i < length; i++) {\r
90133 newRecord = newRecords[i];\r
90134 oldRecord = oldRecords.getByKey(newRecord.getId());\r
90135 if (oldRecord) {\r
90136 oldRecord.set(newRecord.getData());\r
90137 } else {\r
90138 toInsert.push(newRecord);\r
90139 }\r
90140 oldRecord = undefined;\r
90141 }\r
90142 store.insert(0, toInsert);\r
90143 me.setState('loaded');\r
90144 me.fireEvent('latestfetched', me, toInsert);\r
90145 if (me.getAutoSnapBack()) {\r
90146 me.snapBack();\r
90147 }\r
90148 },\r
90149 \r
90150 snapBack: function(force) {\r
90151 var me = this,\r
90152 list, scroller;\r
90153 if (this.getState() !== 'loaded' && force !== true) {\r
90154 return;\r
90155 }\r
90156 list = me.getList();\r
90157 scroller = list.getScrollable();\r
90158 me.setIsSnappingBack(true);\r
90159 scroller.doScrollTo(null, 0, {\r
90160 callback: Ext.bind(me.onSnapBackEnd, me),\r
90161 duration: me.getSnappingAnimationDuration()\r
90162 });\r
90163 },\r
90164 \r
90165 onSnapBackEnd: function() {\r
90166 var list = this.getList(),\r
90167 scroller = list.getScrollable();\r
90168 scroller.setMinUserPosition({\r
90169 x: 0,\r
90170 y: 0\r
90171 });\r
90172 this.setState('pull');\r
90173 this.setIsSnappingBack(false);\r
90174 },\r
90175 \r
90176 onScrollChange: function(scroller, x, y) {\r
90177 if (y > 0) {\r
90178 return;\r
90179 }\r
90180 var me = this,\r
90181 pullHeight = me.getPullHeight(),\r
90182 isSnappingBack = me.getIsSnappingBack(),\r
90183 state = me.getState();\r
90184 if (state === 'loaded' && !isSnappingBack) {\r
90185 me.snapBack();\r
90186 }\r
90187 if (state !== 'loading' && state !== 'loaded') {\r
90188 if (-y >= pullHeight + 10) {\r
90189 me.setState('release');\r
90190 scroller.getElement().onBefore({\r
90191 dragend: 'onScrollerDragEnd',\r
90192 single: true,\r
90193 scope: me\r
90194 });\r
90195 } else if (state === "release" && (-y < pullHeight + 10)) {\r
90196 me.setState('pull');\r
90197 scroller.getElement().unBefore({\r
90198 dragend: 'onScrollerDragEnd',\r
90199 single: true,\r
90200 scope: me\r
90201 });\r
90202 }\r
90203 }\r
90204 me.getTranslatable().translate(0, -y);\r
90205 },\r
90206 \r
90207 onScrollerDragEnd: function() {\r
90208 var me = this,\r
90209 pullHeight, list, scroller;\r
90210 if (me.getState() === 'loading') {\r
90211 return;\r
90212 }\r
90213 list = me.getList();\r
90214 scroller = list.getScrollable();\r
90215 pullHeight = me.getPullHeight();\r
90216 me.setState('loading');\r
90217 scroller.setMinUserPosition({\r
90218 x: 0,\r
90219 y: -pullHeight\r
90220 });\r
90221 scroller.doScrollTo(0, -pullHeight, {\r
90222 callback: Ext.bind(me.fetchLatest, me),\r
90223 easingY: {\r
90224 duration: me.getOverpullSnapBackDuration()\r
90225 }\r
90226 }, true);\r
90227 },\r
90228 \r
90229 updateView: function() {\r
90230 var me = this,\r
90231 innerElement = me.innerElement,\r
90232 state = me.getState(),\r
90233 lastUpdatedText = me.getLastUpdatedText() + Ext.util.Format.date(me.lastUpdated, me.getLastUpdatedDateFormat()),\r
90234 templateConfig = {\r
90235 state: state,\r
90236 updated: lastUpdatedText\r
90237 },\r
90238 stateFn = state.charAt(0).toUpperCase() + state.slice(1).toLowerCase(),\r
90239 fn = 'get' + stateFn + 'Text';\r
90240 if (me[fn] && Ext.isFunction(me[fn])) {\r
90241 templateConfig.message = me[fn].call(me);\r
90242 }\r
90243 innerElement.removeCls([\r
90244 'loaded',\r
90245 'loading',\r
90246 'release',\r
90247 'pull'\r
90248 ], me.refreshCls);\r
90249 innerElement.addCls(state, me.refreshCls);\r
90250 me.getPullTpl().overwrite(innerElement, templateConfig);\r
90251 }\r
90252});\r
90253\r
90254\r
90255Ext.define('Ext.plugin.Responsive', {\r
90256 extend: Ext.mixin.Responsive,\r
90257 alias: 'plugin.responsive',\r
90258 pluginId: 'responsive',\r
90259 isPlugin: true,\r
90260 constructor: function(config) {\r
90261
90262 if (!config || !config.cmp) {\r
90263 Ext.raise('Responsive plugin must be constructed by Component');\r
90264 }\r
90265
90266 var me = this,\r
90267 cmp = config.cmp,\r
90268 cmpConfig = cmp.initialConfig,\r
90269 c = Ext.apply({\r
90270 responsiveConfig: cmpConfig.responsiveConfig,\r
90271 responsiveFormulas: cmpConfig.responsiveFormulas\r
90272 }, config),\r
90273 transformed;\r
90274 delete c.cmp;\r
90275 delete c.type;\r
90276 me.cmp = cmp;\r
90277 me.initConfig(c);\r
90278 transformed = me.transformed;\r
90279
90280 if (transformed) {\r
90281 me.transformed = null;\r
90282 if (cmp.initConfig.$nullFn) {\r
90283
90284
90285 cmp.setConfig(transformed);\r
90286 } else {\r
90287 cmp.initialConfig = Ext.merge(Ext.merge({}, cmpConfig), transformed);\r
90288 }\r
90289 }\r
90290 },\r
90291 init: Ext.emptyFn,\r
90292 privates: {\r
90293 transformInstanceConfig: function(config) {\r
90294
90295
90296 var transformed = this.callParent([\r
90297 config\r
90298 ]),\r
90299 ret;\r
90300 this.transformed = transformed;\r
90301 ret = Ext.apply({}, config);\r
90302 delete ret.responsiveConfig;\r
90303
90304 delete ret.responsiveFormulas;\r
90305 return ret;\r
90306 },\r
90307 updateResponsiveState: function() {\r
90308 var config = this.getResponsiveState();\r
90309
90310 this.cmp.setConfig(config);\r
90311 }\r
90312 }\r
90313});\r
90314\r
90315\r
90316Ext.define('Ext.plugin.field.PlaceHolderLabel', {\r
90317 extend: Ext.AbstractPlugin,\r
90318 alias: 'plugin.placeholderlabel',\r
90319 config: {\r
90320 \r
90321 field: null,\r
90322 \r
90323 labelVisible: false,\r
90324 \r
90325 cls: Ext.baseCSSPrefix + 'placeholderlabel',\r
90326 \r
90327 showCls: Ext.baseCSSPrefix + 'show-label'\r
90328 },\r
90329 constructor: function(config) {\r
90330 this.initConfig(config);\r
90331 this.callParent([\r
90332 config\r
90333 ]);\r
90334 },\r
90335 init: function(field) {\r
90336 this.setField(field);\r
90337
90338 if (field.getValue()) {\r
90339 this.setLabelVisible(true);\r
90340 }\r
90341 },\r
90342 \r
90343 maybeShowLabel: function(field) {\r
90344 this.setLabelVisible(!!field.getValue());\r
90345 },\r
90346 \r
90347 getFieldListeners: function() {\r
90348 return {\r
90349 scope: this,\r
90350 keyup: this.maybeShowLabel,\r
90351 clearicontap: this.maybeShowLabel\r
90352 };\r
90353 },\r
90354 updateField: function(newField, oldField) {\r
90355 var listeners = this.getFieldListeners(),\r
90356 cls = this.getCls(),\r
90357 label, config;\r
90358 if (oldField) {\r
90359
90360 oldField.un(listeners);\r
90361
90362 oldField.removeCls(cls);\r
90363 }\r
90364 if (newField) {\r
90365 label = newField.getLabel();\r
90366 config = {\r
90367 labelAlign: 'top'\r
90368 };\r
90369
90370 if (!label) {\r
90371 config.label = newField.getPlaceHolder();\r
90372 }\r
90373
90374 newField.on(listeners);\r
90375
90376 newField.addCls(cls);\r
90377
90378 newField.setConfig(config);\r
90379 }\r
90380 },\r
90381 updateLabelVisible: function(show) {\r
90382 var field = this.getField();\r
90383 if (field) {\r
90384 field.toggleCls(this.getShowCls(), show);\r
90385 }\r
90386 }\r
90387});\r
90388\r
90389\r
90390Ext.define('Ext.tab.Tab', {\r
90391 extend: Ext.Button,\r
90392 xtype: 'tab',\r
90393 alternateClassName: 'Ext.Tab',\r
90394 \r
90395 isTab: true,\r
90396 config: {\r
90397 \r
90398 baseCls: Ext.baseCSSPrefix + 'tab',\r
90399 \r
90400 pressedCls: Ext.baseCSSPrefix + 'tab-pressed',\r
90401 \r
90402 activeCls: Ext.baseCSSPrefix + 'tab-active',\r
90403 \r
90404 active: false,\r
90405 \r
90406 title: '&nbsp;'\r
90407 },\r
90408 updateIconCls: function(newCls, oldCls) {\r
90409 this.callParent([\r
90410 newCls,\r
90411 oldCls\r
90412 ]);\r
90413 if (oldCls) {\r
90414 this.removeCls('x-tab-icon');\r
90415 }\r
90416 if (newCls) {\r
90417 this.addCls('x-tab-icon');\r
90418 }\r
90419 },\r
90420 \r
90421 \r
90422 updateTitle: function(title) {\r
90423 this.setText(title);\r
90424 },\r
90425 updateActive: function(active, oldActive) {\r
90426 var activeCls = this.getActiveCls();\r
90427 if (active && !oldActive) {\r
90428 this.element.addCls(activeCls);\r
90429 this.fireEvent('activate', this);\r
90430 } else if (oldActive) {\r
90431 this.element.removeCls(activeCls);\r
90432 this.fireEvent('deactivate', this);\r
90433 }\r
90434 }\r
90435}, function() {\r
90436 this.override({\r
90437 activate: function() {\r
90438 this.setActive(true);\r
90439 },\r
90440 deactivate: function() {\r
90441 this.setActive(false);\r
90442 }\r
90443 });\r
90444});\r
90445\r
90446\r
90447Ext.define('Ext.tab.Bar', {\r
90448 extend: Ext.Toolbar,\r
90449 alternateClassName: 'Ext.TabBar',\r
90450 xtype: 'tabbar',\r
90451 config: {\r
90452 \r
90453 baseCls: Ext.baseCSSPrefix + 'tabbar',\r
90454 \r
90455 defaultType: 'tab',\r
90456 \r
90457 defaultTabUI: null,\r
90458 \r
90459 layout: {\r
90460 type: 'hbox',\r
90461 align: 'middle'\r
90462 }\r
90463 },\r
90464 eventedConfig: {\r
90465 \r
90466 activeTab: null\r
90467 },\r
90468 \r
90469 initialize: function() {\r
90470 var me = this;\r
90471 me.callParent();\r
90472 me.on({\r
90473 tap: 'onTabTap',\r
90474 delegate: '> tab',\r
90475 scope: me\r
90476 });\r
90477 },\r
90478 \r
90479 onTabTap: function(tab) {\r
90480 this.setActiveTab(tab);\r
90481 },\r
90482 \r
90483 applyActiveTab: function(newActiveTab, oldActiveTab) {\r
90484 if (!newActiveTab && newActiveTab !== 0) {\r
90485 return;\r
90486 }\r
90487 var newTabInstance = this.parseActiveTab(newActiveTab);\r
90488 if (!newTabInstance) {\r
90489
90490 if (oldActiveTab) {\r
90491 Ext.Logger.warn('Trying to set a non-existent activeTab');\r
90492 }\r
90493
90494 return;\r
90495 }\r
90496 return newTabInstance;\r
90497 },\r
90498 \r
90499 updateDocked: function(newDocked) {\r
90500 var layout = this.getLayout(),\r
90501 initialConfig = this.getInitialConfig(),\r
90502 pack;\r
90503 if (!initialConfig.layout || !initialConfig.layout.pack) {\r
90504 pack = (newDocked == 'bottom') ? 'center' : 'left';\r
90505
90506 if (layout.isLayout) {\r
90507 layout.setPack(pack);\r
90508 } else {\r
90509 layout.pack = (layout && layout.pack) ? layout.pack : pack;\r
90510 }\r
90511 }\r
90512 this.callParent(arguments);\r
90513 },\r
90514 \r
90515 updateActiveTab: function(newTab, oldTab) {\r
90516 if (newTab) {\r
90517 newTab.setActive(true);\r
90518 }\r
90519
90520 if (oldTab && oldTab.parent) {\r
90521 oldTab.setActive(false);\r
90522 }\r
90523 },\r
90524 \r
90525 parseActiveTab: function(tab) {\r
90526
90527 if (typeof tab == 'number') {\r
90528 return this.getItems().items[tab];\r
90529 } else if (typeof tab == 'string') {\r
90530 tab = Ext.getCmp(tab);\r
90531 }\r
90532 return tab;\r
90533 },\r
90534 onItemAdd: function(item, index) {\r
90535 var defaultTabUI = this.getDefaultTabUI();\r
90536 if (defaultTabUI && item.isTab && (item.getUi() == null)) {\r
90537 item.setUi(defaultTabUI);\r
90538 }\r
90539 this.callParent([\r
90540 item,\r
90541 index\r
90542 ]);\r
90543 }\r
90544});\r
90545\r
90546\r
90547Ext.define('Ext.tab.Panel', {\r
90548 extend: Ext.Container,\r
90549 xtype: 'tabpanel',\r
90550 alternateClassName: 'Ext.TabPanel',\r
90551 config: {\r
90552 \r
90553 tabBar: true,\r
90554 \r
90555 tabBarPosition: 'top',\r
90556 \r
90557 layout: {\r
90558 type: 'card',\r
90559 animation: {\r
90560 type: 'slide',\r
90561 direction: 'left'\r
90562 }\r
90563 },\r
90564 \r
90565 cls: Ext.baseCSSPrefix + 'tabpanel'\r
90566 },\r
90567 \r
90568 \r
90569 initialize: function() {\r
90570 this.callParent();\r
90571 this.on({\r
90572 beforeactivetabchange: 'doTabChange',\r
90573 delegate: '> tabbar',\r
90574 scope: this\r
90575 });\r
90576 this.on({\r
90577 disabledchange: 'onItemDisabledChange',\r
90578 delegate: '> component',\r
90579 scope: this\r
90580 });\r
90581 },\r
90582 \r
90583 applyScrollable: function() {\r
90584 return false;\r
90585 },\r
90586 \r
90587 updateUi: function(newUi, oldUi) {\r
90588 this.callParent(arguments);\r
90589 if (this.initialized) {\r
90590 this.getTabBar().setUi(newUi);\r
90591 }\r
90592 },\r
90593 \r
90594 updateActiveItem: function(newActiveItem, oldActiveItem) {\r
90595 if (newActiveItem) {\r
90596 var items = this.getInnerItems(),\r
90597 oldIndex = items.indexOf(oldActiveItem),\r
90598 newIndex = items.indexOf(newActiveItem),\r
90599 reverse = oldIndex > newIndex,\r
90600 animation = this.getLayout().getAnimation(),\r
90601 tabBar = this.getTabBar(),\r
90602 oldTab = tabBar.parseActiveTab(oldIndex),\r
90603 newTab = tabBar.parseActiveTab(newIndex);\r
90604 if (animation && animation.setReverse) {\r
90605 animation.setReverse(reverse);\r
90606 }\r
90607 this.callParent(arguments);\r
90608 if (newIndex != -1) {\r
90609 this.forcedChange = true;\r
90610 tabBar.setActiveTab(newIndex);\r
90611 this.forcedChange = false;\r
90612 if (oldTab) {\r
90613 oldTab.setActive(false);\r
90614 }\r
90615 if (newTab) {\r
90616 newTab.setActive(true);\r
90617 }\r
90618 }\r
90619 }\r
90620 },\r
90621 \r
90622 doTabChange: function(tabBar, newTab) {\r
90623 var oldActiveItem = this.getActiveItem(),\r
90624 newActiveItem;\r
90625 this.setActiveItem(tabBar.indexOf(newTab));\r
90626 newActiveItem = this.getActiveItem();\r
90627 return this.forcedChange || oldActiveItem !== newActiveItem;\r
90628 },\r
90629 \r
90630 applyTabBar: function(config) {\r
90631 if (config === true) {\r
90632 config = {};\r
90633 }\r
90634 if (config) {\r
90635 Ext.applyIf(config, {\r
90636 ui: this.getUi(),\r
90637 docked: this.getTabBarPosition()\r
90638 });\r
90639 }\r
90640 return Ext.factory(config, Ext.tab.Bar, this.getTabBar());\r
90641 },\r
90642 \r
90643 updateTabBar: function(newTabBar) {\r
90644 if (newTabBar) {\r
90645 this.add(newTabBar);\r
90646 this.setTabBarPosition(newTabBar.getDocked());\r
90647 }\r
90648 },\r
90649 \r
90650 updateTabBarPosition: function(position) {\r
90651 var tabBar = this.getTabBar();\r
90652 if (tabBar) {\r
90653 tabBar.setDocked(position);\r
90654 }\r
90655 },\r
90656 onItemAdd: function(card) {\r
90657 var me = this;\r
90658 if (!card.isInnerItem()) {\r
90659 return me.callParent(arguments);\r
90660 }\r
90661 var tabBar = me.getTabBar(),\r
90662 initialConfig = card.getInitialConfig(),\r
90663 tabConfig = initialConfig.tab || {},\r
90664 tabTitle = (card.getTitle) ? card.getTitle() : initialConfig.title,\r
90665 tabIconCls = (card.getIconCls) ? card.getIconCls() : initialConfig.iconCls,\r
90666 tabHidden = (card.getHidden) ? card.getHidden() : initialConfig.hidden,\r
90667 tabDisabled = (card.getDisabled) ? card.getDisabled() : initialConfig.disabled,\r
90668 tabBadgeText = (card.getBadgeText) ? card.getBadgeText() : initialConfig.badgeText,\r
90669 innerItems = me.getInnerItems(),\r
90670 index = innerItems.indexOf(card),\r
90671 tabs = tabBar.getItems(),\r
90672 activeTab = tabBar.getActiveTab(),\r
90673 currentTabInstance = (tabs.length >= innerItems.length) && tabs.getAt(index),\r
90674 header = card.isPanel && card.getHeader(),\r
90675 tabInstance;\r
90676 if (tabTitle && !tabConfig.title) {\r
90677 tabConfig.title = tabTitle;\r
90678 }\r
90679 if (tabIconCls && !tabConfig.iconCls) {\r
90680 tabConfig.iconCls = tabIconCls;\r
90681 }\r
90682 if (tabHidden && !tabConfig.hidden) {\r
90683 tabConfig.hidden = tabHidden;\r
90684 }\r
90685 if (tabDisabled && !tabConfig.disabled) {\r
90686 tabConfig.disabled = tabDisabled;\r
90687 }\r
90688 if (tabBadgeText && !tabConfig.badgeText) {\r
90689 tabConfig.badgeText = tabBadgeText;\r
90690 }\r
90691
90692 if (!currentTabInstance && !tabConfig.title && !tabConfig.iconCls) {\r
90693 if (!tabConfig.title && !tabConfig.iconCls) {\r
90694 Ext.Logger.error('Adding a card to a tab container without specifying any tab configuration');\r
90695 }\r
90696 }\r
90697
90698 tabInstance = Ext.factory(tabConfig, Ext.tab.Tab, currentTabInstance);\r
90699 if (!currentTabInstance) {\r
90700 tabBar.insert(index, tabInstance);\r
90701 }\r
90702 card.tab = tabInstance;\r
90703 if (header) {\r
90704 header.setHidden(true);\r
90705 }\r
90706 me.callParent(arguments);\r
90707 if (!activeTab && activeTab !== 0) {\r
90708 tabBar.setActiveTab(tabBar.getActiveItem());\r
90709 }\r
90710 },\r
90711 \r
90712 onItemDisabledChange: function(item, newDisabled) {\r
90713 if (item && item.tab) {\r
90714 item.tab.setDisabled(newDisabled);\r
90715 }\r
90716 },\r
90717
90718 onItemRemove: function(item, index) {\r
90719 this.getTabBar().remove(item.tab, this.getAutoDestroy());\r
90720 this.callParent(arguments);\r
90721 }\r
90722});\r
90723\r
90724Ext.define('Ext.table.Cell', {\r
90725 extend: Ext.Container,\r
90726 xtype: 'tablecell',\r
90727 config: {\r
90728 baseCls: 'x-table-cell'\r
90729 },\r
90730 getElementConfig: function() {\r
90731 var config = this.callParent();\r
90732 config.children.length = 0;\r
90733 return config;\r
90734 }\r
90735});\r
90736\r
90737Ext.define('Ext.table.Row', {\r
90738 extend: Ext.table.Cell,\r
90739 xtype: 'tablerow',\r
90740 config: {\r
90741 baseCls: 'x-table-row',\r
90742 defaultType: 'tablecell'\r
90743 }\r
90744});\r
90745\r
90746Ext.define('Ext.table.Table', {\r
90747 extend: Ext.Container,\r
90748 xtype: 'table',\r
90749 config: {\r
90750 baseCls: 'x-table',\r
90751 defaultType: 'tablerow'\r
90752 },\r
90753 cachedConfig: {\r
90754 fixedLayout: false\r
90755 },\r
90756 fixedLayoutCls: 'x-table-fixed',\r
90757 updateFixedLayout: function(fixedLayout) {\r
90758 this.innerElement[fixedLayout ? 'addCls' : 'removeCls'](this.fixedLayoutCls);\r
90759 }\r
90760});\r
90761\r
90762Ext.define('Ext.tip.ToolTip', {});\r
90763\r
90764\r
90765Ext.define('Ext.util.Audio', {\r
90766 singleton: true,\r
90767 ctx: null,\r
90768 beep: function(callback) {\r
90769 this.oscillate(200, 1, callback);\r
90770 },\r
90771 oscillate: function(duration, type, callback) {\r
90772 if (!this.ctx) {\r
90773 this.ctx = new (window.audioContext || window.webkitAudioContext)();\r
90774 }\r
90775 if (!this.ctx) {\r
90776 console.log("BEEP");\r
90777 return;\r
90778 }\r
90779 type = (type % 5) || 0;\r
90780 try {\r
90781 var osc = this.ctx.createOscillator();\r
90782 osc.type = type;\r
90783 osc.connect(this.ctx.destination);\r
90784 osc.noteOn(0);\r
90785 Ext.defer(function() {\r
90786 osc.noteOff(0);\r
90787 if (callback) {\r
90788 callback();\r
90789 }\r
90790 \r
90791 }, duration);\r
90792 } catch (e) {\r
90793 throw new Error("[Ext.util.Audio.oscillate] Error with Oscillator playback");\r
90794 }\r
90795 }\r
90796});\r
90797\r
90798\r
90799Ext.define('Ext.util.BufferedCollection', {\r
90800 extend: Ext.util.Collection,\r
90801 mixins: [\r
90802 Ext.mixin.Observable\r
90803 ],\r
90804 config: {\r
90805 totalCount: 0,\r
90806 autoSort: false,\r
90807 autoFilter: false,\r
90808 pageSize: 0\r
90809 },\r
90810 updateTotalCount: function(totalCount) {\r
90811 this.length = totalCount;\r
90812 this.all = this.items = Array.apply(null, new Array(totalCount));\r
90813 },\r
90814 addPage: function(page, records) {\r
90815 var pageSize = this.getPageSize(),\r
90816 start = (page - 1) * pageSize,\r
90817 limit = pageSize;\r
90818 this.all.splice.apply(this.all, [\r
90819 start,\r
90820 limit\r
90821 ].concat(records));\r
90822 this.fireEvent('pageadded', page, records, this.items);\r
90823 },\r
90824 hasRange: function(start, end) {\r
90825 var items = this.items,\r
90826 i;\r
90827 for (i = start; i <= end; i++) {\r
90828 if (!items[i]) {\r
90829 return false;\r
90830 }\r
90831 }\r
90832 return true;\r
90833 }\r
90834});\r
90835\r
90836\r
90837Ext.define('Ext.util.Droppable', {\r
90838 mixins: {\r
90839 observable: Ext.mixin.Observable\r
90840 },\r
90841 config: {\r
90842 \r
90843 baseCls: Ext.baseCSSPrefix + 'droppable'\r
90844 },\r
90845 \r
90846 activeCls: Ext.baseCSSPrefix + 'drop-active',\r
90847 \r
90848 invalidCls: Ext.baseCSSPrefix + 'drop-invalid',\r
90849 \r
90850 hoverCls: Ext.baseCSSPrefix + 'drop-hover',\r
90851 \r
90852 validDropMode: 'intersect',\r
90853 \r
90854 disabled: false,\r
90855 \r
90856 group: 'base',\r
90857
90858 tolerance: null,\r
90859 \r
90860 monitoring: false,\r
90861 \r
90862 constructor: function(el, config) {\r
90863 var me = this;\r
90864 config = config || {};\r
90865 Ext.apply(me, config);\r
90866 \r
90867 \r
90868 \r
90869 \r
90870 \r
90871 me.el = Ext.get(el);\r
90872 me.callParent();\r
90873 me.mixins.observable.constructor.call(me);\r
90874 if (!me.disabled) {\r
90875 me.enable();\r
90876 }\r
90877 me.el.addCls(me.baseCls);\r
90878 },\r
90879 \r
90880 onDragStart: function(draggable, e) {\r
90881 if (draggable.group === this.group) {\r
90882 this.monitoring = true;\r
90883 this.el.addCls(this.activeCls);\r
90884 this.region = this.el.getBox(true);\r
90885 draggable.on({\r
90886 drag: this.onDrag,\r
90887 beforedragend: this.onBeforeDragEnd,\r
90888 dragend: this.onDragEnd,\r
90889 scope: this\r
90890 });\r
90891 if (this.isDragOver(draggable)) {\r
90892 this.setCanDrop(true, draggable, e);\r
90893 }\r
90894 this.fireEvent('dropactivate', this, draggable, e);\r
90895 } else {\r
90896 draggable.on({\r
90897 dragend: function() {\r
90898 this.el.removeCls(this.invalidCls);\r
90899 },\r
90900 scope: this,\r
90901 single: true\r
90902 });\r
90903 this.el.addCls(this.invalidCls);\r
90904 }\r
90905 },\r
90906 \r
90907 isDragOver: function(draggable, region) {\r
90908 return this.region[this.validDropMode](draggable.region);\r
90909 },\r
90910 \r
90911 onDrag: function(draggable, e) {\r
90912 this.setCanDrop(this.isDragOver(draggable), draggable, e);\r
90913 },\r
90914 \r
90915 setCanDrop: function(canDrop, draggable, e) {\r
90916 if (canDrop && !this.canDrop) {\r
90917 this.canDrop = true;\r
90918 this.el.addCls(this.hoverCls);\r
90919 this.fireEvent('dropenter', this, draggable, e);\r
90920 } else if (!canDrop && this.canDrop) {\r
90921 this.canDrop = false;\r
90922 this.el.removeCls(this.hoverCls);\r
90923 this.fireEvent('dropleave', this, draggable, e);\r
90924 }\r
90925 },\r
90926 \r
90927 onBeforeDragEnd: function(draggable, e) {\r
90928 draggable.cancelRevert = this.canDrop;\r
90929 },\r
90930 \r
90931 onDragEnd: function(draggable, e) {\r
90932 this.monitoring = false;\r
90933 this.el.removeCls(this.activeCls);\r
90934 draggable.un({\r
90935 drag: this.onDrag,\r
90936 beforedragend: this.onBeforeDragEnd,\r
90937 dragend: this.onDragEnd,\r
90938 scope: this\r
90939 });\r
90940 if (this.canDrop) {\r
90941 this.canDrop = false;\r
90942 this.el.removeCls(this.hoverCls);\r
90943 this.fireEvent('drop', this, draggable, e);\r
90944 }\r
90945 this.fireEvent('dropdeactivate', this, draggable, e);\r
90946 },\r
90947 \r
90948 enable: function() {\r
90949 if (!this.mgr) {\r
90950 this.mgr = Ext.util.Observable.observe(Ext.util.Draggable);\r
90951 }\r
90952 this.mgr.on({\r
90953 dragstart: this.onDragStart,\r
90954 scope: this\r
90955 });\r
90956 this.disabled = false;\r
90957 },\r
90958 \r
90959 disable: function() {\r
90960 this.mgr.un({\r
90961 dragstart: this.onDragStart,\r
90962 scope: this\r
90963 });\r
90964 this.disabled = true;\r
90965 },\r
90966 \r
90967 isDisabled: function() {\r
90968 return this.disabled;\r
90969 },\r
90970 \r
90971 isMonitoring: function() {\r
90972 return this.monitoring;\r
90973 }\r
90974});\r
90975\r
90976\r
90977Ext.define('Ext.util.TranslatableList', {\r
90978 extend: Ext.util.translatable.Abstract,\r
90979 config: {\r
90980 items: []\r
90981 },\r
90982 applyItems: function(items) {\r
90983 return Ext.Array.from(items);\r
90984 },\r
90985 doTranslate: function(x, y) {\r
90986 var items = this.getItems(),\r
90987 offset = 0,\r
90988 i, ln, item, translateY;\r
90989 for (i = 0 , ln = items.length; i < ln; i++) {\r
90990 item = items[i];\r
90991 if (item && !item._list_hidden) {\r
90992 translateY = y + offset;\r
90993 offset += item.$height;\r
90994 item.translate(0, translateY);\r
90995 }\r
90996 }\r
90997 }\r
90998});