1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-16 04:04:06 +02:00

fix inconsistent render reversed selection (#3804)

* fix inconsistent render reversed selection

* fix type error

* add comment for setReverseDomSelection

* add comment for setReverseDomSelection

* add comment for toDOMRange
This commit is contained in:
Githoniel
2020-08-20 23:43:16 +08:00
committed by GitHub
parent 91564f8812
commit 79eee6b378
3 changed files with 32 additions and 1 deletions

View File

@@ -33,6 +33,7 @@ import {
isDOMText,
DOMStaticRange,
isPlainTextOnlyPaste,
setReverseDomSelection,
} from '../utils/dom'
import {
EDITOR_TO_ELEMENT,
@@ -184,7 +185,11 @@ export const Editable = (props: EditableProps) => {
const newDomRange = selection && ReactEditor.toDOMRange(editor, selection)
if (newDomRange) {
domSelection.addRange(newDomRange!)
if (Range.isBackward(selection!)) {
setReverseDomSelection(newDomRange, domSelection)
} else {
domSelection.addRange(newDomRange!)
}
const leafEl = newDomRange.startContainer.parentElement!
scrollIntoView(leafEl, {
scrollMode: 'if-needed',

View File

@@ -269,6 +269,11 @@ export const ReactEditor = {
/**
* Find a native DOM range from a Slate `range`.
*
* Notice: the returned range will always be ordinal regardless of the direction of Slate `range` due to DOM API limit.
*
* there is no way to create a reverse DOM Range using Range.setStart/setEnd
* according to https://dom.spec.whatwg.org/#concept-range-bp-set.
*/
toDOMRange(editor: ReactEditor, range: Range): DOMRange {

View File

@@ -174,3 +174,24 @@ export const getPlainText = (domNode: DOMNode) => {
return text
}
/**
* there is no way to create a reverse DOM Range using Range.setStart/setEnd
* according to https://dom.spec.whatwg.org/#concept-range-bp-set.
* Luckily it's possible to create a reverse selection via Selection.extend
*
* Note: Selection.extend is not implement in any version of IE (up to and including version 11)
*/
export const setReverseDomSelection = (
domRange: DOMRange,
domSelection: Selection
) => {
const newRange = domRange.cloneRange()
// collapses the range to end
newRange.collapse()
// set both anchor and focus of the selection to domRange's focus
domSelection.addRange(newRange)
// moves the focus of the selection to domRange's anchor
domSelection.extend(domRange.startContainer, domRange.startOffset)
}