source: Dev/branches/rest-dojo-ui/client/dojo/_base/configFirefoxExtension.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

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