From 8407023e5fe0b679cf798a32f0c4866638098c03 Mon Sep 17 00:00:00 2001 From: Mathieu Dutour Date: Mon, 25 Jul 2016 01:53:28 +0100 Subject: [PATCH] add setNodeByKey transform (#157) * modifyNode transform * create DOCUMENT_NODE_TRANSFORMS and use assertDescendant to get the node directly * rename to setNodeByKey --- docs/reference/models/transform.md | 7 +++++ lib/models/transform.js | 27 +++++++++++++++---- lib/models/transforms.js | 24 +++++++++++++++++ .../single-block-string-shorthand/index.js | 10 +++++++ .../single-block-string-shorthand/input.yaml | 8 ++++++ .../single-block-string-shorthand/output.yaml | 8 ++++++ .../modify-node/single-block/index.js | 10 +++++++ .../modify-node/single-block/input.yaml | 10 +++++++ .../modify-node/single-block/output.yaml | 10 +++++++ 9 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 test/transforms/fixtures/modify-node/single-block-string-shorthand/index.js create mode 100644 test/transforms/fixtures/modify-node/single-block-string-shorthand/input.yaml create mode 100644 test/transforms/fixtures/modify-node/single-block-string-shorthand/output.yaml create mode 100644 test/transforms/fixtures/modify-node/single-block/index.js create mode 100644 test/transforms/fixtures/modify-node/single-block/input.yaml create mode 100644 test/transforms/fixtures/modify-node/single-block/output.yaml diff --git a/docs/reference/models/transform.md b/docs/reference/models/transform.md index ecd6c1257..c7ab29a65 100644 --- a/docs/reference/models/transform.md +++ b/docs/reference/models/transform.md @@ -60,6 +60,7 @@ Transform methods can either operate on the [`Document`](./document.md), the [`S - [`unwrapInlineAtRange`](#unwrapinlineatrange) - [`wrapBlockAtRange`](#wrapblockatrange) - [`wrapInlineAtRange`](#wrapinlineatrange) + - [`setNodeByKey`](#setNodeByKey) - [History Transforms](#history-transforms) - [`redo`](#redo) - [`undo`](#undo) @@ -319,6 +320,12 @@ Wrap the [`Block`](./block.md) nodes in a `range` with a new [`Block`](./block.m Wrap the [`Inline`](./inline.md) nodes in a `range` with a new [`Inline`](./inline.md) node of `type`, with optional `data`. +### `setNodeByKey` +`setNodeByKey(key: String, properties: Object) => Transform` +`setNodeByKey(key: String, type: String) => Transform` + +Set the properties of the [`Node`](./node.md) having the specified `key`. + ## History Transforms diff --git a/lib/models/transform.js b/lib/models/transform.js index ae2072968..703a7cdb9 100644 --- a/lib/models/transform.js +++ b/lib/models/transform.js @@ -23,10 +23,10 @@ const Step = new Record({ }) /** - * Document transforms. + * Document range transforms. */ -const DOCUMENT_TRANSFORMS = [ +const DOCUMENT_RANGE_TRANSFORMS = [ 'deleteAtRange', 'deleteBackwardAtRange', 'deleteForwardAtRange', @@ -42,7 +42,15 @@ const DOCUMENT_TRANSFORMS = [ 'unwrapBlockAtRange', 'unwrapInlineAtRange', 'wrapBlockAtRange', - 'wrapInlineAtRange' + 'wrapInlineAtRange', +] + +/** + * Document node transforms. + */ + +const DOCUMENT_NODE_TRANSFORMS = [ + 'setNodeByKey', ] /** @@ -120,7 +128,8 @@ const STATE_TRANSFORMS = [] */ const TRANSFORMS = [] - .concat(DOCUMENT_TRANSFORMS) + .concat(DOCUMENT_RANGE_TRANSFORMS) + .concat(DOCUMENT_NODE_TRANSFORMS) .concat(SELECTION_TRANSFORMS) .concat(STATE_TRANSFORMS) @@ -209,7 +218,7 @@ class Transform extends new Record(DEFAULT_PROPERTIES) { applyStep(state, step) { const { type, args } = step - if (includes(DOCUMENT_TRANSFORMS, type)) { + if (includes(DOCUMENT_RANGE_TRANSFORMS, type)) { let { document, selection } = state let [ range, ...rest ] = args range = range.normalize(document) @@ -219,6 +228,14 @@ class Transform extends new Record(DEFAULT_PROPERTIES) { return state } + else if (includes(DOCUMENT_NODE_TRANSFORMS, type)) { + let { document, selection } = state + document = document[type](...args) + selection = selection.normalize(document) + state = state.merge({ document, selection }) + return state + } + else if (includes(SELECTION_TRANSFORMS, type)) { let { document, selection } = state selection = selection[type](...args) diff --git a/lib/models/transforms.js b/lib/models/transforms.js index 8f7deb4ef..195c5cf1c 100644 --- a/lib/models/transforms.js +++ b/lib/models/transforms.js @@ -899,6 +899,30 @@ const Transforms = { }) return node + }, + + /** + * Modify a block. + * + * @param {String} key + * @param {Object or String} properties + * @return {Node} node + */ + + setNodeByKey(key, properties) { + const node = this + + let newNode = node.assertDescendant(key) + + // Allow for properties to be a string `type` for convenience. + if (typeof properties == 'string') { + properties = { type: properties } + } + + if (properties.data) properties.data = Data.create(properties.data) + + newNode = newNode.merge(properties) + return node.mapDescendants(d => d.key == key ? newNode : d) } } diff --git a/test/transforms/fixtures/modify-node/single-block-string-shorthand/index.js b/test/transforms/fixtures/modify-node/single-block-string-shorthand/index.js new file mode 100644 index 000000000..971bb6cd6 --- /dev/null +++ b/test/transforms/fixtures/modify-node/single-block-string-shorthand/index.js @@ -0,0 +1,10 @@ + +export default function (state) { + const { document, selection } = state + const first = document.nodes.get(0) + + return state + .transform() + .setNodeByKey(first.key, 'code') + .apply() +} diff --git a/test/transforms/fixtures/modify-node/single-block-string-shorthand/input.yaml b/test/transforms/fixtures/modify-node/single-block-string-shorthand/input.yaml new file mode 100644 index 000000000..b1be31e90 --- /dev/null +++ b/test/transforms/fixtures/modify-node/single-block-string-shorthand/input.yaml @@ -0,0 +1,8 @@ + +nodes: + - kind: block + type: paragraph + nodes: + - kind: text + ranges: + - text: word diff --git a/test/transforms/fixtures/modify-node/single-block-string-shorthand/output.yaml b/test/transforms/fixtures/modify-node/single-block-string-shorthand/output.yaml new file mode 100644 index 000000000..e20ab29e7 --- /dev/null +++ b/test/transforms/fixtures/modify-node/single-block-string-shorthand/output.yaml @@ -0,0 +1,8 @@ + +nodes: + - kind: block + type: code + nodes: + - kind: text + ranges: + - text: word diff --git a/test/transforms/fixtures/modify-node/single-block/index.js b/test/transforms/fixtures/modify-node/single-block/index.js new file mode 100644 index 000000000..3b823a4ac --- /dev/null +++ b/test/transforms/fixtures/modify-node/single-block/index.js @@ -0,0 +1,10 @@ + +export default function (state) { + const { document, selection } = state + const first = document.nodes.get(0) + + return state + .transform() + .setNodeByKey(first.key, { data: {key: 'bar'} }) + .apply() +} diff --git a/test/transforms/fixtures/modify-node/single-block/input.yaml b/test/transforms/fixtures/modify-node/single-block/input.yaml new file mode 100644 index 000000000..17341a79a --- /dev/null +++ b/test/transforms/fixtures/modify-node/single-block/input.yaml @@ -0,0 +1,10 @@ + +nodes: + - kind: block + type: paragraph + data: + key: foo + nodes: + - kind: text + ranges: + - text: word diff --git a/test/transforms/fixtures/modify-node/single-block/output.yaml b/test/transforms/fixtures/modify-node/single-block/output.yaml new file mode 100644 index 000000000..35fe3b170 --- /dev/null +++ b/test/transforms/fixtures/modify-node/single-block/output.yaml @@ -0,0 +1,10 @@ + +nodes: + - kind: block + type: paragraph + data: + key: bar + nodes: + - kind: text + ranges: + - text: word