From 654a7a5d03000e6236929fa4dc3e2d6607edb757 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Sat, 21 Sep 2024 13:00:16 +0100 Subject: [PATCH] Lexical: Removed reconciler level direction handling - Updated tests to consider changes --- .../wysiwyg/lexical/core/LexicalReconciler.ts | 115 +------------ .../__tests__/unit/HTMLCopyAndPaste.test.ts | 12 +- .../core/__tests__/unit/LexicalEditor.test.ts | 38 ++--- .../__tests__/unit/LexicalEditorState.test.ts | 6 +- .../core/__tests__/unit/LexicalNode.test.ts | 88 +++++----- .../__tests__/unit/LexicalSelection.test.ts | 18 +- .../unit/LexicalSerialization.test.ts | 4 +- .../__tests__/unit/LexicalTabNode.test.ts | 12 +- .../lexical/core/shared/reactPatches.ts | 22 --- .../lexical/core/shared/useLayoutEffect.ts | 19 --- .../unit/LexicalListItemNode.test.ts | 154 +++++++++--------- .../__tests__/unit/LexicalHeadingNode.test.ts | 12 +- .../__tests__/unit/LexicalSelection.test.ts | 66 ++++---- .../unit/LexicalSelectionHelpers.test.ts | 62 +++---- .../__tests__/unit/LexicalTableNode.test.ts | 8 +- .../unit/LexicalTableSelection.test.ts | 4 +- .../unit/LexicalEventHelpers.test.ts | 92 +++++------ resources/js/wysiwyg/nodes/_common.ts | 30 +++- resources/js/wysiwyg/todo.md | 4 + .../wysiwyg/ui/defaults/buttons/alignments.ts | 11 +- .../js/wysiwyg/ui/defaults/buttons/lists.ts | 10 +- tsconfig.json | 1 + 22 files changed, 329 insertions(+), 459 deletions(-) delete mode 100644 resources/js/wysiwyg/lexical/core/shared/reactPatches.ts delete mode 100644 resources/js/wysiwyg/lexical/core/shared/useLayoutEffect.ts diff --git a/resources/js/wysiwyg/lexical/core/LexicalReconciler.ts b/resources/js/wysiwyg/lexical/core/LexicalReconciler.ts index 0162d2281..09d01bffd 100644 --- a/resources/js/wysiwyg/lexical/core/LexicalReconciler.ts +++ b/resources/js/wysiwyg/lexical/core/LexicalReconciler.ts @@ -42,14 +42,12 @@ import { $textContentRequiresDoubleLinebreakAtEnd, cloneDecorators, getElementByKeyOrThrow, - getTextDirection, setMutatedNode, } from './LexicalUtils'; type IntentionallyMarkedAsDirtyElement = boolean; let subTreeTextContent = ''; -let subTreeDirectionedTextContent = ''; let subTreeTextFormat: number | null = null; let subTreeTextStyle: string = ''; let editorTextContent = ''; @@ -59,7 +57,6 @@ let activeEditorNodes: RegisteredNodes; let treatAllNodesAsDirty = false; let activeEditorStateReadOnly = false; let activeMutationListeners: MutationListeners; -let activeTextDirection: 'ltr' | 'rtl' | null = null; let activeDirtyElements: Map; let activeDirtyLeaves: Set; let activePrevNodeMap: NodeMap; @@ -197,7 +194,7 @@ function $createNode( if (childrenSize !== 0) { const endIndex = childrenSize - 1; const children = createChildrenArray(node, activeNextNodeMap); - $createChildrenWithDirection(children, endIndex, node, dom); + $createChildren(children, node, 0, endIndex, dom, null); } const format = node.__format; @@ -222,10 +219,6 @@ function $createNode( } // Decorators are always non editable dom.contentEditable = 'false'; - } else if ($isTextNode(node)) { - if (!node.isDirectionless()) { - subTreeDirectionedTextContent += text; - } } subTreeTextContent += text; editorTextContent += text; @@ -261,19 +254,6 @@ function $createNode( return dom; } -function $createChildrenWithDirection( - children: Array, - endIndex: number, - element: ElementNode, - dom: HTMLElement, -): void { - const previousSubTreeDirectionedTextContent = subTreeDirectionedTextContent; - subTreeDirectionedTextContent = ''; - $createChildren(children, element, 0, endIndex, dom, null); - reconcileBlockDirection(element, dom); - subTreeDirectionedTextContent = previousSubTreeDirectionedTextContent; -} - function $createChildren( children: Array, element: ElementNode, @@ -388,93 +368,16 @@ function reconcileParagraphStyle(element: ElementNode): void { } } -function reconcileBlockDirection(element: ElementNode, dom: HTMLElement): void { - const previousSubTreeDirectionTextContent: string = - // @ts-expect-error: internal field - dom.__lexicalDirTextContent; - // @ts-expect-error: internal field - const previousDirection: string = dom.__lexicalDir; - - if ( - previousSubTreeDirectionTextContent !== subTreeDirectionedTextContent || - previousDirection !== activeTextDirection - ) { - const hasEmptyDirectionedTextContent = subTreeDirectionedTextContent === ''; - const direction = hasEmptyDirectionedTextContent - ? activeTextDirection - : getTextDirection(subTreeDirectionedTextContent); - - if (direction !== previousDirection) { - const classList = dom.classList; - const theme = activeEditorConfig.theme; - let previousDirectionTheme = - previousDirection !== null ? theme[previousDirection] : undefined; - let nextDirectionTheme = - direction !== null ? theme[direction] : undefined; - - // Remove the old theme classes if they exist - if (previousDirectionTheme !== undefined) { - if (typeof previousDirectionTheme === 'string') { - const classNamesArr = normalizeClassNames(previousDirectionTheme); - previousDirectionTheme = theme[previousDirection] = classNamesArr; - } - - // @ts-ignore: intentional - classList.remove(...previousDirectionTheme); - } - - if ( - direction === null || - (hasEmptyDirectionedTextContent && direction === 'ltr') - ) { - // Remove direction - dom.removeAttribute('dir'); - } else { - // Apply the new theme classes if they exist - if (nextDirectionTheme !== undefined) { - if (typeof nextDirectionTheme === 'string') { - const classNamesArr = normalizeClassNames(nextDirectionTheme); - // @ts-expect-error: intentional - nextDirectionTheme = theme[direction] = classNamesArr; - } - - if (nextDirectionTheme !== undefined) { - classList.add(...nextDirectionTheme); - } - } - - // Update direction - dom.dir = direction; - } - - if (!activeEditorStateReadOnly) { - const writableNode = element.getWritable(); - writableNode.__dir = direction; - } - } - - activeTextDirection = direction; - // @ts-expect-error: internal field - dom.__lexicalDirTextContent = subTreeDirectionedTextContent; - // @ts-expect-error: internal field - dom.__lexicalDir = direction; - } -} - function $reconcileChildrenWithDirection( prevElement: ElementNode, nextElement: ElementNode, dom: HTMLElement, ): void { - const previousSubTreeDirectionTextContent = subTreeDirectionedTextContent; - subTreeDirectionedTextContent = ''; subTreeTextFormat = null; subTreeTextStyle = ''; $reconcileChildren(prevElement, nextElement, dom); - reconcileBlockDirection(nextElement, dom); reconcileParagraphFormat(nextElement); reconcileParagraphStyle(nextElement); - subTreeDirectionedTextContent = previousSubTreeDirectionTextContent; } function createChildrenArray( @@ -624,20 +527,9 @@ function $reconcileNode( subTreeTextContent += previousSubTreeTextContent; editorTextContent += previousSubTreeTextContent; } - - // @ts-expect-error: internal field - const previousSubTreeDirectionTextContent = dom.__lexicalDirTextContent; - - if (previousSubTreeDirectionTextContent !== undefined) { - subTreeDirectionedTextContent += previousSubTreeDirectionTextContent; - } } else { const text = prevNode.getTextContent(); - if ($isTextNode(prevNode) && !prevNode.isDirectionless()) { - subTreeDirectionedTextContent += text; - } - editorTextContent += text; subTreeTextContent += text; } @@ -702,9 +594,6 @@ function $reconcileNode( if (decorator !== null) { reconcileDecorator(key, decorator); } - } else if ($isTextNode(nextNode) && !nextNode.isDirectionless()) { - // Handle text content, for LTR, LTR cases. - subTreeDirectionedTextContent += text; } subTreeTextContent += text; @@ -871,11 +760,9 @@ export function $reconcileRoot( // The cache must be rebuilt during reconciliation to account for any changes. subTreeTextContent = ''; editorTextContent = ''; - subTreeDirectionedTextContent = ''; // Rather than pass around a load of arguments through the stack recursively // we instead set them as bindings within the scope of the module. treatAllNodesAsDirty = dirtyType === FULL_RECONCILE; - activeTextDirection = null; activeEditor = editor; activeEditorConfig = editor._config; activeEditorNodes = editor._nodes; diff --git a/resources/js/wysiwyg/lexical/core/__tests__/unit/HTMLCopyAndPaste.test.ts b/resources/js/wysiwyg/lexical/core/__tests__/unit/HTMLCopyAndPaste.test.ts index 056de19e4..9f832b69e 100644 --- a/resources/js/wysiwyg/lexical/core/__tests__/unit/HTMLCopyAndPaste.test.ts +++ b/resources/js/wysiwyg/lexical/core/__tests__/unit/HTMLCopyAndPaste.test.ts @@ -34,12 +34,12 @@ describe('HTMLCopyAndPaste tests', () => { const HTML_COPY_PASTING_TESTS = [ { - expectedHTML: `

Hello!

`, + expectedHTML: `

Hello!

`, name: 'plain DOM text node', pastedHTML: `Hello!`, }, { - expectedHTML: `

Hello!


`, + expectedHTML: `

Hello!


`, name: 'a paragraph element', pastedHTML: `

Hello!

`, }, @@ -52,7 +52,7 @@ describe('HTMLCopyAndPaste tests', () => { `, }, { - expectedHTML: `

a b c d e

f g h

`, + expectedHTML: `

a b c d e

f g h

`, name: 'multiple nested spans and divs', pastedHTML: `
a b @@ -82,12 +82,12 @@ describe('HTMLCopyAndPaste tests', () => { pastedHTML: ` 123
456
`, }, { - expectedHTML: `
  • done
  • todo
    • done
    • todo
  • todo
`, + expectedHTML: `
  • done
  • todo
    • done
    • todo
  • todo
`, name: 'google doc checklist', - pastedHTML: `
  • checked

    done

  • unchecked

    todo

    • checked

      done

    • unchecked

      todo

  • unchecked

    todo

`, + pastedHTML: `
  • checked

    done

  • unchecked

    todo

    • checked

      done

    • unchecked

      todo

  • unchecked

    todo

`, }, { - expectedHTML: `

checklist

  • done
  • todo
`, + expectedHTML: `

checklist

  • done
  • todo
`, name: 'github checklist', pastedHTML: `

checklist

  • done
  • todo
`, }, diff --git a/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalEditor.test.ts b/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalEditor.test.ts index 4e3e622ce..f3c6f7105 100644 --- a/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalEditor.test.ts +++ b/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalEditor.test.ts @@ -258,7 +258,7 @@ describe('LexicalEditor tests', () => { await Promise.resolve().then(); expect(container.innerHTML).toBe( - '

This works!

', + '

This works!

', ); const initialEditorState = initialEditor.getEditorState(); @@ -276,7 +276,7 @@ describe('LexicalEditor tests', () => { expect(editor.getEditorState()).toEqual(initialEditorState); expect(container.innerHTML).toBe( - '

This works!

', + '

This works!

', ); }); @@ -520,7 +520,7 @@ describe('LexicalEditor tests', () => { underlineListener(); expect(container.innerHTML).toBe( - '

foo

', + '

foo

', ); }); @@ -586,7 +586,7 @@ describe('LexicalEditor tests', () => { italicsListener(); expect(container.innerHTML).toBe( - '

foo

', + '

foo

', ); }); @@ -657,7 +657,7 @@ describe('LexicalEditor tests', () => { boldFooListener(); expect(container.innerHTML).toBe( - '

Foo!!

', + '

Foo!!

', ); }); @@ -875,7 +875,7 @@ describe('LexicalEditor tests', () => { editor.setRootElement(element); expect(container.innerHTML).toBe( - '

This works!

', + '

This works!

', ); }); @@ -897,7 +897,7 @@ describe('LexicalEditor tests', () => { await Promise.resolve().then(); expect(container.innerHTML).toBe( - '

This works!

', + '

This works!

', ); expect(errorListener).toHaveBeenCalledTimes(0); @@ -912,7 +912,7 @@ describe('LexicalEditor tests', () => { expect(errorListener).toHaveBeenCalledTimes(1); expect(container.innerHTML).toBe( - '

This works!

', + '

This works!

', ); }); @@ -953,7 +953,7 @@ describe('LexicalEditor tests', () => { editorInstance.commitUpdates(); expect(container.innerHTML).toBe( - '

Not changed

', + '

Not changed

', ); edContainer = document.createElement('span'); @@ -966,7 +966,7 @@ describe('LexicalEditor tests', () => { expect(rootListener).toHaveBeenCalledTimes(3); expect(updateListener).toHaveBeenCalledTimes(3); expect(container.innerHTML).toBe( - '

Change successful

', + '

Change successful

', ); }); @@ -1046,7 +1046,7 @@ describe('LexicalEditor tests', () => { it('Parses the nodes of a stringified editor state', async () => { expect(parsedRoot).toEqual({ __cachedText: null, - __dir: 'ltr', + __dir: null, __first: paragraphKey, __format: 0, __indent: 0, @@ -1060,7 +1060,7 @@ describe('LexicalEditor tests', () => { __type: 'root', }); expect(parsedParagraph).toEqual({ - __dir: 'ltr', + __dir: null, __first: textKey, __format: 0, __indent: 0, @@ -1128,7 +1128,7 @@ describe('LexicalEditor tests', () => { it('Parses the nodes of a stringified editor state', async () => { expect(parsedRoot).toEqual({ __cachedText: null, - __dir: 'ltr', + __dir: null, __first: paragraphKey, __format: 0, __indent: 0, @@ -1142,7 +1142,7 @@ describe('LexicalEditor tests', () => { __type: 'root', }); expect(parsedParagraph).toEqual({ - __dir: 'ltr', + __dir: null, __first: textKey, __format: 0, __indent: 0, @@ -1275,7 +1275,7 @@ describe('LexicalEditor tests', () => { expect(editor._editorState._nodeMap.size).toBe(keys.length + 1); // + root expect(editor._keyToDOMMap.size).toBe(keys.length + 1); // + root expect(container.innerHTML).toBe( - '

A
B

', + '

A
B

', ); }); @@ -1310,7 +1310,7 @@ describe('LexicalEditor tests', () => { }); expect(container.innerHTML).toBe( - '

B
A

', + '

B
A

', ); }); @@ -1351,7 +1351,7 @@ describe('LexicalEditor tests', () => { }); expect(container.innerHTML).toBe( - '

A
C
B

', + '

A
C
B

', ); }); }); @@ -2294,14 +2294,14 @@ describe('LexicalEditor tests', () => { }); expect(container.firstElementChild?.innerHTML).toBe( - '

Hello

', + '

Hello

', ); }); it('reconciles state without root element', () => { editor = createTestEditor({}); const state = editor.parseEditorState( - `{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Hello world","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}`, + `{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Hello world","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1}],"direction":null,"format":"","indent":0,"type":"root","version":1}}`, ); editor.setEditorState(state); expect(editor._editorState).toBe(state); diff --git a/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalEditorState.test.ts b/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalEditorState.test.ts index 09b49b738..38ecf03bc 100644 --- a/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalEditorState.test.ts +++ b/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalEditorState.test.ts @@ -52,7 +52,7 @@ describe('LexicalEditorState tests', () => { expect(root).toEqual({ __cachedText: 'foo', - __dir: 'ltr', + __dir: null, __first: '1', __format: 0, __indent: 0, @@ -66,7 +66,7 @@ describe('LexicalEditorState tests', () => { __type: 'root', }); expect(paragraph).toEqual({ - __dir: 'ltr', + __dir: null, __first: '2', __format: 0, __indent: 0, @@ -113,7 +113,7 @@ describe('LexicalEditorState tests', () => { }); expect(JSON.stringify(editor.getEditorState().toJSON())).toEqual( - `{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Hello world","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}`, + `{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Hello world","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"root","version":1}}`, ); }); diff --git a/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalNode.test.ts b/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalNode.test.ts index 7373f898d..fcf666213 100644 --- a/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalNode.test.ts +++ b/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalNode.test.ts @@ -645,7 +645,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

foo

', + '

foo

', ); await editor.getEditorState().read(() => { @@ -667,7 +667,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

foobar

', + '

foobar

', ); await editor.getEditorState().read(() => { @@ -694,7 +694,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

foobarbaz

', + '

foobarbaz

', ); await editor.getEditorState().read(() => { @@ -730,7 +730,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

foobar

', + '

foobar

', ); await editor.getEditorState().read(() => { @@ -754,7 +754,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

foobarbaz

', + '

foobarbaz

', ); await editor.getEditorState().read(() => { @@ -795,7 +795,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

fooqux

bar

baz

', + '

fooqux

bar

baz

', ); await editor.getEditorState().read(() => { @@ -828,7 +828,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

foobarbaz

', + '

foobarbaz

', ); await editor.getEditorState().read(() => { @@ -879,7 +879,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

foobarbaz

qux

', + '

foobarbaz

qux

', ); await editor.getEditorState().read(() => { @@ -915,7 +915,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

footoken

', + '

footoken

', ); await editor.getEditorState().read(() => { @@ -935,7 +935,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

foosegmented

', + '

foosegmented

', ); await editor.getEditorState().read(() => { @@ -958,7 +958,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

foodirectionless

', + '

foodirectionless

', ); await editor.getEditorState().read(() => { @@ -1057,7 +1057,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

foo

', + '

foo

', ); await editor.update(() => { @@ -1089,7 +1089,7 @@ describe('LexicalNode tests', () => { const {editor} = testEnv; expect(testEnv.outerHTML).toBe( - '

foo

', + '

foo

', ); let barTextNode: TextNode; @@ -1102,7 +1102,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

foo

bar

', + '

foo

bar

', ); await editor.update(() => { @@ -1110,7 +1110,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

bar


', + '

bar


', ); }); @@ -1118,7 +1118,7 @@ describe('LexicalNode tests', () => { const {editor} = testEnv; expect(testEnv.outerHTML).toBe( - '

foo

', + '

foo

', ); await editor.update(() => { @@ -1127,7 +1127,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

bar

', + '

bar

', ); }); @@ -1135,7 +1135,7 @@ describe('LexicalNode tests', () => { const {editor} = testEnv; expect(testEnv.outerHTML).toBe( - '

foo

', + '

foo

', ); await editor.update(() => { @@ -1144,7 +1144,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

bar

', + '

bar

', ); }); @@ -1152,7 +1152,7 @@ describe('LexicalNode tests', () => { const {editor} = testEnv; expect(testEnv.outerHTML).toBe( - '

foo

', + '

foo

', ); await editor.update(() => { @@ -1161,7 +1161,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

bar

', + '

bar

', ); }); @@ -1169,7 +1169,7 @@ describe('LexicalNode tests', () => { const {editor} = testEnv; expect(testEnv.outerHTML).toBe( - '

foo

', + '

foo

', ); await editor.update(() => { @@ -1205,7 +1205,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '', + '', ); }); @@ -1224,7 +1224,7 @@ describe('LexicalNode tests', () => { const {editor} = testEnv; expect(testEnv.outerHTML).toBe( - '

foo

', + '

foo

', ); await editor.update(() => { @@ -1233,7 +1233,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

foobar

', + '

foobar

', ); }); @@ -1241,7 +1241,7 @@ describe('LexicalNode tests', () => { const {editor} = testEnv; expect(testEnv.outerHTML).toBe( - '

foo

', + '

foo

', ); await editor.update(() => { @@ -1250,7 +1250,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

foobar

', + '

foobar

', ); }); @@ -1258,7 +1258,7 @@ describe('LexicalNode tests', () => { const {editor} = testEnv; expect(testEnv.outerHTML).toBe( - '

foo

', + '

foo

', ); await editor.update(() => { @@ -1267,7 +1267,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

foobar

', + '

foobar

', ); }); @@ -1275,7 +1275,7 @@ describe('LexicalNode tests', () => { const {editor} = testEnv; expect(testEnv.outerHTML).toBe( - '

foo

', + '

foo

', ); await editor.update(() => { @@ -1284,7 +1284,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

foobar

', + '

foobar

', ); // TODO: add text direction validations }); @@ -1314,7 +1314,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

A

B

C

', + '

A

B

C

', ); await editor.update(() => { @@ -1322,7 +1322,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

A

B

C

', + '

A

B

C

', ); }); @@ -1356,7 +1356,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

A

B

C

', + '

A

B

C

', ); await editor.update(() => { @@ -1365,7 +1365,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '



CBA

', + '



CBA

', ); }); @@ -1384,7 +1384,7 @@ describe('LexicalNode tests', () => { const {editor} = testEnv; expect(testEnv.outerHTML).toBe( - '

foo

', + '

foo

', ); let barTextNode; @@ -1397,7 +1397,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

foo

bar

', + '

foo

bar

', ); }); @@ -1405,7 +1405,7 @@ describe('LexicalNode tests', () => { const {editor} = testEnv; expect(testEnv.outerHTML).toBe( - '

foo

', + '

foo

', ); await editor.update(() => { @@ -1414,7 +1414,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

barfoo

', + '

barfoo

', ); }); @@ -1422,7 +1422,7 @@ describe('LexicalNode tests', () => { const {editor} = testEnv; expect(testEnv.outerHTML).toBe( - '

foo

', + '

foo

', ); await editor.update(() => { @@ -1431,7 +1431,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

barfoo

', + '

barfoo

', ); }); @@ -1439,7 +1439,7 @@ describe('LexicalNode tests', () => { const {editor} = testEnv; expect(testEnv.outerHTML).toBe( - '

foo

', + '

foo

', ); await editor.update(() => { @@ -1448,7 +1448,7 @@ describe('LexicalNode tests', () => { }); expect(testEnv.outerHTML).toBe( - '

barfoo

', + '

barfoo

', ); }); @@ -1456,7 +1456,7 @@ describe('LexicalNode tests', () => { const {editor} = testEnv; expect(testEnv.outerHTML).toBe( - '

foo

', + '

foo

', ); await editor.update(() => { diff --git a/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalSelection.test.ts b/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalSelection.test.ts index 7055f361a..ac0ec15e5 100644 --- a/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalSelection.test.ts +++ b/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalSelection.test.ts @@ -61,10 +61,10 @@ describe('LexicalSelection tests', () => { const expectation = mode === 'start-of-paragraph' - ? '

ab

' + ? '

ab

' : mode === 'mid-paragraph' - ? '

abc

' - : '

ab

'; + ? '

abc

' + : '

ab

'; expect(container.innerHTML).toBe(expectation); @@ -113,7 +113,7 @@ describe('LexicalSelection tests', () => { }); expect(container.innerHTML).toBe( - '

xab

', + '

xab

', ); }; @@ -154,7 +154,7 @@ describe('LexicalSelection tests', () => { }); expect(container.innerHTML).toBe( - '

axbc

', + '

axbc

', ); }; @@ -194,7 +194,7 @@ describe('LexicalSelection tests', () => { }); expect(container.innerHTML).toBe( - '

axb

', + '

axb

', ); }; @@ -236,7 +236,7 @@ describe('LexicalSelection tests', () => { }); expect(container.innerHTML).toBe( - '

axb

', + '

axb

', ); }; @@ -277,7 +277,7 @@ describe('LexicalSelection tests', () => { }); expect(container.innerHTML).toBe( - '

abxc

', + '

abxc

', ); }; @@ -319,7 +319,7 @@ describe('LexicalSelection tests', () => { }); expect(container.innerHTML).toBe( - '

abx

', + '

abx

', ); }; diff --git a/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalSerialization.test.ts b/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalSerialization.test.ts index 02231f8bf..5599604c0 100644 --- a/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalSerialization.test.ts +++ b/resources/js/wysiwyg/lexical/core/__tests__/unit/LexicalSerialization.test.ts @@ -106,7 +106,7 @@ describe('LexicalSerialization tests', () => { }); const stringifiedEditorState = JSON.stringify(editor.getEditorState()); - const expectedStringifiedEditorState = `{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Welcome to the playground","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"heading","version":1,"tag":"h1"},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"In case you were wondering what the black box at the bottom is – it's the debug view, showing the current state of the editor. You can disable it by pressing on the settings control in the bottom-left of your screen and toggling the debug view setting.","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"quote","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"The playground is a demo environment built with ","type":"text","version":1},{"detail":0,"format":16,"mode":"normal","style":"","text":"@lexical/react","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":". Try typing in ","type":"text","version":1},{"detail":0,"format":1,"mode":"normal","style":"","text":"some text","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":" with ","type":"text","version":1},{"detail":0,"format":2,"mode":"normal","style":"","text":"different","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":" formats.","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Make sure to check out the various plugins in the toolbar. You can also use #hashtags or @-mentions too!","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"If you'd like to find out more about Lexical, you can:","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Visit the ","type":"text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Lexical website","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"title":null,"url":"https://lexical.dev/"},{"detail":0,"format":0,"mode":"normal","style":"","text":" for documentation and more information.","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"listitem","version":1,"value":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Check out the code on our ","type":"text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"GitHub repository","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"title":null,"url":"https://github.com/facebook/lexical"},{"detail":0,"format":0,"mode":"normal","style":"","text":".","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"listitem","version":1,"value":2},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Playground code can be found ","type":"text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"here","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"title":null,"url":"https://github.com/facebook/lexical/tree/main/packages/lexical-playground"},{"detail":0,"format":0,"mode":"normal","style":"","text":".","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"listitem","version":1,"value":3},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Join our ","type":"text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Discord Server","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"title":null,"url":"https://discord.com/invite/KmG4wQnnD9"},{"detail":0,"format":0,"mode":"normal","style":"","text":" and chat with the team.","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"listitem","version":1,"value":4}],"direction":"ltr","format":"","indent":0,"type":"list","version":1,"listType":"bullet","start":1,"tag":"ul"},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Lastly, we're constantly adding cool new features to this playground. So make sure you check back here when you next get a chance :).","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":3,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":1,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":1,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":1,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":1,"rowSpan":1}],"direction":"ltr","format":"","indent":0,"type":"tablerow","version":1},{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":2,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1}],"direction":"ltr","format":"","indent":0,"type":"tablerow","version":1},{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":2,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1}],"direction":"ltr","format":"","indent":0,"type":"tablerow","version":1},{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":2,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1}],"direction":"ltr","format":"","indent":0,"type":"tablerow","version":1},{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":2,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1}],"direction":"ltr","format":"","indent":0,"type":"tablerow","version":1}],"direction":"ltr","format":"","indent":0,"type":"table","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}`; + const expectedStringifiedEditorState = `{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Welcome to the playground","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"heading","version":1,"tag":"h1"},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"In case you were wondering what the black box at the bottom is – it's the debug view, showing the current state of the editor. You can disable it by pressing on the settings control in the bottom-left of your screen and toggling the debug view setting.","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"quote","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"The playground is a demo environment built with ","type":"text","version":1},{"detail":0,"format":16,"mode":"normal","style":"","text":"@lexical/react","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":". Try typing in ","type":"text","version":1},{"detail":0,"format":1,"mode":"normal","style":"","text":"some text","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":" with ","type":"text","version":1},{"detail":0,"format":2,"mode":"normal","style":"","text":"different","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":" formats.","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Make sure to check out the various plugins in the toolbar. You can also use #hashtags or @-mentions too!","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"If you'd like to find out more about Lexical, you can:","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Visit the ","type":"text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Lexical website","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"title":null,"url":"https://lexical.dev/"},{"detail":0,"format":0,"mode":"normal","style":"","text":" for documentation and more information.","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"listitem","version":1,"value":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Check out the code on our ","type":"text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"GitHub repository","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"title":null,"url":"https://github.com/facebook/lexical"},{"detail":0,"format":0,"mode":"normal","style":"","text":".","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"listitem","version":1,"value":2},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Playground code can be found ","type":"text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"here","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"title":null,"url":"https://github.com/facebook/lexical/tree/main/packages/lexical-playground"},{"detail":0,"format":0,"mode":"normal","style":"","text":".","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"listitem","version":1,"value":3},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Join our ","type":"text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Discord Server","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"title":null,"url":"https://discord.com/invite/KmG4wQnnD9"},{"detail":0,"format":0,"mode":"normal","style":"","text":" and chat with the team.","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"listitem","version":1,"value":4}],"direction":null,"format":"","indent":0,"type":"list","version":1,"listType":"bullet","start":1,"tag":"ul"},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Lastly, we're constantly adding cool new features to this playground. So make sure you check back here when you next get a chance :).","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":3,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":1,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":1,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":1,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":1,"rowSpan":1}],"direction":null,"format":"","indent":0,"type":"tablerow","version":1},{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":2,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1}],"direction":null,"format":"","indent":0,"type":"tablerow","version":1},{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":2,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1}],"direction":null,"format":"","indent":0,"type":"tablerow","version":1},{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":2,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1}],"direction":null,"format":"","indent":0,"type":"tablerow","version":1},{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":2,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1}],"direction":null,"format":"","indent":0,"type":"tablerow","version":1}],"direction":null,"format":"","indent":0,"type":"table","version":1}],"direction":null,"format":"","indent":0,"type":"root","version":1}}`; expect(stringifiedEditorState).toBe(expectedStringifiedEditorState); @@ -115,7 +115,7 @@ describe('LexicalSerialization tests', () => { const otherStringifiedEditorState = JSON.stringify(editorState); expect(otherStringifiedEditorState).toBe( - `{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Welcome to the playground","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"heading","version":1,"tag":"h1"},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"In case you were wondering what the black box at the bottom is – it's the debug view, showing the current state of the editor. You can disable it by pressing on the settings control in the bottom-left of your screen and toggling the debug view setting.","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"quote","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"The playground is a demo environment built with ","type":"text","version":1},{"detail":0,"format":16,"mode":"normal","style":"","text":"@lexical/react","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":". Try typing in ","type":"text","version":1},{"detail":0,"format":1,"mode":"normal","style":"","text":"some text","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":" with ","type":"text","version":1},{"detail":0,"format":2,"mode":"normal","style":"","text":"different","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":" formats.","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Make sure to check out the various plugins in the toolbar. You can also use #hashtags or @-mentions too!","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"If you'd like to find out more about Lexical, you can:","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Visit the ","type":"text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Lexical website","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"title":null,"url":"https://lexical.dev/"},{"detail":0,"format":0,"mode":"normal","style":"","text":" for documentation and more information.","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"listitem","version":1,"value":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Check out the code on our ","type":"text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"GitHub repository","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"title":null,"url":"https://github.com/facebook/lexical"},{"detail":0,"format":0,"mode":"normal","style":"","text":".","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"listitem","version":1,"value":2},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Playground code can be found ","type":"text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"here","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"title":null,"url":"https://github.com/facebook/lexical/tree/main/packages/lexical-playground"},{"detail":0,"format":0,"mode":"normal","style":"","text":".","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"listitem","version":1,"value":3},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Join our ","type":"text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Discord Server","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"title":null,"url":"https://discord.com/invite/KmG4wQnnD9"},{"detail":0,"format":0,"mode":"normal","style":"","text":" and chat with the team.","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"listitem","version":1,"value":4}],"direction":"ltr","format":"","indent":0,"type":"list","version":1,"listType":"bullet","start":1,"tag":"ul"},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Lastly, we're constantly adding cool new features to this playground. So make sure you check back here when you next get a chance :).","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":3,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":1,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":1,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":1,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":1,"rowSpan":1}],"direction":null,"format":"","indent":0,"type":"tablerow","version":1},{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":2,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1}],"direction":null,"format":"","indent":0,"type":"tablerow","version":1},{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":2,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1}],"direction":null,"format":"","indent":0,"type":"tablerow","version":1},{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":2,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1}],"direction":null,"format":"","indent":0,"type":"tablerow","version":1},{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":2,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1}],"direction":null,"format":"","indent":0,"type":"tablerow","version":1}],"direction":null,"format":"","indent":0,"type":"table","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}`, + `{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Welcome to the playground","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"heading","version":1,"tag":"h1"},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"In case you were wondering what the black box at the bottom is – it's the debug view, showing the current state of the editor. You can disable it by pressing on the settings control in the bottom-left of your screen and toggling the debug view setting.","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"quote","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"The playground is a demo environment built with ","type":"text","version":1},{"detail":0,"format":16,"mode":"normal","style":"","text":"@lexical/react","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":". Try typing in ","type":"text","version":1},{"detail":0,"format":1,"mode":"normal","style":"","text":"some text","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":" with ","type":"text","version":1},{"detail":0,"format":2,"mode":"normal","style":"","text":"different","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":" formats.","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Make sure to check out the various plugins in the toolbar. You can also use #hashtags or @-mentions too!","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"If you'd like to find out more about Lexical, you can:","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Visit the ","type":"text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Lexical website","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"title":null,"url":"https://lexical.dev/"},{"detail":0,"format":0,"mode":"normal","style":"","text":" for documentation and more information.","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"listitem","version":1,"value":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Check out the code on our ","type":"text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"GitHub repository","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"title":null,"url":"https://github.com/facebook/lexical"},{"detail":0,"format":0,"mode":"normal","style":"","text":".","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"listitem","version":1,"value":2},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Playground code can be found ","type":"text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"here","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"title":null,"url":"https://github.com/facebook/lexical/tree/main/packages/lexical-playground"},{"detail":0,"format":0,"mode":"normal","style":"","text":".","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"listitem","version":1,"value":3},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Join our ","type":"text","version":1},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Discord Server","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"title":null,"url":"https://discord.com/invite/KmG4wQnnD9"},{"detail":0,"format":0,"mode":"normal","style":"","text":" and chat with the team.","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"listitem","version":1,"value":4}],"direction":null,"format":"","indent":0,"type":"list","version":1,"listType":"bullet","start":1,"tag":"ul"},{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"Lastly, we're constantly adding cool new features to this playground. So make sure you check back here when you next get a chance :).","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""},{"children":[{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":3,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":1,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":1,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":1,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":1,"rowSpan":1}],"direction":null,"format":"","indent":0,"type":"tablerow","version":1},{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":2,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1}],"direction":null,"format":"","indent":0,"type":"tablerow","version":1},{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":2,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1}],"direction":null,"format":"","indent":0,"type":"tablerow","version":1},{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":2,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1}],"direction":null,"format":"","indent":0,"type":"tablerow","version":1},{"children":[{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":2,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1},{"children":[{"children":[],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"tablecell","version":1,"backgroundColor":null,"colSpan":1,"headerState":0,"rowSpan":1}],"direction":null,"format":"","indent":0,"type":"tablerow","version":1}],"direction":null,"format":"","indent":0,"type":"table","version":1}],"direction":null,"format":"","indent":0,"type":"root","version":1}}`, ); }); }); diff --git a/resources/js/wysiwyg/lexical/core/nodes/__tests__/unit/LexicalTabNode.test.ts b/resources/js/wysiwyg/lexical/core/nodes/__tests__/unit/LexicalTabNode.test.ts index 2d751f5fd..a57ff3f42 100644 --- a/resources/js/wysiwyg/lexical/core/nodes/__tests__/unit/LexicalTabNode.test.ts +++ b/resources/js/wysiwyg/lexical/core/nodes/__tests__/unit/LexicalTabNode.test.ts @@ -55,7 +55,7 @@ describe('LexicalTabNode tests', () => { $insertDataTransferForPlainText(dataTransfer, selection); }); expect(testEnv.innerHTML).toBe( - '

hello\tworld
hello\tworld

', + '

hello\tworld
hello\tworld

', ); }); @@ -69,7 +69,7 @@ describe('LexicalTabNode tests', () => { $insertDataTransferForRichText(dataTransfer, selection, editor); }); expect(testEnv.innerHTML).toBe( - '

hello\tworld

hello\tworld

', + '

hello\tworld

hello\tworld

', ); }); @@ -89,7 +89,7 @@ describe('LexicalTabNode tests', () => { // $insertDataTransferForRichText(dataTransfer, selection, editor); // }); // expect(testEnv.innerHTML).toBe( - // '

hello\tworld
hello\tworld

', + // '

hello\tworld
hello\tworld

', // ); // }); @@ -99,7 +99,7 @@ describe('LexicalTabNode tests', () => { // GDoc 2-liner hello\tworld (like previous test) dataTransfer.setData( 'text/html', - `

Hello world

Hello world
`, + `

Hello world

Hello world
`, ); await editor.update(() => { const selection = $getSelection(); @@ -107,7 +107,7 @@ describe('LexicalTabNode tests', () => { $insertDataTransferForRichText(dataTransfer, selection, editor); }); expect(testEnv.innerHTML).toBe( - '

Hello\tworld

Hello\tworld

', + '

Hello\tworld

Hello\tworld

', ); }); @@ -121,7 +121,7 @@ describe('LexicalTabNode tests', () => { $getSelection()!.insertText('f'); }); expect(testEnv.innerHTML).toBe( - '

\tf\t

', + '

\tf\t

', ); }); }); diff --git a/resources/js/wysiwyg/lexical/core/shared/reactPatches.ts b/resources/js/wysiwyg/lexical/core/shared/reactPatches.ts deleted file mode 100644 index 9685cd89e..000000000 --- a/resources/js/wysiwyg/lexical/core/shared/reactPatches.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -import React from 'react'; - -// Webpack + React 17 fails to compile on the usage of `React.startTransition` or -// `React["startTransition"]` even if it's behind a feature detection of -// `"startTransition" in React`. Moving this to a constant avoids the issue :/ -const START_TRANSITION = 'startTransition'; - -export function startTransition(callback: () => void) { - if (START_TRANSITION in React) { - React[START_TRANSITION](callback); - } else { - callback(); - } -} diff --git a/resources/js/wysiwyg/lexical/core/shared/useLayoutEffect.ts b/resources/js/wysiwyg/lexical/core/shared/useLayoutEffect.ts deleted file mode 100644 index 6149879cb..000000000 --- a/resources/js/wysiwyg/lexical/core/shared/useLayoutEffect.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -import {useEffect, useLayoutEffect} from 'react'; -import {CAN_USE_DOM} from 'lexical/shared/canUseDOM'; - -// This workaround is no longer necessary in React 19, -// but we currently support React >=17.x -// https://github.com/facebook/react/pull/26395 -const useLayoutEffectImpl: typeof useLayoutEffect = CAN_USE_DOM - ? useLayoutEffect - : useEffect; - -export default useLayoutEffectImpl; diff --git a/resources/js/wysiwyg/lexical/list/__tests__/unit/LexicalListItemNode.test.ts b/resources/js/wysiwyg/lexical/list/__tests__/unit/LexicalListItemNode.test.ts index 22e555f35..581db0294 100644 --- a/resources/js/wysiwyg/lexical/list/__tests__/unit/LexicalListItemNode.test.ts +++ b/resources/js/wysiwyg/lexical/list/__tests__/unit/LexicalListItemNode.test.ts @@ -182,13 +182,13 @@ describe('LexicalListItemNode tests', () => { style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">
    -
  • +
  • one
  • -
  • +
  • two
  • -
  • +
  • three
@@ -215,13 +215,13 @@ describe('LexicalListItemNode tests', () => { style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">
    -
  • +
  • bar
  • -
  • +
  • two
  • -
  • +
  • three
@@ -245,13 +245,13 @@ describe('LexicalListItemNode tests', () => { style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">
    -
  • +
  • one
  • -
  • +
  • two
  • -
  • +
  • three
@@ -273,10 +273,10 @@ describe('LexicalListItemNode tests', () => { data-lexical-editor="true">


    -
  • +
  • two
  • -
  • +
  • three
@@ -301,10 +301,10 @@ describe('LexicalListItemNode tests', () => { style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">
    -
  • +
  • one
  • -
  • +
  • two
@@ -330,13 +330,13 @@ describe('LexicalListItemNode tests', () => { style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">
    -
  • +
  • one


    -
  • +
  • three
@@ -361,7 +361,7 @@ describe('LexicalListItemNode tests', () => { style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">
    -
  • +
  • one
@@ -421,13 +421,13 @@ describe('LexicalListItemNode tests', () => { style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">
    -
  • +
  • A
  • -
  • +
  • x
  • -
  • +
  • B
@@ -445,10 +445,10 @@ describe('LexicalListItemNode tests', () => { style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">
    -
  • +
  • A
  • -
  • +
  • B
@@ -495,15 +495,15 @@ describe('LexicalListItemNode tests', () => {
    • -
    • +
    • A
  • -
  • +
  • x
  • -
  • +
  • B
@@ -523,12 +523,12 @@ describe('LexicalListItemNode tests', () => {
    • -
    • +
    • A
  • -
  • +
  • B
@@ -573,15 +573,15 @@ describe('LexicalListItemNode tests', () => { style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">
    -
  • +
  • A
  • -
  • +
  • x
    • -
    • +
    • B
    @@ -601,12 +601,12 @@ describe('LexicalListItemNode tests', () => { style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">
      -
    • +
    • A
      • -
      • +
      • B
      @@ -659,17 +659,17 @@ describe('LexicalListItemNode tests', () => {
        • -
        • +
        • A
      • -
      • +
      • x
        • -
        • +
        • B
        @@ -691,10 +691,10 @@ describe('LexicalListItemNode tests', () => {
          • -
          • +
          • A
          • -
          • +
          • B
          @@ -755,24 +755,24 @@ describe('LexicalListItemNode tests', () => {
            • -
            • +
            • A1
              • -
              • +
              • A2
          • -
          • +
          • x
            • -
            • +
            • B
            @@ -794,17 +794,17 @@ describe('LexicalListItemNode tests', () => {
              • -
              • +
              • A1
                • -
                • +
                • A2
              • -
              • +
              • B
              @@ -865,24 +865,24 @@ describe('LexicalListItemNode tests', () => {
                • -
                • +
                • A
              • -
              • +
              • x
                  • -
                  • +
                  • B1
                • -
                • +
                • B2
                @@ -904,17 +904,17 @@ describe('LexicalListItemNode tests', () => {
                  • -
                  • +
                  • A
                    • -
                    • +
                    • B1
                  • -
                  • +
                  • B2
                  @@ -983,31 +983,31 @@ describe('LexicalListItemNode tests', () => {
                    • -
                    • +
                    • A1
                      • -
                      • +
                      • A2
                  • -
                  • +
                  • x
                      • -
                      • +
                      • B1
                    • -
                    • +
                    • B2
                    @@ -1029,20 +1029,20 @@ describe('LexicalListItemNode tests', () => {
                      • -
                      • +
                      • A1
                        • -
                        • +
                        • A2
                        • -
                        • +
                        • B1
                      • -
                      • +
                      • B2
                      @@ -1087,13 +1087,13 @@ describe('LexicalListItemNode tests', () => { style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">
                        -
                      • +
                      • one
                      • -
                      • +
                      • two
                      • -
                      • +
                      • three
                      @@ -1117,14 +1117,14 @@ describe('LexicalListItemNode tests', () => { style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">
                        -
                      • +
                      • one

                      • -
                      • +
                      • two
                      • -
                      • +
                      • three
                      @@ -1148,13 +1148,13 @@ describe('LexicalListItemNode tests', () => { style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">
                        -
                      • +
                      • one
                      • -
                      • +
                      • two
                      • -
                      • +
                      • three

                      • @@ -1179,13 +1179,13 @@ describe('LexicalListItemNode tests', () => { style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">
                          -
                        • +
                        • one
                        • -
                        • +
                        • two
                        • -
                        • +
                        • three

                        • @@ -1211,7 +1211,7 @@ describe('LexicalListItemNode tests', () => { style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">
                            -
                          • +
                          • one
                          @@ -1231,7 +1231,7 @@ describe('LexicalListItemNode tests', () => { style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">
                            -
                          • +
                          • one

                          • @@ -1308,7 +1308,7 @@ describe('LexicalListItemNode tests', () => {
                              • -
                              • +
                              • one
                              @@ -1317,7 +1317,7 @@ describe('LexicalListItemNode tests', () => {
                            -
                          • +
                          • two
                          @@ -1336,10 +1336,10 @@ describe('LexicalListItemNode tests', () => { editor.getRootElement()!.innerHTML, html`
                            -
                          • +
                          • one
                          • -
                          • +
                          • two
                          diff --git a/resources/js/wysiwyg/lexical/rich-text/__tests__/unit/LexicalHeadingNode.test.ts b/resources/js/wysiwyg/lexical/rich-text/__tests__/unit/LexicalHeadingNode.test.ts index dcbd62ab3..a94f9ee0b 100644 --- a/resources/js/wysiwyg/lexical/rich-text/__tests__/unit/LexicalHeadingNode.test.ts +++ b/resources/js/wysiwyg/lexical/rich-text/__tests__/unit/LexicalHeadingNode.test.ts @@ -117,7 +117,7 @@ describe('LexicalHeadingNode tests', () => { headingTextNode.select(5, 5); }); expect(testEnv.outerHTML).toBe( - '

                          hello world

                          ', + '

                          hello world

                          ', ); await editor.update(() => { const selection = $getSelection() as RangeSelection; @@ -126,7 +126,7 @@ describe('LexicalHeadingNode tests', () => { expect(result.getDirection()).toEqual(headingNode.getDirection()); }); expect(testEnv.outerHTML).toBe( - '

                          hello world


                          ', + '

                          hello world


                          ', ); }); @@ -143,7 +143,7 @@ describe('LexicalHeadingNode tests', () => { headingTextNode2.selectEnd(); }); expect(testEnv.outerHTML).toBe( - '

                          hello world

                          ', + '

                          hello world

                          ', ); await editor.update(() => { const selection = $getSelection() as RangeSelection; @@ -152,7 +152,7 @@ describe('LexicalHeadingNode tests', () => { expect(result.getDirection()).toEqual(headingNode.getDirection()); }); expect(testEnv.outerHTML).toBe( - '

                          hello world


                          ', + '

                          hello world


                          ', ); }); @@ -187,7 +187,7 @@ describe('LexicalHeadingNode tests', () => { headingNode.append(textNode); }); expect(testEnv.outerHTML).toBe( - `

                          ${text}

                          `, + `

                          ${text}

                          `, ); await editor.update(() => { const result = headingNode.insertNewAfter(); @@ -195,7 +195,7 @@ describe('LexicalHeadingNode tests', () => { expect(result.getDirection()).toEqual(headingNode.getDirection()); }); expect(testEnv.outerHTML).toBe( - `

                          ${text}


                          `, + `

                          ${text}


                          `, ); }); }); diff --git a/resources/js/wysiwyg/lexical/selection/__tests__/unit/LexicalSelection.test.ts b/resources/js/wysiwyg/lexical/selection/__tests__/unit/LexicalSelection.test.ts index 665f5d854..5f2d9dcc0 100644 --- a/resources/js/wysiwyg/lexical/selection/__tests__/unit/LexicalSelection.test.ts +++ b/resources/js/wysiwyg/lexical/selection/__tests__/unit/LexicalSelection.test.ts @@ -250,7 +250,7 @@ describe('LexicalSelection tests', () => { const suite = [ { expectedHTML: - '

                          Hello

                          ', + '

                          Hello

                          ', expectedSelection: { anchorOffset: 5, anchorPath: [0, 0, 0], @@ -268,7 +268,7 @@ describe('LexicalSelection tests', () => { }, { expectedHTML: - '

                          ' + + '

                          ' + 'Hello

                          ', expectedSelection: { anchorOffset: 5, @@ -288,7 +288,7 @@ describe('LexicalSelection tests', () => { }, { expectedHTML: - '

                          ' + + '

                          ' + 'Hello

                          ', expectedSelection: { anchorOffset: 5, @@ -308,7 +308,7 @@ describe('LexicalSelection tests', () => { }, { expectedHTML: - '

                          ' + + '

                          ' + 'Hello

                          ', expectedSelection: { anchorOffset: 5, @@ -329,7 +329,7 @@ describe('LexicalSelection tests', () => { }, { expectedHTML: - '

                          ' + + '

                          ' + 'Hello

                          ', expectedSelection: { anchorOffset: 5, @@ -349,7 +349,7 @@ describe('LexicalSelection tests', () => { }, { expectedHTML: - '

                          ' + + '

                          ' + 'Hello

                          ', expectedSelection: { anchorOffset: 5, @@ -369,7 +369,7 @@ describe('LexicalSelection tests', () => { }, { expectedHTML: - '

                          ' + + '

                          ' + 'Hello

                          ', expectedSelection: { anchorOffset: 5, @@ -411,7 +411,7 @@ describe('LexicalSelection tests', () => { }, { expectedHTML: - '

                          ' + + '

                          ' + 'Dominic Gannaway' + '

                          ', expectedSelection: { @@ -425,7 +425,7 @@ describe('LexicalSelection tests', () => { }, { expectedHTML: - '

                          ' + + '

                          ' + 'Dominic Gannaway' + '

                          ', expectedSelection: { @@ -443,7 +443,7 @@ describe('LexicalSelection tests', () => { }, { expectedHTML: - '

                          ' + + '

                          ' + 'Dominic Gannaway' + '

                          ', expectedSelection: { @@ -457,7 +457,7 @@ describe('LexicalSelection tests', () => { }, { expectedHTML: - '

                          ' + + '

                          ' + 'Dominic Gannaway' + '

                          ', expectedSelection: { @@ -477,7 +477,7 @@ describe('LexicalSelection tests', () => { expectedHTML: '
                          ' + '


                          ' + - '

                          ' + + '

                          ' + 'Hello world' + '

                          ' + '


                          ' + @@ -501,10 +501,10 @@ describe('LexicalSelection tests', () => { expectedHTML: '
                          ' + '


                          ' + - '

                          ' + + '

                          ' + 'Hello' + '

                          ' + - '

                          ' + + '

                          ' + 'world' + '

                          ' + '


                          ' + @@ -529,11 +529,11 @@ describe('LexicalSelection tests', () => { { expectedHTML: '
                          ' + - '

                          ' + + '

                          ' + 'He' + 'llo' + '

                          ' + - '

                          ' + + '

                          ' + 'wo' + 'rld' + '

                          ' + @@ -557,7 +557,7 @@ describe('LexicalSelection tests', () => { expectedHTML: '
                          ' + '


                          ' + - '

                          ' + + '

                          ' + 'Hello ' + 'world' + '

                          ' + @@ -582,7 +582,7 @@ describe('LexicalSelection tests', () => { expectedHTML: '
                          ' + '


                          ' + - '

                          ' + + '

                          ' + 'Hello' + ' world' + '

                          ' + @@ -608,7 +608,7 @@ describe('LexicalSelection tests', () => { expectedHTML: '
                          ' + '


                          ' + - '

                          ' + + '

                          ' + 'Hello world' + '

                          ' + '


                          ' + @@ -634,7 +634,7 @@ describe('LexicalSelection tests', () => { expectedHTML: '
                          ' + '


                          ' + - '

                          ' + + '

                          ' + 'Hello world' + '

                          ' + '


                          ' + @@ -660,7 +660,7 @@ describe('LexicalSelection tests', () => { expectedHTML: '
                          ' + '


                          ' + - '

                          ' + + '

                          ' + 'Hello world' + '

                          ' + '


                          ' + @@ -686,7 +686,7 @@ describe('LexicalSelection tests', () => { expectedHTML: '
                          ' + '


                          ' + - '

                          ' + + '

                          ' + 'Hello beautiful world' + '

                          ' + '


                          ' + @@ -764,7 +764,7 @@ describe('LexicalSelection tests', () => { }, ].flatMap(({whitespaceCharacter, whitespaceName}) => [ { - expectedHTML: `

                          Hello${printWhitespace( + expectedHTML: `

                          Hello${printWhitespace( whitespaceCharacter, )}

                          `, expectedSelection: { @@ -780,7 +780,7 @@ describe('LexicalSelection tests', () => { name: `Type two words separated by a ${whitespaceName}, delete word backward from end`, }, { - expectedHTML: `

                          ${printWhitespace( + expectedHTML: `

                          ${printWhitespace( whitespaceCharacter, )}world

                          `, expectedSelection: { @@ -798,7 +798,7 @@ describe('LexicalSelection tests', () => { }, { expectedHTML: - '

                          Hello

                          ', + '

                          Hello

                          ', expectedSelection: { anchorOffset: 5, anchorPath: [0, 0, 0], @@ -814,7 +814,7 @@ describe('LexicalSelection tests', () => { }, { expectedHTML: - '

                          world

                          ', + '

                          world

                          ', expectedSelection: { anchorOffset: 0, anchorPath: [0, 0, 0], @@ -830,7 +830,7 @@ describe('LexicalSelection tests', () => { }, { expectedHTML: - '

                          Hello world

                          ', + '

                          Hello world

                          ', expectedSelection: { anchorOffset: 11, anchorPath: [0, 0, 0], @@ -842,7 +842,7 @@ describe('LexicalSelection tests', () => { }, { expectedHTML: - '

                          Hello

                          ', + '

                          Hello

                          ', expectedSelection: { anchorOffset: 6, anchorPath: [0, 0, 0], @@ -859,7 +859,7 @@ describe('LexicalSelection tests', () => { }, { expectedHTML: - '

                          ' + + '

                          ' + 'this is weird test

                          ', expectedSelection: { anchorOffset: 0, @@ -876,7 +876,7 @@ describe('LexicalSelection tests', () => { }, { expectedHTML: - '

                          ' + + '

                          ' + 'Hello ' + 'Bob' + '

                          ', @@ -897,7 +897,7 @@ describe('LexicalSelection tests', () => { }, { expectedHTML: - '

                          ABD\tEFG

                          ', + '

                          ABD\tEFG

                          ', expectedSelection: { anchorOffset: 3, anchorPath: [0, 0, 0], @@ -1883,7 +1883,7 @@ describe('LexicalSelection tests', () => { }); expect(element.innerHTML).toBe( - '

                          Hello awesome

                          world

                          ', + '

                          Hello awesome

                          world

                          ', ); }); @@ -1931,7 +1931,7 @@ describe('LexicalSelection tests', () => { }); expect(element.innerHTML).toBe( - '

                          Hello awesome

                          beautiful world

                          ', + '

                          Hello awesome

                          beautiful world

                          ', ); }); diff --git a/resources/js/wysiwyg/lexical/selection/__tests__/unit/LexicalSelectionHelpers.test.ts b/resources/js/wysiwyg/lexical/selection/__tests__/unit/LexicalSelectionHelpers.test.ts index 7b5bef451..4d88bde0e 100644 --- a/resources/js/wysiwyg/lexical/selection/__tests__/unit/LexicalSelectionHelpers.test.ts +++ b/resources/js/wysiwyg/lexical/selection/__tests__/unit/LexicalSelectionHelpers.test.ts @@ -1827,7 +1827,7 @@ describe('LexicalSelectionHelpers tests', () => { }); expect(element.innerHTML).toBe( - '

                          foo

                          ', + '

                          foo

                          ', ); }); @@ -1868,7 +1868,7 @@ describe('LexicalSelectionHelpers tests', () => { }); expect(element.innerHTML).toBe( - '

                          foobar

                          ', + '

                          foobar

                          ', ); }); @@ -1913,7 +1913,7 @@ describe('LexicalSelectionHelpers tests', () => { }); expect(element.innerHTML).toBe( - '

                          hello world

                          ', + '

                          hello world

                          ', ); }); @@ -1956,7 +1956,7 @@ describe('LexicalSelectionHelpers tests', () => { }); expect(element.innerHTML).toBe( - '

                          foo

                          ', + '

                          foo

                          ', ); }); }); @@ -1999,7 +1999,7 @@ describe('LexicalSelectionHelpers tests', () => { }); expect(element.innerHTML).toBe( - '

                          Existing text...foo

                          ', + '

                          Existing text...foo

                          ', ); }); @@ -2044,7 +2044,7 @@ describe('LexicalSelectionHelpers tests', () => { }); expect(element.innerHTML).toBe( - '

                          Existing text...foobar

                          ', + '

                          Existing text...foobar

                          ', ); }); @@ -2091,7 +2091,7 @@ describe('LexicalSelectionHelpers tests', () => { }); expect(element.innerHTML).toBe( - '

                          Existing text...foo

                          ', + '

                          Existing text...foo

                          ', ); }); @@ -2162,7 +2162,7 @@ describe('LexicalSelectionHelpers tests', () => { }); expect(element.innerHTML).toBe( - '

                          ABCDE

                          ', + '

                          ABCDE

                          ', ); }); }); @@ -2205,7 +2205,7 @@ describe('LexicalSelectionHelpers tests', () => { }); expect(element.innerHTML).toBe( - '

                          foo

                          ', + '

                          foo

                          ', ); }); }); @@ -2252,7 +2252,7 @@ describe('LexicalSelectionHelpers tests', () => { }); expect(element.innerHTML).toBe( - '

                          foolink

                          ', + '

                          foolink

                          ', ); }); }); @@ -2299,7 +2299,7 @@ describe('LexicalSelectionHelpers tests', () => { }); expect(element.innerHTML).toBe( - '

                          linkfoo

                          ', + '

                          linkfoo

                          ', ); }); }); @@ -2324,7 +2324,7 @@ describe('LexicalSelectionHelpers tests', () => { // TODO #5109 ElementNode should have a way to control when other nodes can be inserted inside expect(element.innerHTML).toBe( - '


                          Lexical

                          ', + '


                          Lexical

                          ', ); }); }); @@ -2371,7 +2371,7 @@ describe('LexicalSelectionHelpers tests', () => { }); expect(element.innerHTML).toBe( - '

                          foo

                          ', + '

                          foo

                          ', ); }); }); @@ -2421,7 +2421,7 @@ describe('LexicalSelectionHelpers tests', () => { }); expect(element.innerHTML).toBe( - '

                          foolink

                          ', + '

                          foolink

                          ', ); }); }); @@ -2471,7 +2471,7 @@ describe('LexicalSelectionHelpers tests', () => { }); expect(element.innerHTML).toBe( - '

                          linkfoo

                          ', + '

                          linkfoo

                          ', ); }); }); @@ -2491,7 +2491,7 @@ describe('LexicalSelectionHelpers tests', () => { $insertNodes([linkNode]); }); expect(element.innerHTML).toBe( - '

                          Lexical

                          ', + '

                          Lexical

                          ', ); }); @@ -2511,7 +2511,7 @@ describe('LexicalSelectionHelpers tests', () => { $insertNodes([linkNode, textNode2]); }); expect(element.innerHTML).toBe( - '

                          Lexical...

                          ', + '

                          Lexical...

                          ', ); }); @@ -2604,9 +2604,9 @@ describe('insertNodes', () => { }); expect(element.innerHTML).toBe( - '

                          Text before

                          ' + + '

                          Text before

                          ' + '' + - '

                          Text after

                          ', + '

                          Text after

                          ', ); }); @@ -2678,7 +2678,7 @@ describe('insertNodes', () => { }); editor.getEditorState().read(() => { expect(element.innerHTML).toBe( - '

                          heading


                          ', + '

                          heading


                          ', ); const selectedNode = ($getSelection() as RangeSelection).anchor.getNode(); expect($isParagraphNode(selectedNode)).toBeTruthy(); @@ -2736,8 +2736,8 @@ describe('$patchStyleText', () => { }); expect(element.innerHTML).toBe( - '

                          a' + - '' + + '

                          a' + + '' + 'link' + '' + 'b

                          ', @@ -2789,8 +2789,8 @@ describe('$patchStyleText', () => { }); expect(element.innerHTML).toBe( - '

                          a

                          ' + - '

                          b

                          ', + '

                          a

                          ' + + '

                          b

                          ', ); }); @@ -2838,9 +2838,9 @@ describe('$patchStyleText', () => { }); expect(element.innerHTML).toBe( - '

                          ' + + '

                          ' + 'a' + - '' + + '' + 'link' + '' + '

                          ', @@ -2891,9 +2891,9 @@ describe('$patchStyleText', () => { }); expect(element.innerHTML).toBe( - '

                          ' + + '

                          ' + 'a' + - '' + + '' + 'link' + '' + '

                          ', @@ -2935,7 +2935,7 @@ describe('$patchStyleText', () => { expect(element.innerHTML).toBe( '

                          ' + - '' + + '' + 'link' + '' + '

                          ', @@ -2976,7 +2976,7 @@ describe('$patchStyleText', () => { }); expect(element.innerHTML).toBe( - '

                          text

                          ', + '

                          text

                          ', ); }); @@ -3115,7 +3115,7 @@ describe('$patchStyleText', () => { }); expect(element.innerHTML).toBe( - '

                          ' + + '

                          ' + 'fir' + 'st' + 'second' + diff --git a/resources/js/wysiwyg/lexical/table/__tests__/unit/LexicalTableNode.test.ts b/resources/js/wysiwyg/lexical/table/__tests__/unit/LexicalTableNode.test.ts index 6ce133d18..abc509629 100644 --- a/resources/js/wysiwyg/lexical/table/__tests__/unit/LexicalTableNode.test.ts +++ b/resources/js/wysiwyg/lexical/table/__tests__/unit/LexicalTableNode.test.ts @@ -102,7 +102,7 @@ describe('LexicalTableNode tests', () => { const dataTransfer = new DataTransferMock(); dataTransfer.setData( 'text/html', - '

                          Hello there

                          General Kenobi!

                          Lexical is nice


                          ', + '

                          Hello there

                          General Kenobi!

                          Lexical is nice


                          ', ); await editor.update(() => { const selection = $getSelection(); @@ -115,7 +115,7 @@ describe('LexicalTableNode tests', () => { // Make sure paragraph is inserted inside empty cells const emptyCell = '


                          '; expect(testEnv.innerHTML).toBe( - `${emptyCell}

                          Hello there

                          General Kenobi!

                          Lexical is nice

                          `, + `${emptyCell}

                          Hello there

                          General Kenobi!

                          Lexical is nice

                          `, ); }); @@ -125,7 +125,7 @@ describe('LexicalTableNode tests', () => { const dataTransfer = new DataTransferMock(); dataTransfer.setData( 'text/html', - '
                          SurfaceMWP_WORK_LS_COMPOSER77349
                          LexicalXDS_RICH_TEXT_AREAsdvd sdfvsfs
                          ', + '
                          SurfaceMWP_WORK_LS_COMPOSER77349
                          LexicalXDS_RICH_TEXT_AREAsdvd sdfvsfs
                          ', ); await editor.update(() => { const selection = $getSelection(); @@ -136,7 +136,7 @@ describe('LexicalTableNode tests', () => { $insertDataTransferForRichText(dataTransfer, selection, editor); }); expect(testEnv.innerHTML).toBe( - `

                          Surface

                          MWP_WORK_LS_COMPOSER

                          77349

                          Lexical

                          XDS_RICH_TEXT_AREA

                          sdvd sdfvsfs

                          `, + `

                          Surface

                          MWP_WORK_LS_COMPOSER

                          77349

                          Lexical

                          XDS_RICH_TEXT_AREA

                          sdvd sdfvsfs

                          `, ); }); }, diff --git a/resources/js/wysiwyg/lexical/table/__tests__/unit/LexicalTableSelection.test.ts b/resources/js/wysiwyg/lexical/table/__tests__/unit/LexicalTableSelection.test.ts index 35ee65b68..d5b85ccaa 100644 --- a/resources/js/wysiwyg/lexical/table/__tests__/unit/LexicalTableSelection.test.ts +++ b/resources/js/wysiwyg/lexical/table/__tests__/unit/LexicalTableSelection.test.ts @@ -99,7 +99,7 @@ describe('table selection', () => { it('Parses the nodes of a stringified editor state', async () => { expect(parsedRoot).toEqual({ __cachedText: null, - __dir: 'ltr', + __dir: null, __first: paragraphKey, __format: 0, __indent: 0, @@ -113,7 +113,7 @@ describe('table selection', () => { __type: 'root', }); expect(parsedParagraph).toEqual({ - __dir: 'ltr', + __dir: null, __first: textKey, __format: 0, __indent: 0, diff --git a/resources/js/wysiwyg/lexical/utils/__tests__/unit/LexicalEventHelpers.test.ts b/resources/js/wysiwyg/lexical/utils/__tests__/unit/LexicalEventHelpers.test.ts index 53c743df6..7655b4540 100644 --- a/resources/js/wysiwyg/lexical/utils/__tests__/unit/LexicalEventHelpers.test.ts +++ b/resources/js/wysiwyg/lexical/utils/__tests__/unit/LexicalEventHelpers.test.ts @@ -156,25 +156,25 @@ describe('LexicalEventHelpers', () => { const suite = [ { expectedHTML: - '

                          Hello

                          ', + '

                          Hello

                          ', inputs: [pasteHTML(`

                          Hello

                          `)], name: 'should produce the correct editor state from a pasted HTML h1 element', }, { expectedHTML: - '

                          From

                          ', + '

                          From

                          ', inputs: [pasteHTML(`

                          From

                          `)], name: 'should produce the correct editor state from a pasted HTML h2 element', }, { expectedHTML: - '

                          The

                          ', + '

                          The

                          ', inputs: [pasteHTML(`

                          The

                          `)], name: 'should produce the correct editor state from a pasted HTML h3 element', }, { expectedHTML: - '
                          • Other side
                          • I must have called
                          ', + '
                          • Other side
                          • I must have called
                          ', inputs: [ pasteHTML( `
                          • Other side
                          • I must have called
                          `, @@ -184,7 +184,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '
                          1. To tell you
                          2. I’m sorry
                          ', + '
                          1. To tell you
                          2. I’m sorry
                          ', inputs: [ pasteHTML( `
                          1. To tell you
                          2. I’m sorry
                          `, @@ -194,37 +194,37 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          A thousand times

                          ', + '

                          A thousand times

                          ', inputs: [pasteHTML(`A thousand times`)], name: 'should produce the correct editor state from pasted DOM Text Node', }, { expectedHTML: - '

                          Bold

                          ', + '

                          Bold

                          ', inputs: [pasteHTML(`Bold`)], name: 'should produce the correct editor state from a pasted HTML b element', }, { expectedHTML: - '

                          Italic

                          ', + '

                          Italic

                          ', inputs: [pasteHTML(`Italic`)], name: 'should produce the correct editor state from a pasted HTML i element', }, { expectedHTML: - '

                          Italic

                          ', + '

                          Italic

                          ', inputs: [pasteHTML(`Italic`)], name: 'should produce the correct editor state from a pasted HTML em element', }, { expectedHTML: - '

                          Underline

                          ', + '

                          Underline

                          ', inputs: [pasteHTML(`Underline`)], name: 'should produce the correct editor state from a pasted HTML u element', }, { expectedHTML: - '

                          Lyrics to Hello by Adele

                          A thousand times

                          ', + '

                          Lyrics to Hello by Adele

                          A thousand times

                          ', inputs: [ pasteHTML( `

                          Lyrics to Hello by Adele

                          A thousand times`, @@ -234,7 +234,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '', + '', inputs: [ pasteHTML( `Facebook`, @@ -244,7 +244,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          Welcome toFacebook!

                          ', + '

                          Welcome toFacebook!

                          ', inputs: [ pasteHTML( `Welcome toFacebook!`, @@ -254,7 +254,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          Welcome toFacebook!We hope you like it here.

                          ', + '

                          Welcome toFacebook!We hope you like it here.

                          ', inputs: [ pasteHTML( `Welcome toFacebook!We hope you like it here.`, @@ -264,7 +264,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '
                          • Hello
                          • from the other
                          • side
                          ', + '
                          • Hello
                          • from the other
                          • side
                          ', inputs: [ pasteHTML( `
                          • Hello
                          • from the other
                          • side
                          `, @@ -274,7 +274,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '
                          • Hello
                          • from the other
                          • side
                          ', + '
                          • Hello
                          • from the other
                          • side
                          ', inputs: [ pasteHTML( `
                          • Hello
                          • from the other
                          • side
                          `, @@ -284,7 +284,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          Welcome toFacebook!We hope you like it here.

                          ', + '

                          Welcome toFacebook!We hope you like it here.

                          ', inputs: [ pasteHTML( `Welcome toFacebook!We hope you like it here.`, @@ -294,7 +294,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          Welcome toFacebook!We hope you like it here.

                          ', + '

                          Welcome toFacebook!We hope you like it here.

                          ', inputs: [ pasteHTML( `Welcome toFacebook!We hope you like it here.`, @@ -304,7 +304,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          Welcome toFacebook!We hope you like it here.

                          ', + '

                          Welcome toFacebook!We hope you like it here.

                          ', inputs: [ pasteHTML( `Welcome toFacebook!We hope you like it here.`, @@ -330,7 +330,7 @@ describe('LexicalEventHelpers', () => { const suite = [ { expectedHTML: - '

                          Get schwifty!

                          ', + '

                          Get schwifty!

                          ', inputs: [ pasteHTML( `Get schwifty!`, @@ -340,7 +340,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          Get schwifty!

                          ', + '

                          Get schwifty!

                          ', inputs: [ pasteHTML( `Get schwifty!`, @@ -350,7 +350,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          Get schwifty!

                          ', + '

                          Get schwifty!

                          ', inputs: [ pasteHTML( `Get schwifty!`, @@ -360,7 +360,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          Get schwifty!

                          ', + '

                          Get schwifty!

                          ', inputs: [ pasteHTML( `Get schwifty!`, @@ -386,20 +386,20 @@ describe('LexicalEventHelpers', () => { const suite = [ { expectedHTML: - '

                          hello world

                          ', + '

                          hello world

                          ', inputs: [pasteHTML('hello world')], name: 'inline hello world', }, { expectedHTML: - '

                          hello world

                          ', + '

                          hello world

                          ', inputs: [pasteHTML(' hello world ')], name: 'inline hello world (2)', }, { // MS Office got it right expectedHTML: - '

                          hello world

                          ', + '

                          hello world

                          ', inputs: [ pasteHTML(' hello world '), ], @@ -407,19 +407,19 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          a b\tc

                          ', + '

                          a b\tc

                          ', inputs: [pasteHTML('

                          a b\tc

                          ')], name: 'white-space: pre (1) (no touchy)', }, { expectedHTML: - '

                          a b c

                          ', + '

                          a b c

                          ', inputs: [pasteHTML('

                          \ta\tb c\t\t

                          ')], name: 'tabs are collapsed', }, { expectedHTML: - '

                          hello world

                          ', + '

                          hello world

                          ', inputs: [ pasteHTML(`
                          @@ -432,7 +432,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          hello world

                          ', + '

                          hello world

                          ', inputs: [ pasteHTML(`
                          @@ -447,7 +447,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          a b c

                          ', + '

                          a b c

                          ', inputs: [ pasteHTML(`
                          @@ -461,25 +461,25 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          a b

                          ', + '

                          a b

                          ', inputs: [pasteHTML('
                          a b
                          ')], name: 'collapsibles and neighbors (1)', }, { expectedHTML: - '

                          a b

                          ', + '

                          a b

                          ', inputs: [pasteHTML('
                          a b
                          ')], name: 'collapsibles and neighbors (2)', }, { expectedHTML: - '

                          a b

                          ', + '

                          a b

                          ', inputs: [pasteHTML('
                          a b
                          ')], name: 'collapsibles and neighbors (3)', }, { expectedHTML: - '

                          a b

                          ', + '

                          a b

                          ', inputs: [pasteHTML('
                          a b
                          ')], name: 'collapsibles and neighbors (4)', }, @@ -495,19 +495,19 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          a

                          ', + '

                          a

                          ', inputs: [pasteHTML(' a')], name: 'redundant inline at start', }, { expectedHTML: - '

                          a

                          ', + '

                          a

                          ', inputs: [pasteHTML('a ')], name: 'redundant inline at end', }, { expectedHTML: - '

                          a

                          b

                          ', + '

                          a

                          b

                          ', inputs: [ pasteHTML(`
                          @@ -524,7 +524,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          a b

                          ', + '

                          a b

                          ', inputs: [ pasteHTML(`
                          @@ -541,7 +541,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          a
                          b

                          ', + '

                          a
                          b

                          ', inputs: [ pasteHTML(`

                          @@ -555,7 +555,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          a
                          b

                          ', + '

                          a
                          b

                          ', inputs: [ pasteHTML(`

                          @@ -569,7 +569,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          paragraph1

                          paragraph2

                          ', + '

                          paragraph1

                          paragraph2

                          ', inputs: [ pasteHTML( '\n

                          paragraph1

                          \n

                          paragraph2

                          \n', @@ -579,7 +579,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          line 1
                          line 2


                          paragraph 1

                          paragraph 2

                          ', + '

                          line 1
                          line 2


                          paragraph 1

                          paragraph 2

                          ', inputs: [ pasteHTML( '\n

                          line 1
                          \nline 2

                          \n


                          \n

                          paragraph 1

                          \n

                          paragraph 2

                          \n', @@ -589,7 +589,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          line 1
                          line 2


                          paragraph 1

                          paragraph 2

                          ', + '

                          line 1
                          line 2


                          paragraph 1

                          paragraph 2

                          ', inputs: [ pasteHTML( '\n

                          line 1
                          \nline 2

                          \n

                          \n
                          \n

                          \n

                          paragraph 1

                          \n

                          paragraph 2

                          \n', @@ -599,7 +599,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          line 1
                          line 2

                          ', + '

                          line 1
                          line 2

                          ', inputs: [ pasteHTML( '

                          line 1
                          line 2

                          ', @@ -635,7 +635,7 @@ describe('LexicalEventHelpers', () => { }, { expectedHTML: - '

                          a

                          b b

                          c

                          z

                          d e

                          fg

                          ', + '

                          a

                          b b

                          c

                          z

                          d e

                          fg

                          ', inputs: [ pasteHTML( `
                          a
                          b b
                          c
                          z
                          d e
                          fg
                          `, diff --git a/resources/js/wysiwyg/nodes/_common.ts b/resources/js/wysiwyg/nodes/_common.ts index 8a0475c7b..36e692f25 100644 --- a/resources/js/wysiwyg/nodes/_common.ts +++ b/resources/js/wysiwyg/nodes/_common.ts @@ -1,10 +1,12 @@ import {LexicalNode, Spread} from "lexical"; import type {SerializedElementNode} from "lexical/nodes/LexicalElementNode"; -import {sizeToPixels} from "../utils/dom"; +import {el, sizeToPixels} from "../utils/dom"; export type CommonBlockAlignment = 'left' | 'right' | 'center' | 'justify' | ''; const validAlignments: CommonBlockAlignment[] = ['left', 'right', 'center', 'justify']; +type EditorNodeDirection = 'ltr' | 'rtl' | null; + export type SerializedCommonBlockNode = Spread<{ id: string; alignment: CommonBlockAlignment; @@ -29,7 +31,13 @@ export interface NodeHasInset { getInset(): number; } -interface CommonBlockInterface extends NodeHasId, NodeHasAlignment, NodeHasInset {} +export interface NodeHasDirection { + readonly __dir: EditorNodeDirection; + setDirection(direction: EditorNodeDirection): void; + getDirection(): EditorNodeDirection; +} + +interface CommonBlockInterface extends NodeHasId, NodeHasAlignment, NodeHasInset, NodeHasDirection {} export function extractAlignmentFromElement(element: HTMLElement): CommonBlockAlignment { const textAlignStyle: string = element.style.textAlign || ''; @@ -55,6 +63,15 @@ export function extractInsetFromElement(element: HTMLElement): number { return sizeToPixels(elemPadding); } +function extractDirectionFromElement(element: HTMLElement): EditorNodeDirection { + const elemDir = (element.dir || '').toLowerCase(); + if (elemDir === 'rtl' || elemDir === 'ltr') { + return elemDir; + } + + return null; +} + export function setCommonBlockPropsFromElement(element: HTMLElement, node: CommonBlockInterface): void { if (element.id) { node.setId(element.id); @@ -62,12 +79,14 @@ export function setCommonBlockPropsFromElement(element: HTMLElement, node: Commo node.setAlignment(extractAlignmentFromElement(element)); node.setInset(extractInsetFromElement(element)); + node.setDirection(extractDirectionFromElement(element)); } export function commonPropertiesDifferent(nodeA: CommonBlockInterface, nodeB: CommonBlockInterface): boolean { return nodeA.__id !== nodeB.__id || nodeA.__alignment !== nodeB.__alignment || - nodeA.__inset !== nodeB.__inset; + nodeA.__inset !== nodeB.__inset || + nodeA.__dir !== nodeB.__dir; } export function updateElementWithCommonBlockProps(element: HTMLElement, node: CommonBlockInterface): void { @@ -82,12 +101,17 @@ export function updateElementWithCommonBlockProps(element: HTMLElement, node: Co if (node.__inset) { element.style.paddingLeft = `${node.__inset}px`; } + + if (node.__dir) { + element.dir = node.__dir; + } } export function deserializeCommonBlockNode(serializedNode: SerializedCommonBlockNode, node: CommonBlockInterface): void { node.setId(serializedNode.id); node.setAlignment(serializedNode.alignment); node.setInset(serializedNode.inset); + node.setDirection(serializedNode.direction); } export interface NodeHasSize { diff --git a/resources/js/wysiwyg/todo.md b/resources/js/wysiwyg/todo.md index 874ac537f..e07792a1c 100644 --- a/resources/js/wysiwyg/todo.md +++ b/resources/js/wysiwyg/todo.md @@ -3,6 +3,10 @@ ## In progress - RTL/LTR support + - Basic implementation added + - Test across main range of content blocks + - Test that HTML is being set as expected + - Test editor defaults when between RTL/LTR modes ## Main Todo diff --git a/resources/js/wysiwyg/ui/defaults/buttons/alignments.ts b/resources/js/wysiwyg/ui/defaults/buttons/alignments.ts index 130fd6b72..b1c701dda 100644 --- a/resources/js/wysiwyg/ui/defaults/buttons/alignments.ts +++ b/resources/js/wysiwyg/ui/defaults/buttons/alignments.ts @@ -37,14 +37,15 @@ function setAlignmentForSelection(editor: LexicalEditor, alignment: CommonBlockA $toggleSelection(editor); } -function setDirectionForSelection(editor: LexicalEditor, direction: 'ltr' | 'rtl'): void { - const selection = getLastSelection(editor); +function setDirectionForSelection(context: EditorUiContext, direction: 'ltr' | 'rtl'): void { + const selection = getLastSelection(context.editor); const elements = $getBlockElementNodesInSelection(selection); for (const node of elements) { - console.log('setting direction', node); node.setDirection(direction); } + + context.manager.triggerFutureStateRefresh(); } export const alignLeft: EditorButtonDefinition = { @@ -95,7 +96,7 @@ export const directionLTR: EditorButtonDefinition = { label: 'Left to right', icon: ltrIcon, action(context: EditorUiContext) { - context.editor.update(() => setDirectionForSelection(context.editor, 'ltr')); + context.editor.update(() => setDirectionForSelection(context, 'ltr')); }, isActive(selection: BaseSelection|null) { return $selectionContainsDirection(selection, 'ltr'); @@ -106,7 +107,7 @@ export const directionRTL: EditorButtonDefinition = { label: 'Right to left', icon: rtlIcon, action(context: EditorUiContext) { - context.editor.update(() => setDirectionForSelection(context.editor, 'rtl')); + context.editor.update(() => setDirectionForSelection(context, 'rtl')); }, isActive(selection: BaseSelection|null) { return $selectionContainsDirection(selection, 'rtl'); diff --git a/resources/js/wysiwyg/ui/defaults/buttons/lists.ts b/resources/js/wysiwyg/ui/defaults/buttons/lists.ts index 87630eb27..9cfa8168e 100644 --- a/resources/js/wysiwyg/ui/defaults/buttons/lists.ts +++ b/resources/js/wysiwyg/ui/defaults/buttons/lists.ts @@ -3,7 +3,6 @@ import {EditorButtonDefinition} from "../../framework/buttons"; import {EditorUiContext} from "../../framework/core"; import { BaseSelection, - LexicalEditor, LexicalNode, } from "lexical"; import listBulletIcon from "@icons/editor/list-bullet.svg"; @@ -12,15 +11,10 @@ import listCheckIcon from "@icons/editor/list-check.svg"; import indentIncreaseIcon from "@icons/editor/indent-increase.svg"; import indentDecreaseIcon from "@icons/editor/indent-decrease.svg"; import { - $getBlockElementNodesInSelection, - $selectionContainsNodeType, $selectNodes, $selectSingleNode, - $toggleSelection, - getLastSelection + $selectionContainsNodeType, } from "../../../utils/selection"; import {toggleSelectionAsList} from "../../../utils/formats"; -import {nodeHasInset} from "../../../utils/nodes"; -import {$isCustomListItemNode, CustomListItemNode} from "../../../nodes/custom-list-item"; -import {$nestListItem, $setInsetForSelection, $unnestListItem} from "../../../utils/lists"; +import {$setInsetForSelection} from "../../../utils/lists"; function buildListButton(label: string, type: ListType, icon: string): EditorButtonDefinition { diff --git a/tsconfig.json b/tsconfig.json index 4026872ac..8bffc25f8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,6 @@ { "include": ["resources/js/**/*"], + "exclude": ["resources/js/wysiwyg/lexical/yjs/*"], "compilerOptions": { "target": "es2019", "module": "commonjs",