mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-23 15:32:59 +02:00
fix deleting for void nodes;
This commit is contained in:
@@ -27,36 +27,12 @@ class Void extends React.Component {
|
|||||||
state = state
|
state = state
|
||||||
.transform()
|
.transform()
|
||||||
.moveToStartOf(text)
|
.moveToStartOf(text)
|
||||||
|
.focus()
|
||||||
.apply()
|
.apply()
|
||||||
|
|
||||||
editor.onChange(state)
|
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() {
|
render() {
|
||||||
const { children, node } = this.props
|
const { children, node } = this.props
|
||||||
const Tag = node.kind == 'block' ? 'div' : 'span'
|
const Tag = node.kind == 'block' ? 'div' : 'span'
|
||||||
|
@@ -842,7 +842,9 @@ const Node = {
|
|||||||
|
|
||||||
// That void nodes contain no text.
|
// That void nodes contain no text.
|
||||||
if (desc.isVoid && desc.length) {
|
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)
|
const nodes = desc.nodes.clear().push(text)
|
||||||
desc = desc.merge({ nodes })
|
desc = desc.merge({ nodes })
|
||||||
}
|
}
|
||||||
|
@@ -183,6 +183,7 @@ class Selection extends Record(DEFAULTS) {
|
|||||||
|
|
||||||
normalize(node) {
|
normalize(node) {
|
||||||
let selection = this
|
let selection = this
|
||||||
|
const { isCollapsed } = selection
|
||||||
let { anchorKey, anchorOffset, focusKey, focusOffset, isBackward } = selection
|
let { anchorKey, anchorOffset, focusKey, focusOffset, isBackward } = selection
|
||||||
|
|
||||||
// If the selection isn't formed yet, abort.
|
// If the selection isn't formed yet, abort.
|
||||||
@@ -220,6 +221,36 @@ class Selection extends Record(DEFAULTS) {
|
|||||||
: anchorIndex > focusIndex
|
: 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.
|
// Merge in any updated properties.
|
||||||
return selection.merge({
|
return selection.merge({
|
||||||
anchorKey: anchorNode.key,
|
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.
|
* Move the focus point to the anchor point.
|
||||||
*
|
*
|
||||||
|
@@ -408,13 +408,25 @@ class State extends Record(DEFAULTS) {
|
|||||||
deleteForward(n = 1) {
|
deleteForward(n = 1) {
|
||||||
let state = this
|
let state = this
|
||||||
let { document, selection } = state
|
let { document, selection } = state
|
||||||
|
let { startKey } = selection
|
||||||
let after = selection
|
let after = selection
|
||||||
|
|
||||||
// Determine what the selection should be after deleting.
|
// Determine what the selection should be after deleting.
|
||||||
|
const block = document.getClosestBlock(startKey)
|
||||||
|
const inline = document.getClosestInline(startKey)
|
||||||
|
|
||||||
if (selection.isExpanded) {
|
if (selection.isExpanded) {
|
||||||
after = selection.moveToStart()
|
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.
|
// Delete forward and then update the selection.
|
||||||
document = document.deleteForwardAtRange(selection)
|
document = document.deleteForwardAtRange(selection)
|
||||||
selection = after
|
selection = after
|
||||||
|
@@ -49,19 +49,21 @@ const DOCUMENT_TRANSFORMS = [
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const SELECTION_TRANSFORMS = [
|
const SELECTION_TRANSFORMS = [
|
||||||
'moveToAnchor',
|
'blur',
|
||||||
'moveToFocus',
|
|
||||||
'moveToStart',
|
|
||||||
'moveToEnd',
|
|
||||||
'moveToStartOf',
|
|
||||||
'moveToEndOf',
|
|
||||||
'moveToRangeOf',
|
|
||||||
'moveForward',
|
|
||||||
'moveBackward',
|
|
||||||
'extendForward',
|
|
||||||
'extendBackward',
|
'extendBackward',
|
||||||
|
'extendForward',
|
||||||
|
'extendToEndOf',
|
||||||
'extendToStartOf',
|
'extendToStartOf',
|
||||||
'extendToEndOf'
|
'focus',
|
||||||
|
'moveBackward',
|
||||||
|
'moveForward',
|
||||||
|
'moveToAnchor',
|
||||||
|
'moveToEnd',
|
||||||
|
'moveToEndOf',
|
||||||
|
'moveToFocus',
|
||||||
|
'moveToRangeOf',
|
||||||
|
'moveToStart',
|
||||||
|
'moveToStartOf'
|
||||||
]
|
]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -97,15 +97,22 @@ const Transforms = {
|
|||||||
|
|
||||||
deleteBackwardAtRange(range, n = 1) {
|
deleteBackwardAtRange(range, n = 1) {
|
||||||
let node = this
|
let node = this
|
||||||
|
const { startKey } = range
|
||||||
// When collapsed at the start of the node, there's nothing to do.
|
|
||||||
if (range.isCollapsed && range.isAtStartOf(node)) return node
|
|
||||||
|
|
||||||
// When the range is still expanded, just do a regular delete.
|
// When the range is still expanded, just do a regular delete.
|
||||||
if (range.isExpanded) return node.deleteAtRange(range)
|
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.
|
// When at start of a text node, merge forwards into the next text node.
|
||||||
const { startKey } = range
|
|
||||||
const startNode = node.getDescendant(startKey)
|
const startNode = node.getDescendant(startKey)
|
||||||
|
|
||||||
if (range.isAtStartOf(startNode)) {
|
if (range.isAtStartOf(startNode)) {
|
||||||
@@ -131,17 +138,23 @@ const Transforms = {
|
|||||||
|
|
||||||
deleteForwardAtRange(range, n = 1) {
|
deleteForwardAtRange(range, n = 1) {
|
||||||
let node = this
|
let node = this
|
||||||
|
const { startKey } = range
|
||||||
// When collapsed at the end of the node, there's nothing to do.
|
|
||||||
if (range.isCollapsed && range.isAtEndOf(node)) return node
|
|
||||||
|
|
||||||
// When the range is still expanded, just do a regular delete.
|
// When the range is still expanded, just do a regular delete.
|
||||||
if (range.isExpanded) return node.deleteAtRange(range)
|
if (range.isExpanded) return node.deleteAtRange(range)
|
||||||
|
|
||||||
// When at end of a text node, merge forwards into the next text node.
|
// When collapsed at the end of the node, there's nothing to do.
|
||||||
const { startKey } = range
|
if (range.isAtEndOf(node)) return node
|
||||||
const startNode = node.getDescendant(startKey)
|
|
||||||
|
|
||||||
|
// 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)) {
|
if (range.isAtEndOf(startNode)) {
|
||||||
const next = node.getNextText(startNode)
|
const next = node.getNextText(startNode)
|
||||||
range = range.extendToStartOf(next)
|
range = range.extendToStartOf(next)
|
||||||
|
Reference in New Issue
Block a user