diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 3e7c092c09..df4a7d04d5 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -1981,6 +1981,63 @@ RefPtr Parser::parse_flex_value(ParsingContext const& context, Vecto return FlexStyleValue::create(flex_grow.release_nonnull(), flex_shrink.release_nonnull(), flex_basis.release_nonnull()); } +RefPtr Parser::parse_flex_flow_value(ParsingContext const& context, Vector const& component_values) +{ + auto is_flex_direction = [](StyleValue const& value) -> bool { + switch (value.to_identifier()) { + case ValueID::Row: + case ValueID::RowReverse: + case ValueID::Column: + case ValueID::ColumnReverse: + return true; + default: + return false; + } + }; + + auto is_flex_wrap = [](StyleValue const& value) -> bool { + switch (value.to_identifier()) { + case ValueID::Wrap: + case ValueID::Nowrap: + case ValueID::WrapReverse: + return true; + default: + return false; + } + }; + + if (component_values.size() > 2) + return nullptr; + + RefPtr flex_direction; + RefPtr flex_wrap; + + for (auto& part : component_values) { + auto value = Parser::parse_css_value(context, PropertyID::FlexFlow, part); + if (!value) + return nullptr; + if (is_flex_direction(*value)) { + if (flex_direction) + return nullptr; + flex_direction = value.release_nonnull(); + continue; + } + if (is_flex_wrap(*value)) { + if (flex_wrap) + return nullptr; + flex_wrap = value.release_nonnull(); + continue; + } + } + + if (!flex_direction) + flex_direction = IdentifierStyleValue::create(ValueID::Row); + if (!flex_wrap) + flex_wrap = IdentifierStyleValue::create(ValueID::Nowrap); + + return FlexFlowStyleValue::create(flex_direction.release_nonnull(), flex_wrap.release_nonnull()); +} + RefPtr Parser::parse_font_value(ParsingContext const& context, Vector const& component_values) { auto is_font_size = [](StyleValue const& value) -> bool { @@ -2381,6 +2438,10 @@ RefPtr Parser::parse_css_value(PropertyID property_id, TokenStream parse_background_value(ParsingContext const&, Vector const&); static RefPtr parse_box_shadow_value(ParsingContext const&, Vector const&); static RefPtr parse_flex_value(ParsingContext const&, Vector const&); + static RefPtr parse_flex_flow_value(ParsingContext const&, Vector const&); static RefPtr parse_font_value(ParsingContext const&, Vector const&); static RefPtr parse_list_style_value(ParsingContext const&, Vector const&); static RefPtr parse_text_decoration_value(ParsingContext const&, Vector const&); diff --git a/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp b/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp index 32720bd4a9..bec66219a7 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp @@ -219,37 +219,6 @@ static inline bool is_color(StyleValue const& value) return false; } -static inline bool is_flex_direction(StyleValue const& value) -{ - if (value.is_builtin_or_dynamic()) - return true; - - switch (value.to_identifier()) { - case ValueID::Row: - case ValueID::RowReverse: - case ValueID::Column: - case ValueID::ColumnReverse: - return true; - default: - return false; - } -} - -static inline bool is_flex_wrap(StyleValue const& value) -{ - if (value.is_builtin_or_dynamic()) - return true; - - switch (value.to_identifier()) { - case ValueID::Wrap: - case ValueID::Nowrap: - case ValueID::WrapReverse: - return true; - default: - return false; - } -} - static inline bool is_font_family(StyleValue const& value) { if (value.is_builtin_or_dynamic()) @@ -793,40 +762,17 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope } if (property_id == CSS::PropertyID::FlexFlow) { - if (value.is_component_value_list()) { - auto parts = static_cast(value).values(); - if (parts.is_empty() || parts.size() > 2) - return; - - RefPtr flex_direction_value; - RefPtr flex_wrap_value; - - for (auto& part : parts) { - auto value = Parser::parse_css_value(context, property_id, part); - if (!value) - return; - if (is_flex_direction(*value)) { - if (flex_direction_value) - return; - flex_direction_value = move(value); - continue; - } - if (is_flex_wrap(*value)) { - if (flex_wrap_value) - return; - flex_wrap_value = move(value); - continue; - } - } - - if (flex_direction_value) - style.set_property(CSS::PropertyID::FlexDirection, *flex_direction_value); - if (flex_wrap_value) - style.set_property(CSS::PropertyID::FlexWrap, *flex_wrap_value); - + if (value.is_flex_flow()) { + auto& flex_flow = static_cast(value); + style.set_property(CSS::PropertyID::FlexDirection, flex_flow.flex_direction()); + style.set_property(CSS::PropertyID::FlexWrap, flex_flow.flex_wrap()); + return; + } + if (value.is_builtin()) { + style.set_property(CSS::PropertyID::FlexDirection, value); + style.set_property(CSS::PropertyID::FlexWrap, value); return; } - return; } diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h index 1699a36d58..8fbe2dd7b8 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h @@ -232,6 +232,7 @@ public: Background, BoxShadow, Flex, + FlexFlow, Font, ListStyle, TextDecoration, @@ -254,6 +255,7 @@ public: bool is_background() const { return type() == Type::Background; } bool is_box_shadow() const { return type() == Type::BoxShadow; } bool is_flex() const { return type() == Type::Flex; } + bool is_flex_flow() const { return type() == Type::FlexFlow; } bool is_font() const { return type() == Type::Font; } bool is_list_style() const { return type() == Type::ListStyle; } bool is_text_decoration() const { return type() == Type::TextDecoration; } @@ -716,6 +718,34 @@ private: NonnullRefPtr m_basis; }; +class FlexFlowStyleValue final : public StyleValue { +public: + static NonnullRefPtr create(NonnullRefPtr flex_direction, NonnullRefPtr flex_wrap) + { + return adopt_ref(*new FlexFlowStyleValue(flex_direction, flex_wrap)); + } + virtual ~FlexFlowStyleValue() override { } + + NonnullRefPtr flex_direction() const { return m_flex_direction; } + NonnullRefPtr flex_wrap() const { return m_flex_wrap; } + + virtual String to_string() const override + { + return String::formatted("FlexFlow flex_direction: {}, flex_wrap: {}", m_flex_direction->to_string(), m_flex_wrap->to_string()); + } + +private: + FlexFlowStyleValue(NonnullRefPtr flex_direction, NonnullRefPtr flex_wrap) + : StyleValue(Type::FlexFlow) + , m_flex_direction(flex_direction) + , m_flex_wrap(flex_wrap) + { + } + + NonnullRefPtr m_flex_direction; + NonnullRefPtr m_flex_wrap; +}; + class FontStyleValue final : public StyleValue { public: static NonnullRefPtr create(NonnullRefPtr font_style, NonnullRefPtr font_weight, NonnullRefPtr font_size, NonnullRefPtr line_height, NonnullRefPtrVector&& font_families) { return adopt_ref(*new FontStyleValue(font_style, font_weight, font_size, line_height, move(font_families))); }