zenoamaro / react-quill

A Quill component for React.
https://zenoamaro.github.io/react-quill
MIT License
6.59k stars 905 forks source link

Default blot hijacking custom blot when using same format #278

Open Aaronik opened 6 years ago

Aaronik commented 6 years ago

React-Quill version

Hello,

First off I just want to say thank you for react-quill! As always, OSS holds the world together and your repository is doing no less for me.

The goal:

I'm writing a custom blot. This is to be a format blot. I want to do two things with it: First - add a data-id attribute, second - add a background color (style="background: blue;"). I'll be regularly adding and removing these blots.

The bug:

The default 'background' blot sees that there's a background style in there, and comes in and creates a second blot, with its own <span> tag. The result is instead of having the desired:

<span data-id='1' style="background: blue;"></span>

tag, I have a nested tag:

<span style="background: blue;"><span data-id='1' style="background: blue;"></span></span>

Given this bug, as you would expect, the editor.getContents() delta reflects the secondary blot as well:

image

The behavior this results in is that removing my custom blot only removes the inner <span> tag and the background formatting remains. Confusingly, calling to remove the 'background' tag as well as my custom tag does not work the first time, only the second time around. This piece is not really relevant to my issue though, so I'm not going to elaborate on it.

Hacky Workaround (1/2)

Allow the nested span tags. Make my blot simply add data-id and not background. Use both my blot (which at this point could be an attributor, yes) and the 'background' blot. When it comes time to remove the formatting, both remove my custom blot and remove the default 'background' blot.

Hacky Workaround (2/2)

To keep correct html, override the default background blot. This results in all behavior working correctly, however there's a warning in the console about having overwritten a default blot.

Code pens

I have two pens illustrating the issue in react-quill and how it doesn't exist in regular Quill.

react-quill, with the issue: https://codepen.io/aaronik/pen/yzROLw?editors=0010 Quill, without the issue: https://codepen.io/aaronik/pen/qPMMYd?editors=0010

Hopefully this is clear and helpful. Please let me know if there's any other information I can provide.

alexkrolick commented 6 years ago

I'll look into this more later but it sounds like the error is related to Quill's pasteHTML matching of HTML to Quill blots. If you have 2 formats with similar heuristics it may be possible that they both match.

Things you could try:

Aaronik commented 6 years ago

Yeah I've actually tried both of those, independently and together, and both still leave issues. Whitelisting only 'highlight' and using value results in wonky behavior about the highlight extending to the end of the text. I haven't worked out exactly what happens there. Using only defaultValue results in no change that I can see. Adding both of those things fixes the wonky behavior of just whitelisting 'highlight', but again results in no change that I can find from the original bug.

alexkrolick commented 6 years ago

Here's a demo with pure Quill that uses the same clipboard.dangerouslyPasteHTML method that RQ uses to restore HTML content: https://codepen.io/alexkrolick/pen/gGJEPa?editors=0010

It has the same issue.

alexkrolick commented 6 years ago

Have you tried writing a custom matcher to associate pasted data with your formats? https://quilljs.com/docs/modules/clipboard/#matchers