mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-12 19:19:30 +00:00
LibWeb: Make offsetTop and offsetLeft behave more like other browsers
We now follow the rules from the spec more closely, along with an unspecified quirk for when the offsetParent is a non-positioned body element. (Spec bug linked in a comment.) This fixes a whole bunch of css-flexbox tests on WPT, which already had correct layout, but the reported metrics from JS API were wrong.
This commit is contained in:
parent
34583902dc
commit
d49ae5af32
Notes:
github-actions[bot]
2024-07-25 16:52:52 +00:00
Author: https://github.com/awesomekling
Commit: d49ae5af32
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/831
3 changed files with 48 additions and 16 deletions
|
@ -22,10 +22,10 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
|||
BreakNode <br>
|
||||
BreakNode <br>
|
||||
BlockContainer <pre#out> at (8,109) content-size 784x51 children: inline
|
||||
frag 0 from TextNode start: 0, length: 10, rect: [8,109 72.421875x17] baseline: 13.296875
|
||||
"well: 0, 0"
|
||||
frag 1 from TextNode start: 11, length: 13, rect: [8,126 96.765625x17] baseline: 13.296875
|
||||
"hello: 36, 25"
|
||||
frag 0 from TextNode start: 0, length: 10, rect: [8,109 72.203125x17] baseline: 13.296875
|
||||
"well: 8, 8"
|
||||
frag 1 from TextNode start: 11, length: 13, rect: [8,126 95.359375x17] baseline: 13.296875
|
||||
"hello: 44, 33"
|
||||
frag 2 from TextNode start: 25, length: 15, rect: [8,143 113.65625x17] baseline: 13.296875
|
||||
"friends: 45, 25"
|
||||
TextNode <#text>
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
Top: 0
|
||||
Left: 0
|
||||
Top: 16
|
||||
Left: 8
|
||||
|
|
|
@ -260,14 +260,20 @@ int HTMLElement::offset_top() const
|
|||
if (!layout_node())
|
||||
return 0;
|
||||
|
||||
CSSPixels top_border_edge_of_element;
|
||||
if (paintable()->is_paintable_box()) {
|
||||
top_border_edge_of_element = paintable_box()->absolute_border_box_rect().y();
|
||||
} else {
|
||||
top_border_edge_of_element = paintable()->box_type_agnostic_position().y();
|
||||
}
|
||||
|
||||
// 2. If the offsetParent of the element is null
|
||||
// return the y-coordinate of the top border edge of the first CSS layout box associated with the element,
|
||||
// relative to the initial containing block origin,
|
||||
// ignoring any transforms that apply to the element and its ancestors, and terminate this algorithm.
|
||||
auto offset_parent = this->offset_parent();
|
||||
if (!offset_parent || !offset_parent->layout_node()) {
|
||||
auto position = paintable()->box_type_agnostic_position();
|
||||
return position.y().to_int();
|
||||
return top_border_edge_of_element.to_int();
|
||||
}
|
||||
|
||||
// 3. Return the result of subtracting the y-coordinate of the top padding edge
|
||||
|
@ -275,9 +281,19 @@ int HTMLElement::offset_top() const
|
|||
// from the y-coordinate of the top border edge of the first box associated with the element,
|
||||
// relative to the initial containing block origin,
|
||||
// ignoring any transforms that apply to the element and its ancestors.
|
||||
auto offset_parent_position = offset_parent->paintable()->box_type_agnostic_position();
|
||||
auto position = paintable()->box_type_agnostic_position();
|
||||
return position.y().to_int() - offset_parent_position.y().to_int();
|
||||
|
||||
// NOTE: We give special treatment to the body element to match other browsers.
|
||||
// Spec bug: https://github.com/w3c/csswg-drafts/issues/10549
|
||||
|
||||
CSSPixels top_padding_edge_of_offset_parent;
|
||||
if (offset_parent->is_html_body_element() && !offset_parent->paintable()->is_positioned()) {
|
||||
top_padding_edge_of_offset_parent = 0;
|
||||
} else if (offset_parent->paintable()->is_paintable_box()) {
|
||||
top_padding_edge_of_offset_parent = offset_parent->paintable_box()->absolute_padding_box_rect().y();
|
||||
} else {
|
||||
top_padding_edge_of_offset_parent = offset_parent->paintable()->box_type_agnostic_position().y();
|
||||
}
|
||||
return (top_border_edge_of_element - top_padding_edge_of_offset_parent).to_int();
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/cssom-view-1/#dom-htmlelement-offsetleft
|
||||
|
@ -293,14 +309,20 @@ int HTMLElement::offset_left() const
|
|||
if (!layout_node())
|
||||
return 0;
|
||||
|
||||
CSSPixels left_border_edge_of_element;
|
||||
if (paintable()->is_paintable_box()) {
|
||||
left_border_edge_of_element = paintable_box()->absolute_border_box_rect().x();
|
||||
} else {
|
||||
left_border_edge_of_element = paintable()->box_type_agnostic_position().x();
|
||||
}
|
||||
|
||||
// 2. If the offsetParent of the element is null
|
||||
// return the x-coordinate of the left border edge of the first CSS layout box associated with the element,
|
||||
// relative to the initial containing block origin,
|
||||
// ignoring any transforms that apply to the element and its ancestors, and terminate this algorithm.
|
||||
auto offset_parent = this->offset_parent();
|
||||
if (!offset_parent || !offset_parent->layout_node()) {
|
||||
auto position = paintable()->box_type_agnostic_position();
|
||||
return position.x().to_int();
|
||||
return left_border_edge_of_element.to_int();
|
||||
}
|
||||
|
||||
// 3. Return the result of subtracting the x-coordinate of the left padding edge
|
||||
|
@ -308,9 +330,19 @@ int HTMLElement::offset_left() const
|
|||
// from the x-coordinate of the left border edge of the first CSS layout box associated with the element,
|
||||
// relative to the initial containing block origin,
|
||||
// ignoring any transforms that apply to the element and its ancestors.
|
||||
auto offset_parent_position = offset_parent->paintable()->box_type_agnostic_position();
|
||||
auto position = paintable()->box_type_agnostic_position();
|
||||
return position.x().to_int() - offset_parent_position.x().to_int();
|
||||
|
||||
// NOTE: We give special treatment to the body element to match other browsers.
|
||||
// Spec bug: https://github.com/w3c/csswg-drafts/issues/10549
|
||||
|
||||
CSSPixels left_padding_edge_of_offset_parent;
|
||||
if (offset_parent->is_html_body_element() && !offset_parent->paintable()->is_positioned()) {
|
||||
left_padding_edge_of_offset_parent = 0;
|
||||
} else if (offset_parent->paintable()->is_paintable_box()) {
|
||||
left_padding_edge_of_offset_parent = offset_parent->paintable_box()->absolute_padding_box_rect().x();
|
||||
} else {
|
||||
left_padding_edge_of_offset_parent = offset_parent->paintable()->box_type_agnostic_position().x();
|
||||
}
|
||||
return (left_border_edge_of_element - left_padding_edge_of_offset_parent).to_int();
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetwidth
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue