mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-11 17:53:59 +02:00
set_node operations did not invert correctly after serialization (#4078)
* Use null instead of undefined as the old value for set_node operations that add a property * Changelog * Omit undefined values from `set_node` operations completely. Delete missing property values in `Transforms.apply()` instead. * Add tests for removing set_node properties with null and undefined
This commit is contained in:
5
.changeset/silent-bees-sing.md
Normal file
5
.changeset/silent-bees-sing.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'slate': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
set_node operations did not invert correctly after serialization
|
@@ -182,7 +182,7 @@ export const GeneralTransforms: GeneralTransforms = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 'set_node': {
|
case 'set_node': {
|
||||||
const { path, newProperties } = op
|
const { path, properties, newProperties } = op
|
||||||
|
|
||||||
if (path.length === 0) {
|
if (path.length === 0) {
|
||||||
throw new Error(`Cannot set properties on the root node!`)
|
throw new Error(`Cannot set properties on the root node!`)
|
||||||
@@ -204,6 +204,13 @@ export const GeneralTransforms: GeneralTransforms = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// properties that were previously defined, but are now missing, must be deleted
|
||||||
|
for (const key in properties) {
|
||||||
|
if (!newProperties.hasOwnProperty(key)) {
|
||||||
|
delete node[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -631,7 +631,8 @@ export const NodeTransforms: NodeTransforms = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (props[k] !== node[k]) {
|
if (props[k] !== node[k]) {
|
||||||
properties[k] = node[k]
|
// Omit new properties from the old property list rather than set them to undefined
|
||||||
|
if (node.hasOwnProperty(k)) properties[k] = node[k]
|
||||||
newProperties[k] = props[k]
|
newProperties[k] = props[k]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
28
packages/slate/test/operations/set_node/remove-null.tsx
Normal file
28
packages/slate/test/operations/set_node/remove-null.tsx
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/** @jsx jsx */
|
||||||
|
import { jsx } from 'slate-hyperscript'
|
||||||
|
import { Transforms, Editor } from 'slate'
|
||||||
|
|
||||||
|
export const input = (
|
||||||
|
<editor>
|
||||||
|
<element>
|
||||||
|
<text key />
|
||||||
|
</element>
|
||||||
|
</editor>
|
||||||
|
)
|
||||||
|
|
||||||
|
export const operations = [
|
||||||
|
{
|
||||||
|
type: 'set_node',
|
||||||
|
path: [0, 0],
|
||||||
|
properties: { key: true },
|
||||||
|
newProperties: { key: null },
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export const output = (
|
||||||
|
<editor>
|
||||||
|
<element>
|
||||||
|
<text />
|
||||||
|
</element>
|
||||||
|
</editor>
|
||||||
|
)
|
28
packages/slate/test/operations/set_node/remove-omit.tsx
Normal file
28
packages/slate/test/operations/set_node/remove-omit.tsx
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/** @jsx jsx */
|
||||||
|
import { jsx } from 'slate-hyperscript'
|
||||||
|
import { Transforms, Editor } from 'slate'
|
||||||
|
|
||||||
|
export const input = (
|
||||||
|
<editor>
|
||||||
|
<element>
|
||||||
|
<text key />
|
||||||
|
</element>
|
||||||
|
</editor>
|
||||||
|
)
|
||||||
|
|
||||||
|
export const operations = [
|
||||||
|
{
|
||||||
|
type: 'set_node',
|
||||||
|
path: [0, 0],
|
||||||
|
properties: { key: true },
|
||||||
|
newProperties: {},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export const output = (
|
||||||
|
<editor>
|
||||||
|
<element>
|
||||||
|
<text />
|
||||||
|
</element>
|
||||||
|
</editor>
|
||||||
|
)
|
28
packages/slate/test/operations/set_node/remove-undefined.tsx
Normal file
28
packages/slate/test/operations/set_node/remove-undefined.tsx
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/** @jsx jsx */
|
||||||
|
import { jsx } from 'slate-hyperscript'
|
||||||
|
import { Transforms, Editor } from 'slate'
|
||||||
|
|
||||||
|
export const input = (
|
||||||
|
<editor>
|
||||||
|
<element>
|
||||||
|
<text key />
|
||||||
|
</element>
|
||||||
|
</editor>
|
||||||
|
)
|
||||||
|
|
||||||
|
export const operations = [
|
||||||
|
{
|
||||||
|
type: 'set_node',
|
||||||
|
path: [0, 0],
|
||||||
|
properties: { key: true },
|
||||||
|
newProperties: { key: undefined },
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export const output = (
|
||||||
|
<editor>
|
||||||
|
<element>
|
||||||
|
<text />
|
||||||
|
</element>
|
||||||
|
</editor>
|
||||||
|
)
|
@@ -0,0 +1,25 @@
|
|||||||
|
/** @jsx jsx */
|
||||||
|
import assert from 'assert'
|
||||||
|
import { Editor, Transforms, Operation } from 'slate'
|
||||||
|
import { jsx } from '../../..'
|
||||||
|
|
||||||
|
export const run = (editor: Editor) => {
|
||||||
|
Transforms.setNodes(editor, { key: true }, { at: [0] })
|
||||||
|
const [op] = editor.operations
|
||||||
|
const roundTrip: Operation = JSON.parse(JSON.stringify(op))
|
||||||
|
assert.deepStrictEqual(op, roundTrip)
|
||||||
|
}
|
||||||
|
export const input = (
|
||||||
|
<editor>
|
||||||
|
<block>
|
||||||
|
<text />
|
||||||
|
</block>
|
||||||
|
</editor>
|
||||||
|
)
|
||||||
|
export const output = (
|
||||||
|
<editor>
|
||||||
|
<block key>
|
||||||
|
<text />
|
||||||
|
</block>
|
||||||
|
</editor>
|
||||||
|
)
|
@@ -0,0 +1,25 @@
|
|||||||
|
/** @jsx jsx */
|
||||||
|
import { Editor, Transforms, Operation } from 'slate'
|
||||||
|
import { jsx } from '../../..'
|
||||||
|
|
||||||
|
export const run = (editor: Editor) => {
|
||||||
|
Transforms.setNodes(editor, { key: true }, { at: [0] })
|
||||||
|
const [op] = editor.operations
|
||||||
|
const roundTrip: Operation = JSON.parse(JSON.stringify(op))
|
||||||
|
const inverted = Operation.inverse(roundTrip)
|
||||||
|
editor.apply(inverted)
|
||||||
|
}
|
||||||
|
export const input = (
|
||||||
|
<editor>
|
||||||
|
<block>
|
||||||
|
<text />
|
||||||
|
</block>
|
||||||
|
</editor>
|
||||||
|
)
|
||||||
|
export const output = (
|
||||||
|
<editor>
|
||||||
|
<block>
|
||||||
|
<text />
|
||||||
|
</block>
|
||||||
|
</editor>
|
||||||
|
)
|
Reference in New Issue
Block a user