Skip to content

Commit

Permalink
Implement “internally create a new object implementing the interface”
Browse files Browse the repository at this point in the history
  • Loading branch information
ExE-Boss committed Mar 14, 2021
1 parent 8d92c30 commit eb897a2
Show file tree
Hide file tree
Showing 3 changed files with 1,257 additions and 589 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,11 @@ Creates a new instance of the wrapper class and corresponding implementation cla

This is useful inside implementation class files, where it is easiest to only deal with impls, not wrappers.

#### `new(globalObject)`
#### `new(globalObject, newTarget)`

Creates a new instance of the wrapper class and corresponding implementation class, but without invoking the implementation class constructor logic. Then returns the implementation class.

This corresponds to the [Web IDL "new" algorithm](https://heycam.github.io/webidl/#new), and is useful when implementing specifications that initialize objects in different ways than their constructors do.
This corresponds to the [WebIDL "create a new object implementing the interface"](https://heycam.github.io/webidl/#new) and ["internally create a new object implementing the interface"](https://heycam.github.io/webidl/#internally-create-a-new-object-implementing-the-interface) algorithms, and is useful when implementing specifications that initialize objects in different ways than their constructors do.

#### `setup(obj, globalObject, constructorArgs, privateData)`

Expand Down
22 changes: 15 additions & 7 deletions lib/constructs/interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -1194,17 +1194,25 @@ class Interface {

generateIface() {
this.str += `
function makeWrapper(globalObject) {
function makeWrapper(globalObject, newTarget) {
if (globalObject[ctorRegistrySymbol] === undefined) {
throw new Error('Internal error: invalid global object');
}
const ctor = globalObject[ctorRegistrySymbol]["${this.name}"];
if (ctor === undefined) {
throw new Error('Internal error: constructor ${this.name} is not installed on the passed global object');
let proto;
if (newTarget !== undefined) {
proto = newTarget.prototype;
}
return Object.create(ctor.prototype);
if (!utils.isObject(proto)) {
const ctor = globalObject[ctorRegistrySymbol]["${this.name}"];
if (ctor === undefined) {
throw new Error('Internal error: constructor ${this.name} is not installed on the passed global object');
}
proto = ctor.prototype;
}
return Object.create(proto);
}
`;

Expand Down Expand Up @@ -1272,8 +1280,8 @@ class Interface {
return wrapper;
};
exports.new = globalObject => {
${this.isLegacyPlatformObj ? "let" : "const"} wrapper = makeWrapper(globalObject);
exports.new = (globalObject, newTarget) => {
${this.isLegacyPlatformObj ? "let" : "const"} wrapper = makeWrapper(globalObject, newTarget);
exports._internalSetup(wrapper, globalObject);
Object.defineProperty(wrapper, implSymbol, {
Expand Down
Loading

0 comments on commit eb897a2

Please sign in to comment.