Browse Source

LibWeb: Return used values for grid tracks in getComputedStyle()

That's awkward, but getComputedStyle needs to return used track values
for gridTemplateColumns and gridTemplateRows properties. This change
implements it by saving style values with used values into layout state,
so it could be assigned to paintables during LayoutState::commit() and
later accessed by style_value_for_property().

I haven't seen it used in the wild, but WPT grid tests extensively use
it. For example this change helps to go from 0/10 to 8/10 on this test:
https://wpt.live/css/css-grid/layout-algorithm/grid-fit-content-percentage.html
Aliaksandr Kalenik 9 tháng trước cách đây
mục cha
commit
68fcc37531

+ 2 - 0
Tests/LibWeb/Text/expected/getComputedStyle-grid-template-rows-columns.txt

@@ -0,0 +1,2 @@
+  100px 100px
+50px 50px

+ 21 - 0
Tests/LibWeb/Text/input/getComputedStyle-grid-template-rows-columns.html

@@ -0,0 +1,21 @@
+<script src="include.js"></script>
+<style>
+    .grid-container {
+        width: 200px;
+        display: grid;
+        background-color: lightsalmon;
+    }
+
+    .grid-item {
+        height: 50px;
+        background-color: lightblue;
+    }
+</style>
+<div class="grid-container" style="grid-template-columns: auto auto"><div class="grid-item"></div><div class="grid-item"></div><div class="grid-item"></div><div class="grid-item"></div></div>
+<script>
+    test(() => {
+        const grid = document.querySelector(".grid-container");
+        println(getComputedStyle(grid).gridTemplateColumns);
+        println(getComputedStyle(grid).gridTemplateRows);
+    });
+</script>

+ 10 - 0
Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp

@@ -250,6 +250,16 @@ RefPtr<CSSStyleValue const> ResolvedCSSStyleDeclaration::style_value_for_propert
         return style_value_for_shadow(layout_node.computed_values().box_shadow());
         return style_value_for_shadow(layout_node.computed_values().box_shadow());
     case PropertyID::Color:
     case PropertyID::Color:
         return CSSColorValue::create_from_color(layout_node.computed_values().color());
         return CSSColorValue::create_from_color(layout_node.computed_values().color());
+    // For grid-template-columns and grid-template-rows the resolved value is the used value.
+    // https://www.w3.org/TR/css-grid-2/#resolved-track-list-standalone
+    case PropertyID::GridTemplateColumns: {
+        auto const& paintable_box = verify_cast<Painting::PaintableBox const>(*layout_node.paintable());
+        return paintable_box.used_values_for_grid_template_columns();
+    }
+    case PropertyID::GridTemplateRows: {
+        auto const& paintable_box = verify_cast<Painting::PaintableBox const>(*layout_node.paintable());
+        return paintable_box.used_values_for_grid_template_rows();
+    }
     case PropertyID::OutlineColor:
     case PropertyID::OutlineColor:
         return CSSColorValue::create_from_color(layout_node.computed_values().outline_color());
         return CSSColorValue::create_from_color(layout_node.computed_values().outline_color());
     case PropertyID::TextDecorationColor:
     case PropertyID::TextDecorationColor:

+ 17 - 0
Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp

@@ -1873,6 +1873,23 @@ void GridFormattingContext::run(Box const&, LayoutMode, AvailableSpace const& av
         if (auto independent_formatting_context = layout_inside(grid_item.box, LayoutMode::Normal, available_space_for_children))
         if (auto independent_formatting_context = layout_inside(grid_item.box, LayoutMode::Normal, available_space_for_children))
             independent_formatting_context->parent_context_did_dimension_child_root_box();
             independent_formatting_context->parent_context_did_dimension_child_root_box();
     }
     }
+
+    Vector<Variant<CSS::ExplicitGridTrack, CSS::GridLineNames>> grid_track_columns;
+    grid_track_columns.ensure_capacity(m_grid_columns.size());
+    for (auto const& column : m_grid_columns) {
+        grid_track_columns.append(CSS::ExplicitGridTrack { CSS::GridSize { CSS::LengthPercentage(CSS::Length::make_px(column.base_size)) } });
+    }
+
+    Vector<Variant<CSS::ExplicitGridTrack, CSS::GridLineNames>> grid_track_rows;
+    grid_track_rows.ensure_capacity(m_grid_rows.size());
+    for (auto const& row : m_grid_rows) {
+        grid_track_rows.append(CSS::ExplicitGridTrack { CSS::GridSize { CSS::LengthPercentage(CSS::Length::make_px(row.base_size)) } });
+    }
+
+    // getComputedStyle() needs to return the resolved values of grid-template-columns and grid-template-rows
+    // so they need to be saved in the state, and then assigned to paintables in LayoutState::commit()
+    m_state.get_mutable(grid_container()).set_grid_template_columns(CSS::GridTrackSizeListStyleValue::create(move(grid_track_columns)));
+    m_state.get_mutable(grid_container()).set_grid_template_rows(CSS::GridTrackSizeListStyleValue::create(move(grid_track_rows)));
 }
 }
 
 
 void GridFormattingContext::layout_absolutely_positioned_element(Box const& box, AvailableSpace const& available_space)
 void GridFormattingContext::layout_absolutely_positioned_element(Box const& box, AvailableSpace const& available_space)

+ 5 - 0
Userland/Libraries/LibWeb/Layout/LayoutState.cpp

@@ -278,6 +278,11 @@ void LayoutState::commit(Box& root)
                 auto& svg_geometry_paintable = static_cast<Painting::SVGPathPaintable&>(paintable_box);
                 auto& svg_geometry_paintable = static_cast<Painting::SVGPathPaintable&>(paintable_box);
                 svg_geometry_paintable.set_computed_path(move(*used_values.computed_svg_path()));
                 svg_geometry_paintable.set_computed_path(move(*used_values.computed_svg_path()));
             }
             }
+
+            if (node.display().is_grid_inside()) {
+                paintable_box.set_used_values_for_grid_template_columns(used_values.grid_template_columns());
+                paintable_box.set_used_values_for_grid_template_rows(used_values.grid_template_rows());
+            }
         }
         }
     }
     }
 
 

+ 9 - 0
Userland/Libraries/LibWeb/Layout/LayoutState.h

@@ -139,6 +139,12 @@ struct LayoutState {
         void set_computed_svg_transforms(Painting::SVGGraphicsPaintable::ComputedTransforms const& computed_transforms) { m_computed_svg_transforms = computed_transforms; }
         void set_computed_svg_transforms(Painting::SVGGraphicsPaintable::ComputedTransforms const& computed_transforms) { m_computed_svg_transforms = computed_transforms; }
         auto const& computed_svg_transforms() const { return m_computed_svg_transforms; }
         auto const& computed_svg_transforms() const { return m_computed_svg_transforms; }
 
 
+        void set_grid_template_columns(RefPtr<CSS::GridTrackSizeListStyleValue> used_values_for_grid_template_columns) { m_grid_template_columns = move(used_values_for_grid_template_columns); }
+        auto const& grid_template_columns() const { return m_grid_template_columns; }
+
+        void set_grid_template_rows(RefPtr<CSS::GridTrackSizeListStyleValue> used_values_for_grid_template_rows) { m_grid_template_rows = move(used_values_for_grid_template_rows); }
+        auto const& grid_template_rows() const { return m_grid_template_rows; }
+
     private:
     private:
         AvailableSize available_width_inside() const;
         AvailableSize available_width_inside() const;
         AvailableSize available_height_inside() const;
         AvailableSize available_height_inside() const;
@@ -166,6 +172,9 @@ struct LayoutState {
 
 
         Optional<Gfx::Path> m_computed_svg_path;
         Optional<Gfx::Path> m_computed_svg_path;
         Optional<Painting::SVGGraphicsPaintable::ComputedTransforms> m_computed_svg_transforms;
         Optional<Painting::SVGGraphicsPaintable::ComputedTransforms> m_computed_svg_transforms;
+
+        RefPtr<CSS::GridTrackSizeListStyleValue> m_grid_template_columns;
+        RefPtr<CSS::GridTrackSizeListStyleValue> m_grid_template_rows;
     };
     };
 
 
     // Commits the used values produced by layout and builds a paintable tree.
     // Commits the used values produced by layout and builds a paintable tree.

+ 10 - 0
Userland/Libraries/LibWeb/Painting/PaintableBox.h

@@ -6,6 +6,7 @@
 
 
 #pragma once
 #pragma once
 
 
+#include <LibWeb/CSS/StyleValues/GridTrackSizeListStyleValue.h>
 #include <LibWeb/Painting/BackgroundPainting.h>
 #include <LibWeb/Painting/BackgroundPainting.h>
 #include <LibWeb/Painting/BorderPainting.h>
 #include <LibWeb/Painting/BorderPainting.h>
 #include <LibWeb/Painting/BorderRadiusCornerClipper.h>
 #include <LibWeb/Painting/BorderRadiusCornerClipper.h>
@@ -227,6 +228,12 @@ public:
 
 
     [[nodiscard]] bool is_scrollable() const;
     [[nodiscard]] bool is_scrollable() const;
 
 
+    void set_used_values_for_grid_template_columns(RefPtr<CSS::GridTrackSizeListStyleValue> style_value) { m_used_values_for_grid_template_columns = move(style_value); }
+    RefPtr<CSS::GridTrackSizeListStyleValue> const& used_values_for_grid_template_columns() const { return m_used_values_for_grid_template_columns; }
+
+    void set_used_values_for_grid_template_rows(RefPtr<CSS::GridTrackSizeListStyleValue> style_value) { m_used_values_for_grid_template_rows = move(style_value); }
+    RefPtr<CSS::GridTrackSizeListStyleValue> const& used_values_for_grid_template_rows() const { return m_used_values_for_grid_template_rows; }
+
 protected:
 protected:
     explicit PaintableBox(Layout::Box const&);
     explicit PaintableBox(Layout::Box const&);
 
 
@@ -287,6 +294,9 @@ private:
     ResolvedBackground m_resolved_background;
     ResolvedBackground m_resolved_background;
 
 
     OwnPtr<StickyInsets> m_sticky_insets;
     OwnPtr<StickyInsets> m_sticky_insets;
+
+    RefPtr<CSS::GridTrackSizeListStyleValue> m_used_values_for_grid_template_columns;
+    RefPtr<CSS::GridTrackSizeListStyleValue> m_used_values_for_grid_template_rows;
 };
 };
 
 
 class PaintableWithLines : public PaintableBox {
 class PaintableWithLines : public PaintableBox {