]> git.wh0rd.org Git - tt-rss.git/blob - lib/dojo/_base/loader.js.uncompressed.js
update dojo to 1.7.3
[tt-rss.git] / lib / dojo / _base / loader.js.uncompressed.js
1 define("dojo/_base/loader", ["./kernel", "../has", "require", "module", "./json", "./lang", "./array"], function(dojo, has, require, thisModule, json, lang, array) {
2         // module:
3         //              dojo/_base/lader
4         // summary:
5         //              This module defines the v1.x synchronous loader API.
6
7         // signal the loader in sync mode...
8         //>>pure-amd
9
10         if (!1){
11                 console.error("cannot load the Dojo v1.x loader with a foreign loader");
12                 return 0;
13         }
14
15         var makeErrorToken = function(id){
16                         return {src:thisModule.id, id:id};
17                 },
18
19                 slashName = function(name){
20                         return name.replace(/\./g, "/");
21                 },
22
23                 buildDetectRe = /\/\/>>built/,
24
25                 dojoRequireCallbacks = [],
26                 dojoRequireModuleStack = [],
27
28                 dojoRequirePlugin = function(mid, require, loaded){
29                         dojoRequireCallbacks.push(loaded);
30                         array.forEach(mid.split(","), function(mid){
31                                 var module = getModule(mid, require.module);
32                                 dojoRequireModuleStack.push(module);
33                                 injectModule(module);
34                         });
35                         checkDojoRequirePlugin();
36                 },
37
38                 // checkDojoRequirePlugin inspects all of the modules demanded by a dojo/require!<module-list> dependency
39                 // to see if they have arrived. The loader does not release *any* of these modules to be instantiated
40                 // until *all* of these modules are on board, thereby preventing the evaluation of a module with dojo.require's
41                 // that reference modules that are not available.
42                 //
43                 // The algorithm works by traversing the dependency graphs (remember, there can be cycles so they are not trees)
44                 // of each module in the dojoRequireModuleStack array (which contains the list of modules demanded by dojo/require!).
45                 // The moment a single module is discovered that is missing, the algorithm gives up and indicates that not all
46                 // modules are on board. dojo/loadInit! and dojo/require! are ignored because there dependencies are inserted
47                 // directly in dojoRequireModuleStack. For example, if "your/module" module depends on "dojo/require!my/module", then
48                 // *both* "dojo/require!my/module" and "my/module" will be in dojoRequireModuleStack. Obviously, if "my/module"
49                 // is on board, then "dojo/require!my/module" is also satisfied, so the algorithm doesn't check for "dojo/require!my/module".
50                 //
51                 // Note: inserting a dojo/require!<some-module-list> dependency in the dojoRequireModuleStack achieves nothing
52                 // with the current algorithm; however, having such modules present makes it possible to optimize the algorithm
53                 //
54                 // Note: prior versions of this algorithm had an optimization that signaled loaded on dojo/require! dependencies
55                 // individually (rather than waiting for them all to be resolved). The implementation proved problematic with cycles
56                 // and plugins. However, it is possible to reattach that strategy in the future.
57
58                 // a set from module-id to {undefined | 1 | 0}, where...
59                 //   undefined => the module has not been inspected
60                 //   0 => the module or at least one of its dependencies has not arrived
61                 //   1 => the module is a loadInit! or require! plugin resource, or is currently being traversed (therefore, assume
62                 //        OK until proven otherwise), or has been completely traversed and all dependencies have arrived
63                 touched,
64
65                 traverse = function(m){
66                     touched[m.mid] = 1;
67                         for(var t, module, deps = m.deps || [], i= 0; i<deps.length; i++){
68                                 module = deps[i];
69                                 if(!(t = touched[module.mid])){
70                                         if(t===0 || !traverse(module)){
71                                                 touched[m.mid] = 0;
72                                                 return false;
73                                         }
74                                 }
75                         }
76                         return true;
77                 },
78
79                 checkDojoRequirePlugin = function(){
80                         // initialize the touched hash with easy-to-compute values that help short circuit recursive algorithm;
81                         // recall loadInit/require plugin modules are dependencies of modules in dojoRequireModuleStack...
82                         // which would cause a circular dependency chain that would never be resolved if checked here
83                         // notice all dependencies of any particular loadInit/require plugin module will already
84                         // be checked since those are pushed into dojoRequireModuleStack explicitly by the
85                         // plugin...so if a particular loadInitPlugin module's dependencies are not really
86                         // on board, that *will* be detected elsewhere in the traversal.
87                         var module, mid;
88                         touched = {};
89                         for(mid in modules){
90                                 module = modules[mid];
91                                 // this could be improved by remembering the result of the regex tests
92                                 if(module.executed || module.noReqPluginCheck){
93                                         touched[mid] = 1;
94                                 }else{
95                                         if(module.noReqPluginCheck!==0){
96                                                 // tag the module as either a loadInit or require plugin or not for future reference
97                                                 module.noReqPluginCheck = /loadInit\!/.test(mid) || /require\!/.test(mid) ? 1 : 0;
98                                         }
99                                         if(module.noReqPluginCheck){
100                                                 touched[mid] = 1;
101                                         }else if(module.injected!==arrived){
102                                                 // not executed, has not arrived, and is not a loadInit or require plugin resource
103                                                 touched[mid] = 0;
104                                         }// else, leave undefined and we'll traverse the dependencies
105                                 }
106                         }
107
108                         for(var t, i = 0, end = dojoRequireModuleStack.length; i<end; i++){
109                                 module = dojoRequireModuleStack[i];
110                                 if(!(t = touched[module.mid])){
111                                         if(t===0 || !traverse(module)){
112                                                 return;
113                                         }
114                                 }
115                         }
116                         loaderVars.holdIdle();
117                         var oldCallbacks = dojoRequireCallbacks;
118                         dojoRequireCallbacks = [];
119                         array.forEach(oldCallbacks, function(cb){cb(1);});
120                         loaderVars.releaseIdle();
121                 },
122
123                 dojoLoadInitPlugin = function(mid, require, loaded){
124                         // mid names a module that defines a "dojo load init" bundle, an object with two properties:
125                         //
126                         //   * names: a vector of module ids that give top-level names to define in the lexical scope of def
127                         //   * def: a function that contains some some legacy loader API applications
128                         //
129                         // The point of def is to possibly cause some modules to be loaded (but not executed) by dojo/require! where the module
130                         // ids are possibly-determined at runtime. For example, here is dojox.gfx from v1.6 expressed as an AMD module using the dojo/loadInit
131                         // and dojo/require plugins.
132                         //
133                         // // dojox/gfx:
134                         //
135                         //   define("*loadInit_12, {
136                         //     names:["dojo", "dijit", "dojox"],
137                         //     def: function(){
138                         //       dojo.loadInit(function(){
139                         //         var gfx = lang.getObject("dojox.gfx", true);
140                         //
141                         //         //
142                         //         // code required to set gfx properties ommitted...
143                         //         //
144                         //
145                         //         // now use the calculations to include the runtime-dependent module
146                         //         dojo.require("dojox.gfx." + gfx.renderer);
147                         //       });
148                         //         }
149                         //   });
150                         //
151                         //   define(["dojo", "dojo/loadInit!" + id].concat("dojo/require!dojox/gfx/matric,dojox/gfx/_base"), function(dojo){
152                         //     // when this AMD factory function is executed, the following modules are guaranteed downloaded but not executed:
153                         //     //   "dojox.gfx." + gfx.renderer
154                         //     //   dojox.gfx.matrix
155                         //     //   dojox.gfx._base
156                         //     dojo.provide("dojo.gfx");
157                         //     dojo.require("dojox.gfx.matrix");
158                         //     dojo.require("dojox.gfx._base");
159                         //     dojo.require("dojox.gfx." + gfx.renderer);
160                         //     return lang.getObject("dojo.gfx");
161                         //   });
162                         //  })();
163                         //
164                         // The idea is to run the legacy loader API with global variables shadowed, which allows these variables to
165                         // be relocated. For example, dojox and dojo could be relocated to different names by giving a packageMap and the code above will
166                         // execute properly (because the plugin below resolves the load init bundle.names module with respect to the module that demanded
167                         // the plugin resource).
168                         //
169                         // Note that the relocation is specified in the runtime configuration; relocated names need not be set at build-time.
170                         //
171                         // Warning: this is not the best way to express dojox.gfx as and AMD module. In fact, the module has been properly converted in
172                         // v1.7. However, this technique allows the builder to convert legacy modules into AMD modules and guarantee the codepath is the
173                         // same in the converted AMD module.
174                         require([mid], function(bundle){
175                                 // notice how names is resolved with respect to the module that demanded the plugin resource
176                                 require(bundle.names, function(){
177                                         // bring the bundle names into scope
178                                         for(var scopeText = "", args= [], i = 0; i<arguments.length; i++){
179                                                 scopeText+= "var " + bundle.names[i] + "= arguments[" + i + "]; ";
180                                                 args.push(arguments[i]);
181                                         }
182                                         eval(scopeText);
183
184                                         var callingModule = require.module,
185                                                 deps = [],
186                                                 hold = {},
187                                                 requireList = [],
188                                                 p,
189                                                 syncLoaderApi = {
190                                                         provide:function(moduleName){
191                                                                 // mark modules that arrive consequent to multiple provides in this module as arrived since they can't be injected
192                                                                 moduleName = slashName(moduleName);
193                                                                 var providedModule = getModule(moduleName, callingModule);
194                                                                 if(providedModule!==callingModule){
195                                                                         setArrived(providedModule);
196                                                                 }
197                                                         },
198                                                         require:function(moduleName, omitModuleCheck){
199                                                                 moduleName = slashName(moduleName);
200                                                                 omitModuleCheck && (getModule(moduleName, callingModule).result = nonmodule);
201                                                                 requireList.push(moduleName);
202                                                         },
203                                                         requireLocalization:function(moduleName, bundleName, locale){
204                                                                 // since we're going to need dojo/i8n, add it to deps if not already there
205                                                                 deps.length || (deps = ["dojo/i18n"]);
206
207                                                                 // figure out if the bundle is xdomain; if so, add it to the depsSet
208                                                                 locale = (locale || dojo.locale).toLowerCase();
209                                                                 moduleName = slashName(moduleName) + "/nls/" + (/root/i.test(locale) ? "" : locale + "/") + slashName(bundleName);
210                                                                 if(getModule(moduleName, callingModule).isXd){
211                                                                         deps.push("dojo/i18n!" + moduleName);
212                                                                 }// else the bundle will be loaded synchronously when the module is evaluated
213                                                         },
214                                                         loadInit:function(f){
215                                                                 f();
216                                                         }
217                                                 };
218
219                                         // hijack the correct dojo and apply bundle.def
220                                         try{
221                                                 for(p in syncLoaderApi){
222                                                         hold[p] = dojo[p];
223                                                         dojo[p] = syncLoaderApi[p];
224                                                 }
225                                                 bundle.def.apply(null, args);
226                                         }catch(e){
227                                                 signal("error", [makeErrorToken("failedDojoLoadInit"), e]);
228                                         }finally{
229                                                 for(p in syncLoaderApi){
230                                                         dojo[p] = hold[p];
231                                                 }
232                                         }
233
234                                         // requireList is the list of modules that need to be downloaded but not executed before the callingModule can be executed
235                                         requireList.length && deps.push("dojo/require!" + requireList.join(","));
236
237                                         dojoRequireCallbacks.push(loaded);
238                                         array.forEach(requireList, function(mid){
239                                                 var module = getModule(mid, require.module);
240                                                 dojoRequireModuleStack.push(module);
241                                                 injectModule(module);
242                                         });
243                                         checkDojoRequirePlugin();
244                                 });
245                         });
246                 },
247
248                 extractApplication = function(
249                         text,             // the text to search
250                         startSearch,      // the position in text to start looking for the closing paren
251                         startApplication  // the position in text where the function application expression starts
252                 ){
253                         // find end of the call by finding the matching end paren
254                         // Warning: as usual, this will fail in the presense of unmatched right parans contained in strings, regexs, or unremoved comments
255                         var parenRe = /\(|\)/g,
256                                 matchCount = 1,
257                                 match;
258                         parenRe.lastIndex = startSearch;
259                         while((match = parenRe.exec(text))){
260                                 if(match[0] == ")"){
261                                         matchCount -= 1;
262                                 }else{
263                                         matchCount += 1;
264                                 }
265                                 if(matchCount == 0){
266                                         break;
267                                 }
268                         }
269
270                         if(matchCount != 0){
271                                 throw "unmatched paren around character " + parenRe.lastIndex + " in: " + text;
272                         }
273
274                         //Put the master matching string in the results.
275                         return [dojo.trim(text.substring(startApplication, parenRe.lastIndex))+";\n", parenRe.lastIndex];
276                 },
277
278                 // the following regex is taken from 1.6. It is a very poor technique to remove comments and
279                 // will fail in some cases; for example, consider the code...
280                 //
281                 //    var message = "Category-1 */* Category-2";
282                 //
283                 // The regex that follows will see a /* comment and trash the code accordingly. In fact, there are all
284                 // kinds of cases like this with strings and regexs that will cause this design to fail miserably.
285                 //
286                 // Alternative regex designs exist that will result in less-likely failures, but will still fail in many cases.
287                 // The only solution guaranteed 100% correct is to parse the code and that seems overkill for this
288                 // backcompat/unbuilt-xdomain layer. In the end, since it's been this way for a while, we won't change it.
289                 // See the opening paragraphs of Chapter 7 or ECME-262 which describes the lexical abiguity further.
290                 removeCommentRe = /(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg,
291
292                 syncLoaderApiRe = /(^|\s)dojo\.(loadInit|require|provide|requireLocalization|requireIf|requireAfterIf|platformRequire)\s*\(/mg,
293
294                 amdLoaderApiRe = /(^|\s)(require|define)\s*\(/m,
295
296                 extractLegacyApiApplications = function(text, noCommentText){
297                         // scan the noCommentText for any legacy loader API applications. Copy such applications into result (this is
298                         // used by the builder). Move dojo.loadInit applications to loadInitApplications string. Copy all other applications
299                         // to otherApplications string. If no applications were found, return 0, signalling an AMD module. Otherwise, return
300                         // loadInitApplications + otherApplications. Fixup text by replacing
301                         //
302                         //   dojo.loadInit(// etc...
303                         //
304                         // with
305                         //
306                         //   \n 0 && dojo.loadInit(// etc...
307                         //
308                         // Which results in the dojo.loadInit from *not* being applied. This design goes a long way towards protecting the
309                         // code from an over-agressive removeCommentRe. However...
310                         //
311                         // WARNING: the removeCommentRe will cause an error if a detected comment removes all or part of a legacy-loader application
312                         // that is not in a comment.
313
314                         var match, startSearch, startApplication, application,
315                                 loadInitApplications = [],
316                                 otherApplications = [],
317                                 allApplications = [];
318
319                         // noCommentText may be provided by a build app with comments extracted by a better method than regex (hopefully)
320                         noCommentText = noCommentText || text.replace(removeCommentRe, function(match){
321                                 // remove iff the detected comment has text that looks like a sync loader API application; this helps by
322                                 // removing as little as possible, minimizing the changes the janky regex will kill the module
323                                 syncLoaderApiRe.lastIndex = amdLoaderApiRe.lastIndex = 0;
324                                 return (syncLoaderApiRe.test(match) || amdLoaderApiRe.test(match)) ? "" : match;
325                         });
326
327                         // find and extract all dojo.loadInit applications
328                         while((match = syncLoaderApiRe.exec(noCommentText))){
329                                 startSearch = syncLoaderApiRe.lastIndex;
330                                 startApplication = startSearch  - match[0].length;
331                                 application = extractApplication(noCommentText, startSearch, startApplication);
332                                 if(match[2]=="loadInit"){
333                                         loadInitApplications.push(application[0]);
334                                 }else{
335                                         otherApplications.push(application[0]);
336                                 }
337                                 syncLoaderApiRe.lastIndex = application[1];
338                         }
339                         allApplications = loadInitApplications.concat(otherApplications);
340                         if(allApplications.length || !amdLoaderApiRe.test(noCommentText)){
341                                 // either there were some legacy loader API applications or there were no AMD API applications
342                                 return [text.replace(/(^|\s)dojo\.loadInit\s*\(/g, "\n0 && dojo.loadInit("), allApplications.join(""), allApplications];
343                         }else{
344                                 // legacy loader API *was not* detected and AMD API *was* detected; therefore, assume it's an AMD module
345                                 return 0;
346                         }
347                 },
348
349                 transformToAmd = function(module, text){
350                         // This is roughly the equivalent of dojo._xdCreateResource in 1.6-; however, it expresses a v1.6- dojo
351                         // module in terms of AMD define instead of creating the dojo proprietary xdomain module expression.
352                         // The module could have originated from several sources:
353                         //
354                         //   * amd require() a module, e.g., require(["my/module"])
355                         //   * amd require() a nonmodule, e.g., require(["my/resource.js"')
356                         //   * amd define() deps vector (always a module)
357                         //   * dojo.require() a module, e.g. dojo.require("my.module")
358                         //   * dojo.require() a nonmodule, e.g., dojo.require("my.module", true)
359                         //   * dojo.requireIf/requireAfterIf/platformRequire a module
360                         //
361                         // The module is scanned for legacy loader API applications; if none are found, then assume the module is an
362                         // AMD module and return 0. Otherwise, a synthetic dojo/loadInit plugin resource is created and the module text
363                         // is rewritten as an AMD module with the single dependency of this synthetic resource. When the dojo/loadInit
364                         // plugin loaded the synthetic resource, it will cause all dojo.loadInit's to be executed, find all dojo.require's
365                         // (either directly consequent to dojo.require or indirectly consequent to dojo.require[After]If or
366                         // dojo.platformRequire, and finally cause loading of all dojo.required modules with the dojo/require plugin. Thus,
367                         // when the dojo/loadInit plugin reports it has been loaded, all modules required by the given module are guaranteed
368                         // loaded (but not executed). This then allows the module to execute it's code path without interupts, thereby
369                         // following the synchronous code path.
370
371                         var extractResult, id, names = [], namesAsStrings = [];
372                         if(buildDetectRe.test(text) || !(extractResult = extractLegacyApiApplications(text))){
373                                 // buildDetectRe.test(text) => a built module, always AMD
374                                 // extractResult==0 => no sync API
375                                 return 0;
376                         }
377
378                         // manufacture a synthetic module id that can never be a real mdule id (just like require does)
379                         id = module.mid + "-*loadInit";
380
381                         // construct the dojo/loadInit names vector which causes any relocated names to be defined as lexical variables under their not-relocated name
382                         // the dojo/loadInit plugin assumes the first name in names is "dojo"
383
384                         for(var p in getModule("dojo", module).result.scopeMap){
385                                 names.push(p);
386                                 namesAsStrings.push('"' + p + '"');
387                         }
388
389                         // rewrite the module as a synthetic dojo/loadInit plugin resource + the module expressed as an AMD module that depends on this synthetic resource
390                         return "// xdomain rewrite of " + module.path + "\n" +
391                                 "define('" + id + "',{\n" +
392                                 "\tnames:" + dojo.toJson(names) + ",\n" +
393                                 "\tdef:function(" + names.join(",") + "){" + extractResult[1] + "}" +
394                                 "});\n\n" +
395                             "define(" + dojo.toJson(names.concat(["dojo/loadInit!"+id])) + ", function(" + names.join(",") + "){\n" + extractResult[0] + "});";
396                 },
397
398                 loaderVars = require.initSyncLoader(dojoRequirePlugin, checkDojoRequirePlugin, transformToAmd),
399
400                 sync =
401                         loaderVars.sync,
402
403                 xd =
404                         loaderVars.xd,
405
406                 arrived =
407                         loaderVars.arrived,
408
409                 nonmodule =
410                         loaderVars.nonmodule,
411
412                 executing =
413                         loaderVars.executing,
414
415                 executed =
416                         loaderVars.executed,
417
418                 syncExecStack =
419                         loaderVars.syncExecStack,
420
421                 modules =
422                         loaderVars.modules,
423
424                 execQ =
425                         loaderVars.execQ,
426
427                 getModule =
428                         loaderVars.getModule,
429
430                 injectModule =
431                         loaderVars.injectModule,
432
433                 setArrived =
434                         loaderVars.setArrived,
435
436                 signal =
437                         loaderVars.signal,
438
439                 finishExec =
440                         loaderVars.finishExec,
441
442                 execModule =
443                         loaderVars.execModule,
444
445                 getLegacyMode =
446                         loaderVars.getLegacyMode;
447
448         dojo.provide = function(mid){
449                 var executingModule = syncExecStack[0],
450                         module = lang.mixin(getModule(slashName(mid), require.module), {
451                                 executed:executing,
452                                 result:lang.getObject(mid, true)
453                         });
454                 setArrived(module);
455                 if(executingModule){
456                         (executingModule.provides || (executingModule.provides = [])).push(function(){
457                                 module.result = lang.getObject(mid);
458                                 delete module.provides;
459                                 module.executed!==executed && finishExec(module);
460                         });
461                 }// else dojo.provide called not consequent to loading; therefore, give up trying to publish module value to loader namespace
462                 return module.result;
463         };
464
465         has.add("config-publishRequireResult", 1, 0, 0);
466
467         dojo.require = function(moduleName, omitModuleCheck) {
468                 //      summary:
469                 //              loads a Javascript module from the appropriate URI
470                 //
471                 //      moduleName: String
472                 //              module name to load, using periods for separators,
473                 //               e.g. "dojo.date.locale".  Module paths are de-referenced by dojo's
474                 //              internal mapping of locations to names and are disambiguated by
475                 //              longest prefix. See `dojo.registerModulePath()` for details on
476                 //              registering new modules.
477                 //
478                 //      omitModuleCheck: Boolean?
479                 //              if `true`, omitModuleCheck skips the step of ensuring that the
480                 //              loaded file actually defines the symbol it is referenced by.
481                 //              For example if it called as `dojo.require("a.b.c")` and the
482                 //              file located at `a/b/c.js` does not define an object `a.b.c`,
483                 //              and exception will be throws whereas no exception is raised
484                 //              when called as `dojo.require("a.b.c", true)`
485                 //
486                 //      description:
487                 //              Modules are loaded via dojo.require by using one of two loaders: the normal loader
488                 //              and the xdomain loader. The xdomain loader is used when dojo was built with a
489                 //              custom build that specified loader=xdomain and the module lives on a modulePath
490                 //              that is a whole URL, with protocol and a domain. The versions of Dojo that are on
491                 //              the Google and AOL CDNs use the xdomain loader.
492                 //
493                 //              If the module is loaded via the xdomain loader, it is an asynchronous load, since
494                 //              the module is added via a dynamically created script tag. This
495                 //              means that dojo.require() can return before the module has loaded. However, this
496                 //              should only happen in the case where you do dojo.require calls in the top-level
497                 //              HTML page, or if you purposely avoid the loader checking for dojo.require
498                 //              dependencies in your module by using a syntax like dojo["require"] to load the module.
499                 //
500                 //              Sometimes it is useful to not have the loader detect the dojo.require calls in the
501                 //              module so that you can dynamically load the modules as a result of an action on the
502                 //              page, instead of right at module load time.
503                 //
504                 //              Also, for script blocks in an HTML page, the loader does not pre-process them, so
505                 //              it does not know to download the modules before the dojo.require calls occur.
506                 //
507                 //              So, in those two cases, when you want on-the-fly module loading or for script blocks
508                 //              in the HTML page, special care must be taken if the dojo.required code is loaded
509                 //              asynchronously. To make sure you can execute code that depends on the dojo.required
510                 //              modules, be sure to add the code that depends on the modules in a dojo.addOnLoad()
511                 //              callback. dojo.addOnLoad waits for all outstanding modules to finish loading before
512                 //              executing.
513                 //
514                 //              This type of syntax works with both xdomain and normal loaders, so it is good
515                 //              practice to always use this idiom for on-the-fly code loading and in HTML script
516                 //              blocks. If at some point you change loaders and where the code is loaded from,
517                 //              it will all still work.
518                 //
519                 //              More on how dojo.require
520                 //              `dojo.require("A.B")` first checks to see if symbol A.B is
521                 //              defined. If it is, it is simply returned (nothing to do).
522                 //
523                 //              If it is not defined, it will look for `A/B.js` in the script root
524                 //              directory.
525                 //
526                 //              `dojo.require` throws an exception if it cannot find a file
527                 //              to load, or if the symbol `A.B` is not defined after loading.
528                 //
529                 //              It returns the object `A.B`, but note the caveats above about on-the-fly loading and
530                 //              HTML script blocks when the xdomain loader is loading a module.
531                 //
532                 //              `dojo.require()` does nothing about importing symbols into
533                 //              the current namespace.  It is presumed that the caller will
534                 //              take care of that.
535                 //
536                 //      example:
537                 //              To use dojo.require in conjunction with dojo.ready:
538                 //
539                 //              |       dojo.require("foo");
540                 //              |       dojo.require("bar");
541                 //              |       dojo.addOnLoad(function(){
542                 //              |               //you can now safely do something with foo and bar
543                 //              |       });
544                 //
545                 //      example:
546                 //              For example, to import all symbols into a local block, you might write:
547                 //
548                 //              |       with (dojo.require("A.B")) {
549                 //              |               ...
550                 //              |       }
551                 //
552                 //              And to import just the leaf symbol to a local variable:
553                 //
554                 //              |       var B = dojo.require("A.B");
555                 //              |       ...
556                 //
557                 //      returns:
558                 //              the required namespace object
559                 function doRequire(mid, omitModuleCheck){
560                         var module = getModule(slashName(mid), require.module);
561                         if(syncExecStack.length && syncExecStack[0].finish){
562                                 // switched to async loading in the middle of evaluating a legacy module; stop
563                                 // applying dojo.require so the remaining dojo.requires are applied in order
564                                 syncExecStack[0].finish.push(mid);
565                                 return undefined;
566                         }
567
568                         // recall module.executed has values {0, executing, executed}; therefore, truthy indicates executing or executed
569                         if(module.executed){
570                                 return module.result;
571                         }
572                         omitModuleCheck && (module.result = nonmodule);
573
574                         var currentMode = getLegacyMode();
575
576                         // recall, in sync mode to inject is to *eval* the module text
577                         // if the module is a legacy module, this is the same as executing
578                         // but if the module is an AMD module, this means defining, not executing
579                         injectModule(module);
580                         // the inject may have changed the mode
581                         currentMode = getLegacyMode();
582
583                         // in sync mode to dojo.require is to execute
584                         if(module.executed!==executed && module.injected===arrived){
585                                 // the module was already here before injectModule was called probably finishing up a xdomain
586                                 // load, but maybe a module given to the loader directly rather than having the loader retrieve it
587                                 loaderVars.holdIdle();
588                                 execModule(module);
589                                 loaderVars.releaseIdle();
590                         }
591                         if(module.executed){
592                                 return module.result;
593                         }
594
595                         if(currentMode==sync){
596                                 // the only way to get here is in sync mode and dojo.required a module that
597                                 //   * was loaded async in the injectModule application a few lines up
598                                 //   * was an AMD module that had deps that are being loaded async and therefore couldn't execute
599                                 if(module.cjs){
600                                         // the module was an AMD module; unshift, not push, which causes the current traversal to be reattempted from the top
601                                         execQ.unshift(module);
602                                 }else{
603                                         // the module was a legacy module
604                                         syncExecStack.length && (syncExecStack[0].finish= [mid]);
605                                 }
606                         }else{
607                                 // the loader wasn't in sync mode on entry; probably async mode; therefore, no expectation of getting
608                                 // the module value synchronously; make sure it gets executed though
609                                 execQ.push(module);
610                         }
611                         return undefined;
612                 }
613
614                 var result = doRequire(moduleName, omitModuleCheck);
615                 if(has("config-publishRequireResult") && !lang.exists(moduleName) && result!==undefined){
616                         lang.setObject(moduleName, result);
617                 }
618                 return result;
619         };
620
621         dojo.loadInit = function(f) {
622                 f();
623         };
624
625         dojo.registerModulePath = function(/*String*/moduleName, /*String*/prefix){
626                 //      summary:
627                 //              Maps a module name to a path
628                 //      description:
629                 //              An unregistered module is given the default path of ../[module],
630                 //              relative to Dojo root. For example, module acme is mapped to
631                 //              ../acme.  If you want to use a different module name, use
632                 //              dojo.registerModulePath.
633                 //      example:
634                 //              If your dojo.js is located at this location in the web root:
635                 //      |       /myapp/js/dojo/dojo/dojo.js
636                 //              and your modules are located at:
637                 //      |       /myapp/js/foo/bar.js
638                 //      |       /myapp/js/foo/baz.js
639                 //      |       /myapp/js/foo/thud/xyzzy.js
640                 //              Your application can tell Dojo to locate the "foo" namespace by calling:
641                 //      |       dojo.registerModulePath("foo", "../../foo");
642                 //              At which point you can then use dojo.require() to load the
643                 //              modules (assuming they provide() the same things which are
644                 //              required). The full code might be:
645                 //      |       <script type="text/javascript"
646                 //      |               src="/myapp/js/dojo/dojo/dojo.js"></script>
647                 //      |       <script type="text/javascript">
648                 //      |               dojo.registerModulePath("foo", "../../foo");
649                 //      |               dojo.require("foo.bar");
650                 //      |               dojo.require("foo.baz");
651                 //      |               dojo.require("foo.thud.xyzzy");
652                 //      |       </script>
653
654                 var paths = {};
655                 paths[moduleName.replace(/\./g, "/")] = prefix;
656                 require({paths:paths});
657         };
658
659         dojo.platformRequire = function(/*Object*/modMap){
660                 //      summary:
661                 //              require one or more modules based on which host environment
662                 //              Dojo is currently operating in
663                 //      description:
664                 //              This method takes a "map" of arrays which one can use to
665                 //              optionally load dojo modules. The map is indexed by the
666                 //              possible dojo.name_ values, with two additional values:
667                 //              "default" and "common". The items in the "default" array will
668                 //              be loaded if none of the other items have been choosen based on
669                 //              dojo.name_, set by your host environment. The items in the
670                 //              "common" array will *always* be loaded, regardless of which
671                 //              list is chosen.
672                 //      example:
673                 //              |       dojo.platformRequire({
674                 //              |               browser: [
675                 //              |                       "foo.sample", // simple module
676                 //              |                       "foo.test",
677                 //              |                       ["foo.bar.baz", true] // skip object check in _loadModule (dojo.require)
678                 //              |               ],
679                 //              |               default: [ "foo.sample._base" ],
680                 //              |               common: [ "important.module.common" ]
681                 //              |       });
682
683                 var result = (modMap.common || []).concat(modMap[dojo._name] || modMap["default"] || []),
684                         temp;
685                 while(result.length){
686                         if(lang.isArray(temp = result.shift())){
687                                 dojo.require.apply(dojo, temp);
688                         }else{
689                                 dojo.require(temp);
690                         }
691                 }
692         };
693
694         dojo.requireIf = dojo.requireAfterIf = function(/*Boolean*/ condition, /*String*/ moduleName, /*Boolean?*/omitModuleCheck){
695                 // summary:
696                 //              If the condition is true then call `dojo.require()` for the specified
697                 //              resource
698                 //
699                 // example:
700                 //      |       dojo.requireIf(dojo.isBrowser, "my.special.Module");
701
702                 if(condition){
703                         dojo.require(moduleName, omitModuleCheck);
704                 }
705         };
706
707         dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale){
708                 require(["../i18n"], function(i18n){
709                         i18n.getLocalization(moduleName, bundleName, locale);
710                 });
711         };
712
713         return {
714                 extractLegacyApiApplications:extractLegacyApiApplications,
715                 require:loaderVars.dojoRequirePlugin,
716                 loadInit:dojoLoadInitPlugin
717         };
718 });