mediawiki-skins-Vector/resources/skins.vector.js/features.js
Jon Robson 93a4b76b00 Fixes the pinning functionality
Pinning functionality was broken in
I120f8f7114b33d2cfbd1c3c57ebf41f8b2d7fec4
as it breaks the check against "legacy" feature
classes. We should resort to using the legacy mode
when neither of the new classes can be found.

Bug: T341641
Change-Id: If97a393140175fd41551c3db14b19becb8d9f460
2023-08-08 23:18:12 +00:00

120 lines
3.8 KiB
JavaScript

/** @interface MwApi */
let /** @type {MwApi} */ api;
const debounce = require( /** @type {string} */ ( 'mediawiki.util' ) ).debounce;
/**
* Saves preference to user preferences and/or cookies.
*
* @param {string} feature
* @param {boolean} enabled
*/
function save( feature, enabled ) {
if ( !mw.user.isNamed() ) {
switch ( feature ) {
case 'limited-width':
// FIXME: Cookie is set for cached HTML using the older inline script.
// When removing this code,
// please retain `mw.cookie.set( 'mwclientprefs', null );` for 1-4 weeks
// to clean up after ourselves so users don't have a non-expiring cookie which
// serves no purpose.
if ( enabled ) {
mw.cookie.set( 'mwclientprefs', null );
} else {
mw.cookie.set( 'mwclientprefs', 'vector-feature-limited-width' );
}
// Save the setting under the new system
// @ts-ignore https://github.com/wikimedia/typescript-types/pull/44
mw.user.clientPrefs.set( `vector-feature-${feature}`, enabled ? '1' : '0' );
break;
default:
// not a supported anonymous preference
break;
}
} else {
debounce( function () {
api = api || new mw.Api();
api.saveOption( 'vector-' + feature, enabled ? 1 : 0 );
}, 500 )();
}
}
/**
*
* @param {string} name feature name
* @param {boolean} [override] option to force enabled or disabled state.
* @param {boolean} [isLegacy] should we search for legacy classes
* FIXME: this is for supporting cached HTML,
* this should be removed 1-4 weeks after the patch has been in production.
* @return {boolean} The new feature state (false=disabled, true=enabled).
* @throws {Error} if unknown feature toggled.
*/
function toggleDocClasses( name, override, isLegacy ) {
const suffixEnabled = isLegacy ? 'enabled' : 'clientpref-1';
const suffixDisabled = isLegacy ? 'disabled' : 'clientpref-0';
const featureClassEnabled = `vector-feature-${name}-${suffixEnabled}`,
classList = document.documentElement.classList,
featureClassDisabled = `vector-feature-${name}-${suffixDisabled}`,
// If neither of the classes can be found it is a legacy feature
isLegacyFeature = !classList.contains( featureClassDisabled ) &&
!classList.contains( featureClassEnabled );
// Check in legacy mode.
if ( isLegacyFeature && !isLegacy ) {
// try again using the legacy classes
return toggleDocClasses( name, override, true );
} else if ( classList.contains( featureClassDisabled ) || override === true ) {
classList.remove( featureClassDisabled );
classList.add( featureClassEnabled );
return true;
} else if ( classList.contains( featureClassEnabled ) || override === false ) {
classList.add( featureClassDisabled );
classList.remove( featureClassEnabled );
return false;
} else {
throw new Error( `Attempt to toggle unknown feature: ${name}` );
}
}
/**
* @param {string} name
* @throws {Error} if unknown feature toggled.
*/
function toggle( name ) {
const featureState = toggleDocClasses( name );
save( name, featureState );
}
/**
* Checks if the feature is enabled.
*
* @param {string} name
* @return {boolean}
*/
function isEnabled( name ) {
return document.documentElement.classList.contains( getClass( name, true ) ) ||
document.documentElement.classList.contains( getClass( name, true, true ) );
}
/**
* Get name of feature class.
*
* @param {string} name
* @param {boolean} featureEnabled
* @param {boolean} [isLegacy] FIXME: this is for supporting cached HTML,
* this should be removed 1-4 weeks after the patch has been in production.
* @return {string}
*/
function getClass( name, featureEnabled, isLegacy ) {
if ( featureEnabled ) {
const suffix = isLegacy ? 'enabled' : '1';
return `vector-feature-${name}-${suffix}`;
} else {
const suffix = isLegacy ? 'disabled' : '0';
return `vector-feature-${name}-${suffix}`;
}
}
module.exports = { getClass, isEnabled, toggle, toggleDocClasses };