Restrict a11y autofocus to keyboard interaction
authorAlexander Ebert <ebert@woltlab.com>
Thu, 20 Jun 2019 17:35:19 +0000 (19:35 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Thu, 20 Jun 2019 17:35:19 +0000 (19:35 +0200)
See #2915

wcfsetup/install/files/js/WCF.js
wcfsetup/install/files/js/WoltLabSuite/Core/Controller/User/Notification/Settings.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dropdown/Simple.js

index 5dbf96b073c7dfe4fad40aab748f2d9ed5eab1c4..06943fa68f03b57f6341fd9d0966c7604fc542a7 100755 (executable)
@@ -827,8 +827,8 @@ WCF.Dropdown = {
        /**
         * Initializes a dropdown.
         * 
-        * @param       jQuery          button
-        * @param       boolean         isLazyInitialization
+        * @param       {jQuery}                button
+        * @param       {boolean|Event}         isLazyInitialization
         */
        initDropdown: function(button, isLazyInitialization) {
                window.bc_wcfSimpleDropdown.init(button[0], isLazyInitialization);
@@ -5735,7 +5735,7 @@ if (COMPILER_TARGET_DEFAULT) {
                        }
                        
                        if ($trigger !== null) {
-                               WCF.Dropdown.initDropdown($trigger, true);
+                               WCF.Dropdown.initDropdown($trigger, event.originalEvent || event);
                        }
                        
                        return false;
index bf595683f8f82eb301c0e5a9aa37d2834bba8de4..0afac53be570da1079a2cf7906ce128fccb1fdd3 100644 (file)
@@ -95,7 +95,7 @@ define(['Dictionary', 'Language', 'Dom/Traverse', 'Ui/SimpleDropdown'], function
                                button.parentNode.classList.add('dropdown');
                                button.parentNode.appendChild(data.dropdownMenu);
                                
-                               UiSimpleDropdown.init(button, true);
+                               UiSimpleDropdown.init(button, event);
                        }
                        else {
                                var items = DomTraverse.childrenByTag(data.dropdownMenu, 'LI'), value = data.mailValue.value;
index db7b6cc04704ef72c5f6708252a699d3ad6b6d2b..3742b05fc55c419a8873345b6015c3d22689a4eb 100644 (file)
@@ -64,7 +64,7 @@ define(
                 * Initializes a dropdown.
                 * 
                 * @param       {Element}       button
-                * @param       {boolean}       isLazyInitialization
+                * @param       {boolean|Event} isLazyInitialization
                 */
                init: function(button, isLazyInitialization) {
                        this.setup();
@@ -128,7 +128,15 @@ define(
                        elData(button, 'target', containerId);
                        
                        if (isLazyInitialization) {
-                               setTimeout(function() { Core.triggerEvent(button, WCF_CLICK_EVENT); }, 10);
+                               setTimeout(function() {
+                                       elData(button, 'dropdown-lazy-init', (isLazyInitialization instanceof MouseEvent));
+                                       
+                                       Core.triggerEvent(button, WCF_CLICK_EVENT);
+                                       
+                                       setTimeout(function() {
+                                               button.removeAttribute('data-dropdown-lazy-init');
+                                       }, 10);
+                               }, 10);
                        }
                },
                
@@ -396,14 +404,20 @@ define(
                                
                                //noinspection JSCheckFunctionSignatures
                                targetId = elData(event.currentTarget, 'target');
+                               
+                               if (disableAutoFocus === undefined && event instanceof MouseEvent) {
+                                       disableAutoFocus = true;
+                               }
                        }
                        
                        var dropdown = _dropdowns.get(targetId), preventToggle = false;
                        if (dropdown !== undefined) {
+                               var button;
+                               
                                // check if the dropdown is still the same, as some components (e.g. page actions)
                                // re-create the parent of a button
                                if (event) {
-                                       var button = event.currentTarget, parent = button.parentNode;
+                                       button = event.currentTarget, parent = button.parentNode;
                                        if (parent !== dropdown) {
                                                parent.classList.add('dropdown');
                                                parent.id = dropdown.id;
@@ -417,6 +431,21 @@ define(
                                        }
                                }
                                
+                               if (disableAutoFocus === undefined) {
+                                       button = dropdown.closest('.dropdownToggle');
+                                       if (!button) {
+                                               button = elBySel('.dropdownToggle', dropdown);
+                                               
+                                               if (!button && dropdown.id) {
+                                                       button = elBySel('[data-target="' + dropdown.id + '"]');
+                                               }
+                                       }
+                                       
+                                       if (button && elDataBool(button, 'dropdown-lazy-init')) {
+                                               disableAutoFocus = true;
+                                       }
+                               }
+                               
                                // Repeated clicks on the dropdown button will not cause it to close, the only way
                                // to close it is by clicking somewhere else in the document or on another dropdown
                                // toggle. This is used with the search bar to prevent the dropdown from closing by