From a13c5fbc7b614c804317e66a945080a67a44fa26 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Sat, 22 Aug 2026 09:14:41 +0800 Subject: [PATCH] Apply same blank png logic to OffscreenCanvas Move all of the blank png logic to OffscreenCanvas and apply it to the existing convertToBlob. I agree it doesn't really make that much sense here, but Canvas already references OffscreenCanvas, so given its current usage, it's the most ergonomic place to put it. Canvas's ToBlobCallback now runs microtask after executing the callback and lazily creates the Blob for simpler blob lifecycle. --- .../tests/canvas/canvas_serialization.html | 22 ++++- .../tests/canvas/offscreen_canvas.html | 15 ++- src/browser/webapi/canvas/OffscreenCanvas.zig | 39 +++++++- src/browser/webapi/element/html/Canvas.zig | 97 +++++++------------ 4 files changed, 106 insertions(+), 67 deletions(-) diff --git a/src/browser/tests/canvas/canvas_serialization.html b/src/browser/tests/canvas/canvas_serialization.html index 38a155bd9..37972f340 100644 --- a/src/browser/tests/canvas/canvas_serialization.html +++ b/src/browser/tests/canvas/canvas_serialization.html @@ -81,6 +81,8 @@ testing.expectEqual('function', typeof canvas.toBlob); canvas.toBlob(function(blob) { + // A thrown TypeError in here is only logged, so guard before dereferencing. + testing.expectEqual(true, blob instanceof Blob); testing.expectEqual('image/png', blob.type); testing.expectEqual(67, blob.size); }); @@ -92,8 +94,26 @@ const canvas = document.getElementById('c'); let called = false; canvas.toBlob(function() { called = true; }); - // The callback runs from a task, never synchronously. + // The callback runs from a task, never synchronously... testing.expectEqual(false, called); + // ...but before any task queued after it. + setTimeout(function() { testing.expectEqual(true, called); }, 0); +} + + + diff --git a/src/browser/tests/canvas/offscreen_canvas.html b/src/browser/tests/canvas/offscreen_canvas.html index c7aa2067a..24c1277fe 100644 --- a/src/browser/tests/canvas/offscreen_canvas.html +++ b/src/browser/tests/canvas/offscreen_canvas.html @@ -43,14 +43,25 @@ const canvas = new OffscreenCanvas(64, 64); const promise = canvas.convertToBlob(); testing.expectEqual(true, promise instanceof Promise); - // The promise should resolve to a Blob (even if empty) + // The same blank PNG as HTMLCanvasElement.toBlob. promise.then(blob => { testing.expectEqual(true, blob instanceof Blob); - testing.expectEqual(blob.size, 0); // Empty since no rendering + testing.expectEqual('image/png', blob.type); + testing.expectEqual(67, blob.size); }); } + +