Commit a5b31124 authored by Rune Lillesveen's avatar Rune Lillesveen Committed by Commit Bot

DetachLayoutTree clear hover/active state on dom removal.

We need to traverse into display:none subtrees in DetachLayoutTree on
removal to clear hover/active state properly. We use to do this
unconditionally before Squad. Fixes regression.

Bug: 967548
Change-Id: I8fc7e2824e0be8724cfd6173eab3dad5304a5d82
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1642555Reviewed-by: default avatarAnders Hartvoll Ruud <andruud@chromium.org>
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#665916}
parent bc53564a
......@@ -2282,7 +2282,16 @@ void Element::DetachLayoutTree(bool performing_reattach) {
DetachPseudoElement(kPseudoIdBefore, performing_reattach);
if (ChildNeedsReattachLayoutTree() || GetComputedStyle()) {
// TODO(futhark): We need to traverse into IsUserActionElement() subtrees,
// even if they are already display:none because we do not clear the
// hovered/active bits as part of style recalc, but wait until the next time
// we do a hit test. That means we could be doing a forced layout tree update
// making a hovered subtree display:none and immediately remove the subtree
// leaving stale hovered/active state on ancestors. See relevant issues:
// https://crbug.com/967548
// https://crbug.com/939769
if (ChildNeedsReattachLayoutTree() || GetComputedStyle() ||
(!performing_reattach && IsUserActionElement())) {
if (ShadowRoot* shadow_root = GetShadowRoot()) {
shadow_root->DetachLayoutTree(performing_reattach);
Node::DetachLayoutTree(performing_reattach);
......
<!doctype html>
<title>CSS Reftest Reference</title>
<p>Clicking the right square should make the left one go green.</p>
<div style="width: 100px; height: 100px; background: green;"></div>
<!doctype html>
<html class="reftest-wait">
<title>Selectors: :hover style cleared on ancestor when hovered element is removed.</title>
<link rel="help" href="https://drafts.csswg.org/selectors/#the-hover-pseudo">
<link rel="match" href="remove-hovered-element-ref.html">
<script src="/common/reftest-wait.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<style>
div {
width: 100px;
height: 100px;
background: green;
}
#outer:hover {
background-color: red;
}
#relative {
position: relative;
left: 150px;
}
</style>
<p>Clicking the right square should make the left one go green.</p>
<div id="outer">
<div id="relative"><div id="inner">Click me</div></div>
</div>
<script>
inner.addEventListener("click", () => {
relative.style.display = "none";
// force layout box removal
document.body.offsetTop;
relative.remove();
takeScreenshot();
});
// Hover #inner and click.
var actions = new test_driver.Actions();
actions.pointerMove(0, 0, {origin: inner}).pointerDown().pointerUp().send();
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment