mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-17 20:51:20 +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 {Transform} transform
|
||||||
* @param {Selection} range
|
* @param {Selection} range
|
||||||
* @param {Number} depth (optional)
|
* @param {Number} height (optional)
|
||||||
* @return {Transform}
|
* @return {Transform}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function splitBlockAtRange(transform, range, depth = 1) {
|
export function splitBlockAtRange(transform, range, height = 1) {
|
||||||
let { state } = transform
|
|
||||||
let { document } = state
|
|
||||||
|
|
||||||
// If the range is expanded, remove it first.
|
|
||||||
if (range.isExpanded) {
|
if (range.isExpanded) {
|
||||||
transform = deleteAtRange(transform, range)
|
transform.deleteAtRange(range)
|
||||||
state = transform.state
|
|
||||||
document = state.document
|
|
||||||
range = range.collapseToStart()
|
range = range.collapseToStart()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split the inline nodes at the range.
|
const { startKey, startOffset } = range
|
||||||
transform = splitInlineAtRange(transform, range)
|
const { state } = transform
|
||||||
state = transform.state
|
const { document } = state
|
||||||
document = state.document
|
let node = document.assertDescendant(startKey)
|
||||||
|
let parent = document.getClosestBlock(node)
|
||||||
|
let offset = startOffset
|
||||||
|
let h = 0
|
||||||
|
|
||||||
// Find the highest inline elements that were split.
|
while (parent && parent.kind == 'block' && h < height) {
|
||||||
const { startKey } = range
|
offset += parent.getOffset(node)
|
||||||
const firstText = document.getDescendant(startKey)
|
node = parent
|
||||||
const secondText = document.getNextText(startKey)
|
parent = document.getClosestBlock(parent)
|
||||||
let firstChild = document.getFurthestInline(firstText) || firstText
|
h++
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state = state.merge({ document })
|
transform.splitNodeByKey(node.key, offset)
|
||||||
transform.state = state
|
transform.normalizeDocument()
|
||||||
return transform
|
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 {Transform} transform
|
||||||
* @param {Selection} range
|
* @param {Selection} range
|
||||||
* @param {Number} depth (optiona)
|
* @param {Number} height (optiona)
|
||||||
* @return {Transform}
|
* @return {Transform}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function splitInlineAtRange(transform, range, depth = Infinity) {
|
export function splitInlineAtRange(transform, range, height = Infinity) {
|
||||||
if (range.isExpanded) {
|
if (range.isExpanded) {
|
||||||
transform.deleteAtRange(range)
|
transform.deleteAtRange(range)
|
||||||
range = range.collapseToStart()
|
range = range.collapseToStart()
|
||||||
@@ -704,19 +669,13 @@ export function splitInlineAtRange(transform, range, depth = Infinity) {
|
|||||||
let node = document.assertDescendant(startKey)
|
let node = document.assertDescendant(startKey)
|
||||||
let parent = document.getClosestInline(node)
|
let parent = document.getClosestInline(node)
|
||||||
let offset = startOffset
|
let offset = startOffset
|
||||||
let d = 0
|
let h = 0
|
||||||
|
|
||||||
debugger
|
while (parent && parent.kind == 'inline' && h < height) {
|
||||||
|
offset += parent.getOffset(node)
|
||||||
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
|
|
||||||
node = parent
|
node = parent
|
||||||
parent = document.getClosestInline(parent)
|
parent = document.getClosestInline(parent)
|
||||||
d++
|
h++
|
||||||
}
|
}
|
||||||
|
|
||||||
return transform.splitNodeByKey(node.key, offset)
|
return transform.splitNodeByKey(node.key, offset)
|
||||||
|
@@ -340,9 +340,10 @@ export function splitNodeByKey(transform, key, offset) {
|
|||||||
|
|
||||||
while (child && child != parent) {
|
while (child && child != parent) {
|
||||||
if (child.kind == 'text') {
|
if (child.kind == 'text') {
|
||||||
|
const i = node.kind == 'text' ? offset : offset - node.getOffset(child)
|
||||||
const { characters } = child
|
const { characters } = child
|
||||||
const oneChars = characters.take(offset)
|
const oneChars = characters.take(i)
|
||||||
const twoChars = characters.skip(offset)
|
const twoChars = characters.skip(i)
|
||||||
one = child.merge({ characters: oneChars })
|
one = child.merge({ characters: oneChars })
|
||||||
two = child.merge({ characters: twoChars, key: uid() })
|
two = child.merge({ characters: twoChars, key: uid() })
|
||||||
}
|
}
|
||||||
|
@@ -100,6 +100,15 @@ import {
|
|||||||
moveToRangeOf,
|
moveToRangeOf,
|
||||||
} from './on-selection'
|
} from './on-selection'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
normalizeDocument,
|
||||||
|
normalizeSelection,
|
||||||
|
} from './normalize'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Export.
|
* Export.
|
||||||
*
|
*
|
||||||
@@ -201,4 +210,11 @@ export default {
|
|||||||
moveToOffsets,
|
moveToOffsets,
|
||||||
moveToRangeOf,
|
moveToRangeOf,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize.
|
||||||
|
*/
|
||||||
|
|
||||||
|
normalizeDocument,
|
||||||
|
normalizeSelection,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user