1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-04-21 13:51:59 +02:00

fix to always opt for the furthest text node at an offset

This commit is contained in:
Ian Storm Taylor 2016-11-29 16:19:40 -08:00
parent ecf320eb66
commit 083df2dd93
5 changed files with 62 additions and 8 deletions
src
models
transforms
test/transforms/fixtures/at-range/delete-backward-at-range/join-blocks-with-inline-void

@ -990,8 +990,14 @@ const Node = {
let length = 0
return this
.getTexts()
.find((text) => {
.find((text, i, texts) => {
const next = texts.get(i + 1)
length += text.length
// If the next text is an empty string, return false, because we want
// the furthest text node at the offset, and it will also match.
if (next && next.length == 0) return false
return length >= offset
})
},

@ -61,6 +61,7 @@ export function deleteAtRange(transform, range, options = {}) {
const { normalize = true } = options
const { startKey, startOffset, endKey, endOffset } = range
// If the start and end key are the same, we can just remove text.
if (startKey == endKey) {
const index = startOffset
const length = endOffset - startOffset
@ -68,10 +69,9 @@ export function deleteAtRange(transform, range, options = {}) {
return
}
// Split at the range edges within a common ancestor, without normalizing.
let { state } = transform
let { document } = state
// split the nodes at range, within the common ancestor
let ancestor = document.getCommonAncestor(startKey, endKey)
let startChild = ancestor.getHighestChild(startKey)
let endChild = ancestor.getHighestChild(endKey)
@ -81,12 +81,9 @@ export function deleteAtRange(transform, range, options = {}) {
transform.splitNodeByKey(startChild.key, startOff, OPTS)
transform.splitNodeByKey(endChild.key, endOff, OPTS)
// Refresh variables.
state = transform.state
document = state.document
const startBlock = document.getClosestBlock(startKey)
const endBlock = document.getClosestBlock(document.getNextText(endKey).key)
// remove all of the nodes between range
ancestor = document.getCommonAncestor(startKey, endKey)
startChild = ancestor.getHighestChild(startKey)
endChild = ancestor.getHighestChild(endKey)
@ -94,13 +91,18 @@ export function deleteAtRange(transform, range, options = {}) {
const endIndex = ancestor.nodes.indexOf(endChild)
const middles = ancestor.nodes.slice(startIndex + 1, endIndex + 1)
// Remove all of the middle nodes, between the splits.
if (middles.size) {
// remove first nodes directly so the document is not normalized
middles.forEach(child => {
transform.removeNodeByKey(child.key, OPTS)
})
}
// If the start and end block are different, move all of the nodes from the
// end block into the start block.
const startBlock = document.getClosestBlock(startKey)
const endBlock = document.getClosestBlock(document.getNextText(endKey).key)
if (startBlock.key !== endBlock.key) {
endBlock.nodes.forEach((child, i) => {
const newKey = startBlock.key

@ -0,0 +1,17 @@
export default function (state) {
const { document, selection } = state
const texts = document.getTexts()
const last = texts.last()
const range = selection.merge({
anchorKey: last.key,
anchorOffset: 0,
focusKey: last.key,
focusOffset: 0
})
return state
.transform()
.deleteBackwardAtRange(range)
.apply()
}

@ -0,0 +1,17 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: ""
- kind: inline
type: emoji
isVoid: true
- kind: text
text: ""
- kind: block
type: paragraph
nodes:
- kind: text
text: ""

@ -0,0 +1,12 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: ""
- kind: inline
type: emoji
isVoid: true
- kind: text
text: ""