Prechádzať zdrojové kódy

LibWeb: Set min-width for inline child boxes after inside layout

min-width for boxes with inline children can only be applied after
inside layout is done and width of box content is known.
Aliaksandr Kalenik 1 rok pred
rodič
commit
d32bf4cd41

+ 9 - 0
Tests/LibWeb/Layout/expected/block-and-inline/min-width-for-box-with-inline-children.txt

@@ -0,0 +1,9 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+  BlockContainer <html> at (1,1) content-size 798x76.578125 [BFC] children: not-inline
+    BlockContainer <body> at (10,10) content-size 604x58.578125 children: not-inline
+      BlockContainer <div.outer> at (11,11) content-size 602x56.578125 children: not-inline
+        BlockContainer <div.inner> at (12,12) content-size 600x54.578125 children: inline
+          line 0 width: 426.875, height: 54.578125, bottom: 54.578125, baseline: 42.265625
+            frag 0 from TextNode start: 0, length: 18, rect: [12,12 426.875x54.578125]
+              "well hello friends"
+          TextNode <#text>

+ 12 - 0
Tests/LibWeb/Layout/input/block-and-inline/min-width-for-box-with-inline-children.html

@@ -0,0 +1,12 @@
+<!doctype html><style>
+    * {
+        border: 1px solid black !important;
+    }
+    body {
+        width: max-content;
+    }
+    .inner {
+        min-width: 600px;
+        font-size: 50px;
+    }
+</style><body><div class="outer"><div class="inner">well hello friends

+ 21 - 2
Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp

@@ -510,14 +510,33 @@ void BlockFormattingContext::layout_inline_children(BlockContainer const& block_
         available_space);
 
     if (!block_container_state.has_definite_width()) {
-        // NOTE: max-width for boxes with inline children can only be applied after inside layout is done
-        //       and width of box content is known
+        // NOTE: min-width or max-width for boxes with inline children can only be applied after inside layout
+        //       is done and width of box content is known
         auto used_width_px = context.automatic_content_width();
         if (!should_treat_max_width_as_none(block_container, available_space.width)) {
             auto max_width_px = calculate_inner_width(block_container, available_space.width, block_container.computed_values().max_width()).to_px(block_container);
             if (used_width_px > max_width_px)
                 used_width_px = max_width_px;
         }
+
+        auto should_treat_min_width_as_auto = [&] {
+            auto const& available_width = available_space.width;
+            auto const& min_width = block_container.computed_values().min_width();
+            if (min_width.is_auto())
+                return true;
+            if (min_width.is_fit_content() && available_width.is_intrinsic_sizing_constraint())
+                return true;
+            if (min_width.is_max_content() && available_width.is_max_content())
+                return true;
+            if (min_width.is_min_content() && available_width.is_min_content())
+                return true;
+            return false;
+        }();
+        if (!should_treat_min_width_as_auto) {
+            auto min_width_px = calculate_inner_width(block_container, available_space.width, block_container.computed_values().min_width()).to_px(block_container);
+            if (used_width_px < min_width_px)
+                used_width_px = min_width_px;
+        }
         block_container_state.set_content_width(used_width_px);
     }
     if (!block_container_state.has_definite_height())