diff --git a/src/transforms/at-range.js b/src/transforms/at-range.js index d9f5386c7..f5816fe82 100644 --- a/src/transforms/at-range.js +++ b/src/transforms/at-range.js @@ -131,9 +131,13 @@ export function deleteAtRange(transform, range, options = {}) { export function deleteCharBackwardAtRange(transform, range, options) { const { state } = transform - const { startOffset, startBlock } = state + const { document } = state + const { startKey, startOffset } = range + const startBlock = document.getClosestBlock(startKey) + const offset = startBlock.getOffset(startKey) + const o = offset + startOffset const { text } = startBlock - const n = String.getCharOffsetBackward(text, startOffset) + const n = String.getCharOffsetBackward(text, o) transform.deleteBackwardAtRange(range, n, options) } @@ -148,8 +152,12 @@ export function deleteCharBackwardAtRange(transform, range, options) { export function deleteLineBackwardAtRange(transform, range, options) { const { state } = transform - const { startOffset } = state - transform.deleteBackwardAtRange(range, startOffset, options) + const { document } = state + const { startKey, startOffset } = range + const startBlock = document.getClosestBlock(startKey) + const offset = startBlock.getOffset(startKey) + const o = offset + startOffset + transform.deleteBackwardAtRange(range, o, options) } /** @@ -163,9 +171,13 @@ export function deleteLineBackwardAtRange(transform, range, options) { export function deleteWordBackwardAtRange(transform, range, options) { const { state } = transform - const { startOffset, startBlock } = state + const { document } = state + const { startKey, startOffset } = range + const startBlock = document.getClosestBlock(startKey) + const offset = startBlock.getOffset(startKey) + const o = offset + startOffset const { text } = startBlock - const n = String.getWordOffsetBackward(text, startOffset) + const n = String.getWordOffsetBackward(text, o) transform.deleteBackwardAtRange(range, n, options) } @@ -230,22 +242,58 @@ export function deleteBackwardAtRange(transform, range, n = 1, options = {}) { 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. + // If we're deleting by one character and the previous text node is not + // inside the current block, we need to join the two blocks together. + if (n == 1 && prevBlock != block) { + range = range.merge({ + anchorKey: prev.key, + anchorOffset: prev.length, + }) + + transform.deleteAtRange(range, { normalize }) + return + } + } + + // If the focus offset is farther than the number of characters to delete, + // just remove the characters backwards inside the current node. + if (n < focusOffset) { range = range.merge({ - anchorKey: prev.key, - anchorOffset: prevBlock == block ? prev.length - 1 : prev.length, + focusOffset: focusOffset - n, + isBackward: true, }) transform.deleteAtRange(range, { normalize }) return } - // Otherwise, just remove a character backwards. + // Otherwise, we need to see how many nodes backwards to go. + let node = text + let offset = 0 + let traversed = focusOffset + + while (n > traversed) { + node = document.getPreviousText(node.key) + const next = traversed + node.length + if (n <= next) { + offset = next - n + break + } else { + traversed = next + } + } + + // If the focus node is inside a void, go up until right after it. + if (document.hasVoidParent(node.key)) { + const parent = document.getClosest(node.key, p => p.isVoid) + node = document.getNextText(parent.key) + offset = 0 + } + range = range.merge({ - focusOffset: focusOffset - n, - isBackward: true, + focusKey: node.key, + focusOffset: offset, + isBackward: true }) transform.deleteAtRange(range, { normalize }) @@ -262,9 +310,13 @@ export function deleteBackwardAtRange(transform, range, n = 1, options = {}) { export function deleteCharForwardAtRange(transform, range, options) { const { state } = transform - const { startOffset, startBlock } = state + const { document } = state + const { startKey, startOffset } = range + const startBlock = document.getClosestBlock(startKey) + const offset = startBlock.getOffset(startKey) + const o = offset + startOffset const { text } = startBlock - const n = String.getCharOffsetForward(text, startOffset) + const n = String.getCharOffsetForward(text, o) transform.deleteForwardAtRange(range, n, options) } @@ -279,8 +331,12 @@ export function deleteCharForwardAtRange(transform, range, options) { export function deleteLineForwardAtRange(transform, range, options) { const { state } = transform - const { startOffset, startBlock } = state - transform.deleteForwardAtRange(range, startBlock.length - startOffset, options) + const { document } = state + const { startKey, startOffset } = range + const startBlock = document.getClosestBlock(startKey) + const offset = startBlock.getOffset(startKey) + const o = offset + startOffset + transform.deleteForwardAtRange(range, o, options) } /** @@ -294,9 +350,13 @@ export function deleteLineForwardAtRange(transform, range, options) { export function deleteWordForwardAtRange(transform, range, options) { const { state } = transform - const { startOffset, startBlock } = state + const { document } = state + const { startKey, startOffset } = range + const startBlock = document.getClosestBlock(startKey) + const offset = startBlock.getOffset(startKey) + const o = offset + startOffset const { text } = startBlock - const n = String.getWordOffsetForward(text, startOffset) + const n = String.getWordOffsetForward(text, o) transform.deleteForwardAtRange(range, n, options) } @@ -316,57 +376,102 @@ export function deleteForwardAtRange(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.isAtEndOf(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.isAtEndOf(text)) { const next = document.getNextText(text.key) const nextBlock = document.getClosestBlock(next.key) const nextInline = document.getClosestInline(next.key) + // If the previous block is void, remove it. if (nextBlock && nextBlock.isVoid) { transform.removeNodeByKey(nextBlock.key, { normalize }) return } + // If the previous inline is void, remove it. if (nextInline && nextInline.isVoid) { transform.removeNodeByKey(nextInline.key, { normalize }) 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. + // If we're deleting by one character and the previous text node is not + // inside the current block, we need to join the two blocks together. + if (n == 1 && nextBlock != block) { + range = range.merge({ + focusKey: next.key, + focusOffset: 0 + }) + + transform.deleteAtRange(range, { normalize }) + return + } + } + + // If the remaining characters to the end of the node is greater than or equal + // to the number of characters to delete, just remove the characters forwards + // inside the current node. + if (n <= (text.length - focusOffset)) { range = range.merge({ - focusKey: next.key, - focusOffset: nextBlock == block ? 1 : 0 + focusOffset: focusOffset + n }) transform.deleteAtRange(range, { normalize }) return } + // Otherwise, we need to see how many nodes forwards to go. + let node = text + let offset = focusOffset + let traversed = text.length - focusOffset + + while (n > traversed) { + node = document.getNextText(node.key) + const next = traversed + node.length + if (n <= next) { + offset = n - traversed + break + } else { + traversed = next + } + } + + // If the focus node is inside a void, go up until right before it. + if (document.hasVoidParent(node.key)) { + const parent = document.getClosest(node.key, p => p.isVoid) + node = document.getPreviousText(parent.key) + offset = node.length + } + range = range.merge({ - focusOffset: focusOffset + n + focusKey: node.key, + focusOffset: offset, }) transform.deleteAtRange(range, { normalize }) diff --git a/src/utils/string.js b/src/utils/string.js index 354c747c6..eff8b65cd 100644 --- a/src/utils/string.js +++ b/src/utils/string.js @@ -59,8 +59,9 @@ function isWord(char, remaining) { // If it's a chameleon character, recurse to see if the next one is or not. if (CHAMELEON.test(char)) { - const next = remaining.charAt(0) + let next = remaining.charAt(0) const length = getCharLength(next) + next = remaining.slice(0, length) const rest = remaining.slice(length) if (isWord(next, rest)) return true } @@ -136,13 +137,14 @@ function getWordOffset(text) { while (char = text.charAt(i)) { const l = getCharLength(char) + char = text.slice(i, i + l) const rest = text.slice(i + l) if (isWord(char, rest)) { started = true - length++ + length += l } else if (!started) { - length++ + length += l } else { break } @@ -164,7 +166,8 @@ function getWordOffset(text) { function getWordOffsetBackward(text, offset) { text = text.slice(0, offset) text = reverse(text) - return getWordOffset(text) + const o = getWordOffset(text) + return o } /** @@ -177,7 +180,8 @@ function getWordOffsetBackward(text, offset) { function getWordOffsetForward(text, offset) { text = text.slice(offset) - return getWordOffset(text) + const o = getWordOffset(text) + return o } /** diff --git a/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-after-inline/index.js b/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-after-inline/index.js new file mode 100644 index 000000000..0bdb16466 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-after-inline/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() + .deleteCharBackwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-after-inline/input.yaml b/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-after-inline/input.yaml new file mode 100644 index 000000000..6d23e9f92 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-after-inline/input.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-char-backward-at-range/emoji-after-inline/output.yaml b/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-after-inline/output.yaml new file mode 100644 index 000000000..2b96bda07 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-after-inline/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-char-backward-at-range/emoji-end-of-inline/index.js b/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-end-of-inline/index.js new file mode 100644 index 000000000..0bdb16466 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-end-of-inline/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() + .deleteCharBackwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-end-of-inline/input.yaml b/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-end-of-inline/input.yaml new file mode 100644 index 000000000..f7f5b51f4 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-end-of-inline/input.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-char-backward-at-range/emoji-end-of-inline/output.yaml b/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-end-of-inline/output.yaml new file mode 100644 index 000000000..d5be0d20b --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-end-of-inline/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-char-backward-at-range/emoji-inside-inline/index.js b/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-inside-inline/index.js new file mode 100644 index 000000000..5b7b47d23 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-inside-inline/index.js @@ -0,0 +1,17 @@ + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const second = texts.get(1) + const range = selection.merge({ + anchorKey: second.key, + anchorOffset: second.length - 1, + focusKey: second.key, + focusOffset: second.length - 1 + }) + + return state + .transform() + .deleteCharBackwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-inside-inline/input.yaml b/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-inside-inline/input.yaml new file mode 100644 index 000000000..0fc43b990 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-inside-inline/input.yaml @@ -0,0 +1,14 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: one + - kind: inline + type: link + nodes: + - kind: text + text: tw📛o + - kind: text + text: "" diff --git a/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-inside-inline/output.yaml b/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-inside-inline/output.yaml new file mode 100644 index 000000000..2b96bda07 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-backward-at-range/emoji-inside-inline/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-char-backward-at-range/end-of-word/index.js b/test/transforms/fixtures/at-range/delete-char-backward-at-range/end-of-word/index.js new file mode 100644 index 000000000..0bdb16466 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-backward-at-range/end-of-word/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() + .deleteCharBackwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-char-backward-at-range/end-of-word/input.yaml b/test/transforms/fixtures/at-range/delete-char-backward-at-range/end-of-word/input.yaml new file mode 100644 index 000000000..efc0975dd --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-backward-at-range/end-of-word/input.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "one two three" diff --git a/test/transforms/fixtures/at-range/delete-char-backward-at-range/end-of-word/output.yaml b/test/transforms/fixtures/at-range/delete-char-backward-at-range/end-of-word/output.yaml new file mode 100644 index 000000000..c70b57d2a --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-backward-at-range/end-of-word/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "one two thre" diff --git a/test/transforms/fixtures/at-range/delete-char-backward-at-range/middle-of-word/index.js b/test/transforms/fixtures/at-range/delete-char-backward-at-range/middle-of-word/index.js new file mode 100644 index 000000000..0e4b3d677 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-backward-at-range/middle-of-word/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 - 2, + focusKey: last.key, + focusOffset: last.length - 2 + }) + + return state + .transform() + .deleteCharBackwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-char-backward-at-range/middle-of-word/input.yaml b/test/transforms/fixtures/at-range/delete-char-backward-at-range/middle-of-word/input.yaml new file mode 100644 index 000000000..efc0975dd --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-backward-at-range/middle-of-word/input.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "one two three" diff --git a/test/transforms/fixtures/at-range/delete-char-backward-at-range/middle-of-word/output.yaml b/test/transforms/fixtures/at-range/delete-char-backward-at-range/middle-of-word/output.yaml new file mode 100644 index 000000000..10cef78d4 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-backward-at-range/middle-of-word/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "one two thee" diff --git a/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-before-inline/index.js b/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-before-inline/index.js new file mode 100644 index 000000000..05036f66f --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-before-inline/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() + .deleteCharForwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-before-inline/input.yaml b/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-before-inline/input.yaml new file mode 100644 index 000000000..a9fd480cd --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-before-inline/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-char-forward-at-range/emoji-before-inline/output.yaml b/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-before-inline/output.yaml new file mode 100644 index 000000000..1281167d8 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-before-inline/output.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-char-forward-at-range/emoji-inside-inline/index.js b/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-inside-inline/index.js new file mode 100644 index 000000000..0c26be185 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-inside-inline/index.js @@ -0,0 +1,17 @@ + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const second = texts.get(1) + const range = selection.merge({ + anchorKey: second.key, + anchorOffset: 2, + focusKey: second.key, + focusOffset: 2 + }) + + return state + .transform() + .deleteCharForwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-inside-inline/input.yaml b/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-inside-inline/input.yaml new file mode 100644 index 000000000..0fc43b990 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-inside-inline/input.yaml @@ -0,0 +1,14 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: one + - kind: inline + type: link + nodes: + - kind: text + text: tw📛o + - kind: text + text: "" diff --git a/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-inside-inline/output.yaml b/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-inside-inline/output.yaml new file mode 100644 index 000000000..2b96bda07 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-inside-inline/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-char-forward-at-range/emoji-start-of-inline/index.js b/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-start-of-inline/index.js new file mode 100644 index 000000000..05036f66f --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-start-of-inline/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() + .deleteCharForwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-start-of-inline/input.yaml b/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-start-of-inline/input.yaml new file mode 100644 index 000000000..9c420048a --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-start-of-inline/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-char-forward-at-range/emoji-start-of-inline/output.yaml b/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-start-of-inline/output.yaml new file mode 100644 index 000000000..1281167d8 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-forward-at-range/emoji-start-of-inline/output.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-char-forward-at-range/middle-of-word/index.js b/test/transforms/fixtures/at-range/delete-char-forward-at-range/middle-of-word/index.js new file mode 100644 index 000000000..92498e417 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-forward-at-range/middle-of-word/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: 1, + focusKey: first.key, + focusOffset: 1, + }) + + return state + .transform() + .deleteCharForwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-char-forward-at-range/middle-of-word/input.yaml b/test/transforms/fixtures/at-range/delete-char-forward-at-range/middle-of-word/input.yaml new file mode 100644 index 000000000..efc0975dd --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-forward-at-range/middle-of-word/input.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "one two three" diff --git a/test/transforms/fixtures/at-range/delete-char-forward-at-range/middle-of-word/output.yaml b/test/transforms/fixtures/at-range/delete-char-forward-at-range/middle-of-word/output.yaml new file mode 100644 index 000000000..b4e15dbae --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-forward-at-range/middle-of-word/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "oe two three" diff --git a/test/transforms/fixtures/at-range/delete-char-forward-at-range/start-of-word/index.js b/test/transforms/fixtures/at-range/delete-char-forward-at-range/start-of-word/index.js new file mode 100644 index 000000000..05036f66f --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-forward-at-range/start-of-word/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() + .deleteCharForwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-char-forward-at-range/start-of-word/input.yaml b/test/transforms/fixtures/at-range/delete-char-forward-at-range/start-of-word/input.yaml new file mode 100644 index 000000000..efc0975dd --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-forward-at-range/start-of-word/input.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "one two three" diff --git a/test/transforms/fixtures/at-range/delete-char-forward-at-range/start-of-word/output.yaml b/test/transforms/fixtures/at-range/delete-char-forward-at-range/start-of-word/output.yaml new file mode 100644 index 000000000..8cf0453af --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-char-forward-at-range/start-of-word/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "ne two three" diff --git a/test/transforms/fixtures/at-range/delete-word-backward-at-range/emoji-after-inline/index.js b/test/transforms/fixtures/at-range/delete-word-backward-at-range/emoji-after-inline/index.js new file mode 100644 index 000000000..3cf519e20 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-backward-at-range/emoji-after-inline/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() + .deleteWordBackwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-word-backward-at-range/emoji-after-inline/input.yaml b/test/transforms/fixtures/at-range/delete-word-backward-at-range/emoji-after-inline/input.yaml new file mode 100644 index 000000000..6d23e9f92 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-backward-at-range/emoji-after-inline/input.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-word-backward-at-range/emoji-after-inline/output.yaml b/test/transforms/fixtures/at-range/delete-word-backward-at-range/emoji-after-inline/output.yaml new file mode 100644 index 000000000..f6de4d08a --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-backward-at-range/emoji-after-inline/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "" diff --git a/test/transforms/fixtures/at-range/delete-word-backward-at-range/emoji-inside-inline/index.js b/test/transforms/fixtures/at-range/delete-word-backward-at-range/emoji-inside-inline/index.js new file mode 100644 index 000000000..3cf519e20 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-backward-at-range/emoji-inside-inline/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() + .deleteWordBackwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-word-backward-at-range/emoji-inside-inline/input.yaml b/test/transforms/fixtures/at-range/delete-word-backward-at-range/emoji-inside-inline/input.yaml new file mode 100644 index 000000000..0fc43b990 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-backward-at-range/emoji-inside-inline/input.yaml @@ -0,0 +1,14 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: one + - kind: inline + type: link + nodes: + - kind: text + text: tw📛o + - kind: text + text: "" diff --git a/test/transforms/fixtures/at-range/delete-word-backward-at-range/emoji-inside-inline/output.yaml b/test/transforms/fixtures/at-range/delete-word-backward-at-range/emoji-inside-inline/output.yaml new file mode 100644 index 000000000..f6de4d08a --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-backward-at-range/emoji-inside-inline/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "" diff --git a/test/transforms/fixtures/at-range/delete-word-backward-at-range/end-of-word/index.js b/test/transforms/fixtures/at-range/delete-word-backward-at-range/end-of-word/index.js new file mode 100644 index 000000000..3cf519e20 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-backward-at-range/end-of-word/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() + .deleteWordBackwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-word-backward-at-range/end-of-word/input.yaml b/test/transforms/fixtures/at-range/delete-word-backward-at-range/end-of-word/input.yaml new file mode 100644 index 000000000..efc0975dd --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-backward-at-range/end-of-word/input.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "one two three" diff --git a/test/transforms/fixtures/at-range/delete-word-backward-at-range/end-of-word/output.yaml b/test/transforms/fixtures/at-range/delete-word-backward-at-range/end-of-word/output.yaml new file mode 100644 index 000000000..541ed3175 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-backward-at-range/end-of-word/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "one two " diff --git a/test/transforms/fixtures/at-range/delete-word-backward-at-range/middle-of-word/index.js b/test/transforms/fixtures/at-range/delete-word-backward-at-range/middle-of-word/index.js new file mode 100644 index 000000000..6e41095c4 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-backward-at-range/middle-of-word/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 - 2, + focusKey: last.key, + focusOffset: last.length - 2 + }) + + return state + .transform() + .deleteWordBackwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-word-backward-at-range/middle-of-word/input.yaml b/test/transforms/fixtures/at-range/delete-word-backward-at-range/middle-of-word/input.yaml new file mode 100644 index 000000000..efc0975dd --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-backward-at-range/middle-of-word/input.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "one two three" diff --git a/test/transforms/fixtures/at-range/delete-word-backward-at-range/middle-of-word/output.yaml b/test/transforms/fixtures/at-range/delete-word-backward-at-range/middle-of-word/output.yaml new file mode 100644 index 000000000..70d73622f --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-backward-at-range/middle-of-word/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "one two ee" diff --git a/test/transforms/fixtures/at-range/delete-word-forward-at-range/emoji-after-inline/index.js b/test/transforms/fixtures/at-range/delete-word-forward-at-range/emoji-after-inline/index.js new file mode 100644 index 000000000..5b48c3515 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-forward-at-range/emoji-after-inline/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() + .deleteWordForwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-word-forward-at-range/emoji-after-inline/input.yaml b/test/transforms/fixtures/at-range/delete-word-forward-at-range/emoji-after-inline/input.yaml new file mode 100644 index 000000000..6d23e9f92 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-forward-at-range/emoji-after-inline/input.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-word-forward-at-range/emoji-after-inline/output.yaml b/test/transforms/fixtures/at-range/delete-word-forward-at-range/emoji-after-inline/output.yaml new file mode 100644 index 000000000..f6de4d08a --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-forward-at-range/emoji-after-inline/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "" diff --git a/test/transforms/fixtures/at-range/delete-word-forward-at-range/emoji-inside-inline/index.js b/test/transforms/fixtures/at-range/delete-word-forward-at-range/emoji-inside-inline/index.js new file mode 100644 index 000000000..5b48c3515 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-forward-at-range/emoji-inside-inline/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() + .deleteWordForwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-word-forward-at-range/emoji-inside-inline/input.yaml b/test/transforms/fixtures/at-range/delete-word-forward-at-range/emoji-inside-inline/input.yaml new file mode 100644 index 000000000..0fc43b990 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-forward-at-range/emoji-inside-inline/input.yaml @@ -0,0 +1,14 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: one + - kind: inline + type: link + nodes: + - kind: text + text: tw📛o + - kind: text + text: "" diff --git a/test/transforms/fixtures/at-range/delete-word-forward-at-range/emoji-inside-inline/output.yaml b/test/transforms/fixtures/at-range/delete-word-forward-at-range/emoji-inside-inline/output.yaml new file mode 100644 index 000000000..f6de4d08a --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-forward-at-range/emoji-inside-inline/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "" diff --git a/test/transforms/fixtures/at-range/delete-word-forward-at-range/middle-of-word/index.js b/test/transforms/fixtures/at-range/delete-word-forward-at-range/middle-of-word/index.js new file mode 100644 index 000000000..15f7fa5a3 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-forward-at-range/middle-of-word/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: 1, + focusKey: first.key, + focusOffset: 1, + }) + + return state + .transform() + .deleteWordForwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-word-forward-at-range/middle-of-word/input.yaml b/test/transforms/fixtures/at-range/delete-word-forward-at-range/middle-of-word/input.yaml new file mode 100644 index 000000000..efc0975dd --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-forward-at-range/middle-of-word/input.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "one two three" diff --git a/test/transforms/fixtures/at-range/delete-word-forward-at-range/middle-of-word/output.yaml b/test/transforms/fixtures/at-range/delete-word-forward-at-range/middle-of-word/output.yaml new file mode 100644 index 000000000..18d07866a --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-forward-at-range/middle-of-word/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "o two three" diff --git a/test/transforms/fixtures/at-range/delete-word-forward-at-range/start-of-word/index.js b/test/transforms/fixtures/at-range/delete-word-forward-at-range/start-of-word/index.js new file mode 100644 index 000000000..5b48c3515 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-forward-at-range/start-of-word/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() + .deleteWordForwardAtRange(range) + .apply() +} diff --git a/test/transforms/fixtures/at-range/delete-word-forward-at-range/start-of-word/input.yaml b/test/transforms/fixtures/at-range/delete-word-forward-at-range/start-of-word/input.yaml new file mode 100644 index 000000000..efc0975dd --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-forward-at-range/start-of-word/input.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "one two three" diff --git a/test/transforms/fixtures/at-range/delete-word-forward-at-range/start-of-word/output.yaml b/test/transforms/fixtures/at-range/delete-word-forward-at-range/start-of-word/output.yaml new file mode 100644 index 000000000..49e5f5477 --- /dev/null +++ b/test/transforms/fixtures/at-range/delete-word-forward-at-range/start-of-word/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: " two three"