diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 04a5c4972b..f86538e284 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -8209,6 +8209,33 @@ ErrorOr> Parser::parse_a_calculation(Vector SignCalculationNode::dump(StringBuilder& builder, int indent) cons return {}; } +ErrorOr> ConstantCalculationNode::create(ConstantType constant) +{ + return adopt_nonnull_own_or_enomem(new (nothrow) ConstantCalculationNode(constant)); +} + +ConstantCalculationNode::ConstantCalculationNode(ConstantType constant) + : CalculationNode(Type::Constant) + , m_constant(constant) +{ +} + +ConstantCalculationNode::~ConstantCalculationNode() = default; + +ErrorOr ConstantCalculationNode::to_string() const +{ + switch (m_constant) { + case CalculationNode::ConstantType::E: + return "e"_short_string; + case CalculationNode::ConstantType::PI: + return "pi"_short_string; + case CalculationNode::ConstantType::Infinity: + return "infinity"_string; + case CalculationNode::ConstantType::MinusInfinity: + return "-infinity"_string; + case CalculationNode::ConstantType::NaN: + return "NaN"_string; + } + + VERIFY_NOT_REACHED(); +} +Optional ConstantCalculationNode::resolved_type() const +{ + return CalculatedStyleValue::ResolvedType::Number; +} + +CalculatedStyleValue::CalculationResult ConstantCalculationNode::resolve([[maybe_unused]] Optional context, [[maybe_unused]] CalculatedStyleValue::PercentageBasis const& percentage_basis) const +{ + switch (m_constant) { + case CalculationNode::ConstantType::E: + return { Number(Number::Type::Number, M_E) }; + case CalculationNode::ConstantType::PI: + return { Number(Number::Type::Number, M_PI) }; + // FIXME: We need to keep track of Infinity and NaN across all nodes, since they require special handling. + case CalculationNode::ConstantType::Infinity: + return { Number(Number::Type::Number, NumericLimits::max()) }; + case CalculationNode::ConstantType::MinusInfinity: + return { Number(Number::Type::Number, NumericLimits::lowest()) }; + case CalculationNode::ConstantType::NaN: + return { Number(Number::Type::Number, NAN) }; + } + + VERIFY_NOT_REACHED(); +} + +ErrorOr ConstantCalculationNode::for_each_child_node([[maybe_unused]] Function(NonnullOwnPtr&)> const& callback) +{ + return {}; +} + +ErrorOr ConstantCalculationNode::dump(StringBuilder& builder, int indent) const +{ + TRY(builder.try_appendff("{: >{}}CONSTANT: {}\n", "", indent, TRY(to_string()))); + return {}; +} + void CalculatedStyleValue::CalculationResult::add(CalculationResult const& other, Optional context, PercentageBasis const& percentage_basis) { add_or_subtract_internal(SumOperation::Add, other, context, percentage_basis); diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h index 12e54e9f78..972d2ee1bd 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h @@ -115,6 +115,16 @@ private: // https://www.w3.org/TR/css-values-4/#calculation-tree class CalculationNode { public: + // https://drafts.csswg.org/css-values-4/#calc-constants + // https://drafts.csswg.org/css-values-4/#calc-error-constants + enum class ConstantType { + E, + PI, + NaN, + Infinity, + MinusInfinity, + }; + enum class Type { Numeric, // NOTE: Currently, any value with a `var()` or `attr()` function in it is always an @@ -138,6 +148,10 @@ public: Abs, Sign, + // Constant Nodes + // https://drafts.csswg.org/css-values-4/#calc-constants + Constant, + // This only exists during parsing. Unparsed, }; @@ -354,4 +368,22 @@ private: NonnullOwnPtr m_value; }; +class ConstantCalculationNode final : public CalculationNode { +public: + static ErrorOr> create(CalculationNode::ConstantType); + ~ConstantCalculationNode(); + + virtual ErrorOr to_string() const override; + virtual Optional resolved_type() const override; + virtual bool contains_percentage() const override { return false; }; + virtual CalculatedStyleValue::CalculationResult resolve(Optional context, CalculatedStyleValue::PercentageBasis const&) const override; + virtual ErrorOr for_each_child_node(Function(NonnullOwnPtr&)> const&) override; + + virtual ErrorOr dump(StringBuilder&, int indent) const override; + +private: + ConstantCalculationNode(ConstantType); + CalculationNode::ConstantType m_constant; +}; + }