docs: document the foliate-js reader

Adds a reader section covering the vendored tree, the $foliate alias and the
traps around it, and refreshes the stale stack line, oklch claim and rough
edges. Records why CSP is not enabled in TODO.md.
This commit is contained in:
2026-08-12 01:37:19 -04:00
parent 961a63480e
commit 51c31e6bf6
3 changed files with 106 additions and 23 deletions
+23
View File
@@ -51,6 +51,29 @@ Worth adding at the same time:
## Frontend
### No CSP, so scripted EPUBs run against the app origin
EPUB files may contain JavaScript. foliate-js renders each section in an iframe from a
**same-origin** `blob:` URL and cannot sandbox it — `allow-scripts` is required, and
blob URLs inherit the embedder's origin — so script inside a book can reach `/api/*`
with the session cookie attached. foliate's own README says not to use it without a
Content Security Policy blocking scripts.
The obvious policy is `kit.csp` in `svelte.config.js` with `script-src: ['self']`, and
deliberately no `default-src` (it would also cover `style-src`/`img-src`/`font-src` and
kill both the book's own blob: assets and the inline `<style id="chitai-theme">` that
`hooks.server.ts` injects via `transformPageChunk`).
**What blocks it:** `mode-watcher` renders its own inline `setInitialMode` script, which
sets the dark class before first paint. SvelteKit only nonces the bootstrap script it
injects itself, so that one is blocked and every page load flashes the light theme.
Fixing it means pinning a SHA-256 of a third-party inline script whose contents change
with the package version and the props passed — it would break silently on upgrade, and
the symptom would be a theme flash rather than an error.
Worth revisiting if `mode-watcher` gains a nonce prop, or if the theme class moves to a
cookie so the server can set it without an inline script.
### Remove the epub.js locations-cache purge
`frontend/src/lib/reader/legacy-cache.ts``purgeLegacyLocationCache`