Improve output: distinguish between failed assertions (failures) and unexpected exceptions (errors), and print a filtered stack trace for any exception.
This commit is contained in:
commit
4f2e303079
1839 changed files with 235630 additions and 0 deletions
414
webapp/web/src/loader_xd.js
Normal file
414
webapp/web/src/loader_xd.js
Normal file
|
@ -0,0 +1,414 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
//Cross-domain package loader.
|
||||
|
||||
//FIXME: How will xd loading work with debugAtAllCosts? Any bad interactions?
|
||||
//FIXME: widgets won't work fully (HTML/CSS) and also because of the requireIf() thing.
|
||||
|
||||
dojo.hostenv.resetXd = function(){
|
||||
//This flag indicates where or not we have crossed into xdomain territory. Once any package says
|
||||
//it is cross domain, then the rest of the packages have to be treated as xdomain because we need
|
||||
//to evaluate packages in order. If there is a xdomain package followed by a xhr package, we can't load
|
||||
//the xhr package until the one before it finishes loading. The text of the xhr package will be converted
|
||||
//to match the format for a xd package and put in the xd load queue.
|
||||
//You can force all packages to be treated as xd by setting the djConfig.forceXDomain.
|
||||
this.isXDomain = djConfig.forceXDomain || false;
|
||||
|
||||
this.xdTimer = 0;
|
||||
this.xdInFlight = {};
|
||||
this.xdOrderedReqs = [];
|
||||
this.xdDepMap = {};
|
||||
this.xdContents = [];
|
||||
}
|
||||
|
||||
//Call reset immediately to set the state.
|
||||
dojo.hostenv.resetXd();
|
||||
|
||||
dojo.hostenv.createXdPackage = function(contents){
|
||||
//Find dependencies.
|
||||
var deps = [];
|
||||
var depRegExp = /dojo.(require|requireIf|requireAll|provide|requireAfterIf|requireAfter|kwCompoundRequire|conditionalRequire|hostenv\.conditionalLoadModule|.hostenv\.loadModule|hostenv\.moduleLoaded)\(([\w\W]*?)\)/mg;
|
||||
var match;
|
||||
while((match = depRegExp.exec(contents)) != null){
|
||||
deps.push("\"" + match[1] + "\", " + match[2]);
|
||||
}
|
||||
|
||||
//Create package object and the call to packageLoaded.
|
||||
var output = [];
|
||||
output.push("dojo.hostenv.packageLoaded({\n");
|
||||
|
||||
//Add dependencies
|
||||
if(deps.length > 0){
|
||||
output.push("depends: [");
|
||||
for(var i = 0; i < deps.length; i++){
|
||||
if(i > 0){
|
||||
output.push(",\n");
|
||||
}
|
||||
output.push("[" + deps[i] + "]");
|
||||
}
|
||||
output.push("],");
|
||||
}
|
||||
|
||||
//Add the contents of the file inside a function.
|
||||
//Pass in dojo as an argument to the function to help with
|
||||
//allowing multiple versions of dojo in a page.
|
||||
output.push("\ndefinePackage: function(dojo){");
|
||||
output.push(contents);
|
||||
output.push("\n}});");
|
||||
|
||||
return output.join("");
|
||||
}
|
||||
|
||||
dojo.hostenv.loadPath = function(relpath, module /*optional*/, cb /*optional*/){
|
||||
//Only do getBaseScriptUri if path does not start with a URL with a protocol.
|
||||
//If there is a colon before the first / then, we have a URL with a protocol.
|
||||
var colonIndex = relpath.indexOf(":");
|
||||
var slashIndex = relpath.indexOf("/");
|
||||
var uri;
|
||||
var currentIsXDomain = false;
|
||||
if(colonIndex > 0 && colonIndex < slashIndex){
|
||||
uri = relpath;
|
||||
this.isXDomain = currentIsXDomain = true;
|
||||
}else{
|
||||
uri = this.getBaseScriptUri() + relpath;
|
||||
|
||||
//Is ithe base script URI-based URL a cross domain URL?
|
||||
colonIndex = uri.indexOf(":");
|
||||
slashIndex = uri.indexOf("/");
|
||||
if(colonIndex > 0 && colonIndex < slashIndex && (!location.host || uri.indexOf("http://" + location.host) != 0)){
|
||||
this.isXDomain = currentIsXDomain = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(djConfig.cacheBust && dojo.render.html.capable) { uri += "?" + String(djConfig.cacheBust).replace(/\W+/g,""); }
|
||||
try{
|
||||
return ((!module || this.isXDomain) ? this.loadUri(uri, cb, currentIsXDomain, module) : this.loadUriAndCheck(uri, module, cb));
|
||||
}catch(e){
|
||||
dojo.debug(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//Overriding loadUri for now. Wanted to override getText(), but it is used by
|
||||
//the widget code in too many, synchronous ways right now. This means the xd stuff
|
||||
//is not suitable for widgets yet.
|
||||
dojo.hostenv.loadUri = function(uri, cb, currentIsXDomain, module){
|
||||
if(this.loadedUris[uri]){
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Add the module (package) to the list of modules.
|
||||
if(this.isXDomain){
|
||||
//Curious: is this array going to get whacked with multiple access since scripts
|
||||
//load asynchronously and may be accessing the array at the same time?
|
||||
//JS is single-threaded supposedly, so it should be ok. And we don't need
|
||||
//a precise ordering.
|
||||
this.xdOrderedReqs.push(module);
|
||||
|
||||
//Add to waiting packages.
|
||||
//If this is a __package__.js file, then this must be
|
||||
//a package.* request (since xdomain can only work with the first
|
||||
//path in a package search list. However, .* module names are not
|
||||
//passed to this function, so do an adjustment here.
|
||||
if(uri.indexOf("__package__") != -1){
|
||||
module += ".*";
|
||||
}
|
||||
|
||||
this.xdInFlight[module] = true;
|
||||
|
||||
//Increment inFlightCount
|
||||
//This will stop the modulesLoaded from firing all the way.
|
||||
this.inFlightCount++;
|
||||
|
||||
//Start timer
|
||||
if(!this.xdTimer){
|
||||
this.xdTimer = setInterval("dojo.hostenv.watchInFlightXDomain();", 100);
|
||||
}
|
||||
this.xdStartTime = (new Date()).getTime();
|
||||
}
|
||||
|
||||
if (currentIsXDomain){
|
||||
//Fix name to be a .xd.fileextension name.
|
||||
var lastIndex = uri.lastIndexOf('.');
|
||||
if(lastIndex <= 0){
|
||||
lastIndex = uri.length - 1;
|
||||
}
|
||||
|
||||
var xdUri = uri.substring(0, lastIndex) + ".xd";
|
||||
if(lastIndex != uri.length - 1){
|
||||
xdUri += uri.substring(lastIndex, uri.length);
|
||||
}
|
||||
|
||||
//Add to script src
|
||||
var element = document.createElement("script");
|
||||
element.type = "text/javascript";
|
||||
element.src = xdUri;
|
||||
if(!this.headElement){
|
||||
this.headElement = document.getElementsByTagName("head")[0];
|
||||
}
|
||||
this.headElement.appendChild(element);
|
||||
}else{
|
||||
var contents = this.getText(uri, null, true);
|
||||
if(contents == null){ return 0; }
|
||||
|
||||
if(this.isXDomain){
|
||||
var pkg = this.createXdPackage(contents);
|
||||
dj_eval(pkg);
|
||||
}else{
|
||||
if(cb){ contents = '('+contents+')'; }
|
||||
var value = dj_eval(contents);
|
||||
if(cb){
|
||||
cb(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//These steps are done in the non-xd loader version of this function.
|
||||
//Maintain these steps to fit in with the existing system.
|
||||
this.loadedUris[uri] = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
dojo.hostenv.packageLoaded = function(pkg){
|
||||
var deps = pkg.depends;
|
||||
var requireList = null;
|
||||
var requireAfterList = null;
|
||||
var provideList = [];
|
||||
if(deps && deps.length > 0){
|
||||
var dep = null;
|
||||
var insertHint = 0;
|
||||
var attachedPackage = false;
|
||||
for(var i = 0; i < deps.length; i++){
|
||||
dep = deps[i];
|
||||
|
||||
//Look for specific dependency indicators.
|
||||
if (dep[0] == "provide" || dep[0] == "hostenv.moduleLoaded"){
|
||||
provideList.push(dep[1]);
|
||||
}else{
|
||||
if(!requireList){
|
||||
requireList = [];
|
||||
}
|
||||
if(!requireAfterList){
|
||||
requireAfterList = [];
|
||||
}
|
||||
|
||||
var unpackedDeps = this.unpackXdDependency(dep);
|
||||
if(unpackedDeps.requires){
|
||||
requireList = requireList.concat(unpackedDeps.requires);
|
||||
}
|
||||
if(unpackedDeps.requiresAfter){
|
||||
requireAfterList = requireAfterList.concat(unpackedDeps.requiresAfter);
|
||||
}
|
||||
}
|
||||
|
||||
//Call the dependency indicator to allow for the normal dojo setup.
|
||||
//Only allow for one dot reference, for the hostenv.* type calls.
|
||||
var depType = dep[0];
|
||||
var objPath = depType.split(".");
|
||||
if(objPath.length == 2){
|
||||
dojo[objPath[0]][objPath[1]].apply(dojo[objPath[0]], dep.slice(1));
|
||||
}else{
|
||||
dojo[depType].apply(dojo, dep.slice(1));
|
||||
}
|
||||
}
|
||||
|
||||
//Save off the package contents for definition later.
|
||||
var contentIndex = this.xdContents.push({content: pkg.definePackage, isDefined: false}) - 1;
|
||||
|
||||
//Add provide/requires to dependency map.
|
||||
for(var i = 0; i < provideList.length; i++){
|
||||
this.xdDepMap[provideList[i]] = { requires: requireList, requiresAfter: requireAfterList, contentIndex: contentIndex };
|
||||
}
|
||||
|
||||
//Now update the inflight status for any provided packages in this loaded package.
|
||||
//Do this at the very end (in a *separate* for loop) to avoid shutting down the
|
||||
//inflight timer check too soon.
|
||||
for(var i = 0; i < provideList.length; i++){
|
||||
this.xdInFlight[provideList[i]] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//This is a bit brittle: it has to know about the dojo methods that deal with dependencies
|
||||
//It would be ideal to intercept the actual methods and do something fancy at that point,
|
||||
//but I have concern about knowing which provide to match to the dependency in that case,
|
||||
//since scripts can load whenever they want, and trigger new calls to dojo.hostenv.packageLoaded().
|
||||
dojo.hostenv.unpackXdDependency = function(dep){
|
||||
//Extract the dependency(ies).
|
||||
var newDeps = null;
|
||||
var newAfterDeps = null;
|
||||
switch(dep[0]){
|
||||
case "requireIf":
|
||||
case "requireAfterIf":
|
||||
case "conditionalRequire":
|
||||
//First arg (dep[1]) is the test. Depedency is dep[2].
|
||||
if((dep[1] === true)||(dep[1]=="common")||(dep[1] && dojo.render[dep[1]].capable)){
|
||||
newDeps = [{name: dep[2], content: null}];
|
||||
}
|
||||
break;
|
||||
case "requireAll":
|
||||
//the arguments are an array, each element a call to require.
|
||||
//Get rid of first item, which is "requireAll".
|
||||
dep.shift();
|
||||
newDeps = dep;
|
||||
dojo.hostenv.flattenRequireArray(newDeps);
|
||||
break;
|
||||
case "kwCompoundRequire":
|
||||
case "hostenv.conditionalLoadModule":
|
||||
var modMap = dep[1];
|
||||
var common = modMap["common"]||[];
|
||||
var newDeps = (modMap[dojo.hostenv.name_]) ? common.concat(modMap[dojo.hostenv.name_]||[]) : common.concat(modMap["default"]||[]);
|
||||
dojo.hostenv.flattenRequireArray(newDeps);
|
||||
break;
|
||||
case "require":
|
||||
case "requireAfter":
|
||||
case "hostenv.loadModule":
|
||||
//Just worry about dep[1]
|
||||
newDeps = [{name: dep[1], content: null}];
|
||||
break;
|
||||
}
|
||||
|
||||
//The requireAfterIf or requireAfter needs to be evaluated after the current package is evaluated.
|
||||
if(dep[0] == "requireAfterIf"){
|
||||
newAfterDeps = newDeps;
|
||||
newDeps = null;
|
||||
}
|
||||
return {requires: newDeps, requiresAfter: newAfterDeps};
|
||||
}
|
||||
|
||||
//Walks the requires and evaluates package contents in
|
||||
//the right order.
|
||||
dojo.hostenv.xdWalkReqs = function(){
|
||||
var reqChain = null;
|
||||
var req;
|
||||
for(var i = 0; i < this.xdOrderedReqs.length; i++){
|
||||
req = this.xdOrderedReqs[i];
|
||||
if(this.xdDepMap[req]){
|
||||
reqChain = [req];
|
||||
reqChain[req] = true; //Allow for fast lookup of the req in the array
|
||||
this.xdEvalReqs(reqChain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Trace down any requires.
|
||||
dojo.hostenv.xdTraceReqs = function(reqs, reqChain){
|
||||
if(reqs && reqs.length > 0){
|
||||
var nextReq;
|
||||
for(var i = 0; i < reqs.length; i++){
|
||||
nextReq = reqs[i].name;
|
||||
if(nextReq && !reqChain[nextReq]){
|
||||
//New req depedency. Follow it down.
|
||||
reqChain.push(nextReq);
|
||||
reqChain[nextReq] = true;
|
||||
this.xdEvalReqs(reqChain);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Do a depth first, breadth second search and eval or reqs.
|
||||
dojo.hostenv.xdEvalReqs = function(reqChain){
|
||||
if(reqChain.length > 0){
|
||||
var req = reqChain[reqChain.length - 1];
|
||||
var pkg = this.xdDepMap[req];
|
||||
if(pkg){
|
||||
//Trace down any requires for this package.
|
||||
this.xdTraceReqs(pkg.requires, reqChain);
|
||||
|
||||
//Evaluate the package.
|
||||
var contents = this.xdContents[pkg.contentIndex];
|
||||
if(!contents.isDefined){
|
||||
//Evaluate the package to bring it into being.
|
||||
//Pass dojo in so that later, to support multiple versions of dojo
|
||||
//in a page, we can pass which version of dojo to use.
|
||||
contents.content(dojo);
|
||||
contents.isDefined = true;
|
||||
}
|
||||
this.xdDepMap[req] = null;
|
||||
|
||||
//Trace down any requireAfters for this package..
|
||||
this.xdTraceReqs(pkg.requiresAfter, reqChain);
|
||||
}
|
||||
|
||||
//Done with that require. Remove it and go to the next one.
|
||||
reqChain.pop();
|
||||
this.xdEvalReqs(reqChain);
|
||||
}
|
||||
}
|
||||
|
||||
dojo.hostenv.clearXdInterval = function(){
|
||||
clearInterval(this.xdTimer);
|
||||
this.xdTimer = 0;
|
||||
}
|
||||
|
||||
dojo.hostenv.watchInFlightXDomain = function(){
|
||||
//Make sure we haven't waited timed out.
|
||||
var waitInterval = (djConfig.xdWaitSeconds || 30) * 1000;
|
||||
|
||||
if(this.xdStartTime + waitInterval < (new Date()).getTime()){
|
||||
this.clearXdInterval();
|
||||
var noLoads = "";
|
||||
for(var param in this.xdInFlight){
|
||||
if(this.xdInFlight[param]){
|
||||
noLoads += param + " ";
|
||||
}
|
||||
}
|
||||
dojo.raise("Could not load cross-domain packages: " + noLoads);
|
||||
}
|
||||
|
||||
//If any are true, then still waiting.
|
||||
//Come back later.
|
||||
for(var param in this.xdInFlight){
|
||||
if(this.xdInFlight[param]){
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//All done loading. Clean up and notify that we are loaded.
|
||||
this.clearXdInterval();
|
||||
|
||||
this.xdWalkReqs();
|
||||
|
||||
//Evaluate any packages that were not evaled before.
|
||||
//This normally shouldn't happen with proper dojo.provide and dojo.require
|
||||
//usage, but providing it just in case. Note that these may not be executed
|
||||
//in the original order that the developer intended.
|
||||
//Pass dojo in so that later, to support multiple versions of dojo
|
||||
//in a page, we can pass which version of dojo to use.
|
||||
for(var i = 0; i < this.xdContents.length; i++){
|
||||
var current = this.xdContents[i];
|
||||
if(current.content && !current.isDefined){
|
||||
current.content(dojo);
|
||||
}
|
||||
}
|
||||
|
||||
//Clean up for the next round of xd loading.
|
||||
this.resetXd();
|
||||
|
||||
//Clear inflight count so we will finally do finish work.
|
||||
this.inFlightCount = 0;
|
||||
this.callLoaded();
|
||||
}
|
||||
|
||||
dojo.hostenv.flattenRequireArray = function(target){
|
||||
//Each result could be an array of 3 elements (the 3 arguments to dojo.require).
|
||||
//We only need the first one.
|
||||
if(target){
|
||||
for(var i = 0; i < target.length; i++){
|
||||
if(target[i] instanceof Array){
|
||||
target[i] = {name: target[i][0], content: null};
|
||||
}else{
|
||||
target[i] = {name: target[i], content: null};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue