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