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