LibWeb: Resolve percentages for opacity properties at parse time

This commit is contained in:
Tim Ledbetter 2025-06-18 17:44:58 +01:00 committed by Jelle Raaijmakers
parent 86c8dbbf90
commit 269d5bb40e
Notes: github-actions[bot] 2025-06-19 08:28:47 +00:00
6 changed files with 87 additions and 4 deletions

View file

@ -695,6 +695,13 @@ Parser::ParseErrorOr<NonnullRefPtr<CSSStyleValue const>> Parser::parse_css_value
if (auto parsed_value = parse_math_depth_value(tokens); parsed_value && !tokens.has_next_token())
return parsed_value.release_nonnull();
return ParseError::SyntaxError;
case PropertyID::Opacity:
case PropertyID::FillOpacity:
case PropertyID::StopOpacity:
case PropertyID::StrokeOpacity:
if (auto parsed_value = parse_opacity_value(property_id, tokens); parsed_value && !tokens.has_next_token())
return parsed_value.release_nonnull();
return ParseError::SyntaxError;
case PropertyID::Overflow:
if (auto parsed_value = parse_overflow_value(tokens); parsed_value && !tokens.has_next_token())
return parsed_value.release_nonnull();
@ -3395,6 +3402,28 @@ RefPtr<CSSStyleValue const> Parser::parse_math_depth_value(TokenStream<Component
return nullptr;
}
RefPtr<CSSStyleValue const> Parser::parse_opacity_value(PropertyID property_id, TokenStream<ComponentValue>& tokens)
{
auto value = parse_css_value_for_property(property_id, tokens);
if (!value)
return nullptr;
// Percentages map to the range [0,1] for opacity values
if (value->is_percentage())
value = NumberStyleValue::create(value->as_percentage().percentage().as_fraction());
if (value->is_calculated() && value->as_calculated().resolves_to_percentage()) {
auto maybe_percentage = value->as_calculated().resolve_percentage({});
if (maybe_percentage.has_value()) {
auto resolved_percentage = maybe_percentage->as_fraction();
CalculationContext context {};
auto calc_node = NumericCalculationNode::create(Number { Number::Type::Number, resolved_percentage }, context);
value = CalculatedStyleValue::create(move(calc_node), CSSNumericType { CSSNumericType::BaseType::Length, 1 }, context);
}
}
return value;
}
RefPtr<CSSStyleValue const> Parser::parse_overflow_value(TokenStream<ComponentValue>& tokens)
{
auto transaction = tokens.begin_transaction();