mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-27 00:54:22 +02:00
Apply no-children normalization fix before normalization (#4208)
* Test cases for failure condition * Before normalizing ensure all elements have at least one text child. This is a normalization requirement that some normalization fixes require, so it must be done as an initial dedicated pass.
This commit is contained in:
5
.changeset/silver-snakes-perform.md
Normal file
5
.changeset/silver-snakes-perform.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'slate': patch
|
||||
---
|
||||
|
||||
Fix `Error: Cannot get the start point in the node at path [...] because it has no start text node` caused by normalizing a document where some elements have no children
|
@@ -16,6 +16,7 @@ import {
|
||||
RangeRef,
|
||||
Span,
|
||||
Text,
|
||||
Transforms,
|
||||
} from '..'
|
||||
import {
|
||||
DIRTY_PATHS,
|
||||
@@ -988,6 +989,27 @@ export const Editor: EditorInterface = {
|
||||
}
|
||||
|
||||
Editor.withoutNormalizing(editor, () => {
|
||||
/*
|
||||
Fix dirty elements with no children.
|
||||
editor.normalizeNode() does fix this, but some normalization fixes also require it to work.
|
||||
Running an initial pass avoids the catch-22 race condition.
|
||||
*/
|
||||
for (const dirtyPath of getDirtyPaths(editor)) {
|
||||
if (Node.has(editor, dirtyPath)) {
|
||||
const [node, _] = Editor.node(editor, dirtyPath)
|
||||
|
||||
// Add a text child to elements with no children.
|
||||
// This is safe to do in any order, by definition it can't cause other paths to change.
|
||||
if (Element.isElement(node) && node.children.length === 0) {
|
||||
const child = { text: '' }
|
||||
Transforms.insertNodes(editor, child, {
|
||||
at: dirtyPath.concat(0),
|
||||
voids: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const max = getDirtyPaths(editor).length * 42 // HACK: better way?
|
||||
let m = 0
|
||||
|
||||
|
21
packages/slate/test/transforms/normalization/move_node.tsx
Normal file
21
packages/slate/test/transforms/normalization/move_node.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
/** @jsx jsx */
|
||||
import { Transforms } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>one</block>
|
||||
<block>two</block>
|
||||
</editor>
|
||||
)
|
||||
export const run = editor => {
|
||||
Transforms.moveNodes(editor, { at: [0, 0], to: [1, 0] })
|
||||
}
|
||||
export const output = (
|
||||
<editor>
|
||||
<block>
|
||||
<text />
|
||||
</block>
|
||||
<block>onetwo</block>
|
||||
</editor>
|
||||
)
|
@@ -0,0 +1,84 @@
|
||||
/** @jsx jsx */
|
||||
import { Editor, Transforms } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>
|
||||
<text />
|
||||
<inline>one</inline>
|
||||
<text />
|
||||
</block>
|
||||
<block>
|
||||
<text />
|
||||
<inline>two</inline>
|
||||
<text />
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
export const run = editor => {
|
||||
Editor.withoutNormalizing(editor, () => {
|
||||
const operations = [
|
||||
{
|
||||
type: 'split_node',
|
||||
path: [0, 1],
|
||||
position: 0,
|
||||
properties: { inline: true },
|
||||
},
|
||||
{
|
||||
type: 'split_node',
|
||||
path: [0],
|
||||
position: 1,
|
||||
properties: {},
|
||||
},
|
||||
{
|
||||
type: 'split_node',
|
||||
path: [2, 1, 0],
|
||||
position: 0,
|
||||
properties: {},
|
||||
},
|
||||
{
|
||||
type: 'split_node',
|
||||
path: [2, 1],
|
||||
position: 0,
|
||||
properties: { inline: true },
|
||||
},
|
||||
{
|
||||
type: 'split_node',
|
||||
path: [2],
|
||||
position: 1,
|
||||
properties: {},
|
||||
},
|
||||
{ type: 'insert_node', path: [2, 1], node: { text: '' } },
|
||||
]
|
||||
operations.forEach(editor.apply)
|
||||
})
|
||||
}
|
||||
export const output = (
|
||||
<editor>
|
||||
<block>
|
||||
<text />
|
||||
</block>
|
||||
<block>
|
||||
<text />
|
||||
<inline>
|
||||
<text />
|
||||
</inline>
|
||||
<text />
|
||||
<inline>one</inline>
|
||||
<text />
|
||||
</block>
|
||||
<block>
|
||||
<text />
|
||||
</block>
|
||||
<block>
|
||||
<text />
|
||||
<inline>
|
||||
<text />
|
||||
</inline>
|
||||
<text />
|
||||
<inline>two</inline>
|
||||
<text />
|
||||
</block>
|
||||
</editor>
|
||||
)
|
Reference in New Issue
Block a user