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