mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-11 09:43:58 +02:00
Fix Android cursor jumping to word start after autocorrect (#5901)
* Enhance Android input manager to store current selection before applying diffs and ensure correct selection position post-update. * Add autocorrect test case to Android input examples This update introduces a new test case for autocorrect functionality in both JavaScript and TypeScript examples. The test case instructs users to type "Cant" and verify the cursor position after autocorrection. * Add changeset * Remove unnecessary comments * Drop pending selection change on programatic text insert
This commit is contained in:
5
.changeset/pretty-lies-build.md
Normal file
5
.changeset/pretty-lies-build.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'slate-react': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix Android cursor jumping to word start after autocorrect
|
@@ -689,7 +689,25 @@ export function createAndroidInputManager({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (canStoreDiff) {
|
if (canStoreDiff) {
|
||||||
|
const currentSelection = editor.selection
|
||||||
storeDiff(start.path, diff)
|
storeDiff(start.path, diff)
|
||||||
|
|
||||||
|
if (currentSelection) {
|
||||||
|
const newPoint = {
|
||||||
|
path: start.path,
|
||||||
|
offset: start.offset + text.length,
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduleAction(
|
||||||
|
() => {
|
||||||
|
Transforms.select(editor, {
|
||||||
|
anchor: newPoint,
|
||||||
|
focus: newPoint,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{ at: newPoint }
|
||||||
|
)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import { BaseEditor, Node } from 'slate'
|
import { BaseEditor, Node } from 'slate'
|
||||||
import { withDOM } from 'slate-dom'
|
import { withDOM, IS_ANDROID, EDITOR_TO_PENDING_SELECTION } from 'slate-dom'
|
||||||
import { ReactEditor } from './react-editor'
|
import { ReactEditor } from './react-editor'
|
||||||
import { REACT_MAJOR_VERSION } from '../utils/environment'
|
import { REACT_MAJOR_VERSION } from '../utils/environment'
|
||||||
import { getChunkTreeForNode } from '../chunking'
|
import { getChunkTreeForNode } from '../chunking'
|
||||||
@@ -21,10 +21,24 @@ export const withReact = <T extends BaseEditor>(
|
|||||||
|
|
||||||
e = withDOM(e, clipboardFormatKey)
|
e = withDOM(e, clipboardFormatKey)
|
||||||
|
|
||||||
const { onChange, apply } = e
|
const { onChange, apply, insertText } = e
|
||||||
|
|
||||||
e.getChunkSize = () => null
|
e.getChunkSize = () => null
|
||||||
|
|
||||||
|
if (IS_ANDROID) {
|
||||||
|
e.insertText = (text, options) => {
|
||||||
|
// COMPAT: Android devices, specifically Samsung devices, experience cursor jumping.
|
||||||
|
// This issue occurs when the insertText function is called immediately after typing.
|
||||||
|
// The problem arises because typing schedules a selection change.
|
||||||
|
// However, this selection change is only executed after the insertText function.
|
||||||
|
// As a result, the already obsolete selection is applied, leading to incorrect
|
||||||
|
// final cursor position.
|
||||||
|
EDITOR_TO_PENDING_SELECTION.delete(e)
|
||||||
|
|
||||||
|
return insertText(text, options)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
e.onChange = options => {
|
e.onChange = options => {
|
||||||
// COMPAT: React < 18 doesn't batch `setState` hook calls, which means
|
// COMPAT: React < 18 doesn't batch `setState` hook calls, which means
|
||||||
// that the children and selection can get out of sync for one render
|
// that the children and selection can get out of sync for one render
|
||||||
|
@@ -173,6 +173,18 @@ const TEST_CASES = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'autocorrect',
|
||||||
|
name: 'Autocorrect',
|
||||||
|
instructions:
|
||||||
|
'Type "Cant", then press space to autocorrect it. Make sure the cursor position is correct (after the autocorrected word)',
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
type: 'paragraph',
|
||||||
|
children: [{ text: '' }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
]
|
]
|
||||||
const AndroidTestsExample = () => {
|
const AndroidTestsExample = () => {
|
||||||
const [testId, setTestId] = useState(
|
const [testId, setTestId] = useState(
|
||||||
|
@@ -180,6 +180,18 @@ const TEST_CASES: AndroidTestCase[] = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'autocorrect',
|
||||||
|
name: 'Autocorrect',
|
||||||
|
instructions:
|
||||||
|
'Type "Cant" (make sure to misspell it), then press space to autocorrect it. Make sure the cursor position is correct (after the autocorrected word)',
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
type: 'paragraph',
|
||||||
|
children: [{ text: '' }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const AndroidTestsExample = () => {
|
const AndroidTestsExample = () => {
|
||||||
|
Reference in New Issue
Block a user