Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clicking on the bullet point of an unordered list item causes subsequent keystrokes to be appended to the item when they should be prepended #4600

Open
jn123456789 opened this issue Feb 12, 2025 · 0 comments

Comments

@jn123456789
Copy link

jn123456789 commented Feb 12, 2025

Problem

Users have reported a problem that occurs when they try to edit an item in an unordered list. If they begin by clicking on the first character of text in the list item, everything is fine; subsequent keystrokes are prepended to the item as we would expect. But if they begin by clicking directly on the bullet point of the item, subsequent keystrokes will be appended to the item text.

I made a screen recording that demonstrates the problem: https://www.loom.com/share/50a72af540044d43b0570f5eb3e0a5ec

I think the problem may also occur with ordered lists, but I didn't test that.

That screen recording was made using the official playground site, https://quilljs.com/playground, which is running quill 2.0.3, and it has this bug. My own project is using quill 2.0.2, and it has the same bug.

For the record, I also found an old version of the playground site, https://v1.quilljs.com/playground/, which seems to be using quill 2.0.0-beta.0, and I was not able to reproduce the bug there. I don't know if that's reliable evidence of anything or just a red herring, but I thought I should mention it.

Details

I captured some of the data being passed back and forth through ShareDB in a few scenarios of how a user might begin to edit an item in a bullet list. I hope this can be useful to someone who understands the details of how this piece works.

Initial state

Initial QuillJS ops:

{ "insert": "Hello there! Here's a list:\none" }
{ "insert": "\n", "attributes": { "list": "bullet" } }
{ "insert": "two" }
{ "insert": "\n", "attributes": { "list": "bullet" } }
{ "insert": "three" }
{ "insert": "\n", "attributes": { "list": "bullet" } }

Clicking at the end of the first item and typing "x"

Submitted ShareDB ops (see https://share.github.io/sharedb/api/doc#submitop):

{"p":["b","0","f","1","v"],"t":"rich-text","o":[{"retain":31},{"insert":"x"}],"u":"ns7fn4a0u8np"}

Resulting QuillJS ops (an "x" has been appended to the first list item, as expected):

{ "insert": "Hello there! Here's a list:\nonex" }
{ "insert": "\n", "attributes": { "list": "bullet" } }
{ "insert": "two" }
{ "insert": "\n", "attributes": { "list": "bullet" } }
{ "insert": "three" }
{ "insert": "\n", "attributes": { "list": "bullet" } }

Clicking at the start of the second item (to the right of the bullet point) and typing "x"

Submitted ShareDB ops:

{"p":["b","0","f","1","v"],"t":"rich-text","o":[{"retain":32},{"insert":"x"}],"u":"ns7fn4a0u8np"}

Resulting QuillJS ops (an "x" has been prepended to the second list item, as expected):

{ "insert": "Hello there! Here's a list:\none" }
{ "insert": "\n", "attributes": { "list": "bullet" } }
{ "insert": "xtwo" }
{ "insert": "\n", "attributes": { "list": "bullet" } }
{ "insert": "three" }
{ "insert": "\n", "attributes": { "list": "bullet" } }

Clicking directly on the bullet point of the second item and typing "x"

Submitted ShareDB ops:

{"p":["b","0","f","1","v"],"t":"rich-text","o":[{"retain":35},{"insert":"x"}],"u":"ns7fn4a0u8np"}

Resulting QuillJS ops (an "x" has been appended to the second list item, instead of being prepended):

{ "insert": "Hello there! Here's a list:\none" }
{ "insert": "\n", "attributes": { "list": "bullet" } }
{ "insert": "twox" }
{ "insert": "\n", "attributes": { "list": "bullet" } }
{ "insert": "three" }
{ "insert": "\n", "attributes": { "list": "bullet" } }

Analysis

When the user clicks directly on a bullet point for a list item (as opposed to clicking on the item's text), the value of retain for subsequent insert operations is computed incorrectly. It seems that when the user clicks on a bullet point for a given list item, that event is associated not with the quill op that specifies the text of the item, but with the next op in the list, which both inserts a newline character and retroactively applies a bullet point styling to the previous op. This seems to be throwing off the calculation of retain.

The calculation of this retain value is very obscure to me, but could we solve this problem by making a special case to detect this pattern and adjust the calculation for it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant