Title: [213666] trunk/Source
Revision
213666
Author
nvasil...@apple.com
Date
2017-03-09 13:56:33 -0800 (Thu, 09 Mar 2017)

Log Message

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/_javascript_Core:

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):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (213665 => 213666)


--- trunk/Source/_javascript_Core/ChangeLog	2017-03-09 21:42:04 UTC (rev 213665)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-03-09 21:56:33 UTC (rev 213666)
@@ -1,3 +1,14 @@
+2017-03-09  Nikita Vasilyev  <nvasil...@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:
+
 2017-03-09  Filip Pizlo  <fpi...@apple.com>
 
         Unreviewed, fix weak external symbol error.

Modified: trunk/Source/_javascript_Core/inspector/protocol/Network.json (213665 => 213666)


--- trunk/Source/_javascript_Core/inspector/protocol/Network.json	2017-03-09 21:42:04 UTC (rev 213665)
+++ trunk/Source/_javascript_Core/inspector/protocol/Network.json	2017-03-09 21:56:33 UTC (rev 213666)
@@ -21,6 +21,11 @@
         {
             "id": "Timestamp",
             "type": "number",
+            "description": "Elapsed seconds since frontend connected."
+        },
+        {
+            "id": "Walltime",
+            "type": "number",
             "description": "Number of seconds since epoch."
         },
         {
@@ -255,7 +260,8 @@
             "description": "Fired when WebSocket is about to initiate handshake.",
             "parameters": [
                 { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
-                { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
+                { "name": "timestamp", "$ref": "Timestamp" },
+                { "name": "walltime", "$ref": "Walltime" },
                 { "name": "request", "$ref": "WebSocketRequest", "description": "WebSocket request data." }
             ]
         },
@@ -264,7 +270,7 @@
             "description": "Fired when WebSocket handshake response becomes available.",
             "parameters": [
                 { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
-                { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
+                { "name": "timestamp", "$ref": "Timestamp" },
                 { "name": "response", "$ref": "WebSocketResponse", "description": "WebSocket response data." }
             ]
         },

Modified: trunk/Source/WebCore/ChangeLog (213665 => 213666)


--- 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)
@@ -1,3 +1,17 @@
+2017-03-09  Nikita Vasilyev  <nvasil...@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):
+
 2017-03-09  Brent Fulgham  <bfulg...@apple.com>
 
         Unreviewed build fix after r213628.

Modified: trunk/Source/WebCore/inspector/InspectorNetworkAgent.cpp (213665 => 213666)


--- 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)
@@ -557,7 +557,7 @@
     auto requestObject = Inspector::Protocol::Network::WebSocketRequest::create()
         .setHeaders(buildObjectForHeaders(request.httpHeaderFields()))
         .release();
-    m_frontendDispatcher->webSocketWillSendHandshakeRequest(IdentifiersFactory::requestId(identifier), timestamp(), WTFMove(requestObject));
+    m_frontendDispatcher->webSocketWillSendHandshakeRequest(IdentifiersFactory::requestId(identifier), timestamp(), currentTime(), WTFMove(requestObject));
 }
 
 void InspectorNetworkAgent::didReceiveWebSocketHandshakeResponse(unsigned long identifier, const ResourceResponse& response)

Modified: trunk/Source/WebInspectorUI/ChangeLog (213665 => 213666)


--- 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)
@@ -1,3 +1,69 @@
+2017-03-09  Nikita Vasilyev  <nvasil...@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):
+
 2017-03-09  Matt Baker  <mattba...@apple.com>
 
         Web Inspector: DOMTreeManager dispatches DocumentUpdated twice when the document is cleared

Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (213665 => 213666)


--- 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)
@@ -114,6 +114,7 @@
 localizedStrings["Background"] = "Background";
 localizedStrings["Basis"] = "Basis";
 localizedStrings["Bezier"] = "Bezier";
+localizedStrings["Binary Frame"] = "Binary Frame";
 localizedStrings["Blend"] = "Blend";
 localizedStrings["Block Variables"] = "Block Variables";
 localizedStrings["Blur"] = "Blur";
@@ -191,6 +192,7 @@
 localizedStrings["Condition"] = "Condition";
 localizedStrings["Conditional _expression_"] = "Conditional _expression_";
 localizedStrings["Connection"] = "Connection";
+localizedStrings["Connection Close Frame"] = "Connection Close Frame";
 localizedStrings["Console"] = "Console";
 localizedStrings["Console Evaluation"] = "Console Evaluation";
 localizedStrings["Console Evaluation %d"] = "Console Evaluation %d";
@@ -202,6 +204,7 @@
 localizedStrings["Content"] = "Content";
 localizedStrings["Content Flow"] = "Content Flow";
 localizedStrings["Content Security Policy violation of directive: %s"] = "Content Security Policy violation of directive: %s";
+localizedStrings["Continuation Frame"] = "Continuation Frame";
 localizedStrings["Continue script execution (%s or %s)"] = "Continue script execution (%s or %s)";
 localizedStrings["Continue to Here"] = "Continue to Here";
 localizedStrings["Controls"] = "Controls";
@@ -589,8 +592,10 @@
 localizedStrings["Pause Playback"] = "Pause Playback";
 localizedStrings["Pause Reason"] = "Pause Reason";
 localizedStrings["Pause script execution (%s or %s)"] = "Pause script execution (%s or %s)";
+localizedStrings["Ping Frame"] = "Ping Frame";
 localizedStrings["Play Sound"] = "Play Sound";
 localizedStrings["Polite"] = "Polite";
+localizedStrings["Pong Frame"] = "Pong Frame";
 localizedStrings["Port"] = "Port";
 localizedStrings["Position"] = "Position";
 localizedStrings["Position X"] = "Position X";
@@ -783,6 +788,7 @@
 localizedStrings["Take snapshot"] = "Take snapshot";
 localizedStrings["Template Content"] = "Template Content";
 localizedStrings["Text"] = "Text";
+localizedStrings["Text Frame"] = "Text Frame";
 localizedStrings["Text Node"] = "Text Node";
 localizedStrings["Text Only"] = "Text Only";
 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.";
@@ -854,6 +860,7 @@
 localizedStrings["Warnings"] = "Warnings";
 localizedStrings["Watch Expressions"] = "Watch Expressions";
 localizedStrings["Web Inspector"] = "Web Inspector";
+localizedStrings["WebSocket Connection Established"] = "WebSocket Connection Established";
 localizedStrings["Weight"] = "Weight";
 localizedStrings["Whitespace"] = "Whitespace";
 localizedStrings["Whitespace Characters:"] = "Whitespace Characters:";

Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js (213665 => 213666)


--- 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)
@@ -206,7 +206,7 @@
         this._webSocketIdentifierToURL.set(requestId, url);
     }
 
-    webSocketWillSendHandshakeRequest(requestId, timestamp, request)
+    webSocketWillSendHandshakeRequest(requestId, timestamp, walltime, request)
     {
         let url = ""
         console.assert(url);
@@ -213,6 +213,12 @@
         if (!url)
             return;
 
+        // COMPATIBILITY(iOS 10.3): `walltime` did not exist in 10.3 and earlier.
+        if (!NetworkAgent.hasEventParameter("webSocketWillSendHandshakeRequest", "walltime")) {
+            request = arguments[2];
+            walltime = NaN;
+        }
+
         // FIXME: <webkit.org/b/168475> Web Inspector: Correctly display iframe's and worker's WebSockets
         let frameIdentifier = WebInspector.frameResourceManager.mainFrame.id;
         let loaderIdentifier = WebInspector.frameResourceManager.mainFrame.id;
@@ -223,7 +229,8 @@
         let elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
         let initiatorSourceCodeLocation = null;
 
-        let resource = new WebInspector.WebSocketResource(url, loaderIdentifier, targetId, requestId, request.headers, requestData, elapsedTime, initiatorSourceCodeLocation);
+        let resource = new WebInspector.WebSocketResource(url, loaderIdentifier, targetId, requestId, request.headers, requestData, timestamp, walltime, elapsedTime, initiatorSourceCodeLocation);
+
         frame.addResource(resource);
 
         this._resourceRequestIdentifierMap.set(requestId, resource);
@@ -280,13 +287,15 @@
         if (!resource)
             return;
 
-        let isIncoming = !!response.mask;
+        // Data going from the client to the server is always masked.
+        let isOutgoing = !!response.mask;
+
         let data = ""
         let opcode = response.opcode;
 
         let elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
 
-        resource.addFrame(data, isIncoming, opcode, timestamp, elapsedTime);
+        resource.addFrame(data, isOutgoing, opcode, timestamp, elapsedTime);
     }
 
     markResourceRequestAsServedFromMemoryCache(requestIdentifier)

Added: trunk/Source/WebInspectorUI/UserInterface/Images/ArrowUp.svg (0 => 213666)


--- 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)
@@ -0,0 +1,5 @@
+<?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>

Added: trunk/Source/WebInspectorUI/UserInterface/Images/gtk/ArrowUp.svg (0 => 213666)


--- 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)
@@ -0,0 +1,5 @@
+<?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>

Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (213665 => 213666)


--- 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)
@@ -202,6 +202,7 @@
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
+    <link rel="stylesheet" href=""
 
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
@@ -678,6 +679,7 @@
     <script src=""
     <script src=""
     <script src=""
+    <script src=""
     <script src=""
 
     <script src=""

Modified: trunk/Source/WebInspectorUI/UserInterface/Models/WebSocketResource.js (213665 => 213666)


--- 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)
@@ -25,7 +25,7 @@
 
 WebInspector.WebSocketResource = class WebSocketResource extends WebInspector.Resource
 {
-    constructor(url, loaderIdentifier, targetId, requestIdentifier, requestHeaders, requestData, requestSentTimestamp, initiatorSourceCodeLocation)
+    constructor(url, loaderIdentifier, targetId, requestIdentifier, requestHeaders, requestData, timestamp, walltime, requestSentTimestamp, initiatorSourceCodeLocation)
     {
         const type = WebInspector.Resource.Type.WebSocket;
         const mimeType = null;
@@ -32,6 +32,8 @@
         const requestMethod = "GET";
         super(url, mimeType, type, loaderIdentifier, targetId, requestIdentifier, requestMethod, requestHeaders, requestData, requestSentTimestamp, initiatorSourceCodeLocation);
 
+        this._timestamp = timestamp;
+        this._walltime = walltime;
         this._readyState = WebInspector.WebSocketResource.ReadyState.Connecting;
         this._frames = [];
     }
@@ -39,6 +41,7 @@
     // Public
 
     get frames() { return this._frames; }
+    get walltime() { return this._walltime; }
 
     get readyState()
     {
@@ -56,13 +59,22 @@
         this.dispatchEventToListeners(WebInspector.WebSocketResource.Event.ReadyStateChanged, {previousState, state});
     }
 
-    addFrame(data, isIncoming, opcode, timestamp, elapsedTime)
+    addFrame(data, isOutgoing, opcode, timestamp, elapsedTime)
     {
-        let frame = {data, isIncoming, opcode, timestamp, elapsedTime};
+        let frame = {data, isOutgoing, opcode, walltime: this._walltimeForWebSocketTimestamp(timestamp)};
         this._frames.push(frame);
 
+        this.increaseSize(data.length, elapsedTime);
+
         this.dispatchEventToListeners(WebInspector.WebSocketResource.Event.FrameAdded, frame);
     }
+
+    // Private
+
+    _walltimeForWebSocketTimestamp(timestamp)
+    {
+        return this._walltime + (timestamp - this._timestamp);
+    }
 };
 
 WebInspector.WebSocketResource.Event = {
@@ -75,3 +87,12 @@
     Connecting: Symbol("web-socket-ready-state-connecting"),
     Open: Symbol("web-socket-ready-state-open"),
 };
+
+WebInspector.WebSocketResource.OpCodes = {
+    ContinuationFrame: 0,
+    TextFrame: 1,
+    BinaryFrame: 2,
+    ConnectionCloseFrame: 8,
+    PingFrame: 9,
+    PongFrame: 10,
+};

Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/NetworkObserver.js (213665 => 213666)


--- 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)
@@ -68,9 +68,9 @@
         WebInspector.frameResourceManager.webSocketCreated(requestId, url);
     }
 
-    webSocketWillSendHandshakeRequest(requestId, timestamp, request)
+    webSocketWillSendHandshakeRequest(requestId, timestamp, walltime, request)
     {
-        WebInspector.frameResourceManager.webSocketWillSendHandshakeRequest(requestId, timestamp, request);
+        WebInspector.frameResourceManager.webSocketWillSendHandshakeRequest(requestId, timestamp, walltime, request);
     }
 
     webSocketHandshakeResponseReceived(requestId, timestamp, response)
@@ -88,13 +88,13 @@
         WebInspector.frameResourceManager.webSocketFrameReceived(requestId, timestamp, response);
     }
 
-    webSocketFrameError(requestId, timestamp, errorMessage)
+    webSocketFrameSent(requestId, timestamp, response)
     {
-        // FIXME: Not implemented.
+        WebInspector.frameResourceManager.webSocketFrameSent(requestId, timestamp, response);
     }
 
-    webSocketFrameSent(requestId, timestamp, response)
+    webSocketFrameError(requestId, timestamp, errorMessage)
     {
-        WebInspector.frameResourceManager.webSocketFrameSent(requestId, timestamp, response);
+        // FIXME: Not implemented.
     }
 };

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkSidebarPanel.js (213665 => 213666)


--- 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)
@@ -168,13 +168,10 @@
         closeButton.addEventListener(WebInspector.TreeElementStatusButton.Event.Clicked, this._treeElementCloseButtonClicked, this);
         fragment.appendChild(closeButton.element);
 
-        // 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);
-        }
+        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);
 
         treeElement.status = fragment;
     }

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ResourceClusterContentView.js (213665 => 213666)


--- 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)
@@ -84,7 +84,7 @@
             break;
 
         case WebInspector.Resource.Type.WebSocket:
-            // FIXME: <webkit.org/b/169011> Web Inspector: Show individual messages in the content pane for a WebSocket
+            this._responseContentView = new WebInspector.WebSocketContentView(this._resource);
             break;
 
         default:

Added: trunk/Source/WebInspectorUI/UserInterface/Views/WebSocketContentView.css (0 => 213666)


--- 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)
@@ -0,0 +1,84 @@
+/*
+ * 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%);
+}

Added: trunk/Source/WebInspectorUI/UserInterface/Views/WebSocketContentView.js (0 => 213666)


--- 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)
@@ -0,0 +1,139 @@
+/*
+ * 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();
+    }
+};
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to