mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-21 08:48:57 +00:00
LibWeb/CSS: Implement "Create a sum value"
This commit is contained in:
parent
1c952b01ac
commit
80abffd2e8
Notes:
github-actions[bot]
2025-09-12 11:46:44 +00:00
Author: https://github.com/AtkinsSJ
Commit: 80abffd2e8
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6162
Reviewed-by: https://github.com/gmta ✅
17 changed files with 320 additions and 1 deletions
|
@ -105,7 +105,7 @@ GC::Ref<CSSNumericValue> CSSMathClamp::upper() const
|
||||||
// https://drafts.css-houdini.org/css-typed-om-1/#equal-numeric-value
|
// https://drafts.css-houdini.org/css-typed-om-1/#equal-numeric-value
|
||||||
bool CSSMathClamp::is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const
|
bool CSSMathClamp::is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const
|
||||||
{
|
{
|
||||||
// AD-HOC: Spec doesn't handle clamp()
|
// AD-HOC: Spec doesn't handle clamp(). https://github.com/w3c/css-houdini-drafts/issues/1152
|
||||||
// 1. If value1 and value2 are not members of the same interface, return false.
|
// 1. If value1 and value2 are not members of the same interface, return false.
|
||||||
auto* other_clamp = as_if<CSSMathClamp>(*other);
|
auto* other_clamp = as_if<CSSMathClamp>(*other);
|
||||||
if (!other_clamp)
|
if (!other_clamp)
|
||||||
|
@ -116,4 +116,34 @@ bool CSSMathClamp::is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const
|
||||||
&& m_upper->is_equal_numeric_value(other_clamp->m_upper);
|
&& m_upper->is_equal_numeric_value(other_clamp->m_upper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://drafts.css-houdini.org/css-typed-om-1/#create-a-sum-value
|
||||||
|
Optional<SumValue> CSSMathClamp::create_a_sum_value() const
|
||||||
|
{
|
||||||
|
// AD-HOC: There is no spec for this. https://github.com/w3c/css-houdini-drafts/issues/1152
|
||||||
|
// So, basing it on the spec for CSSMathMin.
|
||||||
|
|
||||||
|
// Create sum values from lower, value, and upper.
|
||||||
|
auto lower = m_lower->create_a_sum_value();
|
||||||
|
auto value = m_value->create_a_sum_value();
|
||||||
|
auto upper = m_upper->create_a_sum_value();
|
||||||
|
|
||||||
|
// If any of those are failure, or has a length greater than one, return failure.
|
||||||
|
if (!lower.has_value() || lower->size() > 1
|
||||||
|
|| !value.has_value() || value->size() > 1
|
||||||
|
|| !upper.has_value() || upper->size() > 1)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// If not all their unit maps are identical, return failure.
|
||||||
|
if (lower->first().unit_map != value->first().unit_map || value->first().unit_map != upper->first().unit_map)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// Return value clamped between lower and upper.
|
||||||
|
return SumValue {
|
||||||
|
SumValueItem {
|
||||||
|
clamp(value->first().value, lower->first().value, upper->first().value),
|
||||||
|
value->first().unit_map,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ public:
|
||||||
|
|
||||||
virtual String serialize_math_value(Nested, Parens) const override;
|
virtual String serialize_math_value(Nested, Parens) const override;
|
||||||
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
|
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
|
||||||
|
virtual Optional<SumValue> create_a_sum_value() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CSSMathClamp(JS::Realm&, NumericType, GC::Ref<CSSNumericValue> lower, GC::Ref<CSSNumericValue> value, GC::Ref<CSSNumericValue> upper);
|
CSSMathClamp(JS::Realm&, NumericType, GC::Ref<CSSNumericValue> lower, GC::Ref<CSSNumericValue> value, GC::Ref<CSSNumericValue> upper);
|
||||||
|
|
|
@ -106,4 +106,29 @@ bool CSSMathInvert::is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const
|
||||||
return m_value->is_equal_numeric_value(other_invert->m_value);
|
return m_value->is_equal_numeric_value(other_invert->m_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://drafts.css-houdini.org/css-typed-om-1/#create-a-sum-value
|
||||||
|
Optional<SumValue> CSSMathInvert::create_a_sum_value() const
|
||||||
|
{
|
||||||
|
// 1. Let values be the result of creating a sum value from this’s value internal slot.
|
||||||
|
auto values = m_value->create_a_sum_value();
|
||||||
|
|
||||||
|
// 2. If values is failure, return failure.
|
||||||
|
if (!values.has_value())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// 3. If the length of values is more than one, return failure.
|
||||||
|
if (values->size() > 1)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// 4. Invert (find the reciprocal of) the value of the item in values, and negate the value of each entry in its unit map.
|
||||||
|
for (auto& [value, unit_map] : *values) {
|
||||||
|
value = 1.0 / value;
|
||||||
|
for (auto& [_, power] : unit_map)
|
||||||
|
power = -power;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Return values.
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ public:
|
||||||
|
|
||||||
virtual String serialize_math_value(Nested, Parens) const override;
|
virtual String serialize_math_value(Nested, Parens) const override;
|
||||||
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
|
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
|
||||||
|
virtual Optional<SumValue> create_a_sum_value() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CSSMathInvert(JS::Realm&, NumericType, GC::Ref<CSSNumericValue>);
|
CSSMathInvert(JS::Realm&, NumericType, GC::Ref<CSSNumericValue>);
|
||||||
|
|
|
@ -129,4 +129,32 @@ bool CSSMathMax::is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const
|
||||||
return m_values->is_equal_numeric_values(other_max->m_values);
|
return m_values->is_equal_numeric_values(other_max->m_values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://drafts.css-houdini.org/css-typed-om-1/#create-a-sum-value
|
||||||
|
Optional<SumValue> CSSMathMax::create_a_sum_value() const
|
||||||
|
{
|
||||||
|
// 1. Let args be the result of creating a sum value for each item in this’s values internal slot.
|
||||||
|
Vector<Optional<SumValue>> args;
|
||||||
|
args.ensure_capacity(m_values->length());
|
||||||
|
for (auto const& value : m_values->values()) {
|
||||||
|
args.unchecked_append(value->create_a_sum_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<SumValue> item_with_largest_value = args.first();
|
||||||
|
for (auto const& item : args) {
|
||||||
|
// 2. If any item of args is failure, or has a length greater than one, return failure.
|
||||||
|
if (!item.has_value() || item->size() > 1)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// 3. If not all of the unit maps among the items of args are identical, return failure.
|
||||||
|
if (item->first().unit_map != item_with_largest_value->first().unit_map)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
if (item->first().value > item_with_largest_value->first().value)
|
||||||
|
item_with_largest_value = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Return the item of args whose sole item has the largest value.
|
||||||
|
return item_with_largest_value;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ public:
|
||||||
|
|
||||||
virtual String serialize_math_value(Nested, Parens) const override;
|
virtual String serialize_math_value(Nested, Parens) const override;
|
||||||
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
|
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
|
||||||
|
virtual Optional<SumValue> create_a_sum_value() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CSSMathMax(JS::Realm&, NumericType, GC::Ref<CSSNumericArray>);
|
CSSMathMax(JS::Realm&, NumericType, GC::Ref<CSSNumericArray>);
|
||||||
|
|
|
@ -130,4 +130,32 @@ bool CSSMathMin::is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const
|
||||||
return m_values->is_equal_numeric_values(other_min->m_values);
|
return m_values->is_equal_numeric_values(other_min->m_values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://drafts.css-houdini.org/css-typed-om-1/#create-a-sum-value
|
||||||
|
Optional<SumValue> CSSMathMin::create_a_sum_value() const
|
||||||
|
{
|
||||||
|
// 1. Let args be the result of creating a sum value for each item in this’s values internal slot.
|
||||||
|
Vector<Optional<SumValue>> args;
|
||||||
|
args.ensure_capacity(m_values->length());
|
||||||
|
for (auto const& value : m_values->values()) {
|
||||||
|
args.unchecked_append(value->create_a_sum_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<SumValue> item_with_smallest_value = args.first();
|
||||||
|
for (auto const& item : args) {
|
||||||
|
// 2. If any item of args is failure, or has a length greater than one, return failure.
|
||||||
|
if (!item.has_value() || item->size() > 1)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// 3. If not all of the unit maps among the items of args are identical, return failure.
|
||||||
|
if (item->first().unit_map != item_with_smallest_value->first().unit_map)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
if (item->first().value < item_with_smallest_value->first().value)
|
||||||
|
item_with_smallest_value = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Return the item of args whose sole item has the smallest value.
|
||||||
|
return item_with_smallest_value;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ public:
|
||||||
|
|
||||||
virtual String serialize_math_value(Nested, Parens) const override;
|
virtual String serialize_math_value(Nested, Parens) const override;
|
||||||
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
|
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
|
||||||
|
virtual Optional<SumValue> create_a_sum_value() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CSSMathMin(JS::Realm&, NumericType, GC::Ref<CSSNumericArray>);
|
CSSMathMin(JS::Realm&, NumericType, GC::Ref<CSSNumericArray>);
|
||||||
|
|
|
@ -103,4 +103,22 @@ bool CSSMathNegate::is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const
|
||||||
return m_value->is_equal_numeric_value(other_negate->m_value);
|
return m_value->is_equal_numeric_value(other_negate->m_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://drafts.css-houdini.org/css-typed-om-1/#create-a-sum-value
|
||||||
|
Optional<SumValue> CSSMathNegate::create_a_sum_value() const
|
||||||
|
{
|
||||||
|
// 1. Let values be the result of creating a sum value from this’s value internal slot.
|
||||||
|
auto values = m_value->create_a_sum_value();
|
||||||
|
|
||||||
|
// 2. If values is failure, return failure.
|
||||||
|
if (!values.has_value())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// 3. Negate the value of each item of values.
|
||||||
|
for (auto& value : *values)
|
||||||
|
value.value = -value.value;
|
||||||
|
|
||||||
|
// 4. Return values.
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ public:
|
||||||
|
|
||||||
virtual String serialize_math_value(Nested, Parens) const override;
|
virtual String serialize_math_value(Nested, Parens) const override;
|
||||||
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
|
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
|
||||||
|
virtual Optional<SumValue> create_a_sum_value() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CSSMathNegate(JS::Realm&, NumericType, GC::Ref<CSSNumericValue>);
|
CSSMathNegate(JS::Realm&, NumericType, GC::Ref<CSSNumericValue>);
|
||||||
|
|
|
@ -152,4 +152,46 @@ bool CSSMathProduct::is_equal_numeric_value(GC::Ref<CSSNumericValue> other) cons
|
||||||
return m_values->is_equal_numeric_values(other_product->m_values);
|
return m_values->is_equal_numeric_values(other_product->m_values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://drafts.css-houdini.org/css-typed-om-1/#create-a-sum-value
|
||||||
|
Optional<SumValue> CSSMathProduct::create_a_sum_value() const
|
||||||
|
{
|
||||||
|
// 1. Let values initially be the sum value «(1, «[ ]»)». (I.e. what you’d get from 1.)
|
||||||
|
SumValue values {
|
||||||
|
SumValueItem { 1, {} }
|
||||||
|
};
|
||||||
|
|
||||||
|
// 2. For each item in this’s values internal slot:
|
||||||
|
for (auto const& item : m_values->values()) {
|
||||||
|
// 1. Let new values be the result of creating a sum value from item.
|
||||||
|
// Let temp initially be an empty list.
|
||||||
|
auto new_values = item->create_a_sum_value();
|
||||||
|
SumValue temp;
|
||||||
|
|
||||||
|
// 2. If new values is failure, return failure.
|
||||||
|
if (!new_values.has_value())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// 3. For each item1 in values:
|
||||||
|
for (auto const& item1 : values) {
|
||||||
|
// 1. For each item2 in new values:
|
||||||
|
for (auto const& item2 : *new_values) {
|
||||||
|
// 1. Let item be a tuple with its value set to the product of the values of item1 and item2, and its
|
||||||
|
// unit map set to the product of the unit maps of item1 and item2, with all entries with a zero
|
||||||
|
// value removed.
|
||||||
|
auto unit_map = product_of_two_unit_maps(item1.unit_map, item2.unit_map);
|
||||||
|
unit_map.remove_all_matching([](auto&, auto& value) { return value == 0; });
|
||||||
|
|
||||||
|
// 2. Append item to temp.
|
||||||
|
temp.empend(item1.value * item2.value, move(unit_map));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Set values to temp.
|
||||||
|
values = move(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Return values.
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ public:
|
||||||
|
|
||||||
virtual String serialize_math_value(Nested, Parens) const override;
|
virtual String serialize_math_value(Nested, Parens) const override;
|
||||||
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
|
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
|
||||||
|
virtual Optional<SumValue> create_a_sum_value() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CSSMathProduct(JS::Realm&, NumericType, GC::Ref<CSSNumericArray>);
|
CSSMathProduct(JS::Realm&, NumericType, GC::Ref<CSSNumericArray>);
|
||||||
|
|
|
@ -151,4 +151,59 @@ bool CSSMathSum::is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const
|
||||||
return m_values->is_equal_numeric_values(other_sum->m_values);
|
return m_values->is_equal_numeric_values(other_sum->m_values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://drafts.css-houdini.org/css-typed-om-1/#create-a-sum-value
|
||||||
|
Optional<SumValue> CSSMathSum::create_a_sum_value() const
|
||||||
|
{
|
||||||
|
// 1. Let values initially be an empty list.
|
||||||
|
SumValue values;
|
||||||
|
|
||||||
|
// 2. For each item in this’s values internal slot:
|
||||||
|
for (auto const item : m_values->values()) {
|
||||||
|
// 1. Let value be the result of creating a sum value from item. If value is failure, return failure.
|
||||||
|
auto maybe_value = item->create_a_sum_value();
|
||||||
|
if (!maybe_value.has_value())
|
||||||
|
return {};
|
||||||
|
auto const& value = maybe_value.value();
|
||||||
|
|
||||||
|
// 2. For each subvalue of value:
|
||||||
|
for (auto const& subvalue : value) {
|
||||||
|
// 1. If values already contains an item with the same unit map as subvalue, increment that item’s value by
|
||||||
|
// the value of subvalue.
|
||||||
|
auto existing_item = values.find_if([&subvalue](SumValueItem const& other) {
|
||||||
|
return subvalue.unit_map == other.unit_map;
|
||||||
|
});
|
||||||
|
if (existing_item != values.end()) {
|
||||||
|
existing_item->value += subvalue.value;
|
||||||
|
}
|
||||||
|
// 2. Otherwise, append subvalue to values.
|
||||||
|
else {
|
||||||
|
values.append(subvalue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Create a type from the unit map of each item of values, and add all the types together.
|
||||||
|
// If the result is failure, return failure.
|
||||||
|
auto added_type = NumericType::create_from_unit_map(values.first().unit_map);
|
||||||
|
if (!added_type.has_value())
|
||||||
|
return {};
|
||||||
|
bool first = true;
|
||||||
|
for (auto const& [_, unit_map] : values) {
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto type = NumericType::create_from_unit_map(unit_map);
|
||||||
|
if (!type.has_value())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
added_type = added_type->added_to(type.value());
|
||||||
|
if (!added_type.has_value())
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Return values.
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ public:
|
||||||
|
|
||||||
virtual String serialize_math_value(Nested, Parens) const override;
|
virtual String serialize_math_value(Nested, Parens) const override;
|
||||||
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
|
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
|
||||||
|
virtual Optional<SumValue> create_a_sum_value() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CSSMathSum(JS::Realm&, NumericType, GC::Ref<CSSNumericArray>);
|
CSSMathSum(JS::Realm&, NumericType, GC::Ref<CSSNumericArray>);
|
||||||
|
|
|
@ -28,6 +28,13 @@ struct CSSNumericType {
|
||||||
// https://drafts.css-houdini.org/css-typed-om-1/#typedefdef-cssnumberish
|
// https://drafts.css-houdini.org/css-typed-om-1/#typedefdef-cssnumberish
|
||||||
using CSSNumberish = Variant<double, GC::Root<CSSNumericValue>>;
|
using CSSNumberish = Variant<double, GC::Root<CSSNumericValue>>;
|
||||||
|
|
||||||
|
// https://drafts.css-houdini.org/css-typed-om-1/#cssnumericvalue-sum-value
|
||||||
|
struct SumValueItem {
|
||||||
|
double value;
|
||||||
|
UnitMap unit_map;
|
||||||
|
};
|
||||||
|
using SumValue = Vector<SumValueItem>;
|
||||||
|
|
||||||
// https://drafts.css-houdini.org/css-typed-om-1/#cssnumericvalue
|
// https://drafts.css-houdini.org/css-typed-om-1/#cssnumericvalue
|
||||||
class CSSNumericValue : public CSSStyleValue {
|
class CSSNumericValue : public CSSStyleValue {
|
||||||
WEB_PLATFORM_OBJECT(CSSNumericValue, CSSStyleValue);
|
WEB_PLATFORM_OBJECT(CSSNumericValue, CSSStyleValue);
|
||||||
|
@ -45,6 +52,8 @@ public:
|
||||||
bool equals_for_bindings(Vector<CSSNumberish>) const;
|
bool equals_for_bindings(Vector<CSSNumberish>) const;
|
||||||
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const = 0;
|
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const = 0;
|
||||||
|
|
||||||
|
virtual Optional<SumValue> create_a_sum_value() const = 0;
|
||||||
|
|
||||||
CSSNumericType type_for_bindings() const;
|
CSSNumericType type_for_bindings() const;
|
||||||
NumericType const& type() const { return m_type; }
|
NumericType const& type() const { return m_type; }
|
||||||
|
|
||||||
|
|
|
@ -186,4 +186,80 @@ bool CSSUnitValue::is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const
|
||||||
&& m_value == other_unit_value->m_value;
|
&& m_value == other_unit_value->m_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://drafts.css-houdini.org/css-typed-om-1/#create-a-sum-value
|
||||||
|
Optional<SumValue> CSSUnitValue::create_a_sum_value() const
|
||||||
|
{
|
||||||
|
// 1. Let unit be the value of this’s unit internal slot, and value be the value of this’s value internal slot.
|
||||||
|
auto unit = m_unit;
|
||||||
|
auto value = m_value;
|
||||||
|
|
||||||
|
// 2. If unit is a member of a set of compatible units, and is not the set’s canonical unit, multiply value
|
||||||
|
// by the conversion ratio between unit and the canonical unit, and change unit to the canonical unit.
|
||||||
|
if (auto dimension_type = dimension_for_unit(unit); dimension_type.has_value()) {
|
||||||
|
switch (*dimension_type) {
|
||||||
|
case DimensionType::Angle: {
|
||||||
|
auto angle_unit = string_to_angle_unit(unit).release_value();
|
||||||
|
auto canonical_unit = canonical_angle_unit();
|
||||||
|
if (angle_unit != canonical_unit && units_are_compatible(angle_unit, canonical_unit)) {
|
||||||
|
value *= ratio_between_units(angle_unit, canonical_unit);
|
||||||
|
unit = CSS::to_string(canonical_unit);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DimensionType::Flex: {
|
||||||
|
auto flex_unit = string_to_flex_unit(unit).release_value();
|
||||||
|
auto canonical_unit = canonical_flex_unit();
|
||||||
|
if (flex_unit != canonical_unit && units_are_compatible(flex_unit, canonical_unit)) {
|
||||||
|
value *= ratio_between_units(flex_unit, canonical_unit);
|
||||||
|
unit = CSS::to_string(canonical_unit);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DimensionType::Frequency: {
|
||||||
|
auto frequency_unit = string_to_frequency_unit(unit).release_value();
|
||||||
|
auto canonical_unit = canonical_frequency_unit();
|
||||||
|
if (frequency_unit != canonical_unit && units_are_compatible(frequency_unit, canonical_unit)) {
|
||||||
|
value *= ratio_between_units(frequency_unit, canonical_unit);
|
||||||
|
unit = CSS::to_string(canonical_unit);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DimensionType::Length: {
|
||||||
|
auto length_unit = string_to_length_unit(unit).release_value();
|
||||||
|
auto canonical_unit = canonical_length_unit();
|
||||||
|
if (length_unit != canonical_unit && units_are_compatible(length_unit, canonical_unit)) {
|
||||||
|
value *= ratio_between_units(length_unit, canonical_unit);
|
||||||
|
unit = CSS::to_string(canonical_unit);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DimensionType::Resolution: {
|
||||||
|
auto resolution_unit = string_to_resolution_unit(unit).release_value();
|
||||||
|
auto canonical_unit = canonical_resolution_unit();
|
||||||
|
if (resolution_unit != canonical_unit && units_are_compatible(resolution_unit, canonical_unit)) {
|
||||||
|
value *= ratio_between_units(resolution_unit, canonical_unit);
|
||||||
|
unit = CSS::to_string(canonical_unit);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DimensionType::Time: {
|
||||||
|
auto time_unit = string_to_time_unit(unit).release_value();
|
||||||
|
auto canonical_unit = canonical_time_unit();
|
||||||
|
if (time_unit != canonical_unit && units_are_compatible(time_unit, canonical_unit)) {
|
||||||
|
value *= ratio_between_units(time_unit, canonical_unit);
|
||||||
|
unit = CSS::to_string(canonical_unit);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. If unit is "number", return «(value, «[ ]»)».
|
||||||
|
if (unit == "number"_fly_string)
|
||||||
|
return SumValue { SumValueItem { value, {} } };
|
||||||
|
|
||||||
|
// 4. Otherwise, return «(value, «[unit → 1]»)».
|
||||||
|
return SumValue { SumValueItem { value, { { unit, 1 } } } };
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ public:
|
||||||
GC::Ptr<CSSUnitValue> converted_to_unit(FlyString const& unit) const;
|
GC::Ptr<CSSUnitValue> converted_to_unit(FlyString const& unit) const;
|
||||||
|
|
||||||
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
|
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
|
||||||
|
virtual Optional<SumValue> create_a_sum_value() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit CSSUnitValue(JS::Realm&, double value, FlyString unit, NumericType type);
|
explicit CSSUnitValue(JS::Realm&, double value, FlyString unit, NumericType type);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue