fix(richtext-lexical): recursively unwrap generic Slate nodes in Lexical migration converter (#13202)
## What? The Slate to Lexical migration script assumes that the depth of Slate nodes matches the depth of the Lexical schema, which isn't necessarily true. This pull request fixes this assumption by first checking for children and unwrapping the text nodes. ## Why? During my migration, I ran into a lot of copy + pasted rich text with list items with untyped nodes with `children`. The existing migration script assumed that since list items can't have paragraphs, all untyped nodes inside must be text nodes. The result of the migration script was a lot of invalid text nodes with `text: undefined` and all of the content in the `children` being silently lost. Beyond the silent loss, the invalid text nodes caused the Lexical editor to unmount with an error about accessing `0 of undefined`, so those documents couldn't be edited. This additionally makes the migration script more closely align with the [recursive serialization logic recommendation from the Payload Slate Rich Text documentation](https://payloadcms.com/docs/rich-text/slate#generating-html). ## Visualization ### Slate ```txt Slate rich text content ┣━┳━ Unordered list ┋ ┣━┳━ List item ┋ ┋ ┗━┳━ Generic (paragraph-like, untyped with children) ┋ ┋ ┣━━━ Text (untyped) `Hello ` ┋ ┋ ┗━━━ Text (untyped) `World! [...] ``` ### Lexical Before PR ```txt Lexical rich text content (invalid) ┣━┳━ Unordered list ┋ ┣━┳━ List item ┋ ┋ ┗━━━ Invalid text (assumed the generic node was text, stopped processing children, cannot restore lost text without a restoring backup with Slate and rerunning the script after this MR) [...] ``` ### Lexical After PR ```txt Lexical rich text content ┣━┳━ Unordered list ┋ ┣━┳━ List item ┋ ┋ ┣━━━ Text `Hello ` ┋ ┋ ┗━━━ Text `World! [...] ``` --------- Co-authored-by: German Jablonski <43938777+GermanJablo@users.noreply.github.com>
This commit is contained in:
@@ -73,7 +73,16 @@ export function generateSlateRichText() {
|
||||
{
|
||||
children: [
|
||||
{
|
||||
text: "It's built with SlateJS",
|
||||
// This node is untyped, because I want to test this scenario:
|
||||
// https://github.com/payloadcms/payload/pull/13202
|
||||
children: [
|
||||
{
|
||||
text: 'This editor is built ',
|
||||
},
|
||||
{
|
||||
text: 'with SlateJS',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
type: 'li',
|
||||
|
||||
Reference in New Issue
Block a user