From 007cdf916f51b3dcdbd52e4f88dd13d2c81b0a14 Mon Sep 17 00:00:00 2001 From: Ian Storm Taylor Date: Tue, 22 Nov 2016 14:37:10 -0800 Subject: [PATCH 01/13] refactor transforms --- src/models/node.js | 3 ++ src/models/transform.js | 3 +- src/transforms/by-key.js | 79 ++++++++-------------------------------- 3 files changed, 20 insertions(+), 65 deletions(-) diff --git a/src/models/node.js b/src/models/node.js index 00dd79b45..addd35f7f 100644 --- a/src/models/node.js +++ b/src/models/node.js @@ -387,6 +387,9 @@ const Node = { */ getCommonAncestor(one, two) { + if (one == this.key) return this + if (two == this.key) return this + this.assertDescendant(one) this.assertDescendant(two) let ancestors = new List() diff --git a/src/models/transform.js b/src/models/transform.js index 857d3554e..7f7fba219 100644 --- a/src/models/transform.js +++ b/src/models/transform.js @@ -99,7 +99,8 @@ class Transform { Object.keys(Transforms).forEach((type) => { Transform.prototype[type] = function (...args) { debug(type, { args }) - return Transforms[type](this, ...args) + Transforms[type](this, ...args) + return this } }) diff --git a/src/transforms/by-key.js b/src/transforms/by-key.js index aab7bbfc3..4791e4224 100644 --- a/src/transforms/by-key.js +++ b/src/transforms/by-key.js @@ -12,7 +12,6 @@ import SCHEMA from '../schemas/core' * @param {Mixed} mark * @param {Object} options * @param {Boolean} normalize - * @return {Transform} */ export function addMarkByKey(transform, key, offset, length, mark, options = {}) { @@ -28,8 +27,6 @@ export function addMarkByKey(transform, key, offset, length, mark, options = {}) const parent = document.getParent(key) transform.normalizeNodeByKey(parent.key, SCHEMA) } - - return transform } /** @@ -41,7 +38,6 @@ export function addMarkByKey(transform, key, offset, length, mark, options = {}) * @param {Node} node * @param {Object} options * @param {Boolean} normalize - * @return {Transform} */ export function insertNodeByKey(transform, key, index, node, options = {}) { @@ -55,8 +51,6 @@ export function insertNodeByKey(transform, key, index, node, options = {}) { if (normalize) { transform.normalizeNodeByKey(key, SCHEMA) } - - return transform } /** @@ -69,7 +63,6 @@ export function insertNodeByKey(transform, key, index, node, options = {}) { * @param {Set} marks (optional) * @param {Object} options * @param {Boolean} normalize - * @return {Transform} */ export function insertTextByKey(transform, key, offset, text, marks, options = {}) { @@ -84,8 +77,6 @@ export function insertTextByKey(transform, key, offset, text, marks, options = { const parent = document.getParent(key) transform.normalizeNodeByKey(parent.key, SCHEMA) } - - return transform } /** @@ -96,7 +87,6 @@ export function insertTextByKey(transform, key, offset, text, marks, options = { * @param {String} withKey * @param {Object} options * @param {Boolean} normalize - * @return {Transform} */ export function joinNodeByKey(transform, key, withKey, options = {}) { @@ -110,14 +100,8 @@ export function joinNodeByKey(transform, key, withKey, options = {}) { if (normalize) { const parent = document.getCommonAncestor(key, withKey) - if (parent) { - transform.normalizeNodeByKey(parent.key, SCHEMA) - } else { - transform.normalizeDocument(SCHEMA) - } + transform.normalizeNodeByKey(parent.key, SCHEMA) } - - return transform } /** @@ -130,7 +114,6 @@ export function joinNodeByKey(transform, key, withKey, options = {}) { * @param {Number} index * @param {Object} options * @param {Boolean} normalize - * @return {Transform} */ export function moveNodeByKey(transform, key, newKey, newIndex, options = {}) { @@ -143,11 +126,9 @@ export function moveNodeByKey(transform, key, newKey, newIndex, options = {}) { transform.moveNodeOperation(path, newPath, newIndex) if (normalize) { - const parent = document.key == newKey ? document : document.getCommonAncestor(key, newKey) + const parent = document.getCommonAncestor(key, newKey) transform.normalizeNodeByKey(parent.key, SCHEMA) } - - return transform } /** @@ -160,7 +141,6 @@ export function moveNodeByKey(transform, key, newKey, newIndex, options = {}) { * @param {Mark} mark * @param {Object} options * @param {Boolean} normalize - * @return {Transform} */ export function removeMarkByKey(transform, key, offset, length, mark, options = {}) { @@ -176,8 +156,6 @@ export function removeMarkByKey(transform, key, offset, length, mark, options = const parent = document.getParent(key) transform.normalizeNodeByKey(parent.key, SCHEMA) } - - return transform } /** @@ -187,7 +165,6 @@ export function removeMarkByKey(transform, key, offset, length, mark, options = * @param {String} key * @param {Object} options * @param {Boolean} normalize - * @return {Transform} */ export function removeNodeByKey(transform, key, options = {}) { @@ -200,14 +177,8 @@ export function removeNodeByKey(transform, key, options = {}) { if (normalize) { const parent = document.getParent(key) - if (parent) { - transform.normalizeNodeByKey(parent.key, SCHEMA) - } else { - transform.normalizeDocument(SCHEMA) - } + transform.normalizeNodeByKey(parent.key, SCHEMA) } - - return transform } /** @@ -219,7 +190,6 @@ export function removeNodeByKey(transform, key, options = {}) { * @param {Number} length * @param {Object} options * @param {Boolean} normalize - * @return {Transform} */ export function removeTextByKey(transform, key, offset, length, options = {}) { @@ -234,8 +204,6 @@ export function removeTextByKey(transform, key, offset, length, options = {}) { const parent = document.getParent(key) transform.normalizeParentsByKey(parent.key, SCHEMA) } - - return transform } /** @@ -248,7 +216,6 @@ export function removeTextByKey(transform, key, offset, length, options = {}) { * @param {Mark} mark * @param {Object} options * @param {Boolean} normalize - * @return {Transform} */ export function setMarkByKey(transform, key, offset, length, mark, properties, options = {}) { @@ -266,8 +233,6 @@ export function setMarkByKey(transform, key, offset, length, mark, properties, o const parent = document.getParent(key) transform.normalizeNodeByKey(parent.key, SCHEMA) } - - return transform } /** @@ -278,7 +243,6 @@ export function setMarkByKey(transform, key, offset, length, mark, properties, o * @param {Object|String} properties * @param {Object} options * @param {Boolean} normalize - * @return {Transform} */ export function setNodeByKey(transform, key, properties, options = {}) { @@ -292,14 +256,8 @@ export function setNodeByKey(transform, key, properties, options = {}) { if (normalize) { const parent = document.getParent(key) - if (parent) { - transform.normalizeNodeByKey(parent.key, SCHEMA) - } else { - transform.normalizeDocument(SCHEMA) - } + transform.normalizeNodeByKey(parent.key, SCHEMA) } - - return transform } /** @@ -310,7 +268,6 @@ export function setNodeByKey(transform, key, properties, options = {}) { * @param {Number} offset * @param {Object} options * @param {Boolean} normalize - * @return {Transform} */ export function splitNodeByKey(transform, key, offset, options = {}) { @@ -323,14 +280,8 @@ export function splitNodeByKey(transform, key, offset, options = {}) { if (normalize) { const parent = document.getParent(key) - if (parent) { - transform.normalizeNodeByKey(parent.key, SCHEMA) - } else { - transform.normalizeDocument(SCHEMA) - } + transform.normalizeNodeByKey(parent.key, SCHEMA) } - - return transform } /** @@ -341,15 +292,16 @@ export function splitNodeByKey(transform, key, offset, options = {}) { * @param {Object|String} properties * @param {Object} options * @param {Boolean} normalize - * @return {Transform} */ export function unwrapInlineByKey(transform, key, properties, options) { const { state } = transform const { document, selection } = state const node = document.assertDescendant(key) - const range = selection.moveToRangeOf(node.getFirstText(), node.getLastText()) - return transform.unwrapInlineAtRange(range, properties, options) + const first = node.getFirstText() + const last = node.getLastText() + const range = selection.moveToRangeOf(first, last) + transform.unwrapInlineAtRange(range, properties, options) } /** @@ -360,15 +312,16 @@ export function unwrapInlineByKey(transform, key, properties, options) { * @param {Object|String} properties * @param {Object} options * @param {Boolean} normalize - * @return {Transform} */ export function unwrapBlockByKey(transform, key, properties, options) { const { state } = transform const { document, selection } = state const node = document.assertDescendant(key) - const range = selection.moveToRangeOf(node.getFirstText(), node.getLastText()) - return transform.unwrapBlockAtRange(range, properties, options) + const first = node.getFirstText() + const last = node.getLastText() + const range = selection.moveToRangeOf(first, last) + transform.unwrapBlockAtRange(range, properties, options) } /** @@ -379,7 +332,6 @@ export function unwrapBlockByKey(transform, key, properties, options) { * @param {Block|Object|String} block The wrapping block (its children are discarded) * @param {Object} options * @param {Boolean} normalize - * @return {Transform} */ export function wrapBlockByKey(transform, key, block, options) { @@ -391,7 +343,6 @@ export function wrapBlockByKey(transform, key, block, options) { const parent = document.getParent(node.key) const index = parent.nodes.indexOf(node) - return transform - .insertNodeByKey(parent.key, index, block, { normalize: false }) - .moveNodeByKey(node.key, block.key, 0, options) + transform.insertNodeByKey(parent.key, index, block, { normalize: false }) + transform.moveNodeByKey(node.key, block.key, 0, options) } From 02120857b9c400d500280b9053f9c3b958018159 Mon Sep 17 00:00:00 2001 From: Ian Storm Taylor Date: Tue, 22 Nov 2016 14:47:41 -0800 Subject: [PATCH 02/13] remove return value from transforms --- src/transforms/apply-operation.js | 4 - src/transforms/at-current-range.js | 77 +++++++----------- src/transforms/at-range.js | 125 ++++++++++------------------- src/transforms/normalize.js | 51 +++--------- src/transforms/on-history.js | 12 +-- src/transforms/on-selection.js | 94 ++++++++-------------- src/transforms/operations.js | 36 +++------ 7 files changed, 131 insertions(+), 268 deletions(-) diff --git a/src/transforms/apply-operation.js b/src/transforms/apply-operation.js index d31ba66b2..0c20b1d30 100644 --- a/src/transforms/apply-operation.js +++ b/src/transforms/apply-operation.js @@ -40,7 +40,6 @@ const OPERATIONS = { * * @param {Transform} transform * @param {Object} operation - * @return {Transform} */ export function applyOperation(transform, operation) { @@ -53,11 +52,8 @@ export function applyOperation(transform, operation) { } debug(type, operation) - transform.state = fn(state, operation) transform.operations = operations.concat([operation]) - - return transform } /** diff --git a/src/transforms/at-current-range.js b/src/transforms/at-current-range.js index 78cac2ded..5f81d2a7d 100644 --- a/src/transforms/at-current-range.js +++ b/src/transforms/at-current-range.js @@ -6,7 +6,6 @@ import Normalize from '../utils/normalize' * * @param {Transform} transform * @param {Mark} mark - * @return {Transform} */ export function addMark(transform, mark) { @@ -16,19 +15,19 @@ export function addMark(transform, mark) { const { document, selection } = state if (selection.isExpanded) { - return transform.addMarkAtRange(selection, mark) + transform.addMarkAtRange(selection, mark) } else if (selection.marks) { const marks = selection.marks.add(mark) const sel = selection.merge({ marks }) - return transform.moveTo(sel) + transform.moveTo(sel) } else { const marks = document.getMarksAtRange(selection).add(mark) const sel = selection.merge({ marks }) - return transform.moveTo(sel) + transform.moveTo(sel) } } @@ -36,7 +35,6 @@ export function addMark(transform, mark) { * Delete at the current selection. * * @param {Transform} transform - * @return {Transform} */ export function _delete(transform) { @@ -44,7 +42,7 @@ export function _delete(transform) { const { document, selection } = state // If the selection is collapsed, there's nothing to delete. - if (selection.isCollapsed) return transform + if (selection.isCollapsed) return const { startText } = state const { startKey, startOffset, endKey, endOffset } = selection @@ -95,7 +93,7 @@ export function _delete(transform) { after = selection.collapseToStart() } - return transform + transform .unsetSelection() .deleteAtRange(selection) .moveTo(after) @@ -106,14 +104,12 @@ export function _delete(transform) { * * @param {Transform} transform * @param {Number} n (optional) - * @return {Transform} */ export function deleteBackward(transform, n = 1) { const { state } = transform const { selection } = state - - return transform + transform .deleteBackwardAtRange(selection, n) .collapseToEnd() } @@ -123,14 +119,12 @@ export function deleteBackward(transform, n = 1) { * * @param {Transform} transform * @param {Number} n (optional) - * @return {Transform} */ export function deleteForward(transform, n = 1) { const { state } = transform const { selection } = state - - return transform + transform .deleteForwardAtRange(selection, n) .collapseToEnd() } @@ -140,7 +134,6 @@ export function deleteForward(transform, n = 1) { * * @param {Transform} transform * @param {String|Object|Block} block - * @return {Transform} */ export function insertBlock(transform, block) { @@ -156,7 +149,7 @@ export function insertBlock(transform, block) { const text = document.getTexts().find(n => !keys.includes(n.key)) const after = selection.collapseToEndOf(text) - return transform.moveTo(after) + transform.moveTo(after) } /** @@ -164,14 +157,13 @@ export function insertBlock(transform, block) { * * @param {Transform} transform * @param {Document} fragment - * @return {Transform} */ export function insertFragment(transform, fragment) { let { state } = transform let { document, selection } = state - if (!fragment.length) return transform + if (!fragment.length) return const { startText, endText } = state const lastText = fragment.getLastText() @@ -207,7 +199,7 @@ export function insertFragment(transform, fragment) { .moveForward(lastText.length) } - return transform.moveTo(after) + transform.moveTo(after) } /** @@ -215,7 +207,6 @@ export function insertFragment(transform, fragment) { * * @param {Transform} transform * @param {String|Object|Block} inline - * @return {Transform} */ export function insertInline(transform, inline) { @@ -246,7 +237,7 @@ export function insertInline(transform, inline) { after = selection.collapseToEndOf(text) } - return transform.moveTo(after) + transform.moveTo(after) } /** @@ -255,7 +246,6 @@ export function insertInline(transform, inline) { * @param {Transform} transform * @param {String} text * @param {Set} marks (optional) - * @return {Transform} */ export function insertText(transform, text, marks) { @@ -279,7 +269,7 @@ export function insertText(transform, text, marks) { marks = marks || selection.marks - return transform + transform .unsetSelection() .insertTextAtRange(selection, text, marks) .moveTo(after) @@ -290,13 +280,12 @@ export function insertText(transform, text, marks) { * * @param {Transform} transform * @param {Object} properties - * @return {Transform} */ export function setBlock(transform, properties) { const { state } = transform const { selection } = state - return transform.setBlockAtRange(selection, properties) + transform.setBlockAtRange(selection, properties) } /** @@ -304,13 +293,12 @@ export function setBlock(transform, properties) { * * @param {Transform} transform * @param {Object} properties - * @return {Transform} */ export function setInline(transform, properties) { const { state } = transform const { selection } = state - return transform.setInlineAtRange(selection, properties) + transform.setInlineAtRange(selection, properties) } /** @@ -318,7 +306,6 @@ export function setInline(transform, properties) { * * @param {Transform} transform * @param {Number} depth (optional) - * @return {Transform} */ export function splitBlock(transform, depth = 1) { @@ -354,7 +341,7 @@ export function splitBlock(transform, depth = 1) { after = selection.collapseToStartOf(nextText) } - return transform.moveTo(after) + transform.moveTo(after) } /** @@ -362,7 +349,6 @@ export function splitBlock(transform, depth = 1) { * * @param {Transform} transform * @param {Number} depth (optional) - * @return {Transform} */ export function splitInline(transform, depth = Infinity) { @@ -389,7 +375,7 @@ export function splitInline(transform, depth = Infinity) { (offset + startOffset == 0) || (offset + startNode.length == startOffset) ) { - return transform + return } transform.unsetSelection() @@ -404,7 +390,7 @@ export function splitInline(transform, depth = Infinity) { after = selection.collapseToStartOf(nextNode) } - return transform.moveTo(after) + transform.moveTo(after) } /** @@ -412,29 +398,27 @@ export function splitInline(transform, depth = Infinity) { * * @param {Transform} transform * @param {Mark} mark - * @return {Transform} */ export function removeMark(transform, mark) { mark = Normalize.mark(mark) - const { state } = transform const { document, selection } = state if (selection.isExpanded) { - return transform.removeMarkAtRange(selection, mark) + transform.removeMarkAtRange(selection, mark) } else if (selection.marks) { const marks = selection.marks.remove(mark) const sel = selection.merge({ marks }) - return transform.moveTo(sel) + transform.moveTo(sel) } else { const marks = document.getMarksAtRange(selection).remove(mark) const sel = selection.merge({ marks }) - return transform.moveTo(sel) + transform.moveTo(sel) } } @@ -444,19 +428,17 @@ export function removeMark(transform, mark) { * * @param {Transform} transform * @param {Mark} mark - * @return {Transform} */ export function toggleMark(transform, mark) { mark = Normalize.mark(mark) - const { state } = transform const exists = state.marks.some(m => m.equals(mark)) if (exists) { - return transform.removeMark(mark) + transform.removeMark(mark) } else { - return transform.addMark(mark) + transform.addMark(mark) } } @@ -465,13 +447,12 @@ export function toggleMark(transform, mark) { * * @param {Transform} transform * @param {Object|String} properties - * @return {Transform} */ export function unwrapBlock(transform, properties) { const { state } = transform const { selection } = state - return transform.unwrapBlockAtRange(selection, properties) + transform.unwrapBlockAtRange(selection, properties) } /** @@ -479,13 +460,12 @@ export function unwrapBlock(transform, properties) { * * @param {Transform} transform * @param {Object|String} properties - * @return {Transform} */ export function unwrapInline(transform, properties) { const { state } = transform const { selection } = state - return transform.unwrapInlineAtRange(selection, properties) + transform.unwrapInlineAtRange(selection, properties) } /** @@ -494,13 +474,12 @@ export function unwrapInline(transform, properties) { * * @param {Transform} transform * @param {Object|String} properties - * @return {Transform} */ export function wrapBlock(transform, properties) { const { state } = transform const { selection } = state - return transform.wrapBlockAtRange(selection, properties) + transform.wrapBlockAtRange(selection, properties) } /** @@ -508,7 +487,6 @@ export function wrapBlock(transform, properties) { * * @param {Transform} transform * @param {Object|String} properties - * @return {Transform} */ export function wrapInline(transform, properties) { @@ -551,7 +529,7 @@ export function wrapInline(transform, properties) { } after = after.normalize(document) - return transform.moveTo(after) + transform.moveTo(after) } /** @@ -560,7 +538,6 @@ export function wrapInline(transform, properties) { * @param {Transform} transform * @param {String} prefix * @param {String} suffix - * @return {Transform} */ export function wrapText(transform, prefix, suffix = prefix) { @@ -580,7 +557,7 @@ export function wrapText(transform, prefix, suffix = prefix) { }) } - return transform + transform .unsetSelection() .wrapTextAtRange(selection, prefix, suffix) .moveTo(after) diff --git a/src/transforms/at-range.js b/src/transforms/at-range.js index 0820d1d1e..57948d53d 100644 --- a/src/transforms/at-range.js +++ b/src/transforms/at-range.js @@ -12,11 +12,10 @@ import { List } from 'immutable' * @param {Mixed} mark * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function addMarkAtRange(transform, range, mark, options = {}) { - if (range.isCollapsed) return transform + if (range.isCollapsed) return const { normalize = true } = options const { state } = transform @@ -35,8 +34,6 @@ export function addMarkAtRange(transform, range, mark, options = {}) { transform.addMarkByKey(key, index, length, mark, { normalize }) }) - - return transform } /** @@ -46,11 +43,10 @@ export function addMarkAtRange(transform, range, mark, options = {}) { * @param {Selection} range * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function deleteAtRange(transform, range, options = {}) { - if (range.isCollapsed) return transform + if (range.isCollapsed) return const { normalize = true } = options const { startKey, startOffset, endKey, endOffset } = range @@ -58,7 +54,8 @@ export function deleteAtRange(transform, range, options = {}) { if (startKey == endKey) { const index = startOffset const length = endOffset - startOffset - return transform.removeTextByKey(startKey, index, length, { normalize }) + transform.removeTextByKey(startKey, index, length, { normalize }) + return } let { state } = transform @@ -108,8 +105,6 @@ export function deleteAtRange(transform, range, options = {}) { if (normalize) { transform.normalizeNodeByKey(ancestor.key, SCHEMA) } - - return transform } /** @@ -120,7 +115,6 @@ export function deleteAtRange(transform, range, options = {}) { * @param {Number} n (optional) * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function deleteBackwardAtRange(transform, range, n = 1, options = {}) { @@ -130,21 +124,24 @@ export function deleteBackwardAtRange(transform, range, n = 1, options = {}) { const { startKey, focusOffset } = range if (range.isExpanded) { - return transform.deleteAtRange(range, { normalize }) + transform.deleteAtRange(range, { normalize }) + return } const block = document.getClosestBlock(startKey) if (block && block.isVoid) { - return transform.removeNodeByKey(block.key, { normalize }) + transform.removeNodeByKey(block.key, { normalize }) + return } const inline = document.getClosestInline(startKey) if (inline && inline.isVoid) { - return transform.removeNodeByKey(inline.key, { normalize }) + transform.removeNodeByKey(inline.key, { normalize }) + return } if (range.isAtStartOf(document)) { - return transform + return } const text = document.getDescendant(startKey) @@ -154,11 +151,13 @@ export function deleteBackwardAtRange(transform, range, n = 1, options = {}) { const prevInline = document.getClosestInline(prev.key) if (prevBlock && prevBlock.isVoid) { - return transform.removeNodeByKey(prevBlock.key, { normalize }) + transform.removeNodeByKey(prevBlock.key, { normalize }) + return } if (prevInline && prevInline.isVoid) { - return transform.removeNodeByKey(prevInline.key, { normalize }) + transform.removeNodeByKey(prevInline.key, { normalize }) + return } range = range.merge({ @@ -166,7 +165,8 @@ export function deleteBackwardAtRange(transform, range, n = 1, options = {}) { anchorOffset: prev.length, }) - return transform.deleteAtRange(range, { normalize }) + transform.deleteAtRange(range, { normalize }) + return } range = range.merge({ @@ -174,7 +174,7 @@ export function deleteBackwardAtRange(transform, range, n = 1, options = {}) { isBackward: true, }) - return transform.deleteAtRange(range, { normalize }) + transform.deleteAtRange(range, { normalize }) } /** @@ -185,7 +185,6 @@ export function deleteBackwardAtRange(transform, range, n = 1, options = {}) { * @param {Number} n (optional) * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function deleteForwardAtRange(transform, range, n = 1, options = {}) { @@ -195,21 +194,24 @@ export function deleteForwardAtRange(transform, range, n = 1, options = {}) { const { startKey, focusOffset } = range if (range.isExpanded) { - return transform.deleteAtRange(range, { normalize }) + transform.deleteAtRange(range, { normalize }) + return } const block = document.getClosestBlock(startKey) if (block && block.isVoid) { - return transform.removeNodeByKey(block.key, { normalize }) + transform.removeNodeByKey(block.key, { normalize }) + return } const inline = document.getClosestInline(startKey) if (inline && inline.isVoid) { - return transform.removeNodeByKey(inline.key, { normalize }) + transform.removeNodeByKey(inline.key, { normalize }) + return } if (range.isAtEndOf(document)) { - return transform + return } const text = document.getDescendant(startKey) @@ -219,11 +221,13 @@ export function deleteForwardAtRange(transform, range, n = 1, options = {}) { const nextInline = document.getClosestInline(next.key) if (nextBlock && nextBlock.isVoid) { - return transform.removeNodeByKey(nextBlock.key, { normalize }) + transform.removeNodeByKey(nextBlock.key, { normalize }) + return } if (nextInline && nextInline.isVoid) { - return transform.removeNodeByKey(nextInline.key, { normalize }) + transform.removeNodeByKey(nextInline.key, { normalize }) + return } range = range.merge({ @@ -231,14 +235,15 @@ export function deleteForwardAtRange(transform, range, n = 1, options = {}) { focusOffset: 0 }) - return transform.deleteAtRange(range, { normalize }) + transform.deleteAtRange(range, { normalize }) + return } range = range.merge({ focusOffset: focusOffset + n }) - return transform.deleteAtRange(range, { normalize }) + transform.deleteAtRange(range, { normalize }) } /** @@ -249,7 +254,6 @@ export function deleteForwardAtRange(transform, range, n = 1, options = {}) { * @param {Block|String|Object} block * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function insertBlockAtRange(transform, range, block, options = {}) { @@ -295,8 +299,6 @@ export function insertBlockAtRange(transform, range, block, options = {}) { if (normalize) { transform.normalizeNodeByKey(parent.key, SCHEMA) } - - return transform } /** @@ -307,7 +309,6 @@ export function insertBlockAtRange(transform, range, block, options = {}) { * @param {Document} fragment * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function insertFragmentAtRange(transform, range, fragment, options = {}) { @@ -320,9 +321,7 @@ export function insertFragmentAtRange(transform, range, fragment, options = {}) } // If the fragment is empty, there's nothing to do after deleting. - if (!fragment.length) { - return transform - } + if (!fragment.length) return // Regenerate the keys for all of the fragments nodes, so that they're // guaranteed not to collide with the existing keys in the document. Otherwise @@ -412,8 +411,6 @@ export function insertFragmentAtRange(transform, range, fragment, options = {}) if (normalize) { transform.normalizeNodeByKey(parent.key, SCHEMA) } - - return transform } /** @@ -424,7 +421,6 @@ export function insertFragmentAtRange(transform, range, fragment, options = {}) * @param {Inline|String|Object} inline * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function insertInlineAtRange(transform, range, inline, options = {}) { @@ -443,9 +439,7 @@ export function insertInlineAtRange(transform, range, inline, options = {}) { const startText = document.assertDescendant(startKey) const index = parent.nodes.indexOf(startText) - if (parent.isVoid) { - return transform - } + if (parent.isVoid) return transform.splitNodeByKey(startKey, startOffset, { normalize: false }) transform.insertNodeByKey(parent.key, index + 1, inline, { normalize: false }) @@ -453,8 +447,6 @@ export function insertInlineAtRange(transform, range, inline, options = {}) { if (normalize) { transform.normalizeNodeByKey(parent.key, SCHEMA) } - - return transform } /** @@ -466,7 +458,6 @@ export function insertInlineAtRange(transform, range, inline, options = {}) { * @param {Set} marks (optional) * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function insertTextAtRange(transform, range, text, marks, options = {}) { @@ -476,9 +467,7 @@ export function insertTextAtRange(transform, range, text, marks, options = {}) { const { startKey, startOffset } = range const parent = document.getParent(startKey) - if (parent.isVoid) { - return transform - } + if (parent.isVoid) return if (range.isExpanded) { transform.deleteAtRange(range, { normalize: false }) @@ -489,7 +478,7 @@ export function insertTextAtRange(transform, range, text, marks, options = {}) { normalize = range.isExpanded } - return transform.insertTextByKey(startKey, startOffset, text, marks, { normalize }) + transform.insertTextByKey(startKey, startOffset, text, marks, { normalize }) } /** @@ -500,11 +489,10 @@ export function insertTextAtRange(transform, range, text, marks, options = {}) { * @param {Mark|String} mark (optional) * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function removeMarkAtRange(transform, range, mark, options = {}) { - if (range.isCollapsed) return transform + if (range.isCollapsed) return const { normalize = true } = options const { state } = transform @@ -523,8 +511,6 @@ export function removeMarkAtRange(transform, range, mark, options = {}) { transform.removeMarkByKey(key, index, length, mark, { normalize }) }) - - return transform } /** @@ -535,7 +521,6 @@ export function removeMarkAtRange(transform, range, mark, options = {}) { * @param {Object|String} properties * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function setBlockAtRange(transform, range, properties, options = {}) { @@ -547,8 +532,6 @@ export function setBlockAtRange(transform, range, properties, options = {}) { blocks.forEach((block) => { transform.setNodeByKey(block.key, properties, { normalize }) }) - - return transform } /** @@ -559,7 +542,6 @@ export function setBlockAtRange(transform, range, properties, options = {}) { * @param {Object|String} properties * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function setInlineAtRange(transform, range, properties, options = {}) { @@ -571,8 +553,6 @@ export function setInlineAtRange(transform, range, properties, options = {}) { inlines.forEach((inline) => { transform.setNodeByKey(inline.key, properties, { normalize}) }) - - return transform } /** @@ -583,7 +563,6 @@ export function setInlineAtRange(transform, range, properties, options = {}) { * @param {Number} height (optional) * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function splitBlockAtRange(transform, range, height = 1, options = {}) { @@ -609,7 +588,7 @@ export function splitBlockAtRange(transform, range, height = 1, options = {}) { h++ } - return transform.splitNodeByKey(node.key, offset, { normalize }) + transform.splitNodeByKey(node.key, offset, { normalize }) } /** @@ -620,7 +599,6 @@ export function splitBlockAtRange(transform, range, height = 1, options = {}) { * @param {Number} height (optional) * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function splitInlineAtRange(transform, range, height = Infinity, options = {}) { @@ -646,7 +624,7 @@ export function splitInlineAtRange(transform, range, height = Infinity, options h++ } - return transform.splitNodeByKey(node.key, offset, { normalize }) + transform.splitNodeByKey(node.key, offset, { normalize }) } /** @@ -658,11 +636,10 @@ export function splitInlineAtRange(transform, range, height = Infinity, options * @param {Mixed} mark * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function toggleMarkAtRange(transform, range, mark, options = {}) { - if (range.isCollapsed) return transform + if (range.isCollapsed) return mark = Normalize.mark(mark) @@ -677,8 +654,6 @@ export function toggleMarkAtRange(transform, range, mark, options = {}) { } else { transform.addMarkAtRange(range, mark, { normalize }) } - - return transform } /** @@ -689,7 +664,6 @@ export function toggleMarkAtRange(transform, range, mark, options = {}) { * @param {String|Object} properties * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function unwrapBlockAtRange(transform, range, properties, options = {}) { @@ -771,8 +745,6 @@ export function unwrapBlockAtRange(transform, range, properties, options = {}) { if (normalize) { transform.normalizeDocument(SCHEMA) } - - return transform } /** @@ -783,7 +755,6 @@ export function unwrapBlockAtRange(transform, range, properties, options = {}) { * @param {String|Object} properties * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function unwrapInlineAtRange(transform, range, properties, options = {}) { @@ -820,8 +791,6 @@ export function unwrapInlineAtRange(transform, range, properties, options = {}) if (normalize) { transform.normalizeDocument(SCHEMA) } - - return transform } /** @@ -832,7 +801,6 @@ export function unwrapInlineAtRange(transform, range, properties, options = {}) * @param {Block|Object|String} block * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function wrapBlockAtRange(transform, range, block, options = {}) { @@ -892,8 +860,6 @@ export function wrapBlockAtRange(transform, range, block, options = {}) { if (normalize) { transform.normalizeNodeByKey(parent.key, SCHEMA) } - - return transform } /** @@ -904,11 +870,10 @@ export function wrapBlockAtRange(transform, range, block, options = {}) { * @param {Inline|Object|String} inline * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function wrapInlineAtRange(transform, range, inline, options = {}) { - if (range.isCollapsed) return transform + if (range.isCollapsed) return inline = Normalize.inline(inline) inline = inline.merge({ nodes: inline.nodes.clear() }) @@ -1016,8 +981,6 @@ export function wrapInlineAtRange(transform, range, inline, options = {}) { } }) } - - return transform } /** @@ -1029,7 +992,6 @@ export function wrapInlineAtRange(transform, range, inline, options = {}) { * @param {String} suffix (optional) * @param {Object} options * @property {Boolean} normalize - * @return {Transform} */ export function wrapTextAtRange(transform, range, prefix, suffix = prefix, options = {}) { @@ -1042,7 +1004,6 @@ export function wrapTextAtRange(transform, range, prefix, suffix = prefix, optio end = end.moveForward(prefix.length) } - return transform - .insertTextAtRange(start, prefix, [], { normalize }) - .insertTextAtRange(end, suffix, [], { normalize }) + transform.insertTextAtRange(start, prefix, [], { normalize }) + transform.insertTextAtRange(end, suffix, [], { normalize }) } diff --git a/src/transforms/normalize.js b/src/transforms/normalize.js index c3f193b1f..0e0395547 100644 --- a/src/transforms/normalize.js +++ b/src/transforms/normalize.js @@ -8,13 +8,11 @@ import warn from '../utils/warn' * * @param {Transform} transform * @param {Schema} schema - * @return {Transform} */ export function normalize(transform, schema) { transform.normalizeDocument(schema) transform.normalizeSelection(schema) - return transform } /** @@ -22,14 +20,12 @@ export function normalize(transform, schema) { * * @param {Transform} transform * @param {Schema} schema - * @return {Transform} */ export function normalizeDocument(transform, schema) { const { state } = transform const { document } = state transform.normalizeNodeByKey(document.key, schema) - return transform } /** @@ -38,24 +34,20 @@ export function normalizeDocument(transform, schema) { * @param {Transform} transform * @param {Node|String} key * @param {Schema} schema - * @return {Transform} */ export function normalizeNodeByKey(transform, key, schema) { assertSchema(schema) - key = Normalize.key(key) // If the schema has no validation rules, there's nothing to normalize. - if (!schema.hasValidators) { - return transform - } + if (!schema.hasValidators) return + key = Normalize.key(key) const { state } = transform const { document } = state const node = document.assertNode(key) normalizeNodeWith(transform, node, schema) - return transform } /** @@ -64,31 +56,26 @@ export function normalizeNodeByKey(transform, key, schema) { * @param {Transform} transform * @param {Node|String} key * @param {Schema} schema - * @return {Transform} */ export function normalizeParentsByKey(transform, key, schema) { assertSchema(schema) - key = Normalize.key(key) // If the schema has no validation rules, there's nothing to normalize. - if (!schema.hasValidators) { - return transform - } + if (!schema.hasValidators) return + key = Normalize.key(key) const { state } = transform const { document } = state const node = document.assertNode(key) normalizeParentsWith(transform, node, schema) - return transform } /** * Normalize only the selection. * * @param {Transform} transform - * @return {Transform} */ export function normalizeSelection(transform) { @@ -117,7 +104,6 @@ export function normalizeSelection(transform) { state = state.merge({ selection }) transform.state = state - return transform } /** @@ -126,7 +112,6 @@ export function normalizeSelection(transform) { * @param {Transform} transform * @param {Node} node * @param {Schema} schema - * @return {Transform} */ function normalizeNodeWith(transform, node, schema) { @@ -145,8 +130,6 @@ function normalizeNodeWith(transform, node, schema) { if (node) { normalizeNodeOnly(transform, node, schema) } - - return transform } /** @@ -155,29 +138,23 @@ function normalizeNodeWith(transform, node, schema) { * @param {Transform} transform * @param {Node} node * @param {Schema} schema - * @return {Transform} */ function normalizeParentsWith(transform, node, schema) { normalizeNodeOnly(transform, node, schema) // Normalize went back up to the very top of the document. - if (node.kind == 'document') { - return transform - } + if (node.kind == 'document') return // Re-find the node first. node = refindNode(transform, node) - - if (!node) { - return transform - } + if (!node) return const { state } = transform const { document } = state const parent = document.getParent(node.key) - return normalizeParentsWith(transform, parent, schema) + normalizeParentsWith(transform, parent, schema) } /** @@ -203,17 +180,14 @@ function refindNode(transform, node) { * @param {Transform} transform * @param {Node} node * @param {Schema} schema - * @return {Transform} */ function normalizeChildrenWith(transform, node, schema) { - if (node.kind == 'text') return transform + if (node.kind == 'text') return node.nodes.forEach((child) => { normalizeNodeWith(transform, child, schema) }) - - return transform } /** @@ -222,7 +196,6 @@ function normalizeChildrenWith(transform, node, schema) { * @param {Transform} transform * @param {Node} node * @param {Schema} schema - * @return {Transform} */ function normalizeNodeOnly(transform, node, schema) { @@ -231,7 +204,7 @@ function normalizeNodeOnly(transform, node, schema) { function iterate(t, n) { const failure = n.validate(schema) - if (!failure) return t + if (!failure) return const { value, rule } = failure @@ -241,7 +214,7 @@ function normalizeNodeOnly(transform, node, schema) { // Re-find the node reference, in case it was updated. If the node no longer // exists, we're done for this branch. n = refindNode(t, n) - if (!n) return t + if (!n) return // Increment the iterations counter, and check to make sure that we haven't // exceeded the max. Without this check, it's easy for the `validate` or @@ -254,10 +227,10 @@ function normalizeNodeOnly(transform, node, schema) { } // Otherwise, iterate again. - return iterate(t, n) + iterate(t, n) } - return iterate(transform, node) + iterate(transform, node) } /** diff --git a/src/transforms/on-history.js b/src/transforms/on-history.js index eb4b2631c..5daa478a1 100644 --- a/src/transforms/on-history.js +++ b/src/transforms/on-history.js @@ -3,7 +3,6 @@ * Redo to the next state in the history. * * @param {Transform} transform - * @return {Transform} */ export function redo(transform) { @@ -13,7 +12,7 @@ export function redo(transform) { // If there's no next snapshot, abort. let next = redos.peek() - if (!next) return transform + if (!next) return // Shift the next state into the undo stack. redos = redos.pop() @@ -31,7 +30,6 @@ export function redo(transform) { // Update the transform. transform.state = state - return transform } /** @@ -39,7 +37,6 @@ export function redo(transform) { * * @param {Transform} transform * @param {Object} options - * @return {Transform} */ export function save(transform, options = {}) { @@ -49,7 +46,7 @@ export function save(transform, options = {}) { let { undos, redos } = history // If there are no operations, abort. - if (!operations.length) return transform + if (!operations.length) return // Create a new save point or merge the operations into the previous one. if (merge) { @@ -71,14 +68,12 @@ export function save(transform, options = {}) { // Update the transform. transform.state = state - return transform } /** * Undo the previous operations in the history. * * @param {Transform} transform - * @return {Transform} */ export function undo(transform) { @@ -88,7 +83,7 @@ export function undo(transform) { // If there's no previous snapshot, abort. let previous = undos.peek() - if (!previous) return transform + if (!previous) return // Shift the previous operations into the redo stack. undos = undos.pop() @@ -108,5 +103,4 @@ export function undo(transform) { // Update the transform. transform.state = state - return transform } diff --git a/src/transforms/on-selection.js b/src/transforms/on-selection.js index 27b3365fb..7f2957399 100644 --- a/src/transforms/on-selection.js +++ b/src/transforms/on-selection.js @@ -3,70 +3,65 @@ * Blur the selection. * * @param {Transform} transform - * @return {Transform} */ export function blur(transform) { const { state } = transform const { selection } = state const sel = selection.blur() - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** * Move the focus point to the anchor point. * * @param {Transform} transform - * @return {Transform} */ export function collapseToAnchor(transform) { const { state } = transform const { selection } = state const sel = selection.collapseToAnchor() - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** * Move the start point to the end point. * * @param {Transform} transform - * @return {Transform} */ export function collapseToEnd(transform) { const { state } = transform const { selection } = state const sel = selection.collapseToEnd() - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** * Move the anchor point to the focus point. * * @param {Transform} transform - * @return {Transform} */ export function collapseToFocus(transform) { const { state } = transform const { selection } = state const sel = selection.collapseToFocus() - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** * Move the end point to the start point. * * @param {Transform} transform - * @return {Transform} */ export function collapseToStart(transform) { const { state } = transform const { selection } = state const sel = selection.collapseToStart() - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** @@ -74,21 +69,19 @@ export function collapseToStart(transform) { * * @param {Transform} transform * @param {Node} node - * @return {Transform} */ export function collapseToEndOf(transform, node) { const { state } = transform const { selection } = state const sel = selection.collapseToEndOf(node) - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** * Move the selection to the end of the next block. * * @param {Transform} tansform - * @return {Transform} */ export function collapseToEndOfNextBlock(transform) { @@ -97,17 +90,16 @@ export function collapseToEndOfNextBlock(transform) { const blocks = document.getBlocksAtRange(selection) const last = blocks.last() const next = document.getNextBlock(last) - if (!next) return transform + if (!next) return const sel = selection.collapseToEndOf(next) - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** * Move the selection to the end of the next text. * * @param {Transform} tansform - * @return {Transform} */ export function collapseToEndOfNextText(transform) { @@ -116,17 +108,16 @@ export function collapseToEndOfNextText(transform) { const texts = document.getTextsAtRange(selection) const last = texts.last() const next = document.getNextText(last) - if (!next) return transform + if (!next) return const sel = selection.collapseToEndOf(next) - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** * Move the selection to the end of the previous block. * * @param {Transform} tansform - * @return {Transform} */ export function collapseToEndOfPreviousBlock(transform) { @@ -135,17 +126,16 @@ export function collapseToEndOfPreviousBlock(transform) { const blocks = document.getBlocksAtRange(selection) const first = blocks.first() const previous = document.getPreviousBlock(first) - if (!previous) return transform + if (!previous) return const sel = selection.collapseToEndOf(previous) - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** * Move the selection to the end of the previous text. * * @param {Transform} tansform - * @return {Transform} */ export function collapseToEndOfPreviousText(transform) { @@ -154,10 +144,10 @@ export function collapseToEndOfPreviousText(transform) { const texts = document.getTextsAtRange(selection) const first = texts.first() const previous = document.getPreviousText(first) - if (!previous) return transform + if (!previous) return const sel = selection.collapseToEndOf(previous) - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** @@ -165,21 +155,19 @@ export function collapseToEndOfPreviousText(transform) { * * @param {Transform} transform * @param {Node} node - * @return {Transform} */ export function collapseToStartOf(transform, node) { const { state } = transform const { selection } = state const sel = selection.collapseToStartOf(node) - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** * Move the selection to the start of the next block. * * @param {Transform} tansform - * @return {Transform} */ export function collapseToStartOfNextBlock(transform) { @@ -188,17 +176,16 @@ export function collapseToStartOfNextBlock(transform) { const blocks = document.getBlocksAtRange(selection) const last = blocks.last() const next = document.getNextBlock(last) - if (!next) return transform + if (!next) return const sel = selection.collapseToStartOf(next) - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** * Move the selection to the start of the next text. * * @param {Transform} tansform - * @return {Transform} */ export function collapseToStartOfNextText(transform) { @@ -207,17 +194,16 @@ export function collapseToStartOfNextText(transform) { const texts = document.getTextsAtRange(selection) const last = texts.last() const next = document.getNextText(last) - if (!next) return transform + if (!next) return const sel = selection.collapseToStartOf(next) - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** * Move the selection to the start of the previous block. * * @param {Transform} tansform - * @return {Transform} */ export function collapseToStartOfPreviousBlock(transform) { @@ -226,17 +212,16 @@ export function collapseToStartOfPreviousBlock(transform) { const blocks = document.getBlocksAtRange(selection) const first = blocks.first() const previous = document.getPreviousBlock(first) - if (!previous) return transform + if (!previous) return const sel = selection.collapseToStartOf(previous) - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** * Move the selection to the start of the previous text. * * @param {Transform} tansform - * @return {Transform} */ export function collapseToStartOfPreviousText(transform) { @@ -245,10 +230,10 @@ export function collapseToStartOfPreviousText(transform) { const texts = document.getTextsAtRange(selection) const first = texts.first() const previous = document.getPreviousText(first) - if (!previous) return transform + if (!previous) return const sel = selection.collapseToStartOf(previous) - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** @@ -256,14 +241,13 @@ export function collapseToStartOfPreviousText(transform) { * * @param {Transform} transform * @param {Number} n (optional) - * @return {Transform} */ export function extendBackward(transform, n) { const { state } = transform const { document, selection } = state const sel = selection.extendBackward(n).normalize(document) - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** @@ -271,14 +255,13 @@ export function extendBackward(transform, n) { * * @param {Transform} transform * @param {Number} n (optional) - * @return {Transform} */ export function extendForward(transform, n) { const { state } = transform const { document, selection } = state const sel = selection.extendForward(n).normalize(document) - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** @@ -286,14 +269,13 @@ export function extendForward(transform, n) { * * @param {Transform} transform * @param {Node} node - * @return {Transform} */ export function extendToEndOf(transform, node) { const { state } = transform const { document, selection } = state const sel = selection.extendToEndOf(node).normalize(document) - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** @@ -301,28 +283,26 @@ export function extendToEndOf(transform, node) { * * @param {Transform} transform * @param {Node} node - * @return {Transform} */ export function extendToStartOf(transform, node) { const { state } = transform const { document, selection } = state const sel = selection.extendToStartOf(node).normalize(document) - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** * Focus the selection. * * @param {Transform} transform - * @return {Transform} */ export function focus(transform) { const { state } = transform const { selection } = state const sel = selection.focus() - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** @@ -330,14 +310,13 @@ export function focus(transform) { * * @param {Transform} transform * @param {Number} n (optional) - * @return {Transform} */ export function moveBackward(transform, n) { const { state } = transform const { document, selection } = state const sel = selection.moveBackward(n).normalize(document) - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** @@ -345,14 +324,13 @@ export function moveBackward(transform, n) { * * @param {Transform} transform * @param {Number} n (optional) - * @return {Transform} */ export function moveForward(transform, n) { const { state } = transform const { document, selection } = state const sel = selection.moveForward(n).normalize(document) - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** @@ -360,11 +338,10 @@ export function moveForward(transform, n) { * * @param {Transform} transform * @param {Object} properties - * @return {Transform} */ export function moveTo(transform, properties) { - return transform.setSelectionOperation(properties) + transform.setSelectionOperation(properties) } /** @@ -373,14 +350,13 @@ export function moveTo(transform, properties) { * @param {Transform} transform * @param {Number} anchor * @param {Number} focus (optional) - * @return {Transform} */ export function moveToOffsets(transform, anchor, fokus) { const { state } = transform const { selection } = state const sel = selection.moveToOffsets(anchor, fokus) - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** @@ -389,25 +365,23 @@ export function moveToOffsets(transform, anchor, fokus) { * @param {Transform} transform * @param {Node} start * @param {Node} end (optional) - * @return {Transform} */ export function moveToRangeOf(transform, start, end) { const { state } = transform const { document, selection } = state const sel = selection.moveToRangeOf(start, end).normalize(document) - return transform.setSelectionOperation(sel) + transform.setSelectionOperation(sel) } /** * Unset the selection, removing an association to a node. * * @param {Transform} transform - * @return {Transform} */ export function unsetSelection(transform) { - return transform.setSelectionOperation({ + transform.setSelectionOperation({ anchorKey: null, anchorOffset: 0, focusKey: null, diff --git a/src/transforms/operations.js b/src/transforms/operations.js index e9ae80939..25413ff23 100644 --- a/src/transforms/operations.js +++ b/src/transforms/operations.js @@ -9,7 +9,6 @@ import Normalize from '../utils/normalize' * @param {Number} offset * @param {Number} length * @param {Mixed} mark - * @return {Transform} */ export function addMarkOperation(transform, path, offset, length, mark) { @@ -30,7 +29,7 @@ export function addMarkOperation(transform, path, offset, length, mark) { inverse, } - return transform.applyOperation(operation) + transform.applyOperation(operation) } /** @@ -40,7 +39,6 @@ export function addMarkOperation(transform, path, offset, length, mark) { * @param {Array} path * @param {Number} index * @param {Node} node - * @return {Transform} */ export function insertNodeOperation(transform, path, index, node) { @@ -58,7 +56,7 @@ export function insertNodeOperation(transform, path, index, node) { inverse, } - return transform.applyOperation(operation) + transform.applyOperation(operation) } /** @@ -69,7 +67,6 @@ export function insertNodeOperation(transform, path, index, node) { * @param {Number} offset * @param {String} text * @param {Set} marks (optional) - * @return {Transform} */ export function insertTextOperation(transform, path, offset, text, marks) { @@ -90,7 +87,7 @@ export function insertTextOperation(transform, path, offset, text, marks) { inverse, } - return transform.applyOperation(operation) + transform.applyOperation(operation) } /** @@ -99,7 +96,6 @@ export function insertTextOperation(transform, path, offset, text, marks) { * @param {Transform} transform * @param {Array} path * @param {Array} withPath - * @return {Transform} */ export function joinNodeOperation(transform, path, withPath) { @@ -134,7 +130,7 @@ export function joinNodeOperation(transform, path, withPath) { inverse, } - return transform.applyOperation(operation) + transform.applyOperation(operation) } /** @@ -144,7 +140,6 @@ export function joinNodeOperation(transform, path, withPath) { * @param {Array} path * @param {Array} newPath * @param {Number} newIndex - * @return {Transform} */ export function moveNodeOperation(transform, path, newPath, newIndex) { @@ -167,7 +162,7 @@ export function moveNodeOperation(transform, path, newPath, newIndex) { inverse, } - return transform.applyOperation(operation) + transform.applyOperation(operation) } /** @@ -178,7 +173,6 @@ export function moveNodeOperation(transform, path, newPath, newIndex) { * @param {Number} offset * @param {Number} length * @param {Mark} mark - * @return {Transform} */ export function removeMarkOperation(transform, path, offset, length, mark) { @@ -199,7 +193,7 @@ export function removeMarkOperation(transform, path, offset, length, mark) { inverse, } - return transform.applyOperation(operation) + transform.applyOperation(operation) } /** @@ -207,7 +201,6 @@ export function removeMarkOperation(transform, path, offset, length, mark) { * * @param {Transform} transform * @param {Array} path - * @return {Transform} */ export function removeNodeOperation(transform, path) { @@ -230,7 +223,7 @@ export function removeNodeOperation(transform, path) { inverse, } - return transform.applyOperation(operation) + transform.applyOperation(operation) } /** @@ -240,7 +233,6 @@ export function removeNodeOperation(transform, path) { * @param {Array} path * @param {Number} offset * @param {Number} length - * @return {Transform} */ export function removeTextOperation(transform, path, offset, length) { @@ -282,7 +274,7 @@ export function removeTextOperation(transform, path, offset, length) { inverse, } - return transform.applyOperation(operation) + transform.applyOperation(operation) } /** @@ -294,7 +286,6 @@ export function removeTextOperation(transform, path, offset, length) { * @param {Number} length * @param {Mark} mark * @param {Mark} newMark - * @return {Transform} */ export function setMarkOperation(transform, path, offset, length, mark, newMark) { @@ -317,7 +308,7 @@ export function setMarkOperation(transform, path, offset, length, mark, newMark) inverse, } - return transform.applyOperation(operation) + transform.applyOperation(operation) } /** @@ -326,7 +317,6 @@ export function setMarkOperation(transform, path, offset, length, mark, newMark) * @param {Transform} transform * @param {Array} path * @param {Object} properties - * @return {Transform} */ export function setNodeOperation(transform, path, properties) { @@ -352,7 +342,7 @@ export function setNodeOperation(transform, path, properties) { inverse, } - return transform.applyOperation(operation) + transform.applyOperation(operation) } /** @@ -360,7 +350,6 @@ export function setNodeOperation(transform, path, properties) { * * @param {Transform} transform * @param {Mixed} selection - * @return {Transform} */ export function setSelectionOperation(transform, properties) { @@ -432,7 +421,7 @@ export function setSelectionOperation(transform, properties) { } // Apply the operation. - return transform.applyOperation(operation) + transform.applyOperation(operation) } /** @@ -441,7 +430,6 @@ export function setSelectionOperation(transform, properties) { * @param {Transform} transform * @param {Array} path * @param {Number} offset - * @return {Transform} */ export function splitNodeOperation(transform, path, offset) { @@ -462,5 +450,5 @@ export function splitNodeOperation(transform, path, offset) { inverse, } - return transform.applyOperation(operation) + transform.applyOperation(operation) } From fda14bf6cdb55f0556458576385bcc991454c16a Mon Sep 17 00:00:00 2001 From: Ian Storm Taylor Date: Tue, 22 Nov 2016 14:48:18 -0800 Subject: [PATCH 03/13] update transforms docblock --- src/transforms/by-key.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/transforms/by-key.js b/src/transforms/by-key.js index 4791e4224..869a52fc3 100644 --- a/src/transforms/by-key.js +++ b/src/transforms/by-key.js @@ -11,7 +11,7 @@ import SCHEMA from '../schemas/core' * @param {Number} length * @param {Mixed} mark * @param {Object} options - * @param {Boolean} normalize + * @property {Boolean} normalize */ export function addMarkByKey(transform, key, offset, length, mark, options = {}) { @@ -37,7 +37,7 @@ export function addMarkByKey(transform, key, offset, length, mark, options = {}) * @param {Number} index * @param {Node} node * @param {Object} options - * @param {Boolean} normalize + * @property {Boolean} normalize */ export function insertNodeByKey(transform, key, index, node, options = {}) { @@ -62,7 +62,7 @@ export function insertNodeByKey(transform, key, index, node, options = {}) { * @param {String} text * @param {Set} marks (optional) * @param {Object} options - * @param {Boolean} normalize + * @property {Boolean} normalize */ export function insertTextByKey(transform, key, offset, text, marks, options = {}) { @@ -86,7 +86,7 @@ export function insertTextByKey(transform, key, offset, text, marks, options = { * @param {String} key * @param {String} withKey * @param {Object} options - * @param {Boolean} normalize + * @property {Boolean} normalize */ export function joinNodeByKey(transform, key, withKey, options = {}) { @@ -113,7 +113,7 @@ export function joinNodeByKey(transform, key, withKey, options = {}) { * @param {String} newKey * @param {Number} index * @param {Object} options - * @param {Boolean} normalize + * @property {Boolean} normalize */ export function moveNodeByKey(transform, key, newKey, newIndex, options = {}) { @@ -140,7 +140,7 @@ export function moveNodeByKey(transform, key, newKey, newIndex, options = {}) { * @param {Number} length * @param {Mark} mark * @param {Object} options - * @param {Boolean} normalize + * @property {Boolean} normalize */ export function removeMarkByKey(transform, key, offset, length, mark, options = {}) { @@ -164,7 +164,7 @@ export function removeMarkByKey(transform, key, offset, length, mark, options = * @param {Transform} transform * @param {String} key * @param {Object} options - * @param {Boolean} normalize + * @property {Boolean} normalize */ export function removeNodeByKey(transform, key, options = {}) { @@ -189,7 +189,7 @@ export function removeNodeByKey(transform, key, options = {}) { * @param {Number} offset * @param {Number} length * @param {Object} options - * @param {Boolean} normalize + * @property {Boolean} normalize */ export function removeTextByKey(transform, key, offset, length, options = {}) { @@ -215,7 +215,7 @@ export function removeTextByKey(transform, key, offset, length, options = {}) { * @param {Number} length * @param {Mark} mark * @param {Object} options - * @param {Boolean} normalize + * @property {Boolean} normalize */ export function setMarkByKey(transform, key, offset, length, mark, properties, options = {}) { @@ -242,7 +242,7 @@ export function setMarkByKey(transform, key, offset, length, mark, properties, o * @param {String} key * @param {Object|String} properties * @param {Object} options - * @param {Boolean} normalize + * @property {Boolean} normalize */ export function setNodeByKey(transform, key, properties, options = {}) { @@ -267,7 +267,7 @@ export function setNodeByKey(transform, key, properties, options = {}) { * @param {String} key * @param {Number} offset * @param {Object} options - * @param {Boolean} normalize + * @property {Boolean} normalize */ export function splitNodeByKey(transform, key, offset, options = {}) { @@ -291,7 +291,7 @@ export function splitNodeByKey(transform, key, offset, options = {}) { * @param {String} key * @param {Object|String} properties * @param {Object} options - * @param {Boolean} normalize + * @property {Boolean} normalize */ export function unwrapInlineByKey(transform, key, properties, options) { @@ -311,7 +311,7 @@ export function unwrapInlineByKey(transform, key, properties, options) { * @param {String} key * @param {Object|String} properties * @param {Object} options - * @param {Boolean} normalize + * @property {Boolean} normalize */ export function unwrapBlockByKey(transform, key, properties, options) { @@ -331,7 +331,7 @@ export function unwrapBlockByKey(transform, key, properties, options) { * @param {String} key The node to wrap * @param {Block|Object|String} block The wrapping block (its children are discarded) * @param {Object} options - * @param {Boolean} normalize + * @property {Boolean} normalize */ export function wrapBlockByKey(transform, key, block, options) { From d32904c7c156a8ee0339a105481f72a3e2ae1d53 Mon Sep 17 00:00:00 2001 From: Ian Storm Taylor Date: Tue, 22 Nov 2016 14:50:17 -0800 Subject: [PATCH 04/13] refactor add/remove mark transforms --- src/transforms/at-current-range.js | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/transforms/at-current-range.js b/src/transforms/at-current-range.js index 5f81d2a7d..7315317bc 100644 --- a/src/transforms/at-current-range.js +++ b/src/transforms/at-current-range.js @@ -10,25 +10,24 @@ import Normalize from '../utils/normalize' export function addMark(transform, mark) { mark = Normalize.mark(mark) - const { state } = transform const { document, selection } = state if (selection.isExpanded) { transform.addMarkAtRange(selection, mark) + return } - else if (selection.marks) { + if (selection.marks) { const marks = selection.marks.add(mark) const sel = selection.merge({ marks }) transform.moveTo(sel) + return } - else { - const marks = document.getMarksAtRange(selection).add(mark) - const sel = selection.merge({ marks }) - transform.moveTo(sel) - } + const marks = document.getMarksAtRange(selection).add(mark) + const sel = selection.merge({ marks }) + transform.moveTo(sel) } /** @@ -407,19 +406,19 @@ export function removeMark(transform, mark) { if (selection.isExpanded) { transform.removeMarkAtRange(selection, mark) + return } - else if (selection.marks) { + if (selection.marks) { const marks = selection.marks.remove(mark) const sel = selection.merge({ marks }) transform.moveTo(sel) + return } - else { - const marks = document.getMarksAtRange(selection).remove(mark) - const sel = selection.merge({ marks }) - transform.moveTo(sel) - } + const marks = document.getMarksAtRange(selection).remove(mark) + const sel = selection.merge({ marks }) + transform.moveTo(sel) } /** From f393973cfa7caf51ca0dd04997c7fe42b309e503 Mon Sep 17 00:00:00 2001 From: Ian Storm Taylor Date: Tue, 22 Nov 2016 15:09:39 -0800 Subject: [PATCH 05/13] refactor transform, simplify selection updating logic --- src/transforms/at-current-range.js | 58 ++++++-------------- src/transforms/at-range.js | 86 +++++++++++++++++------------- 2 files changed, 63 insertions(+), 81 deletions(-) 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) { From da4c1ffcafd2930b42b8180b50075b358b02c15f Mon Sep 17 00:00:00 2001 From: Ian Storm Taylor Date: Tue, 22 Nov 2016 15:23:24 -0800 Subject: [PATCH 06/13] refactor insert text and selection mark updating --- src/transforms/at-current-range.js | 25 +++---------------------- src/transforms/index.js | 2 ++ src/transforms/on-selection.js | 10 ++++++++++ 3 files changed, 15 insertions(+), 22 deletions(-) diff --git a/src/transforms/at-current-range.js b/src/transforms/at-current-range.js index 6f570f91a..091a83fa2 100644 --- a/src/transforms/at-current-range.js +++ b/src/transforms/at-current-range.js @@ -221,29 +221,10 @@ export function insertInline(transform, inline) { export function insertText(transform, text, marks) { const { state } = transform - const { document, selection } = state - const { startKey } = selection - const isVoid = document.hasVoidParent(startKey) - let after - - if (isVoid) { - after = selection - } - - else if (selection.isExpanded) { - after = selection.collapseToStart().moveForward(text.length) - } - - else { - after = selection.moveForward(text.length) - } - + const { selection } = state marks = marks || selection.marks - - transform - .unsetSelection() - .insertTextAtRange(selection, text, marks) - .moveTo(after) + transform.insertTextAtRange(selection, text, marks) + transform.unsetMarks() } /** diff --git a/src/transforms/index.js b/src/transforms/index.js index a1c69037d..3a0d165ae 100644 --- a/src/transforms/index.js +++ b/src/transforms/index.js @@ -129,6 +129,7 @@ import { moveTo, moveToOffsets, moveToRangeOf, + unsetMarks, unsetSelection, } from './on-selection' @@ -281,6 +282,7 @@ export default { moveTo, moveToOffsets, moveToRangeOf, + unsetMarks, unsetSelection, /** diff --git a/src/transforms/on-selection.js b/src/transforms/on-selection.js index 7f2957399..639522b24 100644 --- a/src/transforms/on-selection.js +++ b/src/transforms/on-selection.js @@ -374,6 +374,16 @@ export function moveToRangeOf(transform, start, end) { transform.setSelectionOperation(sel) } +/** + * Unset the selection's marks. + * + * @param {Transform} transform + */ + +export function unsetMarks(transform) { + transform.setSelectionOperation({ marks: null }) +} + /** * Unset the selection, removing an association to a node. * From a6844a4e589395e21b7c2a56e853e54820f57edd Mon Sep 17 00:00:00 2001 From: Ian Storm Taylor Date: Tue, 22 Nov 2016 15:31:50 -0800 Subject: [PATCH 07/13] refactor inserting text removing selection marks --- src/transforms/at-current-range.js | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/transforms/at-current-range.js b/src/transforms/at-current-range.js index 091a83fa2..545424b9e 100644 --- a/src/transforms/at-current-range.js +++ b/src/transforms/at-current-range.js @@ -136,7 +136,10 @@ export function insertBlock(transform, block) { const { state } = transform const { selection } = state transform.insertBlockAtRange(selection, block) - transform.collapseToEndOf(block) + + // If the node was successfully inserted, update the selection. + const node = transform.state.document.getNode(block.key) + if (node) transform.collapseToEndOf(node) } /** @@ -199,16 +202,12 @@ export function insertFragment(transform, fragment) { export function insertInline(transform, inline) { inline = Normalize.inline(inline) const { state } = transform - const { selection, startBlock } = state + const { selection } = state transform.insertInlineAtRange(selection, inline) - // If the start block is void, it won't have inserted at all. - if (startBlock.isVoid) return - - // 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) + // If the node was successfully inserted, update the selection. + const node = transform.state.document.getNode(inline.key) + if (node) transform.collapseToEndOf(node) } /** @@ -221,10 +220,15 @@ export function insertInline(transform, inline) { export function insertText(transform, text, marks) { const { state } = transform - const { selection } = state + const { document, selection } = state marks = marks || selection.marks transform.insertTextAtRange(selection, text, marks) - transform.unsetMarks() + + // If the text was successfully inserted, and the selection had marks on it, + // unset the selection's marks. + if (selection.marks && document != transform.state.document) { + transform.unsetMarks() + } } /** From 68938841749ae5b3d8aede51ba3d6a8b41900568 Mon Sep 17 00:00:00 2001 From: Ian Storm Taylor Date: Tue, 22 Nov 2016 15:46:53 -0800 Subject: [PATCH 08/13] refactor wrapText transform --- src/transforms/at-current-range.js | 24 ++++++++-------------- src/transforms/index.js | 4 ++++ src/transforms/on-selection.js | 32 ++++++++++++++++++++++++++++-- 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/transforms/at-current-range.js b/src/transforms/at-current-range.js index 545424b9e..90639d7e9 100644 --- a/src/transforms/at-current-range.js +++ b/src/transforms/at-current-range.js @@ -499,22 +499,14 @@ export function wrapInline(transform, properties) { export function wrapText(transform, prefix, suffix = prefix) { const { state } = transform const { selection } = state - const { anchorOffset, anchorKey, focusOffset, focusKey, isBackward } = selection - let after + transform.wrapTextAtRange(selection, prefix, suffix) - if (anchorKey == focusKey) { - after = selection.moveForward(prefix.length) + // Adding the suffix will have pushed the end of the selection further on, so + // we need to move it back to account for this. + transform.moveEndOffset(0 - suffix.length) + + // If the selection was collapsed, it will have moved the start offset too. + if (selection.isCollapsed) { + transform.moveStartOffset(0 - prefix.length) } - - else { - after = selection.merge({ - anchorOffset: isBackward ? anchorOffset : anchorOffset + prefix.length, - focusOffset: isBackward ? focusOffset + prefix.length : focusOffset - }) - } - - transform - .unsetSelection() - .wrapTextAtRange(selection, prefix, suffix) - .moveTo(after) } diff --git a/src/transforms/index.js b/src/transforms/index.js index 3a0d165ae..3c0205f36 100644 --- a/src/transforms/index.js +++ b/src/transforms/index.js @@ -126,6 +126,8 @@ import { focus, moveBackward, moveForward, + moveEndOffset, + moveStartOffset, moveTo, moveToOffsets, moveToRangeOf, @@ -279,6 +281,8 @@ export default { focus, moveBackward, moveForward, + moveEndOffset, + moveStartOffset, moveTo, moveToOffsets, moveToRangeOf, diff --git a/src/transforms/on-selection.js b/src/transforms/on-selection.js index 639522b24..8aac5e4f8 100644 --- a/src/transforms/on-selection.js +++ b/src/transforms/on-selection.js @@ -352,10 +352,10 @@ export function moveTo(transform, properties) { * @param {Number} focus (optional) */ -export function moveToOffsets(transform, anchor, fokus) { +export function moveToOffsets(transform, anchor, _focus) { const { state } = transform const { selection } = state - const sel = selection.moveToOffsets(anchor, fokus) + const sel = selection.moveToOffsets(anchor, _focus) transform.setSelectionOperation(sel) } @@ -374,6 +374,34 @@ export function moveToRangeOf(transform, start, end) { transform.setSelectionOperation(sel) } +/** + * Move the start offset by `n`. + * + * @param {Transform} transform + * @param {Number} n + */ + +export function moveStartOffset(transform, n) { + const { state } = transform + const { document, selection } = state + const sel = selection.moveStartOffset(n).normalize(document) + transform.setSelectionOperation(sel) +} + +/** + * Move the end offset by `n`. + * + * @param {Transform} transform + * @param {Number} n + */ + +export function moveEndOffset(transform, n) { + const { state } = transform + const { document, selection } = state + const sel = selection.moveEndOffset(n).normalize(document) + transform.setSelectionOperation(sel) +} + /** * Unset the selection's marks. * From fe836b1daa1a277bb8dd9dd5d6fb2e2bf76547dc Mon Sep 17 00:00:00 2001 From: Ian Storm Taylor Date: Tue, 22 Nov 2016 16:52:55 -0800 Subject: [PATCH 09/13] refactor selection snapshotting --- src/transforms/apply-operation.js | 9 ++--- src/transforms/at-current-range.js | 60 +++--------------------------- src/transforms/index.js | 2 + src/transforms/on-selection.js | 12 ++++++ src/transforms/operations.js | 4 +- 5 files changed, 25 insertions(+), 62 deletions(-) diff --git a/src/transforms/apply-operation.js b/src/transforms/apply-operation.js index 0c20b1d30..a4e50479e 100644 --- a/src/transforms/apply-operation.js +++ b/src/transforms/apply-operation.js @@ -285,16 +285,11 @@ function removeNode(state, operation) { function removeText(state, operation) { const { path, offset, length } = operation + const rangeOffset = offset + length let { document, selection } = state const { startKey, endKey, startOffset, endOffset } = selection let node = document.assertPath(path) - const rangeOffset = offset + length - - // Update the document - node = node.removeText(offset, length) - document = document.updateDescendant(node) - // Update the selection if (startKey == node.key && startOffset >= rangeOffset) { selection = selection.moveStartOffset(-length) @@ -303,6 +298,8 @@ function removeText(state, operation) { selection = selection.moveEndOffset(-length) } + node = node.removeText(offset, length) + document = document.updateDescendant(node) state = state.merge({ document, selection }) return state } diff --git a/src/transforms/at-current-range.js b/src/transforms/at-current-range.js index 90639d7e9..2eeccea38 100644 --- a/src/transforms/at-current-range.js +++ b/src/transforms/at-current-range.js @@ -38,64 +38,16 @@ export function addMark(transform, mark) { export function _delete(transform) { const { state } = transform - const { document, selection } = state - - // If the selection is collapsed, there's nothing to delete. + const { selection } = state if (selection.isCollapsed) return - const { startText } = state - const { startKey, startOffset, endKey, endOffset } = selection - const block = document.getClosestBlock(startKey) - const highest = block.getHighestChild(startKey) - const previous = block.getPreviousSibling(highest.key) - const next = block.getNextSibling(highest.key) - let after - - // If there's a previous node, and we're at the start of the current node, - // and the selection encompasses the entire current node, it won't exist after - // deleting, so we need to update the selection's keys. - if ( - previous && - startOffset == 0 && - (endKey != startKey || endOffset == startText.length) - ) { - - // If the nodes on either sides are text nodes, they will end up being - // combined, so we need to set the selection to right in between them. - if (previous.kind == 'text' && next && next.kind == 'text') { - after = selection.merge({ - anchorKey: previous.key, - anchorOffset: previous.length, - focusKey: previous.key, - focusOffset: previous.length - }) - } - - // Otherwise, if only the previous node is a text node, it won't be merged, - // so collapse to the end of it. - else if (previous.kind == 'text') { - after = selection.collapseToEndOf(previous) - } - - // Otherwise, if the previous node isn't a text node, we need to get the - // last text node inside of it and collapse to the end of that. - else { - const last = previous.getLastText() - after = selection.collapseToEndOf(last) - } - } - - // Otherwise, if the inline is an online child - - // Otherwise simply collapse the selection. - else { - after = selection.collapseToStart() - } - transform - .unsetSelection() + .snapshotSelection() .deleteAtRange(selection) - .moveTo(after) + // Ensure that the selection is collapsed to the start, because in certain + // cases when deleting across inline nodes this isn't guaranteed. + .collapseToStart() + .snapshotSelection() } /** diff --git a/src/transforms/index.js b/src/transforms/index.js index 3c0205f36..6ce9e61cf 100644 --- a/src/transforms/index.js +++ b/src/transforms/index.js @@ -133,6 +133,7 @@ import { moveToRangeOf, unsetMarks, unsetSelection, + snapshotSelection, } from './on-selection' /** @@ -288,6 +289,7 @@ export default { moveToRangeOf, unsetMarks, unsetSelection, + snapshotSelection, /** * History. diff --git a/src/transforms/on-selection.js b/src/transforms/on-selection.js index 8aac5e4f8..9eb177dbc 100644 --- a/src/transforms/on-selection.js +++ b/src/transforms/on-selection.js @@ -412,6 +412,18 @@ export function unsetMarks(transform) { transform.setSelectionOperation({ marks: null }) } +/** + * Snapshot the current selection. + * + * @param {Transform} transform + */ + +export function snapshotSelection(transform) { + const { state } = transform + const { selection } = state + transform.setSelectionOperation(selection, { snapshot: true }) +} + /** * Unset the selection, removing an association to a node. * diff --git a/src/transforms/operations.js b/src/transforms/operations.js index 25413ff23..923919192 100644 --- a/src/transforms/operations.js +++ b/src/transforms/operations.js @@ -352,7 +352,7 @@ export function setNodeOperation(transform, path, properties) { * @param {Mixed} selection */ -export function setSelectionOperation(transform, properties) { +export function setSelectionOperation(transform, properties, options = {}) { properties = Normalize.selectionProperties(properties) const { state } = transform @@ -364,7 +364,7 @@ export function setSelectionOperation(transform, properties) { // create a dictionary of the previous values for all of the properties that // are being changed, for the inverse operation. for (const k in properties) { - if (properties[k] == selection[k]) continue + if (!options.snapshot && properties[k] == selection[k]) continue props[k] = properties[k] prevProps[k] = selection[k] } From 490498f2285e9834c7e3f084bb424a93abf4255f Mon Sep 17 00:00:00 2001 From: Ian Storm Taylor Date: Tue, 22 Nov 2016 16:56:22 -0800 Subject: [PATCH 10/13] refactor splitBlock --- src/transforms/at-current-range.js | 38 +++++------------------------- 1 file changed, 6 insertions(+), 32 deletions(-) diff --git a/src/transforms/at-current-range.js b/src/transforms/at-current-range.js index 2eeccea38..bf4802309 100644 --- a/src/transforms/at-current-range.js +++ b/src/transforms/at-current-range.js @@ -218,38 +218,12 @@ export function setInline(transform, properties) { export function splitBlock(transform, depth = 1) { let { state } = transform - let { document, selection } = state - - transform.unsetSelection() - transform.splitBlockAtRange(selection, depth) - - state = transform.state - document = state.document - - const { startKey, startOffset } = selection - const startText = document.getNode(startKey) - const startBlock = document.getClosestBlock(startKey) - const startInline = startBlock.getFurthestInline(startKey) - const nextText = document.getNextText(startText.key) - let after - - // If the selection is at the start of the highest inline child inside the - // block, the starting text node won't need to be split. - if ( - (startOffset == 0) && - (startBlock.text != '') && - (!startInline || startInline.getOffset(startText.key) == 0) - ) { - after = selection.collapseToStartOf(startText) - } - - // Otherwise, we'll need to move the selection forward one to account for the - // text node that was split. - else { - after = selection.collapseToStartOf(nextText) - } - - transform.moveTo(after) + let { selection } = state + transform + .snapshotSelection() + .splitBlockAtRange(selection, depth) + .collapseToEnd() + .snapshotSelection() } /** From a15570885d67ce80597e2502867f5078949f016c Mon Sep 17 00:00:00 2001 From: Ian Storm Taylor Date: Tue, 22 Nov 2016 16:57:35 -0800 Subject: [PATCH 11/13] refactor splitInline --- src/transforms/at-current-range.js | 43 ++++-------------------------- 1 file changed, 5 insertions(+), 38 deletions(-) diff --git a/src/transforms/at-current-range.js b/src/transforms/at-current-range.js index bf4802309..5c1e6813a 100644 --- a/src/transforms/at-current-range.js +++ b/src/transforms/at-current-range.js @@ -235,44 +235,11 @@ export function splitBlock(transform, depth = 1) { export function splitInline(transform, depth = Infinity) { let { state } = transform - let { document, selection } = state - - // If the selection is expanded, remove it first. - if (selection.isExpanded) { - transform.delete() - state = transform.state - document = state.document - selection = state.selection - } - - let after = selection - const { startKey, startOffset } = selection - let startNode = document.assertDescendant(startKey) - const furthestInline = document.getFurthestInline(startKey) - const offset = furthestInline.getOffset(startNode.key) - - // If the selection is at the start of end of the furthest inline, there isn't - // anything to split, so abort. - if ( - (offset + startOffset == 0) || - (offset + startNode.length == startOffset) - ) { - return - } - - transform.unsetSelection() - transform.splitInlineAtRange(selection, depth) - state = transform.state - document = state.document - const closestInline = document.getClosestInline(startKey) - - if (closestInline) { - startNode = document.getDescendant(startKey) - const nextNode = document.getNextText(startNode.key) - after = selection.collapseToStartOf(nextNode) - } - - transform.moveTo(after) + let { selection } = state + transform + .snapshotSelection() + .splitInlineAtRange(selection, depth) + .snapshotSelection() } /** From 3cacea1516a2f28602fd094209e20552db9b1e6b Mon Sep 17 00:00:00 2001 From: Ian Storm Taylor Date: Tue, 22 Nov 2016 17:35:28 -0800 Subject: [PATCH 12/13] refactor normalize transforms --- src/transforms/normalize.js | 58 +++++++++++++++---------------------- 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/src/transforms/normalize.js b/src/transforms/normalize.js index 0e0395547..f0473c308 100644 --- a/src/transforms/normalize.js +++ b/src/transforms/normalize.js @@ -47,7 +47,7 @@ export function normalizeNodeByKey(transform, key, schema) { const { document } = state const node = document.assertNode(key) - normalizeNodeWith(transform, node, schema) + normalizeNodeAndChildren(transform, node, schema) } /** @@ -69,11 +69,11 @@ export function normalizeParentsByKey(transform, key, schema) { const { document } = state const node = document.assertNode(key) - normalizeParentsWith(transform, node, schema) + normalizeNodeAndParents(transform, node, schema) } /** - * Normalize only the selection. + * Normalize the selection. * * @param {Transform} transform */ @@ -114,21 +114,26 @@ export function normalizeSelection(transform) { * @param {Schema} schema */ -function normalizeNodeWith(transform, node, schema) { - // For performance considerations, we will check if the transform was changed. - const opCount = transform.operations.length +function normalizeNodeAndChildren(transform, node, schema) { + // For performance considerations, we will check if the transform has actually + // added operations to the queue. + const count = transform.operations.length // Iterate over its children. - normalizeChildrenWith(transform, node, schema) + if (node.kind != 'text') { + node.nodes.forEach((child) => { + normalizeNodeAndChildren(transform, child, schema) + }) + } // Re-find the node reference if necessary. - if (transform.operations.length != opCount) { + if (transform.operations.length != count) { node = refindNode(transform, node) } // Now normalize the node itself if it still exists. if (node) { - normalizeNodeOnly(transform, node, schema) + normalizeNode(transform, node, schema) } } @@ -140,10 +145,10 @@ function normalizeNodeWith(transform, node, schema) { * @param {Schema} schema */ -function normalizeParentsWith(transform, node, schema) { - normalizeNodeOnly(transform, node, schema) +function normalizeNodeAndParents(transform, node, schema) { + normalizeNode(transform, node, schema) - // Normalize went back up to the very top of the document. + // We're at the top of the document. if (node.kind == 'document') return // Re-find the node first. @@ -154,7 +159,7 @@ function normalizeParentsWith(transform, node, schema) { const { document } = state const parent = document.getParent(node.key) - normalizeParentsWith(transform, parent, schema) + normalizeNodeAndParents(transform, parent, schema) } /** @@ -174,22 +179,6 @@ function refindNode(transform, node) { : document.getDescendant(node.key) } -/** - * Normalize the children of a `node` with a `schema`. - * - * @param {Transform} transform - * @param {Node} node - * @param {Schema} schema - */ - -function normalizeChildrenWith(transform, node, schema) { - if (node.kind == 'text') return - - node.nodes.forEach((child) => { - normalizeNodeWith(transform, child, schema) - }) -} - /** * Normalize a `node` with a `schema`, but not its children. * @@ -198,7 +187,7 @@ function normalizeChildrenWith(transform, node, schema) { * @param {Schema} schema */ -function normalizeNodeOnly(transform, node, schema) { +function normalizeNode(transform, node, schema) { let max = schema.rules.length let iterations = 0 @@ -206,9 +195,8 @@ function normalizeNodeOnly(transform, node, schema) { const failure = n.validate(schema) if (!failure) return + // Run the `normalize` function for the rule with the invalid value. const { value, rule } = failure - - // Rule the `normalize` function for the rule with the invalid value. rule.normalize(t, n, value) // Re-find the node reference, in case it was updated. If the node no longer @@ -240,9 +228,9 @@ function normalizeNodeOnly(transform, node, schema) { */ function assertSchema(schema) { - if (schema instanceof Schema) return - - if (schema == null) { + if (schema instanceof Schema) { + return + } else if (schema == null) { throw new Error('You must pass a `schema` object.') } else { throw new Error(`You passed an invalid \`schema\` object: ${schema}.`) From 5b81f0bd843abc1aef34c9bb3814a27337d06adb Mon Sep 17 00:00:00 2001 From: Ian Storm Taylor Date: Tue, 22 Nov 2016 17:40:26 -0800 Subject: [PATCH 13/13] remove normalizeParentsByKey --- src/transforms/by-key.js | 4 ++-- src/transforms/index.js | 2 -- src/transforms/normalize.js | 47 ------------------------------------- 3 files changed, 2 insertions(+), 51 deletions(-) diff --git a/src/transforms/by-key.js b/src/transforms/by-key.js index 869a52fc3..3a128f803 100644 --- a/src/transforms/by-key.js +++ b/src/transforms/by-key.js @@ -201,8 +201,8 @@ export function removeTextByKey(transform, key, offset, length, options = {}) { transform.removeTextOperation(path, offset, length) if (normalize) { - const parent = document.getParent(key) - transform.normalizeParentsByKey(parent.key, SCHEMA) + const block = document.getClosestBlock(key) + transform.normalizeNodeByKey(block.key, SCHEMA) } } diff --git a/src/transforms/index.js b/src/transforms/index.js index 6ce9e61cf..8ee1eac6f 100644 --- a/src/transforms/index.js +++ b/src/transforms/index.js @@ -155,7 +155,6 @@ import { normalizeDocument, normalizeSelection, normalizeNodeByKey, - normalizeParentsByKey, } from './normalize' /** @@ -307,5 +306,4 @@ export default { normalizeDocument, normalizeSelection, normalizeNodeByKey, - normalizeParentsByKey, } diff --git a/src/transforms/normalize.js b/src/transforms/normalize.js index f0473c308..76ecbae59 100644 --- a/src/transforms/normalize.js +++ b/src/transforms/normalize.js @@ -50,28 +50,6 @@ export function normalizeNodeByKey(transform, key, schema) { normalizeNodeAndChildren(transform, node, schema) } -/** - * Normalize a `node` and its parents with a `schema`. - * - * @param {Transform} transform - * @param {Node|String} key - * @param {Schema} schema - */ - -export function normalizeParentsByKey(transform, key, schema) { - assertSchema(schema) - - // If the schema has no validation rules, there's nothing to normalize. - if (!schema.hasValidators) return - - key = Normalize.key(key) - const { state } = transform - const { document } = state - const node = document.assertNode(key) - - normalizeNodeAndParents(transform, node, schema) -} - /** * Normalize the selection. * @@ -137,31 +115,6 @@ function normalizeNodeAndChildren(transform, node, schema) { } } -/** - * Normalize a `node` and its parents with a `schema`. - * - * @param {Transform} transform - * @param {Node} node - * @param {Schema} schema - */ - -function normalizeNodeAndParents(transform, node, schema) { - normalizeNode(transform, node, schema) - - // We're at the top of the document. - if (node.kind == 'document') return - - // Re-find the node first. - node = refindNode(transform, node) - if (!node) return - - const { state } = transform - const { document } = state - const parent = document.getParent(node.key) - - normalizeNodeAndParents(transform, parent, schema) -} - /** * Re-find a reference to a node that may have been modified or removed * entirely by a transform.