[FIX] web: popover service: prevent the crash when undefined target
Steps to reproduce: - In debug mode - Go to a cancelled invoice in Accounting - Click to the "Reset to draft" button in a fast timing (before the `PopoverContainer` is mounted). When hovering an element, a tooltip appears. If the target element disappears before the `onMounted` of the `PopoverContainer`, then the popover causes a crash because the target element does not exists anymore. This fix makes the `tooltip_service` verify that the target still exists before adding the popover. closes odoo/odoo#113406 X-original-commit: 589acab37a4c1b68876386b752a91c3412dc4569 Signed-off-by: Aaron Bohy (aab) <aab@odoo.com> Signed-off-by: Dardenne Florent (dafl) <dafl@odoo.com>
This commit is contained in:
@@ -104,14 +104,17 @@ export const tooltipService = {
|
||||
}
|
||||
|
||||
openTooltipTimeout = browser.setTimeout(() => {
|
||||
closeTooltip = popover.add(
|
||||
target,
|
||||
Tooltip,
|
||||
{ tooltip, template, info },
|
||||
{ position }
|
||||
);
|
||||
// Prevent title from showing on a parent at the same time
|
||||
target.title = "";
|
||||
// verify that the element is still in the DOM
|
||||
if (target.isConnected) {
|
||||
closeTooltip = popover.add(
|
||||
target,
|
||||
Tooltip,
|
||||
{ tooltip, template, info },
|
||||
{ position }
|
||||
);
|
||||
// Prevent title from showing on a parent at the same time
|
||||
target.title = "";
|
||||
}
|
||||
}, delay);
|
||||
}
|
||||
|
||||
|
||||
@@ -424,4 +424,28 @@ QUnit.module("Tooltip service", (hooks) => {
|
||||
await triggerEvent(target, "button[data-tooltip]", "touchstart");
|
||||
assert.containsNone(target, ".o_popover_container .o_popover");
|
||||
});
|
||||
|
||||
QUnit.test("tooltip does not crash with disappearing target", async (assert) => {
|
||||
class MyComponent extends Component {}
|
||||
MyComponent.template = xml`<button class="mybtn" data-tooltip="hello">Action</button>`;
|
||||
let simulateTimeout;
|
||||
const mockSetTimeout = async (fn) => {
|
||||
simulateTimeout = fn;
|
||||
};
|
||||
await makeParent(MyComponent, { mockSetTimeout });
|
||||
|
||||
assert.containsNone(target, ".o_popover_container .o_popover");
|
||||
target.querySelector(".mybtn").dispatchEvent(new Event("mouseenter"));
|
||||
await nextTick();
|
||||
assert.containsNone(target, ".o_popover_container .o_popover");
|
||||
|
||||
// the element disappeared from the DOM during the setTimeout
|
||||
target.querySelector(".mybtn").remove();
|
||||
|
||||
simulateTimeout();
|
||||
await nextTick();
|
||||
|
||||
// tooltip did not crash and is not shown
|
||||
assert.containsNone(target, ".o_popover_container .o_popover");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user