From daeca252adc026b2285158a66dff266f9126242e Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 22 Jan 2024 00:31:19 +0900 Subject: [PATCH 01/63] feat: Geometry Interfaces Module Co-authored-by: ud2 --- Cargo.lock | 101 ++ Cargo.toml | 7 + cli/build.rs | 1 + cli/tsc/dts/lib.deno.shared_globals.d.ts | 1 + cli/tsc/mod.rs | 1 + ext/geometry/00_init.js | 27 + ext/geometry/01_geometry.js | 2117 ++++++++++++++++++++++ ext/geometry/Cargo.toml | 18 + ext/geometry/README.md | 108 ++ ext/geometry/lib.deno_geometry.d.ts | 602 ++++++ ext/geometry/lib.rs | 269 +++ ext/webidl/00_webidl.js | 3 + ext/webidl/internal.d.ts | 6 + runtime/Cargo.toml | 2 + runtime/js/98_global_scope_window.js | 103 ++ runtime/js/98_global_scope_worker.js | 36 + runtime/lib.rs | 1 + runtime/shared.rs | 1 + runtime/snapshot.rs | 1 + runtime/web_worker.rs | 1 + runtime/worker.rs | 1 + tests/integration/js_unit_tests.rs | 1 + tests/unit/geometry_test.ts | 1195 ++++++++++++ tests/unit/test_util.ts | 1 + tests/wpt/runner/expectation.json | 205 ++- tools/core_import_map.json | 2 + tools/jsdoc_checker.js | 1 + 27 files changed, 4811 insertions(+), 1 deletion(-) create mode 100644 ext/geometry/00_init.js create mode 100644 ext/geometry/01_geometry.js create mode 100644 ext/geometry/Cargo.toml create mode 100644 ext/geometry/README.md create mode 100644 ext/geometry/lib.deno_geometry.d.ts create mode 100644 ext/geometry/lib.rs create mode 100644 tests/unit/geometry_test.ts diff --git a/Cargo.lock b/Cargo.lock index b054e9fe7ca836..ef2955de3a89dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -192,6 +192,15 @@ version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + [[package]] name = "arbitrary" version = "1.3.2" @@ -1748,6 +1757,14 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "deno_geometry" +version = "0.1.0" +dependencies = [ + "deno_core", + "nalgebra", +] + [[package]] name = "deno_graph" version = "0.86.7" @@ -2218,6 +2235,7 @@ dependencies = [ "deno_fetch", "deno_ffi", "deno_fs", + "deno_geometry", "deno_http", "deno_io", "deno_kv", @@ -4836,6 +4854,16 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +[[package]] +name = "matrixmultiply" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" +dependencies = [ + "autocfg", + "rawpointer", +] + [[package]] name = "md-5" version = "0.10.6" @@ -4994,6 +5022,21 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "nalgebra" +version = "0.33.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b" +dependencies = [ + "approx", + "matrixmultiply", + "num-complex", + "num-rational", + "num-traits", + "simba", + "typenum", +] + [[package]] name = "napi-build" version = "1.2.1" @@ -5165,6 +5208,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "num-complex" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +dependencies = [ + "num-traits", +] + [[package]] name = "num-conv" version = "0.1.0" @@ -5191,6 +5243,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.18" @@ -6141,6 +6204,12 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cc3bcbdb1ddfc11e700e62968e6b4cc9c75bb466464ad28fb61c5b2c964418b" +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + [[package]] name = "rayon" version = "1.10.0" @@ -6590,6 +6659,15 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad97d4ce1560a5e27cec89519dc8300d1aa6035b099821261c651486a19e44d5" +[[package]] +name = "safe_arch" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f398075ce1e6a179b46f51bd88d0598b92b00d3551f1a2d4ac49e771b56ac354" +dependencies = [ + "bytemuck", +] + [[package]] name = "saffron" version = "0.1.0" @@ -6907,6 +6985,19 @@ dependencies = [ "rand_core", ] +[[package]] +name = "simba" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa" +dependencies = [ + "approx", + "num-complex", + "num-traits", + "paste", + "wide", +] + [[package]] name = "simd-abstraction" version = "0.7.1" @@ -8764,6 +8855,16 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wide" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81a1851a719f11d1d2fea40e15c72f6c00de8c142d7ac47c1441cc7e4d0d5bc6" +dependencies = [ + "bytemuck", + "safe_arch", +] + [[package]] name = "widestring" version = "1.1.0" diff --git a/Cargo.toml b/Cargo.toml index fa2813caedcf3a..8dff7d175d9b53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ members = [ "ext/fetch", "ext/ffi", "ext/fs", + "ext/geometry", "ext/http", "ext/io", "ext/kv", @@ -78,6 +79,7 @@ deno_crypto = { version = "0.198.0", path = "./ext/crypto" } deno_fetch = { version = "0.208.0", path = "./ext/fetch" } deno_ffi = { version = "0.171.0", path = "./ext/ffi" } deno_fs = { version = "0.94.0", path = "./ext/fs" } +deno_geometry = { version = "0.1.0", path = "./ext/geometry" } deno_http = { version = "0.182.0", path = "./ext/http" } deno_io = { version = "0.94.0", path = "./ext/io" } deno_kv = { version = "0.92.0", path = "./ext/kv" } @@ -227,6 +229,9 @@ opentelemetry_sdk = "0.27.0" hkdf = "0.12.3" rsa = { version = "0.9.3", default-features = false, features = ["std", "pem", "hazmat"] } # hazmat needed for PrehashSigner in ext/node +# geometry +nalgebra = { version = "0.33.2", default-features = false, features = ["std"] } + # webgpu raw-window-handle = "0.6.0" wgpu-core = "0.21.1" @@ -297,6 +302,8 @@ opt-level = 3 opt-level = 3 [profile.release.package.deno_ffi] opt-level = 3 +[profile.release.package.deno_geometry] +opt-level = 3 [profile.release.package.deno_http] opt-level = 3 [profile.release.package.deno_napi] diff --git a/cli/build.rs b/cli/build.rs index 83290599e6bf06..69bb1d5fcbad75 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -146,6 +146,7 @@ mod ts { op_crate_libs.insert("deno.url", deno_url::get_declaration()); op_crate_libs.insert("deno.web", deno_web::get_declaration()); op_crate_libs.insert("deno.fetch", deno_fetch::get_declaration()); + op_crate_libs.insert("deno.geometry", deno_geometry::get_declaration()); op_crate_libs.insert("deno.webgpu", deno_webgpu_get_declaration()); op_crate_libs.insert("deno.websocket", deno_websocket::get_declaration()); op_crate_libs.insert("deno.webstorage", deno_webstorage::get_declaration()); diff --git a/cli/tsc/dts/lib.deno.shared_globals.d.ts b/cli/tsc/dts/lib.deno.shared_globals.d.ts index a469525270b588..d8ef7794055080 100644 --- a/cli/tsc/dts/lib.deno.shared_globals.d.ts +++ b/cli/tsc/dts/lib.deno.shared_globals.d.ts @@ -11,6 +11,7 @@ /// /// /// +/// /// /// /// diff --git a/cli/tsc/mod.rs b/cli/tsc/mod.rs index 3176c50d5c7e70..0b7508717789c2 100644 --- a/cli/tsc/mod.rs +++ b/cli/tsc/mod.rs @@ -103,6 +103,7 @@ pub fn get_types_declaration_file_text() -> String { "deno.webstorage", "deno.canvas", "deno.crypto", + "deno.geometry", "deno.broadcast_channel", "deno.net", "deno.shared_globals", diff --git a/ext/geometry/00_init.js b/ext/geometry/00_init.js new file mode 100644 index 00000000000000..d1b89bac5cadc6 --- /dev/null +++ b/ext/geometry/00_init.js @@ -0,0 +1,27 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +import { core } from "ext:core/mod.js"; + +const lazyLoad = core.createLazyLoader("ext:deno_geometry/01_geometry.js"); + +let geometry; + +/** + * @param {(transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean }} transformListParser + * @param {boolean} enableWindowFeatures + */ +export function createGeometryLoader( + transformListParser, + enableWindowFeatures, +) { + return () => { + if (geometry !== undefined) { + return geometry; + } + + geometry = lazyLoad(); + geometry.init(transformListParser, enableWindowFeatures); + + return geometry; + }; +} diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js new file mode 100644 index 00000000000000..8b5957ee4e2610 --- /dev/null +++ b/ext/geometry/01_geometry.js @@ -0,0 +1,2117 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +import { primordials } from "ext:core/mod.js"; +import { + op_geometry_flip_x_self, + op_geometry_flip_y_self, + op_geometry_invert_2d_self, + op_geometry_invert_self, + op_geometry_multiply, + op_geometry_multiply_self, + op_geometry_premultiply_point_self, + op_geometry_premultiply_self, + op_geometry_rotate_axis_angle_self, + op_geometry_rotate_from_vector_self, + op_geometry_rotate_self, + op_geometry_scale_self, + op_geometry_scale_with_origin_self, + op_geometry_skew_self, + op_geometry_translate_self, +} from "ext:core/ops"; +const { + ArrayPrototypeJoin, + Float32Array, + Float64Array, + MathMax, + MathMin, + NumberIsFinite, + ObjectDefineProperty, + ObjectIs, + ObjectPrototypeIsPrototypeOf, + Symbol, + SymbolFor, + SymbolIterator, + TypeError, + TypedArrayPrototypeEvery, + TypedArrayPrototypeJoin, +} = primordials; + +import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; +import * as webidl from "ext:deno_webidl/00_webidl.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; + +webidl.converters.DOMPointInit = webidl.createDictionaryConverter( + "DOMPointInit", + [ + { + key: "x", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "y", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "z", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "w", + converter: webidl.converters["unrestricted double"], + defaultValue: 1, + }, + ], +); + +webidl.converters.DOMRectInit = webidl.createDictionaryConverter( + "DOMRectInit", + [ + { + key: "x", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "y", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "width", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "height", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + ], +); + +webidl.converters.DOMQuadInit = webidl.createDictionaryConverter( + "DOMQuadInit", + [ + { + key: "p1", + converter: webidl.converters.DOMPointInit, + }, + { + key: "p2", + converter: webidl.converters.DOMPointInit, + }, + { + key: "p3", + converter: webidl.converters.DOMPointInit, + }, + { + key: "p4", + converter: webidl.converters.DOMPointInit, + }, + ], +); + +/** @type {webidl.Dictionary} */ +const dictDOMMatrix2DInit = [ + { + key: "a", + converter: webidl.converters["unrestricted double"], + }, + { + key: "b", + converter: webidl.converters["unrestricted double"], + }, + { + key: "c", + converter: webidl.converters["unrestricted double"], + }, + { + key: "d", + converter: webidl.converters["unrestricted double"], + }, + { + key: "e", + converter: webidl.converters["unrestricted double"], + }, + { + key: "f", + converter: webidl.converters["unrestricted double"], + }, + { + key: "m11", + converter: webidl.converters["unrestricted double"], + }, + { + key: "m12", + converter: webidl.converters["unrestricted double"], + }, + { + key: "m21", + converter: webidl.converters["unrestricted double"], + }, + { + key: "m22", + converter: webidl.converters["unrestricted double"], + }, + { + key: "m41", + converter: webidl.converters["unrestricted double"], + }, + { + key: "m42", + converter: webidl.converters["unrestricted double"], + }, +]; + +webidl.converters.DOMMatrix2DInit = webidl.createDictionaryConverter( + "DOMMatrix2DInit", + dictDOMMatrix2DInit, +); + +webidl.converters.DOMMatrixInit = webidl.createDictionaryConverter( + "DOMMatrixInit", + dictDOMMatrix2DInit, + [ + { + key: "m13", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "m14", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "m23", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "m24", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "m31", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "m32", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "m33", + converter: webidl.converters["unrestricted double"], + defaultValue: 1, + }, + { + key: "m34", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "m43", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "m44", + converter: webidl.converters["unrestricted double"], + defaultValue: 1, + }, + { + key: "is2D", + converter: webidl.converters["boolean"], + }, + ], +); + +const _raw = Symbol("[[raw]]"); +// Property to prevent writing values when an immutable instance is changed to +// a mutable instance by Object.setPrototypeOf +// TODO(petamoriken): Implementing resistance to Object.setPrototypeOf in the WebIDL layer +const _writable = Symbol("[[writable]]"); +const _brand = webidl.brand; + +class DOMPointReadOnly { + [_writable] = false; + /** @type {Float64Array} */ + [_raw]; + + constructor(x = 0, y = 0, z = 0, w = 1) { + this[_raw] = new Float64Array([ + webidl.converters["unrestricted double"](x), + webidl.converters["unrestricted double"](y), + webidl.converters["unrestricted double"](z), + webidl.converters["unrestricted double"](w), + ]); + this[_brand] = _brand; + } + + static fromPoint(other = {}) { + other = webidl.converters.DOMPointInit( + other, + "Failed to execute 'DOMPointReadOnly.fromPoint'", + "Argument 1", + ); + const point = webidl.createBranded(DOMPointReadOnly); + point[_writable] = false; + point[_raw] = new Float64Array([ + other.x, + other.y, + other.z, + other.w, + ]); + return point; + } + + get x() { + webidl.assertBranded(this, DOMPointReadOnlyPrototype); + return this[_raw][0]; + } + get y() { + webidl.assertBranded(this, DOMPointReadOnlyPrototype); + return this[_raw][1]; + } + get z() { + webidl.assertBranded(this, DOMPointReadOnlyPrototype); + return this[_raw][2]; + } + get w() { + webidl.assertBranded(this, DOMPointReadOnlyPrototype); + return this[_raw][3]; + } + + matrixTransform(matrix = {}) { + webidl.assertBranded(this, DOMPointReadOnlyPrototype); + const prefix = "Failed to execute 'matrixTransform' on 'DOMPointReadOnly'"; + if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, matrix)) { + const _matrix = webidl.converters.DOMMatrixInit( + matrix, + prefix, + "Argument 1", + ); + validateAndFixupMatrixDictionary(_matrix, prefix); + matrix = {}; + initMatrixFromDictonary(matrix, _matrix); + } + + const point = webidl.createBranded(DOMPoint); + point[_writable] = true; + point[_raw] = new Float64Array(this[_raw]); + op_geometry_premultiply_point_self(matrix[_raw], point[_raw]); + return point; + } + + toJSON() { + webidl.assertBranded(this, DOMPointReadOnlyPrototype); + const raw = this[_raw]; + return { + x: raw[0], + y: raw[1], + z: raw[2], + w: raw[3], + }; + } + + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf(DOMPointReadOnlyPrototype, this), + keys: [ + "x", + "y", + "z", + "w", + ], + }), + inspectOptions, + ); + } +} + +webidl.configureInterface(DOMPointReadOnly); +const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; + +class DOMPoint extends DOMPointReadOnly { + [_writable] = true; + + static fromPoint(other = {}) { + other = webidl.converters.DOMPointInit( + other, + "Failed to execute 'DOMPoint.fromPoint'", + "Argument 1", + ); + const point = webidl.createBranded(DOMPoint); + point[_writable] = true; + point[_raw] = new Float64Array([ + other.x, + other.y, + other.z, + other.w, + ]); + return point; + } + + get x() { + webidl.assertBranded(this, DOMPointPrototype); + return this[_raw][0]; + } + set x(value) { + webidl.assertBranded(this, DOMPointPrototype); + assertWritable(this); + this[_raw][0] = webidl.converters["unrestricted double"](value); + } + get y() { + webidl.assertBranded(this, DOMPointPrototype); + return this[_raw][1]; + } + set y(value) { + webidl.assertBranded(this, DOMPointPrototype); + assertWritable(this); + this[_raw][1] = webidl.converters["unrestricted double"](value); + } + get z() { + webidl.assertBranded(this, DOMPointPrototype); + return this[_raw][2]; + } + set z(value) { + webidl.assertBranded(this, DOMPointPrototype); + assertWritable(this); + this[_raw][2] = webidl.converters["unrestricted double"](value); + } + get w() { + webidl.assertBranded(this, DOMPointPrototype); + return this[_raw][3]; + } + set w(value) { + webidl.assertBranded(this, DOMPointPrototype); + assertWritable(this); + this[_raw][3] = webidl.converters["unrestricted double"](value); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf(DOMPointPrototype, this), + keys: [ + "x", + "y", + "z", + "w", + ], + }), + inspectOptions, + ); + } +} + +webidl.configureInterface(DOMPoint); +const DOMPointPrototype = DOMPoint.prototype; + +class DOMRectReadOnly { + [_writable] = false; + /** @type {Float64Array} */ + [_raw]; + + constructor(x = 0, y = 0, width = 0, height = 0) { + this[_raw] = new Float64Array([ + webidl.converters["unrestricted double"](x), + webidl.converters["unrestricted double"](y), + webidl.converters["unrestricted double"](width), + webidl.converters["unrestricted double"](height), + ]); + this[_brand] = _brand; + } + + static fromRect(other = {}) { + other = webidl.converters.DOMRectInit( + other, + "Failed to execute 'DOMRectReadOnly.fromRect'", + "Argument 1", + ); + const rect = webidl.createBranded(DOMRectReadOnly); + rect[_writable] = false; + rect[_raw] = new Float64Array([ + other.x, + other.y, + other.width, + other.height, + ]); + return rect; + } + + get x() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + return this[_raw][0]; + } + get y() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + return this[_raw][1]; + } + get width() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + return this[_raw][2]; + } + get height() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + return this[_raw][3]; + } + get top() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + const raw = this[_raw]; + return MathMin(raw[1], raw[1] + raw[3]); + } + get right() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + const raw = this[_raw]; + return MathMax(raw[0], raw[0] + raw[2]); + } + get bottom() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + const raw = this[_raw]; + return MathMax(raw[1], raw[1] + raw[3]); + } + get left() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + const raw = this[_raw]; + return MathMin(raw[0], raw[0] + raw[2]); + } + + toJSON() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + const raw = this[_raw]; + return { + x: raw[0], + y: raw[1], + width: raw[2], + height: raw[3], + top: MathMin(raw[1], raw[1] + raw[3]), + right: MathMax(raw[0], raw[0] + raw[2]), + bottom: MathMax(raw[1], raw[1] + raw[3]), + left: MathMin(raw[0], raw[0] + raw[2]), + }; + } + + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf(DOMRectReadOnlyPrototype, this), + keys: [ + "x", + "y", + "width", + "height", + "top", + "right", + "bottom", + "left", + ], + }), + inspectOptions, + ); + } +} + +webidl.configureInterface(DOMRectReadOnly); +const DOMRectReadOnlyPrototype = DOMRectReadOnly.prototype; + +class DOMRect extends DOMRectReadOnly { + [_writable] = true; + + static fromRect(other = {}) { + other = webidl.converters.DOMRectInit( + other, + "Failed to execute 'DOMRect.fromRect'", + "Argument 1", + ); + const rect = webidl.createBranded(DOMRect); + rect[_writable] = true; + rect[_raw] = new Float64Array([ + other.x, + other.y, + other.width, + other.height, + ]); + return rect; + } + + get x() { + webidl.assertBranded(this, DOMRectPrototype); + return this[_raw][0]; + } + set x(value) { + webidl.assertBranded(this, DOMRectPrototype); + assertWritable(this); + this[_raw][0] = webidl.converters["unrestricted double"](value); + } + get y() { + webidl.assertBranded(this, DOMRectPrototype); + return this[_raw][1]; + } + set y(value) { + webidl.assertBranded(this, DOMRectPrototype); + assertWritable(this); + this[_raw][1] = webidl.converters["unrestricted double"](value); + } + get width() { + webidl.assertBranded(this, DOMRectPrototype); + return this[_raw][2]; + } + set width(value) { + webidl.assertBranded(this, DOMRectPrototype); + assertWritable(this); + this[_raw][2] = webidl.converters["unrestricted double"](value); + } + get height() { + webidl.assertBranded(this, DOMRectPrototype); + return this[_raw][3]; + } + set height(value) { + webidl.assertBranded(this, DOMRectPrototype); + assertWritable(this); + this[_raw][3] = webidl.converters["unrestricted double"](value); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf(DOMRectPrototype, this), + keys: [ + "x", + "y", + "width", + "height", + "top", + "right", + "bottom", + "left", + ], + }), + inspectOptions, + ); + } +} + +webidl.configureInterface(DOMRect); +const DOMRectPrototype = DOMRect.prototype; + +const _p1 = Symbol("[[p1]]"); +const _p2 = Symbol("[[p2]]"); +const _p3 = Symbol("[[p3]]"); +const _p4 = Symbol("[[p4]]"); + +class DOMQuad { + /** @type {DOMPoint} */ + [_p1]; + /** @type {DOMPoint} */ + [_p2]; + /** @type {DOMPoint} */ + [_p3]; + /** @type {DOMPoint} */ + [_p4]; + + constructor(p1 = {}, p2 = {}, p3 = {}, p4 = {}) { + this[_p1] = DOMPoint.fromPoint(p1); + this[_p2] = DOMPoint.fromPoint(p2); + this[_p3] = DOMPoint.fromPoint(p3); + this[_p4] = DOMPoint.fromPoint(p4); + this[_brand] = _brand; + } + + static fromRect(other = {}) { + other = webidl.converters.DOMRectInit( + other, + "Failed to execute 'DOMQuad.fromRect'", + "Argument 1", + ); + const { x, y, width, height } = other; + const quad = webidl.createBranded(DOMQuad); + quad[_p1] = new DOMPoint(x, y, 0, 1); + quad[_p2] = new DOMPoint(x + width, y, 0, 1); + quad[_p3] = new DOMPoint(x + width, y + height, 0, 1); + quad[_p4] = new DOMPoint(x, y + height, 0, 1); + return quad; + } + + static fromQuad(other = {}) { + other = webidl.converters.DOMQuadInit( + other, + "Failed to execute 'DOMQuad.fromQuad'", + "Argument 1", + ); + const quad = webidl.createBranded(DOMQuad); + quad[_p1] = DOMPoint.fromPoint(other.p1); + quad[_p2] = DOMPoint.fromPoint(other.p2); + quad[_p3] = DOMPoint.fromPoint(other.p3); + quad[_p4] = DOMPoint.fromPoint(other.p4); + return quad; + } + + get p1() { + webidl.assertBranded(this, DOMQuadPrototype); + return this[_p1]; + } + get p2() { + webidl.assertBranded(this, DOMQuadPrototype); + return this[_p2]; + } + get p3() { + webidl.assertBranded(this, DOMQuadPrototype); + return this[_p3]; + } + get p4() { + webidl.assertBranded(this, DOMQuadPrototype); + return this[_p4]; + } + + getBounds() { + webidl.assertBranded(this, DOMQuadPrototype); + const { x: p1x, y: p1y } = this[_p1]; + const { x: p2x, y: p2y } = this[_p2]; + const { x: p3x, y: p3y } = this[_p3]; + const { x: p4x, y: p4y } = this[_p4]; + + const left = MathMin(p1x, p2x, p3x, p4x); + const top = MathMin(p1y, p2y, p3y, p4y); + const right = MathMax(p1x, p2x, p3x, p4x); + const bottom = MathMax(p1y, p2y, p3y, p4y); + + const bounds = webidl.createBranded(DOMRect); + bounds[_writable] = true; + bounds[_raw] = new Float64Array([ + left, + top, + right - left, + bottom - top, + ]); + return bounds; + } + + toJSON() { + webidl.assertBranded(this, DOMQuadPrototype); + return { + p1: this[_p1], + p2: this[_p2], + p3: this[_p3], + p4: this[_p4], + }; + } + + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf(DOMQuadPrototype, this), + keys: [ + "p1", + "p2", + "p3", + "p4", + ], + }), + inspectOptions, + ); + } +} + +webidl.configureInterface(DOMQuad); +const DOMQuadPrototype = DOMQuad.prototype; + +/* + * NOTE: column-major order + * + * For a 2D 3x2 matrix, the index of properties in + * | a c 0 e | | 0 4 _ 12 | + * | b d 0 f | | 1 5 _ 13 | + * | 0 0 1 0 | is | _ _ _ _ | + * | 0 0 0 1 | | _ _ _ _ | + */ +const INDEX_A = 0; +const INDEX_B = 1; +const INDEX_C = 4; +const INDEX_D = 5; +const INDEX_E = 12; +const INDEX_F = 13; + +/* + * NOTE: column-major order + * + * The index of properties in + * | m11 m21 m31 m41 | | 0 4 8 12 | + * | m12 m22 m32 m42 | | 1 5 9 13 | + * | m13 m23 m33 m43 | is | 2 6 10 14 | + * | m14 m24 m34 m44 | | 3 7 11 15 | + */ +const INDEX_M11 = 0; +const INDEX_M12 = 1; +const INDEX_M13 = 2; +const INDEX_M14 = 3; +const INDEX_M21 = 4; +const INDEX_M22 = 5; +const INDEX_M23 = 6; +const INDEX_M24 = 7; +const INDEX_M31 = 8; +const INDEX_M32 = 9; +const INDEX_M33 = 10; +const INDEX_M34 = 11; +const INDEX_M41 = 12; +const INDEX_M42 = 13; +const INDEX_M43 = 14; +const INDEX_M44 = 15; + +const _is2D = Symbol("[[is2D]]"); + +class DOMMatrixReadOnly { + [_writable] = false; + /** @type {Float64Array} */ + [_raw]; + /** @type {boolean} */ + [_is2D]; + + constructor(init = undefined) { + const prefix = `Failed to construct '${this.constructor.name}'`; + this[_brand] = _brand; + if (init === undefined) { + // deno-fmt-ignore + this[_raw] = new Float64Array([ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + ]); + this[_is2D] = true; + } else if ( + webidl.type(init) === "Object" && init[SymbolIterator] !== undefined + ) { + init = webidl.converters["sequence"]( + init, + prefix, + "Argument 1", + ); + initMatrixFromSequence(this, init, prefix); + } else { + init = webidl.converters.DOMString( + init, + prefix, + "Argument 1", + ); + const { matrix, is2D } = parseTransformList(init, prefix); + this[_raw] = matrix; + this[_is2D] = is2D; + } + } + + static fromMatrix(other = {}) { + const prefix = "Failed to execute 'DOMMatrixReadOnly.fromMatrix'"; + const matrix = webidl.createBranded(DOMMatrixReadOnly); + matrix[_writable] = false; + // fast path for DOMMatrix or DOMMatrixReadOnly + if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { + initMatrixFromMatrix(matrix, other); + } else { + other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); + validateAndFixupMatrixDictionary(other, prefix); + initMatrixFromDictonary(matrix, other); + } + return matrix; + } + + static fromFloat32Array(float32) { + const prefix = "Failed to execute 'DOMMatrixReadOnly.fromFloat32Array'"; + webidl.requiredArguments(arguments.length, 1, prefix); + float32 = webidl.converters.Float32Array(float32, prefix, "Argument 1"); + const matrix = webidl.createBranded(DOMMatrixReadOnly); + matrix[_writable] = false; + initMatrixFromSequence(matrix, float32, prefix); + return matrix; + } + + static fromFloat64Array(float64) { + const prefix = "Failed to execute 'DOMMatrixReadOnly.fromFloat64Array'"; + webidl.requiredArguments(arguments.length, 1, prefix); + float64 = webidl.converters.Float64Array(float64, prefix, "Argument 1"); + const matrix = webidl.createBranded(DOMMatrixReadOnly); + matrix[_writable] = false; + initMatrixFromSequence(matrix, float64, prefix); + return matrix; + } + + get a() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_A]; + } + get b() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_B]; + } + get c() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_C]; + } + get d() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_D]; + } + get e() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_E]; + } + get f() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_F]; + } + get m11() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M11]; + } + get m12() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M12]; + } + get m13() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M13]; + } + get m14() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M14]; + } + get m21() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M21]; + } + get m22() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M22]; + } + get m23() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M23]; + } + get m24() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M24]; + } + get m31() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M31]; + } + get m32() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M32]; + } + get m33() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M33]; + } + get m34() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M34]; + } + get m41() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M41]; + } + get m42() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M42]; + } + get m43() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M43]; + } + get m44() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M44]; + } + get is2D() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_is2D]; + } + get isIdentity() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return isIdentityMatrix(this); + } + + translate(tx = 0, ty = 0, tz = 0) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + tx = webidl.converters["unrestricted double"](tx); + ty = webidl.converters["unrestricted double"](ty); + tz = webidl.converters["unrestricted double"](tz); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_translate_self( + tx, + ty, + tz, + matrix[_raw], + ); + matrix[_is2D] = this[_is2D] && tz === 0; + return matrix; + } + + scale( + scaleX = 1, + scaleY = scaleX, + scaleZ = 1, + originX = 0, + originY = 0, + originZ = 0, + ) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + scaleX = webidl.converters["unrestricted double"](scaleX); + scaleY = webidl.converters["unrestricted double"](scaleY); + scaleZ = webidl.converters["unrestricted double"](scaleZ); + originX = webidl.converters["unrestricted double"](originX); + originY = webidl.converters["unrestricted double"](originY); + originZ = webidl.converters["unrestricted double"](originZ); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + if (originX === 0 && originY === 0 && originZ === 0) { + op_geometry_scale_self( + scaleX, + scaleY, + scaleZ, + matrix[_raw], + ); + } else { + op_geometry_scale_with_origin_self( + scaleX, + scaleY, + scaleZ, + originX, + originY, + originZ, + matrix[_raw], + ); + } + matrix[_is2D] = this[_is2D] && scaleZ === 1 && originZ === 0; + return matrix; + } + + scaleNonUniform(scaleX = 1, scaleY = 1) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + scaleX = webidl.converters["unrestricted double"](scaleX); + scaleY = webidl.converters["unrestricted double"](scaleY); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_scale_self( + scaleX, + scaleY, + 1, + matrix[_raw], + ); + matrix[_is2D] = this[_is2D]; + return matrix; + } + + scale3d(scale = 1, originX = 0, originY = 0, originZ = 0) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + scale = webidl.converters["unrestricted double"](scale); + originX = webidl.converters["unrestricted double"](originX); + originY = webidl.converters["unrestricted double"](originY); + originZ = webidl.converters["unrestricted double"](originZ); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + if (originX === 0 && originY === 0 && originZ === 0) { + op_geometry_scale_self( + scale, + scale, + scale, + matrix[_raw], + ); + } else { + op_geometry_scale_with_origin_self( + scale, + scale, + scale, + originX, + originY, + originZ, + matrix[_raw], + ); + } + matrix[_is2D] = this[_is2D] && scale === 1 && originZ === 0; + return matrix; + } + + rotate(rotX = 0, rotY, rotZ) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + rotX = webidl.converters["unrestricted double"](rotX); + if (rotY === undefined && rotZ === undefined) { + rotZ = rotX; + rotX = 0; + rotY = 0; + } else { + rotY = rotY !== undefined + ? webidl.converters["unrestricted double"](rotY) + : 0; + rotZ = rotZ !== undefined + ? webidl.converters["unrestricted double"](rotZ) + : 0; + } + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_rotate_self( + rotX, + rotY, + rotZ, + matrix[_raw], + ); + matrix[_is2D] = this[_is2D] && rotX === 0 && rotY === 0; + return matrix; + } + + rotateFromVector(x = 0, y = 0) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + x = webidl.converters["unrestricted double"](x); + y = webidl.converters["unrestricted double"](y); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_rotate_from_vector_self( + x, + y, + matrix[_raw], + ); + matrix[_is2D] = this[_is2D]; + return matrix; + } + + rotateAxisAngle(x = 0, y = 0, z = 0, angle = 0) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + x = webidl.converters["unrestricted double"](x); + y = webidl.converters["unrestricted double"](y); + z = webidl.converters["unrestricted double"](z); + angle = webidl.converters["unrestricted double"](angle); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + if (x !== 0 || y !== 0 || z !== 0) { + op_geometry_rotate_axis_angle_self( + x, + y, + z, + angle, + matrix[_raw], + ); + } + matrix[_is2D] = this[_is2D] && x === 0 && y === 0; + return matrix; + } + + skewX(sx = 0) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + sx = webidl.converters["unrestricted double"](sx); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_skew_self( + sx, + 0, + matrix[_raw], + ); + matrix[_is2D] = this[_is2D]; + return matrix; + } + + skewY(sy = 0) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + sy = webidl.converters["unrestricted double"](sy); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_skew_self( + 0, + sy, + matrix[_raw], + ); + matrix[_is2D] = this[_is2D]; + return matrix; + } + + multiply(other = {}) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const prefix = "Failed to execute 'multiply' on 'DOMMatrixReadOnly'"; + if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { + const _other = webidl.converters.DOMMatrixInit( + other, + prefix, + "Argument 1", + ); + validateAndFixupMatrixDictionary(_other, prefix); + other = {}; + initMatrixFromDictonary(other, _other); + } + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(16); + op_geometry_multiply(this[_raw], other[_raw], matrix[_raw]); + matrix[_is2D] = this[_is2D] && other[_is2D]; + return matrix; + } + + flipX() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_flip_x_self(matrix[_raw]); + matrix[_is2D] = this[_is2D]; + return matrix; + } + + flipY() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_flip_y_self(matrix[_raw]); + matrix[_is2D] = this[_is2D]; + return matrix; + } + + inverse() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + let invertible; + if (this[_is2D]) { + invertible = op_geometry_invert_2d_self(matrix[_raw]); + } else { + invertible = op_geometry_invert_self(matrix[_raw]); + } + matrix[_is2D] = this[_is2D] && invertible; + return matrix; + } + + transformPoint(point = {}) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + point = webidl.converters.DOMPointInit( + point, + "Failed to execute 'transformPoint' on 'DOMMatrixReadOnly'", + "Argument 1", + ); + const result = webidl.createBranded(DOMPoint); + result[_writable] = true; + result[_raw] = new Float64Array([ + point.x, + point.y, + point.z, + point.w, + ]); + op_geometry_premultiply_point_self(this[_raw], result[_raw]); + return result; + } + + toFloat32Array() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return new Float32Array(this[_raw]); + } + + toFloat64Array() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return new Float64Array(this[_raw]); + } + + toJSON() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const raw = this[_raw]; + return { + a: raw[INDEX_A], + b: raw[INDEX_B], + c: raw[INDEX_C], + d: raw[INDEX_D], + e: raw[INDEX_E], + f: raw[INDEX_F], + m11: raw[INDEX_M11], + m12: raw[INDEX_M12], + m13: raw[INDEX_M13], + m14: raw[INDEX_M14], + m21: raw[INDEX_M21], + m22: raw[INDEX_M22], + m23: raw[INDEX_M23], + m24: raw[INDEX_M24], + m31: raw[INDEX_M31], + m32: raw[INDEX_M32], + m33: raw[INDEX_M33], + m34: raw[INDEX_M34], + m41: raw[INDEX_M41], + m42: raw[INDEX_M42], + m43: raw[INDEX_M43], + m44: raw[INDEX_M44], + is2D: this[_is2D], + isIdentity: isIdentityMatrix(this), + }; + } + + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf( + DOMMatrixReadOnlyPrototype, + this, + ), + keys: [ + "a", + "b", + "c", + "d", + "e", + "f", + "m11", + "m12", + "m13", + "m14", + "m21", + "m22", + "m23", + "m24", + "m31", + "m32", + "m33", + "m34", + "m41", + "m42", + "m43", + "m44", + "is2D", + "isIdentity", + ], + }), + inspectOptions, + ); + } +} + +webidl.configureInterface(DOMMatrixReadOnly); +const DOMMatrixReadOnlyPrototype = DOMMatrixReadOnly.prototype; + +class DOMMatrix extends DOMMatrixReadOnly { + [_writable] = true; + + static fromMatrix(other = {}) { + const prefix = "Failed to execute 'DOMMatrix.fromMatrix'"; + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + // fast path for DOMMatrix or DOMMatrixReadOnly + if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { + initMatrixFromMatrix(matrix, other); + } else { + other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); + validateAndFixupMatrixDictionary(other, prefix); + initMatrixFromDictonary(matrix, other); + } + return matrix; + } + + static fromFloat32Array(float32) { + const prefix = "Failed to execute 'DOMMatrix.fromFloat32Array'"; + webidl.requiredArguments(arguments.length, 1, prefix); + float32 = webidl.converters.Float32Array(float32, prefix, "Argument 1"); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + initMatrixFromSequence(matrix, float32, prefix); + return matrix; + } + + static fromFloat64Array(float64) { + const prefix = "Failed to execute 'DOMMatrix.fromFloat64Array'"; + webidl.requiredArguments(arguments.length, 1, prefix); + float64 = webidl.converters.Float64Array(float64, prefix, "Argument 1"); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + initMatrixFromSequence(matrix, float64, prefix); + return matrix; + } + + get a() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_A]; + } + set a(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_A] = webidl.converters["unrestricted double"](value); + } + get b() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_B]; + } + set b(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_B] = webidl.converters["unrestricted double"](value); + } + get c() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_C]; + } + set c(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_C] = webidl.converters["unrestricted double"](value); + } + get d() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_D]; + } + set d(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_D] = webidl.converters["unrestricted double"](value); + } + get e() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_E]; + } + set e(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_E] = webidl.converters["unrestricted double"](value); + } + get f() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_F]; + } + set f(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_F] = webidl.converters["unrestricted double"](value); + } + get m11() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M11]; + } + set m11(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_M11] = webidl.converters["unrestricted double"](value); + } + get m12() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M12]; + } + set m12(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_M12] = webidl.converters["unrestricted double"](value); + } + get m13() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M13]; + } + set m13(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][INDEX_M13] = webidl.converters["unrestricted double"](value); + } + get m14() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M14]; + } + set m14(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][INDEX_M14] = webidl.converters["unrestricted double"](value); + } + get m21() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M21]; + } + set m21(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_M21] = webidl.converters["unrestricted double"](value); + } + get m22() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M22]; + } + set m22(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_M22] = webidl.converters["unrestricted double"](value); + } + get m23() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M23]; + } + set m23(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][INDEX_M23] = webidl.converters["unrestricted double"](value); + } + get m24() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M24]; + } + set m24(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][INDEX_M24] = webidl.converters["unrestricted double"](value); + } + get m31() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M31]; + } + set m31(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][INDEX_M31] = webidl.converters["unrestricted double"](value); + } + get m32() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M32]; + } + set m32(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][INDEX_M32] = webidl.converters["unrestricted double"](value); + } + get m33() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M33]; + } + set m33(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 1) { + this[_is2D] = false; + } + this[_raw][INDEX_M33] = webidl.converters["unrestricted double"](value); + } + get m34() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M34]; + } + set m34(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][INDEX_M34] = webidl.converters["unrestricted double"](value); + } + get m41() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M41]; + } + set m41(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_M41] = webidl.converters["unrestricted double"](value); + } + get m42() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M42]; + } + set m42(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_M42] = webidl.converters["unrestricted double"](value); + } + get m43() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M43]; + } + set m43(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][INDEX_M43] = webidl.converters["unrestricted double"](value); + } + get m44() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M44]; + } + set m44(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 1) { + this[_is2D] = false; + } + this[_raw][INDEX_M44] = webidl.converters["unrestricted double"](value); + } + + multiplySelf(other = {}) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + const prefix = "Failed to execute 'multiplySelf' on 'DOMMatrix'"; + if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { + const _other = webidl.converters.DOMMatrixInit( + other, + prefix, + "Argument 1", + ); + validateAndFixupMatrixDictionary(_other, prefix); + other = {}; + initMatrixFromDictonary(other, _other); + } else if (this[_raw] === other[_raw]) { + other = {}; + initMatrixFromMatrix(other, this); + } + + op_geometry_multiply_self(other[_raw], this[_raw]); + this[_is2D] &&= other[_is2D]; + return this; + } + + preMultiplySelf(other = {}) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + const prefix = "Failed to execute 'premultiplySelf' on 'DOMMatrix'"; + if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { + const _other = webidl.converters.DOMMatrixInit( + other, + prefix, + "Argument 1", + ); + validateAndFixupMatrixDictionary(_other, prefix); + other = {}; + initMatrixFromDictonary(other, _other); + } else if (this[_raw] === other[_raw]) { + other = {}; + initMatrixFromMatrix(other, this); + } + + op_geometry_premultiply_self(other[_raw], this[_raw]); + this[_is2D] &&= other[_is2D]; + return this; + } + + translateSelf(tx = 0, ty = 0, tz = 0) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + tx = webidl.converters["unrestricted double"](tx); + ty = webidl.converters["unrestricted double"](ty); + tz = webidl.converters["unrestricted double"](tz); + op_geometry_translate_self( + tx, + ty, + tz, + this[_raw], + ); + this[_is2D] &&= tz === 0; + return this; + } + + scaleSelf( + scaleX = 1, + scaleY = scaleX, + scaleZ = 1, + originX = 0, + originY = 0, + originZ = 0, + ) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + scaleX = webidl.converters["unrestricted double"](scaleX); + scaleY = webidl.converters["unrestricted double"](scaleY); + scaleZ = webidl.converters["unrestricted double"](scaleZ); + originX = webidl.converters["unrestricted double"](originX); + originY = webidl.converters["unrestricted double"](originY); + originZ = webidl.converters["unrestricted double"](originZ); + if (originX === 0 && originY === 0 && originZ === 0) { + op_geometry_scale_self( + scaleX, + scaleY, + scaleZ, + this[_raw], + ); + } else { + op_geometry_scale_with_origin_self( + scaleX, + scaleY, + scaleZ, + originX, + originY, + originZ, + this[_raw], + ); + } + this[_is2D] &&= scaleZ === 1 && originZ === 0; + return this; + } + + scale3dSelf(scale = 1, originX = 0, originY = 0, originZ = 0) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + scale = webidl.converters["unrestricted double"](scale); + originX = webidl.converters["unrestricted double"](originX); + originY = webidl.converters["unrestricted double"](originY); + originZ = webidl.converters["unrestricted double"](originZ); + if (originX === 0 && originY === 0 && originZ === 0) { + op_geometry_scale_self( + scale, + scale, + scale, + this[_raw], + ); + } else { + op_geometry_scale_with_origin_self( + scale, + scale, + scale, + originX, + originY, + originZ, + this[_raw], + ); + } + this[_is2D] &&= scale === 1 && originZ === 0; + return this; + } + + rotateSelf(rotX = 0, rotY, rotZ) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + rotX = webidl.converters["unrestricted double"](rotX); + if (rotY === undefined && rotZ === undefined) { + rotZ = rotX; + rotX = 0; + rotY = 0; + } else { + rotY = rotY !== undefined + ? webidl.converters["unrestricted double"](rotY) + : 0; + rotZ = rotZ !== undefined + ? webidl.converters["unrestricted double"](rotZ) + : 0; + } + op_geometry_rotate_self( + rotX, + rotY, + rotZ, + this[_raw], + ); + this[_is2D] &&= rotX === 0 && rotY === 0; + return this; + } + + rotateFromVectorSelf(x = 0, y = 0) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + x = webidl.converters["unrestricted double"](x); + y = webidl.converters["unrestricted double"](y); + op_geometry_rotate_from_vector_self( + x, + y, + this[_raw], + ); + return this; + } + + rotateAxisAngleSelf(x = 0, y = 0, z = 0, angle = 0) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + x = webidl.converters["unrestricted double"](x); + y = webidl.converters["unrestricted double"](y); + z = webidl.converters["unrestricted double"](z); + angle = webidl.converters["unrestricted double"](angle); + if (x !== 0 || y !== 0 || z !== 0) { + op_geometry_rotate_axis_angle_self( + x, + y, + z, + angle, + this[_raw], + ); + } + this[_is2D] &&= x === 0 && y === 0; + return this; + } + + skewXSelf(sx = 0) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + sx = webidl.converters["unrestricted double"](sx); + op_geometry_skew_self( + sx, + 0, + this[_raw], + ); + return this; + } + + skewYSelf(sy = 0) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + sy = webidl.converters["unrestricted double"](sy); + op_geometry_skew_self( + 0, + sy, + this[_raw], + ); + return this; + } + + invertSelf() { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + let invertible; + if (this[_is2D]) { + invertible = op_geometry_invert_2d_self(this[_raw]); + } else { + invertible = op_geometry_invert_self(this[_raw]); + } + this[_is2D] &&= invertible; + return this; + } + + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf(DOMMatrixPrototype, this), + keys: [ + "a", + "b", + "c", + "d", + "e", + "f", + "m11", + "m12", + "m13", + "m14", + "m21", + "m22", + "m23", + "m24", + "m31", + "m32", + "m33", + "m34", + "m41", + "m42", + "m43", + "m44", + "is2D", + "isIdentity", + ], + }), + inspectOptions, + ); + } +} + +webidl.configureInterface(DOMMatrix); +const DOMMatrixPrototype = DOMMatrix.prototype; + +/** + * TODO(petamoriken): Support this by updating WebIDL's brand features + * @param {DOMRect | DOMPoint | DOMMatrix} self + */ +function assertWritable(self) { + if (self[_writable] !== true) { + throw new TypeError("Illegal invocation"); + } +} + +/** + * https://tc39.es/ecma262/#sec-samevaluezero + * @param {number} x + * @param {number} y + */ +function sameValueZero(x, y) { + return x === y || ObjectIs(x, y); +} + +/** + * https://drafts.fxtf.org/geometry/#matrix-validate-and-fixup-2d + * @param {object} dict + * @param {string} prefix + */ +function validateAndFixup2DMatrixDictionary(dict, prefix) { + if ( + ( + dict.a !== undefined && dict.m11 !== undefined && + !sameValueZero(dict.a, dict.m11) + ) || + ( + dict.b !== undefined && dict.m12 !== undefined && + !sameValueZero(dict.b, dict.m12) + ) || + ( + dict.c !== undefined && dict.m21 !== undefined && + !sameValueZero(dict.c, dict.m21) + ) || + ( + dict.d !== undefined && dict.m22 !== undefined && + !sameValueZero(dict.d, dict.m22) + ) || + ( + dict.e !== undefined && dict.m41 !== undefined && + !sameValueZero(dict.e, dict.m41) + ) || + ( + dict.f !== undefined && dict.m42 !== undefined && + !sameValueZero(dict.f, dict.m42) + ) + ) { + throw new TypeError(`${prefix}: Inconsistent 2d matrix value`); + } + if (dict.m11 === undefined) dict.m11 = dict.a ?? 1; + if (dict.m12 === undefined) dict.m12 = dict.b ?? 0; + if (dict.m21 === undefined) dict.m21 = dict.c ?? 0; + if (dict.m22 === undefined) dict.m22 = dict.d ?? 1; + if (dict.m41 === undefined) dict.m41 = dict.e ?? 0; + if (dict.m42 === undefined) dict.m42 = dict.f ?? 0; +} + +/** + * https://drafts.fxtf.org/geometry/#matrix-validate-and-fixup + * @param {object} dict + * @param {string} prefix + */ +function validateAndFixupMatrixDictionary(dict, prefix) { + validateAndFixup2DMatrixDictionary(dict, prefix); + const is2DCanBeTrue = dict.m13 === 0 && + dict.m14 === 0 && + dict.m23 === 0 && + dict.m24 === 0 && + dict.m31 === 0 && + dict.m32 === 0 && + dict.m33 === 1 && + dict.m34 === 0 && + dict.m43 === 0 && + dict.m44 === 1; + if (dict.is2D === true && !is2DCanBeTrue) { + throw new TypeError( + `${prefix}: is2D property is true but the input matrix is a 3d matrix`, + ); + } + if (dict.is2D === undefined) { + dict.is2D = is2DCanBeTrue; + } +} + +/** + * @param {object} target + * @param {number[] | Float32Array | Float64Array} seq + * @param {string} prefix + */ +function initMatrixFromSequence(target, seq, prefix) { + if (seq.length === 6) { + const { 0: a, 1: b, 2: c, 3: d, 4: e, 5: f } = seq; + // deno-fmt-ignore + target[_raw] = new Float64Array([ + a, b, 0, 0, + c, d, 0, 0, + 0, 0, 1, 0, + e, f, 0, 1, + ]); + target[_is2D] = true; + } else if (seq.length === 16) { + target[_raw] = new Float64Array(seq); + target[_is2D] = false; + } else { + throw new TypeError( + `${prefix}: The sequence must contain 6 elements for a 2D matrix or 16 elements for a 3D matrix`, + ); + } +} + +/** + * @param {object} target + * @param {object} dict + */ +function initMatrixFromDictonary(target, dict) { + if (dict.is2D) { + const { m11, m12, m21, m22, m41, m42 } = dict; + // deno-fmt-ignore + target[_raw] = new Float64Array([ + m11, m12, 0, 0, + m21, m22, 0, 0, + 0, 0, 1, 0, + m41, m42, 0, 1, + ]); + target[_is2D] = true; + } else { + const { + m11, + m12, + m13, + m14, + m21, + m22, + m23, + m24, + m31, + m32, + m33, + m34, + m41, + m42, + m43, + m44, + } = dict; + // deno-fmt-ignore + target[_raw] = new Float64Array([ + m11, m12, m13, m14, + m21, m22, m23, m24, + m31, m32, m33, m34, + m41, m42, m43, m44, + ]); + target[_is2D] = false; + } +} + +/** + * @param {object} target + * @type {DOMMatrixReadOnly} matrix + */ +function initMatrixFromMatrix(target, matrix) { + target[_raw] = new Float64Array(matrix[_raw]); + target[_is2D] = matrix[_is2D]; +} + +/** + * https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-isidentity + * @param {DOMMatrixReadOnly} matrix + */ +function isIdentityMatrix(matrix) { + const raw = matrix[_raw]; + return ( + raw[INDEX_M11] === 1 && + raw[INDEX_M12] === 0 && + raw[INDEX_M13] === 0 && + raw[INDEX_M14] === 0 && + raw[INDEX_M21] === 0 && + raw[INDEX_M22] === 1 && + raw[INDEX_M23] === 0 && + raw[INDEX_M24] === 0 && + raw[INDEX_M31] === 0 && + raw[INDEX_M32] === 0 && + raw[INDEX_M33] === 1 && + raw[INDEX_M34] === 0 && + raw[INDEX_M41] === 0 && + raw[INDEX_M42] === 0 && + raw[INDEX_M43] === 0 && + raw[INDEX_M44] === 1 + ); +} + +/** + * CSS parser + * @type {((transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean })} + */ +let parseTransformList; + +/** + * @param {(transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean }} transformListParser + * @param {boolean} enableWindowFeatures + */ +function init(transformListParser, enableWindowFeatures) { + parseTransformList = transformListParser; + + if (enableWindowFeatures) { + // https://drafts.fxtf.org/geometry/#dommatrixreadonly-stringification-behavior + ObjectDefineProperty(DOMMatrixReadOnlyPrototype, "toString", { + value: function toString() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const raw = this[_raw]; + if (!TypedArrayPrototypeEvery(raw, (value) => NumberIsFinite(value))) { + throw new DOMException( + "Failed to execute 'toString' on 'DOMMatrixReadOnly': Cannot be serialized with NaN or Infinity values", + "InvalidStateError", + ); + } + if (this[_is2D]) { + return `matrix(${ + ArrayPrototypeJoin([ + raw[INDEX_A], + raw[INDEX_B], + raw[INDEX_C], + raw[INDEX_D], + raw[INDEX_E], + raw[INDEX_F], + ], ", ") + })`; + } else { + return `matrix3d(${TypedArrayPrototypeJoin(raw, ", ")})`; + } + }, + writable: true, + enumerable: true, + configurable: true, + }); + + // https://drafts.fxtf.org/geometry/#dom-dommatrix-setmatrixvalue + ObjectDefineProperty(DOMMatrixPrototype, "setMatrixValue", { + value: function setMatrixValue(transformList) { + webidl.assertBranded(this, DOMMatrixPrototype); + const prefix = "Failed to execute 'setMatrixValue' on 'DOMMatrix'"; + webidl.requiredArguments(arguments.length, 1, prefix); + transformList = webidl.converters.DOMString( + transformList, + prefix, + "Argument 1", + ); + const { matrix, is2D } = parseTransformList(transformList, prefix); + this[_raw] = matrix; + this[_is2D] = is2D; + }, + writable: true, + enumerable: true, + configurable: true, + }); + } +} + +export { + DOMMatrix, + DOMMatrixPrototype, + DOMMatrixReadOnly, + DOMMatrixReadOnlyPrototype, + DOMPoint, + DOMPointPrototype, + DOMPointReadOnly, + DOMPointReadOnlyPrototype, + DOMQuad, + DOMQuadPrototype, + DOMRect, + DOMRectPrototype, + DOMRectReadOnly, + DOMRectReadOnlyPrototype, + init, +}; diff --git a/ext/geometry/Cargo.toml b/ext/geometry/Cargo.toml new file mode 100644 index 00000000000000..9ab2c7c698eaeb --- /dev/null +++ b/ext/geometry/Cargo.toml @@ -0,0 +1,18 @@ +# Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +[package] +name = "deno_geometry" +version = "0.1.0" +authors.workspace = true +edition.workspace = true +license.workspace = true +readme = "README.md" +repository.workspace = true +description = "Geometry Interfaces Module API implementation for Deno" + +[lib] +path = "lib.rs" + +[dependencies] +deno_core.workspace = true +nalgebra.workspace = true diff --git a/ext/geometry/README.md b/ext/geometry/README.md new file mode 100644 index 00000000000000..09465490254c8e --- /dev/null +++ b/ext/geometry/README.md @@ -0,0 +1,108 @@ +# deno_geometry + +This crate implements the Geometry Interfaces Module API. + +Spec: https://drafts.fxtf.org/geometry/ + +## Usage Example + +From javascript, include the extension's source: + +```javascript +import { core } from "ext:core/mod.js"; +import { createGeometryLoader } from "ext:deno_geometry/00_init.js"; +``` + +For environments that do not have a CSS `` parser, such as Web Worker, configure as follows: + +```javascript +const loadGeometry = createGeometryLoader((_transformList, prefix) => { + throw new TypeError( + `${prefix}: Cannot parse CSS on Workers`, + ); +}, /* enableWindowFeatures */ false); +``` + +On the other hand, in environments with a CSS `` parser, you can configure as follows: + +```javascript +const loadGeometry = createGeometryLoader((transformList, prefix) => { + try { + // parse by yourself + const { sequence, is2D } = parse(transformList); + return { + matrix: new Float64Array(sequence), + is2D, + }; + } catch { + throw new TypeError( + `${prefix}: Invalid string: ${transformList}`, + ); + } +}, /* enableWindowFeatures */ true); +``` + +Then define to globalThis: + +```javascript +Object.defineProperties(globalThis, { + DOMMatrix: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMMatrix, + loadGeometry, + ), + DOMMatrixReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMMatrixReadOnly, + loadGeometry, + ), + DOMPoint: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMPoint, + loadGeometry, + ), + DOMPointReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMPointReadOnly, + loadGeometry, + ), + DOMQuad: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMQuad, + loadGeometry, + ), + DOMRect: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMRect, + loadGeometry, + ), + DOMRectReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMRectReadOnly, + loadGeometry, + ), +}); +``` + +Then from rust, provide: +`deno_geometry::deno_geometry::init_ops_and_esm()` in the `extensions` +field of your `RuntimeOptions` + +## Dependencies + +- **deno_webidl**: Provided by the `deno_webidl` crate +- **deno_web**: Provided by the `deno_web` crate +- **deno_console**: Provided by the `deno_console` crate + +## Provided ops + +Following ops are provided, which can be accessed through `Deno.ops`: + +- op_geometry_translate_self +- op_geometry_scale_self +- op_geometry_scale_with_origin_self +- op_geometry_rotate_self +- op_geometry_rotate_from_vector_self +- op_geometry_rotate_axis_angle_self +- op_geometry_skew_self +- op_geometry_multiply +- op_geometry_multiply_self +- op_geometry_premultiply_self +- op_geometry_flip_x_self +- op_geometry_flip_y_self +- op_geometry_invert_self +- op_geometry_invert_2d_self +- op_geometry_premultiply_point_self diff --git a/ext/geometry/lib.deno_geometry.d.ts b/ext/geometry/lib.deno_geometry.d.ts new file mode 100644 index 00000000000000..44b06d763ebf50 --- /dev/null +++ b/ext/geometry/lib.deno_geometry.d.ts @@ -0,0 +1,602 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +// deno-lint-ignore-file no-var + +/// +/// + +/** @category Geometry Interfaces Module API */ +declare interface DOMMatrix2DInit { + a?: number; + b?: number; + c?: number; + d?: number; + e?: number; + f?: number; + m11?: number; + m12?: number; + m21?: number; + m22?: number; + m41?: number; + m42?: number; +} + +/** @category Geometry Interfaces Module API */ +declare interface DOMMatrixInit extends DOMMatrix2DInit { + is2D?: boolean; + m13?: number; + m14?: number; + m23?: number; + m24?: number; + m31?: number; + m32?: number; + m33?: number; + m34?: number; + m43?: number; + m44?: number; +} + +/** + * A 4×4 matrix (column-major order), suitable for 2D and 3D operations including rotation and translation. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMMatrix) + * + * ``` + * | m11 m21 m31 m41 | + * | m12 m22 m32 m42 | + * | m13 m23 m33 m43 | + * | m14 m24 m34 m44 | + * ``` + * + * @category Geometry Interfaces Module API + */ +declare interface DOMMatrix extends DOMMatrixReadOnly { + a: number; + b: number; + c: number; + d: number; + e: number; + f: number; + m11: number; + m12: number; + m13: number; + m14: number; + m21: number; + m22: number; + m23: number; + m24: number; + m31: number; + m32: number; + m33: number; + m34: number; + m41: number; + m42: number; + m43: number; + m44: number; + /** + * Modifies the matrix by inverting it. + * If the matrix can't be inverted, its components are all set to `NaN`, and is2D property is set to `false`. + */ + invertSelf(): DOMMatrix; + /** + * Modifies the matrix by post-multiplying it with the specified DOMMatrix. + * This is equivalent to the dot product `A⋅B`, where matrix `A` is the source matrix and `B` is the matrix given as an input to the method. + * + * @param other + */ + multiplySelf(other?: DOMMatrixInit): DOMMatrix; + /** + * Modifies the matrix by pre-multiplying it with the specified DOMMatrix. + * This is equivalent to the dot product B⋅A, where matrix `A` is the source matrix and `B` is the matrix given as an input to the method. + * + * @param other + */ + preMultiplySelf(other?: DOMMatrixInit): DOMMatrix; + /** + * Modifies the matrix by rotating it by the specified angle around the given vector. + * + * @param x + * @param y + * @param z + * @param angle in degrees + */ + rotateAxisAngleSelf( + x?: number, + y?: number, + z?: number, + angle?: number, + ): DOMMatrix; + /** + * Modifies the matrix by rotating it by the angle between the specified vector and `(1, 0)`. + * + * @param x + * @param y + */ + rotateFromVectorSelf(x?: number, y?: number): DOMMatrix; + /** + * Modifies the matrix by rotating itself around each axis by the specified number of degrees. + * + * @param rotZ yaw angle in degrees + */ + rotateSelf(rotZ?: number): DOMMatrix; + /** + * Modifies the matrix by rotating itself around each axis by the specified number of degrees. + * + * @param rotX roll angle in degrees + * @param rotY pitch angle in degrees + * @param rotZ yaw angle in degrees + */ + rotateSelf(rotX?: number, rotY?: number, rotZ?: number): DOMMatrix; + /** + * Modifies the matrix by applying the specified scaling factor to all three axes, centered on the given origin. + * + * @param scale + * @param originX + * @param originY + * @param originZ + */ + scale3dSelf( + scale?: number, + originX?: number, + originY?: number, + originZ?: number, + ): DOMMatrix; + /** + * Modifies the matrix by applying the specified scaling factors, with the center located at the specified origin. Also returns itself. + * By default, the X and Z axes are scaled by `1` and the Y axis is given the same scaling value as the X axis. + * The default origin is `(0, 0, 0)`. + * + * @param scaleX + * @param scaleY + * @param scaleZ + * @param originX + * @param originY + * @param originZ + */ + scaleSelf( + scaleX?: number, + scaleY?: number, + scaleZ?: number, + originX?: number, + originY?: number, + originZ?: number, + ): DOMMatrix; + /** + * NOTE: Not available in Worker + * + * Replaces the contents of the matrix with the matrix described by the specified transform or transforms. + * + * @param transformList + */ + setMatrixValue(transformList: string): DOMMatrix; + /** + * Modifies the matrix by applying the specified skew transformation along the X-axis. + * + * @param sx in degrees + */ + skewXSelf(sx?: number): DOMMatrix; + /** + * Modifies the matrix by applying the specified skew transformation along the Y-axis. + * + * @param sy in degrees + */ + skewYSelf(sy?: number): DOMMatrix; + /** + * Modifies the matrix by applying the specified vector. The default vector is `(0, 0, 0)`. + * + * @param tx + * @param ty + * @param tz + */ + translateSelf(tx?: number, ty?: number, tz?: number): DOMMatrix; +} + +/** + * A 4×4 matrix (column-major order), suitable for 2D and 3D operations including rotation and translation. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMMatrix) + * + * ``` + * | m11 m21 m31 m41 | + * | m12 m22 m32 m42 | + * | m13 m23 m33 m43 | + * | m14 m24 m34 m44 | + * ``` + * + * @category Geometry Interfaces Module API + */ +declare var DOMMatrix: { + prototype: DOMMatrix; + new (init?: number[]): DOMMatrix; + new (init: DOMMatrix | DOMMatrixReadOnly): DOMMatrix; + /** NOTE: Not available in Worker */ + new (init: string): DOMMatrix; + fromFloat32Array(array32: Float32Array): DOMMatrix; + fromFloat64Array(array64: Float64Array): DOMMatrix; + fromMatrix(other?: DOMMatrixInit): DOMMatrix; +}; + +/** + * A read-only 4×4 matrix (column-major order), suitable for 2D and 3D operations including rotation and translation. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly) + * + * ``` + * | m11 m21 m31 m41 | + * | m12 m22 m32 m42 | + * | m13 m23 m33 m43 | + * | m14 m24 m34 m44 | + * ``` + * + * @category Geometry Interfaces Module API + */ +declare interface DOMMatrixReadOnly { + readonly a: number; + readonly b: number; + readonly c: number; + readonly d: number; + readonly e: number; + readonly f: number; + readonly is2D: boolean; + readonly isIdentity: boolean; + readonly m11: number; + readonly m12: number; + readonly m13: number; + readonly m14: number; + readonly m21: number; + readonly m22: number; + readonly m23: number; + readonly m24: number; + readonly m31: number; + readonly m32: number; + readonly m33: number; + readonly m34: number; + readonly m41: number; + readonly m42: number; + readonly m43: number; + readonly m44: number; + /** Returns a new `DOMMatrix` created by flipping the source matrix around its X-axis. */ + flipX(): DOMMatrix; + /** Returns a new `DOMMatrix` created by flipping the source matrix around its Y-axis. */ + flipY(): DOMMatrix; + /** + * Returns a new `DOMMatrix` created by inverting the source matrix. + * If the matrix cannot be inverted, the new matrix's components are all set to `NaN` and its is2D property is set to `false`. + */ + inverse(): DOMMatrix; + /** + * Returns a new `DOMMatrix` created by computing the dot product of the source matrix and the specified matrix: `A⋅B`. + * + * @param other + */ + multiply(other?: DOMMatrixInit): DOMMatrix; + /** + * Returns a new `DOMMatrix` created by rotating the source matrix around each of its axes by the specified number of degrees. + * + * @param rotZ yaw angle in degrees + */ + rotate(rotZ?: number): DOMMatrix; + /** + * Returns a new `DOMMatrix` created by rotating the source matrix around each of its axes by the specified number of degrees. + * + * @param rotX roll angle in degrees + * @param rotY pitch angle in degrees + * @param rotZ yaw angle in degrees + */ + rotate(rotX?: number, rotY?: number, rotZ?: number): DOMMatrix; + /** + * Returns a new DOMMatrix created by rotating the source matrix by the given angle around the specified vector. + * + * @param x + * @param y + * @param z + * @param angle in degrees + */ + rotateAxisAngle( + x?: number, + y?: number, + z?: number, + angle?: number, + ): DOMMatrix; + /** + * Returns a new `DOMMatrix` created by rotating the source matrix by the angle between the specified vector and `(1, 0)`. + * + * @param x + * @param y + */ + rotateFromVector(x?: number, y?: number): DOMMatrix; + /** + * Returns a new `DOMMatrix` created by scaling the source matrix by the amount specified for each axis, centered on the given origin. + * By default, the X and Z axes are scaled by `1` and the Y axis is given the same scaling value as the X axis. + * The default origin is `(0, 0, 0)`. + * + * @param scaleX + * @param scaleY + * @param scaleZ + * @param originX + * @param originY + * @param originZ + */ + scale( + scaleX?: number, + scaleY?: number, + scaleZ?: number, + originX?: number, + originY?: number, + originZ?: number, + ): DOMMatrix; + /** + * Returns a new `DOMMatrix` created by scaling the source 3D matrix by the given factor along all its axes, centered on the specified origin point. + * The default origin is `(0, 0, 0)`. + * + * @param scale + * @param originX + * @param originY + * @param originZ + */ + scale3d( + scale?: number, + originX?: number, + originY?: number, + originZ?: number, + ): DOMMatrix; + /** + * Returns a new `DOMMatrix` created by applying the specified scaling on the X, Y, and Z axes, centered at the given origin. + * By default, the X and Y axes' scaling factors are both `1`. + * + * @deprecated Supported for legacy reasons to be compatible with `SVGMatrix` as defined in SVG 1.1. Use `scale()` instead. + * + * @param scaleX + * @param scaleY + */ + scaleNonUniform(scaleX?: number, scaleY?: number): DOMMatrix; + /** + * Returns a new DOMMatrix created by applying the specified skew transformation to the source matrix along its X-axis. + * + * @param sx in degrees + */ + skewX(sx?: number): DOMMatrix; + /** + * Returns a new DOMMatrix created by applying the specified skew transformation to the source matrix along its Y-axis. + * + * @param sy in degrees + */ + skewY(sy?: number): DOMMatrix; + toFloat32Array(): Float32Array; + toFloat64Array(): Float64Array; + toJSON(): { + a: number; + b: number; + c: number; + d: number; + e: number; + f: number; + is2D: boolean; + isIdentity: boolean; + m11: number; + m12: number; + m13: number; + m14: number; + m21: number; + m22: number; + m23: number; + m24: number; + m31: number; + m32: number; + m33: number; + m34: number; + m41: number; + m42: number; + m43: number; + m44: number; + }; + transformPoint(point?: DOMPointInit): DOMPoint; + translate(tx?: number, ty?: number, tz?: number): DOMMatrix; + /** NOTE: Not available in Worker */ + toString(): string; +} + +/** + * A read-only 4×4 matrix (column-major order), suitable for 2D and 3D operations including rotation and translation. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly) + * + * ``` + * | m11 m21 m31 m41 | + * | m12 m22 m32 m42 | + * | m13 m23 m33 m43 | + * | m14 m24 m34 m44 | + * ``` + * + * @category Geometry Interfaces Module API + */ +declare var DOMMatrixReadOnly: { + prototype: DOMMatrixReadOnly; + new (init?: number[]): DOMMatrixReadOnly; + new (init: DOMMatrix | DOMMatrixReadOnly): DOMMatrixReadOnly; + /** Not available in Worker */ + new (init: string): DOMMatrixReadOnly; + fromFloat32Array(array32: Float32Array): DOMMatrixReadOnly; + fromFloat64Array(array64: Float64Array): DOMMatrixReadOnly; + fromMatrix(other?: DOMMatrixInit): DOMMatrixReadOnly; +}; + +/** @category Geometry Interfaces Module API */ +declare interface DOMPointInit { + w?: number; + x?: number; + y?: number; + z?: number; +} + +/** + * A object represents a 2D or 3D point in a coordinate system; it includes values for the coordinates in up to three dimensions, as well as an optional perspective value. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPoint) + * + * @category Geometry Interfaces Module API + */ +declare interface DOMPoint extends DOMPointReadOnly { + w: number; + x: number; + y: number; + z: number; +} + +/** + * A object represents a 2D or 3D point in a coordinate system; it includes values for the coordinates in up to three dimensions, as well as an optional perspective value. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPoint) + * + * @category Geometry Interfaces Module API + */ +declare var DOMPoint: { + prototype: DOMPoint; + new (x?: number, y?: number, z?: number, w?: number): DOMPoint; + fromPoint(other?: DOMPointInit): DOMPoint; +}; + +/** + * A read-only object represents a 2D or 3D point in a coordinate system; it includes values for the coordinates in up to three dimensions, as well as an optional perspective value. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly) + * + * @category Geometry Interfaces Module API + */ +declare interface DOMPointReadOnly { + readonly w: number; + readonly x: number; + readonly y: number; + readonly z: number; + matrixTransform(matrix?: DOMMatrixInit): DOMPoint; + toJSON(): { + w: number; + x: number; + y: number; + z: number; + }; +} + +/** + * A read-only object represents a 2D or 3D point in a coordinate system; it includes values for the coordinates in up to three dimensions, as well as an optional perspective value. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly) + * + * @category Geometry Interfaces Module API + */ +declare var DOMPointReadOnly: { + prototype: DOMPointReadOnly; + new (x?: number, y?: number, z?: number, w?: number): DOMPointReadOnly; + fromPoint(other?: DOMPointInit): DOMPointReadOnly; +}; + +/** @category Geometry Interfaces Module API */ +declare interface DOMQuadInit { + p1?: DOMPointInit; + p2?: DOMPointInit; + p3?: DOMPointInit; + p4?: DOMPointInit; +} + +/** + * A collection of four DOMPoints defining the corners of an arbitrary quadrilateral. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMQuad) + * + * @category Geometry Interfaces Module API + */ +declare interface DOMQuad { + readonly p1: DOMPoint; + readonly p2: DOMPoint; + readonly p3: DOMPoint; + readonly p4: DOMPoint; + getBounds(): DOMRect; + toJSON(): { + p1: DOMPoint; + p2: DOMPoint; + p3: DOMPoint; + p4: DOMPoint; + }; +} + +/** + * A collection of four DOMPoints defining the corners of an arbitrary quadrilateral. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMQuad) + * + * @category Geometry Interfaces Module API + */ +declare var DOMQuad: { + prototype: DOMQuad; + new ( + p1?: DOMPointInit, + p2?: DOMPointInit, + p3?: DOMPointInit, + p4?: DOMPointInit, + ): DOMQuad; + fromQuad(other?: DOMQuadInit): DOMQuad; + fromRect(other?: DOMRectInit): DOMQuad; +}; + +/** @category Geometry Interfaces Module API */ +declare interface DOMRectInit { + height?: number; + width?: number; + x?: number; + y?: number; +} + +/** + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRect) + * + * @category Geometry Interfaces Module API + */ +declare interface DOMRect extends DOMRectReadOnly { + height: number; + width: number; + x: number; + y: number; +} + +/** + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRect) + * + * @category Geometry Interfaces Module API + */ +declare var DOMRect: { + prototype: DOMRect; + new (x?: number, y?: number, width?: number, height?: number): DOMRect; + fromRect(other?: DOMRectInit): DOMRect; +}; + +/** + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly) + * + * @category Geometry Interfaces Module API + */ +declare interface DOMRectReadOnly { + readonly bottom: number; + readonly height: number; + readonly left: number; + readonly right: number; + readonly top: number; + readonly width: number; + readonly x: number; + readonly y: number; + toJSON(): { + bottom: number; + height: number; + left: number; + right: number; + top: number; + width: number; + x: number; + y: number; + }; +} + +/** + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly) + * + * @category Geometry Interfaces Module API + */ +declare var DOMRectReadOnly: { + prototype: DOMRectReadOnly; + new ( + x?: number, + y?: number, + width?: number, + height?: number, + ): DOMRectReadOnly; + fromRect(other?: DOMRectInit): DOMRectReadOnly; +}; diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs new file mode 100644 index 00000000000000..16879f4ddf2071 --- /dev/null +++ b/ext/geometry/lib.rs @@ -0,0 +1,269 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use deno_core::op2; +use nalgebra::Matrix3; +use nalgebra::Matrix4; +use nalgebra::Matrix4x2; +use nalgebra::Matrix4x3; +use nalgebra::MatrixView4; +use nalgebra::MatrixViewMut4; +use nalgebra::Rotation3; +use nalgebra::UnitVector3; +use nalgebra::Vector3; +use nalgebra::Vector4; +use nalgebra::VectorViewMut4; +use std::path::PathBuf; + +deno_core::extension!( + deno_geometry, + deps = [deno_webidl, deno_web, deno_console], + ops = [ + op_geometry_translate_self, + op_geometry_scale_self, + op_geometry_scale_with_origin_self, + op_geometry_rotate_self, + op_geometry_rotate_from_vector_self, + op_geometry_rotate_axis_angle_self, + op_geometry_skew_self, + op_geometry_multiply, + op_geometry_multiply_self, + op_geometry_premultiply_self, + op_geometry_flip_x_self, + op_geometry_flip_y_self, + op_geometry_invert_self, + op_geometry_invert_2d_self, + op_geometry_premultiply_point_self, + ], + esm = ["00_init.js"], + lazy_loaded_esm = ["01_geometry.js"], +); + +pub fn get_declaration() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_geometry.d.ts") +} + +#[op2(fast)] +pub fn op_geometry_translate_self( + x: f64, + y: f64, + z: f64, + #[buffer] inout: &mut [f64], +) { + let shift = Vector3::new(x, y, z); + let mut inout = MatrixViewMut4::from_slice(inout); + inout.prepend_translation_mut(&shift); +} + +#[op2(fast)] +pub fn op_geometry_scale_self( + x: f64, + y: f64, + z: f64, + #[buffer] inout: &mut [f64], +) { + let scaling = Vector3::new(x, y, z); + let mut inout = MatrixViewMut4::from_slice(inout); + inout.prepend_nonuniform_scaling_mut(&scaling); +} + +#[op2(fast)] +pub fn op_geometry_scale_with_origin_self( + x: f64, + y: f64, + z: f64, + origin_x: f64, + origin_y: f64, + origin_z: f64, + #[buffer] inout: &mut [f64], +) { + let scaling = Vector3::new(x, y, z); + let mut shift = Vector3::new(origin_x, origin_y, origin_z); + let mut inout = MatrixViewMut4::from_slice(inout); + inout.prepend_translation_mut(&shift); + inout.prepend_nonuniform_scaling_mut(&scaling); + shift.neg_mut(); + inout.prepend_translation_mut(&shift); +} + +#[op2(fast)] +pub fn op_geometry_rotate_self( + roll_degrees: f64, + pitch_degrees: f64, + yaw_degrees: f64, + #[buffer] inout: &mut [f64], +) { + let rotation = Rotation3::from_euler_angles( + roll_degrees.to_radians(), + pitch_degrees.to_radians(), + yaw_degrees.to_radians(), + ) + .to_homogeneous(); + let mut inout = MatrixViewMut4::from_slice(inout); + let mut result = Matrix4x3::zeros(); + inout.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); + inout.set_column(0, &result.column(0)); + inout.set_column(1, &result.column(1)); + inout.set_column(2, &result.column(2)); +} + +#[op2(fast)] +pub fn op_geometry_rotate_from_vector_self( + x: f64, + y: f64, + #[buffer] inout: &mut [f64], +) { + let rotation = + Rotation3::from_axis_angle(&Vector3::z_axis(), y.atan2(x)).to_homogeneous(); + let mut inout = MatrixViewMut4::from_slice(inout); + let mut result = Matrix4x3::zeros(); + inout.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); + inout.set_column(0, &result.column(0)); + inout.set_column(1, &result.column(1)); + inout.set_column(2, &result.column(2)); +} + +#[op2(fast)] +pub fn op_geometry_rotate_axis_angle_self( + x: f64, + y: f64, + z: f64, + angle_degrees: f64, + #[buffer] inout: &mut [f64], +) { + let rotation = Rotation3::from_axis_angle( + &UnitVector3::new_normalize(Vector3::new(x, y, z)), + angle_degrees.to_radians(), + ) + .to_homogeneous(); + let mut inout = MatrixViewMut4::from_slice(inout); + let mut result = Matrix4x3::zeros(); + inout.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); + inout.set_column(0, &result.column(0)); + inout.set_column(1, &result.column(1)); + inout.set_column(2, &result.column(2)); +} + +#[op2(fast)] +pub fn op_geometry_skew_self( + x_degrees: f64, + y_degrees: f64, + #[buffer] inout: &mut [f64], +) { + let skew = Matrix4x2::new( + 1.0, + x_degrees.to_radians().tan(), + y_degrees.to_radians().tan(), + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + ); + let mut inout = MatrixViewMut4::from_slice(inout); + let mut result = Matrix4x2::zeros(); + inout.mul_to(&skew, &mut result); + inout.set_column(0, &result.column(0)); + inout.set_column(1, &result.column(1)); +} + +#[op2(fast)] +pub fn op_geometry_multiply( + #[buffer] lhs: &[f64], + #[buffer] rhs: &[f64], + #[buffer] out: &mut [f64], +) { + let lhs = MatrixView4::from_slice(lhs); + let rhs = MatrixView4::from_slice(rhs); + let mut out = MatrixViewMut4::from_slice(out); + lhs.mul_to(&rhs, &mut out); +} + +#[op2(fast)] +pub fn op_geometry_multiply_self( + #[buffer] rhs: &[f64], + #[buffer] inout: &mut [f64], +) { + let rhs = MatrixView4::from_slice(rhs); + let mut inout = MatrixViewMut4::from_slice(inout); + let mut result = Matrix4::zeros(); + inout.mul_to(&rhs, &mut result); + inout.copy_from(&result); +} + +#[op2(fast)] +pub fn op_geometry_premultiply_self( + #[buffer] lhs: &[f64], + #[buffer] inout: &mut [f64], +) { + let lhs = MatrixView4::from_slice(lhs); + let mut inout = MatrixViewMut4::from_slice(inout); + let mut result = Matrix4::zeros(); + lhs.mul_to(&inout, &mut result); + inout.copy_from(&result); +} + +#[op2(fast)] +pub fn op_geometry_flip_x_self(#[buffer] inout: &mut [f64]) { + let mut inout = MatrixViewMut4::from_slice(inout); + inout.column_mut(0).neg_mut(); +} + +#[op2(fast)] +pub fn op_geometry_flip_y_self(#[buffer] inout: &mut [f64]) { + let mut inout = MatrixViewMut4::from_slice(inout); + inout.column_mut(1).neg_mut(); +} + +#[op2(fast)] +pub fn op_geometry_invert_self(#[buffer] inout: &mut [f64]) -> bool { + if inout.iter().any(|&x| x.is_infinite()) { + inout.fill(f64::NAN); + return false; + } + + let mut inout = MatrixViewMut4::from_slice(inout); + if !inout.try_inverse_mut() { + inout.fill(f64::NAN); + return false; + } + + true +} + +#[op2(fast)] +pub fn op_geometry_invert_2d_self(#[buffer] inout: &mut [f64]) -> bool { + if inout.iter().any(|&x| x.is_infinite()) { + inout.fill(f64::NAN); + return false; + } + + let mut matrix = Matrix3::new( + inout[0], inout[4], inout[12], inout[1], inout[5], inout[13], 0.0, 0.0, 1.0, + ); + if !matrix.try_inverse_mut() { + inout.fill(f64::NAN); + return false; + } + + let matrix = matrix.as_slice(); + inout[0] = matrix[0]; + inout[1] = matrix[1]; + inout[4] = matrix[3]; + inout[5] = matrix[4]; + inout[12] = matrix[6]; + inout[13] = matrix[7]; + + true +} + +#[op2(fast)] +pub fn op_geometry_premultiply_point_self( + #[buffer] lhs: &[f64], + #[buffer] inout: &mut [f64], +) { + let lhs = MatrixView4::from_slice(lhs); + let mut inout = VectorViewMut4::from_slice(inout); + let mut result = Vector4::zeros(); + lhs.mul_to(&inout, &mut result); + inout.copy_from(&result); +} diff --git a/ext/webidl/00_webidl.js b/ext/webidl/00_webidl.js index b3c3b299f03cbd..e7252cb0ece4d9 100644 --- a/ext/webidl/00_webidl.js +++ b/ext/webidl/00_webidl.js @@ -679,6 +679,9 @@ converters["UVString?"] = createNullableConverter( converters["sequence"] = createSequenceConverter( converters.double, ); +converters["sequence"] = createSequenceConverter( + converters["unrestricted double"], +); converters["sequence"] = createSequenceConverter( converters.object, ); diff --git a/ext/webidl/internal.d.ts b/ext/webidl/internal.d.ts index a884d982aabb2f..adfb6713563c80 100644 --- a/ext/webidl/internal.d.ts +++ b/ext/webidl/internal.d.ts @@ -348,6 +348,12 @@ declare module "ext:deno_webidl/00_webidl.js" { context?: string, opts?: any, ): number[]; + ["sequence"]( + v: any, + prefix?: string, + context?: string, + opts?: any, + ): number[]; [type: string]: ( v: any, diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 9826a7459db2a4..7ed5dec94d895c 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -51,6 +51,7 @@ deno_crypto.workspace = true deno_fetch.workspace = true deno_ffi.workspace = true deno_fs = { workspace = true, features = ["sync_fs"] } +deno_geometry.workspace = true deno_http.workspace = true deno_io.workspace = true deno_net.workspace = true @@ -82,6 +83,7 @@ deno_crypto.workspace = true deno_fetch.workspace = true deno_ffi.workspace = true deno_fs = { workspace = true, features = ["sync_fs"] } +deno_geometry.workspace = true deno_http.workspace = true deno_io.workspace = true deno_kv.workspace = true diff --git a/runtime/js/98_global_scope_window.js b/runtime/js/98_global_scope_window.js index c42a940a829796..2aee67d70cf069 100644 --- a/runtime/js/98_global_scope_window.js +++ b/runtime/js/98_global_scope_window.js @@ -7,18 +7,93 @@ import { op_bootstrap_user_agent, } from "ext:core/ops"; const { + ArrayPrototypeMap, + ArrayPrototypeSome, + Float64Array, + Number, + NumberIsNaN, ObjectDefineProperties, ObjectPrototypeIsPrototypeOf, + SafeRegExp, + StringPrototypeMatch, + StringPrototypeSplit, SymbolFor, + TypeError, } = primordials; import * as location from "ext:deno_web/12_location.js"; import * as console from "ext:deno_console/01_console.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; import * as globalInterfaces from "ext:deno_web/04_global_interfaces.js"; import * as webStorage from "ext:deno_webstorage/01_webstorage.js"; import * as prompt from "ext:runtime/41_prompt.js"; import { loadWebGPU } from "ext:deno_webgpu/00_init.js"; +import { createGeometryLoader } from "ext:deno_geometry/00_init.js"; + +const MATRIX_PATTERN = new SafeRegExp( + /^\s*matrix(3d)?\(([-\+0-9.e,\s]+)\)\s*$/iu, +); + +const loadGeometry = createGeometryLoader((transformList, prefix) => { + if (transformList === "") { + return { + // deno-fmt-ignore + matrix: new Float64Array([ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + ]), + is2D: true, + }; + } + + // Currently only parsing of a single matrix, matrix3d function without units + // as arguments is implemented + // TODO(petamoriken): Add CSS parser such as lightningcss to support more cases + const matrixMatch = StringPrototypeMatch(transformList, MATRIX_PATTERN); + if (matrixMatch !== null) { + const is2D = matrixMatch[1] === undefined; + /** @type {number[]} */ + const seq = ArrayPrototypeMap( + StringPrototypeSplit(matrixMatch[2], ","), + (str) => Number(str), + ); + if ( + is2D && seq.length !== 6 || + !is2D && seq.length !== 16 || + ArrayPrototypeSome(seq, (num) => NumberIsNaN(num)) + ) { + throw new DOMException( + `${prefix}: Failed to parse '${transformList}'`, + "SyntaxError", + ); + } + if (is2D) { + const { 0: a, 1: b, 2: c, 3: d, 4: e, 5: f } = seq; + return { + // deno-fmt-ignore + matrix: new Float64Array([ + a, b, 0, 0, + c, d, 0, 0, + 0, 0, 1, 0, + e, f, 0, 1, + ]), + is2D, + }; + } else { + return { + matrix: new Float64Array(seq), + is2D, + }; + } + } + + throw new TypeError( + `${prefix}: CSS parser is not fully implemented`, + ); +}, true); class Navigator { constructor() { @@ -121,6 +196,34 @@ const mainRuntimeGlobalProperties = { localStorage: core.propGetterOnly(webStorage.localStorage), sessionStorage: core.propGetterOnly(webStorage.sessionStorage), Storage: core.propNonEnumerable(webStorage.Storage), + DOMMatrix: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMMatrix, + loadGeometry, + ), + DOMMatrixReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMMatrixReadOnly, + loadGeometry, + ), + DOMPoint: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMPoint, + loadGeometry, + ), + DOMPointReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMPointReadOnly, + loadGeometry, + ), + DOMQuad: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMQuad, + loadGeometry, + ), + DOMRect: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMRect, + loadGeometry, + ), + DOMRectReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMRectReadOnly, + loadGeometry, + ), }; export { mainRuntimeGlobalProperties, memoizeLazy }; diff --git a/runtime/js/98_global_scope_worker.js b/runtime/js/98_global_scope_worker.js index f10bb2830dbbb6..d1fb739964363f 100644 --- a/runtime/js/98_global_scope_worker.js +++ b/runtime/js/98_global_scope_worker.js @@ -10,6 +10,7 @@ const { ObjectDefineProperties, ObjectPrototypeIsPrototypeOf, SymbolFor, + TypeError, } = primordials; import * as location from "ext:deno_web/12_location.js"; @@ -17,6 +18,13 @@ import * as console from "ext:deno_console/01_console.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; import * as globalInterfaces from "ext:deno_web/04_global_interfaces.js"; import { loadWebGPU } from "ext:deno_webgpu/00_init.js"; +import { createGeometryLoader } from "ext:deno_geometry/00_init.js"; + +const loadGeometry = createGeometryLoader((_transformList, prefix) => { + throw new TypeError( + `${prefix}: Cannot parse CSS on Workers`, + ); +}, false); function memoizeLazy(f) { let v_ = null; @@ -115,6 +123,34 @@ const workerRuntimeGlobalProperties = { WorkerNavigator: core.propNonEnumerable(WorkerNavigator), navigator: core.propGetterOnly(() => workerNavigator), self: core.propGetterOnly(() => globalThis), + DOMMatrix: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMMatrix, + loadGeometry, + ), + DOMMatrixReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMMatrixReadOnly, + loadGeometry, + ), + DOMPoint: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMPoint, + loadGeometry, + ), + DOMPointReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMPointReadOnly, + loadGeometry, + ), + DOMQuad: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMQuad, + loadGeometry, + ), + DOMRect: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMRect, + loadGeometry, + ), + DOMRectReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMRectReadOnly, + loadGeometry, + ), }; export { workerRuntimeGlobalProperties }; diff --git a/runtime/lib.rs b/runtime/lib.rs index 3e48ec89c0a59a..ea8f8f2c928ad2 100644 --- a/runtime/lib.rs +++ b/runtime/lib.rs @@ -10,6 +10,7 @@ pub use deno_crypto; pub use deno_fetch; pub use deno_ffi; pub use deno_fs; +pub use deno_geometry; pub use deno_http; pub use deno_io; pub use deno_kv; diff --git a/runtime/shared.rs b/runtime/shared.rs index 1a9f2e66be1814..321e0a0d573a3f 100644 --- a/runtime/shared.rs +++ b/runtime/shared.rs @@ -22,6 +22,7 @@ extension!(runtime, deno_web, deno_fetch, deno_cache, + deno_geometry, deno_websocket, deno_webstorage, deno_crypto, diff --git a/runtime/snapshot.rs b/runtime/snapshot.rs index 8d008eeab0043a..d7aad4720ef7e7 100644 --- a/runtime/snapshot.rs +++ b/runtime/snapshot.rs @@ -281,6 +281,7 @@ pub fn create_runtime_snapshot( deno_webgpu::deno_webgpu::init_ops_and_esm(), deno_canvas::deno_canvas::init_ops_and_esm(), deno_fetch::deno_fetch::init_ops_and_esm::(Default::default()), + deno_geometry::deno_geometry::init_ops_and_esm(), deno_cache::deno_cache::init_ops_and_esm::(None), deno_websocket::deno_websocket::init_ops_and_esm::( "".to_owned(), diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 270fc1ab9f77b7..83068596f3aa92 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -462,6 +462,7 @@ impl WebWorker { ..Default::default() }, ), + deno_geometry::deno_geometry::init_ops_and_esm(), deno_cache::deno_cache::init_ops_and_esm::( create_cache, ), diff --git a/runtime/worker.rs b/runtime/worker.rs index de29b66291fb8e..52c7a8d89c31f8 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -372,6 +372,7 @@ impl MainWorker { ..Default::default() }, ), + deno_geometry::deno_geometry::init_ops_and_esm(), deno_cache::deno_cache::init_ops_and_esm::( create_cache, ), diff --git a/tests/integration/js_unit_tests.rs b/tests/integration/js_unit_tests.rs index 9ecec8b426c844..b241fb041b5d33 100644 --- a/tests/integration/js_unit_tests.rs +++ b/tests/integration/js_unit_tests.rs @@ -39,6 +39,7 @@ util::unit_test_factory!( filereader_test, files_test, fs_events_test, + geometry_test, get_random_values_test, globals_test, headers_test, diff --git a/tests/unit/geometry_test.ts b/tests/unit/geometry_test.ts new file mode 100644 index 00000000000000..b4910c3e6f5ec6 --- /dev/null +++ b/tests/unit/geometry_test.ts @@ -0,0 +1,1195 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +import { + assertAlmostEquals, + assertEquals, + assertStrictEquals, + assertThrows, +} from "./test_util.ts"; + +Deno.test(function matrixTransformPoint() { + const point = new DOMPoint(1, 2, 3, 4); + // deno-fmt-ignore + const matrix = DOMMatrix.fromMatrix({ + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }); + const point2 = point.matrixTransform(matrix); + const point3 = matrix.transformPoint(point); + assertEquals( + point, + new DOMPoint(1, 2, 3, 4), + ); + assertEquals( + point2, + new DOMPoint(30, 70, 110, 150), + ); + assertEquals( + point3, + new DOMPoint(30, 70, 110, 150), + ); +}); + +Deno.test(function matrixTranslate() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.translate(1, 2, 3); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: 2, m31: 3, m41: 1 * 1 + 2 * 2 + 3 * 3 + 4 * 1, + m12: 5, m22: 6, m32: 7, m42: 5 * 1 + 6 * 2 + 7 * 3 + 8 * 1, + m13: 9, m23: 10, m33: 11, m43: 9 * 1 + 10 * 2 + 11 * 3 + 12 * 1, + m14: 13, m24: 14, m34: 15, m44: 13 * 1 + 14 * 2 + 15 * 3 + 16 * 1, + }), + ); +}); + +Deno.test(function matrixTranslateSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.translateSelf(1, 2, 3); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: 2, m31: 3, m41: 1 * 1 + 2 * 2 + 3 * 3 + 4 * 1, + m12: 5, m22: 6, m32: 7, m42: 5 * 1 + 6 * 2 + 7 * 3 + 8 * 1, + m13: 9, m23: 10, m33: 11, m43: 9 * 1 + 10 * 2 + 11 * 3 + 12 * 1, + m14: 13, m24: 14, m34: 15, m44: 13 * 1 + 14 * 2 + 15 * 3 + 16 * 1, + }), + ); +}); + +Deno.test(function matrixScale() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.scale(1, 2, 3); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: 2 * 2, m31: 3 * 3, m41: 4, + m12: 5, m22: 6 * 2, m32: 7 * 3, m42: 8, + m13: 9, m23: 10 * 2, m33: 11 * 3, m43: 12, + m14: 13, m24: 14 * 2, m34: 15 * 3, m44: 16, + }), + ); +}); + +Deno.test(function matrixScaleSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.scaleSelf(1, 2, 3); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: 2 * 2, m31: 3 * 3, m41: 4, + m12: 5, m22: 6 * 2, m32: 7 * 3, m42: 8, + m13: 9, m23: 10 * 2, m33: 11 * 3, m43: 12, + m14: 13, m24: 14 * 2, m34: 15 * 3, m44: 16, + }), + ); +}); + +Deno.test(function matrixScaleWithOrigin() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.scale(1, 2, 3, 4, 5, 6); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: 2 * 2, m31: 3 * 3, m41: -42, + m12: 5, m22: 6 * 2, m32: 7 * 3, m42: -106, + m13: 9, m23: 10 * 2, m33: 11 * 3, m43: -170, + m14: 13, m24: 14 * 2, m34: 15 * 3, m44: -234, + }), + ); +}); + +Deno.test(function matrixScaleWithOriginSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.scaleSelf(1, 2, 3, 4, 5, 6); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: 2 * 2, m31: 3 * 3, m41: -42, + m12: 5, m22: 6 * 2, m32: 7 * 3, m42: -106, + m13: 9, m23: 10 * 2, m33: 11 * 3, m43: -170, + m14: 13, m24: 14 * 2, m34: 15 * 3, m44: -234, + }), + ); +}); + +Deno.test(function matrixScaleNonUniform() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.scaleNonUniform(1, 2); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: 2 * 2, m31: 3, m41: 4, + m12: 5, m22: 6 * 2, m32: 7, m42: 8, + m13: 9, m23: 10 * 2, m33: 11, m43: 12, + m14: 13, m24: 14 * 2, m34: 15, m44: 16, + }), + ); +}); + +Deno.test(function matrixScale3d() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.scale3d(2); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1 * 2, m21: 2 * 2, m31: 3 * 2, m41: 4, + m12: 5 * 2, m22: 6 * 2, m32: 7 * 2, m42: 8, + m13: 9 * 2, m23: 10 * 2, m33: 11 * 2, m43: 12, + m14: 13 * 2, m24: 14 * 2, m34: 15 * 2, m44: 16, + }), + ); +}); + +Deno.test(function matrixScale3dSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.scale3dSelf(2); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1 * 2, m21: 2 * 2, m31: 3 * 2, m41: 4, + m12: 5 * 2, m22: 6 * 2, m32: 7 * 2, m42: 8, + m13: 9 * 2, m23: 10 * 2, m33: 11 * 2, m43: 12, + m14: 13 * 2, m24: 14 * 2, m34: 15 * 2, m44: 16, + }), + ); +}); + +Deno.test(function matrixScale3dWithOrigin() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.scale3d(2, 4, 5, 6); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1 * 2, m21: 2 * 2, m31: 3 * 2, m41: -28, + m12: 5 * 2, m22: 6 * 2, m32: 7 * 2, m42: -84, + m13: 9 * 2, m23: 10 * 2, m33: 11 * 2, m43: -140, + m14: 13 * 2, m24: 14 * 2, m34: 15 * 2, m44: -196, + }), + ); +}); + +Deno.test(function matrixScale3dWithOriginSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.scale3dSelf(2, 4, 5, 6); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1 * 2, m21: 2 * 2, m31: 3 * 2, m41: -28, + m12: 5 * 2, m22: 6 * 2, m32: 7 * 2, m42: -84, + m13: 9 * 2, m23: 10 * 2, m33: 11 * 2, m43: -140, + m14: 13 * 2, m24: 14 * 2, m34: 15 * 2, m44: -196, + }), + ); +}); + +Deno.test(function matrixRotate() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: -3, m21: -2, m31: -1, m41: 4, + m12: -7, m22: -6, m32: -5, m42: 8, + m13: -11, m23: -10, m33: -9, m43: 12, + m14: -15, m24: -14, m34: -13, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.rotate(0, 90, 180); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix2[key], + value, + ); + } +}); + +Deno.test(function matrixRotateSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: -3, m21: -2, m31: -1, m41: 4, + m12: -7, m22: -6, m32: -5, m42: 8, + m13: -11, m23: -10, m33: -9, m43: 12, + m14: -15, m24: -14, m34: -13, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.rotateSelf(0, 90, 180); + assertStrictEquals( + matrix, + matrix2, + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix[key], + value, + ); + } +}); + +Deno.test(function matrixRotateFromVector() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: 2.121320343559643, m21: 0.7071067811865476, m31: 3, m41: 4, + m12: 7.778174593052023, m22: 0.7071067811865479, m32: 7, m42: 8, + m13: 13.435028842544405, m23: 0.7071067811865470, m33: 11, m43: 12, + m14: 19.091883092036785, m24: 0.7071067811865461, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.rotateFromVector(1, 1); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix2[key], + value, + ); + } +}); + +Deno.test(function matrixRotateFromVectorSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: 2.121320343559643, m21: 0.7071067811865476, m31: 3, m41: 4, + m12: 7.778174593052023, m22: 0.7071067811865479, m32: 7, m42: 8, + m13: 13.435028842544405, m23: 0.7071067811865470, m33: 11, m43: 12, + m14: 19.091883092036785, m24: 0.7071067811865461, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.rotateFromVectorSelf(1, 1); + assertStrictEquals( + matrix, + matrix2, + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix[key], + value, + ); + } +}); + +Deno.test(function matrixRotateAxisAngle() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5.228294835332138, m22: 4.854398120227125, m32: 7.6876363080712045, m42: 8, + m13: 9.456589670664275, m23: 7.708796240454249, m33: 12.3752726161424090, m43: 12, + m14: 13.684884505996411, m24: 10.563194360681376, m34: 17.0629089242136120, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.rotateAxisAngle(1, 2, 3, 30); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix2[key], + value, + ); + } +}); + +Deno.test(function matrixRotateAxisAngleSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5.228294835332138, m22: 4.854398120227125, m32: 7.6876363080712045, m42: 8, + m13: 9.456589670664275, m23: 7.708796240454249, m33: 12.3752726161424090, m43: 12, + m14: 13.684884505996411, m24: 10.563194360681376, m34: 17.0629089242136120, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.rotateAxisAngleSelf(1, 2, 3, 30); + assertStrictEquals( + matrix, + matrix2, + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix[key], + value, + ); + } +}); + +Deno.test(function matrixSkewX() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: 1, m21: 2.5773502691896257, m31: 3, m41: 4, + m12: 5, m22: 8.8867513459481270, m32: 7, m42: 8, + m13: 9, m23: 15.1961524227066300, m33: 11, m43: 12, + m14: 13, m24: 21.5055534994651330, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.skewX(30); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix2[key], + value, + ); + } +}); + +Deno.test(function matrixSkewXSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: 1, m21: 2.5773502691896257, m31: 3, m41: 4, + m12: 5, m22: 8.8867513459481270, m32: 7, m42: 8, + m13: 9, m23: 15.1961524227066300, m33: 11, m43: 12, + m14: 13, m24: 21.5055534994651330, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.skewXSelf(30); + assertStrictEquals( + matrix, + matrix2, + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix[key], + value, + ); + } +}); + +Deno.test(function matrixSkewY() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: 2.1547005383792515, m21: 2, m31: 3, m41: 4, + m12: 8.4641016151377530, m22: 6, m32: 7, m42: 8, + m13: 14.7735026918962560, m23: 10, m33: 11, m43: 12, + m14: 21.0829037686547600, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.skewY(30); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix2[key], + value, + ); + } +}); + +Deno.test(function matrixSkewYSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: 2.1547005383792515, m21: 2, m31: 3, m41: 4, + m12: 8.4641016151377530, m22: 6, m32: 7, m42: 8, + m13: 14.7735026918962560, m23: 10, m33: 11, m43: 12, + m14: 21.0829037686547600, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.skewYSelf(30); + assertStrictEquals( + matrix, + matrix2, + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix[key], + value, + ); + } +}); + +Deno.test(function matrixMultiply() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.multiply({ m11: 1, m22: 2, m33: 3, m44: 4 }); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1 * 1, m21: 2 * 2, m31: 3 * 3, m41: 4 * 4, + m12: 5 * 1, m22: 6 * 2, m32: 7 * 3, m42: 8 * 4, + m13: 9 * 1, m23: 10 * 2, m33: 11 * 3, m43: 12 * 4, + m14: 13 * 1, m24: 14 * 2, m34: 15 * 3, m44: 16 * 4, + }), + ); +}); + +Deno.test(function matrixMultiplySelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.multiplySelf({ m11: 1, m22: 2, m33: 3, m44: 4 }); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1 * 1, m21: 2 * 2, m31: 3 * 3, m41: 4 * 4, + m12: 5 * 1, m22: 6 * 2, m32: 7 * 3, m42: 8 * 4, + m13: 9 * 1, m23: 10 * 2, m33: 11 * 3, m43: 12 * 4, + m14: 13 * 1, m24: 14 * 2, m34: 15 * 3, m44: 16 * 4, + }), + ); +}); + +Deno.test(function matrixMultiplySelfWithSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.multiplySelf(matrix); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 90, m21: 100, m31: 110, m41: 120, + m12: 202, m22: 228, m32: 254, m42: 280, + m13: 314, m23: 356, m33: 398, m43: 440, + m14: 426, m24: 484, m34: 542, m44: 600, + }), + ); +}); + +Deno.test(function matrixPreMultiplySelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.preMultiplySelf({ m11: 1, m22: 2, m33: 3, m44: 4 }); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1 * 1, m21: 2 * 1, m31: 3 * 1, m41: 4 * 1, + m12: 5 * 2, m22: 6 * 2, m32: 7 * 2, m42: 8 * 2, + m13: 9 * 3, m23: 10 * 3, m33: 11 * 3, m43: 12 * 3, + m14: 13 * 4, m24: 14 * 4, m34: 15 * 4, m44: 16 * 4, + }), + ); +}); + +Deno.test(function matrixPreMultiplySelfWithSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.preMultiplySelf(matrix); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 90, m21: 100, m31: 110, m41: 120, + m12: 202, m22: 228, m32: 254, m42: 280, + m13: 314, m23: 356, m33: 398, m43: 440, + m14: 426, m24: 484, m34: 542, m44: 600, + }), + ); +}); + +Deno.test(function matrixFlipX() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.flipX(); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: -1, m21: 2, m31: 3, m41: 4, + m12: -5, m22: 6, m32: 7, m42: 8, + m13: -9, m23: 10, m33: 11, m43: 12, + m14: -13, m24: 14, m34: 15, m44: 16, + }), + ); +}); + +Deno.test(function matrixFlipY() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.flipY(); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: -2, m31: 3, m41: 4, + m12: 5, m22: -6, m32: 7, m42: 8, + m13: 9, m23: -10, m33: 11, m43: 12, + m14: 13, m24: -14, m34: 15, m44: 16, + }), + ); +}); + +Deno.test(function matrixInverse() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 0, m22: 1, m32: 7, m42: 8, + m13: 0, m23: 0, m33: 1, m43: 12, + m14: 0, m24: 0, m34: 0, m44: 1, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.inverse(); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: -2, m31: 11, m41: -120, + m12: 0, m22: 1, m32: -7, m42: 76, + m13: 0, m23: 0, m33: 1, m43: -12, + m14: 0, m24: 0, m34: 0, m44: 1, + }), + ); +}); + +Deno.test(function matrixInvertSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 0, m22: 1, m32: 7, m42: 8, + m13: 0, m23: 0, m33: 1, m43: 12, + m14: 0, m24: 0, m34: 0, m44: 1, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.invertSelf(); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: -2, m31: 11, m41: -120, + m12: 0, m22: 1, m32: -7, m42: 76, + m13: 0, m23: 0, m33: 1, m43: -12, + m14: 0, m24: 0, m34: 0, m44: 1, + }), + ); +}); + +Deno.test(function matrixInverse2D() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 0, m41: 4, + m12: 0, m22: 1, m32: 0, m42: 8, + m13: 0, m23: 0, m33: 1, m43: 0, + m14: 0, m24: 0, m34: 0, m44: 1, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.inverse(); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: -2, m31: 0, m41: 12, + m12: 0, m22: 1, m32: 0, m42: -8, + m13: 0, m23: 0, m33: 1, m43: 0, + m14: 0, m24: 0, m34: 0, m44: 1, + }), + ); +}); + +Deno.test(function matrixInvert2DSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 0, m41: 4, + m12: 0, m22: 1, m32: 0, m42: 8, + m13: 0, m23: 0, m33: 1, m43: 0, + m14: 0, m24: 0, m34: 0, m44: 1, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.invertSelf(); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: -2, m31: 0, m41: 12, + m12: 0, m22: 1, m32: 0, m42: -8, + m13: 0, m23: 0, m33: 1, m43: 0, + m14: 0, m24: 0, m34: 0, m44: 1, + }), + ); +}); + +Deno.test(function prototypeOverwrite() { + const point = new DOMPointReadOnly(); + Object.setPrototypeOf(point, DOMPoint.prototype); + assertThrows( + () => { + // @ts-ignore test + point.x = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + point.y = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + point.z = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + point.w = 1; + }, + TypeError, + "Illegal invocation", + ); + + const rect = new DOMRectReadOnly(); + Object.setPrototypeOf(rect, DOMRect.prototype); + assertThrows( + () => { + // @ts-ignore test + rect.x = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + rect.y = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + rect.width = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + rect.height = 1; + }, + TypeError, + "Illegal invocation", + ); + + const matrix = new DOMMatrixReadOnly(); + Object.setPrototypeOf(matrix, DOMMatrix.prototype); + assertThrows( + () => { + // @ts-ignore test + matrix.a = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.b = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.c = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.d = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.e = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.f = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m11 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m12 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m13 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m14 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m21 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m22 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m23 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m24 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m31 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m32 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m33 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m34 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m41 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m42 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m43 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m44 = 1; + }, + TypeError, + "Illegal invocation", + ); +}); diff --git a/tests/unit/test_util.ts b/tests/unit/test_util.ts index 6e7865ea7a43d4..c4fa660b986e69 100644 --- a/tests/unit/test_util.ts +++ b/tests/unit/test_util.ts @@ -6,6 +6,7 @@ export { colors }; import { join, resolve } from "@std/path"; export { assert, + assertAlmostEquals, assertEquals, assertFalse, AssertionError, diff --git a/tests/wpt/runner/expectation.json b/tests/wpt/runner/expectation.json index 6025ce42a46d81..bafb919a70df77 100644 --- a/tests/wpt/runner/expectation.json +++ b/tests/wpt/runner/expectation.json @@ -14231,12 +14231,215 @@ "eventsource-constructor-stringify.window.html": false, "eventsource-cross-origin.window.html": false, "eventsource-reconnect.window.html": false, - "request-status-error.window.html": false, "eventsource-constructor-empty-url.any.serviceworker.html": false, "eventsource-constructor-empty-url.any.sharedworker.html": false, "eventsource-constructor-url-bogus.any.serviceworker.html": false, "eventsource-constructor-url-bogus.any.sharedworker.html": false, "request-credentials.window.html": false, "request-redirect.window.html": false + }, + "css": { + "geometry": { + "DOMMatrix-001.html": [ + "new DOMMatrix(\"none\")", + "new DOMMatrix(\" none\")", + "new DOMMatrix(\"none \")", + "new DOMMatrix(\"NONE\")", + "new DOMMatrix(\"none/**/\")", + "new DOMMatrix(\"/**/none\")", + "new DOMMatrix(\"scale(2) translateX(5px) translateY(5px)\")", + "new DOMMatrix(\"scale(2, 2) translateX(5px) translateY(5px)\")", + "new DOMMatrix(\"scale(2)translateX(5px)translateY(5px)\")", + "new DOMMatrix(\"scale(2) translateX(calc(2 * 2.5px)) translateY(5px)\")", + "new DOMMatrix(\"scale(2) translateX(5px) translateY(5px) rotate(5deg) rotate(-5deg)\")", + "new DOMMatrix(\"translateX (5px)\")", + "new DOMMatrix(\"scale(2 2) translateX(5) translateY(5)\")", + "new DOMMatrix(\"scale(2, 2), translateX(5) ,translateY(5)\")", + "new DOMMatrix(\"translateX(5em)\")", + "new DOMMatrix(\"translateX(5ex)\")", + "new DOMMatrix(\"translateX(5ch)\")", + "new DOMMatrix(\"translateX(5rem)\")", + "new DOMMatrix(\"translateX(5cqw)\")", + "new DOMMatrix(\"translateX(5cqh)\")", + "new DOMMatrix(\"translateX(5cqb)\")", + "new DOMMatrix(\"translateX(5cqi)\")", + "new DOMMatrix(\"translateX(5cqmin)\")", + "new DOMMatrix(\"translateX(5cqmax)\")", + "new DOMMatrix(\"translateX(5vw)\")", + "new DOMMatrix(\"translateX(5vh)\")", + "new DOMMatrix(\"translateX(5vb)\")", + "new DOMMatrix(\"translateX(5vi)\")", + "new DOMMatrix(\"translateX(5vmin)\")", + "new DOMMatrix(\"translateX(5vmax)\")", + "new DOMMatrix(\"translateX(5%)\")", + "new DOMMatrix(\"rotate(5)\")", + "new DOMMatrix(\"rotate(5, 5, 5)\")", + "new DOMMatrix(\"rotate(5, 5px, 5px)\")", + "new DOMMatrix(\"rotate(5deg, 5px, 5px)\")", + "new DOMMatrix(\" \")", + "new DOMMatrix(\"/**/\")", + "new DOMMatrix(\"\\0\")", + "new DOMMatrix(\";\")", + "new DOMMatrix(\"none;\")", + "new DOMMatrix(\"null\")", + "new DOMMatrix(null)", + "new DOMMatrix(\"undefined\")", + "new DOMMatrix(\"inherit\")", + "new DOMMatrix(\"initial\")", + "new DOMMatrix(\"unset\")", + "new DOMMatrix(\"scale(2, 2), translateX(5px) translateY(5px)\")", + "new DOMMatrixReadOnly(\"none\")", + "new DOMMatrixReadOnly(\" none\")", + "new DOMMatrixReadOnly(\"none \")", + "new DOMMatrixReadOnly(\"NONE\")", + "new DOMMatrixReadOnly(\"none/**/\")", + "new DOMMatrixReadOnly(\"/**/none\")", + "new DOMMatrixReadOnly(\"scale(2) translateX(5px) translateY(5px)\")", + "new DOMMatrixReadOnly(\"scale(2, 2) translateX(5px) translateY(5px)\")", + "new DOMMatrixReadOnly(\"scale(2)translateX(5px)translateY(5px)\")", + "new DOMMatrixReadOnly(\"scale(2) translateX(calc(2 * 2.5px)) translateY(5px)\")", + "new DOMMatrixReadOnly(\"scale(2) translateX(5px) translateY(5px) rotate(5deg) rotate(-5deg)\")", + "new DOMMatrixReadOnly(\"translateX (5px)\")", + "new DOMMatrixReadOnly(\"scale(2 2) translateX(5) translateY(5)\")", + "new DOMMatrixReadOnly(\"scale(2, 2), translateX(5) ,translateY(5)\")", + "new DOMMatrixReadOnly(\"translateX(5em)\")", + "new DOMMatrixReadOnly(\"translateX(5ex)\")", + "new DOMMatrixReadOnly(\"translateX(5ch)\")", + "new DOMMatrixReadOnly(\"translateX(5rem)\")", + "new DOMMatrixReadOnly(\"translateX(5cqw)\")", + "new DOMMatrixReadOnly(\"translateX(5cqh)\")", + "new DOMMatrixReadOnly(\"translateX(5cqb)\")", + "new DOMMatrixReadOnly(\"translateX(5cqi)\")", + "new DOMMatrixReadOnly(\"translateX(5cqmin)\")", + "new DOMMatrixReadOnly(\"translateX(5cqmax)\")", + "new DOMMatrixReadOnly(\"translateX(5vw)\")", + "new DOMMatrixReadOnly(\"translateX(5vh)\")", + "new DOMMatrixReadOnly(\"translateX(5vb)\")", + "new DOMMatrixReadOnly(\"translateX(5vi)\")", + "new DOMMatrixReadOnly(\"translateX(5vmin)\")", + "new DOMMatrixReadOnly(\"translateX(5vmax)\")", + "new DOMMatrixReadOnly(\"translateX(5%)\")", + "new DOMMatrixReadOnly(\"rotate(5)\")", + "new DOMMatrixReadOnly(\"rotate(5, 5, 5)\")", + "new DOMMatrixReadOnly(\"rotate(5, 5px, 5px)\")", + "new DOMMatrixReadOnly(\"rotate(5deg, 5px, 5px)\")", + "new DOMMatrixReadOnly(\" \")", + "new DOMMatrixReadOnly(\"/**/\")", + "new DOMMatrixReadOnly(\"\\0\")", + "new DOMMatrixReadOnly(\";\")", + "new DOMMatrixReadOnly(\"none;\")", + "new DOMMatrixReadOnly(\"null\")", + "new DOMMatrixReadOnly(null)", + "new DOMMatrixReadOnly(\"undefined\")", + "new DOMMatrixReadOnly(\"inherit\")", + "new DOMMatrixReadOnly(\"initial\")", + "new DOMMatrixReadOnly(\"unset\")", + "new DOMMatrixReadOnly(\"scale(2, 2), translateX(5px) translateY(5px)\")" + ], + "DOMMatrix-002.html": true, + "DOMMatrix-003.html": true, + "DOMMatrix-a-f-alias.html": true, + "DOMMatrix-attributes.html": true, + "DOMMatrix-css-string.worker.html": true, + "DOMMatrix-invert-invertible.html": true, + "DOMMatrix-invert-non-invertible.html": true, + "DOMMatrix-invert-preserves-2d.html": true, + "DOMMatrix-newobject.html": true, + "DOMMatrix-stringifier.html": [ + "WebKitCSSMatrix stringifier: identity (2d)", + "WebKitCSSMatrix stringifier: identity (3d)", + "WebKitCSSMatrix stringifier: NaN (2d)", + "WebKitCSSMatrix stringifier: NaN (3d)", + "WebKitCSSMatrix stringifier: Infinity (2d)", + "WebKitCSSMatrix stringifier: Infinity (3d)", + "WebKitCSSMatrix stringifier: -Infinity (2d)", + "WebKitCSSMatrix stringifier: -Infinity (3d)", + "WebKitCSSMatrix stringifier: 1/3 (2d)", + "WebKitCSSMatrix stringifier: 1/3 (3d)", + "WebKitCSSMatrix stringifier: 1/300000 (2d)", + "WebKitCSSMatrix stringifier: 1/300000 (3d)", + "WebKitCSSMatrix stringifier: 1/300000000 (2d)", + "WebKitCSSMatrix stringifier: 1/300000000 (3d)", + "WebKitCSSMatrix stringifier: 100000 + (1/3) (2d)", + "WebKitCSSMatrix stringifier: 100000 + (1/3) (3d)", + "WebKitCSSMatrix stringifier: Math.pow(2, 53) + 1 (2d)", + "WebKitCSSMatrix stringifier: Math.pow(2, 53) + 1 (3d)", + "WebKitCSSMatrix stringifier: Math.pow(2, 53) + 2 (2d)", + "WebKitCSSMatrix stringifier: Math.pow(2, 53) + 2 (3d)", + "WebKitCSSMatrix stringifier: Number.MAX_VALUE (2d)", + "WebKitCSSMatrix stringifier: Number.MAX_VALUE (3d)", + "WebKitCSSMatrix stringifier: Number.MIN_VALUE (2d)", + "WebKitCSSMatrix stringifier: Number.MIN_VALUE (3d)", + "WebKitCSSMatrix stringifier: throwing getters (2d)", + "WebKitCSSMatrix stringifier: throwing getters (3d)" + ], + "DOMMatrix2DInit-validate-fixup.html": false, + "DOMMatrixInit-validate-fixup.html": true, + "DOMPoint-001.html": true, + "DOMPoint-002.html": true, + "DOMQuad-001.html": true, + "DOMQuad-002.html": true, + "DOMQuad-nan.html": true, + "DOMRect-001.html": true, + "DOMRect-002.html": true, + "DOMRect-nan.html": true, + "DOMRectList.html": false, + "WebKitCSSMatrix.html": false, + "WebKitCSSMatrix.worker.html": true, + "historical.html": true, + "idlharness.any.html": [ + "DOMPointReadOnly interface: existence and properties of interface object", + "DOMPoint interface: existence and properties of interface object", + "DOMRectReadOnly interface: existence and properties of interface object", + "DOMRect interface: existence and properties of interface object", + "DOMRectList interface: existence and properties of interface object", + "DOMRectList interface object length", + "DOMRectList interface object name", + "DOMRectList interface: existence and properties of interface prototype object", + "DOMRectList interface: existence and properties of interface prototype object's \"constructor\" property", + "DOMRectList interface: existence and properties of interface prototype object's @@unscopables property", + "DOMRectList interface: attribute length", + "DOMRectList interface: operation item(unsigned long)", + "DOMQuad interface: existence and properties of interface object", + "DOMMatrixReadOnly interface: existence and properties of interface object", + "DOMMatrix interface: existence and properties of interface object" + ], + "idlharness.any.worker.html": [ + "DOMPointReadOnly interface: existence and properties of interface object", + "DOMPoint interface: existence and properties of interface object", + "DOMRectReadOnly interface: existence and properties of interface object", + "DOMRect interface: existence and properties of interface object", + "DOMQuad interface: existence and properties of interface object", + "DOMMatrixReadOnly interface: existence and properties of interface object", + "DOMMatrix interface: existence and properties of interface object" + ], + "spec-examples.html": true, + "structured-serialization.html": [ + "DOMPointReadOnly clone: basic", + "DOMPointReadOnly clone: custom property", + "DOMPointReadOnly clone: non-initial values", + "DOMPoint clone: basic", + "DOMPoint clone: custom property", + "DOMPoint clone: non-initial values", + "DOMRectReadOnly clone: basic", + "DOMRectReadOnly clone: custom property", + "DOMRectReadOnly clone: non-initial values", + "DOMRect clone: basic", + "DOMRect clone: custom property", + "DOMRect clone: non-initial values", + "DOMQuad clone: basic", + "DOMQuad clone: custom property", + "DOMQuad clone: non-initial values", + "DOMMatrixReadOnly clone: basic", + "DOMMatrixReadOnly clone: custom property", + "DOMMatrixReadOnly clone: non-initial values (2d)", + "DOMMatrixReadOnly clone: non-initial values (3d)", + "DOMMatrix clone: basic", + "DOMMatrix clone: custom property", + "DOMMatrix clone: non-initial values (2d)", + "DOMMatrix clone: non-initial values (3d)", + "DOMRectList clone" + ] + } } } diff --git a/tools/core_import_map.json b/tools/core_import_map.json index d38221eb4c8a04..00c47a030791c1 100644 --- a/tools/core_import_map.json +++ b/tools/core_import_map.json @@ -17,6 +17,8 @@ "ext:deno_fetch/26_fetch.js": "../ext/fetch/26_fetch.js", "ext:deno_ffi/00_ffi.js": "../ext/ffi/00_ffi.js", "ext:deno_fs/30_fs.js": "../ext/fs/30_fs.js", + "ext:deno_geometry/00_init.js": "../ext/geometry/00_init.js", + "ext:deno_geometry/01_geometry.js": "../ext/geometry/01_geometry.js", "ext:deno_http/00_serve.ts": "../ext/http/00_serve.ts", "ext:deno_http/01_http.js": "../ext/http/01_http.js", "ext:deno_io/12_io.js": "../ext/io/12_io.js", diff --git a/tools/jsdoc_checker.js b/tools/jsdoc_checker.js index 034782136c13e7..ecac03c8948134 100755 --- a/tools/jsdoc_checker.js +++ b/tools/jsdoc_checker.js @@ -13,6 +13,7 @@ const libs = [ join(ROOT_PATH, "ext/webstorage/lib.deno_webstorage.d.ts"), join(ROOT_PATH, "ext/canvas/lib.deno_canvas.d.ts"), join(ROOT_PATH, "ext/crypto/lib.deno_crypto.d.ts"), + join(ROOT_PATH, "ext/geometry/lib.deno_geometry.d.ts"), join(ROOT_PATH, "ext/net/lib.deno_net.d.ts"), join(ROOT_PATH, "cli/tsc/dts/lib.deno.ns.d.ts"), join(ROOT_PATH, "cli/tsc/dts/lib.deno.shared_globals.d.ts"), From 18e451d8452e9e98fd573c7361d9e4d851466cf0 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Thu, 2 Jan 2025 22:13:04 +0900 Subject: [PATCH 02/63] migrate to op2++ --- ext/geometry/00_init.js | 2 +- ext/geometry/01_geometry.js | 817 +++++++----------- ext/geometry/Cargo.toml | 2 +- ext/geometry/README.md | 30 +- ext/geometry/lib.deno_geometry.d.ts | 2 +- ext/geometry/lib.rs | 1222 ++++++++++++++++++++++----- tests/unit/geometry_test.ts | 2 +- 7 files changed, 1332 insertions(+), 745 deletions(-) diff --git a/ext/geometry/00_init.js b/ext/geometry/00_init.js index d1b89bac5cadc6..ea5e20870f2c87 100644 --- a/ext/geometry/00_init.js +++ b/ext/geometry/00_init.js @@ -1,4 +1,4 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2025 the Deno authors. MIT license. import { core } from "ext:core/mod.js"; diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 8b5957ee4e2610..4a9595d85769e0 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -1,30 +1,13 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2025 the Deno authors. MIT license. import { primordials } from "ext:core/mod.js"; -import { - op_geometry_flip_x_self, - op_geometry_flip_y_self, - op_geometry_invert_2d_self, - op_geometry_invert_self, - op_geometry_multiply, - op_geometry_multiply_self, - op_geometry_premultiply_point_self, - op_geometry_premultiply_self, - op_geometry_rotate_axis_angle_self, - op_geometry_rotate_from_vector_self, - op_geometry_rotate_self, - op_geometry_scale_self, - op_geometry_scale_with_origin_self, - op_geometry_skew_self, - op_geometry_translate_self, -} from "ext:core/ops"; +import { Matrix, op_create_matrix_identity, Point, Rect } from "ext:core/ops"; const { ArrayPrototypeJoin, Float32Array, Float64Array, MathMax, MathMin, - NumberIsFinite, ObjectDefineProperty, ObjectIs, ObjectPrototypeIsPrototypeOf, @@ -32,7 +15,6 @@ const { SymbolFor, SymbolIterator, TypeError, - TypedArrayPrototypeEvery, TypedArrayPrototypeJoin, } = primordials; @@ -232,7 +214,7 @@ webidl.converters.DOMMatrixInit = webidl.createDictionaryConverter( ], ); -const _raw = Symbol("[[raw]]"); +const _inner = Symbol("[[inner]]"); // Property to prevent writing values when an immutable instance is changed to // a mutable instance by Object.setPrototypeOf // TODO(petamoriken): Implementing resistance to Object.setPrototypeOf in the WebIDL layer @@ -241,20 +223,19 @@ const _brand = webidl.brand; class DOMPointReadOnly { [_writable] = false; - /** @type {Float64Array} */ - [_raw]; + [_inner]; constructor(x = 0, y = 0, z = 0, w = 1) { - this[_raw] = new Float64Array([ + this[_inner] = new Point( webidl.converters["unrestricted double"](x), webidl.converters["unrestricted double"](y), webidl.converters["unrestricted double"](z), webidl.converters["unrestricted double"](w), - ]); + ); this[_brand] = _brand; } - static fromPoint(other = {}) { + static fromPoint(other = { __proto__: null }) { other = webidl.converters.DOMPointInit( other, "Failed to execute 'DOMPointReadOnly.fromPoint'", @@ -262,61 +243,62 @@ class DOMPointReadOnly { ); const point = webidl.createBranded(DOMPointReadOnly); point[_writable] = false; - point[_raw] = new Float64Array([ + point[_inner] = new Point( other.x, other.y, other.z, other.w, - ]); + ); return point; } get x() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - return this[_raw][0]; + return this[_inner].x; } get y() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - return this[_raw][1]; + return this[_inner].y; } get z() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - return this[_raw][2]; + return this[_inner].z; } get w() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - return this[_raw][3]; + return this[_inner].w; } - matrixTransform(matrix = {}) { + matrixTransform(matrix = { __proto__: null }) { webidl.assertBranded(this, DOMPointReadOnlyPrototype); const prefix = "Failed to execute 'matrixTransform' on 'DOMPointReadOnly'"; - if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, matrix)) { + if ( + other === null || + !ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, matrix) + ) { const _matrix = webidl.converters.DOMMatrixInit( matrix, prefix, "Argument 1", ); validateAndFixupMatrixDictionary(_matrix, prefix); - matrix = {}; + matrix = { __proto__: null }; initMatrixFromDictonary(matrix, _matrix); } - const point = webidl.createBranded(DOMPoint); point[_writable] = true; - point[_raw] = new Float64Array(this[_raw]); - op_geometry_premultiply_point_self(matrix[_raw], point[_raw]); + point[_inner] = this[_inner].matrixTransform(matrix[_inner]); return point; } toJSON() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - const raw = this[_raw]; + const inner = this[_inner]; return { - x: raw[0], - y: raw[1], - z: raw[2], - w: raw[3], + x: inner.x, + y: inner.y, + z: inner.z, + w: inner.w, }; } @@ -343,7 +325,7 @@ const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; class DOMPoint extends DOMPointReadOnly { [_writable] = true; - static fromPoint(other = {}) { + static fromPoint(other = { __proto__: null }) { other = webidl.converters.DOMPointInit( other, "Failed to execute 'DOMPoint.fromPoint'", @@ -351,50 +333,50 @@ class DOMPoint extends DOMPointReadOnly { ); const point = webidl.createBranded(DOMPoint); point[_writable] = true; - point[_raw] = new Float64Array([ + point[_inner] = new Point( other.x, other.y, other.z, other.w, - ]); + ); return point; } get x() { webidl.assertBranded(this, DOMPointPrototype); - return this[_raw][0]; + return this[_inner].x; } set x(value) { webidl.assertBranded(this, DOMPointPrototype); assertWritable(this); - this[_raw][0] = webidl.converters["unrestricted double"](value); + this[_inner].x = webidl.converters["unrestricted double"](value); } get y() { webidl.assertBranded(this, DOMPointPrototype); - return this[_raw][1]; + return this[_inner].y; } set y(value) { webidl.assertBranded(this, DOMPointPrototype); assertWritable(this); - this[_raw][1] = webidl.converters["unrestricted double"](value); + this[_inner].y = webidl.converters["unrestricted double"](value); } get z() { webidl.assertBranded(this, DOMPointPrototype); - return this[_raw][2]; + return this[_inner].x; } set z(value) { webidl.assertBranded(this, DOMPointPrototype); assertWritable(this); - this[_raw][2] = webidl.converters["unrestricted double"](value); + this[_inner].z = webidl.converters["unrestricted double"](value); } get w() { webidl.assertBranded(this, DOMPointPrototype); - return this[_raw][3]; + return this[_inner].w; } set w(value) { webidl.assertBranded(this, DOMPointPrototype); assertWritable(this); - this[_raw][3] = webidl.converters["unrestricted double"](value); + this[_inner].x = webidl.converters["unrestricted double"](value); } [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { @@ -419,20 +401,19 @@ const DOMPointPrototype = DOMPoint.prototype; class DOMRectReadOnly { [_writable] = false; - /** @type {Float64Array} */ - [_raw]; + [_inner]; constructor(x = 0, y = 0, width = 0, height = 0) { - this[_raw] = new Float64Array([ + this[_inner] = new Rect( webidl.converters["unrestricted double"](x), webidl.converters["unrestricted double"](y), webidl.converters["unrestricted double"](width), webidl.converters["unrestricted double"](height), - ]); + ); this[_brand] = _brand; } - static fromRect(other = {}) { + static fromRect(other = { __proto__: null }) { other = webidl.converters.DOMRectInit( other, "Failed to execute 'DOMRectReadOnly.fromRect'", @@ -440,64 +421,64 @@ class DOMRectReadOnly { ); const rect = webidl.createBranded(DOMRectReadOnly); rect[_writable] = false; - rect[_raw] = new Float64Array([ + rect[_inner] = new Rect( other.x, other.y, other.width, other.height, - ]); + ); return rect; } get x() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_raw][0]; + return this[_inner].x; } get y() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_raw][1]; + return this[_inner].y; } get width() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_raw][2]; + return this[_inner].width; } get height() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_raw][3]; + return this[_inner].height; } get top() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const raw = this[_raw]; - return MathMin(raw[1], raw[1] + raw[3]); + const { y, height } = this[_inner]; + return MathMin(y, y + height); } get right() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const raw = this[_raw]; - return MathMax(raw[0], raw[0] + raw[2]); + const { x, width } = this[_inner]; + return MathMax(x, x + width); } get bottom() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const raw = this[_raw]; - return MathMax(raw[1], raw[1] + raw[3]); + const { y, height } = this[_inner]; + return MathMax(y, y + height); } get left() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const raw = this[_raw]; - return MathMin(raw[0], raw[0] + raw[2]); + const { x, width } = this[_inner]; + return MathMin(x, x + width); } toJSON() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const raw = this[_raw]; + const { x, y, width, height } = this[_inner]; return { - x: raw[0], - y: raw[1], - width: raw[2], - height: raw[3], - top: MathMin(raw[1], raw[1] + raw[3]), - right: MathMax(raw[0], raw[0] + raw[2]), - bottom: MathMax(raw[1], raw[1] + raw[3]), - left: MathMin(raw[0], raw[0] + raw[2]), + x, + y, + width, + height, + top: MathMin(y, y + height), + right: MathMax(x, x + width), + bottom: MathMax(y, y + height), + left: MathMin(x, x + width), }; } @@ -528,7 +509,7 @@ const DOMRectReadOnlyPrototype = DOMRectReadOnly.prototype; class DOMRect extends DOMRectReadOnly { [_writable] = true; - static fromRect(other = {}) { + static fromRect(other = { __proto__: null }) { other = webidl.converters.DOMRectInit( other, "Failed to execute 'DOMRect.fromRect'", @@ -536,50 +517,50 @@ class DOMRect extends DOMRectReadOnly { ); const rect = webidl.createBranded(DOMRect); rect[_writable] = true; - rect[_raw] = new Float64Array([ + rect[_inner] = new Rect( other.x, other.y, other.width, other.height, - ]); + ); return rect; } get x() { webidl.assertBranded(this, DOMRectPrototype); - return this[_raw][0]; + return this[_inner].x; } set x(value) { webidl.assertBranded(this, DOMRectPrototype); assertWritable(this); - this[_raw][0] = webidl.converters["unrestricted double"](value); + this[_inner].x = webidl.converters["unrestricted double"](value); } get y() { webidl.assertBranded(this, DOMRectPrototype); - return this[_raw][1]; + return this[_inner].y; } set y(value) { webidl.assertBranded(this, DOMRectPrototype); assertWritable(this); - this[_raw][1] = webidl.converters["unrestricted double"](value); + this[_inner].y = webidl.converters["unrestricted double"](value); } get width() { webidl.assertBranded(this, DOMRectPrototype); - return this[_raw][2]; + return this[_inner].width; } set width(value) { webidl.assertBranded(this, DOMRectPrototype); assertWritable(this); - this[_raw][2] = webidl.converters["unrestricted double"](value); + this[_inner].width = webidl.converters["unrestricted double"](value); } get height() { webidl.assertBranded(this, DOMRectPrototype); - return this[_raw][3]; + return this[_inner].height; } set height(value) { webidl.assertBranded(this, DOMRectPrototype); assertWritable(this); - this[_raw][3] = webidl.converters["unrestricted double"](value); + this[_inner].height = webidl.converters["unrestricted double"](value); } [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { @@ -621,7 +602,12 @@ class DOMQuad { /** @type {DOMPoint} */ [_p4]; - constructor(p1 = {}, p2 = {}, p3 = {}, p4 = {}) { + constructor( + p1 = { __proto__: null }, + p2 = { __proto__: null }, + p3 = { __proto__: null }, + p4 = { __proto__: null }, + ) { this[_p1] = DOMPoint.fromPoint(p1); this[_p2] = DOMPoint.fromPoint(p2); this[_p3] = DOMPoint.fromPoint(p3); @@ -629,7 +615,7 @@ class DOMQuad { this[_brand] = _brand; } - static fromRect(other = {}) { + static fromRect(other = { __proto__: null }) { other = webidl.converters.DOMRectInit( other, "Failed to execute 'DOMQuad.fromRect'", @@ -644,7 +630,7 @@ class DOMQuad { return quad; } - static fromQuad(other = {}) { + static fromQuad(other = { __proto__: null }) { other = webidl.converters.DOMQuadInit( other, "Failed to execute 'DOMQuad.fromQuad'", @@ -689,12 +675,12 @@ class DOMQuad { const bounds = webidl.createBranded(DOMRect); bounds[_writable] = true; - bounds[_raw] = new Float64Array([ + bounds[_inner] = new Rect( left, top, right - left, bottom - top, - ]); + ); return bounds; } @@ -728,69 +714,15 @@ class DOMQuad { webidl.configureInterface(DOMQuad); const DOMQuadPrototype = DOMQuad.prototype; -/* - * NOTE: column-major order - * - * For a 2D 3x2 matrix, the index of properties in - * | a c 0 e | | 0 4 _ 12 | - * | b d 0 f | | 1 5 _ 13 | - * | 0 0 1 0 | is | _ _ _ _ | - * | 0 0 0 1 | | _ _ _ _ | - */ -const INDEX_A = 0; -const INDEX_B = 1; -const INDEX_C = 4; -const INDEX_D = 5; -const INDEX_E = 12; -const INDEX_F = 13; - -/* - * NOTE: column-major order - * - * The index of properties in - * | m11 m21 m31 m41 | | 0 4 8 12 | - * | m12 m22 m32 m42 | | 1 5 9 13 | - * | m13 m23 m33 m43 | is | 2 6 10 14 | - * | m14 m24 m34 m44 | | 3 7 11 15 | - */ -const INDEX_M11 = 0; -const INDEX_M12 = 1; -const INDEX_M13 = 2; -const INDEX_M14 = 3; -const INDEX_M21 = 4; -const INDEX_M22 = 5; -const INDEX_M23 = 6; -const INDEX_M24 = 7; -const INDEX_M31 = 8; -const INDEX_M32 = 9; -const INDEX_M33 = 10; -const INDEX_M34 = 11; -const INDEX_M41 = 12; -const INDEX_M42 = 13; -const INDEX_M43 = 14; -const INDEX_M44 = 15; - -const _is2D = Symbol("[[is2D]]"); - class DOMMatrixReadOnly { [_writable] = false; - /** @type {Float64Array} */ - [_raw]; - /** @type {boolean} */ - [_is2D]; + [_inner]; constructor(init = undefined) { const prefix = `Failed to construct '${this.constructor.name}'`; this[_brand] = _brand; if (init === undefined) { - // deno-fmt-ignore - this[_raw] = new Float64Array([ - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1, - ]); - this[_is2D] = true; + this[_inner] = op_create_matrix_identity(); } else if ( webidl.type(init) === "Object" && init[SymbolIterator] !== undefined ) { @@ -807,18 +739,20 @@ class DOMMatrixReadOnly { "Argument 1", ); const { matrix, is2D } = parseTransformList(init, prefix); - this[_raw] = matrix; - this[_is2D] = is2D; + this[_inner] = new Matrix(matrix, is2D); } } - static fromMatrix(other = {}) { + static fromMatrix(other = { __proto__: null }) { const prefix = "Failed to execute 'DOMMatrixReadOnly.fromMatrix'"; const matrix = webidl.createBranded(DOMMatrixReadOnly); matrix[_writable] = false; // fast path for DOMMatrix or DOMMatrixReadOnly - if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { - initMatrixFromMatrix(matrix, other); + if ( + other !== null && + ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) + ) { + matrix[_inner] = other[_inner].clone(); } else { other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); validateAndFixupMatrixDictionary(other, prefix); @@ -849,99 +783,99 @@ class DOMMatrixReadOnly { get a() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_A]; + return this[_inner].a; } get b() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_B]; + return this[_inner].b; } get c() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_C]; + return this[_inner].c; } get d() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_D]; + return this[_inner].d; } get e() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_E]; + return this[_inner].e; } get f() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_F]; + return this[_inner].f; } get m11() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M11]; + return this[_inner].m11; } get m12() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M12]; + return this[_inner].m12; } get m13() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M13]; + return this[_inner].m13; } get m14() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M14]; + return this[_inner].m14; } get m21() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M21]; + return this[_inner].m21; } get m22() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M22]; + return this[_inner].m22; } get m23() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M23]; + return this[_inner].m23; } get m24() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M24]; + return this[_inner].m24; } get m31() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M31]; + return this[_inner].m31; } get m32() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M32]; + return this[_inner].m32; } get m33() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M33]; + return this[_inner].m33; } get m34() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M34]; + return this[_inner].m34; } get m41() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M41]; + return this[_inner].m41; } get m42() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M42]; + return this[_inner].m42; } get m43() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M43]; + return this[_inner].m43; } get m44() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M44]; + return this[_inner].m44; } get is2D() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_is2D]; + return this[_inner].is2D; } get isIdentity() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return isIdentityMatrix(this); + return this[_inner].isIdentity; } translate(tx = 0, ty = 0, tz = 0) { @@ -951,14 +885,7 @@ class DOMMatrixReadOnly { tz = webidl.converters["unrestricted double"](tz); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); - op_geometry_translate_self( - tx, - ty, - tz, - matrix[_raw], - ); - matrix[_is2D] = this[_is2D] && tz === 0; + matrix[_inner] = this[_inner].clone().translate(tx, ty, tz); return matrix; } @@ -979,26 +906,18 @@ class DOMMatrixReadOnly { originZ = webidl.converters["unrestricted double"](originZ); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); if (originX === 0 && originY === 0 && originZ === 0) { - op_geometry_scale_self( - scaleX, - scaleY, - scaleZ, - matrix[_raw], - ); + matrix[_inner] = this[_inner].clone().scale(scaleX, scaleY, scaleZ); } else { - op_geometry_scale_with_origin_self( + matrix[_inner] = this[_inner].clone().scaleWithOrigin( scaleX, scaleY, scaleZ, originX, originY, originZ, - matrix[_raw], ); } - matrix[_is2D] = this[_is2D] && scaleZ === 1 && originZ === 0; return matrix; } @@ -1008,14 +927,11 @@ class DOMMatrixReadOnly { scaleY = webidl.converters["unrestricted double"](scaleY); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); - op_geometry_scale_self( + matrix[_inner] = this[_inner].clone().scale( scaleX, scaleY, 1, - matrix[_raw], ); - matrix[_is2D] = this[_is2D]; return matrix; } @@ -1027,26 +943,18 @@ class DOMMatrixReadOnly { originZ = webidl.converters["unrestricted double"](originZ); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); if (originX === 0 && originY === 0 && originZ === 0) { - op_geometry_scale_self( - scale, - scale, - scale, - matrix[_raw], - ); + matrix[_inner] = this[_inner].clone().scale(scale, scale, scale); } else { - op_geometry_scale_with_origin_self( + matrix[_inner] = this[_inner].clone().scaleWithOrigin( scale, scale, scale, originX, originY, originZ, - matrix[_raw], ); } - matrix[_is2D] = this[_is2D] && scale === 1 && originZ === 0; return matrix; } @@ -1067,14 +975,11 @@ class DOMMatrixReadOnly { } const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); - op_geometry_rotate_self( + matrix[_inner] = this[_inner].clone().rotate( rotX, rotY, rotZ, - matrix[_raw], ); - matrix[_is2D] = this[_is2D] && rotX === 0 && rotY === 0; return matrix; } @@ -1084,13 +989,7 @@ class DOMMatrixReadOnly { y = webidl.converters["unrestricted double"](y); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); - op_geometry_rotate_from_vector_self( - x, - y, - matrix[_raw], - ); - matrix[_is2D] = this[_is2D]; + matrix[_inner] = this[_inner].clone().rotateFromVector(x, y); return matrix; } @@ -1102,17 +1001,14 @@ class DOMMatrixReadOnly { angle = webidl.converters["unrestricted double"](angle); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); if (x !== 0 || y !== 0 || z !== 0) { - op_geometry_rotate_axis_angle_self( + matrix[_inner] = this[_inner].clone().rotateAxisAngle( x, y, z, angle, - matrix[_raw], ); } - matrix[_is2D] = this[_is2D] && x === 0 && y === 0; return matrix; } @@ -1121,13 +1017,7 @@ class DOMMatrixReadOnly { sx = webidl.converters["unrestricted double"](sx); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); - op_geometry_skew_self( - sx, - 0, - matrix[_raw], - ); - matrix[_is2D] = this[_is2D]; + matrix[_inner] = this[_inner].clone().skewX(sx); return matrix; } @@ -1136,34 +1026,29 @@ class DOMMatrixReadOnly { sy = webidl.converters["unrestricted double"](sy); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); - op_geometry_skew_self( - 0, - sy, - matrix[_raw], - ); - matrix[_is2D] = this[_is2D]; + matrix[_inner] = this[_inner].clone().skewY(sy); return matrix; } - multiply(other = {}) { + multiply(other = { __proto__: null }) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const prefix = "Failed to execute 'multiply' on 'DOMMatrixReadOnly'"; - if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { + if ( + other === null || + !ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) + ) { const _other = webidl.converters.DOMMatrixInit( other, prefix, "Argument 1", ); validateAndFixupMatrixDictionary(_other, prefix); - other = {}; + other = { __proto__: null }; initMatrixFromDictonary(other, _other); } const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(16); - op_geometry_multiply(this[_raw], other[_raw], matrix[_raw]); - matrix[_is2D] = this[_is2D] && other[_is2D]; + matrix[_inner] = this[_inner].multiply(other[_inner]); return matrix; } @@ -1171,9 +1056,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); - op_geometry_flip_x_self(matrix[_raw]); - matrix[_is2D] = this[_is2D]; + matrix[_inner] = this[_inner].clone().flipX(); return matrix; } @@ -1181,9 +1064,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); - op_geometry_flip_y_self(matrix[_raw]); - matrix[_is2D] = this[_is2D]; + matrix[_inner] = this[_inner].clone().flipY(); return matrix; } @@ -1191,74 +1072,78 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); - let invertible; - if (this[_is2D]) { - invertible = op_geometry_invert_2d_self(matrix[_raw]); - } else { - invertible = op_geometry_invert_self(matrix[_raw]); - } - matrix[_is2D] = this[_is2D] && invertible; + matrix[_inner] = this[_inner].clone().inverse(); return matrix; } - transformPoint(point = {}) { + transformPoint(point = { __proto__: null }) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - point = webidl.converters.DOMPointInit( - point, - "Failed to execute 'transformPoint' on 'DOMMatrixReadOnly'", - "Argument 1", - ); + if ( + other === null || + !ObjectPrototypeIsPrototypeOf(DOMPointReadOnlyPrototype, point) + ) { + const _point = webidl.converters.DOMPointInit( + point, + "Failed to execute 'transformPoint' on 'DOMMatrixReadOnly'", + "Argument 1", + ); + point = { + [_inner]: new Point( + _point.x, + _point.y, + _point.z, + _point.w, + ), + }; + } const result = webidl.createBranded(DOMPoint); result[_writable] = true; - result[_raw] = new Float64Array([ - point.x, - point.y, - point.z, - point.w, - ]); - op_geometry_premultiply_point_self(this[_raw], result[_raw]); + result[_inner] = this[_inner].transformPoint(point[_inner]); return result; } toFloat32Array() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return new Float32Array(this[_raw]); + return new Float32Array( + new Float64Array( + this[_inner].toBuffer(), + ), + ); } toFloat64Array() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return new Float64Array(this[_raw]); + return new Float64Array(this[_inner].toBuffer()); } toJSON() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const raw = this[_raw]; + const inner = this[_inner]; return { - a: raw[INDEX_A], - b: raw[INDEX_B], - c: raw[INDEX_C], - d: raw[INDEX_D], - e: raw[INDEX_E], - f: raw[INDEX_F], - m11: raw[INDEX_M11], - m12: raw[INDEX_M12], - m13: raw[INDEX_M13], - m14: raw[INDEX_M14], - m21: raw[INDEX_M21], - m22: raw[INDEX_M22], - m23: raw[INDEX_M23], - m24: raw[INDEX_M24], - m31: raw[INDEX_M31], - m32: raw[INDEX_M32], - m33: raw[INDEX_M33], - m34: raw[INDEX_M34], - m41: raw[INDEX_M41], - m42: raw[INDEX_M42], - m43: raw[INDEX_M43], - m44: raw[INDEX_M44], - is2D: this[_is2D], - isIdentity: isIdentityMatrix(this), + a: inner.a, + b: inner.b, + c: inner.c, + d: inner.d, + e: inner.e, + f: inner.f, + m11: inner.m11, + m12: inner.m12, + m13: inner.m13, + m14: inner.m14, + m21: inner.m21, + m22: inner.m22, + m23: inner.m23, + m24: inner.m24, + m31: inner.m31, + m32: inner.m32, + m33: inner.m33, + m34: inner.m34, + m41: inner.m41, + m42: inner.m42, + m43: inner.m43, + m44: inner.m44, + is2D: inner.is2D, + isIdentity: inner.isIdentity, }; } @@ -1308,13 +1193,16 @@ const DOMMatrixReadOnlyPrototype = DOMMatrixReadOnly.prototype; class DOMMatrix extends DOMMatrixReadOnly { [_writable] = true; - static fromMatrix(other = {}) { + static fromMatrix(other = { __proto__: null }) { const prefix = "Failed to execute 'DOMMatrix.fromMatrix'"; const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; // fast path for DOMMatrix or DOMMatrixReadOnly - if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { - initMatrixFromMatrix(matrix, other); + if ( + other !== null && + ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) + ) { + matrix[_inner] = other[_inner].clone(); } else { other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); validateAndFixupMatrixDictionary(other, prefix); @@ -1345,276 +1233,242 @@ class DOMMatrix extends DOMMatrixReadOnly { get a() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_A]; + return this[_inner].a; } set a(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_A] = webidl.converters["unrestricted double"](value); + this[_inner].a = webidl.converters["unrestricted double"](value); } get b() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_B]; + return this[_inner].b; } set b(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_B] = webidl.converters["unrestricted double"](value); + this[_inner].b = webidl.converters["unrestricted double"](value); } get c() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_C]; + return this[_inner].c; } set c(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_C] = webidl.converters["unrestricted double"](value); + this[_inner].c = webidl.converters["unrestricted double"](value); } get d() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_D]; + return this[_inner].d; } set d(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_D] = webidl.converters["unrestricted double"](value); + this[_inner].d = webidl.converters["unrestricted double"](value); } get e() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_E]; + return this[_inner].e; } set e(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_E] = webidl.converters["unrestricted double"](value); + this[_inner].e = webidl.converters["unrestricted double"](value); } get f() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_F]; + return this[_inner].f; } set f(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_F] = webidl.converters["unrestricted double"](value); + this[_inner].f = webidl.converters["unrestricted double"](value); } get m11() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M11]; + return this[_inner].m11; } set m11(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_M11] = webidl.converters["unrestricted double"](value); + this[_inner].m11 = webidl.converters["unrestricted double"](value); } get m12() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M12]; + return this[_inner].m12; } set m12(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_M12] = webidl.converters["unrestricted double"](value); + this[_inner].m12 = webidl.converters["unrestricted double"](value); } get m13() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M13]; + return this[_inner].m13; } set m13(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 0) { - this[_is2D] = false; - } - this[_raw][INDEX_M13] = webidl.converters["unrestricted double"](value); + this[_inner].m13 = webidl.converters["unrestricted double"](value); } get m14() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M14]; + return this[_inner].m14; } set m14(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 0) { - this[_is2D] = false; - } - this[_raw][INDEX_M14] = webidl.converters["unrestricted double"](value); + this[_inner].m14 = webidl.converters["unrestricted double"](value); } get m21() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M21]; + return this[_inner].m21; } set m21(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_M21] = webidl.converters["unrestricted double"](value); + this[_inner].m21 = webidl.converters["unrestricted double"](value); } get m22() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M22]; + return this[_inner].m22; } set m22(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_M22] = webidl.converters["unrestricted double"](value); + this[_inner].m22 = webidl.converters["unrestricted double"](value); } get m23() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M23]; + return this[_inner].m23; } set m23(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 0) { - this[_is2D] = false; - } - this[_raw][INDEX_M23] = webidl.converters["unrestricted double"](value); + this[_inner].m23 = webidl.converters["unrestricted double"](value); } get m24() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M24]; + return this[_inner].m24; } set m24(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 0) { - this[_is2D] = false; - } - this[_raw][INDEX_M24] = webidl.converters["unrestricted double"](value); + this[_inner].m24 = webidl.converters["unrestricted double"](value); } get m31() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M31]; + return this[_inner].m31; } set m31(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 0) { - this[_is2D] = false; - } - this[_raw][INDEX_M31] = webidl.converters["unrestricted double"](value); + this[_inner].m31 = webidl.converters["unrestricted double"](value); } get m32() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M32]; + return this[_inner].m32; } set m32(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 0) { - this[_is2D] = false; - } - this[_raw][INDEX_M32] = webidl.converters["unrestricted double"](value); + this[_inner].m32 = webidl.converters["unrestricted double"](value); } get m33() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M33]; + return this[_inner].m33; } set m33(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 1) { - this[_is2D] = false; - } - this[_raw][INDEX_M33] = webidl.converters["unrestricted double"](value); + this[_inner].m33 = webidl.converters["unrestricted double"](value); } get m34() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M34]; + return this[_inner].m34; } set m34(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 0) { - this[_is2D] = false; - } - this[_raw][INDEX_M34] = webidl.converters["unrestricted double"](value); + this[_inner].m34 = webidl.converters["unrestricted double"](value); } get m41() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M41]; + return this[_inner].m41; } set m41(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_M41] = webidl.converters["unrestricted double"](value); + this[_inner].m41 = webidl.converters["unrestricted double"](value); } get m42() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M42]; + return this[_inner].m42; } set m42(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_M42] = webidl.converters["unrestricted double"](value); + this[_inner].m42 = webidl.converters["unrestricted double"](value); } get m43() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M43]; + return this[_inner].m43; } set m43(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 0) { - this[_is2D] = false; - } - this[_raw][INDEX_M43] = webidl.converters["unrestricted double"](value); + this[_inner].m43 = webidl.converters["unrestricted double"](value); } get m44() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M44]; + return this[_inner].m44; } set m44(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 1) { - this[_is2D] = false; - } - this[_raw][INDEX_M44] = webidl.converters["unrestricted double"](value); + this[_inner].m44 = webidl.converters["unrestricted double"](value); } - multiplySelf(other = {}) { + multiplySelf(other = { __proto__: null }) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); const prefix = "Failed to execute 'multiplySelf' on 'DOMMatrix'"; - if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { + if ( + other === null || + !ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) + ) { const _other = webidl.converters.DOMMatrixInit( other, prefix, "Argument 1", ); validateAndFixupMatrixDictionary(_other, prefix); - other = {}; + other = { __proto__: null }; initMatrixFromDictonary(other, _other); - } else if (this[_raw] === other[_raw]) { - other = {}; - initMatrixFromMatrix(other, this); } - - op_geometry_multiply_self(other[_raw], this[_raw]); - this[_is2D] &&= other[_is2D]; + this[_inner].multiplySelf(other[_inner]); return this; } - preMultiplySelf(other = {}) { + preMultiplySelf(other = { __proto__: null }) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); const prefix = "Failed to execute 'premultiplySelf' on 'DOMMatrix'"; - if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { + if ( + other === null || + !ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) + ) { const _other = webidl.converters.DOMMatrixInit( other, prefix, "Argument 1", ); validateAndFixupMatrixDictionary(_other, prefix); - other = {}; + other = { __proto__: null }; initMatrixFromDictonary(other, _other); - } else if (this[_raw] === other[_raw]) { - other = {}; - initMatrixFromMatrix(other, this); } - - op_geometry_premultiply_self(other[_raw], this[_raw]); - this[_is2D] &&= other[_is2D]; + this[_inner].preMultiplySelf(other[_inner]); return this; } @@ -1624,13 +1478,7 @@ class DOMMatrix extends DOMMatrixReadOnly { tx = webidl.converters["unrestricted double"](tx); ty = webidl.converters["unrestricted double"](ty); tz = webidl.converters["unrestricted double"](tz); - op_geometry_translate_self( - tx, - ty, - tz, - this[_raw], - ); - this[_is2D] &&= tz === 0; + this[_inner].translate(tx, ty, tz); return this; } @@ -1651,24 +1499,17 @@ class DOMMatrix extends DOMMatrixReadOnly { originY = webidl.converters["unrestricted double"](originY); originZ = webidl.converters["unrestricted double"](originZ); if (originX === 0 && originY === 0 && originZ === 0) { - op_geometry_scale_self( - scaleX, - scaleY, - scaleZ, - this[_raw], - ); + this[_inner].scale(scaleX, scaleY, scaleZ); } else { - op_geometry_scale_with_origin_self( + this[_inner].scaleWithOrigin( scaleX, scaleY, scaleZ, originX, originY, originZ, - this[_raw], ); } - this[_is2D] &&= scaleZ === 1 && originZ === 0; return this; } @@ -1680,24 +1521,17 @@ class DOMMatrix extends DOMMatrixReadOnly { originY = webidl.converters["unrestricted double"](originY); originZ = webidl.converters["unrestricted double"](originZ); if (originX === 0 && originY === 0 && originZ === 0) { - op_geometry_scale_self( - scale, - scale, - scale, - this[_raw], - ); + this[_inner].scale(scale, scale, scale); } else { - op_geometry_scale_with_origin_self( + this[_inner].scaleWithOrigin( scale, scale, scale, originX, originY, originZ, - this[_raw], ); } - this[_is2D] &&= scale === 1 && originZ === 0; return this; } @@ -1717,13 +1551,11 @@ class DOMMatrix extends DOMMatrixReadOnly { ? webidl.converters["unrestricted double"](rotZ) : 0; } - op_geometry_rotate_self( + this[_inner].rotateSelf( rotX, rotY, rotZ, - this[_raw], ); - this[_is2D] &&= rotX === 0 && rotY === 0; return this; } @@ -1732,11 +1564,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); x = webidl.converters["unrestricted double"](x); y = webidl.converters["unrestricted double"](y); - op_geometry_rotate_from_vector_self( - x, - y, - this[_raw], - ); + this[_inner].rotateFromVectorSelf(x, y); return this; } @@ -1748,15 +1576,13 @@ class DOMMatrix extends DOMMatrixReadOnly { z = webidl.converters["unrestricted double"](z); angle = webidl.converters["unrestricted double"](angle); if (x !== 0 || y !== 0 || z !== 0) { - op_geometry_rotate_axis_angle_self( + this[_inner].rotateAxisAngleSelf( x, y, z, angle, - this[_raw], ); } - this[_is2D] &&= x === 0 && y === 0; return this; } @@ -1764,11 +1590,7 @@ class DOMMatrix extends DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); sx = webidl.converters["unrestricted double"](sx); - op_geometry_skew_self( - sx, - 0, - this[_raw], - ); + this[_inner].skewXSelf(sx); return this; } @@ -1776,24 +1598,14 @@ class DOMMatrix extends DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); sy = webidl.converters["unrestricted double"](sy); - op_geometry_skew_self( - 0, - sy, - this[_raw], - ); + this[_inner].skewYSelf(sy); return this; } invertSelf() { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - let invertible; - if (this[_is2D]) { - invertible = op_geometry_invert_2d_self(this[_raw]); - } else { - invertible = op_geometry_invert_self(this[_raw]); - } - this[_is2D] &&= invertible; + this[_inner].inverse(); return this; } @@ -1934,16 +1746,14 @@ function initMatrixFromSequence(target, seq, prefix) { if (seq.length === 6) { const { 0: a, 1: b, 2: c, 3: d, 4: e, 5: f } = seq; // deno-fmt-ignore - target[_raw] = new Float64Array([ + target[_inner] = new Matrix(new Float64Array([ a, b, 0, 0, c, d, 0, 0, 0, 0, 1, 0, e, f, 0, 1, - ]); - target[_is2D] = true; + ]), /* is2D */ true); } else if (seq.length === 16) { - target[_raw] = new Float64Array(seq); - target[_is2D] = false; + target[_inner] = new Matrix(new Float64Array(seq), /* is2D */ false); } else { throw new TypeError( `${prefix}: The sequence must contain 6 elements for a 2D matrix or 16 elements for a 3D matrix`, @@ -1959,78 +1769,30 @@ function initMatrixFromDictonary(target, dict) { if (dict.is2D) { const { m11, m12, m21, m22, m41, m42 } = dict; // deno-fmt-ignore - target[_raw] = new Float64Array([ + target[_inner] = new Matrix(new Float64Array([ m11, m12, 0, 0, m21, m22, 0, 0, 0, 0, 1, 0, m41, m42, 0, 1, - ]); - target[_is2D] = true; + ]), /* is2D */ true); } else { + // deno-fmt-ignore const { - m11, - m12, - m13, - m14, - m21, - m22, - m23, - m24, - m31, - m32, - m33, - m34, - m41, - m42, - m43, - m44, + m11, m12, m13, m14, + m21, m22, m23, m24, + m31, m32, m33, m34, + m41, m42, m43, m44, } = dict; // deno-fmt-ignore - target[_raw] = new Float64Array([ + target[_inner] = new Matrix(new Float64Array([ m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44, - ]); - target[_is2D] = false; + ]), /* is2D */ false); } } -/** - * @param {object} target - * @type {DOMMatrixReadOnly} matrix - */ -function initMatrixFromMatrix(target, matrix) { - target[_raw] = new Float64Array(matrix[_raw]); - target[_is2D] = matrix[_is2D]; -} - -/** - * https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-isidentity - * @param {DOMMatrixReadOnly} matrix - */ -function isIdentityMatrix(matrix) { - const raw = matrix[_raw]; - return ( - raw[INDEX_M11] === 1 && - raw[INDEX_M12] === 0 && - raw[INDEX_M13] === 0 && - raw[INDEX_M14] === 0 && - raw[INDEX_M21] === 0 && - raw[INDEX_M22] === 1 && - raw[INDEX_M23] === 0 && - raw[INDEX_M24] === 0 && - raw[INDEX_M31] === 0 && - raw[INDEX_M32] === 0 && - raw[INDEX_M33] === 1 && - raw[INDEX_M34] === 0 && - raw[INDEX_M41] === 0 && - raw[INDEX_M42] === 0 && - raw[INDEX_M43] === 0 && - raw[INDEX_M44] === 1 - ); -} - /** * CSS parser * @type {((transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean })} @@ -2047,28 +1809,31 @@ function init(transformListParser, enableWindowFeatures) { if (enableWindowFeatures) { // https://drafts.fxtf.org/geometry/#dommatrixreadonly-stringification-behavior ObjectDefineProperty(DOMMatrixReadOnlyPrototype, "toString", { + __proto__: null, value: function toString() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const raw = this[_raw]; - if (!TypedArrayPrototypeEvery(raw, (value) => NumberIsFinite(value))) { + const inner = this[_inner]; + if (!inner.isFinite) { throw new DOMException( "Failed to execute 'toString' on 'DOMMatrixReadOnly': Cannot be serialized with NaN or Infinity values", "InvalidStateError", ); } - if (this[_is2D]) { + if (inner.is2D) { return `matrix(${ ArrayPrototypeJoin([ - raw[INDEX_A], - raw[INDEX_B], - raw[INDEX_C], - raw[INDEX_D], - raw[INDEX_E], - raw[INDEX_F], + inner.a, + inner.b, + inner.c, + inner.d, + inner.e, + inner.f, ], ", ") })`; } else { - return `matrix3d(${TypedArrayPrototypeJoin(raw, ", ")})`; + return `matrix3d(${ + TypedArrayPrototypeJoin(new Float64Array(inner.toBuffer()), ", ") + })`; } }, writable: true, @@ -2078,6 +1843,7 @@ function init(transformListParser, enableWindowFeatures) { // https://drafts.fxtf.org/geometry/#dom-dommatrix-setmatrixvalue ObjectDefineProperty(DOMMatrixPrototype, "setMatrixValue", { + __proto__: null, value: function setMatrixValue(transformList) { webidl.assertBranded(this, DOMMatrixPrototype); const prefix = "Failed to execute 'setMatrixValue' on 'DOMMatrix'"; @@ -2088,8 +1854,7 @@ function init(transformListParser, enableWindowFeatures) { "Argument 1", ); const { matrix, is2D } = parseTransformList(transformList, prefix); - this[_raw] = matrix; - this[_is2D] = is2D; + this[_inner] = new Matrix(matrix, is2D); }, writable: true, enumerable: true, diff --git a/ext/geometry/Cargo.toml b/ext/geometry/Cargo.toml index 9ab2c7c698eaeb..e831ea7c98edde 100644 --- a/ext/geometry/Cargo.toml +++ b/ext/geometry/Cargo.toml @@ -1,4 +1,4 @@ -# Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +# Copyright 2018-2025 the Deno authors. MIT license. [package] name = "deno_geometry" diff --git a/ext/geometry/README.md b/ext/geometry/README.md index 09465490254c8e..3d5ad3ce4f60a1 100644 --- a/ext/geometry/README.md +++ b/ext/geometry/README.md @@ -13,7 +13,8 @@ import { core } from "ext:core/mod.js"; import { createGeometryLoader } from "ext:deno_geometry/00_init.js"; ``` -For environments that do not have a CSS `` parser, such as Web Worker, configure as follows: +For environments that do not have a CSS `` parser, such as Web +Worker, configure as follows: ```javascript const loadGeometry = createGeometryLoader((_transformList, prefix) => { @@ -23,7 +24,8 @@ const loadGeometry = createGeometryLoader((_transformList, prefix) => { }, /* enableWindowFeatures */ false); ``` -On the other hand, in environments with a CSS `` parser, you can configure as follows: +On the other hand, in environments with a CSS `` parser, you can +configure as follows: ```javascript const loadGeometry = createGeometryLoader((transformList, prefix) => { @@ -77,9 +79,8 @@ Object.defineProperties(globalThis, { }); ``` -Then from rust, provide: -`deno_geometry::deno_geometry::init_ops_and_esm()` in the `extensions` -field of your `RuntimeOptions` +Then from rust, provide: `deno_geometry::deno_geometry::init_ops_and_esm()` in +the `extensions` field of your `RuntimeOptions` ## Dependencies @@ -91,18 +92,7 @@ field of your `RuntimeOptions` Following ops are provided, which can be accessed through `Deno.ops`: -- op_geometry_translate_self -- op_geometry_scale_self -- op_geometry_scale_with_origin_self -- op_geometry_rotate_self -- op_geometry_rotate_from_vector_self -- op_geometry_rotate_axis_angle_self -- op_geometry_skew_self -- op_geometry_multiply -- op_geometry_multiply_self -- op_geometry_premultiply_self -- op_geometry_flip_x_self -- op_geometry_flip_y_self -- op_geometry_invert_self -- op_geometry_invert_2d_self -- op_geometry_premultiply_point_self +- op_create_matrix_identity +- Matrix +- Point +- Rect diff --git a/ext/geometry/lib.deno_geometry.d.ts b/ext/geometry/lib.deno_geometry.d.ts index 44b06d763ebf50..3868044319bbc7 100644 --- a/ext/geometry/lib.deno_geometry.d.ts +++ b/ext/geometry/lib.deno_geometry.d.ts @@ -1,4 +1,4 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2025 the Deno authors. MIT license. // deno-lint-ignore-file no-var diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 16879f4ddf2071..cd7bd76c1e02d3 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -1,39 +1,29 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2025 the Deno authors. MIT license. +use std::cell::Cell; +use std::cell::RefCell; +use std::mem; +use std::path::PathBuf; +use std::slice; + +use deno_core::cppgc; use deno_core::op2; +use deno_core::v8; +use deno_core::GarbageCollected; use nalgebra::Matrix3; use nalgebra::Matrix4; use nalgebra::Matrix4x2; use nalgebra::Matrix4x3; -use nalgebra::MatrixView4; -use nalgebra::MatrixViewMut4; use nalgebra::Rotation3; use nalgebra::UnitVector3; use nalgebra::Vector3; use nalgebra::Vector4; -use nalgebra::VectorViewMut4; -use std::path::PathBuf; deno_core::extension!( deno_geometry, deps = [deno_webidl, deno_web, deno_console], - ops = [ - op_geometry_translate_self, - op_geometry_scale_self, - op_geometry_scale_with_origin_self, - op_geometry_rotate_self, - op_geometry_rotate_from_vector_self, - op_geometry_rotate_axis_angle_self, - op_geometry_skew_self, - op_geometry_multiply, - op_geometry_multiply_self, - op_geometry_premultiply_self, - op_geometry_flip_x_self, - op_geometry_flip_y_self, - op_geometry_invert_self, - op_geometry_invert_2d_self, - op_geometry_premultiply_point_self, - ], + ops = [op_create_matrix_identity], + objects = [Point, Rect, Matrix], esm = ["00_init.js"], lazy_loaded_esm = ["01_geometry.js"], ); @@ -42,228 +32,1070 @@ pub fn get_declaration() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_geometry.d.ts") } -#[op2(fast)] -pub fn op_geometry_translate_self( - x: f64, - y: f64, - z: f64, - #[buffer] inout: &mut [f64], -) { - let shift = Vector3::new(x, y, z); - let mut inout = MatrixViewMut4::from_slice(inout); - inout.prepend_translation_mut(&shift); +pub struct Point { + x: Cell, + y: Cell, + z: Cell, + w: Cell, } -#[op2(fast)] -pub fn op_geometry_scale_self( - x: f64, - y: f64, - z: f64, - #[buffer] inout: &mut [f64], -) { - let scaling = Vector3::new(x, y, z); - let mut inout = MatrixViewMut4::from_slice(inout); - inout.prepend_nonuniform_scaling_mut(&scaling); +impl GarbageCollected for Point {} + +#[op2] +impl Point { + #[constructor] + #[cppgc] + pub fn constructor(x: f64, y: f64, z: f64, w: f64) -> Point { + Point { + x: Cell::new(x), + y: Cell::new(y), + z: Cell::new(z), + w: Cell::new(w), + } + } + + #[fast] + #[getter] + pub fn x(&self) -> f64 { + self.x.get() + } + + #[fast] + #[setter] + pub fn x(&self, value: f64) { + self.x.set(value) + } + + #[fast] + #[getter] + pub fn y(&self) -> f64 { + self.y.get() + } + + #[fast] + #[setter] + pub fn y(&self, value: f64) { + self.y.set(value) + } + + #[fast] + #[getter] + pub fn z(&self) -> f64 { + self.z.get() + } + + #[fast] + #[setter] + pub fn z(&self, value: f64) { + self.z.set(value) + } + + #[fast] + #[getter] + pub fn w(&self) -> f64 { + self.w.get() + } + + #[fast] + #[setter] + pub fn w(&self, value: f64) { + self.w.set(value) + } + + #[cppgc] + pub fn matrixTransform(&self, matrix: v8::Local) -> Point { + let matrix = cast_to_matrix(matrix); + let out = Point { + x: Cell::new(0.0), + y: Cell::new(0.0), + z: Cell::new(0.0), + w: Cell::new(0.0), + }; + matrix_transform_point(&matrix, self, &out); + out + } } -#[op2(fast)] -pub fn op_geometry_scale_with_origin_self( - x: f64, - y: f64, - z: f64, +pub struct Rect { + x: Cell, + y: Cell, + width: Cell, + height: Cell, +} + +impl GarbageCollected for Rect {} + +#[op2] +impl Rect { + #[constructor] + #[cppgc] + pub fn constructor(x: f64, y: f64, width: f64, height: f64) -> Rect { + Rect { + x: Cell::new(x), + y: Cell::new(y), + width: Cell::new(width), + height: Cell::new(height), + } + } + + #[fast] + #[getter] + pub fn x(&self) -> f64 { + self.x.get() + } + + #[fast] + #[setter] + pub fn x(&self, value: f64) { + self.x.set(value) + } + + #[fast] + #[getter] + pub fn y(&self) -> f64 { + self.y.get() + } + + #[fast] + #[setter] + pub fn y(&self, value: f64) { + self.y.set(value) + } + + #[fast] + #[getter] + pub fn width(&self) -> f64 { + self.width.get() + } + + #[fast] + #[setter] + pub fn width(&self, value: f64) { + self.width.set(value) + } + + #[fast] + #[getter] + pub fn height(&self) -> f64 { + self.height.get() + } + + #[fast] + #[setter] + pub fn height(&self, value: f64) { + self.height.set(value) + } +} + +#[derive(Clone)] +pub struct Matrix { + inner: RefCell>, + is_2d: Cell, +} + +impl GarbageCollected for Matrix {} + +/* + * NOTE: column-major order + * + * For a 2D 3x2 matrix, the index of properties in + * | a c 0 e | | 0 4 _ 12 | + * | b d 0 f | | 1 5 _ 13 | + * | 0 0 1 0 | is | _ _ _ _ | + * | 0 0 0 1 | | _ _ _ _ | + */ +const INDEX_A: usize = 0; +const INDEX_B: usize = 1; +const INDEX_C: usize = 4; +const INDEX_D: usize = 5; +const INDEX_E: usize = 12; +const INDEX_F: usize = 13; + +/* + * NOTE: column-major order + * + * The index of properties in + * | m11 m21 m31 m41 | | 0 4 8 12 | + * | m12 m22 m32 m42 | | 1 5 9 13 | + * | m13 m23 m33 m43 | is | 2 6 10 14 | + * | m14 m24 m34 m44 | | 3 7 11 15 | + */ +const INDEX_M11: usize = 0; +const INDEX_M12: usize = 1; +const INDEX_M13: usize = 2; +const INDEX_M14: usize = 3; +const INDEX_M21: usize = 4; +const INDEX_M22: usize = 5; +const INDEX_M23: usize = 6; +const INDEX_M24: usize = 7; +const INDEX_M31: usize = 8; +const INDEX_M32: usize = 9; +const INDEX_M33: usize = 10; +const INDEX_M34: usize = 11; +const INDEX_M41: usize = 12; +const INDEX_M42: usize = 13; +const INDEX_M43: usize = 14; +const INDEX_M44: usize = 15; + +#[op2] +impl Matrix { + #[constructor] + #[cppgc] + pub fn constructor(#[buffer] buffer: &[f64], is_2d: bool) -> Matrix { + Matrix { + inner: RefCell::new(Matrix4::from_column_slice(buffer)), + is_2d: Cell::new(is_2d), + } + } + + #[cppgc] + pub fn clone(&self) -> Matrix { + self.clone() + } + + #[fast] + #[getter] + pub fn a(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_A) } + } + + #[fast] + #[setter] + pub fn a(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_A) = value; + } + } + + #[fast] + #[getter] + pub fn b(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_B) } + } + + #[fast] + #[setter] + pub fn b(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_B) = value; + } + } + + #[fast] + #[getter] + pub fn c(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_C) } + } + + #[fast] + #[setter] + pub fn c(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_C) = value; + } + } + + #[fast] + #[getter] + pub fn d(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_D) } + } + + #[fast] + #[setter] + pub fn d(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_D) = value; + } + } + + #[fast] + #[getter] + pub fn e(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_E) } + } + + #[fast] + #[setter] + pub fn e(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_E) = value; + } + } + + #[fast] + #[getter] + pub fn f(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_F) } + } + + #[fast] + #[setter] + pub fn f(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_F) = value; + } + } + + #[fast] + #[getter] + pub fn m11(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M11) } + } + + #[fast] + #[setter] + pub fn m11(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M11) = value; + } + } + + #[fast] + #[getter] + pub fn m12(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M12) } + } + + #[fast] + #[setter] + pub fn m12(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M12) = value; + } + } + + #[fast] + #[getter] + pub fn m13(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M13) } + } + + #[fast] + #[setter] + pub fn m13(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M13) = value; + } + if value != 0.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn m14(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M14) } + } + + #[fast] + #[setter] + pub fn m14(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M14) = value; + } + if value != 0.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn m21(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M21) } + } + + #[fast] + #[setter] + pub fn m21(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M21) = value; + } + } + + #[fast] + #[getter] + pub fn m22(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M22) } + } + + #[fast] + #[setter] + pub fn m22(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M22) = value; + } + } + + #[fast] + #[getter] + pub fn m23(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M23) } + } + + #[fast] + #[setter] + pub fn m23(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M23) = value; + } + if value != 0.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn m24(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M24) } + } + + #[fast] + #[setter] + pub fn m24(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M24) = value; + } + if value != 0.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn m31(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M31) } + } + + #[fast] + #[setter] + pub fn m31(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M31) = value; + } + if value != 0.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn m32(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M32) } + } + + #[fast] + #[setter] + pub fn m32(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M32) = value; + } + if value != 0.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn m33(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M33) } + } + + #[fast] + #[setter] + pub fn m33(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M33) = value; + } + if value != 1.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn m34(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M34) } + } + + #[fast] + #[setter] + pub fn m34(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M34) = value; + } + if value != 0.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn m41(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M41) } + } + + #[fast] + #[setter] + pub fn m41(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M41) = value; + } + } + + #[fast] + #[getter] + pub fn m42(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M42) } + } + + #[fast] + #[setter] + pub fn m42(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M42) = value; + } + } + + #[fast] + #[getter] + pub fn m43(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M43) } + } + + #[fast] + #[setter] + pub fn m43(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M43) = value; + } + if value != 0.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn m44(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M44) } + } + + #[fast] + #[setter] + pub fn m44(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M44) = value; + } + if value != 1.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn is_2d(&self) -> bool { + self.is_2d.get() + } + + #[fast] + #[getter] + pub fn is_identity(&self) -> bool { + let inner = self.inner.borrow(); + // SAFETY: in-range access + unsafe { + *inner.get_unchecked(INDEX_M11) == 1.0 + && *inner.get_unchecked(INDEX_M12) == 0.0 + && *inner.get_unchecked(INDEX_M13) == 0.0 + && *inner.get_unchecked(INDEX_M14) == 0.0 + && *inner.get_unchecked(INDEX_M21) == 0.0 + && *inner.get_unchecked(INDEX_M22) == 1.0 + && *inner.get_unchecked(INDEX_M23) == 0.0 + && *inner.get_unchecked(INDEX_M24) == 0.0 + && *inner.get_unchecked(INDEX_M31) == 0.0 + && *inner.get_unchecked(INDEX_M32) == 0.0 + && *inner.get_unchecked(INDEX_M33) == 1.0 + && *inner.get_unchecked(INDEX_M34) == 0.0 + && *inner.get_unchecked(INDEX_M41) == 0.0 + && *inner.get_unchecked(INDEX_M42) == 0.0 + && *inner.get_unchecked(INDEX_M43) == 0.0 + && *inner.get_unchecked(INDEX_M44) == 1.0 + } + } + + #[fast] + #[getter] + pub fn is_finite(&self) -> bool { + self + .inner + .borrow() + .into_iter() + .all(|&item| item.is_finite()) + } + + #[arraybuffer] + pub fn to_buffer(&self) -> Vec { + // SAFETY: in-range access + unsafe { + slice::from_raw_parts( + self.inner.borrow().as_slice().as_ptr() as *mut u8, + 128, + ) + } + .to_vec() + } + + #[cppgc] + pub fn translate(&self, tx: f64, ty: f64, tz: f64) -> Matrix { + let out = self.clone(); + matrix_translate(&out, tx, ty, tz); + out + } + + #[fast] + pub fn translate_self(&self, tx: f64, ty: f64, tz: f64) { + matrix_translate(self, tx, ty, tz); + } + + #[cppgc] + pub fn scale(&self, sx: f64, sy: f64, sz: f64) -> Matrix { + let out = self.clone(); + matrix_scale(&out, sx, sy, sz); + out + } + + #[fast] + pub fn scale_self(&self, sx: f64, sy: f64, sz: f64) { + matrix_scale(self, sx, sy, sz); + } + + #[cppgc] + pub fn scale_with_origin( + &self, + sx: f64, + sy: f64, + sz: f64, + origin_x: f64, + origin_y: f64, + origin_z: f64, + ) -> Matrix { + let out = self.clone(); + matrix_scale_with_origin(&out, sx, sy, sz, origin_x, origin_y, origin_z); + out + } + + #[fast] + pub fn scale_with_origin_self( + &self, + sx: f64, + sy: f64, + sz: f64, + origin_x: f64, + origin_y: f64, + origin_z: f64, + ) { + matrix_scale_with_origin(self, sx, sy, sz, origin_x, origin_y, origin_z); + } + + #[cppgc] + pub fn rotate(&self, roll_deg: f64, pitch_deg: f64, yaw_deg: f64) -> Matrix { + let out = self.clone(); + matrix_rotate(&out, roll_deg, pitch_deg, yaw_deg); + out + } + + #[fast] + pub fn rotate_self(&self, roll_deg: f64, pitch_deg: f64, yaw_deg: f64) { + matrix_rotate(self, roll_deg, pitch_deg, yaw_deg); + } + + #[cppgc] + pub fn rotate_from_vector(&self, x: f64, y: f64) -> Matrix { + let out = self.clone(); + matrix_rotate_from_vector(&out, x, y); + out + } + + #[fast] + pub fn rotate_from_vector_self(&self, x: f64, y: f64) { + matrix_rotate_from_vector(self, x, y); + } + + #[cppgc] + pub fn rotate_axis_angle( + &self, + x: f64, + y: f64, + z: f64, + angle_deg: f64, + ) -> Matrix { + let out = self.clone(); + matrix_rotate_axis_angle(&out, x, y, z, angle_deg); + out + } + + #[fast] + pub fn rotate_axis_angle_self(&self, x: f64, y: f64, z: f64, angle_deg: f64) { + matrix_rotate_axis_angle(self, x, y, z, angle_deg); + } + + #[cppgc] + pub fn skew_x(&self, x_deg: f64) -> Matrix { + let out = self.clone(); + matrix_skew_x(&out, x_deg); + out + } + + #[fast] + pub fn skew_x_self(&self, x_deg: f64) { + matrix_skew_x(self, x_deg); + } + + #[cppgc] + pub fn skew_y(&self, y_deg: f64) -> Matrix { + let out = self.clone(); + matrix_skew_y(&out, y_deg); + out + } + + #[fast] + pub fn skew_y_self(&self, y_deg: f64) { + matrix_skew_y(self, y_deg); + } + + #[cppgc] + pub fn multiply(&self, other: v8::Local) -> Matrix { + let other = cast_to_matrix(other); + let out = Matrix { + inner: RefCell::new(Matrix4::zeros()), + is_2d: Cell::new(true), + }; + matrix_multiply(&out, self, &other); + out + } + + #[fast] + pub fn multiply_self(&self, other: v8::Local) { + let other = cast_to_matrix(other); + let result = Matrix { + inner: RefCell::new(Matrix4::zeros()), + is_2d: Cell::new(true), + }; + matrix_multiply(&result, self, &other); + self.inner.borrow_mut().copy_from(&result.inner.borrow()); + self.is_2d.set(result.is_2d.get()); + } + + #[fast] + pub fn pre_multiply_self(&self, other: v8::Local) { + let other = cast_to_matrix(other); + let result = Matrix { + inner: RefCell::new(Matrix4::zeros()), + is_2d: Cell::new(true), + }; + matrix_multiply(&result, &other, self); + self.inner.borrow_mut().copy_from(&result.inner.borrow()); + self.is_2d.set(result.is_2d.get()); + } + + #[cppgc] + pub fn flip_x(&self) -> Matrix { + let out = self.clone(); + matrix_flip_x(&out); + out + } + + #[cppgc] + pub fn flip_y(&self) -> Matrix { + let out = self.clone(); + matrix_flip_y(&out); + out + } + + #[cppgc] + pub fn inverse(&self) -> Matrix { + let out = self.clone(); + matrix_inverse(&out); + out + } + + #[fast] + pub fn invert_self(&self) { + matrix_inverse(self); + } + + #[cppgc] + pub fn transformPoint(&self, point: v8::Local) -> Point { + let point = cast_to_point(point); + let out = Point { + x: Cell::new(0.0), + y: Cell::new(0.0), + z: Cell::new(0.0), + w: Cell::new(0.0), + }; + matrix_transform_point(self, &point, &out); + out + } +} + +#[op2] +pub fn op_create_matrix_identity<'a>( + scope: &mut v8::HandleScope<'a>, +) -> v8::Local<'a, v8::Object> { + cppgc::make_cppgc_object( + scope, + Matrix { + inner: RefCell::new(Matrix4::identity()), + is_2d: Cell::new(true), + }, + ) +} + +fn cast_to_point(obj: v8::Local<'_, v8::Object>) -> v8::Local<'_, Point> { + // SAFETY: cast v8::Local + unsafe { mem::transmute(obj) } +} + +fn cast_to_matrix(obj: v8::Local<'_, v8::Object>) -> v8::Local<'_, Matrix> { + // SAFETY: cast v8::Local + unsafe { mem::transmute(obj) } +} + +#[inline] +fn matrix_translate(matrix: &Matrix, tx: f64, ty: f64, tz: f64) { + let mut inner = matrix.inner.borrow_mut(); + let is_2d = matrix.is_2d.get(); + let shift = Vector3::new(tx, ty, tz); + inner.prepend_translation_mut(&shift); + matrix.is_2d.set(is_2d && tz == 0.0); +} + +#[inline] +fn matrix_scale(matrix: &Matrix, sx: f64, sy: f64, sz: f64) { + let mut inner = matrix.inner.borrow_mut(); + let is_2d = matrix.is_2d.get(); + let scaling = Vector3::new(sx, sy, sz); + inner.prepend_nonuniform_scaling_mut(&scaling); + matrix.is_2d.set(is_2d && sz == 0.0); +} + +#[inline] +fn matrix_scale_with_origin( + matrix: &Matrix, + sx: f64, + sy: f64, + sz: f64, origin_x: f64, origin_y: f64, origin_z: f64, - #[buffer] inout: &mut [f64], ) { - let scaling = Vector3::new(x, y, z); + let mut inner = matrix.inner.borrow_mut(); + let is_2d = matrix.is_2d.get(); + let scaling = Vector3::new(sx, sy, sz); let mut shift = Vector3::new(origin_x, origin_y, origin_z); - let mut inout = MatrixViewMut4::from_slice(inout); - inout.prepend_translation_mut(&shift); - inout.prepend_nonuniform_scaling_mut(&scaling); + inner.prepend_translation_mut(&shift); + inner.prepend_nonuniform_scaling_mut(&scaling); shift.neg_mut(); - inout.prepend_translation_mut(&shift); + inner.prepend_translation_mut(&shift); + matrix.is_2d.set(is_2d && sz == 0.0 && origin_z == 0.0); } -#[op2(fast)] -pub fn op_geometry_rotate_self( - roll_degrees: f64, - pitch_degrees: f64, - yaw_degrees: f64, - #[buffer] inout: &mut [f64], -) { +#[inline] +fn matrix_rotate(matrix: &Matrix, roll_deg: f64, pitch_deg: f64, yaw_deg: f64) { + let mut inner = matrix.inner.borrow_mut(); + let is_2d = matrix.is_2d.get(); let rotation = Rotation3::from_euler_angles( - roll_degrees.to_radians(), - pitch_degrees.to_radians(), - yaw_degrees.to_radians(), + roll_deg.to_radians(), + pitch_deg.to_radians(), + yaw_deg.to_radians(), ) .to_homogeneous(); - let mut inout = MatrixViewMut4::from_slice(inout); let mut result = Matrix4x3::zeros(); - inout.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); - inout.set_column(0, &result.column(0)); - inout.set_column(1, &result.column(1)); - inout.set_column(2, &result.column(2)); + inner.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); + inner.set_column(0, &result.column(0)); + inner.set_column(1, &result.column(1)); + inner.set_column(2, &result.column(2)); + matrix + .is_2d + .set(is_2d && pitch_deg == 0.0 && yaw_deg == 0.0); } -#[op2(fast)] -pub fn op_geometry_rotate_from_vector_self( - x: f64, - y: f64, - #[buffer] inout: &mut [f64], -) { +#[inline] +fn matrix_rotate_from_vector(matrix: &Matrix, x: f64, y: f64) { + let mut inner = matrix.inner.borrow_mut(); let rotation = Rotation3::from_axis_angle(&Vector3::z_axis(), y.atan2(x)).to_homogeneous(); - let mut inout = MatrixViewMut4::from_slice(inout); let mut result = Matrix4x3::zeros(); - inout.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); - inout.set_column(0, &result.column(0)); - inout.set_column(1, &result.column(1)); - inout.set_column(2, &result.column(2)); + inner.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); + inner.set_column(0, &result.column(0)); + inner.set_column(1, &result.column(1)); + inner.set_column(2, &result.column(2)); } -#[op2(fast)] -pub fn op_geometry_rotate_axis_angle_self( +#[inline] +fn matrix_rotate_axis_angle( + matrix: &Matrix, x: f64, y: f64, z: f64, - angle_degrees: f64, - #[buffer] inout: &mut [f64], + angle_deg: f64, ) { + let mut inner = matrix.inner.borrow_mut(); + let is_2d = matrix.is_2d.get(); let rotation = Rotation3::from_axis_angle( &UnitVector3::new_normalize(Vector3::new(x, y, z)), - angle_degrees.to_radians(), + angle_deg.to_radians(), ) .to_homogeneous(); - let mut inout = MatrixViewMut4::from_slice(inout); let mut result = Matrix4x3::zeros(); - inout.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); - inout.set_column(0, &result.column(0)); - inout.set_column(1, &result.column(1)); - inout.set_column(2, &result.column(2)); + inner.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); + inner.set_column(0, &result.column(0)); + inner.set_column(1, &result.column(1)); + inner.set_column(2, &result.column(2)); + matrix.is_2d.set(is_2d && x == 0.0 && y == 0.0); } -#[op2(fast)] -pub fn op_geometry_skew_self( - x_degrees: f64, - y_degrees: f64, - #[buffer] inout: &mut [f64], -) { - let skew = Matrix4x2::new( - 1.0, - x_degrees.to_radians().tan(), - y_degrees.to_radians().tan(), - 1.0, - 0.0, - 0.0, - 0.0, - 0.0, - ); - let mut inout = MatrixViewMut4::from_slice(inout); +#[inline] +fn matrix_skew_x(matrix: &Matrix, x_deg: f64) { + let mut inner = matrix.inner.borrow_mut(); + let skew = + Matrix4x2::new(1.0, x_deg.to_radians().tan(), 0.0, 1.0, 0.0, 0.0, 0.0, 0.0); let mut result = Matrix4x2::zeros(); - inout.mul_to(&skew, &mut result); - inout.set_column(0, &result.column(0)); - inout.set_column(1, &result.column(1)); -} - -#[op2(fast)] -pub fn op_geometry_multiply( - #[buffer] lhs: &[f64], - #[buffer] rhs: &[f64], - #[buffer] out: &mut [f64], -) { - let lhs = MatrixView4::from_slice(lhs); - let rhs = MatrixView4::from_slice(rhs); - let mut out = MatrixViewMut4::from_slice(out); - lhs.mul_to(&rhs, &mut out); + inner.mul_to(&skew, &mut result); + inner.set_column(0, &result.column(0)); + inner.set_column(1, &result.column(1)); } -#[op2(fast)] -pub fn op_geometry_multiply_self( - #[buffer] rhs: &[f64], - #[buffer] inout: &mut [f64], -) { - let rhs = MatrixView4::from_slice(rhs); - let mut inout = MatrixViewMut4::from_slice(inout); - let mut result = Matrix4::zeros(); - inout.mul_to(&rhs, &mut result); - inout.copy_from(&result); +#[inline] +fn matrix_skew_y(matrix: &Matrix, y_deg: f64) { + let mut inner = matrix.inner.borrow_mut(); + let skew = + Matrix4x2::new(1.0, 0.0, y_deg.to_radians().tan(), 1.0, 0.0, 0.0, 0.0, 0.0); + let mut result = Matrix4x2::zeros(); + inner.mul_to(&skew, &mut result); + inner.set_column(0, &result.column(0)); + inner.set_column(1, &result.column(1)); } -#[op2(fast)] -pub fn op_geometry_premultiply_self( - #[buffer] lhs: &[f64], - #[buffer] inout: &mut [f64], -) { - let lhs = MatrixView4::from_slice(lhs); - let mut inout = MatrixViewMut4::from_slice(inout); +#[inline] +fn matrix_multiply(out: &Matrix, lhs: &Matrix, rhs: &Matrix) { + let lhs_inner = lhs.inner.borrow(); + let lhs_is_2d = lhs.is_2d.get(); + let rhs_inner = rhs.inner.borrow(); + let rhs_is_2d = rhs.is_2d.get(); + let mut out_inner = out.inner.borrow_mut(); let mut result = Matrix4::zeros(); - lhs.mul_to(&inout, &mut result); - inout.copy_from(&result); + lhs_inner.mul_to(&rhs_inner, &mut result); + out_inner.copy_from(&result); + out.is_2d.set(lhs_is_2d && rhs_is_2d); } -#[op2(fast)] -pub fn op_geometry_flip_x_self(#[buffer] inout: &mut [f64]) { - let mut inout = MatrixViewMut4::from_slice(inout); - inout.column_mut(0).neg_mut(); +#[inline] +fn matrix_flip_x(matrix: &Matrix) { + let mut inner = matrix.inner.borrow_mut(); + inner.column_mut(0).neg_mut(); } -#[op2(fast)] -pub fn op_geometry_flip_y_self(#[buffer] inout: &mut [f64]) { - let mut inout = MatrixViewMut4::from_slice(inout); - inout.column_mut(1).neg_mut(); +#[inline] +fn matrix_flip_y(matrix: &Matrix) { + let mut inner = matrix.inner.borrow_mut(); + inner.column_mut(1).neg_mut(); } -#[op2(fast)] -pub fn op_geometry_invert_self(#[buffer] inout: &mut [f64]) -> bool { - if inout.iter().any(|&x| x.is_infinite()) { - inout.fill(f64::NAN); - return false; +#[inline] +fn matrix_inverse(matrix: &Matrix) { + let mut inner = matrix.inner.borrow_mut(); + let is_2d = matrix.is_2d.get(); + if inner.iter().any(|&x| x.is_infinite()) { + inner.fill(f64::NAN); + matrix.is_2d.set(false); + return; } - - let mut inout = MatrixViewMut4::from_slice(inout); - if !inout.try_inverse_mut() { - inout.fill(f64::NAN); - return false; + if is_2d { + // SAFETY: in-range access + let mut matrix3 = unsafe { + Matrix3::new( + *inner.get_unchecked(0), + *inner.get_unchecked(4), + *inner.get_unchecked(12), + *inner.get_unchecked(1), + *inner.get_unchecked(5), + *inner.get_unchecked(13), + 0.0, + 0.0, + 1.0, + ) + }; + if !matrix3.try_inverse_mut() { + inner.fill(f64::NAN); + matrix.is_2d.set(false); + return; + } + // SAFETY: in-range access + unsafe { + *inner.get_unchecked_mut(0) = *matrix3.get_unchecked(0); + *inner.get_unchecked_mut(1) = *matrix3.get_unchecked(1); + *inner.get_unchecked_mut(4) = *matrix3.get_unchecked(3); + *inner.get_unchecked_mut(5) = *matrix3.get_unchecked(4); + *inner.get_unchecked_mut(12) = *matrix3.get_unchecked(6); + *inner.get_unchecked_mut(13) = *matrix3.get_unchecked(7); + } + } else if !inner.try_inverse_mut() { + inner.fill(f64::NAN); } - - true } -#[op2(fast)] -pub fn op_geometry_invert_2d_self(#[buffer] inout: &mut [f64]) -> bool { - if inout.iter().any(|&x| x.is_infinite()) { - inout.fill(f64::NAN); - return false; - } - - let mut matrix = Matrix3::new( - inout[0], inout[4], inout[12], inout[1], inout[5], inout[13], 0.0, 0.0, 1.0, - ); - if !matrix.try_inverse_mut() { - inout.fill(f64::NAN); - return false; - } - - let matrix = matrix.as_slice(); - inout[0] = matrix[0]; - inout[1] = matrix[1]; - inout[4] = matrix[3]; - inout[5] = matrix[4]; - inout[12] = matrix[6]; - inout[13] = matrix[7]; - - true -} - -#[op2(fast)] -pub fn op_geometry_premultiply_point_self( - #[buffer] lhs: &[f64], - #[buffer] inout: &mut [f64], -) { - let lhs = MatrixView4::from_slice(lhs); - let mut inout = VectorViewMut4::from_slice(inout); +fn matrix_transform_point(matrix: &Matrix, point: &Point, out: &Point) { + let inner = matrix.inner.borrow(); + let point = + Vector4::new(point.x.get(), point.y.get(), point.z.get(), point.w.get()); let mut result = Vector4::zeros(); - lhs.mul_to(&inout, &mut result); - inout.copy_from(&result); + inner.mul_to(&point, &mut result); + out.x.set(result.x); + out.y.set(result.y); + out.z.set(result.z); + out.w.set(result.w); } diff --git a/tests/unit/geometry_test.ts b/tests/unit/geometry_test.ts index b4910c3e6f5ec6..37ae864411dd77 100644 --- a/tests/unit/geometry_test.ts +++ b/tests/unit/geometry_test.ts @@ -1,4 +1,4 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2025 the Deno authors. MIT license. import { assertAlmostEquals, assertEquals, From 4d3ff7fb0682e0be25a65ba1dce7fbca3d8618f6 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 3 Jan 2025 00:06:07 +0900 Subject: [PATCH 03/63] fix lib.deno_geometry.d.ts --- ext/geometry/lib.deno_geometry.d.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/ext/geometry/lib.deno_geometry.d.ts b/ext/geometry/lib.deno_geometry.d.ts index 3868044319bbc7..800993ee4f3976 100644 --- a/ext/geometry/lib.deno_geometry.d.ts +++ b/ext/geometry/lib.deno_geometry.d.ts @@ -6,7 +6,7 @@ /// /** @category Geometry Interfaces Module API */ -declare interface DOMMatrix2DInit { +interface DOMMatrix2DInit { a?: number; b?: number; c?: number; @@ -22,7 +22,7 @@ declare interface DOMMatrix2DInit { } /** @category Geometry Interfaces Module API */ -declare interface DOMMatrixInit extends DOMMatrix2DInit { +interface DOMMatrixInit extends DOMMatrix2DInit { is2D?: boolean; m13?: number; m14?: number; @@ -49,7 +49,7 @@ declare interface DOMMatrixInit extends DOMMatrix2DInit { * * @category Geometry Interfaces Module API */ -declare interface DOMMatrix extends DOMMatrixReadOnly { +interface DOMMatrix extends DOMMatrixReadOnly { a: number; b: number; c: number; @@ -227,7 +227,7 @@ declare var DOMMatrix: { * * @category Geometry Interfaces Module API */ -declare interface DOMMatrixReadOnly { +interface DOMMatrixReadOnly { readonly a: number; readonly b: number; readonly c: number; @@ -418,7 +418,7 @@ declare var DOMMatrixReadOnly: { }; /** @category Geometry Interfaces Module API */ -declare interface DOMPointInit { +interface DOMPointInit { w?: number; x?: number; y?: number; @@ -431,7 +431,7 @@ declare interface DOMPointInit { * * @category Geometry Interfaces Module API */ -declare interface DOMPoint extends DOMPointReadOnly { +interface DOMPoint extends DOMPointReadOnly { w: number; x: number; y: number; @@ -456,7 +456,7 @@ declare var DOMPoint: { * * @category Geometry Interfaces Module API */ -declare interface DOMPointReadOnly { +interface DOMPointReadOnly { readonly w: number; readonly x: number; readonly y: number; @@ -483,7 +483,7 @@ declare var DOMPointReadOnly: { }; /** @category Geometry Interfaces Module API */ -declare interface DOMQuadInit { +interface DOMQuadInit { p1?: DOMPointInit; p2?: DOMPointInit; p3?: DOMPointInit; @@ -496,7 +496,7 @@ declare interface DOMQuadInit { * * @category Geometry Interfaces Module API */ -declare interface DOMQuad { +interface DOMQuad { readonly p1: DOMPoint; readonly p2: DOMPoint; readonly p3: DOMPoint; @@ -529,7 +529,7 @@ declare var DOMQuad: { }; /** @category Geometry Interfaces Module API */ -declare interface DOMRectInit { +interface DOMRectInit { height?: number; width?: number; x?: number; @@ -541,7 +541,7 @@ declare interface DOMRectInit { * * @category Geometry Interfaces Module API */ -declare interface DOMRect extends DOMRectReadOnly { +interface DOMRect extends DOMRectReadOnly { height: number; width: number; x: number; @@ -564,7 +564,7 @@ declare var DOMRect: { * * @category Geometry Interfaces Module API */ -declare interface DOMRectReadOnly { +interface DOMRectReadOnly { readonly bottom: number; readonly height: number; readonly left: number; From efe2b0feb5c841a726f712d9cf6ac99fce01378f Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 3 Jan 2025 18:44:54 +0900 Subject: [PATCH 04/63] fix --- ext/geometry/01_geometry.js | 127 +++++++++++++++++++++++++------- ext/geometry/README.md | 8 +- ext/geometry/lib.rs | 142 ++++++++++++++++++++++-------------- 3 files changed, 192 insertions(+), 85 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 4a9595d85769e0..e6b421d491d915 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -1,7 +1,12 @@ // Copyright 2018-2025 the Deno authors. MIT license. import { primordials } from "ext:core/mod.js"; -import { Matrix, op_create_matrix_identity, Point, Rect } from "ext:core/ops"; +import { + DOMMatrixInner, + DOMPointInner, + DOMRectInner, + op_geometry_create_matrix_identity, +} from "ext:core/ops"; const { ArrayPrototypeJoin, Float32Array, @@ -226,7 +231,7 @@ class DOMPointReadOnly { [_inner]; constructor(x = 0, y = 0, z = 0, w = 1) { - this[_inner] = new Point( + this[_inner] = new DOMPointInner( webidl.converters["unrestricted double"](x), webidl.converters["unrestricted double"](y), webidl.converters["unrestricted double"](z), @@ -243,7 +248,7 @@ class DOMPointReadOnly { ); const point = webidl.createBranded(DOMPointReadOnly); point[_writable] = false; - point[_inner] = new Point( + point[_inner] = new DOMPointInner( other.x, other.y, other.z, @@ -256,14 +261,17 @@ class DOMPointReadOnly { webidl.assertBranded(this, DOMPointReadOnlyPrototype); return this[_inner].x; } + get y() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); return this[_inner].y; } + get z() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); return this[_inner].z; } + get w() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); return this[_inner].w; @@ -273,7 +281,7 @@ class DOMPointReadOnly { webidl.assertBranded(this, DOMPointReadOnlyPrototype); const prefix = "Failed to execute 'matrixTransform' on 'DOMPointReadOnly'"; if ( - other === null || + matrix === null || !ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, matrix) ) { const _matrix = webidl.converters.DOMMatrixInit( @@ -333,7 +341,7 @@ class DOMPoint extends DOMPointReadOnly { ); const point = webidl.createBranded(DOMPoint); point[_writable] = true; - point[_inner] = new Point( + point[_inner] = new DOMPointInner( other.x, other.y, other.z, @@ -351,6 +359,7 @@ class DOMPoint extends DOMPointReadOnly { assertWritable(this); this[_inner].x = webidl.converters["unrestricted double"](value); } + get y() { webidl.assertBranded(this, DOMPointPrototype); return this[_inner].y; @@ -360,6 +369,7 @@ class DOMPoint extends DOMPointReadOnly { assertWritable(this); this[_inner].y = webidl.converters["unrestricted double"](value); } + get z() { webidl.assertBranded(this, DOMPointPrototype); return this[_inner].x; @@ -369,6 +379,7 @@ class DOMPoint extends DOMPointReadOnly { assertWritable(this); this[_inner].z = webidl.converters["unrestricted double"](value); } + get w() { webidl.assertBranded(this, DOMPointPrototype); return this[_inner].w; @@ -404,7 +415,7 @@ class DOMRectReadOnly { [_inner]; constructor(x = 0, y = 0, width = 0, height = 0) { - this[_inner] = new Rect( + this[_inner] = new DOMRectInner( webidl.converters["unrestricted double"](x), webidl.converters["unrestricted double"](y), webidl.converters["unrestricted double"](width), @@ -421,7 +432,7 @@ class DOMRectReadOnly { ); const rect = webidl.createBranded(DOMRectReadOnly); rect[_writable] = false; - rect[_inner] = new Rect( + rect[_inner] = new DOMRectInner( other.x, other.y, other.width, @@ -434,33 +445,40 @@ class DOMRectReadOnly { webidl.assertBranded(this, DOMRectReadOnlyPrototype); return this[_inner].x; } + get y() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); return this[_inner].y; } + get width() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); return this[_inner].width; } + get height() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); return this[_inner].height; } + get top() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); const { y, height } = this[_inner]; return MathMin(y, y + height); } + get right() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); const { x, width } = this[_inner]; return MathMax(x, x + width); } + get bottom() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); const { y, height } = this[_inner]; return MathMax(y, y + height); } + get left() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); const { x, width } = this[_inner]; @@ -517,7 +535,7 @@ class DOMRect extends DOMRectReadOnly { ); const rect = webidl.createBranded(DOMRect); rect[_writable] = true; - rect[_inner] = new Rect( + rect[_inner] = new DOMRectInner( other.x, other.y, other.width, @@ -535,6 +553,7 @@ class DOMRect extends DOMRectReadOnly { assertWritable(this); this[_inner].x = webidl.converters["unrestricted double"](value); } + get y() { webidl.assertBranded(this, DOMRectPrototype); return this[_inner].y; @@ -544,6 +563,7 @@ class DOMRect extends DOMRectReadOnly { assertWritable(this); this[_inner].y = webidl.converters["unrestricted double"](value); } + get width() { webidl.assertBranded(this, DOMRectPrototype); return this[_inner].width; @@ -553,6 +573,7 @@ class DOMRect extends DOMRectReadOnly { assertWritable(this); this[_inner].width = webidl.converters["unrestricted double"](value); } + get height() { webidl.assertBranded(this, DOMRectPrototype); return this[_inner].height; @@ -648,14 +669,17 @@ class DOMQuad { webidl.assertBranded(this, DOMQuadPrototype); return this[_p1]; } + get p2() { webidl.assertBranded(this, DOMQuadPrototype); return this[_p2]; } + get p3() { webidl.assertBranded(this, DOMQuadPrototype); return this[_p3]; } + get p4() { webidl.assertBranded(this, DOMQuadPrototype); return this[_p4]; @@ -675,7 +699,7 @@ class DOMQuad { const bounds = webidl.createBranded(DOMRect); bounds[_writable] = true; - bounds[_inner] = new Rect( + bounds[_inner] = new DOMRectInner( left, top, right - left, @@ -722,7 +746,7 @@ class DOMMatrixReadOnly { const prefix = `Failed to construct '${this.constructor.name}'`; this[_brand] = _brand; if (init === undefined) { - this[_inner] = op_create_matrix_identity(); + this[_inner] = op_geometry_create_matrix_identity(); } else if ( webidl.type(init) === "Object" && init[SymbolIterator] !== undefined ) { @@ -739,7 +763,7 @@ class DOMMatrixReadOnly { "Argument 1", ); const { matrix, is2D } = parseTransformList(init, prefix); - this[_inner] = new Matrix(matrix, is2D); + this[_inner] = new DOMMatrixInner(matrix, is2D); } } @@ -785,94 +809,117 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].a; } + get b() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].b; } + get c() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].c; } + get d() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].d; } + get e() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].e; } + get f() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].f; } + get m11() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m11; } + get m12() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m12; } + get m13() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m13; } + get m14() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m14; } + get m21() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m21; } + get m22() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m22; } + get m23() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m23; } + get m24() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m24; } + get m31() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m31; } + get m32() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m32; } + get m33() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m33; } + get m34() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m34; } + get m41() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m41; } + get m42() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m42; } + get m43() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m43; } + get m44() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m44; } + get is2D() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].is2D; } + get isIdentity() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].isIdentity; @@ -907,7 +954,11 @@ class DOMMatrixReadOnly { const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; if (originX === 0 && originY === 0 && originZ === 0) { - matrix[_inner] = this[_inner].clone().scale(scaleX, scaleY, scaleZ); + matrix[_inner] = this[_inner].clone().scaleWithoutOrigin( + scaleX, + scaleY, + scaleZ, + ); } else { matrix[_inner] = this[_inner].clone().scaleWithOrigin( scaleX, @@ -927,7 +978,7 @@ class DOMMatrixReadOnly { scaleY = webidl.converters["unrestricted double"](scaleY); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().scale( + matrix[_inner] = this[_inner].clone().scaleWithoutOrigin( scaleX, scaleY, 1, @@ -1079,7 +1130,7 @@ class DOMMatrixReadOnly { transformPoint(point = { __proto__: null }) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); if ( - other === null || + point === null || !ObjectPrototypeIsPrototypeOf(DOMPointReadOnlyPrototype, point) ) { const _point = webidl.converters.DOMPointInit( @@ -1088,7 +1139,7 @@ class DOMMatrixReadOnly { "Argument 1", ); point = { - [_inner]: new Point( + [_inner]: new DOMPointInner( _point.x, _point.y, _point.z, @@ -1240,6 +1291,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].a = webidl.converters["unrestricted double"](value); } + get b() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].b; @@ -1249,6 +1301,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].b = webidl.converters["unrestricted double"](value); } + get c() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].c; @@ -1258,6 +1311,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].c = webidl.converters["unrestricted double"](value); } + get d() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].d; @@ -1267,6 +1321,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].d = webidl.converters["unrestricted double"](value); } + get e() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].e; @@ -1276,6 +1331,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].e = webidl.converters["unrestricted double"](value); } + get f() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].f; @@ -1285,6 +1341,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].f = webidl.converters["unrestricted double"](value); } + get m11() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m11; @@ -1294,6 +1351,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m11 = webidl.converters["unrestricted double"](value); } + get m12() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m12; @@ -1303,6 +1361,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m12 = webidl.converters["unrestricted double"](value); } + get m13() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m13; @@ -1312,6 +1371,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m13 = webidl.converters["unrestricted double"](value); } + get m14() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m14; @@ -1321,6 +1381,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m14 = webidl.converters["unrestricted double"](value); } + get m21() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m21; @@ -1330,6 +1391,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m21 = webidl.converters["unrestricted double"](value); } + get m22() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m22; @@ -1339,6 +1401,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m22 = webidl.converters["unrestricted double"](value); } + get m23() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m23; @@ -1348,6 +1411,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m23 = webidl.converters["unrestricted double"](value); } + get m24() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m24; @@ -1357,6 +1421,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m24 = webidl.converters["unrestricted double"](value); } + get m31() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m31; @@ -1366,6 +1431,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m31 = webidl.converters["unrestricted double"](value); } + get m32() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m32; @@ -1375,6 +1441,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m32 = webidl.converters["unrestricted double"](value); } + get m33() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m33; @@ -1384,6 +1451,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m33 = webidl.converters["unrestricted double"](value); } + get m34() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m34; @@ -1393,6 +1461,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m34 = webidl.converters["unrestricted double"](value); } + get m41() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m41; @@ -1402,6 +1471,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m41 = webidl.converters["unrestricted double"](value); } + get m42() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m42; @@ -1411,6 +1481,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m42 = webidl.converters["unrestricted double"](value); } + get m43() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m43; @@ -1420,6 +1491,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m43 = webidl.converters["unrestricted double"](value); } + get m44() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m44; @@ -1478,7 +1550,7 @@ class DOMMatrix extends DOMMatrixReadOnly { tx = webidl.converters["unrestricted double"](tx); ty = webidl.converters["unrestricted double"](ty); tz = webidl.converters["unrestricted double"](tz); - this[_inner].translate(tx, ty, tz); + this[_inner].translateSelf(tx, ty, tz); return this; } @@ -1499,9 +1571,9 @@ class DOMMatrix extends DOMMatrixReadOnly { originY = webidl.converters["unrestricted double"](originY); originZ = webidl.converters["unrestricted double"](originZ); if (originX === 0 && originY === 0 && originZ === 0) { - this[_inner].scale(scaleX, scaleY, scaleZ); + this[_inner].scaleWithoutOriginSelf(scaleX, scaleY, scaleZ); } else { - this[_inner].scaleWithOrigin( + this[_inner].scaleWithOriginSelf( scaleX, scaleY, scaleZ, @@ -1521,9 +1593,9 @@ class DOMMatrix extends DOMMatrixReadOnly { originY = webidl.converters["unrestricted double"](originY); originZ = webidl.converters["unrestricted double"](originZ); if (originX === 0 && originY === 0 && originZ === 0) { - this[_inner].scale(scale, scale, scale); + this[_inner].scaleWithoutOriginSelf(scale, scale, scale); } else { - this[_inner].scaleWithOrigin( + this[_inner].scaleWithOriginSelf( scale, scale, scale, @@ -1605,7 +1677,7 @@ class DOMMatrix extends DOMMatrixReadOnly { invertSelf() { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].inverse(); + this[_inner].invertSelf(); return this; } @@ -1746,14 +1818,17 @@ function initMatrixFromSequence(target, seq, prefix) { if (seq.length === 6) { const { 0: a, 1: b, 2: c, 3: d, 4: e, 5: f } = seq; // deno-fmt-ignore - target[_inner] = new Matrix(new Float64Array([ + target[_inner] = new DOMMatrixInner(new Float64Array([ a, b, 0, 0, c, d, 0, 0, 0, 0, 1, 0, e, f, 0, 1, ]), /* is2D */ true); } else if (seq.length === 16) { - target[_inner] = new Matrix(new Float64Array(seq), /* is2D */ false); + target[_inner] = new DOMMatrixInner( + new Float64Array(seq), + /* is2D */ false, + ); } else { throw new TypeError( `${prefix}: The sequence must contain 6 elements for a 2D matrix or 16 elements for a 3D matrix`, @@ -1769,7 +1844,7 @@ function initMatrixFromDictonary(target, dict) { if (dict.is2D) { const { m11, m12, m21, m22, m41, m42 } = dict; // deno-fmt-ignore - target[_inner] = new Matrix(new Float64Array([ + target[_inner] = new DOMMatrixInner(new Float64Array([ m11, m12, 0, 0, m21, m22, 0, 0, 0, 0, 1, 0, @@ -1784,7 +1859,7 @@ function initMatrixFromDictonary(target, dict) { m41, m42, m43, m44, } = dict; // deno-fmt-ignore - target[_inner] = new Matrix(new Float64Array([ + target[_inner] = new DOMMatrixInner(new Float64Array([ m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, @@ -1854,7 +1929,7 @@ function init(transformListParser, enableWindowFeatures) { "Argument 1", ); const { matrix, is2D } = parseTransformList(transformList, prefix); - this[_inner] = new Matrix(matrix, is2D); + this[_inner] = new DOMMatrixInner(matrix, is2D); }, writable: true, enumerable: true, diff --git a/ext/geometry/README.md b/ext/geometry/README.md index 3d5ad3ce4f60a1..7e10bfeecd4a1a 100644 --- a/ext/geometry/README.md +++ b/ext/geometry/README.md @@ -92,7 +92,7 @@ the `extensions` field of your `RuntimeOptions` Following ops are provided, which can be accessed through `Deno.ops`: -- op_create_matrix_identity -- Matrix -- Point -- Rect +- op_geometry_create_matrix_identity +- DOMMatrixInner +- DOMPointInner +- DOMRectInner diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index cd7bd76c1e02d3..2fd8c897473430 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -22,8 +22,8 @@ use nalgebra::Vector4; deno_core::extension!( deno_geometry, deps = [deno_webidl, deno_web, deno_console], - ops = [op_create_matrix_identity], - objects = [Point, Rect, Matrix], + ops = [op_geometry_create_matrix_identity], + objects = [DOMPointInner, DOMRectInner, DOMMatrixInner], esm = ["00_init.js"], lazy_loaded_esm = ["01_geometry.js"], ); @@ -32,21 +32,21 @@ pub fn get_declaration() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_geometry.d.ts") } -pub struct Point { +pub struct DOMPointInner { x: Cell, y: Cell, z: Cell, w: Cell, } -impl GarbageCollected for Point {} +impl GarbageCollected for DOMPointInner {} #[op2] -impl Point { +impl DOMPointInner { #[constructor] #[cppgc] - pub fn constructor(x: f64, y: f64, z: f64, w: f64) -> Point { - Point { + pub fn constructor(x: f64, y: f64, z: f64, w: f64) -> DOMPointInner { + DOMPointInner { x: Cell::new(x), y: Cell::new(y), z: Cell::new(z), @@ -103,9 +103,12 @@ impl Point { } #[cppgc] - pub fn matrixTransform(&self, matrix: v8::Local) -> Point { + pub fn matrix_transform( + &self, + matrix: v8::Local, + ) -> DOMPointInner { let matrix = cast_to_matrix(matrix); - let out = Point { + let out = DOMPointInner { x: Cell::new(0.0), y: Cell::new(0.0), z: Cell::new(0.0), @@ -116,21 +119,21 @@ impl Point { } } -pub struct Rect { +pub struct DOMRectInner { x: Cell, y: Cell, width: Cell, height: Cell, } -impl GarbageCollected for Rect {} +impl GarbageCollected for DOMRectInner {} #[op2] -impl Rect { +impl DOMRectInner { #[constructor] #[cppgc] - pub fn constructor(x: f64, y: f64, width: f64, height: f64) -> Rect { - Rect { + pub fn constructor(x: f64, y: f64, width: f64, height: f64) -> DOMRectInner { + DOMRectInner { x: Cell::new(x), y: Cell::new(y), width: Cell::new(width), @@ -188,12 +191,12 @@ impl Rect { } #[derive(Clone)] -pub struct Matrix { +pub struct DOMMatrixInner { inner: RefCell>, is_2d: Cell, } -impl GarbageCollected for Matrix {} +impl GarbageCollected for DOMMatrixInner {} /* * NOTE: column-major order @@ -238,18 +241,18 @@ const INDEX_M43: usize = 14; const INDEX_M44: usize = 15; #[op2] -impl Matrix { +impl DOMMatrixInner { #[constructor] #[cppgc] - pub fn constructor(#[buffer] buffer: &[f64], is_2d: bool) -> Matrix { - Matrix { + pub fn constructor(#[buffer] buffer: &[f64], is_2d: bool) -> DOMMatrixInner { + DOMMatrixInner { inner: RefCell::new(Matrix4::from_column_slice(buffer)), is_2d: Cell::new(is_2d), } } #[cppgc] - pub fn clone(&self) -> Matrix { + pub fn clone(&self) -> DOMMatrixInner { self.clone() } @@ -689,7 +692,7 @@ impl Matrix { } #[cppgc] - pub fn translate(&self, tx: f64, ty: f64, tz: f64) -> Matrix { + pub fn translate(&self, tx: f64, ty: f64, tz: f64) -> DOMMatrixInner { let out = self.clone(); matrix_translate(&out, tx, ty, tz); out @@ -701,14 +704,19 @@ impl Matrix { } #[cppgc] - pub fn scale(&self, sx: f64, sy: f64, sz: f64) -> Matrix { + pub fn scale_without_origin( + &self, + sx: f64, + sy: f64, + sz: f64, + ) -> DOMMatrixInner { let out = self.clone(); matrix_scale(&out, sx, sy, sz); out } #[fast] - pub fn scale_self(&self, sx: f64, sy: f64, sz: f64) { + pub fn scale_without_origin_self(&self, sx: f64, sy: f64, sz: f64) { matrix_scale(self, sx, sy, sz); } @@ -721,7 +729,7 @@ impl Matrix { origin_x: f64, origin_y: f64, origin_z: f64, - ) -> Matrix { + ) -> DOMMatrixInner { let out = self.clone(); matrix_scale_with_origin(&out, sx, sy, sz, origin_x, origin_y, origin_z); out @@ -741,7 +749,12 @@ impl Matrix { } #[cppgc] - pub fn rotate(&self, roll_deg: f64, pitch_deg: f64, yaw_deg: f64) -> Matrix { + pub fn rotate( + &self, + roll_deg: f64, + pitch_deg: f64, + yaw_deg: f64, + ) -> DOMMatrixInner { let out = self.clone(); matrix_rotate(&out, roll_deg, pitch_deg, yaw_deg); out @@ -753,7 +766,7 @@ impl Matrix { } #[cppgc] - pub fn rotate_from_vector(&self, x: f64, y: f64) -> Matrix { + pub fn rotate_from_vector(&self, x: f64, y: f64) -> DOMMatrixInner { let out = self.clone(); matrix_rotate_from_vector(&out, x, y); out @@ -771,7 +784,7 @@ impl Matrix { y: f64, z: f64, angle_deg: f64, - ) -> Matrix { + ) -> DOMMatrixInner { let out = self.clone(); matrix_rotate_axis_angle(&out, x, y, z, angle_deg); out @@ -783,7 +796,7 @@ impl Matrix { } #[cppgc] - pub fn skew_x(&self, x_deg: f64) -> Matrix { + pub fn skew_x(&self, x_deg: f64) -> DOMMatrixInner { let out = self.clone(); matrix_skew_x(&out, x_deg); out @@ -795,7 +808,7 @@ impl Matrix { } #[cppgc] - pub fn skew_y(&self, y_deg: f64) -> Matrix { + pub fn skew_y(&self, y_deg: f64) -> DOMMatrixInner { let out = self.clone(); matrix_skew_y(&out, y_deg); out @@ -807,9 +820,9 @@ impl Matrix { } #[cppgc] - pub fn multiply(&self, other: v8::Local) -> Matrix { + pub fn multiply(&self, other: v8::Local) -> DOMMatrixInner { let other = cast_to_matrix(other); - let out = Matrix { + let out = DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), }; @@ -820,7 +833,7 @@ impl Matrix { #[fast] pub fn multiply_self(&self, other: v8::Local) { let other = cast_to_matrix(other); - let result = Matrix { + let result = DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), }; @@ -832,7 +845,7 @@ impl Matrix { #[fast] pub fn pre_multiply_self(&self, other: v8::Local) { let other = cast_to_matrix(other); - let result = Matrix { + let result = DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), }; @@ -842,21 +855,21 @@ impl Matrix { } #[cppgc] - pub fn flip_x(&self) -> Matrix { + pub fn flip_x(&self) -> DOMMatrixInner { let out = self.clone(); matrix_flip_x(&out); out } #[cppgc] - pub fn flip_y(&self) -> Matrix { + pub fn flip_y(&self) -> DOMMatrixInner { let out = self.clone(); matrix_flip_y(&out); out } #[cppgc] - pub fn inverse(&self) -> Matrix { + pub fn inverse(&self) -> DOMMatrixInner { let out = self.clone(); matrix_inverse(&out); out @@ -868,9 +881,9 @@ impl Matrix { } #[cppgc] - pub fn transformPoint(&self, point: v8::Local) -> Point { + pub fn transform_point(&self, point: v8::Local) -> DOMPointInner { let point = cast_to_point(point); - let out = Point { + let out = DOMPointInner { x: Cell::new(0.0), y: Cell::new(0.0), z: Cell::new(0.0), @@ -882,30 +895,36 @@ impl Matrix { } #[op2] -pub fn op_create_matrix_identity<'a>( +pub fn op_geometry_create_matrix_identity<'a>( scope: &mut v8::HandleScope<'a>, ) -> v8::Local<'a, v8::Object> { cppgc::make_cppgc_object( scope, - Matrix { + DOMMatrixInner { inner: RefCell::new(Matrix4::identity()), is_2d: Cell::new(true), }, ) } -fn cast_to_point(obj: v8::Local<'_, v8::Object>) -> v8::Local<'_, Point> { +#[inline] +fn cast_to_point( + obj: v8::Local<'_, v8::Object>, +) -> v8::Local<'_, DOMPointInner> { // SAFETY: cast v8::Local unsafe { mem::transmute(obj) } } -fn cast_to_matrix(obj: v8::Local<'_, v8::Object>) -> v8::Local<'_, Matrix> { +#[inline] +fn cast_to_matrix( + obj: v8::Local<'_, v8::Object>, +) -> v8::Local<'_, DOMMatrixInner> { // SAFETY: cast v8::Local unsafe { mem::transmute(obj) } } #[inline] -fn matrix_translate(matrix: &Matrix, tx: f64, ty: f64, tz: f64) { +fn matrix_translate(matrix: &DOMMatrixInner, tx: f64, ty: f64, tz: f64) { let mut inner = matrix.inner.borrow_mut(); let is_2d = matrix.is_2d.get(); let shift = Vector3::new(tx, ty, tz); @@ -914,7 +933,7 @@ fn matrix_translate(matrix: &Matrix, tx: f64, ty: f64, tz: f64) { } #[inline] -fn matrix_scale(matrix: &Matrix, sx: f64, sy: f64, sz: f64) { +fn matrix_scale(matrix: &DOMMatrixInner, sx: f64, sy: f64, sz: f64) { let mut inner = matrix.inner.borrow_mut(); let is_2d = matrix.is_2d.get(); let scaling = Vector3::new(sx, sy, sz); @@ -924,7 +943,7 @@ fn matrix_scale(matrix: &Matrix, sx: f64, sy: f64, sz: f64) { #[inline] fn matrix_scale_with_origin( - matrix: &Matrix, + matrix: &DOMMatrixInner, sx: f64, sy: f64, sz: f64, @@ -944,7 +963,12 @@ fn matrix_scale_with_origin( } #[inline] -fn matrix_rotate(matrix: &Matrix, roll_deg: f64, pitch_deg: f64, yaw_deg: f64) { +fn matrix_rotate( + matrix: &DOMMatrixInner, + roll_deg: f64, + pitch_deg: f64, + yaw_deg: f64, +) { let mut inner = matrix.inner.borrow_mut(); let is_2d = matrix.is_2d.get(); let rotation = Rotation3::from_euler_angles( @@ -964,7 +988,7 @@ fn matrix_rotate(matrix: &Matrix, roll_deg: f64, pitch_deg: f64, yaw_deg: f64) { } #[inline] -fn matrix_rotate_from_vector(matrix: &Matrix, x: f64, y: f64) { +fn matrix_rotate_from_vector(matrix: &DOMMatrixInner, x: f64, y: f64) { let mut inner = matrix.inner.borrow_mut(); let rotation = Rotation3::from_axis_angle(&Vector3::z_axis(), y.atan2(x)).to_homogeneous(); @@ -977,7 +1001,7 @@ fn matrix_rotate_from_vector(matrix: &Matrix, x: f64, y: f64) { #[inline] fn matrix_rotate_axis_angle( - matrix: &Matrix, + matrix: &DOMMatrixInner, x: f64, y: f64, z: f64, @@ -999,7 +1023,7 @@ fn matrix_rotate_axis_angle( } #[inline] -fn matrix_skew_x(matrix: &Matrix, x_deg: f64) { +fn matrix_skew_x(matrix: &DOMMatrixInner, x_deg: f64) { let mut inner = matrix.inner.borrow_mut(); let skew = Matrix4x2::new(1.0, x_deg.to_radians().tan(), 0.0, 1.0, 0.0, 0.0, 0.0, 0.0); @@ -1010,7 +1034,7 @@ fn matrix_skew_x(matrix: &Matrix, x_deg: f64) { } #[inline] -fn matrix_skew_y(matrix: &Matrix, y_deg: f64) { +fn matrix_skew_y(matrix: &DOMMatrixInner, y_deg: f64) { let mut inner = matrix.inner.borrow_mut(); let skew = Matrix4x2::new(1.0, 0.0, y_deg.to_radians().tan(), 1.0, 0.0, 0.0, 0.0, 0.0); @@ -1021,7 +1045,11 @@ fn matrix_skew_y(matrix: &Matrix, y_deg: f64) { } #[inline] -fn matrix_multiply(out: &Matrix, lhs: &Matrix, rhs: &Matrix) { +fn matrix_multiply( + out: &DOMMatrixInner, + lhs: &DOMMatrixInner, + rhs: &DOMMatrixInner, +) { let lhs_inner = lhs.inner.borrow(); let lhs_is_2d = lhs.is_2d.get(); let rhs_inner = rhs.inner.borrow(); @@ -1034,19 +1062,19 @@ fn matrix_multiply(out: &Matrix, lhs: &Matrix, rhs: &Matrix) { } #[inline] -fn matrix_flip_x(matrix: &Matrix) { +fn matrix_flip_x(matrix: &DOMMatrixInner) { let mut inner = matrix.inner.borrow_mut(); inner.column_mut(0).neg_mut(); } #[inline] -fn matrix_flip_y(matrix: &Matrix) { +fn matrix_flip_y(matrix: &DOMMatrixInner) { let mut inner = matrix.inner.borrow_mut(); inner.column_mut(1).neg_mut(); } #[inline] -fn matrix_inverse(matrix: &Matrix) { +fn matrix_inverse(matrix: &DOMMatrixInner) { let mut inner = matrix.inner.borrow_mut(); let is_2d = matrix.is_2d.get(); if inner.iter().any(|&x| x.is_infinite()) { @@ -1088,7 +1116,11 @@ fn matrix_inverse(matrix: &Matrix) { } } -fn matrix_transform_point(matrix: &Matrix, point: &Point, out: &Point) { +fn matrix_transform_point( + matrix: &DOMMatrixInner, + point: &DOMPointInner, + out: &DOMPointInner, +) { let inner = matrix.inner.borrow(); let point = Vector4::new(point.x.get(), point.y.get(), point.z.get(), point.w.get()); From 73959f52f7a1c684d63eb9be234385b966df170e Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 5 Jan 2025 01:51:33 +0900 Subject: [PATCH 05/63] migrate DOMPointInit to ext/geometry/lib.rs --- Cargo.lock | 18 ++++++++++-------- Cargo.toml | 2 +- ext/geometry/01_geometry.js | 24 ++---------------------- ext/geometry/lib.rs | 25 +++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef2955de3a89dc..83ea7500817703 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1535,9 +1535,9 @@ dependencies = [ [[package]] name = "deno_core" -version = "0.327.0" +version = "0.328.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf8dff204b9c2415deb47b9f30d4d38b0925d0d88f1f9074e8e76f59e6d7ded" +checksum = "f2cfbe655223c33ed41ad3a4d8527ad2f69da9192d411273ff27083356f7b3ba" dependencies = [ "anyhow", "az", @@ -1763,6 +1763,7 @@ version = "0.1.0" dependencies = [ "deno_core", "nalgebra", + "thiserror 2.0.3", ] [[package]] @@ -2123,10 +2124,11 @@ dependencies = [ [[package]] name = "deno_ops" -version = "0.203.0" +version = "0.204.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b146ca74cac431843486ade58e2accc16c11315fb2c6934590a52a73c56b7ec3" +checksum = "92b6db630a454b9faa2a2b60d91eefe26ad0ee9f2c7ca191dc9b4af5db33862f" dependencies = [ + "indexmap 2.3.0", "proc-macro-rules", "proc-macro2", "quote", @@ -6876,9 +6878,9 @@ dependencies = [ [[package]] name = "serde_v8" -version = "0.236.0" +version = "0.237.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e23b3abce64010612f88f4ff689a959736f99eb3dc0dbf1c7903434b8bd8cda5" +checksum = "be6dcdeb2f531fb20b47a98b47f528d0933b93931e1e5bb8e59f84db994bfa5e" dependencies = [ "num-bigint", "serde", @@ -8510,9 +8512,9 @@ dependencies = [ [[package]] name = "v8" -version = "130.0.2" +version = "130.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee0be58935708fa4d7efb970c6cf9f2d9511d24ee24246481a65b6ee167348d" +checksum = "8b61316a57fcd7e5f3840fe085f13e6dfd37e92d73b040033d2f598c7a1984c3" dependencies = [ "bindgen", "bitflags 2.6.0", diff --git a/Cargo.toml b/Cargo.toml index 8dff7d175d9b53..ebeacc42b1a7f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,7 @@ repository = "https://github.com/denoland/deno" [workspace.dependencies] deno_ast = { version = "=0.44.0", features = ["transpiling"] } -deno_core = { version = "0.327.0" } +deno_core = { version = "0.328.0" } deno_bench_util = { version = "0.178.0", path = "./bench_util" } deno_config = { version = "=0.42.0", features = ["workspace", "sync"] } diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index e6b421d491d915..6daa0e98c5b4ad 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -241,19 +241,9 @@ class DOMPointReadOnly { } static fromPoint(other = { __proto__: null }) { - other = webidl.converters.DOMPointInit( - other, - "Failed to execute 'DOMPointReadOnly.fromPoint'", - "Argument 1", - ); const point = webidl.createBranded(DOMPointReadOnly); point[_writable] = false; - point[_inner] = new DOMPointInner( - other.x, - other.y, - other.z, - other.w, - ); + point[_inner] = DOMPointInner.fromPoint(other); return point; } @@ -334,19 +324,9 @@ class DOMPoint extends DOMPointReadOnly { [_writable] = true; static fromPoint(other = { __proto__: null }) { - other = webidl.converters.DOMPointInit( - other, - "Failed to execute 'DOMPoint.fromPoint'", - "Argument 1", - ); const point = webidl.createBranded(DOMPoint); point[_writable] = true; - point[_inner] = new DOMPointInner( - other.x, - other.y, - other.z, - other.w, - ); + point[_inner] = DOMPointInner.fromPoint(other); return point; } diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 2fd8c897473430..8627956d85cb13 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -10,6 +10,7 @@ use deno_core::cppgc; use deno_core::op2; use deno_core::v8; use deno_core::GarbageCollected; +use deno_core::WebIDL; use nalgebra::Matrix3; use nalgebra::Matrix4; use nalgebra::Matrix4x2; @@ -32,6 +33,19 @@ pub fn get_declaration() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_geometry.d.ts") } +#[derive(WebIDL)] +#[webidl(dictionary)] +pub struct DOMPointInit { + #[webidl(default = 0.0)] + x: f64, + #[webidl(default = 0.0)] + y: f64, + #[webidl(default = 0.0)] + z: f64, + #[webidl(default = 1.0)] + w: f64, +} + pub struct DOMPointInner { x: Cell, y: Cell, @@ -54,6 +68,17 @@ impl DOMPointInner { } } + #[static_method] + #[cppgc] + pub fn from_point(#[webidl] init: DOMPointInit) -> DOMPointInner { + DOMPointInner { + x: Cell::new(init.x), + y: Cell::new(init.y), + z: Cell::new(init.z), + w: Cell::new(init.w), + } + } + #[fast] #[getter] pub fn x(&self) -> f64 { From 48fa87b94a4f61b89d8212cba2f3b4013214d5df Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 5 Jan 2025 01:59:56 +0900 Subject: [PATCH 06/63] fix --- ext/geometry/01_geometry.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 6daa0e98c5b4ad..22b08a6bfe52a1 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -975,7 +975,11 @@ class DOMMatrixReadOnly { const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; if (originX === 0 && originY === 0 && originZ === 0) { - matrix[_inner] = this[_inner].clone().scale(scale, scale, scale); + matrix[_inner] = this[_inner].clone().scaleWithoutOrigin( + scale, + scale, + scale, + ); } else { matrix[_inner] = this[_inner].clone().scaleWithOrigin( scale, From 81021203c331029a136196c9474bdbde80239a55 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 5 Jan 2025 02:52:29 +0900 Subject: [PATCH 07/63] migrate DOMMatrixInit to ext/geometry/lib.rs --- ext/geometry/01_geometry.js | 310 +++++------------------------------- ext/geometry/Cargo.toml | 1 + ext/geometry/lib.rs | 146 +++++++++++++++++ runtime/errors.rs | 8 + 4 files changed, 197 insertions(+), 268 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 22b08a6bfe52a1..f206550936133a 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -101,124 +101,6 @@ webidl.converters.DOMQuadInit = webidl.createDictionaryConverter( ], ); -/** @type {webidl.Dictionary} */ -const dictDOMMatrix2DInit = [ - { - key: "a", - converter: webidl.converters["unrestricted double"], - }, - { - key: "b", - converter: webidl.converters["unrestricted double"], - }, - { - key: "c", - converter: webidl.converters["unrestricted double"], - }, - { - key: "d", - converter: webidl.converters["unrestricted double"], - }, - { - key: "e", - converter: webidl.converters["unrestricted double"], - }, - { - key: "f", - converter: webidl.converters["unrestricted double"], - }, - { - key: "m11", - converter: webidl.converters["unrestricted double"], - }, - { - key: "m12", - converter: webidl.converters["unrestricted double"], - }, - { - key: "m21", - converter: webidl.converters["unrestricted double"], - }, - { - key: "m22", - converter: webidl.converters["unrestricted double"], - }, - { - key: "m41", - converter: webidl.converters["unrestricted double"], - }, - { - key: "m42", - converter: webidl.converters["unrestricted double"], - }, -]; - -webidl.converters.DOMMatrix2DInit = webidl.createDictionaryConverter( - "DOMMatrix2DInit", - dictDOMMatrix2DInit, -); - -webidl.converters.DOMMatrixInit = webidl.createDictionaryConverter( - "DOMMatrixInit", - dictDOMMatrix2DInit, - [ - { - key: "m13", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "m14", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "m23", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "m24", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "m31", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "m32", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "m33", - converter: webidl.converters["unrestricted double"], - defaultValue: 1, - }, - { - key: "m34", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "m43", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "m44", - converter: webidl.converters["unrestricted double"], - defaultValue: 1, - }, - { - key: "is2D", - converter: webidl.converters["boolean"], - }, - ], -); - const _inner = Symbol("[[inner]]"); // Property to prevent writing values when an immutable instance is changed to // a mutable instance by Object.setPrototypeOf @@ -269,23 +151,19 @@ class DOMPointReadOnly { matrixTransform(matrix = { __proto__: null }) { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - const prefix = "Failed to execute 'matrixTransform' on 'DOMPointReadOnly'"; + let matrixInner; + // fast path for DOMMatrix or DOMMatrixReadOnly if ( - matrix === null || - !ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, matrix) + matrix !== null && + ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, matrix) ) { - const _matrix = webidl.converters.DOMMatrixInit( - matrix, - prefix, - "Argument 1", - ); - validateAndFixupMatrixDictionary(_matrix, prefix); - matrix = { __proto__: null }; - initMatrixFromDictonary(matrix, _matrix); + matrixInner = matrix[_inner]; + } else { + matrixInner = DOMMatrixInner.fromMatrix(matrix); } const point = webidl.createBranded(DOMPoint); point[_writable] = true; - point[_inner] = this[_inner].matrixTransform(matrix[_inner]); + point[_inner] = this[_inner].matrixTransform(matrixInner); return point; } @@ -748,7 +626,6 @@ class DOMMatrixReadOnly { } static fromMatrix(other = { __proto__: null }) { - const prefix = "Failed to execute 'DOMMatrixReadOnly.fromMatrix'"; const matrix = webidl.createBranded(DOMMatrixReadOnly); matrix[_writable] = false; // fast path for DOMMatrix or DOMMatrixReadOnly @@ -758,9 +635,7 @@ class DOMMatrixReadOnly { ) { matrix[_inner] = other[_inner].clone(); } else { - other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); - validateAndFixupMatrixDictionary(other, prefix); - initMatrixFromDictonary(matrix, other); + matrix[_inner] = DOMMatrixInner.fromMatrix(other); } return matrix; } @@ -1067,23 +942,19 @@ class DOMMatrixReadOnly { multiply(other = { __proto__: null }) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const prefix = "Failed to execute 'multiply' on 'DOMMatrixReadOnly'"; + let otherInner; + // fast path for DOMMatrix or DOMMatrixReadOnly if ( - other === null || - !ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) + other !== null && + ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) ) { - const _other = webidl.converters.DOMMatrixInit( - other, - prefix, - "Argument 1", - ); - validateAndFixupMatrixDictionary(_other, prefix); - other = { __proto__: null }; - initMatrixFromDictonary(other, _other); + otherInner = other[_inner]; + } else { + otherInner = DOMMatrixInner.fromMatrix(other); } const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].multiply(other[_inner]); + matrix[_inner] = this[_inner].multiply(otherInner); return matrix; } @@ -1113,27 +984,19 @@ class DOMMatrixReadOnly { transformPoint(point = { __proto__: null }) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + let pointInner; + // fast path for DOMPoint or DOMPointReadOnly if ( - point === null || - !ObjectPrototypeIsPrototypeOf(DOMPointReadOnlyPrototype, point) + point !== null && + ObjectPrototypeIsPrototypeOf(DOMPointReadOnlyPrototype, point) ) { - const _point = webidl.converters.DOMPointInit( - point, - "Failed to execute 'transformPoint' on 'DOMMatrixReadOnly'", - "Argument 1", - ); - point = { - [_inner]: new DOMPointInner( - _point.x, - _point.y, - _point.z, - _point.w, - ), - }; + pointInner = point[_inner]; + } else { + pointInner = DOMPointInner.fromPoint(point); } const result = webidl.createBranded(DOMPoint); result[_writable] = true; - result[_inner] = this[_inner].transformPoint(point[_inner]); + result[_inner] = this[_inner].transformPoint(pointInner); return result; } @@ -1229,7 +1092,6 @@ class DOMMatrix extends DOMMatrixReadOnly { [_writable] = true; static fromMatrix(other = { __proto__: null }) { - const prefix = "Failed to execute 'DOMMatrix.fromMatrix'"; const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; // fast path for DOMMatrix or DOMMatrixReadOnly @@ -1239,9 +1101,7 @@ class DOMMatrix extends DOMMatrixReadOnly { ) { matrix[_inner] = other[_inner].clone(); } else { - other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); - validateAndFixupMatrixDictionary(other, prefix); - initMatrixFromDictonary(matrix, other); + matrix[_inner] = DOMMatrixInner.fromMatrix(other); } return matrix; } @@ -1489,42 +1349,34 @@ class DOMMatrix extends DOMMatrixReadOnly { multiplySelf(other = { __proto__: null }) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - const prefix = "Failed to execute 'multiplySelf' on 'DOMMatrix'"; + let otherInner; + // fast path for DOMMatrix or DOMMatrixReadOnly if ( - other === null || - !ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) + other !== null && + ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) ) { - const _other = webidl.converters.DOMMatrixInit( - other, - prefix, - "Argument 1", - ); - validateAndFixupMatrixDictionary(_other, prefix); - other = { __proto__: null }; - initMatrixFromDictonary(other, _other); + otherInner = other[_inner]; + } else { + otherInner = DOMMatrixInner.fromMatrix(other); } - this[_inner].multiplySelf(other[_inner]); + this[_inner].multiplySelf(otherInner); return this; } preMultiplySelf(other = { __proto__: null }) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - const prefix = "Failed to execute 'premultiplySelf' on 'DOMMatrix'"; + let otherInner; + // fast path for DOMMatrix or DOMMatrixReadOnly if ( - other === null || - !ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) + other !== null && + ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) ) { - const _other = webidl.converters.DOMMatrixInit( - other, - prefix, - "Argument 1", - ); - validateAndFixupMatrixDictionary(_other, prefix); - other = { __proto__: null }; - initMatrixFromDictonary(other, _other); + otherInner = other[_inner]; + } else { + otherInner = DOMMatrixInner.fromMatrix(other); } - this[_inner].preMultiplySelf(other[_inner]); + this[_inner].preMultiplySelf(otherInner); return this; } @@ -1715,84 +1567,6 @@ function assertWritable(self) { } } -/** - * https://tc39.es/ecma262/#sec-samevaluezero - * @param {number} x - * @param {number} y - */ -function sameValueZero(x, y) { - return x === y || ObjectIs(x, y); -} - -/** - * https://drafts.fxtf.org/geometry/#matrix-validate-and-fixup-2d - * @param {object} dict - * @param {string} prefix - */ -function validateAndFixup2DMatrixDictionary(dict, prefix) { - if ( - ( - dict.a !== undefined && dict.m11 !== undefined && - !sameValueZero(dict.a, dict.m11) - ) || - ( - dict.b !== undefined && dict.m12 !== undefined && - !sameValueZero(dict.b, dict.m12) - ) || - ( - dict.c !== undefined && dict.m21 !== undefined && - !sameValueZero(dict.c, dict.m21) - ) || - ( - dict.d !== undefined && dict.m22 !== undefined && - !sameValueZero(dict.d, dict.m22) - ) || - ( - dict.e !== undefined && dict.m41 !== undefined && - !sameValueZero(dict.e, dict.m41) - ) || - ( - dict.f !== undefined && dict.m42 !== undefined && - !sameValueZero(dict.f, dict.m42) - ) - ) { - throw new TypeError(`${prefix}: Inconsistent 2d matrix value`); - } - if (dict.m11 === undefined) dict.m11 = dict.a ?? 1; - if (dict.m12 === undefined) dict.m12 = dict.b ?? 0; - if (dict.m21 === undefined) dict.m21 = dict.c ?? 0; - if (dict.m22 === undefined) dict.m22 = dict.d ?? 1; - if (dict.m41 === undefined) dict.m41 = dict.e ?? 0; - if (dict.m42 === undefined) dict.m42 = dict.f ?? 0; -} - -/** - * https://drafts.fxtf.org/geometry/#matrix-validate-and-fixup - * @param {object} dict - * @param {string} prefix - */ -function validateAndFixupMatrixDictionary(dict, prefix) { - validateAndFixup2DMatrixDictionary(dict, prefix); - const is2DCanBeTrue = dict.m13 === 0 && - dict.m14 === 0 && - dict.m23 === 0 && - dict.m24 === 0 && - dict.m31 === 0 && - dict.m32 === 0 && - dict.m33 === 1 && - dict.m34 === 0 && - dict.m43 === 0 && - dict.m44 === 1; - if (dict.is2D === true && !is2DCanBeTrue) { - throw new TypeError( - `${prefix}: is2D property is true but the input matrix is a 3d matrix`, - ); - } - if (dict.is2D === undefined) { - dict.is2D = is2DCanBeTrue; - } -} - /** * @param {object} target * @param {number[] | Float32Array | Float64Array} seq diff --git a/ext/geometry/Cargo.toml b/ext/geometry/Cargo.toml index e831ea7c98edde..0ab9e48e270c0f 100644 --- a/ext/geometry/Cargo.toml +++ b/ext/geometry/Cargo.toml @@ -16,3 +16,4 @@ path = "lib.rs" [dependencies] deno_core.workspace = true nalgebra.workspace = true +thiserror.workspace = true diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 8627956d85cb13..ea28c3172aa9d0 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -33,6 +33,12 @@ pub fn get_declaration() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_geometry.d.ts") } +#[derive(Debug, thiserror::Error)] +pub enum GeometryError { + #[error("Inconsistent 2d matrix value")] + Inconsistent2DMatrix, // TypeError +} + #[derive(WebIDL)] #[webidl(dictionary)] pub struct DOMPointInit { @@ -215,6 +221,57 @@ impl DOMRectInner { } } +#[derive(WebIDL)] +#[webidl(dictionary)] +pub struct DOMMatrixInit { + #[webidl(default = None)] + a: Option, + #[webidl(default = None)] + b: Option, + #[webidl(default = None)] + c: Option, + #[webidl(default = None)] + d: Option, + #[webidl(default = None)] + e: Option, + #[webidl(default = None)] + f: Option, + #[webidl(default = None)] + m11: Option, + #[webidl(default = None)] + m12: Option, + #[webidl(default = 0.0)] + m13: f64, + #[webidl(default = 0.0)] + m14: f64, + #[webidl(default = None)] + m21: Option, + #[webidl(default = None)] + m22: Option, + #[webidl(default = 0.0)] + m23: f64, + #[webidl(default = 0.0)] + m24: f64, + #[webidl(default = 0.0)] + m31: f64, + #[webidl(default = 0.0)] + m32: f64, + #[webidl(default = 1.0)] + m33: f64, + #[webidl(default = 0.0)] + m34: f64, + #[webidl(default = None)] + m41: Option, + #[webidl(default = None)] + m42: Option, + #[webidl(default = 0.0)] + m43: f64, + #[webidl(default = 1.0)] + m44: f64, + #[webidl(default = None)] + is_2d: Option, +} + #[derive(Clone)] pub struct DOMMatrixInner { inner: RefCell>, @@ -276,6 +333,95 @@ impl DOMMatrixInner { } } + #[static_method] + #[cppgc] + pub fn from_matrix( + #[webidl] init: DOMMatrixInit, + ) -> Result { + macro_rules! fixup { + ($value3d:expr, $value2d:expr, $default:expr) => {{ + if let Some(value3d) = $value3d { + if let Some(value2d) = $value2d { + if !(value3d == value2d || value3d.is_nan() && value2d.is_nan()) { + return Err(GeometryError::Inconsistent2DMatrix); + } + } + value3d + } else if let Some(value2d) = $value2d { + value2d + } else { + $default + } + }}; + } + + let m11 = fixup!(init.m11, init.a, 1.0); + let m12 = fixup!(init.m12, init.b, 0.0); + let m21 = fixup!(init.m21, init.c, 0.0); + let m22 = fixup!(init.m22, init.d, 1.0); + let m41 = fixup!(init.m41, init.e, 0.0); + let m42 = fixup!(init.m42, init.f, 0.0); + + let is_2d = { + let is_2d_can_be_true = init.m13 == 0.0 + && init.m14 == 0.0 + && init.m23 == 0.0 + && init.m24 == 0.0 + && init.m31 == 0.0 + && init.m32 == 0.0 + && init.m33 == 1.0 + && init.m34 == 0.0 + && init.m43 == 0.0 + && init.m44 == 1.0; + if let Some(is_2d) = init.is_2d { + if is_2d && !is_2d_can_be_true { + return Err(GeometryError::Inconsistent2DMatrix); + } else { + is_2d + } + } else { + is_2d_can_be_true + } + }; + + if is_2d { + Ok(DOMMatrixInner { + #[rustfmt::skip] + inner: RefCell::new(Matrix4::new( + m11, m21, 0.0, m41, + m12, m22, 0.0, m42, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, + )), + is_2d: Cell::new(true), + }) + } else { + let DOMMatrixInit { + m13, + m14, + m23, + m24, + m31, + m32, + m33, + m34, + m43, + m44, + .. + } = init; + Ok(DOMMatrixInner { + #[rustfmt::skip] + inner: RefCell::new(Matrix4::new( + m11, m21, m31, m41, + m12, m22, m32, m42, + m13, m23, m33, m43, + m14, m24, m34, m44, + )), + is_2d: Cell::new(false), + }) + } + } + #[cppgc] pub fn clone(&self) -> DOMMatrixInner { self.clone() diff --git a/runtime/errors.rs b/runtime/errors.rs index 7b61395866b1ce..3a2d4568f3208e 100644 --- a/runtime/errors.rs +++ b/runtime/errors.rs @@ -37,6 +37,7 @@ use deno_ffi::ReprError; use deno_ffi::StaticError; use deno_fs::FsOpsError; use deno_fs::FsOpsErrorKind; +use deno_geometry::GeometryError; use deno_http::HttpError; use deno_http::HttpNextError; use deno_http::WebSocketUpgradeError; @@ -692,6 +693,12 @@ fn get_broadcast_channel_error(error: &BroadcastChannelError) -> &'static str { } } +fn get_geometry_error(error: &GeometryError) -> &'static str { + match error { + GeometryError::Inconsistent2DMatrix => "TypeError", + } +} + fn get_fetch_error(error: &FetchError) -> &'static str { match error { FetchError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), @@ -1768,6 +1775,7 @@ pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> { .or_else(|| e.downcast_ref::().map(get_http_start_error)) .or_else(|| e.downcast_ref::().map(get_process_error)) .or_else(|| e.downcast_ref::().map(get_os_error)) + .or_else(|| e.downcast_ref::().map(get_geometry_error)) .or_else(|| e.downcast_ref::().map(get_sync_fetch_error)) .or_else(|| { e.downcast_ref::() From 34b91e9faff9e9444e3896db2440bcc311c0be36 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 5 Jan 2025 03:35:06 +0900 Subject: [PATCH 08/63] tweak --- ext/geometry/01_geometry.js | 182 ++++++++-------------------------- ext/geometry/lib.rs | 192 ++++++++++++++++++------------------ 2 files changed, 141 insertions(+), 233 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index f206550936133a..82f90f299afbb7 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -14,7 +14,6 @@ const { MathMax, MathMin, ObjectDefineProperty, - ObjectIs, ObjectPrototypeIsPrototypeOf, Symbol, SymbolFor, @@ -113,12 +112,7 @@ class DOMPointReadOnly { [_inner]; constructor(x = 0, y = 0, z = 0, w = 1) { - this[_inner] = new DOMPointInner( - webidl.converters["unrestricted double"](x), - webidl.converters["unrestricted double"](y), - webidl.converters["unrestricted double"](z), - webidl.converters["unrestricted double"](w), - ); + this[_inner] = new DOMPointInner(x, y, z, w); this[_brand] = _brand; } @@ -215,7 +209,7 @@ class DOMPoint extends DOMPointReadOnly { set x(value) { webidl.assertBranded(this, DOMPointPrototype); assertWritable(this); - this[_inner].x = webidl.converters["unrestricted double"](value); + this[_inner].x = value; } get y() { @@ -225,7 +219,7 @@ class DOMPoint extends DOMPointReadOnly { set y(value) { webidl.assertBranded(this, DOMPointPrototype); assertWritable(this); - this[_inner].y = webidl.converters["unrestricted double"](value); + this[_inner].y = value; } get z() { @@ -235,7 +229,7 @@ class DOMPoint extends DOMPointReadOnly { set z(value) { webidl.assertBranded(this, DOMPointPrototype); assertWritable(this); - this[_inner].z = webidl.converters["unrestricted double"](value); + this[_inner].z = value; } get w() { @@ -245,7 +239,7 @@ class DOMPoint extends DOMPointReadOnly { set w(value) { webidl.assertBranded(this, DOMPointPrototype); assertWritable(this); - this[_inner].x = webidl.converters["unrestricted double"](value); + this[_inner].x = value; } [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { @@ -782,9 +776,6 @@ class DOMMatrixReadOnly { translate(tx = 0, ty = 0, tz = 0) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - tx = webidl.converters["unrestricted double"](tx); - ty = webidl.converters["unrestricted double"](ty); - tz = webidl.converters["unrestricted double"](tz); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; matrix[_inner] = this[_inner].clone().translate(tx, ty, tz); @@ -800,12 +791,6 @@ class DOMMatrixReadOnly { originZ = 0, ) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - scaleX = webidl.converters["unrestricted double"](scaleX); - scaleY = webidl.converters["unrestricted double"](scaleY); - scaleZ = webidl.converters["unrestricted double"](scaleZ); - originX = webidl.converters["unrestricted double"](originX); - originY = webidl.converters["unrestricted double"](originY); - originZ = webidl.converters["unrestricted double"](originZ); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; if (originX === 0 && originY === 0 && originZ === 0) { @@ -829,8 +814,6 @@ class DOMMatrixReadOnly { scaleNonUniform(scaleX = 1, scaleY = 1) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - scaleX = webidl.converters["unrestricted double"](scaleX); - scaleY = webidl.converters["unrestricted double"](scaleY); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; matrix[_inner] = this[_inner].clone().scaleWithoutOrigin( @@ -843,10 +826,6 @@ class DOMMatrixReadOnly { scale3d(scale = 1, originX = 0, originY = 0, originZ = 0) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - scale = webidl.converters["unrestricted double"](scale); - originX = webidl.converters["unrestricted double"](originX); - originY = webidl.converters["unrestricted double"](originY); - originZ = webidl.converters["unrestricted double"](originZ); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; if (originX === 0 && originY === 0 && originZ === 0) { @@ -870,18 +849,13 @@ class DOMMatrixReadOnly { rotate(rotX = 0, rotY, rotZ) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - rotX = webidl.converters["unrestricted double"](rotX); if (rotY === undefined && rotZ === undefined) { rotZ = rotX; rotX = 0; rotY = 0; } else { - rotY = rotY !== undefined - ? webidl.converters["unrestricted double"](rotY) - : 0; - rotZ = rotZ !== undefined - ? webidl.converters["unrestricted double"](rotZ) - : 0; + rotY = rotY !== undefined ? rotY : 0; + rotZ = rotZ !== undefined ? rotZ : 0; } const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; @@ -895,8 +869,6 @@ class DOMMatrixReadOnly { rotateFromVector(x = 0, y = 0) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - x = webidl.converters["unrestricted double"](x); - y = webidl.converters["unrestricted double"](y); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; matrix[_inner] = this[_inner].clone().rotateFromVector(x, y); @@ -905,26 +877,19 @@ class DOMMatrixReadOnly { rotateAxisAngle(x = 0, y = 0, z = 0, angle = 0) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - x = webidl.converters["unrestricted double"](x); - y = webidl.converters["unrestricted double"](y); - z = webidl.converters["unrestricted double"](z); - angle = webidl.converters["unrestricted double"](angle); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - if (x !== 0 || y !== 0 || z !== 0) { - matrix[_inner] = this[_inner].clone().rotateAxisAngle( - x, - y, - z, - angle, - ); - } + matrix[_inner] = this[_inner].clone().rotateAxisAngle( + x, + y, + z, + angle, + ); return matrix; } skewX(sx = 0) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - sx = webidl.converters["unrestricted double"](sx); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; matrix[_inner] = this[_inner].clone().skewX(sx); @@ -933,7 +898,6 @@ class DOMMatrixReadOnly { skewY(sy = 0) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - sy = webidl.converters["unrestricted double"](sy); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; matrix[_inner] = this[_inner].clone().skewY(sy); @@ -1133,7 +1097,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set a(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].a = webidl.converters["unrestricted double"](value); + this[_inner].a = value; } get b() { @@ -1143,7 +1107,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set b(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].b = webidl.converters["unrestricted double"](value); + this[_inner].b = value; } get c() { @@ -1153,7 +1117,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set c(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].c = webidl.converters["unrestricted double"](value); + this[_inner].c = value; } get d() { @@ -1163,7 +1127,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set d(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].d = webidl.converters["unrestricted double"](value); + this[_inner].d = value; } get e() { @@ -1173,7 +1137,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set e(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].e = webidl.converters["unrestricted double"](value); + this[_inner].e = value; } get f() { @@ -1183,7 +1147,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set f(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].f = webidl.converters["unrestricted double"](value); + this[_inner].f = value; } get m11() { @@ -1193,7 +1157,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m11(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m11 = webidl.converters["unrestricted double"](value); + this[_inner].m11 = value; } get m12() { @@ -1203,7 +1167,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m12(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m12 = webidl.converters["unrestricted double"](value); + this[_inner].m12 = value; } get m13() { @@ -1213,7 +1177,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m13(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m13 = webidl.converters["unrestricted double"](value); + this[_inner].m13 = value; } get m14() { @@ -1223,7 +1187,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m14(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m14 = webidl.converters["unrestricted double"](value); + this[_inner].m14 = value; } get m21() { @@ -1233,7 +1197,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m21(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m21 = webidl.converters["unrestricted double"](value); + this[_inner].m21 = value; } get m22() { @@ -1243,7 +1207,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m22(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m22 = webidl.converters["unrestricted double"](value); + this[_inner].m22 = value; } get m23() { @@ -1253,7 +1217,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m23(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m23 = webidl.converters["unrestricted double"](value); + this[_inner].m23 = value; } get m24() { @@ -1263,7 +1227,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m24(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m24 = webidl.converters["unrestricted double"](value); + this[_inner].m24 = value; } get m31() { @@ -1273,7 +1237,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m31(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m31 = webidl.converters["unrestricted double"](value); + this[_inner].m31 = value; } get m32() { @@ -1283,7 +1247,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m32(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m32 = webidl.converters["unrestricted double"](value); + this[_inner].m32 = value; } get m33() { @@ -1293,7 +1257,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m33(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m33 = webidl.converters["unrestricted double"](value); + this[_inner].m33 = value; } get m34() { @@ -1303,7 +1267,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m34(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m34 = webidl.converters["unrestricted double"](value); + this[_inner].m34 = value; } get m41() { @@ -1313,7 +1277,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m41(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m41 = webidl.converters["unrestricted double"](value); + this[_inner].m41 = value; } get m42() { @@ -1323,7 +1287,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m42(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m42 = webidl.converters["unrestricted double"](value); + this[_inner].m42 = value; } get m43() { @@ -1333,7 +1297,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m43(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m43 = webidl.converters["unrestricted double"](value); + this[_inner].m43 = value; } get m44() { @@ -1343,7 +1307,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m44(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m44 = webidl.converters["unrestricted double"](value); + this[_inner].m44 = value; } multiplySelf(other = { __proto__: null }) { @@ -1383,9 +1347,6 @@ class DOMMatrix extends DOMMatrixReadOnly { translateSelf(tx = 0, ty = 0, tz = 0) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - tx = webidl.converters["unrestricted double"](tx); - ty = webidl.converters["unrestricted double"](ty); - tz = webidl.converters["unrestricted double"](tz); this[_inner].translateSelf(tx, ty, tz); return this; } @@ -1400,12 +1361,6 @@ class DOMMatrix extends DOMMatrixReadOnly { ) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - scaleX = webidl.converters["unrestricted double"](scaleX); - scaleY = webidl.converters["unrestricted double"](scaleY); - scaleZ = webidl.converters["unrestricted double"](scaleZ); - originX = webidl.converters["unrestricted double"](originX); - originY = webidl.converters["unrestricted double"](originY); - originZ = webidl.converters["unrestricted double"](originZ); if (originX === 0 && originY === 0 && originZ === 0) { this[_inner].scaleWithoutOriginSelf(scaleX, scaleY, scaleZ); } else { @@ -1424,10 +1379,6 @@ class DOMMatrix extends DOMMatrixReadOnly { scale3dSelf(scale = 1, originX = 0, originY = 0, originZ = 0) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - scale = webidl.converters["unrestricted double"](scale); - originX = webidl.converters["unrestricted double"](originX); - originY = webidl.converters["unrestricted double"](originY); - originZ = webidl.converters["unrestricted double"](originZ); if (originX === 0 && originY === 0 && originZ === 0) { this[_inner].scaleWithoutOriginSelf(scale, scale, scale); } else { @@ -1446,18 +1397,13 @@ class DOMMatrix extends DOMMatrixReadOnly { rotateSelf(rotX = 0, rotY, rotZ) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - rotX = webidl.converters["unrestricted double"](rotX); if (rotY === undefined && rotZ === undefined) { rotZ = rotX; rotX = 0; rotY = 0; } else { - rotY = rotY !== undefined - ? webidl.converters["unrestricted double"](rotY) - : 0; - rotZ = rotZ !== undefined - ? webidl.converters["unrestricted double"](rotZ) - : 0; + rotY = rotY !== undefined ? rotY : 0; + rotZ = rotZ !== undefined ? rotZ : 0; } this[_inner].rotateSelf( rotX, @@ -1470,8 +1416,6 @@ class DOMMatrix extends DOMMatrixReadOnly { rotateFromVectorSelf(x = 0, y = 0) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - x = webidl.converters["unrestricted double"](x); - y = webidl.converters["unrestricted double"](y); this[_inner].rotateFromVectorSelf(x, y); return this; } @@ -1479,25 +1423,18 @@ class DOMMatrix extends DOMMatrixReadOnly { rotateAxisAngleSelf(x = 0, y = 0, z = 0, angle = 0) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - x = webidl.converters["unrestricted double"](x); - y = webidl.converters["unrestricted double"](y); - z = webidl.converters["unrestricted double"](z); - angle = webidl.converters["unrestricted double"](angle); - if (x !== 0 || y !== 0 || z !== 0) { - this[_inner].rotateAxisAngleSelf( - x, - y, - z, - angle, - ); - } + this[_inner].rotateAxisAngleSelf( + x, + y, + z, + angle, + ); return this; } skewXSelf(sx = 0) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - sx = webidl.converters["unrestricted double"](sx); this[_inner].skewXSelf(sx); return this; } @@ -1505,7 +1442,6 @@ class DOMMatrix extends DOMMatrixReadOnly { skewYSelf(sy = 0) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - sy = webidl.converters["unrestricted double"](sy); this[_inner].skewYSelf(sy); return this; } @@ -1594,38 +1530,6 @@ function initMatrixFromSequence(target, seq, prefix) { } } -/** - * @param {object} target - * @param {object} dict - */ -function initMatrixFromDictonary(target, dict) { - if (dict.is2D) { - const { m11, m12, m21, m22, m41, m42 } = dict; - // deno-fmt-ignore - target[_inner] = new DOMMatrixInner(new Float64Array([ - m11, m12, 0, 0, - m21, m22, 0, 0, - 0, 0, 1, 0, - m41, m42, 0, 1, - ]), /* is2D */ true); - } else { - // deno-fmt-ignore - const { - m11, m12, m13, m14, - m21, m22, m23, m24, - m31, m32, m33, m34, - m41, m42, m43, m44, - } = dict; - // deno-fmt-ignore - target[_inner] = new DOMMatrixInner(new Float64Array([ - m11, m12, m13, m14, - m21, m22, m23, m24, - m31, m32, m33, m34, - m41, m42, m43, m44, - ]), /* is2D */ false); - } -} - /** * CSS parser * @type {((transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean })} diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index ea28c3172aa9d0..79bada84b1a843 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -65,7 +65,12 @@ impl GarbageCollected for DOMPointInner {} impl DOMPointInner { #[constructor] #[cppgc] - pub fn constructor(x: f64, y: f64, z: f64, w: f64) -> DOMPointInner { + pub fn constructor( + #[webidl] x: f64, + #[webidl] y: f64, + #[webidl] z: f64, + #[webidl] w: f64, + ) -> DOMPointInner { DOMPointInner { x: Cell::new(x), y: Cell::new(y), @@ -91,9 +96,8 @@ impl DOMPointInner { self.x.get() } - #[fast] #[setter] - pub fn x(&self, value: f64) { + pub fn x(&self, #[webidl] value: f64) { self.x.set(value) } @@ -103,9 +107,8 @@ impl DOMPointInner { self.y.get() } - #[fast] #[setter] - pub fn y(&self, value: f64) { + pub fn y(&self, #[webidl] value: f64) { self.y.set(value) } @@ -115,9 +118,8 @@ impl DOMPointInner { self.z.get() } - #[fast] #[setter] - pub fn z(&self, value: f64) { + pub fn z(&self, #[webidl] value: f64) { self.z.set(value) } @@ -127,9 +129,8 @@ impl DOMPointInner { self.w.get() } - #[fast] #[setter] - pub fn w(&self, value: f64) { + pub fn w(&self, #[webidl] value: f64) { self.w.set(value) } @@ -434,9 +435,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_A) } } - #[fast] #[setter] - pub fn a(&self, value: f64) { + pub fn a(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_A) = value; @@ -450,9 +450,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_B) } } - #[fast] #[setter] - pub fn b(&self, value: f64) { + pub fn b(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_B) = value; @@ -466,9 +465,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_C) } } - #[fast] #[setter] - pub fn c(&self, value: f64) { + pub fn c(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_C) = value; @@ -482,9 +480,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_D) } } - #[fast] #[setter] - pub fn d(&self, value: f64) { + pub fn d(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_D) = value; @@ -498,9 +495,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_E) } } - #[fast] #[setter] - pub fn e(&self, value: f64) { + pub fn e(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_E) = value; @@ -514,9 +510,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_F) } } - #[fast] #[setter] - pub fn f(&self, value: f64) { + pub fn f(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_F) = value; @@ -530,9 +525,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M11) } } - #[fast] #[setter] - pub fn m11(&self, value: f64) { + pub fn m11(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M11) = value; @@ -546,9 +540,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M12) } } - #[fast] #[setter] - pub fn m12(&self, value: f64) { + pub fn m12(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M12) = value; @@ -562,9 +555,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M13) } } - #[fast] #[setter] - pub fn m13(&self, value: f64) { + pub fn m13(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M13) = value; @@ -581,9 +573,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M14) } } - #[fast] #[setter] - pub fn m14(&self, value: f64) { + pub fn m14(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M14) = value; @@ -600,9 +591,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M21) } } - #[fast] #[setter] - pub fn m21(&self, value: f64) { + pub fn m21(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M21) = value; @@ -616,9 +606,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M22) } } - #[fast] #[setter] - pub fn m22(&self, value: f64) { + pub fn m22(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M22) = value; @@ -632,9 +621,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M23) } } - #[fast] #[setter] - pub fn m23(&self, value: f64) { + pub fn m23(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M23) = value; @@ -651,9 +639,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M24) } } - #[fast] #[setter] - pub fn m24(&self, value: f64) { + pub fn m24(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M24) = value; @@ -670,9 +657,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M31) } } - #[fast] #[setter] - pub fn m31(&self, value: f64) { + pub fn m31(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M31) = value; @@ -689,9 +675,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M32) } } - #[fast] #[setter] - pub fn m32(&self, value: f64) { + pub fn m32(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M32) = value; @@ -708,9 +693,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M33) } } - #[fast] #[setter] - pub fn m33(&self, value: f64) { + pub fn m33(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M33) = value; @@ -727,9 +711,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M34) } } - #[fast] #[setter] - pub fn m34(&self, value: f64) { + pub fn m34(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M34) = value; @@ -746,9 +729,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M41) } } - #[fast] #[setter] - pub fn m41(&self, value: f64) { + pub fn m41(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M41) = value; @@ -762,9 +744,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M42) } } - #[fast] #[setter] - pub fn m42(&self, value: f64) { + pub fn m42(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M42) = value; @@ -778,9 +759,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M43) } } - #[fast] #[setter] - pub fn m43(&self, value: f64) { + pub fn m43(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M43) = value; @@ -797,9 +777,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M44) } } - #[fast] #[setter] - pub fn m44(&self, value: f64) { + pub fn m44(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M44) = value; @@ -863,58 +842,70 @@ impl DOMMatrixInner { } #[cppgc] - pub fn translate(&self, tx: f64, ty: f64, tz: f64) -> DOMMatrixInner { + pub fn translate( + &self, + #[webidl] tx: f64, + #[webidl] ty: f64, + #[webidl] tz: f64, + ) -> DOMMatrixInner { let out = self.clone(); matrix_translate(&out, tx, ty, tz); out } - #[fast] - pub fn translate_self(&self, tx: f64, ty: f64, tz: f64) { + pub fn translate_self( + &self, + #[webidl] tx: f64, + #[webidl] ty: f64, + #[webidl] tz: f64, + ) { matrix_translate(self, tx, ty, tz); } #[cppgc] pub fn scale_without_origin( &self, - sx: f64, - sy: f64, - sz: f64, + #[webidl] sx: f64, + #[webidl] sy: f64, + #[webidl] sz: f64, ) -> DOMMatrixInner { let out = self.clone(); matrix_scale(&out, sx, sy, sz); out } - #[fast] - pub fn scale_without_origin_self(&self, sx: f64, sy: f64, sz: f64) { + pub fn scale_without_origin_self( + &self, + #[webidl] sx: f64, + #[webidl] sy: f64, + #[webidl] sz: f64, + ) { matrix_scale(self, sx, sy, sz); } #[cppgc] pub fn scale_with_origin( &self, - sx: f64, - sy: f64, - sz: f64, - origin_x: f64, - origin_y: f64, - origin_z: f64, + #[webidl] sx: f64, + #[webidl] sy: f64, + #[webidl] sz: f64, + #[webidl] origin_x: f64, + #[webidl] origin_y: f64, + #[webidl] origin_z: f64, ) -> DOMMatrixInner { let out = self.clone(); matrix_scale_with_origin(&out, sx, sy, sz, origin_x, origin_y, origin_z); out } - #[fast] pub fn scale_with_origin_self( &self, - sx: f64, - sy: f64, - sz: f64, - origin_x: f64, - origin_y: f64, - origin_z: f64, + #[webidl] sx: f64, + #[webidl] sy: f64, + #[webidl] sz: f64, + #[webidl] origin_x: f64, + #[webidl] origin_y: f64, + #[webidl] origin_z: f64, ) { matrix_scale_with_origin(self, sx, sy, sz, origin_x, origin_y, origin_z); } @@ -922,71 +913,81 @@ impl DOMMatrixInner { #[cppgc] pub fn rotate( &self, - roll_deg: f64, - pitch_deg: f64, - yaw_deg: f64, + #[webidl] roll_deg: f64, + #[webidl] pitch_deg: f64, + #[webidl] yaw_deg: f64, ) -> DOMMatrixInner { let out = self.clone(); matrix_rotate(&out, roll_deg, pitch_deg, yaw_deg); out } - #[fast] - pub fn rotate_self(&self, roll_deg: f64, pitch_deg: f64, yaw_deg: f64) { + pub fn rotate_self( + &self, + #[webidl] roll_deg: f64, + #[webidl] pitch_deg: f64, + #[webidl] yaw_deg: f64, + ) { matrix_rotate(self, roll_deg, pitch_deg, yaw_deg); } #[cppgc] - pub fn rotate_from_vector(&self, x: f64, y: f64) -> DOMMatrixInner { + pub fn rotate_from_vector( + &self, + #[webidl] x: f64, + #[webidl] y: f64, + ) -> DOMMatrixInner { let out = self.clone(); matrix_rotate_from_vector(&out, x, y); out } - #[fast] - pub fn rotate_from_vector_self(&self, x: f64, y: f64) { + pub fn rotate_from_vector_self(&self, #[webidl] x: f64, #[webidl] y: f64) { matrix_rotate_from_vector(self, x, y); } #[cppgc] pub fn rotate_axis_angle( &self, - x: f64, - y: f64, - z: f64, - angle_deg: f64, + #[webidl] x: f64, + #[webidl] y: f64, + #[webidl] z: f64, + #[webidl] angle_deg: f64, ) -> DOMMatrixInner { let out = self.clone(); matrix_rotate_axis_angle(&out, x, y, z, angle_deg); out } - #[fast] - pub fn rotate_axis_angle_self(&self, x: f64, y: f64, z: f64, angle_deg: f64) { + pub fn rotate_axis_angle_self( + &self, + #[webidl] x: f64, + #[webidl] y: f64, + #[webidl] z: f64, + #[webidl] angle_deg: f64, + ) { matrix_rotate_axis_angle(self, x, y, z, angle_deg); } #[cppgc] - pub fn skew_x(&self, x_deg: f64) -> DOMMatrixInner { + pub fn skew_x(&self, #[webidl] x_deg: f64) -> DOMMatrixInner { let out = self.clone(); matrix_skew_x(&out, x_deg); out } - #[fast] - pub fn skew_x_self(&self, x_deg: f64) { + pub fn skew_x_self(&self, #[webidl] x_deg: f64) { matrix_skew_x(self, x_deg); } #[cppgc] - pub fn skew_y(&self, y_deg: f64) -> DOMMatrixInner { + pub fn skew_y(&self, #[webidl] y_deg: f64) -> DOMMatrixInner { let out = self.clone(); matrix_skew_y(&out, y_deg); out } - #[fast] - pub fn skew_y_self(&self, y_deg: f64) { + pub fn skew_y_self(&self, #[webidl] y_deg: f64) { matrix_skew_y(self, y_deg); } @@ -1178,6 +1179,9 @@ fn matrix_rotate_axis_angle( z: f64, angle_deg: f64, ) { + if x == 0.0 && y == 0.0 && z == 0.0 { + return; + } let mut inner = matrix.inner.borrow_mut(); let is_2d = matrix.is_2d.get(); let rotation = Rotation3::from_axis_angle( From 048fe96c1eaab00dad8090139203fc85bc2e42e9 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 5 Jan 2025 16:42:41 +0900 Subject: [PATCH 09/63] tweak --- ext/geometry/01_geometry.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 82f90f299afbb7..8a31ed7ebd9242 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -778,7 +778,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().translate(tx, ty, tz); + matrix[_inner] = this[_inner].translate(tx, ty, tz); return matrix; } @@ -794,13 +794,13 @@ class DOMMatrixReadOnly { const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; if (originX === 0 && originY === 0 && originZ === 0) { - matrix[_inner] = this[_inner].clone().scaleWithoutOrigin( + matrix[_inner] = this[_inner].scaleWithoutOrigin( scaleX, scaleY, scaleZ, ); } else { - matrix[_inner] = this[_inner].clone().scaleWithOrigin( + matrix[_inner] = this[_inner].scaleWithOrigin( scaleX, scaleY, scaleZ, @@ -816,7 +816,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().scaleWithoutOrigin( + matrix[_inner] = this[_inner].scaleWithoutOrigin( scaleX, scaleY, 1, @@ -829,13 +829,13 @@ class DOMMatrixReadOnly { const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; if (originX === 0 && originY === 0 && originZ === 0) { - matrix[_inner] = this[_inner].clone().scaleWithoutOrigin( + matrix[_inner] = this[_inner].scaleWithoutOrigin( scale, scale, scale, ); } else { - matrix[_inner] = this[_inner].clone().scaleWithOrigin( + matrix[_inner] = this[_inner].scaleWithOrigin( scale, scale, scale, @@ -859,7 +859,7 @@ class DOMMatrixReadOnly { } const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().rotate( + matrix[_inner] = this[_inner].rotate( rotX, rotY, rotZ, @@ -871,7 +871,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().rotateFromVector(x, y); + matrix[_inner] = this[_inner].rotateFromVector(x, y); return matrix; } @@ -879,7 +879,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().rotateAxisAngle( + matrix[_inner] = this[_inner].rotateAxisAngle( x, y, z, @@ -892,7 +892,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().skewX(sx); + matrix[_inner] = this[_inner].skewX(sx); return matrix; } @@ -900,7 +900,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().skewY(sy); + matrix[_inner] = this[_inner].skewY(sy); return matrix; } @@ -926,7 +926,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().flipX(); + matrix[_inner] = this[_inner].flipX(); return matrix; } @@ -934,7 +934,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().flipY(); + matrix[_inner] = this[_inner].flipY(); return matrix; } @@ -942,7 +942,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().inverse(); + matrix[_inner] = this[_inner].inverse(); return matrix; } From fd84470aaa64ae875a9c6dd0c80ae6629696745d Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 12 Jan 2025 02:05:30 +0900 Subject: [PATCH 10/63] update --- ext/geometry/01_geometry.js | 73 +++++--------------- ext/geometry/README.md | 2 +- ext/geometry/lib.rs | 131 +++++++++++++++++++++++------------- 3 files changed, 102 insertions(+), 104 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 8a31ed7ebd9242..fa123ba27cc641 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -1,12 +1,7 @@ // Copyright 2018-2025 the Deno authors. MIT license. import { primordials } from "ext:core/mod.js"; -import { - DOMMatrixInner, - DOMPointInner, - DOMRectInner, - op_geometry_create_matrix_identity, -} from "ext:core/ops"; +import { DOMMatrixInner, DOMPointInner, DOMRectInner } from "ext:core/ops"; const { ArrayPrototypeJoin, Float32Array, @@ -267,29 +262,14 @@ class DOMRectReadOnly { [_inner]; constructor(x = 0, y = 0, width = 0, height = 0) { - this[_inner] = new DOMRectInner( - webidl.converters["unrestricted double"](x), - webidl.converters["unrestricted double"](y), - webidl.converters["unrestricted double"](width), - webidl.converters["unrestricted double"](height), - ); + this[_inner] = new DOMRectInner(x, y, width, height); this[_brand] = _brand; } static fromRect(other = { __proto__: null }) { - other = webidl.converters.DOMRectInit( - other, - "Failed to execute 'DOMRectReadOnly.fromRect'", - "Argument 1", - ); const rect = webidl.createBranded(DOMRectReadOnly); rect[_writable] = false; - rect[_inner] = new DOMRectInner( - other.x, - other.y, - other.width, - other.height, - ); + rect[_inner] = DOMRectInner.fromRect(other); return rect; } @@ -315,41 +295,28 @@ class DOMRectReadOnly { get top() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const { y, height } = this[_inner]; - return MathMin(y, y + height); + return this[_inner].top; } get right() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const { x, width } = this[_inner]; - return MathMax(x, x + width); + return this[_inner].right; } get bottom() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const { y, height } = this[_inner]; - return MathMax(y, y + height); + return this[_inner].bottom; } get left() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const { x, width } = this[_inner]; - return MathMin(x, x + width); + return this[_inner].left; } toJSON() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const { x, y, width, height } = this[_inner]; - return { - x, - y, - width, - height, - top: MathMin(y, y + height), - right: MathMax(x, x + width), - bottom: MathMax(y, y + height), - left: MathMin(x, x + width), - }; + const { x, y, width, height, top, right, bottom, left } = this[_inner]; + return { x, y, width, height, top, right, bottom, left }; } [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { @@ -380,19 +347,9 @@ class DOMRect extends DOMRectReadOnly { [_writable] = true; static fromRect(other = { __proto__: null }) { - other = webidl.converters.DOMRectInit( - other, - "Failed to execute 'DOMRect.fromRect'", - "Argument 1", - ); const rect = webidl.createBranded(DOMRect); rect[_writable] = true; - rect[_inner] = new DOMRectInner( - other.x, - other.y, - other.width, - other.height, - ); + rect[_inner] = DOMRectInner.fromRect(other); return rect; } @@ -403,7 +360,7 @@ class DOMRect extends DOMRectReadOnly { set x(value) { webidl.assertBranded(this, DOMRectPrototype); assertWritable(this); - this[_inner].x = webidl.converters["unrestricted double"](value); + this[_inner].x = value; } get y() { @@ -413,7 +370,7 @@ class DOMRect extends DOMRectReadOnly { set y(value) { webidl.assertBranded(this, DOMRectPrototype); assertWritable(this); - this[_inner].y = webidl.converters["unrestricted double"](value); + this[_inner].y = value; } get width() { @@ -423,7 +380,7 @@ class DOMRect extends DOMRectReadOnly { set width(value) { webidl.assertBranded(this, DOMRectPrototype); assertWritable(this); - this[_inner].width = webidl.converters["unrestricted double"](value); + this[_inner].width = value; } get height() { @@ -433,7 +390,7 @@ class DOMRect extends DOMRectReadOnly { set height(value) { webidl.assertBranded(this, DOMRectPrototype); assertWritable(this); - this[_inner].height = webidl.converters["unrestricted double"](value); + this[_inner].height = value; } [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { @@ -598,7 +555,7 @@ class DOMMatrixReadOnly { const prefix = `Failed to construct '${this.constructor.name}'`; this[_brand] = _brand; if (init === undefined) { - this[_inner] = op_geometry_create_matrix_identity(); + this[_inner] = DOMMatrixInner.identity(); } else if ( webidl.type(init) === "Object" && init[SymbolIterator] !== undefined ) { diff --git a/ext/geometry/README.md b/ext/geometry/README.md index 7e10bfeecd4a1a..1ba0d3ee175074 100644 --- a/ext/geometry/README.md +++ b/ext/geometry/README.md @@ -87,12 +87,12 @@ the `extensions` field of your `RuntimeOptions` - **deno_webidl**: Provided by the `deno_webidl` crate - **deno_web**: Provided by the `deno_web` crate - **deno_console**: Provided by the `deno_console` crate +- **deno_error**: Provided by the `deno_error` crate ## Provided ops Following ops are provided, which can be accessed through `Deno.ops`: -- op_geometry_create_matrix_identity - DOMMatrixInner - DOMPointInner - DOMRectInner diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 5645f0fdbb2eb5..94c45f0cd4bf80 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -6,7 +6,6 @@ use std::mem; use std::path::PathBuf; use std::slice; -use deno_core::cppgc; use deno_core::op2; use deno_core::v8; use deno_core::GarbageCollected; @@ -23,7 +22,6 @@ use nalgebra::Vector4; deno_core::extension!( deno_geometry, deps = [deno_webidl, deno_web, deno_console], - ops = [op_geometry_create_matrix_identity], objects = [DOMPointInner, DOMRectInner, DOMMatrixInner], esm = ["00_init.js"], lazy_loaded_esm = ["01_geometry.js"], @@ -140,7 +138,9 @@ impl DOMPointInner { &self, matrix: v8::Local, ) -> DOMPointInner { - let matrix = cast_to_matrix(matrix); + // SAFETY: cast v8::Local + let matrix: v8::Local<'_, DOMMatrixInner> = + unsafe { mem::transmute(matrix) }; let out = DOMPointInner { x: Cell::new(0.0), y: Cell::new(0.0), @@ -152,6 +152,19 @@ impl DOMPointInner { } } +#[derive(WebIDL)] +#[webidl(dictionary)] +pub struct DOMRectInit { + #[webidl(default = 0.0)] + x: f64, + #[webidl(default = 0.0)] + y: f64, + #[webidl(default = 0.0)] + width: f64, + #[webidl(default = 0.0)] + height: f64, +} + pub struct DOMRectInner { x: Cell, y: Cell, @@ -165,7 +178,12 @@ impl GarbageCollected for DOMRectInner {} impl DOMRectInner { #[constructor] #[cppgc] - pub fn constructor(x: f64, y: f64, width: f64, height: f64) -> DOMRectInner { + pub fn constructor( + #[webidl] x: f64, + #[webidl] y: f64, + #[webidl] width: f64, + #[webidl] height: f64, + ) -> DOMRectInner { DOMRectInner { x: Cell::new(x), y: Cell::new(y), @@ -174,15 +192,25 @@ impl DOMRectInner { } } + #[static_method] + #[cppgc] + pub fn from_rect(#[webidl] init: DOMRectInit) -> DOMRectInner { + DOMRectInner { + x: Cell::new(init.x), + y: Cell::new(init.y), + width: Cell::new(init.width), + height: Cell::new(init.height), + } + } + #[fast] #[getter] pub fn x(&self) -> f64 { self.x.get() } - #[fast] #[setter] - pub fn x(&self, value: f64) { + pub fn x(&self, #[webidl] value: f64) { self.x.set(value) } @@ -192,9 +220,8 @@ impl DOMRectInner { self.y.get() } - #[fast] #[setter] - pub fn y(&self, value: f64) { + pub fn y(&self, #[webidl] value: f64) { self.y.set(value) } @@ -204,9 +231,8 @@ impl DOMRectInner { self.width.get() } - #[fast] #[setter] - pub fn width(&self, value: f64) { + pub fn width(&self, #[webidl] value: f64) { self.width.set(value) } @@ -216,11 +242,42 @@ impl DOMRectInner { self.height.get() } - #[fast] #[setter] - pub fn height(&self, value: f64) { + pub fn height(&self, #[webidl] value: f64) { self.height.set(value) } + + #[fast] + #[getter] + pub fn top(&self) -> f64 { + let y = self.y.get(); + let height = self.height.get(); + y.min(y + height) + } + + #[fast] + #[getter] + pub fn right(&self) -> f64 { + let x = self.x.get(); + let width = self.width.get(); + x.max(x + width) + } + + #[fast] + #[getter] + pub fn bottom(&self) -> f64 { + let y = self.y.get(); + let height = self.height.get(); + y.max(y + height) + } + + #[fast] + #[getter] + pub fn left(&self) -> f64 { + let x = self.x.get(); + let width = self.width.get(); + x.min(x + width) + } } #[derive(WebIDL)] @@ -424,6 +481,15 @@ impl DOMMatrixInner { } } + #[static_method] + #[cppgc] + pub fn identity() -> DOMMatrixInner { + DOMMatrixInner { + inner: RefCell::new(Matrix4::identity()), + is_2d: Cell::new(true), + } + } + #[cppgc] pub fn clone(&self) -> DOMMatrixInner { self.clone() @@ -994,7 +1060,8 @@ impl DOMMatrixInner { #[cppgc] pub fn multiply(&self, other: v8::Local) -> DOMMatrixInner { - let other = cast_to_matrix(other); + // SAFETY: cast v8::Local + let other: v8::Local<'_, DOMMatrixInner> = unsafe { mem::transmute(other) }; let out = DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), @@ -1005,7 +1072,8 @@ impl DOMMatrixInner { #[fast] pub fn multiply_self(&self, other: v8::Local) { - let other = cast_to_matrix(other); + // SAFETY: cast v8::Local + let other: v8::Local<'_, DOMMatrixInner> = unsafe { mem::transmute(other) }; let result = DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), @@ -1017,7 +1085,8 @@ impl DOMMatrixInner { #[fast] pub fn pre_multiply_self(&self, other: v8::Local) { - let other = cast_to_matrix(other); + // SAFETY: cast v8::Local + let other: v8::Local<'_, DOMMatrixInner> = unsafe { mem::transmute(other) }; let result = DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), @@ -1055,7 +1124,8 @@ impl DOMMatrixInner { #[cppgc] pub fn transform_point(&self, point: v8::Local) -> DOMPointInner { - let point = cast_to_point(point); + // SAFETY: cast v8::Local + let point: v8::Local<'_, DOMPointInner> = unsafe { mem::transmute(point) }; let out = DOMPointInner { x: Cell::new(0.0), y: Cell::new(0.0), @@ -1067,35 +1137,6 @@ impl DOMMatrixInner { } } -#[op2] -pub fn op_geometry_create_matrix_identity<'a>( - scope: &mut v8::HandleScope<'a>, -) -> v8::Local<'a, v8::Object> { - cppgc::make_cppgc_object( - scope, - DOMMatrixInner { - inner: RefCell::new(Matrix4::identity()), - is_2d: Cell::new(true), - }, - ) -} - -#[inline] -fn cast_to_point( - obj: v8::Local<'_, v8::Object>, -) -> v8::Local<'_, DOMPointInner> { - // SAFETY: cast v8::Local - unsafe { mem::transmute(obj) } -} - -#[inline] -fn cast_to_matrix( - obj: v8::Local<'_, v8::Object>, -) -> v8::Local<'_, DOMMatrixInner> { - // SAFETY: cast v8::Local - unsafe { mem::transmute(obj) } -} - #[inline] fn matrix_translate(matrix: &DOMMatrixInner, tx: f64, ty: f64, tz: f64) { let mut inner = matrix.inner.borrow_mut(); From ecc75e6e6088e8d55c6e554cc9eca1ab05543b27 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 13 Jan 2025 01:36:50 +0900 Subject: [PATCH 11/63] update --- ext/geometry/01_geometry.js | 272 +++++++++++++++--------------------- ext/geometry/README.md | 2 +- ext/geometry/lib.rs | 159 ++++++++++++++++++++- 3 files changed, 274 insertions(+), 159 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index fa123ba27cc641..07f639f424ad9c 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -1,13 +1,16 @@ // Copyright 2018-2025 the Deno authors. MIT license. import { primordials } from "ext:core/mod.js"; -import { DOMMatrixInner, DOMPointInner, DOMRectInner } from "ext:core/ops"; +import { + DOMMatrixInner, + DOMPointInner, + DOMQuadInner, + DOMRectInner, +} from "ext:core/ops"; const { ArrayPrototypeJoin, Float32Array, Float64Array, - MathMax, - MathMin, ObjectDefineProperty, ObjectPrototypeIsPrototypeOf, Symbol, @@ -21,80 +24,6 @@ import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; import { DOMException } from "ext:deno_web/01_dom_exception.js"; -webidl.converters.DOMPointInit = webidl.createDictionaryConverter( - "DOMPointInit", - [ - { - key: "x", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "y", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "z", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "w", - converter: webidl.converters["unrestricted double"], - defaultValue: 1, - }, - ], -); - -webidl.converters.DOMRectInit = webidl.createDictionaryConverter( - "DOMRectInit", - [ - { - key: "x", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "y", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "width", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "height", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - ], -); - -webidl.converters.DOMQuadInit = webidl.createDictionaryConverter( - "DOMQuadInit", - [ - { - key: "p1", - converter: webidl.converters.DOMPointInit, - }, - { - key: "p2", - converter: webidl.converters.DOMPointInit, - }, - { - key: "p3", - converter: webidl.converters.DOMPointInit, - }, - { - key: "p4", - converter: webidl.converters.DOMPointInit, - }, - ], -); - const _inner = Symbol("[[inner]]"); // Property to prevent writing values when an immutable instance is changed to // a mutable instance by Object.setPrototypeOf @@ -104,6 +33,7 @@ const _brand = webidl.brand; class DOMPointReadOnly { [_writable] = false; + /** @type {DOMPointInner} */ [_inner]; constructor(x = 0, y = 0, z = 0, w = 1) { @@ -158,13 +88,8 @@ class DOMPointReadOnly { toJSON() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - const inner = this[_inner]; - return { - x: inner.x, - y: inner.y, - z: inner.z, - w: inner.w, - }; + const { x, y, z, w } = this[_inner]; + return { x, y, z, w }; } [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { @@ -189,6 +114,8 @@ const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; class DOMPoint extends DOMPointReadOnly { [_writable] = true; + /** @type {DOMPointInner} */ + [_inner]; static fromPoint(other = { __proto__: null }) { const point = webidl.createBranded(DOMPoint); @@ -219,7 +146,7 @@ class DOMPoint extends DOMPointReadOnly { get z() { webidl.assertBranded(this, DOMPointPrototype); - return this[_inner].x; + return this[_inner].z; } set z(value) { webidl.assertBranded(this, DOMPointPrototype); @@ -259,6 +186,7 @@ const DOMPointPrototype = DOMPoint.prototype; class DOMRectReadOnly { [_writable] = false; + /** @type {DOMRectInner} */ [_inner]; constructor(x = 0, y = 0, width = 0, height = 0) { @@ -345,6 +273,8 @@ const DOMRectReadOnlyPrototype = DOMRectReadOnly.prototype; class DOMRect extends DOMRectReadOnly { [_writable] = true; + /** @type {DOMRectInner} */ + [_inner]; static fromRect(other = { __proto__: null }) { const rect = webidl.createBranded(DOMRect); @@ -423,13 +353,15 @@ const _p3 = Symbol("[[p3]]"); const _p4 = Symbol("[[p4]]"); class DOMQuad { - /** @type {DOMPoint} */ + /** @type {DOMQuadInner} */ + [_inner]; + /** @type {DOMPoint=} */ [_p1]; - /** @type {DOMPoint} */ + /** @type {DOMPoint=} */ [_p2]; - /** @type {DOMPoint} */ + /** @type {DOMPoint=} */ [_p3]; - /** @type {DOMPoint} */ + /** @type {DOMPoint=} */ [_p4]; constructor( @@ -438,82 +370,83 @@ class DOMQuad { p3 = { __proto__: null }, p4 = { __proto__: null }, ) { - this[_p1] = DOMPoint.fromPoint(p1); - this[_p2] = DOMPoint.fromPoint(p2); - this[_p3] = DOMPoint.fromPoint(p3); - this[_p4] = DOMPoint.fromPoint(p4); + this[_inner] = new DOMQuadInner(p1, p2, p3, p4); this[_brand] = _brand; } static fromRect(other = { __proto__: null }) { - other = webidl.converters.DOMRectInit( - other, - "Failed to execute 'DOMQuad.fromRect'", - "Argument 1", - ); - const { x, y, width, height } = other; const quad = webidl.createBranded(DOMQuad); - quad[_p1] = new DOMPoint(x, y, 0, 1); - quad[_p2] = new DOMPoint(x + width, y, 0, 1); - quad[_p3] = new DOMPoint(x + width, y + height, 0, 1); - quad[_p4] = new DOMPoint(x, y + height, 0, 1); + quad[_inner] = DOMQuadInner.fromRect(other); + quad[_p1] = undefined; + quad[_p2] = undefined; + quad[_p3] = undefined; + quad[_p4] = undefined; return quad; } static fromQuad(other = { __proto__: null }) { - other = webidl.converters.DOMQuadInit( - other, - "Failed to execute 'DOMQuad.fromQuad'", - "Argument 1", - ); const quad = webidl.createBranded(DOMQuad); - quad[_p1] = DOMPoint.fromPoint(other.p1); - quad[_p2] = DOMPoint.fromPoint(other.p2); - quad[_p3] = DOMPoint.fromPoint(other.p3); - quad[_p4] = DOMPoint.fromPoint(other.p4); + quad[_inner] = DOMQuadInner.fromQuad(other); + quad[_p1] = undefined; + quad[_p2] = undefined; + quad[_p3] = undefined; + quad[_p4] = undefined; return quad; } get p1() { webidl.assertBranded(this, DOMQuadPrototype); - return this[_p1]; + if (this[_p1] !== undefined) { + return this[_p1]; + } + const point = webidl.createBranded(DOMPoint); + point[_writable] = true; + point[_inner] = this[_inner].p1; + this[_p1] = point; + return point; } get p2() { webidl.assertBranded(this, DOMQuadPrototype); - return this[_p2]; + if (this[_p2] !== undefined) { + return this[_p2]; + } + const point = webidl.createBranded(DOMPoint); + point[_writable] = true; + point[_inner] = this[_inner].p2; + this[_p2] = point; + return point; } get p3() { webidl.assertBranded(this, DOMQuadPrototype); - return this[_p3]; + if (this[_p3] !== undefined) { + return this[_p3]; + } + const point = webidl.createBranded(DOMPoint); + point[_writable] = true; + point[_inner] = this[_inner].p3; + this[_p3] = point; + return point; } get p4() { webidl.assertBranded(this, DOMQuadPrototype); - return this[_p4]; + if (this[_p4] !== undefined) { + return this[_p4]; + } + const point = webidl.createBranded(DOMPoint); + point[_writable] = true; + point[_inner] = this[_inner].p4; + this[_p4] = point; + return point; } getBounds() { webidl.assertBranded(this, DOMQuadPrototype); - const { x: p1x, y: p1y } = this[_p1]; - const { x: p2x, y: p2y } = this[_p2]; - const { x: p3x, y: p3y } = this[_p3]; - const { x: p4x, y: p4y } = this[_p4]; - - const left = MathMin(p1x, p2x, p3x, p4x); - const top = MathMin(p1y, p2y, p3y, p4y); - const right = MathMax(p1x, p2x, p3x, p4x); - const bottom = MathMax(p1y, p2y, p3y, p4y); - const bounds = webidl.createBranded(DOMRect); bounds[_writable] = true; - bounds[_inner] = new DOMRectInner( - left, - top, - right - left, - bottom - top, - ); + bounds[_inner] = this[_inner].fromBounds(); return bounds; } @@ -937,32 +870,57 @@ class DOMMatrixReadOnly { toJSON() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const inner = this[_inner]; + const { + a, + b, + c, + d, + e, + f, + m11, + m12, + m13, + m14, + m21, + m22, + m23, + m24, + m31, + m32, + m33, + m34, + m41, + m42, + m43, + m44, + is2D, + isIdentity, + } = this[_inner]; return { - a: inner.a, - b: inner.b, - c: inner.c, - d: inner.d, - e: inner.e, - f: inner.f, - m11: inner.m11, - m12: inner.m12, - m13: inner.m13, - m14: inner.m14, - m21: inner.m21, - m22: inner.m22, - m23: inner.m23, - m24: inner.m24, - m31: inner.m31, - m32: inner.m32, - m33: inner.m33, - m34: inner.m34, - m41: inner.m41, - m42: inner.m42, - m43: inner.m43, - m44: inner.m44, - is2D: inner.is2D, - isIdentity: inner.isIdentity, + a, + b, + c, + d, + e, + f, + m11, + m12, + m13, + m14, + m21, + m22, + m23, + m24, + m31, + m32, + m33, + m34, + m41, + m42, + m43, + m44, + is2D, + isIdentity, }; } diff --git a/ext/geometry/README.md b/ext/geometry/README.md index 1ba0d3ee175074..8c2f421b10d5e4 100644 --- a/ext/geometry/README.md +++ b/ext/geometry/README.md @@ -87,7 +87,6 @@ the `extensions` field of your `RuntimeOptions` - **deno_webidl**: Provided by the `deno_webidl` crate - **deno_web**: Provided by the `deno_web` crate - **deno_console**: Provided by the `deno_console` crate -- **deno_error**: Provided by the `deno_error` crate ## Provided ops @@ -95,4 +94,5 @@ Following ops are provided, which can be accessed through `Deno.ops`: - DOMMatrixInner - DOMPointInner +- DOMQuadInner - DOMRectInner diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 94c45f0cd4bf80..39699e910cafa3 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -2,8 +2,10 @@ use std::cell::Cell; use std::cell::RefCell; +use std::cell::UnsafeCell; use std::mem; use std::path::PathBuf; +use std::ptr; use std::slice; use deno_core::op2; @@ -22,7 +24,7 @@ use nalgebra::Vector4; deno_core::extension!( deno_geometry, deps = [deno_webidl, deno_web, deno_console], - objects = [DOMPointInner, DOMRectInner, DOMMatrixInner], + objects = [DOMPointInner, DOMRectInner, DOMQuadInner, DOMMatrixInner], esm = ["00_init.js"], lazy_loaded_esm = ["01_geometry.js"], ); @@ -280,6 +282,161 @@ impl DOMRectInner { } } +#[derive(WebIDL)] +#[webidl(dictionary)] +pub struct DOMQuadInit { + p1: DOMPointInit, + p2: DOMPointInit, + p3: DOMPointInit, + p4: DOMPointInit, +} + +pub struct DOMQuadInner { + p1: UnsafeCell, + p2: UnsafeCell, + p3: UnsafeCell, + p4: UnsafeCell, +} + +impl GarbageCollected for DOMQuadInner {} + +#[op2] +impl DOMQuadInner { + #[constructor] + #[cppgc] + pub fn constructor( + #[webidl] p1: DOMPointInit, + #[webidl] p2: DOMPointInit, + #[webidl] p3: DOMPointInit, + #[webidl] p4: DOMPointInit, + ) -> DOMQuadInner { + #[inline] + fn from_point(point: DOMPointInit) -> DOMPointInner { + DOMPointInner { + x: Cell::new(point.x), + y: Cell::new(point.y), + z: Cell::new(point.z), + w: Cell::new(point.w), + } + } + + DOMQuadInner { + p1: UnsafeCell::new(from_point(p1)), + p2: UnsafeCell::new(from_point(p2)), + p3: UnsafeCell::new(from_point(p3)), + p4: UnsafeCell::new(from_point(p4)), + } + } + + #[static_method] + #[cppgc] + pub fn from_rect(#[webidl] rect: DOMRectInit) -> DOMQuadInner { + let DOMRectInit { + x, + y, + width, + height, + } = rect; + DOMQuadInner { + p1: UnsafeCell::new(DOMPointInner { + x: Cell::new(x), + y: Cell::new(y), + z: Cell::new(0.0), + w: Cell::new(1.0), + }), + p2: UnsafeCell::new(DOMPointInner { + x: Cell::new(x + width), + y: Cell::new(y), + z: Cell::new(0.0), + w: Cell::new(1.0), + }), + p3: UnsafeCell::new(DOMPointInner { + x: Cell::new(x + width), + y: Cell::new(y + height), + z: Cell::new(0.0), + w: Cell::new(1.0), + }), + p4: UnsafeCell::new(DOMPointInner { + x: Cell::new(x), + y: Cell::new(y + height), + z: Cell::new(0.0), + w: Cell::new(1.0), + }), + } + } + + #[static_method] + #[cppgc] + pub fn from_quad(#[webidl] quad: DOMQuadInit) -> DOMQuadInner { + #[inline] + fn from_point(point: DOMPointInit) -> DOMPointInner { + DOMPointInner { + x: Cell::new(point.x), + y: Cell::new(point.y), + z: Cell::new(point.z), + w: Cell::new(point.w), + } + } + + DOMQuadInner { + p1: UnsafeCell::new(from_point(quad.p1)), + p2: UnsafeCell::new(from_point(quad.p2)), + p3: UnsafeCell::new(from_point(quad.p3)), + p4: UnsafeCell::new(from_point(quad.p4)), + } + } + + #[cppgc] + #[getter] + pub fn p1(&self) -> DOMPointInner { + // SAFETY: ptr is alive + unsafe { ptr::read(self.p1.get()) } + } + + #[cppgc] + #[getter] + pub fn p2(&self) -> DOMPointInner { + // SAFETY: ptr is alive + unsafe { ptr::read(self.p2.get()) } + } + + #[cppgc] + #[getter] + pub fn p3(&self) -> DOMPointInner { + // SAFETY: ptr is alive + unsafe { ptr::read(self.p3.get()) } + } + + #[cppgc] + #[getter] + pub fn p4(&self) -> DOMPointInner { + // SAFETY: ptr is alive + unsafe { ptr::read(self.p4.get()) } + } + + #[cppgc] + pub fn get_bounds(&self) -> DOMRectInner { + // SAFETY: ptr is alive + let p1 = unsafe { ptr::read(self.p1.get()) }; + // SAFETY: ptr is alive + let p2 = unsafe { ptr::read(self.p2.get()) }; + // SAFETY: ptr is alive + let p3 = unsafe { ptr::read(self.p3.get()) }; + // SAFETY: ptr is alive + let p4 = unsafe { ptr::read(self.p4.get()) }; + let left = p1.x.get().min(p2.x.get()).min(p3.x.get()).min(p4.x.get()); + let top = p1.y.get().min(p2.y.get()).min(p3.y.get()).min(p4.y.get()); + let right = p1.x.get().max(p2.x.get()).max(p3.x.get()).max(p4.x.get()); + let bottom = p1.y.get().max(p2.y.get()).max(p3.y.get()).max(p4.y.get()); + DOMRectInner { + x: Cell::new(left), + y: Cell::new(top), + width: Cell::new(right - left), + height: Cell::new(bottom - top), + } + } +} + #[derive(WebIDL)] #[webidl(dictionary)] pub struct DOMMatrixInit { From 7cc681ca35d10cd277b8f170064128f1cf86d01f Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 13 Jan 2025 10:31:31 +0900 Subject: [PATCH 12/63] fix --- ext/geometry/01_geometry.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 07f639f424ad9c..db7beec3faea40 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -114,8 +114,6 @@ const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; class DOMPoint extends DOMPointReadOnly { [_writable] = true; - /** @type {DOMPointInner} */ - [_inner]; static fromPoint(other = { __proto__: null }) { const point = webidl.createBranded(DOMPoint); @@ -273,8 +271,6 @@ const DOMRectReadOnlyPrototype = DOMRectReadOnly.prototype; class DOMRect extends DOMRectReadOnly { [_writable] = true; - /** @type {DOMRectInner} */ - [_inner]; static fromRect(other = { __proto__: null }) { const rect = webidl.createBranded(DOMRect); @@ -482,6 +478,7 @@ const DOMQuadPrototype = DOMQuad.prototype; class DOMMatrixReadOnly { [_writable] = false; + /** @type {DOMMatrixInner} */ [_inner]; constructor(init = undefined) { From 3f9b0ee7af9276a9fe8adfa6eeb8d72dfa0f425e Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 13 Jan 2025 10:31:54 +0900 Subject: [PATCH 13/63] refactor --- Cargo.toml | 1 + ext/geometry/lib.rs | 130 +++++++++++++++++--------------------------- 2 files changed, 51 insertions(+), 80 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 47c5c7356e7e04..8b2da31561f9ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -230,6 +230,7 @@ hkdf = "0.12.3" rsa = { version = "0.9.3", default-features = false, features = ["std", "pem", "hazmat"] } # hazmat needed for PrehashSigner in ext/node # geometry +# TODO(petamoriken): Prefer to use glam as well as wgpu, but glam is not sufficient for mutable operations nalgebra = { version = "0.33.2", default-features = false, features = ["std"] } # webgpu diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 39699e910cafa3..115f435d7db9b5 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -54,10 +54,7 @@ pub struct DOMPointInit { } pub struct DOMPointInner { - x: Cell, - y: Cell, - z: Cell, - w: Cell, + inner: RefCell>, } impl GarbageCollected for DOMPointInner {} @@ -73,10 +70,7 @@ impl DOMPointInner { #[webidl] w: f64, ) -> DOMPointInner { DOMPointInner { - x: Cell::new(x), - y: Cell::new(y), - z: Cell::new(z), - w: Cell::new(w), + inner: RefCell::new(Vector4::new(x, y, z, w)), } } @@ -84,55 +78,52 @@ impl DOMPointInner { #[cppgc] pub fn from_point(#[webidl] init: DOMPointInit) -> DOMPointInner { DOMPointInner { - x: Cell::new(init.x), - y: Cell::new(init.y), - z: Cell::new(init.z), - w: Cell::new(init.w), + inner: RefCell::new(Vector4::new(init.x, init.y, init.z, init.w)), } } #[fast] #[getter] pub fn x(&self) -> f64 { - self.x.get() + self.inner.borrow().x } #[setter] pub fn x(&self, #[webidl] value: f64) { - self.x.set(value) + self.inner.borrow_mut().x = value } #[fast] #[getter] pub fn y(&self) -> f64 { - self.y.get() + self.inner.borrow().y } #[setter] pub fn y(&self, #[webidl] value: f64) { - self.y.set(value) + self.inner.borrow_mut().y = value } #[fast] #[getter] pub fn z(&self) -> f64 { - self.z.get() + self.inner.borrow().z } #[setter] pub fn z(&self, #[webidl] value: f64) { - self.z.set(value) + self.inner.borrow_mut().z = value } #[fast] #[getter] pub fn w(&self) -> f64 { - self.w.get() + self.inner.borrow().w } #[setter] pub fn w(&self, #[webidl] value: f64) { - self.w.set(value) + self.inner.borrow_mut().w = value } #[cppgc] @@ -144,10 +135,7 @@ impl DOMPointInner { let matrix: v8::Local<'_, DOMMatrixInner> = unsafe { mem::transmute(matrix) }; let out = DOMPointInner { - x: Cell::new(0.0), - y: Cell::new(0.0), - z: Cell::new(0.0), - w: Cell::new(0.0), + inner: RefCell::new(Vector4::zeros()), }; matrix_transform_point(&matrix, self, &out); out @@ -313,10 +301,7 @@ impl DOMQuadInner { #[inline] fn from_point(point: DOMPointInit) -> DOMPointInner { DOMPointInner { - x: Cell::new(point.x), - y: Cell::new(point.y), - z: Cell::new(point.z), - w: Cell::new(point.w), + inner: RefCell::new(Vector4::new(point.x, point.y, point.z, point.w)), } } @@ -339,28 +324,16 @@ impl DOMQuadInner { } = rect; DOMQuadInner { p1: UnsafeCell::new(DOMPointInner { - x: Cell::new(x), - y: Cell::new(y), - z: Cell::new(0.0), - w: Cell::new(1.0), + inner: RefCell::new(Vector4::new(x, y, 0.0, 1.0)), }), p2: UnsafeCell::new(DOMPointInner { - x: Cell::new(x + width), - y: Cell::new(y), - z: Cell::new(0.0), - w: Cell::new(1.0), + inner: RefCell::new(Vector4::new(x + width, y, 0.0, 1.0)), }), p3: UnsafeCell::new(DOMPointInner { - x: Cell::new(x + width), - y: Cell::new(y + height), - z: Cell::new(0.0), - w: Cell::new(1.0), + inner: RefCell::new(Vector4::new(x + width, y + height, 0.0, 1.0)), }), p4: UnsafeCell::new(DOMPointInner { - x: Cell::new(x), - y: Cell::new(y + height), - z: Cell::new(0.0), - w: Cell::new(1.0), + inner: RefCell::new(Vector4::new(x, y + height, 0.0, 1.0)), }), } } @@ -371,10 +344,7 @@ impl DOMQuadInner { #[inline] fn from_point(point: DOMPointInit) -> DOMPointInner { DOMPointInner { - x: Cell::new(point.x), - y: Cell::new(point.y), - z: Cell::new(point.z), - w: Cell::new(point.w), + inner: RefCell::new(Vector4::new(point.x, point.y, point.z, point.w)), } } @@ -424,10 +394,14 @@ impl DOMQuadInner { let p3 = unsafe { ptr::read(self.p3.get()) }; // SAFETY: ptr is alive let p4 = unsafe { ptr::read(self.p4.get()) }; - let left = p1.x.get().min(p2.x.get()).min(p3.x.get()).min(p4.x.get()); - let top = p1.y.get().min(p2.y.get()).min(p3.y.get()).min(p4.y.get()); - let right = p1.x.get().max(p2.x.get()).max(p3.x.get()).max(p4.x.get()); - let bottom = p1.y.get().max(p2.y.get()).max(p3.y.get()).max(p4.y.get()); + let p1 = p1.inner.borrow(); + let p2 = p2.inner.borrow(); + let p3 = p3.inner.borrow(); + let p4 = p4.inner.borrow(); + let left = p1.x.min(p2.x).min(p3.x).min(p4.x); + let top = p1.y.min(p2.y).min(p3.y).min(p4.y); + let right = p1.x.max(p2.x).max(p3.x).max(p4.x); + let bottom = p1.y.max(p2.y).max(p3.y).max(p4.y); DOMRectInner { x: Cell::new(left), y: Cell::new(top), @@ -577,7 +551,6 @@ impl DOMMatrixInner { let m22 = fixup!(init.m22, init.d, 1.0); let m41 = fixup!(init.m41, init.e, 0.0); let m42 = fixup!(init.m42, init.f, 0.0); - let is_2d = { let is_2d_can_be_true = init.m13 == 0.0 && init.m14 == 0.0 @@ -1059,7 +1032,7 @@ impl DOMMatrixInner { unsafe { slice::from_raw_parts( self.inner.borrow().as_slice().as_ptr() as *mut u8, - 128, + mem::size_of::() * 16, ) } .to_vec() @@ -1094,7 +1067,7 @@ impl DOMMatrixInner { #[webidl] sz: f64, ) -> DOMMatrixInner { let out = self.clone(); - matrix_scale(&out, sx, sy, sz); + matrix_scale_without_origin(&out, sx, sy, sz); out } @@ -1104,7 +1077,7 @@ impl DOMMatrixInner { #[webidl] sy: f64, #[webidl] sz: f64, ) { - matrix_scale(self, sx, sy, sz); + matrix_scale_without_origin(self, sx, sy, sz); } #[cppgc] @@ -1284,10 +1257,7 @@ impl DOMMatrixInner { // SAFETY: cast v8::Local let point: v8::Local<'_, DOMPointInner> = unsafe { mem::transmute(point) }; let out = DOMPointInner { - x: Cell::new(0.0), - y: Cell::new(0.0), - z: Cell::new(0.0), - w: Cell::new(0.0), + inner: RefCell::new(Vector4::zeros()), }; matrix_transform_point(self, &point, &out); out @@ -1304,7 +1274,12 @@ fn matrix_translate(matrix: &DOMMatrixInner, tx: f64, ty: f64, tz: f64) { } #[inline] -fn matrix_scale(matrix: &DOMMatrixInner, sx: f64, sy: f64, sz: f64) { +fn matrix_scale_without_origin( + matrix: &DOMMatrixInner, + sx: f64, + sy: f64, + sz: f64, +) { let mut inner = matrix.inner.borrow_mut(); let is_2d = matrix.is_2d.get(); let scaling = Vector3::new(sx, sy, sz); @@ -1460,12 +1435,12 @@ fn matrix_inverse(matrix: &DOMMatrixInner) { // SAFETY: in-range access let mut matrix3 = unsafe { Matrix3::new( - *inner.get_unchecked(0), - *inner.get_unchecked(4), - *inner.get_unchecked(12), - *inner.get_unchecked(1), - *inner.get_unchecked(5), - *inner.get_unchecked(13), + *inner.get_unchecked(INDEX_A), + *inner.get_unchecked(INDEX_C), + *inner.get_unchecked(INDEX_E), + *inner.get_unchecked(INDEX_B), + *inner.get_unchecked(INDEX_D), + *inner.get_unchecked(INDEX_F), 0.0, 0.0, 1.0, @@ -1478,12 +1453,12 @@ fn matrix_inverse(matrix: &DOMMatrixInner) { } // SAFETY: in-range access unsafe { - *inner.get_unchecked_mut(0) = *matrix3.get_unchecked(0); - *inner.get_unchecked_mut(1) = *matrix3.get_unchecked(1); - *inner.get_unchecked_mut(4) = *matrix3.get_unchecked(3); - *inner.get_unchecked_mut(5) = *matrix3.get_unchecked(4); - *inner.get_unchecked_mut(12) = *matrix3.get_unchecked(6); - *inner.get_unchecked_mut(13) = *matrix3.get_unchecked(7); + *inner.get_unchecked_mut(INDEX_A) = *matrix3.get_unchecked(0); + *inner.get_unchecked_mut(INDEX_B) = *matrix3.get_unchecked(1); + *inner.get_unchecked_mut(INDEX_C) = *matrix3.get_unchecked(3); + *inner.get_unchecked_mut(INDEX_D) = *matrix3.get_unchecked(4); + *inner.get_unchecked_mut(INDEX_E) = *matrix3.get_unchecked(6); + *inner.get_unchecked_mut(INDEX_F) = *matrix3.get_unchecked(7); } } else if !inner.try_inverse_mut() { inner.fill(f64::NAN); @@ -1496,12 +1471,7 @@ fn matrix_transform_point( out: &DOMPointInner, ) { let inner = matrix.inner.borrow(); - let point = - Vector4::new(point.x.get(), point.y.get(), point.z.get(), point.w.get()); - let mut result = Vector4::zeros(); + let point = point.inner.borrow(); + let mut result = out.inner.borrow_mut(); inner.mul_to(&point, &mut result); - out.x.set(result.x); - out.y.set(result.y); - out.z.set(result.z); - out.w.set(result.w); } From c28e753480a0d4cca2a953151929a3298b3dd26e Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 13 Jan 2025 11:26:36 +0900 Subject: [PATCH 14/63] use `unrestricted double` --- ext/geometry/lib.rs | 519 ++++++++++++++++++++++++-------------------- 1 file changed, 288 insertions(+), 231 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 115f435d7db9b5..0af1871a6af4fd 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -10,6 +10,7 @@ use std::slice; use deno_core::op2; use deno_core::v8; +use deno_core::webidl; use deno_core::GarbageCollected; use deno_core::WebIDL; use nalgebra::Matrix3; @@ -43,14 +44,14 @@ pub enum GeometryError { #[derive(WebIDL)] #[webidl(dictionary)] pub struct DOMPointInit { - #[webidl(default = 0.0)] - x: f64, - #[webidl(default = 0.0)] - y: f64, - #[webidl(default = 0.0)] - z: f64, - #[webidl(default = 1.0)] - w: f64, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + x: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + y: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + z: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(1.0))] + w: webidl::UnrestrictedDouble, } pub struct DOMPointInner { @@ -64,13 +65,13 @@ impl DOMPointInner { #[constructor] #[cppgc] pub fn constructor( - #[webidl] x: f64, - #[webidl] y: f64, - #[webidl] z: f64, - #[webidl] w: f64, + #[webidl] x: webidl::UnrestrictedDouble, + #[webidl] y: webidl::UnrestrictedDouble, + #[webidl] z: webidl::UnrestrictedDouble, + #[webidl] w: webidl::UnrestrictedDouble, ) -> DOMPointInner { DOMPointInner { - inner: RefCell::new(Vector4::new(x, y, z, w)), + inner: RefCell::new(Vector4::new(*x, *y, *z, *w)), } } @@ -78,7 +79,7 @@ impl DOMPointInner { #[cppgc] pub fn from_point(#[webidl] init: DOMPointInit) -> DOMPointInner { DOMPointInner { - inner: RefCell::new(Vector4::new(init.x, init.y, init.z, init.w)), + inner: RefCell::new(Vector4::new(*init.x, *init.y, *init.z, *init.w)), } } @@ -89,8 +90,8 @@ impl DOMPointInner { } #[setter] - pub fn x(&self, #[webidl] value: f64) { - self.inner.borrow_mut().x = value + pub fn x(&self, #[webidl] value: webidl::UnrestrictedDouble) { + self.inner.borrow_mut().x = *value } #[fast] @@ -100,8 +101,8 @@ impl DOMPointInner { } #[setter] - pub fn y(&self, #[webidl] value: f64) { - self.inner.borrow_mut().y = value + pub fn y(&self, #[webidl] value: webidl::UnrestrictedDouble) { + self.inner.borrow_mut().y = *value } #[fast] @@ -111,8 +112,8 @@ impl DOMPointInner { } #[setter] - pub fn z(&self, #[webidl] value: f64) { - self.inner.borrow_mut().z = value + pub fn z(&self, #[webidl] value: webidl::UnrestrictedDouble) { + self.inner.borrow_mut().z = *value } #[fast] @@ -122,8 +123,8 @@ impl DOMPointInner { } #[setter] - pub fn w(&self, #[webidl] value: f64) { - self.inner.borrow_mut().w = value + pub fn w(&self, #[webidl] value: webidl::UnrestrictedDouble) { + self.inner.borrow_mut().w = *value } #[cppgc] @@ -145,14 +146,14 @@ impl DOMPointInner { #[derive(WebIDL)] #[webidl(dictionary)] pub struct DOMRectInit { - #[webidl(default = 0.0)] - x: f64, - #[webidl(default = 0.0)] - y: f64, - #[webidl(default = 0.0)] - width: f64, - #[webidl(default = 0.0)] - height: f64, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + x: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + y: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + width: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + height: webidl::UnrestrictedDouble, } pub struct DOMRectInner { @@ -169,16 +170,16 @@ impl DOMRectInner { #[constructor] #[cppgc] pub fn constructor( - #[webidl] x: f64, - #[webidl] y: f64, - #[webidl] width: f64, - #[webidl] height: f64, + #[webidl] x: webidl::UnrestrictedDouble, + #[webidl] y: webidl::UnrestrictedDouble, + #[webidl] width: webidl::UnrestrictedDouble, + #[webidl] height: webidl::UnrestrictedDouble, ) -> DOMRectInner { DOMRectInner { - x: Cell::new(x), - y: Cell::new(y), - width: Cell::new(width), - height: Cell::new(height), + x: Cell::new(*x), + y: Cell::new(*y), + width: Cell::new(*width), + height: Cell::new(*height), } } @@ -186,10 +187,10 @@ impl DOMRectInner { #[cppgc] pub fn from_rect(#[webidl] init: DOMRectInit) -> DOMRectInner { DOMRectInner { - x: Cell::new(init.x), - y: Cell::new(init.y), - width: Cell::new(init.width), - height: Cell::new(init.height), + x: Cell::new(*init.x), + y: Cell::new(*init.y), + width: Cell::new(*init.width), + height: Cell::new(*init.height), } } @@ -200,8 +201,8 @@ impl DOMRectInner { } #[setter] - pub fn x(&self, #[webidl] value: f64) { - self.x.set(value) + pub fn x(&self, #[webidl] value: webidl::UnrestrictedDouble) { + self.x.set(*value) } #[fast] @@ -211,8 +212,8 @@ impl DOMRectInner { } #[setter] - pub fn y(&self, #[webidl] value: f64) { - self.y.set(value) + pub fn y(&self, #[webidl] value: webidl::UnrestrictedDouble) { + self.y.set(*value) } #[fast] @@ -222,8 +223,8 @@ impl DOMRectInner { } #[setter] - pub fn width(&self, #[webidl] value: f64) { - self.width.set(value) + pub fn width(&self, #[webidl] value: webidl::UnrestrictedDouble) { + self.width.set(*value) } #[fast] @@ -233,8 +234,8 @@ impl DOMRectInner { } #[setter] - pub fn height(&self, #[webidl] value: f64) { - self.height.set(value) + pub fn height(&self, #[webidl] value: webidl::UnrestrictedDouble) { + self.height.set(*value) } #[fast] @@ -242,7 +243,7 @@ impl DOMRectInner { pub fn top(&self) -> f64 { let y = self.y.get(); let height = self.height.get(); - y.min(y + height) + minimum(y, y + height) } #[fast] @@ -250,7 +251,7 @@ impl DOMRectInner { pub fn right(&self) -> f64 { let x = self.x.get(); let width = self.width.get(); - x.max(x + width) + maximum(x, x + width) } #[fast] @@ -258,7 +259,7 @@ impl DOMRectInner { pub fn bottom(&self) -> f64 { let y = self.y.get(); let height = self.height.get(); - y.max(y + height) + maximum(y, y + height) } #[fast] @@ -266,7 +267,7 @@ impl DOMRectInner { pub fn left(&self) -> f64 { let x = self.x.get(); let width = self.width.get(); - x.min(x + width) + minimum(x, x + width) } } @@ -301,7 +302,9 @@ impl DOMQuadInner { #[inline] fn from_point(point: DOMPointInit) -> DOMPointInner { DOMPointInner { - inner: RefCell::new(Vector4::new(point.x, point.y, point.z, point.w)), + inner: RefCell::new(Vector4::new( + *point.x, *point.y, *point.z, *point.w, + )), } } @@ -324,16 +327,16 @@ impl DOMQuadInner { } = rect; DOMQuadInner { p1: UnsafeCell::new(DOMPointInner { - inner: RefCell::new(Vector4::new(x, y, 0.0, 1.0)), + inner: RefCell::new(Vector4::new(*x, *y, 0.0, 1.0)), }), p2: UnsafeCell::new(DOMPointInner { - inner: RefCell::new(Vector4::new(x + width, y, 0.0, 1.0)), + inner: RefCell::new(Vector4::new(*x + *width, *y, 0.0, 1.0)), }), p3: UnsafeCell::new(DOMPointInner { - inner: RefCell::new(Vector4::new(x + width, y + height, 0.0, 1.0)), + inner: RefCell::new(Vector4::new(*x + *width, *y + *height, 0.0, 1.0)), }), p4: UnsafeCell::new(DOMPointInner { - inner: RefCell::new(Vector4::new(x, y + height, 0.0, 1.0)), + inner: RefCell::new(Vector4::new(*x, *y + *height, 0.0, 1.0)), }), } } @@ -344,7 +347,9 @@ impl DOMQuadInner { #[inline] fn from_point(point: DOMPointInit) -> DOMPointInner { DOMPointInner { - inner: RefCell::new(Vector4::new(point.x, point.y, point.z, point.w)), + inner: RefCell::new(Vector4::new( + *point.x, *point.y, *point.z, *point.w, + )), } } @@ -398,10 +403,10 @@ impl DOMQuadInner { let p2 = p2.inner.borrow(); let p3 = p3.inner.borrow(); let p4 = p4.inner.borrow(); - let left = p1.x.min(p2.x).min(p3.x).min(p4.x); - let top = p1.y.min(p2.y).min(p3.y).min(p4.y); - let right = p1.x.max(p2.x).max(p3.x).max(p4.x); - let bottom = p1.y.max(p2.y).max(p3.y).max(p4.y); + let left = minimum(minimum(p1.x, p2.x), minimum(p3.x, p4.x)); + let top = minimum(minimum(p1.y, p2.y), minimum(p3.y, p4.y)); + let right = maximum(maximum(p1.x, p2.x), maximum(p3.x, p4.x)); + let bottom = maximum(maximum(p1.y, p2.y), maximum(p3.y, p4.y)); DOMRectInner { x: Cell::new(left), y: Cell::new(top), @@ -415,49 +420,49 @@ impl DOMQuadInner { #[webidl(dictionary)] pub struct DOMMatrixInit { #[webidl(default = None)] - a: Option, + a: Option, #[webidl(default = None)] - b: Option, + b: Option, #[webidl(default = None)] - c: Option, + c: Option, #[webidl(default = None)] - d: Option, + d: Option, #[webidl(default = None)] - e: Option, + e: Option, #[webidl(default = None)] - f: Option, + f: Option, #[webidl(default = None)] - m11: Option, + m11: Option, #[webidl(default = None)] - m12: Option, - #[webidl(default = 0.0)] - m13: f64, - #[webidl(default = 0.0)] - m14: f64, + m12: Option, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + m13: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + m14: webidl::UnrestrictedDouble, #[webidl(default = None)] - m21: Option, + m21: Option, #[webidl(default = None)] - m22: Option, - #[webidl(default = 0.0)] - m23: f64, - #[webidl(default = 0.0)] - m24: f64, - #[webidl(default = 0.0)] - m31: f64, - #[webidl(default = 0.0)] - m32: f64, - #[webidl(default = 1.0)] - m33: f64, - #[webidl(default = 0.0)] - m34: f64, + m22: Option, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + m23: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + m24: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + m31: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + m32: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(1.0))] + m33: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + m34: webidl::UnrestrictedDouble, #[webidl(default = None)] - m41: Option, + m41: Option, #[webidl(default = None)] - m42: Option, - #[webidl(default = 0.0)] - m43: f64, - #[webidl(default = 1.0)] - m44: f64, + m42: Option, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + m43: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(1.0))] + m44: webidl::UnrestrictedDouble, #[webidl(default = None)] is_2d: Option, } @@ -532,7 +537,7 @@ impl DOMMatrixInner { ($value3d:expr, $value2d:expr, $default:expr) => {{ if let Some(value3d) = $value3d { if let Some(value2d) = $value2d { - if !(value3d == value2d || value3d.is_nan() && value2d.is_nan()) { + if !(*value3d == *value2d || value3d.is_nan() && value2d.is_nan()) { return Err(GeometryError::Inconsistent2DMatrix); } } @@ -540,7 +545,7 @@ impl DOMMatrixInner { } else if let Some(value2d) = $value2d { value2d } else { - $default + webidl::UnrestrictedDouble($default) } }}; } @@ -552,16 +557,16 @@ impl DOMMatrixInner { let m41 = fixup!(init.m41, init.e, 0.0); let m42 = fixup!(init.m42, init.f, 0.0); let is_2d = { - let is_2d_can_be_true = init.m13 == 0.0 - && init.m14 == 0.0 - && init.m23 == 0.0 - && init.m24 == 0.0 - && init.m31 == 0.0 - && init.m32 == 0.0 - && init.m33 == 1.0 - && init.m34 == 0.0 - && init.m43 == 0.0 - && init.m44 == 1.0; + let is_2d_can_be_true = *init.m13 == 0.0 + && *init.m14 == 0.0 + && *init.m23 == 0.0 + && *init.m24 == 0.0 + && *init.m31 == 0.0 + && *init.m32 == 0.0 + && *init.m33 == 1.0 + && *init.m34 == 0.0 + && *init.m43 == 0.0 + && *init.m44 == 1.0; if let Some(is_2d) = init.is_2d { if is_2d && !is_2d_can_be_true { return Err(GeometryError::Inconsistent2DMatrix); @@ -577,10 +582,10 @@ impl DOMMatrixInner { Ok(DOMMatrixInner { #[rustfmt::skip] inner: RefCell::new(Matrix4::new( - m11, m21, 0.0, m41, - m12, m22, 0.0, m42, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0, + *m11, *m21, 0.0, *m41, + *m12, *m22, 0.0, *m42, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, )), is_2d: Cell::new(true), }) @@ -601,10 +606,10 @@ impl DOMMatrixInner { Ok(DOMMatrixInner { #[rustfmt::skip] inner: RefCell::new(Matrix4::new( - m11, m21, m31, m41, - m12, m22, m32, m42, - m13, m23, m33, m43, - m14, m24, m34, m44, + *m11, *m21, *m31, *m41, + *m12, *m22, *m32, *m42, + *m13, *m23, *m33, *m43, + *m14, *m24, *m34, *m44, )), is_2d: Cell::new(false), }) @@ -633,10 +638,10 @@ impl DOMMatrixInner { } #[setter] - pub fn a(&self, #[webidl] value: f64) { + pub fn a(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_A) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_A) = *value; } } @@ -648,10 +653,10 @@ impl DOMMatrixInner { } #[setter] - pub fn b(&self, #[webidl] value: f64) { + pub fn b(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_B) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_B) = *value; } } @@ -663,10 +668,10 @@ impl DOMMatrixInner { } #[setter] - pub fn c(&self, #[webidl] value: f64) { + pub fn c(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_C) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_C) = *value; } } @@ -678,10 +683,10 @@ impl DOMMatrixInner { } #[setter] - pub fn d(&self, #[webidl] value: f64) { + pub fn d(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_D) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_D) = *value; } } @@ -693,10 +698,10 @@ impl DOMMatrixInner { } #[setter] - pub fn e(&self, #[webidl] value: f64) { + pub fn e(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_E) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_E) = *value; } } @@ -708,10 +713,10 @@ impl DOMMatrixInner { } #[setter] - pub fn f(&self, #[webidl] value: f64) { + pub fn f(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_F) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_F) = *value; } } @@ -723,10 +728,10 @@ impl DOMMatrixInner { } #[setter] - pub fn m11(&self, #[webidl] value: f64) { + pub fn m11(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M11) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M11) = *value; } } @@ -738,10 +743,10 @@ impl DOMMatrixInner { } #[setter] - pub fn m12(&self, #[webidl] value: f64) { + pub fn m12(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M12) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M12) = *value; } } @@ -753,12 +758,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m13(&self, #[webidl] value: f64) { + pub fn m13(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M13) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M13) = *value; } - if value != 0.0 { + if *value != 0.0 { self.is_2d.set(false); } } @@ -771,12 +776,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m14(&self, #[webidl] value: f64) { + pub fn m14(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M14) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M14) = *value; } - if value != 0.0 { + if *value != 0.0 { self.is_2d.set(false); } } @@ -789,10 +794,10 @@ impl DOMMatrixInner { } #[setter] - pub fn m21(&self, #[webidl] value: f64) { + pub fn m21(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M21) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M21) = *value; } } @@ -804,10 +809,10 @@ impl DOMMatrixInner { } #[setter] - pub fn m22(&self, #[webidl] value: f64) { + pub fn m22(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M22) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M22) = *value; } } @@ -819,12 +824,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m23(&self, #[webidl] value: f64) { + pub fn m23(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M23) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M23) = *value; } - if value != 0.0 { + if *value != 0.0 { self.is_2d.set(false); } } @@ -837,12 +842,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m24(&self, #[webidl] value: f64) { + pub fn m24(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M24) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M24) = *value; } - if value != 0.0 { + if *value != 0.0 { self.is_2d.set(false); } } @@ -855,12 +860,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m31(&self, #[webidl] value: f64) { + pub fn m31(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M31) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M31) = *value; } - if value != 0.0 { + if *value != 0.0 { self.is_2d.set(false); } } @@ -873,12 +878,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m32(&self, #[webidl] value: f64) { + pub fn m32(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M32) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M32) = *value; } - if value != 0.0 { + if *value != 0.0 { self.is_2d.set(false); } } @@ -891,12 +896,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m33(&self, #[webidl] value: f64) { + pub fn m33(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M33) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M33) = *value; } - if value != 1.0 { + if *value != 1.0 { self.is_2d.set(false); } } @@ -909,12 +914,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m34(&self, #[webidl] value: f64) { + pub fn m34(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M34) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M34) = *value; } - if value != 0.0 { + if *value != 0.0 { self.is_2d.set(false); } } @@ -927,10 +932,10 @@ impl DOMMatrixInner { } #[setter] - pub fn m41(&self, #[webidl] value: f64) { + pub fn m41(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M41) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M41) = *value; } } @@ -942,10 +947,10 @@ impl DOMMatrixInner { } #[setter] - pub fn m42(&self, #[webidl] value: f64) { + pub fn m42(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M42) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M42) = *value; } } @@ -957,12 +962,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m43(&self, #[webidl] value: f64) { + pub fn m43(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M43) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M43) = *value; } - if value != 0.0 { + if *value != 0.0 { self.is_2d.set(false); } } @@ -975,12 +980,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m44(&self, #[webidl] value: f64) { + pub fn m44(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M44) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M44) = *value; } - if value != 1.0 { + if *value != 1.0 { self.is_2d.set(false); } } @@ -1041,151 +1046,165 @@ impl DOMMatrixInner { #[cppgc] pub fn translate( &self, - #[webidl] tx: f64, - #[webidl] ty: f64, - #[webidl] tz: f64, + #[webidl] tx: webidl::UnrestrictedDouble, + #[webidl] ty: webidl::UnrestrictedDouble, + #[webidl] tz: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_translate(&out, tx, ty, tz); + matrix_translate(&out, *tx, *ty, *tz); out } pub fn translate_self( &self, - #[webidl] tx: f64, - #[webidl] ty: f64, - #[webidl] tz: f64, + #[webidl] tx: webidl::UnrestrictedDouble, + #[webidl] ty: webidl::UnrestrictedDouble, + #[webidl] tz: webidl::UnrestrictedDouble, ) { - matrix_translate(self, tx, ty, tz); + matrix_translate(self, *tx, *ty, *tz); } #[cppgc] pub fn scale_without_origin( &self, - #[webidl] sx: f64, - #[webidl] sy: f64, - #[webidl] sz: f64, + #[webidl] sx: webidl::UnrestrictedDouble, + #[webidl] sy: webidl::UnrestrictedDouble, + #[webidl] sz: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_scale_without_origin(&out, sx, sy, sz); + matrix_scale_without_origin(&out, *sx, *sy, *sz); out } pub fn scale_without_origin_self( &self, - #[webidl] sx: f64, - #[webidl] sy: f64, - #[webidl] sz: f64, + #[webidl] sx: webidl::UnrestrictedDouble, + #[webidl] sy: webidl::UnrestrictedDouble, + #[webidl] sz: webidl::UnrestrictedDouble, ) { - matrix_scale_without_origin(self, sx, sy, sz); + matrix_scale_without_origin(self, *sx, *sy, *sz); } #[cppgc] pub fn scale_with_origin( &self, - #[webidl] sx: f64, - #[webidl] sy: f64, - #[webidl] sz: f64, - #[webidl] origin_x: f64, - #[webidl] origin_y: f64, - #[webidl] origin_z: f64, + #[webidl] sx: webidl::UnrestrictedDouble, + #[webidl] sy: webidl::UnrestrictedDouble, + #[webidl] sz: webidl::UnrestrictedDouble, + #[webidl] origin_x: webidl::UnrestrictedDouble, + #[webidl] origin_y: webidl::UnrestrictedDouble, + #[webidl] origin_z: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_scale_with_origin(&out, sx, sy, sz, origin_x, origin_y, origin_z); + matrix_scale_with_origin( + &out, *sx, *sy, *sz, *origin_x, *origin_y, *origin_z, + ); out } pub fn scale_with_origin_self( &self, - #[webidl] sx: f64, - #[webidl] sy: f64, - #[webidl] sz: f64, - #[webidl] origin_x: f64, - #[webidl] origin_y: f64, - #[webidl] origin_z: f64, + #[webidl] sx: webidl::UnrestrictedDouble, + #[webidl] sy: webidl::UnrestrictedDouble, + #[webidl] sz: webidl::UnrestrictedDouble, + #[webidl] origin_x: webidl::UnrestrictedDouble, + #[webidl] origin_y: webidl::UnrestrictedDouble, + #[webidl] origin_z: webidl::UnrestrictedDouble, ) { - matrix_scale_with_origin(self, sx, sy, sz, origin_x, origin_y, origin_z); + matrix_scale_with_origin( + self, *sx, *sy, *sz, *origin_x, *origin_y, *origin_z, + ); } #[cppgc] pub fn rotate( &self, - #[webidl] roll_deg: f64, - #[webidl] pitch_deg: f64, - #[webidl] yaw_deg: f64, + #[webidl] roll_deg: webidl::UnrestrictedDouble, + #[webidl] pitch_deg: webidl::UnrestrictedDouble, + #[webidl] yaw_deg: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_rotate(&out, roll_deg, pitch_deg, yaw_deg); + matrix_rotate(&out, *roll_deg, *pitch_deg, *yaw_deg); out } pub fn rotate_self( &self, - #[webidl] roll_deg: f64, - #[webidl] pitch_deg: f64, - #[webidl] yaw_deg: f64, + #[webidl] roll_deg: webidl::UnrestrictedDouble, + #[webidl] pitch_deg: webidl::UnrestrictedDouble, + #[webidl] yaw_deg: webidl::UnrestrictedDouble, ) { - matrix_rotate(self, roll_deg, pitch_deg, yaw_deg); + matrix_rotate(self, *roll_deg, *pitch_deg, *yaw_deg); } #[cppgc] pub fn rotate_from_vector( &self, - #[webidl] x: f64, - #[webidl] y: f64, + #[webidl] x: webidl::UnrestrictedDouble, + #[webidl] y: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_rotate_from_vector(&out, x, y); + matrix_rotate_from_vector(&out, *x, *y); out } - pub fn rotate_from_vector_self(&self, #[webidl] x: f64, #[webidl] y: f64) { - matrix_rotate_from_vector(self, x, y); + pub fn rotate_from_vector_self( + &self, + #[webidl] x: webidl::UnrestrictedDouble, + #[webidl] y: webidl::UnrestrictedDouble, + ) { + matrix_rotate_from_vector(self, *x, *y); } #[cppgc] pub fn rotate_axis_angle( &self, - #[webidl] x: f64, - #[webidl] y: f64, - #[webidl] z: f64, - #[webidl] angle_deg: f64, + #[webidl] x: webidl::UnrestrictedDouble, + #[webidl] y: webidl::UnrestrictedDouble, + #[webidl] z: webidl::UnrestrictedDouble, + #[webidl] angle_deg: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_rotate_axis_angle(&out, x, y, z, angle_deg); + matrix_rotate_axis_angle(&out, *x, *y, *z, *angle_deg); out } pub fn rotate_axis_angle_self( &self, - #[webidl] x: f64, - #[webidl] y: f64, - #[webidl] z: f64, - #[webidl] angle_deg: f64, + #[webidl] x: webidl::UnrestrictedDouble, + #[webidl] y: webidl::UnrestrictedDouble, + #[webidl] z: webidl::UnrestrictedDouble, + #[webidl] angle_deg: webidl::UnrestrictedDouble, ) { - matrix_rotate_axis_angle(self, x, y, z, angle_deg); + matrix_rotate_axis_angle(self, *x, *y, *z, *angle_deg); } #[cppgc] - pub fn skew_x(&self, #[webidl] x_deg: f64) -> DOMMatrixInner { + pub fn skew_x( + &self, + #[webidl] x_deg: webidl::UnrestrictedDouble, + ) -> DOMMatrixInner { let out = self.clone(); - matrix_skew_x(&out, x_deg); + matrix_skew_x(&out, *x_deg); out } - pub fn skew_x_self(&self, #[webidl] x_deg: f64) { - matrix_skew_x(self, x_deg); + pub fn skew_x_self(&self, #[webidl] x_deg: webidl::UnrestrictedDouble) { + matrix_skew_x(self, *x_deg); } #[cppgc] - pub fn skew_y(&self, #[webidl] y_deg: f64) -> DOMMatrixInner { + pub fn skew_y( + &self, + #[webidl] y_deg: webidl::UnrestrictedDouble, + ) -> DOMMatrixInner { let out = self.clone(); - matrix_skew_y(&out, y_deg); + matrix_skew_y(&out, *y_deg); out } - pub fn skew_y_self(&self, #[webidl] y_deg: f64) { - matrix_skew_y(self, y_deg); + pub fn skew_y_self(&self, #[webidl] y_deg: webidl::UnrestrictedDouble) { + matrix_skew_y(self, *y_deg); } #[cppgc] @@ -1264,6 +1283,44 @@ impl DOMMatrixInner { } } +// TODO(petamoriken) Use f64::maximum instead https://github.com/rust-lang/rust/issues/91079 +#[inline] +fn maximum(a: f64, b: f64) -> f64 { + if a > b { + a + } else if b > a { + b + } else if a == b { + if a.is_sign_positive() && b.is_sign_negative() { + a + } else { + b + } + } else { + // At least one input is NaN. Use `+` to perform NaN propagation and quieting. + a + b + } +} + +// TODO(petamoriken) Use f64::minimum instead https://github.com/rust-lang/rust/issues/91079 +#[inline] +fn minimum(a: f64, b: f64) -> f64 { + if a < b { + a + } else if b < a { + b + } else if a == b { + if a.is_sign_negative() && b.is_sign_positive() { + a + } else { + b + } + } else { + // At least one input is NaN. Use `+` to perform NaN propagation and quieting. + a + b + } +} + #[inline] fn matrix_translate(matrix: &DOMMatrixInner, tx: f64, ty: f64, tz: f64) { let mut inner = matrix.inner.borrow_mut(); From 416959239867360c45f2a417c960c52f8fb81640 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 13 Jan 2025 13:03:34 +0900 Subject: [PATCH 15/63] fix --- ext/geometry/lib.rs | 44 ++++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 0af1871a6af4fd..72a396dada7468 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -9,7 +9,6 @@ use std::ptr; use std::slice; use deno_core::op2; -use deno_core::v8; use deno_core::webidl; use deno_core::GarbageCollected; use deno_core::WebIDL; @@ -54,6 +53,7 @@ pub struct DOMPointInit { w: webidl::UnrestrictedDouble, } +#[derive(Debug)] pub struct DOMPointInner { inner: RefCell>, } @@ -130,15 +130,12 @@ impl DOMPointInner { #[cppgc] pub fn matrix_transform( &self, - matrix: v8::Local, + #[cppgc] matrix: &DOMMatrixInner, ) -> DOMPointInner { - // SAFETY: cast v8::Local - let matrix: v8::Local<'_, DOMMatrixInner> = - unsafe { mem::transmute(matrix) }; let out = DOMPointInner { inner: RefCell::new(Vector4::zeros()), }; - matrix_transform_point(&matrix, self, &out); + matrix_transform_point(matrix, self, &out); out } } @@ -156,6 +153,7 @@ pub struct DOMRectInit { height: webidl::UnrestrictedDouble, } +#[derive(Debug)] pub struct DOMRectInner { x: Cell, y: Cell, @@ -280,6 +278,7 @@ pub struct DOMQuadInit { p4: DOMPointInit, } +#[derive(Debug)] pub struct DOMQuadInner { p1: UnsafeCell, p2: UnsafeCell, @@ -467,7 +466,7 @@ pub struct DOMMatrixInit { is_2d: Option, } -#[derive(Clone)] +#[derive(Debug, Clone)] pub struct DOMMatrixInner { inner: RefCell>, is_2d: Cell, @@ -1208,39 +1207,33 @@ impl DOMMatrixInner { } #[cppgc] - pub fn multiply(&self, other: v8::Local) -> DOMMatrixInner { - // SAFETY: cast v8::Local - let other: v8::Local<'_, DOMMatrixInner> = unsafe { mem::transmute(other) }; + pub fn multiply(&self, #[cppgc] other: &DOMMatrixInner) -> DOMMatrixInner { let out = DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), }; - matrix_multiply(&out, self, &other); + matrix_multiply(&out, self, other); out } #[fast] - pub fn multiply_self(&self, other: v8::Local) { - // SAFETY: cast v8::Local - let other: v8::Local<'_, DOMMatrixInner> = unsafe { mem::transmute(other) }; + pub fn multiply_self(&self, #[cppgc] other: &DOMMatrixInner) { let result = DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), }; - matrix_multiply(&result, self, &other); + matrix_multiply(&result, self, other); self.inner.borrow_mut().copy_from(&result.inner.borrow()); self.is_2d.set(result.is_2d.get()); } #[fast] - pub fn pre_multiply_self(&self, other: v8::Local) { - // SAFETY: cast v8::Local - let other: v8::Local<'_, DOMMatrixInner> = unsafe { mem::transmute(other) }; + pub fn pre_multiply_self(&self, #[cppgc] other: &DOMMatrixInner) { let result = DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), }; - matrix_multiply(&result, &other, self); + matrix_multiply(&result, other, self); self.inner.borrow_mut().copy_from(&result.inner.borrow()); self.is_2d.set(result.is_2d.get()); } @@ -1272,13 +1265,14 @@ impl DOMMatrixInner { } #[cppgc] - pub fn transform_point(&self, point: v8::Local) -> DOMPointInner { - // SAFETY: cast v8::Local - let point: v8::Local<'_, DOMPointInner> = unsafe { mem::transmute(point) }; + pub fn transform_point( + &self, + #[cppgc] point: &DOMPointInner, + ) -> DOMPointInner { let out = DOMPointInner { inner: RefCell::new(Vector4::zeros()), }; - matrix_transform_point(self, &point, &out); + matrix_transform_point(self, point, &out); out } } @@ -1461,9 +1455,7 @@ fn matrix_multiply( let rhs_inner = rhs.inner.borrow(); let rhs_is_2d = rhs.is_2d.get(); let mut out_inner = out.inner.borrow_mut(); - let mut result = Matrix4::zeros(); - lhs_inner.mul_to(&rhs_inner, &mut result); - out_inner.copy_from(&result); + lhs_inner.mul_to(&rhs_inner, &mut out_inner); out.is_2d.set(lhs_is_2d && rhs_is_2d); } From c16c83252b18d2b72efe3eef2dbb0e983504f80c Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 13 Jan 2025 23:33:10 +0900 Subject: [PATCH 16/63] fix --- ext/geometry/01_geometry.js | 4 ++-- ext/geometry/lib.rs | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index db7beec3faea40..81ed2c5f18c0db 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -159,7 +159,7 @@ class DOMPoint extends DOMPointReadOnly { set w(value) { webidl.assertBranded(this, DOMPointPrototype); assertWritable(this); - this[_inner].x = value; + this[_inner].w = value; } [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { @@ -442,7 +442,7 @@ class DOMQuad { webidl.assertBranded(this, DOMQuadPrototype); const bounds = webidl.createBranded(DOMRect); bounds[_writable] = true; - bounds[_inner] = this[_inner].fromBounds(); + bounds[_inner] = this[_inner].getBounds(); return bounds; } diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 72a396dada7468..9bddb827615c4b 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -75,6 +75,7 @@ impl DOMPointInner { } } + #[reentrant] #[static_method] #[cppgc] pub fn from_point(#[webidl] init: DOMPointInit) -> DOMPointInner { @@ -181,6 +182,7 @@ impl DOMRectInner { } } + #[reentrant] #[static_method] #[cppgc] pub fn from_rect(#[webidl] init: DOMRectInit) -> DOMRectInner { @@ -291,6 +293,7 @@ impl GarbageCollected for DOMQuadInner {} #[op2] impl DOMQuadInner { #[constructor] + #[reentrant] #[cppgc] pub fn constructor( #[webidl] p1: DOMPointInit, @@ -315,6 +318,7 @@ impl DOMQuadInner { } } + #[reentrant] #[static_method] #[cppgc] pub fn from_rect(#[webidl] rect: DOMRectInit) -> DOMQuadInner { @@ -340,6 +344,7 @@ impl DOMQuadInner { } } + #[reentrant] #[static_method] #[cppgc] pub fn from_quad(#[webidl] quad: DOMQuadInit) -> DOMQuadInner { @@ -527,6 +532,7 @@ impl DOMMatrixInner { } } + #[reentrant] #[static_method] #[cppgc] pub fn from_matrix( @@ -1335,7 +1341,7 @@ fn matrix_scale_without_origin( let is_2d = matrix.is_2d.get(); let scaling = Vector3::new(sx, sy, sz); inner.prepend_nonuniform_scaling_mut(&scaling); - matrix.is_2d.set(is_2d && sz == 0.0); + matrix.is_2d.set(is_2d && sz == 1.0); } #[inline] @@ -1356,7 +1362,7 @@ fn matrix_scale_with_origin( inner.prepend_nonuniform_scaling_mut(&scaling); shift.neg_mut(); inner.prepend_translation_mut(&shift); - matrix.is_2d.set(is_2d && sz == 0.0 && origin_z == 0.0); + matrix.is_2d.set(is_2d && sz == 1.0 && origin_z == 0.0); } #[inline] @@ -1381,7 +1387,7 @@ fn matrix_rotate( inner.set_column(2, &result.column(2)); matrix .is_2d - .set(is_2d && pitch_deg == 0.0 && yaw_deg == 0.0); + .set(is_2d && roll_deg == 0.0 && pitch_deg == 0.0); } #[inline] From 41cce868a4a663bedbc826121c80842e6d0183ae Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 14 Jan 2025 02:12:11 +0900 Subject: [PATCH 17/63] tweak --- ext/geometry/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 9bddb827615c4b..2a3c12579102f1 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -40,7 +40,7 @@ pub enum GeometryError { Inconsistent2DMatrix, } -#[derive(WebIDL)] +#[derive(WebIDL, Debug)] #[webidl(dictionary)] pub struct DOMPointInit { #[webidl(default = webidl::UnrestrictedDouble(0.0))] @@ -141,7 +141,7 @@ impl DOMPointInner { } } -#[derive(WebIDL)] +#[derive(WebIDL, Debug)] #[webidl(dictionary)] pub struct DOMRectInit { #[webidl(default = webidl::UnrestrictedDouble(0.0))] @@ -271,7 +271,7 @@ impl DOMRectInner { } } -#[derive(WebIDL)] +#[derive(WebIDL, Debug)] #[webidl(dictionary)] pub struct DOMQuadInit { p1: DOMPointInit, @@ -420,7 +420,7 @@ impl DOMQuadInner { } } -#[derive(WebIDL)] +#[derive(WebIDL, Debug)] #[webidl(dictionary)] pub struct DOMMatrixInit { #[webidl(default = None)] From 4f1d78337ff3d7c5ec7b32e4f07db4956813fffd Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 14 Jan 2025 06:33:59 +0900 Subject: [PATCH 18/63] tweak --- runtime/errors.rs | 1969 --------------------------------------------- 1 file changed, 1969 deletions(-) delete mode 100644 runtime/errors.rs diff --git a/runtime/errors.rs b/runtime/errors.rs deleted file mode 100644 index f441e58671eaae..00000000000000 --- a/runtime/errors.rs +++ /dev/null @@ -1,1969 +0,0 @@ -// Copyright 2018-2025 the Deno authors. MIT license. - -//! There are many types of errors in Deno: -//! - AnyError: a generic wrapper that can encapsulate any type of error. -//! - JsError: a container for the error message and stack trace for exceptions -//! thrown in JavaScript code. We use this to pretty-print stack traces. -//! - Diagnostic: these are errors that originate in TypeScript's compiler. -//! They're similar to JsError, in that they have line numbers. But -//! Diagnostics are compile-time type errors, whereas JsErrors are runtime -//! exceptions. - -use std::env; -use std::error::Error; -use std::io; -use std::sync::Arc; - -use deno_broadcast_channel::BroadcastChannelError; -use deno_cache::CacheError; -use deno_canvas::CanvasError; -use deno_core::error::AnyError; -use deno_core::serde_json; -use deno_core::url; -use deno_core::ModuleResolutionError; -use deno_cron::CronError; -use deno_crypto::DecryptError; -use deno_crypto::EncryptError; -use deno_crypto::ExportKeyError; -use deno_crypto::GenerateKeyError; -use deno_crypto::ImportKeyError; -use deno_fetch::FetchError; -use deno_fetch::HttpClientCreateError; -use deno_ffi::CallError; -use deno_ffi::CallbackError; -use deno_ffi::DlfcnError; -use deno_ffi::IRError; -use deno_ffi::ReprError; -use deno_ffi::StaticError; -use deno_fs::FsOpsError; -use deno_fs::FsOpsErrorKind; -use deno_geometry::GeometryError; -use deno_http::HttpError; -use deno_http::HttpNextError; -use deno_http::WebSocketUpgradeError; -use deno_io::fs::FsError; -use deno_kv::KvCheckError; -use deno_kv::KvError; -use deno_kv::KvErrorKind; -use deno_kv::KvMutationError; -use deno_napi::NApiError; -use deno_net::ops::NetError; -use deno_permissions::ChildPermissionError; -use deno_permissions::NetDescriptorFromUrlParseError; -use deno_permissions::PathResolveError; -use deno_permissions::PermissionCheckError; -use deno_permissions::RunDescriptorParseError; -use deno_permissions::SysDescriptorParseError; -use deno_tls::TlsError; -use deno_web::BlobError; -use deno_web::CompressionError; -use deno_web::MessagePortError; -use deno_web::StreamResourceError; -use deno_web::WebError; -use deno_websocket::HandshakeError; -use deno_websocket::WebsocketError; -use deno_webstorage::WebStorageError; -use rustyline::error::ReadlineError; - -use crate::ops::fs_events::FsEventsError; -use crate::ops::http::HttpStartError; -use crate::ops::os::OsError; -use crate::ops::permissions::PermissionError; -use crate::ops::process::CheckRunPermissionError; -use crate::ops::process::ProcessError; -use crate::ops::signal::SignalError; -use crate::ops::tty::TtyError; -use crate::ops::web_worker::SyncFetchError; -use crate::ops::worker_host::CreateWorkerError; - -fn get_run_descriptor_parse_error(e: &RunDescriptorParseError) -> &'static str { - match e { - RunDescriptorParseError::Which(_) => "Error", - RunDescriptorParseError::PathResolve(e) => get_path_resolve_error(e), - RunDescriptorParseError::EmptyRunQuery => "Error", - } -} - -fn get_sys_descriptor_parse_error(e: &SysDescriptorParseError) -> &'static str { - match e { - SysDescriptorParseError::InvalidKind(_) => "TypeError", - SysDescriptorParseError::Empty => "Error", - } -} - -fn get_path_resolve_error(e: &PathResolveError) -> &'static str { - match e { - PathResolveError::CwdResolve(e) => get_io_error_class(e), - PathResolveError::EmptyPath => "Error", - } -} - -fn get_permission_error_class(e: &PermissionError) -> &'static str { - match e { - PermissionError::InvalidPermissionName(_) => "ReferenceError", - PermissionError::PathResolve(e) => get_path_resolve_error(e), - PermissionError::NetDescriptorParse(_) => "URIError", - PermissionError::SysDescriptorParse(e) => get_sys_descriptor_parse_error(e), - PermissionError::RunDescriptorParse(e) => get_run_descriptor_parse_error(e), - } -} - -fn get_permission_check_error_class(e: &PermissionCheckError) -> &'static str { - match e { - PermissionCheckError::PermissionDenied(_) => "NotCapable", - PermissionCheckError::InvalidFilePath(_) => "URIError", - PermissionCheckError::NetDescriptorForUrlParse(e) => match e { - NetDescriptorFromUrlParseError::MissingHost(_) => "TypeError", - NetDescriptorFromUrlParseError::Host(_) => "URIError", - }, - PermissionCheckError::SysDescriptorParse(e) => { - get_sys_descriptor_parse_error(e) - } - PermissionCheckError::PathResolve(e) => get_path_resolve_error(e), - PermissionCheckError::HostParse(_) => "URIError", - } -} - -fn get_dlopen_error_class(error: &dlopen2::Error) -> &'static str { - use dlopen2::Error::*; - match error { - NullCharacter(_) => "InvalidData", - OpeningLibraryError(ref e) => get_io_error_class(e), - SymbolGettingError(ref e) => get_io_error_class(e), - AddrNotMatchingDll(ref e) => get_io_error_class(e), - NullSymbol => "NotFound", - } -} - -fn get_env_var_error_class(error: &env::VarError) -> &'static str { - use env::VarError::*; - match error { - NotPresent => "NotFound", - NotUnicode(..) => "InvalidData", - } -} - -fn get_io_error_class(error: &io::Error) -> &'static str { - use io::ErrorKind::*; - match error.kind() { - NotFound => "NotFound", - PermissionDenied => "PermissionDenied", - ConnectionRefused => "ConnectionRefused", - ConnectionReset => "ConnectionReset", - ConnectionAborted => "ConnectionAborted", - NotConnected => "NotConnected", - AddrInUse => "AddrInUse", - AddrNotAvailable => "AddrNotAvailable", - BrokenPipe => "BrokenPipe", - AlreadyExists => "AlreadyExists", - InvalidInput => "TypeError", - InvalidData => "InvalidData", - TimedOut => "TimedOut", - Interrupted => "Interrupted", - WriteZero => "WriteZero", - UnexpectedEof => "UnexpectedEof", - Other => "Error", - WouldBlock => "WouldBlock", - // Non-exhaustive enum - might add new variants - // in the future - kind => { - let kind_str = kind.to_string(); - match kind_str.as_str() { - "FilesystemLoop" => "FilesystemLoop", - "IsADirectory" => "IsADirectory", - "NetworkUnreachable" => "NetworkUnreachable", - "NotADirectory" => "NotADirectory", - _ => "Error", - } - } - } -} - -fn get_module_resolution_error_class( - _: &ModuleResolutionError, -) -> &'static str { - "URIError" -} - -fn get_notify_error_class(error: ¬ify::Error) -> &'static str { - use notify::ErrorKind::*; - match error.kind { - Generic(_) => "Error", - Io(ref e) => get_io_error_class(e), - PathNotFound => "NotFound", - WatchNotFound => "NotFound", - InvalidConfig(_) => "InvalidData", - MaxFilesWatch => "Error", - } -} - -fn get_regex_error_class(error: ®ex::Error) -> &'static str { - use regex::Error::*; - match error { - Syntax(_) => "SyntaxError", - CompiledTooBig(_) => "RangeError", - _ => "Error", - } -} - -fn get_serde_json_error_class( - error: &serde_json::error::Error, -) -> &'static str { - use deno_core::serde_json::error::*; - match error.classify() { - Category::Io => error - .source() - .and_then(|e| e.downcast_ref::()) - .map(get_io_error_class) - .unwrap(), - Category::Syntax => "SyntaxError", - Category::Data => "InvalidData", - Category::Eof => "UnexpectedEof", - } -} - -fn get_url_parse_error_class(_error: &url::ParseError) -> &'static str { - "URIError" -} - -fn get_hyper_error_class(_error: &hyper::Error) -> &'static str { - "Http" -} - -fn get_hyper_util_error_class( - _error: &hyper_util::client::legacy::Error, -) -> &'static str { - "Http" -} - -fn get_hyper_v014_error_class(_error: &hyper_v014::Error) -> &'static str { - "Http" -} - -#[cfg(unix)] -pub fn get_nix_error_class(error: &nix::Error) -> &'static str { - match error { - nix::Error::ECHILD => "NotFound", - nix::Error::EINVAL => "TypeError", - nix::Error::ENOENT => "NotFound", - nix::Error::ENOTTY => "BadResource", - nix::Error::EPERM => "PermissionDenied", - nix::Error::ESRCH => "NotFound", - nix::Error::ELOOP => "FilesystemLoop", - nix::Error::ENOTDIR => "NotADirectory", - nix::Error::ENETUNREACH => "NetworkUnreachable", - nix::Error::EISDIR => "IsADirectory", - nix::Error::UnknownErrno => "Error", - &nix::Error::ENOTSUP => unreachable!(), - _ => "Error", - } -} - -fn get_webgpu_error_class(e: &deno_webgpu::InitError) -> &'static str { - match e { - deno_webgpu::InitError::Resource(e) => { - get_error_class_name(e).unwrap_or("Error") - } - deno_webgpu::InitError::InvalidAdapter(_) => "Error", - deno_webgpu::InitError::RequestDevice(_) => "DOMExceptionOperationError", - deno_webgpu::InitError::InvalidDevice(_) => "Error", - } -} - -fn get_webgpu_buffer_error_class( - e: &deno_webgpu::buffer::BufferError, -) -> &'static str { - match e { - deno_webgpu::buffer::BufferError::Resource(e) => { - get_error_class_name(e).unwrap_or("Error") - } - deno_webgpu::buffer::BufferError::InvalidUsage => "TypeError", - deno_webgpu::buffer::BufferError::Access(_) => "DOMExceptionOperationError", - } -} - -fn get_webgpu_bundle_error_class( - e: &deno_webgpu::bundle::BundleError, -) -> &'static str { - match e { - deno_webgpu::bundle::BundleError::Resource(e) => { - get_error_class_name(e).unwrap_or("Error") - } - deno_webgpu::bundle::BundleError::InvalidSize => "TypeError", - } -} - -fn get_webgpu_byow_error_class( - e: &deno_webgpu::byow::ByowError, -) -> &'static str { - match e { - deno_webgpu::byow::ByowError::WebGPUNotInitiated => "TypeError", - deno_webgpu::byow::ByowError::InvalidParameters => "TypeError", - deno_webgpu::byow::ByowError::CreateSurface(_) => "Error", - deno_webgpu::byow::ByowError::InvalidSystem => "TypeError", - #[cfg(any( - target_os = "windows", - target_os = "linux", - target_os = "freebsd", - target_os = "openbsd" - ))] - deno_webgpu::byow::ByowError::NullWindow => "TypeError", - #[cfg(any( - target_os = "linux", - target_os = "freebsd", - target_os = "openbsd" - ))] - deno_webgpu::byow::ByowError::NullDisplay => "TypeError", - #[cfg(target_os = "macos")] - deno_webgpu::byow::ByowError::NSViewDisplay => "TypeError", - } -} - -fn get_webgpu_render_pass_error_class( - e: &deno_webgpu::render_pass::RenderPassError, -) -> &'static str { - match e { - deno_webgpu::render_pass::RenderPassError::Resource(e) => { - get_error_class_name(e).unwrap_or("Error") - } - deno_webgpu::render_pass::RenderPassError::InvalidSize => "TypeError", - } -} - -fn get_webgpu_surface_error_class( - e: &deno_webgpu::surface::SurfaceError, -) -> &'static str { - match e { - deno_webgpu::surface::SurfaceError::Resource(e) => { - get_error_class_name(e).unwrap_or("Error") - } - deno_webgpu::surface::SurfaceError::Surface(_) => "Error", - deno_webgpu::surface::SurfaceError::InvalidStatus => "Error", - } -} - -fn get_crypto_decrypt_error_class(e: &DecryptError) -> &'static str { - match e { - DecryptError::General(e) => get_crypto_shared_error_class(e), - DecryptError::Pkcs1(_) => "Error", - DecryptError::Failed => "DOMExceptionOperationError", - DecryptError::InvalidLength => "TypeError", - DecryptError::InvalidCounterLength => "TypeError", - DecryptError::InvalidTagLength => "TypeError", - DecryptError::InvalidKeyOrIv => "DOMExceptionOperationError", - DecryptError::TooMuchData => "DOMExceptionOperationError", - DecryptError::InvalidIvLength => "TypeError", - DecryptError::Rsa(_) => "DOMExceptionOperationError", - } -} - -fn get_crypto_encrypt_error_class(e: &EncryptError) -> &'static str { - match e { - EncryptError::General(e) => get_crypto_shared_error_class(e), - EncryptError::InvalidKeyOrIv => "DOMExceptionOperationError", - EncryptError::Failed => "DOMExceptionOperationError", - EncryptError::InvalidLength => "TypeError", - EncryptError::InvalidIvLength => "TypeError", - EncryptError::InvalidCounterLength => "TypeError", - EncryptError::TooMuchData => "DOMExceptionOperationError", - } -} - -fn get_crypto_shared_error_class(e: &deno_crypto::SharedError) -> &'static str { - match e { - deno_crypto::SharedError::ExpectedValidPrivateKey => "TypeError", - deno_crypto::SharedError::ExpectedValidPublicKey => "TypeError", - deno_crypto::SharedError::ExpectedValidPrivateECKey => "TypeError", - deno_crypto::SharedError::ExpectedValidPublicECKey => "TypeError", - deno_crypto::SharedError::ExpectedPrivateKey => "TypeError", - deno_crypto::SharedError::ExpectedPublicKey => "TypeError", - deno_crypto::SharedError::ExpectedSecretKey => "TypeError", - deno_crypto::SharedError::FailedDecodePrivateKey => { - "DOMExceptionOperationError" - } - deno_crypto::SharedError::FailedDecodePublicKey => { - "DOMExceptionOperationError" - } - deno_crypto::SharedError::UnsupportedFormat => { - "DOMExceptionNotSupportedError" - } - } -} - -fn get_crypto_ed25519_error_class( - e: &deno_crypto::Ed25519Error, -) -> &'static str { - match e { - deno_crypto::Ed25519Error::FailedExport => "DOMExceptionOperationError", - deno_crypto::Ed25519Error::Der(_) => "Error", - deno_crypto::Ed25519Error::KeyRejected(_) => "Error", - } -} - -fn get_crypto_export_key_error_class(e: &ExportKeyError) -> &'static str { - match e { - ExportKeyError::General(e) => get_crypto_shared_error_class(e), - ExportKeyError::Der(_) => "Error", - ExportKeyError::UnsupportedNamedCurve => "DOMExceptionNotSupportedError", - } -} - -fn get_crypto_generate_key_error_class(e: &GenerateKeyError) -> &'static str { - match e { - GenerateKeyError::General(e) => get_crypto_shared_error_class(e), - GenerateKeyError::BadPublicExponent => "DOMExceptionOperationError", - GenerateKeyError::InvalidHMACKeyLength => "DOMExceptionOperationError", - GenerateKeyError::FailedRSAKeySerialization => "DOMExceptionOperationError", - GenerateKeyError::InvalidAESKeyLength => "DOMExceptionOperationError", - GenerateKeyError::FailedRSAKeyGeneration => "DOMExceptionOperationError", - GenerateKeyError::FailedECKeyGeneration => "DOMExceptionOperationError", - GenerateKeyError::FailedKeyGeneration => "DOMExceptionOperationError", - } -} - -fn get_crypto_import_key_error_class(e: &ImportKeyError) -> &'static str { - match e { - ImportKeyError::General(e) => get_crypto_shared_error_class(e), - ImportKeyError::InvalidModulus => "DOMExceptionDataError", - ImportKeyError::InvalidPublicExponent => "DOMExceptionDataError", - ImportKeyError::InvalidPrivateExponent => "DOMExceptionDataError", - ImportKeyError::InvalidFirstPrimeFactor => "DOMExceptionDataError", - ImportKeyError::InvalidSecondPrimeFactor => "DOMExceptionDataError", - ImportKeyError::InvalidFirstCRTExponent => "DOMExceptionDataError", - ImportKeyError::InvalidSecondCRTExponent => "DOMExceptionDataError", - ImportKeyError::InvalidCRTCoefficient => "DOMExceptionDataError", - ImportKeyError::InvalidB64Coordinate => "DOMExceptionDataError", - ImportKeyError::InvalidRSAPublicKey => "DOMExceptionDataError", - ImportKeyError::InvalidRSAPrivateKey => "DOMExceptionDataError", - ImportKeyError::UnsupportedAlgorithm => "DOMExceptionDataError", - ImportKeyError::PublicKeyTooLong => "DOMExceptionDataError", - ImportKeyError::PrivateKeyTooLong => "DOMExceptionDataError", - ImportKeyError::InvalidP256ECPoint => "DOMExceptionDataError", - ImportKeyError::InvalidP384ECPoint => "DOMExceptionDataError", - ImportKeyError::InvalidP521ECPoint => "DOMExceptionDataError", - ImportKeyError::UnsupportedNamedCurve => "DOMExceptionDataError", - ImportKeyError::CurveMismatch => "DOMExceptionDataError", - ImportKeyError::InvalidKeyData => "DOMExceptionDataError", - ImportKeyError::InvalidJWKPrivateKey => "DOMExceptionDataError", - ImportKeyError::EllipticCurve(_) => "DOMExceptionDataError", - ImportKeyError::ExpectedValidPkcs8Data => "DOMExceptionDataError", - ImportKeyError::MalformedParameters => "DOMExceptionDataError", - ImportKeyError::Spki(_) => "DOMExceptionDataError", - ImportKeyError::InvalidP256ECSPKIData => "DOMExceptionDataError", - ImportKeyError::InvalidP384ECSPKIData => "DOMExceptionDataError", - ImportKeyError::InvalidP521ECSPKIData => "DOMExceptionDataError", - ImportKeyError::Der(_) => "DOMExceptionDataError", - } -} - -fn get_crypto_x448_error_class(e: &deno_crypto::X448Error) -> &'static str { - match e { - deno_crypto::X448Error::FailedExport => "DOMExceptionOperationError", - deno_crypto::X448Error::Der(_) => "Error", - } -} - -fn get_crypto_x25519_error_class(e: &deno_crypto::X25519Error) -> &'static str { - match e { - deno_crypto::X25519Error::FailedExport => "DOMExceptionOperationError", - deno_crypto::X25519Error::Der(_) => "Error", - } -} - -fn get_crypto_error_class(e: &deno_crypto::Error) -> &'static str { - match e { - deno_crypto::Error::Der(_) => "Error", - deno_crypto::Error::JoinError(_) => "Error", - deno_crypto::Error::MissingArgumentHash => "TypeError", - deno_crypto::Error::MissingArgumentSaltLength => "TypeError", - deno_crypto::Error::Other(e) => get_error_class_name(e).unwrap_or("Error"), - deno_crypto::Error::UnsupportedAlgorithm => "TypeError", - deno_crypto::Error::KeyRejected(_) => "Error", - deno_crypto::Error::RSA(_) => "Error", - deno_crypto::Error::Pkcs1(_) => "Error", - deno_crypto::Error::Unspecified(_) => "Error", - deno_crypto::Error::InvalidKeyFormat => "TypeError", - deno_crypto::Error::MissingArgumentPublicKey => "TypeError", - deno_crypto::Error::P256Ecdsa(_) => "Error", - deno_crypto::Error::DecodePrivateKey => "TypeError", - deno_crypto::Error::MissingArgumentNamedCurve => "TypeError", - deno_crypto::Error::MissingArgumentInfo => "TypeError", - deno_crypto::Error::HKDFLengthTooLarge => "DOMExceptionOperationError", - deno_crypto::Error::General(e) => get_crypto_shared_error_class(e), - deno_crypto::Error::Base64Decode(_) => "Error", - deno_crypto::Error::DataInvalidSize => "TypeError", - deno_crypto::Error::InvalidKeyLength => "TypeError", - deno_crypto::Error::EncryptionError => "DOMExceptionOperationError", - deno_crypto::Error::DecryptionError => "DOMExceptionOperationError", - deno_crypto::Error::ArrayBufferViewLengthExceeded(_) => { - "DOMExceptionQuotaExceededError" - } - } -} - -fn get_napi_error_class(e: &NApiError) -> &'static str { - match e { - NApiError::InvalidPath - | NApiError::LibLoading(_) - | NApiError::ModuleNotFound(_) => "TypeError", - NApiError::Permission(e) => get_permission_check_error_class(e), - } -} - -fn get_web_error_class(e: &WebError) -> &'static str { - match e { - WebError::Base64Decode => "DOMExceptionInvalidCharacterError", - WebError::InvalidEncodingLabel(_) => "RangeError", - WebError::BufferTooLong => "TypeError", - WebError::ValueTooLarge => "RangeError", - WebError::BufferTooSmall => "RangeError", - WebError::DataInvalid => "TypeError", - WebError::DataError(_) => "Error", - } -} - -fn get_web_compression_error_class(e: &CompressionError) -> &'static str { - match e { - CompressionError::UnsupportedFormat => "TypeError", - CompressionError::ResourceClosed => "TypeError", - CompressionError::IoTypeError(_) => "TypeError", - CompressionError::Io(e) => get_io_error_class(e), - } -} - -fn get_web_message_port_error_class(e: &MessagePortError) -> &'static str { - match e { - MessagePortError::InvalidTransfer => "TypeError", - MessagePortError::NotReady => "TypeError", - MessagePortError::TransferSelf => "TypeError", - MessagePortError::Canceled(e) => { - let io_err: io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - } - MessagePortError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - } -} - -fn get_web_stream_resource_error_class( - e: &StreamResourceError, -) -> &'static str { - match e { - StreamResourceError::Canceled(e) => { - let io_err: io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - } - StreamResourceError::Js(_) => "TypeError", - } -} - -fn get_web_blob_error_class(e: &BlobError) -> &'static str { - match e { - BlobError::BlobPartNotFound => "TypeError", - BlobError::SizeLargerThanBlobPart => "TypeError", - BlobError::BlobURLsNotSupported => "TypeError", - BlobError::Url(_) => "Error", - } -} - -fn get_ffi_repr_error_class(e: &ReprError) -> &'static str { - match e { - ReprError::InvalidOffset => "TypeError", - ReprError::InvalidArrayBuffer => "TypeError", - ReprError::DestinationLengthTooShort => "RangeError", - ReprError::InvalidCString => "TypeError", - ReprError::CStringTooLong => "TypeError", - ReprError::InvalidBool => "TypeError", - ReprError::InvalidU8 => "TypeError", - ReprError::InvalidI8 => "TypeError", - ReprError::InvalidU16 => "TypeError", - ReprError::InvalidI16 => "TypeError", - ReprError::InvalidU32 => "TypeError", - ReprError::InvalidI32 => "TypeError", - ReprError::InvalidU64 => "TypeError", - ReprError::InvalidI64 => "TypeError", - ReprError::InvalidF32 => "TypeError", - ReprError::InvalidF64 => "TypeError", - ReprError::InvalidPointer => "TypeError", - ReprError::Permission(e) => get_permission_check_error_class(e), - } -} - -fn get_ffi_dlfcn_error_class(e: &DlfcnError) -> &'static str { - match e { - DlfcnError::RegisterSymbol { .. } => "Error", - DlfcnError::Dlopen(_) => "Error", - DlfcnError::Permission(e) => get_permission_check_error_class(e), - DlfcnError::Other(e) => get_error_class_name(e).unwrap_or("Error"), - } -} - -fn get_ffi_static_error_class(e: &StaticError) -> &'static str { - match e { - StaticError::Dlfcn(e) => get_ffi_dlfcn_error_class(e), - StaticError::InvalidTypeVoid => "TypeError", - StaticError::InvalidTypeStruct => "TypeError", - StaticError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - } -} - -fn get_ffi_callback_error_class(e: &CallbackError) -> &'static str { - match e { - CallbackError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - CallbackError::Other(e) => get_error_class_name(e).unwrap_or("Error"), - CallbackError::Permission(e) => get_permission_check_error_class(e), - } -} - -fn get_ffi_call_error_class(e: &CallError) -> &'static str { - match e { - CallError::IR(_) => "TypeError", - CallError::NonblockingCallFailure(_) => "Error", - CallError::InvalidSymbol(_) => "TypeError", - CallError::Permission(e) => get_permission_check_error_class(e), - CallError::Callback(e) => get_ffi_callback_error_class(e), - CallError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - } -} - -fn get_webstorage_class_name(e: &WebStorageError) -> &'static str { - match e { - WebStorageError::ContextNotSupported => "DOMExceptionNotSupportedError", - WebStorageError::Sqlite(_) => "Error", - WebStorageError::Io(e) => get_io_error_class(e), - WebStorageError::StorageExceeded => "DOMExceptionQuotaExceededError", - } -} - -fn get_tls_error_class(e: &TlsError) -> &'static str { - match e { - TlsError::Rustls(_) => "Error", - TlsError::UnableAddPemFileToCert(e) => get_io_error_class(e), - TlsError::CertInvalid - | TlsError::CertsNotFound - | TlsError::KeysNotFound - | TlsError::KeyDecode => "InvalidData", - } -} - -pub fn get_cron_error_class(e: &CronError) -> &'static str { - match e { - CronError::Resource(e) => { - deno_core::error::get_custom_error_class(e).unwrap_or("Error") - } - CronError::NameExceeded(_) => "TypeError", - CronError::NameInvalid => "TypeError", - CronError::AlreadyExists => "TypeError", - CronError::TooManyCrons => "TypeError", - CronError::InvalidCron => "TypeError", - CronError::InvalidBackoff => "TypeError", - CronError::AcquireError(_) => "Error", - CronError::Other(e) => get_error_class_name(e).unwrap_or("Error"), - } -} - -fn get_canvas_error(e: &CanvasError) -> &'static str { - match e { - CanvasError::UnsupportedColorType(_) => "TypeError", - CanvasError::Image(_) => "Error", - } -} - -pub fn get_cache_error(error: &CacheError) -> &'static str { - match error { - CacheError::Sqlite(_) => "Error", - CacheError::JoinError(_) => "Error", - CacheError::Resource(err) => { - deno_core::error::get_custom_error_class(err).unwrap_or("Error") - } - CacheError::Other(e) => get_error_class_name(e).unwrap_or("Error"), - CacheError::Io(err) => get_io_error_class(err), - } -} - -fn get_broadcast_channel_error(error: &BroadcastChannelError) -> &'static str { - match error { - BroadcastChannelError::Resource(err) => { - deno_core::error::get_custom_error_class(err).unwrap() - } - BroadcastChannelError::MPSCSendError(_) => "Error", - BroadcastChannelError::BroadcastSendError(_) => "Error", - BroadcastChannelError::Other(err) => { - get_error_class_name(err).unwrap_or("Error") - } - } -} - -fn get_geometry_error(error: &GeometryError) -> &'static str { - match error { - GeometryError::Inconsistent2DMatrix => "TypeError", - } -} - -fn get_fetch_error(error: &FetchError) -> &'static str { - match error { - FetchError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - FetchError::Permission(e) => get_permission_check_error_class(e), - FetchError::NetworkError => "TypeError", - FetchError::FsNotGet(_) => "TypeError", - FetchError::PathToUrl(_) => "TypeError", - FetchError::InvalidUrl(_) => "TypeError", - FetchError::InvalidHeaderName(_) => "TypeError", - FetchError::InvalidHeaderValue(_) => "TypeError", - FetchError::DataUrl(_) => "TypeError", - FetchError::Base64(_) => "TypeError", - FetchError::BlobNotFound => "TypeError", - FetchError::SchemeNotSupported(_) => "TypeError", - FetchError::RequestCanceled => "TypeError", - FetchError::Http(_) => "Error", - FetchError::ClientCreate(e) => get_http_client_create_error(e), - FetchError::Url(e) => get_url_parse_error_class(e), - FetchError::Method(_) => "TypeError", - FetchError::ClientSend(_) => "TypeError", - FetchError::RequestBuilderHook(_) => "TypeError", - FetchError::Io(e) => get_io_error_class(e), - } -} - -fn get_http_client_create_error(error: &HttpClientCreateError) -> &'static str { - match error { - HttpClientCreateError::Tls(_) => "TypeError", - HttpClientCreateError::InvalidUserAgent(_) => "TypeError", - HttpClientCreateError::InvalidProxyUrl => "TypeError", - HttpClientCreateError::HttpVersionSelectionInvalid => "TypeError", - HttpClientCreateError::RootCertStore(_) => "TypeError", - } -} - -fn get_websocket_error(error: &WebsocketError) -> &'static str { - match error { - WebsocketError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - WebsocketError::Permission(e) => get_permission_check_error_class(e), - WebsocketError::Url(e) => get_url_parse_error_class(e), - WebsocketError::Io(e) => get_io_error_class(e), - WebsocketError::WebSocket(_) => "TypeError", - WebsocketError::ConnectionFailed(_) => "DOMExceptionNetworkError", - WebsocketError::Uri(_) => "Error", - WebsocketError::Canceled(e) => { - let io_err: io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - } - } -} - -fn get_websocket_handshake_error(error: &HandshakeError) -> &'static str { - match error { - HandshakeError::RootStoreError(e) => { - get_error_class_name(e).unwrap_or("Error") - } - HandshakeError::Tls(e) => get_tls_error_class(e), - HandshakeError::MissingPath => "TypeError", - HandshakeError::Http(_) => "Error", - HandshakeError::InvalidHostname(_) => "TypeError", - HandshakeError::Io(e) => get_io_error_class(e), - HandshakeError::Rustls(_) => "Error", - HandshakeError::H2(_) => "Error", - HandshakeError::NoH2Alpn => "Error", - HandshakeError::InvalidStatusCode(_) => "Error", - HandshakeError::WebSocket(_) => "TypeError", - HandshakeError::HeaderName(_) => "TypeError", - HandshakeError::HeaderValue(_) => "TypeError", - } -} - -fn get_fs_ops_error(error: &FsOpsError) -> &'static str { - use FsOpsErrorKind::*; - match error.as_kind() { - Io(e) => get_io_error_class(e), - OperationError(e) => get_fs_error(&e.err), - Permission(e) => get_permission_check_error_class(e), - Resource(e) | Other(e) => get_error_class_name(e).unwrap_or("Error"), - InvalidUtf8(_) => "InvalidData", - StripPrefix(_) => "Error", - Canceled(e) => { - let io_err: io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - } - InvalidSeekMode(_) => "TypeError", - InvalidControlCharacter(_) => "Error", - InvalidCharacter(_) => "Error", - #[cfg(windows)] - InvalidTrailingCharacter => "Error", - NotCapableAccess { .. } => "NotCapable", - NotCapable(_) => "NotCapable", - } -} - -fn get_kv_error(error: &KvError) -> &'static str { - use KvErrorKind::*; - match error.as_kind() { - DatabaseHandler(e) | Resource(e) | Kv(e) => { - get_error_class_name(e).unwrap_or("Error") - } - TooManyRanges(_) => "TypeError", - TooManyEntries(_) => "TypeError", - TooManyChecks(_) => "TypeError", - TooManyMutations(_) => "TypeError", - TooManyKeys(_) => "TypeError", - InvalidLimit => "TypeError", - InvalidBoundaryKey => "TypeError", - KeyTooLargeToRead(_) => "TypeError", - KeyTooLargeToWrite(_) => "TypeError", - TotalMutationTooLarge(_) => "TypeError", - TotalKeyTooLarge(_) => "TypeError", - Io(e) => get_io_error_class(e), - QueueMessageNotFound => "TypeError", - StartKeyNotInKeyspace => "TypeError", - EndKeyNotInKeyspace => "TypeError", - StartKeyGreaterThanEndKey => "TypeError", - InvalidCheck(e) => match e { - KvCheckError::InvalidVersionstamp => "TypeError", - KvCheckError::Io(e) => get_io_error_class(e), - }, - InvalidMutation(e) => match e { - KvMutationError::BigInt(_) => "Error", - KvMutationError::Io(e) => get_io_error_class(e), - KvMutationError::InvalidMutationWithValue(_) => "TypeError", - KvMutationError::InvalidMutationWithoutValue(_) => "TypeError", - }, - InvalidEnqueue(e) => get_io_error_class(e), - EmptyKey => "TypeError", - ValueTooLarge(_) => "TypeError", - EnqueuePayloadTooLarge(_) => "TypeError", - InvalidCursor => "TypeError", - CursorOutOfBounds => "TypeError", - InvalidRange => "TypeError", - } -} - -fn get_net_error(error: &NetError) -> &'static str { - match error { - NetError::ListenerClosed => "BadResource", - NetError::ListenerBusy => "Busy", - NetError::SocketClosed => "BadResource", - NetError::SocketClosedNotConnected => "NotConnected", - NetError::SocketBusy => "Busy", - NetError::Io(e) => get_io_error_class(e), - NetError::AcceptTaskOngoing => "Busy", - NetError::RootCertStore(e) | NetError::Resource(e) => { - get_error_class_name(e).unwrap_or("Error") - } - NetError::Permission(e) => get_permission_check_error_class(e), - NetError::NoResolvedAddress => "Error", - NetError::AddrParse(_) => "Error", - NetError::Map(e) => get_net_map_error(e), - NetError::Canceled(e) => { - let io_err: io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - } - NetError::DnsNotFound(_) => "NotFound", - NetError::DnsNotConnected(_) => "NotConnected", - NetError::DnsTimedOut(_) => "TimedOut", - NetError::Dns(_) => "Error", - NetError::UnsupportedRecordType => "NotSupported", - NetError::InvalidUtf8(_) => "InvalidData", - NetError::UnexpectedKeyType => "Error", - NetError::InvalidHostname(_) => "TypeError", - NetError::TcpStreamBusy => "Busy", - NetError::Rustls(_) => "Error", - NetError::Tls(e) => get_tls_error_class(e), - NetError::ListenTlsRequiresKey => "InvalidData", - NetError::Reunite(_) => "Error", - } -} - -fn get_net_map_error(error: &deno_net::io::MapError) -> &'static str { - match error { - deno_net::io::MapError::Io(e) => get_io_error_class(e), - deno_net::io::MapError::NoResources => "Error", - } -} - -fn get_child_permission_error(e: &ChildPermissionError) -> &'static str { - match e { - ChildPermissionError::Escalation => "NotCapable", - ChildPermissionError::PathResolve(e) => get_path_resolve_error(e), - ChildPermissionError::NetDescriptorParse(_) => "URIError", - ChildPermissionError::EnvDescriptorParse(_) => "Error", - ChildPermissionError::SysDescriptorParse(e) => { - get_sys_descriptor_parse_error(e) - } - ChildPermissionError::RunDescriptorParse(e) => { - get_run_descriptor_parse_error(e) - } - } -} - -fn get_create_worker_error(error: &CreateWorkerError) -> &'static str { - match error { - CreateWorkerError::ClassicWorkers => "DOMExceptionNotSupportedError", - CreateWorkerError::Permission(e) => get_child_permission_error(e), - CreateWorkerError::ModuleResolution(e) => { - get_module_resolution_error_class(e) - } - CreateWorkerError::Io(e) => get_io_error_class(e), - CreateWorkerError::MessagePort(e) => get_web_message_port_error_class(e), - } -} - -fn get_tty_error(error: &TtyError) -> &'static str { - match error { - TtyError::Resource(e) | TtyError::Other(e) => { - get_error_class_name(e).unwrap_or("Error") - } - TtyError::Io(e) => get_io_error_class(e), - #[cfg(unix)] - TtyError::Nix(e) => get_nix_error_class(e), - } -} - -fn get_readline_error(error: &ReadlineError) -> &'static str { - match error { - ReadlineError::Io(e) => get_io_error_class(e), - ReadlineError::Eof => "Error", - ReadlineError::Interrupted => "Error", - #[cfg(unix)] - ReadlineError::Errno(e) => get_nix_error_class(e), - ReadlineError::WindowResized => "Error", - #[cfg(windows)] - ReadlineError::Decode(_) => "Error", - #[cfg(windows)] - ReadlineError::SystemError(_) => "Error", - _ => "Error", - } -} - -fn get_signal_error(error: &SignalError) -> &'static str { - match error { - SignalError::InvalidSignalStr(_) => "TypeError", - SignalError::InvalidSignalInt(_) => "TypeError", - SignalError::SignalNotAllowed(_) => "TypeError", - SignalError::Io(e) => get_io_error_class(e), - } -} - -fn get_fs_events_error(error: &FsEventsError) -> &'static str { - match error { - FsEventsError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - FsEventsError::Permission(e) => get_permission_check_error_class(e), - FsEventsError::Notify(e) => get_notify_error_class(e), - FsEventsError::Canceled(e) => { - let io_err: io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - } - } -} - -fn get_http_start_error(error: &HttpStartError) -> &'static str { - match error { - HttpStartError::TcpStreamInUse => "Busy", - HttpStartError::TlsStreamInUse => "Busy", - HttpStartError::UnixSocketInUse => "Busy", - HttpStartError::ReuniteTcp(_) => "Error", - #[cfg(unix)] - HttpStartError::ReuniteUnix(_) => "Error", - HttpStartError::Io(e) => get_io_error_class(e), - HttpStartError::Other(e) => get_error_class_name(e).unwrap_or("Error"), - } -} - -fn get_process_error(error: &ProcessError) -> &'static str { - match error { - ProcessError::SpawnFailed { error, .. } => get_process_error(error), - ProcessError::FailedResolvingCwd(e) | ProcessError::Io(e) => { - get_io_error_class(e) - } - ProcessError::Permission(e) => get_permission_check_error_class(e), - ProcessError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - ProcessError::BorrowMut(_) => "Error", - ProcessError::Which(_) => "Error", - ProcessError::ChildProcessAlreadyTerminated => "TypeError", - ProcessError::Signal(e) => get_signal_error(e), - ProcessError::MissingCmd => "Error", - ProcessError::InvalidPid => "TypeError", - #[cfg(unix)] - ProcessError::Nix(e) => get_nix_error_class(e), - ProcessError::RunPermission(e) => match e { - CheckRunPermissionError::Permission(e) => { - get_permission_check_error_class(e) - } - CheckRunPermissionError::Other(e) => { - get_error_class_name(e).unwrap_or("Error") - } - }, - } -} - -fn get_http_error(error: &HttpError) -> &'static str { - match error { - HttpError::Canceled(e) => { - let io_err: io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - } - HttpError::HyperV014(e) => get_hyper_v014_error_class(e), - HttpError::InvalidHeaderName(_) => "Error", - HttpError::InvalidHeaderValue(_) => "Error", - HttpError::Http(_) => "Error", - HttpError::ResponseHeadersAlreadySent => "Http", - HttpError::ConnectionClosedWhileSendingResponse => "Http", - HttpError::AlreadyInUse => "Http", - HttpError::Io(e) => get_io_error_class(e), - HttpError::NoResponseHeaders => "Http", - HttpError::ResponseAlreadyCompleted => "Http", - HttpError::UpgradeBodyUsed => "Http", - HttpError::Resource(e) | HttpError::Other(e) => { - get_error_class_name(e).unwrap_or("Error") - } - } -} - -fn get_http_next_error(error: &HttpNextError) -> &'static str { - match error { - HttpNextError::Io(e) => get_io_error_class(e), - HttpNextError::WebSocketUpgrade(e) => get_websocket_upgrade_error(e), - HttpNextError::Hyper(e) => get_hyper_error_class(e), - HttpNextError::JoinError(_) => "Error", - HttpNextError::Canceled(e) => { - let io_err: io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - } - HttpNextError::UpgradeUnavailable(_) => "Error", - HttpNextError::HttpPropertyExtractor(e) | HttpNextError::Resource(e) => { - get_error_class_name(e).unwrap_or("Error") - } - } -} - -fn get_websocket_upgrade_error(error: &WebSocketUpgradeError) -> &'static str { - match error { - WebSocketUpgradeError::InvalidHeaders => "Http", - WebSocketUpgradeError::HttpParse(_) => "Error", - WebSocketUpgradeError::Http(_) => "Error", - WebSocketUpgradeError::Utf8(_) => "Error", - WebSocketUpgradeError::InvalidHeaderName(_) => "Error", - WebSocketUpgradeError::InvalidHeaderValue(_) => "Error", - WebSocketUpgradeError::InvalidHttpStatusLine => "Http", - WebSocketUpgradeError::UpgradeBufferAlreadyCompleted => "Http", - } -} - -fn get_fs_error(e: &FsError) -> &'static str { - match &e { - FsError::Io(e) => get_io_error_class(e), - FsError::FileBusy => "Busy", - FsError::NotSupported => "NotSupported", - FsError::NotCapable(_) => "NotCapable", - } -} - -mod node { - pub use deno_node::ops::blocklist::BlocklistError; - pub use deno_node::ops::crypto::cipher::CipherContextError; - pub use deno_node::ops::crypto::cipher::CipherError; - pub use deno_node::ops::crypto::cipher::DecipherContextError; - pub use deno_node::ops::crypto::cipher::DecipherError; - pub use deno_node::ops::crypto::digest::HashError; - pub use deno_node::ops::crypto::keys::AsymmetricPrivateKeyDerError; - pub use deno_node::ops::crypto::keys::AsymmetricPrivateKeyError; - pub use deno_node::ops::crypto::keys::AsymmetricPublicKeyDerError; - pub use deno_node::ops::crypto::keys::AsymmetricPublicKeyError; - pub use deno_node::ops::crypto::keys::AsymmetricPublicKeyJwkError; - pub use deno_node::ops::crypto::keys::EcJwkError; - pub use deno_node::ops::crypto::keys::EdRawError; - pub use deno_node::ops::crypto::keys::ExportPrivateKeyPemError; - pub use deno_node::ops::crypto::keys::ExportPublicKeyPemError; - pub use deno_node::ops::crypto::keys::GenerateRsaPssError; - pub use deno_node::ops::crypto::keys::RsaJwkError; - pub use deno_node::ops::crypto::keys::RsaPssParamsParseError; - pub use deno_node::ops::crypto::keys::X509PublicKeyError; - pub use deno_node::ops::crypto::sign::KeyObjectHandlePrehashedSignAndVerifyError; - pub use deno_node::ops::crypto::x509::X509Error; - pub use deno_node::ops::crypto::DiffieHellmanError; - pub use deno_node::ops::crypto::EcdhEncodePubKey; - pub use deno_node::ops::crypto::HkdfError; - pub use deno_node::ops::crypto::Pbkdf2Error; - pub use deno_node::ops::crypto::PrivateEncryptDecryptError; - pub use deno_node::ops::crypto::ScryptAsyncError; - pub use deno_node::ops::crypto::SignEd25519Error; - pub use deno_node::ops::crypto::VerifyEd25519Error; - pub use deno_node::ops::fs::FsError; - pub use deno_node::ops::http::ConnError; - pub use deno_node::ops::http2::Http2Error; - pub use deno_node::ops::idna::IdnaError; - pub use deno_node::ops::ipc::IpcError; - pub use deno_node::ops::ipc::IpcJsonStreamError; - use deno_node::ops::os::priority::PriorityError; - pub use deno_node::ops::os::OsError; - pub use deno_node::ops::require::RequireError; - use deno_node::ops::require::RequireErrorKind; - pub use deno_node::ops::worker_threads::WorkerThreadsFilenameError; - pub use deno_node::ops::zlib::brotli::BrotliError; - pub use deno_node::ops::zlib::mode::ModeError; - pub use deno_node::ops::zlib::ZlibError; - - use super::get_error_class_name; - use super::get_io_error_class; - use super::get_permission_check_error_class; - use super::get_serde_json_error_class; - use super::get_url_parse_error_class; - - pub fn get_blocklist_error(error: &BlocklistError) -> &'static str { - match error { - BlocklistError::AddrParse(_) => "Error", - BlocklistError::IpNetwork(_) => "Error", - BlocklistError::InvalidAddress => "Error", - BlocklistError::IpVersionMismatch => "Error", - } - } - - pub fn get_fs_error(error: &FsError) -> &'static str { - match error { - FsError::Permission(e) => get_permission_check_error_class(e), - FsError::Io(e) => get_io_error_class(e), - #[cfg(windows)] - FsError::PathHasNoRoot => "Error", - #[cfg(not(any(unix, windows)))] - FsError::UnsupportedPlatform => "Error", - FsError::Fs(e) => super::get_fs_error(e), - } - } - - pub fn get_idna_error(error: &IdnaError) -> &'static str { - match error { - IdnaError::InvalidInput => "RangeError", - IdnaError::InputTooLong => "Error", - IdnaError::IllegalInput => "RangeError", - } - } - - pub fn get_ipc_json_stream_error(error: &IpcJsonStreamError) -> &'static str { - match error { - IpcJsonStreamError::Io(e) => get_io_error_class(e), - IpcJsonStreamError::SimdJson(_) => "Error", - } - } - - pub fn get_ipc_error(error: &IpcError) -> &'static str { - match error { - IpcError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - IpcError::IpcJsonStream(e) => get_ipc_json_stream_error(e), - IpcError::Canceled(e) => { - let io_err: std::io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - } - IpcError::SerdeJson(e) => get_serde_json_error_class(e), - } - } - - pub fn get_worker_threads_filename_error( - error: &WorkerThreadsFilenameError, - ) -> &'static str { - match error { - WorkerThreadsFilenameError::Permission(e) => { - get_error_class_name(e).unwrap_or("Error") - } - WorkerThreadsFilenameError::UrlParse(e) => get_url_parse_error_class(e), - WorkerThreadsFilenameError::InvalidRelativeUrl => "Error", - WorkerThreadsFilenameError::UrlFromPathString => "Error", - WorkerThreadsFilenameError::UrlToPathString => "Error", - WorkerThreadsFilenameError::UrlToPath => "Error", - WorkerThreadsFilenameError::FileNotFound(_) => "Error", - WorkerThreadsFilenameError::Fs(e) => super::get_io_error_class(e), - } - } - - pub fn get_require_error(error: &RequireError) -> &'static str { - use RequireErrorKind::*; - match error.as_kind() { - UrlParse(e) => get_url_parse_error_class(e), - Permission(e) => get_error_class_name(e).unwrap_or("Error"), - PackageExportsResolve(_) - | PackageJsonLoad(_) - | ClosestPkgJson(_) - | FilePathConversion(_) - | UrlConversion(_) - | ReadModule(_) - | PackageImportsResolve(_) => "Error", - Fs(e) | UnableToGetCwd(e) => super::get_io_error_class(e), - } - } - - pub fn get_http2_error(error: &Http2Error) -> &'static str { - match error { - Http2Error::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - Http2Error::UrlParse(e) => get_url_parse_error_class(e), - Http2Error::H2(_) => "Error", - } - } - - pub fn get_os_error(error: &OsError) -> &'static str { - match error { - OsError::Priority(e) => match e { - PriorityError::Io(e) => get_io_error_class(e), - #[cfg(windows)] - PriorityError::InvalidPriority => "TypeError", - }, - OsError::Permission(e) => get_permission_check_error_class(e), - OsError::FailedToGetCpuInfo => "TypeError", - OsError::FailedToGetUserInfo(e) => get_io_error_class(e), - } - } - - pub fn get_brotli_error(error: &BrotliError) -> &'static str { - match error { - BrotliError::InvalidEncoderMode => "TypeError", - BrotliError::CompressFailed => "TypeError", - BrotliError::DecompressFailed => "TypeError", - BrotliError::Join(_) => "Error", - BrotliError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - BrotliError::Io(e) => get_io_error_class(e), - } - } - - pub fn get_mode_error(_: &ModeError) -> &'static str { - "Error" - } - - pub fn get_zlib_error(e: &ZlibError) -> &'static str { - match e { - ZlibError::NotInitialized => "TypeError", - ZlibError::Mode(e) => get_mode_error(e), - ZlibError::Other(e) => get_error_class_name(e).unwrap_or("Error"), - } - } - - pub fn get_crypto_cipher_context_error( - e: &CipherContextError, - ) -> &'static str { - match e { - CipherContextError::ContextInUse => "TypeError", - CipherContextError::Cipher(e) => get_crypto_cipher_error(e), - CipherContextError::Resource(e) => { - get_error_class_name(e).unwrap_or("Error") - } - } - } - - pub fn get_crypto_cipher_error(e: &CipherError) -> &'static str { - match e { - CipherError::InvalidIvLength => "TypeError", - CipherError::InvalidKeyLength => "RangeError", - CipherError::InvalidInitializationVector => "TypeError", - CipherError::CannotPadInputData => "TypeError", - CipherError::UnknownCipher(_) => "TypeError", - } - } - - pub fn get_crypto_decipher_context_error( - e: &DecipherContextError, - ) -> &'static str { - match e { - DecipherContextError::ContextInUse => "TypeError", - DecipherContextError::Decipher(e) => get_crypto_decipher_error(e), - DecipherContextError::Resource(e) => { - get_error_class_name(e).unwrap_or("Error") - } - } - } - - pub fn get_crypto_decipher_error(e: &DecipherError) -> &'static str { - match e { - DecipherError::InvalidIvLength => "TypeError", - DecipherError::InvalidKeyLength => "RangeError", - DecipherError::InvalidInitializationVector => "TypeError", - DecipherError::CannotUnpadInputData => "TypeError", - DecipherError::DataAuthenticationFailed => "TypeError", - DecipherError::SetAutoPaddingFalseAes128GcmUnsupported => "TypeError", - DecipherError::SetAutoPaddingFalseAes256GcmUnsupported => "TypeError", - DecipherError::UnknownCipher(_) => "TypeError", - } - } - - pub fn get_x509_error(_: &X509Error) -> &'static str { - "Error" - } - - pub fn get_crypto_key_object_handle_prehashed_sign_and_verify_error( - e: &KeyObjectHandlePrehashedSignAndVerifyError, - ) -> &'static str { - match e { - KeyObjectHandlePrehashedSignAndVerifyError::InvalidDsaSignatureEncoding => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::KeyIsNotPrivate => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::DigestNotAllowedForRsaSignature(_) => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::FailedToSignDigestWithRsa => "Error", - KeyObjectHandlePrehashedSignAndVerifyError::DigestNotAllowedForRsaPssSignature(_) => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::FailedToSignDigestWithRsaPss => "Error", - KeyObjectHandlePrehashedSignAndVerifyError::FailedToSignDigestWithDsa => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::RsaPssHashAlgorithmUnsupported => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::PrivateKeyDisallowsUsage { .. } => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::FailedToSignDigest => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::X25519KeyCannotBeUsedForSigning => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::Ed25519KeyCannotBeUsedForPrehashedSigning => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::DhKeyCannotBeUsedForSigning => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::KeyIsNotPublicOrPrivate => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::InvalidDsaSignature => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::X25519KeyCannotBeUsedForVerification => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::Ed25519KeyCannotBeUsedForPrehashedVerification => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::DhKeyCannotBeUsedForVerification => "TypeError", - } - } - - pub fn get_crypto_hash_error(_: &HashError) -> &'static str { - "Error" - } - - pub fn get_asymmetric_public_key_jwk_error( - e: &AsymmetricPublicKeyJwkError, - ) -> &'static str { - match e { - AsymmetricPublicKeyJwkError::UnsupportedJwkEcCurveP224 => "TypeError", - AsymmetricPublicKeyJwkError::JwkExportNotImplementedForKeyType => { - "TypeError" - } - AsymmetricPublicKeyJwkError::KeyIsNotAsymmetricPublicKey => "TypeError", - } - } - - pub fn get_generate_rsa_pss_error(_: &GenerateRsaPssError) -> &'static str { - "TypeError" - } - - pub fn get_asymmetric_private_key_der_error( - e: &AsymmetricPrivateKeyDerError, - ) -> &'static str { - match e { - AsymmetricPrivateKeyDerError::KeyIsNotAsymmetricPrivateKey => "TypeError", - AsymmetricPrivateKeyDerError::InvalidRsaPrivateKey => "TypeError", - AsymmetricPrivateKeyDerError::ExportingNonRsaPrivateKeyAsPkcs1Unsupported => "TypeError", - AsymmetricPrivateKeyDerError::InvalidEcPrivateKey => "TypeError", - AsymmetricPrivateKeyDerError::ExportingNonEcPrivateKeyAsSec1Unsupported => "TypeError", - AsymmetricPrivateKeyDerError::ExportingNonRsaPssPrivateKeyAsPkcs8Unsupported => "Error", - AsymmetricPrivateKeyDerError::InvalidDsaPrivateKey => "TypeError", - AsymmetricPrivateKeyDerError::InvalidX25519PrivateKey => "TypeError", - AsymmetricPrivateKeyDerError::InvalidEd25519PrivateKey => "TypeError", - AsymmetricPrivateKeyDerError::InvalidDhPrivateKey => "TypeError", - AsymmetricPrivateKeyDerError::UnsupportedKeyType(_) => "TypeError", - } - } - - pub fn get_asymmetric_public_key_der_error( - _: &AsymmetricPublicKeyDerError, - ) -> &'static str { - "TypeError" - } - - pub fn get_export_public_key_pem_error( - e: &ExportPublicKeyPemError, - ) -> &'static str { - match e { - ExportPublicKeyPemError::AsymmetricPublicKeyDer(e) => { - get_asymmetric_public_key_der_error(e) - } - ExportPublicKeyPemError::VeryLargeData => "TypeError", - ExportPublicKeyPemError::Der(_) => "Error", - } - } - - pub fn get_export_private_key_pem_error( - e: &ExportPrivateKeyPemError, - ) -> &'static str { - match e { - ExportPrivateKeyPemError::AsymmetricPublicKeyDer(e) => { - get_asymmetric_private_key_der_error(e) - } - ExportPrivateKeyPemError::VeryLargeData => "TypeError", - ExportPrivateKeyPemError::Der(_) => "Error", - } - } - - pub fn get_x509_public_key_error(e: &X509PublicKeyError) -> &'static str { - match e { - X509PublicKeyError::X509(_) => "Error", - X509PublicKeyError::Rsa(_) => "Error", - X509PublicKeyError::Asn1(_) => "Error", - X509PublicKeyError::Ec(_) => "Error", - X509PublicKeyError::UnsupportedEcNamedCurve => "TypeError", - X509PublicKeyError::MissingEcParameters => "TypeError", - X509PublicKeyError::MalformedDssPublicKey => "TypeError", - X509PublicKeyError::UnsupportedX509KeyType => "TypeError", - } - } - - pub fn get_rsa_jwk_error(e: &RsaJwkError) -> &'static str { - match e { - RsaJwkError::Base64(_) => "Error", - RsaJwkError::Rsa(_) => "Error", - RsaJwkError::MissingRsaPrivateComponent => "TypeError", - } - } - - pub fn get_ec_jwk_error(e: &EcJwkError) -> &'static str { - match e { - EcJwkError::Ec(_) => "Error", - EcJwkError::UnsupportedCurve(_) => "TypeError", - } - } - - pub fn get_ed_raw_error(e: &EdRawError) -> &'static str { - match e { - EdRawError::Ed25519Signature(_) => "Error", - EdRawError::InvalidEd25519Key => "TypeError", - EdRawError::UnsupportedCurve => "TypeError", - } - } - - pub fn get_pbkdf2_error(e: &Pbkdf2Error) -> &'static str { - match e { - Pbkdf2Error::UnsupportedDigest(_) => "TypeError", - Pbkdf2Error::Join(_) => "Error", - } - } - - pub fn get_scrypt_async_error(e: &ScryptAsyncError) -> &'static str { - match e { - ScryptAsyncError::Join(_) => "Error", - ScryptAsyncError::Other(e) => get_error_class_name(e).unwrap_or("Error"), - } - } - - pub fn get_hkdf_error_error(e: &HkdfError) -> &'static str { - match e { - HkdfError::ExpectedSecretKey => "TypeError", - HkdfError::HkdfExpandFailed => "TypeError", - HkdfError::UnsupportedDigest(_) => "TypeError", - HkdfError::Join(_) => "Error", - } - } - - pub fn get_rsa_pss_params_parse_error( - _: &RsaPssParamsParseError, - ) -> &'static str { - "TypeError" - } - - pub fn get_asymmetric_private_key_error( - e: &AsymmetricPrivateKeyError, - ) -> &'static str { - match e { - AsymmetricPrivateKeyError::InvalidPemPrivateKeyInvalidUtf8(_) => "TypeError", - AsymmetricPrivateKeyError::InvalidEncryptedPemPrivateKey => "TypeError", - AsymmetricPrivateKeyError::InvalidPemPrivateKey => "TypeError", - AsymmetricPrivateKeyError::EncryptedPrivateKeyRequiresPassphraseToDecrypt => "TypeError", - AsymmetricPrivateKeyError::InvalidPkcs1PrivateKey => "TypeError", - AsymmetricPrivateKeyError::InvalidSec1PrivateKey => "TypeError", - AsymmetricPrivateKeyError::UnsupportedPemLabel(_) => "TypeError", - AsymmetricPrivateKeyError::RsaPssParamsParse(e) => get_rsa_pss_params_parse_error(e), - AsymmetricPrivateKeyError::InvalidEncryptedPkcs8PrivateKey => "TypeError", - AsymmetricPrivateKeyError::InvalidPkcs8PrivateKey => "TypeError", - AsymmetricPrivateKeyError::Pkcs1PrivateKeyDoesNotSupportEncryptionWithPassphrase => "TypeError", - AsymmetricPrivateKeyError::Sec1PrivateKeyDoesNotSupportEncryptionWithPassphrase => "TypeError", - AsymmetricPrivateKeyError::UnsupportedEcNamedCurve => "TypeError", - AsymmetricPrivateKeyError::InvalidPrivateKey => "TypeError", - AsymmetricPrivateKeyError::InvalidDsaPrivateKey => "TypeError", - AsymmetricPrivateKeyError::MalformedOrMissingNamedCurveInEcParameters => "TypeError", - AsymmetricPrivateKeyError::UnsupportedKeyType(_) => "TypeError", - AsymmetricPrivateKeyError::UnsupportedKeyFormat(_) => "TypeError", - AsymmetricPrivateKeyError::InvalidX25519PrivateKey => "TypeError", - AsymmetricPrivateKeyError::X25519PrivateKeyIsWrongLength => "TypeError", - AsymmetricPrivateKeyError::InvalidEd25519PrivateKey => "TypeError", - AsymmetricPrivateKeyError::MissingDhParameters => "TypeError", - AsymmetricPrivateKeyError::UnsupportedPrivateKeyOid => "TypeError", - } - } - - pub fn get_asymmetric_public_key_error( - e: &AsymmetricPublicKeyError, - ) -> &'static str { - match e { - AsymmetricPublicKeyError::InvalidPemPrivateKeyInvalidUtf8(_) => { - "TypeError" - } - AsymmetricPublicKeyError::InvalidPemPublicKey => "TypeError", - AsymmetricPublicKeyError::InvalidPkcs1PublicKey => "TypeError", - AsymmetricPublicKeyError::AsymmetricPrivateKey(e) => { - get_asymmetric_private_key_error(e) - } - AsymmetricPublicKeyError::InvalidX509Certificate => "TypeError", - AsymmetricPublicKeyError::X509(_) => "Error", - AsymmetricPublicKeyError::X509PublicKey(e) => { - get_x509_public_key_error(e) - } - AsymmetricPublicKeyError::UnsupportedPemLabel(_) => "TypeError", - AsymmetricPublicKeyError::InvalidSpkiPublicKey => "TypeError", - AsymmetricPublicKeyError::UnsupportedKeyType(_) => "TypeError", - AsymmetricPublicKeyError::UnsupportedKeyFormat(_) => "TypeError", - AsymmetricPublicKeyError::Spki(_) => "Error", - AsymmetricPublicKeyError::Pkcs1(_) => "Error", - AsymmetricPublicKeyError::RsaPssParamsParse(_) => "TypeError", - AsymmetricPublicKeyError::MalformedDssPublicKey => "TypeError", - AsymmetricPublicKeyError::MalformedOrMissingNamedCurveInEcParameters => { - "TypeError" - } - AsymmetricPublicKeyError::MalformedOrMissingPublicKeyInEcSpki => { - "TypeError" - } - AsymmetricPublicKeyError::Ec(_) => "Error", - AsymmetricPublicKeyError::UnsupportedEcNamedCurve => "TypeError", - AsymmetricPublicKeyError::MalformedOrMissingPublicKeyInX25519Spki => { - "TypeError" - } - AsymmetricPublicKeyError::X25519PublicKeyIsTooShort => "TypeError", - AsymmetricPublicKeyError::InvalidEd25519PublicKey => "TypeError", - AsymmetricPublicKeyError::MissingDhParameters => "TypeError", - AsymmetricPublicKeyError::MalformedDhParameters => "TypeError", - AsymmetricPublicKeyError::MalformedOrMissingPublicKeyInDhSpki => { - "TypeError" - } - AsymmetricPublicKeyError::UnsupportedPrivateKeyOid => "TypeError", - } - } - - pub fn get_private_encrypt_decrypt_error( - e: &PrivateEncryptDecryptError, - ) -> &'static str { - match e { - PrivateEncryptDecryptError::Pkcs8(_) => "Error", - PrivateEncryptDecryptError::Spki(_) => "Error", - PrivateEncryptDecryptError::Utf8(_) => "Error", - PrivateEncryptDecryptError::Rsa(_) => "Error", - PrivateEncryptDecryptError::UnknownPadding => "TypeError", - } - } - - pub fn get_ecdh_encode_pub_key_error(e: &EcdhEncodePubKey) -> &'static str { - match e { - EcdhEncodePubKey::InvalidPublicKey => "TypeError", - EcdhEncodePubKey::UnsupportedCurve => "TypeError", - EcdhEncodePubKey::Sec1(_) => "Error", - } - } - - pub fn get_diffie_hellman_error(_: &DiffieHellmanError) -> &'static str { - "TypeError" - } - - pub fn get_sign_ed25519_error(_: &SignEd25519Error) -> &'static str { - "TypeError" - } - - pub fn get_verify_ed25519_error(_: &VerifyEd25519Error) -> &'static str { - "TypeError" - } - - pub fn get_conn_error(e: &ConnError) -> &'static str { - match e { - ConnError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - ConnError::Permission(e) => get_permission_check_error_class(e), - ConnError::InvalidUrl(_) => "TypeError", - ConnError::InvalidHeaderName(_) => "TypeError", - ConnError::InvalidHeaderValue(_) => "TypeError", - ConnError::Url(e) => get_url_parse_error_class(e), - ConnError::Method(_) => "TypeError", - ConnError::Io(e) => get_io_error_class(e), - ConnError::Hyper(e) => super::get_hyper_error_class(e), - ConnError::TlsStreamBusy => "Busy", - ConnError::TcpStreamBusy => "Busy", - ConnError::ReuniteTcp(_) => "Error", - ConnError::Canceled(_) => "Error", - } - } -} - -fn get_os_error(error: &OsError) -> &'static str { - match error { - OsError::Permission(e) => get_permission_check_error_class(e), - OsError::InvalidUtf8(_) => "InvalidData", - OsError::EnvEmptyKey => "TypeError", - OsError::EnvInvalidKey(_) => "TypeError", - OsError::EnvInvalidValue(_) => "TypeError", - OsError::Io(e) => get_io_error_class(e), - OsError::Var(e) => get_env_var_error_class(e), - } -} - -fn get_sync_fetch_error(error: &SyncFetchError) -> &'static str { - match error { - SyncFetchError::BlobUrlsNotSupportedInContext => "TypeError", - SyncFetchError::Io(e) => get_io_error_class(e), - SyncFetchError::InvalidScriptUrl => "TypeError", - SyncFetchError::InvalidStatusCode(_) => "TypeError", - SyncFetchError::ClassicScriptSchemeUnsupportedInWorkers(_) => "TypeError", - SyncFetchError::InvalidUri(_) => "Error", - SyncFetchError::InvalidMimeType(_) => "DOMExceptionNetworkError", - SyncFetchError::MissingMimeType => "DOMExceptionNetworkError", - SyncFetchError::Fetch(e) => get_fetch_error(e), - SyncFetchError::Join(_) => "Error", - SyncFetchError::Other(e) => get_error_class_name(e).unwrap_or("Error"), - } -} - -pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> { - deno_core::error::get_custom_error_class(e) - .or_else(|| { - e.downcast_ref::() - .map(get_child_permission_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_permission_check_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_permission_error_class) - }) - .or_else(|| e.downcast_ref::().map(get_fs_error)) - .or_else(|| { - e.downcast_ref::() - .map(node::get_blocklist_error) - }) - .or_else(|| e.downcast_ref::().map(node::get_fs_error)) - .or_else(|| { - e.downcast_ref::() - .map(node::get_idna_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_ipc_json_stream_error) - }) - .or_else(|| e.downcast_ref::().map(node::get_ipc_error)) - .or_else(|| { - e.downcast_ref::() - .map(node::get_worker_threads_filename_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_require_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_http2_error) - }) - .or_else(|| e.downcast_ref::().map(node::get_os_error)) - .or_else(|| { - e.downcast_ref::() - .map(node::get_brotli_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_mode_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_zlib_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_crypto_cipher_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_crypto_cipher_context_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_crypto_decipher_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_crypto_decipher_context_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_x509_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_crypto_key_object_handle_prehashed_sign_and_verify_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_crypto_hash_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_asymmetric_public_key_jwk_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_generate_rsa_pss_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_asymmetric_private_key_der_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_asymmetric_public_key_der_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_export_public_key_pem_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_export_private_key_pem_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_rsa_jwk_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_ec_jwk_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_ed_raw_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_pbkdf2_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_scrypt_async_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_hkdf_error_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_rsa_pss_params_parse_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_asymmetric_private_key_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_asymmetric_public_key_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_private_encrypt_decrypt_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_ecdh_encode_pub_key_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_diffie_hellman_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_sign_ed25519_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_verify_ed25519_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_conn_error) - }) - .or_else(|| e.downcast_ref::().map(get_napi_error_class)) - .or_else(|| e.downcast_ref::().map(get_web_error_class)) - .or_else(|| { - e.downcast_ref::() - .map(get_create_worker_error) - }) - .or_else(|| e.downcast_ref::().map(get_tty_error)) - .or_else(|| e.downcast_ref::().map(get_readline_error)) - .or_else(|| e.downcast_ref::().map(get_signal_error)) - .or_else(|| e.downcast_ref::().map(get_fs_events_error)) - .or_else(|| e.downcast_ref::().map(get_http_start_error)) - .or_else(|| e.downcast_ref::().map(get_process_error)) - .or_else(|| e.downcast_ref::().map(get_os_error)) - .or_else(|| e.downcast_ref::().map(get_geometry_error)) - .or_else(|| e.downcast_ref::().map(get_sync_fetch_error)) - .or_else(|| { - e.downcast_ref::() - .map(get_web_compression_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_web_message_port_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_web_stream_resource_error_class) - }) - .or_else(|| e.downcast_ref::().map(get_web_blob_error_class)) - .or_else(|| e.downcast_ref::().map(|_| "TypeError")) - .or_else(|| e.downcast_ref::().map(get_ffi_repr_error_class)) - .or_else(|| e.downcast_ref::().map(get_http_error)) - .or_else(|| e.downcast_ref::().map(get_http_next_error)) - .or_else(|| { - e.downcast_ref::() - .map(get_websocket_upgrade_error) - }) - .or_else(|| e.downcast_ref::().map(get_fs_ops_error)) - .or_else(|| { - e.downcast_ref::() - .map(get_ffi_dlfcn_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_ffi_static_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_ffi_callback_error_class) - }) - .or_else(|| e.downcast_ref::().map(get_ffi_call_error_class)) - .or_else(|| e.downcast_ref::().map(get_tls_error_class)) - .or_else(|| e.downcast_ref::().map(get_cron_error_class)) - .or_else(|| e.downcast_ref::().map(get_canvas_error)) - .or_else(|| e.downcast_ref::().map(get_cache_error)) - .or_else(|| e.downcast_ref::().map(get_websocket_error)) - .or_else(|| { - e.downcast_ref::() - .map(get_websocket_handshake_error) - }) - .or_else(|| e.downcast_ref::().map(get_kv_error)) - .or_else(|| e.downcast_ref::().map(get_fetch_error)) - .or_else(|| { - e.downcast_ref::() - .map(get_http_client_create_error) - }) - .or_else(|| e.downcast_ref::().map(get_net_error)) - .or_else(|| { - e.downcast_ref::() - .map(get_net_map_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_broadcast_channel_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_webgpu_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_webgpu_buffer_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_webgpu_bundle_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_webgpu_byow_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_webgpu_render_pass_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_webgpu_surface_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_decrypt_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_encrypt_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_shared_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_ed25519_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_export_key_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_generate_key_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_import_key_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_x448_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_x25519_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_webstorage_class_name) - }) - .or_else(|| { - e.downcast_ref::() - .map(|_| "TypeError") - }) - .or_else(|| { - e.downcast_ref::() - .map(get_dlopen_error_class) - }) - .or_else(|| e.downcast_ref::().map(get_hyper_error_class)) - .or_else(|| { - e.downcast_ref::() - .map(get_hyper_util_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_hyper_v014_error_class) - }) - .or_else(|| { - e.downcast_ref::>() - .map(|e| get_hyper_v014_error_class(e)) - }) - .or_else(|| { - e.downcast_ref::().map(|e| { - let io_err: io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - }) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_env_var_error_class) - }) - .or_else(|| e.downcast_ref::().map(get_io_error_class)) - .or_else(|| { - e.downcast_ref::() - .map(get_module_resolution_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_notify_error_class) - }) - .or_else(|| e.downcast_ref::().map(get_regex_error_class)) - .or_else(|| { - e.downcast_ref::() - .map(get_serde_json_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_url_parse_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(|_| "TypeError") - }) - .or_else(|| { - #[cfg(unix)] - let maybe_get_nix_error_class = - || e.downcast_ref::().map(get_nix_error_class); - #[cfg(not(unix))] - let maybe_get_nix_error_class = || Option::<&'static str>::None; - (maybe_get_nix_error_class)() - }) -} - From dfa4af12b093ac3a504d7fe98004ad7affd1c91a Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 24 Jan 2025 01:38:32 +0900 Subject: [PATCH 19/63] fix --- ext/geometry/lib.rs | 156 ++++++++++++++++++++++++++------------------ 1 file changed, 92 insertions(+), 64 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 2a3c12579102f1..4586bfa781586b 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -2,13 +2,14 @@ use std::cell::Cell; use std::cell::RefCell; -use std::cell::UnsafeCell; use std::mem; use std::path::PathBuf; -use std::ptr; use std::slice; +use deno_core::cppgc; +use deno_core::cppgc::SameObject; use deno_core::op2; +use deno_core::v8; use deno_core::webidl; use deno_core::GarbageCollected; use deno_core::WebIDL; @@ -280,12 +281,11 @@ pub struct DOMQuadInit { p4: DOMPointInit, } -#[derive(Debug)] pub struct DOMQuadInner { - p1: UnsafeCell, - p2: UnsafeCell, - p3: UnsafeCell, - p4: UnsafeCell, + p1: SameObject, + p2: SameObject, + p3: SameObject, + p4: SameObject, } impl GarbageCollected for DOMQuadInner {} @@ -296,32 +296,56 @@ impl DOMQuadInner { #[reentrant] #[cppgc] pub fn constructor( + scope: &mut v8::HandleScope, #[webidl] p1: DOMPointInit, #[webidl] p2: DOMPointInit, #[webidl] p3: DOMPointInit, #[webidl] p4: DOMPointInit, ) -> DOMQuadInner { #[inline] - fn from_point(point: DOMPointInit) -> DOMPointInner { - DOMPointInner { + fn from_point( + scope: &mut v8::HandleScope, + point: DOMPointInit, + ) -> SameObject { + let obj = SameObject::new(); + obj.get(scope, |_| DOMPointInner { inner: RefCell::new(Vector4::new( *point.x, *point.y, *point.z, *point.w, )), - } + }); + obj } DOMQuadInner { - p1: UnsafeCell::new(from_point(p1)), - p2: UnsafeCell::new(from_point(p2)), - p3: UnsafeCell::new(from_point(p3)), - p4: UnsafeCell::new(from_point(p4)), + p1: from_point(scope, p1), + p2: from_point(scope, p2), + p3: from_point(scope, p3), + p4: from_point(scope, p4), } } #[reentrant] #[static_method] #[cppgc] - pub fn from_rect(#[webidl] rect: DOMRectInit) -> DOMQuadInner { + pub fn from_rect( + scope: &mut v8::HandleScope, + #[webidl] rect: DOMRectInit, + ) -> DOMQuadInner { + #[inline] + fn create_point( + scope: &mut v8::HandleScope, + x: f64, + y: f64, + z: f64, + w: f64, + ) -> SameObject { + let obj = SameObject::new(); + obj.get(scope, |_| DOMPointInner { + inner: RefCell::new(Vector4::new(x, y, z, w)), + }); + obj + } + let DOMRectInit { x, y, @@ -329,84 +353,88 @@ impl DOMQuadInner { height, } = rect; DOMQuadInner { - p1: UnsafeCell::new(DOMPointInner { - inner: RefCell::new(Vector4::new(*x, *y, 0.0, 1.0)), - }), - p2: UnsafeCell::new(DOMPointInner { - inner: RefCell::new(Vector4::new(*x + *width, *y, 0.0, 1.0)), - }), - p3: UnsafeCell::new(DOMPointInner { - inner: RefCell::new(Vector4::new(*x + *width, *y + *height, 0.0, 1.0)), - }), - p4: UnsafeCell::new(DOMPointInner { - inner: RefCell::new(Vector4::new(*x, *y + *height, 0.0, 1.0)), - }), + p1: create_point(scope, *x, *y, 0.0, 1.0), + p2: create_point(scope, *x + *width, *y, 0.0, 1.0), + p3: create_point(scope, *x + *width, *y + *height, 0.0, 1.0), + p4: create_point(scope, *x, *y + *height, 0.0, 1.0), } } #[reentrant] #[static_method] #[cppgc] - pub fn from_quad(#[webidl] quad: DOMQuadInit) -> DOMQuadInner { + pub fn from_quad( + scope: &mut v8::HandleScope, + #[webidl] quad: DOMQuadInit, + ) -> DOMQuadInner { #[inline] - fn from_point(point: DOMPointInit) -> DOMPointInner { - DOMPointInner { + fn from_point( + scope: &mut v8::HandleScope, + point: DOMPointInit, + ) -> SameObject { + let obj = SameObject::new(); + obj.get(scope, |_| DOMPointInner { inner: RefCell::new(Vector4::new( *point.x, *point.y, *point.z, *point.w, )), - } + }); + obj } DOMQuadInner { - p1: UnsafeCell::new(from_point(quad.p1)), - p2: UnsafeCell::new(from_point(quad.p2)), - p3: UnsafeCell::new(from_point(quad.p3)), - p4: UnsafeCell::new(from_point(quad.p4)), + p1: from_point(scope, quad.p1), + p2: from_point(scope, quad.p2), + p3: from_point(scope, quad.p3), + p4: from_point(scope, quad.p4), } } - #[cppgc] #[getter] - pub fn p1(&self) -> DOMPointInner { - // SAFETY: ptr is alive - unsafe { ptr::read(self.p1.get()) } + #[global] + pub fn p1(&self, scope: &mut v8::HandleScope) -> v8::Global { + self.p1.get(scope, |_| unreachable!()) } - #[cppgc] #[getter] - pub fn p2(&self) -> DOMPointInner { - // SAFETY: ptr is alive - unsafe { ptr::read(self.p2.get()) } + #[global] + pub fn p2(&self, scope: &mut v8::HandleScope) -> v8::Global { + self.p2.get(scope, |_| unreachable!()) } - #[cppgc] #[getter] - pub fn p3(&self) -> DOMPointInner { - // SAFETY: ptr is alive - unsafe { ptr::read(self.p3.get()) } + #[global] + pub fn p3(&self, scope: &mut v8::HandleScope) -> v8::Global { + self.p3.get(scope, |_| unreachable!()) } - #[cppgc] #[getter] - pub fn p4(&self) -> DOMPointInner { - // SAFETY: ptr is alive - unsafe { ptr::read(self.p4.get()) } + #[global] + pub fn p4(&self, scope: &mut v8::HandleScope) -> v8::Global { + self.p4.get(scope, |_| unreachable!()) } #[cppgc] - pub fn get_bounds(&self) -> DOMRectInner { - // SAFETY: ptr is alive - let p1 = unsafe { ptr::read(self.p1.get()) }; - // SAFETY: ptr is alive - let p2 = unsafe { ptr::read(self.p2.get()) }; - // SAFETY: ptr is alive - let p3 = unsafe { ptr::read(self.p3.get()) }; - // SAFETY: ptr is alive - let p4 = unsafe { ptr::read(self.p4.get()) }; - let p1 = p1.inner.borrow(); - let p2 = p2.inner.borrow(); - let p3 = p3.inner.borrow(); - let p4 = p4.inner.borrow(); + pub fn get_bounds(&self, scope: &mut v8::HandleScope) -> DOMRectInner { + let p1 = self.p1.get(scope, |_| unreachable!()); + let p2 = self.p2.get(scope, |_| unreachable!()); + let p3 = self.p3.get(scope, |_| unreachable!()); + let p4 = self.p4.get(scope, |_| unreachable!()); + let p1 = v8::Local::new(scope, p1); + let p2 = v8::Local::new(scope, p2); + let p3 = v8::Local::new(scope, p3); + let p4 = v8::Local::new(scope, p4); + let p1 = cppgc::try_unwrap_cppgc_object::(scope, p1.cast()) + .unwrap(); + let p2 = cppgc::try_unwrap_cppgc_object::(scope, p2.cast()) + .unwrap(); + let p3 = cppgc::try_unwrap_cppgc_object::(scope, p3.cast()) + .unwrap(); + let p4 = cppgc::try_unwrap_cppgc_object::(scope, p4.cast()) + .unwrap(); + let p1 = *p1.inner.borrow(); + let p2 = *p2.inner.borrow(); + let p3 = *p3.inner.borrow(); + let p4 = *p4.inner.borrow(); let left = minimum(minimum(p1.x, p2.x), minimum(p3.x, p4.x)); let top = minimum(minimum(p1.y, p2.y), minimum(p3.y, p4.y)); let right = maximum(maximum(p1.x, p2.x), maximum(p3.x, p4.x)); From 65e579e9cb72b748d57dee411158f6f030c4f43d Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 24 Jan 2025 01:38:42 +0900 Subject: [PATCH 20/63] update expectation.json --- tests/wpt/runner/expectation.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/wpt/runner/expectation.json b/tests/wpt/runner/expectation.json index 65e1fa8ae2691a..5d1ce692c5030b 100644 --- a/tests/wpt/runner/expectation.json +++ b/tests/wpt/runner/expectation.json @@ -14447,7 +14447,8 @@ "DOMMatrix clone: non-initial values (2d)", "DOMMatrix clone: non-initial values (3d)", "DOMRectList clone" - ] + ], + "DOMMatrix-invertSelf.html": true } } } From a37d7692125f3b9ce8db065ddac967acf28c249f Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 24 Jan 2025 01:58:01 +0900 Subject: [PATCH 21/63] fix --- tests/integration/lsp_tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/lsp_tests.rs b/tests/integration/lsp_tests.rs index 196184f3e08d91..0df43e81294965 100644 --- a/tests/integration/lsp_tests.rs +++ b/tests/integration/lsp_tests.rs @@ -5762,7 +5762,7 @@ fn lsp_jsr_auto_import_completion() { json!({ "triggerKind": 1 }), ); assert!(!list.is_incomplete); - assert_eq!(list.items.len(), 268); + assert_eq!(list.items.len(), 275); let item = list.items.iter().find(|i| i.label == "add").unwrap(); assert_eq!(&item.label, "add"); assert_eq!( @@ -5842,7 +5842,7 @@ fn lsp_jsr_auto_import_completion_import_map() { json!({ "triggerKind": 1 }), ); assert!(!list.is_incomplete); - assert_eq!(list.items.len(), 268); + assert_eq!(list.items.len(), 275); let item = list.items.iter().find(|i| i.label == "add").unwrap(); assert_eq!(&item.label, "add"); assert_eq!(json!(&item.label_details), json!({ "description": "add" })); From 15613a3d5b06e86782a950e8d1675824516ce243 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 24 Jan 2025 02:07:10 +0900 Subject: [PATCH 22/63] tweak --- tests/wpt/runner/expectation.json | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/wpt/runner/expectation.json b/tests/wpt/runner/expectation.json index 5d1ce692c5030b..fe39ee5a36b3b0 100644 --- a/tests/wpt/runner/expectation.json +++ b/tests/wpt/runner/expectation.json @@ -14239,6 +14239,7 @@ "eventsource-constructor-stringify.window.html": false, "eventsource-cross-origin.window.html": false, "eventsource-reconnect.window.html": false, + "request-status-error.window.html": false, "eventsource-constructor-empty-url.any.serviceworker.html": false, "eventsource-constructor-empty-url.any.sharedworker.html": false, "eventsource-constructor-url-bogus.any.serviceworker.html": false, From 5a5bea6005d5e896d932089156b0d238ae6e1463 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 24 Jan 2025 14:11:43 +0900 Subject: [PATCH 23/63] remove LSP global symbols count tests --- tests/integration/lsp_tests.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/integration/lsp_tests.rs b/tests/integration/lsp_tests.rs index 0df43e81294965..d3944581807dc1 100644 --- a/tests/integration/lsp_tests.rs +++ b/tests/integration/lsp_tests.rs @@ -5762,7 +5762,6 @@ fn lsp_jsr_auto_import_completion() { json!({ "triggerKind": 1 }), ); assert!(!list.is_incomplete); - assert_eq!(list.items.len(), 275); let item = list.items.iter().find(|i| i.label == "add").unwrap(); assert_eq!(&item.label, "add"); assert_eq!( @@ -5842,7 +5841,6 @@ fn lsp_jsr_auto_import_completion_import_map() { json!({ "triggerKind": 1 }), ); assert!(!list.is_incomplete); - assert_eq!(list.items.len(), 275); let item = list.items.iter().find(|i| i.label == "add").unwrap(); assert_eq!(&item.label, "add"); assert_eq!(json!(&item.label_details), json!({ "description": "add" })); From cd5927246f506d579783f65e520424a90a3a6787 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 24 Jan 2025 14:37:32 +0900 Subject: [PATCH 24/63] refactor --- ext/geometry/lib.rs | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 4586bfa781586b..b12b9a24a502ca 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -415,22 +415,21 @@ impl DOMQuadInner { #[cppgc] pub fn get_bounds(&self, scope: &mut v8::HandleScope) -> DOMRectInner { - let p1 = self.p1.get(scope, |_| unreachable!()); - let p2 = self.p2.get(scope, |_| unreachable!()); - let p3 = self.p3.get(scope, |_| unreachable!()); - let p4 = self.p4.get(scope, |_| unreachable!()); - let p1 = v8::Local::new(scope, p1); - let p2 = v8::Local::new(scope, p2); - let p3 = v8::Local::new(scope, p3); - let p4 = v8::Local::new(scope, p4); - let p1 = cppgc::try_unwrap_cppgc_object::(scope, p1.cast()) - .unwrap(); - let p2 = cppgc::try_unwrap_cppgc_object::(scope, p2.cast()) - .unwrap(); - let p3 = cppgc::try_unwrap_cppgc_object::(scope, p3.cast()) - .unwrap(); - let p4 = cppgc::try_unwrap_cppgc_object::(scope, p4.cast()) - .unwrap(); + #[inline] + fn get_ptr( + scope: &mut v8::HandleScope, + value: &SameObject, + ) -> cppgc::Ptr { + let value = value.get(scope, |_| unreachable!()); + let value = v8::Local::new(scope, value); + cppgc::try_unwrap_cppgc_object::(scope, value.cast()) + .unwrap() + } + + let p1 = get_ptr(scope, &self.p1); + let p2 = get_ptr(scope, &self.p2); + let p3 = get_ptr(scope, &self.p3); + let p4 = get_ptr(scope, &self.p4); let p1 = *p1.inner.borrow(); let p2 = *p2.inner.borrow(); let p3 = *p3.inner.borrow(); From 52400e02876e737dae9486b830e491483f033b1d Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 9 Apr 2025 02:43:24 +0900 Subject: [PATCH 25/63] wip --- Cargo.lock | 2 +- ext/geometry/01_geometry.js | 550 ++----------- ext/geometry/lib.rs | 1465 ++++++++++++++++++++++++----------- 3 files changed, 1072 insertions(+), 945 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4e36031f896669..5cc874957036e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2007,7 +2007,7 @@ dependencies = [ "deno_core", "deno_error", "nalgebra", - "thiserror 2.0.3", + "thiserror 2.0.12", ] [[package]] diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 81ed2c5f18c0db..0eb04f6cb3207b 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -3,9 +3,11 @@ import { primordials } from "ext:core/mod.js"; import { DOMMatrixInner, - DOMPointInner, - DOMQuadInner, - DOMRectInner, + DOMPoint, + DOMPointReadOnly, + DOMQuad, + DOMRect, + DOMRectReadOnly, } from "ext:core/ops"; const { ArrayPrototypeJoin, @@ -24,306 +26,40 @@ import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; import { DOMException } from "ext:deno_web/01_dom_exception.js"; -const _inner = Symbol("[[inner]]"); -// Property to prevent writing values when an immutable instance is changed to -// a mutable instance by Object.setPrototypeOf -// TODO(petamoriken): Implementing resistance to Object.setPrototypeOf in the WebIDL layer -const _writable = Symbol("[[writable]]"); -const _brand = webidl.brand; - -class DOMPointReadOnly { - [_writable] = false; - /** @type {DOMPointInner} */ - [_inner]; - - constructor(x = 0, y = 0, z = 0, w = 1) { - this[_inner] = new DOMPointInner(x, y, z, w); - this[_brand] = _brand; - } - - static fromPoint(other = { __proto__: null }) { - const point = webidl.createBranded(DOMPointReadOnly); - point[_writable] = false; - point[_inner] = DOMPointInner.fromPoint(other); - return point; - } - - get x() { - webidl.assertBranded(this, DOMPointReadOnlyPrototype); - return this[_inner].x; - } - - get y() { - webidl.assertBranded(this, DOMPointReadOnlyPrototype); - return this[_inner].y; - } - - get z() { - webidl.assertBranded(this, DOMPointReadOnlyPrototype); - return this[_inner].z; - } - - get w() { - webidl.assertBranded(this, DOMPointReadOnlyPrototype); - return this[_inner].w; - } - - matrixTransform(matrix = { __proto__: null }) { - webidl.assertBranded(this, DOMPointReadOnlyPrototype); - let matrixInner; - // fast path for DOMMatrix or DOMMatrixReadOnly - if ( - matrix !== null && - ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, matrix) - ) { - matrixInner = matrix[_inner]; - } else { - matrixInner = DOMMatrixInner.fromMatrix(matrix); - } - const point = webidl.createBranded(DOMPoint); - point[_writable] = true; - point[_inner] = this[_inner].matrixTransform(matrixInner); - return point; - } - - toJSON() { - webidl.assertBranded(this, DOMPointReadOnlyPrototype); - const { x, y, z, w } = this[_inner]; - return { x, y, z, w }; - } - - [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { - return inspect( - createFilteredInspectProxy({ - object: this, - evaluate: ObjectPrototypeIsPrototypeOf(DOMPointReadOnlyPrototype, this), - keys: [ - "x", - "y", - "z", - "w", - ], - }), - inspectOptions, - ); - } -} - -webidl.configureInterface(DOMPointReadOnly); -const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; - -class DOMPoint extends DOMPointReadOnly { - [_writable] = true; - - static fromPoint(other = { __proto__: null }) { - const point = webidl.createBranded(DOMPoint); - point[_writable] = true; - point[_inner] = DOMPointInner.fromPoint(other); - return point; - } - - get x() { - webidl.assertBranded(this, DOMPointPrototype); - return this[_inner].x; - } - set x(value) { - webidl.assertBranded(this, DOMPointPrototype); - assertWritable(this); - this[_inner].x = value; - } - - get y() { - webidl.assertBranded(this, DOMPointPrototype); - return this[_inner].y; - } - set y(value) { - webidl.assertBranded(this, DOMPointPrototype); - assertWritable(this); - this[_inner].y = value; - } - - get z() { - webidl.assertBranded(this, DOMPointPrototype); - return this[_inner].z; - } - set z(value) { - webidl.assertBranded(this, DOMPointPrototype); - assertWritable(this); - this[_inner].z = value; - } - - get w() { - webidl.assertBranded(this, DOMPointPrototype); - return this[_inner].w; - } - set w(value) { - webidl.assertBranded(this, DOMPointPrototype); - assertWritable(this); - this[_inner].w = value; - } - - [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { - return inspect( - createFilteredInspectProxy({ - object: this, - evaluate: ObjectPrototypeIsPrototypeOf(DOMPointPrototype, this), - keys: [ - "x", - "y", - "z", - "w", - ], - }), - inspectOptions, - ); - } -} - -webidl.configureInterface(DOMPoint); const DOMPointPrototype = DOMPoint.prototype; - -class DOMRectReadOnly { - [_writable] = false; - /** @type {DOMRectInner} */ - [_inner]; - - constructor(x = 0, y = 0, width = 0, height = 0) { - this[_inner] = new DOMRectInner(x, y, width, height); - this[_brand] = _brand; - } - - static fromRect(other = { __proto__: null }) { - const rect = webidl.createBranded(DOMRectReadOnly); - rect[_writable] = false; - rect[_inner] = DOMRectInner.fromRect(other); - return rect; - } - - get x() { - webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_inner].x; - } - - get y() { - webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_inner].y; - } - - get width() { - webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_inner].width; - } - - get height() { - webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_inner].height; - } - - get top() { - webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_inner].top; - } - - get right() { - webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_inner].right; - } - - get bottom() { - webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_inner].bottom; - } - - get left() { - webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_inner].left; - } - - toJSON() { - webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const { x, y, width, height, top, right, bottom, left } = this[_inner]; - return { x, y, width, height, top, right, bottom, left }; - } - - [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { +const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; +ObjectDefineProperty(DOMPointReadOnlyPrototype, SymbolFor("Deno.privateCustomInspect"), { + __proto__: null, + value: function customInspect(inspect, inspectOptions) { return inspect( createFilteredInspectProxy({ object: this, - evaluate: ObjectPrototypeIsPrototypeOf(DOMRectReadOnlyPrototype, this), - keys: [ - "x", - "y", - "width", - "height", - "top", - "right", - "bottom", - "left", - ], + evaluate: ObjectPrototypeIsPrototypeOf( + DOMPointReadOnlyPrototype, + this, + ), + keys: ["x", "y", "z", "w"], }), inspectOptions, ); - } -} + }, + enumerable: false, + writable: true, + configurable: true, +}); -webidl.configureInterface(DOMRectReadOnly); +const DOMRectPrototype = DOMRect.prototype; const DOMRectReadOnlyPrototype = DOMRectReadOnly.prototype; - -class DOMRect extends DOMRectReadOnly { - [_writable] = true; - - static fromRect(other = { __proto__: null }) { - const rect = webidl.createBranded(DOMRect); - rect[_writable] = true; - rect[_inner] = DOMRectInner.fromRect(other); - return rect; - } - - get x() { - webidl.assertBranded(this, DOMRectPrototype); - return this[_inner].x; - } - set x(value) { - webidl.assertBranded(this, DOMRectPrototype); - assertWritable(this); - this[_inner].x = value; - } - - get y() { - webidl.assertBranded(this, DOMRectPrototype); - return this[_inner].y; - } - set y(value) { - webidl.assertBranded(this, DOMRectPrototype); - assertWritable(this); - this[_inner].y = value; - } - - get width() { - webidl.assertBranded(this, DOMRectPrototype); - return this[_inner].width; - } - set width(value) { - webidl.assertBranded(this, DOMRectPrototype); - assertWritable(this); - this[_inner].width = value; - } - - get height() { - webidl.assertBranded(this, DOMRectPrototype); - return this[_inner].height; - } - set height(value) { - webidl.assertBranded(this, DOMRectPrototype); - assertWritable(this); - this[_inner].height = value; - } - - [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { +ObjectDefineProperty(DOMRectReadOnlyPrototype, SymbolFor("Deno.privateCustomInspect"), { + __proto__: null, + value: function customInspect(inspect, inspectOptions) { return inspect( createFilteredInspectProxy({ object: this, - evaluate: ObjectPrototypeIsPrototypeOf(DOMRectPrototype, this), + evaluate: ObjectPrototypeIsPrototypeOf( + DOMRectReadOnlyPrototype, + this, + ), keys: [ "x", "y", @@ -337,126 +73,16 @@ class DOMRect extends DOMRectReadOnly { }), inspectOptions, ); - } -} - -webidl.configureInterface(DOMRect); -const DOMRectPrototype = DOMRect.prototype; - -const _p1 = Symbol("[[p1]]"); -const _p2 = Symbol("[[p2]]"); -const _p3 = Symbol("[[p3]]"); -const _p4 = Symbol("[[p4]]"); - -class DOMQuad { - /** @type {DOMQuadInner} */ - [_inner]; - /** @type {DOMPoint=} */ - [_p1]; - /** @type {DOMPoint=} */ - [_p2]; - /** @type {DOMPoint=} */ - [_p3]; - /** @type {DOMPoint=} */ - [_p4]; - - constructor( - p1 = { __proto__: null }, - p2 = { __proto__: null }, - p3 = { __proto__: null }, - p4 = { __proto__: null }, - ) { - this[_inner] = new DOMQuadInner(p1, p2, p3, p4); - this[_brand] = _brand; - } - - static fromRect(other = { __proto__: null }) { - const quad = webidl.createBranded(DOMQuad); - quad[_inner] = DOMQuadInner.fromRect(other); - quad[_p1] = undefined; - quad[_p2] = undefined; - quad[_p3] = undefined; - quad[_p4] = undefined; - return quad; - } - - static fromQuad(other = { __proto__: null }) { - const quad = webidl.createBranded(DOMQuad); - quad[_inner] = DOMQuadInner.fromQuad(other); - quad[_p1] = undefined; - quad[_p2] = undefined; - quad[_p3] = undefined; - quad[_p4] = undefined; - return quad; - } - - get p1() { - webidl.assertBranded(this, DOMQuadPrototype); - if (this[_p1] !== undefined) { - return this[_p1]; - } - const point = webidl.createBranded(DOMPoint); - point[_writable] = true; - point[_inner] = this[_inner].p1; - this[_p1] = point; - return point; - } - - get p2() { - webidl.assertBranded(this, DOMQuadPrototype); - if (this[_p2] !== undefined) { - return this[_p2]; - } - const point = webidl.createBranded(DOMPoint); - point[_writable] = true; - point[_inner] = this[_inner].p2; - this[_p2] = point; - return point; - } - - get p3() { - webidl.assertBranded(this, DOMQuadPrototype); - if (this[_p3] !== undefined) { - return this[_p3]; - } - const point = webidl.createBranded(DOMPoint); - point[_writable] = true; - point[_inner] = this[_inner].p3; - this[_p3] = point; - return point; - } - - get p4() { - webidl.assertBranded(this, DOMQuadPrototype); - if (this[_p4] !== undefined) { - return this[_p4]; - } - const point = webidl.createBranded(DOMPoint); - point[_writable] = true; - point[_inner] = this[_inner].p4; - this[_p4] = point; - return point; - } + }, + enumerable: false, + writable: true, + configurable: true, +}); - getBounds() { - webidl.assertBranded(this, DOMQuadPrototype); - const bounds = webidl.createBranded(DOMRect); - bounds[_writable] = true; - bounds[_inner] = this[_inner].getBounds(); - return bounds; - } - - toJSON() { - webidl.assertBranded(this, DOMQuadPrototype); - return { - p1: this[_p1], - p2: this[_p2], - p3: this[_p3], - p4: this[_p4], - }; - } - - [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { +const DOMQuadPrototype = DOMQuad.prototype; +ObjectDefineProperty(DOMQuadPrototype, SymbolFor("Deno.privateCustomInspect"), { + __proto__: null, + value: function customInspect(inspect, inspectOptions) { return inspect( createFilteredInspectProxy({ object: this, @@ -470,11 +96,18 @@ class DOMQuad { }), inspectOptions, ); - } -} + }, + enumerable: false, + writable: true, + configurable: true, +}); -webidl.configureInterface(DOMQuad); -const DOMQuadPrototype = DOMQuad.prototype; +const _inner = Symbol("[[inner]]"); +// Property to prevent writing values when an immutable instance is changed to +// a mutable instance by Object.setPrototypeOf +// TODO(petamoriken): Implementing resistance to Object.setPrototypeOf in the WebIDL layer +const _writable = Symbol("[[writable]]"); +const _brand = webidl.brand; class DOMMatrixReadOnly { [_writable] = false; @@ -867,58 +500,7 @@ class DOMMatrixReadOnly { toJSON() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const { - a, - b, - c, - d, - e, - f, - m11, - m12, - m13, - m14, - m21, - m22, - m23, - m24, - m31, - m32, - m33, - m34, - m41, - m42, - m43, - m44, - is2D, - isIdentity, - } = this[_inner]; - return { - a, - b, - c, - d, - e, - f, - m11, - m12, - m13, - m14, - m21, - m22, - m23, - m24, - m31, - m32, - m33, - m34, - m41, - m42, - m43, - m44, - is2D, - isIdentity, - }; + return this[_inner].toJSON(); } [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { @@ -1364,42 +946,6 @@ class DOMMatrix extends DOMMatrixReadOnly { this[_inner].invertSelf(); return this; } - - [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { - return inspect( - createFilteredInspectProxy({ - object: this, - evaluate: ObjectPrototypeIsPrototypeOf(DOMMatrixPrototype, this), - keys: [ - "a", - "b", - "c", - "d", - "e", - "f", - "m11", - "m12", - "m13", - "m14", - "m21", - "m22", - "m23", - "m24", - "m31", - "m32", - "m33", - "m34", - "m41", - "m42", - "m43", - "m44", - "is2D", - "isIdentity", - ], - }), - inspectOptions, - ); - } } webidl.configureInterface(DOMMatrix); diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 9c530a811dada9..d5a111b50fe908 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -1,5 +1,6 @@ // Copyright 2018-2025 the Deno authors. MIT license. +use std::borrow::Cow; use std::cell::Cell; use std::cell::RefCell; use std::mem; @@ -10,6 +11,9 @@ use deno_core::cppgc::SameObject; use deno_core::op2; use deno_core::v8; use deno_core::webidl; +use deno_core::webidl::WebIdlConverter; +use deno_core::webidl::ContextFn; +use deno_core::webidl::WebIdlError; use deno_core::GarbageCollected; use deno_core::WebIDL; use nalgebra::Matrix3; @@ -24,13 +28,23 @@ use nalgebra::Vector4; deno_core::extension!( deno_geometry, deps = [deno_webidl, deno_web, deno_console], - objects = [DOMPointInner, DOMRectInner, DOMQuadInner, DOMMatrixInner], + objects = [ + DOMPointReadOnly, + DOMPoint, + DOMRectReadOnly, + DOMRect, + DOMQuad, + DOMMatrixInner, + ], esm = ["00_init.js"], lazy_loaded_esm = ["01_geometry.js"], ); #[derive(Debug, thiserror::Error, deno_error::JsError)] pub enum GeometryError { + #[class(inherit)] + #[error(transparent)] + WebIdlError(#[from] WebIdlError), #[class(type)] #[error("Inconsistent 2d matrix value")] Inconsistent2DMatrix, @@ -50,34 +64,61 @@ pub struct DOMPointInit { } #[derive(Debug)] -pub struct DOMPointInner { +pub struct DOMPointReadOnly { inner: RefCell>, } -impl GarbageCollected for DOMPointInner {} +impl GarbageCollected for DOMPointReadOnly {} + +impl DOMPointReadOnly { + fn from_point_inner<'a>( + scope: &mut v8::HandleScope<'a>, + value: v8::Local<'a, v8::Value>, + prefix: Cow<'static, str>, + context: ContextFn<'_>, + ) -> Result { + let init = DOMPointInit::convert(scope, value, prefix, context, &Default::default())?; + Ok(DOMPointReadOnly { + inner: RefCell::new(Vector4::new(*init.x, *init.y, *init.z, *init.w)), + }) + } +} -#[op2] -impl DOMPointInner { +#[op2(base)] +impl DOMPointReadOnly { #[constructor] #[cppgc] - pub fn constructor( - #[webidl] x: webidl::UnrestrictedDouble, - #[webidl] y: webidl::UnrestrictedDouble, - #[webidl] z: webidl::UnrestrictedDouble, - #[webidl] w: webidl::UnrestrictedDouble, - ) -> DOMPointInner { - DOMPointInner { - inner: RefCell::new(Vector4::new(*x, *y, *z, *w)), + pub fn new( + #[webidl] x: Option, + #[webidl] y: Option, + #[webidl] z: Option, + #[webidl] w: Option, + ) -> DOMPointReadOnly { + DOMPointReadOnly { + inner: RefCell::new(Vector4::new( + *x.unwrap_or(webidl::UnrestrictedDouble(0.0)), + *y.unwrap_or(webidl::UnrestrictedDouble(0.0)), + *z.unwrap_or(webidl::UnrestrictedDouble(0.0)), + *w.unwrap_or(webidl::UnrestrictedDouble(1.0)) + )), } } #[reentrant] #[static_method] #[cppgc] - pub fn from_point(#[webidl] init: DOMPointInit) -> DOMPointInner { - DOMPointInner { - inner: RefCell::new(Vector4::new(*init.x, *init.y, *init.z, *init.w)), - } + pub fn from_point<'a>( + scope: &mut v8::HandleScope<'a>, + value: v8::Local<'a, v8::Value>, + ) -> Result { + DOMPointReadOnly::from_point_inner( + scope, + value, + "Failed to execute 'DOMPointReadOnly.fromPoint'".into(), + ContextFn::new_borrowed( + &|| Cow::Borrowed("Argument 1") + ) + ) } #[fast] @@ -86,54 +127,155 @@ impl DOMPointInner { self.inner.borrow().x } - #[setter] - pub fn x(&self, #[webidl] value: webidl::UnrestrictedDouble) { - self.inner.borrow_mut().x = *value - } - #[fast] #[getter] pub fn y(&self) -> f64 { self.inner.borrow().y } - #[setter] - pub fn y(&self, #[webidl] value: webidl::UnrestrictedDouble) { - self.inner.borrow_mut().y = *value - } - #[fast] #[getter] pub fn z(&self) -> f64 { self.inner.borrow().z } - #[setter] - pub fn z(&self, #[webidl] value: webidl::UnrestrictedDouble) { - self.inner.borrow_mut().z = *value - } - #[fast] #[getter] pub fn w(&self) -> f64 { self.inner.borrow().w } - #[setter] - pub fn w(&self, #[webidl] value: webidl::UnrestrictedDouble) { - self.inner.borrow_mut().w = *value + #[rename("toJSON")] + pub fn to_json<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + ) -> v8::Local<'a, v8::Object> { + fn set( + scope: &mut v8::HandleScope, + object: &mut v8::Local, + key: &str, + value: f64, + ) { + let key = v8::String::new(scope, key).unwrap(); + let value = v8::Number::new(scope, value); + object.set(scope, key.into(), value.into()).unwrap(); + } + + let mut obj = v8::Object::new(scope); + set(scope, &mut obj, "x", self.inner.borrow().x); + set(scope, &mut obj, "y", self.inner.borrow().y); + set(scope, &mut obj, "z", self.inner.borrow().z); + set(scope, &mut obj, "w", self.inner.borrow().w); + obj } #[cppgc] - pub fn matrix_transform( + pub fn matrix_transform<'a>( &self, - #[cppgc] matrix: &DOMMatrixInner, - ) -> DOMPointInner { - let out = DOMPointInner { + scope: &mut v8::HandleScope<'a>, + value: v8::Local<'a, v8::Value>, + ) -> Result { + let matrix = DOMMatrixInner::from_matrix_inner( + scope, + value, + "Failed to execute 'DOMPointReadOnly.matrixTransform'".into(), + ContextFn::new_borrowed( + &|| Cow::Borrowed("Argument 1") + ) + )?; + let out = DOMPointReadOnly { inner: RefCell::new(Vector4::zeros()), }; - matrix_transform_point(matrix, self, &out); - out + matrix_transform_point(&matrix, self, &out); + Ok(out) + } +} + +pub struct DOMPoint {} + +impl GarbageCollected for DOMPoint {} + +#[op2(inherit = DOMPointReadOnly)] +impl DOMPoint { + #[constructor] + #[cppgc] + pub fn new( + #[webidl] x: Option, + #[webidl] y: Option, + #[webidl] z: Option, + #[webidl] w: Option, + ) -> (DOMPointReadOnly, DOMPoint) { + let ro = DOMPointReadOnly { + inner: RefCell::new(Vector4::new( + *x.unwrap_or(webidl::UnrestrictedDouble(0.0)), + *y.unwrap_or(webidl::UnrestrictedDouble(0.0)), + *z.unwrap_or(webidl::UnrestrictedDouble(0.0)), + *w.unwrap_or(webidl::UnrestrictedDouble(1.0)) + )), + }; + (ro, DOMPoint {}) + } + + // TODO(petamoriken): returns Result<(DOMPointReadOnly, DOMPoint), GeometryError> + #[reentrant] + #[static_method] + #[cppgc] + pub fn from_point<'a>( + scope: &mut v8::HandleScope<'a>, + value: v8::Local<'a, v8::Value>, + ) -> Result { + DOMPointReadOnly::from_point_inner( + scope, + value, + "Failed to execute 'DOMPoint.fromPoint'".into(), + ContextFn::new_borrowed( + &|| Cow::Borrowed("Argument 1") + ) + ) + } + + #[fast] + #[getter] + pub fn x(&self, #[proto] ro: &DOMPointReadOnly) -> f64 { + ro.inner.borrow().x + } + + #[setter] + pub fn x(&self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMPointReadOnly) { + ro.inner.borrow_mut().x = *value + } + + #[fast] + #[getter] + pub fn y(&self, #[proto] ro: &DOMPointReadOnly) -> f64 { + ro.inner.borrow().y + } + + #[setter] + pub fn y(&self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMPointReadOnly) { + ro.inner.borrow_mut().y = *value + } + + #[fast] + #[getter] + pub fn z(&self, #[proto] ro: &DOMPointReadOnly) -> f64 { + ro.inner.borrow().z + } + + #[setter] + pub fn z(&self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMPointReadOnly) { + ro.inner.borrow_mut().z = *value + } + + #[fast] + #[getter] + pub fn w(&self, #[proto] ro: &DOMPointReadOnly) -> f64 { + ro.inner.borrow().w + } + + #[setter] + pub fn w(&self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMPointReadOnly) { + ro.inner.borrow_mut().w = *value } } @@ -151,43 +293,89 @@ pub struct DOMRectInit { } #[derive(Debug)] -pub struct DOMRectInner { +pub struct DOMRectReadOnly { x: Cell, y: Cell, width: Cell, height: Cell, } -impl GarbageCollected for DOMRectInner {} +impl GarbageCollected for DOMRectReadOnly {} + +impl DOMRectReadOnly { + fn from_rect_inner<'a>( + scope: &mut v8::HandleScope<'a>, + value: v8::Local<'a, v8::Value>, + prefix: Cow<'static, str>, + context: ContextFn<'_>, + ) -> Result { + let init = DOMRectInit::convert(scope, value, prefix, context, &Default::default())?; + Ok(DOMRectReadOnly { + x: Cell::new(*init.x), + y: Cell::new(*init.y), + width: Cell::new(*init.width), + height: Cell::new(*init.height), + }) + } + + fn get_top(&self) -> f64 { + let y = self.y.get(); + let height = self.height.get(); + minimum(y, y + height) + } -#[op2] -impl DOMRectInner { + fn get_right(&self) -> f64 { + let x = self.x.get(); + let width = self.width.get(); + maximum(x, x + width) + } + + fn get_bottom(&self) -> f64 { + let y = self.y.get(); + let height = self.height.get(); + maximum(y, y + height) + } + + fn get_left(&self) -> f64 { + let x = self.x.get(); + let width = self.width.get(); + minimum(x, x + width) + } +} + +#[op2(base)] +impl DOMRectReadOnly { #[constructor] #[cppgc] - pub fn constructor( - #[webidl] x: webidl::UnrestrictedDouble, - #[webidl] y: webidl::UnrestrictedDouble, - #[webidl] width: webidl::UnrestrictedDouble, - #[webidl] height: webidl::UnrestrictedDouble, - ) -> DOMRectInner { - DOMRectInner { - x: Cell::new(*x), - y: Cell::new(*y), - width: Cell::new(*width), - height: Cell::new(*height), + pub fn new( + #[webidl] x: Option, + #[webidl] y: Option, + #[webidl] width: Option, + #[webidl] height: Option, + ) -> DOMRectReadOnly { + DOMRectReadOnly { + x: Cell::new(*x.unwrap_or(webidl::UnrestrictedDouble(0.0))), + y: Cell::new(*y.unwrap_or(webidl::UnrestrictedDouble(0.0))), + width: Cell::new(*width.unwrap_or(webidl::UnrestrictedDouble(0.0))), + height: Cell::new(*height.unwrap_or(webidl::UnrestrictedDouble(0.0))), } } #[reentrant] #[static_method] #[cppgc] - pub fn from_rect(#[webidl] init: DOMRectInit) -> DOMRectInner { - DOMRectInner { - x: Cell::new(*init.x), - y: Cell::new(*init.y), - width: Cell::new(*init.width), - height: Cell::new(*init.height), - } + pub fn from_rect<'a>( + scope: &mut v8::HandleScope<'a>, + value: v8::Local<'a, v8::Value>, + ) -> Result { + DOMRectReadOnly::from_rect_inner( + scope, + value, + "Failed to execute 'DOMRectReadOnly.fromPoint'".into(), + ContextFn::new_borrowed( + &|| Cow::Borrowed("Argument 1") + ) + ) } #[fast] @@ -237,33 +425,139 @@ impl DOMRectInner { #[fast] #[getter] pub fn top(&self) -> f64 { - let y = self.y.get(); - let height = self.height.get(); - minimum(y, y + height) + self.get_top() } #[fast] #[getter] pub fn right(&self) -> f64 { - let x = self.x.get(); - let width = self.width.get(); - maximum(x, x + width) + self.get_right() } #[fast] #[getter] pub fn bottom(&self) -> f64 { - let y = self.y.get(); - let height = self.height.get(); - maximum(y, y + height) + self.get_bottom() } #[fast] #[getter] pub fn left(&self) -> f64 { - let x = self.x.get(); - let width = self.width.get(); - minimum(x, x + width) + self.get_left() + } + + #[rename("toJSON")] + pub fn to_json<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + ) -> v8::Local<'a, v8::Object> { + fn set( + scope: &mut v8::HandleScope, + object: &mut v8::Local, + key: &str, + value: f64, + ) { + let key = v8::String::new(scope, key).unwrap(); + let value = v8::Number::new(scope, value); + object.set(scope, key.into(), value.into()).unwrap(); + } + + let mut obj = v8::Object::new(scope); + set(scope, &mut obj, "x", self.x.get()); + set(scope, &mut obj, "y", self.y.get()); + set(scope, &mut obj, "width", self.width.get()); + set(scope, &mut obj, "height", self.height.get()); + set(scope, &mut obj, "top", self.get_top()); + set(scope, &mut obj, "right", self.get_right()); + set(scope, &mut obj, "bottom", self.get_bottom()); + set(scope, &mut obj, "left", self.get_left()); + obj + } +} + +pub struct DOMRect {} + +impl GarbageCollected for DOMRect {} + +#[op2(inherit = DOMRectReadOnly)] +impl DOMRect { + #[constructor] + #[cppgc] + pub fn new( + #[webidl] x: Option, + #[webidl] y: Option, + #[webidl] width: Option, + #[webidl] height: Option, + ) -> (DOMRectReadOnly, DOMRect) { + let ro = DOMRectReadOnly { + x: Cell::new(*x.unwrap_or(webidl::UnrestrictedDouble(0.0))), + y: Cell::new(*y.unwrap_or(webidl::UnrestrictedDouble(0.0))), + width: Cell::new(*width.unwrap_or(webidl::UnrestrictedDouble(0.0))), + height: Cell::new(*height.unwrap_or(webidl::UnrestrictedDouble(0.0))), + }; + (ro, DOMRect {}) + } + + // TODO(petamoriken): returns Result<(DOMRectReadOnly, DOMPoint), GeometryError> + #[reentrant] + #[static_method] + #[cppgc] + pub fn from_rect<'a>( + scope: &mut v8::HandleScope<'a>, + value: v8::Local<'a, v8::Value>, + ) -> Result { + DOMRectReadOnly::from_rect_inner( + scope, + value, + "Failed to execute 'DOMRect.fromRect'".into(), + ContextFn::new_borrowed( + &|| Cow::Borrowed("Argument 1") + ) + ) + } + + #[fast] + #[getter] + pub fn x(&self, #[proto] ro: &DOMRectReadOnly) -> f64 { + ro.x.get() + } + + #[setter] + pub fn x(&self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMRectReadOnly) { + ro.x.set(*value) + } + + #[fast] + #[getter] + pub fn y(&self, #[proto] ro: &DOMRectReadOnly) -> f64 { + ro.y.get() + } + + #[setter] + pub fn y(&self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMRectReadOnly) { + ro.y.set(*value) + } + + #[fast] + #[getter] + pub fn width(&self, #[proto] ro: &DOMRectReadOnly) -> f64 { + ro.width.get() + } + + #[setter] + pub fn width(&self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMRectReadOnly) { + ro.width.set(*value) + } + + #[fast] + #[getter] + pub fn height(&self, #[proto] ro: &DOMRectReadOnly) -> f64 { + ro.height.get() + } + + #[setter] + pub fn height(&self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMRectReadOnly) { + ro.height.set(*value) } } @@ -276,17 +570,18 @@ pub struct DOMQuadInit { p4: DOMPointInit, } -pub struct DOMQuadInner { - p1: SameObject, - p2: SameObject, - p3: SameObject, - p4: SameObject, +// TODO(petamoriken): store SameObject +pub struct DOMQuad { + p1: SameObject, + p2: SameObject, + p3: SameObject, + p4: SameObject, } -impl GarbageCollected for DOMQuadInner {} +impl GarbageCollected for DOMQuad {} #[op2] -impl DOMQuadInner { +impl DOMQuad { #[constructor] #[reentrant] #[cppgc] @@ -296,22 +591,22 @@ impl DOMQuadInner { #[webidl] p2: DOMPointInit, #[webidl] p3: DOMPointInit, #[webidl] p4: DOMPointInit, - ) -> DOMQuadInner { + ) -> DOMQuad { #[inline] fn from_point( scope: &mut v8::HandleScope, point: DOMPointInit, - ) -> SameObject { + ) -> SameObject { let obj = SameObject::new(); - obj.get(scope, |_| DOMPointInner { + obj.set(scope, DOMPointReadOnly { inner: RefCell::new(Vector4::new( *point.x, *point.y, *point.z, *point.w, )), - }); + }).unwrap(); obj } - DOMQuadInner { + DOMQuad { p1: from_point(scope, p1), p2: from_point(scope, p2), p3: from_point(scope, p3), @@ -325,7 +620,7 @@ impl DOMQuadInner { pub fn from_rect( scope: &mut v8::HandleScope, #[webidl] rect: DOMRectInit, - ) -> DOMQuadInner { + ) -> DOMQuad { #[inline] fn create_point( scope: &mut v8::HandleScope, @@ -333,11 +628,11 @@ impl DOMQuadInner { y: f64, z: f64, w: f64, - ) -> SameObject { + ) -> SameObject { let obj = SameObject::new(); - obj.get(scope, |_| DOMPointInner { + obj.set(scope, DOMPointReadOnly { inner: RefCell::new(Vector4::new(x, y, z, w)), - }); + }).unwrap(); obj } @@ -347,7 +642,7 @@ impl DOMQuadInner { width, height, } = rect; - DOMQuadInner { + DOMQuad { p1: create_point(scope, *x, *y, 0.0, 1.0), p2: create_point(scope, *x + *width, *y, 0.0, 1.0), p3: create_point(scope, *x + *width, *y + *height, 0.0, 1.0), @@ -361,22 +656,22 @@ impl DOMQuadInner { pub fn from_quad( scope: &mut v8::HandleScope, #[webidl] quad: DOMQuadInit, - ) -> DOMQuadInner { + ) -> DOMQuad { #[inline] fn from_point( scope: &mut v8::HandleScope, point: DOMPointInit, - ) -> SameObject { + ) -> SameObject { let obj = SameObject::new(); - obj.get(scope, |_| DOMPointInner { + obj.set(scope, DOMPointReadOnly { inner: RefCell::new(Vector4::new( *point.x, *point.y, *point.z, *point.w, )), - }); + }).unwrap(); obj } - DOMQuadInner { + DOMQuad { p1: from_point(scope, quad.p1), p2: from_point(scope, quad.p2), p3: from_point(scope, quad.p3), @@ -409,15 +704,15 @@ impl DOMQuadInner { } #[cppgc] - pub fn get_bounds(&self, scope: &mut v8::HandleScope) -> DOMRectInner { + pub fn get_bounds(&self, scope: &mut v8::HandleScope) -> DOMRectReadOnly { #[inline] fn get_ptr( scope: &mut v8::HandleScope, - value: &SameObject, - ) -> cppgc::Ptr { + value: &SameObject, + ) -> cppgc::Ptr { let value = value.get(scope, |_| unreachable!()); let value = v8::Local::new(scope, value); - cppgc::try_unwrap_cppgc_object::(scope, value.cast()) + cppgc::try_unwrap_cppgc_object::(scope, value.cast()) .unwrap() } @@ -433,13 +728,41 @@ impl DOMQuadInner { let top = minimum(minimum(p1.y, p2.y), minimum(p3.y, p4.y)); let right = maximum(maximum(p1.x, p2.x), maximum(p3.x, p4.x)); let bottom = maximum(maximum(p1.y, p2.y), maximum(p3.y, p4.y)); - DOMRectInner { + DOMRectReadOnly { x: Cell::new(left), y: Cell::new(top), width: Cell::new(right - left), height: Cell::new(bottom - top), } } + + #[rename("toJSON")] + pub fn to_json<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + ) -> v8::Local<'a, v8::Object> { + fn set( + scope: &mut v8::HandleScope, + object: &mut v8::Local, + key: &str, + value: v8::Global, + ) { + let key = v8::String::new(scope, key).unwrap(); + let value = v8::Local::new(scope, value); + object.set(scope, key.into(), value.into()).unwrap(); + } + + let mut obj = v8::Object::new(scope); + let p1 = self.p1.get(scope, |_| unreachable!()); + let p2 = self.p2.get(scope, |_| unreachable!()); + let p3 = self.p3.get(scope, |_| unreachable!()); + let p4 = self.p4.get(scope, |_| unreachable!()); + set(scope, &mut obj, "p1", p1); + set(scope, &mut obj, "p2", p2); + set(scope, &mut obj, "p3", p3); + set(scope, &mut obj, "p4", p4); + obj + } } #[derive(WebIDL, Debug)] @@ -493,55 +816,501 @@ pub struct DOMMatrixInit { is_2d: Option, } -#[derive(Debug, Clone)] -pub struct DOMMatrixInner { - inner: RefCell>, - is_2d: Cell, -} +#[derive(Debug, Clone)] +pub struct DOMMatrixInner { + inner: RefCell>, + is_2d: Cell, +} + +impl GarbageCollected for DOMMatrixInner {} + +/* + * NOTE: column-major order + * + * For a 2D 3x2 matrix, the index of properties in + * | a c 0 e | | 0 4 _ 12 | + * | b d 0 f | | 1 5 _ 13 | + * | 0 0 1 0 | is | _ _ _ _ | + * | 0 0 0 1 | | _ _ _ _ | + */ +const INDEX_A: usize = 0; +const INDEX_B: usize = 1; +const INDEX_C: usize = 4; +const INDEX_D: usize = 5; +const INDEX_E: usize = 12; +const INDEX_F: usize = 13; + +/* + * NOTE: column-major order + * + * The index of properties in + * | m11 m21 m31 m41 | | 0 4 8 12 | + * | m12 m22 m32 m42 | | 1 5 9 13 | + * | m13 m23 m33 m43 | is | 2 6 10 14 | + * | m14 m24 m34 m44 | | 3 7 11 15 | + */ +const INDEX_M11: usize = 0; +const INDEX_M12: usize = 1; +const INDEX_M13: usize = 2; +const INDEX_M14: usize = 3; +const INDEX_M21: usize = 4; +const INDEX_M22: usize = 5; +const INDEX_M23: usize = 6; +const INDEX_M24: usize = 7; +const INDEX_M31: usize = 8; +const INDEX_M32: usize = 9; +const INDEX_M33: usize = 10; +const INDEX_M34: usize = 11; +const INDEX_M41: usize = 12; +const INDEX_M42: usize = 13; +const INDEX_M43: usize = 14; +const INDEX_M44: usize = 15; + +impl DOMMatrixInner { + fn from_matrix_inner<'a>( + scope: &mut v8::HandleScope<'a>, + value: v8::Local<'a, v8::Value>, + prefix: Cow<'static, str>, + context: ContextFn<'_>, + ) -> Result { + let init = DOMMatrixInit::convert(scope, value, prefix, context, &Default::default())?; + macro_rules! fixup { + ($value3d:expr, $value2d:expr, $default:expr) => {{ + if let Some(value3d) = $value3d { + if let Some(value2d) = $value2d { + if !(*value3d == *value2d || value3d.is_nan() && value2d.is_nan()) { + return Err(GeometryError::Inconsistent2DMatrix); + } + } + value3d + } else if let Some(value2d) = $value2d { + value2d + } else { + webidl::UnrestrictedDouble($default) + } + }}; + } + + let m11 = fixup!(init.m11, init.a, 1.0); + let m12 = fixup!(init.m12, init.b, 0.0); + let m21 = fixup!(init.m21, init.c, 0.0); + let m22 = fixup!(init.m22, init.d, 1.0); + let m41 = fixup!(init.m41, init.e, 0.0); + let m42 = fixup!(init.m42, init.f, 0.0); + let is_2d = { + let is_2d_can_be_true = *init.m13 == 0.0 + && *init.m14 == 0.0 + && *init.m23 == 0.0 + && *init.m24 == 0.0 + && *init.m31 == 0.0 + && *init.m32 == 0.0 + && *init.m33 == 1.0 + && *init.m34 == 0.0 + && *init.m43 == 0.0 + && *init.m44 == 1.0; + if let Some(is_2d) = init.is_2d { + if is_2d && !is_2d_can_be_true { + return Err(GeometryError::Inconsistent2DMatrix); + } else { + is_2d + } + } else { + is_2d_can_be_true + } + }; + + if is_2d { + Ok(DOMMatrixInner { + #[rustfmt::skip] + inner: RefCell::new(Matrix4::new( + *m11, *m21, 0.0, *m41, + *m12, *m22, 0.0, *m42, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, + )), + is_2d: Cell::new(true), + }) + } else { + let DOMMatrixInit { + m13, + m14, + m23, + m24, + m31, + m32, + m33, + m34, + m43, + m44, + .. + } = init; + Ok(DOMMatrixInner { + #[rustfmt::skip] + inner: RefCell::new(Matrix4::new( + *m11, *m21, *m31, *m41, + *m12, *m22, *m32, *m42, + *m13, *m23, *m33, *m43, + *m14, *m24, *m34, *m44, + )), + is_2d: Cell::new(false), + }) + } + } + + #[inline] + fn translate_self_inner(&self, tx: f64, ty: f64, tz: f64) { + let mut inner = self.inner.borrow_mut(); + let is_2d = self.is_2d.get(); + let shift = Vector3::new(tx, ty, tz); + inner.prepend_translation_mut(&shift); + self.is_2d.set(is_2d && tz == 0.0); + } + + #[inline] + fn scale_without_origin_self_inner( + &self, + sx: f64, + sy: f64, + sz: f64, + ) { + let mut inner = self.inner.borrow_mut(); + let is_2d = self.is_2d.get(); + let scaling = Vector3::new(sx, sy, sz); + inner.prepend_nonuniform_scaling_mut(&scaling); + self.is_2d.set(is_2d && sz == 1.0); + } + + #[inline] + fn scale_with_origin_self_inner( + &self, + sx: f64, + sy: f64, + sz: f64, + origin_x: f64, + origin_y: f64, + origin_z: f64, + ) { + let mut inner = self.inner.borrow_mut(); + let is_2d = self.is_2d.get(); + let scaling = Vector3::new(sx, sy, sz); + let mut shift = Vector3::new(origin_x, origin_y, origin_z); + inner.prepend_translation_mut(&shift); + inner.prepend_nonuniform_scaling_mut(&scaling); + shift.neg_mut(); + inner.prepend_translation_mut(&shift); + self.is_2d.set(is_2d && sz == 1.0 && origin_z == 0.0); + } + + #[inline] + fn rotate_self_inner( + &self, + roll_deg: f64, + pitch_deg: f64, + yaw_deg: f64, + ) { + let mut inner = self.inner.borrow_mut(); + let is_2d = self.is_2d.get(); + let rotation = Rotation3::from_euler_angles( + roll_deg.to_radians(), + pitch_deg.to_radians(), + yaw_deg.to_radians(), + ) + .to_homogeneous(); + let mut result = Matrix4x3::zeros(); + inner.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); + inner.set_column(0, &result.column(0)); + inner.set_column(1, &result.column(1)); + inner.set_column(2, &result.column(2)); + self + .is_2d + .set(is_2d && roll_deg == 0.0 && pitch_deg == 0.0); + } + + #[inline] + fn rotate_from_vector_self_inner(&self, x: f64, y: f64) { + let mut inner = self.inner.borrow_mut(); + let rotation = + Rotation3::from_axis_angle(&Vector3::z_axis(), y.atan2(x)).to_homogeneous(); + let mut result = Matrix4x3::zeros(); + inner.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); + inner.set_column(0, &result.column(0)); + inner.set_column(1, &result.column(1)); + inner.set_column(2, &result.column(2)); + } + + #[inline] + fn rotate_axis_angle_self_inner( + &self, + x: f64, + y: f64, + z: f64, + angle_deg: f64, + ) { + if x == 0.0 && y == 0.0 && z == 0.0 { + return; + } + let mut inner = self.inner.borrow_mut(); + let is_2d = self.is_2d.get(); + let rotation = Rotation3::from_axis_angle( + &UnitVector3::new_normalize(Vector3::new(x, y, z)), + angle_deg.to_radians(), + ) + .to_homogeneous(); + let mut result = Matrix4x3::zeros(); + inner.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); + inner.set_column(0, &result.column(0)); + inner.set_column(1, &result.column(1)); + inner.set_column(2, &result.column(2)); + self.is_2d.set(is_2d && x == 0.0 && y == 0.0); + } + + #[inline] + fn skew_x_self_inner(&self, x_deg: f64) { + let mut inner = self.inner.borrow_mut(); + let skew = + Matrix4x2::new(1.0, x_deg.to_radians().tan(), 0.0, 1.0, 0.0, 0.0, 0.0, 0.0); + let mut result = Matrix4x2::zeros(); + inner.mul_to(&skew, &mut result); + inner.set_column(0, &result.column(0)); + inner.set_column(1, &result.column(1)); + } + + #[inline] + fn skew_y_self_inner(&self, y_deg: f64) { + let mut inner = self.inner.borrow_mut(); + let skew = + Matrix4x2::new(1.0, 0.0, y_deg.to_radians().tan(), 1.0, 0.0, 0.0, 0.0, 0.0); + let mut result = Matrix4x2::zeros(); + inner.mul_to(&skew, &mut result); + inner.set_column(0, &result.column(0)); + inner.set_column(1, &result.column(1)); + } + + #[inline] + fn multiply_self_inner( + &self, + lhs: &DOMMatrixInner, + rhs: &DOMMatrixInner, + ) { + let lhs_inner = lhs.inner.borrow(); + let lhs_is_2d = lhs.is_2d.get(); + let rhs_inner = rhs.inner.borrow(); + let rhs_is_2d = rhs.is_2d.get(); + let mut out_inner = self.inner.borrow_mut(); + lhs_inner.mul_to(&rhs_inner, &mut out_inner); + self.is_2d.set(lhs_is_2d && rhs_is_2d); + } + + #[inline] + fn flip_x_inner(&self) { + let mut inner = self.inner.borrow_mut(); + inner.column_mut(0).neg_mut(); + } + + #[inline] + fn flip_y_inner(&self) { + let mut inner = self.inner.borrow_mut(); + inner.column_mut(1).neg_mut(); + } + + #[inline] + fn invert_self_inner(&self) { + let mut inner = self.inner.borrow_mut(); + let is_2d = self.is_2d.get(); + if inner.iter().any(|&x| x.is_infinite()) { + inner.fill(f64::NAN); + self.is_2d.set(false); + return; + } + if is_2d { + // SAFETY: in-range access + let mut matrix3 = unsafe { + Matrix3::new( + *inner.get_unchecked(INDEX_A), + *inner.get_unchecked(INDEX_C), + *inner.get_unchecked(INDEX_E), + *inner.get_unchecked(INDEX_B), + *inner.get_unchecked(INDEX_D), + *inner.get_unchecked(INDEX_F), + 0.0, + 0.0, + 1.0, + ) + }; + if !matrix3.try_inverse_mut() { + inner.fill(f64::NAN); + self.is_2d.set(false); + return; + } + // SAFETY: in-range access + unsafe { + *inner.get_unchecked_mut(INDEX_A) = *matrix3.get_unchecked(0); + *inner.get_unchecked_mut(INDEX_B) = *matrix3.get_unchecked(1); + *inner.get_unchecked_mut(INDEX_C) = *matrix3.get_unchecked(3); + *inner.get_unchecked_mut(INDEX_D) = *matrix3.get_unchecked(4); + *inner.get_unchecked_mut(INDEX_E) = *matrix3.get_unchecked(6); + *inner.get_unchecked_mut(INDEX_F) = *matrix3.get_unchecked(7); + } + } else if !inner.try_inverse_mut() { + inner.fill(f64::NAN); + } + } + + #[inline] + fn get_a(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_A) } + } + + #[inline] + fn get_b(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_B) } + } + + #[inline] + fn get_c(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_C) } + } + + #[inline] + fn get_d(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_D) } + } + + #[inline] + fn get_e(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_E) } + } + + #[inline] + fn get_f(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_F) } + } + + #[inline] + fn get_m11(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M11) } + } + + #[inline] + fn get_m12(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M12) } + } -impl GarbageCollected for DOMMatrixInner {} + #[inline] + fn get_m13(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M13) } + } -/* - * NOTE: column-major order - * - * For a 2D 3x2 matrix, the index of properties in - * | a c 0 e | | 0 4 _ 12 | - * | b d 0 f | | 1 5 _ 13 | - * | 0 0 1 0 | is | _ _ _ _ | - * | 0 0 0 1 | | _ _ _ _ | - */ -const INDEX_A: usize = 0; -const INDEX_B: usize = 1; -const INDEX_C: usize = 4; -const INDEX_D: usize = 5; -const INDEX_E: usize = 12; -const INDEX_F: usize = 13; + #[inline] + fn get_m14(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M14) } + } -/* - * NOTE: column-major order - * - * The index of properties in - * | m11 m21 m31 m41 | | 0 4 8 12 | - * | m12 m22 m32 m42 | | 1 5 9 13 | - * | m13 m23 m33 m43 | is | 2 6 10 14 | - * | m14 m24 m34 m44 | | 3 7 11 15 | - */ -const INDEX_M11: usize = 0; -const INDEX_M12: usize = 1; -const INDEX_M13: usize = 2; -const INDEX_M14: usize = 3; -const INDEX_M21: usize = 4; -const INDEX_M22: usize = 5; -const INDEX_M23: usize = 6; -const INDEX_M24: usize = 7; -const INDEX_M31: usize = 8; -const INDEX_M32: usize = 9; -const INDEX_M33: usize = 10; -const INDEX_M34: usize = 11; -const INDEX_M41: usize = 12; -const INDEX_M42: usize = 13; -const INDEX_M43: usize = 14; -const INDEX_M44: usize = 15; + #[inline] + fn get_m21(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M21) } + } + + #[inline] + fn get_m22(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M22) } + } + + #[inline] + fn get_m23(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M23) } + } + + #[inline] + fn get_m24(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M24) } + } + + #[inline] + fn get_m31(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M31) } + } + + #[inline] + fn get_m32(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M32) } + } + + #[inline] + fn get_m33(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M33) } + } + + #[inline] + fn get_m34(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M34) } + } + + #[inline] + fn get_m41(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M41) } + } + + #[inline] + fn get_m42(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M42) } + } + + #[inline] + fn get_m43(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M43) } + } + + #[inline] + fn get_m44(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M44) } + } + + fn get_is_identity(&self) -> bool { + let inner = self.inner.borrow(); + // SAFETY: in-range access + unsafe { + *inner.get_unchecked(INDEX_M11) == 1.0 + && *inner.get_unchecked(INDEX_M12) == 0.0 + && *inner.get_unchecked(INDEX_M13) == 0.0 + && *inner.get_unchecked(INDEX_M14) == 0.0 + && *inner.get_unchecked(INDEX_M21) == 0.0 + && *inner.get_unchecked(INDEX_M22) == 1.0 + && *inner.get_unchecked(INDEX_M23) == 0.0 + && *inner.get_unchecked(INDEX_M24) == 0.0 + && *inner.get_unchecked(INDEX_M31) == 0.0 + && *inner.get_unchecked(INDEX_M32) == 0.0 + && *inner.get_unchecked(INDEX_M33) == 1.0 + && *inner.get_unchecked(INDEX_M34) == 0.0 + && *inner.get_unchecked(INDEX_M41) == 0.0 + && *inner.get_unchecked(INDEX_M42) == 0.0 + && *inner.get_unchecked(INDEX_M43) == 0.0 + && *inner.get_unchecked(INDEX_M44) == 1.0 + } + } +} #[op2] impl DOMMatrixInner { @@ -660,8 +1429,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn a(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_A) } + self.get_a() } #[setter] @@ -675,8 +1443,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn b(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_B) } + self.get_b() } #[setter] @@ -690,8 +1457,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn c(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_C) } + self.get_c() } #[setter] @@ -705,8 +1471,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn d(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_D) } + self.get_d() } #[setter] @@ -720,8 +1485,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn e(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_E) } + self.get_e() } #[setter] @@ -735,8 +1499,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn f(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_F) } + self.get_f() } #[setter] @@ -750,8 +1513,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn m11(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M11) } + self.get_m11() } #[setter] @@ -765,8 +1527,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn m12(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M12) } + self.get_m12() } #[setter] @@ -780,8 +1541,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn m13(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M13) } + self.get_m13() } #[setter] @@ -798,8 +1558,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn m14(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M14) } + self.get_m14() } #[setter] @@ -816,8 +1575,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn m21(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M21) } + self.get_m21() } #[setter] @@ -831,8 +1589,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn m22(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M22) } + self.get_m22() } #[setter] @@ -846,8 +1603,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn m23(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M23) } + self.get_m23() } #[setter] @@ -864,8 +1620,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn m24(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M24) } + self.get_m24() } #[setter] @@ -882,8 +1637,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn m31(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M31) } + self.get_m31() } #[setter] @@ -900,8 +1654,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn m32(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M32) } + self.get_m32() } #[setter] @@ -918,8 +1671,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn m33(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M33) } + self.get_m33() } #[setter] @@ -936,8 +1688,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn m34(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M34) } + self.get_m34() } #[setter] @@ -954,8 +1705,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn m41(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M41) } + self.get_m41() } #[setter] @@ -969,8 +1719,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn m42(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M42) } + self.get_m42() } #[setter] @@ -984,8 +1733,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn m43(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M43) } + self.get_m43() } #[setter] @@ -1002,8 +1750,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn m44(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M44) } + self.get_m44() } #[setter] @@ -1026,26 +1773,7 @@ impl DOMMatrixInner { #[fast] #[getter] pub fn is_identity(&self) -> bool { - let inner = self.inner.borrow(); - // SAFETY: in-range access - unsafe { - *inner.get_unchecked(INDEX_M11) == 1.0 - && *inner.get_unchecked(INDEX_M12) == 0.0 - && *inner.get_unchecked(INDEX_M13) == 0.0 - && *inner.get_unchecked(INDEX_M14) == 0.0 - && *inner.get_unchecked(INDEX_M21) == 0.0 - && *inner.get_unchecked(INDEX_M22) == 1.0 - && *inner.get_unchecked(INDEX_M23) == 0.0 - && *inner.get_unchecked(INDEX_M24) == 0.0 - && *inner.get_unchecked(INDEX_M31) == 0.0 - && *inner.get_unchecked(INDEX_M32) == 0.0 - && *inner.get_unchecked(INDEX_M33) == 1.0 - && *inner.get_unchecked(INDEX_M34) == 0.0 - && *inner.get_unchecked(INDEX_M41) == 0.0 - && *inner.get_unchecked(INDEX_M42) == 0.0 - && *inner.get_unchecked(INDEX_M43) == 0.0 - && *inner.get_unchecked(INDEX_M44) == 1.0 - } + self.get_is_identity() } #[fast] @@ -1078,7 +1806,7 @@ impl DOMMatrixInner { #[webidl] tz: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_translate(&out, *tx, *ty, *tz); + out.translate_self_inner(*tx, *ty, *tz); out } @@ -1088,7 +1816,7 @@ impl DOMMatrixInner { #[webidl] ty: webidl::UnrestrictedDouble, #[webidl] tz: webidl::UnrestrictedDouble, ) { - matrix_translate(self, *tx, *ty, *tz); + self.translate_self_inner(*tx, *ty, *tz); } #[cppgc] @@ -1099,7 +1827,7 @@ impl DOMMatrixInner { #[webidl] sz: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_scale_without_origin(&out, *sx, *sy, *sz); + out.scale_without_origin_self_inner(*sx, *sy, *sz); out } @@ -1109,7 +1837,7 @@ impl DOMMatrixInner { #[webidl] sy: webidl::UnrestrictedDouble, #[webidl] sz: webidl::UnrestrictedDouble, ) { - matrix_scale_without_origin(self, *sx, *sy, *sz); + self.scale_without_origin_self_inner(*sx, *sy, *sz); } #[cppgc] @@ -1123,8 +1851,8 @@ impl DOMMatrixInner { #[webidl] origin_z: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_scale_with_origin( - &out, *sx, *sy, *sz, *origin_x, *origin_y, *origin_z, + out.scale_with_origin_self_inner( + *sx, *sy, *sz, *origin_x, *origin_y, *origin_z, ); out } @@ -1138,9 +1866,7 @@ impl DOMMatrixInner { #[webidl] origin_y: webidl::UnrestrictedDouble, #[webidl] origin_z: webidl::UnrestrictedDouble, ) { - matrix_scale_with_origin( - self, *sx, *sy, *sz, *origin_x, *origin_y, *origin_z, - ); + self.scale_with_origin_self_inner(*sx, *sy, *sz, *origin_x, *origin_y, *origin_z); } #[cppgc] @@ -1151,7 +1877,7 @@ impl DOMMatrixInner { #[webidl] yaw_deg: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_rotate(&out, *roll_deg, *pitch_deg, *yaw_deg); + out.rotate_self_inner(*roll_deg, *pitch_deg, *yaw_deg); out } @@ -1161,7 +1887,7 @@ impl DOMMatrixInner { #[webidl] pitch_deg: webidl::UnrestrictedDouble, #[webidl] yaw_deg: webidl::UnrestrictedDouble, ) { - matrix_rotate(self, *roll_deg, *pitch_deg, *yaw_deg); + self.rotate_self_inner(*roll_deg, *pitch_deg, *yaw_deg); } #[cppgc] @@ -1171,7 +1897,7 @@ impl DOMMatrixInner { #[webidl] y: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_rotate_from_vector(&out, *x, *y); + out.rotate_from_vector_self_inner(*x, *y); out } @@ -1180,7 +1906,7 @@ impl DOMMatrixInner { #[webidl] x: webidl::UnrestrictedDouble, #[webidl] y: webidl::UnrestrictedDouble, ) { - matrix_rotate_from_vector(self, *x, *y); + self.rotate_from_vector_self_inner(*x, *y); } #[cppgc] @@ -1192,7 +1918,7 @@ impl DOMMatrixInner { #[webidl] angle_deg: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_rotate_axis_angle(&out, *x, *y, *z, *angle_deg); + out.rotate_axis_angle_self_inner(*x, *y, *z, *angle_deg); out } @@ -1203,7 +1929,7 @@ impl DOMMatrixInner { #[webidl] z: webidl::UnrestrictedDouble, #[webidl] angle_deg: webidl::UnrestrictedDouble, ) { - matrix_rotate_axis_angle(self, *x, *y, *z, *angle_deg); + self.rotate_axis_angle_self_inner(*x, *y, *z, *angle_deg); } #[cppgc] @@ -1212,12 +1938,12 @@ impl DOMMatrixInner { #[webidl] x_deg: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_skew_x(&out, *x_deg); + out.skew_x_self_inner(*x_deg); out } pub fn skew_x_self(&self, #[webidl] x_deg: webidl::UnrestrictedDouble) { - matrix_skew_x(self, *x_deg); + self.skew_x_self_inner(*x_deg); } #[cppgc] @@ -1226,12 +1952,12 @@ impl DOMMatrixInner { #[webidl] y_deg: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_skew_y(&out, *y_deg); + out.skew_y_self_inner(*y_deg); out } pub fn skew_y_self(&self, #[webidl] y_deg: webidl::UnrestrictedDouble) { - matrix_skew_y(self, *y_deg); + self.skew_y_self_inner(*y_deg); } #[cppgc] @@ -1240,7 +1966,7 @@ impl DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), }; - matrix_multiply(&out, self, other); + out.multiply_self_inner(self, other); out } @@ -1250,7 +1976,7 @@ impl DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), }; - matrix_multiply(&result, self, other); + result.multiply_self_inner(self, other); self.inner.borrow_mut().copy_from(&result.inner.borrow()); self.is_2d.set(result.is_2d.get()); } @@ -1261,7 +1987,7 @@ impl DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), }; - matrix_multiply(&result, other, self); + result.multiply_self_inner(other, self); self.inner.borrow_mut().copy_from(&result.inner.borrow()); self.is_2d.set(result.is_2d.get()); } @@ -1269,40 +1995,94 @@ impl DOMMatrixInner { #[cppgc] pub fn flip_x(&self) -> DOMMatrixInner { let out = self.clone(); - matrix_flip_x(&out); + out.flip_x_inner(); out } #[cppgc] pub fn flip_y(&self) -> DOMMatrixInner { let out = self.clone(); - matrix_flip_y(&out); + out.flip_y_inner(); out } #[cppgc] pub fn inverse(&self) -> DOMMatrixInner { let out = self.clone(); - matrix_inverse(&out); + out.invert_self_inner(); out } #[fast] pub fn invert_self(&self) { - matrix_inverse(self); + self.invert_self_inner(); } #[cppgc] pub fn transform_point( &self, - #[cppgc] point: &DOMPointInner, - ) -> DOMPointInner { - let out = DOMPointInner { + #[cppgc] point: &DOMPointReadOnly, + ) -> DOMPointReadOnly { + let out = DOMPointReadOnly { inner: RefCell::new(Vector4::zeros()), }; matrix_transform_point(self, point, &out); out } + + #[rename("toJSON")] + pub fn to_json<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + ) -> v8::Local<'a, v8::Object> { + fn set_f64( + scope: &mut v8::HandleScope, + object: &mut v8::Local, + key: &str, + value: f64, + ) { + let key = v8::String::new(scope, key).unwrap(); + let value = v8::Number::new(scope, value); + object.set(scope, key.into(), value.into()).unwrap(); + } + fn set_boolean( + scope: &mut v8::HandleScope, + object: &mut v8::Local, + key: &str, + value: bool, + ) { + let key = v8::String::new(scope, key).unwrap(); + let value = v8::Boolean::new(scope, value); + object.set(scope, key.into(), value.into()).unwrap(); + } + + let mut obj = v8::Object::new(scope); + set_f64(scope, &mut obj, "a", self.get_a()); + set_f64(scope, &mut obj, "b", self.get_b()); + set_f64(scope, &mut obj, "c", self.get_c()); + set_f64(scope, &mut obj, "d", self.get_d()); + set_f64(scope, &mut obj, "e", self.get_e()); + set_f64(scope, &mut obj, "f", self.get_f()); + set_f64(scope, &mut obj, "m11", self.get_m11()); + set_f64(scope, &mut obj, "m12", self.get_m12()); + set_f64(scope, &mut obj, "m13", self.get_m13()); + set_f64(scope, &mut obj, "m14", self.get_m14()); + set_f64(scope, &mut obj, "m21", self.get_m21()); + set_f64(scope, &mut obj, "m22", self.get_m22()); + set_f64(scope, &mut obj, "m23", self.get_m23()); + set_f64(scope, &mut obj, "m24", self.get_m24()); + set_f64(scope, &mut obj, "m31", self.get_m31()); + set_f64(scope, &mut obj, "m32", self.get_m32()); + set_f64(scope, &mut obj, "m33", self.get_m33()); + set_f64(scope, &mut obj, "m34", self.get_m34()); + set_f64(scope, &mut obj, "m41", self.get_m41()); + set_f64(scope, &mut obj, "m42", self.get_m42()); + set_f64(scope, &mut obj, "m43", self.get_m43()); + set_f64(scope, &mut obj, "m44", self.get_m44()); + set_boolean(scope, &mut obj, "is2D", self.is_2d.get()); + set_boolean(scope, &mut obj, "isIdentity", self.get_is_identity()); + obj + } } // TODO(petamoriken) Use f64::maximum instead https://github.com/rust-lang/rust/issues/91079 @@ -1343,209 +2123,10 @@ fn minimum(a: f64, b: f64) -> f64 { } } -#[inline] -fn matrix_translate(matrix: &DOMMatrixInner, tx: f64, ty: f64, tz: f64) { - let mut inner = matrix.inner.borrow_mut(); - let is_2d = matrix.is_2d.get(); - let shift = Vector3::new(tx, ty, tz); - inner.prepend_translation_mut(&shift); - matrix.is_2d.set(is_2d && tz == 0.0); -} - -#[inline] -fn matrix_scale_without_origin( - matrix: &DOMMatrixInner, - sx: f64, - sy: f64, - sz: f64, -) { - let mut inner = matrix.inner.borrow_mut(); - let is_2d = matrix.is_2d.get(); - let scaling = Vector3::new(sx, sy, sz); - inner.prepend_nonuniform_scaling_mut(&scaling); - matrix.is_2d.set(is_2d && sz == 1.0); -} - -#[inline] -fn matrix_scale_with_origin( - matrix: &DOMMatrixInner, - sx: f64, - sy: f64, - sz: f64, - origin_x: f64, - origin_y: f64, - origin_z: f64, -) { - let mut inner = matrix.inner.borrow_mut(); - let is_2d = matrix.is_2d.get(); - let scaling = Vector3::new(sx, sy, sz); - let mut shift = Vector3::new(origin_x, origin_y, origin_z); - inner.prepend_translation_mut(&shift); - inner.prepend_nonuniform_scaling_mut(&scaling); - shift.neg_mut(); - inner.prepend_translation_mut(&shift); - matrix.is_2d.set(is_2d && sz == 1.0 && origin_z == 0.0); -} - -#[inline] -fn matrix_rotate( - matrix: &DOMMatrixInner, - roll_deg: f64, - pitch_deg: f64, - yaw_deg: f64, -) { - let mut inner = matrix.inner.borrow_mut(); - let is_2d = matrix.is_2d.get(); - let rotation = Rotation3::from_euler_angles( - roll_deg.to_radians(), - pitch_deg.to_radians(), - yaw_deg.to_radians(), - ) - .to_homogeneous(); - let mut result = Matrix4x3::zeros(); - inner.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); - inner.set_column(0, &result.column(0)); - inner.set_column(1, &result.column(1)); - inner.set_column(2, &result.column(2)); - matrix - .is_2d - .set(is_2d && roll_deg == 0.0 && pitch_deg == 0.0); -} - -#[inline] -fn matrix_rotate_from_vector(matrix: &DOMMatrixInner, x: f64, y: f64) { - let mut inner = matrix.inner.borrow_mut(); - let rotation = - Rotation3::from_axis_angle(&Vector3::z_axis(), y.atan2(x)).to_homogeneous(); - let mut result = Matrix4x3::zeros(); - inner.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); - inner.set_column(0, &result.column(0)); - inner.set_column(1, &result.column(1)); - inner.set_column(2, &result.column(2)); -} - -#[inline] -fn matrix_rotate_axis_angle( - matrix: &DOMMatrixInner, - x: f64, - y: f64, - z: f64, - angle_deg: f64, -) { - if x == 0.0 && y == 0.0 && z == 0.0 { - return; - } - let mut inner = matrix.inner.borrow_mut(); - let is_2d = matrix.is_2d.get(); - let rotation = Rotation3::from_axis_angle( - &UnitVector3::new_normalize(Vector3::new(x, y, z)), - angle_deg.to_radians(), - ) - .to_homogeneous(); - let mut result = Matrix4x3::zeros(); - inner.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); - inner.set_column(0, &result.column(0)); - inner.set_column(1, &result.column(1)); - inner.set_column(2, &result.column(2)); - matrix.is_2d.set(is_2d && x == 0.0 && y == 0.0); -} - -#[inline] -fn matrix_skew_x(matrix: &DOMMatrixInner, x_deg: f64) { - let mut inner = matrix.inner.borrow_mut(); - let skew = - Matrix4x2::new(1.0, x_deg.to_radians().tan(), 0.0, 1.0, 0.0, 0.0, 0.0, 0.0); - let mut result = Matrix4x2::zeros(); - inner.mul_to(&skew, &mut result); - inner.set_column(0, &result.column(0)); - inner.set_column(1, &result.column(1)); -} - -#[inline] -fn matrix_skew_y(matrix: &DOMMatrixInner, y_deg: f64) { - let mut inner = matrix.inner.borrow_mut(); - let skew = - Matrix4x2::new(1.0, 0.0, y_deg.to_radians().tan(), 1.0, 0.0, 0.0, 0.0, 0.0); - let mut result = Matrix4x2::zeros(); - inner.mul_to(&skew, &mut result); - inner.set_column(0, &result.column(0)); - inner.set_column(1, &result.column(1)); -} - -#[inline] -fn matrix_multiply( - out: &DOMMatrixInner, - lhs: &DOMMatrixInner, - rhs: &DOMMatrixInner, -) { - let lhs_inner = lhs.inner.borrow(); - let lhs_is_2d = lhs.is_2d.get(); - let rhs_inner = rhs.inner.borrow(); - let rhs_is_2d = rhs.is_2d.get(); - let mut out_inner = out.inner.borrow_mut(); - lhs_inner.mul_to(&rhs_inner, &mut out_inner); - out.is_2d.set(lhs_is_2d && rhs_is_2d); -} - -#[inline] -fn matrix_flip_x(matrix: &DOMMatrixInner) { - let mut inner = matrix.inner.borrow_mut(); - inner.column_mut(0).neg_mut(); -} - -#[inline] -fn matrix_flip_y(matrix: &DOMMatrixInner) { - let mut inner = matrix.inner.borrow_mut(); - inner.column_mut(1).neg_mut(); -} - -#[inline] -fn matrix_inverse(matrix: &DOMMatrixInner) { - let mut inner = matrix.inner.borrow_mut(); - let is_2d = matrix.is_2d.get(); - if inner.iter().any(|&x| x.is_infinite()) { - inner.fill(f64::NAN); - matrix.is_2d.set(false); - return; - } - if is_2d { - // SAFETY: in-range access - let mut matrix3 = unsafe { - Matrix3::new( - *inner.get_unchecked(INDEX_A), - *inner.get_unchecked(INDEX_C), - *inner.get_unchecked(INDEX_E), - *inner.get_unchecked(INDEX_B), - *inner.get_unchecked(INDEX_D), - *inner.get_unchecked(INDEX_F), - 0.0, - 0.0, - 1.0, - ) - }; - if !matrix3.try_inverse_mut() { - inner.fill(f64::NAN); - matrix.is_2d.set(false); - return; - } - // SAFETY: in-range access - unsafe { - *inner.get_unchecked_mut(INDEX_A) = *matrix3.get_unchecked(0); - *inner.get_unchecked_mut(INDEX_B) = *matrix3.get_unchecked(1); - *inner.get_unchecked_mut(INDEX_C) = *matrix3.get_unchecked(3); - *inner.get_unchecked_mut(INDEX_D) = *matrix3.get_unchecked(4); - *inner.get_unchecked_mut(INDEX_E) = *matrix3.get_unchecked(6); - *inner.get_unchecked_mut(INDEX_F) = *matrix3.get_unchecked(7); - } - } else if !inner.try_inverse_mut() { - inner.fill(f64::NAN); - } -} - fn matrix_transform_point( matrix: &DOMMatrixInner, - point: &DOMPointInner, - out: &DOMPointInner, + point: &DOMPointReadOnly, + out: &DOMPointReadOnly, ) { let inner = matrix.inner.borrow(); let point = point.inner.borrow(); From f62330fbcbf9eb34de58c276299bce4c4f6852a4 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 28 Apr 2025 14:03:44 +0900 Subject: [PATCH 26/63] wip --- ext/geometry/00_init.js | 24 +- ext/geometry/01_geometry.js | 1139 ++------------- ext/geometry/README.md | 54 +- ext/geometry/lib.rs | 1990 +++++++++++++++++--------- runtime/js/98_global_scope_window.js | 66 +- runtime/js/98_global_scope_worker.js | 8 +- runtime/snapshot.rs | 2 +- runtime/snapshot_info.rs | 2 +- runtime/web_worker.rs | 2 +- runtime/worker.rs | 2 +- 10 files changed, 1496 insertions(+), 1793 deletions(-) diff --git a/ext/geometry/00_init.js b/ext/geometry/00_init.js index ea5e20870f2c87..ac3ea4e173c2df 100644 --- a/ext/geometry/00_init.js +++ b/ext/geometry/00_init.js @@ -2,26 +2,6 @@ import { core } from "ext:core/mod.js"; -const lazyLoad = core.createLazyLoader("ext:deno_geometry/01_geometry.js"); +const loadGeometry = core.createLazyLoader("ext:deno_geometry/01_geometry.js"); -let geometry; - -/** - * @param {(transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean }} transformListParser - * @param {boolean} enableWindowFeatures - */ -export function createGeometryLoader( - transformListParser, - enableWindowFeatures, -) { - return () => { - if (geometry !== undefined) { - return geometry; - } - - geometry = lazyLoad(); - geometry.init(transformListParser, enableWindowFeatures); - - return geometry; - }; -} +export { loadGeometry }; diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 0eb04f6cb3207b..212688032bf9c8 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -2,17 +2,23 @@ import { primordials } from "ext:core/mod.js"; import { - DOMMatrixInner, + DOMMatrix, + DOMMatrixReadOnly, DOMPoint, DOMPointReadOnly, DOMQuad, DOMRect, DOMRectReadOnly, + op_geometry_get_enable_window_features, + op_geometry_matrix_to_buffer, + op_geometry_matrix_to_string, + op_geometry_parse_transform_list, } from "ext:core/ops"; const { ArrayPrototypeJoin, Float32Array, Float64Array, + ObjectDefineProperties, ObjectDefineProperty, ObjectPrototypeIsPrototypeOf, Symbol, @@ -28,56 +34,55 @@ import { DOMException } from "ext:deno_web/01_dom_exception.js"; const DOMPointPrototype = DOMPoint.prototype; const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; -ObjectDefineProperty(DOMPointReadOnlyPrototype, SymbolFor("Deno.privateCustomInspect"), { - __proto__: null, - value: function customInspect(inspect, inspectOptions) { - return inspect( - createFilteredInspectProxy({ - object: this, - evaluate: ObjectPrototypeIsPrototypeOf( - DOMPointReadOnlyPrototype, - this, - ), - keys: ["x", "y", "z", "w"], - }), - inspectOptions, - ); +ObjectDefineProperty( + DOMPointReadOnlyPrototype, + SymbolFor("Deno.privateCustomInspect"), + { + __proto__: null, + value: function customInspect(inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf( + DOMPointReadOnlyPrototype, + this, + ), + keys: ["x", "y", "z", "w"], + }), + inspectOptions, + ); + }, + enumerable: false, + writable: true, + configurable: true, }, - enumerable: false, - writable: true, - configurable: true, -}); +); const DOMRectPrototype = DOMRect.prototype; const DOMRectReadOnlyPrototype = DOMRectReadOnly.prototype; -ObjectDefineProperty(DOMRectReadOnlyPrototype, SymbolFor("Deno.privateCustomInspect"), { - __proto__: null, - value: function customInspect(inspect, inspectOptions) { - return inspect( - createFilteredInspectProxy({ - object: this, - evaluate: ObjectPrototypeIsPrototypeOf( - DOMRectReadOnlyPrototype, - this, - ), - keys: [ - "x", - "y", - "width", - "height", - "top", - "right", - "bottom", - "left", - ], - }), - inspectOptions, - ); +ObjectDefineProperty( + DOMRectReadOnlyPrototype, + SymbolFor("Deno.privateCustomInspect"), + { + __proto__: null, + value: function customInspect(inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf( + DOMRectReadOnlyPrototype, + this, + ), + keys: ["x", "y", "width", "height", "top", "right", "bottom", "left"], + }), + inspectOptions, + ); + }, + enumerable: false, + writable: true, + configurable: true, }, - enumerable: false, - writable: true, - configurable: true, -}); +); const DOMQuadPrototype = DOMQuad.prototype; ObjectDefineProperty(DOMQuadPrototype, SymbolFor("Deno.privateCustomInspect"), { @@ -87,12 +92,7 @@ ObjectDefineProperty(DOMQuadPrototype, SymbolFor("Deno.privateCustomInspect"), { createFilteredInspectProxy({ object: this, evaluate: ObjectPrototypeIsPrototypeOf(DOMQuadPrototype, this), - keys: [ - "p1", - "p2", - "p3", - "p4", - ], + keys: ["p1", "p2", "p3", "p4"], }), inspectOptions, ); @@ -102,960 +102,98 @@ ObjectDefineProperty(DOMQuadPrototype, SymbolFor("Deno.privateCustomInspect"), { configurable: true, }); -const _inner = Symbol("[[inner]]"); -// Property to prevent writing values when an immutable instance is changed to -// a mutable instance by Object.setPrototypeOf -// TODO(petamoriken): Implementing resistance to Object.setPrototypeOf in the WebIDL layer -const _writable = Symbol("[[writable]]"); -const _brand = webidl.brand; - -class DOMMatrixReadOnly { - [_writable] = false; - /** @type {DOMMatrixInner} */ - [_inner]; - - constructor(init = undefined) { - const prefix = `Failed to construct '${this.constructor.name}'`; - this[_brand] = _brand; - if (init === undefined) { - this[_inner] = DOMMatrixInner.identity(); - } else if ( - webidl.type(init) === "Object" && init[SymbolIterator] !== undefined - ) { - init = webidl.converters["sequence"]( - init, - prefix, - "Argument 1", - ); - initMatrixFromSequence(this, init, prefix); - } else { - init = webidl.converters.DOMString( - init, - prefix, - "Argument 1", - ); - const { matrix, is2D } = parseTransformList(init, prefix); - this[_inner] = new DOMMatrixInner(matrix, is2D); - } - } - - static fromMatrix(other = { __proto__: null }) { - const matrix = webidl.createBranded(DOMMatrixReadOnly); - matrix[_writable] = false; - // fast path for DOMMatrix or DOMMatrixReadOnly - if ( - other !== null && - ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) - ) { - matrix[_inner] = other[_inner].clone(); - } else { - matrix[_inner] = DOMMatrixInner.fromMatrix(other); - } - return matrix; - } - - static fromFloat32Array(float32) { - const prefix = "Failed to execute 'DOMMatrixReadOnly.fromFloat32Array'"; - webidl.requiredArguments(arguments.length, 1, prefix); - float32 = webidl.converters.Float32Array(float32, prefix, "Argument 1"); - const matrix = webidl.createBranded(DOMMatrixReadOnly); - matrix[_writable] = false; - initMatrixFromSequence(matrix, float32, prefix); - return matrix; - } - - static fromFloat64Array(float64) { - const prefix = "Failed to execute 'DOMMatrixReadOnly.fromFloat64Array'"; - webidl.requiredArguments(arguments.length, 1, prefix); - float64 = webidl.converters.Float64Array(float64, prefix, "Argument 1"); - const matrix = webidl.createBranded(DOMMatrixReadOnly); - matrix[_writable] = false; - initMatrixFromSequence(matrix, float64, prefix); - return matrix; - } - - get a() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].a; - } - - get b() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].b; - } - - get c() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].c; - } - - get d() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].d; - } - - get e() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].e; - } - - get f() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].f; - } - - get m11() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].m11; - } - - get m12() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].m12; - } - - get m13() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].m13; - } - - get m14() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].m14; - } - - get m21() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].m21; - } - - get m22() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].m22; - } - - get m23() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].m23; - } - - get m24() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].m24; - } - - get m31() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].m31; - } - - get m32() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].m32; - } - - get m33() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].m33; - } - - get m34() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].m34; - } - - get m41() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].m41; - } - - get m42() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].m42; - } - - get m43() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].m43; - } - - get m44() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].m44; - } - - get is2D() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].is2D; - } - - get isIdentity() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].isIdentity; - } - - translate(tx = 0, ty = 0, tz = 0) { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const matrix = webidl.createBranded(DOMMatrix); - matrix[_writable] = true; - matrix[_inner] = this[_inner].translate(tx, ty, tz); - return matrix; - } - - scale( - scaleX = 1, - scaleY = scaleX, - scaleZ = 1, - originX = 0, - originY = 0, - originZ = 0, - ) { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const matrix = webidl.createBranded(DOMMatrix); - matrix[_writable] = true; - if (originX === 0 && originY === 0 && originZ === 0) { - matrix[_inner] = this[_inner].scaleWithoutOrigin( - scaleX, - scaleY, - scaleZ, - ); - } else { - matrix[_inner] = this[_inner].scaleWithOrigin( - scaleX, - scaleY, - scaleZ, - originX, - originY, - originZ, - ); - } - return matrix; - } - - scaleNonUniform(scaleX = 1, scaleY = 1) { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const matrix = webidl.createBranded(DOMMatrix); - matrix[_writable] = true; - matrix[_inner] = this[_inner].scaleWithoutOrigin( - scaleX, - scaleY, - 1, - ); - return matrix; - } - - scale3d(scale = 1, originX = 0, originY = 0, originZ = 0) { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const matrix = webidl.createBranded(DOMMatrix); - matrix[_writable] = true; - if (originX === 0 && originY === 0 && originZ === 0) { - matrix[_inner] = this[_inner].scaleWithoutOrigin( - scale, - scale, - scale, - ); - } else { - matrix[_inner] = this[_inner].scaleWithOrigin( - scale, - scale, - scale, - originX, - originY, - originZ, - ); - } - return matrix; - } - - rotate(rotX = 0, rotY, rotZ) { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - if (rotY === undefined && rotZ === undefined) { - rotZ = rotX; - rotX = 0; - rotY = 0; - } else { - rotY = rotY !== undefined ? rotY : 0; - rotZ = rotZ !== undefined ? rotZ : 0; - } - const matrix = webidl.createBranded(DOMMatrix); - matrix[_writable] = true; - matrix[_inner] = this[_inner].rotate( - rotX, - rotY, - rotZ, - ); - return matrix; - } - - rotateFromVector(x = 0, y = 0) { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const matrix = webidl.createBranded(DOMMatrix); - matrix[_writable] = true; - matrix[_inner] = this[_inner].rotateFromVector(x, y); - return matrix; - } - - rotateAxisAngle(x = 0, y = 0, z = 0, angle = 0) { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const matrix = webidl.createBranded(DOMMatrix); - matrix[_writable] = true; - matrix[_inner] = this[_inner].rotateAxisAngle( - x, - y, - z, - angle, - ); - return matrix; - } - - skewX(sx = 0) { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const matrix = webidl.createBranded(DOMMatrix); - matrix[_writable] = true; - matrix[_inner] = this[_inner].skewX(sx); - return matrix; - } - - skewY(sy = 0) { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const matrix = webidl.createBranded(DOMMatrix); - matrix[_writable] = true; - matrix[_inner] = this[_inner].skewY(sy); - return matrix; - } - - multiply(other = { __proto__: null }) { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - let otherInner; - // fast path for DOMMatrix or DOMMatrixReadOnly - if ( - other !== null && - ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) - ) { - otherInner = other[_inner]; - } else { - otherInner = DOMMatrixInner.fromMatrix(other); - } - const matrix = webidl.createBranded(DOMMatrix); - matrix[_writable] = true; - matrix[_inner] = this[_inner].multiply(otherInner); - return matrix; - } - - flipX() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const matrix = webidl.createBranded(DOMMatrix); - matrix[_writable] = true; - matrix[_inner] = this[_inner].flipX(); - return matrix; - } - - flipY() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const matrix = webidl.createBranded(DOMMatrix); - matrix[_writable] = true; - matrix[_inner] = this[_inner].flipY(); - return matrix; - } - - inverse() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const matrix = webidl.createBranded(DOMMatrix); - matrix[_writable] = true; - matrix[_inner] = this[_inner].inverse(); - return matrix; - } - - transformPoint(point = { __proto__: null }) { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - let pointInner; - // fast path for DOMPoint or DOMPointReadOnly - if ( - point !== null && - ObjectPrototypeIsPrototypeOf(DOMPointReadOnlyPrototype, point) - ) { - pointInner = point[_inner]; - } else { - pointInner = DOMPointInner.fromPoint(point); - } - const result = webidl.createBranded(DOMPoint); - result[_writable] = true; - result[_inner] = this[_inner].transformPoint(pointInner); - return result; - } - - toFloat32Array() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return new Float32Array( - new Float64Array( - this[_inner].toBuffer(), - ), - ); - } - - toFloat64Array() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return new Float64Array(this[_inner].toBuffer()); - } - - toJSON() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_inner].toJSON(); - } - - [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { - return inspect( - createFilteredInspectProxy({ - object: this, - evaluate: ObjectPrototypeIsPrototypeOf( - DOMMatrixReadOnlyPrototype, - this, - ), - keys: [ - "a", - "b", - "c", - "d", - "e", - "f", - "m11", - "m12", - "m13", - "m14", - "m21", - "m22", - "m23", - "m24", - "m31", - "m32", - "m33", - "m34", - "m41", - "m42", - "m43", - "m44", - "is2D", - "isIdentity", - ], - }), - inspectOptions, - ); - } -} - -webidl.configureInterface(DOMMatrixReadOnly); const DOMMatrixReadOnlyPrototype = DOMMatrixReadOnly.prototype; - -class DOMMatrix extends DOMMatrixReadOnly { - [_writable] = true; - - static fromMatrix(other = { __proto__: null }) { - const matrix = webidl.createBranded(DOMMatrix); - matrix[_writable] = true; - // fast path for DOMMatrix or DOMMatrixReadOnly - if ( - other !== null && - ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) - ) { - matrix[_inner] = other[_inner].clone(); - } else { - matrix[_inner] = DOMMatrixInner.fromMatrix(other); - } - return matrix; - } - - static fromFloat32Array(float32) { - const prefix = "Failed to execute 'DOMMatrix.fromFloat32Array'"; - webidl.requiredArguments(arguments.length, 1, prefix); - float32 = webidl.converters.Float32Array(float32, prefix, "Argument 1"); - const matrix = webidl.createBranded(DOMMatrix); - matrix[_writable] = true; - initMatrixFromSequence(matrix, float32, prefix); - return matrix; - } - - static fromFloat64Array(float64) { - const prefix = "Failed to execute 'DOMMatrix.fromFloat64Array'"; - webidl.requiredArguments(arguments.length, 1, prefix); - float64 = webidl.converters.Float64Array(float64, prefix, "Argument 1"); - const matrix = webidl.createBranded(DOMMatrix); - matrix[_writable] = true; - initMatrixFromSequence(matrix, float64, prefix); - return matrix; - } - - get a() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].a; - } - set a(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].a = value; - } - - get b() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].b; - } - set b(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].b = value; - } - - get c() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].c; - } - set c(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].c = value; - } - - get d() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].d; - } - set d(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].d = value; - } - - get e() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].e; - } - set e(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].e = value; - } - - get f() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].f; - } - set f(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].f = value; - } - - get m11() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].m11; - } - set m11(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].m11 = value; - } - - get m12() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].m12; - } - set m12(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].m12 = value; - } - - get m13() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].m13; - } - set m13(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].m13 = value; - } - - get m14() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].m14; - } - set m14(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].m14 = value; - } - - get m21() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].m21; - } - set m21(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].m21 = value; - } - - get m22() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].m22; - } - set m22(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].m22 = value; - } - - get m23() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].m23; - } - set m23(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].m23 = value; - } - - get m24() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].m24; - } - set m24(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].m24 = value; - } - - get m31() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].m31; - } - set m31(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].m31 = value; - } - - get m32() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].m32; - } - set m32(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].m32 = value; - } - - get m33() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].m33; - } - set m33(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].m33 = value; - } - - get m34() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].m34; - } - set m34(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].m34 = value; - } - - get m41() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].m41; - } - set m41(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].m41 = value; - } - - get m42() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].m42; - } - set m42(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].m42 = value; - } - - get m43() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].m43; - } - set m43(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].m43 = value; - } - - get m44() { - webidl.assertBranded(this, DOMMatrixPrototype); - return this[_inner].m44; - } - set m44(value) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].m44 = value; - } - - multiplySelf(other = { __proto__: null }) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - let otherInner; - // fast path for DOMMatrix or DOMMatrixReadOnly - if ( - other !== null && - ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) - ) { - otherInner = other[_inner]; - } else { - otherInner = DOMMatrixInner.fromMatrix(other); - } - this[_inner].multiplySelf(otherInner); - return this; - } - - preMultiplySelf(other = { __proto__: null }) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - let otherInner; - // fast path for DOMMatrix or DOMMatrixReadOnly - if ( - other !== null && - ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) - ) { - otherInner = other[_inner]; - } else { - otherInner = DOMMatrixInner.fromMatrix(other); - } - this[_inner].preMultiplySelf(otherInner); - return this; - } - - translateSelf(tx = 0, ty = 0, tz = 0) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].translateSelf(tx, ty, tz); - return this; - } - - scaleSelf( - scaleX = 1, - scaleY = scaleX, - scaleZ = 1, - originX = 0, - originY = 0, - originZ = 0, - ) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - if (originX === 0 && originY === 0 && originZ === 0) { - this[_inner].scaleWithoutOriginSelf(scaleX, scaleY, scaleZ); - } else { - this[_inner].scaleWithOriginSelf( - scaleX, - scaleY, - scaleZ, - originX, - originY, - originZ, +ObjectDefineProperties(DOMMatrixReadOnlyPrototype, { + toFloat32Array: { + __proto__: null, + value: function toFloat32Array() { + return new Float32Array( + new Float64Array(op_geometry_matrix_to_buffer(this)), ); - } - return this; - } - - scale3dSelf(scale = 1, originX = 0, originY = 0, originZ = 0) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - if (originX === 0 && originY === 0 && originZ === 0) { - this[_inner].scaleWithoutOriginSelf(scale, scale, scale); - } else { - this[_inner].scaleWithOriginSelf( - scale, - scale, - scale, - originX, - originY, - originZ, + }, + enumerable: false, + writable: true, + configurable: true, + }, + toFloat64Array: { + __proto__: null, + value: function toFloat64Array() { + return new Float64Array(op_geometry_matrix_to_buffer(this)); + }, + enumerable: false, + writable: true, + configurable: true, + }, + [SymbolFor("Deno.privateCustomInspect")]: { + __proto__: null, + value: function customInspect(inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf( + DOMMatrixReadOnlyPrototype, + this, + ), + keys: [ + "a", + "b", + "c", + "d", + "e", + "f", + "m11", + "m12", + "m13", + "m14", + "m21", + "m22", + "m23", + "m24", + "m31", + "m32", + "m33", + "m34", + "m41", + "m42", + "m43", + "m44", + "is2D", + "isIdentity", + ], + }), + inspectOptions, ); - } - return this; - } - - rotateSelf(rotX = 0, rotY, rotZ) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - if (rotY === undefined && rotZ === undefined) { - rotZ = rotX; - rotX = 0; - rotY = 0; - } else { - rotY = rotY !== undefined ? rotY : 0; - rotZ = rotZ !== undefined ? rotZ : 0; - } - this[_inner].rotateSelf( - rotX, - rotY, - rotZ, - ); - return this; - } - - rotateFromVectorSelf(x = 0, y = 0) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].rotateFromVectorSelf(x, y); - return this; - } - - rotateAxisAngleSelf(x = 0, y = 0, z = 0, angle = 0) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].rotateAxisAngleSelf( - x, - y, - z, - angle, - ); - return this; - } - - skewXSelf(sx = 0) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].skewXSelf(sx); - return this; - } - - skewYSelf(sy = 0) { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].skewYSelf(sy); - return this; - } - - invertSelf() { - webidl.assertBranded(this, DOMMatrixPrototype); - assertWritable(this); - this[_inner].invertSelf(); - return this; - } -} + }, + enumerable: false, + writable: true, + configurable: true, + }, +}); -webidl.configureInterface(DOMMatrix); const DOMMatrixPrototype = DOMMatrix.prototype; -/** - * TODO(petamoriken): Support this by updating WebIDL's brand features - * @param {DOMRect | DOMPoint | DOMMatrix} self - */ -function assertWritable(self) { - if (self[_writable] !== true) { - throw new TypeError("Illegal invocation"); - } -} - -/** - * @param {object} target - * @param {number[] | Float32Array | Float64Array} seq - * @param {string} prefix - */ -function initMatrixFromSequence(target, seq, prefix) { - if (seq.length === 6) { - const { 0: a, 1: b, 2: c, 3: d, 4: e, 5: f } = seq; - // deno-fmt-ignore - target[_inner] = new DOMMatrixInner(new Float64Array([ - a, b, 0, 0, - c, d, 0, 0, - 0, 0, 1, 0, - e, f, 0, 1, - ]), /* is2D */ true); - } else if (seq.length === 16) { - target[_inner] = new DOMMatrixInner( - new Float64Array(seq), - /* is2D */ false, - ); - } else { - throw new TypeError( - `${prefix}: The sequence must contain 6 elements for a 2D matrix or 16 elements for a 3D matrix`, - ); - } -} - -/** - * CSS parser - * @type {((transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean })} - */ -let parseTransformList; - -/** - * @param {(transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean }} transformListParser - * @param {boolean} enableWindowFeatures - */ -function init(transformListParser, enableWindowFeatures) { - parseTransformList = transformListParser; - - if (enableWindowFeatures) { - // https://drafts.fxtf.org/geometry/#dommatrixreadonly-stringification-behavior - ObjectDefineProperty(DOMMatrixReadOnlyPrototype, "toString", { - __proto__: null, - value: function toString() { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const inner = this[_inner]; - if (!inner.isFinite) { - throw new DOMException( - "Failed to execute 'toString' on 'DOMMatrixReadOnly': Cannot be serialized with NaN or Infinity values", - "InvalidStateError", - ); - } - if (inner.is2D) { - return `matrix(${ - ArrayPrototypeJoin([ - inner.a, - inner.b, - inner.c, - inner.d, - inner.e, - inner.f, - ], ", ") - })`; - } else { - return `matrix3d(${ - TypedArrayPrototypeJoin(new Float64Array(inner.toBuffer()), ", ") - })`; - } - }, - writable: true, - enumerable: true, - configurable: true, - }); - - // https://drafts.fxtf.org/geometry/#dom-dommatrix-setmatrixvalue - ObjectDefineProperty(DOMMatrixPrototype, "setMatrixValue", { - __proto__: null, - value: function setMatrixValue(transformList) { - webidl.assertBranded(this, DOMMatrixPrototype); - const prefix = "Failed to execute 'setMatrixValue' on 'DOMMatrix'"; - webidl.requiredArguments(arguments.length, 1, prefix); - transformList = webidl.converters.DOMString( - transformList, - prefix, - "Argument 1", - ); - const { matrix, is2D } = parseTransformList(transformList, prefix); - this[_inner] = new DOMMatrixInner(matrix, is2D); - }, - writable: true, - enumerable: true, - configurable: true, - }); - } +if (op_geometry_get_enable_window_features()) { + // https://drafts.fxtf.org/geometry/#dommatrixreadonly-stringification-behavior + ObjectDefineProperty(DOMMatrixReadOnlyPrototype, "toString", { + __proto__: null, + value: function toString() { + return op_geometry_matrix_to_string(this); + }, + writable: true, + enumerable: true, + configurable: true, + }); + + // https://drafts.fxtf.org/geometry/#dom-dommatrix-setmatrixvalue + ObjectDefineProperty(DOMMatrixPrototype, "setMatrixValue", { + __proto__: null, + value: function setMatrixValue(transformList) { + return op_geometry_parse_transform_list(transformList); + }, + writable: true, + enumerable: true, + configurable: true, + }); } export { @@ -1073,5 +211,4 @@ export { DOMRectPrototype, DOMRectReadOnly, DOMRectReadOnlyPrototype, - init, }; diff --git a/ext/geometry/README.md b/ext/geometry/README.md index 8c2f421b10d5e4..e03a03a1208bfb 100644 --- a/ext/geometry/README.md +++ b/ext/geometry/README.md @@ -10,38 +10,7 @@ From javascript, include the extension's source: ```javascript import { core } from "ext:core/mod.js"; -import { createGeometryLoader } from "ext:deno_geometry/00_init.js"; -``` - -For environments that do not have a CSS `` parser, such as Web -Worker, configure as follows: - -```javascript -const loadGeometry = createGeometryLoader((_transformList, prefix) => { - throw new TypeError( - `${prefix}: Cannot parse CSS on Workers`, - ); -}, /* enableWindowFeatures */ false); -``` - -On the other hand, in environments with a CSS `` parser, you can -configure as follows: - -```javascript -const loadGeometry = createGeometryLoader((transformList, prefix) => { - try { - // parse by yourself - const { sequence, is2D } = parse(transformList); - return { - matrix: new Float64Array(sequence), - is2D, - }; - } catch { - throw new TypeError( - `${prefix}: Invalid string: ${transformList}`, - ); - } -}, /* enableWindowFeatures */ true); +import { loadGeometry } from "ext:deno_geometry/00_init.js"; ``` Then define to globalThis: @@ -79,8 +48,10 @@ Object.defineProperties(globalThis, { }); ``` -Then from rust, provide: `deno_geometry::deno_geometry::init_ops_and_esm()` in -the `extensions` field of your `RuntimeOptions` +Then from rust, provide: `deno_geometry::deno_geometry::init_ops_and_esm(bool)` +in the `extensions` field of your `RuntimeOptions` + +Where `bool` indicates whether window features are enabled at initialization. ## Dependencies @@ -92,7 +63,14 @@ the `extensions` field of your `RuntimeOptions` Following ops are provided, which can be accessed through `Deno.ops`: -- DOMMatrixInner -- DOMPointInner -- DOMQuadInner -- DOMRectInner +- DOMPointReadOnly +- DOMPoint +- DOMRectReadOnly +- DOMRect +- DOMQuad +- DOMMatrixReadOnly +- DOMMatrix +- op_geometry_matrix_to_buffer +- op_geometry_matrix_to_string +- op_geometry_parse_transform_list +- op_geometry_get_enable_window_features diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index d5a111b50fe908..f6eccb30cbc885 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -11,10 +11,11 @@ use deno_core::cppgc::SameObject; use deno_core::op2; use deno_core::v8; use deno_core::webidl; -use deno_core::webidl::WebIdlConverter; use deno_core::webidl::ContextFn; +use deno_core::webidl::WebIdlConverter; use deno_core::webidl::WebIdlError; use deno_core::GarbageCollected; +use deno_core::OpState; use deno_core::WebIDL; use nalgebra::Matrix3; use nalgebra::Matrix4; @@ -28,26 +29,63 @@ use nalgebra::Vector4; deno_core::extension!( deno_geometry, deps = [deno_webidl, deno_web, deno_console], + ops = [ + op_geometry_matrix_to_buffer, + op_geometry_matrix_to_string, + op_geometry_parse_transform_list, + op_geometry_get_enable_window_features, + ], objects = [ DOMPointReadOnly, DOMPoint, DOMRectReadOnly, DOMRect, DOMQuad, - DOMMatrixInner, + DOMMatrixReadOnly, + DOMMatrix, ], esm = ["00_init.js"], lazy_loaded_esm = ["01_geometry.js"], + options = { + enable_window_features: bool, + }, + state = |state, options| { + state.put(State::new(options.enable_window_features)); + }, ); +struct State { + enable_window_features: bool, +} + +impl State { + fn new(enable_window_features: bool) -> Self { + Self { + enable_window_features, + } + } +} + #[derive(Debug, thiserror::Error, deno_error::JsError)] pub enum GeometryError { #[class(inherit)] #[error(transparent)] - WebIdlError(#[from] WebIdlError), + WebIDL(#[from] WebIdlError), #[class(type)] #[error("Inconsistent 2d matrix value")] Inconsistent2DMatrix, + #[class(type)] + #[error("Cannot parse CSS on Workers")] + DisallowWindowFeatures, + #[class(type)] + #[error("The sequence must contain 6 elements for a 2D matrix or 16 elements for a 3D matrix")] + InvalidSequenceSize, + #[class(type)] + #[error("Mismatched types")] + TypeMismatch, + #[class("DOMExceptionInvalidStateError")] + #[error("Cannot be serialized with NaN or Infinity values")] + InvalidState, } #[derive(WebIDL, Debug)] @@ -71,16 +109,10 @@ pub struct DOMPointReadOnly { impl GarbageCollected for DOMPointReadOnly {} impl DOMPointReadOnly { - fn from_point_inner<'a>( - scope: &mut v8::HandleScope<'a>, - value: v8::Local<'a, v8::Value>, - prefix: Cow<'static, str>, - context: ContextFn<'_>, - ) -> Result { - let init = DOMPointInit::convert(scope, value, prefix, context, &Default::default())?; - Ok(DOMPointReadOnly { + fn from_point_inner(init: DOMPointInit) -> DOMPointReadOnly { + DOMPointReadOnly { inner: RefCell::new(Vector4::new(*init.x, *init.y, *init.z, *init.w)), - }) + } } } @@ -88,7 +120,7 @@ impl DOMPointReadOnly { impl DOMPointReadOnly { #[constructor] #[cppgc] - pub fn new( + pub fn constructor( #[webidl] x: Option, #[webidl] y: Option, #[webidl] z: Option, @@ -99,7 +131,7 @@ impl DOMPointReadOnly { *x.unwrap_or(webidl::UnrestrictedDouble(0.0)), *y.unwrap_or(webidl::UnrestrictedDouble(0.0)), *z.unwrap_or(webidl::UnrestrictedDouble(0.0)), - *w.unwrap_or(webidl::UnrestrictedDouble(1.0)) + *w.unwrap_or(webidl::UnrestrictedDouble(1.0)), )), } } @@ -107,18 +139,8 @@ impl DOMPointReadOnly { #[reentrant] #[static_method] #[cppgc] - pub fn from_point<'a>( - scope: &mut v8::HandleScope<'a>, - value: v8::Local<'a, v8::Value>, - ) -> Result { - DOMPointReadOnly::from_point_inner( - scope, - value, - "Failed to execute 'DOMPointReadOnly.fromPoint'".into(), - ContextFn::new_borrowed( - &|| Cow::Borrowed("Argument 1") - ) - ) + pub fn from_point<'a>(#[webidl] init: DOMPointInit) -> DOMPointReadOnly { + DOMPointReadOnly::from_point_inner(init) } #[fast] @@ -169,20 +191,13 @@ impl DOMPointReadOnly { obj } + // TODO(petamoriken): returns (DOMPointReadOnly, DOMPoint) #[cppgc] pub fn matrix_transform<'a>( &self, - scope: &mut v8::HandleScope<'a>, - value: v8::Local<'a, v8::Value>, - ) -> Result { - let matrix = DOMMatrixInner::from_matrix_inner( - scope, - value, - "Failed to execute 'DOMPointReadOnly.matrixTransform'".into(), - ContextFn::new_borrowed( - &|| Cow::Borrowed("Argument 1") - ) - )?; + #[webidl] value: DOMMatrixInit, + ) -> Result { + let matrix = DOMMatrixReadOnly::from_matrix_inner(value)?; let out = DOMPointReadOnly { inner: RefCell::new(Vector4::zeros()), }; @@ -199,7 +214,7 @@ impl GarbageCollected for DOMPoint {} impl DOMPoint { #[constructor] #[cppgc] - pub fn new( + pub fn constructor( #[webidl] x: Option, #[webidl] y: Option, #[webidl] z: Option, @@ -210,28 +225,19 @@ impl DOMPoint { *x.unwrap_or(webidl::UnrestrictedDouble(0.0)), *y.unwrap_or(webidl::UnrestrictedDouble(0.0)), *z.unwrap_or(webidl::UnrestrictedDouble(0.0)), - *w.unwrap_or(webidl::UnrestrictedDouble(1.0)) + *w.unwrap_or(webidl::UnrestrictedDouble(1.0)), )), }; (ro, DOMPoint {}) } - // TODO(petamoriken): returns Result<(DOMPointReadOnly, DOMPoint), GeometryError> + // TODO(petamoriken): returns (DOMPointReadOnly, DOMPoint) #[reentrant] #[static_method] #[cppgc] - pub fn from_point<'a>( - scope: &mut v8::HandleScope<'a>, - value: v8::Local<'a, v8::Value>, - ) -> Result { - DOMPointReadOnly::from_point_inner( - scope, - value, - "Failed to execute 'DOMPoint.fromPoint'".into(), - ContextFn::new_borrowed( - &|| Cow::Borrowed("Argument 1") - ) - ) + pub fn from_point<'a>(#[webidl] init: DOMPointInit) -> DOMPointReadOnly { + let ro = DOMPointReadOnly::from_point_inner(init); + ro } #[fast] @@ -241,7 +247,11 @@ impl DOMPoint { } #[setter] - pub fn x(&self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMPointReadOnly) { + pub fn x( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMPointReadOnly, + ) { ro.inner.borrow_mut().x = *value } @@ -252,7 +262,11 @@ impl DOMPoint { } #[setter] - pub fn y(&self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMPointReadOnly) { + pub fn y( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMPointReadOnly, + ) { ro.inner.borrow_mut().y = *value } @@ -263,7 +277,11 @@ impl DOMPoint { } #[setter] - pub fn z(&self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMPointReadOnly) { + pub fn z( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMPointReadOnly, + ) { ro.inner.borrow_mut().z = *value } @@ -274,7 +292,11 @@ impl DOMPoint { } #[setter] - pub fn w(&self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMPointReadOnly) { + pub fn w( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMPointReadOnly, + ) { ro.inner.borrow_mut().w = *value } } @@ -303,19 +325,13 @@ pub struct DOMRectReadOnly { impl GarbageCollected for DOMRectReadOnly {} impl DOMRectReadOnly { - fn from_rect_inner<'a>( - scope: &mut v8::HandleScope<'a>, - value: v8::Local<'a, v8::Value>, - prefix: Cow<'static, str>, - context: ContextFn<'_>, - ) -> Result { - let init = DOMRectInit::convert(scope, value, prefix, context, &Default::default())?; - Ok(DOMRectReadOnly { + fn from_rect_inner(init: DOMRectInit) -> DOMRectReadOnly { + DOMRectReadOnly { x: Cell::new(*init.x), y: Cell::new(*init.y), width: Cell::new(*init.width), height: Cell::new(*init.height), - }) + } } fn get_top(&self) -> f64 { @@ -347,7 +363,7 @@ impl DOMRectReadOnly { impl DOMRectReadOnly { #[constructor] #[cppgc] - pub fn new( + pub fn constructor( #[webidl] x: Option, #[webidl] y: Option, #[webidl] width: Option, @@ -364,18 +380,8 @@ impl DOMRectReadOnly { #[reentrant] #[static_method] #[cppgc] - pub fn from_rect<'a>( - scope: &mut v8::HandleScope<'a>, - value: v8::Local<'a, v8::Value>, - ) -> Result { - DOMRectReadOnly::from_rect_inner( - scope, - value, - "Failed to execute 'DOMRectReadOnly.fromPoint'".into(), - ContextFn::new_borrowed( - &|| Cow::Borrowed("Argument 1") - ) - ) + pub fn from_rect<'a>(#[webidl] init: DOMRectInit) -> DOMRectReadOnly { + DOMRectReadOnly::from_rect_inner(init) } #[fast] @@ -483,7 +489,7 @@ impl GarbageCollected for DOMRect {} impl DOMRect { #[constructor] #[cppgc] - pub fn new( + pub fn constructor( #[webidl] x: Option, #[webidl] y: Option, #[webidl] width: Option, @@ -498,22 +504,13 @@ impl DOMRect { (ro, DOMRect {}) } - // TODO(petamoriken): returns Result<(DOMRectReadOnly, DOMPoint), GeometryError> + // TODO(petamoriken): returns (DOMRectReadOnly, DOMRect) #[reentrant] #[static_method] #[cppgc] - pub fn from_rect<'a>( - scope: &mut v8::HandleScope<'a>, - value: v8::Local<'a, v8::Value>, - ) -> Result { - DOMRectReadOnly::from_rect_inner( - scope, - value, - "Failed to execute 'DOMRect.fromRect'".into(), - ContextFn::new_borrowed( - &|| Cow::Borrowed("Argument 1") - ) - ) + pub fn from_rect<'a>(#[webidl] init: DOMRectInit) -> DOMRectReadOnly { + let ro = DOMRectReadOnly::from_rect_inner(init); + ro } #[fast] @@ -523,7 +520,11 @@ impl DOMRect { } #[setter] - pub fn x(&self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMRectReadOnly) { + pub fn x( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMRectReadOnly, + ) { ro.x.set(*value) } @@ -534,7 +535,11 @@ impl DOMRect { } #[setter] - pub fn y(&self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMRectReadOnly) { + pub fn y( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMRectReadOnly, + ) { ro.y.set(*value) } @@ -545,7 +550,11 @@ impl DOMRect { } #[setter] - pub fn width(&self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMRectReadOnly) { + pub fn width( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMRectReadOnly, + ) { ro.width.set(*value) } @@ -556,7 +565,11 @@ impl DOMRect { } #[setter] - pub fn height(&self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMRectReadOnly) { + pub fn height( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMRectReadOnly, + ) { ro.height.set(*value) } } @@ -570,7 +583,7 @@ pub struct DOMQuadInit { p4: DOMPointInit, } -// TODO(petamoriken): store SameObject +// TODO(petamoriken): store SameObject<(DOMPointReadOnly, DOMPoint)> pub struct DOMQuad { p1: SameObject, p2: SameObject, @@ -598,11 +611,16 @@ impl DOMQuad { point: DOMPointInit, ) -> SameObject { let obj = SameObject::new(); - obj.set(scope, DOMPointReadOnly { - inner: RefCell::new(Vector4::new( - *point.x, *point.y, *point.z, *point.w, - )), - }).unwrap(); + obj + .set( + scope, + DOMPointReadOnly { + inner: RefCell::new(Vector4::new( + *point.x, *point.y, *point.z, *point.w, + )), + }, + ) + .unwrap(); obj } @@ -630,9 +648,14 @@ impl DOMQuad { w: f64, ) -> SameObject { let obj = SameObject::new(); - obj.set(scope, DOMPointReadOnly { - inner: RefCell::new(Vector4::new(x, y, z, w)), - }).unwrap(); + obj + .set( + scope, + DOMPointReadOnly { + inner: RefCell::new(Vector4::new(x, y, z, w)), + }, + ) + .unwrap(); obj } @@ -663,11 +686,16 @@ impl DOMQuad { point: DOMPointInit, ) -> SameObject { let obj = SameObject::new(); - obj.set(scope, DOMPointReadOnly { - inner: RefCell::new(Vector4::new( - *point.x, *point.y, *point.z, *point.w, - )), - }).unwrap(); + obj + .set( + scope, + DOMPointReadOnly { + inner: RefCell::new(Vector4::new( + *point.x, *point.y, *point.z, *point.w, + )), + }, + ) + .unwrap(); obj } @@ -817,12 +845,12 @@ pub struct DOMMatrixInit { } #[derive(Debug, Clone)] -pub struct DOMMatrixInner { +pub struct DOMMatrixReadOnly { inner: RefCell>, is_2d: Cell, } -impl GarbageCollected for DOMMatrixInner {} +impl GarbageCollected for DOMMatrixReadOnly {} /* * NOTE: column-major order @@ -866,14 +894,53 @@ const INDEX_M42: usize = 13; const INDEX_M43: usize = 14; const INDEX_M44: usize = 15; -impl DOMMatrixInner { - fn from_matrix_inner<'a>( +impl DOMMatrixReadOnly { + fn new<'a>( + state: &mut OpState, scope: &mut v8::HandleScope<'a>, value: v8::Local<'a, v8::Value>, prefix: Cow<'static, str>, context: ContextFn<'_>, - ) -> Result { - let init = DOMMatrixInit::convert(scope, value, prefix, context, &Default::default())?; + ) -> Result { + if value.is_undefined() { + return Ok(DOMMatrixReadOnly::identity()); + } + if value.is_string() { + let state = state.borrow_mut::(); + if !state.enable_window_features { + return Err(GeometryError::DisallowWindowFeatures); + } + + // TODO(petamoriken): parse CSS + unimplemented!() + } + + let seq = + Vec::::convert(scope, value, prefix, context, &Default::default())?; + if let [a, b, c, d, e, f] = seq.as_slice() { + return Ok(DOMMatrixReadOnly { + #[rustfmt::skip] + inner: RefCell::new(Matrix4::new( + *a, *c, 0.0, *e, + *b, *d, 0.0, *f, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, + )), + is_2d: Cell::new(true), + }); + } else if seq.len() == 16 { + return Ok(DOMMatrixReadOnly { + inner: RefCell::new(Matrix4::from_column_slice(seq.as_slice())), + is_2d: Cell::new(false), + }); + } else { + Err(GeometryError::InvalidSequenceSize) + } + } + + fn from_matrix_inner<'a>( + init: DOMMatrixInit, + ) -> Result { macro_rules! fixup { ($value3d:expr, $value2d:expr, $default:expr) => {{ if let Some(value3d) = $value3d { @@ -920,7 +987,7 @@ impl DOMMatrixInner { }; if is_2d { - Ok(DOMMatrixInner { + Ok(DOMMatrixReadOnly { #[rustfmt::skip] inner: RefCell::new(Matrix4::new( *m11, *m21, 0.0, *m41, @@ -944,7 +1011,7 @@ impl DOMMatrixInner { m44, .. } = init; - Ok(DOMMatrixInner { + Ok(DOMMatrixReadOnly { #[rustfmt::skip] inner: RefCell::new(Matrix4::new( *m11, *m21, *m31, *m41, @@ -957,6 +1024,13 @@ impl DOMMatrixInner { } } + fn identity() -> DOMMatrixReadOnly { + DOMMatrixReadOnly { + inner: RefCell::new(Matrix4::identity()), + is_2d: Cell::new(true), + } + } + #[inline] fn translate_self_inner(&self, tx: f64, ty: f64, tz: f64) { let mut inner = self.inner.borrow_mut(); @@ -967,17 +1041,13 @@ impl DOMMatrixInner { } #[inline] - fn scale_without_origin_self_inner( - &self, - sx: f64, - sy: f64, - sz: f64, - ) { + fn scale_without_origin_self_inner(&self, sx: f64, sy: f64, sz: f64) { let mut inner = self.inner.borrow_mut(); let is_2d = self.is_2d.get(); let scaling = Vector3::new(sx, sy, sz); inner.prepend_nonuniform_scaling_mut(&scaling); self.is_2d.set(is_2d && sz == 1.0); + println!("{:?}", self); } #[inline] @@ -1002,12 +1072,7 @@ impl DOMMatrixInner { } #[inline] - fn rotate_self_inner( - &self, - roll_deg: f64, - pitch_deg: f64, - yaw_deg: f64, - ) { + fn rotate_self_inner(&self, roll_deg: f64, pitch_deg: f64, yaw_deg: f64) { let mut inner = self.inner.borrow_mut(); let is_2d = self.is_2d.get(); let rotation = Rotation3::from_euler_angles( @@ -1021,16 +1086,17 @@ impl DOMMatrixInner { inner.set_column(0, &result.column(0)); inner.set_column(1, &result.column(1)); inner.set_column(2, &result.column(2)); - self - .is_2d - .set(is_2d && roll_deg == 0.0 && pitch_deg == 0.0); + self.is_2d.set(is_2d && roll_deg == 0.0 && pitch_deg == 0.0); } #[inline] fn rotate_from_vector_self_inner(&self, x: f64, y: f64) { + if x == 0.0 && y == 0.0 { + return; + } let mut inner = self.inner.borrow_mut(); - let rotation = - Rotation3::from_axis_angle(&Vector3::z_axis(), y.atan2(x)).to_homogeneous(); + let rotation = Rotation3::from_axis_angle(&Vector3::z_axis(), y.atan2(x)) + .to_homogeneous(); let mut result = Matrix4x3::zeros(); inner.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); inner.set_column(0, &result.column(0)); @@ -1067,8 +1133,16 @@ impl DOMMatrixInner { #[inline] fn skew_x_self_inner(&self, x_deg: f64) { let mut inner = self.inner.borrow_mut(); - let skew = - Matrix4x2::new(1.0, x_deg.to_radians().tan(), 0.0, 1.0, 0.0, 0.0, 0.0, 0.0); + let skew = Matrix4x2::new( + 1.0, + x_deg.to_radians().tan(), + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + ); let mut result = Matrix4x2::zeros(); inner.mul_to(&skew, &mut result); inner.set_column(0, &result.column(0)); @@ -1078,8 +1152,16 @@ impl DOMMatrixInner { #[inline] fn skew_y_self_inner(&self, y_deg: f64) { let mut inner = self.inner.borrow_mut(); - let skew = - Matrix4x2::new(1.0, 0.0, y_deg.to_radians().tan(), 1.0, 0.0, 0.0, 0.0, 0.0); + let skew = Matrix4x2::new( + 1.0, + 0.0, + y_deg.to_radians().tan(), + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + ); let mut result = Matrix4x2::zeros(); inner.mul_to(&skew, &mut result); inner.set_column(0, &result.column(0)); @@ -1089,8 +1171,8 @@ impl DOMMatrixInner { #[inline] fn multiply_self_inner( &self, - lhs: &DOMMatrixInner, - rhs: &DOMMatrixInner, + lhs: &DOMMatrixReadOnly, + rhs: &DOMMatrixReadOnly, ) { let lhs_inner = lhs.inner.borrow(); let lhs_is_2d = lhs.is_2d.get(); @@ -1157,138 +1239,139 @@ impl DOMMatrixInner { } #[inline] - fn get_a(&self) -> f64 { + fn a_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_A) } } #[inline] - fn get_b(&self) -> f64 { + fn b_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_B) } } #[inline] - fn get_c(&self) -> f64 { + fn c_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_C) } } #[inline] - fn get_d(&self) -> f64 { + fn d_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_D) } } #[inline] - fn get_e(&self) -> f64 { + fn e_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_E) } } #[inline] - fn get_f(&self) -> f64 { + fn f_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_F) } } #[inline] - fn get_m11(&self) -> f64 { + fn m11_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_M11) } } #[inline] - fn get_m12(&self) -> f64 { + fn m12_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_M12) } } #[inline] - fn get_m13(&self) -> f64 { + fn m13_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_M13) } } #[inline] - fn get_m14(&self) -> f64 { + fn m14_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_M14) } } #[inline] - fn get_m21(&self) -> f64 { + fn m21_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_M21) } } #[inline] - fn get_m22(&self) -> f64 { + fn m22_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_M22) } } #[inline] - fn get_m23(&self) -> f64 { + fn m23_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_M23) } } #[inline] - fn get_m24(&self) -> f64 { + fn m24_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_M24) } } #[inline] - fn get_m31(&self) -> f64 { + fn m31_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_M31) } } #[inline] - fn get_m32(&self) -> f64 { + fn m32_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_M32) } } #[inline] - fn get_m33(&self) -> f64 { + fn m33_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_M33) } } #[inline] - fn get_m34(&self) -> f64 { + fn m34_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_M34) } } #[inline] - fn get_m41(&self) -> f64 { + fn m41_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_M41) } } #[inline] - fn get_m42(&self) -> f64 { + fn m42_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_M42) } } #[inline] - fn get_m43(&self) -> f64 { + fn m43_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_M43) } } #[inline] - fn get_m44(&self) -> f64 { + fn m44_inner(&self) -> f64 { // SAFETY: in-range access unsafe { *self.inner.borrow().get_unchecked(INDEX_M44) } } - fn get_is_identity(&self) -> bool { + #[inline] + fn is_identity_inner(&self) -> bool { let inner = self.inner.borrow(); // SAFETY: in-range access unsafe { @@ -1310,17 +1393,33 @@ impl DOMMatrixInner { && *inner.get_unchecked(INDEX_M44) == 1.0 } } + + #[inline] + fn is_finite_inner(&self) -> bool { + self + .inner + .borrow() + .into_iter() + .all(|&item| item.is_finite()) + } } -#[op2] -impl DOMMatrixInner { +#[op2(base)] +impl DOMMatrixReadOnly { #[constructor] #[cppgc] - pub fn constructor(#[buffer] buffer: &[f64], is_2d: bool) -> DOMMatrixInner { - DOMMatrixInner { - inner: RefCell::new(Matrix4::from_column_slice(buffer)), - is_2d: Cell::new(is_2d), - } + pub fn constructor<'a>( + state: &mut OpState, + scope: &mut v8::HandleScope<'a>, + value: v8::Local<'a, v8::Value>, + ) -> Result { + DOMMatrixReadOnly::new( + state, + scope, + value, + "Failed to construct 'DOMMatrixReadOnly'".into(), + ContextFn::new_borrowed(&|| Cow::Borrowed("Argument 1")), + ) } #[reentrant] @@ -1328,760 +1427,1268 @@ impl DOMMatrixInner { #[cppgc] pub fn from_matrix( #[webidl] init: DOMMatrixInit, - ) -> Result { - macro_rules! fixup { - ($value3d:expr, $value2d:expr, $default:expr) => {{ - if let Some(value3d) = $value3d { - if let Some(value2d) = $value2d { - if !(*value3d == *value2d || value3d.is_nan() && value2d.is_nan()) { - return Err(GeometryError::Inconsistent2DMatrix); - } - } - value3d - } else if let Some(value2d) = $value2d { - value2d - } else { - webidl::UnrestrictedDouble($default) - } - }}; - } + ) -> Result { + DOMMatrixReadOnly::from_matrix_inner(init) + } - let m11 = fixup!(init.m11, init.a, 1.0); - let m12 = fixup!(init.m12, init.b, 0.0); - let m21 = fixup!(init.m21, init.c, 0.0); - let m22 = fixup!(init.m22, init.d, 1.0); - let m41 = fixup!(init.m41, init.e, 0.0); - let m42 = fixup!(init.m42, init.f, 0.0); - let is_2d = { - let is_2d_can_be_true = *init.m13 == 0.0 - && *init.m14 == 0.0 - && *init.m23 == 0.0 - && *init.m24 == 0.0 - && *init.m31 == 0.0 - && *init.m32 == 0.0 - && *init.m33 == 1.0 - && *init.m34 == 0.0 - && *init.m43 == 0.0 - && *init.m44 == 1.0; - if let Some(is_2d) = init.is_2d { - if is_2d && !is_2d_can_be_true { - return Err(GeometryError::Inconsistent2DMatrix); - } else { - is_2d - } - } else { - is_2d_can_be_true - } - }; + #[rename("fromFloat32Array")] + #[static_method] + #[cppgc] + pub fn from_float32_array<'a>( + scope: &mut v8::HandleScope<'a>, + value: v8::Local<'a, v8::Value>, + ) -> Result { + if !value.is_float32_array() { + return Err(GeometryError::TypeMismatch); + } + let float64 = Vec::::convert( + scope, + value, + "Failed to execute 'DOMMatrixReadOnly.fromFloat32Array'".into(), + (|| Cow::Borrowed("Argument 1")).into(), + &Default::default(), + )?; - if is_2d { - Ok(DOMMatrixInner { + if let [a, b, c, d, e, f] = float64.as_slice() { + return Ok(DOMMatrixReadOnly { #[rustfmt::skip] inner: RefCell::new(Matrix4::new( - *m11, *m21, 0.0, *m41, - *m12, *m22, 0.0, *m42, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0, + *a, *c, 0.0, *e, + *b, *d, 0.0, *f, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, )), is_2d: Cell::new(true), - }) - } else { - let DOMMatrixInit { - m13, - m14, - m23, - m24, - m31, - m32, - m33, - m34, - m43, - m44, - .. - } = init; - Ok(DOMMatrixInner { - #[rustfmt::skip] - inner: RefCell::new(Matrix4::new( - *m11, *m21, *m31, *m41, - *m12, *m22, *m32, *m42, - *m13, *m23, *m33, *m43, - *m14, *m24, *m34, *m44, - )), + }); + } else if float64.len() == 16 { + return Ok(DOMMatrixReadOnly { + inner: RefCell::new(Matrix4::from_column_slice(float64.as_slice())), is_2d: Cell::new(false), - }) + }); + } else { + Err(GeometryError::InvalidSequenceSize) } } + #[rename("fromFloat64Array")] #[static_method] #[cppgc] - pub fn identity() -> DOMMatrixInner { - DOMMatrixInner { - inner: RefCell::new(Matrix4::identity()), - is_2d: Cell::new(true), + pub fn from_float64_array<'a>( + scope: &mut v8::HandleScope<'a>, + value: v8::Local<'a, v8::Value>, + ) -> Result { + if !value.is_float64_array() { + return Err(GeometryError::TypeMismatch); } - } + let float64 = Vec::::convert( + scope, + value, + "Failed to execute 'DOMMatrixReadOnly.fromFloat64Array'".into(), + (|| Cow::Borrowed("Argument 1")).into(), + &Default::default(), + )?; - #[cppgc] - pub fn clone(&self) -> DOMMatrixInner { - self.clone() + if let [a, b, c, d, e, f] = float64.as_slice() { + return Ok(DOMMatrixReadOnly { + #[rustfmt::skip] + inner: RefCell::new(Matrix4::new( + *a, *c, 0.0, *e, + *b, *d, 0.0, *f, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, + )), + is_2d: Cell::new(true), + }); + } else if float64.len() == 16 { + return Ok(DOMMatrixReadOnly { + inner: RefCell::new(Matrix4::from_column_slice(float64.as_slice())), + is_2d: Cell::new(false), + }); + } else { + Err(GeometryError::InvalidSequenceSize) + } } #[fast] #[getter] pub fn a(&self) -> f64 { - self.get_a() - } - - #[setter] - pub fn a(&self, #[webidl] value: webidl::UnrestrictedDouble) { - // SAFETY: in-range access - unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_A) = *value; - } + self.a_inner() } #[fast] #[getter] pub fn b(&self) -> f64 { - self.get_b() - } - - #[setter] - pub fn b(&self, #[webidl] value: webidl::UnrestrictedDouble) { - // SAFETY: in-range access - unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_B) = *value; - } + self.b_inner() } #[fast] #[getter] pub fn c(&self) -> f64 { - self.get_c() - } - - #[setter] - pub fn c(&self, #[webidl] value: webidl::UnrestrictedDouble) { - // SAFETY: in-range access - unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_C) = *value; - } + self.c_inner() } #[fast] #[getter] pub fn d(&self) -> f64 { - self.get_d() + self.d_inner() } - #[setter] - pub fn d(&self, #[webidl] value: webidl::UnrestrictedDouble) { - // SAFETY: in-range access - unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_D) = *value; - } + #[fast] + #[getter] + pub fn e(&self) -> f64 { + self.e_inner() } #[fast] #[getter] - pub fn e(&self) -> f64 { - self.get_e() + pub fn f(&self) -> f64 { + self.f_inner() } - #[setter] - pub fn e(&self, #[webidl] value: webidl::UnrestrictedDouble) { + #[fast] + #[getter] + pub fn m11(&self) -> f64 { + self.m11_inner() + } + + #[fast] + #[getter] + pub fn m12(&self) -> f64 { + self.m12_inner() + } + + #[fast] + #[getter] + pub fn m13(&self) -> f64 { + self.m13_inner() + } + + #[fast] + #[getter] + pub fn m14(&self) -> f64 { + self.m14_inner() + } + + #[fast] + #[getter] + pub fn m21(&self) -> f64 { + self.m21_inner() + } + + #[fast] + #[getter] + pub fn m22(&self) -> f64 { + self.m22_inner() + } + + #[fast] + #[getter] + pub fn m23(&self) -> f64 { + self.m23_inner() + } + + #[fast] + #[getter] + pub fn m24(&self) -> f64 { + self.m24_inner() + } + + #[fast] + #[getter] + pub fn m31(&self) -> f64 { + self.m31_inner() + } + + #[fast] + #[getter] + pub fn m32(&self) -> f64 { + self.m32_inner() + } + + #[fast] + #[getter] + pub fn m33(&self) -> f64 { + self.m33_inner() + } + + #[fast] + #[getter] + pub fn m34(&self) -> f64 { + self.m34_inner() + } + + #[fast] + #[getter] + pub fn m41(&self) -> f64 { + self.m41_inner() + } + + #[fast] + #[getter] + pub fn m42(&self) -> f64 { + self.m42_inner() + } + + #[fast] + #[getter] + pub fn m43(&self) -> f64 { + self.m43_inner() + } + + #[fast] + #[getter] + pub fn m44(&self) -> f64 { + self.m44_inner() + } + + #[fast] + #[getter] + pub fn is_2d(&self) -> bool { + self.is_2d.get() + } + + #[fast] + #[getter] + pub fn is_identity(&self) -> bool { + self.is_identity_inner() + } + + // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) + #[cppgc] + pub fn translate( + &self, + #[webidl] tx: Option, + #[webidl] ty: Option, + #[webidl] tz: Option, + ) -> DOMMatrixReadOnly { + let tx = *tx.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let ty = *ty.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let tz = *tz.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let out = self.clone(); + out.translate_self_inner(tx, ty, tz); + out + } + + // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) + #[cppgc] + pub fn scale( + &self, + #[webidl] sx: Option, + #[webidl] sy: Option, + #[webidl] sz: Option, + #[webidl] origin_x: Option, + #[webidl] origin_y: Option, + #[webidl] origin_z: Option, + ) -> DOMMatrixReadOnly { + let sx = *sx.unwrap_or(webidl::UnrestrictedDouble(1.0)); + let sy = *sy.unwrap_or(webidl::UnrestrictedDouble(sx)); + let sz = *sz.unwrap_or(webidl::UnrestrictedDouble(1.0)); + let origin_x = *origin_x.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let origin_y = *origin_y.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let origin_z = *origin_z.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let out = self.clone(); + if origin_x == 0.0 && origin_y == 0.0 && origin_z == 0.0 { + out.scale_without_origin_self_inner(sx, sy, sz); + } else { + out + .scale_with_origin_self_inner(sx, sy, sz, origin_x, origin_y, origin_z); + } + out + } + + // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) + #[cppgc] + pub fn scale_non_uniform( + &self, + #[webidl] sx: Option, + #[webidl] sy: Option, + ) -> DOMMatrixReadOnly { + let sx = *sx.unwrap_or(webidl::UnrestrictedDouble(1.0)); + let sy = *sy.unwrap_or(webidl::UnrestrictedDouble(1.0)); + let out = self.clone(); + out.scale_without_origin_self_inner(sx, sy, 1.0); + out + } + + // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) + #[cppgc] + pub fn scale3d( + &self, + #[webidl] scale: Option, + #[webidl] origin_x: Option, + #[webidl] origin_y: Option, + #[webidl] origin_z: Option, + ) -> DOMMatrixReadOnly { + let scale = *scale.unwrap_or(webidl::UnrestrictedDouble(1.0)); + let origin_x = *origin_x.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let origin_y = *origin_y.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let origin_z = *origin_z.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let out = self.clone(); + if origin_x == 0.0 && origin_y == 0.0 && origin_z == 0.0 { + out.scale_without_origin_self_inner(scale, scale, scale); + } else { + out.scale_with_origin_self_inner( + scale, scale, scale, origin_x, origin_y, origin_z, + ); + } + out + } + + // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) + #[cppgc] + pub fn rotate( + &self, + #[webidl] rotate_x: Option, + #[webidl] rotate_y: Option, + #[webidl] rotate_z: Option, + ) -> DOMMatrixReadOnly { + let rotate_x = *rotate_x.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let (roll_deg, pitch_deg, yaw_deg) = + if rotate_y.is_none() && rotate_z.is_none() { + (0.0, 0.0, rotate_x) + } else { + ( + rotate_x, + *rotate_y.unwrap_or(webidl::UnrestrictedDouble(0.0)), + *rotate_z.unwrap_or(webidl::UnrestrictedDouble(0.0)), + ) + }; + let out = self.clone(); + out.rotate_self_inner(roll_deg, pitch_deg, yaw_deg); + out + } + + // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) + #[cppgc] + pub fn rotate_from_vector( + &self, + #[webidl] x: Option, + #[webidl] y: Option, + ) -> DOMMatrixReadOnly { + let x = *x.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let y = *y.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let out = self.clone(); + out.rotate_from_vector_self_inner(x, y); + out + } + + // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) + #[cppgc] + pub fn rotate_axis_angle( + &self, + #[webidl] x: Option, + #[webidl] y: Option, + #[webidl] z: Option, + #[webidl] angle_deg: Option, + ) -> DOMMatrixReadOnly { + let x = *x.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let y = *y.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let z = *z.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let angle_deg = *angle_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let out = self.clone(); + out.rotate_axis_angle_self_inner(x, y, z, angle_deg); + out + } + + // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) + #[cppgc] + pub fn skew_x( + &self, + #[webidl] x_deg: Option, + ) -> DOMMatrixReadOnly { + let x_deg = *x_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let out = self.clone(); + out.skew_x_self_inner(x_deg); + out + } + + // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) + #[cppgc] + pub fn skew_y( + &self, + #[webidl] y_deg: Option, + ) -> DOMMatrixReadOnly { + let y_deg = *y_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let out = self.clone(); + out.skew_y_self_inner(y_deg); + out + } + + // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) + #[cppgc] + pub fn multiply<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + other: v8::Local<'a, v8::Value>, + ) -> Result { + let out = self.clone(); + if let Some(other) = + cppgc::try_unwrap_cppgc_proto_object::(scope, other) + { + out.multiply_self_inner(self, &other); + } else { + let other = DOMMatrixInit::convert( + scope, + other, + "Failed to execute 'multiply' on 'DOMMatrixReadOnly'".into(), + (|| Cow::Borrowed("Argument 1")).into(), + &Default::default(), + )?; + let other = DOMMatrixReadOnly::from_matrix_inner(other)?; + out.multiply_self_inner(self, &other); + } + Ok(out) + } + + // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) + #[cppgc] + pub fn flip_x(&self) -> DOMMatrixReadOnly { + let out = self.clone(); + out.flip_x_inner(); + out + } + + // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) + #[cppgc] + pub fn flip_y(&self) -> DOMMatrixReadOnly { + let out = self.clone(); + out.flip_y_inner(); + out + } + + // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) + #[cppgc] + pub fn inverse(&self) -> DOMMatrixReadOnly { + let out = self.clone(); + out.invert_self_inner(); + out + } + + // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) + #[cppgc] + pub fn transform_point<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + point: v8::Local<'a, v8::Value>, + ) -> Result { + let out = DOMPointReadOnly { + inner: RefCell::new(Vector4::zeros()), + }; + if let Some(point) = + cppgc::try_unwrap_cppgc_proto_object::(scope, point) + { + matrix_transform_point(self, &point, &out); + } else { + let point = DOMPointInit::convert( + scope, + point, + "Failed to execute 'transformPoint' on 'DOMMatrixReadOnly'".into(), + (|| Cow::Borrowed("Argument 1")).into(), + &Default::default(), + )?; + let point = DOMPointReadOnly::from_point_inner(point); + matrix_transform_point(self, &point, &out); + } + Ok(out) + } + + #[rename("toJSON")] + pub fn to_json<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + ) -> v8::Local<'a, v8::Object> { + fn set_f64( + scope: &mut v8::HandleScope, + object: &mut v8::Local, + key: &str, + value: f64, + ) { + let key = v8::String::new(scope, key).unwrap(); + let value = v8::Number::new(scope, value); + object.set(scope, key.into(), value.into()).unwrap(); + } + fn set_boolean( + scope: &mut v8::HandleScope, + object: &mut v8::Local, + key: &str, + value: bool, + ) { + let key = v8::String::new(scope, key).unwrap(); + let value = v8::Boolean::new(scope, value); + object.set(scope, key.into(), value.into()).unwrap(); + } + + let mut obj = v8::Object::new(scope); + set_f64(scope, &mut obj, "a", self.a_inner()); + set_f64(scope, &mut obj, "b", self.b_inner()); + set_f64(scope, &mut obj, "c", self.c_inner()); + set_f64(scope, &mut obj, "d", self.d_inner()); + set_f64(scope, &mut obj, "e", self.e_inner()); + set_f64(scope, &mut obj, "f", self.f_inner()); + set_f64(scope, &mut obj, "m11", self.m11_inner()); + set_f64(scope, &mut obj, "m12", self.m12_inner()); + set_f64(scope, &mut obj, "m13", self.m13_inner()); + set_f64(scope, &mut obj, "m14", self.m14_inner()); + set_f64(scope, &mut obj, "m21", self.m21_inner()); + set_f64(scope, &mut obj, "m22", self.m22_inner()); + set_f64(scope, &mut obj, "m23", self.m23_inner()); + set_f64(scope, &mut obj, "m24", self.m24_inner()); + set_f64(scope, &mut obj, "m31", self.m31_inner()); + set_f64(scope, &mut obj, "m32", self.m32_inner()); + set_f64(scope, &mut obj, "m33", self.m33_inner()); + set_f64(scope, &mut obj, "m34", self.m34_inner()); + set_f64(scope, &mut obj, "m41", self.m41_inner()); + set_f64(scope, &mut obj, "m42", self.m42_inner()); + set_f64(scope, &mut obj, "m43", self.m43_inner()); + set_f64(scope, &mut obj, "m44", self.m44_inner()); + set_boolean(scope, &mut obj, "is2D", self.is_2d.get()); + set_boolean(scope, &mut obj, "isIdentity", self.is_identity_inner()); + obj + } +} + +pub struct DOMMatrix {} + +impl GarbageCollected for DOMMatrix {} + +#[op2(inherit = DOMMatrixReadOnly)] +impl DOMMatrix { + #[constructor] + #[cppgc] + pub fn constructor<'a>( + state: &mut OpState, + scope: &mut v8::HandleScope<'a>, + value: v8::Local<'a, v8::Value>, + // TODO(petamoriken): Error when deleting next line. proc-macro bug? + #[webidl] _: Option, + ) -> Result<(DOMMatrixReadOnly, DOMMatrix), GeometryError> { + let ro = DOMMatrixReadOnly::new( + state, + scope, + value, + "Failed to construct 'DOMMatrixReadOnly'".into(), + ContextFn::new_borrowed(&|| Cow::Borrowed("Argument 1")), + )?; + Ok((ro, DOMMatrix {})) + } + + // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) + #[reentrant] + #[static_method] + #[cppgc] + pub fn from_matrix( + #[webidl] init: DOMMatrixInit, + ) -> Result { + DOMMatrixReadOnly::from_matrix_inner(init) + } + + // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) + #[rename("fromFloat32Array")] + #[static_method] + #[cppgc] + pub fn from_float32_array<'a>( + scope: &mut v8::HandleScope<'a>, + value: v8::Local<'a, v8::Value>, + ) -> Result { + if !value.is_float32_array() { + return Err(GeometryError::TypeMismatch); + } + let float64 = Vec::::convert( + scope, + value, + "Failed to execute 'DOMMatrixReadOnly.fromFloat32Array'".into(), + (|| Cow::Borrowed("Argument 1")).into(), + &Default::default(), + )?; + + if let [a, b, c, d, e, f] = float64.as_slice() { + return Ok(DOMMatrixReadOnly { + #[rustfmt::skip] + inner: RefCell::new(Matrix4::new( + *a, *c, 0.0, *e, + *b, *d, 0.0, *f, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, + )), + is_2d: Cell::new(true), + }); + } else if float64.len() == 16 { + return Ok(DOMMatrixReadOnly { + inner: RefCell::new(Matrix4::from_column_slice(float64.as_slice())), + is_2d: Cell::new(false), + }); + } else { + Err(GeometryError::InvalidSequenceSize) + } + } + + // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) + #[rename("fromFloat64Array")] + #[static_method] + #[cppgc] + pub fn from_float64_array<'a>( + scope: &mut v8::HandleScope<'a>, + value: v8::Local<'a, v8::Value>, + ) -> Result { + if !value.is_float64_array() { + return Err(GeometryError::TypeMismatch); + } + let float64 = Vec::::convert( + scope, + value, + "Failed to execute 'DOMMatrixReadOnly.fromFloat64Array'".into(), + (|| Cow::Borrowed("Argument 1")).into(), + &Default::default(), + )?; + + if let [a, b, c, d, e, f] = float64.as_slice() { + return Ok(DOMMatrixReadOnly { + #[rustfmt::skip] + inner: RefCell::new(Matrix4::new( + *a, *c, 0.0, *e, + *b, *d, 0.0, *f, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, + )), + is_2d: Cell::new(true), + }); + } else if float64.len() == 16 { + return Ok(DOMMatrixReadOnly { + inner: RefCell::new(Matrix4::from_column_slice(float64.as_slice())), + is_2d: Cell::new(false), + }); + } else { + Err(GeometryError::InvalidSequenceSize) + } + } + + #[fast] + #[getter] + pub fn a(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.a_inner() + } + + #[setter] + pub fn a( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { + // SAFETY: in-range access + unsafe { + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_A) = *value; + } + } + + #[fast] + #[getter] + pub fn b(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.b_inner() + } + + #[setter] + pub fn b( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { + // SAFETY: in-range access + unsafe { + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_B) = *value; + } + } + + #[fast] + #[getter] + pub fn c(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.c_inner() + } + + #[setter] + pub fn c( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { + // SAFETY: in-range access + unsafe { + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_C) = *value; + } + } + + #[fast] + #[getter] + pub fn d(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.d_inner() + } + + #[setter] + pub fn d( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { + // SAFETY: in-range access + unsafe { + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_D) = *value; + } + } + + #[fast] + #[getter] + pub fn e(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.e_inner() + } + + #[setter] + pub fn e( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_E) = *value; + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_E) = *value; } } #[fast] #[getter] - pub fn f(&self) -> f64 { - self.get_f() + pub fn f(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.f_inner() } #[setter] - pub fn f(&self, #[webidl] value: webidl::UnrestrictedDouble) { + pub fn f( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_F) = *value; + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_F) = *value; } } #[fast] #[getter] - pub fn m11(&self) -> f64 { - self.get_m11() + pub fn m11(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.m11_inner() } #[setter] - pub fn m11(&self, #[webidl] value: webidl::UnrestrictedDouble) { + pub fn m11( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M11) = *value; + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M11) = *value; } } #[fast] #[getter] - pub fn m12(&self) -> f64 { - self.get_m12() + pub fn m12(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.m12_inner() } #[setter] - pub fn m12(&self, #[webidl] value: webidl::UnrestrictedDouble) { + pub fn m12( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M12) = *value; + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M12) = *value; } } #[fast] #[getter] - pub fn m13(&self) -> f64 { - self.get_m13() + pub fn m13(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.m13_inner() } #[setter] - pub fn m13(&self, #[webidl] value: webidl::UnrestrictedDouble) { + pub fn m13( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M13) = *value; + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M13) = *value; } if *value != 0.0 { - self.is_2d.set(false); + ro.is_2d.set(false); } } #[fast] #[getter] - pub fn m14(&self) -> f64 { - self.get_m14() + pub fn m14(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.m14_inner() } #[setter] - pub fn m14(&self, #[webidl] value: webidl::UnrestrictedDouble) { + pub fn m14( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M14) = *value; + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M14) = *value; } if *value != 0.0 { - self.is_2d.set(false); + ro.is_2d.set(false); } } #[fast] #[getter] - pub fn m21(&self) -> f64 { - self.get_m21() + pub fn m21(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.m21_inner() } #[setter] - pub fn m21(&self, #[webidl] value: webidl::UnrestrictedDouble) { + pub fn m21( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M21) = *value; + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M21) = *value; } } #[fast] #[getter] - pub fn m22(&self) -> f64 { - self.get_m22() + pub fn m22(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.m22_inner() } #[setter] - pub fn m22(&self, #[webidl] value: webidl::UnrestrictedDouble) { + pub fn m22( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M22) = *value; + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M22) = *value; } } #[fast] #[getter] - pub fn m23(&self) -> f64 { - self.get_m23() + pub fn m23(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.m23_inner() } #[setter] - pub fn m23(&self, #[webidl] value: webidl::UnrestrictedDouble) { + pub fn m23( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M23) = *value; + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M23) = *value; } if *value != 0.0 { - self.is_2d.set(false); + ro.is_2d.set(false); } } #[fast] #[getter] - pub fn m24(&self) -> f64 { - self.get_m24() + pub fn m24(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.m24_inner() } #[setter] - pub fn m24(&self, #[webidl] value: webidl::UnrestrictedDouble) { + pub fn m24( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M24) = *value; + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M24) = *value; } if *value != 0.0 { - self.is_2d.set(false); + ro.is_2d.set(false); } } #[fast] #[getter] - pub fn m31(&self) -> f64 { - self.get_m31() + pub fn m31(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.m31_inner() } #[setter] - pub fn m31(&self, #[webidl] value: webidl::UnrestrictedDouble) { + pub fn m31( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M31) = *value; + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M31) = *value; } if *value != 0.0 { - self.is_2d.set(false); + ro.is_2d.set(false); } } #[fast] #[getter] - pub fn m32(&self) -> f64 { - self.get_m32() + pub fn m32(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.m32_inner() } #[setter] - pub fn m32(&self, #[webidl] value: webidl::UnrestrictedDouble) { + pub fn m32( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M32) = *value; + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M32) = *value; } if *value != 0.0 { - self.is_2d.set(false); + ro.is_2d.set(false); } } #[fast] #[getter] - pub fn m33(&self) -> f64 { - self.get_m33() + pub fn m33(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.m33_inner() } #[setter] - pub fn m33(&self, #[webidl] value: webidl::UnrestrictedDouble) { + pub fn m33( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M33) = *value; + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M33) = *value; } if *value != 1.0 { - self.is_2d.set(false); + ro.is_2d.set(false); } } #[fast] #[getter] - pub fn m34(&self) -> f64 { - self.get_m34() + pub fn m34(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.m34_inner() } #[setter] - pub fn m34(&self, #[webidl] value: webidl::UnrestrictedDouble) { + pub fn m34( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M34) = *value; + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M34) = *value; } if *value != 0.0 { - self.is_2d.set(false); + ro.is_2d.set(false); } } #[fast] #[getter] - pub fn m41(&self) -> f64 { - self.get_m41() + pub fn m41(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.m41_inner() } #[setter] - pub fn m41(&self, #[webidl] value: webidl::UnrestrictedDouble) { + pub fn m41( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M41) = *value; + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M41) = *value; } } #[fast] #[getter] - pub fn m42(&self) -> f64 { - self.get_m42() + pub fn m42(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.m42_inner() } #[setter] - pub fn m42(&self, #[webidl] value: webidl::UnrestrictedDouble) { + pub fn m42( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M42) = *value; + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M42) = *value; } } #[fast] #[getter] - pub fn m43(&self) -> f64 { - self.get_m43() + pub fn m43(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.m43_inner() } #[setter] - pub fn m43(&self, #[webidl] value: webidl::UnrestrictedDouble) { + pub fn m43( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M43) = *value; + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M43) = *value; } if *value != 0.0 { - self.is_2d.set(false); + ro.is_2d.set(false); } } #[fast] #[getter] - pub fn m44(&self) -> f64 { - self.get_m44() + pub fn m44(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + ro.m44_inner() } #[setter] - pub fn m44(&self, #[webidl] value: webidl::UnrestrictedDouble) { + pub fn m44( + &self, + #[webidl] value: webidl::UnrestrictedDouble, + #[proto] ro: &DOMMatrixReadOnly, + ) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M44) = *value; + *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M44) = *value; } if *value != 1.0 { - self.is_2d.set(false); - } - } - - #[fast] - #[getter] - pub fn is_2d(&self) -> bool { - self.is_2d.get() - } - - #[fast] - #[getter] - pub fn is_identity(&self) -> bool { - self.get_is_identity() - } - - #[fast] - #[getter] - pub fn is_finite(&self) -> bool { - self - .inner - .borrow() - .into_iter() - .all(|&item| item.is_finite()) - } - - #[arraybuffer] - pub fn to_buffer(&self) -> Vec { - // SAFETY: in-range access - unsafe { - slice::from_raw_parts( - self.inner.borrow().as_slice().as_ptr() as *mut u8, - mem::size_of::() * 16, - ) + ro.is_2d.set(false); } - .to_vec() - } - - #[cppgc] - pub fn translate( - &self, - #[webidl] tx: webidl::UnrestrictedDouble, - #[webidl] ty: webidl::UnrestrictedDouble, - #[webidl] tz: webidl::UnrestrictedDouble, - ) -> DOMMatrixInner { - let out = self.clone(); - out.translate_self_inner(*tx, *ty, *tz); - out } + // TODO(petamoriken): returns self pub fn translate_self( &self, - #[webidl] tx: webidl::UnrestrictedDouble, - #[webidl] ty: webidl::UnrestrictedDouble, - #[webidl] tz: webidl::UnrestrictedDouble, + #[webidl] tx: Option, + #[webidl] ty: Option, + #[webidl] tz: Option, + #[proto] ro: &DOMMatrixReadOnly, ) { - self.translate_self_inner(*tx, *ty, *tz); + let tx = *tx.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let ty = *ty.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let tz = *tz.unwrap_or(webidl::UnrestrictedDouble(0.0)); + ro.translate_self_inner(tx, ty, tz); } - #[cppgc] - pub fn scale_without_origin( - &self, - #[webidl] sx: webidl::UnrestrictedDouble, - #[webidl] sy: webidl::UnrestrictedDouble, - #[webidl] sz: webidl::UnrestrictedDouble, - ) -> DOMMatrixInner { - let out = self.clone(); - out.scale_without_origin_self_inner(*sx, *sy, *sz); - out - } - - pub fn scale_without_origin_self( + // TODO(petamoriken): returns self + pub fn scale_self( &self, - #[webidl] sx: webidl::UnrestrictedDouble, - #[webidl] sy: webidl::UnrestrictedDouble, - #[webidl] sz: webidl::UnrestrictedDouble, + #[webidl] sx: Option, + #[webidl] sy: Option, + #[webidl] sz: Option, + #[webidl] origin_x: Option, + #[webidl] origin_y: Option, + #[webidl] origin_z: Option, + #[proto] ro: &DOMMatrixReadOnly, ) { - self.scale_without_origin_self_inner(*sx, *sy, *sz); - } - - #[cppgc] - pub fn scale_with_origin( - &self, - #[webidl] sx: webidl::UnrestrictedDouble, - #[webidl] sy: webidl::UnrestrictedDouble, - #[webidl] sz: webidl::UnrestrictedDouble, - #[webidl] origin_x: webidl::UnrestrictedDouble, - #[webidl] origin_y: webidl::UnrestrictedDouble, - #[webidl] origin_z: webidl::UnrestrictedDouble, - ) -> DOMMatrixInner { - let out = self.clone(); - out.scale_with_origin_self_inner( - *sx, *sy, *sz, *origin_x, *origin_y, *origin_z, - ); - out + let sx = *sx.unwrap_or(webidl::UnrestrictedDouble(1.0)); + let sy = *sy.unwrap_or(webidl::UnrestrictedDouble(sx)); + let sz = *sz.unwrap_or(webidl::UnrestrictedDouble(1.0)); + let origin_x = *origin_x.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let origin_y = *origin_y.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let origin_z = *origin_z.unwrap_or(webidl::UnrestrictedDouble(0.0)); + if origin_x == 0.0 && origin_y == 0.0 && origin_z == 0.0 { + ro.scale_without_origin_self_inner(sx, sy, sz); + } else { + ro.scale_with_origin_self_inner(sx, sy, sz, origin_x, origin_y, origin_z); + } } - pub fn scale_with_origin_self( + // TODO(petamoriken): returns self + pub fn scale3d_self( &self, - #[webidl] sx: webidl::UnrestrictedDouble, - #[webidl] sy: webidl::UnrestrictedDouble, - #[webidl] sz: webidl::UnrestrictedDouble, - #[webidl] origin_x: webidl::UnrestrictedDouble, - #[webidl] origin_y: webidl::UnrestrictedDouble, - #[webidl] origin_z: webidl::UnrestrictedDouble, + #[webidl] scale: Option, + #[webidl] origin_x: Option, + #[webidl] origin_y: Option, + #[webidl] origin_z: Option, + #[proto] ro: &DOMMatrixReadOnly, ) { - self.scale_with_origin_self_inner(*sx, *sy, *sz, *origin_x, *origin_y, *origin_z); - } - - #[cppgc] - pub fn rotate( - &self, - #[webidl] roll_deg: webidl::UnrestrictedDouble, - #[webidl] pitch_deg: webidl::UnrestrictedDouble, - #[webidl] yaw_deg: webidl::UnrestrictedDouble, - ) -> DOMMatrixInner { - let out = self.clone(); - out.rotate_self_inner(*roll_deg, *pitch_deg, *yaw_deg); - out + let scale = *scale.unwrap_or(webidl::UnrestrictedDouble(1.0)); + let origin_x = *origin_x.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let origin_y = *origin_y.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let origin_z = *origin_z.unwrap_or(webidl::UnrestrictedDouble(0.0)); + if origin_x == 0.0 && origin_y == 0.0 && origin_z == 0.0 { + ro.scale_without_origin_self_inner(scale, scale, scale); + } else { + ro.scale_with_origin_self_inner( + scale, scale, scale, origin_x, origin_y, origin_z, + ); + } } + // TODO(petamoriken): returns self pub fn rotate_self( &self, - #[webidl] roll_deg: webidl::UnrestrictedDouble, - #[webidl] pitch_deg: webidl::UnrestrictedDouble, - #[webidl] yaw_deg: webidl::UnrestrictedDouble, + #[webidl] rotate_x: Option, + #[webidl] rotate_y: Option, + #[webidl] rotate_z: Option, + #[proto] ro: &DOMMatrixReadOnly, ) { - self.rotate_self_inner(*roll_deg, *pitch_deg, *yaw_deg); - } - - #[cppgc] - pub fn rotate_from_vector( - &self, - #[webidl] x: webidl::UnrestrictedDouble, - #[webidl] y: webidl::UnrestrictedDouble, - ) -> DOMMatrixInner { - let out = self.clone(); - out.rotate_from_vector_self_inner(*x, *y); - out + let rotate_x = *rotate_x.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let (roll_deg, pitch_deg, yaw_deg) = + if rotate_y.is_none() && rotate_z.is_none() { + (0.0, 0.0, rotate_x) + } else { + ( + rotate_x, + *rotate_y.unwrap_or(webidl::UnrestrictedDouble(0.0)), + *rotate_z.unwrap_or(webidl::UnrestrictedDouble(0.0)), + ) + }; + ro.rotate_self_inner(roll_deg, pitch_deg, yaw_deg); } + // TODO(petamoriken): returns self pub fn rotate_from_vector_self( &self, - #[webidl] x: webidl::UnrestrictedDouble, - #[webidl] y: webidl::UnrestrictedDouble, + #[webidl] x: Option, + #[webidl] y: Option, + #[proto] ro: &DOMMatrixReadOnly, ) { - self.rotate_from_vector_self_inner(*x, *y); - } - - #[cppgc] - pub fn rotate_axis_angle( - &self, - #[webidl] x: webidl::UnrestrictedDouble, - #[webidl] y: webidl::UnrestrictedDouble, - #[webidl] z: webidl::UnrestrictedDouble, - #[webidl] angle_deg: webidl::UnrestrictedDouble, - ) -> DOMMatrixInner { - let out = self.clone(); - out.rotate_axis_angle_self_inner(*x, *y, *z, *angle_deg); - out + let x = *x.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let y = *y.unwrap_or(webidl::UnrestrictedDouble(0.0)); + ro.rotate_from_vector_self_inner(x, y); } + // TODO(petamoriken): returns self pub fn rotate_axis_angle_self( &self, - #[webidl] x: webidl::UnrestrictedDouble, - #[webidl] y: webidl::UnrestrictedDouble, - #[webidl] z: webidl::UnrestrictedDouble, - #[webidl] angle_deg: webidl::UnrestrictedDouble, + #[webidl] x: Option, + #[webidl] y: Option, + #[webidl] z: Option, + #[webidl] angle_deg: Option, + #[proto] ro: &DOMMatrixReadOnly, ) { - self.rotate_axis_angle_self_inner(*x, *y, *z, *angle_deg); + let x = *x.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let y = *y.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let z = *z.unwrap_or(webidl::UnrestrictedDouble(0.0)); + let angle_deg = *angle_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); + ro.rotate_axis_angle_self_inner(x, y, z, angle_deg); } - #[cppgc] - pub fn skew_x( + // TODO(petamoriken): returns self + pub fn skew_x_self( &self, - #[webidl] x_deg: webidl::UnrestrictedDouble, - ) -> DOMMatrixInner { - let out = self.clone(); - out.skew_x_self_inner(*x_deg); - out - } - - pub fn skew_x_self(&self, #[webidl] x_deg: webidl::UnrestrictedDouble) { - self.skew_x_self_inner(*x_deg); + #[webidl] x_deg: Option, + #[proto] ro: &DOMMatrixReadOnly, + ) { + let x_deg = *x_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); + ro.skew_x_self_inner(x_deg); } - #[cppgc] - pub fn skew_y( + // TODO(petamoriken): returns self + pub fn skew_y_self( &self, - #[webidl] y_deg: webidl::UnrestrictedDouble, - ) -> DOMMatrixInner { - let out = self.clone(); - out.skew_y_self_inner(*y_deg); - out - } - - pub fn skew_y_self(&self, #[webidl] y_deg: webidl::UnrestrictedDouble) { - self.skew_y_self_inner(*y_deg); - } - - #[cppgc] - pub fn multiply(&self, #[cppgc] other: &DOMMatrixInner) -> DOMMatrixInner { - let out = DOMMatrixInner { - inner: RefCell::new(Matrix4::zeros()), - is_2d: Cell::new(true), - }; - out.multiply_self_inner(self, other); - out - } - - #[fast] - pub fn multiply_self(&self, #[cppgc] other: &DOMMatrixInner) { - let result = DOMMatrixInner { - inner: RefCell::new(Matrix4::zeros()), - is_2d: Cell::new(true), - }; - result.multiply_self_inner(self, other); - self.inner.borrow_mut().copy_from(&result.inner.borrow()); - self.is_2d.set(result.is_2d.get()); - } - - #[fast] - pub fn pre_multiply_self(&self, #[cppgc] other: &DOMMatrixInner) { - let result = DOMMatrixInner { - inner: RefCell::new(Matrix4::zeros()), - is_2d: Cell::new(true), - }; - result.multiply_self_inner(other, self); - self.inner.borrow_mut().copy_from(&result.inner.borrow()); - self.is_2d.set(result.is_2d.get()); - } - - #[cppgc] - pub fn flip_x(&self) -> DOMMatrixInner { - let out = self.clone(); - out.flip_x_inner(); - out - } - - #[cppgc] - pub fn flip_y(&self) -> DOMMatrixInner { - let out = self.clone(); - out.flip_y_inner(); - out - } - - #[cppgc] - pub fn inverse(&self) -> DOMMatrixInner { - let out = self.clone(); - out.invert_self_inner(); - out - } - + #[webidl] y_deg: Option, + #[proto] ro: &DOMMatrixReadOnly, + ) { + let y_deg = *y_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); + ro.skew_y_self_inner(y_deg); + } + + // TODO(petamoriken): Maybe proc-macro bug + // mismatched types + // expected mutable reference `&mut HandleScope<'_>` + // found mutable reference `&mut &mut Isolate + + // #[fast] + // pub fn multiply_self<'a>( + // &self, + // scope: &mut v8::HandleScope<'a>, + // other: v8::Local<'a, v8::Value>, + // #[proto] ro: &DOMMatrixReadOnly, + // ) -> Result<(), GeometryError> { + // let result = DOMMatrixReadOnly { + // inner: RefCell::new(Matrix4::zeros()), + // is_2d: Cell::new(true), + // }; + // if let Some(other) = + // cppgc::try_unwrap_cppgc_object::(scope, other) + // { + // result.multiply_self_inner(ro, &other); + // } else { + // let other = DOMMatrixInit::convert( + // scope, + // other, + // "Failed to execute 'multiply' on 'DOMMatrixReadOnly'".into(), + // (|| Cow::Borrowed("Argument 1")).into(), + // &Default::default(), + // )?; + // let other = DOMMatrixReadOnly::from_matrix_inner(other)?; + // result.multiply_self_inner(ro, &other); + // } + // ro.inner.borrow_mut().copy_from(&result.inner.borrow()); + // ro.is_2d.set(result.is_2d.get()); + // Ok(()) + // } + + // #[fast] + // pub fn pre_multiply_self<'a>( + // &self, + // scope: &mut v8::HandleScope<'a>, + // other: v8::Local<'a, v8::Value>, + // #[proto] ro: &DOMMatrixReadOnly, + // ) -> Result<(), GeometryError> { + // let result = DOMMatrixReadOnly { + // inner: RefCell::new(Matrix4::zeros()), + // is_2d: Cell::new(true), + // }; + // if let Some(other) = + // cppgc::try_unwrap_cppgc_object::(scope, other) + // { + // result.multiply_self_inner(&other, ro); + // } else { + // let other = DOMMatrixInit::convert( + // scope, + // other, + // "Failed to execute 'multiply' on 'DOMMatrixReadOnly'".into(), + // (|| Cow::Borrowed("Argument 1")).into(), + // &Default::default(), + // )?; + // let other = DOMMatrixReadOnly::from_matrix_inner(other)?; + // result.multiply_self_inner(&other, ro); + // } + // ro.inner.borrow_mut().copy_from(&result.inner.borrow()); + // ro.is_2d.set(result.is_2d.get()); + // Ok(()) + // } + + // TODO(petamoriken): returns self #[fast] - pub fn invert_self(&self) { - self.invert_self_inner(); - } - - #[cppgc] - pub fn transform_point( - &self, - #[cppgc] point: &DOMPointReadOnly, - ) -> DOMPointReadOnly { - let out = DOMPointReadOnly { - inner: RefCell::new(Vector4::zeros()), - }; - matrix_transform_point(self, point, &out); - out - } - - #[rename("toJSON")] - pub fn to_json<'a>( - &self, - scope: &mut v8::HandleScope<'a>, - ) -> v8::Local<'a, v8::Object> { - fn set_f64( - scope: &mut v8::HandleScope, - object: &mut v8::Local, - key: &str, - value: f64, - ) { - let key = v8::String::new(scope, key).unwrap(); - let value = v8::Number::new(scope, value); - object.set(scope, key.into(), value.into()).unwrap(); - } - fn set_boolean( - scope: &mut v8::HandleScope, - object: &mut v8::Local, - key: &str, - value: bool, - ) { - let key = v8::String::new(scope, key).unwrap(); - let value = v8::Boolean::new(scope, value); - object.set(scope, key.into(), value.into()).unwrap(); - } - - let mut obj = v8::Object::new(scope); - set_f64(scope, &mut obj, "a", self.get_a()); - set_f64(scope, &mut obj, "b", self.get_b()); - set_f64(scope, &mut obj, "c", self.get_c()); - set_f64(scope, &mut obj, "d", self.get_d()); - set_f64(scope, &mut obj, "e", self.get_e()); - set_f64(scope, &mut obj, "f", self.get_f()); - set_f64(scope, &mut obj, "m11", self.get_m11()); - set_f64(scope, &mut obj, "m12", self.get_m12()); - set_f64(scope, &mut obj, "m13", self.get_m13()); - set_f64(scope, &mut obj, "m14", self.get_m14()); - set_f64(scope, &mut obj, "m21", self.get_m21()); - set_f64(scope, &mut obj, "m22", self.get_m22()); - set_f64(scope, &mut obj, "m23", self.get_m23()); - set_f64(scope, &mut obj, "m24", self.get_m24()); - set_f64(scope, &mut obj, "m31", self.get_m31()); - set_f64(scope, &mut obj, "m32", self.get_m32()); - set_f64(scope, &mut obj, "m33", self.get_m33()); - set_f64(scope, &mut obj, "m34", self.get_m34()); - set_f64(scope, &mut obj, "m41", self.get_m41()); - set_f64(scope, &mut obj, "m42", self.get_m42()); - set_f64(scope, &mut obj, "m43", self.get_m43()); - set_f64(scope, &mut obj, "m44", self.get_m44()); - set_boolean(scope, &mut obj, "is2D", self.is_2d.get()); - set_boolean(scope, &mut obj, "isIdentity", self.get_is_identity()); - obj + pub fn invert_self(&self, #[proto] ro: &DOMMatrixReadOnly) { + ro.invert_self_inner(); } } @@ -2124,7 +2731,7 @@ fn minimum(a: f64, b: f64) -> f64 { } fn matrix_transform_point( - matrix: &DOMMatrixInner, + matrix: &DOMMatrixReadOnly, point: &DOMPointReadOnly, out: &DOMPointReadOnly, ) { @@ -2133,3 +2740,74 @@ fn matrix_transform_point( let mut result = out.inner.borrow_mut(); inner.mul_to(&point, &mut result); } + +#[op2] +#[arraybuffer] +pub fn op_geometry_matrix_to_buffer<'a>( + scope: &mut v8::HandleScope<'a>, + matrix: v8::Local<'a, v8::Value>, +) -> Vec { + let matrix = + cppgc::try_unwrap_cppgc_proto_object::(scope, matrix) + .unwrap(); + let inner = matrix.inner.borrow(); + // SAFETY: in-range access + unsafe { + slice::from_raw_parts( + inner.as_slice().as_ptr() as *mut u8, + mem::size_of::() * 16, + ) + } + .to_vec() +} + +#[op2] +#[string] +pub fn op_geometry_matrix_to_string<'a>( + scope: &mut v8::HandleScope<'a>, + matrix: v8::Local<'a, v8::Value>, +) -> Result { + let matrix = + cppgc::try_unwrap_cppgc_proto_object::(scope, matrix) + .unwrap(); + if !matrix.is_finite_inner() { + return Err(GeometryError::InvalidState); + } + if matrix.is_2d.get() { + Ok(format!( + "matrix({}, {}, {}, {}, {}, {})", + matrix.a_inner(), + matrix.b_inner(), + matrix.c_inner(), + matrix.d_inner(), + matrix.e_inner(), + matrix.f_inner(), + )) + } else { + Ok(format!( + "matrix3d({})", + matrix + .inner + .borrow() + .iter() + .map(|item| item.to_string()) + .collect::>() + .join(", ") + )) + } +} + +// TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) +#[op2] +#[cppgc] +pub fn op_geometry_parse_transform_list( + #[string] transform_list: &str, +) -> DOMMatrixReadOnly { + unimplemented!() +} + +#[op2(fast)] +fn op_geometry_get_enable_window_features(state: &mut OpState) -> bool { + let state = state.borrow_mut::(); + state.enable_window_features +} diff --git a/runtime/js/98_global_scope_window.js b/runtime/js/98_global_scope_window.js index e4fb5135a2b7ab..2f477272290faf 100644 --- a/runtime/js/98_global_scope_window.js +++ b/runtime/js/98_global_scope_window.js @@ -29,71 +29,7 @@ import * as globalInterfaces from "ext:deno_web/04_global_interfaces.js"; import * as webStorage from "ext:deno_webstorage/01_webstorage.js"; import * as prompt from "ext:runtime/41_prompt.js"; import { loadWebGPU } from "ext:deno_webgpu/00_init.js"; -import { createGeometryLoader } from "ext:deno_geometry/00_init.js"; - -const MATRIX_PATTERN = new SafeRegExp( - /^\s*matrix(3d)?\(([-\+0-9.e,\s]+)\)\s*$/iu, -); - -const loadGeometry = createGeometryLoader((transformList, prefix) => { - if (transformList === "") { - return { - // deno-fmt-ignore - matrix: new Float64Array([ - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1, - ]), - is2D: true, - }; - } - - // Currently only parsing of a single matrix, matrix3d function without units - // as arguments is implemented - // TODO(petamoriken): Add CSS parser such as lightningcss to support more cases - const matrixMatch = StringPrototypeMatch(transformList, MATRIX_PATTERN); - if (matrixMatch !== null) { - const is2D = matrixMatch[1] === undefined; - /** @type {number[]} */ - const seq = ArrayPrototypeMap( - StringPrototypeSplit(matrixMatch[2], ","), - (str) => Number(str), - ); - if ( - is2D && seq.length !== 6 || - !is2D && seq.length !== 16 || - ArrayPrototypeSome(seq, (num) => NumberIsNaN(num)) - ) { - throw new DOMException( - `${prefix}: Failed to parse '${transformList}'`, - "SyntaxError", - ); - } - if (is2D) { - const { 0: a, 1: b, 2: c, 3: d, 4: e, 5: f } = seq; - return { - // deno-fmt-ignore - matrix: new Float64Array([ - a, b, 0, 0, - c, d, 0, 0, - 0, 0, 1, 0, - e, f, 0, 1, - ]), - is2D, - }; - } else { - return { - matrix: new Float64Array(seq), - is2D, - }; - } - } - - throw new TypeError( - `${prefix}: CSS parser is not fully implemented`, - ); -}, true); +import { loadGeometry } from "ext:deno_geometry/00_init.js"; class Navigator { constructor() { diff --git a/runtime/js/98_global_scope_worker.js b/runtime/js/98_global_scope_worker.js index afe8f32470d969..a63c38565bc486 100644 --- a/runtime/js/98_global_scope_worker.js +++ b/runtime/js/98_global_scope_worker.js @@ -18,13 +18,7 @@ import * as console from "ext:deno_console/01_console.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; import * as globalInterfaces from "ext:deno_web/04_global_interfaces.js"; import { loadWebGPU } from "ext:deno_webgpu/00_init.js"; -import { createGeometryLoader } from "ext:deno_geometry/00_init.js"; - -const loadGeometry = createGeometryLoader((_transformList, prefix) => { - throw new TypeError( - `${prefix}: Cannot parse CSS on Workers`, - ); -}, false); +import { loadGeometry } from "ext:deno_geometry/00_init.js"; function memoizeLazy(f) { let v_ = null; diff --git a/runtime/snapshot.rs b/runtime/snapshot.rs index 63e03accab1e62..350d26b5e918ac 100644 --- a/runtime/snapshot.rs +++ b/runtime/snapshot.rs @@ -38,7 +38,7 @@ pub fn create_runtime_snapshot( deno_webgpu::deno_webgpu::init_ops_and_esm(), deno_canvas::deno_canvas::init_ops_and_esm(), deno_fetch::deno_fetch::init_ops_and_esm::(Default::default()), - deno_geometry::deno_geometry::init_ops_and_esm(), + deno_geometry::deno_geometry::init_ops_and_esm(false), deno_cache::deno_cache::init_ops_and_esm(None), deno_websocket::deno_websocket::init_ops_and_esm::( "".to_owned(), diff --git a/runtime/snapshot_info.rs b/runtime/snapshot_info.rs index b584d658c141d4..a7c9dad2cdafa5 100644 --- a/runtime/snapshot_info.rs +++ b/runtime/snapshot_info.rs @@ -281,7 +281,7 @@ pub fn get_extensions_in_snapshot() -> Vec { deno_webgpu::deno_webgpu::init_ops(), deno_canvas::deno_canvas::init_ops(), deno_fetch::deno_fetch::init_ops::(Default::default()), - deno_geometry::deno_geometry::init_ops(), + deno_geometry::deno_geometry::init_ops(false), deno_cache::deno_cache::init_ops(None), deno_websocket::deno_websocket::init_ops::( "".to_owned(), diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 8abe02fc547472..6f433299029a3f 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -515,7 +515,7 @@ impl WebWorker { ..Default::default() }, ), - deno_geometry::deno_geometry::init_ops_and_esm(), + deno_geometry::deno_geometry::init_ops_and_esm(false), deno_cache::deno_cache::init_ops_and_esm(create_cache), deno_websocket::deno_websocket::init_ops_and_esm::( options.bootstrap.user_agent.clone(), diff --git a/runtime/worker.rs b/runtime/worker.rs index 27c426ef449be1..55fc00a47233a4 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -413,7 +413,7 @@ impl MainWorker { ..Default::default() }, ), - deno_geometry::deno_geometry::init_ops_and_esm(), + deno_geometry::deno_geometry::init_ops_and_esm(true), deno_cache::deno_cache::init_ops_and_esm(create_cache), deno_websocket::deno_websocket::init_ops_and_esm::( options.bootstrap.user_agent.clone(), From 691d2aca7777ad9969edeb5a224c9bde25a92d98 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 28 Apr 2025 15:36:08 +0900 Subject: [PATCH 27/63] cleanup --- ext/geometry/lib.rs | 6 +++--- runtime/js/98_global_scope_window.js | 9 --------- runtime/js/98_global_scope_worker.js | 1 - 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index f6eccb30cbc885..3fb169e6ac45e6 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -198,11 +198,11 @@ impl DOMPointReadOnly { #[webidl] value: DOMMatrixInit, ) -> Result { let matrix = DOMMatrixReadOnly::from_matrix_inner(value)?; - let out = DOMPointReadOnly { + let ro = DOMPointReadOnly { inner: RefCell::new(Vector4::zeros()), }; - matrix_transform_point(&matrix, self, &out); - Ok(out) + matrix_transform_point(&matrix, self, &ro); + Ok(ro) } } diff --git a/runtime/js/98_global_scope_window.js b/runtime/js/98_global_scope_window.js index 2f477272290faf..5f28b9c4ccfd32 100644 --- a/runtime/js/98_global_scope_window.js +++ b/runtime/js/98_global_scope_window.js @@ -7,18 +7,9 @@ import { op_bootstrap_user_agent, } from "ext:core/ops"; const { - ArrayPrototypeMap, - ArrayPrototypeSome, - Float64Array, - Number, - NumberIsNaN, ObjectDefineProperties, ObjectPrototypeIsPrototypeOf, - SafeRegExp, - StringPrototypeMatch, - StringPrototypeSplit, SymbolFor, - TypeError, } = primordials; import * as location from "ext:deno_web/12_location.js"; diff --git a/runtime/js/98_global_scope_worker.js b/runtime/js/98_global_scope_worker.js index a63c38565bc486..6a5c9befdca0c0 100644 --- a/runtime/js/98_global_scope_worker.js +++ b/runtime/js/98_global_scope_worker.js @@ -10,7 +10,6 @@ const { ObjectDefineProperties, ObjectPrototypeIsPrototypeOf, SymbolFor, - TypeError, } = primordials; import * as location from "ext:deno_web/12_location.js"; From 289407d16890fe4b84bd3ef976def428899bd406 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 29 Apr 2025 01:32:20 +0900 Subject: [PATCH 28/63] wip --- Cargo.lock | 156 +++++++++++++++- Cargo.toml | 3 +- ext/geometry/01_geometry.js | 4 +- ext/geometry/Cargo.toml | 1 + ext/geometry/README.md | 4 +- ext/geometry/lib.rs | 356 ++++++++++++++++++++++++++++-------- runtime/js/99_main.js | 6 + 7 files changed, 450 insertions(+), 80 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 93b433ae76294a..9c06acdbdf3e4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -98,6 +98,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", + "getrandom", "once_cell", "version_check", "zerocopy", @@ -1048,12 +1049,41 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-str" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21077772762a1002bb421c3af42ac1725fa56066bfc53d9a55bb79905df2aaf3" +dependencies = [ + "const-str-proc-macro", +] + +[[package]] +name = "const-str-proc-macro" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1e0fdd2e5d3041e530e1b21158aeeef8b5d0e306bc5c1e3d6cf0930d10e25a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "convert_case" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "cooked-waker" version = "5.0.0" @@ -1346,6 +1376,38 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25670139e591f1c2869eb8d0d977028f8d05e859132b4c874ecd02a00d3c9174" +[[package]] +name = "cssparser" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9be934d936a0fbed5bcdc01042b770de1398bf79d0e192f49fa7faea0e99281e" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa", + "phf", + "smallvec", +] + +[[package]] +name = "cssparser-color" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556c099a61d85989d7af52b692e35a8d68a57e7df8c6d07563dc0778b3960c9f" +dependencies = [ + "cssparser", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn 2.0.87", +] + [[package]] name = "ctr" version = "0.9.2" @@ -2018,6 +2080,7 @@ version = "0.1.0" dependencies = [ "deno_core", "deno_error", + "lightningcss", "nalgebra", "thiserror 2.0.12", ] @@ -3093,7 +3156,7 @@ version = "0.99.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ - "convert_case", + "convert_case 0.4.0", "proc-macro2", "quote", "rustc_version 0.4.0", @@ -3331,6 +3394,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "dtoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04" + +[[package]] +name = "dtoa-short" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" +dependencies = [ + "dtoa", +] + [[package]] name = "dunce" version = "1.0.5" @@ -4965,6 +5043,15 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.13.0" @@ -5271,6 +5358,41 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "lightningcss" +version = "1.0.0-alpha.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c84f971730745f4aaac013b6cf4328baf1548efc973c0d95cfd843a3c1ca07af" +dependencies = [ + "ahash", + "bitflags 2.8.0", + "const-str", + "cssparser", + "cssparser-color", + "data-encoding", + "getrandom", + "indexmap 2.8.0", + "itertools 0.10.5", + "lazy_static", + "lightningcss-derive", + "parcel_selectors", + "paste", + "pathdiff", + "smallvec", +] + +[[package]] +name = "lightningcss-derive" +version = "1.0.0-alpha.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12744d1279367caed41739ef094c325d53fb0ffcd4f9b84a368796f870252" +dependencies = [ + "convert_case 0.6.0", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "linux-raw-sys" version = "0.4.13" @@ -6129,6 +6251,22 @@ dependencies = [ "par-core", ] +[[package]] +name = "parcel_selectors" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dccbc6fb560df303a44e511618256029410efbc87779018f751ef12c488271fe" +dependencies = [ + "bitflags 2.8.0", + "cssparser", + "log", + "phf", + "phf_codegen", + "precomputed-hash", + "rustc-hash 2.1.1", + "smallvec", +] + [[package]] name = "parking_lot" version = "0.12.3" @@ -6290,6 +6428,16 @@ dependencies = [ "phf_shared", ] +[[package]] +name = "phf_codegen" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +dependencies = [ + "phf_generator", + "phf_shared", +] + [[package]] name = "phf_generator" version = "0.11.2" @@ -6441,6 +6589,12 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + [[package]] name = "prefix-trie" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index 51069ae5af2913..ae131f6c453d05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -365,7 +365,8 @@ napi-build = "1" napi-sys = { version = "=2.2.2", default-features = false } # geometry -# TODO(petamoriken): Prefer to use glam as well as wgpu, but glam is not sufficient for mutable operations +# NOTE: cannot disable grid feature: https://github.com/parcel-bundler/lightningcss/issues/376 +lightningcss = { version = "1.0.0-alpha.65", default-features = false, features = ["grid"] } nalgebra = { version = "0.33.2", default-features = false, features = ["std"] } # webgpu diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 212688032bf9c8..2a00381da8db4c 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -12,7 +12,7 @@ import { op_geometry_get_enable_window_features, op_geometry_matrix_to_buffer, op_geometry_matrix_to_string, - op_geometry_parse_transform_list, + op_geometry_set_matrix_value, } from "ext:core/ops"; const { ArrayPrototypeJoin, @@ -188,7 +188,7 @@ if (op_geometry_get_enable_window_features()) { ObjectDefineProperty(DOMMatrixPrototype, "setMatrixValue", { __proto__: null, value: function setMatrixValue(transformList) { - return op_geometry_parse_transform_list(transformList); + op_geometry_set_matrix_value(this, transformList); }, writable: true, enumerable: true, diff --git a/ext/geometry/Cargo.toml b/ext/geometry/Cargo.toml index eeca9d2f4a0076..7f53629c460fe8 100644 --- a/ext/geometry/Cargo.toml +++ b/ext/geometry/Cargo.toml @@ -16,5 +16,6 @@ path = "lib.rs" [dependencies] deno_core.workspace = true deno_error.workspace = true +lightningcss.workspace = true nalgebra.workspace = true thiserror.workspace = true diff --git a/ext/geometry/README.md b/ext/geometry/README.md index e03a03a1208bfb..2337878f5d3e0e 100644 --- a/ext/geometry/README.md +++ b/ext/geometry/README.md @@ -70,7 +70,7 @@ Following ops are provided, which can be accessed through `Deno.ops`: - DOMQuad - DOMMatrixReadOnly - DOMMatrix +- op_geometry_get_enable_window_features - op_geometry_matrix_to_buffer - op_geometry_matrix_to_string -- op_geometry_parse_transform_list -- op_geometry_get_enable_window_features +- op_geometry_set_matrix_value diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 3fb169e6ac45e6..772f1f6be48486 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -17,6 +17,13 @@ use deno_core::webidl::WebIdlError; use deno_core::GarbageCollected; use deno_core::OpState; use deno_core::WebIDL; +use lightningcss::properties::transform::Matrix as CSSMatrix; +use lightningcss::properties::transform::Matrix3d as CSSMatrix3d; +use lightningcss::properties::transform::Transform; +use lightningcss::properties::transform::TransformList; +use lightningcss::traits::Parse; +use lightningcss::values::length::LengthPercentage; +use lightningcss::values::number::CSSNumber; use nalgebra::Matrix3; use nalgebra::Matrix4; use nalgebra::Matrix4x2; @@ -30,10 +37,10 @@ deno_core::extension!( deno_geometry, deps = [deno_webidl, deno_web, deno_console], ops = [ + op_geometry_get_enable_window_features, op_geometry_matrix_to_buffer, op_geometry_matrix_to_string, - op_geometry_parse_transform_list, - op_geometry_get_enable_window_features, + op_geometry_set_matrix_value, ], objects = [ DOMPointReadOnly, @@ -68,6 +75,9 @@ impl State { #[derive(Debug, thiserror::Error, deno_error::JsError)] pub enum GeometryError { + #[class(type)] + #[error("Illegal invocation")] + IllegalInvocation, #[class(inherit)] #[error(transparent)] WebIDL(#[from] WebIdlError), @@ -75,9 +85,6 @@ pub enum GeometryError { #[error("Inconsistent 2d matrix value")] Inconsistent2DMatrix, #[class(type)] - #[error("Cannot parse CSS on Workers")] - DisallowWindowFeatures, - #[class(type)] #[error("The sequence must contain 6 elements for a 2D matrix or 16 elements for a 3D matrix")] InvalidSequenceSize, #[class(type)] @@ -86,6 +93,15 @@ pub enum GeometryError { #[class("DOMExceptionInvalidStateError")] #[error("Cannot be serialized with NaN or Infinity values")] InvalidState, + #[class(type)] + #[error("Cannot parse a CSS value on Workers")] + DisallowWindowFeatures, + #[class("DOMExceptionSyntaxError")] + #[error("Failed to parse a CSS value")] + FailedToParse, + #[class("DOMExceptionSyntaxError")] + #[error("CSS value contains relative values")] + ContainsRelativeValue, } #[derive(WebIDL, Debug)] @@ -902,19 +918,23 @@ impl DOMMatrixReadOnly { prefix: Cow<'static, str>, context: ContextFn<'_>, ) -> Result { + // omitted (undefined) if value.is_undefined() { return Ok(DOMMatrixReadOnly::identity()); } - if value.is_string() { + + // DOMString + if let Some(value) = value.to_string(scope) { let state = state.borrow_mut::(); if !state.enable_window_features { return Err(GeometryError::DisallowWindowFeatures); } - - // TODO(petamoriken): parse CSS - unimplemented!() + let matrix = DOMMatrixReadOnly::identity(); + matrix.set_matrix_value(&value.to_rust_string_lossy(scope))?; + return Ok(matrix); } + // sequence let seq = Vec::::convert(scope, value, prefix, context, &Default::default())?; if let [a, b, c, d, e, f] = seq.as_slice() { @@ -1047,7 +1067,6 @@ impl DOMMatrixReadOnly { let scaling = Vector3::new(sx, sy, sz); inner.prepend_nonuniform_scaling_mut(&scaling); self.is_2d.set(is_2d && sz == 1.0); - println!("{:?}", self); } #[inline] @@ -1072,21 +1091,17 @@ impl DOMMatrixReadOnly { } #[inline] - fn rotate_self_inner(&self, roll_deg: f64, pitch_deg: f64, yaw_deg: f64) { + fn rotate_self_inner(&self, roll: f64, pitch: f64, yaw: f64) { let mut inner = self.inner.borrow_mut(); let is_2d = self.is_2d.get(); - let rotation = Rotation3::from_euler_angles( - roll_deg.to_radians(), - pitch_deg.to_radians(), - yaw_deg.to_radians(), - ) - .to_homogeneous(); + let rotation = + Rotation3::from_euler_angles(roll, pitch, yaw).to_homogeneous(); let mut result = Matrix4x3::zeros(); inner.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); inner.set_column(0, &result.column(0)); inner.set_column(1, &result.column(1)); inner.set_column(2, &result.column(2)); - self.is_2d.set(is_2d && roll_deg == 0.0 && pitch_deg == 0.0); + self.is_2d.set(is_2d && roll == 0.0 && pitch == 0.0); } #[inline] @@ -1105,13 +1120,7 @@ impl DOMMatrixReadOnly { } #[inline] - fn rotate_axis_angle_self_inner( - &self, - x: f64, - y: f64, - z: f64, - angle_deg: f64, - ) { + fn rotate_axis_angle_self_inner(&self, x: f64, y: f64, z: f64, angle: f64) { if x == 0.0 && y == 0.0 && z == 0.0 { return; } @@ -1119,7 +1128,7 @@ impl DOMMatrixReadOnly { let is_2d = self.is_2d.get(); let rotation = Rotation3::from_axis_angle( &UnitVector3::new_normalize(Vector3::new(x, y, z)), - angle_deg.to_radians(), + angle, ) .to_homogeneous(); let mut result = Matrix4x3::zeros(); @@ -1131,18 +1140,9 @@ impl DOMMatrixReadOnly { } #[inline] - fn skew_x_self_inner(&self, x_deg: f64) { + fn skew_x_self_inner(&self, x: f64) { let mut inner = self.inner.borrow_mut(); - let skew = Matrix4x2::new( - 1.0, - x_deg.to_radians().tan(), - 0.0, - 1.0, - 0.0, - 0.0, - 0.0, - 0.0, - ); + let skew = Matrix4x2::new(1.0, x.tan(), 0.0, 1.0, 0.0, 0.0, 0.0, 0.0); let mut result = Matrix4x2::zeros(); inner.mul_to(&skew, &mut result); inner.set_column(0, &result.column(0)); @@ -1150,24 +1150,40 @@ impl DOMMatrixReadOnly { } #[inline] - fn skew_y_self_inner(&self, y_deg: f64) { + fn skew_y_self_inner(&self, y: f64) { let mut inner = self.inner.borrow_mut(); - let skew = Matrix4x2::new( - 1.0, - 0.0, - y_deg.to_radians().tan(), - 1.0, - 0.0, - 0.0, - 0.0, - 0.0, - ); + let skew = Matrix4x2::new(1.0, 0.0, y.tan(), 1.0, 0.0, 0.0, 0.0, 0.0); + let mut result = Matrix4x2::zeros(); + inner.mul_to(&skew, &mut result); + inner.set_column(0, &result.column(0)); + inner.set_column(1, &result.column(1)); + } + + #[inline] + fn skew_self_inner(&self, x: f64, y: f64) { + let mut inner = self.inner.borrow_mut(); + let skew = Matrix4x2::new(1.0, x.tan(), y.tan(), 1.0, 0.0, 0.0, 0.0, 0.0); let mut result = Matrix4x2::zeros(); inner.mul_to(&skew, &mut result); inner.set_column(0, &result.column(0)); inner.set_column(1, &result.column(1)); } + #[inline] + fn perspective_self(&self, d: f64) { + if d == 0.0 { + return; + } + let mut inner = self.inner.borrow_mut(); + let perspective = + Matrix4x2::new(0.0, 0.0, 1.0, -1.0 / d, 0.0, 0.0, 0.0, 1.0); + let mut result = Matrix4x2::zeros(); + inner.mul_to(&perspective, &mut result); + inner.set_column(2, &result.column(0)); + inner.set_column(3, &result.column(1)); + self.is_2d.set(false); + } + #[inline] fn multiply_self_inner( &self, @@ -1402,6 +1418,179 @@ impl DOMMatrixReadOnly { .into_iter() .all(|&item| item.is_finite()) } + + fn set_matrix_value(&self, input: &str) -> Result<(), GeometryError> { + let Ok(transform_list) = TransformList::parse_string(input) else { + return Err(GeometryError::FailedToParse); + }; + for transform in transform_list.0 { + match transform { + Transform::Translate( + LengthPercentage::Dimension(x), + LengthPercentage::Dimension(y), + ) => { + if let (Some(x), Some(y)) = (x.to_px(), y.to_px()) { + self.translate_self_inner(x.into(), y.into(), 0.0); + } else { + return Err(GeometryError::ContainsRelativeValue); + } + } + Transform::TranslateX(LengthPercentage::Dimension(x)) => { + if let Some(x) = x.to_px() { + self.translate_self_inner(x.into(), 0.0, 0.0); + } else { + return Err(GeometryError::ContainsRelativeValue); + } + } + Transform::TranslateY(LengthPercentage::Dimension(y)) => { + if let Some(y) = y.to_px() { + self.translate_self_inner(0.0, y.into(), 0.0); + } else { + return Err(GeometryError::ContainsRelativeValue); + } + } + Transform::TranslateZ(z) => { + if let Some(z) = z.to_px() { + self.translate_self_inner(0.0, 0.0, z.into()); + } else { + return Err(GeometryError::ContainsRelativeValue); + } + } + Transform::Translate3d( + LengthPercentage::Dimension(x), + LengthPercentage::Dimension(y), + z, + ) => { + if let (Some(x), Some(y), Some(z)) = (x.to_px(), y.to_px(), z.to_px()) + { + self.translate_self_inner(x.into(), y.into(), z.into()); + } else { + return Err(GeometryError::ContainsRelativeValue); + } + } + Transform::Scale(x, y) => { + let x: CSSNumber = (&x).into(); + let y: CSSNumber = (&y).into(); + self.scale_without_origin_self_inner(x.into(), y.into(), 1.0); + } + Transform::ScaleX(x) => { + let x: CSSNumber = (&x).into(); + self.scale_without_origin_self_inner(x.into(), 1.0, 1.0); + } + Transform::ScaleY(y) => { + let y: CSSNumber = (&y).into(); + self.scale_without_origin_self_inner(1.0, y.into(), 1.0); + } + Transform::ScaleZ(z) => { + let z: CSSNumber = (&z).into(); + self.scale_without_origin_self_inner(1.0, 1.0, z.into()); + } + Transform::Scale3d(x, y, z) => { + let x: CSSNumber = (&x).into(); + let y: CSSNumber = (&y).into(); + let z: CSSNumber = (&z).into(); + self.scale_without_origin_self_inner(x.into(), y.into(), z.into()); + } + Transform::Rotate(angle) | Transform::RotateZ(angle) => { + self.rotate_axis_angle_self_inner( + 0.0, + 0.0, + 1.0, + angle.to_radians().into(), + ); + } + Transform::RotateX(angle) => { + self.rotate_axis_angle_self_inner( + 1.0, + 0.0, + 0.0, + angle.to_radians().into(), + ); + } + Transform::RotateY(angle) => { + self.rotate_axis_angle_self_inner( + 0.0, + 0.0, + 1.0, + angle.to_radians().into(), + ); + } + Transform::Rotate3d(x, y, z, angle) => { + self.rotate_axis_angle_self_inner( + x.into(), + y.into(), + z.into(), + angle.to_radians().into(), + ); + } + Transform::Skew(x, y) => { + self.skew_self_inner(x.to_radians().into(), y.to_radians().into()); + } + Transform::SkewX(angle) => { + self.skew_x_self_inner(angle.to_radians().into()); + } + Transform::SkewY(angle) => { + self.skew_y_self_inner(angle.to_radians().into()); + } + Transform::Perspective(length) => { + if let Some(length) = length.to_px() { + self.perspective_self(length.into()); + } else { + return Err(GeometryError::ContainsRelativeValue); + } + } + Transform::Matrix(CSSMatrix { a, b, c, d, e, f }) => { + let lhs = self.clone(); + let rhs = DOMMatrixReadOnly { + #[rustfmt::skip] + inner: RefCell::new(Matrix4::new( + a.into(), c.into(), 0.0, e.into(), + b.into(), d.into(), 0.0, f.into(), + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, + )), + is_2d: Cell::new(true), + }; + self.multiply_self_inner(&lhs, &rhs); + } + Transform::Matrix3d(CSSMatrix3d { + m11, + m12, + m13, + m14, + m21, + m22, + m23, + m24, + m31, + m32, + m33, + m34, + m41, + m42, + m43, + m44, + }) => { + let lhs = self.clone(); + let rhs = DOMMatrixReadOnly { + #[rustfmt::skip] + inner: RefCell::new(Matrix4::new( + m11.into(), m21.into(), m31.into(), m41.into(), + m12.into(), m22.into(), m32.into(), m42.into(), + m13.into(), m23.into(), m33.into(), m43.into(), + m14.into(), m24.into(), m34.into(), m44.into(), + )), + is_2d: Cell::new(false), + }; + self.multiply_self_inner(&lhs, &rhs); + } + _ => { + return Err(GeometryError::ContainsRelativeValue); + } + } + } + Ok(()) + } } #[op2(base)] @@ -1754,7 +1943,11 @@ impl DOMMatrixReadOnly { ) }; let out = self.clone(); - out.rotate_self_inner(roll_deg, pitch_deg, yaw_deg); + out.rotate_self_inner( + roll_deg.to_radians(), + pitch_deg.to_radians(), + yaw_deg.to_radians(), + ); out } @@ -1786,7 +1979,7 @@ impl DOMMatrixReadOnly { let z = *z.unwrap_or(webidl::UnrestrictedDouble(0.0)); let angle_deg = *angle_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); let out = self.clone(); - out.rotate_axis_angle_self_inner(x, y, z, angle_deg); + out.rotate_axis_angle_self_inner(x, y, z, angle_deg.to_radians()); out } @@ -1798,7 +1991,7 @@ impl DOMMatrixReadOnly { ) -> DOMMatrixReadOnly { let x_deg = *x_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); let out = self.clone(); - out.skew_x_self_inner(x_deg); + out.skew_x_self_inner(x_deg.to_radians()); out } @@ -1810,7 +2003,7 @@ impl DOMMatrixReadOnly { ) -> DOMMatrixReadOnly { let y_deg = *y_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); let out = self.clone(); - out.skew_y_self_inner(y_deg); + out.skew_y_self_inner(y_deg.to_radians()); out } @@ -2567,7 +2760,11 @@ impl DOMMatrix { *rotate_z.unwrap_or(webidl::UnrestrictedDouble(0.0)), ) }; - ro.rotate_self_inner(roll_deg, pitch_deg, yaw_deg); + ro.rotate_self_inner( + roll_deg.to_radians(), + pitch_deg.to_radians(), + yaw_deg.to_radians(), + ); } // TODO(petamoriken): returns self @@ -2595,7 +2792,7 @@ impl DOMMatrix { let y = *y.unwrap_or(webidl::UnrestrictedDouble(0.0)); let z = *z.unwrap_or(webidl::UnrestrictedDouble(0.0)); let angle_deg = *angle_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); - ro.rotate_axis_angle_self_inner(x, y, z, angle_deg); + ro.rotate_axis_angle_self_inner(x, y, z, angle_deg.to_radians()); } // TODO(petamoriken): returns self @@ -2605,7 +2802,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { let x_deg = *x_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); - ro.skew_x_self_inner(x_deg); + ro.skew_x_self_inner(x_deg.to_radians()); } // TODO(petamoriken): returns self @@ -2615,7 +2812,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { let y_deg = *y_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); - ro.skew_y_self_inner(y_deg); + ro.skew_y_self_inner(y_deg.to_radians()); } // TODO(petamoriken): Maybe proc-macro bug @@ -2746,19 +2943,23 @@ fn matrix_transform_point( pub fn op_geometry_matrix_to_buffer<'a>( scope: &mut v8::HandleScope<'a>, matrix: v8::Local<'a, v8::Value>, -) -> Vec { - let matrix = +) -> Result, GeometryError> { + let Some(matrix) = cppgc::try_unwrap_cppgc_proto_object::(scope, matrix) - .unwrap(); + else { + return Err(GeometryError::IllegalInvocation); + }; let inner = matrix.inner.borrow(); // SAFETY: in-range access - unsafe { - slice::from_raw_parts( - inner.as_slice().as_ptr() as *mut u8, - mem::size_of::() * 16, - ) - } - .to_vec() + Ok( + unsafe { + slice::from_raw_parts( + inner.as_slice().as_ptr() as *mut u8, + mem::size_of::() * 16, + ) + } + .to_vec(), + ) } #[op2] @@ -2767,9 +2968,11 @@ pub fn op_geometry_matrix_to_string<'a>( scope: &mut v8::HandleScope<'a>, matrix: v8::Local<'a, v8::Value>, ) -> Result { - let matrix = + let Some(matrix) = cppgc::try_unwrap_cppgc_proto_object::(scope, matrix) - .unwrap(); + else { + return Err(GeometryError::IllegalInvocation); + }; if !matrix.is_finite_inner() { return Err(GeometryError::InvalidState); } @@ -2797,13 +3000,18 @@ pub fn op_geometry_matrix_to_string<'a>( } } -// TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) -#[op2] -#[cppgc] -pub fn op_geometry_parse_transform_list( +#[op2(fast)] +pub fn op_geometry_set_matrix_value<'a>( + scope: &mut v8::HandleScope<'a>, + matrix: v8::Local<'a, v8::Value>, #[string] transform_list: &str, -) -> DOMMatrixReadOnly { - unimplemented!() +) -> Result<(), GeometryError> { + let Some(matrix) = + cppgc::try_unwrap_cppgc_proto_object::(scope, matrix) + else { + return Err(GeometryError::IllegalInvocation); + }; + matrix.set_matrix_value(transform_list) } #[op2(fast)] diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index 3d24f91ee5b95e..95ba3ecc123ef4 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -390,6 +390,12 @@ core.registerErrorBuilder( return new DOMException(msg, "InvalidStateError"); }, ); +core.registerErrorBuilder( + "DOMExceptionSyntaxError", + function DOMExceptionSyntaxError(msg) { + return new DOMException(msg, "SyntaxError"); + }, +); function runtimeStart( denoVersion, From 2e1a39b6bdd1f03f7a23eee05681db7bcda9844b Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 29 Apr 2025 01:54:51 +0900 Subject: [PATCH 29/63] fix --- ext/geometry/lib.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 772f1f6be48486..555e5abf310565 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -3000,18 +3000,20 @@ pub fn op_geometry_matrix_to_string<'a>( } } -#[op2(fast)] +#[op2] pub fn op_geometry_set_matrix_value<'a>( scope: &mut v8::HandleScope<'a>, - matrix: v8::Local<'a, v8::Value>, + input: v8::Local<'a, v8::Value>, #[string] transform_list: &str, -) -> Result<(), GeometryError> { - let Some(matrix) = - cppgc::try_unwrap_cppgc_proto_object::(scope, matrix) - else { +) -> Result, GeometryError> { + if cppgc::try_unwrap_cppgc_proto_object::(scope, input).is_none() { return Err(GeometryError::IllegalInvocation); - }; - matrix.set_matrix_value(transform_list) + } + let matrix = + cppgc::try_unwrap_cppgc_proto_object::(scope, input) + .unwrap(); + matrix.set_matrix_value(transform_list)?; + Ok(input) } #[op2(fast)] From 10b41eed94233d40165c448fed9d321375efe9b0 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 29 Apr 2025 02:25:36 +0900 Subject: [PATCH 30/63] wip --- ext/geometry/lib.rs | 72 +++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 555e5abf310565..4b427ad3b72cb0 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -155,7 +155,7 @@ impl DOMPointReadOnly { #[reentrant] #[static_method] #[cppgc] - pub fn from_point<'a>(#[webidl] init: DOMPointInit) -> DOMPointReadOnly { + pub fn from_point(#[webidl] init: DOMPointInit) -> DOMPointReadOnly { DOMPointReadOnly::from_point_inner(init) } @@ -209,7 +209,7 @@ impl DOMPointReadOnly { // TODO(petamoriken): returns (DOMPointReadOnly, DOMPoint) #[cppgc] - pub fn matrix_transform<'a>( + pub fn matrix_transform( &self, #[webidl] value: DOMMatrixInit, ) -> Result { @@ -251,7 +251,7 @@ impl DOMPoint { #[reentrant] #[static_method] #[cppgc] - pub fn from_point<'a>(#[webidl] init: DOMPointInit) -> DOMPointReadOnly { + pub fn from_point(#[webidl] init: DOMPointInit) -> DOMPointReadOnly { let ro = DOMPointReadOnly::from_point_inner(init); ro } @@ -396,7 +396,7 @@ impl DOMRectReadOnly { #[reentrant] #[static_method] #[cppgc] - pub fn from_rect<'a>(#[webidl] init: DOMRectInit) -> DOMRectReadOnly { + pub fn from_rect(#[webidl] init: DOMRectInit) -> DOMRectReadOnly { DOMRectReadOnly::from_rect_inner(init) } @@ -524,7 +524,7 @@ impl DOMRect { #[reentrant] #[static_method] #[cppgc] - pub fn from_rect<'a>(#[webidl] init: DOMRectInit) -> DOMRectReadOnly { + pub fn from_rect(#[webidl] init: DOMRectInit) -> DOMRectReadOnly { let ro = DOMRectReadOnly::from_rect_inner(init); ro } @@ -958,7 +958,7 @@ impl DOMMatrixReadOnly { } } - fn from_matrix_inner<'a>( + fn from_matrix_inner( init: DOMMatrixInit, ) -> Result { macro_rules! fixup { @@ -1509,9 +1509,9 @@ impl DOMMatrixReadOnly { } Transform::RotateY(angle) => { self.rotate_axis_angle_self_inner( - 0.0, 0.0, 1.0, + 0.0, angle.to_radians().into(), ); } @@ -2681,23 +2681,26 @@ impl DOMMatrix { } } - // TODO(petamoriken): returns self + #[global] pub fn translate_self( &self, + #[this] this: v8::Global, #[webidl] tx: Option, #[webidl] ty: Option, #[webidl] tz: Option, #[proto] ro: &DOMMatrixReadOnly, - ) { + ) -> v8::Global { let tx = *tx.unwrap_or(webidl::UnrestrictedDouble(0.0)); let ty = *ty.unwrap_or(webidl::UnrestrictedDouble(0.0)); let tz = *tz.unwrap_or(webidl::UnrestrictedDouble(0.0)); ro.translate_self_inner(tx, ty, tz); + this } - // TODO(petamoriken): returns self + #[global] pub fn scale_self( &self, + #[this] this: v8::Global, #[webidl] sx: Option, #[webidl] sy: Option, #[webidl] sz: Option, @@ -2705,7 +2708,7 @@ impl DOMMatrix { #[webidl] origin_y: Option, #[webidl] origin_z: Option, #[proto] ro: &DOMMatrixReadOnly, - ) { + ) -> v8::Global { let sx = *sx.unwrap_or(webidl::UnrestrictedDouble(1.0)); let sy = *sy.unwrap_or(webidl::UnrestrictedDouble(sx)); let sz = *sz.unwrap_or(webidl::UnrestrictedDouble(1.0)); @@ -2717,17 +2720,19 @@ impl DOMMatrix { } else { ro.scale_with_origin_self_inner(sx, sy, sz, origin_x, origin_y, origin_z); } + this } - // TODO(petamoriken): returns self + #[global] pub fn scale3d_self( &self, + #[this] this: v8::Global, #[webidl] scale: Option, #[webidl] origin_x: Option, #[webidl] origin_y: Option, #[webidl] origin_z: Option, #[proto] ro: &DOMMatrixReadOnly, - ) { + ) -> v8::Global { let scale = *scale.unwrap_or(webidl::UnrestrictedDouble(1.0)); let origin_x = *origin_x.unwrap_or(webidl::UnrestrictedDouble(0.0)); let origin_y = *origin_y.unwrap_or(webidl::UnrestrictedDouble(0.0)); @@ -2739,16 +2744,18 @@ impl DOMMatrix { scale, scale, scale, origin_x, origin_y, origin_z, ); } + this } - // TODO(petamoriken): returns self + #[global] pub fn rotate_self( &self, + #[this] this: v8::Global, #[webidl] rotate_x: Option, #[webidl] rotate_y: Option, #[webidl] rotate_z: Option, #[proto] ro: &DOMMatrixReadOnly, - ) { + ) -> v8::Global { let rotate_x = *rotate_x.unwrap_or(webidl::UnrestrictedDouble(0.0)); let (roll_deg, pitch_deg, yaw_deg) = if rotate_y.is_none() && rotate_z.is_none() { @@ -2765,54 +2772,63 @@ impl DOMMatrix { pitch_deg.to_radians(), yaw_deg.to_radians(), ); + this } - // TODO(petamoriken): returns self + #[global] pub fn rotate_from_vector_self( &self, + #[this] this: v8::Global, #[webidl] x: Option, #[webidl] y: Option, #[proto] ro: &DOMMatrixReadOnly, - ) { + ) -> v8::Global { let x = *x.unwrap_or(webidl::UnrestrictedDouble(0.0)); let y = *y.unwrap_or(webidl::UnrestrictedDouble(0.0)); ro.rotate_from_vector_self_inner(x, y); + this } - // TODO(petamoriken): returns self + #[global] pub fn rotate_axis_angle_self( &self, + #[this] this: v8::Global, #[webidl] x: Option, #[webidl] y: Option, #[webidl] z: Option, #[webidl] angle_deg: Option, #[proto] ro: &DOMMatrixReadOnly, - ) { + ) -> v8::Global { let x = *x.unwrap_or(webidl::UnrestrictedDouble(0.0)); let y = *y.unwrap_or(webidl::UnrestrictedDouble(0.0)); let z = *z.unwrap_or(webidl::UnrestrictedDouble(0.0)); let angle_deg = *angle_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); ro.rotate_axis_angle_self_inner(x, y, z, angle_deg.to_radians()); + this } - // TODO(petamoriken): returns self + #[global] pub fn skew_x_self( &self, + #[this] this: v8::Global, #[webidl] x_deg: Option, #[proto] ro: &DOMMatrixReadOnly, - ) { + ) -> v8::Global { let x_deg = *x_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); ro.skew_x_self_inner(x_deg.to_radians()); + this } - // TODO(petamoriken): returns self + #[global] pub fn skew_y_self( &self, + #[this] this: v8::Global, #[webidl] y_deg: Option, #[proto] ro: &DOMMatrixReadOnly, - ) { + ) -> v8::Global { let y_deg = *y_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); ro.skew_y_self_inner(y_deg.to_radians()); + this } // TODO(petamoriken): Maybe proc-macro bug @@ -2882,10 +2898,14 @@ impl DOMMatrix { // Ok(()) // } - // TODO(petamoriken): returns self - #[fast] - pub fn invert_self(&self, #[proto] ro: &DOMMatrixReadOnly) { + #[global] + pub fn invert_self( + &self, + #[this] this: v8::Global, + #[proto] ro: &DOMMatrixReadOnly, + ) -> v8::Global { ro.invert_self_inner(); + this } } From 41f82411e7212c0de67ff0a05439394f97118fd5 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 29 Apr 2025 02:33:25 +0900 Subject: [PATCH 31/63] wip --- ext/geometry/01_geometry.js | 4 +- ext/geometry/README.md | 2 +- ext/geometry/lib.rs | 150 ++++++++++++++++++------------------ 3 files changed, 79 insertions(+), 77 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 2a00381da8db4c..f81acce03cd102 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -10,9 +10,9 @@ import { DOMRect, DOMRectReadOnly, op_geometry_get_enable_window_features, + op_geometry_matrix_set_matrix_value, op_geometry_matrix_to_buffer, op_geometry_matrix_to_string, - op_geometry_set_matrix_value, } from "ext:core/ops"; const { ArrayPrototypeJoin, @@ -188,7 +188,7 @@ if (op_geometry_get_enable_window_features()) { ObjectDefineProperty(DOMMatrixPrototype, "setMatrixValue", { __proto__: null, value: function setMatrixValue(transformList) { - op_geometry_set_matrix_value(this, transformList); + op_geometry_matrix_set_matrix_value(this, transformList); }, writable: true, enumerable: true, diff --git a/ext/geometry/README.md b/ext/geometry/README.md index 2337878f5d3e0e..f5011bbefcb6f3 100644 --- a/ext/geometry/README.md +++ b/ext/geometry/README.md @@ -71,6 +71,6 @@ Following ops are provided, which can be accessed through `Deno.ops`: - DOMMatrixReadOnly - DOMMatrix - op_geometry_get_enable_window_features +- op_geometry_matrix_set_matrix_value - op_geometry_matrix_to_buffer - op_geometry_matrix_to_string -- op_geometry_set_matrix_value diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 4b427ad3b72cb0..ba0694508f7b8d 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -38,9 +38,9 @@ deno_core::extension!( deps = [deno_webidl, deno_web, deno_console], ops = [ op_geometry_get_enable_window_features, + op_geometry_matrix_set_matrix_value, op_geometry_matrix_to_buffer, op_geometry_matrix_to_string, - op_geometry_set_matrix_value, ], objects = [ DOMPointReadOnly, @@ -747,6 +747,7 @@ impl DOMQuad { self.p4.get(scope, |_| unreachable!()) } + // TODO(petamoriken): returns (DOMRectReadOnly, DOMRect) #[cppgc] pub fn get_bounds(&self, scope: &mut v8::HandleScope) -> DOMRectReadOnly { #[inline] @@ -772,12 +773,13 @@ impl DOMQuad { let top = minimum(minimum(p1.y, p2.y), minimum(p3.y, p4.y)); let right = maximum(maximum(p1.x, p2.x), maximum(p3.x, p4.x)); let bottom = maximum(maximum(p1.y, p2.y), maximum(p3.y, p4.y)); - DOMRectReadOnly { + let ro = DOMRectReadOnly { x: Cell::new(left), y: Cell::new(top), width: Cell::new(right - left), height: Cell::new(bottom - top), - } + }; + ro } #[rename("toJSON")] @@ -924,13 +926,14 @@ impl DOMMatrixReadOnly { } // DOMString - if let Some(value) = value.to_string(scope) { + if value.is_string() { let state = state.borrow_mut::(); if !state.enable_window_features { return Err(GeometryError::DisallowWindowFeatures); } + let value = value.to_string(scope).unwrap(); let matrix = DOMMatrixReadOnly::identity(); - matrix.set_matrix_value(&value.to_rust_string_lossy(scope))?; + matrix.set_matrix_value_inner(&value.to_rust_string_lossy(scope))?; return Ok(matrix); } @@ -1044,6 +1047,7 @@ impl DOMMatrixReadOnly { } } + #[inline] fn identity() -> DOMMatrixReadOnly { DOMMatrixReadOnly { inner: RefCell::new(Matrix4::identity()), @@ -1419,7 +1423,7 @@ impl DOMMatrixReadOnly { .all(|&item| item.is_finite()) } - fn set_matrix_value(&self, input: &str) -> Result<(), GeometryError> { + fn set_matrix_value_inner(&self, input: &str) -> Result<(), GeometryError> { let Ok(transform_list) = TransformList::parse_string(input) else { return Err(GeometryError::FailedToParse); }; @@ -2831,72 +2835,69 @@ impl DOMMatrix { this } - // TODO(petamoriken): Maybe proc-macro bug - // mismatched types - // expected mutable reference `&mut HandleScope<'_>` - // found mutable reference `&mut &mut Isolate - - // #[fast] - // pub fn multiply_self<'a>( - // &self, - // scope: &mut v8::HandleScope<'a>, - // other: v8::Local<'a, v8::Value>, - // #[proto] ro: &DOMMatrixReadOnly, - // ) -> Result<(), GeometryError> { - // let result = DOMMatrixReadOnly { - // inner: RefCell::new(Matrix4::zeros()), - // is_2d: Cell::new(true), - // }; - // if let Some(other) = - // cppgc::try_unwrap_cppgc_object::(scope, other) - // { - // result.multiply_self_inner(ro, &other); - // } else { - // let other = DOMMatrixInit::convert( - // scope, - // other, - // "Failed to execute 'multiply' on 'DOMMatrixReadOnly'".into(), - // (|| Cow::Borrowed("Argument 1")).into(), - // &Default::default(), - // )?; - // let other = DOMMatrixReadOnly::from_matrix_inner(other)?; - // result.multiply_self_inner(ro, &other); - // } - // ro.inner.borrow_mut().copy_from(&result.inner.borrow()); - // ro.is_2d.set(result.is_2d.get()); - // Ok(()) - // } - - // #[fast] - // pub fn pre_multiply_self<'a>( - // &self, - // scope: &mut v8::HandleScope<'a>, - // other: v8::Local<'a, v8::Value>, - // #[proto] ro: &DOMMatrixReadOnly, - // ) -> Result<(), GeometryError> { - // let result = DOMMatrixReadOnly { - // inner: RefCell::new(Matrix4::zeros()), - // is_2d: Cell::new(true), - // }; - // if let Some(other) = - // cppgc::try_unwrap_cppgc_object::(scope, other) - // { - // result.multiply_self_inner(&other, ro); - // } else { - // let other = DOMMatrixInit::convert( - // scope, - // other, - // "Failed to execute 'multiply' on 'DOMMatrixReadOnly'".into(), - // (|| Cow::Borrowed("Argument 1")).into(), - // &Default::default(), - // )?; - // let other = DOMMatrixReadOnly::from_matrix_inner(other)?; - // result.multiply_self_inner(&other, ro); - // } - // ro.inner.borrow_mut().copy_from(&result.inner.borrow()); - // ro.is_2d.set(result.is_2d.get()); - // Ok(()) - // } + #[global] + pub fn multiply_self<'a>( + &self, + #[this] this: v8::Global, + scope: &mut v8::HandleScope<'a>, + other: v8::Local<'a, v8::Value>, + #[proto] ro: &DOMMatrixReadOnly, + ) -> Result, GeometryError> { + let result = DOMMatrixReadOnly { + inner: RefCell::new(Matrix4::zeros()), + is_2d: Cell::new(true), + }; + if let Some(other) = + cppgc::try_unwrap_cppgc_object::(scope, other) + { + result.multiply_self_inner(ro, &other); + } else { + let other = DOMMatrixInit::convert( + scope, + other, + "Failed to execute 'multiply' on 'DOMMatrixReadOnly'".into(), + (|| Cow::Borrowed("Argument 1")).into(), + &Default::default(), + )?; + let other = DOMMatrixReadOnly::from_matrix_inner(other)?; + result.multiply_self_inner(ro, &other); + } + ro.inner.borrow_mut().copy_from(&result.inner.borrow()); + ro.is_2d.set(result.is_2d.get()); + Ok(this) + } + + #[global] + pub fn pre_multiply_self<'a>( + &self, + #[this] this: v8::Global, + scope: &mut v8::HandleScope<'a>, + other: v8::Local<'a, v8::Value>, + #[proto] ro: &DOMMatrixReadOnly, + ) -> Result, GeometryError> { + let result = DOMMatrixReadOnly { + inner: RefCell::new(Matrix4::zeros()), + is_2d: Cell::new(true), + }; + if let Some(other) = + cppgc::try_unwrap_cppgc_object::(scope, other) + { + result.multiply_self_inner(&other, ro); + } else { + let other = DOMMatrixInit::convert( + scope, + other, + "Failed to execute 'multiply' on 'DOMMatrixReadOnly'".into(), + (|| Cow::Borrowed("Argument 1")).into(), + &Default::default(), + )?; + let other = DOMMatrixReadOnly::from_matrix_inner(other)?; + result.multiply_self_inner(&other, ro); + } + ro.inner.borrow_mut().copy_from(&result.inner.borrow()); + ro.is_2d.set(result.is_2d.get()); + Ok(this) + } #[global] pub fn invert_self( @@ -2947,6 +2948,7 @@ fn minimum(a: f64, b: f64) -> f64 { } } +#[inline] fn matrix_transform_point( matrix: &DOMMatrixReadOnly, point: &DOMPointReadOnly, @@ -3021,7 +3023,7 @@ pub fn op_geometry_matrix_to_string<'a>( } #[op2] -pub fn op_geometry_set_matrix_value<'a>( +pub fn op_geometry_matrix_set_matrix_value<'a>( scope: &mut v8::HandleScope<'a>, input: v8::Local<'a, v8::Value>, #[string] transform_list: &str, @@ -3032,7 +3034,7 @@ pub fn op_geometry_set_matrix_value<'a>( let matrix = cppgc::try_unwrap_cppgc_proto_object::(scope, input) .unwrap(); - matrix.set_matrix_value(transform_list)?; + matrix.set_matrix_value_inner(transform_list)?; Ok(input) } From 66210f42ff927620a501dfdaccfb47d7edeb78c6 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 29 Apr 2025 16:44:42 +0900 Subject: [PATCH 32/63] refactor --- ext/geometry/lib.rs | 113 ++++++++++++++------------------------------ 1 file changed, 36 insertions(+), 77 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index ba0694508f7b8d..c374e51efe7481 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -787,6 +787,7 @@ impl DOMQuad { &self, scope: &mut v8::HandleScope<'a>, ) -> v8::Local<'a, v8::Object> { + #[inline] fn set( scope: &mut v8::HandleScope, object: &mut v8::Local, @@ -940,25 +941,7 @@ impl DOMMatrixReadOnly { // sequence let seq = Vec::::convert(scope, value, prefix, context, &Default::default())?; - if let [a, b, c, d, e, f] = seq.as_slice() { - return Ok(DOMMatrixReadOnly { - #[rustfmt::skip] - inner: RefCell::new(Matrix4::new( - *a, *c, 0.0, *e, - *b, *d, 0.0, *f, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0, - )), - is_2d: Cell::new(true), - }); - } else if seq.len() == 16 { - return Ok(DOMMatrixReadOnly { - inner: RefCell::new(Matrix4::from_column_slice(seq.as_slice())), - is_2d: Cell::new(false), - }); - } else { - Err(GeometryError::InvalidSequenceSize) - } + DOMMatrixReadOnly::from_sequence_inner(seq) } fn from_matrix_inner( @@ -1047,6 +1030,30 @@ impl DOMMatrixReadOnly { } } + fn from_sequence_inner( + seq: Vec, + ) -> Result { + if let [a, b, c, d, e, f] = seq.as_slice() { + return Ok(DOMMatrixReadOnly { + #[rustfmt::skip] + inner: RefCell::new(Matrix4::new( + *a, *c, 0.0, *e, + *b, *d, 0.0, *f, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, + )), + is_2d: Cell::new(true), + }); + } else if seq.len() == 16 { + return Ok(DOMMatrixReadOnly { + inner: RefCell::new(Matrix4::from_column_slice(seq.as_slice())), + is_2d: Cell::new(false), + }); + } else { + Err(GeometryError::InvalidSequenceSize) + } + } + #[inline] fn identity() -> DOMMatrixReadOnly { DOMMatrixReadOnly { @@ -1634,33 +1641,14 @@ impl DOMMatrixReadOnly { if !value.is_float32_array() { return Err(GeometryError::TypeMismatch); } - let float64 = Vec::::convert( + let seq = Vec::::convert( scope, value, "Failed to execute 'DOMMatrixReadOnly.fromFloat32Array'".into(), (|| Cow::Borrowed("Argument 1")).into(), &Default::default(), )?; - - if let [a, b, c, d, e, f] = float64.as_slice() { - return Ok(DOMMatrixReadOnly { - #[rustfmt::skip] - inner: RefCell::new(Matrix4::new( - *a, *c, 0.0, *e, - *b, *d, 0.0, *f, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0, - )), - is_2d: Cell::new(true), - }); - } else if float64.len() == 16 { - return Ok(DOMMatrixReadOnly { - inner: RefCell::new(Matrix4::from_column_slice(float64.as_slice())), - is_2d: Cell::new(false), - }); - } else { - Err(GeometryError::InvalidSequenceSize) - } + DOMMatrixReadOnly::from_sequence_inner(seq) } #[rename("fromFloat64Array")] @@ -1673,33 +1661,14 @@ impl DOMMatrixReadOnly { if !value.is_float64_array() { return Err(GeometryError::TypeMismatch); } - let float64 = Vec::::convert( + let seq = Vec::::convert( scope, value, "Failed to execute 'DOMMatrixReadOnly.fromFloat64Array'".into(), (|| Cow::Borrowed("Argument 1")).into(), &Default::default(), )?; - - if let [a, b, c, d, e, f] = float64.as_slice() { - return Ok(DOMMatrixReadOnly { - #[rustfmt::skip] - inner: RefCell::new(Matrix4::new( - *a, *c, 0.0, *e, - *b, *d, 0.0, *f, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0, - )), - is_2d: Cell::new(true), - }); - } else if float64.len() == 16 { - return Ok(DOMMatrixReadOnly { - inner: RefCell::new(Matrix4::from_column_slice(float64.as_slice())), - is_2d: Cell::new(false), - }); - } else { - Err(GeometryError::InvalidSequenceSize) - } + DOMMatrixReadOnly::from_sequence_inner(seq) } #[fast] @@ -2843,14 +2812,11 @@ impl DOMMatrix { other: v8::Local<'a, v8::Value>, #[proto] ro: &DOMMatrixReadOnly, ) -> Result, GeometryError> { - let result = DOMMatrixReadOnly { - inner: RefCell::new(Matrix4::zeros()), - is_2d: Cell::new(true), - }; + let lhs = ro.clone(); if let Some(other) = cppgc::try_unwrap_cppgc_object::(scope, other) { - result.multiply_self_inner(ro, &other); + ro.multiply_self_inner(&lhs, &other); } else { let other = DOMMatrixInit::convert( scope, @@ -2860,10 +2826,8 @@ impl DOMMatrix { &Default::default(), )?; let other = DOMMatrixReadOnly::from_matrix_inner(other)?; - result.multiply_self_inner(ro, &other); + ro.multiply_self_inner(&lhs, &other); } - ro.inner.borrow_mut().copy_from(&result.inner.borrow()); - ro.is_2d.set(result.is_2d.get()); Ok(this) } @@ -2875,14 +2839,11 @@ impl DOMMatrix { other: v8::Local<'a, v8::Value>, #[proto] ro: &DOMMatrixReadOnly, ) -> Result, GeometryError> { - let result = DOMMatrixReadOnly { - inner: RefCell::new(Matrix4::zeros()), - is_2d: Cell::new(true), - }; + let rhs = ro.clone(); if let Some(other) = cppgc::try_unwrap_cppgc_object::(scope, other) { - result.multiply_self_inner(&other, ro); + ro.multiply_self_inner(&other, &rhs); } else { let other = DOMMatrixInit::convert( scope, @@ -2892,10 +2853,8 @@ impl DOMMatrix { &Default::default(), )?; let other = DOMMatrixReadOnly::from_matrix_inner(other)?; - result.multiply_self_inner(&other, ro); + ro.multiply_self_inner(&other, &rhs); } - ro.inner.borrow_mut().copy_from(&result.inner.borrow()); - ro.is_2d.set(result.is_2d.get()); Ok(this) } From 1d5cbd056ce0346a5f3bbba874bf8da77684b18a Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 29 Apr 2025 18:13:59 +0900 Subject: [PATCH 33/63] refactor --- ext/geometry/lib.rs | 134 ++++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 73 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index c374e51efe7481..20dcbb4e8f3899 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -97,10 +97,10 @@ pub enum GeometryError { #[error("Cannot parse a CSS value on Workers")] DisallowWindowFeatures, #[class("DOMExceptionSyntaxError")] - #[error("Failed to parse a CSS value")] + #[error("Failed to parse the string as CSS value")] FailedToParse, #[class("DOMExceptionSyntaxError")] - #[error("CSS value contains relative values")] + #[error("The CSS value contains relative values")] ContainsRelativeValue, } @@ -213,7 +213,7 @@ impl DOMPointReadOnly { &self, #[webidl] value: DOMMatrixInit, ) -> Result { - let matrix = DOMMatrixReadOnly::from_matrix_inner(value)?; + let matrix = DOMMatrixReadOnly::from_matrix_inner(&value)?; let ro = DOMPointReadOnly { inner: RefCell::new(Vector4::zeros()), }; @@ -934,18 +934,23 @@ impl DOMMatrixReadOnly { } let value = value.to_string(scope).unwrap(); let matrix = DOMMatrixReadOnly::identity(); - matrix.set_matrix_value_inner(&value.to_rust_string_lossy(scope))?; + let Ok(transform_list) = + TransformList::parse_string(&value.to_rust_string_lossy(scope)) + else { + return Err(GeometryError::FailedToParse); + }; + matrix.set_matrix_value_inner(&transform_list)?; return Ok(matrix); } // sequence let seq = Vec::::convert(scope, value, prefix, context, &Default::default())?; - DOMMatrixReadOnly::from_sequence_inner(seq) + DOMMatrixReadOnly::from_sequence_inner(&seq) } fn from_matrix_inner( - init: DOMMatrixInit, + init: &DOMMatrixInit, ) -> Result { macro_rules! fixup { ($value3d:expr, $value2d:expr, $default:expr) => {{ @@ -1020,10 +1025,10 @@ impl DOMMatrixReadOnly { Ok(DOMMatrixReadOnly { #[rustfmt::skip] inner: RefCell::new(Matrix4::new( - *m11, *m21, *m31, *m41, - *m12, *m22, *m32, *m42, - *m13, *m23, *m33, *m43, - *m14, *m24, *m34, *m44, + *m11, *m21, **m31, *m41, + *m12, *m22, **m32, *m42, + **m13, **m23, **m33, **m43, + **m14, **m24, **m34, **m44, )), is_2d: Cell::new(false), }) @@ -1031,9 +1036,9 @@ impl DOMMatrixReadOnly { } fn from_sequence_inner( - seq: Vec, + seq: &[f64], ) -> Result { - if let [a, b, c, d, e, f] = seq.as_slice() { + if let [a, b, c, d, e, f] = seq { return Ok(DOMMatrixReadOnly { #[rustfmt::skip] inner: RefCell::new(Matrix4::new( @@ -1046,7 +1051,7 @@ impl DOMMatrixReadOnly { }); } else if seq.len() == 16 { return Ok(DOMMatrixReadOnly { - inner: RefCell::new(Matrix4::from_column_slice(seq.as_slice())), + inner: RefCell::new(Matrix4::from_column_slice(seq)), is_2d: Cell::new(false), }); } else { @@ -1150,26 +1155,6 @@ impl DOMMatrixReadOnly { self.is_2d.set(is_2d && x == 0.0 && y == 0.0); } - #[inline] - fn skew_x_self_inner(&self, x: f64) { - let mut inner = self.inner.borrow_mut(); - let skew = Matrix4x2::new(1.0, x.tan(), 0.0, 1.0, 0.0, 0.0, 0.0, 0.0); - let mut result = Matrix4x2::zeros(); - inner.mul_to(&skew, &mut result); - inner.set_column(0, &result.column(0)); - inner.set_column(1, &result.column(1)); - } - - #[inline] - fn skew_y_self_inner(&self, y: f64) { - let mut inner = self.inner.borrow_mut(); - let skew = Matrix4x2::new(1.0, 0.0, y.tan(), 1.0, 0.0, 0.0, 0.0, 0.0); - let mut result = Matrix4x2::zeros(); - inner.mul_to(&skew, &mut result); - inner.set_column(0, &result.column(0)); - inner.set_column(1, &result.column(1)); - } - #[inline] fn skew_self_inner(&self, x: f64, y: f64) { let mut inner = self.inner.borrow_mut(); @@ -1181,7 +1166,7 @@ impl DOMMatrixReadOnly { } #[inline] - fn perspective_self(&self, d: f64) { + fn perspective_self_inner(&self, d: f64) { if d == 0.0 { return; } @@ -1430,11 +1415,11 @@ impl DOMMatrixReadOnly { .all(|&item| item.is_finite()) } - fn set_matrix_value_inner(&self, input: &str) -> Result<(), GeometryError> { - let Ok(transform_list) = TransformList::parse_string(input) else { - return Err(GeometryError::FailedToParse); - }; - for transform in transform_list.0 { + fn set_matrix_value_inner( + &self, + transform_list: &TransformList, + ) -> Result<(), GeometryError> { + for transform in transform_list.0.iter() { match transform { Transform::Translate( LengthPercentage::Dimension(x), @@ -1480,26 +1465,26 @@ impl DOMMatrixReadOnly { } } Transform::Scale(x, y) => { - let x: CSSNumber = (&x).into(); - let y: CSSNumber = (&y).into(); + let x: CSSNumber = x.into(); + let y: CSSNumber = y.into(); self.scale_without_origin_self_inner(x.into(), y.into(), 1.0); } Transform::ScaleX(x) => { - let x: CSSNumber = (&x).into(); + let x: CSSNumber = x.into(); self.scale_without_origin_self_inner(x.into(), 1.0, 1.0); } Transform::ScaleY(y) => { - let y: CSSNumber = (&y).into(); + let y: CSSNumber = y.into(); self.scale_without_origin_self_inner(1.0, y.into(), 1.0); } Transform::ScaleZ(z) => { - let z: CSSNumber = (&z).into(); + let z: CSSNumber = z.into(); self.scale_without_origin_self_inner(1.0, 1.0, z.into()); } Transform::Scale3d(x, y, z) => { - let x: CSSNumber = (&x).into(); - let y: CSSNumber = (&y).into(); - let z: CSSNumber = (&z).into(); + let x: CSSNumber = x.into(); + let y: CSSNumber = y.into(); + let z: CSSNumber = z.into(); self.scale_without_origin_self_inner(x.into(), y.into(), z.into()); } Transform::Rotate(angle) | Transform::RotateZ(angle) => { @@ -1528,9 +1513,9 @@ impl DOMMatrixReadOnly { } Transform::Rotate3d(x, y, z, angle) => { self.rotate_axis_angle_self_inner( - x.into(), - y.into(), - z.into(), + (*x).into(), + (*y).into(), + (*z).into(), angle.to_radians().into(), ); } @@ -1538,14 +1523,14 @@ impl DOMMatrixReadOnly { self.skew_self_inner(x.to_radians().into(), y.to_radians().into()); } Transform::SkewX(angle) => { - self.skew_x_self_inner(angle.to_radians().into()); + self.skew_self_inner(angle.to_radians().into(), 0.0); } Transform::SkewY(angle) => { - self.skew_y_self_inner(angle.to_radians().into()); + self.skew_self_inner(0.0, angle.to_radians().into()); } Transform::Perspective(length) => { if let Some(length) = length.to_px() { - self.perspective_self(length.into()); + self.perspective_self_inner(length.into()); } else { return Err(GeometryError::ContainsRelativeValue); } @@ -1555,10 +1540,10 @@ impl DOMMatrixReadOnly { let rhs = DOMMatrixReadOnly { #[rustfmt::skip] inner: RefCell::new(Matrix4::new( - a.into(), c.into(), 0.0, e.into(), - b.into(), d.into(), 0.0, f.into(), - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0, + (*a).into(), (*c).into(), 0.0, (*e).into(), + (*b).into(), (*d).into(), 0.0, (*f).into(), + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, )), is_2d: Cell::new(true), }; @@ -1586,10 +1571,10 @@ impl DOMMatrixReadOnly { let rhs = DOMMatrixReadOnly { #[rustfmt::skip] inner: RefCell::new(Matrix4::new( - m11.into(), m21.into(), m31.into(), m41.into(), - m12.into(), m22.into(), m32.into(), m42.into(), - m13.into(), m23.into(), m33.into(), m43.into(), - m14.into(), m24.into(), m34.into(), m44.into(), + (*m11).into(), (*m21).into(), (*m31).into(), (*m41).into(), + (*m12).into(), (*m22).into(), (*m32).into(), (*m42).into(), + (*m13).into(), (*m23).into(), (*m33).into(), (*m43).into(), + (*m14).into(), (*m24).into(), (*m34).into(), (*m44).into(), )), is_2d: Cell::new(false), }; @@ -1628,7 +1613,7 @@ impl DOMMatrixReadOnly { pub fn from_matrix( #[webidl] init: DOMMatrixInit, ) -> Result { - DOMMatrixReadOnly::from_matrix_inner(init) + DOMMatrixReadOnly::from_matrix_inner(&init) } #[rename("fromFloat32Array")] @@ -1648,7 +1633,7 @@ impl DOMMatrixReadOnly { (|| Cow::Borrowed("Argument 1")).into(), &Default::default(), )?; - DOMMatrixReadOnly::from_sequence_inner(seq) + DOMMatrixReadOnly::from_sequence_inner(&seq) } #[rename("fromFloat64Array")] @@ -1668,7 +1653,7 @@ impl DOMMatrixReadOnly { (|| Cow::Borrowed("Argument 1")).into(), &Default::default(), )?; - DOMMatrixReadOnly::from_sequence_inner(seq) + DOMMatrixReadOnly::from_sequence_inner(&seq) } #[fast] @@ -1964,7 +1949,7 @@ impl DOMMatrixReadOnly { ) -> DOMMatrixReadOnly { let x_deg = *x_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); let out = self.clone(); - out.skew_x_self_inner(x_deg.to_radians()); + out.skew_self_inner(x_deg.to_radians(), 0.0); out } @@ -1976,7 +1961,7 @@ impl DOMMatrixReadOnly { ) -> DOMMatrixReadOnly { let y_deg = *y_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); let out = self.clone(); - out.skew_y_self_inner(y_deg.to_radians()); + out.skew_self_inner(0.0, y_deg.to_radians()); out } @@ -2000,7 +1985,7 @@ impl DOMMatrixReadOnly { (|| Cow::Borrowed("Argument 1")).into(), &Default::default(), )?; - let other = DOMMatrixReadOnly::from_matrix_inner(other)?; + let other = DOMMatrixReadOnly::from_matrix_inner(&other)?; out.multiply_self_inner(self, &other); } Ok(out) @@ -2145,7 +2130,7 @@ impl DOMMatrix { pub fn from_matrix( #[webidl] init: DOMMatrixInit, ) -> Result { - DOMMatrixReadOnly::from_matrix_inner(init) + DOMMatrixReadOnly::from_matrix_inner(&init) } // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) @@ -2788,7 +2773,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) -> v8::Global { let x_deg = *x_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); - ro.skew_x_self_inner(x_deg.to_radians()); + ro.skew_self_inner(x_deg.to_radians(), 0.0); this } @@ -2800,7 +2785,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) -> v8::Global { let y_deg = *y_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); - ro.skew_y_self_inner(y_deg.to_radians()); + ro.skew_self_inner(0.0, y_deg.to_radians()); this } @@ -2825,7 +2810,7 @@ impl DOMMatrix { (|| Cow::Borrowed("Argument 1")).into(), &Default::default(), )?; - let other = DOMMatrixReadOnly::from_matrix_inner(other)?; + let other = DOMMatrixReadOnly::from_matrix_inner(&other)?; ro.multiply_self_inner(&lhs, &other); } Ok(this) @@ -2852,7 +2837,7 @@ impl DOMMatrix { (|| Cow::Borrowed("Argument 1")).into(), &Default::default(), )?; - let other = DOMMatrixReadOnly::from_matrix_inner(other)?; + let other = DOMMatrixReadOnly::from_matrix_inner(&other)?; ro.multiply_self_inner(&other, &rhs); } Ok(this) @@ -2993,7 +2978,10 @@ pub fn op_geometry_matrix_set_matrix_value<'a>( let matrix = cppgc::try_unwrap_cppgc_proto_object::(scope, input) .unwrap(); - matrix.set_matrix_value_inner(transform_list)?; + let Ok(transform_list) = TransformList::parse_string(transform_list) else { + return Err(GeometryError::FailedToParse); + }; + matrix.set_matrix_value_inner(&transform_list)?; Ok(input) } From 64e2ecf9697be786a18538190e002357795bebe0 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 29 Apr 2025 18:54:44 +0900 Subject: [PATCH 34/63] wip --- ext/geometry/lib.rs | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 20dcbb4e8f3899..27ad0c573a73b3 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -2934,6 +2934,15 @@ pub fn op_geometry_matrix_to_string<'a>( scope: &mut v8::HandleScope<'a>, matrix: v8::Local<'a, v8::Value>, ) -> Result { + #[inline] + fn to_string( + scope: &mut v8::HandleScope, + value: f64, + ) -> String { + let number = v8::Number::new(scope, value); + number.to_string(scope).unwrap().to_rust_string_lossy(scope) + } + let Some(matrix) = cppgc::try_unwrap_cppgc_proto_object::(scope, matrix) else { @@ -2945,12 +2954,12 @@ pub fn op_geometry_matrix_to_string<'a>( if matrix.is_2d.get() { Ok(format!( "matrix({}, {}, {}, {}, {}, {})", - matrix.a_inner(), - matrix.b_inner(), - matrix.c_inner(), - matrix.d_inner(), - matrix.e_inner(), - matrix.f_inner(), + to_string(scope, matrix.a_inner()), + to_string(scope, matrix.b_inner()), + to_string(scope, matrix.c_inner()), + to_string(scope, matrix.d_inner()), + to_string(scope, matrix.e_inner()), + to_string(scope, matrix.f_inner()), )) } else { Ok(format!( @@ -2959,7 +2968,7 @@ pub fn op_geometry_matrix_to_string<'a>( .inner .borrow() .iter() - .map(|item| item.to_string()) + .map(|item| to_string(scope, *item)) .collect::>() .join(", ") )) From 218b3f52fc3c0dde8ffbc1cbadc862a709d2fc0f Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 29 Apr 2025 19:28:07 +0900 Subject: [PATCH 35/63] wip --- ext/geometry/01_geometry.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index f81acce03cd102..1d85f0b2e93753 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -57,6 +57,8 @@ ObjectDefineProperty( configurable: true, }, ); +webidl.configureInterface(DOMPoint); +webidl.configureInterface(DOMPointReadOnly); const DOMRectPrototype = DOMRect.prototype; const DOMRectReadOnlyPrototype = DOMRectReadOnly.prototype; @@ -83,6 +85,8 @@ ObjectDefineProperty( configurable: true, }, ); +webidl.configureInterface(DOMRect); +webidl.configureInterface(DOMRectReadOnly); const DOMQuadPrototype = DOMQuad.prototype; ObjectDefineProperty(DOMQuadPrototype, SymbolFor("Deno.privateCustomInspect"), { @@ -101,7 +105,9 @@ ObjectDefineProperty(DOMQuadPrototype, SymbolFor("Deno.privateCustomInspect"), { writable: true, configurable: true, }); +webidl.configureInterface(DOMQuad); +const DOMMatrixPrototype = DOMMatrix.prototype; const DOMMatrixReadOnlyPrototype = DOMMatrixReadOnly.prototype; ObjectDefineProperties(DOMMatrixReadOnlyPrototype, { toFloat32Array: { @@ -170,8 +176,6 @@ ObjectDefineProperties(DOMMatrixReadOnlyPrototype, { }, }); -const DOMMatrixPrototype = DOMMatrix.prototype; - if (op_geometry_get_enable_window_features()) { // https://drafts.fxtf.org/geometry/#dommatrixreadonly-stringification-behavior ObjectDefineProperty(DOMMatrixReadOnlyPrototype, "toString", { @@ -196,6 +200,9 @@ if (op_geometry_get_enable_window_features()) { }); } +webidl.configureInterface(DOMMatrix); +webidl.configureInterface(DOMMatrixReadOnly); + export { DOMMatrix, DOMMatrixPrototype, From 8e8af1d413b83f65e65d7b98ecc1144d89e5583f Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 30 Apr 2025 18:21:36 +0900 Subject: [PATCH 36/63] wip --- ext/geometry/01_geometry.js | 2 ++ ext/geometry/lib.rs | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 1d85f0b2e93753..8f9043310139e6 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -192,6 +192,8 @@ if (op_geometry_get_enable_window_features()) { ObjectDefineProperty(DOMMatrixPrototype, "setMatrixValue", { __proto__: null, value: function setMatrixValue(transformList) { + const prefix = "Failed to execute 'setMatrixValue' on 'DOMMatrix'"; + webidl.requiredArguments(arguments.length, 1, prefix); op_geometry_matrix_set_matrix_value(this, transformList); }, writable: true, diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 27ad0c573a73b3..e3ecbebaa0402a 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -1617,6 +1617,7 @@ impl DOMMatrixReadOnly { } #[rename("fromFloat32Array")] + #[required(1)] #[static_method] #[cppgc] pub fn from_float32_array<'a>( @@ -1637,6 +1638,7 @@ impl DOMMatrixReadOnly { } #[rename("fromFloat64Array")] + #[required(1)] #[static_method] #[cppgc] pub fn from_float64_array<'a>( @@ -2135,6 +2137,7 @@ impl DOMMatrix { // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) #[rename("fromFloat32Array")] + #[required(1)] #[static_method] #[cppgc] pub fn from_float32_array<'a>( @@ -2175,6 +2178,7 @@ impl DOMMatrix { // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) #[rename("fromFloat64Array")] + #[required(1)] #[static_method] #[cppgc] pub fn from_float64_array<'a>( @@ -2935,10 +2939,7 @@ pub fn op_geometry_matrix_to_string<'a>( matrix: v8::Local<'a, v8::Value>, ) -> Result { #[inline] - fn to_string( - scope: &mut v8::HandleScope, - value: f64, - ) -> String { + fn to_string(scope: &mut v8::HandleScope, value: f64) -> String { let number = v8::Number::new(scope, value); number.to_string(scope).unwrap().to_rust_string_lossy(scope) } From 738be87fb91f54357361f0521c15235b33322af5 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 2 May 2025 00:12:11 +0900 Subject: [PATCH 37/63] tweak --- ext/geometry/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/geometry/README.md b/ext/geometry/README.md index f5011bbefcb6f3..807ba40712b228 100644 --- a/ext/geometry/README.md +++ b/ext/geometry/README.md @@ -48,7 +48,7 @@ Object.defineProperties(globalThis, { }); ``` -Then from rust, provide: `deno_geometry::deno_geometry::init_ops_and_esm(bool)` +Then from rust, provide: `deno_geometry::deno_geometry::init(bool)` in the `extensions` field of your `RuntimeOptions` Where `bool` indicates whether window features are enabled at initialization. From cea71f51e809725c4d68328ae0ab90c418ab9b82 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 23 May 2025 21:18:09 +0900 Subject: [PATCH 38/63] wip --- Cargo.lock | 8 ++++---- Cargo.toml | 3 +-- ext/geometry/lib.rs | 42 +++++++++++++++++++++++++++++++++++------- 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1f9fc768af20be..d8b773e7ea5475 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5406,9 +5406,9 @@ dependencies = [ [[package]] name = "lightningcss" -version = "1.0.0-alpha.65" +version = "1.0.0-alpha.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c84f971730745f4aaac013b6cf4328baf1548efc973c0d95cfd843a3c1ca07af" +checksum = "9a73ffa17de66534e4b527232f44aa0a89fad22c4f4e0735f9be35494f058e54" dependencies = [ "ahash", "bitflags 2.8.0", @@ -6294,9 +6294,9 @@ dependencies = [ [[package]] name = "parcel_selectors" -version = "0.28.1" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dccbc6fb560df303a44e511618256029410efbc87779018f751ef12c488271fe" +checksum = "54fd03f1ad26cb6b3ec1b7414fa78a3bd639e7dbb421b1a60513c96ce886a196" dependencies = [ "bitflags 2.8.0", "cssparser", diff --git a/Cargo.toml b/Cargo.toml index 5ffc6fa19bcfd4..8fa1a49d35c038 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -368,8 +368,7 @@ napi-build = "1" napi-sys = { version = "=2.2.2", default-features = false } # geometry -# NOTE: cannot disable grid feature: https://github.com/parcel-bundler/lightningcss/issues/376 -lightningcss = { version = "1.0.0-alpha.65", default-features = false, features = ["grid"] } +lightningcss = { version = "1.0.0-alpha.66", default-features = false } nalgebra = { version = "0.33.2", default-features = false, features = ["std"] } # webgpu diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index e3ecbebaa0402a..0492ca4da9ee97 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -122,7 +122,11 @@ pub struct DOMPointReadOnly { inner: RefCell>, } -impl GarbageCollected for DOMPointReadOnly {} +impl GarbageCollected for DOMPointReadOnly { + fn get_name(&self) -> &'static std::ffi::CStr { + c"DOMPointReadOnly" + } +} impl DOMPointReadOnly { fn from_point_inner(init: DOMPointInit) -> DOMPointReadOnly { @@ -224,7 +228,11 @@ impl DOMPointReadOnly { pub struct DOMPoint {} -impl GarbageCollected for DOMPoint {} +impl GarbageCollected for DOMPoint { + fn get_name(&self) -> &'static std::ffi::CStr { + c"DOMPoint" + } +} #[op2(inherit = DOMPointReadOnly)] impl DOMPoint { @@ -338,7 +346,11 @@ pub struct DOMRectReadOnly { height: Cell, } -impl GarbageCollected for DOMRectReadOnly {} +impl GarbageCollected for DOMRectReadOnly { + fn get_name(&self) -> &'static std::ffi::CStr { + c"DOMRectReadOnly" + } +} impl DOMRectReadOnly { fn from_rect_inner(init: DOMRectInit) -> DOMRectReadOnly { @@ -499,7 +511,11 @@ impl DOMRectReadOnly { pub struct DOMRect {} -impl GarbageCollected for DOMRect {} +impl GarbageCollected for DOMRect { + fn get_name(&self) -> &'static std::ffi::CStr { + c"DOMRect" + } +} #[op2(inherit = DOMRectReadOnly)] impl DOMRect { @@ -607,7 +623,11 @@ pub struct DOMQuad { p4: SameObject, } -impl GarbageCollected for DOMQuad {} +impl GarbageCollected for DOMQuad { + fn get_name(&self) -> &'static std::ffi::CStr { + c"DOMQuad" + } +} #[op2] impl DOMQuad { @@ -869,7 +889,11 @@ pub struct DOMMatrixReadOnly { is_2d: Cell, } -impl GarbageCollected for DOMMatrixReadOnly {} +impl GarbageCollected for DOMMatrixReadOnly { + fn get_name(&self) -> &'static std::ffi::CStr { + c"DOMMatrixReadOnly" + } +} /* * NOTE: column-major order @@ -2102,7 +2126,11 @@ impl DOMMatrixReadOnly { pub struct DOMMatrix {} -impl GarbageCollected for DOMMatrix {} +impl GarbageCollected for DOMMatrix { + fn get_name(&self) -> &'static std::ffi::CStr { + c"DOMMatrix" + } +} #[op2(inherit = DOMMatrixReadOnly)] impl DOMMatrix { From fefee0ef9282d684dd8f3eaa328b0739549c83ba Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 20 Jul 2025 02:56:43 +0900 Subject: [PATCH 39/63] wip --- Cargo.lock | 28 ++-- Cargo.toml | 4 +- ext/geometry/README.md | 4 +- ext/geometry/lib.rs | 346 ++++++++++++++++++++--------------------- 4 files changed, 193 insertions(+), 189 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b8de23991f0be..8f3686a3c0be75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -98,7 +98,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom", + "getrandom 0.2.14", "once_cell", "version_check", "zerocopy", @@ -1923,8 +1923,7 @@ dependencies = [ [[package]] name = "deno_core" version = "0.352.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf78f3f72ac8e09b18a588bc26a1b3c5ab853e7fb489889b2f5000654d34db5d" +source = "git+https://github.com/petamoriken/deno_core?branch=feat%2Fmake_cppgc_empty_object#8e0e03692d6948b3d9cc7179e262ca3f285a4f75" dependencies = [ "anyhow", "az", @@ -2672,8 +2671,7 @@ dependencies = [ [[package]] name = "deno_ops" version = "0.228.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf8dbe5abf37d270bb853c5dfe45fbe3b1b6c453877cc11d7fe84e9862a6dbc" +source = "git+https://github.com/petamoriken/deno_core?branch=feat%2Fmake_cppgc_empty_object#8e0e03692d6948b3d9cc7179e262ca3f285a4f75" dependencies = [ "indexmap 2.9.0", "proc-macro-rules", @@ -5383,6 +5381,15 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.12.1" @@ -5732,9 +5739,9 @@ dependencies = [ [[package]] name = "lightningcss" -version = "1.0.0-alpha.66" +version = "1.0.0-alpha.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a73ffa17de66534e4b527232f44aa0a89fad22c4f4e0735f9be35494f058e54" +checksum = "798fba4e1205eed356b8ed7754cc3f7f04914e27855ca641409f4a532e992149" dependencies = [ "ahash", "bitflags 2.8.0", @@ -5742,8 +5749,8 @@ dependencies = [ "cssparser", "cssparser-color", "data-encoding", - "getrandom", - "indexmap 2.8.0", + "getrandom 0.2.14", + "indexmap 2.9.0", "itertools 0.10.5", "lazy_static", "lightningcss-derive", @@ -8169,8 +8176,7 @@ dependencies = [ [[package]] name = "serde_v8" version = "0.261.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3495190857461e87a2716141043218aad5281f219f54a03b7ebbe605b3b931df" +source = "git+https://github.com/petamoriken/deno_core?branch=feat%2Fmake_cppgc_empty_object#8e0e03692d6948b3d9cc7179e262ca3f285a4f75" dependencies = [ "deno_error", "num-bigint", diff --git a/Cargo.toml b/Cargo.toml index e0852b8cb6d16b..479d5add589a6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,7 +61,7 @@ repository = "https://github.com/denoland/deno" [workspace.dependencies] deno_ast = { version = "=0.48.2", features = ["transpiling"] } -deno_core = { version = "0.352.1" } +deno_core = { git = "https://github.com/petamoriken/deno_core", branch = "feat/make_cppgc_empty_object" } deno_cache_dir = "=0.23.0" deno_doc = "=0.179.0" @@ -382,7 +382,7 @@ napi-build = "1" napi-sys = { version = "=2.2.2", default-features = false } # geometry -lightningcss = { version = "1.0.0-alpha.66", default-features = false } +lightningcss = { version = "1.0.0-alpha.67", default-features = false } nalgebra = { version = "0.33.2", default-features = false, features = ["std"] } # webgpu diff --git a/ext/geometry/README.md b/ext/geometry/README.md index 807ba40712b228..1ef3341c9b42cb 100644 --- a/ext/geometry/README.md +++ b/ext/geometry/README.md @@ -48,8 +48,8 @@ Object.defineProperties(globalThis, { }); ``` -Then from rust, provide: `deno_geometry::deno_geometry::init(bool)` -in the `extensions` field of your `RuntimeOptions` +Then from rust, provide: `deno_geometry::deno_geometry::init(bool)` in the +`extensions` field of your `RuntimeOptions` Where `bool` indicates whether window features are enabled at initialization. diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 0492ca4da9ee97..6e9ffb446ca0b3 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -6,17 +6,16 @@ use std::cell::RefCell; use std::mem; use std::slice; +use deno_core::GarbageCollected; +use deno_core::OpState; +use deno_core::WebIDL; use deno_core::cppgc; -use deno_core::cppgc::SameObject; use deno_core::op2; use deno_core::v8; use deno_core::webidl; use deno_core::webidl::ContextFn; use deno_core::webidl::WebIdlConverter; use deno_core::webidl::WebIdlError; -use deno_core::GarbageCollected; -use deno_core::OpState; -use deno_core::WebIDL; use lightningcss::properties::transform::Matrix as CSSMatrix; use lightningcss::properties::transform::Matrix3d as CSSMatrix3d; use lightningcss::properties::transform::Transform; @@ -85,7 +84,9 @@ pub enum GeometryError { #[error("Inconsistent 2d matrix value")] Inconsistent2DMatrix, #[class(type)] - #[error("The sequence must contain 6 elements for a 2D matrix or 16 elements for a 3D matrix")] + #[error( + "The sequence must contain 6 elements for a 2D matrix or 16 elements for a 3D matrix" + )] InvalidSequenceSize, #[class(type)] #[error("Mismatched types")] @@ -123,7 +124,7 @@ pub struct DOMPointReadOnly { } impl GarbageCollected for DOMPointReadOnly { - fn get_name(&self) -> &'static std::ffi::CStr { + fn get_name(&self) -> &'static std::ffi::CStr { c"DOMPointReadOnly" } } @@ -211,18 +212,18 @@ impl DOMPointReadOnly { obj } - // TODO(petamoriken): returns (DOMPointReadOnly, DOMPoint) - #[cppgc] - pub fn matrix_transform( + pub fn matrix_transform<'a>( &self, + scope: &mut v8::HandleScope<'a>, #[webidl] value: DOMMatrixInit, - ) -> Result { + ) -> Result, GeometryError> { let matrix = DOMMatrixReadOnly::from_matrix_inner(&value)?; let ro = DOMPointReadOnly { inner: RefCell::new(Vector4::zeros()), }; matrix_transform_point(&matrix, self, &ro); - Ok(ro) + let obj = cppgc::make_cppgc_empty_object::(scope); + Ok(cppgc::wrap_object2(scope, obj, (ro, DOMPoint {}))) } } @@ -255,13 +256,15 @@ impl DOMPoint { (ro, DOMPoint {}) } - // TODO(petamoriken): returns (DOMPointReadOnly, DOMPoint) #[reentrant] #[static_method] - #[cppgc] - pub fn from_point(#[webidl] init: DOMPointInit) -> DOMPointReadOnly { + pub fn from_point<'a>( + scope: &mut v8::HandleScope<'a>, + #[webidl] init: DOMPointInit, + ) -> v8::Local<'a, v8::Object> { let ro = DOMPointReadOnly::from_point_inner(init); - ro + let obj = cppgc::make_cppgc_empty_object::(scope); + cppgc::wrap_object2(scope, obj, (ro, DOMPoint {})) } #[fast] @@ -536,13 +539,15 @@ impl DOMRect { (ro, DOMRect {}) } - // TODO(petamoriken): returns (DOMRectReadOnly, DOMRect) #[reentrant] #[static_method] - #[cppgc] - pub fn from_rect(#[webidl] init: DOMRectInit) -> DOMRectReadOnly { + pub fn from_rect<'a>( + scope: &mut v8::HandleScope<'a>, + #[webidl] init: DOMRectInit, + ) -> v8::Local<'a, v8::Object> { let ro = DOMRectReadOnly::from_rect_inner(init); - ro + let obj = cppgc::make_cppgc_empty_object::(scope); + cppgc::wrap_object2(scope, obj, (ro, DOMRect {})) } #[fast] @@ -615,12 +620,11 @@ pub struct DOMQuadInit { p4: DOMPointInit, } -// TODO(petamoriken): store SameObject<(DOMPointReadOnly, DOMPoint)> pub struct DOMQuad { - p1: SameObject, - p2: SameObject, - p3: SameObject, - p4: SameObject, + p1: v8::Global, + p2: v8::Global, + p3: v8::Global, + p4: v8::Global, } impl GarbageCollected for DOMQuad { @@ -645,19 +649,15 @@ impl DOMQuad { fn from_point( scope: &mut v8::HandleScope, point: DOMPointInit, - ) -> SameObject { - let obj = SameObject::new(); - obj - .set( - scope, - DOMPointReadOnly { - inner: RefCell::new(Vector4::new( - *point.x, *point.y, *point.z, *point.w, - )), - }, - ) - .unwrap(); - obj + ) -> v8::Global { + let ro = DOMPointReadOnly { + inner: RefCell::new(Vector4::new( + *point.x, *point.y, *point.z, *point.w, + )), + }; + let obj = cppgc::make_cppgc_empty_object::(scope); + cppgc::wrap_object2(scope, obj, (ro, DOMPoint {})); + v8::Global::new(scope, obj) } DOMQuad { @@ -682,17 +682,13 @@ impl DOMQuad { y: f64, z: f64, w: f64, - ) -> SameObject { - let obj = SameObject::new(); - obj - .set( - scope, - DOMPointReadOnly { - inner: RefCell::new(Vector4::new(x, y, z, w)), - }, - ) - .unwrap(); - obj + ) -> v8::Global { + let ro = DOMPointReadOnly { + inner: RefCell::new(Vector4::new(x, y, z, w)), + }; + let obj = cppgc::make_cppgc_empty_object::(scope); + cppgc::wrap_object2(scope, obj, (ro, DOMPoint {})); + v8::Global::new(scope, obj) } let DOMRectInit { @@ -720,19 +716,15 @@ impl DOMQuad { fn from_point( scope: &mut v8::HandleScope, point: DOMPointInit, - ) -> SameObject { - let obj = SameObject::new(); - obj - .set( - scope, - DOMPointReadOnly { - inner: RefCell::new(Vector4::new( - *point.x, *point.y, *point.z, *point.w, - )), - }, - ) - .unwrap(); - obj + ) -> v8::Global { + let ro = DOMPointReadOnly { + inner: RefCell::new(Vector4::new( + *point.x, *point.y, *point.z, *point.w, + )), + }; + let obj = cppgc::make_cppgc_empty_object::(scope); + cppgc::wrap_object2(scope, obj, (ro, DOMPoint {})); + v8::Global::new(scope, obj) } DOMQuad { @@ -745,37 +737,37 @@ impl DOMQuad { #[getter] #[global] - pub fn p1(&self, scope: &mut v8::HandleScope) -> v8::Global { - self.p1.get(scope, |_| unreachable!()) + pub fn p1(&self) -> v8::Global { + self.p1.clone() } #[getter] #[global] - pub fn p2(&self, scope: &mut v8::HandleScope) -> v8::Global { - self.p2.get(scope, |_| unreachable!()) + pub fn p2(&self) -> v8::Global { + self.p2.clone() } #[getter] #[global] - pub fn p3(&self, scope: &mut v8::HandleScope) -> v8::Global { - self.p3.get(scope, |_| unreachable!()) + pub fn p3(&self) -> v8::Global { + self.p3.clone() } #[getter] #[global] - pub fn p4(&self, scope: &mut v8::HandleScope) -> v8::Global { - self.p4.get(scope, |_| unreachable!()) + pub fn p4(&self) -> v8::Global { + self.p4.clone() } - // TODO(petamoriken): returns (DOMRectReadOnly, DOMRect) - #[cppgc] - pub fn get_bounds(&self, scope: &mut v8::HandleScope) -> DOMRectReadOnly { + pub fn get_bounds<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + ) -> v8::Local<'a, v8::Object> { #[inline] fn get_ptr( scope: &mut v8::HandleScope, - value: &SameObject, + value: &v8::Global, ) -> cppgc::Ptr { - let value = value.get(scope, |_| unreachable!()); let value = v8::Local::new(scope, value); cppgc::try_unwrap_cppgc_object::(scope, value.cast()) .unwrap() @@ -799,7 +791,8 @@ impl DOMQuad { width: Cell::new(right - left), height: Cell::new(bottom - top), }; - ro + let obj = cppgc::make_cppgc_empty_object::(scope); + cppgc::wrap_object2(scope, obj, (ro, DOMRect {})) } #[rename("toJSON")] @@ -820,14 +813,10 @@ impl DOMQuad { } let mut obj = v8::Object::new(scope); - let p1 = self.p1.get(scope, |_| unreachable!()); - let p2 = self.p2.get(scope, |_| unreachable!()); - let p3 = self.p3.get(scope, |_| unreachable!()); - let p4 = self.p4.get(scope, |_| unreachable!()); - set(scope, &mut obj, "p1", p1); - set(scope, &mut obj, "p2", p2); - set(scope, &mut obj, "p3", p3); - set(scope, &mut obj, "p4", p4); + set(scope, &mut obj, "p1", self.p1.clone()); + set(scope, &mut obj, "p2", self.p2.clone()); + set(scope, &mut obj, "p3", self.p3.clone()); + set(scope, &mut obj, "p4", self.p4.clone()); obj } } @@ -1826,33 +1815,32 @@ impl DOMMatrixReadOnly { self.is_identity_inner() } - // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) - #[cppgc] - pub fn translate( + pub fn translate<'a>( &self, + scope: &mut v8::HandleScope<'a>, #[webidl] tx: Option, #[webidl] ty: Option, #[webidl] tz: Option, - ) -> DOMMatrixReadOnly { + ) -> v8::Local<'a, v8::Object> { let tx = *tx.unwrap_or(webidl::UnrestrictedDouble(0.0)); let ty = *ty.unwrap_or(webidl::UnrestrictedDouble(0.0)); let tz = *tz.unwrap_or(webidl::UnrestrictedDouble(0.0)); let out = self.clone(); out.translate_self_inner(tx, ty, tz); - out + let obj = cppgc::make_cppgc_empty_object::(scope); + cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) - #[cppgc] - pub fn scale( + pub fn scale<'a>( &self, + scope: &mut v8::HandleScope<'a>, #[webidl] sx: Option, #[webidl] sy: Option, #[webidl] sz: Option, #[webidl] origin_x: Option, #[webidl] origin_y: Option, #[webidl] origin_z: Option, - ) -> DOMMatrixReadOnly { + ) -> v8::Local<'a, v8::Object> { let sx = *sx.unwrap_or(webidl::UnrestrictedDouble(1.0)); let sy = *sy.unwrap_or(webidl::UnrestrictedDouble(sx)); let sz = *sz.unwrap_or(webidl::UnrestrictedDouble(1.0)); @@ -1866,32 +1854,33 @@ impl DOMMatrixReadOnly { out .scale_with_origin_self_inner(sx, sy, sz, origin_x, origin_y, origin_z); } - out + let obj = cppgc::make_cppgc_empty_object::(scope); + cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) - #[cppgc] - pub fn scale_non_uniform( + pub fn scale_non_uniform<'a>( &self, + scope: &mut v8::HandleScope<'a>, #[webidl] sx: Option, #[webidl] sy: Option, - ) -> DOMMatrixReadOnly { + ) -> v8::Local<'a, v8::Object> { let sx = *sx.unwrap_or(webidl::UnrestrictedDouble(1.0)); let sy = *sy.unwrap_or(webidl::UnrestrictedDouble(1.0)); let out = self.clone(); out.scale_without_origin_self_inner(sx, sy, 1.0); - out + let obj = cppgc::make_cppgc_empty_object::(scope); + cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) - #[cppgc] - pub fn scale3d( + #[rename("scale3d")] + pub fn scale3d<'a>( &self, + scope: &mut v8::HandleScope<'a>, #[webidl] scale: Option, #[webidl] origin_x: Option, #[webidl] origin_y: Option, #[webidl] origin_z: Option, - ) -> DOMMatrixReadOnly { + ) -> v8::Local<'a, v8::Object> { let scale = *scale.unwrap_or(webidl::UnrestrictedDouble(1.0)); let origin_x = *origin_x.unwrap_or(webidl::UnrestrictedDouble(0.0)); let origin_y = *origin_y.unwrap_or(webidl::UnrestrictedDouble(0.0)); @@ -1904,17 +1893,17 @@ impl DOMMatrixReadOnly { scale, scale, scale, origin_x, origin_y, origin_z, ); } - out + let obj = cppgc::make_cppgc_empty_object::(scope); + cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) - #[cppgc] - pub fn rotate( + pub fn rotate<'a>( &self, + scope: &mut v8::HandleScope<'a>, #[webidl] rotate_x: Option, #[webidl] rotate_y: Option, #[webidl] rotate_z: Option, - ) -> DOMMatrixReadOnly { + ) -> v8::Local<'a, v8::Object> { let rotate_x = *rotate_x.unwrap_or(webidl::UnrestrictedDouble(0.0)); let (roll_deg, pitch_deg, yaw_deg) = if rotate_y.is_none() && rotate_z.is_none() { @@ -1932,72 +1921,71 @@ impl DOMMatrixReadOnly { pitch_deg.to_radians(), yaw_deg.to_radians(), ); - out + let obj = cppgc::make_cppgc_empty_object::(scope); + cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) - #[cppgc] - pub fn rotate_from_vector( + pub fn rotate_from_vector<'a>( &self, + scope: &mut v8::HandleScope<'a>, #[webidl] x: Option, #[webidl] y: Option, - ) -> DOMMatrixReadOnly { + ) -> v8::Local<'a, v8::Object> { let x = *x.unwrap_or(webidl::UnrestrictedDouble(0.0)); let y = *y.unwrap_or(webidl::UnrestrictedDouble(0.0)); let out = self.clone(); out.rotate_from_vector_self_inner(x, y); - out + let obj = cppgc::make_cppgc_empty_object::(scope); + cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) - #[cppgc] - pub fn rotate_axis_angle( + pub fn rotate_axis_angle<'a>( &self, + scope: &mut v8::HandleScope<'a>, #[webidl] x: Option, #[webidl] y: Option, #[webidl] z: Option, #[webidl] angle_deg: Option, - ) -> DOMMatrixReadOnly { + ) -> v8::Local<'a, v8::Object> { let x = *x.unwrap_or(webidl::UnrestrictedDouble(0.0)); let y = *y.unwrap_or(webidl::UnrestrictedDouble(0.0)); let z = *z.unwrap_or(webidl::UnrestrictedDouble(0.0)); let angle_deg = *angle_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); let out = self.clone(); out.rotate_axis_angle_self_inner(x, y, z, angle_deg.to_radians()); - out + let obj = cppgc::make_cppgc_empty_object::(scope); + cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) - #[cppgc] - pub fn skew_x( + pub fn skew_x<'a>( &self, + scope: &mut v8::HandleScope<'a>, #[webidl] x_deg: Option, - ) -> DOMMatrixReadOnly { + ) -> v8::Local<'a, v8::Object> { let x_deg = *x_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); let out = self.clone(); out.skew_self_inner(x_deg.to_radians(), 0.0); - out + let obj = cppgc::make_cppgc_empty_object::(scope); + cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) - #[cppgc] - pub fn skew_y( + pub fn skew_y<'a>( &self, + scope: &mut v8::HandleScope<'a>, #[webidl] y_deg: Option, - ) -> DOMMatrixReadOnly { + ) -> v8::Local<'a, v8::Object> { let y_deg = *y_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); let out = self.clone(); out.skew_self_inner(0.0, y_deg.to_radians()); - out + let obj = cppgc::make_cppgc_empty_object::(scope); + cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) - #[cppgc] pub fn multiply<'a>( &self, scope: &mut v8::HandleScope<'a>, other: v8::Local<'a, v8::Value>, - ) -> Result { + ) -> Result, GeometryError> { let out = self.clone(); if let Some(other) = cppgc::try_unwrap_cppgc_proto_object::(scope, other) @@ -2014,40 +2002,45 @@ impl DOMMatrixReadOnly { let other = DOMMatrixReadOnly::from_matrix_inner(&other)?; out.multiply_self_inner(self, &other); } - Ok(out) + let obj = cppgc::make_cppgc_empty_object::(scope); + Ok(cppgc::wrap_object2(scope, obj, (out, DOMMatrix {}))) } - // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) - #[cppgc] - pub fn flip_x(&self) -> DOMMatrixReadOnly { + pub fn flip_x<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + ) -> v8::Local<'a, v8::Object> { let out = self.clone(); out.flip_x_inner(); - out + let obj = cppgc::make_cppgc_empty_object::(scope); + cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) - #[cppgc] - pub fn flip_y(&self) -> DOMMatrixReadOnly { + pub fn flip_y<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + ) -> v8::Local<'a, v8::Object> { let out = self.clone(); out.flip_y_inner(); - out + let obj = cppgc::make_cppgc_empty_object::(scope); + cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) - #[cppgc] - pub fn inverse(&self) -> DOMMatrixReadOnly { + pub fn inverse<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + ) -> v8::Local<'a, v8::Object> { let out = self.clone(); out.invert_self_inner(); - out + let obj = cppgc::make_cppgc_empty_object::(scope); + cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) - #[cppgc] pub fn transform_point<'a>( &self, scope: &mut v8::HandleScope<'a>, point: v8::Local<'a, v8::Value>, - ) -> Result { + ) -> Result, GeometryError> { let out = DOMPointReadOnly { inner: RefCell::new(Vector4::zeros()), }; @@ -2066,7 +2059,8 @@ impl DOMMatrixReadOnly { let point = DOMPointReadOnly::from_point_inner(point); matrix_transform_point(self, &point, &out); } - Ok(out) + let obj = cppgc::make_cppgc_empty_object::(scope); + Ok(cppgc::wrap_object2(scope, obj, (out, DOMPoint {}))) } #[rename("toJSON")] @@ -2141,7 +2135,7 @@ impl DOMMatrix { scope: &mut v8::HandleScope<'a>, value: v8::Local<'a, v8::Value>, // TODO(petamoriken): Error when deleting next line. proc-macro bug? - #[webidl] _: Option, + #[webidl] _: bool, ) -> Result<(DOMMatrixReadOnly, DOMMatrix), GeometryError> { let ro = DOMMatrixReadOnly::new( state, @@ -2153,25 +2147,24 @@ impl DOMMatrix { Ok((ro, DOMMatrix {})) } - // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) #[reentrant] #[static_method] - #[cppgc] - pub fn from_matrix( + pub fn from_matrix<'a>( + scope: &mut v8::HandleScope<'a>, #[webidl] init: DOMMatrixInit, - ) -> Result { - DOMMatrixReadOnly::from_matrix_inner(&init) + ) -> Result, GeometryError> { + let ro = DOMMatrixReadOnly::from_matrix_inner(&init)?; + let obj = cppgc::make_cppgc_empty_object::(scope); + Ok(cppgc::wrap_object2(scope, obj, (ro, DOMMatrix {}))) } - // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) #[rename("fromFloat32Array")] #[required(1)] #[static_method] - #[cppgc] pub fn from_float32_array<'a>( scope: &mut v8::HandleScope<'a>, value: v8::Local<'a, v8::Value>, - ) -> Result { + ) -> Result, GeometryError> { if !value.is_float32_array() { return Err(GeometryError::TypeMismatch); } @@ -2183,8 +2176,8 @@ impl DOMMatrix { &Default::default(), )?; - if let [a, b, c, d, e, f] = float64.as_slice() { - return Ok(DOMMatrixReadOnly { + let ro = if let [a, b, c, d, e, f] = float64.as_slice() { + DOMMatrixReadOnly { #[rustfmt::skip] inner: RefCell::new(Matrix4::new( *a, *c, 0.0, *e, @@ -2193,26 +2186,27 @@ impl DOMMatrix { 0.0, 0.0, 0.0, 1.0, )), is_2d: Cell::new(true), - }); + } } else if float64.len() == 16 { - return Ok(DOMMatrixReadOnly { + DOMMatrixReadOnly { inner: RefCell::new(Matrix4::from_column_slice(float64.as_slice())), is_2d: Cell::new(false), - }); + } } else { - Err(GeometryError::InvalidSequenceSize) - } + return Err(GeometryError::InvalidSequenceSize); + }; + + let obj = cppgc::make_cppgc_empty_object::(scope); + Ok(cppgc::wrap_object2(scope, obj, (ro, DOMMatrix {}))) } - // TODO(petamoriken): returns (DOMMatrixReadOnly, DOMMatrix) #[rename("fromFloat64Array")] #[required(1)] #[static_method] - #[cppgc] pub fn from_float64_array<'a>( scope: &mut v8::HandleScope<'a>, value: v8::Local<'a, v8::Value>, - ) -> Result { + ) -> Result, GeometryError> { if !value.is_float64_array() { return Err(GeometryError::TypeMismatch); } @@ -2224,8 +2218,8 @@ impl DOMMatrix { &Default::default(), )?; - if let [a, b, c, d, e, f] = float64.as_slice() { - return Ok(DOMMatrixReadOnly { + let ro = if let [a, b, c, d, e, f] = float64.as_slice() { + DOMMatrixReadOnly { #[rustfmt::skip] inner: RefCell::new(Matrix4::new( *a, *c, 0.0, *e, @@ -2234,15 +2228,18 @@ impl DOMMatrix { 0.0, 0.0, 0.0, 1.0, )), is_2d: Cell::new(true), - }); + } } else if float64.len() == 16 { - return Ok(DOMMatrixReadOnly { + DOMMatrixReadOnly { inner: RefCell::new(Matrix4::from_column_slice(float64.as_slice())), is_2d: Cell::new(false), - }); + } } else { - Err(GeometryError::InvalidSequenceSize) - } + return Err(GeometryError::InvalidSequenceSize); + }; + + let obj = cppgc::make_cppgc_empty_object::(scope); + Ok(cppgc::wrap_object2(scope, obj, (ro, DOMMatrix {}))) } #[fast] @@ -2713,6 +2710,7 @@ impl DOMMatrix { this } + #[rename("scale3dSelf")] #[global] pub fn scale3d_self( &self, From c7945fbe3162cb62b21587e7ef880be108452209 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 20 Jul 2025 04:22:37 +0900 Subject: [PATCH 40/63] wip --- runtime/js/98_global_scope_shared.js | 29 ++++++++++++++++++++++++++++ runtime/js/98_global_scope_window.js | 28 --------------------------- runtime/js/98_global_scope_worker.js | 29 ---------------------------- 3 files changed, 29 insertions(+), 57 deletions(-) diff --git a/runtime/js/98_global_scope_shared.js b/runtime/js/98_global_scope_shared.js index d7554f533a81d1..5c0f9a13d87201 100644 --- a/runtime/js/98_global_scope_shared.js +++ b/runtime/js/98_global_scope_shared.js @@ -35,6 +35,7 @@ import process from "node:process"; import { Buffer } from "node:buffer"; import { clearImmediate, setImmediate } from "node:timers"; import { loadWebGPU } from "ext:deno_webgpu/00_init.js"; +import { loadGeometry } from "ext:deno_geometry/00_init.js"; import * as webgpuSurface from "ext:deno_webgpu/02_surface.js"; import { unstableIds } from "ext:runtime/90_deno_ns.js"; @@ -58,6 +59,34 @@ const windowOrWorkerGlobalScope = { CustomEvent: core.propNonEnumerable(event.CustomEvent), DecompressionStream: core.propNonEnumerable(compression.DecompressionStream), DOMException: core.propNonEnumerable(DOMException), + DOMMatrix: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMMatrix, + loadGeometry, + ), + DOMMatrixReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMMatrixReadOnly, + loadGeometry, + ), + DOMPoint: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMPoint, + loadGeometry, + ), + DOMPointReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMPointReadOnly, + loadGeometry, + ), + DOMQuad: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMQuad, + loadGeometry, + ), + DOMRect: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMRect, + loadGeometry, + ), + DOMRectReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMRectReadOnly, + loadGeometry, + ), ErrorEvent: core.propNonEnumerable(event.ErrorEvent), Event: core.propNonEnumerable(event.Event), EventTarget: core.propNonEnumerable(event.EventTarget), diff --git a/runtime/js/98_global_scope_window.js b/runtime/js/98_global_scope_window.js index 5f28b9c4ccfd32..10df57a06a20b7 100644 --- a/runtime/js/98_global_scope_window.js +++ b/runtime/js/98_global_scope_window.js @@ -124,34 +124,6 @@ const mainRuntimeGlobalProperties = { localStorage: core.propGetterOnly(webStorage.localStorage), sessionStorage: core.propGetterOnly(webStorage.sessionStorage), Storage: core.propNonEnumerable(webStorage.Storage), - DOMMatrix: core.propNonEnumerableLazyLoaded( - (geometry) => geometry.DOMMatrix, - loadGeometry, - ), - DOMMatrixReadOnly: core.propNonEnumerableLazyLoaded( - (geometry) => geometry.DOMMatrixReadOnly, - loadGeometry, - ), - DOMPoint: core.propNonEnumerableLazyLoaded( - (geometry) => geometry.DOMPoint, - loadGeometry, - ), - DOMPointReadOnly: core.propNonEnumerableLazyLoaded( - (geometry) => geometry.DOMPointReadOnly, - loadGeometry, - ), - DOMQuad: core.propNonEnumerableLazyLoaded( - (geometry) => geometry.DOMQuad, - loadGeometry, - ), - DOMRect: core.propNonEnumerableLazyLoaded( - (geometry) => geometry.DOMRect, - loadGeometry, - ), - DOMRectReadOnly: core.propNonEnumerableLazyLoaded( - (geometry) => geometry.DOMRectReadOnly, - loadGeometry, - ), }; export { mainRuntimeGlobalProperties, memoizeLazy }; diff --git a/runtime/js/98_global_scope_worker.js b/runtime/js/98_global_scope_worker.js index 6a5c9befdca0c0..dc53dc8046f3cc 100644 --- a/runtime/js/98_global_scope_worker.js +++ b/runtime/js/98_global_scope_worker.js @@ -17,7 +17,6 @@ import * as console from "ext:deno_console/01_console.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; import * as globalInterfaces from "ext:deno_web/04_global_interfaces.js"; import { loadWebGPU } from "ext:deno_webgpu/00_init.js"; -import { loadGeometry } from "ext:deno_geometry/00_init.js"; function memoizeLazy(f) { let v_ = null; @@ -117,34 +116,6 @@ const workerRuntimeGlobalProperties = { WorkerNavigator: core.propNonEnumerable(WorkerNavigator), navigator: core.propGetterOnly(() => workerNavigator), self: core.propGetterOnly(() => globalThis), - DOMMatrix: core.propNonEnumerableLazyLoaded( - (geometry) => geometry.DOMMatrix, - loadGeometry, - ), - DOMMatrixReadOnly: core.propNonEnumerableLazyLoaded( - (geometry) => geometry.DOMMatrixReadOnly, - loadGeometry, - ), - DOMPoint: core.propNonEnumerableLazyLoaded( - (geometry) => geometry.DOMPoint, - loadGeometry, - ), - DOMPointReadOnly: core.propNonEnumerableLazyLoaded( - (geometry) => geometry.DOMPointReadOnly, - loadGeometry, - ), - DOMQuad: core.propNonEnumerableLazyLoaded( - (geometry) => geometry.DOMQuad, - loadGeometry, - ), - DOMRect: core.propNonEnumerableLazyLoaded( - (geometry) => geometry.DOMRect, - loadGeometry, - ), - DOMRectReadOnly: core.propNonEnumerableLazyLoaded( - (geometry) => geometry.DOMRectReadOnly, - loadGeometry, - ), }; export { workerRuntimeGlobalProperties }; From 8309673ac430289f33f98e58f1ff23ad972f88e9 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 20 Jul 2025 05:50:09 +0900 Subject: [PATCH 41/63] fix --- ext/geometry/01_geometry.js | 6 -- ext/geometry/lib.rs | 83 ++++++++++++++-------------- runtime/js/98_global_scope_shared.js | 2 +- runtime/js/98_global_scope_window.js | 2 - 4 files changed, 44 insertions(+), 49 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 8f9043310139e6..0069ec8ad8fe73 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -15,22 +15,16 @@ import { op_geometry_matrix_to_string, } from "ext:core/ops"; const { - ArrayPrototypeJoin, Float32Array, Float64Array, ObjectDefineProperties, ObjectDefineProperty, ObjectPrototypeIsPrototypeOf, - Symbol, SymbolFor, - SymbolIterator, - TypeError, - TypedArrayPrototypeJoin, } = primordials; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; -import { DOMException } from "ext:deno_web/01_dom_exception.js"; const DOMPointPrototype = DOMPoint.prototype; const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 6e9ffb446ca0b3..5de19e6a147be8 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -212,6 +212,7 @@ impl DOMPointReadOnly { obj } + #[reentrant] pub fn matrix_transform<'a>( &self, scope: &mut v8::HandleScope<'a>, @@ -421,44 +422,24 @@ impl DOMRectReadOnly { self.x.get() } - #[setter] - pub fn x(&self, #[webidl] value: webidl::UnrestrictedDouble) { - self.x.set(*value) - } - #[fast] #[getter] pub fn y(&self) -> f64 { self.y.get() } - #[setter] - pub fn y(&self, #[webidl] value: webidl::UnrestrictedDouble) { - self.y.set(*value) - } - #[fast] #[getter] pub fn width(&self) -> f64 { self.width.get() } - #[setter] - pub fn width(&self, #[webidl] value: webidl::UnrestrictedDouble) { - self.width.set(*value) - } - #[fast] #[getter] pub fn height(&self) -> f64 { self.height.get() } - #[setter] - pub fn height(&self, #[webidl] value: webidl::UnrestrictedDouble) { - self.height.set(*value) - } - #[fast] #[getter] pub fn top(&self) -> f64 { @@ -769,8 +750,11 @@ impl DOMQuad { value: &v8::Global, ) -> cppgc::Ptr { let value = v8::Local::new(scope, value); - cppgc::try_unwrap_cppgc_object::(scope, value.cast()) - .unwrap() + cppgc::try_unwrap_cppgc_proto_object::( + scope, + value.cast(), + ) + .unwrap() } let p1 = get_ptr(scope, &self.p1); @@ -939,27 +923,39 @@ impl DOMMatrixReadOnly { return Ok(DOMMatrixReadOnly::identity()); } + // sequence + if !value.is_string() { + if let Ok(seq) = Vec::::convert( + scope, + value, + prefix, + context, + &Default::default(), + ) { + let seq = seq.into_iter().map(|f| *f).collect::>(); + return DOMMatrixReadOnly::from_sequence_inner(&seq); + } + } + // DOMString - if value.is_string() { + if let Some(value) = value.to_string(scope) { let state = state.borrow_mut::(); if !state.enable_window_features { return Err(GeometryError::DisallowWindowFeatures); } - let value = value.to_string(scope).unwrap(); + let matrix = DOMMatrixReadOnly::identity(); - let Ok(transform_list) = - TransformList::parse_string(&value.to_rust_string_lossy(scope)) - else { - return Err(GeometryError::FailedToParse); - }; - matrix.set_matrix_value_inner(&transform_list)?; + let string = value.to_rust_string_lossy(scope); + if !string.is_empty() { + let Ok(transform_list) = TransformList::parse_string(&string) else { + return Err(GeometryError::FailedToParse); + }; + matrix.set_matrix_value_inner(&transform_list)?; + } return Ok(matrix); } - // sequence - let seq = - Vec::::convert(scope, value, prefix, context, &Default::default())?; - DOMMatrixReadOnly::from_sequence_inner(&seq) + Err(GeometryError::FailedToParse) } fn from_matrix_inner( @@ -1605,6 +1601,7 @@ impl DOMMatrixReadOnly { #[op2(base)] impl DOMMatrixReadOnly { #[constructor] + #[reentrant] #[cppgc] pub fn constructor<'a>( state: &mut OpState, @@ -1640,13 +1637,14 @@ impl DOMMatrixReadOnly { if !value.is_float32_array() { return Err(GeometryError::TypeMismatch); } - let seq = Vec::::convert( + let seq = Vec::::convert( scope, value, "Failed to execute 'DOMMatrixReadOnly.fromFloat32Array'".into(), (|| Cow::Borrowed("Argument 1")).into(), &Default::default(), )?; + let seq = seq.into_iter().map(|f| *f).collect::>(); DOMMatrixReadOnly::from_sequence_inner(&seq) } @@ -1661,13 +1659,14 @@ impl DOMMatrixReadOnly { if !value.is_float64_array() { return Err(GeometryError::TypeMismatch); } - let seq = Vec::::convert( + let seq = Vec::::convert( scope, value, "Failed to execute 'DOMMatrixReadOnly.fromFloat64Array'".into(), (|| Cow::Borrowed("Argument 1")).into(), &Default::default(), )?; + let seq = seq.into_iter().map(|f| *f).collect::>(); DOMMatrixReadOnly::from_sequence_inner(&seq) } @@ -2036,6 +2035,7 @@ impl DOMMatrixReadOnly { cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } + #[reentrant] pub fn transform_point<'a>( &self, scope: &mut v8::HandleScope<'a>, @@ -2129,6 +2129,7 @@ impl GarbageCollected for DOMMatrix { #[op2(inherit = DOMMatrixReadOnly)] impl DOMMatrix { #[constructor] + #[reentrant] #[cppgc] pub fn constructor<'a>( state: &mut OpState, @@ -2168,13 +2169,14 @@ impl DOMMatrix { if !value.is_float32_array() { return Err(GeometryError::TypeMismatch); } - let float64 = Vec::::convert( + let float64 = Vec::::convert( scope, value, "Failed to execute 'DOMMatrixReadOnly.fromFloat32Array'".into(), (|| Cow::Borrowed("Argument 1")).into(), &Default::default(), )?; + let float64 = float64.into_iter().map(|f| *f).collect::>(); let ro = if let [a, b, c, d, e, f] = float64.as_slice() { DOMMatrixReadOnly { @@ -2210,13 +2212,14 @@ impl DOMMatrix { if !value.is_float64_array() { return Err(GeometryError::TypeMismatch); } - let float64 = Vec::::convert( + let float64 = Vec::::convert( scope, value, "Failed to execute 'DOMMatrixReadOnly.fromFloat64Array'".into(), (|| Cow::Borrowed("Argument 1")).into(), &Default::default(), )?; + let float64 = float64.into_iter().map(|f| *f).collect::>(); let ro = if let [a, b, c, d, e, f] = float64.as_slice() { DOMMatrixReadOnly { @@ -2829,7 +2832,7 @@ impl DOMMatrix { ) -> Result, GeometryError> { let lhs = ro.clone(); if let Some(other) = - cppgc::try_unwrap_cppgc_object::(scope, other) + cppgc::try_unwrap_cppgc_proto_object::(scope, other) { ro.multiply_self_inner(&lhs, &other); } else { @@ -2856,7 +2859,7 @@ impl DOMMatrix { ) -> Result, GeometryError> { let rhs = ro.clone(); if let Some(other) = - cppgc::try_unwrap_cppgc_object::(scope, other) + cppgc::try_unwrap_cppgc_proto_object::(scope, other) { ro.multiply_self_inner(&other, &rhs); } else { diff --git a/runtime/js/98_global_scope_shared.js b/runtime/js/98_global_scope_shared.js index 5c0f9a13d87201..1d1397e86b6796 100644 --- a/runtime/js/98_global_scope_shared.js +++ b/runtime/js/98_global_scope_shared.js @@ -59,7 +59,7 @@ const windowOrWorkerGlobalScope = { CustomEvent: core.propNonEnumerable(event.CustomEvent), DecompressionStream: core.propNonEnumerable(compression.DecompressionStream), DOMException: core.propNonEnumerable(DOMException), - DOMMatrix: core.propNonEnumerableLazyLoaded( + DOMMatrix: core.propNonEnumerableLazyLoaded( (geometry) => geometry.DOMMatrix, loadGeometry, ), diff --git a/runtime/js/98_global_scope_window.js b/runtime/js/98_global_scope_window.js index 10df57a06a20b7..a1d4361ffef0ff 100644 --- a/runtime/js/98_global_scope_window.js +++ b/runtime/js/98_global_scope_window.js @@ -15,12 +15,10 @@ const { import * as location from "ext:deno_web/12_location.js"; import * as console from "ext:deno_console/01_console.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; -import { DOMException } from "ext:deno_web/01_dom_exception.js"; import * as globalInterfaces from "ext:deno_web/04_global_interfaces.js"; import * as webStorage from "ext:deno_webstorage/01_webstorage.js"; import * as prompt from "ext:runtime/41_prompt.js"; import { loadWebGPU } from "ext:deno_webgpu/00_init.js"; -import { loadGeometry } from "ext:deno_geometry/00_init.js"; class Navigator { constructor() { From 7f1b5f41c58bd72d37d7fc6159ff6f83c4ee301e Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 20 Jul 2025 05:50:19 +0900 Subject: [PATCH 42/63] update expectation.json --- tests/wpt/runner/expectation.json | 376 ++++++++++++++++++++++-------- 1 file changed, 277 insertions(+), 99 deletions(-) diff --git a/tests/wpt/runner/expectation.json b/tests/wpt/runner/expectation.json index 8e1ce90ab49eef..458b6f1c8674f3 100644 --- a/tests/wpt/runner/expectation.json +++ b/tests/wpt/runner/expectation.json @@ -17831,102 +17831,7 @@ }, "css": { "geometry": { - "DOMMatrix-001.html": [ - "new DOMMatrix(\"none\")", - "new DOMMatrix(\" none\")", - "new DOMMatrix(\"none \")", - "new DOMMatrix(\"NONE\")", - "new DOMMatrix(\"none/**/\")", - "new DOMMatrix(\"/**/none\")", - "new DOMMatrix(\"scale(2) translateX(5px) translateY(5px)\")", - "new DOMMatrix(\"scale(2, 2) translateX(5px) translateY(5px)\")", - "new DOMMatrix(\"scale(2)translateX(5px)translateY(5px)\")", - "new DOMMatrix(\"scale(2) translateX(calc(2 * 2.5px)) translateY(5px)\")", - "new DOMMatrix(\"scale(2) translateX(5px) translateY(5px) rotate(5deg) rotate(-5deg)\")", - "new DOMMatrix(\"translateX (5px)\")", - "new DOMMatrix(\"scale(2 2) translateX(5) translateY(5)\")", - "new DOMMatrix(\"scale(2, 2), translateX(5) ,translateY(5)\")", - "new DOMMatrix(\"translateX(5em)\")", - "new DOMMatrix(\"translateX(5ex)\")", - "new DOMMatrix(\"translateX(5ch)\")", - "new DOMMatrix(\"translateX(5rem)\")", - "new DOMMatrix(\"translateX(5cqw)\")", - "new DOMMatrix(\"translateX(5cqh)\")", - "new DOMMatrix(\"translateX(5cqb)\")", - "new DOMMatrix(\"translateX(5cqi)\")", - "new DOMMatrix(\"translateX(5cqmin)\")", - "new DOMMatrix(\"translateX(5cqmax)\")", - "new DOMMatrix(\"translateX(5vw)\")", - "new DOMMatrix(\"translateX(5vh)\")", - "new DOMMatrix(\"translateX(5vb)\")", - "new DOMMatrix(\"translateX(5vi)\")", - "new DOMMatrix(\"translateX(5vmin)\")", - "new DOMMatrix(\"translateX(5vmax)\")", - "new DOMMatrix(\"translateX(5%)\")", - "new DOMMatrix(\"rotate(5)\")", - "new DOMMatrix(\"rotate(5, 5, 5)\")", - "new DOMMatrix(\"rotate(5, 5px, 5px)\")", - "new DOMMatrix(\"rotate(5deg, 5px, 5px)\")", - "new DOMMatrix(\" \")", - "new DOMMatrix(\"/**/\")", - "new DOMMatrix(\"\\0\")", - "new DOMMatrix(\";\")", - "new DOMMatrix(\"none;\")", - "new DOMMatrix(\"null\")", - "new DOMMatrix(null)", - "new DOMMatrix(\"undefined\")", - "new DOMMatrix(\"inherit\")", - "new DOMMatrix(\"initial\")", - "new DOMMatrix(\"unset\")", - "new DOMMatrix(\"scale(2, 2), translateX(5px) translateY(5px)\")", - "new DOMMatrixReadOnly(\"none\")", - "new DOMMatrixReadOnly(\" none\")", - "new DOMMatrixReadOnly(\"none \")", - "new DOMMatrixReadOnly(\"NONE\")", - "new DOMMatrixReadOnly(\"none/**/\")", - "new DOMMatrixReadOnly(\"/**/none\")", - "new DOMMatrixReadOnly(\"scale(2) translateX(5px) translateY(5px)\")", - "new DOMMatrixReadOnly(\"scale(2, 2) translateX(5px) translateY(5px)\")", - "new DOMMatrixReadOnly(\"scale(2)translateX(5px)translateY(5px)\")", - "new DOMMatrixReadOnly(\"scale(2) translateX(calc(2 * 2.5px)) translateY(5px)\")", - "new DOMMatrixReadOnly(\"scale(2) translateX(5px) translateY(5px) rotate(5deg) rotate(-5deg)\")", - "new DOMMatrixReadOnly(\"translateX (5px)\")", - "new DOMMatrixReadOnly(\"scale(2 2) translateX(5) translateY(5)\")", - "new DOMMatrixReadOnly(\"scale(2, 2), translateX(5) ,translateY(5)\")", - "new DOMMatrixReadOnly(\"translateX(5em)\")", - "new DOMMatrixReadOnly(\"translateX(5ex)\")", - "new DOMMatrixReadOnly(\"translateX(5ch)\")", - "new DOMMatrixReadOnly(\"translateX(5rem)\")", - "new DOMMatrixReadOnly(\"translateX(5cqw)\")", - "new DOMMatrixReadOnly(\"translateX(5cqh)\")", - "new DOMMatrixReadOnly(\"translateX(5cqb)\")", - "new DOMMatrixReadOnly(\"translateX(5cqi)\")", - "new DOMMatrixReadOnly(\"translateX(5cqmin)\")", - "new DOMMatrixReadOnly(\"translateX(5cqmax)\")", - "new DOMMatrixReadOnly(\"translateX(5vw)\")", - "new DOMMatrixReadOnly(\"translateX(5vh)\")", - "new DOMMatrixReadOnly(\"translateX(5vb)\")", - "new DOMMatrixReadOnly(\"translateX(5vi)\")", - "new DOMMatrixReadOnly(\"translateX(5vmin)\")", - "new DOMMatrixReadOnly(\"translateX(5vmax)\")", - "new DOMMatrixReadOnly(\"translateX(5%)\")", - "new DOMMatrixReadOnly(\"rotate(5)\")", - "new DOMMatrixReadOnly(\"rotate(5, 5, 5)\")", - "new DOMMatrixReadOnly(\"rotate(5, 5px, 5px)\")", - "new DOMMatrixReadOnly(\"rotate(5deg, 5px, 5px)\")", - "new DOMMatrixReadOnly(\" \")", - "new DOMMatrixReadOnly(\"/**/\")", - "new DOMMatrixReadOnly(\"\\0\")", - "new DOMMatrixReadOnly(\";\")", - "new DOMMatrixReadOnly(\"none;\")", - "new DOMMatrixReadOnly(\"null\")", - "new DOMMatrixReadOnly(null)", - "new DOMMatrixReadOnly(\"undefined\")", - "new DOMMatrixReadOnly(\"inherit\")", - "new DOMMatrixReadOnly(\"initial\")", - "new DOMMatrixReadOnly(\"unset\")", - "new DOMMatrixReadOnly(\"scale(2, 2), translateX(5px) translateY(5px)\")" - ], + "DOMMatrix-001.html": true, "DOMMatrix-002.html": true, "DOMMatrix-003.html": true, "DOMMatrix-a-f-alias.html": true, @@ -17977,12 +17882,66 @@ "DOMRectList.html": false, "WebKitCSSMatrix.html": false, "WebKitCSSMatrix.worker.html": true, - "historical.html": true, + "historical.html": [ + "DOMMatrixReadOnly scale number of required arguments", + "DOMMatrix scaleSelf number of required arguments", + "DOMMatrixReadOnly translate number of required arguments", + "DOMMatrixReadOnly scale3d number of required arguments", + "DOMMatrixReadOnly rotateFromVector number of required arguments", + "DOMMatrixReadOnly rotateAxisAngle number of required arguments", + "DOMMatrixReadOnly skewX number of required arguments", + "DOMMatrixReadOnly skewY number of required arguments", + "DOMMatrix translateSelf number of required arguments", + "DOMMatrix scale3dSelf number of required arguments", + "DOMMatrix rotateFromVectorSelf number of required arguments", + "DOMMatrix rotateAxisAngleSelf number of required arguments", + "DOMMatrix skewXSelf number of required arguments", + "DOMMatrix skewYSelf number of required arguments", + "DOMPointReadOnly matrixTransform number of required arguments", + "DOMMatrixReadOnly multiply number of required arguments", + "DOMMatrix multiplySelf number of required arguments", + "DOMMatrix preMultiplySelf number of required arguments" + ], "idlharness.any.html": [ "DOMPointReadOnly interface: existence and properties of interface object", + "DOMPointReadOnly interface object length", + "DOMPointReadOnly interface: existence and properties of interface prototype object", + "DOMPointReadOnly interface: operation fromPoint(optional DOMPointInit)", + "DOMPointReadOnly interface: attribute x", + "DOMPointReadOnly interface: attribute y", + "DOMPointReadOnly interface: attribute z", + "DOMPointReadOnly interface: attribute w", + "DOMPointReadOnly interface: operation matrixTransform(optional DOMMatrixInit)", + "DOMPointReadOnly interface: operation toJSON()", "DOMPoint interface: existence and properties of interface object", + "DOMPoint interface object length", + "DOMPoint interface: existence and properties of interface prototype object", + "DOMPoint interface: operation fromPoint(optional DOMPointInit)", + "DOMPoint interface: attribute x", + "DOMPoint interface: attribute y", + "DOMPoint interface: attribute z", + "DOMPoint interface: attribute w", "DOMRectReadOnly interface: existence and properties of interface object", + "DOMRectReadOnly interface object length", + "DOMRectReadOnly interface: existence and properties of interface prototype object", + "DOMRectReadOnly interface: operation fromRect(optional DOMRectInit)", + "DOMRectReadOnly interface: attribute x", + "DOMRectReadOnly interface: attribute y", + "DOMRectReadOnly interface: attribute width", + "DOMRectReadOnly interface: attribute height", + "DOMRectReadOnly interface: attribute top", + "DOMRectReadOnly interface: attribute right", + "DOMRectReadOnly interface: attribute bottom", + "DOMRectReadOnly interface: attribute left", + "DOMRectReadOnly interface: operation toJSON()", "DOMRect interface: existence and properties of interface object", + "DOMRect interface object length", + "DOMRect interface: existence and properties of interface prototype object", + "DOMRect interface: operation fromRect(optional DOMRectInit)", + "DOMRect interface: attribute x", + "DOMRect interface: attribute y", + "DOMRect interface: attribute width", + "DOMRect interface: attribute height", "DOMRectList interface: existence and properties of interface object", "DOMRectList interface object length", "DOMRectList interface object name", @@ -17992,17 +17951,236 @@ "DOMRectList interface: attribute length", "DOMRectList interface: operation item(unsigned long)", "DOMQuad interface: existence and properties of interface object", + "DOMQuad interface object length", + "DOMQuad interface: existence and properties of interface prototype object", + "DOMQuad interface: operation fromRect(optional DOMRectInit)", + "DOMQuad interface: operation fromQuad(optional DOMQuadInit)", + "DOMQuad interface: attribute p1", + "DOMQuad interface: attribute p2", + "DOMQuad interface: attribute p3", + "DOMQuad interface: attribute p4", + "DOMQuad interface: operation getBounds()", + "DOMQuad interface: operation toJSON()", "DOMMatrixReadOnly interface: existence and properties of interface object", - "DOMMatrix interface: existence and properties of interface object" + "DOMMatrixReadOnly interface object length", + "DOMMatrixReadOnly interface: existence and properties of interface prototype object", + "DOMMatrixReadOnly interface: operation fromMatrix(optional DOMMatrixInit)", + "DOMMatrixReadOnly interface: operation fromFloat32Array(Float32Array)", + "DOMMatrixReadOnly interface: operation fromFloat64Array(Float64Array)", + "DOMMatrixReadOnly interface: attribute a", + "DOMMatrixReadOnly interface: attribute b", + "DOMMatrixReadOnly interface: attribute c", + "DOMMatrixReadOnly interface: attribute d", + "DOMMatrixReadOnly interface: attribute e", + "DOMMatrixReadOnly interface: attribute f", + "DOMMatrixReadOnly interface: attribute m11", + "DOMMatrixReadOnly interface: attribute m12", + "DOMMatrixReadOnly interface: attribute m13", + "DOMMatrixReadOnly interface: attribute m14", + "DOMMatrixReadOnly interface: attribute m21", + "DOMMatrixReadOnly interface: attribute m22", + "DOMMatrixReadOnly interface: attribute m23", + "DOMMatrixReadOnly interface: attribute m24", + "DOMMatrixReadOnly interface: attribute m31", + "DOMMatrixReadOnly interface: attribute m32", + "DOMMatrixReadOnly interface: attribute m33", + "DOMMatrixReadOnly interface: attribute m34", + "DOMMatrixReadOnly interface: attribute m41", + "DOMMatrixReadOnly interface: attribute m42", + "DOMMatrixReadOnly interface: attribute m43", + "DOMMatrixReadOnly interface: attribute m44", + "DOMMatrixReadOnly interface: attribute is2D", + "DOMMatrixReadOnly interface: attribute isIdentity", + "DOMMatrixReadOnly interface: operation translate(optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrixReadOnly interface: operation scale(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrixReadOnly interface: operation scaleNonUniform(optional unrestricted double, optional unrestricted double)", + "DOMMatrixReadOnly interface: operation scale3d(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrixReadOnly interface: operation rotate(optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrixReadOnly interface: operation rotateFromVector(optional unrestricted double, optional unrestricted double)", + "DOMMatrixReadOnly interface: operation rotateAxisAngle(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrixReadOnly interface: operation skewX(optional unrestricted double)", + "DOMMatrixReadOnly interface: operation skewY(optional unrestricted double)", + "DOMMatrixReadOnly interface: operation multiply(optional DOMMatrixInit)", + "DOMMatrixReadOnly interface: operation flipX()", + "DOMMatrixReadOnly interface: operation flipY()", + "DOMMatrixReadOnly interface: operation inverse()", + "DOMMatrixReadOnly interface: operation transformPoint(optional DOMPointInit)", + "DOMMatrixReadOnly interface: operation toJSON()", + "DOMMatrix interface: existence and properties of interface object", + "DOMMatrix interface object length", + "DOMMatrix interface: existence and properties of interface prototype object", + "DOMMatrix interface: operation fromMatrix(optional DOMMatrixInit)", + "DOMMatrix interface: operation fromFloat32Array(Float32Array)", + "DOMMatrix interface: operation fromFloat64Array(Float64Array)", + "DOMMatrix interface: attribute a", + "DOMMatrix interface: attribute b", + "DOMMatrix interface: attribute c", + "DOMMatrix interface: attribute d", + "DOMMatrix interface: attribute e", + "DOMMatrix interface: attribute f", + "DOMMatrix interface: attribute m11", + "DOMMatrix interface: attribute m12", + "DOMMatrix interface: attribute m13", + "DOMMatrix interface: attribute m14", + "DOMMatrix interface: attribute m21", + "DOMMatrix interface: attribute m22", + "DOMMatrix interface: attribute m23", + "DOMMatrix interface: attribute m24", + "DOMMatrix interface: attribute m31", + "DOMMatrix interface: attribute m32", + "DOMMatrix interface: attribute m33", + "DOMMatrix interface: attribute m34", + "DOMMatrix interface: attribute m41", + "DOMMatrix interface: attribute m42", + "DOMMatrix interface: attribute m43", + "DOMMatrix interface: attribute m44", + "DOMMatrix interface: operation multiplySelf(optional DOMMatrixInit)", + "DOMMatrix interface: operation preMultiplySelf(optional DOMMatrixInit)", + "DOMMatrix interface: operation translateSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrix interface: operation scaleSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrix interface: operation scale3dSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrix interface: operation rotateSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrix interface: operation rotateFromVectorSelf(optional unrestricted double, optional unrestricted double)", + "DOMMatrix interface: operation rotateAxisAngleSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrix interface: operation skewXSelf(optional unrestricted double)", + "DOMMatrix interface: operation skewYSelf(optional unrestricted double)", + "DOMMatrix interface: operation invertSelf()" ], "idlharness.any.worker.html": [ "DOMPointReadOnly interface: existence and properties of interface object", + "DOMPointReadOnly interface object length", + "DOMPointReadOnly interface: existence and properties of interface prototype object", + "DOMPointReadOnly interface: operation fromPoint(optional DOMPointInit)", + "DOMPointReadOnly interface: attribute x", + "DOMPointReadOnly interface: attribute y", + "DOMPointReadOnly interface: attribute z", + "DOMPointReadOnly interface: attribute w", + "DOMPointReadOnly interface: operation matrixTransform(optional DOMMatrixInit)", + "DOMPointReadOnly interface: operation toJSON()", "DOMPoint interface: existence and properties of interface object", + "DOMPoint interface object length", + "DOMPoint interface: existence and properties of interface prototype object", + "DOMPoint interface: operation fromPoint(optional DOMPointInit)", + "DOMPoint interface: attribute x", + "DOMPoint interface: attribute y", + "DOMPoint interface: attribute z", + "DOMPoint interface: attribute w", "DOMRectReadOnly interface: existence and properties of interface object", + "DOMRectReadOnly interface object length", + "DOMRectReadOnly interface: existence and properties of interface prototype object", + "DOMRectReadOnly interface: operation fromRect(optional DOMRectInit)", + "DOMRectReadOnly interface: attribute x", + "DOMRectReadOnly interface: attribute y", + "DOMRectReadOnly interface: attribute width", + "DOMRectReadOnly interface: attribute height", + "DOMRectReadOnly interface: attribute top", + "DOMRectReadOnly interface: attribute right", + "DOMRectReadOnly interface: attribute bottom", + "DOMRectReadOnly interface: attribute left", + "DOMRectReadOnly interface: operation toJSON()", "DOMRect interface: existence and properties of interface object", + "DOMRect interface object length", + "DOMRect interface: existence and properties of interface prototype object", + "DOMRect interface: operation fromRect(optional DOMRectInit)", + "DOMRect interface: attribute x", + "DOMRect interface: attribute y", + "DOMRect interface: attribute width", + "DOMRect interface: attribute height", "DOMQuad interface: existence and properties of interface object", + "DOMQuad interface object length", + "DOMQuad interface: existence and properties of interface prototype object", + "DOMQuad interface: operation fromRect(optional DOMRectInit)", + "DOMQuad interface: operation fromQuad(optional DOMQuadInit)", + "DOMQuad interface: attribute p1", + "DOMQuad interface: attribute p2", + "DOMQuad interface: attribute p3", + "DOMQuad interface: attribute p4", + "DOMQuad interface: operation getBounds()", + "DOMQuad interface: operation toJSON()", "DOMMatrixReadOnly interface: existence and properties of interface object", - "DOMMatrix interface: existence and properties of interface object" + "DOMMatrixReadOnly interface object length", + "DOMMatrixReadOnly interface: existence and properties of interface prototype object", + "DOMMatrixReadOnly interface: operation fromMatrix(optional DOMMatrixInit)", + "DOMMatrixReadOnly interface: operation fromFloat32Array(Float32Array)", + "DOMMatrixReadOnly interface: operation fromFloat64Array(Float64Array)", + "DOMMatrixReadOnly interface: attribute a", + "DOMMatrixReadOnly interface: attribute b", + "DOMMatrixReadOnly interface: attribute c", + "DOMMatrixReadOnly interface: attribute d", + "DOMMatrixReadOnly interface: attribute e", + "DOMMatrixReadOnly interface: attribute f", + "DOMMatrixReadOnly interface: attribute m11", + "DOMMatrixReadOnly interface: attribute m12", + "DOMMatrixReadOnly interface: attribute m13", + "DOMMatrixReadOnly interface: attribute m14", + "DOMMatrixReadOnly interface: attribute m21", + "DOMMatrixReadOnly interface: attribute m22", + "DOMMatrixReadOnly interface: attribute m23", + "DOMMatrixReadOnly interface: attribute m24", + "DOMMatrixReadOnly interface: attribute m31", + "DOMMatrixReadOnly interface: attribute m32", + "DOMMatrixReadOnly interface: attribute m33", + "DOMMatrixReadOnly interface: attribute m34", + "DOMMatrixReadOnly interface: attribute m41", + "DOMMatrixReadOnly interface: attribute m42", + "DOMMatrixReadOnly interface: attribute m43", + "DOMMatrixReadOnly interface: attribute m44", + "DOMMatrixReadOnly interface: attribute is2D", + "DOMMatrixReadOnly interface: attribute isIdentity", + "DOMMatrixReadOnly interface: operation translate(optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrixReadOnly interface: operation scale(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrixReadOnly interface: operation scaleNonUniform(optional unrestricted double, optional unrestricted double)", + "DOMMatrixReadOnly interface: operation scale3d(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrixReadOnly interface: operation rotate(optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrixReadOnly interface: operation rotateFromVector(optional unrestricted double, optional unrestricted double)", + "DOMMatrixReadOnly interface: operation rotateAxisAngle(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrixReadOnly interface: operation skewX(optional unrestricted double)", + "DOMMatrixReadOnly interface: operation skewY(optional unrestricted double)", + "DOMMatrixReadOnly interface: operation multiply(optional DOMMatrixInit)", + "DOMMatrixReadOnly interface: operation flipX()", + "DOMMatrixReadOnly interface: operation flipY()", + "DOMMatrixReadOnly interface: operation inverse()", + "DOMMatrixReadOnly interface: operation transformPoint(optional DOMPointInit)", + "DOMMatrixReadOnly interface: operation toJSON()", + "DOMMatrix interface: existence and properties of interface object", + "DOMMatrix interface object length", + "DOMMatrix interface: existence and properties of interface prototype object", + "DOMMatrix interface: operation fromMatrix(optional DOMMatrixInit)", + "DOMMatrix interface: operation fromFloat32Array(Float32Array)", + "DOMMatrix interface: operation fromFloat64Array(Float64Array)", + "DOMMatrix interface: attribute a", + "DOMMatrix interface: attribute b", + "DOMMatrix interface: attribute c", + "DOMMatrix interface: attribute d", + "DOMMatrix interface: attribute e", + "DOMMatrix interface: attribute f", + "DOMMatrix interface: attribute m11", + "DOMMatrix interface: attribute m12", + "DOMMatrix interface: attribute m13", + "DOMMatrix interface: attribute m14", + "DOMMatrix interface: attribute m21", + "DOMMatrix interface: attribute m22", + "DOMMatrix interface: attribute m23", + "DOMMatrix interface: attribute m24", + "DOMMatrix interface: attribute m31", + "DOMMatrix interface: attribute m32", + "DOMMatrix interface: attribute m33", + "DOMMatrix interface: attribute m34", + "DOMMatrix interface: attribute m41", + "DOMMatrix interface: attribute m42", + "DOMMatrix interface: attribute m43", + "DOMMatrix interface: attribute m44", + "DOMMatrix interface: operation multiplySelf(optional DOMMatrixInit)", + "DOMMatrix interface: operation preMultiplySelf(optional DOMMatrixInit)", + "DOMMatrix interface: operation translateSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrix interface: operation scaleSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrix interface: operation scale3dSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrix interface: operation rotateSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrix interface: operation rotateFromVectorSelf(optional unrestricted double, optional unrestricted double)", + "DOMMatrix interface: operation rotateAxisAngleSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", + "DOMMatrix interface: operation skewXSelf(optional unrestricted double)", + "DOMMatrix interface: operation skewYSelf(optional unrestricted double)", + "DOMMatrix interface: operation invertSelf()" ], "spec-examples.html": true, "structured-serialization.html": [ From cbb8065d1d3fefd668953b4242b56b038e6e66dc Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 20 Jul 2025 06:31:29 +0900 Subject: [PATCH 43/63] fix --- ext/geometry/lib.rs | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 5de19e6a147be8..e1dd4382a61384 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -1,5 +1,7 @@ // Copyright 2018-2025 the Deno authors. MIT license. +#![allow(clippy::too_many_arguments)] + use std::borrow::Cow; use std::cell::Cell; use std::cell::RefCell; @@ -72,6 +74,12 @@ impl State { } } +#[op2(fast)] +fn op_geometry_get_enable_window_features(state: &mut OpState) -> bool { + let state = state.borrow_mut::(); + state.enable_window_features +} + #[derive(Debug, thiserror::Error, deno_error::JsError)] pub enum GeometryError { #[class(type)] @@ -1048,7 +1056,7 @@ impl DOMMatrixReadOnly { seq: &[f64], ) -> Result { if let [a, b, c, d, e, f] = seq { - return Ok(DOMMatrixReadOnly { + Ok(DOMMatrixReadOnly { #[rustfmt::skip] inner: RefCell::new(Matrix4::new( *a, *c, 0.0, *e, @@ -1057,12 +1065,12 @@ impl DOMMatrixReadOnly { 0.0, 0.0, 0.0, 1.0, )), is_2d: Cell::new(true), - }); + }) } else if seq.len() == 16 { - return Ok(DOMMatrixReadOnly { + Ok(DOMMatrixReadOnly { inner: RefCell::new(Matrix4::from_column_slice(seq)), is_2d: Cell::new(false), - }); + }) } else { Err(GeometryError::InvalidSequenceSize) } @@ -2949,8 +2957,8 @@ pub fn op_geometry_matrix_to_buffer<'a>( return Err(GeometryError::IllegalInvocation); }; let inner = matrix.inner.borrow(); - // SAFETY: in-range access Ok( + // SAFETY: in-range access unsafe { slice::from_raw_parts( inner.as_slice().as_ptr() as *mut u8, @@ -3023,9 +3031,3 @@ pub fn op_geometry_matrix_set_matrix_value<'a>( matrix.set_matrix_value_inner(&transform_list)?; Ok(input) } - -#[op2(fast)] -fn op_geometry_get_enable_window_features(state: &mut OpState) -> bool { - let state = state.borrow_mut::(); - state.enable_window_features -} From d11a658a85b24f38ecedb7192f9aade201cc6fab Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 20 Jul 2025 07:02:52 +0900 Subject: [PATCH 44/63] fix --- cli/tsc/mod.rs | 1 + ext/geometry/lib.rs | 13 ++++++-- tests/unit/geometry_test.ts | 60 ++++++++++++++++++------------------- 3 files changed, 42 insertions(+), 32 deletions(-) diff --git a/cli/tsc/mod.rs b/cli/tsc/mod.rs index 0540b2652fa3b5..f15102dfe64f3a 100644 --- a/cli/tsc/mod.rs +++ b/cli/tsc/mod.rs @@ -191,6 +191,7 @@ pub static LAZILY_LOADED_STATIC_ASSETS: Lazy< ), maybe_compressed_lib!("lib.deno.canvas.d.ts", "lib.deno_canvas.d.ts"), maybe_compressed_lib!("lib.deno.crypto.d.ts", "lib.deno_crypto.d.ts"), + maybe_compressed_lib!("lib.deno.geometry.d.ts", "lib.deno_geometry.d.ts"), maybe_compressed_lib!( "lib.deno.broadcast_channel.d.ts", "lib.deno_broadcast_channel.d.ts" diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index e1dd4382a61384..e040c1ace9277d 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -6,6 +6,7 @@ use std::borrow::Cow; use std::cell::Cell; use std::cell::RefCell; use std::mem; +use std::ptr; use std::slice; use deno_core::GarbageCollected; @@ -2842,7 +2843,11 @@ impl DOMMatrix { if let Some(other) = cppgc::try_unwrap_cppgc_proto_object::(scope, other) { - ro.multiply_self_inner(&lhs, &other); + if ptr::eq(ro, &*other) { + ro.multiply_self_inner(&lhs, &other.clone()); + } else { + ro.multiply_self_inner(&lhs, &other); + }; } else { let other = DOMMatrixInit::convert( scope, @@ -2869,7 +2874,11 @@ impl DOMMatrix { if let Some(other) = cppgc::try_unwrap_cppgc_proto_object::(scope, other) { - ro.multiply_self_inner(&other, &rhs); + if ptr::eq(ro, &*other) { + ro.multiply_self_inner(&other.clone(), &rhs); + } else { + ro.multiply_self_inner(&other, &rhs); + } } else { let other = DOMMatrixInit::convert( scope, diff --git a/tests/unit/geometry_test.ts b/tests/unit/geometry_test.ts index 37ae864411dd77..3ea1806db45724 100644 --- a/tests/unit/geometry_test.ts +++ b/tests/unit/geometry_test.ts @@ -952,7 +952,7 @@ Deno.test(function prototypeOverwrite() { point.x = 1; }, TypeError, - "Illegal invocation", + "expected DOMPoint", ); assertThrows( () => { @@ -960,7 +960,7 @@ Deno.test(function prototypeOverwrite() { point.y = 1; }, TypeError, - "Illegal invocation", + "expected DOMPoint", ); assertThrows( () => { @@ -968,7 +968,7 @@ Deno.test(function prototypeOverwrite() { point.z = 1; }, TypeError, - "Illegal invocation", + "expected DOMPoint", ); assertThrows( () => { @@ -976,7 +976,7 @@ Deno.test(function prototypeOverwrite() { point.w = 1; }, TypeError, - "Illegal invocation", + "expected DOMPoint", ); const rect = new DOMRectReadOnly(); @@ -987,7 +987,7 @@ Deno.test(function prototypeOverwrite() { rect.x = 1; }, TypeError, - "Illegal invocation", + "expected DOMRect", ); assertThrows( () => { @@ -995,7 +995,7 @@ Deno.test(function prototypeOverwrite() { rect.y = 1; }, TypeError, - "Illegal invocation", + "expected DOMRect", ); assertThrows( () => { @@ -1003,7 +1003,7 @@ Deno.test(function prototypeOverwrite() { rect.width = 1; }, TypeError, - "Illegal invocation", + "expected DOMRect", ); assertThrows( () => { @@ -1011,7 +1011,7 @@ Deno.test(function prototypeOverwrite() { rect.height = 1; }, TypeError, - "Illegal invocation", + "expected DOMRect", ); const matrix = new DOMMatrixReadOnly(); @@ -1022,7 +1022,7 @@ Deno.test(function prototypeOverwrite() { matrix.a = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1030,7 +1030,7 @@ Deno.test(function prototypeOverwrite() { matrix.b = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1038,7 +1038,7 @@ Deno.test(function prototypeOverwrite() { matrix.c = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1046,7 +1046,7 @@ Deno.test(function prototypeOverwrite() { matrix.d = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1054,7 +1054,7 @@ Deno.test(function prototypeOverwrite() { matrix.e = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1062,7 +1062,7 @@ Deno.test(function prototypeOverwrite() { matrix.f = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1070,7 +1070,7 @@ Deno.test(function prototypeOverwrite() { matrix.m11 = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1078,7 +1078,7 @@ Deno.test(function prototypeOverwrite() { matrix.m12 = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1086,7 +1086,7 @@ Deno.test(function prototypeOverwrite() { matrix.m13 = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1094,7 +1094,7 @@ Deno.test(function prototypeOverwrite() { matrix.m14 = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1102,7 +1102,7 @@ Deno.test(function prototypeOverwrite() { matrix.m21 = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1110,7 +1110,7 @@ Deno.test(function prototypeOverwrite() { matrix.m22 = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1118,7 +1118,7 @@ Deno.test(function prototypeOverwrite() { matrix.m23 = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1126,7 +1126,7 @@ Deno.test(function prototypeOverwrite() { matrix.m24 = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1134,7 +1134,7 @@ Deno.test(function prototypeOverwrite() { matrix.m31 = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1142,7 +1142,7 @@ Deno.test(function prototypeOverwrite() { matrix.m32 = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1150,7 +1150,7 @@ Deno.test(function prototypeOverwrite() { matrix.m33 = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1158,7 +1158,7 @@ Deno.test(function prototypeOverwrite() { matrix.m34 = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1166,7 +1166,7 @@ Deno.test(function prototypeOverwrite() { matrix.m41 = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1174,7 +1174,7 @@ Deno.test(function prototypeOverwrite() { matrix.m42 = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1182,7 +1182,7 @@ Deno.test(function prototypeOverwrite() { matrix.m43 = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); assertThrows( () => { @@ -1190,6 +1190,6 @@ Deno.test(function prototypeOverwrite() { matrix.m44 = 1; }, TypeError, - "Illegal invocation", + "expected DOMMatrix", ); }); From f4f9f10ee3ceb6795228a8c2aa050558040a0c97 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 20 Jul 2025 20:15:21 +0900 Subject: [PATCH 45/63] tweak --- ext/geometry/lib.rs | 339 ++++++++++++++++++++++++-------------------- 1 file changed, 189 insertions(+), 150 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index e040c1ace9277d..f6310c702faf39 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -149,8 +149,9 @@ impl DOMPointReadOnly { #[op2(base)] impl DOMPointReadOnly { #[constructor] + #[required(0)] #[cppgc] - pub fn constructor( + fn constructor( #[webidl] x: Option, #[webidl] y: Option, #[webidl] z: Option, @@ -167,38 +168,39 @@ impl DOMPointReadOnly { } #[reentrant] + #[required(0)] #[static_method] #[cppgc] - pub fn from_point(#[webidl] init: DOMPointInit) -> DOMPointReadOnly { + fn from_point(#[webidl] init: DOMPointInit) -> DOMPointReadOnly { DOMPointReadOnly::from_point_inner(init) } #[fast] #[getter] - pub fn x(&self) -> f64 { + fn x(&self) -> f64 { self.inner.borrow().x } #[fast] #[getter] - pub fn y(&self) -> f64 { + fn y(&self) -> f64 { self.inner.borrow().y } #[fast] #[getter] - pub fn z(&self) -> f64 { + fn z(&self) -> f64 { self.inner.borrow().z } #[fast] #[getter] - pub fn w(&self) -> f64 { + fn w(&self) -> f64 { self.inner.borrow().w } #[rename("toJSON")] - pub fn to_json<'a>( + fn to_json<'a>( &self, scope: &mut v8::HandleScope<'a>, ) -> v8::Local<'a, v8::Object> { @@ -222,7 +224,8 @@ impl DOMPointReadOnly { } #[reentrant] - pub fn matrix_transform<'a>( + #[required(0)] + fn matrix_transform<'a>( &self, scope: &mut v8::HandleScope<'a>, #[webidl] value: DOMMatrixInit, @@ -248,8 +251,9 @@ impl GarbageCollected for DOMPoint { #[op2(inherit = DOMPointReadOnly)] impl DOMPoint { #[constructor] + #[required(0)] #[cppgc] - pub fn constructor( + fn constructor( #[webidl] x: Option, #[webidl] y: Option, #[webidl] z: Option, @@ -267,8 +271,9 @@ impl DOMPoint { } #[reentrant] + #[required(0)] #[static_method] - pub fn from_point<'a>( + fn from_point<'a>( scope: &mut v8::HandleScope<'a>, #[webidl] init: DOMPointInit, ) -> v8::Local<'a, v8::Object> { @@ -279,12 +284,12 @@ impl DOMPoint { #[fast] #[getter] - pub fn x(&self, #[proto] ro: &DOMPointReadOnly) -> f64 { + fn x(&self, #[proto] ro: &DOMPointReadOnly) -> f64 { ro.inner.borrow().x } #[setter] - pub fn x( + fn x( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMPointReadOnly, @@ -294,12 +299,12 @@ impl DOMPoint { #[fast] #[getter] - pub fn y(&self, #[proto] ro: &DOMPointReadOnly) -> f64 { + fn y(&self, #[proto] ro: &DOMPointReadOnly) -> f64 { ro.inner.borrow().y } #[setter] - pub fn y( + fn y( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMPointReadOnly, @@ -309,12 +314,12 @@ impl DOMPoint { #[fast] #[getter] - pub fn z(&self, #[proto] ro: &DOMPointReadOnly) -> f64 { + fn z(&self, #[proto] ro: &DOMPointReadOnly) -> f64 { ro.inner.borrow().z } #[setter] - pub fn z( + fn z( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMPointReadOnly, @@ -324,12 +329,12 @@ impl DOMPoint { #[fast] #[getter] - pub fn w(&self, #[proto] ro: &DOMPointReadOnly) -> f64 { + fn w(&self, #[proto] ro: &DOMPointReadOnly) -> f64 { ro.inner.borrow().w } #[setter] - pub fn w( + fn w( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMPointReadOnly, @@ -403,8 +408,9 @@ impl DOMRectReadOnly { #[op2(base)] impl DOMRectReadOnly { #[constructor] + #[required(0)] #[cppgc] - pub fn constructor( + fn constructor( #[webidl] x: Option, #[webidl] y: Option, #[webidl] width: Option, @@ -419,62 +425,63 @@ impl DOMRectReadOnly { } #[reentrant] + #[required(0)] #[static_method] #[cppgc] - pub fn from_rect(#[webidl] init: DOMRectInit) -> DOMRectReadOnly { + fn from_rect(#[webidl] init: DOMRectInit) -> DOMRectReadOnly { DOMRectReadOnly::from_rect_inner(init) } #[fast] #[getter] - pub fn x(&self) -> f64 { + fn x(&self) -> f64 { self.x.get() } #[fast] #[getter] - pub fn y(&self) -> f64 { + fn y(&self) -> f64 { self.y.get() } #[fast] #[getter] - pub fn width(&self) -> f64 { + fn width(&self) -> f64 { self.width.get() } #[fast] #[getter] - pub fn height(&self) -> f64 { + fn height(&self) -> f64 { self.height.get() } #[fast] #[getter] - pub fn top(&self) -> f64 { + fn top(&self) -> f64 { self.get_top() } #[fast] #[getter] - pub fn right(&self) -> f64 { + fn right(&self) -> f64 { self.get_right() } #[fast] #[getter] - pub fn bottom(&self) -> f64 { + fn bottom(&self) -> f64 { self.get_bottom() } #[fast] #[getter] - pub fn left(&self) -> f64 { + fn left(&self) -> f64 { self.get_left() } #[rename("toJSON")] - pub fn to_json<'a>( + fn to_json<'a>( &self, scope: &mut v8::HandleScope<'a>, ) -> v8::Local<'a, v8::Object> { @@ -513,8 +520,9 @@ impl GarbageCollected for DOMRect { #[op2(inherit = DOMRectReadOnly)] impl DOMRect { #[constructor] + #[required(0)] #[cppgc] - pub fn constructor( + fn constructor( #[webidl] x: Option, #[webidl] y: Option, #[webidl] width: Option, @@ -530,8 +538,9 @@ impl DOMRect { } #[reentrant] + #[required(0)] #[static_method] - pub fn from_rect<'a>( + fn from_rect<'a>( scope: &mut v8::HandleScope<'a>, #[webidl] init: DOMRectInit, ) -> v8::Local<'a, v8::Object> { @@ -542,12 +551,12 @@ impl DOMRect { #[fast] #[getter] - pub fn x(&self, #[proto] ro: &DOMRectReadOnly) -> f64 { + fn x(&self, #[proto] ro: &DOMRectReadOnly) -> f64 { ro.x.get() } #[setter] - pub fn x( + fn x( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMRectReadOnly, @@ -557,12 +566,12 @@ impl DOMRect { #[fast] #[getter] - pub fn y(&self, #[proto] ro: &DOMRectReadOnly) -> f64 { + fn y(&self, #[proto] ro: &DOMRectReadOnly) -> f64 { ro.y.get() } #[setter] - pub fn y( + fn y( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMRectReadOnly, @@ -572,12 +581,12 @@ impl DOMRect { #[fast] #[getter] - pub fn width(&self, #[proto] ro: &DOMRectReadOnly) -> f64 { + fn width(&self, #[proto] ro: &DOMRectReadOnly) -> f64 { ro.width.get() } #[setter] - pub fn width( + fn width( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMRectReadOnly, @@ -587,12 +596,12 @@ impl DOMRect { #[fast] #[getter] - pub fn height(&self, #[proto] ro: &DOMRectReadOnly) -> f64 { + fn height(&self, #[proto] ro: &DOMRectReadOnly) -> f64 { ro.height.get() } #[setter] - pub fn height( + fn height( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMRectReadOnly, @@ -627,8 +636,9 @@ impl GarbageCollected for DOMQuad { impl DOMQuad { #[constructor] #[reentrant] + #[required(0)] #[cppgc] - pub fn constructor( + fn constructor( scope: &mut v8::HandleScope, #[webidl] p1: DOMPointInit, #[webidl] p2: DOMPointInit, @@ -659,9 +669,10 @@ impl DOMQuad { } #[reentrant] + #[required(0)] #[static_method] #[cppgc] - pub fn from_rect( + fn from_rect( scope: &mut v8::HandleScope, #[webidl] rect: DOMRectInit, ) -> DOMQuad { @@ -696,9 +707,10 @@ impl DOMQuad { } #[reentrant] + #[required(0)] #[static_method] #[cppgc] - pub fn from_quad( + fn from_quad( scope: &mut v8::HandleScope, #[webidl] quad: DOMQuadInit, ) -> DOMQuad { @@ -727,29 +739,29 @@ impl DOMQuad { #[getter] #[global] - pub fn p1(&self) -> v8::Global { + fn p1(&self) -> v8::Global { self.p1.clone() } #[getter] #[global] - pub fn p2(&self) -> v8::Global { + fn p2(&self) -> v8::Global { self.p2.clone() } #[getter] #[global] - pub fn p3(&self) -> v8::Global { + fn p3(&self) -> v8::Global { self.p3.clone() } #[getter] #[global] - pub fn p4(&self) -> v8::Global { + fn p4(&self) -> v8::Global { self.p4.clone() } - pub fn get_bounds<'a>( + fn get_bounds<'a>( &self, scope: &mut v8::HandleScope<'a>, ) -> v8::Local<'a, v8::Object> { @@ -789,7 +801,7 @@ impl DOMQuad { } #[rename("toJSON")] - pub fn to_json<'a>( + fn to_json<'a>( &self, scope: &mut v8::HandleScope<'a>, ) -> v8::Local<'a, v8::Object> { @@ -1611,8 +1623,9 @@ impl DOMMatrixReadOnly { impl DOMMatrixReadOnly { #[constructor] #[reentrant] + #[required(0)] #[cppgc] - pub fn constructor<'a>( + fn constructor<'a>( state: &mut OpState, scope: &mut v8::HandleScope<'a>, value: v8::Local<'a, v8::Value>, @@ -1627,9 +1640,10 @@ impl DOMMatrixReadOnly { } #[reentrant] + #[required(0)] #[static_method] #[cppgc] - pub fn from_matrix( + fn from_matrix( #[webidl] init: DOMMatrixInit, ) -> Result { DOMMatrixReadOnly::from_matrix_inner(&init) @@ -1639,7 +1653,7 @@ impl DOMMatrixReadOnly { #[required(1)] #[static_method] #[cppgc] - pub fn from_float32_array<'a>( + fn from_float32_array<'a>( scope: &mut v8::HandleScope<'a>, value: v8::Local<'a, v8::Value>, ) -> Result { @@ -1661,7 +1675,7 @@ impl DOMMatrixReadOnly { #[required(1)] #[static_method] #[cppgc] - pub fn from_float64_array<'a>( + fn from_float64_array<'a>( scope: &mut v8::HandleScope<'a>, value: v8::Local<'a, v8::Value>, ) -> Result { @@ -1681,149 +1695,150 @@ impl DOMMatrixReadOnly { #[fast] #[getter] - pub fn a(&self) -> f64 { + fn a(&self) -> f64 { self.a_inner() } #[fast] #[getter] - pub fn b(&self) -> f64 { + fn b(&self) -> f64 { self.b_inner() } #[fast] #[getter] - pub fn c(&self) -> f64 { + fn c(&self) -> f64 { self.c_inner() } #[fast] #[getter] - pub fn d(&self) -> f64 { + fn d(&self) -> f64 { self.d_inner() } #[fast] #[getter] - pub fn e(&self) -> f64 { + fn e(&self) -> f64 { self.e_inner() } #[fast] #[getter] - pub fn f(&self) -> f64 { + fn f(&self) -> f64 { self.f_inner() } #[fast] #[getter] - pub fn m11(&self) -> f64 { + fn m11(&self) -> f64 { self.m11_inner() } #[fast] #[getter] - pub fn m12(&self) -> f64 { + fn m12(&self) -> f64 { self.m12_inner() } #[fast] #[getter] - pub fn m13(&self) -> f64 { + fn m13(&self) -> f64 { self.m13_inner() } #[fast] #[getter] - pub fn m14(&self) -> f64 { + fn m14(&self) -> f64 { self.m14_inner() } #[fast] #[getter] - pub fn m21(&self) -> f64 { + fn m21(&self) -> f64 { self.m21_inner() } #[fast] #[getter] - pub fn m22(&self) -> f64 { + fn m22(&self) -> f64 { self.m22_inner() } #[fast] #[getter] - pub fn m23(&self) -> f64 { + fn m23(&self) -> f64 { self.m23_inner() } #[fast] #[getter] - pub fn m24(&self) -> f64 { + fn m24(&self) -> f64 { self.m24_inner() } #[fast] #[getter] - pub fn m31(&self) -> f64 { + fn m31(&self) -> f64 { self.m31_inner() } #[fast] #[getter] - pub fn m32(&self) -> f64 { + fn m32(&self) -> f64 { self.m32_inner() } #[fast] #[getter] - pub fn m33(&self) -> f64 { + fn m33(&self) -> f64 { self.m33_inner() } #[fast] #[getter] - pub fn m34(&self) -> f64 { + fn m34(&self) -> f64 { self.m34_inner() } #[fast] #[getter] - pub fn m41(&self) -> f64 { + fn m41(&self) -> f64 { self.m41_inner() } #[fast] #[getter] - pub fn m42(&self) -> f64 { + fn m42(&self) -> f64 { self.m42_inner() } #[fast] #[getter] - pub fn m43(&self) -> f64 { + fn m43(&self) -> f64 { self.m43_inner() } #[fast] #[getter] - pub fn m44(&self) -> f64 { + fn m44(&self) -> f64 { self.m44_inner() } #[fast] #[getter] - pub fn is_2d(&self) -> bool { + fn is_2d(&self) -> bool { self.is_2d.get() } #[fast] #[getter] - pub fn is_identity(&self) -> bool { + fn is_identity(&self) -> bool { self.is_identity_inner() } - pub fn translate<'a>( + #[required(0)] + fn translate<'a>( &self, scope: &mut v8::HandleScope<'a>, #[webidl] tx: Option, @@ -1839,7 +1854,8 @@ impl DOMMatrixReadOnly { cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - pub fn scale<'a>( + #[required(0)] + fn scale<'a>( &self, scope: &mut v8::HandleScope<'a>, #[webidl] sx: Option, @@ -1866,7 +1882,8 @@ impl DOMMatrixReadOnly { cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - pub fn scale_non_uniform<'a>( + #[required(0)] + fn scale_non_uniform<'a>( &self, scope: &mut v8::HandleScope<'a>, #[webidl] sx: Option, @@ -1881,7 +1898,8 @@ impl DOMMatrixReadOnly { } #[rename("scale3d")] - pub fn scale3d<'a>( + #[required(0)] + fn scale3d<'a>( &self, scope: &mut v8::HandleScope<'a>, #[webidl] scale: Option, @@ -1905,7 +1923,8 @@ impl DOMMatrixReadOnly { cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - pub fn rotate<'a>( + #[required(0)] + fn rotate<'a>( &self, scope: &mut v8::HandleScope<'a>, #[webidl] rotate_x: Option, @@ -1933,7 +1952,8 @@ impl DOMMatrixReadOnly { cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - pub fn rotate_from_vector<'a>( + #[required(0)] + fn rotate_from_vector<'a>( &self, scope: &mut v8::HandleScope<'a>, #[webidl] x: Option, @@ -1947,7 +1967,8 @@ impl DOMMatrixReadOnly { cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - pub fn rotate_axis_angle<'a>( + #[required(0)] + fn rotate_axis_angle<'a>( &self, scope: &mut v8::HandleScope<'a>, #[webidl] x: Option, @@ -1965,7 +1986,8 @@ impl DOMMatrixReadOnly { cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - pub fn skew_x<'a>( + #[required(0)] + fn skew_x<'a>( &self, scope: &mut v8::HandleScope<'a>, #[webidl] x_deg: Option, @@ -1977,7 +1999,8 @@ impl DOMMatrixReadOnly { cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - pub fn skew_y<'a>( + #[required(0)] + fn skew_y<'a>( &self, scope: &mut v8::HandleScope<'a>, #[webidl] y_deg: Option, @@ -1989,7 +2012,8 @@ impl DOMMatrixReadOnly { cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - pub fn multiply<'a>( + #[required(0)] + fn multiply<'a>( &self, scope: &mut v8::HandleScope<'a>, other: v8::Local<'a, v8::Value>, @@ -2014,7 +2038,8 @@ impl DOMMatrixReadOnly { Ok(cppgc::wrap_object2(scope, obj, (out, DOMMatrix {}))) } - pub fn flip_x<'a>( + #[required(0)] + fn flip_x<'a>( &self, scope: &mut v8::HandleScope<'a>, ) -> v8::Local<'a, v8::Object> { @@ -2024,7 +2049,8 @@ impl DOMMatrixReadOnly { cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - pub fn flip_y<'a>( + #[required(0)] + fn flip_y<'a>( &self, scope: &mut v8::HandleScope<'a>, ) -> v8::Local<'a, v8::Object> { @@ -2034,7 +2060,7 @@ impl DOMMatrixReadOnly { cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } - pub fn inverse<'a>( + fn inverse<'a>( &self, scope: &mut v8::HandleScope<'a>, ) -> v8::Local<'a, v8::Object> { @@ -2045,7 +2071,8 @@ impl DOMMatrixReadOnly { } #[reentrant] - pub fn transform_point<'a>( + #[required(0)] + fn transform_point<'a>( &self, scope: &mut v8::HandleScope<'a>, point: v8::Local<'a, v8::Value>, @@ -2073,7 +2100,7 @@ impl DOMMatrixReadOnly { } #[rename("toJSON")] - pub fn to_json<'a>( + fn to_json<'a>( &self, scope: &mut v8::HandleScope<'a>, ) -> v8::Local<'a, v8::Object> { @@ -2139,8 +2166,9 @@ impl GarbageCollected for DOMMatrix { impl DOMMatrix { #[constructor] #[reentrant] + #[required(0)] #[cppgc] - pub fn constructor<'a>( + fn constructor<'a>( state: &mut OpState, scope: &mut v8::HandleScope<'a>, value: v8::Local<'a, v8::Value>, @@ -2158,8 +2186,9 @@ impl DOMMatrix { } #[reentrant] + #[required(0)] #[static_method] - pub fn from_matrix<'a>( + fn from_matrix<'a>( scope: &mut v8::HandleScope<'a>, #[webidl] init: DOMMatrixInit, ) -> Result, GeometryError> { @@ -2171,7 +2200,7 @@ impl DOMMatrix { #[rename("fromFloat32Array")] #[required(1)] #[static_method] - pub fn from_float32_array<'a>( + fn from_float32_array<'a>( scope: &mut v8::HandleScope<'a>, value: v8::Local<'a, v8::Value>, ) -> Result, GeometryError> { @@ -2214,7 +2243,7 @@ impl DOMMatrix { #[rename("fromFloat64Array")] #[required(1)] #[static_method] - pub fn from_float64_array<'a>( + fn from_float64_array<'a>( scope: &mut v8::HandleScope<'a>, value: v8::Local<'a, v8::Value>, ) -> Result, GeometryError> { @@ -2256,12 +2285,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn a(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn a(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.a_inner() } #[setter] - pub fn a( + fn a( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2274,12 +2303,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn b(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn b(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.b_inner() } #[setter] - pub fn b( + fn b( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2292,12 +2321,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn c(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn c(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.c_inner() } #[setter] - pub fn c( + fn c( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2310,12 +2339,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn d(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn d(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.d_inner() } #[setter] - pub fn d( + fn d( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2328,12 +2357,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn e(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn e(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.e_inner() } #[setter] - pub fn e( + fn e( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2346,12 +2375,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn f(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn f(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.f_inner() } #[setter] - pub fn f( + fn f( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2364,12 +2393,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn m11(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn m11(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.m11_inner() } #[setter] - pub fn m11( + fn m11( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2382,12 +2411,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn m12(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn m12(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.m12_inner() } #[setter] - pub fn m12( + fn m12( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2400,12 +2429,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn m13(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn m13(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.m13_inner() } #[setter] - pub fn m13( + fn m13( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2421,12 +2450,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn m14(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn m14(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.m14_inner() } #[setter] - pub fn m14( + fn m14( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2442,12 +2471,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn m21(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn m21(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.m21_inner() } #[setter] - pub fn m21( + fn m21( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2460,12 +2489,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn m22(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn m22(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.m22_inner() } #[setter] - pub fn m22( + fn m22( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2478,12 +2507,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn m23(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn m23(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.m23_inner() } #[setter] - pub fn m23( + fn m23( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2499,12 +2528,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn m24(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn m24(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.m24_inner() } #[setter] - pub fn m24( + fn m24( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2520,12 +2549,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn m31(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn m31(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.m31_inner() } #[setter] - pub fn m31( + fn m31( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2541,12 +2570,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn m32(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn m32(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.m32_inner() } #[setter] - pub fn m32( + fn m32( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2562,12 +2591,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn m33(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn m33(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.m33_inner() } #[setter] - pub fn m33( + fn m33( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2583,12 +2612,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn m34(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn m34(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.m34_inner() } #[setter] - pub fn m34( + fn m34( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2604,12 +2633,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn m41(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn m41(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.m41_inner() } #[setter] - pub fn m41( + fn m41( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2622,12 +2651,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn m42(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn m42(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.m42_inner() } #[setter] - pub fn m42( + fn m42( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2640,12 +2669,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn m43(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn m43(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.m43_inner() } #[setter] - pub fn m43( + fn m43( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2661,12 +2690,12 @@ impl DOMMatrix { #[fast] #[getter] - pub fn m44(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { + fn m44(&self, #[proto] ro: &DOMMatrixReadOnly) -> f64 { ro.m44_inner() } #[setter] - pub fn m44( + fn m44( &self, #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, @@ -2680,8 +2709,9 @@ impl DOMMatrix { } } + #[required(0)] #[global] - pub fn translate_self( + fn translate_self( &self, #[this] this: v8::Global, #[webidl] tx: Option, @@ -2696,8 +2726,9 @@ impl DOMMatrix { this } + #[required(0)] #[global] - pub fn scale_self( + fn scale_self( &self, #[this] this: v8::Global, #[webidl] sx: Option, @@ -2723,8 +2754,9 @@ impl DOMMatrix { } #[rename("scale3dSelf")] + #[required(0)] #[global] - pub fn scale3d_self( + fn scale3d_self( &self, #[this] this: v8::Global, #[webidl] scale: Option, @@ -2747,8 +2779,9 @@ impl DOMMatrix { this } + #[required(0)] #[global] - pub fn rotate_self( + fn rotate_self( &self, #[this] this: v8::Global, #[webidl] rotate_x: Option, @@ -2775,8 +2808,9 @@ impl DOMMatrix { this } + #[required(0)] #[global] - pub fn rotate_from_vector_self( + fn rotate_from_vector_self( &self, #[this] this: v8::Global, #[webidl] x: Option, @@ -2789,8 +2823,9 @@ impl DOMMatrix { this } + #[required(0)] #[global] - pub fn rotate_axis_angle_self( + fn rotate_axis_angle_self( &self, #[this] this: v8::Global, #[webidl] x: Option, @@ -2807,8 +2842,9 @@ impl DOMMatrix { this } + #[required(0)] #[global] - pub fn skew_x_self( + fn skew_x_self( &self, #[this] this: v8::Global, #[webidl] x_deg: Option, @@ -2819,8 +2855,9 @@ impl DOMMatrix { this } + #[required(0)] #[global] - pub fn skew_y_self( + fn skew_y_self( &self, #[this] this: v8::Global, #[webidl] y_deg: Option, @@ -2831,8 +2868,9 @@ impl DOMMatrix { this } + #[required(0)] #[global] - pub fn multiply_self<'a>( + fn multiply_self<'a>( &self, #[this] this: v8::Global, scope: &mut v8::HandleScope<'a>, @@ -2862,8 +2900,9 @@ impl DOMMatrix { Ok(this) } + #[required(0)] #[global] - pub fn pre_multiply_self<'a>( + fn pre_multiply_self<'a>( &self, #[this] this: v8::Global, scope: &mut v8::HandleScope<'a>, @@ -2894,7 +2933,7 @@ impl DOMMatrix { } #[global] - pub fn invert_self( + fn invert_self( &self, #[this] this: v8::Global, #[proto] ro: &DOMMatrixReadOnly, From 3e6252880ea925c65d1446ef30715f04350a19dc Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 2 Aug 2025 01:28:50 +0900 Subject: [PATCH 46/63] chore --- ext/geometry/lib.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index f6310c702faf39..913b4db1ef97fb 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -139,6 +139,7 @@ impl GarbageCollected for DOMPointReadOnly { } impl DOMPointReadOnly { + #[inline] fn from_point_inner(init: DOMPointInit) -> DOMPointReadOnly { DOMPointReadOnly { inner: RefCell::new(Vector4::new(*init.x, *init.y, *init.z, *init.w)), @@ -204,6 +205,7 @@ impl DOMPointReadOnly { &self, scope: &mut v8::HandleScope<'a>, ) -> v8::Local<'a, v8::Object> { + #[inline] fn set( scope: &mut v8::HandleScope, object: &mut v8::Local, @@ -371,6 +373,7 @@ impl GarbageCollected for DOMRectReadOnly { } impl DOMRectReadOnly { + #[inline] fn from_rect_inner(init: DOMRectInit) -> DOMRectReadOnly { DOMRectReadOnly { x: Cell::new(*init.x), @@ -380,24 +383,28 @@ impl DOMRectReadOnly { } } + #[inline] fn get_top(&self) -> f64 { let y = self.y.get(); let height = self.height.get(); minimum(y, y + height) } + #[inline] fn get_right(&self) -> f64 { let x = self.x.get(); let width = self.width.get(); maximum(x, x + width) } + #[inline] fn get_bottom(&self) -> f64 { let y = self.y.get(); let height = self.height.get(); maximum(y, y + height) } + #[inline] fn get_left(&self) -> f64 { let x = self.x.get(); let width = self.width.get(); @@ -2104,6 +2111,7 @@ impl DOMMatrixReadOnly { &self, scope: &mut v8::HandleScope<'a>, ) -> v8::Local<'a, v8::Object> { + #[inline] fn set_f64( scope: &mut v8::HandleScope, object: &mut v8::Local, @@ -2114,6 +2122,8 @@ impl DOMMatrixReadOnly { let value = v8::Number::new(scope, value); object.set(scope, key.into(), value.into()).unwrap(); } + + #[inline] fn set_boolean( scope: &mut v8::HandleScope, object: &mut v8::Local, From ea0ab4f922953ce19e2fbcf6a93f38fce06e1b69 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 2 Aug 2025 01:38:11 +0900 Subject: [PATCH 47/63] chore --- ext/geometry/lib.rs | 127 ++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 75 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 913b4db1ef97fb..39124e7d327fa7 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -205,23 +205,11 @@ impl DOMPointReadOnly { &self, scope: &mut v8::HandleScope<'a>, ) -> v8::Local<'a, v8::Object> { - #[inline] - fn set( - scope: &mut v8::HandleScope, - object: &mut v8::Local, - key: &str, - value: f64, - ) { - let key = v8::String::new(scope, key).unwrap(); - let value = v8::Number::new(scope, value); - object.set(scope, key.into(), value.into()).unwrap(); - } - let mut obj = v8::Object::new(scope); - set(scope, &mut obj, "x", self.inner.borrow().x); - set(scope, &mut obj, "y", self.inner.borrow().y); - set(scope, &mut obj, "z", self.inner.borrow().z); - set(scope, &mut obj, "w", self.inner.borrow().w); + set_f64(scope, &mut obj, "x", self.inner.borrow().x); + set_f64(scope, &mut obj, "y", self.inner.borrow().y); + set_f64(scope, &mut obj, "z", self.inner.borrow().z); + set_f64(scope, &mut obj, "w", self.inner.borrow().w); obj } @@ -492,26 +480,15 @@ impl DOMRectReadOnly { &self, scope: &mut v8::HandleScope<'a>, ) -> v8::Local<'a, v8::Object> { - fn set( - scope: &mut v8::HandleScope, - object: &mut v8::Local, - key: &str, - value: f64, - ) { - let key = v8::String::new(scope, key).unwrap(); - let value = v8::Number::new(scope, value); - object.set(scope, key.into(), value.into()).unwrap(); - } - let mut obj = v8::Object::new(scope); - set(scope, &mut obj, "x", self.x.get()); - set(scope, &mut obj, "y", self.y.get()); - set(scope, &mut obj, "width", self.width.get()); - set(scope, &mut obj, "height", self.height.get()); - set(scope, &mut obj, "top", self.get_top()); - set(scope, &mut obj, "right", self.get_right()); - set(scope, &mut obj, "bottom", self.get_bottom()); - set(scope, &mut obj, "left", self.get_left()); + set_f64(scope, &mut obj, "x", self.x.get()); + set_f64(scope, &mut obj, "y", self.y.get()); + set_f64(scope, &mut obj, "width", self.width.get()); + set_f64(scope, &mut obj, "height", self.height.get()); + set_f64(scope, &mut obj, "top", self.get_top()); + set_f64(scope, &mut obj, "right", self.get_right()); + set_f64(scope, &mut obj, "bottom", self.get_bottom()); + set_f64(scope, &mut obj, "left", self.get_left()); obj } } @@ -812,23 +789,11 @@ impl DOMQuad { &self, scope: &mut v8::HandleScope<'a>, ) -> v8::Local<'a, v8::Object> { - #[inline] - fn set( - scope: &mut v8::HandleScope, - object: &mut v8::Local, - key: &str, - value: v8::Global, - ) { - let key = v8::String::new(scope, key).unwrap(); - let value = v8::Local::new(scope, value); - object.set(scope, key.into(), value.into()).unwrap(); - } - let mut obj = v8::Object::new(scope); - set(scope, &mut obj, "p1", self.p1.clone()); - set(scope, &mut obj, "p2", self.p2.clone()); - set(scope, &mut obj, "p3", self.p3.clone()); - set(scope, &mut obj, "p4", self.p4.clone()); + set_object(scope, &mut obj, "p1", self.p1.clone()); + set_object(scope, &mut obj, "p2", self.p2.clone()); + set_object(scope, &mut obj, "p3", self.p3.clone()); + set_object(scope, &mut obj, "p4", self.p4.clone()); obj } } @@ -2111,30 +2076,6 @@ impl DOMMatrixReadOnly { &self, scope: &mut v8::HandleScope<'a>, ) -> v8::Local<'a, v8::Object> { - #[inline] - fn set_f64( - scope: &mut v8::HandleScope, - object: &mut v8::Local, - key: &str, - value: f64, - ) { - let key = v8::String::new(scope, key).unwrap(); - let value = v8::Number::new(scope, value); - object.set(scope, key.into(), value.into()).unwrap(); - } - - #[inline] - fn set_boolean( - scope: &mut v8::HandleScope, - object: &mut v8::Local, - key: &str, - value: bool, - ) { - let key = v8::String::new(scope, key).unwrap(); - let value = v8::Boolean::new(scope, value); - object.set(scope, key.into(), value.into()).unwrap(); - } - let mut obj = v8::Object::new(scope); set_f64(scope, &mut obj, "a", self.a_inner()); set_f64(scope, &mut obj, "b", self.b_inner()); @@ -2953,6 +2894,42 @@ impl DOMMatrix { } } +#[inline] +fn set_f64( + scope: &mut v8::HandleScope, + object: &mut v8::Local, + key: &str, + value: f64, +) { + let key = v8::String::new(scope, key).unwrap(); + let value = v8::Number::new(scope, value); + object.set(scope, key.into(), value.into()).unwrap(); +} + +#[inline] +fn set_boolean( + scope: &mut v8::HandleScope, + object: &mut v8::Local, + key: &str, + value: bool, +) { + let key = v8::String::new(scope, key).unwrap(); + let value = v8::Boolean::new(scope, value); + object.set(scope, key.into(), value.into()).unwrap(); +} + +#[inline] +fn set_object( + scope: &mut v8::HandleScope, + object: &mut v8::Local, + key: &str, + value: v8::Global, +) { + let key = v8::String::new(scope, key).unwrap(); + let value = v8::Local::new(scope, value); + object.set(scope, key.into(), value.into()).unwrap(); +} + // TODO(petamoriken) Use f64::maximum instead https://github.com/rust-lang/rust/issues/91079 #[inline] fn maximum(a: f64, b: f64) -> f64 { From e14629a08cd74c79db1f47ad9e5e2979a93c1eaa Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 9 Aug 2025 23:28:57 +0900 Subject: [PATCH 48/63] update --- Cargo.lock | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 2 +- 2 files changed, 115 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a1701f9eb2ecfe..8b974f7f308504 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4405,6 +4405,102 @@ dependencies = [ "xml-rs", ] +[[package]] +name = "glam" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "333928d5eb103c5d4050533cec0384302db6be8ef7d3cebd30ec6a35350353da" + +[[package]] +name = "glam" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3abb554f8ee44336b72d522e0a7fe86a29e09f839a36022fa869a7dfe941a54b" + +[[package]] +name = "glam" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4126c0479ccf7e8664c36a2d719f5f2c140fbb4f9090008098d2c291fa5b3f16" + +[[package]] +name = "glam" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01732b97afd8508eee3333a541b9f7610f454bb818669e66e90f5f57c93a776" + +[[package]] +name = "glam" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525a3e490ba77b8e326fb67d4b44b4bd2f920f44d4cc73ccec50adc68e3bee34" + +[[package]] +name = "glam" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b8509e6791516e81c1a630d0bd7fbac36d2fa8712a9da8662e716b52d5051ca" + +[[package]] +name = "glam" +version = "0.20.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43e957e744be03f5801a55472f593d43fabdebf25a4585db250f04d86b1675f" + +[[package]] +name = "glam" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "518faa5064866338b013ff9b2350dc318e14cc4fcd6cb8206d7e7c9886c98815" + +[[package]] +name = "glam" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f597d56c1bd55a811a1be189459e8fad2bbc272616375602443bdfb37fa774" + +[[package]] +name = "glam" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e4afd9ad95555081e109fe1d21f2a30c691b5f0919c67dfa690a2e1eb6bd51c" + +[[package]] +name = "glam" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945" + +[[package]] +name = "glam" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3" + +[[package]] +name = "glam" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e05e7e6723e3455f4818c7b26e855439f7546cf617ef669d1adedb8669e5cb9" + +[[package]] +name = "glam" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "779ae4bf7e8421cf91c0b3b64e7e8b40b862fba4d393f59150042de7c4965a94" + +[[package]] +name = "glam" +version = "0.29.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8babf46d4c1c9d92deac9f7be466f76dfc4482b6452fc5024b5e8daf6ffeb3ee" + +[[package]] +name = "glam" +version = "0.30.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2d1aab06663bdce00d6ca5e5ed586ec8d18033a771906c993a1e3755b368d85" + [[package]] name = "glob" version = "0.3.1" @@ -6028,11 +6124,27 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.33.2" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b" +checksum = "9cd59afb6639828b33677758314a4a1a745c15c02bc597095b851c8fd915cf49" dependencies = [ "approx", + "glam 0.14.0", + "glam 0.15.2", + "glam 0.16.0", + "glam 0.17.3", + "glam 0.18.0", + "glam 0.19.0", + "glam 0.20.5", + "glam 0.21.3", + "glam 0.22.0", + "glam 0.23.0", + "glam 0.24.2", + "glam 0.25.0", + "glam 0.27.0", + "glam 0.28.0", + "glam 0.29.3", + "glam 0.30.5", "matrixmultiply", "num-complex", "num-rational", diff --git a/Cargo.toml b/Cargo.toml index fd2c20e5fab6f8..ffcf0486895d61 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -382,7 +382,7 @@ napi-sys = { version = "=2.2.2", default-features = false } # geometry lightningcss = { version = "1.0.0-alpha.67", default-features = false } -nalgebra = { version = "0.33.2", default-features = false, features = ["std"] } +nalgebra = { version = "0.34.0", default-features = false, features = ["std"] } # webgpu raw-window-handle = "0.6.0" From 5dfc88edee5b54b210c653a6dabfd6edfad9dc74 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 9 Aug 2025 23:39:00 +0900 Subject: [PATCH 49/63] lint --- ext/geometry/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 39124e7d327fa7..47c8ad6c96a7cf 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -917,17 +917,17 @@ impl DOMMatrixReadOnly { } // sequence - if !value.is_string() { - if let Ok(seq) = Vec::::convert( + if !value.is_string() + && let Ok(seq) = Vec::::convert( scope, value, prefix, context, &Default::default(), - ) { - let seq = seq.into_iter().map(|f| *f).collect::>(); - return DOMMatrixReadOnly::from_sequence_inner(&seq); - } + ) + { + let seq = seq.into_iter().map(|f| *f).collect::>(); + return DOMMatrixReadOnly::from_sequence_inner(&seq); } // DOMString From 61cacd12b720193d4b7cba9247d3ddd6b6f271cf Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 16 Aug 2025 14:10:18 +0900 Subject: [PATCH 50/63] fix --- ext/geometry/01_geometry.js | 1 + ext/geometry/lib.rs | 24 +++++++++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 0069ec8ad8fe73..3973cab045736f 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -189,6 +189,7 @@ if (op_geometry_get_enable_window_features()) { const prefix = "Failed to execute 'setMatrixValue' on 'DOMMatrix'"; webidl.requiredArguments(arguments.length, 1, prefix); op_geometry_matrix_set_matrix_value(this, transformList); + return this; }, writable: true, enumerable: true, diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 47c8ad6c96a7cf..48076b7f5d72cd 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -3048,21 +3048,31 @@ pub fn op_geometry_matrix_to_string<'a>( } } -#[op2] +#[op2(fast)] pub fn op_geometry_matrix_set_matrix_value<'a>( scope: &mut v8::HandleScope<'a>, input: v8::Local<'a, v8::Value>, - #[string] transform_list: &str, -) -> Result, GeometryError> { + transform_list: v8::Local<'a, v8::Value>, +) -> Result<(), GeometryError> { if cppgc::try_unwrap_cppgc_proto_object::(scope, input).is_none() { return Err(GeometryError::IllegalInvocation); } let matrix = - cppgc::try_unwrap_cppgc_proto_object::(scope, input) - .unwrap(); - let Ok(transform_list) = TransformList::parse_string(transform_list) else { + cppgc::try_unwrap_cppgc_proto_object::(scope, input) + .unwrap(); + let transform_list = String::convert( + scope, + transform_list, + "Failed to execute 'setMatrixValue' on 'DOMMatrix'".into(), + (|| Cow::Borrowed("Argument 1")).into(), + &Default::default(), + )?; + if transform_list.is_empty() { + return Ok(()); + } + let Ok(transform_list) = TransformList::parse_string(&transform_list) else { return Err(GeometryError::FailedToParse); }; matrix.set_matrix_value_inner(&transform_list)?; - Ok(input) + Ok(()) } From 3047b17f1436774772be1d9d83fea405b1d08a16 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 16 Aug 2025 16:02:25 +0900 Subject: [PATCH 51/63] format --- ext/geometry/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 48076b7f5d72cd..c2922245d237f9 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -3058,8 +3058,8 @@ pub fn op_geometry_matrix_set_matrix_value<'a>( return Err(GeometryError::IllegalInvocation); } let matrix = - cppgc::try_unwrap_cppgc_proto_object::(scope, input) - .unwrap(); + cppgc::try_unwrap_cppgc_proto_object::(scope, input) + .unwrap(); let transform_list = String::convert( scope, transform_list, From 5cc707d3cff21c27c6255a915e736ea9f55b8c14 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 6 Sep 2025 07:28:48 +0900 Subject: [PATCH 52/63] fix --- ext/geometry/lib.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index c2922245d237f9..0022efb43cf079 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -201,6 +201,7 @@ impl DOMPointReadOnly { } #[rename("toJSON")] + #[required(0)] fn to_json<'a>( &self, scope: &mut v8::HandleScope<'a>, @@ -476,6 +477,7 @@ impl DOMRectReadOnly { } #[rename("toJSON")] + #[required(0)] fn to_json<'a>( &self, scope: &mut v8::HandleScope<'a>, @@ -745,6 +747,7 @@ impl DOMQuad { self.p4.clone() } + #[required(0)] fn get_bounds<'a>( &self, scope: &mut v8::HandleScope<'a>, @@ -753,7 +756,7 @@ impl DOMQuad { fn get_ptr( scope: &mut v8::HandleScope, value: &v8::Global, - ) -> cppgc::Ptr { + ) -> cppgc::UnsafePtr { let value = v8::Local::new(scope, value); cppgc::try_unwrap_cppgc_proto_object::( scope, @@ -785,6 +788,7 @@ impl DOMQuad { } #[rename("toJSON")] + #[required(0)] fn to_json<'a>( &self, scope: &mut v8::HandleScope<'a>, @@ -2032,6 +2036,7 @@ impl DOMMatrixReadOnly { cppgc::wrap_object2(scope, obj, (out, DOMMatrix {})) } + #[required(0)] fn inverse<'a>( &self, scope: &mut v8::HandleScope<'a>, @@ -2072,6 +2077,7 @@ impl DOMMatrixReadOnly { } #[rename("toJSON")] + #[required(0)] fn to_json<'a>( &self, scope: &mut v8::HandleScope<'a>, @@ -2883,6 +2889,7 @@ impl DOMMatrix { Ok(this) } + #[required(0)] #[global] fn invert_self( &self, From a92f788c4a07ecffbc55e07a8aadae858b008c03 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 19 Sep 2025 00:24:08 +0900 Subject: [PATCH 53/63] update --- cli/tsc/dts/lib.deno_geometry.d.ts | 41 ++++- ext/geometry/lib.rs | 35 +++- tests/wpt/runner/expectation.json | 265 +---------------------------- 3 files changed, 66 insertions(+), 275 deletions(-) diff --git a/cli/tsc/dts/lib.deno_geometry.d.ts b/cli/tsc/dts/lib.deno_geometry.d.ts index 800993ee4f3976..2fb76ae94dc281 100644 --- a/cli/tsc/dts/lib.deno_geometry.d.ts +++ b/cli/tsc/dts/lib.deno_geometry.d.ts @@ -5,7 +5,10 @@ /// /// -/** @category Geometry Interfaces Module API */ +/** + * @category Geometry Interfaces Module API + * @experimental + */ interface DOMMatrix2DInit { a?: number; b?: number; @@ -21,7 +24,10 @@ interface DOMMatrix2DInit { m42?: number; } -/** @category Geometry Interfaces Module API */ +/** + * @category Geometry Interfaces Module API + * @experimental + */ interface DOMMatrixInit extends DOMMatrix2DInit { is2D?: boolean; m13?: number; @@ -48,6 +54,7 @@ interface DOMMatrixInit extends DOMMatrix2DInit { * ``` * * @category Geometry Interfaces Module API + * @experimental */ interface DOMMatrix extends DOMMatrixReadOnly { a: number; @@ -202,6 +209,7 @@ interface DOMMatrix extends DOMMatrixReadOnly { * ``` * * @category Geometry Interfaces Module API + * @experimental */ declare var DOMMatrix: { prototype: DOMMatrix; @@ -226,6 +234,7 @@ declare var DOMMatrix: { * ``` * * @category Geometry Interfaces Module API + * @experimental */ interface DOMMatrixReadOnly { readonly a: number; @@ -405,19 +414,23 @@ interface DOMMatrixReadOnly { * ``` * * @category Geometry Interfaces Module API + * @experimental */ declare var DOMMatrixReadOnly: { prototype: DOMMatrixReadOnly; new (init?: number[]): DOMMatrixReadOnly; new (init: DOMMatrix | DOMMatrixReadOnly): DOMMatrixReadOnly; - /** Not available in Worker */ + /** NOTE: Not available in Worker */ new (init: string): DOMMatrixReadOnly; fromFloat32Array(array32: Float32Array): DOMMatrixReadOnly; fromFloat64Array(array64: Float64Array): DOMMatrixReadOnly; fromMatrix(other?: DOMMatrixInit): DOMMatrixReadOnly; }; -/** @category Geometry Interfaces Module API */ +/** + * @category Geometry Interfaces Module API + * @experimental + */ interface DOMPointInit { w?: number; x?: number; @@ -430,6 +443,7 @@ interface DOMPointInit { * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPoint) * * @category Geometry Interfaces Module API + * @experimental */ interface DOMPoint extends DOMPointReadOnly { w: number; @@ -443,6 +457,7 @@ interface DOMPoint extends DOMPointReadOnly { * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPoint) * * @category Geometry Interfaces Module API + * @experimental */ declare var DOMPoint: { prototype: DOMPoint; @@ -455,6 +470,7 @@ declare var DOMPoint: { * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly) * * @category Geometry Interfaces Module API + * @experimental */ interface DOMPointReadOnly { readonly w: number; @@ -475,6 +491,7 @@ interface DOMPointReadOnly { * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly) * * @category Geometry Interfaces Module API + * @experimental */ declare var DOMPointReadOnly: { prototype: DOMPointReadOnly; @@ -482,7 +499,10 @@ declare var DOMPointReadOnly: { fromPoint(other?: DOMPointInit): DOMPointReadOnly; }; -/** @category Geometry Interfaces Module API */ +/** + * @category Geometry Interfaces Module API + * @experimental + */ interface DOMQuadInit { p1?: DOMPointInit; p2?: DOMPointInit; @@ -495,6 +515,7 @@ interface DOMQuadInit { * [MDN](https://developer.mozilla.org/docs/Web/API/DOMQuad) * * @category Geometry Interfaces Module API + * @experimental */ interface DOMQuad { readonly p1: DOMPoint; @@ -515,6 +536,7 @@ interface DOMQuad { * [MDN](https://developer.mozilla.org/docs/Web/API/DOMQuad) * * @category Geometry Interfaces Module API + * @experimental */ declare var DOMQuad: { prototype: DOMQuad; @@ -528,7 +550,10 @@ declare var DOMQuad: { fromRect(other?: DOMRectInit): DOMQuad; }; -/** @category Geometry Interfaces Module API */ +/** + * @category Geometry Interfaces Module API + * @experimental + */ interface DOMRectInit { height?: number; width?: number; @@ -540,6 +565,7 @@ interface DOMRectInit { * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRect) * * @category Geometry Interfaces Module API + * @experimental */ interface DOMRect extends DOMRectReadOnly { height: number; @@ -552,6 +578,7 @@ interface DOMRect extends DOMRectReadOnly { * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRect) * * @category Geometry Interfaces Module API + * @experimental */ declare var DOMRect: { prototype: DOMRect; @@ -563,6 +590,7 @@ declare var DOMRect: { * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly) * * @category Geometry Interfaces Module API + * @experimental */ interface DOMRectReadOnly { readonly bottom: number; @@ -589,6 +617,7 @@ interface DOMRectReadOnly { * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly) * * @category Geometry Interfaces Module API + * @experimental */ declare var DOMRectReadOnly: { prototype: DOMRectReadOnly; diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 0022efb43cf079..fec218d007379a 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -132,7 +132,10 @@ pub struct DOMPointReadOnly { inner: RefCell>, } -impl GarbageCollected for DOMPointReadOnly { +// SAFETY: we're sure `DOMPointReadOnly` can be GCed +unsafe impl GarbageCollected for DOMPointReadOnly { + fn trace(&self, _visitor: &mut deno_core::v8::cppgc::Visitor) {} + fn get_name(&self) -> &'static std::ffi::CStr { c"DOMPointReadOnly" } @@ -233,7 +236,10 @@ impl DOMPointReadOnly { pub struct DOMPoint {} -impl GarbageCollected for DOMPoint { +// SAFETY: we're sure `DOMPoint` can be GCed +unsafe impl GarbageCollected for DOMPoint { + fn trace(&self, _visitor: &mut deno_core::v8::cppgc::Visitor) {} + fn get_name(&self) -> &'static std::ffi::CStr { c"DOMPoint" } @@ -355,7 +361,10 @@ pub struct DOMRectReadOnly { height: Cell, } -impl GarbageCollected for DOMRectReadOnly { +// SAFETY: we're sure `DOMRectReadOnly` can be GCed +unsafe impl GarbageCollected for DOMRectReadOnly { + fn trace(&self, _visitor: &mut deno_core::v8::cppgc::Visitor) {} + fn get_name(&self) -> &'static std::ffi::CStr { c"DOMRectReadOnly" } @@ -497,7 +506,10 @@ impl DOMRectReadOnly { pub struct DOMRect {} -impl GarbageCollected for DOMRect { +// SAFETY: we're sure `DOMRect` can be GCed +unsafe impl GarbageCollected for DOMRect { + fn trace(&self, _visitor: &mut deno_core::v8::cppgc::Visitor) {} + fn get_name(&self) -> &'static std::ffi::CStr { c"DOMRect" } @@ -612,7 +624,10 @@ pub struct DOMQuad { p4: v8::Global, } -impl GarbageCollected for DOMQuad { +// SAFETY: we're sure `DOMQuad` can be GCed +unsafe impl GarbageCollected for DOMQuad { + fn trace(&self, _visitor: &mut deno_core::v8::cppgc::Visitor) {} + fn get_name(&self) -> &'static std::ffi::CStr { c"DOMQuad" } @@ -859,7 +874,10 @@ pub struct DOMMatrixReadOnly { is_2d: Cell, } -impl GarbageCollected for DOMMatrixReadOnly { +// SAFETY: we're sure `DOMMatrixReadOnly` can be GCed +unsafe impl GarbageCollected for DOMMatrixReadOnly { + fn trace(&self, _visitor: &mut deno_core::v8::cppgc::Visitor) {} + fn get_name(&self) -> &'static std::ffi::CStr { c"DOMMatrixReadOnly" } @@ -2113,7 +2131,10 @@ impl DOMMatrixReadOnly { pub struct DOMMatrix {} -impl GarbageCollected for DOMMatrix { +// SAFETY: we're sure `DOMMatrix` can be GCed +unsafe impl GarbageCollected for DOMMatrix { + fn trace(&self, _visitor: &mut deno_core::v8::cppgc::Visitor) {} + fn get_name(&self) -> &'static std::ffi::CStr { c"DOMMatrix" } diff --git a/tests/wpt/runner/expectation.json b/tests/wpt/runner/expectation.json index 6f516f7ba7d0a2..41f41271db7807 100644 --- a/tests/wpt/runner/expectation.json +++ b/tests/wpt/runner/expectation.json @@ -17882,66 +17882,16 @@ "DOMRectList.html": false, "WebKitCSSMatrix.html": false, "WebKitCSSMatrix.worker.html": true, - "historical.html": [ - "DOMMatrixReadOnly scale number of required arguments", - "DOMMatrix scaleSelf number of required arguments", - "DOMMatrixReadOnly translate number of required arguments", - "DOMMatrixReadOnly scale3d number of required arguments", - "DOMMatrixReadOnly rotateFromVector number of required arguments", - "DOMMatrixReadOnly rotateAxisAngle number of required arguments", - "DOMMatrixReadOnly skewX number of required arguments", - "DOMMatrixReadOnly skewY number of required arguments", - "DOMMatrix translateSelf number of required arguments", - "DOMMatrix scale3dSelf number of required arguments", - "DOMMatrix rotateFromVectorSelf number of required arguments", - "DOMMatrix rotateAxisAngleSelf number of required arguments", - "DOMMatrix skewXSelf number of required arguments", - "DOMMatrix skewYSelf number of required arguments", - "DOMPointReadOnly matrixTransform number of required arguments", - "DOMMatrixReadOnly multiply number of required arguments", - "DOMMatrix multiplySelf number of required arguments", - "DOMMatrix preMultiplySelf number of required arguments" - ], + "historical.html": true, "idlharness.any.html": [ "DOMPointReadOnly interface: existence and properties of interface object", - "DOMPointReadOnly interface object length", "DOMPointReadOnly interface: existence and properties of interface prototype object", - "DOMPointReadOnly interface: operation fromPoint(optional DOMPointInit)", - "DOMPointReadOnly interface: attribute x", - "DOMPointReadOnly interface: attribute y", - "DOMPointReadOnly interface: attribute z", - "DOMPointReadOnly interface: attribute w", - "DOMPointReadOnly interface: operation matrixTransform(optional DOMMatrixInit)", - "DOMPointReadOnly interface: operation toJSON()", "DOMPoint interface: existence and properties of interface object", - "DOMPoint interface object length", "DOMPoint interface: existence and properties of interface prototype object", - "DOMPoint interface: operation fromPoint(optional DOMPointInit)", - "DOMPoint interface: attribute x", - "DOMPoint interface: attribute y", - "DOMPoint interface: attribute z", - "DOMPoint interface: attribute w", "DOMRectReadOnly interface: existence and properties of interface object", - "DOMRectReadOnly interface object length", "DOMRectReadOnly interface: existence and properties of interface prototype object", - "DOMRectReadOnly interface: operation fromRect(optional DOMRectInit)", - "DOMRectReadOnly interface: attribute x", - "DOMRectReadOnly interface: attribute y", - "DOMRectReadOnly interface: attribute width", - "DOMRectReadOnly interface: attribute height", - "DOMRectReadOnly interface: attribute top", - "DOMRectReadOnly interface: attribute right", - "DOMRectReadOnly interface: attribute bottom", - "DOMRectReadOnly interface: attribute left", - "DOMRectReadOnly interface: operation toJSON()", "DOMRect interface: existence and properties of interface object", - "DOMRect interface object length", "DOMRect interface: existence and properties of interface prototype object", - "DOMRect interface: operation fromRect(optional DOMRectInit)", - "DOMRect interface: attribute x", - "DOMRect interface: attribute y", - "DOMRect interface: attribute width", - "DOMRect interface: attribute height", "DOMRectList interface: existence and properties of interface object", "DOMRectList interface object length", "DOMRectList interface object name", @@ -17951,236 +17901,27 @@ "DOMRectList interface: attribute length", "DOMRectList interface: operation item(unsigned long)", "DOMQuad interface: existence and properties of interface object", - "DOMQuad interface object length", "DOMQuad interface: existence and properties of interface prototype object", - "DOMQuad interface: operation fromRect(optional DOMRectInit)", - "DOMQuad interface: operation fromQuad(optional DOMQuadInit)", - "DOMQuad interface: attribute p1", - "DOMQuad interface: attribute p2", - "DOMQuad interface: attribute p3", - "DOMQuad interface: attribute p4", - "DOMQuad interface: operation getBounds()", - "DOMQuad interface: operation toJSON()", "DOMMatrixReadOnly interface: existence and properties of interface object", - "DOMMatrixReadOnly interface object length", "DOMMatrixReadOnly interface: existence and properties of interface prototype object", - "DOMMatrixReadOnly interface: operation fromMatrix(optional DOMMatrixInit)", - "DOMMatrixReadOnly interface: operation fromFloat32Array(Float32Array)", - "DOMMatrixReadOnly interface: operation fromFloat64Array(Float64Array)", - "DOMMatrixReadOnly interface: attribute a", - "DOMMatrixReadOnly interface: attribute b", - "DOMMatrixReadOnly interface: attribute c", - "DOMMatrixReadOnly interface: attribute d", - "DOMMatrixReadOnly interface: attribute e", - "DOMMatrixReadOnly interface: attribute f", - "DOMMatrixReadOnly interface: attribute m11", - "DOMMatrixReadOnly interface: attribute m12", - "DOMMatrixReadOnly interface: attribute m13", - "DOMMatrixReadOnly interface: attribute m14", - "DOMMatrixReadOnly interface: attribute m21", - "DOMMatrixReadOnly interface: attribute m22", - "DOMMatrixReadOnly interface: attribute m23", - "DOMMatrixReadOnly interface: attribute m24", - "DOMMatrixReadOnly interface: attribute m31", - "DOMMatrixReadOnly interface: attribute m32", - "DOMMatrixReadOnly interface: attribute m33", - "DOMMatrixReadOnly interface: attribute m34", - "DOMMatrixReadOnly interface: attribute m41", - "DOMMatrixReadOnly interface: attribute m42", - "DOMMatrixReadOnly interface: attribute m43", - "DOMMatrixReadOnly interface: attribute m44", - "DOMMatrixReadOnly interface: attribute is2D", - "DOMMatrixReadOnly interface: attribute isIdentity", - "DOMMatrixReadOnly interface: operation translate(optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrixReadOnly interface: operation scale(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrixReadOnly interface: operation scaleNonUniform(optional unrestricted double, optional unrestricted double)", - "DOMMatrixReadOnly interface: operation scale3d(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrixReadOnly interface: operation rotate(optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrixReadOnly interface: operation rotateFromVector(optional unrestricted double, optional unrestricted double)", - "DOMMatrixReadOnly interface: operation rotateAxisAngle(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrixReadOnly interface: operation skewX(optional unrestricted double)", - "DOMMatrixReadOnly interface: operation skewY(optional unrestricted double)", - "DOMMatrixReadOnly interface: operation multiply(optional DOMMatrixInit)", - "DOMMatrixReadOnly interface: operation flipX()", - "DOMMatrixReadOnly interface: operation flipY()", - "DOMMatrixReadOnly interface: operation inverse()", - "DOMMatrixReadOnly interface: operation transformPoint(optional DOMPointInit)", - "DOMMatrixReadOnly interface: operation toJSON()", "DOMMatrix interface: existence and properties of interface object", - "DOMMatrix interface object length", - "DOMMatrix interface: existence and properties of interface prototype object", - "DOMMatrix interface: operation fromMatrix(optional DOMMatrixInit)", - "DOMMatrix interface: operation fromFloat32Array(Float32Array)", - "DOMMatrix interface: operation fromFloat64Array(Float64Array)", - "DOMMatrix interface: attribute a", - "DOMMatrix interface: attribute b", - "DOMMatrix interface: attribute c", - "DOMMatrix interface: attribute d", - "DOMMatrix interface: attribute e", - "DOMMatrix interface: attribute f", - "DOMMatrix interface: attribute m11", - "DOMMatrix interface: attribute m12", - "DOMMatrix interface: attribute m13", - "DOMMatrix interface: attribute m14", - "DOMMatrix interface: attribute m21", - "DOMMatrix interface: attribute m22", - "DOMMatrix interface: attribute m23", - "DOMMatrix interface: attribute m24", - "DOMMatrix interface: attribute m31", - "DOMMatrix interface: attribute m32", - "DOMMatrix interface: attribute m33", - "DOMMatrix interface: attribute m34", - "DOMMatrix interface: attribute m41", - "DOMMatrix interface: attribute m42", - "DOMMatrix interface: attribute m43", - "DOMMatrix interface: attribute m44", - "DOMMatrix interface: operation multiplySelf(optional DOMMatrixInit)", - "DOMMatrix interface: operation preMultiplySelf(optional DOMMatrixInit)", - "DOMMatrix interface: operation translateSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrix interface: operation scaleSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrix interface: operation scale3dSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrix interface: operation rotateSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrix interface: operation rotateFromVectorSelf(optional unrestricted double, optional unrestricted double)", - "DOMMatrix interface: operation rotateAxisAngleSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrix interface: operation skewXSelf(optional unrestricted double)", - "DOMMatrix interface: operation skewYSelf(optional unrestricted double)", - "DOMMatrix interface: operation invertSelf()" + "DOMMatrix interface: existence and properties of interface prototype object" ], "idlharness.any.worker.html": [ "DOMPointReadOnly interface: existence and properties of interface object", - "DOMPointReadOnly interface object length", "DOMPointReadOnly interface: existence and properties of interface prototype object", - "DOMPointReadOnly interface: operation fromPoint(optional DOMPointInit)", - "DOMPointReadOnly interface: attribute x", - "DOMPointReadOnly interface: attribute y", - "DOMPointReadOnly interface: attribute z", - "DOMPointReadOnly interface: attribute w", - "DOMPointReadOnly interface: operation matrixTransform(optional DOMMatrixInit)", - "DOMPointReadOnly interface: operation toJSON()", "DOMPoint interface: existence and properties of interface object", - "DOMPoint interface object length", "DOMPoint interface: existence and properties of interface prototype object", - "DOMPoint interface: operation fromPoint(optional DOMPointInit)", - "DOMPoint interface: attribute x", - "DOMPoint interface: attribute y", - "DOMPoint interface: attribute z", - "DOMPoint interface: attribute w", "DOMRectReadOnly interface: existence and properties of interface object", - "DOMRectReadOnly interface object length", "DOMRectReadOnly interface: existence and properties of interface prototype object", - "DOMRectReadOnly interface: operation fromRect(optional DOMRectInit)", - "DOMRectReadOnly interface: attribute x", - "DOMRectReadOnly interface: attribute y", - "DOMRectReadOnly interface: attribute width", - "DOMRectReadOnly interface: attribute height", - "DOMRectReadOnly interface: attribute top", - "DOMRectReadOnly interface: attribute right", - "DOMRectReadOnly interface: attribute bottom", - "DOMRectReadOnly interface: attribute left", - "DOMRectReadOnly interface: operation toJSON()", "DOMRect interface: existence and properties of interface object", - "DOMRect interface object length", "DOMRect interface: existence and properties of interface prototype object", - "DOMRect interface: operation fromRect(optional DOMRectInit)", - "DOMRect interface: attribute x", - "DOMRect interface: attribute y", - "DOMRect interface: attribute width", - "DOMRect interface: attribute height", "DOMQuad interface: existence and properties of interface object", - "DOMQuad interface object length", "DOMQuad interface: existence and properties of interface prototype object", - "DOMQuad interface: operation fromRect(optional DOMRectInit)", - "DOMQuad interface: operation fromQuad(optional DOMQuadInit)", - "DOMQuad interface: attribute p1", - "DOMQuad interface: attribute p2", - "DOMQuad interface: attribute p3", - "DOMQuad interface: attribute p4", - "DOMQuad interface: operation getBounds()", - "DOMQuad interface: operation toJSON()", "DOMMatrixReadOnly interface: existence and properties of interface object", - "DOMMatrixReadOnly interface object length", "DOMMatrixReadOnly interface: existence and properties of interface prototype object", - "DOMMatrixReadOnly interface: operation fromMatrix(optional DOMMatrixInit)", - "DOMMatrixReadOnly interface: operation fromFloat32Array(Float32Array)", - "DOMMatrixReadOnly interface: operation fromFloat64Array(Float64Array)", - "DOMMatrixReadOnly interface: attribute a", - "DOMMatrixReadOnly interface: attribute b", - "DOMMatrixReadOnly interface: attribute c", - "DOMMatrixReadOnly interface: attribute d", - "DOMMatrixReadOnly interface: attribute e", - "DOMMatrixReadOnly interface: attribute f", - "DOMMatrixReadOnly interface: attribute m11", - "DOMMatrixReadOnly interface: attribute m12", - "DOMMatrixReadOnly interface: attribute m13", - "DOMMatrixReadOnly interface: attribute m14", - "DOMMatrixReadOnly interface: attribute m21", - "DOMMatrixReadOnly interface: attribute m22", - "DOMMatrixReadOnly interface: attribute m23", - "DOMMatrixReadOnly interface: attribute m24", - "DOMMatrixReadOnly interface: attribute m31", - "DOMMatrixReadOnly interface: attribute m32", - "DOMMatrixReadOnly interface: attribute m33", - "DOMMatrixReadOnly interface: attribute m34", - "DOMMatrixReadOnly interface: attribute m41", - "DOMMatrixReadOnly interface: attribute m42", - "DOMMatrixReadOnly interface: attribute m43", - "DOMMatrixReadOnly interface: attribute m44", - "DOMMatrixReadOnly interface: attribute is2D", - "DOMMatrixReadOnly interface: attribute isIdentity", - "DOMMatrixReadOnly interface: operation translate(optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrixReadOnly interface: operation scale(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrixReadOnly interface: operation scaleNonUniform(optional unrestricted double, optional unrestricted double)", - "DOMMatrixReadOnly interface: operation scale3d(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrixReadOnly interface: operation rotate(optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrixReadOnly interface: operation rotateFromVector(optional unrestricted double, optional unrestricted double)", - "DOMMatrixReadOnly interface: operation rotateAxisAngle(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrixReadOnly interface: operation skewX(optional unrestricted double)", - "DOMMatrixReadOnly interface: operation skewY(optional unrestricted double)", - "DOMMatrixReadOnly interface: operation multiply(optional DOMMatrixInit)", - "DOMMatrixReadOnly interface: operation flipX()", - "DOMMatrixReadOnly interface: operation flipY()", - "DOMMatrixReadOnly interface: operation inverse()", - "DOMMatrixReadOnly interface: operation transformPoint(optional DOMPointInit)", - "DOMMatrixReadOnly interface: operation toJSON()", "DOMMatrix interface: existence and properties of interface object", - "DOMMatrix interface object length", - "DOMMatrix interface: existence and properties of interface prototype object", - "DOMMatrix interface: operation fromMatrix(optional DOMMatrixInit)", - "DOMMatrix interface: operation fromFloat32Array(Float32Array)", - "DOMMatrix interface: operation fromFloat64Array(Float64Array)", - "DOMMatrix interface: attribute a", - "DOMMatrix interface: attribute b", - "DOMMatrix interface: attribute c", - "DOMMatrix interface: attribute d", - "DOMMatrix interface: attribute e", - "DOMMatrix interface: attribute f", - "DOMMatrix interface: attribute m11", - "DOMMatrix interface: attribute m12", - "DOMMatrix interface: attribute m13", - "DOMMatrix interface: attribute m14", - "DOMMatrix interface: attribute m21", - "DOMMatrix interface: attribute m22", - "DOMMatrix interface: attribute m23", - "DOMMatrix interface: attribute m24", - "DOMMatrix interface: attribute m31", - "DOMMatrix interface: attribute m32", - "DOMMatrix interface: attribute m33", - "DOMMatrix interface: attribute m34", - "DOMMatrix interface: attribute m41", - "DOMMatrix interface: attribute m42", - "DOMMatrix interface: attribute m43", - "DOMMatrix interface: attribute m44", - "DOMMatrix interface: operation multiplySelf(optional DOMMatrixInit)", - "DOMMatrix interface: operation preMultiplySelf(optional DOMMatrixInit)", - "DOMMatrix interface: operation translateSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrix interface: operation scaleSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrix interface: operation scale3dSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrix interface: operation rotateSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrix interface: operation rotateFromVectorSelf(optional unrestricted double, optional unrestricted double)", - "DOMMatrix interface: operation rotateAxisAngleSelf(optional unrestricted double, optional unrestricted double, optional unrestricted double, optional unrestricted double)", - "DOMMatrix interface: operation skewXSelf(optional unrestricted double)", - "DOMMatrix interface: operation skewYSelf(optional unrestricted double)", - "DOMMatrix interface: operation invertSelf()" + "DOMMatrix interface: existence and properties of interface prototype object" ], "spec-examples.html": true, "structured-serialization.html": [ From f6f2a2c10a55bf58b5181f0fb99ad3e2bf597e69 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 20 Sep 2025 00:24:54 +0900 Subject: [PATCH 54/63] consistent with lib.dom.d.ts --- cli/tsc/dts/lib.deno_geometry.d.ts | 511 +++++++++++++++++++---------- 1 file changed, 336 insertions(+), 175 deletions(-) diff --git a/cli/tsc/dts/lib.deno_geometry.d.ts b/cli/tsc/dts/lib.deno_geometry.d.ts index 2fb76ae94dc281..e2a6063d91bf4f 100644 --- a/cli/tsc/dts/lib.deno_geometry.d.ts +++ b/cli/tsc/dts/lib.deno_geometry.d.ts @@ -43,7 +43,8 @@ interface DOMMatrixInit extends DOMMatrix2DInit { } /** - * A 4×4 matrix (column-major order), suitable for 2D and 3D operations including rotation and translation. + * The **`DOMMatrix`** interface represents 4×4 matrices, suitable for 2D and 3D operations including rotation and translation. + * * [MDN](https://developer.mozilla.org/docs/Web/API/DOMMatrix) * * ``` @@ -57,54 +58,72 @@ interface DOMMatrixInit extends DOMMatrix2DInit { * @experimental */ interface DOMMatrix extends DOMMatrixReadOnly { + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ a: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ b: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ c: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ d: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ e: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ f: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ m11: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ m12: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ m13: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ m14: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ m21: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ m22: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ m23: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ m24: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ m31: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ m32: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ m33: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ m34: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ m41: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ m42: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ m43: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix#instance_properties) */ m44: number; /** - * Modifies the matrix by inverting it. - * If the matrix can't be inverted, its components are all set to `NaN`, and is2D property is set to `false`. + * The **`invertSelf()`** method of the DOMMatrix interface inverts the original matrix. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix/invertSelf) */ invertSelf(): DOMMatrix; /** - * Modifies the matrix by post-multiplying it with the specified DOMMatrix. - * This is equivalent to the dot product `A⋅B`, where matrix `A` is the source matrix and `B` is the matrix given as an input to the method. + * The **`multiplySelf()`** method of the DOMMatrix interface multiplies a matrix by the `otherMatrix` parameter, computing the dot product of the original matrix and the specified matrix: `A⋅B`. * - * @param other + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix/multiplySelf) */ multiplySelf(other?: DOMMatrixInit): DOMMatrix; /** - * Modifies the matrix by pre-multiplying it with the specified DOMMatrix. - * This is equivalent to the dot product B⋅A, where matrix `A` is the source matrix and `B` is the matrix given as an input to the method. + * The **`preMultiplySelf()`** method of the DOMMatrix interface modifies the matrix by pre-multiplying it with the specified `DOMMatrix`. * - * @param other + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix/preMultiplySelf) */ preMultiplySelf(other?: DOMMatrixInit): DOMMatrix; /** - * Modifies the matrix by rotating it by the specified angle around the given vector. + * The `rotateAxisAngleSelf()` method of the DOMMatrix interface is a transformation method that rotates the source matrix by the given vector and angle, returning the altered matrix. * - * @param x - * @param y - * @param z - * @param angle in degrees + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix/rotateAxisAngleSelf) */ rotateAxisAngleSelf( x?: number, @@ -113,33 +132,21 @@ interface DOMMatrix extends DOMMatrixReadOnly { angle?: number, ): DOMMatrix; /** - * Modifies the matrix by rotating it by the angle between the specified vector and `(1, 0)`. + * The `rotateFromVectorSelf()` method of the DOMMatrix interface is a mutable transformation method that modifies a matrix by rotating the matrix by the angle between the specified vector and `(1, 0)`. * - * @param x - * @param y + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix/rotateFromVectorSelf) */ rotateFromVectorSelf(x?: number, y?: number): DOMMatrix; /** - * Modifies the matrix by rotating itself around each axis by the specified number of degrees. - * - * @param rotZ yaw angle in degrees - */ - rotateSelf(rotZ?: number): DOMMatrix; - /** - * Modifies the matrix by rotating itself around each axis by the specified number of degrees. + * The `rotateSelf()` method of the DOMMatrix interface is a mutable transformation method that modifies a matrix. * - * @param rotX roll angle in degrees - * @param rotY pitch angle in degrees - * @param rotZ yaw angle in degrees + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix/rotateSelf) */ rotateSelf(rotX?: number, rotY?: number, rotZ?: number): DOMMatrix; /** - * Modifies the matrix by applying the specified scaling factor to all three axes, centered on the given origin. + * The **`scale3dSelf()`** method of the DOMMatrix interface is a mutable transformation method that modifies a matrix by applying a specified scaling factor to all three axes, centered on the given origin, with a default origin of `(0, 0, 0)`, returning the 3D-scaled matrix. * - * @param scale - * @param originX - * @param originY - * @param originZ + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix/scale3dSelf) */ scale3dSelf( scale?: number, @@ -148,16 +155,9 @@ interface DOMMatrix extends DOMMatrixReadOnly { originZ?: number, ): DOMMatrix; /** - * Modifies the matrix by applying the specified scaling factors, with the center located at the specified origin. Also returns itself. - * By default, the X and Z axes are scaled by `1` and the Y axis is given the same scaling value as the X axis. - * The default origin is `(0, 0, 0)`. + * The **`scaleSelf()`** method of the DOMMatrix interface is a mutable transformation method that modifies a matrix by applying a specified scaling factor, centered on the given origin, with a default origin of `(0, 0)`, returning the scaled matrix. * - * @param scaleX - * @param scaleY - * @param scaleZ - * @param originX - * @param originY - * @param originZ + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix/scaleSelf) */ scaleSelf( scaleX?: number, @@ -168,31 +168,27 @@ interface DOMMatrix extends DOMMatrixReadOnly { originZ?: number, ): DOMMatrix; /** - * NOTE: Not available in Worker - * - * Replaces the contents of the matrix with the matrix described by the specified transform or transforms. + * The **`setMatrixValue()`** method of the DOMMatrix interface replaces the contents of the matrix with the matrix described by the specified transform or transforms, returning itself. * - * @param transformList + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix/setMatrixValue) */ setMatrixValue(transformList: string): DOMMatrix; /** - * Modifies the matrix by applying the specified skew transformation along the X-axis. + * The `skewXSelf()` method of the DOMMatrix interface is a mutable transformation method that modifies a matrix. * - * @param sx in degrees + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix/skewXSelf) */ skewXSelf(sx?: number): DOMMatrix; /** - * Modifies the matrix by applying the specified skew transformation along the Y-axis. + * The `skewYSelf()` method of the DOMMatrix interface is a mutable transformation method that modifies a matrix. * - * @param sy in degrees + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix/skewYSelf) */ skewYSelf(sy?: number): DOMMatrix; /** - * Modifies the matrix by applying the specified vector. The default vector is `(0, 0, 0)`. + * The `translateSelf()` method of the DOMMatrix interface is a mutable transformation method that modifies a matrix. * - * @param tx - * @param ty - * @param tz + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix/translateSelf) */ translateSelf(tx?: number, ty?: number, tz?: number): DOMMatrix; } @@ -213,17 +209,15 @@ interface DOMMatrix extends DOMMatrixReadOnly { */ declare var DOMMatrix: { prototype: DOMMatrix; - new (init?: number[]): DOMMatrix; - new (init: DOMMatrix | DOMMatrixReadOnly): DOMMatrix; - /** NOTE: Not available in Worker */ - new (init: string): DOMMatrix; - fromFloat32Array(array32: Float32Array): DOMMatrix; - fromFloat64Array(array64: Float64Array): DOMMatrix; + new (init?: string | number[]): DOMMatrix; + fromFloat32Array(array32: Float32Array): DOMMatrix; + fromFloat64Array(array64: Float64Array): DOMMatrix; fromMatrix(other?: DOMMatrixInit): DOMMatrix; }; /** - * A read-only 4×4 matrix (column-major order), suitable for 2D and 3D operations including rotation and translation. + * The **`DOMMatrixReadOnly`** interface represents a read-only 4×4 matrix, suitable for 2D and 3D operations. + * * [MDN](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly) * * ``` @@ -237,66 +231,96 @@ declare var DOMMatrix: { * @experimental */ interface DOMMatrixReadOnly { + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly a: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly b: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly c: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly d: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly e: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly f: number; + /** + * The readonly **`is2D`** property of the DOMMatrixReadOnly interface is a Boolean flag that is `true` when the matrix is 2D. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/is2D) + */ readonly is2D: boolean; + /** + * The readonly **`isIdentity`** property of the DOMMatrixReadOnly interface is a Boolean whose value is `true` if the matrix is the identity matrix. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/isIdentity) + */ readonly isIdentity: boolean; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly m11: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly m12: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly m13: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly m14: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly m21: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly m22: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly m23: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly m24: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly m31: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly m32: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly m33: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly m34: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly m41: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly m42: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly m43: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly#instance_properties) */ readonly m44: number; - /** Returns a new `DOMMatrix` created by flipping the source matrix around its X-axis. */ + /** + * The **`flipX()`** method of the DOMMatrixReadOnly interface creates a new matrix being the result of the original matrix flipped about the x-axis. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/flipX) + */ flipX(): DOMMatrix; - /** Returns a new `DOMMatrix` created by flipping the source matrix around its Y-axis. */ - flipY(): DOMMatrix; /** - * Returns a new `DOMMatrix` created by inverting the source matrix. - * If the matrix cannot be inverted, the new matrix's components are all set to `NaN` and its is2D property is set to `false`. + * The **`flipY()`** method of the DOMMatrixReadOnly interface creates a new matrix being the result of the original matrix flipped about the y-axis. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/flipY) */ - inverse(): DOMMatrix; + flipY(): DOMMatrix; /** - * Returns a new `DOMMatrix` created by computing the dot product of the source matrix and the specified matrix: `A⋅B`. + * The **`inverse()`** method of the DOMMatrixReadOnly interface creates a new matrix which is the inverse of the original matrix. * - * @param other + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/inverse) */ - multiply(other?: DOMMatrixInit): DOMMatrix; + inverse(): DOMMatrix; /** - * Returns a new `DOMMatrix` created by rotating the source matrix around each of its axes by the specified number of degrees. + * The **`multiply()`** method of the DOMMatrixReadOnly interface creates and returns a new matrix which is the dot product of the matrix and the `otherMatrix` parameter. * - * @param rotZ yaw angle in degrees + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/multiply) */ - rotate(rotZ?: number): DOMMatrix; + multiply(other?: DOMMatrixInit): DOMMatrix; /** - * Returns a new `DOMMatrix` created by rotating the source matrix around each of its axes by the specified number of degrees. + * The `rotate()` method of the DOMMatrixReadOnly interface returns a new DOMMatrix created by rotating the source matrix around each of its axes by the specified number of degrees. * - * @param rotX roll angle in degrees - * @param rotY pitch angle in degrees - * @param rotZ yaw angle in degrees + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/rotate) */ rotate(rotX?: number, rotY?: number, rotZ?: number): DOMMatrix; /** - * Returns a new DOMMatrix created by rotating the source matrix by the given angle around the specified vector. + * The `rotateAxisAngle()` method of the DOMMatrixReadOnly interface returns a new DOMMatrix created by rotating the source matrix by the given vector and angle. * - * @param x - * @param y - * @param z - * @param angle in degrees + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/rotateAxisAngle) */ rotateAxisAngle( x?: number, @@ -305,23 +329,15 @@ interface DOMMatrixReadOnly { angle?: number, ): DOMMatrix; /** - * Returns a new `DOMMatrix` created by rotating the source matrix by the angle between the specified vector and `(1, 0)`. + * The `rotateFromVector()` method of the DOMMatrixReadOnly interface is returns a new DOMMatrix created by rotating the source matrix by the angle between the specified vector and `(1, 0)`. * - * @param x - * @param y + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/rotateFromVector) */ rotateFromVector(x?: number, y?: number): DOMMatrix; /** - * Returns a new `DOMMatrix` created by scaling the source matrix by the amount specified for each axis, centered on the given origin. - * By default, the X and Z axes are scaled by `1` and the Y axis is given the same scaling value as the X axis. - * The default origin is `(0, 0, 0)`. + * The **`scale()`** method of the original matrix with a scale transform applied. * - * @param scaleX - * @param scaleY - * @param scaleZ - * @param originX - * @param originY - * @param originZ + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/scale) */ scale( scaleX?: number, @@ -332,13 +348,9 @@ interface DOMMatrixReadOnly { originZ?: number, ): DOMMatrix; /** - * Returns a new `DOMMatrix` created by scaling the source 3D matrix by the given factor along all its axes, centered on the specified origin point. - * The default origin is `(0, 0, 0)`. + * The **`scale3d()`** method of the DOMMatrixReadOnly interface creates a new matrix which is the result of a 3D scale transform being applied to the matrix. * - * @param scale - * @param originX - * @param originY - * @param originZ + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/scale3d) */ scale3d( scale?: number, @@ -346,64 +358,56 @@ interface DOMMatrixReadOnly { originY?: number, originZ?: number, ): DOMMatrix; + /** @deprecated */ + scaleNonUniform(scaleX?: number, scaleY?: number): DOMMatrix; /** - * Returns a new `DOMMatrix` created by applying the specified scaling on the X, Y, and Z axes, centered at the given origin. - * By default, the X and Y axes' scaling factors are both `1`. + * The `skewX()` method of the DOMMatrixReadOnly interface returns a new DOMMatrix created by applying the specified skew transformation to the source matrix along its x-axis. * - * @deprecated Supported for legacy reasons to be compatible with `SVGMatrix` as defined in SVG 1.1. Use `scale()` instead. + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/skewX) + */ + skewX(sx?: number): DOMMatrix; + /** + * The `skewY()` method of the DOMMatrixReadOnly interface returns a new DOMMatrix created by applying the specified skew transformation to the source matrix along its y-axis. * - * @param scaleX - * @param scaleY + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/skewY) */ - scaleNonUniform(scaleX?: number, scaleY?: number): DOMMatrix; + skewY(sy?: number): DOMMatrix; /** - * Returns a new DOMMatrix created by applying the specified skew transformation to the source matrix along its X-axis. + * The **`toFloat32Array()`** method of the DOMMatrixReadOnly interface returns a new Float32Array containing all 16 elements (`m11`, `m12`, `m13`, `m14`, `m21`, `m22`, `m23`, `m24`, `m31`, `m32`, `m33`, `m34`, `m41`, `m42`, `m43`, `m44`) which comprise the matrix. * - * @param sx in degrees + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/toFloat32Array) */ - skewX(sx?: number): DOMMatrix; + toFloat32Array(): Float32Array; /** - * Returns a new DOMMatrix created by applying the specified skew transformation to the source matrix along its Y-axis. + * The **`toFloat64Array()`** method of the DOMMatrixReadOnly interface returns a new Float64Array containing all 16 elements (`m11`, `m12`, `m13`, `m14`, `m21`, `m22`, `m23`, `m24`, `m31`, `m32`, `m33`, `m34`, `m41`, `m42`, `m43`, `m44`) which comprise the matrix. * - * @param sy in degrees + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/toFloat64Array) + */ + toFloat64Array(): Float64Array; + /** + * The **`toJSON()`** method of the DOMMatrixReadOnly interface creates and returns a JSON object. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/toJSON) + */ + toJSON(): any; + /** + * The **`transformPoint`** method of the You can also create a new `DOMPoint` by applying a matrix to a point with the DOMPointReadOnly.matrixTransform() method. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/transformPoint) */ - skewY(sy?: number): DOMMatrix; - toFloat32Array(): Float32Array; - toFloat64Array(): Float64Array; - toJSON(): { - a: number; - b: number; - c: number; - d: number; - e: number; - f: number; - is2D: boolean; - isIdentity: boolean; - m11: number; - m12: number; - m13: number; - m14: number; - m21: number; - m22: number; - m23: number; - m24: number; - m31: number; - m32: number; - m33: number; - m34: number; - m41: number; - m42: number; - m43: number; - m44: number; - }; transformPoint(point?: DOMPointInit): DOMPoint; + /** + * The `translate()` method of the DOMMatrixReadOnly interface creates a new matrix being the result of the original matrix with a translation applied. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/translate) + */ translate(tx?: number, ty?: number, tz?: number): DOMMatrix; - /** NOTE: Not available in Worker */ toString(): string; } /** - * A read-only 4×4 matrix (column-major order), suitable for 2D and 3D operations including rotation and translation. + * The **`DOMMatrixReadOnly`** interface represents a read-only 4×4 matrix, suitable for 2D and 3D operations. + * * [MDN](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly) * * ``` @@ -418,12 +422,9 @@ interface DOMMatrixReadOnly { */ declare var DOMMatrixReadOnly: { prototype: DOMMatrixReadOnly; - new (init?: number[]): DOMMatrixReadOnly; - new (init: DOMMatrix | DOMMatrixReadOnly): DOMMatrixReadOnly; - /** NOTE: Not available in Worker */ - new (init: string): DOMMatrixReadOnly; - fromFloat32Array(array32: Float32Array): DOMMatrixReadOnly; - fromFloat64Array(array64: Float64Array): DOMMatrixReadOnly; + new (init?: string | number[]): DOMMatrixReadOnly; + fromFloat32Array(array32: Float32Array): DOMMatrixReadOnly; + fromFloat64Array(array64: Float64Array): DOMMatrixReadOnly; fromMatrix(other?: DOMMatrixInit): DOMMatrixReadOnly; }; @@ -439,21 +440,43 @@ interface DOMPointInit { } /** - * A object represents a 2D or 3D point in a coordinate system; it includes values for the coordinates in up to three dimensions, as well as an optional perspective value. + * A **`DOMPoint`** object represents a 2D or 3D point in a coordinate system; it includes values for the coordinates in up to three dimensions, as well as an optional perspective value. + * * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPoint) * * @category Geometry Interfaces Module API * @experimental */ interface DOMPoint extends DOMPointReadOnly { + /** + * The **`DOMPoint`** interface's **`w`** property holds the point's perspective value, w, for a point in space. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPoint/w) + */ w: number; + /** + * The **`DOMPoint`** interface's **`x`** property holds the horizontal coordinate, x, for a point in space. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPoint/x) + */ x: number; + /** + * The **`DOMPoint`** interface's **`y`** property holds the vertical coordinate, _y_, for a point in space. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPoint/y) + */ y: number; + /** + * The **`DOMPoint`** interface's **`z`** property specifies the depth coordinate of a point in space. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPoint/z) + */ z: number; } /** - * A object represents a 2D or 3D point in a coordinate system; it includes values for the coordinates in up to three dimensions, as well as an optional perspective value. + * A **`DOMPoint`** object represents a 2D or 3D point in a coordinate system; it includes values for the coordinates in up to three dimensions, as well as an optional perspective value. + * * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPoint) * * @category Geometry Interfaces Module API @@ -462,32 +485,64 @@ interface DOMPoint extends DOMPointReadOnly { declare var DOMPoint: { prototype: DOMPoint; new (x?: number, y?: number, z?: number, w?: number): DOMPoint; + /** + * The **`fromPoint()`** static method of the DOMPoint interface creates and returns a new mutable `DOMPoint` object given a source point. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPoint/fromPoint_static) + */ fromPoint(other?: DOMPointInit): DOMPoint; }; /** - * A read-only object represents a 2D or 3D point in a coordinate system; it includes values for the coordinates in up to three dimensions, as well as an optional perspective value. + * The **`DOMPointReadOnly`** interface specifies the coordinate and perspective fields used by DOMPoint to define a 2D or 3D point in a coordinate system. + * * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly) * * @category Geometry Interfaces Module API * @experimental */ interface DOMPointReadOnly { + /** + * The **`DOMPointReadOnly`** interface's **`w`** property holds the point's perspective value, `w`, for a read-only point in space. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/w) + */ readonly w: number; + /** + * The **`DOMPointReadOnly`** interface's **`x`** property holds the horizontal coordinate, x, for a read-only point in space. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/x) + */ readonly x: number; + /** + * The **`DOMPointReadOnly`** interface's **`y`** property holds the vertical coordinate, y, for a read-only point in space. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/y) + */ readonly y: number; + /** + * The **`DOMPointReadOnly`** interface's **`z`** property holds the depth coordinate, z, for a read-only point in space. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/z) + */ readonly z: number; + /** + * The **`matrixTransform()`** method of the DOMPointReadOnly interface applies a matrix transform specified as an object to the DOMPointReadOnly object, creating and returning a new `DOMPointReadOnly` object. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/matrixTransform) + */ matrixTransform(matrix?: DOMMatrixInit): DOMPoint; - toJSON(): { - w: number; - x: number; - y: number; - z: number; - }; + /** + * The DOMPointReadOnly method `toJSON()` returns an object giving the ```js-nolint toJSON() ``` None. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/toJSON) + */ + toJSON(): any; } /** - * A read-only object represents a 2D or 3D point in a coordinate system; it includes values for the coordinates in up to three dimensions, as well as an optional perspective value. + * The **`DOMPointReadOnly`** interface specifies the coordinate and perspective fields used by DOMPoint to define a 2D or 3D point in a coordinate system. + * * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly) * * @category Geometry Interfaces Module API @@ -496,6 +551,11 @@ interface DOMPointReadOnly { declare var DOMPointReadOnly: { prototype: DOMPointReadOnly; new (x?: number, y?: number, z?: number, w?: number): DOMPointReadOnly; + /** + * The static **DOMPointReadOnly** method `fromPoint()` creates and returns a new `DOMPointReadOnly` object given a source point. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/fromPoint_static) + */ fromPoint(other?: DOMPointInit): DOMPointReadOnly; }; @@ -511,28 +571,55 @@ interface DOMQuadInit { } /** - * A collection of four DOMPoints defining the corners of an arbitrary quadrilateral. + * A `DOMQuad` is a collection of four `DOMPoint`s defining the corners of an arbitrary quadrilateral. + * * [MDN](https://developer.mozilla.org/docs/Web/API/DOMQuad) * * @category Geometry Interfaces Module API * @experimental */ interface DOMQuad { + /** + * The **`DOMQuad`** interface's **`p1`** property holds the DOMPoint object that represents one of the four corners of the `DOMQuad`. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMQuad/p1) + */ readonly p1: DOMPoint; + /** + * The **`DOMQuad`** interface's **`p2`** property holds the DOMPoint object that represents one of the four corners of the `DOMQuad`. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMQuad/p2) + */ readonly p2: DOMPoint; + /** + * The **`DOMQuad`** interface's **`p3`** property holds the DOMPoint object that represents one of the four corners of the `DOMQuad`. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMQuad/p3) + */ readonly p3: DOMPoint; + /** + * The **`DOMQuad`** interface's **`p4`** property holds the DOMPoint object that represents one of the four corners of the `DOMQuad`. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMQuad/p4) + */ readonly p4: DOMPoint; + /** + * The DOMQuad method `getBounds()` returns a DOMRect object representing the smallest rectangle that fully contains the `DOMQuad` object. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMQuad/getBounds) + */ getBounds(): DOMRect; - toJSON(): { - p1: DOMPoint; - p2: DOMPoint; - p3: DOMPoint; - p4: DOMPoint; - }; + /** + * The DOMQuad method `toJSON()` returns a ```js-nolint toJSON() ``` None. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMQuad/toJSON) + */ + toJSON(): any; } /** - * A collection of four DOMPoints defining the corners of an arbitrary quadrilateral. + * A `DOMQuad` is a collection of four `DOMPoint`s defining the corners of an arbitrary quadrilateral. + * * [MDN](https://developer.mozilla.org/docs/Web/API/DOMQuad) * * @category Geometry Interfaces Module API @@ -562,19 +649,43 @@ interface DOMRectInit { } /** + * A **`DOMRect`** describes the size and position of a rectangle. + * * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRect) * * @category Geometry Interfaces Module API * @experimental */ interface DOMRect extends DOMRectReadOnly { + /** + * The **`height`** property of the DOMRect interface represents the height of the rectangle. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRect/height) + */ height: number; + /** + * The **`width`** property of the DOMRect interface represents the width of the rectangle. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRect/width) + */ width: number; + /** + * The **`x`** property of the DOMRect interface represents the x-coordinate of the rectangle, which is the horizontal distance between the viewport's left edge and the rectangle's origin. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRect/x) + */ x: number; + /** + * The **`y`** property of the DOMRect interface represents the y-coordinate of the rectangle, which is the vertical distance between the viewport's top edge and the rectangle's origin. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRect/y) + */ y: number; } /** + * A **`DOMRect`** describes the size and position of a rectangle. + * * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRect) * * @category Geometry Interfaces Module API @@ -583,37 +694,82 @@ interface DOMRect extends DOMRectReadOnly { declare var DOMRect: { prototype: DOMRect; new (x?: number, y?: number, width?: number, height?: number): DOMRect; + /** + * The **`fromRect()`** static method of the object with a given location and dimensions. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRect/fromRect_static) + */ fromRect(other?: DOMRectInit): DOMRect; }; /** + * The **`DOMRectReadOnly`** interface specifies the standard properties (also used by DOMRect) to define a rectangle whose properties are immutable. + * * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly) * * @category Geometry Interfaces Module API * @experimental */ interface DOMRectReadOnly { + /** + * The **`bottom`** read-only property of the **`DOMRectReadOnly`** interface returns the bottom coordinate value of the `DOMRect`. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/bottom) + */ readonly bottom: number; + /** + * The **`height`** read-only property of the **`DOMRectReadOnly`** interface represents the height of the `DOMRect`. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/height) + */ readonly height: number; + /** + * The **`left`** read-only property of the **`DOMRectReadOnly`** interface returns the left coordinate value of the `DOMRect`. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/left) + */ readonly left: number; + /** + * The **`right`** read-only property of the **`DOMRectReadOnly`** interface returns the right coordinate value of the `DOMRect`. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/right) + */ readonly right: number; + /** + * The **`top`** read-only property of the **`DOMRectReadOnly`** interface returns the top coordinate value of the `DOMRect`. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/top) + */ readonly top: number; + /** + * The **`width`** read-only property of the **`DOMRectReadOnly`** interface represents the width of the `DOMRect`. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/width) + */ readonly width: number; + /** + * The **`x`** read-only property of the **`DOMRectReadOnly`** interface represents the x coordinate of the `DOMRect`'s origin. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/x) + */ readonly x: number; + /** + * The **`y`** read-only property of the **`DOMRectReadOnly`** interface represents the y coordinate of the `DOMRect`'s origin. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/y) + */ readonly y: number; - toJSON(): { - bottom: number; - height: number; - left: number; - right: number; - top: number; - width: number; - x: number; - y: number; - }; + /** + * The DOMRectReadOnly method `toJSON()` returns a JSON representation of the `DOMRectReadOnly` object. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/toJSON) + */ + toJSON(): any; } /** + * The **`DOMRectReadOnly`** interface specifies the standard properties (also used by DOMRect) to define a rectangle whose properties are immutable. + * * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly) * * @category Geometry Interfaces Module API @@ -627,5 +783,10 @@ declare var DOMRectReadOnly: { width?: number, height?: number, ): DOMRectReadOnly; + /** + * The **`fromRect()`** static method of the object with a given location and dimensions. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/fromRect_static) + */ fromRect(other?: DOMRectInit): DOMRectReadOnly; }; From 58aebdf1c1d858c459baa65b329557626adec5dc Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 20 Sep 2025 00:25:04 +0900 Subject: [PATCH 55/63] use create_data_property Co-authored-by: ud2 --- ext/geometry/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index fec218d007379a..4abdc3dbe78527 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -2931,7 +2931,7 @@ fn set_f64( ) { let key = v8::String::new(scope, key).unwrap(); let value = v8::Number::new(scope, value); - object.set(scope, key.into(), value.into()).unwrap(); + object.create_data_property(scope, key.into(), value.into()); } #[inline] @@ -2943,7 +2943,7 @@ fn set_boolean( ) { let key = v8::String::new(scope, key).unwrap(); let value = v8::Boolean::new(scope, value); - object.set(scope, key.into(), value.into()).unwrap(); + object.create_data_property(scope, key.into(), value.into()); } #[inline] @@ -2955,7 +2955,7 @@ fn set_object( ) { let key = v8::String::new(scope, key).unwrap(); let value = v8::Local::new(scope, value); - object.set(scope, key.into(), value.into()).unwrap(); + object.create_data_property(scope, key.into(), value.into()); } // TODO(petamoriken) Use f64::maximum instead https://github.com/rust-lang/rust/issues/91079 From 44105d92b700114763f00f2c1ee45d2071ad7dbc Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 20 Sep 2025 00:37:27 +0900 Subject: [PATCH 56/63] fix `DOMMatrixInit` order --- ext/geometry/lib.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 4abdc3dbe78527..d707630bfd1d80 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -820,6 +820,7 @@ impl DOMQuad { #[derive(WebIDL, Debug)] #[webidl(dictionary)] pub struct DOMMatrixInit { + // Need to place the inherited DOMMatrixInit2D first #[webidl(default = None)] a: Option, #[webidl(default = None)] @@ -836,14 +837,19 @@ pub struct DOMMatrixInit { m11: Option, #[webidl(default = None)] m12: Option, - #[webidl(default = webidl::UnrestrictedDouble(0.0))] - m13: webidl::UnrestrictedDouble, - #[webidl(default = webidl::UnrestrictedDouble(0.0))] - m14: webidl::UnrestrictedDouble, #[webidl(default = None)] m21: Option, #[webidl(default = None)] m22: Option, + #[webidl(default = None)] + m41: Option, + #[webidl(default = None)] + m42: Option, + + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + m13: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + m14: webidl::UnrestrictedDouble, #[webidl(default = webidl::UnrestrictedDouble(0.0))] m23: webidl::UnrestrictedDouble, #[webidl(default = webidl::UnrestrictedDouble(0.0))] @@ -856,10 +862,6 @@ pub struct DOMMatrixInit { m33: webidl::UnrestrictedDouble, #[webidl(default = webidl::UnrestrictedDouble(0.0))] m34: webidl::UnrestrictedDouble, - #[webidl(default = None)] - m41: Option, - #[webidl(default = None)] - m42: Option, #[webidl(default = webidl::UnrestrictedDouble(0.0))] m43: webidl::UnrestrictedDouble, #[webidl(default = webidl::UnrestrictedDouble(1.0))] From d250f3c930abd7ccddd6f5c78a8404a42dd7125d Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 20 Sep 2025 00:45:37 +0900 Subject: [PATCH 57/63] fix `DOMMatrixReadOnly` constructor Co-authored-by: ud2 --- ext/geometry/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index d707630bfd1d80..a1de75428b0e50 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -941,7 +941,7 @@ impl DOMMatrixReadOnly { } // sequence - if !value.is_string() + if value.is_object() && let Ok(seq) = Vec::::convert( scope, value, @@ -972,7 +972,7 @@ impl DOMMatrixReadOnly { return Ok(matrix); } - Err(GeometryError::FailedToParse) + Ok(DOMMatrixReadOnly::identity()) } fn from_matrix_inner( From 327b98512526aa6fb298c3cafcd5ac379b8f26e3 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 20 Sep 2025 01:09:07 +0900 Subject: [PATCH 58/63] remove unsafe `get_unchecked(_mut)`s --- ext/geometry/lib.rs | 230 +++++++++++++++----------------------------- 1 file changed, 77 insertions(+), 153 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index a1de75428b0e50..71bf40730133b6 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -1243,34 +1243,28 @@ impl DOMMatrixReadOnly { return; } if is_2d { - // SAFETY: in-range access - let mut matrix3 = unsafe { - Matrix3::new( - *inner.get_unchecked(INDEX_A), - *inner.get_unchecked(INDEX_C), - *inner.get_unchecked(INDEX_E), - *inner.get_unchecked(INDEX_B), - *inner.get_unchecked(INDEX_D), - *inner.get_unchecked(INDEX_F), - 0.0, - 0.0, - 1.0, - ) - }; + let mut matrix3 = Matrix3::new( + inner[INDEX_A], + inner[INDEX_C], + inner[INDEX_E], + inner[INDEX_B], + inner[INDEX_D], + inner[INDEX_F], + 0.0, + 0.0, + 1.0, + ); if !matrix3.try_inverse_mut() { inner.fill(f64::NAN); self.is_2d.set(false); return; } - // SAFETY: in-range access - unsafe { - *inner.get_unchecked_mut(INDEX_A) = *matrix3.get_unchecked(0); - *inner.get_unchecked_mut(INDEX_B) = *matrix3.get_unchecked(1); - *inner.get_unchecked_mut(INDEX_C) = *matrix3.get_unchecked(3); - *inner.get_unchecked_mut(INDEX_D) = *matrix3.get_unchecked(4); - *inner.get_unchecked_mut(INDEX_E) = *matrix3.get_unchecked(6); - *inner.get_unchecked_mut(INDEX_F) = *matrix3.get_unchecked(7); - } + inner[INDEX_A] = matrix3[0]; + inner[INDEX_B] = matrix3[1]; + inner[INDEX_C] = matrix3[3]; + inner[INDEX_D] = matrix3[4]; + inner[INDEX_E] = matrix3[6]; + inner[INDEX_F] = matrix3[7]; } else if !inner.try_inverse_mut() { inner.fill(f64::NAN); } @@ -1278,158 +1272,133 @@ impl DOMMatrixReadOnly { #[inline] fn a_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_A) } + self.inner.borrow()[INDEX_A] } #[inline] fn b_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_B) } + self.inner.borrow()[INDEX_B] } #[inline] fn c_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_C) } + self.inner.borrow()[INDEX_C] } #[inline] fn d_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_D) } + self.inner.borrow()[INDEX_D] } #[inline] fn e_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_E) } + self.inner.borrow()[INDEX_E] } #[inline] fn f_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_F) } + self.inner.borrow()[INDEX_F] } #[inline] fn m11_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M11) } + self.inner.borrow()[INDEX_M11] } #[inline] fn m12_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M12) } + self.inner.borrow()[INDEX_M12] } #[inline] fn m13_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M13) } + self.inner.borrow()[INDEX_M13] } #[inline] fn m14_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M14) } + self.inner.borrow()[INDEX_M14] } #[inline] fn m21_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M21) } + self.inner.borrow()[INDEX_M21] } #[inline] fn m22_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M22) } + self.inner.borrow()[INDEX_M22] } #[inline] fn m23_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M23) } + self.inner.borrow()[INDEX_M23] } #[inline] fn m24_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M24) } + self.inner.borrow()[INDEX_M24] } #[inline] fn m31_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M31) } + self.inner.borrow()[INDEX_M31] } #[inline] fn m32_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M32) } + self.inner.borrow()[INDEX_M32] } #[inline] fn m33_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M33) } + self.inner.borrow()[INDEX_M33] } #[inline] fn m34_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M34) } + self.inner.borrow()[INDEX_M34] } #[inline] fn m41_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M41) } + self.inner.borrow()[INDEX_M41] } #[inline] fn m42_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M42) } + self.inner.borrow()[INDEX_M42] } #[inline] fn m43_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M43) } + self.inner.borrow()[INDEX_M43] } #[inline] fn m44_inner(&self) -> f64 { - // SAFETY: in-range access - unsafe { *self.inner.borrow().get_unchecked(INDEX_M44) } + self.inner.borrow()[INDEX_M44] } #[inline] fn is_identity_inner(&self) -> bool { let inner = self.inner.borrow(); - // SAFETY: in-range access - unsafe { - *inner.get_unchecked(INDEX_M11) == 1.0 - && *inner.get_unchecked(INDEX_M12) == 0.0 - && *inner.get_unchecked(INDEX_M13) == 0.0 - && *inner.get_unchecked(INDEX_M14) == 0.0 - && *inner.get_unchecked(INDEX_M21) == 0.0 - && *inner.get_unchecked(INDEX_M22) == 1.0 - && *inner.get_unchecked(INDEX_M23) == 0.0 - && *inner.get_unchecked(INDEX_M24) == 0.0 - && *inner.get_unchecked(INDEX_M31) == 0.0 - && *inner.get_unchecked(INDEX_M32) == 0.0 - && *inner.get_unchecked(INDEX_M33) == 1.0 - && *inner.get_unchecked(INDEX_M34) == 0.0 - && *inner.get_unchecked(INDEX_M41) == 0.0 - && *inner.get_unchecked(INDEX_M42) == 0.0 - && *inner.get_unchecked(INDEX_M43) == 0.0 - && *inner.get_unchecked(INDEX_M44) == 1.0 - } + inner[INDEX_M11] == 1.0 + && inner[INDEX_M12] == 0.0 + && inner[INDEX_M13] == 0.0 + && inner[INDEX_M14] == 0.0 + && inner[INDEX_M21] == 0.0 + && inner[INDEX_M22] == 1.0 + && inner[INDEX_M23] == 0.0 + && inner[INDEX_M24] == 0.0 + && inner[INDEX_M31] == 0.0 + && inner[INDEX_M32] == 0.0 + && inner[INDEX_M33] == 1.0 + && inner[INDEX_M34] == 0.0 + && inner[INDEX_M41] == 0.0 + && inner[INDEX_M42] == 0.0 + && inner[INDEX_M43] == 0.0 + && inner[INDEX_M44] == 1.0 } #[inline] @@ -2275,10 +2244,7 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_A) = *value; - } + ro.inner.borrow_mut()[INDEX_A] = *value; } #[fast] @@ -2294,9 +2260,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_B) = *value; - } + ro.inner.borrow_mut()[INDEX_B] = *value; } #[fast] @@ -2312,9 +2276,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_C) = *value; - } + ro.inner.borrow_mut()[INDEX_C] = *value; } #[fast] @@ -2330,9 +2292,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_D) = *value; - } + ro.inner.borrow_mut()[INDEX_D] = *value; } #[fast] @@ -2348,9 +2308,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_E) = *value; - } + ro.inner.borrow_mut()[INDEX_E] = *value; } #[fast] @@ -2366,9 +2324,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_F) = *value; - } + ro.inner.borrow_mut()[INDEX_F] = *value; } #[fast] @@ -2384,9 +2340,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M11) = *value; - } + ro.inner.borrow_mut()[INDEX_M11] = *value; } #[fast] @@ -2402,9 +2356,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M12) = *value; - } + ro.inner.borrow_mut()[INDEX_M12] = *value; } #[fast] @@ -2420,9 +2372,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M13) = *value; - } + ro.inner.borrow_mut()[INDEX_M13] = *value; if *value != 0.0 { ro.is_2d.set(false); } @@ -2441,9 +2391,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M14) = *value; - } + ro.inner.borrow_mut()[INDEX_M14] = *value; if *value != 0.0 { ro.is_2d.set(false); } @@ -2462,9 +2410,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M21) = *value; - } + ro.inner.borrow_mut()[INDEX_M21] = *value; } #[fast] @@ -2480,9 +2426,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M22) = *value; - } + ro.inner.borrow_mut()[INDEX_M22] = *value; } #[fast] @@ -2498,9 +2442,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M23) = *value; - } + ro.inner.borrow_mut()[INDEX_M23] = *value; if *value != 0.0 { ro.is_2d.set(false); } @@ -2519,9 +2461,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M24) = *value; - } + ro.inner.borrow_mut()[INDEX_M24] = *value; if *value != 0.0 { ro.is_2d.set(false); } @@ -2540,9 +2480,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M31) = *value; - } + ro.inner.borrow_mut()[INDEX_M31] = *value; if *value != 0.0 { ro.is_2d.set(false); } @@ -2561,9 +2499,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M32) = *value; - } + ro.inner.borrow_mut()[INDEX_M32] = *value; if *value != 0.0 { ro.is_2d.set(false); } @@ -2582,9 +2518,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M33) = *value; - } + ro.inner.borrow_mut()[INDEX_M33] = *value; if *value != 1.0 { ro.is_2d.set(false); } @@ -2603,9 +2537,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M34) = *value; - } + ro.inner.borrow_mut()[INDEX_M34] = *value; if *value != 0.0 { ro.is_2d.set(false); } @@ -2624,9 +2556,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M41) = *value; - } + ro.inner.borrow_mut()[INDEX_M41] = *value; } #[fast] @@ -2642,9 +2572,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M42) = *value; - } + ro.inner.borrow_mut()[INDEX_M42] = *value; } #[fast] @@ -2660,9 +2588,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M43) = *value; - } + ro.inner.borrow_mut()[INDEX_M43] = *value; if *value != 0.0 { ro.is_2d.set(false); } @@ -2681,9 +2607,7 @@ impl DOMMatrix { #[proto] ro: &DOMMatrixReadOnly, ) { // SAFETY: in-range access - unsafe { - *ro.inner.borrow_mut().get_unchecked_mut(INDEX_M44) = *value; - } + ro.inner.borrow_mut()[INDEX_M44] = *value; if *value != 1.0 { ro.is_2d.set(false); } From 16501a3607c732f8a117c509f8b22485f63cd5ae Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 20 Sep 2025 01:18:04 +0900 Subject: [PATCH 59/63] fix perspective operator Co-authored-by: ud2 Signed-off-by: Kenta Moriuchi --- ext/geometry/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 71bf40730133b6..9cb431b6975354 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -1198,7 +1198,7 @@ impl DOMMatrixReadOnly { } let mut inner = self.inner.borrow_mut(); let perspective = - Matrix4x2::new(0.0, 0.0, 1.0, -1.0 / d, 0.0, 0.0, 0.0, 1.0); + Matrix4x2::new(0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0 / d, 1.0); let mut result = Matrix4x2::zeros(); inner.mul_to(&perspective, &mut result); inner.set_column(2, &result.column(0)); From 448fa30096347c63f95321c9c42514cc5f6e4a78 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 20 Sep 2025 01:48:05 +0900 Subject: [PATCH 60/63] fix --- ext/geometry/lib.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 71bf40730133b6..b93136daca8cb8 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -1443,6 +1443,7 @@ impl DOMMatrixReadOnly { Transform::TranslateZ(z) => { if let Some(z) = z.to_px() { self.translate_self_inner(0.0, 0.0, z.into()); + self.is_2d.set(false); } else { return Err(GeometryError::ContainsRelativeValue); } @@ -1455,6 +1456,7 @@ impl DOMMatrixReadOnly { if let (Some(x), Some(y), Some(z)) = (x.to_px(), y.to_px(), z.to_px()) { self.translate_self_inner(x.into(), y.into(), z.into()); + self.is_2d.set(false); } else { return Err(GeometryError::ContainsRelativeValue); } @@ -1475,14 +1477,16 @@ impl DOMMatrixReadOnly { Transform::ScaleZ(z) => { let z: CSSNumber = z.into(); self.scale_without_origin_self_inner(1.0, 1.0, z.into()); + self.is_2d.set(false); } Transform::Scale3d(x, y, z) => { let x: CSSNumber = x.into(); let y: CSSNumber = y.into(); let z: CSSNumber = z.into(); self.scale_without_origin_self_inner(x.into(), y.into(), z.into()); + self.is_2d.set(false); } - Transform::Rotate(angle) | Transform::RotateZ(angle) => { + Transform::Rotate(angle) => { self.rotate_axis_angle_self_inner( 0.0, 0.0, @@ -1497,6 +1501,7 @@ impl DOMMatrixReadOnly { 0.0, angle.to_radians().into(), ); + self.is_2d.set(false); } Transform::RotateY(angle) => { self.rotate_axis_angle_self_inner( @@ -1505,6 +1510,16 @@ impl DOMMatrixReadOnly { 0.0, angle.to_radians().into(), ); + self.is_2d.set(false); + } + Transform::RotateZ(angle) => { + self.rotate_axis_angle_self_inner( + 0.0, + 0.0, + 1.0, + angle.to_radians().into(), + ); + self.is_2d.set(false); } Transform::Rotate3d(x, y, z, angle) => { self.rotate_axis_angle_self_inner( @@ -1513,6 +1528,7 @@ impl DOMMatrixReadOnly { (*z).into(), angle.to_radians().into(), ); + self.is_2d.set(false); } Transform::Skew(x, y) => { self.skew_self_inner(x.to_radians().into(), y.to_radians().into()); @@ -1526,6 +1542,7 @@ impl DOMMatrixReadOnly { Transform::Perspective(length) => { if let Some(length) = length.to_px() { self.perspective_self_inner(length.into()); + self.is_2d.set(false); } else { return Err(GeometryError::ContainsRelativeValue); } @@ -3022,6 +3039,11 @@ pub fn op_geometry_matrix_set_matrix_value<'a>( &Default::default(), )?; if transform_list.is_empty() { + // Make it an identity matrix + let mut inner = matrix.inner.borrow_mut(); + inner.fill(0.0); + inner.fill_diagonal(1.0); + matrix.is_2d.set(true); return Ok(()); } let Ok(transform_list) = TransformList::parse_string(&transform_list) else { From 01ddbeeaeb35a57032246fa718e539a77f95b06e Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 20 Sep 2025 02:05:27 +0900 Subject: [PATCH 61/63] use `v8::TracedReference` for `DOMQuad` Co-authored-by: ud2 --- ext/geometry/lib.rs | 97 +++++++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 42 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 3297476e4e5b4a..43eb5a1a6e8313 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -618,15 +618,20 @@ pub struct DOMQuadInit { } pub struct DOMQuad { - p1: v8::Global, - p2: v8::Global, - p3: v8::Global, - p4: v8::Global, + p1: v8::TracedReference, + p2: v8::TracedReference, + p3: v8::TracedReference, + p4: v8::TracedReference, } // SAFETY: we're sure `DOMQuad` can be GCed unsafe impl GarbageCollected for DOMQuad { - fn trace(&self, _visitor: &mut deno_core::v8::cppgc::Visitor) {} + fn trace(&self, visitor: &mut deno_core::v8::cppgc::Visitor) { + visitor.trace(&self.p1); + visitor.trace(&self.p2); + visitor.trace(&self.p3); + visitor.trace(&self.p4); + } fn get_name(&self) -> &'static std::ffi::CStr { c"DOMQuad" @@ -650,7 +655,7 @@ impl DOMQuad { fn from_point( scope: &mut v8::HandleScope, point: DOMPointInit, - ) -> v8::Global { + ) -> v8::TracedReference { let ro = DOMPointReadOnly { inner: RefCell::new(Vector4::new( *point.x, *point.y, *point.z, *point.w, @@ -658,7 +663,7 @@ impl DOMQuad { }; let obj = cppgc::make_cppgc_empty_object::(scope); cppgc::wrap_object2(scope, obj, (ro, DOMPoint {})); - v8::Global::new(scope, obj) + v8::TracedReference::new(scope, obj) } DOMQuad { @@ -684,13 +689,13 @@ impl DOMQuad { y: f64, z: f64, w: f64, - ) -> v8::Global { + ) -> v8::TracedReference { let ro = DOMPointReadOnly { inner: RefCell::new(Vector4::new(x, y, z, w)), }; let obj = cppgc::make_cppgc_empty_object::(scope); cppgc::wrap_object2(scope, obj, (ro, DOMPoint {})); - v8::Global::new(scope, obj) + v8::TracedReference::new(scope, obj) } let DOMRectInit { @@ -719,7 +724,7 @@ impl DOMQuad { fn from_point( scope: &mut v8::HandleScope, point: DOMPointInit, - ) -> v8::Global { + ) -> v8::TracedReference { let ro = DOMPointReadOnly { inner: RefCell::new(Vector4::new( *point.x, *point.y, *point.z, *point.w, @@ -727,7 +732,7 @@ impl DOMQuad { }; let obj = cppgc::make_cppgc_empty_object::(scope); cppgc::wrap_object2(scope, obj, (ro, DOMPoint {})); - v8::Global::new(scope, obj) + v8::TracedReference::new(scope, obj) } DOMQuad { @@ -739,27 +744,35 @@ impl DOMQuad { } #[getter] - #[global] - fn p1(&self) -> v8::Global { - self.p1.clone() + fn p1<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + ) -> v8::Local<'a, v8::Object> { + self.p1.get(scope).unwrap() } #[getter] - #[global] - fn p2(&self) -> v8::Global { - self.p2.clone() + fn p2<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + ) -> v8::Local<'a, v8::Object> { + self.p2.get(scope).unwrap() } #[getter] - #[global] - fn p3(&self) -> v8::Global { - self.p3.clone() + fn p3<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + ) -> v8::Local<'a, v8::Object> { + self.p3.get(scope).unwrap() } #[getter] - #[global] - fn p4(&self) -> v8::Global { - self.p4.clone() + fn p4<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + ) -> v8::Local<'a, v8::Object> { + self.p4.get(scope).unwrap() } #[required(0)] @@ -770,12 +783,12 @@ impl DOMQuad { #[inline] fn get_ptr( scope: &mut v8::HandleScope, - value: &v8::Global, + value: &v8::TracedReference, ) -> cppgc::UnsafePtr { - let value = v8::Local::new(scope, value); + let value = value.get(scope).unwrap(); cppgc::try_unwrap_cppgc_proto_object::( scope, - value.cast(), + value.into(), ) .unwrap() } @@ -808,11 +821,23 @@ impl DOMQuad { &self, scope: &mut v8::HandleScope<'a>, ) -> v8::Local<'a, v8::Object> { + #[inline] + fn set_object( + scope: &mut v8::HandleScope, + object: &mut v8::Local, + key: &str, + value: &v8::TracedReference, + ) { + let key = v8::String::new(scope, key).unwrap(); + let value = value.get(scope).unwrap(); + object.create_data_property(scope, key.into(), value.into()); + } + let mut obj = v8::Object::new(scope); - set_object(scope, &mut obj, "p1", self.p1.clone()); - set_object(scope, &mut obj, "p2", self.p2.clone()); - set_object(scope, &mut obj, "p3", self.p3.clone()); - set_object(scope, &mut obj, "p4", self.p4.clone()); + set_object(scope, &mut obj, "p1", &self.p1); + set_object(scope, &mut obj, "p2", &self.p2); + set_object(scope, &mut obj, "p3", &self.p3); + set_object(scope, &mut obj, "p4", &self.p4); obj } } @@ -2889,18 +2914,6 @@ fn set_boolean( object.create_data_property(scope, key.into(), value.into()); } -#[inline] -fn set_object( - scope: &mut v8::HandleScope, - object: &mut v8::Local, - key: &str, - value: v8::Global, -) { - let key = v8::String::new(scope, key).unwrap(); - let value = v8::Local::new(scope, value); - object.create_data_property(scope, key.into(), value.into()); -} - // TODO(petamoriken) Use f64::maximum instead https://github.com/rust-lang/rust/issues/91079 #[inline] fn maximum(a: f64, b: f64) -> f64 { From 27b87831f76c47d0b4ec70237ae140cea075ea9b Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 20 Sep 2025 12:06:06 +0900 Subject: [PATCH 62/63] remove SAFETY comments --- ext/geometry/lib.rs | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 43eb5a1a6e8313..46ef73ef61df5c 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -2301,7 +2301,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_B] = *value; } @@ -2317,7 +2316,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_C] = *value; } @@ -2333,7 +2331,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_D] = *value; } @@ -2349,7 +2346,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_E] = *value; } @@ -2365,7 +2361,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_F] = *value; } @@ -2381,7 +2376,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_M11] = *value; } @@ -2397,7 +2391,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_M12] = *value; } @@ -2413,7 +2406,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_M13] = *value; if *value != 0.0 { ro.is_2d.set(false); @@ -2432,7 +2424,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_M14] = *value; if *value != 0.0 { ro.is_2d.set(false); @@ -2451,7 +2442,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_M21] = *value; } @@ -2467,7 +2457,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_M22] = *value; } @@ -2483,7 +2472,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_M23] = *value; if *value != 0.0 { ro.is_2d.set(false); @@ -2502,7 +2490,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_M24] = *value; if *value != 0.0 { ro.is_2d.set(false); @@ -2521,7 +2508,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_M31] = *value; if *value != 0.0 { ro.is_2d.set(false); @@ -2540,7 +2526,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_M32] = *value; if *value != 0.0 { ro.is_2d.set(false); @@ -2559,7 +2544,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_M33] = *value; if *value != 1.0 { ro.is_2d.set(false); @@ -2578,7 +2562,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_M34] = *value; if *value != 0.0 { ro.is_2d.set(false); @@ -2597,7 +2580,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_M41] = *value; } @@ -2613,7 +2595,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_M42] = *value; } @@ -2629,7 +2610,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_M43] = *value; if *value != 0.0 { ro.is_2d.set(false); @@ -2648,7 +2628,6 @@ impl DOMMatrix { #[webidl] value: webidl::UnrestrictedDouble, #[proto] ro: &DOMMatrixReadOnly, ) { - // SAFETY: in-range access ro.inner.borrow_mut()[INDEX_M44] = *value; if *value != 1.0 { ro.is_2d.set(false); From b9f9025b3fb3427dad06ec9c186762f78a6c5d75 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Thu, 25 Sep 2025 02:39:47 +0900 Subject: [PATCH 63/63] update --- ext/geometry/lib.rs | 100 ++++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 46ef73ef61df5c..7f34f6c67a40c9 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -207,7 +207,7 @@ impl DOMPointReadOnly { #[required(0)] fn to_json<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, ) -> v8::Local<'a, v8::Object> { let mut obj = v8::Object::new(scope); set_f64(scope, &mut obj, "x", self.inner.borrow().x); @@ -221,7 +221,7 @@ impl DOMPointReadOnly { #[required(0)] fn matrix_transform<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, #[webidl] value: DOMMatrixInit, ) -> Result, GeometryError> { let matrix = DOMMatrixReadOnly::from_matrix_inner(&value)?; @@ -271,7 +271,7 @@ impl DOMPoint { #[required(0)] #[static_method] fn from_point<'a>( - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, #[webidl] init: DOMPointInit, ) -> v8::Local<'a, v8::Object> { let ro = DOMPointReadOnly::from_point_inner(init); @@ -489,7 +489,7 @@ impl DOMRectReadOnly { #[required(0)] fn to_json<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, ) -> v8::Local<'a, v8::Object> { let mut obj = v8::Object::new(scope); set_f64(scope, &mut obj, "x", self.x.get()); @@ -539,7 +539,7 @@ impl DOMRect { #[required(0)] #[static_method] fn from_rect<'a>( - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, #[webidl] init: DOMRectInit, ) -> v8::Local<'a, v8::Object> { let ro = DOMRectReadOnly::from_rect_inner(init); @@ -645,7 +645,7 @@ impl DOMQuad { #[required(0)] #[cppgc] fn constructor( - scope: &mut v8::HandleScope, + scope: &mut v8::PinScope<'_, '_>, #[webidl] p1: DOMPointInit, #[webidl] p2: DOMPointInit, #[webidl] p3: DOMPointInit, @@ -653,7 +653,7 @@ impl DOMQuad { ) -> DOMQuad { #[inline] fn from_point( - scope: &mut v8::HandleScope, + scope: &mut v8::PinScope<'_, '_>, point: DOMPointInit, ) -> v8::TracedReference { let ro = DOMPointReadOnly { @@ -679,12 +679,12 @@ impl DOMQuad { #[static_method] #[cppgc] fn from_rect( - scope: &mut v8::HandleScope, + scope: &mut v8::PinScope<'_, '_>, #[webidl] rect: DOMRectInit, ) -> DOMQuad { #[inline] fn create_point( - scope: &mut v8::HandleScope, + scope: &mut v8::PinScope<'_, '_>, x: f64, y: f64, z: f64, @@ -717,12 +717,12 @@ impl DOMQuad { #[static_method] #[cppgc] fn from_quad( - scope: &mut v8::HandleScope, + scope: &mut v8::PinScope<'_, '_>, #[webidl] quad: DOMQuadInit, ) -> DOMQuad { #[inline] fn from_point( - scope: &mut v8::HandleScope, + scope: &mut v8::PinScope<'_, '_>, point: DOMPointInit, ) -> v8::TracedReference { let ro = DOMPointReadOnly { @@ -746,7 +746,7 @@ impl DOMQuad { #[getter] fn p1<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, ) -> v8::Local<'a, v8::Object> { self.p1.get(scope).unwrap() } @@ -754,7 +754,7 @@ impl DOMQuad { #[getter] fn p2<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, ) -> v8::Local<'a, v8::Object> { self.p2.get(scope).unwrap() } @@ -762,7 +762,7 @@ impl DOMQuad { #[getter] fn p3<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, ) -> v8::Local<'a, v8::Object> { self.p3.get(scope).unwrap() } @@ -770,7 +770,7 @@ impl DOMQuad { #[getter] fn p4<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, ) -> v8::Local<'a, v8::Object> { self.p4.get(scope).unwrap() } @@ -778,11 +778,11 @@ impl DOMQuad { #[required(0)] fn get_bounds<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, ) -> v8::Local<'a, v8::Object> { #[inline] fn get_ptr( - scope: &mut v8::HandleScope, + scope: &mut v8::PinScope<'_, '_>, value: &v8::TracedReference, ) -> cppgc::UnsafePtr { let value = value.get(scope).unwrap(); @@ -819,11 +819,11 @@ impl DOMQuad { #[required(0)] fn to_json<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, ) -> v8::Local<'a, v8::Object> { #[inline] fn set_object( - scope: &mut v8::HandleScope, + scope: &mut v8::PinScope<'_, '_>, object: &mut v8::Local, key: &str, value: &v8::TracedReference, @@ -955,7 +955,7 @@ const INDEX_M44: usize = 15; impl DOMMatrixReadOnly { fn new<'a>( state: &mut OpState, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, value: v8::Local<'a, v8::Value>, prefix: Cow<'static, str>, context: ContextFn<'_>, @@ -1634,7 +1634,7 @@ impl DOMMatrixReadOnly { #[cppgc] fn constructor<'a>( state: &mut OpState, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, value: v8::Local<'a, v8::Value>, ) -> Result { DOMMatrixReadOnly::new( @@ -1661,7 +1661,7 @@ impl DOMMatrixReadOnly { #[static_method] #[cppgc] fn from_float32_array<'a>( - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, value: v8::Local<'a, v8::Value>, ) -> Result { if !value.is_float32_array() { @@ -1683,7 +1683,7 @@ impl DOMMatrixReadOnly { #[static_method] #[cppgc] fn from_float64_array<'a>( - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, value: v8::Local<'a, v8::Value>, ) -> Result { if !value.is_float64_array() { @@ -1847,7 +1847,7 @@ impl DOMMatrixReadOnly { #[required(0)] fn translate<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, #[webidl] tx: Option, #[webidl] ty: Option, #[webidl] tz: Option, @@ -1864,7 +1864,7 @@ impl DOMMatrixReadOnly { #[required(0)] fn scale<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, #[webidl] sx: Option, #[webidl] sy: Option, #[webidl] sz: Option, @@ -1892,7 +1892,7 @@ impl DOMMatrixReadOnly { #[required(0)] fn scale_non_uniform<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, #[webidl] sx: Option, #[webidl] sy: Option, ) -> v8::Local<'a, v8::Object> { @@ -1908,7 +1908,7 @@ impl DOMMatrixReadOnly { #[required(0)] fn scale3d<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, #[webidl] scale: Option, #[webidl] origin_x: Option, #[webidl] origin_y: Option, @@ -1933,7 +1933,7 @@ impl DOMMatrixReadOnly { #[required(0)] fn rotate<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, #[webidl] rotate_x: Option, #[webidl] rotate_y: Option, #[webidl] rotate_z: Option, @@ -1962,7 +1962,7 @@ impl DOMMatrixReadOnly { #[required(0)] fn rotate_from_vector<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, #[webidl] x: Option, #[webidl] y: Option, ) -> v8::Local<'a, v8::Object> { @@ -1977,7 +1977,7 @@ impl DOMMatrixReadOnly { #[required(0)] fn rotate_axis_angle<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, #[webidl] x: Option, #[webidl] y: Option, #[webidl] z: Option, @@ -1996,7 +1996,7 @@ impl DOMMatrixReadOnly { #[required(0)] fn skew_x<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, #[webidl] x_deg: Option, ) -> v8::Local<'a, v8::Object> { let x_deg = *x_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); @@ -2009,7 +2009,7 @@ impl DOMMatrixReadOnly { #[required(0)] fn skew_y<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, #[webidl] y_deg: Option, ) -> v8::Local<'a, v8::Object> { let y_deg = *y_deg.unwrap_or(webidl::UnrestrictedDouble(0.0)); @@ -2022,7 +2022,7 @@ impl DOMMatrixReadOnly { #[required(0)] fn multiply<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, other: v8::Local<'a, v8::Value>, ) -> Result, GeometryError> { let out = self.clone(); @@ -2048,7 +2048,7 @@ impl DOMMatrixReadOnly { #[required(0)] fn flip_x<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, ) -> v8::Local<'a, v8::Object> { let out = self.clone(); out.flip_x_inner(); @@ -2059,7 +2059,7 @@ impl DOMMatrixReadOnly { #[required(0)] fn flip_y<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, ) -> v8::Local<'a, v8::Object> { let out = self.clone(); out.flip_y_inner(); @@ -2070,7 +2070,7 @@ impl DOMMatrixReadOnly { #[required(0)] fn inverse<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, ) -> v8::Local<'a, v8::Object> { let out = self.clone(); out.invert_self_inner(); @@ -2082,7 +2082,7 @@ impl DOMMatrixReadOnly { #[required(0)] fn transform_point<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, point: v8::Local<'a, v8::Value>, ) -> Result, GeometryError> { let out = DOMPointReadOnly { @@ -2111,7 +2111,7 @@ impl DOMMatrixReadOnly { #[required(0)] fn to_json<'a>( &self, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, ) -> v8::Local<'a, v8::Object> { let mut obj = v8::Object::new(scope); set_f64(scope, &mut obj, "a", self.a_inner()); @@ -2161,7 +2161,7 @@ impl DOMMatrix { #[cppgc] fn constructor<'a>( state: &mut OpState, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, value: v8::Local<'a, v8::Value>, // TODO(petamoriken): Error when deleting next line. proc-macro bug? #[webidl] _: bool, @@ -2180,7 +2180,7 @@ impl DOMMatrix { #[required(0)] #[static_method] fn from_matrix<'a>( - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, #[webidl] init: DOMMatrixInit, ) -> Result, GeometryError> { let ro = DOMMatrixReadOnly::from_matrix_inner(&init)?; @@ -2192,7 +2192,7 @@ impl DOMMatrix { #[required(1)] #[static_method] fn from_float32_array<'a>( - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, value: v8::Local<'a, v8::Value>, ) -> Result, GeometryError> { if !value.is_float32_array() { @@ -2235,7 +2235,7 @@ impl DOMMatrix { #[required(1)] #[static_method] fn from_float64_array<'a>( - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, value: v8::Local<'a, v8::Value>, ) -> Result, GeometryError> { if !value.is_float64_array() { @@ -2798,7 +2798,7 @@ impl DOMMatrix { fn multiply_self<'a>( &self, #[this] this: v8::Global, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, other: v8::Local<'a, v8::Value>, #[proto] ro: &DOMMatrixReadOnly, ) -> Result, GeometryError> { @@ -2830,7 +2830,7 @@ impl DOMMatrix { fn pre_multiply_self<'a>( &self, #[this] this: v8::Global, - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, other: v8::Local<'a, v8::Value>, #[proto] ro: &DOMMatrixReadOnly, ) -> Result, GeometryError> { @@ -2871,7 +2871,7 @@ impl DOMMatrix { #[inline] fn set_f64( - scope: &mut v8::HandleScope, + scope: &mut v8::PinScope<'_, '_>, object: &mut v8::Local, key: &str, value: f64, @@ -2883,7 +2883,7 @@ fn set_f64( #[inline] fn set_boolean( - scope: &mut v8::HandleScope, + scope: &mut v8::PinScope<'_, '_>, object: &mut v8::Local, key: &str, value: bool, @@ -2946,7 +2946,7 @@ fn matrix_transform_point( #[op2] #[arraybuffer] pub fn op_geometry_matrix_to_buffer<'a>( - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, matrix: v8::Local<'a, v8::Value>, ) -> Result, GeometryError> { let Some(matrix) = @@ -2970,11 +2970,11 @@ pub fn op_geometry_matrix_to_buffer<'a>( #[op2] #[string] pub fn op_geometry_matrix_to_string<'a>( - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, matrix: v8::Local<'a, v8::Value>, ) -> Result { #[inline] - fn to_string(scope: &mut v8::HandleScope, value: f64) -> String { + fn to_string(scope: &mut v8::PinScope<'_, '_>, value: f64) -> String { let number = v8::Number::new(scope, value); number.to_string(scope).unwrap().to_rust_string_lossy(scope) } @@ -3013,7 +3013,7 @@ pub fn op_geometry_matrix_to_string<'a>( #[op2(fast)] pub fn op_geometry_matrix_set_matrix_value<'a>( - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, input: v8::Local<'a, v8::Value>, transform_list: v8::Local<'a, v8::Value>, ) -> Result<(), GeometryError> {