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:
@@ -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)
|
||||
|
@@ -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
|
||||
},
|
||||
|
||||
|
Reference in New Issue
Block a user