mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-16 12:14:14 +02:00
refactor more transforms
This commit is contained in:
@@ -614,85 +614,50 @@ export function setInlineAtRange(transform, range, properties) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Split the block nodes at a `range`, to optional `depth`.
|
||||
* Split the block nodes at a `range`, to optional `height`.
|
||||
*
|
||||
* @param {Transform} transform
|
||||
* @param {Selection} range
|
||||
* @param {Number} depth (optional)
|
||||
* @param {Number} height (optional)
|
||||
* @return {Transform}
|
||||
*/
|
||||
|
||||
export function splitBlockAtRange(transform, range, depth = 1) {
|
||||
let { state } = transform
|
||||
let { document } = state
|
||||
|
||||
// If the range is expanded, remove it first.
|
||||
export function splitBlockAtRange(transform, range, height = 1) {
|
||||
if (range.isExpanded) {
|
||||
transform = deleteAtRange(transform, range)
|
||||
state = transform.state
|
||||
document = state.document
|
||||
transform.deleteAtRange(range)
|
||||
range = range.collapseToStart()
|
||||
}
|
||||
|
||||
// Split the inline nodes at the range.
|
||||
transform = splitInlineAtRange(transform, range)
|
||||
state = transform.state
|
||||
document = state.document
|
||||
const { startKey, startOffset } = range
|
||||
const { state } = transform
|
||||
const { document } = state
|
||||
let node = document.assertDescendant(startKey)
|
||||
let parent = document.getClosestBlock(node)
|
||||
let offset = startOffset
|
||||
let h = 0
|
||||
|
||||
// Find the highest inline elements that were split.
|
||||
const { startKey } = range
|
||||
const firstText = document.getDescendant(startKey)
|
||||
const secondText = document.getNextText(startKey)
|
||||
let firstChild = document.getFurthestInline(firstText) || firstText
|
||||
let secondChild = document.getFurthestInline(secondText) || secondText
|
||||
let parent = document.getClosestBlock(firstChild)
|
||||
let firstChildren
|
||||
let secondChildren
|
||||
let d = 0
|
||||
|
||||
// While the parent is a block, split the block nodes.
|
||||
while (parent && d < depth) {
|
||||
firstChildren = parent.nodes.takeUntil(n => n == firstChild).push(firstChild)
|
||||
secondChildren = parent.nodes.skipUntil(n => n == secondChild)
|
||||
firstChild = parent.merge({ nodes: firstChildren })
|
||||
secondChild = Block.create({
|
||||
nodes: secondChildren,
|
||||
type: parent.type,
|
||||
data: parent.data
|
||||
})
|
||||
|
||||
// Add the new children.
|
||||
const grandparent = document.getParent(parent)
|
||||
const nodes = grandparent.nodes
|
||||
.takeUntil(n => n.key == firstChild.key)
|
||||
.push(firstChild)
|
||||
.push(secondChild)
|
||||
.concat(grandparent.nodes.skipUntil(n => n.key == firstChild.key).rest())
|
||||
|
||||
// Update the grandparent.
|
||||
document = grandparent == document
|
||||
? document.merge({ nodes })
|
||||
: document.updateDescendant(grandparent.merge({ nodes }))
|
||||
|
||||
d++
|
||||
parent = document.getClosestBlock(firstChild)
|
||||
while (parent && parent.kind == 'block' && h < height) {
|
||||
offset += parent.getOffset(node)
|
||||
node = parent
|
||||
parent = document.getClosestBlock(parent)
|
||||
h++
|
||||
}
|
||||
|
||||
state = state.merge({ document })
|
||||
transform.state = state
|
||||
transform.splitNodeByKey(node.key, offset)
|
||||
transform.normalizeDocument()
|
||||
return transform
|
||||
}
|
||||
|
||||
/**
|
||||
* Split the inline nodes at a `range`, to optional `depth`.
|
||||
* Split the inline nodes at a `range`, to optional `height`.
|
||||
*
|
||||
* @param {Transform} transform
|
||||
* @param {Selection} range
|
||||
* @param {Number} depth (optiona)
|
||||
* @param {Number} height (optiona)
|
||||
* @return {Transform}
|
||||
*/
|
||||
|
||||
export function splitInlineAtRange(transform, range, depth = Infinity) {
|
||||
export function splitInlineAtRange(transform, range, height = Infinity) {
|
||||
if (range.isExpanded) {
|
||||
transform.deleteAtRange(range)
|
||||
range = range.collapseToStart()
|
||||
@@ -704,19 +669,13 @@ export function splitInlineAtRange(transform, range, depth = Infinity) {
|
||||
let node = document.assertDescendant(startKey)
|
||||
let parent = document.getClosestInline(node)
|
||||
let offset = startOffset
|
||||
let d = 0
|
||||
let h = 0
|
||||
|
||||
debugger
|
||||
|
||||
while (parent && parent.kind == 'inline' && d < depth) {
|
||||
const index = parent.nodes.indexOf(node)
|
||||
const befores = parent.nodes.take(index)
|
||||
const length = befores.reduce((l, n) => n.length, 0)
|
||||
|
||||
offset += length
|
||||
while (parent && parent.kind == 'inline' && h < height) {
|
||||
offset += parent.getOffset(node)
|
||||
node = parent
|
||||
parent = document.getClosestInline(parent)
|
||||
d++
|
||||
h++
|
||||
}
|
||||
|
||||
return transform.splitNodeByKey(node.key, offset)
|
||||
|
@@ -340,9 +340,10 @@ export function splitNodeByKey(transform, key, offset) {
|
||||
|
||||
while (child && child != parent) {
|
||||
if (child.kind == 'text') {
|
||||
const i = node.kind == 'text' ? offset : offset - node.getOffset(child)
|
||||
const { characters } = child
|
||||
const oneChars = characters.take(offset)
|
||||
const twoChars = characters.skip(offset)
|
||||
const oneChars = characters.take(i)
|
||||
const twoChars = characters.skip(i)
|
||||
one = child.merge({ characters: oneChars })
|
||||
two = child.merge({ characters: twoChars, key: uid() })
|
||||
}
|
||||
|
@@ -100,6 +100,15 @@ import {
|
||||
moveToRangeOf,
|
||||
} from './on-selection'
|
||||
|
||||
/**
|
||||
* Normalize.
|
||||
*/
|
||||
|
||||
import {
|
||||
normalizeDocument,
|
||||
normalizeSelection,
|
||||
} from './normalize'
|
||||
|
||||
/**
|
||||
* Export.
|
||||
*
|
||||
@@ -201,4 +210,11 @@ export default {
|
||||
moveToOffsets,
|
||||
moveToRangeOf,
|
||||
|
||||
/**
|
||||
* Normalize.
|
||||
*/
|
||||
|
||||
normalizeDocument,
|
||||
normalizeSelection,
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user