Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 29x 29x 29x 29x 29x 12x 28x 28x 28x 27x 27x 13x 13x 13x 13x 13x 2x 27x 2x 28x 12x 3x | // SPDX-License-Identifier: MIT
/**
* Theme application logic
*/
import { DOM_IDS, DOM_SELECTORS, THEME_FAMILIES } from './constants.js';
import { getBaseUrl, applyThemeClass, loadThemeCSS, resolveAssetPath, getCurrentThemeFromClasses } from './theme-loader.js';
import { setItemActiveState } from './dropdown/helpers.js';
import { ThemeErrors, logThemeError } from './errors.js';
import { resolveTheme } from './theme-resolver.js';
/**
* Applies a theme to the document
*/
export async function applyTheme(doc: Document, themeId: string): Promise<void> {
const theme = resolveTheme(themeId);
Iif (!theme) {
logThemeError(ThemeErrors.NO_THEMES_AVAILABLE());
return;
}
const baseUrl = getBaseUrl(doc);
// Add loading state to trigger button
const trigger = doc.getElementById(DOM_IDS.THEME_FLAVOR_TRIGGER) as HTMLButtonElement | null;
if (trigger) {
trigger.classList.add('is-loading');
}
try {
// Apply theme class immediately (before CSS loading)
applyThemeClass(doc, theme.id);
// Load theme CSS
await loadThemeCSS(doc, theme, baseUrl);
// Update trigger button icon
const triggerIcon = doc.getElementById(
DOM_IDS.THEME_FLAVOR_TRIGGER_ICON
) as HTMLImageElement | null;
if (triggerIcon && theme.icon) {
try {
triggerIcon.src = resolveAssetPath(theme.icon, baseUrl);
const familyName = THEME_FAMILIES[theme.family].name;
triggerIcon.alt = `${familyName} ${theme.name}`;
triggerIcon.title = `${familyName} ${theme.name}`;
} catch {
logThemeError(ThemeErrors.INVALID_ICON_PATH(theme.id));
}
}
// Update active state in dropdown
doc.querySelectorAll(DOM_SELECTORS.DROPDOWN_ITEMS).forEach((item) => {
setItemActiveState(item, item.getAttribute('data-theme-id') === theme.id);
});
} finally {
if (trigger) {
trigger.classList.remove('is-loading');
}
}
}
/**
* Gets the current theme from classes or returns default
*/
export function getCurrentTheme(doc: Document, defaultTheme: string): string {
return getCurrentThemeFromClasses(doc.documentElement) || defaultTheme;
}
|