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