mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-12 18:24:03 +02:00
refactor selection snapshotting
This commit is contained in:
@@ -285,16 +285,11 @@ function removeNode(state, operation) {
|
|||||||
|
|
||||||
function removeText(state, operation) {
|
function removeText(state, operation) {
|
||||||
const { path, offset, length } = operation
|
const { path, offset, length } = operation
|
||||||
|
const rangeOffset = offset + length
|
||||||
let { document, selection } = state
|
let { document, selection } = state
|
||||||
const { startKey, endKey, startOffset, endOffset } = selection
|
const { startKey, endKey, startOffset, endOffset } = selection
|
||||||
let node = document.assertPath(path)
|
let node = document.assertPath(path)
|
||||||
|
|
||||||
const rangeOffset = offset + length
|
|
||||||
|
|
||||||
// Update the document
|
|
||||||
node = node.removeText(offset, length)
|
|
||||||
document = document.updateDescendant(node)
|
|
||||||
|
|
||||||
// Update the selection
|
// Update the selection
|
||||||
if (startKey == node.key && startOffset >= rangeOffset) {
|
if (startKey == node.key && startOffset >= rangeOffset) {
|
||||||
selection = selection.moveStartOffset(-length)
|
selection = selection.moveStartOffset(-length)
|
||||||
@@ -303,6 +298,8 @@ function removeText(state, operation) {
|
|||||||
selection = selection.moveEndOffset(-length)
|
selection = selection.moveEndOffset(-length)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node = node.removeText(offset, length)
|
||||||
|
document = document.updateDescendant(node)
|
||||||
state = state.merge({ document, selection })
|
state = state.merge({ document, selection })
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
@@ -38,64 +38,16 @@ export function addMark(transform, mark) {
|
|||||||
|
|
||||||
export function _delete(transform) {
|
export function _delete(transform) {
|
||||||
const { state } = transform
|
const { state } = transform
|
||||||
const { document, selection } = state
|
const { selection } = state
|
||||||
|
|
||||||
// If the selection is collapsed, there's nothing to delete.
|
|
||||||
if (selection.isCollapsed) return
|
if (selection.isCollapsed) return
|
||||||
|
|
||||||
const { startText } = state
|
|
||||||
const { startKey, startOffset, endKey, endOffset } = selection
|
|
||||||
const block = document.getClosestBlock(startKey)
|
|
||||||
const highest = block.getHighestChild(startKey)
|
|
||||||
const previous = block.getPreviousSibling(highest.key)
|
|
||||||
const next = block.getNextSibling(highest.key)
|
|
||||||
let after
|
|
||||||
|
|
||||||
// If there's a previous node, and we're at the start of the current node,
|
|
||||||
// and the selection encompasses the entire current node, it won't exist after
|
|
||||||
// deleting, so we need to update the selection's keys.
|
|
||||||
if (
|
|
||||||
previous &&
|
|
||||||
startOffset == 0 &&
|
|
||||||
(endKey != startKey || endOffset == startText.length)
|
|
||||||
) {
|
|
||||||
|
|
||||||
// If the nodes on either sides are text nodes, they will end up being
|
|
||||||
// combined, so we need to set the selection to right in between them.
|
|
||||||
if (previous.kind == 'text' && next && next.kind == 'text') {
|
|
||||||
after = selection.merge({
|
|
||||||
anchorKey: previous.key,
|
|
||||||
anchorOffset: previous.length,
|
|
||||||
focusKey: previous.key,
|
|
||||||
focusOffset: previous.length
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, if only the previous node is a text node, it won't be merged,
|
|
||||||
// so collapse to the end of it.
|
|
||||||
else if (previous.kind == 'text') {
|
|
||||||
after = selection.collapseToEndOf(previous)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, if the previous node isn't a text node, we need to get the
|
|
||||||
// last text node inside of it and collapse to the end of that.
|
|
||||||
else {
|
|
||||||
const last = previous.getLastText()
|
|
||||||
after = selection.collapseToEndOf(last)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, if the inline is an online child
|
|
||||||
|
|
||||||
// Otherwise simply collapse the selection.
|
|
||||||
else {
|
|
||||||
after = selection.collapseToStart()
|
|
||||||
}
|
|
||||||
|
|
||||||
transform
|
transform
|
||||||
.unsetSelection()
|
.snapshotSelection()
|
||||||
.deleteAtRange(selection)
|
.deleteAtRange(selection)
|
||||||
.moveTo(after)
|
// Ensure that the selection is collapsed to the start, because in certain
|
||||||
|
// cases when deleting across inline nodes this isn't guaranteed.
|
||||||
|
.collapseToStart()
|
||||||
|
.snapshotSelection()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -133,6 +133,7 @@ import {
|
|||||||
moveToRangeOf,
|
moveToRangeOf,
|
||||||
unsetMarks,
|
unsetMarks,
|
||||||
unsetSelection,
|
unsetSelection,
|
||||||
|
snapshotSelection,
|
||||||
} from './on-selection'
|
} from './on-selection'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -288,6 +289,7 @@ export default {
|
|||||||
moveToRangeOf,
|
moveToRangeOf,
|
||||||
unsetMarks,
|
unsetMarks,
|
||||||
unsetSelection,
|
unsetSelection,
|
||||||
|
snapshotSelection,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* History.
|
* History.
|
||||||
|
@@ -412,6 +412,18 @@ export function unsetMarks(transform) {
|
|||||||
transform.setSelectionOperation({ marks: null })
|
transform.setSelectionOperation({ marks: null })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Snapshot the current selection.
|
||||||
|
*
|
||||||
|
* @param {Transform} transform
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function snapshotSelection(transform) {
|
||||||
|
const { state } = transform
|
||||||
|
const { selection } = state
|
||||||
|
transform.setSelectionOperation(selection, { snapshot: true })
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unset the selection, removing an association to a node.
|
* Unset the selection, removing an association to a node.
|
||||||
*
|
*
|
||||||
|
@@ -352,7 +352,7 @@ export function setNodeOperation(transform, path, properties) {
|
|||||||
* @param {Mixed} selection
|
* @param {Mixed} selection
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function setSelectionOperation(transform, properties) {
|
export function setSelectionOperation(transform, properties, options = {}) {
|
||||||
properties = Normalize.selectionProperties(properties)
|
properties = Normalize.selectionProperties(properties)
|
||||||
|
|
||||||
const { state } = transform
|
const { state } = transform
|
||||||
@@ -364,7 +364,7 @@ export function setSelectionOperation(transform, properties) {
|
|||||||
// create a dictionary of the previous values for all of the properties that
|
// create a dictionary of the previous values for all of the properties that
|
||||||
// are being changed, for the inverse operation.
|
// are being changed, for the inverse operation.
|
||||||
for (const k in properties) {
|
for (const k in properties) {
|
||||||
if (properties[k] == selection[k]) continue
|
if (!options.snapshot && properties[k] == selection[k]) continue
|
||||||
props[k] = properties[k]
|
props[k] = properties[k]
|
||||||
prevProps[k] = selection[k]
|
prevProps[k] = selection[k]
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user