mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/Vector.git
synced 2024-11-23 15:26:47 +00:00
Make the limited width and font size controls work for logged in users
For time being manage classes inside Vector. Document with FIXME and a test. Bug: T351447 Change-Id: Icc084a59a0141ec2b7c772cf92e8cc58c11f15b1
This commit is contained in:
parent
c4802af02c
commit
845a0ab71d
|
@ -47,6 +47,10 @@ module.exports = {
|
|||
'vue'
|
||||
],
|
||||
|
||||
modulePathIgnorePatterns: [
|
||||
'<rootDir>/tests/integration-qunit/'
|
||||
],
|
||||
|
||||
// The paths to modules that run some code to configure or
|
||||
// set up the testing environment before each test
|
||||
setupFiles: [
|
||||
|
|
14
package-lock.json
generated
14
package-lock.json
generated
|
@ -15,7 +15,7 @@
|
|||
"@wikimedia/codex": "0.20.0",
|
||||
"@wikimedia/codex-icons": "0.20.0",
|
||||
"@wikimedia/mw-node-qunit": "7.2.0",
|
||||
"@wikimedia/types-wikimedia": "0.4.1",
|
||||
"@wikimedia/types-wikimedia": "0.4.2",
|
||||
"eslint-config-wikimedia": "0.25.1",
|
||||
"eslint-plugin-no-jquery": "2.7.0",
|
||||
"grunt-banana-checker": "0.11.0",
|
||||
|
@ -2562,9 +2562,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@wikimedia/types-wikimedia": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@wikimedia/types-wikimedia/-/types-wikimedia-0.4.1.tgz",
|
||||
"integrity": "sha512-RJUZXQNo+z7zBjcRSsVRR5GH2/R8/aSJc9Vo/ntnTzr8v1TjUlM3Dh4sP6XQODYKm/0HQn+hln3bWyeU6YTyRw==",
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@wikimedia/types-wikimedia/-/types-wikimedia-0.4.2.tgz",
|
||||
"integrity": "sha512-MWZJE6JRUYRSuwajjiO4l7xz6530MUqdTOP0t0AteVm8Gqs+hUEcs5tTmAVJDg/ByvzyZ/M/KsW1UcuTRs0N8g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/abab": {
|
||||
|
@ -14469,9 +14469,9 @@
|
|||
}
|
||||
},
|
||||
"@wikimedia/types-wikimedia": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@wikimedia/types-wikimedia/-/types-wikimedia-0.4.1.tgz",
|
||||
"integrity": "sha512-RJUZXQNo+z7zBjcRSsVRR5GH2/R8/aSJc9Vo/ntnTzr8v1TjUlM3Dh4sP6XQODYKm/0HQn+hln3bWyeU6YTyRw==",
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@wikimedia/types-wikimedia/-/types-wikimedia-0.4.2.tgz",
|
||||
"integrity": "sha512-MWZJE6JRUYRSuwajjiO4l7xz6530MUqdTOP0t0AteVm8Gqs+hUEcs5tTmAVJDg/ByvzyZ/M/KsW1UcuTRs0N8g==",
|
||||
"dev": true
|
||||
},
|
||||
"abab": {
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
"@wikimedia/codex": "0.20.0",
|
||||
"@wikimedia/codex-icons": "0.20.0",
|
||||
"@wikimedia/mw-node-qunit": "7.2.0",
|
||||
"@wikimedia/types-wikimedia": "0.4.1",
|
||||
"@wikimedia/types-wikimedia": "0.4.2",
|
||||
"eslint-config-wikimedia": "0.25.1",
|
||||
"eslint-plugin-no-jquery": "2.7.0",
|
||||
"grunt-banana-checker": "0.11.0",
|
||||
|
|
|
@ -21,14 +21,40 @@ function getClientPreferences() {
|
|||
).map( ( className ) => className.split( '-clientpref-' )[ 0 ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} featureName
|
||||
* @param {string} value
|
||||
*/
|
||||
function toggleDocClassAndSave( featureName, value ) {
|
||||
const pref = config[ featureName ];
|
||||
if ( mw.user.isNamed() ) {
|
||||
// FIXME: Ideally this would be done in mw.user.clientprefs API.
|
||||
// mw.user.clientPrefs.get is marked as being only stable for anonymous and temporary users.
|
||||
// So instead we have to keep track of all the different possible values and remove them
|
||||
// before adding the new class.
|
||||
config[ featureName ].options.forEach( ( possibleValue ) => {
|
||||
document.documentElement.classList.remove( `${featureName}-clientpref-${possibleValue}` );
|
||||
} );
|
||||
document.documentElement.classList.add( `${featureName}-clientpref-${value}` );
|
||||
// Ideally this should be taken care of via a single core helper function.
|
||||
mw.util.debounce( function () {
|
||||
api = api || new mw.Api();
|
||||
api.saveOption( pref.preferenceKey, value );
|
||||
}, 100 )();
|
||||
// END FIXME.
|
||||
} else {
|
||||
// This case is much simpler - the API transparently takes care of classes as well as storage.
|
||||
mw.user.clientPrefs.set( featureName, value );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Element} parent
|
||||
* @param {string} featureName
|
||||
* @param {ClientPreference} pref
|
||||
* @param {string} value
|
||||
* @param {string} currentValue
|
||||
*/
|
||||
function appendRadioToggle( parent, featureName, pref, value, currentValue ) {
|
||||
function appendRadioToggle( parent, featureName, value, currentValue ) {
|
||||
const input = document.createElement( 'input' );
|
||||
const name = `vector-client-pref-${featureName}-group`;
|
||||
const id = `vector-client-pref-${featureName}-value-${value}`;
|
||||
|
@ -55,14 +81,7 @@ function appendRadioToggle( parent, featureName, pref, value, currentValue ) {
|
|||
container.appendChild( label );
|
||||
parent.appendChild( container );
|
||||
input.addEventListener( 'change', () => {
|
||||
// @ts-ignore https://github.com/wikimedia/typescript-types/pull/44
|
||||
mw.user.clientPrefs.set( featureName, value );
|
||||
if ( mw.user.isNamed() ) {
|
||||
mw.util.debounce( function () {
|
||||
api = api || new mw.Api();
|
||||
api.saveOption( pref.preferenceKey, value );
|
||||
}, 100 )();
|
||||
}
|
||||
toggleDocClassAndSave( featureName, value );
|
||||
} );
|
||||
}
|
||||
|
||||
|
@ -87,17 +106,16 @@ function makeClientPreferenceBinaryToggle( featureName ) {
|
|||
if ( !pref ) {
|
||||
return null;
|
||||
}
|
||||
// @ts-ignore https://github.com/wikimedia/typescript-types/pull/44
|
||||
const currentValue = mw.user.clientPrefs.get( featureName );
|
||||
// The client preference was invalid. This shouldn't happen unless a gadget
|
||||
// or script has modified the documentElement.
|
||||
if ( !currentValue ) {
|
||||
if ( typeof currentValue === 'boolean' ) {
|
||||
return null;
|
||||
}
|
||||
const row = createRow( '' );
|
||||
const form = document.createElement( 'form' );
|
||||
pref.options.forEach( ( value ) => {
|
||||
appendRadioToggle( form, featureName, pref, value, currentValue );
|
||||
appendRadioToggle( form, featureName, value, currentValue );
|
||||
} );
|
||||
row.appendChild( form );
|
||||
return row;
|
||||
|
@ -194,5 +212,6 @@ function bind( clickSelector, renderSelector ) {
|
|||
}
|
||||
module.exports = {
|
||||
bind,
|
||||
toggleDocClassAndSave,
|
||||
render
|
||||
};
|
||||
|
|
|
@ -549,6 +549,14 @@
|
|||
"+ext.uls.interface": "skinStyles/ext.uls.interface.less"
|
||||
}
|
||||
},
|
||||
"QUnitTestModule": {
|
||||
"localBasePath": "",
|
||||
"remoteExtPath": "Vector",
|
||||
"dependencies": [ "skins.vector.clientPreferences" ],
|
||||
"scripts": [
|
||||
"tests/integration-qunit/integration.test.js"
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
"VectorClientPreferences": {
|
||||
"value": {
|
||||
|
|
27
tests/integration-qunit/integration.test.js
Normal file
27
tests/integration-qunit/integration.test.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* global QUnit */
|
||||
const clientPreferences = require( 'skins.vector.clientPreferences' );
|
||||
|
||||
/*!
|
||||
* Vector integration tests.
|
||||
*
|
||||
* This should only be used to test APIs that Vector depends on to work.
|
||||
* For unit tests please see tests/jest.
|
||||
*/
|
||||
QUnit.module( 'Vector (integration)', function () {
|
||||
QUnit.test( 'Client preferences: Behaves same for all users', function ( assert ) {
|
||||
const sandbox = this.sandbox;
|
||||
const helper = ( feature, isNamedReturnValue ) => {
|
||||
document.documentElement.setAttribute( 'class', `${feature}-clientpref-0` );
|
||||
const stub = sandbox.stub( mw.user, 'isNamed', () => isNamedReturnValue );
|
||||
clientPreferences.toggleDocClassAndSave( feature, '1' );
|
||||
stub.restore();
|
||||
return document.documentElement.getAttribute( 'class' );
|
||||
};
|
||||
|
||||
assert.strictEqual(
|
||||
helper( 'vector-feature-limited-width', false ),
|
||||
helper( 'vector-feature-limited-width', true ),
|
||||
'The same classes are modified regardless of the user status.'
|
||||
);
|
||||
} );
|
||||
} );
|
|
@ -4,7 +4,8 @@
|
|||
"jest.setup.js",
|
||||
"vendor",
|
||||
"coverage",
|
||||
"tests/jest"
|
||||
"tests/jest",
|
||||
"tests/integration-qunit"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"resolveJsonModule": true,
|
||||
|
|
Loading…
Reference in a new issue