diff --git a/web_src/js/features/aria.js b/web_src/js/features/aria.js index 8230ba0a85b3e..15fed5b87a386 100644 --- a/web_src/js/features/aria.js +++ b/web_src/js/features/aria.js @@ -127,41 +127,31 @@ function attachOneDropdownAria($dropdown) { // * desktop event sequence: mousedown -> focus -> mouseup -> click // * mobile event sequence: focus -> mousedown -> mouseup -> click // Fomantic may stop propagation of blur event, use capture to make sure we can still get the event - // keep the debug code for developers who want to confirm&debug this code for different browsers (without attaching a remote debugger) - const showDebug = false; - const debug = (msg) => showDebug && $('.page-content').append($('
').text(`${$menu.attr('id')} ${msg}, menu visible=${isMenuVisible()}`)); let ignoreClickPreEvents = 0, ignoreClickPreVisible = 0; $dropdown[0].addEventListener('mousedown', (e) => { - debug(e.type); ignoreClickPreVisible += isMenuVisible() ? 1 : 0; ignoreClickPreEvents++; }, true); $dropdown[0].addEventListener('focus', (e) => { - debug(e.type); ignoreClickPreVisible += isMenuVisible() ? 1 : 0; ignoreClickPreEvents++; deferredRefreshAria(); }, true); $dropdown[0].addEventListener('blur', (e) => { - debug(e.type); ignoreClickPreVisible = ignoreClickPreEvents = 0; deferredRefreshAria(100); }, true); $dropdown[0].addEventListener('mouseup', (e) => { - debug(e.type); setTimeout(() => { - debug(`${e.type} (deferred)`); ignoreClickPreVisible = ignoreClickPreEvents = 0; deferredRefreshAria(100); }, 0); }, true); $dropdown[0].addEventListener('click', (e) => { - debug(`${e.type}, pre-visible=${ignoreClickPreVisible}, pre-events=${ignoreClickPreEvents}`); if (isMenuVisible() && ignoreClickPreVisible !== 2 && // dropdown is switch from invisible to visible ignoreClickPreEvents === 2 // the click event is related to mousedown+focus ) { - debug(`${e.type}, stop click propagation`); e.stopPropagation(); // if the dropdown menu has been opened by focus, do not trigger the next click event again } ignoreClickPreEvents = ignoreClickPreVisible = 0; diff --git a/web_src/js/features/aria.md b/web_src/js/features/aria.md index 09f134b262b85..679cec774cd2c 100644 --- a/web_src/js/features/aria.md +++ b/web_src/js/features/aria.md @@ -1,4 +1,27 @@ -**This document is used as aria/a11y reference for future developers** +# Background + +This document is used as aria/accessibility(a11y) reference for future developers. + +There are a lot of a11y problems in the Fomantic UI library. This `aria.js` is used +as a workaround to make the UI more accessible. + +The `aria.js` is designed to avoid touching the official Fomantic UI library, +and to be as independent as possible, so it can be easily modified/removed in the future. + +To test the aria/accessibility with screen readers, developers can use the following steps: + +* On macOS, you can use VoiceOver. + * Press `Command + F5` to turn on VoiceOver. + * Try to operate the UI with keyboard-only. + * Use Tab/Shift+Tab to switch focus between elements. + * Arrow keys to navigate between menu/combobox items (only aria-active, not really focused). + * Press Enter to trigger the aria-active element. +* On Android, you can use TalkBack. + * Go to Settings -> Accessibility -> TalkBack, turn it on. + * Long-press or press+swipe to switch the aria-active element (not really focused). + * Double-tap means old single-tap on the aria-active element. + * Double-finger swipe means old single-finger swipe. +* TODO: on Windows, on Linux, on iOS # Checkbox @@ -10,7 +33,8 @@ The ideal checkboxes should be: ``` -However, related styles aren't supported (not implemented) yet, so at the moment, almost all the checkboxes are still using Fomantic UI checkbox. +However, related CSS styles aren't supported (not implemented) yet, so at the moment, +almost all the checkboxes are still using Fomantic UI checkbox. ## Fomantic UI Checkbox @@ -21,64 +45,52 @@ However, related styles aren't supported (not implemented) yet, so at the moment
``` -Then the JS `$.checkbox()` should be called to make it work with keyboard and label-clicking, then it works like the ideal checkboxes. +Then the JS `$.checkbox()` should be called to make it work with keyboard and label-clicking, +then it works like the ideal checkboxes. -There is still a problem: Fomantic UI checkbox is not friendly to screen readers, so we add IDs to all the Fomantic UI checkboxes automatically by JS. +There is still a problem: Fomantic UI checkbox is not friendly to screen readers, +so we add IDs to all the Fomantic UI checkboxes automatically by JS. +If the `label` part is empty, then the checkbox needs to get the `aria-label` attribute manually. # Dropdown -## ARIA Dropdown - -There are different solutions: - -* combobox + listbox + option -* menu + menuitem - -```html -
- - -
-``` - - ## Fomantic UI Dropdown -There are 2 possible solutions about the role: combobox or menu +Fomantic Dropdown is designed to be used for many purposes: -1. Detect if the dropdown has an input, if yes, it works like a combobox, otherwise it works like a menu -2. Always use "combobox", never use "menu" +* Menu (the profile menu in navbar, the language menu in footer) +* Popup (the branch/tag panel, the review box) +* Simple `