From 0214b630778e7fa3b6ebcdf6cd9a8e4cf7351bd3 Mon Sep 17 00:00:00 2001 From: Andrew Herron Date: Fri, 6 Aug 2021 03:12:53 +1000 Subject: [PATCH] Skip wrapping nodes when the only match is an editor (#4253) * Skip wrapping nodes when the only match is an editor * Check for empty path instead of using isEditor --- .changeset/khaki-readers-battle.md | 5 +++ packages/slate/src/transforms/node.ts | 6 ++++ .../transforms/wrapNodes/block/omit-all.tsx | 32 +++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 .changeset/khaki-readers-battle.md create mode 100644 packages/slate/test/transforms/wrapNodes/block/omit-all.tsx diff --git a/.changeset/khaki-readers-battle.md b/.changeset/khaki-readers-battle.md new file mode 100644 index 000000000..8e2d58acf --- /dev/null +++ b/.changeset/khaki-readers-battle.md @@ -0,0 +1,5 @@ +--- +'slate': patch +--- + +Fix `Transforms.wrapNodes` crashing when the `match` function matched only the editor diff --git a/packages/slate/src/transforms/node.ts b/packages/slate/src/transforms/node.ts index 0178b9f36..8746f500d 100644 --- a/packages/slate/src/transforms/node.ts +++ b/packages/slate/src/transforms/node.ts @@ -942,6 +942,12 @@ export const NodeTransforms: NodeTransforms = { const last = matches[matches.length - 1] const [, firstPath] = first const [, lastPath] = last + + if (firstPath.length === 0 && lastPath.length === 0) { + // if there's no matching parent - usually means the node is an editor - don't do anything + continue + } + const commonPath = Path.equals(firstPath, lastPath) ? Path.parent(firstPath) : Path.common(firstPath, lastPath) diff --git a/packages/slate/test/transforms/wrapNodes/block/omit-all.tsx b/packages/slate/test/transforms/wrapNodes/block/omit-all.tsx new file mode 100644 index 000000000..1892251f6 --- /dev/null +++ b/packages/slate/test/transforms/wrapNodes/block/omit-all.tsx @@ -0,0 +1,32 @@ +/** @jsx jsx */ +import { Editor, Node, Text, Transforms } from 'slate' +import { jsx } from '../../..' + +export const run = editor => { + Transforms.wrapNodes(editor, , { + match: (node, currentPath) => { + // reject all nodes inside blocks tagged `noneditable`. Which is everything. + if (node.noneditable) return false + for (const [node, _] of Node.ancestors(editor, currentPath)) { + if (node.noneditable) return false + } + return true + }, + }) +} +export const input = ( + + + + word + + +) +export const output = ( + + + + word + + +)