Skip to content
Snippets Groups Projects
Commit a6f2a4c2 authored by Marius Dumitru Florea's avatar Marius Dumitru Florea
Browse files

XWIKI-22290: The edited content is re-rendered even when no macro is modified

* Ignore the inline flag of XWiki macro widgets when comparing the new with the old content (because it depends on the macro output which is not synced).
parent a3f67585
No related branches found
No related tags found
No related merge requests found
......@@ -235,7 +235,7 @@ define('xwiki-ckeditor-realtime-adapter', [
// name and data. We can only update an existing widget in a generic way if its type doesn't change.
const widgetPlaceholder = widgetWrapper.ownerDocument.createElement('xwiki-widget-' + widget.name);
widgetPlaceholder.classList.add('xwiki-widget');
widgetPlaceholder.setAttribute('value', JSONSortify(widget.data));
widgetPlaceholder.setAttribute('value', this._serializeWidgetData(widget));
widgetPlaceholder.dataset.widgetId = widget.id;
widgetWrapper.replaceWith(widgetPlaceholder);
......@@ -266,7 +266,7 @@ define('xwiki-ckeditor-realtime-adapter', [
// data is an object and this makes the check always return false. The problem with this is that when the data
// event is fired the scroll postion is updated, making it hard to scroll the content while remote changes are
// applied (the scroll bar jumps). So we have to check ourselves if the data has changed.
if (widgetData !== JSONSortify(widget.data)) {
if (widgetData !== this._serializeWidgetData(widget)) {
widgetData = JSON.parse(widgetData);
widget.setData(widgetData);
}
......@@ -314,6 +314,27 @@ define('xwiki-ckeditor-realtime-adapter', [
this._widgetCache = {};
}
_serializeWidgetData(widget) {
// Clone the data so that we can modify it without affecting the widget.
const data = JSON.parse((JSON.stringify(widget.data)));
if (widget.name === 'xwiki-macro') {
// Whether a macro widget is inline or block depends on the macro output, which is not synchronized and thus is
// missing from the new content that we want to apply to the editor. When the macro widgets from the new content
// are initialized the inline flag is set (in the absence of the macro outut) based on the siblings and the
// parent of the macro widget. But there are cases where the macro can be both inline and block in the same
// context (parent and siblings) so we don't know for sure if the original macro widget was inline or block
// (e.g. an info box can technically be both inline and block inside a table cell because a table cell accepts
// both inline and block level content). We had two options:
// * include information about whether a macro widget is inline or block in the content that we synchronize (so
// that the inline flag is properly set when the macro widgets from the new content are initialized)
// * ignore the inline flag when computing the changes between the old and the new content
// We chose the second option because it's simpler and because the user can't change only the inline flag
// without also changing either the macro parameters and content or the context where the macro is called.
delete data.inline;
}
return JSONSortify(data);
}
async _updateWidgets(updatedNodes) {
// Reset the focused and selected widgets, as well as the widget holding the focused editable because they may
// have been invalidated by the DOM changes.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment