Skip to content

Commit

Permalink
Implement CloseWatcher integration for popovers
Browse files Browse the repository at this point in the history
This is being integrated in this HTML spec PR which adds CloseWatchers:
whatwg/html#9462

CloseWatcher is not enabled right now, so this patch should not make any
behavior changes to stable chrome.

This patch makes it so that pressing the escape key uses the
document/window's closewatcher stack to find a popover to light dismiss
rather than HandlePopoverLightDismiss hiding whatever the
TopmostPopoverOrHint is. Hopefully they agree with each other.

The behavior change for popovers is that the android back button can
close popovers, and this gives popovers the
grouping-without-user-activation behavior that dialogs have (with the
flag enabled). If you open 5 popovers with a single user activation,
then any close signal (including Esc on desktop) will close all 5 of
those popovers, not just the topmost one.

Bug: 1171318
Change-Id: I73740c3eb9c16b0883862ae259be4867b824a79c
  • Loading branch information
josepharhar authored and chromium-wpt-export-bot committed Jul 20, 2023
1 parent f920686 commit 866157d
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
44 changes: 44 additions & 0 deletions close-watcher/popover-closewatcher-multiple-plus-free.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!DOCTYPE html>
<link rel=author href="mailto:[email protected]">
<link rel=help href="https://github.com/whatwg/html/pull/9462">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/resources/testdriver-actions.js"></script>

<button id=b0>b0</button>

<div id=p1 popover=auto>
<button id=b1>b1</button>

<div id=p2 popover=auto>
<button id=b2>b2</button>

<div id=p3 popover=auto>p3</div>
</div>
</div>

<script>
const escapeKey = '\uE00C';

promise_test(async () => {
p1.showPopover();
await test_driver.click(b1);
p2.showPopover();
p3.showPopover();
assert_true(p1.matches(':popover-open'), 'p1 should be open.');
assert_true(p2.matches(':popover-open'), 'p2 should be open.');
assert_true(p3.matches(':popover-open'), 'p3 should be open.');

await test_driver.send_keys(p3, escapeKey);
assert_true(p1.matches(':popover-open'), 'first escape: p1 should be open.');
assert_false(p2.matches(':popover-open'), 'first escape: p2 should be closed.');
assert_false(p3.matches(':popover-open'), 'first escape: p3 should be closed.');

await test_driver.send_keys(p1, escapeKey);
assert_false(p1.matches(':popover-open'), 'second escape: p1 should be closed.');
assert_false(p2.matches(':popover-open'), 'second escape: p2 should be closed.');
assert_false(p3.matches(':popover-open'), 'second escape: p3 should be closed.');
}, 'Multiple popovers opened from a single user activation close together, but original popover closes separately.');
</script>
65 changes: 65 additions & 0 deletions close-watcher/popover-closewatcher.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<!DOCTYPE html>
<link rel=author href="mailto:[email protected]">
<link rel=help href="https://github.com/whatwg/html/pull/9462">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/resources/testdriver-actions.js"></script>

<button id=b0>b0</button>

<div id=p1 popover=auto>
<button id=b1>b1</button>

<div id=p2 popover=auto>
<button id=b2>b2</button>

<div id=p3 popover=auto>p3</div>
</div>
</div>

<script>
const escapeKey = '\uE00C';

promise_test(async () => {
p1.showPopover();
p2.showPopover();
p3.showPopover();
assert_true(p1.matches(':popover-open'), 'p1 should be open.');
assert_true(p2.matches(':popover-open'), 'p2 should be open.');
assert_true(p3.matches(':popover-open'), 'p3 should be open.');

await test_driver.send_keys(p3, escapeKey);
assert_false(p1.matches(':popover-open'), 'p1 should be closed.');
assert_false(p2.matches(':popover-open'), 'p2 should be closed.');
assert_false(p3.matches(':popover-open'), 'p3 should be closed.');
}, 'Opening multiple popovers without user activation causes them all to be closed with one close signal.');

promise_test(async () => {
await test_driver.click(b0);
p1.showPopover();
await test_driver.click(b1);
p2.showPopover();
await test_driver.click(b2);
p3.showPopover();
assert_true(p1.matches(':popover-open'), 'p1 should be open.');
assert_true(p2.matches(':popover-open'), 'p2 should be open.');
assert_true(p3.matches(':popover-open'), 'p3 should be open.');

await test_driver.send_keys(p3, escapeKey);
assert_true(p1.matches(':popover-open'), 'first escape: p1 should be open.');
assert_true(p2.matches(':popover-open'), 'first escape: p2 should be open.');
assert_false(p3.matches(':popover-open'), 'first escape: p3 should be closed.');

await test_driver.send_keys(p2, escapeKey);
assert_true(p1.matches(':popover-open'), 'second escape: p1 should be open.');
assert_false(p2.matches(':popover-open'), 'second escape: p2 should be closed.');
assert_false(p3.matches(':popover-open'), 'second escape: p3 should be closed.');

await test_driver.send_keys(p1, escapeKey);
assert_false(p1.matches(':popover-open'), 'third escape: p1 should be closed.');
assert_false(p2.matches(':popover-open'), 'third escape: p2 should be closed.');
assert_false(p3.matches(':popover-open'), 'third escape: p3 should be closed.');
}, 'Opening multiple popovers with user activation should close one at a time with close signals.');
</script>

0 comments on commit 866157d

Please sign in to comment.