@ohos-ports/vi-canvas-mock 1.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/lib/classes/CanvasGradient.js +24 -0
- package/lib/classes/CanvasPattern.js +15 -0
- package/lib/classes/CanvasRenderingContext2D.js +1246 -0
- package/lib/classes/DOMMatrix.js +192 -0
- package/lib/classes/ImageBitmap.js +25 -0
- package/lib/classes/ImageData.js +61 -0
- package/lib/classes/Path2D.js +34 -0
- package/lib/classes/TextMetrics.js +27 -0
- package/lib/index.js +26 -0
- package/lib/mock/createCanvasEvent.js +28 -0
- package/lib/mock/createImageBitmap.js +48 -0
- package/lib/mock/prototype.js +108 -0
- package/lib/window.js +66 -0
- package/package.json +36 -0
- package/types/index.d.ts +96 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
8
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
9
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
10
|
+
function sumMultipleOfMatricesCells(matrix1Array, matrix2Array, {
|
|
11
|
+
i,
|
|
12
|
+
j
|
|
13
|
+
}) {
|
|
14
|
+
let sum = 0;
|
|
15
|
+
for (let k = 0; k < 4; k++) {
|
|
16
|
+
const matrix1Index = j - 1 + k * 4;
|
|
17
|
+
const matrix2Index = (i - 1) * 4 + k;
|
|
18
|
+
sum += matrix1Array[matrix1Index] * matrix2Array[matrix2Index];
|
|
19
|
+
}
|
|
20
|
+
return sum;
|
|
21
|
+
}
|
|
22
|
+
function multiplyMatrices(leftMatrix, rightMatrix) {
|
|
23
|
+
const leftMatrixArray = leftMatrix.toFloat64Array();
|
|
24
|
+
const rightMatrixArray = rightMatrix.toFloat64Array();
|
|
25
|
+
for (let i = 1; i <= 4; i++) {
|
|
26
|
+
for (let j = 1; j <= 4; j++) {
|
|
27
|
+
leftMatrix[`m${i}${j}`] = sumMultipleOfMatricesCells(leftMatrixArray, rightMatrixArray, {
|
|
28
|
+
i,
|
|
29
|
+
j
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
class DOMMatrix {
|
|
35
|
+
constructor(transform) {
|
|
36
|
+
_defineProperty(this, "_is2D", true);
|
|
37
|
+
_defineProperty(this, "m11", 1.0);
|
|
38
|
+
_defineProperty(this, "m12", 0.0);
|
|
39
|
+
_defineProperty(this, "m13", 0.0);
|
|
40
|
+
_defineProperty(this, "m14", 0.0);
|
|
41
|
+
_defineProperty(this, "m21", 0.0);
|
|
42
|
+
_defineProperty(this, "m22", 1.0);
|
|
43
|
+
_defineProperty(this, "m23", 0.0);
|
|
44
|
+
_defineProperty(this, "m24", 0.0);
|
|
45
|
+
_defineProperty(this, "m31", 0.0);
|
|
46
|
+
_defineProperty(this, "m32", 0.0);
|
|
47
|
+
_defineProperty(this, "m33", 1.0);
|
|
48
|
+
_defineProperty(this, "m34", 0.0);
|
|
49
|
+
_defineProperty(this, "m41", 0.0);
|
|
50
|
+
_defineProperty(this, "m42", 0.0);
|
|
51
|
+
_defineProperty(this, "m43", 0.0);
|
|
52
|
+
_defineProperty(this, "m44", 1.0);
|
|
53
|
+
if (transform && transform.length === 6) {
|
|
54
|
+
this.m11 = transform[0];
|
|
55
|
+
this.m12 = transform[1];
|
|
56
|
+
this.m21 = transform[2];
|
|
57
|
+
this.m22 = transform[3];
|
|
58
|
+
this.m41 = transform[4];
|
|
59
|
+
this.m42 = transform[5];
|
|
60
|
+
this._is2D = true;
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
63
|
+
if (transform && transform.length === 16) {
|
|
64
|
+
this.m11 = transform[0];
|
|
65
|
+
this.m12 = transform[1];
|
|
66
|
+
this.m13 = transform[2];
|
|
67
|
+
this.m14 = transform[3];
|
|
68
|
+
this.m21 = transform[4];
|
|
69
|
+
this.m22 = transform[5];
|
|
70
|
+
this.m23 = transform[6];
|
|
71
|
+
this.m24 = transform[7];
|
|
72
|
+
this.m31 = transform[8];
|
|
73
|
+
this.m32 = transform[9];
|
|
74
|
+
this.m33 = transform[10];
|
|
75
|
+
this.m34 = transform[11];
|
|
76
|
+
this.m41 = transform[12];
|
|
77
|
+
this.m42 = transform[13];
|
|
78
|
+
this.m43 = transform[14];
|
|
79
|
+
this.m44 = transform[15];
|
|
80
|
+
this._is2D = false;
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
if (transform) {
|
|
84
|
+
throw new TypeError("Failed to construct 'DOMMatrix': The sequence must contain 6 elements for a 2D matrix or 16 elements for a 3D matrix.");
|
|
85
|
+
}
|
|
86
|
+
this._is2D = false;
|
|
87
|
+
}
|
|
88
|
+
get isIdentity() {
|
|
89
|
+
if (this._is2D) {
|
|
90
|
+
return this.m11 == 1.0 && this.m12 == 0.0 && this.m21 == 0.0 && this.m22 == 1.0 && this.m41 == 0.0 && this.m42 == 0.0;
|
|
91
|
+
} else {
|
|
92
|
+
return this.m11 = 1.0 && this.m12 === 0.0 && this.m13 === 0.0 && this.m14 === 0.0 && this.m21 === 0.0 && this.m22 === 1.0 && this.m23 === 0.0 && this.m24 === 0.0 && this.m31 === 0.0 && this.m32 === 0.0 && this.m33 === 1.0 && this.m34 === 0.0 && this.m41 === 0.0 && this.m42 === 0.0 && this.m43 === 0.0 && this.m44 === 1.0;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
get a() {
|
|
96
|
+
return this.m11;
|
|
97
|
+
}
|
|
98
|
+
set a(value) {
|
|
99
|
+
this.m11 = value;
|
|
100
|
+
}
|
|
101
|
+
get b() {
|
|
102
|
+
return this.m12;
|
|
103
|
+
}
|
|
104
|
+
set b(value) {
|
|
105
|
+
this.m12 = value;
|
|
106
|
+
}
|
|
107
|
+
get c() {
|
|
108
|
+
return this.m21;
|
|
109
|
+
}
|
|
110
|
+
set c(value) {
|
|
111
|
+
this.m21 = value;
|
|
112
|
+
}
|
|
113
|
+
get d() {
|
|
114
|
+
return this.m22;
|
|
115
|
+
}
|
|
116
|
+
set d(value) {
|
|
117
|
+
this.m22 = value;
|
|
118
|
+
}
|
|
119
|
+
get e() {
|
|
120
|
+
return this.m41;
|
|
121
|
+
}
|
|
122
|
+
set e(value) {
|
|
123
|
+
this.m41 = value;
|
|
124
|
+
}
|
|
125
|
+
get f() {
|
|
126
|
+
return this.m42;
|
|
127
|
+
}
|
|
128
|
+
set f(value) {
|
|
129
|
+
this.m42 = value;
|
|
130
|
+
}
|
|
131
|
+
get is2D() {
|
|
132
|
+
return this._is2D;
|
|
133
|
+
}
|
|
134
|
+
toFloat32Array() {
|
|
135
|
+
return new Float32Array([this.m11, this.m12, this.m13, this.m14, this.m21, this.m22, this.m23, this.m24, this.m31, this.m32, this.m33, this.m34, this.m41, this.m42, this.m43, this.m44]);
|
|
136
|
+
}
|
|
137
|
+
toFloat64Array() {
|
|
138
|
+
return new Float64Array([this.m11, this.m12, this.m13, this.m14, this.m21, this.m22, this.m23, this.m24, this.m31, this.m32, this.m33, this.m34, this.m41, this.m42, this.m43, this.m44]);
|
|
139
|
+
}
|
|
140
|
+
translateSelf(x, y, z) {
|
|
141
|
+
const tx = Number(x),
|
|
142
|
+
ty = Number(y),
|
|
143
|
+
tz = isNaN(Number(z)) ? 0 : Number(z);
|
|
144
|
+
const translationMatrix = new DOMMatrix();
|
|
145
|
+
translationMatrix.m41 = tx;
|
|
146
|
+
translationMatrix.m42 = ty;
|
|
147
|
+
translationMatrix.m43 = tz;
|
|
148
|
+
multiplyMatrices(this, translationMatrix);
|
|
149
|
+
if (tz) {
|
|
150
|
+
this._is2D = false;
|
|
151
|
+
}
|
|
152
|
+
return this;
|
|
153
|
+
}
|
|
154
|
+
translate(x, y, z) {
|
|
155
|
+
let translatedMatrix;
|
|
156
|
+
if (this.is2D) {
|
|
157
|
+
translatedMatrix = new DOMMatrix([this.a, this.b, this.c, this.d, this.e, this.f]);
|
|
158
|
+
} else {
|
|
159
|
+
translatedMatrix = new DOMMatrix(this.toFloat32Array());
|
|
160
|
+
}
|
|
161
|
+
return translatedMatrix.translateSelf(x, y, z);
|
|
162
|
+
}
|
|
163
|
+
scaleSelf(scaleX, scaleY, scaleZ, originX, originY, originZ) {
|
|
164
|
+
const sx = Number(scaleX),
|
|
165
|
+
sy = isNaN(Number(scaleY)) ? sx : Number(scaleY),
|
|
166
|
+
sz = isNaN(Number(scaleZ)) ? 1 : Number(scaleZ);
|
|
167
|
+
const ox = isNaN(Number(originX)) ? 0 : Number(originX),
|
|
168
|
+
oy = isNaN(Number(originY)) ? 0 : Number(originY),
|
|
169
|
+
oz = isNaN(Number(originZ)) ? 0 : Number(originZ);
|
|
170
|
+
this.translateSelf(ox, oy, oz);
|
|
171
|
+
const scaleMatrix = new DOMMatrix();
|
|
172
|
+
scaleMatrix.m11 = sx;
|
|
173
|
+
scaleMatrix.m22 = sy;
|
|
174
|
+
scaleMatrix.m33 = sz;
|
|
175
|
+
multiplyMatrices(this, scaleMatrix);
|
|
176
|
+
this.translateSelf(-ox, -oy, -oz);
|
|
177
|
+
if (Math.abs(sz) !== 1) {
|
|
178
|
+
this._is2D = false;
|
|
179
|
+
}
|
|
180
|
+
return this;
|
|
181
|
+
}
|
|
182
|
+
scale(scaleX, scaleY, scaleZ, originX, originY, originZ) {
|
|
183
|
+
let scaledMatrix;
|
|
184
|
+
if (this.is2D) {
|
|
185
|
+
scaledMatrix = new DOMMatrix([this.a, this.b, this.c, this.d, this.e, this.f]);
|
|
186
|
+
} else {
|
|
187
|
+
scaledMatrix = new DOMMatrix(this.toFloat32Array());
|
|
188
|
+
}
|
|
189
|
+
return scaledMatrix.scaleSelf(scaleX, scaleY, scaleZ, originX, originY, originZ);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
exports.default = DOMMatrix;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
8
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
9
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
10
|
+
class ImageBitmap {
|
|
11
|
+
constructor(width, height) {
|
|
12
|
+
_defineProperty(this, "width", 0);
|
|
13
|
+
_defineProperty(this, "height", 0);
|
|
14
|
+
_defineProperty(this, "_closed", false);
|
|
15
|
+
this.width = width;
|
|
16
|
+
this.height = height;
|
|
17
|
+
this.close = vi.fn(this.close.bind(this));
|
|
18
|
+
}
|
|
19
|
+
close() {
|
|
20
|
+
this.width = 0;
|
|
21
|
+
this.height = 0;
|
|
22
|
+
this._closed = true;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.default = ImageBitmap;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
8
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
9
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
10
|
+
class ImageData {
|
|
11
|
+
get width() {
|
|
12
|
+
return this._width;
|
|
13
|
+
}
|
|
14
|
+
get height() {
|
|
15
|
+
return this._height;
|
|
16
|
+
}
|
|
17
|
+
get data() {
|
|
18
|
+
return this._data;
|
|
19
|
+
}
|
|
20
|
+
constructor(arr, w, h) {
|
|
21
|
+
_defineProperty(this, "_width", 0);
|
|
22
|
+
_defineProperty(this, "_height", 0);
|
|
23
|
+
_defineProperty(this, "_data", null);
|
|
24
|
+
if (arguments.length === 2) {
|
|
25
|
+
if (arr instanceof Uint8ClampedArray) {
|
|
26
|
+
if (arr.length === 0) throw new RangeError('Source length must be a positive multiple of 4.');
|
|
27
|
+
if (arr.length % 4 !== 0) throw new RangeError('Source length must be a positive multiple of 4.');
|
|
28
|
+
if (!Number.isFinite(w)) throw new RangeError('The width is zero or not a number.');
|
|
29
|
+
if (w === 0) throw new RangeError('The width is zero or not a number.');
|
|
30
|
+
this._width = w;
|
|
31
|
+
this._height = arr.length / 4 / w;
|
|
32
|
+
this._data = arr;
|
|
33
|
+
} else {
|
|
34
|
+
const width = arr;
|
|
35
|
+
const height = w;
|
|
36
|
+
if (!Number.isFinite(height)) throw new RangeError('The height is zero or not a number.');
|
|
37
|
+
if (height === 0) throw new RangeError('The height is zero or not a number.');
|
|
38
|
+
if (!Number.isFinite(width)) throw new RangeError('The width is zero or not a number.');
|
|
39
|
+
if (width === 0) throw new RangeError('The width is zero or not a number.');
|
|
40
|
+
this._width = width;
|
|
41
|
+
this._height = height;
|
|
42
|
+
this._data = new Uint8ClampedArray(width * height * 4);
|
|
43
|
+
}
|
|
44
|
+
} else if (arguments.length === 3) {
|
|
45
|
+
if (!(arr instanceof Uint8ClampedArray)) throw new TypeError('First argument must be a Uint8ClampedArray when using 3 arguments.');
|
|
46
|
+
if (arr.length === 0) throw new RangeError('Source length must be a positive multiple of 4.');
|
|
47
|
+
if (arr.length % 4 !== 0) throw new RangeError('Source length must be a positive multiple of 4.');
|
|
48
|
+
if (!Number.isFinite(h)) throw new RangeError('The height is zero or not a number.');
|
|
49
|
+
if (h === 0) throw new RangeError('The height is zero or not a number.');
|
|
50
|
+
if (!Number.isFinite(w)) throw new RangeError('The width is zero or not a number.');
|
|
51
|
+
if (w === 0) throw new RangeError('The width is zero or not a number.');
|
|
52
|
+
if (arr.length !== w * h * 4) throw new RangeError("Source doesn'n contain the exact number of pixels needed.");
|
|
53
|
+
this._width = w;
|
|
54
|
+
this._height = h;
|
|
55
|
+
this._data = arr;
|
|
56
|
+
} else {
|
|
57
|
+
throw new TypeError('Wrong number of arguments provided.');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.default = ImageData;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _CanvasRenderingContext2D = _interopRequireDefault(require("./CanvasRenderingContext2D"));
|
|
8
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
9
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
10
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
11
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
12
|
+
// Path2D.prototype
|
|
13
|
+
const Path2DFunc = ['addPath'];
|
|
14
|
+
const borrowedFromCanvas = ['closePath', 'moveTo', 'lineTo', 'bezierCurveTo', 'quadraticCurveTo', 'arc', 'arcTo', 'ellipse', 'rect'];
|
|
15
|
+
class Path2D {
|
|
16
|
+
constructor() {
|
|
17
|
+
_defineProperty(this, "_path", []);
|
|
18
|
+
_defineProperty(this, "_events", []);
|
|
19
|
+
_defineProperty(this, "_stackIndex", 0);
|
|
20
|
+
_defineProperty(this, "_transformStack", [[1, 0, 0, 1, 0, 0]]);
|
|
21
|
+
borrowedFromCanvas.forEach(key => {
|
|
22
|
+
this[key] = vi.fn(_CanvasRenderingContext2D.default.prototype[key].bind(this));
|
|
23
|
+
});
|
|
24
|
+
Path2DFunc.forEach(key => {
|
|
25
|
+
this[key] = vi.fn(this[key].bind(this));
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
addPath(path) {
|
|
29
|
+
if (arguments.length < 1) throw new TypeError("Failed to execute 'addPath' on 'Path2D': 1 argument required, but only 0 present.");
|
|
30
|
+
if (!(path instanceof Path2D)) throw new TypeError("Failed to execute 'addPath' on 'Path2D': parameter 1 is not of type 'Path2D'.");
|
|
31
|
+
for (let i = 0; i < path._path.length; i++) this._path.push(path._path[i]);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.default = Path2D;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
8
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
9
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
10
|
+
class TextMetrics {
|
|
11
|
+
constructor(text) {
|
|
12
|
+
_defineProperty(this, "width", 0);
|
|
13
|
+
_defineProperty(this, "actualBoundingBoxLeft", 0);
|
|
14
|
+
_defineProperty(this, "actualBoundingBoxRight", 0);
|
|
15
|
+
_defineProperty(this, "fontBoundingBoxAscent", 0);
|
|
16
|
+
_defineProperty(this, "fontBoundingBoxDescent", 0);
|
|
17
|
+
_defineProperty(this, "actualBoundingBoxAscent", 0);
|
|
18
|
+
_defineProperty(this, "actualBoundingBoxDescent", 0);
|
|
19
|
+
_defineProperty(this, "emHeightAscent", 0);
|
|
20
|
+
_defineProperty(this, "emHeightDescent", 0);
|
|
21
|
+
_defineProperty(this, "hangingBaseline", 0);
|
|
22
|
+
_defineProperty(this, "alphabeticBaseline", 0);
|
|
23
|
+
_defineProperty(this, "ideographicBaseline", 0);
|
|
24
|
+
this.width = text.length;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.default = TextMetrics;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.setupVitestCanvasMock = setupVitestCanvasMock;
|
|
7
|
+
exports.ver = void 0;
|
|
8
|
+
var _window = _interopRequireDefault(require("./window"));
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
/**
|
|
11
|
+
* Created by hustcc 17/12/25.
|
|
12
|
+
* Contract: i@hust.cc
|
|
13
|
+
* Adapted to Vitest by schirrel at March 1 2023
|
|
14
|
+
* Contract: me@schirrel.dev
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// mock global window
|
|
18
|
+
// TODO: Force coverage to ignore this branch
|
|
19
|
+
if (typeof window !== 'undefined') {
|
|
20
|
+
(0, _window.default)(global.window);
|
|
21
|
+
}
|
|
22
|
+
const ver = "1.0.0";
|
|
23
|
+
exports.ver = ver;
|
|
24
|
+
function setupVitestCanvasMock(window) {
|
|
25
|
+
(0, _window.default)(window || global.window);
|
|
26
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = createCanvasEvent;
|
|
7
|
+
/**
|
|
8
|
+
* This function returns a CanvasRenderingContext2DEvent. Whenever an operation would modify the canvas
|
|
9
|
+
* context, this function should be used to generate an "event" that represents that sort of modification.
|
|
10
|
+
* This will be used to mock for snapshots.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* interface CanvasRenderingContext2DEvent {
|
|
14
|
+
* type: string;
|
|
15
|
+
* transform: [number, number, number, number, number, number]; // the resulting current transform
|
|
16
|
+
* props: {
|
|
17
|
+
* // if the event is a property was set, `event.props.value` would be set
|
|
18
|
+
* [propName: string]: any;
|
|
19
|
+
* };
|
|
20
|
+
* }
|
|
21
|
+
*/
|
|
22
|
+
function createCanvasEvent(type, transform, props) {
|
|
23
|
+
return {
|
|
24
|
+
type,
|
|
25
|
+
transform,
|
|
26
|
+
props
|
|
27
|
+
};
|
|
28
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _ImageBitmap = _interopRequireDefault(require("../classes/ImageBitmap"));
|
|
8
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
9
|
+
var _default = vi.fn(function createImageBitmap(img, sx, sy, sWidth, sHeight, options) {
|
|
10
|
+
var length = arguments.length;
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
if (length === 0) return reject(new TypeError("Failed to execute 'createImageBitmap' on 'Window': 1 argument required, but only 0 present."));
|
|
13
|
+
if (length === 3 || length === 4) return reject(new TypeError("Failed to execute 'createImageBitmap' on 'Window': Valid arities are: [1, 2, 5, 6], but " + length + ' arguments provided.'));
|
|
14
|
+
let validImage = false;
|
|
15
|
+
if (img instanceof HTMLImageElement) validImage = true;
|
|
16
|
+
if (img instanceof HTMLVideoElement) validImage = true;
|
|
17
|
+
if (img instanceof HTMLCanvasElement) validImage = true;
|
|
18
|
+
// checking constructor name is the only reliable way to verify the object's constructing class is "blob-like"
|
|
19
|
+
if (img instanceof Blob || img && img.constructor && img.constructor.name === 'Blob') validImage = true;
|
|
20
|
+
if (img instanceof _ImageBitmap.default) validImage = true;
|
|
21
|
+
if (img instanceof ImageData) validImage = true;
|
|
22
|
+
if (!validImage) return reject(new TypeError("Failed to execute 'createImageBitmap' on 'Window': The provided value is not of type '(HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or Blob or ImageData or ImageBitmap or OffscreenCanvas)'"));
|
|
23
|
+
if (length >= 2) {
|
|
24
|
+
let index = 6;
|
|
25
|
+
if (length === 2) {
|
|
26
|
+
index = 2;
|
|
27
|
+
options = sx;
|
|
28
|
+
}
|
|
29
|
+
if (length === 5) options = null;
|
|
30
|
+
if (options !== null && options !== void 0) {
|
|
31
|
+
if (typeof options !== 'object') throw new TypeError("Failed to execute 'createImageBitmap' on 'Window': parameter " + index + " ('options') is not an object.");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (length >= 5) {
|
|
35
|
+
sWidth = Number(sWidth);
|
|
36
|
+
sHeight = Number(sHeight);
|
|
37
|
+
if (sWidth === 0 || !Number.isFinite(sWidth)) return reject(new RangeError('The crop rect width is 0.'));
|
|
38
|
+
if (sHeight === 0 || !Number.isFinite(sHeight)) return reject(new RangeError('The crop rect height is 0.'));
|
|
39
|
+
sWidth = Math.abs(sWidth);
|
|
40
|
+
sHeight = Math.abs(sHeight);
|
|
41
|
+
} else {
|
|
42
|
+
sWidth = img.width || 1;
|
|
43
|
+
sHeight = img.height || 1;
|
|
44
|
+
}
|
|
45
|
+
return resolve(new _ImageBitmap.default(sWidth, sHeight));
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
exports.default = _default;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = mockPrototype;
|
|
7
|
+
function mockPrototype() {
|
|
8
|
+
/**
|
|
9
|
+
* This weakmap is designed to contain all of the generated canvas contexts. It's keys are the
|
|
10
|
+
* jsdom canvases obtained by using the `this` keyword inside the `#getContext('2d')` function
|
|
11
|
+
* call. It's values are the generated `CanvasRenderingContext2D` objects.
|
|
12
|
+
*/
|
|
13
|
+
const generatedContexts = new WeakMap();
|
|
14
|
+
/**
|
|
15
|
+
* Overrides getContext. Every test run will create a new function that overrides the current
|
|
16
|
+
* value of getContext. It attempts to preserve the original getContext function by storing it on
|
|
17
|
+
* the callback as a property.
|
|
18
|
+
*/
|
|
19
|
+
const getContext2D = vi.fn(function getContext2d(type) {
|
|
20
|
+
if (type === '2d') {
|
|
21
|
+
/**
|
|
22
|
+
* Contexts must be idempotent. Once they are generated, they should be returned when
|
|
23
|
+
* getContext() is called on the same canvas object multiple times.
|
|
24
|
+
*/
|
|
25
|
+
if (generatedContexts.has(this)) return generatedContexts.get(this);
|
|
26
|
+
const ctx = new CanvasRenderingContext2D(this);
|
|
27
|
+
generatedContexts.set(this, ctx);
|
|
28
|
+
return ctx;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
if (!this.dataset.internalRequireTest) require('canvas');
|
|
32
|
+
} catch (_unused) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
return getContext2D.internal.call(this, type);
|
|
36
|
+
});
|
|
37
|
+
if (!vi.isMockFunction(HTMLCanvasElement.prototype.getContext)) {
|
|
38
|
+
getContext2D.internal = HTMLCanvasElement.prototype.getContext;
|
|
39
|
+
} else {
|
|
40
|
+
getContext2D.internal = HTMLCanvasElement.prototype.getContext.internal;
|
|
41
|
+
}
|
|
42
|
+
HTMLCanvasElement.prototype.getContext = getContext2D;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* This function technically throws SecurityError at runtime, but it cannot be mocked, because
|
|
46
|
+
* we don't know if the canvas is tainted. These kinds of errors will be silent.
|
|
47
|
+
*/
|
|
48
|
+
const toBlobOverride = vi.fn(function toBlobOverride(callback, mimetype) {
|
|
49
|
+
if (arguments.length < 1) throw new TypeError("Failed to execute 'toBlob' on 'HTMLCanvasElement': 1 argument required, but only 0 present.");
|
|
50
|
+
if (typeof callback !== 'function') throw new TypeError("Failed to execute 'toBlob' on 'HTMLCanvasElement': The callback provided as parameter 1 is not a function.");
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Mime type must be image/jpeg or image/webp exactly for the browser to accept it, otherwise
|
|
54
|
+
* it's image/png.
|
|
55
|
+
*/
|
|
56
|
+
switch (mimetype) {
|
|
57
|
+
case 'image/webp':
|
|
58
|
+
break;
|
|
59
|
+
case 'image/jpeg':
|
|
60
|
+
break;
|
|
61
|
+
default:
|
|
62
|
+
mimetype = 'image/png';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* This section creates a blob of size width * height * 4. This is not actually valid, because
|
|
67
|
+
* jpeg size is variable, and so is png. TODO: Is there a better way to do this?
|
|
68
|
+
*/
|
|
69
|
+
const length = this.width * this.height * 4;
|
|
70
|
+
const data = new Uint8Array(length);
|
|
71
|
+
const blob = new window.Blob([data], {
|
|
72
|
+
type: mimetype
|
|
73
|
+
});
|
|
74
|
+
setTimeout(() => callback(blob), 0);
|
|
75
|
+
});
|
|
76
|
+
if (!vi.isMockFunction(HTMLCanvasElement.prototype.toBlob)) {
|
|
77
|
+
toBlobOverride.internal = HTMLCanvasElement.prototype.toBlob;
|
|
78
|
+
} else {
|
|
79
|
+
toBlobOverride.internal = HTMLCanvasElement.prototype.toBlob.internal;
|
|
80
|
+
}
|
|
81
|
+
HTMLCanvasElement.prototype.toBlob = toBlobOverride;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* This section creates a dataurl with a validated mime type. This is not actually valid, because
|
|
85
|
+
* jpeg size is variable, and so is png. TODO: Is there a better way to do this?
|
|
86
|
+
*/
|
|
87
|
+
const toDataURLOverride = vi.fn(function toDataURLOverride(type, encoderOptions) {
|
|
88
|
+
switch (type) {
|
|
89
|
+
case 'image/jpeg':
|
|
90
|
+
break;
|
|
91
|
+
case 'image/webp':
|
|
92
|
+
break;
|
|
93
|
+
default:
|
|
94
|
+
type = 'image/png';
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* This is the smallest valid data url I could generate.
|
|
99
|
+
*/
|
|
100
|
+
return 'data:' + type + ';base64,00';
|
|
101
|
+
});
|
|
102
|
+
if (!vi.isMockFunction(HTMLCanvasElement.prototype.toDataURL)) {
|
|
103
|
+
toDataURLOverride.internal = HTMLCanvasElement.prototype.toDataURL;
|
|
104
|
+
} else {
|
|
105
|
+
toDataURLOverride.internal = HTMLCanvasElement.prototype.toDataURL.internal;
|
|
106
|
+
}
|
|
107
|
+
HTMLCanvasElement.prototype.toDataURL = toDataURLOverride;
|
|
108
|
+
}
|
package/lib/window.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _Path2D = _interopRequireDefault(require("./classes/Path2D"));
|
|
8
|
+
var _CanvasGradient = _interopRequireDefault(require("./classes/CanvasGradient"));
|
|
9
|
+
var _CanvasPattern = _interopRequireDefault(require("./classes/CanvasPattern"));
|
|
10
|
+
var _CanvasRenderingContext2D = _interopRequireDefault(require("./classes/CanvasRenderingContext2D"));
|
|
11
|
+
var _DOMMatrix = _interopRequireDefault(require("./classes/DOMMatrix"));
|
|
12
|
+
var _ImageData = _interopRequireDefault(require("./classes/ImageData"));
|
|
13
|
+
var _TextMetrics = _interopRequireDefault(require("./classes/TextMetrics"));
|
|
14
|
+
var _ImageBitmap = _interopRequireDefault(require("./classes/ImageBitmap"));
|
|
15
|
+
var _prototype = _interopRequireDefault(require("./mock/prototype"));
|
|
16
|
+
var _createImageBitmap = _interopRequireDefault(require("./mock/createImageBitmap"));
|
|
17
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
18
|
+
/**
|
|
19
|
+
* Created by hustcc 17/12/25.
|
|
20
|
+
* Contract: i@hust.cc
|
|
21
|
+
* Adapted to Vitest by schirrel at March 1 2023
|
|
22
|
+
* Contract: me@schirrel.dev
|
|
23
|
+
*/
|
|
24
|
+
var _default = win => {
|
|
25
|
+
const d = win.document;
|
|
26
|
+
const f = win.document.createElement;
|
|
27
|
+
|
|
28
|
+
// jsdom@11.6.2 console.error in Function getContext();
|
|
29
|
+
// https://github.com/jsdom/jsdom/blob/4c7698f760fc64f20b2a0ddff450eddbdd193176/lib/jsdom/living/nodes/HTMLCanvasElement-impl.js#L55-L58
|
|
30
|
+
// console.error will make ci error.
|
|
31
|
+
// try {
|
|
32
|
+
// // get the context 2d.
|
|
33
|
+
// const ctx = d.createElement('canvas').getContext('2d');
|
|
34
|
+
//
|
|
35
|
+
// // if canvas and context2d all exist, means mock is not needed.
|
|
36
|
+
// if (ctx) {
|
|
37
|
+
// console.warn('Context 2d of canvas is exist! No need to mock');
|
|
38
|
+
// return win;
|
|
39
|
+
// }
|
|
40
|
+
// } catch (_) {
|
|
41
|
+
// // catch the throw `Error: Not implemented: HTMLCanvasElement.prototype.getContext`
|
|
42
|
+
// // https://github.com/jsdom/jsdom/blob/4c7698f760fc64f20b2a0ddff450eddbdd193176/lib/jsdom/living/nodes/HTMLCanvasElement-impl.js
|
|
43
|
+
// // when throw error, means mock is needed.
|
|
44
|
+
// // code continue
|
|
45
|
+
// }
|
|
46
|
+
// if ctx not exist, mock it.
|
|
47
|
+
// just mock canvas creator.
|
|
48
|
+
/*
|
|
49
|
+
win.document.createElement = param => param.toString().toLowerCase() === 'canvas'
|
|
50
|
+
? createCanvas('canvas')
|
|
51
|
+
: f.call(d, param);
|
|
52
|
+
*/
|
|
53
|
+
// if not exist, then mock it.
|
|
54
|
+
if (!win.Path2D) win.Path2D = _Path2D.default;
|
|
55
|
+
if (!win.CanvasGradient) win.CanvasGradient = _CanvasGradient.default;
|
|
56
|
+
if (!win.CanvasPattern) win.CanvasPattern = _CanvasPattern.default;
|
|
57
|
+
if (!win.CanvasRenderingContext2D) win.CanvasRenderingContext2D = _CanvasRenderingContext2D.default;
|
|
58
|
+
if (!win.DOMMatrix) win.DOMMatrix = _DOMMatrix.default;
|
|
59
|
+
if (!win.ImageData) win.ImageData = _ImageData.default;
|
|
60
|
+
if (!win.TextMetrics) win.TextMetrics = _TextMetrics.default;
|
|
61
|
+
if (!win.ImageBitmap) win.ImageBitmap = _ImageBitmap.default;
|
|
62
|
+
if (!win.createImageBitmap) win.createImageBitmap = _createImageBitmap.default;
|
|
63
|
+
(0, _prototype.default)();
|
|
64
|
+
return win;
|
|
65
|
+
};
|
|
66
|
+
exports.default = _default;
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ohos-ports/vi-canvas-mock",
|
|
3
|
+
"version": "1.0.0-beta.0",
|
|
4
|
+
"description": "Mock a canvas in your vitest tests.",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"types": "types/index.d.ts",
|
|
7
|
+
"scripts": {},
|
|
8
|
+
"dependencies": {
|
|
9
|
+
"cssfontparser": "^1.2.1",
|
|
10
|
+
"moo-color": "^1.0.2"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/ohos-ports/ohos-ports.git",
|
|
15
|
+
"directory": "ports/vi-canvas-mock/1.0.0"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"mock",
|
|
19
|
+
"vitest",
|
|
20
|
+
"vitest-mock",
|
|
21
|
+
"canvas",
|
|
22
|
+
"test",
|
|
23
|
+
"unit"
|
|
24
|
+
],
|
|
25
|
+
"files": [
|
|
26
|
+
"CHANGELOG.md",
|
|
27
|
+
"lib/",
|
|
28
|
+
"types/"
|
|
29
|
+
],
|
|
30
|
+
"author": "schirrel",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/ohos-ports/ohos-ports/issues"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://github.com/schirrel/vi-canvas-mock#readme"
|
|
36
|
+
}
|