LibWeb: Always check paintable boxes children during hit-testing

Children of a paintable box are not guaranteed to be contained within
its border box. Therefore, during hit-testing, we must always check
them.

Fixes https://github.com/SerenityOS/serenity/issues/23219
This commit is contained in:
Aliaksandr Kalenik 2024-03-05 13:46:03 +01:00 committed by Andreas Kling
parent c1dbde72e9
commit 16f33aafda
Notes: sideshowbarker 2024-07-17 03:16:02 +09:00
5 changed files with 49 additions and 3 deletions

View File

@ -0,0 +1 @@
here be bugsyou can't see me toggle open

View File

@ -0,0 +1,28 @@
<!DOCTYPE html><style>
body {
margin: 0;
}
* {
border: 1px solid black;
}
nav {
position: absolute;
height: 600px;
}
nav > div {
height: 100%;
}
</style><nav><div></div><button id="btn">Run</button></nav>
<script src="../include.js"></script>
<script>
asyncTest(done => {
btn.onclick = () => {
println("Clicked!");
done();
};
internals.click(20, 615);
});
</script>

View File

@ -0,0 +1,16 @@
<style>
body {
margin: 0;
}
</style>
<details id="details"><summary><span>here be bugs</span></summary><span>you can't see me</span></details>
<script src="../include.js"></script>
<script>
asyncTest(done => {
details.ontoggle = (event) => {
println(`toggle ${event.newState}`);
done();
};
internals.click(5, 5);
});
</script>

View File

@ -861,9 +861,6 @@ TraversalDecision PaintableBox::hit_test(CSSPixelPoint position, HitTestType typ
return stacking_context()->hit_test(position, type, callback);
}
if (!absolute_border_box_rect().contains(position_adjusted_by_scroll_offset.x(), position_adjusted_by_scroll_offset.y()))
return TraversalDecision::Continue;
for (auto const* child = last_child(); child; child = child->previous_sibling()) {
auto z_index = child->computed_values().z_index();
if (child->layout_node().is_positioned() && z_index.value_or(0) == 0)
@ -872,6 +869,9 @@ TraversalDecision PaintableBox::hit_test(CSSPixelPoint position, HitTestType typ
return TraversalDecision::Break;
}
if (!absolute_border_box_rect().contains(position_adjusted_by_scroll_offset.x(), position_adjusted_by_scroll_offset.y()))
return TraversalDecision::Continue;
if (!visible_for_hit_testing())
return TraversalDecision::Continue;