From 70eeca96b41d92e07f2468bd6374ae324c2642ab Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 22 Jan 2024 00:31:19 +0900 Subject: [PATCH 01/66] feat: add `DOMPoint` --- Cargo.lock | 8 ++ Cargo.toml | 6 + cli/build.rs | 1 + cli/tsc/dts/lib.deno.shared_globals.d.ts | 1 + cli/tsc/mod.rs | 1 + ext/geometry/01_geometry.js | 159 +++++++++++++++++++++++ ext/geometry/Cargo.toml | 17 +++ ext/geometry/README.md | 5 + ext/geometry/lib.deno_geometry.d.ts | 4 + ext/geometry/lib.rs | 13 ++ runtime/Cargo.toml | 2 + runtime/js/98_global_scope_shared.js | 3 + runtime/lib.rs | 1 + runtime/shared.rs | 1 + runtime/snapshot.rs | 1 + runtime/web_worker.rs | 1 + runtime/worker.rs | 1 + tools/core_import_map.json | 1 + 18 files changed, 226 insertions(+) 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 diff --git a/Cargo.lock b/Cargo.lock index 979fffc169580f..362aa0ff7847c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1401,6 +1401,13 @@ dependencies = [ "winapi", ] +[[package]] +name = "deno_geometry" +version = "0.1.0" +dependencies = [ + "deno_core", +] + [[package]] name = "deno_graph" version = "0.65.1" @@ -1704,6 +1711,7 @@ dependencies = [ "deno_fetch", "deno_ffi", "deno_fs", + "deno_geometry", "deno_http", "deno_io", "deno_kv", diff --git a/Cargo.toml b/Cargo.toml index bf075418fc00ee..7cfa483c49a952 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ members = [ "ext/fetch", "ext/ffi", "ext/fs", + "ext/geometry", "ext/http", "ext/io", "ext/kv", @@ -68,6 +69,7 @@ deno_crypto = { version = "0.151.0", path = "./ext/crypto" } deno_fetch = { version = "0.161.0", path = "./ext/fetch" } deno_ffi = { version = "0.124.0", path = "./ext/ffi" } deno_fs = { version = "0.47.0", path = "./ext/fs" } +deno_geometry = { version = "0.1.0", path = "./ext/geometry" } deno_http = { version = "0.134.0", path = "./ext/http" } deno_io = { version = "0.47.0", path = "./ext/io" } deno_kv = { version = "0.45.0", path = "./ext/kv" } @@ -257,6 +259,8 @@ opt-level = 3 opt-level = 3 [profile.bench.package.deno_crypto] opt-level = 3 +[profile.bench.package.deno_geometry] +opt-level = 3 [profile.bench.package.deno_node] opt-level = 3 [profile.bench.package.num-bigint-dig] @@ -315,6 +319,8 @@ opt-level = 3 opt-level = 3 [profile.release.package.deno_crypto] opt-level = 3 +[profile.release.package.deno_geometry] +opt-level = 3 [profile.release.package.deno_node] opt-level = 3 [profile.release.package.deno_broadcast_channel] diff --git a/cli/build.rs b/cli/build.rs index 5fd6ca4d50e68b..c6b9ada7901bba 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -149,6 +149,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 86bf8237eceb0c..97f44555277379 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 18316b750eca29..de00c5bf4b9dfe 100644 --- a/cli/tsc/mod.rs +++ b/cli/tsc/mod.rs @@ -96,6 +96,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/01_geometry.js b/ext/geometry/01_geometry.js new file mode 100644 index 00000000000000..0f07f890aeb408 --- /dev/null +++ b/ext/geometry/01_geometry.js @@ -0,0 +1,159 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +import { primordials } from "ext:core/mod.js"; +const { + ObjectPrototypeIsPrototypeOf, + Symbol, + SymbolFor, +} = primordials; + +import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; +import * as webidl from "ext:deno_webidl/00_webidl.js"; + +const _brand = webidl.brand; + +const _x = Symbol("[[x]]"); +const _y = Symbol("[[y]]"); +const _z = Symbol("[[z]]"); +const _w = Symbol("[[w]]"); + +class DOMPointReadOnly { + [_x]; + [_y]; + [_z]; + [_w]; + + constructor(x = 0, y = 0, z = 0, w = 1) { + this[_x] = webidl.converters["unrestricted double"](x); + this[_y] = webidl.converters["unrestricted double"](y); + this[_z] = webidl.converters["unrestricted double"](z); + this[_w] = webidl.converters["unrestricted double"](w); + this[_brand] = _brand; + } + + static fromPoint(other = {}) { + return new DOMPointReadOnly( + other.x, + other.y, + other.z, + other.w, + ); + } + + get x() { + webidl.assertBranded(this, DOMPointReadOnlyPrototype); + return this[_x]; + } + get y() { + webidl.assertBranded(this, DOMPointReadOnlyPrototype); + return this[_y]; + } + get z() { + webidl.assertBranded(this, DOMPointReadOnlyPrototype); + return this[_z]; + } + get w() { + webidl.assertBranded(this, DOMPointReadOnlyPrototype); + return this[_w]; + } + + // TODO + matrixTransform() {} + + toJSON() { + webidl.assertBranded(this, DOMPointReadOnlyPrototype); + return { + x: this[_x], + y: this[_y], + z: this[_z], + w: this[_w], + }; + } + + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf(DOMPointReadOnlyPrototype, this), + keys: [ + "x", + "y", + "z", + "w", + ], + }), + inspectOptions, + ); + } +} + +const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; + +class DOMPoint extends DOMPointReadOnly { + static fromPoint(other = {}) { + return new DOMPoint( + other.x, + other.y, + other.z, + other.w, + ); + } + + get x() { + webidl.assertBranded(this, DOMPointPrototype); + return this[_x]; + } + set x(value) { + webidl.assertBranded(this, DOMPointPrototype); + this[_x] = webidl.converters["unrestricted double"](value); + } + get y() { + webidl.assertBranded(this, DOMPointPrototype); + return this[_y]; + } + set y(value) { + webidl.assertBranded(this, DOMPointPrototype); + this[_y] = webidl.converters["unrestricted double"](value); + } + get z() { + webidl.assertBranded(this, DOMPointPrototype); + return this[_z]; + } + set z(value) { + webidl.assertBranded(this, DOMPointPrototype); + this[_z] = webidl.converters["unrestricted double"](value); + } + get w() { + webidl.assertBranded(this, DOMPointPrototype); + return this[_w]; + } + set w(value) { + webidl.assertBranded(this, DOMPointPrototype); + this[_w] = 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, + ); + } +} + +const DOMPointPrototype = DOMPoint.prototype; + +export { + DOMPoint, + DOMPointPrototype, + DOMPointReadOnly, + DOMPointReadOnlyPrototype, +}; diff --git a/ext/geometry/Cargo.toml b/ext/geometry/Cargo.toml new file mode 100644 index 00000000000000..99d9f9282f61eb --- /dev/null +++ b/ext/geometry/Cargo.toml @@ -0,0 +1,17 @@ +# 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 diff --git a/ext/geometry/README.md b/ext/geometry/README.md new file mode 100644 index 00000000000000..a8ea2cba96ce81 --- /dev/null +++ b/ext/geometry/README.md @@ -0,0 +1,5 @@ +# deno_geometry + +This crate implements the Geometry Interfaces Module API. + +Spec: https://drafts.fxtf.org/geometry/ diff --git a/ext/geometry/lib.deno_geometry.d.ts b/ext/geometry/lib.deno_geometry.d.ts new file mode 100644 index 00000000000000..e8b3fa1927454a --- /dev/null +++ b/ext/geometry/lib.deno_geometry.d.ts @@ -0,0 +1,4 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +/// +/// diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs new file mode 100644 index 00000000000000..7df5efa1014f7e --- /dev/null +++ b/ext/geometry/lib.rs @@ -0,0 +1,13 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use std::path::PathBuf; + +deno_core::extension!( + deno_geometry, + deps = [deno_webidl, deno_console], + esm = ["01_geometry.js"], +); + +pub fn get_declaration() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_geometry.d.ts") +} diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 408518975b616d..4cc1792647e9b6 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -52,6 +52,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 @@ -84,6 +85,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_shared.js b/runtime/js/98_global_scope_shared.js index aba0f3710f42a2..d05b1b5f331785 100644 --- a/runtime/js/98_global_scope_shared.js +++ b/runtime/js/98_global_scope_shared.js @@ -26,6 +26,7 @@ import * as request from "ext:deno_fetch/23_request.js"; import * as response from "ext:deno_fetch/23_response.js"; import * as fetch from "ext:deno_fetch/26_fetch.js"; import * as eventSource from "ext:deno_fetch/27_eventsource.js"; +import * as geometry from "ext:deno_geometry/01_geometry.js"; import * as messagePort from "ext:deno_web/13_message_port.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; import { DOMException } from "ext:deno_web/01_dom_exception.js"; @@ -54,6 +55,8 @@ const windowOrWorkerGlobalScope = { CustomEvent: core.propNonEnumerable(event.CustomEvent), DecompressionStream: core.propNonEnumerable(compression.DecompressionStream), DOMException: core.propNonEnumerable(DOMException), + DOMPoint: core.propNonEnumerable(geometry.DOMPoint), + DOMPointReadOnly: core.propNonEnumerable(geometry.DOMPointReadOnly), ErrorEvent: core.propNonEnumerable(event.ErrorEvent), Event: core.propNonEnumerable(event.Event), EventTarget: core.propNonEnumerable(event.EventTarget), diff --git a/runtime/lib.rs b/runtime/lib.rs index b63fd41340b538..2a79dea4f3348b 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 04fcdcfdb725d8..f6dc0a6994b2b9 100644 --- a/runtime/shared.rs +++ b/runtime/shared.rs @@ -20,6 +20,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 b23b024ee1358e..01497f7b732b44 100644 --- a/runtime/snapshot.rs +++ b/runtime/snapshot.rs @@ -214,6 +214,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 b21833a2e48137..32eeb4a35e3cd9 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -423,6 +423,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 449c50e10d5f7e..8c2476d4160c04 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -358,6 +358,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/tools/core_import_map.json b/tools/core_import_map.json index 9e70f52f7fbb06..02cb88666f19ca 100644 --- a/tools/core_import_map.json +++ b/tools/core_import_map.json @@ -15,6 +15,7 @@ "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/01_geometry.js": "../ext/geometry/01_geometry.js", "ext:deno_http/00_serve.js": "../ext/http/00_serve.js", "ext:deno_http/01_http.js": "../ext/http/01_http.js", "ext:deno_io/12_io.js": "../ext/io/12_io.js", From a84a51249de83a0a0f43db05dab3766d4123f47e Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 22 Jan 2024 01:39:53 +0900 Subject: [PATCH 02/66] add `DOMRect` --- ext/geometry/01_geometry.js | 167 +++++++++++++++++++++++++++ runtime/js/98_global_scope_shared.js | 2 + 2 files changed, 169 insertions(+) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 0f07f890aeb408..d85b67a692558f 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -2,6 +2,8 @@ import { primordials } from "ext:core/mod.js"; const { + MathMax, + MathMin, ObjectPrototypeIsPrototypeOf, Symbol, SymbolFor, @@ -16,6 +18,8 @@ const _x = Symbol("[[x]]"); const _y = Symbol("[[y]]"); const _z = Symbol("[[z]]"); const _w = Symbol("[[w]]"); +const _width = Symbol("[[width]]"); +const _height = Symbol("[[height]]"); class DOMPointReadOnly { [_x]; @@ -151,9 +155,172 @@ class DOMPoint extends DOMPointReadOnly { const DOMPointPrototype = DOMPoint.prototype; +class DOMRectReadOnly { + [_x]; + [_y]; + [_width]; + [_height]; + + constructor(x = 0, y = 0, width = 0, height = 0) { + this[_x] = webidl.converters["unrestricted double"](x); + this[_y] = webidl.converters["unrestricted double"](y); + this[_width] = webidl.converters["unrestricted double"](width); + this[_height] = webidl.converters["unrestricted double"](height); + this[_brand] = _brand; + } + + static fromRect(other = {}) { + return new DOMRectReadOnly( + other.x, + other.y, + other.width, + other.height, + ); + } + + get x() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + return this[_x]; + } + get y() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + return this[_y]; + } + get width() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + return this[_width]; + } + get height() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + return this[_height]; + } + get top() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + return MathMin(this[_y], this[_y] + this[_height]); + } + get right() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + return MathMax(this[_x], this[_x] + this[_width]); + } + get bottom() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + return MathMax(this[_y], this[_y] + this[_height]); + } + get left() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + return MathMin(this[_x], this[_x] + this[_width]); + } + + toJSON() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + return { + x: this[_x], + y: this[_y], + width: this[_width], + height: this[_height], + top: MathMin(this[_y], this[_y] + this[_height]), + right: MathMax(this[_x], this[_x] + this[_width]), + bottom: MathMax(this[_y], this[_y] + this[_height]), + left: MathMin(this[_x], this[_x] + this[_width]), + }; + } + + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf(DOMRectReadOnlyPrototype, this), + keys: [ + "x", + "y", + "width", + "height", + "top", + "right", + "bottom", + "left", + ], + }), + inspectOptions, + ); + } +} + +const DOMRectReadOnlyPrototype = DOMRectReadOnly.prototype; + +class DOMRect extends DOMRectReadOnly { + static fromRect(other = {}) { + return new DOMRect( + other.x, + other.y, + other.width, + other.height, + ); + } + + get x() { + webidl.assertBranded(this, DOMRectPrototype); + return this[_x]; + } + set x(value) { + webidl.assertBranded(this, DOMRectPrototype); + this[_x] = webidl.converters["unrestricted double"](value); + } + get y() { + webidl.assertBranded(this, DOMRectPrototype); + return this[_y]; + } + set y(value) { + webidl.assertBranded(this, DOMRectPrototype); + this[_y] = webidl.converters["unrestricted double"](value); + } + get width() { + webidl.assertBranded(this, DOMRectPrototype); + return this[_width]; + } + set width(value) { + webidl.assertBranded(this, DOMRectPrototype); + this[_width] = webidl.converters["unrestricted double"](value); + } + get height() { + webidl.assertBranded(this, DOMRectPrototype); + return this[_height]; + } + set height(value) { + webidl.assertBranded(this, DOMRectPrototype); + this[_height] = 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, + ); + } +} + +const DOMRectPrototype = DOMRect.prototype; + export { DOMPoint, DOMPointPrototype, DOMPointReadOnly, DOMPointReadOnlyPrototype, + DOMRect, + DOMRectPrototype, + DOMRectReadOnly, + DOMRectReadOnlyPrototype, }; diff --git a/runtime/js/98_global_scope_shared.js b/runtime/js/98_global_scope_shared.js index d05b1b5f331785..1fc647effed855 100644 --- a/runtime/js/98_global_scope_shared.js +++ b/runtime/js/98_global_scope_shared.js @@ -57,6 +57,8 @@ const windowOrWorkerGlobalScope = { DOMException: core.propNonEnumerable(DOMException), DOMPoint: core.propNonEnumerable(geometry.DOMPoint), DOMPointReadOnly: core.propNonEnumerable(geometry.DOMPointReadOnly), + DOMRect: core.propNonEnumerable(geometry.DOMRect), + DOMRectReadOnly: core.propNonEnumerable(geometry.DOMRectReadOnly), ErrorEvent: core.propNonEnumerable(event.ErrorEvent), Event: core.propNonEnumerable(event.Event), EventTarget: core.propNonEnumerable(event.EventTarget), From 90b3dde5f1a547099d8190fb44d2dd31e5fd9ee5 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 24 Jan 2024 00:19:46 +0900 Subject: [PATCH 03/66] use `Float64Array` --- ext/geometry/01_geometry.js | 125 ++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 63 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index d85b67a692558f..b1b08fc2e48519 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -2,6 +2,7 @@ import { primordials } from "ext:core/mod.js"; const { + Float64Array, MathMax, MathMin, ObjectPrototypeIsPrototypeOf, @@ -12,26 +13,19 @@ const { import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; +const _raw = Symbol("[[raw]]"); const _brand = webidl.brand; -const _x = Symbol("[[x]]"); -const _y = Symbol("[[y]]"); -const _z = Symbol("[[z]]"); -const _w = Symbol("[[w]]"); -const _width = Symbol("[[width]]"); -const _height = Symbol("[[height]]"); - class DOMPointReadOnly { - [_x]; - [_y]; - [_z]; - [_w]; + [_raw]; constructor(x = 0, y = 0, z = 0, w = 1) { - this[_x] = webidl.converters["unrestricted double"](x); - this[_y] = webidl.converters["unrestricted double"](y); - this[_z] = webidl.converters["unrestricted double"](z); - this[_w] = webidl.converters["unrestricted double"](w); + 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; } @@ -46,19 +40,19 @@ class DOMPointReadOnly { get x() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - return this[_x]; + return this[_raw][0]; } get y() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - return this[_y]; + return this[_raw][1]; } get z() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - return this[_z]; + return this[_raw][2]; } get w() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - return this[_w]; + return this[_raw][3]; } // TODO @@ -66,11 +60,12 @@ class DOMPointReadOnly { toJSON() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); + const raw = this[_raw]; return { - x: this[_x], - y: this[_y], - z: this[_z], - w: this[_w], + x: raw[0], + y: raw[1], + z: raw[2], + w: raw[3], }; } @@ -105,35 +100,35 @@ class DOMPoint extends DOMPointReadOnly { get x() { webidl.assertBranded(this, DOMPointPrototype); - return this[_x]; + return this[_raw][0]; } set x(value) { webidl.assertBranded(this, DOMPointPrototype); - this[_x] = webidl.converters["unrestricted double"](value); + this[_raw][0] = webidl.converters["unrestricted double"](value); } get y() { webidl.assertBranded(this, DOMPointPrototype); - return this[_y]; + return this[_raw][1]; } set y(value) { webidl.assertBranded(this, DOMPointPrototype); - this[_y] = webidl.converters["unrestricted double"](value); + this[_raw][1] = webidl.converters["unrestricted double"](value); } get z() { webidl.assertBranded(this, DOMPointPrototype); - return this[_z]; + return this[_raw][2]; } set z(value) { webidl.assertBranded(this, DOMPointPrototype); - this[_z] = webidl.converters["unrestricted double"](value); + this[_raw][2] = webidl.converters["unrestricted double"](value); } get w() { webidl.assertBranded(this, DOMPointPrototype); - return this[_w]; + return this[_raw][3]; } set w(value) { webidl.assertBranded(this, DOMPointPrototype); - this[_w] = webidl.converters["unrestricted double"](value); + this[_raw][3] = webidl.converters["unrestricted double"](value); } [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { @@ -156,16 +151,15 @@ class DOMPoint extends DOMPointReadOnly { const DOMPointPrototype = DOMPoint.prototype; class DOMRectReadOnly { - [_x]; - [_y]; - [_width]; - [_height]; + [_raw]; constructor(x = 0, y = 0, width = 0, height = 0) { - this[_x] = webidl.converters["unrestricted double"](x); - this[_y] = webidl.converters["unrestricted double"](y); - this[_width] = webidl.converters["unrestricted double"](width); - this[_height] = webidl.converters["unrestricted double"](height); + this[_raw] = new Float32Array([ + webidl.converters["unrestricted double"](x), + webidl.converters["unrestricted double"](y), + webidl.converters["unrestricted double"](width), + webidl.converters["unrestricted double"](height), + ]); this[_brand] = _brand; } @@ -180,48 +174,53 @@ class DOMRectReadOnly { get x() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_x]; + return this[_raw][0]; } get y() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_y]; + return this[_raw][1]; } get width() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_width]; + return this[_raw][2]; } get height() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_height]; + return this[_raw][3]; } get top() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return MathMin(this[_y], this[_y] + this[_height]); + const raw = this[_raw]; + return MathMin(raw[1], raw[1] + raw[3]); } get right() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return MathMax(this[_x], this[_x] + this[_width]); + const raw = this[_raw]; + return MathMax(raw[0], raw[0] + raw[2]); } get bottom() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return MathMax(this[_y], this[_y] + this[_height]); + const raw = this[_raw]; + return MathMax(raw[1], raw[1] + raw[3]); } get left() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return MathMin(this[_x], this[_x] + this[_width]); + const raw = this[_raw]; + return MathMin(raw[0], raw[0] + raw[2]); } toJSON() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); + const raw = this[_raw]; return { - x: this[_x], - y: this[_y], - width: this[_width], - height: this[_height], - top: MathMin(this[_y], this[_y] + this[_height]), - right: MathMax(this[_x], this[_x] + this[_width]), - bottom: MathMax(this[_y], this[_y] + this[_height]), - left: MathMin(this[_x], this[_x] + this[_width]), + 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]), }; } @@ -260,35 +259,35 @@ class DOMRect extends DOMRectReadOnly { get x() { webidl.assertBranded(this, DOMRectPrototype); - return this[_x]; + return this[_raw][0]; } set x(value) { webidl.assertBranded(this, DOMRectPrototype); - this[_x] = webidl.converters["unrestricted double"](value); + this[_raw][0] = webidl.converters["unrestricted double"](value); } get y() { webidl.assertBranded(this, DOMRectPrototype); - return this[_y]; + return this[_raw][1]; } set y(value) { webidl.assertBranded(this, DOMRectPrototype); - this[_y] = webidl.converters["unrestricted double"](value); + this[_raw][1] = webidl.converters["unrestricted double"](value); } get width() { webidl.assertBranded(this, DOMRectPrototype); - return this[_width]; + return this[_raw][2]; } set width(value) { webidl.assertBranded(this, DOMRectPrototype); - this[_width] = webidl.converters["unrestricted double"](value); + this[_raw][2] = webidl.converters["unrestricted double"](value); } get height() { webidl.assertBranded(this, DOMRectPrototype); - return this[_height]; + return this[_raw][3]; } set height(value) { webidl.assertBranded(this, DOMRectPrototype); - this[_height] = webidl.converters["unrestricted double"](value); + this[_raw][3] = webidl.converters["unrestricted double"](value); } [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { From e887135662e609c74ffe751f3f3dfe8633cd96a5 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 24 Jan 2024 01:02:57 +0900 Subject: [PATCH 04/66] use `webidl.createDictionaryConverter` --- ext/geometry/01_geometry.js | 72 +++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index b1b08fc2e48519..9bff846418cb9e 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -13,6 +13,58 @@ const { import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; import * as webidl from "ext:deno_webidl/00_webidl.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, + }, + ], +); + const _raw = Symbol("[[raw]]"); const _brand = webidl.brand; @@ -30,6 +82,11 @@ class DOMPointReadOnly { } static fromPoint(other = {}) { + other = webidl.converters["DOMPointInit"]( + other, + "Failed to call 'DOMPointReadOnly.fromPoint'", + "Argument 1", + ); return new DOMPointReadOnly( other.x, other.y, @@ -90,6 +147,11 @@ const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; class DOMPoint extends DOMPointReadOnly { static fromPoint(other = {}) { + other = webidl.converters["DOMPointInit"]( + other, + "Failed to call 'DOMPoint.fromPoint'", + "Argument 1", + ); return new DOMPoint( other.x, other.y, @@ -164,6 +226,11 @@ class DOMRectReadOnly { } static fromRect(other = {}) { + other = webidl.converters["DOMRectInit"]( + other, + "Failed to call 'DOMRectReadOnly.fromRect'", + "Argument 1", + ); return new DOMRectReadOnly( other.x, other.y, @@ -249,6 +316,11 @@ const DOMRectReadOnlyPrototype = DOMRectReadOnly.prototype; class DOMRect extends DOMRectReadOnly { static fromRect(other = {}) { + other = webidl.converters["DOMRectInit"]( + other, + "Failed to call 'DOMRect.fromRect'", + "Argument 1", + ); return new DOMRect( other.x, other.y, From 39fa46366c6761db122d95010414878304776b5e Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 24 Jan 2024 01:11:49 +0900 Subject: [PATCH 05/66] tweak --- ext/geometry/01_geometry.js | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 9bff846418cb9e..ef7e7d83525cd4 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -87,12 +87,14 @@ class DOMPointReadOnly { "Failed to call 'DOMPointReadOnly.fromPoint'", "Argument 1", ); - return new DOMPointReadOnly( + const point = webidl.createBranded(DOMPointReadOnly); + point[_raw] = new Float64Array([ other.x, other.y, other.z, other.w, - ); + ]); + return point; } get x() { @@ -152,12 +154,14 @@ class DOMPoint extends DOMPointReadOnly { "Failed to call 'DOMPoint.fromPoint'", "Argument 1", ); - return new DOMPoint( + const point = webidl.createBranded(DOMPoint); + point[_raw] = new Float64Array([ other.x, other.y, other.z, other.w, - ); + ]); + return point; } get x() { @@ -216,7 +220,7 @@ class DOMRectReadOnly { [_raw]; constructor(x = 0, y = 0, width = 0, height = 0) { - this[_raw] = new Float32Array([ + this[_raw] = new Float64Array([ webidl.converters["unrestricted double"](x), webidl.converters["unrestricted double"](y), webidl.converters["unrestricted double"](width), @@ -231,12 +235,14 @@ class DOMRectReadOnly { "Failed to call 'DOMRectReadOnly.fromRect'", "Argument 1", ); - return new DOMRectReadOnly( + const rect = webidl.createBranded(DOMRectReadOnly); + rect[_raw] = new Float64Array([ other.x, other.y, other.width, other.height, - ); + ]); + return rect; } get x() { @@ -321,12 +327,14 @@ class DOMRect extends DOMRectReadOnly { "Failed to call 'DOMRect.fromRect'", "Argument 1", ); - return new DOMRect( + const rect = webidl.createBranded(DOMRect); + rect[_raw] = new Float64Array([ other.x, other.y, other.width, other.height, - ); + ]); + return rect; } get x() { From 5cfb1f704ee2eb1560541323b918d5286d92242c Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 24 Jan 2024 02:53:57 +0900 Subject: [PATCH 06/66] add `DOMQuad` --- ext/geometry/01_geometry.js | 140 +++++++++++++++++++++++++++ runtime/js/98_global_scope_shared.js | 1 + 2 files changed, 141 insertions(+) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index ef7e7d83525cd4..ff7a46c9e78f05 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -65,6 +65,28 @@ webidl.converters["DOMRectInit"] = webidl.createDictionaryConverter( ], ); +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 _raw = Symbol("[[raw]]"); const _brand = webidl.brand; @@ -393,6 +415,122 @@ class DOMRect extends DOMRectReadOnly { const DOMRectPrototype = DOMRect.prototype; +const _p1 = Symbol("[[p1]]"); +const _p2 = Symbol("[[p2]]"); +const _p3 = Symbol("[[p3]]"); +const _p4 = Symbol("[[p4]]"); + +class DOMQuad { + [_p1]; + [_p2]; + [_p3]; + [_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 call 'DOMQuad.fromRect'", + "Argument 1", + ); + const { x, y, width, height } = other; + const point = webidl.createBranded(DOMQuad); + point[_p1] = new DOMPoint(x, y, 0, 1); + point[_p2] = new DOMPoint(x + width, y, 0, 1); + point[_p3] = new DOMPoint(x + width, y + height, 0, 1); + point[_p4] = new DOMPoint(x, y + height, 0, 1); + return point; + } + + static fromQuad(other = {}) { + other = webidl.converters["DOMQuadInit"]( + other, + "Failed to call 'DOMQuad.fromQuad'", + "Argument 1", + ); + const point = webidl.createBranded(DOMQuad); + point[_p1] = new DOMPoint.fromPoint(other.p1); + point[_p2] = new DOMPoint.fromPoint(other.p2); + point[_p3] = new DOMPoint.fromPoint(other.p3); + point[_p4] = new DOMPoint.fromPoint(other.p4); + return point; + } + + 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[_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, + ); + } +} + +const DOMQuadPrototype = DOMQuad.prototype; + export { DOMPoint, DOMPointPrototype, @@ -402,4 +540,6 @@ export { DOMRectPrototype, DOMRectReadOnly, DOMRectReadOnlyPrototype, + DOMQuad, + DOMQuadPrototype, }; diff --git a/runtime/js/98_global_scope_shared.js b/runtime/js/98_global_scope_shared.js index 1fc647effed855..e4d85166c546b0 100644 --- a/runtime/js/98_global_scope_shared.js +++ b/runtime/js/98_global_scope_shared.js @@ -57,6 +57,7 @@ const windowOrWorkerGlobalScope = { DOMException: core.propNonEnumerable(DOMException), DOMPoint: core.propNonEnumerable(geometry.DOMPoint), DOMPointReadOnly: core.propNonEnumerable(geometry.DOMPointReadOnly), + DOMQuad: core.propNonEnumerable(geometry.DOMQuad), DOMRect: core.propNonEnumerable(geometry.DOMRect), DOMRectReadOnly: core.propNonEnumerable(geometry.DOMRectReadOnly), ErrorEvent: core.propNonEnumerable(event.ErrorEvent), From 78b453f49e55260d5bca2dd9acaae629848a5cb7 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 24 Jan 2024 03:30:46 +0900 Subject: [PATCH 07/66] fix --- ext/geometry/01_geometry.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index ff7a46c9e78f05..5ebaa4c87f30fc 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -456,10 +456,10 @@ class DOMQuad { "Argument 1", ); const point = webidl.createBranded(DOMQuad); - point[_p1] = new DOMPoint.fromPoint(other.p1); - point[_p2] = new DOMPoint.fromPoint(other.p2); - point[_p3] = new DOMPoint.fromPoint(other.p3); - point[_p4] = new DOMPoint.fromPoint(other.p4); + point[_p1] = DOMPoint.fromPoint(other.p1); + point[_p2] = DOMPoint.fromPoint(other.p2); + point[_p3] = DOMPoint.fromPoint(other.p3); + point[_p4] = DOMPoint.fromPoint(other.p4); return point; } From 478af5611b9507518879335989119a593e57ae61 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 26 Jan 2024 01:52:07 +0900 Subject: [PATCH 08/66] tweak --- ext/geometry/01_geometry.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 5ebaa4c87f30fc..569c16f1b8b480 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -13,7 +13,7 @@ const { import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; -webidl.converters["DOMPointInit"] = webidl.createDictionaryConverter( +webidl.converters.DOMPointInit = webidl.createDictionaryConverter( "DOMPointInit", [ { @@ -39,7 +39,7 @@ webidl.converters["DOMPointInit"] = webidl.createDictionaryConverter( ], ); -webidl.converters["DOMRectInit"] = webidl.createDictionaryConverter( +webidl.converters.DOMRectInit = webidl.createDictionaryConverter( "DOMRectInit", [ { @@ -65,24 +65,24 @@ webidl.converters["DOMRectInit"] = webidl.createDictionaryConverter( ], ); -webidl.converters["DOMQuadInit"] = webidl.createDictionaryConverter( +webidl.converters.DOMQuadInit = webidl.createDictionaryConverter( "DOMQuadInit", [ { key: "p1", - converter: webidl.converters["DOMPointInit"], + converter: webidl.converters.DOMPointInit, }, { key: "p2", - converter: webidl.converters["DOMPointInit"], + converter: webidl.converters.DOMPointInit, }, { key: "p3", - converter: webidl.converters["DOMPointInit"], + converter: webidl.converters.DOMPointInit, }, { key: "p4", - converter: webidl.converters["DOMPointInit"], + converter: webidl.converters.DOMPointInit, }, ], ); @@ -104,7 +104,7 @@ class DOMPointReadOnly { } static fromPoint(other = {}) { - other = webidl.converters["DOMPointInit"]( + other = webidl.converters.DOMPointInit( other, "Failed to call 'DOMPointReadOnly.fromPoint'", "Argument 1", @@ -171,7 +171,7 @@ const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; class DOMPoint extends DOMPointReadOnly { static fromPoint(other = {}) { - other = webidl.converters["DOMPointInit"]( + other = webidl.converters.DOMPointInit( other, "Failed to call 'DOMPoint.fromPoint'", "Argument 1", @@ -252,7 +252,7 @@ class DOMRectReadOnly { } static fromRect(other = {}) { - other = webidl.converters["DOMRectInit"]( + other = webidl.converters.DOMRectInit( other, "Failed to call 'DOMRectReadOnly.fromRect'", "Argument 1", @@ -344,7 +344,7 @@ const DOMRectReadOnlyPrototype = DOMRectReadOnly.prototype; class DOMRect extends DOMRectReadOnly { static fromRect(other = {}) { - other = webidl.converters["DOMRectInit"]( + other = webidl.converters.DOMRectInit( other, "Failed to call 'DOMRect.fromRect'", "Argument 1", @@ -435,7 +435,7 @@ class DOMQuad { } static fromRect(other = {}) { - other = webidl.converters["DOMRectInit"]( + other = webidl.converters.DOMRectInit( other, "Failed to call 'DOMQuad.fromRect'", "Argument 1", @@ -450,7 +450,7 @@ class DOMQuad { } static fromQuad(other = {}) { - other = webidl.converters["DOMQuadInit"]( + other = webidl.converters.DOMQuadInit( other, "Failed to call 'DOMQuad.fromQuad'", "Argument 1", From 2ff44de72116fd261d733ace8d52521a2544db29 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 26 Jan 2024 02:09:38 +0900 Subject: [PATCH 09/66] add `DOMMatrix` except transform methods --- ext/geometry/01_geometry.js | 823 ++++++++++++++++++++++++++- ext/webidl/00_webidl.js | 3 + ext/webidl/internal.d.ts | 6 + runtime/js/98_global_scope_shared.js | 2 + 4 files changed, 832 insertions(+), 2 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 569c16f1b8b480..c6283db5c434db 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -2,12 +2,15 @@ import { primordials } from "ext:core/mod.js"; const { + Float32Array, Float64Array, MathMax, MathMin, + ObjectIs, ObjectPrototypeIsPrototypeOf, Symbol, SymbolFor, + TypeError, } = primordials; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; @@ -87,6 +90,116 @@ webidl.converters.DOMQuadInit = webidl.createDictionaryConverter( ], ); +webidl.converters.DOMMatrixInit = webidl.createDictionaryConverter( + "DOMMatrixInit", + [ + { + 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"], + }, + ], + [ + { + 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]]"); const _brand = webidl.brand; @@ -531,15 +644,721 @@ class DOMQuad { const DOMQuadPrototype = DOMQuad.prototype; +const _a = 0; +const _b = 1; +const _c = 4; +const _d = 5; +const _e = 12; +const _f = 13; +const _m11 = 0; +const _m12 = 1; +const _m13 = 2; +const _m14 = 3; +const _m21 = 4; +const _m22 = 5; +const _m23 = 6; +const _m24 = 7; +const _m31 = 8; +const _m32 = 9; +const _m33 = 10; +const _m34 = 11; +const _m41 = 12; +const _m42 = 13; +const _m43 = 14; +const _m44 = 15; +const _is2D = Symbol("[[is2D]]"); + +class DOMMatrixReadOnly { + [_raw]; + [_is2D]; + + constructor(init = undefined) { + const prefix = `Failed to construct '${this.constructor.name}'`; + if (typeof init === "string") { + // TODO(petamoriken): Add parser in Window global object + throw new TypeError( + `${prefix}: CSS parser is not implemented`, + ); + } + 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 { + init = webidl.converters["sequence"]( + init, + prefix, + "Argument 1", + ); + initMatrixFromSequence(this, init, prefix); + } + } + + // TODO: fast path from DOMMatrix, DOMMatrixReadOnly + static fromMatrix(other = {}) { + const prefix = "Failed to call 'DOMMatrixReadOnly.fromMatrix'"; + other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); + validateAndFixupMatrix(other, prefix); + const matrix = webidl.createBranded(DOMMatrixReadOnly); + initMatrixFromDictonary(matrix, other); + return matrix; + } + + static fromFloat32Array(float32) { + const prefix = "Failed to call 'DOMMatrixReadOnly.fromFloat32Array'"; + float32 = webidl.converters.Float32Array(float32, prefix, "Argument 1"); + const matrix = webidl.createBranded(DOMMatrixReadOnly); + initMatrixFromSequence(matrix, float32, prefix); + return matrix; + } + + static fromFloat64Array(float64) { + const prefix = "Failed to call 'DOMMatrixReadOnly.fromFloat64Array'"; + float64 = webidl.converters.Float64Array(float64, prefix, "Argument 1"); + const matrix = webidl.createBranded(DOMMatrixReadOnly); + initMatrixFromSequence(matrix, float64, prefix); + return matrix; + } + + get a() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_a]; + } + get b() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_b]; + } + get c() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_c]; + } + get d() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_d]; + } + get e() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_e]; + } + get f() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_f]; + } + get m11() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_m11]; + } + get m12() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_m12]; + } + get m13() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_m13]; + } + get m14() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_m14]; + } + get m21() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_m21]; + } + get m22() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_m22]; + } + get m23() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_m23]; + } + get m24() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_m24]; + } + get m31() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_m31]; + } + get m32() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_m32]; + } + get m33() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_m33]; + } + get m34() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_m34]; + } + get m41() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_m41]; + } + get m42() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_m42]; + } + get m43() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_m43]; + } + get m44() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][_m44]; + } + get is2D() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_is2D]; + } + get isIdentity() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return isMatrixIdentity(this); + } + + 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[_a], + b: raw[_b], + c: raw[_c], + d: raw[_d], + e: raw[_e], + f: raw[_f], + m11: raw[_m11], + m12: raw[_m12], + m13: raw[_m13], + m14: raw[_m14], + m21: raw[_m21], + m22: raw[_m22], + m23: raw[_m23], + m24: raw[_m24], + m31: raw[_m31], + m32: raw[_m32], + m33: raw[_m33], + m34: raw[_m34], + m41: raw[_m41], + m42: raw[_m42], + m43: raw[_m43], + m44: raw[_m44], + is2D: this[_is2D], + isIdentity: isMatrixIdentity(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, + ); + } +} + +const DOMMatrixReadOnlyPrototype = DOMMatrixReadOnly.prototype; + +class DOMMatrix extends DOMMatrixReadOnly { + // TODO: fast path from DOMMatrix, DOMMatrixReadOnly + static fromMatrix(other = {}) { + const prefix = "Failed to call 'DOMMatrix.fromMatrix'"; + other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); + validateAndFixupMatrix(other, prefix); + const matrix = webidl.createBranded(DOMMatrix); + initMatrixFromDictonary(matrix, other); + return matrix; + } + + static fromFloat32Array(float32) { + const prefix = "Failed to call 'DOMMatrix.fromFloat32Array'"; + float32 = webidl.converters.Float32Array(float32, prefix, "Argument 1"); + const matrix = webidl.createBranded(DOMMatrix); + initMatrixFromSequence(matrix, float32, prefix); + return matrix; + } + + static fromFloat64Array(float64) { + const prefix = "Failed to call 'DOMMatrix.fromFloat64Array'"; + float64 = webidl.converters.Float64Array(float64, prefix, "Argument 1"); + const matrix = webidl.createBranded(DOMMatrix); + initMatrixFromSequence(matrix, float64, prefix); + return matrix; + } + + get a() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_a]; + } + set a(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + this[_raw][_a] = webidl.converters["unrestricted double"](value); + } + get b() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_b]; + } + set b(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + this[_raw][_b] = webidl.converters["unrestricted double"](value); + } + get c() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_c]; + } + set c(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + this[_raw][_c] = webidl.converters["unrestricted double"](value); + } + get d() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_d]; + } + set d(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + this[_raw][_d] = webidl.converters["unrestricted double"](value); + } + get e() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_e]; + } + set e(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + this[_raw][_e] = webidl.converters["unrestricted double"](value); + } + get f() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_f]; + } + set f(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + this[_raw][_f] = webidl.converters["unrestricted double"](value); + } + get m11() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_m11]; + } + set m11(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + this[_raw][_m11] = webidl.converters["unrestricted double"](value); + } + get m12() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_m12]; + } + set m12(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + this[_raw][_m12] = webidl.converters["unrestricted double"](value); + } + get m13() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_m13]; + } + set m13(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][_m13] = webidl.converters["unrestricted double"](value); + } + get m14() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_m14]; + } + set m14(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][_m14] = webidl.converters["unrestricted double"](value); + } + get m21() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_m21]; + } + set m21(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + this[_raw][_m21] = webidl.converters["unrestricted double"](value); + } + get m22() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_m22]; + } + set m22(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + this[_raw][_m22] = webidl.converters["unrestricted double"](value); + } + get m23() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_m23]; + } + set m23(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][_m23] = webidl.converters["unrestricted double"](value); + } + get m24() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_m24]; + } + set m24(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][_m24] = webidl.converters["unrestricted double"](value); + } + get m31() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_m31]; + } + set m31(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][_m31] = webidl.converters["unrestricted double"](value); + } + get m32() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_m32]; + } + set m32(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][_m32] = webidl.converters["unrestricted double"](value); + } + get m33() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_m33]; + } + set m33(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + if (value !== 1) { + this[_is2D] = false; + } + this[_raw][_m33] = webidl.converters["unrestricted double"](value); + } + get m34() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_m34]; + } + set m34(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][_m34] = webidl.converters["unrestricted double"](value); + } + get m41() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_m41]; + } + set m41(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + this[_raw][_m41] = webidl.converters["unrestricted double"](value); + } + get m42() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_m42]; + } + set m42(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + this[_raw][_m42] = webidl.converters["unrestricted double"](value); + } + get m43() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_m43]; + } + set m43(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][_m43] = webidl.converters["unrestricted double"](value); + } + get m44() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][_m44]; + } + set m44(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + if (value !== 1) { + this[_is2D] = false; + } + this[_raw][_m44] = webidl.converters["unrestricted double"](value); + } + + // TODO(petamoriken): Add setMatrixValue in Window global object + // setMatrixValue(transformList) {} + + [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, + ); + } +} + +const DOMMatrixPrototype = DOMMatrix.prototype; + +/** + * 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} init + * @param {string} prefix + */ +function validateAndFixup2DMatrix(init, prefix) { + if ( + ( + init.a !== undefined && init.m11 !== undefined && + !sameValueZero(init.a, init.m11) + ) || + ( + init.b !== undefined && init.m12 !== undefined && + !sameValueZero(init.b, init.m12) + ) || + ( + init.c !== undefined && init.m21 !== undefined && + !sameValueZero(init.c, init.m21) + ) || + ( + init.d !== undefined && init.m22 !== undefined && + !sameValueZero(init.d, init.m22) + ) || + ( + init.e !== undefined && init.m41 !== undefined && + !sameValueZero(init.e, init.m41) + ) || + ( + init.f !== undefined && init.m42 !== undefined && + !sameValueZero(init.f, init.m42) + ) + ) { + throw new TypeError(`${prefix}: Inconsistent 2d matrix value`); + } + if (init.m11 === undefined) init.m11 = init.a ?? 1; + if (init.m12 === undefined) init.m12 = init.b ?? 0; + if (init.m21 === undefined) init.m21 = init.c ?? 0; + if (init.m22 === undefined) init.m22 = init.d ?? 1; + if (init.m41 === undefined) init.m41 = init.e ?? 0; + if (init.m42 === undefined) init.m42 = init.f ?? 0; +} + +/** + * https://drafts.fxtf.org/geometry/#matrix-validate-and-fixup + * @param {object} init + * @param {string} prefix + */ +function validateAndFixupMatrix(init, prefix) { + validateAndFixup2DMatrix(init, prefix); + const is2DCanBeTrue = init.m13 === 0 && + init.m14 === 0 && + init.m23 === 0 && + init.m24 === 0 && + init.m31 === 0 && + init.m32 === 0 && + init.m33 === 1 && + init.m34 === 0 && + init.m43 === 0 && + init.m44 === 1; + if (init.is2D === true && !is2DCanBeTrue) { + throw new TypeError( + `${prefix}: is2D property is true but the input matrix is a 3d matrix`, + ); + } + if (init.is2D === undefined) { + init.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 { + // 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[_raw] = new Float64Array([ + m11, m12, m13, m14, + m21, m22, m23, m24, + m31, m32, m33, m34, + m41, m42, m43, m44, + ]); + target[_is2D] = false; + } +} + +/** + * https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-isidentity + * @param {DOMMatrixReadOnly} matrix + */ +function isMatrixIdentity(matrix) { + const raw = matrix[_raw]; + return ( + raw[_m11] === 1 && + raw[_m12] === 0 && + raw[_m13] === 0 && + raw[_m14] === 0 && + raw[_m21] === 0 && + raw[_m22] === 1 && + raw[_m23] === 0 && + raw[_m24] === 0 && + raw[_m31] === 0 && + raw[_m32] === 0 && + raw[_m33] === 1 && + raw[_m34] === 0 && + raw[_m41] === 0 && + raw[_m42] === 0 && + raw[_m43] === 0 && + raw[_m44] === 1 + ); +} + export { + DOMMatrix, + DOMMatrixPrototype, + DOMMatrixReadOnly, + DOMMatrixReadOnlyPrototype, DOMPoint, DOMPointPrototype, DOMPointReadOnly, DOMPointReadOnlyPrototype, + DOMQuad, + DOMQuadPrototype, DOMRect, DOMRectPrototype, DOMRectReadOnly, DOMRectReadOnlyPrototype, - DOMQuad, - DOMQuadPrototype, }; diff --git a/ext/webidl/00_webidl.js b/ext/webidl/00_webidl.js index 6cf2c5f8cc357a..f2cf634b7c5271 100644 --- a/ext/webidl/00_webidl.js +++ b/ext/webidl/00_webidl.js @@ -660,6 +660,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 1ce45463ecc37e..16141e63fbda87 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/js/98_global_scope_shared.js b/runtime/js/98_global_scope_shared.js index e4d85166c546b0..a22f3a7a9f9cab 100644 --- a/runtime/js/98_global_scope_shared.js +++ b/runtime/js/98_global_scope_shared.js @@ -55,6 +55,8 @@ const windowOrWorkerGlobalScope = { CustomEvent: core.propNonEnumerable(event.CustomEvent), DecompressionStream: core.propNonEnumerable(compression.DecompressionStream), DOMException: core.propNonEnumerable(DOMException), + DOMMatrix: core.propNonEnumerable(geometry.DOMMatrix), + DOMMatrixReadOnly: core.propNonEnumerable(geometry.DOMMatrixReadOnly), DOMPoint: core.propNonEnumerable(geometry.DOMPoint), DOMPointReadOnly: core.propNonEnumerable(geometry.DOMPointReadOnly), DOMQuad: core.propNonEnumerable(geometry.DOMQuad), From 9271f25980c85546f16e61e49e687d01fa7d81e4 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 26 Jan 2024 03:36:32 +0900 Subject: [PATCH 10/66] add Window features --- ext/geometry/01_geometry.js | 161 +++++++++++++++++++-------- ext/geometry/lib.rs | 2 +- runtime/js/98_global_scope_window.js | 23 ++++ 3 files changed, 140 insertions(+), 46 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index c6283db5c434db..fada05f12fdcf7 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -2,19 +2,25 @@ import { primordials } from "ext:core/mod.js"; const { + ArrayPrototypeJoin, Float32Array, Float64Array, MathMax, MathMin, + NumberIsFinite, + ObjectDefineProperty, ObjectIs, ObjectPrototypeIsPrototypeOf, Symbol, SymbolFor, + TypedArrayPrototypeEvery, + TypedArrayPrototypeJoin, TypeError, } = 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", @@ -674,14 +680,16 @@ class DOMMatrixReadOnly { constructor(init = undefined) { const prefix = `Failed to construct '${this.constructor.name}'`; - if (typeof init === "string") { - // TODO(petamoriken): Add parser in Window global object - throw new TypeError( - `${prefix}: CSS parser is not implemented`, - ); - } this[_brand] = _brand; - if (init === undefined) { + if (typeof init === "string") { + if (parseTransformList === null) { + throw new TypeError(`${prefix}: Cannot be constructed with string on Workers`); + } else { + const { matrix, is2D } = parseTransformList(init); + this[_raw] = matrix; + this[_is2D] = is2D; + } + } else if (init === undefined) { // deno-fmt-ignore this[_raw] = new Float64Array([ 1, 0, 0, 0, @@ -704,7 +712,7 @@ class DOMMatrixReadOnly { static fromMatrix(other = {}) { const prefix = "Failed to call 'DOMMatrixReadOnly.fromMatrix'"; other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); - validateAndFixupMatrix(other, prefix); + validateAndFixupMatrixDictionary(other, prefix); const matrix = webidl.createBranded(DOMMatrixReadOnly); initMatrixFromDictonary(matrix, other); return matrix; @@ -911,7 +919,7 @@ class DOMMatrix extends DOMMatrixReadOnly { static fromMatrix(other = {}) { const prefix = "Failed to call 'DOMMatrix.fromMatrix'"; other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); - validateAndFixupMatrix(other, prefix); + validateAndFixupMatrixDictionary(other, prefix); const matrix = webidl.createBranded(DOMMatrix); initMatrixFromDictonary(matrix, other); return matrix; @@ -1193,70 +1201,70 @@ function sameValueZero(x, y) { /** * https://drafts.fxtf.org/geometry/#matrix-validate-and-fixup-2d - * @param {object} init + * @param {object} dict * @param {string} prefix */ -function validateAndFixup2DMatrix(init, prefix) { +function validateAndFixup2DMatrixDictionary(dict, prefix) { if ( ( - init.a !== undefined && init.m11 !== undefined && - !sameValueZero(init.a, init.m11) + dict.a !== undefined && dict.m11 !== undefined && + !sameValueZero(dict.a, dict.m11) ) || ( - init.b !== undefined && init.m12 !== undefined && - !sameValueZero(init.b, init.m12) + dict.b !== undefined && dict.m12 !== undefined && + !sameValueZero(dict.b, dict.m12) ) || ( - init.c !== undefined && init.m21 !== undefined && - !sameValueZero(init.c, init.m21) + dict.c !== undefined && dict.m21 !== undefined && + !sameValueZero(dict.c, dict.m21) ) || ( - init.d !== undefined && init.m22 !== undefined && - !sameValueZero(init.d, init.m22) + dict.d !== undefined && dict.m22 !== undefined && + !sameValueZero(dict.d, dict.m22) ) || ( - init.e !== undefined && init.m41 !== undefined && - !sameValueZero(init.e, init.m41) + dict.e !== undefined && dict.m41 !== undefined && + !sameValueZero(dict.e, dict.m41) ) || ( - init.f !== undefined && init.m42 !== undefined && - !sameValueZero(init.f, init.m42) + dict.f !== undefined && dict.m42 !== undefined && + !sameValueZero(dict.f, dict.m42) ) ) { throw new TypeError(`${prefix}: Inconsistent 2d matrix value`); } - if (init.m11 === undefined) init.m11 = init.a ?? 1; - if (init.m12 === undefined) init.m12 = init.b ?? 0; - if (init.m21 === undefined) init.m21 = init.c ?? 0; - if (init.m22 === undefined) init.m22 = init.d ?? 1; - if (init.m41 === undefined) init.m41 = init.e ?? 0; - if (init.m42 === undefined) init.m42 = init.f ?? 0; + 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} init + * @param {object} dict * @param {string} prefix */ -function validateAndFixupMatrix(init, prefix) { - validateAndFixup2DMatrix(init, prefix); - const is2DCanBeTrue = init.m13 === 0 && - init.m14 === 0 && - init.m23 === 0 && - init.m24 === 0 && - init.m31 === 0 && - init.m32 === 0 && - init.m33 === 1 && - init.m34 === 0 && - init.m43 === 0 && - init.m44 === 1; - if (init.is2D === true && !is2DCanBeTrue) { +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 (init.is2D === undefined) { - init.is2D = is2DCanBeTrue; + if (dict.is2D === undefined) { + dict.is2D = is2DCanBeTrue; } } @@ -1346,6 +1354,68 @@ function isMatrixIdentity(matrix) { ); } +/** + * CSS parser + * @type {((transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean }) | null} + */ +let parseTransformList = null; + +/** + * @param {(transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean }} parser + */ +function enableWindowFeatures(parser) { + parseTransformList = parser; + + // 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 'DOMMatrixReadOnly.prototype.toString': Cannot be serialized with NaN or Infinity values", + "InvalidStateError", + ) + } + if (this[_is2D]) { + return `matrix(${ArrayPrototypeJoin([ + raw[_a], + raw[_b], + raw[_c], + raw[_d], + raw[_e], + raw[_f], + ], ", ")})`; + } else { + return `matrix3d(${TypedArrayPrototypeJoin(raw, ", ")})`; + } + }, + writable: true, + enumerable: false, + 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 call 'DOMMatrix.prototype.setMatrixValue'"; + webidl.requiredArguments(arguments.length, 1, prefix); + transformList = webidl.converters.DOMString( + transformList, + prefix, + "Argument 1", + ); + const { matrix, is2D } = parser(transformList); + this[_raw] = matrix; + this[_is2D] = is2D; + }, + writable: true, + enumerable: false, + configurable: true, + }); +} + export { DOMMatrix, DOMMatrixPrototype, @@ -1361,4 +1431,5 @@ export { DOMRectPrototype, DOMRectReadOnly, DOMRectReadOnlyPrototype, + enableWindowFeatures, }; diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 7df5efa1014f7e..f103d05c793c11 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -4,7 +4,7 @@ use std::path::PathBuf; deno_core::extension!( deno_geometry, - deps = [deno_webidl, deno_console], + deps = [deno_webidl, deno_web, deno_console], esm = ["01_geometry.js"], ); diff --git a/runtime/js/98_global_scope_window.js b/runtime/js/98_global_scope_window.js index aa18ed36136139..512ee03a469a07 100644 --- a/runtime/js/98_global_scope_window.js +++ b/runtime/js/98_global_scope_window.js @@ -9,7 +9,9 @@ import { const { ObjectDefineProperties, ObjectPrototypeIsPrototypeOf, + Float64Array, SymbolFor, + TypeError, } = primordials; import * as location from "ext:deno_web/12_location.js"; @@ -17,6 +19,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 * as webStorage from "ext:deno_webstorage/01_webstorage.js"; +import * as geometry from "ext:deno_geometry/01_geometry.js"; import * as prompt from "ext:runtime/41_prompt.js"; import { loadWebGPU } from "ext:deno_webgpu/00_init.js"; @@ -103,6 +106,26 @@ ObjectDefineProperties(Navigator.prototype, { }); const NavigatorPrototype = Navigator.prototype; +geometry.enableWindowFeatures((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, + }; + } + + // TODO(petamoriken): Add CSS parser + throw new TypeError( + `${prefix}: CSS parser is not implemented`, + ); +}); + const mainRuntimeGlobalProperties = { Location: location.locationConstructorDescriptor, location: location.locationDescriptor, From d94b6b388955ff0660e1ff270850def6e3060538 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 26 Jan 2024 03:38:54 +0900 Subject: [PATCH 11/66] tweak --- ext/geometry/01_geometry.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index fada05f12fdcf7..b392f01709ed0f 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -720,6 +720,7 @@ class DOMMatrixReadOnly { static fromFloat32Array(float32) { const prefix = "Failed to call 'DOMMatrixReadOnly.fromFloat32Array'"; + webidl.requiredArguments(arguments.length, 1, prefix); float32 = webidl.converters.Float32Array(float32, prefix, "Argument 1"); const matrix = webidl.createBranded(DOMMatrixReadOnly); initMatrixFromSequence(matrix, float32, prefix); @@ -728,6 +729,7 @@ class DOMMatrixReadOnly { static fromFloat64Array(float64) { const prefix = "Failed to call 'DOMMatrixReadOnly.fromFloat64Array'"; + webidl.requiredArguments(arguments.length, 1, prefix); float64 = webidl.converters.Float64Array(float64, prefix, "Argument 1"); const matrix = webidl.createBranded(DOMMatrixReadOnly); initMatrixFromSequence(matrix, float64, prefix); From 62481c3e7f80c3891a8f567691dd95cfeaec523d Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 26 Jan 2024 03:39:50 +0900 Subject: [PATCH 12/66] tweak --- ext/geometry/01_geometry.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index b392f01709ed0f..2ecdf86b6d4fd8 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -929,6 +929,7 @@ class DOMMatrix extends DOMMatrixReadOnly { static fromFloat32Array(float32) { const prefix = "Failed to call 'DOMMatrix.fromFloat32Array'"; + webidl.requiredArguments(arguments.length, 1, prefix); float32 = webidl.converters.Float32Array(float32, prefix, "Argument 1"); const matrix = webidl.createBranded(DOMMatrix); initMatrixFromSequence(matrix, float32, prefix); @@ -937,6 +938,7 @@ class DOMMatrix extends DOMMatrixReadOnly { static fromFloat64Array(float64) { const prefix = "Failed to call 'DOMMatrix.fromFloat64Array'"; + webidl.requiredArguments(arguments.length, 1, prefix); float64 = webidl.converters.Float64Array(float64, prefix, "Argument 1"); const matrix = webidl.createBranded(DOMMatrix); initMatrixFromSequence(matrix, float64, prefix); From 7571b7390f286facfa7e61b229791dc5c02ea22d Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 28 Jan 2024 00:47:43 +0900 Subject: [PATCH 13/66] fmt --- ext/geometry/01_geometry.js | 48 +++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 2ecdf86b6d4fd8..0b6fc30a6a07d8 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -683,7 +683,9 @@ class DOMMatrixReadOnly { this[_brand] = _brand; if (typeof init === "string") { if (parseTransformList === null) { - throw new TypeError(`${prefix}: Cannot be constructed with string on Workers`); + throw new TypeError( + `${prefix}: Cannot be constructed with string on Workers`, + ); } else { const { matrix, is2D } = parseTransformList(init); this[_raw] = matrix; @@ -1152,9 +1154,6 @@ class DOMMatrix extends DOMMatrixReadOnly { this[_raw][_m44] = webidl.converters["unrestricted double"](value); } - // TODO(petamoriken): Add setMatrixValue in Window global object - // setMatrixValue(transformList) {} - [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { return inspect( createFilteredInspectProxy({ @@ -1314,12 +1313,23 @@ function initMatrixFromDictonary(target, dict) { ]); target[_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([ @@ -1379,17 +1389,19 @@ function enableWindowFeatures(parser) { throw new DOMException( "Failed to execute 'DOMMatrixReadOnly.prototype.toString': Cannot be serialized with NaN or Infinity values", "InvalidStateError", - ) + ); } if (this[_is2D]) { - return `matrix(${ArrayPrototypeJoin([ - raw[_a], - raw[_b], - raw[_c], - raw[_d], - raw[_e], - raw[_f], - ], ", ")})`; + return `matrix(${ + ArrayPrototypeJoin([ + raw[_a], + raw[_b], + raw[_c], + raw[_d], + raw[_e], + raw[_f], + ], ", ") + })`; } else { return `matrix3d(${TypedArrayPrototypeJoin(raw, ", ")})`; } From 8dabe11f4ef8514db6536007826a91d117efc7c6 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 28 Jan 2024 16:37:31 +0900 Subject: [PATCH 14/66] perf --- ext/geometry/01_geometry.js | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 0b6fc30a6a07d8..6cd0d4ab8522e3 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -710,13 +710,17 @@ class DOMMatrixReadOnly { } } - // TODO: fast path from DOMMatrix, DOMMatrixReadOnly static fromMatrix(other = {}) { const prefix = "Failed to call 'DOMMatrixReadOnly.fromMatrix'"; - other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); - validateAndFixupMatrixDictionary(other, prefix); const matrix = webidl.createBranded(DOMMatrixReadOnly); - initMatrixFromDictonary(matrix, other); + // fast path for DOMMatrix or DOMMatrixReadOnly + if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnly, other)) { + initMatrixFromMatrix(matrix, other); + } else { + other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); + validateAndFixupMatrixDictionary(other, prefix); + initMatrixFromDictonary(matrix, other); + } return matrix; } @@ -919,13 +923,17 @@ class DOMMatrixReadOnly { const DOMMatrixReadOnlyPrototype = DOMMatrixReadOnly.prototype; class DOMMatrix extends DOMMatrixReadOnly { - // TODO: fast path from DOMMatrix, DOMMatrixReadOnly static fromMatrix(other = {}) { const prefix = "Failed to call 'DOMMatrix.fromMatrix'"; - other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); - validateAndFixupMatrixDictionary(other, prefix); const matrix = webidl.createBranded(DOMMatrix); - initMatrixFromDictonary(matrix, other); + // fast path for DOMMatrix or DOMMatrixReadOnly + if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnly, other)) { + initMatrixFromMatrix(matrix, other); + } else { + other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); + validateAndFixupMatrixDictionary(other, prefix); + initMatrixFromDictonary(matrix, other); + } return matrix; } @@ -1342,6 +1350,15 @@ function initMatrixFromDictonary(target, dict) { } } +/** + * @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 From 7018b554ed585df2550dfc7b241125c0ad204aad Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 29 Jan 2024 00:14:59 +0900 Subject: [PATCH 15/66] add types --- ext/geometry/01_geometry.js | 20 ++ ext/geometry/lib.deno_geometry.d.ts | 425 ++++++++++++++++++++++++++++ 2 files changed, 445 insertions(+) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 6cd0d4ab8522e3..dd90792dddd076 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -650,12 +650,31 @@ class 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 _a = 0; const _b = 1; const _c = 4; const _d = 5; const _e = 12; const _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 _m11 = 0; const _m12 = 1; const _m13 = 2; @@ -672,6 +691,7 @@ const _m41 = 12; const _m42 = 13; const _m43 = 14; const _m44 = 15; + const _is2D = Symbol("[[is2D]]"); class DOMMatrixReadOnly { diff --git a/ext/geometry/lib.deno_geometry.d.ts b/ext/geometry/lib.deno_geometry.d.ts index e8b3fa1927454a..b223842eb4d339 100644 --- a/ext/geometry/lib.deno_geometry.d.ts +++ b/ext/geometry/lib.deno_geometry.d.ts @@ -2,3 +2,428 @@ /// /// + +/** @category Geometry Interfaces Module API */ +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 */ +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 + */ +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; + invertSelf(): DOMMatrix; + multiplySelf(other?: DOMMatrixInit): DOMMatrix; + preMultiplySelf(other?: DOMMatrixInit): DOMMatrix; + rotateAxisAngleSelf( + x?: number, + y?: number, + z?: number, + angle?: number, + ): DOMMatrix; + rotateFromVectorSelf(x?: number, y?: number): DOMMatrix; + rotateSelf(rotX?: number, rotY?: number, rotZ?: number): DOMMatrix; + scale3dSelf( + scale?: number, + originX?: number, + originY?: number, + originZ?: number, + ): DOMMatrix; + scaleSelf( + scaleX?: number, + scaleY?: number, + scaleZ?: number, + originX?: number, + originY?: number, + originZ?: number, + ): DOMMatrix; + /** Not available in Worker */ + setMatrixValue(transformList: string): DOMMatrix; + skewXSelf(sx?: number): DOMMatrix; + skewYSelf(sy?: number): DOMMatrix; + 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; + /** 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 + */ +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; + flipX(): DOMMatrix; + flipY(): DOMMatrix; + inverse(): DOMMatrix; + multiply(other?: DOMMatrixInit): DOMMatrix; + rotate(rotX?: number, rotY?: number, rotZ?: number): DOMMatrix; + rotateAxisAngle( + x?: number, + y?: number, + z?: number, + angle?: number, + ): DOMMatrix; + rotateFromVector(x?: number, y?: number): DOMMatrix; + scale( + scaleX?: number, + scaleY?: number, + scaleZ?: number, + originX?: number, + originY?: number, + originZ?: number, + ): DOMMatrix; + scale3d( + scale?: number, + originX?: number, + originY?: number, + originZ?: number, + ): DOMMatrix; + /** @deprecated Supported for legacy reasons to be compatible with SVGMatrix as defined in SVG 1.1. Use scale() instead. */ + scaleNonUniform(scaleX?: number, scaleY?: number): DOMMatrix; + skewX(sx?: number): DOMMatrix; + 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; + /** 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; + /** 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 */ +interface DOMPointInit { + w?: number; + x?: number; + y?: number; + z?: number; +} + +/** + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPoint) + * + * @category Geometry Interfaces Module API + */ +interface DOMPoint extends DOMPointReadOnly { + w: number; + x: number; + y: number; + z: number; +} + +/** + * [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; +}; + +/** + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly) + * + * @category Geometry Interfaces Module API + */ +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; + }; +} + +/** + * [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 */ +interface DOMQuadInit { + p1?: DOMPointInit; + p2?: DOMPointInit; + p3?: DOMPointInit; + p4?: DOMPointInit; +} + +/** + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMQuad) + * + * @category Geometry Interfaces Module API + */ +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; + }; +} + +/** + * [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 */ +interface DOMRectInit { + height?: number; + width?: number; + x?: number; + y?: number; +} + +/** + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRect) + * + * @category Geometry Interfaces Module API + */ +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 Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly) + * + * @category Geometry Interfaces Module API + */ +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 Reference](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; +}; From e6b76034170097f7c5063418485a207a6ef1d421 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 29 Jan 2024 00:17:02 +0900 Subject: [PATCH 16/66] add multiply methods --- Cargo.lock | 82 ++++++++++++++++++++++++++ Cargo.toml | 3 + cli/tests/integration/js_unit_tests.rs | 1 + cli/tests/unit/geometry_test.ts | 28 +++++++++ ext/geometry/01_geometry.js | 69 ++++++++++++++++++++++ ext/geometry/Cargo.toml | 1 + ext/geometry/lib.rs | 49 +++++++++++++++ 7 files changed, 233 insertions(+) create mode 100644 cli/tests/unit/geometry_test.ts diff --git a/Cargo.lock b/Cargo.lock index 362aa0ff7847c7..e5b01220af59f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -191,6 +191,15 @@ version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + [[package]] name = "arrayvec" version = "0.7.4" @@ -1406,6 +1415,7 @@ name = "deno_geometry" version = "0.1.0" dependencies = [ "deno_core", + "nalgebra", ] [[package]] @@ -3759,6 +3769,16 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" +[[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" @@ -3899,6 +3919,21 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "nalgebra" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "307ed9b18cc2423f29e83f84fd23a8e73628727990181f18641a8b5dc2ab1caa" +dependencies = [ + "approx", + "matrixmultiply", + "num-complex", + "num-rational", + "num-traits", + "simba", + "typenum", +] + [[package]] name = "napi-build" version = "1.2.1" @@ -4059,6 +4094,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "num-complex" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +dependencies = [ + "num-traits", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -4863,6 +4907,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + [[package]] name = "rayon" version = "1.8.0" @@ -5252,6 +5302,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4950d85bc52415f8432144c97c4791bd0c4f7954de32a7270ee9cccd3c22b12b" +[[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" @@ -5528,6 +5587,19 @@ dependencies = [ "rand_core", ] +[[package]] +name = "simba" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae" +dependencies = [ + "approx", + "num-complex", + "num-traits", + "paste", + "wide", +] + [[package]] name = "simd-adler32" version = "0.3.7" @@ -7206,6 +7278,16 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wide" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b31891d644eba1789fb6715f27fbc322e4bdf2ecdc412ede1993246159271613" +dependencies = [ + "bytemuck", + "safe_arch", +] + [[package]] name = "widestring" version = "1.0.2" diff --git a/Cargo.toml b/Cargo.toml index 7cfa483c49a952..048dfe7efe2915 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -178,6 +178,9 @@ zstd = "=0.12.4" 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.32.3", default-features = false, features = ["std"] } + # webgpu raw-window-handle = "0.5.0" wgpu-core = { version = "=0.18", features = ["raw-window-handle"] } diff --git a/cli/tests/integration/js_unit_tests.rs b/cli/tests/integration/js_unit_tests.rs index 0e3a1a118249bb..4059d06172a743 100644 --- a/cli/tests/integration/js_unit_tests.rs +++ b/cli/tests/integration/js_unit_tests.rs @@ -38,6 +38,7 @@ util::unit_test_factory!( files_test, flock_test, fs_events_test, + geometry_test, get_random_values_test, globals_test, headers_test, diff --git a/cli/tests/unit/geometry_test.ts b/cli/tests/unit/geometry_test.ts new file mode 100644 index 00000000000000..d66375c41af758 --- /dev/null +++ b/cli/tests/unit/geometry_test.ts @@ -0,0 +1,28 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +import { assertEquals } from "./test_util.ts"; + +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(init); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // 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, + }), + ); +}); diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index dd90792dddd076..89e7c9ea935897 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -1,6 +1,11 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. import { primordials } from "ext:core/mod.js"; +import { + op_geometry_multiply, + op_geometry_multiply_self, + op_geometry_premultiply_self, +} from "ext:core/ops"; const { ArrayPrototypeJoin, Float32Array, @@ -859,6 +864,26 @@ class DOMMatrixReadOnly { return isMatrixIdentity(this); } + multiply(other = {}) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const prefix = "Failed to call 'DOMMatrixReadOnly.prototype.multiply'"; + 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[_raw] = new Float64Array(16); + op_geometry_multiply(this[_raw], other[_raw], matrix[_raw]); + matrix[_is2D] = this[_is2D] && other[_is2D]; + return matrix; + } + toFloat32Array() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return new Float32Array(this[_raw]); @@ -1182,6 +1207,50 @@ class DOMMatrix extends DOMMatrixReadOnly { this[_raw][_m44] = webidl.converters["unrestricted double"](value); } + multiplySelf(other = {}) { + webidl.assertBranded(this, DOMMatrixPrototype); + const prefix = "Failed to call 'DOMMatrix.prototype.multiplySelf'"; + 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); + const prefix = "Failed to call 'DOMMatrix.prototype.premultiplySelf'"; + 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; + } + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { return inspect( createFilteredInspectProxy({ diff --git a/ext/geometry/Cargo.toml b/ext/geometry/Cargo.toml index 99d9f9282f61eb..9ab2c7c698eaeb 100644 --- a/ext/geometry/Cargo.toml +++ b/ext/geometry/Cargo.toml @@ -15,3 +15,4 @@ path = "lib.rs" [dependencies] deno_core.workspace = true +nalgebra.workspace = true diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index f103d05c793c11..e63c7ab9b37068 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -1,13 +1,62 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +use deno_core::op2; +use nalgebra::Matrix4; +use nalgebra::MatrixView4; +use nalgebra::MatrixViewMut4; use std::path::PathBuf; +type Matrix = Matrix4; +type MatrixView<'a> = MatrixView4<'a, f64>; +type MatrixViewMut<'a> = MatrixViewMut4<'a, f64>; + deno_core::extension!( deno_geometry, deps = [deno_webidl, deno_web, deno_console], + ops = [ + op_geometry_multiply, + op_geometry_multiply_self, + op_geometry_premultiply_self, + ], 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_multiply( + #[buffer] lhs: &[f64], + #[buffer] rhs: &[f64], + #[buffer] out: &mut [f64], +) -> () { + let lhs = MatrixView::from_slice(lhs); + let rhs = MatrixView::from_slice(rhs); + let mut out = MatrixViewMut::from_slice(out); + lhs.mul_to(&rhs, &mut out); +} + +#[op2(fast)] +pub fn op_geometry_multiply_self( + #[buffer] rhs: &[f64], + #[buffer] out: &mut [f64], +) -> () { + let rhs = MatrixView::from_slice(rhs); + let mut out = MatrixViewMut::from_slice(out); + let mut result = Matrix::zeros(); + out.mul_to(&rhs, &mut result); + out.copy_from(&result); +} + +#[op2(fast)] +pub fn op_geometry_premultiply_self( + #[buffer] lhs: &[f64], + #[buffer] out: &mut [f64], +) -> () { + let lhs = MatrixView::from_slice(lhs); + let mut out = MatrixViewMut::from_slice(out); + let mut result = Matrix::zeros(); + lhs.mul_to(&out, &mut result); + out.copy_from(&result); +} From 75b79825dbf0a0911c2d1cab98719d5e506fe82d Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 29 Jan 2024 00:38:31 +0900 Subject: [PATCH 17/66] fix --- cli/tests/unit/geometry_test.ts | 64 +++++++++++++++++++++++++++++---- ext/geometry/01_geometry.js | 2 +- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/cli/tests/unit/geometry_test.ts b/cli/tests/unit/geometry_test.ts index d66375c41af758..7a10ff0eff54d1 100644 --- a/cli/tests/unit/geometry_test.ts +++ b/cli/tests/unit/geometry_test.ts @@ -1,5 +1,5 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -import { assertEquals } from "./test_util.ts"; +import { assertEquals, assertStrictEquals } from "./test_util.ts"; Deno.test(function matrixMultiply() { // deno-fmt-ignore @@ -10,7 +10,7 @@ Deno.test(function matrixMultiply() { m14: 13, m24: 14, m34: 15, m44: 16, }; const matrix = DOMMatrix.fromMatrix(init); - const matrix2 = matrix.multiply(init); + const matrix2 = matrix.multiply({ m11: 1, m22: 2, m33: 3, m44: 4 }); assertEquals( matrix, DOMMatrix.fromMatrix(init), @@ -19,10 +19,62 @@ Deno.test(function matrixMultiply() { matrix2, // 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, + 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 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, }), ); }); diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 89e7c9ea935897..73b520465f3eb3 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -1229,7 +1229,7 @@ class DOMMatrix extends DOMMatrixReadOnly { return this; } - premultiplySelf(other = {}) { + preMultiplySelf(other = {}) { webidl.assertBranded(this, DOMMatrixPrototype); const prefix = "Failed to call 'DOMMatrix.prototype.premultiplySelf'"; if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { From e431da42126767b16d1597cd5ce1ae1b585a4c8b Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 29 Jan 2024 13:11:59 +0900 Subject: [PATCH 18/66] add TODO comments --- ext/geometry/01_geometry.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 73b520465f3eb3..f097787aea4364 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -293,6 +293,7 @@ class DOMPointReadOnly { const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; +// TODO: protect for [[Prototype]] overwrite class DOMPoint extends DOMPointReadOnly { static fromPoint(other = {}) { other = webidl.converters.DOMPointInit( @@ -466,6 +467,7 @@ class DOMRectReadOnly { const DOMRectReadOnlyPrototype = DOMRectReadOnly.prototype; +// TODO: protect for [[Prototype]] overwrite class DOMRect extends DOMRectReadOnly { static fromRect(other = {}) { other = webidl.converters.DOMRectInit( @@ -967,6 +969,7 @@ class DOMMatrixReadOnly { const DOMMatrixReadOnlyPrototype = DOMMatrixReadOnly.prototype; +// TODO: protect for [[Prototype]] overwrite class DOMMatrix extends DOMMatrixReadOnly { static fromMatrix(other = {}) { const prefix = "Failed to call 'DOMMatrix.fromMatrix'"; From 36378c733a69bb206da958e0a67e310fefc69582 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 2 Feb 2024 03:13:24 +0900 Subject: [PATCH 19/66] add tests --- cli/tests/unit/geometry_test.ts | 53 +++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/cli/tests/unit/geometry_test.ts b/cli/tests/unit/geometry_test.ts index 7a10ff0eff54d1..52723fca89569f 100644 --- a/cli/tests/unit/geometry_test.ts +++ b/cli/tests/unit/geometry_test.ts @@ -53,6 +53,32 @@ Deno.test(function matrixMultiplySelf() { ); }); +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 = { @@ -78,3 +104,30 @@ Deno.test(function matrixPreMultiplySelf() { }), ); }); + +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, + }), + ); +}); + From 3270c3aebd8d84cb1d7c7a2ec2bd85ade813ff8c Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 2 Feb 2024 03:14:38 +0900 Subject: [PATCH 20/66] add translate methods --- cli/tests/unit/geometry_test.ts | 52 +++++++++++++++++++++++++++++++++ ext/geometry/01_geometry.js | 29 ++++++++++++++++++ ext/geometry/lib.rs | 29 ++++++++++++++++++ 3 files changed, 110 insertions(+) diff --git a/cli/tests/unit/geometry_test.ts b/cli/tests/unit/geometry_test.ts index 52723fca89569f..1662a0b1aaa5ca 100644 --- a/cli/tests/unit/geometry_test.ts +++ b/cli/tests/unit/geometry_test.ts @@ -1,6 +1,58 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. import { assertEquals, assertStrictEquals } from "./test_util.ts"; +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 matrixMultiply() { // deno-fmt-ignore const init = { diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index f097787aea4364..20ddb45b0fe2fa 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -5,6 +5,8 @@ import { op_geometry_multiply, op_geometry_multiply_self, op_geometry_premultiply_self, + op_geometry_translate, + op_geometry_translate_self, } from "ext:core/ops"; const { ArrayPrototypeJoin, @@ -866,6 +868,21 @@ class DOMMatrixReadOnly { return isMatrixIdentity(this); } + translate(tx = 0, ty = 0, tz = 0) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_raw] = new Float64Array(16); + op_geometry_translate( + this[_raw], + webidl.converters["unrestricted double"](tx), + webidl.converters["unrestricted double"](ty), + webidl.converters["unrestricted double"](tz), + matrix[_raw], + ); + matrix[_is2D] = this[_is2D] && tz === 0; + return matrix; + } + multiply(other = {}) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const prefix = "Failed to call 'DOMMatrixReadOnly.prototype.multiply'"; @@ -1254,6 +1271,18 @@ class DOMMatrix extends DOMMatrixReadOnly { return this; } + translateSelf(tx = 0, ty = 0, tz = 0) { + webidl.assertBranded(this, DOMMatrixPrototype); + op_geometry_translate_self( + webidl.converters["unrestricted double"](tx), + webidl.converters["unrestricted double"](ty), + webidl.converters["unrestricted double"](tz), + this[_raw], + ); + this[_is2D] &&= tz === 0; + return this; + } + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { return inspect( createFilteredInspectProxy({ diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index e63c7ab9b37068..2e0867c13cda3d 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -4,6 +4,7 @@ use deno_core::op2; use nalgebra::Matrix4; use nalgebra::MatrixView4; use nalgebra::MatrixViewMut4; +use nalgebra::Vector3; use std::path::PathBuf; type Matrix = Matrix4; @@ -14,6 +15,8 @@ deno_core::extension!( deno_geometry, deps = [deno_webidl, deno_web, deno_console], ops = [ + op_geometry_translate, + op_geometry_translate_self, op_geometry_multiply, op_geometry_multiply_self, op_geometry_premultiply_self, @@ -25,6 +28,32 @@ pub fn get_declaration() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_geometry.d.ts") } +#[op2(fast)] +pub fn op_geometry_translate( + #[buffer] input: &[f64], + x: f64, + y: f64, + z: f64, + #[buffer] out: &mut [f64], +) -> () { + let shift = Vector3::new(x, y, z); + let mut out = MatrixViewMut::from_slice(out); + out.copy_from_slice(input); + out.prepend_translation_mut(&shift); +} + +#[op2(fast)] +pub fn op_geometry_translate_self( + x: f64, + y: f64, + z: f64, + #[buffer] out: &mut [f64], +) -> () { + let shift = Vector3::new(x, y, z); + let mut out = MatrixViewMut::from_slice(out); + out.prepend_translation_mut(&shift); +} + #[op2(fast)] pub fn op_geometry_multiply( #[buffer] lhs: &[f64], From 065e85f9a82f4ec074535a4d3bba78615fcd7b45 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 5 Feb 2024 04:35:04 +0900 Subject: [PATCH 21/66] tweak --- ext/geometry/lib.deno_geometry.d.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ext/geometry/lib.deno_geometry.d.ts b/ext/geometry/lib.deno_geometry.d.ts index b223842eb4d339..19991943cd22ec 100644 --- a/ext/geometry/lib.deno_geometry.d.ts +++ b/ext/geometry/lib.deno_geometry.d.ts @@ -189,7 +189,7 @@ interface DOMMatrixReadOnly { originY?: number, originZ?: number, ): DOMMatrix; - /** @deprecated Supported for legacy reasons to be compatible with SVGMatrix as defined in SVG 1.1. Use scale() instead. */ + /** @deprecated Supported for legacy reasons to be compatible with `SVGMatrix` as defined in SVG 1.1. Use `scale()` instead. */ scaleNonUniform(scaleX?: number, scaleY?: number): DOMMatrix; skewX(sx?: number): DOMMatrix; skewY(sy?: number): DOMMatrix; @@ -259,6 +259,7 @@ 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. * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPoint) * * @category Geometry Interfaces Module API @@ -271,6 +272,7 @@ interface DOMPoint extends DOMPointReadOnly { } /** + * 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 @@ -282,6 +284,7 @@ declare var 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 @@ -301,6 +304,7 @@ interface DOMPointReadOnly { } /** + * 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 @@ -320,6 +324,7 @@ interface DOMQuadInit { } /** + * 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 @@ -339,6 +344,7 @@ interface DOMQuad { } /** + * 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 @@ -387,7 +393,7 @@ declare var DOMRect: { }; /** - * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly) + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly) * * @category Geometry Interfaces Module API */ @@ -413,7 +419,7 @@ interface DOMRectReadOnly { } /** - * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly) + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly) * * @category Geometry Interfaces Module API */ From 76d69adcb1e6f224022c61f87c3a5e322599e9a8 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 5 Feb 2024 04:41:32 +0900 Subject: [PATCH 22/66] add scale methods --- cli/tests/unit/geometry_test.ts | 234 ++++++++++++++++++++++++++++++++ ext/geometry/01_geometry.js | 151 +++++++++++++++++++++ ext/geometry/lib.rs | 70 ++++++++++ 3 files changed, 455 insertions(+) diff --git a/cli/tests/unit/geometry_test.ts b/cli/tests/unit/geometry_test.ts index 1662a0b1aaa5ca..d18ff59f8919b1 100644 --- a/cli/tests/unit/geometry_test.ts +++ b/cli/tests/unit/geometry_test.ts @@ -53,6 +53,240 @@ Deno.test(function matrixTranslateSelf() { ); }); +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 matrixMultiply() { // deno-fmt-ignore const init = { diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 20ddb45b0fe2fa..0c59a5709d152d 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -5,6 +5,10 @@ import { op_geometry_multiply, op_geometry_multiply_self, op_geometry_premultiply_self, + op_geometry_scale, + op_geometry_scale_self, + op_geometry_scale_with_origin, + op_geometry_scale_with_origin_self, op_geometry_translate, op_geometry_translate_self, } from "ext:core/ops"; @@ -883,6 +887,91 @@ class DOMMatrixReadOnly { return matrix; } + scale( + scaleX = 1, + scaleY = scaleX, + scaleZ = 1, + originX = 0, + originY = 0, + originZ = 0, + ) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + originX = webidl.converters["unrestricted double"](originX); + originY = webidl.converters["unrestricted double"](originY); + originZ = webidl.converters["unrestricted double"](originZ); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_raw] = new Float64Array(16); + if (originX === 0 && originY === 0 && originZ === 0) { + op_geometry_scale( + this[_raw], + webidl.converters["unrestricted double"](scaleX), + webidl.converters["unrestricted double"](scaleY), + webidl.converters["unrestricted double"](scaleZ), + matrix[_raw], + ); + } else { + op_geometry_scale_with_origin( + this[_raw], + webidl.converters["unrestricted double"](scaleX), + webidl.converters["unrestricted double"](scaleY), + webidl.converters["unrestricted double"](scaleZ), + originX, + originY, + originZ, + matrix[_raw], + ); + } + matrix[_is2D] = this[_is2D] && scaleZ === 1; + return matrix; + } + + scaleNonUniform(scaleX = 1, scaleY = 1) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_raw] = new Float64Array(16); + op_geometry_scale( + this[_raw], + webidl.converters["unrestricted double"](scaleX), + webidl.converters["unrestricted double"](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[_raw] = new Float64Array(16); + if (originX === 0 && originY === 0 && originZ === 0) { + op_geometry_scale( + this[_raw], + scale, + scale, + scale, + matrix[_raw], + ); + } else { + op_geometry_scale_with_origin( + this[_raw], + scale, + scale, + scale, + originX, + originY, + originZ, + matrix[_raw], + ); + } + matrix[_is2D] = this[_is2D] && scale === 1; + return matrix; + } + multiply(other = {}) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const prefix = "Failed to call 'DOMMatrixReadOnly.prototype.multiply'"; @@ -1283,6 +1372,68 @@ class DOMMatrix extends DOMMatrixReadOnly { return this; } + scaleSelf( + scaleX = 1, + scaleY = scaleX, + scaleZ = 1, + originX = 0, + originY = 0, + originZ = 0, + ) { + webidl.assertBranded(this, DOMMatrixPrototype); + 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( + webidl.converters["unrestricted double"](scaleX), + webidl.converters["unrestricted double"](scaleY), + webidl.converters["unrestricted double"](scaleZ), + this[_raw], + ); + } else { + op_geometry_scale_with_origin_self( + webidl.converters["unrestricted double"](scaleX), + webidl.converters["unrestricted double"](scaleY), + webidl.converters["unrestricted double"](scaleZ), + originX, + originY, + originZ, + this[_raw], + ); + } + this[_is2D] &&= scaleZ === 1; + return this; + } + + scale3dSelf(scale = 1, originX = 0, originY = 0, originZ = 0) { + webidl.assertBranded(this, DOMMatrixPrototype); + 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; + return this; + } + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { return inspect( createFilteredInspectProxy({ diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 2e0867c13cda3d..f4a703dd276b83 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -17,6 +17,10 @@ deno_core::extension!( ops = [ op_geometry_translate, op_geometry_translate_self, + op_geometry_scale, + op_geometry_scale_self, + op_geometry_scale_with_origin, + op_geometry_scale_with_origin_self, op_geometry_multiply, op_geometry_multiply_self, op_geometry_premultiply_self, @@ -54,6 +58,72 @@ pub fn op_geometry_translate_self( out.prepend_translation_mut(&shift); } +#[op2(fast)] +pub fn op_geometry_scale( + #[buffer] input: &[f64], + x: f64, + y: f64, + z: f64, + #[buffer] out: &mut [f64], +) -> () { + let scaling = Vector3::new(x, y, z); + let mut out = MatrixViewMut::from_slice(out); + out.copy_from_slice(input); + out.prepend_nonuniform_scaling_mut(&scaling); +} + +#[op2(fast)] +pub fn op_geometry_scale_self( + x: f64, + y: f64, + z: f64, + #[buffer] out: &mut [f64], +) -> () { + let scaling = Vector3::new(x, y, z); + let mut out = MatrixViewMut::from_slice(out); + out.prepend_nonuniform_scaling_mut(&scaling); +} + +#[op2(fast)] +pub fn op_geometry_scale_with_origin( + #[buffer] input: &[f64], + x: f64, + y: f64, + z: f64, + origin_x: f64, + origin_y: f64, + origin_z: f64, + #[buffer] out: &mut [f64], +) -> () { + let scaling = Vector3::new(x, y, z); + let mut shift = Vector3::new(origin_x, origin_y, origin_z); + let mut out = MatrixViewMut::from_slice(out); + out.copy_from_slice(input); + out.prepend_translation_mut(&shift); + out.prepend_nonuniform_scaling_mut(&scaling); + shift.neg_mut(); + out.prepend_translation_mut(&shift); +} + +#[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] out: &mut [f64], +) -> () { + let scaling = Vector3::new(x, y, z); + let mut shift = Vector3::new(origin_x, origin_y, origin_z); + let mut out = MatrixViewMut::from_slice(out); + out.prepend_translation_mut(&shift); + out.prepend_nonuniform_scaling_mut(&scaling); + shift.neg_mut(); + out.prepend_translation_mut(&shift); +} + #[op2(fast)] pub fn op_geometry_multiply( #[buffer] lhs: &[f64], From e8a413df15163f76a4a81bb370376f1f39b09497 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 5 Feb 2024 19:08:51 +0900 Subject: [PATCH 23/66] refactor --- ext/geometry/01_geometry.js | 29 +++++------- ext/geometry/lib.rs | 90 ++++++++----------------------------- 2 files changed, 29 insertions(+), 90 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 0c59a5709d152d..b77c2a196122a4 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -5,11 +5,8 @@ import { op_geometry_multiply, op_geometry_multiply_self, op_geometry_premultiply_self, - op_geometry_scale, op_geometry_scale_self, - op_geometry_scale_with_origin, op_geometry_scale_with_origin_self, - op_geometry_translate, op_geometry_translate_self, } from "ext:core/ops"; const { @@ -875,9 +872,8 @@ class DOMMatrixReadOnly { translate(tx = 0, ty = 0, tz = 0) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); - matrix[_raw] = new Float64Array(16); - op_geometry_translate( - this[_raw], + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_translate_self( webidl.converters["unrestricted double"](tx), webidl.converters["unrestricted double"](ty), webidl.converters["unrestricted double"](tz), @@ -900,18 +896,16 @@ class DOMMatrixReadOnly { originY = webidl.converters["unrestricted double"](originY); originZ = webidl.converters["unrestricted double"](originZ); const matrix = webidl.createBranded(DOMMatrix); - matrix[_raw] = new Float64Array(16); + matrix[_raw] = new Float64Array(this[_raw]); if (originX === 0 && originY === 0 && originZ === 0) { - op_geometry_scale( - this[_raw], + op_geometry_scale_self( webidl.converters["unrestricted double"](scaleX), webidl.converters["unrestricted double"](scaleY), webidl.converters["unrestricted double"](scaleZ), matrix[_raw], ); } else { - op_geometry_scale_with_origin( - this[_raw], + op_geometry_scale_with_origin_self( webidl.converters["unrestricted double"](scaleX), webidl.converters["unrestricted double"](scaleY), webidl.converters["unrestricted double"](scaleZ), @@ -928,9 +922,8 @@ class DOMMatrixReadOnly { scaleNonUniform(scaleX = 1, scaleY = 1) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); - matrix[_raw] = new Float64Array(16); - op_geometry_scale( - this[_raw], + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_scale_self( webidl.converters["unrestricted double"](scaleX), webidl.converters["unrestricted double"](scaleY), 1, @@ -947,18 +940,16 @@ class DOMMatrixReadOnly { originY = webidl.converters["unrestricted double"](originY); originZ = webidl.converters["unrestricted double"](originZ); const matrix = webidl.createBranded(DOMMatrix); - matrix[_raw] = new Float64Array(16); + matrix[_raw] = new Float64Array(this[_raw]); if (originX === 0 && originY === 0 && originZ === 0) { - op_geometry_scale( - this[_raw], + op_geometry_scale_self( scale, scale, scale, matrix[_raw], ); } else { - op_geometry_scale_with_origin( - this[_raw], + op_geometry_scale_with_origin_self( scale, scale, scale, diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index f4a703dd276b83..4d2380fbf5b41b 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -15,11 +15,8 @@ deno_core::extension!( deno_geometry, deps = [deno_webidl, deno_web, deno_console], ops = [ - op_geometry_translate, op_geometry_translate_self, - op_geometry_scale, op_geometry_scale_self, - op_geometry_scale_with_origin, op_geometry_scale_with_origin_self, op_geometry_multiply, op_geometry_multiply_self, @@ -32,44 +29,16 @@ pub fn get_declaration() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_geometry.d.ts") } -#[op2(fast)] -pub fn op_geometry_translate( - #[buffer] input: &[f64], - x: f64, - y: f64, - z: f64, - #[buffer] out: &mut [f64], -) -> () { - let shift = Vector3::new(x, y, z); - let mut out = MatrixViewMut::from_slice(out); - out.copy_from_slice(input); - out.prepend_translation_mut(&shift); -} - #[op2(fast)] pub fn op_geometry_translate_self( x: f64, y: f64, z: f64, - #[buffer] out: &mut [f64], + #[buffer] inout: &mut [f64], ) -> () { let shift = Vector3::new(x, y, z); - let mut out = MatrixViewMut::from_slice(out); - out.prepend_translation_mut(&shift); -} - -#[op2(fast)] -pub fn op_geometry_scale( - #[buffer] input: &[f64], - x: f64, - y: f64, - z: f64, - #[buffer] out: &mut [f64], -) -> () { - let scaling = Vector3::new(x, y, z); - let mut out = MatrixViewMut::from_slice(out); - out.copy_from_slice(input); - out.prepend_nonuniform_scaling_mut(&scaling); + let mut inout = MatrixViewMut::from_slice(inout); + inout.prepend_translation_mut(&shift); } #[op2(fast)] @@ -77,32 +46,11 @@ pub fn op_geometry_scale_self( x: f64, y: f64, z: f64, - #[buffer] out: &mut [f64], + #[buffer] inout: &mut [f64], ) -> () { let scaling = Vector3::new(x, y, z); - let mut out = MatrixViewMut::from_slice(out); - out.prepend_nonuniform_scaling_mut(&scaling); -} - -#[op2(fast)] -pub fn op_geometry_scale_with_origin( - #[buffer] input: &[f64], - x: f64, - y: f64, - z: f64, - origin_x: f64, - origin_y: f64, - origin_z: f64, - #[buffer] out: &mut [f64], -) -> () { - let scaling = Vector3::new(x, y, z); - let mut shift = Vector3::new(origin_x, origin_y, origin_z); - let mut out = MatrixViewMut::from_slice(out); - out.copy_from_slice(input); - out.prepend_translation_mut(&shift); - out.prepend_nonuniform_scaling_mut(&scaling); - shift.neg_mut(); - out.prepend_translation_mut(&shift); + let mut inout = MatrixViewMut::from_slice(inout); + inout.prepend_nonuniform_scaling_mut(&scaling); } #[op2(fast)] @@ -113,15 +61,15 @@ pub fn op_geometry_scale_with_origin_self( origin_x: f64, origin_y: f64, origin_z: f64, - #[buffer] out: &mut [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 out = MatrixViewMut::from_slice(out); - out.prepend_translation_mut(&shift); - out.prepend_nonuniform_scaling_mut(&scaling); + let mut inout = MatrixViewMut::from_slice(inout); + inout.prepend_translation_mut(&shift); + inout.prepend_nonuniform_scaling_mut(&scaling); shift.neg_mut(); - out.prepend_translation_mut(&shift); + inout.prepend_translation_mut(&shift); } #[op2(fast)] @@ -139,23 +87,23 @@ pub fn op_geometry_multiply( #[op2(fast)] pub fn op_geometry_multiply_self( #[buffer] rhs: &[f64], - #[buffer] out: &mut [f64], + #[buffer] inout: &mut [f64], ) -> () { let rhs = MatrixView::from_slice(rhs); - let mut out = MatrixViewMut::from_slice(out); + let mut inout = MatrixViewMut::from_slice(inout); let mut result = Matrix::zeros(); - out.mul_to(&rhs, &mut result); - out.copy_from(&result); + inout.mul_to(&rhs, &mut result); + inout.copy_from(&result); } #[op2(fast)] pub fn op_geometry_premultiply_self( #[buffer] lhs: &[f64], - #[buffer] out: &mut [f64], + #[buffer] inout: &mut [f64], ) -> () { let lhs = MatrixView::from_slice(lhs); - let mut out = MatrixViewMut::from_slice(out); + let mut inout = MatrixViewMut::from_slice(inout); let mut result = Matrix::zeros(); - lhs.mul_to(&out, &mut result); - out.copy_from(&result); + lhs.mul_to(&inout, &mut result); + inout.copy_from(&result); } From 4462ca65f3082adeab2a130fdac3bf1c9b731bb6 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 7 Feb 2024 04:45:04 +0900 Subject: [PATCH 24/66] update types --- ext/geometry/lib.deno_geometry.d.ts | 172 +++++++++++++++++++++++++++- 1 file changed, 168 insertions(+), 4 deletions(-) diff --git a/ext/geometry/lib.deno_geometry.d.ts b/ext/geometry/lib.deno_geometry.d.ts index 19991943cd22ec..75d63044ba801a 100644 --- a/ext/geometry/lib.deno_geometry.d.ts +++ b/ext/geometry/lib.deno_geometry.d.ts @@ -70,23 +70,86 @@ interface DOMMatrix extends DOMMatrixReadOnly { 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, @@ -95,10 +158,33 @@ interface DOMMatrix extends DOMMatrixReadOnly { originY?: number, originZ?: number, ): DOMMatrix; - /** Not available in Worker */ + /** + * 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 + */ skewXSelf(sx?: number): DOMMatrix; + /** + * Modifies the matrix by applying the specified skew transformation along the Y-axis. + * + * @param sy + */ 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; } @@ -118,7 +204,7 @@ interface DOMMatrix extends DOMMatrixReadOnly { declare var DOMMatrix: { prototype: DOMMatrix; new (init?: number[]): DOMMatrix; - /** Not available in Worker */ + /** NOTE: Not available in Worker */ new (init: string): DOMMatrix; fromFloat32Array(array32: Float32Array): DOMMatrix; fromFloat64Array(array64: Float64Array): DOMMatrix; @@ -163,18 +249,68 @@ interface DOMMatrixReadOnly { 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, @@ -183,15 +319,43 @@ interface DOMMatrixReadOnly { 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; - /** @deprecated Supported for legacy reasons to be compatible with `SVGMatrix` as defined in SVG 1.1. Use `scale()` instead. */ + /** + * 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 Y and Z axes' scaling factors are both `1`, but the scaling factor for X must be specified. + * The default origin is `(0, 0, 0)`. + * + * @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 + */ 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 + */ skewY(sy?: number): DOMMatrix; toFloat32Array(): Float32Array; toFloat64Array(): Float64Array; @@ -223,7 +387,7 @@ interface DOMMatrixReadOnly { }; transformPoint(point?: DOMPointInit): DOMPoint; translate(tx?: number, ty?: number, tz?: number): DOMMatrix; - /** Not available in Worker */ + /** NOTE: Not available in Worker */ toString(): string; } From 4ed7117795a1aa1fc1a88ba72a30db2c1c810670 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 7 Feb 2024 04:52:53 +0900 Subject: [PATCH 25/66] add rotate methods --- cli/tests/unit/geometry_test.ts | 210 +++++++++++++++++++++++++++++++- cli/tests/unit/test_util.ts | 1 + ext/geometry/01_geometry.js | 116 ++++++++++++++++++ ext/geometry/lib.rs | 57 +++++++++ 4 files changed, 383 insertions(+), 1 deletion(-) diff --git a/cli/tests/unit/geometry_test.ts b/cli/tests/unit/geometry_test.ts index d18ff59f8919b1..4d75caa4dba8db 100644 --- a/cli/tests/unit/geometry_test.ts +++ b/cli/tests/unit/geometry_test.ts @@ -1,5 +1,9 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -import { assertEquals, assertStrictEquals } from "./test_util.ts"; +import { + assertAlmostEquals, + assertEquals, + assertStrictEquals, +} from "./test_util.ts"; Deno.test(function matrixTranslate() { // deno-fmt-ignore @@ -287,6 +291,210 @@ Deno.test(function matrixScale3dWithOriginSelf() { ); }); +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.707106781186547 , 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 matrixMultiply() { // deno-fmt-ignore const init = { diff --git a/cli/tests/unit/test_util.ts b/cli/tests/unit/test_util.ts index 2f2730794af5a2..31b4e6e268148e 100644 --- a/cli/tests/unit/test_util.ts +++ b/cli/tests/unit/test_util.ts @@ -5,6 +5,7 @@ export { colors }; import { join, resolve } from "@test_util/std/path/mod.ts"; export { assert, + assertAlmostEquals, assertEquals, assertFalse, AssertionError, diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index b77c2a196122a4..220cb193fa8e98 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -5,6 +5,9 @@ import { op_geometry_multiply, op_geometry_multiply_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_translate_self, @@ -963,6 +966,66 @@ class DOMMatrixReadOnly { 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[_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); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_rotate_from_vector_self( + webidl.converters["unrestricted double"](x), + webidl.converters["unrestricted double"](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); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_raw] = new Float64Array(this[_raw]); + if (x !== 0 || y !== 0 || z !== 0) { + op_geometry_rotate_axis_angle_self( + x, + y, + z, + webidl.converters["unrestricted double"](angle), + matrix[_raw], + ); + } + matrix[_is2D] = this[_is2D] && x === 0 && y === 0; + return matrix; + } + multiply(other = {}) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const prefix = "Failed to call 'DOMMatrixReadOnly.prototype.multiply'"; @@ -1425,6 +1488,59 @@ class DOMMatrix extends DOMMatrixReadOnly { return this; } + rotateSelf(rotX = 0, rotY, rotZ) { + webidl.assertBranded(this, DOMMatrixPrototype); + 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); + op_geometry_rotate_from_vector_self( + webidl.converters["unrestricted double"](x), + webidl.converters["unrestricted double"](y), + this[_raw], + ); + return this; + } + + rotateAxisAngleSelf(x = 0, y = 0, z = 0, angle = 0) { + webidl.assertBranded(this, DOMMatrixPrototype); + x = webidl.converters["unrestricted double"](x); + y = webidl.converters["unrestricted double"](y); + z = webidl.converters["unrestricted double"](z); + if (x !== 0 || y !== 0 || z !== 0) { + op_geometry_rotate_axis_angle_self( + x, + y, + z, + webidl.converters["unrestricted double"](angle), + this[_raw], + ); + } + this[_is2D] &&= x === 0 && y === 0; + return this; + } + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { return inspect( createFilteredInspectProxy({ diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 4d2380fbf5b41b..cb826040702200 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -4,6 +4,8 @@ use deno_core::op2; use nalgebra::Matrix4; use nalgebra::MatrixView4; use nalgebra::MatrixViewMut4; +use nalgebra::Rotation3; +use nalgebra::UnitVector3; use nalgebra::Vector3; use std::path::PathBuf; @@ -18,6 +20,9 @@ deno_core::extension!( 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_multiply, op_geometry_multiply_self, op_geometry_premultiply_self, @@ -72,6 +77,58 @@ pub fn op_geometry_scale_with_origin_self( 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 = MatrixViewMut::from_slice(inout); + let mut result = Matrix::zeros(); + inout.mul_to(&rotation, &mut result); + inout.copy_from(&result); +} + +#[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 = MatrixViewMut::from_slice(inout); + let mut result = Matrix::zeros(); + inout.mul_to(&rotation, &mut result); + inout.copy_from(&result); +} + +#[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 = MatrixViewMut::from_slice(inout); + let mut result = Matrix::zeros(); + inout.mul_to(&rotation, &mut result); + inout.copy_from(&result); +} + #[op2(fast)] pub fn op_geometry_multiply( #[buffer] lhs: &[f64], From ad4298586b9e11f19daf43fee3ec42a7ee602de9 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 7 Feb 2024 04:59:25 +0900 Subject: [PATCH 26/66] tweak --- ext/geometry/lib.deno_geometry.d.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/geometry/lib.deno_geometry.d.ts b/ext/geometry/lib.deno_geometry.d.ts index 75d63044ba801a..bb00c1bc42aab2 100644 --- a/ext/geometry/lib.deno_geometry.d.ts +++ b/ext/geometry/lib.deno_geometry.d.ts @@ -169,13 +169,13 @@ interface DOMMatrix extends DOMMatrixReadOnly { /** * Modifies the matrix by applying the specified skew transformation along the X-axis. * - * @param sx + * @param sx in degrees */ skewXSelf(sx?: number): DOMMatrix; /** * Modifies the matrix by applying the specified skew transformation along the Y-axis. * - * @param sy + * @param sy in degrees */ skewYSelf(sy?: number): DOMMatrix; /** @@ -348,13 +348,13 @@ interface DOMMatrixReadOnly { /** * Returns a new DOMMatrix created by applying the specified skew transformation to the source matrix along its X-axis. * - * @param sx + * @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 + * @param sy in degrees */ skewY(sy?: number): DOMMatrix; toFloat32Array(): Float32Array; From 914058ebb28b06ab9f641f53f8362f0bab558a16 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 7 Feb 2024 19:26:52 +0900 Subject: [PATCH 27/66] add skew methods --- cli/tests/unit/geometry_test.ts | 136 ++++++++++++++++++++++++++++++++ ext/geometry/01_geometry.js | 47 +++++++++++ ext/geometry/lib.rs | 36 +++++++++ 3 files changed, 219 insertions(+) diff --git a/cli/tests/unit/geometry_test.ts b/cli/tests/unit/geometry_test.ts index 4d75caa4dba8db..54a58582cee81e 100644 --- a/cli/tests/unit/geometry_test.ts +++ b/cli/tests/unit/geometry_test.ts @@ -495,6 +495,142 @@ Deno.test(function matrixRotateAxisAngleSelf() { } }); +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 = { diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 220cb193fa8e98..37491c0c157cc0 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -10,6 +10,7 @@ import { 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 { @@ -1026,6 +1027,32 @@ class DOMMatrixReadOnly { return matrix; } + skewX(sx = 0) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_skew_self( + webidl.converters["unrestricted double"](sx), + 0, + matrix[_raw], + ); + matrix[_is2D] = this[_is2D]; + return matrix; + } + + skewY(sy = 0) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_skew_self( + 0, + webidl.converters["unrestricted double"](sy), + matrix[_raw], + ); + matrix[_is2D] = this[_is2D]; + return matrix; + } + multiply(other = {}) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const prefix = "Failed to call 'DOMMatrixReadOnly.prototype.multiply'"; @@ -1541,6 +1568,26 @@ class DOMMatrix extends DOMMatrixReadOnly { return this; } + skewXSelf(sx = 0) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + op_geometry_skew_self( + webidl.converters["unrestricted double"](sx), + 0, + this[_raw], + ); + return this; + } + + skewYSelf(sy = 0) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + op_geometry_skew_self( + 0, + webidl.converters["unrestricted double"](sy), + this[_raw], + ); + return this; + } + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { return inspect( createFilteredInspectProxy({ diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index cb826040702200..5ce63ce34f324e 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -23,6 +23,7 @@ deno_core::extension!( 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, @@ -129,6 +130,41 @@ pub fn op_geometry_rotate_axis_angle_self( inout.copy_from(&result); } +#[op2(fast)] +pub fn op_geometry_skew_self( + x_degrees: f64, + y_degrees: f64, + #[buffer] inout: &mut [f64], +) -> () { + let skew: nalgebra::Matrix< + f64, + nalgebra::Const<4>, + nalgebra::Const<4>, + nalgebra::ArrayStorage, + > = Matrix::new( + 1.0, + x_degrees.to_radians().tan(), + 0.0, + 0.0, + y_degrees.to_radians().tan(), + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + ); + let mut inout = MatrixViewMut::from_slice(inout); + let mut result = Matrix::zeros(); + inout.mul_to(&skew, &mut result); + inout.copy_from(&result); +} + #[op2(fast)] pub fn op_geometry_multiply( #[buffer] lhs: &[f64], From 8f6513c0d9a82fe22c63e21f38ee3260928254bc Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 7 Feb 2024 19:37:52 +0900 Subject: [PATCH 28/66] tweak --- ext/geometry/lib.rs | 51 +++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 5ce63ce34f324e..669b1a163f750b 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -9,10 +9,6 @@ use nalgebra::UnitVector3; use nalgebra::Vector3; use std::path::PathBuf; -type Matrix = Matrix4; -type MatrixView<'a> = MatrixView4<'a, f64>; -type MatrixViewMut<'a> = MatrixViewMut4<'a, f64>; - deno_core::extension!( deno_geometry, deps = [deno_webidl, deno_web, deno_console], @@ -43,7 +39,7 @@ pub fn op_geometry_translate_self( #[buffer] inout: &mut [f64], ) -> () { let shift = Vector3::new(x, y, z); - let mut inout = MatrixViewMut::from_slice(inout); + let mut inout = MatrixViewMut4::from_slice(inout); inout.prepend_translation_mut(&shift); } @@ -55,7 +51,7 @@ pub fn op_geometry_scale_self( #[buffer] inout: &mut [f64], ) -> () { let scaling = Vector3::new(x, y, z); - let mut inout = MatrixViewMut::from_slice(inout); + let mut inout = MatrixViewMut4::from_slice(inout); inout.prepend_nonuniform_scaling_mut(&scaling); } @@ -71,7 +67,7 @@ pub fn op_geometry_scale_with_origin_self( ) -> () { let scaling = Vector3::new(x, y, z); let mut shift = Vector3::new(origin_x, origin_y, origin_z); - let mut inout = MatrixViewMut::from_slice(inout); + let mut inout = MatrixViewMut4::from_slice(inout); inout.prepend_translation_mut(&shift); inout.prepend_nonuniform_scaling_mut(&scaling); shift.neg_mut(); @@ -91,8 +87,8 @@ pub fn op_geometry_rotate_self( yaw_degrees.to_radians(), ) .to_homogeneous(); - let mut inout = MatrixViewMut::from_slice(inout); - let mut result = Matrix::zeros(); + let mut inout = MatrixViewMut4::from_slice(inout); + let mut result = Matrix4::zeros(); inout.mul_to(&rotation, &mut result); inout.copy_from(&result); } @@ -105,8 +101,8 @@ pub fn op_geometry_rotate_from_vector_self( ) -> () { let rotation = Rotation3::from_axis_angle(&Vector3::z_axis(), y.atan2(x)).to_homogeneous(); - let mut inout = MatrixViewMut::from_slice(inout); - let mut result = Matrix::zeros(); + let mut inout = MatrixViewMut4::from_slice(inout); + let mut result = Matrix4::zeros(); inout.mul_to(&rotation, &mut result); inout.copy_from(&result); } @@ -124,8 +120,8 @@ pub fn op_geometry_rotate_axis_angle_self( angle_degrees.to_radians(), ) .to_homogeneous(); - let mut inout = MatrixViewMut::from_slice(inout); - let mut result = Matrix::zeros(); + let mut inout = MatrixViewMut4::from_slice(inout); + let mut result = Matrix4::zeros(); inout.mul_to(&rotation, &mut result); inout.copy_from(&result); } @@ -136,12 +132,7 @@ pub fn op_geometry_skew_self( y_degrees: f64, #[buffer] inout: &mut [f64], ) -> () { - let skew: nalgebra::Matrix< - f64, - nalgebra::Const<4>, - nalgebra::Const<4>, - nalgebra::ArrayStorage, - > = Matrix::new( + let skew = Matrix4::new( 1.0, x_degrees.to_radians().tan(), 0.0, @@ -159,8 +150,8 @@ pub fn op_geometry_skew_self( 0.0, 1.0, ); - let mut inout = MatrixViewMut::from_slice(inout); - let mut result = Matrix::zeros(); + let mut inout = MatrixViewMut4::from_slice(inout); + let mut result = Matrix4::zeros(); inout.mul_to(&skew, &mut result); inout.copy_from(&result); } @@ -171,9 +162,9 @@ pub fn op_geometry_multiply( #[buffer] rhs: &[f64], #[buffer] out: &mut [f64], ) -> () { - let lhs = MatrixView::from_slice(lhs); - let rhs = MatrixView::from_slice(rhs); - let mut out = MatrixViewMut::from_slice(out); + 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); } @@ -182,9 +173,9 @@ pub fn op_geometry_multiply_self( #[buffer] rhs: &[f64], #[buffer] inout: &mut [f64], ) -> () { - let rhs = MatrixView::from_slice(rhs); - let mut inout = MatrixViewMut::from_slice(inout); - let mut result = Matrix::zeros(); + 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); } @@ -194,9 +185,9 @@ pub fn op_geometry_premultiply_self( #[buffer] lhs: &[f64], #[buffer] inout: &mut [f64], ) -> () { - let lhs = MatrixView::from_slice(lhs); - let mut inout = MatrixViewMut::from_slice(inout); - let mut result = Matrix::zeros(); + 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); } From 284a6744f9b7ea75e2292579ea9d91ea1a6fc563 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 7 Feb 2024 19:59:56 +0900 Subject: [PATCH 29/66] perf --- ext/geometry/lib.rs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 669b1a163f750b..4faaee13e71a84 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -132,28 +132,21 @@ pub fn op_geometry_skew_self( y_degrees: f64, #[buffer] inout: &mut [f64], ) -> () { - let skew = Matrix4::new( + let skew = Matrix4x2::new( 1.0, x_degrees.to_radians().tan(), - 0.0, - 0.0, y_degrees.to_radians().tan(), 1.0, 0.0, 0.0, 0.0, 0.0, - 1.0, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0, ); let mut inout = MatrixViewMut4::from_slice(inout); - let mut result = Matrix4::zeros(); + let mut result = Matrix4x2::zeros(); inout.mul_to(&skew, &mut result); - inout.copy_from(&result); + inout.set_column(0, &result.column(0)); + inout.set_column(1, &result.column(1)); } #[op2(fast)] From 4b315e35ac697e52ba5eb46e444f072520d8af27 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 7 Feb 2024 20:12:44 +0900 Subject: [PATCH 30/66] add flip methods --- cli/tests/unit/geometry_test.ts | 52 +++++++++++++++++++++++++++++++++ ext/geometry/01_geometry.js | 20 +++++++++++++ ext/geometry/lib.rs | 15 ++++++++++ 3 files changed, 87 insertions(+) diff --git a/cli/tests/unit/geometry_test.ts b/cli/tests/unit/geometry_test.ts index 54a58582cee81e..c4d706479c0662 100644 --- a/cli/tests/unit/geometry_test.ts +++ b/cli/tests/unit/geometry_test.ts @@ -761,3 +761,55 @@ Deno.test(function matrixPreMultiplySelfWithSelf() { ); }); +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 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.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, + }), + ); +}); + diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 37491c0c157cc0..fa92c42b9424f4 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -2,6 +2,8 @@ import { primordials } from "ext:core/mod.js"; import { + op_geometry_flip_x_self, + op_geometry_flip_y_self, op_geometry_multiply, op_geometry_multiply_self, op_geometry_premultiply_self, @@ -1073,6 +1075,24 @@ class DOMMatrixReadOnly { return matrix; } + flipX() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const matrix = webidl.createBranded(DOMMatrix); + 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[_raw] = new Float64Array(this[_raw]); + op_geometry_flip_y_self(matrix[_raw]); + matrix[_is2D] = this[_is2D]; + return matrix; + } + toFloat32Array() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return new Float32Array(this[_raw]); diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 4faaee13e71a84..950f54af8a7afe 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -2,6 +2,7 @@ use deno_core::op2; use nalgebra::Matrix4; +use nalgebra::Matrix4x2; use nalgebra::MatrixView4; use nalgebra::MatrixViewMut4; use nalgebra::Rotation3; @@ -23,6 +24,8 @@ deno_core::extension!( op_geometry_multiply, op_geometry_multiply_self, op_geometry_premultiply_self, + op_geometry_flip_x_self, + op_geometry_flip_y_self, ], esm = ["01_geometry.js"], ); @@ -184,3 +187,15 @@ pub fn op_geometry_premultiply_self( 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() +} From c0042c06619e3adee49f43e6f22325f6a797edf3 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 10 Feb 2024 17:46:12 +0900 Subject: [PATCH 31/66] perf --- ext/geometry/lib.rs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 950f54af8a7afe..8c96cb3f81517c 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -3,6 +3,7 @@ use deno_core::op2; use nalgebra::Matrix4; use nalgebra::Matrix4x2; +use nalgebra::Matrix4x3; use nalgebra::MatrixView4; use nalgebra::MatrixViewMut4; use nalgebra::Rotation3; @@ -91,9 +92,11 @@ pub fn op_geometry_rotate_self( ) .to_homogeneous(); let mut inout = MatrixViewMut4::from_slice(inout); - let mut result = Matrix4::zeros(); - inout.mul_to(&rotation, &mut result); - inout.copy_from(&result); + 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)] @@ -105,9 +108,11 @@ pub fn op_geometry_rotate_from_vector_self( let rotation = Rotation3::from_axis_angle(&Vector3::z_axis(), y.atan2(x)).to_homogeneous(); let mut inout = MatrixViewMut4::from_slice(inout); - let mut result = Matrix4::zeros(); - inout.mul_to(&rotation, &mut result); - inout.copy_from(&result); + 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)] @@ -124,9 +129,11 @@ pub fn op_geometry_rotate_axis_angle_self( ) .to_homogeneous(); let mut inout = MatrixViewMut4::from_slice(inout); - let mut result = Matrix4::zeros(); - inout.mul_to(&rotation, &mut result); - inout.copy_from(&result); + 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)] From b32a43ff3f71f6bd92778573c0c24726bdea67b0 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 10 Feb 2024 18:40:56 +0900 Subject: [PATCH 32/66] add inverse methods --- cli/tests/unit/geometry_test.ts | 51 +++++++++++++++++++++++++++++++++ ext/geometry/01_geometry.js | 21 ++++++++++++-- ext/geometry/lib.rs | 22 ++++++++++++-- 3 files changed, 90 insertions(+), 4 deletions(-) diff --git a/cli/tests/unit/geometry_test.ts b/cli/tests/unit/geometry_test.ts index c4d706479c0662..1e25102d698f22 100644 --- a/cli/tests/unit/geometry_test.ts +++ b/cli/tests/unit/geometry_test.ts @@ -813,3 +813,54 @@ Deno.test(function matrixflipX() { ); }); +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, + }), + ); +}); diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index fa92c42b9424f4..3a8ee7cf972938 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -4,6 +4,7 @@ import { primordials } from "ext:core/mod.js"; import { op_geometry_flip_x_self, op_geometry_flip_y_self, + op_geometry_invert_self, op_geometry_multiply, op_geometry_multiply_self, op_geometry_premultiply_self, @@ -1093,6 +1094,15 @@ class DOMMatrixReadOnly { return matrix; } + inverse() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_raw] = new Float64Array(this[_raw]); + const invertible = op_geometry_invert_self(matrix[_raw]); + matrix[_is2D] = this[_is2D] && invertible; + return matrix; + } + toFloat32Array() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return new Float32Array(this[_raw]); @@ -1589,7 +1599,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } skewXSelf(sx = 0) { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + webidl.assertBranded(this, DOMMatrixPrototype); op_geometry_skew_self( webidl.converters["unrestricted double"](sx), 0, @@ -1599,7 +1609,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } skewYSelf(sy = 0) { - webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + webidl.assertBranded(this, DOMMatrixPrototype); op_geometry_skew_self( 0, webidl.converters["unrestricted double"](sy), @@ -1608,6 +1618,13 @@ class DOMMatrix extends DOMMatrixReadOnly { return this; } + invertSelf() { + webidl.assertBranded(this, DOMMatrixPrototype); + const invertible = op_geometry_invert_self(this[_raw]); + this[_is2D] &&= invertible; + return this; + } + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { return inspect( createFilteredInspectProxy({ diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 8c96cb3f81517c..1a101f21d95b6c 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -27,6 +27,7 @@ deno_core::extension!( op_geometry_premultiply_self, op_geometry_flip_x_self, op_geometry_flip_y_self, + op_geometry_invert_self, ], esm = ["01_geometry.js"], ); @@ -198,11 +199,28 @@ pub fn op_geometry_premultiply_self( #[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() + 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() + inout.column_mut(1).neg_mut(); +} + +#[op2(fast)] +pub fn op_geometry_invert_self(#[buffer] inout: &mut [f64]) -> bool { + let mut inout = MatrixViewMut4::from_slice(inout); + + if inout.iter().any(|&x| x.is_infinite()) { + inout.fill(f64::NAN); + return false; + } + + if !inout.try_inverse_mut() { + inout.fill(f64::NAN); + return false; + } + + true } From 9025bd84b9bfdf0719e9edf13ea33338b09b03f1 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 10 Feb 2024 19:10:14 +0900 Subject: [PATCH 33/66] add transform point methods --- cli/tests/unit/geometry_test.ts | 25 ++++++++++++++++++++ ext/geometry/01_geometry.js | 41 +++++++++++++++++++++++++++++++-- ext/geometry/lib.rs | 15 ++++++++++++ 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/cli/tests/unit/geometry_test.ts b/cli/tests/unit/geometry_test.ts index 1e25102d698f22..22ca76097c2810 100644 --- a/cli/tests/unit/geometry_test.ts +++ b/cli/tests/unit/geometry_test.ts @@ -5,6 +5,31 @@ import { assertStrictEquals, } 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 = { diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 3a8ee7cf972938..2ce0c1eabb817b 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -7,6 +7,7 @@ import { 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, @@ -270,8 +271,26 @@ class DOMPointReadOnly { return this[_raw][3]; } - // TODO - matrixTransform() {} + matrixTransform(matrix = {}) { + webidl.assertBranded(this, DOMPointReadOnlyPrototype); + const prefix = + "Failed to call 'DOMPointReadOnly.prototype.matrixTransform'"; + 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[_raw] = new Float64Array(this[_raw]); + op_geometry_premultiply_point_self(matrix[_raw], point[_raw]); + return point; + } toJSON() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); @@ -1103,6 +1122,24 @@ class DOMMatrixReadOnly { return matrix; } + transformPoint(point = {}) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + point = webidl.converters.DOMPointInit( + point, + "Failed to call 'DOMMatrixReadOnly.prototype.transformPoint'", + "Argument 1", + ); + const result = webidl.createBranded(DOMPoint); + 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]); diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 1a101f21d95b6c..5964425883d8c2 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -9,6 +9,8 @@ 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!( @@ -28,6 +30,7 @@ deno_core::extension!( op_geometry_flip_x_self, op_geometry_flip_y_self, op_geometry_invert_self, + op_geometry_premultiply_point_self, ], esm = ["01_geometry.js"], ); @@ -224,3 +227,15 @@ pub fn op_geometry_invert_self(#[buffer] inout: &mut [f64]) -> bool { 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); +} From 034c965dac691630a6a8dba3ff10a1eba13d67f0 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 10 Feb 2024 19:36:27 +0900 Subject: [PATCH 34/66] add prototype overwrite checks --- cli/tests/unit/geometry_test.ts | 252 ++++++++++++++++++++++++++++++++ ext/geometry/01_geometry.js | 76 +++++++++- 2 files changed, 325 insertions(+), 3 deletions(-) diff --git a/cli/tests/unit/geometry_test.ts b/cli/tests/unit/geometry_test.ts index 22ca76097c2810..c2c3433b45a219 100644 --- a/cli/tests/unit/geometry_test.ts +++ b/cli/tests/unit/geometry_test.ts @@ -3,6 +3,7 @@ import { assertAlmostEquals, assertEquals, assertStrictEquals, + assertThrows, } from "./test_util.ts"; Deno.test(function matrixTransformPoint() { @@ -889,3 +890,254 @@ Deno.test(function matrixInvertSelf() { }), ); }); + +Deno.test(function prototypeOverwrite() { + const point = new DOMPointReadOnly(); + Object.setPrototypeOf(point, DOMPoint.prototype); + assertThrows( + () => { + // @ts-ignore + point.x = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + point.y = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + point.z = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + point.w = 1; + }, + TypeError, + "Illegal invocation", + ); + + const rect = new DOMRectReadOnly(); + Object.setPrototypeOf(rect, DOMRect.prototype); + assertThrows( + () => { + // @ts-ignore + rect.x = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + rect.y = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + rect.width = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + rect.height = 1; + }, + TypeError, + "Illegal invocation", + ); + + const matrix = new DOMMatrixReadOnly(); + Object.setPrototypeOf(matrix, DOMMatrix.prototype); + assertThrows( + () => { + // @ts-ignore + matrix.a = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.b = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.c = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.d = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.e = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.f = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.m11 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.m12 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.m13 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.m14 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.m21 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.m22 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.m23 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.m24 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.m31 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.m32 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.m33 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.m34 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.m41 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.m42 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.m43 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore + matrix.m44 = 1; + }, + TypeError, + "Illegal invocation", + ); +}); diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 2ce0c1eabb817b..163fd24107837f 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -223,9 +223,11 @@ webidl.converters.DOMMatrixInit = webidl.createDictionaryConverter( ); const _raw = Symbol("[[raw]]"); +const _writable = Symbol("[[writable]]"); const _brand = webidl.brand; class DOMPointReadOnly { + [_writable] = false; [_raw]; constructor(x = 0, y = 0, z = 0, w = 1) { @@ -245,6 +247,7 @@ class DOMPointReadOnly { "Argument 1", ); const point = webidl.createBranded(DOMPointReadOnly); + point[_writable] = false; point[_raw] = new Float64Array([ other.x, other.y, @@ -287,6 +290,7 @@ class DOMPointReadOnly { } 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; @@ -322,8 +326,9 @@ class DOMPointReadOnly { const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; -// TODO: protect for [[Prototype]] overwrite class DOMPoint extends DOMPointReadOnly { + [_writable] = true; + static fromPoint(other = {}) { other = webidl.converters.DOMPointInit( other, @@ -331,6 +336,7 @@ class DOMPoint extends DOMPointReadOnly { "Argument 1", ); const point = webidl.createBranded(DOMPoint); + point[_writable] = true; point[_raw] = new Float64Array([ other.x, other.y, @@ -346,6 +352,7 @@ class DOMPoint extends DOMPointReadOnly { } set x(value) { webidl.assertBranded(this, DOMPointPrototype); + assertWritable(this); this[_raw][0] = webidl.converters["unrestricted double"](value); } get y() { @@ -354,6 +361,7 @@ class DOMPoint extends DOMPointReadOnly { } set y(value) { webidl.assertBranded(this, DOMPointPrototype); + assertWritable(this); this[_raw][1] = webidl.converters["unrestricted double"](value); } get z() { @@ -362,6 +370,7 @@ class DOMPoint extends DOMPointReadOnly { } set z(value) { webidl.assertBranded(this, DOMPointPrototype); + assertWritable(this); this[_raw][2] = webidl.converters["unrestricted double"](value); } get w() { @@ -370,6 +379,7 @@ class DOMPoint extends DOMPointReadOnly { } set w(value) { webidl.assertBranded(this, DOMPointPrototype); + assertWritable(this); this[_raw][3] = webidl.converters["unrestricted double"](value); } @@ -393,6 +403,7 @@ class DOMPoint extends DOMPointReadOnly { const DOMPointPrototype = DOMPoint.prototype; class DOMRectReadOnly { + [_writable] = false; [_raw]; constructor(x = 0, y = 0, width = 0, height = 0) { @@ -412,6 +423,7 @@ class DOMRectReadOnly { "Argument 1", ); const rect = webidl.createBranded(DOMRectReadOnly); + rect[_writable] = false; rect[_raw] = new Float64Array([ other.x, other.y, @@ -496,8 +508,9 @@ class DOMRectReadOnly { const DOMRectReadOnlyPrototype = DOMRectReadOnly.prototype; -// TODO: protect for [[Prototype]] overwrite class DOMRect extends DOMRectReadOnly { + [_writable] = true; + static fromRect(other = {}) { other = webidl.converters.DOMRectInit( other, @@ -505,6 +518,7 @@ class DOMRect extends DOMRectReadOnly { "Argument 1", ); const rect = webidl.createBranded(DOMRect); + rect[_writable] = true; rect[_raw] = new Float64Array([ other.x, other.y, @@ -520,6 +534,7 @@ class DOMRect extends DOMRectReadOnly { } set x(value) { webidl.assertBranded(this, DOMRectPrototype); + assertWritable(this); this[_raw][0] = webidl.converters["unrestricted double"](value); } get y() { @@ -528,6 +543,7 @@ class DOMRect extends DOMRectReadOnly { } set y(value) { webidl.assertBranded(this, DOMRectPrototype); + assertWritable(this); this[_raw][1] = webidl.converters["unrestricted double"](value); } get width() { @@ -536,6 +552,7 @@ class DOMRect extends DOMRectReadOnly { } set width(value) { webidl.assertBranded(this, DOMRectPrototype); + assertWritable(this); this[_raw][2] = webidl.converters["unrestricted double"](value); } get height() { @@ -544,6 +561,7 @@ class DOMRect extends DOMRectReadOnly { } set height(value) { webidl.assertBranded(this, DOMRectPrototype); + assertWritable(this); this[_raw][3] = webidl.converters["unrestricted double"](value); } @@ -648,6 +666,7 @@ class DOMQuad { const bottom = MathMax(p1y, p2y, p3y, p4y); const bounds = webidl.createBranded(DOMRect); + bounds[_writable] = true; bounds[_raw] = new Float64Array([ left, top, @@ -731,11 +750,13 @@ const _m44 = 15; const _is2D = Symbol("[[is2D]]"); class DOMMatrixReadOnly { + [_writable] = false; [_raw]; [_is2D]; constructor(init = undefined) { const prefix = `Failed to construct '${this.constructor.name}'`; + this[_writable] = false; this[_brand] = _brand; if (typeof init === "string") { if (parseTransformList === null) { @@ -769,6 +790,7 @@ class DOMMatrixReadOnly { static fromMatrix(other = {}) { const prefix = "Failed to call 'DOMMatrixReadOnly.fromMatrix'"; const matrix = webidl.createBranded(DOMMatrixReadOnly); + matrix[_writable] = false; // fast path for DOMMatrix or DOMMatrixReadOnly if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnly, other)) { initMatrixFromMatrix(matrix, other); @@ -785,6 +807,7 @@ class DOMMatrixReadOnly { 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; } @@ -794,6 +817,7 @@ class DOMMatrixReadOnly { 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; } @@ -898,6 +922,7 @@ class DOMMatrixReadOnly { translate(tx = 0, ty = 0, tz = 0) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; matrix[_raw] = new Float64Array(this[_raw]); op_geometry_translate_self( webidl.converters["unrestricted double"](tx), @@ -922,6 +947,7 @@ class DOMMatrixReadOnly { 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( @@ -948,6 +974,7 @@ class DOMMatrixReadOnly { scaleNonUniform(scaleX = 1, scaleY = 1) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; matrix[_raw] = new Float64Array(this[_raw]); op_geometry_scale_self( webidl.converters["unrestricted double"](scaleX), @@ -966,6 +993,7 @@ class DOMMatrixReadOnly { 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( @@ -1005,6 +1033,7 @@ class DOMMatrixReadOnly { : 0; } const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; matrix[_raw] = new Float64Array(this[_raw]); op_geometry_rotate_self( rotX, @@ -1019,6 +1048,7 @@ class DOMMatrixReadOnly { rotateFromVector(x = 0, y = 0) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; matrix[_raw] = new Float64Array(this[_raw]); op_geometry_rotate_from_vector_self( webidl.converters["unrestricted double"](x), @@ -1035,6 +1065,7 @@ class DOMMatrixReadOnly { y = webidl.converters["unrestricted double"](y); z = webidl.converters["unrestricted double"](z); 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( @@ -1052,6 +1083,7 @@ class DOMMatrixReadOnly { skewX(sx = 0) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; matrix[_raw] = new Float64Array(this[_raw]); op_geometry_skew_self( webidl.converters["unrestricted double"](sx), @@ -1065,6 +1097,7 @@ class DOMMatrixReadOnly { skewY(sy = 0) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; matrix[_raw] = new Float64Array(this[_raw]); op_geometry_skew_self( 0, @@ -1089,6 +1122,7 @@ class DOMMatrixReadOnly { 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]; @@ -1098,6 +1132,7 @@ class DOMMatrixReadOnly { 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]; @@ -1107,6 +1142,7 @@ class DOMMatrixReadOnly { 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]; @@ -1116,6 +1152,7 @@ class DOMMatrixReadOnly { inverse() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; matrix[_raw] = new Float64Array(this[_raw]); const invertible = op_geometry_invert_self(matrix[_raw]); matrix[_is2D] = this[_is2D] && invertible; @@ -1130,6 +1167,7 @@ class DOMMatrixReadOnly { "Argument 1", ); const result = webidl.createBranded(DOMPoint); + result[_writable] = true; result[_raw] = new Float64Array([ point.x, point.y, @@ -1223,11 +1261,13 @@ class DOMMatrixReadOnly { const DOMMatrixReadOnlyPrototype = DOMMatrixReadOnly.prototype; -// TODO: protect for [[Prototype]] overwrite class DOMMatrix extends DOMMatrixReadOnly { + [_writable] = true; + static fromMatrix(other = {}) { const prefix = "Failed to call 'DOMMatrix.fromMatrix'"; const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; // fast path for DOMMatrix or DOMMatrixReadOnly if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnly, other)) { initMatrixFromMatrix(matrix, other); @@ -1244,6 +1284,7 @@ class DOMMatrix extends DOMMatrixReadOnly { 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; } @@ -1253,6 +1294,7 @@ class DOMMatrix extends DOMMatrixReadOnly { 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; } @@ -1263,6 +1305,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set a(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); this[_raw][_a] = webidl.converters["unrestricted double"](value); } get b() { @@ -1271,6 +1314,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set b(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); this[_raw][_b] = webidl.converters["unrestricted double"](value); } get c() { @@ -1279,6 +1323,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set c(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); this[_raw][_c] = webidl.converters["unrestricted double"](value); } get d() { @@ -1287,6 +1332,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set d(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); this[_raw][_d] = webidl.converters["unrestricted double"](value); } get e() { @@ -1295,6 +1341,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set e(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); this[_raw][_e] = webidl.converters["unrestricted double"](value); } get f() { @@ -1303,6 +1350,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set f(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); this[_raw][_f] = webidl.converters["unrestricted double"](value); } get m11() { @@ -1311,6 +1359,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set m11(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); this[_raw][_m11] = webidl.converters["unrestricted double"](value); } get m12() { @@ -1319,6 +1368,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set m12(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); this[_raw][_m12] = webidl.converters["unrestricted double"](value); } get m13() { @@ -1327,6 +1377,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set m13(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); if (value !== 0) { this[_is2D] = false; } @@ -1338,6 +1389,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set m14(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); if (value !== 0) { this[_is2D] = false; } @@ -1349,6 +1401,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set m21(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); this[_raw][_m21] = webidl.converters["unrestricted double"](value); } get m22() { @@ -1357,6 +1410,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set m22(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); this[_raw][_m22] = webidl.converters["unrestricted double"](value); } get m23() { @@ -1365,6 +1419,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set m23(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); if (value !== 0) { this[_is2D] = false; } @@ -1376,6 +1431,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set m24(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); if (value !== 0) { this[_is2D] = false; } @@ -1387,6 +1443,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set m31(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); if (value !== 0) { this[_is2D] = false; } @@ -1398,6 +1455,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set m32(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); if (value !== 0) { this[_is2D] = false; } @@ -1409,6 +1467,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set m33(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); if (value !== 1) { this[_is2D] = false; } @@ -1420,6 +1479,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set m34(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); if (value !== 0) { this[_is2D] = false; } @@ -1431,6 +1491,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set m41(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); this[_raw][_m41] = webidl.converters["unrestricted double"](value); } get m42() { @@ -1439,6 +1500,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set m42(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); this[_raw][_m42] = webidl.converters["unrestricted double"](value); } get m43() { @@ -1447,6 +1509,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set m43(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); if (value !== 0) { this[_is2D] = false; } @@ -1458,6 +1521,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } set m44(value) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); if (value !== 1) { this[_is2D] = false; } @@ -1701,6 +1765,12 @@ class DOMMatrix extends DOMMatrixReadOnly { const DOMMatrixPrototype = DOMMatrix.prototype; +function assertWritable(self) { + if (self[_writable] !== true) { + throw new TypeError("Illegal invocation"); + } +} + /** * https://tc39.es/ecma262/#sec-samevaluezero * @param {number} x From ce9544c38ef642ce89ec556d6bd952cf2715ff85 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 10 Feb 2024 19:59:36 +0900 Subject: [PATCH 35/66] lazyload --- ext/geometry/lib.rs | 2 +- runtime/js/98_global_scope_shared.js | 8 ---- runtime/js/98_global_scope_window.js | 72 +++++++++++++++++++++------- runtime/js/98_global_scope_worker.js | 29 +++++++++++ 4 files changed, 84 insertions(+), 27 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 5964425883d8c2..6ed8460b6bb03c 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -32,7 +32,7 @@ deno_core::extension!( op_geometry_invert_self, op_geometry_premultiply_point_self, ], - esm = ["01_geometry.js"], + lazy_loaded_esm = ["01_geometry.js"], ); pub fn get_declaration() -> PathBuf { diff --git a/runtime/js/98_global_scope_shared.js b/runtime/js/98_global_scope_shared.js index a22f3a7a9f9cab..aba0f3710f42a2 100644 --- a/runtime/js/98_global_scope_shared.js +++ b/runtime/js/98_global_scope_shared.js @@ -26,7 +26,6 @@ import * as request from "ext:deno_fetch/23_request.js"; import * as response from "ext:deno_fetch/23_response.js"; import * as fetch from "ext:deno_fetch/26_fetch.js"; import * as eventSource from "ext:deno_fetch/27_eventsource.js"; -import * as geometry from "ext:deno_geometry/01_geometry.js"; import * as messagePort from "ext:deno_web/13_message_port.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; import { DOMException } from "ext:deno_web/01_dom_exception.js"; @@ -55,13 +54,6 @@ const windowOrWorkerGlobalScope = { CustomEvent: core.propNonEnumerable(event.CustomEvent), DecompressionStream: core.propNonEnumerable(compression.DecompressionStream), DOMException: core.propNonEnumerable(DOMException), - DOMMatrix: core.propNonEnumerable(geometry.DOMMatrix), - DOMMatrixReadOnly: core.propNonEnumerable(geometry.DOMMatrixReadOnly), - DOMPoint: core.propNonEnumerable(geometry.DOMPoint), - DOMPointReadOnly: core.propNonEnumerable(geometry.DOMPointReadOnly), - DOMQuad: core.propNonEnumerable(geometry.DOMQuad), - DOMRect: core.propNonEnumerable(geometry.DOMRect), - DOMRectReadOnly: core.propNonEnumerable(geometry.DOMRectReadOnly), 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 512ee03a469a07..71fdd9a6aefc87 100644 --- a/runtime/js/98_global_scope_window.js +++ b/runtime/js/98_global_scope_window.js @@ -19,9 +19,9 @@ 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 * as webStorage from "ext:deno_webstorage/01_webstorage.js"; -import * as geometry from "ext:deno_geometry/01_geometry.js"; import * as prompt from "ext:runtime/41_prompt.js"; import { loadWebGPU } from "ext:deno_webgpu/00_init.js"; +const loadGeometry = core.createLazyLoader("ext:deno_geometry/01_geometry.js"); class Navigator { constructor() { @@ -106,25 +106,33 @@ ObjectDefineProperties(Navigator.prototype, { }); const NavigatorPrototype = Navigator.prototype; -geometry.enableWindowFeatures((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, - }; +let geometry; + +function initGeometry() { + if (geometry === undefined) { + geometry = loadGeometry(); + geometry.enableWindowFeatures((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, + }; + } + // TODO(petamoriken): Add CSS parser + throw new TypeError( + `${prefix}: CSS parser is not implemented`, + ); + }); } - // TODO(petamoriken): Add CSS parser - throw new TypeError( - `${prefix}: CSS parser is not implemented`, - ); -}); + return geometry; +} const mainRuntimeGlobalProperties = { Location: location.locationConstructorDescriptor, @@ -140,6 +148,34 @@ const mainRuntimeGlobalProperties = { localStorage: core.propGetterOnly(webStorage.localStorage), sessionStorage: core.propGetterOnly(webStorage.sessionStorage), Storage: core.propNonEnumerable(webStorage.Storage), + DOMMatrix: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMMatrix, + initGeometry, + ), + DOMMatrixReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMMatrixReadOnly, + initGeometry, + ), + DOMPoint: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMPoint, + initGeometry, + ), + DOMPointReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMPointReadOnly, + initGeometry, + ), + DOMQuad: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMQuad, + initGeometry, + ), + DOMRect: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMRect, + initGeometry, + ), + DOMRectReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMRectReadOnly, + initGeometry, + ), }; export { mainRuntimeGlobalProperties, memoizeLazy }; diff --git a/runtime/js/98_global_scope_worker.js b/runtime/js/98_global_scope_worker.js index 8e292108f8305e..e91d329ab32738 100644 --- a/runtime/js/98_global_scope_worker.js +++ b/runtime/js/98_global_scope_worker.js @@ -17,6 +17,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"; +const loadGeometry = core.createLazyLoader("ext:deno_geometry/01_geometry.js"); function memoizeLazy(f) { let v_ = null; @@ -110,6 +111,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 }; From 682fd33535851f767e939e17f1a81026ed27b16b Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 10 Feb 2024 20:06:54 +0900 Subject: [PATCH 36/66] lint --- cli/tests/unit/geometry_test.ts | 60 ++++++++++++++--------------- ext/geometry/lib.deno_geometry.d.ts | 2 + ext/geometry/lib.rs | 26 ++++++------- 3 files changed, 45 insertions(+), 43 deletions(-) diff --git a/cli/tests/unit/geometry_test.ts b/cli/tests/unit/geometry_test.ts index c2c3433b45a219..60b889736de9d7 100644 --- a/cli/tests/unit/geometry_test.ts +++ b/cli/tests/unit/geometry_test.ts @@ -896,7 +896,7 @@ Deno.test(function prototypeOverwrite() { Object.setPrototypeOf(point, DOMPoint.prototype); assertThrows( () => { - // @ts-ignore + // @ts-ignore test point.x = 1; }, TypeError, @@ -904,7 +904,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test point.y = 1; }, TypeError, @@ -912,7 +912,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test point.z = 1; }, TypeError, @@ -920,7 +920,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test point.w = 1; }, TypeError, @@ -931,7 +931,7 @@ Deno.test(function prototypeOverwrite() { Object.setPrototypeOf(rect, DOMRect.prototype); assertThrows( () => { - // @ts-ignore + // @ts-ignore test rect.x = 1; }, TypeError, @@ -939,7 +939,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test rect.y = 1; }, TypeError, @@ -947,7 +947,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test rect.width = 1; }, TypeError, @@ -955,7 +955,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test rect.height = 1; }, TypeError, @@ -966,7 +966,7 @@ Deno.test(function prototypeOverwrite() { Object.setPrototypeOf(matrix, DOMMatrix.prototype); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.a = 1; }, TypeError, @@ -974,7 +974,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.b = 1; }, TypeError, @@ -982,7 +982,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.c = 1; }, TypeError, @@ -990,7 +990,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.d = 1; }, TypeError, @@ -998,7 +998,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.e = 1; }, TypeError, @@ -1006,7 +1006,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.f = 1; }, TypeError, @@ -1014,7 +1014,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.m11 = 1; }, TypeError, @@ -1022,7 +1022,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.m12 = 1; }, TypeError, @@ -1030,7 +1030,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.m13 = 1; }, TypeError, @@ -1038,7 +1038,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.m14 = 1; }, TypeError, @@ -1046,7 +1046,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.m21 = 1; }, TypeError, @@ -1054,7 +1054,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.m22 = 1; }, TypeError, @@ -1062,7 +1062,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.m23 = 1; }, TypeError, @@ -1070,7 +1070,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.m24 = 1; }, TypeError, @@ -1078,7 +1078,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.m31 = 1; }, TypeError, @@ -1086,7 +1086,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.m32 = 1; }, TypeError, @@ -1094,7 +1094,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.m33 = 1; }, TypeError, @@ -1102,7 +1102,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.m34 = 1; }, TypeError, @@ -1110,7 +1110,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.m41 = 1; }, TypeError, @@ -1118,7 +1118,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.m42 = 1; }, TypeError, @@ -1126,7 +1126,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.m43 = 1; }, TypeError, @@ -1134,7 +1134,7 @@ Deno.test(function prototypeOverwrite() { ); assertThrows( () => { - // @ts-ignore + // @ts-ignore test matrix.m44 = 1; }, TypeError, diff --git a/ext/geometry/lib.deno_geometry.d.ts b/ext/geometry/lib.deno_geometry.d.ts index bb00c1bc42aab2..fc506034a78436 100644 --- a/ext/geometry/lib.deno_geometry.d.ts +++ b/ext/geometry/lib.deno_geometry.d.ts @@ -1,5 +1,7 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +// deno-lint-ignore-file no-var + /// /// diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 6ed8460b6bb03c..56ba0112e76547 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -45,7 +45,7 @@ pub fn op_geometry_translate_self( 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); @@ -57,7 +57,7 @@ pub fn op_geometry_scale_self( 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); @@ -72,7 +72,7 @@ pub fn op_geometry_scale_with_origin_self( 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); @@ -88,7 +88,7 @@ pub fn op_geometry_rotate_self( pitch_degrees: f64, yaw_degrees: f64, #[buffer] inout: &mut [f64], -) -> () { +) { let rotation = Rotation3::from_euler_angles( roll_degrees.to_radians(), pitch_degrees.to_radians(), @@ -108,7 +108,7 @@ 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); @@ -126,7 +126,7 @@ pub fn op_geometry_rotate_axis_angle_self( 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(), @@ -145,7 +145,7 @@ 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(), @@ -168,7 +168,7 @@ 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); @@ -179,7 +179,7 @@ pub fn op_geometry_multiply( 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(); @@ -191,7 +191,7 @@ pub fn op_geometry_multiply_self( 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(); @@ -200,13 +200,13 @@ pub fn op_geometry_premultiply_self( } #[op2(fast)] -pub fn op_geometry_flip_x_self(#[buffer] inout: &mut [f64]) -> () { +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]) -> () { +pub fn op_geometry_flip_y_self(#[buffer] inout: &mut [f64]) { let mut inout = MatrixViewMut4::from_slice(inout); inout.column_mut(1).neg_mut(); } @@ -232,7 +232,7 @@ pub fn op_geometry_invert_self(#[buffer] inout: &mut [f64]) -> bool { 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(); From a95399142f5fdba6976c531539ea66870c54eb6c Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 10 Feb 2024 21:00:43 +0900 Subject: [PATCH 37/66] Update wpt --- tools/wpt/expectation.json | 471 ++++++++++++++++++++++++++++++++++++- 1 file changed, 470 insertions(+), 1 deletion(-) diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index 6de59bec9b1232..253b675146c3fe 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -11000,5 +11000,474 @@ "eventsource-cross-origin.window.html": false, "eventsource-reconnect.window.html": false, "request-status-error.window.html": false + }, + "css": { + "geometry": { + "DOMMatrix-001.html": [ + "new DOMMatrix(new DOMMatrix())", + "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(matrix)", + "new DOMMatrix(\"scale(2, 2), translateX(5px) translateY(5px)\")", + "new DOMMatrixReadOnly(new DOMMatrixReadOnly())", + "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(matrix)", + "new DOMMatrixReadOnly(\"scale(2, 2), translateX(5px) translateY(5px)\")" + ], + "DOMMatrix-002.html": true, + "DOMMatrix-003.html": [ + "test scale() with identity scale and nonzero originZ" + ], + "DOMMatrix-a-f-alias.html": true, + "DOMMatrix-attributes.html": true, + "DOMMatrix-css-string.worker.html": [ + "DOMMatrix stringifier in worker (2d identity)", + "DOMMatrix stringifier in worker (3d identity)", + "DOMMatrix stringifier in worker (non-finite values)", + "DOMMatrixReadOnly stringifier in worker (2d identity)", + "DOMMatrixReadOnly stringifier in worker (3d identity)", + "DOMMatrixReadOnly stringifier in worker (non-finite values)" + ], + "DOMMatrix-invert-invertible.html": true, + "DOMMatrix-invert-non-invertible.html": true, + "DOMMatrix-invert-preserves-2d.html": [ + "scale" + ], + "DOMMatrix-newobject.html": false, + "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", + "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()", + "Stringification of new DOMPointReadOnly()", + "DOMPoint interface: existence and properties of interface object", + "DOMPoint interface: operation fromPoint(optional DOMPointInit)", + "DOMPoint interface: attribute x", + "DOMPoint interface: attribute y", + "DOMPoint interface: attribute z", + "DOMPoint interface: attribute w", + "Stringification of new DOMPoint()", + "DOMRectReadOnly interface: existence and properties of interface 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()", + "Stringification of new DOMRectReadOnly()", + "DOMRect interface: existence and properties of interface object", + "DOMRect interface: operation fromRect(optional DOMRectInit)", + "DOMRect interface: attribute x", + "DOMRect interface: attribute y", + "DOMRect interface: attribute width", + "DOMRect interface: attribute height", + "Stringification of new DOMRect()", + "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", + "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()", + "Stringification of new DOMQuad()", + "DOMMatrixReadOnly interface: existence and properties of interface 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 toFloat32Array()", + "DOMMatrixReadOnly interface: operation toFloat64Array()", + "DOMMatrixReadOnly interface: stringifier", + "DOMMatrixReadOnly interface: operation toJSON()", + "Stringification of new DOMMatrixReadOnly()", + "Stringification of DOMMatrixReadOnly.fromMatrix({is2D: false})", + "DOMMatrix interface: existence and properties of interface 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: operation setMatrixValue(DOMString)", + "Stringification of new DOMMatrix()", + "Stringification of DOMMatrix.fromMatrix({is2D: false})" + ], + "idlharness.any.worker.html": [ + "DOMPointReadOnly interface: existence and properties of interface 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()", + "Stringification of new DOMPointReadOnly()", + "DOMPoint interface: existence and properties of interface object", + "DOMPoint interface: operation fromPoint(optional DOMPointInit)", + "DOMPoint interface: attribute x", + "DOMPoint interface: attribute y", + "DOMPoint interface: attribute z", + "DOMPoint interface: attribute w", + "Stringification of new DOMPoint()", + "DOMRectReadOnly interface: existence and properties of interface 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()", + "Stringification of new DOMRectReadOnly()", + "DOMRect interface: existence and properties of interface object", + "DOMRect interface: operation fromRect(optional DOMRectInit)", + "DOMRect interface: attribute x", + "DOMRect interface: attribute y", + "DOMRect interface: attribute width", + "DOMRect interface: attribute height", + "Stringification of new DOMRect()", + "DOMQuad interface: existence and properties of interface 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()", + "Stringification of new DOMQuad()", + "DOMMatrixReadOnly interface: existence and properties of interface 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 toFloat32Array()", + "DOMMatrixReadOnly interface: operation toFloat64Array()", + "DOMMatrixReadOnly interface: operation toJSON()", + "Stringification of new DOMMatrixReadOnly()", + "Stringification of DOMMatrixReadOnly.fromMatrix({is2D: false})", + "DOMMatrix interface: existence and properties of interface 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()", + "Stringification of new DOMMatrix()", + "Stringification of DOMMatrix.fromMatrix({is2D: false})" + ], + "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" + ] + } } -} +} \ No newline at end of file From 8147325c7a323f45380edfbb7d0710905a471622 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 10 Feb 2024 21:03:13 +0900 Subject: [PATCH 38/66] `Symbol.toStringTag` --- ext/geometry/01_geometry.js | 50 +++++++++++++++++++++++++++++++++++++ tools/wpt/expectation.json | 33 +++--------------------- 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 163fd24107837f..19c2f1025356fd 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -29,6 +29,7 @@ const { ObjectPrototypeIsPrototypeOf, Symbol, SymbolFor, + SymbolToStringTag, TypedArrayPrototypeEvery, TypedArrayPrototypeJoin, TypeError, @@ -326,6 +327,13 @@ class DOMPointReadOnly { const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; +ObjectDefineProperty(DOMPointReadOnlyPrototype, SymbolToStringTag, { + value: "DOMPointReadOnly", + configurable: true, + enumerable: false, + writable: false, +}); + class DOMPoint extends DOMPointReadOnly { [_writable] = true; @@ -402,6 +410,13 @@ class DOMPoint extends DOMPointReadOnly { const DOMPointPrototype = DOMPoint.prototype; +ObjectDefineProperty(DOMPointPrototype, SymbolToStringTag, { + value: "DOMPoint", + configurable: true, + enumerable: false, + writable: false, +}); + class DOMRectReadOnly { [_writable] = false; [_raw]; @@ -508,6 +523,13 @@ class DOMRectReadOnly { const DOMRectReadOnlyPrototype = DOMRectReadOnly.prototype; +ObjectDefineProperty(DOMRectReadOnlyPrototype, SymbolToStringTag, { + value: "DOMRectReadOnly", + configurable: true, + enumerable: false, + writable: false, +}); + class DOMRect extends DOMRectReadOnly { [_writable] = true; @@ -588,6 +610,13 @@ class DOMRect extends DOMRectReadOnly { const DOMRectPrototype = DOMRect.prototype; +ObjectDefineProperty(DOMRectPrototype, SymbolToStringTag, { + value: "DOMRect", + configurable: true, + enumerable: false, + writable: false, +}); + const _p1 = Symbol("[[p1]]"); const _p2 = Symbol("[[p2]]"); const _p3 = Symbol("[[p3]]"); @@ -705,6 +734,13 @@ class DOMQuad { const DOMQuadPrototype = DOMQuad.prototype; +ObjectDefineProperty(DOMQuadPrototype, SymbolToStringTag, { + value: "DOMQuad", + configurable: true, + enumerable: false, + writable: false, +}); + /** * NOTE: column-major order * @@ -1261,6 +1297,13 @@ class DOMMatrixReadOnly { const DOMMatrixReadOnlyPrototype = DOMMatrixReadOnly.prototype; +ObjectDefineProperty(DOMMatrixReadOnlyPrototype, SymbolToStringTag, { + value: "DOMMatrixReadOnly", + configurable: true, + enumerable: false, + writable: false, +}); + class DOMMatrix extends DOMMatrixReadOnly { [_writable] = true; @@ -1765,6 +1808,13 @@ class DOMMatrix extends DOMMatrixReadOnly { const DOMMatrixPrototype = DOMMatrix.prototype; +ObjectDefineProperty(DOMMatrixPrototype, SymbolToStringTag, { + value: "DOMMatrix", + configurable: true, + enumerable: false, + writable: false, +}); + function assertWritable(self) { if (self[_writable] !== true) { throw new TypeError("Illegal invocation"); diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index 253b675146c3fe..e19c5f694af649 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -11109,20 +11109,13 @@ ], "DOMMatrix-a-f-alias.html": true, "DOMMatrix-attributes.html": true, - "DOMMatrix-css-string.worker.html": [ - "DOMMatrix stringifier in worker (2d identity)", - "DOMMatrix stringifier in worker (3d identity)", - "DOMMatrix stringifier in worker (non-finite values)", - "DOMMatrixReadOnly stringifier in worker (2d identity)", - "DOMMatrixReadOnly stringifier in worker (3d identity)", - "DOMMatrixReadOnly stringifier in worker (non-finite values)" - ], + "DOMMatrix-css-string.worker.html": true, "DOMMatrix-invert-invertible.html": true, "DOMMatrix-invert-non-invertible.html": true, "DOMMatrix-invert-preserves-2d.html": [ "scale" ], - "DOMMatrix-newobject.html": false, + "DOMMatrix-newobject.html": true, "DOMMatrix-stringifier.html": [ "WebKitCSSMatrix stringifier: identity (2d)", "WebKitCSSMatrix stringifier: identity (3d)", @@ -11174,14 +11167,12 @@ "DOMPointReadOnly interface: attribute w", "DOMPointReadOnly interface: operation matrixTransform(optional DOMMatrixInit)", "DOMPointReadOnly interface: operation toJSON()", - "Stringification of new DOMPointReadOnly()", "DOMPoint interface: existence and properties of interface object", "DOMPoint interface: operation fromPoint(optional DOMPointInit)", "DOMPoint interface: attribute x", "DOMPoint interface: attribute y", "DOMPoint interface: attribute z", "DOMPoint interface: attribute w", - "Stringification of new DOMPoint()", "DOMRectReadOnly interface: existence and properties of interface object", "DOMRectReadOnly interface: operation fromRect(optional DOMRectInit)", "DOMRectReadOnly interface: attribute x", @@ -11193,14 +11184,12 @@ "DOMRectReadOnly interface: attribute bottom", "DOMRectReadOnly interface: attribute left", "DOMRectReadOnly interface: operation toJSON()", - "Stringification of new DOMRectReadOnly()", "DOMRect interface: existence and properties of interface object", "DOMRect interface: operation fromRect(optional DOMRectInit)", "DOMRect interface: attribute x", "DOMRect interface: attribute y", "DOMRect interface: attribute width", "DOMRect interface: attribute height", - "Stringification of new DOMRect()", "DOMRectList interface: existence and properties of interface object", "DOMRectList interface object length", "DOMRectList interface object name", @@ -11218,7 +11207,6 @@ "DOMQuad interface: attribute p4", "DOMQuad interface: operation getBounds()", "DOMQuad interface: operation toJSON()", - "Stringification of new DOMQuad()", "DOMMatrixReadOnly interface: existence and properties of interface object", "DOMMatrixReadOnly interface: operation fromMatrix(optional DOMMatrixInit)", "DOMMatrixReadOnly interface: operation fromFloat32Array(Float32Array)", @@ -11265,8 +11253,6 @@ "DOMMatrixReadOnly interface: operation toFloat64Array()", "DOMMatrixReadOnly interface: stringifier", "DOMMatrixReadOnly interface: operation toJSON()", - "Stringification of new DOMMatrixReadOnly()", - "Stringification of DOMMatrixReadOnly.fromMatrix({is2D: false})", "DOMMatrix interface: existence and properties of interface object", "DOMMatrix interface: operation fromMatrix(optional DOMMatrixInit)", "DOMMatrix interface: operation fromFloat32Array(Float32Array)", @@ -11304,9 +11290,7 @@ "DOMMatrix interface: operation skewXSelf(optional unrestricted double)", "DOMMatrix interface: operation skewYSelf(optional unrestricted double)", "DOMMatrix interface: operation invertSelf()", - "DOMMatrix interface: operation setMatrixValue(DOMString)", - "Stringification of new DOMMatrix()", - "Stringification of DOMMatrix.fromMatrix({is2D: false})" + "DOMMatrix interface: operation setMatrixValue(DOMString)" ], "idlharness.any.worker.html": [ "DOMPointReadOnly interface: existence and properties of interface object", @@ -11317,14 +11301,12 @@ "DOMPointReadOnly interface: attribute w", "DOMPointReadOnly interface: operation matrixTransform(optional DOMMatrixInit)", "DOMPointReadOnly interface: operation toJSON()", - "Stringification of new DOMPointReadOnly()", "DOMPoint interface: existence and properties of interface object", "DOMPoint interface: operation fromPoint(optional DOMPointInit)", "DOMPoint interface: attribute x", "DOMPoint interface: attribute y", "DOMPoint interface: attribute z", "DOMPoint interface: attribute w", - "Stringification of new DOMPoint()", "DOMRectReadOnly interface: existence and properties of interface object", "DOMRectReadOnly interface: operation fromRect(optional DOMRectInit)", "DOMRectReadOnly interface: attribute x", @@ -11336,14 +11318,12 @@ "DOMRectReadOnly interface: attribute bottom", "DOMRectReadOnly interface: attribute left", "DOMRectReadOnly interface: operation toJSON()", - "Stringification of new DOMRectReadOnly()", "DOMRect interface: existence and properties of interface object", "DOMRect interface: operation fromRect(optional DOMRectInit)", "DOMRect interface: attribute x", "DOMRect interface: attribute y", "DOMRect interface: attribute width", "DOMRect interface: attribute height", - "Stringification of new DOMRect()", "DOMQuad interface: existence and properties of interface object", "DOMQuad interface: operation fromRect(optional DOMRectInit)", "DOMQuad interface: operation fromQuad(optional DOMQuadInit)", @@ -11353,7 +11333,6 @@ "DOMQuad interface: attribute p4", "DOMQuad interface: operation getBounds()", "DOMQuad interface: operation toJSON()", - "Stringification of new DOMQuad()", "DOMMatrixReadOnly interface: existence and properties of interface object", "DOMMatrixReadOnly interface: operation fromMatrix(optional DOMMatrixInit)", "DOMMatrixReadOnly interface: operation fromFloat32Array(Float32Array)", @@ -11399,8 +11378,6 @@ "DOMMatrixReadOnly interface: operation toFloat32Array()", "DOMMatrixReadOnly interface: operation toFloat64Array()", "DOMMatrixReadOnly interface: operation toJSON()", - "Stringification of new DOMMatrixReadOnly()", - "Stringification of DOMMatrixReadOnly.fromMatrix({is2D: false})", "DOMMatrix interface: existence and properties of interface object", "DOMMatrix interface: operation fromMatrix(optional DOMMatrixInit)", "DOMMatrix interface: operation fromFloat32Array(Float32Array)", @@ -11437,9 +11414,7 @@ "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()", - "Stringification of new DOMMatrix()", - "Stringification of DOMMatrix.fromMatrix({is2D: false})" + "DOMMatrix interface: operation invertSelf()" ], "spec-examples.html": true, "structured-serialization.html": [ From 6b1636d6bf77dbc31cb4bc935b4246f4c7620910 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 10 Feb 2024 21:29:37 +0900 Subject: [PATCH 39/66] accept `DOMMatrix` in constructor --- ext/geometry/01_geometry.js | 3 +++ ext/geometry/lib.deno_geometry.d.ts | 2 ++ tools/wpt/expectation.json | 4 ---- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 19c2f1025356fd..40b1285c9f58d2 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -813,6 +813,9 @@ class DOMMatrixReadOnly { 0, 0, 0, 1, ]); this[_is2D] = true; + } else if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, init)) { + this[_raw] = new Float64Array(init[_raw]); + this[_is2D] = init[_is2D]; } else { init = webidl.converters["sequence"]( init, diff --git a/ext/geometry/lib.deno_geometry.d.ts b/ext/geometry/lib.deno_geometry.d.ts index fc506034a78436..8b32f2905a7a27 100644 --- a/ext/geometry/lib.deno_geometry.d.ts +++ b/ext/geometry/lib.deno_geometry.d.ts @@ -206,6 +206,7 @@ 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; @@ -409,6 +410,7 @@ interface DOMMatrixReadOnly { 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; diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index e19c5f694af649..bcbabd77162910 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -11004,7 +11004,6 @@ "css": { "geometry": { "DOMMatrix-001.html": [ - "new DOMMatrix(new DOMMatrix())", "new DOMMatrix(\"none\")", "new DOMMatrix(\" none\")", "new DOMMatrix(\"none \")", @@ -11051,9 +11050,7 @@ "new DOMMatrix(\"inherit\")", "new DOMMatrix(\"initial\")", "new DOMMatrix(\"unset\")", - "new DOMMatrix(matrix)", "new DOMMatrix(\"scale(2, 2), translateX(5px) translateY(5px)\")", - "new DOMMatrixReadOnly(new DOMMatrixReadOnly())", "new DOMMatrixReadOnly(\"none\")", "new DOMMatrixReadOnly(\" none\")", "new DOMMatrixReadOnly(\"none \")", @@ -11100,7 +11097,6 @@ "new DOMMatrixReadOnly(\"inherit\")", "new DOMMatrixReadOnly(\"initial\")", "new DOMMatrixReadOnly(\"unset\")", - "new DOMMatrixReadOnly(matrix)", "new DOMMatrixReadOnly(\"scale(2, 2), translateX(5px) translateY(5px)\")" ], "DOMMatrix-002.html": true, From bdcd342776c59675aa54a25e430f964c93bf8abf Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 10 Feb 2024 21:36:48 +0900 Subject: [PATCH 40/66] fmt --- ext/geometry/lib.deno_geometry.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/geometry/lib.deno_geometry.d.ts b/ext/geometry/lib.deno_geometry.d.ts index 8b32f2905a7a27..e646bc758f94a8 100644 --- a/ext/geometry/lib.deno_geometry.d.ts +++ b/ext/geometry/lib.deno_geometry.d.ts @@ -206,7 +206,7 @@ interface DOMMatrix extends DOMMatrixReadOnly { declare var DOMMatrix: { prototype: DOMMatrix; new (init?: number[]): DOMMatrix; - new (init: DOMMatrix|DOMMatrixReadOnly): DOMMatrix; + new (init: DOMMatrix | DOMMatrixReadOnly): DOMMatrix; /** NOTE: Not available in Worker */ new (init: string): DOMMatrix; fromFloat32Array(array32: Float32Array): DOMMatrix; @@ -410,7 +410,7 @@ interface DOMMatrixReadOnly { declare var DOMMatrixReadOnly: { prototype: DOMMatrixReadOnly; new (init?: number[]): DOMMatrixReadOnly; - new (init: DOMMatrix|DOMMatrixReadOnly): DOMMatrixReadOnly; + new (init: DOMMatrix | DOMMatrixReadOnly): DOMMatrixReadOnly; /** Not available in Worker */ new (init: string): DOMMatrixReadOnly; fromFloat32Array(array32: Float32Array): DOMMatrixReadOnly; From 5a5b89f36316b3e84568aceeb7f44c542f83dcf1 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 10 Feb 2024 23:01:45 +0900 Subject: [PATCH 41/66] reduce errors --- cli/tests/unit/geometry_test.ts | 52 +++++++++++++++++++++++++++++++++ ext/geometry/01_geometry.js | 23 +++++++++++---- ext/geometry/lib.rs | 40 +++++++++++++++++++++++-- tools/wpt/expectation.json | 8 ++--- 4 files changed, 109 insertions(+), 14 deletions(-) diff --git a/cli/tests/unit/geometry_test.ts b/cli/tests/unit/geometry_test.ts index 60b889736de9d7..d3fd204d5370fc 100644 --- a/cli/tests/unit/geometry_test.ts +++ b/cli/tests/unit/geometry_test.ts @@ -891,6 +891,58 @@ Deno.test(function matrixInvertSelf() { ); }); +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); diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 40b1285c9f58d2..18b6268fb25fd6 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -4,6 +4,7 @@ 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, @@ -1006,7 +1007,7 @@ class DOMMatrixReadOnly { matrix[_raw], ); } - matrix[_is2D] = this[_is2D] && scaleZ === 1; + matrix[_is2D] = this[_is2D] && scaleZ === 1 && originZ === 0; return matrix; } @@ -1052,7 +1053,7 @@ class DOMMatrixReadOnly { matrix[_raw], ); } - matrix[_is2D] = this[_is2D] && scale === 1; + matrix[_is2D] = this[_is2D] && scale === 1 && originZ === 0; return matrix; } @@ -1193,7 +1194,12 @@ class DOMMatrixReadOnly { const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; matrix[_raw] = new Float64Array(this[_raw]); - const invertible = op_geometry_invert_self(matrix[_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; } @@ -1660,7 +1666,7 @@ class DOMMatrix extends DOMMatrixReadOnly { this[_raw], ); } - this[_is2D] &&= scaleZ === 1; + this[_is2D] &&= scaleZ === 1 && originZ === 0; return this; } @@ -1688,7 +1694,7 @@ class DOMMatrix extends DOMMatrixReadOnly { this[_raw], ); } - this[_is2D] &&= scale === 1; + this[_is2D] &&= scale === 1 && originZ === 0; return this; } @@ -1767,7 +1773,12 @@ class DOMMatrix extends DOMMatrixReadOnly { invertSelf() { webidl.assertBranded(this, DOMMatrixPrototype); - const invertible = op_geometry_invert_self(this[_raw]); + 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; } diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 56ba0112e76547..207af5ef04b5ec 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -1,6 +1,7 @@ // 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; @@ -30,6 +31,7 @@ deno_core::extension!( op_geometry_flip_x_self, op_geometry_flip_y_self, op_geometry_invert_self, + op_geometry_invert_2d_self, op_geometry_premultiply_point_self, ], lazy_loaded_esm = ["01_geometry.js"], @@ -212,14 +214,48 @@ pub fn op_geometry_flip_y_self(#[buffer] inout: &mut [f64]) { } #[op2(fast)] -pub fn op_geometry_invert_self(#[buffer] inout: &mut [f64]) -> bool { - let mut inout = MatrixViewMut4::from_slice(inout); +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_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; diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index bcbabd77162910..ac362b26352797 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -11100,17 +11100,13 @@ "new DOMMatrixReadOnly(\"scale(2, 2), translateX(5px) translateY(5px)\")" ], "DOMMatrix-002.html": true, - "DOMMatrix-003.html": [ - "test scale() with identity scale and nonzero originZ" - ], + "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": [ - "scale" - ], + "DOMMatrix-invert-preserves-2d.html": true, "DOMMatrix-newobject.html": true, "DOMMatrix-stringifier.html": [ "WebKitCSSMatrix stringifier: identity (2d)", From 7c62dbcb194393df7444c480b58d0a4631ce2ca8 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 10 Feb 2024 23:23:27 +0900 Subject: [PATCH 42/66] tweak --- ext/geometry/01_geometry.js | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 18b6268fb25fd6..831191f268b22d 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -795,17 +795,7 @@ class DOMMatrixReadOnly { const prefix = `Failed to construct '${this.constructor.name}'`; this[_writable] = false; this[_brand] = _brand; - if (typeof init === "string") { - if (parseTransformList === null) { - throw new TypeError( - `${prefix}: Cannot be constructed with string on Workers`, - ); - } else { - const { matrix, is2D } = parseTransformList(init); - this[_raw] = matrix; - this[_is2D] = is2D; - } - } else if (init === undefined) { + if (init === undefined) { // deno-fmt-ignore this[_raw] = new Float64Array([ 1, 0, 0, 0, @@ -817,13 +807,28 @@ class DOMMatrixReadOnly { } else if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, init)) { this[_raw] = new Float64Array(init[_raw]); this[_is2D] = init[_is2D]; - } else { + } else if (webidl.type(init) === "Object") { init = webidl.converters["sequence"]( init, prefix, "Argument 1", ); initMatrixFromSequence(this, init, prefix); + } else { + init = webidl.converters.DOMString( + init, + prefix, + "Argument 1", + ); + if (parseTransformList === null) { + throw new TypeError( + `${prefix}: Cannot be constructed with string on Workers`, + ); + } else { + const { matrix, is2D } = parseTransformList(init); + this[_raw] = matrix; + this[_is2D] = is2D; + } } } From 6d37886e8d7d4a190641a2eee4d414b0fa58abbb Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sat, 10 Feb 2024 23:39:39 +0900 Subject: [PATCH 43/66] fmt --- ext/geometry/lib.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 207af5ef04b5ec..4754516bb025ec 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -221,15 +221,7 @@ pub fn op_geometry_invert_2d_self(#[buffer] inout: &mut [f64]) -> bool { } let mut matrix = Matrix3::new( - inout[0], - inout[4], - inout[12], - inout[1], - inout[5], - inout[13], - 0.0, - 0.0, - 1.0, + inout[0], inout[4], inout[12], inout[1], inout[5], inout[13], 0.0, 0.0, 1.0, ); if !matrix.try_inverse_mut() { From 53829ae851792adef63a839f90384cf364827ade Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 11 Feb 2024 10:01:53 +0900 Subject: [PATCH 44/66] tweak --- ext/geometry/lib.deno_geometry.d.ts | 3 +-- ext/geometry/lib.rs | 33 ++++++++++++++--------------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/ext/geometry/lib.deno_geometry.d.ts b/ext/geometry/lib.deno_geometry.d.ts index e646bc758f94a8..16c94d46f11482 100644 --- a/ext/geometry/lib.deno_geometry.d.ts +++ b/ext/geometry/lib.deno_geometry.d.ts @@ -339,8 +339,7 @@ interface DOMMatrixReadOnly { ): 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 Y and Z axes' scaling factors are both `1`, but the scaling factor for X must be specified. - * The default origin is `(0, 0, 0)`. + * 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. * diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 4754516bb025ec..5ffc09c693aace 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -214,45 +214,44 @@ pub fn op_geometry_flip_y_self(#[buffer] inout: &mut [f64]) { } #[op2(fast)] -pub fn op_geometry_invert_2d_self(#[buffer] inout: &mut [f64]) -> bool { +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 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() { + let mut inout = MatrixViewMut4::from_slice(inout); + if !inout.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_invert_self(#[buffer] inout: &mut [f64]) -> bool { +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 inout = MatrixViewMut4::from_slice(inout); - if !inout.try_inverse_mut() { + 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 } From 092bcd86e7c89545bcf35fd5d05028116054b90d Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 11 Feb 2024 16:22:10 +0900 Subject: [PATCH 45/66] fix --- ext/geometry/01_geometry.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 831191f268b22d..4815ee71b7001d 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -1587,6 +1587,7 @@ class DOMMatrix extends DOMMatrixReadOnly { multiplySelf(other = {}) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); const prefix = "Failed to call 'DOMMatrix.prototype.multiplySelf'"; if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { const _other = webidl.converters.DOMMatrixInit( @@ -1609,6 +1610,7 @@ class DOMMatrix extends DOMMatrixReadOnly { preMultiplySelf(other = {}) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); const prefix = "Failed to call 'DOMMatrix.prototype.premultiplySelf'"; if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { const _other = webidl.converters.DOMMatrixInit( @@ -1631,6 +1633,7 @@ class DOMMatrix extends DOMMatrixReadOnly { translateSelf(tx = 0, ty = 0, tz = 0) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); op_geometry_translate_self( webidl.converters["unrestricted double"](tx), webidl.converters["unrestricted double"](ty), @@ -1650,6 +1653,7 @@ class DOMMatrix extends DOMMatrixReadOnly { originZ = 0, ) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); originX = webidl.converters["unrestricted double"](originX); originY = webidl.converters["unrestricted double"](originY); originZ = webidl.converters["unrestricted double"](originZ); @@ -1677,6 +1681,7 @@ 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); @@ -1705,6 +1710,7 @@ 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; @@ -1730,6 +1736,7 @@ class DOMMatrix extends DOMMatrixReadOnly { rotateFromVectorSelf(x = 0, y = 0) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); op_geometry_rotate_from_vector_self( webidl.converters["unrestricted double"](x), webidl.converters["unrestricted double"](y), @@ -1740,6 +1747,7 @@ 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); @@ -1758,6 +1766,7 @@ class DOMMatrix extends DOMMatrixReadOnly { skewXSelf(sx = 0) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); op_geometry_skew_self( webidl.converters["unrestricted double"](sx), 0, @@ -1768,6 +1777,7 @@ class DOMMatrix extends DOMMatrixReadOnly { skewYSelf(sy = 0) { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); op_geometry_skew_self( 0, webidl.converters["unrestricted double"](sy), @@ -1778,6 +1788,7 @@ class DOMMatrix extends DOMMatrixReadOnly { invertSelf() { webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); let invertible; if (this[_is2D]) { invertible = op_geometry_invert_2d_self(this[_raw]); From 8d2be61851eaadd47f9c092d5a6b28bd519bf24f Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 12 Feb 2024 10:00:28 +0900 Subject: [PATCH 46/66] use `webidl.configureInterface` Co-authored-by: ud2 --- ext/geometry/01_geometry.js | 57 ++------- tools/wpt/expectation.json | 232 +----------------------------------- 2 files changed, 8 insertions(+), 281 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 4815ee71b7001d..b0368299dbe791 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -30,7 +30,6 @@ const { ObjectPrototypeIsPrototypeOf, Symbol, SymbolFor, - SymbolToStringTag, TypedArrayPrototypeEvery, TypedArrayPrototypeJoin, TypeError, @@ -326,15 +325,9 @@ class DOMPointReadOnly { } } +webidl.configureInterface(DOMPointReadOnly); const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; -ObjectDefineProperty(DOMPointReadOnlyPrototype, SymbolToStringTag, { - value: "DOMPointReadOnly", - configurable: true, - enumerable: false, - writable: false, -}); - class DOMPoint extends DOMPointReadOnly { [_writable] = true; @@ -409,15 +402,9 @@ class DOMPoint extends DOMPointReadOnly { } } +webidl.configureInterface(DOMPoint); const DOMPointPrototype = DOMPoint.prototype; -ObjectDefineProperty(DOMPointPrototype, SymbolToStringTag, { - value: "DOMPoint", - configurable: true, - enumerable: false, - writable: false, -}); - class DOMRectReadOnly { [_writable] = false; [_raw]; @@ -522,15 +509,9 @@ class DOMRectReadOnly { } } +webidl.configureInterface(DOMRectReadOnly); const DOMRectReadOnlyPrototype = DOMRectReadOnly.prototype; -ObjectDefineProperty(DOMRectReadOnlyPrototype, SymbolToStringTag, { - value: "DOMRectReadOnly", - configurable: true, - enumerable: false, - writable: false, -}); - class DOMRect extends DOMRectReadOnly { [_writable] = true; @@ -609,15 +590,9 @@ class DOMRect extends DOMRectReadOnly { } } +webidl.configureInterface(DOMRect); const DOMRectPrototype = DOMRect.prototype; -ObjectDefineProperty(DOMRectPrototype, SymbolToStringTag, { - value: "DOMRect", - configurable: true, - enumerable: false, - writable: false, -}); - const _p1 = Symbol("[[p1]]"); const _p2 = Symbol("[[p2]]"); const _p3 = Symbol("[[p3]]"); @@ -733,15 +708,9 @@ class DOMQuad { } } +webidl.configureInterface(DOMQuad); const DOMQuadPrototype = DOMQuad.prototype; -ObjectDefineProperty(DOMQuadPrototype, SymbolToStringTag, { - value: "DOMQuad", - configurable: true, - enumerable: false, - writable: false, -}); - /** * NOTE: column-major order * @@ -1309,15 +1278,9 @@ class DOMMatrixReadOnly { } } +webidl.configureInterface(DOMMatrixReadOnly); const DOMMatrixReadOnlyPrototype = DOMMatrixReadOnly.prototype; -ObjectDefineProperty(DOMMatrixReadOnlyPrototype, SymbolToStringTag, { - value: "DOMMatrixReadOnly", - configurable: true, - enumerable: false, - writable: false, -}); - class DOMMatrix extends DOMMatrixReadOnly { [_writable] = true; @@ -1836,15 +1799,9 @@ class DOMMatrix extends DOMMatrixReadOnly { } } +webidl.configureInterface(DOMMatrix); const DOMMatrixPrototype = DOMMatrix.prototype; -ObjectDefineProperty(DOMMatrixPrototype, SymbolToStringTag, { - value: "DOMMatrix", - configurable: true, - enumerable: false, - writable: false, -}); - function assertWritable(self) { if (self[_writable] !== true) { throw new TypeError("Illegal invocation"); diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index ac362b26352797..07a05b1be195f8 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -11152,36 +11152,9 @@ "historical.html": true, "idlharness.any.html": [ "DOMPointReadOnly interface: existence and properties of interface 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: 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: 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: 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", @@ -11191,222 +11164,19 @@ "DOMRectList interface: attribute length", "DOMRectList interface: operation item(unsigned long)", "DOMQuad interface: existence and properties of interface 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: 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 toFloat32Array()", - "DOMMatrixReadOnly interface: operation toFloat64Array()", "DOMMatrixReadOnly interface: stringifier", - "DOMMatrixReadOnly interface: operation toJSON()", "DOMMatrix interface: existence and properties of interface 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: operation setMatrixValue(DOMString)" ], "idlharness.any.worker.html": [ "DOMPointReadOnly interface: existence and properties of interface 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: 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: 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: 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: 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: 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 toFloat32Array()", - "DOMMatrixReadOnly interface: operation toFloat64Array()", - "DOMMatrixReadOnly interface: operation toJSON()", - "DOMMatrix interface: existence and properties of interface 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 object" ], "spec-examples.html": true, "structured-serialization.html": [ From af9717e8d7c3bf9d1c748742d53916fb3c8a908f Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 12 Feb 2024 10:13:46 +0900 Subject: [PATCH 47/66] fix Co-authored-by: ud2 --- ext/geometry/01_geometry.js | 4 ++-- tools/wpt/expectation.json | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index b0368299dbe791..5f4aa1c605979f 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -2031,7 +2031,7 @@ function enableWindowFeatures(parser) { } }, writable: true, - enumerable: false, + enumerable: true, configurable: true, }); @@ -2051,7 +2051,7 @@ function enableWindowFeatures(parser) { this[_is2D] = is2D; }, writable: true, - enumerable: false, + enumerable: true, configurable: true, }); } diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index 07a05b1be195f8..d48d58e5320140 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -11165,9 +11165,7 @@ "DOMRectList interface: operation item(unsigned long)", "DOMQuad interface: existence and properties of interface object", "DOMMatrixReadOnly interface: existence and properties of interface object", - "DOMMatrixReadOnly interface: stringifier", - "DOMMatrix interface: existence and properties of interface object", - "DOMMatrix interface: operation setMatrixValue(DOMString)" + "DOMMatrix interface: existence and properties of interface object" ], "idlharness.any.worker.html": [ "DOMPointReadOnly interface: existence and properties of interface object", From a4569f985f477d2139c22831647ac29f0c75522b Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 12 Feb 2024 11:20:33 +0900 Subject: [PATCH 48/66] fix --- ext/geometry/01_geometry.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 5f4aa1c605979f..ccecbd11429372 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -762,7 +762,6 @@ class DOMMatrixReadOnly { constructor(init = undefined) { const prefix = `Failed to construct '${this.constructor.name}'`; - this[_writable] = false; this[_brand] = _brand; if (init === undefined) { // deno-fmt-ignore @@ -774,8 +773,8 @@ class DOMMatrixReadOnly { ]); this[_is2D] = true; } else if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, init)) { - this[_raw] = new Float64Array(init[_raw]); - this[_is2D] = init[_is2D]; + // NOTE: not in the spec, but requested by wpt + initMatrixFromMatrix(this, init); } else if (webidl.type(init) === "Object") { init = webidl.converters["sequence"]( init, @@ -806,7 +805,7 @@ class DOMMatrixReadOnly { const matrix = webidl.createBranded(DOMMatrixReadOnly); matrix[_writable] = false; // fast path for DOMMatrix or DOMMatrixReadOnly - if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnly, other)) { + if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { initMatrixFromMatrix(matrix, other); } else { other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); @@ -1289,7 +1288,7 @@ class DOMMatrix extends DOMMatrixReadOnly { const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; // fast path for DOMMatrix or DOMMatrixReadOnly - if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnly, other)) { + if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { initMatrixFromMatrix(matrix, other); } else { other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); From 8e3c0358959e8fc36d9f9ccc8e56d1e5e88ed0d1 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 13 Feb 2024 14:21:02 +0900 Subject: [PATCH 49/66] tweak --- ext/geometry/01_geometry.js | 138 +++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 65 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index ccecbd11429372..87960df0e43d45 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -113,58 +113,66 @@ 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", - [ - { - 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"], - }, - ], + dictDOMMatrix2DInit, [ { key: "m13", @@ -619,12 +627,12 @@ class DOMQuad { "Argument 1", ); const { x, y, width, height } = other; - const point = webidl.createBranded(DOMQuad); - point[_p1] = new DOMPoint(x, y, 0, 1); - point[_p2] = new DOMPoint(x + width, y, 0, 1); - point[_p3] = new DOMPoint(x + width, y + height, 0, 1); - point[_p4] = new DOMPoint(x, y + height, 0, 1); - return point; + 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 = {}) { @@ -633,12 +641,12 @@ class DOMQuad { "Failed to call 'DOMQuad.fromQuad'", "Argument 1", ); - const point = webidl.createBranded(DOMQuad); - point[_p1] = DOMPoint.fromPoint(other.p1); - point[_p2] = DOMPoint.fromPoint(other.p2); - point[_p3] = DOMPoint.fromPoint(other.p3); - point[_p4] = DOMPoint.fromPoint(other.p4); - return point; + 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() { @@ -929,7 +937,7 @@ class DOMMatrixReadOnly { } get isIdentity() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return isMatrixIdentity(this); + return isIdentityMatrix(this); } translate(tx = 0, ty = 0, tz = 0) { @@ -1233,7 +1241,7 @@ class DOMMatrixReadOnly { m43: raw[_m43], m44: raw[_m44], is2D: this[_is2D], - isIdentity: isMatrixIdentity(this), + isIdentity: isIdentityMatrix(this), }; } @@ -1969,7 +1977,7 @@ function initMatrixFromMatrix(target, matrix) { * https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-isidentity * @param {DOMMatrixReadOnly} matrix */ -function isMatrixIdentity(matrix) { +function isIdentityMatrix(matrix) { const raw = matrix[_raw]; return ( raw[_m11] === 1 && From ca71d50f59a325615e2ddc76ee17733ec0279684 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 26 Feb 2024 00:02:32 +0900 Subject: [PATCH 50/66] add geometry/00_init.js --- ext/geometry/00_init.js | 27 ++++++ ext/geometry/01_geometry.js | 127 +++++++++++++-------------- ext/geometry/lib.rs | 1 + runtime/js/98_global_scope_window.js | 64 ++++++-------- runtime/js/98_global_scope_worker.js | 9 +- tools/core_import_map.json | 1 + 6 files changed, 127 insertions(+), 102 deletions(-) create mode 100644 ext/geometry/00_init.js 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 index 87960df0e43d45..c1f0888a939462 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -796,15 +796,9 @@ class DOMMatrixReadOnly { prefix, "Argument 1", ); - if (parseTransformList === null) { - throw new TypeError( - `${prefix}: Cannot be constructed with string on Workers`, - ); - } else { - const { matrix, is2D } = parseTransformList(init); - this[_raw] = matrix; - this[_is2D] = is2D; - } + const { matrix, is2D } = parseTransformList(init, prefix); + this[_raw] = matrix; + this[_is2D] = is2D; } } @@ -2001,66 +1995,69 @@ function isIdentityMatrix(matrix) { /** * CSS parser - * @type {((transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean }) | null} + * @type {((transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean })} */ -let parseTransformList = null; +let parseTransformList; /** - * @param {(transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean }} parser + * @param {(transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean }} transformListParser + * @param {boolean} enableWindowFeatures */ -function enableWindowFeatures(parser) { - parseTransformList = parser; - - // 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 'DOMMatrixReadOnly.prototype.toString': Cannot be serialized with NaN or Infinity values", - "InvalidStateError", +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 'DOMMatrixReadOnly.prototype.toString': Cannot be serialized with NaN or Infinity values", + "InvalidStateError", + ); + } + if (this[_is2D]) { + return `matrix(${ + ArrayPrototypeJoin([ + raw[_a], + raw[_b], + raw[_c], + raw[_d], + raw[_e], + raw[_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 call 'DOMMatrix.prototype.setMatrixValue'"; + webidl.requiredArguments(arguments.length, 1, prefix); + transformList = webidl.converters.DOMString( + transformList, + prefix, + "Argument 1", ); - } - if (this[_is2D]) { - return `matrix(${ - ArrayPrototypeJoin([ - raw[_a], - raw[_b], - raw[_c], - raw[_d], - raw[_e], - raw[_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 call 'DOMMatrix.prototype.setMatrixValue'"; - webidl.requiredArguments(arguments.length, 1, prefix); - transformList = webidl.converters.DOMString( - transformList, - prefix, - "Argument 1", - ); - const { matrix, is2D } = parser(transformList); - this[_raw] = matrix; - this[_is2D] = is2D; - }, - writable: true, - enumerable: true, - configurable: true, - }); + const { matrix, is2D } = parseTransformList(transformList, prefix); + this[_raw] = matrix; + this[_is2D] = is2D; + }, + writable: true, + enumerable: true, + configurable: true, + }); + } } export { @@ -2078,5 +2075,5 @@ export { DOMRectPrototype, DOMRectReadOnly, DOMRectReadOnlyPrototype, - enableWindowFeatures, + init, }; diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 5ffc09c693aace..16879f4ddf2071 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -34,6 +34,7 @@ deno_core::extension!( op_geometry_invert_2d_self, op_geometry_premultiply_point_self, ], + esm = ["00_init.js"], lazy_loaded_esm = ["01_geometry.js"], ); diff --git a/runtime/js/98_global_scope_window.js b/runtime/js/98_global_scope_window.js index 71fdd9a6aefc87..0af75c3af8d878 100644 --- a/runtime/js/98_global_scope_window.js +++ b/runtime/js/98_global_scope_window.js @@ -21,7 +21,27 @@ 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"; -const loadGeometry = core.createLazyLoader("ext:deno_geometry/01_geometry.js"); +import { createGeometryLoader } from "ext:deno_geometry/00_init.js"; + +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, + }; + } + + // TODO(petamoriken): Add CSS parser + throw new TypeError( + `${prefix}: CSS parser is not implemented`, + ); +}, true); class Navigator { constructor() { @@ -106,34 +126,6 @@ ObjectDefineProperties(Navigator.prototype, { }); const NavigatorPrototype = Navigator.prototype; -let geometry; - -function initGeometry() { - if (geometry === undefined) { - geometry = loadGeometry(); - geometry.enableWindowFeatures((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, - }; - } - // TODO(petamoriken): Add CSS parser - throw new TypeError( - `${prefix}: CSS parser is not implemented`, - ); - }); - } - - return geometry; -} - const mainRuntimeGlobalProperties = { Location: location.locationConstructorDescriptor, location: location.locationDescriptor, @@ -150,31 +142,31 @@ const mainRuntimeGlobalProperties = { Storage: core.propNonEnumerable(webStorage.Storage), DOMMatrix: core.propNonEnumerableLazyLoaded( (geometry) => geometry.DOMMatrix, - initGeometry, + loadGeometry, ), DOMMatrixReadOnly: core.propNonEnumerableLazyLoaded( (geometry) => geometry.DOMMatrixReadOnly, - initGeometry, + loadGeometry, ), DOMPoint: core.propNonEnumerableLazyLoaded( (geometry) => geometry.DOMPoint, - initGeometry, + loadGeometry, ), DOMPointReadOnly: core.propNonEnumerableLazyLoaded( (geometry) => geometry.DOMPointReadOnly, - initGeometry, + loadGeometry, ), DOMQuad: core.propNonEnumerableLazyLoaded( (geometry) => geometry.DOMQuad, - initGeometry, + loadGeometry, ), DOMRect: core.propNonEnumerableLazyLoaded( (geometry) => geometry.DOMRect, - initGeometry, + loadGeometry, ), DOMRectReadOnly: core.propNonEnumerableLazyLoaded( (geometry) => geometry.DOMRectReadOnly, - initGeometry, + loadGeometry, ), }; diff --git a/runtime/js/98_global_scope_worker.js b/runtime/js/98_global_scope_worker.js index e91d329ab32738..20783c17b292f1 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,7 +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"; -const loadGeometry = core.createLazyLoader("ext:deno_geometry/01_geometry.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; diff --git a/tools/core_import_map.json b/tools/core_import_map.json index 02cb88666f19ca..48c2c3957bc3d4 100644 --- a/tools/core_import_map.json +++ b/tools/core_import_map.json @@ -15,6 +15,7 @@ "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.js": "../ext/http/00_serve.js", "ext:deno_http/01_http.js": "../ext/http/01_http.js", From 494777b833fe2927889446b27ba716fab776e937 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 26 Feb 2024 00:18:15 +0900 Subject: [PATCH 51/66] fix: rename constants --- ext/geometry/01_geometry.js | 270 ++++++++++++++++++------------------ 1 file changed, 135 insertions(+), 135 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index c1f0888a939462..c4b08d7db10412 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -719,7 +719,7 @@ class DOMQuad { webidl.configureInterface(DOMQuad); const DOMQuadPrototype = DOMQuad.prototype; -/** +/* * NOTE: column-major order * * For a 2D 3x2 matrix, the index of properties in @@ -728,14 +728,14 @@ const DOMQuadPrototype = DOMQuad.prototype; * | 0 0 1 0 | is | _ _ _ _ | * | 0 0 0 1 | | _ _ _ _ | */ -const _a = 0; -const _b = 1; -const _c = 4; -const _d = 5; -const _e = 12; -const _f = 13; - -/** +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 @@ -744,22 +744,22 @@ const _f = 13; * | m13 m23 m33 m43 | is | 2 6 10 14 | * | m14 m24 m34 m44 | | 3 7 11 15 | */ -const _m11 = 0; -const _m12 = 1; -const _m13 = 2; -const _m14 = 3; -const _m21 = 4; -const _m22 = 5; -const _m23 = 6; -const _m24 = 7; -const _m31 = 8; -const _m32 = 9; -const _m33 = 10; -const _m34 = 11; -const _m41 = 12; -const _m42 = 13; -const _m43 = 14; -const _m44 = 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]]"); @@ -839,91 +839,91 @@ class DOMMatrixReadOnly { get a() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_a]; + return this[_raw][INDEX_A]; } get b() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_b]; + return this[_raw][INDEX_B]; } get c() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_c]; + return this[_raw][INDEX_C]; } get d() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_d]; + return this[_raw][INDEX_D]; } get e() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_e]; + return this[_raw][INDEX_E]; } get f() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_f]; + return this[_raw][INDEX_F]; } get m11() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_m11]; + return this[_raw][INDEX_M11]; } get m12() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_m12]; + return this[_raw][INDEX_M12]; } get m13() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_m13]; + return this[_raw][INDEX_M13]; } get m14() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_m14]; + return this[_raw][INDEX_M14]; } get m21() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_m21]; + return this[_raw][INDEX_M21]; } get m22() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_m22]; + return this[_raw][INDEX_M22]; } get m23() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_m23]; + return this[_raw][INDEX_M23]; } get m24() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_m24]; + return this[_raw][INDEX_M24]; } get m31() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_m31]; + return this[_raw][INDEX_M31]; } get m32() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_m32]; + return this[_raw][INDEX_M32]; } get m33() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_m33]; + return this[_raw][INDEX_M33]; } get m34() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_m34]; + return this[_raw][INDEX_M34]; } get m41() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_m41]; + return this[_raw][INDEX_M41]; } get m42() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_m42]; + return this[_raw][INDEX_M42]; } get m43() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_m43]; + return this[_raw][INDEX_M43]; } get m44() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][_m44]; + return this[_raw][INDEX_M44]; } get is2D() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); @@ -1212,28 +1212,28 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const raw = this[_raw]; return { - a: raw[_a], - b: raw[_b], - c: raw[_c], - d: raw[_d], - e: raw[_e], - f: raw[_f], - m11: raw[_m11], - m12: raw[_m12], - m13: raw[_m13], - m14: raw[_m14], - m21: raw[_m21], - m22: raw[_m22], - m23: raw[_m23], - m24: raw[_m24], - m31: raw[_m31], - m32: raw[_m32], - m33: raw[_m33], - m34: raw[_m34], - m41: raw[_m41], - m42: raw[_m42], - m43: raw[_m43], - m44: raw[_m44], + 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), }; @@ -1322,79 +1322,79 @@ class DOMMatrix extends DOMMatrixReadOnly { get a() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_a]; + return this[_raw][INDEX_A]; } set a(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][_a] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_A] = webidl.converters["unrestricted double"](value); } get b() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_b]; + return this[_raw][INDEX_B]; } set b(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][_b] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_B] = webidl.converters["unrestricted double"](value); } get c() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_c]; + return this[_raw][INDEX_C]; } set c(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][_c] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_C] = webidl.converters["unrestricted double"](value); } get d() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_d]; + return this[_raw][INDEX_D]; } set d(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][_d] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_D] = webidl.converters["unrestricted double"](value); } get e() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_e]; + return this[_raw][INDEX_E]; } set e(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][_e] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_E] = webidl.converters["unrestricted double"](value); } get f() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_f]; + return this[_raw][INDEX_F]; } set f(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][_f] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_F] = webidl.converters["unrestricted double"](value); } get m11() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_m11]; + return this[_raw][INDEX_M11]; } set m11(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][_m11] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_M11] = webidl.converters["unrestricted double"](value); } get m12() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_m12]; + return this[_raw][INDEX_M12]; } set m12(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][_m12] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_M12] = webidl.converters["unrestricted double"](value); } get m13() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_m13]; + return this[_raw][INDEX_M13]; } set m13(value) { webidl.assertBranded(this, DOMMatrixPrototype); @@ -1402,11 +1402,11 @@ class DOMMatrix extends DOMMatrixReadOnly { if (value !== 0) { this[_is2D] = false; } - this[_raw][_m13] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_M13] = webidl.converters["unrestricted double"](value); } get m14() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_m14]; + return this[_raw][INDEX_M14]; } set m14(value) { webidl.assertBranded(this, DOMMatrixPrototype); @@ -1414,29 +1414,29 @@ class DOMMatrix extends DOMMatrixReadOnly { if (value !== 0) { this[_is2D] = false; } - this[_raw][_m14] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_M14] = webidl.converters["unrestricted double"](value); } get m21() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_m21]; + return this[_raw][INDEX_M21]; } set m21(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][_m21] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_M21] = webidl.converters["unrestricted double"](value); } get m22() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_m22]; + return this[_raw][INDEX_M22]; } set m22(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][_m22] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_M22] = webidl.converters["unrestricted double"](value); } get m23() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_m23]; + return this[_raw][INDEX_M23]; } set m23(value) { webidl.assertBranded(this, DOMMatrixPrototype); @@ -1444,11 +1444,11 @@ class DOMMatrix extends DOMMatrixReadOnly { if (value !== 0) { this[_is2D] = false; } - this[_raw][_m23] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_M23] = webidl.converters["unrestricted double"](value); } get m24() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_m24]; + return this[_raw][INDEX_M24]; } set m24(value) { webidl.assertBranded(this, DOMMatrixPrototype); @@ -1456,11 +1456,11 @@ class DOMMatrix extends DOMMatrixReadOnly { if (value !== 0) { this[_is2D] = false; } - this[_raw][_m24] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_M24] = webidl.converters["unrestricted double"](value); } get m31() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_m31]; + return this[_raw][INDEX_M31]; } set m31(value) { webidl.assertBranded(this, DOMMatrixPrototype); @@ -1468,11 +1468,11 @@ class DOMMatrix extends DOMMatrixReadOnly { if (value !== 0) { this[_is2D] = false; } - this[_raw][_m31] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_M31] = webidl.converters["unrestricted double"](value); } get m32() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_m32]; + return this[_raw][INDEX_M32]; } set m32(value) { webidl.assertBranded(this, DOMMatrixPrototype); @@ -1480,11 +1480,11 @@ class DOMMatrix extends DOMMatrixReadOnly { if (value !== 0) { this[_is2D] = false; } - this[_raw][_m32] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_M32] = webidl.converters["unrestricted double"](value); } get m33() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_m33]; + return this[_raw][INDEX_M33]; } set m33(value) { webidl.assertBranded(this, DOMMatrixPrototype); @@ -1492,11 +1492,11 @@ class DOMMatrix extends DOMMatrixReadOnly { if (value !== 1) { this[_is2D] = false; } - this[_raw][_m33] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_M33] = webidl.converters["unrestricted double"](value); } get m34() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_m34]; + return this[_raw][INDEX_M34]; } set m34(value) { webidl.assertBranded(this, DOMMatrixPrototype); @@ -1504,29 +1504,29 @@ class DOMMatrix extends DOMMatrixReadOnly { if (value !== 0) { this[_is2D] = false; } - this[_raw][_m34] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_M34] = webidl.converters["unrestricted double"](value); } get m41() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_m41]; + return this[_raw][INDEX_M41]; } set m41(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][_m41] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_M41] = webidl.converters["unrestricted double"](value); } get m42() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_m42]; + return this[_raw][INDEX_M42]; } set m42(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][_m42] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_M42] = webidl.converters["unrestricted double"](value); } get m43() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_m43]; + return this[_raw][INDEX_M43]; } set m43(value) { webidl.assertBranded(this, DOMMatrixPrototype); @@ -1534,11 +1534,11 @@ class DOMMatrix extends DOMMatrixReadOnly { if (value !== 0) { this[_is2D] = false; } - this[_raw][_m43] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_M43] = webidl.converters["unrestricted double"](value); } get m44() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][_m44]; + return this[_raw][INDEX_M44]; } set m44(value) { webidl.assertBranded(this, DOMMatrixPrototype); @@ -1546,7 +1546,7 @@ class DOMMatrix extends DOMMatrixReadOnly { if (value !== 1) { this[_is2D] = false; } - this[_raw][_m44] = webidl.converters["unrestricted double"](value); + this[_raw][INDEX_M44] = webidl.converters["unrestricted double"](value); } multiplySelf(other = {}) { @@ -1974,22 +1974,22 @@ function initMatrixFromMatrix(target, matrix) { function isIdentityMatrix(matrix) { const raw = matrix[_raw]; return ( - raw[_m11] === 1 && - raw[_m12] === 0 && - raw[_m13] === 0 && - raw[_m14] === 0 && - raw[_m21] === 0 && - raw[_m22] === 1 && - raw[_m23] === 0 && - raw[_m24] === 0 && - raw[_m31] === 0 && - raw[_m32] === 0 && - raw[_m33] === 1 && - raw[_m34] === 0 && - raw[_m41] === 0 && - raw[_m42] === 0 && - raw[_m43] === 0 && - raw[_m44] === 1 + 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 ); } @@ -2021,12 +2021,12 @@ function init(transformListParser, enableWindowFeatures) { if (this[_is2D]) { return `matrix(${ ArrayPrototypeJoin([ - raw[_a], - raw[_b], - raw[_c], - raw[_d], - raw[_e], - raw[_f], + raw[INDEX_A], + raw[INDEX_B], + raw[INDEX_C], + raw[INDEX_D], + raw[INDEX_E], + raw[INDEX_F], ], ", ") })`; } else { From 9ca5e9b5485583572d01b3f91af209b8a675277f Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 26 Feb 2024 00:18:30 +0900 Subject: [PATCH 52/66] 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 3ae738111724fd..b37409ede63d5c 100644 --- a/tests/integration/lsp_tests.rs +++ b/tests/integration/lsp_tests.rs @@ -4870,7 +4870,7 @@ fn lsp_jsr_auto_import_completion() { json!({ "triggerKind": 1 }), ); assert!(!list.is_incomplete); - assert_eq!(list.items.len(), 261); + assert_eq!(list.items.len(), 268); let item = list.items.iter().find(|i| i.label == "add").unwrap(); assert_eq!(&item.label, "add"); assert_eq!( @@ -4950,7 +4950,7 @@ fn lsp_jsr_auto_import_completion_import_map() { json!({ "triggerKind": 1 }), ); assert!(!list.is_incomplete); - assert_eq!(list.items.len(), 261); + assert_eq!(list.items.len(), 268); 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 b891a774b91f2e66f4c9f12dbbc84cfed8bd4d44 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 26 Feb 2024 03:49:40 +0900 Subject: [PATCH 53/66] fix error messages --- ext/geometry/01_geometry.js | 38 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index c4b08d7db10412..972007d1d058ae 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -252,7 +252,7 @@ class DOMPointReadOnly { static fromPoint(other = {}) { other = webidl.converters.DOMPointInit( other, - "Failed to call 'DOMPointReadOnly.fromPoint'", + "Failed to execute 'DOMPointReadOnly.fromPoint'", "Argument 1", ); const point = webidl.createBranded(DOMPointReadOnly); @@ -286,7 +286,7 @@ class DOMPointReadOnly { matrixTransform(matrix = {}) { webidl.assertBranded(this, DOMPointReadOnlyPrototype); const prefix = - "Failed to call 'DOMPointReadOnly.prototype.matrixTransform'"; + "Failed to execute 'matrixTransform' on 'DOMPointReadOnly'"; if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, matrix)) { const _matrix = webidl.converters.DOMMatrixInit( matrix, @@ -342,7 +342,7 @@ class DOMPoint extends DOMPointReadOnly { static fromPoint(other = {}) { other = webidl.converters.DOMPointInit( other, - "Failed to call 'DOMPoint.fromPoint'", + "Failed to execute 'DOMPoint.fromPoint'", "Argument 1", ); const point = webidl.createBranded(DOMPoint); @@ -430,7 +430,7 @@ class DOMRectReadOnly { static fromRect(other = {}) { other = webidl.converters.DOMRectInit( other, - "Failed to call 'DOMRectReadOnly.fromRect'", + "Failed to execute 'DOMRectReadOnly.fromRect'", "Argument 1", ); const rect = webidl.createBranded(DOMRectReadOnly); @@ -526,7 +526,7 @@ class DOMRect extends DOMRectReadOnly { static fromRect(other = {}) { other = webidl.converters.DOMRectInit( other, - "Failed to call 'DOMRect.fromRect'", + "Failed to execute 'DOMRect.fromRect'", "Argument 1", ); const rect = webidl.createBranded(DOMRect); @@ -623,7 +623,7 @@ class DOMQuad { static fromRect(other = {}) { other = webidl.converters.DOMRectInit( other, - "Failed to call 'DOMQuad.fromRect'", + "Failed to execute 'DOMQuad.fromRect'", "Argument 1", ); const { x, y, width, height } = other; @@ -638,7 +638,7 @@ class DOMQuad { static fromQuad(other = {}) { other = webidl.converters.DOMQuadInit( other, - "Failed to call 'DOMQuad.fromQuad'", + "Failed to execute 'DOMQuad.fromQuad'", "Argument 1", ); const quad = webidl.createBranded(DOMQuad); @@ -803,7 +803,7 @@ class DOMMatrixReadOnly { } static fromMatrix(other = {}) { - const prefix = "Failed to call 'DOMMatrixReadOnly.fromMatrix'"; + const prefix = "Failed to execute 'DOMMatrixReadOnly.fromMatrix'"; const matrix = webidl.createBranded(DOMMatrixReadOnly); matrix[_writable] = false; // fast path for DOMMatrix or DOMMatrixReadOnly @@ -818,7 +818,7 @@ class DOMMatrixReadOnly { } static fromFloat32Array(float32) { - const prefix = "Failed to call 'DOMMatrixReadOnly.fromFloat32Array'"; + 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); @@ -828,7 +828,7 @@ class DOMMatrixReadOnly { } static fromFloat64Array(float64) { - const prefix = "Failed to call 'DOMMatrixReadOnly.fromFloat64Array'"; + 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); @@ -1125,7 +1125,7 @@ class DOMMatrixReadOnly { multiply(other = {}) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const prefix = "Failed to call 'DOMMatrixReadOnly.prototype.multiply'"; + const prefix = "Failed to execute 'multiply' on 'DOMMatrixReadOnly'"; if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { const _other = webidl.converters.DOMMatrixInit( other, @@ -1183,7 +1183,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); point = webidl.converters.DOMPointInit( point, - "Failed to call 'DOMMatrixReadOnly.prototype.transformPoint'", + "Failed to execute 'transformPoint' on 'DOMMatrixReadOnly'", "Argument 1", ); const result = webidl.createBranded(DOMPoint); @@ -1286,7 +1286,7 @@ class DOMMatrix extends DOMMatrixReadOnly { [_writable] = true; static fromMatrix(other = {}) { - const prefix = "Failed to call 'DOMMatrix.fromMatrix'"; + const prefix = "Failed to execute 'DOMMatrix.fromMatrix'"; const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; // fast path for DOMMatrix or DOMMatrixReadOnly @@ -1301,7 +1301,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } static fromFloat32Array(float32) { - const prefix = "Failed to call 'DOMMatrix.fromFloat32Array'"; + 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); @@ -1311,7 +1311,7 @@ class DOMMatrix extends DOMMatrixReadOnly { } static fromFloat64Array(float64) { - const prefix = "Failed to call 'DOMMatrix.fromFloat64Array'"; + 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); @@ -1552,7 +1552,7 @@ class DOMMatrix extends DOMMatrixReadOnly { multiplySelf(other = {}) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - const prefix = "Failed to call 'DOMMatrix.prototype.multiplySelf'"; + const prefix = "Failed to execute 'multiplySelf' on 'DOMMatrix'"; if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { const _other = webidl.converters.DOMMatrixInit( other, @@ -1575,7 +1575,7 @@ class DOMMatrix extends DOMMatrixReadOnly { preMultiplySelf(other = {}) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - const prefix = "Failed to call 'DOMMatrix.prototype.premultiplySelf'"; + const prefix = "Failed to execute 'premultiplySelf' on 'DOMMatrix'"; if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { const _other = webidl.converters.DOMMatrixInit( other, @@ -2014,7 +2014,7 @@ function init(transformListParser, enableWindowFeatures) { const raw = this[_raw]; if (!TypedArrayPrototypeEvery(raw, (value) => NumberIsFinite(value))) { throw new DOMException( - "Failed to execute 'DOMMatrixReadOnly.prototype.toString': Cannot be serialized with NaN or Infinity values", + "Failed to execute 'toString' on 'DOMMatrixReadOnly': Cannot be serialized with NaN or Infinity values", "InvalidStateError", ); } @@ -2042,7 +2042,7 @@ function init(transformListParser, enableWindowFeatures) { ObjectDefineProperty(DOMMatrixPrototype, "setMatrixValue", { value: function setMatrixValue(transformList) { webidl.assertBranded(this, DOMMatrixPrototype); - const prefix = "Failed to call 'DOMMatrix.prototype.setMatrixValue'"; + const prefix = "Failed to execute 'setMatrixValue' on 'DOMMatrix'"; webidl.requiredArguments(arguments.length, 1, prefix); transformList = webidl.converters.DOMString( transformList, From d5f341477e8218a3090b089f4379bf2971bb8281 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 26 Feb 2024 04:22:24 +0900 Subject: [PATCH 54/66] fmt --- ext/geometry/01_geometry.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 972007d1d058ae..9a322cf81f17dd 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -285,8 +285,7 @@ class DOMPointReadOnly { matrixTransform(matrix = {}) { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - const prefix = - "Failed to execute 'matrixTransform' on 'DOMPointReadOnly'"; + const prefix = "Failed to execute 'matrixTransform' on 'DOMPointReadOnly'"; if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, matrix)) { const _matrix = webidl.converters.DOMMatrixInit( matrix, From 085ef53acd15f4042a046e929af1827387190af5 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 27 Feb 2024 02:38:08 +0900 Subject: [PATCH 55/66] add JSDoc --- ext/geometry/01_geometry.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 9a322cf81f17dd..6c75ba3266b639 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -237,6 +237,7 @@ const _brand = webidl.brand; class DOMPointReadOnly { [_writable] = false; + /** @type {Float64Array} */ [_raw]; constructor(x = 0, y = 0, z = 0, w = 1) { @@ -414,6 +415,7 @@ const DOMPointPrototype = DOMPoint.prototype; class DOMRectReadOnly { [_writable] = false; + /** @type {Float64Array} */ [_raw]; constructor(x = 0, y = 0, width = 0, height = 0) { @@ -606,9 +608,13 @@ 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 = {}) { @@ -764,7 +770,9 @@ const _is2D = Symbol("[[is2D]]"); class DOMMatrixReadOnly { [_writable] = false; + /** @type {Float64Array} */ [_raw]; + /** @type {boolean} */ [_is2D]; constructor(init = undefined) { @@ -1802,6 +1810,10 @@ class DOMMatrix extends DOMMatrixReadOnly { 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"); From 8f40286773c76c5b6f01a975c5493b2d084909da Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 27 Feb 2024 04:36:31 +0900 Subject: [PATCH 56/66] add parser for single matrix and matrix3d functions --- runtime/js/98_global_scope_window.js | 58 ++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/runtime/js/98_global_scope_window.js b/runtime/js/98_global_scope_window.js index 0af75c3af8d878..8e3dcb17743902 100644 --- a/runtime/js/98_global_scope_window.js +++ b/runtime/js/98_global_scope_window.js @@ -7,9 +7,17 @@ import { op_bootstrap_user_agent, } from "ext:core/ops"; const { + ArrayPrototypeMap, + ArrayPrototypeSome, + Float64Array, + Number, + NumberIsNaN, ObjectDefineProperties, ObjectPrototypeIsPrototypeOf, - Float64Array, + SafeRegExp, + StringPrototypeMatch, + StringPrototypeSplit, + StringPrototypeTrim, SymbolFor, TypeError, } = primordials; @@ -17,12 +25,17 @@ 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 { 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 { @@ -37,9 +50,48 @@ const loadGeometry = createGeometryLoader((transformList, prefix) => { }; } - // TODO(petamoriken): Add CSS parser + // Currently only parsing of a single matrix, matrix3d function is implemented + // TODO(petamoriken): Add CSS parser such as lightningcss + const matrixMatch = StringPrototypeMatch(transformList, MATRIX_PATTERN); + if (matrixMatch !== null) { + const is2D = matrixMatch[1] === undefined; + /** @type {number[]} */ + const seq = ArrayPrototypeMap( + StringPrototypeSplit(matrixMatch[2], ","), + (str) => Number(StringPrototypeTrim(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: true, + }; + } else { + return { + matrix: new Float64Array(seq), + is2D: false, + }; + } + } + throw new TypeError( - `${prefix}: CSS parser is not implemented`, + `${prefix}: CSS parser is not fully implemented`, ); }, true); From 0ab3f03d9f3598678ae8754aa70eead40b1a0646 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 27 Feb 2024 04:37:36 +0900 Subject: [PATCH 57/66] fix WebIDL union type --- ext/geometry/01_geometry.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 6c75ba3266b639..499eb4f4cfe631 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -30,9 +30,10 @@ const { ObjectPrototypeIsPrototypeOf, Symbol, SymbolFor, + SymbolIterator, + TypeError, TypedArrayPrototypeEvery, TypedArrayPrototypeJoin, - TypeError, } = primordials; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; @@ -787,10 +788,9 @@ class DOMMatrixReadOnly { 0, 0, 0, 1, ]); this[_is2D] = true; - } else if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, init)) { - // NOTE: not in the spec, but requested by wpt - initMatrixFromMatrix(this, init); - } else if (webidl.type(init) === "Object") { + } else if ( + webidl.type(init) === "Object" && init[SymbolIterator] !== undefined + ) { init = webidl.converters["sequence"]( init, prefix, From 9b1f7a674d7f520d84dbf367aca2e11da72eae8e Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 27 Feb 2024 05:10:43 +0900 Subject: [PATCH 58/66] tweak: StringNumericLiteral allows whitespaces --- runtime/js/98_global_scope_window.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/runtime/js/98_global_scope_window.js b/runtime/js/98_global_scope_window.js index 8e3dcb17743902..0314871c5e9f24 100644 --- a/runtime/js/98_global_scope_window.js +++ b/runtime/js/98_global_scope_window.js @@ -17,7 +17,6 @@ const { SafeRegExp, StringPrototypeMatch, StringPrototypeSplit, - StringPrototypeTrim, SymbolFor, TypeError, } = primordials; @@ -58,7 +57,7 @@ const loadGeometry = createGeometryLoader((transformList, prefix) => { /** @type {number[]} */ const seq = ArrayPrototypeMap( StringPrototypeSplit(matrixMatch[2], ","), - (str) => Number(StringPrototypeTrim(str)), + (str) => Number(str), ); if ( is2D && seq.length !== 6 || From 51a18cbc8c5d3c609e5fd502f683fa34f578463f Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 27 Feb 2024 05:53:49 +0900 Subject: [PATCH 59/66] tweak --- runtime/js/98_global_scope_window.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/js/98_global_scope_window.js b/runtime/js/98_global_scope_window.js index 0314871c5e9f24..aeedf0aefe4cff 100644 --- a/runtime/js/98_global_scope_window.js +++ b/runtime/js/98_global_scope_window.js @@ -79,12 +79,12 @@ const loadGeometry = createGeometryLoader((transformList, prefix) => { 0, 0, 1, 0, e, f, 0, 1, ]), - is2D: true, + is2D, }; } else { return { matrix: new Float64Array(seq), - is2D: false, + is2D, }; } } From b45014bb4a4fc3f469d0dbca44f7e317738c6231 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 28 Feb 2024 02:05:01 +0900 Subject: [PATCH 60/66] fix Co-authored-by: ud2 --- tests/unit/geometry_test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/geometry_test.ts b/tests/unit/geometry_test.ts index d3fd204d5370fc..e2fec120d4e4f7 100644 --- a/tests/unit/geometry_test.ts +++ b/tests/unit/geometry_test.ts @@ -787,7 +787,7 @@ Deno.test(function matrixPreMultiplySelfWithSelf() { ); }); -Deno.test(function matrixflipX() { +Deno.test(function matrixFlipX() { // deno-fmt-ignore const init = { m11: 1, m21: 2, m31: 3, m41: 4, @@ -813,7 +813,7 @@ Deno.test(function matrixflipX() { ); }); -Deno.test(function matrixflipX() { +Deno.test(function matrixFlipY() { // deno-fmt-ignore const init = { m11: 1, m21: 2, m31: 3, m41: 4, From 51a1914ee6efbd900d68cde84eabb3ccfb61ff1d Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 28 Feb 2024 02:22:41 +0900 Subject: [PATCH 61/66] fix --- ext/geometry/01_geometry.js | 84 ++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 30 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 499eb4f4cfe631..5c64bc028a9956 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -943,13 +943,16 @@ 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[_raw] = new Float64Array(this[_raw]); op_geometry_translate_self( - webidl.converters["unrestricted double"](tx), - webidl.converters["unrestricted double"](ty), - webidl.converters["unrestricted double"](tz), + tx, + ty, + tz, matrix[_raw], ); matrix[_is2D] = this[_is2D] && tz === 0; @@ -965,6 +968,9 @@ 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); @@ -973,16 +979,16 @@ class DOMMatrixReadOnly { matrix[_raw] = new Float64Array(this[_raw]); if (originX === 0 && originY === 0 && originZ === 0) { op_geometry_scale_self( - webidl.converters["unrestricted double"](scaleX), - webidl.converters["unrestricted double"](scaleY), - webidl.converters["unrestricted double"](scaleZ), + scaleX, + scaleY, + scaleZ, matrix[_raw], ); } else { op_geometry_scale_with_origin_self( - webidl.converters["unrestricted double"](scaleX), - webidl.converters["unrestricted double"](scaleY), - webidl.converters["unrestricted double"](scaleZ), + scaleX, + scaleY, + scaleZ, originX, originY, originZ, @@ -995,12 +1001,14 @@ 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[_raw] = new Float64Array(this[_raw]); op_geometry_scale_self( - webidl.converters["unrestricted double"](scaleX), - webidl.converters["unrestricted double"](scaleY), + scaleX, + scaleY, 1, matrix[_raw], ); @@ -1069,12 +1077,14 @@ 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[_raw] = new Float64Array(this[_raw]); op_geometry_rotate_from_vector_self( - webidl.converters["unrestricted double"](x), - webidl.converters["unrestricted double"](y), + x, + y, matrix[_raw], ); matrix[_is2D] = this[_is2D]; @@ -1086,6 +1096,7 @@ class DOMMatrixReadOnly { 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]); @@ -1094,7 +1105,7 @@ class DOMMatrixReadOnly { x, y, z, - webidl.converters["unrestricted double"](angle), + angle, matrix[_raw], ); } @@ -1104,11 +1115,12 @@ class DOMMatrixReadOnly { 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( - webidl.converters["unrestricted double"](sx), + sx, 0, matrix[_raw], ); @@ -1118,12 +1130,13 @@ class DOMMatrixReadOnly { 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, - webidl.converters["unrestricted double"](sy), + sy, matrix[_raw], ); matrix[_is2D] = this[_is2D]; @@ -1605,10 +1618,13 @@ 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); op_geometry_translate_self( - webidl.converters["unrestricted double"](tx), - webidl.converters["unrestricted double"](ty), - webidl.converters["unrestricted double"](tz), + tx, + ty, + tz, this[_raw], ); this[_is2D] &&= tz === 0; @@ -1625,21 +1641,24 @@ 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) { op_geometry_scale_self( - webidl.converters["unrestricted double"](scaleX), - webidl.converters["unrestricted double"](scaleY), - webidl.converters["unrestricted double"](scaleZ), + scaleX, + scaleY, + scaleZ, this[_raw], ); } else { op_geometry_scale_with_origin_self( - webidl.converters["unrestricted double"](scaleX), - webidl.converters["unrestricted double"](scaleY), - webidl.converters["unrestricted double"](scaleZ), + scaleX, + scaleY, + scaleZ, originX, originY, originZ, @@ -1708,9 +1727,11 @@ 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); op_geometry_rotate_from_vector_self( - webidl.converters["unrestricted double"](x), - webidl.converters["unrestricted double"](y), + x, + y, this[_raw], ); return this; @@ -1722,12 +1743,13 @@ class DOMMatrix extends DOMMatrixReadOnly { 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, - webidl.converters["unrestricted double"](angle), + angle, this[_raw], ); } @@ -1738,8 +1760,9 @@ class DOMMatrix extends DOMMatrixReadOnly { skewXSelf(sx = 0) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); + sx = webidl.converters["unrestricted double"](sx); op_geometry_skew_self( - webidl.converters["unrestricted double"](sx), + sx, 0, this[_raw], ); @@ -1749,9 +1772,10 @@ class DOMMatrix extends DOMMatrixReadOnly { skewYSelf(sy = 0) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); + sy = webidl.converters["unrestricted double"](sy); op_geometry_skew_self( 0, - webidl.converters["unrestricted double"](sy), + sy, this[_raw], ); return this; From 584af3ca84fd192836cd3648288d8e0194b7c0b4 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 20 Mar 2024 12:15:03 +0900 Subject: [PATCH 62/66] update Cargo.lock --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3ba472f7c0862c..6f17130fda5c97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4087,9 +4087,9 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.32.3" +version = "0.32.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307ed9b18cc2423f29e83f84fd23a8e73628727990181f18641a8b5dc2ab1caa" +checksum = "4541eb06dce09c0241ebbaab7102f0a01a0c8994afed2e5d0d66775016e25ac2" dependencies = [ "approx", "matrixmultiply", @@ -4262,9 +4262,9 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" dependencies = [ "num-traits", ] @@ -7507,9 +7507,9 @@ dependencies = [ [[package]] name = "wide" -version = "0.7.14" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b31891d644eba1789fb6715f27fbc322e4bdf2ecdc412ede1993246159271613" +checksum = "89beec544f246e679fc25490e3f8e08003bc4bf612068f325120dad4cea02c1c" dependencies = [ "bytemuck", "safe_arch", diff --git a/Cargo.toml b/Cargo.toml index 00c07020726320..88baaf692c9216 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -185,7 +185,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 -nalgebra = { version = "0.32.3", default-features = false, features = ["std"] } +nalgebra = { version = "0.32.4", default-features = false, features = ["std"] } # webgpu raw-window-handle = "0.5.0" From c3265c877fa60f351e3695f42239b1faaf8c9b5b Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Thu, 28 Mar 2024 13:49:19 +0900 Subject: [PATCH 63/66] update comments --- ext/geometry/01_geometry.js | 3 +++ runtime/js/98_global_scope_window.js | 5 +++-- tests/unit/geometry_test.ts | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 5c64bc028a9956..8b5957ee4e2610 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -233,6 +233,9 @@ webidl.converters.DOMMatrixInit = webidl.createDictionaryConverter( ); 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; diff --git a/runtime/js/98_global_scope_window.js b/runtime/js/98_global_scope_window.js index aeedf0aefe4cff..c8ca3cb8c167ee 100644 --- a/runtime/js/98_global_scope_window.js +++ b/runtime/js/98_global_scope_window.js @@ -49,8 +49,9 @@ const loadGeometry = createGeometryLoader((transformList, prefix) => { }; } - // Currently only parsing of a single matrix, matrix3d function is implemented - // TODO(petamoriken): Add CSS parser such as lightningcss + // 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; diff --git a/tests/unit/geometry_test.ts b/tests/unit/geometry_test.ts index e2fec120d4e4f7..b4910c3e6f5ec6 100644 --- a/tests/unit/geometry_test.ts +++ b/tests/unit/geometry_test.ts @@ -397,7 +397,7 @@ Deno.test(function matrixRotateFromVector() { 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.707106781186547 , m33: 11, m43: 12, + 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); From e38c0ea4b7ba1f91e8651f192eff42f416870f39 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 30 Apr 2024 00:53:22 +0900 Subject: [PATCH 64/66] update jsdoc_checker.js --- ext/geometry/lib.deno_geometry.d.ts | 24 ++++++++++++------------ tools/jsdoc_checker.js | 1 + 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/ext/geometry/lib.deno_geometry.d.ts b/ext/geometry/lib.deno_geometry.d.ts index 16c94d46f11482..44b06d763ebf50 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 */ -interface DOMMatrix2DInit { +declare interface DOMMatrix2DInit { a?: number; b?: number; c?: number; @@ -22,7 +22,7 @@ interface DOMMatrix2DInit { } /** @category Geometry Interfaces Module API */ -interface DOMMatrixInit extends DOMMatrix2DInit { +declare interface DOMMatrixInit extends DOMMatrix2DInit { is2D?: boolean; m13?: number; m14?: number; @@ -49,7 +49,7 @@ interface DOMMatrixInit extends DOMMatrix2DInit { * * @category Geometry Interfaces Module API */ -interface DOMMatrix extends DOMMatrixReadOnly { +declare interface DOMMatrix extends DOMMatrixReadOnly { a: number; b: number; c: number; @@ -227,7 +227,7 @@ declare var DOMMatrix: { * * @category Geometry Interfaces Module API */ -interface DOMMatrixReadOnly { +declare interface DOMMatrixReadOnly { readonly a: number; readonly b: number; readonly c: number; @@ -418,7 +418,7 @@ declare var DOMMatrixReadOnly: { }; /** @category Geometry Interfaces Module API */ -interface DOMPointInit { +declare interface DOMPointInit { w?: number; x?: number; y?: number; @@ -431,7 +431,7 @@ interface DOMPointInit { * * @category Geometry Interfaces Module API */ -interface DOMPoint extends DOMPointReadOnly { +declare interface DOMPoint extends DOMPointReadOnly { w: number; x: number; y: number; @@ -456,7 +456,7 @@ declare var DOMPoint: { * * @category Geometry Interfaces Module API */ -interface DOMPointReadOnly { +declare interface DOMPointReadOnly { readonly w: number; readonly x: number; readonly y: number; @@ -483,7 +483,7 @@ declare var DOMPointReadOnly: { }; /** @category Geometry Interfaces Module API */ -interface DOMQuadInit { +declare interface DOMQuadInit { p1?: DOMPointInit; p2?: DOMPointInit; p3?: DOMPointInit; @@ -496,7 +496,7 @@ interface DOMQuadInit { * * @category Geometry Interfaces Module API */ -interface DOMQuad { +declare interface DOMQuad { readonly p1: DOMPoint; readonly p2: DOMPoint; readonly p3: DOMPoint; @@ -529,7 +529,7 @@ declare var DOMQuad: { }; /** @category Geometry Interfaces Module API */ -interface DOMRectInit { +declare interface DOMRectInit { height?: number; width?: number; x?: number; @@ -541,7 +541,7 @@ interface DOMRectInit { * * @category Geometry Interfaces Module API */ -interface DOMRect extends DOMRectReadOnly { +declare interface DOMRect extends DOMRectReadOnly { height: number; width: number; x: number; @@ -564,7 +564,7 @@ declare var DOMRect: { * * @category Geometry Interfaces Module API */ -interface DOMRectReadOnly { +declare interface DOMRectReadOnly { readonly bottom: number; readonly height: number; readonly left: number; diff --git a/tools/jsdoc_checker.js b/tools/jsdoc_checker.js index 733790c4e30666..541fd4aa3c159e 100644 --- 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 3172c383b2783a0932fd001adbefe18f01533e76 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 30 Apr 2024 12:30:26 +0900 Subject: [PATCH 65/66] tweak --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 27779536e29737..2de13f435b408c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4149,9 +4149,9 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.32.4" +version = "0.32.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4541eb06dce09c0241ebbaab7102f0a01a0c8994afed2e5d0d66775016e25ac2" +checksum = "3ea4908d4f23254adda3daa60ffef0f1ac7b8c3e9a864cf3cc154b251908a2ef" dependencies = [ "approx", "matrixmultiply", @@ -7586,9 +7586,9 @@ dependencies = [ [[package]] name = "wide" -version = "0.7.15" +version = "0.7.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89beec544f246e679fc25490e3f8e08003bc4bf612068f325120dad4cea02c1c" +checksum = "81a1851a719f11d1d2fea40e15c72f6c00de8c142d7ac47c1441cc7e4d0d5bc6" dependencies = [ "bytemuck", "safe_arch", From dc891f84599d636418ad936be80d5b47d1383d12 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 27 May 2024 06:00:34 +0900 Subject: [PATCH 66/66] tweak --- tests/wpt/runner/expectation.json | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/wpt/runner/expectation.json b/tests/wpt/runner/expectation.json index bc8a874fa36de9..afb177dce89e1f 100644 --- a/tests/wpt/runner/expectation.json +++ b/tests/wpt/runner/expectation.json @@ -12903,7 +12903,6 @@ "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,