diff --git a/Libraries/LibWeb/Layout/Box.cpp b/Libraries/LibWeb/Layout/Box.cpp index a6a7e34b3c..62941a20ec 100644 --- a/Libraries/LibWeb/Layout/Box.cpp +++ b/Libraries/LibWeb/Layout/Box.cpp @@ -106,9 +106,7 @@ HitTestResult Box::hit_test(const Gfx::IntPoint& position, HitTestType type) con // parts of the layout tree, but currently we can't just check // m_rect.contains() since inline text rects can't be trusted.. HitTestResult result { absolute_rect().contains(position.x(), position.y()) ? this : nullptr }; - for_each_child([&](auto& child) { - if (is(child) && downcast(child).stacking_context()) - return; + for_each_child_in_paint_order([&](auto& child) { auto child_result = child.hit_test(position, type); if (child_result.layout_node) result = child_result; diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index 6086295835..b1147bd5c6 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -93,9 +93,7 @@ void Node::paint(PaintContext& context, PaintPhase phase) before_children_paint(context, phase); - for_each_child([&](auto& child) { - if (child.is_box() && downcast(child).stacking_context()) - return; + for_each_child_in_paint_order([&](auto& child) { child.paint(context, phase); }); @@ -105,11 +103,7 @@ void Node::paint(PaintContext& context, PaintPhase phase) HitTestResult Node::hit_test(const Gfx::IntPoint& position, HitTestType type) const { HitTestResult result; - for_each_child([&](auto& child) { - // Skip over children that establish their own stacking context. - // The outer loop who called us will take care of those. - if (is(child) && downcast(child).stacking_context()) - return; + for_each_child_in_paint_order([&](auto& child) { auto child_result = child.hit_test(position, type); if (child_result.layout_node) result = child_result; diff --git a/Libraries/LibWeb/Layout/Node.h b/Libraries/LibWeb/Layout/Node.h index 1fe0792bf7..69a7192b4f 100644 --- a/Libraries/LibWeb/Layout/Node.h +++ b/Libraries/LibWeb/Layout/Node.h @@ -177,6 +177,23 @@ public: SelectionState selection_state() const { return m_selection_state; } void set_selection_state(SelectionState state) { m_selection_state = state; } + template + void for_each_child_in_paint_order(Callback callback) const + { + for_each_child([&](auto& child) { + if (is(child) && downcast(child).stacking_context()) + return; + if (!child.is_positioned()) + callback(child); + }); + for_each_child([&](auto& child) { + if (is(child) && downcast(child).stacking_context()) + return; + if (child.is_positioned()) + callback(child); + }); + } + protected: Node(DOM::Document&, DOM::Node*);