Skip to content

Commit

Permalink
Selection#formatText to retain selection and handle all text nodes (#…
Browse files Browse the repository at this point in the history
…2770)

* Selection retention after text format

* Fix e2e tests
  • Loading branch information
fantactuka authored and thegreatercurve committed Nov 25, 2022
1 parent 43485af commit 3a8a531
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 131 deletions.
57 changes: 24 additions & 33 deletions packages/lexical-playground/__tests__/e2e/TextFormatting.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,9 @@ test.describe('TextFormatting', () => {
`,
);
await assertSelection(page, {
anchorOffset: 0,
anchorOffset: 5,
anchorPath: [0, 1, 0],
focusOffset: 5,
focusOffset: 0,
focusPath: [0, 1, 0],
});

Expand All @@ -201,9 +201,9 @@ test.describe('TextFormatting', () => {
`,
);
await assertSelection(page, {
anchorOffset: 6,
anchorOffset: 11,
anchorPath: [0, 0, 0],
focusOffset: 11,
focusOffset: 6,
focusPath: [0, 0, 0],
});
});
Expand Down Expand Up @@ -289,9 +289,9 @@ test.describe('TextFormatting', () => {
`,
);
await assertSelection(page, {
anchorOffset: 0,
anchorOffset: 5,
anchorPath: [0, 1, 0],
focusOffset: 5,
focusOffset: 0,
focusPath: [0, 1, 0],
});

Expand All @@ -307,9 +307,9 @@ test.describe('TextFormatting', () => {
`,
);
await assertSelection(page, {
anchorOffset: 6,
anchorOffset: 11,
anchorPath: [0, 0, 0],
focusOffset: 11,
focusOffset: 6,
focusPath: [0, 0, 0],
});
});
Expand Down Expand Up @@ -349,9 +349,9 @@ test.describe('TextFormatting', () => {
`,
);
await assertSelection(page, {
anchorOffset: 0,
anchorOffset: 5,
anchorPath: [0, 1, 0],
focusOffset: 5,
focusOffset: 0,
focusPath: [0, 1, 0],
});

Expand All @@ -367,9 +367,9 @@ test.describe('TextFormatting', () => {
`,
);
await assertSelection(page, {
anchorOffset: 6,
anchorOffset: 11,
anchorPath: [0, 0, 0],
focusOffset: 11,
focusOffset: 6,
focusPath: [0, 0, 0],
});

Expand All @@ -394,9 +394,9 @@ test.describe('TextFormatting', () => {
`,
);
await assertSelection(page, {
anchorOffset: 0,
anchorOffset: 5,
anchorPath: [0, 1, 0],
focusOffset: 5,
focusOffset: 0,
focusPath: [0, 1, 0],
});

Expand All @@ -419,9 +419,9 @@ test.describe('TextFormatting', () => {
`,
);
await assertSelection(page, {
anchorOffset: 0,
anchorOffset: 5,
anchorPath: [0, 1, 0],
focusOffset: 5,
focusOffset: 0,
focusPath: [0, 1, 0],
});
});
Expand Down Expand Up @@ -601,9 +601,9 @@ test.describe('TextFormatting', () => {
`,
);
await assertSelection(page, {
anchorOffset: 0,
anchorOffset: 5,
anchorPath: [0, 1, 0],
focusOffset: 5,
focusOffset: 0,
focusPath: [0, 1, 0],
});

Expand Down Expand Up @@ -736,21 +736,12 @@ test.describe('TextFormatting', () => {
`,
);

if (browserName === 'webkit') {
await assertSelection(page, {
anchorOffset: 0,
anchorPath: [0, 1, 0],
focusOffset: 5,
focusPath: [0, 1, 0],
});
} else {
await assertSelection(page, {
anchorOffset: 6,
anchorPath: [0, 0, 0],
focusOffset: 5,
focusPath: [0, 1, 0],
});
}
await assertSelection(page, {
anchorOffset: 0,
anchorPath: [0, 1, 0],
focusOffset: 5,
focusPath: [0, 1, 0],
});

await toggleItalic(page);
await assertHTML(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import {
formatStrikeThrough,
formatUnderline,
getNodeFromPath,
insertParagraph,
insertSegmentedNode,
insertText,
insertTokenNode,
Expand Down Expand Up @@ -441,6 +442,136 @@ describe('LexicalSelection tests', () => {
],
name: 'Convert text to a segmented node',
},
{
expectedHTML:
'<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" dir="ltr">' +
'<strong class="editor-text-bold" data-lexical-text="true">Hello world</strong>' +
'</p>' +
'<p class="editor-paragraph"><br></p>' +
'</div>',
expectedSelection: {
anchorOffset: 0,
anchorPath: [0],
focusOffset: 0,
focusPath: [2],
},
inputs: [
insertParagraph(),
insertText('Hello world'),
insertParagraph(),
moveNativeSelection([0], 0, [2], 0),
formatBold(),
],
name: 'Format selection that starts and ends on element and retain selection',
},
{
expectedHTML:
'<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" dir="ltr">' +
'<strong class="editor-text-bold" data-lexical-text="true">Hello</strong>' +
'</p>' +
'<p class="editor-paragraph" dir="ltr">' +
'<strong class="editor-text-bold" data-lexical-text="true">world</strong>' +
'</p>' +
'<p class="editor-paragraph"><br></p>' +
'</div>',
expectedSelection: {
anchorOffset: 0,
anchorPath: [0],
focusOffset: 0,
focusPath: [3],
},
inputs: [
insertParagraph(),
insertText('Hello'),
insertParagraph(),
insertText('world'),
insertParagraph(),
moveNativeSelection([0], 0, [3], 0),
formatBold(),
],
name: 'Format multiline text selection that starts and ends on element and retain selection',
},
{
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">He</span>' +
'<strong class="editor-text-bold" data-lexical-text="true">llo</strong>' +
'</p>' +
'<p class="editor-paragraph" dir="ltr">' +
'<strong class="editor-text-bold" data-lexical-text="true">wo</strong>' +
'<span data-lexical-text="true">rld</span>' +
'</p>' +
'</div>',
expectedSelection: {
anchorOffset: 0,
anchorPath: [0, 1, 0],
focusOffset: 2,
focusPath: [1, 0, 0],
},
inputs: [
insertText('Hello'),
insertParagraph(),
insertText('world'),
moveNativeSelection([0, 0, 0], 2, [1, 0, 0], 2),
formatBold(),
],
name: 'Format multiline text selection that starts and ends within text',
},
{
expectedHTML:
'<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" dir="ltr">' +
'<span data-lexical-text="true">Hello </span>' +
'<strong class="editor-text-bold" data-lexical-text="true">world</strong>' +
'</p>' +
'<p class="editor-paragraph"><br></p>' +
'</div>',
expectedSelection: {
anchorOffset: 0,
anchorPath: [1, 1, 0],
focusOffset: 0,
focusPath: [2],
},
inputs: [
insertParagraph(),
insertText('Hello world'),
insertParagraph(),
moveNativeSelection([1, 0, 0], 6, [2], 0),
formatBold(),
],
name: 'Format selection that starts on text and ends on element and retain selection',
},
{
expectedHTML:
'<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" dir="ltr">' +
'<strong class="editor-text-bold" data-lexical-text="true">Hello</strong>' +
'<span data-lexical-text="true"> world</span>' +
'</p>' +
'<p class="editor-paragraph"><br></p>' +
'</div>',
expectedSelection: {
anchorOffset: 0,
anchorPath: [0],
focusOffset: 5,
focusPath: [1, 0, 0],
},
inputs: [
insertParagraph(),
insertText('Hello world'),
insertParagraph(),
moveNativeSelection([0], 0, [1, 0, 0], 5),
formatBold(),
],
name: 'Format selection that starts on element and ends on text and retain selection',
},
// Tests need fixing:
// ...GRAPHEME_SCENARIOS.flatMap(({description, grapheme}) => [
// {
Expand Down
2 changes: 1 addition & 1 deletion packages/lexical-selection/src/__tests__/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ export function convertToSegmentedNode() {
};
}

export function insertParagraph(text) {
export function insertParagraph() {
return {
type: 'insert_paragraph',
};
Expand Down
Loading

0 comments on commit 3a8a531

Please sign in to comment.