]> git.wh0rd.org - tt-rss.git/blame - lib/dojo/_base/_loader/loader.js
upgrade Dojo to 1.6.1
[tt-rss.git] / lib / dojo / _base / _loader / loader.js
CommitLineData
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
8if(!dojo._hasResource["dojo.foo"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
9dojo._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}