source: Dev/branches/rest-dojo-ui/client/dojo/_base/loader.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

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