Widget reuse between Decoration.replace and Decoration.widget

It seems like widgets that go from a Decoration.replace to a Decoration.widget are not able to be reused due to a block type check, even if they implement the widget eq and updateDOM correctly.

Is there any particular reason why this case is restricted? I’m running into a rather common use case where I’m switching a widget between a “replacement” and a “block after” depending on whether the selection is in the text, and I’m seeing the widgets constantly re-generated as the cursor scans through.

One alternative I have considered before is always emitting the widget as a “block after” and using an additional replacement decoration to hide the text, but doing so causes the widget to no longer be associated with being the text replacement, which would cause adverse interactions with the selection. For example, it would cause selection starting from the widget to always “anchor” to the end of the replaced text, rather than finding the closest position before or after the replacement text.

Here is an example:

Cursor moved outside of text:

Cursor in text:

This is especially unpleasant when the widget uses an <iframe> (for example, a YouTube embed), as it gets regenerated every time the element is moved around the DOM.

This seems unproblematic to support. See this patch.

1 Like

Yay! Thank you!