mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-02 14:19:48 +00:00
LibWeb: Make transform: scale(calc(..))
work
The `transform` property supports transform functions that sometimes need their `calc(percentage)` values to be converted to a number instead of a length. Currently this only applies to the `scale*` family of functions, which are marked as such in `TransformFunctions.json`. We were not consistently applying the `NumberPercentage` type to these functions though, and in addition, any `NumberPercentage` value would not consider calculated values.
This commit is contained in:
parent
202cbe7df6
commit
545d151948
Notes:
github-actions[bot]
2025-03-25 19:54:42 +00:00
Author: https://github.com/gmta
Commit: 545d151948
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4088
Reviewed-by: https://github.com/AtkinsSJ ✅
5 changed files with 26 additions and 10 deletions
|
@ -3313,6 +3313,12 @@ RefPtr<CSSStyleValue> Parser::parse_calculated_value(ComponentValue const& compo
|
||||||
"conic-gradient"sv, "repeating-conic-gradient"sv)) {
|
"conic-gradient"sv, "repeating-conic-gradient"sv)) {
|
||||||
return CalculationContext { .percentages_resolve_as = ValueType::Length };
|
return CalculationContext { .percentages_resolve_as = ValueType::Length };
|
||||||
}
|
}
|
||||||
|
// https://drafts.csswg.org/css-transforms-2/#transform-functions
|
||||||
|
// The scale family of functions treats percentages as numbers.
|
||||||
|
if (function.name.is_one_of_ignoring_ascii_case(
|
||||||
|
"scale"sv, "scalex"sv, "scaley"sv, "scalez"sv, "scale3d"sv)) {
|
||||||
|
return CalculationContext { .percentages_resolve_as = ValueType::Number };
|
||||||
|
}
|
||||||
// FIXME: Add other functions that provide a context for resolving values
|
// FIXME: Add other functions that provide a context for resolving values
|
||||||
return {};
|
return {};
|
||||||
});
|
});
|
||||||
|
|
|
@ -24,17 +24,15 @@ Transformation TransformationStyleValue::to_transformation() const
|
||||||
Vector<TransformValue> values;
|
Vector<TransformValue> values;
|
||||||
size_t argument_index = 0;
|
size_t argument_index = 0;
|
||||||
for (auto& transformation_value : m_properties.values) {
|
for (auto& transformation_value : m_properties.values) {
|
||||||
|
auto const function_type = function_metadata.parameters[argument_index].type;
|
||||||
|
|
||||||
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 (function_type == TransformFunctionParameterType::NumberPercentage
|
||||||
values.append(LengthPercentage { calculated });
|
&& (calculated.resolves_to_number() || calculated.resolves_to_percentage())) {
|
||||||
} else if (calculated.resolves_to_percentage()) {
|
|
||||||
// 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 });
|
values.append(NumberPercentage { calculated });
|
||||||
} else {
|
} else if (calculated.resolves_to_length_percentage()) {
|
||||||
values.append(LengthPercentage { calculated });
|
values.append(LengthPercentage { calculated });
|
||||||
}
|
|
||||||
} else if (calculated.resolves_to_number()) {
|
} else if (calculated.resolves_to_number()) {
|
||||||
values.append(NumberPercentage { calculated });
|
values.append(NumberPercentage { calculated });
|
||||||
} else if (calculated.resolves_to_angle()) {
|
} else if (calculated.resolves_to_angle()) {
|
||||||
|
@ -45,7 +43,7 @@ Transformation TransformationStyleValue::to_transformation() const
|
||||||
} 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()) {
|
||||||
if (function_metadata.parameters[argument_index].type == TransformFunctionParameterType::NumberPercentage) {
|
if (function_type == TransformFunctionParameterType::NumberPercentage) {
|
||||||
values.append(NumberPercentage { transformation_value->as_percentage().percentage() });
|
values.append(NumberPercentage { transformation_value->as_percentage().percentage() });
|
||||||
} else {
|
} else {
|
||||||
values.append(LengthPercentage { transformation_value->as_percentage().percentage() });
|
values.append(LengthPercentage { transformation_value->as_percentage().percentage() });
|
||||||
|
|
|
@ -46,7 +46,15 @@ ErrorOr<Gfx::FloatMatrix4x4> Transformation::to_matrix(Optional<Painting::Painta
|
||||||
[&](CSS::NumberPercentage const& value) -> ErrorOr<float> {
|
[&](CSS::NumberPercentage const& value) -> ErrorOr<float> {
|
||||||
if (value.is_percentage())
|
if (value.is_percentage())
|
||||||
return value.percentage().as_fraction();
|
return value.percentage().as_fraction();
|
||||||
|
if (value.is_number())
|
||||||
return value.number().value();
|
return value.number().value();
|
||||||
|
if (value.is_calculated()) {
|
||||||
|
if (value.calculated()->resolves_to_number())
|
||||||
|
return value.calculated()->resolve_number(context).value();
|
||||||
|
if (value.calculated()->resolves_to_percentage())
|
||||||
|
return value.calculated()->resolve_percentage(context)->as_fraction();
|
||||||
|
}
|
||||||
|
return Error::from_string_literal("Transform contains non absolute units");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ 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)
|
scale(100%, 200%) => matrix(1, 0, 0, 2, 0, 0)
|
||||||
|
scale(calc(1 / 2)) => matrix(0.5, 0, 0, 0.5, 0, 0)
|
||||||
|
scale(calc(50% + 25%)) => matrix(0.75, 0, 0, 0.75, 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)
|
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)
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
"translateY(1%)",
|
"translateY(1%)",
|
||||||
"scale(1, 2)",
|
"scale(1, 2)",
|
||||||
"scale(100%, 200%)",
|
"scale(100%, 200%)",
|
||||||
|
"scale(calc(1 / 2))",
|
||||||
|
"scale(calc(50% + 25%))",
|
||||||
"scaleX(2)",
|
"scaleX(2)",
|
||||||
"scaleX(200%)",
|
"scaleX(200%)",
|
||||||
"scaleY(2.5)",
|
"scaleY(2.5)",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue