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