diff --git a/Userland/Libraries/LibWeb/CSS/ComputedValues.h b/Userland/Libraries/LibWeb/CSS/ComputedValues.h index a7456e241f..65e43bf8fa 100644 --- a/Userland/Libraries/LibWeb/CSS/ComputedValues.h +++ b/Userland/Libraries/LibWeb/CSS/ComputedValues.h @@ -64,8 +64,8 @@ public: static CSS::Size height() { return CSS::Size::make_auto(); } static CSS::Size min_height() { return CSS::Size::make_auto(); } static CSS::Size max_height() { return CSS::Size::make_none(); } - static Vector grid_template_columns() { return Vector {}; } - static Vector grid_template_rows() { return Vector {}; } + static CSS::ExplicitTrackSizing grid_template_columns() { return CSS::ExplicitTrackSizing::make_auto(); } + static CSS::ExplicitTrackSizing grid_template_rows() { return CSS::ExplicitTrackSizing::make_auto(); } static CSS::GridTrackPlacement grid_column_end() { return CSS::GridTrackPlacement::make_auto(); } static CSS::GridTrackPlacement grid_column_start() { return CSS::GridTrackPlacement::make_auto(); } static CSS::GridTrackPlacement grid_row_end() { return CSS::GridTrackPlacement::make_auto(); } @@ -182,8 +182,8 @@ public: CSS::Size const& min_height() const { return m_noninherited.min_height; } CSS::Size const& max_height() const { return m_noninherited.max_height; } Variant const& vertical_align() const { return m_noninherited.vertical_align; } - Vector const& grid_template_columns() const { return m_noninherited.grid_template_columns; } - Vector const& grid_template_rows() const { return m_noninherited.grid_template_rows; } + CSS::ExplicitTrackSizing const& grid_template_columns() const { return m_noninherited.grid_template_columns; } + CSS::ExplicitTrackSizing const& grid_template_rows() const { return m_noninherited.grid_template_rows; } CSS::GridTrackPlacement const& grid_column_end() const { return m_noninherited.grid_column_end; } CSS::GridTrackPlacement const& grid_column_start() const { return m_noninherited.grid_column_start; } CSS::GridTrackPlacement const& grid_row_end() const { return m_noninherited.grid_row_end; } @@ -304,8 +304,8 @@ protected: CSS::BoxSizing box_sizing { InitialValues::box_sizing() }; CSS::ContentData content; Variant vertical_align { InitialValues::vertical_align() }; - Vector grid_template_columns; - Vector grid_template_rows; + CSS::ExplicitTrackSizing grid_template_columns; + CSS::ExplicitTrackSizing grid_template_rows; CSS::GridTrackPlacement grid_column_end { InitialValues::grid_column_end() }; CSS::GridTrackPlacement grid_column_start { InitialValues::grid_column_start() }; CSS::GridTrackPlacement grid_row_end { InitialValues::grid_row_end() }; @@ -382,8 +382,8 @@ public: void set_box_sizing(CSS::BoxSizing value) { m_noninherited.box_sizing = value; } void set_vertical_align(Variant value) { m_noninherited.vertical_align = move(value); } void set_visibility(CSS::Visibility value) { m_inherited.visibility = value; } - void set_grid_template_columns(Vector value) { m_noninherited.grid_template_columns = move(value); } - void set_grid_template_rows(Vector value) { m_noninherited.grid_template_rows = move(value); } + void set_grid_template_columns(CSS::ExplicitTrackSizing value) { m_noninherited.grid_template_columns = move(value); } + void set_grid_template_rows(CSS::ExplicitTrackSizing value) { m_noninherited.grid_template_rows = move(value); } void set_grid_column_end(CSS::GridTrackPlacement value) { m_noninherited.grid_column_end = value; } void set_grid_column_start(CSS::GridTrackPlacement value) { m_noninherited.grid_column_start = value; } void set_grid_row_end(CSS::GridTrackPlacement value) { m_noninherited.grid_row_end = value; } diff --git a/Userland/Libraries/LibWeb/CSS/GridTrackSize.cpp b/Userland/Libraries/LibWeb/CSS/GridTrackSize.cpp index e461001516..1b389305fc 100644 --- a/Userland/Libraries/LibWeb/CSS/GridTrackSize.cpp +++ b/Userland/Libraries/LibWeb/CSS/GridTrackSize.cpp @@ -57,4 +57,51 @@ Length GridTrackSize::length() const return m_length; } +MetaGridTrackSize::MetaGridTrackSize(GridTrackSize grid_track_size) + : m_min_grid_track_size(grid_track_size) + , m_max_grid_track_size(grid_track_size) +{ +} + +String MetaGridTrackSize::to_string() const +{ + return String::formatted("{}", m_min_grid_track_size.to_string()); +} + +ExplicitTrackSizing::ExplicitTrackSizing() +{ +} + +ExplicitTrackSizing::ExplicitTrackSizing(Vector meta_grid_track_sizes) + : m_meta_grid_track_sizes(meta_grid_track_sizes) +{ +} + +ExplicitTrackSizing::ExplicitTrackSizing(Vector meta_grid_track_sizes, int repeat_count) + : m_meta_grid_track_sizes(meta_grid_track_sizes) + , m_is_repeat(true) + , m_repeat_count(repeat_count) +{ +} + +String ExplicitTrackSizing::to_string() const +{ + StringBuilder builder; + if (m_is_repeat) { + builder.append("repeat("sv); + builder.append(m_repeat_count); + builder.append(", "sv); + } + for (int _ = 0; _ < m_repeat_count; ++_) { + for (size_t y = 0; y < m_meta_grid_track_sizes.size(); ++y) { + builder.append(m_meta_grid_track_sizes[y].to_string()); + if (y != m_meta_grid_track_sizes.size() - 1) + builder.append(" "sv); + } + } + if (m_is_repeat) + builder.append(")"sv); + return builder.to_string(); +} + } diff --git a/Userland/Libraries/LibWeb/CSS/GridTrackSize.h b/Userland/Libraries/LibWeb/CSS/GridTrackSize.h index 1673f18a5d..4202837469 100644 --- a/Userland/Libraries/LibWeb/CSS/GridTrackSize.h +++ b/Userland/Libraries/LibWeb/CSS/GridTrackSize.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include @@ -64,4 +65,48 @@ private: float m_flexible_length { 0 }; }; +class MetaGridTrackSize { +public: + MetaGridTrackSize(CSS::GridTrackSize); + + GridTrackSize grid_track_size() const& { return m_min_grid_track_size; } + GridTrackSize min_grid_track_size() const& { return m_min_grid_track_size; } + GridTrackSize max_grid_track_size() const& { return m_max_grid_track_size; } + + String to_string() const; + bool operator==(MetaGridTrackSize const& other) const + { + return m_min_grid_track_size == other.min_grid_track_size() + && m_max_grid_track_size == other.max_grid_track_size(); + } + +private: + GridTrackSize m_min_grid_track_size; + GridTrackSize m_max_grid_track_size; +}; + +class ExplicitTrackSizing { +public: + ExplicitTrackSizing(); + ExplicitTrackSizing(Vector); + ExplicitTrackSizing(Vector, int repeat_count); + static ExplicitTrackSizing make_auto() { return ExplicitTrackSizing(); }; + + bool is_repeat() const { return m_is_repeat; } + int repeat_count() const { return m_repeat_count; } + + Vector meta_grid_track_sizes() const& { return m_meta_grid_track_sizes; } + + String to_string() const; + bool operator==(ExplicitTrackSizing const& other) const + { + return m_meta_grid_track_sizes == other.meta_grid_track_sizes(); + } + +private: + Vector m_meta_grid_track_sizes; + bool m_is_repeat { false }; + int m_repeat_count { 0 }; +}; + } diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 4ba4f03d4a..cf5482aa1c 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -5409,7 +5409,7 @@ RefPtr Parser::parse_as_css_value(PropertyID property_id) RefPtr Parser::parse_grid_track_sizes(Vector const& component_values) { - Vector params; + Vector params; for (auto const& component_value : component_values) { if (component_value.is_function()) { auto const& function_token = component_value.function(); @@ -5439,7 +5439,7 @@ RefPtr Parser::parse_grid_track_sizes(Vector const& if (!part_two_tokens.has_next_token()) continue; - Vector repeat_params; + Vector repeat_params; while (true) { part_two_tokens.skip_whitespace(); auto current_component_value = part_two_tokens.next_token(); @@ -5469,13 +5469,8 @@ RefPtr Parser::parse_grid_track_sizes(Vector const& } } part_two_tokens.skip_whitespace(); - if (!part_two_tokens.has_next_token()) { - for (int i = 0; i < repeat_count; ++i) { - for (auto const& repeat_param : repeat_params) - params.append(repeat_param); - } + if (!part_two_tokens.has_next_token()) break; - } } // Automatic repetitions (auto-fill or auto-fit) cannot be combined with intrinsic or flexible sizes. @@ -5499,17 +5494,18 @@ RefPtr Parser::parse_grid_track_sizes(Vector const& // If a repeat() function that is not a ends up placing two adjacent to // each other, the name lists are merged. For example, repeat(2, [a] 1fr [b]) is equivalent to [a] // 1fr [b a] 1fr [b]. + return GridTrackSizeStyleValue::create(CSS::ExplicitTrackSizing(repeat_params, repeat_count)); } else { // FIXME: Implement MinMax, etc. } continue; } if (component_value.is_block()) { - params.append(Length::make_auto()); + params.append(GridTrackSize(Length::make_auto())); continue; } if (component_value.is(Token::Type::Ident) && component_value.token().ident().equals_ignoring_case("auto"sv)) { - params.append(Length::make_auto()); + params.append(GridTrackSize(Length::make_auto())); continue; } if (component_value.token().type() == Token::Type::Dimension) { @@ -5525,9 +5521,9 @@ RefPtr Parser::parse_grid_track_sizes(Vector const& if (!dimension.has_value()) return GridTrackSizeStyleValue::create({}); if (dimension->is_length()) - params.append(dimension->length()); + params.append(GridTrackSize(dimension->length())); if (dimension->is_percentage()) - params.append(dimension->percentage()); + params.append(GridTrackSize(dimension->percentage())); } return GridTrackSizeStyleValue::create(params); } diff --git a/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp b/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp index 68a726d8cb..84028bdd9a 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp @@ -705,16 +705,16 @@ Optional StyleProperties::font_variant() const return value_id_to_font_variant(value->to_identifier()); } -Vector StyleProperties::grid_template_columns() const +CSS::ExplicitTrackSizing StyleProperties::grid_template_columns() const { auto value = property(CSS::PropertyID::GridTemplateColumns); - return value->as_grid_track_size().grid_track_size(); + return value->as_explicit_track_sizing().explicit_track_sizing(); } -Vector StyleProperties::grid_template_rows() const +CSS::ExplicitTrackSizing StyleProperties::grid_template_rows() const { auto value = property(CSS::PropertyID::GridTemplateRows); - return value->as_grid_track_size().grid_track_size(); + return value->as_explicit_track_sizing().explicit_track_sizing(); } CSS::GridTrackPlacement StyleProperties::grid_column_end() const diff --git a/Userland/Libraries/LibWeb/CSS/StyleProperties.h b/Userland/Libraries/LibWeb/CSS/StyleProperties.h index 316709dca7..63c44f4fb7 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleProperties.h +++ b/Userland/Libraries/LibWeb/CSS/StyleProperties.h @@ -84,8 +84,8 @@ public: Optional pointer_events() const; Variant vertical_align() const; Optional font_variant() const; - Vector grid_template_columns() const; - Vector grid_template_rows() const; + CSS::ExplicitTrackSizing grid_template_columns() const; + CSS::ExplicitTrackSizing grid_template_rows() const; CSS::GridTrackPlacement grid_column_end() const; CSS::GridTrackPlacement grid_column_start() const; CSS::GridTrackPlacement grid_row_end() const; diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp index dcde804726..009850fca3 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp @@ -168,9 +168,9 @@ LengthStyleValue const& StyleValue::as_length() const return static_cast(*this); } -GridTrackSizeStyleValue const& StyleValue::as_grid_track_size() const +GridTrackSizeStyleValue const& StyleValue::as_explicit_track_sizing() const { - VERIFY(is_grid_track_size()); + VERIFY(is_explicit_track_sizing()); return static_cast(*this); } @@ -1418,21 +1418,15 @@ bool GridTrackPlacementStyleValue::equals(StyleValue const& other) const String GridTrackSizeStyleValue::to_string() const { - StringBuilder builder; - for (size_t i = 0; i < m_grid_track.size(); i++) { - builder.append(m_grid_track[i].to_string()); - if (i != m_grid_track.size() - 1) - builder.append(" "sv); - } - return builder.to_string(); + return m_explicit_track_sizing.to_string(); } bool GridTrackSizeStyleValue::equals(StyleValue const& other) const { if (type() != other.type()) return false; - auto const& typed_other = other.as_grid_track_size(); - return m_grid_track == typed_other.grid_track_size(); + auto const& typed_other = other.as_explicit_track_sizing(); + return m_explicit_track_sizing == typed_other.explicit_track_sizing(); } String IdentifierStyleValue::to_string() const @@ -2151,9 +2145,9 @@ NonnullRefPtr GridTrackPlacementStyleValue::create return adopt_ref(*new GridTrackPlacementStyleValue(grid_track_placement)); } -NonnullRefPtr GridTrackSizeStyleValue::create(Vector grid_track_size) +NonnullRefPtr GridTrackSizeStyleValue::create(CSS::ExplicitTrackSizing explicit_track_sizing) { - return adopt_ref(*new GridTrackSizeStyleValue(grid_track_size)); + return adopt_ref(*new GridTrackSizeStyleValue(explicit_track_sizing)); } NonnullRefPtr RectStyleValue::create(EdgeRect rect) diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h index 3e5e0fb3ee..4425544753 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h @@ -174,6 +174,7 @@ public: Calculated, Color, Content, + ExplicitTrackSizing, FilterValueList, Flex, FlexFlow, @@ -181,7 +182,6 @@ public: Frequency, GridTrackPlacement, GridTrackPlacementShorthand, - GridTrackSize, Identifier, Image, Inherit, @@ -226,7 +226,7 @@ public: bool is_frequency() const { return type() == Type::Frequency; } bool is_grid_track_placement() const { return type() == Type::GridTrackPlacement; } bool is_grid_track_placement_shorthand() const { return type() == Type::GridTrackPlacementShorthand; } - bool is_grid_track_size() const { return type() == Type::GridTrackSize; } + bool is_explicit_track_sizing() const { return type() == Type::ExplicitTrackSizing; } bool is_identifier() const { return type() == Type::Identifier; } bool is_image() const { return type() == Type::Image; } bool is_inherit() const { return type() == Type::Inherit; } @@ -269,7 +269,7 @@ public: FrequencyStyleValue const& as_frequency() const; GridTrackPlacementShorthandStyleValue const& as_grid_track_placement_shorthand() const; GridTrackPlacementStyleValue const& as_grid_track_placement() const; - GridTrackSizeStyleValue const& as_grid_track_size() const; + GridTrackSizeStyleValue const& as_explicit_track_sizing() const; IdentifierStyleValue const& as_identifier() const; ImageStyleValue const& as_image() const; InheritStyleValue const& as_inherit() const; @@ -310,7 +310,7 @@ public: FrequencyStyleValue& as_frequency() { return const_cast(const_cast(*this).as_frequency()); } GridTrackPlacementShorthandStyleValue& as_grid_track_placement_shorthand() { return const_cast(const_cast(*this).as_grid_track_placement_shorthand()); } GridTrackPlacementStyleValue& as_grid_track_placement() { return const_cast(const_cast(*this).as_grid_track_placement()); } - GridTrackSizeStyleValue& as_grid_track_size() { return const_cast(const_cast(*this).as_grid_track_size()); } + GridTrackSizeStyleValue& as_explicit_track_sizing() { return const_cast(const_cast(*this).as_explicit_track_sizing()); } IdentifierStyleValue& as_identifier() { return const_cast(const_cast(*this).as_identifier()); } ImageStyleValue& as_image() { return const_cast(const_cast(*this).as_image()); } InheritStyleValue& as_inherit() { return const_cast(const_cast(*this).as_inherit()); } @@ -1048,21 +1048,21 @@ private: class GridTrackSizeStyleValue final : public StyleValue { public: - static NonnullRefPtr create(Vector grid_track_size); + static NonnullRefPtr create(CSS::ExplicitTrackSizing explicit_track_sizing); virtual ~GridTrackSizeStyleValue() override = default; - Vector grid_track_size() const { return m_grid_track; } + CSS::ExplicitTrackSizing explicit_track_sizing() const { return m_explicit_track_sizing; } virtual String to_string() const override; virtual bool equals(StyleValue const& other) const override; private: - explicit GridTrackSizeStyleValue(Vector grid_track_size) - : StyleValue(Type::GridTrackSize) - , m_grid_track(grid_track_size) + explicit GridTrackSizeStyleValue(CSS::ExplicitTrackSizing explicit_track_sizing) + : StyleValue(Type::ExplicitTrackSizing) + , m_explicit_track_sizing(explicit_track_sizing) { } - Vector m_grid_track; + CSS::ExplicitTrackSizing m_explicit_track_sizing; }; class IdentifierStyleValue final : public StyleValue { diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index aee0245f86..6fd940a3d1 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -50,6 +50,7 @@ class CSSStyleSheet; class CSSSupportsRule; class Display; class ElementInlineCSSStyleDeclaration; +class ExplicitTrackSizing; class FilterValueListStyleValue; class FlexFlowStyleValue; class FlexStyleValue; @@ -78,6 +79,7 @@ class MediaList; class MediaQuery; class MediaQueryList; class MediaQueryListEvent; +class MetaGridTrackSize; class Number; class NumericStyleValue; class OverflowStyleValue; diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp index ba702f48a4..3a207c620c 100644 --- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp @@ -57,7 +57,9 @@ void GridFormattingContext::run(Box const& box, LayoutMode, AvailableSpace const boxes_to_place.append(child_box); return IterationDecision::Continue; }); - auto occupation_grid = OccupationGrid(static_cast(box.computed_values().grid_template_columns().size()), static_cast(box.computed_values().grid_template_rows().size())); + auto column_repeat_count = box.computed_values().grid_template_columns().is_repeat() ? box.computed_values().grid_template_columns().repeat_count() : 1; + auto row_repeat_count = box.computed_values().grid_template_rows().is_repeat() ? box.computed_values().grid_template_rows().repeat_count() : 1; + auto occupation_grid = OccupationGrid(column_repeat_count * box.computed_values().grid_template_columns().meta_grid_track_sizes().size(), row_repeat_count * box.computed_values().grid_template_rows().meta_grid_track_sizes().size()); // https://drafts.csswg.org/css-grid/#auto-placement-algo // 8.5. Grid Item Placement Algorithm @@ -521,10 +523,14 @@ void GridFormattingContext::run(Box const& box, LayoutMode, AvailableSpace const Vector grid_rows; Vector grid_columns; - for (auto& column_size : box.computed_values().grid_template_columns()) - grid_columns.append({ column_size, column_size }); - for (auto& row_size : box.computed_values().grid_template_rows()) - grid_rows.append({ row_size, row_size }); + for (int x = 0; x < column_repeat_count; ++x) { + for (auto& meta_grid_track_size : box.computed_values().grid_template_columns().meta_grid_track_sizes()) + grid_columns.append({ meta_grid_track_size.min_grid_track_size(), meta_grid_track_size.max_grid_track_size() }); + } + for (int x = 0; x < row_repeat_count; ++x) { + for (auto& meta_grid_track_size : box.computed_values().grid_template_rows().meta_grid_track_sizes()) + grid_rows.append({ meta_grid_track_size.min_grid_track_size(), meta_grid_track_size.max_grid_track_size() }); + } for (int column_index = grid_columns.size(); column_index < occupation_grid.column_count(); column_index++) grid_columns.append({ CSS::GridTrackSize::make_auto(), CSS::GridTrackSize::make_auto() });