[FIX] web_editor: update UI on link content change

When changing a link's content, its URL (href attribute) might change
(if the new label is a valid URL), due to a mechanism in OdooEditor.

Before this commit, when a change in the link's content leads to a href
change:
- if the LinkTools is opened, the URL input field would become outdated
and display an incorrect URL.
- likewise, if the popover is shown, its content and position would be
outdated (possibly covering the link's new content).

This commit makes sure both the LinkTools URL input field and the
popover stay up-to-date if a link's content or href changes.

task-3284649

X-original-commit: 1b0952f3635f5677ba3ab221a28ceb26920a1862
Part-of: odoo/odoo#136278
This commit is contained in:
Rodolpho Lima
2023-09-25 11:30:13 +00:00
parent e881bc6284
commit 196cf4a7ce
2 changed files with 43 additions and 7 deletions
@@ -183,6 +183,24 @@ export class LinkPopoverWidget {
if (document !== this.wysiwyg.odooEditor.document) {
$(this.wysiwyg.odooEditor.document).on('mouseup.link_popover', onClickDocument);
}
// Update popover's content and position upon changes
// on the link's label or href.
this._observer = new MutationObserver(records => {
if (!popoverShown) {
return;
}
if (records.some(record => record.type === 'attributes')) {
this._loadAsyncLinkPreview();
}
this.$target.popover('update');
});
this._observer.observe(this.target, {
subtree: true,
characterData: true,
attributes: true,
attributeFilter: ['href'],
});
}
/**
*
@@ -196,6 +214,7 @@ export class LinkPopoverWidget {
$(document).off('.link_popover');
$(this.wysiwyg.odooEditor.document).off('.link_popover');
this.$target.popover('dispose');
this._observer.disconnect();
}
/**
@@ -5,6 +5,8 @@ import { ColorPalette } from '@web_editor/js/wysiwyg/widgets/color_palette';
import weUtils from "@web_editor/js/common/utils";
import {
onWillUpdateProps,
onMounted,
onWillUnmount,
useState,
} from "@odoo/owl";
import { normalizeCSSColor } from '@web/core/utils/colors';
@@ -54,16 +56,32 @@ export class LinkTools extends Link {
this._setSelectOptionFromLink();
this._updateOptionsUI();
});
onMounted(() => {
this._observer = new MutationObserver(records => {
if (records.some(record => record.type === 'attributes')) {
this.state.url = this.props.link.getAttribute('href') || '';
this._setUrl();
}
this._updateLabelInput();
});
this._observerOptions = {
subtree: true,
childList: true,
characterData: true,
attributes: true,
attributeFilter: ['href'],
};
this._observer.observe(this.props.link, this._observerOptions);
});
onWillUnmount(() => {
this._observer.disconnect();
});
}
/**
* @override
*/
async _updateState() {
await super._updateState(...arguments);
this._observer = new MutationObserver(async () => {
this._updateLabelInput();
});
this._observer.observe(this.props.link, {subtree: true, childList: true, characterData: true});
// Keep track of each selected custom color and colorpicker.
this.customColors = {};
this.PREFIXES = {
@@ -102,7 +120,6 @@ export class LinkTools extends Link {
if (shouldUnlink(this.$link[0], this.colorCombinationClass)) {
$contents.unwrap();
}
this._observer.disconnect();
super.destroy(...arguments);
this.props.onDestroy();
}
@@ -112,7 +129,7 @@ export class LinkTools extends Link {
super.applyLinkToDom(...arguments);
this.props.wysiwyg.odooEditor.historyStep();
this.props.onPostApplyLink();
this._observer.observe(this.props.link, {subtree: true, childList: true, characterData: true});
this._observer.observe(this.props.link, this._observerOptions);
}
//--------------------------------------------------------------------------
@@ -489,7 +506,7 @@ export class LinkTools extends Link {
// Force update of link's content with new data using 'force: true'.
// Without this, no update if input is same as original text.
this._updateLinkContent(this.$link, data, {force: true});
this._observer.observe(this.props.link, {subtree: true, childList: true, characterData: true});
this._observer.observe(this.props.link, this._observerOptions);
}
/* If content is equal to previous URL, update it to match current URL.
*