mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 20:29:18 +00:00
LibWeb/CSS: Use NumericCalculationNode for constants
Having multiple kinds of node that hold numeric values made things more complicated than they needed to be, and we were already converting ConstantCalculationNodes to NumericCalculationNodes in the first simplification pass that happens at parse-time, so they didn't exist after that. As noted, the spec allows for other contexts to introduce their own numeric keywords, which might be resolved later than parse-time. We'll need a different mechanism to support those, but ConstantCalculationNode could not have done so anyway.
This commit is contained in:
parent
7b13ccabd4
commit
f97ac33cb3
Notes:
github-actions[bot]
2025-02-27 20:43:53 +00:00
Author: https://github.com/AtkinsSJ
Commit: f97ac33cb3
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3719
6 changed files with 45 additions and 140 deletions
|
@ -129,26 +129,6 @@ static NonnullRefPtr<CalculationNode> simplify_2_children(T const& original, Non
|
|||
return original;
|
||||
}
|
||||
|
||||
Optional<CalculationNode::ConstantType> CalculationNode::constant_type_from_string(StringView string)
|
||||
{
|
||||
if (string.equals_ignoring_ascii_case("e"sv))
|
||||
return CalculationNode::ConstantType::E;
|
||||
|
||||
if (string.equals_ignoring_ascii_case("pi"sv))
|
||||
return CalculationNode::ConstantType::Pi;
|
||||
|
||||
if (string.equals_ignoring_ascii_case("infinity"sv))
|
||||
return CalculationNode::ConstantType::Infinity;
|
||||
|
||||
if (string.equals_ignoring_ascii_case("-infinity"sv))
|
||||
return CalculationNode::ConstantType::MinusInfinity;
|
||||
|
||||
if (string.equals_ignoring_ascii_case("NaN"sv))
|
||||
return CalculationNode::ConstantType::NaN;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
CalculationNode::CalculationNode(Type type, Optional<CSSNumericType> numeric_type)
|
||||
: m_type(type)
|
||||
, m_numeric_type(move(numeric_type))
|
||||
|
@ -228,6 +208,29 @@ NonnullRefPtr<NumericCalculationNode> NumericCalculationNode::create(NumericValu
|
|||
return adopt_ref(*new (nothrow) NumericCalculationNode(move(value), numeric_type));
|
||||
}
|
||||
|
||||
RefPtr<NumericCalculationNode> NumericCalculationNode::from_keyword(Keyword keyword, CalculationContext const& context)
|
||||
{
|
||||
switch (keyword) {
|
||||
case Keyword::E:
|
||||
// https://drafts.csswg.org/css-values-4/#valdef-calc-e
|
||||
return create(Number { Number::Type::Number, AK::E<double> }, context);
|
||||
case Keyword::Pi:
|
||||
// https://drafts.csswg.org/css-values-4/#valdef-calc-pi
|
||||
return create(Number { Number::Type::Number, AK::Pi<double> }, context);
|
||||
case Keyword::Infinity:
|
||||
// https://drafts.csswg.org/css-values-4/#valdef-calc-infinity
|
||||
return create(Number { Number::Type::Number, AK::Infinity<double> }, context);
|
||||
case Keyword::NegativeInfinity:
|
||||
// https://drafts.csswg.org/css-values-4/#valdef-calc--infinity
|
||||
return create(Number { Number::Type::Number, -AK::Infinity<double> }, context);
|
||||
case Keyword::Nan:
|
||||
// https://drafts.csswg.org/css-values-4/#valdef-calc-nan
|
||||
return create(Number { Number::Type::Number, AK::NaN<double> }, context);
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
NumericCalculationNode::NumericCalculationNode(NumericValue value, CSSNumericType numeric_type)
|
||||
: CalculationNode(Type::Numeric, move(numeric_type))
|
||||
, m_value(move(value))
|
||||
|
@ -1114,73 +1117,6 @@ bool SignCalculationNode::equals(CalculationNode const& other) const
|
|||
return m_value->equals(*static_cast<SignCalculationNode const&>(other).m_value);
|
||||
}
|
||||
|
||||
NonnullRefPtr<ConstantCalculationNode> ConstantCalculationNode::create(ConstantType constant)
|
||||
{
|
||||
return adopt_ref(*new (nothrow) ConstantCalculationNode(constant));
|
||||
}
|
||||
|
||||
ConstantCalculationNode::ConstantCalculationNode(ConstantType constant)
|
||||
// https://www.w3.org/TR/css-values-4/#determine-the-type-of-a-calculation
|
||||
// Anything else is a terminal value, whose type is determined based on its CSS type:
|
||||
// -> <calc-constant>
|
||||
// the type is «[ ]» (empty map)
|
||||
: CalculationNode(Type::Constant, CSSNumericType {})
|
||||
, m_constant(constant)
|
||||
{
|
||||
}
|
||||
|
||||
ConstantCalculationNode::~ConstantCalculationNode() = default;
|
||||
|
||||
String ConstantCalculationNode::to_string() const
|
||||
{
|
||||
switch (m_constant) {
|
||||
case CalculationNode::ConstantType::E:
|
||||
return "e"_string;
|
||||
case CalculationNode::ConstantType::Pi:
|
||||
return "pi"_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();
|
||||
}
|
||||
|
||||
CalculatedStyleValue::CalculationResult ConstantCalculationNode::resolve(CalculationResolutionContext const&) const
|
||||
{
|
||||
switch (m_constant) {
|
||||
case ConstantType::E:
|
||||
return { AK::E<double>, CSSNumericType {} };
|
||||
case ConstantType::Pi:
|
||||
return { AK::Pi<double>, CSSNumericType {} };
|
||||
case ConstantType::Infinity:
|
||||
return { AK::Infinity<double>, CSSNumericType {} };
|
||||
case ConstantType::MinusInfinity:
|
||||
return { -AK::Infinity<double>, CSSNumericType {} };
|
||||
case ConstantType::NaN:
|
||||
return { AK::NaN<double>, CSSNumericType {} };
|
||||
}
|
||||
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
void ConstantCalculationNode::dump(StringBuilder& builder, int indent) const
|
||||
{
|
||||
builder.appendff("{: >{}}CONSTANT: {}\n", "", indent, to_string());
|
||||
}
|
||||
|
||||
bool ConstantCalculationNode::equals(CalculationNode const& other) const
|
||||
{
|
||||
if (this == &other)
|
||||
return true;
|
||||
if (type() != other.type())
|
||||
return false;
|
||||
return m_constant == static_cast<ConstantCalculationNode const&>(other).m_constant;
|
||||
}
|
||||
|
||||
NonnullRefPtr<SinCalculationNode> SinCalculationNode::create(NonnullRefPtr<CalculationNode> value)
|
||||
{
|
||||
return adopt_ref(*new (nothrow) SinCalculationNode(move(value)));
|
||||
|
@ -2795,24 +2731,13 @@ NonnullRefPtr<CalculationNode> simplify_a_calculation_tree(CalculationNode const
|
|||
}
|
||||
|
||||
// 3. If root is a <calc-keyword> that can be resolved, return what it resolves to, simplified.
|
||||
// NOTE: This is handled below.
|
||||
// NOTE: We already resolve our `<calc-keyword>`s at parse-time.
|
||||
// FIXME: Revisit this once we support any keywords that need resolving later.
|
||||
|
||||
// 4. Otherwise, return root.
|
||||
return root;
|
||||
}
|
||||
|
||||
// AD-HOC: Step 1.3 is done here as we have a separate node type for them.
|
||||
if (root->type() == CalculationNode::Type::Constant) {
|
||||
auto const& root_constant = as<ConstantCalculationNode>(*root);
|
||||
|
||||
// 3. If root is a <calc-keyword> that can be resolved, return what it resolves to, simplified.
|
||||
// FIXME: At the moment these are all constant numbers. Revisit this once that's not the case.
|
||||
// (Notably, relative-color syntax allows some other keywords that are relative to the color.)
|
||||
auto resolved = root_constant.resolve(resolution_context);
|
||||
VERIFY(resolved.type()->matches_number({}));
|
||||
return NumericCalculationNode::create(Number { Number::Type::Number, resolved.value() }, context);
|
||||
}
|
||||
|
||||
// 2. If root is any other leaf node (not an operator node):
|
||||
// FIXME: We don't yet allow any of these inside a calculation tree. Revisit once we do.
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue