diff --git a/docs/reference/models/transform.md b/docs/reference/models/transform.md index 49d8b4576..c650fb8cd 100644 --- a/docs/reference/models/transform.md +++ b/docs/reference/models/transform.md @@ -57,6 +57,8 @@ Transform methods can either operate on the [`Document`](./document.md), the [`S - [`setMarkByKey`](#setmarkbykey) - [`setNodeByKey`](#setnodebykey) - [`splitNodeByKey`](#splitnodebykey) + - [`unwrapInlineByKey`](#unwrapinlinebykey) + - [`unwrapBlockByKey`](#unwrapblockbykey) - [Document Transforms](#document-transforms) - [`deleteAtRange`](#deleteatrange) - [`deleteBackwardAtRange`](#deletebackwardatrange) @@ -317,6 +319,19 @@ Set a dictionary of `properties` on a [`Node`](./node.md) by its `key`. For conv Split a node by its `key` at an `offset`. +### `unwrapInlineByKey` +`unwrapInlineByKey(key: String, properties: Object) => Transform`
+`unwrapInlineByKey(key: String, type: String) => Transform` + +Unwrap all inner content of an [`Inline`](./inline.md) node that match `properties`. For convenience, you can pass a `type` string or `properties` object. + +### `unwrapBlockByKey` +`unwrapBlockByKey(key: String, properties: Object) => Transform`
+`unwrapBlockByKey(key: String, type: String) => Transform` + +Unwrap all inner content of a [`Block`](./block.md) node that match `properties`. For convenience, you can pass a `type` string or `properties` object. + +>>>>>>> slate/master ## Document Transforms ### `deleteBackwardAtRange` diff --git a/src/transforms/at-range.js b/src/transforms/at-range.js index 69ab12723..c09a792af 100644 --- a/src/transforms/at-range.js +++ b/src/transforms/at-range.js @@ -775,7 +775,7 @@ export function unwrapInlineAtRange(transform, range, properties, options = {}) const { normalize = true } = options const { state } = transform const { document } = state - const texts = document.getTexts() + const texts = document.getTextsAtRange(range) const inlines = texts .map((text) => { return document.getClosest(text, (parent) => { diff --git a/src/transforms/by-key.js b/src/transforms/by-key.js index dc27ca4da..0bfb45a01 100644 --- a/src/transforms/by-key.js +++ b/src/transforms/by-key.js @@ -323,3 +323,39 @@ export function splitNodeByKey(transform, key, offset, options = {}) { return transform } + +/** + * Unwrap content from an inline parent with `properties`. + * + * @param {Transform} transform + * @param {String} key + * @param {Object or String} properties + * @return {Transform} + */ + +export function unwrapInlineByKey(transform, key, properties) { + const { state } = transform + const { document, selection } = state + const node = document.assertDescendant(key) + const texts = node.getTexts() + const range = selection.moveToRangeOf(texts.first(), texts.last()) + return transform.unwrapInlineAtRange(range, properties) +} + +/** + * Unwrap content from a block parent with `properties`. + * + * @param {Transform} transform + * @param {String} key + * @param {Object or String} properties + * @return {Transform} + */ + +export function unwrapBlockByKey(transform, key, properties) { + const { state } = transform + const { document, selection } = state + const node = document.assertDescendant(key) + const texts = node.getTexts() + const range = selection.moveToRangeOf(texts.first(), texts.last()) + return transform.unwrapBlockAtRange(range, properties) +} diff --git a/src/transforms/index.js b/src/transforms/index.js index bc9ac26bc..5bb9d8b97 100644 --- a/src/transforms/index.js +++ b/src/transforms/index.js @@ -94,7 +94,8 @@ import { setMarkByKey, setNodeByKey, splitNodeByKey, - unwrapInlineByKey + unwrapInlineByKey, + unwrapBlockByKey, } from './by-key' /** @@ -250,6 +251,10 @@ export default { setNodeByKey, splitNodeByKey, unwrapInlineByKey, +<<<<<<< HEAD +======= + unwrapBlockByKey, +>>>>>>> slate/master /** * On selection. 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 0a24eb2b9..2a1231b72 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 @@ -5,11 +5,12 @@ export default function (state) { const { document, selection } = state const texts = document.getTexts() const first = texts.first() + const last = texts.get(1) const range = selection.merge({ anchorKey: first.key, anchorOffset: 1, - focusKey: first.key, - focusOffset: 3 + focusKey: last.key, + focusOffset: 2 }) const next = state 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 new file mode 100644 index 000000000..2dc5f582a --- /dev/null +++ b/test/transforms/fixtures/at-current-range/unwrap-inline/only-one/index.js @@ -0,0 +1,28 @@ + +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 range = selection.merge({ + anchorKey: first.key, + anchorOffset: 2, + focusKey: last.key, + focusOffset: 2 + }) + + const next = state + .transform() + .moveTo(range) + .unwrapInline('hashtag') + .apply() + + assert.deepEqual( + next.selection.toJS(), + range.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 new file mode 100644 index 000000000..d93ed90ad --- /dev/null +++ b/test/transforms/fixtures/at-current-range/unwrap-inline/only-one/input.yaml @@ -0,0 +1,21 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: he + - kind: inline + type: hashtag + nodes: + - kind: text + text: ll + - kind: text + text: "o w" + - kind: inline + type: hashtag + nodes: + - kind: text + text: or + - kind: text + text: d 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 new file mode 100644 index 000000000..80cea6855 --- /dev/null +++ b/test/transforms/fixtures/at-current-range/unwrap-inline/only-one/output.yaml @@ -0,0 +1,14 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: he + - kind: inline + type: hashtag + nodes: + - kind: text + text: ll + - kind: text + text: "o word" 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 0a24eb2b9..2a1231b72 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 @@ -5,11 +5,12 @@ export default function (state) { const { document, selection } = state const texts = document.getTexts() const first = texts.first() + const last = texts.get(1) const range = selection.merge({ anchorKey: first.key, anchorOffset: 1, - focusKey: first.key, - focusOffset: 3 + focusKey: last.key, + focusOffset: 2 }) const next = state diff --git a/test/transforms/fixtures/at-current-range/unwrap-inline/with-object/index.js b/test/transforms/fixtures/at-current-range/unwrap-inline/with-object/index.js index ac861d6cb..971d03375 100644 --- a/test/transforms/fixtures/at-current-range/unwrap-inline/with-object/index.js +++ b/test/transforms/fixtures/at-current-range/unwrap-inline/with-object/index.js @@ -5,11 +5,12 @@ export default function (state) { const { document, selection } = state const texts = document.getTexts() const first = texts.first() + const last = texts.get(1) const range = selection.merge({ anchorKey: first.key, anchorOffset: 1, - focusKey: first.key, - focusOffset: 3 + focusKey: last.key, + focusOffset: 2 }) const next = state diff --git a/test/transforms/fixtures/at-range/unwrap-inline-at-range/nested-block/index.js b/test/transforms/fixtures/at-range/unwrap-inline-at-range/nested-block/index.js index 8d03c6ce9..cdf642f9c 100644 --- a/test/transforms/fixtures/at-range/unwrap-inline-at-range/nested-block/index.js +++ b/test/transforms/fixtures/at-range/unwrap-inline-at-range/nested-block/index.js @@ -3,11 +3,12 @@ export default function (state) { const { document, selection } = state const texts = document.getTexts() const first = texts.first() + const last = texts.get(1) const range = selection.merge({ anchorKey: first.key, anchorOffset: 1, - focusKey: first.key, - focusOffset: 3 + focusKey: last.key, + focusOffset: 2 }) return state diff --git a/test/transforms/fixtures/at-range/unwrap-inline-at-range/single-block/index.js b/test/transforms/fixtures/at-range/unwrap-inline-at-range/single-block/index.js index 8d03c6ce9..cdf642f9c 100644 --- a/test/transforms/fixtures/at-range/unwrap-inline-at-range/single-block/index.js +++ b/test/transforms/fixtures/at-range/unwrap-inline-at-range/single-block/index.js @@ -3,11 +3,12 @@ export default function (state) { const { document, selection } = state const texts = document.getTexts() const first = texts.first() + const last = texts.get(1) const range = selection.merge({ anchorKey: first.key, anchorOffset: 1, - focusKey: first.key, - focusOffset: 3 + focusKey: last.key, + focusOffset: 2 }) return state diff --git a/test/transforms/fixtures/at-range/unwrap-inline-at-range/with-object/index.js b/test/transforms/fixtures/at-range/unwrap-inline-at-range/with-object/index.js index e18ed3821..4f3f594cc 100644 --- a/test/transforms/fixtures/at-range/unwrap-inline-at-range/with-object/index.js +++ b/test/transforms/fixtures/at-range/unwrap-inline-at-range/with-object/index.js @@ -3,11 +3,12 @@ export default function (state) { const { document, selection } = state const texts = document.getTexts() const first = texts.first() + const last = texts.get(1) const range = selection.merge({ anchorKey: first.key, anchorOffset: 1, - focusKey: first.key, - focusOffset: 3 + focusKey: last.key, + focusOffset: 2 }) return state diff --git a/test/transforms/fixtures/by-key/unwrap-block-by-key/single-block/index.js b/test/transforms/fixtures/by-key/unwrap-block-by-key/single-block/index.js new file mode 100644 index 000000000..57e84a62e --- /dev/null +++ b/test/transforms/fixtures/by-key/unwrap-block-by-key/single-block/index.js @@ -0,0 +1,10 @@ + +export default function (state) { + const { document, selection } = state + const block = document.nodes.get(0) + + return state + .transform() + .unwrapBlockByKey(block, 'quote') + .apply() +} diff --git a/test/transforms/fixtures/by-key/unwrap-block-by-key/single-block/input.yaml b/test/transforms/fixtures/by-key/unwrap-block-by-key/single-block/input.yaml new file mode 100644 index 000000000..ab4efb609 --- /dev/null +++ b/test/transforms/fixtures/by-key/unwrap-block-by-key/single-block/input.yaml @@ -0,0 +1,18 @@ + +nodes: + - kind: block + type: quote + nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: word + - kind: block + type: quote + nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: word diff --git a/test/transforms/fixtures/by-key/unwrap-block-by-key/single-block/output.yaml b/test/transforms/fixtures/by-key/unwrap-block-by-key/single-block/output.yaml new file mode 100644 index 000000000..c5a0f1a30 --- /dev/null +++ b/test/transforms/fixtures/by-key/unwrap-block-by-key/single-block/output.yaml @@ -0,0 +1,15 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: word + - kind: block + type: quote + nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: word diff --git a/test/transforms/fixtures/by-key/unwrap-inline-by-key/single-block/index.js b/test/transforms/fixtures/by-key/unwrap-inline-by-key/single-block/index.js new file mode 100644 index 000000000..150a8fcf8 --- /dev/null +++ b/test/transforms/fixtures/by-key/unwrap-inline-by-key/single-block/index.js @@ -0,0 +1,14 @@ + +import assert from 'assert' + +export default function (state) { + const { document, selection } = state + const inline = document.assertPath([0, 1]) + + const next = state + .transform() + .unwrapInlineByKey(inline.key, 'hashtag') + .apply() + + return next +} diff --git a/test/transforms/fixtures/by-key/unwrap-inline-by-key/single-block/input.yaml b/test/transforms/fixtures/by-key/unwrap-inline-by-key/single-block/input.yaml new file mode 100644 index 000000000..4a8715778 --- /dev/null +++ b/test/transforms/fixtures/by-key/unwrap-inline-by-key/single-block/input.yaml @@ -0,0 +1,19 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: w + - kind: inline + type: hashtag + nodes: + - kind: text + text: or + - kind: text + text: d + - kind: inline + type: hashtag + nodes: + - kind: text + text: another diff --git a/test/transforms/fixtures/by-key/unwrap-inline-by-key/single-block/output.yaml b/test/transforms/fixtures/by-key/unwrap-inline-by-key/single-block/output.yaml new file mode 100644 index 000000000..f5dba7769 --- /dev/null +++ b/test/transforms/fixtures/by-key/unwrap-inline-by-key/single-block/output.yaml @@ -0,0 +1,12 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + text: word + - kind: inline + type: hashtag + nodes: + - kind: text + text: another