diff options
author | Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com> | 2022-10-26 16:09:20 +0300 |
---|---|---|
committer | Sam Atkins <atkinssj@gmail.com> | 2022-11-02 11:04:23 +0000 |
commit | f099e2aa12dde9fcbf6cd0bdd734824cd77e06f3 (patch) | |
tree | 0505fc3cdbdbbf992e6d62cfe37f78b99f8d9010 | |
parent | 4bf587811f4a90cf22b6118a55f72f3c16f1f45f (diff) | |
download | serenity-f099e2aa12dde9fcbf6cd0bdd734824cd77e06f3.zip |
LibWeb: Use more verbose input in CSS transform function generator
3 files changed, 93 insertions, 61 deletions
diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSTransformFunctions.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSTransformFunctions.cpp index 7637c28877..bb2d33ec6b 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSTransformFunctions.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSTransformFunctions.cpp @@ -58,6 +58,7 @@ ErrorOr<void> generate_header_file(JsonObject& transforms_data, Core::Stream::Fi #include <AK/Optional.h> #include <AK/StringView.h> +#include <AK/Vector.h> namespace Web::CSS { @@ -81,10 +82,13 @@ enum class TransformFunctionParameterType { Number, }; +struct TransformFunctionParameter { + TransformFunctionParameterType type; + bool required; +}; + struct TransformFunctionMetadata { - size_t min_parameters; - size_t max_parameters; - TransformFunctionParameterType parameter_type; + Vector<TransformFunctionParameter> parameters; }; TransformFunctionMetadata transform_function_metadata(TransformFunction); )~~~"); @@ -153,48 +157,40 @@ TransformFunctionMetadata transform_function_metadata(TransformFunction transfor )~~~"); transforms_data.for_each_member([&](auto& name, auto& value) { VERIFY(value.is_object()); - auto parameters_string = value.as_object().get("parameters"sv).as_string(); - GenericLexer lexer { parameters_string }; - - VERIFY(lexer.consume_specific('<')); - auto parameter_type_name = lexer.consume_until('>'); - VERIFY(lexer.consume_specific('>')); - - StringView parameter_type = ""sv; - if (parameter_type_name == "angle"sv) - parameter_type = "Angle"sv; - else if (parameter_type_name == "length-percentage"sv) - parameter_type = "LengthPercentage"sv; - else if (parameter_type_name == "number"sv) - parameter_type = "Number"sv; - else - VERIFY_NOT_REACHED(); - - StringView min_parameters = "1"sv; - StringView max_parameters = "1"sv; - if (!lexer.is_eof()) { - VERIFY(lexer.consume_specific('{')); - min_parameters = lexer.consume_until([](auto c) { return c == ',' || c == '}'; }); - if (lexer.consume_specific(',')) - max_parameters = lexer.consume_until('}'); - else - max_parameters = min_parameters; - VERIFY(lexer.consume_specific('}')); - } - VERIFY(lexer.is_eof()); auto member_generator = generator.fork(); member_generator.set("name:titlecase", title_casify_transform_function(name)); - member_generator.set("min_parameters", min_parameters); - member_generator.set("max_parameters", max_parameters); - member_generator.set("parameter_type", parameter_type); member_generator.append(R"~~~( case TransformFunction::@name:titlecase@: return TransformFunctionMetadata { - .min_parameters = @min_parameters@, - .max_parameters = @max_parameters@, - .parameter_type = TransformFunctionParameterType::@parameter_type@ - }; + .parameters = {)~~~"); + + const JsonArray& parameters = value.as_object().get("parameters"sv).as_array(); + bool first = true; + parameters.for_each([&](JsonValue const& value) { + GenericLexer lexer { value.as_object().get("type"sv).as_string() }; + VERIFY(lexer.consume_specific('<')); + auto parameter_type_name = lexer.consume_until('>'); + VERIFY(lexer.consume_specific('>')); + + StringView parameter_type = ""sv; + if (parameter_type_name == "angle"sv) + parameter_type = "Angle"sv; + else if (parameter_type_name == "length-percentage"sv) + parameter_type = "LengthPercentage"sv; + else if (parameter_type_name == "number"sv) + parameter_type = "Number"sv; + else + VERIFY_NOT_REACHED(); + + member_generator.append(first ? " "sv : ", "sv); + first = false; + + member_generator.append(String::formatted("{{ TransformFunctionParameterType::{}, {}}}", parameter_type, value.as_object().get("required"sv).to_string())); + }); + + member_generator.append(R"~~~( } + }; )~~~"); }); generator.append(R"~~~( diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 5ee33377fe..6441f64180 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -5531,7 +5531,13 @@ RefPtr<StyleValue> Parser::parse_transform_value(Vector<ComponentValue> const& c NonnullRefPtrVector<StyleValue> values; auto argument_tokens = TokenStream { part.function().values() }; argument_tokens.skip_whitespace(); + size_t argument_index = 0; while (argument_tokens.has_next_token()) { + if (argument_index == function_metadata.parameters.size()) { + dbgln_if(CSS_PARSER_DEBUG, "Too many arguments to {}. max: {}", part.function().name(), function_metadata.parameters.size()); + return nullptr; + } + auto const& value = argument_tokens.next_token(); RefPtr<CalculatedStyleValue> maybe_calc_value; if (auto maybe_dynamic_value = parse_dynamic_value(value)) { @@ -5542,7 +5548,7 @@ RefPtr<StyleValue> Parser::parse_transform_value(Vector<ComponentValue> const& c maybe_calc_value = maybe_dynamic_value->as_calculated(); } - switch (function_metadata.parameter_type) { + switch (function_metadata.parameters[argument_index].type) { case TransformFunctionParameterType::Angle: { // These are `<angle> | <zero>` in the spec, so we have to check for both kinds. if (maybe_calc_value && maybe_calc_value->resolves_to_angle()) { @@ -5596,15 +5602,12 @@ RefPtr<StyleValue> Parser::parse_transform_value(Vector<ComponentValue> const& c if (!argument_tokens.has_next_token()) return nullptr; } - } - if (values.size() < function_metadata.min_parameters) { - dbgln_if(CSS_PARSER_DEBUG, "Not enough arguments to {}. min: {}, given: {}", part.function().name(), function_metadata.min_parameters, values.size()); - return nullptr; + argument_index++; } - if (values.size() > function_metadata.max_parameters) { - dbgln_if(CSS_PARSER_DEBUG, "Too many arguments to {}. max: {}, given: {}", part.function().name(), function_metadata.max_parameters, values.size()); + if (argument_index < function_metadata.parameters.size() && function_metadata.parameters[argument_index].required) { + dbgln_if(CSS_PARSER_DEBUG, "Required parameter at position {} is missing", argument_index); return nullptr; } diff --git a/Userland/Libraries/LibWeb/CSS/TransformFunctions.json b/Userland/Libraries/LibWeb/CSS/TransformFunctions.json index 510f73bcdb..bca5b145bb 100644 --- a/Userland/Libraries/LibWeb/CSS/TransformFunctions.json +++ b/Userland/Libraries/LibWeb/CSS/TransformFunctions.json @@ -1,47 +1,80 @@ { "matrix": { - "parameters": "<number>{6}" + "parameters": [ + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true } + ] }, "matrix3d": { - "parameters": "<number>{16}" + "parameters": [ + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true }, + { "type": "<number>", "required": true } + ] }, "translate": { - "parameters": "<length-percentage>{1,2}" + "parameters": [ + { "type": "<length-percentage>", "required": true }, + { "type": "<length-percentage>", "required": false } + ] }, "translateX": { - "parameters": "<length-percentage>" + "parameters": [{ "type": "<length-percentage>", "required": true }] }, "translateY": { - "parameters": "<length-percentage>" + "parameters": [{ "type": "<length-percentage>", "required": true }] }, "scale": { - "parameters": "<number>{1,2}" + "parameters": [ + { "type": "<number>", "required": true }, + { "type": "<number>", "required": false } + ] }, "scaleX": { - "parameters": "<number>" + "parameters": [{ "type": "<number>", "required": true }] }, "scaleY": { - "parameters": "<number>" + "parameters": [{ "type": "<number>", "required": true }] }, "rotate": { - "parameters": "<angle>" + "parameters": [{ "type": "<angle>", "required": true }] }, "rotateX": { - "parameters": "<angle>" + "parameters": [{ "type": "<angle>", "required": true }] }, "rotateY": { - "parameters": "<angle>" + "parameters": [{ "type": "<angle>", "required": true }] }, "rotateZ": { - "parameters": "<angle>" + "parameters": [{ "type": "<angle>", "required": true }] }, "skew": { - "parameters": "<angle>{1,2}" + "parameters": [ + { "type": "<angle>", "required": true }, + { "type": "<angle>", "required": false } + ] }, "skewX": { - "parameters": "<angle>" + "parameters": [{ "type": "<angle>", "required": true }] }, "skewY": { - "parameters": "<angle>" + "parameters": [{ "type": "<angle>", "required": true }] } } |