diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/relpos-inline-element-js-offsets.txt b/Tests/LibWeb/Layout/expected/block-and-inline/relpos-inline-element-js-offsets.txt
index e5ba2553d6f..dd47cd5571f 100644
--- a/Tests/LibWeb/Layout/expected/block-and-inline/relpos-inline-element-js-offsets.txt
+++ b/Tests/LibWeb/Layout/expected/block-and-inline/relpos-inline-element-js-offsets.txt
@@ -22,10 +22,10 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BreakNode
BreakNode
BlockContainer
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> diff --git a/Tests/LibWeb/Text/expected/DOM/Offset-of-empty-inline-element.txt b/Tests/LibWeb/Text/expected/DOM/Offset-of-empty-inline-element.txt index 369a7c12782..b2808a6caec 100644 --- a/Tests/LibWeb/Text/expected/DOM/Offset-of-empty-inline-element.txt +++ b/Tests/LibWeb/Text/expected/DOM/Offset-of-empty-inline-element.txt @@ -1,2 +1,2 @@ - Top: 0 -Left: 0 + Top: 16 +Left: 8 diff --git a/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp index 04a281d6118..2f4310573da 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp @@ -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