mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 20:15:17 +00:00
LibWeb/CSS: Recalculate calc() numeric type when resolving percentages
Previously, `percentage_of` would be called on the previous value, potentially changing its numeric type, yet this potential change was never reflected as the old numeric type was always used. Now, the numeric type will be re-calculated every time after the percentage is resolved. As well, VERIFY checks have been placed to uphold the requirements for the numeric types to match what the actual values are.
This commit is contained in:
parent
938ffe183e
commit
db58986e5f
Notes:
github-actions[bot]
2025-01-04 18:48:41 +00:00
Author: https://github.com/Jaycadox 🔰 Commit: https://github.com/LadybirdBrowser/ladybird/commit/db58986e5f5 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3007 Reviewed-by: https://github.com/AtkinsSJ ✅ Reviewed-by: https://github.com/LucasChollet
3 changed files with 28 additions and 4 deletions
|
@ -109,12 +109,12 @@ CalculationNode::CalculationNode(Type type, Optional<CSSNumericType> numeric_typ
|
|||
|
||||
CalculationNode::~CalculationNode() = default;
|
||||
|
||||
NonnullOwnPtr<NumericCalculationNode> NumericCalculationNode::create(NumericValue value, Optional<ValueType> percentage_resolved_type)
|
||||
static CSSNumericType numeric_type_from_calculated_style_value(CalculatedStyleValue::CalculationResult::Value const& value, Optional<ValueType> percentage_resolved_type)
|
||||
{
|
||||
// https://drafts.csswg.org/css-values-4/#determine-the-type-of-a-calculation
|
||||
// Anything else is a terminal value, whose type is determined based on its CSS type.
|
||||
// (Unless otherwise specified, the type’s associated percent hint is null.)
|
||||
auto numeric_type = value.visit(
|
||||
return value.visit(
|
||||
[](Number const&) {
|
||||
// -> <number>
|
||||
// -> <integer>
|
||||
|
@ -172,7 +172,11 @@ NonnullOwnPtr<NumericCalculationNode> NumericCalculationNode::create(NumericValu
|
|||
// result.set_percent_hint(CSSNumericType::BaseType::Percent);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
NonnullOwnPtr<NumericCalculationNode> NumericCalculationNode::create(NumericValue value, Optional<ValueType> percentage_resolved_type)
|
||||
{
|
||||
auto numeric_type = numeric_type_from_calculated_style_value(value, percentage_resolved_type);
|
||||
return adopt_own(*new (nothrow) NumericCalculationNode(move(value), numeric_type));
|
||||
}
|
||||
|
||||
|
@ -200,11 +204,13 @@ CalculatedStyleValue::CalculationResult NumericCalculationNode::resolve(Optional
|
|||
// NOTE: Depending on whether percentage_basis is set, the caller of resolve() is expecting a raw percentage or
|
||||
// resolved type.
|
||||
return percentage_basis.visit(
|
||||
[&](Empty const&) -> CalculatedStyleValue::CalculationResult {
|
||||
[&](Empty const&) {
|
||||
VERIFY(numeric_type_from_calculated_style_value(m_value, {}) == numeric_type());
|
||||
return CalculatedStyleValue::CalculationResult::from_value(m_value, resolution_context, numeric_type());
|
||||
},
|
||||
[&](auto const& value) {
|
||||
return CalculatedStyleValue::CalculationResult::from_value(value.percentage_of(m_value.get<Percentage>()), resolution_context, numeric_type());
|
||||
auto const calculated_value = value.percentage_of(m_value.get<Percentage>());
|
||||
return CalculatedStyleValue::CalculationResult::from_value(calculated_value, resolution_context, numeric_type_from_calculated_style_value(calculated_value, {}));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1730,6 +1736,11 @@ bool RemCalculationNode::equals(CalculationNode const& other) const
|
|||
|
||||
CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalculationResult::from_value(Value const& value, Optional<Length::ResolutionContext const&> context, Optional<CSSNumericType> numeric_type)
|
||||
{
|
||||
auto const expected_numeric_type = numeric_type_from_calculated_style_value(value, {});
|
||||
if (numeric_type.has_value()) {
|
||||
VERIFY(numeric_type.value() == expected_numeric_type);
|
||||
}
|
||||
|
||||
auto number = value.visit(
|
||||
[](Number const& number) { return number.value(); },
|
||||
[](Angle const& angle) { return angle.to_degrees(); },
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
PASS! (Didn't crash)
|
|
@ -0,0 +1,12 @@
|
|||
<script src="../include.js"></script>
|
||||
<style>
|
||||
div {
|
||||
transform: translateX(calc(10%))
|
||||
}
|
||||
</style>
|
||||
<div></div>
|
||||
<script>
|
||||
test(() => {
|
||||
println(`PASS! (Didn't crash)`);
|
||||
});
|
||||
</script>
|
Loading…
Add table
Reference in a new issue