2 * Inline script for ResourceLoader\ClientHtml.php.
4 * This is tested via an exported function that takes `document` and `$VARS`.
5 * See also QUnitTestResources.php.
7 * Like startup.js, this file is enforced by ESLint to be ES3-syntax compatible and
8 * must degrade gracefully in older browsers.
10 * Use of ES5 (e.g. forEach) or ES6 methods (not syntax) is safe within the cookie conditional.
14 var className = $VARS.jsClass;
15 var cookie = document.cookie.match( /(?:^|; )__COOKIE_PREFIX__mwclientpreferences=([^;]+)/ );
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.
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
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+( |$)' ),
45 document.documentElement.className = className;