From d6c71a838d590f78fdff15c805d93f43c8a5a1a5 Mon Sep 17 00:00:00 2001 From: Myles J Date: Sat, 6 Apr 2024 00:29:46 +0100 Subject: [PATCH] fix: unexpected renderText() for contentful nodes (#3410) --- packages/core/src/helpers/getTextBetween.ts | 6 +- .../integration/core/generateText.spec.ts | 66 +++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 tests/cypress/integration/core/generateText.spec.ts diff --git a/packages/core/src/helpers/getTextBetween.ts b/packages/core/src/helpers/getTextBetween.ts index f15f10517..c9fa52abb 100644 --- a/packages/core/src/helpers/getTextBetween.ts +++ b/packages/core/src/helpers/getTextBetween.ts @@ -33,7 +33,11 @@ export function getTextBetween( range, }) } - } else if (node.isText) { + // do not descend into child nodes when there exists a serializer + return false + } + + if (node.isText) { text += node?.text?.slice(Math.max(from, pos) - pos, to - pos) // eslint-disable-line separated = false } else if (node.isBlock && !separated) { diff --git a/tests/cypress/integration/core/generateText.spec.ts b/tests/cypress/integration/core/generateText.spec.ts new file mode 100644 index 000000000..073ba0e17 --- /dev/null +++ b/tests/cypress/integration/core/generateText.spec.ts @@ -0,0 +1,66 @@ +/// + +import { generateText, Node, NodeConfig } from '@tiptap/core' +import Document from '@tiptap/extension-document' +import Paragraph from '@tiptap/extension-paragraph' +import Text from '@tiptap/extension-text' + +describe(generateText.name, () => { + it('generates Text from JSON without an editor instance', () => { + const json = { + type: 'doc', + content: [{ + type: 'paragraph', + content: [ + { + type: 'custom-node-default-renderer', + content: [ + { + type: 'text', + text: 'Example One', + }, + ], + }, + { + type: 'text', + text: ' ', + }, + { + type: 'custom-node-custom-renderer', + content: [ + { + type: 'text', + text: 'Example Two', + }, + ], + }, + ], + }], + } + + const contentfulInlineNode = (name: string, config?: Partial) => Node.create({ + name, + group: 'inline', + inline: true, + content: 'text*', + parseHTML() { + return [{ tag: name }] + }, + ...config, + }) + + const text = generateText(json, [ + Document, + Paragraph, + Text, + contentfulInlineNode('custom-node-default-renderer'), + contentfulInlineNode('custom-node-custom-renderer', { + renderText({ node }) { + return `~${node.textContent}~` + }, + }), + ]) + + expect(text).to.eq('Example One ~Example Two~') + }) +})