mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-28 19:59:17 +00:00
LibWeb: Resolve percentages for opacity properties at parse time
This commit is contained in:
parent
86c8dbbf90
commit
269d5bb40e
Notes:
github-actions[bot]
2025-06-19 08:28:47 +00:00
Author: https://github.com/tcl3
Commit: 269d5bb40e
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5137
Reviewed-by: https://github.com/gmta ✅
6 changed files with 87 additions and 4 deletions
|
@ -377,8 +377,6 @@ float ComputedProperties::resolve_opacity_value(CSSStyleValue const& value)
|
|||
else
|
||||
dbgln("Unable to resolve calc() as opacity (number): {}", value.to_string(SerializationMode::Normal));
|
||||
}
|
||||
} else if (value.is_percentage()) {
|
||||
unclamped_opacity = value.as_percentage().percentage().as_fraction();
|
||||
}
|
||||
|
||||
return clamp(unclamped_opacity, 0.0f, 1.0f);
|
||||
|
|
|
@ -412,6 +412,7 @@ private:
|
|||
RefPtr<CSSStyleValue const> parse_font_variant_numeric_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<CSSStyleValue const> parse_list_style_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<CSSStyleValue const> parse_math_depth_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<CSSStyleValue const> parse_opacity_value(PropertyID property_id, TokenStream<ComponentValue>&);
|
||||
RefPtr<CSSStyleValue const> parse_overflow_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<CSSStyleValue const> parse_place_content_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<CSSStyleValue const> parse_place_items_value(TokenStream<ComponentValue>&);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -138,8 +138,8 @@ ry: 'calc(2%)' -> '2%'
|
|||
ry: 'calc(2% * var(--n))' -> 'calc(2 * 2%)'
|
||||
stop-opacity: 'calc(2)' -> '2'
|
||||
stop-opacity: 'calc(2 * var(--n))' -> '4'
|
||||
stroke-opacity: 'calc(2%)' -> '2%'
|
||||
stroke-opacity: 'calc(2% * var(--n))' -> '4%'
|
||||
stroke-opacity: 'calc(2%)' -> '0.02'
|
||||
stroke-opacity: 'calc(2% * var(--n))' -> '0.04'
|
||||
stroke-width: 'calc(2px)' -> '2px'
|
||||
stroke-width: 'calc(2px * var(--n))' -> '4px'
|
||||
tab-size: 'calc(2px)' -> '2px'
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 16 tests
|
||||
|
||||
16 Pass
|
||||
Pass e.style['opacity'] = "1" should set the property value
|
||||
Pass e.style['opacity'] = "0.5" should set the property value
|
||||
Pass e.style['opacity'] = "0" should set the property value
|
||||
Pass e.style['opacity'] = "-2" should set the property value
|
||||
Pass e.style['opacity'] = "3" should set the property value
|
||||
Pass e.style['opacity'] = "-100%" should set the property value
|
||||
Pass e.style['opacity'] = "50%" should set the property value
|
||||
Pass e.style['opacity'] = "300%" should set the property value
|
||||
Pass e.style['opacity'] = "clamp(50%, 0%, 70%)" should set the property value
|
||||
Pass e.style['opacity'] = "clamp(50%, 80%, 70%)" should set the property value
|
||||
Pass e.style['opacity'] = "clamp(50%, 60%, 70%)" should set the property value
|
||||
Pass e.style['opacity'] = "min(50%, 0%)" should set the property value
|
||||
Pass e.style['opacity'] = "min(0%, 50%)" should set the property value
|
||||
Pass e.style['opacity'] = "max(50%, 0%)" should set the property value
|
||||
Pass e.style['opacity'] = "max(0%, 50%)" should set the property value
|
||||
Pass e.style['opacity'] = "min(-40%, 50%)" should set the property value
|
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Color Level 3: parsing opacity with valid values</title>
|
||||
<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org">
|
||||
<link rel="help" href="https://www.w3.org/TR/css-color-3/#opacity">
|
||||
<meta name="assert" content="opacity supports the full grammar '<alphavalue>'.">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../css/support/parsing-testcommon.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
test_valid_value("opacity", "1");
|
||||
test_valid_value("opacity", "0.5");
|
||||
test_valid_value("opacity", "0");
|
||||
test_valid_value("opacity", "-2");
|
||||
test_valid_value("opacity", "3");
|
||||
test_valid_value("opacity", "-100%", "-1");
|
||||
test_valid_value("opacity", "50%", "0.5");
|
||||
test_valid_value("opacity", "300%", "3");
|
||||
test_valid_value("opacity", "clamp(50%, 0%, 70%)", "calc(0.5)");
|
||||
test_valid_value("opacity", "clamp(50%, 80%, 70%)", "calc(0.7)");
|
||||
test_valid_value("opacity", "clamp(50%, 60%, 70%)", "calc(0.6)");
|
||||
test_valid_value("opacity", "min(50%, 0%)", "calc(0)");
|
||||
test_valid_value("opacity", "min(0%, 50%)", "calc(0)");
|
||||
test_valid_value("opacity", "max(50%, 0%)", "calc(0.5)");
|
||||
test_valid_value("opacity", "max(0%, 50%)", "calc(0.5)");
|
||||
test_valid_value("opacity", "min(-40%, 50%)", "calc(-0.4)");
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue