Sfoglia il codice sorgente

LibWeb: Account for x-axis in static position for inline items

..and delay static position calculation in IFC until trailing
whitespace are removed, because otherwise it's not possible to correctly
calculate x offset.
Aliaksandr Kalenik 10 mesi fa
parent
commit
91b2cd7d31

+ 34 - 0
Tests/LibWeb/Layout/expected/grid/inline-abspos-item.txt

@@ -0,0 +1,34 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+  BlockContainer <html> at (0,0) content-size 800x537 [BFC] children: not-inline
+    BlockContainer <body> at (8,8) content-size 784x521 children: not-inline
+      Box <div.grid> at (18,117) content-size 550x400 positioned [GFC] children: not-inline
+        BlockContainer <(anonymous)> (not painted) [BFC] children: inline
+          TextNode <#text>
+        BlockContainer <div> at (18,117) content-size 200x150 [BFC] children: inline
+          frag 0 from TextNode start: 1, length: 1, rect: [18,117 11.5625x17] baseline: 13.296875
+              "X"
+          frag 1 from TextNode start: 0, length: 2, rect: [18,134 23.125x17] baseline: 13.296875
+              "XX"
+          TextNode <#text>
+          BreakNode <br>
+          TextNode <#text>
+          BlockContainer <div.abspos> at (41.125,134) content-size 23.125x17 positioned [BFC] children: inline
+            frag 0 from TextNode start: 0, length: 2, rect: [41.125,134 23.125x17] baseline: 13.296875
+                "XX"
+            TextNode <#text>
+          TextNode <#text>
+        BlockContainer <(anonymous)> (not painted) [BFC] children: inline
+          TextNode <#text>
+      BlockContainer <(anonymous)> at (8,532) content-size 784x0 children: inline
+        TextNode <#text>
+
+ViewportPaintable (Viewport<#document>) [0,0 800x600]
+  PaintableWithLines (BlockContainer<HTML>) [0,0 800x537]
+    PaintableWithLines (BlockContainer<BODY>) [8,8 784x521] overflow: [8,8 784x524]
+      PaintableBox (Box<DIV>.grid) [12,8 559x521]
+        PaintableWithLines (BlockContainer<DIV>) [18,117 200x150]
+          TextPaintable (TextNode<#text>)
+          TextPaintable (TextNode<#text>)
+          PaintableWithLines (BlockContainer<DIV>.abspos) [41.125,134 23.125x17]
+            TextPaintable (TextNode<#text>)
+      PaintableWithLines (BlockContainer(anonymous)) [8,532 784x0]

+ 25 - 0
Tests/LibWeb/Layout/input/grid/inline-abspos-item.html

@@ -0,0 +1,25 @@
+<!-- Reduced from https://wpt.live/css/css-grid/abspos/positioned-grid-descendants-001.html -->
+<!DOCTYPE html>
+<style>
+  .grid {
+    display: grid;
+    grid: 150px 100px/200px 300px;
+    margin: 1px 2px 3px 4px;
+    padding-top: 100px;
+    border-width: 9px 3px 12px 6px;
+    border-style: solid;
+    width: 550px;
+    height: 400px;
+    position: relative;
+  }
+  .abspos {
+    position: absolute;
+    display: inline;
+  }
+</style>
+<div class="grid">
+  <div style="grid-area: 1/1">
+    X<br />XX
+    <div class="abspos" style="grid-area: auto/auto/1/1; inset: auto">XX</div>
+  </div>
+</div>

+ 1 - 0
Userland/Libraries/LibWeb/Layout/FormattingContext.cpp

@@ -1204,6 +1204,7 @@ StaticPositionRect FormattingContext::calculate_static_position_rect(Box const&
                 }
             }
             if (last_fragment) {
+                x = last_fragment->offset().x() + last_fragment->width();
                 y = last_fragment->offset().y() + last_fragment->height();
             }
         } else {

+ 9 - 2
Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp

@@ -260,6 +260,8 @@ void InlineFormattingContext::generate_line_boxes()
     //       axis, so that we can add it to the first non-whitespace chunk.
     CSSPixels leading_margin_from_collapsible_whitespace = 0;
 
+    Vector<Box const*> absolute_boxes;
+
     for (;;) {
         auto item_opt = iterator.next();
         if (!item_opt.has_value())
@@ -307,8 +309,8 @@ void InlineFormattingContext::generate_line_boxes()
         case InlineLevelIterator::Item::Type::AbsolutelyPositionedElement:
             if (is<Box>(*item.node)) {
                 auto const& box = static_cast<Layout::Box const&>(*item.node);
-                auto& box_state = m_state.get_mutable(box);
-                box_state.set_static_position_rect(calculate_static_position_rect(box));
+                // Calculation of static position for absolute boxes is delayed until trailing whitespaces are removed.
+                absolute_boxes.append(&box);
             }
             break;
 
@@ -410,6 +412,11 @@ void InlineFormattingContext::generate_line_boxes()
             apply_justification_to_fragments(text_justify, line_box, is_last_line);
         }
     }
+
+    for (auto* box : absolute_boxes) {
+        auto& box_state = m_state.get_mutable(*box);
+        box_state.set_static_position_rect(calculate_static_position_rect(*box));
+    }
 }
 
 bool InlineFormattingContext::any_floats_intrude_at_y(CSSPixels y) const