You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
336 lines
11 KiB
336 lines
11 KiB
// TODO: this file needs to be converted to the v1.7 loader |
|
|
|
// a host environment specifically built for Mozilla extensions, but derived |
|
// from the browser host environment |
|
if(typeof window != 'undefined'){ |
|
dojo.isBrowser = true; |
|
dojo._name = "browser"; |
|
|
|
|
|
// FIXME: PORTME |
|
// http://developer.mozilla.org/en/mozIJSSubScriptLoader |
|
|
|
|
|
// attempt to figure out the path to dojo if it isn't set in the config |
|
(function(){ |
|
// this is a scope protection closure. We set browser versions and grab |
|
// the URL we were loaded from here. |
|
|
|
// FIXME: need to probably use a different reference to "document" to get the hosting XUL environment |
|
|
|
dojo.baseUrl = dojo.config.baseUrl; |
|
|
|
// fill in the rendering support information in dojo.render.* |
|
var n = navigator; |
|
var dua = n.userAgent; |
|
var dav = n.appVersion; |
|
var tv = parseFloat(dav); |
|
|
|
dojo.isMozilla = dojo.isMoz = tv; |
|
if(dojo.isMoz){ |
|
dojo.isFF = parseFloat(dua.split("Firefox/")[1]) || undefined; |
|
} |
|
|
|
// FIXME |
|
dojo.isQuirks = document.compatMode == "BackCompat"; |
|
|
|
// FIXME |
|
// TODO: is the HTML LANG attribute relevant? |
|
dojo.locale = dojo.config.locale || n.language.toLowerCase(); |
|
|
|
dojo._xhrObj = function(){ |
|
return new XMLHttpRequest(); |
|
}; |
|
|
|
// monkey-patch _loadUri to handle file://, chrome://, and resource:// url's |
|
var oldLoadUri = dojo._loadUri; |
|
dojo._loadUri = function(uri, cb){ |
|
var handleLocal = ["file:", "chrome:", "resource:"].some(function(prefix){ |
|
return String(uri).indexOf(prefix) == 0; |
|
}); |
|
if(handleLocal){ |
|
// see: |
|
// http://developer.mozilla.org/en/mozIJSSubScriptLoader |
|
var l = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] |
|
.getService(Components.interfaces.mozIJSSubScriptLoader); |
|
var value = l.loadSubScript(uri, dojo.global); |
|
if(cb){ cb(value); } |
|
return true; |
|
}else{ |
|
// otherwise, call the pre-existing version |
|
return oldLoadUri.apply(dojo, arguments); |
|
} |
|
}; |
|
|
|
// FIXME: PORTME |
|
dojo._isDocumentOk = function(http){ |
|
var stat = http.status || 0; |
|
return (stat >= 200 && stat < 300) || // Boolean |
|
stat == 304 || // allow any 2XX response code |
|
stat == 1223 || // get it out of the cache |
|
(!stat && (location.protocol == "file:" || location.protocol == "chrome:") ); |
|
}; |
|
|
|
// FIXME: PORTME |
|
// var owloc = window.location+""; |
|
// var base = document.getElementsByTagName("base"); |
|
// var hasBase = (base && base.length > 0); |
|
var hasBase = false; |
|
|
|
dojo._getText = function(/*URI*/ uri, /*Boolean*/ fail_ok){ |
|
// summary: |
|
// Read the contents of the specified uri and return those contents. |
|
// uri: |
|
// A relative or absolute uri. If absolute, it still must be in |
|
// the same "domain" as we are. |
|
// fail_ok: |
|
// Default false. If fail_ok and loading fails, return null |
|
// instead of throwing. |
|
// returns: |
|
// The response text. null is returned when there is a |
|
// failure and failure is okay (an exception otherwise) |
|
|
|
// alert("_getText: " + uri); |
|
|
|
// NOTE: must be declared before scope switches ie. this._xhrObj() |
|
var http = dojo._xhrObj(); |
|
|
|
if(!hasBase && dojo._Url){ |
|
uri = (new dojo._Url(uri)).toString(); |
|
} |
|
if(dojo.config.cacheBust){ |
|
//Make sure we have a string before string methods are used on uri |
|
uri += ""; |
|
uri += (uri.indexOf("?") == -1 ? "?" : "&") + String(dojo.config.cacheBust).replace(/\W+/g, ""); |
|
} |
|
var handleLocal = ["file:", "chrome:", "resource:"].some(function(prefix){ |
|
return String(uri).indexOf(prefix) == 0; |
|
}); |
|
if(handleLocal){ |
|
// see: |
|
// http://forums.mozillazine.org/viewtopic.php?p=921150#921150 |
|
var ioService = Components.classes["@mozilla.org/network/io-service;1"] |
|
.getService(Components.interfaces.nsIIOService); |
|
var scriptableStream = Components |
|
.classes["@mozilla.org/scriptableinputstream;1"] |
|
.getService(Components.interfaces.nsIScriptableInputStream); |
|
|
|
var channel = ioService.newChannel(uri, null, null); |
|
var input = channel.open(); |
|
scriptableStream.init(input); |
|
var str = scriptableStream.read(input.available()); |
|
scriptableStream.close(); |
|
input.close(); |
|
return str; |
|
}else{ |
|
http.open('GET', uri, false); |
|
try{ |
|
http.send(null); |
|
// alert(http); |
|
if(!dojo._isDocumentOk(http)){ |
|
var err = Error("Unable to load " + uri + " status:" + http.status); |
|
err.status = http.status; |
|
err.responseText = http.responseText; |
|
throw err; |
|
} |
|
}catch(e){ |
|
if(fail_ok){ |
|
return null; |
|
} // null |
|
// rethrow the exception |
|
throw e; |
|
} |
|
return http.responseText; // String |
|
} |
|
}; |
|
|
|
dojo._windowUnloaders = []; |
|
|
|
// FIXME: PORTME |
|
dojo.windowUnloaded = function(){ |
|
// summary: |
|
// signal fired by impending window destruction. You may use |
|
// dojo.addOnWIndowUnload() or dojo.connect() to this method to perform |
|
// page/application cleanup methods. See dojo.addOnWindowUnload for more info. |
|
var mll = dojo._windowUnloaders; |
|
while(mll.length){ |
|
(mll.pop())(); |
|
} |
|
}; |
|
|
|
// FIXME: PORTME |
|
dojo.addOnWindowUnload = function(/*Object?*/obj, /*String|Function?*/functionName){ |
|
// summary: |
|
// registers a function to be triggered when window.onunload fires. |
|
// Be careful trying to modify the DOM or access JavaScript properties |
|
// during this phase of page unloading: they may not always be available. |
|
// Consider dojo.addOnUnload() if you need to modify the DOM or do heavy |
|
// JavaScript work. |
|
// example: |
|
// | dojo.addOnWindowUnload(functionPointer) |
|
// | dojo.addOnWindowUnload(object, "functionName") |
|
// | dojo.addOnWindowUnload(object, function(){ /* ... */}); |
|
|
|
dojo._onto(dojo._windowUnloaders, obj, functionName); |
|
}; |
|
|
|
// XUL specific APIs |
|
var contexts = []; |
|
var current = null; |
|
dojo._defaultContext = [ window, document ]; |
|
|
|
dojo.pushContext = function(/*Object|String?*/g, /*MDocumentElement?*/d){ |
|
// summary: |
|
// causes subsequent calls to Dojo methods to assume the |
|
// passed object and, optionally, document as the default |
|
// scopes to use. A 2-element array of the previous global and |
|
// document are returned. |
|
// description: |
|
// dojo.pushContext treats contexts as a stack. The |
|
// auto-detected contexts which are initially provided using |
|
// dojo.setContext() require authors to keep state in order to |
|
// "return" to a previous context, whereas the |
|
// dojo.pushContext and dojo.popContext methods provide a more |
|
// natural way to augment blocks of code to ensure that they |
|
// execute in a different window or frame without issue. If |
|
// called without any arguments, the default context (the |
|
// context when Dojo is first loaded) is instead pushed into |
|
// the stack. If only a single string is passed, a node in the |
|
// intitial context's document is looked up and its |
|
// contextWindow and contextDocument properties are used as |
|
// the context to push. This means that iframes can be given |
|
// an ID and code can be executed in the scope of the iframe's |
|
// document in subsequent calls easily. |
|
// g: |
|
// The global context. If a string, the id of the frame to |
|
// search for a context and document. |
|
// d: |
|
// The document element to execute subsequent code with. |
|
var old = [dojo.global, dojo.doc]; |
|
contexts.push(old); |
|
var n; |
|
if(!g && !d){ |
|
n = dojo._defaultContext; |
|
}else{ |
|
n = [ g, d ]; |
|
if(!d && dojo.isString(g)){ |
|
var t = document.getElementById(g); |
|
if(t.contentDocument){ |
|
n = [t.contentWindow, t.contentDocument]; |
|
} |
|
} |
|
} |
|
current = n; |
|
dojo.setContext.apply(dojo, n); |
|
return old; // Array |
|
}; |
|
|
|
dojo.popContext = function(){ |
|
// summary: |
|
// If the context stack contains elements, ensure that |
|
// subsequent code executes in the *previous* context to the |
|
// current context. The current context set ([global, |
|
// document]) is returned. |
|
var oc = current; |
|
if(!contexts.length){ |
|
return oc; |
|
} |
|
dojo.setContext.apply(dojo, contexts.pop()); |
|
return oc; |
|
}; |
|
|
|
// FIXME: |
|
// don't really like the current arguments and order to |
|
// _inContext, so don't make it public until it's right! |
|
dojo._inContext = function(g, d, f){ |
|
var a = dojo._toArray(arguments); |
|
f = a.pop(); |
|
if(a.length == 1){ |
|
d = null; |
|
} |
|
dojo.pushContext(g, d); |
|
var r = f(); |
|
dojo.popContext(); |
|
return r; |
|
}; |
|
|
|
})(); |
|
|
|
dojo._initFired = false; |
|
// BEGIN DOMContentLoaded, from Dean Edwards (http://dean.edwards.name/weblog/2006/06/again/) |
|
dojo._loadInit = function(e){ |
|
dojo._initFired = true; |
|
// allow multiple calls, only first one will take effect |
|
// A bug in khtml calls events callbacks for document for event which isnt supported |
|
// for example a created contextmenu event calls DOMContentLoaded, workaround |
|
var type = (e && e.type) ? e.type.toLowerCase() : "load"; |
|
if(arguments.callee.initialized || (type != "domcontentloaded" && type != "load")){ return; } |
|
arguments.callee.initialized = true; |
|
if(dojo._inFlightCount == 0){ |
|
dojo._modulesLoaded(); |
|
} |
|
}; |
|
|
|
/* |
|
(function(){ |
|
var _w = window; |
|
var _handleNodeEvent = function(evtName, fp){ |
|
// summary: |
|
// non-destructively adds the specified function to the node's |
|
// evtName handler. |
|
// evtName: should be in the form "onclick" for "onclick" handlers. |
|
// Make sure you pass in the "on" part. |
|
var oldHandler = _w[evtName] || function(){}; |
|
_w[evtName] = function(){ |
|
fp.apply(_w, arguments); |
|
oldHandler.apply(_w, arguments); |
|
}; |
|
}; |
|
// FIXME: PORT |
|
// FIXME: dojo.unloaded requires dojo scope, so using anon function wrapper. |
|
_handleNodeEvent("onbeforeunload", function(){ dojo.unloaded(); }); |
|
_handleNodeEvent("onunload", function(){ dojo.windowUnloaded(); }); |
|
})(); |
|
*/ |
|
|
|
|
|
// FIXME: PORTME |
|
// this event fires a lot, namely for all plugin XUL overlays and for |
|
// all iframes (in addition to window navigations). We only want |
|
// Dojo's to fire once..but we might care if pages navigate. We'll |
|
// probably need an extension-specific API |
|
if(!dojo.config.afterOnLoad){ |
|
window.addEventListener("DOMContentLoaded", function(e){ |
|
dojo._loadInit(e); |
|
// console.log("DOM content loaded", e); |
|
}, false); |
|
} |
|
|
|
} //if (typeof window != 'undefined') |
|
|
|
//Register any module paths set up in djConfig. Need to do this |
|
//in the hostenvs since hostenv_browser can read djConfig from a |
|
//script tag's attribute. |
|
(function(){ |
|
var mp = dojo.config["modulePaths"]; |
|
if(mp){ |
|
for(var param in mp){ |
|
dojo.registerModulePath(param, mp[param]); |
|
} |
|
} |
|
})(); |
|
|
|
//Load debug code if necessary. |
|
if(dojo.config.isDebug){ |
|
// logging stub for extension logging |
|
console.log = function(m){ |
|
var s = Components.classes["@mozilla.org/consoleservice;1"].getService( |
|
Components.interfaces.nsIConsoleService |
|
); |
|
s.logStringMessage(m); |
|
}; |
|
console.debug = function(){ |
|
console.log(dojo._toArray(arguments).join(" ")); |
|
}; |
|
// FIXME: what about the rest of the console.* methods? And is there any way to reach into firebug and log into it directly? |
|
}
|
|
|