quill
quill copied to clipboard
Custom inline blot is being rendered multiple times when pressing ENTER
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
- Visit https://codepen.io/anon/pen/OExJvW
- Enter "Hello "
- Then press the Macro button in the example
- 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
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 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).
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.
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.
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());
})
}
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: