ueberdosis / tiptap

The headless rich text editor framework for web artisans.
https://tiptap.dev
MIT License
24.64k stars 2.06k forks source link

[PRO]: Gapcursor and focus don't play nicely together #4048

Open carlobeltrame opened 1 year ago

carlobeltrame commented 1 year ago

Which packages did you experience the bug in?

core, gapcursor

What Tiptap version are you using?

2.0.3

What’s the bug you are facing?

When using editor.commands.focus to focus a Gapcursor position, the focus behaves as though the Gapcursor plugin weren't installed.

Steps to reproduce the behavior:

  1. Have an editor with Gapcursor and some block elements
  2. Use editor.commands.focus(position) to focus a position that should result in a Gapcursor (e.g. position 0 in the provided CodeSandbox)
  3. Focusing and typing text works, but the selection never behaves like a gapcursor. When focusing position 0, the selection actually selects the first block element instead of being at a position before it. When typing, this replaces that first block element. To make matters worse, there is currently no indication (outline etc.) anymore that the block element is focused.

What browser are you using?

Firefox

Code example

https://codesandbox.io/s/reverent-hill-tsytji?file=/src/components/Editor.vue

What did you expect to happen?

If the Gapcursor plugin is active, whenever a position is focused, Tiptap should determine whether a Gapcursor or a TextSelection makes more sense at that position. In other words, if you follow the steps to reproduce the bug, and then press the left arrow key, that's the state I'd expect right after calling editor.commands.focus().

Anything to add? (optional)

In the CodeSandbox, I added a FixExtension which fixes the problem. As long as the FixExtension is not activated in the editor, the problem is reproducible.

Prosemirror has to make the same decision in this method already: https://github.com/ProseMirror/prosemirror-gapcursor/blob/master/src/index.js#L56. That function is not exported unfortunately, but according to https://github.com/ProseMirror/prosemirror/issues/1201 we should be able to simply use new GapCursor($resolvedPos) when the gapcursor plugin is installed. Let me know if you'd like me to prepare a PR for this.

This issue is a continuation of the mistakenly closed issues #1899, #3074 and #3658. The problem actually got worse since then, because now it's not just a display issue anymore, but the focus is actually wrong (it focuses the block element instead of the position before it).

:warning: Please don't ignore me :warning:

It is a very bad experience for a contributor like me to have my issues autoclosed when they offer to implement a fix but have never been answered by the maintainers. I even tried to keep the issue alive, but stalebot wouldn't have any of it. I can understand autoclosing issues which wait for more input from the issue reporter, but please consider configuring stalebot to never close issues that haven't even been looked at by a maintainer. If you just tell me to propose a fix PR, I will gladly do it, as stated in the original issue.

Did you update your dependencies?

Are you sponsoring us?

ghost commented 10 months ago

Hi! I just want to say that I've read your previous threads (and here), and I wanted to thank you for continuing to follow up on this.

Originally posted by @sipec:

Another workaround: after focus() do createParagraphNear() which will add a new empty paragraph node and focus it if the currently focused node is a block node (like an image). This only solves some use cases however.

This is an amazing solution. I was having so many issues with custom nodes (in this example), but using the createParagraphNear trick has helped immensely. Thank you both for participating in these threads.

Nantris commented 10 months ago

I think this issue could use a reply from a maintainer since the author has put a lot of time into documenting and fixing this and is willing to propose a PR if willingness to consider it is confirmed.

@svenadlung