configFirefoxExtension.js 11 KB

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