<!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>[213666] trunk/Source</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/213666">213666</a></dd>
<dt>Author</dt> <dd>nvasilyev@apple.com</dd>
<dt>Date</dt> <dd>2017-03-09 13:56:33 -0800 (Thu, 09 Mar 2017)</dd>
</dl>
<h3>Log Message</h3>
<pre>Web Inspector: Show individual messages in the content pane for a WebSocket
https://bugs.webkit.org/show_bug.cgi?id=169011
Reviewed by Joseph Pecoraro.
Source/JavaScriptCore:
Add walltime parameter and correct the description of Timestamp type.
* inspector/protocol/Network.json:
Source/WebCore:
Add walltime parameter.
No new tests. Tests will be added in a follow up patch.
* inspector/InspectorNetworkAgent.cpp:
(WebCore::InspectorNetworkAgent::willSendWebSocketHandshakeRequest):
Source/WebInspectorUI:
When selecting a Web Socket in Network panel or Resources, display a table
of all messages that have been sent and received.
* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Controllers/FrameResourceManager.js:
(WebInspector.FrameResourceManager.prototype.webSocketWillSendHandshakeRequest):
Add a walltime parameter.
(WebInspector.FrameResourceManager.prototype._webSocketFrameReceivedOrSent):
Fix a bug: masked messages are outgoing, not incoming.
* UserInterface/Images/ArrowUp.svg: Added.
* UserInterface/Images/gtk/ArrowUp.svg: Added.
Add an icon for outgoing messages.
* UserInterface/Main.html:
* UserInterface/Models/WebSocketResource.js:
(WebInspector.WebSocketResource):
(WebInspector.WebSocketResource.prototype.get walltime):
(WebInspector.WebSocketResource.prototype.addFrame):
(WebInspector.WebSocketResource.prototype._walltimeForWebSocketTimestamp):
* UserInterface/Protocol/NetworkObserver.js:
(WebInspector.NetworkObserver.prototype.webSocketWillSendHandshakeRequest):
(WebInspector.NetworkObserver.prototype.webSocketFrameSent):
(WebInspector.NetworkObserver.prototype.webSocketFrameError):
(WebInspector.NetworkObserver):
* UserInterface/Views/NetworkSidebarPanel.js:
(WebInspector.NetworkSidebarPanel.prototype.treeElementAddedOrChanged):
* UserInterface/Views/ResourceClusterContentView.js:
(WebInspector.ResourceClusterContentView.prototype.get responseContentView):
* UserInterface/Views/WebSocketContentView.css: Added.
(.web-socket.content-view > .data-grid):
(.web-socket.content-view > .data-grid table.data):
(.web-socket.content-view > .data-grid td.data-column,):
(body[dir=ltr] .web-socket.content-view > .data-grid .data-column > div):
(body[dir=rtl] .web-socket.content-view > .data-grid .data-column > div):
(.web-socket.content-view .icon):
(body[dir=ltr] .web-socket.content-view .icon):
(body[dir=rtl] .web-socket.content-view .icon):
(.web-socket.content-view .outgoing .icon):
(.web-socket.content-view .data-grid.variable-height-rows table.data tr:nth-child(odd)):
(.web-socket.content-view .data-grid table.data tr.revealed):
(.web-socket.content-view .data-grid.variable-height-rows table.data tr.outgoing):
(.web-socket.content-view .data-grid.variable-height-rows table.data tr.non-text-frame):
* UserInterface/Views/WebSocketContentView.js: Added.
(WebInspector.WebSocketContentView):
Only show Time column when walltime is available.
(WebInspector.WebSocketContentView.textForOpcode):
(WebInspector.WebSocketContentView.prototype.shown):
(WebInspector.WebSocketContentView.prototype.hidden):
(WebInspector.WebSocketContentView.prototype.addFrame):
(WebInspector.WebSocketContentView.prototype._updateFrames):
Only render frames that haven't been rendered yet.
(WebInspector.WebSocketContentView.prototype._addRow):
(WebInspector.WebSocketContentView.prototype._timeStringFromTimestamp):</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorprotocolNetworkjson">trunk/Source/JavaScriptCore/inspector/protocol/Network.json</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorNetworkAgentcpp">trunk/Source/WebCore/inspector/InspectorNetworkAgent.cpp</a></li>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUILocalizationsenlprojlocalizedStringsjs">trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceControllersFrameResourceManagerjs">trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceMainhtml">trunk/Source/WebInspectorUI/UserInterface/Main.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsWebSocketResourcejs">trunk/Source/WebInspectorUI/UserInterface/Models/WebSocketResource.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceProtocolNetworkObserverjs">trunk/Source/WebInspectorUI/UserInterface/Protocol/NetworkObserver.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsNetworkSidebarPaneljs">trunk/Source/WebInspectorUI/UserInterface/Views/NetworkSidebarPanel.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsResourceClusterContentViewjs">trunk/Source/WebInspectorUI/UserInterface/Views/ResourceClusterContentView.js</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceImagesArrowUpsvg">trunk/Source/WebInspectorUI/UserInterface/Images/ArrowUp.svg</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceImagesgtkArrowUpsvg">trunk/Source/WebInspectorUI/UserInterface/Images/gtk/ArrowUp.svg</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsWebSocketContentViewcss">trunk/Source/WebInspectorUI/UserInterface/Views/WebSocketContentView.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsWebSocketContentViewjs">trunk/Source/WebInspectorUI/UserInterface/Views/WebSocketContentView.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (213665 => 213666)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2017-03-09 21:42:04 UTC (rev 213665)
+++ trunk/Source/JavaScriptCore/ChangeLog        2017-03-09 21:56:33 UTC (rev 213666)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2017-03-09 Nikita Vasilyev <nvasilyev@apple.com>
+
+ Web Inspector: Show individual messages in the content pane for a WebSocket
+ https://bugs.webkit.org/show_bug.cgi?id=169011
+
+ Reviewed by Joseph Pecoraro.
+
+ Add walltime parameter and correct the description of Timestamp type.
+
+ * inspector/protocol/Network.json:
+
</ins><span class="cx"> 2017-03-09 Filip Pizlo <fpizlo@apple.com>
</span><span class="cx">
</span><span class="cx"> Unreviewed, fix weak external symbol error.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorprotocolNetworkjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/protocol/Network.json (213665 => 213666)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/protocol/Network.json        2017-03-09 21:42:04 UTC (rev 213665)
+++ trunk/Source/JavaScriptCore/inspector/protocol/Network.json        2017-03-09 21:56:33 UTC (rev 213666)
</span><span class="lines">@@ -21,6 +21,11 @@
</span><span class="cx"> {
</span><span class="cx"> "id": "Timestamp",
</span><span class="cx"> "type": "number",
</span><ins>+ "description": "Elapsed seconds since frontend connected."
+ },
+ {
+ "id": "Walltime",
+ "type": "number",
</ins><span class="cx"> "description": "Number of seconds since epoch."
</span><span class="cx"> },
</span><span class="cx"> {
</span><span class="lines">@@ -255,7 +260,8 @@
</span><span class="cx"> "description": "Fired when WebSocket is about to initiate handshake.",
</span><span class="cx"> "parameters": [
</span><span class="cx"> { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
</span><del>- { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
</del><ins>+ { "name": "timestamp", "$ref": "Timestamp" },
+ { "name": "walltime", "$ref": "Walltime" },
</ins><span class="cx"> { "name": "request", "$ref": "WebSocketRequest", "description": "WebSocket request data." }
</span><span class="cx"> ]
</span><span class="cx"> },
</span><span class="lines">@@ -264,7 +270,7 @@
</span><span class="cx"> "description": "Fired when WebSocket handshake response becomes available.",
</span><span class="cx"> "parameters": [
</span><span class="cx"> { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
</span><del>- { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
</del><ins>+ { "name": "timestamp", "$ref": "Timestamp" },
</ins><span class="cx"> { "name": "response", "$ref": "WebSocketResponse", "description": "WebSocket response data." }
</span><span class="cx"> ]
</span><span class="cx"> },
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (213665 => 213666)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-03-09 21:42:04 UTC (rev 213665)
+++ trunk/Source/WebCore/ChangeLog        2017-03-09 21:56:33 UTC (rev 213666)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2017-03-09 Nikita Vasilyev <nvasilyev@apple.com>
+
+ Web Inspector: Show individual messages in the content pane for a WebSocket
+ https://bugs.webkit.org/show_bug.cgi?id=169011
+
+ Reviewed by Joseph Pecoraro.
+
+ Add walltime parameter.
+
+ No new tests. Tests will be added in a follow up patch.
+
+ * inspector/InspectorNetworkAgent.cpp:
+ (WebCore::InspectorNetworkAgent::willSendWebSocketHandshakeRequest):
+
</ins><span class="cx"> 2017-03-09 Brent Fulgham <bfulgham@apple.com>
</span><span class="cx">
</span><span class="cx"> Unreviewed build fix after r213628.
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorNetworkAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorNetworkAgent.cpp (213665 => 213666)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorNetworkAgent.cpp        2017-03-09 21:42:04 UTC (rev 213665)
+++ trunk/Source/WebCore/inspector/InspectorNetworkAgent.cpp        2017-03-09 21:56:33 UTC (rev 213666)
</span><span class="lines">@@ -557,7 +557,7 @@
</span><span class="cx"> auto requestObject = Inspector::Protocol::Network::WebSocketRequest::create()
</span><span class="cx"> .setHeaders(buildObjectForHeaders(request.httpHeaderFields()))
</span><span class="cx"> .release();
</span><del>- m_frontendDispatcher->webSocketWillSendHandshakeRequest(IdentifiersFactory::requestId(identifier), timestamp(), WTFMove(requestObject));
</del><ins>+ m_frontendDispatcher->webSocketWillSendHandshakeRequest(IdentifiersFactory::requestId(identifier), timestamp(), currentTime(), WTFMove(requestObject));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void InspectorNetworkAgent::didReceiveWebSocketHandshakeResponse(unsigned long identifier, const ResourceResponse& response)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (213665 => 213666)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2017-03-09 21:42:04 UTC (rev 213665)
+++ trunk/Source/WebInspectorUI/ChangeLog        2017-03-09 21:56:33 UTC (rev 213666)
</span><span class="lines">@@ -1,3 +1,69 @@
</span><ins>+2017-03-09 Nikita Vasilyev <nvasilyev@apple.com>
+
+ Web Inspector: Show individual messages in the content pane for a WebSocket
+ https://bugs.webkit.org/show_bug.cgi?id=169011
+
+ Reviewed by Joseph Pecoraro.
+
+ When selecting a Web Socket in Network panel or Resources, display a table
+ of all messages that have been sent and received.
+
+ * Localizations/en.lproj/localizedStrings.js:
+ * UserInterface/Controllers/FrameResourceManager.js:
+ (WebInspector.FrameResourceManager.prototype.webSocketWillSendHandshakeRequest):
+ Add a walltime parameter.
+
+ (WebInspector.FrameResourceManager.prototype._webSocketFrameReceivedOrSent):
+ Fix a bug: masked messages are outgoing, not incoming.
+
+ * UserInterface/Images/ArrowUp.svg: Added.
+ * UserInterface/Images/gtk/ArrowUp.svg: Added.
+ Add an icon for outgoing messages.
+
+ * UserInterface/Main.html:
+ * UserInterface/Models/WebSocketResource.js:
+ (WebInspector.WebSocketResource):
+ (WebInspector.WebSocketResource.prototype.get walltime):
+ (WebInspector.WebSocketResource.prototype.addFrame):
+ (WebInspector.WebSocketResource.prototype._walltimeForWebSocketTimestamp):
+ * UserInterface/Protocol/NetworkObserver.js:
+ (WebInspector.NetworkObserver.prototype.webSocketWillSendHandshakeRequest):
+ (WebInspector.NetworkObserver.prototype.webSocketFrameSent):
+ (WebInspector.NetworkObserver.prototype.webSocketFrameError):
+ (WebInspector.NetworkObserver):
+ * UserInterface/Views/NetworkSidebarPanel.js:
+ (WebInspector.NetworkSidebarPanel.prototype.treeElementAddedOrChanged):
+ * UserInterface/Views/ResourceClusterContentView.js:
+ (WebInspector.ResourceClusterContentView.prototype.get responseContentView):
+ * UserInterface/Views/WebSocketContentView.css: Added.
+ (.web-socket.content-view > .data-grid):
+ (.web-socket.content-view > .data-grid table.data):
+ (.web-socket.content-view > .data-grid td.data-column,):
+ (body[dir=ltr] .web-socket.content-view > .data-grid .data-column > div):
+ (body[dir=rtl] .web-socket.content-view > .data-grid .data-column > div):
+ (.web-socket.content-view .icon):
+ (body[dir=ltr] .web-socket.content-view .icon):
+ (body[dir=rtl] .web-socket.content-view .icon):
+ (.web-socket.content-view .outgoing .icon):
+ (.web-socket.content-view .data-grid.variable-height-rows table.data tr:nth-child(odd)):
+ (.web-socket.content-view .data-grid table.data tr.revealed):
+ (.web-socket.content-view .data-grid.variable-height-rows table.data tr.outgoing):
+ (.web-socket.content-view .data-grid.variable-height-rows table.data tr.non-text-frame):
+
+ * UserInterface/Views/WebSocketContentView.js: Added.
+ (WebInspector.WebSocketContentView):
+ Only show Time column when walltime is available.
+
+ (WebInspector.WebSocketContentView.textForOpcode):
+ (WebInspector.WebSocketContentView.prototype.shown):
+ (WebInspector.WebSocketContentView.prototype.hidden):
+ (WebInspector.WebSocketContentView.prototype.addFrame):
+ (WebInspector.WebSocketContentView.prototype._updateFrames):
+ Only render frames that haven't been rendered yet.
+
+ (WebInspector.WebSocketContentView.prototype._addRow):
+ (WebInspector.WebSocketContentView.prototype._timeStringFromTimestamp):
+
</ins><span class="cx"> 2017-03-09 Matt Baker <mattbaker@apple.com>
</span><span class="cx">
</span><span class="cx"> Web Inspector: DOMTreeManager dispatches DocumentUpdated twice when the document is cleared
</span></span></pre></div>
<a id="trunkSourceWebInspectorUILocalizationsenlprojlocalizedStringsjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (213665 => 213666)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js        2017-03-09 21:42:04 UTC (rev 213665)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js        2017-03-09 21:56:33 UTC (rev 213666)
</span><span class="lines">@@ -114,6 +114,7 @@
</span><span class="cx"> localizedStrings["Background"] = "Background";
</span><span class="cx"> localizedStrings["Basis"] = "Basis";
</span><span class="cx"> localizedStrings["Bezier"] = "Bezier";
</span><ins>+localizedStrings["Binary Frame"] = "Binary Frame";
</ins><span class="cx"> localizedStrings["Blend"] = "Blend";
</span><span class="cx"> localizedStrings["Block Variables"] = "Block Variables";
</span><span class="cx"> localizedStrings["Blur"] = "Blur";
</span><span class="lines">@@ -191,6 +192,7 @@
</span><span class="cx"> localizedStrings["Condition"] = "Condition";
</span><span class="cx"> localizedStrings["Conditional expression"] = "Conditional expression";
</span><span class="cx"> localizedStrings["Connection"] = "Connection";
</span><ins>+localizedStrings["Connection Close Frame"] = "Connection Close Frame";
</ins><span class="cx"> localizedStrings["Console"] = "Console";
</span><span class="cx"> localizedStrings["Console Evaluation"] = "Console Evaluation";
</span><span class="cx"> localizedStrings["Console Evaluation %d"] = "Console Evaluation %d";
</span><span class="lines">@@ -202,6 +204,7 @@
</span><span class="cx"> localizedStrings["Content"] = "Content";
</span><span class="cx"> localizedStrings["Content Flow"] = "Content Flow";
</span><span class="cx"> localizedStrings["Content Security Policy violation of directive: %s"] = "Content Security Policy violation of directive: %s";
</span><ins>+localizedStrings["Continuation Frame"] = "Continuation Frame";
</ins><span class="cx"> localizedStrings["Continue script execution (%s or %s)"] = "Continue script execution (%s or %s)";
</span><span class="cx"> localizedStrings["Continue to Here"] = "Continue to Here";
</span><span class="cx"> localizedStrings["Controls"] = "Controls";
</span><span class="lines">@@ -589,8 +592,10 @@
</span><span class="cx"> localizedStrings["Pause Playback"] = "Pause Playback";
</span><span class="cx"> localizedStrings["Pause Reason"] = "Pause Reason";
</span><span class="cx"> localizedStrings["Pause script execution (%s or %s)"] = "Pause script execution (%s or %s)";
</span><ins>+localizedStrings["Ping Frame"] = "Ping Frame";
</ins><span class="cx"> localizedStrings["Play Sound"] = "Play Sound";
</span><span class="cx"> localizedStrings["Polite"] = "Polite";
</span><ins>+localizedStrings["Pong Frame"] = "Pong Frame";
</ins><span class="cx"> localizedStrings["Port"] = "Port";
</span><span class="cx"> localizedStrings["Position"] = "Position";
</span><span class="cx"> localizedStrings["Position X"] = "Position X";
</span><span class="lines">@@ -783,6 +788,7 @@
</span><span class="cx"> localizedStrings["Take snapshot"] = "Take snapshot";
</span><span class="cx"> localizedStrings["Template Content"] = "Template Content";
</span><span class="cx"> localizedStrings["Text"] = "Text";
</span><ins>+localizedStrings["Text Frame"] = "Text Frame";
</ins><span class="cx"> localizedStrings["Text Node"] = "Text Node";
</span><span class="cx"> localizedStrings["Text Only"] = "Text Only";
</span><span class="cx"> localizedStrings["The selector “%s” is invalid.\nClick to revert to the previous selector."] = "The selector “%s” is invalid.\nClick to revert to the previous selector.";
</span><span class="lines">@@ -854,6 +860,7 @@
</span><span class="cx"> localizedStrings["Warnings"] = "Warnings";
</span><span class="cx"> localizedStrings["Watch Expressions"] = "Watch Expressions";
</span><span class="cx"> localizedStrings["Web Inspector"] = "Web Inspector";
</span><ins>+localizedStrings["WebSocket Connection Established"] = "WebSocket Connection Established";
</ins><span class="cx"> localizedStrings["Weight"] = "Weight";
</span><span class="cx"> localizedStrings["Whitespace"] = "Whitespace";
</span><span class="cx"> localizedStrings["Whitespace Characters:"] = "Whitespace Characters:";
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceControllersFrameResourceManagerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js (213665 => 213666)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js        2017-03-09 21:42:04 UTC (rev 213665)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js        2017-03-09 21:56:33 UTC (rev 213666)
</span><span class="lines">@@ -206,7 +206,7 @@
</span><span class="cx"> this._webSocketIdentifierToURL.set(requestId, url);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- webSocketWillSendHandshakeRequest(requestId, timestamp, request)
</del><ins>+ webSocketWillSendHandshakeRequest(requestId, timestamp, walltime, request)
</ins><span class="cx"> {
</span><span class="cx"> let url = this._webSocketIdentifierToURL.get(requestId);
</span><span class="cx"> console.assert(url);
</span><span class="lines">@@ -213,6 +213,12 @@
</span><span class="cx"> if (!url)
</span><span class="cx"> return;
</span><span class="cx">
</span><ins>+ // COMPATIBILITY(iOS 10.3): `walltime` did not exist in 10.3 and earlier.
+ if (!NetworkAgent.hasEventParameter("webSocketWillSendHandshakeRequest", "walltime")) {
+ request = arguments[2];
+ walltime = NaN;
+ }
+
</ins><span class="cx"> // FIXME: <webkit.org/b/168475> Web Inspector: Correctly display iframe's and worker's WebSockets
</span><span class="cx"> let frameIdentifier = WebInspector.frameResourceManager.mainFrame.id;
</span><span class="cx"> let loaderIdentifier = WebInspector.frameResourceManager.mainFrame.id;
</span><span class="lines">@@ -223,7 +229,8 @@
</span><span class="cx"> let elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
</span><span class="cx"> let initiatorSourceCodeLocation = null;
</span><span class="cx">
</span><del>- let resource = new WebInspector.WebSocketResource(url, loaderIdentifier, targetId, requestId, request.headers, requestData, elapsedTime, initiatorSourceCodeLocation);
</del><ins>+ let resource = new WebInspector.WebSocketResource(url, loaderIdentifier, targetId, requestId, request.headers, requestData, timestamp, walltime, elapsedTime, initiatorSourceCodeLocation);
+
</ins><span class="cx"> frame.addResource(resource);
</span><span class="cx">
</span><span class="cx"> this._resourceRequestIdentifierMap.set(requestId, resource);
</span><span class="lines">@@ -280,13 +287,15 @@
</span><span class="cx"> if (!resource)
</span><span class="cx"> return;
</span><span class="cx">
</span><del>- let isIncoming = !!response.mask;
</del><ins>+ // Data going from the client to the server is always masked.
+ let isOutgoing = !!response.mask;
+
</ins><span class="cx"> let data = response.payloadData;
</span><span class="cx"> let opcode = response.opcode;
</span><span class="cx">
</span><span class="cx"> let elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
</span><span class="cx">
</span><del>- resource.addFrame(data, isIncoming, opcode, timestamp, elapsedTime);
</del><ins>+ resource.addFrame(data, isOutgoing, opcode, timestamp, elapsedTime);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> markResourceRequestAsServedFromMemoryCache(requestIdentifier)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceImagesArrowUpsvg"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Images/ArrowUp.svg (0 => 213666)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Images/ArrowUp.svg         (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Images/ArrowUp.svg        2017-03-09 21:56:33 UTC (rev 213666)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+<?xml version="1.0"?>
+<!-- Copyright © 2017 Apple Inc. All rights reserved. -->
+<svg xmlns="http://www.w3.org/2000/svg" id="root" version="1.1" width="16" height="16" viewBox="0 0 16 16">
+ <path fill="none" stroke="currentColor" stroke-width="1" d="M 8 2 L 2 11 H 6 v 4 h 4 V 11 h 4 Z"/>
+</svg>
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceImagesgtkArrowUpsvg"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Images/gtk/ArrowUp.svg (0 => 213666)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Images/gtk/ArrowUp.svg         (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Images/gtk/ArrowUp.svg        2017-03-09 21:56:33 UTC (rev 213666)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+<?xml version="1.0"?>
+<!-- Licensed under the Creative Commons Attribution-Share Alike 3.0 United States License (http://creativecommons.org/licenses/by-sa/3.0/) -->
+<svg xmlns="http://www.w3.org/2000/svg" id="root" version="1.1" width="16" height="16" viewBox="0 0 16 16">
+ <path fill="currentColor" stroke-width="0" d="M 8 2 L 2 11 H 6 v 4 h 4 V 11 h 4 Z"/>
+</svg>
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceMainhtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (213665 => 213666)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Main.html        2017-03-09 21:42:04 UTC (rev 213665)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html        2017-03-09 21:56:33 UTC (rev 213666)
</span><span class="lines">@@ -202,6 +202,7 @@
</span><span class="cx"> <link rel="stylesheet" href="Views/VisualStyleTabbedPropertiesRow.css">
</span><span class="cx"> <link rel="stylesheet" href="Views/VisualStyleTimingEditor.css">
</span><span class="cx"> <link rel="stylesheet" href="Views/VisualStyleUnitSlider.css">
</span><ins>+ <link rel="stylesheet" href="Views/WebSocketContentView.css">
</ins><span class="cx">
</span><span class="cx"> <link rel="stylesheet" href="Controllers/CodeMirrorCompletionController.css">
</span><span class="cx"> <link rel="stylesheet" href="Controllers/CodeMirrorDragToAdjustNumberController.css">
</span><span class="lines">@@ -678,6 +679,7 @@
</span><span class="cx"> <script src="Views/TypeTokenView.js"></script>
</span><span class="cx"> <script src="Views/TypeTreeElement.js"></script>
</span><span class="cx"> <script src="Views/TypeTreeView.js"></script>
</span><ins>+ <script src="Views/WebSocketContentView.js"></script>
</ins><span class="cx"> <script src="Views/WorkerTreeElement.js"></script>
</span><span class="cx">
</span><span class="cx"> <script src="Views/VisualStyleDetailsPanel.js"></script>
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsWebSocketResourcejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/WebSocketResource.js (213665 => 213666)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/WebSocketResource.js        2017-03-09 21:42:04 UTC (rev 213665)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/WebSocketResource.js        2017-03-09 21:56:33 UTC (rev 213666)
</span><span class="lines">@@ -25,7 +25,7 @@
</span><span class="cx">
</span><span class="cx"> WebInspector.WebSocketResource = class WebSocketResource extends WebInspector.Resource
</span><span class="cx"> {
</span><del>- constructor(url, loaderIdentifier, targetId, requestIdentifier, requestHeaders, requestData, requestSentTimestamp, initiatorSourceCodeLocation)
</del><ins>+ constructor(url, loaderIdentifier, targetId, requestIdentifier, requestHeaders, requestData, timestamp, walltime, requestSentTimestamp, initiatorSourceCodeLocation)
</ins><span class="cx"> {
</span><span class="cx"> const type = WebInspector.Resource.Type.WebSocket;
</span><span class="cx"> const mimeType = null;
</span><span class="lines">@@ -32,6 +32,8 @@
</span><span class="cx"> const requestMethod = "GET";
</span><span class="cx"> super(url, mimeType, type, loaderIdentifier, targetId, requestIdentifier, requestMethod, requestHeaders, requestData, requestSentTimestamp, initiatorSourceCodeLocation);
</span><span class="cx">
</span><ins>+ this._timestamp = timestamp;
+ this._walltime = walltime;
</ins><span class="cx"> this._readyState = WebInspector.WebSocketResource.ReadyState.Connecting;
</span><span class="cx"> this._frames = [];
</span><span class="cx"> }
</span><span class="lines">@@ -39,6 +41,7 @@
</span><span class="cx"> // Public
</span><span class="cx">
</span><span class="cx"> get frames() { return this._frames; }
</span><ins>+ get walltime() { return this._walltime; }
</ins><span class="cx">
</span><span class="cx"> get readyState()
</span><span class="cx"> {
</span><span class="lines">@@ -56,13 +59,22 @@
</span><span class="cx"> this.dispatchEventToListeners(WebInspector.WebSocketResource.Event.ReadyStateChanged, {previousState, state});
</span><span class="cx"> }
</span><span class="cx">
</span><del>- addFrame(data, isIncoming, opcode, timestamp, elapsedTime)
</del><ins>+ addFrame(data, isOutgoing, opcode, timestamp, elapsedTime)
</ins><span class="cx"> {
</span><del>- let frame = {data, isIncoming, opcode, timestamp, elapsedTime};
</del><ins>+ let frame = {data, isOutgoing, opcode, walltime: this._walltimeForWebSocketTimestamp(timestamp)};
</ins><span class="cx"> this._frames.push(frame);
</span><span class="cx">
</span><ins>+ this.increaseSize(data.length, elapsedTime);
+
</ins><span class="cx"> this.dispatchEventToListeners(WebInspector.WebSocketResource.Event.FrameAdded, frame);
</span><span class="cx"> }
</span><ins>+
+ // Private
+
+ _walltimeForWebSocketTimestamp(timestamp)
+ {
+ return this._walltime + (timestamp - this._timestamp);
+ }
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> WebInspector.WebSocketResource.Event = {
</span><span class="lines">@@ -75,3 +87,12 @@
</span><span class="cx"> Connecting: Symbol("web-socket-ready-state-connecting"),
</span><span class="cx"> Open: Symbol("web-socket-ready-state-open"),
</span><span class="cx"> };
</span><ins>+
+WebInspector.WebSocketResource.OpCodes = {
+ ContinuationFrame: 0,
+ TextFrame: 1,
+ BinaryFrame: 2,
+ ConnectionCloseFrame: 8,
+ PingFrame: 9,
+ PongFrame: 10,
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceProtocolNetworkObserverjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/NetworkObserver.js (213665 => 213666)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Protocol/NetworkObserver.js        2017-03-09 21:42:04 UTC (rev 213665)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/NetworkObserver.js        2017-03-09 21:56:33 UTC (rev 213666)
</span><span class="lines">@@ -68,9 +68,9 @@
</span><span class="cx"> WebInspector.frameResourceManager.webSocketCreated(requestId, url);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- webSocketWillSendHandshakeRequest(requestId, timestamp, request)
</del><ins>+ webSocketWillSendHandshakeRequest(requestId, timestamp, walltime, request)
</ins><span class="cx"> {
</span><del>- WebInspector.frameResourceManager.webSocketWillSendHandshakeRequest(requestId, timestamp, request);
</del><ins>+ WebInspector.frameResourceManager.webSocketWillSendHandshakeRequest(requestId, timestamp, walltime, request);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> webSocketHandshakeResponseReceived(requestId, timestamp, response)
</span><span class="lines">@@ -88,13 +88,13 @@
</span><span class="cx"> WebInspector.frameResourceManager.webSocketFrameReceived(requestId, timestamp, response);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- webSocketFrameError(requestId, timestamp, errorMessage)
</del><ins>+ webSocketFrameSent(requestId, timestamp, response)
</ins><span class="cx"> {
</span><del>- // FIXME: Not implemented.
</del><ins>+ WebInspector.frameResourceManager.webSocketFrameSent(requestId, timestamp, response);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- webSocketFrameSent(requestId, timestamp, response)
</del><ins>+ webSocketFrameError(requestId, timestamp, errorMessage)
</ins><span class="cx"> {
</span><del>- WebInspector.frameResourceManager.webSocketFrameSent(requestId, timestamp, response);
</del><ins>+ // FIXME: Not implemented.
</ins><span class="cx"> }
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsNetworkSidebarPaneljs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkSidebarPanel.js (213665 => 213666)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/NetworkSidebarPanel.js        2017-03-09 21:42:04 UTC (rev 213665)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NetworkSidebarPanel.js        2017-03-09 21:56:33 UTC (rev 213666)
</span><span class="lines">@@ -168,13 +168,10 @@
</span><span class="cx"> closeButton.addEventListener(WebInspector.TreeElementStatusButton.Event.Clicked, this._treeElementCloseButtonClicked, this);
</span><span class="cx"> fragment.appendChild(closeButton.element);
</span><span class="cx">
</span><del>- // FIXME: <webkit.org/b/169011> Web Inspector: Show individual messages in the content pane for a WebSocket
- if (treeElement.resource.type !== WebInspector.Resource.Type.WebSocket) {
- let goToButton = new WebInspector.TreeElementStatusButton(WebInspector.createGoToArrowButton());
- goToButton[WebInspector.NetworkSidebarPanel.TreeElementSymbol] = treeElement;
- goToButton.addEventListener(WebInspector.TreeElementStatusButton.Event.Clicked, this._treeElementGoToArrowWasClicked, this);
- fragment.appendChild(goToButton.element);
- }
</del><ins>+ let goToButton = new WebInspector.TreeElementStatusButton(WebInspector.createGoToArrowButton());
+ goToButton[WebInspector.NetworkSidebarPanel.TreeElementSymbol] = treeElement;
+ goToButton.addEventListener(WebInspector.TreeElementStatusButton.Event.Clicked, this._treeElementGoToArrowWasClicked, this);
+ fragment.appendChild(goToButton.element);
</ins><span class="cx">
</span><span class="cx"> treeElement.status = fragment;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsResourceClusterContentViewjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ResourceClusterContentView.js (213665 => 213666)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ResourceClusterContentView.js        2017-03-09 21:42:04 UTC (rev 213665)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ResourceClusterContentView.js        2017-03-09 21:56:33 UTC (rev 213666)
</span><span class="lines">@@ -84,7 +84,7 @@
</span><span class="cx"> break;
</span><span class="cx">
</span><span class="cx"> case WebInspector.Resource.Type.WebSocket:
</span><del>- // FIXME: <webkit.org/b/169011> Web Inspector: Show individual messages in the content pane for a WebSocket
</del><ins>+ this._responseContentView = new WebInspector.WebSocketContentView(this._resource);
</ins><span class="cx"> break;
</span><span class="cx">
</span><span class="cx"> default:
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsWebSocketContentViewcss"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Views/WebSocketContentView.css (0 => 213666)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/WebSocketContentView.css         (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/WebSocketContentView.css        2017-03-09 21:56:33 UTC (rev 213666)
</span><span class="lines">@@ -0,0 +1,84 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+.web-socket.content-view > .data-grid {
+ height: 100%;
+}
+
+.web-socket.content-view > .data-grid table.data {
+ height: auto;
+ background-image: none;
+}
+
+.web-socket.content-view > .data-grid td.data-column,
+.web-socket.content-view .data-grid td.data-column > div {
+ height: auto;
+ white-space: pre-wrap;
+}
+
+body[dir=ltr] .web-socket.content-view > .data-grid .data-column > div {
+ padding-left: 18px;
+}
+
+body[dir=rtl] .web-socket.content-view > .data-grid .data-column > div {
+ padding-right: 18px;
+}
+
+.web-socket.content-view .icon {
+ position: absolute;
+ margin-top: -1px;
+}
+
+body[dir=ltr] .web-socket.content-view .icon {
+ left: 4px;
+ margin-right: 2px;
+}
+
+body[dir=rtl] .web-socket.content-view .icon {
+ right: 4px;
+ margin-left: 2px;
+}
+
+.web-socket.content-view .outgoing .icon {
+ background-image: url("../Images/ArrowUp.svg");
+}
+
+.web-socket.content-view .data-grid.variable-height-rows table.data tr:nth-child(odd) {
+ background-color: unset;
+}
+
+.web-socket.content-view .data-grid table.data tr.revealed {
+ border-bottom: 0.5px solid hsla(0, 0%, 0%, 0.1);
+}
+
+.web-socket.content-view .data-grid.variable-height-rows table.data tr.outgoing {
+ background-color: hsl(80, 85%, 92%);
+ color: hsl(120, 100%, 16%);
+}
+
+.web-socket.content-view .data-grid.variable-height-rows table.data tr.non-text-frame {
+ background-color: hsl(50, 100%, 90%);
+ color: hsl(3, 96%, 27%);
+}
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsWebSocketContentViewjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Views/WebSocketContentView.js (0 => 213666)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/WebSocketContentView.js         (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/WebSocketContentView.js        2017-03-09 21:56:33 UTC (rev 213666)
</span><span class="lines">@@ -0,0 +1,139 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.WebSocketContentView = class WebSocketContentView extends WebInspector.ContentView
+{
+ constructor(resource)
+ {
+ console.assert(resource instanceof WebInspector.WebSocketResource, resource);
+
+ super(resource);
+
+ this._resource = resource;
+ this._framesRendered = 0;
+
+ // COMPATIBILITY (iOS 10.3): `walltime` did not exist in 10.3 and earlier.
+ this._showTimeColumn = NetworkAgent.hasEventParameter("webSocketWillSendHandshakeRequest", "walltime");
+
+ this.element.classList.add("web-socket", "resource");
+
+ let columns = {data: {}};
+ columns.data.title = WebInspector.UIString("Data");
+ columns.data.sortable = false;
+ columns.data.icon = true;
+ columns.data.width = "85%";
+
+ if (this._showTimeColumn)
+ columns.time = {title: WebInspector.UIString("Time"), sortable: true};
+
+ this._dataGrid = new WebInspector.DataGrid(columns);
+ this._dataGrid.variableHeightRows = true;
+ this.addSubview(this._dataGrid);
+
+ this._addRow(WebInspector.UIString("WebSocket Connection Established"), this._resource.walltime, ["non-text-frame"]);
+
+ this._dataGrid.updateLayout();
+ }
+
+ // Static
+
+ static textForOpcode(opcode)
+ {
+ switch (opcode) {
+ case WebInspector.WebSocketResource.OpCodes.ContinuationFrame:
+ return WebInspector.UIString("Continuation Frame");
+ case WebInspector.WebSocketResource.OpCodes.TextFrame:
+ return WebInspector.UIString("Text Frame");
+ case WebInspector.WebSocketResource.OpCodes.BinaryFrame:
+ return WebInspector.UIString("Binary Frame");
+ case WebInspector.WebSocketResource.OpCodes.ConnectionCloseFrame:
+ return WebInspector.UIString("Connection Close Frame");
+ case WebInspector.WebSocketResource.OpCodes.PingFrame:
+ return WebInspector.UIString("Ping Frame");
+ case WebInspector.WebSocketResource.OpCodes.PongFrame:
+ return WebInspector.UIString("Pong Frame");
+ }
+ }
+
+ // Public
+
+ shown()
+ {
+ this._updateFrames();
+ this._resource.addEventListener(WebInspector.WebSocketResource.Event.FrameAdded, this._updateFrames, this);
+ }
+
+ hidden()
+ {
+ this._resource.removeEventListener(WebInspector.WebSocketResource.Event.FrameAdded, this._updateFrames, this);
+ }
+
+ addFrame(data, isOutgoing, opcode, time)
+ {
+ let nodeText;
+ if (opcode === WebInspector.WebSocketResource.OpCodes.TextFrame)
+ nodeText = data;
+ else
+ nodeText = WebInspector.WebSocketContentView.textForOpcode(opcode);
+
+ let classNames = [
+ isOutgoing ? "outgoing" : "incoming",
+ opcode === WebInspector.WebSocketResource.OpCodes.TextFrame ? "text-frame" : "non-text-frame"
+ ];
+
+ this._addRow(nodeText, time, classNames);
+ }
+
+ // Private
+
+ _updateFrames()
+ {
+ let framesLength = this._resource.frames.length;
+ for (let index = this._framesRendered; index < framesLength; index++) {
+ let frame = this._resource.frames[index];
+ let {data, isOutgoing, opcode, walltime} = frame;
+ this.addFrame(data, isOutgoing, opcode, walltime);
+ }
+ this._framesRendered = framesLength;
+ }
+
+ _addRow(data, time, classNames)
+ {
+ let node;
+ if (this._showTimeColumn)
+ node = new WebInspector.DataGridNode({data, time: this._timeStringFromTimestamp(time)});
+ else
+ node = new WebInspector.DataGridNode({data});
+
+ this._dataGrid.appendChild(node);
+
+ node.element.classList.add(...classNames);
+ }
+
+ _timeStringFromTimestamp(timestamp)
+ {
+ return new Date(timestamp * 1000).toLocaleTimeString();
+ }
+};
</ins></span></pre>
</div>
</div>
</body>
</html>