From 95f402c59414331b2eeca9a19bd2c73c0ab6cd6c Mon Sep 17 00:00:00 2001 From: Ridham Bhat <44293164+ridhambhat@users.noreply.github.com> Date: Tue, 13 Apr 2021 20:45:47 +0530 Subject: [PATCH] Correcting the splitting logic in setNodes (#4168) * Defined conditions to always split nodes Those conditions are: - When the anchor does not lie at the start of a node. - When the focus does not lie at the end of a node. * prev variable now points to correct updated node. Previously, in the case the previous node gets merged in last iteration, prev pointer could be pointing to the wrong node. That posed problems, especially when normalizing empty text nodes. So, now in every iteration, we get a copy of updated node structure, and take value of prev from that. * Test to check splitting and normalization logic. - In this, since anchor and focus bleeds on both sides, splits happen. - Empty text nodes are introduced on either side. - New properties are set in the new node selection. - Normalization happens and takes care of those empty text nodes. * Create two-lies-appear.md * Update two-lies-appear.md Co-authored-by: Ian Storm Taylor --- .changeset/two-lies-appear.md | 5 +++ packages/slate/src/create-editor.ts | 4 +- packages/slate/src/transforms/node.ts | 4 ++ .../transforms/setNodes/text/merge-across.tsx | 41 +++++++++++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 .changeset/two-lies-appear.md create mode 100644 packages/slate/test/transforms/setNodes/text/merge-across.tsx diff --git a/.changeset/two-lies-appear.md b/.changeset/two-lies-appear.md new file mode 100644 index 000000000..f5ebe105a --- /dev/null +++ b/.changeset/two-lies-appear.md @@ -0,0 +1,5 @@ +--- +slate: patch +--- + +Fixed a bug in splitting and applying overlapping marks to text nodes. diff --git a/packages/slate/src/create-editor.ts b/packages/slate/src/create-editor.ts index aa436ca96..f19d93846 100644 --- a/packages/slate/src/create-editor.ts +++ b/packages/slate/src/create-editor.ts @@ -224,8 +224,10 @@ export const createEditor = (): Editor => { let n = 0 for (let i = 0; i < node.children.length; i++, n++) { + const currentNode = Node.get(editor, path) + if (Text.isText(currentNode)) continue const child = node.children[i] as Descendant - const prev = node.children[i - 1] as Descendant + const prev = currentNode.children[n - 1] as Descendant const isLast = i === node.children.length - 1 const isInlineOrText = Text.isText(child) || diff --git a/packages/slate/src/transforms/node.ts b/packages/slate/src/transforms/node.ts index 2a4d2d061..0178b9f36 100644 --- a/packages/slate/src/transforms/node.ts +++ b/packages/slate/src/transforms/node.ts @@ -592,17 +592,21 @@ export const NodeTransforms: NodeTransforms = { const rangeRef = Editor.rangeRef(editor, at, { affinity: 'inward' }) const [start, end] = Range.edges(at) const splitMode = mode === 'lowest' ? 'lowest' : 'highest' + const endAtEndOfNode = Editor.isEnd(editor, end, end.path) Transforms.splitNodes(editor, { at: end, match, mode: splitMode, voids, + always: !endAtEndOfNode, }) + const startAtStartOfNode = Editor.isStart(editor, start, start.path) Transforms.splitNodes(editor, { at: start, match, mode: splitMode, voids, + always: !startAtStartOfNode, }) at = rangeRef.unref()! diff --git a/packages/slate/test/transforms/setNodes/text/merge-across.tsx b/packages/slate/test/transforms/setNodes/text/merge-across.tsx new file mode 100644 index 000000000..7b5b086d8 --- /dev/null +++ b/packages/slate/test/transforms/setNodes/text/merge-across.tsx @@ -0,0 +1,41 @@ +/** @jsx jsx */ +import { Transforms, Text } from 'slate' +import { jsx } from '../../..' + +export const run = editor => { + Transforms.setNodes( + editor, + { key: true }, + { match: Text.isText, split: true } + ) +} +export const input = ( + + + + One + + + Two + + + Three + + + +) +export const output = ( + + + + One + + + + Two + + + Three + + +)