Localisation updates from https://translatewiki.net.
[mediawiki.git] / resources / src / startup / clientprefs.js
blobcbc728df23a01a7f89b0bfa48b31d35df9c781a8
1 /*!
2  * Inline script for ResourceLoader\ClientHtml.php.
3  *
4  * This is tested via an exported function that takes `document` and `$VARS`.
5  * See also QUnitTestResources.php.
6  *
7  * Like startup.js, this file is enforced by ESLint to be ES3-syntax compatible and
8  * must degrade gracefully in older browsers.
9  *
10  * Use of ES5 (e.g. forEach) or ES6 methods (not syntax) is safe within the cookie conditional.
11  */
12 /* global $VARS */
13 ( function () {
14         var className = $VARS.jsClass;
15         var cookie = document.cookie.match( /(?:^|; )__COOKIE_PREFIX__mwclientpreferences=([^;]+)/ );
16         if ( cookie ) {
17                 // The comma is escaped by mw.cookie.set
18                 cookie[ 1 ].split( '%2C' ).forEach( function ( pref ) {
19                         // To avoid misuse and to allow emergency shut-off, classes are only set when a matching
20                         // class for the same key already set. For new features, the default class must be set
21                         // a couple of weeks before the feature toggle is deployed, to give time for the
22                         // CDN/HTML cache to roll over.
23                         //
24                         // Regex explanation:
25                         // 1. `\w+`, match the "-value" suffix, this is equivalent to [a-zA-Z0-9_].
26                         //     This is stripped from the desired class to create a match for a current class.
27                         // 2. `[^\w-]`, any non-alphanumeric characters. This should never match but is
28                         //     stripped to ensure regex safety by keeping it simple (no need to escape).
29                         // 3. Match an existing class name as follows:
30                         //    * (^| ) = start of string or space
31                         //    * -clientpref- = enforce present of this literal string
32                         //    * ( |$) = end of string or space
33                         //
34                         // Replacement examples:
35                         // * vector-feature-foo-clientpref-2 -> vector-feature-foo-clientpref-4
36                         // * mw-foo-clientpref-enabled       -> mw-foo-clientpref-disabled
37                         // * mw-display-clientpref-dark      -> mw-display-clientpref-light
38                         className = className.replace(
40                                 new RegExp( '(^| )' + pref.replace( /-clientpref-\w+$|[^\w-]+/g, '' ) + '-clientpref-\\w+( |$)' ),
41                                 '$1' + pref + '$2'
42                         );
43                 } );
44         }
45         document.documentElement.className = className;
46 }() );