Переглянути джерело

LibWeb: Add boxes for before/after pseudos post button layout tweak

When a button should use flex for alignment and also has ::before
and/or ::after, we previously did the following:
1. Prepended/appended the button's children with boxes for
   pseudo-elements.
2. Replaced the button's direct children with a flex container that
   contains its children.
As a result, the generated boxes for ::before/::after ended up as
children of the generated flex item, instead of being direct children
of the button layout box as they were supposed to be.

This change reverses these steps, ensuring that boxes for
pseudo-elements are generated only after modifications inside the
button layout are completed.
Aliaksandr Kalenik 1 рік тому
батько
коміт
40dea272d2

+ 6 - 6
Tests/LibWeb/Layout/expected/block-and-inline/button-with-abspos-pseudo-element.txt

@@ -5,15 +5,15 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
         frag 0 from BlockContainer start: 0, length: 0, rect: [29,29 0x0]
       BlockContainer <button> at (29,29) content-size 0x0 positioned inline-block [BFC] children: not-inline
         BlockContainer <(anonymous)> at (29,29) content-size 0x0 flex-container(column) [FFC] children: not-inline
-          BlockContainer <(anonymous)> at (29,29) content-size 0x0 flex-item [BFC] children: not-inline
-            BlockContainer <(anonymous)> at (9,9) content-size 40x40 positioned [BFC] children: inline
-              TextNode <#text>
+          BlockContainer <(anonymous)> at (29,29) content-size 0x0 [BFC] children: not-inline
+        BlockContainer <(anonymous)> at (9,9) content-size 40x40 positioned [BFC] children: inline
+          TextNode <#text>
       TextNode <#text>
 
 ViewportPaintable (Viewport<#document>) [0,0 800x600]
   PaintableWithLines (BlockContainer<HTML>) [0,0 800x58]
     PaintableWithLines (BlockContainer<BODY>) [8,8 784x42]
       PaintableWithLines (BlockContainer<BUTTON>) [8,8 42x42]
-        PaintableWithLines (BlockContainer(anonymous)) [29,29 0x0] overflow: [9,9 40x40]
-          PaintableWithLines (BlockContainer(anonymous)) [29,29 0x0] overflow: [9,9 40x40]
-            PaintableWithLines (BlockContainer(anonymous)) [9,9 40x40]
+        PaintableWithLines (BlockContainer(anonymous)) [29,29 0x0]
+          PaintableWithLines (BlockContainer(anonymous)) [29,29 0x0]
+        PaintableWithLines (BlockContainer(anonymous)) [9,9 40x40]

+ 23 - 0
Tests/LibWeb/Layout/expected/block-and-inline/button-with-after-pseudo.txt

@@ -0,0 +1,23 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+  BlockContainer <html> at (0,0) content-size 800x74.59375 [BFC] children: not-inline
+    BlockContainer <body> at (8,8) content-size 784x58.59375 children: inline
+      line 0 width: 424.640625, height: 58.59375, bottom: 58.59375, baseline: 42.28125
+        frag 0 from BlockContainer start: 0, length: 0, rect: [13,10 414.640625x54.59375]
+      BlockContainer <button.button_button___eDCW> at (13,10) content-size 414.640625x54.59375 positioned inline-block [BFC] children: not-inline
+        BlockContainer <(anonymous)> at (13,10) content-size 414.640625x54.59375 flex-container(column) [FFC] children: not-inline
+          BlockContainer <(anonymous)> at (13,10) content-size 414.640625x54.59375 flex-item [BFC] children: inline
+            line 0 width: 414.640625, height: 54.59375, bottom: 54.59375, baseline: 42.28125
+              frag 0 from TextNode start: 0, length: 14, rect: [13,10 414.640625x54.59375]
+                "See more games"
+            TextNode <#text>
+        BlockContainer <(anonymous)> at (9,9) content-size 422.640625x56.59375 positioned [BFC] children: inline
+          TextNode <#text>
+
+ViewportPaintable (Viewport<#document>) [0,0 800x600]
+  PaintableWithLines (BlockContainer<HTML>) [0,0 800x74.59375]
+    PaintableWithLines (BlockContainer<BODY>) [8,8 784x58.59375]
+      PaintableWithLines (BlockContainer<BUTTON>.button_button___eDCW) [8,8 424.640625x58.59375]
+        PaintableWithLines (BlockContainer(anonymous)) [13,10 414.640625x54.59375]
+          PaintableWithLines (BlockContainer(anonymous)) [13,10 414.640625x54.59375]
+            TextPaintable (TextNode<#text>)
+        PaintableWithLines (BlockContainer(anonymous)) [9,9 422.640625x56.59375]

+ 23 - 0
Tests/LibWeb/Layout/expected/block-and-inline/button-with-before-pseudo.txt

@@ -0,0 +1,23 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+  BlockContainer <html> at (0,0) content-size 800x74.59375 [BFC] children: not-inline
+    BlockContainer <body> at (8,8) content-size 784x58.59375 children: inline
+      line 0 width: 424.640625, height: 58.59375, bottom: 58.59375, baseline: 42.28125
+        frag 0 from BlockContainer start: 0, length: 0, rect: [13,10 414.640625x54.59375]
+      BlockContainer <button.button_button___eDCW> at (13,10) content-size 414.640625x54.59375 positioned inline-block [BFC] children: not-inline
+        BlockContainer <(anonymous)> at (9,9) content-size 422.640625x56.59375 positioned [BFC] children: inline
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (13,10) content-size 414.640625x54.59375 flex-container(column) [FFC] children: not-inline
+          BlockContainer <(anonymous)> at (13,10) content-size 414.640625x54.59375 flex-item [BFC] children: inline
+            line 0 width: 414.640625, height: 54.59375, bottom: 54.59375, baseline: 42.28125
+              frag 0 from TextNode start: 0, length: 14, rect: [13,10 414.640625x54.59375]
+                "See more games"
+            TextNode <#text>
+
+ViewportPaintable (Viewport<#document>) [0,0 800x600]
+  PaintableWithLines (BlockContainer<HTML>) [0,0 800x74.59375]
+    PaintableWithLines (BlockContainer<BODY>) [8,8 784x58.59375]
+      PaintableWithLines (BlockContainer<BUTTON>.button_button___eDCW) [8,8 424.640625x58.59375]
+        PaintableWithLines (BlockContainer(anonymous)) [9,9 422.640625x56.59375]
+        PaintableWithLines (BlockContainer(anonymous)) [13,10 414.640625x54.59375]
+          PaintableWithLines (BlockContainer(anonymous)) [13,10 414.640625x54.59375]
+            TextPaintable (TextNode<#text>)

+ 20 - 0
Tests/LibWeb/Layout/input/block-and-inline/button-with-after-pseudo.html

@@ -0,0 +1,20 @@
+<!DOCTYPE html><style type="text/css">
+    button {
+      background-color: initial;
+    }
+    .button_button___eDCW {
+      font-size: 50px;
+      position: relative;
+      color: blueviolet;
+    }
+    .button_button___eDCW:after {
+      content: "";
+      position: absolute;
+      z-index: -1;
+      left: 0;
+      top: 0;
+      background-color: #d1ccb6;
+      width: 100%;
+      height: 100%;
+    }
+  </style><button class="button_button___eDCW">See more games</button>

+ 18 - 0
Tests/LibWeb/Layout/input/block-and-inline/button-with-before-pseudo.html

@@ -0,0 +1,18 @@
+<!DOCTYPE html><style type="text/css">
+.button_button___eDCW {
+    background-color: initial;
+    font-size: 50px;
+    position: relative;
+    color: blueviolet;
+}
+.button_button___eDCW:before {
+    content: "";
+    position: absolute;
+    z-index: -1;
+    left: 0;
+    top: 0;
+    background-color: #d1ccb6;
+    width: 100%;
+    height: 100%;
+}
+</style><button class="button_button___eDCW">See more games</button>

+ 9 - 9
Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp

@@ -332,15 +332,6 @@ ErrorOr<void> TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder::
         pop_parent();
     }
 
-    // Add nodes for the ::before and ::after pseudo-elements.
-    if (is<DOM::Element>(dom_node)) {
-        auto& element = static_cast<DOM::Element&>(dom_node);
-        push_parent(verify_cast<NodeWithStyle>(*layout_node));
-        TRY(create_pseudo_element_if_needed(element, CSS::Selector::PseudoElement::Before, AppendOrPrepend::Prepend));
-        TRY(create_pseudo_element_if_needed(element, CSS::Selector::PseudoElement::After, AppendOrPrepend::Append));
-        pop_parent();
-    }
-
     if (is<ListItemBox>(*layout_node)) {
         auto& element = static_cast<DOM::Element&>(dom_node);
         int child_index = layout_node->parent()->index_of_child<ListItemBox>(*layout_node).value();
@@ -414,6 +405,15 @@ ErrorOr<void> TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder::
         parent.set_children_are_inline(false);
     }
 
+    // Add nodes for the ::before and ::after pseudo-elements.
+    if (is<DOM::Element>(dom_node)) {
+        auto& element = static_cast<DOM::Element&>(dom_node);
+        push_parent(verify_cast<NodeWithStyle>(*layout_node));
+        TRY(create_pseudo_element_if_needed(element, CSS::Selector::PseudoElement::Before, AppendOrPrepend::Prepend));
+        TRY(create_pseudo_element_if_needed(element, CSS::Selector::PseudoElement::After, AppendOrPrepend::Append));
+        pop_parent();
+    }
+
     return {};
 }