Files
codey.lol/public/scripts/theme-init.js

95 lines
2.8 KiB
JavaScript
Raw Normal View History

2025-12-17 13:33:31 -05:00
/**
* Theme initialization script - must run before page renders
* This prevents flash of wrong theme colors
*
* Replaces astro-themes functionality with external file to reduce HTML size
*/
(function() {
var d = document.documentElement;
var stored = localStorage.getItem('theme');
var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
var isDark = stored === 'dark' || (!stored && prefersDark);
var theme = isDark ? 'dark' : 'light';
// Set theme immediately
d.setAttribute('data-theme', theme);
d.style.colorScheme = theme;
if (isDark) {
d.classList.add('dark');
} else {
d.classList.remove('dark');
}
// Mark ready when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
d.classList.add('ready');
});
} else {
d.classList.add('ready');
}
// Handle theme changes from other tabs
window.addEventListener('storage', function(e) {
if (e.key === 'theme') {
var newTheme = e.newValue || (prefersDark ? 'dark' : 'light');
d.setAttribute('data-theme', newTheme);
d.style.colorScheme = newTheme;
if (newTheme === 'dark') {
d.classList.add('dark');
} else {
d.classList.remove('dark');
}
}
});
// Handle system preference changes
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function() {
if (!localStorage.getItem('theme')) {
var newTheme = this.matches ? 'dark' : 'light';
d.setAttribute('data-theme', newTheme);
d.style.colorScheme = newTheme;
if (newTheme === 'dark') {
d.classList.add('dark');
} else {
d.classList.remove('dark');
}
}
});
// Handle set-theme custom event (for toggle button)
document.addEventListener('set-theme', function(e) {
var newTheme = e.detail;
if (newTheme) {
localStorage.setItem('theme', newTheme);
} else {
localStorage.removeItem('theme');
newTheme = prefersDark ? 'dark' : 'light';
}
d.setAttribute('data-theme', newTheme);
d.style.colorScheme = newTheme;
if (newTheme === 'dark') {
d.classList.add('dark');
} else {
d.classList.remove('dark');
}
});
// Re-apply theme after client-side navigation
// Support both original and obfuscated event names
var swapHandler = function() {
var s = localStorage.getItem('theme');
var pDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
var t = s || (pDark ? 'dark' : 'light');
d.setAttribute('data-theme', t);
d.style.colorScheme = t;
if (t === 'dark') {
d.classList.add('dark');
} else {
d.classList.remove('dark');
}
d.classList.add('ready');
};
document.addEventListener('astro:after-swap', swapHandler);
})();