Skip to content

Commit eb897a2

Browse files
committed
Implement “internally create a new object implementing the interface”
1 parent 8d92c30 commit eb897a2

File tree

3 files changed

+1257
-589
lines changed

3 files changed

+1257
-589
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -282,11 +282,11 @@ Creates a new instance of the wrapper class and corresponding implementation cla
282282

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

285-
#### `new(globalObject)`
285+
#### `new(globalObject, newTarget)`
286286

287287
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.
288288

289-
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.
289+
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.
290290

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

lib/constructs/interface.js

+15-7
Original file line numberDiff line numberDiff line change
@@ -1194,17 +1194,25 @@ class Interface {
11941194

11951195
generateIface() {
11961196
this.str += `
1197-
function makeWrapper(globalObject) {
1197+
function makeWrapper(globalObject, newTarget) {
11981198
if (globalObject[ctorRegistrySymbol] === undefined) {
11991199
throw new Error('Internal error: invalid global object');
12001200
}
12011201
1202-
const ctor = globalObject[ctorRegistrySymbol]["${this.name}"];
1203-
if (ctor === undefined) {
1204-
throw new Error('Internal error: constructor ${this.name} is not installed on the passed global object');
1202+
let proto;
1203+
if (newTarget !== undefined) {
1204+
proto = newTarget.prototype;
12051205
}
12061206
1207-
return Object.create(ctor.prototype);
1207+
if (!utils.isObject(proto)) {
1208+
const ctor = globalObject[ctorRegistrySymbol]["${this.name}"];
1209+
if (ctor === undefined) {
1210+
throw new Error('Internal error: constructor ${this.name} is not installed on the passed global object');
1211+
}
1212+
proto = ctor.prototype;
1213+
}
1214+
1215+
return Object.create(proto);
12081216
}
12091217
`;
12101218

@@ -1272,8 +1280,8 @@ class Interface {
12721280
return wrapper;
12731281
};
12741282
1275-
exports.new = globalObject => {
1276-
${this.isLegacyPlatformObj ? "let" : "const"} wrapper = makeWrapper(globalObject);
1283+
exports.new = (globalObject, newTarget) => {
1284+
${this.isLegacyPlatformObj ? "let" : "const"} wrapper = makeWrapper(globalObject, newTarget);
12771285
12781286
exports._internalSetup(wrapper, globalObject);
12791287
Object.defineProperty(wrapper, implSymbol, {

0 commit comments

Comments
 (0)