From 6994ea5885f613a78c718981d2e88db10060dfeb Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 10 Dec 2023 21:33:03 +0100 Subject: [PATCH] LibWeb: Skip out-of-flow boxes when wrapping inlines in anonymous block Out-of-flow boxes (floating and absolutely-positioned elements) were previously collected and put in the anonymous block wrapper as well, but this actually made hit testing not able to find them, since they were breaking expectations about tree structure that hit testing relies on. After this change, we simply let out-of-flow boxes stay in their original parent, preserving the author's intended box tree structure. --- ...-consider-all-currently-stacked-floats.txt | 20 +++++----- .../expected/block-and-inline/clearfix.txt | 4 +- .../expected/block-and-inline/float-2.txt | 6 +-- .../expected/position-absolute-top-left.txt | 32 ++++++++-------- .../resolve-height-of-containing-block.txt | 4 +- .../expected/set-margin-of-floating-box.txt | 6 +-- .../float-with-inline-sibling-after.txt | 1 + .../float-with-inline-sibling-after.html | 38 +++++++++++++++++++ .../Libraries/LibWeb/Layout/TreeBuilder.cpp | 13 +++++-- .../LibWeb/Painting/PaintableBox.cpp | 2 +- 10 files changed, 86 insertions(+), 40 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/hit_testing/float-with-inline-sibling-after.txt create mode 100644 Tests/LibWeb/Text/input/hit_testing/float-with-inline-sibling-after.html diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/bfc-consider-all-currently-stacked-floats.txt b/Tests/LibWeb/Layout/expected/block-and-inline/bfc-consider-all-currently-stacked-floats.txt index fdaa11b127..ce27a4ac5a 100644 --- a/Tests/LibWeb/Layout/expected/block-and-inline/bfc-consider-all-currently-stacked-floats.txt +++ b/Tests/LibWeb/Layout/expected/block-and-inline/bfc-consider-all-currently-stacked-floats.txt @@ -3,17 +3,17 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline BlockContainer <(anonymous)> at (0,0) content-size 800x0 children: inline TextNode <#text> BlockContainer at (8,8) content-size 784x34.9375 children: not-inline + BlockContainer at (8,8) content-size 100x100 floating [BFC] children: not-inline + BlockContainer at (108,8) content-size 29.109375x17.46875 floating [BFC] children: inline + line 0 width: 29.109375, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 0, length: 3, rect: [108,8 29.109375x17.46875] + "xxx" + TextNode <#text> BlockContainer <(anonymous)> at (8,8) content-size 784x17.46875 children: inline line 0 width: 27.640625, height: 17.46875, bottom: 17.46875, baseline: 13.53125 frag 0 from TextNode start: 1, length: 3, rect: [137,8 27.640625x17.46875] "bar" - BlockContainer at (8,8) content-size 100x100 floating [BFC] children: not-inline TextNode <#text> - BlockContainer at (108,8) content-size 29.109375x17.46875 floating [BFC] children: inline - line 0 width: 29.109375, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 3, rect: [108,8 29.109375x17.46875] - "xxx" - TextNode <#text> TextNode <#text> BlockContainer
at (8,25.46875) content-size 784x17.46875 children: inline line 0 width: 27.203125, height: 17.46875, bottom: 17.46875, baseline: 13.53125 @@ -32,11 +32,11 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline ViewportPaintable (Viewport<#document>) [0,0 800x600] PaintableWithLines (BlockContainer) [0,0 800x108] PaintableWithLines (BlockContainer(anonymous)) [0,0 800x0] - PaintableWithLines (BlockContainer) [8,8 784x34.9375] + PaintableWithLines (BlockContainer) [8,8 784x34.9375] overflow: [8,8 784x100] + PaintableWithLines (BlockContainer
.big-float) [8,8 100x100] + PaintableWithLines (BlockContainer
.xxx) [108,8 29.109375x17.46875] + TextPaintable (TextNode<#text>) PaintableWithLines (BlockContainer(anonymous)) [8,8 784x17.46875] - PaintableWithLines (BlockContainer
.big-float) [8,8 100x100] - PaintableWithLines (BlockContainer
.xxx) [108,8 29.109375x17.46875] - TextPaintable (TextNode<#text>) TextPaintable (TextNode<#text>) PaintableWithLines (BlockContainer
) [8,25.46875 784x17.46875] PaintableWithLines (BlockContainer
.yyy) [108,25.46875 21.515625x17.46875] diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/clearfix.txt b/Tests/LibWeb/Layout/expected/block-and-inline/clearfix.txt index 2d008679ef..e769496db7 100644 --- a/Tests/LibWeb/Layout/expected/block-and-inline/clearfix.txt +++ b/Tests/LibWeb/Layout/expected/block-and-inline/clearfix.txt @@ -2,9 +2,9 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline BlockContainer at (0,0) content-size 800x600 [BFC] children: not-inline BlockContainer at (8,8) content-size 784x100 children: not-inline BlockContainer
at (8,8) content-size 784x100 children: not-inline + BlockContainer at (8,8) content-size 100x100 floating [BFC] children: not-inline BlockContainer <(anonymous)> at (8,8) content-size 784x0 children: inline TextNode <#text> - BlockContainer at (8,8) content-size 100x100 floating [BFC] children: not-inline TextNode <#text> BlockContainer at (8,108) content-size 784x0 children: not-inline BlockContainer <(anonymous)> at (8,108) content-size 784x0 children: inline @@ -18,8 +18,8 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600] PaintableWithLines (BlockContainer) [0,0 800x600] PaintableWithLines (BlockContainer) [8,8 784x100] PaintableWithLines (BlockContainer
) [8,8 784x100] + PaintableWithLines (BlockContainer
.square.white) [8,8 100x100] PaintableWithLines (BlockContainer(anonymous)) [8,8 784x0] - PaintableWithLines (BlockContainer
.square.white) [8,8 100x100] PaintableWithLines (BlockContainer
.clearfix) [8,108 784x0] PaintableWithLines (BlockContainer(anonymous)) [8,108 784x0] PaintableWithLines (BlockContainer
.square.black) [8,108 49x49] diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/float-2.txt b/Tests/LibWeb/Layout/expected/block-and-inline/float-2.txt index f775d92c76..71420f5766 100644 --- a/Tests/LibWeb/Layout/expected/block-and-inline/float-2.txt +++ b/Tests/LibWeb/Layout/expected/block-and-inline/float-2.txt @@ -3,9 +3,9 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline BlockContainer <(anonymous)> at (0,0) content-size 800x0 children: inline TextNode <#text> BlockContainer at (8,8) content-size 784x17.46875 children: not-inline + BlockContainer at (9,9) content-size 50x50 floating [BFC] children: not-inline BlockContainer <(anonymous)> at (8,8) content-size 784x0 children: inline TextNode <#text> - BlockContainer at (9,9) content-size 50x50 floating [BFC] children: not-inline TextNode <#text> BlockContainer at (8,8) content-size 784x17.46875 children: inline line 0 width: 37.578125, height: 17.46875, bottom: 17.46875, baseline: 13.53125 @@ -18,9 +18,9 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline ViewportPaintable (Viewport<#document>) [0,0 800x600] PaintableWithLines (BlockContainer) [0,0 800x60] PaintableWithLines (BlockContainer(anonymous)) [0,0 800x0] - PaintableWithLines (BlockContainer) [8,8 784x17.46875] + PaintableWithLines (BlockContainer) [8,8 784x17.46875] overflow: [8,8 784x52] + PaintableWithLines (BlockContainer
#b) [8,8 52x52] PaintableWithLines (BlockContainer(anonymous)) [8,8 784x0] - PaintableWithLines (BlockContainer
#b) [8,8 52x52] PaintableWithLines (BlockContainer
#a) [8,8 784x17.46875] TextPaintable (TextNode<#text>) PaintableWithLines (BlockContainer(anonymous)) [8,25.46875 784x0] diff --git a/Tests/LibWeb/Layout/expected/position-absolute-top-left.txt b/Tests/LibWeb/Layout/expected/position-absolute-top-left.txt index 531018b468..a4d1aa4c00 100644 --- a/Tests/LibWeb/Layout/expected/position-absolute-top-left.txt +++ b/Tests/LibWeb/Layout/expected/position-absolute-top-left.txt @@ -3,19 +3,19 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline BlockContainer <(anonymous)> at (0,0) content-size 800x0 children: inline TextNode <#text> BlockContainer at (8,8) content-size 784x600 children: not-inline + BlockContainer at (208,208) content-size 200x200 positioned [BFC] children: inline + TextNode <#text> + BlockContainer at (308,308) content-size 100x100 positioned [BFC] children: not-inline + TextNode <#text> + BlockContainer at (258,258) content-size 100x100 positioned [BFC] children: inline + TextNode <#text> + BlockContainer at (308,308) content-size 50x50 positioned [BFC] children: not-inline + TextNode <#text> + TextNode <#text> + BlockContainer at (508,508) content-size 100x100 positioned [BFC] children: not-inline + TextNode <#text> BlockContainer <(anonymous)> at (8,8) content-size 784x0 children: inline TextNode <#text> - BlockContainer at (208,208) content-size 200x200 positioned [BFC] children: inline - TextNode <#text> - BlockContainer at (308,308) content-size 100x100 positioned [BFC] children: not-inline - TextNode <#text> - BlockContainer at (258,258) content-size 100x100 positioned [BFC] children: inline - TextNode <#text> - BlockContainer at (308,308) content-size 50x50 positioned [BFC] children: not-inline - TextNode <#text> - TextNode <#text> - BlockContainer at (508,508) content-size 100x100 positioned [BFC] children: not-inline - TextNode <#text> TextNode <#text> BlockContainer at (8,8) content-size 200x200 children: not-inline BlockContainer <(anonymous)> at (8,8) content-size 200x0 children: inline @@ -39,12 +39,12 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600] overflow: [0,0 800x616] PaintableWithLines (BlockContainer) [0,0 800x616] PaintableWithLines (BlockContainer(anonymous)) [0,0 800x0] PaintableWithLines (BlockContainer) [8,8 784x600] + PaintableWithLines (BlockContainer
.blue.absolute) [208,208 200x200] + PaintableWithLines (BlockContainer
.red.absolute) [308,308 100x100] + PaintableWithLines (BlockContainer
.yellow.absolute) [258,258 100x100] + PaintableWithLines (BlockContainer
.black.absolute) [308,308 50x50] + PaintableWithLines (BlockContainer
.green.absolute) [508,508 100x100] PaintableWithLines (BlockContainer(anonymous)) [8,8 784x0] - PaintableWithLines (BlockContainer
.blue.absolute) [208,208 200x200] - PaintableWithLines (BlockContainer
.red.absolute) [308,308 100x100] - PaintableWithLines (BlockContainer
.yellow.absolute) [258,258 100x100] - PaintableWithLines (BlockContainer
.black.absolute) [308,308 50x50] - PaintableWithLines (BlockContainer
.green.absolute) [508,508 100x100] PaintableWithLines (BlockContainer
.blue) [8,8 200x200] overflow: [8,8 200x300] PaintableWithLines (BlockContainer(anonymous)) [8,8 200x0] PaintableWithLines (BlockContainer
.red) [8,8 100x100] diff --git a/Tests/LibWeb/Layout/expected/resolve-height-of-containing-block.txt b/Tests/LibWeb/Layout/expected/resolve-height-of-containing-block.txt index a83b608236..8cf10b385f 100644 --- a/Tests/LibWeb/Layout/expected/resolve-height-of-containing-block.txt +++ b/Tests/LibWeb/Layout/expected/resolve-height-of-containing-block.txt @@ -9,9 +9,9 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline BlockContainer <(anonymous)> at (8,16) content-size 1280x0 children: inline TextNode <#text> BlockContainer
at (8,16) content-size 1280x400 children: not-inline + ImageBox at (488,16) content-size 800x400 floating children: not-inline BlockContainer <(anonymous)> at (8,16) content-size 1280x0 children: inline TextNode <#text> - ImageBox at (488,16) content-size 800x400 floating children: not-inline TextNode <#text> BlockContainer

at (8,16) content-size 1280x17.46875 children: inline line 0 width: 37.21875, height: 17.46875, bottom: 17.46875, baseline: 13.53125 @@ -33,8 +33,8 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600] overflow: [0,0 1288x824] PaintableWithLines (BlockContainer

.foo) [8,16 1280x800] PaintableWithLines (BlockContainer(anonymous)) [8,16 1280x0] PaintableWithLines (BlockContainer
) [8,16 1280x400] + ImagePaintable (ImageBox) [488,16 800x400] PaintableWithLines (BlockContainer(anonymous)) [8,16 1280x0] - ImagePaintable (ImageBox) [488,16 800x400] PaintableWithLines (BlockContainer

) [8,16 1280x17.46875] TextPaintable (TextNode<#text>) PaintableWithLines (BlockContainer(anonymous)) [8,49.46875 1280x0] diff --git a/Tests/LibWeb/Layout/expected/set-margin-of-floating-box.txt b/Tests/LibWeb/Layout/expected/set-margin-of-floating-box.txt index 7fb135428b..726373d0d2 100644 --- a/Tests/LibWeb/Layout/expected/set-margin-of-floating-box.txt +++ b/Tests/LibWeb/Layout/expected/set-margin-of-floating-box.txt @@ -3,9 +3,9 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline BlockContainer <(anonymous)> at (0,0) content-size 800x0 children: inline TextNode <#text> BlockContainer at (8,16) content-size 784x17.46875 children: not-inline + ImageBox at (8,16) content-size 200x100 floating children: not-inline BlockContainer <(anonymous)> at (8,16) content-size 784x0 children: inline TextNode <#text> - ImageBox at (8,16) content-size 200x100 floating children: not-inline TextNode <#text> BlockContainer

at (8,16) content-size 784x17.46875 children: inline line 0 width: 37.21875, height: 17.46875, bottom: 17.46875, baseline: 13.53125 @@ -18,9 +18,9 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline ViewportPaintable (Viewport<#document>) [0,0 800x600] PaintableWithLines (BlockContainer) [0,0 800x116] PaintableWithLines (BlockContainer(anonymous)) [0,0 800x0] - PaintableWithLines (BlockContainer) [8,16 784x17.46875] overflow: [8,16 784x33.46875] + PaintableWithLines (BlockContainer) [8,16 784x17.46875] overflow: [8,16 784x100] + ImagePaintable (ImageBox) [8,16 200x100] PaintableWithLines (BlockContainer(anonymous)) [8,16 784x0] - ImagePaintable (ImageBox) [8,16 200x100] PaintableWithLines (BlockContainer

) [8,16 784x17.46875] TextPaintable (TextNode<#text>) PaintableWithLines (BlockContainer(anonymous)) [8,49.46875 784x0] diff --git a/Tests/LibWeb/Text/expected/hit_testing/float-with-inline-sibling-after.txt b/Tests/LibWeb/Text/expected/hit_testing/float-with-inline-sibling-after.txt new file mode 100644 index 0000000000..b489ed6570 --- /dev/null +++ b/Tests/LibWeb/Text/expected/hit_testing/float-with-inline-sibling-after.txt @@ -0,0 +1 @@ + true diff --git a/Tests/LibWeb/Text/input/hit_testing/float-with-inline-sibling-after.html b/Tests/LibWeb/Text/input/hit_testing/float-with-inline-sibling-after.html new file mode 100644 index 0000000000..c8c061c396 --- /dev/null +++ b/Tests/LibWeb/Text/input/hit_testing/float-with-inline-sibling-after.html @@ -0,0 +1,38 @@ +

+
+ + diff --git a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp index 3a68e408a7..97215d4f06 100644 --- a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp +++ b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp @@ -121,9 +121,16 @@ static Layout::Node& insertion_parent_for_block_node(Layout::NodeWithStyle& layo // Parent block has inline-level children (our siblings). // First move these siblings into an anonymous wrapper block. Vector> children; - while (JS::GCPtr child = layout_parent.first_child()) { - layout_parent.remove_child(*child); - children.append(*child); + { + JS::GCPtr next; + for (JS::GCPtr child = layout_parent.first_child(); child; child = next) { + next = child->next_sibling(); + // NOTE: We let out-of-flow children stay in the parent, to preserve tree structure. + if (child->is_floating() || child->is_absolutely_positioned()) + continue; + layout_parent.remove_child(*child); + children.append(*child); + } } layout_parent.append_child(layout_parent.create_anonymous_wrapper()); layout_parent.set_children_are_inline(false); diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp index cc9c06ab0f..739b8313f0 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -805,7 +805,7 @@ Optional PaintableBox::hit_test(CSSPixelPoint position, HitTestTy Optional PaintableWithLines::hit_test(CSSPixelPoint position, HitTestType type) const { - if (!layout_box().children_are_inline()) + if (!layout_box().children_are_inline() || m_line_boxes.is_empty()) return PaintableBox::hit_test(position, type); Optional last_good_candidate;