hangoutsslackgmailskypefacebook-workplaceoutlookemailmicrosoft-teamsdiscordmessengercustom-servicesmacoslinuxwindowsinboxwhatsappicloudtweetdeckhipchattelegram
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2029 lines
67 KiB
2029 lines
67 KiB
9 years ago
|
// @tag class
|
||
|
/**
|
||
|
* @class Ext.ClassManager
|
||
|
*
|
||
|
* Ext.ClassManager manages all classes and handles mapping from string class name to
|
||
|
* actual class objects throughout the whole framework. It is not generally accessed directly, rather through
|
||
|
* these convenient shorthands:
|
||
|
*
|
||
|
* - {@link Ext#define Ext.define}
|
||
|
* - {@link Ext#create Ext.create}
|
||
|
* - {@link Ext#widget Ext.widget}
|
||
|
* - {@link Ext#getClass Ext.getClass}
|
||
|
* - {@link Ext#getClassName Ext.getClassName}
|
||
|
*
|
||
|
* # Basic syntax:
|
||
|
*
|
||
|
* Ext.define(className, properties);
|
||
|
*
|
||
|
* in which `properties` is an object represent a collection of properties that apply to the class. See
|
||
|
* {@link Ext.ClassManager#create} for more detailed instructions.
|
||
|
*
|
||
|
* Ext.define('Person', {
|
||
|
* name: 'Unknown',
|
||
|
*
|
||
|
* constructor: function(name) {
|
||
|
* if (name) {
|
||
|
* this.name = name;
|
||
|
* }
|
||
|
* },
|
||
|
*
|
||
|
* eat: function(foodType) {
|
||
|
* alert("I'm eating: " + foodType);
|
||
|
*
|
||
|
* return this;
|
||
|
* }
|
||
|
* });
|
||
|
*
|
||
|
* var aaron = new Person("Aaron");
|
||
|
* aaron.eat("Sandwich"); // alert("I'm eating: Sandwich");
|
||
|
*
|
||
|
* Ext.Class has a powerful set of extensible {@link Ext.Class#registerPreprocessor pre-processors} which takes care of
|
||
|
* everything related to class creation, including but not limited to inheritance, mixins, configuration, statics, etc.
|
||
|
*
|
||
|
* # Inheritance:
|
||
|
*
|
||
|
* Ext.define('Developer', {
|
||
|
* extend: 'Person',
|
||
|
*
|
||
|
* constructor: function(name, isGeek) {
|
||
|
* this.isGeek = isGeek;
|
||
|
*
|
||
|
* // Apply a method from the parent class' prototype
|
||
|
* this.callParent([name]);
|
||
|
* },
|
||
|
*
|
||
|
* code: function(language) {
|
||
|
* alert("I'm coding in: " + language);
|
||
|
*
|
||
|
* this.eat("Bugs");
|
||
|
*
|
||
|
* return this;
|
||
|
* }
|
||
|
* });
|
||
|
*
|
||
|
* var jacky = new Developer("Jacky", true);
|
||
|
* jacky.code("JavaScript"); // alert("I'm coding in: JavaScript");
|
||
|
* // alert("I'm eating: Bugs");
|
||
|
*
|
||
|
* See {@link Ext.Base#callParent} for more details on calling superclass' methods
|
||
|
*
|
||
|
* # Mixins:
|
||
|
*
|
||
|
* Ext.define('CanPlayGuitar', {
|
||
|
* playGuitar: function() {
|
||
|
* alert("F#...G...D...A");
|
||
|
* }
|
||
|
* });
|
||
|
*
|
||
|
* Ext.define('CanComposeSongs', {
|
||
|
* composeSongs: function() { ... }
|
||
|
* });
|
||
|
*
|
||
|
* Ext.define('CanSing', {
|
||
|
* sing: function() {
|
||
|
* alert("For he's a jolly good fellow...")
|
||
|
* }
|
||
|
* });
|
||
|
*
|
||
|
* Ext.define('Musician', {
|
||
|
* extend: 'Person',
|
||
|
*
|
||
|
* mixins: {
|
||
|
* canPlayGuitar: 'CanPlayGuitar',
|
||
|
* canComposeSongs: 'CanComposeSongs',
|
||
|
* canSing: 'CanSing'
|
||
|
* }
|
||
|
* })
|
||
|
*
|
||
|
* Ext.define('CoolPerson', {
|
||
|
* extend: 'Person',
|
||
|
*
|
||
|
* mixins: {
|
||
|
* canPlayGuitar: 'CanPlayGuitar',
|
||
|
* canSing: 'CanSing'
|
||
|
* },
|
||
|
*
|
||
|
* sing: function() {
|
||
|
* alert("Ahem....");
|
||
|
*
|
||
|
* this.mixins.canSing.sing.call(this);
|
||
|
*
|
||
|
* alert("[Playing guitar at the same time...]");
|
||
|
*
|
||
|
* this.playGuitar();
|
||
|
* }
|
||
|
* });
|
||
|
*
|
||
|
* var me = new CoolPerson("Jacky");
|
||
|
*
|
||
|
* me.sing(); // alert("Ahem...");
|
||
|
* // alert("For he's a jolly good fellow...");
|
||
|
* // alert("[Playing guitar at the same time...]");
|
||
|
* // alert("F#...G...D...A");
|
||
|
*
|
||
|
* # Config:
|
||
|
*
|
||
|
* Ext.define('SmartPhone', {
|
||
|
* config: {
|
||
|
* hasTouchScreen: false,
|
||
|
* operatingSystem: 'Other',
|
||
|
* price: 500
|
||
|
* },
|
||
|
*
|
||
|
* isExpensive: false,
|
||
|
*
|
||
|
* constructor: function(config) {
|
||
|
* this.initConfig(config);
|
||
|
* },
|
||
|
*
|
||
|
* applyPrice: function(price) {
|
||
|
* this.isExpensive = (price > 500);
|
||
|
*
|
||
|
* return price;
|
||
|
* },
|
||
|
*
|
||
|
* applyOperatingSystem: function(operatingSystem) {
|
||
|
* if (!(/^(iOS|Android|BlackBerry)$/i).test(operatingSystem)) {
|
||
|
* return 'Other';
|
||
|
* }
|
||
|
*
|
||
|
* return operatingSystem;
|
||
|
* }
|
||
|
* });
|
||
|
*
|
||
|
* var iPhone = new SmartPhone({
|
||
|
* hasTouchScreen: true,
|
||
|
* operatingSystem: 'iOS'
|
||
|
* });
|
||
|
*
|
||
|
* iPhone.getPrice(); // 500;
|
||
|
* iPhone.getOperatingSystem(); // 'iOS'
|
||
|
* iPhone.getHasTouchScreen(); // true;
|
||
|
*
|
||
|
* iPhone.isExpensive; // false;
|
||
|
* iPhone.setPrice(600);
|
||
|
* iPhone.getPrice(); // 600
|
||
|
* iPhone.isExpensive; // true;
|
||
|
*
|
||
|
* iPhone.setOperatingSystem('AlienOS');
|
||
|
* iPhone.getOperatingSystem(); // 'Other'
|
||
|
*
|
||
|
* # Statics:
|
||
|
*
|
||
|
* Ext.define('Computer', {
|
||
|
* statics: {
|
||
|
* factory: function(brand) {
|
||
|
* // 'this' in static methods refer to the class itself
|
||
|
* return new this(brand);
|
||
|
* }
|
||
|
* },
|
||
|
*
|
||
|
* constructor: function() { ... }
|
||
|
* });
|
||
|
*
|
||
|
* var dellComputer = Computer.factory('Dell');
|
||
|
*
|
||
|
* Also see {@link Ext.Base#statics} and {@link Ext.Base#self} for more details on accessing
|
||
|
* static properties within class methods
|
||
|
*
|
||
|
* @singleton
|
||
|
*/
|
||
|
Ext.ClassManager = (function(Class, alias, arraySlice, arrayFrom, global) {
|
||
|
// @define Ext.ClassManager
|
||
|
// @require Ext.Inventory
|
||
|
// @require Ext.Class
|
||
|
// @require Ext.Function
|
||
|
// @require Ext.Array
|
||
|
|
||
|
var makeCtor = Ext.Class.makeCtor,
|
||
|
//<if nonBrowser>
|
||
|
isNonBrowser = typeof window === 'undefined',
|
||
|
//</if>
|
||
|
|
||
|
Manager = Ext.apply(new Ext.Inventory(), {
|
||
|
/**
|
||
|
* @property {Object} classes
|
||
|
* All classes which were defined through the ClassManager. Keys are the
|
||
|
* name of the classes and the values are references to the classes.
|
||
|
* @private
|
||
|
*/
|
||
|
classes: {},
|
||
|
|
||
|
classState: {
|
||
|
/*
|
||
|
* 'Ext.foo.Bar': <state enum>
|
||
|
*
|
||
|
* 10 = Ext.define called
|
||
|
* 20 = Ext.define/override called
|
||
|
* 30 = Manager.existCache[<name>] == true for define
|
||
|
* 40 = Manager.existCache[<name>] == true for define/override
|
||
|
* 50 = Manager.isCreated(<name>) == true for define
|
||
|
* 60 = Manager.isCreated(<name>) == true for define/override
|
||
|
*
|
||
|
*/
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
existCache: {},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
namespaceRewrites: [{
|
||
|
from: 'Ext.',
|
||
|
to: Ext
|
||
|
}],
|
||
|
|
||
|
/** @private */
|
||
|
enableNamespaceParseCache: true,
|
||
|
|
||
|
/** @private */
|
||
|
namespaceParseCache: {},
|
||
|
|
||
|
/** @private */
|
||
|
instantiators: [],
|
||
|
|
||
|
/**
|
||
|
* Checks if a class has already been created.
|
||
|
*
|
||
|
* @param {String} className
|
||
|
* @return {Boolean} exist
|
||
|
*/
|
||
|
isCreated: function(className) {
|
||
|
var i, ln, part, root, parts;
|
||
|
|
||
|
//<debug>
|
||
|
if (typeof className !== 'string' || className.length < 1) {
|
||
|
throw new Error("[Ext.ClassManager] Invalid classname, must be a string and must not be empty");
|
||
|
}
|
||
|
//</debug>
|
||
|
|
||
|
if (Manager.classes[className] || Manager.existCache[className]) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
root = global;
|
||
|
parts = Manager.parseNamespace(className);
|
||
|
|
||
|
for (i = 0, ln = parts.length; i < ln; i++) {
|
||
|
part = parts[i];
|
||
|
|
||
|
if (typeof part !== 'string') {
|
||
|
root = part;
|
||
|
} else {
|
||
|
if (!root || !root[part]) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
root = root[part];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Manager.triggerCreated(className);
|
||
|
|
||
|
return true;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
createdListeners: [],
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
nameCreatedListeners: {},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
existsListeners: [],
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
nameExistsListeners: {},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
overrideMap: {},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
triggerCreated: function (className, state) {
|
||
|
Manager.existCache[className] = state || 1;
|
||
|
Manager.classState[className] += 40;
|
||
|
Manager.notify(className, Manager.createdListeners, Manager.nameCreatedListeners);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
onCreated: function(fn, scope, className) {
|
||
|
Manager.addListener(fn, scope, className, Manager.createdListeners, Manager.nameCreatedListeners);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
notify: function (className, listeners, nameListeners) {
|
||
|
var alternateNames = Manager.getAlternatesByName(className),
|
||
|
names = [className],
|
||
|
i, ln, j, subLn, listener, name;
|
||
|
|
||
|
for (i = 0,ln = listeners.length; i < ln; i++) {
|
||
|
listener = listeners[i];
|
||
|
listener.fn.call(listener.scope, className);
|
||
|
}
|
||
|
|
||
|
while (names) {
|
||
|
for (i = 0,ln = names.length; i < ln; i++) {
|
||
|
name = names[i];
|
||
|
listeners = nameListeners[name];
|
||
|
|
||
|
if (listeners) {
|
||
|
for (j = 0,subLn = listeners.length; j < subLn; j++) {
|
||
|
listener = listeners[j];
|
||
|
listener.fn.call(listener.scope, name);
|
||
|
}
|
||
|
delete nameListeners[name];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
names = alternateNames; // for 2nd pass (if needed)
|
||
|
alternateNames = null; // no 3rd pass
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
addListener: function(fn, scope, className, listeners, nameListeners) {
|
||
|
if (Ext.isArray(className)) {
|
||
|
fn = Ext.Function.createBarrier(className.length, fn, scope);
|
||
|
for (i = 0; i < className.length; i++) {
|
||
|
this.addListener(fn, null, className[i], listeners, nameListeners);
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
var i,
|
||
|
listener = {
|
||
|
fn: fn,
|
||
|
scope: scope
|
||
|
};
|
||
|
|
||
|
if (className) {
|
||
|
if (this.isCreated(className)) {
|
||
|
fn.call(scope, className);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!nameListeners[className]) {
|
||
|
nameListeners[className] = [];
|
||
|
}
|
||
|
|
||
|
nameListeners[className].push(listener);
|
||
|
}
|
||
|
else {
|
||
|
listeners.push(listener);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Supports namespace rewriting.
|
||
|
* @private
|
||
|
*/
|
||
|
parseNamespace: function(namespace) {
|
||
|
//<debug>
|
||
|
if (typeof namespace !== 'string') {
|
||
|
throw new Error("[Ext.ClassManager] Invalid namespace, must be a string");
|
||
|
}
|
||
|
//</debug>
|
||
|
|
||
|
var cache = this.namespaceParseCache,
|
||
|
parts,
|
||
|
rewrites,
|
||
|
root,
|
||
|
name,
|
||
|
rewrite, from, to, i, ln;
|
||
|
|
||
|
if (this.enableNamespaceParseCache) {
|
||
|
if (cache.hasOwnProperty(namespace)) {
|
||
|
return cache[namespace];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
parts = [];
|
||
|
rewrites = this.namespaceRewrites;
|
||
|
root = global;
|
||
|
name = namespace;
|
||
|
|
||
|
for (i = 0, ln = rewrites.length; i < ln; i++) {
|
||
|
rewrite = rewrites[i];
|
||
|
from = rewrite.from;
|
||
|
to = rewrite.to;
|
||
|
|
||
|
if (name === from || name.substring(0, from.length) === from) {
|
||
|
name = name.substring(from.length);
|
||
|
|
||
|
if (typeof to !== 'string') {
|
||
|
root = to;
|
||
|
} else {
|
||
|
parts = parts.concat(to.split('.'));
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
parts.push(root);
|
||
|
|
||
|
parts = parts.concat(name.split('.'));
|
||
|
|
||
|
if (this.enableNamespaceParseCache) {
|
||
|
cache[namespace] = parts;
|
||
|
}
|
||
|
|
||
|
return parts;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Creates a namespace and assign the `value` to the created object.
|
||
|
*
|
||
|
* Ext.ClassManager.setNamespace('MyCompany.pkg.Example', someObject);
|
||
|
*
|
||
|
* alert(MyCompany.pkg.Example === someObject); // alerts true
|
||
|
*
|
||
|
* @param {String} name
|
||
|
* @param {Object} value
|
||
|
*/
|
||
|
setNamespace: function(name, value) {
|
||
|
var root = global,
|
||
|
parts = this.parseNamespace(name),
|
||
|
ln = parts.length - 1,
|
||
|
leaf = parts[ln],
|
||
|
i, part;
|
||
|
|
||
|
for (i = 0; i < ln; i++) {
|
||
|
part = parts[i];
|
||
|
|
||
|
if (typeof part !== 'string') {
|
||
|
root = part;
|
||
|
} else {
|
||
|
if (!root[part]) {
|
||
|
root[part] = {};
|
||
|
}
|
||
|
|
||
|
root = root[part];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
root[leaf] = value;
|
||
|
|
||
|
return root[leaf];
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* The new Ext.ns, supports namespace rewriting.
|
||
|
* @private
|
||
|
*/
|
||
|
createNamespaces: function() {
|
||
|
var root = global,
|
||
|
parts, part, i, j, ln, subLn;
|
||
|
|
||
|
for (i = 0, ln = arguments.length; i < ln; i++) {
|
||
|
parts = this.parseNamespace(arguments[i]);
|
||
|
|
||
|
for (j = 0, subLn = parts.length; j < subLn; j++) {
|
||
|
part = parts[j];
|
||
|
|
||
|
if (typeof part !== 'string') {
|
||
|
root = part;
|
||
|
} else {
|
||
|
if (!root[part]) {
|
||
|
root[part] = {};
|
||
|
}
|
||
|
|
||
|
root = root[part];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return root;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Sets a name reference to a class.
|
||
|
*
|
||
|
* @param {String} name
|
||
|
* @param {Object} value
|
||
|
* @return {Ext.ClassManager} this
|
||
|
*/
|
||
|
set: function (name, value) {
|
||
|
var me = this,
|
||
|
targetName = me.getName(value);
|
||
|
|
||
|
me.classes[name] = me.setNamespace(name, value);
|
||
|
|
||
|
if (targetName && targetName !== name) {
|
||
|
me.addAlternate(targetName, name);
|
||
|
}
|
||
|
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Retrieve a class by its name.
|
||
|
*
|
||
|
* @param {String} name
|
||
|
* @return {Ext.Class} class
|
||
|
*/
|
||
|
get: function(name) {
|
||
|
var classes = this.classes,
|
||
|
root,
|
||
|
parts,
|
||
|
part, i, ln;
|
||
|
|
||
|
if (classes[name]) {
|
||
|
return classes[name];
|
||
|
}
|
||
|
|
||
|
root = global;
|
||
|
parts = this.parseNamespace(name);
|
||
|
|
||
|
for (i = 0, ln = parts.length; i < ln; i++) {
|
||
|
part = parts[i];
|
||
|
|
||
|
if (typeof part !== 'string') {
|
||
|
root = part;
|
||
|
} else {
|
||
|
if (!root || !root[part]) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
root = root[part];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return root;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Adds a batch of class name to alias mappings.
|
||
|
* @param {Object} aliases The set of mappings of the form.
|
||
|
* className : [values...]
|
||
|
*/
|
||
|
addNameAliasMappings: function(aliases) {
|
||
|
this.addAlias(aliases);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
* @param {Object} alternates The set of mappings of the form
|
||
|
* className : [values...]
|
||
|
*/
|
||
|
addNameAlternateMappings: function (alternates) {
|
||
|
this.addAlternate(alternates);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get a reference to the class by its alias.
|
||
|
*
|
||
|
* @param {String} alias
|
||
|
* @return {Ext.Class} class
|
||
|
*/
|
||
|
getByAlias: function(alias) {
|
||
|
return this.get(this.getNameByAlias(alias));
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get the name of the class by its reference or its instance. This is
|
||
|
* usually invoked by the shorthand {@link Ext#getClassName}.
|
||
|
*
|
||
|
* Ext.ClassManager.getName(Ext.Action); // returns "Ext.Action"
|
||
|
*
|
||
|
* @param {Ext.Class/Object} object
|
||
|
* @return {String} className
|
||
|
*/
|
||
|
getName: function(object) {
|
||
|
return object && object.$className || '';
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Get the class of the provided object; returns null if it's not an instance
|
||
|
* of any class created with Ext.define. This is usually invoked by the
|
||
|
* shorthand {@link Ext#getClass}.
|
||
|
*
|
||
|
* var component = new Ext.Component();
|
||
|
*
|
||
|
* Ext.getClass(component); // returns Ext.Component
|
||
|
*
|
||
|
* @param {Object} object
|
||
|
* @return {Ext.Class} class
|
||
|
*/
|
||
|
getClass: function(object) {
|
||
|
return object && object.self || null;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Defines a class.
|
||
|
* @deprecated Use {@link Ext#define} instead, as that also supports creating overrides.
|
||
|
* @private
|
||
|
*/
|
||
|
create: function(className, data, createdFn) {
|
||
|
//<debug>
|
||
|
if (className != null && typeof className !== 'string') {
|
||
|
throw new Error("[Ext.define] Invalid class name '" + className + "' specified, must be a non-empty string");
|
||
|
}
|
||
|
//</debug>
|
||
|
|
||
|
var ctor = makeCtor(className);
|
||
|
if (typeof data === 'function') {
|
||
|
data = data(ctor);
|
||
|
}
|
||
|
|
||
|
//<debug>
|
||
|
if (className) {
|
||
|
if(Manager.classes[className]) {
|
||
|
Ext.log.warn("[Ext.define] Duplicate class name '" + className + "' specified, must be a non-empty string");
|
||
|
}
|
||
|
ctor.name = className;
|
||
|
}
|
||
|
//</debug>
|
||
|
|
||
|
data.$className = className;
|
||
|
|
||
|
return new Class(ctor, data, function() {
|
||
|
var postprocessorStack = data.postprocessors || Manager.defaultPostprocessors,
|
||
|
registeredPostprocessors = Manager.postprocessors,
|
||
|
postprocessors = [],
|
||
|
postprocessor, i, ln, j, subLn, postprocessorProperties, postprocessorProperty;
|
||
|
|
||
|
delete data.postprocessors;
|
||
|
|
||
|
for (i = 0,ln = postprocessorStack.length; i < ln; i++) {
|
||
|
postprocessor = postprocessorStack[i];
|
||
|
|
||
|
if (typeof postprocessor === 'string') {
|
||
|
postprocessor = registeredPostprocessors[postprocessor];
|
||
|
postprocessorProperties = postprocessor.properties;
|
||
|
|
||
|
if (postprocessorProperties === true) {
|
||
|
postprocessors.push(postprocessor.fn);
|
||
|
}
|
||
|
else if (postprocessorProperties) {
|
||
|
for (j = 0,subLn = postprocessorProperties.length; j < subLn; j++) {
|
||
|
postprocessorProperty = postprocessorProperties[j];
|
||
|
|
||
|
if (data.hasOwnProperty(postprocessorProperty)) {
|
||
|
postprocessors.push(postprocessor.fn);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
postprocessors.push(postprocessor);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
data.postprocessors = postprocessors;
|
||
|
data.createdFn = createdFn;
|
||
|
Manager.processCreate(className, this, data);
|
||
|
});
|
||
|
},
|
||
|
|
||
|
processCreate: function(className, cls, clsData){
|
||
|
var me = this,
|
||
|
postprocessor = clsData.postprocessors.shift(),
|
||
|
createdFn = clsData.createdFn;
|
||
|
|
||
|
if (!postprocessor) {
|
||
|
//<debug>
|
||
|
Ext.classSystemMonitor && Ext.classSystemMonitor(className, 'Ext.ClassManager#classCreated', arguments);
|
||
|
//</debug>
|
||
|
|
||
|
if (className) {
|
||
|
me.set(className, cls);
|
||
|
}
|
||
|
|
||
|
delete cls._classHooks;
|
||
|
|
||
|
if (createdFn) {
|
||
|
createdFn.call(cls, cls);
|
||
|
}
|
||
|
|
||
|
if (className) {
|
||
|
me.triggerCreated(className);
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (postprocessor.call(me, className, cls, clsData, me.processCreate) !== false) {
|
||
|
me.processCreate(className, cls, clsData);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
createOverride: function (className, data, createdFn) {
|
||
|
var me = this,
|
||
|
overriddenClassName = data.override,
|
||
|
requires = data.requires,
|
||
|
uses = data.uses,
|
||
|
mixins = data.mixins,
|
||
|
mixinsIsArray,
|
||
|
compat = data.compatibility,
|
||
|
depedenciesLoaded,
|
||
|
classReady = function () {
|
||
|
var cls, dependencies, i, key, temp;
|
||
|
|
||
|
if (!depedenciesLoaded) {
|
||
|
dependencies = requires ? requires.slice(0) : [];
|
||
|
|
||
|
if (mixins) {
|
||
|
if (!(mixinsIsArray = mixins instanceof Array)) {
|
||
|
for (key in mixins) {
|
||
|
if (Ext.isString(cls = mixins[key])) {
|
||
|
dependencies.push(cls);
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
for (i = 0, temp = mixins.length; i < temp; ++i) {
|
||
|
if (Ext.isString(cls = mixins[i])) {
|
||
|
dependencies.push(cls);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
depedenciesLoaded = true;
|
||
|
if (dependencies.length) {
|
||
|
// Since the override is going to be used (its target class is
|
||
|
// now created), we need to fetch the required classes for the
|
||
|
// override and call us back once they are loaded:
|
||
|
Ext.require(dependencies, classReady);
|
||
|
return;
|
||
|
}
|
||
|
// else we have no dependencies, so proceed
|
||
|
}
|
||
|
|
||
|
// transform mixin class names into class references, This
|
||
|
// loop can handle both the array and object forms of
|
||
|
// mixin definitions
|
||
|
if (mixinsIsArray) {
|
||
|
for (i = 0, temp = mixins.length; i < temp; ++i) {
|
||
|
if (Ext.isString(cls = mixins[i])) {
|
||
|
mixins[i] = Ext.ClassManager.get(cls);
|
||
|
}
|
||
|
}
|
||
|
} else if (mixins) {
|
||
|
for (key in mixins) {
|
||
|
if (Ext.isString(cls = mixins[key])) {
|
||
|
mixins[key] = Ext.ClassManager.get(cls);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// The target class and the required classes for this override are
|
||
|
// ready, so we can apply the override now:
|
||
|
cls = me.get(overriddenClassName);
|
||
|
|
||
|
// We don't want to apply these:
|
||
|
delete data.override;
|
||
|
delete data.compatibility;
|
||
|
delete data.requires;
|
||
|
delete data.uses;
|
||
|
|
||
|
Ext.override(cls, data);
|
||
|
|
||
|
// This pushes the overriding file itself into Ext.Loader.history
|
||
|
// Hence if the target class never exists, the overriding file will
|
||
|
// never be included in the build.
|
||
|
Ext.Loader.history.push(className);
|
||
|
|
||
|
if (uses) {
|
||
|
// This "hides" from the Cmd auto-dependency scanner since
|
||
|
// the reference is circular (Loader requires us).
|
||
|
Ext['Loader'].addUsedClasses(uses); // get these classes too!
|
||
|
}
|
||
|
|
||
|
if (createdFn) {
|
||
|
createdFn.call(cls, cls); // last but not least!
|
||
|
}
|
||
|
};
|
||
|
|
||
|
Manager.overrideMap[className] = true;
|
||
|
|
||
|
if (!compat || Ext.checkVersion(compat)) {
|
||
|
// Override the target class right after it's created
|
||
|
me.onCreated(classReady, me, overriddenClassName);
|
||
|
}
|
||
|
|
||
|
me.triggerCreated(className, 2);
|
||
|
return me;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Instantiate a class by its alias. This is usually invoked by the
|
||
|
* shorthand {@link Ext#createByAlias}.
|
||
|
*
|
||
|
* If {@link Ext.Loader} is {@link Ext.Loader#setConfig enabled} and the class
|
||
|
* has not been defined yet, it will attempt to load the class via synchronous
|
||
|
* loading.
|
||
|
*
|
||
|
* var window = Ext.createByAlias('widget.window', { width: 600, height: 800 });
|
||
|
*
|
||
|
* @param {String} alias
|
||
|
* @param {Object...} args Additional arguments after the alias will be passed to the
|
||
|
* class constructor.
|
||
|
* @return {Object} instance
|
||
|
*/
|
||
|
instantiateByAlias: function() {
|
||
|
var alias = arguments[0],
|
||
|
args = arraySlice.call(arguments),
|
||
|
className = this.getNameByAlias(alias);
|
||
|
|
||
|
//<debug>
|
||
|
if (!className) {
|
||
|
throw new Error("[Ext.createByAlias] Unrecognized alias: " + alias);
|
||
|
}
|
||
|
//</debug>
|
||
|
|
||
|
args[0] = className;
|
||
|
|
||
|
return Ext.create.apply(Ext, args);
|
||
|
},
|
||
|
|
||
|
//<deprecated since=5.0>
|
||
|
/**
|
||
|
* Instantiate a class by either full name, alias or alternate name
|
||
|
* @param {String} name
|
||
|
* @param {Mixed} args Additional arguments after the name will be passed to the class' constructor.
|
||
|
* @return {Object} instance
|
||
|
* @deprecated 5.0 Use Ext.create() instead.
|
||
|
*/
|
||
|
instantiate: function() {
|
||
|
//<debug>
|
||
|
Ext.log.warn('Ext.ClassManager.instantiate() is deprecated. Use Ext.create() instead.');
|
||
|
//</debug>
|
||
|
return Ext.create.apply(Ext, arguments);
|
||
|
},
|
||
|
//</deprecated>
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
* @param name
|
||
|
* @param args
|
||
|
*/
|
||
|
dynInstantiate: function(name, args) {
|
||
|
args = arrayFrom(args, true);
|
||
|
args.unshift(name);
|
||
|
|
||
|
return Ext.create.apply(Ext, args);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
* @param length
|
||
|
*/
|
||
|
getInstantiator: function(length) {
|
||
|
var instantiators = this.instantiators,
|
||
|
instantiator,
|
||
|
i,
|
||
|
args;
|
||
|
|
||
|
instantiator = instantiators[length];
|
||
|
|
||
|
if (!instantiator) {
|
||
|
i = length;
|
||
|
args = [];
|
||
|
|
||
|
for (i = 0; i < length; i++) {
|
||
|
args.push('a[' + i + ']');
|
||
|
}
|
||
|
|
||
|
instantiator = instantiators[length] = new Function('c', 'a', 'return new c(' + args.join(',') + ')');
|
||
|
//<debug>
|
||
|
instantiator.name = "Ext.create" + length;
|
||
|
//</debug>
|
||
|
}
|
||
|
|
||
|
return instantiator;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
postprocessors: {},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
defaultPostprocessors: [],
|
||
|
|
||
|
/**
|
||
|
* Register a post-processor function.
|
||
|
*
|
||
|
* @private
|
||
|
* @param {String} name
|
||
|
* @param {Function} postprocessor
|
||
|
*/
|
||
|
registerPostprocessor: function(name, fn, properties, position, relativeTo) {
|
||
|
if (!position) {
|
||
|
position = 'last';
|
||
|
}
|
||
|
|
||
|
if (!properties) {
|
||
|
properties = [name];
|
||
|
}
|
||
|
|
||
|
this.postprocessors[name] = {
|
||
|
name: name,
|
||
|
properties: properties || false,
|
||
|
fn: fn
|
||
|
};
|
||
|
|
||
|
this.setDefaultPostprocessorPosition(name, position, relativeTo);
|
||
|
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Set the default post processors array stack which are applied to every class.
|
||
|
*
|
||
|
* @private
|
||
|
* @param {String/Array} postprocessors The name of a registered post processor or an array of registered names.
|
||
|
* @return {Ext.ClassManager} this
|
||
|
*/
|
||
|
setDefaultPostprocessors: function(postprocessors) {
|
||
|
this.defaultPostprocessors = arrayFrom(postprocessors);
|
||
|
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Insert this post-processor at a specific position in the stack, optionally relative to
|
||
|
* any existing post-processor
|
||
|
*
|
||
|
* @private
|
||
|
* @param {String} name The post-processor name. Note that it needs to be registered with
|
||
|
* {@link Ext.ClassManager#registerPostprocessor} before this
|
||
|
* @param {String} offset The insertion position. Four possible values are:
|
||
|
* 'first', 'last', or: 'before', 'after' (relative to the name provided in the third argument)
|
||
|
* @param {String} relativeName
|
||
|
* @return {Ext.ClassManager} this
|
||
|
*/
|
||
|
setDefaultPostprocessorPosition: function(name, offset, relativeName) {
|
||
|
var defaultPostprocessors = this.defaultPostprocessors,
|
||
|
index;
|
||
|
|
||
|
if (typeof offset === 'string') {
|
||
|
if (offset === 'first') {
|
||
|
defaultPostprocessors.unshift(name);
|
||
|
|
||
|
return this;
|
||
|
}
|
||
|
else if (offset === 'last') {
|
||
|
defaultPostprocessors.push(name);
|
||
|
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
offset = (offset === 'after') ? 1 : -1;
|
||
|
}
|
||
|
|
||
|
index = Ext.Array.indexOf(defaultPostprocessors, relativeName);
|
||
|
|
||
|
if (index !== -1) {
|
||
|
Ext.Array.splice(defaultPostprocessors, Math.max(0, index + offset), 0, name);
|
||
|
}
|
||
|
|
||
|
return this;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* @cfg xtype
|
||
|
* @member Ext.Class
|
||
|
* @inheritdoc Ext.Component#cfg-xtype
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @cfg {String} override
|
||
|
* @member Ext.Class
|
||
|
* Overrides members of the specified `target` class.
|
||
|
*
|
||
|
* **NOTE:** the overridden class must have been defined using
|
||
|
* {@link #define Ext.define} in order to use the `override` config.
|
||
|
*
|
||
|
* Methods defined on the overriding class will not automatically call the methods of
|
||
|
* the same name in the ancestor class chain. To call the parent's method of the
|
||
|
* same name you must call {@link Ext.Base#callParent callParent}. To skip the
|
||
|
* method of the overridden class and call its parent you will instead call
|
||
|
* {@link Ext.Base#callSuper callSuper}.
|
||
|
*
|
||
|
* See {@link Ext#define Ext.define} for additional usage examples.
|
||
|
*/
|
||
|
|
||
|
//<feature classSystem.alias>
|
||
|
/**
|
||
|
* @cfg {String/String[]} alias
|
||
|
* @member Ext.Class
|
||
|
* List of short aliases for class names. An alias consists of a namespace and a name concatenated by a period as <namespace>.<name>
|
||
|
*
|
||
|
* - **namespace** - The namespace describes what kind of alias this is and must be all lowercase.
|
||
|
* - **name** - The name of the alias which allows the lazy-instantiation via the alias. The name shouldn't contain any periods.
|
||
|
*
|
||
|
* A list of namespaces and the usages are:
|
||
|
*
|
||
|
* - **feature** - {@link Ext.grid.Panel Grid} features
|
||
|
* - **plugin** - Plugins
|
||
|
* - **store** - {@link Ext.data.Store}
|
||
|
* - **widget** - Components
|
||
|
*
|
||
|
* Most useful for defining xtypes for widgets:
|
||
|
*
|
||
|
* Ext.define('MyApp.CoolPanel', {
|
||
|
* extend: 'Ext.panel.Panel',
|
||
|
* alias: ['widget.coolpanel'],
|
||
|
* title: 'Yeah!'
|
||
|
* });
|
||
|
*
|
||
|
* // Using Ext.create
|
||
|
* Ext.create('widget.coolpanel');
|
||
|
*
|
||
|
* // Using the shorthand for defining widgets by xtype
|
||
|
* Ext.widget('panel', {
|
||
|
* items: [
|
||
|
* {xtype: 'coolpanel', html: 'Foo'},
|
||
|
* {xtype: 'coolpanel', html: 'Bar'}
|
||
|
* ]
|
||
|
* });
|
||
|
*/
|
||
|
Manager.registerPostprocessor('alias', function(name, cls, data) {
|
||
|
//<debug>
|
||
|
Ext.classSystemMonitor && Ext.classSystemMonitor(name, 'Ext.ClassManager#aliasPostProcessor', arguments);
|
||
|
//</debug>
|
||
|
|
||
|
var aliases = Ext.Array.from(data.alias),
|
||
|
i, ln;
|
||
|
|
||
|
for (i = 0,ln = aliases.length; i < ln; i++) {
|
||
|
alias = aliases[i];
|
||
|
|
||
|
this.addAlias(cls, alias);
|
||
|
}
|
||
|
|
||
|
}, ['xtype', 'alias']);
|
||
|
//</feature>
|
||
|
|
||
|
//<feature classSystem.singleton>
|
||
|
/**
|
||
|
* @cfg {Boolean} singleton
|
||
|
* @member Ext.Class
|
||
|
* When set to true, the class will be instantiated as singleton. For example:
|
||
|
*
|
||
|
* Ext.define('Logger', {
|
||
|
* singleton: true,
|
||
|
* log: function(msg) {
|
||
|
* console.log(msg);
|
||
|
* }
|
||
|
* });
|
||
|
*
|
||
|
* Logger.log('Hello');
|
||
|
*/
|
||
|
Manager.registerPostprocessor('singleton', function(name, cls, data, fn) {
|
||
|
//<debug>
|
||
|
Ext.classSystemMonitor && Ext.classSystemMonitor(name, 'Ext.ClassManager#singletonPostProcessor', arguments);
|
||
|
//</debug>
|
||
|
|
||
|
if (data.singleton) {
|
||
|
fn.call(this, name, new cls(), data);
|
||
|
}
|
||
|
else {
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
});
|
||
|
//</feature>
|
||
|
|
||
|
//<feature classSystem.alternateClassName>
|
||
|
/**
|
||
|
* @cfg {String/String[]} alternateClassName
|
||
|
* @member Ext.Class
|
||
|
* Defines alternate names for this class. For example:
|
||
|
*
|
||
|
* Ext.define('Developer', {
|
||
|
* alternateClassName: ['Coder', 'Hacker'],
|
||
|
* code: function(msg) {
|
||
|
* alert('Typing... ' + msg);
|
||
|
* }
|
||
|
* });
|
||
|
*
|
||
|
* var joe = Ext.create('Developer');
|
||
|
* joe.code('stackoverflow');
|
||
|
*
|
||
|
* var rms = Ext.create('Hacker');
|
||
|
* rms.code('hack hack');
|
||
|
*/
|
||
|
Manager.registerPostprocessor('alternateClassName', function(name, cls, data) {
|
||
|
//<debug>
|
||
|
Ext.classSystemMonitor && Ext.classSystemMonitor(name, 'Ext.ClassManager#alternateClassNamePostprocessor', arguments);
|
||
|
//</debug>
|
||
|
|
||
|
var alternates = data.alternateClassName,
|
||
|
i, ln, alternate;
|
||
|
|
||
|
if (!(alternates instanceof Array)) {
|
||
|
alternates = [alternates];
|
||
|
}
|
||
|
|
||
|
for (i = 0, ln = alternates.length; i < ln; i++) {
|
||
|
alternate = alternates[i];
|
||
|
|
||
|
//<debug>
|
||
|
if (typeof alternate !== 'string') {
|
||
|
throw new Error("[Ext.define] Invalid alternate of: '" + alternate + "' for class: '" + name + "'; must be a valid string");
|
||
|
}
|
||
|
//</debug>
|
||
|
|
||
|
this.set(alternate, cls);
|
||
|
}
|
||
|
});
|
||
|
//</feature>
|
||
|
|
||
|
/**
|
||
|
* @cfg {Object} debugHooks
|
||
|
* A collection of diagnostic methods to decorate the real methods of the class. These
|
||
|
* methods are applied as an `override` if this class has debug enabled as defined by
|
||
|
* `Ext.isDebugEnabled`.
|
||
|
*
|
||
|
* These will be automatically removed by the Sencha Cmd compiler for production builds.
|
||
|
*
|
||
|
* Example usage:
|
||
|
*
|
||
|
* Ext.define('Foo.bar.Class', {
|
||
|
* foo: function (a, b, c) {
|
||
|
* ...
|
||
|
* },
|
||
|
*
|
||
|
* bar: function (a, b) {
|
||
|
* ...
|
||
|
* return 42;
|
||
|
* },
|
||
|
*
|
||
|
* debugHooks: {
|
||
|
* foo: function (a, b, c) {
|
||
|
* // check arguments...
|
||
|
* return this.callParent(arguments);
|
||
|
* }
|
||
|
* }
|
||
|
* });
|
||
|
*
|
||
|
* If you specify a `$enabled` property in the `debugHooks` object that will be used
|
||
|
* as the default enabled state for the hooks. If the `{@link Ext#manifest}` contains
|
||
|
* a `debug` object of if `{@link Ext#debugConfig}` is specified, the `$enabled` flag
|
||
|
* will override its "*" value.
|
||
|
*/
|
||
|
Manager.registerPostprocessor('debugHooks', function(name, Class, data) {
|
||
|
//<debug>
|
||
|
Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#debugHooks', arguments);
|
||
|
|
||
|
if (Ext.isDebugEnabled(Class.$className, data.debugHooks.$enabled)) {
|
||
|
delete data.debugHooks.$enabled;
|
||
|
Ext.override(Class, data.debugHooks);
|
||
|
}
|
||
|
//</debug>
|
||
|
|
||
|
// may already have an instance here in the case of singleton
|
||
|
var target = Class.isInstance ? Class.self : Class;
|
||
|
|
||
|
delete target.prototype.debugHooks;
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* @cfg {Object} deprecated
|
||
|
* The object given has properties that describe the versions at which the deprecations
|
||
|
* apply.
|
||
|
*
|
||
|
* The purpose of the `deprecated` declaration is to enable development mode to give
|
||
|
* suitable error messages when deprecated methods or properties are used. Methods can
|
||
|
* always be injected to provide this feedback, but properties can only be handled on
|
||
|
* some browsers (those that support `Object.defineProperty`).
|
||
|
*
|
||
|
* In some cases, deprecated methods can be restored to their previous behavior or
|
||
|
* added back if they have been removed.
|
||
|
*
|
||
|
* The structure of a `deprecated` declaration is this:
|
||
|
*
|
||
|
* Ext.define('Foo.bar.Class', {
|
||
|
* ...
|
||
|
*
|
||
|
* deprecated: {
|
||
|
* // Optional package name - default is the framework (ext or touch)
|
||
|
* name: 'foobar',
|
||
|
*
|
||
|
* '5.0': {
|
||
|
* methods: {
|
||
|
* // Throws: '"removedMethod" is deprecated.'
|
||
|
* removedMethod: null,
|
||
|
*
|
||
|
* // Throws: '"oldMethod" is deprecated. Please use "newMethod" instead.'
|
||
|
* oldMethod: 'newMethod',
|
||
|
*
|
||
|
* // When this block is enabled, this method is applied as an
|
||
|
* // override. Otherwise you get same as "removeMethod".
|
||
|
* method: function () {
|
||
|
* // Do what v5 "method" did. If "method" exists in newer
|
||
|
* // versions callParent can call it. If 5.1 has "method"
|
||
|
* // then it would be next in line, otherwise 5.2 and last
|
||
|
* // would be the current class.
|
||
|
* },
|
||
|
*
|
||
|
* moreHelpful: {
|
||
|
* message: 'Something helpful to do instead.',
|
||
|
* fn: function () {
|
||
|
* // The v5 "moreHelpful" method to use when enabled.
|
||
|
* }
|
||
|
* }
|
||
|
* },
|
||
|
* properties: {
|
||
|
* // Throws: '"removedProp" is deprecated.'
|
||
|
* removedProp: null,
|
||
|
*
|
||
|
* // Throws: '"oldProp" is deprecated. Please use "newProp" instead.'
|
||
|
* oldProp: 'newProp',
|
||
|
*
|
||
|
* helpful: {
|
||
|
* message: 'Something helpful message about what to do.'
|
||
|
* }
|
||
|
* ...
|
||
|
* },
|
||
|
* statics: {
|
||
|
* methods: {
|
||
|
* ...
|
||
|
* },
|
||
|
* properties: {
|
||
|
* ...
|
||
|
* },
|
||
|
* }
|
||
|
* },
|
||
|
*
|
||
|
* '5.1': {
|
||
|
* ...
|
||
|
* },
|
||
|
*
|
||
|
* '5.2': {
|
||
|
* ...
|
||
|
* }
|
||
|
* }
|
||
|
* });
|
||
|
*
|
||
|
* The primary content of `deprecated` are the version number keys. These indicate
|
||
|
* a version number where methods or properties were deprecated. These versions are
|
||
|
* compared to the version reported by `Ext.getCompatVersion` to determine the action
|
||
|
* to take for each "block".
|
||
|
*
|
||
|
* When the compatibility version is set to a value less than a version number key,
|
||
|
* that block is said to be "enabled". For example, if a method was deprecated in
|
||
|
* version 5.0 but the desired compatibility level is 4.2 then the block is used to
|
||
|
* patch methods and (to some degree) restore pre-5.0 compatibility.
|
||
|
*
|
||
|
* When multiple active blocks have the same method name, each method is applied as
|
||
|
* an override in reverse order of version. In the above example, if a method appears
|
||
|
* in the "5.0", "5.1" and "5.2" blocks then the "5.2" method is applied as an override
|
||
|
* first, followed by the "5.1" method and finally the "5.0" method. This means that
|
||
|
* the `callParent` from the "5.0" method calls the "5.1" method which calls the
|
||
|
* "5.2" method which can (if applicable) call the current version.
|
||
|
*/
|
||
|
Manager.registerPostprocessor('deprecated', function(name, Class, data) {
|
||
|
//<debug>
|
||
|
Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#deprecated', arguments);
|
||
|
//</debug>
|
||
|
|
||
|
// may already have an instance here in the case of singleton
|
||
|
var target = Class.isInstance ? Class.self : Class;
|
||
|
target.addDeprecations(data.deprecated);
|
||
|
|
||
|
delete target.prototype.deprecated;
|
||
|
});
|
||
|
|
||
|
Ext.apply(Ext, {
|
||
|
/**
|
||
|
* Instantiate a class by either full name, alias or alternate name.
|
||
|
*
|
||
|
* If {@link Ext.Loader} is {@link Ext.Loader#setConfig enabled} and the class has
|
||
|
* not been defined yet, it will attempt to load the class via synchronous loading.
|
||
|
*
|
||
|
* For example, all these three lines return the same result:
|
||
|
*
|
||
|
* // xtype
|
||
|
* var window = Ext.create({
|
||
|
* xtype: 'window',
|
||
|
* width: 600,
|
||
|
* height: 800,
|
||
|
* ...
|
||
|
* });
|
||
|
*
|
||
|
* // alias
|
||
|
* var window = Ext.create('widget.window', {
|
||
|
* width: 600,
|
||
|
* height: 800,
|
||
|
* ...
|
||
|
* });
|
||
|
*
|
||
|
* // alternate name
|
||
|
* var window = Ext.create('Ext.Window', {
|
||
|
* width: 600,
|
||
|
* height: 800,
|
||
|
* ...
|
||
|
* });
|
||
|
*
|
||
|
* // full class name
|
||
|
* var window = Ext.create('Ext.window.Window', {
|
||
|
* width: 600,
|
||
|
* height: 800,
|
||
|
* ...
|
||
|
* });
|
||
|
*
|
||
|
* // single object with xclass property:
|
||
|
* var window = Ext.create({
|
||
|
* xclass: 'Ext.window.Window', // any valid value for 'name' (above)
|
||
|
* width: 600,
|
||
|
* height: 800,
|
||
|
* ...
|
||
|
* });
|
||
|
*
|
||
|
* @param {String} [name] The class name or alias. Can be specified as `xclass`
|
||
|
* property if only one object parameter is specified.
|
||
|
* @param {Object...} [args] Additional arguments after the name will be passed to
|
||
|
* the class' constructor.
|
||
|
* @return {Object} instance
|
||
|
* @member Ext
|
||
|
* @method create
|
||
|
*/
|
||
|
create: function () {
|
||
|
var name = arguments[0],
|
||
|
nameType = typeof name,
|
||
|
args = arraySlice.call(arguments, 1),
|
||
|
cls;
|
||
|
|
||
|
if (nameType === 'function') {
|
||
|
cls = name;
|
||
|
} else {
|
||
|
if (nameType !== 'string' && args.length === 0) {
|
||
|
args = [name];
|
||
|
if (!(name = name.xclass)) {
|
||
|
name = args[0].xtype;
|
||
|
if (name) {
|
||
|
name = 'widget.' + name;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//<debug>
|
||
|
if (typeof name !== 'string' || name.length < 1) {
|
||
|
throw new Error("[Ext.create] Invalid class name or alias '" + name +
|
||
|
"' specified, must be a non-empty string");
|
||
|
}
|
||
|
//</debug>
|
||
|
|
||
|
name = Manager.resolveName(name);
|
||
|
cls = Manager.get(name);
|
||
|
}
|
||
|
|
||
|
// Still not existing at this point, try to load it via synchronous mode as the last resort
|
||
|
if (!cls) {
|
||
|
//<debug>
|
||
|
//<if nonBrowser>
|
||
|
!isNonBrowser &&
|
||
|
//</if>
|
||
|
Ext.log.warn("[Ext.Loader] Synchronously loading '" + name + "'; consider adding " +
|
||
|
"Ext.require('" + name + "') above Ext.onReady");
|
||
|
//</debug>
|
||
|
|
||
|
Ext.syncRequire(name);
|
||
|
|
||
|
cls = Manager.get(name);
|
||
|
}
|
||
|
|
||
|
//<debug>
|
||
|
if (!cls) {
|
||
|
throw new Error("[Ext.create] Unrecognized class name / alias: " + name);
|
||
|
}
|
||
|
|
||
|
if (typeof cls !== 'function') {
|
||
|
throw new Error("[Ext.create] Singleton '" + name + "' cannot be instantiated.");
|
||
|
}
|
||
|
//</debug>
|
||
|
|
||
|
return Manager.getInstantiator(args.length)(cls, args);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Convenient shorthand to create a widget by its xtype or a config object.
|
||
|
*
|
||
|
* var button = Ext.widget('button'); // Equivalent to Ext.create('widget.button');
|
||
|
*
|
||
|
* var panel = Ext.widget('panel', { // Equivalent to Ext.create('widget.panel')
|
||
|
* title: 'Panel'
|
||
|
* });
|
||
|
*
|
||
|
* var grid = Ext.widget({
|
||
|
* xtype: 'grid',
|
||
|
* ...
|
||
|
* });
|
||
|
*
|
||
|
* If a {@link Ext.Component component} instance is passed, it is simply returned.
|
||
|
*
|
||
|
* @member Ext
|
||
|
* @param {String} [name] The xtype of the widget to create.
|
||
|
* @param {Object} [config] The configuration object for the widget constructor.
|
||
|
* @return {Object} The widget instance
|
||
|
*/
|
||
|
widget: function(name, config) {
|
||
|
// forms:
|
||
|
// 1: (xtype)
|
||
|
// 2: (xtype, config)
|
||
|
// 3: (config)
|
||
|
// 4: (xtype, component)
|
||
|
// 5: (component)
|
||
|
//
|
||
|
var xtype = name,
|
||
|
alias, className, T;
|
||
|
|
||
|
if (typeof xtype !== 'string') { // if (form 3 or 5)
|
||
|
// first arg is config or component
|
||
|
config = name; // arguments[0]
|
||
|
xtype = config.xtype;
|
||
|
className = config.xclass;
|
||
|
} else {
|
||
|
config = config || {};
|
||
|
}
|
||
|
|
||
|
if (config.isComponent) {
|
||
|
return config;
|
||
|
}
|
||
|
|
||
|
if (!className) {
|
||
|
alias = 'widget.' + xtype;
|
||
|
className = Manager.getNameByAlias(alias);
|
||
|
}
|
||
|
|
||
|
// this is needed to support demand loading of the class
|
||
|
if (className) {
|
||
|
T = Manager.get(className);
|
||
|
}
|
||
|
|
||
|
if (!T) {
|
||
|
return Ext.create(className || alias, config);
|
||
|
}
|
||
|
return new T(config);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @inheritdoc Ext.ClassManager#instantiateByAlias
|
||
|
* @member Ext
|
||
|
* @method createByAlias
|
||
|
*/
|
||
|
createByAlias: alias(Manager, 'instantiateByAlias'),
|
||
|
|
||
|
/**
|
||
|
* Defines a class or override. A basic class is defined like this:
|
||
|
*
|
||
|
* Ext.define('My.awesome.Class', {
|
||
|
* someProperty: 'something',
|
||
|
*
|
||
|
* someMethod: function(s) {
|
||
|
* alert(s + this.someProperty);
|
||
|
* }
|
||
|
*
|
||
|
* ...
|
||
|
* });
|
||
|
*
|
||
|
* var obj = new My.awesome.Class();
|
||
|
*
|
||
|
* obj.someMethod('Say '); // alerts 'Say something'
|
||
|
*
|
||
|
* To create an anonymous class, pass `null` for the `className`:
|
||
|
*
|
||
|
* Ext.define(null, {
|
||
|
* constructor: function () {
|
||
|
* // ...
|
||
|
* }
|
||
|
* });
|
||
|
*
|
||
|
* In some cases, it is helpful to create a nested scope to contain some private
|
||
|
* properties. The best way to do this is to pass a function instead of an object
|
||
|
* as the second parameter. This function will be called to produce the class
|
||
|
* body:
|
||
|
*
|
||
|
* Ext.define('MyApp.foo.Bar', function () {
|
||
|
* var id = 0;
|
||
|
*
|
||
|
* return {
|
||
|
* nextId: function () {
|
||
|
* return ++id;
|
||
|
* }
|
||
|
* };
|
||
|
* });
|
||
|
*
|
||
|
* _Note_ that when using override, the above syntax will not override successfully, because
|
||
|
* the passed function would need to be executed first to determine whether or not the result
|
||
|
* is an override or defining a new object. As such, an alternative syntax that immediately
|
||
|
* invokes the function can be used:
|
||
|
*
|
||
|
* Ext.define('MyApp.override.BaseOverride', function () {
|
||
|
* var counter = 0;
|
||
|
*
|
||
|
* return {
|
||
|
* override: 'Ext.Component',
|
||
|
* logId: function () {
|
||
|
* console.log(++counter, this.id);
|
||
|
* }
|
||
|
* };
|
||
|
* }());
|
||
|
*
|
||
|
*
|
||
|
* When using this form of `Ext.define`, the function is passed a reference to its
|
||
|
* class. This can be used as an efficient way to access any static properties you
|
||
|
* may have:
|
||
|
*
|
||
|
* Ext.define('MyApp.foo.Bar', function (Bar) {
|
||
|
* return {
|
||
|
* statics: {
|
||
|
* staticMethod: function () {
|
||
|
* // ...
|
||
|
* }
|
||
|
* },
|
||
|
*
|
||
|
* method: function () {
|
||
|
* return Bar.staticMethod();
|
||
|
* }
|
||
|
* };
|
||
|
* });
|
||
|
*
|
||
|
* To define an override, include the `override` property. The content of an
|
||
|
* override is aggregated with the specified class in order to extend or modify
|
||
|
* that class. This can be as simple as setting default property values or it can
|
||
|
* extend and/or replace methods. This can also extend the statics of the class.
|
||
|
*
|
||
|
* One use for an override is to break a large class into manageable pieces.
|
||
|
*
|
||
|
* // File: /src/app/Panel.js
|
||
|
*
|
||
|
* Ext.define('My.app.Panel', {
|
||
|
* extend: 'Ext.panel.Panel',
|
||
|
* requires: [
|
||
|
* 'My.app.PanelPart2',
|
||
|
* 'My.app.PanelPart3'
|
||
|
* ]
|
||
|
*
|
||
|
* constructor: function (config) {
|
||
|
* this.callParent(arguments); // calls Ext.panel.Panel's constructor
|
||
|
* //...
|
||
|
* },
|
||
|
*
|
||
|
* statics: {
|
||
|
* method: function () {
|
||
|
* return 'abc';
|
||
|
* }
|
||
|
* }
|
||
|
* });
|
||
|
*
|
||
|
* // File: /src/app/PanelPart2.js
|
||
|
* Ext.define('My.app.PanelPart2', {
|
||
|
* override: 'My.app.Panel',
|
||
|
*
|
||
|
* constructor: function (config) {
|
||
|
* this.callParent(arguments); // calls My.app.Panel's constructor
|
||
|
* //...
|
||
|
* }
|
||
|
* });
|
||
|
*
|
||
|
* Another use of overrides is to provide optional parts of classes that can be
|
||
|
* independently required. In this case, the class may even be unaware of the
|
||
|
* override altogether.
|
||
|
*
|
||
|
* Ext.define('My.ux.CoolTip', {
|
||
|
* override: 'Ext.tip.ToolTip',
|
||
|
*
|
||
|
* constructor: function (config) {
|
||
|
* this.callParent(arguments); // calls Ext.tip.ToolTip's constructor
|
||
|
* //...
|
||
|
* }
|
||
|
* });
|
||
|
*
|
||
|
* The above override can now be required as normal.
|
||
|
*
|
||
|
* Ext.define('My.app.App', {
|
||
|
* requires: [
|
||
|
* 'My.ux.CoolTip'
|
||
|
* ]
|
||
|
* });
|
||
|
*
|
||
|
* Overrides can also contain statics, inheritableStatics, or privates:
|
||
|
*
|
||
|
* Ext.define('My.app.BarMod', {
|
||
|
* override: 'Ext.foo.Bar',
|
||
|
*
|
||
|
* statics: {
|
||
|
* method: function (x) {
|
||
|
* return this.callParent([x * 2]); // call Ext.foo.Bar.method
|
||
|
* }
|
||
|
* }
|
||
|
* });
|
||
|
*
|
||
|
* Starting in version 4.2.2, overrides can declare their `compatibility` based
|
||
|
* on the framework version or on versions of other packages. For details on the
|
||
|
* syntax and options for these checks, see `Ext.checkVersion`.
|
||
|
*
|
||
|
* The simplest use case is to test framework version for compatibility:
|
||
|
*
|
||
|
* Ext.define('App.overrides.grid.Panel', {
|
||
|
* override: 'Ext.grid.Panel',
|
||
|
*
|
||
|
* compatibility: '4.2.2', // only if framework version is 4.2.2
|
||
|
*
|
||
|
* //...
|
||
|
* });
|
||
|
*
|
||
|
* An array is treated as an OR, so if any specs match, the override is
|
||
|
* compatible.
|
||
|
*
|
||
|
* Ext.define('App.overrides.some.Thing', {
|
||
|
* override: 'Foo.some.Thing',
|
||
|
*
|
||
|
* compatibility: [
|
||
|
* '4.2.2',
|
||
|
* '[email protected]'
|
||
|
* ],
|
||
|
*
|
||
|
* //...
|
||
|
* });
|
||
|
*
|
||
|
* To require that all specifications match, an object can be provided:
|
||
|
*
|
||
|
* Ext.define('App.overrides.some.Thing', {
|
||
|
* override: 'Foo.some.Thing',
|
||
|
*
|
||
|
* compatibility: {
|
||
|
* and: [
|
||
|
* '4.2.2',
|
||
|
* '[email protected]'
|
||
|
* ]
|
||
|
* },
|
||
|
*
|
||
|
* //...
|
||
|
* });
|
||
|
*
|
||
|
* Because the object form is just a recursive check, these can be nested:
|
||
|
*
|
||
|
* Ext.define('App.overrides.some.Thing', {
|
||
|
* override: 'Foo.some.Thing',
|
||
|
*
|
||
|
* compatibility: {
|
||
|
* and: [
|
||
|
* '4.2.2', // exactly version 4.2.2 of the framework *AND*
|
||
|
* {
|
||
|
* // either (or both) of these package specs:
|
||
|
* or: [
|
||
|
* '[email protected]',
|
||
|
* '[email protected]+'
|
||
|
* ]
|
||
|
* }
|
||
|
* ]
|
||
|
* },
|
||
|
*
|
||
|
* //...
|
||
|
* });
|
||
|
*
|
||
|
* IMPORTANT: An override is only included in a build if the class it overrides is
|
||
|
* required. Otherwise, the override, like the target class, is not included. In
|
||
|
* Sencha Cmd v4, the `compatibility` declaration can likewise be used to remove
|
||
|
* incompatible overrides from a build.
|
||
|
*
|
||
|
* @param {String} className The class name to create in string dot-namespaced format, for example:
|
||
|
* 'My.very.awesome.Class', 'FeedViewer.plugin.CoolPager'
|
||
|
* It is highly recommended to follow this simple convention:
|
||
|
* - The root and the class name are 'CamelCased'
|
||
|
* - Everything else is lower-cased
|
||
|
* Pass `null` to create an anonymous class.
|
||
|
* @param {Object} data The key - value pairs of properties to apply to this class. Property names can be of any valid
|
||
|
* strings, except those in the reserved listed below:
|
||
|
*
|
||
|
* - {@link Ext.Class#cfg-alias alias}
|
||
|
* - {@link Ext.Class#cfg-alternateClassName alternateClassName}
|
||
|
* - {@link Ext.Class#cfg-cachedConfig cachedConfig}
|
||
|
* - {@link Ext.Class#cfg-config config}
|
||
|
* - {@link Ext.Class#cfg-extend extend}
|
||
|
* - {@link Ext.Class#cfg-inheritableStatics inheritableStatics}
|
||
|
* - {@link Ext.Class#cfg-mixins mixins}
|
||
|
* - {@link Ext.Class#cfg-override override}
|
||
|
* - {@link Ext.Class#cfg-platformConfig platformConfig}
|
||
|
* - {@link Ext.Class#cfg-privates privates}
|
||
|
* - {@link Ext.Class#cfg-requires requires}
|
||
|
* - `self`
|
||
|
* - {@link Ext.Class#cfg-singleton singleton}
|
||
|
* - {@link Ext.Class#cfg-statics statics}
|
||
|
* - {@link Ext.Class#cfg-uses uses}
|
||
|
* - {@link Ext.Class#cfg-xtype xtype} (for {@link Ext.Component Components} only)
|
||
|
*
|
||
|
* @param {Function} [createdFn] Callback to execute after the class is created, the execution scope of which
|
||
|
* (`this`) will be the newly created class itself.
|
||
|
* @return {Ext.Base}
|
||
|
* @member Ext
|
||
|
*/
|
||
|
define: function (className, data, createdFn) {
|
||
|
//<debug>
|
||
|
Ext.classSystemMonitor && Ext.classSystemMonitor(className, 'ClassManager#define', arguments);
|
||
|
//</debug>
|
||
|
|
||
|
if (data.override) {
|
||
|
Manager.classState[className] = 20;
|
||
|
return Manager.createOverride.apply(Manager, arguments);
|
||
|
}
|
||
|
|
||
|
Manager.classState[className] = 10;
|
||
|
return Manager.create.apply(Manager, arguments);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Undefines a class defined using the #define method. Typically used
|
||
|
* for unit testing where setting up and tearing down a class multiple
|
||
|
* times is required. For example:
|
||
|
*
|
||
|
* // define a class
|
||
|
* Ext.define('Foo', {
|
||
|
* ...
|
||
|
* });
|
||
|
*
|
||
|
* // run test
|
||
|
*
|
||
|
* // undefine the class
|
||
|
* Ext.undefine('Foo');
|
||
|
* @param {String} className The class name to undefine in string dot-namespaced format.
|
||
|
* @private
|
||
|
*/
|
||
|
undefine: function(className) {
|
||
|
//<debug>
|
||
|
Ext.classSystemMonitor && Ext.classSystemMonitor(className, 'Ext.ClassManager#undefine', arguments);
|
||
|
//</debug>
|
||
|
|
||
|
var classes = Manager.classes,
|
||
|
parts, partCount, namespace, i;
|
||
|
|
||
|
delete Manager.namespaceParseCache[className];
|
||
|
delete classes[className];
|
||
|
delete Manager.existCache[className];
|
||
|
delete Manager.classState[className];
|
||
|
|
||
|
Manager.removeName(className);
|
||
|
|
||
|
parts = Manager.parseNamespace(className);
|
||
|
partCount = parts.length - 1;
|
||
|
namespace = parts[0];
|
||
|
|
||
|
for (i = 1; i < partCount; i++) {
|
||
|
namespace = namespace[parts[i]];
|
||
|
if (!namespace) {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Old IE blows up on attempt to delete window property
|
||
|
try {
|
||
|
delete namespace[parts[partCount]];
|
||
|
}
|
||
|
catch (e) {
|
||
|
namespace[parts[partCount]] = undefined;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @inheritdoc Ext.ClassManager#getName
|
||
|
* @member Ext
|
||
|
* @method getClassName
|
||
|
*/
|
||
|
getClassName: alias(Manager, 'getName'),
|
||
|
|
||
|
/**
|
||
|
* Returns the displayName property or className or object. When all else fails, returns "Anonymous".
|
||
|
* @param {Object} object
|
||
|
* @return {String}
|
||
|
*/
|
||
|
getDisplayName: function(object) {
|
||
|
if (object) {
|
||
|
if (object.displayName) {
|
||
|
return object.displayName;
|
||
|
}
|
||
|
|
||
|
if (object.$name && object.$class) {
|
||
|
return Ext.getClassName(object.$class) + '#' + object.$name;
|
||
|
}
|
||
|
|
||
|
if (object.$className) {
|
||
|
return object.$className;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 'Anonymous';
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @inheritdoc Ext.ClassManager#getClass
|
||
|
* @member Ext
|
||
|
* @method getClass
|
||
|
*/
|
||
|
getClass: alias(Manager, 'getClass'),
|
||
|
|
||
|
/**
|
||
|
* Creates namespaces to be used for scoping variables and classes so that they are not global.
|
||
|
* Specifying the last node of a namespace implicitly creates all other nodes. Usage:
|
||
|
*
|
||
|
* Ext.namespace('Company', 'Company.data');
|
||
|
*
|
||
|
* // equivalent and preferable to the above syntax
|
||
|
* Ext.ns('Company.data');
|
||
|
*
|
||
|
* Company.Widget = function() { ... };
|
||
|
*
|
||
|
* Company.data.CustomStore = function(config) { ... };
|
||
|
*
|
||
|
* @param {String...} namespaces
|
||
|
* @return {Object} The namespace object.
|
||
|
* (If multiple arguments are passed, this will be the last namespace created)
|
||
|
* @member Ext
|
||
|
* @method namespace
|
||
|
*/
|
||
|
namespace: alias(Manager, 'createNamespaces')
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* Old name for {@link Ext#widget}.
|
||
|
* @deprecated Use {@link Ext#widget} instead.
|
||
|
* @method createWidget
|
||
|
* @member Ext
|
||
|
* @private
|
||
|
*/
|
||
|
Ext.createWidget = Ext.widget;
|
||
|
|
||
|
/**
|
||
|
* Convenient alias for {@link Ext#namespace Ext.namespace}.
|
||
|
* @inheritdoc Ext#namespace
|
||
|
* @member Ext
|
||
|
* @method ns
|
||
|
*/
|
||
|
Ext.ns = Ext.namespace;
|
||
|
|
||
|
Class.registerPreprocessor('className', function(cls, data) {
|
||
|
if ('$className' in data) {
|
||
|
cls.$className = data.$className;
|
||
|
//<debug>
|
||
|
cls.displayName = cls.$className;
|
||
|
//</debug>
|
||
|
}
|
||
|
|
||
|
//<debug>
|
||
|
Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.ClassManager#classNamePreprocessor', arguments);
|
||
|
//</debug>
|
||
|
}, true, 'first');
|
||
|
|
||
|
Class.registerPreprocessor('alias', function(cls, data) {
|
||
|
//<debug>
|
||
|
Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.ClassManager#aliasPreprocessor', arguments);
|
||
|
//</debug>
|
||
|
|
||
|
var prototype = cls.prototype,
|
||
|
xtypes = arrayFrom(data.xtype),
|
||
|
aliases = arrayFrom(data.alias),
|
||
|
widgetPrefix = 'widget.',
|
||
|
widgetPrefixLength = widgetPrefix.length,
|
||
|
xtypesChain = Array.prototype.slice.call(prototype.xtypesChain || []),
|
||
|
xtypesMap = Ext.merge({}, prototype.xtypesMap || {}),
|
||
|
i, ln, alias, xtype;
|
||
|
|
||
|
for (i = 0,ln = aliases.length; i < ln; i++) {
|
||
|
alias = aliases[i];
|
||
|
|
||
|
//<debug>
|
||
|
if (typeof alias !== 'string' || alias.length < 1) {
|
||
|
throw new Error("[Ext.define] Invalid alias of: '" + alias + "' for class: '" + name + "'; must be a valid string");
|
||
|
}
|
||
|
//</debug>
|
||
|
|
||
|
if (alias.substring(0, widgetPrefixLength) === widgetPrefix) {
|
||
|
xtype = alias.substring(widgetPrefixLength);
|
||
|
Ext.Array.include(xtypes, xtype);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
cls.xtype = data.xtype = xtypes[0];
|
||
|
data.xtypes = xtypes;
|
||
|
|
||
|
for (i = 0,ln = xtypes.length; i < ln; i++) {
|
||
|
xtype = xtypes[i];
|
||
|
|
||
|
if (!xtypesMap[xtype]) {
|
||
|
xtypesMap[xtype] = true;
|
||
|
xtypesChain.push(xtype);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
data.xtypesChain = xtypesChain;
|
||
|
data.xtypesMap = xtypesMap;
|
||
|
|
||
|
Ext.Function.interceptAfter(data, 'onClassCreated', function() {
|
||
|
//<debug>
|
||
|
Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.ClassManager#aliasPreprocessor#afterClassCreated', arguments);
|
||
|
//</debug>
|
||
|
|
||
|
var mixins = prototype.mixins,
|
||
|
key, mixin;
|
||
|
|
||
|
for (key in mixins) {
|
||
|
if (mixins.hasOwnProperty(key)) {
|
||
|
mixin = mixins[key];
|
||
|
|
||
|
xtypes = mixin.xtypes;
|
||
|
|
||
|
if (xtypes) {
|
||
|
for (i = 0,ln = xtypes.length; i < ln; i++) {
|
||
|
xtype = xtypes[i];
|
||
|
|
||
|
if (!xtypesMap[xtype]) {
|
||
|
xtypesMap[xtype] = true;
|
||
|
xtypesChain.push(xtype);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
for (i = 0,ln = xtypes.length; i < ln; i++) {
|
||
|
xtype = xtypes[i];
|
||
|
|
||
|
//<debug>
|
||
|
if (typeof xtype !== 'string' || xtype.length < 1) {
|
||
|
throw new Error("[Ext.define] Invalid xtype of: '" + xtype + "' for class: '" + name + "'; must be a valid non-empty string");
|
||
|
}
|
||
|
//</debug>
|
||
|
|
||
|
Ext.Array.include(aliases, widgetPrefix + xtype);
|
||
|
}
|
||
|
|
||
|
data.alias = aliases;
|
||
|
|
||
|
}, ['xtype', 'alias']);
|
||
|
|
||
|
// load the cmd-5 style app manifest metadata now, if available...
|
||
|
if(Ext.manifest) {
|
||
|
var manifest = Ext.manifest,
|
||
|
classes = manifest.classes,
|
||
|
paths = manifest.paths,
|
||
|
aliases = {},
|
||
|
alternates = {},
|
||
|
className, obj, name, path, baseUrl;
|
||
|
|
||
|
if(paths) {
|
||
|
// if the manifest paths were calculated as relative to the
|
||
|
// bootstrap file, then we need to prepend Boot.baseUrl to the
|
||
|
// paths before processing
|
||
|
if(manifest.bootRelative) {
|
||
|
baseUrl = Ext.Boot.baseUrl;
|
||
|
for(path in paths) {
|
||
|
if(paths.hasOwnProperty(path)) {
|
||
|
paths[path] = baseUrl + paths[path];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
Manager.setPath(paths);
|
||
|
}
|
||
|
|
||
|
if(classes) {
|
||
|
for(className in classes) {
|
||
|
alternates[className] = [];
|
||
|
aliases[className] = [];
|
||
|
obj = classes[className];
|
||
|
if(obj.alias) {
|
||
|
aliases[className] = obj.alias;
|
||
|
}
|
||
|
if(obj.alternates) {
|
||
|
alternates[className] = obj.alternates;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Manager.addAlias(aliases);
|
||
|
Manager.addAlternate(alternates);
|
||
|
}
|
||
|
|
||
|
return Manager;
|
||
|
}(Ext.Class, Ext.Function.alias, Array.prototype.slice, Ext.Array.from, Ext.global));
|
||
|
|