[lexical][lexical-rich-text][lexical-list] Bug Fix: Import dir attribute in importDOM#8412
Conversation
…ute in importDOM Read the dir attribute from HTML elements during importDOM and call setDirection() on the created node. Previously, exportDOM correctly exported the dir attribute but importDOM did not read it back, causing text direction to be lost on HTML import. Fixes facebook#7765
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
tests are failing, expectations probably need to change to match the more correct behavior |
…r attribute Update test fixtures to reflect that importDOM now preserves the dir attribute on imported elements. Affects HTMLCopyAndPaste, LexicalTabNode, and LexicalTableNode external-source paste tests.
|
Done — fixed the expectations so |
…import Update playground e2e fixtures to reflect that importDOM now preserves the dir attribute. Affects code block, table, BIU formatting, and font-size paste tests where the source HTML carried dir="ltr".
| let direction: string | null = null; | ||
| editor.getEditorState().read(() => { | ||
| const firstChild = $getRoot().getFirstChild(); | ||
| if ($isElementNode(firstChild)) { | ||
| direction = firstChild.getDirection(); | ||
| } | ||
| }); | ||
| return direction; |
There was a problem hiding this comment.
| let direction: string | null = null; | |
| editor.getEditorState().read(() => { | |
| const firstChild = $getRoot().getFirstChild(); | |
| if ($isElementNode(firstChild)) { | |
| direction = firstChild.getDirection(); | |
| } | |
| }); | |
| return direction; | |
| return editor.read(() => { | |
| const firstChild = $getRoot().getFirstChild(); | |
| return $isElementNode(firstChild) ? firstChild.getDirection() : null; | |
| }); |
| ).toBe('rtl'); | ||
| }); | ||
|
|
||
| test('list with dir="rtl"', () => { |
There was a problem hiding this comment.
this looks like it could be an importAndGetDirection test
also these could be simplified a bit further by using a data structure to build the tests https://vitest.dev/api/test.html#test-for
| const dir = domNode.getAttribute('dir'); | ||
| if (dir === 'ltr' || dir === 'rtl') { | ||
| node.setDirection(dir); | ||
| } |
There was a problem hiding this comment.
This seems like a useful helper to export from lexical since it's used across several places, e.g.
export function $setDirectionFromDOM<T extends ElementNode>(node: T, domNode: HTMLElement): T {
const dir = domNode.getAttribute('dir');
return dir === 'ltr' || dir === 'rtl' ? node.setDirection(dir) : node;
}…tract $setDirectionFromDOM helper Extract the dir attribute import pattern into $setDirectionFromDOM in LexicalUtils and reuse it in ParagraphNode, ListItemNode, ListNode, and the heading/blockquote converters in lexical-rich-text. Refactor the LexicalHtml dir-import tests to use editor.read(cb) returning directly and consolidate the cases into a single test.for table.
|
Thanks for the pointers — all three applied:
|
| elementNode.setIndent(indent); | ||
| } | ||
|
|
||
| export function $setDirectionFromDOM<T extends ElementNode>( |
There was a problem hiding this comment.
Let's add some API docs for this new export, otherwise I think everything here looks great
|
Done — added JSDoc for |
Description
Fixes #7765
The
dirattribute is exported correctly viaexportDOM(added in #7727), butimportDOMconversion functions don't read it back. This means the text direction is lost when importing HTML — for example, RTL content pasted into the editor loses its direction.What changed
Added
dirattribute handling to all ElementNodeimportDOMconversion functions:$convertParagraphElement(LexicalParagraphNode.ts)$convertHeadingElement(lexical-rich-text)$convertBlockquoteElement(lexical-rich-text)$convertListNode(lexical-list)$convertListItemElement(lexical-list)Each reads
element.getAttribute('dir')and callsnode.setDirection(dir)when the value is'ltr'or'rtl'.Test Plan
Added tests for HTML import → direction preservation: