Incorrect handling of the return focus
authorAlexander Ebert <ebert@woltlab.com>
Sat, 14 May 2022 12:30:38 +0000 (14:30 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Mon, 16 May 2022 09:38:24 +0000 (11:38 +0200)
Related https://www.woltlab.com/community/thread/295562-inhalte-k%C3%B6nnen-doppelt-gemeldet-werden/

(cherry picked from commit e9ffefb4d0db61bf8e12b3824c6515ac16fe3812)

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

index a0ac4c163baa306278441fd1b7d1b68f3f4deb70..384a723fc3e3c43050a300ef1c1ba4884b9f8220 100644 (file)
@@ -783,7 +783,20 @@ const UiDialog = {
       throw new Error("Expected a valid dialog id, '" + id + "' does not match any active dialog.");
     }
 
-    data.focusTrap.deactivate();
+    try {
+      data.focusTrap.deactivate();
+    } catch (e) {
+      // The focus trap is unable to return the focus if
+      // the origin is no longer focusable. This can happen
+      // when the source is removed or is not longer visible,
+      // the latter typically caused by collapsing menus
+      // on mobile devices.
+      const ignoreErrorMessage =
+        "Your focus-trap must have at least one container with at least one tabbable node in it at all times";
+      if (e.message !== ignoreErrorMessage) {
+        throw e;
+      }
+    }
 
     data.dialog.setAttribute("aria-hidden", "true");
 
index 40c05c5c13c453dce54fa95786348a093ca252de..89c363d0ac3d763220747f3929f4de0b9a761bb6 100644 (file)
@@ -266,6 +266,7 @@ function toggleMobileNavigation(message: HTMLElement, quickOptions: HTMLElement,
 
       return false;
     },
+    setReturnFocus: quickOptions,
   });
   _focusTrap.activate();
 }
index 4e574134c1e6747fc9e646acc9f8f927b6777586..8474b12fd3cb158a05b392716dfecec55a626a9e 100644 (file)
@@ -644,7 +644,20 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Change/Listener", "./S
             if (data === undefined) {
                 throw new Error("Expected a valid dialog id, '" + id + "' does not match any active dialog.");
             }
-            data.focusTrap.deactivate();
+            try {
+                data.focusTrap.deactivate();
+            }
+            catch (e) {
+                // The focus trap is unable to return the focus if
+                // the origin is no longer focusable. This can happen
+                // when the source is removed or is not longer visible,
+                // the latter typically caused by collapsing menus
+                // on mobile devices.
+                const ignoreErrorMessage = "Your focus-trap must have at least one container with at least one tabbable node in it at all times";
+                if (e.message !== ignoreErrorMessage) {
+                    throw e;
+                }
+            }
             data.dialog.setAttribute("aria-hidden", "true");
             // Move the keyboard focus away from a now hidden element.
             const activeElement = document.activeElement;
index 0631e43394089ee934c68372efc2be42065cf24e..ade8133efc461a40ba0bd2c69e88daecf7d1ca70 100644 (file)
@@ -232,6 +232,7 @@ define(["require", "exports", "tslib", "focus-trap", "../Core", "../Dom/Change/L
                 toggleMobileNavigation(message, quickOptions, navigation);
                 return false;
             },
+            setReturnFocus: quickOptions,
         });
         _focusTrap.activate();
     }