From d995b1ab35295df38a7bb82cee1bd3a2b97c735d Mon Sep 17 00:00:00 2001 From: Ian Storm Taylor Date: Fri, 15 Jul 2016 12:49:29 -0700 Subject: [PATCH] fix a few void block transform and rendering bugs --- lib/components/content.js | 2 +- lib/models/node.js | 12 +++++++++++- lib/models/state.js | 14 +++++++++++--- lib/models/transforms.js | 8 ++++++++ lib/plugins/core.js | 11 +++++++++-- 5 files changed, 40 insertions(+), 7 deletions(-) diff --git a/lib/components/content.js b/lib/components/content.js index 3198a1587..0bf9f8641 100644 --- a/lib/components/content.js +++ b/lib/components/content.js @@ -324,7 +324,7 @@ class Content extends React.Component { focusKey: focus.key, focusOffset: focus.offset }) - .apply({ isNative: true }) + .apply() this.onChange(state) } diff --git a/lib/models/node.js b/lib/models/node.js index b414135dd..dd74ad7ff 100644 --- a/lib/models/node.js +++ b/lib/models/node.js @@ -763,6 +763,17 @@ const Node = { }) }, + /** + * Check if a node has a void parent by `key`. + * + * @param {String or Node} key + * @return {Boolean} + */ + + hasVoidParent(key) { + return !!this.getClosest(key, n => n.isVoid) + }, + /** * Insert child `nodes` after child by `key`. * @@ -772,7 +783,6 @@ const Node = { */ insertChildrenAfter(key, nodes) { - key = normalizeKey(key) const child = this.getChild(key) const index = this.nodes.indexOf(child) diff --git a/lib/models/state.js b/lib/models/state.js index f2ae395ab..1376e1d40 100644 --- a/lib/models/state.js +++ b/lib/models/state.js @@ -560,9 +560,17 @@ class State extends new Record(DEFAULTS) { } else if (selection.isAtStartOf(startNode)) { - const parent = document.getParent(startNode) - const previous = document.getPreviousSibling(parent).nodes.first() - after = selection.collapseToEndOf(previous) + const previous = document.getPreviousText(startNode) + const prevBlock = document.getClosestBlock(previous) + const prevInline = document.getClosestInline(previous) + + if (prevBlock && prevBlock.isVoid) { + after = selection + } else if (prevInline && prevInline.isVoid) { + after = selection + } else { + after = selection.collapseToEndOf(previous) + } } else { diff --git a/lib/models/transforms.js b/lib/models/transforms.js index cfe9ad4d3..b3778f4a8 100644 --- a/lib/models/transforms.js +++ b/lib/models/transforms.js @@ -117,6 +117,14 @@ const Transforms = { if (range.isAtStartOf(startNode)) { const previous = node.getPreviousText(startNode) + + // If the previous descendant is void, remove it. + const prevBlock = node.getClosestBlock(previous) + if (prevBlock && prevBlock.isVoid) return node.removeDescendant(prevBlock) + + const prevInline = node.getClosestInline(previous) + if (prevInline && prevInline.isVoid) return node.removeDescendant(prevInline) + range = range.extendToEndOf(previous) range = range.normalize(node) return node.deleteAtRange(range) diff --git a/lib/plugins/core.js b/lib/plugins/core.js index e92a419b4..fa1bdd75c 100644 --- a/lib/plugins/core.js +++ b/lib/plugins/core.js @@ -147,11 +147,18 @@ function Plugin(options = {}) { onKeyDown(e, state, editor) { const key = keycode(e.which) - const transform = state.transform() + let transform = state.transform() switch (key) { case 'enter': { - return transform.splitBlock().apply() + const { startBlock } = state + if (startBlock && !startBlock.isVoid) return transform.splitBlock().apply() + + const { document, startKey } = state + const text = document.getNextText(startKey) + if (!text) return + + return transform.collapseToStartOf(text).apply() } case 'backspace': {