Skip to content

Commit fb2166f

Browse files
kalenikaliaksandrawesomekling
authored andcommitted
LibWeb: Account for CSS transform in Element::getClientRects()
1 parent 96d5f55 commit fb2166f

File tree

3 files changed

+45
-3
lines changed

3 files changed

+45
-3
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"x":68,"y":118,"width":100,"height":100,"top":118,"right":168,"bottom":218,"left":68}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!DOCTYPE html>
2+
<style type="text/css">
3+
.transform-1 {
4+
transform: translate(100px, 100px);
5+
}
6+
7+
.transform-2 {
8+
transform: translate(-50px, 0px);
9+
}
10+
11+
#box {
12+
background-color: magenta;
13+
width: 100px;
14+
height: 100px;
15+
opacity: 0.1;
16+
transform: translate(10px, 10px);
17+
}
18+
</style>
19+
<div class="transform-1">
20+
<div class="transform-2">
21+
<div id="box"></div>
22+
</div>
23+
</div>
24+
<script src="include.js"></script>
25+
<script>
26+
test(() => {
27+
const transformed_box_rect = document.getElementById("box").getBoundingClientRect();
28+
println(JSON.stringify(transformed_box_rect));
29+
});
30+
</script>

Userland/Libraries/LibWeb/DOM/Element.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -900,24 +900,35 @@ JS::NonnullGCPtr<Geometry::DOMRectList> Element::get_client_rects() const
900900

901901
// 3. Return a DOMRectList object containing DOMRect objects in content order, one for each box fragment,
902902
// describing its border area (including those with a height or width of zero) with the following constraints:
903-
// FIXME: - Apply the transforms that apply to the element and its ancestors.
903+
// - Apply the transforms that apply to the element and its ancestors.
904904
// FIXME: - If the element on which the method was invoked has a computed value for the display property of table
905905
// or inline-table include both the table box and the caption box, if any, but not the anonymous container box.
906906
// FIXME: - Replace each anonymous block box with its child box(es) and repeat this until no anonymous block boxes
907907
// are left in the final list.
908908
const_cast<Document&>(document()).update_layout();
909909
VERIFY(document().navigable());
910910
auto viewport_offset = document().navigable()->viewport_scroll_offset();
911+
912+
Gfx::AffineTransform transform;
913+
for (auto const* containing_block = this->layout_node(); containing_block; containing_block = containing_block->containing_block()) {
914+
Gfx::AffineTransform containing_block_transform;
915+
if (containing_block->paintable() && containing_block->paintable()->is_paintable_box()) {
916+
auto const& containing_block_paintable_box = static_cast<Painting::PaintableBox const&>(*containing_block->paintable());
917+
containing_block_transform = Gfx::extract_2d_affine_transform(containing_block_paintable_box.transform());
918+
}
919+
transform = transform.multiply(containing_block_transform);
920+
}
921+
911922
auto const* paintable = this->paintable();
912923
if (auto const* paintable_box = this->paintable_box()) {
913924
auto absolute_rect = paintable_box->absolute_border_box_rect();
914925
absolute_rect.translate_by(-viewport_offset.x(), -viewport_offset.y());
915-
rects.append(Geometry::DOMRect::create(realm(), absolute_rect.to_type<float>()));
926+
rects.append(Geometry::DOMRect::create(realm(), transform.map(absolute_rect.to_type<float>())));
916927
} else if (paintable && is<Painting::InlinePaintable>(*paintable)) {
917928
auto const& inline_paintable = static_cast<Painting::InlinePaintable const&>(*paintable);
918929
auto absolute_rect = inline_paintable.bounding_rect();
919930
absolute_rect.translate_by(-viewport_offset.x(), -viewport_offset.y());
920-
rects.append(Geometry::DOMRect::create(realm(), absolute_rect.to_type<float>()));
931+
rects.append(Geometry::DOMRect::create(realm(), transform.map(absolute_rect.to_type<float>())));
921932
} else if (paintable) {
922933
dbgln("FIXME: Failed to get client rects for element ({})", debug_description());
923934
}

0 commit comments

Comments
 (0)