Bug 172867

Summary: Can't extend RTCPeerConnection
Product: WebKit Reporter: Andrew Morris <andrew>
Component: JavaScriptCoreAssignee: Keith Miller <keith_miller>
Status: RESOLVED DUPLICATE    
Severity: Normal CC: aiham, ashvayka, cdumez, ggaren, jonlee, keith_miller, rniwa, saam, sam, webkit-bug-importer, youennf, ysuzuki
Priority: P2 Keywords: InRadar
Version: WebKit Local Build   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
WIP none

Andrew Morris
Reported 2017-06-02 11:59:03 PDT
This code: class PC extends RTCPeerConnection {} const pc = new PC(); console.log(pc instanceof PC); outputs `false`. It should output `true`. Trying to define new methods for pc via the PC prototype also fails. This prevents our attempt to use webrtc/adapter without modifying globals.
Attachments
WIP (18.20 KB, patch)
2017-06-06 09:11 PDT, Keith Miller
no flags
Andrew Morris
Comment 1 2017-06-02 12:07:07 PDT
Also seeing this behavior, might be the same underlying issue: ```js function Foo() {} Foo.prototype = Object.create(RTCPeerConnection.prototype); Foo.prototype.constructor = Foo; console.log(RTCPeerConnection.prototype.constructor !== Foo); ``` Again, output is `false`, should be `true`.
Radar WebKit Bug Importer
Comment 2 2017-06-02 20:59:39 PDT
Chris Dumez
Comment 3 2017-06-05 20:01:12 PDT
This seems like a generic JS bindings bug where we do not support having a JS class extend a platform object such as RTCPeerConnection or Document (I verified that it does not work for Document either).
Chris Dumez
Comment 4 2017-06-05 20:03:23 PDT
Saam / Keith pointed me to our getDOMStructure() implementation which likely needs to be aware of the fact we're building for a subclass. Ditto for WrapperClass::createPrototype(vm, globalObject)) which likely needs to call createSubclassStructure() if needed. I am really not familiar with this so I hope what I typed makes sense :)
youenn fablet
Comment 5 2017-06-05 20:30:55 PDT
Sam/Keith, any idea for a workaround? Maybe à JS object wrapping a peerconnection, or a proxy on the peerconnection prototype...
Keith Miller
Comment 6 2017-06-05 21:41:39 PDT
(In reply to Andrew Morris from comment #1) > Also seeing this behavior, might be the same underlying issue: > > ```js > function Foo() {} > > Foo.prototype = Object.create(RTCPeerConnection.prototype); > Foo.prototype.constructor = Foo; > > console.log(RTCPeerConnection.prototype.constructor !== Foo); > ``` > > Again, output is `false`, should be `true`. Based on my reading of the spec it looks like FF and Chrome are wrong here, although I could be wrong. For some reason they are adding a "constructor" property to the object returned by Object.create which is intercepting your assignment on the next line. See: https://tc39.github.io/ecma262/#sec-object.create. (In reply to youenn fablet from comment #5) > Sam/Keith, any idea for a workaround? Maybe à JS object wrapping a > peerconnection, or a proxy on the peerconnection prototype... The best workaround I can think of (which is a little annoying is to set the prototype in your constructor) i.e. class PC extends RTCPeerConnection { constructor() { super(...arguments); this.__proto__ = PC.prototype; } } That should be roughly the same as RTCPeerConnection properly subclassing.
Keith Miller
Comment 7 2017-06-06 09:11:07 PDT
Created attachment 312077 [details] WIP Works for RTCPeerConnection, doesn't seem to work for other Document.
Alexey Shvayka
Comment 8 2021-04-24 12:24:18 PDT
Proper subclassing of WebIDL interfaces was implemented in r256716, including RTCPeerConnection. Both code snippets in comment #0 and comment #1 now output `true`. *** This bug has been marked as a duplicate of bug 174313 ***
Note You need to log in before you can comment on or make changes to this bug.