From 024471e37f417cb20ce0006306cc0eb1ca938bc1 Mon Sep 17 00:00:00 2001
From: Rodolpho Lima <rcdl@odoo.com>
Date: Fri, 14 Apr 2023 19:40:21 +0200
Subject: [PATCH] [FIX] web_editor: update link content on URL change

If a link's content is equivalent to its URL, two problems can arise
when its URL is changed via the LinkTools:
- The link's content becomes outdated, showing a different URL;
- On LinkTools destroy, the OdooEditor mechanism that updates a link's
href on label(content) change will update the href according to the old
label, effectively reverting the changes in the URL.

This commit avoids such issues by syncing the label with the URL input
field in such cases.

task-3284649

Part-of: odoo/odoo#118676
---
 .../src/js/wysiwyg/widgets/link_tools.js      | 26 +++++++++++++++++++
 1 file changed, 26 insertions(+)

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 8cb0ec693cd7..2c20294ce299 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
@@ -470,9 +470,35 @@ const LinkTools = Link.extend({
     __onURLInput() {
         this._super(...arguments);
         this.options.wysiwyg.odooEditor.historyPauseSteps('_onURLInput');
+        this._syncContent();
         this._adaptPreview();
         this.options.wysiwyg.odooEditor.historyUnpauseSteps('_onURLInput');
     },
+    /**
+     * If content is equal to previous URL, update it to match current URL.
+     *
+     * @private
+     */
+    _syncContent() {
+        const previousUrl = this._link.getAttribute('href');
+        if (!previousUrl) {
+            return;
+        }
+        const protocolLessPrevUrl = previousUrl.replace(/^https?:\/\/|^mailto:/i, '');
+        const content = this._link.innerText;
+        if (content === previousUrl || content === protocolLessPrevUrl) {
+            const newUrl = this.el.querySelector('input[name="url"]').value;
+            const protocolLessNewUrl = newUrl.replace(/^https?:\/\/|^mailto:/i, '')
+            const newContent = content.replace(protocolLessPrevUrl, protocolLessNewUrl);
+            this._observer.disconnect();
+            // Update link content with `force: true` otherwise it would fail if
+            // new content matches `originalText`. The `url` parameter is set to
+            // an empty string so that the link's content is set to the empty
+            // string if `newContent` has no length.
+            this._updateLinkContent(this.$link, { content: newContent, url: '' }, { force: true });
+            this._setLinkContent = false;
+        }
+    },
 });
 
 return LinkTools;
-- 
GitLab