[codex] Add RTL direction detection helpers#3674
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
b29c4f8 to
2c2d462
Compare
| </h6> | ||
| ); | ||
| }, | ||
| ul({ node, children, ...props }) { |
There was a problem hiding this comment.
🟡 Medium components/ChatMarkdown.tsx:1427
The ul, ol, and li component overrides compute dir by calling blockDirForMarkdownNode(text, node, children), but a list node's position spans the entire subtree including nested lists. A top-level English list that contains a long nested Hebrew/Arabic sublist will resolve the outer <ul>/<ol> and parent <li> as dir="rtl", placing the top-level bullets/numbers on the wrong side even though the parent items are LTR. Consider computing the direction from only the node's own direct text rather than the full subtree range.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/ChatMarkdown.tsx around line 1427:
The `ul`, `ol`, and `li` component overrides compute `dir` by calling `blockDirForMarkdownNode(text, node, children)`, but a list node's `position` spans the entire subtree including nested lists. A top-level English list that contains a long nested Hebrew/Arabic sublist will resolve the outer `<ul>`/`<ol>` and parent `<li>` as `dir="rtl"`, placing the top-level bullets/numbers on the wrong side even though the parent items are LTR. Consider computing the direction from only the node's own direct text rather than the full subtree range.
bfba339 to
e3f7120
Compare
| }, | ||
| [createAssetUrl, openPreview, preparedConnection, threadRef], | ||
| ); | ||
| const markdownComponents = useMemo<Components>( |
There was a problem hiding this comment.
🟡 Medium components/ChatMarkdown.tsx:1424
The dir computation calls blockDirForMarkdownNode(text, node, children), which derives direction from offsets into the raw markdown text. Because rehypeRaw is enabled, raw HTML inside markdown like <blockquote>שלום</blockquote> contributes ASCII tag names (blockquote, kbd, etc.) to the scanned source slice, so dirForMarkdown counts that ASCII content as visible LTR text and the node is assigned dir="ltr" even when the visible content is purely RTL. As a result, raw-HTML RTL blocks render with the wrong text direction. Consider computing direction from the rendered text content (children) rather than the raw markdown source offsets.
Also found in 2 other location(s)
apps/web/src/components/ComposerPromptEditor.tsx:865
composerDirectionText()formatsComposerTerminalContextNodewithformatTerminalContextLabel(), which injects the English wordsline/linesinto the direction text. For an RTL-only terminal chip such as{ terminalLabel: "מסוף", lineStart: 1, lineEnd: 1 }, the plugin computesdirFor("מסוף line 1"), anddirForfalls back to LTR on the 4-vs-4 tie. The visible chip text is actually the compact inline form (@מסוף:1), which is RTL. As a result, a composer containing only RTL terminal-context chips is still rendered LTR, so this change fails to fix RTL direction for that case.
apps/web/src/components/chat/userMessageTerminalContexts.ts:27
buildUserMessageDirectionText()always appendsbuildInlineTerminalContextText(contexts)totext, even whenprops.textalready contains those inline terminal labels. In the embedded-label path,UserMessageBodyrenders each label only once, butdirFor(directionText)counts the RTL header characters twice. A mixed message likedone @מסוף:1will therefore be classified asrtleven though the rendered content has an LTR majority/tie, so the whole user message bubble gets the wrong base direction.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/ChatMarkdown.tsx around line 1424:
The `dir` computation calls `blockDirForMarkdownNode(text, node, children)`, which derives direction from offsets into the raw markdown `text`. Because `rehypeRaw` is enabled, raw HTML inside markdown like `<blockquote>שלום</blockquote>` contributes ASCII tag names (`blockquote`, `kbd`, etc.) to the scanned source slice, so `dirForMarkdown` counts that ASCII content as visible LTR text and the node is assigned `dir="ltr"` even when the visible content is purely RTL. As a result, raw-HTML RTL blocks render with the wrong text direction. Consider computing direction from the rendered text content (`children`) rather than the raw markdown source offsets.
Also found in 2 other location(s):
- apps/web/src/components/ComposerPromptEditor.tsx:865 -- `composerDirectionText()` formats `ComposerTerminalContextNode` with `formatTerminalContextLabel()`, which injects the English words `line`/`lines` into the direction text. For an RTL-only terminal chip such as `{ terminalLabel: "מסוף", lineStart: 1, lineEnd: 1 }`, the plugin computes `dirFor("מסוף line 1")`, and `dirFor` falls back to LTR on the 4-vs-4 tie. The visible chip text is actually the compact inline form (`@מסוף:1`), which is RTL. As a result, a composer containing only RTL terminal-context chips is still rendered LTR, so this change fails to fix RTL direction for that case.
- apps/web/src/components/chat/userMessageTerminalContexts.ts:27 -- `buildUserMessageDirectionText()` always appends `buildInlineTerminalContextText(contexts)` to `text`, even when `props.text` already contains those inline terminal labels. In the embedded-label path, `UserMessageBody` renders each label only once, but `dirFor(directionText)` counts the RTL header characters twice. A mixed message like ``done @מסוף:1`` will therefore be classified as `rtl` even though the rendered content has an LTR majority/tie, so the whole user message bubble gets the wrong base direction.
e3f7120 to
58fe92c
Compare
Summary
Part of #1771.
Stack
This PR is the first small slice of the RTL fix stack:
1771-rtl-markdown-rendering- markdown/list/blockquote rendering, stacked on this branch.1771-rtl-composer-message-direction- composer and user-message direction, stacked on the markdown branch.The follow-up branches are pushed to the fork. They should be opened against upstream after the prior slice lands, because this fork does not have permission to create upstream base branches for true stacked PRs.
Validation
pnpm --dir apps/web exec vp test run src/lib/rtl.test.ts --passWithNoTests --project unitpnpm exec vp run typecheckpnpm exec vp check(passes with existing warnings)