Backspace on decoration work strangely in mobile keyboard

I want to replace emoji with custom element, here I use span element instead my component.

The deletion is work perfectly on desktop browser.
When I using mobile to test, it will just selecting the decoration, keyboard hide and show again, then the decoration will not be deleted.
This only happen on using English Gboard keyboard, no problem on other Gboard languages.


Here is my code:

import { MatchDecorator, Decoration, WidgetType, EditorView, ViewPlugin, DecorationSet, ViewUpdate } from "@codemirror/view";

class EmojiWidget extends WidgetType {
    text: string;
    constructor(text: string) {
        this.text = text;
    toDOM(view: EditorView): HTMLElement {
        const span = document.createElement('span');
        return span

const emojiMatcher = new MatchDecorator({
    regexp: /\p{Emoji_Presentation}/gu,
    decoration: match => Decoration.replace({
        widget: new EmojiWidget(match[0])

export const emojiPlugin = ViewPlugin.fromClass(class {
    decorations : DecorationSet;
    constructor(view : EditorView) {
        this.decorations = emojiMatcher.createDeco(view)
    update(update : ViewUpdate) {
        this.decorations = emojiMatcher.updateDeco(update, this.decorations)
}, {
    decorations: instance => instance.decorations,
    provide: plugin => EditorView.atomicRanges.of(view => {
        const value = view.plugin(plugin);
        return value ? value.decorations : Decoration.none;

I also tried input on this example editor, deletion is not working.

Thanks, I managed to reproduce this. This patch seems to help.

1 Like

I test the newest version on Android. The backspace deletion still have the same bug.

I was only able to reproduce this on the decoration demo, not on the code you pasted. That problem was fixed by the patch I linked. Your example doesn’t actually create an editor view, so I’m not entirely sure what you may be doing. Are you sure you are including a keymap that actually binds backspace in your configuration?

I am using defaultKeymap and that included standardKeymap, backspace are work normally on other situation.
I try on demo, deletion also work on my device, but keyboard will hide and show again.

I found the one of reason that backspace not work correctly, if my custom element is fill with text only, then deletion is working (but keyboard still hide and show again). If fill with emoji character or image element, deletion will be crashed.

The hiding of the keyboard is a chrome bug that CodeMirror cannot really do anything about. I cannot reproduce the thing where the widget is not deleted in your demo. But since it doesn’t provide any content for the editor, maybe you are using a different emoji or different text than I am? Could you provide a bit more detailed reproduction instructions?