LibWeb/CSS: Add various CSSMathXXX constructor helpers

The exact same two steps are repeated for all of these in
CSSNumericValue. These steps are complicated enough that it makes
sense to factor them out into some helpers.
This commit is contained in:
Shannon Booth 2026-01-11 00:13:56 +01:00 committed by Sam Atkins
parent 3cb428e76d
commit 09f2db7aa9
8 changed files with 88 additions and 64 deletions

View file

@ -22,6 +22,26 @@ GC::Ref<CSSMathMax> CSSMathMax::create(JS::Realm& realm, NumericType type, GC::R
return realm.create<CSSMathMax>(realm, move(type), move(values));
}
WebIDL::ExceptionOr<GC::Ref<CSSMathMax>> CSSMathMax::add_all_types_into_math_max(JS::Realm& realm, GC::RootVector<GC::Ref<CSSNumericValue>> const& values)
{
auto type = values.first()->type();
bool first = true;
for (auto const& value : values) {
if (first) {
first = false;
continue;
}
if (auto added_types = type.added_to(value->type()); added_types.has_value()) {
type = added_types.release_value();
} else {
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Cannot create a CSSMathMax with values of incompatible types"sv };
}
}
auto values_array = CSSNumericArray::create(realm, { values });
return CSSMathMax::create(realm, type, values_array);
}
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssmathmin-cssmathmin
WebIDL::ExceptionOr<GC::Ref<CSSMathMax>> CSSMathMax::construct_impl(JS::Realm& realm, Vector<CSSNumberish> values)
{
@ -41,23 +61,8 @@ WebIDL::ExceptionOr<GC::Ref<CSSMathMax>> CSSMathMax::construct_impl(JS::Realm& r
return WebIDL::SyntaxError::create(realm, "Cannot create an empty CSSMathMax"_utf16);
// 3. Let type be the result of adding the types of all the items of args. If type is failure, throw a TypeError.
auto type = converted_values.first()->type();
bool first = true;
for (auto const& value : converted_values) {
if (first) {
first = false;
continue;
}
if (auto added_types = type.added_to(value->type()); added_types.has_value()) {
type = added_types.release_value();
} else {
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Cannot create a CSSMathMax with values of incompatible types"sv };
}
}
// 4. Return a new CSSMathMax whose values internal slot is set to args.
auto values_array = CSSNumericArray::create(realm, { converted_values });
return CSSMathMax::create(realm, move(type), move(values_array));
return add_all_types_into_math_max(realm, converted_values);
}
CSSMathMax::CSSMathMax(JS::Realm& realm, NumericType type, GC::Ref<CSSNumericArray> values)

View file

@ -18,6 +18,7 @@ class CSSMathMax final : public CSSMathValue {
public:
[[nodiscard]] static GC::Ref<CSSMathMax> create(JS::Realm&, NumericType, GC::Ref<CSSNumericArray>);
static WebIDL::ExceptionOr<GC::Ref<CSSMathMax>> construct_impl(JS::Realm&, Vector<CSSNumberish>);
static WebIDL::ExceptionOr<GC::Ref<CSSMathMax>> add_all_types_into_math_max(JS::Realm&, GC::RootVector<GC::Ref<CSSNumericValue>> const&);
virtual ~CSSMathMax() override;

View file

@ -23,6 +23,26 @@ GC::Ref<CSSMathMin> CSSMathMin::create(JS::Realm& realm, NumericType type, GC::R
return realm.create<CSSMathMin>(realm, move(type), move(values));
}
WebIDL::ExceptionOr<GC::Ref<CSSMathMin>> CSSMathMin::add_all_types_into_math_min(JS::Realm& realm, GC::RootVector<GC::Ref<CSSNumericValue>> const& values)
{
auto type = values.first()->type();
bool first = true;
for (auto const& value : values) {
if (first) {
first = false;
continue;
}
if (auto added_types = type.added_to(value->type()); added_types.has_value()) {
type = added_types.release_value();
} else {
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Cannot create a CSSMathMin with values of incompatible types"sv };
}
}
auto values_array = CSSNumericArray::create(realm, { values });
return CSSMathMin::create(realm, type, values_array);
}
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssmathmin-cssmathmin
WebIDL::ExceptionOr<GC::Ref<CSSMathMin>> CSSMathMin::construct_impl(JS::Realm& realm, Vector<CSSNumberish> values)
{
@ -42,23 +62,8 @@ WebIDL::ExceptionOr<GC::Ref<CSSMathMin>> CSSMathMin::construct_impl(JS::Realm& r
return WebIDL::SyntaxError::create(realm, "Cannot create an empty CSSMathMin"_utf16);
// 3. Let type be the result of adding the types of all the items of args. If type is failure, throw a TypeError.
auto type = converted_values.first()->type();
bool first = true;
for (auto const& value : converted_values) {
if (first) {
first = false;
continue;
}
if (auto added_types = type.added_to(value->type()); added_types.has_value()) {
type = added_types.release_value();
} else {
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Cannot create a CSSMathMin with values of incompatible types"sv };
}
}
// 4. Return a new CSSMathMin whose values internal slot is set to args.
auto values_array = CSSNumericArray::create(realm, { converted_values });
return CSSMathMin::create(realm, move(type), move(values_array));
return CSSMathMin::add_all_types_into_math_min(realm, converted_values);
}
CSSMathMin::CSSMathMin(JS::Realm& realm, NumericType type, GC::Ref<CSSNumericArray> values)

View file

@ -18,6 +18,7 @@ class CSSMathMin final : public CSSMathValue {
public:
[[nodiscard]] static GC::Ref<CSSMathMin> create(JS::Realm&, NumericType, GC::Ref<CSSNumericArray>);
static WebIDL::ExceptionOr<GC::Ref<CSSMathMin>> construct_impl(JS::Realm&, Vector<CSSNumberish>);
static WebIDL::ExceptionOr<GC::Ref<CSSMathMin>> add_all_types_into_math_min(JS::Realm&, GC::RootVector<GC::Ref<CSSNumericValue>> const&);
virtual ~CSSMathMin() override;

View file

@ -22,6 +22,26 @@ GC::Ref<CSSMathProduct> CSSMathProduct::create(JS::Realm& realm, NumericType typ
return realm.create<CSSMathProduct>(realm, move(type), move(values));
}
WebIDL::ExceptionOr<GC::Ref<CSSMathProduct>> CSSMathProduct::multiply_all_types_into_math_product(JS::Realm& realm, GC::RootVector<GC::Ref<CSSNumericValue>> const& values)
{
auto type = values.first()->type();
bool first = true;
for (auto const& value : values) {
if (first) {
first = false;
continue;
}
if (auto multiplied_types = type.multiplied_by(value->type()); multiplied_types.has_value()) {
type = multiplied_types.release_value();
} else {
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Cannot create a CSSMathProduct with values of incompatible types"sv };
}
}
auto values_array = CSSNumericArray::create(realm, { values });
return CSSMathProduct::create(realm, type, values_array);
}
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssmathproduct-cssmathproduct
WebIDL::ExceptionOr<GC::Ref<CSSMathProduct>> CSSMathProduct::construct_impl(JS::Realm& realm, Vector<CSSNumberish> values)
{
@ -41,23 +61,8 @@ WebIDL::ExceptionOr<GC::Ref<CSSMathProduct>> CSSMathProduct::construct_impl(JS::
return WebIDL::SyntaxError::create(realm, "Cannot create an empty CSSMathProduct"_utf16);
// 3. Let type be the result of multiplying the types of all the items of args. If type is failure, throw a TypeError.
auto type = converted_values.first()->type();
bool first = true;
for (auto const& value : converted_values) {
if (first) {
first = false;
continue;
}
if (auto multiplied_types = type.multiplied_by(value->type()); multiplied_types.has_value()) {
type = multiplied_types.release_value();
} else {
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Cannot create a CSSMathProduct with values of incompatible types"sv };
}
}
// 4. Return a new CSSMathProduct whose values internal slot is set to args.
auto values_array = CSSNumericArray::create(realm, { converted_values });
return CSSMathProduct::create(realm, move(type), move(values_array));
return multiply_all_types_into_math_product(realm, converted_values);
}
CSSMathProduct::CSSMathProduct(JS::Realm& realm, NumericType type, GC::Ref<CSSNumericArray> values)

View file

@ -18,6 +18,7 @@ class CSSMathProduct final : public CSSMathValue {
public:
[[nodiscard]] static GC::Ref<CSSMathProduct> create(JS::Realm&, NumericType, GC::Ref<CSSNumericArray>);
static WebIDL::ExceptionOr<GC::Ref<CSSMathProduct>> construct_impl(JS::Realm&, Vector<CSSNumberish>);
static WebIDL::ExceptionOr<GC::Ref<CSSMathProduct>> multiply_all_types_into_math_product(JS::Realm&, GC::RootVector<GC::Ref<CSSNumericValue>> const&);
virtual ~CSSMathProduct() override;

View file

@ -22,6 +22,26 @@ GC::Ref<CSSMathSum> CSSMathSum::create(JS::Realm& realm, NumericType type, GC::R
return realm.create<CSSMathSum>(realm, move(type), move(values));
}
WebIDL::ExceptionOr<GC::Ref<CSSMathSum>> CSSMathSum::add_all_types_into_math_sum(JS::Realm& realm, GC::RootVector<GC::Ref<CSSNumericValue>> const& values)
{
auto type = values.first()->type();
bool first = true;
for (auto const& value : values) {
if (first) {
first = false;
continue;
}
if (auto added_types = type.added_to(value->type()); added_types.has_value()) {
type = added_types.release_value();
} else {
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Cannot create a CSSMathSum with values of incompatible types"sv };
}
}
auto values_array = CSSNumericArray::create(realm, { values });
return CSSMathSum::create(realm, type, values_array);
}
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssmathsum-cssmathsum
WebIDL::ExceptionOr<GC::Ref<CSSMathSum>> CSSMathSum::construct_impl(JS::Realm& realm, Vector<CSSNumberish> values)
{
@ -39,23 +59,8 @@ WebIDL::ExceptionOr<GC::Ref<CSSMathSum>> CSSMathSum::construct_impl(JS::Realm& r
return WebIDL::SyntaxError::create(realm, "Cannot create an empty CSSMathSum"_utf16);
// 3. Let type be the result of adding the types of all the items of args. If type is failure, throw a TypeError.
auto type = converted_values.first()->type();
bool first = true;
for (auto const& value : converted_values) {
if (first) {
first = false;
continue;
}
if (auto added_types = type.added_to(value->type()); added_types.has_value()) {
type = added_types.release_value();
} else {
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Cannot create a CSSMathSum with values of incompatible types"sv };
}
}
// 4. Return a new CSSMathSum whose values internal slot is set to args.
auto values_array = CSSNumericArray::create(realm, { converted_values });
return CSSMathSum::create(realm, move(type), move(values_array));
return add_all_types_into_math_sum(realm, converted_values);
}
CSSMathSum::CSSMathSum(JS::Realm& realm, NumericType type, GC::Ref<CSSNumericArray> values)

View file

@ -18,6 +18,7 @@ class CSSMathSum final : public CSSMathValue {
public:
[[nodiscard]] static GC::Ref<CSSMathSum> create(JS::Realm&, NumericType, GC::Ref<CSSNumericArray>);
static WebIDL::ExceptionOr<GC::Ref<CSSMathSum>> construct_impl(JS::Realm&, Vector<CSSNumberish>);
static WebIDL::ExceptionOr<GC::Ref<CSSMathSum>> add_all_types_into_math_sum(JS::Realm&, GC::RootVector<GC::Ref<CSSNumericValue>> const&);
virtual ~CSSMathSum() override;