mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 23:50:19 +00:00
LibWeb: Use more verbose input in CSS transform function generator
This commit is contained in:
parent
4bf587811f
commit
f099e2aa12
Notes:
sideshowbarker
2024-07-17 04:53:07 +09:00
Author: https://github.com/kalenikaliaksandr Commit: https://github.com/SerenityOS/serenity/commit/f099e2aa12 Pull-request: https://github.com/SerenityOS/serenity/pull/15807 Reviewed-by: https://github.com/AtkinsSJ ✅ Reviewed-by: https://github.com/gmta
3 changed files with 94 additions and 62 deletions
|
@ -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"~~~(
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
argument_index++;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 }]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue