diff --git a/src/transforms/at-current-range.js b/src/transforms/at-current-range.js index 7315317bc..6f570f91a 100644 --- a/src/transforms/at-current-range.js +++ b/src/transforms/at-current-range.js @@ -108,9 +108,7 @@ export function _delete(transform) { export function deleteBackward(transform, n = 1) { const { state } = transform const { selection } = state - transform - .deleteBackwardAtRange(selection, n) - .collapseToEnd() + transform.deleteBackwardAtRange(selection, n) } /** @@ -123,9 +121,7 @@ export function deleteBackward(transform, n = 1) { export function deleteForward(transform, n = 1) { const { state } = transform const { selection } = state - transform - .deleteForwardAtRange(selection, n) - .collapseToEnd() + transform.deleteForwardAtRange(selection, n) } /** @@ -136,19 +132,11 @@ export function deleteForward(transform, n = 1) { */ export function insertBlock(transform, block) { - let { state } = transform - let { document, selection } = state - const keys = document.getTexts().map(text => text.key) - - transform.unsetSelection() + block = Normalize.block(block) + const { state } = transform + const { selection } = state transform.insertBlockAtRange(selection, block) - state = transform.state - document = state.document - - const text = document.getTexts().find(n => !keys.includes(n.key)) - const after = selection.collapseToEndOf(text) - - transform.moveTo(after) + transform.collapseToEndOf(block) } /** @@ -209,34 +197,18 @@ export function insertFragment(transform, fragment) { */ export function insertInline(transform, inline) { - let { state } = transform - let { document, selection, startText } = state - let after - - const hasVoid = document.hasVoidParent(startText.key) - const keys = document.getTexts().map(text => text.key) - - transform.unsetSelection() + inline = Normalize.inline(inline) + const { state } = transform + const { selection, startBlock } = state transform.insertInlineAtRange(selection, inline) - state = transform.state - document = state.document - if (hasVoid) { - after = selection - } + // If the start block is void, it won't have inserted at all. + if (startBlock.isVoid) return - else { - const text = document.getTexts().find((n) => { - if (keys.includes(n.key)) return false - const parent = document.getParent(n.key) - if (parent.kind != 'inline') return false - return true - }) - - after = selection.collapseToEndOf(text) - } - - transform.moveTo(after) + // Otherwise, find the inserted inline node, and collapse to the start of it. + const { document } = transform.state + inline = document.assertNode(inline.key) + transform.collapseToEndOf(inline) } /** diff --git a/src/transforms/at-range.js b/src/transforms/at-range.js index 57948d53d..0b126220b 100644 --- a/src/transforms/at-range.js +++ b/src/transforms/at-range.js @@ -4,6 +4,16 @@ import Normalize from '../utils/normalize' import SCHEMA from '../schemas/core' import { List } from 'immutable' +/** + * An options object with normalize set to `false`. + * + * @type {Object} + */ + +const OPTS = { + normalize: false +} + /** * Add a new `mark` to the characters at `range`. * @@ -68,8 +78,8 @@ export function deleteAtRange(transform, range, options = {}) { const startOff = (startChild.kind == 'text' ? 0 : startChild.getOffset(startKey)) + startOffset const endOff = (endChild.kind == 'text' ? 0 : endChild.getOffset(endKey)) + endOffset - transform.splitNodeByKey(startChild.key, startOff, { normalize: false }) - transform.splitNodeByKey(endChild.key, endOff, { normalize: false }) + transform.splitNodeByKey(startChild.key, startOff, OPTS) + transform.splitNodeByKey(endChild.key, endOff, OPTS) state = transform.state document = state.document @@ -87,7 +97,7 @@ export function deleteAtRange(transform, range, options = {}) { if (middles.size) { // remove first nodes directly so the document is not normalized middles.forEach(child => { - transform.removeNodeByKey(child.key, { normalize: false }) + transform.removeNodeByKey(child.key, OPTS) }) } @@ -95,11 +105,11 @@ export function deleteAtRange(transform, range, options = {}) { endBlock.nodes.forEach((child, i) => { const newKey = startBlock.key const newIndex = startBlock.nodes.size + i - transform.moveNodeByKey(child.key, newKey, newIndex, { normalize: false }) + transform.moveNodeByKey(child.key, newKey, newIndex, OPTS) }) const lonely = document.getFurthest(endBlock.key, p => p.nodes.size == 1) || endBlock - transform.removeNodeByKey(lonely.key, { normalize: false }) + transform.removeNodeByKey(lonely.key, OPTS) } if (normalize) { @@ -316,7 +326,7 @@ export function insertFragmentAtRange(transform, range, fragment, options = {}) // If the range is expanded, delete it first. if (range.isExpanded) { - transform.deleteAtRange(range, { normalize: false }) + transform.deleteAtRange(range, OPTS) range = range.collapseToStart() } @@ -357,13 +367,13 @@ export function insertFragmentAtRange(transform, range, fragment, options = {}) fragment.nodes.forEach((node, i) => { const newIndex = startIndex + i + 1 - transform.insertNodeByKey(parent.key, newIndex, node, { normalize: false }) + transform.insertNodeByKey(parent.key, newIndex, node, OPTS) }) } // Check if we need to split the node. if (startOffset != 0) { - transform.splitNodeByKey(startChild.key, offset, { normalize: false }) + transform.splitNodeByKey(startChild.key, offset, OPTS) } // Update our variables with the new state. @@ -383,15 +393,15 @@ export function insertFragmentAtRange(transform, range, fragment, options = {}) nextNodes.forEach((node, i) => { const newIndex = lastIndex + i - transform.moveNodeByKey(node.key, lastBlock.key, newIndex, { normalize: false }) + transform.moveNodeByKey(node.key, lastBlock.key, newIndex, OPTS) }) } // If the starting block is empty, we replace it entirely with the first block // of the fragment, since this leads to a more expected behavior for the user. if (startBlock.isEmpty) { - transform.removeNodeByKey(startBlock.key, { normalize: false }) - transform.insertNodeByKey(parent.key, index, firstBlock, { normalize: false }) + transform.removeNodeByKey(startBlock.key, OPTS) + transform.insertNodeByKey(parent.key, index, firstBlock, OPTS) } // Otherwise, we maintain the starting block, and insert all of the first @@ -403,7 +413,7 @@ export function insertFragmentAtRange(transform, range, fragment, options = {}) firstBlock.nodes.forEach((inline, i) => { const o = startOffset == 0 ? 0 : 1 const newIndex = inlineIndex + i + o - transform.insertNodeByKey(startBlock.key, newIndex, inline, { normalize: false }) + transform.insertNodeByKey(startBlock.key, newIndex, inline, OPTS) }) } @@ -428,7 +438,7 @@ export function insertInlineAtRange(transform, range, inline, options = {}) { inline = Normalize.inline(inline) if (range.isExpanded) { - transform.deleteAtRange(range, { normalize: false }) + transform.deleteAtRange(range, OPTS) range = range.collapseToStart() } @@ -441,8 +451,8 @@ export function insertInlineAtRange(transform, range, inline, options = {}) { if (parent.isVoid) return - transform.splitNodeByKey(startKey, startOffset, { normalize: false }) - transform.insertNodeByKey(parent.key, index + 1, inline, { normalize: false }) + transform.splitNodeByKey(startKey, startOffset, OPTS) + transform.insertNodeByKey(parent.key, index + 1, inline, OPTS) if (normalize) { transform.normalizeNodeByKey(parent.key, SCHEMA) @@ -470,7 +480,7 @@ export function insertTextAtRange(transform, range, text, marks, options = {}) { if (parent.isVoid) return if (range.isExpanded) { - transform.deleteAtRange(range, { normalize: false }) + transform.deleteAtRange(range, OPTS) } // PERF: Unless specified, don't normalize if only inserting text. @@ -702,17 +712,17 @@ export function unwrapBlockAtRange(transform, range, properties, options = {}) { if (first == firstMatch && last == lastMatch) { block.nodes.forEach((child, i) => { - transform.moveNodeByKey(child.key, parent.key, index + i, { normalize: false }) + transform.moveNodeByKey(child.key, parent.key, index + i, OPTS) }) - transform.removeNodeByKey(block.key, { normalize: false }) + transform.removeNodeByKey(block.key, OPTS) } else if (last == lastMatch) { block.nodes .skipUntil(n => n == firstMatch) .forEach((child, i) => { - transform.moveNodeByKey(child.key, parent.key, index + 1 + i, { normalize: false }) + transform.moveNodeByKey(child.key, parent.key, index + 1 + i, OPTS) }) } @@ -721,23 +731,23 @@ export function unwrapBlockAtRange(transform, range, properties, options = {}) { .takeUntil(n => n == lastMatch) .push(lastMatch) .forEach((child, i) => { - transform.moveNodeByKey(child.key, parent.key, index + i, { normalize: false }) + transform.moveNodeByKey(child.key, parent.key, index + i, OPTS) }) } else { const offset = block.getOffset(firstMatch.key) - transform.splitNodeByKey(block.key, offset, { normalize: false }) + transform.splitNodeByKey(block.key, offset, OPTS) state = transform.state document = state.document const extra = document.getPreviousSibling(firstMatch.key) children.forEach((child, i) => { - transform.moveNodeByKey(child.key, parent.key, index + 1 + i, { normalize: false }) + transform.moveNodeByKey(child.key, parent.key, index + 1 + i, OPTS) }) - transform.removeNodeByKey(extra.key, { normalize: false }) + transform.removeNodeByKey(extra.key, OPTS) } }) @@ -783,7 +793,7 @@ export function unwrapInlineAtRange(transform, range, properties, options = {}) const index = parent.nodes.indexOf(inline) inline.nodes.forEach((child, i) => { - transform.moveNodeByKey(child.key, parent.key, index + i, { normalize: false }) + transform.moveNodeByKey(child.key, parent.key, index + i, OPTS) }) }) @@ -850,11 +860,11 @@ export function wrapBlockAtRange(transform, range, block, options = {}) { } // inject the new block node into the parent - transform.insertNodeByKey(parent.key, index, block, { normalize: false }) + transform.insertNodeByKey(parent.key, index, block, OPTS) // move the sibling nodes into the new block node siblings.forEach((node, i) => { - transform.moveNodeByKey(node.key, block.key, i, { normalize: false }) + transform.moveNodeByKey(node.key, block.key, i, OPTS) }) if (normalize) { @@ -900,11 +910,11 @@ export function wrapInlineAtRange(transform, range, inline, options = {}) { if (startBlock == endBlock) { if (endOff != endChild.length) { - transform.splitNodeByKey(endChild.key, endOff, { normalize: false }) + transform.splitNodeByKey(endChild.key, endOff, OPTS) } if (startOff != 0) { - transform.splitNodeByKey(startChild.key, startOff, { normalize: false }) + transform.splitNodeByKey(startChild.key, startOff, OPTS) } state = transform.state @@ -926,10 +936,10 @@ export function wrapInlineAtRange(transform, range, inline, options = {}) { const node = inline.regenerateKey() - transform.insertNodeByKey(startBlock.key, startInnerIndex, node, { normalize: false }) + transform.insertNodeByKey(startBlock.key, startInnerIndex, node, OPTS) inlines.forEach((child, i) => { - transform.moveNodeByKey(child.key, node.key, i, { normalize: false }) + transform.moveNodeByKey(child.key, node.key, i, OPTS) }) if (normalize) { @@ -938,8 +948,8 @@ export function wrapInlineAtRange(transform, range, inline, options = {}) { } else { - transform.splitNodeByKey(startChild.key, startOff, { normalize: false }) - transform.splitNodeByKey(endChild.key, endOff, { normalize: false }) + transform.splitNodeByKey(startChild.key, startOff, OPTS) + transform.splitNodeByKey(endChild.key, endOff, OPTS) state = transform.state document = state.document @@ -951,15 +961,15 @@ export function wrapInlineAtRange(transform, range, inline, options = {}) { const startNode = inline.regenerateKey() const endNode = inline.regenerateKey() - transform.insertNodeByKey(startBlock.key, startIndex - 1, startNode, { normalize: false }) - transform.insertNodeByKey(endBlock.key, endIndex, endNode, { normalize: false }) + transform.insertNodeByKey(startBlock.key, startIndex - 1, startNode, OPTS) + transform.insertNodeByKey(endBlock.key, endIndex, endNode, OPTS) startInlines.forEach((child, i) => { - transform.moveNodeByKey(child.key, startNode.key, i, { normalize: false }) + transform.moveNodeByKey(child.key, startNode.key, i, OPTS) }) endInlines.forEach((child, i) => { - transform.moveNodeByKey(child.key, endNode.key, i, { normalize: false }) + transform.moveNodeByKey(child.key, endNode.key, i, OPTS) }) if (normalize) { @@ -970,10 +980,10 @@ export function wrapInlineAtRange(transform, range, inline, options = {}) { blocks.slice(1, -1).forEach((block) => { const node = inline.regenerateKey() - transform.insertNodeByKey(block.key, 0, node, { normalize: false }) + transform.insertNodeByKey(block.key, 0, node, OPTS) block.nodes.forEach((child, i) => { - transform.moveNodeByKey(child.key, node.key, i, { normalize: false }) + transform.moveNodeByKey(child.key, node.key, i, OPTS) }) if (normalize) {