Description
Issue or Feature
The Image
implementation lacks an onload
call (at least based on https://github.com/Automattic/node-canvas/blob/master/lib/image.js), making it impossible to use it "the normal way" where the onload is our signal that image data is available and now we can do something with that data.
(onload
on the HTML side = incredibly bad, do not use. onload
on the JS side: unfortunately still extremely necessary for Image
, WebSocket
, etc. etc. it never went away in JS land and we kept reinforcing it by introducing new object types that kept the onload
and onerror
pattern firmly alive right up to today =S)
Steps to Reproduce
const IN_BROWSER = !!globalThis.document;
let Image = globalThis.Image;
let createCanvas = (w, h) => {
const cvs = globalThis.document.createElement(`canvas`);
cvs.width = w;
cvs.heigh = h;
return cvs;
};
if (!IN_BROWSER) {
const { createCanvas as create, Image as ImageClass } = await import(`canvas`);
createCanvas = create;
Image = ImageClass;
}
const img = new Image();
img.src = "./some/path.png";
img.onload = () => {
// actually do things here, because we like idempotent code that just runs,
// irrespective of whether it's in the browser or Node.js
const myCanvas = createCanvas(...);
};
The above code won't actually do anything for node-canvas
(but will run perfectly fine in the browser) because the shimmed Image
has no code to trigger the onload
"callback".
Suggested fix
Add an onload
property with getter/setter:
Object.defineProperty(Image.prototype, 'onload', {
get: function() { return this._onload },
set: function(fn) {
this._onload = fn;
if (this.src) fn();
}
);
And update setSource
to something like
function setSource (img, src, origSrc) {
SetSource.call(img, src)
img._originalSource = origSrc
img._onload?.()
}