diff options
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp | 45 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/Parser.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/StyleResolver.cpp | 13 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/StyleValue.h | 30 |
4 files changed, 87 insertions, 2 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 0240cfc322..6f82f9755b 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -2503,6 +2503,47 @@ RefPtr<StyleValue> Parser::parse_list_style_value(ParsingContext const& context, return ListStyleStyleValue::create(list_position.release_nonnull(), list_image.release_nonnull(), list_type.release_nonnull()); } +RefPtr<StyleValue> Parser::parse_overflow_value(ParsingContext const& context, Vector<StyleComponentValueRule> const& component_values) +{ + auto is_overflow = [](StyleValue const& value) -> bool { + switch (value.to_identifier()) { + case ValueID::Auto: + case ValueID::Clip: + case ValueID::Hidden: + case ValueID::Scroll: + case ValueID::Visible: + return true; + default: + return false; + } + }; + + if (component_values.size() == 1) { + auto maybe_value = parse_css_value(context, PropertyID::Overflow, component_values.first()); + if (!maybe_value) + return nullptr; + auto value = maybe_value.release_nonnull(); + if (is_overflow(*value)) + return OverflowStyleValue::create(value, value); + return nullptr; + } + + if (component_values.size() == 2) { + auto maybe_x_value = parse_css_value(context, PropertyID::OverflowX, component_values[0]); + auto maybe_y_value = parse_css_value(context, PropertyID::OverflowY, component_values[1]); + + if (!maybe_x_value || !maybe_y_value) + return nullptr; + auto x_value = maybe_x_value.release_nonnull(); + auto y_value = maybe_y_value.release_nonnull(); + if (!is_overflow(x_value) || !is_overflow(y_value)) + return nullptr; + return OverflowStyleValue::create(x_value, y_value); + } + + return nullptr; +} + RefPtr<StyleValue> Parser::parse_text_decoration_value(ParsingContext const& context, Vector<StyleComponentValueRule> const& component_values) { auto is_text_decoration_line = [](StyleValue const& value) -> bool { @@ -2650,6 +2691,10 @@ RefPtr<StyleValue> Parser::parse_css_value(PropertyID property_id, TokenStream<S if (auto parsed_value = parse_list_style_value(m_context, component_values)) return parsed_value; break; + case PropertyID::Overflow: + if (auto parsed_value = parse_overflow_value(m_context, component_values)) + return parsed_value; + break; case PropertyID::TextDecoration: if (auto parsed_value = parse_text_decoration_value(m_context, component_values)) return parsed_value; diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index 12fd729d8f..4ef0aa3b2d 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -184,6 +184,7 @@ private: static RefPtr<StyleValue> parse_flex_flow_value(ParsingContext const&, Vector<StyleComponentValueRule> const&); static RefPtr<StyleValue> parse_font_value(ParsingContext const&, Vector<StyleComponentValueRule> const&); static RefPtr<StyleValue> parse_list_style_value(ParsingContext const&, Vector<StyleComponentValueRule> const&); + static RefPtr<StyleValue> parse_overflow_value(ParsingContext const&, Vector<StyleComponentValueRule> const&); static RefPtr<StyleValue> parse_text_decoration_value(ParsingContext const&, Vector<StyleComponentValueRule> const&); // calc() parsing, according to https://www.w3.org/TR/css-values-3/#calc-syntax diff --git a/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp b/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp index 669f6842b7..3d6181741f 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp @@ -220,8 +220,17 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope } if (property_id == CSS::PropertyID::Overflow) { - style.set_property(CSS::PropertyID::OverflowX, value); - style.set_property(CSS::PropertyID::OverflowY, value); + if (value.is_overflow()) { + auto& overflow = static_cast<OverflowStyleValue const&>(value); + style.set_property(CSS::PropertyID::OverflowX, overflow.overflow_x()); + style.set_property(CSS::PropertyID::OverflowY, overflow.overflow_y()); + return; + } + if (value.is_builtin()) { + style.set_property(CSS::PropertyID::OverflowX, value); + style.set_property(CSS::PropertyID::OverflowY, value); + return; + } return; } diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h index 66e1dd3f09..4a190f5e76 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h @@ -237,6 +237,7 @@ public: FlexFlow, Font, ListStyle, + Overflow, TextDecoration, }; @@ -262,6 +263,7 @@ public: 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_overflow() const { return type() == Type::Overflow; } bool is_text_decoration() const { return type() == Type::TextDecoration; } bool is_builtin() const { return is_inherit() || is_initial(); } @@ -902,6 +904,34 @@ private: NonnullRefPtr<StyleValue> m_style_type; }; +class OverflowStyleValue final : public StyleValue { +public: + static NonnullRefPtr<OverflowStyleValue> create(NonnullRefPtr<StyleValue> overflow_x, NonnullRefPtr<StyleValue> overflow_y) + { + return adopt_ref(*new OverflowStyleValue(overflow_x, overflow_y)); + } + virtual ~OverflowStyleValue() override { } + + NonnullRefPtr<StyleValue> overflow_x() const { return m_overflow_x; } + NonnullRefPtr<StyleValue> overflow_y() const { return m_overflow_y; } + + virtual String to_string() const override + { + return String::formatted("{} {}", m_overflow_x->to_string(), m_overflow_y->to_string()); + } + +private: + OverflowStyleValue(NonnullRefPtr<StyleValue> overflow_x, NonnullRefPtr<StyleValue> overflow_y) + : StyleValue(Type::Overflow) + , m_overflow_x(overflow_x) + , m_overflow_y(overflow_y) + { + } + + NonnullRefPtr<StyleValue> m_overflow_x; + NonnullRefPtr<StyleValue> m_overflow_y; +}; + class TextDecorationStyleValue final : public StyleValue { public: static NonnullRefPtr<TextDecorationStyleValue> create( |