mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 23:07:35 +00:00
LibWeb: Allow percentages on CSS transform scale functions
This commit is contained in:
parent
57ea3e160a
commit
c443f80137
9 changed files with 63 additions and 11 deletions
|
@ -81,6 +81,7 @@ enum class TransformFunctionParameterType {
|
||||||
Length,
|
Length,
|
||||||
LengthPercentage,
|
LengthPercentage,
|
||||||
Number,
|
Number,
|
||||||
|
NumberPercentage
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TransformFunctionParameter {
|
struct TransformFunctionParameter {
|
||||||
|
@ -183,6 +184,8 @@ TransformFunctionMetadata transform_function_metadata(TransformFunction transfor
|
||||||
parameter_type = "LengthPercentage"sv;
|
parameter_type = "LengthPercentage"sv;
|
||||||
else if (parameter_type_name == "number"sv)
|
else if (parameter_type_name == "number"sv)
|
||||||
parameter_type = "Number"sv;
|
parameter_type = "Number"sv;
|
||||||
|
else if (parameter_type_name == "number-percentage"sv)
|
||||||
|
parameter_type = "NumberPercentage"sv;
|
||||||
else
|
else
|
||||||
VERIFY_NOT_REACHED();
|
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)
|
translateX(1px) => matrix(1, 0, 0, 1, 1, 0)
|
||||||
translateY(1%) => matrix(1, 0, 0, 1, 0, 0)
|
translateY(1%) => matrix(1, 0, 0, 1, 0, 0)
|
||||||
scale(1, 2) => matrix(1, 0, 0, 2, 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(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(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)
|
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)
|
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)
|
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)",
|
"translateX(1px)",
|
||||||
"translateY(1%)",
|
"translateY(1%)",
|
||||||
"scale(1, 2)",
|
"scale(1, 2)",
|
||||||
|
"scale(100%, 200%)",
|
||||||
"scaleX(2)",
|
"scaleX(2)",
|
||||||
|
"scaleX(200%)",
|
||||||
"scaleY(2.5)",
|
"scaleY(2.5)",
|
||||||
|
"scaleY(250%)",
|
||||||
"rotate(1deg)",
|
"rotate(1deg)",
|
||||||
"rotateX(1rad)",
|
"rotateX(1rad)",
|
||||||
"rotateY(1grad)",
|
"rotateY(1grad)",
|
||||||
|
|
|
@ -2175,6 +2175,21 @@ RefPtr<StyleValue> Parser::parse_number_value(TokenStream<ComponentValue>& token
|
||||||
return nullptr;
|
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)
|
RefPtr<StyleValue> Parser::parse_identifier_value(ComponentValue const& component_value)
|
||||||
{
|
{
|
||||||
if (component_value.is(Token::Type::Ident)) {
|
if (component_value.is(Token::Type::Ident)) {
|
||||||
|
@ -5158,6 +5173,19 @@ RefPtr<StyleValue> Parser::parse_transform_value(TokenStream<ComponentValue>& to
|
||||||
}
|
}
|
||||||
break;
|
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();
|
argument_tokens.skip_whitespace();
|
||||||
|
|
|
@ -220,6 +220,7 @@ private:
|
||||||
RefPtr<StyleValue> parse_dimension_value(ComponentValue const&);
|
RefPtr<StyleValue> parse_dimension_value(ComponentValue const&);
|
||||||
RefPtr<StyleValue> parse_integer_value(TokenStream<ComponentValue>&);
|
RefPtr<StyleValue> parse_integer_value(TokenStream<ComponentValue>&);
|
||||||
RefPtr<StyleValue> parse_number_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_identifier_value(ComponentValue const&);
|
||||||
RefPtr<StyleValue> parse_color_value(ComponentValue const&);
|
RefPtr<StyleValue> parse_color_value(ComponentValue const&);
|
||||||
RefPtr<StyleValue> parse_rect_value(ComponentValue const&);
|
RefPtr<StyleValue> parse_rect_value(ComponentValue const&);
|
||||||
|
|
|
@ -422,16 +422,23 @@ Vector<CSS::Transformation> StyleProperties::transformations_for_style_value(Sty
|
||||||
return {};
|
return {};
|
||||||
auto& transformation_style_value = it->as_transformation();
|
auto& transformation_style_value = it->as_transformation();
|
||||||
auto function = transformation_style_value.transform_function();
|
auto function = transformation_style_value.transform_function();
|
||||||
|
auto function_metadata = transform_function_metadata(function);
|
||||||
Vector<TransformValue> values;
|
Vector<TransformValue> values;
|
||||||
|
size_t argument_index = 0;
|
||||||
for (auto& transformation_value : transformation_style_value.values()) {
|
for (auto& transformation_value : transformation_style_value.values()) {
|
||||||
if (transformation_value->is_calculated()) {
|
if (transformation_value->is_calculated()) {
|
||||||
auto& calculated = transformation_value->as_calculated();
|
auto& calculated = transformation_value->as_calculated();
|
||||||
if (calculated.resolves_to_length_percentage()) {
|
if (calculated.resolves_to_length_percentage()) {
|
||||||
values.append(CSS::LengthPercentage { calculated });
|
values.append(CSS::LengthPercentage { calculated });
|
||||||
} else if (calculated.resolves_to_percentage()) {
|
} 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()) {
|
} 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()) {
|
} else if (calculated.resolves_to_angle()) {
|
||||||
values.append({ calculated.resolve_angle().value() });
|
values.append({ calculated.resolve_angle().value() });
|
||||||
} else {
|
} else {
|
||||||
|
@ -440,14 +447,19 @@ Vector<CSS::Transformation> StyleProperties::transformations_for_style_value(Sty
|
||||||
} else if (transformation_value->is_length()) {
|
} else if (transformation_value->is_length()) {
|
||||||
values.append({ transformation_value->as_length().length() });
|
values.append({ transformation_value->as_length().length() });
|
||||||
} else if (transformation_value->is_percentage()) {
|
} 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()) {
|
} 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()) {
|
} else if (transformation_value->is_angle()) {
|
||||||
values.append({ transformation_value->as_angle().angle() });
|
values.append({ transformation_value->as_angle().angle() });
|
||||||
} else {
|
} else {
|
||||||
dbgln("FIXME: Unsupported value in transform! {}", transformation_value->to_string());
|
dbgln("FIXME: Unsupported value in transform! {}", transformation_value->to_string());
|
||||||
}
|
}
|
||||||
|
argument_index++;
|
||||||
}
|
}
|
||||||
transformations.empend(function, move(values));
|
transformations.empend(function, move(values));
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,11 +150,11 @@
|
||||||
"scale": {
|
"scale": {
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "<number>",
|
"type": "<number-percentage>",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "<number>",
|
"type": "<number-percentage>",
|
||||||
"required": false
|
"required": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -162,7 +162,7 @@
|
||||||
"scaleX": {
|
"scaleX": {
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "<number>",
|
"type": "<number-percentage>",
|
||||||
"required": true
|
"required": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -170,7 +170,7 @@
|
||||||
"scaleY": {
|
"scaleY": {
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "<number>",
|
"type": "<number-percentage>",
|
||||||
"required": true
|
"required": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -35,8 +35,10 @@ ErrorOr<Gfx::FloatMatrix4x4> Transformation::to_matrix(Optional<Painting::Painta
|
||||||
return value.value().to_radians();
|
return value.value().to_radians();
|
||||||
return Error::from_string_literal("Transform contains non absolute units");
|
return Error::from_string_literal("Transform contains non absolute units");
|
||||||
},
|
},
|
||||||
[](double value) -> ErrorOr<float> {
|
[&](CSS::NumberPercentage const& value) -> ErrorOr<float> {
|
||||||
return value;
|
if (value.is_percentage())
|
||||||
|
return value.percentage().as_fraction();
|
||||||
|
return value.number().value();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
namespace Web::CSS {
|
namespace Web::CSS {
|
||||||
|
|
||||||
using TransformValue = Variant<AngleOrCalculated, LengthPercentage, double>;
|
using TransformValue = Variant<AngleOrCalculated, LengthPercentage, NumberPercentage>;
|
||||||
|
|
||||||
class Transformation {
|
class Transformation {
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue