diff --git a/Sources/WebAPIKit/Generated.swift b/Sources/WebAPIKit/Generated.swift index 0203bcad..899f294f 100644 --- a/Sources/WebAPIKit/Generated.swift +++ b/Sources/WebAPIKit/Generated.swift @@ -11886,10 +11886,7 @@ public class HTMLCanvasElement: HTMLElement { @ReadWriteAttribute public var height: UInt32 - @inlinable public func getContext(contextId: String, options: JSValue? = nil) -> RenderingContext? { - let this = jsObject - return this[Strings.getContext].function!(this: this, arguments: [contextId.jsValue, options?.jsValue ?? .undefined]).fromJSValue()! - } + // XXX: member 'getContext' is ignored @inlinable public func toDataURL(type: String? = nil, quality: JSValue? = nil) -> String { let this = jsObject @@ -18099,10 +18096,7 @@ public class OffscreenCanvas: EventTarget { @ReadWriteAttribute public var height: UInt64 - @inlinable public func getContext(contextId: OffscreenRenderingContextId, options: JSValue? = nil) -> OffscreenRenderingContext? { - let this = jsObject - return this[Strings.getContext].function!(this: this, arguments: [contextId.jsValue, options?.jsValue ?? .undefined]).fromJSValue()! - } + // XXX: member 'getContext' is ignored @inlinable public func transferToImageBitmap() -> ImageBitmap { let this = jsObject @@ -18147,27 +18141,6 @@ public class OffscreenCanvasRenderingContext2D: JSBridgedClass, CanvasState, Can public var canvas: OffscreenCanvas } -public enum OffscreenRenderingContextId: JSString, JSValueCompatible { - case _2d = "2d" - case bitmaprenderer = "bitmaprenderer" - case webgl = "webgl" - case webgl2 = "webgl2" - case webgpu = "webgpu" - - @inlinable public static func construct(from jsValue: JSValue) -> Self? { - if let string = jsValue.jsString { - return Self(rawValue: string) - } - return nil - } - - @inlinable public init?(string: String) { - self.init(rawValue: JSString(string)) - } - - @inlinable public var jsValue: JSValue { rawValue.jsValue } -} - public class OptionalEffectTiming: BridgedDictionary { public convenience init(delay: Double, endDelay: Double, fill: FillMode, iterationStart: Double, iterations: Double, duration: Double_or_String, direction: PlaybackDirection, easing: String) { let object = JSObject.global[Strings.Object].function!.new() @@ -28619,7 +28592,6 @@ public enum console { @usableFromInline static let getClientRects: JSString = "getClientRects" @usableFromInline static let getComputedTiming: JSString = "getComputedTiming" @usableFromInline static let getConstraints: JSString = "getConstraints" - @usableFromInline static let getContext: JSString = "getContext" @usableFromInline static let getContextAttributes: JSString = "getContextAttributes" @usableFromInline static let getCueById: JSString = "getCueById" @usableFromInline static let getCurrentTexture: JSString = "getCurrentTexture" @@ -32066,90 +32038,6 @@ public enum Node_or_String: JSValueCompatible, Any_Node_or_String { } } -public protocol Any_OffscreenRenderingContext: ConvertibleToJSValue {} -extension GPUCanvasContext: Any_OffscreenRenderingContext {} -extension ImageBitmapRenderingContext: Any_OffscreenRenderingContext {} -extension OffscreenCanvasRenderingContext2D: Any_OffscreenRenderingContext {} -extension WebGL2RenderingContext: Any_OffscreenRenderingContext {} -extension WebGLRenderingContext: Any_OffscreenRenderingContext {} - -public enum OffscreenRenderingContext: JSValueCompatible, Any_OffscreenRenderingContext { - case gpuCanvasContext(GPUCanvasContext) - case imageBitmapRenderingContext(ImageBitmapRenderingContext) - case offscreenCanvasRenderingContext2D(OffscreenCanvasRenderingContext2D) - case webGL2RenderingContext(WebGL2RenderingContext) - case webGLRenderingContext(WebGLRenderingContext) - - public var gpuCanvasContext: GPUCanvasContext? { - switch self { - case let .gpuCanvasContext(gpuCanvasContext): return gpuCanvasContext - default: return nil - } - } - - public var imageBitmapRenderingContext: ImageBitmapRenderingContext? { - switch self { - case let .imageBitmapRenderingContext(imageBitmapRenderingContext): return imageBitmapRenderingContext - default: return nil - } - } - - public var offscreenCanvasRenderingContext2D: OffscreenCanvasRenderingContext2D? { - switch self { - case let .offscreenCanvasRenderingContext2D(offscreenCanvasRenderingContext2D): return offscreenCanvasRenderingContext2D - default: return nil - } - } - - public var webGL2RenderingContext: WebGL2RenderingContext? { - switch self { - case let .webGL2RenderingContext(webGL2RenderingContext): return webGL2RenderingContext - default: return nil - } - } - - public var webGLRenderingContext: WebGLRenderingContext? { - switch self { - case let .webGLRenderingContext(webGLRenderingContext): return webGLRenderingContext - default: return nil - } - } - - public static func construct(from value: JSValue) -> Self? { - if let gpuCanvasContext: GPUCanvasContext = value.fromJSValue() { - return .gpuCanvasContext(gpuCanvasContext) - } - if let imageBitmapRenderingContext: ImageBitmapRenderingContext = value.fromJSValue() { - return .imageBitmapRenderingContext(imageBitmapRenderingContext) - } - if let offscreenCanvasRenderingContext2D: OffscreenCanvasRenderingContext2D = value.fromJSValue() { - return .offscreenCanvasRenderingContext2D(offscreenCanvasRenderingContext2D) - } - if let webGL2RenderingContext: WebGL2RenderingContext = value.fromJSValue() { - return .webGL2RenderingContext(webGL2RenderingContext) - } - if let webGLRenderingContext: WebGLRenderingContext = value.fromJSValue() { - return .webGLRenderingContext(webGLRenderingContext) - } - return nil - } - - public var jsValue: JSValue { - switch self { - case let .gpuCanvasContext(gpuCanvasContext): - return gpuCanvasContext.jsValue - case let .imageBitmapRenderingContext(imageBitmapRenderingContext): - return imageBitmapRenderingContext.jsValue - case let .offscreenCanvasRenderingContext2D(offscreenCanvasRenderingContext2D): - return offscreenCanvasRenderingContext2D.jsValue - case let .webGL2RenderingContext(webGL2RenderingContext): - return webGL2RenderingContext.jsValue - case let .webGLRenderingContext(webGLRenderingContext): - return webGLRenderingContext.jsValue - } - } -} - public protocol Any_Path2D_or_String: ConvertibleToJSValue {} extension Path2D: Any_Path2D_or_String {} extension String: Any_Path2D_or_String {} @@ -32276,90 +32164,6 @@ public enum ReadableStreamReader: JSValueCompatible, Any_ReadableStreamReader { } } -public protocol Any_RenderingContext: ConvertibleToJSValue {} -extension CanvasRenderingContext2D: Any_RenderingContext {} -extension GPUCanvasContext: Any_RenderingContext {} -extension ImageBitmapRenderingContext: Any_RenderingContext {} -extension WebGL2RenderingContext: Any_RenderingContext {} -extension WebGLRenderingContext: Any_RenderingContext {} - -public enum RenderingContext: JSValueCompatible, Any_RenderingContext { - case canvasRenderingContext2D(CanvasRenderingContext2D) - case gpuCanvasContext(GPUCanvasContext) - case imageBitmapRenderingContext(ImageBitmapRenderingContext) - case webGL2RenderingContext(WebGL2RenderingContext) - case webGLRenderingContext(WebGLRenderingContext) - - public var canvasRenderingContext2D: CanvasRenderingContext2D? { - switch self { - case let .canvasRenderingContext2D(canvasRenderingContext2D): return canvasRenderingContext2D - default: return nil - } - } - - public var gpuCanvasContext: GPUCanvasContext? { - switch self { - case let .gpuCanvasContext(gpuCanvasContext): return gpuCanvasContext - default: return nil - } - } - - public var imageBitmapRenderingContext: ImageBitmapRenderingContext? { - switch self { - case let .imageBitmapRenderingContext(imageBitmapRenderingContext): return imageBitmapRenderingContext - default: return nil - } - } - - public var webGL2RenderingContext: WebGL2RenderingContext? { - switch self { - case let .webGL2RenderingContext(webGL2RenderingContext): return webGL2RenderingContext - default: return nil - } - } - - public var webGLRenderingContext: WebGLRenderingContext? { - switch self { - case let .webGLRenderingContext(webGLRenderingContext): return webGLRenderingContext - default: return nil - } - } - - public static func construct(from value: JSValue) -> Self? { - if let canvasRenderingContext2D: CanvasRenderingContext2D = value.fromJSValue() { - return .canvasRenderingContext2D(canvasRenderingContext2D) - } - if let gpuCanvasContext: GPUCanvasContext = value.fromJSValue() { - return .gpuCanvasContext(gpuCanvasContext) - } - if let imageBitmapRenderingContext: ImageBitmapRenderingContext = value.fromJSValue() { - return .imageBitmapRenderingContext(imageBitmapRenderingContext) - } - if let webGL2RenderingContext: WebGL2RenderingContext = value.fromJSValue() { - return .webGL2RenderingContext(webGL2RenderingContext) - } - if let webGLRenderingContext: WebGLRenderingContext = value.fromJSValue() { - return .webGLRenderingContext(webGLRenderingContext) - } - return nil - } - - public var jsValue: JSValue { - switch self { - case let .canvasRenderingContext2D(canvasRenderingContext2D): - return canvasRenderingContext2D.jsValue - case let .gpuCanvasContext(gpuCanvasContext): - return gpuCanvasContext.jsValue - case let .imageBitmapRenderingContext(imageBitmapRenderingContext): - return imageBitmapRenderingContext.jsValue - case let .webGL2RenderingContext(webGL2RenderingContext): - return webGL2RenderingContext.jsValue - case let .webGLRenderingContext(webGLRenderingContext): - return webGLRenderingContext.jsValue - } - } -} - public protocol Any_RequestInfo: ConvertibleToJSValue {} extension Request: Any_RequestInfo {} extension String: Any_RequestInfo {} diff --git a/Sources/WebAPIKit/RenderingContext.swift b/Sources/WebAPIKit/RenderingContext.swift new file mode 100644 index 00000000..81628ccf --- /dev/null +++ b/Sources/WebAPIKit/RenderingContext.swift @@ -0,0 +1,69 @@ +import JavaScriptKit + +public protocol RenderingContext: JSValueCompatible { + /// Textual identifier of this context type, passed to `getContext` under the hood. + static var contextID: JSString { get } +} + +extension GPUCanvasContext: RenderingContext { + public static var contextID: JSString { "webgpu" } +} + +extension ImageBitmapRenderingContext: RenderingContext { + public static var contextID: JSString { "bitmaprenderer" } +} + +extension CanvasRenderingContext2D: RenderingContext { + public static var contextID: JSString { "2d" } +} + +extension WebGL2RenderingContext: RenderingContext { + public static var contextID: JSString { "webgl2" } +} + +extension WebGLRenderingContext: RenderingContext { + public static var contextID: JSString { "webgl" } +} + +public protocol OffscreenRenderingContext: JSValueCompatible { + static var contextID: JSString { get } +} + +extension GPUCanvasContext: OffscreenRenderingContext {} +extension ImageBitmapRenderingContext: OffscreenRenderingContext {} +extension CanvasRenderingContext2D: OffscreenRenderingContext {} +extension WebGL2RenderingContext: OffscreenRenderingContext {} +extension WebGLRenderingContext: OffscreenRenderingContext {} +extension OffscreenCanvasRenderingContext2D: OffscreenRenderingContext { + public static var contextID: JSString { "2d" } +} + +extension Strings { + @usableFromInline static let getContext: JSString = "getContext" +} + +public extension HTMLCanvasElement { + @inlinable func getContext( + _ contextType: Context.Type, + options: JSValue? = nil + ) -> Context? { + let this = jsObject + return this[Strings.getContext].function!( + this: this, + arguments: [contextType.contextID.jsValue, options?.jsValue ?? .undefined] + ).fromJSValue()! + } +} + +public extension OffscreenCanvas { + @inlinable func getContext( + _ contextType: Context.Type, + options: JSValue? = nil + ) -> Context? { + let this = jsObject + return this[Strings.getContext].function!( + this: this, + arguments: [contextType.contextID.jsValue, options?.jsValue ?? .undefined] + ).fromJSValue()! + } +} diff --git a/Sources/WebAPIKitDemo/WebGLDemo.swift b/Sources/WebAPIKitDemo/WebGLDemo.swift index 454c8c63..b73594c4 100644 --- a/Sources/WebAPIKitDemo/WebGLDemo.swift +++ b/Sources/WebAPIKitDemo/WebGLDemo.swift @@ -117,7 +117,10 @@ func runWebGLDemo() { // Get A WebGL context let canvas = HTMLCanvasElement(from: document.createElement(localName: "canvas"))! _ = document.body?.appendChild(node: canvas) - let context = canvas.getContext(contextId: "webgl2")!.webGL2RenderingContext! + guard let context = canvas.getContext(WebGL2RenderingContext.self) else { + console.error(data: "Failed to create WebGL2 rendering context") + return + } // create GLSL shaders, upload the GLSL source, compile the shaders guard diff --git a/Sources/WebIDLToSwift/IDLBuilder.swift b/Sources/WebIDLToSwift/IDLBuilder.swift index 0ec86fc2..2d54b304 100644 --- a/Sources/WebIDLToSwift/IDLBuilder.swift +++ b/Sources/WebIDLToSwift/IDLBuilder.swift @@ -25,6 +25,9 @@ enum IDLBuilder { "BigInt64Array_or_BigUint64Array_or_DataView_or_Float32Array_or_Float64Array_or_Int16Array_or_Int32Array_or_Int8Array_or_Uint16Array_or_Uint32Array_or_Uint8Array_or_Uint8ClampedArray", // RotationMatrixType "DOMMatrix_or_Float32Array_or_Float64Array", + "RenderingContext", + "OffscreenRenderingContext", + "OffscreenRenderingContextId", ] static func writeFile(path: String, content: String) throws { @@ -58,7 +61,7 @@ enum IDLBuilder { "FileSystemEntry": ["getParent"], "FileSystemFileEntry": ["file"], "Geolocation": ["getCurrentPosition", "watchPosition"], - "HTMLCanvasElement": ["toBlob"], + "HTMLCanvasElement": ["toBlob", "getContext"], "HTMLVideoElement": ["requestVideoFrameCallback"], "IntersectionObserver": [""], "LayoutWorkletGlobalScope": ["registerLayout"], @@ -97,6 +100,7 @@ enum IDLBuilder { "HTMLMediaElement": ["srcObject"], "Blob": ["stream"], "Body": ["body"], + "OffscreenCanvas": ["getContext"], ], types: merged.types )) {