slab / quill

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

Spaces are not being preserved while copying in HTML format #4108

Open amigup opened 7 months ago

amigup commented 7 months ago

Spacing between words are not being preserved while copying and pasting to a destination app via HTML format.

Steps for Reproduction

  1. Visit https://codesandbox.io/p/sandbox/quill-copy-space-issue-5j6t64?file=%2Fsrc%2Findex.tsx
  2. Type a word and add few spaces and type another word.
  3. Copy the message from quill Editor
  4. Paste to a app which reads the HTML format
<html>
<body>
<!--StartFragment--><span style="color: rgb(0, 0, 0); font-family: Helvetica, Arial, sans-serif; font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: pre-wrap; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none;">FirstWord                                         AnotherWord</span><!--EndFragment-->
</body>
</html>

Expected behavior: Spacing between word should be preserved on pasting via HTML format image

Actual behavior: Spacing between word are not preserved on pasting via HTML format image

Platforms: Chrome, windows

Version: Quill version 1.3.1

BlakeSearlSonocent commented 1 week ago

We are experiencing the same issue on 2.0.2.

It can be replicated via the Quill playground:

I believe the issue is related to the html that ends up on the clipboard when copying from the quill editor. If you run

setTimeout(async()=> {
    const clipboardContents = await navigator.clipboard.read();
    for (const item of clipboardContents) {
      if (item.types.includes("text/html")) {
        const blob = await item.getType("text/html");   

        const html = await blob.text()
        console.log('html', html);
      }

      const plainText = await navigator.clipboard.readText();
      console.log('plain text', plainText);

    }
}, 3000)

Then the html is <meta charset="utf-8">a a

Because spaces are collapsed by default in html, this results in the spaces being collapsed in to a single space.

In comparison, copying the 'same' text from google docs results in

<meta charset="utf-8"><meta charset="utf-8"><b style="font-weight:normal;" id="docs-internal-guid-85e5c22f-7fff-c3b6-313f-b46412c0e719"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">a&nbsp; a</span></b>

With the seemingly important bit being a&nbsp; a, i.e. using a non-breaking spaces to try and prevent the spaces collapsing.

Note: This still results in a single space when pasted in to the quill editor, the rule seems to be if you have n+1 spaces on the clipboard, then pasting in to the quill editor results in n spaces