From 80a78c4debaffeee07bcbd0b512ed0e780b9a4dc Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 14 Sep 2023 14:30:39 +0200 Subject: [PATCH] LibWeb: Don't generate ::before/::after for BR elements We shouldn't be putting generated pseudo elements inside elements that can't have children in the first place. This patch fixes two issues: - We stop generating pseudo elements for layout nodes that can't have children anyway. - We mark Layout::BreakNode as not being able to have children. --- .../br-should-not-generate-pseudo-before.txt | 29 +++++++++++++++++++ .../br-should-not-generate-pseudo-before.html | 3 ++ Userland/Libraries/LibWeb/Layout/BreakNode.h | 1 + .../Libraries/LibWeb/Layout/TreeBuilder.cpp | 2 +- 4 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 Tests/LibWeb/Layout/expected/br-should-not-generate-pseudo-before.txt create mode 100644 Tests/LibWeb/Layout/input/br-should-not-generate-pseudo-before.html diff --git a/Tests/LibWeb/Layout/expected/br-should-not-generate-pseudo-before.txt b/Tests/LibWeb/Layout/expected/br-should-not-generate-pseudo-before.txt new file mode 100644 index 0000000000..13e6dfc1d2 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/br-should-not-generate-pseudo-before.txt @@ -0,0 +1,29 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x84.875 [BFC] children: not-inline + BlockContainer at (8,16) content-size 784x68.875 children: not-inline + BlockContainer

at (8,16) content-size 784x17.46875 children: inline + line 0 width: 310.625, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 0, length: 1, rect: [8,16 10.625x17.46875] + "+" + frag 1 from TextNode start: 0, length: 36, rect: [19,16 300x17.46875] + "P should generate a ::before pseudo." + InlineNode <(anonymous)> + TextNode <#text> + TextNode <#text> + BlockContainer <(anonymous)> at (8,49.46875) content-size 784x35.40625 children: inline + line 0 width: 0, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + line 1 width: 120.578125, height: 17.9375, bottom: 35.40625, baseline: 13.53125 + frag 0 from TextNode start: 0, length: 14, rect: [8,66.46875 120.578125x17.46875] + "BR should not!" + BreakNode
+ TextNode <#text> + +ViewportPaintable (Viewport<#document>) [0,0 800x600] + PaintableWithLines (BlockContainer) [0,0 800x84.875] + PaintableWithLines (BlockContainer) [8,16 784x68.875] + PaintableWithLines (BlockContainer

) [8,16 784x17.46875] + InlinePaintable (InlineNode(anonymous)) + TextPaintable (TextNode<#text>) + TextPaintable (TextNode<#text>) + PaintableWithLines (BlockContainer(anonymous)) [8,49.46875 784x35.40625] + TextPaintable (TextNode<#text>) diff --git a/Tests/LibWeb/Layout/input/br-should-not-generate-pseudo-before.html b/Tests/LibWeb/Layout/input/br-should-not-generate-pseudo-before.html new file mode 100644 index 0000000000..eec9c69413 --- /dev/null +++ b/Tests/LibWeb/Layout/input/br-should-not-generate-pseudo-before.html @@ -0,0 +1,3 @@ +

P should generate a ::before pseudo.


BR should not! diff --git a/Userland/Libraries/LibWeb/Layout/BreakNode.h b/Userland/Libraries/LibWeb/Layout/BreakNode.h index f3c814b3ae..6e4a1063ae 100644 --- a/Userland/Libraries/LibWeb/Layout/BreakNode.h +++ b/Userland/Libraries/LibWeb/Layout/BreakNode.h @@ -22,6 +22,7 @@ public: private: virtual bool is_break_node() const final { return true; } + virtual bool can_have_children() const override { return false; } }; template<> diff --git a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp index 56ce152697..1ff65354c2 100644 --- a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp +++ b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp @@ -427,7 +427,7 @@ ErrorOr TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder:: } // Add nodes for the ::before and ::after pseudo-elements. - if (is(dom_node)) { + if (is(dom_node) && layout_node->can_have_children()) { auto& element = static_cast(dom_node); push_parent(verify_cast(*layout_node)); TRY(create_pseudo_element_if_needed(element, CSS::Selector::PseudoElement::Before, AppendOrPrepend::Prepend));