configFirefoxExtension.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. // TODO: this file needs to be converted to the v1.7 loader
  2. // a host environment specifically built for Mozilla extensions, but derived
  3. // from the browser host environment
  4. if(typeof window != 'undefined'){
  5. dojo.isBrowser = true;
  6. dojo._name = "browser";
  7. // FIXME: PORTME
  8. // http://developer.mozilla.org/en/mozIJSSubScriptLoader
  9. // attempt to figure out the path to dojo if it isn't set in the config
  10. (function(){
  11. // this is a scope protection closure. We set browser versions and grab
  12. // the URL we were loaded from here.
  13. // FIXME: need to probably use a different reference to "document" to get the hosting XUL environment
  14. dojo.baseUrl = dojo.config.baseUrl;
  15. // fill in the rendering support information in dojo.render.*
  16. var n = navigator;
  17. var dua = n.userAgent;
  18. var dav = n.appVersion;
  19. var tv = parseFloat(dav);
  20. dojo.isMozilla = dojo.isMoz = tv;
  21. if(dojo.isMoz){
  22. dojo.isFF = parseFloat(dua.split("Firefox/")[1]) || undefined;
  23. }
  24. // FIXME
  25. dojo.isQuirks = document.compatMode == "BackCompat";
  26. // FIXME
  27. // TODO: is the HTML LANG attribute relevant?
  28. dojo.locale = dojo.config.locale || n.language.toLowerCase();
  29. dojo._xhrObj = function(){
  30. return new XMLHttpRequest();
  31. };
  32. // monkey-patch _loadUri to handle file://, chrome://, and resource:// url's
  33. var oldLoadUri = dojo._loadUri;
  34. dojo._loadUri = function(uri, cb){
  35. var handleLocal = ["file:", "chrome:", "resource:"].some(function(prefix){
  36. return String(uri).indexOf(prefix) == 0;
  37. });
  38. if(handleLocal){
  39. // see:
  40. // http://developer.mozilla.org/en/mozIJSSubScriptLoader
  41. var l = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
  42. .getService(Components.interfaces.mozIJSSubScriptLoader);
  43. var value = l.loadSubScript(uri, dojo.global);
  44. if(cb){ cb(value); }
  45. return true;
  46. }else{
  47. // otherwise, call the pre-existing version
  48. return oldLoadUri.apply(dojo, arguments);
  49. }
  50. };
  51. // FIXME: PORTME
  52. dojo._isDocumentOk = function(http){
  53. var stat = http.status || 0;
  54. return (stat >= 200 && stat < 300) || // Boolean
  55. stat == 304 || // allow any 2XX response code
  56. stat == 1223 || // get it out of the cache
  57. (!stat && (location.protocol == "file:" || location.protocol == "chrome:") );
  58. };
  59. // FIXME: PORTME
  60. // var owloc = window.location+"";
  61. // var base = document.getElementsByTagName("base");
  62. // var hasBase = (base && base.length > 0);
  63. var hasBase = false;
  64. dojo._getText = function(/*URI*/ uri, /*Boolean*/ fail_ok){
  65. // summary: Read the contents of the specified uri and return those contents.
  66. // uri:
  67. // A relative or absolute uri. If absolute, it still must be in
  68. // the same "domain" as we are.
  69. // fail_ok:
  70. // Default false. If fail_ok and loading fails, return null
  71. // instead of throwing.
  72. // returns: The response text. null is returned when there is a
  73. // failure and failure is okay (an exception otherwise)
  74. // alert("_getText: " + uri);
  75. // NOTE: must be declared before scope switches ie. this._xhrObj()
  76. var http = dojo._xhrObj();
  77. if(!hasBase && dojo._Url){
  78. uri = (new dojo._Url(uri)).toString();
  79. }
  80. if(dojo.config.cacheBust){
  81. //Make sure we have a string before string methods are used on uri
  82. uri += "";
  83. uri += (uri.indexOf("?") == -1 ? "?" : "&") + String(dojo.config.cacheBust).replace(/\W+/g, "");
  84. }
  85. var handleLocal = ["file:", "chrome:", "resource:"].some(function(prefix){
  86. return String(uri).indexOf(prefix) == 0;
  87. });
  88. if(handleLocal){
  89. // see:
  90. // http://forums.mozillazine.org/viewtopic.php?p=921150#921150
  91. var ioService = Components.classes["@mozilla.org/network/io-service;1"]
  92. .getService(Components.interfaces.nsIIOService);
  93. var scriptableStream = Components
  94. .classes["@mozilla.org/scriptableinputstream;1"]
  95. .getService(Components.interfaces.nsIScriptableInputStream);
  96. var channel = ioService.newChannel(uri, null, null);
  97. var input = channel.open();
  98. scriptableStream.init(input);
  99. var str = scriptableStream.read(input.available());
  100. scriptableStream.close();
  101. input.close();
  102. return str;
  103. }else{
  104. http.open('GET', uri, false);
  105. try{
  106. http.send(null);
  107. // alert(http);
  108. if(!dojo._isDocumentOk(http)){
  109. var err = Error("Unable to load " + uri + " status:" + http.status);
  110. err.status = http.status;
  111. err.responseText = http.responseText;
  112. throw err;
  113. }
  114. }catch(e){
  115. if(fail_ok){
  116. return null;
  117. } // null
  118. // rethrow the exception
  119. throw e;
  120. }
  121. return http.responseText; // String
  122. }
  123. };
  124. dojo._windowUnloaders = [];
  125. // FIXME: PORTME
  126. dojo.windowUnloaded = function(){
  127. // summary:
  128. // signal fired by impending window destruction. You may use
  129. // dojo.addOnWIndowUnload() or dojo.connect() to this method to perform
  130. // page/application cleanup methods. See dojo.addOnWindowUnload for more info.
  131. var mll = dojo._windowUnloaders;
  132. while(mll.length){
  133. (mll.pop())();
  134. }
  135. };
  136. // FIXME: PORTME
  137. dojo.addOnWindowUnload = function(/*Object?*/obj, /*String|Function?*/functionName){
  138. // summary:
  139. // registers a function to be triggered when window.onunload fires.
  140. // Be careful trying to modify the DOM or access JavaScript properties
  141. // during this phase of page unloading: they may not always be available.
  142. // Consider dojo.addOnUnload() if you need to modify the DOM or do heavy
  143. // JavaScript work.
  144. // example:
  145. // | dojo.addOnWindowUnload(functionPointer)
  146. // | dojo.addOnWindowUnload(object, "functionName")
  147. // | dojo.addOnWindowUnload(object, function(){ /* ... */});
  148. dojo._onto(dojo._windowUnloaders, obj, functionName);
  149. };
  150. // XUL specific APIs
  151. var contexts = [];
  152. var current = null;
  153. dojo._defaultContext = [ window, document ];
  154. dojo.pushContext = function(/*Object|String?*/g, /*MDocumentElement?*/d){
  155. // summary:
  156. // causes subsequent calls to Dojo methods to assume the
  157. // passed object and, optionally, document as the default
  158. // scopes to use. A 2-element array of the previous global and
  159. // document are returned.
  160. // description:
  161. // dojo.pushContext treats contexts as a stack. The
  162. // auto-detected contexts which are initially provided using
  163. // dojo.setContext() require authors to keep state in order to
  164. // "return" to a previous context, whereas the
  165. // dojo.pushContext and dojo.popContext methods provide a more
  166. // natural way to augment blocks of code to ensure that they
  167. // execute in a different window or frame without issue. If
  168. // called without any arguments, the default context (the
  169. // context when Dojo is first loaded) is instead pushed into
  170. // the stack. If only a single string is passed, a node in the
  171. // intitial context's document is looked up and its
  172. // contextWindow and contextDocument properties are used as
  173. // the context to push. This means that iframes can be given
  174. // an ID and code can be executed in the scope of the iframe's
  175. // document in subsequent calls easily.
  176. // g:
  177. // The global context. If a string, the id of the frame to
  178. // search for a context and document.
  179. // d:
  180. // The document element to execute subsequent code with.
  181. var old = [dojo.global, dojo.doc];
  182. contexts.push(old);
  183. var n;
  184. if(!g && !d){
  185. n = dojo._defaultContext;
  186. }else{
  187. n = [ g, d ];
  188. if(!d && dojo.isString(g)){
  189. var t = document.getElementById(g);
  190. if(t.contentDocument){
  191. n = [t.contentWindow, t.contentDocument];
  192. }
  193. }
  194. }
  195. current = n;
  196. dojo.setContext.apply(dojo, n);
  197. return old; // Array
  198. };
  199. dojo.popContext = function(){
  200. // summary:
  201. // If the context stack contains elements, ensure that
  202. // subsequent code executes in the *previous* context to the
  203. // current context. The current context set ([global,
  204. // document]) is returned.
  205. var oc = current;
  206. if(!contexts.length){
  207. return oc;
  208. }
  209. dojo.setContext.apply(dojo, contexts.pop());
  210. return oc;
  211. };
  212. // FIXME:
  213. // don't really like the current arguments and order to
  214. // _inContext, so don't make it public until it's right!
  215. dojo._inContext = function(g, d, f){
  216. var a = dojo._toArray(arguments);
  217. f = a.pop();
  218. if(a.length == 1){
  219. d = null;
  220. }
  221. dojo.pushContext(g, d);
  222. var r = f();
  223. dojo.popContext();
  224. return r;
  225. };
  226. })();
  227. dojo._initFired = false;
  228. // BEGIN DOMContentLoaded, from Dean Edwards (http://dean.edwards.name/weblog/2006/06/again/)
  229. dojo._loadInit = function(e){
  230. dojo._initFired = true;
  231. // allow multiple calls, only first one will take effect
  232. // A bug in khtml calls events callbacks for document for event which isnt supported
  233. // for example a created contextmenu event calls DOMContentLoaded, workaround
  234. var type = (e && e.type) ? e.type.toLowerCase() : "load";
  235. if(arguments.callee.initialized || (type != "domcontentloaded" && type != "load")){ return; }
  236. arguments.callee.initialized = true;
  237. if(dojo._inFlightCount == 0){
  238. dojo._modulesLoaded();
  239. }
  240. };
  241. /*
  242. (function(){
  243. var _w = window;
  244. var _handleNodeEvent = function(evtName, fp){
  245. // summary:
  246. // non-destructively adds the specified function to the node's
  247. // evtName handler.
  248. // evtName: should be in the form "onclick" for "onclick" handlers.
  249. // Make sure you pass in the "on" part.
  250. var oldHandler = _w[evtName] || function(){};
  251. _w[evtName] = function(){
  252. fp.apply(_w, arguments);
  253. oldHandler.apply(_w, arguments);
  254. };
  255. };
  256. // FIXME: PORT
  257. // FIXME: dojo.unloaded requires dojo scope, so using anon function wrapper.
  258. _handleNodeEvent("onbeforeunload", function() { dojo.unloaded(); });
  259. _handleNodeEvent("onunload", function() { dojo.windowUnloaded(); });
  260. })();
  261. */
  262. // FIXME: PORTME
  263. // this event fires a lot, namely for all plugin XUL overlays and for
  264. // all iframes (in addition to window navigations). We only want
  265. // Dojo's to fire once..but we might care if pages navigate. We'll
  266. // probably need an extension-specific API
  267. if(!dojo.config.afterOnLoad){
  268. window.addEventListener("DOMContentLoaded", function(e){
  269. dojo._loadInit(e);
  270. // console.log("DOM content loaded", e);
  271. }, false);
  272. }
  273. } //if (typeof window != 'undefined')
  274. //Register any module paths set up in djConfig. Need to do this
  275. //in the hostenvs since hostenv_browser can read djConfig from a
  276. //script tag's attribute.
  277. (function(){
  278. var mp = dojo.config["modulePaths"];
  279. if(mp){
  280. for(var param in mp){
  281. dojo.registerModulePath(param, mp[param]);
  282. }
  283. }
  284. })();
  285. //Load debug code if necessary.
  286. if(dojo.config.isDebug){
  287. // logging stub for extension logging
  288. console.log = function(m){
  289. var s = Components.classes["@mozilla.org/consoleservice;1"].getService(
  290. Components.interfaces.nsIConsoleService
  291. );
  292. s.logStringMessage(m);
  293. };
  294. console.debug = function(){
  295. console.log(dojo._toArray(arguments).join(" "));
  296. };
  297. // FIXME: what about the rest of the console.* methods? And is there any way to reach into firebug and log into it directly?
  298. }