]> git.wh0rd.org - tt-rss.git/blob - lib/dojo/_base/_loader/hostenv_browser.js
remove call-by-reference to comply with php 5.4
[tt-rss.git] / lib / dojo / _base / _loader / hostenv_browser.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 /*=====
9 dojo.isBrowser = {
10 // example:
11 // | if(dojo.isBrowser){ ... }
12 };
13
14 dojo.isFF = {
15 // example:
16 // | if(dojo.isFF > 1){ ... }
17 };
18
19 dojo.isIE = {
20 // example:
21 // | if(dojo.isIE > 6){
22 // | // we are IE7
23 // | }
24 };
25
26 dojo.isSafari = {
27 // example:
28 // | if(dojo.isSafari){ ... }
29 // example:
30 // Detect iPhone:
31 // | if(dojo.isSafari && navigator.userAgent.indexOf("iPhone") != -1){
32 // | // we are iPhone. Note, iPod touch reports "iPod" above and fails this test.
33 // | }
34 };
35
36 dojo = {
37 // isBrowser: Boolean
38 // True if the client is a web-browser
39 isBrowser: true,
40 // isFF: Number | undefined
41 // Version as a Number if client is FireFox. undefined otherwise. Corresponds to
42 // major detected FireFox version (1.5, 2, 3, etc.)
43 isFF: 2,
44 // isIE: Number | undefined
45 // Version as a Number if client is MSIE(PC). undefined otherwise. Corresponds to
46 // major detected IE version (6, 7, 8, etc.)
47 isIE: 6,
48 // isKhtml: Number | undefined
49 // Version as a Number if client is a KHTML browser. undefined otherwise. Corresponds to major
50 // detected version.
51 isKhtml: 0,
52 // isWebKit: Number | undefined
53 // Version as a Number if client is a WebKit-derived browser (Konqueror,
54 // Safari, Chrome, etc.). undefined otherwise.
55 isWebKit: 0,
56 // isMozilla: Number | undefined
57 // Version as a Number if client is a Mozilla-based browser (Firefox,
58 // SeaMonkey). undefined otherwise. Corresponds to major detected version.
59 isMozilla: 0,
60 // isOpera: Number | undefined
61 // Version as a Number if client is Opera. undefined otherwise. Corresponds to
62 // major detected version.
63 isOpera: 0,
64 // isSafari: Number | undefined
65 // Version as a Number if client is Safari or iPhone. undefined otherwise.
66 isSafari: 0,
67 // isChrome: Number | undefined
68 // Version as a Number if client is Chrome browser. undefined otherwise.
69 isChrome: 0
70 // isMac: Boolean
71 // True if the client runs on Mac
72 }
73 =====*/
74 if(typeof window != 'undefined'){
75 dojo.isBrowser = true;
76 dojo._name = "browser";
77
78
79 // attempt to figure out the path to dojo if it isn't set in the config
80 (function(){
81 var d = dojo;
82
83 // this is a scope protection closure. We set browser versions and grab
84 // the URL we were loaded from here.
85
86 // grab the node we were loaded from
87 if(document && document.getElementsByTagName){
88 var scripts = document.getElementsByTagName("script");
89 var rePkg = /dojo(\.xd)?\.js(\W|$)/i;
90 for(var i = 0; i < scripts.length; i++){
91 var src = scripts[i].getAttribute("src");
92 if(!src){ continue; }
93 var m = src.match(rePkg);
94 if(m){
95 // find out where we came from
96 if(!d.config.baseUrl){
97 d.config.baseUrl = src.substring(0, m.index);
98 }
99 // and find out if we need to modify our behavior
100 var cfg = (scripts[i].getAttribute("djConfig") || scripts[i].getAttribute("data-dojo-config"));
101 if(cfg){
102 var cfgo = eval("({ "+cfg+" })");
103 for(var x in cfgo){
104 dojo.config[x] = cfgo[x];
105 }
106 }
107 break; // "first Dojo wins"
108 }
109 }
110 }
111 d.baseUrl = d.config.baseUrl;
112
113 // fill in the rendering support information in dojo.render.*
114 var n = navigator;
115 var dua = n.userAgent,
116 dav = n.appVersion,
117 tv = parseFloat(dav);
118
119 if(dua.indexOf("Opera") >= 0){ d.isOpera = tv; }
120 if(dua.indexOf("AdobeAIR") >= 0){ d.isAIR = 1; }
121 d.isKhtml = (dav.indexOf("Konqueror") >= 0) ? tv : 0;
122 d.isWebKit = parseFloat(dua.split("WebKit/")[1]) || undefined;
123 d.isChrome = parseFloat(dua.split("Chrome/")[1]) || undefined;
124 d.isMac = dav.indexOf("Macintosh") >= 0;
125
126 // safari detection derived from:
127 // http://developer.apple.com/internet/safari/faq.html#anchor2
128 // http://developer.apple.com/internet/safari/uamatrix.html
129 var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);
130 if(index && !dojo.isChrome){
131 // try to grab the explicit Safari version first. If we don't get
132 // one, look for less than 419.3 as the indication that we're on something
133 // "Safari 2-ish".
134 d.isSafari = parseFloat(dav.split("Version/")[1]);
135 if(!d.isSafari || parseFloat(dav.substr(index + 7)) <= 419.3){
136 d.isSafari = 2;
137 }
138 }
139
140 if(dua.indexOf("Gecko") >= 0 && !d.isKhtml && !d.isWebKit){ d.isMozilla = d.isMoz = tv; }
141 if(d.isMoz){
142 //We really need to get away from this. Consider a sane isGecko approach for the future.
143 d.isFF = parseFloat(dua.split("Firefox/")[1] || dua.split("Minefield/")[1]) || undefined;
144 }
145 if(document.all && !d.isOpera){
146 d.isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
147 //In cases where the page has an HTTP header or META tag with
148 //X-UA-Compatible, then it is in emulation mode.
149 //Make sure isIE reflects the desired version.
150 //document.documentMode of 5 means quirks mode.
151 //Only switch the value if documentMode's major version
152 //is different from isIE's major version.
153 var mode = document.documentMode;
154 if(mode && mode != 5 && Math.floor(d.isIE) != mode){
155 d.isIE = mode;
156 }
157 }
158
159 //Workaround to get local file loads of dojo to work on IE 7
160 //by forcing to not use native xhr.
161 if(dojo.isIE && window.location.protocol === "file:"){
162 dojo.config.ieForceActiveXXhr=true;
163 }
164
165 d.isQuirks = document.compatMode == "BackCompat";
166
167 // TODO: is the HTML LANG attribute relevant?
168 d.locale = dojo.config.locale || (d.isIE ? n.userLanguage : n.language).toLowerCase();
169
170 // These are in order of decreasing likelihood; this will change in time.
171 d._XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'];
172
173 d._xhrObj = function(){
174 // summary:
175 // does the work of portably generating a new XMLHTTPRequest object.
176 var http, last_e;
177 if(!dojo.isIE || !dojo.config.ieForceActiveXXhr){
178 try{ http = new XMLHttpRequest(); }catch(e){}
179 }
180 if(!http){
181 for(var i=0; i<3; ++i){
182 var progid = d._XMLHTTP_PROGIDS[i];
183 try{
184 http = new ActiveXObject(progid);
185 }catch(e){
186 last_e = e;
187 }
188
189 if(http){
190 d._XMLHTTP_PROGIDS = [progid]; // so faster next time
191 break;
192 }
193 }
194 }
195
196 if(!http){
197 throw new Error("XMLHTTP not available: "+last_e);
198 }
199
200 return http; // XMLHTTPRequest instance
201 }
202
203 d._isDocumentOk = function(http){
204 var stat = http.status || 0,
205 lp = location.protocol;
206 return (stat >= 200 && stat < 300) || // Boolean
207 stat == 304 || // allow any 2XX response code
208 stat == 1223 || // get it out of the cache
209 // Internet Explorer mangled the status code
210 // Internet Explorer mangled the status code OR we're Titanium/browser chrome/chrome extension requesting a local file
211 (!stat && (lp == "file:" || lp == "chrome:" || lp == "chrome-extension:" || lp == "app:"));
212 }
213
214 //See if base tag is in use.
215 //This is to fix http://trac.dojotoolkit.org/ticket/3973,
216 //but really, we need to find out how to get rid of the dojo._Url reference
217 //below and still have DOH work with the dojo.i18n test following some other
218 //test that uses the test frame to load a document (trac #2757).
219 //Opera still has problems, but perhaps a larger issue of base tag support
220 //with XHR requests (hasBase is true, but the request is still made to document
221 //path, not base path).
222 var owloc = window.location+"";
223 var base = document.getElementsByTagName("base");
224 var hasBase = (base && base.length > 0);
225
226 d._getText = function(/*URI*/ uri, /*Boolean*/ fail_ok){
227 // summary: Read the contents of the specified uri and return those contents.
228 // uri:
229 // A relative or absolute uri. If absolute, it still must be in
230 // the same "domain" as we are.
231 // fail_ok:
232 // Default false. If fail_ok and loading fails, return null
233 // instead of throwing.
234 // returns: The response text. null is returned when there is a
235 // failure and failure is okay (an exception otherwise)
236
237 // NOTE: must be declared before scope switches ie. this._xhrObj()
238 var http = d._xhrObj();
239
240 if(!hasBase && dojo._Url){
241 uri = (new dojo._Url(owloc, uri)).toString();
242 }
243
244 if(d.config.cacheBust){
245 //Make sure we have a string before string methods are used on uri
246 uri += "";
247 uri += (uri.indexOf("?") == -1 ? "?" : "&") + String(d.config.cacheBust).replace(/\W+/g,"");
248 }
249
250 http.open('GET', uri, false);
251 try{
252 http.send(null);
253 if(!d._isDocumentOk(http)){
254 var err = Error("Unable to load "+uri+" status:"+ http.status);
255 err.status = http.status;
256 err.responseText = http.responseText;
257 throw err;
258 }
259 }catch(e){
260 if(fail_ok){ return null; } // null
261 // rethrow the exception
262 throw e;
263 }
264 return http.responseText; // String
265 }
266
267
268 var _w = window;
269 var _handleNodeEvent = function(/*String*/evtName, /*Function*/fp){
270 // summary:
271 // non-destructively adds the specified function to the node's
272 // evtName handler.
273 // evtName: should be in the form "onclick" for "onclick" handlers.
274 // Make sure you pass in the "on" part.
275 var _a = _w.attachEvent || _w.addEventListener;
276 evtName = _w.attachEvent ? evtName : evtName.substring(2);
277 _a(evtName, function(){
278 fp.apply(_w, arguments);
279 }, false);
280 };
281
282
283 d._windowUnloaders = [];
284
285 d.windowUnloaded = function(){
286 // summary:
287 // signal fired by impending window destruction. You may use
288 // dojo.addOnWindowUnload() to register a listener for this
289 // event. NOTE: if you wish to dojo.connect() to this method
290 // to perform page/application cleanup, be aware that this
291 // event WILL NOT fire if no handler has been registered with
292 // dojo.addOnWindowUnload. This behavior started in Dojo 1.3.
293 // Previous versions always triggered dojo.windowUnloaded. See
294 // dojo.addOnWindowUnload for more info.
295 var mll = d._windowUnloaders;
296 while(mll.length){
297 (mll.pop())();
298 }
299 d = null;
300 };
301
302 var _onWindowUnloadAttached = 0;
303 d.addOnWindowUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
304 // summary:
305 // registers a function to be triggered when window.onunload
306 // fires.
307 // description:
308 // The first time that addOnWindowUnload is called Dojo
309 // will register a page listener to trigger your unload
310 // handler with. Note that registering these handlers may
311 // destory "fastback" page caching in browsers that support
312 // it. Be careful trying to modify the DOM or access
313 // JavaScript properties during this phase of page unloading:
314 // they may not always be available. Consider
315 // dojo.addOnUnload() if you need to modify the DOM or do
316 // heavy JavaScript work since it fires at the eqivalent of
317 // the page's "onbeforeunload" event.
318 // example:
319 // | dojo.addOnWindowUnload(functionPointer)
320 // | dojo.addOnWindowUnload(object, "functionName");
321 // | dojo.addOnWindowUnload(object, function(){ /* ... */});
322
323 d._onto(d._windowUnloaders, obj, functionName);
324 if(!_onWindowUnloadAttached){
325 _onWindowUnloadAttached = 1;
326 _handleNodeEvent("onunload", d.windowUnloaded);
327 }
328 };
329
330 var _onUnloadAttached = 0;
331 d.addOnUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
332 // summary:
333 // registers a function to be triggered when the page unloads.
334 // description:
335 // The first time that addOnUnload is called Dojo will
336 // register a page listener to trigger your unload handler
337 // with.
338 //
339 // In a browser enviroment, the functions will be triggered
340 // during the window.onbeforeunload event. Be careful of doing
341 // too much work in an unload handler. onbeforeunload can be
342 // triggered if a link to download a file is clicked, or if
343 // the link is a javascript: link. In these cases, the
344 // onbeforeunload event fires, but the document is not
345 // actually destroyed. So be careful about doing destructive
346 // operations in a dojo.addOnUnload callback.
347 //
348 // Further note that calling dojo.addOnUnload will prevent
349 // browsers from using a "fast back" cache to make page
350 // loading via back button instantaneous.
351 // example:
352 // | dojo.addOnUnload(functionPointer)
353 // | dojo.addOnUnload(object, "functionName")
354 // | dojo.addOnUnload(object, function(){ /* ... */});
355
356 d._onto(d._unloaders, obj, functionName);
357 if(!_onUnloadAttached){
358 _onUnloadAttached = 1;
359 _handleNodeEvent("onbeforeunload", dojo.unloaded);
360 }
361 };
362
363 })();
364
365 //START DOMContentLoaded
366 dojo._initFired = false;
367 dojo._loadInit = function(e){
368 if(dojo._scrollIntervalId){
369 clearInterval(dojo._scrollIntervalId);
370 dojo._scrollIntervalId = 0;
371 }
372
373 if(!dojo._initFired){
374 dojo._initFired = true;
375
376 //Help out IE to avoid memory leak.
377 if(!dojo.config.afterOnLoad && window.detachEvent){
378 window.detachEvent("onload", dojo._loadInit);
379 }
380
381 if(dojo._inFlightCount == 0){
382 dojo._modulesLoaded();
383 }
384 }
385 }
386
387 if(!dojo.config.afterOnLoad){
388 if(document.addEventListener){
389 //Standards. Hooray! Assumption here that if standards based,
390 //it knows about DOMContentLoaded. It is OK if it does not, the fall through
391 //to window onload should be good enough.
392 document.addEventListener("DOMContentLoaded", dojo._loadInit, false);
393 window.addEventListener("load", dojo._loadInit, false);
394 }else if(window.attachEvent){
395 window.attachEvent("onload", dojo._loadInit);
396
397 //DOMContentLoaded approximation. Diego Perini found this MSDN article
398 //that indicates doScroll is available after DOM ready, so do a setTimeout
399 //to check when it is available.
400 //http://msdn.microsoft.com/en-us/library/ms531426.aspx
401 if(!dojo.config.skipIeDomLoaded && self === self.top){
402 dojo._scrollIntervalId = setInterval(function (){
403 try{
404 //When dojo is loaded into an iframe in an IE HTML Application
405 //(HTA), such as in a selenium test, javascript in the iframe
406 //can't see anything outside of it, so self===self.top is true,
407 //but the iframe is not the top window and doScroll will be
408 //available before document.body is set. Test document.body
409 //before trying the doScroll trick
410 if(document.body){
411 document.documentElement.doScroll("left");
412 dojo._loadInit();
413 }
414 }catch (e){}
415 }, 30);
416 }
417 }
418 }
419
420 if(dojo.isIE){
421 try{
422 (function(){
423 document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
424 var vmlElems = ["*", "group", "roundrect", "oval", "shape", "rect", "imagedata", "path", "textpath", "text"],
425 i = 0, l = 1, s = document.createStyleSheet();
426 if(dojo.isIE >= 8){
427 i = 1;
428 l = vmlElems.length;
429 }
430 for(; i < l; ++i){
431 s.addRule("v\\:" + vmlElems[i], "behavior:url(#default#VML); display:inline-block");
432 }
433 })();
434 }catch(e){}
435 }
436 //END DOMContentLoaded
437
438
439 /*
440 OpenAjax.subscribe("OpenAjax", "onload", function(){
441 if(dojo._inFlightCount == 0){
442 dojo._modulesLoaded();
443 }
444 });
445
446 OpenAjax.subscribe("OpenAjax", "onunload", function(){
447 dojo.unloaded();
448 });
449 */
450 } //if (typeof window != 'undefined')
451
452 //Register any module paths set up in djConfig. Need to do this
453 //in the hostenvs since hostenv_browser can read djConfig from a
454 //script tag's attribute.
455 (function(){
456 var mp = dojo.config["modulePaths"];
457 if(mp){
458 for(var param in mp){
459 dojo.registerModulePath(param, mp[param]);
460 }
461 }
462 })();
463
464 //Load debug code if necessary.
465 if(dojo.config.isDebug){
466 dojo.require("dojo._firebug.firebug");
467 }
468
469 if(dojo.config.debugAtAllCosts){
470 // this breaks the new AMD based module loader. The XDomain won't be necessary
471 // anyway if you switch to the asynchronous loader
472 //dojo.config.useXDomain = true;
473 //dojo.require("dojo._base._loader.loader_xd");
474 dojo.require("dojo._base._loader.loader_debug");
475 dojo.require("dojo.i18n");
476 }
477