slab / quill

Quill is a modern WYSIWYG editor built for compatibility and extensibility
https://quilljs.com
BSD 3-Clause "New" or "Revised" License
43.92k stars 3.41k forks source link

Break tags are stripped from Break blot in getSemanticHTML #4159

Open amyasmith opened 7 months ago

amyasmith commented 7 months ago

The Break blot for empty newlines is rendered as <p><br></p> in the editor, which correctly shows multiple sequential newlines, but this becomes <p></p> when converted to HTML with getSemanticHTML(). This causes a discrepancy in the output.

Steps for Reproduction

  1. Visit the Quill playground
  2. Enter some newlines
  3. Check inspector
  4. Run getSemanticHTML()

Expected behavior: Semantic HTML will include <br> tags

Actual behavior: Semantic HTML does not include <br> tags

Platforms:

Tested on MacOS Sonoma on Firefox and Chrome

Version:

2.0.1

amyasmith commented 7 months ago

I would appreciate if anyone has a quick fix to this that can be implemented with Parchment/Registry. I don't want to have to do replaceAll() on the HTML output to fix this.

AltiorPetitM commented 6 months ago

Hey ^^, One way i found was to make the p become a div, and then replace the empty <div></div> with <div><br></biv> when i export the html using the getSemanticHTML()

import Quill from 'quill'

const Block = Quill.import('blots/block')
Block.tagName = 'DIV'

export default Block

You can use this to make the p tag become a div and then when you want to export you can do this quill.getSemanticHTML().replace(/<div><\/div>/g, '<div><br></div>')

Napam commented 5 months ago

I experience the same issue

Napam commented 5 months ago

Hey ^^, One way i found was to make the p become a div, and then replace the empty <div></div> with <div><br></biv> when i export the html using the getSemanticHTML()

import Quill from 'quill'

const Block = Quill.import('blots/block')
Block.tagName = 'DIV'

export default Block

You can use this to make the p tag become a div and then when you want to export you can do this quill.getSemanticHTML().replace(/<div><\/div>/g, '<div><br></div>')

Just wondering, why not just do quill.getSemanticHTML().replace(/p><\p>/g, '<p><br></p>') directly?

markleppke commented 3 months ago

Our customers are experiencing this issue as in our application. Our users use the the quill instance to edit an email that shows up in a preview side-by-side with the editor. The output that we bind to inherits this bug, and the lack of <br> shows up in the email preview.

So our customers are saying they can't add a line break between lines.

+1 on getting this fixed

Stonepaw commented 3 months ago

Our customers also were experiencing this issue. We use quill via ngx-quill and the solution I came up with to fix this for all our quill editors was to monkey patch the getHTML function to replace the empty <p></p> with <p><br /></p> . This is obviously not an ideal solution but is the best I could come up with for now.

const originalGetHTML = Editor.prototype.getHTML;
Editor.prototype.getHTML = function (index, length): string {
    return originalGetHTML.call(this, index, length).replace(/<p><\/p>/g, '<p><br /></p>');
};

I put this into some app initialization code so that it is patched when we first configure ngx-quill.

thomasgebets commented 3 months ago

Our customers also were experiencing this issue. We use quill via ngx-quill and the solution I came up with to fix this for all our quill editors was to monkey patch the getHTML function to replace the empty <p></p> with <p><br /></p> . This is obviously not an ideal solution but is the best I could come up with for now.

const originalGetHTML = Editor.prototype.getHTML;
Editor.prototype.getHTML = function (index, length): string {
    return originalGetHTML.call(this, index, length).replace(/<p><\/p>/g, '<p><br /></p>');
};

I put this into some app initialization code so that it is patched when we first configure ngx-quill.

Hi, thanks for your suggestion! We are also using ngx-quill but as far as i found online, the getHTML function is not available for quill 2.x anymore? Where would you put this initialization logic? Thanks a lot :)

thomasgebets commented 3 months ago

Ok i have solved it by adapting in this manner:

const originalGetSemanticHTML = this.quill.getSemanticHTML;
this.quill.getSemanticHTML = function (): string {
  return originalGetSemanticHTML.call(this).replace(/<p><\/p>/g, '<p><br /></p>');
}

Thanks a lot for the hint!! :)

Stonepaw commented 1 week ago

We've updated our regex to handle cases where the text is right aligned by keeping the classes on the empty <p>

replace(/<p([^>]+)?><\/p>/g, '<p$1><br></p>')