Automatic update from web-platform-tests Fix user action pseudo-classes when elements enter/exit top layer This behavior was recently changed, in [1]. When an element enters or exits the top layer, its ancestor chain for user action pseudo-classes (:hover, :focus-within, and :active) needs to be re-evaluated. This is because the tree traversal used to propagate these states stops at the top layer. Thus, ancestors might need their state cleared when the element enters the top layer, or applied when it exits. Additionally, a requestAnimationFrame is added to the related WPT test (toplayer-transition-001.html) since hidePopover style invalidations require a frame to fully resolve before the pseudo-classes update correctly. [1] https://crrev.com/c/7683005 Fixed: 496700727 Change-Id: I8370db87780ce6f3f6034d87487994ec197ddebc Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7709256 Commit-Queue: Mason Freed <masonf@chromium.org> Reviewed-by: David Baron <dbaron@chromium.org> Auto-Submit: Mason Freed <masonf@chromium.org> Cr-Commit-Position: refs/heads/main@{#1608927} -- wpt-commits: 2ba865f94c2666ba9b8209e36ec60181fcec42bf wpt-pr: 58932
68 lines
3.3 KiB
HTML
68 lines
3.3 KiB
HTML
<!DOCTYPE html>
|
|
<meta charset="utf-8">
|
|
<title>Selectors: top layer transitions should adjust pseudo-classes on ancestors</title>
|
|
<link rel="help" href="https://drafts.csswg.org/selectors/#the-hover-pseudo">
|
|
<link rel="help" href="https://drafts.csswg.org/selectors/#the-focus-within-pseudo">
|
|
<link rel="help" href="https://drafts.csswg.org/css-position-4/#top-layer">
|
|
<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>
|
|
<style>
|
|
[popover] { display: block; }
|
|
</style>
|
|
|
|
<div id="container">
|
|
<div id="popover" popover="manual">
|
|
<input id="input">
|
|
<div id="hoverTarget">hover here</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
promise_test(async t => {
|
|
t.add_cleanup(() => { if (popover.matches(':popover-open')) popover.hidePopover(); });
|
|
|
|
input.focus();
|
|
assert_true(input.matches(':focus'), 'input should be focused');
|
|
assert_true(container.matches(':focus-within'), 'container should match :focus-within before showPopover');
|
|
|
|
popover.showPopover();
|
|
assert_true(input.matches(':focus'), 'input should still be focused after showPopover');
|
|
assert_true(popover.matches(':focus-within'), 'popover should match :focus-within after showPopover');
|
|
assert_false(container.matches(':focus-within'), 'container should not match :focus-within after showPopover');
|
|
assert_false(document.body.matches(':focus-within'), 'body should not match :focus-within after showPopover');
|
|
|
|
popover.hidePopover();
|
|
await new Promise(requestAnimationFrame);
|
|
assert_true(input.matches(':focus'), 'input should still be focused after hidePopover');
|
|
assert_true(container.matches(':focus-within'), 'container should match :focus-within after hidePopover');
|
|
assert_true(document.body.matches(':focus-within'), 'body should match :focus-within after hidePopover');
|
|
}, ':focus-within should be adjusted on ancestors when popover enters/exits top layer.');
|
|
|
|
promise_test(async t => {
|
|
t.add_cleanup(() => { if (popover.matches(':popover-open')) popover.hidePopover(); });
|
|
|
|
await new test_driver.Actions()
|
|
.pointerMove(1, 1, {origin: hoverTarget})
|
|
.send();
|
|
await new Promise(requestAnimationFrame);
|
|
|
|
assert_true(hoverTarget.matches(':hover'), 'hoverTarget should match :hover');
|
|
assert_true(container.matches(':hover'), 'container should match :hover before showPopover');
|
|
|
|
popover.showPopover();
|
|
assert_true(hoverTarget.matches(':hover'), 'hoverTarget should still match :hover after showPopover');
|
|
assert_true(popover.matches(':hover'), 'popover should match :hover after showPopover');
|
|
assert_false(container.matches(':hover'), 'container should not match :hover after showPopover');
|
|
assert_false(document.body.matches(':hover'), 'body should not match :hover after showPopover');
|
|
|
|
popover.hidePopover();
|
|
await new Promise(requestAnimationFrame);
|
|
assert_true(hoverTarget.matches(':hover'), 'hoverTarget should still match :hover after hidePopover');
|
|
assert_true(container.matches(':hover'), 'container should match :hover after hidePopover');
|
|
assert_true(document.body.matches(':hover'), 'body should match :hover after hidePopover');
|
|
}, ':hover should be adjusted on ancestors when popover enters/exits top layer.');
|
|
</script>
|