1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-17 12:41:44 +02:00

refactor more transforms

This commit is contained in:
Ian Storm Taylor
2016-08-17 01:41:37 -07:00
parent 1d4c6db4d4
commit 3ad03538fd
3 changed files with 44 additions and 68 deletions

View File

@@ -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)

View File

@@ -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() })
}

View File

@@ -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,
}