diff --git a/Libraries/LibWeb/CSS/Angle.cpp b/Libraries/LibWeb/CSS/Angle.cpp index b7b47d7ed21..16e91fef4d3 100644 --- a/Libraries/LibWeb/CSS/Angle.cpp +++ b/Libraries/LibWeb/CSS/Angle.cpp @@ -84,9 +84,14 @@ Optional Angle::unit_from_name(StringView name) return {}; } -Angle Angle::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const&, Angle const& reference_value) +Angle Angle::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const& layout_node, Angle const& reference_value) { - return calculated->resolve_angle_percentage(reference_value).value(); + return calculated->resolve_angle( + { + .percentage_basis = reference_value, + .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node), + }) + .value(); } } diff --git a/Libraries/LibWeb/CSS/CSSStyleValue.cpp b/Libraries/LibWeb/CSS/CSSStyleValue.cpp index 3f33633515e..fb1361aba8c 100644 --- a/Libraries/LibWeb/CSS/CSSStyleValue.cpp +++ b/Libraries/LibWeb/CSS/CSSStyleValue.cpp @@ -386,7 +386,7 @@ int CSSStyleValue::to_font_weight() const return round_to(as_number().number()); } if (is_calculated()) { - auto maybe_weight = as_calculated().resolve_integer(); + auto maybe_weight = as_calculated().resolve_integer({}); if (maybe_weight.has_value()) return maybe_weight.value(); } diff --git a/Libraries/LibWeb/CSS/CalculatedOr.cpp b/Libraries/LibWeb/CSS/CalculatedOr.cpp index 37fe91bde6d..4ffeb0a439f 100644 --- a/Libraries/LibWeb/CSS/CalculatedOr.cpp +++ b/Libraries/LibWeb/CSS/CalculatedOr.cpp @@ -17,9 +17,9 @@ namespace Web::CSS { -Angle AngleOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const&) const +Angle AngleOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const& layout_node) const { - return calculated->resolve_angle().value(); + return calculated->resolve_angle({ .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value(); } NonnullRefPtr AngleOrCalculated::create_style_value() const @@ -27,9 +27,9 @@ NonnullRefPtr AngleOrCalculated::create_style_value() const return AngleStyleValue::create(value()); } -Flex FlexOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const&) const +Flex FlexOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const& layout_node) const { - return calculated->resolve_flex().value(); + return calculated->resolve_flex({ .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value(); } NonnullRefPtr FlexOrCalculated::create_style_value() const @@ -37,9 +37,9 @@ NonnullRefPtr FlexOrCalculated::create_style_value() const return FlexStyleValue::create(value()); } -Frequency FrequencyOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const&) const +Frequency FrequencyOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const& layout_node) const { - return calculated->resolve_frequency().value(); + return calculated->resolve_frequency({ .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value(); } NonnullRefPtr FrequencyOrCalculated::create_style_value() const @@ -49,13 +49,13 @@ NonnullRefPtr FrequencyOrCalculated::create_style_value() const i64 IntegerOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const& layout_node) const { - return calculated->resolve_integer(layout_node).value(); + return calculated->resolve_integer({ .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value(); } i64 IntegerOrCalculated::resolved(Length::ResolutionContext const& context) const { if (is_calculated()) - return calculated()->resolve_integer(context).value(); + return calculated()->resolve_integer({ .length_resolution_context = context }).value(); return value(); } @@ -66,13 +66,13 @@ NonnullRefPtr IntegerOrCalculated::create_style_value() const Length LengthOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const& layout_node) const { - return calculated->resolve_length(layout_node).value(); + return calculated->resolve_length({ .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value(); } Length LengthOrCalculated::resolved(Length::ResolutionContext const& context) const { if (is_calculated()) - return calculated()->resolve_length(context).value(); + return calculated()->resolve_length({ .length_resolution_context = context }).value(); return value(); } @@ -83,7 +83,7 @@ NonnullRefPtr LengthOrCalculated::create_style_value() const double NumberOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const& layout_node) const { - return calculated->resolve_number(layout_node).value(); + return calculated->resolve_number({ .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value(); } NonnullRefPtr NumberOrCalculated::create_style_value() const @@ -91,9 +91,9 @@ NonnullRefPtr NumberOrCalculated::create_style_value() const return NumberStyleValue::create(value()); } -Percentage PercentageOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const&) const +Percentage PercentageOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const& layout_node) const { - return calculated->resolve_percentage().value(); + return calculated->resolve_percentage({ .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value(); } NonnullRefPtr PercentageOrCalculated::create_style_value() const @@ -101,15 +101,15 @@ NonnullRefPtr PercentageOrCalculated::create_style_value() const return PercentageStyleValue::create(value()); } -Resolution ResolutionOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const&) const +Resolution ResolutionOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const& layout_node) const { - return calculated->resolve_resolution().value(); + return calculated->resolve_resolution({ .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value(); } Resolution ResolutionOrCalculated::resolved() const { if (is_calculated()) - return calculated()->resolve_resolution().value(); + return calculated()->resolve_resolution({}).value(); return value(); } @@ -118,9 +118,9 @@ NonnullRefPtr ResolutionOrCalculated::create_style_value() const return ResolutionStyleValue::create(value()); } -Time TimeOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const&) const +Time TimeOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const& layout_node) const { - return calculated->resolve_time().value(); + return calculated->resolve_time({ .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value(); } NonnullRefPtr TimeOrCalculated::create_style_value() const diff --git a/Libraries/LibWeb/CSS/ComputedProperties.cpp b/Libraries/LibWeb/CSS/ComputedProperties.cpp index ada580407af..f014c72421f 100644 --- a/Libraries/LibWeb/CSS/ComputedProperties.cpp +++ b/Libraries/LibWeb/CSS/ComputedProperties.cpp @@ -301,8 +301,12 @@ CSSPixels ComputedProperties::compute_line_height(CSSPixelRect const& viewport_r } if (line_height.is_calculated()) { + CalculationResolutionContext context { + .percentage_basis = Length(1, Length::Type::Em), + .length_resolution_context = Length::ResolutionContext { viewport_rect, font_metrics, root_font_metrics }, + }; if (line_height.as_calculated().resolves_to_number()) { - auto resolved = line_height.as_calculated().resolve_number(); + auto resolved = line_height.as_calculated().resolve_number(context); if (!resolved.has_value()) { dbgln("FIXME: Failed to resolve calc() line-height (number): {}", line_height.as_calculated().to_string(CSSStyleValue::SerializationMode::Normal)); return CSSPixels::nearest_value_for(m_font_list->first().pixel_metrics().line_spacing()); @@ -310,7 +314,7 @@ CSSPixels ComputedProperties::compute_line_height(CSSPixelRect const& viewport_r return Length(resolved.value(), Length::Type::Em).to_px(viewport_rect, font_metrics, root_font_metrics); } - auto resolved = line_height.as_calculated().resolve_length(Length::ResolutionContext { viewport_rect, font_metrics, root_font_metrics }); + auto resolved = line_height.as_calculated().resolve_length(context); if (!resolved.has_value()) { dbgln("FIXME: Failed to resolve calc() line-height: {}", line_height.as_calculated().to_string(CSSStyleValue::SerializationMode::Normal)); return CSSPixels::nearest_value_for(m_font_list->first().pixel_metrics().line_spacing()); @@ -346,14 +350,15 @@ float ComputedProperties::resolve_opacity_value(CSSStyleValue const& value) unclamped_opacity = value.as_number().number(); } else if (value.is_calculated()) { auto const& calculated = value.as_calculated(); + CalculationResolutionContext context {}; if (calculated.resolves_to_percentage()) { - auto maybe_percentage = value.as_calculated().resolve_percentage(); + auto maybe_percentage = value.as_calculated().resolve_percentage(context); if (maybe_percentage.has_value()) unclamped_opacity = maybe_percentage->as_fraction(); else dbgln("Unable to resolve calc() as opacity (percentage): {}", value.to_string(CSSStyleValue::SerializationMode::Normal)); } else if (calculated.resolves_to_number()) { - auto maybe_number = value.as_calculated().resolve_number(); + auto maybe_number = value.as_calculated().resolve_number(context); if (maybe_number.has_value()) unclamped_opacity = maybe_number.value(); else @@ -485,7 +490,7 @@ CSS::Length ComputedProperties::border_spacing_horizontal(Layout::Node const& la if (value.is_length()) return value.as_length().length(); if (value.is_calculated()) - return value.as_calculated().resolve_length(layout_node).value_or(CSS::Length(0, CSS::Length::Type::Px)); + return value.as_calculated().resolve_length({ .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value_or(CSS::Length(0, CSS::Length::Type::Px)); auto const& list = value.as_value_list(); return list.value_at(0, false)->as_length().length(); } @@ -496,7 +501,7 @@ CSS::Length ComputedProperties::border_spacing_vertical(Layout::Node const& layo if (value.is_length()) return value.as_length().length(); if (value.is_calculated()) - return value.as_calculated().resolve_length(layout_node).value_or(CSS::Length(0, CSS::Length::Type::Px)); + return value.as_calculated().resolve_length({ .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value_or(CSS::Length(0, CSS::Length::Type::Px)); auto const& list = value.as_value_list(); return list.value_at(1, false)->as_length().length(); } @@ -1038,7 +1043,7 @@ Vector ComputedProperties::shadow(PropertyID property_id, Layout::No if (value->is_length()) return value->as_length().length(); if (value->is_calculated()) - return value->as_calculated().resolve_length(layout_node); + return value->as_calculated().resolve_length({ .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }); return {}; }; @@ -1503,7 +1508,7 @@ Vector ComputedProperties::counter_data(PropertyID property_id) con if (counter.value->is_integer()) { data.value = AK::clamp_to(counter.value->as_integer().integer()); } else if (counter.value->is_calculated()) { - auto maybe_int = counter.value->as_calculated().resolve_integer(); + auto maybe_int = counter.value->as_calculated().resolve_integer({}); if (maybe_int.has_value()) data.value = AK::clamp_to(*maybe_int); } else { diff --git a/Libraries/LibWeb/CSS/Frequency.cpp b/Libraries/LibWeb/CSS/Frequency.cpp index 1cecd756cc8..cb295c70732 100644 --- a/Libraries/LibWeb/CSS/Frequency.cpp +++ b/Libraries/LibWeb/CSS/Frequency.cpp @@ -63,9 +63,14 @@ Optional Frequency::unit_from_name(StringView name) return {}; } -Frequency Frequency::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const&, Frequency const& reference_value) +Frequency Frequency::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const& layout_node, Frequency const& reference_value) { - return calculated->resolve_frequency_percentage(reference_value).value(); + return calculated->resolve_frequency( + { + .percentage_basis = reference_value, + .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node), + }) + .value(); } } diff --git a/Libraries/LibWeb/CSS/Length.cpp b/Libraries/LibWeb/CSS/Length.cpp index 2bff0a24905..9609e577aa3 100644 --- a/Libraries/LibWeb/CSS/Length.cpp +++ b/Libraries/LibWeb/CSS/Length.cpp @@ -411,12 +411,22 @@ Length Length::absolutized(CSSPixelRect const& viewport_rect, FontMetrics const& Length Length::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const& layout_node, Length const& reference_value) { - return calculated->resolve_length_percentage(layout_node, reference_value).value(); + return calculated->resolve_length( + { + .percentage_basis = reference_value, + .length_resolution_context = ResolutionContext::for_layout_node(layout_node), + }) + .value(); } Length Length::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const& layout_node, CSSPixels reference_value) { - return calculated->resolve_length_percentage(layout_node, reference_value).value(); + return calculated->resolve_length( + { + .percentage_basis = make_px(reference_value), + .length_resolution_context = ResolutionContext::for_layout_node(layout_node), + }) + .value(); } } diff --git a/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Libraries/LibWeb/CSS/Parser/Parser.cpp index 96adf9dfacb..370e5ec5364 100644 --- a/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -2174,6 +2174,10 @@ Optional Parser::parse_ratio(TokenStream& tokens) auto transaction = tokens.begin_transaction(); tokens.discard_whitespace(); + // FIXME: It seems like `calc(...) / calc(...)` is a valid , but this case is neither mentioned in a spec, + // nor tested in WPT, as far as I can tell. + // Still, we should probably support it. That means not assuming we can resolve the calculation immediately. + auto read_number_value = [this](ComponentValue const& component_value) -> Optional { if (component_value.is(Token::Type::Number)) { return component_value.token().number_value(); @@ -2181,7 +2185,7 @@ Optional Parser::parse_ratio(TokenStream& tokens) auto maybe_calc = parse_calculated_value(component_value); if (!maybe_calc || !maybe_calc->resolves_to_number()) return {}; - if (auto resolved_number = maybe_calc->resolve_number(); resolved_number.has_value() && resolved_number.value() >= 0) { + if (auto resolved_number = maybe_calc->resolve_number({}); resolved_number.has_value() && resolved_number.value() >= 0) { return resolved_number.value(); } } @@ -8129,7 +8133,7 @@ RefPtr Parser::parse_grid_track_placement(TokenStr auto const& token = tokens.consume_a_token(); if (auto maybe_calculated = parse_calculated_value(token); maybe_calculated && maybe_calculated->resolves_to_number()) { transaction.commit(); - return GridTrackPlacementStyleValue::create(GridTrackPlacement::make_line(static_cast(maybe_calculated->resolve_integer().value()), {})); + return GridTrackPlacementStyleValue::create(GridTrackPlacement::make_line(static_cast(maybe_calculated->resolve_integer({}).value()), {})); } if (token.is_ident("auto"sv)) { transaction.commit(); @@ -9710,17 +9714,19 @@ bool Parser::expand_unresolved_values(DOM::Element& element, FlyString const& pr } if (property.has_value()) { + // FIXME: I think we don't need any of this once simplification is implemented. It runs inside parse_calculation_node() already. + // So, this is just a temporary hack to not change behaviour until that's done. if (auto maybe_calc_value = parse_calculated_value(value); maybe_calc_value && maybe_calc_value->is_calculated()) { - // FIXME: Run the actual simplification algorithm auto& calc_value = maybe_calc_value->as_calculated(); + CalculationResolutionContext context {}; if (property_accepts_type(*property, ValueType::Angle) && calc_value.resolves_to_angle()) { - auto resolved_value = calc_value.resolve_angle(); - dest.empend(Token::create_dimension(resolved_value->to_degrees(), "deg"_fly_string)); + if (auto resolved_value = calc_value.resolve_angle(context); resolved_value.has_value()) + dest.empend(Token::create_dimension(resolved_value->to_degrees(), "deg"_fly_string)); continue; } if (property_accepts_type(*property, ValueType::Frequency) && calc_value.resolves_to_frequency()) { - auto resolved_value = calc_value.resolve_frequency(); - dest.empend(Token::create_dimension(resolved_value->to_hertz(), "hz"_fly_string)); + if (auto resolved_value = calc_value.resolve_frequency(context); resolved_value.has_value()) + dest.empend(Token::create_dimension(resolved_value->to_hertz(), "hz"_fly_string)); continue; } if (property_accepts_type(*property, ValueType::Length) && calc_value.resolves_to_length()) { @@ -9729,23 +9735,23 @@ bool Parser::expand_unresolved_values(DOM::Element& element, FlyString const& pr // This might be easier once we have calc-simplification implemented. } if (property_accepts_type(*property, ValueType::Percentage) && calc_value.resolves_to_percentage()) { - auto resolved_value = calc_value.resolve_percentage(); - dest.empend(Token::create_percentage(resolved_value.value().value())); + if (auto resolved_value = calc_value.resolve_percentage(context); resolved_value.has_value()) + dest.empend(Token::create_percentage(resolved_value.value().value())); continue; } if (property_accepts_type(*property, ValueType::Time) && calc_value.resolves_to_time()) { - auto resolved_value = calc_value.resolve_time(); - dest.empend(Token::create_dimension(resolved_value->to_seconds(), "s"_fly_string)); + if (auto resolved_value = calc_value.resolve_time(context); resolved_value.has_value()) + dest.empend(Token::create_dimension(resolved_value->to_seconds(), "s"_fly_string)); continue; } if (property_accepts_type(*property, ValueType::Number) && calc_value.resolves_to_number()) { - auto resolved_value = calc_value.resolve_number(); - dest.empend(Token::create_number(resolved_value.value(), Number::Type::Number)); + if (auto resolved_value = calc_value.resolve_number(context); resolved_value.has_value()) + dest.empend(Token::create_number(resolved_value.value(), Number::Type::Number)); continue; } if (property_accepts_type(*property, ValueType::Integer) && calc_value.resolves_to_number()) { - auto resolved_value = calc_value.resolve_integer(); - dest.empend(Token::create_number(resolved_value.value(), Number::Type::Integer)); + if (auto resolved_value = calc_value.resolve_integer(context); resolved_value.has_value()) + dest.empend(Token::create_number(resolved_value.value(), Number::Type::Integer)); continue; } } diff --git a/Libraries/LibWeb/CSS/Parser/RuleParsing.cpp b/Libraries/LibWeb/CSS/Parser/RuleParsing.cpp index 84b2a80a846..f18cc26b99a 100644 --- a/Libraries/LibWeb/CSS/Parser/RuleParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/RuleParsing.cpp @@ -621,7 +621,7 @@ GC::Ptr Parser::convert_to_font_face_rule(AtRule const& rule) // TODO: Once we implement calc-simplification in the parser, we should no longer see math values here, // unless they're impossible to resolve and thus invalid. if (percentage_value->is_calculated()) { - if (auto result = percentage_value->as_calculated().resolve_percentage(); result.has_value()) + if (auto result = percentage_value->as_calculated().resolve_percentage({}); result.has_value()) return result.value(); } @@ -736,7 +736,7 @@ GC::Ptr Parser::convert_to_font_face_rule(AtRule const& rule) if (setting_value->is_integer()) { settings.set(feature_tag->as_open_type_tagged().tag(), setting_value->as_integer().integer()); } else if (setting_value->is_calculated() && setting_value->as_calculated().resolves_to_number()) { - if (auto integer = setting_value->as_calculated().resolve_integer(); integer.has_value()) { + if (auto integer = setting_value->as_calculated().resolve_integer({}); integer.has_value()) { settings.set(feature_tag->as_open_type_tagged().tag(), *integer); } else { dbgln_if(CSS_PARSER_DEBUG, "CSSParser: Calculated value in font-feature-settings descriptor cannot be resolved at parse time; skipping"); @@ -810,7 +810,7 @@ GC::Ptr Parser::convert_to_font_face_rule(AtRule const& rule) if (setting_value->is_number()) { settings.set(variation_tag->as_open_type_tagged().tag(), setting_value->as_number().number()); } else if (setting_value->is_calculated() && setting_value->as_calculated().resolves_to_number()) { - if (auto number = setting_value->as_calculated().resolve_number(); number.has_value()) { + if (auto number = setting_value->as_calculated().resolve_number({}); number.has_value()) { settings.set(variation_tag->as_open_type_tagged().tag(), *number); } else { dbgln_if(CSS_PARSER_DEBUG, "CSSParser: Calculated value in font-variation-settings descriptor cannot be resolved at parse time; skipping"); diff --git a/Libraries/LibWeb/CSS/StyleComputer.cpp b/Libraries/LibWeb/CSS/StyleComputer.cpp index 17bed09d3df..06ce9bb0693 100644 --- a/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -1963,11 +1963,10 @@ RefPtr StyleComputer::compute_font_for_style_values( } else if (font_size.is_length()) { maybe_length = font_size.as_length().length(); } else if (font_size.is_calculated()) { - if (font_size.as_calculated().contains_percentage()) { - maybe_length = font_size.as_calculated().resolve_length_percentage(length_resolution_context, Length::make_px(parent_font_size())); - } else { - maybe_length = font_size.as_calculated().resolve_length(length_resolution_context); - } + maybe_length = font_size.as_calculated().resolve_length({ + .percentage_basis = Length::make_px(parent_font_size()), + .length_resolution_context = length_resolution_context, + }); } if (maybe_length.has_value()) { font_size_in_px = maybe_length.value().to_px(length_resolution_context); @@ -3034,7 +3033,7 @@ void StyleComputer::compute_math_depth(ComputedProperties& style, DOM::Element c if (integer_value.is_integer()) return integer_value.as_integer().integer(); if (integer_value.is_calculated()) - return integer_value.as_calculated().resolve_integer().value(); + return integer_value.as_calculated().resolve_integer({}).value(); VERIFY_NOT_REACHED(); }; diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSColorValue.cpp b/Libraries/LibWeb/CSS/StyleValues/CSSColorValue.cpp index da532d48bfb..a86da4c2998 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSColorValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/CSSColorValue.cpp @@ -42,7 +42,7 @@ Optional CSSColorValue::resolve_hue(CSSStyleValue const& style_value) return normalized(style_value.as_angle().angle().to_degrees()); if (style_value.is_calculated() && style_value.as_calculated().resolves_to_angle()) - return normalized(style_value.as_calculated().resolve_angle().value().to_degrees()); + return normalized(style_value.as_calculated().resolve_angle({}).value().to_degrees()); if (style_value.is_keyword() && style_value.to_keyword() == Keyword::None) return 0; @@ -65,10 +65,11 @@ Optional CSSColorValue::resolve_with_reference_value(CSSStyleValue const if (style_value.is_calculated()) { auto const& calculated = style_value.as_calculated(); + CalculationResolutionContext context {}; if (calculated.resolves_to_number()) - return calculated.resolve_number().value(); + return calculated.resolve_number(context).value(); if (calculated.resolves_to_percentage()) - return normalize_percentage(calculated.resolve_percentage().value()); + return normalize_percentage(calculated.resolve_percentage(context).value()); } if (style_value.is_keyword() && style_value.to_keyword() == Keyword::None) @@ -94,10 +95,11 @@ Optional CSSColorValue::resolve_alpha(CSSStyleValue const& style_value) if (style_value.is_calculated()) { auto const& calculated = style_value.as_calculated(); + CalculationResolutionContext context {}; if (calculated.resolves_to_number()) - return normalized(calculated.resolve_number().value()); + return normalized(calculated.resolve_number(context).value()); if (calculated.resolves_to_percentage()) - return normalized(calculated.resolve_percentage().value().as_fraction()); + return normalized(calculated.resolve_percentage(context).value().as_fraction()); } if (style_value.is_keyword() && style_value.to_keyword() == Keyword::None) diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSRGB.cpp b/Libraries/LibWeb/CSS/StyleValues/CSSRGB.cpp index 5829fc5dd49..da553821f0a 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSRGB.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/CSSRGB.cpp @@ -32,10 +32,11 @@ Color CSSRGB::to_color(Optional) const if (style_value.is_calculated()) { auto const& calculated = style_value.as_calculated(); + CalculationResolutionContext context {}; if (calculated.resolves_to_number()) - return normalized(calculated.resolve_number().value()); + return normalized(calculated.resolve_number(context).value()); if (calculated.resolves_to_percentage()) - return normalized(calculated.resolve_percentage().value().value() * 255 / 100); + return normalized(calculated.resolve_percentage(context).value().value() * 255 / 100); } if (style_value.is_keyword() && style_value.to_keyword() == Keyword::None) diff --git a/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp index 5f23ccbc993..3daf4d79a7a 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2021, Tobias Christiansen - * Copyright (c) 2021-2024, Sam Atkins + * Copyright (c) 2021-2025, Sam Atkins * Copyright (c) 2022-2023, MacDue * * SPDX-License-Identifier: BSD-2-Clause @@ -198,23 +198,23 @@ bool NumericCalculationNode::contains_percentage() const return m_value.has(); } -CalculatedStyleValue::CalculationResult NumericCalculationNode::resolve(Optional resolution_context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult NumericCalculationNode::resolve(CalculationResolutionContext const& context) const { if (m_value.has()) { // NOTE: Depending on whether percentage_basis is set, the caller of resolve() is expecting a raw percentage or // resolved type. - return percentage_basis.visit( + return context.percentage_basis.visit( [&](Empty const&) { VERIFY(numeric_type_from_calculated_style_value(m_value, {}) == numeric_type()); - return CalculatedStyleValue::CalculationResult::from_value(m_value, resolution_context, numeric_type()); + return CalculatedStyleValue::CalculationResult::from_value(m_value, context, numeric_type()); }, [&](auto const& value) { auto const calculated_value = value.percentage_of(m_value.get()); - return CalculatedStyleValue::CalculationResult::from_value(calculated_value, resolution_context, numeric_type_from_calculated_style_value(calculated_value, {})); + return CalculatedStyleValue::CalculationResult::from_value(calculated_value, context, numeric_type_from_calculated_style_value(calculated_value, {})); }); } - return CalculatedStyleValue::CalculationResult::from_value(m_value, resolution_context, numeric_type()); + return CalculatedStyleValue::CalculationResult::from_value(m_value, context, numeric_type()); } void NumericCalculationNode::dump(StringBuilder& builder, int indent) const @@ -272,17 +272,17 @@ bool SumCalculationNode::contains_percentage() const return false; } -CalculatedStyleValue::CalculationResult SumCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult SumCalculationNode::resolve(CalculationResolutionContext const& context) const { Optional total; for (auto& additional_product : m_values) { - auto additional_value = additional_product->resolve(context, percentage_basis); + auto additional_value = additional_product->resolve(context); if (!total.has_value()) { total = additional_value; continue; } - total->add(additional_value, context, percentage_basis); + total->add(additional_value); } return total.value(); @@ -350,17 +350,17 @@ bool ProductCalculationNode::contains_percentage() const return false; } -CalculatedStyleValue::CalculationResult ProductCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult ProductCalculationNode::resolve(CalculationResolutionContext const& context) const { Optional total; for (auto& additional_product : m_values) { - auto additional_value = additional_product->resolve(context, percentage_basis); + auto additional_value = additional_product->resolve(context); if (!total.has_value()) { total = additional_value; continue; } - total->multiply_by(additional_value, context); + total->multiply_by(additional_value); } return total.value(); @@ -412,9 +412,9 @@ bool NegateCalculationNode::contains_percentage() const return m_value->contains_percentage(); } -CalculatedStyleValue::CalculationResult NegateCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult NegateCalculationNode::resolve(CalculationResolutionContext const& context) const { - auto child_value = m_value->resolve(context, percentage_basis); + auto child_value = m_value->resolve(context); child_value.negate(); return child_value; } @@ -464,9 +464,9 @@ bool InvertCalculationNode::contains_percentage() const return m_value->contains_percentage(); } -CalculatedStyleValue::CalculationResult InvertCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult InvertCalculationNode::resolve(CalculationResolutionContext const& context) const { - auto child_value = m_value->resolve(context, percentage_basis); + auto child_value = m_value->resolve(context); child_value.invert(); return child_value; } @@ -525,13 +525,13 @@ bool MinCalculationNode::contains_percentage() const return false; } -CalculatedStyleValue::CalculationResult MinCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult MinCalculationNode::resolve(CalculationResolutionContext const& context) const { - CalculatedStyleValue::CalculationResult smallest_node = m_values.first()->resolve(context, percentage_basis); + CalculatedStyleValue::CalculationResult smallest_node = m_values.first()->resolve(context); auto smallest_value = smallest_node.value(); for (size_t i = 1; i < m_values.size(); i++) { - auto child_resolved = m_values[i]->resolve(context, percentage_basis); + auto child_resolved = m_values[i]->resolve(context); auto child_value = child_resolved.value(); if (child_value < smallest_value) { @@ -604,13 +604,13 @@ bool MaxCalculationNode::contains_percentage() const return false; } -CalculatedStyleValue::CalculationResult MaxCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult MaxCalculationNode::resolve(CalculationResolutionContext const& context) const { - CalculatedStyleValue::CalculationResult largest_node = m_values.first()->resolve(context, percentage_basis); + CalculatedStyleValue::CalculationResult largest_node = m_values.first()->resolve(context); auto largest_value = largest_node.value(); for (size_t i = 1; i < m_values.size(); i++) { - auto child_resolved = m_values[i]->resolve(context, percentage_basis); + auto child_resolved = m_values[i]->resolve(context); auto child_value = child_resolved.value(); if (child_value > largest_value) { @@ -680,11 +680,11 @@ bool ClampCalculationNode::contains_percentage() const return m_min_value->contains_percentage() || m_center_value->contains_percentage() || m_max_value->contains_percentage(); } -CalculatedStyleValue::CalculationResult ClampCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult ClampCalculationNode::resolve(CalculationResolutionContext const& context) const { - auto min_node = m_min_value->resolve(context, percentage_basis); - auto center_node = m_center_value->resolve(context, percentage_basis); - auto max_node = m_max_value->resolve(context, percentage_basis); + auto min_node = m_min_value->resolve(context); + auto center_node = m_center_value->resolve(context); + auto max_node = m_max_value->resolve(context); auto min_value = min_node.value(); auto center_value = center_node.value(); @@ -750,9 +750,9 @@ bool AbsCalculationNode::contains_percentage() const return m_value->contains_percentage(); } -CalculatedStyleValue::CalculationResult AbsCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult AbsCalculationNode::resolve(CalculationResolutionContext const& context) const { - auto node_a = m_value->resolve(context, percentage_basis); + auto node_a = m_value->resolve(context); if (node_a.value() < 0) node_a.negate(); return node_a; @@ -801,9 +801,9 @@ bool SignCalculationNode::contains_percentage() const return m_value->contains_percentage(); } -CalculatedStyleValue::CalculationResult SignCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult SignCalculationNode::resolve(CalculationResolutionContext const& context) const { - auto node_a = m_value->resolve(context, percentage_basis); + auto node_a = m_value->resolve(context); auto node_a_value = node_a.value(); if (node_a_value < 0) @@ -864,7 +864,7 @@ String ConstantCalculationNode::to_string() const VERIFY_NOT_REACHED(); } -CalculatedStyleValue::CalculationResult ConstantCalculationNode::resolve([[maybe_unused]] Optional context, [[maybe_unused]] CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult ConstantCalculationNode::resolve(CalculationResolutionContext const&) const { switch (m_constant) { case ConstantType::E: @@ -925,9 +925,9 @@ bool SinCalculationNode::contains_percentage() const return m_value->contains_percentage(); } -CalculatedStyleValue::CalculationResult SinCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult SinCalculationNode::resolve(CalculationResolutionContext const& context) const { - auto node_a = m_value->resolve(context, percentage_basis); + auto node_a = m_value->resolve(context); auto node_a_value = AK::to_radians(node_a.value()); auto result = sin(node_a_value); @@ -977,9 +977,9 @@ bool CosCalculationNode::contains_percentage() const return m_value->contains_percentage(); } -CalculatedStyleValue::CalculationResult CosCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult CosCalculationNode::resolve(CalculationResolutionContext const& context) const { - auto node_a = m_value->resolve(context, percentage_basis); + auto node_a = m_value->resolve(context); auto node_a_value = AK::to_radians(node_a.value()); auto result = cos(node_a_value); @@ -1029,9 +1029,9 @@ bool TanCalculationNode::contains_percentage() const return m_value->contains_percentage(); } -CalculatedStyleValue::CalculationResult TanCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult TanCalculationNode::resolve(CalculationResolutionContext const& context) const { - auto node_a = m_value->resolve(context, percentage_basis); + auto node_a = m_value->resolve(context); auto node_a_value = AK::to_radians(node_a.value()); auto result = tan(node_a_value); @@ -1081,9 +1081,9 @@ bool AsinCalculationNode::contains_percentage() const return m_value->contains_percentage(); } -CalculatedStyleValue::CalculationResult AsinCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult AsinCalculationNode::resolve(CalculationResolutionContext const& context) const { - auto node_a = m_value->resolve(context, percentage_basis); + auto node_a = m_value->resolve(context); auto result = AK::to_degrees(asin(node_a.value())); return { result, CSSNumericType { CSSNumericType::BaseType::Angle, 1 } }; } @@ -1131,9 +1131,9 @@ bool AcosCalculationNode::contains_percentage() const return m_value->contains_percentage(); } -CalculatedStyleValue::CalculationResult AcosCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult AcosCalculationNode::resolve(CalculationResolutionContext const& context) const { - auto node_a = m_value->resolve(context, percentage_basis); + auto node_a = m_value->resolve(context); auto result = AK::to_degrees(acos(node_a.value())); return { result, CSSNumericType { CSSNumericType::BaseType::Angle, 1 } }; } @@ -1181,9 +1181,9 @@ bool AtanCalculationNode::contains_percentage() const return m_value->contains_percentage(); } -CalculatedStyleValue::CalculationResult AtanCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult AtanCalculationNode::resolve(CalculationResolutionContext const& context) const { - auto node_a = m_value->resolve(context, percentage_basis); + auto node_a = m_value->resolve(context); auto result = AK::to_degrees(atan(node_a.value())); return { result, CSSNumericType { CSSNumericType::BaseType::Angle, 1 } }; } @@ -1234,10 +1234,10 @@ bool Atan2CalculationNode::contains_percentage() const return m_y->contains_percentage() || m_x->contains_percentage(); } -CalculatedStyleValue::CalculationResult Atan2CalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult Atan2CalculationNode::resolve(CalculationResolutionContext const& context) const { - auto node_a = m_y->resolve(context, percentage_basis); - auto node_b = m_x->resolve(context, percentage_basis); + auto node_a = m_y->resolve(context); + auto node_b = m_x->resolve(context); auto result = AK::to_degrees(atan2(node_a.value(), node_b.value())); return { result, CSSNumericType { CSSNumericType::BaseType::Angle, 1 } }; } @@ -1284,10 +1284,10 @@ String PowCalculationNode::to_string() const return MUST(builder.to_string()); } -CalculatedStyleValue::CalculationResult PowCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult PowCalculationNode::resolve(CalculationResolutionContext const& context) const { - auto node_a = m_x->resolve(context, percentage_basis); - auto node_b = m_y->resolve(context, percentage_basis); + auto node_a = m_x->resolve(context); + auto node_b = m_y->resolve(context); auto result = pow(node_a.value(), node_b.value()); return { result, CSSNumericType {} }; } @@ -1331,9 +1331,9 @@ String SqrtCalculationNode::to_string() const return MUST(builder.to_string()); } -CalculatedStyleValue::CalculationResult SqrtCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult SqrtCalculationNode::resolve(CalculationResolutionContext const& context) const { - auto node_a = m_value->resolve(context, percentage_basis); + auto node_a = m_value->resolve(context); auto result = sqrt(node_a.value()); return { result, CSSNumericType {} }; } @@ -1391,13 +1391,13 @@ bool HypotCalculationNode::contains_percentage() const return false; } -CalculatedStyleValue::CalculationResult HypotCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult HypotCalculationNode::resolve(CalculationResolutionContext const& context) const { double square_sum = 0.0; Optional result_type; for (auto const& value : m_values) { - auto child_resolved = value->resolve(context, percentage_basis); + auto child_resolved = value->resolve(context); auto child_value = child_resolved.value(); square_sum += child_value * child_value; @@ -1459,10 +1459,10 @@ String LogCalculationNode::to_string() const return MUST(builder.to_string()); } -CalculatedStyleValue::CalculationResult LogCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult LogCalculationNode::resolve(CalculationResolutionContext const& context) const { - auto node_a = m_x->resolve(context, percentage_basis); - auto node_b = m_y->resolve(context, percentage_basis); + auto node_a = m_x->resolve(context); + auto node_b = m_y->resolve(context); auto result = log2(node_a.value()) / log2(node_b.value()); return { result, CSSNumericType {} }; } @@ -1506,9 +1506,9 @@ String ExpCalculationNode::to_string() const return MUST(builder.to_string()); } -CalculatedStyleValue::CalculationResult ExpCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult ExpCalculationNode::resolve(CalculationResolutionContext const& context) const { - auto node_a = m_value->resolve(context, percentage_basis); + auto node_a = m_value->resolve(context); auto result = exp(node_a.value()); return { result, CSSNumericType {} }; } @@ -1563,10 +1563,10 @@ bool RoundCalculationNode::contains_percentage() const return m_x->contains_percentage() || m_y->contains_percentage(); } -CalculatedStyleValue::CalculationResult RoundCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult RoundCalculationNode::resolve(CalculationResolutionContext const& context) const { - auto node_a = m_x->resolve(context, percentage_basis); - auto node_b = m_y->resolve(context, percentage_basis); + auto node_a = m_x->resolve(context); + auto node_b = m_y->resolve(context); auto node_a_value = node_a.value(); auto node_b_value = node_b.value(); @@ -1650,10 +1650,10 @@ bool ModCalculationNode::contains_percentage() const return m_x->contains_percentage() || m_y->contains_percentage(); } -CalculatedStyleValue::CalculationResult ModCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult ModCalculationNode::resolve(CalculationResolutionContext const& context) const { - auto node_a = m_x->resolve(context, percentage_basis); - auto node_b = m_y->resolve(context, percentage_basis); + auto node_a = m_x->resolve(context); + auto node_b = m_y->resolve(context); auto node_a_value = node_a.value(); auto node_b_value = node_b.value(); @@ -1711,10 +1711,10 @@ bool RemCalculationNode::contains_percentage() const return m_x->contains_percentage() || m_y->contains_percentage(); } -CalculatedStyleValue::CalculationResult RemCalculationNode::resolve(Optional context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult RemCalculationNode::resolve(CalculationResolutionContext const& context) const { - auto node_a = m_x->resolve(context, percentage_basis); - auto node_b = m_y->resolve(context, percentage_basis); + auto node_a = m_x->resolve(context); + auto node_b = m_y->resolve(context); auto value = fmod(node_a.value(), node_b.value()); return { value, node_a.type() }; } @@ -1734,7 +1734,7 @@ bool RemCalculationNode::equals(CalculationNode const& other) const && m_y->equals(*static_cast(other).m_y); } -CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalculationResult::from_value(Value const& value, Optional context, Optional numeric_type) +CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalculationResult::from_value(Value const& value, CalculationResolutionContext const& context, Optional numeric_type) { auto const expected_numeric_type = numeric_type_from_calculated_style_value(value, {}); if (numeric_type.has_value()) { @@ -1755,12 +1755,12 @@ CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalculationResult: return length.absolute_length_to_px().to_double(); // If we don't have a context, we cant resolve the length, so return NAN - if (!context.has_value()) { + if (!context.length_resolution_context.has_value()) { dbgln("Failed to resolve length, likely due to calc() being used with relative units and a property not taking it into account"); return AK::NaN; } - return length.to_px(*context).to_double(); + return length.to_px(context.length_resolution_context.value()).to_double(); }, [](Resolution const& resolution) { return resolution.to_dots_per_pixel(); }, [](Time const& time) { return time.to_seconds(); }, @@ -1769,25 +1769,25 @@ CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalculationResult: return CalculationResult { number, numeric_type }; } -void CalculatedStyleValue::CalculationResult::add(CalculationResult const& other, Optional, PercentageBasis const&) +void CalculatedStyleValue::CalculationResult::add(CalculationResult const& other) { m_value = m_value + other.m_value; m_type = m_type.has_value() && other.m_type.has_value() ? m_type->added_to(*other.m_type) : OptionalNone {}; } -void CalculatedStyleValue::CalculationResult::subtract(CalculationResult const& other, Optional, PercentageBasis const&) +void CalculatedStyleValue::CalculationResult::subtract(CalculationResult const& other) { m_value = m_value - other.m_value; m_type = m_type.has_value() && other.m_type.has_value() ? m_type->added_to(*other.m_type) : OptionalNone {}; } -void CalculatedStyleValue::CalculationResult::multiply_by(CalculationResult const& other, Optional) +void CalculatedStyleValue::CalculationResult::multiply_by(CalculationResult const& other) { m_value = m_value * other.m_value; m_type = m_type.has_value() && other.m_type.has_value() ? m_type->multiplied_by(*other.m_type) : OptionalNone {}; } -void CalculatedStyleValue::CalculationResult::divide_by(CalculationResult const& other, Optional) +void CalculatedStyleValue::CalculationResult::divide_by(CalculationResult const& other) { auto other_copy = other; other_copy.invert(); @@ -1822,164 +1822,78 @@ bool CalculatedStyleValue::equals(CSSStyleValue const& other) const return m_calculation->equals(*other.as_calculated().m_calculation); } -Optional CalculatedStyleValue::resolve_angle() const +Optional CalculatedStyleValue::resolve_angle(CalculationResolutionContext const& context) const { - auto result = m_calculation->resolve({}, {}); + auto result = m_calculation->resolve(context); if (result.type().has_value() && result.type()->matches_angle(m_context.percentages_resolve_as)) return Angle::make_degrees(result.value()); return {}; } -Optional CalculatedStyleValue::resolve_angle(Layout::Node const& layout_node) const +Optional CalculatedStyleValue::resolve_flex(CalculationResolutionContext const& context) const { - return resolve_angle(Length::ResolutionContext::for_layout_node(layout_node)); -} - -Optional CalculatedStyleValue::resolve_angle(Length::ResolutionContext const& context) const -{ - auto result = m_calculation->resolve(context, {}); - if (result.type().has_value() && result.type()->matches_angle(m_context.percentages_resolve_as)) - return Angle::make_degrees(result.value()); - return {}; -} - -Optional CalculatedStyleValue::resolve_angle_percentage(Angle const& percentage_basis) const -{ - auto result = m_calculation->resolve({}, percentage_basis); - if (result.type().has_value() && result.type()->matches_angle(m_context.percentages_resolve_as)) - return Angle::make_degrees(result.value()); - return {}; -} - -Optional CalculatedStyleValue::resolve_flex() const -{ - auto result = m_calculation->resolve({}, {}); + auto result = m_calculation->resolve(context); if (result.type().has_value() && result.type()->matches_flex(m_context.percentages_resolve_as)) return Flex::make_fr(result.value()); return {}; } -Optional CalculatedStyleValue::resolve_frequency() const +Optional CalculatedStyleValue::resolve_frequency(CalculationResolutionContext const& context) const { - auto result = m_calculation->resolve({}, {}); + auto result = m_calculation->resolve(context); if (result.type().has_value() && result.type()->matches_frequency(m_context.percentages_resolve_as)) return Frequency::make_hertz(result.value()); return {}; } -Optional CalculatedStyleValue::resolve_frequency_percentage(Frequency const& percentage_basis) const +Optional CalculatedStyleValue::resolve_length(CalculationResolutionContext const& context) const { - auto result = m_calculation->resolve({}, percentage_basis); - if (result.type().has_value() && result.type()->matches_frequency(m_context.percentages_resolve_as)) - return Frequency::make_hertz(result.value()); - return {}; -} - -Optional CalculatedStyleValue::resolve_length(Length::ResolutionContext const& context) const -{ - auto result = m_calculation->resolve(context, {}); + auto result = m_calculation->resolve(context); if (result.type().has_value() && result.type()->matches_length(m_context.percentages_resolve_as)) return Length::make_px(CSSPixels { result.value() }); return {}; } -Optional CalculatedStyleValue::resolve_length(Layout::Node const& layout_node) const +Optional CalculatedStyleValue::resolve_percentage(CalculationResolutionContext const& context) const { - return resolve_length(Length::ResolutionContext::for_layout_node(layout_node)); -} - -Optional CalculatedStyleValue::resolve_length_percentage(Layout::Node const& layout_node, Length const& percentage_basis) const -{ - return resolve_length_percentage(Length::ResolutionContext::for_layout_node(layout_node), percentage_basis); -} - -Optional CalculatedStyleValue::resolve_length_percentage(Layout::Node const& layout_node, CSSPixels percentage_basis) const -{ - return resolve_length_percentage(Length::ResolutionContext::for_layout_node(layout_node), Length::make_px(percentage_basis)); -} - -Optional CalculatedStyleValue::resolve_length_percentage(Length::ResolutionContext const& resolution_context, Length const& percentage_basis) const -{ - auto result = m_calculation->resolve(resolution_context, percentage_basis); - if (result.type().has_value() && result.type()->matches_length(m_context.percentages_resolve_as)) - return Length::make_px(CSSPixels { result.value() }); - return {}; -} - -Optional CalculatedStyleValue::resolve_percentage() const -{ - auto result = m_calculation->resolve({}, {}); + auto result = m_calculation->resolve(context); if (result.type().has_value() && result.type()->matches_percentage()) return Percentage { result.value() }; return {}; } -Optional CalculatedStyleValue::resolve_resolution() const +Optional CalculatedStyleValue::resolve_resolution(CalculationResolutionContext const& context) const { - auto result = m_calculation->resolve({}, {}); + auto result = m_calculation->resolve(context); if (result.type().has_value() && result.type()->matches_resolution(m_context.percentages_resolve_as)) return Resolution::make_dots_per_pixel(result.value()); return {}; } -Optional