diff --git a/src/transforms/at-range.js b/src/transforms/at-range.js index dc6773bba..d9f5386c7 100644 --- a/src/transforms/at-range.js +++ b/src/transforms/at-range.js @@ -185,52 +185,64 @@ export function deleteBackwardAtRange(transform, range, n = 1, options = {}) { const { document } = state const { startKey, focusOffset } = range + // If the range is expanded, perform a regular delete instead. if (range.isExpanded) { transform.deleteAtRange(range, { normalize }) return } + // If the closest block is void, delete it. const block = document.getClosestBlock(startKey) if (block && block.isVoid) { transform.removeNodeByKey(block.key, { normalize }) return } + // If the closest inline is void, delete it. const inline = document.getClosestInline(startKey) if (inline && inline.isVoid) { transform.removeNodeByKey(inline.key, { normalize }) return } + // If the range is at the start of the document, abort. if (range.isAtStartOf(document)) { return } + // If the range is at the start of the text node, we need to figure out what + // is behind it to know how to delete... const text = document.getDescendant(startKey) if (range.isAtStartOf(text)) { const prev = document.getPreviousText(text.key) const prevBlock = document.getClosestBlock(prev.key) const prevInline = document.getClosestInline(prev.key) + // If the previous block is void, remove it. if (prevBlock && prevBlock.isVoid) { transform.removeNodeByKey(prevBlock.key, { normalize }) return } + // If the previous inline is void, remove it. if (prevInline && prevInline.isVoid) { transform.removeNodeByKey(prevInline.key, { normalize }) return } + // If the previous text's block is inside the current block, then we need + // to remove a character when deleteing. Otherwise, we just want to join + // the two blocks together. range = range.merge({ anchorKey: prev.key, - anchorOffset: prev.length, + anchorOffset: prevBlock == block ? prev.length - 1 : prev.length, }) transform.deleteAtRange(range, { normalize }) return } + // Otherwise, just remove a character backwards. range = range.merge({ focusOffset: focusOffset - n, isBackward: true, @@ -341,9 +353,12 @@ export function deleteForwardAtRange(transform, range, n = 1, options = {}) { return } + // If the next text's block is inside the current block, then we need + // to remove a character when deleteing. Otherwise, we just want to join + // the two blocks together. range = range.merge({ focusKey: next.key, - focusOffset: 0 + focusOffset: nextBlock == block ? 1 : 0 }) transform.deleteAtRange(range, { normalize }) diff --git a/test/transforms/fixtures/at-range/delete-backward-at-range/before-inline-sibling/index.js b/test/transforms/fixtures/at-range/delete-backward-at-range/after-inline-sibling-across/index.js similarity index 100% rename from test/transforms/fixtures/at-range/delete-backward-at-range/before-inline-sibling/index.js rename to test/transforms/fixtures/at-range/delete-backward-at-range/after-inline-sibling-across/index.js diff --git a/test/transforms/fixtures/at-range/delete-backward-at-range/before-inline-sibling/output.yaml b/test/transforms/fixtures/at-range/delete-backward-at-range/after-inline-sibling-across/input.yaml similarity index 100% rename from test/transforms/fixtures/at-range/delete-backward-at-range/before-inline-sibling/output.yaml rename to test/transforms/fixtures/at-range/delete-backward-at-range/after-inline-sibling-across/input.yaml diff --git a/test/transforms/fixtures/at-range/delete-backward-at-range/after-inline-sibling-across/output.yaml b/test/transforms/fixtures/at-range/delete-backward-at-range/after-inline-sibling-across/output.yaml new file mode 100644 index 000000000..d5be0d20b --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-backward-at-range/after-inline-sibling-across/output.yaml @@ -0,0 +1,14 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: one + - kind: inline + type: link + nodes: + - kind: text + text: tw + - kind: text + text: "" diff --git a/test/transforms/fixtures/at-range/delete-backward-at-range/after-inline-sibling/index.js b/test/transforms/fixtures/at-range/delete-backward-at-range/after-inline-sibling/index.js new file mode 100644 index 000000000..cce7cc965 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-backward-at-range/after-inline-sibling/index.js @@ -0,0 +1,17 @@ + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const last = texts.last() + const range = selection.merge({ + anchorKey: last.key, + anchorOffset: last.length, + focusKey: last.key, + focusOffset: last.length + }) + + return state + .transform() + .deleteBackwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-backward-at-range/before-inline-sibling/input.yaml b/test/transforms/fixtures/at-range/delete-backward-at-range/after-inline-sibling/input.yaml similarity index 100% rename from test/transforms/fixtures/at-range/delete-backward-at-range/before-inline-sibling/input.yaml rename to test/transforms/fixtures/at-range/delete-backward-at-range/after-inline-sibling/input.yaml diff --git a/test/transforms/fixtures/at-range/delete-backward-at-range/after-inline-sibling/output.yaml b/test/transforms/fixtures/at-range/delete-backward-at-range/after-inline-sibling/output.yaml new file mode 100644 index 000000000..2b96bda07 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-backward-at-range/after-inline-sibling/output.yaml @@ -0,0 +1,14 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: one + - kind: inline + type: link + nodes: + - kind: text + text: two + - kind: text + text: "" diff --git a/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling-into/index.js b/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling-into/index.js new file mode 100644 index 000000000..255f645ee --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling-into/index.js @@ -0,0 +1,17 @@ + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const first = texts.first() + const range = selection.merge({ + anchorKey: first.key, + anchorOffset: 0, + focusKey: first.key, + focusOffset: 0 + }) + + return state + .transform() + .deleteForwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling-into/input.yaml b/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling-into/input.yaml new file mode 100644 index 000000000..1281167d8 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling-into/input.yaml @@ -0,0 +1,14 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "" + - kind: inline + type: link + nodes: + - kind: text + text: two + - kind: text + text: three diff --git a/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling-into/output.yaml b/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling-into/output.yaml new file mode 100644 index 000000000..fea2131af --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling-into/output.yaml @@ -0,0 +1,14 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "" + - kind: inline + type: link + nodes: + - kind: text + text: wo + - kind: text + text: three diff --git a/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling/index.js b/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling/index.js index 876bb95df..255f645ee 100644 --- a/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling/index.js +++ b/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling/index.js @@ -2,11 +2,11 @@ export default function (state) { const { document, selection } = state const texts = document.getTexts() - const last = texts.last() + const first = texts.first() const range = selection.merge({ - anchorKey: last.key, + anchorKey: first.key, anchorOffset: 0, - focusKey: last.key, + focusKey: first.key, focusOffset: 0 }) diff --git a/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling/input.yaml b/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling/input.yaml index 6286c3b87..c6b3f118d 100644 --- a/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling/input.yaml +++ b/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling/input.yaml @@ -4,11 +4,11 @@ nodes: type: paragraph nodes: - kind: text - text: one + text: a - kind: inline type: link nodes: - kind: text text: two - kind: text - text: a + text: three diff --git a/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling/output.yaml b/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling/output.yaml index 2b96bda07..1281167d8 100644 --- a/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling/output.yaml +++ b/test/transforms/fixtures/at-range/delete-forward-at-range/before-inline-sibling/output.yaml @@ -4,11 +4,11 @@ nodes: type: paragraph nodes: - kind: text - text: one + text: "" - kind: inline type: link nodes: - kind: text text: two - kind: text - text: "" + text: three