]> git.wh0rd.org - 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 }