1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-09-01 03:11:44 +02:00

Fix bugs in deleteAtRange (#1072)

* Fix bug in deleteAtRange when selecting part of non-void block followed by void block

* Fix bug in deleteAtRange when selecting from an inline void node

* Fix bug with deleteAtRange if a whole startBlock was selected, fixes #1021
This commit is contained in:
Per-Kristian Nordnes
2017-09-07 18:15:25 +02:00
committed by Ian Storm Taylor
parent 01bc6944bd
commit 697a771014
16 changed files with 347 additions and 8 deletions

View File

@@ -135,6 +135,16 @@ Changes.deleteAtRange = (change, range, options = {}) => {
}
}
// If the selection starts at an inline void, remove that void inline first
const startInline = document.getClosestInline(startKey)
if (startInline && startInline.isVoid &&
startInline.getTexts().first().key == startKey) {
const nextText = document.getNextText(startInline.getTexts().first().key)
change.removeNodeByKey(startInline.key, OPTS)
startKey = nextText.key
startOffset = 0
}
// If the start and end key are the same, we can just remove it.
if (startKey == endKey) {
// If it is a void node, remove the whole node
@@ -178,10 +188,12 @@ Changes.deleteAtRange = (change, range, options = {}) => {
ancestor = document.getCommonAncestor(startKey, endKey)
startChild = ancestor.getFurthestAncestor(startKey)
endChild = ancestor.getFurthestAncestor(endKey)
const nextText = document.getNextText(endKey)
const startIndex = ancestor.nodes.indexOf(startChild)
const endIndex = ancestor.nodes.indexOf(endChild)
const middles = ancestor.nodes.slice(startIndex + 1, endIndex + 1)
const next = document.getNextText(endKey)
// Remove all of the middle nodes, between the splits.
if (middles.size) {
@@ -190,16 +202,25 @@ Changes.deleteAtRange = (change, range, options = {}) => {
})
}
// If the start and end block are different, move all of the nodes from the
// end block into the start block.
// Refresh variables
state = change.state
document = state.document
const startBlock = document.getClosestBlock(startKey)
const endBlock = document.getClosestBlock(next.key)
// If the endBlock is void, just remove the startBlock
if (endBlock.isVoid) {
change.removeNodeByKey(startBlock.key)
const startBlock = document.getClosestBlock(startKey)
const endBlock = document.getClosestBlock(nextText.key)
// If the whole startBlock is selected but the endBlock is different, just remove the startBlock
if (startBlock.key !== endBlock.key && startChild.text.length === endOffset && startOffset === 0) {
document = change.removeNodeByKey(startBlock.key, OPTS).state.document
return
}
// If the endBlock is void, remove what is selected of the start block
if (endBlock.isVoid && endOffset === 0) {
// If part of the startBlock is selected, split it and remove the unwanted part
document = change.splitNodeByKey(startChild.key, startOffset, OPTS).state.document
const toBeRemoved = document.nodes.get(startIndex + 1)
change.removeNodeByKey(toBeRemoved.key, OPTS)
return
}

View File

@@ -0,0 +1,37 @@
import assert from 'assert'
export default function (state) {
const { document, selection } = state
const texts = document.getTexts()
const first = texts.first()
const second = texts.get(1)
const range = selection.merge({
anchorKey: first.key,
anchorOffset: 4,
focusKey: second.key,
focusOffset: 0
})
const next = state
.change()
.select(range)
.delete()
.state
const anchorAndFocusKey = next.document.getTexts().first()
assert.deepEqual(
next.selection.toJS(),
{
anchorKey: anchorAndFocusKey.key,
anchorOffset: anchorAndFocusKey.characters.size,
focusKey: anchorAndFocusKey.key,
focusOffset: anchorAndFocusKey.characters.size,
isBackward: false,
isFocused: false,
marks: null
}
)
return next
}

View File

@@ -0,0 +1,15 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: one two
- kind: block
type: image
isVoid: true
- kind: block
type: paragraph
nodes:
- kind: text
text: three

View File

@@ -0,0 +1,15 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: "one "
- kind: block
type: image
isVoid: true
- kind: block
type: paragraph
nodes:
- kind: text
text: three

View File

@@ -0,0 +1,37 @@
import assert from 'assert'
export default function (state) {
const { document, selection } = state
const texts = document.getTexts()
const first = texts.first()
const second = texts.get(1)
const range = selection.merge({
anchorKey: first.key,
anchorOffset: 4,
focusKey: second.key,
focusOffset: 1
})
const next = state
.change()
.select(range)
.delete()
.state
const anchorAndFocusKey = next.document.getTexts().first()
assert.deepEqual(
next.selection.toJS(),
{
anchorKey: anchorAndFocusKey.key,
anchorOffset: anchorAndFocusKey.characters.size,
focusKey: anchorAndFocusKey.key,
focusOffset: anchorAndFocusKey.characters.size,
isBackward: false,
isFocused: false,
marks: null
}
)
return next
}

View File

@@ -0,0 +1,15 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: one two
- kind: block
type: image
isVoid: true
- kind: block
type: paragraph
nodes:
- kind: text
text: three

View File

@@ -0,0 +1,12 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: "one "
- kind: block
type: paragraph
nodes:
- kind: text
text: three

View File

@@ -0,0 +1,36 @@
import assert from 'assert'
export default function (state) {
const { document, selection } = state
const texts = document.getTexts()
const first = texts.first()
const range = selection.merge({
anchorKey: first.key,
anchorOffset: 4,
focusKey: first.key,
focusOffset: 7
})
const next = state
.change()
.select(range)
.delete()
.state
const anchorAndFocusKey = next.document.getTexts().first()
assert.deepEqual(
next.selection.toJS(),
{
anchorKey: anchorAndFocusKey.key,
anchorOffset: anchorAndFocusKey.characters.size,
focusKey: anchorAndFocusKey.key,
focusOffset: anchorAndFocusKey.characters.size,
isBackward: false,
isFocused: false,
marks: null
}
)
return next
}

View File

@@ -0,0 +1,15 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: one two
- kind: block
type: image
isVoid: true
- kind: block
type: paragraph
nodes:
- kind: text
text: three

View File

@@ -0,0 +1,15 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: "one "
- kind: block
type: image
isVoid: true
- kind: block
type: paragraph
nodes:
- kind: text
text: three

View File

@@ -0,0 +1,37 @@
import assert from 'assert'
export default function (state) {
const { document, selection } = state
const texts = document.getTexts()
const firstText = texts.first()
const inlineText = texts.get(1)
const lastBlockText = texts.get(3)
const range = selection.merge({
anchorKey: inlineText.key,
anchorOffset: 0,
focusKey: lastBlockText.key,
focusOffset: 0
})
const next = state
.change()
.select(range)
.delete()
.state
const newFirstText = next.document.getTexts().first()
assert.deepEqual(
next.selection.toJS(),
{
anchorKey: newFirstText.key,
anchorOffset: firstText.text.length,
focusKey: newFirstText.key,
focusOffset: firstText.text.length,
isBackward: false,
isFocused: false,
marks: null
}
)
return next
}

View File

@@ -0,0 +1,20 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: one
- kind: inline
type: image
isVoid: true
nodes:
- kind: text
text: ""
- kind: text
text: two
- kind: block
type: paragraph
nodes:
- kind: text
text: three

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: onethree

View File

@@ -0,0 +1,38 @@
import assert from 'assert'
export default function (state) {
const { document, selection } = state
const texts = document.getTexts()
const first = texts.first()
const second = texts.get(1)
const range = selection.merge({
anchorKey: first.key,
anchorOffset: 0,
focusKey: second.key,
focusOffset: 0
})
const next = state
.change()
.select(range)
.delete()
.state
const newFirst = next.document.getTexts().first()
assert.deepEqual(
next.selection.toJS(),
{
anchorKey: newFirst.key,
anchorOffset: 0,
focusKey: newFirst.key,
focusOffset: 0,
isBackward: false,
isFocused: false,
marks: null
}
)
return next
}

View File

@@ -0,0 +1,12 @@
nodes:
- kind: block
type: h1
nodes:
- kind: text
text: "A header"
- kind: block
type: paragraph
nodes:
- kind: text
text: "A paragraph"

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: "A paragraph"