From 1882a2e19bda2c59bb5b4843e638be41b96a95d7 Mon Sep 17 00:00:00 2001 From: Milo van der Tier Date: Fri, 29 Nov 2024 16:41:40 +0100 Subject: [PATCH] LibWeb/CSS: Pass Length::ResolutionContext to resolve_integer The length resolution context might be needed even when resolving an integer value, since it might contain a sign() function with length values inside. This fixes a WPT subtest. --- Libraries/LibWeb/CSS/CalculatedOr.cpp | 12 ++++---- Libraries/LibWeb/CSS/CalculatedOr.h | 2 +- Libraries/LibWeb/CSS/MediaQuery.cpp | 15 +++++----- Libraries/LibWeb/CSS/Parser/MediaParsing.cpp | 3 +- .../LibWeb/CSS/StyleValues/CSSMathValue.cpp | 30 +++++++++++++++++++ .../LibWeb/CSS/StyleValues/CSSMathValue.h | 6 +++- .../mq-calc-sign-function-006.html | 24 +++++++++++++++ 7 files changed, 75 insertions(+), 17 deletions(-) create mode 100644 Tests/LibWeb/Ref/input/wpt-import/css/mediaqueries/mq-calc-sign-function-006.html diff --git a/Libraries/LibWeb/CSS/CalculatedOr.cpp b/Libraries/LibWeb/CSS/CalculatedOr.cpp index b191c41f7ad..43fe8864311 100644 --- a/Libraries/LibWeb/CSS/CalculatedOr.cpp +++ b/Libraries/LibWeb/CSS/CalculatedOr.cpp @@ -47,15 +47,15 @@ NonnullRefPtr FrequencyOrCalculated::create_style_value() const return FrequencyStyleValue::create(value()); } -i64 IntegerOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const&) const +i64 IntegerOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const& layout_node) const { - return calculated->resolve_integer().value(); + return calculated->resolve_integer(layout_node).value(); } -i64 IntegerOrCalculated::resolved() const +i64 IntegerOrCalculated::resolved(Length::ResolutionContext const& context) const { if (is_calculated()) - return calculated()->resolve_integer().value(); + return calculated()->resolve_integer(context).value(); return value(); } @@ -81,9 +81,9 @@ NonnullRefPtr LengthOrCalculated::create_style_value() const return LengthStyleValue::create(value()); } -double NumberOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const&) const +double NumberOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const& layout_node) const { - return calculated->resolve_number().value(); + return calculated->resolve_number(layout_node).value(); } NonnullRefPtr NumberOrCalculated::create_style_value() const diff --git a/Libraries/LibWeb/CSS/CalculatedOr.h b/Libraries/LibWeb/CSS/CalculatedOr.h index 4efbc949e9e..15703f0f2a7 100644 --- a/Libraries/LibWeb/CSS/CalculatedOr.h +++ b/Libraries/LibWeb/CSS/CalculatedOr.h @@ -119,7 +119,7 @@ class IntegerOrCalculated : public CalculatedOr { public: using CalculatedOr::CalculatedOr; - [[nodiscard]] i64 resolved() const; + [[nodiscard]] i64 resolved(Length::ResolutionContext const&) const; private: virtual i64 resolve_calculated(NonnullRefPtr const&, Layout::Node const&) const override; diff --git a/Libraries/LibWeb/CSS/MediaQuery.cpp b/Libraries/LibWeb/CSS/MediaQuery.cpp index 5dffd5934eb..3270fdc596f 100644 --- a/Libraries/LibWeb/CSS/MediaQuery.cpp +++ b/Libraries/LibWeb/CSS/MediaQuery.cpp @@ -90,12 +90,12 @@ bool MediaFeature::evaluate(HTML::Window const& window) const return false; auto queried_value = maybe_queried_value.release_value(); + auto resolution_context = Length::ResolutionContext::for_window(window); switch (m_type) { case Type::IsTrue: if (queried_value.is_integer()) - return queried_value.integer().resolved() != 0; + return queried_value.integer().resolved(resolution_context) != 0; if (queried_value.is_length()) { - auto resolution_context = Length::ResolutionContext::for_window(window); auto length = queried_value.length().resolved(resolution_context); return length.raw_value() != 0; } @@ -149,17 +149,18 @@ bool MediaFeature::compare(HTML::Window const& window, MediaFeatureValue left, C } if (left.is_integer()) { + auto resolution_context = Length::ResolutionContext::for_window(window); switch (comparison) { case Comparison::Equal: - return left.integer().resolved() == right.integer().resolved(); + return left.integer().resolved(resolution_context) == right.integer().resolved(resolution_context); case Comparison::LessThan: - return left.integer().resolved() < right.integer().resolved(); + return left.integer().resolved(resolution_context) < right.integer().resolved(resolution_context); case Comparison::LessThanOrEqual: - return left.integer().resolved() <= right.integer().resolved(); + return left.integer().resolved(resolution_context) <= right.integer().resolved(resolution_context); case Comparison::GreaterThan: - return left.integer().resolved() > right.integer().resolved(); + return left.integer().resolved(resolution_context) > right.integer().resolved(resolution_context); case Comparison::GreaterThanOrEqual: - return left.integer().resolved() >= right.integer().resolved(); + return left.integer().resolved(resolution_context) >= right.integer().resolved(resolution_context); } VERIFY_NOT_REACHED(); } diff --git a/Libraries/LibWeb/CSS/Parser/MediaParsing.cpp b/Libraries/LibWeb/CSS/Parser/MediaParsing.cpp index cf15cf20095..713b16c400a 100644 --- a/Libraries/LibWeb/CSS/Parser/MediaParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/MediaParsing.cpp @@ -569,8 +569,7 @@ Optional Parser::parse_media_feature_value(MediaFeatureID med auto transaction = tokens.begin_transaction(); tokens.discard_whitespace(); if (auto integer = parse_integer(tokens); integer.has_value()) { - auto integer_value = integer.value().resolved(); - if (integer_value == 0 || integer_value == 1) { + if (integer.value().is_calculated() || integer->value() == 0 || integer->value() == 1) { transaction.commit(); return MediaFeatureValue(integer.release_value()); } diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSMathValue.cpp b/Libraries/LibWeb/CSS/StyleValues/CSSMathValue.cpp index e79b075c2b0..4c89928381d 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSMathValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/CSSMathValue.cpp @@ -2797,19 +2797,49 @@ Optional