diff --git a/lib/models/state.js b/lib/models/state.js index 969cc854e..0ee1daaa7 100644 --- a/lib/models/state.js +++ b/lib/models/state.js @@ -428,39 +428,48 @@ class State extends Record(DEFAULTS) { const nextBlock = nextText ? document.getClosestBlock(nextText) : null const nextNextText = nextText ? document.getNextText(nextText) : null + const docTexts = document.getTextNodes() + // Insert the fragment. document = document.insertFragmentAtRange(selection, fragment) // Determine what the selection should be after inserting. - if (texts.size == 1) { - after = selection - .moveToStart() - .moveForward(fragment.length) - } + // if (texts.size == 1) { + // after = selection + // .moveToStart() + // .moveForward(fragment.length) + // } - else if (!nextText) { - const text = document.getTextNodes().last() - after = selection - .moveToStartOf(text) - .moveForward(lastText.length) - } + // else if (!nextText) { + // const text = document.getTextNodes().last() + // after = selection + // .moveToStartOf(text) + // .moveForward(lastText.length) + // } - else if (nextBlock != startBlock || lastInline || startInline) { - const text = document.getPreviousText(nextText) - after = selection - .moveToStartOf(text) - .moveForward(lastText.length) - } + // else if (nextBlock != startBlock || lastInline || startInline) { + // const text = document.getPreviousText(nextText) + // after = selection + // .moveToStartOf(text) + // .moveForward(lastText.length) + // } - else { - const text = nextNextText - ? document.getPreviousText(nextNextText) - : document.getPreviousText(document.getTextNodes().last()) + // else { + // const text = nextNextText + // ? document.getPreviousText(nextNextText) + // : document.getPreviousText(document.getTextNodes().last()) - after = selection - .moveToStartOf(text) - .moveForward(lastText.length) - } + // after = selection + // .moveToStartOf(text) + // .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. selection = after @@ -468,6 +477,9 @@ class State extends Record(DEFAULTS) { return state } + + + /** * Insert a `text` string at the current selection. * diff --git a/lib/models/transforms.js b/lib/models/transforms.js index 6cc0da38f..bf55fe88e 100644 --- a/lib/models/transforms.js +++ b/lib/models/transforms.js @@ -176,30 +176,50 @@ const Transforms = { // If the fragment is empty, do nothing. 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. if (!node.isInlineSplitAtRange(range)) { node = node.splitInlineAtRange(range) } - // Make sure each node in the fragment has a new key. - fragment = fragment.mapDescendants(node => node.set('key', uid())) - - // Insert the contents of the first block into the block at the cursor. + // Determine the start and next children to insert into. const { startKey, endKey } = range let block = node.getClosestBlock(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 - const nextChild = startChild - ? block.getNextSibling(startChild) - : node.getClosestBlock(node.getTextNodes().first()) + if (range.isAtStartOf(node)) { + nextChild = 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 firstBlock = blocks.first() 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) // If there are no other siblings, that's it.