Skip to content

Commit

Permalink
Remove immutable node references (facebook#2310)
Browse files Browse the repository at this point in the history
  • Loading branch information
thegreatercurve authored Jun 1, 2022
1 parent 099376f commit d828f13
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ function testSuite(charset) {
});
});

test('displays overflow on immutable nodes', async ({page, isCollab}) => {
test('displays overflow on token nodes', async ({page, isCollab}) => {
// The smile emoji (S) is length 2, so for 1234S56:
// - 1234 is non-overflow text
// - S takes characters 5 and 6, since it's immutable and can't be split we count the whole
// - S takes characters 5 and 6, since it's a token and can't be split we count the whole
// node as overflowed
// - 56 is overflowed
test.skip(isCollab);
Expand Down Expand Up @@ -244,12 +244,12 @@ function testSuite(charset) {
}
});

test('can delete text in front and overflow is recomputed (immutable nodes)', async ({
test('can delete text in front and overflow is recomputed (token nodes)', async ({
page,
isCollab,
}) => {
test.skip(isCollab);
// See 'displays overflow on immutable nodes'
// See 'displays overflow on token nodes'
await page.focus('div[contenteditable="true"]');

await page.keyboard.type('1234:)56');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ test.describe('Emoticons', () => {
}

await moveToLineBeginning(page);
// This should not crash on a deletion on an immutable node
// This should not crash on a deletion on a token node
await page.keyboard.press('Backspace');
await moveToLineEnd(page);

Expand Down
4 changes: 2 additions & 2 deletions packages/lexical-playground/src/plugins/MentionsPlugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -842,7 +842,7 @@ function getTextUpToAnchor(selection: RangeSelection): string | null {
const anchorNode = anchor.getNode();
// We should not be attempting to extract mentions out of nodes
// that are already being used for other core things. This is
// especially true for immutable nodes, which can't be mutated at all.
// especially true for token nodes, which can't be mutated at all.
if (!anchorNode.isSimpleText()) {
return null;
}
Expand Down Expand Up @@ -924,7 +924,7 @@ function createMentionNodeFromSearchResult(
const anchorNode = anchor.getNode();
// We should not be attempting to extract mentions out of nodes
// that are already being used for other core things. This is
// especially true for immutable nodes, which can't be mutated at all.
// especially true for token nodes, which can't be mutated at all.
if (!anchorNode.isSimpleText()) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ import * as ReactTestUtils from 'react-dom/test-utils';

import {
applySelectionInputs,
convertToImmutableNode,
convertToSegmentedNode,
convertToTokenNode,
deleteBackward,
deleteWordBackward,
deleteWordForward,
Expand All @@ -44,9 +44,9 @@ import {
formatStrikeThrough,
formatUnderline,
getNodeFromPath,
insertImmutableNode,
insertSegmentedNode,
insertText,
insertTokenNode,
moveBackward,
moveEnd,
moveNativeSelection,
Expand Down Expand Up @@ -381,8 +381,8 @@ describe('LexicalSelection tests', () => {
focusOffset: 16,
focusPath: [0, 0, 0],
},
inputs: [insertImmutableNode('Dominic Gannaway')],
name: 'Creation of an immutable node',
inputs: [insertTokenNode('Dominic Gannaway')],
name: 'Creation of an token node',
},
{
expectedHTML:
Expand All @@ -398,9 +398,9 @@ describe('LexicalSelection tests', () => {
inputs: [
insertText('Dominic Gannaway'),
moveNativeSelection([0, 0, 0], 0, [0, 0, 0], 16),
convertToImmutableNode(),
convertToTokenNode(),
],
name: 'Convert text to an immutable node',
name: 'Convert text to an token node',
},
{
expectedHTML:
Expand Down Expand Up @@ -908,12 +908,12 @@ describe('LexicalSelection tests', () => {
},
inputs: [
insertText('Hello '),
insertImmutableNode('Bob'),
insertTokenNode('Bob'),
moveBackward(1),
moveBackward(1),
moveEnd(),
],
name: 'Type a text and an immutable text, move the caret to the end of the first text',
name: 'Type a text and token text, move the caret to the end of the first text',
},
{
expectedHTML:
Expand Down
18 changes: 8 additions & 10 deletions packages/lexical-selection/src/__tests__/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,10 @@ export function insertText(text) {
};
}

export function insertImmutableNode(text) {
export function insertTokenNode(text) {
return {
text,
type: 'insert_immutable_node',
type: 'insert_token_node',
};
}

Expand All @@ -245,10 +245,10 @@ export function insertSegmentedNode(text) {
};
}

export function convertToImmutableNode() {
export function convertToTokenNode() {
return {
text: null,
type: 'convert_to_immutable_node',
type: 'convert_to_token_node',
};
}

Expand Down Expand Up @@ -725,10 +725,9 @@ export async function applySelectionInputs(inputs, update, editor) {
break;
}

case 'insert_immutable_node': {
case 'insert_token_node': {
const text = $createTextNode(input.text);
// @ts-expect-error TODO Remove or refactor these tests as immutable nodes are no longer valid.
text.setMode('immutable');
text.setMode('token');
if ($isRangeSelection(selection)) {
selection.insertNodes([text]);
}
Expand All @@ -745,10 +744,9 @@ export async function applySelectionInputs(inputs, update, editor) {
break;
}

case 'convert_to_immutable_node': {
case 'convert_to_token_node': {
const text = $createTextNode(selection.getTextContent());
// @ts-expect-error TODO Remove or refactor these tests as immutable nodes are no longer valid.
text.setMode('immutable');
text.setMode('token');
if ($isRangeSelection(selection)) {
selection.insertNodes([text]);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/lexical-yjs/src/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export function $createCollabNodeFromLexicalNode(
collabNode.syncPropertiesFromLexical(binding, lexicalNode, null);
collabNode.syncChildrenFromLexical(binding, lexicalNode, null, null, null);
} else if ($isTextNode(lexicalNode)) {
// TODO create a token text node for immutable, segmented or inert nodes.
// TODO create a token text node for token, segmented or inert nodes.
const map = new YMap();
collabNode = $createCollabTextNode(
map,
Expand Down
2 changes: 1 addition & 1 deletion packages/lexical/src/LexicalSelection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1207,7 +1207,7 @@ export class RangeSelection implements BaseSelection {
} else if (anchorOffset === textContentLength) {
target = anchorNode;
} else if ($isTokenOrInert(anchorNode)) {
// Do nothing if we're inside an immutable/inert node
// Do nothing if we're inside a token/inert node
return false;
} else {
// If we started with a range selected grab the danglingText after the
Expand Down
26 changes: 11 additions & 15 deletions packages/lexical/src/__tests__/unit/LexicalNode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -525,11 +525,11 @@ describe('LexicalNode tests', () => {

test('LexicalNode.isToken()', async () => {
const {editor} = testEnv;
let immutableTextNode;
let tokenTextNode;

await editor.update(() => {
immutableTextNode = new TextNode('token').setMode('token');
paragraphNode.append(immutableTextNode);
tokenTextNode = new TextNode('token').setMode('token');
paragraphNode.append(tokenTextNode);
});

expect(testEnv.outerHTML).toBe(
Expand All @@ -538,7 +538,7 @@ describe('LexicalNode tests', () => {

await editor.getEditorState().read(() => {
expect(textNode.isToken(textNode)).toBe(false);
expect(immutableTextNode.isToken()).toBe(true);
expect(tokenTextNode.isToken()).toBe(true);
});
expect(() => textNode.isToken()).toThrow();
});
Expand Down Expand Up @@ -765,16 +765,15 @@ describe('LexicalNode tests', () => {
);
});

test('LexicalNode.replace(): immutable', async () => {
test('LexicalNode.replace(): token', async () => {
const {editor} = testEnv;

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>',
);

await editor.update(() => {
// @ts-expect-error
const barTextNode = new TextNode('bar').setMode('immutable');
const barTextNode = new TextNode('bar').setMode('token');
textNode.replace(barTextNode);
});

Expand Down Expand Up @@ -861,16 +860,15 @@ describe('LexicalNode tests', () => {
);
});

test('LexicalNode.insertAfter(): immutable', async () => {
test('LexicalNode.insertAfter(): token', async () => {
const {editor} = testEnv;

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>',
);

await editor.update(() => {
// @ts-expect-error
const barTextNode = new TextNode('bar').setMode('immutable');
const barTextNode = new TextNode('bar').setMode('token');
textNode.insertAfter(barTextNode);
});

Expand All @@ -887,8 +885,7 @@ describe('LexicalNode tests', () => {
);

await editor.update(() => {
// @ts-expect-error
const barTextNode = new TextNode('bar').setMode('immutable');
const barTextNode = new TextNode('bar').setMode('token');
textNode.insertAfter(barTextNode);
});

Expand Down Expand Up @@ -1049,16 +1046,15 @@ describe('LexicalNode tests', () => {
);
});

test('LexicalNode.insertBefore(): immutable', async () => {
test('LexicalNode.insertBefore(): token', async () => {
const {editor} = testEnv;

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>',
);

await editor.update(() => {
// @ts-expect-error
const barTextNode = new TextNode('bar').setMode('immutable');
const barTextNode = new TextNode('bar').setMode('token');
textNode.insertBefore(barTextNode);
});

Expand Down

0 comments on commit d828f13

Please sign in to comment.