<!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>[188283] 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/188283">188283</a></dd>
<dt>Author</dt> <dd>burg@cs.washington.edu</dd>
<dt>Date</dt> <dd>2015-08-11 13:15:16 -0700 (Tue, 11 Aug 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: Agent commands do not actually return a promise when expected
https://bugs.webkit.org/show_bug.cgi?id=138665

Reviewed by Timothy Hatcher.

Source/WebInspectorUI:

This patch unifies the handling of different invocation and dispatch modes in the
InspectorBackend protocol system. Command responses are dispatched to a provided
callback function; if no function was provided, then the command returns a promise.

Rather than awkwardly converting between promises and callbacks at invocation and
response dispatch time, the backend now stores the callback or promise thunks and
knows how to invoke each when the response comes. This mirrors how response handling
works in ProtocolTestStub.js. InspectorBackend includes more machinery to support Agent
objects and various debug flags.

Performanace impact is expected to be negligible, because there are relatively
few commands issued by the inspector frontend and returned promises are short-lived.

Remove all uses of Command.prototype.promise, since it is no longer necessary.

* UserInterface/Base/Test.js:
(InspectorTest.reloadPage):
* UserInterface/Controllers/ReplayManager.js:
(WebInspector.ReplayManager.prototype.getSession.get var):
(WebInspector.ReplayManager.getSegment.get var):
* UserInterface/Models/ReplaySession.js:
(WebInspector.ReplaySession.prototype.segmentsChanged):
* UserInterface/Models/Resource.js:
(WebInspector.Resource.prototype.requestContentFromBackend):
* UserInterface/Models/Script.js:
(WebInspector.Script.prototype.requestContentFromBackend):
* UserInterface/Models/SourceMapResource.js:
(WebInspector.SourceMapResource.prototype.requestContentFromBackend):
* UserInterface/Protocol/InspectorBackend.js:
(InspectorBackendClass):
(InspectorBackendClass.prototype.dispatch):
(InspectorBackendClass.prototype.runAfterPendingDispatches):
(InspectorBackendClass.prototype._sendCommandToBackendWithCallback.set this):
(InspectorBackendClass.set this):
(InspectorBackendClass.prototype._sendCommandToBackendWithCallback):
(InspectorBackendClass.prototype._dispatchResponseToCallback):
(InspectorBackendClass.prototype._dispatchResponseToPromise):
(InspectorBackendClass.prototype._flushPendingScripts):
(InspectorBackend.Command.prototype.invoke):
(InspectorBackend.Command.prototype._invokeWithArguments):
(InspectorBackendClass.prototype._willSendMessageToBackend.set return): Deleted.
(InspectorBackendClass._dispatchCallback.get if): Deleted.
(InspectorBackendClass.prototype._willSendMessageToBackend): Deleted.
(InspectorBackendClass.prototype._invokeCommand): Deleted.
(.callable): Deleted.
(InspectorBackend.Command.create): Deleted.
(InspectorBackend.Command.prototype.promise): Deleted.

LayoutTests:

Add a new test that only checks for proper invocation return values.
Once the async test suite infrastructure is available for frontend tests,
more thorough tests of promises and callbacks will be added.

* inspector/protocol/inspector-backend-invocation-return-value-expected.txt: Added.
* inspector/protocol/inspector-backend-invocation-return-value.html: Added.
* inspector/protocol/protocol-promise-result-expected.txt: Removed.
* inspector/protocol/protocol-promise-result.html: Removed.
* platform/win/TestExpectations: Remove deleted test.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformwinTestExpectations">trunk/LayoutTests/platform/win/TestExpectations</a></li>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceBaseTestjs">trunk/Source/WebInspectorUI/UserInterface/Base/Test.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceControllersReplayManagerjs">trunk/Source/WebInspectorUI/UserInterface/Controllers/ReplayManager.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsReplaySessionjs">trunk/Source/WebInspectorUI/UserInterface/Models/ReplaySession.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsResourcejs">trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsScriptjs">trunk/Source/WebInspectorUI/UserInterface/Models/Script.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsSourceMapResourcejs">trunk/Source/WebInspectorUI/UserInterface/Models/SourceMapResource.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceProtocolInspectorBackendjs">trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsinspectorprotocolinspectorbackendinvocationreturnvalueexpectedtxt">trunk/LayoutTests/inspector/protocol/inspector-backend-invocation-return-value-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorprotocolinspectorbackendinvocationreturnvaluehtml">trunk/LayoutTests/inspector/protocol/inspector-backend-invocation-return-value.html</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsinspectorprotocolprotocolpromiseresultexpectedtxt">trunk/LayoutTests/inspector/protocol/protocol-promise-result-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorprotocolprotocolpromiseresulthtml">trunk/LayoutTests/inspector/protocol/protocol-promise-result.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (188282 => 188283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-08-11 20:08:56 UTC (rev 188282)
+++ trunk/LayoutTests/ChangeLog        2015-08-11 20:15:16 UTC (rev 188283)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2015-08-11  Brian Burg  &lt;bburg@apple.com&gt;
+
+        Web Inspector: Agent commands do not actually return a promise when expected
+        https://bugs.webkit.org/show_bug.cgi?id=138665
+
+        Reviewed by Timothy Hatcher.
+
+        Add a new test that only checks for proper invocation return values.
+        Once the async test suite infrastructure is available for frontend tests,
+        more thorough tests of promises and callbacks will be added.
+
+        * inspector/protocol/inspector-backend-invocation-return-value-expected.txt: Added.
+        * inspector/protocol/inspector-backend-invocation-return-value.html: Added.
+        * inspector/protocol/protocol-promise-result-expected.txt: Removed.
+        * inspector/protocol/protocol-promise-result.html: Removed.
+        * platform/win/TestExpectations: Remove deleted test.
+
</ins><span class="cx"> 2015-08-11  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         feMorphology is not rendered correctly on Retina display
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorprotocolinspectorbackendinvocationreturnvalueexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/protocol/inspector-backend-invocation-return-value-expected.txt (0 => 188283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/protocol/inspector-backend-invocation-return-value-expected.txt                                (rev 0)
+++ trunk/LayoutTests/inspector/protocol/inspector-backend-invocation-return-value-expected.txt        2015-08-11 20:15:16 UTC (rev 188283)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+Testing the inspector backend's return values when invoking a protocol command in various ways.
+
+PASS: RuntimeAgent.evaluate should not return a promise when invoked with a function as the last parameter.
+PASS: RuntimeAgent.evaluate should return a Promise when invoked without a callback.
+
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorprotocolinspectorbackendinvocationreturnvaluehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/protocol/inspector-backend-invocation-return-value.html (0 => 188283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/protocol/inspector-backend-invocation-return-value.html                                (rev 0)
+++ trunk/LayoutTests/inspector/protocol/inspector-backend-invocation-return-value.html        2015-08-11 20:15:16 UTC (rev 188283)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../http/tests/inspector/resources/inspector-test.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+function test()
+{
+    let dummyCallback = function(){};
+    let invokeCallbackResult = RuntimeAgent.evaluate(&quot;41&quot;, dummyCallback);
+    InspectorTest.expectThat(!(invokeCallbackResult instanceof Promise), &quot;RuntimeAgent.evaluate should not return a promise when invoked with a function as the last parameter.&quot;);
+
+    let invokePromiseResult = RuntimeAgent.evaluate(&quot;42&quot;);
+    InspectorTest.expectThat(invokePromiseResult instanceof Promise, &quot;RuntimeAgent.evaluate should return a Promise when invoked without a callback.&quot;);
+
+    InspectorTest.completeTest();
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;runTest()&quot;&gt;
+    &lt;p&gt;Testing the inspector backend's return values when invoking a protocol command in various ways.&lt;/p&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorprotocolprotocolpromiseresultexpectedtxt"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/inspector/protocol/protocol-promise-result-expected.txt (188282 => 188283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/protocol/protocol-promise-result-expected.txt        2015-08-11 20:08:56 UTC (rev 188282)
+++ trunk/LayoutTests/inspector/protocol/protocol-promise-result-expected.txt        2015-08-11 20:15:16 UTC (rev 188283)
</span><span class="lines">@@ -1,7 +0,0 @@
</span><del>-Testing that the inspector backend can return command results using promises.
-
-Using a callback, got RuntimeAgent.evaluate() result: 41
-Setting up two promises for RuntimeAgent.evaluate.
-Using a promise, got RuntimeAgent.evaluate() result: 42
-Using a promise, got RuntimeAgent.evaluate() result: 43
-
</del></span></pre></div>
<a id="trunkLayoutTestsinspectorprotocolprotocolpromiseresulthtml"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/inspector/protocol/protocol-promise-result.html (188282 => 188283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/protocol/protocol-promise-result.html        2015-08-11 20:08:56 UTC (rev 188282)
+++ trunk/LayoutTests/inspector/protocol/protocol-promise-result.html        2015-08-11 20:15:16 UTC (rev 188283)
</span><span class="lines">@@ -1,38 +0,0 @@
</span><del>-&lt;!doctype html&gt;
-&lt;html&gt;
-&lt;head&gt;
-&lt;script src=&quot;../../http/tests/inspector/resources/inspector-test.js&quot;&gt;&lt;/script&gt;
-&lt;script&gt;
-function test()
-{
-    var c1 = RuntimeAgent.evaluate(&quot;41&quot;, function(err, result, wasThrown) {
-        InspectorTest.log(&quot;Using a callback, got RuntimeAgent.evaluate() result: &quot; + result.value);
-
-        InspectorTest.log(&quot;Setting up two promises for RuntimeAgent.evaluate.&quot;);
-
-        var p1 = RuntimeAgent.evaluate.promise(&quot;42&quot;);
-        var p2 = RuntimeAgent.evaluate(&quot;43&quot;);
-
-        InspectorTest.assert(!(c1 instanceof Promise), &quot;A promise was returned even though a callback was supplied to the command!&quot;);
-
-        p1.then(function(payload) {
-            InspectorTest.log(&quot;Using a promise, got RuntimeAgent.evaluate() result: &quot; + payload.result.value);
-        });
-        p2.then(function(payload) {
-            InspectorTest.log(&quot;Using a promise, got RuntimeAgent.evaluate() result: &quot; + payload.result.value);
-        });
-
-        Promise.all([p1, p2]).then(function() {
-            InspectorTest.completeTest();
-        }).catch(function(error) {
-            InspectorTest.log(&quot;ERROR: &quot; + error);
-            InspectorTest.completeTest();
-        })
-    });
-}
-&lt;/script&gt;
-&lt;/head&gt;
-&lt;body onload=&quot;runTest()&quot;&gt;
-    &lt;p&gt;Testing that the inspector backend can return command results using promises.&lt;/p&gt;
-&lt;/body&gt;
-&lt;/html&gt;
</del></span></pre></div>
<a id="trunkLayoutTestsplatformwinTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/win/TestExpectations (188282 => 188283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/win/TestExpectations        2015-08-11 20:08:56 UTC (rev 188282)
+++ trunk/LayoutTests/platform/win/TestExpectations        2015-08-11 20:15:16 UTC (rev 188283)
</span><span class="lines">@@ -2369,7 +2369,6 @@
</span><span class="cx"> webkit.org/b/137157 [ Release ] inspector/model/remote-object-get-properties.html [ Pass Timeout ]
</span><span class="cx"> webkit.org/b/137157 [ Debug ] inspector/model/remote-object-get-properties.html [ Skip ] # Debug Assertion
</span><span class="cx"> webkit.org/b/137157 inspector/page/main-frame-resource.html [ Skip ]
</span><del>-webkit.org/b/137157 inspector/protocol-promise-result.html [ Skip ]
</del><span class="cx"> http/tests/inspector/css/bad-mime-type.html [ Skip ]
</span><span class="cx"> inspector/test-harness-trivially-works.html [ Skip ]
</span><span class="cx"> inspector/dom/content-node-region-info.html [ Crash Pass Failure Timeout ]
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (188282 => 188283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2015-08-11 20:08:56 UTC (rev 188282)
+++ trunk/Source/WebInspectorUI/ChangeLog        2015-08-11 20:15:16 UTC (rev 188283)
</span><span class="lines">@@ -1,3 +1,58 @@
</span><ins>+2015-08-11  Brian Burg  &lt;bburg@apple.com&gt;
+
+        Web Inspector: Agent commands do not actually return a promise when expected
+        https://bugs.webkit.org/show_bug.cgi?id=138665
+
+        Reviewed by Timothy Hatcher.
+
+        This patch unifies the handling of different invocation and dispatch modes in the
+        InspectorBackend protocol system. Command responses are dispatched to a provided
+        callback function; if no function was provided, then the command returns a promise.
+
+        Rather than awkwardly converting between promises and callbacks at invocation and
+        response dispatch time, the backend now stores the callback or promise thunks and
+        knows how to invoke each when the response comes. This mirrors how response handling
+        works in ProtocolTestStub.js. InspectorBackend includes more machinery to support Agent
+        objects and various debug flags.
+
+        Performanace impact is expected to be negligible, because there are relatively
+        few commands issued by the inspector frontend and returned promises are short-lived.
+
+        Remove all uses of Command.prototype.promise, since it is no longer necessary.
+
+        * UserInterface/Base/Test.js:
+        (InspectorTest.reloadPage):
+        * UserInterface/Controllers/ReplayManager.js:
+        (WebInspector.ReplayManager.prototype.getSession.get var):
+        (WebInspector.ReplayManager.getSegment.get var):
+        * UserInterface/Models/ReplaySession.js:
+        (WebInspector.ReplaySession.prototype.segmentsChanged):
+        * UserInterface/Models/Resource.js:
+        (WebInspector.Resource.prototype.requestContentFromBackend):
+        * UserInterface/Models/Script.js:
+        (WebInspector.Script.prototype.requestContentFromBackend):
+        * UserInterface/Models/SourceMapResource.js:
+        (WebInspector.SourceMapResource.prototype.requestContentFromBackend):
+        * UserInterface/Protocol/InspectorBackend.js:
+        (InspectorBackendClass):
+        (InspectorBackendClass.prototype.dispatch):
+        (InspectorBackendClass.prototype.runAfterPendingDispatches):
+        (InspectorBackendClass.prototype._sendCommandToBackendWithCallback.set this):
+        (InspectorBackendClass.set this):
+        (InspectorBackendClass.prototype._sendCommandToBackendWithCallback):
+        (InspectorBackendClass.prototype._dispatchResponseToCallback):
+        (InspectorBackendClass.prototype._dispatchResponseToPromise):
+        (InspectorBackendClass.prototype._flushPendingScripts):
+        (InspectorBackend.Command.prototype.invoke):
+        (InspectorBackend.Command.prototype._invokeWithArguments):
+        (InspectorBackendClass.prototype._willSendMessageToBackend.set return): Deleted.
+        (InspectorBackendClass._dispatchCallback.get if): Deleted.
+        (InspectorBackendClass.prototype._willSendMessageToBackend): Deleted.
+        (InspectorBackendClass.prototype._invokeCommand): Deleted.
+        (.callable): Deleted.
+        (InspectorBackend.Command.create): Deleted.
+        (InspectorBackend.Command.prototype.promise): Deleted.
+
</ins><span class="cx"> 2015-08-11  Devin Rousso  &lt;drousso@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Hovering over an element in the Elements tab should highlight the whole line
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceBaseTestjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Test.js (188282 => 188283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Base/Test.js        2015-08-11 20:08:56 UTC (rev 188282)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Test.js        2015-08-11 20:15:16 UTC (rev 188283)
</span><span class="lines">@@ -220,7 +220,7 @@
</span><span class="cx"> 
</span><span class="cx">     this._testPageIsReloading = true;
</span><span class="cx"> 
</span><del>-    return PageAgent.reload.promise(!!shouldIgnoreCache)
</del><ins>+    return PageAgent.reload(!!shouldIgnoreCache)
</ins><span class="cx">         .then(function() {
</span><span class="cx">             this._shouldResendResults = true;
</span><span class="cx">             this._testPageReloadedOnce = true;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceControllersReplayManagerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/ReplayManager.js (188282 => 188283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Controllers/ReplayManager.js        2015-08-11 20:08:56 UTC (rev 188282)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/ReplayManager.js        2015-08-11 20:15:16 UTC (rev 188283)
</span><span class="lines">@@ -133,7 +133,7 @@
</span><span class="cx">         if (this._sessionPromises.has(sessionId))
</span><span class="cx">             return this._sessionPromises.get(sessionId);
</span><span class="cx"> 
</span><del>-        var newPromise = ReplayAgent.getSessionData.promise(sessionId)
</del><ins>+        var newPromise = ReplayAgent.getSessionData(sessionId)
</ins><span class="cx">             .then(function(payload) {
</span><span class="cx">                 return Promise.resolve(WebInspector.ReplaySession.fromPayload(sessionId, payload));
</span><span class="cx">             });
</span><span class="lines">@@ -148,7 +148,7 @@
</span><span class="cx">         if (this._segmentPromises.has(segmentId))
</span><span class="cx">             return this._segmentPromises.get(segmentId);
</span><span class="cx"> 
</span><del>-        var newPromise = ReplayAgent.getSegmentData.promise(segmentId)
</del><ins>+        var newPromise = ReplayAgent.getSegmentData(segmentId)
</ins><span class="cx">             .then(function(payload) {
</span><span class="cx">                 return Promise.resolve(new WebInspector.ReplaySessionSegment(segmentId, payload));
</span><span class="cx">             });
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsReplaySessionjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/ReplaySession.js (188282 => 188283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/ReplaySession.js        2015-08-11 20:08:56 UTC (rev 188282)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/ReplaySession.js        2015-08-11 20:15:16 UTC (rev 188283)
</span><span class="lines">@@ -55,7 +55,7 @@
</span><span class="cx">     segmentsChanged()
</span><span class="cx">     {
</span><span class="cx">         // The replay manager won't update the session's list of segments nor create a new session.
</span><del>-        ReplayAgent.getSessionData.promise(this.identifier)
</del><ins>+        ReplayAgent.getSessionData(this.identifier)
</ins><span class="cx">             .then(this._updateFromPayload.bind(this));
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsResourcejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js (188282 => 188283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js        2015-08-11 20:08:56 UTC (rev 188282)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Resource.js        2015-08-11 20:15:16 UTC (rev 188283)
</span><span class="lines">@@ -484,11 +484,11 @@
</span><span class="cx">         // If we have the requestIdentifier we can get the actual response for this specific resource.
</span><span class="cx">         // Otherwise the content will be cached resource data, which might not exist anymore.
</span><span class="cx">         if (this._requestIdentifier)
</span><del>-            return NetworkAgent.getResponseBody.promise(this._requestIdentifier);
</del><ins>+            return NetworkAgent.getResponseBody(this._requestIdentifier);
</ins><span class="cx"> 
</span><span class="cx">         // There is no request identifier or frame to request content from.
</span><span class="cx">         if (this._parentFrame)
</span><del>-            return PageAgent.getResourceContent.promise(this._parentFrame.id, this._url);
</del><ins>+            return PageAgent.getResourceContent(this._parentFrame.id, this._url);
</ins><span class="cx"> 
</span><span class="cx">         return Promise.reject(new Error(&quot;Content request failed.&quot;));
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsScriptjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Script.js (188282 => 188283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/Script.js        2015-08-11 20:08:56 UTC (rev 188282)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Script.js        2015-08-11 20:15:16 UTC (rev 188283)
</span><span class="lines">@@ -118,7 +118,7 @@
</span><span class="cx">             return Promise.reject(new Error(&quot;There is no identifier to request content with.&quot;));
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        return DebuggerAgent.getScriptSource.promise(this._id);
</del><ins>+        return DebuggerAgent.getScriptSource(this._id);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     saveIdentityToCookie(cookie)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsSourceMapResourcejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/SourceMapResource.js (188282 => 188283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/SourceMapResource.js        2015-08-11 20:08:56 UTC (rev 188282)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/SourceMapResource.js        2015-08-11 20:15:16 UTC (rev 188283)
</span><span class="lines">@@ -137,7 +137,7 @@
</span><span class="cx">         if (!frameIdentifier)
</span><span class="cx">             frameIdentifier = WebInspector.frameResourceManager.mainFrame.id;
</span><span class="cx"> 
</span><del>-        return NetworkAgent.loadResource.promise(frameIdentifier, this.url).then(sourceMapResourceLoaded.bind(this)).catch(sourceMapResourceLoadError.bind(this));
</del><ins>+        return NetworkAgent.loadResource(frameIdentifier, this.url).then(sourceMapResourceLoaded.bind(this)).catch(sourceMapResourceLoadError.bind(this));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     createSourceCodeLocation(lineNumber, columnNumber)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceProtocolInspectorBackendjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js (188282 => 188283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js        2015-08-11 20:08:56 UTC (rev 188282)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js        2015-08-11 20:15:16 UTC (rev 188283)
</span><span class="lines">@@ -35,8 +35,7 @@
</span><span class="cx">     constructor()
</span><span class="cx">     {
</span><span class="cx">         this._lastSequenceId = 1;
</span><del>-        this._pendingResponsesCount = 0;
-        this._callbackData = new Map;
</del><ins>+        this._pendingResponses = new Map;
</ins><span class="cx">         this._agents = {};
</span><span class="cx">         this._deferredScripts = [];
</span><span class="cx"> 
</span><span class="lines">@@ -83,7 +82,7 @@
</span><span class="cx">         var messageObject = (typeof message === &quot;string&quot;) ? JSON.parse(message) : message;
</span><span class="cx"> 
</span><span class="cx">         if (&quot;id&quot; in messageObject)
</span><del>-            this._dispatchCallback(messageObject);
</del><ins>+            this._dispatchResponse(messageObject);
</ins><span class="cx">         else
</span><span class="cx">             this._dispatchEvent(messageObject);
</span><span class="cx">     }
</span><span class="lines">@@ -93,7 +92,7 @@
</span><span class="cx">         console.assert(script);
</span><span class="cx">         console.assert(typeof script === &quot;function&quot;);
</span><span class="cx"> 
</span><del>-        if (!this._pendingResponsesCount)
</del><ins>+        if (!this._pendingResponses.size)
</ins><span class="cx">             script.call(this);
</span><span class="cx">         else
</span><span class="cx">             this._deferredScripts.push(script);
</span><span class="lines">@@ -122,81 +121,128 @@
</span><span class="cx">         return agent;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    _willSendMessageToBackend(command, callback)
</del><ins>+    _sendCommandToBackendWithCallback(command, parameters, callback)
</ins><span class="cx">     {
</span><del>-        ++this._pendingResponsesCount;
-        var sequenceId = this._lastSequenceId++;
</del><ins>+        let sequenceId = this._lastSequenceId++;
</ins><span class="cx"> 
</span><del>-        if (callback &amp;&amp; typeof callback === &quot;function&quot;) {
-            var callbackData =  {
-                &quot;callback&quot;: callback,
-                &quot;command&quot;: command,
-            };
</del><ins>+        let messageObject = {
+            &quot;id&quot;: sequenceId,
+            &quot;method&quot;: command.qualifiedName,
+        };
</ins><span class="cx"> 
</span><del>-            if (this.dumpInspectorTimeStats)
-                callbackData.sendRequestTime = Date.now();
</del><ins>+        if (Object.keys(parameters).length)
+            messageObject[&quot;params&quot;] = parameters;
</ins><span class="cx"> 
</span><del>-            this._callbackData.set(sequenceId, callbackData);
-        }
</del><ins>+        let responseData = {command, callback};
</ins><span class="cx"> 
</span><del>-        return sequenceId;
</del><ins>+        // FIXME: &lt;https://webkit.org/b/135467&gt; use performance.now() where available.
+        if (this.dumpInspectorTimeStats)
+            responseData.sendRequestTime = Date.now();
+
+        this._pendingResponses.set(sequenceId, responseData);
+        this._sendMessageToBackend(messageObject);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    _dispatchCallback(messageObject)
</del><ins>+    _sendCommandToBackendExpectingPromise(command, parameters)
</ins><span class="cx">     {
</span><del>-        --this._pendingResponsesCount;
-        console.assert(this._pendingResponsesCount &gt;= 0);
</del><ins>+        let sequenceId = this._lastSequenceId++;
</ins><span class="cx"> 
</span><ins>+        let messageObject = {
+            &quot;id&quot;: sequenceId,
+            &quot;method&quot;: command.qualifiedName,
+        };
+
+        if (Object.keys(parameters).length)
+            messageObject[&quot;params&quot;] = parameters;
+
+        let responseData = {command};
+
+        // FIXME: &lt;https://webkit.org/b/135467&gt; use performance.now() where available.
+        if (this.dumpInspectorTimeStats)
+            responseData.sendRequestTime = Date.now();
+
+        let responsePromise = new Promise(function(resolve, reject) {
+            responseData.promise = {resolve, reject};
+        });
+
+        this._pendingResponses.set(sequenceId, responseData);
+        this._sendMessageToBackend(messageObject);
+
+        return responsePromise;
+    }
+
+    _sendMessageToBackend(messageObject)
+    {
+        let stringifiedMessage = JSON.stringify(messageObject);
+        if (this.dumpInspectorProtocolMessages)
+            console.log(&quot;frontend: &quot; + stringifiedMessage);
+
+        InspectorFrontendHost.sendMessageToBackend(stringifiedMessage);
+    }
+
+    _dispatchResponse(messageObject)
+    {
+        console.assert(this._pendingResponses.size &gt;= 0);
+
</ins><span class="cx">         if (messageObject[&quot;error&quot;]) {
</span><span class="cx">             if (messageObject[&quot;error&quot;].code !== -32000)
</span><span class="cx">                 this._reportProtocolError(messageObject);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        var callbackData = this._callbackData.get(messageObject[&quot;id&quot;]);
-        if (callbackData &amp;&amp; typeof callbackData.callback === &quot;function&quot;) {
-            var command = callbackData.command;
-            var callback = callbackData.callback;
-            var callbackArguments = [];
</del><ins>+        let sequenceId = messageObject[&quot;id&quot;];
+        console.assert(this._pendingResponses.has(sequenceId), sequenceId, this._pendingResponses);
</ins><span class="cx"> 
</span><del>-            callbackArguments.push(messageObject[&quot;error&quot;] ? messageObject[&quot;error&quot;].message : null);
</del><ins>+        let responseData = this._pendingResponses.take(sequenceId);
+        let {command, callback, promise} = responseData;
</ins><span class="cx"> 
</span><del>-            if (messageObject[&quot;result&quot;]) {
-                // FIXME: this should be indicated by invoking the command differently, rather
-                // than by setting a magical property on the callback. &lt;webkit.org/b/132386&gt;
-                if (callback.expectsResultObject) {
-                    // The callback expects results as an object with properties, this is useful
-                    // for backwards compatibility with renamed or different parameters.
-                    callbackArguments.push(messageObject[&quot;result&quot;]);
-                } else {
-                    for (var parameterName of command.replySignature)
-                        callbackArguments.push(messageObject[&quot;result&quot;][parameterName]);
-                }
-            }
</del><ins>+        var processingStartTime;
+        if (this.dumpInspectorTimeStats)
+            processingStartTime = Date.now();
</ins><span class="cx"> 
</span><del>-            var processingStartTime;
-            if (this.dumpInspectorTimeStats)
-                processingStartTime = Date.now();
</del><ins>+        if (typeof callback === &quot;function&quot;)
+            this._dispatchResponseToCallback(command, messageObject, callback);
+        else if (typeof promise === &quot;object&quot;)
+            this._dispatchResponseToPromise(command, messageObject, promise);
+        else
+            console.error(&quot;Received a command response without a corresponding callback or promise.&quot;, messageObject, command);
</ins><span class="cx"> 
</span><del>-            try {
-                callback.apply(null, callbackArguments);
-            } catch (e) {
-                console.error(&quot;Uncaught exception in inspector page while dispatching callback for command &quot; + command.qualifiedName + &quot;: &quot;, e, e.stack);
-            }
</del><ins>+        var processingDuration = Date.now() - processingStartTime;
+        if (this.warnForLongMessageHandling &amp;&amp; processingDuration &gt; this.longMessageHandlingThreshold)
+            console.warn(&quot;InspectorBackend: took &quot; + processingDuration + &quot;ms to handle response for command: &quot; + command.qualifiedName);
</ins><span class="cx"> 
</span><del>-            var processingDuration = Date.now() - processingStartTime;
-            if (this.warnForLongMessageHandling &amp;&amp; processingDuration &gt; this.longMessageHandlingThreshold)
-                console.warn(&quot;InspectorBackend: took &quot; + processingDuration + &quot;ms to handle response for command: &quot; + command.qualifiedName);
</del><ins>+        if (this.dumpInspectorTimeStats)
+            console.log(&quot;time-stats: Handling: &quot; + processingDuration + &quot;ms; RTT: &quot; + (processingStartTime - responseData.sendRequestTime) + &quot;ms; (command &quot; + command.qualifiedName + &quot;)&quot;);
</ins><span class="cx"> 
</span><del>-            if (this.dumpInspectorTimeStats)
-                console.log(&quot;time-stats: Handling: &quot; + processingDuration + &quot;ms; RTT: &quot; + (processingStartTime - callbackData.sendRequestTime) + &quot;ms; (command &quot; + command.qualifiedName + &quot;)&quot;);
</del><ins>+        if (this._deferredScripts.length &amp;&amp; !this._pendingResponses.size)
+            this._flushPendingScripts();
+    }
</ins><span class="cx"> 
</span><del>-            this._callbackData.delete(messageObject[&quot;id&quot;]);
</del><ins>+    _dispatchResponseToCallback(command, messageObject, callback)
+    {
+        let callbackArguments = [];
+        callbackArguments.push(messageObject[&quot;error&quot;] ? messageObject[&quot;error&quot;].message : null);
+
+        if (messageObject[&quot;result&quot;]) {
+            for (var parameterName of command.replySignature)
+                callbackArguments.push(messageObject[&quot;result&quot;][parameterName]);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (this._deferredScripts.length &amp;&amp; !this._pendingResponsesCount)
-            this._flushPendingScripts();
</del><ins>+        try {
+            callback.apply(null, callbackArguments);
+        } catch (e) {
+            console.error(&quot;Uncaught exception in inspector page while dispatching callback for command &quot; + command.qualifiedName + &quot;: &quot;, e, e.stack);
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    _dispatchResponseToPromise(command, messageObject, promise)
+    {
+        let {resolve, reject} = promise;
+        if (messageObject[&quot;error&quot;])
+            reject(new Error(messageObject[&quot;error&quot;].message));
+        else
+            resolve(messageObject[&quot;result&quot;]);
+    }
+
</ins><span class="cx">     _dispatchEvent(messageObject)
</span><span class="cx">     {
</span><span class="cx">         var qualifiedName = messageObject[&quot;method&quot;];
</span><span class="lines">@@ -243,25 +289,6 @@
</span><span class="cx">             console.log(&quot;time-stats: Handling: &quot; + processingDuration + &quot;ms (event &quot; + messageObject[&quot;method&quot;] + &quot;)&quot;);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    _invokeCommand(command, parameters, callback)
-    {
-        var messageObject = {};
-        messageObject[&quot;method&quot;] = command.qualifiedName;
-
-        if (parameters)
-            messageObject[&quot;params&quot;] = parameters;
-
-        // We always assign an id as a sequence identifier.
-        // Callback data is saved only if a callback is actually passed.
-        messageObject[&quot;id&quot;] = this._willSendMessageToBackend(command, callback);
-
-        var stringifiedMessage = JSON.stringify(messageObject);
-        if (this.dumpInspectorProtocolMessages)
-            console.log(&quot;frontend: &quot; + stringifiedMessage);
-
-        InspectorFrontendHost.sendMessageToBackend(stringifiedMessage);
-    }
-
</del><span class="cx">     _reportProtocolError(messageObject)
</span><span class="cx">     {
</span><span class="cx">         console.error(&quot;Request with id = &quot; + messageObject[&quot;id&quot;] + &quot; failed. &quot; + JSON.stringify(messageObject[&quot;error&quot;]));
</span><span class="lines">@@ -269,7 +296,7 @@
</span><span class="cx"> 
</span><span class="cx">     _flushPendingScripts()
</span><span class="cx">     {
</span><del>-        console.assert(!this._pendingResponsesCount);
</del><ins>+        console.assert(this._pendingResponses.size === 0);
</ins><span class="cx"> 
</span><span class="cx">         var scriptsToRun = this._deferredScripts;
</span><span class="cx">         this._deferredScripts = [];
</span><span class="lines">@@ -378,9 +405,6 @@
</span><span class="cx">     var instance = new InspectorBackend.Command(backend, commandName, callSignature, replySignature);
</span><span class="cx"> 
</span><span class="cx">     function callable() {
</span><del>-        // If the last argument to the command is not a function, return a result promise.
-        if (!arguments.length || typeof arguments[arguments.length - 1] !== &quot;function&quot;)
-            return instance.promise.apply(instance, arguments);
</del><span class="cx">         return instance._invokeWithArguments.apply(instance, arguments);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -421,28 +445,12 @@
</span><span class="cx">     {
</span><span class="cx">         'use strict';
</span><span class="cx"> 
</span><del>-        var instance = this._instance;
-        instance._backend._invokeCommand(instance, commandArguments, callback);
-    },
</del><ins>+        let instance = this._instance;
</ins><span class="cx"> 
</span><del>-    promise: function()
-    {
-        'use strict';
-
-        var instance = this._instance;
-        var promiseArguments = Array.from(arguments);
-        return new Promise(function(resolve, reject) {
-            function convertToPromiseCallback(error, payload) {
-                return error ? reject(new Error(error)) : resolve(payload);
-            }
-
-            // FIXME: this should be indicated by invoking the command differently, rather
-            // than by setting a magical property on the callback. &lt;webkit.org/b/132386&gt;
-            convertToPromiseCallback.expectsResultObject = true;
-
-            promiseArguments.push(convertToPromiseCallback);
-            instance._invokeWithArguments.apply(instance, promiseArguments);
-        });
</del><ins>+        if (typeof callback === &quot;function&quot;)
+            instance._backend._sendCommandToBackendWithCallback(instance, commandArguments, callback);
+        else
+            return instance._backend._sendCommandToBackendExpectingPromise(instance, commandArguments);
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     supports: function(parameterName)
</span><span class="lines">@@ -461,23 +469,22 @@
</span><span class="cx">     {
</span><span class="cx">         'use strict';
</span><span class="cx"> 
</span><del>-        var instance = this._instance;
-        var commandArguments = Array.from(arguments);
-        var callback = typeof commandArguments.lastValue === &quot;function&quot; ? commandArguments.pop() : null;
</del><ins>+        let instance = this._instance;
+        let commandArguments = Array.from(arguments);
+        let callback = typeof commandArguments.lastValue === &quot;function&quot; ? commandArguments.pop() : null;
</ins><span class="cx"> 
</span><del>-        var parameters = {};
-        for (var i = 0; i &lt; instance.callSignature.length; ++i) {
-            var parameter = instance.callSignature[i];
-            var parameterName = parameter[&quot;name&quot;];
-            var typeName = parameter[&quot;type&quot;];
-            var optionalFlag = parameter[&quot;optional&quot;];
</del><ins>+        let parameters = {};
+        for (let parameter of instance.callSignature) {
+            let parameterName = parameter[&quot;name&quot;];
+            let typeName = parameter[&quot;type&quot;];
+            let optionalFlag = parameter[&quot;optional&quot;];
</ins><span class="cx"> 
</span><span class="cx">             if (!commandArguments.length &amp;&amp; !optionalFlag) {
</span><span class="cx">                 console.error(&quot;Protocol Error: Invalid number of arguments for method '&quot; + instance.qualifiedName + &quot;' call. It must have the following arguments '&quot; + JSON.stringify(instance.callSignature) + &quot;'.&quot;);
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            var value = commandArguments.shift();
</del><ins>+            let value = commandArguments.shift();
</ins><span class="cx">             if (optionalFlag &amp;&amp; value === undefined)
</span><span class="cx">                 continue;
</span><span class="cx"> 
</span><span class="lines">@@ -496,7 +503,10 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        instance._backend._invokeCommand(instance, Object.keys(parameters).length ? parameters : null, callback);
</del><ins>+        if (callback)
+            instance._backend._sendCommandToBackendWithCallback(instance, parameters, callback);
+        else
+            return instance._backend._sendCommandToBackendExpectingPromise(instance, parameters);
</ins><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>