diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp index 3c17869a30..c067a015ad 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp @@ -249,7 +249,6 @@ String BackgroundStyleValue::to_string() const return builder.to_string(); } -<<<<<<< HEAD String BackgroundRepeatStyleValue::to_string() const { return String::formatted("{} {}", CSS::to_string(m_repeat_x), CSS::to_string(m_repeat_y)); @@ -273,7 +272,8 @@ String BorderRadiusStyleValue::to_string() const String BoxShadowStyleValue::to_string() const { return String::formatted("{} {} {} {}", m_offset_x.to_string(), m_offset_y.to_string(), m_blur_radius.to_string(), m_color.to_string()); -======= +} + void CalculatedStyleValue::CalculationResult::add(CalculationResult const& other, Layout::Node const* layout_node, Length const& percentage_basis) { add_or_subtract_internal(SumOperation::Add, other, layout_node, percentage_basis); @@ -354,6 +354,7 @@ void CalculatedStyleValue::CalculationResult::multiply_by(CalculationResult cons } }, [&](Length const& length) { + VERIFY(layout_node); m_value = Length::make_px(length.to_px(*layout_node) * other.m_value.get()); }, [&](Percentage const& percentage) { @@ -374,126 +375,47 @@ void CalculatedStyleValue::CalculationResult::divide_by(CalculationResult const& m_value = f / denominator; }, [&](Length const& length) { + VERIFY(layout_node); m_value = Length::make_px(length.to_px(*layout_node) / denominator); }, [&](Percentage const& percentage) { m_value = Percentage { percentage.value() / denominator }; }); ->>>>>>> d91d120251 (LibWeb: Implement CalculationResult type for calc() results) } -static float resolve_calc_value(CalculatedStyleValue::CalcValue const& calc_value, Layout::Node const& layout_node); -static float resolve_calc_number_value(CalculatedStyleValue::CalcNumberValue const&); -static float resolve_calc_product(NonnullOwnPtr const& calc_product, Layout::Node const& layout_node); -static float resolve_calc_sum(NonnullOwnPtr const& calc_sum, Layout::Node const& layout_node); -static float resolve_calc_number_sum(NonnullOwnPtr const&); -static float resolve_calc_number_product(NonnullOwnPtr const&); - Optional CalculatedStyleValue::resolve_length(Layout::Node const& layout_node) const { - auto length = resolve_calc_sum(m_expression, layout_node); - return Length::make_px(length); -} + auto result = m_expression->resolve(&layout_node, {}); -static float resolve_calc_value(CalculatedStyleValue::CalcValue const& calc_value, Layout::Node const& layout_node) -{ - return calc_value.value.visit( - [](float value) { return value; }, - [&](Length const& length) { - return length.resolved_or_zero(layout_node).to_px(layout_node); + return result.value().visit( + [&](float) -> Optional { + return {}; }, - [&](NonnullOwnPtr const& calc_sum) { - return resolve_calc_sum(calc_sum, layout_node); + [&](Length const& length) -> Optional { + return length; }, - [](auto&) { - VERIFY_NOT_REACHED(); - return 0.0f; + [&](Percentage const&) -> Optional { + return {}; }); } -static float resolve_calc_number_product(NonnullOwnPtr const& calc_number_product) +Optional CalculatedStyleValue::resolve_length_percentage(Layout::Node const& layout_node, Length const& percentage_basis) const { - auto value = resolve_calc_number_value(calc_number_product->first_calc_number_value); + VERIFY(!percentage_basis.is_undefined()); + auto result = m_expression->resolve(&layout_node, percentage_basis); - for (auto& additional_number_value : calc_number_product->zero_or_more_additional_calc_number_values) { - auto additional_value = resolve_calc_number_value(additional_number_value.value); - if (additional_number_value.op == CalculatedStyleValue::ProductOperation::Multiply) - value *= additional_value; - else if (additional_number_value.op == CalculatedStyleValue::ProductOperation::Divide) - value /= additional_value; - else - VERIFY_NOT_REACHED(); - } - - return value; -} - -static float resolve_calc_number_sum(NonnullOwnPtr const& calc_number_sum) -{ - auto value = resolve_calc_number_product(calc_number_sum->first_calc_number_product); - - for (auto& additional_product : calc_number_sum->zero_or_more_additional_calc_number_products) { - auto additional_value = resolve_calc_number_product(additional_product.value); - if (additional_product.op == CSS::CalculatedStyleValue::SumOperation::Add) - value += additional_value; - else if (additional_product.op == CSS::CalculatedStyleValue::SumOperation::Subtract) - value -= additional_value; - else - VERIFY_NOT_REACHED(); - } - - return value; -} - -static float resolve_calc_number_value(CalculatedStyleValue::CalcNumberValue const& number_value) -{ - return number_value.value.visit( - [](float number) { return number; }, - [](NonnullOwnPtr const& calc_number_sum) { - return resolve_calc_number_sum(calc_number_sum); + return result.value().visit( + [&](float) -> Optional { + return {}; + }, + [&](Length const& length) -> Optional { + return length; + }, + [&](Percentage const& percentage) -> Optional { + return percentage; }); } -static float resolve_calc_product(NonnullOwnPtr const& calc_product, Layout::Node const& layout_node) -{ - auto value = resolve_calc_value(calc_product->first_calc_value, layout_node); - - for (auto& additional_value : calc_product->zero_or_more_additional_calc_values) { - additional_value.value.visit( - [&](CalculatedStyleValue::CalcValue const& calc_value) { - if (additional_value.op != CalculatedStyleValue::ProductOperation::Multiply) - VERIFY_NOT_REACHED(); - auto resolved_value = resolve_calc_value(calc_value, layout_node); - value *= resolved_value; - }, - [&](CalculatedStyleValue::CalcNumberValue const& calc_number_value) { - if (additional_value.op != CalculatedStyleValue::ProductOperation::Divide) - VERIFY_NOT_REACHED(); - auto resolved_calc_number_value = resolve_calc_number_value(calc_number_value); - value /= resolved_calc_number_value; - }); - } - - return value; -} - -static float resolve_calc_sum(NonnullOwnPtr const& calc_sum, Layout::Node const& layout_node) -{ - auto value = resolve_calc_product(calc_sum->first_calc_product, layout_node); - - for (auto& additional_product : calc_sum->zero_or_more_additional_calc_products) { - auto additional_value = resolve_calc_product(additional_product.value, layout_node); - if (additional_product.op == CalculatedStyleValue::SumOperation::Add) - value += additional_value; - else if (additional_product.op == CalculatedStyleValue::SumOperation::Subtract) - value -= additional_value; - else - VERIFY_NOT_REACHED(); - } - - return value; -} - static bool is_number(CalculatedStyleValue::ResolvedType type) { return type == CalculatedStyleValue::ResolvedType::Number || type == CalculatedStyleValue::ResolvedType::Integer; @@ -662,6 +584,132 @@ Optional CalculatedStyleValue::CalcNumberVal [](NonnullOwnPtr const& sum) { return sum->resolved_type(); }); } +CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcNumberValue::resolve(Layout::Node const* layout_node, Length const& percentage_basis) const +{ + return value.visit( + [&](float f) -> CalculatedStyleValue::CalculationResult { + return CalculatedStyleValue::CalculationResult { f }; + }, + [&](NonnullOwnPtr const& sum) -> CalculatedStyleValue::CalculationResult { + return sum->resolve(layout_node, percentage_basis); + }); +} + +CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcValue::resolve(Layout::Node const* layout_node, Length const& percentage_basis) const +{ + return value.visit( + [&](float f) -> CalculatedStyleValue::CalculationResult { + return CalculatedStyleValue::CalculationResult { f }; + }, + [&](Length const& length) -> CalculatedStyleValue::CalculationResult { + return CalculatedStyleValue::CalculationResult { length }; + }, + [&](NonnullOwnPtr const& sum) -> CalculatedStyleValue::CalculationResult { + return sum->resolve(layout_node, percentage_basis); + }); +} + +CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcSum::resolve(Layout::Node const* layout_node, Length const& percentage_basis) const +{ + auto value = first_calc_product->resolve(layout_node, percentage_basis); + + for (auto& additional_product : zero_or_more_additional_calc_products) { + auto additional_value = additional_product.resolve(layout_node, percentage_basis); + + if (additional_product.op == CalculatedStyleValue::SumOperation::Add) + value.add(additional_value, layout_node, percentage_basis); + else if (additional_product.op == CalculatedStyleValue::SumOperation::Subtract) + value.subtract(additional_value, layout_node, percentage_basis); + else + VERIFY_NOT_REACHED(); + } + + return value; +} + +CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcNumberSum::resolve(Layout::Node const* layout_node, Length const& percentage_basis) const +{ + auto value = first_calc_number_product->resolve(layout_node, percentage_basis); + + for (auto& additional_product : zero_or_more_additional_calc_number_products) { + auto additional_value = additional_product.resolve(layout_node, percentage_basis); + + if (additional_product.op == CSS::CalculatedStyleValue::SumOperation::Add) + value.add(additional_value, layout_node, percentage_basis); + else if (additional_product.op == CalculatedStyleValue::SumOperation::Subtract) + value.subtract(additional_value, layout_node, percentage_basis); + else + VERIFY_NOT_REACHED(); + } + + return value; +} + +CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcProduct::resolve(Layout::Node const* layout_node, Length const& percentage_basis) const +{ + auto value = first_calc_value.resolve(layout_node, percentage_basis); + + for (auto& additional_value : zero_or_more_additional_calc_values) { + additional_value.value.visit( + [&](CalculatedStyleValue::CalcValue const& calc_value) { + VERIFY(additional_value.op == CalculatedStyleValue::ProductOperation::Multiply); + auto resolved_value = calc_value.resolve(layout_node, percentage_basis); + value.multiply_by(resolved_value, layout_node); + }, + [&](CalculatedStyleValue::CalcNumberValue const& calc_number_value) { + VERIFY(additional_value.op == CalculatedStyleValue::ProductOperation::Divide); + auto resolved_calc_number_value = calc_number_value.resolve(layout_node, percentage_basis); + value.divide_by(resolved_calc_number_value, layout_node); + }); + } + + return value; +} + +CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcNumberProduct::resolve(Layout::Node const* layout_node, Length const& percentage_basis) const +{ + auto value = first_calc_number_value.resolve(layout_node, percentage_basis); + + for (auto& additional_number_value : zero_or_more_additional_calc_number_values) { + auto additional_value = additional_number_value.resolve(layout_node, percentage_basis); + + if (additional_number_value.op == CalculatedStyleValue::ProductOperation::Multiply) + value.multiply_by(additional_value, layout_node); + else if (additional_number_value.op == CalculatedStyleValue::ProductOperation::Divide) + value.divide_by(additional_value, layout_node); + else + VERIFY_NOT_REACHED(); + } + + return value; +} + +CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcProductPartWithOperator::resolve(Layout::Node const* layout_node, Length const& percentage_basis) const +{ + return value.visit( + [&](CalcValue const& calc_value) { + return calc_value.resolve(layout_node, percentage_basis); + }, + [&](CalcNumberValue const& calc_number_value) { + return calc_number_value.resolve(layout_node, percentage_basis); + }); +} + +CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcSumPartWithOperator::resolve(Layout::Node const* layout_node, Length const& percentage_basis) const +{ + return value->resolve(layout_node, percentage_basis); +} + +CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcNumberProductPartWithOperator::resolve(Layout::Node const* layout_node, Length const& percentage_basis) const +{ + return value.resolve(layout_node, percentage_basis); +} + +CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcNumberSumPartWithOperator::resolve(Layout::Node const* layout_node, Length const& percentage_basis) const +{ + return value->resolve(layout_node, percentage_basis); +} + // https://www.w3.org/TR/css-color-4/#serializing-sRGB-values String ColorStyleValue::to_string() const { diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h index 3bfd434bf9..5c753ac4f2 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h @@ -703,11 +703,13 @@ public: struct CalcNumberValue { Variant> value; Optional resolved_type() const; + CalculationResult resolve(Layout::Node const*, Length const& percentage_basis) const; }; struct CalcValue { Variant> value; Optional resolved_type() const; + CalculationResult resolve(Layout::Node const*, Length const& percentage_basis) const; }; // This represents that: https://www.w3.org/TR/css-values-3/#calc-syntax @@ -720,6 +722,7 @@ public: NonnullOwnPtrVector zero_or_more_additional_calc_products; Optional resolved_type() const; + CalculationResult resolve(Layout::Node const*, Length const& percentage_basis) const; }; struct CalcNumberSum { @@ -731,6 +734,7 @@ public: NonnullOwnPtrVector zero_or_more_additional_calc_number_products; Optional resolved_type() const; + CalculationResult resolve(Layout::Node const*, Length const& percentage_basis) const; }; struct CalcProduct { @@ -738,6 +742,7 @@ public: NonnullOwnPtrVector zero_or_more_additional_calc_values; Optional resolved_type() const; + CalculationResult resolve(Layout::Node const*, Length const& percentage_basis) const; }; struct CalcSumPartWithOperator { @@ -749,6 +754,7 @@ public: NonnullOwnPtr value; Optional resolved_type() const; + CalculationResult resolve(Layout::Node const*, Length const& percentage_basis) const; }; struct CalcProductPartWithOperator { @@ -756,6 +762,7 @@ public: Variant value; Optional resolved_type() const; + CalculationResult resolve(Layout::Node const*, Length const& percentage_basis) const; }; struct CalcNumberProduct { @@ -763,6 +770,7 @@ public: NonnullOwnPtrVector zero_or_more_additional_calc_number_values; Optional resolved_type() const; + CalculationResult resolve(Layout::Node const*, Length const& percentage_basis) const; }; struct CalcNumberProductPartWithOperator { @@ -770,6 +778,7 @@ public: CalcNumberValue value; Optional resolved_type() const; + CalculationResult resolve(Layout::Node const*, Length const& percentage_basis) const; }; struct CalcNumberSumPartWithOperator { @@ -781,6 +790,7 @@ public: NonnullOwnPtr value; Optional resolved_type() const; + CalculationResult resolve(Layout::Node const*, Length const& percentage_basis) const; }; static NonnullRefPtr create(String const& expression_string, NonnullOwnPtr calc_sum, ResolvedType resolved_type) @@ -792,6 +802,7 @@ public: ResolvedType resolved_type() const { return m_resolved_type; } NonnullOwnPtr const& expression() const { return m_expression; } Optional resolve_length(Layout::Node const& layout_node) const; + Optional resolve_length_percentage(Layout::Node const&, Length const& percentage_basis) const; private: explicit CalculatedStyleValue(String const& expression_string, NonnullOwnPtr calc_sum, ResolvedType resolved_type)