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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | 68x 68x 5x 5x 8x 8x 8x 2x 2x 4x 4x 1x 41x 8x 33x 22x 22x 22x 4x 4x 36x 36x 33x 3x 5x 1x 1x 4x | // SPDX-License-Identifier: MIT
/**
* Storage utilities for theme persistence
*/
import { STORAGE_KEY, LEGACY_STORAGE_KEYS, DEFAULT_THEME } from './constants.js';
import { ThemeErrors, logThemeError } from './errors.js';
// Re-export DEFAULT_THEME for convenience
export { DEFAULT_THEME } from './constants.js';
/**
* Safely get an item from localStorage.
* Returns null if storage is unavailable (e.g., private browsing mode).
*/
function safeGetItem(windowObj: Window, key: string): string | null {
try {
return windowObj.localStorage.getItem(key);
} catch (error) {
logThemeError(ThemeErrors.STORAGE_UNAVAILABLE('getItem', error));
return null;
}
}
/**
* Safely set an item in localStorage.
* Returns false if storage is unavailable.
*/
function safeSetItem(windowObj: Window, key: string, value: string): boolean {
try {
windowObj.localStorage.setItem(key, value);
return true;
} catch (error) {
logThemeError(ThemeErrors.STORAGE_UNAVAILABLE('setItem', error));
return false;
}
}
/**
* Safely remove an item from localStorage.
* Silently fails if storage is unavailable.
*/
function safeRemoveItem(windowObj: Window, key: string): void {
try {
windowObj.localStorage.removeItem(key);
} catch (error) {
logThemeError(ThemeErrors.STORAGE_UNAVAILABLE('removeItem', error));
}
}
/**
* Validates a theme ID against a set of valid IDs.
* Returns the theme ID if valid, otherwise returns the default theme.
*/
export function validateThemeId(themeId: string | null, validIds: Set<string>): string {
if (themeId && validIds.has(themeId)) {
return themeId;
}
return DEFAULT_THEME;
}
/**
* Migrates legacy storage keys to the current format.
* Safely handles unavailable localStorage (e.g., private browsing).
*/
export function migrateLegacyStorage(windowObj: Window): void {
for (const legacyKey of LEGACY_STORAGE_KEYS) {
const legacy = safeGetItem(windowObj, legacyKey);
if (legacy && !safeGetItem(windowObj, STORAGE_KEY)) {
safeSetItem(windowObj, STORAGE_KEY, legacy);
safeRemoveItem(windowObj, legacyKey);
}
}
}
/**
* Gets the saved theme from localStorage, or returns default.
* Optionally validates against a set of valid theme IDs.
* Safely handles unavailable localStorage (e.g., private browsing).
*/
export function getSavedTheme(windowObj: Window, validIds?: Set<string>): string {
const stored = safeGetItem(windowObj, STORAGE_KEY);
if (validIds) {
return validateThemeId(stored, validIds);
}
return stored || DEFAULT_THEME;
}
/**
* Saves a theme to localStorage.
* Optionally validates the theme ID against a set of valid IDs before saving.
* Safely handles unavailable localStorage (e.g., private browsing).
*
* @param windowObj - Window object with localStorage
* @param themeId - Theme ID to save
* @param validIds - Optional set of valid theme IDs for validation
* @returns true if saved successfully, false otherwise
*/
export function saveTheme(windowObj: Window, themeId: string, validIds?: Set<string>): boolean {
if (validIds && !validIds.has(themeId)) {
logThemeError(ThemeErrors.INVALID_THEME_ID(themeId));
return false;
}
return safeSetItem(windowObj, STORAGE_KEY, themeId);
}
|