I’m trying to use CKEditor5 here to correctly cast an SVG sprite element and display it as a widget, but unfortunately I’m only partially succeeding.
The HTML element to be cast looks like this:
<svg class="fas fa-backward svgsprite" style="color:red;" fill="currentColor" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
<use href="/localpath/sprites/solid.svg#backward">
</svg>
Essentially, so far I’ve managed to get the upcast of the elements to the model to work:


The dataDowncast also works as expected:

And the view element also seems to be correct from my point of view:

However, I have the problem that the editingDowncast does not work as I would expect:

On the one hand, the widget cannot be selected and moved, and on the other hand, no SVG is displayed at all (which is the primary point of this question).
The relevant parts of the code I use look like this:
export class IconpackEditing extends Plugin {
init() {
this._defineSchema();
this._defineConverters();
}
_defineSchema() {
const schema = this.editor.model.schema;
schema.register('svgSprite', {
allowAttributes: ['class', 'style', 'viewBox', 'fill', 'xmlns'],
allowWhere: '$text',
isInline: true,
isObject: true,
isLimit: true,
allowChildren: 'svgSpriteUse',
});
schema.register('svgSpriteUse', {
allowAttributes: ['href'],
allowIn: 'svgSprite',
allowEmpty: true,
});
this.editor.editing.view.domConverter.inlineObjectElements.push('svgSprite');
schema.addChildCheck((context, childDefinition) => {
if (context.endsWith('svgSpriteUse') && childDefinition.name == 'svgSprite') {
return false;
}
});
}
/**
* SVG Sprite converters
*/
_defineConverters() {
const conversion = this.editor.conversion;
conversion.for('upcast').elementToElement({
view: {
name: 'use',
attributes: ['href']
},
model: (viewElement, { writer: modelWriter }) => {
return modelWriter.createElement( 'svgSpriteUse', viewElement.getAttributes());
},
converterPriority: 'highest'
});
conversion.for('dataDowncast').elementToElement({
model: 'svgSpriteUse',
view: (modelElement, { writer }) => {
return writer.createContainerElement('use', modelElement.getAttributes());
}
});
conversion.for('editingDowncast').elementToElement({
model: 'svgSpriteUse',
view: (modelElement, { writer: viewWriter }) => {
return viewWriter.createContainerElement('use', modelElement.getAttributes());
}
});
conversion.for('upcast').elementToElement({
view: {
name: 'svg',
classes: 'svgsprite'
},
model: (viewElement, { writer: modelWriter }) => {
return modelWriter.createElement('svgSprite', viewElement.getAttributes());
},
converterPriority: 'highest'
});
conversion.for('dataDowncast').elementToElement({
model: 'svgSprite',
view: (modelElement, { writer }) => {
return writer.createContainerElement('svg', modelElement.getAttributes());
},
});
conversion.for('editingDowncast').elementToElement({
model: 'svgSprite',
view: (modelElement, { writer: viewWriter }) => {
const viewElement = viewWriter.createContainerElement('svg', modelElement.getAttributes());
viewElement._addClass('ck-widget-svgicon');
return toWidget(viewElement, viewWriter, { label: 'SVG icon widget' });
}
});
}
}
I have tried all settings for the editingDowncast and also checked if there is something wrong with the paths. But the paths are 100% correct (even if I replaced them in this example with localpath) and in the same document the SVG element can be displayed …but unfortunately not in the CKEditor and I just can’t figure out what I’m doing wrong here.
I would be grateful for any help!