Merge "Give instructions on removing email address from account"
[mediawiki.git] / resources / src / startup.js
blob1a10f8379e4c2590d101bde425e3e0efbaa3f3aa
1 /**
2  * This script provides a function which is run to evaluate whether or not to
3  * continue loading jQuery and the MediaWiki modules. This code should work on
4  * even the most ancient of browsers, so be very careful when editing.
5  */
6 /*jshint unused: false, evil: true */
7 /*globals mw, RLQ: true, $VARS, $CODE, performance */
9 var mediaWikiLoadStart = ( new Date() ).getTime(),
11         mwPerformance = ( window.performance && performance.mark ) ? performance : {
12                 mark: function () {}
13         };
15 mwPerformance.mark( 'mwLoadStart' );
17 /**
18  * Returns false for Grade C supported browsers.
19  *
20  * This function should only be used by the Startup module, do not expand it to
21  * be generally useful beyond startup.
22  *
23  * See also:
24  * - https://www.mediawiki.org/wiki/Compatibility#Browsers
25  * - https://jquery.com/browser-support/
26  */
27 function isCompatible( ua ) {
28         if ( ua === undefined ) {
29                 ua = navigator.userAgent;
30         }
32         // Browsers with outdated or limited JavaScript engines get the no-JS experience
33         return !(
34                 // Internet Explorer < 8
35                 ( ua.indexOf( 'MSIE' ) !== -1 && parseFloat( ua.split( 'MSIE' )[ 1 ] ) < 8 ) ||
36                 // Firefox < 3
37                 ( ua.indexOf( 'Firefox/' ) !== -1 && parseFloat( ua.split( 'Firefox/' )[ 1 ] ) < 3 ) ||
38                 // Opera < 12
39                 ( ua.indexOf( 'Opera/' ) !== -1 && ( ua.indexOf( 'Version/' ) === -1 ?
40                         // "Opera/x.y"
41                         parseFloat( ua.split( 'Opera/' )[ 1 ] ) < 10 :
42                         // "Opera/9.80 ... Version/x.y"
43                         parseFloat( ua.split( 'Version/' )[ 1 ] ) < 12
44                 ) ) ||
45                 // "Mozilla/0.0 ... Opera x.y"
46                 ( ua.indexOf( 'Opera ' ) !== -1 && parseFloat( ua.split( ' Opera ' )[ 1 ] ) < 10 ) ||
47                 // BlackBerry < 6
48                 ua.match( /BlackBerry[^\/]*\/[1-5]\./ ) ||
49                 // Open WebOS < 1.5
50                 ua.match( /webOS\/1\.[0-4]/ ) ||
51                 // Anything PlayStation based.
52                 ua.match( /PlayStation/i ) ||
53                 // Any Symbian based browsers
54                 ua.match( /SymbianOS|Series60/ ) ||
55                 // Any NetFront based browser
56                 ua.match( /NetFront/ ) ||
57                 // Opera Mini, all versions
58                 ua.match( /Opera Mini/ ) ||
59                 // Nokia's Ovi Browser
60                 ua.match( /S40OviBrowser/ ) ||
61                 // MeeGo's browser
62                 ua.match( /MeeGo/ ) ||
63                 // Google Glass browser groks JS but UI is too limited
64                 ( ua.match( /Glass/ ) && ua.match( /Android/ ) )
65         );
68 // Conditional script injection
69 ( function () {
70         if ( !isCompatible() ) {
71                 // Undo class swapping in case of an unsupported browser.
72                 // See OutputPage::getHeadScripts().
73                 document.documentElement.className = document.documentElement.className
74                         .replace( /(^|\s)client-js(\s|$)/, '$1client-nojs$2' );
75                 return;
76         }
78         /**
79          * The $CODE and $VARS placeholders are substituted in ResourceLoaderStartUpModule.php.
80          */
81         function startUp() {
82                 mw.config = new mw.Map( $VARS.wgLegacyJavaScriptGlobals );
84                 $CODE.registrations();
86                 mw.config.set( $VARS.configuration );
88                 // Must be after mw.config.set because these callbacks may use mw.loader which
89                 // needs to have values 'skin', 'debug' etc. from mw.config.
90                 window.RLQ = window.RLQ || [];
91                 while ( RLQ.length ) {
92                         RLQ.shift()();
93                 }
94                 window.RLQ = {
95                         push: function ( fn ) {
96                                 fn();
97                         }
98                 };
99         }
101         var script = document.createElement( 'script' );
102         script.src = $VARS.baseModulesUri;
103         script.onload = script.onreadystatechange = function () {
104                 if ( !script.readyState || /loaded|complete/.test( script.readyState ) ) {
105                         // Clean up
106                         script.onload = script.onreadystatechange = null;
107                         script = null;
108                         // Callback
109                         startUp();
110                 }
111         };
112         document.getElementsByTagName( 'head' )[ 0 ].appendChild( script );
113 }() );