From 9b5ae077e242f5fe907670525b918f2d49177532 Mon Sep 17 00:00:00 2001 From: FunctionPoint Date: Sun, 4 Aug 2024 23:14:51 +0200 Subject: [PATCH] Browser: Added Canvas support #15 partial Implemented unit tests where possible. Drawing methods will be tested visually later. Implemented classes for DOM point and matrix operations. Moved component classes to separate folder. Fixed debugging source-mapped ST files with Firefox. (Is still a todo for other browser projects) Updated NPM packages. --- .gitignore | 2 +- Browser/.vscode/launch.json | 35 ++- Browser/.vscode/tasks.json | 4 +- Browser/build.sh | 2 +- Browser/src/App.ts | 2 +- .../src/{ => Components}/AnchorComponent.st | 0 .../src/{ => Components}/CanvasComponent.st | 0 .../{ => Components}/ClipboardComponent.st | 0 Browser/src/{ => Components}/CssComponent.st | 0 .../src/{ => Components}/DialogsComponent.st | 0 .../src/{ => Components}/EmbedComponent.st | 0 .../src/{ => Components}/FieldSetComponent.st | 0 Browser/src/{ => Components}/FormComponent.st | 0 .../src/{ => Components}/ScriptComponent.st | 0 .../{ => Components}/SelectionComponent.st | 0 .../Test/TestAnchorComponent.st | 0 .../{ => Components}/Test/TestCssComponent.st | 0 .../Test/TestEmbedComponent.st | 0 .../Test/TestFieldSetComponent.st | 0 .../Test/TestFormComponent.st | 0 .../Test/TestScriptComponent.st | 0 .../Test/TestSelectionComponent.st | 0 .../Test/TestTextAreaComponent.st | 0 .../src/{ => Components}/TextAreaComponent.st | 0 .../CheckboxInputComponent.st | 0 .../DateInputComponent.st | 0 .../FileInputComponent.st | 0 .../ImageInputComponent.st | 0 .../InputComponent.st | 0 .../ListInputComponent.st | 0 .../RadioInputComponent.st | 0 .../Test/TestCheckboxInputComponent.st | 0 .../Test/TestDateInputComponent.st | 0 .../Test/TestFileInputComponent.st | 0 .../Test/TestImageInputComponent.st | 0 .../Test/TestInputComponent.st | 0 .../Test/TestListInputCompent.st | 0 .../Test/TestRadioInputComponent.st | 0 Compiler/package-lock.json | 31 +-- Compiler/package.json | 2 +- Examples/Shop/Server/package-lock.json | 89 +++++-- Examples/Shop/Server/package.json | 4 +- Node/package-lock.json | 50 +++- Node/package.json | 4 +- Smalltalk/Browser/Canvas/CanvasPattern.st | 2 +- Smalltalk/Browser/Canvas/ContextAttributes.st | 3 +- Smalltalk/Browser/Canvas/DomMatrix.st | 237 +++++++++++++++++- Smalltalk/Browser/Canvas/DomMatrixReadOnly.st | 146 ----------- Smalltalk/Browser/Canvas/DomPoint.st | 35 ++- Smalltalk/Browser/Canvas/DomPointReadOnly.st | 39 --- Smalltalk/Browser/Canvas/HtmlCanvasElement.st | 3 + Smalltalk/Browser/Canvas/ImageData.st | 12 +- Smalltalk/Browser/Canvas/OffscreenCanvas.st | 3 +- .../Test/TestCanvasRenderingContext2d.st | 16 +- .../Canvas/Test/TestContextAttributes.st | 13 + .../Browser/Canvas/Test/TestDomMatrix.st | 118 +++++++++ .../Canvas/Test/TestDomMatrixReadOnly.st | 71 ------ Smalltalk/Browser/Canvas/Test/TestDomPoint.st | 33 ++- .../Canvas/Test/TestDomPointReadOnly.st | 32 --- .../Canvas/Test/TestHtmlCanvasElement.st | 2 + .../Browser/Canvas/Test/TestImageData.st | 21 ++ .../Browser/Canvas/Test/TestTextMetrics.st | 22 ++ Smalltalk/Browser/Canvas/TextMetrics.st | 41 ++- 63 files changed, 695 insertions(+), 379 deletions(-) rename Browser/src/{ => Components}/AnchorComponent.st (100%) rename Browser/src/{ => Components}/CanvasComponent.st (100%) rename Browser/src/{ => Components}/ClipboardComponent.st (100%) rename Browser/src/{ => Components}/CssComponent.st (100%) rename Browser/src/{ => Components}/DialogsComponent.st (100%) rename Browser/src/{ => Components}/EmbedComponent.st (100%) rename Browser/src/{ => Components}/FieldSetComponent.st (100%) rename Browser/src/{ => Components}/FormComponent.st (100%) rename Browser/src/{ => Components}/ScriptComponent.st (100%) rename Browser/src/{ => Components}/SelectionComponent.st (100%) rename Browser/src/{ => Components}/Test/TestAnchorComponent.st (100%) rename Browser/src/{ => Components}/Test/TestCssComponent.st (100%) rename Browser/src/{ => Components}/Test/TestEmbedComponent.st (100%) rename Browser/src/{ => Components}/Test/TestFieldSetComponent.st (100%) rename Browser/src/{ => Components}/Test/TestFormComponent.st (100%) rename Browser/src/{ => Components}/Test/TestScriptComponent.st (100%) rename Browser/src/{ => Components}/Test/TestSelectionComponent.st (100%) rename Browser/src/{ => Components}/Test/TestTextAreaComponent.st (100%) rename Browser/src/{ => Components}/TextAreaComponent.st (100%) rename Browser/src/{Input => InputComponents}/CheckboxInputComponent.st (100%) rename Browser/src/{Input => InputComponents}/DateInputComponent.st (100%) rename Browser/src/{Input => InputComponents}/FileInputComponent.st (100%) rename Browser/src/{Input => InputComponents}/ImageInputComponent.st (100%) rename Browser/src/{Input => InputComponents}/InputComponent.st (100%) rename Browser/src/{Input => InputComponents}/ListInputComponent.st (100%) rename Browser/src/{Input => InputComponents}/RadioInputComponent.st (100%) rename Browser/src/{Input => InputComponents}/Test/TestCheckboxInputComponent.st (100%) rename Browser/src/{Input => InputComponents}/Test/TestDateInputComponent.st (100%) rename Browser/src/{Input => InputComponents}/Test/TestFileInputComponent.st (100%) rename Browser/src/{Input => InputComponents}/Test/TestImageInputComponent.st (100%) rename Browser/src/{Input => InputComponents}/Test/TestInputComponent.st (100%) rename Browser/src/{Input => InputComponents}/Test/TestListInputCompent.st (100%) rename Browser/src/{Input => InputComponents}/Test/TestRadioInputComponent.st (100%) delete mode 100644 Smalltalk/Browser/Canvas/DomMatrixReadOnly.st delete mode 100644 Smalltalk/Browser/Canvas/DomPointReadOnly.st create mode 100644 Smalltalk/Browser/Canvas/Test/TestContextAttributes.st create mode 100644 Smalltalk/Browser/Canvas/Test/TestDomMatrix.st delete mode 100644 Smalltalk/Browser/Canvas/Test/TestDomMatrixReadOnly.st delete mode 100644 Smalltalk/Browser/Canvas/Test/TestDomPointReadOnly.st create mode 100644 Smalltalk/Browser/Canvas/Test/TestImageData.st create mode 100644 Smalltalk/Browser/Canvas/Test/TestTextMetrics.st diff --git a/.gitignore b/.gitignore index da25e61..a58342e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,7 @@ **/node_modules **/out /Browser/web/App.js -/Browser/web/Smalltalk +/Browser/web/Script /Examples/Balls/web/App.js /Examples/Balls/web/Smalltalk /Examples/Benchmark/web/App.js diff --git a/Browser/.vscode/launch.json b/Browser/.vscode/launch.json index 1c056d4..d3991ae 100644 --- a/Browser/.vscode/launch.json +++ b/Browser/.vscode/launch.json @@ -43,16 +43,17 @@ "reAttach": true, "url": "http://localhost:3000", "webRoot": "${workspaceFolder}/web", - "preLaunchTask": "Compile Smalltalk" - // In FireFox, enable this to let the debugger find mappped *.st files. - // But then the *.js files will not open correctly anymore. - // A workaround is to copy (merge) the entire Smalltalk source folder to web/Smalltalk - // "pathMappings": [ - // { - // "url": "http://localhost:3000/Smalltalk", - // "path": "${workspaceFolder}../Smalltalk" - // } - // ] + "preLaunchTask": "Compile Smalltalk", + "pathMappings": [ + { + "url": "http://localhost:3000/src", + "path": "${workspaceFolder}/src" + }, + { + "url": "http://localhost:3000/Smalltalk", + "path": "${workspaceFolder}/../Smalltalk" + } + ] }, { "name": "Launch Firefox test", @@ -61,7 +62,17 @@ "reAttach": true, "url": "http://localhost:3000/?test", "webRoot": "${workspaceFolder}/web", - "preLaunchTask": "Compile Smalltalk" + "preLaunchTask": "Compile Smalltalk", + "pathMappings": [ + { + "url": "http://localhost:3000/src", + "path": "${workspaceFolder}/src" + }, + { + "url": "http://localhost:3000/Smalltalk", + "path": "${workspaceFolder}/../Smalltalk" + } + ] } ] -} +} \ No newline at end of file diff --git a/Browser/.vscode/tasks.json b/Browser/.vscode/tasks.json index 4cecc19..54fc685 100644 --- a/Browser/.vscode/tasks.json +++ b/Browser/.vscode/tasks.json @@ -19,8 +19,8 @@ "label": "Compile Smalltalk", "type": "shell", "command": "node", - "args": [ "../Compiler/out/App.js", "../Smalltalk/Core", "../Smalltalk/Browser", "src", "web/Smalltalk" ], - // "args": [ "../Compiler/out/App.js", "-s", "../Smalltalk/Core", "../Smalltalk/Browser", "src", "web/Smalltalk" ], + "args": [ "../Compiler/out/App.js", "../Smalltalk/Core", "../Smalltalk/Browser", "src", "web/Script" ], + // "args": [ "../Compiler/out/App.js", "-s", "../Smalltalk/Core", "../Smalltalk/Browser", "src", "web/Script" ], "options": { "cwd": "${workspaceFolder}" }, diff --git a/Browser/build.sh b/Browser/build.sh index e4ba85a..c184aa2 100755 --- a/Browser/build.sh +++ b/Browser/build.sh @@ -15,7 +15,7 @@ tsc # Compile Smalltalk -node ../Compiler/out/App.js ../Smalltalk/Core ../Smalltalk/Browser src web/Smalltalk +node ../Compiler/out/App.js ../Smalltalk/Core ../Smalltalk/Browser src web/Script # Check for and run .env file for locations of enabled browsers to test. diff --git a/Browser/src/App.ts b/Browser/src/App.ts index 057dcd0..016db0a 100644 --- a/Browser/src/App.ts +++ b/Browser/src/App.ts @@ -1,5 +1,5 @@ // Invoke the start method on a new BrowserApp ST object. -let moduleName: string = "./Smalltalk/BrowserApp.js"; +let moduleName: string = "./Script/BrowserApp.js"; import( moduleName ) .then( module => { module.stMyBrowserApp$class.$new().$start(); } ); diff --git a/Browser/src/AnchorComponent.st b/Browser/src/Components/AnchorComponent.st similarity index 100% rename from Browser/src/AnchorComponent.st rename to Browser/src/Components/AnchorComponent.st diff --git a/Browser/src/CanvasComponent.st b/Browser/src/Components/CanvasComponent.st similarity index 100% rename from Browser/src/CanvasComponent.st rename to Browser/src/Components/CanvasComponent.st diff --git a/Browser/src/ClipboardComponent.st b/Browser/src/Components/ClipboardComponent.st similarity index 100% rename from Browser/src/ClipboardComponent.st rename to Browser/src/Components/ClipboardComponent.st diff --git a/Browser/src/CssComponent.st b/Browser/src/Components/CssComponent.st similarity index 100% rename from Browser/src/CssComponent.st rename to Browser/src/Components/CssComponent.st diff --git a/Browser/src/DialogsComponent.st b/Browser/src/Components/DialogsComponent.st similarity index 100% rename from Browser/src/DialogsComponent.st rename to Browser/src/Components/DialogsComponent.st diff --git a/Browser/src/EmbedComponent.st b/Browser/src/Components/EmbedComponent.st similarity index 100% rename from Browser/src/EmbedComponent.st rename to Browser/src/Components/EmbedComponent.st diff --git a/Browser/src/FieldSetComponent.st b/Browser/src/Components/FieldSetComponent.st similarity index 100% rename from Browser/src/FieldSetComponent.st rename to Browser/src/Components/FieldSetComponent.st diff --git a/Browser/src/FormComponent.st b/Browser/src/Components/FormComponent.st similarity index 100% rename from Browser/src/FormComponent.st rename to Browser/src/Components/FormComponent.st diff --git a/Browser/src/ScriptComponent.st b/Browser/src/Components/ScriptComponent.st similarity index 100% rename from Browser/src/ScriptComponent.st rename to Browser/src/Components/ScriptComponent.st diff --git a/Browser/src/SelectionComponent.st b/Browser/src/Components/SelectionComponent.st similarity index 100% rename from Browser/src/SelectionComponent.st rename to Browser/src/Components/SelectionComponent.st diff --git a/Browser/src/Test/TestAnchorComponent.st b/Browser/src/Components/Test/TestAnchorComponent.st similarity index 100% rename from Browser/src/Test/TestAnchorComponent.st rename to Browser/src/Components/Test/TestAnchorComponent.st diff --git a/Browser/src/Test/TestCssComponent.st b/Browser/src/Components/Test/TestCssComponent.st similarity index 100% rename from Browser/src/Test/TestCssComponent.st rename to Browser/src/Components/Test/TestCssComponent.st diff --git a/Browser/src/Test/TestEmbedComponent.st b/Browser/src/Components/Test/TestEmbedComponent.st similarity index 100% rename from Browser/src/Test/TestEmbedComponent.st rename to Browser/src/Components/Test/TestEmbedComponent.st diff --git a/Browser/src/Test/TestFieldSetComponent.st b/Browser/src/Components/Test/TestFieldSetComponent.st similarity index 100% rename from Browser/src/Test/TestFieldSetComponent.st rename to Browser/src/Components/Test/TestFieldSetComponent.st diff --git a/Browser/src/Test/TestFormComponent.st b/Browser/src/Components/Test/TestFormComponent.st similarity index 100% rename from Browser/src/Test/TestFormComponent.st rename to Browser/src/Components/Test/TestFormComponent.st diff --git a/Browser/src/Test/TestScriptComponent.st b/Browser/src/Components/Test/TestScriptComponent.st similarity index 100% rename from Browser/src/Test/TestScriptComponent.st rename to Browser/src/Components/Test/TestScriptComponent.st diff --git a/Browser/src/Test/TestSelectionComponent.st b/Browser/src/Components/Test/TestSelectionComponent.st similarity index 100% rename from Browser/src/Test/TestSelectionComponent.st rename to Browser/src/Components/Test/TestSelectionComponent.st diff --git a/Browser/src/Test/TestTextAreaComponent.st b/Browser/src/Components/Test/TestTextAreaComponent.st similarity index 100% rename from Browser/src/Test/TestTextAreaComponent.st rename to Browser/src/Components/Test/TestTextAreaComponent.st diff --git a/Browser/src/TextAreaComponent.st b/Browser/src/Components/TextAreaComponent.st similarity index 100% rename from Browser/src/TextAreaComponent.st rename to Browser/src/Components/TextAreaComponent.st diff --git a/Browser/src/Input/CheckboxInputComponent.st b/Browser/src/InputComponents/CheckboxInputComponent.st similarity index 100% rename from Browser/src/Input/CheckboxInputComponent.st rename to Browser/src/InputComponents/CheckboxInputComponent.st diff --git a/Browser/src/Input/DateInputComponent.st b/Browser/src/InputComponents/DateInputComponent.st similarity index 100% rename from Browser/src/Input/DateInputComponent.st rename to Browser/src/InputComponents/DateInputComponent.st diff --git a/Browser/src/Input/FileInputComponent.st b/Browser/src/InputComponents/FileInputComponent.st similarity index 100% rename from Browser/src/Input/FileInputComponent.st rename to Browser/src/InputComponents/FileInputComponent.st diff --git a/Browser/src/Input/ImageInputComponent.st b/Browser/src/InputComponents/ImageInputComponent.st similarity index 100% rename from Browser/src/Input/ImageInputComponent.st rename to Browser/src/InputComponents/ImageInputComponent.st diff --git a/Browser/src/Input/InputComponent.st b/Browser/src/InputComponents/InputComponent.st similarity index 100% rename from Browser/src/Input/InputComponent.st rename to Browser/src/InputComponents/InputComponent.st diff --git a/Browser/src/Input/ListInputComponent.st b/Browser/src/InputComponents/ListInputComponent.st similarity index 100% rename from Browser/src/Input/ListInputComponent.st rename to Browser/src/InputComponents/ListInputComponent.st diff --git a/Browser/src/Input/RadioInputComponent.st b/Browser/src/InputComponents/RadioInputComponent.st similarity index 100% rename from Browser/src/Input/RadioInputComponent.st rename to Browser/src/InputComponents/RadioInputComponent.st diff --git a/Browser/src/Input/Test/TestCheckboxInputComponent.st b/Browser/src/InputComponents/Test/TestCheckboxInputComponent.st similarity index 100% rename from Browser/src/Input/Test/TestCheckboxInputComponent.st rename to Browser/src/InputComponents/Test/TestCheckboxInputComponent.st diff --git a/Browser/src/Input/Test/TestDateInputComponent.st b/Browser/src/InputComponents/Test/TestDateInputComponent.st similarity index 100% rename from Browser/src/Input/Test/TestDateInputComponent.st rename to Browser/src/InputComponents/Test/TestDateInputComponent.st diff --git a/Browser/src/Input/Test/TestFileInputComponent.st b/Browser/src/InputComponents/Test/TestFileInputComponent.st similarity index 100% rename from Browser/src/Input/Test/TestFileInputComponent.st rename to Browser/src/InputComponents/Test/TestFileInputComponent.st diff --git a/Browser/src/Input/Test/TestImageInputComponent.st b/Browser/src/InputComponents/Test/TestImageInputComponent.st similarity index 100% rename from Browser/src/Input/Test/TestImageInputComponent.st rename to Browser/src/InputComponents/Test/TestImageInputComponent.st diff --git a/Browser/src/Input/Test/TestInputComponent.st b/Browser/src/InputComponents/Test/TestInputComponent.st similarity index 100% rename from Browser/src/Input/Test/TestInputComponent.st rename to Browser/src/InputComponents/Test/TestInputComponent.st diff --git a/Browser/src/Input/Test/TestListInputCompent.st b/Browser/src/InputComponents/Test/TestListInputCompent.st similarity index 100% rename from Browser/src/Input/Test/TestListInputCompent.st rename to Browser/src/InputComponents/Test/TestListInputCompent.st diff --git a/Browser/src/Input/Test/TestRadioInputComponent.st b/Browser/src/InputComponents/Test/TestRadioInputComponent.st similarity index 100% rename from Browser/src/Input/Test/TestRadioInputComponent.st rename to Browser/src/InputComponents/Test/TestRadioInputComponent.st diff --git a/Compiler/package-lock.json b/Compiler/package-lock.json index e4f6465..a550004 100644 --- a/Compiler/package-lock.json +++ b/Compiler/package-lock.json @@ -5,17 +5,17 @@ "packages": { "": { "dependencies": { - "@types/node": "^20.14.10", + "@types/node": "^22.1.0", "source-map": "^0.7.4" } }, "node_modules/@types/node": { - "version": "20.14.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", - "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", + "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.13.0" } }, "node_modules/source-map": { @@ -27,18 +27,19 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", + "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==", + "license": "MIT" } }, "dependencies": { "@types/node": { - "version": "20.14.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", - "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", + "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", "requires": { - "undici-types": "~5.26.4" + "undici-types": "~6.13.0" } }, "source-map": { @@ -47,9 +48,9 @@ "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" }, "undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", + "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==" } } } diff --git a/Compiler/package.json b/Compiler/package.json index fa9a1de..966b3f2 100644 --- a/Compiler/package.json +++ b/Compiler/package.json @@ -1,7 +1,7 @@ { "type": "module", "dependencies": { - "@types/node": "^20.14.10", + "@types/node": "^22.1.0", "source-map": "^0.7.4" } } diff --git a/Examples/Shop/Server/package-lock.json b/Examples/Shop/Server/package-lock.json index 17b7f73..83dfb59 100644 --- a/Examples/Shop/Server/package-lock.json +++ b/Examples/Shop/Server/package-lock.json @@ -5,12 +5,12 @@ "packages": { "": { "dependencies": { - "@types/node": "^20.14.10", + "@types/node": "^22.1.0", "express": "^4.19.2", "express-session": "^1.18.0", "http-terminator": "^3.2.0", "mariadb": "^3.3.1", - "mysql2": "^3.10.2", + "mysql2": "^3.11.0", "node-fetch": "^3.3.2", "pg": "^8.12.0" } @@ -21,12 +21,12 @@ "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" }, "node_modules/@types/node": { - "version": "20.14.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", - "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", + "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.13.0" } }, "node_modules/accepts": { @@ -61,6 +61,15 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "node_modules/aws-ssl-profiles": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.1.tgz", + "integrity": "sha512-+H+kuK34PfMaI9PNU/NSjBKL5hh/KDM9J72kwYeYEm0A8B1AC4fuCy3qsjnA7lxklgyXsB68yn8Z2xoZEjgwCQ==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", @@ -643,6 +652,15 @@ "node": ">= 14" } }, + "node_modules/mariadb/node_modules/@types/node": { + "version": "20.14.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", + "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/mariadb/node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -662,6 +680,12 @@ "node": "14 || >=16.14" } }, + "node_modules/mariadb/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "license": "MIT" + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -719,11 +743,12 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/mysql2": { - "version": "3.10.2", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.10.2.tgz", - "integrity": "sha512-KCXPEvAkO0RcHPr362O5N8tFY2fXvbjfkPvRY/wGumh4EOemo9Hm5FjQZqv/pCmrnuxGu5OxnSENG0gTXqKMgQ==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.11.0.tgz", + "integrity": "sha512-J9phbsXGvTOcRVPR95YedzVSxJecpW5A5+cQ57rhHIFXteTP10HCs+VBjS7DHIKfEaI1zQ5tlVrquCd64A6YvA==", "license": "MIT", "dependencies": { + "aws-ssl-profiles": "^1.1.1", "denque": "^2.1.0", "generate-function": "^2.3.1", "iconv-lite": "^0.6.3", @@ -1287,9 +1312,10 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", + "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==", + "license": "MIT" }, "node_modules/unpipe": { "version": "1.0.0", @@ -1347,11 +1373,11 @@ "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" }, "@types/node": { - "version": "20.14.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", - "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", + "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", "requires": { - "undici-types": "~5.26.4" + "undici-types": "~6.13.0" } }, "accepts": { @@ -1379,6 +1405,11 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "aws-ssl-profiles": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.1.tgz", + "integrity": "sha512-+H+kuK34PfMaI9PNU/NSjBKL5hh/KDM9J72kwYeYEm0A8B1AC4fuCy3qsjnA7lxklgyXsB68yn8Z2xoZEjgwCQ==" + }, "body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", @@ -1803,6 +1834,14 @@ "lru-cache": "^10.2.0" }, "dependencies": { + "@types/node": { + "version": "20.14.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", + "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", + "requires": { + "undici-types": "~5.26.4" + } + }, "iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -1815,6 +1854,11 @@ "version": "10.2.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==" + }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" } } }, @@ -1857,10 +1901,11 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "mysql2": { - "version": "3.10.2", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.10.2.tgz", - "integrity": "sha512-KCXPEvAkO0RcHPr362O5N8tFY2fXvbjfkPvRY/wGumh4EOemo9Hm5FjQZqv/pCmrnuxGu5OxnSENG0gTXqKMgQ==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.11.0.tgz", + "integrity": "sha512-J9phbsXGvTOcRVPR95YedzVSxJecpW5A5+cQ57rhHIFXteTP10HCs+VBjS7DHIKfEaI1zQ5tlVrquCd64A6YvA==", "requires": { + "aws-ssl-profiles": "^1.1.1", "denque": "^2.1.0", "generate-function": "^2.3.1", "iconv-lite": "^0.6.3", @@ -2254,9 +2299,9 @@ } }, "undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", + "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==" }, "unpipe": { "version": "1.0.0", diff --git a/Examples/Shop/Server/package.json b/Examples/Shop/Server/package.json index 38d8d97..3e34a67 100644 --- a/Examples/Shop/Server/package.json +++ b/Examples/Shop/Server/package.json @@ -1,12 +1,12 @@ { "type": "module", "dependencies": { - "@types/node": "^20.14.10", + "@types/node": "^22.1.0", "express": "^4.19.2", "express-session": "^1.18.0", "http-terminator": "^3.2.0", "mariadb": "^3.3.1", - "mysql2": "^3.10.2", + "mysql2": "^3.11.0", "node-fetch": "^3.3.2", "pg": "^8.12.0" } diff --git a/Node/package-lock.json b/Node/package-lock.json index 1513968..ba94c51 100644 --- a/Node/package-lock.json +++ b/Node/package-lock.json @@ -5,12 +5,12 @@ "packages": { "": { "dependencies": { - "@types/node": "^20.14.10", + "@types/node": "^22.1.0", "express": "^4.19.2", "express-session": "^1.18.0", "http-terminator": "^3.2.0", "mariadb": "^3.3.1", - "mysql2": "^3.10.2", + "mysql2": "^3.11.0", "node-fetch": "^3.3.2", "pg": "^8.12.0" } @@ -21,12 +21,12 @@ "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" }, "node_modules/@types/node": { - "version": "20.14.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", - "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", + "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.13.0" } }, "node_modules/accepts": { @@ -46,6 +46,15 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "node_modules/aws-ssl-profiles": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.1.tgz", + "integrity": "sha512-+H+kuK34PfMaI9PNU/NSjBKL5hh/KDM9J72kwYeYEm0A8B1AC4fuCy3qsjnA7lxklgyXsB68yn8Z2xoZEjgwCQ==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", @@ -562,6 +571,15 @@ "node": ">= 14" } }, + "node_modules/mariadb/node_modules/@types/node": { + "version": "20.14.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", + "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/mariadb/node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -573,6 +591,12 @@ "node": ">=0.10.0" } }, + "node_modules/mariadb/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "license": "MIT" + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -630,11 +654,12 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/mysql2": { - "version": "3.10.2", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.10.2.tgz", - "integrity": "sha512-KCXPEvAkO0RcHPr362O5N8tFY2fXvbjfkPvRY/wGumh4EOemo9Hm5FjQZqv/pCmrnuxGu5OxnSENG0gTXqKMgQ==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.11.0.tgz", + "integrity": "sha512-J9phbsXGvTOcRVPR95YedzVSxJecpW5A5+cQ57rhHIFXteTP10HCs+VBjS7DHIKfEaI1zQ5tlVrquCd64A6YvA==", "license": "MIT", "dependencies": { + "aws-ssl-profiles": "^1.1.1", "denque": "^2.1.0", "generate-function": "^2.3.1", "iconv-lite": "^0.6.3", @@ -1177,9 +1202,10 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", + "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==", + "license": "MIT" }, "node_modules/unpipe": { "version": "1.0.0", diff --git a/Node/package.json b/Node/package.json index 38d8d97..3e34a67 100644 --- a/Node/package.json +++ b/Node/package.json @@ -1,12 +1,12 @@ { "type": "module", "dependencies": { - "@types/node": "^20.14.10", + "@types/node": "^22.1.0", "express": "^4.19.2", "express-session": "^1.18.0", "http-terminator": "^3.2.0", "mariadb": "^3.3.1", - "mysql2": "^3.10.2", + "mysql2": "^3.11.0", "node-fetch": "^3.3.2", "pg": "^8.12.0" } diff --git a/Smalltalk/Browser/Canvas/CanvasPattern.st b/Smalltalk/Browser/Canvas/CanvasPattern.st index f7df2c6..69f8d1d 100644 --- a/Smalltalk/Browser/Canvas/CanvasPattern.st +++ b/Smalltalk/Browser/Canvas/CanvasPattern.st @@ -6,5 +6,5 @@ CLASS CanvasPattern EXTENDS JsObject MODULE Browser CLASSVARS '' VARS '' created by the CanvasRenderingContext2D.createPattern() method." setTransform: domMatrix - ^ INLINE 'setTransform( domMatrix )' + INLINE 'setTransform( domMatrix )' ! diff --git a/Smalltalk/Browser/Canvas/ContextAttributes.st b/Smalltalk/Browser/Canvas/ContextAttributes.st index 607ef2f..3dc4ece 100644 --- a/Smalltalk/Browser/Canvas/ContextAttributes.st +++ b/Smalltalk/Browser/Canvas/ContextAttributes.st @@ -10,5 +10,6 @@ desynchronized ^ Boolean fromJs: INLINE 'this.js.desynchronized'. ! willReadFrequently - ^ Boolean fromJs: INLINE 'this.js.willReadFrequently'. + "Chromium browser put a string in this field?" + ^ Boolean fromJs: INLINE 'this.js.willReadFrequently == true'. ! diff --git a/Smalltalk/Browser/Canvas/DomMatrix.st b/Smalltalk/Browser/Canvas/DomMatrix.st index 19a0628..c84d66f 100644 --- a/Smalltalk/Browser/Canvas/DomMatrix.st +++ b/Smalltalk/Browser/Canvas/DomMatrix.st @@ -1,4 +1,237 @@ -CLASS DomMatrix EXTENDS DomMatrixReadOnly MODULE Browser CLASSVARS '' VARS '' +CLASS DomMatrix EXTENDS JsObject MODULE Browser CLASSVARS '' VARS '' -"TODO: Implement properties and methods" +"This class also implements DomMatrixReadOnly. + It uses the Point and Point3d classes for point and vector operations, + so not the DomPoint class." +CLASSMETHODS + +new + ^ self fromJs: INLINE 'new DOMMatrix()'. +! +init: array + "Array should be either 6 or float values 16 values, + to intialize the matrix for 2D or 3D operations respectively." + ^ self fromJs: INLINE 'new DOMMatrix( array.$toJs() )'. +! +fromMatrix: matrix + ^ DomMatrix fromJs: INLINE 'DOMMatrix.fromMatrix( matrix.js )' +! + +METHODS + +"Accessing 2D" + +a + ^ Float fromJs: INLINE 'this.js.a'. +! +b + ^ Float fromJs: INLINE 'this.js.b'. +! +c + ^ Float fromJs: INLINE 'this.js.c'. +! +d + ^ Float fromJs: INLINE 'this.js.d'. +! +e + ^ Float fromJs: INLINE 'this.js.e'. +! +f + ^ Float fromJs: INLINE 'this.js.f'. +! + +"Accessing 3D" + +m11 + ^ Float fromJs: INLINE 'this.js.m11'. +! +m12 + ^ Float fromJs: INLINE 'this.js.m12'. +! +m13 + ^ Float fromJs: INLINE 'this.js.m13'. +! +m14 + ^ Float fromJs: INLINE 'this.js.m14'. +! + +m21 + ^ Float fromJs: INLINE 'this.js.m21'. +! +m22 + ^ Float fromJs: INLINE 'this.js.m22'. +! +m23 + ^ Float fromJs: INLINE 'this.js.m23'. +! +m24 + ^ Float fromJs: INLINE 'this.js.m24'. +! + +m31 + ^ Float fromJs: INLINE 'this.js.m31'. +! +m32 + ^ Float fromJs: INLINE 'this.js.m32'. +! +m33 + ^ Float fromJs: INLINE 'this.js.m33'. +! +m34 + ^ Float fromJs: INLINE 'this.js.m34'. +! + +m41 + ^ Float fromJs: INLINE 'this.js.m41'. +! +m42 + ^ Float fromJs: INLINE 'this.js.m42'. +! +m43 + ^ Float fromJs: INLINE 'this.js.m43'. +! +m44 + ^ Float fromJs: INLINE 'this.js.m44'. +! + +"Converting" + +toString + ^ String fromJs: INLINE 'this.js.toString()'. +! +toJson + ^ JsObject fromJs: INLINE 'this.js.toJSON()'. +! +copy + ^ DomMatrix fromMatrix: self. +! + +"Testing" + +is2d + ^ Boolean fromJs: INLINE 'this.js.is2D'. +! +is3d + ^ self is2d not. +! +isIdentity + ^ Boolean fromJs: INLINE 'this.js.isIdentity'. +! + +"Comparing" + +equals2d: matrix precision: precision + ^ self is2d & matrix is2d & + ( ( self a - matrix a ) abs <= precision ) & + ( ( self b - matrix b ) abs <= precision ) & + ( ( self c - matrix c ) abs <= precision ) & + ( ( self d - matrix d ) abs <= precision ) & + ( ( self e - matrix e ) abs <= precision ) & + ( ( self f - matrix f ) abs <= precision ). +! + +equals3d: matrix precision: precision + ^ self is3d & matrix is3d & + ( ( self m11 - matrix m11 ) abs <= precision ) & + ( ( self m12 - matrix m12 ) abs <= precision ) & + ( ( self m13 - matrix m13 ) abs <= precision ) & + ( ( self m14 - matrix m14 ) abs <= precision ) & + ( ( self m21 - matrix m21 ) abs <= precision ) & + ( ( self m22 - matrix m22 ) abs <= precision ) & + ( ( self m23 - matrix m23 ) abs <= precision ) & + ( ( self m24 - matrix m24 ) abs <= precision ) & + ( ( self m31 - matrix m31 ) abs <= precision ) & + ( ( self m32 - matrix m32 ) abs <= precision ) & + ( ( self m33 - matrix m33 ) abs <= precision ) & + ( ( self m34 - matrix m34 ) abs <= precision ) & + ( ( self m41 - matrix m41 ) abs <= precision ) & + ( ( self m42 - matrix m42 ) abs <= precision ) & + ( ( self m43 - matrix m43 ) abs <= precision ) & + ( ( self m44 - matrix m44 ) abs <= precision ). +! + +"Arithmetic, non-mutating" + +flipX + ^ DomMatrix fromJs: INLINE 'this.js.flipX()'. +! +flipY + ^ DomMatrix fromJs: INLINE 'this.js.flipY()'. +! +inverse + ^ DomMatrix fromJs: INLINE 'this.js.inverse()'. +! +multiply: matrix + ^ DomMatrix fromJs: INLINE 'this.js.multiply( matrix.js )'. +! +rotateAxis: degrees3d angle: angle + ^ DomMatrix fromJs: INLINE 'this.js.rotateAxisAngle( degrees3d.x.js, degrees3d.y.js, degrees3d.z.js, angle.js )'. +! +rotate: angle + ^ DomMatrix fromJs: INLINE 'this.js.rotate( angle.js )'. +! +rotateFromVector: point3d + ^ DomMatrix fromJs: INLINE 'this.js.rotate( point3d.x.js, point3d.y.js, point3d.z.js )'. +! +scale: scale3d + ^ DomMatrix fromJs: INLINE 'this.js.rotate( scale3d.x.js, scale3d.y.js, scale3d.z.js )'. +! +scale: scale3d origin: origin3d + ^ DomMatrix fromJs: INLINE 'this.js.rotate( scale3d.x.js, scale3d.y.js, scale3d.z.js, origin3d.x.js, origin3d.y.js, origin3d.z.js )'. +! +transformPoint: domPoint + ^ DomPoint fromJs: INLINE 'this.js.transformPoint( domPoint.js )'. +! +translate: domPoint + ^ DomMatrix fromJs: INLINE 'this.js.translate( domPoint.js.x, domPoint.js.y, domPoint.js.z )'. +! + +"Arithmetic, mutating" + +invertSelf + INLINE 'this.js.invertSelf()'. +! +multiplySelf: matrix + INLINE 'this.js.multiplySelf( matrix.js )'. +! +preMultiplySelf: matrix + INLINE 'this.js.preMultiplySelf( matrix.js )'. +! +translateSelf: point3d + INLINE 'this.js.translateSelf( point3d.x.js, point3d.y.js, point3d.z.js )'. +! + +scaleSelf: scale + INLINE 'this.js.scaleSelf( scale.js )'. +! +scaleSelf: scale origin: origin + INLINE 'this.js.scaleSelf( scale.js, origin.x.js, origin.y.js, origin.z.js )'. +! +scale3dSelf: scale3d + INLINE 'this.js.scale3dSelf( scale3d.x.js, scale3d.y.js, scale3d.z.js )'. +! +scale3dSelf: scale3d origin: origin + INLINE 'this.js.scale3dSelf( scale3d.x.js, scale3d.y.js, scale3d.z.js, origin.x.js, origin.y.js, origin.z.js )'. +! + +rotateSelf: degrees3d + INLINE 'this.js.rotateSelf( degrees3d.x.js, degrees3d.y.js, degrees3d.z.js )'. +! +rotateAxisAngleSelf: point3d degrees: degrees + INLINE 'this.js.rotateAxisAngleSelf( point3d.x.js, point3d.y.js, point3d.z.js, degrees.js )'. +! +rotateFromVectorSelf: point + INLINE 'this.js.rotateFromVectorSelf( point.x.js, point.y.js )'. +! + +skewXSelf: degrees + INLINE 'this.js.skewXSelf( degrees.js )'. +! +skewYSelf: degrees + INLINE 'this.js.skewYSelf( degrees.js )'. +! + +setMatrixValue: transform "string" + INLINE 'this.js.setMatrixValue( transform.js )'. +! diff --git a/Smalltalk/Browser/Canvas/DomMatrixReadOnly.st b/Smalltalk/Browser/Canvas/DomMatrixReadOnly.st deleted file mode 100644 index a4c6dd6..0000000 --- a/Smalltalk/Browser/Canvas/DomMatrixReadOnly.st +++ /dev/null @@ -1,146 +0,0 @@ -CLASS DomMatrixReadOnly EXTENDS JsObject MODULE Browser CLASSVARS '' VARS '' - -"This class uses the Point and Point3d classes voor point and vector operations, - so not the DomPoint class." - -CLASSMETHODS - -new - ^ self fromJs: INLINE 'new DOMMatrixReadOnly()'. -! -init: array - "Array should be either 6 or float values 16 values, - to intialize the matrix for 2D or 3D operations respectively." - ^ self fromJs: INLINE 'new DOMMatrixReadOnly( array.$toJs() )'. -! - -METHODS - -"Accessing 2D" - -a - ^ Float fromJs: INLINE 'this.js.a'. -! -b - ^ Float fromJs: INLINE 'this.js.b'. -! -c - ^ Float fromJs: INLINE 'this.js.c'. -! -d - ^ Float fromJs: INLINE 'this.js.d'. -! -e - ^ Float fromJs: INLINE 'this.js.e'. -! -f - ^ Float fromJs: INLINE 'this.js.f'. -! - -"Accessing 3D" - -m11 - ^ Float fromJs: INLINE 'this.js.m11'. -! -m12 - ^ Float fromJs: INLINE 'this.js.m12'. -! -m13 - ^ Float fromJs: INLINE 'this.js.m13'. -! -m14 - ^ Float fromJs: INLINE 'this.js.m14'. -! - -m21 - ^ Float fromJs: INLINE 'this.js.m21'. -! -m22 - ^ Float fromJs: INLINE 'this.js.m22'. -! -m23 - ^ Float fromJs: INLINE 'this.js.m23'. -! -m24 - ^ Float fromJs: INLINE 'this.js.m24'. -! - -m31 - ^ Float fromJs: INLINE 'this.js.m31'. -! -m32 - ^ Float fromJs: INLINE 'this.js.m32'. -! -m33 - ^ Float fromJs: INLINE 'this.js.m33'. -! -m34 - ^ Float fromJs: INLINE 'this.js.m34'. -! - -m41 - ^ Float fromJs: INLINE 'this.js.m41'. -! -m42 - ^ Float fromJs: INLINE 'this.js.m42'. -! -m43 - ^ Float fromJs: INLINE 'this.js.m43'. -! -m44 - ^ Float fromJs: INLINE 'this.js.m44'. -! - -"Converting" - -toString - ^ String fromJs: INLINE 'this.js.toString()'. -! -toJson - ^ JsObject fromJs: INLINE 'this.js.toJSON()'. -! - -"Testing" - -is2d - ^ Boolean fromJs: INLINE 'this.js.is2D'. -! -isIdentity - ^ Boolean fromJs: INLINE 'this.js.isIdentity'. -! - -"Arithmatic" - -flipX - ^ DomMatrixReadOnly fromJs: INLINE 'this.js.flipX()'. -! -flipY - ^ DomMatrixReadOnly fromJs: INLINE 'this.js.flipY()'. -! -inverse - ^ DomMatrixReadOnly fromJs: INLINE 'this.js.inverse()'. -! -multiply: matrix - ^ DomMatrixReadOnly fromJs: INLINE 'this.js.multiply( matrix.js )'. -! -rotateAxis: point3d angle: angle - ^ DomMatrixReadOnly fromJs: INLINE 'this.js.rotateAxisAngle( point3d.x.js, point3d.y.js, point3d.z.js, angle.js )'. -! -rotate: angle - ^ DomMatrixReadOnly fromJs: INLINE 'this.js.rotate( angle.js )'. -! -rotateFromVector: point3d - ^ DomMatrixReadOnly fromJs: INLINE 'this.js.rotate( point3d.x.js, point3d.y.js, point3d.z.js )'. -! -scale: scale3d - ^ DomMatrixReadOnly fromJs: INLINE 'this.js.rotate( scale3d.x.js, scale3d.y.js, scale3d.z.js )'. -! -scale: scale3d origin: origin3d - ^ DomMatrixReadOnly fromJs: INLINE 'this.js.rotate( scale3d.x.js, scale3d.y.js, scale3d.z.js, origin3d.x.js, origin3d.y.js, origin3d.z.js )'. -! -transformPoint: domPoint - ^ DomPoint fromJs: INLINE 'this.js.transformPoint( domPoint.js )'. -! -translate: domPoint - ^ DomMatrixReadOnly fromJs: INLINE 'this.js.translate( domPoint.js.x, domPoint.js.y, domPoint.js.z )'. -! diff --git a/Smalltalk/Browser/Canvas/DomPoint.st b/Smalltalk/Browser/Canvas/DomPoint.st index 787d89b..9d1c3af 100644 --- a/Smalltalk/Browser/Canvas/DomPoint.st +++ b/Smalltalk/Browser/Canvas/DomPoint.st @@ -1,4 +1,6 @@ -CLASS DomPoint EXTENDS DomPointReadOnly MODULE Browser CLASSVARS '' VARS '' +CLASS DomPoint EXTENDS JsObject MODULE Browser CLASSVARS '' VARS '' + +"This class also implements DomPointReadOnly." CLASSMETHODS @@ -11,21 +13,48 @@ x: x y: y z: z x: x y: y z: z w: w ^ self fromJs: INLINE 'new DOMPoint( x.js, y.js, z.js, w.js )'. ! -formPoint: point - ^ self x: point x y: point y z: point z. +fromPoint3d: point3d + ^ self x: point3d x y: point3d y z: point3d z. +! +fromDomPoint: domPoint + ^ DomPoint fromJs: INLINE 'DOMPoint.fromPoint( domPoint.js )'. ! METHODS +"Converting" + +toJson + ^ String fromJs: INLINE 'this.js.toJSON()'. +! +copy + ^ DomPoint fromDomPoint: self. +! + +"Accessing" + +x + ^ Float fromJs: INLINE 'this.js.x'. +! x: x INLINE 'this.js.x = x.js'. ! +y + ^ Float fromJs: INLINE 'this.js.y'. +! y: y INLINE 'this.js.y = y.js'. ! +z + ^ Float fromJs: INLINE 'this.js.z'. +! z: z INLINE 'this.js.z = z.js'. ! +w + ^ Float fromJs: INLINE 'this.js.w'. +! + w: w INLINE 'this.js.w = w.js'. ! diff --git a/Smalltalk/Browser/Canvas/DomPointReadOnly.st b/Smalltalk/Browser/Canvas/DomPointReadOnly.st deleted file mode 100644 index 0abd98e..0000000 --- a/Smalltalk/Browser/Canvas/DomPointReadOnly.st +++ /dev/null @@ -1,39 +0,0 @@ -CLASS DomPointReadOnly EXTENDS JsObject MODULE Browser CLASSVARS '' VARS '' - -CLASSMETHODS - -x: x y: y - ^ self fromJs: INLINE 'new DOMPointReadOnly( x.js, y.js )'. -! -x: x y: y z: z - ^ self fromJs: INLINE 'new DOMPointReadOnly( x.js, y.js, z.js )'. -! -x: x y: y z: z w: w - ^ self fromJs: INLINE 'new DOMPointReadOnly( x.js, y.js, z.js, w.js )'. -! -fromPoint: domPoint - ^ self fromJs: INLINE 'domPoint.js'. -! - -METHODS - -"Converting" - -toJson - ^ String fromJs: INLINE 'this.js.toJSON()'. -! - -"Accessing" - -x - ^ Float fromJs: INLINE 'this.js.x'. -! -y - ^ Float fromJs: INLINE 'this.js.y'. -! -z - ^ Float fromJs: INLINE 'this.js.z'. -! -w - ^ Float fromJs: INLINE 'this.js.w'. -! diff --git a/Smalltalk/Browser/Canvas/HtmlCanvasElement.st b/Smalltalk/Browser/Canvas/HtmlCanvasElement.st index afea5d2..e750dff 100644 --- a/Smalltalk/Browser/Canvas/HtmlCanvasElement.st +++ b/Smalltalk/Browser/Canvas/HtmlCanvasElement.st @@ -33,6 +33,9 @@ getContext: type self error: [ 'Unsupported or invalid canvas context', context jsClassName ]. ! +getContext2d + ^ CanvasRenderingContext2d fromJs: INLINE 'this.js.getContext( "2d" )'. +! toBlobType: type quality: quality then: block Blob. "Force import" INLINE 'this.js.toBlob( ( blob ) => block.$value$( stBlob$class.$fromJs$( blob ) ), type.js, quality.js )'. diff --git a/Smalltalk/Browser/Canvas/ImageData.st b/Smalltalk/Browser/Canvas/ImageData.st index acd4a68..bc1a5a4 100644 --- a/Smalltalk/Browser/Canvas/ImageData.st +++ b/Smalltalk/Browser/Canvas/ImageData.st @@ -1,17 +1,19 @@ CLASS ImageData EXTENDS JsObject MODULE Browser CLASSVARS '' VARS '' +"Data" + data ^ Uint8Array fromJs: INLINE 'this.js.data'. ! -colorSpace - ^ String fromJs: INLINE 'this.js.colorSpace'. + +"Dimensions" + +width + ^ Integer fromJs: INLINE 'this.js.width'. ! height ^ Integer fromJs: INLINE 'this.js.height'. ! -width - ^ Integer fromJs: INLINE 'this.js.width'. -! extent ^ self width @ self height. ! diff --git a/Smalltalk/Browser/Canvas/OffscreenCanvas.st b/Smalltalk/Browser/Canvas/OffscreenCanvas.st index 43be29e..c8e20a5 100644 --- a/Smalltalk/Browser/Canvas/OffscreenCanvas.st +++ b/Smalltalk/Browser/Canvas/OffscreenCanvas.st @@ -1,3 +1,4 @@ CLASS OffscreenCanvas EXTENDS JsObject MODULE Browser CLASSVARS '' VARS '' -"Todo: Implement properties and methods." +"TODO: Implement properties and methods. + Implementation is only useful if the worker API is also implemented first." diff --git a/Smalltalk/Browser/Canvas/Test/TestCanvasRenderingContext2d.st b/Smalltalk/Browser/Canvas/Test/TestCanvasRenderingContext2d.st index 9e957ec..171e57c 100644 --- a/Smalltalk/Browser/Canvas/Test/TestCanvasRenderingContext2d.st +++ b/Smalltalk/Browser/Canvas/Test/TestCanvasRenderingContext2d.st @@ -102,7 +102,7 @@ testMethods Only methods that return a result are tested here. Methods that draw on the canvas are tested visually in CanvasComponent." - | canvas context imageData pattern gradient attributes lineDash matrix | + | canvas context imageData pattern gradient attributes lineDash matrix textMetrics contextAttributes | canvas := Document default createElement: 'canvas'. self assert: [ canvas class = HtmlCanvasElement ]. @@ -110,6 +110,9 @@ testMethods context := canvas getContext: '2d'. self assert: [ context class = CanvasRenderingContext2d ]. + imageData := context getImageData: ( Rectangle origin: ( 20 @ 10 ) extent: ( 40 @ 30 ) ). + self assert: [ imageData class = ImageData ]. + imageData := context createImageData: ( 20 @ 10 ). self assert: [ imageData class = ImageData ]. @@ -129,16 +132,19 @@ testMethods attributes := context getContextAttributes. self assert: [ attributes class = ContextAttributes ]. - imageData := context getImageData: ( Rectangle origin: ( 20 @ 10 ) extent: ( 40 @ 30 ) ). - self assert: [ imageData class = ImageData ]. - lineDash := context getLineDash. self assert: [ lineDash = #( ) ]. matrix := context getTransform. - self assert: [ matrix class = DomMatrix ]. + self assert: [ matrix isIdentity ]. self assert: [ context isContextLost not ]. self assert: [ ( context isPointInPath: ( 10 @ 0 ) ) not ]. self assert: [ ( context isPointInStroke: ( 10 @ 0 ) ) not ]. + + textMetrics := context measureText: 'Hello world'. + self assert: [ textMetrics class = TextMetrics ]. + + contextAttributes := context getContextAttributes. + self assert: [ contextAttributes class = ContextAttributes ]. ! diff --git a/Smalltalk/Browser/Canvas/Test/TestContextAttributes.st b/Smalltalk/Browser/Canvas/Test/TestContextAttributes.st new file mode 100644 index 0000000..a7966b6 --- /dev/null +++ b/Smalltalk/Browser/Canvas/Test/TestContextAttributes.st @@ -0,0 +1,13 @@ +CLASS TestContextAttributes EXTENDS Test MODULE TestBrowser CLASSVARS '' VARS '' + +test + | context contextAttributes | + context := ( Document default createElement: 'canvas' ) getContext2d. + contextAttributes := context getContextAttributes. + self assert: [ contextAttributes class = ContextAttributes ]. + + self assert: [ contextAttributes alpha ]. + self assert: [ contextAttributes colorSpace = 'srgb' ]. + self assert: [ contextAttributes desynchronized not ]. + self assert: [ contextAttributes willReadFrequently not ]. +! diff --git a/Smalltalk/Browser/Canvas/Test/TestDomMatrix.st b/Smalltalk/Browser/Canvas/Test/TestDomMatrix.st new file mode 100644 index 0000000..2b7d200 --- /dev/null +++ b/Smalltalk/Browser/Canvas/Test/TestDomMatrix.st @@ -0,0 +1,118 @@ +CLASS TestDomMatrix EXTENDS Test MODULE TestBrowser CLASSVARS '' VARS '' + +"2D testing" + +test2dReadOnly + | matrix jsObject matrix2 point | + + matrix := DomMatrix new. + self assert: [ matrix is2d ]. + self assert: [ matrix isIdentity ]. + + matrix := DomMatrix init: #( 1 2 3 4 5 6 ). + self assert: [ matrix is2d ]. + self assert: [ matrix isIdentity not ]. + self assert: [ matrix toString = 'matrix(1, 2, 3, 4, 5, 6)' ]. + self assert: [ matrix a = 1 ]. + self assert: [ matrix b = 2 ]. + self assert: [ matrix c = 3 ]. + self assert: [ matrix d = 4 ]. + self assert: [ matrix e = 5 ]. + self assert: [ matrix f = 6 ]. + + jsObject := matrix toJson. + self assert: [ ( jsObject atJsProperty: 'a' ) = 1 ]. + self assert: [ ( jsObject atJsProperty: 'b' ) = 2 ]. + self assert: [ ( jsObject atJsProperty: 'c' ) = 3 ]. + self assert: [ ( jsObject atJsProperty: 'd' ) = 4 ]. + self assert: [ ( jsObject atJsProperty: 'e' ) = 5 ]. + self assert: [ ( jsObject atJsProperty: 'f' ) = 6 ]. + + matrix2 := matrix flipX. + self assert: [ matrix2 equals2d: ( DomMatrix init: #( -1 -2 3 4 5 6 ) ) precision: 0.001 ]. + + matrix2 := matrix flipY. + self assert: [ matrix2 equals2d: ( DomMatrix init: #( 1 2 -3 -4 5 6 ) ) precision: 0.001 ]. + + matrix2 := matrix inverse. + self assert: [ matrix2 equals2d: ( DomMatrix init: #( -2 1 1.5 -0.5 1 -2 ) ) precision: 0.001 ]. + + matrix2 := matrix multiply: matrix. + self assert: [ matrix2 equals2d: ( DomMatrix init: #( 7 10 15 22 28 40 ) ) precision: 0.001 ]. + + matrix2 := matrix rotateAxis: ( 1 @ 0 @ 0 ) angle: 90. + self assert: [ matrix2 equals3d: ( DomMatrix init: #( 1 2 0 0 0 0 1 0 -3 -4 0 0 5 6 0 1 ) ) precision: 0.001 ]. + + matrix2 := matrix rotate: 90. + self assert: [ matrix2 equals2d: ( DomMatrix init: #( 3 4 -1 -2 5 6 ) ) precision: 0.001 ]. + + matrix2 := matrix rotateFromVector: ( 1 @ 0 @ 0 ). + self assert: [ ( matrix2 a = 1 ) & ( matrix2 b = 2 ) ]. + + matrix2 := matrix scale: ( 2 @ 2 @ 2 ). + self assert: [ ( matrix2 a * 10 ) toInteger = 11 ]. + + point := matrix transformPoint: ( DomPoint x: 1 y: 2 z: 3 ). + self assert: [ point = ( DomPoint x: 12 y: 16 z: 3 w: 1 ) ]. + + matrix2 := matrix translate: ( DomPoint x: 1 y: 2 z: 3 ). + self assert: [ matrix2 equals3d: ( DomMatrix init: #( 1 2 0 0 3 4 0 0 0 0 1 0 12 16 3 1 ) ) precision: 0.001 ]. +! +test2dMutating + | matrix matrix2 point | + + matrix := DomMatrix init: #( 1 2 3 4 5 6 ). + + matrix2 := matrix copy invertSelf. + self assert: [ matrix2 equals2d: ( DomMatrix init: #( -2 1 1.5 -0.5 1 -2 ) ) precision: 0.001 ]. + + matrix2 := matrix copy multiplySelf: matrix copy. + self assert: [ matrix2 equals2d: ( DomMatrix init: #( 7 10 15 22 28 40 ) ) precision: 0.001 ]. + + matrix2 := matrix copy preMultiplySelf: matrix copy. + self assert: [ matrix2 equals2d: ( DomMatrix init: #( 7 10 15 22 28 40 ) ) precision: 0.001 ]. + + matrix2 := matrix copy translateSelf: ( 1 @ 2 @ 3 ). + self assert: [ matrix2 equals3d: ( DomMatrix init: #( 1 2 0 0 3 4 0 0 0 0 1 0 12 16 3 1 ) ) precision: 0.001 ]. + + matrix2 := matrix copy scaleSelf: 2. + self assert: [ matrix2 equals2d: ( DomMatrix init: #( 2 4 6 8 5 6 ) ) precision: 0.001 ]. + + matrix2 := matrix copy scaleSelf: 3 origin: ( 1 @ 2 @ 3 ). + self assert: [ matrix2 equals3d: ( DomMatrix init: #( 3 6 0 0 3 4 0 0 0 0 2 0 -1 -6 0 1 ) ) precision: 0.001 ]. + + matrix2 := matrix copy scale3dSelf: ( 2 @ 3 @ 4 ). + self assert: [ matrix2 equals3d: ( DomMatrix init: #( 2 4 0 0 6 8 0 0 0 0 2 0 -10 -16 0 1 ) ) precision: 0.001 ]. + + matrix2 := matrix copy scale3dSelf: ( 2 @ 3 @ 4 ) origin: ( 1 @ 2 @ 3 ). + self assert: [ matrix2 equals3d: ( DomMatrix init: #( 2 4 0 0 6 8 0 0 0 0 2 0 -10 -16 -1 1 ) ) precision: 0.001 ]. + + matrix2 := matrix copy rotateSelf: ( 45 @ 45 @ 45 ). + self assert: [ matrix2 equals3d: ( DomMatrix init: #( 2 3 -0.70 0 2.41 3.12 0.5 0 0.41 1.12 0.5 0 5 6 0 1 ) ) precision: 0.1 ]. + + matrix2 := matrix copy rotateAxisAngleSelf: ( 1 @ 2 @ 3 ) degrees: 90. + self assert: [ matrix2 equals3d: ( DomMatrix init: #( 2.90 3.92 -0.32 0 0.19 -0.17 0.69 0 1.23 2.14 0.64 0 5 6 0 1 ) ) precision: 0.1 ]. + + matrix2 := matrix copy rotateFromVectorSelf: ( 1 @ 2 @ 3 ). + self assert: [ matrix2 equals2d: ( DomMatrix init: #( 3.13 4.47 0.44 0 5 6 ) ) precision: 0.1 ]. + + matrix2 := DomMatrix new setMatrixValue: 'scale( 2 )'. + self assert: [ matrix2 equals2d: ( DomMatrix init: #( 2 0 0 2 0 0 ) ) precision: 0.001 ]. + + matrix2 := matrix copy skewXSelf: 10. + self assert: [ matrix2 equals2d: ( DomMatrix init: #( 1 2 3.17 4.35 5 6 ) ) precision: 0.1 ]. + + matrix2 := matrix copy skewYSelf: 20. + self assert: [ matrix2 equals2d: ( DomMatrix init: #( 2.09 3.45 3 4 5 6 ) ) precision: 0.1 ]. +! + +"3D testing" + +test3d + | matrix jsObject | + + matrix := DomMatrix init: #( 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ). + self assert: [ matrix is3d ]. +! + +"TODO: more...?" diff --git a/Smalltalk/Browser/Canvas/Test/TestDomMatrixReadOnly.st b/Smalltalk/Browser/Canvas/Test/TestDomMatrixReadOnly.st deleted file mode 100644 index 0e34d5d..0000000 --- a/Smalltalk/Browser/Canvas/Test/TestDomMatrixReadOnly.st +++ /dev/null @@ -1,71 +0,0 @@ -CLASS TestDomMatrixReadOnly EXTENDS Test MODULE TestBrowser CLASSVARS '' VARS '' - -test2d - | matrix jsObject matrix2 point | - - matrix := DomMatrixReadOnly new. - self assert: [ matrix is2d ]. - self assert: [ matrix isIdentity ]. - - matrix := DomMatrix init: #( 1 2 3 4 5 6 ). - self assert: [ matrix is2d ]. - self assert: [ matrix isIdentity not ]. - self assert: [ matrix toString = 'matrix(1, 2, 3, 4, 5, 6)' ]. - self assert: [ matrix a = 1 ]. - self assert: [ matrix b = 2 ]. - self assert: [ matrix c = 3 ]. - self assert: [ matrix d = 4 ]. - self assert: [ matrix e = 5 ]. - self assert: [ matrix f = 6 ]. - - jsObject := matrix toJson. - self assert: [ ( jsObject atJsProperty: 'a' ) = 1 ]. - self assert: [ ( jsObject atJsProperty: 'b' ) = 2 ]. - self assert: [ ( jsObject atJsProperty: 'c' ) = 3 ]. - self assert: [ ( jsObject atJsProperty: 'd' ) = 4 ]. - self assert: [ ( jsObject atJsProperty: 'e' ) = 5 ]. - self assert: [ ( jsObject atJsProperty: 'f' ) = 6 ]. - - matrix2 := matrix flipX. - self assert: [ matrix2 toString = 'matrix(-1, -2, 3, 4, 5, 6)' ]. - - matrix2 := matrix flipY. - self assert: [ matrix2 toString = 'matrix(1, 2, -3, -4, 5, 6)' ]. - - matrix2 := matrix inverse. - self assert: [ matrix2 toString = 'matrix(-2, 1, 1.5, -0.5, 1, -2)' ]. - - matrix2 := matrix multiply: matrix. - self assert: [ matrix2 toString = 'matrix(7, 10, 15, 22, 28, 40)' ]. - - matrix2 := matrix rotateAxis: ( 1 @ 0 @ 0 ) angle: 90. - self assert: [ matrix2 toString = 'matrix3d(1, 2, 0, 0, 0, 0, 1, 0, -3, -4, 0, 0, 5, 6, 0, 1)' ]. - - matrix2 := matrix rotate: 90. -self log: matrix2 toString. - self assert: [ matrix2 toString = 'matrix(3, 4, -1, -2, 5, 6)' ]. - - matrix2 := matrix rotateFromVector: ( 1 @ 0 @ 0 ). - self assert: [ ( matrix2 a = 1 ) & ( matrix2 b = 2 ) ]. - - matrix2 := matrix scale: ( 2 @ 2 @ 2 ). - self assert: [ ( matrix2 a * 10 ) toInteger = 11 ]. - - point := matrix transformPoint: ( DomPoint x: 1 y: 2 z: 3 ). - self assert: [ point = ( DomPoint x: 12 y: 16 z: 3 w: 1 ) ]. - - matrix2 := matrix translate: ( DomPoint x: 1 y: 2 z: 3 ). - self assert: [ matrix2 toString = 'matrix3d(1, 2, 0, 0, 3, 4, 0, 0, 0, 0, 1, 0, 12, 16, 3, 1)' ]. -! - -translate: point3d - ^ self new fromJs: INLINE 'this.js.translate( point3d.js.x, mapoint3dtrix.js.y, point3d.js.z )'. -! - -test3d - | matrix jsObject | - - matrix := DomMatrixReadOnly init: - #( 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ). - self assert: [ matrix is2d not ]. -! diff --git a/Smalltalk/Browser/Canvas/Test/TestDomPoint.st b/Smalltalk/Browser/Canvas/Test/TestDomPoint.st index d0df9a5..26d1213 100644 --- a/Smalltalk/Browser/Canvas/Test/TestDomPoint.st +++ b/Smalltalk/Browser/Canvas/Test/TestDomPoint.st @@ -1,6 +1,37 @@ CLASS TestDomPoint EXTENDS Test MODULE TestBrowser CLASSVARS '' VARS '' -test +testReadonly + | domPoint domPoint2 jsObject | + + domPoint := DomPoint x: 1 y: 2. + self assert: [ domPoint x = 1 ]. + self assert: [ domPoint y = 2 ]. + + domPoint := DomPoint x: 3 y: 4 z: 5. + self assert: [ domPoint x = 3 ]. + self assert: [ domPoint y = 4 ]. + self assert: [ domPoint z = 5 ]. + + domPoint := DomPoint x: 6 y: 7 z: 8 w: 9. + self assert: [ domPoint x = 6 ]. + self assert: [ domPoint y = 7 ]. + self assert: [ domPoint z = 8 ]. + self assert: [ domPoint w = 9 ]. + + jsObject := domPoint toJson. + self assert: [ ( jsObject atJsProperty: 'x' ) = 6 ]. + self assert: [ ( jsObject atJsProperty: 'y' ) = 7 ]. + self assert: [ ( jsObject atJsProperty: 'z' ) = 8 ]. + self assert: [ ( jsObject atJsProperty: 'w' ) = 9 ]. + + domPoint2 := domPoint copy. + self assert: [ domPoint2 x = 6 ]. + self assert: [ domPoint2 y = 7 ]. + self assert: [ domPoint2 z = 8 ]. + self assert: [ domPoint2 w = 9 ]. +! + +testMutable | domPoint domPoint2 | domPoint := DomPoint x: 0 y: 0. diff --git a/Smalltalk/Browser/Canvas/Test/TestDomPointReadOnly.st b/Smalltalk/Browser/Canvas/Test/TestDomPointReadOnly.st deleted file mode 100644 index 4c85fe7..0000000 --- a/Smalltalk/Browser/Canvas/Test/TestDomPointReadOnly.st +++ /dev/null @@ -1,32 +0,0 @@ -CLASS TestDomPointReadOnly EXTENDS Test MODULE TestBrowser CLASSVARS '' VARS '' - -test - | domPoint domPoint2 jsObject | - - domPoint := DomPointReadOnly x: 1 y: 2. - self assert: [ domPoint x = 1 ]. - self assert: [ domPoint y = 2 ]. - - domPoint := DomPointReadOnly x: 3 y: 4 z: 5. - self assert: [ domPoint x = 3 ]. - self assert: [ domPoint y = 4 ]. - self assert: [ domPoint z = 5 ]. - - domPoint := DomPointReadOnly x: 6 y: 7 z: 8 w: 9. - self assert: [ domPoint x = 6 ]. - self assert: [ domPoint y = 7 ]. - self assert: [ domPoint z = 8 ]. - self assert: [ domPoint w = 9 ]. - - jsObject := domPoint toJson. - self assert: [ ( jsObject atJsProperty: 'x' ) = 6 ]. - self assert: [ ( jsObject atJsProperty: 'y' ) = 7 ]. - self assert: [ ( jsObject atJsProperty: 'z' ) = 8 ]. - self assert: [ ( jsObject atJsProperty: 'w' ) = 9 ]. - - domPoint2 := DomPointReadOnly fromPoint: domPoint. - self assert: [ domPoint2 x = 6 ]. - self assert: [ domPoint2 y = 7 ]. - self assert: [ domPoint2 z = 8 ]. - self assert: [ domPoint2 w = 9 ]. -! diff --git a/Smalltalk/Browser/Canvas/Test/TestHtmlCanvasElement.st b/Smalltalk/Browser/Canvas/Test/TestHtmlCanvasElement.st index d327f9f..429cfc5 100644 --- a/Smalltalk/Browser/Canvas/Test/TestHtmlCanvasElement.st +++ b/Smalltalk/Browser/Canvas/Test/TestHtmlCanvasElement.st @@ -19,6 +19,8 @@ test context := canvas getContext: '2d'. self assert: [ context class = CanvasRenderingContext2d ]. + context := canvas getContext2d. + self assert: [ context class = CanvasRenderingContext2d ]. canvas toBlobType: 'image/png' quality: 1.0 then: [ :blob | self onToBlob: blob ]. diff --git a/Smalltalk/Browser/Canvas/Test/TestImageData.st b/Smalltalk/Browser/Canvas/Test/TestImageData.st new file mode 100644 index 0000000..4bb610d --- /dev/null +++ b/Smalltalk/Browser/Canvas/Test/TestImageData.st @@ -0,0 +1,21 @@ +CLASS TestImageData EXTENDS Test MODULE TestBrowser CLASSVARS '' VARS '' + +test + | context imageData | + context := ( Document default createElement: 'canvas' ) getContext2d. + imageData := context getImageData: ( Rectangle origin: ( 20 @ 10 ) extent: ( 40 @ 30 ) ). + self assert: [ imageData class = ImageData ]. + + self assert: [ imageData data length = 4800 ]. + self assert: [ imageData width = 40 ]. + self assert: [ imageData height = 30 ]. + self assert: [ imageData extent = ( 40 @ 30 ) ]. + + imageData := context createImageData: ( 20 @ 10 ). + self assert: [ imageData class = ImageData ]. + + self assert: [ imageData width = 20 ]. + self assert: [ imageData height = 10 ]. + self assert: [ imageData extent = ( 20 @ 10 ) ]. + +! diff --git a/Smalltalk/Browser/Canvas/Test/TestTextMetrics.st b/Smalltalk/Browser/Canvas/Test/TestTextMetrics.st new file mode 100644 index 0000000..82b4458 --- /dev/null +++ b/Smalltalk/Browser/Canvas/Test/TestTextMetrics.st @@ -0,0 +1,22 @@ +CLASS TestTextMetrics EXTENDS Test MODULE TestBrowser CLASSVARS '' VARS '' + +test + | context textMetrics | + context := ( Document default createElement: 'canvas' ) getContext2d. + textMetrics := context measureText: 'Hello world'. + self assert: [ textMetrics class = TextMetrics ]. + + self assert: [ textMetrics width > 40 ]. + + self assert: [ textMetrics actualBoundingBoxLeft <= 0 ]. + self assert: [ textMetrics actualBoundingBoxRight >= 40 ]. + self assert: [ textMetrics actualBoundingBoxAscent >= 5 ]. + self assert: [ textMetrics actualBoundingBoxDescent >= 0 ]. + + self assert: [ textMetrics fontBoundingBoxAscent >= 5 ]. + self assert: [ textMetrics fontBoundingBoxDescent >= 0 ]. + + self assert: [ textMetrics hangingBaseline >= 5 ]. + self assert: [ textMetrics alphabeticBaseline = 0 ]. + self assert: [ textMetrics ideographicBaseline < -0.5 ]. +! diff --git a/Smalltalk/Browser/Canvas/TextMetrics.st b/Smalltalk/Browser/Canvas/TextMetrics.st index b3f03d5..a180dd4 100644 --- a/Smalltalk/Browser/Canvas/TextMetrics.st +++ b/Smalltalk/Browser/Canvas/TextMetrics.st @@ -1,4 +1,43 @@ CLASS TextMetrics EXTENDS JsObject MODULE Browser CLASSVARS '' VARS '' -"TODO: Implement properties and methods" +"Width" +width + ^ Float fromJs: INLINE 'this.js.width'. +! + +"Actual bounding box" + +actualBoundingBoxLeft + ^ Float fromJs: INLINE 'this.js.actualBoundingBoxLeft'. +! +actualBoundingBoxRight + ^ Float fromJs: INLINE 'this.js.actualBoundingBoxRight'. +! +actualBoundingBoxAscent + ^ Float fromJs: INLINE 'this.js.actualBoundingBoxAscent'. +! +actualBoundingBoxDescent + ^ Float fromJs: INLINE 'this.js.actualBoundingBoxDescent'. +! + +"Font bounding box" + +fontBoundingBoxAscent + ^ Float fromJs: INLINE 'this.js.fontBoundingBoxAscent'. +! +fontBoundingBoxDescent + ^ Float fromJs: INLINE 'this.js.fontBoundingBoxDescent'. +! + +"Baseline" + +hangingBaseline + ^ Float fromJs: INLINE 'this.js.hangingBaseline'. +! +alphabeticBaseline + ^ Float fromJs: INLINE 'this.js.alphabeticBaseline'. +! +ideographicBaseline + ^ Float fromJs: INLINE 'this.js.ideographicBaseline'. +!