Inconsistent cursor position for a widget created by Decoration.replace in Chrome and Safari


I have a simple widget created using the following code:

let deco = Decoration.replace({
              widget: new CheckWidget(checked),
              inclusive: true,

The blinking cursor’s position is after the widget in Chrome, which is expected; however, it is before the widget in Safari, which seems to be incorrect:

Screen Shot 2021-05-31 at 2.25.38 PM

Screen Shot 2021-05-31 at 2.25.45 PM

Could you review this and check if this is a bug? Thanks a lot!

Are you using @codemirror/view 0.18.14? That fixes a bug that may be related to this. If that doesn’t help, is the cursor just drawn incorrectly, or is it also incorrect in state.selection?

I upgraded to 0.18.14 but the issue still exists. I think it’s just the currsor is drawn incorrectly in Safari. The selection is correct. I made a screen recording:
Jun-01-2021 22-15-55

And in Chrome it’s working as expected:
Jun-01-2021 22-17-18

Can you set up a minimal demo (just an editor with a widget, without any extra logic) that demonstrates the issue?


I created this minimal demo in this branch GitHub - fuermosi777/markword at incorrect-cursor-pos

Need to download the code and run yarn install and then yarn dev, then visit

The entry file is this one.
The plugin it loads for the task widget is this one

Should be able to see something like this:
Screen Shot 2021-06-02 at 7.05.15 PM

Thank you.

Hey, thanks for setting up a github repository, but there’s still a lot of code in there. What I was talking about was a simple script that just creates a widget in a vanilla editor, so that I don’t have to deal with a lot of peripheral complexity to figure out what is causing this. I can’t reproduce the issue when I just add an <input type=checkbox> with side = -1 as a widget.

Thank you. I managed to create a smaller piece of code: codemirror-6-checkbox - StackBlitz

Will this help?

Ah, you are using the native selection. That does indeed produce a very weird cursor on Safari in this situation.The only workaround I could find for that is to wrap the widget in a span and put zero-width spaces on both sides of the checkbox. Setting the selection differently from the library side doesn’t appear to be able to affect this. Any reason you’re not using drawSelection?

Ah. I never knew the existence of drawSelection. I tried it and it does solve the issue. Thanks for looking into this!