Empty paragraphs inserted into and before div-like elements.

Created on 8 January 2025, 7 days ago

Problem/Motivation

Since 2.0.1, using div-like html elements (div, article, section, aside, etc) in CKEditor results in a behaviour whereby an empty paragraph containing   is inserted before and inside of the element when editing a piece.

We use <aside> elements for floating sidebars.

However, this bug means that if you are editing the beginning of an article with a sidebar beyond the scroll view and save your changes five times, there will be 10 empty lines added for every sidebar which you didn't get a chance to correct.

Steps to reproduce

  1. Install drupal/wysiwyg_linebreaks 2.0.1
  2. Create a text format which permits <aside> or <div> elements using CKEditor & enable the filter
  3. Add new content using the text format
  4. Insert an <aside> element with text inside and around.
  5. Save Changes
  6. Edit
  7. Save Changes
  8. Edit
  9. Save Changes
  10. Edit
  11. Note that every time you edit, more empty lines are added

The problem seems to lie with this replacement:
.replace(new RegExp("([\\s\\S]+?)\\n\\n", "mg"),"<p>$1</p>\n")

When I use regex101.org to play with this replacement with an example I can see how the problem arises...

Before replacement:

<aside>
  Paragraph 1

  Paragraph 2

</aside>


After replacing ([\s\S]+?)\n\n with <p>$1</p>\n:

<p><aside>
  Paragraph 1</p>
<p>  Paragraph 2</p>
<p></aside></p>

It's now clear that the problem is with nested paragraphs. In the markup above <p> tags are not just wrapping the paragraphs within the <aside> but are wrapping the <aside> tags as if they were part of the paragraph.

I imagine what happens next is some other filter then comes through and closes the faulty <p> tags, and inserts non-breaking-spaces to retain the paragraphs. Resulting in something like this:

<p>
  &nbsp;
</p>
<aside>
  <p>
    Paragraph 1
  </p>
  <p>  
    Paragraph 2
  </p>
  <p>
    &nbsp;
  </p>
</aside>

... and more similar empty lines are added on each edit.

Proposed resolution

I'd think that .replace(new RegExp("([\\s\\S]+?)\\n\\n", "mg"),"<p>$1</p>\n") probably needs to be adjusted to account for scenarios like this, or the way the markup is prepared before the replacement is done in a way which means <aside>, <div> and other similar potential parent elements of a paragraph are not captured by the regular expression.

Remaining tasks

  • Propose a working alternative (maybe borrowing from working approaches which are used elsewhere in the JS)
  • Review
  • Merge

User interface changes

Allows the safe use of div-like elements which paragraphs can safely be nested inside without producing anomalous extra line breaks.

API changes

Proposed changes to the javascript

Data model changes

None

🐛 Bug report
Status

Active

Version

2.0

Component

Code

Created by

🇬🇧United Kingdom jacobupal Leeds

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Production build 0.71.5 2024