From c456cad5bbb39b6eb406728eb602c64b077c8502 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Mon, 20 Mar 2023 08:14:39 -0700 Subject: [PATCH 1/2] add string tags --- CHANGELOG.md | 1 + lib/bindings.js | 24 ++++++++++++++++++++++++ test/canvas.test.js | 22 +++++++++++++++++++++- test/image.test.js | 5 +++++ test/imageData.test.js | 5 +++++ test/wpt/generated/the-canvas-element.js | 6 ++++++ 6 files changed, 62 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11023e97c..fc539a008 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ project adheres to [Semantic Versioning](http://semver.org/). ================== ### Changed ### Added +* Added string tags to support class detection ### Fixed * Add missing property `canvas` to the `CanvasRenderingContext2D` type * Fixed glyph positions getting rounded, resulting text having a slight `letter-spacing` effect diff --git a/lib/bindings.js b/lib/bindings.js index c638a5878..96aa11e74 100644 --- a/lib/bindings.js +++ b/lib/bindings.js @@ -4,10 +4,34 @@ const bindings = require('../build/Release/canvas.node') module.exports = bindings +Object.defineProperty(bindings.Canvas.prototype, Symbol.toStringTag, { + value: 'HTMLCanvasElement' +}) + +Object.defineProperty(bindings.Image.prototype, Symbol.toStringTag, { + value: 'HTMLImageElement' +}) + bindings.ImageData.prototype.toString = function () { return '[object ImageData]' } +Object.defineProperty(bindings.ImageData.prototype, Symbol.toStringTag, { + value: 'ImageData' +}) + bindings.CanvasGradient.prototype.toString = function () { return '[object CanvasGradient]' } + +Object.defineProperty(bindings.CanvasGradient.prototype, Symbol.toStringTag, { + value: 'CanvasGradient' +}) + +Object.defineProperty(bindings.CanvasPattern.prototype, Symbol.toStringTag, { + value: 'CanvasPattern' +}) + +Object.defineProperty(bindings.CanvasRenderingContext2d.prototype, Symbol.toStringTag, { + value: 'CanvasRenderingContext2d' +}) diff --git a/test/canvas.test.js b/test/canvas.test.js index 083459ab6..9573688f5 100644 --- a/test/canvas.test.js +++ b/test/canvas.test.js @@ -1410,6 +1410,14 @@ describe('Canvas', function () { assert.strictEqual(pattern.toString(), '[object CanvasPattern]') }) + it('CanvasPattern has class string of `CanvasPattern`', async function () { + const img = await loadImage(path.join(__dirname, '/fixtures/checkers.png')); + const canvas = createCanvas(20, 20) + const ctx = canvas.getContext('2d') + const pattern = ctx.createPattern(img) + assert.strictEqual(Object.prototype.toString.call(pattern), '[object CanvasPattern]') + }) + it('Context2d#createLinearGradient()', function () { const canvas = createCanvas(20, 1) const ctx = canvas.getContext('2d') @@ -1439,6 +1447,11 @@ describe('Canvas', function () { assert.equal(0, imageData.data[i + 2]) assert.equal(255, imageData.data[i + 3]) }) + it('Canvas has class string of `HTMLCanvasElement`', function () { + const canvas = createCanvas(20, 1) + + assert.strictEqual(Object.prototype.toString.call(canvas), '[object HTMLCanvasElement]') + }) it('CanvasGradient stringifies as [object CanvasGradient]', function () { const canvas = createCanvas(20, 1) @@ -1447,6 +1460,13 @@ describe('Canvas', function () { assert.strictEqual(gradient.toString(), '[object CanvasGradient]') }) + it('CanvasGradient has class string of `CanvasGradient`', function () { + const canvas = createCanvas(20, 1) + const ctx = canvas.getContext('2d') + const gradient = ctx.createLinearGradient(1, 1, 19, 1) + assert.strictEqual(Object.prototype.toString.call(gradient), '[object CanvasGradient]') + }) + describe('Context2d#putImageData()', function () { it('throws for invalid arguments', function () { const canvas = createCanvas(2, 1) @@ -1943,7 +1963,7 @@ describe('Canvas', function () { ctx[k] = v ctx.restore() assert.strictEqual(ctx[k], old) - + // save() doesn't modify the value: ctx[k] = v old = ctx[k] diff --git a/test/image.test.js b/test/image.test.js index 8d54dd90f..ec1631a10 100644 --- a/test/image.test.js +++ b/test/image.test.js @@ -30,6 +30,11 @@ describe('Image', function () { assert(Image.prototype.hasOwnProperty('width')) }) + it('Image has class string of `HTMLImageElement`', async function () { + const img = new Image() + assert.strictEqual(Object.prototype.toString.call(img), '[object HTMLImageElement]') + }) + it('loads JPEG image', function () { return loadImage(jpgFace).then((img) => { assert.strictEqual(img.onerror, null) diff --git a/test/imageData.test.js b/test/imageData.test.js index d3c84c29a..04b117b45 100644 --- a/test/imageData.test.js +++ b/test/imageData.test.js @@ -17,6 +17,11 @@ describe('ImageData', function () { assert.strictEqual(imageData.toString(), '[object ImageData]') }) + it('gives class string as `ImageData`', function () { + const imageData = createImageData(2, 3) + assert.strictEqual(Object.prototype.toString.call(imageData), '[object ImageData]') + }) + it('should throw with invalid numeric arguments', function () { assert.throws(() => { createImageData(0, 0) }, /width is zero/) assert.throws(() => { createImageData(1, 0) }, /height is zero/) diff --git a/test/wpt/generated/the-canvas-element.js b/test/wpt/generated/the-canvas-element.js index 8b1a6817e..cea4fd9b4 100644 --- a/test/wpt/generated/the-canvas-element.js +++ b/test/wpt/generated/the-canvas-element.js @@ -171,6 +171,12 @@ describe("WPT: the-canvas-element", function () { assert.strictEqual(window.CanvasRenderingContext2D.prototype.fill, undefined, "window.CanvasRenderingContext2D.prototype.fill", "undefined") }); + it("2d.type class string", function () { + const canvas = createCanvas(100, 50); + const ctx = canvas.getContext("2d"); + assert.strictEqual(Object.prototype.toString.call(ctx), '[object CanvasRenderingContext2D]') + }) + it("2d.type.replace", function () { // Interface methods can be overridden const canvas = createCanvas(100, 50); From 96f9d60794415837e45ddd20bf7e5dc6d62014c3 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Mon, 17 Apr 2023 08:55:45 -0700 Subject: [PATCH 2/2] set toStringTag property to configurable: true --- lib/bindings.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/bindings.js b/lib/bindings.js index 96aa11e74..40cef3c69 100644 --- a/lib/bindings.js +++ b/lib/bindings.js @@ -5,11 +5,13 @@ const bindings = require('../build/Release/canvas.node') module.exports = bindings Object.defineProperty(bindings.Canvas.prototype, Symbol.toStringTag, { - value: 'HTMLCanvasElement' + value: 'HTMLCanvasElement', + configurable: true }) Object.defineProperty(bindings.Image.prototype, Symbol.toStringTag, { - value: 'HTMLImageElement' + value: 'HTMLImageElement', + configurable: true }) bindings.ImageData.prototype.toString = function () { @@ -17,7 +19,8 @@ bindings.ImageData.prototype.toString = function () { } Object.defineProperty(bindings.ImageData.prototype, Symbol.toStringTag, { - value: 'ImageData' + value: 'ImageData', + configurable: true }) bindings.CanvasGradient.prototype.toString = function () { @@ -25,13 +28,16 @@ bindings.CanvasGradient.prototype.toString = function () { } Object.defineProperty(bindings.CanvasGradient.prototype, Symbol.toStringTag, { - value: 'CanvasGradient' + value: 'CanvasGradient', + configurable: true }) Object.defineProperty(bindings.CanvasPattern.prototype, Symbol.toStringTag, { - value: 'CanvasPattern' + value: 'CanvasPattern', + configurable: true }) Object.defineProperty(bindings.CanvasRenderingContext2d.prototype, Symbol.toStringTag, { - value: 'CanvasRenderingContext2d' + value: 'CanvasRenderingContext2d', + configurable: true })