1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-17 12:41:44 +02:00

Prioritize using Selection over Range to preserve direction (#3594)

accout for zero-width nodes
This commit is contained in:
David Hrdlicka
2020-04-26 07:23:52 +02:00
committed by GitHub
parent 4f6ca7bc62
commit 67c4b3b330
2 changed files with 26 additions and 16 deletions

View File

@@ -145,13 +145,11 @@ export const Editable = (props: EditableProps) => {
return
}
const newDomRange = selection && ReactEditor.toDOMRange(editor, selection)
// If the DOM selection is already correct, we're done.
if (
hasDomSelection &&
newDomRange &&
isRangeEqual(domSelection.getRangeAt(0), newDomRange)
selection &&
Range.equals(ReactEditor.toSlateRange(editor, domSelection), selection)
) {
return
}
@@ -161,6 +159,8 @@ export const Editable = (props: EditableProps) => {
state.isUpdatingSelection = true
domSelection.removeAllRanges()
const newDomRange = selection && ReactEditor.toDOMRange(editor, selection)
if (newDomRange) {
domSelection.addRange(newDomRange!)
const leafEl = newDomRange.startContainer.parentElement!
@@ -356,10 +356,6 @@ export const Editable = (props: EditableProps) => {
const { activeElement } = window.document
const el = ReactEditor.toDOMNode(editor, editor)
const domSelection = window.getSelection()
const domRange =
domSelection &&
domSelection.rangeCount > 0 &&
domSelection.getRangeAt(0)
if (activeElement === el) {
state.latestElement = activeElement
@@ -369,11 +365,11 @@ export const Editable = (props: EditableProps) => {
}
if (
domRange &&
hasEditableTarget(editor, domRange.startContainer) &&
hasEditableTarget(editor, domRange.endContainer)
domSelection &&
hasEditableTarget(editor, domSelection.anchorNode) &&
hasEditableTarget(editor, domSelection.focusNode)
) {
const range = ReactEditor.toSlateRange(editor, domRange)
const range = ReactEditor.toSlateRange(editor, domSelection)
Transforms.select(editor, range)
} else {
Transforms.deselect(editor)

View File

@@ -264,16 +264,30 @@ export const ReactEditor = {
toDOMRange(editor: ReactEditor, range: Range): DOMRange {
const { anchor, focus } = range
const isBackward = Range.isBackward(range)
const domAnchor = ReactEditor.toDOMPoint(editor, anchor)
const domFocus = Range.isCollapsed(range)
? domAnchor
: ReactEditor.toDOMPoint(editor, focus)
const domRange = window.document.createRange()
const start = Range.isBackward(range) ? domFocus : domAnchor
const end = Range.isBackward(range) ? domAnchor : domFocus
domRange.setStart(start[0], start[1])
domRange.setEnd(end[0], end[1])
const [startNode, startOffset] = isBackward ? domFocus : domAnchor
const [endNode, endOffset] = isBackward ? domAnchor : domFocus
// A slate Point at zero-width Leaf always has an offset of 0 but a native DOM selection at
// zero-width node has an offset of 1 so we have to check if we are in a zero-width node and
// adjust the offset accordingly.
const startEl = (isDOMElement(startNode)
? startNode
: startNode.parentElement) as HTMLElement
const isStartAtZeroWidth = !!startEl.getAttribute('data-slate-zero-width')
const endEl = (isDOMElement(endNode)
? endNode
: endNode.parentElement) as HTMLElement
const isEndAtZeroWidth = !!endEl.getAttribute('data-slate-zero-width')
domRange.setStart(startNode, isStartAtZeroWidth ? 1 : startOffset)
domRange.setEnd(endNode, isEndAtZeroWidth ? 1 : endOffset)
return domRange
},