From 135a12f7aa2df839a0b619704110a360b980c738 Mon Sep 17 00:00:00 2001 From: bdbch <6538827+bdbch@users.noreply.github.com> Date: Mon, 8 Jan 2024 20:21:45 +0100 Subject: [PATCH] fix(core): fix insertContentAt keeping new lines in html content (#4465) * fix(core): fix insertContentAt keeping new lines in html content * test(core): add tests * chore: remove stray console.log * chore: remove buttons from demo * fix(core): fix replacement on multiple breaks --- demos/src/Issues/2720/React/index.html | 0 demos/src/Issues/2720/React/index.jsx | 62 +++++++++++++++++++ demos/src/Issues/2720/React/index.spec.js | 23 +++++++ demos/src/Issues/2720/React/styles.scss | 56 +++++++++++++++++ .../core/src/helpers/createNodeFromContent.ts | 1 + 5 files changed, 142 insertions(+) create mode 100644 demos/src/Issues/2720/React/index.html create mode 100644 demos/src/Issues/2720/React/index.jsx create mode 100644 demos/src/Issues/2720/React/index.spec.js create mode 100644 demos/src/Issues/2720/React/styles.scss diff --git a/demos/src/Issues/2720/React/index.html b/demos/src/Issues/2720/React/index.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/demos/src/Issues/2720/React/index.jsx b/demos/src/Issues/2720/React/index.jsx new file mode 100644 index 0000000000..ac574f71d6 --- /dev/null +++ b/demos/src/Issues/2720/React/index.jsx @@ -0,0 +1,62 @@ +import './styles.scss' + +import { Color } from '@tiptap/extension-color' +import ListItem from '@tiptap/extension-list-item' +import TextStyle from '@tiptap/extension-text-style' +import { EditorProvider, useCurrentEditor } from '@tiptap/react' +import StarterKit from '@tiptap/starter-kit' +import React from 'react' + +const htmlContent = ` +

Tiptap

+

Hello World

+

This is a paragraph
with a break.

+

And this is some additional string content.

+` + +const textContent = `Hello World +This is content with a new line. Is this working? + +Lets see if multiple new lines are inserted correctly + +And more lines` + +const MenuBar = () => { + const { editor } = useCurrentEditor() + + if (!editor) { + return null + } + + return ( + <> + + + + ) +} + +const extensions = [ + Color.configure({ types: [TextStyle.name, ListItem.name] }), + TextStyle.configure({ types: [ListItem.name] }), + StarterKit.configure({ + bulletList: { + keepMarks: true, + }, + orderedList: { + keepMarks: true, + }, + }), +] + +const content = '' + +export default () => { + return ( + } extensions={extensions} content={content}> + ) +} diff --git a/demos/src/Issues/2720/React/index.spec.js b/demos/src/Issues/2720/React/index.spec.js new file mode 100644 index 0000000000..6035fd14a5 --- /dev/null +++ b/demos/src/Issues/2720/React/index.spec.js @@ -0,0 +1,23 @@ +context('/src/Issues/2720/React/', () => { + before(() => { + cy.visit('/src/Issues/2720/React/') + }) + + beforeEach(() => { + cy.get('.tiptap').type('{selectall}{backspace}') + }) + + it('should insert html content correctly', () => { + cy.get('button[data-test-id="html-content"]').click() + + // check if the content html is correct + cy.get('.tiptap').should('contain.html', '

Tiptap

Hello World

This is a paragraph
with a break.

And this is some additional string content.

') + }) + + it('should insert text content correctly', () => { + cy.get('button[data-test-id="text-content"]').click() + + // check if the content html is correct + cy.get('.tiptap').should('contain.html', 'Hello World\nThis is content with a new line. Is this working?\n\nLets see if multiple new lines are inserted correctly') + }) +}) diff --git a/demos/src/Issues/2720/React/styles.scss b/demos/src/Issues/2720/React/styles.scss new file mode 100644 index 0000000000..4d2b2c81ea --- /dev/null +++ b/demos/src/Issues/2720/React/styles.scss @@ -0,0 +1,56 @@ +/* Basic editor styles */ +.tiptap { + > * + * { + margin-top: 0.75em; + } + + ul, + ol { + padding: 0 1rem; + } + + h1, + h2, + h3, + h4, + h5, + h6 { + line-height: 1.1; + } + + code { + background-color: rgba(#616161, 0.1); + color: #616161; + } + + pre { + background: #0D0D0D; + color: #FFF; + font-family: 'JetBrainsMono', monospace; + padding: 0.75rem 1rem; + border-radius: 0.5rem; + + code { + color: inherit; + padding: 0; + background: none; + font-size: 0.8rem; + } + } + + img { + max-width: 100%; + height: auto; + } + + blockquote { + padding-left: 1rem; + border-left: 2px solid rgba(#0D0D0D, 0.1); + } + + hr { + border: none; + border-top: 2px solid rgba(#0D0D0D, 0.1); + margin: 2rem 0; + } +} diff --git a/packages/core/src/helpers/createNodeFromContent.ts b/packages/core/src/helpers/createNodeFromContent.ts index b6a7e74895..7b161d67ec 100644 --- a/packages/core/src/helpers/createNodeFromContent.ts +++ b/packages/core/src/helpers/createNodeFromContent.ts @@ -40,6 +40,7 @@ export function createNodeFromContent( } if (typeof content === 'string') { + content = content.split('\n').map(part => part.trim()).join('') // we need to remove new lines since the parser will add breaks const parser = DOMParser.fromSchema(schema) return options.slice