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