| /* |
| 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 |
| */ |
| |
| /* |
| * Adobe SVG Viewer host environment |
| */ |
| if(typeof window == 'undefined'){ |
| dojo.raise("attempt to use adobe svg hostenv when no window object"); |
| } |
| |
| with(dojo.render){ |
| name = navigator.appName; |
| ver = parseFloat(navigator.appVersion, 10); |
| switch(navigator.platform){ |
| case "MacOS": |
| os.osx = true; |
| break; |
| case "Linux": |
| os.linux = true; |
| break; |
| case "Windows": |
| os.win = true; |
| break; |
| default: |
| os.linux = true; |
| break; |
| }; |
| svg.capable = true; |
| svg.support.builtin = true; |
| svg.adobe = true; |
| }; |
| |
| // browserEval("alert(window.location);"); |
| |
| dojo.hostenv.println = function(s){ |
| try{ |
| // FIXME: this may not work with adobe's viewer, as we may first need a |
| // reference to the svgDocument |
| // FIXME: need a way to determine where to position the text for this |
| var ti = document.createElement("text"); |
| ti.setAttribute("x","50"); |
| var yPos = 25 + 15*document.getElementsByTagName("text").length; |
| ti.setAttribute("y",yPos); |
| var tn = document.createTextNode(s); |
| ti.appendChild(tn); |
| document.documentElement.appendChild(ti); |
| }catch(e){ |
| |
| } |
| } |
| |
| dojo.debug = function() { |
| if (!djConfig.isDebug) { return; } |
| var args = arguments; |
| if(typeof dojo.hostenv.println != 'function'){ |
| dojo.raise("attempt to call dojo.debug when there is no dojo.hostenv println implementation (yet?)"); |
| } |
| var isJUM = dj_global["jum"]; |
| var s = isJUM ? "": "DEBUG: "; |
| for(var i=0;i<args.length;++i){ s += args[i]; } |
| if(isJUM){ // this seems to be the only way to get JUM to "play nice" |
| jum.debug(s); |
| }else{ |
| dojo.hostenv.println(s); |
| } |
| } |
| |
| dojo.hostenv.startPackage("dojo.hostenv"); |
| |
| dojo.hostenv.name_ = 'adobesvg'; |
| |
| dojo.hostenv.anonCtr = 0; |
| dojo.hostenv.anon = {}; |
| |
| dojo.hostenv.nameAnonFunc = function(anonFuncPtr, namespaceObj){ |
| var ret = "_"+this.anonCtr++; |
| var nso = (namespaceObj || this.anon); |
| while(typeof nso[ret] != "undefined"){ |
| ret = "_"+this.anonCtr++; |
| } |
| nso[ret] = anonFuncPtr; |
| return ret; |
| } |
| |
| dojo.hostenv.modulesLoadedFired = false; |
| dojo.hostenv.modulesLoadedListeners = []; |
| dojo.hostenv.getTextStack = []; |
| dojo.hostenv.loadUriStack = []; |
| dojo.hostenv.loadedUris = []; |
| |
| |
| dojo.hostenv.modulesLoaded = function(){ |
| if(this.modulesLoadedFired){ return; } |
| if((this.loadUriStack.length==0)&&(this.getTextStack.length==0)){ |
| if(this.inFlightCount > 0){ |
| dojo.debug("couldn't initialize, there are files still in flight"); |
| return; |
| } |
| this.modulesLoadedFired = true; |
| var mll = this.modulesLoadedListeners; |
| for(var x=0; x<mll.length; x++){ |
| mll[x](); |
| } |
| } |
| } |
| |
| dojo.hostenv.getNewAnonFunc = function(){ |
| var ret = "_"+this.anonCtr++; |
| while(typeof this.anon[ret] != "undefined"){ |
| ret = "_"+this.anonCtr++; |
| } |
| // this.anon[ret] = function(){}; |
| eval("dojo.nostenv.anon."+ret+" = function(){};"); |
| return [ret, this.anon[ret]]; |
| } |
| |
| dojo.hostenv.displayStack = function(){ |
| var oa = []; |
| var stack = this.loadUriStack; |
| for(var x=0; x<stack.length; x++){ |
| oa.unshift([stack[x][0], (typeof stack[x][2])]); |
| } |
| dojo.debug("<pre>"+oa.join("\n")+"</pre>"); |
| } |
| |
| dojo.hostenv.unwindUriStack = function(){ |
| var stack = this.loadUriStack; |
| for(var x in dojo.hostenv.loadedUris){ |
| for(var y=stack.length-1; y>=0; y--){ |
| if(stack[y][0]==x){ |
| stack.splice(y, 1); |
| } |
| } |
| } |
| var next = stack.pop(); |
| if((!next)&&(stack.length==0)){ |
| return; |
| } |
| for(var x=0; x<stack.length; x++){ |
| if((stack[x][0]==next[0])&&(stack[x][2])){ |
| next[2] == stack[x][2] |
| } |
| } |
| var last = next; |
| while(dojo.hostenv.loadedUris[next[0]]){ |
| last = next; |
| next = stack.pop(); |
| } |
| while(typeof next[2] == "string"){ // unwind as far as we can |
| try{ |
| // dojo.debug("<pre><![CDATA["+next[2]+"]]></pre>"); |
| dj_eval(next[2]); |
| next[1](true); |
| }catch(e){ |
| dojo.debug("we got an error when loading "+next[0]); |
| dojo.debug("error: "+e); |
| // for(var x in e){ alert(x+" "+e[x]); } |
| } |
| dojo.hostenv.loadedUris[next[0]] = true; |
| dojo.hostenv.loadedUris.push(next[0]); |
| last = next; |
| next = stack.pop(); |
| if((!next)&&(stack.length==0)){ break; } |
| while(dojo.hostenv.loadedUris[next[0]]){ |
| last = next; |
| next = stack.pop(); |
| } |
| } |
| if(next){ |
| stack.push(next); |
| dojo.debug("### CHOKED ON: "+next[0]); |
| } |
| } |
| |
| /** |
| * Reads the contents of the URI, and evaluates the contents. |
| * Returns true if it succeeded. Returns false if the URI reading failed. Throws if the evaluation throws. |
| * The result of the eval is not available to the caller. |
| */ |
| dojo.hostenv.loadUri = function(uri, cb){ |
| if(dojo.hostenv.loadedUris[uri]){ |
| return; |
| } |
| var stack = this.loadUriStack; |
| stack.push([uri, cb, null]); |
| var tcb = function(contents){ |
| // gratuitous hack for Adobe SVG 3 |
| if(contents.content){ |
| contents = contents.content; |
| } |
| |
| // stack management |
| var next = stack.pop(); |
| if((!next)&&(stack.length==0)){ |
| dojo.hostenv.modulesLoaded(); |
| return; |
| } |
| if(typeof contents == "string"){ |
| stack.push(next); |
| for(var x=0; x<stack.length; x++){ |
| if(stack[x][0]==uri){ |
| stack[x][2] = contents; |
| } |
| } |
| next = stack.pop(); |
| } |
| if(dojo.hostenv.loadedUris[next[0]]){ |
| // dojo.debug("WE ALREADY HAD: "+next[0]); |
| dojo.hostenv.unwindUriStack(); |
| return; |
| } |
| // push back onto stack |
| stack.push(next); |
| if(next[0]!=uri){ |
| // and then unwind as far as we can |
| if(typeof next[2] == "string"){ |
| dojo.hostenv.unwindUriStack(); |
| } |
| |
| }else{ |
| if(!contents){ |
| next[1](false); |
| }else{ |
| var deps = dojo.hostenv.getDepsForEval(next[2]); |
| if(deps.length>0){ |
| eval(deps.join(";")); |
| }else{ |
| dojo.hostenv.unwindUriStack(); |
| } |
| } |
| } |
| } |
| this.getText(uri, tcb, true); |
| } |
| |
| /** |
| * loadModule("A.B") first checks to see if symbol A.B is defined. |
| * If it is, it is simply returned (nothing to do). |
| * If it is not defined, it will look for "A/B.js" in the script root directory, followed |
| * by "A.js". |
| * It throws if it cannot find a file to load, or if the symbol A.B is not defined after loading. |
| * It returns the object A.B. |
| * |
| * This does nothing about importing symbols into the current package. |
| * It is presumed that the caller will take care of that. For example, to import |
| * all symbols: |
| * |
| * with (dojo.hostenv.loadModule("A.B")) { |
| * ... |
| * } |
| * |
| * And to import just the leaf symbol: |
| * |
| * var B = dojo.hostenv.loadModule("A.B"); |
| * ... |
| * |
| * dj_load is an alias for dojo.hostenv.loadModule |
| */ |
| dojo.hostenv.loadModule = function(modulename, exact_only, omit_module_check){ |
| // alert("dojo.hostenv.loadModule('"+modulename+"');"); |
| var module = this.findModule(modulename, 0); |
| if(module){ |
| return module; |
| } |
| |
| // dojo.debug("dojo.hostenv.loadModule('"+modulename+"');"); |
| |
| // protect against infinite recursion from mutual dependencies |
| if (typeof this.loading_modules_[modulename] !== 'undefined'){ |
| // NOTE: this should never throw an exception!! "recursive" includes |
| // are normal in the course of app and module building, so blow out of |
| // it gracefully, but log it in debug mode |
| |
| // dojo.raise("recursive attempt to load module '" + modulename + "'"); |
| dojo.debug("recursive attempt to load module '" + modulename + "'"); |
| }else{ |
| this.addedToLoadingCount.push(modulename); |
| } |
| this.loading_modules_[modulename] = 1; |
| |
| |
| // convert periods to slashes |
| var relpath = modulename.replace(/\./g, '/') + '.js'; |
| |
| var syms = modulename.split("."); |
| var nsyms = modulename.split("."); |
| if(syms[0]=="dojo"){ // FIXME: need a smarter way to do this! |
| syms[0] = "src"; |
| } |
| var last = syms.pop(); |
| syms.push(last); |
| // figure out if we're looking for a full package, if so, we want to do |
| // things slightly diffrently |
| var _this = this; |
| var pfn = this.pkgFileName; |
| if(last=="*"){ |
| modulename = (nsyms.slice(0, -1)).join('.'); |
| |
| var module = this.findModule(modulename, 0); |
| // dojo.debug("found: "+modulename+"="+module); |
| if(module){ |
| _this.removedFromLoadingCount.push(modulename); |
| return module; |
| } |
| |
| var nextTry = function(lastStatus){ |
| if(lastStatus){ |
| module = _this.findModule(modulename, false); // pass in false so we can give better error |
| if((!module)&&(syms[syms.length-1]!=pfn)){ |
| dojo.raise("Module symbol '" + modulename + "' is not defined after loading '" + relpath + "'"); |
| } |
| if(module){ |
| _this.removedFromLoadingCount.push(modulename); |
| dojo.hostenv.modulesLoaded(); |
| return; |
| } |
| } |
| syms.pop(); |
| syms.push(pfn); |
| // dojo.debug("syms: "+syms); |
| relpath = syms.join("/") + '.js'; |
| if(relpath.charAt(0)=="/"){ |
| relpath = relpath.slice(1); |
| } |
| // dojo.debug("relpath: "+relpath); |
| _this.loadPath(relpath, ((!omit_module_check) ? modulename : null), nextTry); |
| } |
| |
| nextTry(); |
| }else{ |
| relpath = syms.join("/") + '.js'; |
| modulename = nsyms.join('.'); |
| |
| var nextTry = function(lastStatus){ |
| // dojo.debug("lastStatus: "+lastStatus); |
| if(lastStatus){ |
| // dojo.debug("inital relpath: "+relpath); |
| module = _this.findModule(modulename, false); // pass in false so we can give better error |
| // if(!module){ |
| if((!module)&&(syms[syms.length-1]!=pfn)){ |
| dojo.raise("Module symbol '" + modulename + "' is not defined after loading '" + relpath + "'"); |
| } |
| if(module){ |
| _this.removedFromLoadingCount.push(modulename); |
| dojo.hostenv.modulesLoaded(); |
| return; |
| } |
| } |
| var setPKG = (syms[syms.length-1]==pfn) ? false : true; |
| syms.pop(); |
| if(setPKG){ |
| syms.push(pfn); |
| } |
| relpath = syms.join("/") + '.js'; |
| if(relpath.charAt(0)=="/"){ |
| relpath = relpath.slice(1); |
| } |
| // dojo.debug("relpath: "+relpath); |
| _this.loadPath(relpath, ((!omit_module_check) ? modulename : null), nextTry); |
| } |
| |
| this.loadPath(relpath, ((!omit_module_check) ? modulename : null), nextTry); |
| } |
| return; |
| } |
| |
| /** |
| * Read the contents of the specified uri and return those contents. |
| * |
| * FIXME: Make sure this is consistent with other implementations of getText |
| * @param uri A relative or absolute uri. If absolute, it still must be in the same "domain" as we are. |
| * @param async_cb If not specified, returns false as synchronous is not |
| * supported. If specified, load asynchronously, and use async_cb as the handler which receives the result of the request. |
| * @param fail_ok Default false. If fail_ok and !async_cb and loading fails, return null instead of throwing. |
| */ |
| dojo.hostenv.async_cb = null; |
| |
| dojo.hostenv.unWindGetTextStack = function(){ |
| if(dojo.hostenv.inFlightCount>0){ |
| setTimeout("dojo.hostenv.unWindGetTextStack()", 100); |
| return; |
| } |
| // we serialize because this environment is too messed up |
| // to know how to do anything else |
| dojo.hostenv.inFlightCount++; |
| var next = dojo.hostenv.getTextStack.pop(); |
| if((!next)&&(dojo.hostenv.getTextStack.length==0)){ |
| dojo.hostenv.inFlightCount--; |
| dojo.hostenv.async_cb = function(){}; |
| return; |
| } |
| dojo.hostenv.async_cb = next[1]; |
| // http = window.getURL(uri, dojo.hostenv.anon[cbn]); |
| window.getURL(next[0], function(result){ |
| dojo.hostenv.inFlightCount--; |
| dojo.hostenv.async_cb(result.content); |
| dojo.hostenv.unWindGetTextStack(); |
| }); |
| } |
| |
| dojo.hostenv.getText = function(uri, async_cb, fail_ok){ |
| // dojo.debug("Calling getText()"); |
| try{ |
| if(async_cb){ |
| dojo.hostenv.getTextStack.push([uri, async_cb, fail_ok]); |
| dojo.hostenv.unWindGetTextStack(); |
| }else{ |
| return dojo.raise("No synchronous XMLHTTP implementation available, for uri " + uri); |
| } |
| }catch(e){ |
| return dojo.raise("No XMLHTTP implementation available, for uri " + uri); |
| } |
| } |
| |
| |
| /** |
| * Makes an async post to the specified uri. |
| * |
| * FIXME: Not sure that we need this, but adding for completeness. |
| * More details about the implementation of this are available at |
| * http://wiki.svg.org/index.php/PostUrl |
| * @param uri A relative or absolute uri. If absolute, it still must be in the same "domain" as we are. |
| * @param async_cb If not specified, returns false as synchronous is not |
| * supported. If specified, load asynchronously, and use async_cb as the progress handler which takes the xmlhttp object as its argument. If async_cb, this function returns null. |
| * @param text Data to post |
| * @param fail_ok Default false. If fail_ok and !async_cb and loading fails, return null instead of throwing. |
| * @param mime_type optional MIME type of the posted data (such as "text/plain") |
| * @param encoding optional encoding for data. null, 'gzip' and 'deflate' are possible values. If browser does not support binary post this parameter is ignored. |
| */ |
| dojo.hostenv.postText = function(uri, async_cb, text, fail_ok, mime_type, encoding){ |
| var http = null; |
| |
| var async_callback = function(httpResponse){ |
| if (!httpResponse.success) { |
| dojo.raise("Request for uri '" + uri + "' resulted in " + httpResponse.status); |
| } |
| |
| if(!httpResponse.content) { |
| if (!fail_ok) dojo.raise("Request for uri '" + uri + "' resulted in no content"); |
| return null; |
| } |
| // FIXME: wtf, I'm losing a reference to async_cb |
| async_cb(httpResponse.content); |
| } |
| |
| try { |
| if(async_cb) { |
| http = window.postURL(uri, text, async_callback, mimeType, encoding); |
| } else { |
| return dojo.raise("No synchronous XMLHTTP post implementation available, for uri " + uri); |
| } |
| } catch(e) { |
| return dojo.raise("No XMLHTTP post implementation available, for uri " + uri); |
| } |
| } |
| |
| /* |
| * It turns out that if we check *right now*, as this script file is being loaded, |
| * then the last script element in the window DOM is ourselves. |
| * That is because any subsequent script elements haven't shown up in the document |
| * object yet. |
| */ |
| function dj_last_script_src() { |
| var scripts = window.document.getElementsByTagName('script'); |
| if(scripts.length < 1){ |
| dojo.raise("No script elements in window.document, so can't figure out my script src"); |
| } |
| var li = scripts.length-1; |
| var xlinkNS = "http://www.w3.org/1999/xlink"; |
| var src = null; |
| var script = null; |
| while(!src){ |
| script = scripts.item(li); |
| src = script.getAttributeNS(xlinkNS,"href"); |
| li--; |
| if(li<0){ break; } |
| // break; |
| } |
| if(!src){ |
| dojo.raise("Last script element (out of " + scripts.length + ") has no src"); |
| } |
| return src; |
| } |
| |
| if(!dojo.hostenv["library_script_uri_"]){ |
| dojo.hostenv.library_script_uri_ = dj_last_script_src(); |
| } |
| |
| // dojo.hostenv.loadUri = function(uri){ |
| /* FIXME: adding a script element doesn't seem to be synchronous, and so |
| * checking for namespace or object existance after loadUri using this |
| * method will error out. Need to figure out some other way of handling |
| * this! |
| */ |
| /* |
| var se = document.createElement("script"); |
| se.src = uri; |
| var head = document.getElementsByTagName("head")[0]; |
| head.appendChild(se); |
| // document.write("<script type='text/javascript' src='"+uri+"' />"); |
| return 1; |
| } |
| */ |