diff --git a/Userland/Libraries/LibWeb/DOM/Node.h b/Userland/Libraries/LibWeb/DOM/Node.h index 96392c2d66..8e1818a754 100644 --- a/Userland/Libraries/LibWeb/DOM/Node.h +++ b/Userland/Libraries/LibWeb/DOM/Node.h @@ -636,6 +636,15 @@ public: return nullptr; } + template + U const* shadow_including_first_ancestor_of_type() const + { + return const_cast(this)->template shadow_including_first_ancestor_of_type(); + } + + template + U* shadow_including_first_ancestor_of_type(); + bool is_parent_of(Node const& other) const { for (auto* child = first_child(); child; child = child->next_sibling()) { diff --git a/Userland/Libraries/LibWeb/DOM/ParentNode.h b/Userland/Libraries/LibWeb/DOM/ParentNode.h index 4501822bd3..0761d23fb1 100644 --- a/Userland/Libraries/LibWeb/DOM/ParentNode.h +++ b/Userland/Libraries/LibWeb/DOM/ParentNode.h @@ -55,6 +55,16 @@ private: template<> inline bool Node::fast_is() const { return is_parent_node(); } +template +inline U* Node::shadow_including_first_ancestor_of_type() +{ + for (auto* ancestor = parent_or_shadow_host(); ancestor; ancestor = ancestor->parent_or_shadow_host()) { + if (is(*ancestor)) + return &verify_cast(*ancestor); + } + return nullptr; +} + template inline void ParentNode::for_each_child(Callback callback) const { diff --git a/Userland/Libraries/LibWeb/Layout/SVGGeometryBox.cpp b/Userland/Libraries/LibWeb/Layout/SVGGeometryBox.cpp index b1497c05e6..134d764642 100644 --- a/Userland/Libraries/LibWeb/Layout/SVGGeometryBox.cpp +++ b/Userland/Libraries/LibWeb/Layout/SVGGeometryBox.cpp @@ -19,7 +19,7 @@ SVGGeometryBox::SVGGeometryBox(DOM::Document& document, SVG::SVGGeometryElement& CSSPixelPoint SVGGeometryBox::viewbox_origin() const { - auto* svg_box = dom_node().first_ancestor_of_type(); + auto* svg_box = dom_node().shadow_including_first_ancestor_of_type(); if (!svg_box || !svg_box->view_box().has_value()) return { 0, 0 }; return { svg_box->view_box().value().min_x, svg_box->view_box().value().min_y }; @@ -29,7 +29,7 @@ Optional SVGGeometryBox::layout_transform() const { auto& geometry_element = dom_node(); auto transform = geometry_element.get_transform(); - auto* svg_box = geometry_element.first_ancestor_of_type(); + auto* svg_box = geometry_element.shadow_including_first_ancestor_of_type(); double scaling = 1; auto origin = viewbox_origin().to_type().to_type(); Gfx::FloatPoint paint_offset = {}; diff --git a/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp b/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp index 979a59fbf3..931b8f6211 100644 --- a/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp +++ b/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp @@ -62,7 +62,7 @@ void SVGGeometryPaintable::paint(PaintContext& context, PaintPhase phase) const auto offset = context.floored_device_point(svg_context.svg_element_position()).to_type().to_type(); painter.translate(offset); - auto const* svg_element = geometry_element.first_ancestor_of_type(); + auto const* svg_element = geometry_element.shadow_including_first_ancestor_of_type(); auto maybe_view_box = svg_element->view_box(); auto transform = layout_box().layout_transform(); diff --git a/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp index 3b9ca3419d..54e1528b6e 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp @@ -97,7 +97,7 @@ Gfx::AffineTransform SVGGraphicsElement::get_transform() const { // FIXME: It would be nice to do this using the SVGContext, however, then layout/hit testing knows nothing about the transform. Gfx::AffineTransform transform = m_transform; - for (auto* svg_ancestor = first_ancestor_of_type(); svg_ancestor; svg_ancestor = svg_ancestor->first_ancestor_of_type()) { + for (auto* svg_ancestor = shadow_including_first_ancestor_of_type(); svg_ancestor; svg_ancestor = svg_ancestor->shadow_including_first_ancestor_of_type()) { transform = Gfx::AffineTransform { svg_ancestor->m_transform }.multiply(transform); } return transform; @@ -179,7 +179,7 @@ Optional SVGGraphicsElement::stroke_width() const // FIXME: This isn't right, but it's something. CSSPixels viewport_width = 0; CSSPixels viewport_height = 0; - if (auto* svg_svg_element = first_ancestor_of_type()) { + if (auto* svg_svg_element = shadow_including_first_ancestor_of_type()) { if (auto* svg_svg_layout_node = svg_svg_element->layout_node()) { viewport_width = svg_svg_layout_node->computed_values().width().to_px(*svg_svg_layout_node, 0); viewport_height = svg_svg_layout_node->computed_values().height().to_px(*svg_svg_layout_node, 0);