WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.48k stars 4.18k forks source link

Pasting converts an empty span tag into a non-breaking space. #21904

Open nevnein opened 4 years ago

nevnein commented 4 years ago

Describe the bug Pasting a copied text whose HTML contains an empty <span> tag converts the tag into a non-breaking space, even if the spaces around (or inside) the tag are normal spaces.

To reproduce Steps to reproduce the behavior:

  1. Copy a text whose HTML contains an empty <span>, eg. Hello <span></span> World (Hello World)
  2. Paste it on the editor
  3. Check the console or switch to HTML.
  4. See the processed HTML, in our example Hello&nbsp;World

Expected behavior As none of the spaces in or around the empty tag are &nbsp;, the space(s) in the processed HTML should be normal spaces and not &nbsp;.

Editor version

Desktop

Additional context The <span> can be either empty or containing a normal space, result is the same. No classes or other attributes are present on the tag.

This issue is kinda nasty as it causes visualization problems on the front, especially on mobile, because the extra &nbsp;s lead to unexpected text overflows (that can't be mitigated via CSS) and subsequently some strange layout issues and horizontal scrolling.

I've discovered this behavior copy-pasting from random Wikipedia articles to have some rich text dummy content. Strangely enough, the HTML from Wikipedia doesn't contain any empty <span> tags, but the received HTML logged by Gutenberg in the console does.

nevnein commented 4 years ago

May I suggest the [Feature] Raw Handling label?

oxyc commented 4 years ago

I can reproduce it in master.

oxyc commented 4 years ago

So I debugged a bit:

If I have a DOM element with: <p>testing <span></span>empty span</p>, copy it (with twentytwenty) and paste it, rich-text onPaste handler reports:

Received HTML:

 <meta charset='utf-8'><p style="box-sizing: inherit; -webkit-font-smoothing: antialiased; word-break: break-word; overflow-wrap: break-word; border: none; font-size: 21px; line-height: 1.476; margin: 0px auto 1.25em; padding: 0px; text-align: left; max-width: 58rem; width: calc(100% - 4rem); color: rgb(0, 0, 0); font-family: NonBreakingSpaceOverride, &quot;Hoefler Text&quot;, Garamond, &quot;Times New Roman&quot;, serif; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(245, 239, 224); text-decoration-style: initial; text-decoration-color: initial;">testing<span> </span><span style="box-sizing: inherit; -webkit-font-smoothing: antialiased; word-break: break-word; overflow-wrap: break-word;"></span>empty span</p><br class="Apple-interchange-newline">

Notice testing<span> </span>, the space from clipboardData added the space within the <span> instead of outside.

This is then converted to &nbsp; when innerHTML is juggled which can be tested eg by running this in the console:

let doc = document.implementation.createHTMLDocument( '' );
doc.body.innerHTML = '<meta charset="utf-8"><div class="section-container">Click the button<span> </span><span></span>to</div>';
console.log(doc.body.innerHTML);
// <meta charset="utf-8"><div class="section-container">Click the button<span>&nbsp;</span><span></span>to</div>

Seems like this is how ckeditor handles it https://github.com/ckeditor/ckeditor5-clipboard/blob/master/src/utils/normalizeclipboarddata.js#L16.

ping @ellatrix since you're the author of most of these things right? Should this be handled when retrieved from the clipboard or maybe as a general rule somewhere in the pasteHandler?

getsource commented 3 years ago

We tested this in triage today, and three folks were able to reproduce, so adding the Bug label.

A note, though, that it didn't seem to happen every time. It was able to be reproduced most commonly in Chrome, copying from Chrome to Chrome.

torounit commented 3 years ago

This problem still reproduced.

Gutenberg: 10.3.0-rc.1

ellatrix commented 3 years ago

The fix in https://github.com/ckeditor/ckeditor5-clipboard/blob/master/src/utils/normalizeclipboarddata.js#L16 seem good to have. Would be great if someone could try it out.