mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-02-23 16:55:23 +01:00
improvements to wrapBlockAtRange() (#343)
* add failing test for 340 * fix wrapBlockAtRange to handle multiple deep children (#340) * failing test for wrapblock changes * wrapBlockAtRange using top-most parent logic * Revert "wrapBlockAtRange using top-most parent logic" This reverts commit 4f056285f78e0ed2fc6ed34586f204c601fe8d29.
This commit is contained in:
parent
e486e87311
commit
27168a388d
@ -721,24 +721,53 @@ export function wrapBlockAtRange(transform, range, block) {
|
||||
|
||||
const { state } = transform
|
||||
const { document } = state
|
||||
|
||||
const blocks = document.getBlocksAtRange(range)
|
||||
const depth = blocks.map(n => document.getDepth(n)).min()
|
||||
const firstblock = blocks.first()
|
||||
const lastblock = blocks.last()
|
||||
let parent, siblings, index
|
||||
|
||||
const siblings = blocks
|
||||
.map((node) => {
|
||||
const d = document.getDepth(node)
|
||||
if (d == depth) return node
|
||||
return document.getClosest(node, p => document.getDepth(p) == depth)
|
||||
// if there is only one block in the selection then we know the parent and siblings
|
||||
if (blocks.length === 1) {
|
||||
parent = document.getParent(firstblock)
|
||||
siblings = blocks
|
||||
}
|
||||
|
||||
// determine closest shared parent to all blocks in selection
|
||||
else {
|
||||
parent = document.getClosest(firstblock, p1 => {
|
||||
return !!document.getClosest(lastblock, p2 => p1 == p2)
|
||||
})
|
||||
.toOrderedSet()
|
||||
.toList()
|
||||
}
|
||||
|
||||
const first = siblings.first()
|
||||
const parent = document.getParent(first)
|
||||
const index = parent.nodes.indexOf(first)
|
||||
// if no shared parent could be found then the parent is the document
|
||||
if (parent == null) parent = document
|
||||
|
||||
transform.insertNodeByKey(parent.key, index, block)
|
||||
// create a list of direct children siblings of parent that fall in the selection
|
||||
if (siblings == null) {
|
||||
const indexes = parent.nodes.reduce((ind, node, i) => {
|
||||
if (node == firstblock || node.hasDescendant(firstblock)) ind[0] = i
|
||||
if (node == lastblock || node.hasDescendant(lastblock)) ind[1] = i
|
||||
return ind
|
||||
}, [])
|
||||
|
||||
index = indexes[0]
|
||||
siblings = parent.nodes.slice(indexes[0], indexes[1] + 1)
|
||||
}
|
||||
|
||||
// get the index to place the new wrapped node at
|
||||
if (index == null) {
|
||||
index = parent.nodes.indexOf(siblings.first())
|
||||
}
|
||||
|
||||
// inject the new block node into the parent
|
||||
if (parent != document) {
|
||||
transform.insertNodeByKey(parent.key, index, block)
|
||||
} else {
|
||||
transform.insertNodeOperation([], index, block)
|
||||
}
|
||||
|
||||
// move the sibling nodes into the new block node
|
||||
siblings.forEach((node, i) => {
|
||||
transform.moveNodeByKey(node.key, block.key, i)
|
||||
})
|
||||
|
@ -0,0 +1,11 @@
|
||||
|
||||
export default function (state) {
|
||||
const { selection, document } = state
|
||||
const blocks = document.getBlocks()
|
||||
const range = selection.moveToRangeOf(blocks.first(), blocks.last())
|
||||
|
||||
return state
|
||||
.transform()
|
||||
.wrapBlockAtRange(range, 'bulleted-list')
|
||||
.apply()
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: list-item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: text
|
||||
text: word1
|
||||
- kind: block
|
||||
type: list-item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: text
|
||||
text: word2
|
@ -0,0 +1,21 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: bulleted-list
|
||||
nodes:
|
||||
- kind: block
|
||||
type: list-item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: text
|
||||
text: word1
|
||||
- kind: block
|
||||
type: list-item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: text
|
||||
text: word2
|
Loading…
x
Reference in New Issue
Block a user