IME input may break when cursor is adjacent to widget due to cm-widgetBuffer reconstruction

Description

In Safari, when the cursor is positioned on either side of a widget, IME input may behave unexpectedly.

Even when the widget itself does not change, an IME composition can trigger reconstruction of cm-widgetBuffer nodes. This causes the DOM structure around the composition range to change during input, which may lead to abnormal IME behavior.

For example, given the following DOM layout:

| .cm-widgetBuffer | input | widget | .cm-widgetBuffer |

Although the widget content remains unchanged, this unnecessary reconstruction modifies the DOM during composition and can interrupt or corrupt IME input.

Environment

  • Browser: Safari 26.5 (20624.2.5.18.3)

  • OS: macOS 15.7.7

Demo

This sounds a lot like this issue. Can you still reproduce this with @codemirror/view 6.43.1?

Yes, this issue is reproducible on @codemirror/view@6.43.1.

It seems related to CompositeTile.sync, where the ordering of tile.children becomes inconsistent with the actual DOM order.

In the case of:

| .cm-widgetBuffer | input | widget | .cm-widgetBuffer |

tile.children is iterated as:

TextTile → WidgetBufferTile → WidgetTile → WidgetBufferTile

but the DOM order is:

.cm-widgetBuffer → text → widget → .cm-widgetBuffer

What your demo is doing is always collapsing the second character of the document. And the screenshot suggests you’re seeing the issue when starting a composition after the first character of the document. Which will then immediately be hidden. That this disrupts the composition seems rather obvious. Am I missing something?

Demo has some issues. The point I wanted to demonstrate is that, during view.composing, a DOM update can still be triggered even when the only operation performed is decorationSet.map(update.changes), without any decoration recomputation or recreation.

Looking into this, I found two misbehaviors that may be related to what you’re seeing. But since you didn’t provide a clear reproduction, I am not sure whether the patches below help.