2022-10-21 18:14:54 +00:00
|
|
|
/** @interface MwApi */
|
|
|
|
|
2022-12-07 22:10:09 +00:00
|
|
|
const debounce = require( /** @type {string} */ ( 'mediawiki.util' ) ).debounce;
|
2024-06-06 02:17:00 +00:00
|
|
|
const userPreferences = require( './userPreferences.js' );
|
2022-10-21 18:14:54 +00:00
|
|
|
|
|
|
|
/**
|
2023-01-24 19:14:00 +00:00
|
|
|
* Saves preference to user preferences and/or cookies.
|
2022-10-21 18:14:54 +00:00
|
|
|
*
|
|
|
|
* @param {string} feature
|
|
|
|
* @param {boolean} enabled
|
|
|
|
*/
|
|
|
|
function save( feature, enabled ) {
|
2023-06-07 11:46:26 +00:00
|
|
|
if ( !mw.user.isNamed() ) {
|
2023-01-24 19:14:00 +00:00
|
|
|
switch ( feature ) {
|
2023-09-14 15:27:58 +00:00
|
|
|
case 'toc-pinned':
|
2023-01-24 19:14:00 +00:00
|
|
|
case 'limited-width':
|
2024-04-12 03:27:34 +00:00
|
|
|
case 'appearance-pinned':
|
2023-07-11 23:13:57 +00:00
|
|
|
// Save the setting under the new system
|
2024-01-11 19:08:25 +00:00
|
|
|
mw.user.clientPrefs.set( `vector-feature-${ feature }`, enabled ? '1' : '0' );
|
2023-01-24 19:14:00 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// not a supported anonymous preference
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
2024-06-06 15:22:05 +00:00
|
|
|
debounce( () => {
|
2024-06-06 02:17:00 +00:00
|
|
|
userPreferences.saveOptions( {
|
|
|
|
[ `vector-${ feature }` ]: enabled ? 1 : 0
|
|
|
|
} );
|
2022-10-21 18:14:54 +00:00
|
|
|
}, 500 )();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-21 18:37:26 +00:00
|
|
|
/**
|
|
|
|
* @param {string} name feature name
|
|
|
|
* @param {boolean} [override] option to force enabled or disabled state.
|
2024-07-08 16:25:30 +00:00
|
|
|
* @param {boolean} [isNotClientPreference] the feature is not a client preference,
|
|
|
|
* so does not persist for logged out users.
|
2022-10-21 18:37:26 +00:00
|
|
|
* @return {boolean} The new feature state (false=disabled, true=enabled).
|
|
|
|
* @throws {Error} if unknown feature toggled.
|
|
|
|
*/
|
2024-07-08 16:25:30 +00:00
|
|
|
function toggleDocClasses( name, override, isNotClientPreference ) {
|
|
|
|
const suffixEnabled = isNotClientPreference ? 'enabled' : 'clientpref-1';
|
|
|
|
const suffixDisabled = isNotClientPreference ? 'disabled' : 'clientpref-0';
|
2024-01-11 19:08:25 +00:00
|
|
|
const featureClassEnabled = `vector-feature-${ name }-${ suffixEnabled }`,
|
2022-10-21 18:37:26 +00:00
|
|
|
classList = document.documentElement.classList,
|
2024-01-11 19:08:25 +00:00
|
|
|
featureClassDisabled = `vector-feature-${ name }-${ suffixDisabled }`,
|
2023-08-08 23:05:14 +00:00
|
|
|
// If neither of the classes can be found it is a legacy feature
|
2024-07-08 16:25:30 +00:00
|
|
|
isLoggedInOnlyFeature = !classList.contains( featureClassDisabled ) &&
|
2023-08-08 23:05:14 +00:00
|
|
|
!classList.contains( featureClassEnabled );
|
2022-10-21 18:37:26 +00:00
|
|
|
|
2023-08-08 23:05:14 +00:00
|
|
|
// Check in legacy mode.
|
2024-07-08 16:25:30 +00:00
|
|
|
if ( isLoggedInOnlyFeature && !isNotClientPreference ) {
|
2023-08-08 23:05:14 +00:00
|
|
|
// try again using the legacy classes
|
|
|
|
return toggleDocClasses( name, override, true );
|
|
|
|
} else if ( classList.contains( featureClassDisabled ) || override === true ) {
|
2022-10-21 18:37:26 +00:00
|
|
|
classList.remove( featureClassDisabled );
|
|
|
|
classList.add( featureClassEnabled );
|
|
|
|
return true;
|
|
|
|
} else if ( classList.contains( featureClassEnabled ) || override === false ) {
|
|
|
|
classList.add( featureClassDisabled );
|
|
|
|
classList.remove( featureClassEnabled );
|
|
|
|
return false;
|
|
|
|
} else {
|
2024-01-11 19:08:25 +00:00
|
|
|
throw new Error( `Attempt to toggle unknown feature: ${ name }` );
|
2022-10-21 18:37:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-11 14:52:45 +00:00
|
|
|
/**
|
|
|
|
* @param {string} name
|
|
|
|
* @throws {Error} if unknown feature toggled.
|
|
|
|
*/
|
|
|
|
function toggle( name ) {
|
2022-10-21 18:37:26 +00:00
|
|
|
const featureState = toggleDocClasses( name );
|
2023-01-11 14:52:45 +00:00
|
|
|
save( name, featureState );
|
|
|
|
}
|
|
|
|
|
2022-11-17 21:51:11 +00:00
|
|
|
/**
|
|
|
|
* Checks if the feature is enabled.
|
|
|
|
*
|
|
|
|
* @param {string} name
|
|
|
|
* @return {boolean}
|
|
|
|
*/
|
|
|
|
function isEnabled( name ) {
|
2023-07-11 23:13:57 +00:00
|
|
|
return document.documentElement.classList.contains( getClass( name, true ) ) ||
|
|
|
|
document.documentElement.classList.contains( getClass( name, true, true ) );
|
2022-11-17 21:51:11 +00:00
|
|
|
}
|
|
|
|
|
2023-03-03 21:23:28 +00:00
|
|
|
/**
|
|
|
|
* Get name of feature class.
|
|
|
|
*
|
|
|
|
* @param {string} name
|
|
|
|
* @param {boolean} featureEnabled
|
2024-07-08 16:25:30 +00:00
|
|
|
* @param {boolean} [isClientPreference] whether the feature is also a client preference
|
2023-03-03 21:23:28 +00:00
|
|
|
* @return {string}
|
|
|
|
*/
|
2024-07-08 16:25:30 +00:00
|
|
|
function getClass( name, featureEnabled, isClientPreference ) {
|
2023-03-03 21:23:28 +00:00
|
|
|
if ( featureEnabled ) {
|
2024-07-08 16:25:30 +00:00
|
|
|
const suffix = isClientPreference ? 'clientpref-1' : 'enabled';
|
2024-01-11 19:08:25 +00:00
|
|
|
return `vector-feature-${ name }-${ suffix }`;
|
2023-03-03 21:23:28 +00:00
|
|
|
} else {
|
2024-07-08 16:25:30 +00:00
|
|
|
const suffix = isClientPreference ? 'clientpref-0' : 'disabled';
|
2024-01-11 19:08:25 +00:00
|
|
|
return `vector-feature-${ name }-${ suffix }`;
|
2023-03-03 21:23:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = { getClass, isEnabled, toggle, toggleDocClasses };
|