mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 21:57:35 +00:00
LibWeb: Use more verbose input in CSS transform function generator
This commit is contained in:
parent
4bf587811f
commit
f099e2aa12
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/Optional.h>
|
||||||
#include <AK/StringView.h>
|
#include <AK/StringView.h>
|
||||||
|
#include <AK/Vector.h>
|
||||||
|
|
||||||
namespace Web::CSS {
|
namespace Web::CSS {
|
||||||
|
|
||||||
|
@ -81,10 +82,13 @@ enum class TransformFunctionParameterType {
|
||||||
Number,
|
Number,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TransformFunctionParameter {
|
||||||
|
TransformFunctionParameterType type;
|
||||||
|
bool required;
|
||||||
|
};
|
||||||
|
|
||||||
struct TransformFunctionMetadata {
|
struct TransformFunctionMetadata {
|
||||||
size_t min_parameters;
|
Vector<TransformFunctionParameter> parameters;
|
||||||
size_t max_parameters;
|
|
||||||
TransformFunctionParameterType parameter_type;
|
|
||||||
};
|
};
|
||||||
TransformFunctionMetadata transform_function_metadata(TransformFunction);
|
TransformFunctionMetadata transform_function_metadata(TransformFunction);
|
||||||
)~~~");
|
)~~~");
|
||||||
|
@ -153,48 +157,40 @@ TransformFunctionMetadata transform_function_metadata(TransformFunction transfor
|
||||||
)~~~");
|
)~~~");
|
||||||
transforms_data.for_each_member([&](auto& name, auto& value) {
|
transforms_data.for_each_member([&](auto& name, auto& value) {
|
||||||
VERIFY(value.is_object());
|
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();
|
auto member_generator = generator.fork();
|
||||||
member_generator.set("name:titlecase", title_casify_transform_function(name));
|
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"~~~(
|
member_generator.append(R"~~~(
|
||||||
case TransformFunction::@name:titlecase@:
|
case TransformFunction::@name:titlecase@:
|
||||||
return TransformFunctionMetadata {
|
return TransformFunctionMetadata {
|
||||||
.min_parameters = @min_parameters@,
|
.parameters = {)~~~");
|
||||||
.max_parameters = @max_parameters@,
|
|
||||||
.parameter_type = TransformFunctionParameterType::@parameter_type@
|
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"~~~(
|
generator.append(R"~~~(
|
||||||
|
|
|
@ -5531,7 +5531,13 @@ RefPtr<StyleValue> Parser::parse_transform_value(Vector<ComponentValue> const& c
|
||||||
NonnullRefPtrVector<StyleValue> values;
|
NonnullRefPtrVector<StyleValue> values;
|
||||||
auto argument_tokens = TokenStream { part.function().values() };
|
auto argument_tokens = TokenStream { part.function().values() };
|
||||||
argument_tokens.skip_whitespace();
|
argument_tokens.skip_whitespace();
|
||||||
|
size_t argument_index = 0;
|
||||||
while (argument_tokens.has_next_token()) {
|
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();
|
auto const& value = argument_tokens.next_token();
|
||||||
RefPtr<CalculatedStyleValue> maybe_calc_value;
|
RefPtr<CalculatedStyleValue> maybe_calc_value;
|
||||||
if (auto maybe_dynamic_value = parse_dynamic_value(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();
|
maybe_calc_value = maybe_dynamic_value->as_calculated();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (function_metadata.parameter_type) {
|
switch (function_metadata.parameters[argument_index].type) {
|
||||||
case TransformFunctionParameterType::Angle: {
|
case TransformFunctionParameterType::Angle: {
|
||||||
// These are `<angle> | <zero>` in the spec, so we have to check for both kinds.
|
// 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()) {
|
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())
|
if (!argument_tokens.has_next_token())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
argument_index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (values.size() < function_metadata.min_parameters) {
|
if (argument_index < function_metadata.parameters.size() && function_metadata.parameters[argument_index].required) {
|
||||||
dbgln_if(CSS_PARSER_DEBUG, "Not enough arguments to {}. min: {}, given: {}", part.function().name(), function_metadata.min_parameters, values.size());
|
dbgln_if(CSS_PARSER_DEBUG, "Required parameter at position {} is missing", argument_index);
|
||||||
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());
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,47 +1,80 @@
|
||||||
{
|
{
|
||||||
"matrix": {
|
"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": {
|
"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": {
|
"translate": {
|
||||||
"parameters": "<length-percentage>{1,2}"
|
"parameters": [
|
||||||
|
{ "type": "<length-percentage>", "required": true },
|
||||||
|
{ "type": "<length-percentage>", "required": false }
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"translateX": {
|
"translateX": {
|
||||||
"parameters": "<length-percentage>"
|
"parameters": [{ "type": "<length-percentage>", "required": true }]
|
||||||
},
|
},
|
||||||
"translateY": {
|
"translateY": {
|
||||||
"parameters": "<length-percentage>"
|
"parameters": [{ "type": "<length-percentage>", "required": true }]
|
||||||
},
|
},
|
||||||
"scale": {
|
"scale": {
|
||||||
"parameters": "<number>{1,2}"
|
"parameters": [
|
||||||
|
{ "type": "<number>", "required": true },
|
||||||
|
{ "type": "<number>", "required": false }
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"scaleX": {
|
"scaleX": {
|
||||||
"parameters": "<number>"
|
"parameters": [{ "type": "<number>", "required": true }]
|
||||||
},
|
},
|
||||||
"scaleY": {
|
"scaleY": {
|
||||||
"parameters": "<number>"
|
"parameters": [{ "type": "<number>", "required": true }]
|
||||||
},
|
},
|
||||||
"rotate": {
|
"rotate": {
|
||||||
"parameters": "<angle>"
|
"parameters": [{ "type": "<angle>", "required": true }]
|
||||||
},
|
},
|
||||||
"rotateX": {
|
"rotateX": {
|
||||||
"parameters": "<angle>"
|
"parameters": [{ "type": "<angle>", "required": true }]
|
||||||
},
|
},
|
||||||
"rotateY": {
|
"rotateY": {
|
||||||
"parameters": "<angle>"
|
"parameters": [{ "type": "<angle>", "required": true }]
|
||||||
},
|
},
|
||||||
"rotateZ": {
|
"rotateZ": {
|
||||||
"parameters": "<angle>"
|
"parameters": [{ "type": "<angle>", "required": true }]
|
||||||
},
|
},
|
||||||
"skew": {
|
"skew": {
|
||||||
"parameters": "<angle>{1,2}"
|
"parameters": [
|
||||||
|
{ "type": "<angle>", "required": true },
|
||||||
|
{ "type": "<angle>", "required": false }
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"skewX": {
|
"skewX": {
|
||||||
"parameters": "<angle>"
|
"parameters": [{ "type": "<angle>", "required": true }]
|
||||||
},
|
},
|
||||||
"skewY": {
|
"skewY": {
|
||||||
"parameters": "<angle>"
|
"parameters": [{ "type": "<angle>", "required": true }]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue