diff --git a/inputfiles/addedTypes.jsonc b/inputfiles/addedTypes.jsonc index 62a55b192..df27d57c5 100644 --- a/inputfiles/addedTypes.jsonc +++ b/inputfiles/addedTypes.jsonc @@ -1,16 +1,6 @@ { "mixins": { "mixin": { - "AbstractWorker": { - "events": { - "event": [ - { - "name": "error", - "type": "ErrorEvent" - } - ] - } - }, "DocumentAndElementEventHandlers": { "events": { "event": [ diff --git a/inputfiles/patches/events.kdl b/inputfiles/patches/events.kdl new file mode 100644 index 000000000..1d8c40f68 --- /dev/null +++ b/inputfiles/patches/events.kdl @@ -0,0 +1,3 @@ +interface-mixin AbstractWorker { + event error type=ErrorEvent +} diff --git a/src/build/patches.ts b/src/build/patches.ts index b2875f6b2..86ba83232 100644 --- a/src/build/patches.ts +++ b/src/build/patches.ts @@ -1,5 +1,5 @@ -import { parse } from "kdljs"; -import type { Enum } from "./types"; +import { parse, type Node } from "kdljs"; +import type { Enum, Event } from "./types"; import { readdir, readFile } from "fs/promises"; import { merge } from "./helpers.js"; @@ -15,14 +15,22 @@ function parseKDL(kdlText: string) { const nodes = output!; const enums: Record = {}; + const mixins: Record = {}; for (const node of nodes) { - if (node.name === "enum") { - handleEnum(node, enums); + switch (node.name) { + case "enum": + handleEnum(node, enums); + break; + case "interface-mixin": + handleMixin(node, mixins); + break; + default: + throw new Error(`Unknown node name: ${node.name}`); } } - return { enums: { enum: enums } }; + return { enums: { enum: enums }, mixins: { mixin: mixins } }; } /** @@ -31,20 +39,43 @@ function parseKDL(kdlText: string) { * @param node The enum node to handle. * @param enums The record of enums to update. */ -function handleEnum(node: any, enums: Record) { +function handleEnum(node: Node, enums: Record) { const name = node.values[0]; if (typeof name !== "string") { throw new Error("Missing enum name"); } const values: string[] = []; - for (const child of node.children ?? []) { + for (const child of node.children) { values.push(child.name); } enums[name] = { name, value: values }; } +/** + * Handles a mixin node by extracting its name and associated events. + * Throws an error if the mixin name is missing. + * If the mixin node specifies "event" as its second value, it collects all child nodes as events, + * each with a name and type, and adds them to the mixins record under the mixin's name. + * @param node The mixin node to handle. + * @param mixins The record of mixins to update. + */ +function handleMixin(node: Node, mixins: Record) { + const name = node.values[0]; + if (typeof name !== "string") { + throw new Error("Missing mixin name"); + } + const rawEvents = node.children.filter( + (child: any) => child.name === "event", + ); + const event: Event[] = rawEvents.map((child: any) => ({ + name: child.values[0], + type: child.properties.type, + })); + mixins[name] = { name, events: { event } }; +} + /** * Collect all file URLs in a directory. */