mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-22 15:02:51 +02:00
fix deleting for void nodes;
This commit is contained in:
@@ -27,36 +27,12 @@ class Void extends React.Component {
|
||||
state = state
|
||||
.transform()
|
||||
.moveToStartOf(text)
|
||||
.focus()
|
||||
.apply()
|
||||
|
||||
editor.onChange(state)
|
||||
}
|
||||
|
||||
onKeyDown(e) {
|
||||
let { state, editor } = this.props
|
||||
const key = keycode(e)
|
||||
|
||||
switch (key) {
|
||||
default:
|
||||
return
|
||||
case 'left arrow':
|
||||
case 'up arrow':
|
||||
state = state
|
||||
.transform()
|
||||
.moveToEndOfPreviousBlock()
|
||||
.apply()
|
||||
case 'right arrow':
|
||||
case 'down arrow':
|
||||
state = state
|
||||
.transform()
|
||||
.moveToStartOfNextBlock()
|
||||
.apply()
|
||||
}
|
||||
|
||||
e.preventDefault()
|
||||
editor.onChange(state)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children, node } = this.props
|
||||
const Tag = node.kind == 'block' ? 'div' : 'span'
|
||||
|
@@ -842,7 +842,9 @@ const Node = {
|
||||
|
||||
// That void nodes contain no text.
|
||||
if (desc.isVoid && desc.length) {
|
||||
const text = Text.create()
|
||||
let text = desc.getTextNodes().first()
|
||||
let characters = text.characters.clear()
|
||||
text = text.merge({ characters })
|
||||
const nodes = desc.nodes.clear().push(text)
|
||||
desc = desc.merge({ nodes })
|
||||
}
|
||||
|
@@ -183,6 +183,7 @@ class Selection extends Record(DEFAULTS) {
|
||||
|
||||
normalize(node) {
|
||||
let selection = this
|
||||
const { isCollapsed } = selection
|
||||
let { anchorKey, anchorOffset, focusKey, focusOffset, isBackward } = selection
|
||||
|
||||
// If the selection isn't formed yet, abort.
|
||||
@@ -220,6 +221,36 @@ class Selection extends Record(DEFAULTS) {
|
||||
: anchorIndex > focusIndex
|
||||
}
|
||||
|
||||
// If the selection is expanded and has an edge on a void block, move it.
|
||||
// if (isExpanded) {
|
||||
// let anchorBlock = node.getClosestBlock(anchorNode)
|
||||
// let focusBlock = node.getClosestBlock(focusNode)
|
||||
|
||||
// if (anchorBlock.isVoid) {
|
||||
// while (anchorBanchorBlock.isVoid) {
|
||||
// anchorBlock = isBackward
|
||||
// ? node.getPreviousBlock(anchorBlock)
|
||||
// : node.getNextBlock(anchorBlock)
|
||||
// }
|
||||
|
||||
// anchorNode = isBackward
|
||||
// ? anchorBlock.getTextNodes().last()
|
||||
// : anchorBlock.getTextNodes().first()
|
||||
// anchorOffset = isBackward
|
||||
// ? anchorNode.length
|
||||
// : 0
|
||||
// }
|
||||
|
||||
// else if (focusBlock.isVoid) {
|
||||
// focusNode = isBackward
|
||||
// ? node.getNextBlock(focusBlock).getTextNodes().first()
|
||||
// : node.getPreviousBlock(focusBlock).getTextNodes().last()
|
||||
// focusOffset = isBackward
|
||||
// ? 0
|
||||
// : focusNode.length
|
||||
// }
|
||||
// }
|
||||
|
||||
// Merge in any updated properties.
|
||||
return selection.merge({
|
||||
anchorKey: anchorNode.key,
|
||||
@@ -230,6 +261,30 @@ class Selection extends Record(DEFAULTS) {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus the selection.
|
||||
*
|
||||
* @return {Selection} selection
|
||||
*/
|
||||
|
||||
focus() {
|
||||
return this.merge({
|
||||
isFocused: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Blur the selection.
|
||||
*
|
||||
* @return {Selection} selection
|
||||
*/
|
||||
|
||||
blur() {
|
||||
return this.merge({
|
||||
isFocused: false
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the focus point to the anchor point.
|
||||
*
|
||||
|
@@ -408,13 +408,25 @@ class State extends Record(DEFAULTS) {
|
||||
deleteForward(n = 1) {
|
||||
let state = this
|
||||
let { document, selection } = state
|
||||
let { startKey } = selection
|
||||
let after = selection
|
||||
|
||||
// Determine what the selection should be after deleting.
|
||||
const block = document.getClosestBlock(startKey)
|
||||
const inline = document.getClosestInline(startKey)
|
||||
|
||||
if (selection.isExpanded) {
|
||||
after = selection.moveToStart()
|
||||
}
|
||||
|
||||
else if ((block && block.isVoid) || (inline && inline.isVoid)) {
|
||||
const next = document.getNextText(startKey)
|
||||
const previous = document.getPreviousText(startKey)
|
||||
after = next
|
||||
? selection.moveToStartOf(next)
|
||||
: selection.moveToEndOf(previous)
|
||||
}
|
||||
|
||||
// Delete forward and then update the selection.
|
||||
document = document.deleteForwardAtRange(selection)
|
||||
selection = after
|
||||
|
@@ -49,19 +49,21 @@ const DOCUMENT_TRANSFORMS = [
|
||||
*/
|
||||
|
||||
const SELECTION_TRANSFORMS = [
|
||||
'moveToAnchor',
|
||||
'moveToFocus',
|
||||
'moveToStart',
|
||||
'moveToEnd',
|
||||
'moveToStartOf',
|
||||
'moveToEndOf',
|
||||
'moveToRangeOf',
|
||||
'moveForward',
|
||||
'moveBackward',
|
||||
'extendForward',
|
||||
'blur',
|
||||
'extendBackward',
|
||||
'extendForward',
|
||||
'extendToEndOf',
|
||||
'extendToStartOf',
|
||||
'extendToEndOf'
|
||||
'focus',
|
||||
'moveBackward',
|
||||
'moveForward',
|
||||
'moveToAnchor',
|
||||
'moveToEnd',
|
||||
'moveToEndOf',
|
||||
'moveToFocus',
|
||||
'moveToRangeOf',
|
||||
'moveToStart',
|
||||
'moveToStartOf'
|
||||
]
|
||||
|
||||
/**
|
||||
|
@@ -97,15 +97,22 @@ const Transforms = {
|
||||
|
||||
deleteBackwardAtRange(range, n = 1) {
|
||||
let node = this
|
||||
|
||||
// When collapsed at the start of the node, there's nothing to do.
|
||||
if (range.isCollapsed && range.isAtStartOf(node)) return node
|
||||
const { startKey } = range
|
||||
|
||||
// When the range is still expanded, just do a regular delete.
|
||||
if (range.isExpanded) return node.deleteAtRange(range)
|
||||
|
||||
// When collapsed at the start of the node, there's nothing to do.
|
||||
if (range.isAtStartOf(node)) return node
|
||||
|
||||
// When collapsed in a void node, remove that node.
|
||||
const block = node.getClosestBlock(startKey)
|
||||
if (block && block.isVoid) return node.removeDescendant(block)
|
||||
|
||||
const inline = node.getClosestInline(startKey)
|
||||
if (inline && inline.isVoid) return node.removeDescendant(inline)
|
||||
|
||||
// When at start of a text node, merge forwards into the next text node.
|
||||
const { startKey } = range
|
||||
const startNode = node.getDescendant(startKey)
|
||||
|
||||
if (range.isAtStartOf(startNode)) {
|
||||
@@ -131,17 +138,23 @@ const Transforms = {
|
||||
|
||||
deleteForwardAtRange(range, n = 1) {
|
||||
let node = this
|
||||
|
||||
// When collapsed at the end of the node, there's nothing to do.
|
||||
if (range.isCollapsed && range.isAtEndOf(node)) return node
|
||||
const { startKey } = range
|
||||
|
||||
// When the range is still expanded, just do a regular delete.
|
||||
if (range.isExpanded) return node.deleteAtRange(range)
|
||||
|
||||
// When at end of a text node, merge forwards into the next text node.
|
||||
const { startKey } = range
|
||||
const startNode = node.getDescendant(startKey)
|
||||
// When collapsed at the end of the node, there's nothing to do.
|
||||
if (range.isAtEndOf(node)) return node
|
||||
|
||||
// When collapsed in a void node, remove that node.
|
||||
const block = node.getClosestBlock(startKey)
|
||||
if (block && block.isVoid) return node.removeDescendant(block)
|
||||
|
||||
const inline = node.getClosestInline(startKey)
|
||||
if (inline && inline.isVoid) return node.removeDescendant(inline)
|
||||
|
||||
// When at end of a text node, merge forwards into the next text node.
|
||||
const startNode = node.getDescendant(startKey)
|
||||
if (range.isAtEndOf(startNode)) {
|
||||
const next = node.getNextText(startNode)
|
||||
range = range.extendToStartOf(next)
|
||||
|
Reference in New Issue
Block a user