Socket
Socket
Sign inDemoInstall

webidl2js

Package Overview
Dependencies
Maintainers
6
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 13.0.0 to 14.0.0

7

lib/constructs/attribute.js

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

if (utils.hasCEReactions(this.idl)) {
const processorConfig = { requires };
getterBody = this.ctx.invokeProcessCEReactions(getterBody, processorConfig);
setterBody = this.ctx.invokeProcessCEReactions(setterBody, processorConfig);
}
addMethod(this.idl.name, [], `

@@ -68,0 +75,0 @@ ${brandCheck}

144

lib/constructs/interface.js

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

this.name = idl.name;
for (const member of this.idl.members) {

@@ -93,2 +94,3 @@ member.definingInterface = this.name;

this.stringifier = null;
this.needsPerGlobalProxyHandler = false;

@@ -233,2 +235,5 @@ this.iterable = null;

this.indexedSetter = member;
if (utils.hasCEReactions(member)) {
this.needsPerGlobalProxyHandler = true;
}
} else if (isNamed(member)) {

@@ -239,2 +244,5 @@ if (this.namedSetter) {

this.namedSetter = member;
if (utils.hasCEReactions(member)) {
this.needsPerGlobalProxyHandler = true;
}
} else {

@@ -259,2 +267,5 @@ throw new Error(msg + "setter is neither indexed nor named");

this.namedDeleter = member;
if (utils.hasCEReactions(member)) {
this.needsPerGlobalProxyHandler = true;
}
} else {

@@ -590,3 +601,3 @@ throw new Error(msg + "deleter is not named");

generateLegacyProxy() {
generateLegacyProxyHandler() {
const hasIndexedSetter = this.indexedSetter !== null;

@@ -647,3 +658,3 @@ const hasNamedSetter = this.namedSetter !== null;

let str = `
const prolog = `
const index = ${P} >>> 0;

@@ -654,4 +665,5 @@ let indexedValue = ${V};

let invocation;
if (!this.indexedSetter.name) {
str += `
invocation = `
const creating = !(${supportsPropertyIndex(O, "index")});

@@ -665,3 +677,3 @@ if (creating) {

} else {
str += `
invocation = `
${O}[impl].${this.indexedSetter.name}(index, indexedValue);

@@ -671,3 +683,9 @@ `;

return str;
if (utils.hasCEReactions(this.indexedSetter)) {
invocation = this.ctx.invokeProcessCEReactions(invocation, {
requires: this.requires
});
}
return prolog + invocation;
};

@@ -683,3 +701,3 @@

let str = `
const prolog = `
let namedValue = ${V};

@@ -689,4 +707,5 @@ ${conv.body}

let invocation;
if (!this.namedSetter.name) {
str += `
invocation = `
const creating = !(${supportsPropertyName(O, P)});

@@ -700,3 +719,3 @@ if (creating) {

} else {
str += `
invocation = `
${O}[impl].${this.namedSetter.name}(${P}, namedValue);

@@ -706,8 +725,26 @@ `;

return str;
if (utils.hasCEReactions(this.namedSetter)) {
invocation = this.ctx.invokeProcessCEReactions(invocation, {
requires: this.requires
});
}
return prolog + invocation;
};
this.str += `
obj = new Proxy(obj, {
`;
let sep = "";
if (this.needsPerGlobalProxyHandler) {
this.str += `
const proxyHandlerCache = new WeakMap();
class ProxyHandler {
constructor(globalObject) {
this._globalObject = globalObject;
}
`;
} else {
this.str += `
const proxyHandler = {
`;
sep = ",";
}

@@ -736,3 +773,3 @@ // [[Get]] (necessary because of proxy semantics)

return Reflect.apply(getter, receiver, []);
},
}${sep}
`;

@@ -755,3 +792,3 @@

return false;
},
}${sep}
`;

@@ -787,3 +824,3 @@

return [...keys];
},
}${sep}
`;

@@ -862,3 +899,3 @@

return Reflect.getOwnPropertyDescriptor(target, P);
},
}${sep}
`;

@@ -875,2 +912,8 @@

if (this.needsPerGlobalProxyHandler) {
this.str += `
const globalObject = this._globalObject;
`;
}
if (this.supportsIndexedProperties) {

@@ -972,3 +1015,3 @@ if (hasIndexedSetter) {

return Reflect.defineProperty(receiver, P, valueDesc);
},
}${sep}
`;

@@ -983,2 +1026,9 @@

`;
if (this.needsPerGlobalProxyHandler) {
this.str += `
const globalObject = this._globalObject;
`;
}
if (this.supportsIndexedProperties) {

@@ -1062,3 +1112,3 @@ this.str += `

this.str += `
},
}${sep}
`;

@@ -1073,2 +1123,9 @@

`;
if (this.needsPerGlobalProxyHandler) {
this.str += `
const globalObject = this._globalObject;
`;
}
if (this.supportsIndexedProperties) {

@@ -1091,9 +1148,11 @@ this.str += `

} else {
let invocation;
const func = this.namedDeleter.name ? `.${this.namedDeleter.name}` : "[utils.namedDelete]";
if (this.namedDeleter.idlType.idlType === "bool") {
this.str += `
invocation = `
return target[impl]${func}(P);
`;
} else {
this.str += `
invocation = `
target[impl]${func}(P);

@@ -1103,2 +1162,10 @@ return true;

}
if (utils.hasCEReactions(this.namedDeleter)) {
invocation = this.ctx.invokeProcessCEReactions(invocation, {
requires: this.requires
});
}
this.str += invocation;
}

@@ -1111,3 +1178,3 @@ this.str += `

return Reflect.deleteProperty(target, P);
},
}${sep}
`;

@@ -1123,3 +1190,3 @@

this.str += `
});
};
`;

@@ -1172,3 +1239,18 @@ }

if (this.isLegacyPlatformObj) {
this.generateLegacyProxy();
if (this.needsPerGlobalProxyHandler) {
this.str += `
{
let proxyHandler = proxyHandlerCache.get(globalObject);
if (proxyHandler === undefined) {
proxyHandler = new ProxyHandler(globalObject);
proxyHandlerCache.set(globalObject, proxyHandler);
}
obj = new Proxy(obj, proxyHandler);
}
`;
} else {
this.str += `
obj = new Proxy(obj, proxyHandler);
`;
}
}

@@ -1221,2 +1303,8 @@

if (utils.getExtAttr(this.idl.extAttrs, "HTMLConstructor")) {
body = this.ctx.invokeProcessHTMLConstructor(body, {
requires: this.requires
});
}
this.addMethod("prototype", "constructor", argNames, body, "regular", { enumerable: false });

@@ -1471,5 +1559,5 @@ }

}
globalObject[ctorRegistry]["${name}"] = ${name};
globalObject[ctorRegistry][interfaceName] = ${name};
Object.defineProperty(globalObject, "${name}", {
Object.defineProperty(globalObject, interfaceName, {
configurable: true,

@@ -1484,2 +1572,5 @@ writable: true,

generate() {
this.str += `
const interfaceName = "${this.name}";
`;
this.generateIterator();

@@ -1490,2 +1581,5 @@

this.generateInstall();
if (this.isLegacyPlatformObj) {
this.generateLegacyProxyHandler();
}

@@ -1492,0 +1586,0 @@ this.generateMixins();

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

const requires = new utils.RequiresMap(this.ctx);
this.fixUpArgsExtAttrs();

@@ -82,8 +83,9 @@ let str = "";

let invocation;
if (overloads.every(overload => conversions[overload.operation.idlType.idlType])) {
str += `
invocation = `
return ${callOn}.${implFunc}(${argsSpread});
`;
} else {
str += `
invocation = `
return utils.tryWrapperForImpl(${callOn}.${implFunc}(${argsSpread}));

@@ -93,2 +95,9 @@ `;

if (utils.hasCEReactions(this.idls[0])) {
invocation = this.ctx.invokeProcessCEReactions(invocation, {
requires
});
}
str += invocation;
if (this.static) {

@@ -95,0 +104,0 @@ this.interface.addStaticMethod(this.name, argNames, str);

@@ -13,6 +13,18 @@ "use strict";

function defaultProcessor(code) {
return code;
}
class Context {
constructor({ implSuffix = "", options } = {}) {
constructor({
implSuffix = "",
processCEReactions = defaultProcessor,
processHTMLConstructor = defaultProcessor,
options
} = {}) {
this.implSuffix = implSuffix;
this.processCEReactions = processCEReactions;
this.processHTMLConstructor = processHTMLConstructor;
this.options = options;
this.initialize();

@@ -48,4 +60,28 @@ }

}
invokeProcessCEReactions(code, config) {
return this._invokeProcessor(this.processCEReactions, code, config);
}
invokeProcessHTMLConstructor(code, config) {
return this._invokeProcessor(this.processHTMLConstructor, code, config);
}
_invokeProcessor(processor, code, config) {
const { requires } = config;
if (!requires) {
throw new TypeError("Internal error: missing requires object in context");
}
const context = {
addImport(source, imported) {
return requires.add(source, imported);
}
};
return processor.call(context, code);
}
}
module.exports = Context;

@@ -20,2 +20,4 @@ "use strict";

implSuffix: opts.implSuffix,
processCEReactions: opts.processCEReactions,
processHTMLConstructor: opts.processHTMLConstructor,
options: {

@@ -22,0 +24,0 @@ suppressErrors: Boolean(opts.suppressErrors)

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

function hasCEReactions(idl) {
return Boolean(getExtAttr(idl.extAttrs, "CEReactions"));
}
function isOnInstance(memberIDL, interfaceIDL) {

@@ -72,8 +76,13 @@ return memberIDL.special !== "static" && (getExtAttr(memberIDL.extAttrs, "Unforgeable") || isGlobal(interfaceIDL));

add(type, func = "") {
const key = func + type;
let req = `require("./${type}.js")`;
const key = (func + type).replace(/[./-]+/g, " ").trim().replace(/ /g, "_");
const path = type.startsWith(".") ? type : `./${type}`;
let req = `require("${path}.js")`;
if (func) {
req += `.${func}`;
}
this.addRaw(key, req);
return key;
}

@@ -106,2 +115,3 @@

isGlobal,
hasCEReactions,
isOnInstance,

@@ -108,0 +118,0 @@ stringifyPropertyKey,

8

package.json
{
"name": "webidl2js",
"version": "13.0.0",
"version": "14.0.0",
"description": "Auto-generates class structures for WebIDL specifications",

@@ -14,4 +14,4 @@ "main": "lib/transformer.js",

"devDependencies": {
"eslint": "^6.6.0",
"jest": "^24.9.0"
"eslint": "^6.8.0",
"jest": "^25.1.0"
},

@@ -30,3 +30,3 @@ "scripts": {

"engines": {
"node": ">=8"
"node": ">=10"
},

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

@@ -111,4 +111,5 @@ # JavaScript bindings generator for Web IDL

- `implSuffix`: a suffix used, if any, to find files within the source directory based on the IDL file name.
- `suppressErrors`: set to true to suppress errors during generation.
- `implSuffix`: a suffix used, if any, to find files within the source directory based on the IDL file name
- `suppressErrors`: set to true to suppress errors during generation
- `processCEReactions` and `processHTMLConstructor`: see below

@@ -125,2 +126,62 @@ The `addSource()` method can then be called multiple times to add directories containing `.webidl` IDL files and `.js` implementation class files.

### `[CEReactions]` and `[HTMLConstructor]`
By default webidl2js ignores HTML Standard-defined extended attributes [`[CEReactions]`](https://html.spec.whatwg.org/multipage/custom-elements.html#cereactions) and [`[HTMLConstructor]`](https://html.spec.whatwg.org/multipage/dom.html#htmlconstructor), since they require detailed knowledge of the host environment to implement correctly. The `processCEReactions` and `processHTMLConstructor` hooks provide a way to customize the generation of the wrapper class files when these extended attributes are present.
Both hooks have the signature `(code) => replacementCode`, where:
- `code` is the code generated by webidl2js normally, for calling into the impl class.
- `replacementCode` is the new code that will be output in place of `code` in the wrapper class.
If either hook is omitted, then the code will not be replaced, i.e. the default is equivalent to `(code) => code`.
Both hooks also have some utility methods that are accessible via `this`:
- `addImport(relPath, [importedIdentifier])` utility to require external modules from the generated interface. This method accepts 2 parameters: `relPath` the relative path from the generated interface file, and an optional `importedIdentifier` the identifier to import. This method returns the local identifier from the imported path.
The following variables are available in the scope of the replacement code:
- `globalObject` (object) is the global object associated with the interface
- `interfaceName` (string) is the name of the interface
An example of code that uses these hooks is as follows:
```js
"use strict";
const WebIDL2JS = require("webidl2js");
const transformer = new WebIDL2JS({
implSuffix: "-impl",
processCEReactions(code) {
// Add `require("../ce-reactions")` to generated file.
const ceReactions = this.addImport("../ce-reactions");
return `
${ceReactions}.preSteps(globalObject);
try {
${code}
} finally {
${ceReactions}.postSteps(globalObject);
}
`;
},
processHTMLConstructor(/* code */) {
// Add `require("../HTMLConstructor").HTMLConstructor` to generated file.
const htmlConstructor = this.addImport("../HTMLConstructor", "HTMLConstructor");
return `
return ${htmlConstructor}(globalObject, interfaceName);
`;
}
});
transformer.addSource("idl", "impls");
transformer.generate("wrappers").catch(err => {
console.error(err.stack);
process.exit(1);
});
```
## Generated wrapper class file API

@@ -343,2 +404,7 @@

Supported Web IDL extensions defined in HTML:
- `[CEReactions]` - behavior can be defined via the `processCEReactions` hook
- `[HTMLConstructor]` - behavior can be defined via the `processHTMLConstructor` hook
Notable missing features include:

@@ -372,3 +438,3 @@

In the future we may move this extended attribute out into some sort of plugin, since it is more related to HTML than to Web IDL.
In the future we may change this extended attribute to be handled by the caller, similar to `[CEReactions]` and `[HTMLConstructor]`, since it is more related to HTML than to Web IDL.

@@ -375,0 +441,0 @@ ### `[WebIDL2JSValueAsUnsupported=value]`

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