commit 3df2f204043cdd204a77b3fae34f61fc4b842d3b
parent 397453bb28eabc6440ef6663eaa43cc3f9e1c37f
Author: Mason Freed <masonf@chromium.org>
Date: Tue, 14 Oct 2025 22:23:06 +0000
Bug 1992828 [wpt PR 55257] - Fix infinite loop in popover/slot tab navigation, a=testonly
Automatic update from web-platform-tests
Fix infinite loop in popover/slot tab navigation
Since <slot popover> is both a focus navigation scope owner
and the root of a focus navigation scope, there was a potential
infinite loop. This eliminates that loop.
Fixed: 447888734
Change-Id: I522b4a2ef10e2f8a5b0d34d271d2d7752e82fe3f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7009310
Auto-Submit: Mason Freed <masonf@chromium.org>
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1525768}
--
wpt-commits: 847972dbae879fbb28506f7f9c61a8ed0a938774
wpt-pr: 55257
Diffstat:
1 file changed, 50 insertions(+), 0 deletions(-)
diff --git a/testing/web-platform/tests/html/semantics/popovers/popover-focus-slotted.html b/testing/web-platform/tests/html/semantics/popovers/popover-focus-slotted.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>Popover focus with slotted popover and invoker</title>
+<link rel="author" href="mailto:masonf@chromium.org">
+<link rel=help href="https://crbug.com/447888734">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-actions.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="/html/semantics/popovers/resources/popover-utils.js"></script>
+
+<div id="host">
+ <template shadowrootmode="open">
+ <div>
+ <slot id="invoker" name="invoker"></slot>
+ <slot id="popover" popover="manual"></slot>
+ </div>
+ </template>
+ <button slot="invoker">Click me</button>
+ <button id="inner">Click me next</button>
+</div>
+
+<script>
+ const div = document.getElementById('host');
+ const invoker = div.shadowRoot.querySelector("#invoker");
+ const popover = div.shadowRoot.querySelector("#popover");
+ const inner = document.getElementById('inner');
+ popover.togglePopover({source: invoker});
+
+ promise_test(async () => {
+ assert_true(popover.matches(':popover-open'), 'Popover should be open');
+ inner.focus();
+ assert_equals(document.activeElement, inner, 'Start with inner focused');
+
+ // Tab forward
+ await sendTab();
+ assert_not_equals(document.activeElement, inner, 'Focus should move');
+ }, 'Tabbing forward out of a <slot popover> should not hang.');
+
+ promise_test(async () => {
+ assert_true(popover.matches(':popover-open'), 'Popover should be open');
+ inner.focus();
+ assert_equals(document.activeElement, inner, 'Start with inner focused');
+
+ // Tab backwards
+ await sendShiftTab();
+ assert_not_equals(document.activeElement, inner, 'Focus should move');
+ }, 'Tabbing backwards out of a <slot popover> should not hang.');
+</script>