mirror of
https://github.com/StarCitizenTools/mediawiki-skins-Citizen.git
synced 2024-11-24 06:24:22 +00:00
refactor(core): remove duplicated auto theme handling
Refactor auto theme handling into inline script since theme.js is basically duplicated code at this point. Also add the event listener whenever auto theme is set. Closes: #461
This commit is contained in:
parent
71999f8838
commit
da619c793b
|
@ -75,7 +75,7 @@ class SkinHooks implements SkinPageReadyConfigHook, BeforePageDisplayHook {
|
|||
$script = sprintf(
|
||||
'<script%s>%s</script>',
|
||||
$nonce !== false ? sprintf( ' nonce="%s"', $nonce ) : '',
|
||||
'window.applyPref=()=>{const a="skin-citizen-",b={fontsize:"font-size",pagewidth:"--width-layout",lineheight:"--line-height"},c=()=>["auto","dark","light"].map(b=>a+b),d=a=>{let b=document.getElementById("citizen-style");null===b&&(b=document.createElement("style"),b.setAttribute("id","citizen-style"),document.head.appendChild(b)),b.textContent=`:root{${a}}`};try{const e=window.localStorage.getItem("skin-citizen-theme");let f="";if(null!==e){const b=document.documentElement;b.classList.remove(...c(a)),b.classList.add(a+e)}for(const[c,d]of Object.entries(b)){const b=window.localStorage.getItem(a+c);null!==b&&(f+=`${d}:${b};`)}f&&d(f)}catch(a){}},(()=>{const a="skin-citizen-theme";if("auto"===window.localStorage.getItem("skin-citizen-theme")){const b=window.matchMedia("(prefers-color-scheme: dark)")?"dark":"light";window.localStorage.setItem(a,b),window.applyPref(),window.localStorage.setItem(a,"auto")}else window.applyPref()})();'
|
||||
'window.applyPref=()=>{const a="skin-citizen-",b="skin-citizen-theme",c=a=>window.localStorage.getItem(a),d=c("skin-citizen-theme"),e=()=>{const d={fontsize:"font-size",pagewidth:"--width-layout",lineheight:"--line-height"},e=()=>["auto","dark","light"].map(b=>a+b),f=a=>{let b=document.getElementById("citizen-style");null===b&&(b=document.createElement("style"),b.setAttribute("id","citizen-style"),document.head.appendChild(b)),b.textContent=`:root{${a}}`};try{const g=c(b);let h="";if(null!==g){const b=document.documentElement;b.classList.remove(...e(a)),b.classList.add(a+g)}for(const[b,e]of Object.entries(d)){const d=c(a+b);null!==d&&(h+=`${e}:${d};`)}h&&f(h)}catch(a){}};if("auto"===d||null===d){const a=window.matchMedia("(prefers-color-scheme: dark)"),c=a.matches?"dark":"light",d=(a,b)=>window.localStorage.setItem(a,b);d(b,c),e(),a.addEventListener("change",()=>{e()}),d(b,"auto")}else e()},(()=>{window.applyPref()})();'
|
||||
);
|
||||
|
||||
$out->addHeadItem( 'skin.citizen.inline', $script );
|
||||
|
|
|
@ -7,78 +7,102 @@
|
|||
* Mangle using https://jscompress.com/
|
||||
*/
|
||||
window.applyPref = () => {
|
||||
const prefix = 'skin-citizen-';
|
||||
const cssProps = {
|
||||
fontsize: 'font-size',
|
||||
pagewidth: '--width-layout',
|
||||
lineheight: '--line-height'
|
||||
const
|
||||
prefix = 'skin-citizen-',
|
||||
themeKey = prefix + 'theme';
|
||||
|
||||
const getStorage = ( key ) => {
|
||||
return window.localStorage.getItem( key );
|
||||
};
|
||||
|
||||
// Generates an array of prefix-(auto|dark|light) strings
|
||||
const classNames = () => {
|
||||
return [ 'auto', 'dark', 'light' ].map( ( themeType ) => {
|
||||
return prefix + themeType;
|
||||
} );
|
||||
};
|
||||
const targetTheme = getStorage( themeKey );
|
||||
|
||||
const injectStyles = ( css ) => {
|
||||
const styleId = 'citizen-style';
|
||||
let style = document.getElementById( styleId );
|
||||
const apply = () => {
|
||||
const cssProps = {
|
||||
fontsize: 'font-size',
|
||||
pagewidth: '--width-layout',
|
||||
lineheight: '--line-height'
|
||||
};
|
||||
|
||||
if ( style === null ) {
|
||||
style = document.createElement( 'style' );
|
||||
style.setAttribute( 'id', styleId );
|
||||
document.head.appendChild( style );
|
||||
}
|
||||
style.textContent = `:root{${css}}`;
|
||||
};
|
||||
// Generates an array of prefix-(auto|dark|light) strings
|
||||
const classNames = () => {
|
||||
return [ 'auto', 'dark', 'light' ].map( ( themeType ) => {
|
||||
return prefix + themeType;
|
||||
} );
|
||||
};
|
||||
|
||||
try {
|
||||
const theme = window.localStorage.getItem( prefix + 'theme' );
|
||||
const injectStyles = ( css ) => {
|
||||
const styleId = 'citizen-style';
|
||||
let style = document.getElementById( styleId );
|
||||
|
||||
let cssDeclaration = '';
|
||||
|
||||
// Apply pref by changing class
|
||||
if ( theme !== null ) {
|
||||
const htmlElement = document.documentElement;
|
||||
// Remove all theme classes then add the right one
|
||||
// The following classes are used here:
|
||||
// * skin-citizen-auto
|
||||
// * skin-citizen-light
|
||||
// * skin-citizen-dark
|
||||
htmlElement.classList.remove( ...classNames( prefix ) );
|
||||
|
||||
htmlElement.classList.add( prefix + theme );
|
||||
}
|
||||
|
||||
// Apply pref by adding CSS to root
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
for ( const [ key, property ] of Object.entries( cssProps ) ) {
|
||||
const value = window.localStorage.getItem( prefix + key );
|
||||
|
||||
if ( value !== null ) {
|
||||
cssDeclaration += `${property}:${value};`;
|
||||
if ( style === null ) {
|
||||
style = document.createElement( 'style' );
|
||||
style.setAttribute( 'id', styleId );
|
||||
document.head.appendChild( style );
|
||||
}
|
||||
}
|
||||
style.textContent = `:root{${css}}`;
|
||||
};
|
||||
|
||||
if ( cssDeclaration ) {
|
||||
injectStyles( cssDeclaration );
|
||||
try {
|
||||
const theme = getStorage( themeKey );
|
||||
|
||||
let cssDeclaration = '';
|
||||
|
||||
// Apply pref by changing class
|
||||
if ( theme !== null ) {
|
||||
const htmlElement = document.documentElement;
|
||||
// Remove all theme classes then add the right one
|
||||
// The following classes are used here:
|
||||
// * skin-citizen-auto
|
||||
// * skin-citizen-light
|
||||
// * skin-citizen-dark
|
||||
htmlElement.classList.remove( ...classNames( prefix ) );
|
||||
|
||||
htmlElement.classList.add( prefix + theme );
|
||||
}
|
||||
|
||||
// Apply pref by adding CSS to root
|
||||
/* eslint-disable-next-line compat/compat */
|
||||
for ( const [ key, property ] of Object.entries( cssProps ) ) {
|
||||
const value = getStorage( prefix + key );
|
||||
|
||||
if ( value !== null ) {
|
||||
cssDeclaration += `${property}:${value};`;
|
||||
}
|
||||
}
|
||||
|
||||
if ( cssDeclaration ) {
|
||||
injectStyles( cssDeclaration );
|
||||
}
|
||||
} catch ( e ) {
|
||||
}
|
||||
} catch ( e ) {
|
||||
};
|
||||
|
||||
// Set up auto theme based on prefers-color-scheme
|
||||
if ( targetTheme === 'auto' || targetTheme === null ) {
|
||||
const prefersDark = window.matchMedia( '(prefers-color-scheme: dark)' );
|
||||
const autoTheme = prefersDark.matches ? 'dark' : 'light';
|
||||
|
||||
const setStorage = ( key, value ) => {
|
||||
return window.localStorage.setItem( key, value );
|
||||
};
|
||||
|
||||
// Set to the right theme temporarily
|
||||
setStorage( themeKey, autoTheme );
|
||||
apply();
|
||||
|
||||
// Attach listener for future changes
|
||||
prefersDark.addEventListener( 'change', () => {
|
||||
apply();
|
||||
} );
|
||||
|
||||
// Reset back to auto
|
||||
setStorage( themeKey, 'auto' );
|
||||
} else {
|
||||
apply();
|
||||
}
|
||||
};
|
||||
|
||||
( () => {
|
||||
const themeId = 'skin-citizen-theme';
|
||||
// Set up auto theme based on prefers-color-scheme
|
||||
if ( window.localStorage.getItem( themeId ) === 'auto' ) {
|
||||
const autoTheme = window.matchMedia( '(prefers-color-scheme: dark)' ) ? 'dark' : 'light';
|
||||
// Set to the right theme temporarily
|
||||
window.localStorage.setItem( themeId, autoTheme );
|
||||
window.applyPref();
|
||||
// Reset back to auto
|
||||
window.localStorage.setItem( themeId, 'auto' );
|
||||
} else {
|
||||
window.applyPref();
|
||||
}
|
||||
window.applyPref();
|
||||
} )();
|
||||
|
|
|
@ -85,14 +85,11 @@ function onTitleHidden( document ) {
|
|||
* @return {void}
|
||||
*/
|
||||
function main( window ) {
|
||||
const
|
||||
theme = require( './theme.js' ),
|
||||
search = require( './search.js' );
|
||||
const search = require( './search.js' );
|
||||
|
||||
const tocContainer = document.getElementById( 'toc' );
|
||||
|
||||
enableCssAnimations( window.document );
|
||||
theme.init( window );
|
||||
search.init( window );
|
||||
onTitleHidden( window.document );
|
||||
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
/**
|
||||
* @param {Window} window
|
||||
* @return {void}
|
||||
*/
|
||||
function initThemeSettings( window ) {
|
||||
const setLocalStorage = ( themeName ) => {
|
||||
try {
|
||||
// eslint-disable-next-line indent
|
||||
localStorage.setItem( 'skin-citizen-theme', themeName );
|
||||
} catch ( e ) {}
|
||||
};
|
||||
|
||||
const prefersDark = window.matchMedia( '(prefers-color-scheme: dark)' ),
|
||||
applyTheme = () => {
|
||||
window.applyPref();
|
||||
// So that theme is applied but localStorage keeps the auto config
|
||||
setLocalStorage( 'auto' );
|
||||
};
|
||||
|
||||
// Monitor prefers-color-scheme changes
|
||||
prefersDark.addEventListener( 'change', ( event ) => {
|
||||
setLocalStorage( event.matches ? 'dark' : 'light' );
|
||||
applyTheme();
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Window} window
|
||||
* @return {void}
|
||||
*/
|
||||
function initTheme( window ) {
|
||||
if ( typeof window.mw !== 'undefined' ) {
|
||||
const theme = window.localStorage.getItem( 'skin-citizen-theme' );
|
||||
if ( theme === null || theme === 'auto' ) {
|
||||
initThemeSettings( window );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
init: initTheme
|
||||
};
|
|
@ -191,8 +191,7 @@
|
|||
"resources/skins.citizen.scripts/scrollObserver.js",
|
||||
"resources/skins.citizen.scripts/sectionObserver.js",
|
||||
"resources/skins.citizen.scripts/search.js",
|
||||
"resources/skins.citizen.scripts/tableOfContents.js",
|
||||
"resources/skins.citizen.scripts/theme.js"
|
||||
"resources/skins.citizen.scripts/tableOfContents.js"
|
||||
],
|
||||
"targets": [
|
||||
"desktop",
|
||||
|
|
Loading…
Reference in a new issue