mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-01-29 19:27:43 +01:00
Restore user selection after beforeinput with target range (#4919)
* Restore user selection after beforeinput with target range * Add changeset
This commit is contained in:
parent
ce63a08c8e
commit
7de7cdcf56
5
.changeset/late-monkeys-hug.md
Normal file
5
.changeset/late-monkeys-hug.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'slate-react': patch
|
||||
---
|
||||
|
||||
Restore user selection after applying beforeinput with target range
|
@ -8,6 +8,7 @@ import {
|
||||
Text,
|
||||
Transforms,
|
||||
Path,
|
||||
RangeRef,
|
||||
} from 'slate'
|
||||
import getDirection from 'direction'
|
||||
import debounce from 'lodash/debounce'
|
||||
@ -51,6 +52,7 @@ import {
|
||||
IS_FOCUSED,
|
||||
PLACEHOLDER_SYMBOL,
|
||||
EDITOR_TO_WINDOW,
|
||||
EDITOR_TO_USER_SELECTION,
|
||||
} from '../utils/weak-maps'
|
||||
|
||||
type DeferredOperation = () => void
|
||||
@ -399,7 +401,14 @@ export const Editable = (props: EditableProps) => {
|
||||
})
|
||||
|
||||
if (!selection || !Range.equals(selection, range)) {
|
||||
const selectionRef =
|
||||
editor.selection && Editor.rangeRef(editor, editor.selection)
|
||||
|
||||
Transforms.select(editor, range)
|
||||
|
||||
if (selectionRef) {
|
||||
EDITOR_TO_USER_SELECTION.set(editor, selectionRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -523,6 +532,17 @@ export const Editable = (props: EditableProps) => {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the actual user section if nothing manually set it.
|
||||
const toRestore = EDITOR_TO_USER_SELECTION.get(editor)?.unref()
|
||||
EDITOR_TO_USER_SELECTION.delete(editor)
|
||||
|
||||
if (
|
||||
toRestore &&
|
||||
(!editor.selection || !Range.equals(editor.selection, toRestore))
|
||||
) {
|
||||
Transforms.select(editor, toRestore)
|
||||
}
|
||||
}
|
||||
},
|
||||
[readOnly, propsOnDOMBeforeInput]
|
||||
@ -1385,23 +1405,6 @@ const defaultScrollSelectionIntoView = (
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if two DOM range objects are equal.
|
||||
*/
|
||||
|
||||
export const isRangeEqual = (a: DOMRange, b: DOMRange) => {
|
||||
return (
|
||||
(a.startContainer === b.startContainer &&
|
||||
a.startOffset === b.startOffset &&
|
||||
a.endContainer === b.endContainer &&
|
||||
a.endOffset === b.endOffset) ||
|
||||
(a.startContainer === b.endContainer &&
|
||||
a.startOffset === b.endOffset &&
|
||||
a.endContainer === b.startContainer &&
|
||||
a.endOffset === b.startOffset)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the target is in the editor.
|
||||
*/
|
||||
|
@ -7,6 +7,7 @@ import {
|
||||
EDITOR_TO_KEY_TO_ELEMENT,
|
||||
EDITOR_TO_ON_CHANGE,
|
||||
NODE_TO_KEY,
|
||||
EDITOR_TO_USER_SELECTION,
|
||||
} from '../utils/weak-maps'
|
||||
import {
|
||||
isDOMText,
|
||||
@ -74,6 +75,13 @@ export const withReact = <T extends Editor>(editor: T) => {
|
||||
break
|
||||
}
|
||||
|
||||
case 'set_selection': {
|
||||
// Selection was manually set, don't restore the user selection after the change.
|
||||
EDITOR_TO_USER_SELECTION.get(editor)?.unref()
|
||||
EDITOR_TO_USER_SELECTION.delete(editor)
|
||||
break
|
||||
}
|
||||
|
||||
case 'insert_node':
|
||||
case 'remove_node': {
|
||||
matches.push(...getMatches(e, Path.parent(op.path)))
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Ancestor, Editor, Node } from 'slate'
|
||||
import { Ancestor, Editor, Node, RangeRef } from 'slate'
|
||||
import { Key } from './key'
|
||||
import { TextInsertion } from '../components/android/diff-text'
|
||||
|
||||
@ -36,6 +36,8 @@ export const IS_CLICKING: WeakMap<Editor, boolean> = new WeakMap()
|
||||
export const IS_COMPOSING: WeakMap<Editor, boolean> = new WeakMap()
|
||||
export const IS_ON_COMPOSITION_END: WeakMap<Editor, boolean> = new WeakMap()
|
||||
|
||||
export const EDITOR_TO_USER_SELECTION: WeakMap<Editor, RangeRef> = new WeakMap()
|
||||
|
||||
/**
|
||||
* Weak maps for saving text on composition stage.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user