From 36cb71b67644c48266f7cdc9ed3bcb3bafe053d0 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Tue, 7 Jul 2026 09:21:26 -0400 Subject: [PATCH] submissions(#23): format submission bodies (safe markdown-lite) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Submission cards showed the raw form markdown ("### Bug Report", "- npub: …"). Added a tiny, SAFE renderer: `#…###` headings → bold lines, leading `- `/`* ` bullet markers stripped, `**bold**` honored inline — built entirely with textContent/createTextNode + , so no HTML is ever parsed from the content (submissions are untrusted public events; rendering raw markdown/HTML would be an XSS hole). Lint (innerHTML check) + build clean; tests 26/26. Co-Authored-By: Claude Opus 4.8 --- css/tailwind.source.css | 14 +++++++- js/ui/profileModal/submissionsSection.js | 45 ++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/css/tailwind.source.css b/css/tailwind.source.css index 2143db6e..ce715fe1 100644 --- a/css/tailwind.source.css +++ b/css/tailwind.source.css @@ -3210,10 +3210,22 @@ } .submission-card__body { + display: flex; + flex-direction: column; + gap: var(--space-3xs); + } + + .submission-card__heading { + margin: 0; + font-size: var(--font-size-sm); + font-weight: 600; + color: var(--color-text-strong); + } + + .submission-card__line { margin: 0; font-size: var(--font-size-sm); color: var(--color-text); - white-space: pre-wrap; word-break: break-word; } diff --git a/js/ui/profileModal/submissionsSection.js b/js/ui/profileModal/submissionsSection.js index dbd6b897..0ee59e3b 100644 --- a/js/ui/profileModal/submissionsSection.js +++ b/js/ui/profileModal/submissionsSection.js @@ -69,6 +69,47 @@ export function renderSubmissions(controller) { } } +// Render `**bold**` segments as ; everything else as plain text — never +// parse HTML from the content (submissions are untrusted public events). +function appendInline(el, text) { + const parts = String(text).split("**"); + parts.forEach((part, i) => { + if (!part) { + return; + } + if (i % 2 === 1) { + const strong = document.createElement("strong"); + strong.textContent = part; + el.appendChild(strong); + } else { + el.appendChild(document.createTextNode(part)); + } + }); +} + +// Tiny, SAFE markdown-lite renderer for the form-generated body: `#…###` +// headings become bold lines, leading `- `/`* ` bullet markers are stripped, +// `**bold**` is honored inline. No HTML is ever parsed from the content. +function renderSubmissionBody(container, content) { + for (const raw of String(content).split("\n")) { + const line = raw.replace(/\s+$/, ""); + if (!line.trim()) { + continue; + } + if (/^#{1,6}\s/.test(line)) { + const heading = document.createElement("p"); + heading.className = "submission-card__heading"; + appendInline(heading, line.replace(/^#{1,6}\s+/, "")); + container.appendChild(heading); + } else { + const p = document.createElement("p"); + p.className = "submission-card__line"; + appendInline(p, line.replace(/^[-*]\s+/, "")); + container.appendChild(p); + } + } +} + function renderSubmissionRow(submission) { const li = document.createElement("li"); li.className = "submission-card"; @@ -90,9 +131,9 @@ function renderSubmissionRow(submission) { li.appendChild(head); if (submission.content) { - const body = document.createElement("p"); + const body = document.createElement("div"); body.className = "submission-card__body"; - body.textContent = submission.content; + renderSubmissionBody(body, submission.content); li.appendChild(body); }