Skip to content

Commit 5902219

Browse files
authored
add string tags for browser polyglot classes (#2214)
* add string tags * set toStringTag property to configurable: true
1 parent f3184ba commit 5902219

File tree

6 files changed

+68
-1
lines changed

6 files changed

+68
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ project adheres to [Semantic Versioning](http://semver.org/).
1414
* Avoid calling virtual methods in constructors/destructors to avoid bypassing virtual dispatch. (#2229)
1515
* Remove unused private field `backend` in the `Backend` class. (#2229)
1616
### Added
17+
* Added string tags to support class detection
1718
### Fixed
1819
* Fix a case of use-after-free. (#2229)
1920
* Fix usage of garbage value by filling the allocated memory entirely with zeros if it's not modified. (#2229)

lib/bindings.js

+30
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,40 @@ const bindings = require('../build/Release/canvas.node')
44

55
module.exports = bindings
66

7+
Object.defineProperty(bindings.Canvas.prototype, Symbol.toStringTag, {
8+
value: 'HTMLCanvasElement',
9+
configurable: true
10+
})
11+
12+
Object.defineProperty(bindings.Image.prototype, Symbol.toStringTag, {
13+
value: 'HTMLImageElement',
14+
configurable: true
15+
})
16+
717
bindings.ImageData.prototype.toString = function () {
818
return '[object ImageData]'
919
}
1020

21+
Object.defineProperty(bindings.ImageData.prototype, Symbol.toStringTag, {
22+
value: 'ImageData',
23+
configurable: true
24+
})
25+
1126
bindings.CanvasGradient.prototype.toString = function () {
1227
return '[object CanvasGradient]'
1328
}
29+
30+
Object.defineProperty(bindings.CanvasGradient.prototype, Symbol.toStringTag, {
31+
value: 'CanvasGradient',
32+
configurable: true
33+
})
34+
35+
Object.defineProperty(bindings.CanvasPattern.prototype, Symbol.toStringTag, {
36+
value: 'CanvasPattern',
37+
configurable: true
38+
})
39+
40+
Object.defineProperty(bindings.CanvasRenderingContext2d.prototype, Symbol.toStringTag, {
41+
value: 'CanvasRenderingContext2d',
42+
configurable: true
43+
})

test/canvas.test.js

+21-1
Original file line numberDiff line numberDiff line change
@@ -1410,6 +1410,14 @@ describe('Canvas', function () {
14101410
assert.strictEqual(pattern.toString(), '[object CanvasPattern]')
14111411
})
14121412

1413+
it('CanvasPattern has class string of `CanvasPattern`', async function () {
1414+
const img = await loadImage(path.join(__dirname, '/fixtures/checkers.png'));
1415+
const canvas = createCanvas(20, 20)
1416+
const ctx = canvas.getContext('2d')
1417+
const pattern = ctx.createPattern(img)
1418+
assert.strictEqual(Object.prototype.toString.call(pattern), '[object CanvasPattern]')
1419+
})
1420+
14131421
it('Context2d#createLinearGradient()', function () {
14141422
const canvas = createCanvas(20, 1)
14151423
const ctx = canvas.getContext('2d')
@@ -1439,6 +1447,11 @@ describe('Canvas', function () {
14391447
assert.equal(0, imageData.data[i + 2])
14401448
assert.equal(255, imageData.data[i + 3])
14411449
})
1450+
it('Canvas has class string of `HTMLCanvasElement`', function () {
1451+
const canvas = createCanvas(20, 1)
1452+
1453+
assert.strictEqual(Object.prototype.toString.call(canvas), '[object HTMLCanvasElement]')
1454+
})
14421455

14431456
it('CanvasGradient stringifies as [object CanvasGradient]', function () {
14441457
const canvas = createCanvas(20, 1)
@@ -1447,6 +1460,13 @@ describe('Canvas', function () {
14471460
assert.strictEqual(gradient.toString(), '[object CanvasGradient]')
14481461
})
14491462

1463+
it('CanvasGradient has class string of `CanvasGradient`', function () {
1464+
const canvas = createCanvas(20, 1)
1465+
const ctx = canvas.getContext('2d')
1466+
const gradient = ctx.createLinearGradient(1, 1, 19, 1)
1467+
assert.strictEqual(Object.prototype.toString.call(gradient), '[object CanvasGradient]')
1468+
})
1469+
14501470
describe('Context2d#putImageData()', function () {
14511471
it('throws for invalid arguments', function () {
14521472
const canvas = createCanvas(2, 1)
@@ -1943,7 +1963,7 @@ describe('Canvas', function () {
19431963
ctx[k] = v
19441964
ctx.restore()
19451965
assert.strictEqual(ctx[k], old)
1946-
1966+
19471967
// save() doesn't modify the value:
19481968
ctx[k] = v
19491969
old = ctx[k]

test/image.test.js

+5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ describe('Image', function () {
3030
assert(Image.prototype.hasOwnProperty('width'))
3131
})
3232

33+
it('Image has class string of `HTMLImageElement`', async function () {
34+
const img = new Image()
35+
assert.strictEqual(Object.prototype.toString.call(img), '[object HTMLImageElement]')
36+
})
37+
3338
it('loads JPEG image', function () {
3439
return loadImage(jpgFace).then((img) => {
3540
assert.strictEqual(img.onerror, null)

test/imageData.test.js

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ describe('ImageData', function () {
1717
assert.strictEqual(imageData.toString(), '[object ImageData]')
1818
})
1919

20+
it('gives class string as `ImageData`', function () {
21+
const imageData = createImageData(2, 3)
22+
assert.strictEqual(Object.prototype.toString.call(imageData), '[object ImageData]')
23+
})
24+
2025
it('should throw with invalid numeric arguments', function () {
2126
assert.throws(() => { createImageData(0, 0) }, /width is zero/)
2227
assert.throws(() => { createImageData(1, 0) }, /height is zero/)

test/wpt/generated/the-canvas-element.js

+6
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@ describe("WPT: the-canvas-element", function () {
171171
assert.strictEqual(window.CanvasRenderingContext2D.prototype.fill, undefined, "window.CanvasRenderingContext2D.prototype.fill", "undefined")
172172
});
173173

174+
it("2d.type class string", function () {
175+
const canvas = createCanvas(100, 50);
176+
const ctx = canvas.getContext("2d");
177+
assert.strictEqual(Object.prototype.toString.call(ctx), '[object CanvasRenderingContext2D]')
178+
})
179+
174180
it("2d.type.replace", function () {
175181
// Interface methods can be overridden
176182
const canvas = createCanvas(100, 50);

0 commit comments

Comments
 (0)