1
0
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:
Andrew Herron
2021-05-06 09:39:37 +10:00
committed by GitHub
parent 796389c7d3
commit feb293aaa2
4 changed files with 132 additions and 0 deletions

View 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

View File

@@ -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

View 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>
)

View File

@@ -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>
)