diff --git a/Libraries/LibWeb/CSS/ComputedProperties.cpp b/Libraries/LibWeb/CSS/ComputedProperties.cpp index 2f8d3868d3f..c3933632214 100644 --- a/Libraries/LibWeb/CSS/ComputedProperties.cpp +++ b/Libraries/LibWeb/CSS/ComputedProperties.cpp @@ -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); diff --git a/Libraries/LibWeb/CSS/Parser/Parser.h b/Libraries/LibWeb/CSS/Parser/Parser.h index bcf32a00c8d..d1354433537 100644 --- a/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Libraries/LibWeb/CSS/Parser/Parser.h @@ -412,6 +412,7 @@ private: RefPtr parse_font_variant_numeric_value(TokenStream&); RefPtr parse_list_style_value(TokenStream&); RefPtr parse_math_depth_value(TokenStream&); + RefPtr parse_opacity_value(PropertyID property_id, TokenStream&); RefPtr parse_overflow_value(TokenStream&); RefPtr parse_place_content_value(TokenStream&); RefPtr parse_place_items_value(TokenStream&); diff --git a/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp b/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp index 7cce668cc9b..4370c142b50 100644 --- a/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp @@ -695,6 +695,13 @@ Parser::ParseErrorOr> 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 Parser::parse_math_depth_value(TokenStream Parser::parse_opacity_value(PropertyID property_id, TokenStream& 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 Parser::parse_overflow_value(TokenStream& tokens) { auto transaction = tokens.begin_transaction(); diff --git a/Tests/LibWeb/Text/expected/css/calc-coverage.txt b/Tests/LibWeb/Text/expected/css/calc-coverage.txt index 4057ce572b5..e40c999b9ed 100644 --- a/Tests/LibWeb/Text/expected/css/calc-coverage.txt +++ b/Tests/LibWeb/Text/expected/css/calc-coverage.txt @@ -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' diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-color/parsing/opacity-valid.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-color/parsing/opacity-valid.txt new file mode 100644 index 00000000000..db9a3732987 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-color/parsing/opacity-valid.txt @@ -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 \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-color/parsing/opacity-valid.html b/Tests/LibWeb/Text/input/wpt-import/css/css-color/parsing/opacity-valid.html new file mode 100644 index 00000000000..fe7d9b6da76 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-color/parsing/opacity-valid.html @@ -0,0 +1,34 @@ + + + + +CSS Color Level 3: parsing opacity with valid values + + + + + + + + + + +