From e0d723df147c2ffbd30c18fef49bed9361dfa65a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Lohrer?= Date: Tue, 28 Apr 2026 08:00:56 +0200 Subject: [PATCH] feat(render): renderMarkdown auf isomorphic-dompurify umgestellt Funktioniert jetzt sowohl in Browser/jsdom als auch in Node (SvelteKit-Build). Schritt 1 der prerender-snapshot-migration. Verhalten in der SPA unveraendert. Co-Authored-By: Claude Opus 4.7 (1M context) --- app/package.json | 1 + app/src/lib/render/markdown.ts | 20 +------------------- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/app/package.json b/app/package.json index ddbc357..7a8b932 100644 --- a/app/package.json +++ b/app/package.json @@ -35,6 +35,7 @@ "applesauce-signers": "^5.2.0", "dompurify": "^3.4.0", "highlight.js": "^11.11.1", + "isomorphic-dompurify": "^3.10.0", "marked": "^18.0.0", "nostr-tools": "^2.23.3", "rxjs": "^7.8.2", diff --git a/app/src/lib/render/markdown.ts b/app/src/lib/render/markdown.ts index 0f6f2ff..383fdfe 100644 --- a/app/src/lib/render/markdown.ts +++ b/app/src/lib/render/markdown.ts @@ -1,5 +1,5 @@ import { Marked } from 'marked'; -import DOMPurify from 'dompurify'; +import DOMPurify from 'isomorphic-dompurify'; import hljs from 'highlight.js/lib/core'; import javascript from 'highlight.js/lib/languages/javascript'; import bash from 'highlight.js/lib/languages/bash'; @@ -14,11 +14,6 @@ hljs.registerLanguage('bash', bash); hljs.registerLanguage('sh', bash); hljs.registerLanguage('json', json); -/** - * Lokaler Marked-Instance, damit die globale `marked`-Singleton nicht - * mutiert wird — andere Module können `marked` unbeeinflusst weiterverwenden. - * (Spec §3: lokale Ersetzbarkeit der Engine.) - */ const markedInstance = new Marked({ breaks: true, gfm: true, @@ -34,20 +29,7 @@ const markedInstance = new Marked({ } }); -/** - * Rendert einen Markdown-String zu sanitized HTML. - * Einziger Export des Moduls — so bleibt Austausch der Engine lokal. - * - * Nur im Browser/jsdom aufrufen: DOMPurify braucht ein DOM. Die SPA - * hat SSR global ausgeschaltet (`+layout.ts: ssr = false`), Vitest läuft - * in jsdom — beide Szenarien sind abgedeckt. Ein Aufruf in reiner - * Node-Umgebung würde hier laut fehlschlagen statt stumm unsicher - * durchzulaufen. - */ export function renderMarkdown(md: string): string { - if (typeof window === 'undefined') { - throw new Error('renderMarkdown: DOM-Kontext erforderlich (Browser oder jsdom).'); - } const raw = markedInstance.parse(md, { async: false }) as string; return DOMPurify.sanitize(raw); }