Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / docs / source / ClassManager.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-ClassManager'>/**
19 </span> * @author Jacky Nguyen &lt;jacky@sencha.com&gt;
20  * @docauthor Jacky Nguyen &lt;jacky@sencha.com&gt;
21  * @class Ext.ClassManager
22  *
23  * Ext.ClassManager manages all classes and handles mapping from string class name to
24  * actual class objects throughout the whole framework. It is not generally accessed directly, rather through
25  * these convenient shorthands:
26  *
27  * - {@link Ext#define Ext.define}
28  * - {@link Ext#create Ext.create}
29  * - {@link Ext#widget Ext.widget}
30  * - {@link Ext#getClass Ext.getClass}
31  * - {@link Ext#getClassName Ext.getClassName}
32  *
33  * @singleton
34  */
35 (function(Class, alias) {
36
37     var slice = Array.prototype.slice;
38
39     var Manager = Ext.ClassManager = {
40
41 <span id='Ext-ClassManager-property-classes'>        /**
42 </span>         * @property {Object} classes
43          * All classes which were defined through the ClassManager. Keys are the
44          * name of the classes and the values are references to the classes.
45          * @private
46          */
47         classes: {},
48
49 <span id='Ext-ClassManager-property-existCache'>        /**
50 </span>         * @private
51          */
52         existCache: {},
53
54 <span id='Ext-ClassManager-property-namespaceRewrites'>        /**
55 </span>         * @private
56          */
57         namespaceRewrites: [{
58             from: 'Ext.',
59             to: Ext
60         }],
61
62 <span id='Ext-ClassManager-property-maps'>        /**
63 </span>         * @private
64          */
65         maps: {
66             alternateToName: {},
67             aliasToName: {},
68             nameToAliases: {}
69         },
70
71 <span id='Ext-ClassManager-property-enableNamespaceParseCache'>        /** @private */
72 </span>        enableNamespaceParseCache: true,
73
74 <span id='Ext-ClassManager-property-namespaceParseCache'>        /** @private */
75 </span>        namespaceParseCache: {},
76
77 <span id='Ext-ClassManager-property-instantiators'>        /** @private */
78 </span>        instantiators: [],
79
80         //&lt;debug&gt;
81 <span id='Ext-ClassManager-property-instantiationCounts'>        /** @private */
82 </span>        instantiationCounts: {},
83         //&lt;/debug&gt;
84
85 <span id='Ext-ClassManager-method-isCreated'>        /**
86 </span>         * Checks if a class has already been created.
87          *
88          * @param {String} className
89          * @return {Boolean} exist
90          */
91         isCreated: function(className) {
92             var i, ln, part, root, parts;
93
94             //&lt;debug error&gt;
95             if (typeof className !== 'string' || className.length &lt; 1) {
96                 Ext.Error.raise({
97                     sourceClass: &quot;Ext.ClassManager&quot;,
98                     sourceMethod: &quot;exist&quot;,
99                     msg: &quot;Invalid classname, must be a string and must not be empty&quot;
100                 });
101             }
102             //&lt;/debug&gt;
103
104             if (this.classes.hasOwnProperty(className) || this.existCache.hasOwnProperty(className)) {
105                 return true;
106             }
107
108             root = Ext.global;
109             parts = this.parseNamespace(className);
110
111             for (i = 0, ln = parts.length; i &lt; ln; i++) {
112                 part = parts[i];
113
114                 if (typeof part !== 'string') {
115                     root = part;
116                 } else {
117                     if (!root || !root[part]) {
118                         return false;
119                     }
120
121                     root = root[part];
122                 }
123             }
124
125             Ext.Loader.historyPush(className);
126
127             this.existCache[className] = true;
128
129             return true;
130         },
131
132 <span id='Ext-ClassManager-method-parseNamespace'>        /**
133 </span>         * Supports namespace rewriting
134          * @private
135          */
136         parseNamespace: function(namespace) {
137             //&lt;debug error&gt;
138             if (typeof namespace !== 'string') {
139                 Ext.Error.raise({
140                     sourceClass: &quot;Ext.ClassManager&quot;,
141                     sourceMethod: &quot;parseNamespace&quot;,
142                     msg: &quot;Invalid namespace, must be a string&quot;
143                 });
144             }
145             //&lt;/debug&gt;
146
147             var cache = this.namespaceParseCache;
148
149             if (this.enableNamespaceParseCache) {
150                 if (cache.hasOwnProperty(namespace)) {
151                     return cache[namespace];
152                 }
153             }
154
155             var parts = [],
156                 rewrites = this.namespaceRewrites,
157                 rewrite, from, to, i, ln, root = Ext.global;
158
159             for (i = 0, ln = rewrites.length; i &lt; ln; i++) {
160                 rewrite = rewrites[i];
161                 from = rewrite.from;
162                 to = rewrite.to;
163
164                 if (namespace === from || namespace.substring(0, from.length) === from) {
165                     namespace = namespace.substring(from.length);
166
167                     if (typeof to !== 'string') {
168                         root = to;
169                     } else {
170                         parts = parts.concat(to.split('.'));
171                     }
172
173                     break;
174                 }
175             }
176
177             parts.push(root);
178
179             parts = parts.concat(namespace.split('.'));
180
181             if (this.enableNamespaceParseCache) {
182                 cache[namespace] = parts;
183             }
184
185             return parts;
186         },
187
188 <span id='Ext-ClassManager-method-setNamespace'>        /**
189 </span>         * Creates a namespace and assign the `value` to the created object
190          *
191          *     Ext.ClassManager.setNamespace('MyCompany.pkg.Example', someObject);
192          *
193          *     alert(MyCompany.pkg.Example === someObject); // alerts true
194          *
195          * @param {String} name
196          * @param {Mixed} value
197          */
198         setNamespace: function(name, value) {
199             var root = Ext.global,
200                 parts = this.parseNamespace(name),
201                 leaf = parts.pop(),
202                 i, ln, part;
203
204             for (i = 0, ln = parts.length; i &lt; ln; i++) {
205                 part = parts[i];
206
207                 if (typeof part !== 'string') {
208                     root = part;
209                 } else {
210                     if (!root[part]) {
211                         root[part] = {};
212                     }
213
214                     root = root[part];
215                 }
216             }
217
218             root[leaf] = value;
219
220             return root[leaf];
221         },
222
223 <span id='Ext-ClassManager-method-createNamespaces'>        /**
224 </span>         * The new Ext.ns, supports namespace rewriting
225          * @private
226          */
227         createNamespaces: function() {
228             var root = Ext.global,
229                 parts, part, i, j, ln, subLn;
230
231             for (i = 0, ln = arguments.length; i &lt; ln; i++) {
232                 parts = this.parseNamespace(arguments[i]);
233
234                 for (j = 0, subLn = parts.length; j &lt; subLn; j++) {
235                     part = parts[j];
236
237                     if (typeof part !== 'string') {
238                         root = part;
239                     } else {
240                         if (!root[part]) {
241                             root[part] = {};
242                         }
243
244                         root = root[part];
245                     }
246                 }
247             }
248
249             return root;
250         },
251
252 <span id='Ext-ClassManager-method-set'>        /**
253 </span>         * Sets a name reference to a class.
254          *
255          * @param {String} name
256          * @param {Object} value
257          * @return {Ext.ClassManager} this
258          */
259         set: function(name, value) {
260             var targetName = this.getName(value);
261
262             this.classes[name] = this.setNamespace(name, value);
263
264             if (targetName &amp;&amp; targetName !== name) {
265                 this.maps.alternateToName[name] = targetName;
266             }
267
268             return this;
269         },
270
271 <span id='Ext-ClassManager-method-get'>        /**
272 </span>         * Retrieve a class by its name.
273          *
274          * @param {String} name
275          * @return {Class} class
276          */
277         get: function(name) {
278             if (this.classes.hasOwnProperty(name)) {
279                 return this.classes[name];
280             }
281
282             var root = Ext.global,
283                 parts = this.parseNamespace(name),
284                 part, i, ln;
285
286             for (i = 0, ln = parts.length; i &lt; ln; i++) {
287                 part = parts[i];
288
289                 if (typeof part !== 'string') {
290                     root = part;
291                 } else {
292                     if (!root || !root[part]) {
293                         return null;
294                     }
295
296                     root = root[part];
297                 }
298             }
299
300             return root;
301         },
302
303 <span id='Ext-ClassManager-method-setAlias'>        /**
304 </span>         * Register the alias for a class.
305          *
306          * @param {Class/String} cls a reference to a class or a className
307          * @param {String} alias Alias to use when referring to this class
308          */
309         setAlias: function(cls, alias) {
310             var aliasToNameMap = this.maps.aliasToName,
311                 nameToAliasesMap = this.maps.nameToAliases,
312                 className;
313
314             if (typeof cls === 'string') {
315                 className = cls;
316             } else {
317                 className = this.getName(cls);
318             }
319
320             if (alias &amp;&amp; aliasToNameMap[alias] !== className) {
321                 //&lt;debug info&gt;
322                 if (aliasToNameMap.hasOwnProperty(alias) &amp;&amp; Ext.isDefined(Ext.global.console)) {
323                     Ext.global.console.log(&quot;[Ext.ClassManager] Overriding existing alias: '&quot; + alias + &quot;' &quot; +
324                         &quot;of: '&quot; + aliasToNameMap[alias] + &quot;' with: '&quot; + className + &quot;'. Be sure it's intentional.&quot;);
325                 }
326                 //&lt;/debug&gt;
327
328                 aliasToNameMap[alias] = className;
329             }
330
331             if (!nameToAliasesMap[className]) {
332                 nameToAliasesMap[className] = [];
333             }
334
335             if (alias) {
336                 Ext.Array.include(nameToAliasesMap[className], alias);
337             }
338
339             return this;
340         },
341
342 <span id='Ext-ClassManager-method-getByAlias'>        /**
343 </span>         * Get a reference to the class by its alias.
344          *
345          * @param {String} alias
346          * @return {Class} class
347          */
348         getByAlias: function(alias) {
349             return this.get(this.getNameByAlias(alias));
350         },
351
352 <span id='Ext-ClassManager-method-getNameByAlias'>        /**
353 </span>         * Get the name of a class by its alias.
354          *
355          * @param {String} alias
356          * @return {String} className
357          */
358         getNameByAlias: function(alias) {
359             return this.maps.aliasToName[alias] || '';
360         },
361
362 <span id='Ext-ClassManager-method-getNameByAlternate'>        /**
363 </span>         * Get the name of a class by its alternate name.
364          *
365          * @param {String} alternate
366          * @return {String} className
367          */
368         getNameByAlternate: function(alternate) {
369             return this.maps.alternateToName[alternate] || '';
370         },
371
372 <span id='Ext-ClassManager-method-getAliasesByName'>        /**
373 </span>         * Get the aliases of a class by the class name
374          *
375          * @param {String} name
376          * @return {Array} aliases
377          */
378         getAliasesByName: function(name) {
379             return this.maps.nameToAliases[name] || [];
380         },
381
382 <span id='Ext-ClassManager-method-getName'>        /**
383 </span>         * Get the name of the class by its reference or its instance.
384          *
385          *     Ext.ClassManager.getName(Ext.Action); // returns &quot;Ext.Action&quot;
386          *
387          * {@link Ext#getClassName Ext.getClassName} is alias for {@link Ext.ClassManager#getName Ext.ClassManager.getName}.
388          *
389          * @param {Class/Object} object
390          * @return {String} className
391          */
392         getName: function(object) {
393             return object &amp;&amp; object.$className || '';
394         },
395
396 <span id='Ext-ClassManager-method-getClass'>        /**
397 </span>         * Get the class of the provided object; returns null if it's not an instance
398          * of any class created with Ext.define.
399          *
400          *     var component = new Ext.Component();
401          *
402          *     Ext.ClassManager.getClass(component); // returns Ext.Component
403          *
404          * {@link Ext#getClass Ext.getClass} is alias for {@link Ext.ClassManager#getClass Ext.ClassManager.getClass}.
405          *
406          * @param {Object} object
407          * @return {Class} class
408          */
409         getClass: function(object) {
410             return object &amp;&amp; object.self || null;
411         },
412
413 <span id='Ext-ClassManager-method-create'>        /**
414 </span>         * Defines a class.
415          *
416          *     Ext.ClassManager.create('My.awesome.Class', {
417          *         someProperty: 'something',
418          *         someMethod: function() { ... }
419          *         ...
420          *
421          *     }, function() {
422          *         alert('Created!');
423          *         alert(this === My.awesome.Class); // alerts true
424          *
425          *         var myInstance = new this();
426          *     });
427          *
428          * {@link Ext#define Ext.define} is alias for {@link Ext.ClassManager#create Ext.ClassManager.create}.
429          *
430          * @param {String} className The class name to create in string dot-namespaced format, for example:
431          * 'My.very.awesome.Class', 'FeedViewer.plugin.CoolPager'
432          * It is highly recommended to follow this simple convention:
433          *
434          * - The root and the class name are 'CamelCased'
435          * - Everything else is lower-cased
436          *
437          * @param {Object} data The key - value pairs of properties to apply to this class. Property names can be of any valid
438          * strings, except those in the reserved list below:
439          *
440          * - {@link Ext.Base#self self}
441          * - {@link Ext.Class#alias alias}
442          * - {@link Ext.Class#alternateClassName alternateClassName}
443          * - {@link Ext.Class#config config}
444          * - {@link Ext.Class#extend extend}
445          * - {@link Ext.Class#inheritableStatics inheritableStatics}
446          * - {@link Ext.Class#mixins mixins}
447          * - {@link Ext.Class#requires requires}
448          * - {@link Ext.Class#singleton singleton}
449          * - {@link Ext.Class#statics statics}
450          * - {@link Ext.Class#uses uses}
451          *
452          * @param {Function} createdFn Optional callback to execute after the class is created, the execution scope of which
453          * (`this`) will be the newly created class itself.
454          * @return {Ext.Base}
455          */
456         create: function(className, data, createdFn) {
457             var manager = this;
458
459             //&lt;debug error&gt;
460             if (typeof className !== 'string') {
461                 Ext.Error.raise({
462                     sourceClass: &quot;Ext&quot;,
463                     sourceMethod: &quot;define&quot;,
464                     msg: &quot;Invalid class name '&quot; + className + &quot;' specified, must be a non-empty string&quot;
465                 });
466             }
467             //&lt;/debug&gt;
468
469             data.$className = className;
470
471             return new Class(data, function() {
472                 var postprocessorStack = data.postprocessors || manager.defaultPostprocessors,
473                     registeredPostprocessors = manager.postprocessors,
474                     index = 0,
475                     postprocessors = [],
476                     postprocessor, postprocessors, process, i, ln;
477
478                 delete data.postprocessors;
479
480                 for (i = 0, ln = postprocessorStack.length; i &lt; ln; i++) {
481                     postprocessor = postprocessorStack[i];
482
483                     if (typeof postprocessor === 'string') {
484                         postprocessor = registeredPostprocessors[postprocessor];
485
486                         if (!postprocessor.always) {
487                             if (data[postprocessor.name] !== undefined) {
488                                 postprocessors.push(postprocessor.fn);
489                             }
490                         }
491                         else {
492                             postprocessors.push(postprocessor.fn);
493                         }
494                     }
495                     else {
496                         postprocessors.push(postprocessor);
497                     }
498                 }
499
500                 process = function(clsName, cls, clsData) {
501                     postprocessor = postprocessors[index++];
502
503                     if (!postprocessor) {
504                         manager.set(className, cls);
505
506                         Ext.Loader.historyPush(className);
507
508                         if (createdFn) {
509                             createdFn.call(cls, cls);
510                         }
511
512                         return;
513                     }
514
515                     if (postprocessor.call(this, clsName, cls, clsData, process) !== false) {
516                         process.apply(this, arguments);
517                     }
518                 };
519
520                 process.call(manager, className, this, data);
521             });
522         },
523
524 <span id='Ext-ClassManager-method-instantiateByAlias'>        /**
525 </span>         * Instantiate a class by its alias.
526          *
527          * If {@link Ext.Loader} is {@link Ext.Loader#setConfig enabled} and the class has not been defined yet, it will
528          * attempt to load the class via synchronous loading.
529          *
530          *     var window = Ext.ClassManager.instantiateByAlias('widget.window', { width: 600, height: 800, ... });
531          *
532          * {@link Ext#createByAlias Ext.createByAlias} is alias for {@link Ext.ClassManager#instantiateByAlias Ext.ClassManager.instantiateByAlias}.
533          *
534          * @param {String} alias
535          * @param {Mixed} args,... Additional arguments after the alias will be passed to the
536          * class constructor.
537          * @return {Object} instance
538          */
539         instantiateByAlias: function() {
540             var alias = arguments[0],
541                 args = slice.call(arguments),
542                 className = this.getNameByAlias(alias);
543
544             if (!className) {
545                 className = this.maps.aliasToName[alias];
546
547                 //&lt;debug error&gt;
548                 if (!className) {
549                     Ext.Error.raise({
550                         sourceClass: &quot;Ext&quot;,
551                         sourceMethod: &quot;createByAlias&quot;,
552                         msg: &quot;Cannot create an instance of unrecognized alias: &quot; + alias
553                     });
554                 }
555                 //&lt;/debug&gt;
556
557                 //&lt;debug warn&gt;
558                 if (Ext.global.console) {
559                     Ext.global.console.warn(&quot;[Ext.Loader] Synchronously loading '&quot; + className + &quot;'; consider adding &quot; +
560                          &quot;Ext.require('&quot; + alias + &quot;') above Ext.onReady&quot;);
561                 }
562                 //&lt;/debug&gt;
563
564                 Ext.syncRequire(className);
565             }
566
567             args[0] = className;
568
569             return this.instantiate.apply(this, args);
570         },
571
572 <span id='Ext-ClassManager-method-instantiate'>        /**
573 </span>         * Instantiate a class by either full name, alias or alternate name.
574          *
575          * If {@link Ext.Loader} is {@link Ext.Loader#setConfig enabled} and the class has not been defined yet, it will
576          * attempt to load the class via synchronous loading.
577          *
578          * For example, all these three lines return the same result:
579          *
580          *     // alias
581          *     var window = Ext.ClassManager.instantiate('widget.window', { width: 600, height: 800, ... });
582          *
583          *     // alternate name
584          *     var window = Ext.ClassManager.instantiate('Ext.Window', { width: 600, height: 800, ... });
585          *
586          *     // full class name
587          *     var window = Ext.ClassManager.instantiate('Ext.window.Window', { width: 600, height: 800, ... });
588          *
589          * {@link Ext#create Ext.create} is alias for {@link Ext.ClassManager#instantiate Ext.ClassManager.instantiate}.
590          *
591          * @param {String} name
592          * @param {Mixed} args,... Additional arguments after the name will be passed to the class' constructor.
593          * @return {Object} instance
594          */
595         instantiate: function() {
596             var name = arguments[0],
597                 args = slice.call(arguments, 1),
598                 alias = name,
599                 possibleName, cls;
600
601             if (typeof name !== 'function') {
602                 //&lt;debug error&gt;
603                 if ((typeof name !== 'string' || name.length &lt; 1)) {
604                     Ext.Error.raise({
605                         sourceClass: &quot;Ext&quot;,
606                         sourceMethod: &quot;create&quot;,
607                         msg: &quot;Invalid class name or alias '&quot; + name + &quot;' specified, must be a non-empty string&quot;
608                     });
609                 }
610                 //&lt;/debug&gt;
611
612                 cls = this.get(name);
613             }
614             else {
615                 cls = name;
616             }
617
618             // No record of this class name, it's possibly an alias, so look it up
619             if (!cls) {
620                 possibleName = this.getNameByAlias(name);
621
622                 if (possibleName) {
623                     name = possibleName;
624
625                     cls = this.get(name);
626                 }
627             }
628
629             // Still no record of this class name, it's possibly an alternate name, so look it up
630             if (!cls) {
631                 possibleName = this.getNameByAlternate(name);
632
633                 if (possibleName) {
634                     name = possibleName;
635
636                     cls = this.get(name);
637                 }
638             }
639
640             // Still not existing at this point, try to load it via synchronous mode as the last resort
641             if (!cls) {
642                 //&lt;debug warn&gt;
643                 if (Ext.global.console) {
644                     Ext.global.console.warn(&quot;[Ext.Loader] Synchronously loading '&quot; + name + &quot;'; consider adding &quot; +
645                          &quot;Ext.require('&quot; + ((possibleName) ? alias : name) + &quot;') above Ext.onReady&quot;);
646                 }
647                 //&lt;/debug&gt;
648
649                 Ext.syncRequire(name);
650
651                 cls = this.get(name);
652             }
653
654             //&lt;debug error&gt;
655             if (!cls) {
656                 Ext.Error.raise({
657                     sourceClass: &quot;Ext&quot;,
658                     sourceMethod: &quot;create&quot;,
659                     msg: &quot;Cannot create an instance of unrecognized class name / alias: &quot; + alias
660                 });
661             }
662
663             if (typeof cls !== 'function') {
664                 Ext.Error.raise({
665                     sourceClass: &quot;Ext&quot;,
666                     sourceMethod: &quot;create&quot;,
667                     msg: &quot;'&quot; + name + &quot;' is a singleton and cannot be instantiated&quot;
668                 });
669             }
670             //&lt;/debug&gt;
671
672             //&lt;debug&gt;
673             if (!this.instantiationCounts[name]) {
674                 this.instantiationCounts[name] = 0;
675             }
676
677             this.instantiationCounts[name]++;
678             //&lt;/debug&gt;
679
680             return this.getInstantiator(args.length)(cls, args);
681         },
682
683 <span id='Ext-ClassManager-method-dynInstantiate'>        /**
684 </span>         * @private
685          * @param name
686          * @param args
687          */
688         dynInstantiate: function(name, args) {
689             args = Ext.Array.from(args, true);
690             args.unshift(name);
691
692             return this.instantiate.apply(this, args);
693         },
694
695 <span id='Ext-ClassManager-method-getInstantiator'>        /**
696 </span>         * @private
697          * @param length
698          */
699         getInstantiator: function(length) {
700             if (!this.instantiators[length]) {
701                 var i = length,
702                     args = [];
703
704                 for (i = 0; i &lt; length; i++) {
705                     args.push('a['+i+']');
706                 }
707
708                 this.instantiators[length] = new Function('c', 'a', 'return new c('+args.join(',')+')');
709             }
710
711             return this.instantiators[length];
712         },
713
714 <span id='Ext-ClassManager-property-postprocessors'>        /**
715 </span>         * @private
716          */
717         postprocessors: {},
718
719 <span id='Ext-ClassManager-property-defaultPostprocessors'>        /**
720 </span>         * @private
721          */
722         defaultPostprocessors: [],
723
724 <span id='Ext-ClassManager-method-registerPostprocessor'>        /**
725 </span>         * Register a post-processor function.
726          *
727          * @param {String} name
728          * @param {Function} postprocessor
729          */
730         registerPostprocessor: function(name, fn, always) {
731             this.postprocessors[name] = {
732                 name: name,
733                 always: always ||  false,
734                 fn: fn
735             };
736
737             return this;
738         },
739
740 <span id='Ext-ClassManager-method-setDefaultPostprocessors'>        /**
741 </span>         * Set the default post processors array stack which are applied to every class.
742          *
743          * @param {String/Array} The name of a registered post processor or an array of registered names.
744          * @return {Ext.ClassManager} this
745          */
746         setDefaultPostprocessors: function(postprocessors) {
747             this.defaultPostprocessors = Ext.Array.from(postprocessors);
748
749             return this;
750         },
751
752 <span id='Ext-ClassManager-method-setDefaultPostprocessorPosition'>        /**
753 </span>         * Insert this post-processor at a specific position in the stack, optionally relative to
754          * any existing post-processor
755          *
756          * @param {String} name The post-processor name. Note that it needs to be registered with
757          * {@link Ext.ClassManager#registerPostprocessor} before this
758          * @param {String} offset The insertion position. Four possible values are:
759          * 'first', 'last', or: 'before', 'after' (relative to the name provided in the third argument)
760          * @param {String} relativeName
761          * @return {Ext.ClassManager} this
762          */
763         setDefaultPostprocessorPosition: function(name, offset, relativeName) {
764             var defaultPostprocessors = this.defaultPostprocessors,
765                 index;
766
767             if (typeof offset === 'string') {
768                 if (offset === 'first') {
769                     defaultPostprocessors.unshift(name);
770
771                     return this;
772                 }
773                 else if (offset === 'last') {
774                     defaultPostprocessors.push(name);
775
776                     return this;
777                 }
778
779                 offset = (offset === 'after') ? 1 : -1;
780             }
781
782             index = Ext.Array.indexOf(defaultPostprocessors, relativeName);
783
784             if (index !== -1) {
785                 Ext.Array.splice(defaultPostprocessors, Math.max(0, index + offset), 0, name);
786             }
787
788             return this;
789         },
790
791 <span id='Ext-ClassManager-method-getNamesByExpression'>        /**
792 </span>         * Converts a string expression to an array of matching class names. An expression can either refers to class aliases
793          * or class names. Expressions support wildcards:
794          *
795          *     // returns ['Ext.window.Window']
796          *     var window = Ext.ClassManager.getNamesByExpression('widget.window');
797          *
798          *     // returns ['widget.panel', 'widget.window', ...]
799          *     var allWidgets = Ext.ClassManager.getNamesByExpression('widget.*');
800          *
801          *     // returns ['Ext.data.Store', 'Ext.data.ArrayProxy', ...]
802          *     var allData = Ext.ClassManager.getNamesByExpression('Ext.data.*');
803          *
804          * @param {String} expression
805          * @return {Array} classNames
806          * @markdown
807          */
808         getNamesByExpression: function(expression) {
809             var nameToAliasesMap = this.maps.nameToAliases,
810                 names = [],
811                 name, alias, aliases, possibleName, regex, i, ln;
812
813             //&lt;debug error&gt;
814             if (typeof expression !== 'string' || expression.length &lt; 1) {
815                 Ext.Error.raise({
816                     sourceClass: &quot;Ext.ClassManager&quot;,
817                     sourceMethod: &quot;getNamesByExpression&quot;,
818                     msg: &quot;Expression &quot; + expression + &quot; is invalid, must be a non-empty string&quot;
819                 });
820             }
821             //&lt;/debug&gt;
822
823             if (expression.indexOf('*') !== -1) {
824                 expression = expression.replace(/\*/g, '(.*?)');
825                 regex = new RegExp('^' + expression + '$');
826
827                 for (name in nameToAliasesMap) {
828                     if (nameToAliasesMap.hasOwnProperty(name)) {
829                         aliases = nameToAliasesMap[name];
830
831                         if (name.search(regex) !== -1) {
832                             names.push(name);
833                         }
834                         else {
835                             for (i = 0, ln = aliases.length; i &lt; ln; i++) {
836                                 alias = aliases[i];
837
838                                 if (alias.search(regex) !== -1) {
839                                     names.push(name);
840                                     break;
841                                 }
842                             }
843                         }
844                     }
845                 }
846
847             } else {
848                 possibleName = this.getNameByAlias(expression);
849
850                 if (possibleName) {
851                     names.push(possibleName);
852                 } else {
853                     possibleName = this.getNameByAlternate(expression);
854
855                     if (possibleName) {
856                         names.push(possibleName);
857                     } else {
858                         names.push(expression);
859                     }
860                 }
861             }
862
863             return names;
864         }
865     };
866
867 <span id='Ext-Class-cfg-alias'>    /**
868 </span>     * @cfg {[String]} alias
869      * @member Ext.Class
870      * List of short aliases for class names.  Most useful for defining xtypes for widgets:
871      *
872      *     Ext.define('MyApp.CoolPanel', {
873      *         extend: 'Ext.panel.Panel',
874      *         alias: ['widget.coolpanel'],
875      *         title: 'Yeah!'
876      *     });
877      *
878      *     // Using Ext.create
879      *     Ext.widget('widget.coolpanel');
880      *     // Using the shorthand for widgets and in xtypes
881      *     Ext.widget('panel', {
882      *         items: [
883      *             {xtype: 'coolpanel', html: 'Foo'},
884      *             {xtype: 'coolpanel', html: 'Bar'}
885      *         ]
886      *     });
887      */
888     Manager.registerPostprocessor('alias', function(name, cls, data) {
889         var aliases = data.alias,
890             widgetPrefix = 'widget.',
891             i, ln, alias;
892
893         if (!(aliases instanceof Array)) {
894             aliases = [aliases];
895         }
896
897         for (i = 0, ln = aliases.length; i &lt; ln; i++) {
898             alias = aliases[i];
899
900             //&lt;debug error&gt;
901             if (typeof alias !== 'string') {
902                 Ext.Error.raise({
903                     sourceClass: &quot;Ext&quot;,
904                     sourceMethod: &quot;define&quot;,
905                     msg: &quot;Invalid alias of: '&quot; + alias + &quot;' for class: '&quot; + name + &quot;'; must be a valid string&quot;
906                 });
907             }
908             //&lt;/debug&gt;
909
910             this.setAlias(cls, alias);
911         }
912
913         // This is ugly, will change to make use of parseNamespace for alias later on
914         for (i = 0, ln = aliases.length; i &lt; ln; i++) {
915             alias = aliases[i];
916
917             if (alias.substring(0, widgetPrefix.length) === widgetPrefix) {
918                 // Only the first alias with 'widget.' prefix will be used for xtype
919                 cls.xtype = cls.$xtype = alias.substring(widgetPrefix.length);
920                 break;
921             }
922         }
923     });
924
925 <span id='Ext-Class-cfg-singleton'>    /**
926 </span>     * @cfg {Boolean} singleton
927      * @member Ext.Class
928      * When set to true, the class will be instanciated as singleton.  For example:
929      *
930      *     Ext.define('Logger', {
931      *         singleton: true,
932      *         log: function(msg) {
933      *             console.log(msg);
934      *         }
935      *     });
936      *
937      *     Logger.log('Hello');
938      */
939     Manager.registerPostprocessor('singleton', function(name, cls, data, fn) {
940         fn.call(this, name, new cls(), data);
941         return false;
942     });
943
944 <span id='Ext-Class-cfg-alternateClassName'>    /**
945 </span>     * @cfg {String/[String]} alternateClassName
946      * @member Ext.Class
947      * Defines alternate names for this class.  For example:
948      *
949      *     Ext.define('Developer', {
950      *         alternateClassName: ['Coder', 'Hacker'],
951      *         code: function(msg) {
952      *             alert('Typing... ' + msg);
953      *         }
954      *     });
955      *
956      *     var joe = Ext.create('Developer');
957      *     joe.code('stackoverflow');
958      *
959      *     var rms = Ext.create('Hacker');
960      *     rms.code('hack hack');
961      */
962     Manager.registerPostprocessor('alternateClassName', function(name, cls, data) {
963         var alternates = data.alternateClassName,
964             i, ln, alternate;
965
966         if (!(alternates instanceof Array)) {
967             alternates = [alternates];
968         }
969
970         for (i = 0, ln = alternates.length; i &lt; ln; i++) {
971             alternate = alternates[i];
972
973             //&lt;debug error&gt;
974             if (typeof alternate !== 'string') {
975                 Ext.Error.raise({
976                     sourceClass: &quot;Ext&quot;,
977                     sourceMethod: &quot;define&quot;,
978                     msg: &quot;Invalid alternate of: '&quot; + alternate + &quot;' for class: '&quot; + name + &quot;'; must be a valid string&quot;
979                 });
980             }
981             //&lt;/debug&gt;
982
983             this.set(alternate, cls);
984         }
985     });
986
987     Manager.setDefaultPostprocessors(['alias', 'singleton', 'alternateClassName']);
988
989     Ext.apply(Ext, {
990 <span id='Ext-method-create'>        /**
991 </span>         * @method
992          * @member Ext
993          * @alias Ext.ClassManager#instantiate
994          */
995         create: alias(Manager, 'instantiate'),
996
997 <span id='Ext-ClassManager-method-factory'>        /**
998 </span>         * @private
999          * API to be stablized
1000          *
1001          * @param {Mixed} item
1002          * @param {String} namespace
1003          */
1004         factory: function(item, namespace) {
1005             if (item instanceof Array) {
1006                 var i, ln;
1007
1008                 for (i = 0, ln = item.length; i &lt; ln; i++) {
1009                     item[i] = Ext.factory(item[i], namespace);
1010                 }
1011
1012                 return item;
1013             }
1014
1015             var isString = (typeof item === 'string');
1016
1017             if (isString || (item instanceof Object &amp;&amp; item.constructor === Object)) {
1018                 var name, config = {};
1019
1020                 if (isString) {
1021                     name = item;
1022                 }
1023                 else {
1024                     name = item.className;
1025                     config = item;
1026                     delete config.className;
1027                 }
1028
1029                 if (namespace !== undefined &amp;&amp; name.indexOf(namespace) === -1) {
1030                     name = namespace + '.' + Ext.String.capitalize(name);
1031                 }
1032
1033                 return Ext.create(name, config);
1034             }
1035
1036             if (typeof item === 'function') {
1037                 return Ext.create(item);
1038             }
1039
1040             return item;
1041         },
1042
1043 <span id='Ext-method-widget'>        /**
1044 </span>         * Convenient shorthand to create a widget by its xtype, also see {@link Ext.ClassManager#instantiateByAlias}
1045          *
1046          *     var button = Ext.widget('button'); // Equivalent to Ext.create('widget.button')
1047          *     var panel = Ext.widget('panel'); // Equivalent to Ext.create('widget.panel')
1048          *
1049          * @method
1050          * @member Ext
1051          * @param {String} name  xtype of the widget to create.
1052          * @return {Object} widget instance
1053          */
1054         widget: function(name) {
1055             var args = slice.call(arguments);
1056             args[0] = 'widget.' + name;
1057
1058             return Manager.instantiateByAlias.apply(Manager, args);
1059         },
1060
1061 <span id='Ext-method-createByAlias'>        /**
1062 </span>         * @method
1063          * @member Ext
1064          * @alias Ext.ClassManager#instantiateByAlias
1065          */
1066         createByAlias: alias(Manager, 'instantiateByAlias'),
1067
1068 <span id='Ext-method-define'>        /**
1069 </span>         * @method
1070          * @member Ext
1071          * @alias Ext.ClassManager#create
1072          */
1073         define: alias(Manager, 'create'),
1074
1075 <span id='Ext-method-getClassName'>        /**
1076 </span>         * @method
1077          * @member Ext
1078          * @alias Ext.ClassManager#getName
1079          */
1080         getClassName: alias(Manager, 'getName'),
1081
1082 <span id='Ext-ClassManager-method-getDisplayName'>        /**
1083 </span>         *
1084          * @param {Mixed} object
1085          */
1086         getDisplayName: function(object) {
1087             if (object.displayName) {
1088                 return object.displayName;
1089             }
1090
1091             if (object.$name &amp;&amp; object.$class) {
1092                 return Ext.getClassName(object.$class) + '#' + object.$name;
1093             }
1094
1095             if (object.$className) {
1096                 return object.$className;
1097             }
1098
1099             return 'Anonymous';
1100         },
1101
1102 <span id='Ext-method-getClass'>        /**
1103 </span>         * @method
1104          * @member Ext
1105          * @alias Ext.ClassManager#getClass
1106          */
1107         getClass: alias(Manager, 'getClass'),
1108
1109 <span id='Ext-method-namespace'>        /**
1110 </span>         * Creates namespaces to be used for scoping variables and classes so that they are not global.
1111          * Specifying the last node of a namespace implicitly creates all other nodes. Usage:
1112          *
1113          *     Ext.namespace('Company', 'Company.data');
1114          *
1115          *     // equivalent and preferable to the above syntax
1116          *     Ext.namespace('Company.data');
1117          *
1118          *     Company.Widget = function() { ... };
1119          *
1120          *     Company.data.CustomStore = function(config) { ... };
1121          *
1122          * @method
1123          * @member Ext
1124          * @param {String} namespace1
1125          * @param {String} namespace2
1126          * @param {String} etc
1127          * @return {Object} The namespace object. (If multiple arguments are passed, this will be the last namespace created)
1128          */
1129         namespace: alias(Manager, 'createNamespaces')
1130     });
1131
1132 <span id='Ext-method-createWidget'>    /**
1133 </span>     * Old name for {@link Ext#widget}.
1134      * @deprecated 4.0.0 Use {@link Ext#widget} instead.
1135      * @method
1136      * @member Ext
1137      * @alias Ext#widget
1138      */
1139     Ext.createWidget = Ext.widget;
1140
1141 <span id='Ext-method-ns'>    /**
1142 </span>     * Convenient alias for {@link Ext#namespace Ext.namespace}
1143      * @method
1144      * @member Ext
1145      * @alias Ext#namespace
1146      */
1147     Ext.ns = Ext.namespace;
1148
1149     Class.registerPreprocessor('className', function(cls, data) {
1150         if (data.$className) {
1151             cls.$className = data.$className;
1152             //&lt;debug&gt;
1153             cls.displayName = cls.$className;
1154             //&lt;/debug&gt;
1155         }
1156     }, true);
1157
1158     Class.setDefaultPreprocessorPosition('className', 'first');
1159
1160 })(Ext.Class, Ext.Function.alias);
1161 </pre>
1162 </body>
1163 </html>