]> git.proxmox.com Git - extjs.git/blame - extjs/packages/core/src/class/ClassManager.js
add extjs 6.0.1 sources
[extjs.git] / extjs / packages / core / src / class / ClassManager.js
CommitLineData
6527f429
DM
1// @tag class\r
2/**\r
3 * @class Ext.ClassManager\r
4 *\r
5 * Ext.ClassManager manages all classes and handles mapping from string class name to\r
6 * actual class objects throughout the whole framework. It is not generally accessed directly, rather through\r
7 * these convenient shorthands:\r
8 *\r
9 * - {@link Ext#define Ext.define}\r
10 * - {@link Ext#create Ext.create}\r
11 * - {@link Ext#widget Ext.widget}\r
12 * - {@link Ext#getClass Ext.getClass}\r
13 * - {@link Ext#getClassName Ext.getClassName}\r
14 *\r
15 * # Basic syntax:\r
16 *\r
17 * Ext.define(className, properties);\r
18 *\r
19 * in which `properties` is an object represent a collection of properties that apply to the class. See\r
20 * {@link Ext.ClassManager#create} for more detailed instructions.\r
21 *\r
22 * Ext.define('Person', {\r
23 * name: 'Unknown',\r
24 *\r
25 * constructor: function(name) {\r
26 * if (name) {\r
27 * this.name = name;\r
28 * }\r
29 * },\r
30 *\r
31 * eat: function(foodType) {\r
32 * alert("I'm eating: " + foodType);\r
33 *\r
34 * return this;\r
35 * }\r
36 * });\r
37 *\r
38 * var aaron = new Person("Aaron");\r
39 * aaron.eat("Sandwich"); // alert("I'm eating: Sandwich");\r
40 *\r
41 * Ext.Class has a powerful set of extensible {@link Ext.Class#registerPreprocessor pre-processors} which takes care of\r
42 * everything related to class creation, including but not limited to inheritance, mixins, configuration, statics, etc.\r
43 *\r
44 * # Inheritance:\r
45 *\r
46 * Ext.define('Developer', {\r
47 * extend: 'Person',\r
48 *\r
49 * constructor: function(name, isGeek) {\r
50 * this.isGeek = isGeek;\r
51 *\r
52 * // Apply a method from the parent class' prototype\r
53 * this.callParent([name]);\r
54 * },\r
55 *\r
56 * code: function(language) {\r
57 * alert("I'm coding in: " + language);\r
58 *\r
59 * this.eat("Bugs");\r
60 *\r
61 * return this;\r
62 * }\r
63 * });\r
64 *\r
65 * var jacky = new Developer("Jacky", true);\r
66 * jacky.code("JavaScript"); // alert("I'm coding in: JavaScript");\r
67 * // alert("I'm eating: Bugs");\r
68 *\r
69 * See {@link Ext.Base#callParent} for more details on calling superclass' methods\r
70 *\r
71 * # Mixins:\r
72 *\r
73 * Ext.define('CanPlayGuitar', {\r
74 * playGuitar: function() {\r
75 * alert("F#...G...D...A");\r
76 * }\r
77 * });\r
78 *\r
79 * Ext.define('CanComposeSongs', {\r
80 * composeSongs: function() { ... }\r
81 * });\r
82 *\r
83 * Ext.define('CanSing', {\r
84 * sing: function() {\r
85 * alert("For he's a jolly good fellow...")\r
86 * }\r
87 * });\r
88 *\r
89 * Ext.define('Musician', {\r
90 * extend: 'Person',\r
91 *\r
92 * mixins: {\r
93 * canPlayGuitar: 'CanPlayGuitar',\r
94 * canComposeSongs: 'CanComposeSongs',\r
95 * canSing: 'CanSing'\r
96 * }\r
97 * })\r
98 *\r
99 * Ext.define('CoolPerson', {\r
100 * extend: 'Person',\r
101 *\r
102 * mixins: {\r
103 * canPlayGuitar: 'CanPlayGuitar',\r
104 * canSing: 'CanSing'\r
105 * },\r
106 *\r
107 * sing: function() {\r
108 * alert("Ahem....");\r
109 *\r
110 * this.mixins.canSing.sing.call(this);\r
111 *\r
112 * alert("[Playing guitar at the same time...]");\r
113 *\r
114 * this.playGuitar();\r
115 * }\r
116 * });\r
117 *\r
118 * var me = new CoolPerson("Jacky");\r
119 *\r
120 * me.sing(); // alert("Ahem...");\r
121 * // alert("For he's a jolly good fellow...");\r
122 * // alert("[Playing guitar at the same time...]");\r
123 * // alert("F#...G...D...A");\r
124 *\r
125 * # Config:\r
126 *\r
127 * Ext.define('SmartPhone', {\r
128 * config: {\r
129 * hasTouchScreen: false,\r
130 * operatingSystem: 'Other',\r
131 * price: 500\r
132 * },\r
133 *\r
134 * isExpensive: false,\r
135 *\r
136 * constructor: function(config) {\r
137 * this.initConfig(config);\r
138 * },\r
139 *\r
140 * applyPrice: function(price) {\r
141 * this.isExpensive = (price > 500);\r
142 *\r
143 * return price;\r
144 * },\r
145 *\r
146 * applyOperatingSystem: function(operatingSystem) {\r
147 * if (!(/^(iOS|Android|BlackBerry)$/i).test(operatingSystem)) {\r
148 * return 'Other';\r
149 * }\r
150 *\r
151 * return operatingSystem;\r
152 * }\r
153 * });\r
154 *\r
155 * var iPhone = new SmartPhone({\r
156 * hasTouchScreen: true,\r
157 * operatingSystem: 'iOS'\r
158 * });\r
159 *\r
160 * iPhone.getPrice(); // 500;\r
161 * iPhone.getOperatingSystem(); // 'iOS'\r
162 * iPhone.getHasTouchScreen(); // true;\r
163 *\r
164 * iPhone.isExpensive; // false;\r
165 * iPhone.setPrice(600);\r
166 * iPhone.getPrice(); // 600\r
167 * iPhone.isExpensive; // true;\r
168 *\r
169 * iPhone.setOperatingSystem('AlienOS');\r
170 * iPhone.getOperatingSystem(); // 'Other'\r
171 *\r
172 * # Statics:\r
173 *\r
174 * Ext.define('Computer', {\r
175 * statics: {\r
176 * factory: function(brand) {\r
177 * // 'this' in static methods refer to the class itself\r
178 * return new this(brand);\r
179 * }\r
180 * },\r
181 *\r
182 * constructor: function() { ... }\r
183 * });\r
184 *\r
185 * var dellComputer = Computer.factory('Dell');\r
186 *\r
187 * Also see {@link Ext.Base#statics} and {@link Ext.Base#self} for more details on accessing\r
188 * static properties within class methods\r
189 *\r
190 * @singleton\r
191 */\r
192Ext.ClassManager = (function(Class, alias, arraySlice, arrayFrom, global) {\r
193// @define Ext.ClassManager\r
194// @require Ext.Inventory\r
195// @require Ext.Class\r
196// @require Ext.Function\r
197// @require Ext.Array\r
198\r
199var makeCtor = Ext.Class.makeCtor,\r
200 //<if nonBrowser>\r
201 isNonBrowser = typeof window === 'undefined',\r
202 //</if>\r
203 nameLookupStack = [],\r
204 namespaceCache = {\r
205 Ext: {\r
206 name: 'Ext',\r
207 value: Ext // specially added for sandbox (Ext === global.Ext6)\r
208 }\r
209 /*\r
210 'Ext.grid': {\r
211 name: 'grid',\r
212 parent: namespaceCache['Ext']\r
213 },\r
214 'Ext.grid.Panel': {\r
215 name: 'Panel',\r
216 parent: namespaceCache['Ext.grid']\r
217 },\r
218 ...\r
219\r
220 Also,\r
221 'MyApp': {\r
222 name: 'MyApp',\r
223 value: MyApp\r
224 }\r
225 */\r
226 },\r
227\r
228 Manager = Ext.apply(new Ext.Inventory(), {\r
229 /**\r
230 * @property {Object} classes\r
231 * All classes which were defined through the ClassManager. Keys are the\r
232 * name of the classes and the values are references to the classes.\r
233 * @private\r
234 */\r
235 classes: {},\r
236\r
237 classState: {\r
238 /*\r
239 * 'Ext.foo.Bar': <state enum>\r
240 *\r
241 * 10 = Ext.define called\r
242 * 20 = Ext.define/override called\r
243 * 30 = Manager.existCache[<name>] == true for define\r
244 * 40 = Manager.existCache[<name>] == true for define/override\r
245 * 50 = Manager.isCreated(<name>) == true for define\r
246 * 60 = Manager.isCreated(<name>) == true for define/override\r
247 *\r
248 */\r
249 },\r
250\r
251 /**\r
252 * @private\r
253 */\r
254 existCache: {},\r
255\r
256 /** @private */\r
257 instantiators: [],\r
258\r
259 /**\r
260 * Checks if a class has already been created.\r
261 *\r
262 * @param {String} className\r
263 * @return {Boolean} exist\r
264 */\r
265 isCreated: function(className) {\r
266 //<debug>\r
267 if (typeof className !== 'string' || className.length < 1) {\r
268 throw new Error("[Ext.ClassManager] Invalid classname, must be a string and must not be empty");\r
269 }\r
270 //</debug>\r
271\r
272 if (Manager.classes[className] || Manager.existCache[className]) {\r
273 return true;\r
274 }\r
275\r
276 if (!Manager.lookupName(className, false)) {\r
277 return false;\r
278 }\r
279\r
280 Manager.triggerCreated(className);\r
281 return true;\r
282 },\r
283\r
284 /**\r
285 * @private\r
286 */\r
287 createdListeners: [],\r
288\r
289 /**\r
290 * @private\r
291 */\r
292 nameCreatedListeners: {},\r
293\r
294 /**\r
295 * @private\r
296 */\r
297 existsListeners: [],\r
298\r
299 /**\r
300 * @private\r
301 */\r
302 nameExistsListeners: {},\r
303\r
304 /**\r
305 * @private\r
306 */\r
307 overrideMap: {},\r
308\r
309 /**\r
310 * @private\r
311 */\r
312 triggerCreated: function (className, state) {\r
313 Manager.existCache[className] = state || 1;\r
314 Manager.classState[className] += 40;\r
315 Manager.notify(className, Manager.createdListeners, Manager.nameCreatedListeners);\r
316 },\r
317\r
318 /**\r
319 * @private\r
320 */\r
321 onCreated: function(fn, scope, className) {\r
322 Manager.addListener(fn, scope, className, Manager.createdListeners, Manager.nameCreatedListeners);\r
323 },\r
324\r
325 /**\r
326 * @private\r
327 */\r
328 notify: function (className, listeners, nameListeners) {\r
329 var alternateNames = Manager.getAlternatesByName(className),\r
330 names = [className],\r
331 i, ln, j, subLn, listener, name;\r
332\r
333 for (i = 0,ln = listeners.length; i < ln; i++) {\r
334 listener = listeners[i];\r
335 listener.fn.call(listener.scope, className);\r
336 }\r
337\r
338 while (names) {\r
339 for (i = 0,ln = names.length; i < ln; i++) {\r
340 name = names[i];\r
341 listeners = nameListeners[name];\r
342\r
343 if (listeners) {\r
344 for (j = 0,subLn = listeners.length; j < subLn; j++) {\r
345 listener = listeners[j];\r
346 listener.fn.call(listener.scope, name);\r
347 }\r
348 delete nameListeners[name];\r
349 }\r
350 }\r
351\r
352 names = alternateNames; // for 2nd pass (if needed)\r
353 alternateNames = null; // no 3rd pass\r
354 }\r
355 },\r
356\r
357 /**\r
358 * @private\r
359 */\r
360 addListener: function(fn, scope, className, listeners, nameListeners) {\r
361 if (Ext.isArray(className)) {\r
362 fn = Ext.Function.createBarrier(className.length, fn, scope);\r
363 for (i = 0; i < className.length; i++) {\r
364 this.addListener(fn, null, className[i], listeners, nameListeners);\r
365 }\r
366 return;\r
367 }\r
368 var i,\r
369 listener = {\r
370 fn: fn,\r
371 scope: scope\r
372 };\r
373\r
374 if (className) {\r
375 if (this.isCreated(className)) {\r
376 fn.call(scope, className);\r
377 return;\r
378 }\r
379\r
380 if (!nameListeners[className]) {\r
381 nameListeners[className] = [];\r
382 }\r
383\r
384 nameListeners[className].push(listener);\r
385 }\r
386 else {\r
387 listeners.push(listener);\r
388 }\r
389 },\r
390\r
391 /**\r
392 * Supports namespace rewriting.\r
393 * @private\r
394 */\r
395 $namespaceCache: namespaceCache,\r
396\r
397 /**\r
398 * See `{@link Ext#addRootNamespaces Ext.addRootNamespaces}`.\r
399 * @since 6.0.0\r
400 * @private\r
401 */\r
402 addRootNamespaces: function (namespaces) {\r
403 for (var name in namespaces) {\r
404 namespaceCache[name] = {\r
405 name: name,\r
406 value: namespaces[name]\r
407 };\r
408 }\r
409 },\r
410\r
411 /**\r
412 * Clears the namespace lookup cache. After application launch, this cache can\r
413 * often contain several hundred entries that are unlikely to be needed again.\r
414 * These will be rebuilt as needed, so it is harmless to clear this cache even\r
415 * if its results will be used again.\r
416 * @since 6.0.0\r
417 * @private\r
418 */\r
419 clearNamespaceCache: function () {\r
420 nameLookupStack.length = 0;\r
421\r
422 for (var name in namespaceCache) {\r
423 if (!namespaceCache[name].value) {\r
424 delete namespaceCache[name];\r
425 }\r
426 }\r
427 },\r
428\r
429 /**\r
430 * Return the namespace cache entry for the given a class name or namespace (e.g.,\r
431 * "Ext.grid.Panel").\r
432 *\r
433 * @param {String} namespace The namespace or class name to lookup.\r
434 * @return {Object} The cache entry.\r
435 * @return {String} return.name The leaf name ("Panel" for "Ext.grid.Panel").\r
436 * @return {Object} return.parent The entry of the parent namespace (i.e., "Ext.grid").\r
437 * @return {Object} return.value The namespace object. This is only set for\r
438 * top-level namespace entries to support renaming them for sandboxing ("Ext6" vs\r
439 * "Ext").\r
440 * @since 6.0.0\r
441 * @private\r
442 */\r
443 getNamespaceEntry: function (namespace) {\r
444 if (typeof namespace !== 'string') {\r
445 return namespace; // assume we've been given an entry object\r
446 }\r
447\r
448 var entry = namespaceCache[namespace],\r
449 i;\r
450\r
451 if (!entry) {\r
452 i = namespace.lastIndexOf('.');\r
453\r
454 if (i < 0) {\r
455 entry = {\r
456 name: namespace\r
457 };\r
458 } else {\r
459 entry = {\r
460 name: namespace.substring(i + 1),\r
461 parent: Manager.getNamespaceEntry(namespace.substring(0, i))\r
462 };\r
463 }\r
464\r
465 namespaceCache[namespace] = entry;\r
466 }\r
467\r
468 return entry;\r
469 },\r
470\r
471 /**\r
472 * Return the value of the given "dot path" name. This supports remapping (for use\r
473 * in sandbox builds) as well as auto-creating of namespaces.\r
474 *\r
475 * @param {String} namespace The name of the namespace or class.\r
476 * @param {Boolean} [autoCreate] Pass `true` to create objects for undefined names.\r
477 * @return {Object} The object that is the namespace or class name.\r
478 * @since 6.0.0\r
479 * @private\r
480 */\r
481 lookupName: function (namespace, autoCreate) {\r
482 var entry = Manager.getNamespaceEntry(namespace),\r
483 scope = Ext.global,\r
484 i = 0,\r
485 e, parent;\r
486\r
487 // Put entries on the stack in reverse order: [ 'Panel', 'grid', 'Ext' ]\r
488 for (e = entry; e; e = e.parent) {\r
489 // since we process only what we add to the array, and that always\r
490 // starts at index=0, we don't need to clean up the array (that would\r
491 // just encourage the GC to do something pointless).\r
492 nameLookupStack[i++] = e;\r
493 }\r
494\r
495 while (scope && i-- > 0) {\r
496 // We'll process entries in top-down order ('Ext', 'grid' then 'Panel').\r
497 e = nameLookupStack[i];\r
498 parent = scope;\r
499\r
500 scope = e.value || scope[e.name];\r
501\r
502 if (!scope && autoCreate) {\r
503 parent[e.name] = scope = {};\r
504 }\r
505 }\r
506\r
507 return scope;\r
508 },\r
509\r
510 /**\r
511 * Creates a namespace and assign the `value` to the created object.\r
512 *\r
513 * Ext.ClassManager.setNamespace('MyCompany.pkg.Example', someObject);\r
514 *\r
515 * alert(MyCompany.pkg.Example === someObject); // alerts true\r
516 *\r
517 * @param {String} name\r
518 * @param {Object} value\r
519 */\r
520 setNamespace: function (namespace, value) {\r
521 var entry = Manager.getNamespaceEntry(namespace),\r
522 scope = Ext.global;\r
523\r
524 if (entry.parent) {\r
525 scope = Manager.lookupName(entry.parent, true);\r
526 }\r
527\r
528 scope[entry.name] = value;\r
529\r
530 return value;\r
531 },\r
532\r
533 /**\r
534 * Changes the mapping of an `xtype` to map to the specified component class.\r
535 * @param {String/Ext.Class} cls The class or class name to which `xtype` is mapped.\r
536 * @param {String} xtype The `xtype` to map or redefine as `cls`.\r
537 * @since 6.0.1\r
538 * @private\r
539 */\r
540 setXType: function (cls, xtype) {\r
541 var className = cls.$className,\r
542 C = className ? cls : Manager.get(className = cls),\r
543 proto = C.prototype,\r
544 xtypes = proto.xtypes,\r
545 xtypesChain = proto.xtypesChain,\r
546 xtypesMap = proto.xtypesMap;\r
547\r
548 if (!proto.hasOwnProperty('xtypes')) {\r
549 proto.xtypes = xtypes = [];\r
550 proto.xtypesChain = xtypesChain = xtypesChain ? xtypesChain.slice(0) : [];\r
551 proto.xtypesMap = xtypesMap = Ext.apply({}, xtypesMap);\r
552 }\r
553\r
554 Manager.addAlias(className, 'widget.' + xtype, true);\r
555\r
556 xtypes.push(xtype);\r
557 xtypesChain.push(xtype);\r
558 xtypesMap[xtype] = true;\r
559\r
560 //TODO consider updating derived class xtypesChain / xtypesMap\r
561 },\r
562\r
563 /**\r
564 * Sets a name reference to a class.\r
565 *\r
566 * @param {String} name\r
567 * @param {Object} value\r
568 * @return {Ext.ClassManager} this\r
569 */\r
570 set: function (name, value) {\r
571 var targetName = Manager.getName(value);\r
572\r
573 Manager.classes[name] = Manager.setNamespace(name, value);\r
574\r
575 if (targetName && targetName !== name) {\r
576 Manager.addAlternate(targetName, name);\r
577 }\r
578\r
579 return Manager;\r
580 },\r
581\r
582 /**\r
583 * Retrieve a class by its name.\r
584 *\r
585 * @param {String} name\r
586 * @return {Ext.Class} class\r
587 */\r
588 get: function(name) {\r
589 return Manager.classes[name] || Manager.lookupName(name, false);\r
590 },\r
591\r
592 /**\r
593 * Adds a batch of class name to alias mappings.\r
594 * @param {Object} aliases The set of mappings of the form.\r
595 * className : [values...]\r
596 */\r
597 addNameAliasMappings: function(aliases) {\r
598 Manager.addAlias(aliases);\r
599 },\r
600\r
601 /**\r
602 *\r
603 * @param {Object} alternates The set of mappings of the form\r
604 * className : [values...]\r
605 */\r
606 addNameAlternateMappings: function (alternates) {\r
607 Manager.addAlternate(alternates);\r
608 },\r
609\r
610 /**\r
611 * Get a reference to the class by its alias.\r
612 *\r
613 * @param {String} alias\r
614 * @return {Ext.Class} class\r
615 */\r
616 getByAlias: function(alias) {\r
617 return Manager.get(Manager.getNameByAlias(alias));\r
618 },\r
619\r
620 /**\r
621 * Get a component class name from a config object.\r
622 * @param {Object} config The config object.\r
623 * @param {String} [aliasPrefix] A prefix to use when getting\r
624 * a class name by alias.\r
625 * @return {Ext.Class} The class.\r
626 *\r
627 * @private\r
628 */\r
629 getByConfig: function(config, aliasPrefix) {\r
630 var xclass = config.xclass,\r
631 name;\r
632\r
633 if (xclass) {\r
634 name = xclass;\r
635 } else {\r
636 name = config.xtype;\r
637 if (name) {\r
638 aliasPrefix = 'widget.';\r
639 } else {\r
640 name = config.type;\r
641 }\r
642 name = Manager.getNameByAlias(aliasPrefix + name);\r
643 }\r
644 return Manager.get(name);\r
645 }, \r
646\r
647 /**\r
648 * Get the name of the class by its reference or its instance. This is\r
649 * usually invoked by the shorthand {@link Ext#getClassName}.\r
650 *\r
651 * Ext.ClassManager.getName(Ext.Action); // returns "Ext.Action"\r
652 *\r
653 * @param {Ext.Class/Object} object\r
654 * @return {String} className\r
655 */\r
656 getName: function(object) {\r
657 return object && object.$className || '';\r
658 },\r
659\r
660 /**\r
661 * Get the class of the provided object; returns null if it's not an instance\r
662 * of any class created with Ext.define. This is usually invoked by the\r
663 * shorthand {@link Ext#getClass}.\r
664 *\r
665 * var component = new Ext.Component();\r
666 *\r
667 * Ext.getClass(component); // returns Ext.Component\r
668 *\r
669 * @param {Object} object\r
670 * @return {Ext.Class} class\r
671 */\r
672 getClass: function(object) {\r
673 return object && object.self || null;\r
674 },\r
675\r
676 /**\r
677 * Defines a class.\r
678 * @deprecated Use {@link Ext#define} instead, as that also supports creating overrides.\r
679 * @private\r
680 */\r
681 create: function(className, data, createdFn) {\r
682 //<debug>\r
683 if (className != null && typeof className !== 'string') {\r
684 throw new Error("[Ext.define] Invalid class name '" + className + "' specified, must be a non-empty string");\r
685 }\r
686 //</debug>\r
687\r
688 var ctor = makeCtor(className);\r
689 if (typeof data === 'function') {\r
690 data = data(ctor);\r
691 }\r
692\r
693 //<debug>\r
694 if (className) {\r
695 if (Manager.classes[className]) {\r
696 Ext.log.warn("[Ext.define] Duplicate class name '" + className + "' specified, must be a non-empty string");\r
697 }\r
698 ctor.name = className;\r
699 }\r
700 //</debug>\r
701\r
702 data.$className = className;\r
703\r
704 return new Class(ctor, data, function() {\r
705 var postprocessorStack = data.postprocessors || Manager.defaultPostprocessors,\r
706 registeredPostprocessors = Manager.postprocessors,\r
707 postprocessors = [],\r
708 postprocessor, i, ln, j, subLn, postprocessorProperties, postprocessorProperty;\r
709\r
710 delete data.postprocessors;\r
711\r
712 for (i = 0,ln = postprocessorStack.length; i < ln; i++) {\r
713 postprocessor = postprocessorStack[i];\r
714\r
715 if (typeof postprocessor === 'string') {\r
716 postprocessor = registeredPostprocessors[postprocessor];\r
717 postprocessorProperties = postprocessor.properties;\r
718\r
719 if (postprocessorProperties === true) {\r
720 postprocessors.push(postprocessor.fn);\r
721 }\r
722 else if (postprocessorProperties) {\r
723 for (j = 0,subLn = postprocessorProperties.length; j < subLn; j++) {\r
724 postprocessorProperty = postprocessorProperties[j];\r
725\r
726 if (data.hasOwnProperty(postprocessorProperty)) {\r
727 postprocessors.push(postprocessor.fn);\r
728 break;\r
729 }\r
730 }\r
731 }\r
732 }\r
733 else {\r
734 postprocessors.push(postprocessor);\r
735 }\r
736 }\r
737\r
738 data.postprocessors = postprocessors;\r
739 data.createdFn = createdFn;\r
740 Manager.processCreate(className, this, data);\r
741 });\r
742 },\r
743\r
744 processCreate: function(className, cls, clsData){\r
745 var me = this,\r
746 postprocessor = clsData.postprocessors.shift(),\r
747 createdFn = clsData.createdFn;\r
748\r
749 if (!postprocessor) {\r
750 //<debug>\r
751 Ext.classSystemMonitor && Ext.classSystemMonitor(className, 'Ext.ClassManager#classCreated', arguments);\r
752 //</debug>\r
753\r
754 if (className) {\r
755 me.set(className, cls);\r
756 }\r
757\r
758 delete cls._classHooks;\r
759\r
760 if (createdFn) {\r
761 createdFn.call(cls, cls);\r
762 }\r
763\r
764 if (className) {\r
765 me.triggerCreated(className);\r
766 }\r
767 return;\r
768 }\r
769\r
770 if (postprocessor.call(me, className, cls, clsData, me.processCreate) !== false) {\r
771 me.processCreate(className, cls, clsData);\r
772 }\r
773 },\r
774\r
775 createOverride: function (className, data, createdFn) {\r
776 var me = this,\r
777 overriddenClassName = data.override,\r
778 requires = data.requires,\r
779 uses = data.uses,\r
780 mixins = data.mixins,\r
781 mixinsIsArray,\r
782 compat = 1, // default if 'compatibility' is not specified\r
783 depedenciesLoaded,\r
784 classReady = function () {\r
785 var cls, dependencies, i, key, temp;\r
786\r
787 if (!depedenciesLoaded) {\r
788 dependencies = requires ? requires.slice(0) : [];\r
789\r
790 if (mixins) {\r
791 if (!(mixinsIsArray = mixins instanceof Array)) {\r
792 for (key in mixins) {\r
793 if (Ext.isString(cls = mixins[key])) {\r
794 dependencies.push(cls);\r
795 }\r
796 }\r
797 } else {\r
798 for (i = 0, temp = mixins.length; i < temp; ++i) {\r
799 if (Ext.isString(cls = mixins[i])) {\r
800 dependencies.push(cls);\r
801 }\r
802 }\r
803 }\r
804 }\r
805\r
806 depedenciesLoaded = true;\r
807 if (dependencies.length) {\r
808 // Since the override is going to be used (its target class is\r
809 // now created), we need to fetch the required classes for the\r
810 // override and call us back once they are loaded:\r
811 Ext.require(dependencies, classReady);\r
812 return;\r
813 }\r
814 // else we have no dependencies, so proceed\r
815 }\r
816\r
817 // transform mixin class names into class references, This\r
818 // loop can handle both the array and object forms of\r
819 // mixin definitions\r
820 if (mixinsIsArray) {\r
821 for (i = 0, temp = mixins.length; i < temp; ++i) {\r
822 if (Ext.isString(cls = mixins[i])) {\r
823 mixins[i] = Ext.ClassManager.get(cls);\r
824 }\r
825 }\r
826 } else if (mixins) {\r
827 for (key in mixins) {\r
828 if (Ext.isString(cls = mixins[key])) {\r
829 mixins[key] = Ext.ClassManager.get(cls);\r
830 }\r
831 }\r
832 }\r
833\r
834 // The target class and the required classes for this override are\r
835 // ready, so we can apply the override now:\r
836 cls = me.get(overriddenClassName);\r
837\r
838 // We don't want to apply these:\r
839 delete data.override;\r
840 delete data.compatibility;\r
841 delete data.requires;\r
842 delete data.uses;\r
843\r
844 Ext.override(cls, data);\r
845\r
846 // This pushes the overriding file itself into Ext.Loader.history\r
847 // Hence if the target class never exists, the overriding file will\r
848 // never be included in the build.\r
849 Ext.Loader.history.push(className);\r
850\r
851 if (uses) {\r
852 // This "hides" from the Cmd auto-dependency scanner since\r
853 // the reference is circular (Loader requires us).\r
854 Ext['Loader'].addUsedClasses(uses); // get these classes too!\r
855 }\r
856\r
857 if (createdFn) {\r
858 createdFn.call(cls, cls); // last but not least!\r
859 }\r
860 };\r
861\r
862 Manager.overrideMap[className] = true;\r
863\r
864 // If specified, parse strings as versions, but otherwise treat as a\r
865 // boolean (maybe "compatibility: Ext.isIE8" or something).\r
866 //\r
867 if ('compatibility' in data && Ext.isString(compat = data.compatibility)) {\r
868 compat = Ext.checkVersion(compat);\r
869 }\r
870\r
871 if (compat) {\r
872 // Override the target class right after it's created\r
873 me.onCreated(classReady, me, overriddenClassName);\r
874 }\r
875\r
876 me.triggerCreated(className, 2);\r
877 return me;\r
878 },\r
879\r
880 /**\r
881 * Instantiate a class by its alias. This is usually invoked by the\r
882 * shorthand {@link Ext#createByAlias}.\r
883 *\r
884 * If {@link Ext.Loader} is {@link Ext.Loader#setConfig enabled} and the class\r
885 * has not been defined yet, it will attempt to load the class via synchronous\r
886 * loading.\r
887 *\r
888 * var window = Ext.createByAlias('widget.window', { width: 600, height: 800 });\r
889 *\r
890 * @param {String} alias\r
891 * @param {Object...} args Additional arguments after the alias will be passed to the\r
892 * class constructor.\r
893 * @return {Object} instance\r
894 */\r
895 instantiateByAlias: function() {\r
896 var alias = arguments[0],\r
897 args = arraySlice.call(arguments),\r
898 className = this.getNameByAlias(alias);\r
899\r
900 //<debug>\r
901 if (!className) {\r
902 throw new Error("[Ext.createByAlias] Unrecognized alias: " + alias);\r
903 }\r
904 //</debug>\r
905\r
906 args[0] = className;\r
907\r
908 return Ext.create.apply(Ext, args);\r
909 },\r
910\r
911 //<deprecated since=5.0>\r
912 /**\r
913 * Instantiate a class by either full name, alias or alternate name\r
914 * @param {String} name\r
915 * @param {Mixed} args Additional arguments after the name will be passed to the class' constructor.\r
916 * @return {Object} instance\r
917 * @deprecated 5.0 Use Ext.create() instead.\r
918 */\r
919 instantiate: function() {\r
920 //<debug>\r
921 Ext.log.warn('Ext.ClassManager.instantiate() is deprecated. Use Ext.create() instead.');\r
922 //</debug>\r
923 return Ext.create.apply(Ext, arguments);\r
924 },\r
925 //</deprecated>\r
926\r
927 /**\r
928 * @private\r
929 * @param name\r
930 * @param args\r
931 */\r
932 dynInstantiate: function(name, args) {\r
933 args = arrayFrom(args, true);\r
934 args.unshift(name);\r
935\r
936 return Ext.create.apply(Ext, args);\r
937 },\r
938\r
939 /**\r
940 * @private\r
941 * @param length\r
942 */\r
943 getInstantiator: function(length) {\r
944 var instantiators = this.instantiators,\r
945 instantiator,\r
946 i,\r
947 args;\r
948\r
949 instantiator = instantiators[length];\r
950\r
951 if (!instantiator) {\r
952 i = length;\r
953 args = [];\r
954\r
955 for (i = 0; i < length; i++) {\r
956 args.push('a[' + i + ']');\r
957 }\r
958\r
959 instantiator = instantiators[length] = new Function('c', 'a', 'return new c(' + args.join(',') + ')');\r
960 //<debug>\r
961 instantiator.name = "Ext.create" + length;\r
962 //</debug>\r
963 }\r
964\r
965 return instantiator;\r
966 },\r
967\r
968 /**\r
969 * @private\r
970 */\r
971 postprocessors: {},\r
972\r
973 /**\r
974 * @private\r
975 */\r
976 defaultPostprocessors: [],\r
977\r
978 /**\r
979 * Register a post-processor function.\r
980 *\r
981 * @private\r
982 * @param {String} name\r
983 * @param {Function} postprocessor\r
984 */\r
985 registerPostprocessor: function(name, fn, properties, position, relativeTo) {\r
986 if (!position) {\r
987 position = 'last';\r
988 }\r
989\r
990 if (!properties) {\r
991 properties = [name];\r
992 }\r
993\r
994 this.postprocessors[name] = {\r
995 name: name,\r
996 properties: properties || false,\r
997 fn: fn\r
998 };\r
999\r
1000 this.setDefaultPostprocessorPosition(name, position, relativeTo);\r
1001\r
1002 return this;\r
1003 },\r
1004\r
1005 /**\r
1006 * Set the default post processors array stack which are applied to every class.\r
1007 *\r
1008 * @private\r
1009 * @param {String/Array} postprocessors The name of a registered post processor or an array of registered names.\r
1010 * @return {Ext.ClassManager} this\r
1011 */\r
1012 setDefaultPostprocessors: function(postprocessors) {\r
1013 this.defaultPostprocessors = arrayFrom(postprocessors);\r
1014\r
1015 return this;\r
1016 },\r
1017\r
1018 /**\r
1019 * Insert this post-processor at a specific position in the stack, optionally relative to\r
1020 * any existing post-processor\r
1021 *\r
1022 * @private\r
1023 * @param {String} name The post-processor name. Note that it needs to be registered with\r
1024 * {@link Ext.ClassManager#registerPostprocessor} before this\r
1025 * @param {String} offset The insertion position. Four possible values are:\r
1026 * 'first', 'last', or: 'before', 'after' (relative to the name provided in the third argument)\r
1027 * @param {String} relativeName\r
1028 * @return {Ext.ClassManager} this\r
1029 */\r
1030 setDefaultPostprocessorPosition: function(name, offset, relativeName) {\r
1031 var defaultPostprocessors = this.defaultPostprocessors,\r
1032 index;\r
1033\r
1034 if (typeof offset === 'string') {\r
1035 if (offset === 'first') {\r
1036 defaultPostprocessors.unshift(name);\r
1037\r
1038 return this;\r
1039 }\r
1040 else if (offset === 'last') {\r
1041 defaultPostprocessors.push(name);\r
1042\r
1043 return this;\r
1044 }\r
1045\r
1046 offset = (offset === 'after') ? 1 : -1;\r
1047 }\r
1048\r
1049 index = Ext.Array.indexOf(defaultPostprocessors, relativeName);\r
1050\r
1051 if (index !== -1) {\r
1052 Ext.Array.splice(defaultPostprocessors, Math.max(0, index + offset), 0, name);\r
1053 }\r
1054\r
1055 return this;\r
1056 }\r
1057 });\r
1058\r
1059 /**\r
1060 * @cfg xtype\r
1061 * @member Ext.Class\r
1062 * @inheritdoc Ext.Component#cfg-xtype\r
1063 */\r
1064\r
1065 /**\r
1066 * @cfg {String} override\r
1067 * @member Ext.Class\r
1068 * Overrides members of the specified `target` class.\r
1069 * \r
1070 * **NOTE:** the overridden class must have been defined using \r
1071 * {@link Ext#define Ext.define} in order to use the `override` config.\r
1072 * \r
1073 * Methods defined on the overriding class will not automatically call the methods of \r
1074 * the same name in the ancestor class chain. To call the parent's method of the \r
1075 * same name you must call {@link Ext.Base#callParent callParent}. To skip the \r
1076 * method of the overridden class and call its parent you will instead call \r
1077 * {@link Ext.Base#callSuper callSuper}.\r
1078 *\r
1079 * See {@link Ext#define Ext.define} for additional usage examples.\r
1080 */\r
1081 \r
1082 //<feature classSystem.alias>\r
1083 /**\r
1084 * @cfg {String/String[]} alias\r
1085 * @member Ext.Class\r
1086 * List of short aliases for class names. An alias consists of a namespace and a name\r
1087 * concatenated by a period as &#60;namespace&#62;.&#60;name&#62;\r
1088 *\r
1089 * - **namespace** - The namespace describes what kind of alias this is and must be\r
1090 * all lowercase.\r
1091 * - **name** - The name of the alias which allows the lazy-instantiation via the\r
1092 * alias. The name shouldn't contain any periods.\r
1093 *\r
1094 * A list of namespaces and the usages are:\r
1095 *\r
1096 * - **feature** - {@link Ext.grid.Panel Grid} features\r
1097 * - **plugin** - Plugins\r
1098 * - **store** - {@link Ext.data.Store}\r
1099 * - **widget** - Components\r
1100 *\r
1101 * Most useful for defining xtypes for widgets:\r
1102 *\r
1103 * Ext.define('MyApp.CoolPanel', {\r
1104 * extend: 'Ext.panel.Panel',\r
1105 * alias: ['widget.coolpanel'],\r
1106 * title: 'Yeah!'\r
1107 * });\r
1108 *\r
1109 * // Using Ext.create\r
1110 * Ext.create('widget.coolpanel');\r
1111 *\r
1112 * // Using the shorthand for defining widgets by xtype\r
1113 * Ext.widget('panel', {\r
1114 * items: [\r
1115 * {xtype: 'coolpanel', html: 'Foo'},\r
1116 * {xtype: 'coolpanel', html: 'Bar'}\r
1117 * ]\r
1118 * });\r
1119 */\r
1120 Manager.registerPostprocessor('alias', function(name, cls, data) {\r
1121 //<debug>\r
1122 Ext.classSystemMonitor && Ext.classSystemMonitor(name, 'Ext.ClassManager#aliasPostProcessor', arguments);\r
1123 //</debug>\r
1124 \r
1125 var aliases = Ext.Array.from(data.alias),\r
1126 i, ln;\r
1127\r
1128 for (i = 0,ln = aliases.length; i < ln; i++) {\r
1129 alias = aliases[i];\r
1130\r
1131 this.addAlias(cls, alias);\r
1132 }\r
1133\r
1134 }, ['xtype', 'alias']);\r
1135 //</feature>\r
1136\r
1137 //<feature classSystem.singleton>\r
1138 /**\r
1139 * @cfg {Boolean} singleton\r
1140 * @member Ext.Class\r
1141 * When set to true, the class will be instantiated as singleton. For example:\r
1142 *\r
1143 * Ext.define('Logger', {\r
1144 * singleton: true,\r
1145 * log: function(msg) {\r
1146 * console.log(msg);\r
1147 * }\r
1148 * });\r
1149 *\r
1150 * Logger.log('Hello');\r
1151 */\r
1152 Manager.registerPostprocessor('singleton', function(name, cls, data, fn) {\r
1153 //<debug>\r
1154 Ext.classSystemMonitor && Ext.classSystemMonitor(name, 'Ext.ClassManager#singletonPostProcessor', arguments);\r
1155 //</debug>\r
1156 \r
1157 if (data.singleton) {\r
1158 fn.call(this, name, new cls(), data);\r
1159 }\r
1160 else {\r
1161 return true;\r
1162 }\r
1163 return false;\r
1164 });\r
1165 //</feature>\r
1166\r
1167 //<feature classSystem.alternateClassName>\r
1168 /**\r
1169 * @cfg {String/String[]} alternateClassName\r
1170 * @member Ext.Class\r
1171 * Defines alternate names for this class. For example:\r
1172 *\r
1173 * Ext.define('Developer', {\r
1174 * alternateClassName: ['Coder', 'Hacker'],\r
1175 * code: function(msg) {\r
1176 * alert('Typing... ' + msg);\r
1177 * }\r
1178 * });\r
1179 *\r
1180 * var joe = Ext.create('Developer');\r
1181 * joe.code('stackoverflow');\r
1182 *\r
1183 * var rms = Ext.create('Hacker');\r
1184 * rms.code('hack hack');\r
1185 */\r
1186 Manager.registerPostprocessor('alternateClassName', function(name, cls, data) {\r
1187 //<debug>\r
1188 Ext.classSystemMonitor && Ext.classSystemMonitor(name, 'Ext.ClassManager#alternateClassNamePostprocessor', arguments);\r
1189 //</debug>\r
1190 \r
1191 var alternates = data.alternateClassName,\r
1192 i, ln, alternate;\r
1193\r
1194 if (!(alternates instanceof Array)) {\r
1195 alternates = [alternates];\r
1196 }\r
1197\r
1198 for (i = 0, ln = alternates.length; i < ln; i++) {\r
1199 alternate = alternates[i];\r
1200\r
1201 //<debug>\r
1202 if (typeof alternate !== 'string') {\r
1203 throw new Error("[Ext.define] Invalid alternate of: '" + alternate + "' for class: '" + name + "'; must be a valid string");\r
1204 }\r
1205 //</debug>\r
1206\r
1207 this.set(alternate, cls);\r
1208 }\r
1209 });\r
1210 //</feature>\r
1211\r
1212 /**\r
1213 * @cfg {Object} debugHooks\r
1214 * A collection of diagnostic methods to decorate the real methods of the class. These\r
1215 * methods are applied as an `override` if this class has debug enabled as defined by\r
1216 * `Ext.isDebugEnabled`.\r
1217 *\r
1218 * These will be automatically removed by the Sencha Cmd compiler for production builds.\r
1219 *\r
1220 * Example usage:\r
1221 *\r
1222 * Ext.define('Foo.bar.Class', {\r
1223 * foo: function (a, b, c) {\r
1224 * ...\r
1225 * },\r
1226 *\r
1227 * bar: function (a, b) {\r
1228 * ...\r
1229 * return 42;\r
1230 * },\r
1231 *\r
1232 * debugHooks: {\r
1233 * foo: function (a, b, c) {\r
1234 * // check arguments...\r
1235 * return this.callParent(arguments);\r
1236 * }\r
1237 * }\r
1238 * });\r
1239 *\r
1240 * If you specify a `$enabled` property in the `debugHooks` object that will be used\r
1241 * as the default enabled state for the hooks. If the `{@link Ext#manifest}` contains\r
1242 * a `debug` object of if `{@link Ext#debugConfig}` is specified, the `$enabled` flag\r
1243 * will override its "*" value.\r
1244 */\r
1245 Manager.registerPostprocessor('debugHooks', function(name, Class, data) {\r
1246 //<debug>\r
1247 Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#debugHooks', arguments);\r
1248\r
1249 if (Ext.isDebugEnabled(Class.$className, data.debugHooks.$enabled)) {\r
1250 delete data.debugHooks.$enabled;\r
1251 Ext.override(Class, data.debugHooks);\r
1252 }\r
1253 //</debug>\r
1254\r
1255 // may already have an instance here in the case of singleton\r
1256 var target = Class.isInstance ? Class.self : Class;\r
1257\r
1258 delete target.prototype.debugHooks;\r
1259 });\r
1260\r
1261 /**\r
1262 * @cfg {Object} deprecated\r
1263 * The object given has properties that describe the versions at which the deprecations\r
1264 * apply.\r
1265 *\r
1266 * The purpose of the `deprecated` declaration is to enable development mode to give\r
1267 * suitable error messages when deprecated methods or properties are used. Methods can\r
1268 * always be injected to provide this feedback, but properties can only be handled on\r
1269 * some browsers (those that support `Object.defineProperty`).\r
1270 *\r
1271 * In some cases, deprecated methods can be restored to their previous behavior or\r
1272 * added back if they have been removed.\r
1273 *\r
1274 * The structure of a `deprecated` declaration is this:\r
1275 *\r
1276 * Ext.define('Foo.bar.Class', {\r
1277 * ...\r
1278 *\r
1279 * deprecated: {\r
1280 * // Optional package name - default is the framework (ext or touch)\r
1281 * name: 'foobar',\r
1282 *\r
1283 * '5.0': {\r
1284 * methods: {\r
1285 * // Throws: '"removedMethod" is deprecated.'\r
1286 * removedMethod: null,\r
1287 *\r
1288 * // Throws: '"oldMethod" is deprecated. Please use "newMethod" instead.'\r
1289 * oldMethod: 'newMethod',\r
1290 *\r
1291 * // When this block is enabled, this method is applied as an\r
1292 * // override. Otherwise you get same as "removeMethod".\r
1293 * method: function () {\r
1294 * // Do what v5 "method" did. If "method" exists in newer\r
1295 * // versions callParent can call it. If 5.1 has "method"\r
1296 * // then it would be next in line, otherwise 5.2 and last\r
1297 * // would be the current class.\r
1298 * },\r
1299 *\r
1300 * moreHelpful: {\r
1301 * message: 'Something helpful to do instead.',\r
1302 * fn: function () {\r
1303 * // The v5 "moreHelpful" method to use when enabled.\r
1304 * }\r
1305 * }\r
1306 * },\r
1307 * properties: {\r
1308 * // Throws: '"removedProp" is deprecated.'\r
1309 * removedProp: null,\r
1310 *\r
1311 * // Throws: '"oldProp" is deprecated. Please use "newProp" instead.'\r
1312 * oldProp: 'newProp',\r
1313 *\r
1314 * helpful: {\r
1315 * message: 'Something helpful message about what to do.'\r
1316 * }\r
1317 * ...\r
1318 * },\r
1319 * statics: {\r
1320 * methods: {\r
1321 * ...\r
1322 * },\r
1323 * properties: {\r
1324 * ...\r
1325 * },\r
1326 * }\r
1327 * },\r
1328 *\r
1329 * '5.1': {\r
1330 * ...\r
1331 * },\r
1332 *\r
1333 * '5.2': {\r
1334 * ...\r
1335 * }\r
1336 * }\r
1337 * });\r
1338 *\r
1339 * The primary content of `deprecated` are the version number keys. These indicate\r
1340 * a version number where methods or properties were deprecated. These versions are\r
1341 * compared to the version reported by `Ext.getCompatVersion` to determine the action\r
1342 * to take for each "block".\r
1343 *\r
1344 * When the compatibility version is set to a value less than a version number key,\r
1345 * that block is said to be "enabled". For example, if a method was deprecated in\r
1346 * version 5.0 but the desired compatibility level is 4.2 then the block is used to\r
1347 * patch methods and (to some degree) restore pre-5.0 compatibility.\r
1348 *\r
1349 * When multiple active blocks have the same method name, each method is applied as\r
1350 * an override in reverse order of version. In the above example, if a method appears\r
1351 * in the "5.0", "5.1" and "5.2" blocks then the "5.2" method is applied as an override\r
1352 * first, followed by the "5.1" method and finally the "5.0" method. This means that\r
1353 * the `callParent` from the "5.0" method calls the "5.1" method which calls the\r
1354 * "5.2" method which can (if applicable) call the current version.\r
1355 */\r
1356 Manager.registerPostprocessor('deprecated', function(name, Class, data) {\r
1357 //<debug>\r
1358 Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#deprecated', arguments);\r
1359 //</debug>\r
1360\r
1361 // may already have an instance here in the case of singleton\r
1362 var target = Class.isInstance ? Class.self : Class;\r
1363 target.addDeprecations(data.deprecated);\r
1364\r
1365 delete target.prototype.deprecated;\r
1366 });\r
1367\r
1368 Ext.apply(Ext, {\r
1369 /**\r
1370 * Instantiate a class by either full name, alias or alternate name.\r
1371 *\r
1372 * If {@link Ext.Loader} is {@link Ext.Loader#setConfig enabled} and the class has\r
1373 * not been defined yet, it will attempt to load the class via synchronous loading.\r
1374 *\r
1375 * For example, all these three lines return the same result:\r
1376 *\r
1377 * // xtype\r
1378 * var window = Ext.create({\r
1379 * xtype: 'window',\r
1380 * width: 600,\r
1381 * height: 800,\r
1382 * ...\r
1383 * });\r
1384 *\r
1385 * // alias\r
1386 * var window = Ext.create('widget.window', {\r
1387 * width: 600,\r
1388 * height: 800,\r
1389 * ...\r
1390 * });\r
1391 *\r
1392 * // alternate name\r
1393 * var window = Ext.create('Ext.Window', {\r
1394 * width: 600,\r
1395 * height: 800,\r
1396 * ...\r
1397 * });\r
1398 *\r
1399 * // full class name\r
1400 * var window = Ext.create('Ext.window.Window', {\r
1401 * width: 600,\r
1402 * height: 800,\r
1403 * ...\r
1404 * });\r
1405 *\r
1406 * // single object with xclass property:\r
1407 * var window = Ext.create({\r
1408 * xclass: 'Ext.window.Window', // any valid value for 'name' (above)\r
1409 * width: 600,\r
1410 * height: 800,\r
1411 * ...\r
1412 * });\r
1413 *\r
1414 * @param {String} [name] The class name or alias. Can be specified as `xclass`\r
1415 * property if only one object parameter is specified.\r
1416 * @param {Object...} [args] Additional arguments after the name will be passed to\r
1417 * the class' constructor.\r
1418 * @return {Object} instance\r
1419 * @member Ext\r
1420 * @method create\r
1421 */\r
1422 create: function () {\r
1423 var name = arguments[0],\r
1424 nameType = typeof name,\r
1425 args = arraySlice.call(arguments, 1),\r
1426 cls;\r
1427\r
1428 if (nameType === 'function') {\r
1429 cls = name;\r
1430 } else {\r
1431 if (nameType !== 'string' && args.length === 0) {\r
1432 args = [name];\r
1433 if (!(name = name.xclass)) {\r
1434 name = args[0].xtype;\r
1435 if (name) {\r
1436 name = 'widget.' + name;\r
1437 }\r
1438 }\r
1439 }\r
1440\r
1441 //<debug>\r
1442 if (typeof name !== 'string' || name.length < 1) {\r
1443 throw new Error("[Ext.create] Invalid class name or alias '" + name +\r
1444 "' specified, must be a non-empty string");\r
1445 }\r
1446 //</debug>\r
1447\r
1448 name = Manager.resolveName(name);\r
1449 cls = Manager.get(name);\r
1450 }\r
1451\r
1452 // Still not existing at this point, try to load it via synchronous mode as the last resort\r
1453 if (!cls) {\r
1454 //<debug>\r
1455 //<if nonBrowser>\r
1456 !isNonBrowser &&\r
1457 //</if>\r
1458 Ext.log.warn("[Ext.Loader] Synchronously loading '" + name + "'; consider adding " +\r
1459 "Ext.require('" + name + "') above Ext.onReady");\r
1460 //</debug>\r
1461\r
1462 Ext.syncRequire(name);\r
1463\r
1464 cls = Manager.get(name);\r
1465 }\r
1466\r
1467 //<debug>\r
1468 if (!cls) {\r
1469 throw new Error("[Ext.create] Unrecognized class name / alias: " + name);\r
1470 }\r
1471\r
1472 if (typeof cls !== 'function') {\r
1473 throw new Error("[Ext.create] Singleton '" + name + "' cannot be instantiated.");\r
1474 }\r
1475 //</debug>\r
1476\r
1477 return Manager.getInstantiator(args.length)(cls, args);\r
1478 },\r
1479\r
1480 /**\r
1481 * Convenient shorthand to create a widget by its xtype or a config object.\r
1482 *\r
1483 * var button = Ext.widget('button'); // Equivalent to Ext.create('widget.button');\r
1484 *\r
1485 * var panel = Ext.widget('panel', { // Equivalent to Ext.create('widget.panel')\r
1486 * title: 'Panel'\r
1487 * });\r
1488 *\r
1489 * var grid = Ext.widget({\r
1490 * xtype: 'grid',\r
1491 * ...\r
1492 * });\r
1493 *\r
1494 * If a {@link Ext.Component component} instance is passed, it is simply returned.\r
1495 *\r
1496 * @member Ext\r
1497 * @param {String} [name] The xtype of the widget to create.\r
1498 * @param {Object} [config] The configuration object for the widget constructor.\r
1499 * @return {Object} The widget instance\r
1500 */\r
1501 widget: function(name, config) {\r
1502 // forms:\r
1503 // 1: (xtype)\r
1504 // 2: (xtype, config)\r
1505 // 3: (config)\r
1506 // 4: (xtype, component)\r
1507 // 5: (component)\r
1508 // \r
1509 var xtype = name,\r
1510 alias, className, T;\r
1511\r
1512 if (typeof xtype !== 'string') { // if (form 3 or 5)\r
1513 // first arg is config or component\r
1514 config = name; // arguments[0]\r
1515 xtype = config.xtype;\r
1516 className = config.xclass;\r
1517 } else {\r
1518 config = config || {};\r
1519 }\r
1520\r
1521 if (config.isComponent) {\r
1522 return config;\r
1523 }\r
1524\r
1525 if (!className) {\r
1526 alias = 'widget.' + xtype;\r
1527 className = Manager.getNameByAlias(alias);\r
1528 }\r
1529\r
1530 // this is needed to support demand loading of the class\r
1531 if (className) {\r
1532 T = Manager.get(className);\r
1533 }\r
1534\r
1535 if (!T) {\r
1536 return Ext.create(className || alias, config);\r
1537 }\r
1538 return new T(config);\r
1539 },\r
1540\r
1541 /**\r
1542 * @inheritdoc Ext.ClassManager#instantiateByAlias\r
1543 * @member Ext\r
1544 * @method createByAlias\r
1545 */\r
1546 createByAlias: alias(Manager, 'instantiateByAlias'),\r
1547\r
1548 /**\r
1549 * Defines a class or override. A basic class is defined like this:\r
1550 *\r
1551 * Ext.define('My.awesome.Class', {\r
1552 * someProperty: 'something',\r
1553 *\r
1554 * someMethod: function(s) {\r
1555 * alert(s + this.someProperty);\r
1556 * }\r
1557 *\r
1558 * ...\r
1559 * });\r
1560 *\r
1561 * var obj = new My.awesome.Class();\r
1562 *\r
1563 * obj.someMethod('Say '); // alerts 'Say something'\r
1564 *\r
1565 * To create an anonymous class, pass `null` for the `className`:\r
1566 *\r
1567 * Ext.define(null, {\r
1568 * constructor: function () {\r
1569 * // ...\r
1570 * }\r
1571 * });\r
1572 *\r
1573 * In some cases, it is helpful to create a nested scope to contain some private\r
1574 * properties. The best way to do this is to pass a function instead of an object\r
1575 * as the second parameter. This function will be called to produce the class\r
1576 * body:\r
1577 *\r
1578 * Ext.define('MyApp.foo.Bar', function () {\r
1579 * var id = 0;\r
1580 *\r
1581 * return {\r
1582 * nextId: function () {\r
1583 * return ++id;\r
1584 * }\r
1585 * };\r
1586 * });\r
1587 * \r
1588 * _Note_ that when using override, the above syntax will not override successfully, because\r
1589 * the passed function would need to be executed first to determine whether or not the result \r
1590 * is an override or defining a new object. As such, an alternative syntax that immediately \r
1591 * invokes the function can be used:\r
1592 * \r
1593 * Ext.define('MyApp.override.BaseOverride', function () {\r
1594 * var counter = 0;\r
1595 *\r
1596 * return {\r
1597 * override: 'Ext.Component',\r
1598 * logId: function () {\r
1599 * console.log(++counter, this.id);\r
1600 * }\r
1601 * };\r
1602 * }());\r
1603 * \r
1604 *\r
1605 * When using this form of `Ext.define`, the function is passed a reference to its\r
1606 * class. This can be used as an efficient way to access any static properties you\r
1607 * may have:\r
1608 *\r
1609 * Ext.define('MyApp.foo.Bar', function (Bar) {\r
1610 * return {\r
1611 * statics: {\r
1612 * staticMethod: function () {\r
1613 * // ...\r
1614 * }\r
1615 * },\r
1616 *\r
1617 * method: function () {\r
1618 * return Bar.staticMethod();\r
1619 * }\r
1620 * };\r
1621 * });\r
1622 *\r
1623 * To define an override, include the `override` property. The content of an\r
1624 * override is aggregated with the specified class in order to extend or modify\r
1625 * that class. This can be as simple as setting default property values or it can\r
1626 * extend and/or replace methods. This can also extend the statics of the class.\r
1627 *\r
1628 * One use for an override is to break a large class into manageable pieces.\r
1629 *\r
1630 * // File: /src/app/Panel.js\r
1631 *\r
1632 * Ext.define('My.app.Panel', {\r
1633 * extend: 'Ext.panel.Panel',\r
1634 * requires: [\r
1635 * 'My.app.PanelPart2',\r
1636 * 'My.app.PanelPart3'\r
1637 * ]\r
1638 *\r
1639 * constructor: function (config) {\r
1640 * this.callParent(arguments); // calls Ext.panel.Panel's constructor\r
1641 * //...\r
1642 * },\r
1643 *\r
1644 * statics: {\r
1645 * method: function () {\r
1646 * return 'abc';\r
1647 * }\r
1648 * }\r
1649 * });\r
1650 *\r
1651 * // File: /src/app/PanelPart2.js\r
1652 * Ext.define('My.app.PanelPart2', {\r
1653 * override: 'My.app.Panel',\r
1654 *\r
1655 * constructor: function (config) {\r
1656 * this.callParent(arguments); // calls My.app.Panel's constructor\r
1657 * //...\r
1658 * }\r
1659 * });\r
1660 *\r
1661 * Another use of overrides is to provide optional parts of classes that can be\r
1662 * independently required. In this case, the class may even be unaware of the\r
1663 * override altogether.\r
1664 *\r
1665 * Ext.define('My.ux.CoolTip', {\r
1666 * override: 'Ext.tip.ToolTip',\r
1667 *\r
1668 * constructor: function (config) {\r
1669 * this.callParent(arguments); // calls Ext.tip.ToolTip's constructor\r
1670 * //...\r
1671 * }\r
1672 * });\r
1673 *\r
1674 * The above override can now be required as normal.\r
1675 *\r
1676 * Ext.define('My.app.App', {\r
1677 * requires: [\r
1678 * 'My.ux.CoolTip'\r
1679 * ]\r
1680 * });\r
1681 *\r
1682 * Overrides can also contain statics, inheritableStatics, or privates:\r
1683 *\r
1684 * Ext.define('My.app.BarMod', {\r
1685 * override: 'Ext.foo.Bar',\r
1686 *\r
1687 * statics: {\r
1688 * method: function (x) {\r
1689 * return this.callParent([x * 2]); // call Ext.foo.Bar.method\r
1690 * }\r
1691 * }\r
1692 * });\r
1693 * \r
1694 * Starting in version 4.2.2, overrides can declare their `compatibility` based\r
1695 * on the framework version or on versions of other packages. For details on the\r
1696 * syntax and options for these checks, see `Ext.checkVersion`.\r
1697 * \r
1698 * The simplest use case is to test framework version for compatibility:\r
1699 * \r
1700 * Ext.define('App.overrides.grid.Panel', {\r
1701 * override: 'Ext.grid.Panel',\r
1702 *\r
1703 * compatibility: '4.2.2', // only if framework version is 4.2.2\r
1704 *\r
1705 * //...\r
1706 * });\r
1707 * \r
1708 * An array is treated as an OR, so if any specs match, the override is\r
1709 * compatible.\r
1710 * \r
1711 * Ext.define('App.overrides.some.Thing', {\r
1712 * override: 'Foo.some.Thing',\r
1713 *\r
1714 * compatibility: [\r
1715 * '4.2.2',\r
1716 * 'foo@1.0.1-1.0.2'\r
1717 * ],\r
1718 *\r
1719 * //...\r
1720 * });\r
1721 * \r
1722 * To require that all specifications match, an object can be provided:\r
1723 * \r
1724 * Ext.define('App.overrides.some.Thing', {\r
1725 * override: 'Foo.some.Thing',\r
1726 *\r
1727 * compatibility: {\r
1728 * and: [\r
1729 * '4.2.2',\r
1730 * 'foo@1.0.1-1.0.2'\r
1731 * ]\r
1732 * },\r
1733 *\r
1734 * //...\r
1735 * });\r
1736 * \r
1737 * Because the object form is just a recursive check, these can be nested:\r
1738 * \r
1739 * Ext.define('App.overrides.some.Thing', {\r
1740 * override: 'Foo.some.Thing',\r
1741 *\r
1742 * compatibility: {\r
1743 * and: [\r
1744 * '4.2.2', // exactly version 4.2.2 of the framework *AND*\r
1745 * {\r
1746 * // either (or both) of these package specs:\r
1747 * or: [\r
1748 * 'foo@1.0.1-1.0.2',\r
1749 * 'bar@3.0+'\r
1750 * ]\r
1751 * }\r
1752 * ]\r
1753 * },\r
1754 *\r
1755 * //...\r
1756 * });\r
1757 *\r
1758 * IMPORTANT: An override is only included in a build if the class it overrides is\r
1759 * required. Otherwise, the override, like the target class, is not included. In\r
1760 * Sencha Cmd v4, the `compatibility` declaration can likewise be used to remove\r
1761 * incompatible overrides from a build.\r
1762 *\r
1763 * @param {String} className The class name to create in string dot-namespaced format, for example:\r
1764 * 'My.very.awesome.Class', 'FeedViewer.plugin.CoolPager'\r
1765 * It is highly recommended to follow this simple convention:\r
1766 * - The root and the class name are 'CamelCased'\r
1767 * - Everything else is lower-cased\r
1768 * Pass `null` to create an anonymous class.\r
1769 * @param {Object} data The key - value pairs of properties to apply to this class. Property names can be of any valid\r
1770 * strings, except those in the reserved listed below:\r
1771 * \r
1772 * - {@link Ext.Class#cfg-alias alias}\r
1773 * - {@link Ext.Class#cfg-alternateClassName alternateClassName}\r
1774 * - {@link Ext.Class#cfg-cachedConfig cachedConfig}\r
1775 * - {@link Ext.Class#cfg-config config}\r
1776 * - {@link Ext.Class#cfg-extend extend}\r
1777 * - {@link Ext.Class#cfg-inheritableStatics inheritableStatics}\r
1778 * - {@link Ext.Class#cfg-mixins mixins}\r
1779 * - {@link Ext.Class#cfg-override override}\r
1780 * - {@link Ext.Class#cfg-platformConfig platformConfig}\r
1781 * - {@link Ext.Class#cfg-privates privates}\r
1782 * - {@link Ext.Class#cfg-requires requires}\r
1783 * - `self`\r
1784 * - {@link Ext.Class#cfg-singleton singleton}\r
1785 * - {@link Ext.Class#cfg-statics statics}\r
1786 * - {@link Ext.Class#cfg-uses uses}\r
1787 * - {@link Ext.Class#cfg-xtype xtype} (for {@link Ext.Component Components} only)\r
1788 *\r
1789 * @param {Function} [createdFn] Callback to execute after the class is created, the execution scope of which\r
1790 * (`this`) will be the newly created class itself.\r
1791 * @return {Ext.Base}\r
1792 * @member Ext\r
1793 */\r
1794 define: function (className, data, createdFn) {\r
1795 //<debug>\r
1796 Ext.classSystemMonitor && Ext.classSystemMonitor(className, 'ClassManager#define', arguments);\r
1797 //</debug>\r
1798 \r
1799 if (data.override) {\r
1800 Manager.classState[className] = 20;\r
1801 return Manager.createOverride.apply(Manager, arguments);\r
1802 }\r
1803\r
1804 Manager.classState[className] = 10;\r
1805 return Manager.create.apply(Manager, arguments);\r
1806 },\r
1807\r
1808 /**\r
1809 * Undefines a class defined using the #define method. Typically used\r
1810 * for unit testing where setting up and tearing down a class multiple\r
1811 * times is required. For example:\r
1812 * \r
1813 * // define a class\r
1814 * Ext.define('Foo', {\r
1815 * ...\r
1816 * });\r
1817 * \r
1818 * // run test\r
1819 * \r
1820 * // undefine the class\r
1821 * Ext.undefine('Foo');\r
1822 * @param {String} className The class name to undefine in string dot-namespaced format.\r
1823 * @private\r
1824 */\r
1825 undefine: function(className) {\r
1826 //<debug>\r
1827 Ext.classSystemMonitor && Ext.classSystemMonitor(className, 'Ext.ClassManager#undefine', arguments);\r
1828 //</debug>\r
1829 \r
1830 var classes = Manager.classes;\r
1831\r
1832 delete classes[className];\r
1833 delete Manager.existCache[className];\r
1834 delete Manager.classState[className];\r
1835\r
1836 Manager.removeName(className);\r
1837\r
1838 var entry = Manager.getNamespaceEntry(className),\r
1839 scope = entry.parent ? Manager.lookupName(entry.parent, false) : Ext.global;\r
1840\r
1841 if (scope) {\r
1842 // Old IE blows up on attempt to delete window property\r
1843 try {\r
1844 delete scope[entry.name];\r
1845 }\r
1846 catch (e) {\r
1847 scope[entry.name] = undefined;\r
1848 }\r
1849 }\r
1850 },\r
1851\r
1852 /**\r
1853 * @inheritdoc Ext.ClassManager#getName\r
1854 * @member Ext\r
1855 * @method getClassName\r
1856 */\r
1857 getClassName: alias(Manager, 'getName'),\r
1858\r
1859 /**\r
1860 * Returns the displayName property or className or object. When all else fails, returns "Anonymous".\r
1861 * @param {Object} object\r
1862 * @return {String}\r
1863 */\r
1864 getDisplayName: function(object) {\r
1865 if (object) {\r
1866 if (object.displayName) {\r
1867 return object.displayName;\r
1868 }\r
1869\r
1870 if (object.$name && object.$class) {\r
1871 return Ext.getClassName(object.$class) + '#' + object.$name;\r
1872 }\r
1873\r
1874 if (object.$className) {\r
1875 return object.$className;\r
1876 }\r
1877 }\r
1878\r
1879 return 'Anonymous';\r
1880 },\r
1881\r
1882 /**\r
1883 * @inheritdoc Ext.ClassManager#getClass\r
1884 * @member Ext\r
1885 * @method getClass\r
1886 */\r
1887 getClass: alias(Manager, 'getClass'),\r
1888\r
1889 /**\r
1890 * Creates namespaces to be used for scoping variables and classes so that they are not global.\r
1891 * Specifying the last node of a namespace implicitly creates all other nodes. Usage:\r
1892 *\r
1893 * Ext.namespace('Company', 'Company.data');\r
1894 *\r
1895 * // equivalent and preferable to the above syntax\r
1896 * Ext.ns('Company.data');\r
1897 *\r
1898 * Company.Widget = function() { ... };\r
1899 *\r
1900 * Company.data.CustomStore = function(config) { ... };\r
1901 *\r
1902 * @param {String...} namespaces\r
1903 * @return {Object} The (last) namespace object created.\r
1904 * @member Ext\r
1905 * @method namespace\r
1906 */\r
1907 namespace: function () {\r
1908 var root = global,\r
1909 i;\r
1910\r
1911 for (i = arguments.length; i-- > 0; ) {\r
1912 root = Manager.lookupName(arguments[i], true);\r
1913 }\r
1914\r
1915 return root;\r
1916 }\r
1917 });\r
1918\r
1919 /**\r
1920 * This function registers top-level (root) namespaces. This is needed for "sandbox"\r
1921 * builds.\r
1922 *\r
1923 * Ext.addRootNamespaces({\r
1924 * MyApp: MyApp,\r
1925 * Common: Common\r
1926 * });\r
1927 *\r
1928 * In the above example, `MyApp` and `Common` are top-level namespaces that happen\r
1929 * to also be included in the sandbox closure. Something like this:\r
1930 *\r
1931 * (function(Ext) {\r
1932 *\r
1933 * Ext.sandboxName = 'Ext6';\r
1934 * Ext.isSandboxed = true;\r
1935 * Ext.buildSettings = { baseCSSPrefix: "x6-", scopeResetCSS: true };\r
1936 *\r
1937 * var MyApp = MyApp || {};\r
1938 * Ext.addRootNamespaces({ MyApp: MyApp );\r
1939 *\r
1940 * ... normal app.js goes here ...\r
1941 *\r
1942 * })(this.Ext6 || (this.Ext6 = {}));\r
1943 *\r
1944 * The sandbox wrapper around the normally built `app.js` content has to take care\r
1945 * of introducing top-level namespaces as well as call this method.\r
1946 *\r
1947 * @param {Object} namespaces\r
1948 * @method addRootNamespaces\r
1949 * @member Ext\r
1950 * @since 6.0.0\r
1951 * @private\r
1952 */\r
1953 Ext.addRootNamespaces = Manager.addRootNamespaces;\r
1954\r
1955 /**\r
1956 * Old name for {@link Ext#widget}.\r
1957 * @deprecated Use {@link Ext#widget} instead.\r
1958 * @method createWidget\r
1959 * @member Ext\r
1960 * @private\r
1961 */\r
1962 Ext.createWidget = Ext.widget;\r
1963\r
1964 /**\r
1965 * Convenient alias for {@link Ext#namespace Ext.namespace}.\r
1966 * @inheritdoc Ext#namespace\r
1967 * @member Ext\r
1968 * @method ns\r
1969 */\r
1970 Ext.ns = Ext.namespace;\r
1971\r
1972 Class.registerPreprocessor('className', function(cls, data) {\r
1973 if ('$className' in data) {\r
1974 cls.$className = data.$className;\r
1975 //<debug>\r
1976 cls.displayName = cls.$className;\r
1977 //</debug>\r
1978 }\r
1979 \r
1980 //<debug>\r
1981 Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.ClassManager#classNamePreprocessor', arguments);\r
1982 //</debug>\r
1983 }, true, 'first');\r
1984\r
1985 Class.registerPreprocessor('alias', function(cls, data) {\r
1986 //<debug>\r
1987 Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.ClassManager#aliasPreprocessor', arguments);\r
1988 //</debug>\r
1989 \r
1990 var prototype = cls.prototype,\r
1991 xtypes = arrayFrom(data.xtype),\r
1992 aliases = arrayFrom(data.alias),\r
1993 widgetPrefix = 'widget.',\r
1994 widgetPrefixLength = widgetPrefix.length,\r
1995 xtypesChain = Array.prototype.slice.call(prototype.xtypesChain || []),\r
1996 xtypesMap = Ext.merge({}, prototype.xtypesMap || {}),\r
1997 i, ln, alias, xtype;\r
1998\r
1999 for (i = 0,ln = aliases.length; i < ln; i++) {\r
2000 alias = aliases[i];\r
2001\r
2002 //<debug>\r
2003 if (typeof alias !== 'string' || alias.length < 1) {\r
2004 throw new Error("[Ext.define] Invalid alias of: '" + alias + "' for class: '" + name + "'; must be a valid string");\r
2005 }\r
2006 //</debug>\r
2007\r
2008 if (alias.substring(0, widgetPrefixLength) === widgetPrefix) {\r
2009 xtype = alias.substring(widgetPrefixLength);\r
2010 Ext.Array.include(xtypes, xtype);\r
2011 }\r
2012 }\r
2013\r
2014 cls.xtype = data.xtype = xtypes[0];\r
2015 data.xtypes = xtypes;\r
2016\r
2017 for (i = 0,ln = xtypes.length; i < ln; i++) {\r
2018 xtype = xtypes[i];\r
2019\r
2020 if (!xtypesMap[xtype]) {\r
2021 xtypesMap[xtype] = true;\r
2022 xtypesChain.push(xtype);\r
2023 }\r
2024 }\r
2025\r
2026 data.xtypesChain = xtypesChain;\r
2027 data.xtypesMap = xtypesMap;\r
2028\r
2029 Ext.Function.interceptAfter(data, 'onClassCreated', function() {\r
2030 //<debug>\r
2031 Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.ClassManager#aliasPreprocessor#afterClassCreated', arguments);\r
2032 //</debug>\r
2033 \r
2034 var mixins = prototype.mixins,\r
2035 key, mixin;\r
2036\r
2037 for (key in mixins) {\r
2038 if (mixins.hasOwnProperty(key)) {\r
2039 mixin = mixins[key];\r
2040\r
2041 xtypes = mixin.xtypes;\r
2042\r
2043 if (xtypes) {\r
2044 for (i = 0,ln = xtypes.length; i < ln; i++) {\r
2045 xtype = xtypes[i];\r
2046\r
2047 if (!xtypesMap[xtype]) {\r
2048 xtypesMap[xtype] = true;\r
2049 xtypesChain.push(xtype);\r
2050 }\r
2051 }\r
2052 }\r
2053 }\r
2054 }\r
2055 });\r
2056\r
2057 for (i = 0,ln = xtypes.length; i < ln; i++) {\r
2058 xtype = xtypes[i];\r
2059\r
2060 //<debug>\r
2061 if (typeof xtype !== 'string' || xtype.length < 1) {\r
2062 throw new Error("[Ext.define] Invalid xtype of: '" + xtype + "' for class: '" + name + "'; must be a valid non-empty string");\r
2063 }\r
2064 //</debug>\r
2065\r
2066 Ext.Array.include(aliases, widgetPrefix + xtype);\r
2067 }\r
2068\r
2069 data.alias = aliases;\r
2070\r
2071 }, ['xtype', 'alias']);\r
2072\r
2073 // load the cmd-5 style app manifest metadata now, if available...\r
2074 if (Ext.manifest) {\r
2075 var manifest = Ext.manifest,\r
2076 classes = manifest.classes,\r
2077 paths = manifest.paths,\r
2078 aliases = {},\r
2079 alternates = {},\r
2080 className, obj, name, path, baseUrl;\r
2081\r
2082 if (paths) {\r
2083 // if the manifest paths were calculated as relative to the\r
2084 // bootstrap file, then we need to prepend Boot.baseUrl to the\r
2085 // paths before processing\r
2086 if (manifest.bootRelative) {\r
2087 baseUrl = Ext.Boot.baseUrl;\r
2088 for (path in paths) {\r
2089 if (paths.hasOwnProperty(path)) {\r
2090 paths[path] = baseUrl + paths[path];\r
2091 }\r
2092 }\r
2093 }\r
2094 Manager.setPath(paths);\r
2095 }\r
2096\r
2097 if (classes) {\r
2098 for (className in classes) {\r
2099 alternates[className] = [];\r
2100 aliases[className] = [];\r
2101 obj = classes[className];\r
2102 if (obj.alias) {\r
2103 aliases[className] = obj.alias;\r
2104 }\r
2105 if (obj.alternates) {\r
2106 alternates[className] = obj.alternates;\r
2107 }\r
2108 }\r
2109 }\r
2110\r
2111 Manager.addAlias(aliases);\r
2112 Manager.addAlternate(alternates);\r
2113 }\r
2114\r
2115 return Manager;\r
2116}(Ext.Class, Ext.Function.alias, Array.prototype.slice, Ext.Array.from, Ext.global));\r