<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>The source code</title>
- <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="../prettify/prettify.js"></script>
+ <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
+ <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
<style type="text/css">
.highlight { display: block; background-color: #ddd; }
</style>
</head>
<body onload="prettyPrint(); highlight();">
<pre class="prettyprint lang-js"><span id='Ext-Loader'>/**
-</span> * @author Jacky Nguyen <jacky@sencha.com>
+</span> * @class Ext.Loader
+ * @singleton
+ * @author Jacky Nguyen <jacky@sencha.com>
* @docauthor Jacky Nguyen <jacky@sencha.com>
- * @class Ext.Loader
*
-
-Ext.Loader is the heart of the new dynamic dependency loading capability in Ext JS 4+. It is most commonly used
-via the {@link Ext#require} shorthand. Ext.Loader supports both asynchronous and synchronous loading
-approaches, and leverage their advantages for the best development flow. We'll discuss about the pros and cons of each approach:
-
-# Asynchronous Loading #
-
-- Advantages:
- + Cross-domain
- + No web server needed: you can run the application via the file system protocol (i.e: `file://path/to/your/index
- .html`)
- + Best possible debugging experience: error messages come with the exact file name and line number
-
-- Disadvantages:
- + Dependencies need to be specified before-hand
-
-### Method 1: Explicitly include what you need: ###
-
- // Syntax
- Ext.require({String/Array} expressions);
-
- // Example: Single alias
- Ext.require('widget.window');
-
- // Example: Single class name
- Ext.require('Ext.window.Window');
-
- // Example: Multiple aliases / class names mix
- Ext.require(['widget.window', 'layout.border', 'Ext.data.Connection']);
-
- // Wildcards
- Ext.require(['widget.*', 'layout.*', 'Ext.data.*']);
-
-### Method 2: Explicitly exclude what you don't need: ###
-
- // Syntax: Note that it must be in this chaining format.
- Ext.exclude({String/Array} expressions)
- .require({String/Array} expressions);
-
- // Include everything except Ext.data.*
- Ext.exclude('Ext.data.*').require('*');
-
- // Include all widgets except widget.checkbox*,
- // which will match widget.checkbox, widget.checkboxfield, widget.checkboxgroup, etc.
- Ext.exclude('widget.checkbox*').require('widget.*');
-
-# Synchronous Loading on Demand #
-
-- *Advantages:*
- + There's no need to specify dependencies before-hand, which is always the convenience of including ext-all.js
- before
-
-- *Disadvantages:*
- + Not as good debugging experience since file name won't be shown (except in Firebug at the moment)
- + Must be from the same domain due to XHR restriction
- + Need a web server, same reason as above
-
-There's one simple rule to follow: Instantiate everything with Ext.create instead of the `new` keyword
-
- Ext.create('widget.window', { ... }); // Instead of new Ext.window.Window({...});
-
- Ext.create('Ext.window.Window', {}); // Same as above, using full class name instead of alias
-
- Ext.widget('window', {}); // Same as above, all you need is the traditional `xtype`
-
-Behind the scene, {@link Ext.ClassManager} will automatically check whether the given class name / alias has already
- existed on the page. If it's not, Ext.Loader will immediately switch itself to synchronous mode and automatic load the given
- class and all its dependencies.
-
-# Hybrid Loading - The Best of Both Worlds #
-
-It has all the advantages combined from asynchronous and synchronous loading. The development flow is simple:
-
-### Step 1: Start writing your application using synchronous approach. Ext.Loader will automatically fetch all
- dependencies on demand as they're needed during run-time. For example: ###
-
- Ext.onReady(function(){
- var window = Ext.createWidget('window', {
- width: 500,
- height: 300,
- layout: {
- type: 'border',
- padding: 5
- },
- title: 'Hello Dialog',
- items: [{
- title: 'Navigation',
- collapsible: true,
- region: 'west',
- width: 200,
- html: 'Hello',
- split: true
- }, {
- title: 'TabPanel',
- region: 'center'
- }]
- });
-
- window.show();
- })
-
-### Step 2: Along the way, when you need better debugging ability, watch the console for warnings like these: ###
-
- [Ext.Loader] Synchronously loading 'Ext.window.Window'; consider adding Ext.require('Ext.window.Window') before your application's code
- ClassManager.js:432
- [Ext.Loader] Synchronously loading 'Ext.layout.container.Border'; consider adding Ext.require('Ext.layout.container.Border') before your application's code
-
-Simply copy and paste the suggested code above `Ext.onReady`, i.e:
-
- Ext.require('Ext.window.Window');
- Ext.require('Ext.layout.container.Border');
-
- Ext.onReady(...);
-
-Everything should now load via asynchronous mode.
-
-# Deployment #
-
-It's important to note that dynamic loading should only be used during development on your local machines.
-During production, all dependencies should be combined into one single JavaScript file. Ext.Loader makes
-the whole process of transitioning from / to between development / maintenance and production as easy as
-possible. Internally {@link Ext.Loader#history Ext.Loader.history} maintains the list of all dependencies your application
-needs in the exact loading sequence. It's as simple as concatenating all files in this array into one,
-then include it on top of your application.
-
-This process will be automated with Sencha Command, to be released and documented towards Ext JS 4 Final.
-
- * @singleton
- * @markdown
+ * Ext.Loader is the heart of the new dynamic dependency loading capability in Ext JS 4+. It is most commonly used
+ * via the {@link Ext#require} shorthand. Ext.Loader supports both asynchronous and synchronous loading
+ * approaches, and leverage their advantages for the best development flow. We'll discuss about the pros and cons
+ * of each approach:
+ *
+ * # Asynchronous Loading
+ *
+ * - Advantages:
+ * + Cross-domain
+ * + No web server needed: you can run the application via the file system protocol
+ * (i.e: `file://path/to/your/index.html`)
+ * + Best possible debugging experience: error messages come with the exact file name and line number
+ *
+ * - Disadvantages:
+ * + Dependencies need to be specified before-hand
+ *
+ * ### Method 1: Explicitly include what you need:
+ *
+ * // Syntax
+ * Ext.require({String/Array} expressions);
+ *
+ * // Example: Single alias
+ * Ext.require('widget.window');
+ *
+ * // Example: Single class name
+ * Ext.require('Ext.window.Window');
+ *
+ * // Example: Multiple aliases / class names mix
+ * Ext.require(['widget.window', 'layout.border', 'Ext.data.Connection']);
+ *
+ * // Wildcards
+ * Ext.require(['widget.*', 'layout.*', 'Ext.data.*']);
+ *
+ * ### Method 2: Explicitly exclude what you don't need:
+ *
+ * // Syntax: Note that it must be in this chaining format.
+ * Ext.exclude({String/Array} expressions)
+ * .require({String/Array} expressions);
+ *
+ * // Include everything except Ext.data.*
+ * Ext.exclude('Ext.data.*').require('*');
+ *
+ * // Include all widgets except widget.checkbox*,
+ * // which will match widget.checkbox, widget.checkboxfield, widget.checkboxgroup, etc.
+ * Ext.exclude('widget.checkbox*').require('widget.*');
+ *
+ * # Synchronous Loading on Demand
+ *
+ * - Advantages:
+ * + There's no need to specify dependencies before-hand, which is always the convenience of including
+ * ext-all.js before
+ *
+ * - Disadvantages:
+ * + Not as good debugging experience since file name won't be shown (except in Firebug at the moment)
+ * + Must be from the same domain due to XHR restriction
+ * + Need a web server, same reason as above
+ *
+ * There's one simple rule to follow: Instantiate everything with Ext.create instead of the `new` keyword
+ *
+ * Ext.create('widget.window', { ... }); // Instead of new Ext.window.Window({...});
+ *
+ * Ext.create('Ext.window.Window', {}); // Same as above, using full class name instead of alias
+ *
+ * Ext.widget('window', {}); // Same as above, all you need is the traditional `xtype`
+ *
+ * Behind the scene, {@link Ext.ClassManager} will automatically check whether the given class name / alias has already
+ * existed on the page. If it's not, Ext.Loader will immediately switch itself to synchronous mode and automatic load
+ * the given class and all its dependencies.
+ *
+ * # Hybrid Loading - The Best of Both Worlds
+ *
+ * It has all the advantages combined from asynchronous and synchronous loading. The development flow is simple:
+ *
+ * ### Step 1: Start writing your application using synchronous approach.
+ *
+ * Ext.Loader will automatically fetch all dependencies on demand as they're needed during run-time. For example:
+ *
+ * Ext.onReady(function(){
+ * var window = Ext.createWidget('window', {
+ * width: 500,
+ * height: 300,
+ * layout: {
+ * type: 'border',
+ * padding: 5
+ * },
+ * title: 'Hello Dialog',
+ * items: [{
+ * title: 'Navigation',
+ * collapsible: true,
+ * region: 'west',
+ * width: 200,
+ * html: 'Hello',
+ * split: true
+ * }, {
+ * title: 'TabPanel',
+ * region: 'center'
+ * }]
+ * });
+ *
+ * window.show();
+ * })
+ *
+ * ### Step 2: Along the way, when you need better debugging ability, watch the console for warnings like these:
+ *
+ * [Ext.Loader] Synchronously loading 'Ext.window.Window'; consider adding Ext.require('Ext.window.Window') before your application's code ClassManager.js:432
+ * [Ext.Loader] Synchronously loading 'Ext.layout.container.Border'; consider adding Ext.require('Ext.layout.container.Border') before your application's code
+ *
+ * Simply copy and paste the suggested code above `Ext.onReady`, e.g.:
+ *
+ * Ext.require('Ext.window.Window');
+ * Ext.require('Ext.layout.container.Border');
+ *
+ * Ext.onReady(...);
+ *
+ * Everything should now load via asynchronous mode.
+ *
+ * # Deployment
+ *
+ * It's important to note that dynamic loading should only be used during development on your local machines.
+ * During production, all dependencies should be combined into one single JavaScript file. Ext.Loader makes
+ * the whole process of transitioning from / to between development / maintenance and production as easy as
+ * possible. Internally {@link Ext.Loader#history Ext.Loader.history} maintains the list of all dependencies
+ * your application needs in the exact loading sequence. It's as simple as concatenating all files in this
+ * array into one, then include it on top of your application.
+ *
+ * This process will be automated with Sencha Command, to be released and documented towards Ext JS 4 Final.
*/
-
(function(Manager, Class, flexSetter, alias) {
var
classNameToFilePathMap: {},
<span id='Ext-Loader-property-history'> /**
-</span> * An array of class names to keep track of the dependency loading order.
- * This is not guaranteed to be the same everytime due to the asynchronous
- * nature of the Loader.
- *
- * @property history
- * @type Array
+</span> * @property {String[]} history
+ * An array of class names to keep track of the dependency loading order.
+ * This is not guaranteed to be the same everytime due to the asynchronous nature of the Loader.
*/
history: [],
*/
config: {
<span id='Ext-Loader-cfg-enabled'> /**
-</span> * Whether or not to enable the dynamic dependency loading feature
- * Defaults to false
- * @cfg {Boolean} enabled
+</span> * @cfg {Boolean} enabled
+ * Whether or not to enable the dynamic dependency loading feature.
*/
enabled: false,
<span id='Ext-Loader-cfg-disableCaching'> /**
</span> * @cfg {Boolean} disableCaching
- * Appends current timestamp to script files to prevent caching
- * Defaults to true
+ * Appends current timestamp to script files to prevent caching.
*/
disableCaching: true,
<span id='Ext-Loader-cfg-disableCachingParam'> /**
</span> * @cfg {String} disableCachingParam
* The get parameter name for the cache buster's timestamp.
- * Defaults to '_dc'
*/
disableCachingParam: '_dc',
<span id='Ext-Loader-cfg-paths'> /**
</span> * @cfg {Object} paths
* The mapping from namespaces to file paths
- {
- 'Ext': '.', // This is set by default, Ext.layout.container.Container will be
- // loaded from ./layout/Container.js
-
- 'My': './src/my_own_folder' // My.layout.Container will be loaded from
- // ./src/my_own_folder/layout/Container.js
- }
+ *
+ * {
+ * 'Ext': '.', // This is set by default, Ext.layout.container.Container will be
+ * // loaded from ./layout/Container.js
+ *
+ * 'My': './src/my_own_folder' // My.layout.Container will be loaded from
+ * // ./src/my_own_folder/layout/Container.js
+ * }
+ *
* Note that all relative paths are relative to the current HTML document.
- * If not being specified, for example, <code>Other.awesome.Class</code>
- * will simply be loaded from <code>./Other/awesome/Class.js</code>
+ * If not being specified, for example, `Other.awesome.Class`
+ * will simply be loaded from `./Other/awesome/Class.js`
*/
paths: {
'Ext': '.'
<span id='Ext-Loader-method-setConfig'> /**
</span> * Set the configuration for the loader. This should be called right after ext-core.js
- * (or ext-core-debug.js) is included in the page, i.e:
-
- <script type="text/javascript" src="ext-core-debug.js"></script>
- <script type="text/javascript">
- Ext.Loader.setConfig({
- enabled: true,
- paths: {
- 'My': 'my_own_path'
- }
- });
- <script>
- <script type="text/javascript">
- Ext.require(...);
-
- Ext.onReady(function() {
- // application code here
- });
- </script>
-
- * Refer to {@link Ext.Loader#configs} for the list of possible properties
+ * (or ext-core-debug.js) is included in the page, e.g.:
*
- * @param {Object} config The config object to override the default values in {@link Ext.Loader#config}
+ * <script type="text/javascript" src="ext-core-debug.js"></script>
+ * <script type="text/javascript">
+ * Ext.Loader.setConfig({
+ * enabled: true,
+ * paths: {
+ * 'My': 'my_own_path'
+ * }
+ * });
+ * <script>
+ * <script type="text/javascript">
+ * Ext.require(...);
+ *
+ * Ext.onReady(function() {
+ * // application code here
+ * });
+ * </script>
+ *
+ * Refer to config options of {@link Ext.Loader} for the list of possible properties.
+ *
+ * @param {String/Object} name Name of the value to override, or a config object to override multiple values.
+ * @param {Object} value (optional) The new value to set, needed if first parameter is String.
* @return {Ext.Loader} this
- * @markdown
*/
setConfig: function(name, value) {
if (Ext.isObject(name) && arguments.length === 1) {
},
<span id='Ext-Loader-method-getConfig'> /**
-</span> * Get the config value corresponding to the specified name. If no name is given, will return the config object
+</span> * Get the config value corresponding to the specified name.
+ * If no name is given, will return the config object.
* @param {String} name The config property name
- * @return {Object/Mixed}
+ * @return {Object}
*/
getConfig: function(name) {
if (name) {
},
<span id='Ext-Loader-method-setPath'> /**
-</span> * Sets the path of a namespace.
- * For Example:
-
- Ext.Loader.setPath('Ext', '.');
-
+</span> * Sets the path of a namespace. For Example:
+ *
+ * Ext.Loader.setPath('Ext', '.');
+ *
* @param {String/Object} name See {@link Ext.Function#flexSetter flexSetter}
* @param {String} path See {@link Ext.Function#flexSetter flexSetter}
* @return {Ext.Loader} this
* @method
- * @markdown
*/
setPath: flexSetter(function(name, path) {
//<if nonBrowser>
}),
<span id='Ext-Loader-method-getPath'> /**
-</span> * Translates a className to a file path by adding the
- * the proper prefix and converting the .'s to /'s. For example:
-
- Ext.Loader.setPath('My', '/path/to/My');
-
- alert(Ext.Loader.getPath('My.awesome.Class')); // alerts '/path/to/My/awesome/Class.js'
-
+</span> * Translates a className to a file path by adding the the proper prefix and converting the .'s to /'s.
+ * For example:
+ *
+ * Ext.Loader.setPath('My', '/path/to/My');
+ *
+ * alert(Ext.Loader.getPath('My.awesome.Class')); // alerts '/path/to/My/awesome/Class.js'
+ *
* Note that the deeper namespace levels, if explicitly set, are always resolved first. For example:
-
- Ext.Loader.setPath({
- 'My': '/path/to/lib',
- 'My.awesome': '/other/path/for/awesome/stuff',
- 'My.awesome.more': '/more/awesome/path'
- });
-
- alert(Ext.Loader.getPath('My.awesome.Class')); // alerts '/other/path/for/awesome/stuff/Class.js'
-
- alert(Ext.Loader.getPath('My.awesome.more.Class')); // alerts '/more/awesome/path/Class.js'
-
- alert(Ext.Loader.getPath('My.cool.Class')); // alerts '/path/to/lib/cool/Class.js'
-
- alert(Ext.Loader.getPath('Unknown.strange.Stuff')); // alerts 'Unknown/strange/Stuff.js'
-
+ *
+ * Ext.Loader.setPath({
+ * 'My': '/path/to/lib',
+ * 'My.awesome': '/other/path/for/awesome/stuff',
+ * 'My.awesome.more': '/more/awesome/path'
+ * });
+ *
+ * alert(Ext.Loader.getPath('My.awesome.Class')); // alerts '/other/path/for/awesome/stuff/Class.js'
+ *
+ * alert(Ext.Loader.getPath('My.awesome.more.Class')); // alerts '/more/awesome/path/Class.js'
+ *
+ * alert(Ext.Loader.getPath('My.cool.Class')); // alerts '/path/to/lib/cool/Class.js'
+ *
+ * alert(Ext.Loader.getPath('Unknown.strange.Stuff')); // alerts 'Unknown/strange/Stuff.js'
+ *
* @param {String} className
* @return {String} path
- * @markdown
*/
getPath: function(className) {
var path = '',
do {
if (Manager.isCreated(requires[j])) {
// Take out from the queue
- requires.splice(j, 1);
+ Ext.Array.erase(requires, j, 1);
}
else {
j++;
} while (j < requires.length);
if (item.requires.length === 0) {
- this.queue.splice(i, 1);
+ Ext.Array.erase(this.queue, i, 1);
item.callback.call(item.scope);
this.refreshQueue();
break;
*
* @param {String} url
* @param {Function} onLoad
- * @param {Scope} scope
+ * @param {Object} scope
* @param {Boolean} synchronous
* @private
*/
<span id='Ext-Loader-method-exclude'> /**
</span> * Explicitly exclude files from being loaded. Useful when used in conjunction with a broad include expression.
- * Can be chained with more `require` and `exclude` methods, eg:
-
- Ext.exclude('Ext.data.*').require('*');
-
- Ext.exclude('widget.button*').require('widget.*');
-
- * @param {Array} excludes
+ * Can be chained with more `require` and `exclude` methods, e.g.:
+ *
+ * Ext.exclude('Ext.data.*').require('*');
+ *
+ * Ext.exclude('widget.button*').require('widget.*');
+ *
+ * {@link Ext#exclude Ext.exclude} is alias for {@link Ext.Loader#exclude Ext.Loader.exclude} for convenience.
+ *
+ * @param {String/String[]} excludes
* @return {Object} object contains `require` method for chaining
- * @markdown
*/
exclude: function(excludes) {
var me = this;
},
<span id='Ext-Loader-method-syncRequire'> /**
-</span> * Synchronously loads all classes by the given names and all their direct dependencies; optionally executes the given callback function when finishes, within the optional scope. This method is aliased by {@link Ext#syncRequire} for convenience
- * @param {String/Array} expressions Can either be a string or an array of string
+</span> * Synchronously loads all classes by the given names and all their direct dependencies;
+ * optionally executes the given callback function when finishes, within the optional scope.
+ *
+ * {@link Ext#syncRequire Ext.syncRequire} is alias for {@link Ext.Loader#syncRequire Ext.Loader.syncRequire} for convenience.
+ *
+ * @param {String/String[]} expressions Can either be a string or an array of string
* @param {Function} fn (Optional) The callback function
* @param {Object} scope (Optional) The execution scope (`this`) of the callback function
- * @param {String/Array} excludes (Optional) Classes to be excluded, useful when being used with expressions
- * @markdown
+ * @param {String/String[]} excludes (Optional) Classes to be excluded, useful when being used with expressions
*/
syncRequire: function() {
this.syncModeEnabled = true;
},
<span id='Ext-Loader-method-require'> /**
-</span> * Loads all classes by the given names and all their direct dependencies; optionally executes the given callback function when
- * finishes, within the optional scope. This method is aliased by {@link Ext#require Ext.require} for convenience
- * @param {String/Array} expressions Can either be a string or an array of string
+</span> * Loads all classes by the given names and all their direct dependencies;
+ * optionally executes the given callback function when finishes, within the optional scope.
+ *
+ * {@link Ext#require Ext.require} is alias for {@link Ext.Loader#require Ext.Loader.require} for convenience.
+ *
+ * @param {String/String[]} expressions Can either be a string or an array of string
* @param {Function} fn (Optional) The callback function
* @param {Object} scope (Optional) The execution scope (`this`) of the callback function
- * @param {String/Array} excludes (Optional) Classes to be excluded, useful when being used with expressions
- * @markdown
+ * @param {String/String[]} excludes (Optional) Classes to be excluded, useful when being used with expressions
*/
require: function(expressions, fn, scope, excludes) {
var filePath, expression, exclude, className, excluded = {},
},
<span id='Ext-Loader-method-onReady'> /**
-</span> * Add a new listener to be executed when all required scripts are fully loaded
+</span> * Adds new listener to be executed when all required scripts are fully loaded.
*
* @param {Function} fn The function callback to be executed
- * @param {Object} scope The execution scope (<code>this</code>) of the callback function
+ * @param {Object} scope The execution scope (`this`) of the callback function
* @param {Boolean} withDomReady Whether or not to wait for document dom ready as well
*/
onReady: function(fn, scope, withDomReady, options) {
};
<span id='Ext-method-require'> /**
-</span> * Convenient alias of {@link Ext.Loader#require}. Please see the introduction documentation of
- * {@link Ext.Loader} for examples.
- * @member Ext
+</span> * @member Ext
* @method require
+ * @alias Ext.Loader#require
*/
Ext.require = alias(Loader, 'require');
<span id='Ext-method-syncRequire'> /**
-</span> * Synchronous version of {@link Ext#require}, convenient alias of {@link Ext.Loader#syncRequire}.
- *
- * @member Ext
+</span> * @member Ext
* @method syncRequire
+ * @alias Ext.Loader#syncRequire
*/
Ext.syncRequire = alias(Loader, 'syncRequire');
<span id='Ext-method-exclude'> /**
-</span> * Convenient shortcut to {@link Ext.Loader#exclude}
- * @member Ext
+</span> * @member Ext
* @method exclude
+ * @alias Ext.Loader#exclude
*/
Ext.exclude = alias(Loader, 'exclude');
<span id='Ext-method-onReady'> /**
</span> * @member Ext
* @method onReady
+ * @alias Ext.Loader#onReady
*/
Ext.onReady = function(fn, scope, options) {
Loader.onReady(fn, scope, true, options);
};
+<span id='Ext-Class-cfg-requires'> /**
+</span> * @cfg {String[]} requires
+ * @member Ext.Class
+ * List of classes that have to be loaded before instantiating this class.
+ * For example:
+ *
+ * Ext.define('Mother', {
+ * requires: ['Child'],
+ * giveBirth: function() {
+ * // we can be sure that child class is available.
+ * return new Child();
+ * }
+ * });
+ */
Class.registerPreprocessor('loader', function(cls, data, continueFn) {
var me = this,
dependencies = [],
}
}
}
- else {
+ else if (typeof propertyValue != 'function') {
for (j in propertyValue) {
if (propertyValue.hasOwnProperty(j)) {
value = propertyValue[j];
}
}
}
- else {
+ else if (typeof propertyValue != 'function') {
for (var k in propertyValue) {
if (propertyValue.hasOwnProperty(k)) {
value = propertyValue[k];
Class.setDefaultPreprocessorPosition('loader', 'after', 'className');
+<span id='Ext-Class-cfg-uses'> /**
+</span> * @cfg {String[]} uses
+ * @member Ext.Class
+ * List of classes to load together with this class. These aren't neccessarily loaded before
+ * this class is instantiated. For example:
+ *
+ * Ext.define('Mother', {
+ * uses: ['Child'],
+ * giveBirth: function() {
+ * // This code might, or might not work:
+ * // return new Child();
+ *
+ * // Instead use Ext.create() to load the class at the spot if not loaded already:
+ * return Ext.create('Child');
+ * }
+ * });
+ */
Manager.registerPostprocessor('uses', function(name, cls, data) {
var uses = Ext.Array.from(data.uses),
items = [],