LibWeb/CSS: Migrate some call sites to non-deprecated resolve_* methods

This ensures that we clamp values for properties like padding-* to valid
ranges (non-negative in this case) if they are specified with `calc()`.

The length-related changes in this commit combined with the ones from
the previous commit fix the primary layout issue on https://lwn.net
(yes, not the first place I would have expected problems either).
This commit is contained in:
InvalidUsernameException 2025-09-05 16:22:17 +02:00 committed by Sam Atkins
commit b057bad102
Notes: github-actions[bot] 2025-09-07 14:56:24 +00:00
7 changed files with 55 additions and 34 deletions

View file

@ -100,12 +100,11 @@ Optional<Angle::Type> Angle::unit_from_name(StringView name)
Angle Angle::resolve_calculated(NonnullRefPtr<CalculatedStyleValue const> const& calculated, Layout::Node const& layout_node, Angle const& reference_value)
{
return calculated->resolve_angle_deprecated(
{
.percentage_basis = reference_value,
.length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node),
})
.value();
CalculationResolutionContext context {
.percentage_basis = reference_value,
.length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node),
};
return calculated->resolve_angle(context).value();
}
}

View file

@ -79,12 +79,11 @@ Optional<Frequency::Type> Frequency::unit_from_name(StringView name)
Frequency Frequency::resolve_calculated(NonnullRefPtr<CalculatedStyleValue const> const& calculated, Layout::Node const& layout_node, Frequency const& reference_value)
{
return calculated->resolve_frequency_deprecated(
{
.percentage_basis = reference_value,
.length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node),
})
.value();
CalculationResolutionContext context {
.percentage_basis = reference_value,
.length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node),
};
return calculated->resolve_frequency(context).value();
}
}

View file

@ -431,22 +431,16 @@ Length Length::absolutized(CSSPixelRect const& viewport_rect, FontMetrics const&
Length Length::resolve_calculated(NonnullRefPtr<CalculatedStyleValue const> const& calculated, Layout::Node const& layout_node, Length const& reference_value)
{
return calculated->resolve_length_deprecated(
{
.percentage_basis = reference_value,
.length_resolution_context = ResolutionContext::for_layout_node(layout_node),
})
.value();
CalculationResolutionContext context {
.percentage_basis = reference_value,
.length_resolution_context = ResolutionContext::for_layout_node(layout_node),
};
return calculated->resolve_length(context).value();
}
Length Length::resolve_calculated(NonnullRefPtr<CalculatedStyleValue const> const& calculated, Layout::Node const& layout_node, CSSPixels reference_value)
{
return calculated->resolve_length_deprecated(
{
.percentage_basis = make_px(reference_value),
.length_resolution_context = ResolutionContext::for_layout_node(layout_node),
})
.value();
return resolve_calculated(calculated, layout_node, make_px(reference_value));
}
}

View file

@ -90,12 +90,11 @@ Optional<Time::Type> Time::unit_from_name(StringView name)
Time Time::resolve_calculated(NonnullRefPtr<CalculatedStyleValue const> const& calculated, Layout::Node const& layout_node, Time const& reference_value)
{
return calculated->resolve_time_deprecated(
{
.percentage_basis = reference_value,
.length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node),
})
.value();
CalculationResolutionContext context {
.percentage_basis = reference_value,
.length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node),
};
return calculated->resolve_time(context).value();
}
}

View file

@ -0,0 +1,3 @@
PASS Negative padding on element #one is clamped to zero.
PASS Negative padding on element #two is clamped to zero.
PASS Negative padding on element #three is clamped to zero.

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 229 tests
215 Pass
14 Fail
217 Pass
12 Fail
Pass round(10,10) should be used-value-equivalent to 10
Pass mod(1,1) should be used-value-equivalent to 0
Pass rem(1,1) should be used-value-equivalent to 0
@ -121,8 +121,8 @@ Pass rem(10deg,6deg) should be used-value-equivalent to 4deg
Pass rem(10grad,6grad) should be used-value-equivalent to 4grad
Pass rem(10rad,6rad) should be used-value-equivalent to 4rad
Pass rem(10turn,6turn) should be used-value-equivalent to 4turn
Fail round(10%,1px) should be used-value-equivalent to 8px
Fail round(10%,5px) should be used-value-equivalent to 10px
Pass round(10%,1px) should be used-value-equivalent to 8px
Pass round(10%,5px) should be used-value-equivalent to 10px
Pass round(2rem,5px) should be used-value-equivalent to 30px
Pass round(100px,1rem) should be used-value-equivalent to 96px
Pass round(10s,6000ms) should be used-value-equivalent to 12s

View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<script src="include.js"></script>
<style>
#one { padding-left: calc(-100px); }
#two { padding-left: calc(0% - 100px); }
#three { padding-left: calc(0% - 12.5vw); }
</style>
<div id="one">This should not have padding.</div>
<div id="two">Neither should this.</div>
<div id="three">Or this.</div>
<script>
test(() => {
function assert_padding_clamped(element_id) {
const element = document.getElementById(element_id);
const computed_style = getComputedStyle(element);
const padding_left = computed_style["padding-left"];
if (padding_left === "0px") {
println(`PASS Negative padding on element #${element_id} is clamped to zero.`);
} else {
println(`FAIL Negative padding on element #${element_id} was not clamped. Expected 0px, but got ${padding_left}.`);
}
}
assert_padding_clamped("one");
assert_padding_clamped("two");
assert_padding_clamped("three");
});
</script>