From 7d83fcf5117e3a49b58715be274a4daf1285d034 Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Wed, 19 Feb 2025 18:29:15 +0100 Subject: [PATCH 1/2] fix: table cell merging --- packages/core/src/api/nodeConversions/nodeToBlock.ts | 6 ++---- .../core/src/blocks/TableBlockContent/TableBlockContent.ts | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/core/src/api/nodeConversions/nodeToBlock.ts b/packages/core/src/api/nodeConversions/nodeToBlock.ts index 3d90168824..ca298b52a3 100644 --- a/packages/core/src/api/nodeConversions/nodeToBlock.ts +++ b/packages/core/src/api/nodeConversions/nodeToBlock.ts @@ -67,10 +67,8 @@ export function contentNodeToTableContent< return { type: "tableCell", - content: contentNodeToInlineContent( - cellNode.firstChild!, - inlineContentSchema, - styleSchema + content: cellNode.content.content.flatMap((child) => + contentNodeToInlineContent(child, inlineContentSchema, styleSchema) ), props: { colspan: cellNode.attrs.colspan, diff --git a/packages/core/src/blocks/TableBlockContent/TableBlockContent.ts b/packages/core/src/blocks/TableBlockContent/TableBlockContent.ts index 309b0b5068..be59382502 100644 --- a/packages/core/src/blocks/TableBlockContent/TableBlockContent.ts +++ b/packages/core/src/blocks/TableBlockContent/TableBlockContent.ts @@ -159,10 +159,10 @@ export const Table = createBlockSpecFromStronglyTypedTiptapNode( TableExtension, TableParagraph, TableHeader.extend({ - content: "tableContent", + content: "tableContent*", }), TableCell.extend({ - content: "tableContent", + content: "tableContent*", }), TableRow, ] From 61abc711faa37c38b20218da5949fc0ccca1418c Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Wed, 26 Feb 2025 15:26:06 +0100 Subject: [PATCH 2/2] fix: better merging of styled text in table cells --- .../src/api/nodeConversions/nodeToBlock.ts | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/packages/core/src/api/nodeConversions/nodeToBlock.ts b/packages/core/src/api/nodeConversions/nodeToBlock.ts index ca298b52a3..5d25d1ea58 100644 --- a/packages/core/src/api/nodeConversions/nodeToBlock.ts +++ b/packages/core/src/api/nodeConversions/nodeToBlock.ts @@ -64,12 +64,40 @@ export function contentNodeToTableContent< } // Mark the cell as a header if it is a tableHeader node. headerMatrix[rowIndex][cellIndex] = cellNode.type.name === "tableHeader"; + // Convert cell content to inline content and merge adjacent styled text nodes + const content = cellNode.content.content + .map((child) => + contentNodeToInlineContent(child, inlineContentSchema, styleSchema) + ) + // The reason that we merge this content is that we allow table cells to contain multiple tableParagraph nodes + // So that we can leverage prosemirror-tables native merging + // If the schema only allowed a single tableParagraph node, then the merging would not work and cause prosemirror to fit the content into a new cell + .reduce((acc, contentPartial) => { + if (!acc.length) { + return contentPartial; + } + + const last = acc[acc.length - 1]; + const first = contentPartial[0]; + + // Only merge if the last and first content are both styled text nodes and have the same styles + if ( + isStyledTextInlineContent(last) && + isStyledTextInlineContent(first) && + JSON.stringify(last.styles) === JSON.stringify(first.styles) + ) { + // Join them together if they have the same styles + last.text += "\n" + first.text; + acc.push(...contentPartial.slice(1)); + return acc; + } + acc.push(...contentPartial); + return acc; + }, [] as InlineContent[]); return { type: "tableCell", - content: cellNode.content.content.flatMap((child) => - contentNodeToInlineContent(child, inlineContentSchema, styleSchema) - ), + content, props: { colspan: cellNode.attrs.colspan, rowspan: cellNode.attrs.rowspan,