feat(activity): Markdown rendering for descriptions
Activity descriptions now render through a small marked + DOMPurify pipeline. Client-side only — the server keeps storing raw markdown source, private descriptions stay inside the encrypted payload. frontend/src/lib/markdown.ts exposes a single renderMarkdown(src) helper. Allowlist: p / br / hr / strong / em / del / s / code / pre / ul / ol / li / blockquote / a / h3–h6. URL scheme allowlist: http(s) and mailto. Images are deliberately stripped — external image URLs leak the viewer's IP to the linker's host. Raw HTML pass-through is off. A DOMPurify afterSanitizeAttributes hook forces target="_blank" rel="noopener noreferrer ugc" on every <a>, matching the existing external-link pattern in PublicList. h1/h2 in the source get downshifted to h3 via walkTokens so the description's heading hierarchy doesn't collide with the SPA's own <h1>/<h2>. Render sites: the two description spots in ActivityRow.svelte (one for the decrypted private branch, one for non-private). New .md class in styles.css gives the rendered block tight spacing, discreet code/pre/blockquote treatment, accent-coloured links. UX: a "Du kan bruke Markdown — **fet**, *kursiv*, [lenke](https://…), lister med -" hint under the textarea in ActivityForm. No preview pane to keep scope contained. Tests: 14 cases in tests/markdown.test.ts covering the allowlist (bold/italic/strike/lists/links/mailto), the sanitisation surface (javascript: / data: / script / iframe / on* handlers / images), and the h1/h2 → h3 downshift. happy-dom is registered locally in beforeAll (and the markdown module dynamic-imported) rather than as a project-wide preload — the latter overrides fetch/Request/Response and breaks Bun-fetch-based API tests in other files. Bundle impact: marked + dompurify add ~60KB to the SPA bundle.
This commit is contained in:
parent
95f989639d
commit
1c95dbed00
7 changed files with 276 additions and 2 deletions
|
|
@ -14,14 +14,18 @@
|
|||
"reset-password": "bun run server/reset-password.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"dompurify": "^3.4.5",
|
||||
"hono": "^4.6.0",
|
||||
"libsodium-wrappers-sumo": "^0.7.15",
|
||||
"marked": "^18.0.4",
|
||||
"svelte-dnd-action": "^0.9.69"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@happy-dom/global-registrator": "^20.9.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.0",
|
||||
"@tsconfig/svelte": "^5.0.4",
|
||||
"@types/bun": "^1.1.0",
|
||||
"@types/dompurify": "^3.2.0",
|
||||
"@types/libsodium-wrappers-sumo": "^0.7.8",
|
||||
"svelte": "^5.0.0",
|
||||
"svelte-check": "^4.0.0",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue