LibWeb: Don't hit test anonymous containers if there are no fragments

We were always delegating hit tests to PaintableBox if a
PaintableWithLines has no fragments, which means that anonymous
containers could overlap with previous siblings and prioritize their
border box rect. Instead, the nearest non-anonymous ancestor should take
care of hit testing the children so the correct order is maintained.

To achieve this, we no longer do an early hit test in
PaintableWithLines::hit_test() if there are no fragments and default
to the later PaintableBox::hit_test() call that does take anonymous
containers into account.

Fixes the issue seen in #4864.
This commit is contained in:
Jelle Raaijmakers 2025-07-04 14:57:30 +02:00 committed by Tim Ledbetter
commit 2cc8f0821c
Notes: github-actions[bot] 2025-07-05 22:57:45 +00:00
3 changed files with 24 additions and 2 deletions

View file

@ -1203,7 +1203,7 @@ TraversalDecision PaintableWithLines::hit_test(CSSPixelPoint position, HitTestTy
return TraversalDecision::Break;
}
if (!layout_node().children_are_inline() || m_fragments.is_empty())
if (!layout_node().children_are_inline())
return PaintableBox::hit_test(position, type, callback);
// NOTE: This CSSPixels -> Float -> CSSPixels conversion is because we can't AffineTransform::map() a CSSPixelPoint.
@ -1282,7 +1282,7 @@ TraversalDecision PaintableWithLines::hit_test(CSSPixelPoint position, HitTestTy
}
}
if (!stacking_context() && is_visible() && !layout_node().is_anonymous()
if (!stacking_context() && is_visible() && (!layout_node().is_anonymous() || layout_node().is_positioned())
&& absolute_border_box_rect().contains(position_adjusted_by_scroll_offset)) {
if (callback(HitTestResult { const_cast<PaintableWithLines&>(*this) }) == TraversalDecision::Break)
return TraversalDecision::Break;