mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-10 01:51:03 +09:00
LibWeb: Account for CSS transform in Element::getClientRects()
This commit is contained in:
parent
96d5f555e1
commit
fb2166f19c
Notes:
sideshowbarker
2024-07-17 07:14:09 +09:00
Author: https://github.com/kalenikaliaksandr
Commit: fb2166f19c
Pull-request: https://github.com/SerenityOS/serenity/pull/23015
3 changed files with 45 additions and 3 deletions
|
@ -0,0 +1 @@
|
||||||
|
{"x":68,"y":118,"width":100,"height":100,"top":118,"right":168,"bottom":218,"left":68}
|
|
@ -0,0 +1,30 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<style type="text/css">
|
||||||
|
.transform-1 {
|
||||||
|
transform: translate(100px, 100px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.transform-2 {
|
||||||
|
transform: translate(-50px, 0px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#box {
|
||||||
|
background-color: magenta;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
opacity: 0.1;
|
||||||
|
transform: translate(10px, 10px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="transform-1">
|
||||||
|
<div class="transform-2">
|
||||||
|
<div id="box"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="include.js"></script>
|
||||||
|
<script>
|
||||||
|
test(() => {
|
||||||
|
const transformed_box_rect = document.getElementById("box").getBoundingClientRect();
|
||||||
|
println(JSON.stringify(transformed_box_rect));
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -900,7 +900,7 @@ JS::NonnullGCPtr<Geometry::DOMRectList> Element::get_client_rects() const
|
||||||
|
|
||||||
// 3. Return a DOMRectList object containing DOMRect objects in content order, one for each box fragment,
|
// 3. Return a DOMRectList object containing DOMRect objects in content order, one for each box fragment,
|
||||||
// describing its border area (including those with a height or width of zero) with the following constraints:
|
// describing its border area (including those with a height or width of zero) with the following constraints:
|
||||||
// FIXME: - Apply the transforms that apply to the element and its ancestors.
|
// - Apply the transforms that apply to the element and its ancestors.
|
||||||
// FIXME: - If the element on which the method was invoked has a computed value for the display property of table
|
// FIXME: - If the element on which the method was invoked has a computed value for the display property of table
|
||||||
// or inline-table include both the table box and the caption box, if any, but not the anonymous container box.
|
// or inline-table include both the table box and the caption box, if any, but not the anonymous container box.
|
||||||
// FIXME: - Replace each anonymous block box with its child box(es) and repeat this until no anonymous block boxes
|
// FIXME: - Replace each anonymous block box with its child box(es) and repeat this until no anonymous block boxes
|
||||||
|
@ -908,16 +908,27 @@ JS::NonnullGCPtr<Geometry::DOMRectList> Element::get_client_rects() const
|
||||||
const_cast<Document&>(document()).update_layout();
|
const_cast<Document&>(document()).update_layout();
|
||||||
VERIFY(document().navigable());
|
VERIFY(document().navigable());
|
||||||
auto viewport_offset = document().navigable()->viewport_scroll_offset();
|
auto viewport_offset = document().navigable()->viewport_scroll_offset();
|
||||||
|
|
||||||
|
Gfx::AffineTransform transform;
|
||||||
|
for (auto const* containing_block = this->layout_node(); containing_block; containing_block = containing_block->containing_block()) {
|
||||||
|
Gfx::AffineTransform containing_block_transform;
|
||||||
|
if (containing_block->paintable() && containing_block->paintable()->is_paintable_box()) {
|
||||||
|
auto const& containing_block_paintable_box = static_cast<Painting::PaintableBox const&>(*containing_block->paintable());
|
||||||
|
containing_block_transform = Gfx::extract_2d_affine_transform(containing_block_paintable_box.transform());
|
||||||
|
}
|
||||||
|
transform = transform.multiply(containing_block_transform);
|
||||||
|
}
|
||||||
|
|
||||||
auto const* paintable = this->paintable();
|
auto const* paintable = this->paintable();
|
||||||
if (auto const* paintable_box = this->paintable_box()) {
|
if (auto const* paintable_box = this->paintable_box()) {
|
||||||
auto absolute_rect = paintable_box->absolute_border_box_rect();
|
auto absolute_rect = paintable_box->absolute_border_box_rect();
|
||||||
absolute_rect.translate_by(-viewport_offset.x(), -viewport_offset.y());
|
absolute_rect.translate_by(-viewport_offset.x(), -viewport_offset.y());
|
||||||
rects.append(Geometry::DOMRect::create(realm(), absolute_rect.to_type<float>()));
|
rects.append(Geometry::DOMRect::create(realm(), transform.map(absolute_rect.to_type<float>())));
|
||||||
} else if (paintable && is<Painting::InlinePaintable>(*paintable)) {
|
} else if (paintable && is<Painting::InlinePaintable>(*paintable)) {
|
||||||
auto const& inline_paintable = static_cast<Painting::InlinePaintable const&>(*paintable);
|
auto const& inline_paintable = static_cast<Painting::InlinePaintable const&>(*paintable);
|
||||||
auto absolute_rect = inline_paintable.bounding_rect();
|
auto absolute_rect = inline_paintable.bounding_rect();
|
||||||
absolute_rect.translate_by(-viewport_offset.x(), -viewport_offset.y());
|
absolute_rect.translate_by(-viewport_offset.x(), -viewport_offset.y());
|
||||||
rects.append(Geometry::DOMRect::create(realm(), absolute_rect.to_type<float>()));
|
rects.append(Geometry::DOMRect::create(realm(), transform.map(absolute_rect.to_type<float>())));
|
||||||
} else if (paintable) {
|
} else if (paintable) {
|
||||||
dbgln("FIXME: Failed to get client rects for element ({})", debug_description());
|
dbgln("FIXME: Failed to get client rects for element ({})", debug_description());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue