Skip to content

KDL Parser #2064

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 33 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
73855ea
chore: install deps
Bashamega Jul 6, 2025
82c47f9
Parser
Bashamega Jul 6, 2025
ac0e253
patch: types
Bashamega Jul 6, 2025
99e1b99
-
Bashamega Jul 8, 2025
28cdf7d
chore: ignore mdn and idl folders
Bashamega Jul 8, 2025
ae4e21b
Merge branch 'microsoft:main' into kdl/parser
Bashamega Jul 8, 2025
b68c508
Update src/build/utils/kdl.ts
Bashamega Jul 9, 2025
761bc35
Update src/build/utils/kdl.ts
Bashamega Jul 9, 2025
1aaee0d
Update src/build/utils/kdl.ts
Bashamega Jul 9, 2025
fc238c7
Update src/build/utils/kdl.ts
Bashamega Jul 9, 2025
56f7ebf
Update src/build/utils/kdl.ts
Bashamega Jul 9, 2025
4f15c5d
-
Bashamega Jul 9, 2025
4625aa4
chore: rename
Bashamega Jul 9, 2025
3f1bd04
chore: create patches folder
Bashamega Jul 9, 2025
97e5390
patch: rename url
Bashamega Jul 9, 2025
4c85911
-
Bashamega Jul 9, 2025
16c4f14
KDL parser
Bashamega Jul 9, 2025
2d3d3e4
-
Bashamega Jul 9, 2025
da909af
feat: rename
Bashamega Jul 10, 2025
3e236c4
chore: remove EnumDescriptor
Bashamega Jul 10, 2025
1f4e523
chore: remove an extra variable
Bashamega Jul 10, 2025
c9c4eee
rename
Bashamega Jul 10, 2025
f69385e
rename
Bashamega Jul 10, 2025
7213180
lint
Bashamega Jul 10, 2025
a5176a7
rename
Bashamega Jul 10, 2025
b056cf1
split into smaller functions
Bashamega Jul 10, 2025
609c174
Update src/build/patches.ts
Bashamega Jul 10, 2025
72303fd
Update src/build/patches.ts
Bashamega Jul 10, 2025
2552032
Integrate more enums
Bashamega Jul 10, 2025
4d1ab0f
Revert "Integrate more enums" (#3)
Bashamega Jul 11, 2025
811a217
Update patches.ts
saschanaz Jul 12, 2025
e7e2597
Update and rename autoFills.kdl to autocomplete.kdl
saschanaz Jul 12, 2025
7ff687c
Update build.ts
saschanaz Jul 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 0 additions & 92 deletions inputfiles/addedTypes.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -373,98 +373,6 @@
// Full support: https://developer.mozilla.org/en-US/docs/Web/API/Storage_Access_API#browser_compatibility
"storage-access"
]
},
"AutoFillBase": {
"name": "AutoFillBase",
"value": [
// Off
"off",
// Automatic
"on",
""
]
},
"AutoFillAddressKind": {
"name": "AutoFillAddressKind",
"value": [
"shipping",
"billing"
]
},
"AutoFillNormalField": {
"name": "AutoFillNormalField",
"value": [
"name",
"honorific-prefix",
"given-name",
"additional-name",
"family-name",
"honorific-suffix",

"username",
"new-password",
"current-password",
// Supported in iOS Safari too even though WPT tests
// for Safari currently fail as of 2023-06.
"one-time-code",

"organization",
"street-address",
"address-line1",
"address-line2",
"address-line3",
"address-level4",
"address-level3",
"address-level2",
"address-level1",
"country",
"country-name",
"postal-code",

"cc-name",
"cc-given-name",
"cc-family-name",
"cc-number",
"cc-exp",
"cc-exp-month",
"cc-exp-year",
"cc-csc",
"cc-type",
"transaction-currency",
"transaction-amount",

"bday-day",
"bday-month",
"bday-year"
]
},
"AutoFillContactKind": {
"name": "AutoFillContactKind",
"value": [
"home",
"work",
"mobile"
]
},
"AutoFillContactField": {
"name": "AutoFillContactField",
"value": [
"tel",
"tel-country-code",
"tel-national",
"tel-area-code",
"tel-local",
"tel-local-prefix",
"tel-local-suffix",
"tel-extension",
"email"
]
},
"AutoFillCredentialField": {
"name": "AutoFillCredentialField",
"value": [
"webauthn"
]
}
}
},
Expand Down
74 changes: 74 additions & 0 deletions inputfiles/patches/autocomplete.kdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
enum AutoFillBase {
// Off
off
// Automatic
on
""
}
enum AutoFillAddressKind {
shipping
billing
}
enum AutoFillNormalField {
name
honorific-prefix
given-name
additional-name
family-name
honorific-suffix

username
new-password
current-password
// Supported in iOS Safari too even though WPT tests
// for Safari currently fail as of 2023-06.
one-time-code

organization
street-address
address-line1
address-line2
address-line3
address-level4
address-level3
address-level2
address-level1
country
country-name
postal-code

cc-name
cc-given-name
cc-family-name
cc-number
cc-exp
cc-exp-month
cc-exp-year
cc-csc
cc-type
transaction-currency
transaction-amount

bday-day
bday-month
bday-year
}
enum AutoFillContactKind {
home
work
mobile
}
enum AutoFillContactField {
tel
tel-country-code
tel-national
tel-area-code
tel-local
tel-local-prefix
tel-local-suffix
tel-extension
email
}
enum AutoFillCredentialField {
webauthn
}
77 changes: 77 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"eslint-plugin-prettier": "^5.1.3",
"globals": "^16.0.0",
"jsonc-parser": "^3.2.1",
"kdljs": "^0.3.0",
"node-fetch": "^3.3.2",
"prettier": "^3.2.5",
"print-diff": "^2.0.0",
Expand Down
3 changes: 3 additions & 0 deletions src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { getInterfaceToEventMap } from "./build/webref/events.js";
import { getWebidls } from "./build/webref/idl.js";
import jsonc from "jsonc-parser";
import { generateDescriptions } from "./build/mdn-comments.js";
import readPatches from "./build/patches.js";

function mergeNamesakes(filtered: Browser.WebIdl) {
const targets = [
Expand Down Expand Up @@ -93,6 +94,7 @@ async function emitDom() {

const overriddenItems = await readInputJSON("overridingTypes.jsonc");
const addedItems = await readInputJSON("addedTypes.jsonc");
const patches = await readPatches();
const comments = await readInputJSON("comments.json");
const deprecatedInfo = await readInputJSON("deprecatedMessage.json");
const documentationFromMDN = await generateDescriptions();
Expand Down Expand Up @@ -230,6 +232,7 @@ async function emitDom() {
webidl = mergeApiDescriptions(webidl, documentationFromMDN);
webidl = merge(webidl, addedItems);
webidl = merge(webidl, overriddenItems);
webidl = merge(webidl, patches);
webidl = merge(webidl, comments);
webidl = mergeDeprecatedMessage(webidl, deprecatedInfo);
for (const name in webidl.interfaces!.interface) {
Expand Down
74 changes: 74 additions & 0 deletions src/build/patches.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { parse } from "kdljs";
import type { Enum } from "./types";
import { readdir, readFile } from "fs/promises";
import { merge } from "./helpers.js";

/**
* Converts patch files in KDL to match the [types](types.d.ts).
*/
function parseKDL(kdlText: string) {
const { output, errors } = parse(kdlText);

if (errors.length) {
throw new Error("KDL parse errors", { cause: errors });
}

const nodes = output!;
const enums: Record<string, Enum> = {};

for (const node of nodes) {
if (node.name === "enum") {
handleEnum(node, enums);
}
}

return { enums: { enum: enums } };
}

/**
* Handles an enum node by extracting its name and values.
* Throws an error if the enum name is missing or if the values are not in the correct format.
* @param node The enum node to handle.
* @param enums The record of enums to update.
*/
function handleEnum(node: any, enums: Record<string, Enum>) {
const name = node.values[0];
if (typeof name !== "string") {
throw new Error("Missing enum name");
}
const values: string[] = [];

for (const child of node.children ?? []) {
values.push(child.name);
}

enums[name] = { name, value: values };
}

/**
* Collect all file URLs in a directory.
*/
async function getAllFileURLs(folder: URL): Promise<URL[]> {
const entries = await readdir(folder, { withFileTypes: true });
return entries.map((entry) => new URL(entry.name, folder));
}

/**
* Read and parse a single KDL file.
*/
export async function readPatch(fileUrl: URL): Promise<any> {
const text = await readFile(fileUrl, "utf8");
return parseKDL(text);
}

/**
* Read, parse, and merge all KDL files under the input folder.
*/
export default async function readPatches(): Promise<any> {
const patchDirectory = new URL("../../inputfiles/patches/", import.meta.url);
const fileUrls = await getAllFileURLs(patchDirectory);

const parsedContents = await Promise.all(fileUrls.map(readPatch));

return parsedContents.reduce((acc, current) => merge(acc, current), {});
}