<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[211436] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/211436">211436</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2017-01-31 09:52:33 -0800 (Tue, 31 Jan 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>RTCPeerConnection methods can take dictionaries as input
https://bugs.webkit.org/show_bug.cgi?id=167590

Patch by Youenn Fablet &lt;youenn@apple.com&gt; on 2017-01-31
Reviewed by Alex Christensen.

Source/WebCore:

Test: webrtc/rtcpeerconnection-error-messages.html

Made addIceCandidate/setRemoteDescription/setLocalDescription take either dictionaries or objects as parameter.
Spec only mandates this for addIceCandidate, but sites may be using the old version for setRemoteDescription and setLocalDescription.

Updated RTCPeerConnection methods error messages.

* Modules/mediastream/RTCPeerConnection.js:
(getLocalStreams):
(getStreamById):
(addStream):
(createOffer):
(createAnswer):
(setLocalDescription):
(setRemoteDescription):
(addIceCandidate):
(getStats):
* Modules/mediastream/RTCPeerConnectionInternals.js:

LayoutTests:

Replacing fast/mediastream/RTCPeerConnection-js-built-ins-check-this.html by webrtc/rtcpeerconnection-error-messages.html.
It is a bit more thorough and does not hard code the error message.

* fast/mediastream/RTCPeerConnection-addIceCandidate-expected.txt:
* fast/mediastream/RTCPeerConnection-addIceCandidate.html:
* fast/mediastream/RTCPeerConnection-js-built-ins-check-this-expected.txt: Removed.
* fast/mediastream/RTCPeerConnection-js-built-ins-check-this.html: Removed.
* fast/mediastream/RTCPeerConnection-setLocalDescription-offer-expected.txt:
* fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html:
* fast/mediastream/RTCPeerConnection-setRemoteDescription-offer-expected.txt:
* fast/mediastream/RTCPeerConnection-setRemoteDescription-offer.html:
* webrtc/rtcpeerconnection-error-messages-expected.txt: Added.
* webrtc/rtcpeerconnection-error-messages.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamRTCPeerConnectionaddIceCandidateexpectedtxt">trunk/LayoutTests/fast/mediastream/RTCPeerConnection-addIceCandidate-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamRTCPeerConnectionaddIceCandidatehtml">trunk/LayoutTests/fast/mediastream/RTCPeerConnection-addIceCandidate.html</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamRTCPeerConnectionsetLocalDescriptionofferexpectedtxt">trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setLocalDescription-offer-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamRTCPeerConnectionsetLocalDescriptionofferhtml">trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamRTCPeerConnectionsetRemoteDescriptionofferexpectedtxt">trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setRemoteDescription-offer-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamRTCPeerConnectionsetRemoteDescriptionofferhtml">trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setRemoteDescription-offer.html</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamRTCPeerConnectionjs">trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.js</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamRTCPeerConnectionInternalsjs">trunk/Source/WebCore/Modules/mediastream/RTCPeerConnectionInternals.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestswebrtcrtcpeerconnectionerrormessagesexpectedtxt">trunk/LayoutTests/webrtc/rtcpeerconnection-error-messages-expected.txt</a></li>
<li><a href="#trunkLayoutTestswebrtcrtcpeerconnectionerrormessageshtml">trunk/LayoutTests/webrtc/rtcpeerconnection-error-messages.html</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastmediastreamRTCPeerConnectionjsbuiltinscheckthisexpectedtxt">trunk/LayoutTests/fast/mediastream/RTCPeerConnection-js-built-ins-check-this-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamRTCPeerConnectionjsbuiltinscheckthishtml">trunk/LayoutTests/fast/mediastream/RTCPeerConnection-js-built-ins-check-this.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (211435 => 211436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2017-01-31 17:21:42 UTC (rev 211435)
+++ trunk/LayoutTests/ChangeLog        2017-01-31 17:52:33 UTC (rev 211436)
</span><span class="lines">@@ -1,3 +1,24 @@
</span><ins>+2017-01-31  Youenn Fablet  &lt;youenn@apple.com&gt;
+
+        RTCPeerConnection methods can take dictionaries as input
+        https://bugs.webkit.org/show_bug.cgi?id=167590
+
+        Reviewed by Alex Christensen.
+
+        Replacing fast/mediastream/RTCPeerConnection-js-built-ins-check-this.html by webrtc/rtcpeerconnection-error-messages.html.
+        It is a bit more thorough and does not hard code the error message.
+
+        * fast/mediastream/RTCPeerConnection-addIceCandidate-expected.txt:
+        * fast/mediastream/RTCPeerConnection-addIceCandidate.html:
+        * fast/mediastream/RTCPeerConnection-js-built-ins-check-this-expected.txt: Removed.
+        * fast/mediastream/RTCPeerConnection-js-built-ins-check-this.html: Removed.
+        * fast/mediastream/RTCPeerConnection-setLocalDescription-offer-expected.txt:
+        * fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html:
+        * fast/mediastream/RTCPeerConnection-setRemoteDescription-offer-expected.txt:
+        * fast/mediastream/RTCPeerConnection-setRemoteDescription-offer.html:
+        * webrtc/rtcpeerconnection-error-messages-expected.txt: Added.
+        * webrtc/rtcpeerconnection-error-messages.html: Added.
+
</ins><span class="cx"> 2017-01-31  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add better test coverage for scripting windows opened via window.open()
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamRTCPeerConnectionaddIceCandidateexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-addIceCandidate-expected.txt (211435 => 211436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-addIceCandidate-expected.txt        2017-01-31 17:21:42 UTC (rev 211435)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-addIceCandidate-expected.txt        2017-01-31 17:52:33 UTC (rev 211436)
</span><span class="lines">@@ -23,7 +23,7 @@
</span><span class="cx"> PASS promise pc.addIceCandidate(new RTCIceCandidate({candidate: 'bad content', sdpMLineIndex: sdpMLineIndex})) rejected with OperationError (DOM Exception 34): Invalid candidate content
</span><span class="cx"> 
</span><span class="cx"> *** Test some OK input
</span><del>-PASS promise pc.addIceCandidate(new RTCIceCandidate({candidate: validCandidate, sdpMid: sdpMid})) fulfilled with undefined
</del><ins>+PASS promise pc.addIceCandidate({candidate: validCandidate, sdpMid: sdpMid}) fulfilled with undefined
</ins><span class="cx"> PASS promise pc.addIceCandidate(new RTCIceCandidate({candidate: validCandidate, sdpMLineIndex: sdpMLineIndex})) fulfilled with undefined
</span><span class="cx"> *** A valid sdpMid takes precedesce over a bad sdpMLineIndex
</span><span class="cx"> PASS promise pc.addIceCandidate(new RTCIceCandidate({candidate: validCandidate, sdpMid: sdpMid, sdpMLineIndex: badSdpMLineIndex})) fulfilled with undefined
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamRTCPeerConnectionaddIceCandidatehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-addIceCandidate.html (211435 => 211436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-addIceCandidate.html        2017-01-31 17:21:42 UTC (rev 211435)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-addIceCandidate.html        2017-01-31 17:52:33 UTC (rev 211436)
</span><span class="lines">@@ -74,9 +74,11 @@
</span><span class="cx">             })
</span><span class="cx">             .then(function () {
</span><span class="cx">                 debug(&quot;&lt;br&gt;*** Test some OK input&quot;);
</span><del>-                return promiseShouldResolve(&quot;pc.addIceCandidate(new RTCIceCandidate({candidate: validCandidate, sdpMid: sdpMid}))&quot;);
</del><ins>+                // Testing passing a RTCIceCandidateInit
+                return promiseShouldResolve(&quot;pc.addIceCandidate({candidate: validCandidate, sdpMid: sdpMid})&quot;);
</ins><span class="cx">             })
</span><span class="cx">             .then(function () {
</span><ins>+                // Testing passing a RTCIceCandidate
</ins><span class="cx">                 return promiseShouldResolve(&quot;pc.addIceCandidate(new RTCIceCandidate({candidate: validCandidate, sdpMLineIndex: sdpMLineIndex}))&quot;);
</span><span class="cx">             })
</span><span class="cx">             .then(function () {
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamRTCPeerConnectionjsbuiltinscheckthisexpectedtxt"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-js-built-ins-check-this-expected.txt (211435 => 211436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-js-built-ins-check-this-expected.txt        2017-01-31 17:21:42 UTC (rev 211435)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-js-built-ins-check-this-expected.txt        2017-01-31 17:52:33 UTC (rev 211436)
</span><span class="lines">@@ -1,22 +0,0 @@
</span><del>-Verify that the RTCPeerConnection JS built-in methods check calling 'this'
-
-On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
-
-
-PASS promise RTCPeerConnection.prototype.createOffer.call({}) rejected with TypeError: Function should be called on an RTCPeerConnection
-PASS promise RTCPeerConnection.prototype.createAnswer.call({}) rejected with TypeError: Function should be called on an RTCPeerConnection
-PASS promise RTCPeerConnection.prototype.setLocalDescription.call({}) rejected with TypeError: Function should be called on an RTCPeerConnection
-PASS promise RTCPeerConnection.prototype.setRemoteDescription.call({}) rejected with TypeError: Function should be called on an RTCPeerConnection
-PASS promise RTCPeerConnection.prototype.addIceCandidate.call({}) rejected with TypeError: Function should be called on an RTCPeerConnection
-FAIL promise RTCPeerConnection.prototype.getStats.call({}, null) rejected with TypeError: Can only call RTCPeerConnection.getStats on instances of RTCPeerConnection; expected reason TypeError: Function should be called on an RTCPeerConnection
-PASS promise objectWithPcPrototype.createOffer() rejected with TypeError: Function should be called on an RTCPeerConnection
-PASS promise objectWithPcPrototype.createAnswer() rejected with TypeError: Function should be called on an RTCPeerConnection
-PASS promise objectWithPcPrototype.setLocalDescription() rejected with TypeError: Function should be called on an RTCPeerConnection
-PASS promise objectWithPcPrototype.setRemoteDescription() rejected with TypeError: Function should be called on an RTCPeerConnection
-PASS promise objectWithPcPrototype.addIceCandidate() rejected with TypeError: Function should be called on an RTCPeerConnection
-FAIL promise objectWithPcPrototype.getStats() rejected with TypeError: Can only call RTCPeerConnection.getStats on instances of RTCPeerConnection; expected reason TypeError: Function should be called on an RTCPeerConnection
-PASS End of test promise chain
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
</del></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamRTCPeerConnectionjsbuiltinscheckthishtml"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-js-built-ins-check-this.html (211435 => 211436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-js-built-ins-check-this.html        2017-01-31 17:21:42 UTC (rev 211435)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-js-built-ins-check-this.html        2017-01-31 17:52:33 UTC (rev 211436)
</span><span class="lines">@@ -1,46 +0,0 @@
</span><del>-&lt;!DOCTYPE html&gt;
-&lt;html&gt;
-    &lt;head&gt;
-        &lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
-        &lt;script src=&quot;resources/promise-utils.js&quot;&gt;&lt;/script&gt;
-    &lt;/head&gt;
-    &lt;body&gt;
-        &lt;script&gt;
-            description(&quot;Verify that the RTCPeerConnection JS built-in methods check calling 'this'&quot;);
-
-            const reason = &quot;TypeError: Function should be called on an RTCPeerConnection&quot;;
-
-            function Foo() {}
-            Foo.prototype = RTCPeerConnection.prototype;
-            let objectWithPcPrototype = new Foo();
-
-            promiseShouldReject(&quot;RTCPeerConnection.prototype.createOffer.call({})&quot;, &quot;reason&quot;)
-            .then(() =&gt; promiseShouldReject(&quot;RTCPeerConnection.prototype.createAnswer.call({})&quot;, &quot;reason&quot;))
-            .then(() =&gt; promiseShouldReject(&quot;RTCPeerConnection.prototype.setLocalDescription.call({})&quot;, &quot;reason&quot;))
-            .then(() =&gt; promiseShouldReject(&quot;RTCPeerConnection.prototype.setRemoteDescription.call({})&quot;, &quot;reason&quot;))
-            .then(() =&gt; promiseShouldReject(&quot;RTCPeerConnection.prototype.addIceCandidate.call({})&quot;, &quot;reason&quot;))
-            .then(() =&gt; promiseShouldReject(&quot;RTCPeerConnection.prototype.getStats.call({}, null)&quot;, &quot;reason&quot;))
-
-            .then(() =&gt; promiseShouldReject(&quot;objectWithPcPrototype.createOffer()&quot;, &quot;reason&quot;))
-            .then(() =&gt; promiseShouldReject(&quot;objectWithPcPrototype.createAnswer()&quot;, &quot;reason&quot;))
-            .then(() =&gt; promiseShouldReject(&quot;objectWithPcPrototype.setLocalDescription()&quot;, &quot;reason&quot;))
-            .then(() =&gt; promiseShouldReject(&quot;objectWithPcPrototype.setRemoteDescription()&quot;, &quot;reason&quot;))
-            .then(() =&gt; promiseShouldReject(&quot;objectWithPcPrototype.addIceCandidate()&quot;, &quot;reason&quot;))
-            .then(() =&gt; promiseShouldReject(&quot;objectWithPcPrototype.getStats()&quot;, &quot;reason&quot;))
-
-            .then(() =&gt; {
-                testPassed(&quot;End of test promise chain&quot;);
-                finishJSTest();
-            })
-            .catch(error =&gt; {
-                testFailed(&quot;Error in promise chain: &quot; + error);
-                finishJSTest();
-            });
-
-            window.jsTestIsAsync = true;
-            window.successfullyParsed = true;
-
-        &lt;/script&gt;
-        &lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
-    &lt;/body&gt;
-&lt;/html&gt;
</del></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamRTCPeerConnectionsetLocalDescriptionofferexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setLocalDescription-offer-expected.txt (211435 => 211436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setLocalDescription-offer-expected.txt        2017-01-31 17:21:42 UTC (rev 211435)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setLocalDescription-offer-expected.txt        2017-01-31 17:52:33 UTC (rev 211436)
</span><span class="lines">@@ -31,8 +31,8 @@
</span><span class="cx"> PASS pc.signalingState is 'have-local-offer'
</span><span class="cx"> 
</span><span class="cx"> *** Try setting local descriptions with bad types for the current state
</span><del>-PASS promise pc.setLocalDescription(new RTCSessionDescription({type:'answer', sdp:firstOffer.sdp})); rejected with InvalidStateError (DOM Exception 11): Description type incompatible with current signaling state
-PASS promise pc.setLocalDescription(new RTCSessionDescription({type:'pranswer', sdp:firstOffer.sdp})); rejected with InvalidStateError (DOM Exception 11): Description type incompatible with current signaling state
</del><ins>+PASS promise pc.setLocalDescription({type:'answer', sdp:firstOffer.sdp}); rejected with InvalidStateError (DOM Exception 11): Description type incompatible with current signaling state
+PASS promise pc.setLocalDescription({type:'pranswer', sdp:firstOffer.sdp}); rejected with InvalidStateError (DOM Exception 11): Description type incompatible with current signaling state
</ins><span class="cx"> 
</span><span class="cx"> *** Add videoTrack
</span><span class="cx"> PASS pc.getTransceivers().length is 2
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamRTCPeerConnectionsetLocalDescriptionofferhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html (211435 => 211436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html        2017-01-31 17:21:42 UTC (rev 211435)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setLocalDescription-offer.html        2017-01-31 17:52:33 UTC (rev 211436)
</span><span class="lines">@@ -84,10 +84,10 @@
</span><span class="cx">                 debug(&quot;&quot;);
</span><span class="cx"> 
</span><span class="cx">                 debug(&quot;*** Try setting local descriptions with bad types for the current state&quot;);
</span><del>-                return promiseShouldReject(&quot;pc.setLocalDescription(new RTCSessionDescription({type:'answer', sdp:firstOffer.sdp}));&quot;);
</del><ins>+                return promiseShouldReject(&quot;pc.setLocalDescription({type:'answer', sdp:firstOffer.sdp});&quot;);
</ins><span class="cx">             })
</span><span class="cx">             .then(function () {
</span><del>-                return promiseShouldReject(&quot;pc.setLocalDescription(new RTCSessionDescription({type:'pranswer', sdp:firstOffer.sdp}));&quot;);
</del><ins>+                return promiseShouldReject(&quot;pc.setLocalDescription({type:'pranswer', sdp:firstOffer.sdp});&quot;);
</ins><span class="cx">             })
</span><span class="cx">             .then(function () {
</span><span class="cx">                 debug(&quot;&quot;);
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamRTCPeerConnectionsetRemoteDescriptionofferexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setRemoteDescription-offer-expected.txt (211435 => 211436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setRemoteDescription-offer-expected.txt        2017-01-31 17:21:42 UTC (rev 211435)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setRemoteDescription-offer-expected.txt        2017-01-31 17:52:33 UTC (rev 211436)
</span><span class="lines">@@ -33,8 +33,8 @@
</span><span class="cx"> PASS pc.signalingState is 'have-remote-offer'
</span><span class="cx"> 
</span><span class="cx"> *** Try setting local descriptions with bad types for the current state
</span><del>-PASS promise pc.setRemoteDescription(new RTCSessionDescription({type:'answer', sdp:remoteOffer1.sdp})); rejected with InvalidStateError (DOM Exception 11): Description type incompatible with current signaling state
-PASS promise pc.setRemoteDescription(new RTCSessionDescription({type:'pranswer', sdp:remoteOffer1.sdp})); rejected with InvalidStateError (DOM Exception 11): Description type incompatible with current signaling state
</del><ins>+PASS promise pc.setRemoteDescription({type:'answer', sdp:remoteOffer1.sdp}); rejected with InvalidStateError (DOM Exception 11): Description type incompatible with current signaling state
+PASS promise pc.setRemoteDescription({type:'pranswer', sdp:remoteOffer1.sdp}); rejected with InvalidStateError (DOM Exception 11): Description type incompatible with current signaling state
</ins><span class="cx"> 
</span><span class="cx"> *** Create (remote) offer with video (remoteOffer2)
</span><span class="cx"> *** Done, start testing with remoteOffer2
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamRTCPeerConnectionsetRemoteDescriptionofferhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setRemoteDescription-offer.html (211435 => 211436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setRemoteDescription-offer.html        2017-01-31 17:21:42 UTC (rev 211435)
+++ trunk/LayoutTests/fast/mediastream/RTCPeerConnection-setRemoteDescription-offer.html        2017-01-31 17:52:33 UTC (rev 211436)
</span><span class="lines">@@ -106,10 +106,10 @@
</span><span class="cx">                 debug(&quot;&quot;);
</span><span class="cx"> 
</span><span class="cx">                 debug(&quot;*** Try setting local descriptions with bad types for the current state&quot;);
</span><del>-                return promiseShouldReject(&quot;pc.setRemoteDescription(new RTCSessionDescription({type:'answer', sdp:remoteOffer1.sdp}));&quot;);
</del><ins>+                return promiseShouldReject(&quot;pc.setRemoteDescription({type:'answer', sdp:remoteOffer1.sdp});&quot;);
</ins><span class="cx">             })
</span><span class="cx">             .then(function () {
</span><del>-                return promiseShouldReject(&quot;pc.setRemoteDescription(new RTCSessionDescription({type:'pranswer', sdp:remoteOffer1.sdp}));&quot;);
</del><ins>+                return promiseShouldReject(&quot;pc.setRemoteDescription({type:'pranswer', sdp:remoteOffer1.sdp});&quot;);
</ins><span class="cx">             })
</span><span class="cx">             .then(function () {
</span><span class="cx">                 debug(&quot;&quot;);
</span></span></pre></div>
<a id="trunkLayoutTestswebrtcrtcpeerconnectionerrormessagesexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webrtc/rtcpeerconnection-error-messages-expected.txt (0 => 211436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webrtc/rtcpeerconnection-error-messages-expected.txt                                (rev 0)
+++ trunk/LayoutTests/webrtc/rtcpeerconnection-error-messages-expected.txt        2017-01-31 17:52:33 UTC (rev 211436)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+TypeError: The RTCPeerConnection.localDescription getter can only be used on instances of RTCPeerConnection
+TypeError: The RTCPeerConnection.currentLocalDescription getter can only be used on instances of RTCPeerConnection
+TypeError: The RTCPeerConnection.pendingLocalDescription getter can only be used on instances of RTCPeerConnection
+TypeError: The RTCPeerConnection.remoteDescription getter can only be used on instances of RTCPeerConnection
+TypeError: The RTCPeerConnection.currentRemoteDescription getter can only be used on instances of RTCPeerConnection
+TypeError: The RTCPeerConnection.pendingRemoteDescription getter can only be used on instances of RTCPeerConnection
+TypeError: The RTCPeerConnection.signalingState getter can only be used on instances of RTCPeerConnection
+TypeError: The RTCPeerConnection.iceGatheringState getter can only be used on instances of RTCPeerConnection
+TypeError: The RTCPeerConnection.iceConnectionState getter can only be used on instances of RTCPeerConnection
+[object RTCPeerConnection] has no property named connectionState
+[object RTCPeerConnection] has no property named canTrickleIceCandidates
+[object RTCPeerConnection] has no property named defaultIceServers
+TypeError: Can only call RTCPeerConnection.getConfiguration on instances of RTCPeerConnection
+TypeError: Can only call RTCPeerConnection.setConfiguration on instances of RTCPeerConnection
+TypeError: Can only call RTCPeerConnection.close on instances of RTCPeerConnection
+TypeError: The RTCPeerConnection.onnegotiationneeded getter can only be used on instances of RTCPeerConnection
+TypeError: The RTCPeerConnection.onicecandidate getter can only be used on instances of RTCPeerConnection
+[object RTCPeerConnection] has no property named onicecandidateerror
+TypeError: The RTCPeerConnection.onsignalingstatechange getter can only be used on instances of RTCPeerConnection
+TypeError: The RTCPeerConnection.oniceconnectionstatechange getter can only be used on instances of RTCPeerConnection
+TypeError: The RTCPeerConnection.onicegatheringstatechange getter can only be used on instances of RTCPeerConnection
+[object RTCPeerConnection] has no property named onconnectionstatechange
+Promise rejected with: TypeError: Can only call RTCPeerConnection.createOffer on instances of RTCPeerConnection
+Promise rejected with: TypeError: Can only call RTCPeerConnection.createAnswer on instances of RTCPeerConnection
+Promise rejected with: TypeError: Can only call RTCPeerConnection.setLocalDescription on instances of RTCPeerConnection
+Promise rejected with: TypeError: Can only call RTCPeerConnection.setRemoteDescription on instances of RTCPeerConnection
+Promise rejected with: TypeError: Can only call RTCPeerConnection.addIceCandidate on instances of RTCPeerConnection
+
+PASS Exercising TypeError messages in RTCPeerConnection 
+
</ins></span></pre></div>
<a id="trunkLayoutTestswebrtcrtcpeerconnectionerrormessageshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webrtc/rtcpeerconnection-error-messages.html (0 => 211436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webrtc/rtcpeerconnection-error-messages.html                                (rev 0)
+++ trunk/LayoutTests/webrtc/rtcpeerconnection-error-messages.html        2017-01-31 17:52:33 UTC (rev 211436)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;div id=&quot;log&quot;&gt;&lt;/div&gt;
+&lt;script src='../resources/testharness.js'&gt;&lt;/script&gt;
+&lt;script src='../resources/testharnessreport.js'&gt;&lt;/script&gt;
+&lt;script&gt;
+function log(msg)
+{
+    document.getElementById(&quot;log&quot;).innerHTML += msg + &quot;&lt;br&gt;&quot;;
+}
+
+function printMethodError(method, target)
+{
+    try {
+        method.call(target);
+        assert_unreached();
+    } catch(e) {
+         log(e);
+    }
+}
+
+function printPromiseMethodError(method, target)
+{
+    return method.call(target).then(assert_unreached, (e) =&gt; {
+         log(&quot;Promise rejected with: &quot; + e);
+    });
+}
+
+function printGetterError(object, getterName, target)
+{
+    const property = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(object), getterName);
+    if (property  === undefined) {
+        log(object + &quot; has no property named &quot; + getterName);
+        return;
+    }
+    printMethodError(property.get, target);
+}
+
+promise_test(function(test) {
+    // This test prints exceptions to check the format of their messages.
+
+    var pc = new RTCPeerConnection();
+    var candidate = new RTCIceCandidate({ candidate: &quot;foo&quot;, sdpMid: &quot;bar&quot; });
+
+    var results = [
+        printPromiseMethodError(pc.createOffer, candidate),
+        printPromiseMethodError(pc.createAnswer, candidate),
+        printPromiseMethodError(pc.setLocalDescription, candidate),
+        printPromiseMethodError(pc.setRemoteDescription, candidate),
+        printPromiseMethodError(pc.addIceCandidate, candidate),
+
+        printGetterError(pc, &quot;localDescription&quot;, candidate),
+        printGetterError(pc, &quot;currentLocalDescription&quot;, candidate),
+        printGetterError(pc, &quot;pendingLocalDescription&quot;, candidate),
+        printGetterError(pc, &quot;remoteDescription&quot;, candidate),
+        printGetterError(pc, &quot;currentRemoteDescription&quot;, candidate),
+        printGetterError(pc, &quot;pendingRemoteDescription&quot;, candidate),
+        printGetterError(pc, &quot;signalingState&quot;, candidate),
+        printGetterError(pc, &quot;iceGatheringState&quot;, candidate),
+        printGetterError(pc, &quot;iceConnectionState&quot;, candidate),
+        printGetterError(pc, &quot;connectionState&quot;, candidate),
+        printGetterError(pc, &quot;canTrickleIceCandidates&quot;, candidate),
+        printGetterError(pc, &quot;defaultIceServers&quot;, candidate),
+
+        printMethodError(pc.getConfiguration, candidate),
+        printMethodError(pc.setConfiguration, candidate),
+        printMethodError(pc.close, candidate),
+
+        printGetterError(pc, &quot;onnegotiationneeded&quot;, candidate),
+        printGetterError(pc, &quot;onicecandidate&quot;, candidate),
+        printGetterError(pc, &quot;onicecandidateerror&quot;, candidate),
+        printGetterError(pc, &quot;onsignalingstatechange&quot;, candidate),
+        printGetterError(pc, &quot;oniceconnectionstatechange&quot;, candidate),
+        printGetterError(pc, &quot;onicegatheringstatechange&quot;, candidate),
+        printGetterError(pc, &quot;onconnectionstatechange&quot;, candidate),
+    ];
+    return Promise.all(results);
+}, &quot;Exercising TypeError messages in RTCPeerConnection&quot;);
+&lt;/script&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (211435 => 211436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-01-31 17:21:42 UTC (rev 211435)
+++ trunk/Source/WebCore/ChangeLog        2017-01-31 17:52:33 UTC (rev 211436)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2017-01-31  Youenn Fablet  &lt;youenn@apple.com&gt;
+
+        RTCPeerConnection methods can take dictionaries as input
+        https://bugs.webkit.org/show_bug.cgi?id=167590
+
+        Reviewed by Alex Christensen.
+
+        Test: webrtc/rtcpeerconnection-error-messages.html
+
+        Made addIceCandidate/setRemoteDescription/setLocalDescription take either dictionaries or objects as parameter.
+        Spec only mandates this for addIceCandidate, but sites may be using the old version for setRemoteDescription and setLocalDescription.
+
+        Updated RTCPeerConnection methods error messages.
+
+        * Modules/mediastream/RTCPeerConnection.js:
+        (getLocalStreams):
+        (getStreamById):
+        (addStream):
+        (createOffer):
+        (createAnswer):
+        (setLocalDescription):
+        (setRemoteDescription):
+        (addIceCandidate):
+        (getStats):
+        * Modules/mediastream/RTCPeerConnectionInternals.js:
+
</ins><span class="cx"> 2017-01-31  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         REGRESSION (r209411): Scrolling to a fragment identifier in overflow:scroll inside position:fixed no longer works
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamRTCPeerConnectionjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.js (211435 => 211436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.js        2017-01-31 17:21:42 UTC (rev 211435)
+++ trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.js        2017-01-31 17:52:33 UTC (rev 211436)
</span><span class="lines">@@ -58,7 +58,7 @@
</span><span class="cx">     &quot;use strict&quot;;
</span><span class="cx"> 
</span><span class="cx">     if (!@isRTCPeerConnection(this))
</span><del>-        @throwTypeError(&quot;Function should be called on an RTCPeerConnection&quot;);
</del><ins>+        throw @makeThisTypeError(&quot;RTCPeerConnection&quot;, &quot;getLocalStreams&quot;);
</ins><span class="cx"> 
</span><span class="cx">     return this.@localStreams.slice();
</span><span class="cx"> }
</span><span class="lines">@@ -68,7 +68,7 @@
</span><span class="cx">     &quot;use strict&quot;;
</span><span class="cx"> 
</span><span class="cx">     if (!@isRTCPeerConnection(this))
</span><del>-        @throwTypeError(&quot;Function should be called on an RTCPeerConnection&quot;);
</del><ins>+        throw @makeThisTypeError(&quot;RTCPeerConnection&quot;, &quot;getStreamById&quot;);
</ins><span class="cx"> 
</span><span class="cx">     if (arguments.length &lt; 1)
</span><span class="cx">         @throwTypeError(&quot;Not enough arguments&quot;);
</span><span class="lines">@@ -85,7 +85,7 @@
</span><span class="cx">     &quot;use strict&quot;;
</span><span class="cx"> 
</span><span class="cx">     if (!@isRTCPeerConnection(this))
</span><del>-        @throwTypeError(&quot;Function should be called on an RTCPeerConnection&quot;);
</del><ins>+        throw @makeThisTypeError(&quot;RTCPeerConnection&quot;, &quot;addStream&quot;);
</ins><span class="cx"> 
</span><span class="cx">     if (arguments.length &lt; 1)
</span><span class="cx">         @throwTypeError(&quot;Not enough arguments&quot;);
</span><span class="lines">@@ -105,7 +105,7 @@
</span><span class="cx">     &quot;use strict&quot;;
</span><span class="cx"> 
</span><span class="cx">     if (!@isRTCPeerConnection(this))
</span><del>-        @throwTypeError(&quot;Function should be called on an RTCPeerConnection&quot;);
</del><ins>+        throw @makeThisTypeError(&quot;RTCPeerConnection&quot;, &quot;removeStream&quot;);
</ins><span class="cx"> 
</span><span class="cx">     if (arguments.length &lt; 1)
</span><span class="cx">         @throwTypeError(&quot;Not enough arguments&quot;);
</span><span class="lines">@@ -132,7 +132,7 @@
</span><span class="cx">     &quot;use strict&quot;;
</span><span class="cx"> 
</span><span class="cx">     if (!@isRTCPeerConnection(this))
</span><del>-        return @Promise.@reject(new @TypeError(&quot;Function should be called on an RTCPeerConnection&quot;));
</del><ins>+        return @Promise.@reject(@makeThisTypeError(&quot;RTCPeerConnection&quot;, &quot;createOffer&quot;));
</ins><span class="cx"> 
</span><span class="cx">     const peerConnection = this;
</span><span class="cx"> 
</span><span class="lines">@@ -156,7 +156,7 @@
</span><span class="cx">     &quot;use strict&quot;;
</span><span class="cx"> 
</span><span class="cx">     if (!@isRTCPeerConnection(this))
</span><del>-        return @Promise.@reject(new @TypeError(&quot;Function should be called on an RTCPeerConnection&quot;));
</del><ins>+        return @Promise.@reject(@makeThisTypeError(&quot;RTCPeerConnection&quot;, &quot;createAnswer&quot;));
</ins><span class="cx"> 
</span><span class="cx">     const peerConnection = this;
</span><span class="cx"> 
</span><span class="lines">@@ -180,14 +180,16 @@
</span><span class="cx">     &quot;use strict&quot;;
</span><span class="cx"> 
</span><span class="cx">     if (!@isRTCPeerConnection(this))
</span><del>-        return @Promise.@reject(new @TypeError(&quot;Function should be called on an RTCPeerConnection&quot;));
</del><ins>+        return @Promise.@reject(@makeThisTypeError(&quot;RTCPeerConnection&quot;, &quot;setLocalDescription&quot;));
</ins><span class="cx"> 
</span><span class="cx">     const peerConnection = this;
</span><span class="cx"> 
</span><ins>+    // FIXME: According the spec, we should throw when receiving a RTCSessionDescription.
</ins><span class="cx">     const objectInfo = {
</span><span class="cx">         &quot;constructor&quot;: @RTCSessionDescription,
</span><span class="cx">         &quot;argName&quot;: &quot;description&quot;,
</span><del>-        &quot;argType&quot;: &quot;RTCSessionDescription&quot;
</del><ins>+        &quot;argType&quot;: &quot;RTCSessionDescription&quot;,
+        &quot;maybeDictionary&quot;: &quot;true&quot;
</ins><span class="cx">     };
</span><span class="cx">     return @objectAndCallbacksOverload(arguments, &quot;setLocalDescription&quot;, objectInfo, function (description) {
</span><span class="cx">         // Promise mode
</span><span class="lines">@@ -209,14 +211,16 @@
</span><span class="cx">     &quot;use strict&quot;;
</span><span class="cx"> 
</span><span class="cx">     if (!@isRTCPeerConnection(this))
</span><del>-        return @Promise.@reject(new @TypeError(&quot;Function should be called on an RTCPeerConnection&quot;));
</del><ins>+        return @Promise.@reject(@makeThisTypeError(&quot;RTCPeerConnection&quot;, &quot;setRemoteDescription&quot;));
</ins><span class="cx"> 
</span><span class="cx">     const peerConnection = this;
</span><span class="cx"> 
</span><ins>+    // FIXME: According the spec, we should throw when receiving a RTCSessionDescription.
</ins><span class="cx">     const objectInfo = {
</span><span class="cx">         &quot;constructor&quot;: @RTCSessionDescription,
</span><span class="cx">         &quot;argName&quot;: &quot;description&quot;,
</span><del>-        &quot;argType&quot;: &quot;RTCSessionDescription&quot;
</del><ins>+        &quot;argType&quot;: &quot;RTCSessionDescription&quot;,
+        &quot;maybeDictionary&quot;: &quot;true&quot;
</ins><span class="cx">     };
</span><span class="cx">     return @objectAndCallbacksOverload(arguments, &quot;setRemoteDescription&quot;, objectInfo, function (description) {
</span><span class="cx">         // Promise mode
</span><span class="lines">@@ -238,7 +242,7 @@
</span><span class="cx">     &quot;use strict&quot;;
</span><span class="cx"> 
</span><span class="cx">     if (!@isRTCPeerConnection(this))
</span><del>-        return @Promise.@reject(new @TypeError(&quot;Function should be called on an RTCPeerConnection&quot;));
</del><ins>+        return @Promise.@reject(@makeThisTypeError(&quot;RTCPeerConnection&quot;, &quot;addIceCandidate&quot;));
</ins><span class="cx"> 
</span><span class="cx">     const peerConnection = this;
</span><span class="cx"> 
</span><span class="lines">@@ -245,7 +249,8 @@
</span><span class="cx">     const objectInfo = {
</span><span class="cx">         &quot;constructor&quot;: @RTCIceCandidate,
</span><span class="cx">         &quot;argName&quot;: &quot;candidate&quot;,
</span><del>-        &quot;argType&quot;: &quot;RTCIceCandidate&quot;
</del><ins>+        &quot;argType&quot;: &quot;RTCIceCandidate&quot;,
+        &quot;maybeDictionary&quot;: &quot;true&quot;
</ins><span class="cx">     };
</span><span class="cx">     return @objectAndCallbacksOverload(arguments, &quot;addIceCandidate&quot;, objectInfo, function (candidate) {
</span><span class="cx">         // Promise mode
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamRTCPeerConnectionInternalsjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/RTCPeerConnectionInternals.js (211435 => 211436)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/RTCPeerConnectionInternals.js        2017-01-31 17:21:42 UTC (rev 211435)
+++ trunk/Source/WebCore/Modules/mediastream/RTCPeerConnectionInternals.js        2017-01-31 17:52:33 UTC (rev 211436)
</span><span class="lines">@@ -71,7 +71,18 @@
</span><span class="cx">         argsCount = 1;
</span><span class="cx">     } else {
</span><span class="cx">         const hasMatchingType = objectArg instanceof objectInfo.constructor;
</span><del>-        objectArgOk = objectInfo.defaultsToNull ? (objectArg === null || typeof objectArg === &quot;undefined&quot; || hasMatchingType) : hasMatchingType;
</del><ins>+        if (hasMatchingType)
+            objectArgOk = true;
+        else if (objectInfo.defaultsToNull)
+            objectArgOk = objectArg === null || typeof objectArg === &quot;undefined&quot;;
+        else if (objectInfo.maybeDictionary) {
+            try {
+                objectArg = new objectInfo.constructor(objectArg);
+                objectArgOk = true;
+            } catch (e) {
+                objectArgOk = false;
+            }
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (!objectArgOk)
</span></span></pre>
</div>
</div>

</body>
</html>