loader-base.js revision 3d28b8d571c51289f876620f486903bcd279f220
'gallerycss-': {
type:
'css' } }
// this makes skins in builds earlier than // 2.6.0 work as long as combine is false * Loader dynamically loads script and css files. It includes the dependency * info for the version of the library in use, and will automatically pull in * dependencies for the modules requested. It supports rollup files and will * automatically use these when appropriate in order to minimize the number of * http connections required to load all of the dependencies. It can load the * files from the Yahoo! CDN, and it can utilize the combo service provided on * this network to reduce the number of http connections required to download * The component metadata is stored in Y.Env.meta. * Part of the loader module. * Loader dynamically loads script and css files. It includes the dependency * info for the version of the library in use, and will automatically pull in * dependencies for the modules requested. It supports rollup files and will * automatically use these when appropriate in order to minimize the number of * http connections required to load all of the dependencies. It can load the * files from the Yahoo! CDN, and it can utilize the combo service provided on * this network to reduce the number of http connections required to download * While the loader can be instantiated by the end user, it normally is not. * @see YUI.use for the normal use case. The use function automatically will * pull in missing dependencies. * @param {object} o an optional set of configuration options. Valid options: * The root path to prepend to module names for the combo service. * A filter to apply to result urls. This filter will modify the default * path for all modules. The default path for the YUI library is the * minified version of the files (e.g., event-min.js). The filter property * can be a predefined filter or a custom filter. The valid predefined * <dd>Selects the debug versions of the library (e.g., event-debug.js). * This option will automatically include the Logger widget</dd> * <dd>Selects the non-minified version of the library (e.g., event.js). * You can also define a custom filter, which must be an object literal * containing a search expression and a replace string: * 'searchExp': "-min\\.js", * <li>filters: per-component filter specification. If specified * for a given component, this overrides the filter config. _Note:_ This does not work on combo urls, use the filter property instead.</li> * Use the YUI combo service to reduce the number of http connections * required to load your dependencies</li> * A list of modules that should never be dynamically loaded</li> * A list of modules that should always be loaded when required, even if * already present on the page</li> * Node or id for a node that should be used as the insertion point for * charset for dynamic nodes (deprecated, use jsAttributes or cssAttributes) * <li>jsAttributes: object literal containing attributes to add to script * <li>cssAttributes: object literal containing attributes to add to link * The number of milliseconds before a timeout occurs when dynamically * loading nodes. If not set, there is no timeout</li> * execution context for all callbacks</li> * callback for the 'success' event</li> * <li>onFailure: callback for the 'failure' event</li> * <li>onCSS: callback for the 'CSSComplete' event. When loading YUI * components with CSS the CSS is loaded first, then the script. This * provides a moment you can tie into to improve * the presentation of the page while the script is loading.</li> * callback for the 'timeout' event</li> * callback executed each time a script or css file is loaded</li> * A list of module definitions. See Loader.addModule for the supported * A list of group definitions. Each group can contain specific definitions * for base, comboBase, combine, and accepts a list of modules. See above * for the description of these properties.</li> * <li>2in3: the version of the YUI 2 in 3 wrapper to use. The intrinsic * support for YUI 2 modules in YUI 3 relies on versions of the YUI 2 * components inside YUI 3 module wrappers. These wrappers * change over time to accomodate the issues that arise from running YUI 2 * in a YUI 3 sandbox.</li> * <li>yui2: when using the 2in3 project, you can select the version of * YUI 2 to use. Valid values * are 2.2.2, 2.3.1, 2.4.1, 2.5.2, 2.6.0, * 2.7.0, 2.8.0, and 2.8.1 [default] -- plus all versions of YUI 2 * Internal callback to handle multiple internal insert() calls * so that css is inserted prior to js * @property _internalCallback // self._internalCallback = null; * Callback that will be executed when the loader is finished // self.onSuccess = null; * Callback that will be executed if there is a failure // self.onFailure = null; * Callback for the 'CSSComplete' event. When loading YUI components * with CSS the CSS is loaded first, then the script. This provides * a moment you can tie into to improve the presentation of the page * while the script is loading. * Callback executed each time a script or css file is loaded // self.onProgress = null; * Callback that will be executed if a timeout occurs // self.onTimeout = null; * The execution context for all callbacks * @default {YUI} the YUI instance * Data that is passed to all callbacks * Node reference or id where new nodes should be inserted before * @type string|HTMLElement // self.insertBefore = null; * The charset attribute for inserted nodes * @deprecated , use cssAttributes or jsAttributes. * An object literal containing attributes to add to link nodes * @property cssAttributes // self.cssAttributes = null; * An object literal containing attributes to add to script nodes * Base path for the combo service * Base path for language packs. // self.langBase = Y.Env.meta.langBase; * If configured, the loader will attempt to use the combo * service for YUI resources and configured external resources. * @default true if a base dir isn't in the config * The default seperator to use between files in a combo URL * Max url length for combo urls. The default is 2048. This is the URL * limit for the Yahoo! hosted combo servers. If consuming * a different combo service that has a different URL limit * it is possible to override this default by supplying * the maxURLLength config option. The config option will * only take effect if lower than the default. * Ignore modules registered on the YUI global * @property ignoreRegistered // self.ignoreRegistered = false; * Root path to prepend to module path for the combo * @default [YUI VERSION]/build/ * Timeout value in milliseconds. If set, self value will be used by * the get utility. the timeout event will fire if * A list of modules that should not be loaded, even if * they turn up in the dependency tree * A list of modules that should always be loaded, even * if they have already been inserted into the page. * Should we allow rollups * A filter to apply to result urls. This filter will modify the default * path for all modules. The default path for the YUI library is the * minified version of the files (e.g., event-min.js). The filter property * can be a predefined filter or a custom filter. The valid predefined * <dd>Selects the debug versions of the library (e.g., event-debug.js). * This option will automatically include the Logger widget</dd> * <dd>Selects the non-minified version of the library (e.g., event.js). * You can also define a custom filter, which must be an object literal * containing a search expression and a replace string: * 'searchExp': "-min\\.js", * @type string| {searchExp: string, replaceStr: string} * per-component filter specification. If specified for a given * component, this overrides the filter config. * The list of requested modules * @type {string: boolean} * If a module name is predefined when requested, it is checked againsts * the patterns provided in this property. If there is a match, the * module is added with the default configuration. * At the moment only supporting module prefixes, but anticipate * supporting at least regular expressions. // self.patterns = Y.merge(Y.Env.meta.patterns); // self.moduleInfo = Y.merge(Y.Env.meta.moduleInfo); * Provides the information used to skin the skinnable components. * The following skin definition would result in 'skin1' and 'skin2' * being loaded for calendar (if calendar was requested), and * 'sam' for all other skinnable components: * // The default skin, which is automatically applied if not * // overriden by a component-specific skin definition. * // Change this in to apply a different skin globally * // This is combined with the loader base property to get * // the default root directory for a skin. ex: * // Any component-specific overrides can be specified here, * // making it possible to load different skins for different * // components. It is possible to load more than one skin * // for a given component as well. * calendar: ['skin1', 'skin2'] * Map of conditional modules // map of modules with a hash of modules that meet the requirement //self.moduleInfo[k] = Y.merge(v); //self.conditions[k] = Y.merge(v); //GLOBAL_ENV._renderedMods = Y.merge(self.moduleInfo); //GLOBAL_ENV._conditions = Y.merge(self.conditions); * List of rollup files found in the library metadata * Whether or not to load optional dependencies for // self.loadOptional = false; * All of the derived dependencies in sorted order, which * will be populated when either calculate() or insert() * Set when beginning to compute the dependency tree. * Composed of what YUI reports to be loaded combined * with what has been loaded by any instance on the page * with the version number specified in the metadata. * @type {string: boolean} * A list of modules to attach to the YUI instance when complete. * If not supplied, the sorted list of dependencies are applied. // self.attaching = null; * Flag to indicate the dependency tree needs to be recomputed * if insert is called again. * List of modules inserted by the utility * @type {string: boolean} * List of skipped modules during insert() because the module // Y.on('yui:load', self.loadNext, self); * Cached sorted calculate results 'searchExp':
'-min\\.js',
'searchExp':
'-min\\.js',
* Check the pages meta-data and cache the result. // console.log('deleting ' + m.name); // m.requres = YObject.keys(Y.merge(YArray.hash(req), YArray.hash(mr))); // delete m.expanded_map; * returns true if b is not loaded, and is required directly or by means of modules it supersedes. * @param {String} mod1 The first module to compare * @param {String} mod2 The second module to compare // check if this module should be sorted after the other // do this first to short circut circular deps // check if this module requires one the other supersedes for (i =
0; i < s.
length; i++) {
for (i =
0; i < s.
length; i++) {
// check if this module requires the other directly // if (r && YArray.indexOf(r, mod2) > -1) { // external css files should be sorted below yui css * Apply a new config to the Loader instance * @param {Object} o The new configuration }
else if (i ==
'skin') {
}
else if (i ==
'groups') {
}
else if (i ==
'modules') {
// add a hash of module definitions }
else if (i ==
'gallery') {
}
else if (i ==
'yui2' || i ==
'2in3') {
}
else if (i ==
'maxURLLength') {
* Returns the skin module name for the specified skin name. If a * module name is supplied, the returned skin module name is * specific to the module passed in. * @param {string} skin the name of the skin. * @param {string} mod optional: the name of a module to skin. * @return {string} the full skin module name. * Adds the skin def to the module info * @param {string} skin the name of the skin. * @param {string} mod the name of the module. * @param {string} parent parent module if this is a skin of a * @return {string} the module name for the skin. // Add a module definition for the module-specific skin css * <dt>name:</dt> <dd>required, the group name</dd> * <dt>base:</dt> <dd>The base dir for this module group</dd> * <dt>root:</dt> <dd>The root path to add to each combo * <dt>combine:</dt> <dd>combo handle</dd> * <dt>comboBase:</dt> <dd>combo service base path</dd> * <dt>modules:</dt> <dd>the group of modules</dd> * @param {object} o An object containing the module data. * @param {string} name the group name. * Add a new module to the component metadata. * <dt>name:</dt> <dd>required, the component name</dd> * <dt>type:</dt> <dd>required, the component type (js or css) * <dt>path:</dt> <dd>required, the path to the script from * <dt>requires:</dt> <dd>array of modules required by this * <dt>optional:</dt> <dd>array of optional modules for this * <dt>supersedes:</dt> <dd>array of the modules this component * <dt>after:</dt> <dd>array of modules the components which, if * present, should be sorted above this one</dd> * <dt>after_map:</dt> <dd>faster alternative to 'after' -- supply * a hash instead of an array</dd> * <dt>rollup:</dt> <dd>the number of superseded modules required * for automatic rollup</dd> * <dt>fullpath:</dt> <dd>If fullpath is specified, this is used * instead of the configured base + path</dd> * <dt>skinnable:</dt> <dd>flag to determine if skin assets should * automatically be pulled in</dd> * <dt>submodules:</dt> <dd>a hash of submodules</dd> * <dt>group:</dt> <dd>The group the module belongs to -- this * is set automatically when it is added as part of a group * <dd>array of BCP 47 language tags of languages for which this * module has localized resource bundles, * e.g., ["en-GB","zh-Hans-CN"]</dd> * <dd>Specifies that the module should be loaded automatically if * a condition is met. This is an object with up to three fields: * [trigger] - the name of a module that can trigger the auto-load * [test] - a function that returns true when the module is to be * [when] - specifies the load order of the conditional module * with regard to the position of the trigger module. * This should be one of three values: 'before', 'after', or * 'instead'. The default is 'after'. * <dt>testresults:</dt><dd>a hash of test results from Y.Features.all()</dd> * @param {object} o An object containing the module data. * @param {string} name the module name (optional), required if not * @return {object} the module definition or null if * the object passed in did not provide all required attributes. //Only merge this data if the temp flag is set //from an earlier pass from a pattern or else //an override module (YUI_config) can not be used to //replace a default module. //This catches temp modules loaded via a pattern // The module will be added twice, once from the pattern and // Once from the actual add call, this ensures that properties // that were added to the module the first time around (group: gallery) // are also added the second time around too. // Handle submodule logic // , existing = this.moduleInfo[name], newr; // looks like we are expected to work out the metadata // for the parent module language packs from what is // specified in the child modules. // Add rollup file, need to add to supersedes list too // Add rollup file, need to add to supersedes list too //o.supersedes = YObject.keys(YArray.hash(sup)); for (i =
0; i < t.
length; i++) {
// the 'when' attribute can be 'before', 'after', or 'instead' if (
when ==
'instead') {
// replace the trigger }
else {
// before the trigger // the trigger requires the conditional mod, // so it should appear before the conditional // mod if we do not intersede. }
else {
// after the trigger * Add a requirement for one or more module * @param {string[] | string*} what the modules to load. * Grab all the items that were asked for, check to see if the Loader * meta-data contains a "use" array. If it doesm remove the asked item and replace it with * the content of the "use". * This will make asking for: "dd" * Actually ask for: "dd-ddm-base,dd-ddm,dd-ddm-drop,dd-drag,dd-proxy,dd-constrain,dd-drop,dd-scroll,dd-drop-plugin" * @method _explodeRollups * Explodes the required array to remove aliases and replace them with real modules * @param {Array} r The original requires array * @return {Array} The new array of exploded requirements var c = [], i,
mod, o, m;
for (i =
0; i < r.
length; i++) {
//Must walk the other modules in case a module is a rollup of rollups (datatype) * Returns an object containing properties for all modules required * in order to load the requested module * @param {object} mod The module definition from moduleInfo. * @return {array} the expanded requirement list. // pattern match leaves module stub that needs to be filled out // console.log('cache: ' + mod.langCache + ' == ' + this.lang); // if (mod.expanded && (!mod.langCache || mod.langCache == this.lang)) { //If a module has a lang attribute, auto add the intl requirement. for (i =
0; i < r.
length; i++) {
// get the requirements from superseded modules, if any for (i =
0; i < r.
length; i++) {
// if this module has submodules, the requirements list is // expanded to include the submodules. This is so we can // prevent dups when a submodule is already loaded and the for (i =
0; i < o.
length; i++) {
//first see if they've specfied a ua check //then see if they've got a test fn & if it returns true //otherwise just having a condition block is enough * Returns a hash of module names the supplied module satisfies. * @param {string} name The name of the module. * @return {object} what this module provides. // supmap = this.provides; * Calculates the dependency tree, the result is stored in the sorted * @param {object} o optional options object. * @param {string} type optional argument to prune modules. * Creates a "psuedo" package for languages provided in the lang array * @param {String} lang The language to create * @param {Object} m The module definition to create the language pack around * @return {Object} The module definition * Investigates the current YUI configuration on the page. By default, * modules already detected will not be loaded again unless a force * option is encountered. Called by calculate() //m.requires = YObject.keys(YArray.hash(m.requires)); // Create lang pack modules // Setup root package if the module has lang defined, // it needs to provide a root language pack //l = Y.merge(this.inserted); // add the ignore list to the list of loaded packages // expand the list to include superseded modules // remove modules on the force list from the loaded list if (
this.
force[i]
in l) {
* Builds a module name for a language pack * @method getLangPackName * @param {string} lang the language code. * @param {string} mname the module to build it for. * @return {string} the language pack module name. * Inspects the required modules list looking for additional * dependencies. Expands the required list to include all * required modules. Called by calculate() // the setup phase is over, all modules have been created * Get's the loader meta data for the requested module * @param {String} mname The module name to get * @return {Object} The module metadata //TODO: Remove name check - it's a quick hack to fix pattern WIP // check the patterns library to see if we should automatically add // the module with defaults // use the metadata supplied for the pattern // as the module definition. // impl in rollup submodule * Remove superceded modules and loaded modules. Called by * calculate() after we have the mega list of all dependencies * @return {object} the reduced dependency hash. // remove if already loaded // remove anything this module supersedes for (j =
0; j < s.
length; j++) {
* Handles the queue when a module has been loaded for all cases * @param {String} msg The message from Loader * @param {Boolean} success A boolean denoting success or failure * The default Loader onSuccess handler, calls this.onSuccess with a payload * The default Loader onFailure handler, calls this.onFailure with a payload * The default Loader onTimeout handler, calls this.onTimeout with a payload * Sorts the dependency tree. The last step of calculate() // create an indexed list // keep going until we make a pass without moving anything // start the loop after items that are already sorted for (j = p; j < l; j++) {
// check the next module on the list to see if its // dependencies have been met // check everything below current item and move if we // find a requirement for the current item for (k = j +
1; k < l; k++) {
// extract the dependency so we can move it up // insert the dependency above the item that // only swap two dependencies once to short circut // jump out of loop if we moved something // this item is sorted, move our pointer and keep going // when we make it here and moved is false, we are * Handles the actual insertion of script/link tags * @param {Object} source The YUI instance the request came from * @param {Object} o The metadata to include * @param {String} type JS or CSS * @param {Boolean} [skipcalc=false] Do a Loader.calculate on the meta // restore the state at the time of the request // build the dependency list // don't include type so we can process CSS and script in // one pass when the type is not specified. // IE hack for style overrides that are not being applied // set a flag to indicate the load has started // flag to indicate we are done with the combo service // and any additional files will need to be loaded * Once a loader operation is completely finished, process any additional queued items. * inserts the requested modules and their dependencies. * <code>type</code> can be "js" or "css". Both script and * css are inserted if type is not provided. * @param {object} o optional options object. * @param {string} type the type of dependency to insert. * Executed every time a module is loaded, and if we are in a load * cycle, we attempt to load the next script. Public so that it * is possible to call this if using a method other than * Y.register to determine when scripts are fully loaded * @param {string} mname optional the name of the module that has * been loaded (which is usually why it is time to load the next // It is possible that this function is executed due to something // else on the page loading a YUI module. Only react when we // are actively loading something var s,
len, i, m,
url,
fn,
msg,
attr,
group,
groupName, j,
frag,
for (i =
0; i <
len; i++) {
// the default combo base for (i =
0; i <
len; i++) {
for (i =
0; i <
len; i++) {
// m = self.getModule(s[i]); // Do not try to combine non-yui JS unless combo def if ((
url !== j) && (i <= (
len -
1)) &&
//Hack until this is rewritten to use an array and not string concat: //Hack until this is rewritten to use an array and not string concat: // if the module that was just loaded isn't what we were expecting, // The global handler that is called when each module is loaded // will pass that module name to this function. Storing this // data to avoid loading the same module multiple times // centralize this in the callback // self.loaded[mname] = true; // provided = self.getProvides(mname); // Y.mix(self.loaded, provided); // Y.mix(self.inserted, provided); for (i =
0; i <
len; i = i +
1) {
// this.inserted keeps track of what the loader has loaded. // move on if this item is done. // Because rollups will cause multiple load notifications // from Y, loadNext may be called multiple times for // the same module when loading a rollup. We can safely // skip the subsequent requests // log("inserting " + s[i]); msg =
'Undefined module ' + s[i] +
' skipped';
// self.inserted[s[i]] = true; // The load type is stored to offer the possibility to load // the css separately from the script. // internal callback for loading css first * Apply filter defined for this instance to a url/path * @param {string} u the string to filter. * @param {string} name the name of the module, if we are processing * a single module as opposed to a combined url. * @return {string} the filtered string. * Generates the full url for a module * @param {string} path the path fragment. * @param {String} name The name of the module * @pamra {String} [base=self.base] The base url to use * @return {string} the full url. * Returns an Object hash of file arrays built from `loader.sorted` or from an arbitrary list of sorted modules. * @param {Boolean} [calc=false] Perform a loader.calculate() before anything else * @param {Array} [s=loader.sorted] An override for the loader.sorted array * @return {Object} Object hash (js and css) of two arrays of file lists * @example This method can be used as an off-line dep calculator * var loader = new Y.Loader({ * require: ['node', 'dd', 'console'] * var out = loader.resolve(true); for (i =
0; i < s.
length; i++) {
* Returns an Object hash of hashes built from `loader.sorted` or from an arbitrary list of sorted modules. * @param {Boolean} [calc=false] Perform a loader.calculate() before anything else * @param {Array} [s=loader.sorted] An override for the loader.sorted array * @return {Object} Object hash (js and css) of two object hashes of file lists, with the module name as the key * @example This method can be used as an off-line dep calculator * var loader = new Y.Loader({ * require: ['node', 'dd', 'console'] * var out = loader.hash(true); for (i =
0; i < s.
length; i++) {