LearnNewsExamplesServices
Frontmatter
id12325
titleFix Portal discussion timeline HTML literal rendering
stateClosed
labels
bugjavascriptai
assigneesneo-gpt
createdAtJun 1, 2026, 10:45 PM
updatedAtJun 7, 2026, 7:18 PM
githubUrlhttps://github.com/neomjs/neo/issues/12325
authorneo-gpt
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 1, 2026, 11:16 PM

Fix Portal discussion timeline HTML literal rendering

neo-gpt
neo-gpt commented on Jun 1, 2026, 10:45 PM

Context

@tobiu surfaced a Portal News Discussions rendering defect via @neo-opus-ada: discussion comment bodies can display the timeline component's own generated HTML markup as literal text, e.g. neo-timeline-item, neo-timeline-avatar, and bounded GitHub avatar URLs appearing inside the rendered discussion content for discussion #11891.

This ticket exists because the symptom is separate from the parallel timeline/canvas spine work and needs its own owner.

The Problem

The discussion markdown file itself does not contain the leaked generated timeline markup. Local V-B-A against resources/content/discussions/chunk-2/discussion-11891.md found ordinary synced discussion markdown around the cited Input from GPT-5 Codex (Codex Desktop) comment, but no timeline-11891-2, neo-timeline-item, or neo-timeline-avatar strings.

The likely failure boundary is the render pipeline:

  • apps/portal/view/news/discussions/Component.mjs builds final timeline HTML in modifyMarkdown() and returns it to the base markdown component.
  • src/component/Markdown.mjs then calls render({code: value}), and render() runs marked.parse(content) over the returned value.
  • A parser probe confirmed that indented raw HTML passed through marked.parse() can be converted into escaped <pre><code>..., which matches the visible literal-markup symptom.

The Architectural Reality

The Portal news timeline views are specialized subclasses of the shared markdown/content stack:

  • Portal.view.news.discussions.Component owns the Discussion grammar and generates .neo-timeline-item[data-record-id] HTML plus sections records for Portal.view.content.TimelineCanvas.
  • Neo.component.Markdown.afterSetValue() treats modifyMarkdown() output as markdown input and routes it through render({code}).
  • Neo.component.Markdown.render() is the shared markdown compiler and is correct for markdown input, but Discussion timeline HTML is already generated HTML by the time it returns from the subclass.

The fix must preserve the shared Markdown component's behavior for normal docs/pages and avoid broad sanitizer/parser changes that would destabilize DevIndex or learn content.

The Fix

Add a narrow render-path fix for Portal discussion timeline HTML so generated timeline markup is inserted as HTML rather than being parsed again as markdown code. Candidate shape:

  • Add a discussion-specific helper/override only if the scope can stay local.
  • Or add a small opt-in hook/config in the shared Markdown/content stack if tests show the same final-HTML contract is shared by tickets/pulls/discussions.
  • Add unit coverage using the real discussion grammar: generated timeline HTML must survive as DOM HTML, while comment markdown and fenced code inside comments still render correctly.

Acceptance Criteria

  • Discussion #11891 no longer renders generated neo-timeline-item / neo-timeline-avatar markup as literal text in comment content.
  • Discussion timeline items still exist as real .neo-timeline-item[data-record-id] nodes and still populate the sections store.
  • Comment markdown still renders via marked as expected, including blockquotes and normal fenced code blocks inside comment bodies.
  • The fix is scoped so generic Markdown pages continue to use the existing Markdown compiler pipeline.
  • Add targeted Playwright unit coverage for the regression path.

Out of Scope

  • Timeline/canvas spine placement bugs.
  • Rewriting the tickets/pulls timeline renderers unless the verification step proves the same failure is active there.
  • Changing GitHub sync output or editing resources/content/discussions/** source markdown.
  • Broad HTML sanitization policy changes.

Related

  • Discussion content repro: resources/content/discussions/chunk-2/discussion-11891.md
  • Sibling active Portal News work: #12204
  • Delegated by @neo-opus-ada via A2A message MESSAGE:966f1625-3bf0-4478-bd7d-855e2ab9ec90

Handoff Retrieval Hint: Portal discussion timeline HTML literal rendering marked.parse modifyMarkdown render pipeline

tobiu closed this issue on Jun 1, 2026, 11:16 PM
tobiu referenced in commit 5bdc12e - "fix(portal): keep discussion timeline html literal-safe (#12325) (#12326) on Jun 1, 2026, 11:16 PM