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.
This commit is contained in:
parent
8bec80ac47
commit
1882a2e19b
Notes:
github-actions[bot]
2024-12-04 12:38:56 +00:00
Author: https://github.com/milotier Commit: https://github.com/LadybirdBrowser/ladybird/commit/1882a2e19bd Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2640 Reviewed-by: https://github.com/AtkinsSJ ✅
7 changed files with 75 additions and 17 deletions
|
@ -47,15 +47,15 @@ NonnullRefPtr<CSSStyleValue> FrequencyOrCalculated::create_style_value() const
|
|||
return FrequencyStyleValue::create(value());
|
||||
}
|
||||
|
||||
i64 IntegerOrCalculated::resolve_calculated(NonnullRefPtr<CSSMathValue> const& calculated, Layout::Node const&) const
|
||||
i64 IntegerOrCalculated::resolve_calculated(NonnullRefPtr<CSSMathValue> 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<CSSStyleValue> LengthOrCalculated::create_style_value() const
|
|||
return LengthStyleValue::create(value());
|
||||
}
|
||||
|
||||
double NumberOrCalculated::resolve_calculated(NonnullRefPtr<CSSMathValue> const& calculated, Layout::Node const&) const
|
||||
double NumberOrCalculated::resolve_calculated(NonnullRefPtr<CSSMathValue> const& calculated, Layout::Node const& layout_node) const
|
||||
{
|
||||
return calculated->resolve_number().value();
|
||||
return calculated->resolve_number(layout_node).value();
|
||||
}
|
||||
|
||||
NonnullRefPtr<CSSStyleValue> NumberOrCalculated::create_style_value() const
|
||||
|
|
|
@ -119,7 +119,7 @@ class IntegerOrCalculated : public CalculatedOr<i64> {
|
|||
public:
|
||||
using CalculatedOr<i64>::CalculatedOr;
|
||||
|
||||
[[nodiscard]] i64 resolved() const;
|
||||
[[nodiscard]] i64 resolved(Length::ResolutionContext const&) const;
|
||||
|
||||
private:
|
||||
virtual i64 resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -569,8 +569,7 @@ Optional<MediaFeatureValue> 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());
|
||||
}
|
||||
|
|
|
@ -2797,19 +2797,49 @@ Optional<Time> CSSMathValue::resolve_time_percentage(Time const& percentage_basi
|
|||
Optional<double> CSSMathValue::resolve_number() const
|
||||
{
|
||||
auto result = m_calculation->resolve({}, {});
|
||||
|
||||
if (result.value().has<Number>())
|
||||
return result.value().get<Number>().value();
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<double> CSSMathValue::resolve_number(Length::ResolutionContext const& context) const
|
||||
{
|
||||
auto result = m_calculation->resolve(context, {});
|
||||
|
||||
if (result.value().has<Number>())
|
||||
return result.value().get<Number>().value();
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<double> CSSMathValue::resolve_number(Layout::Node const& layout_node) const
|
||||
{
|
||||
return resolve_number(Length::ResolutionContext::for_layout_node(layout_node));
|
||||
}
|
||||
|
||||
Optional<i64> CSSMathValue::resolve_integer() const
|
||||
{
|
||||
auto result = m_calculation->resolve({}, {});
|
||||
|
||||
if (result.value().has<Number>())
|
||||
return result.value().get<Number>().integer_value();
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<i64> CSSMathValue::resolve_integer(Length::ResolutionContext const& context) const
|
||||
{
|
||||
auto result = m_calculation->resolve(context, {});
|
||||
|
||||
if (result.value().has<Number>())
|
||||
return result.value().get<Number>().integer_value();
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<i64> CSSMathValue::resolve_integer(Layout::Node const& layout_node) const
|
||||
{
|
||||
return resolve_integer(Length::ResolutionContext::for_layout_node(layout_node));
|
||||
}
|
||||
|
||||
bool CSSMathValue::contains_percentage() const
|
||||
{
|
||||
return m_calculation->contains_percentage();
|
||||
|
|
|
@ -99,7 +99,7 @@ public:
|
|||
|
||||
bool resolves_to_length() const { return m_resolved_type.matches_length(); }
|
||||
bool resolves_to_length_percentage() const { return m_resolved_type.matches_length_percentage(); }
|
||||
[[nodiscard]] Optional<Length> resolve_length(Length::ResolutionContext const&) const;
|
||||
Optional<Length> resolve_length(Length::ResolutionContext const&) const;
|
||||
Optional<Length> resolve_length(Layout::Node const& layout_node) const;
|
||||
Optional<Length> resolve_length_percentage(Layout::Node const&, Length const& percentage_basis) const;
|
||||
Optional<Length> resolve_length_percentage(Layout::Node const&, CSSPixels percentage_basis) const;
|
||||
|
@ -119,7 +119,11 @@ public:
|
|||
bool resolves_to_number() const { return m_resolved_type.matches_number(); }
|
||||
bool resolves_to_number_percentage() const { return m_resolved_type.matches_number_percentage(); }
|
||||
Optional<double> resolve_number() const;
|
||||
Optional<double> resolve_number(Length::ResolutionContext const&) const;
|
||||
Optional<double> resolve_number(Layout::Node const& layout_node) const;
|
||||
Optional<i64> resolve_integer() const;
|
||||
Optional<i64> resolve_integer(Length::ResolutionContext const&) const;
|
||||
Optional<i64> resolve_integer(Layout::Node const& layout_node) const;
|
||||
|
||||
bool resolves_to_dimension() const { return m_resolved_type.matches_dimension(); }
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<!doctype html>
|
||||
<title>Test: support for calc with sign() in Media Queries</title>
|
||||
<link rel="author" title="Daniil Sakhapov" href="mailto:sakhapov@chromium.org">
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-values/#calc-notation">
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-mediaqueries/#units">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/mediaqueries/../reference/ref-filled-green-100px-square.xht">
|
||||
<style>
|
||||
:root {
|
||||
font-size: 16px;
|
||||
}
|
||||
div {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
@media (grid: calc(2 * sign(17px - 1rem))) {
|
||||
div {
|
||||
background-color: red;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||
<div></div>
|
Loading…
Add table
Reference in a new issue