diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 10923271be..49ff0fc7be 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -7134,11 +7134,6 @@ Optional Parser::parse_calc_value(TokenStream Parser::parse_calc_product_part_with_operator(TokenStream& tokens) { - // Note: The default value is not used or passed around. - auto product_with_operator = make( - CalculatedStyleValue::ProductOperation::Multiply, - CalculatedStyleValue::CalcNumberValue { Number {} }); - tokens.skip_whitespace(); auto const& op_token = tokens.peek_token(); @@ -7146,160 +7141,33 @@ OwnPtr Parser::parse_calc_pro return nullptr; auto op = op_token.token().delim(); - if (op == '*') { - tokens.next_token(); - tokens.skip_whitespace(); - product_with_operator->op = CalculatedStyleValue::ProductOperation::Multiply; - auto parsed_calc_value = parse_calc_value(tokens); - if (!parsed_calc_value.has_value()) - return nullptr; - product_with_operator->value = { parsed_calc_value.release_value() }; - - } else if (op == '/') { - // FIXME: Detect divide-by-zero if possible - tokens.next_token(); - tokens.skip_whitespace(); - product_with_operator->op = CalculatedStyleValue::ProductOperation::Divide; - auto parsed_calc_number_value = parse_calc_number_value(tokens); - if (!parsed_calc_number_value.has_value()) - return nullptr; - product_with_operator->value = { parsed_calc_number_value.release_value() }; - } else { + if (op != '*' && op != '/') return nullptr; - } - - return product_with_operator; -} - -OwnPtr Parser::parse_calc_number_product_part_with_operator(TokenStream& tokens) -{ - // Note: The default value is not used or passed around. - auto number_product_with_operator = make( - CalculatedStyleValue::ProductOperation::Multiply, - CalculatedStyleValue::CalcNumberValue { Number {} }); + tokens.next_token(); tokens.skip_whitespace(); - - auto const& op_token = tokens.peek_token(); - if (!op_token.is(Token::Type::Delim)) - return nullptr; - - auto op = op_token.token().delim(); - if (op == '*') { - tokens.next_token(); - tokens.skip_whitespace(); - number_product_with_operator->op = CalculatedStyleValue::ProductOperation::Multiply; - } else if (op == '/') { - // FIXME: Detect divide-by-zero if possible - tokens.next_token(); - tokens.skip_whitespace(); - number_product_with_operator->op = CalculatedStyleValue::ProductOperation::Divide; - } else { - return nullptr; - } - - auto parsed_calc_value = parse_calc_number_value(tokens); + auto parsed_calc_value = parse_calc_value(tokens); if (!parsed_calc_value.has_value()) return nullptr; - number_product_with_operator->value = parsed_calc_value.release_value(); - return number_product_with_operator; -} - -OwnPtr Parser::parse_calc_number_product(TokenStream& tokens) -{ - auto calc_number_product = make( - CalculatedStyleValue::CalcNumberValue { Number {} }, - Vector> {}); - - auto first_calc_number_value_or_error = parse_calc_number_value(tokens); - if (!first_calc_number_value_or_error.has_value()) - return nullptr; - calc_number_product->first_calc_number_value = first_calc_number_value_or_error.release_value(); - - while (tokens.has_next_token()) { - auto number_product_with_operator = parse_calc_number_product_part_with_operator(tokens); - if (!number_product_with_operator) - break; - calc_number_product->zero_or_more_additional_calc_number_values.append(number_product_with_operator.release_nonnull()); - } - - return calc_number_product; -} - -OwnPtr Parser::parse_calc_number_sum_part_with_operator(TokenStream& tokens) -{ - if (!(tokens.peek_token().is(Token::Type::Delim) - && (tokens.peek_token().token().delim() == '+' || tokens.peek_token().token().delim() == '-') - && tokens.peek_token(1).is(Token::Type::Whitespace))) - return nullptr; - - auto const& token = tokens.next_token(); - tokens.skip_whitespace(); - - CalculatedStyleValue::SumOperation op; - auto delim = token.token().delim(); - if (delim == '+') - op = CalculatedStyleValue::SumOperation::Add; - else if (delim == '-') - op = CalculatedStyleValue::SumOperation::Subtract; - else - return nullptr; - - auto calc_number_product = parse_calc_number_product(tokens); - if (!calc_number_product) - return nullptr; - return make(op, calc_number_product.release_nonnull()); -} - -OwnPtr Parser::parse_calc_number_sum(TokenStream& tokens) -{ - auto first_calc_number_product_or_error = parse_calc_number_product(tokens); - if (!first_calc_number_product_or_error) - return nullptr; - - Vector> additional {}; - while (tokens.has_next_token()) { - auto calc_sum_part = parse_calc_number_sum_part_with_operator(tokens); - if (!calc_sum_part) - return nullptr; - additional.append(calc_sum_part.release_nonnull()); - } - - tokens.skip_whitespace(); - - auto calc_number_sum = make(first_calc_number_product_or_error.release_nonnull(), move(additional)); - return calc_number_sum; -} - -Optional Parser::parse_calc_number_value(TokenStream& tokens) -{ - auto const& first = tokens.peek_token(); - if (first.is_block() && first.block().is_paren()) { - tokens.next_token(); - auto block_values = TokenStream(first.block().values()); - auto calc_number_sum = parse_calc_number_sum(block_values); - if (calc_number_sum) - return CalculatedStyleValue::CalcNumberValue { calc_number_sum.release_nonnull() }; - } - - if (!first.is(Token::Type::Number)) - return {}; - tokens.next_token(); - - return CalculatedStyleValue::CalcNumberValue { first.token().number() }; + auto operation = op == '*' + ? CalculatedStyleValue::ProductOperation::Multiply + : CalculatedStyleValue::ProductOperation::Divide; + return make(operation, parsed_calc_value.release_value()); } +// https://www.w3.org/TR/css-values-4/#typedef-calc-product OwnPtr Parser::parse_calc_product(TokenStream& tokens) { - auto calc_product = make( - CalculatedStyleValue::CalcValue { Number {} }, - Vector> {}); + // ` = [ [ '*' | '/' ] ]*` auto first_calc_value_or_error = parse_calc_value(tokens); if (!first_calc_value_or_error.has_value()) return nullptr; - calc_product->first_calc_value = first_calc_value_or_error.release_value(); + + auto calc_product = make( + first_calc_value_or_error.release_value(), + Vector> {}); while (tokens.has_next_token()) { auto product_with_operator = parse_calc_product_part_with_operator(tokens); @@ -7338,8 +7206,11 @@ OwnPtr Parser::parse_calc_sum_par return make(op, calc_product.release_nonnull()); }; +// https://www.w3.org/TR/css-values-4/#typedef-calc-sum OwnPtr Parser::parse_calc_sum(TokenStream& tokens) { + // ` = [ [ '+' | '-' ] ]*` + auto parsed_calc_product = parse_calc_product(tokens); if (!parsed_calc_product) return nullptr; diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index f3a45863f2..76894a6f40 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -327,13 +327,8 @@ private: OwnPtr parse_calc_sum(TokenStream&); OwnPtr parse_calc_product(TokenStream&); Optional parse_calc_value(TokenStream&); - OwnPtr parse_calc_number_sum(TokenStream&); - OwnPtr parse_calc_number_product(TokenStream&); - Optional parse_calc_number_value(TokenStream&); OwnPtr parse_calc_product_part_with_operator(TokenStream&); OwnPtr parse_calc_sum_part_with_operator(TokenStream&); - OwnPtr parse_calc_number_product_part_with_operator(TokenStream& tokens); - OwnPtr parse_calc_number_sum_part_with_operator(TokenStream&); OwnPtr parse_calc_expression(Vector const&); ParseErrorOr> parse_complex_selector(TokenStream&, SelectorType); diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp index 6b87e3313e..5697510909 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp @@ -214,13 +214,6 @@ bool CalculatedStyleValue::equals(StyleValue const& other) const return to_string().release_value_but_fixme_should_propagate_errors() == other.to_string().release_value_but_fixme_should_propagate_errors(); } -ErrorOr CalculatedStyleValue::CalcNumberValue::to_string() const -{ - return value.visit( - [](Number const& number) -> ErrorOr { return String::number(number.value()); }, - [](NonnullOwnPtr const& sum) -> ErrorOr { return String::formatted("({})", TRY(sum->to_string())); }); -} - ErrorOr CalculatedStyleValue::CalcValue::to_string() const { return value.visit( @@ -238,15 +231,6 @@ ErrorOr CalculatedStyleValue::CalcSum::to_string() const return builder.to_string(); } -ErrorOr CalculatedStyleValue::CalcNumberSum::to_string() const -{ - StringBuilder builder; - TRY(builder.try_append(TRY(first_calc_number_product->to_string()))); - for (auto const& item : zero_or_more_additional_calc_number_products) - TRY(builder.try_append(TRY(item->to_string()))); - return builder.to_string(); -} - ErrorOr CalculatedStyleValue::CalcProduct::to_string() const { StringBuilder builder; @@ -262,32 +246,10 @@ ErrorOr CalculatedStyleValue::CalcSumPartWithOperator::to_string() const } ErrorOr CalculatedStyleValue::CalcProductPartWithOperator::to_string() const -{ - auto value_string = TRY(value.visit( - [](CalcValue const& v) { return v.to_string(); }, - [](CalcNumberValue const& v) { return v.to_string(); })); - return String::formatted(" {} {}", op == ProductOperation::Multiply ? "*"sv : "/"sv, value_string); -} - -ErrorOr CalculatedStyleValue::CalcNumberProduct::to_string() const -{ - StringBuilder builder; - TRY(builder.try_append(TRY(first_calc_number_value.to_string()))); - for (auto const& item : zero_or_more_additional_calc_number_values) - TRY(builder.try_append(TRY(item->to_string()))); - return builder.to_string(); -} - -ErrorOr CalculatedStyleValue::CalcNumberProductPartWithOperator::to_string() const { return String::formatted(" {} {}", op == ProductOperation::Multiply ? "*"sv : "/"sv, TRY(value.to_string())); } -ErrorOr CalculatedStyleValue::CalcNumberSumPartWithOperator::to_string() const -{ - return String::formatted(" {} {}", op == SumOperation::Add ? "+"sv : "-"sv, TRY(value->to_string())); -} - Optional CalculatedStyleValue::resolve_angle() const { auto result = m_expression->resolve(nullptr, {}); @@ -466,15 +428,6 @@ Optional CalculatedStyleValue::CalcSum::reso return resolve_sum_type(type, zero_or_more_additional_calc_products); } -Optional CalculatedStyleValue::CalcNumberSum::resolved_type() const -{ - auto maybe_type = first_calc_number_product->resolved_type(); - if (!maybe_type.has_value()) - return {}; - auto type = maybe_type.value(); - return resolve_sum_type(type, zero_or_more_additional_calc_number_products); -} - template static Optional resolve_product_type(CalculatedStyleValue::ResolvedType first_type, Vector> const& zero_or_more_additional_values) { @@ -532,34 +485,9 @@ Optional CalculatedStyleValue::CalcSumPartWi return value->resolved_type(); } -Optional CalculatedStyleValue::CalcNumberProduct::resolved_type() const -{ - auto maybe_type = first_calc_number_value.resolved_type(); - if (!maybe_type.has_value()) - return {}; - auto type = maybe_type.value(); - return resolve_product_type(type, zero_or_more_additional_calc_number_values); -} - -Optional CalculatedStyleValue::CalcNumberProductPartWithOperator::resolved_type() const -{ - return value.resolved_type(); -} - -Optional CalculatedStyleValue::CalcNumberSumPartWithOperator::resolved_type() const -{ - return value->resolved_type(); -} - Optional CalculatedStyleValue::CalcProductPartWithOperator::resolved_type() const { - return value.visit( - [](CalcValue const& calc_value) { - return calc_value.resolved_type(); - }, - [](CalcNumberValue const& calc_number_value) { - return calc_number_value.resolved_type(); - }); + return value.resolved_type(); } Optional CalculatedStyleValue::CalcValue::resolved_type() const @@ -576,26 +504,6 @@ Optional CalculatedStyleValue::CalcValue::re [](NonnullOwnPtr const& sum) { return sum->resolved_type(); }); } -Optional CalculatedStyleValue::CalcNumberValue::resolved_type() const -{ - return value.visit( - [](Number const& number) -> Optional { - return { number.is_integer() ? ResolvedType::Integer : ResolvedType::Number }; - }, - [](NonnullOwnPtr const& sum) { return sum->resolved_type(); }); -} - -CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcNumberValue::resolve(Layout::Node const* layout_node, PercentageBasis const& percentage_basis) const -{ - return value.visit( - [&](Number const& number) -> CalculatedStyleValue::CalculationResult { - return CalculatedStyleValue::CalculationResult { number }; - }, - [&](NonnullOwnPtr const& sum) -> CalculatedStyleValue::CalculationResult { - return sum->resolve(layout_node, percentage_basis); - }); -} - CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcValue::resolve(Layout::Node const* layout_node, PercentageBasis const& percentage_basis) const { return value.visit( @@ -625,87 +533,31 @@ CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcSum::resolve(L return value; } -CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcNumberSum::resolve(Layout::Node const* layout_node, PercentageBasis 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, PercentageBasis 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); - // FIXME: Checking for division by 0 should happen during parsing. - VERIFY(resolved_calc_number_value.value().get().value() != 0.0f); - value.divide_by(resolved_calc_number_value, layout_node); - }); - } - - return value; -} - -CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcNumberProduct::resolve(Layout::Node const* layout_node, PercentageBasis 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(); + if (additional_value->op == ProductOperation::Multiply) { + auto resolved_value = additional_value->value.resolve(layout_node, percentage_basis); + value.multiply_by(resolved_value, layout_node); + } else { + auto resolved_calc_number_value = additional_value->value.resolve(layout_node, percentage_basis); + // FIXME: Return the relevant constant here. (infinity?) + VERIFY(resolved_calc_number_value.value().get().value() != 0.0f); + value.divide_by(resolved_calc_number_value, layout_node); + } } return value; } CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcProductPartWithOperator::resolve(Layout::Node const* layout_node, PercentageBasis 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, PercentageBasis const& percentage_basis) const -{ - return value->resolve(layout_node, percentage_basis); -} - -CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcNumberProductPartWithOperator::resolve(Layout::Node const* layout_node, PercentageBasis const& percentage_basis) const { return value.resolve(layout_node, percentage_basis); } -CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcNumberSumPartWithOperator::resolve(Layout::Node const* layout_node, PercentageBasis const& percentage_basis) const +CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcSumPartWithOperator::resolve(Layout::Node const* layout_node, PercentageBasis const& percentage_basis) const { return value->resolve(layout_node, percentage_basis); } @@ -744,9 +596,7 @@ bool CalculatedStyleValue::CalcProduct::contains_percentage() const bool CalculatedStyleValue::CalcProductPartWithOperator::contains_percentage() const { - return value.visit( - [](CalcValue const& value) { return value.contains_percentage(); }, - [](CalcNumberValue const&) { return false; }); + return value.contains_percentage(); } bool CalculatedStyleValue::CalcValue::contains_percentage() const diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h index 88b1726c17..9e2873ed34 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h @@ -64,17 +64,6 @@ public: struct CalcSumPartWithOperator; struct CalcProduct; struct CalcProductPartWithOperator; - struct CalcNumberSum; - struct CalcNumberSumPartWithOperator; - struct CalcNumberProduct; - struct CalcNumberProductPartWithOperator; - - struct CalcNumberValue { - Variant> value; - ErrorOr to_string() const; - Optional resolved_type() const; - CalculationResult resolve(Layout::Node const*, PercentageBasis const& percentage_basis) const; - }; struct CalcValue { Variant> value; @@ -100,19 +89,6 @@ public: bool contains_percentage() const; }; - struct CalcNumberSum { - CalcNumberSum(NonnullOwnPtr first_calc_number_product, Vector> additional) - : first_calc_number_product(move(first_calc_number_product)) - , zero_or_more_additional_calc_number_products(move(additional)) {}; - - NonnullOwnPtr first_calc_number_product; - Vector> zero_or_more_additional_calc_number_products; - - ErrorOr to_string() const; - Optional resolved_type() const; - CalculationResult resolve(Layout::Node const*, PercentageBasis const& percentage_basis) const; - }; - struct CalcProduct { CalcValue first_calc_value; Vector> zero_or_more_additional_calc_values; @@ -139,7 +115,7 @@ public: struct CalcProductPartWithOperator { ProductOperation op; - Variant value; + CalcValue value; ErrorOr to_string() const; Optional resolved_type() const; @@ -148,37 +124,6 @@ public: bool contains_percentage() const; }; - struct CalcNumberProduct { - CalcNumberValue first_calc_number_value; - Vector> zero_or_more_additional_calc_number_values; - - ErrorOr to_string() const; - Optional resolved_type() const; - CalculationResult resolve(Layout::Node const*, PercentageBasis const& percentage_basis) const; - }; - - struct CalcNumberProductPartWithOperator { - ProductOperation op; - CalcNumberValue value; - - ErrorOr to_string() const; - Optional resolved_type() const; - CalculationResult resolve(Layout::Node const*, PercentageBasis const& percentage_basis) const; - }; - - struct CalcNumberSumPartWithOperator { - CalcNumberSumPartWithOperator(SumOperation op, NonnullOwnPtr calc_number_product) - : op(op) - , value(move(calc_number_product)) {}; - - SumOperation op; - NonnullOwnPtr value; - - ErrorOr to_string() const; - Optional resolved_type() const; - CalculationResult resolve(Layout::Node const*, PercentageBasis const& percentage_basis) const; - }; - static ValueComparingNonnullRefPtr create(NonnullOwnPtr calc_sum, ResolvedType resolved_type) { return adopt_ref(*new CalculatedStyleValue(move(calc_sum), resolved_type));