From c5a889cdf123ab9380a22240ccad381a3d94fa0f Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Sat, 20 May 2023 18:53:52 +0200 Subject: [PATCH] Fix the animation of dialogs in Safari Safari executes the resize observer asynchronously, causing the offset to be not calculated when the dialog was just added to the DOM. In addition the `contentBoxSize` was observed to report the width of the element without any borders. We are able to simplify the code by querying the client rect instead which reports the proper width. Fixes #5519 --- ts/WoltLabSuite/Core/Ui/Dialog.ts | 22 +++++-------------- .../files/js/WoltLabSuite/Core/Ui/Dialog.js | 21 +++++------------- wcfsetup/install/files/style/ui/dialog.scss | 7 +++--- 3 files changed, 14 insertions(+), 36 deletions(-) diff --git a/ts/WoltLabSuite/Core/Ui/Dialog.ts b/ts/WoltLabSuite/Core/Ui/Dialog.ts index f8e1473727..fbb338dc49 100644 --- a/ts/WoltLabSuite/Core/Ui/Dialog.ts +++ b/ts/WoltLabSuite/Core/Ui/Dialog.ts @@ -403,23 +403,10 @@ const UiDialog = { // elements to be squished together. The actual value for // `transform` must not use percent values, because this // causes blurry text rendering in Chromium. - const resizeObserver = new ResizeObserver((entries) => { + const resizeObserver = new ResizeObserver(() => { if (dialog.getAttribute("aria-hidden") === "false") { - for (const entry of entries) { - let width: number; - if (entry.contentBoxSize) { - const contentBoxSize: ResizeObserverSize = Array.isArray(entry.contentBoxSize) - ? entry.contentBoxSize[0] - : entry.contentBoxSize; - width = contentBoxSize.inlineSize; - } else { - // Safari < 15.4 supports only the older spec. - width = entry.contentRect.width; - } - - const offset = Math.floor(width / 2); - dialog.style.setProperty("--translate-x", `-${offset}px`); - } + const offset = Math.floor(dialog.getBoundingClientRect().width / 2); + dialog.style.setProperty("--translate-x", `-${offset}px`); } }); resizeObserver.observe(dialog); @@ -637,6 +624,9 @@ const UiDialog = { const maximumHeight = window.innerHeight * (_dialogFullHeight ? 1 : 0.8) - unavailableHeight; contentContainer.style.setProperty("max-height", `${~~maximumHeight}px`, ""); + const offset = Math.floor(data.dialog.getBoundingClientRect().width / 2); + data.dialog.style.setProperty("--translate-x", `-${offset}px`); + const callbackObject = _dialogToObject.get(id); //noinspection JSUnresolvedVariable if (callbackObject !== undefined && typeof callbackObject._dialogSubmit === "function") { diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dialog.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dialog.js index 2b71adca3f..33fc124653 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dialog.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dialog.js @@ -331,23 +331,10 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Change/Listener", "./S // elements to be squished together. The actual value for // `transform` must not use percent values, because this // causes blurry text rendering in Chromium. - const resizeObserver = new ResizeObserver((entries) => { + const resizeObserver = new ResizeObserver(() => { if (dialog.getAttribute("aria-hidden") === "false") { - for (const entry of entries) { - let width; - if (entry.contentBoxSize) { - const contentBoxSize = Array.isArray(entry.contentBoxSize) - ? entry.contentBoxSize[0] - : entry.contentBoxSize; - width = contentBoxSize.inlineSize; - } - else { - // Safari < 15.4 supports only the older spec. - width = entry.contentRect.width; - } - const offset = Math.floor(width / 2); - dialog.style.setProperty("--translate-x", `-${offset}px`); - } + const offset = Math.floor(dialog.getBoundingClientRect().width / 2); + dialog.style.setProperty("--translate-x", `-${offset}px`); } }); resizeObserver.observe(dialog); @@ -528,6 +515,8 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Change/Listener", "./S unavailableHeight += Util_1.default.outerHeight(data.header); const maximumHeight = window.innerHeight * (_dialogFullHeight ? 1 : 0.8) - unavailableHeight; contentContainer.style.setProperty("max-height", `${~~maximumHeight}px`, ""); + const offset = Math.floor(data.dialog.getBoundingClientRect().width / 2); + data.dialog.style.setProperty("--translate-x", `-${offset}px`); const callbackObject = _dialogToObject.get(id); //noinspection JSUnresolvedVariable if (callbackObject !== undefined && typeof callbackObject._dialogSubmit === "function") { diff --git a/wcfsetup/install/files/style/ui/dialog.scss b/wcfsetup/install/files/style/ui/dialog.scss index 993fd7ee1f..8e0a99afff 100644 --- a/wcfsetup/install/files/style/ui/dialog.scss +++ b/wcfsetup/install/files/style/ui/dialog.scss @@ -23,12 +23,11 @@ @keyframes wcfDialog { 0% { visibility: visible; - transform: translateX(var(--translate-x, 0)) translateY(calc(-50% - 20px)); - //top: 8%; + transform: translateX(var(--translate-x)) translateY(calc(-50% - 20px)); } 100% { visibility: visible; - //top: 10%; + transform: translateX(var(--translate-x)) translateY(-50%); } } @@ -71,7 +70,7 @@ // this causes a blurry text rendering in Chromium. // The offset is calculated using a `ResizeObserver`. left: 50%; - transform: translateX(var(--translate-x, 0)) translateY(-50%); + transform: translateX(var(--translate-x)) translateY(-50%); &[aria-hidden="false"] { animation: wcfDialog 0.24s; -- 2.20.1