Skip to content
21 changes: 0 additions & 21 deletions inputfiles/overridingTypes.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
7 changes: 7 additions & 0 deletions inputfiles/patches/events.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ interface-mixin GlobalEventHandlers {
event transitionstart type=TransitionEvent
event transitionend type=TransitionEvent
event transitioncancel type=TransitionEvent
// 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
Copy link
Contributor

@saschanaz saschanaz Aug 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should go to touch-events.kdl. With that LGTM.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have moved them to a separate file

property onerror overrideType=OnErrorEventHandler
}

interface-mixin MessageEventTarget {
Expand Down
31 changes: 24 additions & 7 deletions src/build/patches.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -7,6 +7,24 @@ type DeepPartial<T> = T extends object
? { [K in keyof T]?: DeepPartial<T[K]> }
: T;

function optionalMember<const T>(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).
*/
Expand Down Expand Up @@ -92,15 +110,12 @@ function handleMixin(node: Node): DeepPartial<Interface> {
}
}

const result = {
return {
name,
events: { event },
properties: { property },
...optionalMember("extends", "string", node.properties?.extends),
} as DeepPartial<Interface>;
if (node.properties.extends) {
result.extends = node.properties.extends as string;
}
return result;
}

/**
Expand All @@ -121,7 +136,9 @@ function handleEvent(child: Node): Event {
function handleProperty(child: Node): Partial<Property> {
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),
};
}

Expand Down