Widget should be removed.
Widget is removed from model, but not from view and remains visible
Hopefully it will be clear from this recording:

I also tried with the example Placeholder inline widget but that one was behaving correctly. I have a suspicion that this is caused by the fact that my inline widget uses UI element.
If you'd like to see this fixed sooner, add a 👍 reaction to this post.
Hi, thanks for the report. Could you share some minimal amount of code which allows to reproduce the problem? Without seeing it, it's impossible to find a source of the problem.
Here's the minimal plugin which can reproduce the problem. Just execute referenceLink command to insert the model element and then you can try the backspace (and as a bonus then Undo will duplicate the view):
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import { toWidget, viewToModelPositionOutsideModelElement } from '@ckeditor/ckeditor5-widget/src/utils';
import Widget from '@ckeditor/ckeditor5-widget/src/widget';
import Command from '@ckeditor/ckeditor5-core/src/command';
export default class ReferenceLink extends Plugin {
static get requires() {
return [ ReferenceLinkEditing ];
}
}
class ReferenceLinkCommand extends Command {
execute() {
this.editor.model.change(writer => {
const referenceLinkEl = writer.createElement('reference');
this.editor.model.insertContent(referenceLinkEl);
writer.setSelection(referenceLinkEl, 'after');
});
}
refresh() {
const model = this.editor.model;
const selection = model.document.selection;
this.isEnabled = model.schema.checkChild(selection.focus.parent, 'reference');
}
}
class ReferenceLinkEditing extends Plugin {
static get requires() {
return [ Widget ];
}
init() {
this._defineSchema();
this._defineConverters();
this.editor.commands.add( 'referenceLink', new ReferenceLinkCommand( this.editor ) );
this.editor.editing.mapper.on(
'viewToModelPosition',
viewToModelPositionOutsideModelElement( this.editor.model,
viewElement => viewElement.hasClass( 'reference-link' ) )
);
}
_defineSchema() {
const schema = this.editor.model.schema;
schema.register( 'reference', {
// Allow wherever text is allowed:
allowWhere: '$text',
isInline: true,
// The inline widget is self-contained so it cannot be split by the caret and it can be selected:
isObject: true
} );
}
_defineConverters() {
const editor = this.editor;
const conversion = editor.conversion;
conversion.for( 'upcast' ).elementToElement( {
view: {
name: 'a',
classes: [ 'reference-link' ]
},
model: ( viewElement, modelWriter ) => {
return modelWriter.createElement( 'reference' );
}
} );
conversion.for( 'editingDowncast' ).elementToElement( {
model: 'reference',
view: ( modelItem, viewWriter ) => {
const referenceLinkView = viewWriter.createUIElement('a', {
class: 'reference-link'
}, function( domDocument ) {
const domElement = this.toDomElement( domDocument );
// dummy, normally there's more code which is irrelevant though
domElement.innerText = 'Hello!';
return domElement;
});
// Enable widget handling on a reference element inside the editing view.
return toWidget( referenceLinkView, viewWriter );
}
} );
conversion.for( 'dataDowncast' ).elementToElement( {
model: 'reference',
view: ( modelItem, viewWriter ) => {
return viewWriter.createContainerElement( 'a', {
class: 'reference-link'
} );
}
} );
}
}
Thanks for the details. As you noticed, your issue occurs because you use UI element in your model \<--> view conversion. You cannot convert a model element to a UI element. UI elements need to be created for markers or as additional elements inside normal container elements.
Is there a reason for using UI elements in your code?
After changing the editingDowncast conversion to use container element, everything works fine:
conversion.for( 'editingDowncast' ).elementToElement( {
model: 'reference',
view: ( modelItem, viewWriter ) => {
const referenceLinkView = viewWriter.createContainerElement( 'a', {
class: 'reference-link'
} );
const innerText = viewWriter.createText( 'Hello!' );
viewWriter.insert( viewWriter.createPositionAt( referenceLinkView, 0 ), innerText );
// Enable widget handling on a reference element inside the editing view.
return toWidget( referenceLinkView, viewWriter );
}
} );
Reason for using UI element was that I do some custom (async) rendering there. But I didn't realize UI element must be inside container element. Reason I thought this was a bug was that my code was working in the previous versions (18 and earlier) and seemed to break only in v19 (or perhaps v19.1), but now it looks like I was just using it wrong.
Anyway, I tried to just wrap my UI element into a Container element and now everything works as expected.
Thanks!
Most helpful comment
Thanks for the details. As you noticed, your issue occurs because you use UI element in your model \<--> view conversion. You cannot convert a model element to a UI element. UI elements need to be created for markers or as additional elements inside normal container elements.
Is there a reason for using UI elements in your code?
After changing the
editingDowncastconversion to use container element, everything works fine: