126 lines
3.5 KiB
JavaScript
126 lines
3.5 KiB
JavaScript
(function () {
|
|
'use strict';
|
|
|
|
var config = window.tt5Ldt || {};
|
|
var btn = document.getElementById('tt5-ldt-toggle');
|
|
if (!btn) return;
|
|
|
|
var storageKey = config.storageKey || 'tt5_ldt_scheme';
|
|
var cookieName = config.cookieName || 'tt5_ldt_scheme';
|
|
var prefersDark = window.matchMedia('(prefers-color-scheme: dark)');
|
|
|
|
function getStoredScheme() {
|
|
try {
|
|
var stored = localStorage.getItem(storageKey);
|
|
if (stored === 'light' || stored === 'dark') {
|
|
return stored;
|
|
}
|
|
} catch (e) {}
|
|
|
|
var match = document.cookie.match(
|
|
new RegExp('(?:^|; )' + cookieName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '=([^;]*)')
|
|
);
|
|
if (match) {
|
|
var cookieVal = decodeURIComponent(match[1]);
|
|
if (cookieVal === 'light' || cookieVal === 'dark') {
|
|
return cookieVal;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function getScheme() {
|
|
var stored = getStoredScheme();
|
|
if (stored) {
|
|
return stored;
|
|
}
|
|
return document.documentElement.classList.contains('tt5-ldt-dark')
|
|
? 'dark'
|
|
: 'light';
|
|
}
|
|
|
|
function setCookie(scheme) {
|
|
var path = config.cookiePath || '/';
|
|
var domain = config.cookieDomain ? '; domain=' + config.cookieDomain : '';
|
|
var maxAge = 60 * 60 * 24 * 365;
|
|
document.cookie =
|
|
cookieName +
|
|
'=' +
|
|
encodeURIComponent(scheme) +
|
|
';path=' +
|
|
path +
|
|
domain +
|
|
';max-age=' +
|
|
maxAge +
|
|
';SameSite=Lax';
|
|
}
|
|
|
|
function applyScheme(scheme, animate) {
|
|
var root = document.documentElement;
|
|
var isDark = scheme === 'dark';
|
|
|
|
if (animate) {
|
|
root.classList.add('tt5-ldt-animate');
|
|
window.setTimeout(function () {
|
|
root.classList.remove('tt5-ldt-animate');
|
|
}, 300);
|
|
}
|
|
|
|
root.classList.toggle('tt5-ldt-dark', isDark);
|
|
root.setAttribute('data-tt5-scheme', scheme);
|
|
|
|
try {
|
|
localStorage.setItem(storageKey, scheme);
|
|
} catch (e) {}
|
|
|
|
setCookie(scheme);
|
|
updateButton(isDark);
|
|
|
|
if (config.isLoggedIn && config.ajaxUrl && config.nonce) {
|
|
var body = new FormData();
|
|
body.append('action', 'tt5_ldt_save_scheme');
|
|
body.append('nonce', config.nonce);
|
|
body.append('scheme', scheme);
|
|
fetch(config.ajaxUrl, { method: 'POST', body: body, credentials: 'same-origin' });
|
|
}
|
|
}
|
|
|
|
function updateButton(isDark) {
|
|
var i18n = config.i18n || {};
|
|
btn.setAttribute('aria-pressed', isDark ? 'true' : 'false');
|
|
btn.setAttribute(
|
|
'aria-label',
|
|
isDark ? i18n.light || 'Switch to light mode' : i18n.dark || 'Switch to dark mode'
|
|
);
|
|
btn.setAttribute(
|
|
'title',
|
|
isDark ? i18n.lightLabel || 'Light mode' : i18n.darkLabel || 'Dark mode'
|
|
);
|
|
|
|
var label = btn.querySelector('.tt5-ldt-toggle__label');
|
|
if (label) {
|
|
label.textContent = isDark ? i18n.lightLabel || 'Light' : i18n.darkLabel || 'Dark';
|
|
}
|
|
}
|
|
|
|
btn.addEventListener('click', function () {
|
|
var next = getScheme() === 'dark' ? 'light' : 'dark';
|
|
applyScheme(next, true);
|
|
});
|
|
|
|
// First visit: no saved preference — follow system setting until user toggles.
|
|
if (!getStoredScheme() && !document.documentElement.getAttribute('data-tt5-scheme')) {
|
|
applyScheme(prefersDark.matches ? 'dark' : 'light', false);
|
|
} else {
|
|
updateButton(document.documentElement.classList.contains('tt5-ldt-dark'));
|
|
}
|
|
|
|
prefersDark.addEventListener('change', function (event) {
|
|
if (getStoredScheme()) {
|
|
return;
|
|
}
|
|
applyScheme(event.matches ? 'dark' : 'light', true);
|
|
});
|
|
})();
|