Repository navigation
Conversation
There was a problem hiding this comment.
Thanks for picking this up. As it stands, in-document links still don't reach their headings in the app, so I can't confirm the fix.
How I checked: the new parser tests pass and packages/ui typechecks. I also ran the parser output through DOMPurify with the session timeline's settings (packages/session-ui/src/components/markdown-cache.tsx). Its SANITIZE_NAMED_PROPS: true setting renames every heading id to user-content-<slug>, while the link stays #<slug>. The link no longer opens a new tab, but clicking it finds no heading. Either the # hrefs need the same prefix, or the timeline needs a click handler that resolves #slug to user-content-slug and scrolls its own container. That handler is the third step proposed in #57971. A test that covers parse plus sanitize would catch this.
Other things to address:
- Rebase needed: on the latest
dev(#57937),createMarkdownParserno longer takes a highlighter and the link renderer lives inpackages/ui/src/context/marked-base.tsx. That file is also used byparseSmallMarkdown, so the link and heading changes need to move there. - Repeated ids: see the inline comment on numbering duplicates.
Public API: unchanged. Only the HTML rendered for markdown changes.
| heading({ tokens, depth }) { | ||
| const text = this.parser.parseInline(tokens, this.parser.textRenderer) | ||
| const base = slugifyHeading(text) | ||
| const counts = headingCounts.get(this.parser) ?? new Map<string, number>() |
There was a problem hiding this comment.
The -1, -2 numbering only applies within one parse() call. While a reply streams, markdown-stream.ts sends each finished top-level block to the worker separately. So two ## Install headings in the same reply each get id="install". Every message in a timeline also reuses the same ids, so #install always jumps to the first matching heading on the page, even if it's in a different message. In-document links probably need to be resolved within the message's own container, not left to the browser's hash navigation.
In the app, this HTML goes through DOMPurify with SANITIZE_NAMED_PROPS: true (session-ui/src/components/markdown-cache.tsx). That renames id="install" to id="user-content-install" but leaves href="#install" as it is. I checked this with the PR's output: after sanitizing, the link points at an id that no longer exists, so clicking it does nothing useful. The # link needs to match the prefixed id, or a click handler needs to map one to the other.
Issue for this PR
Closes #57971
Type of change
What does this PR do?
Markdown in-document links such as
[Install](#install)no longer open a new tab. Headings now receive stable, document-scoped ids with-1,-2, etc. suffixes for duplicates, so table-of-contents links have real targets.The heading counter is keyed by Marked parser instance, so concurrent or later parses do not share ids.
How did you verify your code works?
bun test src/context/marked-parser.test.tsfrompackages/uibun typecheckfrompackages/uiScreenshots / recordings
Not applicable: this changes shared Markdown HTML rendering.
Checklist
Added by the opencode bot (AI-generated).
Related: #46550, #44902