/**
- * This script provides a function which is run to evaluate whether or not to
- * continue loading jQuery and the MediaWiki modules. This code should work on
- * even the most ancient of browsers, so be very careful when editing.
+ * Code in this file MUST work on even the most ancient of browsers!
+ *
+ * This file is where we decide whether to initialise the modern run-time.
*/
/*jshint unused: false, evil: true */
/*globals mw, RLQ: true, NORLQ: true, $VARS, $CODE, performance */
mwPerformance.mark( 'mwLoadStart' );
/**
- * Returns false for Grade C supported browsers.
+ * See <https://www.mediawiki.org/wiki/Compatibility#Browsers>
+ *
+ * Capabilities required for modern run-time:
+ * - DOM Level 4 & Selectors API Level 1
+ * - HTML5 & Web Storage
+ * - DOM Level 2 Events
+ *
+ * Browsers we support in our modern run-time (Grade A):
+ * - Chrome
+ * - IE 9+
+ * - Firefox 3.5+
+ * - Safari 4+
+ * - Opera 10.5+
+ * - Mobile Safari (iOS 1+)
+ * - Android 2.0+
*
- * This function should only be used by the Startup module, do not expand it to
- * be generally useful beyond startup.
+ * Browsers we support in our no-javascript run-time (Grade C):
+ * - IE 6+
+ * - Firefox 3+
+ * - Safari 3+
+ * - Opera 10+
+ * - WebOS < 1.5
+ * - PlayStation
+ * - Symbian-based browsers
+ * - NetFront-based browser
+ * - Opera Mini
+ * - Nokia's Ovi Browser
+ * - MeeGo's browser
+ * - Google Glass
*
- * See also:
- * - https://www.mediawiki.org/wiki/Compatibility#Browsers
- * - https://jquery.com/browser-support/
+ * Other browsers that pass the check are considered Grade X.
*/
-function isCompatible( ua ) {
- if ( ua === undefined ) {
- ua = navigator.userAgent;
- }
+function isCompatible( str ) {
+ var ua = str || navigator.userAgent;
+ return !!(
+ // http://caniuse.com/#feat=queryselector
+ 'querySelector' in document
+
+ // http://caniuse.com/#feat=namevalue-storage
+ // https://developer.blackberry.com/html5/apis/v1_0/localstorage.html
+ // https://blog.whatwg.org/this-week-in-html-5-episode-30
+ && 'localStorage' in window
+
+ // http://caniuse.com/#feat=addeventlistener
+ && 'addEventListener' in window
- // Browsers with outdated or limited JavaScript engines get the no-JS experience
- return !(
- // Internet Explorer < 9
- ( ua.indexOf( 'MSIE' ) !== -1 && parseFloat( ua.split( 'MSIE' )[ 1 ] ) < 9 ) ||
- // Firefox < 3
- ( ua.indexOf( 'Firefox/' ) !== -1 && parseFloat( ua.split( 'Firefox/' )[ 1 ] ) < 3 ) ||
- // Opera < 12
- ( ua.indexOf( 'Opera/' ) !== -1 && ( ua.indexOf( 'Version/' ) === -1 ?
- // "Opera/x.y"
- parseFloat( ua.split( 'Opera/' )[ 1 ] ) < 10 :
- // "Opera/9.80 ... Version/x.y"
- parseFloat( ua.split( 'Version/' )[ 1 ] ) < 12
- ) ) ||
- // "Mozilla/0.0 ... Opera x.y"
- ( ua.indexOf( 'Opera ' ) !== -1 && parseFloat( ua.split( ' Opera ' )[ 1 ] ) < 10 ) ||
- // BlackBerry < 6
- ua.match( /BlackBerry[^\/]*\/[1-5]\./ ) ||
- // Open WebOS < 1.5
- ua.match( /webOS\/1\.[0-4]/ ) ||
- // Anything PlayStation based.
- ua.match( /PlayStation/i ) ||
- // Any Symbian based browsers
- ua.match( /SymbianOS|Series60/ ) ||
- // Any NetFront based browser
- ua.match( /NetFront/ ) ||
- // Opera Mini, all versions
- ua.match( /Opera Mini/ ) ||
- // Nokia's Ovi Browser
- ua.match( /S40OviBrowser/ ) ||
- // MeeGo's browser
- ua.match( /MeeGo/ ) ||
- // Google Glass browser groks JS but UI is too limited
- ( ua.match( /Glass/ ) && ua.match( /Android/ ) )
+ // Hardcoded exceptions for browsers that pass the requirement but we don't want to
+ // support in the modern run-time.
+ && !(
+ ua.match( /webOS\/1\.[0-4]/ ) ||
+ ua.match( /PlayStation/i ) ||
+ ua.match( /SymbianOS|Series60|NetFront|Opera Mini|S40OviBrowser|MeeGo/ ) ||
+ ( ua.match( /Glass/ ) && ua.match( /Android/ ) )
+ )
);
}
/*global isCompatible: true */
( function ( $ ) {
var testcases = {
- gradeA: [
+ tested: [
+ /* Grade A */
+
// Chrome
'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.205 Safari/534.16',
// Firefox 4+
'Mozilla/5.0 (ipod: U;CPU iPhone OS 2_2 like Mac OS X: es_es) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.0 Mobile/3B48b Safari/419.3',
'Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3B48b Safari/419.3',
// Android
- 'Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17'
- ],
- gradeC: [
+ 'Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17',
+
+ /* Grade C */
+
// Internet Explorer < 9
'Mozilla/2.0 (compatible; MSIE 3.03; Windows 3.1)',
'Mozilla/4.0 (compatible; MSIE 4.01; Windows 95)',
// BlackBerry < 6
'BlackBerry9300/5.0.0.716 Profile/MIDP-2.1 Configuration/CLDC-1.1 VendorID/133',
'BlackBerry7250/4.0.0 Profile/MIDP-2.0 Configuration/CLDC-1.1',
- // Open WebOS < 1.5 (Palm Pre, Palm Pixi)
- 'Mozilla/5.0 (webOS/1.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/1.0',
- 'Mozilla/5.0 (webOS/1.4.0; U; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Version/1.0 Safari/532.2 Pixi/1.1 ',
- // SymbianOS
- 'NokiaN95_8GB-3;Mozilla/5.0 SymbianOS/9.2;U;Series60/3.1 NokiaN95_8GB-3/11.2.011 Profile/MIDP-2.0 Configuration/CLDC-1.1 AppleWebKit/413 (KHTML, like Gecko)',
- 'Nokia7610/2.0 (5.0509.0) SymbianOS/7.0s Series60/2.1 Profile/MIDP-2.0 Configuration/CLDC-1.0 ',
- 'Mozilla/5.0 (SymbianOS/9.1; U; [en]; SymbianOS/91 Series60/3.0) AppleWebKit/413 (KHTML, like Gecko) Safari/413',
- 'Mozilla/5.0 (SymbianOS/9.3; Series60/3.2 NokiaE52-2/091.003; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/533.4 (KHTML, like Gecko) NokiaBrowser/7.3.1.34 Mobile Safari/533.4',
- // NetFront
- 'Mozilla/4.0 (compatible; Linux 2.6.10) NetFront/3.3 Kindle/1.0 (screen 600x800)',
- 'Mozilla/4.0 (compatible; Linux 2.6.22) NetFront/3.4 Kindle/2.0 (screen 824x1200; rotate)',
- 'Mozilla/4.08 (Windows; Mobile Content Viewer/1.0) NetFront/3.2',
- // Opera Mini
- 'Opera/9.80 (J2ME/MIDP; Opera Mini/3.1.10423/22.387; U; en) Presto/2.5.25 Version/10.54',
- 'Opera/9.50 (J2ME/MIDP; Opera Mini/4.0.10031/298; U; en)',
- 'Opera/9.80 (J2ME/MIDP; Opera Mini/6.24093/26.1305; U; en) Presto/2.8.119 Version/10.54',
- 'Opera/9.80 (Android; Opera Mini/7.29530/27.1407; U; en) Presto/2.8.119 Version/11.10',
- // Ovi Browser
- 'Mozilla/5.0 (Series40; NokiaX3-02/05.60; Profile/MIDP-2.1 Configuration/CLDC-1.1) Gecko/20100401 S40OviBrowser/3.2.0.0.6',
- 'Mozilla/5.0 (Series40; Nokia305/05.92; Profile/MIDP-2.1 Configuration/CLDC-1.1) Gecko/20100401 S40OviBrowser/3.7.0.0.11',
- // Google Glass
- 'Mozilla/5.0 (Linux; U; Android 4.0.4; en-us; Glass 1 Build/IMM76L; XE11) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
- // MeeGo
- 'Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13'
- ],
- // No explicit support for or against these browsers, they're given a shot at Grade A.
- gradeX: [
+
+ /* Grade X */
+
// Firefox 3.6
'Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3',
// Gecko
'I\'m an unknown browser',
// Empty
''
+ ],
+ blacklisted: [
+ /* Grade C */
+
+ // Open WebOS < 1.5 (Palm Pre, Palm Pixi)
+ 'Mozilla/5.0 (webOS/1.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/1.0',
+ 'Mozilla/5.0 (webOS/1.4.0; U; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Version/1.0 Safari/532.2 Pixi/1.1 ',
+ // SymbianOS
+ 'NokiaN95_8GB-3;Mozilla/5.0 SymbianOS/9.2;U;Series60/3.1 NokiaN95_8GB-3/11.2.011 Profile/MIDP-2.0 Configuration/CLDC-1.1 AppleWebKit/413 (KHTML, like Gecko)',
+ 'Nokia7610/2.0 (5.0509.0) SymbianOS/7.0s Series60/2.1 Profile/MIDP-2.0 Configuration/CLDC-1.0 ',
+ 'Mozilla/5.0 (SymbianOS/9.1; U; [en]; SymbianOS/91 Series60/3.0) AppleWebKit/413 (KHTML, like Gecko) Safari/413',
+ 'Mozilla/5.0 (SymbianOS/9.3; Series60/3.2 NokiaE52-2/091.003; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/533.4 (KHTML, like Gecko) NokiaBrowser/7.3.1.34 Mobile Safari/533.4',
+ // NetFront
+ 'Mozilla/4.0 (compatible; Linux 2.6.10) NetFront/3.3 Kindle/1.0 (screen 600x800)',
+ 'Mozilla/4.0 (compatible; Linux 2.6.22) NetFront/3.4 Kindle/2.0 (screen 824x1200; rotate)',
+ 'Mozilla/4.08 (Windows; Mobile Content Viewer/1.0) NetFront/3.2',
+ // Opera Mini
+ 'Opera/9.80 (J2ME/MIDP; Opera Mini/3.1.10423/22.387; U; en) Presto/2.5.25 Version/10.54',
+ 'Opera/9.50 (J2ME/MIDP; Opera Mini/4.0.10031/298; U; en)',
+ 'Opera/9.80 (J2ME/MIDP; Opera Mini/6.24093/26.1305; U; en) Presto/2.8.119 Version/10.54',
+ 'Opera/9.80 (Android; Opera Mini/7.29530/27.1407; U; en) Presto/2.8.119 Version/11.10',
+ // Ovi Browser
+ 'Mozilla/5.0 (Series40; NokiaX3-02/05.60; Profile/MIDP-2.1 Configuration/CLDC-1.1) Gecko/20100401 S40OviBrowser/3.2.0.0.6',
+ 'Mozilla/5.0 (Series40; Nokia305/05.92; Profile/MIDP-2.1 Configuration/CLDC-1.1) Gecko/20100401 S40OviBrowser/3.7.0.0.11',
+ // Google Glass
+ 'Mozilla/5.0 (Linux; U; Android 4.0.4; en-us; Glass 1 Build/IMM76L; XE11) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
+ // MeeGo
+ 'Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13'
]
};
QUnit.module( 'startup', QUnit.newMwEnvironment() );
- QUnit.test( 'isCompatible( Grade A )', testcases.gradeA.length, function ( assert ) {
- $.each( testcases.gradeA, function ( i, ua ) {
+ QUnit.test( 'isCompatible( featureTestable )', testcases.tested.length, function ( assert ) {
+ $.each( testcases.tested, function ( i, ua ) {
assert.strictEqual( isCompatible( ua ), true, ua );
}
);
} );
- QUnit.test( 'isCompatible( Grade C )', testcases.gradeC.length, function ( assert ) {
- $.each( testcases.gradeC, function ( i, ua ) {
+ QUnit.test( 'isCompatible( blacklisted )', testcases.blacklisted.length, function ( assert ) {
+ $.each( testcases.blacklisted, function ( i, ua ) {
assert.strictEqual( isCompatible( ua ), false, ua );
}
);
} );
-
- QUnit.test( 'isCompatible( Grade X )', testcases.gradeX.length, function ( assert ) {
- $.each( testcases.gradeX, function ( i, ua ) {
- assert.strictEqual( isCompatible( ua ), true, ua );
- }
- );
- } );
-
}( jQuery ) );