From a80408fea68b60ad2e8d2bc2a69a43563d7852bc Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Mon, 7 Apr 2025 11:54:51 +0100 Subject: [PATCH] LibWeb/CSS: Store `@property` initial value as a style value For now, it's the "raw" UnresolvedStyleValue. Later, we'll need to try to parse it into a "real" style value using the property's syntax. --- Libraries/LibWeb/CSS/CSSPropertyRule.cpp | 15 +++++++++++---- Libraries/LibWeb/CSS/CSSPropertyRule.h | 9 ++++----- Libraries/LibWeb/CSS/Parser/DescriptorParsing.cpp | 10 ++++------ Libraries/LibWeb/CSS/Parser/RuleParsing.cpp | 9 +++++---- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/Libraries/LibWeb/CSS/CSSPropertyRule.cpp b/Libraries/LibWeb/CSS/CSSPropertyRule.cpp index ab9c7fd4580..e6443cb0c79 100644 --- a/Libraries/LibWeb/CSS/CSSPropertyRule.cpp +++ b/Libraries/LibWeb/CSS/CSSPropertyRule.cpp @@ -13,12 +13,12 @@ namespace Web::CSS { GC_DEFINE_ALLOCATOR(CSSPropertyRule); -GC::Ref CSSPropertyRule::create(JS::Realm& realm, FlyString name, FlyString syntax, bool inherits, Optional initial_value) +GC::Ref CSSPropertyRule::create(JS::Realm& realm, FlyString name, FlyString syntax, bool inherits, RefPtr initial_value) { return realm.create(realm, move(name), move(syntax), inherits, move(initial_value)); } -CSSPropertyRule::CSSPropertyRule(JS::Realm& realm, FlyString name, FlyString syntax, bool inherits, Optional initial_value) +CSSPropertyRule::CSSPropertyRule(JS::Realm& realm, FlyString name, FlyString syntax, bool inherits, RefPtr initial_value) : CSSRule(realm, Type::Property) , m_name(move(name)) , m_syntax(move(syntax)) @@ -27,6 +27,13 @@ CSSPropertyRule::CSSPropertyRule(JS::Realm& realm, FlyString name, FlyString syn { } +Optional CSSPropertyRule::initial_value() const +{ + if (m_initial_value) + return m_initial_value->to_string(CSSStyleValue::SerializationMode::Normal); + return {}; +} + void CSSPropertyRule::initialize(JS::Realm& realm) { Base::initialize(realm); @@ -63,8 +70,8 @@ String CSSPropertyRule::serialized() const // 8. If the rule’s initial-value is present, follow these substeps: if (initial_value().has_value()) { // 1. The string "initial-value:". - // 2. The result of performing serialize a CSS value in the rule’s initial-value followed by a single SEMICOLON (U+003B), followed by a SPACE (U+0020). - // FIXME: Follow the spec for serializing the value whenever we actually have a CSS value here. + // 2. The result of performing serialize a CSS value in the rule’s initial-value followed by a single SEMICOLON + // (U+003B), followed by a SPACE (U+0020). builder.appendff("initial-value: {}; ", initial_value()); } // 9. A single RIGHT CURLY BRACKET (U+007D). diff --git a/Libraries/LibWeb/CSS/CSSPropertyRule.h b/Libraries/LibWeb/CSS/CSSPropertyRule.h index 58802c020a8..159361fc92a 100644 --- a/Libraries/LibWeb/CSS/CSSPropertyRule.h +++ b/Libraries/LibWeb/CSS/CSSPropertyRule.h @@ -21,17 +21,17 @@ class CSSPropertyRule final : public CSSRule { GC_DECLARE_ALLOCATOR(CSSPropertyRule); public: - static GC::Ref create(JS::Realm&, FlyString name, FlyString syntax, bool inherits, Optional initial_value); + static GC::Ref create(JS::Realm&, FlyString name, FlyString syntax, bool inherits, RefPtr initial_value); virtual ~CSSPropertyRule() = default; FlyString const& name() const { return m_name; } FlyString const& syntax() const { return m_syntax; } bool inherits() const { return m_inherits; } - Optional initial_value() const { return m_initial_value; } + Optional initial_value() const; private: - CSSPropertyRule(JS::Realm&, FlyString name, FlyString syntax, bool inherits, Optional initial_value); + CSSPropertyRule(JS::Realm&, FlyString name, FlyString syntax, bool inherits, RefPtr initial_value); virtual void initialize(JS::Realm&) override; virtual String serialized() const override; @@ -39,8 +39,7 @@ private: FlyString m_name; FlyString m_syntax; bool m_inherits; - // FIXME: This should hold an actual CSS value, matching the syntax - Optional m_initial_value; + RefPtr m_initial_value; }; template<> diff --git a/Libraries/LibWeb/CSS/Parser/DescriptorParsing.cpp b/Libraries/LibWeb/CSS/Parser/DescriptorParsing.cpp index 50bc317a5e1..31dcc622d8e 100644 --- a/Libraries/LibWeb/CSS/Parser/DescriptorParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/DescriptorParsing.cpp @@ -65,13 +65,11 @@ Parser::ParseErrorOr> Parser::parse_descriptor_valu return parse_comma_separated_value_list(tokens, [this](auto& tokens) -> RefPtr { return parse_font_source_value(tokens); }); - case DescriptorMetadata::ValueType::OptionalDeclarationValue: { - // FIXME: This is for an @property's initial value. Figure out what this should actually do once we need it. - StringBuilder initial_value_sb; + case DescriptorMetadata::ValueType::OptionalDeclarationValue: + // `component_values` already has what we want. Just skip through its tokens so code below knows we consumed them. while (tokens.has_next_token()) - initial_value_sb.append(tokens.consume_a_token().to_string()); - return StringStyleValue::create(initial_value_sb.to_fly_string_without_validation()); - } + tokens.discard_a_token(); + return UnresolvedStyleValue::create(move(component_values), false, {}); case DescriptorMetadata::ValueType::PositivePercentage: if (auto percentage_value = parse_percentage_value(tokens)) { if (percentage_value->is_percentage()) { diff --git a/Libraries/LibWeb/CSS/Parser/RuleParsing.cpp b/Libraries/LibWeb/CSS/Parser/RuleParsing.cpp index 35f0597db8c..cddd279e031 100644 --- a/Libraries/LibWeb/CSS/Parser/RuleParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/RuleParsing.cpp @@ -535,7 +535,7 @@ GC::Ptr Parser::convert_to_property_rule(AtRule const& rule) Optional syntax_maybe; Optional inherits_maybe; - Optional initial_value_maybe; + RefPtr initial_value_maybe; rule.for_each_as_declaration_list([&](auto& declaration) { if (auto descriptor = convert_to_descriptor(AtRuleID::Property, declaration); descriptor.has_value()) { @@ -558,15 +558,16 @@ GC::Ptr Parser::convert_to_property_rule(AtRule const& rule) return; } if (descriptor->descriptor_id == DescriptorID::InitialValue) { - if (descriptor->value->is_string()) - initial_value_maybe = descriptor->value->as_string().string_value().to_string(); + initial_value_maybe = *descriptor->value; return; } } }); + // TODO: Parse the initial value using the syntax, if it's provided. + if (syntax_maybe.has_value() && inherits_maybe.has_value()) { - return CSSPropertyRule::create(realm(), name, syntax_maybe.value(), inherits_maybe.value(), std::move(initial_value_maybe)); + return CSSPropertyRule::create(realm(), name, syntax_maybe.value(), inherits_maybe.value(), move(initial_value_maybe)); } return {}; }