mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-10 17:24:02 +02:00
feat: add custom compare node props (#4889)
* feat: add custom compare props * chore: add test for custom compare props
This commit is contained in:
@@ -1721,3 +1721,5 @@ export const Editor: EditorInterface = {
|
|||||||
export type NodeMatch<T extends Node> =
|
export type NodeMatch<T extends Node> =
|
||||||
| ((node: Node, path: Path) => node is T)
|
| ((node: Node, path: Path) => node is T)
|
||||||
| ((node: Node, path: Path) => boolean)
|
| ((node: Node, path: Path) => boolean)
|
||||||
|
|
||||||
|
export type PropsCompare = (prop: Partial<Node>, node: Partial<Node>) => boolean
|
||||||
|
@@ -11,7 +11,7 @@ import {
|
|||||||
NodeEntry,
|
NodeEntry,
|
||||||
Ancestor,
|
Ancestor,
|
||||||
} from '..'
|
} from '..'
|
||||||
import { NodeMatch } from '../interfaces/editor'
|
import { NodeMatch, PropsCompare } from '../interfaces/editor'
|
||||||
|
|
||||||
export interface NodeTransforms {
|
export interface NodeTransforms {
|
||||||
insertNodes: <T extends Node>(
|
insertNodes: <T extends Node>(
|
||||||
@@ -75,6 +75,7 @@ export interface NodeTransforms {
|
|||||||
hanging?: boolean
|
hanging?: boolean
|
||||||
split?: boolean
|
split?: boolean
|
||||||
voids?: boolean
|
voids?: boolean
|
||||||
|
compare?: PropsCompare
|
||||||
}
|
}
|
||||||
) => void
|
) => void
|
||||||
splitNodes: <T extends Node>(
|
splitNodes: <T extends Node>(
|
||||||
@@ -568,10 +569,11 @@ export const NodeTransforms: NodeTransforms = {
|
|||||||
hanging?: boolean
|
hanging?: boolean
|
||||||
split?: boolean
|
split?: boolean
|
||||||
voids?: boolean
|
voids?: boolean
|
||||||
|
compare?: PropsCompare
|
||||||
} = {}
|
} = {}
|
||||||
): void {
|
): void {
|
||||||
Editor.withoutNormalizing(editor, () => {
|
Editor.withoutNormalizing(editor, () => {
|
||||||
let { match, at = editor.selection } = options
|
let { match, at = editor.selection, compare } = options
|
||||||
const {
|
const {
|
||||||
hanging = false,
|
hanging = false,
|
||||||
mode = 'lowest',
|
mode = 'lowest',
|
||||||
@@ -628,6 +630,10 @@ export const NodeTransforms: NodeTransforms = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!compare) {
|
||||||
|
compare = (prop, nodeProp) => prop !== nodeProp
|
||||||
|
}
|
||||||
|
|
||||||
for (const [node, path] of Editor.nodes(editor, {
|
for (const [node, path] of Editor.nodes(editor, {
|
||||||
at,
|
at,
|
||||||
match,
|
match,
|
||||||
@@ -649,7 +655,7 @@ export const NodeTransforms: NodeTransforms = {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props[k] !== node[k]) {
|
if (compare(props[k], node[k])) {
|
||||||
hasChanges = true
|
hasChanges = true
|
||||||
// Omit new properties from the old properties list
|
// Omit new properties from the old properties list
|
||||||
if (node.hasOwnProperty(k)) properties[k] = node[k]
|
if (node.hasOwnProperty(k)) properties[k] = node[k]
|
||||||
|
43
packages/slate/test/transforms/normalization/set_node.tsx
Normal file
43
packages/slate/test/transforms/normalization/set_node.tsx
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/** @jsx jsx */
|
||||||
|
import { Editor, Element, Transforms } from 'slate'
|
||||||
|
import { jsx } from '../..'
|
||||||
|
import _ from 'lodash'
|
||||||
|
|
||||||
|
export const input = (
|
||||||
|
<editor>
|
||||||
|
<block type="body" attr={{ a: true }}>
|
||||||
|
one
|
||||||
|
</block>
|
||||||
|
</editor>
|
||||||
|
)
|
||||||
|
|
||||||
|
const editor = (input as unknown) as Editor
|
||||||
|
const defaultNormalize = editor.normalizeNode
|
||||||
|
editor.normalizeNode = entry => {
|
||||||
|
const [node, path] = entry
|
||||||
|
if (
|
||||||
|
Element.isElement(node) &&
|
||||||
|
(node as any).type === 'body' &&
|
||||||
|
Editor.string(editor, path, { voids: true }) === 'one'
|
||||||
|
) {
|
||||||
|
Transforms.setNodes(
|
||||||
|
editor,
|
||||||
|
{ attr: { a: false } },
|
||||||
|
{ at: path, compare: (p, n) => !_.isEqual(p, n) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultNormalize(entry)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const run = editor => {
|
||||||
|
Editor.normalize(editor, { force: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const output = (
|
||||||
|
<editor>
|
||||||
|
<block type="body" attr={{ a: false }}>
|
||||||
|
one
|
||||||
|
</block>
|
||||||
|
</editor>
|
||||||
|
)
|
Reference in New Issue
Block a user