1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-20 06:01:24 +02:00

fix insert fragment logic;

This commit is contained in:
Ian Storm Taylor
2016-06-27 15:15:11 -07:00
parent 9fd4e0af86
commit cb2dda5bf4
2 changed files with 67 additions and 35 deletions

View File

@@ -428,39 +428,48 @@ class State extends Record(DEFAULTS) {
const nextBlock = nextText ? document.getClosestBlock(nextText) : null const nextBlock = nextText ? document.getClosestBlock(nextText) : null
const nextNextText = nextText ? document.getNextText(nextText) : null const nextNextText = nextText ? document.getNextText(nextText) : null
const docTexts = document.getTextNodes()
// Insert the fragment. // Insert the fragment.
document = document.insertFragmentAtRange(selection, fragment) document = document.insertFragmentAtRange(selection, fragment)
// Determine what the selection should be after inserting. // Determine what the selection should be after inserting.
if (texts.size == 1) { // if (texts.size == 1) {
after = selection // after = selection
.moveToStart() // .moveToStart()
.moveForward(fragment.length) // .moveForward(fragment.length)
} // }
else if (!nextText) { // else if (!nextText) {
const text = document.getTextNodes().last() // const text = document.getTextNodes().last()
after = selection // after = selection
.moveToStartOf(text) // .moveToStartOf(text)
.moveForward(lastText.length) // .moveForward(lastText.length)
} // }
else if (nextBlock != startBlock || lastInline || startInline) { // else if (nextBlock != startBlock || lastInline || startInline) {
const text = document.getPreviousText(nextText) // const text = document.getPreviousText(nextText)
after = selection // after = selection
.moveToStartOf(text) // .moveToStartOf(text)
.moveForward(lastText.length) // .moveForward(lastText.length)
} // }
else { // else {
const text = nextNextText // const text = nextNextText
? document.getPreviousText(nextNextText) // ? document.getPreviousText(nextNextText)
: document.getPreviousText(document.getTextNodes().last()) // : document.getPreviousText(document.getTextNodes().last())
after = selection // after = selection
.moveToStartOf(text) // .moveToStartOf(text)
.moveForward(lastText.length) // .moveForward(lastText.length)
} // }
const keys = docTexts.map(text => text.key)
const text = document.getTextNodes().findLast(text => !keys.includes(text.key))
after = text
? selection.moveToStartOf(text).moveForward(lastText.length)
: selection.moveToStart().moveForward(lastText.length)
// Update the document and selection. // Update the document and selection.
selection = after selection = after
@@ -468,6 +477,9 @@ class State extends Record(DEFAULTS) {
return state return state
} }
/** /**
* Insert a `text` string at the current selection. * Insert a `text` string at the current selection.
* *

View File

@@ -176,30 +176,50 @@ const Transforms = {
// If the fragment is empty, do nothing. // If the fragment is empty, do nothing.
if (!fragment.length) return node if (!fragment.length) return node
// Make sure each node in the fragment has a unique key.
fragment = fragment.mapDescendants(node => node.set('key', uid()))
// Split the inlines if need be. // Split the inlines if need be.
if (!node.isInlineSplitAtRange(range)) { if (!node.isInlineSplitAtRange(range)) {
node = node.splitInlineAtRange(range) node = node.splitInlineAtRange(range)
} }
// Make sure each node in the fragment has a new key. // Determine the start and next children to insert into.
fragment = fragment.mapDescendants(node => node.set('key', uid()))
// Insert the contents of the first block into the block at the cursor.
const { startKey, endKey } = range const { startKey, endKey } = range
let block = node.getClosestBlock(startKey) let block = node.getClosestBlock(startKey)
let start = node.getDescendant(startKey) let start = node.getDescendant(startKey)
if (!range.isAtEndOf(start)) start = node.getPreviousText(start) let startChild
let nextChild
const startChild = start ? block.getHighestChild(start) : null if (range.isAtStartOf(node)) {
const nextChild = startChild nextChild = node.getClosestBlock(node.getTextNodes().first())
? block.getNextSibling(startChild) }
: node.getClosestBlock(node.getTextNodes().first())
if (range.isAtStartOf(block)) {
nextChild = block.getHighestChild(block.getTextNodes().first())
}
else if (range.isAtStartOf(start)) {
startChild = block.getHighestChild(block.getPreviousText(start))
nextChild = block.getNextSibling(startChild)
}
else {
startChild = block.getHighestChild(start)
nextChild = block.getNextSibling(startChild)
}
// Insert the contents of the first block into the block at the cursor.
const blocks = fragment.getDeepestBlocks() const blocks = fragment.getDeepestBlocks()
const firstBlock = blocks.first() const firstBlock = blocks.first()
let lastBlock = blocks.last() let lastBlock = blocks.last()
block = block.insertChildrenBefore(nextChild, firstBlock.nodes) if (startChild) {
block = block.insertChildrenAfter(startChild, firstBlock.nodes)
} else {
block = block.insertChildrenBefore(nextChild, firstBlock.nodes)
}
node = node.updateDescendant(block) node = node.updateDescendant(block)
// If there are no other siblings, that's it. // If there are no other siblings, that's it.