eslint: Re-enable valid-jsdoc and make a pass
[lhc/web/wiklou.git] / resources / src / startup.js
1 /**
2 * Code in this file MUST work on even the most ancient of browsers!
3 *
4 * This file is where we decide whether to initialise the modern run-time.
5 */
6
7 /* global mw, $VARS, $CODE */
8
9 // eslint-disable-next-line no-unused-vars
10 var mediaWikiLoadStart = ( new Date() ).getTime(),
11 mwPerformance = ( window.performance && performance.mark ) ? performance : {
12 mark: function () {}
13 };
14
15 mwPerformance.mark( 'mwLoadStart' );
16
17 /**
18 * See <https://www.mediawiki.org/wiki/Compatibility#Browsers>
19 *
20 * Capabilities required for modern run-time:
21 * - DOM Level 4 & Selectors API Level 1
22 * - HTML5 & Web Storage
23 * - DOM Level 2 Events
24 *
25 * Browsers we support in our modern run-time (Grade A):
26 * - Chrome
27 * - IE 9+
28 * - Firefox 3.5+
29 * - Safari 4+
30 * - Opera 10.5+
31 * - Mobile Safari (iOS 1+)
32 * - Android 2.0+
33 *
34 * Browsers we support in our no-javascript run-time (Grade C):
35 * - IE 6+
36 * - Firefox 3+
37 * - Safari 3+
38 * - Opera 10+
39 * - WebOS < 1.5
40 * - PlayStation
41 * - Symbian-based browsers
42 * - NetFront-based browser
43 * - Opera Mini
44 * - Nokia's Ovi Browser
45 * - MeeGo's browser
46 * - Google Glass
47 *
48 * Other browsers that pass the check are considered Grade X.
49 *
50 * @param {string} [str] User agent, defaults to navigator.userAgent
51 * @return {boolean} User agent is compatible with MediaWiki JS
52 */
53 function isCompatible( str ) {
54 var ua = str || navigator.userAgent;
55 return !!(
56 // http://caniuse.com/#feat=queryselector
57 'querySelector' in document &&
58
59 // http://caniuse.com/#feat=namevalue-storage
60 // https://developer.blackberry.com/html5/apis/v1_0/localstorage.html
61 // https://blog.whatwg.org/this-week-in-html-5-episode-30
62 'localStorage' in window &&
63
64 // http://caniuse.com/#feat=addeventlistener
65 'addEventListener' in window &&
66
67 // Hardcoded exceptions for browsers that pass the requirement but we don't want to
68 // support in the modern run-time.
69 !(
70 ua.match( /webOS\/1\.[0-4]|SymbianOS|Series60|NetFront|Opera Mini|S40OviBrowser|MeeGo|Android.+Glass/ ) ||
71 ua.match( /PlayStation/i ) ||
72 // UC Mini (speed mode on)
73 ua.match( /^Mozilla\/5\.0 .+ Gecko\/$/ )
74 )
75 );
76 }
77
78 // Conditional script injection
79 ( function () {
80 var NORLQ, script;
81 if ( !isCompatible() ) {
82 // Undo class swapping in case of an unsupported browser.
83 // See ResourceLoaderClientHtml::getDocumentAttributes().
84 document.documentElement.className = document.documentElement.className
85 .replace( /(^|\s)client-js(\s|$)/, '$1client-nojs$2' );
86
87 NORLQ = window.NORLQ || [];
88 while ( NORLQ.length ) {
89 NORLQ.shift()();
90 }
91 window.NORLQ = {
92 push: function ( fn ) {
93 fn();
94 }
95 };
96
97 // Clear and disable the other queue
98 window.RLQ = {
99 // No-op
100 push: function () {}
101 };
102
103 return;
104 }
105
106 /**
107 * The $CODE and $VARS placeholders are substituted in ResourceLoaderStartUpModule.php.
108 */
109 function startUp() {
110 mw.config = new mw.Map( $VARS.wgLegacyJavaScriptGlobals );
111
112 $CODE.registrations();
113
114 mw.config.set( $VARS.configuration );
115
116 // Must be after mw.config.set because these callbacks may use mw.loader which
117 // needs to have values 'skin', 'debug' etc. from mw.config.
118 // eslint-disable-next-line vars-on-top
119 var RLQ = window.RLQ || [];
120 while ( RLQ.length ) {
121 RLQ.shift()();
122 }
123 window.RLQ = {
124 push: function ( fn ) {
125 fn();
126 }
127 };
128
129 // Clear and disable the other queue
130 window.NORLQ = {
131 // No-op
132 push: function () {}
133 };
134 }
135
136 script = document.createElement( 'script' );
137 script.src = $VARS.baseModulesUri;
138 script.onload = script.onreadystatechange = function () {
139 if ( !script.readyState || /loaded|complete/.test( script.readyState ) ) {
140 // Clean up
141 script.onload = script.onreadystatechange = null;
142 script = null;
143 // Callback
144 startUp();
145 }
146 };
147 document.getElementsByTagName( 'head' )[ 0 ].appendChild( script );
148 }() );