diff --git a/src/models/node.js b/src/models/node.js index ddebb8719..2b4e66e35 100644 --- a/src/models/node.js +++ b/src/models/node.js @@ -658,15 +658,20 @@ const Node = { */ getHighestOnlyChildParent(key) { - let child = this.assertDescendant(key) - let match = null - let parent + const ancestors = this.getAncestors(key) - while (parent = this.getParent(child)) { - if (parent == null || parent.nodes.size > 1) return match - match = parent - child = parent + if (!ancestors) { + key = Normalize.key(key) + throw new Error(`Could not find a descendant node with key "${key}".`) } + + return ancestors + // Skip this node + .skipLast() + // Take parents until there are more than one child + .reverse().takeUntil(p => p.nodes.size > 1) + // Pick the highest + .last() }, /** diff --git a/src/transforms/at-range.js b/src/transforms/at-range.js index f5816fe82..6f6aee1ab 100644 --- a/src/transforms/at-range.js +++ b/src/transforms/at-range.js @@ -111,7 +111,8 @@ export function deleteAtRange(transform, range, options = {}) { transform.moveNodeByKey(child.key, newKey, newIndex, OPTS) }) - const lonely = document.getFurthest(endBlock.key, p => p.nodes.size == 1) || endBlock + // Remove parents of endBlock as long as they have a single child + const lonely = document.getHighestOnlyChildParent(endBlock.key) || endBlock transform.removeNodeByKey(lonely.key, OPTS) } diff --git a/test/transforms/fixtures/at-range/delete-at-range/double-nested-block/index.js b/test/transforms/fixtures/at-range/delete-at-range/double-nested-block/index.js new file mode 100644 index 000000000..69d0e28e5 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-at-range/double-nested-block/index.js @@ -0,0 +1,7 @@ + +export default function (state) { + return state + .transform() + .deleteAtRange(state.selection) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-at-range/double-nested-block/input.yaml b/test/transforms/fixtures/at-range/delete-at-range/double-nested-block/input.yaml new file mode 100644 index 000000000..1bc26659b --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-at-range/double-nested-block/input.yaml @@ -0,0 +1,32 @@ + +document: + key: a + nodes: + - key: b + kind: block + type: list + nodes: + - key: c + kind: block + type: item + nodes: + - key: d + kind: block + type: line + nodes: + - key: e + kind: text + text: "Text" + - key: f + kind: block + type: line + nodes: + - key: g + kind: text + text: "" +selection: + anchorKey: e + anchorOffset: 4 + focusKey: g + focusOffset: 0 + isFocused: true diff --git a/test/transforms/fixtures/at-range/delete-at-range/double-nested-block/output.yaml b/test/transforms/fixtures/at-range/delete-at-range/double-nested-block/output.yaml new file mode 100644 index 000000000..71a6d4138 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-at-range/double-nested-block/output.yaml @@ -0,0 +1,13 @@ + +nodes: +- kind: block + type: list + nodes: + - kind: block + type: item + nodes: + - kind: block + type: line + nodes: + - kind: text + text: "Text"