From 0ad2a3f784f0b803adcc21448808dd26b7269fbf Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 12 Jun 2023 11:53:50 +0200 Subject: [PATCH] fix: paste tables into document Fixes #2708. Try to read the first table row as headings. Pasting works via `insertContent` while opening uses `setContent`. They use the schema in different ways. So we also need to make sure to test both for some corner cases. `setContent` is fairly flexible in turning the input into a valid document structure. `insertContent` however fails to resolve structures that would require picking lower priority parent elements. Note: Some tests in src/tests/nodes/Table.spec.js fail when using `insertContent` instead of `setContent`. Pasting the correponding html table is fixed never the less. Signed-off-by: Max --- src/nodes/Table/TableHeadRow.js | 2 +- src/nodes/Table/TableRow.js | 2 +- src/tests/helpers.js | 15 +++++++++++++++ src/tests/markdown.spec.js | 15 ++++++++++++++- 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/nodes/Table/TableHeadRow.js b/src/nodes/Table/TableHeadRow.js index e2974c7e8a..677780389d 100644 --- a/src/nodes/Table/TableHeadRow.js +++ b/src/nodes/Table/TableHeadRow.js @@ -22,7 +22,7 @@ export default TableRow.extend({ parseHTML() { return [ - { tag: 'tr', priority: 70 }, + { tag: 'tr:first-of-type', priority: 80 }, ] }, }) diff --git a/src/nodes/Table/TableRow.js b/src/nodes/Table/TableRow.js index b7343eb9a6..b6ce01d823 100644 --- a/src/nodes/Table/TableRow.js +++ b/src/nodes/Table/TableRow.js @@ -11,7 +11,7 @@ export default TableRow.extend({ parseHTML() { return [ - { tag: 'tr', priority: 80 }, + { tag: 'tr', priority: 70 }, ] }, }) diff --git a/src/tests/helpers.js b/src/tests/helpers.js index 5195792712..38c17153d6 100644 --- a/src/tests/helpers.js +++ b/src/tests/helpers.js @@ -49,3 +49,18 @@ export function markdownThroughEditorHtml(html) { const serializer = createMarkdownSerializer(tiptap.schema) return serializer.serialize(tiptap.state.doc) } + +/** + * Paste HTML into the Editor and return the serialized markdown + * + * @param {string} html + * @returns {string} + */ +export function markdownFromPaste(html) { + const tiptap = createEditor({ + enableRichEditing: true + }) + tiptap.commands.insertContent(html) + const serializer = createMarkdownSerializer(tiptap.schema) + return serializer.serialize(tiptap.state.doc) +} diff --git a/src/tests/markdown.spec.js b/src/tests/markdown.spec.js index 40e31fca2a..ca6fbc12e2 100644 --- a/src/tests/markdown.spec.js +++ b/src/tests/markdown.spec.js @@ -1,7 +1,11 @@ import spec from "./fixtures/spec" import markdownit from './../markdownit' import { typesAvailable } from './../markdownit/callouts' -import { markdownThroughEditor, markdownThroughEditorHtml } from "./helpers"; +import { + markdownThroughEditor, + markdownThroughEditorHtml, + markdownFromPaste +} from './helpers.js' import { createMarkdownSerializer } from "../extensions/Markdown"; import createEditor from "../EditorFactory"; @@ -195,11 +199,20 @@ describe('Markdown serializer from html', () => { )).toBe(`::: warn\n!warning!\n\n:::`) }) + test('table', () => { + expect(markdownThroughEditorHtml('
greetings
hello
')).toBe('| greetings |\n|-----------|\n| hello |\n') + }) + test('table cell escaping', () => { // while '|' has no special meaning in commonmark is has to be escaped for GFM tables expect(markdownThroughEditorHtml('
greetings
hello | hallo
')).toBe('| greetings |\n|-----------|\n| hello \\| hallo |\n') }) + test('table pastes (#2708)', () => { + // while '|' has no special meaning in commonmark is has to be escaped for GFM tables + expect(markdownFromPaste('
greetings
hello
')).toBe('| greetings |\n|-----------|\n| hello |\n') + }) + test('front matter', () => { expect(markdownThroughEditorHtml('
some: value

Heading

')).toBe('---\nsome: value\n---\n\n# Heading') // Test --- within front matter is allowed