Skip to content

Commit 5727e27

Browse files
stelar7AtkinsSJ
authored andcommitted
LibWeb: Implement CSS exp()
1 parent 6dde494 commit 5727e27

File tree

4 files changed

+94
-0
lines changed

4 files changed

+94
-0
lines changed

Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3940,6 +3940,29 @@ ErrorOr<OwnPtr<CalculationNode>> Parser::parse_log_function(Function const& func
39403940
return TRY(LogCalculationNode::create(node_a.release_nonnull(), node_b.release_nonnull()));
39413941
}
39423942

3943+
ErrorOr<OwnPtr<CalculationNode>> Parser::parse_exp_function(Function const& function)
3944+
{
3945+
auto node_a = TRY(parse_a_calculation(function.values()));
3946+
if (!node_a) {
3947+
dbgln_if(CSS_PARSER_DEBUG, "exp() parameter must be valid calculation"sv);
3948+
return nullptr;
3949+
}
3950+
3951+
auto maybe_parameter_type = node_a->resolved_type();
3952+
if (!maybe_parameter_type.has_value()) {
3953+
dbgln_if(CSS_PARSER_DEBUG, "Failed to resolve type for exp() parameter"sv);
3954+
return nullptr;
3955+
}
3956+
3957+
auto resolved_type = maybe_parameter_type.value();
3958+
if (resolved_type != CalculatedStyleValue::ResolvedType::Number) {
3959+
dbgln_if(CSS_PARSER_DEBUG, "exp() parameter must be number"sv);
3960+
return nullptr;
3961+
}
3962+
3963+
return TRY(ExpCalculationNode::create(node_a.release_nonnull()));
3964+
}
3965+
39433966
ErrorOr<RefPtr<StyleValue>> Parser::parse_dynamic_value(ComponentValue const& component_value)
39443967
{
39453968
if (component_value.is_function()) {
@@ -4017,6 +4040,9 @@ ErrorOr<OwnPtr<CalculationNode>> Parser::parse_a_calc_function_node(Function con
40174040
if (function.name().equals_ignoring_ascii_case("log"sv))
40184041
return TRY(parse_log_function(function));
40194042

4043+
if (function.name().equals_ignoring_ascii_case("exp"sv))
4044+
return TRY(parse_exp_function(function));
4045+
40204046
dbgln_if(CSS_PARSER_DEBUG, "We didn't implement `{}` function yet", function.name());
40214047
return nullptr;
40224048
}

Userland/Libraries/LibWeb/CSS/Parser/Parser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ class Parser {
306306
ErrorOr<OwnPtr<CalculationNode>> parse_sqrt_function(Function const&);
307307
ErrorOr<OwnPtr<CalculationNode>> parse_hypot_function(Function const&);
308308
ErrorOr<OwnPtr<CalculationNode>> parse_log_function(Function const&);
309+
ErrorOr<OwnPtr<CalculationNode>> parse_exp_function(Function const&);
309310
ErrorOr<RefPtr<StyleValue>> parse_dimension_value(ComponentValue const&);
310311
ErrorOr<RefPtr<StyleValue>> parse_integer_value(TokenStream<ComponentValue>&);
311312
ErrorOr<RefPtr<StyleValue>> parse_number_value(TokenStream<ComponentValue>&);

Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,6 +1478,55 @@ ErrorOr<void> LogCalculationNode::dump(StringBuilder& builder, int indent) const
14781478
return {};
14791479
}
14801480

1481+
ErrorOr<NonnullOwnPtr<ExpCalculationNode>> ExpCalculationNode::create(NonnullOwnPtr<CalculationNode> value)
1482+
{
1483+
return adopt_nonnull_own_or_enomem(new (nothrow) ExpCalculationNode(move(value)));
1484+
}
1485+
1486+
ExpCalculationNode::ExpCalculationNode(NonnullOwnPtr<CalculationNode> value)
1487+
: CalculationNode(Type::Exp)
1488+
, m_value(move(value))
1489+
{
1490+
}
1491+
1492+
ExpCalculationNode::~ExpCalculationNode() = default;
1493+
1494+
ErrorOr<String> ExpCalculationNode::to_string() const
1495+
{
1496+
StringBuilder builder;
1497+
builder.append("exp("sv);
1498+
builder.append(TRY(m_value->to_string()));
1499+
builder.append(")"sv);
1500+
return builder.to_string();
1501+
}
1502+
1503+
Optional<CalculatedStyleValue::ResolvedType> ExpCalculationNode::resolved_type() const
1504+
{
1505+
return CalculatedStyleValue::ResolvedType::Number;
1506+
}
1507+
1508+
CalculatedStyleValue::CalculationResult ExpCalculationNode::resolve(Optional<Length::ResolutionContext const&> context, CalculatedStyleValue::PercentageBasis const& percentage_basis) const
1509+
{
1510+
auto node_a = m_value->resolve(context, percentage_basis);
1511+
auto node_a_value = resolve_value(node_a.value(), context);
1512+
auto result = exp(node_a_value);
1513+
1514+
return { Number(Number::Type::Number, result) };
1515+
}
1516+
1517+
ErrorOr<void> ExpCalculationNode::for_each_child_node(Function<ErrorOr<void>(NonnullOwnPtr<CalculationNode>&)> const& callback)
1518+
{
1519+
TRY(m_value->for_each_child_node(callback));
1520+
TRY(callback(m_value));
1521+
return {};
1522+
}
1523+
1524+
ErrorOr<void> ExpCalculationNode::dump(StringBuilder& builder, int indent) const
1525+
{
1526+
TRY(builder.try_appendff("{: >{}}EXP: {}\n", "", indent, TRY(to_string())));
1527+
return {};
1528+
}
1529+
14811530
void CalculatedStyleValue::CalculationResult::add(CalculationResult const& other, Optional<Length::ResolutionContext const&> context, PercentageBasis const& percentage_basis)
14821531
{
14831532
add_or_subtract_internal(SumOperation::Add, other, context, percentage_basis);

Userland/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,4 +605,22 @@ class LogCalculationNode final : public CalculationNode {
605605
NonnullOwnPtr<CalculationNode> m_y;
606606
};
607607

608+
class ExpCalculationNode final : public CalculationNode {
609+
public:
610+
static ErrorOr<NonnullOwnPtr<ExpCalculationNode>> create(NonnullOwnPtr<CalculationNode>);
611+
~ExpCalculationNode();
612+
613+
virtual ErrorOr<String> to_string() const override;
614+
virtual Optional<CalculatedStyleValue::ResolvedType> resolved_type() const override;
615+
virtual bool contains_percentage() const override { return false; };
616+
virtual CalculatedStyleValue::CalculationResult resolve(Optional<Length::ResolutionContext const&>, CalculatedStyleValue::PercentageBasis const&) const override;
617+
virtual ErrorOr<void> for_each_child_node(Function<ErrorOr<void>(NonnullOwnPtr<CalculationNode>&)> const&) override;
618+
619+
virtual ErrorOr<void> dump(StringBuilder&, int indent) const override;
620+
621+
private:
622+
ExpCalculationNode(NonnullOwnPtr<CalculationNode>);
623+
NonnullOwnPtr<CalculationNode> m_value;
624+
};
625+
608626
}

0 commit comments

Comments
 (0)