1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-29 09:59:48 +02:00

moveNode operation fix (#782)

* Fix `moveNode` operation.
When `parent` is an ancestor of `target` and the index of `node` is
less than the index of the ancestor of `target` with the same depth
of `node`, removing `node` changes the path to `target`.
As consequence of that, `newPath` needs to be adjusted.

* Add test.

* Improve code.
This commit is contained in:
AlbertHilb
2017-05-05 02:14:24 +02:00
committed by Ian Storm Taylor
parent 526d162002
commit e396941963
4 changed files with 70 additions and 6 deletions

View File

@@ -187,19 +187,42 @@ function moveNode(state, operation) {
const { path, newPath, newIndex } = operation
let { document } = state
const node = document.assertPath(path)
const index = path.pop()
const parentDepth = path.length
// Remove the node from its current parent
let parent = document.getParent(node.key)
const isParent = document == parent
const index = parent.nodes.indexOf(node)
parent = parent.removeNode(index)
document = isParent ? parent : document.updateDescendant(parent)
document = parent.kind === 'document' ? parent : document.updateDescendant(parent)
// Check if `parent` is an anchestor of `target`
const isAncestor = path.every((x, i) => x === newPath[i])
let target
// If `parent` ia an ancestor of `target` and they have the same depth,
// then `parent` and `target` are the same node.
if (isAncestor && parentDepth === newPath.length) {
target = parent
}
// Else if `parent` is an ancestor of `target` and `node` index is less than
// the index of the `target` ancestor with the same depth of `node`,
// then removing `node` changes the path to `target`.
// So we have to adjust `newPath` before picking `target`.
else if (isAncestor && index < newPath[parentDepth]) {
newPath[parentDepth]--
target = document.assertPath(newPath)
}
// Else pick `target`
else {
target = document.assertPath(newPath)
}
// Insert the new node to its new parent
let target = document.assertPath(newPath)
const isTarget = document == target
target = target.insertNode(newIndex, node)
document = isTarget ? target : document.updateDescendant(target)
document = target.kind === 'document' ? target : document.updateDescendant(target)
state = state.set('document', document)
return state

View File

@@ -0,0 +1,11 @@
export default function (state) {
const { document, selection } = state
const first = document.getBlocks().first()
const container = document.nodes.last()
return state
.transform()
.moveNodeByKey(first.key, container.key, 1)
.apply()
}

View File

@@ -0,0 +1,15 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: one
- kind: block
type: container
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: two

View File

@@ -0,0 +1,15 @@
nodes:
- kind: block
type: container
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: two
- kind: block
type: paragraph
nodes:
- kind: text
text: one