From 08e2409afe49b1f1dc0754a4f009609ce37b788a Mon Sep 17 00:00:00 2001 From: MerlinGuillaume Date: Tue, 13 Jun 2023 07:26:18 +0000 Subject: [PATCH] [FIX] web: reposition popover when image is loaded When hovering over an employee's photo (without edit rights) and the image hasn't been loaded in the cache, the popover is positioned to the right of the image. With a big image, the popover can be outside of the page. Steps to reproduce: 1. Install Employees and set a 4k image to any employee 2. Remove all the rights of Marc Demo on Employees 3. Connect as Marc Demo 4. Open the form of the employee with the 4k image 5. Hover on the employee photo 6. The image position is off Solution: Update the position of the popover when the image is loaded and restrict the image width in the popover to the popover width Problem: When we try to find the best position to display the popover and the image is not loaded, we will find that there is some room for the popover on the right because the image has no height or width opw-3281649 closes odoo/odoo#125951 X-original-commit: 532c4cfa4e60bc95319b774794680eabc80b1219 Signed-off-by: Bruno Boi (boi) Signed-off-by: Guillaume Merlin (megu) --- addons/web/static/src/core/position_hook.js | 2 ++ .../static/src/views/fields/image/image_field.scss | 2 +- addons/web/static/tests/core/position_hook_tests.js | 12 ++++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/core/position_hook.js b/addons/web/static/src/core/position_hook.js index 0d87c7e78be..01d626469ad 100644 --- a/addons/web/static/src/core/position_hook.js +++ b/addons/web/static/src/core/position_hook.js @@ -339,9 +339,11 @@ export function usePosition(target, options) { // Attach listeners to keep the positioning up to date const targetDocument = getTarget()?.ownerDocument; targetDocument?.addEventListener("scroll", throttledUpdate, { capture: true }); + targetDocument?.addEventListener("load", throttledUpdate, { capture: true }); window.addEventListener("resize", throttledUpdate); return () => { targetDocument?.removeEventListener("scroll", throttledUpdate, { capture: true }); + targetDocument?.removeEventListener("load", throttledUpdate, { capture: true }); window.removeEventListener("resize", throttledUpdate); }; } diff --git a/addons/web/static/src/views/fields/image/image_field.scss b/addons/web/static/src/views/fields/image/image_field.scss index ba7dadf6d7b..01016fde7a9 100644 --- a/addons/web/static/src/views/fields/image/image_field.scss +++ b/addons/web/static/src/views/fields/image/image_field.scss @@ -22,7 +22,7 @@ .o_image_zoom { img { - max-width: 50vw; + max-width: 100%; max-height: 50vh; } } diff --git a/addons/web/static/tests/core/position_hook_tests.js b/addons/web/static/tests/core/position_hook_tests.js index 7a973d92d05..cdf987fd1af 100644 --- a/addons/web/static/tests/core/position_hook_tests.js +++ b/addons/web/static/tests/core/position_hook_tests.js @@ -333,6 +333,18 @@ QUnit.test("has no effect when component is destroyed", async (assert) => { ); }); +QUnit.test("reposition popper when a load event occurs", async (assert) => { + const TestComp = getTestComponent({ + onPositioned: () => { + assert.step("onPositioned called"); + }, + }); + await mount(TestComp, container); + assert.verifySteps(["onPositioned called"], "onPositioned called when component mounted"); + await document.querySelector('[id="popper"]').dispatchEvent(new Event("load")); + assert.verifySteps(["onPositioned called"], "onPositioned called when load event is triggered"); +}); + QUnit.test("is positioned relative to its containing block", async (assert) => { const fixtureBox = getFixture().getBoundingClientRect(); // offset the container