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'
|
'vue'
|
||||||
],
|
],
|
||||||
|
|
||||||
|
modulePathIgnorePatterns: [
|
||||||
|
'<rootDir>/tests/integration-qunit/'
|
||||||
|
],
|
||||||
|
|
||||||
// The paths to modules that run some code to configure or
|
// The paths to modules that run some code to configure or
|
||||||
// set up the testing environment before each test
|
// set up the testing environment before each test
|
||||||
setupFiles: [
|
setupFiles: [
|
||||||
|
|
14
package-lock.json
generated
14
package-lock.json
generated
|
@ -15,7 +15,7 @@
|
||||||
"@wikimedia/codex": "0.20.0",
|
"@wikimedia/codex": "0.20.0",
|
||||||
"@wikimedia/codex-icons": "0.20.0",
|
"@wikimedia/codex-icons": "0.20.0",
|
||||||
"@wikimedia/mw-node-qunit": "7.2.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-config-wikimedia": "0.25.1",
|
||||||
"eslint-plugin-no-jquery": "2.7.0",
|
"eslint-plugin-no-jquery": "2.7.0",
|
||||||
"grunt-banana-checker": "0.11.0",
|
"grunt-banana-checker": "0.11.0",
|
||||||
|
@ -2562,9 +2562,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@wikimedia/types-wikimedia": {
|
"node_modules/@wikimedia/types-wikimedia": {
|
||||||
"version": "0.4.1",
|
"version": "0.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/@wikimedia/types-wikimedia/-/types-wikimedia-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@wikimedia/types-wikimedia/-/types-wikimedia-0.4.2.tgz",
|
||||||
"integrity": "sha512-RJUZXQNo+z7zBjcRSsVRR5GH2/R8/aSJc9Vo/ntnTzr8v1TjUlM3Dh4sP6XQODYKm/0HQn+hln3bWyeU6YTyRw==",
|
"integrity": "sha512-MWZJE6JRUYRSuwajjiO4l7xz6530MUqdTOP0t0AteVm8Gqs+hUEcs5tTmAVJDg/ByvzyZ/M/KsW1UcuTRs0N8g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/abab": {
|
"node_modules/abab": {
|
||||||
|
@ -14469,9 +14469,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@wikimedia/types-wikimedia": {
|
"@wikimedia/types-wikimedia": {
|
||||||
"version": "0.4.1",
|
"version": "0.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/@wikimedia/types-wikimedia/-/types-wikimedia-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@wikimedia/types-wikimedia/-/types-wikimedia-0.4.2.tgz",
|
||||||
"integrity": "sha512-RJUZXQNo+z7zBjcRSsVRR5GH2/R8/aSJc9Vo/ntnTzr8v1TjUlM3Dh4sP6XQODYKm/0HQn+hln3bWyeU6YTyRw==",
|
"integrity": "sha512-MWZJE6JRUYRSuwajjiO4l7xz6530MUqdTOP0t0AteVm8Gqs+hUEcs5tTmAVJDg/ByvzyZ/M/KsW1UcuTRs0N8g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"abab": {
|
"abab": {
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
"@wikimedia/codex": "0.20.0",
|
"@wikimedia/codex": "0.20.0",
|
||||||
"@wikimedia/codex-icons": "0.20.0",
|
"@wikimedia/codex-icons": "0.20.0",
|
||||||
"@wikimedia/mw-node-qunit": "7.2.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-config-wikimedia": "0.25.1",
|
||||||
"eslint-plugin-no-jquery": "2.7.0",
|
"eslint-plugin-no-jquery": "2.7.0",
|
||||||
"grunt-banana-checker": "0.11.0",
|
"grunt-banana-checker": "0.11.0",
|
||||||
|
|
|
@ -21,14 +21,40 @@ function getClientPreferences() {
|
||||||
).map( ( className ) => className.split( '-clientpref-' )[ 0 ] );
|
).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 {Element} parent
|
||||||
* @param {string} featureName
|
* @param {string} featureName
|
||||||
* @param {ClientPreference} pref
|
|
||||||
* @param {string} value
|
* @param {string} value
|
||||||
* @param {string} currentValue
|
* @param {string} currentValue
|
||||||
*/
|
*/
|
||||||
function appendRadioToggle( parent, featureName, pref, value, currentValue ) {
|
function appendRadioToggle( parent, featureName, value, currentValue ) {
|
||||||
const input = document.createElement( 'input' );
|
const input = document.createElement( 'input' );
|
||||||
const name = `vector-client-pref-${featureName}-group`;
|
const name = `vector-client-pref-${featureName}-group`;
|
||||||
const id = `vector-client-pref-${featureName}-value-${value}`;
|
const id = `vector-client-pref-${featureName}-value-${value}`;
|
||||||
|
@ -55,14 +81,7 @@ function appendRadioToggle( parent, featureName, pref, value, currentValue ) {
|
||||||
container.appendChild( label );
|
container.appendChild( label );
|
||||||
parent.appendChild( container );
|
parent.appendChild( container );
|
||||||
input.addEventListener( 'change', () => {
|
input.addEventListener( 'change', () => {
|
||||||
// @ts-ignore https://github.com/wikimedia/typescript-types/pull/44
|
toggleDocClassAndSave( featureName, value );
|
||||||
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 )();
|
|
||||||
}
|
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,17 +106,16 @@ function makeClientPreferenceBinaryToggle( featureName ) {
|
||||||
if ( !pref ) {
|
if ( !pref ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// @ts-ignore https://github.com/wikimedia/typescript-types/pull/44
|
|
||||||
const currentValue = mw.user.clientPrefs.get( featureName );
|
const currentValue = mw.user.clientPrefs.get( featureName );
|
||||||
// The client preference was invalid. This shouldn't happen unless a gadget
|
// The client preference was invalid. This shouldn't happen unless a gadget
|
||||||
// or script has modified the documentElement.
|
// or script has modified the documentElement.
|
||||||
if ( !currentValue ) {
|
if ( typeof currentValue === 'boolean' ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const row = createRow( '' );
|
const row = createRow( '' );
|
||||||
const form = document.createElement( 'form' );
|
const form = document.createElement( 'form' );
|
||||||
pref.options.forEach( ( value ) => {
|
pref.options.forEach( ( value ) => {
|
||||||
appendRadioToggle( form, featureName, pref, value, currentValue );
|
appendRadioToggle( form, featureName, value, currentValue );
|
||||||
} );
|
} );
|
||||||
row.appendChild( form );
|
row.appendChild( form );
|
||||||
return row;
|
return row;
|
||||||
|
@ -194,5 +212,6 @@ function bind( clickSelector, renderSelector ) {
|
||||||
}
|
}
|
||||||
module.exports = {
|
module.exports = {
|
||||||
bind,
|
bind,
|
||||||
|
toggleDocClassAndSave,
|
||||||
render
|
render
|
||||||
};
|
};
|
||||||
|
|
|
@ -549,6 +549,14 @@
|
||||||
"+ext.uls.interface": "skinStyles/ext.uls.interface.less"
|
"+ext.uls.interface": "skinStyles/ext.uls.interface.less"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"QUnitTestModule": {
|
||||||
|
"localBasePath": "",
|
||||||
|
"remoteExtPath": "Vector",
|
||||||
|
"dependencies": [ "skins.vector.clientPreferences" ],
|
||||||
|
"scripts": [
|
||||||
|
"tests/integration-qunit/integration.test.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"VectorClientPreferences": {
|
"VectorClientPreferences": {
|
||||||
"value": {
|
"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",
|
"jest.setup.js",
|
||||||
"vendor",
|
"vendor",
|
||||||
"coverage",
|
"coverage",
|
||||||
"tests/jest"
|
"tests/jest",
|
||||||
|
"tests/integration-qunit"
|
||||||
],
|
],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
|
|
Loading…
Reference in a new issue