ladybird/Libraries/LibWeb/CSS/StyleValues/CSSMathValue.h
Sam Atkins 6969d1eba3 LibWeb/CSS: Parse calc() as intermediate types instead of UnparsedCN
Previously we created a tree of CalculationNodes with dummy
UnparsedCalculationNode children, and then swapped those with the real
children. This matched the spec closely but had the unfortunate
downside that CalculationNodes couldn't be immutable, and couldn't know
their properties at construct-time. UnparsedCalculationNode is also a
footgun, as if it gets left in the tree accidentally we would VERIFY().

So instead, let's parse the calc() tree into an intermediate format, and
then convert each node in that tree, depth-first, into its
corresponding CalculationNode. This means each CalculationNode knows
what its children are when it is constructed, and they never change.

Apart from deleting UnparsedCalculationNode, we can also get rid of the
for_each_child_node() method that was only used by this "replace the
children" code.
2024-12-18 12:21:22 +00:00

781 lines
32 KiB
C++

/*
* Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
* Copyright (c) 2021-2024, Sam Atkins <sam@ladybird.org>
* Copyright (c) 2022-2023, MacDue <macdue@dueutil.tech>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Function.h>
#include <LibWeb/CSS/Angle.h>
#include <LibWeb/CSS/CSSNumericType.h>
#include <LibWeb/CSS/CSSStyleValue.h>
#include <LibWeb/CSS/Flex.h>
#include <LibWeb/CSS/Frequency.h>
#include <LibWeb/CSS/Length.h>
#include <LibWeb/CSS/Percentage.h>
#include <LibWeb/CSS/Resolution.h>
#include <LibWeb/CSS/Time.h>
namespace Web::CSS {
class CalculationNode;
class CSSMathValue : public CSSStyleValue {
public:
enum class ResolvedType {
Angle,
Flex,
Frequency,
Integer,
Length,
Number,
Percentage,
Resolution,
Time,
};
enum class SumOperation {
Add,
Subtract,
};
enum class ProductOperation {
Multiply,
Divide,
};
using PercentageBasis = Variant<Empty, Angle, Flex, Frequency, Length, Time>;
class CalculationResult {
public:
using Value = Variant<Number, Angle, Flex, Frequency, Length, Percentage, Resolution, Time>;
CalculationResult(Value value)
: m_value(move(value))
{
}
void add(CalculationResult const& other, Optional<Length::ResolutionContext const&>, PercentageBasis const& percentage_basis);
void subtract(CalculationResult const& other, Optional<Length::ResolutionContext const&>, PercentageBasis const& percentage_basis);
void multiply_by(CalculationResult const& other, Optional<Length::ResolutionContext const&>);
void divide_by(CalculationResult const& other, Optional<Length::ResolutionContext const&>);
void negate();
void invert();
Value const& value() const { return m_value; }
ResolvedType resolved_type() const;
[[nodiscard]] bool operator==(CalculationResult const&) const = default;
private:
void add_or_subtract_internal(SumOperation op, CalculationResult const& other, Optional<Length::ResolutionContext const&>, PercentageBasis const& percentage_basis);
Value m_value;
};
static ValueComparingNonnullRefPtr<CSSMathValue> create(NonnullOwnPtr<CalculationNode> calculation, CSSNumericType resolved_type)
{
return adopt_ref(*new (nothrow) CSSMathValue(move(calculation), resolved_type));
}
virtual String to_string(SerializationMode) const override;
virtual bool equals(CSSStyleValue const& other) const override;
bool resolves_to_angle() const { return m_resolved_type.matches_angle(); }
bool resolves_to_angle_percentage() const { return m_resolved_type.matches_angle_percentage(); }
Optional<Angle> resolve_angle() const;
Optional<Angle> resolve_angle(Layout::Node const& layout_node) const;
Optional<Angle> resolve_angle(Length::ResolutionContext const& context) const;
Optional<Angle> resolve_angle_percentage(Angle const& percentage_basis) const;
bool resolves_to_flex() const { return m_resolved_type.matches_flex(); }
Optional<Flex> resolve_flex() const;
bool resolves_to_frequency() const { return m_resolved_type.matches_frequency(); }
bool resolves_to_frequency_percentage() const { return m_resolved_type.matches_frequency_percentage(); }
Optional<Frequency> resolve_frequency() const;
Optional<Frequency> resolve_frequency_percentage(Frequency const& percentage_basis) const;
bool resolves_to_length() const { return m_resolved_type.matches_length(); }
bool resolves_to_length_percentage() const { return m_resolved_type.matches_length_percentage(); }
Optional<Length> resolve_length(Length::ResolutionContext const&) const;
Optional<Length> resolve_length(Layout::Node const& layout_node) const;
Optional<Length> resolve_length_percentage(Layout::Node const&, Length const& percentage_basis) const;
Optional<Length> resolve_length_percentage(Layout::Node const&, CSSPixels percentage_basis) const;
Optional<Length> resolve_length_percentage(Length::ResolutionContext const&, Length const& percentage_basis) const;
bool resolves_to_percentage() const { return m_resolved_type.matches_percentage(); }
Optional<Percentage> resolve_percentage() const;
bool resolves_to_resolution() const { return m_resolved_type.matches_resolution(); }
Optional<Resolution> resolve_resolution() const;
bool resolves_to_time() const { return m_resolved_type.matches_time(); }
bool resolves_to_time_percentage() const { return m_resolved_type.matches_time_percentage(); }
Optional<Time> resolve_time() const;
Optional<Time> resolve_time_percentage(Time const& percentage_basis) const;
bool resolves_to_number() const { return m_resolved_type.matches_number(); }
bool resolves_to_number_percentage() const { return m_resolved_type.matches_number_percentage(); }
Optional<double> resolve_number() const;
Optional<double> resolve_number(Length::ResolutionContext const&) const;
Optional<double> resolve_number(Layout::Node const& layout_node) const;
Optional<i64> resolve_integer() const;
Optional<i64> resolve_integer(Length::ResolutionContext const&) const;
Optional<i64> resolve_integer(Layout::Node const& layout_node) const;
bool resolves_to_dimension() const { return m_resolved_type.matches_dimension(); }
bool contains_percentage() const;
String dump() const;
private:
explicit CSSMathValue(NonnullOwnPtr<CalculationNode> calculation, CSSNumericType resolved_type)
: CSSStyleValue(Type::Math)
, m_resolved_type(resolved_type)
, m_calculation(move(calculation))
{
}
CSSNumericType m_resolved_type;
NonnullOwnPtr<CalculationNode> m_calculation;
};
// 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,
};
static Optional<ConstantType> constant_type_from_string(StringView);
enum class Type {
Numeric,
// NOTE: Currently, any value with a `var()` or `attr()` function in it is always an
// UnresolvedStyleValue so we do not have to implement a NonMathFunction type here.
// Comparison function nodes, a sub-type of operator node
// https://drafts.csswg.org/css-values-4/#comp-func
Min,
Max,
Clamp,
// Calc-operator nodes, a sub-type of operator node
// https://www.w3.org/TR/css-values-4/#calculation-tree-calc-operator-nodes
Sum,
Product,
Negate,
Invert,
// Sign-Related Functions, a sub-type of operator node
// https://drafts.csswg.org/css-values-4/#sign-funcs
Abs,
Sign,
// Constant Nodes
// https://drafts.csswg.org/css-values-4/#calc-constants
Constant,
// Trigonometric functions, a sub-type of operator node
// https://drafts.csswg.org/css-values-4/#trig-funcs
Sin,
Cos,
Tan,
Asin,
Acos,
Atan,
Atan2,
// Exponential functions, a sub-type of operator node
// https://drafts.csswg.org/css-values-4/#exponent-funcs
Pow,
Sqrt,
Hypot,
Log,
Exp,
// Stepped value functions, a sub-type of operator node
// https://drafts.csswg.org/css-values-4/#round-func
Round,
Mod,
Rem,
// This only exists during parsing.
Unparsed,
};
using NumericValue = CSSMathValue::CalculationResult::Value;
virtual ~CalculationNode();
Type type() const { return m_type; }
// https://www.w3.org/TR/css-values-4/#calculation-tree-operator-nodes
bool is_operator_node() const
{
return is_calc_operator_node() || is_math_function_node();
}
bool is_math_function_node() const
{
switch (m_type) {
case Type::Min:
case Type::Max:
case Type::Clamp:
case Type::Abs:
case Type::Sign:
case Type::Sin:
case Type::Cos:
case Type::Tan:
case Type::Asin:
case Type::Acos:
case Type::Atan:
case Type::Atan2:
case Type::Pow:
case Type::Sqrt:
case Type::Hypot:
case Type::Log:
case Type::Exp:
case Type::Round:
case Type::Mod:
case Type::Rem:
return true;
default:
return false;
}
}
// https://www.w3.org/TR/css-values-4/#calculation-tree-calc-operator-nodes
bool is_calc_operator_node() const
{
return first_is_one_of(m_type, Type::Sum, Type::Product, Type::Negate, Type::Invert);
}
virtual String to_string() const = 0;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const = 0;
virtual Optional<CSSNumericType> determine_type(PropertyID) const = 0;
virtual bool contains_percentage() const = 0;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const = 0;
virtual void dump(StringBuilder&, int indent) const = 0;
virtual bool equals(CalculationNode const&) const = 0;
protected:
explicit CalculationNode(Type);
private:
Type m_type;
};
class NumericCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<NumericCalculationNode> create(NumericValue);
~NumericCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
explicit NumericCalculationNode(NumericValue);
NumericValue m_value;
};
class SumCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<SumCalculationNode> create(Vector<NonnullOwnPtr<CalculationNode>>);
~SumCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
explicit SumCalculationNode(Vector<NonnullOwnPtr<CalculationNode>>);
Vector<NonnullOwnPtr<CalculationNode>> m_values;
};
class ProductCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<ProductCalculationNode> create(Vector<NonnullOwnPtr<CalculationNode>>);
~ProductCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
explicit ProductCalculationNode(Vector<NonnullOwnPtr<CalculationNode>>);
Vector<NonnullOwnPtr<CalculationNode>> m_values;
};
class NegateCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<NegateCalculationNode> create(NonnullOwnPtr<CalculationNode>);
~NegateCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
explicit NegateCalculationNode(NonnullOwnPtr<CalculationNode>);
NonnullOwnPtr<CalculationNode> m_value;
};
class InvertCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<InvertCalculationNode> create(NonnullOwnPtr<CalculationNode>);
~InvertCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
explicit InvertCalculationNode(NonnullOwnPtr<CalculationNode>);
NonnullOwnPtr<CalculationNode> m_value;
};
class MinCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<MinCalculationNode> create(Vector<NonnullOwnPtr<CalculationNode>>);
~MinCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
explicit MinCalculationNode(Vector<NonnullOwnPtr<CalculationNode>>);
Vector<NonnullOwnPtr<CalculationNode>> m_values;
};
class MaxCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<MaxCalculationNode> create(Vector<NonnullOwnPtr<CalculationNode>>);
~MaxCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
explicit MaxCalculationNode(Vector<NonnullOwnPtr<CalculationNode>>);
Vector<NonnullOwnPtr<CalculationNode>> m_values;
};
class ClampCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<ClampCalculationNode> create(NonnullOwnPtr<CalculationNode>, NonnullOwnPtr<CalculationNode>, NonnullOwnPtr<CalculationNode>);
~ClampCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
explicit ClampCalculationNode(NonnullOwnPtr<CalculationNode>, NonnullOwnPtr<CalculationNode>, NonnullOwnPtr<CalculationNode>);
NonnullOwnPtr<CalculationNode> m_min_value;
NonnullOwnPtr<CalculationNode> m_center_value;
NonnullOwnPtr<CalculationNode> m_max_value;
};
class AbsCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<AbsCalculationNode> create(NonnullOwnPtr<CalculationNode>);
~AbsCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
AbsCalculationNode(NonnullOwnPtr<CalculationNode>);
NonnullOwnPtr<CalculationNode> m_value;
};
class SignCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<SignCalculationNode> create(NonnullOwnPtr<CalculationNode>);
~SignCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
SignCalculationNode(NonnullOwnPtr<CalculationNode>);
NonnullOwnPtr<CalculationNode> m_value;
};
class ConstantCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<ConstantCalculationNode> create(CalculationNode::ConstantType);
~ConstantCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override { return false; }
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&> context, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
ConstantCalculationNode(ConstantType);
CalculationNode::ConstantType m_constant;
};
class SinCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<SinCalculationNode> create(NonnullOwnPtr<CalculationNode>);
~SinCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
SinCalculationNode(NonnullOwnPtr<CalculationNode>);
NonnullOwnPtr<CalculationNode> m_value;
};
class CosCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<CosCalculationNode> create(NonnullOwnPtr<CalculationNode>);
~CosCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
CosCalculationNode(NonnullOwnPtr<CalculationNode>);
NonnullOwnPtr<CalculationNode> m_value;
};
class TanCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<TanCalculationNode> create(NonnullOwnPtr<CalculationNode>);
~TanCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
TanCalculationNode(NonnullOwnPtr<CalculationNode>);
NonnullOwnPtr<CalculationNode> m_value;
};
class AsinCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<AsinCalculationNode> create(NonnullOwnPtr<CalculationNode>);
~AsinCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
AsinCalculationNode(NonnullOwnPtr<CalculationNode>);
NonnullOwnPtr<CalculationNode> m_value;
};
class AcosCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<AcosCalculationNode> create(NonnullOwnPtr<CalculationNode>);
~AcosCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
AcosCalculationNode(NonnullOwnPtr<CalculationNode>);
NonnullOwnPtr<CalculationNode> m_value;
};
class AtanCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<AtanCalculationNode> create(NonnullOwnPtr<CalculationNode>);
~AtanCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
AtanCalculationNode(NonnullOwnPtr<CalculationNode>);
NonnullOwnPtr<CalculationNode> m_value;
};
class Atan2CalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<Atan2CalculationNode> create(NonnullOwnPtr<CalculationNode>, NonnullOwnPtr<CalculationNode>);
~Atan2CalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
Atan2CalculationNode(NonnullOwnPtr<CalculationNode>, NonnullOwnPtr<CalculationNode>);
NonnullOwnPtr<CalculationNode> m_y;
NonnullOwnPtr<CalculationNode> m_x;
};
class PowCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<PowCalculationNode> create(NonnullOwnPtr<CalculationNode>, NonnullOwnPtr<CalculationNode>);
~PowCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override { return false; }
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
explicit PowCalculationNode(NonnullOwnPtr<CalculationNode>, NonnullOwnPtr<CalculationNode>);
NonnullOwnPtr<CalculationNode> m_x;
NonnullOwnPtr<CalculationNode> m_y;
};
class SqrtCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<SqrtCalculationNode> create(NonnullOwnPtr<CalculationNode>);
~SqrtCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override { return false; }
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
SqrtCalculationNode(NonnullOwnPtr<CalculationNode>);
NonnullOwnPtr<CalculationNode> m_value;
};
class HypotCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<HypotCalculationNode> create(Vector<NonnullOwnPtr<CalculationNode>>);
~HypotCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
explicit HypotCalculationNode(Vector<NonnullOwnPtr<CalculationNode>>);
Vector<NonnullOwnPtr<CalculationNode>> m_values;
};
class LogCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<LogCalculationNode> create(NonnullOwnPtr<CalculationNode>, NonnullOwnPtr<CalculationNode>);
~LogCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override { return false; }
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
LogCalculationNode(NonnullOwnPtr<CalculationNode>, NonnullOwnPtr<CalculationNode>);
NonnullOwnPtr<CalculationNode> m_x;
NonnullOwnPtr<CalculationNode> m_y;
};
class ExpCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<ExpCalculationNode> create(NonnullOwnPtr<CalculationNode>);
~ExpCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override { return false; }
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
ExpCalculationNode(NonnullOwnPtr<CalculationNode>);
NonnullOwnPtr<CalculationNode> m_value;
};
class RoundCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<RoundCalculationNode> create(RoundingStrategy, NonnullOwnPtr<CalculationNode>, NonnullOwnPtr<CalculationNode>);
~RoundCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
RoundCalculationNode(RoundingStrategy, NonnullOwnPtr<CalculationNode>, NonnullOwnPtr<CalculationNode>);
RoundingStrategy m_strategy;
NonnullOwnPtr<CalculationNode> m_x;
NonnullOwnPtr<CalculationNode> m_y;
};
class ModCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<ModCalculationNode> create(NonnullOwnPtr<CalculationNode>, NonnullOwnPtr<CalculationNode>);
~ModCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
ModCalculationNode(NonnullOwnPtr<CalculationNode>, NonnullOwnPtr<CalculationNode>);
NonnullOwnPtr<CalculationNode> m_x;
NonnullOwnPtr<CalculationNode> m_y;
};
class RemCalculationNode final : public CalculationNode {
public:
static NonnullOwnPtr<RemCalculationNode> create(NonnullOwnPtr<CalculationNode>, NonnullOwnPtr<CalculationNode>);
~RemCalculationNode();
virtual String to_string() const override;
virtual Optional<CSSMathValue::ResolvedType> resolved_type() const override;
virtual Optional<CSSNumericType> determine_type(PropertyID) const override;
virtual bool contains_percentage() const override;
virtual CSSMathValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CSSMathValue::PercentageBasis const&) const override;
virtual void dump(StringBuilder&, int indent) const override;
virtual bool equals(CalculationNode const&) const override;
private:
RemCalculationNode(NonnullOwnPtr<CalculationNode>, NonnullOwnPtr<CalculationNode>);
NonnullOwnPtr<CalculationNode> m_x;
NonnullOwnPtr<CalculationNode> m_y;
};
}