4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8 <style type="text/css">
9 .highlight { display: block; background-color: #ddd; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-ClassManager'>/**
19 </span> * @author Jacky Nguyen <jacky@sencha.com>
20 * @docauthor Jacky Nguyen <jacky@sencha.com>
21 * @class Ext.ClassManager
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:
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}
35 * Ext.define(className, properties);
37 * in which `properties` is an object represent a collection of properties that apply to the class. See
38 * {@link Ext.ClassManager#create} for more detailed instructions.
40 * Ext.define('Person', {
43 * constructor: function(name) {
51 * eat: function(foodType) {
52 * alert("I'm eating: " + foodType);
58 * var aaron = new Person("Aaron");
59 * aaron.eat("Sandwich"); // alert("I'm eating: Sandwich");
61 * Ext.Class has a powerful set of extensible {@link Ext.Class#registerPreprocessor pre-processors} which takes care of
62 * everything related to class creation, including but not limited to inheritance, mixins, configuration, statics, etc.
66 * Ext.define('Developer', {
69 * constructor: function(name, isGeek) {
70 * this.isGeek = isGeek;
72 * // Apply a method from the parent class' prototype
73 * this.callParent([name]);
79 * code: function(language) {
80 * alert("I'm coding in: " + language);
82 * this.eat("Bugs");
88 * var jacky = new Developer("Jacky", true);
89 * jacky.code("JavaScript"); // alert("I'm coding in: JavaScript");
90 * // alert("I'm eating: Bugs");
92 * See {@link Ext.Base#callParent} for more details on calling superclass' methods
96 * Ext.define('CanPlayGuitar', {
97 * playGuitar: function() {
98 * alert("F#...G...D...A");
102 * Ext.define('CanComposeSongs', {
103 * composeSongs: function() { ... }
106 * Ext.define('CanSing', {
108 * alert("I'm on the highway to hell...")
112 * Ext.define('Musician', {
116 * canPlayGuitar: 'CanPlayGuitar',
117 * canComposeSongs: 'CanComposeSongs',
122 * Ext.define('CoolPerson', {
126 * canPlayGuitar: 'CanPlayGuitar',
131 * alert("Ahem....");
133 * this.mixins.canSing.sing.call(this);
135 * alert("[Playing guitar at the same time...]");
141 * var me = new CoolPerson("Jacky");
143 * me.sing(); // alert("Ahem...");
144 * // alert("I'm on the highway to hell...");
145 * // alert("[Playing guitar at the same time...]");
146 * // alert("F#...G...D...A");
150 * Ext.define('SmartPhone', {
152 * hasTouchScreen: false,
153 * operatingSystem: 'Other',
157 * isExpensive: false,
159 * constructor: function(config) {
160 * this.initConfig(config);
165 * applyPrice: function(price) {
166 * this.isExpensive = (price > 500);
171 * applyOperatingSystem: function(operatingSystem) {
172 * if (!(/^(iOS|Android|BlackBerry)$/i).test(operatingSystem)) {
176 * return operatingSystem;
180 * var iPhone = new SmartPhone({
181 * hasTouchScreen: true,
182 * operatingSystem: 'iOS'
185 * iPhone.getPrice(); // 500;
186 * iPhone.getOperatingSystem(); // 'iOS'
187 * iPhone.getHasTouchScreen(); // true;
188 * iPhone.hasTouchScreen(); // true
190 * iPhone.isExpensive; // false;
191 * iPhone.setPrice(600);
192 * iPhone.getPrice(); // 600
193 * iPhone.isExpensive; // true;
195 * iPhone.setOperatingSystem('AlienOS');
196 * iPhone.getOperatingSystem(); // 'Other'
200 * Ext.define('Computer', {
202 * factory: function(brand) {
203 * // 'this' in static methods refer to the class itself
204 * return new this(brand);
208 * constructor: function() { ... }
211 * var dellComputer = Computer.factory('Dell');
213 * Also see {@link Ext.Base#statics} and {@link Ext.Base#self} for more details on accessing
214 * static properties within class methods
218 (function(Class, alias) {
220 var slice = Array.prototype.slice;
222 var Manager = Ext.ClassManager = {
224 <span id='Ext-ClassManager-property-classes'> /**
225 </span> * @property {Object} classes
226 * All classes which were defined through the ClassManager. Keys are the
227 * name of the classes and the values are references to the classes.
232 <span id='Ext-ClassManager-property-existCache'> /**
237 <span id='Ext-ClassManager-property-namespaceRewrites'> /**
240 namespaceRewrites: [{
245 <span id='Ext-ClassManager-property-maps'> /**
254 <span id='Ext-ClassManager-property-enableNamespaceParseCache'> /** @private */
255 </span> enableNamespaceParseCache: true,
257 <span id='Ext-ClassManager-property-namespaceParseCache'> /** @private */
258 </span> namespaceParseCache: {},
260 <span id='Ext-ClassManager-property-instantiators'> /** @private */
261 </span> instantiators: [],
264 <span id='Ext-ClassManager-property-instantiationCounts'> /** @private */
265 </span> instantiationCounts: {},
268 <span id='Ext-ClassManager-method-isCreated'> /**
269 </span> * Checks if a class has already been created.
271 * @param {String} className
272 * @return {Boolean} exist
274 isCreated: function(className) {
275 var i, ln, part, root, parts;
277 //<debug error>
278 if (typeof className !== 'string' || className.length < 1) {
280 sourceClass: "Ext.ClassManager",
281 sourceMethod: "exist",
282 msg: "Invalid classname, must be a string and must not be empty"
287 if (this.classes.hasOwnProperty(className) || this.existCache.hasOwnProperty(className)) {
292 parts = this.parseNamespace(className);
294 for (i = 0, ln = parts.length; i < ln; i++) {
297 if (typeof part !== 'string') {
300 if (!root || !root[part]) {
308 Ext.Loader.historyPush(className);
310 this.existCache[className] = true;
315 <span id='Ext-ClassManager-method-parseNamespace'> /**
316 </span> * Supports namespace rewriting
319 parseNamespace: function(namespace) {
320 //<debug error>
321 if (typeof namespace !== 'string') {
323 sourceClass: "Ext.ClassManager",
324 sourceMethod: "parseNamespace",
325 msg: "Invalid namespace, must be a string"
330 var cache = this.namespaceParseCache;
332 if (this.enableNamespaceParseCache) {
333 if (cache.hasOwnProperty(namespace)) {
334 return cache[namespace];
339 rewrites = this.namespaceRewrites,
340 rewrite, from, to, i, ln, root = Ext.global;
342 for (i = 0, ln = rewrites.length; i < ln; i++) {
343 rewrite = rewrites[i];
347 if (namespace === from || namespace.substring(0, from.length) === from) {
348 namespace = namespace.substring(from.length);
350 if (typeof to !== 'string') {
353 parts = parts.concat(to.split('.'));
362 parts = parts.concat(namespace.split('.'));
364 if (this.enableNamespaceParseCache) {
365 cache[namespace] = parts;
371 <span id='Ext-ClassManager-method-setNamespace'> /**
372 </span> * Creates a namespace and assign the `value` to the created object
374 * Ext.ClassManager.setNamespace('MyCompany.pkg.Example', someObject);
376 * alert(MyCompany.pkg.Example === someObject); // alerts true
378 * @param {String} name
379 * @param {Object} value
381 setNamespace: function(name, value) {
382 var root = Ext.global,
383 parts = this.parseNamespace(name),
384 ln = parts.length - 1,
388 for (i = 0; i < ln; i++) {
391 if (typeof part !== 'string') {
407 <span id='Ext-ClassManager-method-createNamespaces'> /**
408 </span> * The new Ext.ns, supports namespace rewriting
411 createNamespaces: function() {
412 var root = Ext.global,
413 parts, part, i, j, ln, subLn;
415 for (i = 0, ln = arguments.length; i < ln; i++) {
416 parts = this.parseNamespace(arguments[i]);
418 for (j = 0, subLn = parts.length; j < subLn; j++) {
421 if (typeof part !== 'string') {
436 <span id='Ext-ClassManager-method-set'> /**
437 </span> * Sets a name reference to a class.
439 * @param {String} name
440 * @param {Object} value
441 * @return {Ext.ClassManager} this
443 set: function(name, value) {
444 var targetName = this.getName(value);
446 this.classes[name] = this.setNamespace(name, value);
448 if (targetName && targetName !== name) {
449 this.maps.alternateToName[name] = targetName;
455 <span id='Ext-ClassManager-method-get'> /**
456 </span> * Retrieve a class by its name.
458 * @param {String} name
459 * @return {Ext.Class} class
461 get: function(name) {
462 if (this.classes.hasOwnProperty(name)) {
463 return this.classes[name];
466 var root = Ext.global,
467 parts = this.parseNamespace(name),
470 for (i = 0, ln = parts.length; i < ln; i++) {
473 if (typeof part !== 'string') {
476 if (!root || !root[part]) {
487 <span id='Ext-ClassManager-method-setAlias'> /**
488 </span> * Register the alias for a class.
490 * @param {Ext.Class/String} cls a reference to a class or a className
491 * @param {String} alias Alias to use when referring to this class
493 setAlias: function(cls, alias) {
494 var aliasToNameMap = this.maps.aliasToName,
495 nameToAliasesMap = this.maps.nameToAliases,
498 if (typeof cls === 'string') {
501 className = this.getName(cls);
504 if (alias && aliasToNameMap[alias] !== className) {
506 if (aliasToNameMap.hasOwnProperty(alias) && Ext.isDefined(Ext.global.console)) {
507 Ext.global.console.log("[Ext.ClassManager] Overriding existing alias: '" + alias + "' " +
508 "of: '" + aliasToNameMap[alias] + "' with: '" + className + "'. Be sure it's intentional.");
512 aliasToNameMap[alias] = className;
515 if (!nameToAliasesMap[className]) {
516 nameToAliasesMap[className] = [];
520 Ext.Array.include(nameToAliasesMap[className], alias);
526 <span id='Ext-ClassManager-method-getByAlias'> /**
527 </span> * Get a reference to the class by its alias.
529 * @param {String} alias
530 * @return {Ext.Class} class
532 getByAlias: function(alias) {
533 return this.get(this.getNameByAlias(alias));
536 <span id='Ext-ClassManager-method-getNameByAlias'> /**
537 </span> * Get the name of a class by its alias.
539 * @param {String} alias
540 * @return {String} className
542 getNameByAlias: function(alias) {
543 return this.maps.aliasToName[alias] || '';
546 <span id='Ext-ClassManager-method-getNameByAlternate'> /**
547 </span> * Get the name of a class by its alternate name.
549 * @param {String} alternate
550 * @return {String} className
552 getNameByAlternate: function(alternate) {
553 return this.maps.alternateToName[alternate] || '';
556 <span id='Ext-ClassManager-method-getAliasesByName'> /**
557 </span> * Get the aliases of a class by the class name
559 * @param {String} name
560 * @return {String[]} aliases
562 getAliasesByName: function(name) {
563 return this.maps.nameToAliases[name] || [];
566 <span id='Ext-ClassManager-method-getName'> /**
567 </span> * Get the name of the class by its reference or its instance.
569 * Ext.ClassManager.getName(Ext.Action); // returns "Ext.Action"
571 * {@link Ext#getClassName Ext.getClassName} is alias for {@link Ext.ClassManager#getName Ext.ClassManager.getName}.
573 * @param {Ext.Class/Object} object
574 * @return {String} className
576 getName: function(object) {
577 return object && object.$className || '';
580 <span id='Ext-ClassManager-method-getClass'> /**
581 </span> * Get the class of the provided object; returns null if it's not an instance
582 * of any class created with Ext.define.
584 * var component = new Ext.Component();
586 * Ext.ClassManager.getClass(component); // returns Ext.Component
588 * {@link Ext#getClass Ext.getClass} is alias for {@link Ext.ClassManager#getClass Ext.ClassManager.getClass}.
590 * @param {Object} object
591 * @return {Ext.Class} class
593 getClass: function(object) {
594 return object && object.self || null;
597 <span id='Ext-ClassManager-method-create'> /**
598 </span> * Defines a class.
600 * {@link Ext#define Ext.define} and {@link Ext.ClassManager#create Ext.ClassManager.create} are almost aliases
601 * of each other, with the only exception that Ext.define allows definition of {@link Ext.Class#override overrides}.
602 * To avoid trouble, always use Ext.define.
604 * Ext.define('My.awesome.Class', {
605 * someProperty: 'something',
606 * someMethod: function() { ... }
611 * alert(this === My.awesome.Class); // alerts true
613 * var myInstance = new this();
616 * @param {String} className The class name to create in string dot-namespaced format, for example:
617 * `My.very.awesome.Class`, `FeedViewer.plugin.CoolPager`. It is highly recommended to follow this simple convention:
619 * - The root and the class name are 'CamelCased'
620 * - Everything else is lower-cased
622 * @param {Object} data The key-value pairs of properties to apply to this class. Property names can be of any valid
623 * strings, except those in the reserved list below:
625 * - {@link Ext.Base#self self}
626 * - {@link Ext.Class#alias alias}
627 * - {@link Ext.Class#alternateClassName alternateClassName}
628 * - {@link Ext.Class#config config}
629 * - {@link Ext.Class#extend extend}
630 * - {@link Ext.Class#inheritableStatics inheritableStatics}
631 * - {@link Ext.Class#mixins mixins}
632 * - {@link Ext.Class#override override} (only when using {@link Ext#define Ext.define})
633 * - {@link Ext.Class#requires requires}
634 * - {@link Ext.Class#singleton singleton}
635 * - {@link Ext.Class#statics statics}
636 * - {@link Ext.Class#uses uses}
638 * @param {Function} [createdFn] callback to execute after the class is created, the execution scope of which
639 * (`this`) will be the newly created class itself.
643 create: function(className, data, createdFn) {
646 //<debug error>
647 if (typeof className !== 'string') {
649 sourceClass: "Ext",
650 sourceMethod: "define",
651 msg: "Invalid class name '" + className + "' specified, must be a non-empty string"
656 data.$className = className;
658 return new Class(data, function() {
659 var postprocessorStack = data.postprocessors || manager.defaultPostprocessors,
660 registeredPostprocessors = manager.postprocessors,
663 postprocessor, process, i, ln;
665 delete data.postprocessors;
667 for (i = 0, ln = postprocessorStack.length; i < ln; i++) {
668 postprocessor = postprocessorStack[i];
670 if (typeof postprocessor === 'string') {
671 postprocessor = registeredPostprocessors[postprocessor];
673 if (!postprocessor.always) {
674 if (data[postprocessor.name] !== undefined) {
675 postprocessors.push(postprocessor.fn);
679 postprocessors.push(postprocessor.fn);
683 postprocessors.push(postprocessor);
687 process = function(clsName, cls, clsData) {
688 postprocessor = postprocessors[index++];
690 if (!postprocessor) {
691 manager.set(className, cls);
693 Ext.Loader.historyPush(className);
696 createdFn.call(cls, cls);
702 if (postprocessor.call(this, clsName, cls, clsData, process) !== false) {
703 process.apply(this, arguments);
707 process.call(manager, className, this, data);
711 <span id='Ext-ClassManager-method-instantiateByAlias'> /**
712 </span> * Instantiate a class by its alias.
714 * If {@link Ext.Loader} is {@link Ext.Loader#setConfig enabled} and the class has not been defined yet, it will
715 * attempt to load the class via synchronous loading.
717 * var window = Ext.ClassManager.instantiateByAlias('widget.window', { width: 600, height: 800, ... });
719 * {@link Ext#createByAlias Ext.createByAlias} is alias for {@link Ext.ClassManager#instantiateByAlias Ext.ClassManager.instantiateByAlias}.
721 * @param {String} alias
722 * @param {Object...} args Additional arguments after the alias will be passed to the
724 * @return {Object} instance
726 instantiateByAlias: function() {
727 var alias = arguments[0],
728 args = slice.call(arguments),
729 className = this.getNameByAlias(alias);
732 className = this.maps.aliasToName[alias];
734 //<debug error>
737 sourceClass: "Ext",
738 sourceMethod: "createByAlias",
739 msg: "Cannot create an instance of unrecognized alias: " + alias
745 if (Ext.global.console) {
746 Ext.global.console.warn("[Ext.Loader] Synchronously loading '" + className + "'; consider adding " +
747 "Ext.require('" + alias + "') above Ext.onReady");
751 Ext.syncRequire(className);
756 return this.instantiate.apply(this, args);
759 <span id='Ext-ClassManager-method-instantiate'> /**
760 </span> * Instantiate a class by either full name, alias or alternate name.
762 * If {@link Ext.Loader} is {@link Ext.Loader#setConfig enabled} and the class has not been defined yet, it will
763 * attempt to load the class via synchronous loading.
765 * For example, all these three lines return the same result:
768 * var window = Ext.ClassManager.instantiate('widget.window', { width: 600, height: 800, ... });
771 * var window = Ext.ClassManager.instantiate('Ext.Window', { width: 600, height: 800, ... });
774 * var window = Ext.ClassManager.instantiate('Ext.window.Window', { width: 600, height: 800, ... });
776 * {@link Ext#create Ext.create} is alias for {@link Ext.ClassManager#instantiate Ext.ClassManager.instantiate}.
778 * @param {String} name
779 * @param {Object...} args Additional arguments after the name will be passed to the class' constructor.
780 * @return {Object} instance
782 instantiate: function() {
783 var name = arguments[0],
784 args = slice.call(arguments, 1),
788 if (typeof name !== 'function') {
789 //<debug error>
790 if ((typeof name !== 'string' || name.length < 1)) {
792 sourceClass: "Ext",
793 sourceMethod: "create",
794 msg: "Invalid class name or alias '" + name + "' specified, must be a non-empty string"
799 cls = this.get(name);
805 // No record of this class name, it's possibly an alias, so look it up
807 possibleName = this.getNameByAlias(name);
812 cls = this.get(name);
816 // Still no record of this class name, it's possibly an alternate name, so look it up
818 possibleName = this.getNameByAlternate(name);
823 cls = this.get(name);
827 // Still not existing at this point, try to load it via synchronous mode as the last resort
830 if (Ext.global.console) {
831 Ext.global.console.warn("[Ext.Loader] Synchronously loading '" + name + "'; consider adding " +
832 "Ext.require('" + ((possibleName) ? alias : name) + "') above Ext.onReady");
836 Ext.syncRequire(name);
838 cls = this.get(name);
841 //<debug error>
844 sourceClass: "Ext",
845 sourceMethod: "create",
846 msg: "Cannot create an instance of unrecognized class name / alias: " + alias
850 if (typeof cls !== 'function') {
852 sourceClass: "Ext",
853 sourceMethod: "create",
854 msg: "'" + name + "' is a singleton and cannot be instantiated"
860 if (!this.instantiationCounts[name]) {
861 this.instantiationCounts[name] = 0;
864 this.instantiationCounts[name]++;
867 return this.getInstantiator(args.length)(cls, args);
870 <span id='Ext-ClassManager-method-dynInstantiate'> /**
875 dynInstantiate: function(name, args) {
876 args = Ext.Array.from(args, true);
879 return this.instantiate.apply(this, args);
882 <span id='Ext-ClassManager-method-getInstantiator'> /**
886 getInstantiator: function(length) {
887 if (!this.instantiators[length]) {
891 for (i = 0; i < length; i++) {
892 args.push('a['+i+']');
895 this.instantiators[length] = new Function('c', 'a', 'return new c('+args.join(',')+')');
898 return this.instantiators[length];
901 <span id='Ext-ClassManager-property-postprocessors'> /**
906 <span id='Ext-ClassManager-property-defaultPostprocessors'> /**
909 defaultPostprocessors: [],
911 <span id='Ext-ClassManager-method-registerPostprocessor'> /**
912 </span> * Register a post-processor function.
914 * @param {String} name
915 * @param {Function} postprocessor
917 registerPostprocessor: function(name, fn, always) {
918 this.postprocessors[name] = {
920 always: always || false,
927 <span id='Ext-ClassManager-method-setDefaultPostprocessors'> /**
928 </span> * Set the default post processors array stack which are applied to every class.
930 * @param {String/String[]} The name of a registered post processor or an array of registered names.
931 * @return {Ext.ClassManager} this
933 setDefaultPostprocessors: function(postprocessors) {
934 this.defaultPostprocessors = Ext.Array.from(postprocessors);
939 <span id='Ext-ClassManager-method-setDefaultPostprocessorPosition'> /**
940 </span> * Insert this post-processor at a specific position in the stack, optionally relative to
941 * any existing post-processor
943 * @param {String} name The post-processor name. Note that it needs to be registered with
944 * {@link Ext.ClassManager#registerPostprocessor} before this
945 * @param {String} offset The insertion position. Four possible values are:
946 * 'first', 'last', or: 'before', 'after' (relative to the name provided in the third argument)
947 * @param {String} relativeName
948 * @return {Ext.ClassManager} this
950 setDefaultPostprocessorPosition: function(name, offset, relativeName) {
951 var defaultPostprocessors = this.defaultPostprocessors,
954 if (typeof offset === 'string') {
955 if (offset === 'first') {
956 defaultPostprocessors.unshift(name);
960 else if (offset === 'last') {
961 defaultPostprocessors.push(name);
966 offset = (offset === 'after') ? 1 : -1;
969 index = Ext.Array.indexOf(defaultPostprocessors, relativeName);
972 Ext.Array.splice(defaultPostprocessors, Math.max(0, index + offset), 0, name);
978 <span id='Ext-ClassManager-method-getNamesByExpression'> /**
979 </span> * Converts a string expression to an array of matching class names. An expression can either refers to class aliases
980 * or class names. Expressions support wildcards:
982 * // returns ['Ext.window.Window']
983 * var window = Ext.ClassManager.getNamesByExpression('widget.window');
985 * // returns ['widget.panel', 'widget.window', ...]
986 * var allWidgets = Ext.ClassManager.getNamesByExpression('widget.*');
988 * // returns ['Ext.data.Store', 'Ext.data.ArrayProxy', ...]
989 * var allData = Ext.ClassManager.getNamesByExpression('Ext.data.*');
991 * @param {String} expression
992 * @return {String[]} classNames
994 getNamesByExpression: function(expression) {
995 var nameToAliasesMap = this.maps.nameToAliases,
997 name, alias, aliases, possibleName, regex, i, ln;
999 //<debug error>
1000 if (typeof expression !== 'string' || expression.length < 1) {
1002 sourceClass: "Ext.ClassManager",
1003 sourceMethod: "getNamesByExpression",
1004 msg: "Expression " + expression + " is invalid, must be a non-empty string"
1009 if (expression.indexOf('*') !== -1) {
1010 expression = expression.replace(/\*/g, '(.*?)');
1011 regex = new RegExp('^' + expression + '$');
1013 for (name in nameToAliasesMap) {
1014 if (nameToAliasesMap.hasOwnProperty(name)) {
1015 aliases = nameToAliasesMap[name];
1017 if (name.search(regex) !== -1) {
1021 for (i = 0, ln = aliases.length; i < ln; i++) {
1024 if (alias.search(regex) !== -1) {
1034 possibleName = this.getNameByAlias(expression);
1037 names.push(possibleName);
1039 possibleName = this.getNameByAlternate(expression);
1042 names.push(possibleName);
1044 names.push(expression);
1053 var defaultPostprocessors = Manager.defaultPostprocessors;
1054 //<feature classSystem.alias>
1056 <span id='Ext-Class-cfg-alias'> /**
1057 </span> * @cfg {String[]} alias
1059 * List of short aliases for class names. Most useful for defining xtypes for widgets:
1061 * Ext.define('MyApp.CoolPanel', {
1062 * extend: 'Ext.panel.Panel',
1063 * alias: ['widget.coolpanel'],
1067 * // Using Ext.create
1068 * Ext.widget('widget.coolpanel');
1069 * // Using the shorthand for widgets and in xtypes
1070 * Ext.widget('panel', {
1072 * {xtype: 'coolpanel', html: 'Foo'},
1073 * {xtype: 'coolpanel', html: 'Bar'}
1077 Manager.registerPostprocessor('alias', function(name, cls, data) {
1078 var aliases = data.alias,
1083 for (i = 0, ln = aliases.length; i < ln; i++) {
1086 this.setAlias(cls, alias);
1090 <span id='Ext-Class-cfg-singleton'> /**
1091 </span> * @cfg {Boolean} singleton
1093 * When set to true, the class will be instantiated as singleton. For example:
1095 * Ext.define('Logger', {
1097 * log: function(msg) {
1102 * Logger.log('Hello');
1104 Manager.registerPostprocessor('singleton', function(name, cls, data, fn) {
1105 fn.call(this, name, new cls(), data);
1109 <span id='Ext-Class-cfg-alternateClassName'> /**
1110 </span> * @cfg {String/String[]} alternateClassName
1112 * Defines alternate names for this class. For example:
1114 * Ext.define('Developer', {
1115 * alternateClassName: ['Coder', 'Hacker'],
1116 * code: function(msg) {
1117 * alert('Typing... ' + msg);
1121 * var joe = Ext.create('Developer');
1122 * joe.code('stackoverflow');
1124 * var rms = Ext.create('Hacker');
1125 * rms.code('hack hack');
1127 Manager.registerPostprocessor('alternateClassName', function(name, cls, data) {
1128 var alternates = data.alternateClassName,
1131 if (!(alternates instanceof Array)) {
1132 alternates = [alternates];
1135 for (i = 0, ln = alternates.length; i < ln; i++) {
1136 alternate = alternates[i];
1138 //<debug error>
1139 if (typeof alternate !== 'string') {
1141 sourceClass: "Ext",
1142 sourceMethod: "define",
1143 msg: "Invalid alternate of: '" + alternate + "' for class: '" + name + "'; must be a valid string"
1148 this.set(alternate, cls);
1152 Manager.setDefaultPostprocessors(['alias', 'singleton', 'alternateClassName']);
1155 <span id='Ext-method-create'> /**
1158 * @alias Ext.ClassManager#instantiate
1160 create: alias(Manager, 'instantiate'),
1162 <span id='Ext-ClassManager-method-factory'> /**
1164 * API to be stablized
1166 * @param {Object} item
1167 * @param {String} namespace
1169 factory: function(item, namespace) {
1170 if (item instanceof Array) {
1173 for (i = 0, ln = item.length; i < ln; i++) {
1174 item[i] = Ext.factory(item[i], namespace);
1180 var isString = (typeof item === 'string');
1182 if (isString || (item instanceof Object && item.constructor === Object)) {
1183 var name, config = {};
1189 name = item.className;
1191 delete config.className;
1194 if (namespace !== undefined && name.indexOf(namespace) === -1) {
1195 name = namespace + '.' + Ext.String.capitalize(name);
1198 return Ext.create(name, config);
1201 if (typeof item === 'function') {
1202 return Ext.create(item);
1208 <span id='Ext-method-widget'> /**
1209 </span> * Convenient shorthand to create a widget by its xtype, also see {@link Ext.ClassManager#instantiateByAlias}
1211 * var button = Ext.widget('button'); // Equivalent to Ext.create('widget.button')
1212 * var panel = Ext.widget('panel'); // Equivalent to Ext.create('widget.panel')
1216 * @param {String} name xtype of the widget to create.
1217 * @param {Object...} args arguments for the widget constructor.
1218 * @return {Object} widget instance
1220 widget: function(name) {
1221 var args = slice.call(arguments);
1222 args[0] = 'widget.' + name;
1224 return Manager.instantiateByAlias.apply(Manager, args);
1227 <span id='Ext-method-createByAlias'> /**
1230 * @alias Ext.ClassManager#instantiateByAlias
1232 createByAlias: alias(Manager, 'instantiateByAlias'),
1234 <span id='Ext-Class-cfg-override'> /**
1235 </span> * @cfg {String} override
1238 * Defines an override applied to a class. Note that **overrides can only be created using
1239 * {@link Ext#define}.** {@link Ext.ClassManager#create} only creates classes.
1241 * To define an override, include the override property. The content of an override is
1242 * aggregated with the specified class in order to extend or modify that class. This can be
1243 * as simple as setting default property values or it can extend and/or replace methods.
1244 * This can also extend the statics of the class.
1246 * One use for an override is to break a large class into manageable pieces.
1248 * // File: /src/app/Panel.js
1250 * Ext.define('My.app.Panel', {
1251 * extend: 'Ext.panel.Panel',
1253 * 'My.app.PanelPart2',
1254 * 'My.app.PanelPart3'
1257 * constructor: function (config) {
1258 * this.callSuper(arguments); // calls Ext.panel.Panel's constructor
1263 * method: function () {
1269 * // File: /src/app/PanelPart2.js
1270 * Ext.define('My.app.PanelPart2', {
1271 * override: 'My.app.Panel',
1273 * constructor: function (config) {
1274 * this.callSuper(arguments); // calls My.app.Panel's constructor
1279 * Another use of overrides is to provide optional parts of classes that can be
1280 * independently required. In this case, the class may even be unaware of the
1281 * override altogether.
1283 * Ext.define('My.ux.CoolTip', {
1284 * override: 'Ext.tip.ToolTip',
1286 * constructor: function (config) {
1287 * this.callSuper(arguments); // calls Ext.tip.ToolTip's constructor
1292 * The above override can now be required as normal.
1294 * Ext.define('My.app.App', {
1300 * Overrides can also contain statics:
1302 * Ext.define('My.app.BarMod', {
1303 * override: 'Ext.foo.Bar',
1306 * method: function (x) {
1307 * return this.callSuper([x * 2]); // call Ext.foo.Bar.method
1312 * IMPORTANT: An override is only included in a build if the class it overrides is
1313 * required. Otherwise, the override, like the target class, is not included.
1316 <span id='Ext-method-define'> /**
1320 * @alias Ext.ClassManager#create
1322 define: function (className, data, createdFn) {
1323 if (!data.override) {
1324 return Manager.create.apply(Manager, arguments);
1327 var requires = data.requires,
1329 overrideName = className;
1331 className = data.override;
1333 // hoist any 'requires' or 'uses' from the body onto the faux class:
1334 data = Ext.apply({}, data);
1335 delete data.requires;
1337 delete data.override;
1339 // make sure className is in the requires list:
1340 if (typeof requires == 'string') {
1341 requires = [ className, requires ];
1342 } else if (requires) {
1343 requires = requires.slice(0);
1344 requires.unshift(className);
1346 requires = [ className ];
1349 // TODO - we need to rework this to allow the override to not require the target class
1350 // and rather 'wait' for it in such a way that if the target class is not in the build,
1351 // neither are any of its overrides.
1353 // Also, this should process the overrides for a class ASAP (ideally before any derived
1354 // classes) if the target class 'requires' the overrides. Without some special handling, the
1355 // overrides so required will be processed before the class and have to be bufferred even
1358 // TODO - we should probably support the "config" processor on an override (to config new
1359 // functionaliy like Aria) and maybe inheritableStatics (although static is now supported
1360 // by callSuper). If inheritableStatics causes those statics to be included on derived class
1361 // constructors, that probably means "no" to this since an override can come after other
1362 // classes extend the target.
1363 return Manager.create(overrideName, {
1367 constructor: function () {
1368 //<debug error>
1369 throw new Error("Cannot create override '" + overrideName + "'");
1373 var cls = Manager.get(className);
1374 if (cls.override) { // if (normal class)
1376 } else { // else (singleton)
1377 cls.self.override(data);
1381 // called once the override is applied and with the context of the
1382 // overridden class (the override itself is a meaningless, name-only
1384 createdFn.call(cls);
1389 <span id='Ext-method-getClassName'> /**
1392 * @alias Ext.ClassManager#getName
1394 getClassName: alias(Manager, 'getName'),
1396 <span id='Ext-ClassManager-method-getDisplayName'> /**
1397 </span> * Returns the displayName property or className or object.
1398 * When all else fails, returns "Anonymous".
1399 * @param {Object} object
1402 getDisplayName: function(object) {
1403 if (object.displayName) {
1404 return object.displayName;
1407 if (object.$name && object.$class) {
1408 return Ext.getClassName(object.$class) + '#' + object.$name;
1411 if (object.$className) {
1412 return object.$className;
1418 <span id='Ext-method-getClass'> /**
1421 * @alias Ext.ClassManager#getClass
1423 getClass: alias(Manager, 'getClass'),
1425 <span id='Ext-method-namespace'> /**
1426 </span> * Creates namespaces to be used for scoping variables and classes so that they are not global.
1427 * Specifying the last node of a namespace implicitly creates all other nodes. Usage:
1429 * Ext.namespace('Company', 'Company.data');
1431 * // equivalent and preferable to the above syntax
1432 * Ext.namespace('Company.data');
1434 * Company.Widget = function() { ... };
1436 * Company.data.CustomStore = function(config) { ... };
1440 * @param {String} namespace1
1441 * @param {String} namespace2
1442 * @param {String} etc
1443 * @return {Object} The namespace object. (If multiple arguments are passed, this will be the last namespace created)
1445 namespace: alias(Manager, 'createNamespaces')
1448 <span id='Ext-method-createWidget'> /**
1449 </span> * Old name for {@link Ext#widget}.
1450 * @deprecated 4.0.0 Use {@link Ext#widget} instead.
1455 Ext.createWidget = Ext.widget;
1457 <span id='Ext-method-ns'> /**
1458 </span> * Convenient alias for {@link Ext#namespace Ext.namespace}
1461 * @alias Ext#namespace
1463 Ext.ns = Ext.namespace;
1465 Class.registerPreprocessor('className', function(cls, data) {
1466 if (data.$className) {
1467 cls.$className = data.$className;
1469 cls.displayName = cls.$className;
1474 Class.setDefaultPreprocessorPosition('className', 'first');
1476 Class.registerPreprocessor('xtype', function(cls, data) {
1477 var xtypes = Ext.Array.from(data.xtype),
1478 widgetPrefix = 'widget.',
1479 aliases = Ext.Array.from(data.alias),
1482 data.xtype = xtypes[0];
1483 data.xtypes = xtypes;
1485 aliases = data.alias = Ext.Array.from(data.alias);
1487 for (i = 0,ln = xtypes.length; i < ln; i++) {
1490 //<debug error>
1491 if (typeof xtype != 'string' || xtype.length < 1) {
1492 throw new Error("[Ext.define] Invalid xtype of: '" + xtype + "' for class: '" + name + "'; must be a valid non-empty string");
1496 aliases.push(widgetPrefix + xtype);
1499 data.alias = aliases;
1502 Class.setDefaultPreprocessorPosition('xtype', 'last');
1504 Class.registerPreprocessor('alias', function(cls, data) {
1505 var aliases = Ext.Array.from(data.alias),
1506 xtypes = Ext.Array.from(data.xtypes),
1507 widgetPrefix = 'widget.',
1508 widgetPrefixLength = widgetPrefix.length,
1509 i, ln, alias, xtype;
1511 for (i = 0, ln = aliases.length; i < ln; i++) {
1514 //<debug error>
1515 if (typeof alias != 'string') {
1516 throw new Error("[Ext.define] Invalid alias of: '" + alias + "' for class: '" + name + "'; must be a valid string");
1520 if (alias.substring(0, widgetPrefixLength) === widgetPrefix) {
1521 xtype = alias.substring(widgetPrefixLength);
1522 Ext.Array.include(xtypes, xtype);
1525 cls.xtype = data.xtype = xtype;
1530 data.alias = aliases;
1531 data.xtypes = xtypes;
1534 Class.setDefaultPreprocessorPosition('alias', 'last');
1536 })(Ext.Class, Ext.Function.alias);