mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-09-09 14:40:41 +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:
committed by
Ian Storm Taylor
parent
526d162002
commit
e396941963
@@ -187,19 +187,42 @@ function moveNode(state, operation) {
|
|||||||
const { path, newPath, newIndex } = operation
|
const { path, newPath, newIndex } = operation
|
||||||
let { document } = state
|
let { document } = state
|
||||||
const node = document.assertPath(path)
|
const node = document.assertPath(path)
|
||||||
|
const index = path.pop()
|
||||||
|
const parentDepth = path.length
|
||||||
|
|
||||||
// Remove the node from its current parent
|
// Remove the node from its current parent
|
||||||
let parent = document.getParent(node.key)
|
let parent = document.getParent(node.key)
|
||||||
const isParent = document == parent
|
|
||||||
const index = parent.nodes.indexOf(node)
|
|
||||||
parent = parent.removeNode(index)
|
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
|
// Insert the new node to its new parent
|
||||||
let target = document.assertPath(newPath)
|
|
||||||
const isTarget = document == target
|
|
||||||
target = target.insertNode(newIndex, node)
|
target = target.insertNode(newIndex, node)
|
||||||
document = isTarget ? target : document.updateDescendant(target)
|
document = target.kind === 'document' ? target : document.updateDescendant(target)
|
||||||
|
|
||||||
state = state.set('document', document)
|
state = state.set('document', document)
|
||||||
return state
|
return state
|
||||||
|
@@ -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()
|
||||||
|
}
|
@@ -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
|
@@ -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
|
Reference in New Issue
Block a user