Przeglądaj źródła

LibWeb: Stop inserting inline nodes into a generated wrapper box

493dd5d93cce6ec2afd9c49bf0e67d78247a1191 caused the `::before`
pseudo-element node to be inserted before the element's content, which
caused issues with how we determine where to insert inline nodes into
the layout tree. At the time, I noticed the issue with contents of flex
containers, and prevented them from merging into a `::before` box.

However, a similar situation happens when we're not in a flex container,
but the pseudo-element has `display: block`. This commit fixes that
situation by using the same logic in both places, so a similar mistake
can't be made again.

This fixes the tab text being invisible on GitHub project pages. :^)
Sam Atkins 1 rok temu
rodzic
commit
1132c858e9

+ 21 - 0
Tests/LibWeb/Layout/expected/block-and-inline/inline-node-not-inserted-into-generated-box.txt

@@ -0,0 +1,21 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+  BlockContainer <html> at (0,0) content-size 800x50.9375 [BFC] children: not-inline
+    BlockContainer <body> at (8,8) content-size 784x34.9375 children: not-inline
+      BlockContainer <(anonymous)> at (8,8) content-size 784x17.46875 children: inline
+        line 0 width: 27.15625, height: 17.46875, bottom: 17.46875, baseline: 13.53125
+          frag 0 from TextNode start: 0, length: 3, rect: [8,8 27.15625x17.46875]
+            "foo"
+        TextNode <#text>
+      BlockContainer <(anonymous)> at (8,25.46875) 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: 0, length: 3, rect: [8,25.46875 27.640625x17.46875]
+            "bar"
+        TextNode <#text>
+
+ViewportPaintable (Viewport<#document>) [0,0 800x600]
+  PaintableWithLines (BlockContainer<HTML>) [0,0 800x50.9375]
+    PaintableWithLines (BlockContainer<BODY>) [8,8 784x34.9375]
+      PaintableWithLines (BlockContainer(anonymous)) [8,8 784x17.46875]
+        TextPaintable (TextNode<#text>)
+      PaintableWithLines (BlockContainer(anonymous)) [8,25.46875 784x17.46875]
+        TextPaintable (TextNode<#text>)

+ 6 - 0
Tests/LibWeb/Layout/input/block-and-inline/inline-node-not-inserted-into-generated-box.html

@@ -0,0 +1,6 @@
+<!DOCTYPE html><style>
+    body::before {
+        content: "foo";
+        display: block;
+    }
+</style><body>bar

+ 13 - 10
Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp

@@ -66,24 +66,27 @@ static bool has_in_flow_block_children(Layout::Node const& layout_node)
 
 static Layout::Node& insertion_parent_for_inline_node(Layout::NodeWithStyle& layout_parent)
 {
+    auto last_child_creating_anonymous_wrapper_if_needed = [](auto& layout_parent) -> Layout::Node& {
+        if (!layout_parent.last_child()
+            || !layout_parent.last_child()->is_anonymous()
+            || !layout_parent.last_child()->children_are_inline()
+            || layout_parent.last_child()->is_generated()) {
+            layout_parent.append_child(layout_parent.create_anonymous_wrapper());
+        }
+        return *layout_parent.last_child();
+    };
+
     if (layout_parent.display().is_inline_outside() && layout_parent.display().is_flow_inside())
         return layout_parent;
 
-    if (layout_parent.display().is_flex_inside() || layout_parent.display().is_grid_inside()) {
-        if (layout_parent.last_child() && layout_parent.last_child()->is_anonymous() && layout_parent.last_child()->children_are_inline() && !layout_parent.last_child()->is_generated())
-            return *layout_parent.last_child();
-        layout_parent.append_child(layout_parent.create_anonymous_wrapper());
-        return *layout_parent.last_child();
-    }
+    if (layout_parent.display().is_flex_inside() || layout_parent.display().is_grid_inside())
+        return last_child_creating_anonymous_wrapper_if_needed(layout_parent);
 
     if (!has_in_flow_block_children(layout_parent) || layout_parent.children_are_inline())
         return layout_parent;
 
     // Parent has block-level children, insert into an anonymous wrapper block (and create it first if needed)
-    if (!layout_parent.last_child()->is_anonymous() || !layout_parent.last_child()->children_are_inline()) {
-        layout_parent.append_child(layout_parent.create_anonymous_wrapper());
-    }
-    return *layout_parent.last_child();
+    return last_child_creating_anonymous_wrapper_if_needed(layout_parent);
 }
 
 static Layout::Node& insertion_parent_for_block_node(Layout::NodeWithStyle& layout_parent, Layout::Node& layout_node)