diff --git a/src/models/node.js b/src/models/node.js index cba45b4e7..21b653efd 100644 --- a/src/models/node.js +++ b/src/models/node.js @@ -975,38 +975,37 @@ const Node = { }, /** - * Join a node by `key` with another `withKey`. - * It brings Node after Node + * Join a children node `first` with another children node `second`. + * `first` and `second` will be concatenated in that order. + * `first` and `second` must be two Nodes or two Text. * - * @param {String} key - * @param {String} withKey + * @param {Node} first + * @param {Node} second * @return {Node} */ - joinNode(key, withKey) { + joinNode(first, second) { let node = this - let target = node.assertPath(key) - let withTarget = node.assertPath(withKey) - let parent = node.getParent(target) + let parent = node.getParent(second) const isParent = node == parent - const index = parent.nodes.indexOf(target) + const index = parent.nodes.indexOf(second) - if (target.kind == 'text') { - let { characters } = withTarget - characters = characters.concat(target.characters) - withTarget = withTarget.merge({ characters }) + if (second.kind == 'text') { + let { characters } = first + characters = characters.concat(second.characters) + first = first.merge({ characters }) } else { - const size = withTarget.nodes.size - target.nodes.forEach((child, i) => { - withTarget = withTarget.insertNode(size + i, child) + const size = first.nodes.size + second.nodes.forEach((child, i) => { + first = first.insertNode(size + i, child) }) } parent = parent.removeNode(index) node = isParent ? parent : node.updateDescendant(parent) - node = node.updateDescendant(withTarget) + node = node.updateDescendant(first) return node }, diff --git a/src/models/selection.js b/src/models/selection.js index d4608c8ec..38e2c9f4a 100644 --- a/src/models/selection.js +++ b/src/models/selection.js @@ -569,6 +569,58 @@ class Selection extends new Record(DEFAULTS) { }) } + /** + * Extend the start point forward `n` characters. + * + * @param {Number} n (optional) + * @return {Selection} selection + */ + + moveStartOffset(n = 1) { + return this.isBackward + ? this.merge({ focusOffset: this.focusOffset + n }) + : this.merge({ anchorOffset: this.anchorOffset + n }) + } + + /** + * Extend the end point forward `n` characters. + * + * @param {Number} n (optional) + * @return {Selection} selection + */ + + moveEndOffset(n = 1) { + return this.isBackward + ? this.merge({ anchorOffset: this.anchorOffset + n }) + : this.merge({ focusOffset: this.focusOffset + n }) + } + + /** + * Move the start key, while preserving the direction + * + * @param {String} key + * @return {Selection} selection + */ + + moveStartTo(key, offset = 0) { + return this.isBackward + ? this.merge({ focusKey: key, focusOffset: offset }) + : this.merge({ anchorKey: key, anchorOffset: offset }) + } + + /** + * Move the end key, while preserving the direction + * + * @param {String} key + * @return {Selection} selection + */ + + moveEndTo(key, offset = 0) { + return this.isBackward + ? this.merge({ anchorKey: key, anchorOffset: offset }) + : this.merge({ focusKey: key, focusOffset: offset }) + } + /** * Extend the focus point to the start of a `node`. * @@ -599,6 +651,23 @@ class Selection extends new Record(DEFAULTS) { }) } + /** + * Unset the selection + * + * @return {Selection} selection + */ + + unset() { + return this.merge({ + anchorKey: null, + anchorOffset: 0, + focusKey: null, + focusOffset: 0, + isFocused: false, + isBackward: false + }) + } + } /** diff --git a/src/transforms/apply-operation.js b/src/transforms/apply-operation.js index b91723d2f..11d8f5305 100644 --- a/src/transforms/apply-operation.js +++ b/src/transforms/apply-operation.js @@ -1,5 +1,6 @@ import Debug from 'debug' +import warning from '../utils/warning' /** * Debug. @@ -106,11 +107,23 @@ function insertNode(state, operation) { function insertText(state, operation) { const { path, offset, text, marks } = operation - let { document } = state + let { document, selection } = state + const { startKey, endKey, startOffset, endOffset } = selection let node = document.assertPath(path) + + // Update the document node = node.insertText(offset, text, marks) document = document.updateDescendant(node) - state = state.merge({ document }) + + // Update the selection + if (startKey == node.key && startOffset >= offset) { + selection = selection.moveStartOffset(text.length) + } + if (endKey == node.key && endOffset >= offset) { + selection = selection.moveEndOffset(text.length) + } + + state = state.merge({ document, selection }) return state } @@ -124,9 +137,33 @@ function insertText(state, operation) { function joinNode(state, operation) { const { path, withPath } = operation - let { document } = state - document = document.joinNode(path, withPath) - state = state.merge({ document }) + let { document, selection } = state + const first = document.assertPath(withPath) + const second = document.assertPath(path) + + // Update doc + document = document.joinNode(first, second) + + // Update selection + // When merging two texts together + if (second.kind == 'text') { + const { anchorKey, anchorOffset, focusKey, focusOffset } = selection + // The final key is the `first` key + if (anchorKey == second.key) { + selection = selection.merge({ + anchorKey: first.key, + anchorOffset: anchorOffset + first.characters.size + }) + } + if (focusKey == second.key) { + selection = selection.merge({ + focusKey: first.key, + focusOffset: focusOffset + first.characters.size + }) + } + } + + state = state.merge({ document, selection }) return state } @@ -143,12 +180,14 @@ function moveNode(state, operation) { let { document } = state const node = document.assertPath(path) + // Remove the node from its current parent let parent = document.getParent(node) const isParent = document == parent const index = parent.nodes.indexOf(node) parent = parent.removeNode(index) document = isParent ? parent : document.updateDescendant(parent) + // Insert the new node to its new parent let target = document.assertPath(newPath) const isTarget = document == target target = target.insertNode(newIndex, node) @@ -186,14 +225,55 @@ function removeMark(state, operation) { function removeNode(state, operation) { const { path } = operation - let { document } = state + let { document, selection } = state + const { startKey, endKey } = selection + + // Preserve previous document + const prevDocument = document + + // Update the document const node = document.assertPath(path) let parent = document.getParent(node) const index = parent.nodes.indexOf(node) const isParent = document == parent parent = parent.removeNode(index) document = isParent ? parent : document.updateDescendant(parent) - state = state.merge({ document }) + + function getRemoved(key) { + if (key === node.key) return node + if (node.kind == 'text') return null + return node.getDescendant(key) + } + + // Update the selection, if one of the anchor/focus has been removed + const startDesc = startKey ? getRemoved(startKey) : null + const endDesc = endKey ? getRemoved(endKey) : null + + if (startDesc) { + const prevText = prevDocument.getTexts() + .takeUntil(text => text.key == startKey) + .filter(text => !getRemoved(text.key)) + .last() + if (!prevText) selection = selection.unset() + else selection = selection.moveStartTo(prevText.key, prevText.length) + } + if (endDesc) { + // The whole selection is inside the node, we collapse to the previous text node + if (startKey == endKey) { + selection = selection.collapseToStart() + } else { + const nextText = prevDocument.getTexts() + .skipUntil(text => text.key == startKey) + .slice(1) + .filter(text => !getRemoved(text.key)) + .first() + + if (!nextText) selection = selection.unset() + else selection = selection.moveEndTo(nextText.key, 0) + } + } + + state = state.merge({ document, selection }) return state } @@ -207,11 +287,25 @@ function removeNode(state, operation) { function removeText(state, operation) { const { path, offset, length } = operation - let { document } = state + 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) - state = state.merge({ document }) + + // Update the selection + if (startKey == node.key && startOffset >= rangeOffset) { + selection = selection.moveStartOffset(-length) + } + if (endKey == node.key && endOffset >= rangeOffset) { + selection = selection.moveEndOffset(-length) + } + + state = state.merge({ document, selection }) return state } @@ -245,6 +339,16 @@ function setNode(state, operation) { const { path, properties } = operation let { document } = state let node = document.assertPath(path) + + // Deprecate using setNode for updating children, or keys + if (properties.nodes && properties.nodes != node.nodes) { + warning('Updating Node.nodes through setNode is not allowed. Use appropriate insertion and removal functions.') + delete properties.nodes + } else if (properties.key && properties.key != node.key) { + warning('Updating Node.key through setNode is not allowed. You should not have to update keys yourself.') + delete properties.key + } + node = node.merge(properties) document = document.updateDescendant(node) state = state.merge({ document }) @@ -293,10 +397,58 @@ function setSelection(state, operation) { function splitNode(state, operation) { const { path, offset } = operation - let { document } = state + const { document } = state - document = document.splitNode(path, offset) + // Update document + const newDocument = document.splitNode(path, offset) - state = state.merge({ document }) + // Update selection + let { selection } = state + const { anchorKey, anchorOffset, focusKey, focusOffset } = selection + + const node = document.assertPath(path) + // The text node that was split + const splittedText = node.kind == 'text' + ? node + : node.getTextAtOffset(offset) + const textOffset = node.kind == 'text' + ? offset + : offset - node.getOffset(splittedText) + + // Should we update the selection ? + const shouldUpdateAnchor = splittedText.key == anchorKey && textOffset <= anchorOffset + const shouldUpdateFocus = splittedText.key == focusKey && textOffset <= focusOffset + if (shouldUpdateFocus || shouldUpdateAnchor) { + // The node next to `node`, resulting from the split + const secondNode = newDocument.getNextSibling(node) + let secondText, newOffset + + if (shouldUpdateAnchor) { + newOffset = anchorOffset - textOffset + secondText = secondNode.kind == 'text' + ? secondNode + : secondNode.getTextAtOffset(newOffset) + selection = selection.merge({ + anchorKey: secondText.key, + anchorOffset: newOffset + }) + } + + if (shouldUpdateFocus) { + newOffset = focusOffset - textOffset + secondText = secondNode.kind == 'text' + ? secondNode + : secondNode.getTextAtOffset(newOffset) + selection = selection.merge({ + focusKey: secondText.key, + focusOffset: newOffset + }) + } + } + + state = state.merge({ + document: newDocument, + selection + }) return state } diff --git a/src/transforms/at-current-range.js b/src/transforms/at-current-range.js index 7780527e3..c028eff5a 100644 --- a/src/transforms/at-current-range.js +++ b/src/transforms/at-current-range.js @@ -95,70 +95,11 @@ export function _delete(transform) { export function deleteBackward(transform, n = 1) { const { state } = transform - const { document, selection } = state - let after - - const { startKey } = selection - const startNode = document.getDescendant(startKey) - - if (selection.isExpanded) { - after = selection.collapseToStart() - } - - else if (selection.isAtStartOf(document)) { - after = selection - } - - else if (selection.isAtStartOf(startNode)) { - 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) { - const prevPrev = document.getPreviousText(previous) - after = selection.collapseToEndOf(prevPrev) - } else { - after = selection.collapseToEndOf(previous) - } - } - - else if (selection.isAtEndOf(startNode) && startNode.length == 1) { - const block = document.getClosestBlock(startKey) - const highest = block.getHighestChild(startKey) - const previous = block.getPreviousSibling(highest) - const next = block.getNextSibling(highest) - - if (previous) { - if (previous.kind == 'text') { - if (next && next.kind == 'text') { - after = selection.merge({ - anchorKey: previous.key, - anchorOffset: previous.length, - focusKey: previous.key, - focusOffset: previous.length - }) - } else { - after = selection.collapseToEndOf(previous) - } - } else { - const last = previous.getTexts().last() - after = selection.collapseToEndOf(last) - } - } else { - after = selection.moveBackward(n) - } - } - - else { - after = selection.moveBackward(n) - } + const { selection } = state return transform - .unsetSelection() .deleteBackwardAtRange(selection, n) - .moveTo(after) + .collapseToEnd() } /** @@ -171,54 +112,10 @@ export function deleteBackward(transform, n = 1) { export function deleteForward(transform, n = 1) { const { state } = transform - const { document, selection, startText } = state - const { startKey, startOffset } = selection - let after - - const block = document.getClosestBlock(startKey) - const inline = document.getClosestInline(startKey) - const highest = block.getHighestChild(startKey) - const previous = block.getPreviousSibling(highest) - const next = block.getNextSibling(highest) - - if (selection.isExpanded) { - after = selection.collapseToStart() - } - - else if ((block && block.isVoid) || (inline && inline.isVoid)) { - const nextText = document.getNextText(startKey) - const prevText = document.getPreviousText(startKey) - after = next - ? selection.collapseToStartOf(nextText) - : selection.collapseToEndOf(prevText) - } - - else if (previous && startOffset == 0 && startText.length == 1) { - if (previous.kind == 'text') { - if (next && next.kind == 'text') { - after = selection.merge({ - anchorKey: previous.key, - anchorOffset: previous.length, - focusKey: previous.key, - focusOffset: previous.length - }) - } else { - after = selection.collapseToEndOf(previous) - } - } else { - const last = previous.getTexts().last() - after = selection.collapseToEndOf(last) - } - } - - else { - after = selection - } - + const { selection } = state return transform - .unsetSelection() .deleteForwardAtRange(selection, n) - .moveTo(after) + .collapseToEnd() } /** diff --git a/src/utils/warning.js b/src/utils/warning.js index db0f7bcd1..6c4c5bf7d 100644 --- a/src/utils/warning.js +++ b/src/utils/warning.js @@ -15,7 +15,7 @@ export default function warning(message) { } if (typeof console !== 'undefined') { - console.error('Warning: ', message) // eslint-disable-line no-console + console.error(`Warning: ${message}`) // eslint-disable-line no-console } try { diff --git a/test.js b/test.js index ef1faf612..4d46f3276 100644 --- a/test.js +++ b/test.js @@ -1,3 +1,5 @@ +/* eslint-disable no-console */ + import { Raw, Inline } from './src' function printNode(node, depth = 0) { @@ -29,28 +31,9 @@ const state = Raw.deserialize({ key: 'container', nodes: [ { - key: 'in1', - kind: 'inline', - type: 'link', - nodes: [ - { - key: 'sometext', - kind: 'text', - text: 'Hello' - }, - { - key: 'in2', - kind: 'inline', - type: 'image', - isVoid: true, - nodes: [ - { - kind: 'text', - text: ' ' - } - ] - } - ] + key: 'sometext', + kind: 'text', + text: 'Hello' } ] } @@ -60,7 +43,14 @@ const state = Raw.deserialize({ print(state) const newState = state.transform() - .moveNodeByKey('in2', 'container') + .moveTo({ + anchorKey: 'sometext', + focusKey: 'sometext', + anchorOffset: 3, + focusOffset: 3 + }) + .insertTextByKey('sometext', 1, 'X') .apply() +console.log(newState.selection.toJS()) print(newState) diff --git a/test/transforms/fixtures/at-current-range/unwrap-inline/across-blocks/index.js b/test/transforms/fixtures/at-current-range/unwrap-inline/across-blocks/index.js index 49c6255e8..fa7f133bb 100644 --- a/test/transforms/fixtures/at-current-range/unwrap-inline/across-blocks/index.js +++ b/test/transforms/fixtures/at-current-range/unwrap-inline/across-blocks/index.js @@ -2,14 +2,11 @@ import assert from 'assert' export default function (state) { - const { document, selection } = state - const texts = document.getTexts() - let first = texts.first() - const second = texts.last() + const { selection } = state const range = selection.merge({ - anchorKey: first.key, - anchorOffset: 2, - focusKey: second.key, + anchorKey: 'anchor', + anchorOffset: 1, + focusKey: 'focus', focusOffset: 2 }) @@ -19,15 +16,18 @@ export default function (state) { .unwrapInline('hashtag') .apply() - // Selection is reset, in theory it should me on the image - first = next.document.getTexts().first() + // Test selection + const { document } = next + const first = document.getTexts().first() + const last = document.getTexts().last() + assert.deepEqual( next.selection.toJS(), range.merge({ anchorKey: first.key, - anchorOffset: 0, - focusKey: first.key, - focusOffset: 0 + anchorOffset: 1, + focusKey: last.key, + focusOffset: 4 }).toJS() ) diff --git a/test/transforms/fixtures/at-current-range/unwrap-inline/across-blocks/input.yaml b/test/transforms/fixtures/at-current-range/unwrap-inline/across-blocks/input.yaml index 57d48f74f..efe76eccf 100644 --- a/test/transforms/fixtures/at-current-range/unwrap-inline/across-blocks/input.yaml +++ b/test/transforms/fixtures/at-current-range/unwrap-inline/across-blocks/input.yaml @@ -4,6 +4,7 @@ nodes: type: paragraph nodes: - kind: text + key: 'anchor' # w[o text: wo - kind: inline type: hashtag @@ -19,4 +20,5 @@ nodes: - kind: text text: an - kind: text + key: 'focus' # ot]her text: other diff --git a/test/transforms/fixtures/at-current-range/unwrap-inline/across-blocks/output.yaml b/test/transforms/fixtures/at-current-range/unwrap-inline/across-blocks/output.yaml index 881deb1d9..612d61ee1 100644 --- a/test/transforms/fixtures/at-current-range/unwrap-inline/across-blocks/output.yaml +++ b/test/transforms/fixtures/at-current-range/unwrap-inline/across-blocks/output.yaml @@ -10,3 +10,5 @@ nodes: nodes: - kind: text text: another +# Selection +# w[ordanot]her \ No newline at end of file diff --git a/test/transforms/fixtures/at-current-range/unwrap-inline/nested-block/index.js b/test/transforms/fixtures/at-current-range/unwrap-inline/nested-block/index.js index 80ede57bf..6b8cc9d94 100644 --- a/test/transforms/fixtures/at-current-range/unwrap-inline/nested-block/index.js +++ b/test/transforms/fixtures/at-current-range/unwrap-inline/nested-block/index.js @@ -2,14 +2,11 @@ import assert from 'assert' export default function (state) { - const { document, selection } = state - const texts = document.getTexts() - const first = texts.first() - const last = texts.get(1) + const { selection } = state const range = selection.merge({ - anchorKey: first.key, + anchorKey: 'anchor', anchorOffset: 1, - focusKey: last.key, + focusKey: 'focus', focusOffset: 2 }) @@ -21,7 +18,10 @@ export default function (state) { assert.deepEqual( next.selection.toJS(), - range.collapseToStartOf(next.document).toJS() + range.merge({ + focusKey: 'anchor', + focusOffset: 3 + }).toJS() ) return next diff --git a/test/transforms/fixtures/at-current-range/unwrap-inline/nested-block/input.yaml b/test/transforms/fixtures/at-current-range/unwrap-inline/nested-block/input.yaml index dda085eb1..bace31d67 100644 --- a/test/transforms/fixtures/at-current-range/unwrap-inline/nested-block/input.yaml +++ b/test/transforms/fixtures/at-current-range/unwrap-inline/nested-block/input.yaml @@ -7,11 +7,15 @@ nodes: type: paragraph nodes: - kind: text + key: 'anchor' text: w - kind: inline type: hashtag nodes: - kind: text + key: 'focus' text: or - kind: text text: d +# Selection +# w[or]d \ No newline at end of file diff --git a/test/transforms/fixtures/at-current-range/unwrap-inline/only-one/index.js b/test/transforms/fixtures/at-current-range/unwrap-inline/only-one/index.js index 2c11e5ddd..221ab5fed 100644 --- a/test/transforms/fixtures/at-current-range/unwrap-inline/only-one/index.js +++ b/test/transforms/fixtures/at-current-range/unwrap-inline/only-one/index.js @@ -2,14 +2,11 @@ import assert from 'assert' export default function (state) { - const { document, selection } = state - const texts = document.getTexts() - const first = texts.get(2) - const last = texts.get(3) + const { selection } = state const range = selection.merge({ - anchorKey: first.key, + anchorKey: 'anchor', anchorOffset: 2, - focusKey: last.key, + focusKey: 'focus', focusOffset: 2 }) @@ -21,7 +18,10 @@ export default function (state) { assert.deepEqual( next.selection.toJS(), - range.collapseToStartOf(next.document).toJS() + range.merge({ + focusKey: 'anchor', + focusOffset: 5 + }).toJS() ) return next diff --git a/test/transforms/fixtures/at-current-range/unwrap-inline/only-one/input.yaml b/test/transforms/fixtures/at-current-range/unwrap-inline/only-one/input.yaml index d93ed90ad..a21510e72 100644 --- a/test/transforms/fixtures/at-current-range/unwrap-inline/only-one/input.yaml +++ b/test/transforms/fixtures/at-current-range/unwrap-inline/only-one/input.yaml @@ -11,11 +11,16 @@ nodes: - kind: text text: ll - kind: text + key: 'anchor' text: "o w" - kind: inline type: hashtag nodes: - kind: text + key: 'focus' text: or - kind: text text: d + +# Selection +# hello [wor]d \ No newline at end of file diff --git a/test/transforms/fixtures/at-current-range/unwrap-inline/only-one/output.yaml b/test/transforms/fixtures/at-current-range/unwrap-inline/only-one/output.yaml index 80cea6855..046a57fc0 100644 --- a/test/transforms/fixtures/at-current-range/unwrap-inline/only-one/output.yaml +++ b/test/transforms/fixtures/at-current-range/unwrap-inline/only-one/output.yaml @@ -12,3 +12,5 @@ nodes: text: ll - kind: text text: "o word" +# Selection +# hello [wor]d \ No newline at end of file diff --git a/test/transforms/fixtures/at-current-range/unwrap-inline/single-block/index.js b/test/transforms/fixtures/at-current-range/unwrap-inline/single-block/index.js index 80ede57bf..6b8cc9d94 100644 --- a/test/transforms/fixtures/at-current-range/unwrap-inline/single-block/index.js +++ b/test/transforms/fixtures/at-current-range/unwrap-inline/single-block/index.js @@ -2,14 +2,11 @@ import assert from 'assert' export default function (state) { - const { document, selection } = state - const texts = document.getTexts() - const first = texts.first() - const last = texts.get(1) + const { selection } = state const range = selection.merge({ - anchorKey: first.key, + anchorKey: 'anchor', anchorOffset: 1, - focusKey: last.key, + focusKey: 'focus', focusOffset: 2 }) @@ -21,7 +18,10 @@ export default function (state) { assert.deepEqual( next.selection.toJS(), - range.collapseToStartOf(next.document).toJS() + range.merge({ + focusKey: 'anchor', + focusOffset: 3 + }).toJS() ) return next diff --git a/test/transforms/fixtures/at-current-range/unwrap-inline/single-block/input.yaml b/test/transforms/fixtures/at-current-range/unwrap-inline/single-block/input.yaml index 7bfbe8b4b..1e1a75bbb 100644 --- a/test/transforms/fixtures/at-current-range/unwrap-inline/single-block/input.yaml +++ b/test/transforms/fixtures/at-current-range/unwrap-inline/single-block/input.yaml @@ -4,11 +4,16 @@ nodes: type: paragraph nodes: - kind: text + key: 'anchor' text: w - kind: inline type: hashtag nodes: - kind: text + key: 'focus' text: or - kind: text text: d + +# selection: +# w[or]d \ No newline at end of file diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/end-text/index.js b/test/transforms/fixtures/by-key/insert-text-by-key/end-text/index.js new file mode 100644 index 000000000..b6f28ef3d --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/end-text/index.js @@ -0,0 +1,29 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const firstText = texts.first() + const secondText = texts.get(1) + + const nextSelection = selection.merge({ + anchorKey: firstText.key, + focusKey: firstText.key, + anchorOffset: 2, + focusOffset: 2 + }) + + const next = state + .transform() + .moveTo(nextSelection) + .insertTextByKey(secondText.key, 5, 'X') + .apply() + + assert.deepEqual( + next.selection.toJS(), + nextSelection.toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/end-text/input.yaml b/test/transforms/fixtures/by-key/insert-text-by-key/end-text/input.yaml new file mode 100644 index 000000000..dfc5d6974 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/end-text/input.yaml @@ -0,0 +1,12 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: outside + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/end-text/output.yaml b/test/transforms/fixtures/by-key/insert-text-by-key/end-text/output.yaml new file mode 100644 index 000000000..e032ceeff --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/end-text/output.yaml @@ -0,0 +1,12 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: outside + - kind: block + type: paragraph + nodes: + - kind: text + text: helloX diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/middle-text-with-marks/index.js b/test/transforms/fixtures/by-key/insert-text-by-key/middle-text-with-marks/index.js new file mode 100644 index 000000000..b91900902 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/middle-text-with-marks/index.js @@ -0,0 +1,29 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const firstText = texts.first() + const secondText = texts.get(1) + + const nextSelection = selection.merge({ + anchorKey: firstText.key, + focusKey: firstText.key, + anchorOffset: 2, + focusOffset: 2 + }) + + const next = state + .transform() + .moveTo(nextSelection) + .insertTextByKey(secondText.key, 2, 'XX', [ { type: 'bold' } ]) + .apply() + + assert.deepEqual( + next.selection.toJS(), + nextSelection.toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/middle-text-with-marks/input.yaml b/test/transforms/fixtures/by-key/insert-text-by-key/middle-text-with-marks/input.yaml new file mode 100644 index 000000000..dfc5d6974 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/middle-text-with-marks/input.yaml @@ -0,0 +1,12 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: outside + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/middle-text-with-marks/output.yaml b/test/transforms/fixtures/by-key/insert-text-by-key/middle-text-with-marks/output.yaml new file mode 100644 index 000000000..0a9a59915 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/middle-text-with-marks/output.yaml @@ -0,0 +1,17 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: outside + - kind: block + type: paragraph + nodes: + - kind: text + ranges: + - text: he + - text: XX + marks: + - type: bold + - text: llo diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/middle-text/index.js b/test/transforms/fixtures/by-key/insert-text-by-key/middle-text/index.js new file mode 100644 index 000000000..4c7584c43 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/middle-text/index.js @@ -0,0 +1,29 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const firstText = texts.first() + const secondText = texts.get(1) + + const nextSelection = selection.merge({ + anchorKey: firstText.key, + focusKey: firstText.key, + anchorOffset: 2, + focusOffset: 2 + }) + + const next = state + .transform() + .moveTo(nextSelection) + .insertTextByKey(secondText.key, 2, 'X') + .apply() + + assert.deepEqual( + next.selection.toJS(), + nextSelection.toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/middle-text/input.yaml b/test/transforms/fixtures/by-key/insert-text-by-key/middle-text/input.yaml new file mode 100644 index 000000000..dfc5d6974 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/middle-text/input.yaml @@ -0,0 +1,12 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: outside + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/middle-text/output.yaml b/test/transforms/fixtures/by-key/insert-text-by-key/middle-text/output.yaml new file mode 100644 index 000000000..fb7679358 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/middle-text/output.yaml @@ -0,0 +1,12 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: outside + - kind: block + type: paragraph + nodes: + - kind: text + text: heXllo diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/selection-after/index.js b/test/transforms/fixtures/by-key/insert-text-by-key/selection-after/index.js new file mode 100644 index 000000000..bbd33aa5a --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/selection-after/index.js @@ -0,0 +1,31 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const firstText = texts.first() + + const nextSelection = selection.merge({ + anchorKey: firstText.key, + focusKey: firstText.key, + anchorOffset: 2, + focusOffset: 2 + }) + + const next = state + .transform() + .moveTo(nextSelection) + .insertTextByKey(firstText.key, 0, 'XX') + .apply() + + assert.deepEqual( + next.selection.toJS(), + nextSelection.merge({ + anchorOffset: 4, + focusOffset: 4 + }).toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/selection-after/input.yaml b/test/transforms/fixtures/by-key/insert-text-by-key/selection-after/input.yaml new file mode 100644 index 000000000..98adb1781 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/selection-after/input.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/selection-after/output.yaml b/test/transforms/fixtures/by-key/insert-text-by-key/selection-after/output.yaml new file mode 100644 index 000000000..02b635283 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/selection-after/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: XXhello diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/selection-before/index.js b/test/transforms/fixtures/by-key/insert-text-by-key/selection-before/index.js new file mode 100644 index 000000000..2129b7c09 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/selection-before/index.js @@ -0,0 +1,28 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const firstText = texts.first() + + const nextSelection = selection.merge({ + anchorKey: firstText.key, + focusKey: firstText.key, + anchorOffset: 2, + focusOffset: 2 + }) + + const next = state + .transform() + .moveTo(nextSelection) + .insertTextByKey(firstText.key, 5, 'XX') + .apply() + + assert.deepEqual( + next.selection.toJS(), + nextSelection.toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/selection-before/input.yaml b/test/transforms/fixtures/by-key/insert-text-by-key/selection-before/input.yaml new file mode 100644 index 000000000..98adb1781 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/selection-before/input.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/selection-before/output.yaml b/test/transforms/fixtures/by-key/insert-text-by-key/selection-before/output.yaml new file mode 100644 index 000000000..c3dba6a90 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/selection-before/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: helloXX diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/selection-end/index.js b/test/transforms/fixtures/by-key/insert-text-by-key/selection-end/index.js new file mode 100644 index 000000000..18dd57cc2 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/selection-end/index.js @@ -0,0 +1,30 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const firstText = texts.first() + + const nextSelection = selection.merge({ + anchorKey: firstText.key, + focusKey: firstText.key, + anchorOffset: 2, + focusOffset: 4 + }) + + const next = state + .transform() + .moveTo(nextSelection) + .insertTextByKey(firstText.key, 4, 'XX') + .apply() + + assert.deepEqual( + next.selection.toJS(), + nextSelection.merge({ + focusOffset: 6 + }).toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/selection-end/input.yaml b/test/transforms/fixtures/by-key/insert-text-by-key/selection-end/input.yaml new file mode 100644 index 000000000..98adb1781 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/selection-end/input.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/selection-end/output.yaml b/test/transforms/fixtures/by-key/insert-text-by-key/selection-end/output.yaml new file mode 100644 index 000000000..607d42d0c --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/selection-end/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: hellXXo diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/selection-start/index.js b/test/transforms/fixtures/by-key/insert-text-by-key/selection-start/index.js new file mode 100644 index 000000000..8391fa7c6 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/selection-start/index.js @@ -0,0 +1,31 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const firstText = texts.first() + + const nextSelection = selection.merge({ + anchorKey: firstText.key, + focusKey: firstText.key, + anchorOffset: 2, + focusOffset: 4 + }) + + const next = state + .transform() + .moveTo(nextSelection) + .insertTextByKey(firstText.key, 2, 'XX') + .apply() + + assert.deepEqual( + next.selection.toJS(), + nextSelection.merge({ + anchorOffset: 4, + focusOffset: 6 + }).toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/selection-start/input.yaml b/test/transforms/fixtures/by-key/insert-text-by-key/selection-start/input.yaml new file mode 100644 index 000000000..98adb1781 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/selection-start/input.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/selection-start/output.yaml b/test/transforms/fixtures/by-key/insert-text-by-key/selection-start/output.yaml new file mode 100644 index 000000000..5395838b8 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/selection-start/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: heXXllo diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/selection-wrap/index.js b/test/transforms/fixtures/by-key/insert-text-by-key/selection-wrap/index.js new file mode 100644 index 000000000..a84f3a281 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/selection-wrap/index.js @@ -0,0 +1,31 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const firstText = texts.first() + + const nextSelection = selection.merge({ + anchorKey: firstText.key, + focusKey: firstText.key, + anchorOffset: 2, + focusOffset: 4 + }) + + const next = state + .transform() + .moveTo(nextSelection) + .insertTextByKey(firstText.key, 3, 'XX') + .apply() + + assert.deepEqual( + next.selection.toJS(), + nextSelection.merge({ + anchorOffset: 2, + focusOffset: 6 + }).toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/selection-wrap/input.yaml b/test/transforms/fixtures/by-key/insert-text-by-key/selection-wrap/input.yaml new file mode 100644 index 000000000..98adb1781 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/selection-wrap/input.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/selection-wrap/output.yaml b/test/transforms/fixtures/by-key/insert-text-by-key/selection-wrap/output.yaml new file mode 100644 index 000000000..25eed75eb --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/selection-wrap/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: helXXlo diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/start-text/index.js b/test/transforms/fixtures/by-key/insert-text-by-key/start-text/index.js new file mode 100644 index 000000000..a7a26f928 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/start-text/index.js @@ -0,0 +1,29 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const firstText = texts.first() + const secondText = texts.get(1) + + const nextSelection = selection.merge({ + anchorKey: firstText.key, + focusKey: firstText.key, + anchorOffset: 2, + focusOffset: 2 + }) + + const next = state + .transform() + .moveTo(nextSelection) + .insertTextByKey(secondText.key, 0, 'X') + .apply() + + assert.deepEqual( + next.selection.toJS(), + nextSelection.toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/start-text/input.yaml b/test/transforms/fixtures/by-key/insert-text-by-key/start-text/input.yaml new file mode 100644 index 000000000..dfc5d6974 --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/start-text/input.yaml @@ -0,0 +1,12 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: outside + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/insert-text-by-key/start-text/output.yaml b/test/transforms/fixtures/by-key/insert-text-by-key/start-text/output.yaml new file mode 100644 index 000000000..44942732a --- /dev/null +++ b/test/transforms/fixtures/by-key/insert-text-by-key/start-text/output.yaml @@ -0,0 +1,12 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: outside + - kind: block + type: paragraph + nodes: + - kind: text + text: Xhello diff --git a/test/transforms/fixtures/by-key/join-node-by-key/block/index.js b/test/transforms/fixtures/by-key/join-node-by-key/block/index.js new file mode 100644 index 000000000..f991fd9c7 --- /dev/null +++ b/test/transforms/fixtures/by-key/join-node-by-key/block/index.js @@ -0,0 +1,29 @@ + +import assert from 'assert' + +export default function (state) { + const { selection } = state + + const range = selection.merge({ + anchorKey: 'anchor', + anchorOffset: 1, + focusKey: 'focus', + focusOffset: 2 + }) + + const next = state + .transform() + .moveTo(range) + .joinNodeByKey('key2', 'key1') + .apply() + + assert.deepEqual( + next.selection.toJS(), + range.merge({ + focusKey: 'anchor', + focusOffset: 5 + }).toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/join-node-by-key/block/input.yaml b/test/transforms/fixtures/by-key/join-node-by-key/block/input.yaml new file mode 100644 index 000000000..66df88e7a --- /dev/null +++ b/test/transforms/fixtures/by-key/join-node-by-key/block/input.yaml @@ -0,0 +1,16 @@ + +nodes: + - kind: block + key: 'key1' + type: paragraph + nodes: + - kind: text + key: 'anchor' + text: The + - kind: block + key: 'key2' + type: paragraph + nodes: + - kind: text + key: 'focus' + text: text diff --git a/test/transforms/fixtures/by-key/join-node-by-key/block/output.yaml b/test/transforms/fixtures/by-key/join-node-by-key/block/output.yaml new file mode 100644 index 000000000..f965e4ab2 --- /dev/null +++ b/test/transforms/fixtures/by-key/join-node-by-key/block/output.yaml @@ -0,0 +1,8 @@ + +nodes: + - kind: block + key: key1 + type: paragraph + nodes: + - kind: text + text: Thetext diff --git a/test/transforms/fixtures/by-key/join-node-by-key/text/index.js b/test/transforms/fixtures/by-key/join-node-by-key/text/index.js new file mode 100644 index 000000000..797f72907 --- /dev/null +++ b/test/transforms/fixtures/by-key/join-node-by-key/text/index.js @@ -0,0 +1,29 @@ + +import assert from 'assert' + +export default function (state) { + const { selection } = state + + const range = selection.merge({ + anchorKey: 'anchor', + anchorOffset: 1, + focusKey: 'focus', + focusOffset: 2 + }) + + const next = state + .transform() + .moveTo(range) + .joinNodeByKey('focus', 'anchor') + .apply() + + assert.deepEqual( + next.selection.toJS(), + range.merge({ + focusKey: 'anchor', + focusOffset: 5 + }).toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/join-node-by-key/text/input.yaml b/test/transforms/fixtures/by-key/join-node-by-key/text/input.yaml new file mode 100644 index 000000000..1d54b7ee6 --- /dev/null +++ b/test/transforms/fixtures/by-key/join-node-by-key/text/input.yaml @@ -0,0 +1,16 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + key: 'anchor' + text: one + - kind: inline + type: link + nodes: + - kind: text + text: two + - kind: text + key: 'focus' + text: three diff --git a/test/transforms/fixtures/by-key/join-node-by-key/text/output.yaml b/test/transforms/fixtures/by-key/join-node-by-key/text/output.yaml new file mode 100644 index 000000000..434082dfa --- /dev/null +++ b/test/transforms/fixtures/by-key/join-node-by-key/text/output.yaml @@ -0,0 +1,13 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + key: 'anchor' + text: onethree + - kind: inline + type: link + nodes: + - kind: text + text: two diff --git a/test/transforms/fixtures/by-key/remove-node-by-key/block/index.js b/test/transforms/fixtures/by-key/remove-node-by-key/block/index.js new file mode 100644 index 000000000..c3cb4b8f1 --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-node-by-key/block/index.js @@ -0,0 +1,28 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const secondText = texts.get(1) + + const nextSelection = selection.merge({ + anchorKey: secondText.key, + focusKey: secondText.key, + anchorOffset: 0, + focusOffset: 0 + }) + + const next = state + .transform() + .moveTo(nextSelection) + .removeNodeByKey('todelete') + .apply() + + assert.deepEqual( + next.selection.toJS(), + nextSelection.toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/remove-node-by-key/block/input.yaml b/test/transforms/fixtures/by-key/remove-node-by-key/block/input.yaml new file mode 100644 index 000000000..aa812a33f --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-node-by-key/block/input.yaml @@ -0,0 +1,13 @@ + +nodes: + - kind: block + key: todelete + type: paragraph + nodes: + - kind: text + text: removed + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/remove-node-by-key/block/output.yaml b/test/transforms/fixtures/by-key/remove-node-by-key/block/output.yaml new file mode 100644 index 000000000..98adb1781 --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-node-by-key/block/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/remove-node-by-key/inline/index.js b/test/transforms/fixtures/by-key/remove-node-by-key/inline/index.js new file mode 100644 index 000000000..c3cb4b8f1 --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-node-by-key/inline/index.js @@ -0,0 +1,28 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const secondText = texts.get(1) + + const nextSelection = selection.merge({ + anchorKey: secondText.key, + focusKey: secondText.key, + anchorOffset: 0, + focusOffset: 0 + }) + + const next = state + .transform() + .moveTo(nextSelection) + .removeNodeByKey('todelete') + .apply() + + assert.deepEqual( + next.selection.toJS(), + nextSelection.toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/remove-node-by-key/inline/input.yaml b/test/transforms/fixtures/by-key/remove-node-by-key/inline/input.yaml new file mode 100644 index 000000000..cd7017235 --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-node-by-key/inline/input.yaml @@ -0,0 +1,16 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: inline + type: link + key: todelete + nodes: + - kind: text + text: removed + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/remove-node-by-key/inline/output.yaml b/test/transforms/fixtures/by-key/remove-node-by-key/inline/output.yaml new file mode 100644 index 000000000..566468356 --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-node-by-key/inline/output.yaml @@ -0,0 +1,12 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "" + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/remove-node-by-key/selection-inside/index.js b/test/transforms/fixtures/by-key/remove-node-by-key/selection-inside/index.js new file mode 100644 index 000000000..8405cc39d --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-node-by-key/selection-inside/index.js @@ -0,0 +1,34 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const firstText = texts.first() + const secondText = texts.get(1) + + const nextSelection = selection.merge({ + anchorKey: secondText.key, + focusKey: secondText.key, + anchorOffset: 2, + focusOffset: 2 + }) + + const next = state + .transform() + .moveTo(nextSelection) + .removeNodeByKey('todelete') + .apply() + + assert.deepEqual( + next.selection.toJS(), + nextSelection.merge({ + anchorKey: firstText.key, + focusKey: firstText.key, + anchorOffset: 5, + focusOffset: 5 + }).toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/remove-node-by-key/selection-inside/input.yaml b/test/transforms/fixtures/by-key/remove-node-by-key/selection-inside/input.yaml new file mode 100644 index 000000000..494fcb20c --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-node-by-key/selection-inside/input.yaml @@ -0,0 +1,13 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: hello + - kind: block + key: todelete + type: paragraph + nodes: + - kind: text + text: removed diff --git a/test/transforms/fixtures/by-key/remove-node-by-key/selection-inside/output.yaml b/test/transforms/fixtures/by-key/remove-node-by-key/selection-inside/output.yaml new file mode 100644 index 000000000..98adb1781 --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-node-by-key/selection-inside/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/remove-node-by-key/text/index.js b/test/transforms/fixtures/by-key/remove-node-by-key/text/index.js new file mode 100644 index 000000000..c3cb4b8f1 --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-node-by-key/text/index.js @@ -0,0 +1,28 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const secondText = texts.get(1) + + const nextSelection = selection.merge({ + anchorKey: secondText.key, + focusKey: secondText.key, + anchorOffset: 0, + focusOffset: 0 + }) + + const next = state + .transform() + .moveTo(nextSelection) + .removeNodeByKey('todelete') + .apply() + + assert.deepEqual( + next.selection.toJS(), + nextSelection.toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/remove-node-by-key/text/input.yaml b/test/transforms/fixtures/by-key/remove-node-by-key/text/input.yaml new file mode 100644 index 000000000..5a45e00ea --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-node-by-key/text/input.yaml @@ -0,0 +1,13 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + key: todelete + text: removed + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/remove-node-by-key/text/output.yaml b/test/transforms/fixtures/by-key/remove-node-by-key/text/output.yaml new file mode 100644 index 000000000..566468356 --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-node-by-key/text/output.yaml @@ -0,0 +1,12 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: "" + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/remove-text-by-key/selection-after/index.js b/test/transforms/fixtures/by-key/remove-text-by-key/selection-after/index.js new file mode 100644 index 000000000..996827711 --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-text-by-key/selection-after/index.js @@ -0,0 +1,31 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const firstText = texts.first() + + const nextSelection = selection.merge({ + anchorKey: firstText.key, + focusKey: firstText.key, + anchorOffset: 2, + focusOffset: 2 + }) + + const next = state + .transform() + .moveTo(nextSelection) + .removeTextByKey(firstText.key, 0, 1) + .apply() + + assert.deepEqual( + next.selection.toJS(), + nextSelection.merge({ + anchorOffset: 1, + focusOffset: 1 + }).toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/remove-text-by-key/selection-after/input.yaml b/test/transforms/fixtures/by-key/remove-text-by-key/selection-after/input.yaml new file mode 100644 index 000000000..98adb1781 --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-text-by-key/selection-after/input.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/remove-text-by-key/selection-after/output.yaml b/test/transforms/fixtures/by-key/remove-text-by-key/selection-after/output.yaml new file mode 100644 index 000000000..d82d81f13 --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-text-by-key/selection-after/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: ello diff --git a/test/transforms/fixtures/by-key/remove-text-by-key/selection-before/index.js b/test/transforms/fixtures/by-key/remove-text-by-key/selection-before/index.js new file mode 100644 index 000000000..beeddb3a7 --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-text-by-key/selection-before/index.js @@ -0,0 +1,31 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const firstText = texts.first() + + const nextSelection = selection.merge({ + anchorKey: firstText.key, + focusKey: firstText.key, + anchorOffset: 2, + focusOffset: 2 + }) + + const next = state + .transform() + .moveTo(nextSelection) + .removeTextByKey(firstText.key, 3, 1) + .apply() + + assert.deepEqual( + next.selection.toJS(), + nextSelection.merge({ + anchorOffset: 2, + focusOffset: 2 + }).toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/remove-text-by-key/selection-before/input.yaml b/test/transforms/fixtures/by-key/remove-text-by-key/selection-before/input.yaml new file mode 100644 index 000000000..98adb1781 --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-text-by-key/selection-before/input.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/remove-text-by-key/selection-before/output.yaml b/test/transforms/fixtures/by-key/remove-text-by-key/selection-before/output.yaml new file mode 100644 index 000000000..bac33813a --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-text-by-key/selection-before/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: helo diff --git a/test/transforms/fixtures/by-key/remove-text-by-key/selection-start/index.js b/test/transforms/fixtures/by-key/remove-text-by-key/selection-start/index.js new file mode 100644 index 000000000..aa51524ee --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-text-by-key/selection-start/index.js @@ -0,0 +1,31 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const firstText = texts.first() + + const nextSelection = selection.merge({ + anchorKey: firstText.key, + focusKey: firstText.key, + anchorOffset: 3, + focusOffset: 3 + }) + + const next = state + .transform() + .moveTo(nextSelection) + .removeTextByKey(firstText.key, 2, 1) + .apply() + + assert.deepEqual( + next.selection.toJS(), + nextSelection.merge({ + anchorOffset: 2, + focusOffset: 2 + }).toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/remove-text-by-key/selection-start/input.yaml b/test/transforms/fixtures/by-key/remove-text-by-key/selection-start/input.yaml new file mode 100644 index 000000000..98adb1781 --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-text-by-key/selection-start/input.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/remove-text-by-key/selection-start/output.yaml b/test/transforms/fixtures/by-key/remove-text-by-key/selection-start/output.yaml new file mode 100644 index 000000000..bac33813a --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-text-by-key/selection-start/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: helo diff --git a/test/transforms/fixtures/by-key/remove-text-by-key/selection-wrap/index.js b/test/transforms/fixtures/by-key/remove-text-by-key/selection-wrap/index.js new file mode 100644 index 000000000..29398de14 --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-text-by-key/selection-wrap/index.js @@ -0,0 +1,31 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const texts = document.getTexts() + const firstText = texts.first() + + const nextSelection = selection.merge({ + anchorKey: firstText.key, + focusKey: firstText.key, + anchorOffset: 1, + focusOffset: 5 + }) + + const next = state + .transform() + .moveTo(nextSelection) + .removeTextByKey(firstText.key, 2, 1) + .apply() + + assert.deepEqual( + next.selection.toJS(), + nextSelection.merge({ + anchorOffset: 1, + focusOffset: 4 + }).toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/remove-text-by-key/selection-wrap/input.yaml b/test/transforms/fixtures/by-key/remove-text-by-key/selection-wrap/input.yaml new file mode 100644 index 000000000..98adb1781 --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-text-by-key/selection-wrap/input.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: hello diff --git a/test/transforms/fixtures/by-key/remove-text-by-key/selection-wrap/output.yaml b/test/transforms/fixtures/by-key/remove-text-by-key/selection-wrap/output.yaml new file mode 100644 index 000000000..bac33813a --- /dev/null +++ b/test/transforms/fixtures/by-key/remove-text-by-key/selection-wrap/output.yaml @@ -0,0 +1,7 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: helo diff --git a/test/transforms/fixtures/by-key/split-node-by-key/block/index.js b/test/transforms/fixtures/by-key/split-node-by-key/block/index.js new file mode 100644 index 000000000..fc5a6a69f --- /dev/null +++ b/test/transforms/fixtures/by-key/split-node-by-key/block/index.js @@ -0,0 +1,32 @@ + +import assert from 'assert' + +export default function (state) { + const { selection } = state + + const range = selection.merge({ + anchorKey: 'anchor', + anchorOffset: 2, + focusKey: 'anchor', + focusOffset: 5 + }) + + const next = state + .transform() + .moveTo(range) + .splitNodeByKey('key', 3) + .apply() + + + const second = next.document.getTexts().last() + + assert.deepEqual( + next.selection.toJS(), + range.merge({ + focusKey: second.key, + focusOffset: 2 + }).toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/split-node-by-key/block/input.yaml b/test/transforms/fixtures/by-key/split-node-by-key/block/input.yaml new file mode 100644 index 000000000..564fe1a8f --- /dev/null +++ b/test/transforms/fixtures/by-key/split-node-by-key/block/input.yaml @@ -0,0 +1,11 @@ + +nodes: + - kind: block + key: 'key' + type: paragraph + nodes: + - kind: text + key: 'anchor' + text: Thetext +# Selection +# Th[ete]xt \ No newline at end of file diff --git a/test/transforms/fixtures/by-key/split-node-by-key/block/output.yaml b/test/transforms/fixtures/by-key/split-node-by-key/block/output.yaml new file mode 100644 index 000000000..763d9da44 --- /dev/null +++ b/test/transforms/fixtures/by-key/split-node-by-key/block/output.yaml @@ -0,0 +1,12 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: The + - kind: block + type: paragraph + nodes: + - kind: text + text: text diff --git a/test/transforms/fixtures/by-key/split-node-by-key/text/index.js b/test/transforms/fixtures/by-key/split-node-by-key/text/index.js new file mode 100644 index 000000000..1b2865e2d --- /dev/null +++ b/test/transforms/fixtures/by-key/split-node-by-key/text/index.js @@ -0,0 +1,34 @@ + +import assert from 'assert' + +export default function (state) { + const { selection } = state + + const range = selection.merge({ + anchorKey: 'anchor', + anchorOffset: 4, + focusKey: 'anchor', + focusOffset: 5 + }) + + const next = state + .transform() + .moveTo(range) + .splitNodeByKey('anchor', 3, { normalize: false }) + .apply() + + // The second text + const second = next.document.getTexts().last() + + assert.deepEqual( + next.selection.toJS(), + range.merge({ + anchorKey: second.key, + anchorOffset: 1, + focusKey: second.key, + focusOffset: 2 + }).toJS() + ) + + return next +} diff --git a/test/transforms/fixtures/by-key/split-node-by-key/text/input.yaml b/test/transforms/fixtures/by-key/split-node-by-key/text/input.yaml new file mode 100644 index 000000000..33b7acde9 --- /dev/null +++ b/test/transforms/fixtures/by-key/split-node-by-key/text/input.yaml @@ -0,0 +1,10 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + key: 'anchor' + text: onetwo +# Selection +# onet[w]o \ No newline at end of file diff --git a/test/transforms/fixtures/by-key/split-node-by-key/text/output.yaml b/test/transforms/fixtures/by-key/split-node-by-key/text/output.yaml new file mode 100644 index 000000000..91ceb3594 --- /dev/null +++ b/test/transforms/fixtures/by-key/split-node-by-key/text/output.yaml @@ -0,0 +1,10 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + key: 'anchor' + text: one + - kind: text + text: two