diff options
author | Sam Atkins <atkinssj@serenityos.org> | 2022-02-23 19:56:25 +0000 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-02-25 19:35:34 +0100 |
commit | adaab231496a05ac6e3ece59b6c97a8b7affb015 (patch) | |
tree | 654d88e2b78d5cf7c1accb306b9a5a66620532b5 /Userland/Libraries | |
parent | a9ad72cc0ff197fda4ea7a138a5dc388782316bb (diff) | |
download | serenity-adaab231496a05ac6e3ece59b6c97a8b7affb015.zip |
LibWeb: Parse the `content` property
For now, we only understand `none`, `normal`, `<image>` and `<string>`.
The various other functions and identifiers can be added later.
We can *almost* use a StyleValueList for this, except it's divided into
two parts - the content, and the optional "alt text". So, I've added a
new StyleValue for it.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp | 64 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/Parser.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Properties.json | 12 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/StyleValue.cpp | 13 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/StyleValue.h | 29 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Forward.h | 1 |
6 files changed, 120 insertions, 0 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 69b216a74a..a55787c6d0 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -3280,6 +3280,66 @@ RefPtr<StyleValue> Parser::parse_single_box_shadow_value(TokenStream<StyleCompon return BoxShadowStyleValue::create(color.release_value(), offset_x.release_value(), offset_y.release_value(), blur_radius.release_value(), spread_distance.release_value(), placement.release_value()); } +RefPtr<StyleValue> Parser::parse_content_value(Vector<StyleComponentValueRule> const& component_values) +{ + // FIXME: `content` accepts several kinds of function() type, which we don't handle in property_accepts_value() yet. + + auto is_single_value_identifier = [](ValueID identifier) -> bool { + switch (identifier) { + case ValueID::None: + case ValueID::Normal: + return true; + default: + return false; + } + }; + + if (component_values.size() == 1) { + if (auto identifier = parse_identifier_value(component_values.first())) { + if (is_single_value_identifier(identifier->to_identifier())) + return identifier; + } + } + + NonnullRefPtrVector<StyleValue> content_values; + NonnullRefPtrVector<StyleValue> alt_text_values; + bool in_alt_text = false; + + for (auto const& value : component_values) { + if (value.is(Token::Type::Delim) && value.token().delim() == "/"sv) { + if (in_alt_text || content_values.is_empty()) + return {}; + in_alt_text = true; + continue; + } + auto style_value = parse_css_value(value); + if (style_value && property_accepts_value(PropertyID::Content, *style_value)) { + if (is_single_value_identifier(style_value->to_identifier())) + return {}; + + if (in_alt_text) { + alt_text_values.append(style_value.release_nonnull()); + } else { + content_values.append(style_value.release_nonnull()); + } + continue; + } + + return {}; + } + + if (content_values.is_empty()) + return {}; + if (in_alt_text && alt_text_values.is_empty()) + return {}; + + RefPtr<StyleValueList> alt_text; + if (!alt_text_values.is_empty()) + alt_text = StyleValueList::create(move(alt_text_values), StyleValueList::Separator::Space); + + return ContentStyleValue::create(StyleValueList::create(move(content_values), StyleValueList::Separator::Space), move(alt_text)); +} + RefPtr<StyleValue> Parser::parse_flex_value(Vector<StyleComponentValueRule> const& component_values) { if (component_values.size() == 1) { @@ -3864,6 +3924,10 @@ Result<NonnullRefPtr<StyleValue>, Parser::ParsingResult> Parser::parse_css_value if (auto parsed_value = parse_box_shadow_value(component_values)) return parsed_value.release_nonnull(); return ParsingResult::SyntaxError; + case PropertyID::Content: + if (auto parsed_value = parse_content_value(component_values)) + return parsed_value.release_nonnull(); + return ParsingResult::SyntaxError; case PropertyID::Flex: if (auto parsed_value = parse_flex_value(component_values)) return parsed_value.release_nonnull(); diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index febe81110b..a1ae0c5871 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -274,6 +274,7 @@ private: RefPtr<StyleValue> parse_border_radius_shorthand_value(Vector<StyleComponentValueRule> const&); RefPtr<StyleValue> parse_box_shadow_value(Vector<StyleComponentValueRule> const&); RefPtr<StyleValue> parse_single_box_shadow_value(TokenStream<StyleComponentValueRule>&); + RefPtr<StyleValue> parse_content_value(Vector<StyleComponentValueRule> const&); RefPtr<StyleValue> parse_flex_value(Vector<StyleComponentValueRule> const&); RefPtr<StyleValue> parse_flex_flow_value(Vector<StyleComponentValueRule> const&); RefPtr<StyleValue> parse_font_value(Vector<StyleComponentValueRule> const&); diff --git a/Userland/Libraries/LibWeb/CSS/Properties.json b/Userland/Libraries/LibWeb/CSS/Properties.json index 76b2980fee..4d72137c9c 100644 --- a/Userland/Libraries/LibWeb/CSS/Properties.json +++ b/Userland/Libraries/LibWeb/CSS/Properties.json @@ -510,6 +510,18 @@ "hashless-hex-color" ] }, + "content": { + "inherited": false, + "initial": "normal", + "__comment": "FIXME: This accepts a whole lot of other types and identifiers!", + "valid-types": [ + "string" + ], + "valid-identifiers": [ + "normal", + "none" + ] + }, "cursor": { "inherited": true, "initial": "auto", diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp index 61574be54c..0aab0d5ab4 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp @@ -81,6 +81,12 @@ ColorStyleValue const& StyleValue::as_color() const return static_cast<ColorStyleValue const&>(*this); } +ContentStyleValue const& StyleValue::as_content() const +{ + VERIFY(is_content()); + return static_cast<ContentStyleValue const&>(*this); +} + FlexStyleValue const& StyleValue::as_flex() const { VERIFY(is_flex()); @@ -1015,6 +1021,13 @@ String CombinedBorderRadiusStyleValue::to_string() const return String::formatted("{} {} {} {} / {} {} {} {}", m_top_left->horizontal_radius().to_string(), m_top_right->horizontal_radius().to_string(), m_bottom_right->horizontal_radius().to_string(), m_bottom_left->horizontal_radius().to_string(), m_top_left->vertical_radius().to_string(), m_top_right->vertical_radius().to_string(), m_bottom_right->vertical_radius().to_string(), m_bottom_left->vertical_radius().to_string()); } +String ContentStyleValue::to_string() const +{ + if (has_alt_text()) + return String::formatted("{} / {}", m_content->to_string(), m_alt_text->to_string()); + return m_content->to_string(); +} + String FlexStyleValue::to_string() const { return String::formatted("{} {} {}", m_grow->to_string(), m_shrink->to_string(), m_basis->to_string()); diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h index b98cf3ff19..ad09542f20 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h @@ -297,6 +297,7 @@ public: Calculated, Color, CombinedBorderRadius, + Content, Flex, FlexFlow, Font, @@ -333,6 +334,7 @@ public: bool is_box_shadow() const { return type() == Type::BoxShadow; } bool is_calculated() const { return type() == Type::Calculated; } bool is_color() const { return type() == Type::Color; } + bool is_content() const { return type() == Type::Content; } 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; } @@ -367,6 +369,7 @@ public: BoxShadowStyleValue const& as_box_shadow() const; CalculatedStyleValue const& as_calculated() const; ColorStyleValue const& as_color() const; + ContentStyleValue const& as_content() const; FlexFlowStyleValue const& as_flex_flow() const; FlexStyleValue const& as_flex() const; FontStyleValue const& as_font() const; @@ -399,6 +402,7 @@ public: BoxShadowStyleValue& as_box_shadow() { return const_cast<BoxShadowStyleValue&>(const_cast<StyleValue const&>(*this).as_box_shadow()); } CalculatedStyleValue& as_calculated() { return const_cast<CalculatedStyleValue&>(const_cast<StyleValue const&>(*this).as_calculated()); } ColorStyleValue& as_color() { return const_cast<ColorStyleValue&>(const_cast<StyleValue const&>(*this).as_color()); } + ContentStyleValue& as_content() { return const_cast<ContentStyleValue&>(const_cast<StyleValue const&>(*this).as_content()); } FlexFlowStyleValue& as_flex_flow() { return const_cast<FlexFlowStyleValue&>(const_cast<StyleValue const&>(*this).as_flex_flow()); } FlexStyleValue& as_flex() { return const_cast<FlexStyleValue&>(const_cast<StyleValue const&>(*this).as_flex()); } FontStyleValue& as_font() { return const_cast<FontStyleValue&>(const_cast<StyleValue const&>(*this).as_font()); } @@ -969,6 +973,31 @@ private: NonnullRefPtr<BorderRadiusStyleValue> m_bottom_left; }; +class ContentStyleValue final : public StyleValue { +public: + static NonnullRefPtr<ContentStyleValue> create(NonnullRefPtr<StyleValueList> content, RefPtr<StyleValueList> alt_text) + { + return adopt_ref(*new ContentStyleValue(move(content), move(alt_text))); + } + + StyleValueList const& content() const { return *m_content; } + bool has_alt_text() const { return !m_alt_text.is_null(); } + StyleValueList const* alt_text() const { return m_alt_text; } + + virtual String to_string() const override; + +private: + ContentStyleValue(NonnullRefPtr<StyleValueList> content, RefPtr<StyleValueList> alt_text) + : StyleValue(Type::Content) + , m_content(move(content)) + , m_alt_text(move(alt_text)) + { + } + + NonnullRefPtr<StyleValueList> m_content; + RefPtr<StyleValueList> m_alt_text; +}; + class FlexStyleValue final : public StyleValue { public: static NonnullRefPtr<FlexStyleValue> create( diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index fbdadad579..e26f5f06da 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -30,6 +30,7 @@ class BorderStyleValue; class BoxShadowStyleValue; class CalculatedStyleValue; class ColorStyleValue; +class ContentStyleValue; class CSSImportRule; class CSSMediaRule; class CSSRule; |