loader.js revision e34097fb797b12bf93384fd9a50f7d8d42708106
202N/A * @submodule loader-base '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 * information for the version of the library in use, and will automatically pull in * dependencies for the modules requested. It can also 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 //Catch no config passed. * 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 * 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} * 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() * 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 Regex that matches a CSS URL. Used to guess the file type when it's not * Default filters for raw and debug 'searchExp':
'-min\\.js',
'searchExp':
'-min\\.js',
* Check the pages meta-data and cache the result. //Inspect the page for CSS only modules and mark them as loaded. // console.log('deleting ' + m.name); * 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') {
//If the config.skin is a string, format to the expected object if (
typeof val ===
'string') {
}
else if (i ==
'groups') {
}
else if (i ==
'modules') {
// add a hash of module definitions }
else if (i ==
'gallery') {
}
else if (i ==
'yui2' || i ==
'2in3') {
* 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. if (
typeof v ===
'string') {
* 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. if (
typeof o ===
'string') {
//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. //Always assume it's javascript unless the CSS pattern is matched. // 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. //console.log('returning no reqs for ' + mod.name); //console.log('returning requires for ' + mod.name, mod.requires); //TODO add modue cache here out of scope.. // 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++) {
//Set the module to not parsed since we have conditionals and this could change the dependency tree. //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 * Check to see if named css module is already loaded on the page * @param {String} name The name of the css file //TODO - Make this call a batching call with name being an array //Add the classname to the element if (
style[
'display'] ===
'none') {
* 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() //TODO Move done out of scope // 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 //There is no test method, create a default one that tests // the pattern against the mod name // 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 onProgress handler, calls this.onProgress 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 //TODO Move this out of scope // 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. //Filter out the opposite type and reset the array so the checks later work //console.log('Resolved Modules: ', modules); var errs = {}, i =
0, u =
'',
fn;
* 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 * 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 * @param {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); var len, i, m,
url,
fn,
msg,
attr,
group,
groupName, j,
frag,
// the default combo base for (i =
0; i <
len; i++) {
//This is not a combo module, skip it and load it singly later. //This is not a combo module, skip it and load it singly later. for (i =
0; i <
len; i++) {
// Do not try to combine non-yui JS unless combo def //Add them to the next process.. //singles.push(mods[i].name); for (s =
0; s <
len; s++) {
Shortcut to calculate, resolve and load all modules. var loader = new Y.Loader({ console.log('All modules have loaded..'); @param {Callback} cb Executed after all load operations are complete },
'@VERSION@' ,{
requires:[
'get',
'features']});
YUI.
add(
'loader-rollup',
function(Y) {
* Optional automatic rollup logic for reducing http connections * when not using a combo service. * Look for rollup packages to determine if all of the modules a * rollup supersedes are required. If so, include the rollup to * help reduce the total number of connections required. Called * by calculate(). This is an optional feature, and requires the * appropriate submodule to function. // find and cache rollup modules // if (m && m.rollup && m.supersedes) { // make as many passes as needed to pick up rollup rollups // go through the rollup candidates // there can be only one, unless forced for (j =
0; j < s.
length; j++) {
// if the superseded module is loaded, we can't // load the rollup unless it has been forced. // increment the counter if this module is required. // if we are beyond the rollup threshold, we will // expand the rollup's dependencies // if we made it here w/o rolling up something, we are done },
'@VERSION@' ,{
requires:[
'loader-base']});
YUI.
add(
'loader-yui3',
function(Y) {
"autocomplete-filters": {
"autocomplete-filters-accentfold": {
"autocomplete-highlighters": {
"autocomplete-highlighters-accentfold": {
"autocomplete-list-keys": {
"name":
"autocomplete-list-keys",
// Only add keyboard support to autocomplete-list if this doesn't appear to // be an iOS or Android-based mobile device. // There's currently no feasible way to actually detect whether a device has // a hardware keyboard, so this sniff will have to do. It can easily be // overridden by manually loading the autocomplete-list-keys module. // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari // doesn't fire the keyboard events used by AutoCompleteList, so there's // no point loading the -keys module even when a bluetooth keyboard may be "trigger":
"autocomplete-list" "autocomplete-sources": {
"datasource-arrayschema",
"datasource-arrayschema": {
"datasource-jsonschema": {
"datasource-textschema": {
"datasource-xmlschema": {
"datatable-column-widths",
"datatable-column-widths": {
"datatable-datasource": {
"datatable-column-widths",
"datatype-date-format": {
"datatype-date-parse": {},
"datatype-number-format": {},
"datatype-number-parse": {},
"datatype-xml-format": {},
"datatype-xml-parse": {},
"event-custom-complex": {
"name":
"graphics-canvas",
"graphics-canvas-default": {
"name":
"graphics-canvas-default",
"graphics-svg-default": {
"name":
"graphics-svg-default",
"graphics-vml-default": {
"name":
"graphics-vml-default",
"highlight-accentfold": {
"name":
"history-hash-ie",
"trigger":
"history-hash" "querystring-stringify-simple" "widget-position-constrain" "widget-position-constrain",
"querystring-parse-simple": {
"querystring-stringify": {
"querystring-stringify-simple": {
"name":
"scrollview-base-ie",
"trigger":
"scrollview-base",
"scrollview-paginator": {
"scrollview-scrollbars": {
"text-data-accentfold": {
"name":
"transition-timer",
"name":
"widget-base-ie",
"trigger":
"widget-base",
"widget-position-align": {
"widget-position-constrain": {
},
'@VERSION@' ,{
requires:[
'loader-base']});
YUI.
add(
'loader',
function(Y){},
'@VERSION@' ,{
use:[
'loader-base',
'loader-rollup',
'loader-yui3' ]});