You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: 🐛 defer HTML entity decoding to leaf renderers
User-typed text in mrkdwn payloads contains Slack-escaped `<`, `>`, `&`
chars as `<`, `>`, `&`. Decoding these in `text_object.tsx`
BEFORE markdown_parser was incorrect: a literal `<@u123>` typed by a
user (delivered as `<@u123>`) decoded to `<@u123>` and got
tokenized as a real user mention, firing `hooks.user` and producing a
chip when Slack itself would render literal `<@u123>` text.
Slack's own renderer tokenizes the raw payload first and decodes
entities only at render time — confirmed empirically in section/mrkdwn
side-by-side. This change matches that:
- Remove entity decoding from text_object.tsx.
- Decode in the leaf renderers that emit user-visible text: Text, HTML,
InlineCode (and its plain-code path), the fenced Code element, and
Link (for the href; label children go through Text).
- New tests cover escaped `<@u123>`, `<#C123>`, `<!here>` staying
literal, `&` `<` `>` decoding in plain text, and entity
decoding inside inline and fenced code.
The `>` → "> " trailing-space hack (which existed to make blockquote
detection survive entity escaping) is removed. Slack itself does not
render blockquotes in section/mrkdwn, so user-typed `> quote` (delivered
as `> quote`) no longer renders as a blockquote — which better
matches Slack's behavior.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: .changeset/fix-mrkdwn-directives.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,4 +2,4 @@
2
2
"slack-blocks-to-jsx": patch
3
3
---
4
4
5
-
Resolve Slack directive atoms (`<@U…>`, `<#C…>`, `<!subteam^…>`, `<!channel|here|everyone>`, `<!date^…>`) in `section`/`mrkdwn` text and other mrkdwn-typed text. Directives now fire the same hooks as the `rich_text` path. `verbatim: true` matches Slack's empirical behavior — it suppresses bare-form `@here` / `@channel` / `@everyone` interpolation but is otherwise a no-op (markdown sugar, code spans, angle-bracket URLs, and structured `<!…>` directives all render the same in both modes). `&` is now decoded alongside `>`/ `<` so escaped ampersands don't leak into hrefs or visible text.
5
+
Resolve Slack directive atoms (`<@U…>`, `<#C…>`, `<!subteam^…>`, `<!channel|here|everyone>`, `<!date^…>`) in `section`/`mrkdwn` text and other mrkdwn-typed text. Directives now fire the same hooks as the `rich_text` path. `verbatim: true` matches Slack's empirical behavior — it suppresses bare-form `@here` / `@channel` / `@everyone` interpolation but is otherwise a no-op (markdown sugar, code spans, angle-bracket URLs, and structured `<!…>` directives all render the same in both modes). HTML entity decoding (`<`, `>`, `&`) is deferred from input pre-processing to leaf renderers, so escaped sequences like `<@U123>`(user typed `<@U123>` literally) stay literal instead of being incorrectly resolved as a user mention — matching Slack's renderer.
0 commit comments