diff --git a/demo/require.js b/demo/require.js index bfaccea6..739a12a3 100644 --- a/demo/require.js +++ b/demo/require.js @@ -13,7 +13,7 @@ setInterval: false, importScripts: false */ var require; (function () { //Change this version number for each release. - var version = "0.14.1", + var version = "0.14.2", empty = {}, s, i, defContextName = "_", contextLoads = [], scripts, script, rePkg, src, m, dataMain, cfg = {}, setReadyState, @@ -43,7 +43,7 @@ var require; cfg = require; } } - + /** * Calls a method on a plugin. The obj object should have two property, * name: the name of the method to call on the plugin @@ -65,7 +65,7 @@ var require; req(["require/" + prefix], context.contextName); } } - + /** * Convenience method to call main for a require.def call that was put on * hold in the defQueue. @@ -78,6 +78,33 @@ var require; context.loaded[args[0]] = true; } + /** + * Used to set up package paths from a packagePaths or packages config object. + * @param {Object} packages the object to store the new package config + * @param {Array} currentPackages an array of packages to configure + * @param {String} [dir] a prefix dir to use. + */ + function configurePackageDir(packages, currentPackages, dir) { + var i, location, pkgObj; + for (i = 0; (pkgObj = currentPackages[i]); i++) { + pkgObj = typeof pkgObj === "string" ? { name: pkgObj } : pkgObj; + location = pkgObj.location; + + //Add dir to the path, but avoid paths that start with a slash + //or have a colon (indicates a protocol) + if (dir && (!location || (location.indexOf("/") !== 0 && location.indexOf(":") === -1))) { + pkgObj.location = dir + "/" + (pkgObj.location || pkgObj.name); + } + + //Normalize package paths. + pkgObj.location = pkgObj.location || pkgObj.name; + pkgObj.lib = pkgObj.lib || "lib"; + pkgObj.main = pkgObj.main || "main"; + + packages[pkgObj.name] = pkgObj; + } + } + /** * Resumes tracing of dependencies and then checks if everything is loaded. */ @@ -253,7 +280,7 @@ var require; var context, newContext, loaded, pluginPrefix, canSetContext, prop, newLength, outDeps, mods, paths, index, i, deferMods, deferModArgs, lastModArg, waitingName, packages, - packagePaths, pkgPath, pkgNames, pkgName, pkgObj; + packagePaths; contextName = contextName ? contextName : (config && config.context ? config.context : s.ctxName); context = s.contexts[contextName]; @@ -271,7 +298,7 @@ var require; pluginPrefix = context.defPlugin[name]; } - + //If module already defined for context, or already waiting to be //evaluated, leave. waitingName = context.waiting[name]; @@ -326,7 +353,7 @@ var require; if (s.plugins.newContext) { s.plugins.newContext(newContext); } - + context = s.contexts[contextName] = newContext; } @@ -365,43 +392,14 @@ var require; if (packagePaths) { for (prop in packagePaths) { if (!(prop in empty)) { - pkgPath = prop; - pkgNames = packagePaths[pkgPath]; - for (i = 0; (pkgName = pkgNames[i]); i++) { - if (typeof pkgName === "string") { - //Standard package mapping. - pkgObj = packages[pkgName] = { - name: pkgName, - location: pkgPath + "/" + pkgName - }; - } else { - //A custom setup. - pkgObj = context.config.packages[pkgName.name] = pkgName; - pkgObj.location = pkgPath + "/" + (pkgObj.location || pkgObj.name); - } - } + configurePackageDir(packages, packagePaths[prop], prop); } } } //Adjust packages if necessary. if (config.packages) { - for (prop in config.packages) { - if (!(prop in empty)) { - pkgObj = packages[prop] = config.packages[prop]; - pkgObj.name = pkgObj.name || prop; - } - } - } - - //Normalize package paths. - for (prop in packages) { - if (!(prop in empty)) { - pkgObj = packages[prop]; - pkgObj.location = pkgObj.location || pkgObj.name; - pkgObj.lib = pkgObj.lib || "lib"; - pkgObj.main = pkgObj.main || "main"; - } + configurePackageDir(packages, config.packages); } //Done with modifications, assing packages back to context config @@ -430,7 +428,7 @@ var require; if (config.ready) { req.ready(config.ready); } - + //If it is just a config block, nothing else, //then return. if (!deps) { @@ -445,7 +443,7 @@ var require; outDeps = deps; deps = []; for (i = 0; i < outDeps.length; i++) { - deps[i] = req.splitPrefix(outDeps[i], name); + deps[i] = req.splitPrefix(outDeps[i], name, context); } } @@ -501,7 +499,7 @@ var require; args: [name, deps, callback, context] }); } - + //Hold on to the module until a script load or other adapter has finished //evaluating the whole file. This helps when a file has more than one //module in it -- dependencies are not traced and fetched until the whole @@ -630,7 +628,7 @@ var require; return req; }; - + /** * Internal method used by environment adapters to complete a load event. * A load event could be a script load or just a load pass from a synchronous @@ -663,7 +661,7 @@ var require; //moduleName that maps to a require.def call. This line is important //for traditional browser scripts. context.loaded[moduleName] = true; - + context.scriptCount -= 1; resume(context); }; @@ -788,7 +786,7 @@ var require; } } }; - + req.isArray = function (it) { return ostring.call(it) === "[object Array]"; }; @@ -817,10 +815,12 @@ var require; } contextName = contextName || s.ctxName; - //Normalize module name, if it contains . or .. - moduleName = req.normalizeName(moduleName, relModuleName); + var ret, context = s.contexts[contextName]; - var ret = s.contexts[contextName].defined[moduleName]; + //Normalize module name, if it contains . or .. + moduleName = req.normalizeName(moduleName, relModuleName, context); + + ret = context.defined[moduleName]; if (ret === undefined) { req.onError(new Error("require: module name '" + moduleName + @@ -867,16 +867,17 @@ var require; req.jsExtRegExp = /\.js$/; - + /** * Given a relative module name, like ./something, normalize it to * a real name that can be mapped to a path. * @param {String} name the relative name * @param {String} baseName a real name that the name arg is relative * to. + * @param {Object} context * @returns {String} normalized name */ - req.normalizeName = function (name, baseName) { + req.normalizeName = function (name, baseName, context) { //Adjust any relative paths. var part; if (name.charAt(0) === ".") { @@ -885,13 +886,20 @@ var require; name + ", no relative module name available.")); } - //Convert baseName to array, and lop off the last part, - //so that . matches that "directory" and not name of the baseName's - //module. For instance, baseName of "one/two/three", maps to - //"one/two/three.js", but we want the directory, "one/two" for - //this normalization. - baseName = baseName.split("/"); - baseName = baseName.slice(0, baseName.length - 1); + + if (context.config.packages[baseName]) { + //If the baseName is a package name, then just treat it as one + //name to concat the name with. + baseName = [baseName]; + } else { + //Convert baseName to array, and lop off the last part, + //so that . matches that "directory" and not name of the baseName's + //module. For instance, baseName of "one/two/three", maps to + //"one/two/three.js", but we want the directory, "one/two" for + //this normalization. + baseName = baseName.split("/"); + baseName = baseName.slice(0, baseName.length - 1); + } name = baseName.concat(name.split("/")); for (i = 0; (part = name[i]); i++) { @@ -912,16 +920,17 @@ var require; * Splits a name into a possible plugin prefix and * the module name. If baseName is provided it will * also normalize the name via require.normalizeName() - * + * * @param {String} name the module name * @param {String} [baseName] base name that name is * relative to. + * @param {Object} context * * @returns {Object} with properties, 'prefix' (which * may be null), 'name' and 'fullName', which is a combination * of the prefix (if it exists) and the name. */ - req.splitPrefix = function (name, baseName) { + req.splitPrefix = function (name, baseName, context) { var index = name.indexOf("!"), prefix = null; if (index !== -1) { prefix = name.substring(0, index); @@ -929,7 +938,7 @@ var require; } //Account for relative paths if there is a base name. - name = req.normalizeName(name, baseName); + name = req.normalizeName(name, baseName, context); return { prefix: prefix, @@ -943,10 +952,11 @@ var require; */ req.nameToUrl = function (moduleName, ext, contextName, relModuleName) { var paths, packages, pkg, pkgPath, syms, i, parentModule, url, - config = s.contexts[contextName].config; + context = s.contexts[contextName], + config = context.config; //Normalize module name if have a base relative module name to work from. - moduleName = req.normalizeName(moduleName, relModuleName); + moduleName = req.normalizeName(moduleName, relModuleName, context); //If a colon is in the URL, it indicates a protocol is used and it is just //an URL to a file, or if it starts with a slash or ends with .js, it is just a plain file. @@ -1010,7 +1020,7 @@ var require; priorityName, pIsWaiting = s.plugins.isWaiting, pOrderDeps = s.plugins.orderDeps, - + i, module, allDone, loads, loadArgs, err; //If already doing a checkLoaded call, @@ -1103,7 +1113,7 @@ var require; if (pOrderDeps) { pOrderDeps(context); } - + //Before defining the modules, give priority treatment to any modifiers //for modules that are already defined. for (prop in modifiers) { @@ -1113,7 +1123,7 @@ var require; } } } - + //Define the modules, doing a depth first search. for (i = 0; (module = waiting[i]); i++) { req.exec(module, {}, waiting, context); @@ -1212,12 +1222,12 @@ var require; /** * Executes the modules in the correct order. - * + * * @private */ req.exec = function (module, traced, waiting, context) { //Some modules are just plain script files, abddo not have a formal - //module definition, + //module definition, if (!module) { //Returning undefined for Spidermonky strict checking in Komodo return undefined; @@ -1281,7 +1291,7 @@ var require; ret = defined[name]; } else { if (cjsModule && "exports" in cjsModule) { - ret = defined[name] = depModule.exports; + ret = defined[name] = cjsModule.exports; } else { if (name in defined && !usingExports) { req.onError(new Error(name + " has already been defined")); @@ -1294,7 +1304,7 @@ var require; //Execute modifiers, if they exist. req.execModifiers(name, traced, waiting, context); - + return ret; }; @@ -1334,7 +1344,7 @@ var require; delete modifiers[target]; } }; - + /** * callback for script loads, used to check status of loading. * @@ -1455,11 +1465,11 @@ var require; if (cfg.baseUrlMatch) { rePkg = cfg.baseUrlMatch; } else { - - - + + + rePkg = /(allplugins-|transportD-)?require\.js(\W|$)/i; - + } for (i = scripts.length - 1; i > -1 && (script = scripts[i]); i--) { @@ -1590,7 +1600,7 @@ var require; } } //****** END page load functionality **************** - + //Set up default context. If require was a configuration object, use that as base config. req(cfg); @@ -1888,7 +1898,7 @@ var require; if (loc === "_match") { //Found default locale to use for the top-level bundle name. defLoc = msWaiting[loc]; - + } else if (msWaiting[loc] !== loc) { //A "best fit" locale, store it off to the end and handle //it at the end by just assigning the best fit value, since @@ -1918,7 +1928,7 @@ var require; //loop above so that the default locale bundle has been properly mixed //together. context.defined[master] = context.defined[modulePrefix + "/" + defLoc + "/" + moduleSuffix]; - + //Handle any best fit locale definitions. if (bestFit) { for (loc in bestFit) { @@ -1983,7 +1993,7 @@ var require; progIds = [progId]; // so faster next time break; } - } + } } if (!xhr) { @@ -1993,7 +2003,7 @@ var require; return xhr; }; } - + if (!require.fetchText) { require.fetchText = function (url, callback) { var xhr = require.getXhr(); @@ -2092,7 +2102,7 @@ var require; require.fetchText(url, function (text) { context.text[key] = text; context.loaded[name] = true; - require.checkLoaded(contextName); + require.checkLoaded(contextName); }); } }, @@ -2376,7 +2386,7 @@ var require; /** * Called when all modules have been loaded. Not needed for this plugin. - * State is reset as part of scriptCacheCallback. + * State is reset as part of scriptCacheCallback. */ orderDeps: function (context) { }