Преглед изворни кода

LibWeb: Parse calc() function in grid sizes

Adds missing part of grid size parsing function to handle calc().
Aliaksandr Kalenik пре 2 година
родитељ
комит
c2f6ba8f5f

+ 11 - 0
Tests/LibWeb/Layout/expected/grid/calc-track-size.txt

@@ -0,0 +1,11 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+  BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
+    BlockContainer <body> at (8,8) content-size 784x17.46875 children: not-inline
+      Box <div.grid-container> at (8,8) content-size 784x17.46875 [GFC] children: not-inline
+        BlockContainer <div.grid-item> at (8,8) content-size 200x17.46875 [BFC] children: inline
+          line 0 width: 31.265625, height: 17.46875, bottom: 17.46875, baseline: 13.53125
+            frag 0 from TextNode start: 0, length: 3, rect: [8,8 31.265625x17.46875]
+              "Uno"
+          TextNode <#text>
+      BlockContainer <(anonymous)> at (8,25.46875) content-size 784x0 children: inline
+        TextNode <#text>

+ 12 - 0
Tests/LibWeb/Layout/input/grid/calc-track-size.html

@@ -0,0 +1,12 @@
+<style>
+.grid-container {
+    display: grid;
+    grid-template-columns: calc(200px);
+    grid-template-rows: auto;
+}
+
+.grid-item {
+    background-color: lightskyblue;
+}
+</style>
+<div class="grid-container"><div class="grid-item">Uno</div></div>

+ 3 - 0
Userland/Libraries/LibWeb/CSS/GridTrackSize.cpp

@@ -48,6 +48,9 @@ Size GridSize::css_size() const
         return CSS::Size::make_auto();
         return CSS::Size::make_auto();
     if (m_length_percentage.is_length())
     if (m_length_percentage.is_length())
         return CSS::Size::make_length(m_length_percentage.length());
         return CSS::Size::make_length(m_length_percentage.length());
+    if (m_length_percentage.is_calculated()) {
+        return CSS::Size::make_calculated(m_length_percentage.calculated());
+    }
     return CSS::Size::make_percentage(m_length_percentage.percentage());
     return CSS::Size::make_percentage(m_length_percentage.percentage());
 }
 }
 
 

+ 16 - 2
Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp

@@ -6238,9 +6238,18 @@ ErrorOr<RefPtr<StyleValue>> Parser::parse_as_css_value(PropertyID property_id)
 
 
 Optional<CSS::GridSize> Parser::parse_grid_size(ComponentValue const& component_value)
 Optional<CSS::GridSize> Parser::parse_grid_size(ComponentValue const& component_value)
 {
 {
-    // FIXME: Parse calc here if necessary
-    if (component_value.is_function())
+    if (component_value.is_function()) {
+        auto const& function = component_value.function();
+        if (function.name().equals_ignoring_ascii_case("calc"sv)) {
+            auto calculated_style_value = parse_calculated_value(function.values());
+            if (calculated_style_value.is_error()) {
+                // FIXME: Propagate error
+                return {};
+            }
+            return GridSize(LengthPercentage { *calculated_style_value.release_value() });
+        }
         return {};
         return {};
+    }
     auto token = component_value.token();
     auto token = component_value.token();
     if (token.is(Token::Type::Dimension) && token.dimension_unit().equals_ignoring_ascii_case("fr"sv)) {
     if (token.is(Token::Type::Dimension) && token.dimension_unit().equals_ignoring_ascii_case("fr"sv)) {
         float numeric_value = token.dimension_value();
         float numeric_value = token.dimension_value();
@@ -6417,6 +6426,11 @@ Optional<CSS::ExplicitGridTrack> Parser::parse_track_sizing_function(ComponentVa
                 return CSS::ExplicitGridTrack(maybe_min_max_value.value());
                 return CSS::ExplicitGridTrack(maybe_min_max_value.value());
             else
             else
                 return {};
                 return {};
+        } else if (function_token.name().equals_ignoring_ascii_case("calc"sv)) {
+            auto grid_size = parse_grid_size(token);
+            if (!grid_size.has_value())
+                return {};
+            return CSS::ExplicitGridTrack(grid_size.value());
         }
         }
         return {};
         return {};
     } else if (token.is(Token::Type::Ident) && token.token().ident().equals_ignoring_ascii_case("auto"sv)) {
     } else if (token.is(Token::Type::Ident) && token.token().ident().equals_ignoring_ascii_case("auto"sv)) {