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.1.1 to 7.2.0

.eslintignore

196

lib/constructs/attribute.js

@@ -9,111 +9,121 @@ "use strict";

function Attribute(ctx, obj, I, idl) {
this.ctx = ctx;
this.obj = obj;
this.interface = I;
this.idl = idl;
}
class Attribute {
constructor(ctx, obj, I, idl) {
this.ctx = ctx;
this.obj = obj;
this.interface = I;
this.idl = idl;
}
Attribute.prototype.generate = function () {
let str = "";
let requires = {};
generate() {
let str = "";
const requires = {};
const configurable = !utils.getExtAttr(this.idl.extAttrs, "Unforgeable");
const shouldReflect = utils.getExtAttr(this.idl.extAttrs, "Reflect");
const sameObject = utils.getExtAttr(this.idl.extAttrs, "SameObject");
const configurable = !utils.getExtAttr(this.idl.extAttrs, "Unforgeable");
const shouldReflect = utils.getExtAttr(this.idl.extAttrs, "Reflect");
const sameObject = utils.getExtAttr(this.idl.extAttrs, "SameObject");
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
objName = `obj`;
definedOn = `obj`;
}
let getterBody = `return utils.tryWrapperForImpl(${objName}[impl]["${this.idl.name}"]);`;
let setterBody = `${objName}[impl]["${this.idl.name}"] = V;`;
if (conversions[this.idl.idlType.idlType]) {
getterBody = `return ${objName}[impl]["${this.idl.name}"];`;
}
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
objName = `obj`;
definedOn = `obj`;
}
let getterBody = `return utils.tryWrapperForImpl(${objName}[impl]["${this.idl.name}"]);`;
let setterBody = `${objName}[impl]["${this.idl.name}"] = V;`;
if (conversions[this.idl.idlType.idlType]) {
getterBody = `return ${objName}[impl]["${this.idl.name}"];`;
}
if (this.idl.static) {
getterBody = `return Impl["${this.idl.name}"];`;
setterBody = `Impl["${this.idl.name}"] = V;`;
} else if (shouldReflect) {
if (!reflector[this.idl.idlType.idlType]) {
throw new Error("Unknown reflector type: " + this.idl.idlType.idlType);
if (this.idl.static) {
getterBody = `return Impl["${this.idl.name}"];`;
setterBody = `Impl["${this.idl.name}"] = V;`;
} else if (shouldReflect) {
if (!reflector[this.idl.idlType.idlType]) {
throw new Error("Unknown reflector type: " + this.idl.idlType.idlType);
}
const attrName = shouldReflect.rhs && shouldReflect.rhs.value.replace(/_/g, "-") || this.idl.name;
getterBody = reflector[this.idl.idlType.idlType].get(objName, attrName);
setterBody = reflector[this.idl.idlType.idlType].set(objName, attrName);
}
const attrName = shouldReflect.rhs && shouldReflect.rhs.value.replace(/_/g, '-') || this.idl.name;
getterBody = reflector[this.idl.idlType.idlType].get(objName, attrName);
setterBody = reflector[this.idl.idlType.idlType].set(objName, attrName);
}
if (sameObject) {
getterBody = `return utils.getSameObject(this, "${this.idl.name}", () => { ${getterBody} });`;
}
if (sameObject) {
getterBody = `return utils.getSameObject(this, "${this.idl.name}", () => { ${getterBody} });`;
}
str += `Object.defineProperty(${definedOn}, "${this.idl.name}", {
get() {
${getterBody}
},`;
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"`);
Object.assign(requires, conv.requires);
let conversion = conv.body.replace(/\n/g, "\n ");
str += `
set(V) {${conversion}
${setterBody}
},`;
} else if (utils.getExtAttr(this.idl.extAttrs, "PutForwards")) {
str += `
set(V) {
this.${this.idl.name}.${utils.getExtAttr(this.idl.extAttrs, "PutForwards").rhs.value} = V;
},`;
} else if (utils.getExtAttr(this.idl.extAttrs, "Replaceable")) {
str += `
set(V) {
Object.defineProperty(this, "${this.idl.name}", {
configurable: true,
enumerable: true,
value: V,
writable: true
});
},`;
}
str += `
enumerable: true,
configurable: ${JSON.stringify(configurable)}
});\n\n`;
if (this.idl.stringifier) {
const functionExpression = `
function toString() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
${getterBody};
}
Object.defineProperty(${definedOn}, "${this.idl.name}", {
get() {
${getterBody}
},
`;
if (utils.getExtAttr(this.idl.extAttrs, "Unforgeable")) {
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"`);
Object.assign(requires, conv.requires);
str += `
Object.defineProperty(${definedOn}, "toString", {
writable: false,
enumerable: true,
configurable: false,
value: ${functionExpression}
});
set(V) {
${conv.body}
${setterBody}
},
`;
} else {
} else if (utils.getExtAttr(this.idl.extAttrs, "PutForwards")) {
str += `
${definedOn}.toString = ${functionExpression};
set(V) {
this.${this.idl.name}.${utils.getExtAttr(this.idl.extAttrs, "PutForwards").rhs.value} = V;
},
`;
} else if (utils.getExtAttr(this.idl.extAttrs, "Replaceable")) {
str += `
set(V) {
Object.defineProperty(this, "${this.idl.name}", {
configurable: true,
enumerable: true,
value: V,
writable: true
});
},
`;
}
str += "\n";
str += `
enumerable: true,
configurable: ${JSON.stringify(configurable)}
});
`;
if (this.idl.stringifier) {
const functionExpression = `
function toString() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
${getterBody};
}
`;
if (utils.getExtAttr(this.idl.extAttrs, "Unforgeable")) {
str += `
Object.defineProperty(${definedOn}, "toString", {
writable: false,
enumerable: true,
configurable: false,
value: ${functionExpression}
});
`;
} else {
str += `
${definedOn}.toString = ${functionExpression};
`;
}
str += "\n";
}
return {
requires,
body: str
};
}
}
return {
requires,
body: str
};
};
module.exports = Attribute;
"use strict";
function Constant(ctx, obj, I, idl) {
this.ctx = ctx;
this.obj = obj;
this.interface = I;
this.idl = idl;
class Constant {
constructor(ctx, obj, I, idl) {
this.ctx = ctx;
this.obj = obj;
this.interface = I;
this.idl = idl;
this.str = null;
this.str = null;
}
generate() {
const body = `
Object.defineProperty(${this.obj.name}, "${this.idl.name}", {
value: ${JSON.stringify(this.idl.value.value)},
enumerable: true
});
Object.defineProperty(${this.obj.name}.prototype, "${this.idl.name}", {
value: ${JSON.stringify(this.idl.value.value)},
enumerable: true
});
`;
return {
requires: {},
body
};
}
}
Constant.prototype.generate = function () {
const body = `Object.defineProperty(${this.obj.name}, "${this.idl.name}", {
value: ${JSON.stringify(this.idl.value.value)},
enumerable: true
});
Object.defineProperty(${this.obj.name}.prototype, "${this.idl.name}", {
value: ${JSON.stringify(this.idl.value.value)},
enumerable: true
});\n\n`;
return {
requires: {},
body
};
};
module.exports = Constant;

@@ -11,9 +11,11 @@ "use strict";

this.name = idl.name;
this.requires = {};
}
_generateConversions() {
_prepareFields() {
const fields = [];
const members = this.idl.members;
members.forEach(member => {
if (member.type !== 'field') {
if (member.type !== "field") {
throw new Error("webidl2js doesn't support non-field members in dictionaries");

@@ -25,39 +27,45 @@ }

fields.sort((a, b) => a.name < b.name ? -1 : 1);
return fields;
}
this.str += `
let key, value;`;
fields.forEach(field => {
this.str += `\n
key = "${field.name}";
value = obj === undefined || obj === null ? undefined : obj[key];`;
_generateConversions() {
let str = "";
for (const field of this._prepareFields()) {
const typeConversion = field.idlType;
this.str += `
if (value !== undefined) {`;
const argAttrs = field.extAttrs;
const conv = Types.generateTypeConversion(
this.ctx, "value", typeConversion, argAttrs, this.name, `context + " has member ${field.name} that"`);
Object.assign(this.requires, conv.requires);
const conv = Types.generateTypeConversion(this.ctx, "value", typeConversion, argAttrs, this.name, `\`\${context} has member ${field.name} that\``);
for (let key in conv.requires) {
this.str = `const ${key} = ${conv.requires[key]};\n` + this.str;
}
this.str += conv.body;
this.str += `
ret[key] = value;`
str += `
{
const key = "${field.name}";
let value = obj === undefined || obj === null ? undefined : obj[key];
if (value !== undefined) {
${conv.body}
ret[key] = value;
}
`;
if (field.required) {
this.str += `
} else {
throw new TypeError("${field.name} is required in '${this.name}'");`;
str += `
else {
throw new TypeError("${field.name} is required in '${this.name}'");
}
`;
} else if (field.default) {
this.str += `
} else {
ret[key] = `;
if (field.default.type === "null") {
this.str += `null;`;
} else {
this.str += JSON.stringify(field.default.value) + ';';
str += `
else {
ret[key] = ${utils.getDefault(field.default)};
}
`;
}
str += `
}
}
this.str += `
}`;
});
`;
}
return str;
}

@@ -67,23 +75,36 @@

this.str += `
module.exports = {
convertInherit(obj, ret, { context = "The provided value" } = {}) {`;
module.exports = {
convertInherit(obj, ret, { context = "The provided value" } = {}) {
`;
if (this.idl.inheritance) {
this.str = `const ${this.idl.inheritance} = require("./${this.idl.inheritance}");\n` + this.str;
this.str += `
${this.idl.inheritance}.convertInherit(obj, ret, { context });`;
${this.idl.inheritance}.convertInherit(obj, ret, { context });
`;
}
this._generateConversions();
this.str += `
},
${this._generateConversions()}
},
convert(obj, { context = "The provided value" } = {}) {
if (obj !== undefined && typeof obj !== "object" && typeof obj !== "function") {
throw new TypeError(\`\${context} is not an object.\`);
convert(obj, { context = "The provided value" } = {}) {
if (obj !== undefined && typeof obj !== "object" && typeof obj !== "function") {
throw new TypeError(\`\${context} is not an object.\`);
}
const ret = Object.create(null);
module.exports.convertInherit(obj, ret, { context });
return ret;
}
};
`;
if (this.idl.inheritance) {
this.requires[this.idl.inheritance] = `require("./${this.idl.inheritance}")`;
}
this.str = `
${Object.keys(this.requires).map(key => `const ${key} = ${this.requires[key]};`).join("\n")}
const ret = Object.create(null);
module.exports.convertInherit(obj, ret, { context });
return ret;
}
};`;
${this.str}
`;

@@ -94,3 +115,3 @@ return this.str;

toString() {
this.str = ``;
this.str = "";
this.generate();

@@ -97,0 +118,0 @@ return this.str;

"use strict";
const path = require("path");
const utils = require("../utils");

@@ -14,442 +12,472 @@ const Attribute = require("./attribute");

function Interface(ctx, idl, opts) {
this.ctx = ctx;
this.idl = idl;
this.name = idl.name;
this.factory = !!utils.getExtAttr(this.idl.extAttrs, "WebIDL2JSFactory");
class Interface {
constructor(ctx, idl, opts) {
this.ctx = ctx;
this.idl = idl;
this.name = idl.name;
this.factory = Boolean(utils.getExtAttr(this.idl.extAttrs, "WebIDL2JSFactory"));
this.mixins = [];
this.requires = {};
this.str = null;
this.opts = opts;
this.hasPairIterator = this.idl.members.some(utils.isPairIterable);
}
this.mixins = [];
this.requires = {};
this.str = null;
this.opts = opts;
}
Interface.prototype.type = "interface";
get hasPairIterator() {
return this.idl.members.some(utils.isPairIterable);
}
Interface.prototype.implements = function (source) {
this.mixins.push(source);
};
implements(source) {
this.mixins.push(source);
}
Interface.prototype.generateIterator = function () {
if (this.hasPairIterator) {
this.str += `
const IteratorPrototype = Object.create(utils.IteratorPrototype, {
next: {
value: function next() {
const internal = this[utils.iterInternalSymbol];
const { target, kind, index } = internal;
const values = Array.from(target[impl]);
const len = values.length;
if (index >= len) {
return { value: undefined, done: true };
}
generateIterator() {
if (this.hasPairIterator) {
this.str += `
const IteratorPrototype = Object.create(utils.IteratorPrototype, {
next: {
value: function next() {
const internal = this[utils.iterInternalSymbol];
const { target, kind, index } = internal;
const values = Array.from(target[impl]);
const len = values.length;
if (index >= len) {
return { value: undefined, done: true };
}
const pair = values[index];
internal.index = index + 1;
const [key, value] = pair.map(utils.tryWrapperForImpl);
const pair = values[index];
internal.index = index + 1;
const [key, value] = pair.map(utils.tryWrapperForImpl);
let result;
switch (kind) {
case "key":
result = key;
break;
case "value":
result = value;
break;
case "key+value":
result = [key, value];
break;
}
return { value: result, done: false };
},
writable: true,
enumerable: true,
configurable: true
},
[Symbol.toStringTag]: {
value: "${this.name}Iterator",
writable: false,
enumerable: false,
configurable: true
let result;
switch (kind) {
case "key":
result = key;
break;
case "value":
result = value;
break;
case "key+value":
result = [key, value];
break;
}
return { value: result, done: false };
},
writable: true,
enumerable: true,
configurable: true
},
[Symbol.toStringTag]: {
value: "${this.name}Iterator",
writable: false,
enumerable: false,
configurable: true
}
});
`;
}
}
});
`;
}
};
generateConstructor() {
const overloads = Overloads.getEffectiveOverloads("constructor", 0, this.idl, null);
Interface.prototype.generateConstructor = function () {
const overloads = Overloads.getEffectiveOverloads("constructor", 0, this.idl, null);
if (overloads.length !== 0) {
let minConstructor = overloads[0];
if (overloads.length !== 0) {
let minConstructor = overloads[0];
for (let i = 1; i < overloads.length; ++i) {
if (overloads[i].nameList.length < minConstructor.nameList.length) {
minConstructor = overloads[i];
}
}
for (let i = 1; i < overloads.length; ++i) {
if (overloads[i].nameList.length < minConstructor.nameList.length) {
minConstructor = overloads[i];
const conversions =
Parameters.generateOverloadConversions(this.ctx, overloads, this.name, `Failed to construct '${this.name}': `);
Object.assign(this.requires, conversions.requires);
minConstructor.nameList = minConstructor.nameList.map(name => (keywords.has(name) ? "_" : "") + name);
this.str += `
function ${this.name}(${minConstructor.nameList.join(", ")}) {
`;
if (minConstructor.nameList.length !== 0) {
const plural = minConstructor.nameList.length > 1 ? "s" : "";
this.str += `
if (!new.target) {
throw new TypeError("Failed to construct '${this.name}'. Please use the 'new' operator; this constructor " +
"cannot be called as a function.");
}
if (arguments.length < ${minConstructor.nameList.length}) {
throw new TypeError("Failed to construct '${this.name}': ${minConstructor.nameList.length} " +
"argument${plural} required, but only " + arguments.length + " present.");
}
`;
}
this.str += conversions.body + "\n";
const passArgs = conversions.hasArgs ? ", args" : "";
this.str += `
iface.setup(this${passArgs});
}
`;
} else {
this.str += `
function ${this.name}() {
throw new TypeError("Illegal constructor");
}
`;
}
const conversions = Parameters.generateOverloadConversions(this.ctx, overloads, this.name, `Failed to construct '${this.name}': `);
Object.assign(this.requires, conversions.requires);
minConstructor.nameList = minConstructor.nameList.map((name) => (keywords.has(name) ? "_" : "") + name);
this.str += `function ${this.name}(${minConstructor.nameList.join(", ")}) {`;
if (minConstructor.nameList.length !== 0) {
const plural = minConstructor.nameList.length > 1 ? "s" : "";
if (this.idl.inheritance) {
this.str += `
if (!new.target) {
throw new TypeError("Failed to construct '${this.name}'. Please use the 'new' operator; this constructor cannot be called as a function.");
}
if (arguments.length < ${minConstructor.nameList.length}) {
throw new TypeError("Failed to construct '${this.name}': ${minConstructor.nameList.length} argument${plural} required, but only " + arguments.length + " present.");
}`;
Object.setPrototypeOf(${this.name}.prototype, ${this.idl.inheritance}.interface.prototype);
Object.setPrototypeOf(${this.name}, ${this.idl.inheritance}.interface);
`;
}
this.str += conversions.body + "\n";
const passArgs = conversions.hasArgs ? ", args" : "";
this.str += `
iface.setup(this${passArgs});
}\n`;
} else {
this.str += `function ${this.name}() {
throw new TypeError("Illegal constructor");
}\n`;
Object.defineProperty(${this.name}, "prototype", {
value: ${this.name}.prototype,
writable: false,
enumerable: false,
configurable: false
});
`;
}
if (this.idl.inheritance) {
this.str += `Object.setPrototypeOf(${this.name}.prototype, ${this.idl.inheritance}.interface.prototype);
Object.setPrototypeOf(${this.name}, ${this.idl.inheritance}.interface);\n`;
}
};
generateRequires() {
this.requires.impl = "utils.implSymbol";
Interface.prototype.generateRequires = function () {
let requireStr = ``;
if (this.idl.inheritance !== null) {
this.requires[this.idl.inheritance] = `require("./${this.idl.inheritance}.js")`;
}
if (this.idl.inheritance !== null) {
requireStr += `const ${this.idl.inheritance} = require("./${this.idl.inheritance}.js");\n`;
}
if (this.mixins.length !== 0) {
this.requires.mixin = "utils.mixin";
for (const mixin of this.mixins) {
this.requires[mixin] = `require("./${mixin}.js")`;
}
}
requireStr += `const impl = utils.implSymbol;\n`;
this.str = `
${Object.keys(this.requires).map(key => `const ${key} = ${this.requires[key]};`).join("\n")}
if (this.mixins.length !== 0) {
requireStr += `const mixin = utils.mixin;\n`;
for (let i = 0; i < this.mixins.length; ++i) {
requireStr += `const ${this.mixins[i]} = require("./${this.mixins[i]}.js");\n`;
}
${this.str}
`;
}
for (let key in this.requires) {
requireStr += `const ${key} = ${this.requires[key]};\n`;
generateMixins() {
for (const mixin of this.mixins) {
this.str += `
mixin(${this.name}.prototype, ${mixin}.interface.prototype);
${mixin}.mixedInto.push(${this.name});
`;
}
}
requireStr += `\n`;
this.str = requireStr + this.str;
};
generateExport() {
this.str += `
mixedInto: [],
is(obj) {
if (obj) {
if (obj[impl] instanceof Impl.implementation) {
return true;
}
for (let i = 0; i < module.exports.mixedInto.length; ++i) {
if (obj instanceof module.exports.mixedInto[i]) {
return true;
}
}
}
return false;
},
isImpl(obj) {
if (obj) {
if (obj instanceof Impl.implementation) {
return true;
}
Interface.prototype.generateMixins = function () {
this.str += `\n`;
for (let i = 0; i < this.mixins.length; ++i) {
this.str += `mixin(${this.name}.prototype, ${this.mixins[i]}.interface.prototype);
${this.mixins[i]}.mixedInto.push(${this.name});\n`;
}
};
Interface.prototype.generateExport = function () {
this.str += `
mixedInto: [],
is(obj) {
if (obj) {
if (obj[impl] instanceof Impl.implementation) {
return true;
}
for (let i = 0; i < module.exports.mixedInto.length; ++i) {
if (obj instanceof module.exports.mixedInto[i]) {
return true;
const wrapper = utils.wrapperForImpl(obj);
for (let i = 0; i < module.exports.mixedInto.length; ++i) {
if (wrapper instanceof module.exports.mixedInto[i]) {
return true;
}
}
}
}
}
return false;
},
isImpl(obj) {
if (obj) {
if (obj instanceof Impl.implementation) {
return true;
}
return false;
},
convert(obj, { context = "The provided value" } = {}) {
if (module.exports.is(obj)) {
return utils.implForWrapper(obj);
}
throw new TypeError(\`\${context} is not of type '${this.name}'.\`);
},
`;
const wrapper = utils.wrapperForImpl(obj);
for (let i = 0; i < module.exports.mixedInto.length; ++i) {
if (wrapper instanceof module.exports.mixedInto[i]) {
return true;
}
}
if (this.hasPairIterator) {
this.str += `
createDefaultIterator(target, kind) {
const iterator = Object.create(IteratorPrototype);
Object.defineProperty(iterator, utils.iterInternalSymbol, {
value: { target, kind, index: 0 },
writable: false,
enumerable: false,
configurable: true
});
return iterator;
},
`;
}
return false;
},
convert(obj, { context = "The provided value" } = {}) {
if (module.exports.is(obj)) {
return utils.implForWrapper(obj);
}
throw new TypeError(\`\${context} is not of type '${this.name}'.\`);
},`;
if (this.hasPairIterator) {
this.str += `
createDefaultIterator(target, kind) {
const iterator = Object.create(IteratorPrototype);
Object.defineProperty(iterator, utils.iterInternalSymbol, {
value: { target, kind, index: 0 },
writable: false,
enumerable: false,
configurable: true
});
return iterator;
},`;
}
};
Interface.prototype.generateIface = function () {
const shouldExposeRoot = !utils.getExtAttr(this.idl.extAttrs, "NoInterfaceObject");
generateIface() {
const shouldExposeRoot = !utils.getExtAttr(this.idl.extAttrs, "NoInterfaceObject");
const exposedMap = {};
if (shouldExposeRoot) {
let exposedOn = ["Window"];
const exposedAttrs = this.idl.extAttrs
.filter(function (attr) { return attr.name === "Exposed"; });
if (exposedAttrs.length !== 0) {
if (typeof exposedAttrs[0].rhs.value === "string") {
exposedAttrs[0].rhs.value = [exposedAttrs[0].rhs.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;
}
exposedOn = exposedAttrs[0].rhs.value;
}
for (let i = 0; i < exposedOn.length; ++i) {
if (!exposedMap[exposedOn[i]]) {
exposedMap[exposedOn[i]] = [];
for (let i = 0; i < exposedOn.length; ++i) {
if (!exposedMap[exposedOn[i]]) {
exposedMap[exposedOn[i]] = [];
}
exposedMap[exposedOn[i]].push(this.name);
}
exposedMap[exposedOn[i]].push(this.name);
}
}
let exposers = [];
for (let keys = Object.keys(exposedMap), i = 0; i < keys.length; ++i) {
let exposedOnObj = exposedMap[keys[i]].map(function (o) { return o + ": " + o; });
exposers.push(keys[i] + ": { " + exposedOnObj.join(", ") + " }");
}
const exposers = [];
for (let keys = Object.keys(exposedMap), i = 0; i < keys.length; ++i) {
exposers.push(keys[i] + ": { " + exposedMap[keys[i]].join(", ") + " }");
}
// since we don't have spread arg calls, we can't do new Interface(...arguments) yet
// add initialized symbol as to not destroy the object shape and cause deopts
this.str += `
create(constructorArgs, privateData) {
let obj = Object.create(${this.name}.prototype);
this.setup(obj, constructorArgs, privateData);
return obj;
},
createImpl(constructorArgs, privateData) {
let obj = Object.create(${this.name}.prototype);
this.setup(obj, constructorArgs, privateData);
return utils.implForWrapper(obj);
},
_internalSetup(obj) {`;
// since we don't have spread arg calls, we can't do new Interface(...arguments) yet
// add initialized symbol as to not destroy the object shape and cause deopts
this.str += `
create(constructorArgs, privateData) {
let obj = Object.create(${this.name}.prototype);
this.setup(obj, constructorArgs, privateData);
return obj;
},
createImpl(constructorArgs, privateData) {
let obj = Object.create(${this.name}.prototype);
this.setup(obj, constructorArgs, privateData);
return utils.implForWrapper(obj);
},
_internalSetup(obj) {
`;
if (this.idl.inheritance) {
this.str += `
${this.idl.inheritance}._internalSetup(obj);\n`;
${this.idl.inheritance}._internalSetup(obj);
`;
}
for (let i = 0; i < this.idl.members.length; ++i) {
const memberIdl = this.idl.members[i];
if (utils.isOnInstance(memberIdl, this.idl)) {
let member;
switch (memberIdl.type) {
case "operation": {
member = new Operation(this.ctx, this, this.idl, memberIdl);
break;
for (let i = 0; i < this.idl.members.length; ++i) {
const memberIdl = this.idl.members[i];
if (utils.isOnInstance(memberIdl, this.idl)) {
let member;
switch (memberIdl.type) {
case "operation": {
member = new Operation(this.ctx, this, this.idl, memberIdl);
break;
}
case "attribute": {
member = new Attribute(this.ctx, this, this.idl, memberIdl);
break;
}
default: {
throw new Error("Cannot handle on-instance members that are not operations or attributes");
}
}
case "attribute": {
member = new Attribute(this.ctx, this, this.idl, memberIdl);
break;
}
default: {
throw new Error("Cannot handle on-instance members that are not operations or attributes");
}
this.str += member.generate().body;
}
this.str += "\n" + member.generate().body;
}
}
this.str += `
},
setup(obj, constructorArgs, privateData) {
if (!privateData) privateData = {};`;
if (this.factory) {
this.str += `
for (var prop in defaultPrivateData) {
if (!(prop in privateData)) {
privateData[prop] = defaultPrivateData[prop];
}
}`;
}
},
setup(obj, constructorArgs, privateData) {
if (!privateData) privateData = {};
`;
this.str += `
privateData.wrapper = obj;
if (this.factory) {
this.str += `
for (var prop in defaultPrivateData) {
if (!(prop in privateData)) {
privateData[prop] = defaultPrivateData[prop];
}
}
`;
}
this._internalSetup(obj);\n`;
this.str += `
privateData.wrapper = obj;
const implClass = require(this.opts.implDir + "/" + this.name + this.ctx.implSuffix);
this.str += `
Object.defineProperty(obj, impl, {
value: new Impl.implementation(constructorArgs, privateData),
writable: false,
enumerable: false,
configurable: true
});
obj[impl][utils.wrapperSymbol] = obj;`;
if (implClass.init) {
this.str += `
Impl.init(obj[impl], privateData);`;
this._internalSetup(obj);
Object.defineProperty(obj, impl, {
value: new Impl.implementation(constructorArgs, privateData),
writable: false,
enumerable: false,
configurable: true
});
obj[impl][utils.wrapperSymbol] = obj;
if (Impl.init) {
Impl.init(obj[impl], privateData);
}
},
interface: ${this.name},
expose: {
${exposers.join(",\n ")}
}
`;
}
this.str += `
},
interface: ${this.name},
expose: {
${exposers.join(",\n ")}
}`;
};
Interface.prototype.generateOperations = function () {
const done = {};
for (let i = 0; i < this.idl.members.length; ++i) {
const memberIdl = this.idl.members[i];
let member = null;
generateOperations() {
const done = {};
for (let i = 0; i < this.idl.members.length; ++i) {
const memberIdl = this.idl.members[i];
let member = null;
switch (memberIdl.type) {
case "operation":
if (utils.isOnInstance(memberIdl, this.idl)) {
switch (memberIdl.type) {
case "operation":
if (utils.isOnInstance(memberIdl, this.idl)) {
break;
}
member = new Operation(this.ctx, this, this.idl, memberIdl);
if (done[member.name]) {
continue;
}
done[member.name] = true;
break;
}
member = new Operation(this.ctx, this, this.idl, memberIdl);
if (done[member.name]) {
continue;
}
done[member.name] = true;
break;
case "iterable":
member = new Iterable(this.ctx, this, this.idl, memberIdl);
break;
default:
//throw new Error("Can't handle member of type '" + memberIdl.type + "'");
break;
}
case "iterable":
member = new Iterable(this.ctx, this, this.idl, memberIdl);
break;
default:
// throw new Error("Can't handle member of type '" + memberIdl.type + "'");
break;
}
if (member !== null) {
const data = member.generate();
Object.assign(this.requires, data.requires),
this.str += data.body;
if (member !== null) {
const data = member.generate();
Object.assign(this.requires, data.requires);
this.str += data.body;
}
}
}
};
Interface.prototype.generateAttributes = function () {
for (let i = 0; i < this.idl.members.length; ++i) {
const memberIdl = this.idl.members[i];
let member = null;
generateAttributes() {
for (let i = 0; i < this.idl.members.length; ++i) {
const memberIdl = this.idl.members[i];
let member = null;
switch (memberIdl.type) {
case "attribute":
if (utils.isOnInstance(memberIdl, this.idl)) {
switch (memberIdl.type) {
case "attribute":
if (utils.isOnInstance(memberIdl, this.idl)) {
break;
}
member = new Attribute(this.ctx, this, this.idl, memberIdl);
break;
}
member = new Attribute(this.ctx, this, this.idl, memberIdl);
break;
case "const":
member = new Constant(this.ctx, this, this.idl, memberIdl);
break;
default:
//throw new Error("Can't handle member of type '" + memberIdl.type + "'");
break;
}
case "const":
member = new Constant(this.ctx, this, this.idl, memberIdl);
break;
default:
// throw new Error("Can't handle member of type '" + memberIdl.type + "'");
break;
}
if (member !== null) {
const data = member.generate();
Object.assign(this.requires, data.requires);
this.str += data.body;
if (member !== null) {
const data = member.generate();
Object.assign(this.requires, data.requires);
this.str += data.body;
}
}
}
};
Interface.prototype.generateSymbols = function () {
const unscopables = {};
for (const member of this.idl.members) {
if (utils.getExtAttr(member.extAttrs, "Unscopeable")) {
unscopables[member.name] = true;
generateSymbols() {
const unscopables = Object.create(null);
for (const member of this.idl.members) {
if (utils.getExtAttr(member.extAttrs, "Unscopeable")) {
unscopables[member.name] = true;
}
}
}
if (Object.keys(unscopables).length) {
if (Object.keys(unscopables).length) {
this.str += `
Object.defineProperty(${this.name}.prototype, Symbol.unscopables, {
value: ${JSON.stringify(unscopables, null, " ")},
writable: false,
enumerable: false,
configurable: true
});
`;
}
this.str += `
Object.defineProperty(${this.name}.prototype, Symbol.unscopables, {
value: ${JSON.stringify(unscopables, null, ' ')},
writable: false,
enumerable: false,
configurable: true
});\n`;
Object.defineProperty(${this.name}.prototype, Symbol.toStringTag, {
value: "${this.name}",
writable: false,
enumerable: false,
configurable: true
});
`;
}
this.str += `
Object.defineProperty(${this.name}.prototype, Symbol.toStringTag, {
value: "${this.name}",
writable: false,
enumerable: false,
configurable: true
});\n`;
};
Interface.prototype.generate = function () {
this.generateIterator();
generate() {
this.generateIterator();
if (this.factory) {
this.str += `
module.exports = {
createInterface: function (defaultPrivateData = {}) {\n\n`;
}
if (this.factory) {
this.str += `
module.exports = {
createInterface: function (defaultPrivateData = {}) {
`;
}
this.generateConstructor();
this.generateMixins();
this.generateConstructor();
this.generateMixins();
this.generateOperations();
this.generateAttributes();
this.generateOperations();
this.generateAttributes();
this.generateRequires();
this.generateRequires();
this.generateSymbols();
this.generateSymbols();
this.str += `
const iface = {`;
this.str += `
const iface = {
`;
if (this.factory) {
this.generateIface();
this.str += `
};
return iface;
},`;
this.generateExport();
this.str += `
};\n`;
} else {
this.generateExport();
this.generateIface();
this.str += `
};
module.exports = iface;\n`;
if (this.factory) {
this.generateIface();
this.str += `
}; // iface
return iface;
}, // createInterface
`;
this.generateExport();
this.str += `
}; // module.exports
`;
} else {
this.generateExport();
this.generateIface();
this.str += `
}; // iface
module.exports = iface;
`;
}
}
};
Interface.prototype.toString = function () {
this.str = "";
this.generate();
return this.str;
};
toString() {
this.str = "";
this.generate();
return this.str;
}
}
Interface.prototype.type = "interface";
module.exports = Interface;
"use strict";
const conversions = require("webidl-conversions");
const keywords = require("../keywords");
const utils = require("../utils");
function Iterable(ctx, obj, I, idl) {
this.ctx = ctx;
this.obj = obj;
this.interface = I;
this.idl = idl;
this.name = idl.type;
}
Iterable.prototype.generateFunction = function (key, kind, keyExpr, fnName) {
if (fnName === undefined) {
fnName = typeof key === "symbol" ? "" : (keywords.has(key) ? "_" : key);
class Iterable {
constructor(ctx, obj, I, idl) {
this.ctx = ctx;
this.obj = obj;
this.interface = I;
this.idl = idl;
this.name = idl.type;
}
const propExpr = typeof key === "symbol" ? `[${keyExpr}]` : `.${key}`;
generateFunction(key, kind, keyExpr, fnName) {
if (fnName === undefined) {
if (typeof key === "symbol") {
fnName = "";
} else {
fnName = keywords.has(key) ? "_" : key;
}
}
return `\n${this.obj.name}.prototype${propExpr} = function ${fnName}() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
const propExpr = typeof key === "symbol" ? `[${keyExpr}]` : `.${key}`;
return `
${this.obj.name}.prototype${propExpr} = function ${fnName}() {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
return module.exports.createDefaultIterator(this, "${kind}");
};
`;
}
return module.exports.createDefaultIterator(this, "${kind}");
}`;
};
Iterable.prototype.generate = function () {
const isPairIterator = utils.isPairIterable(this.idl);
let str = "";
generate() {
const isPairIterator = utils.isPairIterable(this.idl);
let str = "";
if (isPairIterator) {
str += this.generateFunction(Symbol.iterator, "key+value", "Symbol.iterator", "entries");
str += `\n${this.obj.name}.prototype.entries = ${this.obj.name}.prototype[Symbol.iterator];`;
str += this.generateFunction("keys", "key");
str += this.generateFunction("values", "value");
str += `\n${this.obj.name}.prototype.forEach = function forEach(callback) {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
if (arguments.length < 1) {
throw new TypeError("Failed to execute 'forEach' on '${this.obj.name}': 1 argument required, but only 0 present.");
}
if (typeof callback !== "function") {
throw new TypeError("Failed to execute 'forEach' on '${this.obj.name}': The callback provided as parameter 1 is not a function.");
}
const thisArg = arguments[1];
let pairs = Array.from(this[impl]);
let i = 0;
while (i < pairs.length) {
const [key, value] = pairs[i].map(utils.tryWrapperForImpl);
callback.call(thisArg, value, key, this);
pairs = Array.from(this[impl]);
i++;
}
};`;
} else {
// value iterator; WIP
}
if (isPairIterator) {
str += `
${this.generateFunction(Symbol.iterator, "key+value", "Symbol.iterator", "entries")}
${this.obj.name}.prototype.entries = ${this.obj.name}.prototype[Symbol.iterator];
${this.generateFunction("keys", "key")}
${this.generateFunction("values", "value")}
${this.obj.name}.prototype.forEach = function forEach(callback) {
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
if (arguments.length < 1) {
throw new TypeError("Failed to execute 'forEach' on '${this.obj.name}': 1 argument required, " +
"but only 0 present.");
}
if (typeof callback !== "function") {
throw new TypeError("Failed to execute 'forEach' on '${this.obj.name}': The callback provided " +
"as parameter 1 is not a function.");
}
const thisArg = arguments[1];
let pairs = Array.from(this[impl]);
let i = 0;
while (i < pairs.length) {
const [key, value] = pairs[i].map(utils.tryWrapperForImpl);
callback.call(thisArg, value, key, this);
pairs = Array.from(this[impl]);
i++;
}
};
`;
} else {
// value iterator; WIP
}
return {
requires: {},
body: str
return {
requires: {},
body: str
};
}
};
}
module.exports = Iterable;

@@ -10,85 +10,89 @@ "use strict";

function Operation(ctx, obj, I, idl) {
this.ctx = ctx;
this.obj = obj;
this.interface = I;
this.idl = idl;
this.name = idl.name;
}
class Operation {
constructor(ctx, obj, I, idl) {
this.ctx = ctx;
this.obj = obj;
this.interface = I;
this.idl = idl;
this.name = idl.name;
}
Operation.prototype.generate = function () {
let requires = {};
let str = "";
generate() {
const requires = {};
let str = "";
if (this.idl.name === null) {
return { requires: {}, body: "" };
}
let name = this.idl.name;
if (!name) {
if (this.idl.stringifier) {
name = "toString";
} else {
return { requires: {}, body: "" };
}
}
let name = this.idl.name;
if (this.idl.stringifier && !name) {
name = "toString";
}
let targetObj = this.obj.name + (this.idl.static ? "" : ".prototype");
if (utils.isOnInstance(this.idl, this.interface)) {
targetObj = "obj";
}
let targetObj = this.obj.name + (this.idl.static ? "" : ".prototype");
if (utils.isOnInstance(this.idl, this.interface)) {
targetObj = "obj";
}
const overloads = Overloads.getEffectiveOverloads(name, 0, this.interface, null);
let minConstructor = overloads[0];
const overloads = Overloads.getEffectiveOverloads(name, 0, this.interface, null);
let minConstructor = overloads[0];
for (let i = 1; i < overloads.length; ++i) {
if (overloads[i].nameList.length < minConstructor.nameList.length) {
minConstructor = overloads[i];
for (let i = 1; i < overloads.length; ++i) {
if (overloads[i].nameList.length < minConstructor.nameList.length) {
minConstructor = overloads[i];
}
}
}
const fnName = keywords.has(name) ? "_" : name;
minConstructor.nameList = minConstructor.nameList.map((name) => (keywords.has(name) ? "_" : "") + name);
const fnName = keywords.has(name) ? "_" : name;
minConstructor.nameList = minConstructor.nameList.map(n => (keywords.has(n) ? "_" : "") + n);
str += `\n${targetObj}.${name} = function ${fnName}(${minConstructor.nameList.join(", ")}) {`;
if (!this.idl.static) {
str += `
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}`;
}
${targetObj}.${name} = function ${fnName}(${minConstructor.nameList.join(", ")}) {
`;
if (!this.idl.static) {
str += `
if (!this || !module.exports.is(this)) {
throw new TypeError("Illegal invocation");
}
`;
}
if (minConstructor.nameList.length !== 0) {
const plural = minConstructor.nameList.length > 1 ? "s" : "";
str += `
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.");
}`;
}
if (minConstructor.nameList.length !== 0) {
const plural = minConstructor.nameList.length > 1 ? "s" : "";
str += `
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.");
}
`;
}
const callOn = this.idl.static ? "Impl" : "this[impl]";
const callOn = this.idl.static ? "Impl" : "this[impl]";
const parameterConversions = Parameters.generateOverloadConversions(this.ctx, overloads, this.interface.name, `Failed to execute '${name}' on '${this.obj.name}': `);
const argsSpread = parameterConversions.hasArgs ? "...args" : "";
Object.assign(requires, parameterConversions.requires);
str += parameterConversions.body;
if (!this.idl.stringifier && overloads.every((overload) => conversions[overload.operation.idlType.idlType])) {
str += `
return ${callOn}.${name}(${argsSpread});
};\n`;
} else {
str += `
return utils.tryWrapperForImpl(${callOn}.${name}(${argsSpread}));
};\n`;
}
if (this.idl.stringifier && name !== "toString") {
str += `\n${this.name}.prototype.toString(${minConstructor.nameList.join(", ")}) {`;
const parameterConversions = Parameters.generateOverloadConversions(
this.ctx, overloads, this.interface.name, `Failed to execute '${name}' on '${this.obj.name}': `);
const argsSpread = parameterConversions.hasArgs ? "...args" : "";
Object.assign(requires, parameterConversions.requires);
str += parameterConversions.body;
str += `
return ${callOn}.${name}.apply(${argsSpread});
};\n`;
}
return {
requires,
body: str
if (this.idl.stringifier || overloads.every(overload => conversions[overload.operation.idlType.idlType])) {
str += `
return ${callOn}.${name}(${argsSpread});
};
`;
} else {
str += `
return utils.tryWrapperForImpl(${callOn}.${name}(${argsSpread}));
};
`;
}
return {
requires,
body: str
};
}
};
}
module.exports = Operation;

@@ -22,4 +22,4 @@ "use strict";

this.typedefs = new Map();
this.interfaces = Object.create(null);
this.dictionaries = Object.create(null);
this.interfaces = new Map();
this.dictionaries = new Map();

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

@@ -0,1 +1,3 @@

"use strict";
module.exports = new Set([

@@ -10,2 +12,2 @@ "break", "case", "class", "catch", "const", "continue", "debugger", "default", "delete",

"null", "true", "false"]);
"null", "true", "false"]);

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

}
return Buffer.from(bufferSource.buffer, bufferSource.byteOffset, bufferSource.byteLength)
return Buffer.from(bufferSource.buffer, bufferSource.byteOffset, bufferSource.byteLength);
}

@@ -48,3 +48,4 @@

return wrapper[sameObjectCaches][prop] = creator();
wrapper[sameObjectCaches][prop] = creator();
return wrapper[sameObjectCaches][prop];
}

@@ -54,7 +55,7 @@

return impl ? impl[wrapperSymbol] : null;
};
}
function implForWrapper(wrapper) {
return wrapper ? wrapper[implSymbol] : null;
};
}

@@ -64,3 +65,3 @@ function tryWrapperForImpl(impl) {

return wrapper ? wrapper : impl;
};
}

@@ -70,3 +71,3 @@ function tryImplForWrapper(wrapper) {

return impl ? impl : wrapper;
};
}

@@ -73,0 +74,0 @@ const iterInternalSymbol = Symbol("internal");

"use strict";
module.exports.getEffectiveOverloads = function (A, N, I, C) {
module.exports.getEffectiveOverloads = function (A, N, I) { // No |C| since we don't support callback function yet.
const S = [];
let F = null;
if (A === 'constructor') { // let's hope no-one specs a member named "constructor"
F = I.extAttrs
.filter(function (a) { return a.name === 'Constructor'; });
F.forEach(function (c) { if (!c.arguments) { c.arguments = []; }});
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 = [];
}
}
} else if (typeof A === "string") {
F = I.members
.filter(function (m) {
return m.name === A || (A === "toString" && m.stringifier);
});
F.forEach(function (m) { if (m.stringifier) { m.arguments = []; }});
F = I.members.filter(m => m.name === A || (A === "toString" && m.stringifier));
for (const m of F) {
if (m.stringifier) {
m.arguments = [];
}
}
}

@@ -29,7 +33,11 @@

const n = X.arguments.length;
const nameList = X.arguments.map(function (arg) { return arg.name; });
const typeList = X.arguments.map(function (arg) { return arg.idlType.idlType; });
const optionalityList = X.arguments.map(function (arg) {
if (arg.optional) return "optional";
if (arg.variadic) return "variadic";
const nameList = X.arguments.map(arg => arg.name);
const typeList = X.arguments.map(arg => arg.idlType.idlType);
const optionalityList = X.arguments.map(arg => {
if (arg.optional) {
return "optional";
}
if (arg.variadic) {
return "variadic";
}
return "required";

@@ -40,19 +48,22 @@ });

operation: X,
nameList: nameList,
typeList: typeList,
optionalityList: optionalityList
nameList,
typeList,
optionalityList
});
if (optionalityList[optionalityList.length - 1] === "variadic") {
S.push({
operation: X,
nameList: nameList.slice(0, -1),
typeList: typeList.slice(0, -1),
optionalityList: optionalityList.slice(0, -1)
});
//TODO: Handle variadic arguments better
for (let i = n; i <= m - 1; i++) {
S.push({
operation: X,
nameList: nameList.slice(0, i + 1),
typeList: typeList.slice(0, i + 1),
optionalityList: optionalityList.slice(0, i + 1)
});
}
}
for (let i = n - 1; i >= 0; --i) {
if (optionalityList[i] === "required") break;
if (optionalityList[i] === "required") {
break;
}
S.push({

@@ -59,0 +70,0 @@ operation: X,

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

function getDefault(dflt) {
switch (dflt.type) {
case "boolean":
case "number":
case "string":
return JSON.stringify(dflt.value);
case "null":
case "NaN":
return dflt.type;
case "Infinity":
return `${dflt.negative ? "-" : ""}Infinity`;
case "sequence":
return "[]";
}
throw new Error("Unexpected default type: " + dflt.type);
}
function generateVarConversion(ctx, name, conversion, argAttrs, ...typeArgs) {

@@ -32,5 +15,8 @@ const { customTypes } = ctx;

if (conversion.optional && customTypes.get(idlType.idlType) !== "dictionary") { // always (try to) force-convert dictionaries
// Always (try to) force-convert dictionaries
const optional = conversion.optional && customTypes.get(idlType.idlType) !== "dictionary";
if (optional) {
str += `
if (${name} !== undefined) {`;
if (${name} !== undefined) {
`;
}

@@ -42,9 +28,10 @@

if (conversion.optional && customTypes.get(idlType.idlType) !== "dictionary") {
str += `
}`;
if (optional) {
str += "}";
if (conversion.default) {
str += ` else {
${name} = ${getDefault(conversion.default)};
}`;
str += `
else {
${name} = ${utils.getDefault(conversion.default)};
}
`;
}

@@ -57,6 +44,5 @@ }

};
};
}
module.exports.generateOverloadConversions = function (ctx, overloads, parentName, errPrefix) {
const { customTypes } = ctx;
const requires = {};

@@ -85,7 +71,8 @@ let str = ``;

const extraClause = !isVariadic ? ` && i < ${maxArguments}` : ``;
str += `\n
const args = [];
for (let i = 0; i < arguments.length${extraClause}; ++i) {
args[i] = arguments[i];
}`;
str += `
const args = [];
for (let i = 0; i < arguments.length${extraClause}; ++i) {
args[i] = arguments[i];
}
`;

@@ -97,3 +84,5 @@ for (let i = 0; i < typeConversions.length; ++i) {

const conv = generateVarConversion(ctx, `args[${i}]`, typeConversions[i], maxConstructor.operation.arguments[i].extAttrs, parentName, `"${errPrefix}parameter ${i + 1}"`);
const conv = generateVarConversion(
ctx, `args[${i}]`, typeConversions[i], maxConstructor.operation.arguments[i].extAttrs, parentName,
`"${errPrefix}parameter ${i + 1}"`);
Object.assign(requires, conv.requires);

@@ -100,0 +89,0 @@ str += conv.body;

"use strict";
module.exports["boolean"] = {
module.exports.boolean = {
get(objName, attrName) {

@@ -8,14 +8,18 @@ return `return this.hasAttribute("${attrName}");`;

set(objName, attrName) {
return `if (V) {
this.setAttribute("${attrName}", "");
} else {
this.removeAttribute("${attrName}");
}`;
return `
if (V) {
this.setAttribute("${attrName}", "");
} else {
this.removeAttribute("${attrName}");
}
`;
}
};
module.exports["DOMString"] = {
module.exports.DOMString = {
get(objName, attrName) {
return `const value = this.getAttribute("${attrName}");
return value === null ? "" : value;`;
return `
const value = this.getAttribute("${attrName}");
return value === null ? "" : value;
`;
},

@@ -27,6 +31,8 @@ set(objName, attrName) {

module.exports["long"] = {
module.exports.long = {
get(objName, attrName) {
return `const value = parseInt(this.getAttribute("${attrName}"));
return isNaN(value) || value < -2147483648 || value > 2147483647 ? 0 : value`;
return `
const value = parseInt(this.getAttribute("${attrName}"));
return isNaN(value) || value < -2147483648 || value > 2147483647 ? 0 : value
`;
},

@@ -40,9 +46,10 @@ set(objName, attrName) {

get(objName, attrName) {
return `const value = parseInt(this.getAttribute("${attrName}"));
return isNaN(value) || value < 0 || value > 2147483647 ? 0 : value`;
return `
const value = parseInt(this.getAttribute("${attrName}"));
return isNaN(value) || value < 0 || value > 2147483647 ? 0 : value
`;
},
set(objName, attrName) {
return `V = V > 2147483647 ? 0 : V;
this.setAttribute("${attrName}", String(V));`;
return `this.setAttribute("${attrName}", String(V > 2147483647 ? 0 : V));`;
}
};

@@ -38,4 +38,4 @@ "use strict";

*_collectSources() {
const stats = yield Promise.all(this.sources.map((src) => fs.stat(src.idlPath)));
* _collectSources() {
const stats = yield Promise.all(this.sources.map(src => fs.stat(src.idlPath)));
const files = [];

@@ -63,5 +63,5 @@ for (let i = 0; i < stats.length; ++i) {

*_readFiles(files) {
* _readFiles(files) {
const zipped = [];
const fileContents = yield Promise.all(files.map((f) => fs.readFile(f.idlPath, { encoding: 'utf-8' })));
const fileContents = yield Promise.all(files.map(f => fs.readFile(f.idlPath, { encoding: "utf-8" })));
for (let i = 0; i < files.length; ++i) {

@@ -76,4 +76,4 @@ zipped.push({

*_parse(outputDir, contents) {
const parsed = contents.map((content) => ({
_parse(outputDir, contents) {
const parsed = contents.map(content => ({
idl: webidl.parse(content.idlContent),

@@ -99,3 +99,3 @@ impl: content.impl

});
interfaces[obj.name] = obj;
interfaces.set(obj.name, obj);
customTypes.set(obj.name, "interface");

@@ -111,3 +111,3 @@ break;

obj = new Dictionary(this.ctx, instruction);
dictionaries[obj.name] = obj;
dictionaries.set(obj.name, obj);
customTypes.set(obj.name, "dictionary");

@@ -138,9 +138,9 @@ break;

if (this.options.suppressErrors && !interfaces[instruction.name]) {
if (this.options.suppressErrors && !interfaces.has(instruction.name)) {
break;
}
oldMembers = interfaces[instruction.name].idl.members;
oldMembers.push.apply(oldMembers, instruction.members);
extAttrs = interfaces[instruction.name].idl.extAttrs;
extAttrs.push.apply(extAttrs, instruction.extAttrs);
oldMembers = interfaces.get(instruction.name).idl.members;
oldMembers.push(...instruction.members);
extAttrs = interfaces.get(instruction.name).idl.extAttrs;
extAttrs.push(...instruction.extAttrs);
break;

@@ -151,15 +151,15 @@ case "dictionary":

}
if (this.options.suppressErrors && !dictionaries[instruction.name]) {
if (this.options.suppressErrors && !dictionaries.has(instruction.name)) {
break;
}
oldMembers = dictionaries[instruction.name].idl.members;
oldMembers.push.apply(oldMembers, instruction.members);
extAttrs = dictionaries[instruction.name].idl.extAttrs;
extAttrs.push.apply(extAttrs, instruction.extAttrs);
oldMembers = dictionaries.get(instruction.name).idl.members;
oldMembers.push(...instruction.members);
extAttrs = dictionaries.get(instruction.name).idl.extAttrs;
extAttrs.push(...instruction.extAttrs);
break;
case "implements":
if (this.options.suppressErrors && !interfaces[instruction.target]) {
if (this.options.suppressErrors && !interfaces.has(instruction.target)) {
break;
}
interfaces[instruction.target].implements(instruction.implements);
interfaces.get(instruction.target).implements(instruction.implements);
break;

@@ -171,4 +171,4 @@ }

*_writeFiles(outputDir) {
let utilsText = yield fs.readFile(__dirname + "/output/utils.js");
* _writeFiles(outputDir) {
const utilsText = yield fs.readFile(path.resolve(__dirname, "output/utils.js"));
yield fs.writeFile(this.options.utilPath, utilsText);

@@ -178,15 +178,3 @@

let interfaceStub = yield fs.readFile(__dirname + "/output/interfaceStub.js");
let keys = Object.keys(interfaces).concat(Object.keys(dictionaries));
for (let key of keys) {
if (interfaces[key]) {
yield fs.writeFile(path.join(outputDir, interfaces[key].name + ".js"), interfaceStub);
} else {
yield fs.writeFile(path.join(outputDir, dictionaries[key].name + ".js"), "");
}
}
keys = Object.keys(interfaces);
for (let i = 0; i < keys.length; ++i) {
const obj = interfaces[keys[i]];
for (const obj of interfaces.values()) {
let source = obj.toString();

@@ -200,3 +188,3 @@

let relativeUtils = path.relative(outputDir, this.options.utilPath).replace(/\\/g, '/');
let relativeUtils = path.relative(outputDir, this.options.utilPath).replace(/\\/g, "/");
if (relativeUtils[0] !== ".") {

@@ -206,7 +194,10 @@ relativeUtils = "./" + relativeUtils;

source = `"use strict";
source = `
"use strict";
const conversions = require("webidl-conversions");
const utils = require("${relativeUtils}");\n${source}
const Impl = require("${implFile}.js");\n`;
const conversions = require("webidl-conversions");
const utils = require("${relativeUtils}");
${source}
const Impl = require("${implFile}.js");
`;

@@ -218,8 +209,6 @@ source = this._prettify(source);

keys = Object.keys(dictionaries);
for (let i = 0; i < keys.length; ++i) {
const obj = dictionaries[keys[i]];
for (const obj of dictionaries.values()) {
let source = obj.toString();
let relativeUtils = path.relative(outputDir, this.options.utilPath).replace(/\\/g, '/');
let relativeUtils = path.relative(outputDir, this.options.utilPath).replace(/\\/g, "/");
if (relativeUtils[0] !== ".") {

@@ -229,6 +218,9 @@ relativeUtils = "./" + relativeUtils;

source = `"use strict";
source = `
"use strict";
const conversions = require("webidl-conversions");
const utils = require("${relativeUtils}");\n\n` + source;
const conversions = require("webidl-conversions");
const utils = require("${relativeUtils}");
${source}
`;

@@ -243,3 +235,3 @@ source = this._prettify(source);

return prettier.format(source, {
printWidth: 120,
printWidth: 120
});

@@ -249,3 +241,5 @@ }

generate(outputDir) {
if (!this.options.utilPath) this.options.utilPath = path.join(outputDir, "utils.js");
if (!this.options.utilPath) {
this.options.utilPath = path.join(outputDir, "utils.js");
}

@@ -255,3 +249,3 @@ return co(function* () {

const contents = yield* this._readFiles(sources);
yield* this._parse(outputDir, contents);
this._parse(outputDir, contents);
yield* this._writeFiles(outputDir);

@@ -258,0 +252,0 @@ }.bind(this));

@@ -7,2 +7,15 @@ "use strict";

const arrayBufferViewTypes = new Set([
"Int8Array", "Int16Array", "Int32Array", "Uint8Array", "Uint16Array", "Uint32Array",
"Uint8ClampedArray", "Float32Array", "Float64Array", "DataView"
]);
const stringTypes = new Set(["DOMString", "ByteString", "USVString"]);
const integerTypes = new Set([
"byte", "octet", "short", "unsigned short", "long", "unsigned long",
"long long", "unsigned long long"
]);
const numericTypes = new Set([
...integerTypes, "float", "unrestricted float", "double", "unrestricted double"
]);
function mergeExtAttrs(a = [], b = []) {

@@ -55,6 +68,5 @@ return [...a, ...b];

return idlType;
} else {
// unknown
return idlType;
}
// unknown
return idlType;
}

@@ -76,5 +88,6 @@

str += `
if (${name} === null || ${name} === undefined) {
${name} = null;
} else {`;
if (${name} === null || ${name} === undefined) {
${name} = null;
} else {
`;
}

@@ -115,8 +128,8 @@

str += `
${name} = utils.tryImplForWrapper(${name});`;
${name} = utils.tryImplForWrapper(${name});
`;
}
if (idlType.nullable) {
str += `
}`;
str += "}";
}

@@ -140,8 +153,9 @@

if (!idlType.nullable && union.dictionary) {
let str = `if (${name} === null || ${name} === undefined) {`
const conv = generateTypeConversion(ctx, name, union.dictionary, [], parentName, errPrefix);
Object.assign(requires, conv.requires);
str += conv.body;
str += "}";
output.push(str);
output.push(`
if (${name} === null || ${name} === undefined) {
${conv.body}
}
`);
}

@@ -165,5 +179,7 @@

});
output.push(`if (${exprs.join(" || ")}) {
${name} = utils.implForWrapper(${name});
}`);
output.push(`
if (${exprs.join(" || ")}) {
${name} = utils.implForWrapper(${name});
}
`);
}

@@ -195,10 +211,11 @@

if (union.sequenceLike || union.dictionary || union.record || union.object) {
let str = `if (utils.isObject(${name})) {`;
let code = `if (utils.isObject(${name})) {`;
if (union.sequenceLike) {
str += `if (${name}[Symbol.iterator] !== undefined) {`;
const conv = generateTypeConversion(ctx, name, union.sequenceLike, [], parentName, `${errPrefix} + " sequence"`);
code += `if (${name}[Symbol.iterator] !== undefined) {`;
const conv = generateTypeConversion(ctx, name, union.sequenceLike, [], parentName,
`${errPrefix} + " sequence"`);
Object.assign(requires, conv.requires);
str += conv.body;
str += `} else {`;
code += conv.body;
code += `} else {`;
}

@@ -208,5 +225,6 @@

const prop = union.dictionary ? "dictionary" : "record";
const conv = generateTypeConversion(ctx, name, union[prop], [], parentName, `${errPrefix} + " ${prop}"`);
const conv = generateTypeConversion(ctx, name, union[prop], [], parentName,
`${errPrefix} + " ${prop}"`);
Object.assign(requires, conv.requires);
str += conv.body;
code += conv.body;
} else if (union.object) {

@@ -217,32 +235,36 @@ // noop

if (union.sequenceLike) {
str += "}";
code += "}";
}
str += "}";
code += "}";
output.push(str);
output.push(code);
}
if (union.boolean) {
output.push(`if (typeof ${name} === "boolean") {
${generateTypeConversion(ctx, name, union.boolean, [], parentName, errPrefix).body}
}`);
output.push(`
if (typeof ${name} === "boolean") {
${generateTypeConversion(ctx, name, union.boolean, [], parentName, errPrefix).body}
}
`);
}
if (union.numeric) {
output.push(`if (typeof ${name} === "number") {
${generateTypeConversion(ctx, name, union.numeric, [], parentName, errPrefix).body}
}`);
output.push(`
if (typeof ${name} === "number") {
${generateTypeConversion(ctx, name, union.numeric, [], parentName, errPrefix).body}
}
`);
}
{
let str = "{";
let code = "{";
const type = union.string || union.numeric || union.boolean;
if (type) {
str += generateTypeConversion(ctx, name, type, [], parentName, errPrefix).body;
code += generateTypeConversion(ctx, name, type, [], parentName, errPrefix).body;
} else {
str += `throw new TypeError(${errPrefix} + " is not of any supported type.")`;
code += `throw new TypeError(${errPrefix} + " is not of any supported type.")`;
}
str += "}";
output.push(str);
code += "}";
output.push(code);
}

@@ -254,61 +276,68 @@

function generateSequence() {
str += `
if (!utils.isObject(${name})) {
throw new TypeError(${errPrefix} + " is not an iterable object.");
} else {
const V = [];
const tmp = ${name};
for (let nextItem of tmp) {`;
const conv = generateTypeConversion(ctx, "nextItem", idlType.idlType, [], parentName, `${errPrefix} + "'s element"`);
const conv = generateTypeConversion(ctx, "nextItem", idlType.idlType, [], parentName,
`${errPrefix} + "'s element"`);
Object.assign(requires, conv.requires);
str += conv.body;
str += `
V.push(nextItem);
}
${name} = V;
}`;
if (!utils.isObject(${name})) {
throw new TypeError(${errPrefix} + " is not an iterable object.");
} else {
const V = [];
const tmp = ${name};
for (let nextItem of tmp) {
${conv.body}
V.push(nextItem);
}
${name} = V;
}
`;
}
function generateRecord() {
str += `
if (!utils.isObject(${name})) {
throw new TypeError(${errPrefix} + " is not an object.");
} else {
const result = Object.create(null);
for (const key of Reflect.ownKeys(${name})) {
const desc = Object.getOwnPropertyDescriptor(${name}, key);
if (desc && desc.enumerable) {
let typedKey = key;
let typedValue = ${name}[key];`;
const keyConv = generateTypeConversion(ctx, "typedKey", idlType.idlType[0], [], parentName,
`${errPrefix} + "'s key"`);
Object.assign(requires, keyConv.requires);
const valConv = generateTypeConversion(ctx, "typedValue", idlType.idlType[1], [], parentName,
`${errPrefix} + "'s value"`);
Object.assign(requires, valConv.requires);
str += generateTypeConversion(ctx, "typedKey", idlType.idlType[0], [], parentName, `${errPrefix} + "'s key"`).body;
const conv = generateTypeConversion(ctx, "typedValue", idlType.idlType[1], [], parentName, `${errPrefix} + "'s value"`);
Object.assign(requires, conv.requires);
str += conv.body;
str += `
result[typedKey] = typedValue;
if (!utils.isObject(${name})) {
throw new TypeError(${errPrefix} + " is not an object.");
} else {
const result = Object.create(null);
for (const key of Reflect.ownKeys(${name})) {
const desc = Object.getOwnPropertyDescriptor(${name}, key);
if (desc && desc.enumerable) {
let typedKey = key;
let typedValue = ${name}[key];
${keyConv.body}
${valConv.body}
result[typedKey] = typedValue;
}
}
${name} = result;
}
}
${name} = result;
}`;
`;
}
function generatePromise() {
str += `
${name} = Promise.resolve(${name}).then(value => {`
let handler;
if (idlType.idlType.idlType === "void") {
// Do nothing.
handler = "";
} else {
const conv = generateTypeConversion(ctx, "value", idlType.idlType, [], parentName, `${errPrefix} + " promise value"`);
const conv = generateTypeConversion(ctx, "value", idlType.idlType, [], parentName,
`${errPrefix} + " promise value"`);
Object.assign(requires, conv.requires);
str += conv.body;
str += `
return value;`;
handler = `
${conv.body}
return value;
`;
}
str += `
}, reason => reason);`;
${name} = Promise.resolve(${name}).then(value => {
${handler}
}, reason => reason);
`;
}

@@ -318,4 +347,3 @@

generateSequence();
str += `
${name} = Object.freeze(${name});`;
str += `${name} = Object.freeze(${name});`;
}

@@ -328,21 +356,22 @@

let optString = `, { context: ${errPrefix}`;
let optString = `context: ${errPrefix},`;
if (clamp) {
optString += ", clamp: true";
optString += "clamp: true,";
}
if (enforceRange) {
optString += ", enforceRange: true";
optString += "enforceRange: true,";
}
if (treatNullAs && treatNullAs.rhs.value === "EmptyString") {
optString += ", treatNullAsEmptyString: true";
optString += "treatNullAsEmptyString: true,";
}
optString += " }";
if (idlType.array) {
str += `
for (let i = 0; i < ${name}.length; ++i) {
${name}[i] = ${conversionFn}(${name}[i]${optString});
}`;
for (let i = 0; i < ${name}.length; ++i) {
${name}[i] = ${conversionFn}(${name}[i], { ${optString} });
}
`;
} else {
str += `
${name} = ${conversionFn}(${name}${optString});`;
${name} = ${conversionFn}(${name}, { ${optString} });
`;
}

@@ -352,15 +381,2 @@ }

const arrayBufferViewTypes = new Set([
"Int8Array", "Int16Array", "Int32Array", "Uint8Array", "Uint16Array", "Uint32Array",
"Uint8ClampedArray", "Float32Array", "Float64Array", "DataView"
]);
const stringTypes = new Set(["DOMString", "ByteString", "USVString"]);
const integerTypes = new Set([
"byte", "octet", "short", "unsigned short", "long", "unsigned long",
"long long", "unsigned long long"
]);
const numericTypes = new Set([
...integerTypes, "float", "unrestricted float", "double", "unrestricted double"
]);
// Condense the member types of a union to a more consumable structured object. At the same time, check for the validity

@@ -485,3 +501,3 @@ // of the union type (no forbidden types, no indistinguishable member types). Duplicated types are allowed for now

} else {
error(`Unknown custom type ${type}`)
error(`Unknown custom type ${type}`);
}

@@ -495,3 +511,3 @@ } else {

function error(msg) {
throw new Error(`${msg}\n When compiling "${eval(errPrefix)}"`);
throw new Error(`${msg}\n When compiling "${eval(errPrefix)}"`); // eslint-disable-line no-eval
}

@@ -498,0 +514,0 @@ }

"use strict";
module.exports.getExtAttr = function getExtAttr(attrs, name) {
function getDefault(dflt) {
switch (dflt.type) {
case "boolean":
case "number":
case "string":
return JSON.stringify(dflt.value);
case "null":
case "NaN":
return dflt.type;
case "Infinity":
return `${dflt.negative ? "-" : ""}Infinity`;
case "sequence":
return "[]";
}
throw new Error("Unexpected default type: " + dflt.type);
}
function getExtAttr(attrs, name) {
for (let i = 0; i < attrs.length; ++i) {

@@ -11,16 +28,23 @@ if (attrs[i].name === name) {

return null;
};
}
module.exports.isGlobal = function isGlobal(idl) {
const isGlobal = !!module.exports.getExtAttr(idl.extAttrs, "Global") ||
!!module.exports.getExtAttr(idl.extAttrs, "PrimaryGlobal");
return isGlobal;
};
function isGlobal(idl) {
return Boolean(getExtAttr(idl.extAttrs, "Global")) ||
Boolean(getExtAttr(idl.extAttrs, "PrimaryGlobal"));
}
module.exports.isPairIterable = function isPairIterable(idl) {
function isPairIterable(idl) {
return idl.type === "iterable" && Array.isArray(idl.idlType) && idl.idlType.length === 2;
};
}
module.exports.isOnInstance = (memberIDL, interfaceIDL) => {
return module.exports.getExtAttr(memberIDL.extAttrs, "Unforgeable") || module.exports.isGlobal(interfaceIDL);
function isOnInstance(memberIDL, interfaceIDL) {
return getExtAttr(memberIDL.extAttrs, "Unforgeable") || isGlobal(interfaceIDL);
}
module.exports = {
getDefault,
getExtAttr,
isGlobal,
isPairIterable,
isOnInstance
};
{
"name": "webidl2js",
"version": "7.1.1",
"version": "7.2.0",
"description": "Auto-generates class structures for WebIDL specifications",

@@ -9,7 +9,8 @@ "main": "lib/transformer.js",

"pn": "^1.0.0",
"prettier": "^1.5.2",
"prettier": "^1.5.3",
"webidl-conversions": "^4.0.0",
"webidl2": "^4.0.0"
"webidl2": "^4.1.0"
},
"devDependencies": {
"eslint": "^4.3.0",
"jest": "^20.0.4"

@@ -19,3 +20,4 @@ },

"test": "jest",
"update-snapshots": "jest --updateSnapshot"
"update-snapshots": "jest --updateSnapshot",
"lint": "eslint ."
},

@@ -22,0 +24,0 @@ "author": "Sebastian Mayr <npm@smayr.name>",

Sorry, the diff of this file is not supported yet

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