diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPropertyID.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPropertyID.cpp index b0f554a5c4..c47ba8ea98 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPropertyID.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPropertyID.cpp @@ -20,7 +20,7 @@ void generate_bounds_checking_function(JsonObject& properties, SourceGenerator& static bool type_name_is_enum(StringView type_name) { - return !AK::first_is_one_of(type_name, "angle"sv, "color"sv, "custom-ident"sv, "frequency"sv, "image"sv, "integer"sv, "length"sv, "number"sv, "percentage"sv, "ratio"sv, "rect"sv, "resolution"sv, "string"sv, "time"sv, "url"sv); + return !AK::first_is_one_of(type_name, "angle"sv, "color"sv, "custom-ident"sv, "frequency"sv, "image"sv, "integer"sv, "length"sv, "number"sv, "paint"sv, "percentage"sv, "ratio"sv, "rect"sv, "resolution"sv, "string"sv, "time"sv, "url"sv); } ErrorOr serenity_main(Main::Arguments arguments) @@ -611,6 +611,8 @@ bool property_accepts_type(PropertyID property_id, ValueType value_type) property_generator.appendln(" case ValueType::Length:"); } else if (type_name == "number") { property_generator.appendln(" case ValueType::Number:"); + } else if (type_name == "paint") { + property_generator.appendln(" case ValueType::Paint:"); } else if (type_name == "percentage") { property_generator.appendln(" case ValueType::Percentage:"); } else if (type_name == "ratio") { diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 3de898abe2..3367332243 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -4652,6 +4652,39 @@ ErrorOr> Parser::parse_image_value(ComponentValue const& comp return parse_radial_gradient_function(component_value); } +// https://svgwg.org/svg2-draft/painting.html#SpecifyingPaint +ErrorOr> Parser::parse_paint_value(TokenStream& tokens) +{ + // ` = none | | [none | ]? | context-fill | context-stroke` + + if (tokens.peek_token().is(Token::Type::Ident)) { + auto maybe_ident = value_id_from_string(tokens.peek_token().token().ident()); + if (maybe_ident.has_value()) { + // FIXME: Accept `context-fill` and `context-stroke` + switch (*maybe_ident) { + case ValueID::None: + (void)tokens.next_token(); + return IdentifierStyleValue::create(*maybe_ident); + default: + return nullptr; + } + } + } + + if (auto color = TRY(parse_color_value(tokens.peek_token()))) { + (void)tokens.next_token(); + return color; + } + + if (auto url = TRY(parse_url_value(tokens.peek_token(), AllowedDataUrlType::Image))) { + // FIXME: Accept `[none | ]?` + (void)tokens.next_token(); + return url; + } + + return nullptr; +} + template ErrorOr> Parser::parse_comma_separated_value_list(Vector const& component_values, ParseFunction parse_one_value) { @@ -7760,15 +7793,6 @@ Parser::ParseErrorOr> Parser::parse_css_value(Property if (auto parsed_value = FIXME_TRY(parse_transform_origin_value(component_values))) return parsed_value.release_nonnull(); return ParseError ::SyntaxError; - case PropertyID::Fill: - case PropertyID::Stroke: - if (component_values.size() == 1) { - if (auto parsed_url = FIXME_TRY(parse_url_value(component_values.first()))) - return parsed_url.release_nonnull(); - } - // Allow normal value parsing to continue. - // URL is done here to avoid ambiguity with images. - break; default: break; } @@ -8055,6 +8079,11 @@ ErrorOr Parser::parse_css_value_for_properties(Readonl } } + if (auto property = any_property_accepts_type(property_ids, ValueType::Paint); property.has_value()) { + if (auto value = TRY(parse_paint_value(tokens))) + return PropertyAndValue { *property, value.release_nonnull() }; + } + return PropertyAndValue { property_ids.first(), nullptr }; } diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index b1dce14e31..20c5054430 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -311,6 +311,7 @@ private: ErrorOr> parse_ratio_value(TokenStream&); ErrorOr> parse_string_value(ComponentValue const&); ErrorOr> parse_image_value(ComponentValue const&); + ErrorOr> parse_paint_value(TokenStream&); template ErrorOr> parse_comma_separated_value_list(Vector const&, ParseFunction); ErrorOr> parse_simple_comma_separated_value_list(PropertyID, Vector const&); diff --git a/Userland/Libraries/LibWeb/CSS/Properties.json b/Userland/Libraries/LibWeb/CSS/Properties.json index 327ea57413..cf28263594 100644 --- a/Userland/Libraries/LibWeb/CSS/Properties.json +++ b/Userland/Libraries/LibWeb/CSS/Properties.json @@ -737,13 +737,8 @@ "affects-layout": false, "inherited": true, "initial": "black", - "__comment": "FIXME: Use `paint` as the type, once we have a PaintStyleValue and generic parsing for it.", "valid-types": [ - "color", - "url" - ], - "valid-identifiers": [ - "none" + "paint" ] }, "fill-opacity": { @@ -1709,13 +1704,8 @@ "affects-layout": false, "inherited": true, "initial": "none", - "__comment": "FIXME: Use `paint` as the type, once we have a PaintStyleValue and generic parsing for it.", "valid-types": [ - "color", - "url" - ], - "valid-identifiers": [ - "none" + "paint" ] }, "stroke-opacity": {