Don't process images until their 'load' event has been emitted

In IE11, the 'complete' property on an image is set before the image is
fully initialized (so it still has 0x0 dimensions). So rather than
relying on this property, always just wait for the 'load' event.
This commit is contained in:
Jesper Dam 2014-07-11 15:18:22 +02:00 committed by Jesper Alf Dam
parent e1d50c8c10
commit b5d205d58e
2 changed files with 13 additions and 10 deletions

View File

@ -375,13 +375,16 @@ export default class Display {
imageRect(x, y, mime, arr) {
const img = new Image();
img._noVNC_display = this;
img.src = "data: " + mime + ";base64," + Base64.encode(arr);
img.addEventListener('load', this._resume_renderQ);
this._renderQ_push({
'type': 'img',
'img': img,
'x': x,
'y': y
});
return img;
}
// start updating a tile
@ -602,6 +605,7 @@ export default class Display {
// "this" is the object that is ready, not the
// display object
this.removeEventListener('load', this._noVNC_display._resume_renderQ);
this.completeAndLoaded = true;
this._noVNC_display._scan_renderQ();
}
@ -629,11 +633,9 @@ export default class Display {
this.blitRgbxImage(a.x, a.y, a.width, a.height, a.data, 0, true);
break;
case 'img':
if (a.img.complete) {
if (a.img.completeAndLoaded) {
this.drawImage(a.img, a.x, a.y);
} else {
a.img._noVNC_display = this;
a.img.addEventListener('load', this._resume_renderQ);
// We need to wait for this image to 'load'
// to keep things in-order
ready = false;

View File

@ -321,12 +321,15 @@ describe('Display/Canvas Helper', function () {
});
it('should support drawing images via #imageRect', function (done) {
display.imageRect(0, 0, "image/png", make_image_png(checked_data));
const img = display.imageRect(0, 0, "image/png", make_image_png(checked_data));
img.dispatchEvent(new CustomEvent('load', {}));
display.flip();
display.onflush = () => {
expect(display).to.have.displayed(checked_data);
expect(img.completeAndLoaded).to.equal(true);
done();
};
display.flush();
});
@ -422,7 +425,7 @@ describe('Display/Canvas Helper', function () {
});
it('should wait until an image is loaded to attempt to draw it and the rest of the queue', function () {
const img = { complete: false, addEventListener: sinon.spy() };
const img = { completeAndLoaded: false };
display._renderQ = [{ type: 'img', x: 3, y: 4, img: img },
{ type: 'fill', x: 1, y: 2, width: 3, height: 4, color: 5 }];
display.drawImage = sinon.spy();
@ -431,13 +434,11 @@ describe('Display/Canvas Helper', function () {
display._scan_renderQ();
expect(display.drawImage).to.not.have.been.called;
expect(display.fillRect).to.not.have.been.called;
expect(img.addEventListener).to.have.been.calledOnce;
display._renderQ[0].img.complete = true;
display._renderQ[0].img.completeAndLoaded = true;
display._scan_renderQ();
expect(display.drawImage).to.have.been.calledOnce;
expect(display.fillRect).to.have.been.calledOnce;
expect(img.addEventListener).to.have.been.calledOnce;
});
it('should call callback when queue is flushed', function () {
@ -478,9 +479,9 @@ describe('Display/Canvas Helper', function () {
it('should draw an image from an image object on type "img" (if complete)', function () {
display.drawImage = sinon.spy();
display._renderQ_push({ type: 'img', x: 3, y: 4, img: { complete: true } });
display._renderQ_push({ type: 'img', x: 3, y: 4, img: { completeAndLoaded: true } });
expect(display.drawImage).to.have.been.calledOnce;
expect(display.drawImage).to.have.been.calledWith({ complete: true }, 3, 4);
expect(display.drawImage).to.have.been.calledWith({ completeAndLoaded: true }, 3, 4);
});
});
});