diff --git a/demos/src/Issues/2720/React/index.spec.js b/demos/src/Issues/2720/React/index.spec.js index 6035fd14a5..025c7b7b3d 100644 --- a/demos/src/Issues/2720/React/index.spec.js +++ b/demos/src/Issues/2720/React/index.spec.js @@ -20,4 +20,11 @@ context('/src/Issues/2720/React/', () => { // 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') }) + + it('should keep newlines in pre tag', () => { + cy.get('.tiptap').then(([{ editor }]) => { + editor.commands.setContent('
foo\nbar
') + cy.get('.tiptap').should('contain.html', '
foo\nbar
') + }) + }) }) diff --git a/packages/core/src/helpers/createNodeFromContent.ts b/packages/core/src/helpers/createNodeFromContent.ts index 7b161d67ec..b6a7e74895 100644 --- a/packages/core/src/helpers/createNodeFromContent.ts +++ b/packages/core/src/helpers/createNodeFromContent.ts @@ -40,7 +40,6 @@ 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 diff --git a/packages/core/src/utilities/elementFromString.ts b/packages/core/src/utilities/elementFromString.ts index bbfd794bd5..69a27634a9 100644 --- a/packages/core/src/utilities/elementFromString.ts +++ b/packages/core/src/utilities/elementFromString.ts @@ -1,6 +1,26 @@ +const removeWhitespaces = (node: HTMLElement) => { + const children = node.childNodes + + for (let i = children.length - 1; i >= 0; i -= 1) { + const child = children[i] + + if (child.nodeType === 3 && child.nodeValue && !/\S/.test(child.nodeValue)) { + node.removeChild(child) + } else if (child.nodeType === 1) { + removeWhitespaces(child as HTMLElement) + } + } + + return node +} + export function elementFromString(value: string): HTMLElement { // add a wrapper to preserve leading and trailing whitespace const wrappedValue = `${value}` - return new window.DOMParser().parseFromString(wrappedValue, 'text/html').body + const html = new window.DOMParser().parseFromString(wrappedValue, 'text/html').body + + removeWhitespaces(html) + + return removeWhitespaces(html) }