mediawiki-skin-crystal/resources/main.js

122 lines
4.5 KiB
JavaScript

// This is the skin's only javascript file. If you want to add more JS files, you need to include them in skin.json's ResourceModules section, the way this one is.
// This all is for the color scheme toggle. Javascript is only truly necessary for the user's choice to persist. Without the toggle, the CSS will still respect the browser-level preference.
function getPreferredColorScheme(){
let systemScheme = 'light';
if (window.matchMedia('(prefers-color-scheme: dark)').matches){
systemScheme = 'dark';
}
let chosenScheme = systemScheme;
if (localStorage.getItem('scheme')) {
chosenScheme = localStorage.getItem('scheme');
}
if (systemScheme === chosenScheme) {
localStorage.removeItem('scheme')
}
return chosenScheme;
}
function savePreferredColorScheme(scheme) {
let systemScheme = 'light';
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
systemScheme = 'dark';
};
if (systemScheme === scheme) {
localStorage.removeItem('scheme');
} else {
localStorage.setItem('scheme', scheme);
};
}
function toggleColorScheme() {
let newScheme = 'light';
let scheme = getPreferredColorScheme();
if (scheme === 'light') {
newScheme = 'dark';
}
applyPreferredColorScheme(newScheme);
savePreferredColorScheme(newScheme);
}
function applyPreferredColorScheme(scheme) {
for (var s = 0; s < document.styleSheets.length; s++) {
for (var i = 0; i < document.styleSheets[s].cssRules.length; i++) {
rule = document.styleSheets[s].cssRules[i];
if (rule && rule.media && rule.media.mediaText.includes("prefers-color-scheme")) {
switch (scheme) {
case "light":
rule.media.appendMedium("original-prefers-color-scheme");
if (rule.media.mediaText.includes("light")) rule.media.deleteMedium("(prefers-color-scheme: light)");
if (rule.media.mediaText.includes("dark")) rule.media.deleteMedium("(prefers-color-scheme: dark)");
break;
case "dark":
rule.media.appendMedium("(prefers-color-scheme: light)");
rule.media.appendMedium("(prefers-color-scheme: dark)");
if (rule.media.mediaText.includes("original")) rule.media.deleteMedium("original-prefers-color-scheme");
break;
default:
rule.media.appendMedium("(prefers-color-scheme: dark)");
if (rule.media.mediaText.includes("light")) rule.media.deleteMedium("(prefers-color-scheme: light)");
if (rule.media.mediaText.includes("original")) rule.media.deleteMedium("original-prefers-color-scheme");
break;
}
}
}
}
if (scheme === "dark") {
document.getElementById("toggle-to-light").style.display = 'block';
document.getElementById("toggle-to-dark").style.display = 'none';
} else {
document.getElementById("toggle-to-dark").style.display = 'block';
document.getElementById("toggle-to-light").style.display = 'none';
}
}
applyPreferredColorScheme(getPreferredColorScheme());
const toggles = document.getElementsByClassName('color-scheme-toggle');
for (const toggle of toggles) {
console.log(toggle)
toggle.addEventListener('click', toggleColorScheme);
};
// The wrapper function is needed to make sure all of the mediawiki JS is loaded before the page's is, and load relevant parts for use here.
mw.loader.using( [
'mediawiki.jqueryMsg'
] ).then( () => {
// This gets the user's current username, and puts it the user menu button.
const username = mw.user.getName();
const buttons = document.getElementsByClassName('site-header-user');
for (const button of buttons) {
if (username) {
button.firstElementChild.textContent = username;
} else {
button.firstElementChild.textContent = mw.message( 'login' ).text();
}
}
// This replaces the text of the print link with the current 'print' system message.
const print = document.getElementById('page-action-print').children[0];
print.textContent = mw.message( 'print' ).text();
const toctitle = document.getElementById('site-nav-toc').children[0];
toctitle.textContent = mw.message( 'toc' ).text();
}
)