LibWeb: Make HTMLElement.offset{Left,Top} work on inline elements

Before this change, we were returning (0, 0) for inline elements, due to
a bogus paintable type check in box_type_agnostic_position().
This commit is contained in:
Andreas Kling 2023-08-15 15:51:54 +02:00
parent 79db9c27c6
commit dea91afba7
Notes: sideshowbarker 2024-07-16 23:34:44 +09:00
3 changed files with 86 additions and 10 deletions

View file

@ -0,0 +1,58 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x156.6875 children: not-inline
BlockContainer <(anonymous)> at (8,8) content-size 784x17.46875 children: inline
line 0 width: 136.609375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 5, rect: [8,8 36.40625x17.46875]
"well "
frag 1 from TextNode start: 0, length: 6, rect: [44,33 44.84375x17.46875]
"hello "
frag 2 from TextNode start: 0, length: 7, rect: [89,58 55.359375x17.46875]
"friends"
InlineNode <span>
TextNode <#text>
InlineNode <b>
TextNode <#text>
InlineNode <i>
TextNode <#text>
TextNode <#text>
BlockContainer <div> at (8,25.46875) content-size 784x139.21875 children: not-inline
BlockContainer <(anonymous)> at (8,25.46875) content-size 784x69.875 children: inline
line 0 width: 0, height: 17.46875, bottom: 17.46875, baseline: 13.53125
line 1 width: 0, height: 17.46875, bottom: 34.9375, baseline: 13.53125
line 2 width: 0, height: 17.46875, bottom: 52.40625, baseline: 13.53125
line 3 width: 0, height: 17.46875, bottom: 69.875, baseline: 13.53125
BreakNode <br>
BreakNode <br>
BreakNode <br>
BreakNode <br>
BlockContainer <pre#out> at (8,111.34375) content-size 784x53.34375 children: inline
line 0 width: 72.421875, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 10, rect: [8,111.34375 72.421875x17.46875]
"well: 0, 0"
line 1 width: 96.765625, height: 17.9375, bottom: 35.40625, baseline: 13.53125
frag 0 from TextNode start: 11, length: 13, rect: [8,128.34375 96.765625x17.46875]
"hello: 36, 25"
line 2 width: 113.65625, height: 18.40625, bottom: 53.34375, baseline: 13.53125
frag 0 from TextNode start: 25, length: 15, rect: [8,145.34375 113.65625x17.46875]
"friends: 45, 25"
TextNode <#text>
BlockContainer <(anonymous)> at (8,180.6875) content-size 784x0 children: inline
TextNode <#text>
TextNode <#text>
PaintableWithLines (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x156.6875] overflow: [8,8 784x172.6875]
PaintableWithLines (BlockContainer(anonymous)) [8,8 784x17.46875] overflow: [8,8 784x67.46875]
InlinePaintable (InlineNode<SPAN>)
TextPaintable (TextNode<#text>)
InlinePaintable (InlineNode<B>)
TextPaintable (TextNode<#text>)
InlinePaintable (InlineNode<I>)
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<DIV>) [8,25.46875 784x139.21875]
PaintableWithLines (BlockContainer(anonymous)) [8,25.46875 784x69.875]
PaintableWithLines (BlockContainer<PRE>#out) [8,111.34375 784x53.34375]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer(anonymous)) [8,180.6875 784x0]

View file

@ -0,0 +1,20 @@
<style>
b, i {
position: relative;
top: 25px;
}
</style><span>well <b>hello <i>friends</i></b></span>
<div><br><br><br><br><pre id=out></pre></div>
<script>
function println(s) {
let out = document.getElementById("out");
out.innerHTML += s + "\n";
}
let i = document.getElementsByTagName("i")[0]
let b = document.getElementsByTagName("b")[0]
let span = document.getElementsByTagName("span")[0]
println("well: " + span.offsetLeft + ", " + span.offsetTop)
println("hello: " + b.offsetLeft + ", " + b.offsetTop)
println("friends: " + i.offsetLeft + ", " + i.offsetTop)
</script>

View file

@ -229,16 +229,14 @@ CSSPixelPoint Node::box_type_agnostic_position() const
return verify_cast<Box>(*this).paintable_box()->absolute_position();
VERIFY(is_inline());
CSSPixelPoint position;
if (auto* block = containing_block()) {
if (is<Painting::PaintableWithLines>(*block)) {
static_cast<Painting::PaintableWithLines const&>(*block->paintable_box()).for_each_fragment([&](auto& fragment) {
if (&fragment.layout_node() == this || is_ancestor_of(fragment.layout_node())) {
position = fragment.absolute_rect().location();
return IterationDecision::Break;
}
return IterationDecision::Continue;
});
}
if (auto* block = containing_block(); block && block->paintable() && is<Painting::PaintableWithLines>(*block->paintable())) {
static_cast<Painting::PaintableWithLines const&>(*block->paintable_box()).for_each_fragment([&](auto& fragment) {
if (&fragment.layout_node() == this || is_ancestor_of(fragment.layout_node())) {
position = fragment.absolute_rect().location();
return IterationDecision::Break;
}
return IterationDecision::Continue;
});
}
return position;
}