Socket
Socket
Sign inDemoInstall

webidl2js

Package Overview
Dependencies
Maintainers
2
Versions
57
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

webidl2js - npm Package Compare versions

Comparing version 7.4.0 to 8.0.0

lib/constructs/enumeration.js

37

lib/constructs/attribute.js

@@ -10,7 +10,7 @@ "use strict";

class Attribute {
constructor(ctx, obj, I, idl) {
constructor(ctx, I, idl) {
this.ctx = ctx;
this.obj = obj;
this.interface = I;
this.idl = idl;
this.static = idl.static;
}

@@ -27,4 +27,4 @@

let objName = `this`;
let definedOn = this.obj.name + (this.idl.static ? "" : ".prototype");
if (utils.isOnInstance(this.idl, this.interface)) { // we're in a setup method
let definedOn = this.interface.name + (this.static ? "" : ".prototype");
if (utils.isOnInstance(this.idl, this.interface.idl)) { // we're in a setup method
objName = `obj`;

@@ -44,6 +44,6 @@ definedOn = `obj`;

if (this.idl.static) {
if (this.static) {
brandCheck = "";
getterBody = `return Impl["${this.idl.name}"];`;
setterBody = `Impl["${this.idl.name}"] = V;`;
getterBody = `return Impl.implementation["${this.idl.name}"];`;
setterBody = `Impl.implementation["${this.idl.name}"] = V;`;
} else if (shouldReflect) {

@@ -74,10 +74,23 @@ if (!reflector[this.idl.idlType.idlType]) {

if (!this.idl.readonly) {
const conv = Types.generateTypeConversion(
this.ctx, "V", this.idl.idlType, this.idl.extAttrs, this.interface.name,
`"Failed to set the '${this.idl.name}' property on '${this.interface.name}': The provided value"`);
requires.merge(conv.requires);
let idlConversion;
if (typeof this.idl.idlType.idlType === "string" && !this.idl.idlType.nullable &&
this.ctx.enumerations.has(this.idl.idlType.idlType)) {
requires.add(this.idl.idlType.idlType);
idlConversion = `
V = \`\${V}\`;
if (!${this.idl.idlType.idlType}.enumerationValues.has(V)) {
return;
}
`;
} else {
const conv = Types.generateTypeConversion(
this.ctx, "V", this.idl.idlType, this.idl.extAttrs, this.interface.name,
`"Failed to set the '${this.idl.name}' property on '${this.interface.name}': The provided value"`);
requires.merge(conv.requires);
idlConversion = conv.body;
}
str += `
set(V) {
${brandCheck}
${conv.body}
${idlConversion}
${setterBody}

@@ -84,0 +97,0 @@ },

@@ -6,5 +6,4 @@ "use strict";

class Constant {
constructor(ctx, obj, I, idl) {
constructor(ctx, I, idl) {
this.ctx = ctx;
this.obj = obj;
this.interface = I;

@@ -18,7 +17,7 @@ this.idl = idl;

const body = `
Object.defineProperty(${this.obj.name}, "${this.idl.name}", {
Object.defineProperty(${this.interface.name}, "${this.idl.name}", {
value: ${JSON.stringify(this.idl.value.value)},
enumerable: true
});
Object.defineProperty(${this.obj.name}.prototype, "${this.idl.name}", {
Object.defineProperty(${this.interface.name}.prototype, "${this.idl.name}", {
value: ${JSON.stringify(this.idl.value.value)},

@@ -25,0 +24,0 @@ enumerable: true

@@ -13,5 +13,2 @@ "use strict";

// Used as a sentinel in inheritedMembers to signify that the following members are inherited.
const inherited = Symbol("inherited");
function isNamed(idl) {

@@ -30,2 +27,5 @@ return idl.arguments[0].idlType.idlType === "DOMString";

this.factory = Boolean(utils.getExtAttr(this.idl.extAttrs, "WebIDL2JSFactory"));
for (const member of this.idl.members) {
member.definingInterface = this.name;
}

@@ -38,3 +38,5 @@ this.str = null;

this.operations = new Map();
this.staticOperations = new Map();
this.attributes = new Map();
this.staticAttributes = new Map();
this.constants = new Map();

@@ -47,2 +49,3 @@

this.namedDeleter = null;
this.stringifier = null;

@@ -54,52 +57,8 @@ this.iterable = null;

_analyzeMembers() {
let definingInterface = null;
for (const member of this.inheritedMembers()) {
if (member[0] === inherited) {
definingInterface = member[1];
continue;
}
if (!definingInterface) {
switch (member.type) {
case "operation": {
let name = member.name;
if (name === null && member.stringifier) {
name = "toString";
}
if (name !== null && !this.operations.has(name)) {
this.operations.set(name, new Operation(this.ctx, this, this.idl, member));
}
break;
}
case "attribute":
this.attributes.set(member.name, new Attribute(this.ctx, this, this.idl, member));
break;
case "const":
this.constants.set(member.name, new Constant(this.ctx, this, this.idl, member));
break;
case "iterable":
if (this.iterable) {
throw new Error(`Interface ${this.name} has more than one iterable declaration`);
}
this.iterable = new Iterable(this.ctx, this, this.idl, member);
break;
default:
if (!this.ctx.options.suppressErrors) {
throw new Error(`Unknown IDL member type "${member.type}" in interface ${this.name}`);
}
}
} else {
switch (member.type) {
case "iterable":
if (this.iterable) {
throw new Error(`Iterable interface ${this.name} inherits from another iterable interface ` +
`${definingInterface}`);
}
break;
}
}
const handleSpecialOperations = member => {
if (member.type === "operation") {
if (member.getter) {
let msg = `Invalid getter ${member.name ? `"${member.name}" ` : ""}on interface ${this.name}`;
if (definingInterface) {
msg += ` (defined in ${definingInterface})`;
if (member.definingInterface !== this.name) {
msg += ` (defined in ${member.definingInterface})`;
}

@@ -127,4 +86,4 @@ msg += ": ";

let msg = `Invalid setter ${member.name ? `"${member.name}" ` : ""}on interface ${this.name}`;
if (definingInterface) {
msg += ` (defined in ${definingInterface})`;
if (member.definingInterface !== this.name) {
msg += ` (defined in ${member.definingInterface})`;
}

@@ -153,4 +112,4 @@ msg += ": ";

let msg = `Invalid deleter ${member.name ? `"${member.name}" ` : ""}on interface ${this.name}`;
if (definingInterface) {
msg += ` (defined in ${definingInterface})`;
if (member.definingInterface !== this.name) {
msg += ` (defined in ${member.definingInterface})`;
}

@@ -173,5 +132,94 @@ msg += ": ";

}
};
const seen = new Set([this.name]);
for (const member of this.members(seen)) {
let key;
switch (member.type) {
case "operation":
key = member.static ? "staticOperations" : "operations";
if (member.name) {
if (!this[key].has(member.name)) {
this[key].set(member.name, new Operation(this.ctx, this, member));
} else {
this[key].get(member.name).idls.push(member);
}
}
break;
case "attribute":
key = member.static ? "staticAttributes" : "attributes";
this[key].set(member.name, new Attribute(this.ctx, this, member));
break;
case "const":
this.constants.set(member.name, new Constant(this.ctx, this, member));
break;
case "iterable":
if (this.iterable) {
throw new Error(`Interface ${this.name} has more than one iterable declaration`);
}
this.iterable = new Iterable(this.ctx, this, member);
break;
default:
if (!this.ctx.options.suppressErrors) {
throw new Error(`Unknown IDL member type "${member.type}" in interface ${this.name}`);
}
}
handleSpecialOperations(member);
if (member.stringifier) {
let msg = `Invalid stringifier ${member.name ? `"${member.name}" ` : ""}on interface ${this.name}`;
if (member.definingInterface !== this.name) {
msg += ` (defined in ${member.definingInterface})`;
}
msg += ": ";
if (member.type === "operation") {
if (!member.idlType) {
member.idlType = { idlType: "DOMString" };
}
if (!member.arguments) {
member.arguments = [];
}
if (!this.ctx.options.suppressErrors) {
if (member.arguments.length > 0) {
throw new Error(msg + "takes more than zero arguments");
}
if (member.idlType.idlType !== "DOMString" || member.idlType.nullable) {
throw new Error(msg + "returns something other than a plain DOMString");
}
if (this.stringifier) {
throw new Error(msg + "duplicated stringifier");
}
}
const op = new Operation(this.ctx, this, member);
op.name = "toString";
this.operations.set("toString", op);
} else if (member.type === "attribute") {
if (member.static) {
throw new Error(msg + "keyword cannot be placed on static attribute");
}
if (!this.ctx.options.suppressErrors) {
if (member.idlType.idlType !== "DOMString" && member.idlType.idlType !== "USVString" ||
member.idlType.nullable) {
throw new Error(msg + "attribute can only be of type DOMString or USVString");
}
}
// Implemented in Attribute class.
} else {
throw new Error(msg + `keyword placed on incompatible type ${member.type}`);
}
this.stringifier = member;
}
}
for (const member of this.inheritedMembers(seen)) {
if (this.iterable && member.type === "iterable") {
throw new Error(`Iterable interface ${this.name} inherits from another iterable interface ` +
`${member.definingInterface}`);
}
const forbiddenMembers = new Set();
handleSpecialOperations(member);
}
// https://heycam.github.io/webidl/#dfn-reserved-identifier
const forbiddenMembers = new Set(["constructor", "toString"]);
if (this.iterable) {

@@ -190,12 +238,7 @@ if (this.iterable.isValue) {

}
definingInterface = null;
for (const member of this.inheritedMembers()) {
if (member[0] === inherited) {
definingInterface = member[1];
continue;
}
if (forbiddenMembers.has(member.name)) {
for (const member of this.allMembers()) {
if (forbiddenMembers.has(member.name) || (member.name && member.name[0] === "_")) {
let msg = `${member.name} is forbidden in interface ${this.name}`;
if (definingInterface) {
msg += ` (defined in ${definingInterface})`;
if (member.definingInterface !== this.name) {
msg += ` (defined in ${member.definingInterface})`;
}

@@ -220,2 +263,10 @@ throw new Error(msg);

implements(source) {
const iface = this.ctx.interfaces.get(source);
if (!iface) {
if (this.ctx.options.suppressErrors) {
return;
}
throw new Error(`${source} interface not found (used as a mixin for ${this.name})`);
}
this.mixins.push(source);

@@ -272,3 +323,3 @@ }

generateConstructor() {
const overloads = Overloads.getEffectiveOverloads("constructor", 0, this.idl, null);
const overloads = Overloads.getEffectiveOverloads("constructor", this.name, 0, this);

@@ -341,12 +392,52 @@ if (overloads.length !== 0) {

* inheritedMembers() {
// https://heycam.github.io/webidl/#dfn-consequential-interfaces
* consequentialInterfaces(seen = new Set([this.name]), root = this.name) {
for (const mixin of this.mixins) {
if (seen.has(mixin)) {
throw new Error(`${root} has a dependency cycle`);
}
seen.add(mixin);
yield* this.ctx.interfaces.get(mixin).allInterfaces(seen);
}
}
// All interfaces an object of this interface implements.
* allInterfaces(seen = new Set([this.name]), root = this.name) {
yield this.name;
yield* this.consequentialInterfaces(seen, root);
if (this.idl.inheritance && this.ctx.interfaces.has(this.idl.inheritance)) {
if (seen.has(this.idl.inheritance)) {
throw new Error(`${root} has an inheritance cycle`);
}
seen.add(this.idl.inheritance);
yield* this.ctx.interfaces.get(this.idl.inheritance).allInterfaces(seen, root);
}
}
// Members that will be visible on this interface's prototype object, i.e. members from this
// interface and its consequential interfaces.
* members(seen = new Set([this.name]), root = this.name) {
yield* this.idl.members;
for (const iface of [...this.mixins, this.idl.inheritance]) {
if (this.ctx.interfaces.has(iface)) {
yield [inherited, iface];
yield* this.ctx.interfaces.get(iface).inheritedMembers();
for (const mixin of this.consequentialInterfaces(seen, root)) {
yield* this.ctx.interfaces.get(mixin).idl.members;
}
}
// Members from this interface's inherited interfaces and their consequential interfaces.
* inheritedMembers(seen = new Set([this.name]), root = this.name) {
if (this.idl.inheritance && this.ctx.interfaces.has(this.idl.inheritance)) {
if (seen.has(this.idl.inheritance)) {
throw new Error(`${root} has an inheritance cycle`);
}
seen.add(this.idl.inheritance);
yield* this.ctx.interfaces.get(this.idl.inheritance).allMembers(seen, root);
}
}
* allMembers(seen = new Set([this.name]), root = this.name) {
for (const iface of this.allInterfaces(seen, root)) {
yield* this.ctx.interfaces.get(iface).idl.members;
}
}
generateRequires() {

@@ -359,7 +450,4 @@ this.requires.addRaw("impl", "utils.implSymbol");

if (this.mixins.length !== 0) {
this.requires.addRaw("mixin", "utils.mixin");
for (const mixin of this.mixins) {
this.requires.add(mixin);
}
for (const mixin of this.consequentialInterfaces()) {
this.requires.add(mixin);
}

@@ -375,6 +463,5 @@

generateMixins() {
for (const mixin of this.mixins) {
for (const mixin of this.consequentialInterfaces()) {
this.str += `
mixin(${this.name}.prototype, ${mixin}.interface.prototype);
${mixin}.mixedInto.push(${this.name});
${mixin}._mixedIntoPredicates.push(module.exports.is);
`;

@@ -386,10 +473,13 @@ }

this.str += `
mixedInto: [],
// When an interface-module that implements this interface as a mixin is loaded, it will append its own \`.is()\`
// method into this array. It allows objects that directly implements *those* interfaces to be recognized as
// implementing this mixin interface.
_mixedIntoPredicates: [],
is(obj) {
if (obj) {
if (obj[impl] instanceof Impl.implementation) {
if (utils.hasOwn(obj, impl) && obj[impl] instanceof Impl.implementation) {
return true;
}
for (let i = 0; i < module.exports.mixedInto.length; ++i) {
if (obj instanceof module.exports.mixedInto[i]) {
for (const isMixedInto of module.exports._mixedIntoPredicates) {
if (isMixedInto(obj)) {
return true;

@@ -408,4 +498,4 @@ }

const wrapper = utils.wrapperForImpl(obj);
for (let i = 0; i < module.exports.mixedInto.length; ++i) {
if (wrapper instanceof module.exports.mixedInto[i]) {
for (const isMixedInto of module.exports._mixedIntoPredicates) {
if (isMixedInto(wrapper)) {
return true;

@@ -481,3 +571,3 @@ }

if (overrideBuiltins) {
conditions.push(`!Object.prototype.hasOwnProperty.call(${O}, ${P})`);
conditions.push(`!utils.hasOwn(${O}, ${P})`);
} else {

@@ -844,6 +934,3 @@ // TODO: create a named properties object.

const unforgeable = new Set();
for (const m of this.inheritedMembers()) {
if (m[0] === inherited) {
continue;
}
for (const m of this.allMembers()) {
if ((m.type === "attribute" || m.type === "operation") && !m.static &&

@@ -860,3 +947,3 @@ utils.getExtAttr(m.extAttrs, "Unforgeable")) {

needFallback = true;
this.str += "if (!Object.prototype.hasOwnProperty.call(target, P)) {";
this.str += "if (!utils.hasOwn(target, P)) {";
}

@@ -1012,3 +1099,10 @@

for (const member of [...this.operations.values(), ...this.attributes.values()]) {
for (const member of this.operations.values()) {
if (member.isOnInstance()) {
const data = member.generate();
this.requires.merge(data.requires);
this.str += data.body;
}
}
for (const member of this.attributes.values()) {
if (utils.isOnInstance(member.idl, this.idl)) {

@@ -1132,4 +1226,4 @@ const data = member.generate();

for (const member of this.operations.values()) {
if (!utils.isOnInstance(member.idl, this.idl)) {
for (const member of [...this.operations.values(), ...this.staticOperations.values()]) {
if (!member.isOnInstance()) {
const data = member.generate();

@@ -1148,3 +1242,3 @@ this.requires.merge(data.requires);

generateAttributes() {
for (const member of [...this.attributes.values(), ...this.constants.values()]) {
for (const member of [...this.attributes.values(), ...this.staticAttributes.values(), ...this.constants.values()]) {
if (member instanceof Attribute && utils.isOnInstance(member.idl, this.idl)) {

@@ -1198,3 +1292,2 @@ continue;

this.generateConstructor();
this.generateMixins();

@@ -1230,2 +1323,3 @@ this.generateOperations();

this.generateMixins();
this.generateRequires();

@@ -1232,0 +1326,0 @@ }

@@ -7,5 +7,4 @@ "use strict";

class Iterable {
constructor(ctx, obj, I, idl) {
constructor(ctx, I, idl) {
this.ctx = ctx;
this.obj = obj;
this.interface = I;

@@ -36,3 +35,3 @@ this.idl = idl;

return `
${this.obj.name}.prototype${propExpr} = function ${fnName}() {
${this.interface.name}.prototype${propExpr} = function ${fnName}() {
if (!this || !module.exports.is(this)) {

@@ -51,3 +50,3 @@ throw new TypeError("Illegal invocation");

str += `
${this.obj.name}.prototype.entries = ${this.obj.name}.prototype[Symbol.iterator];
${this.interface.name}.prototype.entries = ${this.interface.name}.prototype[Symbol.iterator];
${this.generateFunction("keys", "key")}

@@ -58,5 +57,5 @@ ${this.generateFunction("values", "value")}

str += `
${this.obj.name}.prototype.entries = Array.prototype.entries;
${this.obj.name}.prototype.keys = Array.prototype.keys;
${this.obj.name}.prototype.values = Array.prototype[Symbol.iterator];
${this.interface.name}.prototype.entries = Array.prototype.entries;
${this.interface.name}.prototype.keys = Array.prototype.keys;
${this.interface.name}.prototype.values = Array.prototype[Symbol.iterator];
`;

@@ -63,0 +62,0 @@ }

@@ -11,10 +11,20 @@ "use strict";

class Operation {
constructor(ctx, obj, I, idl) {
constructor(ctx, I, idl) {
this.ctx = ctx;
this.obj = obj;
this.interface = I;
this.idl = idl;
this.idls = [idl];
this.name = idl.name;
this.static = idl.static;
}
isOnInstance() {
const firstOverloadOnInstance = utils.isOnInstance(this.idls[0], this.interface.idl);
for (const overload of this.idls.slice(1)) {
if (utils.isOnInstance(overload, this.interface.idl) !== firstOverloadOnInstance) {
throw new Error(`[Unforgeable] is not applied uniformly to operation "${this.name}" on ${this.interface.name}`);
}
}
return firstOverloadOnInstance;
}
generate() {

@@ -24,17 +34,13 @@ const requires = new utils.RequiresMap(this.ctx);

let name = this.idl.name;
if (!name) {
if (this.idl.stringifier) {
name = "toString";
} else {
return { requires, body: "" };
}
if (!this.name) {
throw new Error(`Internal error: this operation does not have a name (in interface ${this.interface.name})`);
}
let targetObj = this.obj.name + (this.idl.static ? "" : ".prototype");
if (utils.isOnInstance(this.idl, this.interface)) {
let targetObj = this.interface.name + (this.static ? "" : ".prototype");
if (this.isOnInstance()) {
targetObj = "obj";
}
const overloads = Overloads.getEffectiveOverloads(name, 0, this.interface, null);
const type = this.static ? "static operation" : "regular operation";
const overloads = Overloads.getEffectiveOverloads(type, this.name, 0, this.interface);
let minConstructor = overloads[0];

@@ -48,9 +54,9 @@

const fnName = keywords.has(name) ? "_" : name;
const fnName = keywords.has(this.name) ? "_" : this.name;
minConstructor.nameList = minConstructor.nameList.map(n => (keywords.has(n) ? "_" : "") + n);
str += `
${targetObj}.${name} = function ${fnName}(${minConstructor.nameList.join(", ")}) {
${targetObj}.${this.name} = function ${fnName}(${minConstructor.nameList.join(", ")}) {
`;
if (!this.idl.static) {
if (!this.static) {
str += `

@@ -67,4 +73,5 @@ if (!this || !module.exports.is(this)) {

if (arguments.length < ${minConstructor.nameList.length}) {
throw new TypeError("Failed to execute '${name}' on '${this.obj.name}': ${minConstructor.nameList.length} " +
"argument${plural} required, but only " + arguments.length + " present.");
throw new TypeError("Failed to execute '${this.name}' on '${this.interface.name}': " +
"${minConstructor.nameList.length} argument${plural} required, but only " +
arguments.length + " present.");
}

@@ -74,6 +81,9 @@ `;

const callOn = this.idl.static ? "Impl" : "this[impl]";
const callOn = this.static ? "Impl.implementation" : "this[impl]";
// In case of stringifiers, use the named implementation function rather than hardcoded "toString".
// All overloads will have the same name, so pick the first one.
const implFunc = this.idls[0].name || this.name;
const parameterConversions = Parameters.generateOverloadConversions(
this.ctx, overloads, this.interface.name, `Failed to execute '${name}' on '${this.obj.name}': `);
this.ctx, overloads, this.interface.name, `Failed to execute '${this.name}' on '${this.interface.name}': `);
const argsSpread = parameterConversions.hasArgs ? "...args" : "";

@@ -83,5 +93,5 @@ requires.merge(parameterConversions.requires);

if (this.idl.stringifier || overloads.every(overload => conversions[overload.operation.idlType.idlType])) {
if (overloads.every(overload => conversions[overload.operation.idlType.idlType])) {
str += `
return ${callOn}.${name}(${argsSpread});
return ${callOn}.${implFunc}(${argsSpread});
};

@@ -91,3 +101,3 @@ `;

str += `
return utils.tryWrapperForImpl(${callOn}.${name}(${argsSpread}));
return utils.tryWrapperForImpl(${callOn}.${implFunc}(${argsSpread}));
};

@@ -94,0 +104,0 @@ `;

@@ -25,2 +25,3 @@ "use strict";

this.dictionaries = new Map();
this.enumerations = new Map();

@@ -27,0 +28,0 @@ for (const typedef of builtinTypedefs) {

@@ -8,2 +8,6 @@ "use strict";

function hasOwn(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
function getReferenceToBytes(bufferSource) {

@@ -24,13 +28,2 @@ // Node.js' Buffer does not allow subclassing for now, so we can get away with a prototype object check for perf.

function mixin(target, source) {
const keys = Object.getOwnPropertyNames(source);
for (let i = 0; i < keys.length; ++i) {
if (keys[i] in target) {
continue;
}
Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(source, keys[i]));
}
}
const wrapperSymbol = Symbol("wrapper");

@@ -103,5 +96,5 @@ const implSymbol = Symbol("impl");

isObject,
hasOwn,
getReferenceToBytes,
getCopyToBytes,
mixin,
wrapperSymbol,

@@ -108,0 +101,0 @@ implSymbol,

"use strict";
module.exports.getEffectiveOverloads = function (A, N, I) { // No |C| since we don't support callback function yet.
module.exports.getEffectiveOverloads = function (type, A, N, I) {
const S = [];
let F = null;
if (A === "constructor") { // let's hope no-one specs a member named "constructor"
F = I.extAttrs.filter(a => a.name === "Constructor");
for (const c of F) {
if (!c.arguments) {
c.arguments = [];
switch (type) {
case "regular operation":
F = I.operations.get(A).idls;
break;
case "static operation":
F = I.staticOperations.get(A).idls;
break;
case "constructor":
F = I.idl.extAttrs.filter(a => a.name === "Constructor");
for (const c of F) {
if (!c.arguments) {
c.arguments = [];
}
}
}
} else if (typeof A === "string") {
F = I.members.filter(m => m.name === A || (A === "toString" && m.stringifier));
for (const m of F) {
if (m.stringifier) {
m.arguments = [];
}
}
break;
default:
throw new RangeError(`${type}s are not yet supported`);
}

@@ -22,0 +25,0 @@

@@ -14,2 +14,3 @@ "use strict";

const Dictionary = require("./constructs/dictionary");
const Enumeration = require("./constructs/enumeration");

@@ -47,3 +48,3 @@ class Transformer {

for (const file of folderContents) {
if (file.endsWith(".idl")) {
if (file.endsWith(".webidl")) {
files.push({

@@ -84,3 +85,3 @@ idlPath: path.join(this.sources[i].idlPath, file),

this.ctx.initialize();
const { interfaces, dictionaries, typedefs, customTypes } = this.ctx;
const { interfaces, dictionaries, enumerations, typedefs, customTypes } = this.ctx;

@@ -114,2 +115,7 @@ // first we're gathering all full interfaces and ignore partial ones

break;
case "enum":
obj = new Enumeration(this.ctx, instruction);
enumerations.set(obj.name, obj);
customTypes.set(obj.name, "enumeration");
break;
case "typedef":

@@ -173,3 +179,3 @@ obj = new Typedef(this.ctx, instruction);

const { interfaces, dictionaries } = this.ctx;
const { interfaces, dictionaries, enumerations } = this.ctx;

@@ -224,2 +230,11 @@ for (const obj of interfaces.values()) {

}
for (const obj of enumerations.values()) {
const source = this._prettify(`
"use strict";
${obj.toString()}
`);
yield fs.writeFile(path.join(outputDir, obj.name + ".js"), source);
}
}

@@ -226,0 +241,0 @@

@@ -255,3 +255,5 @@ "use strict";

if (type) {
code += generateTypeConversion(ctx, name, type, [], parentName, errPrefix).body;
const conv = generateTypeConversion(ctx, name, type, [], parentName, errPrefix);
code += conv.body;
requires.merge(conv.requires);
} else {

@@ -374,3 +376,3 @@ code += `throw new TypeError(${errPrefix} + " is not of any supported type.")`;

function extractUnionInfo(ctx, idlType, errPrefix) {
const { customTypes } = ctx;
const { customTypes, enumerations } = ctx;
const seen = {

@@ -428,3 +430,3 @@ sequenceLike: null,

seen.ArrayBufferViews.add(item.idlType);
} else if (stringTypes.has(item.idlType)) {
} else if (stringTypes.has(item.idlType) || enumerations.has(item.idlType)) {
if (seen.string) {

@@ -473,2 +475,3 @@ error("There can only be one string type in a union type");

} else if (customTypes.has(item.idlType)) {
// Enumerations were handled with the string types.
const type = customTypes.get(item.idlType);

@@ -475,0 +478,0 @@ if (type === "dictionary") {

@@ -36,3 +36,3 @@ "use strict";

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

@@ -39,0 +39,0 @@

{
"name": "webidl2js",
"version": "7.4.0",
"version": "8.0.0",
"description": "Auto-generates class structures for WebIDL specifications",

@@ -5,0 +5,0 @@ "main": "lib/transformer.js",

@@ -113,7 +113,7 @@ # JavaScript bindings generator for Web IDL

The `addSource()` method can then be called multiple times to add directories containing `.idl` IDL files and `.js` implementation class files.
The `addSource()` method can then be called multiple times to add directories containing `.webidl` IDL files and `.js` implementation class files.
Finally, the `generate()` method will generate corresponding wrapper class files in the given directory.
In this example, a file at `idl/SomeInterface.idl` would generate a new wrapper class at `wrappers/SomeInterface.js`, which would refer to an implementation class at `impls/SomeInterface-impl.js`. (In practice, usually at least two of these directories are the same, making `implSuffix` a useful option.)
In this example, a file at `idl/SomeInterface.webidl` would generate a new wrapper class at `wrappers/SomeInterface.js`, which would refer to an implementation class at `impls/SomeInterface-impl.js`. (In practice, usually at least two of these directories are the same, making `implSuffix` a useful option.)

@@ -276,2 +276,6 @@ The transformer will also generate a file named `utils.js` inside the wrapper class directory, which contains utilities used by all the wrapper class files.

#### Static operations
IDL static operations are declared as properties on the constructor, to mimic how the generated class works. This makes using `class` syntax especially idiomatic for defining an interface implementation, as you can just use `static` methods.
### Properties implementing IDL attributes

@@ -283,2 +287,6 @@

#### Static attributes
Just like static operations, static attributes are defined as properties on the constructor of the implementation class. And just like other attributes, the attribute can either be implemented as an accessor attribute or (if it is readonly) a data attribute. Note that, unless the `[WebIDL2JSFactory]` extended attribute is specified on the interface, any mutations to writable static attributes of the class will reflect on other places that use the same interface.
### toString method implementing IDL stringifier

@@ -360,2 +368,3 @@

- Dictionary types
- Enumeration types
- Union types

@@ -371,3 +380,3 @@ - Callback function types, somewhat

- Basic types (via [webidl-conversions][])
- Mixins, i.e. `implements` (with a [notable bug](https://github.com/jsdom/webidl2js/issues/49))
- Mixins, i.e. `implements`
- Overload resolution (although [tricky cases are not easy on the implementation class](#overloaded-operations))

@@ -392,3 +401,2 @@ - Variadic arguments ([only non-overloaded operations](#variadic-operations) are supported though)

- Namespaces
- Enumeration types ([#28](https://github.com/jsdom/webidl2js/issues/28))
- Callback interfaces

@@ -395,0 +403,0 @@ - `maplike<>` and `setlike<>`

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc