Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

webidl2js

Package Overview
Dependencies
Maintainers
1
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 1.0.1 to 2.0.0

lib/constructs/dictionary.js

50

index.js

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

const Interface = require("./lib/constructs/interface");
const Dictionary = require("./lib/constructs/dictionary");

@@ -14,7 +15,16 @@ module.exports.generate = function (text, outputDir, implDir, opts) {

if (!opts.implSuffix) opts.implSuffix = "";
if (!opts.utilPath) opts.utilPath = path.join(implDir, "utils.js");
if (!opts.utilPath) opts.utilPath = path.join(outputDir, "utils.js");
const interfaces = {};
const dictionaries = {};
const customTypes = new Set();
const idl = webidl.parse(text);
for (var i = 0; i < idl.length; ++i) {
switch (idl[i].type) {
case "dictionary":
customTypes.add(idl[i].name);
break;
}
}
for (var i = 0; i < idl.length; ++i) {
let obj;

@@ -27,3 +37,3 @@ switch (idl[i].type) {

obj = new Interface(idl[i], { implDir: path.resolve(outputDir, implDir), implSuffix: opts.implSuffix });
obj = new Interface(idl[i], { implDir: path.resolve(outputDir, implDir), implSuffix: opts.implSuffix, customTypes });
interfaces[obj.name] = obj;

@@ -33,2 +43,6 @@ break;

break; // handled later
case "dictionary":
obj = new Dictionary(idl[i], { customTypes });
dictionaries[obj.name] = obj;
break;
default:

@@ -66,5 +80,3 @@ if (!opts.suppressErrors) {

let utilsText = fs.readFileSync(__dirname + "/lib/output/utils.js");
const keys = Object.keys(interfaces);
let keys = Object.keys(interfaces);
for (let i = 0; i < keys.length; ++i) {

@@ -79,3 +91,6 @@ const obj = interfaces[keys[i]];

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

@@ -89,6 +104,27 @@ source = `"use strict";

fs.writeFileSync(path.join(outputDir, obj.name + ".js"), source);
utilsText += `module.exports.implSymbols["${keys[i]}"] = Symbol("${keys[i]} implementation");\n`;
}
keys = Object.keys(dictionaries);
for (let i = 0; i < keys.length; ++i) {
const obj = dictionaries[keys[i]];
let source = obj.toString();
const relativeUtils = path.relative(outputDir, opts.utilPath).replace(/\\/g, '/');
source = `"use strict";
const conversions = require("webidl-conversions");
const utils = require("${relativeUtils}");\n\n` + source;
fs.writeFileSync(path.join(outputDir, obj.name + ".js"), source);
}
let utilsText = fs.readFileSync(__dirname + "/lib/output/utils.js");
const interfaceNames = opts.utilSymbols || [];
interfaceNames.push.apply(interfaceNames, Object.keys(interfaces));
for (let i = 0; i < interfaceNames.length; ++i) {
utilsText += `module.exports.implSymbols["${interfaceNames[i]}"] = Symbol("${interfaceNames[i]} implementation");\n`;
}
fs.writeFileSync(opts.utilPath, utilsText);
};

54

lib/constructs/attribute.js

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

const reflector = require("../reflector");
const Parameters = require("../parameters");

@@ -13,19 +14,22 @@ function Attribute(obj, I, idl) {

this.idl = idl;
this.str = null;
}
Attribute.prototype.generate = function () {
const configurable = utils.hasExtAttr(this.idl.extAttrs, "Unforgeable") ? "false" : "true";
const shouldReflect = utils.hasExtAttr(this.idl.extAttrs, "Reflect");
let str = "";
let requires = {};
const configurable = utils.getExtAttr(this.idl.extAttrs, "Unforgeable") ? "false" : "true";
const shouldReflect = utils.getExtAttr(this.idl.extAttrs, "Reflect");
let objName = `this`;
let definedOn = this.obj.name + (this.idl.static ? "" : ".prototype");
if (configurable === "false") { // we're in the constructor and define an Unforgeable attribute
definedOn = `this`;
if (configurable === "false") { // we're in a setup method and define an Unforgeable attribute
objName = `obj`;
definedOn = `obj`;
}
let getterBody = `return this[impl].${this.idl.name}`;
let setterBody = `this[impl].${this.idl.name} = V;`;
let getterBody = `return ${objName}[impl].${this.idl.name};`;
let setterBody = `${objName}[impl].${this.idl.name} = V;`;
if (this.idl.static) {
getterBody = `return Impl.${this.idl.name}`;
getterBody = `return Impl.${this.idl.name};`;
setterBody = `Impl.${this.idl.name} = V;`;

@@ -36,7 +40,7 @@ } else if (shouldReflect) {

}
getterBody = reflector[this.idl.idlType.idlType].get(this.idl.name);
setterBody = reflector[this.idl.idlType.idlType].set(this.idl.name);
getterBody = reflector[this.idl.idlType.idlType].get(objName, this.idl.name);
setterBody = reflector[this.idl.idlType.idlType].set(objName, this.idl.name);
}
this.str += `Object.defineProperty(${definedOn}, "${this.idl.name}", {
str += `Object.defineProperty(${definedOn}, "${this.idl.name}", {
get() {

@@ -46,8 +50,6 @@ ${getterBody}

if (!this.idl.readonly) {
let conversion = ``;
if (conversions[this.idl.idlType.idlType]) {
conversion = `
V = conversions["${this.idl.idlType.idlType}"](V);`;
}
this.str += `
const conv = Parameters.generateVarConversion("V", { type: this.idl.idlType, optional: false }, this.idl.extAttrs, new Set());
Object.assign(requires, conv.requires);
let conversion = conv.body.replace(/\n/g, "\n ");
str += `
set(V) {${conversion}

@@ -57,3 +59,3 @@ ${setterBody}

}
this.str += `
str += `
enumerable: true,

@@ -64,14 +66,16 @@ configurable: ${configurable}

if (this.idl.stringifier) {
this.str += `${this.obj.name}.prototype.toString = function () {
str += `${this.obj.name}.prototype.toString = function () {
if (!this || !this[impl]) {
throw new TypeError("Illegal invocation");
}
return this.${this.idl.name};
};\n\n`;
}
};
Attribute.prototype.toString = function () {
this.str = "";
this.generate();
return this.str;
return {
requires,
body: str
};
};
module.exports = Attribute;

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

Constant.prototype.generate = function () {
this.str += `Object.defineProperty(${this.obj.name}, "${this.idl.name}", {
const body = `Object.defineProperty(${this.obj.name}, "${this.idl.name}", {
value: ${JSON.stringify(this.idl.value.value)},

@@ -21,10 +21,8 @@ enumerable: true

});\n\n`;
return {
requires: {},
body
};
};
Constant.prototype.toString = function () {
this.str = "";
this.generate();
return this.str;
};
module.exports = Constant;

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

this.mixins = [];
this.requires = {};
this.str = null;

@@ -40,18 +41,18 @@ this.opts = opts;

const conversions = Parameters.generateOverloadConversions(overloads, this.opts.customTypes);
Object.assign(this.requires, conversions.requires);
this.str += `function ${this.name}(${minConstructor.nameList.join(", ")}) {`;
if (minConstructor.nameList.length !== 0) {
const plural = minConstructor.nameList.length > 1 ? "s" : "";
this.str += `
if (!this || this[impl] || !(this instanceof ${this.name})) {
throw new TypeError("Failed to construct '${this.name}': Please use the 'new' operator, this DOM object 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 required, but only " + arguments.length + " present.");
throw new TypeError("Failed to construct '${this.name}': ${minConstructor.nameList.length} argument${plural} required, but only " + arguments.length + " present.");
}`;
}
this.str += Parameters.generateConversions(overloads) + "\n";
this.str += conversions.body + "\n";
for (let i = 0; i < this.idl.members.length; ++i) {
const memberIdl = this.idl.members[i];
if (memberIdl.type === "attribute" && utils.hasExtAttr(memberIdl.extAttrs, "Unforgeable")) {
const member = new Attribute(this, this.idl, memberIdl);
this.str += "\n " + member.toString().replace(/\n/g, '\n ');
}
}
this.str += `

@@ -68,12 +69,14 @@ module.exports.setup(this, args);

Interface.prototype.generateRequires = function () {
let requireStr = ``;
if (this.idl.inheritance !== null) {
this.str += `const ${this.idl.inheritance} = require("./${this.idl.inheritance}.js");\n`;
requireStr += `const ${this.idl.inheritance} = require("./${this.idl.inheritance}.js");\n`;
}
this.str += `const impl = utils.implSymbols["${this.name}"];\n`;
requireStr += `const impl = utils.implSymbols["${this.name}"];\n`;
if (this.mixins.length !== 0) {
this.str += `const mixin = utils.mixin;\n`;
requireStr += `const mixin = utils.mixin;\n`;
for (let i = 0; i < this.mixins.length; ++i) {
this.str += `const ${this.mixins[i]} = require("./${this.mixins[i]}.js").interface;\n`;
requireStr += `const ${this.mixins[i]} = require("./${this.mixins[i]}.js").interface;\n`;
}

@@ -86,3 +89,3 @@ }

const memberIdl = this.idl.members[i];
if (memberIdl.type === "attribute" && utils.hasExtAttr(memberIdl.extAttrs, "Reflect")) {
if (memberIdl.type === "attribute" && utils.getExtAttr(memberIdl.extAttrs, "Reflect")) {
needsElement = true;

@@ -93,6 +96,12 @@ break;

if (needsElement) {
this.str += `const Element = require("./Element.js").interface;\n`;
requireStr += `const Element = require("./Element.js").interface;\n`;
}
}
this.str += `\n`;
for (let key in this.requires) {
requireStr += `const ${key} = ${this.requires[key]};\n`;
}
requireStr += `\n`;
this.str = requireStr + this.str;
};

@@ -107,3 +116,3 @@

Interface.prototype.generateExport = function () {
const shouldExposeRoot = !utils.hasExtAttr(this.idl.extAttrs, "NoInterfaceObject");
const shouldExposeRoot = !utils.getExtAttr(this.idl.extAttrs, "NoInterfaceObject");

@@ -155,5 +164,23 @@ const exposedMap = {};

}
this.str += `\n`;
for (let i = 0; i < this.idl.members.length; ++i) {
const memberIdl = this.idl.members[i];
if (memberIdl.type === "attribute" && utils.getExtAttr(memberIdl.extAttrs, "Unforgeable")) {
const member = new Attribute(this, this.idl, memberIdl);
this.str += "\n " + member.generate().body.replace(/\n/g, '\n ');
}
}
if (utils.getExtAttr(this.idl.extAttrs, "Unforgeable")) {
this.str += `
Object.defineProperty(obj, "valueOf", {
value: function valueOf() { return this; },
enumerable: true
});\n`;
}
if (implClass) {
this.str += `
obj[impl] = new (Function.prototype.bind.apply(Impl.implementation, [null].concat(constructorArgs)))();
obj[impl] = new Impl.implementation(constructorArgs, privateData);
obj[impl][utils.wrapperSymbol] = obj;`;

@@ -164,2 +191,5 @@ if (implClass.init) {

}
} else {
this.str += `
obj[impl] = {};`;
}

@@ -183,3 +213,3 @@ this.str += `

case "operation":
member = new Operation(this, this.idl, memberIdl);
member = new Operation(this, this.idl, memberIdl, { customTypes: this.opts.customTypes });
if (done[member.name]) {

@@ -196,3 +226,5 @@ continue;

if (member !== null) {
this.str += member.toString();
const data = member.generate();
Object.assign(this.requires, data.requires),
this.str += data.body;
}

@@ -209,3 +241,3 @@ }

case "attribute":
if (utils.hasExtAttr(memberIdl.extAttrs, "Unforgeable")) {
if (utils.getExtAttr(memberIdl.extAttrs, "Unforgeable")) {
break;

@@ -224,3 +256,5 @@ }

if (member !== null) {
this.str += member.toString();
const data = member.generate();
Object.assign(this.requires, data.requires);
this.str += data.body;
}

@@ -231,5 +265,4 @@ }

Interface.prototype.generate = function () {
this.generateRequires();
this.generateConstructor();
this.generateMixins();

@@ -239,4 +272,4 @@ this.generateOperations();

this.generateAttributes();
this.generateRequires();
this.generateMixins();
this.generateExport();

@@ -243,0 +276,0 @@ };

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

this.name = idl.name;
this.str = null;
}
Operation.prototype.generate = function () {
let requires = {};
let str = "";
const targetObj = this.idl.static ? "" : ".prototype";

@@ -25,3 +25,3 @@ let name = this.idl.name;

if (this.idl.name === null) return "";
if (this.idl.name === null) return { requires: {}, body: "" };
const overloads = Overloads.getEffectiveOverloads(name, 0, this.interface, null);

@@ -38,32 +38,40 @@ let minConstructor = overloads[0];

this.str += `\n${this.obj.name + targetObj}.${name} = function ${fnName}(${minConstructor.nameList.join(", ")}) {
if (!this || !this[impl] || !(this instanceof ${this.obj.name})) {
str += `\n${this.obj.name + targetObj}.${name} = function ${fnName}(${minConstructor.nameList.join(", ")}) {`;
if (!this.idl.static) {
str += `
if (!this || !this[impl]) {
throw new TypeError("Illegal invocation");
}`;
}
if (minConstructor.nameList.length !== 0) {
this.str += `
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 required, but only " + arguments.length + " present.");
throw new TypeError("Failed to execute '${name}' on '${this.obj.name}': ${minConstructor.nameList.length} argument${plural} required, but only " + arguments.length + " present.");
}`;
}
this.str += Parameters.generateConversions(overloads);
this.str += `
return this[impl].${name}.apply(this[impl], args);
const callOn = this.idl.static ? "Impl" : "this[impl]";
const parameterConversions = Parameters.generateOverloadConversions(overloads, this.obj.opts.customTypes);
Object.assign(requires, parameterConversions.requires);
str += parameterConversions.body;
str += `
return ${callOn}.${name}.apply(${callOn}, args);
};\n`;
if (this.idl.stringifier && name !== "toString") {
this.str += `\n${this.name + targetObj}.toString(${minConstructor.nameList.join(", ")}) {`;
this.str += Parameters.generateConversions(overloads);
this.str += `
return this[impl].${name}.apply(this[impl], args);
str += `\n${this.name}.prototype.toString(${minConstructor.nameList.join(", ")}) {`;
str += parameterConversions.body;
str += `
return ${callOn}.${name}.apply(${callOn}, args);
};\n`;
}
};
Operation.prototype.toString = function () {
this.str = "";
this.generate();
return this.str;
return {
requires,
body: str
}
};
module.exports = Operation;

@@ -67,1 +67,29 @@ "use strict";

};
module.exports.proveSimiliarity = function (overloads) {
let maxArguments = overloads[0].nameList.length;
for (let i = 1; i < overloads.length; ++i) {
if (overloads[i].nameList.length > maxArguments) {
maxArguments = overloads[i].nameList.length;
}
}
const typeConversions = [];
for (let i = 0; i < maxArguments; ++i) {
let maybeType = { type: overloads[0].operation.arguments[i].idlType, optional: overloads[0].optionalityList[i] !== "required" };
for (let j = 1; j < overloads.length; ++j) {
if (overloads[j].optionalityList[i] !== "required") {
maybeType.optional = true;
}
const thisType = overloads[j].operation.arguments[i].idlType;
if (maybeType.type.idlType !== thisType.idlType || maybeType.type.array !== thisType.array) {
maybeType = null;
}
}
typeConversions.push(maybeType);
}
return typeConversions;
};
"use strict";
const conversions = require("webidl-conversions");
const Overloads = require("./overloads");
const utils = require("./utils");
module.exports.generateConversions = function (overloads) {
module.exports.generateVarConversion = function (name, conversion, argAttrs, customTypes) {
const requires = {};
let str = "";
const idlType = conversion.type;
if (conversions[idlType.idlType] || customTypes.has(idlType.idlType)) {
const enforceRange = utils.getExtAttr(argAttrs, "EnforceRange");
const clamp = utils.getExtAttr(argAttrs, "Clamp");
const treatNullAs = utils.getExtAttr(argAttrs, "TreatNullAs");
let optString = "";
if (clamp) {
optString = `, { clamp: true }`;
} else if (enforceRange) {
optString = `, { enforceRange: true }`;
} else if (treatNullAs && treatNullAs.rhs.value === "EmptyString") {
optString = `, { treatNullAsEmptyString: true }`;
}
let conversionFn = null;
if (conversions[idlType.idlType]) {
conversionFn = `conversions["${idlType.idlType}"]`;
} else {
requires[`convert${idlType.idlType}`] = `require("./${idlType.idlType}").convert`;
conversionFn = `convert${idlType.idlType}`;
}
if (conversion.optional) {
str += `
if (${name} !== undefined) {`;
}
if (idlType.array) {
str += `
for (let i = 0; i < ${name}.length; ++i) {
${name}[i] = ${conversionFn}(${name}[i]${optString});
}`;
} else {
str += `
${name} = ${conversionFn}(${name}${optString});`;
}
if (conversion.optional) {
str += `
}`;
}
}
return {
requires,
body: str
};
};
module.exports.generateOverloadConversions = function (overloads, customTypes) {
const requires = {};
let str = ``;

@@ -25,24 +78,4 @@ let maxConstructor = overloads[0];

const typeConversions = [];
const typeConversions = Overloads.proveSimiliarity(overloads);
argumentLoop:
for (let i = 0; i < maxArguments; ++i) {
let maybeType = null;
for (let j = 0; j < overloads.length; ++j) {
if (overloads[j].optionalityList[i] !== "required") {
break argumentLoop;
}
const thisType = overloads[j].operation.arguments[i].idlType;
if (maybeType === null) {
maybeType = thisType;
} else if (maybeType.idlType !== thisType.idlType || maybeType.array !== thisType.array) {
maybeType = null;
break;
}
}
typeConversions.push(maybeType);
}
str += `

@@ -58,32 +91,14 @@ const args = [];

for (let i = 0; i < typeConversions.length; ++i) {
const typeConversion = typeConversions[i];
if (typeConversion === null) {
if (typeConversions[i] === null) {
continue;
}
if (conversions[typeConversion.idlType]) {
const argAttrs = maxConstructor.operation.arguments[i].extAttrs;
const enforceRange = utils.hasExtAttr(argAttrs, "EnforceRange");
const clamp = utils.hasExtAttr(argAttrs, "Clamp");
let optString = "";
if (clamp) {
optString = `, { clamp: true }`;
} else if (enforceRange) {
optString = `, { enforceRange: true }`;
}
if (typeConversion.array) {
str += `
for (let i = 0; i < args[${i}].length; ++i) {
args[${i}][i] = conversions["${typeConversion.idlType}"](args[${i}][i]${optString});
}`;
} else {
str += `
args[${i}] = conversions["${typeConversion.idlType}"](args[${i}]${optString});`;
}
}
const conv = module.exports.generateVarConversion(`args[${i}]`, typeConversions[i], maxConstructor.operation.arguments[i].extAttrs, customTypes);
Object.assign(requires, conv.requires);
str += conv.body;
}
return str;
return {
requires,
body: str
};
};
"use strict";
module.exports["boolean"] = {
get(attrName) {
return `return Element.prototype.hasAttribute.call(this, "${attrName}");`;
get(objName, attrName) {
return `return Element.prototype.hasAttribute.call(${objName}, "${attrName}");`;
},
set(attrName) {
set(objName, attrName) {
return `if (V) {
Element.prototype.setAttribute.call(this, "${attrName}", "");
Element.prototype.setAttribute.call(${objName}, "${attrName}", "");
} else {
Element.prototype.removeAttribute.call(this, "${attrName}");
Element.prototype.removeAttribute.call(${objName}, "${attrName}");
}`;

@@ -17,9 +17,9 @@ }

module.exports["DOMString"] = {
get(attrName) {
return `const value = Element.prototype.getAttribute.call(this, "${attrName}");
get(objName, attrName) {
return `const value = Element.prototype.getAttribute.call(${objName}, "${attrName}");
return value === null ? "" : value;`;
},
set(attrName) {
return `Element.prototype.setAttribute.call(this, "${attrName}", V);`;
set(objName, attrName) {
return `Element.prototype.setAttribute.call(${objName}, "${attrName}", V);`;
}
}
"use strict";
module.exports.hasExtAttr = function hasExtAttr(attrs, name) {
module.exports.getExtAttr = function getExtAttr(attrs, name) {
for (let i = 0; i < attrs.length; ++i) {
if (attrs[i].name === name) {
return true;
return attrs[i];
}
}
return false;
return null;
};
{
"name": "webidl2js",
"version": "1.0.1",
"version": "2.0.0",
"description": "Auto-generates class structures for WebIDL specifications",

@@ -5,0 +5,0 @@ "main": "index.js",

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