86 lines
3.8 KiB
JavaScript
Executable File
86 lines
3.8 KiB
JavaScript
Executable File
document.documentElement.classList.add('js');
|
|
|
|
function readThemePreference(key, fallback) {
|
|
try {
|
|
return localStorage.getItem(key) || fallback;
|
|
} catch (error) {
|
|
return fallback;
|
|
}
|
|
}
|
|
|
|
const moduleName = document.documentElement.dataset.module || '';
|
|
const mainThemeMode = readThemePreference('nexus.theme', 'day');
|
|
const mainThemeAccent = readThemePreference('nexus.accent', 'logo');
|
|
const moduleThemeMode = moduleName ? readThemePreference(`nexus.module.${moduleName}.theme`, 'inherit') : mainThemeMode;
|
|
const moduleThemeAccent = moduleName ? readThemePreference(`nexus.module.${moduleName}.accent`, 'inherit') : mainThemeAccent;
|
|
|
|
function normalizeThemeValue(value, allowed, fallback) {
|
|
return allowed.includes(value) ? value : fallback;
|
|
}
|
|
|
|
function storedTheme() {
|
|
const rawMode = moduleName ? readThemePreference(`nexus.module.${moduleName}.theme`, 'inherit') : readThemePreference('nexus.theme', 'day');
|
|
const rawAccent = moduleName ? readThemePreference(`nexus.module.${moduleName}.accent`, 'inherit') : readThemePreference('nexus.accent', 'logo');
|
|
const mode = moduleName ? normalizeThemeValue(rawMode, ['inherit', 'day', 'night'], 'inherit') : normalizeThemeValue(rawMode, ['day', 'night'], 'day');
|
|
const accent = moduleName ? normalizeThemeValue(rawAccent, ['inherit', 'logo', 'pink', 'cyan', 'orange', 'green'], 'inherit') : normalizeThemeValue(rawAccent, ['logo', 'pink', 'cyan', 'orange', 'green'], 'logo');
|
|
return { mode, accent };
|
|
}
|
|
|
|
function applyTheme(mode, accent, persist = true) {
|
|
const allowedModes = moduleName ? ['inherit', 'day', 'night'] : ['day', 'night'];
|
|
const allowedAccents = moduleName ? ['inherit', 'logo', 'pink', 'cyan', 'orange', 'green'] : ['logo', 'pink', 'cyan', 'orange', 'green'];
|
|
const normalizedMode = normalizeThemeValue(mode, allowedModes, moduleName ? 'inherit' : 'day');
|
|
const normalizedAccent = normalizeThemeValue(accent, allowedAccents, moduleName ? 'inherit' : 'logo');
|
|
const effectiveMode = normalizedMode === 'inherit' ? mainThemeMode : normalizedMode;
|
|
const effectiveAccent = normalizedAccent === 'inherit' ? mainThemeAccent : normalizedAccent;
|
|
document.documentElement.dataset.theme = effectiveMode;
|
|
document.documentElement.dataset.accent = effectiveAccent;
|
|
try {
|
|
if (persist) {
|
|
if (moduleName) {
|
|
if (normalizedMode === 'inherit') {
|
|
localStorage.removeItem(`nexus.module.${moduleName}.theme`);
|
|
} else {
|
|
localStorage.setItem(`nexus.module.${moduleName}.theme`, normalizedMode);
|
|
}
|
|
if (normalizedAccent === 'inherit') {
|
|
localStorage.removeItem(`nexus.module.${moduleName}.accent`);
|
|
} else {
|
|
localStorage.setItem(`nexus.module.${moduleName}.accent`, normalizedAccent);
|
|
}
|
|
} else {
|
|
localStorage.setItem('nexus.theme', normalizedMode);
|
|
localStorage.setItem('nexus.accent', normalizedAccent);
|
|
}
|
|
}
|
|
} catch (error) {
|
|
// Ignore blocked storage; the current page still receives the theme.
|
|
}
|
|
return { mode: normalizedMode, accent: normalizedAccent };
|
|
}
|
|
|
|
const initialTheme = applyTheme(moduleThemeMode, moduleThemeAccent, false);
|
|
|
|
const themeModeSelect = document.querySelector('[data-theme-mode]');
|
|
const themeAccentSelect = document.querySelector('[data-theme-accent]');
|
|
|
|
if (themeModeSelect) {
|
|
themeModeSelect.value = initialTheme.mode;
|
|
themeModeSelect.addEventListener('change', () => {
|
|
const current = storedTheme();
|
|
applyTheme(themeModeSelect.value, current.accent);
|
|
});
|
|
}
|
|
|
|
if (themeAccentSelect) {
|
|
themeAccentSelect.value = initialTheme.accent;
|
|
themeAccentSelect.addEventListener('change', () => {
|
|
const current = storedTheme();
|
|
applyTheme(current.mode, themeAccentSelect.value);
|
|
});
|
|
}
|
|
|
|
for (const element of document.querySelectorAll('[data-reveal]')) {
|
|
element.classList.add('reveal');
|
|
}
|