]>
Commit | Line | Data |
---|---|---|
2f01fe57 | 1 | /* |
81bea17a | 2 | Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved. |
2f01fe57 AD |
3 | Available via Academic Free License >= 2.1 OR the modified BSD license. |
4 | see: http://dojotoolkit.org/license for details | |
5 | */ | |
6 | ||
7 | ||
a089699c AD |
8 | if(!dojo._hasResource["dojo.foo"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
9 | dojo._hasResource["dojo.foo"] = true; | |
10 | /* | |
11 | * loader.js - A bootstrap module. Runs before the hostenv_*.js file. Contains | |
12 | * all of the package loading methods. | |
13 | */ | |
2f01fe57 | 14 | (function(){ |
81bea17a | 15 | var d = dojo, currentModule; |
a089699c AD |
16 | |
17 | d.mixin(d, { | |
18 | _loadedModules: {}, | |
19 | _inFlightCount: 0, | |
20 | _hasResource: {}, | |
21 | ||
22 | _modulePrefixes: { | |
23 | dojo: { name: "dojo", value: "." }, | |
24 | // dojox: { name: "dojox", value: "../dojox" }, | |
25 | // dijit: { name: "dijit", value: "../dijit" }, | |
26 | doh: { name: "doh", value: "../util/doh" }, | |
27 | tests: { name: "tests", value: "tests" } | |
28 | }, | |
29 | ||
30 | _moduleHasPrefix: function(/*String*/module){ | |
31 | // summary: checks to see if module has been established | |
32 | var mp = d._modulePrefixes; | |
33 | return !!(mp[module] && mp[module].value); // Boolean | |
34 | }, | |
35 | ||
36 | _getModulePrefix: function(/*String*/module){ | |
37 | // summary: gets the prefix associated with module | |
38 | var mp = d._modulePrefixes; | |
39 | if(d._moduleHasPrefix(module)){ | |
40 | return mp[module].value; // String | |
41 | } | |
42 | return module; // String | |
43 | }, | |
44 | ||
45 | _loadedUrls: [], | |
46 | ||
81bea17a | 47 | //WARNING: |
a089699c AD |
48 | // This variable is referenced by packages outside of bootstrap: |
49 | // FloatingPane.js and undo/browser.js | |
50 | _postLoad: false, | |
81bea17a | 51 | |
a089699c AD |
52 | //Egad! Lots of test files push on this directly instead of using dojo.addOnLoad. |
53 | _loaders: [], | |
54 | _unloaders: [], | |
55 | _loadNotifying: false | |
56 | }); | |
57 | ||
58 | ||
59 | dojo._loadPath = function(/*String*/relpath, /*String?*/module, /*Function?*/cb){ | |
60 | // summary: | |
61 | // Load a Javascript module given a relative path | |
62 | // | |
63 | // description: | |
64 | // Loads and interprets the script located at relpath, which is | |
65 | // relative to the script root directory. If the script is found but | |
66 | // its interpretation causes a runtime exception, that exception is | |
67 | // not caught by us, so the caller will see it. We return a true | |
68 | // value if and only if the script is found. | |
69 | // | |
81bea17a | 70 | // relpath: |
a089699c AD |
71 | // A relative path to a script (no leading '/', and typically ending |
72 | // in '.js'). | |
81bea17a | 73 | // module: |
a089699c AD |
74 | // A module whose existance to check for after loading a path. Can be |
75 | // used to determine success or failure of the load. | |
81bea17a | 76 | // cb: |
a089699c AD |
77 | // a callback function to pass the result of evaluating the script |
78 | ||
79 | var uri = ((relpath.charAt(0) == '/' || relpath.match(/^\w+:/)) ? "" : d.baseUrl) + relpath; | |
80 | try{ | |
81bea17a | 81 | currentModule = module; |
a089699c AD |
82 | return !module ? d._loadUri(uri, cb) : d._loadUriAndCheck(uri, module, cb); // Boolean |
83 | }catch(e){ | |
84 | console.error(e); | |
85 | return false; // Boolean | |
81bea17a AD |
86 | }finally{ |
87 | currentModule = null; | |
a089699c AD |
88 | } |
89 | } | |
90 | ||
91 | dojo._loadUri = function(/*String*/uri, /*Function?*/cb){ | |
92 | // summary: | |
93 | // Loads JavaScript from a URI | |
94 | // description: | |
95 | // Reads the contents of the URI, and evaluates the contents. This is | |
96 | // used to load modules as well as resource bundles. Returns true if | |
97 | // it succeeded. Returns false if the URI reading failed. Throws if | |
98 | // the evaluation throws. | |
99 | // uri: a uri which points at the script to be loaded | |
81bea17a | 100 | // cb: |
a089699c AD |
101 | // a callback function to process the result of evaluating the script |
102 | // as an expression, typically used by the resource bundle loader to | |
103 | // load JSON-style resources | |
104 | ||
105 | if(d._loadedUrls[uri]){ | |
106 | return true; // Boolean | |
107 | } | |
108 | d._inFlightCount++; // block addOnLoad calls that arrive while we're busy downloading | |
109 | var contents = d._getText(uri, true); | |
110 | if(contents){ // not 404, et al | |
111 | d._loadedUrls[uri] = true; | |
112 | d._loadedUrls.push(uri); | |
113 | if(cb){ | |
81bea17a AD |
114 | //conditional to support script-inject i18n bundle format |
115 | contents = /^define\(/.test(contents) ? contents : '('+contents+')'; | |
a089699c AD |
116 | }else{ |
117 | //Only do the scoping if no callback. If a callback is specified, | |
118 | //it is most likely the i18n bundle stuff. | |
119 | contents = d._scopePrefix + contents + d._scopeSuffix; | |
120 | } | |
121 | if(!d.isIE){ contents += "\r\n//@ sourceURL=" + uri; } // debugging assist for Firebug | |
122 | var value = d["eval"](contents); | |
123 | if(cb){ cb(value); } | |
124 | } | |
125 | // Check to see if we need to call _callLoaded() due to an addOnLoad() that arrived while we were busy downloading | |
126 | if(--d._inFlightCount == 0 && d._postLoad && d._loaders.length){ | |
81bea17a AD |
127 | // We shouldn't be allowed to get here but Firefox allows an event |
128 | // (mouse, keybd, async xhrGet) to interrupt a synchronous xhrGet. | |
a089699c AD |
129 | // If the current script block contains multiple require() statements, then after each |
130 | // require() returns, inFlightCount == 0, but we want to hold the _callLoaded() until | |
131 | // all require()s are done since the out-of-sequence addOnLoad() presumably needs them all. | |
132 | // setTimeout allows the next require() to start (if needed), and then we check this again. | |
81bea17a AD |
133 | setTimeout(function(){ |
134 | // If inFlightCount > 0, then multiple require()s are running sequentially and | |
a089699c | 135 | // the next require() started after setTimeout() was executed but before we got here. |
81bea17a | 136 | if(d._inFlightCount == 0){ |
a089699c AD |
137 | d._callLoaded(); |
138 | } | |
139 | }, 0); | |
140 | } | |
141 | return !!contents; // Boolean: contents? true : false | |
142 | } | |
143 | ||
144 | // FIXME: probably need to add logging to this method | |
145 | dojo._loadUriAndCheck = function(/*String*/uri, /*String*/moduleName, /*Function?*/cb){ | |
146 | // summary: calls loadUri then findModule and returns true if both succeed | |
147 | var ok = false; | |
148 | try{ | |
149 | ok = d._loadUri(uri, cb); | |
150 | }catch(e){ | |
151 | console.error("failed loading " + uri + " with error: " + e); | |
152 | } | |
153 | return !!(ok && d._loadedModules[moduleName]); // Boolean | |
154 | } | |
155 | ||
156 | dojo.loaded = function(){ | |
157 | // summary: | |
158 | // signal fired when initial environment and package loading is | |
81bea17a | 159 | // complete. You should use dojo.addOnLoad() instead of doing a |
a089699c AD |
160 | // direct dojo.connect() to this method in order to handle |
161 | // initialization tasks that require the environment to be | |
81bea17a | 162 | // initialized. In a browser host, declarative widgets will |
a089699c AD |
163 | // be constructed when this function finishes runing. |
164 | d._loadNotifying = true; | |
165 | d._postLoad = true; | |
166 | var mll = d._loaders; | |
167 | ||
168 | //Clear listeners so new ones can be added | |
169 | //For other xdomain package loads after the initial load. | |
170 | d._loaders = []; | |
171 | ||
172 | for(var x = 0; x < mll.length; x++){ | |
173 | mll[x](); | |
174 | } | |
175 | ||
176 | d._loadNotifying = false; | |
177 | ||
178 | //Make sure nothing else got added to the onload queue | |
179 | //after this first run. If something did, and we are not waiting for any | |
180 | //more inflight resources, run again. | |
181 | if(d._postLoad && d._inFlightCount == 0 && mll.length){ | |
182 | d._callLoaded(); | |
183 | } | |
184 | } | |
185 | ||
186 | dojo.unloaded = function(){ | |
187 | // summary: | |
188 | // signal fired by impending environment destruction. You should use | |
81bea17a AD |
189 | // dojo.addOnUnload() instead of doing a direct dojo.connect() to this |
190 | // method to perform page/application cleanup methods. See | |
a089699c AD |
191 | // dojo.addOnUnload for more info. |
192 | var mll = d._unloaders; | |
193 | while(mll.length){ | |
194 | (mll.pop())(); | |
195 | } | |
196 | } | |
197 | ||
198 | d._onto = function(arr, obj, fn){ | |
199 | if(!fn){ | |
200 | arr.push(obj); | |
201 | }else if(fn){ | |
202 | var func = (typeof fn == "string") ? obj[fn] : fn; | |
203 | arr.push(function(){ func.call(obj); }); | |
204 | } | |
205 | } | |
206 | ||
207 | dojo.ready = dojo.addOnLoad = function(/*Object*/obj, /*String|Function?*/functionName){ | |
208 | // summary: | |
81bea17a | 209 | // Registers a function to be triggered after the DOM and dojo.require() calls |
a089699c AD |
210 | // have finished loading. |
211 | // | |
212 | // description: | |
213 | // Registers a function to be triggered after the DOM has finished | |
81bea17a AD |
214 | // loading and `dojo.require` modules have loaded. Widgets declared in markup |
215 | // have been instantiated if `djConfig.parseOnLoad` is true when this fires. | |
a089699c AD |
216 | // |
217 | // Images and CSS files may or may not have finished downloading when | |
218 | // the specified function is called. (Note that widgets' CSS and HTML | |
219 | // code is guaranteed to be downloaded before said widgets are | |
220 | // instantiated, though including css resouces BEFORE any script elements | |
221 | // is highly recommended). | |
222 | // | |
223 | // example: | |
224 | // Register an anonymous function to run when everything is ready | |
225 | // | dojo.addOnLoad(function(){ doStuff(); }); | |
226 | // | |
227 | // example: | |
228 | // Register a function to run when everything is ready by pointer: | |
229 | // | var init = function(){ doStuff(); } | |
230 | // | dojo.addOnLoad(init); | |
231 | // | |
232 | // example: | |
233 | // Register a function to run scoped to `object`, either by name or anonymously: | |
234 | // | dojo.addOnLoad(object, "functionName"); | |
235 | // | dojo.addOnLoad(object, function(){ doStuff(); }); | |
236 | ||
237 | d._onto(d._loaders, obj, functionName); | |
238 | ||
239 | //Added for xdomain loading. dojo.addOnLoad is used to | |
240 | //indicate callbacks after doing some dojo.require() statements. | |
241 | //In the xdomain case, if all the requires are loaded (after initial | |
242 | //page load), then immediately call any listeners. | |
243 | if(d._postLoad && d._inFlightCount == 0 && !d._loadNotifying){ | |
244 | d._callLoaded(); | |
245 | } | |
246 | } | |
247 | ||
248 | //Support calling dojo.addOnLoad via djConfig.addOnLoad. Support all the | |
249 | //call permutations of dojo.addOnLoad. Mainly useful when dojo is added | |
250 | //to the page after the page has loaded. | |
251 | var dca = d.config.addOnLoad; | |
252 | if(dca){ | |
253 | d.addOnLoad[(dca instanceof Array ? "apply" : "call")](d, dca); | |
254 | } | |
255 | ||
256 | dojo._modulesLoaded = function(){ | |
257 | if(d._postLoad){ return; } | |
81bea17a | 258 | if(d._inFlightCount > 0){ |
a089699c AD |
259 | console.warn("files still in flight!"); |
260 | return; | |
261 | } | |
262 | d._callLoaded(); | |
263 | } | |
264 | ||
265 | dojo._callLoaded = function(){ | |
266 | ||
267 | // The "object" check is for IE, and the other opera check fixes an | |
268 | // issue in Opera where it could not find the body element in some | |
269 | // widget test cases. For 0.9, maybe route all browsers through the | |
270 | // setTimeout (need protection still for non-browser environments | |
271 | // though). This might also help the issue with FF 2.0 and freezing | |
272 | // issues where we try to do sync xhr while background css images are | |
273 | // being loaded (trac #2572)? Consider for 0.9. | |
274 | if(typeof setTimeout == "object" || (d.config.useXDomain && d.isOpera)){ | |
275 | setTimeout( | |
276 | d.isAIR ? function(){ d.loaded(); } : d._scopeName + ".loaded();", | |
277 | 0); | |
278 | }else{ | |
279 | d.loaded(); | |
280 | } | |
281 | } | |
282 | ||
283 | dojo._getModuleSymbols = function(/*String*/modulename){ | |
284 | // summary: | |
285 | // Converts a module name in dotted JS notation to an array | |
286 | // representing the path in the source tree | |
287 | var syms = modulename.split("."); | |
288 | for(var i = syms.length; i>0; i--){ | |
289 | var parentModule = syms.slice(0, i).join("."); | |
81bea17a AD |
290 | if(i == 1 && !d._moduleHasPrefix(parentModule)){ |
291 | // Support default module directory (sibling of dojo) for top-level modules | |
a089699c AD |
292 | syms[0] = "../" + syms[0]; |
293 | }else{ | |
294 | var parentModulePath = d._getModulePrefix(parentModule); | |
295 | if(parentModulePath != parentModule){ | |
296 | syms.splice(0, i, parentModulePath); | |
297 | break; | |
298 | } | |
299 | } | |
300 | } | |
301 | return syms; // Array | |
302 | } | |
303 | ||
304 | dojo._global_omit_module_check = false; | |
305 | ||
306 | dojo.loadInit = function(/*Function*/init){ | |
307 | // summary: | |
308 | // Executes a function that needs to be executed for the loader's dojo.requireIf | |
309 | // resolutions to work. This is needed mostly for the xdomain loader case where | |
310 | // a function needs to be executed to set up the possible values for a dojo.requireIf | |
311 | // call. | |
312 | // init: | |
313 | // a function reference. Executed immediately. | |
314 | // description: This function is mainly a marker for the xdomain loader to know parts of | |
315 | // code that needs be executed outside the function wrappper that is placed around modules. | |
316 | // The init function could be executed more than once, and it should make no assumptions | |
317 | // on what is loaded, or what modules are available. Only the functionality in Dojo Base | |
318 | // is allowed to be used. Avoid using this method. For a valid use case, | |
319 | // see the source for dojox.gfx. | |
320 | init(); | |
321 | } | |
322 | ||
323 | dojo._loadModule = dojo.require = function(/*String*/moduleName, /*Boolean?*/omitModuleCheck){ | |
324 | // summary: | |
325 | // loads a Javascript module from the appropriate URI | |
81bea17a AD |
326 | // |
327 | // moduleName: String | |
a089699c AD |
328 | // module name to load, using periods for separators, |
329 | // e.g. "dojo.date.locale". Module paths are de-referenced by dojo's | |
330 | // internal mapping of locations to names and are disambiguated by | |
331 | // longest prefix. See `dojo.registerModulePath()` for details on | |
332 | // registering new modules. | |
81bea17a AD |
333 | // |
334 | // omitModuleCheck: Boolean? | |
a089699c AD |
335 | // if `true`, omitModuleCheck skips the step of ensuring that the |
336 | // loaded file actually defines the symbol it is referenced by. | |
337 | // For example if it called as `dojo.require("a.b.c")` and the | |
338 | // file located at `a/b/c.js` does not define an object `a.b.c`, | |
339 | // and exception will be throws whereas no exception is raised | |
340 | // when called as `dojo.require("a.b.c", true)` | |
81bea17a | 341 | // |
a089699c AD |
342 | // description: |
343 | // Modules are loaded via dojo.require by using one of two loaders: the normal loader | |
344 | // and the xdomain loader. The xdomain loader is used when dojo was built with a | |
345 | // custom build that specified loader=xdomain and the module lives on a modulePath | |
346 | // that is a whole URL, with protocol and a domain. The versions of Dojo that are on | |
347 | // the Google and AOL CDNs use the xdomain loader. | |
81bea17a | 348 | // |
a089699c AD |
349 | // If the module is loaded via the xdomain loader, it is an asynchronous load, since |
350 | // the module is added via a dynamically created script tag. This | |
81bea17a | 351 | // means that dojo.require() can return before the module has loaded. However, this |
a089699c AD |
352 | // should only happen in the case where you do dojo.require calls in the top-level |
353 | // HTML page, or if you purposely avoid the loader checking for dojo.require | |
354 | // dependencies in your module by using a syntax like dojo["require"] to load the module. | |
81bea17a | 355 | // |
a089699c AD |
356 | // Sometimes it is useful to not have the loader detect the dojo.require calls in the |
357 | // module so that you can dynamically load the modules as a result of an action on the | |
358 | // page, instead of right at module load time. | |
81bea17a | 359 | // |
a089699c AD |
360 | // Also, for script blocks in an HTML page, the loader does not pre-process them, so |
361 | // it does not know to download the modules before the dojo.require calls occur. | |
81bea17a | 362 | // |
a089699c AD |
363 | // So, in those two cases, when you want on-the-fly module loading or for script blocks |
364 | // in the HTML page, special care must be taken if the dojo.required code is loaded | |
365 | // asynchronously. To make sure you can execute code that depends on the dojo.required | |
366 | // modules, be sure to add the code that depends on the modules in a dojo.addOnLoad() | |
367 | // callback. dojo.addOnLoad waits for all outstanding modules to finish loading before | |
81bea17a AD |
368 | // executing. |
369 | // | |
a089699c AD |
370 | // This type of syntax works with both xdomain and normal loaders, so it is good |
371 | // practice to always use this idiom for on-the-fly code loading and in HTML script | |
372 | // blocks. If at some point you change loaders and where the code is loaded from, | |
373 | // it will all still work. | |
81bea17a | 374 | // |
a089699c AD |
375 | // More on how dojo.require |
376 | // `dojo.require("A.B")` first checks to see if symbol A.B is | |
377 | // defined. If it is, it is simply returned (nothing to do). | |
81bea17a | 378 | // |
a089699c AD |
379 | // If it is not defined, it will look for `A/B.js` in the script root |
380 | // directory. | |
81bea17a AD |
381 | // |
382 | // `dojo.require` throws an exception if it cannot find a file | |
a089699c | 383 | // to load, or if the symbol `A.B` is not defined after loading. |
81bea17a | 384 | // |
a089699c AD |
385 | // It returns the object `A.B`, but note the caveats above about on-the-fly loading and |
386 | // HTML script blocks when the xdomain loader is loading a module. | |
81bea17a | 387 | // |
a089699c AD |
388 | // `dojo.require()` does nothing about importing symbols into |
389 | // the current namespace. It is presumed that the caller will | |
81bea17a AD |
390 | // take care of that. |
391 | // | |
392 | // example: | |
393 | // To use dojo.require in conjunction with dojo.ready: | |
394 | // | |
395 | // | dojo.require("foo"); | |
396 | // | dojo.require("bar"); | |
397 | // | dojo.addOnLoad(function(){ | |
398 | // | //you can now safely do something with foo and bar | |
399 | // | }); | |
400 | // | |
401 | // example: | |
402 | // For example, to import all symbols into a local block, you might write: | |
403 | // | |
a089699c AD |
404 | // | with (dojo.require("A.B")) { |
405 | // | ... | |
406 | // | } | |
81bea17a | 407 | // |
a089699c | 408 | // And to import just the leaf symbol to a local variable: |
81bea17a | 409 | // |
a089699c AD |
410 | // | var B = dojo.require("A.B"); |
411 | // | ... | |
81bea17a AD |
412 | // |
413 | // returns: | |
414 | // the required namespace object | |
a089699c AD |
415 | omitModuleCheck = d._global_omit_module_check || omitModuleCheck; |
416 | ||
417 | //Check if it is already loaded. | |
418 | var module = d._loadedModules[moduleName]; | |
419 | if(module){ | |
420 | return module; | |
421 | } | |
422 | ||
423 | // convert periods to slashes | |
424 | var relpath = d._getModuleSymbols(moduleName).join("/") + '.js'; | |
a089699c AD |
425 | var modArg = !omitModuleCheck ? moduleName : null; |
426 | var ok = d._loadPath(relpath, modArg); | |
a089699c AD |
427 | if(!ok && !omitModuleCheck){ |
428 | throw new Error("Could not load '" + moduleName + "'; last tried '" + relpath + "'"); | |
429 | } | |
430 | ||
431 | // check that the symbol was defined | |
432 | // Don't bother if we're doing xdomain (asynchronous) loading. | |
433 | if(!omitModuleCheck && !d._isXDomain){ | |
434 | // pass in false so we can give better error | |
435 | module = d._loadedModules[moduleName]; | |
436 | if(!module){ | |
81bea17a | 437 | throw new Error("symbol '" + moduleName + "' is not defined after loading '" + relpath + "'"); |
a089699c AD |
438 | } |
439 | } | |
440 | ||
441 | return module; | |
442 | } | |
443 | ||
444 | dojo.provide = function(/*String*/ resourceName){ | |
445 | // summary: | |
446 | // Register a resource with the package system. Works in conjunction with `dojo.require` | |
447 | // | |
448 | // description: | |
449 | // Each javascript source file is called a resource. When a | |
450 | // resource is loaded by the browser, `dojo.provide()` registers | |
451 | // that it has been loaded. | |
452 | // | |
453 | // Each javascript source file must have at least one | |
454 | // `dojo.provide()` call at the top of the file, corresponding to | |
455 | // the file name. For example, `js/dojo/foo.js` must have | |
456 | // `dojo.provide("dojo.foo");` before any calls to | |
457 | // `dojo.require()` are made. | |
81bea17a | 458 | // |
a089699c AD |
459 | // For backwards compatibility reasons, in addition to registering |
460 | // the resource, `dojo.provide()` also ensures that the javascript | |
461 | // object for the module exists. For example, | |
462 | // `dojo.provide("dojox.data.FlickrStore")`, in addition to | |
463 | // registering that `FlickrStore.js` is a resource for the | |
464 | // `dojox.data` module, will ensure that the `dojox.data` | |
81bea17a | 465 | // javascript object exists, so that calls like |
a089699c AD |
466 | // `dojo.data.foo = function(){ ... }` don't fail. |
467 | // | |
468 | // In the case of a build where multiple javascript source files | |
469 | // are combined into one bigger file (similar to a .lib or .jar | |
470 | // file), that file may contain multiple dojo.provide() calls, to | |
471 | // note that it includes multiple resources. | |
472 | // | |
473 | // resourceName: String | |
81bea17a | 474 | // A dot-sperated string identifying a resource. |
a089699c AD |
475 | // |
476 | // example: | |
477 | // Safely create a `my` object, and make dojo.require("my.CustomModule") work | |
81bea17a | 478 | // | dojo.provide("my.CustomModule"); |
a089699c AD |
479 | |
480 | //Make sure we have a string. | |
481 | resourceName = resourceName + ""; | |
482 | return (d._loadedModules[resourceName] = d.getObject(resourceName, true)); // Object | |
483 | } | |
484 | ||
485 | //Start of old bootstrap2: | |
486 | ||
487 | dojo.platformRequire = function(/*Object*/modMap){ | |
488 | // summary: | |
489 | // require one or more modules based on which host environment | |
490 | // Dojo is currently operating in | |
491 | // description: | |
492 | // This method takes a "map" of arrays which one can use to | |
493 | // optionally load dojo modules. The map is indexed by the | |
494 | // possible dojo.name_ values, with two additional values: | |
495 | // "default" and "common". The items in the "default" array will | |
496 | // be loaded if none of the other items have been choosen based on | |
497 | // dojo.name_, set by your host environment. The items in the | |
498 | // "common" array will *always* be loaded, regardless of which | |
499 | // list is chosen. | |
500 | // example: | |
501 | // | dojo.platformRequire({ | |
502 | // | browser: [ | |
503 | // | "foo.sample", // simple module | |
504 | // | "foo.test", | |
505 | // | ["foo.bar.baz", true] // skip object check in _loadModule (dojo.require) | |
506 | // | ], | |
507 | // | default: [ "foo.sample._base" ], | |
508 | // | common: [ "important.module.common" ] | |
509 | // | }); | |
510 | ||
511 | var common = modMap.common || []; | |
512 | var result = common.concat(modMap[d._name] || modMap["default"] || []); | |
513 | ||
514 | for(var x=0; x<result.length; x++){ | |
515 | var curr = result[x]; | |
516 | if(curr.constructor == Array){ | |
517 | d._loadModule.apply(d, curr); | |
518 | }else{ | |
519 | d._loadModule(curr); | |
520 | } | |
521 | } | |
522 | } | |
523 | ||
524 | dojo.requireIf = function(/*Boolean*/ condition, /*String*/ resourceName){ | |
525 | // summary: | |
526 | // If the condition is true then call `dojo.require()` for the specified | |
527 | // resource | |
528 | // | |
529 | // example: | |
530 | // | dojo.requireIf(dojo.isBrowser, "my.special.Module"); | |
531 | ||
532 | if(condition === true){ | |
533 | // FIXME: why do we support chained require()'s here? does the build system? | |
534 | var args = []; | |
81bea17a | 535 | for(var i = 1; i < arguments.length; i++){ |
a089699c AD |
536 | args.push(arguments[i]); |
537 | } | |
538 | d.require.apply(d, args); | |
539 | } | |
540 | } | |
541 | ||
542 | dojo.requireAfterIf = d.requireIf; | |
543 | ||
544 | dojo.registerModulePath = function(/*String*/module, /*String*/prefix){ | |
81bea17a | 545 | // summary: |
a089699c | 546 | // Maps a module name to a path |
81bea17a | 547 | // description: |
a089699c AD |
548 | // An unregistered module is given the default path of ../[module], |
549 | // relative to Dojo root. For example, module acme is mapped to | |
550 | // ../acme. If you want to use a different module name, use | |
81bea17a | 551 | // dojo.registerModulePath. |
a089699c AD |
552 | // example: |
553 | // If your dojo.js is located at this location in the web root: | |
554 | // | /myapp/js/dojo/dojo/dojo.js | |
555 | // and your modules are located at: | |
556 | // | /myapp/js/foo/bar.js | |
557 | // | /myapp/js/foo/baz.js | |
558 | // | /myapp/js/foo/thud/xyzzy.js | |
559 | // Your application can tell Dojo to locate the "foo" namespace by calling: | |
560 | // | dojo.registerModulePath("foo", "../../foo"); | |
561 | // At which point you can then use dojo.require() to load the | |
562 | // modules (assuming they provide() the same things which are | |
563 | // required). The full code might be: | |
81bea17a | 564 | // | <script type="text/javascript" |
a089699c AD |
565 | // | src="/myapp/js/dojo/dojo/dojo.js"></script> |
566 | // | <script type="text/javascript"> | |
567 | // | dojo.registerModulePath("foo", "../../foo"); | |
568 | // | dojo.require("foo.bar"); | |
569 | // | dojo.require("foo.baz"); | |
570 | // | dojo.require("foo.thud.xyzzy"); | |
571 | // | </script> | |
572 | d._modulePrefixes[module] = { name: module, value: prefix }; | |
81bea17a AD |
573 | }; |
574 | ||
a089699c AD |
575 | dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String?*/availableFlatLocales){ |
576 | // summary: | |
577 | // Declares translated resources and loads them if necessary, in the | |
578 | // same style as dojo.require. Contents of the resource bundle are | |
579 | // typically strings, but may be any name/value pair, represented in | |
580 | // JSON format. See also `dojo.i18n.getLocalization`. | |
581 | // | |
582 | // description: | |
583 | // Load translated resource bundles provided underneath the "nls" | |
584 | // directory within a package. Translated resources may be located in | |
81bea17a | 585 | // different packages throughout the source tree. |
a089699c AD |
586 | // |
587 | // Each directory is named for a locale as specified by RFC 3066, | |
588 | // (http://www.ietf.org/rfc/rfc3066.txt), normalized in lowercase. | |
589 | // Note that the two bundles in the example do not define all the | |
590 | // same variants. For a given locale, bundles will be loaded for | |
591 | // that locale and all more general locales above it, including a | |
592 | // fallback at the root directory. For example, a declaration for | |
593 | // the "de-at" locale will first load `nls/de-at/bundleone.js`, | |
594 | // then `nls/de/bundleone.js` and finally `nls/bundleone.js`. The | |
595 | // data will be flattened into a single Object so that lookups | |
596 | // will follow this cascading pattern. An optional build step can | |
597 | // preload the bundles to avoid data redundancy and the multiple | |
598 | // network hits normally required to load these resources. | |
599 | // | |
81bea17a | 600 | // moduleName: |
a089699c AD |
601 | // name of the package containing the "nls" directory in which the |
602 | // bundle is found | |
603 | // | |
81bea17a | 604 | // bundleName: |
a089699c AD |
605 | // bundle name, i.e. the filename without the '.js' suffix. Using "nls" as a |
606 | // a bundle name is not supported, since "nls" is the name of the folder | |
607 | // that holds bundles. Using "nls" as the bundle name will cause problems | |
608 | // with the custom build. | |
609 | // | |
81bea17a | 610 | // locale: |
a089699c AD |
611 | // the locale to load (optional) By default, the browser's user |
612 | // locale as defined by dojo.locale | |
613 | // | |
81bea17a | 614 | // availableFlatLocales: |
a089699c AD |
615 | // A comma-separated list of the available, flattened locales for this |
616 | // bundle. This argument should only be set by the build process. | |
617 | // | |
618 | // example: | |
619 | // A particular widget may define one or more resource bundles, | |
620 | // structured in a program as follows, where moduleName is | |
621 | // mycode.mywidget and bundleNames available include bundleone and | |
622 | // bundletwo: | |
623 | // | ... | |
624 | // | mycode/ | |
625 | // | mywidget/ | |
626 | // | nls/ | |
627 | // | bundleone.js (the fallback translation, English in this example) | |
628 | // | bundletwo.js (also a fallback translation) | |
629 | // | de/ | |
630 | // | bundleone.js | |
631 | // | bundletwo.js | |
632 | // | de-at/ | |
633 | // | bundleone.js | |
634 | // | en/ | |
635 | // | (empty; use the fallback translation) | |
636 | // | en-us/ | |
637 | // | bundleone.js | |
638 | // | en-gb/ | |
639 | // | bundleone.js | |
640 | // | es/ | |
641 | // | bundleone.js | |
642 | // | bundletwo.js | |
643 | // | ...etc | |
644 | // | ... | |
645 | // | |
646 | ||
647 | d.require("dojo.i18n"); | |
648 | d.i18n._requireLocalization.apply(d.hostenv, arguments); | |
649 | }; | |
650 | ||
651 | ||
652 | var ore = new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"), | |
653 | ire = new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$"); | |
654 | ||
655 | dojo._Url = function(/*dojo._Url|String...*/){ | |
81bea17a | 656 | // summary: |
a089699c AD |
657 | // Constructor to create an object representing a URL. |
658 | // It is marked as private, since we might consider removing | |
659 | // or simplifying it. | |
81bea17a | 660 | // description: |
a089699c AD |
661 | // Each argument is evaluated in order relative to the next until |
662 | // a canonical uri is produced. To get an absolute Uri relative to | |
663 | // the current document use: | |
664 | // new dojo._Url(document.baseURI, url) | |
665 | ||
666 | var n = null, | |
667 | _a = arguments, | |
668 | uri = [_a[0]]; | |
669 | // resolve uri components relative to each other | |
670 | for(var i = 1; i<_a.length; i++){ | |
671 | if(!_a[i]){ continue; } | |
672 | ||
673 | // Safari doesn't support this.constructor so we have to be explicit | |
674 | // FIXME: Tracked (and fixed) in Webkit bug 3537. | |
675 | // http://bugs.webkit.org/show_bug.cgi?id=3537 | |
676 | var relobj = new d._Url(_a[i]+""), | |
677 | uriobj = new d._Url(uri[0]+""); | |
678 | ||
679 | if( | |
680 | relobj.path == "" && | |
681 | !relobj.scheme && | |
682 | !relobj.authority && | |
683 | !relobj.query | |
684 | ){ | |
685 | if(relobj.fragment != n){ | |
686 | uriobj.fragment = relobj.fragment; | |
687 | } | |
688 | relobj = uriobj; | |
689 | }else if(!relobj.scheme){ | |
690 | relobj.scheme = uriobj.scheme; | |
691 | ||
692 | if(!relobj.authority){ | |
693 | relobj.authority = uriobj.authority; | |
694 | ||
695 | if(relobj.path.charAt(0) != "/"){ | |
696 | var path = uriobj.path.substring(0, | |
697 | uriobj.path.lastIndexOf("/") + 1) + relobj.path; | |
698 | ||
699 | var segs = path.split("/"); | |
700 | for(var j = 0; j < segs.length; j++){ | |
701 | if(segs[j] == "."){ | |
702 | // flatten "./" references | |
703 | if(j == segs.length - 1){ | |
704 | segs[j] = ""; | |
705 | }else{ | |
706 | segs.splice(j, 1); | |
707 | j--; | |
708 | } | |
709 | }else if(j > 0 && !(j == 1 && segs[0] == "") && | |
710 | segs[j] == ".." && segs[j-1] != ".."){ | |
711 | // flatten "../" references | |
712 | if(j == (segs.length - 1)){ | |
713 | segs.splice(j, 1); | |
714 | segs[j - 1] = ""; | |
715 | }else{ | |
716 | segs.splice(j - 1, 2); | |
717 | j -= 2; | |
718 | } | |
719 | } | |
720 | } | |
721 | relobj.path = segs.join("/"); | |
722 | } | |
723 | } | |
724 | } | |
725 | ||
726 | uri = []; | |
81bea17a | 727 | if(relobj.scheme){ |
a089699c AD |
728 | uri.push(relobj.scheme, ":"); |
729 | } | |
730 | if(relobj.authority){ | |
731 | uri.push("//", relobj.authority); | |
732 | } | |
733 | uri.push(relobj.path); | |
734 | if(relobj.query){ | |
735 | uri.push("?", relobj.query); | |
736 | } | |
737 | if(relobj.fragment){ | |
738 | uri.push("#", relobj.fragment); | |
739 | } | |
740 | } | |
741 | ||
742 | this.uri = uri.join(""); | |
743 | ||
744 | // break the uri into its main components | |
745 | var r = this.uri.match(ore); | |
746 | ||
747 | this.scheme = r[2] || (r[1] ? "" : n); | |
748 | this.authority = r[4] || (r[3] ? "" : n); | |
749 | this.path = r[5]; // can never be undefined | |
750 | this.query = r[7] || (r[6] ? "" : n); | |
751 | this.fragment = r[9] || (r[8] ? "" : n); | |
752 | ||
753 | if(this.authority != n){ | |
754 | // server based naming authority | |
755 | r = this.authority.match(ire); | |
756 | ||
757 | this.user = r[3] || n; | |
758 | this.password = r[4] || n; | |
759 | this.host = r[6] || r[7]; // ipv6 || ipv4 | |
760 | this.port = r[9] || n; | |
761 | } | |
762 | } | |
763 | ||
764 | dojo._Url.prototype.toString = function(){ return this.uri; }; | |
765 | ||
766 | dojo.moduleUrl = function(/*String*/module, /*dojo._Url||String*/url){ | |
81bea17a | 767 | // summary: |
a089699c AD |
768 | // Returns a `dojo._Url` object relative to a module. |
769 | // example: | |
770 | // | var pngPath = dojo.moduleUrl("acme","images/small.png"); | |
771 | // | console.dir(pngPath); // list the object properties | |
772 | // | // create an image and set it's source to pngPath's value: | |
773 | // | var img = document.createElement("img"); | |
774 | // | // NOTE: we assign the string representation of the url object | |
81bea17a | 775 | // | img.src = pngPath.toString(); |
a089699c AD |
776 | // | // add our image to the document |
777 | // | dojo.body().appendChild(img); | |
81bea17a | 778 | // example: |
a089699c AD |
779 | // you may de-reference as far as you like down the package |
780 | // hierarchy. This is sometimes handy to avoid lenghty relative | |
781 | // urls or for building portable sub-packages. In this example, | |
782 | // the `acme.widget` and `acme.util` directories may be located | |
783 | // under different roots (see `dojo.registerModulePath`) but the | |
784 | // the modules which reference them can be unaware of their | |
785 | // relative locations on the filesystem: | |
786 | // | // somewhere in a configuration block | |
787 | // | dojo.registerModulePath("acme.widget", "../../acme/widget"); | |
788 | // | dojo.registerModulePath("acme.util", "../../util"); | |
81bea17a | 789 | // | |
a089699c | 790 | // | // ... |
81bea17a | 791 | // | |
a089699c AD |
792 | // | // code in a module using acme resources |
793 | // | var tmpltPath = dojo.moduleUrl("acme.widget","templates/template.html"); | |
794 | // | var dataPath = dojo.moduleUrl("acme.util","resources/data.json"); | |
795 | ||
796 | var loc = d._getModuleSymbols(module).join('/'); | |
797 | if(!loc){ return null; } | |
798 | if(loc.lastIndexOf("/") != loc.length-1){ | |
799 | loc += "/"; | |
800 | } | |
801 | ||
802 | //If the path is an absolute path (starts with a / or is on another | |
803 | //domain/xdomain) then don't add the baseUrl. | |
804 | var colonIndex = loc.indexOf(":"); | |
805 | if(loc.charAt(0) != "/" && (colonIndex == -1 || colonIndex > loc.indexOf("/"))){ | |
806 | loc = d.baseUrl + loc; | |
807 | } | |
808 | ||
809 | return new d._Url(loc, url); // dojo._Url | |
81bea17a AD |
810 | }; |
811 | ||
812 | ||
813 | ||
2f01fe57 | 814 | })(); |
a089699c | 815 | |
2f01fe57 | 816 | } |