Plato on Github
Report Home
dojo/_base/loader.js
Maintainability
64.56
Lines of code
776
Difficulty
67.12
Estimated Errors
4.16
Function weight
By Complexity
By SLOC
define(["./kernel", "../has", "require", "module", "../json", "./lang", "./array"], function(dojo, has, require, thisModule, json, lang, array) { // module: // dojo/_base/loader // This module defines the v1.x synchronous loader API. // signal the loader in sync mode... //>>pure-amd if (!has("dojo-loader")){ console.error("cannot load the Dojo v1.x loader with a foreign loader"); return 0; } has.add("dojo-fast-sync-require", 1); var makeErrorToken = function(id){ return {src:thisModule.id, id:id}; }, slashName = function(name){ return name.replace(/\./g, "/"); }, buildDetectRe = /\/\/>>built/, dojoRequireCallbacks = [], dojoRequireModuleStack = [], dojoRequirePlugin = function(mid, require, loaded){ dojoRequireCallbacks.push(loaded); array.forEach(mid.split(","), function(mid){ var module = getModule(mid, require.module); dojoRequireModuleStack.push(module); injectModule(module); }); checkDojoRequirePlugin(); }, checkDojoRequirePlugin = (has("dojo-fast-sync-require") ? // This version of checkDojoRequirePlugin makes the observation that all dojoRequireCallbacks can be released // when all *non-dojo/require!, dojo/loadInit!* modules are either executed, not requested, or arrived. This is // the case since there are no more modules the loader is waiting for, therefore, dojo/require! must have // everything it needs on board. // // The potential weakness of this algorithm is that dojo/require will not execute callbacks until *all* dependency // trees are ready. It is possible that some trees may be ready earlier than others, and this extra wait is non-optimal. // Still, for big projects, this seems better than the original algorithm below that proved slow in some cases. // Note, however, the original algorithm had the potential to execute partial trees, but that potential was never enabled. // There are also other optimization available with the original algorithm that have not been explored. function(){ var module, mid; for(mid in modules){ module = modules[mid]; if(module.noReqPluginCheck===undefined){ // tag the module as either a loadInit or require plugin or not for future reference module.noReqPluginCheck = /loadInit\!/.test(mid) || /require\!/.test(mid) ? 1 : 0; } if(!module.executed && !module.noReqPluginCheck && module.injected==requested){ return; } } guardCheckComplete(function(){ var oldCallbacks = dojoRequireCallbacks; dojoRequireCallbacks = []; array.forEach(oldCallbacks, function(cb){cb(1);}); }); } : (function(){ // Note: this is the original checkDojoRequirePlugin that is much slower than the algorithm above. However, we know it // works, so we leave it here in case the algorithm above fails in some corner case. // // checkDojoRequirePlugin inspects all of the modules demanded by a dojo/require!<module-list> dependency // to see if they have arrived. The loader does not release *any* of these modules to be instantiated // until *all* of these modules are on board, thereby preventing the evaluation of a module with dojo.require's // that reference modules that are not available. // // The algorithm works by traversing the dependency graphs (remember, there can be cycles so they are not trees) // of each module in the dojoRequireModuleStack array (which contains the list of modules demanded by dojo/require!). // The moment a single module is discovered that is missing, the algorithm gives up and indicates that not all // modules are on board. dojo/loadInit! and dojo/require! are ignored because there dependencies are inserted // directly in dojoRequireModuleStack. For example, if "your/module" module depends on "dojo/require!my/module", then // *both* "dojo/require!my/module" and "my/module" will be in dojoRequireModuleStack. Obviously, if "my/module" // is on board, then "dojo/require!my/module" is also satisfied, so the algorithm doesn't check for "dojo/require!my/module". // // Note: inserting a dojo/require!<some-module-list> dependency in the dojoRequireModuleStack achieves nothing // with the current algorithm; however, having such modules present makes it possible to optimize the algorithm // // Note: prior versions of this algorithm had an optimization that signaled loaded on dojo/require! dependencies // individually (rather than waiting for them all to be resolved). The implementation proved problematic with cycles // and plugins. However, it is possible to reattach that strategy in the future. // a set from module-id to {undefined | 1 | 0}, where... // undefined => the module has not been inspected // 0 => the module or at least one of its dependencies has not arrived // 1 => the module is a loadInit! or require! plugin resource, or is currently being traversed (therefore, assume // OK until proven otherwise), or has been completely traversed and all dependencies have arrived var touched, traverse = function(m){ touched[m.mid] = 1; for(var t, module, deps = m.deps || [], i= 0; i<deps.length; i++){ module = deps[i]; if(!(t = touched[module.mid])){ if(t===0 || !traverse(module)){ touched[m.mid] = 0; return false; } } } return true; }; return function(){ // initialize the touched hash with easy-to-compute values that help short circuit recursive algorithm; // recall loadInit/require plugin modules are dependencies of modules in dojoRequireModuleStack... // which would cause a circular dependency chain that would never be resolved if checked here // notice all dependencies of any particular loadInit/require plugin module will already // be checked since those are pushed into dojoRequireModuleStack explicitly by the // plugin...so if a particular loadInitPlugin module's dependencies are not really // on board, that *will* be detected elsewhere in the traversal. var module, mid; touched = {}; for(mid in modules){ module = modules[mid]; if(module.executed || module.noReqPluginCheck){ touched[mid] = 1; }else{ if(module.noReqPluginCheck!==0){ // tag the module as either a loadInit or require plugin or not for future reference module.noReqPluginCheck = /loadInit\!/.test(mid) || /require\!/.test(mid) ? 1 : 0; } if(module.noReqPluginCheck){ touched[mid] = 1; }else if(module.injected!==arrived){ // not executed, has not arrived, and is not a loadInit or require plugin resource touched[mid] = 0; }// else, leave undefined and we'll traverse the dependencies } } for(var t, i = 0, end = dojoRequireModuleStack.length; i<end; i++){ module = dojoRequireModuleStack[i]; if(!(t = touched[module.mid])){ if(t===0 || !traverse(module)){ return; } } } guardCheckComplete(function(){ var oldCallbacks = dojoRequireCallbacks; dojoRequireCallbacks = []; array.forEach(oldCallbacks, function(cb){cb(1);}); }); }; })()), dojoLoadInitPlugin = function(mid, require, loaded){ // mid names a module that defines a "dojo load init" bundle, an object with two properties: // // * names: a vector of module ids that give top-level names to define in the lexical scope of def // * def: a function that contains some some legacy loader API applications // // The point of def is to possibly cause some modules to be loaded (but not executed) by dojo/require! where the module // ids are possibly-determined at runtime. For example, here is dojox.gfx from v1.6 expressed as an AMD module using the dojo/loadInit // and dojo/require plugins. // // // dojox/gfx: // // define("*loadInit_12, { // names:["dojo", "dijit", "dojox"], // def: function(){ // dojo.loadInit(function(){ // var gfx = lang.getObject("dojox.gfx", true); // // // // // code required to set gfx properties ommitted... // // // // // now use the calculations to include the runtime-dependent module // dojo.require("dojox.gfx." + gfx.renderer); // }); // } // }); // // define(["dojo", "dojo/loadInit!" + id].concat("dojo/require!dojox/gfx/matric,dojox/gfx/_base"), function(dojo){ // // when this AMD factory function is executed, the following modules are guaranteed downloaded but not executed: // // "dojox.gfx." + gfx.renderer // // dojox.gfx.matrix // // dojox.gfx._base // dojo.provide("dojo.gfx"); // dojo.require("dojox.gfx.matrix"); // dojo.require("dojox.gfx._base"); // dojo.require("dojox.gfx." + gfx.renderer); // return lang.getObject("dojo.gfx"); // }); // })(); // // The idea is to run the legacy loader API with global variables shadowed, which allows these variables to // be relocated. For example, dojox and dojo could be relocated to different names by giving a map and the code above will // execute properly (because the plugin below resolves the load init bundle.names module with respect to the module that demanded // the plugin resource). // // Note that the relocation is specified in the runtime configuration; relocated names need not be set at build-time. // // Warning: this is not the best way to express dojox.gfx as and AMD module. In fact, the module has been properly converted in // v1.7. However, this technique allows the builder to convert legacy modules into AMD modules and guarantee the codepath is the // same in the converted AMD module. require([mid], function(bundle){ // notice how names is resolved with respect to the module that demanded the plugin resource require(bundle.names, function(){ // bring the bundle names into scope for(var scopeText = "", args= [], i = 0; i<arguments.length; i++){ scopeText+= "var " + bundle.names[i] + "= arguments[" + i + "]; "; args.push(arguments[i]); } eval(scopeText); var callingModule = require.module, // the list of modules that need to be downloaded but not executed before the callingModule can be executed requireList = [], // the list of i18n bundles that are xdomain; undefined if none i18nDeps, syncLoaderApi = { provide:function(moduleName){ // mark modules that arrive consequent to multiple provides in this module as arrived since they can't be injected moduleName = slashName(moduleName); var providedModule = getModule(moduleName, callingModule); if(providedModule!==callingModule){ setArrived(providedModule); } }, require:function(moduleName, omitModuleCheck){ moduleName = slashName(moduleName); omitModuleCheck && (getModule(moduleName, callingModule).result = nonmodule); requireList.push(moduleName); }, requireLocalization:function(moduleName, bundleName, locale){ // since we're going to need dojo/i8n, add it to i18nDeps if not already there if(!i18nDeps){ // don't have to map since that will occur when the dependency is resolved i18nDeps = ["dojo/i18n"]; } // figure out if the bundle is xdomain; if so, add it to the i18nDepsSet locale = (locale || dojo.locale).toLowerCase(); moduleName = slashName(moduleName) + "/nls/" + (/root/i.test(locale) ? "" : locale + "/") + slashName(bundleName); if(getModule(moduleName, callingModule).isXd){ // don't have to map since that will occur when the dependency is resolved i18nDeps.push("dojo/i18n!" + moduleName); }// else the bundle will be loaded synchronously when the module is evaluated }, loadInit:function(f){ f(); } }, hold = {}, p; // hijack the correct dojo and apply bundle.def try{ for(p in syncLoaderApi){ hold[p] = dojo[p]; dojo[p] = syncLoaderApi[p]; } bundle.def.apply(null, args); }catch(e){ signal("error", [makeErrorToken("failedDojoLoadInit"), e]); }finally{ for(p in syncLoaderApi){ dojo[p] = hold[p]; } } if(i18nDeps){ requireList = requireList.concat(i18nDeps); } if(requireList.length){ dojoRequirePlugin(requireList.join(","), require, loaded); }else{ loaded(); } }); }); }, extractApplication = function( text, // the text to search startSearch, // the position in text to start looking for the closing paren startApplication // the position in text where the function application expression starts ){ // find end of the call by finding the matching end paren // Warning: as usual, this will fail in the presence of unmatched right parans contained in strings, regexs, or unremoved comments var parenRe = /\(|\)/g, matchCount = 1, match; parenRe.lastIndex = startSearch; while((match = parenRe.exec(text))){ if(match[0] == ")"){ matchCount -= 1; }else{ matchCount += 1; } if(matchCount == 0){ break; } } if(matchCount != 0){ throw "unmatched paren around character " + parenRe.lastIndex + " in: " + text; } //Put the master matching string in the results. return [dojo.trim(text.substring(startApplication, parenRe.lastIndex))+";\n", parenRe.lastIndex]; }, // the following regex is taken from 1.6. It is a very poor technique to remove comments and // will fail in some cases; for example, consider the code... // // var message = "Category-1 */* Category-2"; // // The regex that follows will see a /* comment and trash the code accordingly. In fact, there are all // kinds of cases like this with strings and regexs that will cause this design to fail miserably. // // Alternative regex designs exist that will result in less-likely failures, but will still fail in many cases. // The only solution guaranteed 100% correct is to parse the code and that seems overkill for this // backcompat/unbuilt-xdomain layer. In the end, since it's been this way for a while, we won't change it. // See the opening paragraphs of Chapter 7 or ECME-262 which describes the lexical abiguity further. removeCommentRe = /(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, syncLoaderApiRe = /(^|\s)dojo\.(loadInit|require|provide|requireLocalization|requireIf|requireAfterIf|platformRequire)\s*\(/mg, amdLoaderApiRe = /(^|\s)(require|define)\s*\(/m, extractLegacyApiApplications = function(text, noCommentText){ // scan the noCommentText for any legacy loader API applications. Copy such applications into result (this is // used by the builder). Move dojo.loadInit applications to loadInitApplications string. Copy all other applications // to otherApplications string. If no applications were found, return 0, signalling an AMD module. Otherwise, return // loadInitApplications + otherApplications. Fixup text by replacing // // dojo.loadInit(// etc... // // with // // \n 0 && dojo.loadInit(// etc... // // Which results in the dojo.loadInit from *not* being applied. This design goes a long way towards protecting the // code from an over-agressive removeCommentRe. However... // // WARNING: the removeCommentRe will cause an error if a detected comment removes all or part of a legacy-loader application // that is not in a comment. var match, startSearch, startApplication, application, loadInitApplications = [], otherApplications = [], allApplications = []; // noCommentText may be provided by a build app with comments extracted by a better method than regex (hopefully) noCommentText = noCommentText || text.replace(removeCommentRe, function(match){ // remove iff the detected comment has text that looks like a sync loader API application; this helps by // removing as little as possible, minimizing the changes the janky regex will kill the module syncLoaderApiRe.lastIndex = amdLoaderApiRe.lastIndex = 0; return (syncLoaderApiRe.test(match) || amdLoaderApiRe.test(match)) ? "" : match; }); // find and extract all dojo.loadInit applications while((match = syncLoaderApiRe.exec(noCommentText))){ startSearch = syncLoaderApiRe.lastIndex; startApplication = startSearch - match[0].length; application = extractApplication(noCommentText, startSearch, startApplication); if(match[2]=="loadInit"){ loadInitApplications.push(application[0]); }else{ otherApplications.push(application[0]); } syncLoaderApiRe.lastIndex = application[1]; } allApplications = loadInitApplications.concat(otherApplications); if(allApplications.length || !amdLoaderApiRe.test(noCommentText)){ // either there were some legacy loader API applications or there were no AMD API applications return [text.replace(/(^|\s)dojo\.loadInit\s*\(/g, "\n0 && dojo.loadInit("), allApplications.join(""), allApplications]; }else{ // legacy loader API *was not* detected and AMD API *was* detected; therefore, assume it's an AMD module return 0; } }, transformToAmd = function(module, text){ // This is roughly the equivalent of dojo._xdCreateResource in 1.6-; however, it expresses a v1.6- dojo // module in terms of AMD define instead of creating the dojo proprietary xdomain module expression. // The module could have originated from several sources: // // * amd require() a module, e.g., require(["my/module"]) // * amd require() a nonmodule, e.g., require(["my/resource.js"') // * amd define() deps vector (always a module) // * dojo.require() a module, e.g. dojo.require("my.module") // * dojo.require() a nonmodule, e.g., dojo.require("my.module", true) // * dojo.requireIf/requireAfterIf/platformRequire a module // // The module is scanned for legacy loader API applications; if none are found, then assume the module is an // AMD module and return 0. Otherwise, a synthetic dojo/loadInit plugin resource is created and the module text // is rewritten as an AMD module with the single dependency of this synthetic resource. When the dojo/loadInit // plugin loaded the synthetic resource, it will cause all dojo.loadInit's to be executed, find all dojo.require's // (either directly consequent to dojo.require or indirectly consequent to dojo.require[After]If or // dojo.platformRequire, and finally cause loading of all dojo.required modules with the dojo/require plugin. Thus, // when the dojo/loadInit plugin reports it has been loaded, all modules required by the given module are guaranteed // loaded (but not executed). This then allows the module to execute it's code path without interupts, thereby // following the synchronous code path. // // Notice that this function behaves the same whether or not it happens to be in a mapped dojo/loader module. var extractResult, id, names = [], namesAsStrings = []; if(buildDetectRe.test(text) || !(extractResult = extractLegacyApiApplications(text))){ // buildDetectRe.test(text) => a built module, always AMD // extractResult==0 => no sync API return 0; } // manufacture a synthetic module id that can never be a real mdule id (just like require does) id = module.mid + "-*loadInit"; // construct the dojo/loadInit names vector which causes any relocated names to be defined as lexical variables under their not-relocated name // the dojo/loadInit plugin assumes the first name in names is "dojo" for(var p in getModule("dojo", module).result.scopeMap){ names.push(p); namesAsStrings.push('"' + p + '"'); } // rewrite the module as a synthetic dojo/loadInit plugin resource + the module expressed as an AMD module that depends on this synthetic resource // don't have to map dojo/init since that will occur when the dependency is resolved return "// xdomain rewrite of " + module.mid + "\n" + "define('" + id + "',{\n" + "\tnames:" + json.stringify(names) + ",\n" + "\tdef:function(" + names.join(",") + "){" + extractResult[1] + "}" + "});\n\n" + "define(" + json.stringify(names.concat(["dojo/loadInit!"+id])) + ", function(" + names.join(",") + "){\n" + extractResult[0] + "});"; }, loaderVars = require.initSyncLoader(dojoRequirePlugin, checkDojoRequirePlugin, transformToAmd), sync = loaderVars.sync, requested = loaderVars.requested, arrived = loaderVars.arrived, nonmodule = loaderVars.nonmodule, executing = loaderVars.executing, executed = loaderVars.executed, syncExecStack = loaderVars.syncExecStack, modules = loaderVars.modules, execQ = loaderVars.execQ, getModule = loaderVars.getModule, injectModule = loaderVars.injectModule, setArrived = loaderVars.setArrived, signal = loaderVars.signal, finishExec = loaderVars.finishExec, execModule = loaderVars.execModule, getLegacyMode = loaderVars.getLegacyMode, guardCheckComplete = loaderVars.guardCheckComplete; // there is exactly one dojoRequirePlugin among possibly-many dojo/_base/loader's (owing to mapping) dojoRequirePlugin = loaderVars.dojoRequirePlugin; dojo.provide = function(mid){ var executingModule = syncExecStack[0], module = lang.mixin(getModule(slashName(mid), require.module), { executed:executing, result:lang.getObject(mid, true) }); setArrived(module); if(executingModule){ (executingModule.provides || (executingModule.provides = [])).push(function(){ module.result = lang.getObject(mid); delete module.provides; module.executed!==executed && finishExec(module); }); }// else dojo.provide called not consequent to loading; therefore, give up trying to publish module value to loader namespace return module.result; }; has.add("config-publishRequireResult", 1, 0, 0); dojo.require = function(moduleName, omitModuleCheck) { // summary: // loads a Javascript module from the appropriate URI // // moduleName: String // module name to load, using periods for separators, // e.g. "dojo.date.locale". Module paths are de-referenced by dojo's // internal mapping of locations to names and are disambiguated by // longest prefix. See `dojo.registerModulePath()` for details on // registering new modules. // // omitModuleCheck: Boolean? // if `true`, omitModuleCheck skips the step of ensuring that the // loaded file actually defines the symbol it is referenced by. // For example if it called as `dojo.require("a.b.c")` and the // file located at `a/b/c.js` does not define an object `a.b.c`, // and exception will be throws whereas no exception is raised // when called as `dojo.require("a.b.c", true)` // // description: // Modules are loaded via dojo.require by using one of two loaders: the normal loader // and the xdomain loader. The xdomain loader is used when dojo was built with a // custom build that specified loader=xdomain and the module lives on a modulePath // that is a whole URL, with protocol and a domain. The versions of Dojo that are on // the Google and AOL CDNs use the xdomain loader. // // If the module is loaded via the xdomain loader, it is an asynchronous load, since // the module is added via a dynamically created script tag. This // means that dojo.require() can return before the module has loaded. However, this // should only happen in the case where you do dojo.require calls in the top-level // HTML page, or if you purposely avoid the loader checking for dojo.require // dependencies in your module by using a syntax like dojo["require"] to load the module. // // Sometimes it is useful to not have the loader detect the dojo.require calls in the // module so that you can dynamically load the modules as a result of an action on the // page, instead of right at module load time. // // Also, for script blocks in an HTML page, the loader does not pre-process them, so // it does not know to download the modules before the dojo.require calls occur. // // So, in those two cases, when you want on-the-fly module loading or for script blocks // in the HTML page, special care must be taken if the dojo.required code is loaded // asynchronously. To make sure you can execute code that depends on the dojo.required // modules, be sure to add the code that depends on the modules in a dojo.addOnLoad() // callback. dojo.addOnLoad waits for all outstanding modules to finish loading before // executing. // // This type of syntax works with both xdomain and normal loaders, so it is good // practice to always use this idiom for on-the-fly code loading and in HTML script // blocks. If at some point you change loaders and where the code is loaded from, // it will all still work. // // More on how dojo.require // `dojo.require("A.B")` first checks to see if symbol A.B is // defined. If it is, it is simply returned (nothing to do). // // If it is not defined, it will look for `A/B.js` in the script root // directory. // // `dojo.require` throws an exception if it cannot find a file // to load, or if the symbol `A.B` is not defined after loading. // // It returns the object `A.B`, but note the caveats above about on-the-fly loading and // HTML script blocks when the xdomain loader is loading a module. // // `dojo.require()` does nothing about importing symbols into // the current namespace. It is presumed that the caller will // take care of that. // // example: // To use dojo.require in conjunction with dojo.ready: // // | dojo.require("foo"); // | dojo.require("bar"); // | dojo.addOnLoad(function(){ // | //you can now safely do something with foo and bar // | }); // // example: // For example, to import all symbols into a local block, you might write: // // | with (dojo.require("A.B")) { // | ... // | } // // And to import just the leaf symbol to a local variable: // // | var B = dojo.require("A.B"); // | ... // // returns: // the required namespace object function doRequire(mid, omitModuleCheck){ var module = getModule(slashName(mid), require.module); if(syncExecStack.length && syncExecStack[0].finish){ // switched to async loading in the middle of evaluating a legacy module; stop // applying dojo.require so the remaining dojo.requires are applied in order syncExecStack[0].finish.push(mid); return undefined; } // recall module.executed has values {0, executing, executed}; therefore, truthy indicates executing or executed if(module.executed){ return module.result; } omitModuleCheck && (module.result = nonmodule); // rcg...why here and in two lines?? var currentMode = getLegacyMode(); // recall, in sync mode to inject is to *eval* the module text // if the module is a legacy module, this is the same as executing // but if the module is an AMD module, this means defining, not executing injectModule(module); // the inject may have changed the mode currentMode = getLegacyMode(); // in sync mode to dojo.require is to execute if(module.executed!==executed && module.injected===arrived){ // the module was already here before injectModule was called probably finishing up a xdomain // load, but maybe a module given to the loader directly rather than having the loader retrieve it loaderVars.guardCheckComplete(function(){ execModule(module); }); } if(module.executed){ return module.result; } if(currentMode==sync){ // the only way to get here is in sync mode and dojo.required a module that // * was loaded async in the injectModule application a few lines up // * was an AMD module that had deps that are being loaded async and therefore couldn't execute if(module.cjs){ // the module was an AMD module; unshift, not push, which causes the current traversal to be reattempted from the top execQ.unshift(module); }else{ // the module was a legacy module syncExecStack.length && (syncExecStack[0].finish= [mid]); } }else{ // the loader wasn't in sync mode on entry; probably async mode; therefore, no expectation of getting // the module value synchronously; make sure it gets executed though execQ.push(module); } return undefined; } var result = doRequire(moduleName, omitModuleCheck); if(has("config-publishRequireResult") && !lang.exists(moduleName) && result!==undefined){ lang.setObject(moduleName, result); } return result; }; dojo.loadInit = function(f) { f(); }; dojo.registerModulePath = function(/*String*/moduleName, /*String*/prefix){ // summary: // Maps a module name to a path // description: // An unregistered module is given the default path of ../[module], // relative to Dojo root. For example, module acme is mapped to // ../acme. If you want to use a different module name, use // dojo.registerModulePath. // example: // If your dojo.js is located at this location in the web root: // | /myapp/js/dojo/dojo/dojo.js // and your modules are located at: // | /myapp/js/foo/bar.js // | /myapp/js/foo/baz.js // | /myapp/js/foo/thud/xyzzy.js // Your application can tell Dojo to locate the "foo" namespace by calling: // | dojo.registerModulePath("foo", "../../foo"); // At which point you can then use dojo.require() to load the // modules (assuming they provide() the same things which are // required). The full code might be: // | <script type="text/javascript" // | src="/myapp/js/dojo/dojo/dojo.js"></script> // | <script type="text/javascript"> // | dojo.registerModulePath("foo", "../../foo"); // | dojo.require("foo.bar"); // | dojo.require("foo.baz"); // | dojo.require("foo.thud.xyzzy"); // | </script> var paths = {}; paths[moduleName.replace(/\./g, "/")] = prefix; require({paths:paths}); }; dojo.platformRequire = function(/*Object*/modMap){ // summary: // require one or more modules based on which host environment // Dojo is currently operating in // description: // This method takes a "map" of arrays which one can use to // optionally load dojo modules. The map is indexed by the // possible dojo.name_ values, with two additional values: // "default" and "common". The items in the "default" array will // be loaded if none of the other items have been chosen based on // dojo.name_, set by your host environment. The items in the // "common" array will *always* be loaded, regardless of which // list is chosen. // example: // | dojo.platformRequire({ // | browser: [ // | "foo.sample", // simple module // | "foo.test", // | ["foo.bar.baz", true] // skip object check in _loadModule (dojo.require) // | ], // | default: [ "foo.sample._base" ], // | common: [ "important.module.common" ] // | }); var result = (modMap.common || []).concat(modMap[dojo._name] || modMap["default"] || []), temp; while(result.length){ if(lang.isArray(temp = result.shift())){ dojo.require.apply(dojo, temp); }else{ dojo.require(temp); } } }; dojo.requireIf = dojo.requireAfterIf = function(/*Boolean*/ condition, /*String*/ moduleName, /*Boolean?*/omitModuleCheck){ // summary: // If the condition is true then call `dojo.require()` for the specified // resource // // example: // | dojo.requireIf(dojo.isBrowser, "my.special.Module"); if(condition){ dojo.require(moduleName, omitModuleCheck); } }; dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale){ require(["../i18n"], function(i18n){ i18n.getLocalization(moduleName, bundleName, locale); }); }; return { // summary: // This module defines the v1.x synchronous loader API. extractLegacyApiApplications:extractLegacyApiApplications, require:dojoRequirePlugin, loadInit:dojoLoadInitPlugin }; });