diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 85346ecf08..9fbde739a3 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -8770,6 +8770,7 @@ public: virtual ErrorOr to_string() const override { VERIFY_NOT_REACHED(); } virtual Optional resolved_type() const override { VERIFY_NOT_REACHED(); } + virtual Optional determine_type(Web::CSS::PropertyID) const override { VERIFY_NOT_REACHED(); } virtual bool contains_percentage() const override { VERIFY_NOT_REACHED(); } virtual CalculatedStyleValue::CalculationResult resolve(Optional, CalculatedStyleValue::PercentageBasis const&) const override { VERIFY_NOT_REACHED(); } diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp index a896230e63..e97129bf85 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp @@ -9,6 +9,7 @@ #include "CalculatedStyleValue.h" #include +#include namespace Web::CSS { @@ -43,6 +44,27 @@ static double resolve_value(CalculatedStyleValue::CalculationResult::Value value [](Time const& time) { return time.to_seconds(); }); }; +static Optional add_the_types(Vector> const& nodes, PropertyID property_id) +{ + Optional left_type; + for (auto const& value : nodes) { + auto right_type = value->determine_type(property_id); + if (!right_type.has_value()) + return {}; + + if (left_type.has_value()) { + left_type = left_type->added_to(right_type.value()); + } else { + left_type = right_type; + } + + if (!left_type.has_value()) + return {}; + } + + return left_type; +} + static CalculatedStyleValue::CalculationResult to_resolved_type(CalculatedStyleValue::ResolvedType type, double value) { switch (type) { @@ -101,6 +123,59 @@ Optional NumericCalculationNode::resolved_ty [](Time const&) { return CalculatedStyleValue::ResolvedType::Time; }); } +// https://www.w3.org/TR/css-values-4/#determine-the-type-of-a-calculation +Optional NumericCalculationNode::determine_type(PropertyID property_id) const +{ + // Anything else is a terminal value, whose type is determined based on its CSS type: + return m_value.visit( + [](Number const&) { + // -> + // -> + // the type is «[ ]» (empty map) + return CSSNumericType {}; + }, + [](Length const&) { + // -> + // the type is «[ "length" → 1 ]» + return CSSNumericType { CSSNumericType::BaseType::Length, 1 }; + }, + [](Angle const&) { + // -> + // the type is «[ "angle" → 1 ]» + return CSSNumericType { CSSNumericType::BaseType::Angle, 1 }; + }, + [](Time const&) { + // ->