LibWeb/CSS: Use LengthOrAuto for clip rects

This commit is contained in:
Sam Atkins 2025-08-27 16:22:48 +01:00
parent f663c0a72d
commit 9b27aaa00c
5 changed files with 22 additions and 15 deletions

View File

@ -22,7 +22,7 @@ Clip::Clip(EdgeRect edge_rect)
Clip Clip::make_auto()
{
return Clip(Type::Auto, EdgeRect { Length::make_auto(), Length::make_auto(), Length::make_auto(), Length::make_auto() });
return Clip(Type::Auto, EdgeRect { LengthOrAuto::make_auto(), LengthOrAuto::make_auto(), LengthOrAuto::make_auto(), LengthOrAuto::make_auto() });
}
}

View File

@ -24,10 +24,10 @@ CSSPixelRect EdgeRect::resolved(Layout::Node const& layout_node, CSSPixelRect bo
// widths for <bottom>, and the same as the used value of the width plus the sum of the
// horizontal padding and border widths for <right>, such that four 'auto' values result in the
// clipping region being the same as the element's border box).
auto left = border_box.left() + (left_edge.is_auto() ? 0 : left_edge.to_px(layout_node));
auto top = border_box.top() + (top_edge.is_auto() ? 0 : top_edge.to_px(layout_node));
auto right = border_box.left() + (right_edge.is_auto() ? border_box.width() : right_edge.to_px(layout_node));
auto bottom = border_box.top() + (bottom_edge.is_auto() ? border_box.height() : bottom_edge.to_px(layout_node));
auto left = border_box.left() + (left_edge.is_auto() ? 0 : left_edge.length().to_px(layout_node));
auto top = border_box.top() + (top_edge.is_auto() ? 0 : top_edge.length().to_px(layout_node));
auto right = border_box.left() + (right_edge.is_auto() ? border_box.width() : right_edge.length().to_px(layout_node));
auto bottom = border_box.top() + (bottom_edge.is_auto() ? border_box.height() : bottom_edge.length().to_px(layout_node));
return CSSPixelRect {
left,
top,

View File

@ -16,10 +16,10 @@
namespace Web::CSS {
struct WEB_API EdgeRect {
Length top_edge;
Length right_edge;
Length bottom_edge;
Length left_edge;
LengthOrAuto top_edge;
LengthOrAuto right_edge;
LengthOrAuto bottom_edge;
LengthOrAuto left_edge;
CSSPixelRect resolved(Layout::Node const&, CSSPixelRect) const;
bool operator==(EdgeRect const&) const = default;
};

View File

@ -1217,11 +1217,18 @@ static RefPtr<StyleValue const> interpolate_value_impl(DOM::Element& element, Ca
if (from_rect.top_edge.is_auto() != to_rect.top_edge.is_auto() || from_rect.right_edge.is_auto() != to_rect.right_edge.is_auto() || from_rect.bottom_edge.is_auto() != to_rect.bottom_edge.is_auto() || from_rect.left_edge.is_auto() != to_rect.left_edge.is_auto())
return {};
auto interpolate_length_or_auto = [](LengthOrAuto const& from, LengthOrAuto const& to, float delta) {
if (from.is_auto() && to.is_auto())
return LengthOrAuto::make_auto();
// FIXME: Actually handle the units not matching.
return LengthOrAuto { Length { interpolate_raw(from.length().raw_value(), to.length().raw_value(), delta), from.length().type() } };
};
return RectStyleValue::create({
Length(interpolate_raw(from_rect.top_edge.raw_value(), to_rect.top_edge.raw_value(), delta), from_rect.top_edge.type()),
Length(interpolate_raw(from_rect.right_edge.raw_value(), to_rect.right_edge.raw_value(), delta), from_rect.right_edge.type()),
Length(interpolate_raw(from_rect.bottom_edge.raw_value(), to_rect.bottom_edge.raw_value(), delta), from_rect.bottom_edge.type()),
Length(interpolate_raw(from_rect.left_edge.raw_value(), to_rect.left_edge.raw_value(), delta), from_rect.left_edge.type()),
interpolate_length_or_auto(from_rect.top_edge, to_rect.top_edge, delta),
interpolate_length_or_auto(from_rect.right_edge, to_rect.right_edge, delta),
interpolate_length_or_auto(from_rect.bottom_edge, to_rect.bottom_edge, delta),
interpolate_length_or_auto(from_rect.left_edge, to_rect.left_edge, delta),
});
}
case StyleValue::Type::Transformation:

View File

@ -1351,7 +1351,7 @@ RefPtr<StyleValue const> Parser::parse_rect_value(TokenStream<ComponentValue>& t
auto context_guard = push_temporary_value_parsing_context(FunctionContext { "rect"sv });
Vector<Length, 4> params;
Vector<LengthOrAuto, 4> params;
auto argument_tokens = TokenStream { function_token.function().value };
enum class CommaRequirement {
@ -1379,7 +1379,7 @@ RefPtr<StyleValue const> Parser::parse_rect_value(TokenStream<ComponentValue>& t
// Negative lengths are permitted.
if (argument_tokens.next_token().is_ident("auto"sv)) {
(void)argument_tokens.consume_a_token(); // `auto`
params.append(Length::make_auto());
params.append(LengthOrAuto::make_auto());
} else {
auto maybe_length = parse_length(argument_tokens);
if (!maybe_length.has_value())