From 2253f0572b93676e140e50ba7630d8beb3d38657 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Thu, 20 Jun 2019 19:35:19 +0200 Subject: [PATCH] Restrict a11y autofocus to keyboard interaction See #2915 --- wcfsetup/install/files/js/WCF.js | 6 ++-- .../Controller/User/Notification/Settings.js | 2 +- .../WoltLabSuite/Core/Ui/Dropdown/Simple.js | 35 +++++++++++++++++-- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/wcfsetup/install/files/js/WCF.js b/wcfsetup/install/files/js/WCF.js index 5dbf96b073..06943fa68f 100755 --- a/wcfsetup/install/files/js/WCF.js +++ b/wcfsetup/install/files/js/WCF.js @@ -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; diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Controller/User/Notification/Settings.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Controller/User/Notification/Settings.js index bf595683f8..0afac53be5 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Controller/User/Notification/Settings.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Controller/User/Notification/Settings.js @@ -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; diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dropdown/Simple.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dropdown/Simple.js index db7b6cc047..3742b05fc5 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dropdown/Simple.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dropdown/Simple.js @@ -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 -- 2.20.1