diff --git a/Libraries/LibWeb/CSS/NumericType.h b/Libraries/LibWeb/CSS/NumericType.h index c69752214d1..a5c826fb4b0 100644 --- a/Libraries/LibWeb/CSS/NumericType.h +++ b/Libraries/LibWeb/CSS/NumericType.h @@ -106,6 +106,7 @@ public: bool operator==(NumericType const& other) const = default; String dump() const; + Optional entry_with_value_1_while_all_others_are_0() const; private: bool contains_all_the_non_zero_entries_of_other_with_the_same_value(NumericType const& other) const; @@ -116,7 +117,6 @@ private: }; void copy_all_entries_from(NumericType const& other, SkipIfAlreadyPresent); - Optional entry_with_value_1_while_all_others_are_0() const; bool matches_dimension(BaseType, Optional percentages_resolve_as) const; bool matches_dimension_percentage(BaseType, Optional percentages_resolve_as) const; diff --git a/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp index 67354c144bd..9769a29fd84 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp @@ -2877,7 +2877,46 @@ ValueComparingNonnullRefPtr CalculatedStyleValue::absolutized( .root_font_metrics = root_font_metrics }; - return CalculatedStyleValue::create(simplify_a_calculation_tree(m_calculation, m_context, { .length_resolution_context = length_resolution_context }), m_resolved_type, m_context); + auto simplified_calculation_tree = simplify_a_calculation_tree(m_calculation, m_context, { .length_resolution_context = length_resolution_context }); + + auto const simplified_percentage_dimension_mix = [&]() -> Optional> { + // NOTE: A percentage dimension mix is a SumCalculationNode with two NumericCalculationNode children which have + // matching base types - only the first of which has a percent hint. + if (simplified_calculation_tree->type() != CalculationNode::Type::Sum) + return {}; + + auto const& sum_node = as(*simplified_calculation_tree); + + if (sum_node.children()[0]->type() != CalculationNode::Type::Numeric || sum_node.children()[1]->type() != CalculationNode::Type::Numeric) + return {}; + + auto const& first_node = as(*sum_node.children()[0]); + auto const& second_node = as(*sum_node.children()[1]); + + auto first_base_type = first_node.numeric_type()->entry_with_value_1_while_all_others_are_0(); + auto second_base_type = second_node.numeric_type()->entry_with_value_1_while_all_others_are_0(); + + if (!first_base_type.has_value() || first_base_type != second_base_type) + return {}; + + if (!first_node.numeric_type()->percent_hint().has_value() || second_node.numeric_type()->percent_hint().has_value()) + return {}; + + auto dimension_component = try_get_value_with_canonical_unit(second_node, m_context, {}); + + // https://drafts.csswg.org/css-values-4/#combine-mixed + // The computed value of a percentage-dimension mix is defined as + // - a computed percentage if the dimension component is zero + if (dimension_component->value() == 0) + return PercentageStyleValue::create(first_node.value().get()); + + return {}; + }(); + + if (simplified_percentage_dimension_mix.has_value()) + return simplified_percentage_dimension_mix.value(); + + return CalculatedStyleValue::create(simplified_calculation_tree, m_resolved_type, m_context); } bool CalculatedStyleValue::equals(StyleValue const& other) const diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/parsing/flex-basis-computed.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/parsing/flex-basis-computed.txt index 107471dd4b0..ca478096933 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/parsing/flex-basis-computed.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/parsing/flex-basis-computed.txt @@ -2,8 +2,7 @@ Harness status: OK Found 12 tests -11 Pass -1 Fail +12 Pass Pass Property flex-basis value '1px' Pass Property flex-basis value '400%' Pass Property flex-basis value 'auto' @@ -15,4 +14,4 @@ Pass Property flex-basis value 'calc(10px + 0.5em)' Pass Property flex-basis value 'calc(10px - 0.5em)' Pass Property flex-basis value 'calc(10%)' Pass Property flex-basis value 'calc(0% + 10px)' -Fail Property flex-basis value 'calc(10% + 0px)' \ No newline at end of file +Pass Property flex-basis value 'calc(10% + 0px)' \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-text-decor/animations/text-underline-offset-interpolation.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-text-decor/animations/text-underline-offset-interpolation.txt index 7bf5cdd7f80..dde73508656 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-text-decor/animations/text-underline-offset-interpolation.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-text-decor/animations/text-underline-offset-interpolation.txt @@ -2,8 +2,7 @@ Harness status: OK Found 320 tests -300 Pass -20 Fail +320 Pass Pass CSS Transitions: property from [15px] to [0px] at (0) should be [15px] Pass CSS Transitions: property from [15px] to [0px] at (0.3) should be [10.5px] Pass CSS Transitions: property from [15px] to [0px] at (0.6) should be [6px] @@ -260,38 +259,38 @@ Pass Web Animations: property from [100%] to [0px] at (0 Pass Web Animations: property from [100%] to [0px] at (0.3) should be [70%] Pass Web Animations: property from [100%] to [0px] at (0.6) should be [40%] Pass Web Animations: property from [100%] to [0px] at (1) should be [0%] -Fail CSS Transitions: property from [100%] to [32px] at (0) should be [calc(100% + 0px)] +Pass CSS Transitions: property from [100%] to [32px] at (0) should be [calc(100% + 0px)] Pass CSS Transitions: property from [100%] to [32px] at (0.3) should be [calc(70% + 9.6px)] Pass CSS Transitions: property from [100%] to [32px] at (0.6) should be [calc(40% + 19.2px)] Pass CSS Transitions: property from [100%] to [32px] at (1) should be [calc(0% + 32px)] -Fail CSS Transitions with transition: all: property from [100%] to [32px] at (0) should be [calc(100% + 0px)] +Pass CSS Transitions with transition: all: property from [100%] to [32px] at (0) should be [calc(100% + 0px)] Pass CSS Transitions with transition: all: property from [100%] to [32px] at (0.3) should be [calc(70% + 9.6px)] Pass CSS Transitions with transition: all: property from [100%] to [32px] at (0.6) should be [calc(40% + 19.2px)] Pass CSS Transitions with transition: all: property from [100%] to [32px] at (1) should be [calc(0% + 32px)] -Fail CSS Animations: property from [100%] to [32px] at (0) should be [calc(100% + 0px)] +Pass CSS Animations: property from [100%] to [32px] at (0) should be [calc(100% + 0px)] Pass CSS Animations: property from [100%] to [32px] at (0.3) should be [calc(70% + 9.6px)] Pass CSS Animations: property from [100%] to [32px] at (0.6) should be [calc(40% + 19.2px)] Pass CSS Animations: property from [100%] to [32px] at (1) should be [calc(0% + 32px)] -Fail Web Animations: property from [100%] to [32px] at (0) should be [calc(100% + 0px)] +Pass Web Animations: property from [100%] to [32px] at (0) should be [calc(100% + 0px)] Pass Web Animations: property from [100%] to [32px] at (0.3) should be [calc(70% + 9.6px)] Pass Web Animations: property from [100%] to [32px] at (0.6) should be [calc(40% + 19.2px)] Pass Web Animations: property from [100%] to [32px] at (1) should be [calc(0% + 32px)] -Fail CSS Transitions: property from [100%] to [0em] at (0) should be [calc(100% + 0em)] -Fail CSS Transitions: property from [100%] to [0em] at (0.3) should be [calc(70% + 0em)] -Fail CSS Transitions: property from [100%] to [0em] at (0.6) should be [calc(40% + 0em)] -Fail CSS Transitions: property from [100%] to [0em] at (1) should be [calc(0% + 0em)] -Fail CSS Transitions with transition: all: property from [100%] to [0em] at (0) should be [calc(100% + 0em)] -Fail CSS Transitions with transition: all: property from [100%] to [0em] at (0.3) should be [calc(70% + 0em)] -Fail CSS Transitions with transition: all: property from [100%] to [0em] at (0.6) should be [calc(40% + 0em)] -Fail CSS Transitions with transition: all: property from [100%] to [0em] at (1) should be [calc(0% + 0em)] -Fail CSS Animations: property from [100%] to [0em] at (0) should be [calc(100% + 0em)] -Fail CSS Animations: property from [100%] to [0em] at (0.3) should be [calc(70% + 0em)] -Fail CSS Animations: property from [100%] to [0em] at (0.6) should be [calc(40% + 0em)] -Fail CSS Animations: property from [100%] to [0em] at (1) should be [calc(0% + 0em)] -Fail Web Animations: property from [100%] to [0em] at (0) should be [calc(100% + 0em)] -Fail Web Animations: property from [100%] to [0em] at (0.3) should be [calc(70% + 0em)] -Fail Web Animations: property from [100%] to [0em] at (0.6) should be [calc(40% + 0em)] -Fail Web Animations: property from [100%] to [0em] at (1) should be [calc(0% + 0em)] +Pass CSS Transitions: property from [100%] to [0em] at (0) should be [calc(100% + 0em)] +Pass CSS Transitions: property from [100%] to [0em] at (0.3) should be [calc(70% + 0em)] +Pass CSS Transitions: property from [100%] to [0em] at (0.6) should be [calc(40% + 0em)] +Pass CSS Transitions: property from [100%] to [0em] at (1) should be [calc(0% + 0em)] +Pass CSS Transitions with transition: all: property from [100%] to [0em] at (0) should be [calc(100% + 0em)] +Pass CSS Transitions with transition: all: property from [100%] to [0em] at (0.3) should be [calc(70% + 0em)] +Pass CSS Transitions with transition: all: property from [100%] to [0em] at (0.6) should be [calc(40% + 0em)] +Pass CSS Transitions with transition: all: property from [100%] to [0em] at (1) should be [calc(0% + 0em)] +Pass CSS Animations: property from [100%] to [0em] at (0) should be [calc(100% + 0em)] +Pass CSS Animations: property from [100%] to [0em] at (0.3) should be [calc(70% + 0em)] +Pass CSS Animations: property from [100%] to [0em] at (0.6) should be [calc(40% + 0em)] +Pass CSS Animations: property from [100%] to [0em] at (1) should be [calc(0% + 0em)] +Pass Web Animations: property from [100%] to [0em] at (0) should be [calc(100% + 0em)] +Pass Web Animations: property from [100%] to [0em] at (0.3) should be [calc(70% + 0em)] +Pass Web Animations: property from [100%] to [0em] at (0.6) should be [calc(40% + 0em)] +Pass Web Animations: property from [100%] to [0em] at (1) should be [calc(0% + 0em)] Pass CSS Transitions: property from [100%] to [2em] at (0) should be [100%] Pass CSS Transitions: property from [100%] to [2em] at (0.3) should be [calc(70% + 9.6px)] Pass CSS Transitions: property from [100%] to [2em] at (0.6) should be [calc(40% + 19.2px)] diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-text-decor/text-underline-offset-computed.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-text-decor/text-underline-offset-computed.txt index 0bec500b364..320861d7786 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-text-decor/text-underline-offset-computed.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-text-decor/text-underline-offset-computed.txt @@ -2,17 +2,16 @@ Harness status: OK Found 15 tests -13 Pass -2 Fail +15 Pass Pass Property text-underline-offset value 'auto' Pass Property text-underline-offset value 'calc(10px - 8px)' Pass Property text-underline-offset value '32px' Pass Property text-underline-offset value '2em' Pass Property text-underline-offset value '200%' Pass Property text-underline-offset value 'calc(2em - 0px)' -Fail Property text-underline-offset value 'calc(200% - 0px)' +Pass Property text-underline-offset value 'calc(200% - 0px)' Pass Property text-underline-offset value 'calc(0.5em - 0px)' -Fail Property text-underline-offset value 'calc(50% - 0px)' +Pass Property text-underline-offset value 'calc(50% - 0px)' Pass Property text-underline-offset value 'calc(2em - 8px)' Pass Property text-underline-offset value 'calc(2em - 0.5em)' Pass Property text-underline-offset value 'calc(2em - 50%)'