Skip to content

Commit 5af205c

Browse files
authored
Implement support for [LegacyWindowAlias] and [NoInterfaceObject]
Fixed #187.
1 parent 1455648 commit 5af205c

File tree

8 files changed

+676
-70
lines changed

8 files changed

+676
-70
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,8 @@ webidl2js is implementing an ever-growing subset of the Web IDL specification. S
456456
- `[EnforceRange]`
457457
- `[LegacyArrayClass]`
458458
- `[LegacyUnenumerableNamedProperties]`
459+
- `[LegacyWindowAlias]`
460+
- `[NoInterfaceObject]`
459461
- `[OverrideBuiltins]`
460462
- `[PutForwards]`
461463
- `[Replaceable]`
@@ -477,7 +479,6 @@ Notable missing features include:
477479
- `[Default]` (for `toJSON()` operations)
478480
- `[Global]`'s various consequences, including the named properties object and `[[SetPrototypeOf]]`
479481
- `[Exposed]`
480-
- `[LegacyWindowAlias]`
481482
- `[LenientSetter]`
482483
- `[LenientThis]`
483484
- `[NamedConstructor]`

lib/constructs/interface.js

+71-1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,49 @@ class Interface {
7676
if (global && !global.rhs) {
7777
throw new Error(`[Global] must take an identifier or an identifier list in interface ${this.name}`);
7878
}
79+
80+
const exposed = utils.getExtAttr(this.idl.extAttrs, "Exposed");
81+
if (exposed) {
82+
if (!exposed.rhs || (exposed.rhs.type !== "identifier" && exposed.rhs.type !== "identifier-list")) {
83+
throw new Error(`[Exposed] must take an identifier or an identifier list in interface ${this.name}`);
84+
}
85+
86+
if (exposed.rhs.type === "identifier") {
87+
this.exposed = new Set([exposed.rhs.value]);
88+
} else {
89+
this.exposed = new Set(exposed.rhs.value.map(token => token.value));
90+
}
91+
} else {
92+
this.exposed = new Set();
93+
}
94+
95+
if (!exposed && !utils.getExtAttr(this.idl.extAttrs, "NoInterfaceObject")) {
96+
throw new Error(`Interface ${this.name} has neither [Exposed] nor [NoInterfaceObject]`);
97+
}
98+
99+
const legacyWindowAlias = utils.getExtAttr(this.idl.extAttrs, "LegacyWindowAlias");
100+
if (legacyWindowAlias) {
101+
if (utils.getExtAttr(this.idl.extAttrs, "NoInterfaceObject")) {
102+
throw new Error(`Interface ${this.name} has [LegacyWindowAlias] and [NoInterfaceObject]`);
103+
}
104+
105+
if (!this.exposed.has("Window")) {
106+
throw new Error(`Interface ${this.name} has [LegacyWindowAlias] without [Exposed=Window]`);
107+
}
108+
109+
if (!legacyWindowAlias.rhs ||
110+
(legacyWindowAlias.rhs.type !== "identifier" && legacyWindowAlias.rhs.type !== "identifier-list")) {
111+
throw new Error(`[LegacyWindowAlias] must take an identifier or an identifier list in interface ${this.name}`);
112+
}
113+
114+
if (legacyWindowAlias.rhs.type === "identifier") {
115+
this.legacyWindowAliases = new Set([legacyWindowAlias.rhs.value]);
116+
} else {
117+
this.legacyWindowAliases = new Set(legacyWindowAlias.rhs.value.map(token => token.value));
118+
}
119+
} else {
120+
this.legacyWindowAliases = null;
121+
}
79122
}
80123

81124
// whence is either "instance" or "prototype"
@@ -1420,7 +1463,7 @@ class Interface {
14201463
const { idl, name } = this;
14211464

14221465
this.str += `
1423-
exports.install = function install(globalObject) {
1466+
exports.install = (globalObject, globalName) => {
14241467
`;
14251468

14261469
if (idl.inheritance) {
@@ -1444,12 +1487,39 @@ class Interface {
14441487
globalObject[ctorRegistrySymbol] = Object.create(null);
14451488
}
14461489
globalObject[ctorRegistrySymbol][interfaceName] = ${name};
1490+
`;
14471491

1492+
if (!utils.getExtAttr(this.idl.extAttrs, "NoInterfaceObject")) {
1493+
this.str += `
14481494
Object.defineProperty(globalObject, interfaceName, {
14491495
configurable: true,
14501496
writable: true,
14511497
value: ${name}
14521498
});
1499+
`;
1500+
1501+
if (this.legacyWindowAliases) {
1502+
this.str += `
1503+
if (globalName === "Window") {
1504+
`;
1505+
1506+
for (const legacyWindowAlias of this.legacyWindowAliases) {
1507+
this.str += `
1508+
Object.defineProperty(globalObject, "${legacyWindowAlias}", {
1509+
configurable: true,
1510+
writable: true,
1511+
value: ${name}
1512+
});
1513+
`;
1514+
}
1515+
1516+
this.str += `
1517+
}
1518+
`;
1519+
}
1520+
}
1521+
1522+
this.str += `
14531523
};
14541524
`;
14551525
}

0 commit comments

Comments
 (0)