I’m building an attachments plugin for CKEditor 5. Working from the inline widget example, I’ve been able to create the functionality for adding and removing a custom widget. I’m adding server-side checks to ensure that attachments are valid in case paste or undo cause attachment widgets to be created. If they aren’t, the client needs to replace the attachment widget with some error text. So far I’ve been able to remove the widget, but inserting a text node causes an exception: ‘CKEditorError: model-createpositionat-offset-required’. The exception isn’t thrown until after the callback function returns.
//Invalid attachments are in props.failedLocks and props.notFound
model.change(writer =>
{
let range = writer.model.createRangeIn(writer.model.document.getRoot());
let toReplace = [];
for(let value of range.getWalker({ignoreElementEnd: true}))
{
let element = value.item;
if(element.name === 'attachmentwidget' && element.hasAttribute('key'))
{
let key = element.getAttribute('key') ?? null;
if(key !== null)
{
let errorText = null;
if(props.notFound.indexOf(key) > -1)
{
let title = element.getAttribute('title') ?? null;
errorText = '<<Error: attachment not found' + (title ? ' (' + title + ')': '') + '>>';
}
else if(key in props.failedLocks)
{
errorText = writer.createText('<<Error: failed to lock attachment (' + props.failedLocks[key].title + ')>>', {bold: true});
}
if(errorText !== null)
{
toReplace.push({element: element, errorText: errorText});
}
}
}
}
for(let i = 0; i < toReplace.length; i++)
{
let errorElement = writer.createElement('span', { style: 'color:red;' });
writer.insert(writer.createText(toReplace[i].errorText, {bold: true}), errorElement);
//If I remove this line, the error goes away
writer.insert(errorElement, writer.createPositionBefore(toReplace[i].element));
writer.remove(toReplace[i].element);
}
});