Standard Alpine evaluates every attribute expression through new Function(), which a strict Content-Security-Policy cannot allow. Swap to the official CSP-safe build (@alpinejs/csp), whose parser evaluates expressions against registered component scope without eval. script-src now carries only 'self' and 'unsafe-inline' (the latter still required by the pre-paint theme flash guard). Bindings rewritten out of the unsupported expression shapes: - 21 multi-statement sequences across admin, audio_reader, docs, header, index, and reader became single component methods (init/loadWatchStatus hooks, commitScrub, pickSkip, pickSpeed, pickDefaultSpeed, chooseSleepOption, chooseSleepClockMode, toggleFxInvert, openPageThumbs, submitNote, clearSearch, pickReadingTheme) - the header sidebar's inline x-data (openPanel/themeMode IIFE) became a registered sidebarShell component; openPanel itself moved to the header root so every sidebar panel shares one open state - the appearance-panel moved into the component init() - header init() now also seeds openPanel from localStorage (or the admin section on /admin pages) Alpine magics (, , , ) remain available — the CSP evaluator injects them into scope. The Playwright suite covers the converted surfaces end to end.
17 lines
421 B
TypeScript
17 lines
421 B
TypeScript
import Alpine from "@alpinejs/csp";
|
|
|
|
// Extend Window interface to include Alpine. The `htmx` member is declared
|
|
// once in shims.d.ts — redeclaring it here with a different shape is a
|
|
// compile error (TS2717) and split-brained typing.
|
|
declare global {
|
|
interface Window {
|
|
Alpine: typeof Alpine;
|
|
}
|
|
}
|
|
|
|
// Initialize Alpine
|
|
window.Alpine = Alpine;
|
|
|
|
// Re-export Alpine for other modules to use
|
|
export { Alpine };
|