2 Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
3 Available via Academic Free License >= 2.1 OR the modified BSD license.
4 see: http://dojotoolkit.org/license for details
8 if(!dojo
._hasResource
["dojo._base._loader.loader_xd"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
9 dojo
._hasResource
["dojo._base._loader.loader_xd"] = true;
10 //Cross-domain resource loader.
11 dojo
.provide("dojo._base._loader.loader_xd");
13 dojo
._xdReset = function(){
14 //summary: Internal xd loader function. Resets the xd state.
16 //This flag indicates where or not we have crossed into xdomain territory. Once any resource says
17 //it is cross domain, then the rest of the resources have to be treated as xdomain because we need
18 //to evaluate resources in order. If there is a xdomain resource followed by a xhr resource, we can't load
19 //the xhr resource until the one before it finishes loading. The text of the xhr resource will be converted
20 //to match the format for a xd resource and put in the xd load queue.
21 dojo
._isXDomain
= dojo
.config
.useXDomain
|| false;
23 dojo
._xdClearInterval();
24 dojo
._xdInFlight
= {};
25 dojo
._xdOrderedReqs
= [];
27 dojo
._xdContents
= [];
31 dojo
._xdClearInterval = function(){
32 //summary: Internal xd loader function.
33 //Clears the interval timer used to check on the
34 //status of in-flight xd module resource requests.
36 clearInterval(dojo
._xdTimer
);
42 //Call reset immediately to set the state.
45 dojo
._xdCreateResource = function(/*String*/contents
, /*String*/resourceName
, /*String*/resourcePath
){
46 //summary: Internal xd loader function. Creates an xd module source given an
47 //non-xd module contents.
49 //Remove comments. Not perfect, but good enough for dependency resolution.
50 var depContents
= contents
.replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg , "");
54 var depRegExp
= /dojo.(require|requireIf|provide|requireAfterIf|platformRequire|requireLocalization)\s*\(([\w\W]*?)\)/mg;
56 while((match
= depRegExp
.exec(depContents
)) != null){
57 if(match
[1] == "requireLocalization"){
58 //Need to load the local bundles asap, since they are not
59 //part of the list of modules watched for loading.
62 deps
.push('"' + match
[1] + '", ' + match
[2]);
66 //Create resource object and the call to _xdResourceLoaded.
68 output
.push(dojo
._scopeName
+ "._xdResourceLoaded(function(" + dojo
._scopePrefixArgs
+ "){\n");
70 //See if there are any dojo.loadInit calls
71 var loadInitCalls
= dojo
._xdExtractLoadInits(contents
);
73 //Adjust fileContents since extractLoadInits removed something.
74 contents
= loadInitCalls
[0];
76 //Add any loadInit calls to the top of the xd file.
77 for(var i
= 1; i
< loadInitCalls
.length
; i
++){
78 output
.push(loadInitCalls
[i
] + ";\n");
82 output
.push("return {");
86 output
.push("depends: [");
87 for(i
= 0; i
< deps
.length
; i
++){
91 output
.push("[" + deps
[i
] + "]");
96 //Add the contents of the file inside a function.
97 //Pass in scope arguments so we can support multiple versions of the
98 //same module on a page.
99 output
.push("\ndefineResource: function(" + dojo
._scopePrefixArgs
+ "){");
101 //Don't put in the contents in the debugAtAllCosts case
102 //since the contents may have syntax errors. Let those
103 //get pushed up when the script tags are added to the page
104 //in the debugAtAllCosts case.
105 if(!dojo
.config
["debugAtAllCosts"] || resourceName
== "dojo._base._loader.loader_debug"){
106 output
.push(contents
);
108 //Add isLocal property so we know if we have to do something different
109 //in debugAtAllCosts situations.
110 output
.push("\n}, resourceName: '" + resourceName
+ "', resourcePath: '" + resourcePath
+ "'};});");
112 return output
.join(""); //String
115 dojo
._xdExtractLoadInits = function(/*String*/fileContents
){
117 var regexp
= /dojo.loadInit\s*\(/g;
118 regexp
.lastIndex
= 0;
120 var parenRe
= /[\(\)]/g;
121 parenRe
.lastIndex
= 0;
125 while((matches
= regexp
.exec(fileContents
))){
126 //Find end of the call by finding the matching end paren
127 parenRe
.lastIndex
= regexp
.lastIndex
;
130 while((parenMatch
= parenRe
.exec(fileContents
))){
131 if(parenMatch
[0] == ")"){
142 throw "unmatched paren around character " + parenRe
.lastIndex
+ " in: " + fileContents
;
145 //Put the master matching string in the results.
146 var startIndex
= regexp
.lastIndex
- matches
[0].length
;
147 results
.push(fileContents
.substring(startIndex
, parenRe
.lastIndex
));
149 //Remove the matching section.
150 var remLength
= parenRe
.lastIndex
- startIndex
;
151 fileContents
= fileContents
.substring(0, startIndex
) + fileContents
.substring(parenRe
.lastIndex
, fileContents
.length
);
153 //Move the master regexp past the last matching paren point.
154 regexp
.lastIndex
= parenRe
.lastIndex
- remLength
;
156 regexp
.lastIndex
= parenRe
.lastIndex
;
159 if(results
.length
> 0){
160 results
.unshift(fileContents
);
163 return (results
.length
? results
: null);
166 dojo
._xdIsXDomainPath = function(/*string*/relpath
) {
167 //summary: Figure out whether the path is local or x-domain
168 //If there is a colon before the first / then, we have a URL with a protocol.
170 var colonIndex
= relpath
.indexOf(":");
171 var slashIndex
= relpath
.indexOf("/");
173 if(colonIndex
> 0 && colonIndex
< slashIndex
|| relpath
.indexOf("//") === 0){
176 //Is the base script URI-based URL a cross domain URL?
177 //If so, then the relpath will be evaluated relative to
178 //baseUrl, and therefore qualify as xdomain.
179 //Only treat it as xdomain if the page does not have a
180 //host (file:// url), if the baseUrl does not match the
181 //current window's domain, or if the baseUrl starts with //.
182 //If baseUrl starts with // then it probably means that xdomain
183 //is wanted since it is such a specific path request. This is not completely robust,
184 //but something more robust would require normalizing the protocol on baseUrl and on the location
185 //to see if they differ. However, that requires more code, and // as a start path is unusual.
186 var url
= dojo
.baseUrl
;
187 colonIndex
= url
.indexOf(":");
188 slashIndex
= url
.indexOf("/");
189 if(url
.indexOf("//") === 0 || (colonIndex
> 0 && colonIndex
< slashIndex
&& (!location
.host
|| url
.indexOf("http://" + location
.host
) != 0))){
196 dojo
._loadPath = function(/*String*/relpath
, /*String?*/module
, /*Function?*/cb
){
197 //summary: Internal xd loader function. Overrides loadPath() from loader.js.
198 //xd loading requires slightly different behavior from loadPath().
200 var currentIsXDomain
= dojo
._xdIsXDomainPath(relpath
);
201 dojo
._isXDomain
|= currentIsXDomain
;
203 var uri
= ((relpath
.charAt(0) == '/' || relpath
.match(/^\w
+:/)) ? "" : dojo
.baseUrl
) + relpath
;
206 return ((!module
|| dojo
._isXDomain
) ? dojo
._loadUri(uri
, cb
, currentIsXDomain
, module
) : dojo
._loadUriAndCheck(uri
, module
, cb
)); //Boolean
209 return false; //Boolean
213 dojo
._xdCharSet
= "utf-8";
215 dojo
._loadUri = function(/*String*/uri
, /*Function?*/cb
, /*boolean*/currentIsXDomain
, /*String?*/module
){
216 //summary: Internal xd loader function. Overrides loadUri() from loader.js.
217 // xd loading requires slightly different behavior from loadPath().
218 //description: Wanted to override getText(), but it is used by
219 // the widget code in too many, synchronous ways right now.
220 if(dojo
._loadedUrls
[uri
]){
224 //Add the module (resource) to the list of modules.
225 //Only do this work if we have a modlue name. Otherwise,
226 //it is a non-xd i18n bundle, which can load immediately and does not
227 //need to be tracked. Also, don't track dojo.i18n, since it is a prerequisite
228 //and will be loaded correctly if we load it right away: it has no dependencies.
229 if(dojo
._isXDomain
&& module
&& module
!= "dojo.i18n"){
230 dojo
._xdOrderedReqs
.push(module
);
232 //Add to waiting resources if it is an xdomain resource.
233 //Don't add non-xdomain i18n bundles, those get evaled immediately.
234 if(currentIsXDomain
|| uri
.indexOf("/nls/") == -1){
235 dojo
._xdInFlight
[module
] = true;
237 //Increment inFlightCount
238 //This will stop the modulesLoaded from firing all the way.
239 dojo
._inFlightCount
++;
245 dojo
._xdTimer
= setInterval(function(){dojo
._xdWatchInFlight();}, 100);
247 dojo
._xdTimer
= setInterval(dojo
._scopeName
+ "._xdWatchInFlight();", 100);
250 dojo
._xdStartTime
= (new Date()).getTime();
253 if (currentIsXDomain
){
254 //Fix name to be a .xd.fileextension name.
255 var lastIndex
= uri
.lastIndexOf('.');
257 lastIndex
= uri
.length
- 1;
260 var xdUri
= uri
.substring(0, lastIndex
) + ".xd";
261 if(lastIndex
!= uri
.length
- 1){
262 xdUri
+= uri
.substring(lastIndex
, uri
.length
);
266 xdUri
= xdUri
.replace("app:/", "/");
270 var element
= document
.createElement("script");
271 element
.type
= "text/javascript";
273 element
.charset
= dojo
._xdCharSet
;
276 if(!dojo
.headElement
){
277 dojo
._headElement
= document
.getElementsByTagName("head")[0];
279 //Head element may not exist, particularly in html
280 //html 4 or tag soup cases where the page does not
281 //have a head tag in it. Use html element, since that will exist.
282 //Seems to be an issue mostly with Opera 9 and to lesser extent Safari 2
283 if(!dojo
._headElement
){
284 dojo
._headElement
= document
.getElementsByTagName("html")[0];
287 dojo
._headElement
.appendChild(element
);
289 var contents
= dojo
._getText(uri
, null, true);
290 if(contents
== null){ return 0; /*boolean*/}
292 //If this is not xdomain, or if loading a i18n resource bundle, then send it down
293 //the normal eval/callback path.
295 && uri
.indexOf("/nls/") == -1
296 && module
!= "dojo.i18n"){
297 var res
= dojo
._xdCreateResource(contents
, module
, uri
);
301 contents
= '('+contents
+')';
303 //Only do the scoping if no callback. If a callback is specified,
304 //it is most likely the i18n bundle stuff.
305 contents
= dojo
._scopePrefix
+ contents
+ dojo
._scopeSuffix
;
307 var value
= dojo
["eval"](contents
+"\r\n//@ sourceURL="+uri
);
314 //These steps are done in the non-xd loader version of this function.
315 //Maintain these steps to fit in with the existing system.
316 dojo
._loadedUrls
[uri
] = true;
317 dojo
._loadedUrls
.push(uri
);
318 return true; //Boolean
321 dojo
._xdResourceLoaded = function(/*Object*/res
){
322 //summary: Internal xd loader function. Called by an xd module resource when
323 //it has been loaded via a script tag.
325 //Evaluate the function with scopeArgs for multiversion support.
326 res
= res
.apply(dojo
.global
, dojo
._scopeArgs
);
328 //Work through dependencies.
329 var deps
= res
.depends
;
330 var requireList
= null;
331 var requireAfterList
= null;
332 var provideList
= [];
333 if(deps
&& deps
.length
> 0){
336 var attachedResource
= false;
337 for(var i
= 0; i
< deps
.length
; i
++){
340 //Look for specific dependency indicators.
341 if (dep
[0] == "provide"){
342 provideList
.push(dep
[1]);
347 if(!requireAfterList
){
348 requireAfterList
= [];
351 var unpackedDeps
= dojo
._xdUnpackDependency(dep
);
352 if(unpackedDeps
.requires
){
353 requireList
= requireList
.concat(unpackedDeps
.requires
);
355 if(unpackedDeps
.requiresAfter
){
356 requireAfterList
= requireAfterList
.concat(unpackedDeps
.requiresAfter
);
360 //Call the dependency indicator to allow for the normal dojo setup.
361 //Only allow for one dot reference, for the i18n._preloadLocalizations calls
362 //(and maybe future, one-dot things).
363 var depType
= dep
[0];
364 var objPath
= depType
.split(".");
365 if(objPath
.length
== 2){
366 dojo
[objPath
[0]][objPath
[1]].apply(dojo
[objPath
[0]], dep
.slice(1));
368 dojo
[depType
].apply(dojo
, dep
.slice(1));
373 //If loading the debugAtAllCosts module, eval it right away since we need
374 //its functions to properly load the other modules.
375 if(provideList
.length
== 1 && provideList
[0] == "dojo._base._loader.loader_debug"){
376 res
.defineResource(dojo
);
378 //Save off the resource contents for definition later.
379 var contentIndex
= dojo
._xdContents
.push({
380 content
: res
.defineResource
,
381 resourceName
: res
["resourceName"],
382 resourcePath
: res
["resourcePath"],
386 //Add provide/requires to dependency map.
387 for(i
= 0; i
< provideList
.length
; i
++){
388 dojo
._xdDepMap
[provideList
[i
]] = { requires
: requireList
, requiresAfter
: requireAfterList
, contentIndex
: contentIndex
};
392 //Now update the inflight status for any provided resources in this loaded resource.
393 //Do this at the very end (in a *separate* for loop) to avoid shutting down the
394 //inflight timer check too soon.
395 for(i
= 0; i
< provideList
.length
; i
++){
396 dojo
._xdInFlight
[provideList
[i
]] = false;
401 dojo
._xdLoadFlattenedBundle = function(/*String*/moduleName
, /*String*/bundleName
, /*String?*/locale
, /*Object*/bundleData
){
402 //summary: Internal xd loader function. Used when loading
403 //a flattened localized bundle via a script tag.
404 locale
= locale
|| "root";
405 var jsLoc
= dojo
.i18n
.normalizeLocale(locale
).replace('-', '_');
406 var bundleResource
= [moduleName
, "nls", bundleName
].join(".");
407 var bundle
= dojo
["provide"](bundleResource
);
408 bundle
[jsLoc
] = bundleData
;
410 //Assign the bundle for the original locale(s) we wanted.
411 var mapName
= [moduleName
, jsLoc
, bundleName
].join(".");
412 var bundleMap
= dojo
._xdBundleMap
[mapName
];
414 for(var param
in bundleMap
){
415 bundle
[param
] = bundleData
;
421 dojo
._xdInitExtraLocales = function(){
422 // Simulate the extra locale work that dojo.requireLocalization does.
424 var extra
= dojo
.config
.extraLocale
;
426 if(!extra
instanceof Array
){
430 dojo
._xdReqLoc
= dojo
.xdRequireLocalization
;
431 dojo
.xdRequireLocalization = function(m
, b
, locale
, fLocales
){
432 dojo
._xdReqLoc(m
,b
,locale
, fLocales
);
434 for(var i
=0; i
<extra
.length
; i
++){
435 dojo
._xdReqLoc(m
,b
,extra
[i
], fLocales
);
441 dojo
._xdBundleMap
= {};
443 dojo
.xdRequireLocalization = function(/*String*/moduleName
, /*String*/bundleName
, /*String?*/locale
, /*String*/availableFlatLocales
){
444 //summary: Internal xd loader function. The xd version of dojo.requireLocalization.
447 //Account for allowing multiple extra locales. Do this here inside the function
448 //since dojo._xdInitExtraLocales() depends on djConfig being set up, but that only
449 //happens after hostenv_browser runs. loader_xd has to come before hostenv_browser
450 //though since hostenv_browser can do a dojo.require for the debug module.
451 if(dojo
._xdInitExtraLocales
){
452 dojo
._xdInitExtraLocales();
453 dojo
._xdInitExtraLocales
= null;
454 dojo
.xdRequireLocalization
.apply(dojo
, arguments
);
458 var locales
= availableFlatLocales
.split(",");
460 //Find the best-match locale to load.
461 //Assumes dojo.i18n has already been loaded. This is true for xdomain builds,
462 //since it is included in dojo.xd.js.
463 var jsLoc
= dojo
.i18n
.normalizeLocale(locale
);
466 for(var i
= 0; i
< locales
.length
; i
++){
467 //Locale must match from start of string.
468 if(jsLoc
.indexOf(locales
[i
]) == 0){
469 if(locales
[i
].length
> bestLocale
.length
){
470 bestLocale
= locales
[i
];
475 var fixedBestLocale
= bestLocale
.replace('-', '_');
476 //See if the bundle we are going to use is already loaded.
477 var bundleResource
= dojo
.getObject([moduleName
, "nls", bundleName
].join("."));
478 if(!bundleResource
|| !bundleResource
[fixedBestLocale
]){
479 //Need to remember what locale we wanted and which one we actually use.
480 //Then when we load the one we are actually using, use that bundle for the one
481 //we originally wanted.
482 var mapName
= [moduleName
, (fixedBestLocale
||"root"), bundleName
].join(".");
483 var bundleMap
= dojo
._xdBundleMap
[mapName
];
485 bundleMap
= dojo
._xdBundleMap
[mapName
] = {};
487 bundleMap
[jsLoc
.replace('-', '_')] = true;
489 //Do just a normal dojo.require so the resource tracking stuff works as usual.
490 dojo
.require(moduleName
+ ".nls" + (bestLocale
? "." + bestLocale
: "") + "." + bundleName
);
494 // Replace dojo.requireLocalization with a wrapper
495 dojo
._xdRealRequireLocalization
= dojo
.requireLocalization
;
496 dojo
.requireLocalization = function(/*String*/moduleName
, /*String*/bundleName
, /*String?*/locale
, /*String*/availableFlatLocales
){
497 // summary: loads a bundle intelligently based on whether the module is
498 // local or xd. Overrides the local-case implementation.
500 var modulePath
= dojo
.moduleUrl(moduleName
).toString();
501 if (dojo
._xdIsXDomainPath(modulePath
)) {
502 // call cross-domain loader
503 return dojo
.xdRequireLocalization
.apply(dojo
, arguments
);
506 return dojo
._xdRealRequireLocalization
.apply(dojo
, arguments
);
510 //This is a bit brittle: it has to know about the dojo methods that deal with dependencies
511 //It would be ideal to intercept the actual methods and do something fancy at that point,
512 //but I have concern about knowing which provide to match to the dependency in that case,
513 //since scripts can load whenever they want, and trigger new calls to dojo._xdResourceLoaded().
514 dojo
._xdUnpackDependency = function(/*Array*/dep
){
515 //summary: Internal xd loader function. Determines what to do with a dependency
516 //that was listed in an xd version of a module contents.
518 //Extract the dependency(ies).
520 var newAfterDeps
= null;
523 case "requireAfterIf":
524 //First arg (dep[1]) is the test. Depedency is dep[2].
526 newDeps
= [{name
: dep
[2], content
: null}];
529 case "platformRequire":
531 var common
= modMap
["common"]||[];
532 newDeps
= (modMap
[dojo
.hostenv
.name_
]) ? common
.concat(modMap
[dojo
.hostenv
.name_
]||[]) : common
.concat(modMap
["default"]||[]);
533 //Flatten the array of arrays into a one-level deep array.
534 //Each result could be an array of 3 elements (the 3 arguments to dojo.require).
535 //We only need the first one.
537 for(var i
= 0; i
< newDeps
.length
; i
++){
538 if(newDeps
[i
] instanceof Array
){
539 newDeps
[i
] = {name
: newDeps
[i
][0], content
: null};
541 newDeps
[i
] = {name
: newDeps
[i
], content
: null};
547 //Just worry about dep[1]
548 newDeps
= [{name
: dep
[1], content
: null}];
550 case "i18n._preloadLocalizations":
551 //We can eval these immediately, since they load i18n bundles.
552 //Since i18n bundles have no dependencies, whenever they are loaded
553 //in a script tag, they are evaluated immediately, so we do not have to
554 //treat them has an explicit dependency for the dependency mapping.
555 //We can call it immediately since dojo.i18n is part of dojo.xd.js.
556 dojo
.i18n
._preloadLocalizations
.apply(dojo
.i18n
._preloadLocalizations
, dep
.slice(1));
560 //The requireIf and requireAfterIf needs to be evaluated after the current resource is evaluated.
561 if(dep
[0] == "requireAfterIf" || dep
[0] == "requireIf"){
562 newAfterDeps
= newDeps
;
565 return {requires
: newDeps
, requiresAfter
: newAfterDeps
}; //Object
568 dojo
._xdWalkReqs = function(){
569 //summary: Internal xd loader function.
570 //Walks the requires and evaluates module resource contents in
574 for(var i
= 0; i
< dojo
._xdOrderedReqs
.length
; i
++){
575 req
= dojo
._xdOrderedReqs
[i
];
576 if(dojo
._xdDepMap
[req
]){
578 reqChain
[req
] = true; //Allow for fast lookup of the req in the array
579 dojo
._xdEvalReqs(reqChain
);
584 dojo
._xdEvalReqs = function(/*Array*/reqChain
){
585 //summary: Internal xd loader function.
586 //Does a depth first, breadth second search and eval of required modules.
587 while(reqChain
.length
> 0){
588 var req
= reqChain
[reqChain
.length
- 1];
589 var res
= dojo
._xdDepMap
[req
];
590 var i
, reqs
, nextReq
;
592 //Trace down any requires for this resource.
593 //START dojo._xdTraceReqs() inlining for small Safari 2.0 call stack
595 if(reqs
&& reqs
.length
> 0){
596 for(i
= 0; i
< reqs
.length
; i
++){
597 nextReq
= reqs
[i
].name
;
598 if(nextReq
&& !reqChain
[nextReq
]){
599 //New req depedency. Follow it down.
600 reqChain
.push(nextReq
);
601 reqChain
[nextReq
] = true;
602 dojo
._xdEvalReqs(reqChain
);
606 //END dojo._xdTraceReqs() inlining for small Safari 2.0 call stack
608 //Evaluate the resource.
609 var contents
= dojo
._xdContents
[res
.contentIndex
];
610 if(!contents
.isDefined
){
611 var content
= contents
.content
;
612 content
["resourceName"] = contents
["resourceName"];
613 content
["resourcePath"] = contents
["resourcePath"];
614 dojo
._xdDefList
.push(content
);
615 contents
.isDefined
= true;
617 dojo
._xdDepMap
[req
] = null;
619 //Trace down any requireAfters for this resource.
620 //START dojo._xdTraceReqs() inlining for small Safari 2.0 call stack
621 reqs
= res
.requiresAfter
;
622 if(reqs
&& reqs
.length
> 0){
623 for(i
= 0; i
< reqs
.length
; i
++){
624 nextReq
= reqs
[i
].name
;
625 if(nextReq
&& !reqChain
[nextReq
]){
626 //New req depedency. Follow it down.
627 reqChain
.push(nextReq
);
628 reqChain
[nextReq
] = true;
629 dojo
._xdEvalReqs(reqChain
);
633 //END dojo._xdTraceReqs() inlining for small Safari 2.0 call stack
636 //Done with that require. Remove it and go to the next one.
641 dojo
._xdWatchInFlight = function(){
642 //summary: Internal xd loader function.
643 //Monitors in-flight requests for xd module resources.
646 var waitInterval
= (dojo
.config
.xdWaitSeconds
|| 15) * 1000;
647 var expired
= (dojo
._xdStartTime
+ waitInterval
) < (new Date()).getTime();
649 //If any xdInFlight are true, then still waiting for something to load.
650 //Come back later. If we timed out, report the things that did not load.
651 for(var param
in dojo
._xdInFlight
){
652 if(dojo
._xdInFlight
[param
] === true){
654 noLoads
+= param
+ " ";
661 //All done. Clean up and notify.
662 dojo
._xdClearInterval();
665 throw "Could not load cross-domain resources: " + noLoads
;
670 var defLength
= dojo
._xdDefList
.length
;
671 for(var i
= 0; i
< defLength
; i
++){
672 var content
= dojo
._xdDefList
[i
];
673 if(dojo
.config
["debugAtAllCosts"] && content
["resourceName"]){
674 if(!dojo
["_xdDebugQueue"]){
675 dojo
._xdDebugQueue
= [];
677 dojo
._xdDebugQueue
.push({resourceName
: content
.resourceName
, resourcePath
: content
.resourcePath
});
679 //Evaluate the resource to bring it into being.
680 //Pass in scope args to allow multiple versions of modules in a page.
681 content
.apply(dojo
.global
, dojo
._scopeArgs
);
685 //Evaluate any resources that were not evaled before.
686 //This normally shouldn't happen with proper dojo.provide and dojo.require
687 //usage, but providing it just in case. Note that these may not be executed
688 //in the original order that the developer intended.
689 for(i
= 0; i
< dojo
._xdContents
.length
; i
++){
690 var current
= dojo
._xdContents
[i
];
691 if(current
.content
&& !current
.isDefined
){
692 //Pass in scope args to allow multiple versions of modules in a page.
693 current
.content
.apply(dojo
.global
, dojo
._scopeArgs
);
697 //Clean up for the next round of xd loading.
700 if(dojo
["_xdDebugQueue"] && dojo
._xdDebugQueue
.length
> 0){
701 dojo
._xdDebugFileLoaded();
703 dojo
._xdNotifyLoaded();
707 dojo
._xdNotifyLoaded = function(){
708 //Clear inflight count so we will finally do finish work.
710 //Just having a legitimate status (true or false) for an inflight item
711 //means that it is still being processed. Do the typeof test
712 //to avoid bad JavaScript that might tinker with Object.prototype.
713 for(var prop
in dojo
._xdInFlight
){
714 if(typeof dojo
._xdInFlight
[prop
] == "boolean"){
719 dojo
._inFlightCount
= 0;
721 //Only trigger call loaded if dj_load_init has run.
722 if(dojo
._initFired
&& !dojo
._loadNotifying
){