diff --git a/packages/slate/src/interfaces/editor.ts b/packages/slate/src/interfaces/editor.ts index b8618ebab..055a845be 100644 --- a/packages/slate/src/interfaces/editor.ts +++ b/packages/slate/src/interfaces/editor.ts @@ -1736,3 +1736,4 @@ export type NodeMatch = | ((node: Node, path: Path) => boolean) export type PropsCompare = (prop: Partial, node: Partial) => boolean +export type PropsMerge = (prop: Partial, node: Partial) => object diff --git a/packages/slate/src/transforms/node.ts b/packages/slate/src/transforms/node.ts index c2747ffa4..ba1c32834 100644 --- a/packages/slate/src/transforms/node.ts +++ b/packages/slate/src/transforms/node.ts @@ -11,7 +11,7 @@ import { NodeEntry, Ancestor, } from '..' -import { NodeMatch, PropsCompare } from '../interfaces/editor' +import { NodeMatch, PropsCompare, PropsMerge } from '../interfaces/editor' export interface NodeTransforms { insertNodes: ( @@ -76,6 +76,7 @@ export interface NodeTransforms { split?: boolean voids?: boolean compare?: PropsCompare + merge?: PropsMerge } ) => void splitNodes: ( @@ -570,10 +571,11 @@ export const NodeTransforms: NodeTransforms = { split?: boolean voids?: boolean compare?: PropsCompare + merge?: PropsMerge } = {} ): void { Editor.withoutNormalizing(editor, () => { - let { match, at = editor.selection, compare } = options + let { match, at = editor.selection, compare, merge } = options const { hanging = false, mode = 'lowest', @@ -660,7 +662,11 @@ export const NodeTransforms: NodeTransforms = { // Omit new properties from the old properties list if (node.hasOwnProperty(k)) properties[k] = node[k] // Omit properties that have been removed from the new properties list - if (props[k] != null) newProperties[k] = props[k] + if (merge) { + if (props[k] != null) newProperties[k] = merge(node[k], props[k]) + } else { + if (props[k] != null) newProperties[k] = props[k] + } } } diff --git a/packages/slate/test/transforms/setNodes/merge/text.tsx b/packages/slate/test/transforms/setNodes/merge/text.tsx new file mode 100644 index 000000000..6fc5c1937 --- /dev/null +++ b/packages/slate/test/transforms/setNodes/merge/text.tsx @@ -0,0 +1,26 @@ +/** @jsx jsx */ +import { Transforms, Text } from 'slate' +import { jsx } from '../../..' +import _ from 'lodash' + +export const run = editor => { + Transforms.setNodes( + editor, + { a: { b: 2, c: 3 } }, + { at: [0, 0], match: Text.isText, merge: (n, p) => _.defaultsDeep(p, n) } + ) +} +export const input = ( + + + word + + +) +export const output = ( + + + word + + +)