diff --git a/Tests/LibWeb/Text/expected/get-bounding-client-rect.txt b/Tests/LibWeb/Text/expected/get-bounding-client-rect.txt
index d7833895ea..4ecaca45e0 100644
--- a/Tests/LibWeb/Text/expected/get-bounding-client-rect.txt
+++ b/Tests/LibWeb/Text/expected/get-bounding-client-rect.txt
@@ -1 +1,2 @@
- {"x":8,"y":500,"width":784,"height":150,"top":500,"right":792,"bottom":650,"left":8}
\ No newline at end of file
+ inline {"x":8,"y":500,"width":784,"height":150,"top":500,"right":792,"bottom":650,"left":8}
+{"x":8,"y":650,"width":41.296875,"height":17.46875,"top":650,"right":49.296875,"bottom":667.46875,"left":8}
\ No newline at end of file
diff --git a/Tests/LibWeb/Text/input/get-bounding-client-rect.html b/Tests/LibWeb/Text/input/get-bounding-client-rect.html
index 3206ec0aa5..eb7da97d5d 100644
--- a/Tests/LibWeb/Text/input/get-bounding-client-rect.html
+++ b/Tests/LibWeb/Text/input/get-bounding-client-rect.html
@@ -9,10 +9,16 @@
}
+inline
diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp
index 8f00731784..7cdc6aa951 100644
--- a/Userland/Libraries/LibWeb/DOM/Element.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Element.cpp
@@ -61,6 +61,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -834,16 +835,24 @@ JS::NonnullGCPtr Element::get_bounding_client_rect() const
{
// // NOTE: Ensure that layout is up-to-date before looking at metrics.
const_cast(document()).update_layout();
-
- // FIXME: Support inline layout nodes as well.
- auto* paintable_box = this->paintable_box();
- if (!paintable_box)
- return Geometry::DOMRect::construct_impl(realm(), 0, 0, 0, 0).release_value_but_fixme_should_propagate_errors();
-
VERIFY(document().navigable());
auto viewport_offset = document().navigable()->viewport_scroll_offset();
- return Geometry::DOMRect::create(realm(), paintable_box->absolute_border_box_rect().translated(-viewport_offset.x(), -viewport_offset.y()).to_type());
+ if (auto const* paintable_box = this->paintable_box()) {
+ auto absolute_rect = paintable_box->absolute_border_box_rect();
+ absolute_rect.translate_by(-viewport_offset.x(), -viewport_offset.y());
+ return Geometry::DOMRect::create(realm(), absolute_rect.to_type());
+ }
+
+ if (auto const* paintable = this->paintable(); is(*paintable)) {
+ auto const& inline_paintable = static_cast(*paintable);
+ auto absolute_rect = inline_paintable.bounding_rect();
+ absolute_rect.translate_by(-viewport_offset.x(), -viewport_offset.y());
+ return Geometry::DOMRect::create(realm(), absolute_rect.to_type());
+ }
+
+ dbgln("FIXME: Failed to get bounding client rect for element ({})", debug_description());
+ return Geometry::DOMRect::construct_impl(realm(), 0, 0, 0, 0).release_value_but_fixme_should_propagate_errors();
}
// https://drafts.csswg.org/cssom-view/#dom-element-getclientrects
diff --git a/Userland/Libraries/LibWeb/Painting/InlinePaintable.cpp b/Userland/Libraries/LibWeb/Painting/InlinePaintable.cpp
index 98162fd5c9..ceb4883b35 100644
--- a/Userland/Libraries/LibWeb/Painting/InlinePaintable.cpp
+++ b/Userland/Libraries/LibWeb/Painting/InlinePaintable.cpp
@@ -173,4 +173,32 @@ void InlinePaintable::for_each_fragment(Callback callback) const
}
}
+CSSPixelRect InlinePaintable::bounding_rect() const
+{
+ auto top = CSSPixels::max();
+ auto left = CSSPixels::max();
+ auto right = CSSPixels::min();
+ auto bottom = CSSPixels::min();
+ auto has_fragments = false;
+ for_each_fragment([&](auto const& fragment, bool, bool) {
+ has_fragments = true;
+ auto fragment_absolute_rect = fragment.absolute_rect();
+ if (fragment_absolute_rect.top() < top)
+ top = fragment_absolute_rect.top();
+ if (fragment_absolute_rect.left() < left)
+ left = fragment_absolute_rect.left();
+ if (fragment_absolute_rect.right() > right)
+ right = fragment_absolute_rect.right();
+ if (fragment_absolute_rect.bottom() > bottom)
+ bottom = fragment_absolute_rect.bottom();
+ });
+
+ if (!has_fragments) {
+ // FIXME: This is adhoc, and we should return rect of empty fragment instead.
+ auto containing_block_position_in_absolute_coordinates = containing_block()->paintable_box()->absolute_position();
+ return { containing_block_position_in_absolute_coordinates, { 0, 0 } };
+ }
+ return { left, top, right - left, bottom - top };
+}
+
}
diff --git a/Userland/Libraries/LibWeb/Painting/InlinePaintable.h b/Userland/Libraries/LibWeb/Painting/InlinePaintable.h
index f53e20fcb4..204413be6b 100644
--- a/Userland/Libraries/LibWeb/Painting/InlinePaintable.h
+++ b/Userland/Libraries/LibWeb/Painting/InlinePaintable.h
@@ -22,6 +22,8 @@ public:
Layout::InlineNode const& layout_node() const;
auto const& box_model() const { return layout_node().box_model(); }
+ CSSPixelRect bounding_rect() const;
+
private:
InlinePaintable(Layout::InlineNode const&);