LibWeb: Allow percentages on CSS transform scale functions
This commit is contained in:
parent
57ea3e160a
commit
c443f80137
Notes:
sideshowbarker
2024-07-17 10:08:28 +09:00
Author: https://github.com/bplaat Commit: https://github.com/SerenityOS/serenity/commit/c443f80137 Pull-request: https://github.com/SerenityOS/serenity/pull/22601 Reviewed-by: https://github.com/nico
9 changed files with 63 additions and 11 deletions
|
@ -81,6 +81,7 @@ enum class TransformFunctionParameterType {
|
|||
Length,
|
||||
LengthPercentage,
|
||||
Number,
|
||||
NumberPercentage
|
||||
};
|
||||
|
||||
struct TransformFunctionParameter {
|
||||
|
@ -183,6 +184,8 @@ TransformFunctionMetadata transform_function_metadata(TransformFunction transfor
|
|||
parameter_type = "LengthPercentage"sv;
|
||||
else if (parameter_type_name == "number"sv)
|
||||
parameter_type = "Number"sv;
|
||||
else if (parameter_type_name == "number-percentage"sv)
|
||||
parameter_type = "NumberPercentage"sv;
|
||||
else
|
||||
VERIFY_NOT_REACHED();
|
||||
|
||||
|
|
|
@ -6,8 +6,11 @@ translate3d(1%, 2px, 3em) => matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7.8281
|
|||
translateX(1px) => matrix(1, 0, 0, 1, 1, 0)
|
||||
translateY(1%) => matrix(1, 0, 0, 1, 0, 0)
|
||||
scale(1, 2) => matrix(1, 0, 0, 2, 0, 0)
|
||||
scale(100%, 200%) => matrix(1, 0, 0, 2, 0, 0)
|
||||
scaleX(2) => matrix(2, 0, 0, 1, 0, 0)
|
||||
scaleX(200%) => matrix(2, 0, 0, 1, 0, 0)
|
||||
scaleY(2.5) => matrix(1, 0, 0, 2.5, 0, 0)
|
||||
scaleY(250%) => matrix(1, 0, 0, 2.5, 0, 0)
|
||||
rotate(1deg) => matrix(0.9998477101325989, 0.017452405765652657, -0.017452405765652657, 0.9998477101325989, 0, 0)
|
||||
rotateX(1rad) => matrix3d(1, 0, 0, 0, 0, 0.5403022766113281, 0.8414709568023682, 0, 0, -0.8414709568023682, 0.5403022766113281, 0, 0, 0, 0, 1)
|
||||
rotateY(1grad) => matrix3d(0.9998766183853149, 0, -0.015707317739725113, 0, 0, 1, 0, 0, 0.015707317739725113, 0, 0.9998766183853149, 0, 0, 0, 0, 1)
|
||||
|
|
|
@ -18,8 +18,11 @@
|
|||
"translateX(1px)",
|
||||
"translateY(1%)",
|
||||
"scale(1, 2)",
|
||||
"scale(100%, 200%)",
|
||||
"scaleX(2)",
|
||||
"scaleX(200%)",
|
||||
"scaleY(2.5)",
|
||||
"scaleY(250%)",
|
||||
"rotate(1deg)",
|
||||
"rotateX(1rad)",
|
||||
"rotateY(1grad)",
|
||||
|
|
|
@ -2175,6 +2175,21 @@ RefPtr<StyleValue> Parser::parse_number_value(TokenStream<ComponentValue>& token
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<StyleValue> Parser::parse_number_or_percentage_value(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
auto peek_token = tokens.peek_token();
|
||||
if (peek_token.is(Token::Type::Number)) {
|
||||
(void)tokens.next_token();
|
||||
return NumberStyleValue::create(peek_token.token().number().value());
|
||||
}
|
||||
if (peek_token.is(Token::Type::Percentage)) {
|
||||
(void)tokens.next_token();
|
||||
return PercentageStyleValue::create(Percentage(peek_token.token().percentage()));
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<StyleValue> Parser::parse_identifier_value(ComponentValue const& component_value)
|
||||
{
|
||||
if (component_value.is(Token::Type::Ident)) {
|
||||
|
@ -5158,6 +5173,19 @@ RefPtr<StyleValue> Parser::parse_transform_value(TokenStream<ComponentValue>& to
|
|||
}
|
||||
break;
|
||||
}
|
||||
case TransformFunctionParameterType::NumberPercentage: {
|
||||
if (maybe_calc_value && maybe_calc_value->resolves_to_number()) {
|
||||
values.append(maybe_calc_value.release_nonnull());
|
||||
} else {
|
||||
// FIXME: Remove this reconsume once all parsing functions are TokenStream-based.
|
||||
argument_tokens.reconsume_current_input_token();
|
||||
auto number_or_percentage = parse_number_or_percentage_value(argument_tokens);
|
||||
if (!number_or_percentage)
|
||||
return nullptr;
|
||||
values.append(number_or_percentage.release_nonnull());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
argument_tokens.skip_whitespace();
|
||||
|
|
|
@ -220,6 +220,7 @@ private:
|
|||
RefPtr<StyleValue> parse_dimension_value(ComponentValue const&);
|
||||
RefPtr<StyleValue> parse_integer_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<StyleValue> parse_number_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<StyleValue> parse_number_or_percentage_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<StyleValue> parse_identifier_value(ComponentValue const&);
|
||||
RefPtr<StyleValue> parse_color_value(ComponentValue const&);
|
||||
RefPtr<StyleValue> parse_rect_value(ComponentValue const&);
|
||||
|
|
|
@ -422,16 +422,23 @@ Vector<CSS::Transformation> StyleProperties::transformations_for_style_value(Sty
|
|||
return {};
|
||||
auto& transformation_style_value = it->as_transformation();
|
||||
auto function = transformation_style_value.transform_function();
|
||||
auto function_metadata = transform_function_metadata(function);
|
||||
Vector<TransformValue> values;
|
||||
size_t argument_index = 0;
|
||||
for (auto& transformation_value : transformation_style_value.values()) {
|
||||
if (transformation_value->is_calculated()) {
|
||||
auto& calculated = transformation_value->as_calculated();
|
||||
if (calculated.resolves_to_length_percentage()) {
|
||||
values.append(CSS::LengthPercentage { calculated });
|
||||
} else if (calculated.resolves_to_percentage()) {
|
||||
values.append({ calculated.resolve_percentage().value() });
|
||||
// FIXME: Maybe transform this for loop to always check the metadata for the correct types
|
||||
if (function_metadata.parameters[argument_index].type == TransformFunctionParameterType::NumberPercentage) {
|
||||
values.append(NumberPercentage { calculated.resolve_percentage().value() });
|
||||
} else {
|
||||
values.append(LengthPercentage { calculated.resolve_percentage().value() });
|
||||
}
|
||||
} else if (calculated.resolves_to_number()) {
|
||||
values.append({ calculated.resolve_number().value() });
|
||||
values.append({ Number(Number::Type::Number, calculated.resolve_number().value()) });
|
||||
} else if (calculated.resolves_to_angle()) {
|
||||
values.append({ calculated.resolve_angle().value() });
|
||||
} else {
|
||||
|
@ -440,14 +447,19 @@ Vector<CSS::Transformation> StyleProperties::transformations_for_style_value(Sty
|
|||
} else if (transformation_value->is_length()) {
|
||||
values.append({ transformation_value->as_length().length() });
|
||||
} else if (transformation_value->is_percentage()) {
|
||||
values.append({ transformation_value->as_percentage().percentage() });
|
||||
if (function_metadata.parameters[argument_index].type == TransformFunctionParameterType::NumberPercentage) {
|
||||
values.append(NumberPercentage { transformation_value->as_percentage().percentage() });
|
||||
} else {
|
||||
values.append(LengthPercentage { transformation_value->as_percentage().percentage() });
|
||||
}
|
||||
} else if (transformation_value->is_number()) {
|
||||
values.append({ transformation_value->as_number().number() });
|
||||
values.append({ Number(Number::Type::Number, transformation_value->as_number().number()) });
|
||||
} else if (transformation_value->is_angle()) {
|
||||
values.append({ transformation_value->as_angle().angle() });
|
||||
} else {
|
||||
dbgln("FIXME: Unsupported value in transform! {}", transformation_value->to_string());
|
||||
}
|
||||
argument_index++;
|
||||
}
|
||||
transformations.empend(function, move(values));
|
||||
}
|
||||
|
|
|
@ -150,11 +150,11 @@
|
|||
"scale": {
|
||||
"parameters": [
|
||||
{
|
||||
"type": "<number>",
|
||||
"type": "<number-percentage>",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "<number>",
|
||||
"type": "<number-percentage>",
|
||||
"required": false
|
||||
}
|
||||
]
|
||||
|
@ -162,7 +162,7 @@
|
|||
"scaleX": {
|
||||
"parameters": [
|
||||
{
|
||||
"type": "<number>",
|
||||
"type": "<number-percentage>",
|
||||
"required": true
|
||||
}
|
||||
]
|
||||
|
@ -170,7 +170,7 @@
|
|||
"scaleY": {
|
||||
"parameters": [
|
||||
{
|
||||
"type": "<number>",
|
||||
"type": "<number-percentage>",
|
||||
"required": true
|
||||
}
|
||||
]
|
||||
|
|
|
@ -35,8 +35,10 @@ ErrorOr<Gfx::FloatMatrix4x4> Transformation::to_matrix(Optional<Painting::Painta
|
|||
return value.value().to_radians();
|
||||
return Error::from_string_literal("Transform contains non absolute units");
|
||||
},
|
||||
[](double value) -> ErrorOr<float> {
|
||||
return value;
|
||||
[&](CSS::NumberPercentage const& value) -> ErrorOr<float> {
|
||||
if (value.is_percentage())
|
||||
return value.percentage().as_fraction();
|
||||
return value.number().value();
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
namespace Web::CSS {
|
||||
|
||||
using TransformValue = Variant<AngleOrCalculated, LengthPercentage, double>;
|
||||
using TransformValue = Variant<AngleOrCalculated, LengthPercentage, NumberPercentage>;
|
||||
|
||||
class Transformation {
|
||||
public:
|
||||
|
|
Loading…
Add table
Reference in a new issue