From 55ff8f00e46e5fd0f2aef41da321c02b6d3a0f70 Mon Sep 17 00:00:00 2001 From: Andrew Herron Date: Thu, 12 Aug 2021 06:01:44 +1000 Subject: [PATCH] Fixed regression in #4208 where normalization on empty block nodes could not be overridden (#4431) --- .changeset/popular-ways-fail.md | 5 +++ packages/slate/src/interfaces/editor.ts | 18 +++++---- .../block/insert-custom-block.tsx | 40 +++++++++++++++++++ 3 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 .changeset/popular-ways-fail.md create mode 100644 packages/slate/test/normalization/block/insert-custom-block.tsx diff --git a/.changeset/popular-ways-fail.md b/.changeset/popular-ways-fail.md new file mode 100644 index 000000000..12e4de2ab --- /dev/null +++ b/.changeset/popular-ways-fail.md @@ -0,0 +1,5 @@ +--- +'slate': minor +--- + +Fixed regression in #4208 where normalization on empty block nodes could not be overridden diff --git a/packages/slate/src/interfaces/editor.ts b/packages/slate/src/interfaces/editor.ts index 1863e071e..f56626828 100644 --- a/packages/slate/src/interfaces/editor.ts +++ b/packages/slate/src/interfaces/editor.ts @@ -997,16 +997,18 @@ export const Editor: EditorInterface = { */ for (const dirtyPath of getDirtyPaths(editor)) { if (Node.has(editor, dirtyPath)) { - const [node, _] = Editor.node(editor, dirtyPath) + const entry = Editor.node(editor, dirtyPath) + const [node, _] = entry - // 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. + /* + The default normalizer inserts an empty text node in this scenario, but it can be customised. + So there is some risk here. + + As long as the normalizer only inserts child nodes for this case it is safe to do in any order; + by definition adding children to an empty node 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, - }) + editor.normalizeNode(entry) } } } diff --git a/packages/slate/test/normalization/block/insert-custom-block.tsx b/packages/slate/test/normalization/block/insert-custom-block.tsx new file mode 100644 index 000000000..55797b762 --- /dev/null +++ b/packages/slate/test/normalization/block/insert-custom-block.tsx @@ -0,0 +1,40 @@ +/** @jsx jsx */ +import { jsx } from '../..' +import { Editor, Element, Transforms } from 'slate' + +export const input = ( + + + +) + +// patch in a custom normalizer that inserts empty paragraphs in the body instead of text nodes +// this test also verifies the new node itself is also normalized, because it's inserting a non-normalized node +const editor = (input as unknown) as Editor +const defaultNormalize = editor.normalizeNode +editor.normalizeNode = entry => { + const [node, path] = entry + if ( + Element.isElement(node) && + node.children.length === 0 && + (node as any).type === 'body' + ) { + const child = { type: 'paragraph', children: [] } + Transforms.insertNodes(editor, child, { + at: path.concat(0), + voids: true, + }) + } else { + defaultNormalize(entry) + } +} + +export const output = ( + + + + + + + +)