mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-17 04:34:00 +02:00
fix deleteAtRange to split only to common ancestor
This commit is contained in:
@@ -296,6 +296,32 @@ const Node = {
|
||||
return this.nodes.find(node => node.key == key)
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the common ancestor of nodes `one` and `two` by keys.
|
||||
*
|
||||
* @param {String or Node} one
|
||||
* @param {String or Node} two
|
||||
* @return {Node}
|
||||
*/
|
||||
|
||||
getCommonAncestor(one, two) {
|
||||
this.assertDescendant(one)
|
||||
this.assertDescendant(two)
|
||||
let ancestors = new List()
|
||||
let oneParent = this.getParent(one)
|
||||
let twoParent = this.getParent(two)
|
||||
|
||||
while (oneParent) {
|
||||
ancestors = ancestors.push(oneParent)
|
||||
oneParent = this.getParent(oneParent)
|
||||
}
|
||||
|
||||
while (twoParent) {
|
||||
if (ancestors.includes(twoParent)) return twoParent
|
||||
twoParent = this.getParent(twoParent)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a descendant node by `key`.
|
||||
*
|
||||
|
@@ -86,42 +86,50 @@ const Transforms = {
|
||||
// Split the blocks and determine the edge boundaries.
|
||||
const start = range.collapseToStart()
|
||||
const end = range.collapseToEnd()
|
||||
node = node.splitBlockAtRange(start, Infinity)
|
||||
node = node.splitBlockAtRange(end, Infinity)
|
||||
let ancestor = node.getCommonAncestor(startKey, endKey)
|
||||
const isAncestor = ancestor == node
|
||||
|
||||
const startText = node.getDescendant(startKey)
|
||||
const startEdgeText = node.getNextText(startKey)
|
||||
ancestor = ancestor.splitBlockAtRange(start, Infinity)
|
||||
ancestor = ancestor.splitBlockAtRange(end, Infinity)
|
||||
|
||||
const endText = node.getNextText(endKey)
|
||||
const endEdgeText = node.getDescendant(endKey)
|
||||
const startText = ancestor.getDescendant(startKey)
|
||||
const startEdgeText = ancestor.getNextText(startKey)
|
||||
|
||||
const endText = ancestor.getNextText(endKey)
|
||||
const endEdgeText = ancestor.getDescendant(endKey)
|
||||
|
||||
// Remove the new blocks inside the edges.
|
||||
const startEdgeBlock = node.getFurthestBlock(startEdgeText)
|
||||
const endEdgeBlock = node.getFurthestBlock(endEdgeText)
|
||||
const startEdgeBlock = ancestor.getFurthestBlock(startEdgeText)
|
||||
const endEdgeBlock = ancestor.getFurthestBlock(endEdgeText)
|
||||
|
||||
const nodes = node.nodes
|
||||
const nodes = ancestor.nodes
|
||||
.takeUntil(n => n == startEdgeBlock)
|
||||
.concat(node.nodes.skipUntil(n => n == endEdgeBlock).rest())
|
||||
.concat(ancestor.nodes.skipUntil(n => n == endEdgeBlock).rest())
|
||||
|
||||
node = node.merge({ nodes })
|
||||
ancestor = ancestor.merge({ nodes })
|
||||
|
||||
// Take the end edge's split text and move it to the start edge.
|
||||
let startBlock = node.getClosestBlock(startText)
|
||||
let endChild = node.getFurthestInline(endText) || endText
|
||||
let startBlock = ancestor.getClosestBlock(startText)
|
||||
let endChild = ancestor.getFurthestInline(endText) || endText
|
||||
|
||||
const startNodes = startBlock.nodes.push(endChild)
|
||||
startBlock = startBlock.merge({ nodes: startNodes })
|
||||
node = node.updateDescendant(startBlock)
|
||||
ancestor = ancestor.updateDescendant(startBlock)
|
||||
|
||||
// While the end child is an only child, remove the block it's in.
|
||||
let endParent = node.getClosestBlock(endChild)
|
||||
let endParent = ancestor.getClosestBlock(endChild)
|
||||
|
||||
while (endParent && endParent.nodes.size == 1) {
|
||||
endChild = endParent
|
||||
endParent = node.getClosestBlock(endParent)
|
||||
endParent = ancestor.getClosestBlock(endParent)
|
||||
}
|
||||
|
||||
node = node.removeDescendant(endChild)
|
||||
ancestor = ancestor.removeDescendant(endChild)
|
||||
|
||||
// Update the node.
|
||||
node = isAncestor
|
||||
? ancestor
|
||||
: node.updateDescendant(ancestor)
|
||||
|
||||
// Normalize the adjacent text nodes.
|
||||
return node.normalize()
|
||||
|
@@ -0,0 +1,19 @@
|
||||
|
||||
export default function (state) {
|
||||
const { document, selection } = state
|
||||
const texts = document.getTexts()
|
||||
const first = texts.get(0)
|
||||
const second = texts.get(1)
|
||||
const third = texts.get(2)
|
||||
const range = selection.merge({
|
||||
anchorKey: first.key,
|
||||
anchorOffset: first.length,
|
||||
focusKey: second.key,
|
||||
focusOffset: 0
|
||||
})
|
||||
|
||||
return state
|
||||
.transform()
|
||||
.deleteAtRange(range)
|
||||
.apply()
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: list
|
||||
nodes:
|
||||
- kind: block
|
||||
type: item
|
||||
nodes:
|
||||
- kind: text
|
||||
text: one
|
||||
- kind: block
|
||||
type: item
|
||||
nodes:
|
||||
- kind: text
|
||||
text: two
|
||||
- kind: block
|
||||
type: item
|
||||
nodes:
|
||||
- kind: text
|
||||
text: three
|
@@ -0,0 +1,15 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: list
|
||||
nodes:
|
||||
- kind: block
|
||||
type: item
|
||||
nodes:
|
||||
- kind: text
|
||||
text: onetwo
|
||||
- kind: block
|
||||
type: item
|
||||
nodes:
|
||||
- kind: text
|
||||
text: three
|
@@ -0,0 +1,29 @@
|
||||
|
||||
import assert from 'assert'
|
||||
|
||||
export default function (state) {
|
||||
const { document, selection } = state
|
||||
const texts = document.getTexts()
|
||||
const first = texts.get(0)
|
||||
const second = texts.get(1)
|
||||
const third = texts.get(2)
|
||||
const range = selection.merge({
|
||||
anchorKey: first.key,
|
||||
anchorOffset: first.length,
|
||||
focusKey: second.key,
|
||||
focusOffset: 0
|
||||
})
|
||||
|
||||
const next = state
|
||||
.transform()
|
||||
.moveTo(range)
|
||||
.delete()
|
||||
.apply()
|
||||
|
||||
assert.deepEqual(
|
||||
next.selection.toJS(),
|
||||
range.collapseToStart().toJS()
|
||||
)
|
||||
|
||||
return next
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: list
|
||||
nodes:
|
||||
- kind: block
|
||||
type: item
|
||||
nodes:
|
||||
- kind: text
|
||||
text: one
|
||||
- kind: block
|
||||
type: item
|
||||
nodes:
|
||||
- kind: text
|
||||
text: two
|
||||
- kind: block
|
||||
type: item
|
||||
nodes:
|
||||
- kind: text
|
||||
text: three
|
@@ -0,0 +1,15 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: list
|
||||
nodes:
|
||||
- kind: block
|
||||
type: item
|
||||
nodes:
|
||||
- kind: text
|
||||
text: onetwo
|
||||
- kind: block
|
||||
type: item
|
||||
nodes:
|
||||
- kind: text
|
||||
text: three
|
Reference in New Issue
Block a user