quill icon indicating copy to clipboard operation
quill copied to clipboard

Custom inline blot is being rendered multiple times when pressing ENTER

Open vasilionjea opened this issue 6 years ago • 5 comments

Hello,

We have decided to use Quill for a project and I'm running into an odd issue where a custom inline Blot is being copied and rendered multiple times when pressing the ENTER key immediately after formatting with my custom Blot.

Steps for Reproduction

  1. Visit https://codepen.io/anon/pen/OExJvW
  2. Enter "Hello "
  3. Then press the Macro button in the example
  4. Then press the ENTER key multiple times

Expected behavior: The custom Macro blot shouldn't be copied and rendered multiple times. Simply a new line should be rendered. Actual behavior: It's copied and rendered multiple times.

Platforms: Google Chrome 66, macOS Sierra Version: Quill 1.3.6

vasilionjea avatar Jun 15 '18 05:06 vasilionjea

I found a solution to this: https://codepen.io/anon/pen/MXEXBb Basically I removed the static formats(domNode) definition - not sure if it's even needed. With that said, not totally sure how you'd go about wrapping the text in a span with a classname with this approach.

Another approach is to use an Embed like in this example: https://codepen.io/anon/pen/jKGKbg which works for the most part. The only issue with the Embed approach is that the cursor position "jumps" way to the right without this hack in place: quill.insertText(range.index + 1, ' ', Quill.sources.SILENT).

vasilionjea avatar Jun 15 '18 21:06 vasilionjea

@vasilionjea I think the hack works, but only if the blot contains text with a length of 1. A generic use case would have to use something like quill.insertText(range.index + data.length + 1, ' ', Quill.sources.SILENT).

arslnb avatar Jul 12 '19 11:07 arslnb

I am facing the same problem. Does anyone know a not-hacky solution for this? The first solution mentioned by @vasilionjea does not work for me cause I am not overriding the static formats(domNode) method anyway. The second approach is also not works for me because I am already using insertEmbed method to insert my custom blot. And, even though we use quill.insertText(range.index + data.length + 1, ' ', Quill.sources.SILENT) to insert a emply space after inserting the blot, the user can select the ending of the blot, and press enter. When this happens the second approach becomes useless. So, highly appreciated if anyone can provide a solution.

DevLaka avatar Aug 01 '21 18:08 DevLaka

I have spent hours stepping through Quill source, but the async nature of the DOM Observer that responds to the insert of the first occurrence of the blot makes it very hard to track down where the duplicate call is coming from. However, I finally discovered that beyond setting the base attributes passed in by Quill my code was modifying the DOM during the create function of the custom blot. This can be a result of either adding attribute value of modifying child nodes. By creating a Shadow DOM for the element, I was able to eliminate the Observer invoking Quill to repaint and duplicate my inline nodes.

If you are experiencing the node duplication issue, do a thorough walkthrough of your code looking for DOM modifications.

anywhichway avatar Jul 04 '22 15:07 anywhichway

An additional solution is to give all your inlines an id and then add code something like this:

// total HACK to get rid of Quill bug that inserts duplicate inline blots when they are in any way complex
if(inline) {
                setTimeout(() => { 
                    const nodes = [...document.querySelectorAll(`[id="${attributes.id}"]`)].slice(1);
                    nodes.forEach((node) => node.parentElement.remove());
                })
            }

anywhichway avatar Jul 06 '22 14:07 anywhichway

Quill 2.0 has been released (announcement post) with many changes and fixes. If this is still an issue please create a new issue after reviewing our updated Contributing guide :pray:

quill-bot avatar Apr 17 '24 11:04 quill-bot