What this changes, and why
Hardening pass on the custom markdown editor used by the event and story description forms (MarkdownEditor2, a contenteditable WYSIWYG with a markdown bridge). Fixes from a security audit plus extended edge-case testing:
- HTML injection and attribute breakout in the inline parser
- Multi-line blockquotes kept only the first
> line
- Fenced code blocks were mangled on save/reload
- Mixed bold+italic (
**a*b*c**) lost the literal stars
- Trailing-space growth on every save (soft breaks)
- Duplicate
.mde-editor p CSS rule
- Autolinks (
<https://...>) eaten as HTML tags
- Link titles (
[x](url "title")) broke the URL attribute
- Nested lists and continuation lines were dropped
- Missing constructs vs the renderer: h1/h5/h6, inline code,
<hr>,
images, 1) lists, backslash escapes, task lists
Adds fenced code blocks with sugar-high syntax highlighting (GitHub-dark palette). Interactive behavior hardened: Enter splits blocks into new paragraphs (Shift+Enter = soft break), the code button is selection-aware (only the selection becomes a block; a collapsed caret inserts a fresh one), empty paste no longer destroys the selection, Enter in an empty list item keeps the list, linking over a link is refused.
Round-trips are byte-stable, escaping is minimal so nostr clients and marked never show stray backslashes, and the editor was fuzzed (unicode, deep nesting, huge inputs) without crashes, loss or XSS.
What this affects
src/components/MarkdownEditor2.astro - the editor (used by both
create-event and create-story forms)
public/scripts/render-markdown.js - public renderer, imports the
sugar-high bundle for fenced code highlighting
public/scripts/sugar-high.bundle.mjs - new vendored bundle
src/styles/_base.scss - .mde-editor styles and --sh-* tokens
package.json / pnpm-lock.yaml - sugar-high@^2.0.0 dependency
docs/markdown-editor.md - new editor documentation
Review carefully: inline HTML escaping and URL sanitization (same allowlist as the public renderer), block-start escaping, and the Range-based DOM surgery in the Enter / code-button paths.
How to try it
On the preview link, open "Create event" (or a story):
- Type a paragraph, press Enter - a new paragraph starts; Shift+Enter
makes a soft line break. Save and reload: content is byte-identical.
- Select text and press
</> - only the selection becomes a code
block; surrounding text stays put.
- On an empty line,
</> starts a fresh code block. Enter adds lines.
- Fenced code with a language (e.g. ```js) renders highlighted on the
public event page.
- Paste an image (no text) - the selection is preserved.
Before you ask for review
- [x] Branch named
feat/..., fix/..., chore/..., docs/... or hotfix/...
- [x] Commit messages follow Conventional Commits
- [x]
pnpm format has been run and the checks are green
- [ ] Tried it on the preview link
- [x] Rebased on the latest
main