diff --git a/.changeset/spotty-squids-walk.md b/.changeset/spotty-squids-walk.md new file mode 100644 index 000000000..43a7a142e --- /dev/null +++ b/.changeset/spotty-squids-walk.md @@ -0,0 +1,5 @@ +--- +'slate': minor +--- + +Don't set `null` in `set_node`'s `newProperties` object when using `Transforms.unsetNodes()` diff --git a/packages/slate/src/transforms/node.ts b/packages/slate/src/transforms/node.ts index e90412b32..caa863170 100644 --- a/packages/slate/src/transforms/node.ts +++ b/packages/slate/src/transforms/node.ts @@ -632,19 +632,23 @@ export const NodeTransforms: NodeTransforms = { continue } + let hasChanges = false + for (const k in props) { if (k === 'children' || k === 'text') { continue } if (props[k] !== node[k]) { - // Omit new properties from the old property list rather than set them to undefined + hasChanges = true + // Omit new properties from the old properties list if (node.hasOwnProperty(k)) properties[k] = node[k] - newProperties[k] = props[k] + // Omit properties that have been removed from the new properties list + if (props[k] != null) newProperties[k] = props[k] } } - if (Object.keys(newProperties).length !== 0) { + if (hasChanges) { editor.apply({ type: 'set_node', path, diff --git a/packages/slate/test/operations/set_node/remove-null.tsx b/packages/slate/test/operations/set_node/remove-null.tsx index 918d65809..b50357575 100644 --- a/packages/slate/test/operations/set_node/remove-null.tsx +++ b/packages/slate/test/operations/set_node/remove-null.tsx @@ -10,6 +10,7 @@ export const input = ( ) +// this is supported for backwards compatibility only; newProperties should omit removed values. export const operations = [ { type: 'set_node', diff --git a/packages/slate/test/operations/set_node/remove-undefined.tsx b/packages/slate/test/operations/set_node/remove-undefined.tsx index 0c8cc7d96..826e03278 100644 --- a/packages/slate/test/operations/set_node/remove-undefined.tsx +++ b/packages/slate/test/operations/set_node/remove-undefined.tsx @@ -10,6 +10,7 @@ export const input = ( ) +// this is supported for backwards compatibility only; newProperties should omit removed values. export const operations = [ { type: 'set_node', diff --git a/packages/slate/test/transforms/unsetNodes/operation-contents-check.tsx b/packages/slate/test/transforms/unsetNodes/operation-contents-check.tsx new file mode 100644 index 000000000..321a651b2 --- /dev/null +++ b/packages/slate/test/transforms/unsetNodes/operation-contents-check.tsx @@ -0,0 +1,35 @@ +/** @jsx jsx */ +import assert from 'assert' +import { Transforms, Text, Editor } from 'slate' +import { jsx } from '../..' + +export const run = (editor: Editor) => { + Transforms.unsetNodes(editor, 'key', { at: [0] }) + + // unsetNodes uses null to remove properties, but that should not + // flow through to the operation + const [setNode] = editor.operations + + if (setNode.type === 'set_node') { + assert.deepStrictEqual(setNode, { + type: 'set_node', + path: [0], + properties: { key: true }, + newProperties: {}, + }) + } else { + // eslint-disable-next-line no-console + console.error('operations:', editor.operations) + assert.fail('operation was not a set node') + } +} +export const input = ( + + word + +) +export const output = ( + + word + +) diff --git a/packages/slate/test/transforms/unsetNodes/text/text.tsx b/packages/slate/test/transforms/unsetNodes/text.tsx similarity index 92% rename from packages/slate/test/transforms/unsetNodes/text/text.tsx rename to packages/slate/test/transforms/unsetNodes/text.tsx index 306af936b..d35d436f3 100644 --- a/packages/slate/test/transforms/unsetNodes/text/text.tsx +++ b/packages/slate/test/transforms/unsetNodes/text.tsx @@ -1,6 +1,6 @@ /** @jsx jsx */ import { Transforms, Text } from 'slate' -import { jsx } from '../../..' +import { jsx } from '../..' export const run = editor => { Transforms.unsetNodes(editor, 'key', { match: Text.isText })