From 623729832f6d69abecd6bab7eab296a94dceed4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Geelen=20=28sge=29?= Date: Wed, 15 Mar 2023 15:51:06 +0000 Subject: [PATCH] [FIX] web_editor: fix inline html_field Revert changes made in #101768. Wrong assumption were made in #101768 regarding inline conversion of html field. I though Inline HTML field always had two Field, one for the raw content and one for the inlined content. This is not correct. Some only have one (i.e. email templates). They override the raw version and save the inline version directly. In those case the inlining was not saved and was always reverted before saving. This error is corrected here. task-3222474 X-original-commit: 578600c506fab1461863decdaecaa414f6530eab Part-of: odoo/odoo#124020 --- .../static/src/js/backend/html_field.js | 5 ++- .../js/editor/odoo-editor/src/OdooEditor.js | 34 +++++++++++-------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/addons/web_editor/static/src/js/backend/html_field.js b/addons/web_editor/static/src/js/backend/html_field.js index 9b396634681..9632128e211 100644 --- a/addons/web_editor/static/src/js/backend/html_field.js +++ b/addons/web_editor/static/src/js/backend/html_field.js @@ -570,8 +570,6 @@ export class HtmlField extends Component { const html = this.wysiwyg.getValue(); const $odooEditor = $editable.closest('.odoo-editor-editable'); // Save correct nodes references. - const originalContents = document.createDocumentFragment(); - originalContents.append(...$editable[0].childNodes); // Remove temporarily the class so that css editing will not be converted. $odooEditor.removeClass('odoo-editor-editable'); $editable.html(html); @@ -579,7 +577,8 @@ export class HtmlField extends Component { await toInline($editable, this.cssRules, this.wysiwyg.$iframe); $odooEditor.addClass('odoo-editor-editable'); - $editable[0].replaceChildren(...originalContents.childNodes); + this.wysiwyg.setValue($editable.html()); + this.wysiwyg.odooEditor.sanitize(this.wysiwyg.odooEditor.editable); } async _getWysiwygClass() { return getWysiwygClass(); diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js b/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js index 4b5473145b1..4149edf2245 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js @@ -707,7 +707,7 @@ export class OdooEditor extends EventTarget { resetContent(value) { value = value || '


'; this.editable.innerHTML = value; - this.sanitize(); + this.sanitize(this.editable); this.historyStep(true); // The unbreakable protection mechanism detects an anomaly and attempts // to trigger a rollback when the content is reset using `innerHTML`. @@ -719,17 +719,22 @@ export class OdooEditor extends EventTarget { } } - sanitize() { + sanitize(target) { this.observerFlush(); - let commonAncestor, record; - for (record of this._currentStep.mutations) { - const node = this.idFind(record.parentId || record.id) || this.editable; - commonAncestor = commonAncestor - ? commonParentGet(commonAncestor, node, this.editable) - : node; + let record; + if (!target) { + // If the target is not given, + // find the closest common ancestor to all the nodes referenced + // in the mutations from the last step. + for (record of this._currentStep.mutations) { + const node = this.idFind(record.parentId || record.id) || this.editable; + target = target + ? commonParentGet(target, node, this.editable) + : node; + } } - if (!commonAncestor) { + if (!target) { return false; } @@ -741,15 +746,16 @@ export class OdooEditor extends EventTarget { //
  • // : these two lists should be merged together so the common // ancestor should be the
      element). - const nestedListAncestor = closestElement(commonAncestor, '.oe-nested'); + const nestedListAncestor = closestElement(target, '.oe-nested'); if (nestedListAncestor && nestedListAncestor.parentElement) { - commonAncestor = nestedListAncestor.parentElement; + target = nestedListAncestor.parentElement; } // sanitize and mark current position as sanitized - sanitize(commonAncestor); - this._pluginCall('sanitizeElement', [commonAncestor]); - this.options.onPostSanitize(commonAncestor); + sanitize(target); + this._pluginCall('sanitizeElement', + [target.parentElement]); + this.options.onPostSanitize(target); } addDomListener(element, eventName, callback) {