]> git.pond.sub.org Git - eow/blob - static/dojo-release-1.1.1/dojo/_base/_loader/loader_xd.js
Comment class stub
[eow] / static / dojo-release-1.1.1 / dojo / _base / _loader / loader_xd.js
1 if(!dojo._hasResource["dojo._base._loader.loader_xd"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dojo._base._loader.loader_xd"] = true;
3 //Cross-domain resource loader.
4 dojo.provide("dojo._base._loader.loader_xd");
5
6 dojo._xdReset = function(){
7         //summary: Internal xd loader function. Resets the xd state.
8
9         //This flag indicates where or not we have crossed into xdomain territory. Once any resource says
10         //it is cross domain, then the rest of the resources have to be treated as xdomain because we need
11         //to evaluate resources in order. If there is a xdomain resource followed by a xhr resource, we can't load
12         //the xhr resource until the one before it finishes loading. The text of the xhr resource will be converted
13         //to match the format for a xd resource and put in the xd load queue.
14         this._isXDomain = dojo.config.useXDomain || false;
15
16         this._xdTimer = 0;
17         this._xdInFlight = {};
18         this._xdOrderedReqs = [];
19         this._xdDepMap = {};
20         this._xdContents = [];
21         this._xdDefList = [];
22 }
23
24 //Call reset immediately to set the state.
25 dojo._xdReset();
26
27 dojo._xdCreateResource = function(/*String*/contents, /*String*/resourceName, /*String*/resourcePath){
28         //summary: Internal xd loader function. Creates an xd module source given an
29         //non-xd module contents.
30
31         //Remove comments. Not perfect, but good enough for dependency resolution.
32         var depContents = contents.replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg , "");
33
34         //Find dependencies.
35         var deps = [];
36     var depRegExp = /dojo.(require|requireIf|provide|requireAfterIf|platformRequire|requireLocalization)\(([\w\W]*?)\)/mg;
37     var match;
38         while((match = depRegExp.exec(depContents)) != null){
39                 if(match[1] == "requireLocalization"){
40                         //Need to load the local bundles asap, since they are not
41                         //part of the list of modules watched for loading.
42                         eval(match[0]);
43                 }else{
44                         deps.push('"' + match[1] + '", ' + match[2]);
45                 }
46         }
47
48         //Create resource object and the call to _xdResourceLoaded.
49         var output = [];
50         output.push(dojo._scopeName + "._xdResourceLoaded({\n");
51
52         //Add dependencies
53         if(deps.length > 0){
54                 output.push("depends: [");
55                 for(var i = 0; i < deps.length; i++){
56                         if(i > 0){
57                                 output.push(",\n");
58                         }
59                         output.push("[" + deps[i] + "]");
60                 }
61                 output.push("],");
62         }
63
64         //Add the contents of the file inside a function.
65         //Pass in scope arguments so we can support multiple versions of the
66         //same module on a page.
67         output.push("\ndefineResource: function(" + dojo._scopePrefixArgs + "){");
68
69         //Don't put in the contents in the debugAtAllCosts case
70         //since the contents may have syntax errors. Let those
71         //get pushed up when the script tags are added to the page
72         //in the debugAtAllCosts case.
73         if(!dojo.config["debugAtAllCosts"] || resourceName == "dojo._base._loader.loader_debug"){
74                 output.push(contents);
75         }
76         //Add isLocal property so we know if we have to do something different
77         //in debugAtAllCosts situations.
78         output.push("\n}, resourceName: '" + resourceName + "', resourcePath: '" + resourcePath + "'});");
79         
80         return output.join(""); //String
81 }
82
83 dojo._xdIsXDomainPath = function(/*string*/relpath) {
84     //summary: Figure out whether the path is local or x-domain
85         //If there is a colon before the first / then, we have a URL with a protocol.
86     
87         var colonIndex = relpath.indexOf(":");
88         var slashIndex = relpath.indexOf("/");
89
90         if(colonIndex > 0 && colonIndex < slashIndex){
91                 return true;
92         }else{
93                 //Is the base script URI-based URL a cross domain URL?
94                 //If so, then the relpath will be evaluated relative to
95                 //baseUrl, and therefore qualify as xdomain.
96                 //Only treat it as xdomain if the page does not have a
97                 //host (file:// url) or if the baseUrl does not match the
98                 //current window's domain.
99                 var url = this.baseUrl;
100                 colonIndex = url.indexOf(":");
101                 slashIndex = url.indexOf("/");
102                 if(colonIndex > 0 && colonIndex < slashIndex && (!location.host || url.indexOf("http://" + location.host) != 0)){
103                         return true;
104                 }
105         }
106     return false;     
107 }
108
109 dojo._loadPath = function(/*String*/relpath, /*String?*/module, /*Function?*/cb){
110         //summary: Internal xd loader function. Overrides loadPath() from loader.js.
111         //xd loading requires slightly different behavior from loadPath().
112
113         var currentIsXDomain = this._xdIsXDomainPath(relpath);
114     this._isXDomain |= currentIsXDomain;
115
116         var uri = ((relpath.charAt(0) == '/' || relpath.match(/^\w+:/)) ? "" : this.baseUrl) + relpath;
117
118         try{
119                 return ((!module || this._isXDomain) ? this._loadUri(uri, cb, currentIsXDomain, module) : this._loadUriAndCheck(uri, module, cb)); //Boolean
120         }catch(e){
121                 console.debug(e);
122                 return false; //Boolean
123         }
124 }
125
126 dojo._loadUri = function(/*String*/uri, /*Function?*/cb, /*boolean*/currentIsXDomain, /*String?*/module){
127         //summary: Internal xd loader function. Overrides loadUri() from loader.js.
128         //              xd loading requires slightly different behavior from loadPath().
129         //description: Wanted to override getText(), but it is used by
130         //              the widget code in too many, synchronous ways right now.
131         if(this._loadedUrls[uri]){
132                 return 1; //Boolean
133         }
134
135         //Add the module (resource) to the list of modules.
136         //Only do this work if we have a modlue name. Otherwise, 
137         //it is a non-xd i18n bundle, which can load immediately and does not 
138         //need to be tracked. Also, don't track dojo.i18n, since it is a prerequisite
139         //and will be loaded correctly if we load it right away: it has no dependencies.
140         if(this._isXDomain && module && module != "dojo.i18n"){
141                 this._xdOrderedReqs.push(module);
142
143                 //Add to waiting resources if it is an xdomain resource.
144                 //Don't add non-xdomain i18n bundles, those get evaled immediately.
145                 if(currentIsXDomain || uri.indexOf("/nls/") == -1){
146                         this._xdInFlight[module] = true;
147
148                         //Increment inFlightCount
149                         //This will stop the modulesLoaded from firing all the way.
150                         this._inFlightCount++;
151                 }
152
153                 //Start timer
154                 if(!this._xdTimer){
155                         if(dojo.isAIR){
156                                 this._xdTimer = setInterval(function(){dojo._xdWatchInFlight();}, 100);
157                         }else{
158                                 this._xdTimer = setInterval(dojo._scopeName + "._xdWatchInFlight();", 100);
159                         }
160                 }
161                 this._xdStartTime = (new Date()).getTime();
162         }
163
164         if (currentIsXDomain){
165                 //Fix name to be a .xd.fileextension name.
166                 var lastIndex = uri.lastIndexOf('.');
167                 if(lastIndex <= 0){
168                         lastIndex = uri.length - 1;
169                 }
170
171                 var xdUri = uri.substring(0, lastIndex) + ".xd";
172                 if(lastIndex != uri.length - 1){
173                         xdUri += uri.substring(lastIndex, uri.length);
174                 }
175
176                 if (dojo.isAIR){
177                         xdUri = xdUri.replace("app:/", "/");
178                 }
179
180                 //Add to script src
181                 var element = document.createElement("script");
182                 element.type = "text/javascript";
183                 element.src = xdUri;
184                 if(!this.headElement){
185                         this._headElement = document.getElementsByTagName("head")[0];
186
187                         //Head element may not exist, particularly in html
188                         //html 4 or tag soup cases where the page does not
189                         //have a head tag in it. Use html element, since that will exist.
190                         //Seems to be an issue mostly with Opera 9 and to lesser extent Safari 2
191                         if(!this._headElement){
192                                 this._headElement = document.getElementsByTagName("html")[0];
193                         }
194                 }
195                 this._headElement.appendChild(element);
196         }else{
197                 var contents = this._getText(uri, null, true);
198                 if(contents == null){ return 0; /*boolean*/}
199                 
200                 //If this is not xdomain, or if loading a i18n resource bundle, then send it down
201                 //the normal eval/callback path.
202                 if(this._isXDomain
203                         && uri.indexOf("/nls/") == -1
204                         && module != "dojo.i18n"){
205                         var res = this._xdCreateResource(contents, module, uri);
206                         dojo.eval(res);
207                 }else{
208                         if(cb){
209                                 contents = '('+contents+')';
210                         }else{
211                                 //Only do the scoping if no callback. If a callback is specified,
212                                 //it is most likely the i18n bundle stuff.
213                                 contents = this._scopePrefix + contents + this._scopeSuffix;
214                         }
215                         var value = dojo["eval"](contents+"\r\n//@ sourceURL="+uri);
216                         if(cb){
217                                 cb(value);
218                         }
219                 }
220         }
221
222         //These steps are done in the non-xd loader version of this function.
223         //Maintain these steps to fit in with the existing system.
224         this._loadedUrls[uri] = true;
225         this._loadedUrls.push(uri);
226         return true; //Boolean
227 }
228
229 dojo._xdResourceLoaded = function(/*Object*/res){
230         //summary: Internal xd loader function. Called by an xd module resource when
231         //it has been loaded via a script tag.
232         var deps = res.depends;
233         var requireList = null;
234         var requireAfterList = null;
235         var provideList = [];
236         if(deps && deps.length > 0){
237                 var dep = null;
238                 var insertHint = 0;
239                 var attachedResource = false;
240                 for(var i = 0; i < deps.length; i++){
241                         dep = deps[i];
242
243                         //Look for specific dependency indicators.
244                         if (dep[0] == "provide"){
245                                 provideList.push(dep[1]);
246                         }else{
247                                 if(!requireList){
248                                         requireList = [];
249                                 }
250                                 if(!requireAfterList){
251                                         requireAfterList = [];
252                                 }
253
254                                 var unpackedDeps = this._xdUnpackDependency(dep);
255                                 if(unpackedDeps.requires){
256                                         requireList = requireList.concat(unpackedDeps.requires);
257                                 }
258                                 if(unpackedDeps.requiresAfter){
259                                         requireAfterList = requireAfterList.concat(unpackedDeps.requiresAfter);
260                                 }
261                         }
262
263                         //Call the dependency indicator to allow for the normal dojo setup.
264                         //Only allow for one dot reference, for the i18n._preloadLocalizations calls
265                         //(and maybe future, one-dot things).
266                         var depType = dep[0];
267                         var objPath = depType.split(".");
268                         if(objPath.length == 2){
269                                 dojo[objPath[0]][objPath[1]].apply(dojo[objPath[0]], dep.slice(1));
270                         }else{
271                                 dojo[depType].apply(dojo, dep.slice(1));
272                         }
273                 }
274
275
276                 //If loading the debugAtAllCosts module, eval it right away since we need
277                 //its functions to properly load the other modules.
278                 if(provideList.length == 1 && provideList[0] == "dojo._base._loader.loader_debug"){
279                         res.defineResource(dojo);
280                 }else{
281                         //Save off the resource contents for definition later.
282                         var contentIndex = this._xdContents.push({
283                                         content: res.defineResource,
284                                         resourceName: res["resourceName"],
285                                         resourcePath: res["resourcePath"],
286                                         isDefined: false
287                                 }) - 1;
288         
289                         //Add provide/requires to dependency map.
290                         for(var i = 0; i < provideList.length; i++){
291                                 this._xdDepMap[provideList[i]] = { requires: requireList, requiresAfter: requireAfterList, contentIndex: contentIndex };
292                         }
293                 }
294
295                 //Now update the inflight status for any provided resources in this loaded resource.
296                 //Do this at the very end (in a *separate* for loop) to avoid shutting down the 
297                 //inflight timer check too soon.
298                 for(var i = 0; i < provideList.length; i++){
299                         this._xdInFlight[provideList[i]] = false;
300                 }
301         }
302 }
303
304 dojo._xdLoadFlattenedBundle = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*Object*/bundleData){
305         //summary: Internal xd loader function. Used when loading
306         //a flattened localized bundle via a script tag.
307         locale = locale || "root";
308         var jsLoc = dojo.i18n.normalizeLocale(locale).replace('-', '_');
309         var bundleResource = [moduleName, "nls", bundleName].join(".");
310         var bundle = dojo["provide"](bundleResource);
311         bundle[jsLoc] = bundleData;
312         
313         //Assign the bundle for the original locale(s) we wanted.
314         var mapName = [moduleName, jsLoc, bundleName].join(".");
315         var bundleMap = dojo._xdBundleMap[mapName];
316         if(bundleMap){
317                 for(var param in bundleMap){
318                         bundle[param] = bundleData;
319                 }
320         }
321 };
322
323
324 dojo._xdInitExtraLocales = function(){
325         // Simulate the extra locale work that dojo.requireLocalization does.
326
327         var extra = dojo.config.extraLocale;
328         if(extra){
329                 if(!extra instanceof Array){
330                         extra = [extra];
331                 }
332
333                 dojo._xdReqLoc = dojo.xdRequireLocalization;
334                 dojo.xdRequireLocalization = function(m, b, locale, fLocales){
335                         dojo._xdReqLoc(m,b,locale, fLocales);
336                         if(locale){return;}
337                         for(var i=0; i<extra.length; i++){
338                                 dojo._xdReqLoc(m,b,extra[i], fLocales);
339                         }
340                 };
341         }
342 }
343
344 dojo._xdBundleMap = {};
345
346 dojo.xdRequireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String*/availableFlatLocales){
347         //summary: Internal xd loader function. The xd version of dojo.requireLocalization.
348         
349
350         //Account for allowing multiple extra locales. Do this here inside the function
351         //since dojo._xdInitExtraLocales() depends on djConfig being set up, but that only
352         //happens after hostenv_browser runs. loader_xd has to come before hostenv_browser
353         //though since hostenv_browser can do a dojo.require for the debug module.
354         if(dojo._xdInitExtraLocales){
355                 dojo._xdInitExtraLocales();
356                 dojo._xdInitExtraLocales = null;
357                 dojo.xdRequireLocalization.apply(dojo, arguments);
358                 return;
359         }
360
361         var locales = availableFlatLocales.split(",");
362         
363         //Find the best-match locale to load.
364         //Assumes dojo.i18n has already been loaded. This is true for xdomain builds,
365         //since it is included in dojo.xd.js.
366         var jsLoc = dojo.i18n.normalizeLocale(locale);
367
368         var bestLocale = "";
369         for(var i = 0; i < locales.length; i++){
370                 //Locale must match from start of string.
371                 if(jsLoc.indexOf(locales[i]) == 0){
372                         if(locales[i].length > bestLocale.length){
373                                 bestLocale = locales[i];
374                         }
375                 }
376         }
377
378         var fixedBestLocale = bestLocale.replace('-', '_');
379         //See if the bundle we are going to use is already loaded.
380         var bundleResource = dojo.getObject([moduleName, "nls", bundleName].join("."));
381         if(bundleResource && bundleResource[fixedBestLocale]){
382                 bundle[jsLoc.replace('-', '_')] = bundleResource[fixedBestLocale];
383         }else{
384                 //Need to remember what locale we wanted and which one we actually use.
385                 //Then when we load the one we are actually using, use that bundle for the one
386                 //we originally wanted.
387                 var mapName = [moduleName, (fixedBestLocale||"root"), bundleName].join(".");
388                 var bundleMap = dojo._xdBundleMap[mapName];
389                 if(!bundleMap){
390                         bundleMap = dojo._xdBundleMap[mapName] = {};
391                 }
392                 bundleMap[jsLoc.replace('-', '_')] = true;
393                 
394                 //Do just a normal dojo.require so the resource tracking stuff works as usual.
395                 dojo.require(moduleName + ".nls" + (bestLocale ? "." + bestLocale : "") + "." + bundleName);
396         }
397 }
398
399 // Replace dojo.requireLocalization with a wrapper
400 dojo._xdRealRequireLocalization = dojo.requireLocalization;
401 dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String*/availableFlatLocales){
402     // summary: loads a bundle intelligently based on whether the module is 
403     // local or xd. Overrides the local-case implementation.
404     
405     var modulePath = this.moduleUrl(moduleName).toString();
406     if (this._xdIsXDomainPath(modulePath)) {
407         // call cross-domain loader
408         return dojo.xdRequireLocalization.apply(dojo, arguments);
409     } else {
410         // call local-loader
411         return dojo._xdRealRequireLocalization.apply(dojo, arguments);
412     }
413 }
414
415 //This is a bit brittle: it has to know about the dojo methods that deal with dependencies
416 //It would be ideal to intercept the actual methods and do something fancy at that point,
417 //but I have concern about knowing which provide to match to the dependency in that case,
418 //since scripts can load whenever they want, and trigger new calls to dojo._xdResourceLoaded().
419 dojo._xdUnpackDependency = function(/*Array*/dep){
420         //summary: Internal xd loader function. Determines what to do with a dependency
421         //that was listed in an xd version of a module contents.
422
423         //Extract the dependency(ies).
424         var newDeps = null;
425         var newAfterDeps = null;
426         switch(dep[0]){
427                 case "requireIf":
428                 case "requireAfterIf":
429                         //First arg (dep[1]) is the test. Depedency is dep[2].
430                         if(dep[1] === true){
431                                 newDeps = [{name: dep[2], content: null}];
432                         }
433                         break;
434                 case "platformRequire":
435                         var modMap = dep[1];
436                         var common = modMap["common"]||[];
437                         var newDeps = (modMap[dojo.hostenv.name_]) ? common.concat(modMap[dojo.hostenv.name_]||[]) : common.concat(modMap["default"]||[]);      
438                         //Flatten the array of arrays into a one-level deep array.
439                         //Each result could be an array of 3 elements  (the 3 arguments to dojo.require).
440                         //We only need the first one.
441                         if(newDeps){
442                                 for(var i = 0; i < newDeps.length; i++){
443                                         if(newDeps[i] instanceof Array){
444                                                 newDeps[i] = {name: newDeps[i][0], content: null};
445                                         }else{
446                                                 newDeps[i] = {name: newDeps[i], content: null};
447                                         }
448                                 }
449                         }
450                         break;
451                 case "require":
452                         //Just worry about dep[1]
453                         newDeps = [{name: dep[1], content: null}];
454                         break;
455                 case "i18n._preloadLocalizations":
456                         //We can eval these immediately, since they load i18n bundles.
457                         //Since i18n bundles have no dependencies, whenever they are loaded
458                         //in a script tag, they are evaluated immediately, so we do not have to
459                         //treat them has an explicit dependency for the dependency mapping.
460                         //We can call it immediately since dojo.i18n is part of dojo.xd.js.
461                         dojo.i18n._preloadLocalizations.apply(dojo.i18n._preloadLocalizations, dep.slice(1));
462                         break;
463         }
464
465         //The requireIf and requireAfterIf needs to be evaluated after the current resource is evaluated.
466         if(dep[0] == "requireAfterIf" || dep[0] == "requireIf"){
467                 newAfterDeps = newDeps;
468                 newDeps = null;
469         }
470         return {requires: newDeps, requiresAfter: newAfterDeps}; //Object
471 }
472
473 dojo._xdWalkReqs = function(){
474         //summary: Internal xd loader function. 
475         //Walks the requires and evaluates module resource contents in
476         //the right order.
477         var reqChain = null;
478         var req;
479         for(var i = 0; i < this._xdOrderedReqs.length; i++){
480                 req = this._xdOrderedReqs[i];
481                 if(this._xdDepMap[req]){
482                         reqChain = [req];
483                         reqChain[req] = true; //Allow for fast lookup of the req in the array
484                         this._xdEvalReqs(reqChain);
485                 }
486         }
487 }
488
489 dojo._xdEvalReqs = function(/*Array*/reqChain){
490         //summary: Internal xd loader function. 
491         //Does a depth first, breadth second search and eval of required modules.
492         while(reqChain.length > 0){
493                 var req = reqChain[reqChain.length - 1];
494                 var res = this._xdDepMap[req];
495                 if(res){
496                         //Trace down any requires for this resource.
497                         //START dojo._xdTraceReqs() inlining for small Safari 2.0 call stack
498                         var reqs = res.requires;
499                         if(reqs && reqs.length > 0){
500                                 var nextReq;
501                                 for(var i = 0; i < reqs.length; i++){
502                                         nextReq = reqs[i].name;
503                                         if(nextReq && !reqChain[nextReq]){
504                                                 //New req depedency. Follow it down.
505                                                 reqChain.push(nextReq);
506                                                 reqChain[nextReq] = true;
507                                                 this._xdEvalReqs(reqChain);
508                                         }
509                                 }
510                         }
511                         //END dojo._xdTraceReqs() inlining for small Safari 2.0 call stack
512
513                         //Evaluate the resource.
514                         var contents = this._xdContents[res.contentIndex];
515                         if(!contents.isDefined){
516                                 var content = contents.content;
517                                 content["resourceName"] = contents["resourceName"];
518                                 content["resourcePath"] = contents["resourcePath"];
519                                 this._xdDefList.push(content);
520                                 contents.isDefined = true;
521                         }
522                         this._xdDepMap[req] = null;
523
524                         //Trace down any requireAfters for this resource.
525                         //START dojo._xdTraceReqs() inlining for small Safari 2.0 call stack
526                         var reqs = res.requiresAfter;
527                         if(reqs && reqs.length > 0){
528                                 var nextReq;
529                                 for(var i = 0; i < reqs.length; i++){
530                                         nextReq = reqs[i].name;
531                                         if(nextReq && !reqChain[nextReq]){
532                                                 //New req depedency. Follow it down.
533                                                 reqChain.push(nextReq);
534                                                 reqChain[nextReq] = true;
535                                                 this._xdEvalReqs(reqChain);
536                                         }
537                                 }
538                         }
539                         //END dojo._xdTraceReqs() inlining for small Safari 2.0 call stack
540                 }
541
542                 //Done with that require. Remove it and go to the next one.
543                 reqChain.pop();
544         }
545 }
546
547 dojo._xdClearInterval = function(){
548         //summary: Internal xd loader function.
549         //Clears the interval timer used to check on the
550         //status of in-flight xd module resource requests.
551         clearInterval(this._xdTimer);
552         this._xdTimer = 0;
553 }
554
555 dojo._xdWatchInFlight = function(){
556         //summary: Internal xd loader function.
557         //Monitors in-flight requests for xd module resources.
558
559         var noLoads = "";
560         var waitInterval = (dojo.config.xdWaitSeconds || 15) * 1000;
561         var expired = (this._xdStartTime + waitInterval) < (new Date()).getTime();
562
563         //If any xdInFlight are true, then still waiting for something to load.
564         //Come back later. If we timed out, report the things that did not load.
565         for(var param in this._xdInFlight){
566                 if(this._xdInFlight[param] === true){
567                         if(expired){
568                                 noLoads += param + " ";
569                         }else{
570                                 return;
571                         }
572                 }
573         }
574
575         //All done. Clean up and notify.
576         this._xdClearInterval();
577
578         if(expired){
579                 throw "Could not load cross-domain resources: " + noLoads;
580         }
581
582         this._xdWalkReqs();
583         
584         var defLength = this._xdDefList.length;
585         for(var i= 0; i < defLength; i++){
586                 var content = dojo._xdDefList[i];
587                 if(dojo.config["debugAtAllCosts"] && content["resourceName"]){
588                         if(!this["_xdDebugQueue"]){
589                                 this._xdDebugQueue = [];
590                         }
591                         this._xdDebugQueue.push({resourceName: content.resourceName, resourcePath: content.resourcePath});
592                 }else{
593                         //Evaluate the resource to bring it into being.
594                         //Pass in scope args to allow multiple versions of modules in a page.   
595                         content.apply(dojo.global, dojo._scopeArgs);
596                 }
597         }
598
599         //Evaluate any resources that were not evaled before.
600         //This normally shouldn't happen with proper dojo.provide and dojo.require
601         //usage, but providing it just in case. Note that these may not be executed
602         //in the original order that the developer intended.
603         for(var i = 0; i < this._xdContents.length; i++){
604                 var current = this._xdContents[i];
605                 if(current.content && !current.isDefined){
606                         //Pass in scope args to allow multiple versions of modules in a page.   
607                         current.content.apply(dojo.global, dojo._scopeArgs);
608                 }
609         }
610
611         //Clean up for the next round of xd loading.
612         this._xdReset();
613
614         if(this["_xdDebugQueue"] && this._xdDebugQueue.length > 0){
615                 this._xdDebugFileLoaded();
616         }else{
617                 this._xdNotifyLoaded();
618         }
619 }
620
621 dojo._xdNotifyLoaded = function(){
622         //Clear inflight count so we will finally do finish work.
623         this._inFlightCount = 0; 
624         
625         //Only trigger call loaded if dj_load_init has run. 
626         if(this._initFired && !this._loadNotifying){ 
627                 this._callLoaded();
628         }
629 }
630
631 }