feat(prefs): move page width to clientPrefs

Now all of the existing prefs are migrated to clientPrefs,
we can discard the code from the old system.
This commit is contained in:
alistair3149 2024-04-25 17:41:22 -04:00
parent 964a4a534d
commit 241dc96cfe
No known key found for this signature in database
10 changed files with 49 additions and 294 deletions

View file

@ -43,8 +43,6 @@
"citizen-tagline-ns-help": "Help page",
"citizen-tagline-ns-category": "Category page",
"citizen-tagline-user-regdate": "Joined $1",
"prefs-citizen-pagewidth-label": "Page width",
"prefs-citizen-resetbutton-label": "Reset to default",
"citizen-theme-name": "Color",
"citizen-theme-description": "Change the theme of the wiki",
@ -60,5 +58,10 @@
"citizen-feature-custom-font-size-name": "Text",
"citizen-feature-custom-font-size-0-label": "Small",
"citizen-feature-custom-font-size-1-label": "Standard",
"citizen-feature-custom-font-size-2-label": "Large"
"citizen-feature-custom-font-size-2-label": "Large",
"citizen-feature-custom-width-name": "Width",
"citizen-feature-custom-width-0-label": "Standard",
"citizen-feature-custom-width-1-label": "Wide",
"citizen-feature-custom-width-2-label": "Full"
}

View file

@ -46,8 +46,6 @@
"citizen-tagline-ns-help": "Tagline for pages in help namespace",
"citizen-tagline-ns-category": "Tagline for pages in category namespace",
"citizen-tagline-user-regdate": "Label for registration date in taglines on userpages",
"prefs-citizen-pagewidth-label": "Label for the page width settings",
"prefs-citizen-resetbutton-label": "Label for the reset button that restore default settings",
"citizen-theme-name": "Heading label for setting that allows you to change theme.",
"citizen-theme-description": "Description for theme.",
"citizen-theme-day-label": "Label for light/day theme.",
@ -60,5 +58,9 @@
"citizen-feature-custom-font-size-name": "Heading label for font size",
"citizen-feature-custom-font-size-0-label": "Label for small font size. An adjective that describes \"text\" ({{msg-mw|Citizen-feature-custom-font-size-name}}).",
"citizen-feature-custom-font-size-1-label": "Label for standard font size. An adjective that describes \"text\" ({{msg-mw|Citizen-feature-custom-font-size-name}})",
"citizen-feature-custom-font-size-2-label": "Label for large font size. An adjective that describes \"text\" ({{msg-mw|Citizen-feature-custom-font-size-name}})."
"citizen-feature-custom-font-size-2-label": "Label for large font size. An adjective that describes \"text\" ({{msg-mw|Citizen-feature-custom-font-size-name}}).",
"citizen-feature-custom-width-name": "Heading label for page width",
"citizen-feature-custom-width-0-label": "Label for standard page width. An adjective that describes \"text\" ({{msg-mw|Citizen-feature-custom-width-name}}).",
"citizen-feature-custom-width-1-label": "Label for wide page width. An adjective that describes \"text\" ({{msg-mw|Citizen-feature-custom-width-name}}).",
"citizen-feature-custom-width-2-label": "Label for full page width. An adjective that describes \"text\" ({{msg-mw|Citizen-feature-custom-width-name}})."
}

View file

@ -176,6 +176,7 @@ class SkinCitizen extends SkinMustache {
// Clientprefs feature handling
$this->addClientPrefFeature( 'citizen-feature-pure-black', '0' );
$this->addClientPrefFeature( 'citizen-feature-custom-font-size', '1' );
$this->addClientPrefFeature( 'citizen-feature-custom-width', '0' );
// Collapsible sections
// Load in content pages

View file

@ -10,5 +10,9 @@
"citizen-feature-custom-font-size": {
"options": [ "0", "1", "2" ],
"preferenceKey": "citizen-font-size"
},
"citizen-feature-custom-width": {
"options": [ "0", "1", "2" ],
"preferenceKey": "citizen-width"
}
}

View file

@ -1,12 +1,4 @@
/* global applyPref */
/**
* TODO: Maybe combine the localStorage keys into one object
*/
const
CLASS = 'citizen-pref',
PREFIX_KEY = 'skin-citizen-';
const CLASS = 'citizen-pref';
/**
* Clientprefs names theme differently from Citizen, we will need to translate it
@ -20,127 +12,6 @@ const CLIENTPREFS_THEME_MAP = {
const clientPrefs = require( './clientPrefs.polyfill.js' )();
/**
* Set the value of the input element
*
* @param {string} key
* @param {string} value
*/
function setInputValue( key, value ) {
const element = document.getElementById( CLASS + '-' + key + '__input' );
if ( element ) {
element.value = value;
}
}
/**
* Set the text of the indicator element
*
* @param {string} key
* @param {string} value
*/
function setIndicator( key, value ) {
const element = document.getElementById( CLASS + '-' + key + '__value' );
if ( element ) {
element.innerText = value;
}
}
/**
* Convert the pref values for use with the form input
*
* @param {Object} pref
* @return {Object}
*/
function convertForForm( pref ) {
return {
pagewidth: Number( pref.pagewidth.slice( 0, -2 ) ) / 120 - 6
};
}
/**
* Retrieve localstorage or default preferences
*
* @return {Object} pref
*/
function getPref() {
const rootStyle = window.getComputedStyle( document.documentElement );
const pref = {
pagewidth: mw.storage.get( PREFIX_KEY + 'pagewidth' ) || rootStyle.getPropertyValue( '--width-layout' )
};
return pref;
}
/**
* Save to localstorage if preference is changed
*
* @return {void}
*/
function setPref() {
const
// eslint-disable-next-line compat/compat
formData = Object.fromEntries( new FormData( document.getElementById( CLASS + '-form' ) ) ),
currentPref = convertForForm( getPref() ),
newPref = {
pagewidth: Number( formData[ CLASS + '-pagewidth' ] )
};
if ( currentPref.pagewidth !== newPref.pagewidth ) {
let formattedPageWidth;
// Max setting would be full browser width
if ( newPref.pagewidth === 10 ) {
formattedPageWidth = '100vw';
} else {
formattedPageWidth = ( newPref.pagewidth + 6 ) * 120 + 'px';
}
mw.storage.set( PREFIX_KEY + 'pagewidth', formattedPageWidth );
setIndicator( 'pagewidth', formattedPageWidth );
}
applyPref();
}
/**
* Reset preference by clearing localStorage and inline styles
*
* @return {void}
*/
function resetPref() {
const keys = [ 'pagewidth' ];
// Remove style
if ( document.getElementById( 'citizen-style' ) ) {
document.getElementById( 'citizen-style' ).remove();
}
// Remove localStorage
keys.forEach( ( key ) => {
const keyName = PREFIX_KEY + key;
if ( mw.storage.get( keyName ) ) {
localStorage.removeItem( keyName );
}
} );
const pref = getPref(),
prefValue = convertForForm( pref );
keys.forEach( ( key ) => {
const keyName = PREFIX_KEY + key;
mw.storage.set( keyName, pref[ key ] );
setIndicator( key, pref[ key ] );
setInputValue( key, prefValue[ key ] );
} );
applyPref();
}
/**
* Dismiss the prefernce panel when clicked outside
*
@ -181,22 +52,16 @@ function togglePanel() {
const CLASS_PANEL_ACTIVE = CLASS + '-panel--active';
const
toggle = document.getElementById( CLASS + '-toggle' ),
panel = document.getElementById( CLASS + '-panel' ),
form = document.getElementById( CLASS + '-form' ),
resetButton = document.getElementById( CLASS + '-resetbutton' );
panel = document.getElementById( CLASS + '-panel' );
if ( !panel.classList.contains( CLASS_PANEL_ACTIVE ) ) {
panel.classList.add( CLASS_PANEL_ACTIVE );
toggle.setAttribute( 'aria-expanded', true );
form.addEventListener( 'input', setPref );
resetButton.addEventListener( 'click', resetPref );
window.addEventListener( 'click', dismissOnClickOutside );
window.addEventListener( 'keydown', dismissOnEscape );
} else {
panel.classList.remove( CLASS_PANEL_ACTIVE );
toggle.setAttribute( 'aria-expanded', false );
form.removeEventListener( 'input', setPref );
resetButton.removeEventListener( 'click', resetPref );
window.removeEventListener( 'click', dismissOnClickOutside );
window.removeEventListener( 'keydown', dismissOnEscape );
}
@ -209,9 +74,7 @@ function togglePanel() {
*/
function getMessages() {
const keys = [
'preferences',
'prefs-citizen-pagewidth-label',
'prefs-citizen-resetbutton-label'
'preferences'
],
data = {};
@ -238,10 +101,7 @@ function initPanel( event ) {
'skins.citizen.preferences',
'resources/skins.citizen.preferences/templates/preferences.mustache'
),
data = getMessages(),
pref = getPref(),
prefValue = convertForForm( pref ),
keys = [ 'pagewidth' ];
data = getMessages();
// To Mustache is to jQuery sigh
// TODO: Use ES6 template literals when RL does not screw up multiline
@ -250,12 +110,6 @@ function initPanel( event ) {
// Attach panel after button
event.currentTarget.parentNode.insertBefore( panel, event.currentTarget.nextSibling );
// Set up initial state
keys.forEach( ( key ) => {
setIndicator( key, pref[ key ] );
setInputValue( key, prefValue[ key ] );
} );
togglePanel();
event.currentTarget.addEventListener( 'click', togglePanel );
event.currentTarget.removeEventListener( 'click', initPanel );

View file

@ -6,36 +6,6 @@
background-color: var( --background-color-primary--active );
}
}
&-item {
display: grid;
gap: 0.25rem;
&__label {
display: flex;
justify-content: space-between;
width: 100%;
}
&__title {
font-size: var( --font-size-x-small );
color: var( --color-base--subtle );
letter-spacing: 0.05em;
}
&__value {
font-weight: var( --font-weight-medium );
color: var( --color-base--emphasized );
}
}
// We only show min and max value
&__tickmarks {
display: flex;
justify-content: space-between;
font-size: var( --font-size-x-small );
color: var( --color-base--subtle );
}
}
#citizen-pref {
@ -66,34 +36,6 @@
opacity: 0;
}
}
&-form {
display: grid;
gap: var( --space-md );
margin: var( --space-md ) 0;
}
&-resetbutton {
width: 100%;
padding: var( --space-sm ) var( --space-md );
font-family: inherit;
font-size: var( --font-size-small );
font-weight: var( --font-weight-medium );
color: #fff;
appearance: none;
cursor: pointer;
background: var( --color-destructive );
border: 0;
border-radius: 0 0 var( --border-radius--medium ) var( --border-radius--medium );
&:hover {
background: var( --color-destructive--hover );
}
&:active {
background: var( --color-destructive--active );
}
}
}
// New clientPrefs styles
@ -101,11 +43,12 @@
display: flex;
flex-direction: column;
gap: var( --space-xs );
padding-bottom: var( --space-lg );
form {
display: grid;
// This is not the best because it does not adapt to the text length but will revisit later
grid-template-columns: repeat( 2, 1fr );
grid-template-columns: repeat( 3, 1fr );
gap: var( --space-xxs );
text-align: center;
}
@ -153,10 +96,6 @@
}
#skin-client-prefs-skin-theme {
form {
grid-template-columns: repeat( 3, 1fr );
}
.citizen-client-prefs-radio__label {
background: var( --color-surface-0 );
@ -179,6 +118,10 @@
#skin-client-prefs-citizen-feature-pure-black {
display: none;
form {
grid-template-columns: repeat( 2, 1fr );
}
// Display on dark theme
.skin-theme-clientpref-night & {
display: block;
@ -196,10 +139,6 @@
}
#skin-client-prefs-citizen-feature-custom-font-size {
form {
grid-template-columns: repeat( 3, 1fr );
}
.citizen-client-prefs-radio__label {
font-size: var( --font-size-medium );

View file

@ -12,28 +12,4 @@
<aside id="citizen-pref-panel" class="citizen-pref-panel">
<header id="citizen-pref-header">{{msg-preferences}}</header>
<div class="citizen-client-prefs" id="citizen-client-prefs"></div>
<form id="citizen-pref-form">
{{! Page width }}
<fieldset class="citizen-pref-item" id="citizen-pref-pagewidth">
<label for="citizen-pref-pagewidth" class="citizen-pref-item__label">
<span class="citizen-pref-item__title">{{msg-prefs-citizen-pagewidth-label}}</span>
<span class="citizen-pref-item__value" id="citizen-pref-pagewidth__value"></span>
</label>
<input id="citizen-pref-pagewidth__input" name="citizen-pref-pagewidth" type="range" max="10" list="citizen-pref-pagewidth__tickmarks">
<datalist id="citizen-pref-pagewidth__tickmarks" class="citizen-pref__tickmarks">
<option value="0" label="720px"></option>
<option value="1"></option>
<option value="2"></option>
<option value="3"></option>
<option value="4"></option>
<option value="5"></option>
<option value="6"></option>
<option value="7"></option>
<option value="8"></option>
<option value="9"></option>
<option value="10" label="∞"></option>
</datalist>
</fieldset>
</form>
<button id="citizen-pref-resetbutton">{{msg-prefs-citizen-resetbutton-label}}</button>
</aside>

View file

@ -5,49 +5,6 @@
*/
const LEGACY_PREFIX = 'skin-citizen-';
window.applyPref = () => {
const getStorage = ( key ) => {
return window.localStorage.getItem( key );
};
const apply = () => {
const cssProps = {
pagewidth: '--width-layout'
};
const injectStyles = ( css ) => {
const styleId = 'citizen-style';
let style = document.getElementById( styleId );
if ( style === null ) {
style = document.createElement( 'style' );
style.setAttribute( 'id', styleId );
document.head.appendChild( style );
}
style.textContent = `:root{${ css }}`;
};
try {
let cssDeclaration = '';
// Apply pref by adding CSS to root
for ( const [ key, property ] of Object.entries( cssProps ) ) {
const value = getStorage( LEGACY_PREFIX + key );
if ( value !== null ) {
cssDeclaration += `${ property }:${ value };`;
}
}
if ( cssDeclaration ) {
injectStyles( cssDeclaration );
}
} catch ( e ) {
}
};
apply();
};
/**
* Backported from MW 1.42
* Modified to use localStorage only
@ -89,6 +46,5 @@ window.clientPrefs = () => {
};
( () => {
window.applyPref();
window.clientPrefs();
} )();

View file

@ -89,3 +89,21 @@
font-size: var( --font-size-large );
}
}
.citizen-feature-custom-width-clientpref-0 {
:root& {
--width-layout: 1080px;
}
}
.citizen-feature-custom-width-clientpref-1 {
:root& {
--width-layout: 1600px;
}
}
.citizen-feature-custom-width-clientpref-2 {
:root& {
--width-layout: 100vw;
}
}

View file

@ -233,8 +233,6 @@
],
"messages": [
"preferences",
"prefs-citizen-pagewidth-label",
"prefs-citizen-resetbutton-label",
"citizen-theme-name",
"citizen-theme-description",
"citizen-theme-day-label",
@ -247,7 +245,11 @@
"citizen-feature-custom-font-size-name",
"citizen-feature-custom-font-size-0-label",
"citizen-feature-custom-font-size-1-label",
"citizen-feature-custom-font-size-2-label"
"citizen-feature-custom-font-size-2-label",
"citizen-feature-custom-width-name",
"citizen-feature-custom-width-0-label",
"citizen-feature-custom-width-1-label",
"citizen-feature-custom-width-2-label"
],
"dependencies": [
"mediawiki.storage",