From 54746012d37c457d4c2f32d419b03f21cd8718f9 Mon Sep 17 00:00:00 2001 From: Benoit Socias Date: Fri, 16 Dec 2022 15:00:25 +0000 Subject: [PATCH] [FIX] web_editor, website: avoid updating the DOM when selecting a link When `link_tools` was introduced at [1], `_onURLInput` did only update the configuration form and did not touch the edited DOM. Even though its name would be misleading for that purpose, it was therefore used without issue as an event handler responding to the configuration form input events and as a private method called in the `start` method of the widget lifecycle. At a later stage, with [2], DOM modifications were introduced in `_onURLInput` (using the misleading `_adaptPreview` method whose refactoring at [3] made it update the configuration form only in the case of the "Link Dialog" but update the actual link DOM for the "Link tools" (website / mass mailing)). This commit fixes that behavior by touching what is strictly necessary in stable to keep the original intend of `_onURLInput` (updating the configuration UI) but at the same time update the DOM following configuration form input events (as intended by [2]). In master, all of this should be reviewed. Here are steps which revealed the problem. Although, meanwhile, [4] and its parents were merged which fixed other parts of this issue but keeping the potentially problematic DOM update on selection as described above. Notice that [4] and its parents may be reviewed further in a future update. - Edit Home page - Drop a "Banner" block - Select the "Contact Us" button - Select "Custom" style in the link tool - Select a fill color - Deselect the button by clicking on the Banner's text - Select the button again => Button is redrawn without its color [1]: https://github.com/odoo/odoo/commit/740168ce8d27da3d6a7156d2d79655a898394923 [2]: https://github.com/odoo/odoo/commit/226c4c4032c26d3d8f622b29fb151fa8e78ba70a [3]: https://github.com/odoo/odoo/commit/4a1d776243b059d423152bd026bb8bc758477224 [4]: https://github.com/odoo/odoo/commit/eb4edac560227b46efdcfe958e3b93e0b88def64 opw-3086198 task-3096806 X-original-commit: da25eadde299b81b78d84678978b7e1f703530cc Part-of: odoo/odoo#108812 Co-authored-by: qsm-odoo --- .../static/src/js/wysiwyg/widgets/link.js | 25 ++++++++++++++++--- .../src/js/wysiwyg/widgets/link_dialog.js | 1 + .../src/js/wysiwyg/widgets/link_tools.js | 9 +++++++ .../static/src/js/editor/widget_link.js | 3 --- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/addons/web_editor/static/src/js/wysiwyg/widgets/link.js b/addons/web_editor/static/src/js/wysiwyg/widgets/link.js index 8b5f988bbc9..8e99f888bbe 100644 --- a/addons/web_editor/static/src/js/wysiwyg/widgets/link.js +++ b/addons/web_editor/static/src/js/wysiwyg/widgets/link.js @@ -17,7 +17,7 @@ const Link = Widget.extend({ events: { 'input': '_onAnyChange', 'change': '_onAnyChange', - 'input input[name="url"]': '_onURLInput', + 'input input[name="url"]': '__onURLInput', 'change input[name="url"]': '_onURLInputChange', }, @@ -485,6 +485,23 @@ const Link = Widget.extend({ this._adaptPreview(); } }, + /** + * @todo Adapt in master: in stable _onURLInput was both used as an event + * handler responding to url input events + a private method called at the + * widget lifecycle start. Originally both points were to update the link + * tools/dialog UI. It was later wanted to actually update the DOM... but + * should only be done in event handler part. + * + * This allows to differentiate the event handler part. In master, we should + * take the opportunity to also update the `_updatePreview` concept which + * updates the "preview" of the original link dialog but actually updates + * the real DOM for the "new" link tools. + * + * @private + */ + __onURLInput: function () { + this._onURLInput(...arguments); + }, /** * @private */ @@ -495,10 +512,10 @@ const Link = Widget.extend({ let isLink = value.indexOf('@') < 0; this.$('input[name="is_new_window"]').closest('.row').toggleClass('d-none', !isLink); this.$('.o_strip_domain').toggleClass('d-none', value.indexOf(window.location.origin) !== 0); - this.options.wysiwyg && this.options.wysiwyg.odooEditor.historyPauseSteps('_onURLInput'); - this._adaptPreview(); - this.options.wysiwyg && this.options.wysiwyg.odooEditor.historyUnpauseSteps('_onURLInput'); }, + /** + * @private + */ _onURLInputChange: function () { this._adaptPreview(); this._savedURLInputOnDestroy = false; diff --git a/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js b/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js index 3acf848e136..e09e4fa3c42 100644 --- a/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js +++ b/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js @@ -160,6 +160,7 @@ const _DialogLinkWidget = Link.extend({ _onURLInput: function () { this._super(...arguments); this.$('#o_link_dialog_url_input').closest('.o_url_input').removeClass('o_has_error').find('.form-control, .form-select').removeClass('is-invalid'); + this._adaptPreview(); }, }); diff --git a/addons/web_editor/static/src/js/wysiwyg/widgets/link_tools.js b/addons/web_editor/static/src/js/wysiwyg/widgets/link_tools.js index 927900c8f25..f126d3a6b10 100644 --- a/addons/web_editor/static/src/js/wysiwyg/widgets/link_tools.js +++ b/addons/web_editor/static/src/js/wysiwyg/widgets/link_tools.js @@ -425,6 +425,15 @@ const LinkTools = Link.extend({ this.options.wysiwyg.odooEditor.historyStep(); } }, + /** + * @override + */ + __onURLInput() { + this._super(...arguments); + this.options.wysiwyg.odooEditor.historyPauseSteps('_onURLInput'); + this._adaptPreview(); + this.options.wysiwyg.odooEditor.historyUnpauseSteps('_onURLInput'); + }, }); return LinkTools; diff --git a/addons/website/static/src/js/editor/widget_link.js b/addons/website/static/src/js/editor/widget_link.js index b1f887b89f5..9de80f11e25 100644 --- a/addons/website/static/src/js/editor/widget_link.js +++ b/addons/website/static/src/js/editor/widget_link.js @@ -5,9 +5,6 @@ var weWidgets = require('wysiwyg.widgets'); var wUtils = require('website.utils'); weWidgets.LinkTools.include({ - events: _.extend({}, weWidgets.LinkTools.prototype.events || {}, { - 'input input[name="url"]': '_onURLInput', - }), custom_events: _.extend({}, weWidgets.LinkTools.prototype.custom_events || {}, { website_url_chosen: '_onAutocompleteClose', }),