Lexical: Removed reconciler level direction handling

- Updated tests to consider changes
This commit is contained in:
Dan Brown 2024-09-21 13:00:16 +01:00
parent dba8ab947f
commit 654a7a5d03
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
22 changed files with 329 additions and 459 deletions

View File

@ -42,14 +42,12 @@ import {
$textContentRequiresDoubleLinebreakAtEnd, $textContentRequiresDoubleLinebreakAtEnd,
cloneDecorators, cloneDecorators,
getElementByKeyOrThrow, getElementByKeyOrThrow,
getTextDirection,
setMutatedNode, setMutatedNode,
} from './LexicalUtils'; } from './LexicalUtils';
type IntentionallyMarkedAsDirtyElement = boolean; type IntentionallyMarkedAsDirtyElement = boolean;
let subTreeTextContent = ''; let subTreeTextContent = '';
let subTreeDirectionedTextContent = '';
let subTreeTextFormat: number | null = null; let subTreeTextFormat: number | null = null;
let subTreeTextStyle: string = ''; let subTreeTextStyle: string = '';
let editorTextContent = ''; let editorTextContent = '';
@ -59,7 +57,6 @@ let activeEditorNodes: RegisteredNodes;
let treatAllNodesAsDirty = false; let treatAllNodesAsDirty = false;
let activeEditorStateReadOnly = false; let activeEditorStateReadOnly = false;
let activeMutationListeners: MutationListeners; let activeMutationListeners: MutationListeners;
let activeTextDirection: 'ltr' | 'rtl' | null = null;
let activeDirtyElements: Map<NodeKey, IntentionallyMarkedAsDirtyElement>; let activeDirtyElements: Map<NodeKey, IntentionallyMarkedAsDirtyElement>;
let activeDirtyLeaves: Set<NodeKey>; let activeDirtyLeaves: Set<NodeKey>;
let activePrevNodeMap: NodeMap; let activePrevNodeMap: NodeMap;
@ -197,7 +194,7 @@ function $createNode(
if (childrenSize !== 0) { if (childrenSize !== 0) {
const endIndex = childrenSize - 1; const endIndex = childrenSize - 1;
const children = createChildrenArray(node, activeNextNodeMap); const children = createChildrenArray(node, activeNextNodeMap);
$createChildrenWithDirection(children, endIndex, node, dom); $createChildren(children, node, 0, endIndex, dom, null);
} }
const format = node.__format; const format = node.__format;
@ -222,10 +219,6 @@ function $createNode(
} }
// Decorators are always non editable // Decorators are always non editable
dom.contentEditable = 'false'; dom.contentEditable = 'false';
} else if ($isTextNode(node)) {
if (!node.isDirectionless()) {
subTreeDirectionedTextContent += text;
}
} }
subTreeTextContent += text; subTreeTextContent += text;
editorTextContent += text; editorTextContent += text;
@ -261,19 +254,6 @@ function $createNode(
return dom; return dom;
} }
function $createChildrenWithDirection(
children: Array<NodeKey>,
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( function $createChildren(
children: Array<NodeKey>, children: Array<NodeKey>,
element: ElementNode, 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( function $reconcileChildrenWithDirection(
prevElement: ElementNode, prevElement: ElementNode,
nextElement: ElementNode, nextElement: ElementNode,
dom: HTMLElement, dom: HTMLElement,
): void { ): void {
const previousSubTreeDirectionTextContent = subTreeDirectionedTextContent;
subTreeDirectionedTextContent = '';
subTreeTextFormat = null; subTreeTextFormat = null;
subTreeTextStyle = ''; subTreeTextStyle = '';
$reconcileChildren(prevElement, nextElement, dom); $reconcileChildren(prevElement, nextElement, dom);
reconcileBlockDirection(nextElement, dom);
reconcileParagraphFormat(nextElement); reconcileParagraphFormat(nextElement);
reconcileParagraphStyle(nextElement); reconcileParagraphStyle(nextElement);
subTreeDirectionedTextContent = previousSubTreeDirectionTextContent;
} }
function createChildrenArray( function createChildrenArray(
@ -624,20 +527,9 @@ function $reconcileNode(
subTreeTextContent += previousSubTreeTextContent; subTreeTextContent += previousSubTreeTextContent;
editorTextContent += previousSubTreeTextContent; editorTextContent += previousSubTreeTextContent;
} }
// @ts-expect-error: internal field
const previousSubTreeDirectionTextContent = dom.__lexicalDirTextContent;
if (previousSubTreeDirectionTextContent !== undefined) {
subTreeDirectionedTextContent += previousSubTreeDirectionTextContent;
}
} else { } else {
const text = prevNode.getTextContent(); const text = prevNode.getTextContent();
if ($isTextNode(prevNode) && !prevNode.isDirectionless()) {
subTreeDirectionedTextContent += text;
}
editorTextContent += text; editorTextContent += text;
subTreeTextContent += text; subTreeTextContent += text;
} }
@ -702,9 +594,6 @@ function $reconcileNode(
if (decorator !== null) { if (decorator !== null) {
reconcileDecorator(key, decorator); reconcileDecorator(key, decorator);
} }
} else if ($isTextNode(nextNode) && !nextNode.isDirectionless()) {
// Handle text content, for LTR, LTR cases.
subTreeDirectionedTextContent += text;
} }
subTreeTextContent += text; subTreeTextContent += text;
@ -871,11 +760,9 @@ export function $reconcileRoot(
// The cache must be rebuilt during reconciliation to account for any changes. // The cache must be rebuilt during reconciliation to account for any changes.
subTreeTextContent = ''; subTreeTextContent = '';
editorTextContent = ''; editorTextContent = '';
subTreeDirectionedTextContent = '';
// Rather than pass around a load of arguments through the stack recursively // Rather than pass around a load of arguments through the stack recursively
// we instead set them as bindings within the scope of the module. // we instead set them as bindings within the scope of the module.
treatAllNodesAsDirty = dirtyType === FULL_RECONCILE; treatAllNodesAsDirty = dirtyType === FULL_RECONCILE;
activeTextDirection = null;
activeEditor = editor; activeEditor = editor;
activeEditorConfig = editor._config; activeEditorConfig = editor._config;
activeEditorNodes = editor._nodes; activeEditorNodes = editor._nodes;

File diff suppressed because one or more lines are too long

View File

@ -258,7 +258,7 @@ describe('LexicalEditor tests', () => {
await Promise.resolve().then(); await Promise.resolve().then();
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<div style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">This works!</span></p></div>', '<div style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">This works!</span></p></div>',
); );
const initialEditorState = initialEditor.getEditorState(); const initialEditorState = initialEditor.getEditorState();
@ -276,7 +276,7 @@ describe('LexicalEditor tests', () => {
expect(editor.getEditorState()).toEqual(initialEditorState); expect(editor.getEditorState()).toEqual(initialEditorState);
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<div style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">This works!</span></p></div>', '<div style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">This works!</span></p></div>',
); );
}); });
@ -520,7 +520,7 @@ describe('LexicalEditor tests', () => {
underlineListener(); underlineListener();
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><strong class="editor-text-bold editor-text-italic editor-text-underline" data-lexical-text="true">foo</strong></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><strong class="editor-text-bold editor-text-italic editor-text-underline" data-lexical-text="true">foo</strong></p></div>',
); );
}); });
@ -586,7 +586,7 @@ describe('LexicalEditor tests', () => {
italicsListener(); italicsListener();
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><strong class="editor-text-bold editor-text-italic" data-lexical-text="true">foo</strong></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><strong class="editor-text-bold editor-text-italic" data-lexical-text="true">foo</strong></p></div>',
); );
}); });
@ -657,7 +657,7 @@ describe('LexicalEditor tests', () => {
boldFooListener(); boldFooListener();
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><strong class="editor-text-bold" data-lexical-text="true">Foo!!</strong></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><strong class="editor-text-bold" data-lexical-text="true">Foo!!</strong></p></div>',
); );
}); });
@ -875,7 +875,7 @@ describe('LexicalEditor tests', () => {
editor.setRootElement(element); editor.setRootElement(element);
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">This works!</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">This works!</span></p></div>',
); );
}); });
@ -897,7 +897,7 @@ describe('LexicalEditor tests', () => {
await Promise.resolve().then(); await Promise.resolve().then();
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">This works!</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">This works!</span></p></div>',
); );
expect(errorListener).toHaveBeenCalledTimes(0); expect(errorListener).toHaveBeenCalledTimes(0);
@ -912,7 +912,7 @@ describe('LexicalEditor tests', () => {
expect(errorListener).toHaveBeenCalledTimes(1); expect(errorListener).toHaveBeenCalledTimes(1);
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">This works!</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">This works!</span></p></div>',
); );
}); });
@ -953,7 +953,7 @@ describe('LexicalEditor tests', () => {
editorInstance.commitUpdates(); editorInstance.commitUpdates();
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">Not changed</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">Not changed</span></p></div>',
); );
edContainer = document.createElement('span'); edContainer = document.createElement('span');
@ -966,7 +966,7 @@ describe('LexicalEditor tests', () => {
expect(rootListener).toHaveBeenCalledTimes(3); expect(rootListener).toHaveBeenCalledTimes(3);
expect(updateListener).toHaveBeenCalledTimes(3); expect(updateListener).toHaveBeenCalledTimes(3);
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<span contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">Change successful</span></p></span>', '<span contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">Change successful</span></p></span>',
); );
}); });
@ -1046,7 +1046,7 @@ describe('LexicalEditor tests', () => {
it('Parses the nodes of a stringified editor state', async () => { it('Parses the nodes of a stringified editor state', async () => {
expect(parsedRoot).toEqual({ expect(parsedRoot).toEqual({
__cachedText: null, __cachedText: null,
__dir: 'ltr', __dir: null,
__first: paragraphKey, __first: paragraphKey,
__format: 0, __format: 0,
__indent: 0, __indent: 0,
@ -1060,7 +1060,7 @@ describe('LexicalEditor tests', () => {
__type: 'root', __type: 'root',
}); });
expect(parsedParagraph).toEqual({ expect(parsedParagraph).toEqual({
__dir: 'ltr', __dir: null,
__first: textKey, __first: textKey,
__format: 0, __format: 0,
__indent: 0, __indent: 0,
@ -1128,7 +1128,7 @@ describe('LexicalEditor tests', () => {
it('Parses the nodes of a stringified editor state', async () => { it('Parses the nodes of a stringified editor state', async () => {
expect(parsedRoot).toEqual({ expect(parsedRoot).toEqual({
__cachedText: null, __cachedText: null,
__dir: 'ltr', __dir: null,
__first: paragraphKey, __first: paragraphKey,
__format: 0, __format: 0,
__indent: 0, __indent: 0,
@ -1142,7 +1142,7 @@ describe('LexicalEditor tests', () => {
__type: 'root', __type: 'root',
}); });
expect(parsedParagraph).toEqual({ expect(parsedParagraph).toEqual({
__dir: 'ltr', __dir: null,
__first: textKey, __first: textKey,
__format: 0, __format: 0,
__indent: 0, __indent: 0,
@ -1275,7 +1275,7 @@ describe('LexicalEditor tests', () => {
expect(editor._editorState._nodeMap.size).toBe(keys.length + 1); // + root expect(editor._editorState._nodeMap.size).toBe(keys.length + 1); // + root
expect(editor._keyToDOMMap.size).toBe(keys.length + 1); // + root expect(editor._keyToDOMMap.size).toBe(keys.length + 1); // + root
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><div dir="ltr"><span data-lexical-text="true">A</span><div dir="ltr"><span data-lexical-text="true">B</span></div></div></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><div><span data-lexical-text="true">A</span><div><span data-lexical-text="true">B</span></div></div></p></div>',
); );
}); });
@ -1310,7 +1310,7 @@ describe('LexicalEditor tests', () => {
}); });
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><div dir="ltr"><span data-lexical-text="true">B</span><div dir="ltr"><span data-lexical-text="true">A</span></div></div></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><div><span data-lexical-text="true">B</span><div><span data-lexical-text="true">A</span></div></div></p></div>',
); );
}); });
@ -1351,7 +1351,7 @@ describe('LexicalEditor tests', () => {
}); });
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><div dir="ltr"><span data-lexical-text="true">A</span><div dir="ltr"><span data-lexical-text="true">C</span></div></div><div dir="ltr"><span data-lexical-text="true">B</span></div></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><div><span data-lexical-text="true">A</span><div><span data-lexical-text="true">C</span></div></div><div><span data-lexical-text="true">B</span></div></p></div>',
); );
}); });
}); });
@ -2294,14 +2294,14 @@ describe('LexicalEditor tests', () => {
}); });
expect(container.firstElementChild?.innerHTML).toBe( expect(container.firstElementChild?.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">Hello</span><a></a></p>', '<p><span data-lexical-text="true">Hello</span><a></a></p>',
); );
}); });
it('reconciles state without root element', () => { it('reconciles state without root element', () => {
editor = createTestEditor({}); editor = createTestEditor({});
const state = editor.parseEditorState( 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); editor.setEditorState(state);
expect(editor._editorState).toBe(state); expect(editor._editorState).toBe(state);

View File

@ -52,7 +52,7 @@ describe('LexicalEditorState tests', () => {
expect(root).toEqual({ expect(root).toEqual({
__cachedText: 'foo', __cachedText: 'foo',
__dir: 'ltr', __dir: null,
__first: '1', __first: '1',
__format: 0, __format: 0,
__indent: 0, __indent: 0,
@ -66,7 +66,7 @@ describe('LexicalEditorState tests', () => {
__type: 'root', __type: 'root',
}); });
expect(paragraph).toEqual({ expect(paragraph).toEqual({
__dir: 'ltr', __dir: null,
__first: '2', __first: '2',
__format: 0, __format: 0,
__indent: 0, __indent: 0,
@ -113,7 +113,7 @@ describe('LexicalEditorState tests', () => {
}); });
expect(JSON.stringify(editor.getEditorState().toJSON())).toEqual( 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}}`,
); );
}); });

View File

@ -645,7 +645,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span></p></div>',
); );
await editor.getEditorState().read(() => { await editor.getEditorState().read(() => {
@ -667,7 +667,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span><span data-lexical-text="true">bar</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span><span data-lexical-text="true">bar</span></p></div>',
); );
await editor.getEditorState().read(() => { await editor.getEditorState().read(() => {
@ -694,7 +694,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span><span data-lexical-text="true">bar</span><span data-lexical-text="true">baz</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span><span data-lexical-text="true">bar</span><span data-lexical-text="true">baz</span></p></div>',
); );
await editor.getEditorState().read(() => { await editor.getEditorState().read(() => {
@ -730,7 +730,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span><span data-lexical-text="true">bar</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span><span data-lexical-text="true">bar</span></p></div>',
); );
await editor.getEditorState().read(() => { await editor.getEditorState().read(() => {
@ -754,7 +754,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span><span data-lexical-text="true">bar</span><span data-lexical-text="true">baz</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span><span data-lexical-text="true">bar</span><span data-lexical-text="true">baz</span></p></div>',
); );
await editor.getEditorState().read(() => { await editor.getEditorState().read(() => {
@ -795,7 +795,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span><span data-lexical-text="true">qux</span></p><p dir="ltr"><span data-lexical-text="true">bar</span></p><p dir="ltr"><span data-lexical-text="true">baz</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span><span data-lexical-text="true">qux</span></p><p><span data-lexical-text="true">bar</span></p><p><span data-lexical-text="true">baz</span></p></div>',
); );
await editor.getEditorState().read(() => { await editor.getEditorState().read(() => {
@ -828,7 +828,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span><span data-lexical-text="true">bar</span><span data-lexical-text="true">baz</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span><span data-lexical-text="true">bar</span><span data-lexical-text="true">baz</span></p></div>',
); );
await editor.getEditorState().read(() => { await editor.getEditorState().read(() => {
@ -879,7 +879,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span><span data-lexical-text="true">bar</span><span data-lexical-text="true">baz</span></p><p dir="ltr"><span data-lexical-text="true">qux</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span><span data-lexical-text="true">bar</span><span data-lexical-text="true">baz</span></p><p><span data-lexical-text="true">qux</span></p></div>',
); );
await editor.getEditorState().read(() => { await editor.getEditorState().read(() => {
@ -915,7 +915,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span><span data-lexical-text="true">token</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span><span data-lexical-text="true">token</span></p></div>',
); );
await editor.getEditorState().read(() => { await editor.getEditorState().read(() => {
@ -935,7 +935,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span><span data-lexical-text="true">segmented</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span><span data-lexical-text="true">segmented</span></p></div>',
); );
await editor.getEditorState().read(() => { await editor.getEditorState().read(() => {
@ -958,7 +958,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span><span data-lexical-text="true">directionless</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span><span data-lexical-text="true">directionless</span></p></div>',
); );
await editor.getEditorState().read(() => { await editor.getEditorState().read(() => {
@ -1057,7 +1057,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span></p></div>',
); );
await editor.update(() => { await editor.update(() => {
@ -1089,7 +1089,7 @@ describe('LexicalNode tests', () => {
const {editor} = testEnv; const {editor} = testEnv;
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span></p></div>',
); );
let barTextNode: TextNode; let barTextNode: TextNode;
@ -1102,7 +1102,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span></p><p dir="ltr"><span data-lexical-text="true">bar</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span></p><p><span data-lexical-text="true">bar</span></p></div>',
); );
await editor.update(() => { await editor.update(() => {
@ -1110,7 +1110,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">bar</span></p><p dir="ltr"><br></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">bar</span></p><p><br></p></div>',
); );
}); });
@ -1118,7 +1118,7 @@ describe('LexicalNode tests', () => {
const {editor} = testEnv; const {editor} = testEnv;
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span></p></div>',
); );
await editor.update(() => { await editor.update(() => {
@ -1127,7 +1127,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">bar</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">bar</span></p></div>',
); );
}); });
@ -1135,7 +1135,7 @@ describe('LexicalNode tests', () => {
const {editor} = testEnv; const {editor} = testEnv;
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span></p></div>',
); );
await editor.update(() => { await editor.update(() => {
@ -1144,7 +1144,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">bar</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">bar</span></p></div>',
); );
}); });
@ -1152,7 +1152,7 @@ describe('LexicalNode tests', () => {
const {editor} = testEnv; const {editor} = testEnv;
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span></p></div>',
); );
await editor.update(() => { await editor.update(() => {
@ -1161,7 +1161,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">bar</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">bar</span></p></div>',
); );
}); });
@ -1169,7 +1169,7 @@ describe('LexicalNode tests', () => {
const {editor} = testEnv; const {editor} = testEnv;
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span></p></div>',
); );
await editor.update(() => { await editor.update(() => {
@ -1205,7 +1205,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><a dir="ltr"><span data-lexical-text="true">world</span></a></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><a><span data-lexical-text="true">world</span></a></p></div>',
); );
}); });
@ -1224,7 +1224,7 @@ describe('LexicalNode tests', () => {
const {editor} = testEnv; const {editor} = testEnv;
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span></p></div>',
); );
await editor.update(() => { await editor.update(() => {
@ -1233,7 +1233,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foobar</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foobar</span></p></div>',
); );
}); });
@ -1241,7 +1241,7 @@ describe('LexicalNode tests', () => {
const {editor} = testEnv; const {editor} = testEnv;
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span></p></div>',
); );
await editor.update(() => { await editor.update(() => {
@ -1250,7 +1250,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span><span data-lexical-text="true">bar</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span><span data-lexical-text="true">bar</span></p></div>',
); );
}); });
@ -1258,7 +1258,7 @@ describe('LexicalNode tests', () => {
const {editor} = testEnv; const {editor} = testEnv;
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span></p></div>',
); );
await editor.update(() => { await editor.update(() => {
@ -1267,7 +1267,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span><span data-lexical-text="true">bar</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span><span data-lexical-text="true">bar</span></p></div>',
); );
}); });
@ -1275,7 +1275,7 @@ describe('LexicalNode tests', () => {
const {editor} = testEnv; const {editor} = testEnv;
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span></p></div>',
); );
await editor.update(() => { await editor.update(() => {
@ -1284,7 +1284,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foobar</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foobar</span></p></div>',
); );
// TODO: add text direction validations // TODO: add text direction validations
}); });
@ -1314,7 +1314,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">A</span></p><p dir="ltr"><span data-lexical-text="true">B</span></p><p dir="ltr"><span data-lexical-text="true">C</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">A</span></p><p><span data-lexical-text="true">B</span></p><p><span data-lexical-text="true">C</span></p></div>',
); );
await editor.update(() => { await editor.update(() => {
@ -1322,7 +1322,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">A</span><p dir="ltr"><span data-lexical-text="true">B</span></p></p><p dir="ltr"><span data-lexical-text="true">C</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">A</span><p><span data-lexical-text="true">B</span></p></p><p><span data-lexical-text="true">C</span></p></div>',
); );
}); });
@ -1356,7 +1356,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">A</span></p><p dir="ltr"><span data-lexical-text="true">B</span></p><p dir="ltr"><span data-lexical-text="true">C</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">A</span></p><p><span data-lexical-text="true">B</span></p><p><span data-lexical-text="true">C</span></p></div>',
); );
await editor.update(() => { await editor.update(() => {
@ -1365,7 +1365,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><br></p><p><br></p><p dir="ltr"><span data-lexical-text="true">C</span><span data-lexical-text="true">B</span><span data-lexical-text="true">A</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><br></p><p><br></p><p><span data-lexical-text="true">C</span><span data-lexical-text="true">B</span><span data-lexical-text="true">A</span></p></div>',
); );
}); });
@ -1384,7 +1384,7 @@ describe('LexicalNode tests', () => {
const {editor} = testEnv; const {editor} = testEnv;
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span></p></div>',
); );
let barTextNode; let barTextNode;
@ -1397,7 +1397,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span></p><p dir="ltr"><span data-lexical-text="true">bar</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span></p><p><span data-lexical-text="true">bar</span></p></div>',
); );
}); });
@ -1405,7 +1405,7 @@ describe('LexicalNode tests', () => {
const {editor} = testEnv; const {editor} = testEnv;
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span></p></div>',
); );
await editor.update(() => { await editor.update(() => {
@ -1414,7 +1414,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">barfoo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">barfoo</span></p></div>',
); );
}); });
@ -1422,7 +1422,7 @@ describe('LexicalNode tests', () => {
const {editor} = testEnv; const {editor} = testEnv;
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span></p></div>',
); );
await editor.update(() => { await editor.update(() => {
@ -1431,7 +1431,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">bar</span><span data-lexical-text="true">foo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">bar</span><span data-lexical-text="true">foo</span></p></div>',
); );
}); });
@ -1439,7 +1439,7 @@ describe('LexicalNode tests', () => {
const {editor} = testEnv; const {editor} = testEnv;
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span></p></div>',
); );
await editor.update(() => { await editor.update(() => {
@ -1448,7 +1448,7 @@ describe('LexicalNode tests', () => {
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">bar</span><span data-lexical-text="true">foo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">bar</span><span data-lexical-text="true">foo</span></p></div>',
); );
}); });
@ -1456,7 +1456,7 @@ describe('LexicalNode tests', () => {
const {editor} = testEnv; const {editor} = testEnv;
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">foo</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">foo</span></p></div>',
); );
await editor.update(() => { await editor.update(() => {

View File

@ -61,10 +61,10 @@ describe('LexicalSelection tests', () => {
const expectation = const expectation =
mode === 'start-of-paragraph' mode === 'start-of-paragraph'
? '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><a href="https://" dir="ltr"><span data-lexical-text="true">a</span></a><span data-lexical-text="true">b</span></p></div>' ? '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><a href="https://"><span data-lexical-text="true">a</span></a><span data-lexical-text="true">b</span></p></div>'
: mode === 'mid-paragraph' : mode === 'mid-paragraph'
? '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">a</span><a href="https://" dir="ltr"><span data-lexical-text="true">b</span></a><span data-lexical-text="true">c</span></p></div>' ? '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">a</span><a href="https://"><span data-lexical-text="true">b</span></a><span data-lexical-text="true">c</span></p></div>'
: '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">a</span><a href="https://" dir="ltr"><span data-lexical-text="true">b</span></a></p></div>'; : '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">a</span><a href="https://"><span data-lexical-text="true">b</span></a></p></div>';
expect(container.innerHTML).toBe(expectation); expect(container.innerHTML).toBe(expectation);
@ -113,7 +113,7 @@ describe('LexicalSelection tests', () => {
}); });
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">x</span><a href="https://" dir="ltr"><span data-lexical-text="true">a</span></a><span data-lexical-text="true">b</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">x</span><a href="https://"><span data-lexical-text="true">a</span></a><span data-lexical-text="true">b</span></p></div>',
); );
}; };
@ -154,7 +154,7 @@ describe('LexicalSelection tests', () => {
}); });
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">ax</span><a href="https://" dir="ltr"><span data-lexical-text="true">b</span></a><span data-lexical-text="true">c</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">ax</span><a href="https://"><span data-lexical-text="true">b</span></a><span data-lexical-text="true">c</span></p></div>',
); );
}; };
@ -194,7 +194,7 @@ describe('LexicalSelection tests', () => {
}); });
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">ax</span><a href="https://" dir="ltr"><span data-lexical-text="true">b</span></a></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">ax</span><a href="https://"><span data-lexical-text="true">b</span></a></p></div>',
); );
}; };
@ -236,7 +236,7 @@ describe('LexicalSelection tests', () => {
}); });
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><a href="https://" dir="ltr"><span data-lexical-text="true">a</span></a><span data-lexical-text="true">xb</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><a href="https://"><span data-lexical-text="true">a</span></a><span data-lexical-text="true">xb</span></p></div>',
); );
}; };
@ -277,7 +277,7 @@ describe('LexicalSelection tests', () => {
}); });
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">a</span><a href="https://" dir="ltr"><span data-lexical-text="true">b</span></a><span data-lexical-text="true">xc</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">a</span><a href="https://"><span data-lexical-text="true">b</span></a><span data-lexical-text="true">xc</span></p></div>',
); );
}; };
@ -319,7 +319,7 @@ describe('LexicalSelection tests', () => {
}); });
expect(container.innerHTML).toBe( expect(container.innerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p dir="ltr"><span data-lexical-text="true">a</span><a href="https://" dir="ltr"><span data-lexical-text="true">b</span></a><span data-lexical-text="true">x</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p><span data-lexical-text="true">a</span><a href="https://"><span data-lexical-text="true">b</span></a><span data-lexical-text="true">x</span></p></div>',
); );
}; };

File diff suppressed because one or more lines are too long

View File

@ -55,7 +55,7 @@ describe('LexicalTabNode tests', () => {
$insertDataTransferForPlainText(dataTransfer, selection); $insertDataTransferForPlainText(dataTransfer, selection);
}); });
expect(testEnv.innerHTML).toBe( expect(testEnv.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">hello</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">world</span><br><span data-lexical-text="true">hello</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">world</span></p>', '<p><span data-lexical-text="true">hello</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">world</span><br><span data-lexical-text="true">hello</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">world</span></p>',
); );
}); });
@ -69,7 +69,7 @@ describe('LexicalTabNode tests', () => {
$insertDataTransferForRichText(dataTransfer, selection, editor); $insertDataTransferForRichText(dataTransfer, selection, editor);
}); });
expect(testEnv.innerHTML).toBe( expect(testEnv.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">hello</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">world</span></p><p dir="ltr"><span data-lexical-text="true">hello</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">world</span></p>', '<p><span data-lexical-text="true">hello</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">world</span></p><p><span data-lexical-text="true">hello</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">world</span></p>',
); );
}); });
@ -89,7 +89,7 @@ describe('LexicalTabNode tests', () => {
// $insertDataTransferForRichText(dataTransfer, selection, editor); // $insertDataTransferForRichText(dataTransfer, selection, editor);
// }); // });
// expect(testEnv.innerHTML).toBe( // expect(testEnv.innerHTML).toBe(
// '<p dir="ltr"><span data-lexical-text="true">hello</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">world</span><br><span data-lexical-text="true">hello</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">world</span></p>', // '<p><span data-lexical-text="true">hello</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">world</span><br><span data-lexical-text="true">hello</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">world</span></p>',
// ); // );
// }); // });
@ -99,7 +99,7 @@ describe('LexicalTabNode tests', () => {
// GDoc 2-liner hello\tworld (like previous test) // GDoc 2-liner hello\tworld (like previous test)
dataTransfer.setData( dataTransfer.setData(
'text/html', 'text/html',
`<meta charset='utf-8'><meta charset="utf-8"><b style="font-weight:normal;" id="docs-internal-guid-123"><p dir="ltr" style="line-height:1.38;margin-left: 36pt;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Hello</span><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><span class="Apple-tab-span" style="white-space:pre;"> </span></span><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">world</span></p><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Hello</span><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><span class="Apple-tab-span" style="white-space:pre;"> </span></span><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">world</span></b>`, `<meta charset='utf-8'><meta charset="utf-8"><b style="font-weight:normal;" id="docs-internal-guid-123"><p style="line-height:1.38;margin-left: 36pt;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Hello</span><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><span class="Apple-tab-span" style="white-space:pre;"> </span></span><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">world</span></p><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Hello</span><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"><span class="Apple-tab-span" style="white-space:pre;"> </span></span><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">world</span></b>`,
); );
await editor.update(() => { await editor.update(() => {
const selection = $getSelection(); const selection = $getSelection();
@ -107,7 +107,7 @@ describe('LexicalTabNode tests', () => {
$insertDataTransferForRichText(dataTransfer, selection, editor); $insertDataTransferForRichText(dataTransfer, selection, editor);
}); });
expect(testEnv.innerHTML).toBe( expect(testEnv.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">Hello</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">world</span></p><p dir="ltr"><span data-lexical-text="true">Hello</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">world</span></p>', '<p><span data-lexical-text="true">Hello</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">world</span></p><p><span data-lexical-text="true">Hello</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">world</span></p>',
); );
}); });
@ -121,7 +121,7 @@ describe('LexicalTabNode tests', () => {
$getSelection()!.insertText('f'); $getSelection()!.insertText('f');
}); });
expect(testEnv.innerHTML).toBe( expect(testEnv.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">\t</span><span data-lexical-text="true">f</span><span data-lexical-text="true">\t</span></p>', '<p><span data-lexical-text="true">\t</span><span data-lexical-text="true">f</span><span data-lexical-text="true">\t</span></p>',
); );
}); });
}); });

View File

@ -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();
}
}

View File

@ -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;

View File

@ -182,13 +182,13 @@ describe('LexicalListItemNode tests', () => {
style="user-select: text; white-space: pre-wrap; word-break: break-word;" style="user-select: text; white-space: pre-wrap; word-break: break-word;"
data-lexical-editor="true"> data-lexical-editor="true">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">one</span> <span data-lexical-text="true">one</span>
</li> </li>
<li value="2" dir="ltr"> <li value="2">
<span data-lexical-text="true">two</span> <span data-lexical-text="true">two</span>
</li> </li>
<li value="3" dir="ltr"> <li value="3">
<span data-lexical-text="true">three</span> <span data-lexical-text="true">three</span>
</li> </li>
</ul> </ul>
@ -215,13 +215,13 @@ describe('LexicalListItemNode tests', () => {
style="user-select: text; white-space: pre-wrap; word-break: break-word;" style="user-select: text; white-space: pre-wrap; word-break: break-word;"
data-lexical-editor="true"> data-lexical-editor="true">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">bar</span> <span data-lexical-text="true">bar</span>
</li> </li>
<li value="2" dir="ltr"> <li value="2">
<span data-lexical-text="true">two</span> <span data-lexical-text="true">two</span>
</li> </li>
<li value="3" dir="ltr"> <li value="3">
<span data-lexical-text="true">three</span> <span data-lexical-text="true">three</span>
</li> </li>
</ul> </ul>
@ -245,13 +245,13 @@ describe('LexicalListItemNode tests', () => {
style="user-select: text; white-space: pre-wrap; word-break: break-word;" style="user-select: text; white-space: pre-wrap; word-break: break-word;"
data-lexical-editor="true"> data-lexical-editor="true">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">one</span> <span data-lexical-text="true">one</span>
</li> </li>
<li value="2" dir="ltr"> <li value="2">
<span data-lexical-text="true">two</span> <span data-lexical-text="true">two</span>
</li> </li>
<li value="3" dir="ltr"> <li value="3">
<span data-lexical-text="true">three</span> <span data-lexical-text="true">three</span>
</li> </li>
</ul> </ul>
@ -273,10 +273,10 @@ describe('LexicalListItemNode tests', () => {
data-lexical-editor="true"> data-lexical-editor="true">
<p><br></p> <p><br></p>
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">two</span> <span data-lexical-text="true">two</span>
</li> </li>
<li value="2" dir="ltr"> <li value="2">
<span data-lexical-text="true">three</span> <span data-lexical-text="true">three</span>
</li> </li>
</ul> </ul>
@ -301,10 +301,10 @@ describe('LexicalListItemNode tests', () => {
style="user-select: text; white-space: pre-wrap; word-break: break-word;" style="user-select: text; white-space: pre-wrap; word-break: break-word;"
data-lexical-editor="true"> data-lexical-editor="true">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">one</span> <span data-lexical-text="true">one</span>
</li> </li>
<li value="2" dir="ltr"> <li value="2">
<span data-lexical-text="true">two</span> <span data-lexical-text="true">two</span>
</li> </li>
</ul> </ul>
@ -330,13 +330,13 @@ describe('LexicalListItemNode tests', () => {
style="user-select: text; white-space: pre-wrap; word-break: break-word;" style="user-select: text; white-space: pre-wrap; word-break: break-word;"
data-lexical-editor="true"> data-lexical-editor="true">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">one</span> <span data-lexical-text="true">one</span>
</li> </li>
</ul> </ul>
<p><br></p> <p><br></p>
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">three</span> <span data-lexical-text="true">three</span>
</li> </li>
</ul> </ul>
@ -361,7 +361,7 @@ describe('LexicalListItemNode tests', () => {
style="user-select: text; white-space: pre-wrap; word-break: break-word;" style="user-select: text; white-space: pre-wrap; word-break: break-word;"
data-lexical-editor="true"> data-lexical-editor="true">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">one</span> <span data-lexical-text="true">one</span>
</li> </li>
</ul> </ul>
@ -421,13 +421,13 @@ describe('LexicalListItemNode tests', () => {
style="user-select: text; white-space: pre-wrap; word-break: break-word;" style="user-select: text; white-space: pre-wrap; word-break: break-word;"
data-lexical-editor="true"> data-lexical-editor="true">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">A</span> <span data-lexical-text="true">A</span>
</li> </li>
<li value="2" dir="ltr"> <li value="2">
<span data-lexical-text="true">x</span> <span data-lexical-text="true">x</span>
</li> </li>
<li value="3" dir="ltr"> <li value="3">
<span data-lexical-text="true">B</span> <span data-lexical-text="true">B</span>
</li> </li>
</ul> </ul>
@ -445,10 +445,10 @@ describe('LexicalListItemNode tests', () => {
style="user-select: text; white-space: pre-wrap; word-break: break-word;" style="user-select: text; white-space: pre-wrap; word-break: break-word;"
data-lexical-editor="true"> data-lexical-editor="true">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">A</span> <span data-lexical-text="true">A</span>
</li> </li>
<li value="2" dir="ltr"> <li value="2">
<span data-lexical-text="true">B</span> <span data-lexical-text="true">B</span>
</li> </li>
</ul> </ul>
@ -495,15 +495,15 @@ describe('LexicalListItemNode tests', () => {
<ul> <ul>
<li value="1"> <li value="1">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">A</span> <span data-lexical-text="true">A</span>
</li> </li>
</ul> </ul>
</li> </li>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">x</span> <span data-lexical-text="true">x</span>
</li> </li>
<li value="2" dir="ltr"> <li value="2">
<span data-lexical-text="true">B</span> <span data-lexical-text="true">B</span>
</li> </li>
</ul> </ul>
@ -523,12 +523,12 @@ describe('LexicalListItemNode tests', () => {
<ul> <ul>
<li value="1"> <li value="1">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">A</span> <span data-lexical-text="true">A</span>
</li> </li>
</ul> </ul>
</li> </li>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">B</span> <span data-lexical-text="true">B</span>
</li> </li>
</ul> </ul>
@ -573,15 +573,15 @@ describe('LexicalListItemNode tests', () => {
style="user-select: text; white-space: pre-wrap; word-break: break-word;" style="user-select: text; white-space: pre-wrap; word-break: break-word;"
data-lexical-editor="true"> data-lexical-editor="true">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">A</span> <span data-lexical-text="true">A</span>
</li> </li>
<li value="2" dir="ltr"> <li value="2">
<span data-lexical-text="true">x</span> <span data-lexical-text="true">x</span>
</li> </li>
<li value="3"> <li value="3">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">B</span> <span data-lexical-text="true">B</span>
</li> </li>
</ul> </ul>
@ -601,12 +601,12 @@ describe('LexicalListItemNode tests', () => {
style="user-select: text; white-space: pre-wrap; word-break: break-word;" style="user-select: text; white-space: pre-wrap; word-break: break-word;"
data-lexical-editor="true"> data-lexical-editor="true">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">A</span> <span data-lexical-text="true">A</span>
</li> </li>
<li value="2"> <li value="2">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">B</span> <span data-lexical-text="true">B</span>
</li> </li>
</ul> </ul>
@ -659,17 +659,17 @@ describe('LexicalListItemNode tests', () => {
<ul> <ul>
<li value="1"> <li value="1">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">A</span> <span data-lexical-text="true">A</span>
</li> </li>
</ul> </ul>
</li> </li>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">x</span> <span data-lexical-text="true">x</span>
</li> </li>
<li value="2"> <li value="2">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">B</span> <span data-lexical-text="true">B</span>
</li> </li>
</ul> </ul>
@ -691,10 +691,10 @@ describe('LexicalListItemNode tests', () => {
<ul> <ul>
<li value="1"> <li value="1">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">A</span> <span data-lexical-text="true">A</span>
</li> </li>
<li value="2" dir="ltr"> <li value="2">
<span data-lexical-text="true">B</span> <span data-lexical-text="true">B</span>
</li> </li>
</ul> </ul>
@ -755,24 +755,24 @@ describe('LexicalListItemNode tests', () => {
<ul> <ul>
<li value="1"> <li value="1">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">A1</span> <span data-lexical-text="true">A1</span>
</li> </li>
<li value="2"> <li value="2">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">A2</span> <span data-lexical-text="true">A2</span>
</li> </li>
</ul> </ul>
</li> </li>
</ul> </ul>
</li> </li>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">x</span> <span data-lexical-text="true">x</span>
</li> </li>
<li value="2"> <li value="2">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">B</span> <span data-lexical-text="true">B</span>
</li> </li>
</ul> </ul>
@ -794,17 +794,17 @@ describe('LexicalListItemNode tests', () => {
<ul> <ul>
<li value="1"> <li value="1">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">A1</span> <span data-lexical-text="true">A1</span>
</li> </li>
<li value="2"> <li value="2">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">A2</span> <span data-lexical-text="true">A2</span>
</li> </li>
</ul> </ul>
</li> </li>
<li value="2" dir="ltr"> <li value="2">
<span data-lexical-text="true">B</span> <span data-lexical-text="true">B</span>
</li> </li>
</ul> </ul>
@ -865,24 +865,24 @@ describe('LexicalListItemNode tests', () => {
<ul> <ul>
<li value="1"> <li value="1">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">A</span> <span data-lexical-text="true">A</span>
</li> </li>
</ul> </ul>
</li> </li>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">x</span> <span data-lexical-text="true">x</span>
</li> </li>
<li value="2"> <li value="2">
<ul> <ul>
<li value="1"> <li value="1">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">B1</span> <span data-lexical-text="true">B1</span>
</li> </li>
</ul> </ul>
</li> </li>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">B2</span> <span data-lexical-text="true">B2</span>
</li> </li>
</ul> </ul>
@ -904,17 +904,17 @@ describe('LexicalListItemNode tests', () => {
<ul> <ul>
<li value="1"> <li value="1">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">A</span> <span data-lexical-text="true">A</span>
</li> </li>
<li value="2"> <li value="2">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">B1</span> <span data-lexical-text="true">B1</span>
</li> </li>
</ul> </ul>
</li> </li>
<li value="2" dir="ltr"> <li value="2">
<span data-lexical-text="true">B2</span> <span data-lexical-text="true">B2</span>
</li> </li>
</ul> </ul>
@ -983,31 +983,31 @@ describe('LexicalListItemNode tests', () => {
<ul> <ul>
<li value="1"> <li value="1">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">A1</span> <span data-lexical-text="true">A1</span>
</li> </li>
<li value="2"> <li value="2">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">A2</span> <span data-lexical-text="true">A2</span>
</li> </li>
</ul> </ul>
</li> </li>
</ul> </ul>
</li> </li>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">x</span> <span data-lexical-text="true">x</span>
</li> </li>
<li value="2"> <li value="2">
<ul> <ul>
<li value="1"> <li value="1">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">B1</span> <span data-lexical-text="true">B1</span>
</li> </li>
</ul> </ul>
</li> </li>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">B2</span> <span data-lexical-text="true">B2</span>
</li> </li>
</ul> </ul>
@ -1029,20 +1029,20 @@ describe('LexicalListItemNode tests', () => {
<ul> <ul>
<li value="1"> <li value="1">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">A1</span> <span data-lexical-text="true">A1</span>
</li> </li>
<li value="2"> <li value="2">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">A2</span> <span data-lexical-text="true">A2</span>
</li> </li>
<li value="2" dir="ltr"> <li value="2">
<span data-lexical-text="true">B1</span> <span data-lexical-text="true">B1</span>
</li> </li>
</ul> </ul>
</li> </li>
<li value="2" dir="ltr"> <li value="2">
<span data-lexical-text="true">B2</span> <span data-lexical-text="true">B2</span>
</li> </li>
</ul> </ul>
@ -1087,13 +1087,13 @@ describe('LexicalListItemNode tests', () => {
style="user-select: text; white-space: pre-wrap; word-break: break-word;" style="user-select: text; white-space: pre-wrap; word-break: break-word;"
data-lexical-editor="true"> data-lexical-editor="true">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">one</span> <span data-lexical-text="true">one</span>
</li> </li>
<li value="2" dir="ltr"> <li value="2">
<span data-lexical-text="true">two</span> <span data-lexical-text="true">two</span>
</li> </li>
<li value="3" dir="ltr"> <li value="3">
<span data-lexical-text="true">three</span> <span data-lexical-text="true">three</span>
</li> </li>
</ul> </ul>
@ -1117,14 +1117,14 @@ describe('LexicalListItemNode tests', () => {
style="user-select: text; white-space: pre-wrap; word-break: break-word;" style="user-select: text; white-space: pre-wrap; word-break: break-word;"
data-lexical-editor="true"> data-lexical-editor="true">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">one</span> <span data-lexical-text="true">one</span>
</li> </li>
<li value="2"><br></li> <li value="2"><br></li>
<li value="3" dir="ltr"> <li value="3">
<span data-lexical-text="true">two</span> <span data-lexical-text="true">two</span>
</li> </li>
<li value="4" dir="ltr"> <li value="4">
<span data-lexical-text="true">three</span> <span data-lexical-text="true">three</span>
</li> </li>
</ul> </ul>
@ -1148,13 +1148,13 @@ describe('LexicalListItemNode tests', () => {
style="user-select: text; white-space: pre-wrap; word-break: break-word;" style="user-select: text; white-space: pre-wrap; word-break: break-word;"
data-lexical-editor="true"> data-lexical-editor="true">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">one</span> <span data-lexical-text="true">one</span>
</li> </li>
<li value="2" dir="ltr"> <li value="2">
<span data-lexical-text="true">two</span> <span data-lexical-text="true">two</span>
</li> </li>
<li value="3" dir="ltr"> <li value="3">
<span data-lexical-text="true">three</span> <span data-lexical-text="true">three</span>
</li> </li>
<li value="4"><br></li> <li value="4"><br></li>
@ -1179,13 +1179,13 @@ describe('LexicalListItemNode tests', () => {
style="user-select: text; white-space: pre-wrap; word-break: break-word;" style="user-select: text; white-space: pre-wrap; word-break: break-word;"
data-lexical-editor="true"> data-lexical-editor="true">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">one</span> <span data-lexical-text="true">one</span>
</li> </li>
<li value="2" dir="ltr"> <li value="2">
<span data-lexical-text="true">two</span> <span data-lexical-text="true">two</span>
</li> </li>
<li value="3" dir="ltr"> <li value="3">
<span data-lexical-text="true">three</span> <span data-lexical-text="true">three</span>
</li> </li>
<li value="4"><br></li> <li value="4"><br></li>
@ -1211,7 +1211,7 @@ describe('LexicalListItemNode tests', () => {
style="user-select: text; white-space: pre-wrap; word-break: break-word;" style="user-select: text; white-space: pre-wrap; word-break: break-word;"
data-lexical-editor="true"> data-lexical-editor="true">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">one</span> <span data-lexical-text="true">one</span>
</li> </li>
</ul> </ul>
@ -1231,7 +1231,7 @@ describe('LexicalListItemNode tests', () => {
style="user-select: text; white-space: pre-wrap; word-break: break-word;" style="user-select: text; white-space: pre-wrap; word-break: break-word;"
data-lexical-editor="true"> data-lexical-editor="true">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">one</span> <span data-lexical-text="true">one</span>
</li> </li>
<li value="2"><br></li> <li value="2"><br></li>
@ -1308,7 +1308,7 @@ describe('LexicalListItemNode tests', () => {
<ul> <ul>
<li value="1"> <li value="1">
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">one</span> <span data-lexical-text="true">one</span>
</li> </li>
</ul> </ul>
@ -1317,7 +1317,7 @@ describe('LexicalListItemNode tests', () => {
</li> </li>
</ul> </ul>
</li> </li>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">two</span> <span data-lexical-text="true">two</span>
</li> </li>
</ul> </ul>
@ -1336,10 +1336,10 @@ describe('LexicalListItemNode tests', () => {
editor.getRootElement()!.innerHTML, editor.getRootElement()!.innerHTML,
html` html`
<ul> <ul>
<li value="1" dir="ltr"> <li value="1">
<span data-lexical-text="true">one</span> <span data-lexical-text="true">one</span>
</li> </li>
<li value="2" dir="ltr"> <li value="2">
<span data-lexical-text="true">two</span> <span data-lexical-text="true">two</span>
</li> </li>
</ul> </ul>

View File

@ -117,7 +117,7 @@ describe('LexicalHeadingNode tests', () => {
headingTextNode.select(5, 5); headingTextNode.select(5, 5);
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h1 dir="ltr"><span data-lexical-text="true">hello world</span></h1></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h1><span data-lexical-text="true">hello world</span></h1></div>',
); );
await editor.update(() => { await editor.update(() => {
const selection = $getSelection() as RangeSelection; const selection = $getSelection() as RangeSelection;
@ -126,7 +126,7 @@ describe('LexicalHeadingNode tests', () => {
expect(result.getDirection()).toEqual(headingNode.getDirection()); expect(result.getDirection()).toEqual(headingNode.getDirection());
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h1 dir="ltr"><span data-lexical-text="true">hello world</span></h1><h1><br></h1></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h1><span data-lexical-text="true">hello world</span></h1><h1><br></h1></div>',
); );
}); });
@ -143,7 +143,7 @@ describe('LexicalHeadingNode tests', () => {
headingTextNode2.selectEnd(); headingTextNode2.selectEnd();
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h1 dir="ltr"><span data-lexical-text="true">hello</span><strong data-lexical-text="true"> world</strong></h1></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h1><span data-lexical-text="true">hello</span><strong data-lexical-text="true"> world</strong></h1></div>',
); );
await editor.update(() => { await editor.update(() => {
const selection = $getSelection() as RangeSelection; const selection = $getSelection() as RangeSelection;
@ -152,7 +152,7 @@ describe('LexicalHeadingNode tests', () => {
expect(result.getDirection()).toEqual(headingNode.getDirection()); expect(result.getDirection()).toEqual(headingNode.getDirection());
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h1 dir="ltr"><span data-lexical-text="true">hello</span><strong data-lexical-text="true"> world</strong></h1><p><br></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h1><span data-lexical-text="true">hello</span><strong data-lexical-text="true"> world</strong></h1><p><br></p></div>',
); );
}); });
@ -187,7 +187,7 @@ describe('LexicalHeadingNode tests', () => {
headingNode.append(textNode); headingNode.append(textNode);
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
`<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h2 dir="ltr"><span data-lexical-text="true">${text}</span></h2></div>`, `<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h2><span data-lexical-text="true">${text}</span></h2></div>`,
); );
await editor.update(() => { await editor.update(() => {
const result = headingNode.insertNewAfter(); const result = headingNode.insertNewAfter();
@ -195,7 +195,7 @@ describe('LexicalHeadingNode tests', () => {
expect(result.getDirection()).toEqual(headingNode.getDirection()); expect(result.getDirection()).toEqual(headingNode.getDirection());
}); });
expect(testEnv.outerHTML).toBe( expect(testEnv.outerHTML).toBe(
`<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h2 dir="ltr"><span data-lexical-text="true">${text}</span></h2><p><br></p></div>`, `<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h2><span data-lexical-text="true">${text}</span></h2><p><br></p></div>`,
); );
}); });
}); });

View File

@ -250,7 +250,7 @@ describe('LexicalSelection tests', () => {
const suite = [ const suite = [
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">Hello</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><span data-lexical-text="true">Hello</span></p></div>',
expectedSelection: { expectedSelection: {
anchorOffset: 5, anchorOffset: 5,
anchorPath: [0, 0, 0], anchorPath: [0, 0, 0],
@ -268,7 +268,7 @@ describe('LexicalSelection tests', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph">' +
'<strong class="editor-text-bold" data-lexical-text="true">Hello</strong></p></div>', '<strong class="editor-text-bold" data-lexical-text="true">Hello</strong></p></div>',
expectedSelection: { expectedSelection: {
anchorOffset: 5, anchorOffset: 5,
@ -288,7 +288,7 @@ describe('LexicalSelection tests', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph">' +
'<em class="editor-text-italic" data-lexical-text="true">Hello</em></p></div>', '<em class="editor-text-italic" data-lexical-text="true">Hello</em></p></div>',
expectedSelection: { expectedSelection: {
anchorOffset: 5, anchorOffset: 5,
@ -308,7 +308,7 @@ describe('LexicalSelection tests', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph">' +
'<strong class="editor-text-bold editor-text-italic" data-lexical-text="true">Hello</strong></p></div>', '<strong class="editor-text-bold editor-text-italic" data-lexical-text="true">Hello</strong></p></div>',
expectedSelection: { expectedSelection: {
anchorOffset: 5, anchorOffset: 5,
@ -329,7 +329,7 @@ describe('LexicalSelection tests', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph">' +
'<span class="editor-text-underline" data-lexical-text="true">Hello</span></p></div>', '<span class="editor-text-underline" data-lexical-text="true">Hello</span></p></div>',
expectedSelection: { expectedSelection: {
anchorOffset: 5, anchorOffset: 5,
@ -349,7 +349,7 @@ describe('LexicalSelection tests', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph">' +
'<span class="editor-text-strikethrough" data-lexical-text="true">Hello</span></p></div>', '<span class="editor-text-strikethrough" data-lexical-text="true">Hello</span></p></div>',
expectedSelection: { expectedSelection: {
anchorOffset: 5, anchorOffset: 5,
@ -369,7 +369,7 @@ describe('LexicalSelection tests', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph">' +
'<span class="editor-text-underlineStrikethrough" data-lexical-text="true">Hello</span></p></div>', '<span class="editor-text-underlineStrikethrough" data-lexical-text="true">Hello</span></p></div>',
expectedSelection: { expectedSelection: {
anchorOffset: 5, anchorOffset: 5,
@ -411,7 +411,7 @@ describe('LexicalSelection tests', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph">' +
'<span data-lexical-text="true">Dominic Gannaway</span>' + '<span data-lexical-text="true">Dominic Gannaway</span>' +
'</p></div>', '</p></div>',
expectedSelection: { expectedSelection: {
@ -425,7 +425,7 @@ describe('LexicalSelection tests', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph">' +
'<span data-lexical-text="true">Dominic Gannaway</span>' + '<span data-lexical-text="true">Dominic Gannaway</span>' +
'</p></div>', '</p></div>',
expectedSelection: { expectedSelection: {
@ -443,7 +443,7 @@ describe('LexicalSelection tests', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph">' +
'<span data-lexical-text="true">Dominic Gannaway</span>' + '<span data-lexical-text="true">Dominic Gannaway</span>' +
'</p></div>', '</p></div>',
expectedSelection: { expectedSelection: {
@ -457,7 +457,7 @@ describe('LexicalSelection tests', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph">' +
'<span data-lexical-text="true">Dominic Gannaway</span>' + '<span data-lexical-text="true">Dominic Gannaway</span>' +
'</p></div>', '</p></div>',
expectedSelection: { expectedSelection: {
@ -477,7 +477,7 @@ describe('LexicalSelection tests', () => {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">' +
'<p class="editor-paragraph"><br></p>' + '<p class="editor-paragraph"><br></p>' +
'<p class="editor-paragraph" dir="ltr">' + '<p class="editor-paragraph">' +
'<strong class="editor-text-bold" data-lexical-text="true">Hello world</strong>' + '<strong class="editor-text-bold" data-lexical-text="true">Hello world</strong>' +
'</p>' + '</p>' +
'<p class="editor-paragraph"><br></p>' + '<p class="editor-paragraph"><br></p>' +
@ -501,10 +501,10 @@ describe('LexicalSelection tests', () => {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">' +
'<p class="editor-paragraph"><br></p>' + '<p class="editor-paragraph"><br></p>' +
'<p class="editor-paragraph" dir="ltr">' + '<p class="editor-paragraph">' +
'<strong class="editor-text-bold" data-lexical-text="true">Hello</strong>' + '<strong class="editor-text-bold" data-lexical-text="true">Hello</strong>' +
'</p>' + '</p>' +
'<p class="editor-paragraph" dir="ltr">' + '<p class="editor-paragraph">' +
'<strong class="editor-text-bold" data-lexical-text="true">world</strong>' + '<strong class="editor-text-bold" data-lexical-text="true">world</strong>' +
'</p>' + '</p>' +
'<p class="editor-paragraph"><br></p>' + '<p class="editor-paragraph"><br></p>' +
@ -529,11 +529,11 @@ describe('LexicalSelection tests', () => {
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">' +
'<p class="editor-paragraph" dir="ltr">' + '<p class="editor-paragraph">' +
'<span data-lexical-text="true">He</span>' + '<span data-lexical-text="true">He</span>' +
'<strong class="editor-text-bold" data-lexical-text="true">llo</strong>' + '<strong class="editor-text-bold" data-lexical-text="true">llo</strong>' +
'</p>' + '</p>' +
'<p class="editor-paragraph" dir="ltr">' + '<p class="editor-paragraph">' +
'<strong class="editor-text-bold" data-lexical-text="true">wo</strong>' + '<strong class="editor-text-bold" data-lexical-text="true">wo</strong>' +
'<span data-lexical-text="true">rld</span>' + '<span data-lexical-text="true">rld</span>' +
'</p>' + '</p>' +
@ -557,7 +557,7 @@ describe('LexicalSelection tests', () => {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">' +
'<p class="editor-paragraph"><br></p>' + '<p class="editor-paragraph"><br></p>' +
'<p class="editor-paragraph" dir="ltr">' + '<p class="editor-paragraph">' +
'<span data-lexical-text="true">Hello </span>' + '<span data-lexical-text="true">Hello </span>' +
'<strong class="editor-text-bold" data-lexical-text="true">world</strong>' + '<strong class="editor-text-bold" data-lexical-text="true">world</strong>' +
'</p>' + '</p>' +
@ -582,7 +582,7 @@ describe('LexicalSelection tests', () => {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">' +
'<p class="editor-paragraph"><br></p>' + '<p class="editor-paragraph"><br></p>' +
'<p class="editor-paragraph" dir="ltr">' + '<p class="editor-paragraph">' +
'<strong class="editor-text-bold" data-lexical-text="true">Hello</strong>' + '<strong class="editor-text-bold" data-lexical-text="true">Hello</strong>' +
'<span data-lexical-text="true"> world</span>' + '<span data-lexical-text="true"> world</span>' +
'</p>' + '</p>' +
@ -608,7 +608,7 @@ describe('LexicalSelection tests', () => {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">' +
'<p class="editor-paragraph"><br></p>' + '<p class="editor-paragraph"><br></p>' +
'<p class="editor-paragraph" dir="ltr">' + '<p class="editor-paragraph">' +
'<strong class="editor-text-bold" data-lexical-text="true">Hello</strong><strong class="editor-text-bold" data-lexical-text="true"> world</strong>' + '<strong class="editor-text-bold" data-lexical-text="true">Hello</strong><strong class="editor-text-bold" data-lexical-text="true"> world</strong>' +
'</p>' + '</p>' +
'<p class="editor-paragraph"><br></p>' + '<p class="editor-paragraph"><br></p>' +
@ -634,7 +634,7 @@ describe('LexicalSelection tests', () => {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">' +
'<p class="editor-paragraph"><br></p>' + '<p class="editor-paragraph"><br></p>' +
'<p class="editor-paragraph" dir="ltr">' + '<p class="editor-paragraph">' +
'<strong class="editor-text-bold" data-lexical-text="true">Hello </strong><strong class="editor-text-bold" data-lexical-text="true">world</strong>' + '<strong class="editor-text-bold" data-lexical-text="true">Hello </strong><strong class="editor-text-bold" data-lexical-text="true">world</strong>' +
'</p>' + '</p>' +
'<p class="editor-paragraph"><br></p>' + '<p class="editor-paragraph"><br></p>' +
@ -660,7 +660,7 @@ describe('LexicalSelection tests', () => {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">' +
'<p class="editor-paragraph"><br></p>' + '<p class="editor-paragraph"><br></p>' +
'<p class="editor-paragraph" dir="ltr">' + '<p class="editor-paragraph">' +
'<strong class="editor-text-bold" data-lexical-text="true">Hello</strong><span data-lexical-text="true"> world</span>' + '<strong class="editor-text-bold" data-lexical-text="true">Hello</strong><span data-lexical-text="true"> world</span>' +
'</p>' + '</p>' +
'<p class="editor-paragraph"><br></p>' + '<p class="editor-paragraph"><br></p>' +
@ -686,7 +686,7 @@ describe('LexicalSelection tests', () => {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true">' +
'<p class="editor-paragraph"><br></p>' + '<p class="editor-paragraph"><br></p>' +
'<p class="editor-paragraph" dir="ltr">' + '<p class="editor-paragraph">' +
'<strong class="editor-text-bold" data-lexical-text="true">Hello </strong><strong class="editor-text-bold" data-lexical-text="true">beautiful</strong><strong class="editor-text-bold" data-lexical-text="true"> world</strong>' + '<strong class="editor-text-bold" data-lexical-text="true">Hello </strong><strong class="editor-text-bold" data-lexical-text="true">beautiful</strong><strong class="editor-text-bold" data-lexical-text="true"> world</strong>' +
'</p>' + '</p>' +
'<p class="editor-paragraph"><br></p>' + '<p class="editor-paragraph"><br></p>' +
@ -764,7 +764,7 @@ describe('LexicalSelection tests', () => {
}, },
].flatMap(({whitespaceCharacter, whitespaceName}) => [ ].flatMap(({whitespaceCharacter, whitespaceName}) => [
{ {
expectedHTML: `<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">Hello${printWhitespace( expectedHTML: `<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><span data-lexical-text="true">Hello${printWhitespace(
whitespaceCharacter, whitespaceCharacter,
)}</span></p></div>`, )}</span></p></div>`,
expectedSelection: { expectedSelection: {
@ -780,7 +780,7 @@ describe('LexicalSelection tests', () => {
name: `Type two words separated by a ${whitespaceName}, delete word backward from end`, name: `Type two words separated by a ${whitespaceName}, delete word backward from end`,
}, },
{ {
expectedHTML: `<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">${printWhitespace( expectedHTML: `<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><span data-lexical-text="true">${printWhitespace(
whitespaceCharacter, whitespaceCharacter,
)}world</span></p></div>`, )}world</span></p></div>`,
expectedSelection: { expectedSelection: {
@ -798,7 +798,7 @@ describe('LexicalSelection tests', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">Hello</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><span data-lexical-text="true">Hello</span></p></div>',
expectedSelection: { expectedSelection: {
anchorOffset: 5, anchorOffset: 5,
anchorPath: [0, 0, 0], anchorPath: [0, 0, 0],
@ -814,7 +814,7 @@ describe('LexicalSelection tests', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">world</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><span data-lexical-text="true">world</span></p></div>',
expectedSelection: { expectedSelection: {
anchorOffset: 0, anchorOffset: 0,
anchorPath: [0, 0, 0], anchorPath: [0, 0, 0],
@ -830,7 +830,7 @@ describe('LexicalSelection tests', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">Hello world</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><span data-lexical-text="true">Hello world</span></p></div>',
expectedSelection: { expectedSelection: {
anchorOffset: 11, anchorOffset: 11,
anchorPath: [0, 0, 0], anchorPath: [0, 0, 0],
@ -842,7 +842,7 @@ describe('LexicalSelection tests', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">Hello </span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><span data-lexical-text="true">Hello </span></p></div>',
expectedSelection: { expectedSelection: {
anchorOffset: 6, anchorOffset: 6,
anchorPath: [0, 0, 0], anchorPath: [0, 0, 0],
@ -859,7 +859,7 @@ describe('LexicalSelection tests', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph">' +
'<span data-lexical-text="true">this is weird test</span></p></div>', '<span data-lexical-text="true">this is weird test</span></p></div>',
expectedSelection: { expectedSelection: {
anchorOffset: 0, anchorOffset: 0,
@ -876,7 +876,7 @@ describe('LexicalSelection tests', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr">' + '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph">' +
'<span data-lexical-text="true">Hello </span>' + '<span data-lexical-text="true">Hello </span>' +
'<span data-lexical-text="true">Bob</span>' + '<span data-lexical-text="true">Bob</span>' +
'</p></div>', '</p></div>',
@ -897,7 +897,7 @@ describe('LexicalSelection tests', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">ABD</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">EFG</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><span data-lexical-text="true">ABD</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">EFG</span></p></div>',
expectedSelection: { expectedSelection: {
anchorOffset: 3, anchorOffset: 3,
anchorPath: [0, 0, 0], anchorPath: [0, 0, 0],
@ -1883,7 +1883,7 @@ describe('LexicalSelection tests', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">Hello </span><strong data-lexical-text="true">awesome</strong></p><p dir="ltr"><span data-lexical-text="true"> world</span></p>', '<p><span data-lexical-text="true">Hello </span><strong data-lexical-text="true">awesome</strong></p><p><span data-lexical-text="true"> world</span></p>',
); );
}); });
@ -1931,7 +1931,7 @@ describe('LexicalSelection tests', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">Hello </span><strong data-lexical-text="true">awesome </strong></p><p dir="ltr"><span data-lexical-text="true">beautiful</span><strong data-lexical-text="true"> world</strong></p>', '<p><span data-lexical-text="true">Hello </span><strong data-lexical-text="true">awesome </strong></p><p><span data-lexical-text="true">beautiful</span><strong data-lexical-text="true"> world</strong></p>',
); );
}); });

View File

@ -1827,7 +1827,7 @@ describe('LexicalSelectionHelpers tests', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">foo</span></p>', '<p><span data-lexical-text="true">foo</span></p>',
); );
}); });
@ -1868,7 +1868,7 @@ describe('LexicalSelectionHelpers tests', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">foobar</span></p>', '<p><span data-lexical-text="true">foobar</span></p>',
); );
}); });
@ -1913,7 +1913,7 @@ describe('LexicalSelectionHelpers tests', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">h</span><a href="https://" dir="ltr"><span data-lexical-text="true">ello worl</span></a><span data-lexical-text="true">d</span></p>', '<p><span data-lexical-text="true">h</span><a href="https://"><span data-lexical-text="true">ello worl</span></a><span data-lexical-text="true">d</span></p>',
); );
}); });
@ -1956,7 +1956,7 @@ describe('LexicalSelectionHelpers tests', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<h1 dir="ltr"><span data-lexical-text="true">foo</span></h1>', '<h1><span data-lexical-text="true">foo</span></h1>',
); );
}); });
}); });
@ -1999,7 +1999,7 @@ describe('LexicalSelectionHelpers tests', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">Existing text...foo</span></p>', '<p><span data-lexical-text="true">Existing text...foo</span></p>',
); );
}); });
@ -2044,7 +2044,7 @@ describe('LexicalSelectionHelpers tests', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">Existing text...foobar</span></p>', '<p><span data-lexical-text="true">Existing text...foobar</span></p>',
); );
}); });
@ -2091,7 +2091,7 @@ describe('LexicalSelectionHelpers tests', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">Existing text...foo</span></p>', '<p><span data-lexical-text="true">Existing text...foo</span></p>',
); );
}); });
@ -2162,7 +2162,7 @@ describe('LexicalSelectionHelpers tests', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">AB</span><em data-lexical-text="true">C</em><span data-lexical-text="true">DE</span></p>', '<p><span data-lexical-text="true">AB</span><em data-lexical-text="true">C</em><span data-lexical-text="true">DE</span></p>',
); );
}); });
}); });
@ -2205,7 +2205,7 @@ describe('LexicalSelectionHelpers tests', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">foo</span></p>', '<p><span data-lexical-text="true">foo</span></p>',
); );
}); });
}); });
@ -2252,7 +2252,7 @@ describe('LexicalSelectionHelpers tests', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">foo</span><a href="https://" dir="ltr"><span data-lexical-text="true">link</span></a></p>', '<p><span data-lexical-text="true">foo</span><a href="https://"><span data-lexical-text="true">link</span></a></p>',
); );
}); });
}); });
@ -2299,7 +2299,7 @@ describe('LexicalSelectionHelpers tests', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><a href="https://" dir="ltr"><span data-lexical-text="true">link</span></a><span data-lexical-text="true">foo</span></p>', '<p><a href="https://"><span data-lexical-text="true">link</span></a><span data-lexical-text="true">foo</span></p>',
); );
}); });
}); });
@ -2324,7 +2324,7 @@ describe('LexicalSelectionHelpers tests', () => {
// TODO #5109 ElementNode should have a way to control when other nodes can be inserted inside // TODO #5109 ElementNode should have a way to control when other nodes can be inserted inside
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p><a href="https://lexical.dev/" dir="ltr"><br><span data-lexical-text="true">Lexical</span></a></p>', '<p><a href="https://lexical.dev/"><br><span data-lexical-text="true">Lexical</span></a></p>',
); );
}); });
}); });
@ -2371,7 +2371,7 @@ describe('LexicalSelectionHelpers tests', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">foo</span></p>', '<p><span data-lexical-text="true">foo</span></p>',
); );
}); });
}); });
@ -2421,7 +2421,7 @@ describe('LexicalSelectionHelpers tests', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">foo</span><a href="https://" dir="ltr"><span data-lexical-text="true">link</span></a></p>', '<p><span data-lexical-text="true">foo</span><a href="https://"><span data-lexical-text="true">link</span></a></p>',
); );
}); });
}); });
@ -2471,7 +2471,7 @@ describe('LexicalSelectionHelpers tests', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><a href="https://" dir="ltr"><span data-lexical-text="true">link</span></a><span data-lexical-text="true">foo</span></p>', '<p><a href="https://"><span data-lexical-text="true">link</span></a><span data-lexical-text="true">foo</span></p>',
); );
}); });
}); });
@ -2491,7 +2491,7 @@ describe('LexicalSelectionHelpers tests', () => {
$insertNodes([linkNode]); $insertNodes([linkNode]);
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p><a href="https://lexical.dev" dir="ltr"><span data-lexical-text="true">Lexical</span></a></p>', '<p><a href="https://lexical.dev"><span data-lexical-text="true">Lexical</span></a></p>',
); );
}); });
@ -2511,7 +2511,7 @@ describe('LexicalSelectionHelpers tests', () => {
$insertNodes([linkNode, textNode2]); $insertNodes([linkNode, textNode2]);
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p><a href="https://lexical.dev" dir="ltr"><span data-lexical-text="true">Lexical</span></a><span data-lexical-text="true">...</span></p>', '<p><a href="https://lexical.dev"><span data-lexical-text="true">Lexical</span></a><span data-lexical-text="true">...</span></p>',
); );
}); });
@ -2604,9 +2604,9 @@ describe('insertNodes', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">Text before</span></p>' + '<p><span data-lexical-text="true">Text before</span></p>' +
'<span data-lexical-decorator="true" contenteditable="false"></span>' + '<span data-lexical-decorator="true" contenteditable="false"></span>' +
'<p dir="ltr"><span data-lexical-text="true">Text after</span></p>', '<p><span data-lexical-text="true">Text after</span></p>',
); );
}); });
@ -2678,7 +2678,7 @@ describe('insertNodes', () => {
}); });
editor.getEditorState().read(() => { editor.getEditorState().read(() => {
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<h1 dir="ltr"><span data-lexical-text="true">heading</span></h1><p><br></p>', '<h1><span data-lexical-text="true">heading</span></h1><p><br></p>',
); );
const selectedNode = ($getSelection() as RangeSelection).anchor.getNode(); const selectedNode = ($getSelection() as RangeSelection).anchor.getNode();
expect($isParagraphNode(selectedNode)).toBeTruthy(); expect($isParagraphNode(selectedNode)).toBeTruthy();
@ -2736,8 +2736,8 @@ describe('$patchStyleText', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">a</span>' + '<p><span data-lexical-text="true">a</span>' +
'<a href="https://" dir="ltr">' + '<a href="https://">' +
'<span style="text-emphasis: filled;" data-lexical-text="true">link</span>' + '<span style="text-emphasis: filled;" data-lexical-text="true">link</span>' +
'</a>' + '</a>' +
'<span style="text-emphasis: filled;" data-lexical-text="true">b</span></p>', '<span style="text-emphasis: filled;" data-lexical-text="true">b</span></p>',
@ -2789,8 +2789,8 @@ describe('$patchStyleText', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">a</span></p>' + '<p><span data-lexical-text="true">a</span></p>' +
'<p dir="ltr"><span style="text-emphasis: filled;" data-lexical-text="true">b</span></p>', '<p><span style="text-emphasis: filled;" data-lexical-text="true">b</span></p>',
); );
}); });
@ -2838,9 +2838,9 @@ describe('$patchStyleText', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr">' + '<p>' +
'<span style="text-emphasis: filled;" data-lexical-text="true">a</span>' + '<span style="text-emphasis: filled;" data-lexical-text="true">a</span>' +
'<a href="https://" dir="ltr">' + '<a href="https://">' +
'<span style="text-emphasis: filled;" data-lexical-text="true">link</span>' + '<span style="text-emphasis: filled;" data-lexical-text="true">link</span>' +
'</a>' + '</a>' +
'</p>', '</p>',
@ -2891,9 +2891,9 @@ describe('$patchStyleText', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr">' + '<p>' +
'<span style="text-emphasis: filled;" data-lexical-text="true">a</span>' + '<span style="text-emphasis: filled;" data-lexical-text="true">a</span>' +
'<a href="https://" dir="ltr">' + '<a href="https://">' +
'<span style="text-emphasis: filled;" data-lexical-text="true">link</span>' + '<span style="text-emphasis: filled;" data-lexical-text="true">link</span>' +
'</a>' + '</a>' +
'</p>', '</p>',
@ -2935,7 +2935,7 @@ describe('$patchStyleText', () => {
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p>' + '<p>' +
'<a href="https://" dir="ltr">' + '<a href="https://">' +
'<span style="text-emphasis: filled;" data-lexical-text="true">link</span>' + '<span style="text-emphasis: filled;" data-lexical-text="true">link</span>' +
'</a>' + '</a>' +
'</p>', '</p>',
@ -2976,7 +2976,7 @@ describe('$patchStyleText', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr"><span data-lexical-text="true">text</span></p>', '<p><span data-lexical-text="true">text</span></p>',
); );
}); });
@ -3115,7 +3115,7 @@ describe('$patchStyleText', () => {
}); });
expect(element.innerHTML).toBe( expect(element.innerHTML).toBe(
'<p dir="ltr">' + '<p>' +
'<strong data-lexical-text="true">fir</strong>' + '<strong data-lexical-text="true">fir</strong>' +
'<strong style="font-size: 15px;" data-lexical-text="true">st</strong>' + '<strong style="font-size: 15px;" data-lexical-text="true">st</strong>' +
'<span style="font-size: 15px;" data-lexical-text="true">second</span>' + '<span style="font-size: 15px;" data-lexical-text="true">second</span>' +

View File

@ -102,7 +102,7 @@ describe('LexicalTableNode tests', () => {
const dataTransfer = new DataTransferMock(); const dataTransfer = new DataTransferMock();
dataTransfer.setData( dataTransfer.setData(
'text/html', 'text/html',
'<html><body><meta charset="utf-8"><b style="font-weight:normal;" id="docs-internal-guid-16a69100-7fff-6cb9-b829-cb1def16a58d"><div dir="ltr" style="margin-left:0pt;" align="left"><table style="border:none;border-collapse:collapse;table-layout:fixed;width:468pt"><colgroup><col /><col /></colgroup><tbody><tr style="height:22.015pt"><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Hello there</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">General Kenobi!</span></p></td></tr><tr style="height:22.015pt"><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Lexical is nice</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><br /></td></tr></tbody></table></div></b><!--EndFragment--></body></html>', '<html><body><meta charset="utf-8"><b style="font-weight:normal;" id="docs-internal-guid-16a69100-7fff-6cb9-b829-cb1def16a58d"><div style="margin-left:0pt;" align="left"><table style="border:none;border-collapse:collapse;table-layout:fixed;width:468pt"><colgroup><col /><col /></colgroup><tbody><tr style="height:22.015pt"><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Hello there</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">General Kenobi!</span></p></td></tr><tr style="height:22.015pt"><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Lexical is nice</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><br /></td></tr></tbody></table></div></b><!--EndFragment--></body></html>',
); );
await editor.update(() => { await editor.update(() => {
const selection = $getSelection(); const selection = $getSelection();
@ -115,7 +115,7 @@ describe('LexicalTableNode tests', () => {
// Make sure paragraph is inserted inside empty cells // Make sure paragraph is inserted inside empty cells
const emptyCell = '<td><p><br></p></td>'; const emptyCell = '<td><p><br></p></td>';
expect(testEnv.innerHTML).toBe( expect(testEnv.innerHTML).toBe(
`<table><tr><td><p dir="ltr"><span data-lexical-text="true">Hello there</span></p></td><td><p dir="ltr"><span data-lexical-text="true">General Kenobi!</span></p></td></tr><tr><td><p dir="ltr"><span data-lexical-text="true">Lexical is nice</span></p></td>${emptyCell}</tr></table>`, `<table><tr><td><p><span data-lexical-text="true">Hello there</span></p></td><td><p><span data-lexical-text="true">General Kenobi!</span></p></td></tr><tr><td><p><span data-lexical-text="true">Lexical is nice</span></p></td>${emptyCell}</tr></table>`,
); );
}); });
@ -125,7 +125,7 @@ describe('LexicalTableNode tests', () => {
const dataTransfer = new DataTransferMock(); const dataTransfer = new DataTransferMock();
dataTransfer.setData( dataTransfer.setData(
'text/html', 'text/html',
'<google-sheets-html-origin><style type="text/css"><!--td {border: 1px solid #cccccc;}br {mso-data-placement:same-cell;}--></style><table xmlns="http://www.w3.org/1999/xhtml" cellspacing="0" cellpadding="0" dir="ltr" border="1" style="table-layout:fixed;font-size:10pt;font-family:Arial;width:0px;border-collapse:collapse;border:none" data-sheets-root="1"><colgroup><col width="100"/><col width="189"/><col width="171"/></colgroup><tbody><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;font-weight:bold;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Surface&quot;}">Surface</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;font-style:italic;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;MWP_WORK_LS_COMPOSER&quot;}">MWP_WORK_LS_COMPOSER</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-decoration:underline;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:77349}">77349</td></tr><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Lexical&quot;}">Lexical</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-decoration:line-through;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;XDS_RICH_TEXT_AREA&quot;}">XDS_RICH_TEXT_AREA</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;sdvd sdfvsfs&quot;}" data-sheets-textstyleruns="{&quot;1&quot;:0}{&quot;1&quot;:5,&quot;2&quot;:{&quot;5&quot;:1}}"><span style="font-size:10pt;font-family:Arial;font-style:normal;">sdvd </span><span style="font-size:10pt;font-family:Arial;font-weight:bold;font-style:normal;">sdfvsfs</span></td></tr></tbody></table>', '<google-sheets-html-origin><style type="text/css"><!--td {border: 1px solid #cccccc;}br {mso-data-placement:same-cell;}--></style><table xmlns="http://www.w3.org/1999/xhtml" cellspacing="0" cellpadding="0" border="1" style="table-layout:fixed;font-size:10pt;font-family:Arial;width:0px;border-collapse:collapse;border:none" data-sheets-root="1"><colgroup><col width="100"/><col width="189"/><col width="171"/></colgroup><tbody><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;font-weight:bold;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Surface&quot;}">Surface</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;font-style:italic;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;MWP_WORK_LS_COMPOSER&quot;}">MWP_WORK_LS_COMPOSER</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-decoration:underline;text-align:right;" data-sheets-value="{&quot;1&quot;:3,&quot;3&quot;:77349}">77349</td></tr><tr style="height:21px;"><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Lexical&quot;}">Lexical</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;text-decoration:line-through;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;XDS_RICH_TEXT_AREA&quot;}">XDS_RICH_TEXT_AREA</td><td style="overflow:hidden;padding:2px 3px 2px 3px;vertical-align:bottom;" data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;sdvd sdfvsfs&quot;}" data-sheets-textstyleruns="{&quot;1&quot;:0}{&quot;1&quot;:5,&quot;2&quot;:{&quot;5&quot;:1}}"><span style="font-size:10pt;font-family:Arial;font-style:normal;">sdvd </span><span style="font-size:10pt;font-family:Arial;font-weight:bold;font-style:normal;">sdfvsfs</span></td></tr></tbody></table>',
); );
await editor.update(() => { await editor.update(() => {
const selection = $getSelection(); const selection = $getSelection();
@ -136,7 +136,7 @@ describe('LexicalTableNode tests', () => {
$insertDataTransferForRichText(dataTransfer, selection, editor); $insertDataTransferForRichText(dataTransfer, selection, editor);
}); });
expect(testEnv.innerHTML).toBe( expect(testEnv.innerHTML).toBe(
`<table><tr style="height: 21px;"><td><p dir="ltr"><strong data-lexical-text="true">Surface</strong></p></td><td><p dir="ltr"><em data-lexical-text="true">MWP_WORK_LS_COMPOSER</em></p></td><td><p style="text-align: right;"><span data-lexical-text="true">77349</span></p></td></tr><tr style="height: 21px;"><td><p dir="ltr"><span data-lexical-text="true">Lexical</span></p></td><td><p dir="ltr"><span data-lexical-text="true">XDS_RICH_TEXT_AREA</span></p></td><td><p dir="ltr"><span data-lexical-text="true">sdvd </span><strong data-lexical-text="true">sdfvsfs</strong></p></td></tr></table>`, `<table><tr style="height: 21px;"><td><p><strong data-lexical-text="true">Surface</strong></p></td><td><p><em data-lexical-text="true">MWP_WORK_LS_COMPOSER</em></p></td><td><p style="text-align: right;"><span data-lexical-text="true">77349</span></p></td></tr><tr style="height: 21px;"><td><p><span data-lexical-text="true">Lexical</span></p></td><td><p><span data-lexical-text="true">XDS_RICH_TEXT_AREA</span></p></td><td><p><span data-lexical-text="true">sdvd </span><strong data-lexical-text="true">sdfvsfs</strong></p></td></tr></table>`,
); );
}); });
}, },

View File

@ -99,7 +99,7 @@ describe('table selection', () => {
it('Parses the nodes of a stringified editor state', async () => { it('Parses the nodes of a stringified editor state', async () => {
expect(parsedRoot).toEqual({ expect(parsedRoot).toEqual({
__cachedText: null, __cachedText: null,
__dir: 'ltr', __dir: null,
__first: paragraphKey, __first: paragraphKey,
__format: 0, __format: 0,
__indent: 0, __indent: 0,
@ -113,7 +113,7 @@ describe('table selection', () => {
__type: 'root', __type: 'root',
}); });
expect(parsedParagraph).toEqual({ expect(parsedParagraph).toEqual({
__dir: 'ltr', __dir: null,
__first: textKey, __first: textKey,
__format: 0, __format: 0,
__indent: 0, __indent: 0,

View File

@ -156,25 +156,25 @@ describe('LexicalEventHelpers', () => {
const suite = [ const suite = [
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h1 class="editor-heading-h1" dir="ltr"><span data-lexical-text="true">Hello</span></h1></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h1 class="editor-heading-h1"><span data-lexical-text="true">Hello</span></h1></div>',
inputs: [pasteHTML(`<meta charset='utf-8'><h1>Hello</h1>`)], inputs: [pasteHTML(`<meta charset='utf-8'><h1>Hello</h1>`)],
name: 'should produce the correct editor state from a pasted HTML h1 element', name: 'should produce the correct editor state from a pasted HTML h1 element',
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h2 class="editor-heading-h2" dir="ltr"><span data-lexical-text="true">From</span></h2></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h2 class="editor-heading-h2"><span data-lexical-text="true">From</span></h2></div>',
inputs: [pasteHTML(`<meta charset='utf-8'><h2>From</h2>`)], inputs: [pasteHTML(`<meta charset='utf-8'><h2>From</h2>`)],
name: 'should produce the correct editor state from a pasted HTML h2 element', name: 'should produce the correct editor state from a pasted HTML h2 element',
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h3 class="editor-heading-h3" dir="ltr"><span data-lexical-text="true">The</span></h3></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h3 class="editor-heading-h3"><span data-lexical-text="true">The</span></h3></div>',
inputs: [pasteHTML(`<meta charset='utf-8'><h3>The</h3>`)], inputs: [pasteHTML(`<meta charset='utf-8'><h3>The</h3>`)],
name: 'should produce the correct editor state from a pasted HTML h3 element', name: 'should produce the correct editor state from a pasted HTML h3 element',
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><ul class="editor-list-ul"><li value="1" class="editor-listitem" dir="ltr"><span data-lexical-text="true">Other side</span></li><li value="2" class="editor-listitem" dir="ltr"><span data-lexical-text="true">I must have called</span></li></ul></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><ul class="editor-list-ul"><li value="1" class="editor-listitem"><span data-lexical-text="true">Other side</span></li><li value="2" class="editor-listitem"><span data-lexical-text="true">I must have called</span></li></ul></div>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
`<meta charset='utf-8'><ul><li>Other side</li><li>I must have called</li></ul>`, `<meta charset='utf-8'><ul><li>Other side</li><li>I must have called</li></ul>`,
@ -184,7 +184,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><ol class="editor-list-ol"><li value="1" class="editor-listitem" dir="ltr"><span data-lexical-text="true">To tell you</span></li><li value="2" class="editor-listitem" dir="ltr"><span data-lexical-text="true">Im sorry</span></li></ol></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><ol class="editor-list-ol"><li value="1" class="editor-listitem"><span data-lexical-text="true">To tell you</span></li><li value="2" class="editor-listitem"><span data-lexical-text="true">Im sorry</span></li></ol></div>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
`<meta charset='utf-8'><ol><li>To tell you</li><li>Im sorry</li></ol>`, `<meta charset='utf-8'><ol><li>To tell you</li><li>Im sorry</li></ol>`,
@ -194,37 +194,37 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">A thousand times</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><span data-lexical-text="true">A thousand times</span></p></div>',
inputs: [pasteHTML(`<meta charset='utf-8'>A thousand times`)], inputs: [pasteHTML(`<meta charset='utf-8'>A thousand times`)],
name: 'should produce the correct editor state from pasted DOM Text Node', name: 'should produce the correct editor state from pasted DOM Text Node',
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><strong class="editor-text-bold" data-lexical-text="true">Bold</strong></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><strong class="editor-text-bold" data-lexical-text="true">Bold</strong></p></div>',
inputs: [pasteHTML(`<meta charset='utf-8'><b>Bold</b>`)], inputs: [pasteHTML(`<meta charset='utf-8'><b>Bold</b>`)],
name: 'should produce the correct editor state from a pasted HTML b element', name: 'should produce the correct editor state from a pasted HTML b element',
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><em class="editor-text-italic" data-lexical-text="true">Italic</em></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><em class="editor-text-italic" data-lexical-text="true">Italic</em></p></div>',
inputs: [pasteHTML(`<meta charset='utf-8'><i>Italic</i>`)], inputs: [pasteHTML(`<meta charset='utf-8'><i>Italic</i>`)],
name: 'should produce the correct editor state from a pasted HTML i element', name: 'should produce the correct editor state from a pasted HTML i element',
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><em class="editor-text-italic" data-lexical-text="true">Italic</em></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><em class="editor-text-italic" data-lexical-text="true">Italic</em></p></div>',
inputs: [pasteHTML(`<meta charset='utf-8'><em>Italic</em>`)], inputs: [pasteHTML(`<meta charset='utf-8'><em>Italic</em>`)],
name: 'should produce the correct editor state from a pasted HTML em element', name: 'should produce the correct editor state from a pasted HTML em element',
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><span class="editor-text-underline" data-lexical-text="true">Underline</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><span class="editor-text-underline" data-lexical-text="true">Underline</span></p></div>',
inputs: [pasteHTML(`<meta charset='utf-8'><u>Underline</u>`)], inputs: [pasteHTML(`<meta charset='utf-8'><u>Underline</u>`)],
name: 'should produce the correct editor state from a pasted HTML u element', name: 'should produce the correct editor state from a pasted HTML u element',
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h1 class="editor-heading-h1" dir="ltr"><span data-lexical-text="true">Lyrics to Hello by Adele</span></h1><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">A thousand times</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><h1 class="editor-heading-h1"><span data-lexical-text="true">Lyrics to Hello by Adele</span></h1><p class="editor-paragraph"><span data-lexical-text="true">A thousand times</span></p></div>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
`<meta charset='utf-8'><h1>Lyrics to Hello by Adele</h1>A thousand times`, `<meta charset='utf-8'><h1>Lyrics to Hello by Adele</h1>A thousand times`,
@ -234,7 +234,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><a href="https://facebook.com" dir="ltr"><span data-lexical-text="true">Facebook</span></a></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><a href="https://facebook.com"><span data-lexical-text="true">Facebook</span></a></p></div>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
`<meta charset='utf-8'><a href="https://facebook.com">Facebook</a>`, `<meta charset='utf-8'><a href="https://facebook.com">Facebook</a>`,
@ -244,7 +244,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">Welcome to</span><a href="https://facebook.com" dir="ltr"><span data-lexical-text="true">Facebook!</span></a></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><span data-lexical-text="true">Welcome to</span><a href="https://facebook.com"><span data-lexical-text="true">Facebook!</span></a></p></div>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
`<meta charset='utf-8'>Welcome to<a href="https://facebook.com">Facebook!</a>`, `<meta charset='utf-8'>Welcome to<a href="https://facebook.com">Facebook!</a>`,
@ -254,7 +254,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">Welcome to</span><a href="https://facebook.com" dir="ltr"><span data-lexical-text="true">Facebook!</span></a><span data-lexical-text="true">We hope you like it here.</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><span data-lexical-text="true">Welcome to</span><a href="https://facebook.com"><span data-lexical-text="true">Facebook!</span></a><span data-lexical-text="true">We hope you like it here.</span></p></div>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
`<meta charset='utf-8'>Welcome to<a href="https://facebook.com">Facebook!</a>We hope you like it here.`, `<meta charset='utf-8'>Welcome to<a href="https://facebook.com">Facebook!</a>We hope you like it here.`,
@ -264,7 +264,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><ul class="editor-list-ul"><li value="1" class="editor-listitem" dir="ltr"><span data-lexical-text="true">Hello</span></li><li value="2" class="editor-listitem" dir="ltr"><span data-lexical-text="true">from the other</span></li><li value="3" class="editor-listitem" dir="ltr"><span data-lexical-text="true">side</span></li></ul></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><ul class="editor-list-ul"><li value="1" class="editor-listitem"><span data-lexical-text="true">Hello</span></li><li value="2" class="editor-listitem"><span data-lexical-text="true">from the other</span></li><li value="3" class="editor-listitem"><span data-lexical-text="true">side</span></li></ul></div>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
`<meta charset='utf-8'><doesnotexist><ul><li>Hello</li><li>from the other</li><li>side</li></ul></doesnotexist>`, `<meta charset='utf-8'><doesnotexist><ul><li>Hello</li><li>from the other</li><li>side</li></ul></doesnotexist>`,
@ -274,7 +274,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><ul class="editor-list-ul"><li value="1" class="editor-listitem" dir="ltr"><span data-lexical-text="true">Hello</span></li><li value="2" class="editor-listitem" dir="ltr"><span data-lexical-text="true">from the other</span></li><li value="3" class="editor-listitem" dir="ltr"><span data-lexical-text="true">side</span></li></ul></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><ul class="editor-list-ul"><li value="1" class="editor-listitem"><span data-lexical-text="true">Hello</span></li><li value="2" class="editor-listitem"><span data-lexical-text="true">from the other</span></li><li value="3" class="editor-listitem"><span data-lexical-text="true">side</span></li></ul></div>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
`<meta charset='utf-8'><doesnotexist><doesnotexist><ul><li>Hello</li><li>from the other</li><li>side</li></ul></doesnotexist></doesnotexist>`, `<meta charset='utf-8'><doesnotexist><doesnotexist><ul><li>Hello</li><li>from the other</li><li>side</li></ul></doesnotexist></doesnotexist>`,
@ -284,7 +284,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">Welcome to</span><a href="https://facebook.com" dir="ltr"><strong class="editor-text-bold" data-lexical-text="true">Facebook!</strong></a><span data-lexical-text="true">We hope you like it here.</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><span data-lexical-text="true">Welcome to</span><a href="https://facebook.com"><strong class="editor-text-bold" data-lexical-text="true">Facebook!</strong></a><span data-lexical-text="true">We hope you like it here.</span></p></div>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
`<meta charset='utf-8'>Welcome to<b><a href="https://facebook.com">Facebook!</a></b>We hope you like it here.`, `<meta charset='utf-8'>Welcome to<b><a href="https://facebook.com">Facebook!</a></b>We hope you like it here.`,
@ -294,7 +294,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">Welcome to</span><a href="https://facebook.com" dir="ltr"><strong class="editor-text-bold" data-lexical-text="true">Facebook!</strong></a><strong class="editor-text-bold" data-lexical-text="true">We hope you like it here.</strong></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><span data-lexical-text="true">Welcome to</span><a href="https://facebook.com"><strong class="editor-text-bold" data-lexical-text="true">Facebook!</strong></a><strong class="editor-text-bold" data-lexical-text="true">We hope you like it here.</strong></p></div>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
`<meta charset='utf-8'>Welcome to<b><a href="https://facebook.com">Facebook!</a>We hope you like it here.</b>`, `<meta charset='utf-8'>Welcome to<b><a href="https://facebook.com">Facebook!</a>We hope you like it here.</b>`,
@ -304,7 +304,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">Welcome to</span><a href="https://facebook.com" dir="ltr"><strong class="editor-text-bold editor-text-italic" data-lexical-text="true">Facebook!</strong></a><strong class="editor-text-bold editor-text-italic" data-lexical-text="true">We hope you like it here.</strong></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><span data-lexical-text="true">Welcome to</span><a href="https://facebook.com"><strong class="editor-text-bold editor-text-italic" data-lexical-text="true">Facebook!</strong></a><strong class="editor-text-bold editor-text-italic" data-lexical-text="true">We hope you like it here.</strong></p></div>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
`<meta charset='utf-8'>Welcome to<b><i><a href="https://facebook.com">Facebook!</a>We hope you like it here.</i></b>`, `<meta charset='utf-8'>Welcome to<b><i><a href="https://facebook.com">Facebook!</a>We hope you like it here.</i></b>`,
@ -330,7 +330,7 @@ describe('LexicalEventHelpers', () => {
const suite = [ const suite = [
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">Get schwifty!</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><span data-lexical-text="true">Get schwifty!</span></p></div>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
`<b style="font-weight:normal;" id="docs-internal-guid-2c706577-7fff-f54a-fe65-12f480020fac"><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Get schwifty!</span></b>`, `<b style="font-weight:normal;" id="docs-internal-guid-2c706577-7fff-f54a-fe65-12f480020fac"><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Get schwifty!</span></b>`,
@ -340,7 +340,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><strong class="editor-text-bold" data-lexical-text="true">Get schwifty!</strong></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><strong class="editor-text-bold" data-lexical-text="true">Get schwifty!</strong></p></div>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
`<b style="font-weight:normal;" id="docs-internal-guid-9db03964-7fff-c26c-8b1e-9484fb3b54a4"><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Get schwifty!</span></b>`, `<b style="font-weight:normal;" id="docs-internal-guid-9db03964-7fff-c26c-8b1e-9484fb3b54a4"><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:700;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Get schwifty!</span></b>`,
@ -350,7 +350,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><em class="editor-text-italic" data-lexical-text="true">Get schwifty!</em></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><em class="editor-text-italic" data-lexical-text="true">Get schwifty!</em></p></div>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
`<b style="font-weight:normal;" id="docs-internal-guid-9db03964-7fff-c26c-8b1e-9484fb3b54a4"><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:italic;font-variant:normal;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Get schwifty!</span></b>`, `<b style="font-weight:normal;" id="docs-internal-guid-9db03964-7fff-c26c-8b1e-9484fb3b54a4"><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:italic;font-variant:normal;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Get schwifty!</span></b>`,
@ -360,7 +360,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph" dir="ltr"><span class="editor-text-strikethrough" data-lexical-text="true">Get schwifty!</span></p></div>', '<div contenteditable="true" style="user-select: text; white-space: pre-wrap; word-break: break-word;" data-lexical-editor="true"><p class="editor-paragraph"><span class="editor-text-strikethrough" data-lexical-text="true">Get schwifty!</span></p></div>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
`<b style="font-weight:normal;" id="docs-internal-guid-9db03964-7fff-c26c-8b1e-9484fb3b54a4"><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:line-through;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Get schwifty!</span></b>`, `<b style="font-weight:normal;" id="docs-internal-guid-9db03964-7fff-c26c-8b1e-9484fb3b54a4"><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:line-through;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Get schwifty!</span></b>`,
@ -386,20 +386,20 @@ describe('LexicalEventHelpers', () => {
const suite = [ const suite = [
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">hello world</span></p>', '<p class="editor-paragraph"><span data-lexical-text="true">hello world</span></p>',
inputs: [pasteHTML('<span>hello world</span>')], inputs: [pasteHTML('<span>hello world</span>')],
name: 'inline hello world', name: 'inline hello world',
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">hello world</span></p>', '<p class="editor-paragraph"><span data-lexical-text="true">hello world</span></p>',
inputs: [pasteHTML('<span> hello </span>world ')], inputs: [pasteHTML('<span> hello </span>world ')],
name: 'inline hello world (2)', name: 'inline hello world (2)',
}, },
{ {
// MS Office got it right // MS Office got it right
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true"> hello world</span></p>', '<p class="editor-paragraph"><span data-lexical-text="true"> hello world</span></p>',
inputs: [ inputs: [
pasteHTML(' <span style="white-space: pre"> hello </span> world '), pasteHTML(' <span style="white-space: pre"> hello </span> world '),
], ],
@ -407,19 +407,19 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true"> a b</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">c </span></p>', '<p class="editor-paragraph"><span data-lexical-text="true"> a b</span><span data-lexical-text="true">\t</span><span data-lexical-text="true">c </span></p>',
inputs: [pasteHTML('<p style="white-space: pre"> a b\tc </p>')], inputs: [pasteHTML('<p style="white-space: pre"> a b\tc </p>')],
name: 'white-space: pre (1) (no touchy)', name: 'white-space: pre (1) (no touchy)',
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">a b c</span></p>', '<p class="editor-paragraph"><span data-lexical-text="true">a b c</span></p>',
inputs: [pasteHTML('<p>\ta\tb <span>c\t</span>\t</p>')], inputs: [pasteHTML('<p>\ta\tb <span>c\t</span>\t</p>')],
name: 'tabs are collapsed', name: 'tabs are collapsed',
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">hello world</span></p>', '<p class="editor-paragraph"><span data-lexical-text="true">hello world</span></p>',
inputs: [ inputs: [
pasteHTML(` pasteHTML(`
<div> <div>
@ -432,7 +432,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><strong class="editor-text-bold" data-lexical-text="true">hello world</strong></p>', '<p class="editor-paragraph"><strong class="editor-text-bold" data-lexical-text="true">hello world</strong></p>',
inputs: [ inputs: [
pasteHTML(` pasteHTML(`
<div> <div>
@ -447,7 +447,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">a </span><strong class="editor-text-bold" data-lexical-text="true">b</strong><span data-lexical-text="true"> c</span></p>', '<p class="editor-paragraph"><span data-lexical-text="true">a </span><strong class="editor-text-bold" data-lexical-text="true">b</strong><span data-lexical-text="true"> c</span></p>',
inputs: [ inputs: [
pasteHTML(` pasteHTML(`
<div> <div>
@ -461,25 +461,25 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><strong class="editor-text-bold" data-lexical-text="true">a </strong><span data-lexical-text="true">b</span></p>', '<p class="editor-paragraph"><strong class="editor-text-bold" data-lexical-text="true">a </strong><span data-lexical-text="true">b</span></p>',
inputs: [pasteHTML('<div><strong>a </strong>b</div>')], inputs: [pasteHTML('<div><strong>a </strong>b</div>')],
name: 'collapsibles and neighbors (1)', name: 'collapsibles and neighbors (1)',
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">a</span><strong class="editor-text-bold" data-lexical-text="true"> b</strong></p>', '<p class="editor-paragraph"><span data-lexical-text="true">a</span><strong class="editor-text-bold" data-lexical-text="true"> b</strong></p>',
inputs: [pasteHTML('<div>a<strong> b</strong></div>')], inputs: [pasteHTML('<div>a<strong> b</strong></div>')],
name: 'collapsibles and neighbors (2)', name: 'collapsibles and neighbors (2)',
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><strong class="editor-text-bold" data-lexical-text="true">a </strong><span data-lexical-text="true">b</span></p>', '<p class="editor-paragraph"><strong class="editor-text-bold" data-lexical-text="true">a </strong><span data-lexical-text="true">b</span></p>',
inputs: [pasteHTML('<div><strong>a </strong><span></span>b</div>')], inputs: [pasteHTML('<div><strong>a </strong><span></span>b</div>')],
name: 'collapsibles and neighbors (3)', name: 'collapsibles and neighbors (3)',
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">a</span><strong class="editor-text-bold" data-lexical-text="true"> b</strong></p>', '<p class="editor-paragraph"><span data-lexical-text="true">a</span><strong class="editor-text-bold" data-lexical-text="true"> b</strong></p>',
inputs: [pasteHTML('<div>a<span></span><strong> b</strong></div>')], inputs: [pasteHTML('<div>a<span></span><strong> b</strong></div>')],
name: 'collapsibles and neighbors (4)', name: 'collapsibles and neighbors (4)',
}, },
@ -495,19 +495,19 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">a</span></p>', '<p class="editor-paragraph"><span data-lexical-text="true">a</span></p>',
inputs: [pasteHTML('<span> </span><span>a</span>')], inputs: [pasteHTML('<span> </span><span>a</span>')],
name: 'redundant inline at start', name: 'redundant inline at start',
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">a</span></p>', '<p class="editor-paragraph"><span data-lexical-text="true">a</span></p>',
inputs: [pasteHTML('<span>a</span><span> </span>')], inputs: [pasteHTML('<span>a</span><span> </span>')],
name: 'redundant inline at end', name: 'redundant inline at end',
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">a</span></p><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">b</span></p>', '<p class="editor-paragraph"><span data-lexical-text="true">a</span></p><p class="editor-paragraph"><span data-lexical-text="true">b</span></p>',
inputs: [ inputs: [
pasteHTML(` pasteHTML(`
<div> <div>
@ -524,7 +524,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><strong class="editor-text-bold" data-lexical-text="true">a b</strong></p>', '<p class="editor-paragraph"><strong class="editor-text-bold" data-lexical-text="true">a b</strong></p>',
inputs: [ inputs: [
pasteHTML(` pasteHTML(`
<div> <div>
@ -541,7 +541,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">a</span><br><span data-lexical-text="true">b</span></p>', '<p class="editor-paragraph"><span data-lexical-text="true">a</span><br><span data-lexical-text="true">b</span></p>',
inputs: [ inputs: [
pasteHTML(` pasteHTML(`
<p> <p>
@ -555,7 +555,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">a</span><br><span data-lexical-text="true">b</span></p>', '<p class="editor-paragraph"><span data-lexical-text="true">a</span><br><span data-lexical-text="true">b</span></p>',
inputs: [ inputs: [
pasteHTML(` pasteHTML(`
<p> <p>
@ -569,7 +569,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">paragraph1</span></p><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">paragraph2</span></p>', '<p class="editor-paragraph"><span data-lexical-text="true">paragraph1</span></p><p class="editor-paragraph"><span data-lexical-text="true">paragraph2</span></p>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
'\n<p class="p1">paragraph1</p>\n<p class="p1">paragraph2</p>\n', '\n<p class="p1">paragraph1</p>\n<p class="p1">paragraph2</p>\n',
@ -579,7 +579,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">line 1</span><br><span data-lexical-text="true">line 2</span></p><p class="editor-paragraph"><br></p><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">paragraph 1</span></p><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">paragraph 2</span></p>', '<p class="editor-paragraph"><span data-lexical-text="true">line 1</span><br><span data-lexical-text="true">line 2</span></p><p class="editor-paragraph"><br></p><p class="editor-paragraph"><span data-lexical-text="true">paragraph 1</span></p><p class="editor-paragraph"><span data-lexical-text="true">paragraph 2</span></p>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
'\n<p class="p1">line 1<br>\nline 2</p>\n<p class="p2"><br></p>\n<p class="p1">paragraph 1</p>\n<p class="p1">paragraph 2</p>\n', '\n<p class="p1">line 1<br>\nline 2</p>\n<p class="p2"><br></p>\n<p class="p1">paragraph 1</p>\n<p class="p1">paragraph 2</p>\n',
@ -589,7 +589,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">line 1</span><br><span data-lexical-text="true">line 2</span></p><p class="editor-paragraph"><br></p><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">paragraph 1</span></p><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">paragraph 2</span></p>', '<p class="editor-paragraph"><span data-lexical-text="true">line 1</span><br><span data-lexical-text="true">line 2</span></p><p class="editor-paragraph"><br></p><p class="editor-paragraph"><span data-lexical-text="true">paragraph 1</span></p><p class="editor-paragraph"><span data-lexical-text="true">paragraph 2</span></p>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
'\n<p class="p1">line 1<br>\nline 2</p>\n<p class="p2">\n<br>\n</p>\n<p class="p1">paragraph 1</p>\n<p class="p1">paragraph 2</p>\n', '\n<p class="p1">line 1<br>\nline 2</p>\n<p class="p2">\n<br>\n</p>\n<p class="p1">paragraph 1</p>\n<p class="p1">paragraph 2</p>\n',
@ -599,7 +599,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">line 1</span><br><span data-lexical-text="true">line 2</span></p>', '<p class="editor-paragraph"><span data-lexical-text="true">line 1</span><br><span data-lexical-text="true">line 2</span></p>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
'<p class="p1"><span>line 1</span><span><br></span><span>line 2</span></p>', '<p class="p1"><span>line 1</span><span><br></span><span>line 2</span></p>',
@ -635,7 +635,7 @@ describe('LexicalEventHelpers', () => {
}, },
{ {
expectedHTML: expectedHTML:
'<p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">a</span></p><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">b b</span></p><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">c</span></p><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">z</span></p><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">d e</span></p><p class="editor-paragraph" dir="ltr"><span data-lexical-text="true">fg</span></p>', '<p class="editor-paragraph"><span data-lexical-text="true">a</span></p><p class="editor-paragraph"><span data-lexical-text="true">b b</span></p><p class="editor-paragraph"><span data-lexical-text="true">c</span></p><p class="editor-paragraph"><span data-lexical-text="true">z</span></p><p class="editor-paragraph"><span data-lexical-text="true">d e</span></p><p class="editor-paragraph"><span data-lexical-text="true">fg</span></p>',
inputs: [ inputs: [
pasteHTML( pasteHTML(
`<div>a<div>b b<div>c<div><div></div>z</div></div>d e</div>fg</div>`, `<div>a<div>b b<div>c<div><div></div>z</div></div>d e</div>fg</div>`,

View File

@ -1,10 +1,12 @@
import {LexicalNode, Spread} from "lexical"; import {LexicalNode, Spread} from "lexical";
import type {SerializedElementNode} from "lexical/nodes/LexicalElementNode"; 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' | ''; export type CommonBlockAlignment = 'left' | 'right' | 'center' | 'justify' | '';
const validAlignments: CommonBlockAlignment[] = ['left', 'right', 'center', 'justify']; const validAlignments: CommonBlockAlignment[] = ['left', 'right', 'center', 'justify'];
type EditorNodeDirection = 'ltr' | 'rtl' | null;
export type SerializedCommonBlockNode = Spread<{ export type SerializedCommonBlockNode = Spread<{
id: string; id: string;
alignment: CommonBlockAlignment; alignment: CommonBlockAlignment;
@ -29,7 +31,13 @@ export interface NodeHasInset {
getInset(): number; 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 { export function extractAlignmentFromElement(element: HTMLElement): CommonBlockAlignment {
const textAlignStyle: string = element.style.textAlign || ''; const textAlignStyle: string = element.style.textAlign || '';
@ -55,6 +63,15 @@ export function extractInsetFromElement(element: HTMLElement): number {
return sizeToPixels(elemPadding); 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 { export function setCommonBlockPropsFromElement(element: HTMLElement, node: CommonBlockInterface): void {
if (element.id) { if (element.id) {
node.setId(element.id); node.setId(element.id);
@ -62,12 +79,14 @@ export function setCommonBlockPropsFromElement(element: HTMLElement, node: Commo
node.setAlignment(extractAlignmentFromElement(element)); node.setAlignment(extractAlignmentFromElement(element));
node.setInset(extractInsetFromElement(element)); node.setInset(extractInsetFromElement(element));
node.setDirection(extractDirectionFromElement(element));
} }
export function commonPropertiesDifferent(nodeA: CommonBlockInterface, nodeB: CommonBlockInterface): boolean { export function commonPropertiesDifferent(nodeA: CommonBlockInterface, nodeB: CommonBlockInterface): boolean {
return nodeA.__id !== nodeB.__id || return nodeA.__id !== nodeB.__id ||
nodeA.__alignment !== nodeB.__alignment || nodeA.__alignment !== nodeB.__alignment ||
nodeA.__inset !== nodeB.__inset; nodeA.__inset !== nodeB.__inset ||
nodeA.__dir !== nodeB.__dir;
} }
export function updateElementWithCommonBlockProps(element: HTMLElement, node: CommonBlockInterface): void { export function updateElementWithCommonBlockProps(element: HTMLElement, node: CommonBlockInterface): void {
@ -82,12 +101,17 @@ export function updateElementWithCommonBlockProps(element: HTMLElement, node: Co
if (node.__inset) { if (node.__inset) {
element.style.paddingLeft = `${node.__inset}px`; element.style.paddingLeft = `${node.__inset}px`;
} }
if (node.__dir) {
element.dir = node.__dir;
}
} }
export function deserializeCommonBlockNode(serializedNode: SerializedCommonBlockNode, node: CommonBlockInterface): void { export function deserializeCommonBlockNode(serializedNode: SerializedCommonBlockNode, node: CommonBlockInterface): void {
node.setId(serializedNode.id); node.setId(serializedNode.id);
node.setAlignment(serializedNode.alignment); node.setAlignment(serializedNode.alignment);
node.setInset(serializedNode.inset); node.setInset(serializedNode.inset);
node.setDirection(serializedNode.direction);
} }
export interface NodeHasSize { export interface NodeHasSize {

View File

@ -3,6 +3,10 @@
## In progress ## In progress
- RTL/LTR support - 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 ## Main Todo

View File

@ -37,14 +37,15 @@ function setAlignmentForSelection(editor: LexicalEditor, alignment: CommonBlockA
$toggleSelection(editor); $toggleSelection(editor);
} }
function setDirectionForSelection(editor: LexicalEditor, direction: 'ltr' | 'rtl'): void { function setDirectionForSelection(context: EditorUiContext, direction: 'ltr' | 'rtl'): void {
const selection = getLastSelection(editor); const selection = getLastSelection(context.editor);
const elements = $getBlockElementNodesInSelection(selection); const elements = $getBlockElementNodesInSelection(selection);
for (const node of elements) { for (const node of elements) {
console.log('setting direction', node);
node.setDirection(direction); node.setDirection(direction);
} }
context.manager.triggerFutureStateRefresh();
} }
export const alignLeft: EditorButtonDefinition = { export const alignLeft: EditorButtonDefinition = {
@ -95,7 +96,7 @@ export const directionLTR: EditorButtonDefinition = {
label: 'Left to right', label: 'Left to right',
icon: ltrIcon, icon: ltrIcon,
action(context: EditorUiContext) { action(context: EditorUiContext) {
context.editor.update(() => setDirectionForSelection(context.editor, 'ltr')); context.editor.update(() => setDirectionForSelection(context, 'ltr'));
}, },
isActive(selection: BaseSelection|null) { isActive(selection: BaseSelection|null) {
return $selectionContainsDirection(selection, 'ltr'); return $selectionContainsDirection(selection, 'ltr');
@ -106,7 +107,7 @@ export const directionRTL: EditorButtonDefinition = {
label: 'Right to left', label: 'Right to left',
icon: rtlIcon, icon: rtlIcon,
action(context: EditorUiContext) { action(context: EditorUiContext) {
context.editor.update(() => setDirectionForSelection(context.editor, 'rtl')); context.editor.update(() => setDirectionForSelection(context, 'rtl'));
}, },
isActive(selection: BaseSelection|null) { isActive(selection: BaseSelection|null) {
return $selectionContainsDirection(selection, 'rtl'); return $selectionContainsDirection(selection, 'rtl');

View File

@ -3,7 +3,6 @@ import {EditorButtonDefinition} from "../../framework/buttons";
import {EditorUiContext} from "../../framework/core"; import {EditorUiContext} from "../../framework/core";
import { import {
BaseSelection, BaseSelection,
LexicalEditor,
LexicalNode, LexicalNode,
} from "lexical"; } from "lexical";
import listBulletIcon from "@icons/editor/list-bullet.svg"; 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 indentIncreaseIcon from "@icons/editor/indent-increase.svg";
import indentDecreaseIcon from "@icons/editor/indent-decrease.svg"; import indentDecreaseIcon from "@icons/editor/indent-decrease.svg";
import { import {
$getBlockElementNodesInSelection, $selectionContainsNodeType,
$selectionContainsNodeType, $selectNodes, $selectSingleNode,
$toggleSelection,
getLastSelection
} from "../../../utils/selection"; } from "../../../utils/selection";
import {toggleSelectionAsList} from "../../../utils/formats"; import {toggleSelectionAsList} from "../../../utils/formats";
import {nodeHasInset} from "../../../utils/nodes"; import {$setInsetForSelection} from "../../../utils/lists";
import {$isCustomListItemNode, CustomListItemNode} from "../../../nodes/custom-list-item";
import {$nestListItem, $setInsetForSelection, $unnestListItem} from "../../../utils/lists";
function buildListButton(label: string, type: ListType, icon: string): EditorButtonDefinition { function buildListButton(label: string, type: ListType, icon: string): EditorButtonDefinition {

View File

@ -1,5 +1,6 @@
{ {
"include": ["resources/js/**/*"], "include": ["resources/js/**/*"],
"exclude": ["resources/js/wysiwyg/lexical/yjs/*"],
"compilerOptions": { "compilerOptions": {
"target": "es2019", "target": "es2019",
"module": "commonjs", "module": "commonjs",