Fix the overlay container being stuck in dialogs
authorAlexander Ebert <ebert@woltlab.com>
Mon, 11 Dec 2023 16:33:01 +0000 (17:33 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Mon, 11 Dec 2023 16:33:01 +0000 (17:33 +0100)
The `MutationObserver` is an async process that does not reliably fire when a property is mutated repeatedly within a short time.

See https://www.woltlab.com/community/thread/303449-url-einem-bild-zuweisen-erst-nach-speichern-m%C3%B6glich/
See https://www.woltlab.com/community/thread/303397-men%C3%BC-zur-bildpositionierung-%C3%B6ffnet-sich-nicht-nach-dem-einf%C3%BCgen/

ts/WoltLabSuite/Core/Ui/Dialog.ts
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dialog.js

index c65f04ac591f58f0e9f7f949715199dc421177bf..760f72e6ebca9dcf23eeb11ce0d01d3676299099 100644 (file)
@@ -62,25 +62,21 @@ const UiDialog = {
       { passive: false },
     );
 
-    const observer = new MutationObserver((mutations) => {
+    let containsPageOverlay = false;
+    const observer = new MutationObserver(() => {
       const currentValue = _container.getAttribute("aria-hidden");
 
-      for (const mutation of mutations) {
-        if (mutation.oldValue === currentValue) {
-          continue;
-        }
-
-        if (currentValue === "false") {
-          adoptPageOverlayContainer(_container);
-        } else {
-          releasePageOverlayContainer(_container);
-        }
+      if (currentValue === "true") {
+        releasePageOverlayContainer(_container);
+        containsPageOverlay = false;
+      } else if (!containsPageOverlay) {
+        adoptPageOverlayContainer(_container);
+        containsPageOverlay = true;
       }
     });
     observer.observe(_container, {
       attributes: true,
       attributeFilter: ["aria-hidden"],
-      attributeOldValue: true,
     });
 
     document.getElementById("content")!.appendChild(_container);
index 3125c9817f5cb1caf0a88e8ca952bea5922005ef..bd0ec196d4b2238c4b442cdc00965c36494f1241 100644 (file)
@@ -44,24 +44,21 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Change/Listener", "./S
                     event.preventDefault();
                 }
             }, { passive: false });
-            const observer = new MutationObserver((mutations) => {
+            let containsPageOverlay = false;
+            const observer = new MutationObserver(() => {
                 const currentValue = _container.getAttribute("aria-hidden");
-                for (const mutation of mutations) {
-                    if (mutation.oldValue === currentValue) {
-                        continue;
-                    }
-                    if (currentValue === "false") {
-                        (0, PageOverlay_1.adoptPageOverlayContainer)(_container);
-                    }
-                    else {
-                        (0, PageOverlay_1.releasePageOverlayContainer)(_container);
-                    }
+                if (currentValue === "true") {
+                    (0, PageOverlay_1.releasePageOverlayContainer)(_container);
+                    containsPageOverlay = false;
+                }
+                else if (!containsPageOverlay) {
+                    (0, PageOverlay_1.adoptPageOverlayContainer)(_container);
+                    containsPageOverlay = true;
                 }
             });
             observer.observe(_container, {
                 attributes: true,
                 attributeFilter: ["aria-hidden"],
-                attributeOldValue: true,
             });
             document.getElementById("content").appendChild(_container);
             _keyupListener = (event) => {