User:Monster Domosed/common.js: Difference between revisions

No edit summary
No edit summary
Line 3: Line 3:


const CONFIG = {
const CONFIG = {
optionKey: 'gadget-theme',
cookieKey: 'mode',
cookieKey: 'theme',
className: 'theme-light',
toggleId: 'pt-theme-toggle'
toggleId: 'pt-theme-toggle'
};
};
Line 16: Line 14:
};
};


function Storage() {
function getMode() {
function loggedIn() {
return document.documentElement.getAttribute('data-mode') === 'light'
return mw.user.isNamed();
? 'light'
}
: 'dark';
}


// true = light theme, false = dark (default)
function saveMode(mode) {
function getState() {
mw.cookie.set(CONFIG.cookieKey, mode, {
return mw.user.options.get(CONFIG.optionKey) == 1;
expires: 365 * 86400,
}
prefix: ''
});
}


function save(value) {
function iconFor(mode) {
if (loggedIn()) {
return mode === 'light' ? ICONS.moon : ICONS.sun;
return new mw.Api().saveOption(CONFIG.optionKey, value ? 1 : 0);
}
}


mw.cookie.set(CONFIG.cookieKey, value ? '1' : '0', {
function labelFor(mode) {
expires: 365 * 86400,
return mode === 'light'
prefix: ''
? 'Switch to dark theme'
});
: 'Switch to light theme';
 
}
return $.Deferred().resolve().promise();
}


function readCookieFallback(defaultValue) {
function apply(mode) {
if (loggedIn()) return defaultValue;
document.documentElement.setAttribute('data-mode', mode);


return mw.cookie.get(CONFIG.cookieKey, '', defaultValue ? '1' : '0') === '1';
const a = document.querySelector('#' + CONFIG.toggleId + ' a');
if (a) {
a.innerHTML = iconFor(mode);
a.setAttribute('aria-label', labelFor(mode));
a.title = labelFor(mode);
}
}
}


return {
function setMode(mode) {
loggedIn,
apply(mode);
getState,
saveMode(mode);
save,
readCookieFallback
};
}
}


function View() {
function toggleMode() {
function iconFor(light) {
setMode(getMode() === 'light' ? 'dark' : 'light');
return light ? ICONS.moon : ICONS.sun;
}
}


function labelFor(light) {
function createToggle() {
return light ? 'Switch to dark theme' : 'Switch to light theme';
const ul = document.querySelector('#p-personal ul');
}


function apply(light) {
if (!ul) {
document.documentElement.classList.toggle(CONFIG.className, light);
setTimeout(createToggle, 300);
 
return;
const a = document.querySelector('#' + CONFIG.toggleId + ' a');
if (a) {
a.innerHTML = iconFor(light);
a.setAttribute('aria-label', labelFor(light));
a.title = labelFor(light);
}
}
}


function createToggle(onToggle, getState) {
if (document.getElementById(CONFIG.toggleId)) {
function findTarget() {
return;
return document.querySelector('#p-personal ul');
}
 
const ul = findTarget();
 
if (!ul) {
setTimeout(function () {
createToggle(onToggle, getState);
}, 300);
return;
}
 
if (document.getElementById(CONFIG.toggleId)) return;
 
const light = getState();
 
const li = document.createElement('li');
li.id = CONFIG.toggleId;
 
const a = document.createElement('a');
a.href = '#';
a.innerHTML = iconFor(light);
a.setAttribute('aria-label', labelFor(light));
a.title = labelFor(light);
 
a.addEventListener('click', function (e) {
e.preventDefault();
onToggle();
});
 
li.appendChild(a);
ul.insertBefore(li, ul.firstChild);
}
}


return {
const mode = getMode();
apply,
createToggle
};
}
 
function Controller() {
const store = Storage();
const view = View();


let state = store.getState();
const li = document.createElement('li');
li.id = CONFIG.toggleId;


function set(next) {
const a = document.createElement('a');
state = next;
a.href = '#';
a.innerHTML = iconFor(mode);
a.setAttribute('aria-label', labelFor(mode));
a.title = labelFor(mode);


view.apply(state);
a.addEventListener('click', function (e) {
 
e.preventDefault();
store.save(state).fail(function () {
toggleMode();
mw.notify('Could not save theme preference.', {
});
title: 'Theme toggle',
type: 'warn',
tag: 'themeToggle'
});
});
}
 
function toggle() {
set(!state);
}
 
function init() {
if (!store.loggedIn()) {
state = store.readCookieFallback(state);
}
 
view.apply(state);
view.createToggle(toggle, function () {
return state;
});
}


return {
li.appendChild(a);
init
ul.insertBefore(li, ul.firstChild);
};
}
}


$(function () {
$(function () {
new Controller().init();
apply(getMode());
createToggle();
});
});
})();
})();