diff --git a/inputfiles/overridingTypes.jsonc b/inputfiles/overridingTypes.jsonc index 0460a94ed..d22bac434 100644 --- a/inputfiles/overridingTypes.jsonc +++ b/inputfiles/overridingTypes.jsonc @@ -38,27 +38,6 @@ } } }, - "GlobalEventHandlers": { - "properties": { - "property": { - "onerror": { - "overrideType": "OnErrorEventHandler" - }, - "ontouchcancel": { - "optional": true - }, - "ontouchend": { - "optional": true - }, - "ontouchmove": { - "optional": true - }, - "ontouchstart": { - "optional": true - } - } - } - }, "HTMLOrSVGElement": { "properties": { "property": { diff --git a/inputfiles/patches/events.kdl b/inputfiles/patches/events.kdl index 7772dd592..58fa23520 100644 --- a/inputfiles/patches/events.kdl +++ b/inputfiles/patches/events.kdl @@ -1,98 +1,99 @@ interface-mixin AbstractWorker { - event error type=ErrorEvent + event error type=ErrorEvent } interface-mixin DocumentAndElementEventHandlers { - event copy type=ClipboardEvent - event cut type=ClipboardEvent - event paste type=ClipboardEvent + event copy type=ClipboardEvent + event cut type=ClipboardEvent + event paste type=ClipboardEvent } interface-mixin GlobalEventHandlers { - event abort type=UIEvent - event auxclick type=PointerEvent - event beforeinput type=InputEvent - event beforetoggle type=ToggleEvent - event blur type=FocusEvent - event click type=PointerEvent - event compositionend type=CompositionEvent - event compositionstart type=CompositionEvent - event compositionupdate type=CompositionEvent - event contextmenu type=PointerEvent - event dblclick type=MouseEvent - event drag type=DragEvent - event dragend type=DragEvent - event dragenter type=DragEvent - event dragleave type=DragEvent - event dragover type=DragEvent - event dragstart type=DragEvent - event drop type=DragEvent - event error type=ErrorEvent - event focus type=FocusEvent - event focusin type=FocusEvent - event focusout type=FocusEvent - event formdata type=FormDataEvent - event keydown type=KeyboardEvent - event keypress type=KeyboardEvent - event keyup type=KeyboardEvent - event mousedown type=MouseEvent - event mouseenter type=MouseEvent - event mouseleave type=MouseEvent - event mousemove type=MouseEvent - event mouseout type=MouseEvent - event mouseover type=MouseEvent - event mouseup type=MouseEvent - event progress type=ProgressEvent - event resize type=UIEvent - event securitypolicyviolation type=SecurityPolicyViolationEvent - event submit type=SubmitEvent - event toggle type=ToggleEvent - event wheel type=WheelEvent - event animationcancel type=AnimationEvent - event animationend type=AnimationEvent - event animationiteration type=AnimationEvent - event animationstart type=AnimationEvent - event cut type=ClipboardEvent - event copy type=ClipboardEvent - event paste type=ClipboardEvent - event gotpointercapture type=PointerEvent - event lostpointercapture type=PointerEvent - event pointercancel type=PointerEvent - event pointerdown type=PointerEvent - event pointerenter type=PointerEvent - event pointerleave type=PointerEvent - event pointermove type=PointerEvent - event pointerout type=PointerEvent - event pointerover type=PointerEvent - event pointerup type=PointerEvent - event touchcancel type=TouchEvent - event touchend type=TouchEvent - event touchmove type=TouchEvent - event touchstart type=TouchEvent - event transitionrun type=TransitionEvent - event transitionstart type=TransitionEvent - event transitionend type=TransitionEvent - event transitioncancel type=TransitionEvent + event abort type=UIEvent + event auxclick type=PointerEvent + event beforeinput type=InputEvent + event beforetoggle type=ToggleEvent + event blur type=FocusEvent + event click type=PointerEvent + event compositionend type=CompositionEvent + event compositionstart type=CompositionEvent + event compositionupdate type=CompositionEvent + event contextmenu type=PointerEvent + event dblclick type=MouseEvent + event drag type=DragEvent + event dragend type=DragEvent + event dragenter type=DragEvent + event dragleave type=DragEvent + event dragover type=DragEvent + event dragstart type=DragEvent + event drop type=DragEvent + event error type=ErrorEvent + event focus type=FocusEvent + event focusin type=FocusEvent + event focusout type=FocusEvent + event formdata type=FormDataEvent + event keydown type=KeyboardEvent + event keypress type=KeyboardEvent + event keyup type=KeyboardEvent + event mousedown type=MouseEvent + event mouseenter type=MouseEvent + event mouseleave type=MouseEvent + event mousemove type=MouseEvent + event mouseout type=MouseEvent + event mouseover type=MouseEvent + event mouseup type=MouseEvent + event progress type=ProgressEvent + event resize type=UIEvent + event securitypolicyviolation type=SecurityPolicyViolationEvent + event submit type=SubmitEvent + event toggle type=ToggleEvent + event wheel type=WheelEvent + event animationcancel type=AnimationEvent + event animationend type=AnimationEvent + event animationiteration type=AnimationEvent + event animationstart type=AnimationEvent + event cut type=ClipboardEvent + event copy type=ClipboardEvent + event paste type=ClipboardEvent + event gotpointercapture type=PointerEvent + event lostpointercapture type=PointerEvent + event pointercancel type=PointerEvent + event pointerdown type=PointerEvent + event pointerenter type=PointerEvent + event pointerleave type=PointerEvent + event pointermove type=PointerEvent + event pointerout type=PointerEvent + event pointerover type=PointerEvent + event pointerup type=PointerEvent + event touchcancel type=TouchEvent + event touchend type=TouchEvent + event touchmove type=TouchEvent + event touchstart type=TouchEvent + event transitionrun type=TransitionEvent + event transitionstart type=TransitionEvent + event transitionend type=TransitionEvent + event transitioncancel type=TransitionEvent + property onerror overrideType=OnErrorEventHandler } interface-mixin MessageEventTarget { - event message type=MessageEvent - event messageerror type=MessageEvent + event message type=MessageEvent + event messageerror type=MessageEvent } interface-mixin WindowEventHandlers { - event beforeunload type=BeforeUnloadEvent - event gamepadconnected type=GamepadEvent - event gamepaddisconnected type=GamepadEvent - event hashchange type=HashChangeEvent - event message type=MessageEvent - event messageerror type=MessageEvent - event pagehide type=PageTransitionEvent - event pagereveal type=PageRevealEvent - event pageshow type=PageTransitionEvent - event pageswap type=PageSwapEvent - event popstate type=PopStateEvent - event rejectionhandled type=PromiseRejectionEvent - event storage type=StorageEvent - event unhandledrejection type=PromiseRejectionEvent + event beforeunload type=BeforeUnloadEvent + event gamepadconnected type=GamepadEvent + event gamepaddisconnected type=GamepadEvent + event hashchange type=HashChangeEvent + event message type=MessageEvent + event messageerror type=MessageEvent + event pagehide type=PageTransitionEvent + event pagereveal type=PageRevealEvent + event pageshow type=PageTransitionEvent + event pageswap type=PageSwapEvent + event popstate type=PopStateEvent + event rejectionhandled type=PromiseRejectionEvent + event storage type=StorageEvent + event unhandledrejection type=PromiseRejectionEvent } diff --git a/inputfiles/patches/touch-events.kdl b/inputfiles/patches/touch-events.kdl new file mode 100644 index 000000000..e687a40e2 --- /dev/null +++ b/inputfiles/patches/touch-events.kdl @@ -0,0 +1,8 @@ +interface-mixin GlobalEventHandlers { + // Touch event handlers are intentionally hidden in non-mobile web browsers. + // See w3c.github.io/touch-events#dfn-expose-legacy-touch-event-apis. + property ontouchcancel optional=#true + property ontouchend optional=#true + property ontouchmove optional=#true + property ontouchstart optional=#true +} diff --git a/inputfiles/patches/webgl.kdl b/inputfiles/patches/webgl.kdl index 44df9262d..efb9fed9f 100644 --- a/inputfiles/patches/webgl.kdl +++ b/inputfiles/patches/webgl.kdl @@ -1,3 +1,3 @@ interface-mixin WebGLRenderingContextBase { - property canvas exposed=Window + property canvas exposed=Window } diff --git a/src/build/patches.ts b/src/build/patches.ts index a6061561e..d21404989 100644 --- a/src/build/patches.ts +++ b/src/build/patches.ts @@ -1,4 +1,4 @@ -import { parse, type Node } from "kdljs"; +import { parse, type Value, type Node } from "kdljs"; import type { Enum, Event, Property, Interface, WebIdl } from "./types"; import { readdir, readFile } from "fs/promises"; import { merge } from "./helpers.js"; @@ -7,6 +7,24 @@ type DeepPartial = T extends object ? { [K in keyof T]?: DeepPartial } : T; +function optionalMember(prop: string, type: T, value?: Value) { + if (value === undefined) { + return {}; + } + if (typeof value !== type) { + throw new Error(`Expected type ${value} for ${prop}`); + } + return { + [prop]: value as T extends "string" + ? string + : T extends "number" + ? number + : T extends "boolean" + ? boolean + : never, + }; +} + /** * Converts patch files in KDL to match the [types](types.d.ts). */ @@ -92,15 +110,12 @@ function handleMixin(node: Node): DeepPartial { } } - const result = { + return { name, events: { event }, properties: { property }, + ...optionalMember("extends", "string", node.properties?.extends), } as DeepPartial; - if (node.properties.extends) { - result.extends = node.properties.extends as string; - } - return result; } /** @@ -121,7 +136,9 @@ function handleEvent(child: Node): Event { function handleProperty(child: Node): Partial { return { name: child.values[0] as string, - exposed: child.properties?.exposed as string, + ...optionalMember("exposed", "string", child.properties?.exposed), + ...optionalMember("optional", "boolean", child.properties?.optional), + ...optionalMember("overrideType", "string", child.properties?.overrideType), }; }