diff --git a/src/browser/webapi/element/html/Canvas.zig b/src/browser/webapi/element/html/Canvas.zig
index 13002f66..c01fb651 100644
--- a/src/browser/webapi/element/html/Canvas.zig
+++ b/src/browser/webapi/element/html/Canvas.zig
@@ -30,6 +30,13 @@ const OffscreenCanvas = @import("../../canvas/OffscreenCanvas.zig");
const Canvas = @This();
_proto: *HtmlElement,
+/// Cached context type. Once set, requesting a different type returns null (per spec).
+_context_type: ContextType = .none,
+/// Cached 2D rendering context (same object returned on repeated getContext("2d") calls).
+_ctx_2d: ?*CanvasRenderingContext2D = null,
+
+const ContextType = enum { none, @"2d", webgl };
+
pub fn asElement(self: *Canvas) *Element {
return self._proto._proto;
}
@@ -69,12 +76,23 @@ const DrawingContext = union(enum) {
pub fn getContext(self: *Canvas, context_type: []const u8, page: *Page) !?DrawingContext {
if (std.mem.eql(u8, context_type, "2d")) {
+ // Return cached context if available.
+ if (self._ctx_2d) |cached| return .{ .@"2d" = cached };
+ // Per spec: return null if a different context type was already requested.
+ if (self._context_type != .none) return null;
+
const ctx = try page._factory.create(CanvasRenderingContext2D{ ._canvas = self });
+ self._ctx_2d = ctx;
+ self._context_type = .@"2d";
return .{ .@"2d" = ctx };
}
if (std.mem.eql(u8, context_type, "webgl") or std.mem.eql(u8, context_type, "experimental-webgl")) {
+ // Per spec: return null if a different context type was already requested.
+ if (self._context_type != .none and self._context_type != .webgl) return null;
+
const ctx = try page._factory.create(WebGLRenderingContext{});
+ self._context_type = .webgl;
return .{ .webgl = ctx };
}