Skip to content
This repository was archived by the owner on Feb 6, 2023. It is now read-only.

Commit 084bdb6

Browse files
existentialismfacebook-github-bot
authored andcommitted
Ensure selection collapses if user tries to replace with matching text
Summary: **Summary** This PR ensures that the selection is always collapsed for the cases where a user replaces the current selection with matching text. I admittedly didn't really dig into the original issue when fixing the previous crash :) **Test Plan** Small repro: 1. Type in "abc" 1. Select "c" from right-to-left 1. Type "c" 1. Select "c" from left-to-right 1. Type "c" Thanks to JLarky for bringing this to my intention! Closes #1661 Differential Revision: D7055502 fbshipit-source-id: ee4cf80d292ee715e40c017e4c6bd18f806b0e24
1 parent 04c2b9c commit 084bdb6

File tree

3 files changed

+45
-72
lines changed

3 files changed

+45
-72
lines changed

src/component/handlers/edit/__tests__/__snapshots__/editOnBeforeInput.test.js.snap

Lines changed: 17 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -76,74 +76,22 @@ Immutable.Record {
7676

7777
exports[`editor selectionstate is updated if new text matches current selection 1`] = `
7878
Immutable.Record {
79-
"entityMap": Object {
80-
"__add": [Function],
81-
"__create": [Function],
82-
"__get": [Function],
83-
"__getLastCreatedEntityKey": [Function],
84-
"__mergeData": [Function],
85-
"__replaceData": [Function],
86-
"add": [Function],
87-
"create": [Function],
88-
"get": [Function],
89-
"getLastCreatedEntityKey": [Function],
90-
"mergeData": [Function],
91-
"replaceData": [Function],
92-
},
93-
"blockMap": Immutable.OrderedMap {
94-
"a": Immutable.Record {
95-
"key": "a",
96-
"type": "unstyled",
97-
"text": "Arsenal",
98-
"characterList": Immutable.List [
99-
Immutable.Record {
100-
"style": Immutable.OrderedSet [],
101-
"entity": null,
102-
},
103-
Immutable.Record {
104-
"style": Immutable.OrderedSet [],
105-
"entity": null,
106-
},
107-
Immutable.Record {
108-
"style": Immutable.OrderedSet [],
109-
"entity": null,
110-
},
111-
Immutable.Record {
112-
"style": Immutable.OrderedSet [],
113-
"entity": null,
114-
},
115-
Immutable.Record {
116-
"style": Immutable.OrderedSet [],
117-
"entity": null,
118-
},
119-
Immutable.Record {
120-
"style": Immutable.OrderedSet [],
121-
"entity": null,
122-
},
123-
Immutable.Record {
124-
"style": Immutable.OrderedSet [],
125-
"entity": null,
126-
},
127-
],
128-
"depth": 0,
129-
"data": Immutable.Map {},
130-
},
131-
},
132-
"selectionBefore": Immutable.Record {
133-
"anchorKey": "a",
134-
"anchorOffset": 0,
135-
"focusKey": "a",
136-
"focusOffset": 0,
137-
"isBackward": false,
138-
"hasFocus": false,
139-
},
140-
"selectionAfter": Immutable.Record {
141-
"anchorKey": "a",
142-
"anchorOffset": 0,
143-
"focusKey": "a",
144-
"focusOffset": 0,
145-
"isBackward": false,
146-
"hasFocus": false,
147-
},
79+
"anchorKey": "a",
80+
"anchorOffset": 1,
81+
"focusKey": "a",
82+
"focusOffset": 1,
83+
"isBackward": false,
84+
"hasFocus": true,
85+
}
86+
`;
87+
88+
exports[`editor selectionstate is updated if new text matches current selection and user selected backwards 1`] = `
89+
Immutable.Record {
90+
"anchorKey": "a",
91+
"anchorOffset": 1,
92+
"focusKey": "a",
93+
"focusOffset": 1,
94+
"isBackward": true,
95+
"hasFocus": true,
14896
}
14997
`;

src/component/handlers/edit/__tests__/editOnBeforeInput.test.js

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,17 @@ const DEFAULT_SELECTION = {
2929
isBackward: false,
3030
};
3131

32-
//const collapsedSelection = new SelectionState(DEFAULT_SELECTION);
33-
3432
const rangedSelection = new SelectionState({
3533
...DEFAULT_SELECTION,
3634
focusOffset: 1,
3735
});
3836

37+
const rangedSelectionBackwards = new SelectionState({
38+
...DEFAULT_SELECTION,
39+
anchorOffset: 1,
40+
isBackward: true,
41+
});
42+
3943
const getEditorState = () => {
4044
return EditorState.createWithContent(
4145
ContentState.createFromBlockArray([
@@ -125,5 +129,25 @@ test('editor selectionstate is updated if new text matches current selection', (
125129
expect(editor.update).toHaveBeenCalledTimes(1);
126130

127131
const newEditorState = editor.update.mock.calls[0][0];
128-
expect(newEditorState.getCurrentContent()).toMatchSnapshot();
132+
expect(newEditorState.getSelection()).toMatchSnapshot();
133+
});
134+
135+
test('editor selectionstate is updated if new text matches current selection and user selected backwards', () => {
136+
const editorState = EditorState.acceptSelection(
137+
getEditorState(),
138+
rangedSelectionBackwards,
139+
);
140+
141+
const editor = {
142+
_latestEditorState: editorState,
143+
props: {},
144+
update: jest.fn(),
145+
};
146+
147+
onBeforeInput(editor, getInputEvent('A'));
148+
149+
expect(editor.update).toHaveBeenCalledTimes(1);
150+
151+
const newEditorState = editor.update.mock.calls[0][0];
152+
expect(newEditorState.getSelection()).toMatchSnapshot();
129153
});

src/component/handlers/edit/editOnBeforeInput.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ function editOnBeforeInput(
129129
EditorState.forceSelection(
130130
editorState,
131131
selection.merge({
132+
anchorOffset: selectionEnd,
132133
focusOffset: selectionEnd,
133134
}),
134135
),

0 commit comments

Comments
 (0)