Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ This export is the wrapper class interface, suitable for example for putting on

#### `expose`

This export contains information about where an interface is supposed to be exposed as a property. It takes into account the Web IDL extended attributes `[Expose]` and `[NoInterfaceObject]` to generate a data structure of the form:
This export contains information about where an interface is supposed to be exposed as a property. It takes into account the Web IDL extended attribute `[Exposed]` to generate a data structure of the form:

```js
{
Expand Down Expand Up @@ -346,7 +346,7 @@ webidl2js is implementing an ever-growing subset of the Web IDL specification. S
- `[Clamp]`
- `[Constructor]`
- `[EnforceRange]`
- `[Exposed]` and `[NoInterfaceObject]` (by exporting metadata on where/whether it is exposed)
- `[Exposed]` (by exporting metadata on where/whether it is exposed)
- `[LegacyArrayClass]`
- `[LegacyUnenumerableNamedProperties]`
- `[OverrideBuiltins]`
Expand Down
4 changes: 2 additions & 2 deletions lib/constructs/attribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Attribute {
this.ctx = ctx;
this.interface = I;
this.idl = idl;
this.static = idl.static;
this.static = idl.special === "static";
}

generate() {
Expand Down Expand Up @@ -109,7 +109,7 @@ class Attribute {
`, "set", { configurable });
}

if (!this.static && this.idl.stringifier) {
if (!this.static && this.idl.special === "stringifier") {
addMethod("toString", [], `
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
Expand Down
67 changes: 33 additions & 34 deletions lib/constructs/interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class Interface {

const global = utils.getExtAttr(this.idl.extAttrs, "Global");
this.isGlobal = Boolean(global);
if (global && (!global.rhs || global.arguments)) {
if (global && !global.rhs) {
throw new Error(`[Global] must take an identifier or an identifier list in interface ${this.name}`);
}
}
Expand Down Expand Up @@ -190,7 +190,7 @@ class Interface {
_analyzeMembers() {
const handleSpecialOperations = member => {
if (member.type === "operation") {
if (member.getter) {
if (member.special === "getter") {
let msg = `Invalid getter ${member.name ? `"${member.name}" ` : ""}on interface ${this.name}`;
if (member.definingInterface !== this.name) {
msg += ` (defined in ${member.definingInterface})`;
Expand All @@ -213,7 +213,7 @@ class Interface {
throw new Error(msg + "getter is neither indexed nor named");
}
}
if (member.setter) {
if (member.special === "setter") {
let msg = `Invalid setter ${member.name ? `"${member.name}" ` : ""}on interface ${this.name}`;
if (member.definingInterface !== this.name) {
msg += ` (defined in ${member.definingInterface})`;
Expand All @@ -237,7 +237,7 @@ class Interface {
throw new Error(msg + "setter is neither indexed nor named");
}
}
if (member.deleter) {
if (member.special === "deleter") {
let msg = `Invalid deleter ${member.name ? `"${member.name}" ` : ""}on interface ${this.name}`;
if (member.definingInterface !== this.name) {
msg += ` (defined in ${member.definingInterface})`;
Expand All @@ -264,7 +264,7 @@ class Interface {
let key;
switch (member.type) {
case "operation":
key = member.static ? "staticOperations" : "operations";
key = member.special === "static" ? "staticOperations" : "operations";
if (member.name) {
if (!this[key].has(member.name)) {
this[key].set(member.name, new Operation(this.ctx, this, member));
Expand All @@ -274,7 +274,7 @@ class Interface {
}
break;
case "attribute":
key = member.static ? "staticAttributes" : "attributes";
key = member.special === "static" ? "staticAttributes" : "attributes";
this[key].set(member.name, new Attribute(this.ctx, this, member));
break;
case "const":
Expand All @@ -294,7 +294,7 @@ class Interface {

handleSpecialOperations(member);

if (member.stringifier) {
if (member.special === "stringifier") {
let msg = `Invalid stringifier ${member.name ? `"${member.name}" ` : ""}on interface ${this.name}`;
if (member.definingInterface !== this.name) {
msg += ` (defined in ${member.definingInterface})`;
Expand All @@ -320,7 +320,7 @@ class Interface {
op.name = "toString";
this.operations.set("toString", op);
} else if (member.type === "attribute") {
if (member.static) {
if (member.special === "static") {
throw new Error(msg + "keyword cannot be placed on static attribute");
}
if (member.idlType.idlType !== "DOMString" && member.idlType.idlType !== "USVString" ||
Expand Down Expand Up @@ -359,7 +359,7 @@ class Interface {
}
}
for (const member of this.allMembers()) {
if (forbiddenMembers.has(member.name) || (member.name && member.name[0] === "_")) {
if (forbiddenMembers.has(member.name)) {
let msg = `${member.name} is forbidden in interface ${this.name}`;
if (member.definingInterface !== this.name) {
msg += ` (defined in ${member.definingInterface})`;
Expand Down Expand Up @@ -588,7 +588,7 @@ class Interface {
unsupportedValue = unsupportedValue.rhs.value;
}
if (unsupportedValue) {
const func = this.indexedGetter.name !== null ? `.${this.indexedGetter.name}` : "[utils.indexedGet]";
const func = this.indexedGetter.name ? `.${this.indexedGetter.name}` : "[utils.indexedGet]";
const value = indexedValue || `${O}[impl]${func}(${index})`;
return `${value} !== ${unsupportedValue}`;
}
Expand All @@ -601,7 +601,7 @@ class Interface {
unsupportedValue = unsupportedValue.rhs.value;
}
if (unsupportedValue) {
const func = this.namedGetter.name !== null ? `.${this.namedGetter.name}` : "[utils.namedGet]";
const func = this.namedGetter.name ? `.${this.namedGetter.name}` : "[utils.namedGet]";
const value = namedValue || `${O}[impl]${func}(${P})`;
return `${value} !== ${unsupportedValue}`;
}
Expand Down Expand Up @@ -638,7 +638,7 @@ class Interface {
${conv.body}
`;

if (this.indexedSetter.name === null) {
if (!this.indexedSetter.name) {
str += `
const creating = !(${supportsPropertyIndex(O, "index")});
if (creating) {
Expand Down Expand Up @@ -669,7 +669,7 @@ class Interface {
${conv.body}
`;

if (this.namedSetter.name === null) {
if (!this.namedSetter.name) {
str += `
const creating = !(${supportsPropertyName(O, P)});
if (creating) {
Expand Down Expand Up @@ -779,7 +779,7 @@ class Interface {
const index = P >>> 0;
`;

const func = this.indexedGetter.name !== null ? `.${this.indexedGetter.name}` : "[utils.indexedGet]";
const func = this.indexedGetter.name ? `.${this.indexedGetter.name}` : "[utils.indexedGet]";
let preamble = "";
let condition;
if (utils.getExtAttr(this.indexedGetter.extAttrs, "WebIDL2JSValueAsUnsupported")) {
Expand All @@ -805,7 +805,7 @@ class Interface {
`;
}
if (this.supportsNamedProperties) {
const func = this.namedGetter.name !== null ? `.${this.namedGetter.name}` : "[utils.namedGet]";
const func = this.namedGetter.name ? `.${this.namedGetter.name}` : "[utils.namedGet]";
const enumerable = !utils.getExtAttr(this.idl.extAttrs, "LegacyUnenumerableNamedProperties");
let preamble = "";
const conditions = [];
Expand Down Expand Up @@ -889,7 +889,7 @@ class Interface {
const index = P >>> 0;
`;

const func = this.indexedGetter.name !== null ? `.${this.indexedGetter.name}` : "[utils.indexedGet]";
const func = this.indexedGetter.name ? `.${this.indexedGetter.name}` : "[utils.indexedGet]";
let preamble = "";
let condition;
if (utils.getExtAttr(this.indexedGetter.extAttrs, "WebIDL2JSValueAsUnsupported")) {
Expand Down Expand Up @@ -979,7 +979,7 @@ class Interface {
if (this.supportsNamedProperties && !this.isGlobal) {
const unforgeable = new Set();
for (const m of this.allMembers()) {
if ((m.type === "attribute" || m.type === "operation") && !m.static &&
if ((m.type === "attribute" || m.type === "operation") && m.special !== "static" &&
utils.getExtAttr(m.extAttrs, "Unforgeable")) {
unforgeable.add(m.name);
}
Expand Down Expand Up @@ -1059,7 +1059,7 @@ class Interface {
return false;
`;
} else {
const func = this.namedDeleter.name !== null ? `.${this.namedDeleter.name}` : "[utils.namedDelete]";
const func = this.namedDeleter.name ? `.${this.namedDeleter.name}` : "[utils.namedDelete]";
if (this.namedDeleter.idlType.idlType === "bool") {
this.str += `
return target[impl]${func}(P);
Expand Down Expand Up @@ -1093,25 +1093,24 @@ class Interface {
}

generateIface() {
const shouldExposeRoot = !utils.getExtAttr(this.idl.extAttrs, "NoInterfaceObject");
const exposedAttrs = this.idl.extAttrs
.filter(attr => attr.name === "Exposed");
if (exposedAttrs.length === 0) {
throw new Error(`Missing [Exposed] extended attribute on ${this.name}`);
}
if (exposedAttrs.length > 1) {
throw new Error(`Too many [Exposed] extended attributes on ${this.name}`);
}

const rhs = exposedAttrs[0].rhs.value;
const exposedOn = typeof rhs === "string" ? [rhs] : rhs.map(arg => arg.value);

const exposedMap = {};
if (shouldExposeRoot) {
let exposedOn = ["Window"];
const exposedAttrs = this.idl.extAttrs
.filter(attr => attr.name === "Exposed");
if (exposedAttrs.length !== 0) {
if (typeof exposedAttrs[0].rhs.value === "string") {
exposedAttrs[0].rhs.value = [exposedAttrs[0].rhs.value];
}
exposedOn = exposedAttrs[0].rhs.value;
}
for (let i = 0; i < exposedOn.length; ++i) {
if (!exposedMap[exposedOn[i]]) {
exposedMap[exposedOn[i]] = [];
}
exposedMap[exposedOn[i]].push(this.name);
for (let i = 0; i < exposedOn.length; ++i) {
if (!exposedMap[exposedOn[i]]) {
exposedMap[exposedOn[i]] = [];
}
exposedMap[exposedOn[i]].push(this.name);
}

const exposers = [];
Expand Down
2 changes: 1 addition & 1 deletion lib/constructs/operation.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Operation {
this.interface = I;
this.idls = [idl];
this.name = idl.name;
this.static = idl.static;
this.static = idl.special === "static";
}

isOnInstance() {
Expand Down
11 changes: 4 additions & 7 deletions lib/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,7 @@ function resolveType(ctx, idlType, stack = []) {
}
idlType.idlType = types;
return idlType;
} else if (idlType.generic === "sequence" || idlType.generic === "FrozenArray" || idlType.generic === "Promise") {
idlType.idlType = resolveType(ctx, idlType.idlType, stack);
return idlType;
} else if (idlType.generic === "record") {
} else if (idlType.generic) {
idlType.idlType = idlType.idlType.map(t => resolveType(ctx, t, stack));
return idlType;
} else if (resolvedTypes.has(ctx.typeOf(idlType.idlType))) {
Expand Down Expand Up @@ -279,7 +276,7 @@ function generateTypeConversion(ctx, name, idlType, argAttrs = [], parentName, e
}

function generateSequence() {
const conv = generateTypeConversion(ctx, "nextItem", idlType.idlType, [], parentName,
const conv = generateTypeConversion(ctx, "nextItem", idlType.idlType[0], [], parentName,
`${errPrefix} + "'s element"`);
requires.merge(conv.requires);

Expand Down Expand Up @@ -329,11 +326,11 @@ function generateTypeConversion(ctx, name, idlType, argAttrs = [], parentName, e

function generatePromise() {
let handler;
if (idlType.idlType.idlType === "void") {
if (idlType.idlType[0].idlType === "void") {
// Do nothing.
handler = "";
} else {
const conv = generateTypeConversion(ctx, "value", idlType.idlType, [], parentName,
const conv = generateTypeConversion(ctx, "value", idlType.idlType[0], [], parentName,
`${errPrefix} + " promise value"`);
requires.merge(conv.requires);
handler = `
Expand Down
2 changes: 1 addition & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function isGlobal(idl) {
}

function isOnInstance(memberIDL, interfaceIDL) {
return !memberIDL.static && (getExtAttr(memberIDL.extAttrs, "Unforgeable") || isGlobal(interfaceIDL));
return memberIDL.special !== "static" && (getExtAttr(memberIDL.extAttrs, "Unforgeable") || isGlobal(interfaceIDL));
}

function stringifyPropertyName(propName) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"pn": "^1.1.0",
"prettier": "^1.18.2",
"webidl-conversions": "^4.0.0",
"webidl2": "^10.3.3"
"webidl2": "^23.10.1"
},
"devDependencies": {
"eslint": "^6.5.1",
Expand Down
1 change: 1 addition & 0 deletions test/cases/DictionaryConvert.webidl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[Exposed=Window]
interface DictionaryConvert {
// Test force-conversion of dictionary types.
DOMString op(optional DOMString arg1, optional Dictionary arg2);
Expand Down
1 change: 1 addition & 0 deletions test/cases/Enum.webidl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[Exposed=Window]
interface Enum {
void op(RequestDestination destination);
attribute RequestDestination attr;
Expand Down
2 changes: 1 addition & 1 deletion test/cases/Factory.webidl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[WebIDL2JSFactory]
[WebIDL2JSFactory,Exposed=Window]
interface Factory {
DOMString method();
attribute double _attribute;
Expand Down
2 changes: 1 addition & 1 deletion test/cases/Global.webidl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[Global=Global]
[Global=Global,Exposed=Window]
interface Global {
void op();
[Unforgeable] void unforgeableOp();
Expand Down
2 changes: 1 addition & 1 deletion test/cases/LegacyArrayClass.webidl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[LegacyArrayClass]
[LegacyArrayClass,Exposed=Window]
interface LegacyArrayClass {
readonly attribute unsigned long length;
};
1 change: 1 addition & 0 deletions test/cases/MixedIn.webidl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[Exposed=Window]
interface MixedIn {
attribute DOMString mixedInAttr;
DOMString mixedInOp();
Expand Down
3 changes: 2 additions & 1 deletion test/cases/Overloads.webidl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[Constructor,
Constructor(DOMString arg1),
Constructor(URL arg1)]
Constructor(URL arg1),
Exposed=Window]
interface Overloads {
DOMString compatible(DOMString arg1);
byte compatible(DOMString arg1, DOMString arg2);
Expand Down
1 change: 1 addition & 0 deletions test/cases/PromiseTypes.webidl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[Exposed=Window]
interface PromiseTypes {
void voidPromiseConsumer(Promise<void> p);
void promiseConsumer(Promise<double> p);
Expand Down
1 change: 1 addition & 0 deletions test/cases/Reflect.webidl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[Exposed=Window]
interface Reflect {
[Reflect] attribute boolean ReflectedBoolean;
[FooBar, Reflect] attribute DOMString ReflectedDOMString;
Expand Down
2 changes: 1 addition & 1 deletion test/cases/SeqAndRec.webidl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[Constructor]
[Constructor,Exposed=Window]
interface SeqAndRec {
void recordConsumer(record<USVString, double> rec);
void recordConsumer2(record<USVString, URL> rec);
Expand Down
1 change: 1 addition & 0 deletions test/cases/Static.webidl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[Exposed=Window]
interface Static {
static attribute DOMString abc;
attribute DOMString abc;
Expand Down
1 change: 1 addition & 0 deletions test/cases/Storage.webidl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// https://html.spec.whatwg.org/multipage/webstorage.html#storage-2<Paste>
[Exposed=Window]
interface Storage {
readonly attribute unsigned long length;
DOMString? key(unsigned long index);
Expand Down
1 change: 1 addition & 0 deletions test/cases/StringifierAttribute.webidl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[Exposed=Window]
interface StringifierAttribute {
stringifier readonly attribute DOMString attr;
};
1 change: 1 addition & 0 deletions test/cases/StringifierDefaultOperation.webidl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[Exposed=Window]
interface StringifierDefaultOperation {
stringifier;
};
1 change: 1 addition & 0 deletions test/cases/StringifierNamedOperation.webidl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[Exposed=Window]
interface StringifierNamedOperation {
stringifier DOMString operation();
};
1 change: 1 addition & 0 deletions test/cases/StringifierOperation.webidl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[Exposed=Window]
interface StringifierOperation {
stringifier DOMString ();
};
1 change: 1 addition & 0 deletions test/cases/TypedefsAndUnions.webidl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[Exposed=Window]
interface TypedefsAndUnions {
void numOrStrConsumer(NumOrStr a);
void numOrEnumConsumer((double or RequestDestination)? a);
Expand Down
Loading