slab / quill

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

handleBackspace causes blockembed attributes to be passed into next blot #4364

Open enzedonline opened 2 months ago

enzedonline commented 2 months ago

This behaviour occurs when there are two consecutive videos. If the selection (cursor) is placed between the 2 videos and backspace is pressed to delete the first video, the height and width of the deleted video are transferred to the second video.

This does not occur if the cursor is before the first video and deleted with the delete key. It does not occur if there is a blank line (or other content) separating the two videos.

There are two default Backspace bindings pointing to the handler:

https://github.com/slab/quill/blob/b213e1073bac1478649f26e3c0dad50ad0eb2a49/packages/quill/src/modules/keyboard.ts#L105-L109

https://github.com/slab/quill/blob/b213e1073bac1478649f26e3c0dad50ad0eb2a49/packages/quill/src/modules/keyboard.ts#L126-L136

And, for firefox: https://github.com/slab/quill/blob/b213e1073bac1478649f26e3c0dad50ad0eb2a49/packages/quill/src/modules/keyboard.ts#L94-L98

Removing these from quill.keyboard.bindings.Backspace removes the bug.

Demonstration: The cursor is placed at the end of the first video and backspace pressed to delete the video. After deletion, the second video now has the width & height attributes of the first. The delete is undone, the two loaded keyboard bindings for Backspace that point to handleBackspace are both deleted. The delete action is repeated (cursor between videos, backspace pressed), this time the second video retains its width/height attributes.

https://github.com/user-attachments/assets/c757b415-3190-4c23-8de0-c08e1fbde472

Steps for Reproduction

  1. Standard quill instance
  2. Insert two adjacent videos
  3. Format first with custom height/width
  4. Format second with different height/width
  5. Set cursor between videos, press backspace to delete the first video
  6. See the remaining video size attributes have been replaced with those from the first
  7. Undo delete
  8. Delete Backspace keyboard bindings from quill instance (quill.keyboard.bindings.Backspace)
  9. Set cursor between videos, press backspace to delete the first video
  10. See the remaining video size attributes have not been altered

Version: 2.0.2

enzedonline commented 2 months ago

This is my workaround for now:

      this.quill.keyboard.bindings.Backspace.unshift({
        key: 'Backspace',
        empty: true,
        line: {
          domNode: {
            tagName: "IFRAME"
          }
        },
        handler: (range: any) => {
          this.quill.deleteText(range.index - 1, 1, "user");
        }
      });