From e9a622b668a830fca425a164071ffd9691b19d0a Mon Sep 17 00:00:00 2001 From: Mason Freed Date: Wed, 9 Nov 2022 14:41:20 -0800 Subject: [PATCH] Implement correct focus behavior for popovers This implements the focus behavior described in [1], which: 1. Moves focus from an invoking element to its invoked popover, regardless of where in the DOM that popover lives. 2. Moves focus back to the next focusable element after the invoking element once focus leaves the invoked popover. 3. Skips over an open invoked popover otherwise. The logic follows very closely the case of slotted light DOM content, for which focus moves from the shadow root content to the slotted light DOM content and back. [1] https://github.com/w3c/html-aam/wiki/HTML-Popup-Attribute-A11y-Proposal-%28manual-and-auto%29 Bug: 1307772 Change-Id: Ic12441fc3b8d2f1c405bf912234dd24e4b05dc69 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4006714 Commit-Queue: Mason Freed Reviewed-by: Joey Arhar Cr-Commit-Position: refs/heads/main@{#1069375} --- .../popovers/popover-focus.tentative.html | 80 +++++++++++++++++++ .../popover-light-dismiss.tentative.html | 35 -------- .../popovers/resources/popover-utils.js | 25 +++++- 3 files changed, 102 insertions(+), 38 deletions(-) diff --git a/html/semantics/popovers/popover-focus.tentative.html b/html/semantics/popovers/popover-focus.tentative.html index 10c91bcebba7b4..0d35281164c3b9 100644 --- a/html/semantics/popovers/popover-focus.tentative.html +++ b/html/semantics/popovers/popover-focus.tentative.html @@ -266,3 +266,83 @@ document.querySelectorAll('body > [popover]').forEach(popover => activateAndVerify(popover)); + +
+ +
+ + + +
+ + + +
+ + +
+
+ Non-focusable popover +
+ +
+ + diff --git a/html/semantics/popovers/popover-light-dismiss.tentative.html b/html/semantics/popovers/popover-light-dismiss.tentative.html index 2581ca6fdeea0f..2a101483cb8c8e 100644 --- a/html/semantics/popovers/popover-light-dismiss.tentative.html +++ b/html/semantics/popovers/popover-light-dismiss.tentative.html @@ -389,41 +389,6 @@ },'Moving focus back to the anchor element should not dismiss the popover'); -
- - Inside popover 9 after button -
- - - -
Popover 1
Anchor diff --git a/html/semantics/popovers/resources/popover-utils.js b/html/semantics/popovers/resources/popover-utils.js index 8f66dc0844975d..efc318b3c9fd34 100644 --- a/html/semantics/popovers/resources/popover-utils.js +++ b/html/semantics/popovers/resources/popover-utils.js @@ -12,14 +12,33 @@ async function clickOn(element) { } async function sendTab() { await waitForRender(); - await new test_driver.send_keys(document.body,'\uE004'); // Tab - await waitForRender(); -} + const kTab = '\uE004'; + await new test_driver.send_keys(document.body,kTab); + await waitForRender(); +} +// Waiting for crbug.com/893480: +// async function sendShiftTab() { +// await waitForRender(); +// const kShift = '\uE008'; +// const kTab = '\uE004'; +// await new test_driver.Actions() +// .keyDown(kShift) +// .keyDown(kTab) +// .keyUp(kTab) +// .keyUp(kShift) +// .send(); +// await waitForRender(); +// } async function sendEscape() { await waitForRender(); await new test_driver.send_keys(document.body,'\uE00C'); // Escape await waitForRender(); } +async function sendEnter() { + await waitForRender(); + await new test_driver.send_keys(document.body,'\uE007'); // Enter + await waitForRender(); +} function isElementVisible(el) { return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length); }