From cf7c78c9cbcada2c2804687d17ed3b3f5a186bd2 Mon Sep 17 00:00:00 2001 From: "Mehdi Outagant (MOU)" Date: Mon, 26 Feb 2024 16:21:13 +0100 Subject: [PATCH] [FIX] web_editor: fix the linktools editing behaviour Steps to reproduce: - Go to website (Homepage) > Switch to "Edit" mode. - double-click the "Contact Us" button in the header or keep clicking it many times > Traceback: Cannot read properties of undefined (reading 'find')... After converting the `linktools` widget to Owl in [1], the DOM element of the component [2] was retrieved in an async process after it was mounted, (some legacy code can trigger the instantiation of the `linktools` when its parent component is not in the DOM and `this.linkComponentWrapperRef.el` won't be returned, see: `Link` > `onMounted`). When double-clicking the link, This implementation will lead to a race condition where the `onWillUpdateProps()` (mainly triggered by the click to focus the URL input...) will try to access the DOM element from [2] before being correctly set in `onMounted()`. The goal of this commit is to fix this behaviour by simply waiting for `onMounted` changes to be done before doing any adaptation on the `linktools` DOM. [1]: https://github.com/odoo/odoo/commit/d7245d2abf528d093226c80e40975e63d61e8997 opw-3706902 closes odoo/odoo#155418 Signed-off-by: David Monjoie (dmo) --- addons/web_editor/static/src/js/wysiwyg/widgets/link.js | 9 +++++++-- .../static/src/js/wysiwyg/widgets/link_tools.js | 3 ++- 2 files changed, 9 insertions(+), 3 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 614a676d18e..4fb94380139 100644 --- a/addons/web_editor/static/src/js/wysiwyg/widgets/link.js +++ b/addons/web_editor/static/src/js/wysiwyg/widgets/link.js @@ -48,6 +48,9 @@ export class Link extends Component { ]; setup() { this.state = useState({}); + // We need to wait for the `onMounted` changes to be done before + // accessing `this.$el`. + this.mountedPromise = new Promise(resolve => this.mountedResolve = resolve); onWillStart(() => this._updateState(this.props)); let started = false; @@ -82,8 +85,10 @@ export class Link extends Component { this.$el.find('[name="url"]').on('change', this._onURLInputChange.bind(this)); await this.start(); + this.mountedResolve(); }); - onWillUpdateProps((newProps) => { + onWillUpdateProps(async (newProps) => { + await this.mountedPromise; this._updateState(newProps); this.state.url = newProps.link.getAttribute('href') || ''; this._setUrl({ shouldFocus: newProps.shouldFocusUrl }); @@ -182,7 +187,7 @@ export class Link extends Component { * Focuses the url input. */ focusUrl() { - const urlInput = this.linkComponentWrapperRef.el.querySelector('input[name="url"]'); + const urlInput = this.$el[0].querySelector('input[name="url"]'); urlInput.focus(); urlInput.select(); } 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 92d1b71bfe0..96d09bc7e35 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 @@ -52,7 +52,8 @@ export class LinkTools extends Link { setup() { super.setup(...arguments); - onWillUpdateProps((newProps) => { + onWillUpdateProps(async (newProps) => { + await this.mountedPromise; this.$link = newProps.link ? $(newProps.link) : this.link; this._setSelectOptionFromLink(); this._updateOptionsUI();