diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index d8922a0c60..b394d067fe 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -662,7 +662,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter auto @cpp_name@ = JS::make_handle(TRY(@js_name@@js_suffix@.to_object(vm))); )~~~"); } - } else if (parameter.type->name() == "BufferSource") { + } else if (parameter.type->name() == "BufferSource" || parameter.type->name() == "Float32Array" || parameter.type->name() == "Float64Array") { if (optional) { scoped_generator.append(R"~~~( Optional> @cpp_name@; diff --git a/Tests/LibWeb/Text/expected/geometry/dommatrix-create.txt b/Tests/LibWeb/Text/expected/geometry/dommatrix-create.txt index ef3f561853..bd434f0af8 100644 --- a/Tests/LibWeb/Text/expected/geometry/dommatrix-create.txt +++ b/Tests/LibWeb/Text/expected/geometry/dommatrix-create.txt @@ -1,4 +1,10 @@ 1. {"a":10,"b":20,"c":30,"d":40,"e":50,"f":60,"m11":10,"m12":20,"m13":0,"m14":0,"m21":30,"m22":40,"m23":0,"m24":0,"m31":0,"m32":0,"m33":1,"m34":0,"m41":50,"m42":60,"m43":0,"m44":1,"is2D":true,"isIdentity":false} -2. {"a":10,"b":20,"c":30,"d":40,"e":50,"f":60,"m11":10,"m12":20,"m13":0,"m14":0,"m21":30,"m22":40,"m23":0,"m24":0,"m31":0,"m32":0,"m33":1,"m34":0,"m41":50,"m42":60,"m43":0,"m44":1,"is2D":true,"isIdentity":false} -3. {"a":10,"b":20,"c":50,"d":60,"e":130,"f":140,"m11":10,"m12":20,"m13":30,"m14":40,"m21":50,"m22":60,"m23":70,"m24":80,"m31":90,"m32":100,"m33":110,"m34":120,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false} +2. {"a":10,"b":20,"c":50,"d":60,"e":130,"f":140,"m11":10,"m12":20,"m13":30,"m14":40,"m21":50,"m22":60,"m23":70,"m24":80,"m31":90,"m32":100,"m33":110,"m34":120,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false} +3. {"a":10,"b":20,"c":30,"d":40,"e":50,"f":60,"m11":10,"m12":20,"m13":0,"m14":0,"m21":30,"m22":40,"m23":0,"m24":0,"m31":0,"m32":0,"m33":1,"m34":0,"m41":50,"m42":60,"m43":0,"m44":1,"is2D":true,"isIdentity":false} 4. {"a":10,"b":20,"c":50,"d":60,"e":130,"f":140,"m11":10,"m12":20,"m13":30,"m14":40,"m21":50,"m22":60,"m23":70,"m24":80,"m31":90,"m32":100,"m33":110,"m34":120,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false} +5. {"a":10,"b":20,"c":30,"d":40,"e":50,"f":60,"m11":10,"m12":20,"m13":0,"m14":0,"m21":30,"m22":40,"m23":0,"m24":0,"m31":0,"m32":0,"m33":1,"m34":0,"m41":50,"m42":60,"m43":0,"m44":1,"is2D":true,"isIdentity":false} +6. {"a":10,"b":20,"c":50,"d":60,"e":130,"f":140,"m11":10,"m12":20,"m13":30,"m14":40,"m21":50,"m22":60,"m23":70,"m24":80,"m31":90,"m32":100,"m33":110,"m34":120,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false} +7. {"a":10,"b":20,"c":30,"d":40,"e":50,"f":60,"m11":10,"m12":20,"m13":0,"m14":0,"m21":30,"m22":40,"m23":0,"m24":0,"m31":0,"m32":0,"m33":1,"m34":0,"m41":50,"m42":60,"m43":0,"m44":1,"is2D":true,"isIdentity":false} +8. {"a":10,"b":20,"c":50,"d":60,"e":130,"f":140,"m11":10,"m12":20,"m13":30,"m14":40,"m21":50,"m22":60,"m23":70,"m24":80,"m31":90,"m32":100,"m33":110,"m34":120,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false} +9. Exception: TypeError +10. Exception: TypeError diff --git a/Tests/LibWeb/Text/input/geometry/dommatrix-create.html b/Tests/LibWeb/Text/input/geometry/dommatrix-create.html index 1c171dbbed..12d3cd11bf 100644 --- a/Tests/LibWeb/Text/input/geometry/dommatrix-create.html +++ b/Tests/LibWeb/Text/input/geometry/dommatrix-create.html @@ -3,19 +3,42 @@ test(() => { let testCounter = 1; function testPart(part) { - println(`${testCounter++}. ${JSON.stringify(part())}`); + try { + println(`${testCounter}. ${JSON.stringify(part())}`); + } catch (e) { + println(`${testCounter}. Exception: ${e.name}`); + } + testCounter++; } // 1. Creating a DOMMatrix testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60])); - // 2. Creating a DOMMatrix with fromMatrix - testPart(() => DOMMatrix.fromMatrix({ a: 10, b: 20, c: 30, d: 40, e: 50, f: 60 })); - - // 3. Creating a DOMMatrix + // 2. Creating a DOMMatrix testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160])); + // 3. Creating a DOMMatrix with fromMatrix + testPart(() => DOMMatrix.fromMatrix({ a: 10, b: 20, c: 30, d: 40, e: 50, f: 60 })); + // 4. Creating a DOMMatrix with fromMatrix testPart(() => DOMMatrix.fromMatrix({ m11: 10, m12: 20, m13: 30, m14: 40, m21: 50, m22: 60, m23: 70, m24: 80, m31: 90, m32: 100, m33: 110, m34: 120, m41: 130, m42: 140, m43: 150, m44: 160 })); + + // 5. Creating a DOMMatrix with fromFloat32Array + testPart(() => DOMMatrix.fromFloat32Array(new Float32Array([10, 20, 30, 40, 50, 60]))); + + // 6. Creating a DOMMatrix with fromFloat32Array + testPart(() => DOMMatrix.fromFloat32Array(new Float32Array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]))); + + // 7. Creating a DOMMatrix with fromFloat64Array + testPart(() => DOMMatrix.fromFloat64Array(new Float64Array([10, 20, 30, 40, 50, 60]))); + + // 8. Creating a DOMMatrix with fromFloat64Array + testPart(() => DOMMatrix.fromFloat64Array(new Float64Array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]))); + + // 9. Creating a DOMMatrix with fromFloat32Array wrong amount + testPart(() => DOMMatrix.fromFloat32Array(new Float32Array([10, 20, 30, 40]))); + + // 10. Creating a DOMMatrix with fromFloat64Array wrong amount + testPart(() => DOMMatrix.fromFloat64Array(new Float64Array([10, 20, 30, 40]))); }); diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp index 5d2e5177cf..7a0649945f 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp @@ -5,6 +5,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -104,6 +105,56 @@ WebIDL::ExceptionOr> DOMMatrix::from_matrix(JS::VM& return create_from_dom_matrix_init(*vm.current_realm(), other); } +// https://drafts.fxtf.org/geometry/#dom-dommatrix-fromfloat32array +WebIDL::ExceptionOr> DOMMatrix::from_float32_array(JS::VM& vm, JS::Handle const& array32) +{ + if (!is(*array32)) + return vm.throw_completion(JS::ErrorType::NotAnObjectOfType, "Float32Array"); + + auto& realm = *vm.current_realm(); + auto& float32_array = static_cast(*array32); + ReadonlySpan elements = float32_array.data(); + + // If array32 has 6 elements, return the result of invoking create a 2d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array32 in the provided order. + if (elements.size() == 6) + return realm.heap().allocate(realm, realm, elements.at(0), elements.at(1), elements.at(2), elements.at(3), elements.at(4), elements.at(5)); + + // If array32 has 16 elements, return the result of invoking create a 3d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array32 in the provided order. + if (elements.size() == 16) + return realm.heap().allocate(realm, realm, elements.at(0), elements.at(1), elements.at(2), elements.at(3), + elements.at(4), elements.at(5), elements.at(6), elements.at(7), + elements.at(8), elements.at(9), elements.at(10), elements.at(11), + elements.at(12), elements.at(13), elements.at(14), elements.at(15)); + + // Otherwise, throw a TypeError exception. + return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Expected a Float32Array argument with 6 or 16 elements"_string }; +} + +// https://drafts.fxtf.org/geometry/#dom-dommatrix-fromfloat64array +WebIDL::ExceptionOr> DOMMatrix::from_float64_array(JS::VM& vm, JS::Handle const& array64) +{ + if (!is(*array64)) + return vm.throw_completion(JS::ErrorType::NotAnObjectOfType, "Float64Array"); + + auto& realm = *vm.current_realm(); + auto& float64_array = static_cast(*array64); + ReadonlySpan elements = float64_array.data(); + + // If array64 has 6 elements, return the result of invoking create a 2d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array64 in the provided order. + if (elements.size() == 6) + return realm.heap().allocate(realm, realm, elements.at(0), elements.at(1), elements.at(2), elements.at(3), elements.at(4), elements.at(5)); + + // If array64 has 16 elements, return the result of invoking create a 3d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array64 in the provided order. + if (elements.size() == 16) + return realm.heap().allocate(realm, realm, elements.at(0), elements.at(1), elements.at(2), elements.at(3), + elements.at(4), elements.at(5), elements.at(6), elements.at(7), + elements.at(8), elements.at(9), elements.at(10), elements.at(11), + elements.at(12), elements.at(13), elements.at(14), elements.at(15)); + + // Otherwise, throw a TypeError exception. + return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Expected a Float64Array argument with 6 or 16 elements"_string }; +} + // https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-m11 void DOMMatrix::set_m11(double value) { diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.h b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.h index 16ac205006..ceb29264f6 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.h +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.h @@ -24,6 +24,8 @@ public: virtual ~DOMMatrix() override; static WebIDL::ExceptionOr> from_matrix(JS::VM&, DOMMatrixInit other = {}); + static WebIDL::ExceptionOr> from_float32_array(JS::VM&, JS::Handle const& array32); + static WebIDL::ExceptionOr> from_float64_array(JS::VM&, JS::Handle const& array64); void set_m11(double value); void set_m12(double value); diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl index c225218172..98ad307418 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl @@ -7,8 +7,8 @@ interface DOMMatrix : DOMMatrixReadOnly { constructor(optional (DOMString or sequence) init); [NewObject] static DOMMatrix fromMatrix(optional DOMMatrixInit other = {}); - // FIXME: [NewObject] static DOMMatrix fromFloat32Array(Float32Array array32); - // FIXME: [NewObject] static DOMMatrix fromFloat64Array(Float64Array array64); + [NewObject] static DOMMatrix fromFloat32Array(Float32Array array32); + [NewObject] static DOMMatrix fromFloat64Array(Float64Array array64); // These attributes are simple aliases for certain elements of the 4x4 matrix inherit attribute unrestricted double a; diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp index 70cc3d0a24..2c8c62b1ea 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp @@ -5,7 +5,6 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include #include #include #include @@ -208,6 +207,56 @@ WebIDL::ExceptionOr> DOMMatrixReadOnly::from return create_from_dom_matrix_init(*vm.current_realm(), other); } +// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-fromfloat32array +WebIDL::ExceptionOr> DOMMatrixReadOnly::from_float32_array(JS::VM& vm, JS::Handle const& array32) +{ + if (!is(*array32)) + return vm.throw_completion(JS::ErrorType::NotAnObjectOfType, "Float32Array"); + + auto& realm = *vm.current_realm(); + auto& float32_array = static_cast(*array32); + ReadonlySpan elements = float32_array.data(); + + // If array32 has 6 elements, return the result of invoking create a 2d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array32 in the provided order. + if (elements.size() == 6) + return realm.heap().allocate(realm, realm, elements.at(0), elements.at(1), elements.at(2), elements.at(3), elements.at(4), elements.at(5)); + + // If array32 has 16 elements, return the result of invoking create a 3d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array32 in the provided order. + if (elements.size() == 16) + return realm.heap().allocate(realm, realm, elements.at(0), elements.at(1), elements.at(2), elements.at(3), + elements.at(4), elements.at(5), elements.at(6), elements.at(7), + elements.at(8), elements.at(9), elements.at(10), elements.at(11), + elements.at(12), elements.at(13), elements.at(14), elements.at(15)); + + // Otherwise, throw a TypeError exception. + return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Expected a Float32Array argument with 6 or 16 elements"_string }; +} + +// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-fromfloat64array +WebIDL::ExceptionOr> DOMMatrixReadOnly::from_float64_array(JS::VM& vm, JS::Handle const& array64) +{ + if (!is(*array64)) + return vm.throw_completion(JS::ErrorType::NotAnObjectOfType, "Float64Array"); + + auto& realm = *vm.current_realm(); + auto& float64_array = static_cast(*array64); + ReadonlySpan elements = float64_array.data(); + + // If array64 has 6 elements, return the result of invoking create a 2d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array64 in the provided order. + if (elements.size() == 6) + return realm.heap().allocate(realm, realm, elements.at(0), elements.at(1), elements.at(2), elements.at(3), elements.at(4), elements.at(5)); + + // If array64 has 16 elements, return the result of invoking create a 3d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array64 in the provided order. + if (elements.size() == 16) + return realm.heap().allocate(realm, realm, elements.at(0), elements.at(1), elements.at(2), elements.at(3), + elements.at(4), elements.at(5), elements.at(6), elements.at(7), + elements.at(8), elements.at(9), elements.at(10), elements.at(11), + elements.at(12), elements.at(13), elements.at(14), elements.at(15)); + + // Otherwise, throw a TypeError exception. + return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Expected a Float64Array argument with 6 or 16 elements"_string }; +} + // https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-isidentity bool DOMMatrixReadOnly::is_identity() const { diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h index a0239a93e6..80a48c9498 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h @@ -56,6 +56,8 @@ public: virtual ~DOMMatrixReadOnly() override; static WebIDL::ExceptionOr> from_matrix(JS::VM&, DOMMatrixInit& other); + static WebIDL::ExceptionOr> from_float32_array(JS::VM&, JS::Handle const& array32); + static WebIDL::ExceptionOr> from_float64_array(JS::VM&, JS::Handle const& array64); // https://drafts.fxtf.org/geometry/#dommatrix-attributes double m11() const { return m_matrix.elements()[0][0]; } diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl index 212ae3c6ba..9197c46b85 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl @@ -7,8 +7,8 @@ interface DOMMatrixReadOnly { constructor(optional (DOMString or sequence) init); [NewObject] static DOMMatrixReadOnly fromMatrix(optional DOMMatrixInit other = {}); - // FIXME: [NewObject] static DOMMatrixReadOnly fromFloat32Array(Float32Array array32); - // FIXME: [NewObject] static DOMMatrixReadOnly fromFloat64Array(Float64Array array64); + [NewObject] static DOMMatrixReadOnly fromFloat32Array(Float32Array array32); + [NewObject] static DOMMatrixReadOnly fromFloat64Array(Float64Array array64); // These attributes are simple aliases for certain elements of the 4x4 matrix readonly attribute unrestricted double a;