| Differences between
and this patch
- a/Source/JavaScriptCore/ChangeLog +11 lines
Lines 1-3 a/Source/JavaScriptCore/ChangeLog_sec1
1
2017-03-09  Nikita Vasilyev  <nvasilyev@apple.com>
2
3
        Web Inspector: Show individual messages in the content pane for a WebSocket
4
        https://bugs.webkit.org/show_bug.cgi?id=169011
5
6
        Reviewed by Joseph Pecoraro.
7
8
        Add walltime parameter and correct the description of Timestamp type.
9
10
        * inspector/protocol/Network.json:
11
1
2017-03-07  Dean Jackson  <dino@apple.com>
12
2017-03-07  Dean Jackson  <dino@apple.com>
2
13
3
        Some platforms won't be able to create a GPUDevice
14
        Some platforms won't be able to create a GPUDevice
- a/Source/JavaScriptCore/inspector/protocol/Network.json -2 / +8 lines
Lines 21-26 a/Source/JavaScriptCore/inspector/protocol/Network.json_sec1
21
        {
21
        {
22
            "id": "Timestamp",
22
            "id": "Timestamp",
23
            "type": "number",
23
            "type": "number",
24
            "description": "Elapsed seconds since frontend connected."
25
        },
26
        {
27
            "id": "Walltime",
28
            "type": "number",
24
            "description": "Number of seconds since epoch."
29
            "description": "Number of seconds since epoch."
25
        },
30
        },
26
        {
31
        {
Lines 255-261 a/Source/JavaScriptCore/inspector/protocol/Network.json_sec2
255
            "description": "Fired when WebSocket is about to initiate handshake.",
260
            "description": "Fired when WebSocket is about to initiate handshake.",
256
            "parameters": [
261
            "parameters": [
257
                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
262
                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
258
                { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
263
                { "name": "timestamp", "$ref": "Timestamp" },
264
                { "name": "walltime", "$ref": "Walltime" },
259
                { "name": "request", "$ref": "WebSocketRequest", "description": "WebSocket request data." }
265
                { "name": "request", "$ref": "WebSocketRequest", "description": "WebSocket request data." }
260
            ]
266
            ]
261
        },
267
        },
Lines 264-270 a/Source/JavaScriptCore/inspector/protocol/Network.json_sec3
264
            "description": "Fired when WebSocket handshake response becomes available.",
270
            "description": "Fired when WebSocket handshake response becomes available.",
265
            "parameters": [
271
            "parameters": [
266
                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
272
                { "name": "requestId", "$ref": "RequestId", "description": "Request identifier." },
267
                { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp." },
273
                { "name": "timestamp", "$ref": "Timestamp" },
268
                { "name": "response", "$ref": "WebSocketResponse", "description": "WebSocket response data." }
274
                { "name": "response", "$ref": "WebSocketResponse", "description": "WebSocket response data." }
269
            ]
275
            ]
270
        },
276
        },
- a/Source/WebCore/ChangeLog +14 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2017-03-09  Nikita Vasilyev  <nvasilyev@apple.com>
2
3
        Web Inspector: Show individual messages in the content pane for a WebSocket
4
        https://bugs.webkit.org/show_bug.cgi?id=169011
5
6
        Reviewed by Joseph Pecoraro.
7
8
        Add walltime parameter.
9
10
        No new tests. Tests will be added in a follow up patch.
11
12
        * inspector/InspectorNetworkAgent.cpp:
13
        (WebCore::InspectorNetworkAgent::willSendWebSocketHandshakeRequest):
14
1
2017-03-07  Jiewen Tan  <jiewen_tan@apple.com>
15
2017-03-07  Jiewen Tan  <jiewen_tan@apple.com>
2
16
3
        [WebCrypto] Implement ECDH ImportKey/ExportKey operations
17
        [WebCrypto] Implement ECDH ImportKey/ExportKey operations
- a/Source/WebCore/inspector/InspectorNetworkAgent.cpp -1 / +1 lines
Lines 541-547 void InspectorNetworkAgent::willSendWebSocketHandshakeRequest(unsigned long iden a/Source/WebCore/inspector/InspectorNetworkAgent.cpp_sec1
541
    auto requestObject = Inspector::Protocol::Network::WebSocketRequest::create()
541
    auto requestObject = Inspector::Protocol::Network::WebSocketRequest::create()
542
        .setHeaders(buildObjectForHeaders(request.httpHeaderFields()))
542
        .setHeaders(buildObjectForHeaders(request.httpHeaderFields()))
543
        .release();
543
        .release();
544
    m_frontendDispatcher->webSocketWillSendHandshakeRequest(IdentifiersFactory::requestId(identifier), timestamp(), WTFMove(requestObject));
544
    m_frontendDispatcher->webSocketWillSendHandshakeRequest(IdentifiersFactory::requestId(identifier), timestamp(), currentTime(), WTFMove(requestObject));
545
}
545
}
546
546
547
void InspectorNetworkAgent::didReceiveWebSocketHandshakeResponse(unsigned long identifier, const ResourceResponse& response)
547
void InspectorNetworkAgent::didReceiveWebSocketHandshakeResponse(unsigned long identifier, const ResourceResponse& response)
- a/Source/WebInspectorUI/ChangeLog +66 lines
Lines 1-3 a/Source/WebInspectorUI/ChangeLog_sec1
1
2017-03-09  Nikita Vasilyev  <nvasilyev@apple.com>
2
3
        Web Inspector: Show individual messages in the content pane for a WebSocket
4
        https://bugs.webkit.org/show_bug.cgi?id=169011
5
6
        Reviewed by Joseph Pecoraro.
7
8
        When selecting a Web Socket in Network panel or Resources, display a table
9
        of all messages that have been sent and received.
10
11
        * Localizations/en.lproj/localizedStrings.js:
12
        * UserInterface/Controllers/FrameResourceManager.js:
13
        (WebInspector.FrameResourceManager.prototype.webSocketWillSendHandshakeRequest):
14
        Add a walltime parameter.
15
16
        (WebInspector.FrameResourceManager.prototype._webSocketFrameReceivedOrSent):
17
        Fix a bug: masked messages are outgoing, not incoming.
18
19
        * UserInterface/Images/ArrowUp.svg: Added.
20
        * UserInterface/Images/gtk/ArrowUp.svg: Added.
21
        Add an icon for outgoing messages.
22
23
        * UserInterface/Main.html:
24
        * UserInterface/Models/WebSocketResource.js:
25
        (WebInspector.WebSocketResource):
26
        (WebInspector.WebSocketResource.prototype.get walltime):
27
        (WebInspector.WebSocketResource.prototype.addFrame):
28
        (WebInspector.WebSocketResource.prototype._walltimeForWebSocketTimestamp):
29
        * UserInterface/Protocol/NetworkObserver.js:
30
        (WebInspector.NetworkObserver.prototype.webSocketWillSendHandshakeRequest):
31
        (WebInspector.NetworkObserver.prototype.webSocketFrameSent):
32
        (WebInspector.NetworkObserver.prototype.webSocketFrameError):
33
        (WebInspector.NetworkObserver):
34
        * UserInterface/Views/NetworkSidebarPanel.js:
35
        (WebInspector.NetworkSidebarPanel.prototype.treeElementAddedOrChanged):
36
        * UserInterface/Views/ResourceClusterContentView.js:
37
        (WebInspector.ResourceClusterContentView.prototype.get responseContentView):
38
        * UserInterface/Views/WebSocketContentView.css: Added.
39
        (.web-socket.content-view > .data-grid):
40
        (.web-socket.content-view > .data-grid table.data):
41
        (.web-socket.content-view > .data-grid td.data-column,):
42
        (body[dir=ltr] .web-socket.content-view > .data-grid .data-column > div):
43
        (body[dir=rtl] .web-socket.content-view > .data-grid .data-column > div):
44
        (.web-socket.content-view .icon):
45
        (body[dir=ltr] .web-socket.content-view .icon):
46
        (body[dir=rtl] .web-socket.content-view .icon):
47
        (.web-socket.content-view .outgoing .icon):
48
        (.web-socket.content-view .data-grid.variable-height-rows table.data tr:nth-child(odd)):
49
        (.web-socket.content-view .data-grid table.data tr.revealed):
50
        (.web-socket.content-view .data-grid.variable-height-rows table.data tr.outgoing):
51
        (.web-socket.content-view .data-grid.variable-height-rows table.data tr.non-text-frame):
52
53
        * UserInterface/Views/WebSocketContentView.js: Added.
54
        (WebInspector.WebSocketContentView):
55
        Only show Time column when walltime is available.
56
57
        (WebInspector.WebSocketContentView.textForOpcode):
58
        (WebInspector.WebSocketContentView.prototype.shown):
59
        (WebInspector.WebSocketContentView.prototype.hidden):
60
        (WebInspector.WebSocketContentView.prototype.addFrame):
61
        (WebInspector.WebSocketContentView.prototype._updateFrames):
62
        Only render frames that haven't been rendered yet.
63
64
        (WebInspector.WebSocketContentView.prototype._addRow):
65
        (WebInspector.WebSocketContentView.prototype._timeStringFromTimestamp):
66
1
2017-03-07  Chris Dumez  <cdumez@apple.com>
67
2017-03-07  Chris Dumez  <cdumez@apple.com>
2
68
3
        Drop non-standard MessageEvent.webkitInitMessageEvent()
69
        Drop non-standard MessageEvent.webkitInitMessageEvent()
- a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js +7 lines
Lines 110-115 localizedStrings["Back (%s)"] = "Back (%s)"; a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js_sec1
110
localizedStrings["Background"] = "Background";
110
localizedStrings["Background"] = "Background";
111
localizedStrings["Basis"] = "Basis";
111
localizedStrings["Basis"] = "Basis";
112
localizedStrings["Bezier"] = "Bezier";
112
localizedStrings["Bezier"] = "Bezier";
113
localizedStrings["Binary Frame"] = "Binary Frame";
113
localizedStrings["Blend"] = "Blend";
114
localizedStrings["Blend"] = "Blend";
114
localizedStrings["Block Variables"] = "Block Variables";
115
localizedStrings["Block Variables"] = "Block Variables";
115
localizedStrings["Blur"] = "Blur";
116
localizedStrings["Blur"] = "Blur";
Lines 186-191 localizedStrings["Compression"] = "Compression"; a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js_sec2
186
localizedStrings["Condition"] = "Condition";
187
localizedStrings["Condition"] = "Condition";
187
localizedStrings["Conditional expression"] = "Conditional expression";
188
localizedStrings["Conditional expression"] = "Conditional expression";
188
localizedStrings["Connection"] = "Connection";
189
localizedStrings["Connection"] = "Connection";
190
localizedStrings["Connection Close Frame"] = "Connection Close Frame";
189
localizedStrings["Console"] = "Console";
191
localizedStrings["Console"] = "Console";
190
localizedStrings["Console Evaluation"] = "Console Evaluation";
192
localizedStrings["Console Evaluation"] = "Console Evaluation";
191
localizedStrings["Console Evaluation %d"] = "Console Evaluation %d";
193
localizedStrings["Console Evaluation %d"] = "Console Evaluation %d";
Lines 197-202 localizedStrings["Container Regions"] = "Container Regions"; a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js_sec3
197
localizedStrings["Content"] = "Content";
199
localizedStrings["Content"] = "Content";
198
localizedStrings["Content Flow"] = "Content Flow";
200
localizedStrings["Content Flow"] = "Content Flow";
199
localizedStrings["Content Security Policy violation of directive: %s"] = "Content Security Policy violation of directive: %s";
201
localizedStrings["Content Security Policy violation of directive: %s"] = "Content Security Policy violation of directive: %s";
202
localizedStrings["Continuation Frame"] = "Continuation Frame";
200
localizedStrings["Continue script execution (%s or %s)"] = "Continue script execution (%s or %s)";
203
localizedStrings["Continue script execution (%s or %s)"] = "Continue script execution (%s or %s)";
201
localizedStrings["Continue to Here"] = "Continue to Here";
204
localizedStrings["Continue to Here"] = "Continue to Here";
202
localizedStrings["Controls"] = "Controls";
205
localizedStrings["Controls"] = "Controls";
Lines 581-588 localizedStrings["Path"] = "Path"; a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js_sec4
581
localizedStrings["Pause Playback"] = "Pause Playback";
584
localizedStrings["Pause Playback"] = "Pause Playback";
582
localizedStrings["Pause Reason"] = "Pause Reason";
585
localizedStrings["Pause Reason"] = "Pause Reason";
583
localizedStrings["Pause script execution (%s or %s)"] = "Pause script execution (%s or %s)";
586
localizedStrings["Pause script execution (%s or %s)"] = "Pause script execution (%s or %s)";
587
localizedStrings["Ping Frame"] = "Ping Frame";
584
localizedStrings["Play Sound"] = "Play Sound";
588
localizedStrings["Play Sound"] = "Play Sound";
585
localizedStrings["Polite"] = "Polite";
589
localizedStrings["Polite"] = "Polite";
590
localizedStrings["Pong Frame"] = "Pong Frame";
586
localizedStrings["Port"] = "Port";
591
localizedStrings["Port"] = "Port";
587
localizedStrings["Position"] = "Position";
592
localizedStrings["Position"] = "Position";
588
localizedStrings["Position X"] = "Position X";
593
localizedStrings["Position X"] = "Position X";
Lines 771-776 localizedStrings["Tabs"] = "Tabs"; a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js_sec5
771
localizedStrings["Take snapshot"] = "Take snapshot";
776
localizedStrings["Take snapshot"] = "Take snapshot";
772
localizedStrings["Template Content"] = "Template Content";
777
localizedStrings["Template Content"] = "Template Content";
773
localizedStrings["Text"] = "Text";
778
localizedStrings["Text"] = "Text";
779
localizedStrings["Text Frame"] = "Text Frame";
774
localizedStrings["Text Node"] = "Text Node";
780
localizedStrings["Text Node"] = "Text Node";
775
localizedStrings["Text Only"] = "Text Only";
781
localizedStrings["Text Only"] = "Text Only";
776
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.";
782
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.";
Lines 841-846 localizedStrings["Warning: "] = "Warning: "; a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js_sec6
841
localizedStrings["Warnings"] = "Warnings";
847
localizedStrings["Warnings"] = "Warnings";
842
localizedStrings["Watch Expressions"] = "Watch Expressions";
848
localizedStrings["Watch Expressions"] = "Watch Expressions";
843
localizedStrings["Web Inspector"] = "Web Inspector";
849
localizedStrings["Web Inspector"] = "Web Inspector";
850
localizedStrings["WebSocket Connection Established"] = "WebSocket Connection Established";
844
localizedStrings["Weight"] = "Weight";
851
localizedStrings["Weight"] = "Weight";
845
localizedStrings["Whitespace"] = "Whitespace";
852
localizedStrings["Whitespace"] = "Whitespace";
846
localizedStrings["Whitespace Characters:"] = "Whitespace Characters:";
853
localizedStrings["Whitespace Characters:"] = "Whitespace Characters:";
- a/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js -4 / +13 lines
Lines 206-218 WebInspector.FrameResourceManager = class FrameResourceManager extends WebInspec a/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js_sec1
206
        this._webSocketIdentifierToURL.set(requestId, url);
206
        this._webSocketIdentifierToURL.set(requestId, url);
207
    }
207
    }
208
208
209
    webSocketWillSendHandshakeRequest(requestId, timestamp, request)
209
    webSocketWillSendHandshakeRequest(requestId, timestamp, walltime, request)
210
    {
210
    {
211
        let url = this._webSocketIdentifierToURL.get(requestId);
211
        let url = this._webSocketIdentifierToURL.get(requestId);
212
        console.assert(url);
212
        console.assert(url);
213
        if (!url)
213
        if (!url)
214
            return;
214
            return;
215
215
216
        // COMPATIBILITY(iOS 10.3): `walltime` did not exist in 10.3 and earlier.
217
        if (!NetworkAgent.hasEventParameter("webSocketWillSendHandshakeRequest", "walltime")) {
218
            request = arguments[2];
219
            walltime = NaN;
220
        }
221
216
        // FIXME: <webkit.org/b/168475> Web Inspector: Correctly display iframe's and worker's WebSockets
222
        // FIXME: <webkit.org/b/168475> Web Inspector: Correctly display iframe's and worker's WebSockets
217
        let frameIdentifier = WebInspector.frameResourceManager.mainFrame.id;
223
        let frameIdentifier = WebInspector.frameResourceManager.mainFrame.id;
218
        let loaderIdentifier = WebInspector.frameResourceManager.mainFrame.id;
224
        let loaderIdentifier = WebInspector.frameResourceManager.mainFrame.id;
Lines 223-229 WebInspector.FrameResourceManager = class FrameResourceManager extends WebInspec a/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js_sec2
223
        let elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
229
        let elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
224
        let initiatorSourceCodeLocation = null;
230
        let initiatorSourceCodeLocation = null;
225
231
226
        let resource = new WebInspector.WebSocketResource(url, loaderIdentifier, targetId, requestId, request.headers, requestData, elapsedTime, initiatorSourceCodeLocation);
232
        let resource = new WebInspector.WebSocketResource(url, loaderIdentifier, targetId, requestId, request.headers, requestData, timestamp, walltime, elapsedTime, initiatorSourceCodeLocation);
233
227
        frame.addResource(resource);
234
        frame.addResource(resource);
228
235
229
        this._resourceRequestIdentifierMap.set(requestId, resource);
236
        this._resourceRequestIdentifierMap.set(requestId, resource);
Lines 280-292 WebInspector.FrameResourceManager = class FrameResourceManager extends WebInspec a/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js_sec3
280
        if (!resource)
287
        if (!resource)
281
            return;
288
            return;
282
289
283
        let isIncoming = !!response.mask;
290
        // Data going from the client to the server is always masked.
291
        let isOutgoing = !!response.mask;
292
284
        let data = response.payloadData;
293
        let data = response.payloadData;
285
        let opcode = response.opcode;
294
        let opcode = response.opcode;
286
295
287
        let elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
296
        let elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
288
297
289
        resource.addFrame(data, isIncoming, opcode, timestamp, elapsedTime);
298
        resource.addFrame(data, isOutgoing, opcode, timestamp, elapsedTime);
290
    }
299
    }
291
300
292
    markResourceRequestAsServedFromMemoryCache(requestIdentifier)
301
    markResourceRequestAsServedFromMemoryCache(requestIdentifier)
- a/Source/WebInspectorUI/UserInterface/Images/ArrowUp.svg +5 lines
Line 0 a/Source/WebInspectorUI/UserInterface/Images/ArrowUp.svg_sec1
1
<?xml version="1.0"?>
2
<!-- Copyright © 2017 Apple Inc. All rights reserved. -->
3
<svg xmlns="http://www.w3.org/2000/svg" id="root" version="1.1" width="16" height="16" viewBox="0 0 16 16">
4
    <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"/>
5
</svg>
- a/Source/WebInspectorUI/UserInterface/Images/gtk/ArrowUp.svg +5 lines
Line 0 a/Source/WebInspectorUI/UserInterface/Images/gtk/ArrowUp.svg_sec1
1
<?xml version="1.0"?>
2
<!-- Licensed under the Creative Commons Attribution-Share Alike 3.0 United States License (http://creativecommons.org/licenses/by-sa/3.0/) -->
3
<svg xmlns="http://www.w3.org/2000/svg" id="root" version="1.1" width="16" height="16" viewBox="0 0 16 16">
4
    <path fill="currentColor" stroke-width="0" d="M 8 2 L 2 11 H 6 v 4 h 4 V 11 h 4 Z"/>
5
</svg>
- a/Source/WebInspectorUI/UserInterface/Main.html +2 lines
Lines 201-206 a/Source/WebInspectorUI/UserInterface/Main.html_sec1
201
    <link rel="stylesheet" href="Views/VisualStyleTabbedPropertiesRow.css">
201
    <link rel="stylesheet" href="Views/VisualStyleTabbedPropertiesRow.css">
202
    <link rel="stylesheet" href="Views/VisualStyleTimingEditor.css">
202
    <link rel="stylesheet" href="Views/VisualStyleTimingEditor.css">
203
    <link rel="stylesheet" href="Views/VisualStyleUnitSlider.css">
203
    <link rel="stylesheet" href="Views/VisualStyleUnitSlider.css">
204
    <link rel="stylesheet" href="Views/WebSocketContentView.css">
204
205
205
    <link rel="stylesheet" href="Controllers/CodeMirrorCompletionController.css">
206
    <link rel="stylesheet" href="Controllers/CodeMirrorCompletionController.css">
206
    <link rel="stylesheet" href="Controllers/CodeMirrorDragToAdjustNumberController.css">
207
    <link rel="stylesheet" href="Controllers/CodeMirrorDragToAdjustNumberController.css">
Lines 674-679 a/Source/WebInspectorUI/UserInterface/Main.html_sec2
674
    <script src="Views/TypeTokenView.js"></script>
675
    <script src="Views/TypeTokenView.js"></script>
675
    <script src="Views/TypeTreeElement.js"></script>
676
    <script src="Views/TypeTreeElement.js"></script>
676
    <script src="Views/TypeTreeView.js"></script>
677
    <script src="Views/TypeTreeView.js"></script>
678
    <script src="Views/WebSocketContentView.js"></script>
677
    <script src="Views/WorkerTreeElement.js"></script>
679
    <script src="Views/WorkerTreeElement.js"></script>
678
680
679
    <script src="Views/VisualStyleDetailsPanel.js"></script>
681
    <script src="Views/VisualStyleDetailsPanel.js"></script>
- a/Source/WebInspectorUI/UserInterface/Models/WebSocketResource.js -3 / +24 lines
Lines 25-37 a/Source/WebInspectorUI/UserInterface/Models/WebSocketResource.js_sec1
25
25
26
WebInspector.WebSocketResource = class WebSocketResource extends WebInspector.Resource
26
WebInspector.WebSocketResource = class WebSocketResource extends WebInspector.Resource
27
{
27
{
28
    constructor(url, loaderIdentifier, targetId, requestIdentifier, requestHeaders, requestData, requestSentTimestamp, initiatorSourceCodeLocation)
28
    constructor(url, loaderIdentifier, targetId, requestIdentifier, requestHeaders, requestData, timestamp, walltime, requestSentTimestamp, initiatorSourceCodeLocation)
29
    {
29
    {
30
        const type = WebInspector.Resource.Type.WebSocket;
30
        const type = WebInspector.Resource.Type.WebSocket;
31
        const mimeType = null;
31
        const mimeType = null;
32
        const requestMethod = "GET";
32
        const requestMethod = "GET";
33
        super(url, mimeType, type, loaderIdentifier, targetId, requestIdentifier, requestMethod, requestHeaders, requestData, requestSentTimestamp, initiatorSourceCodeLocation);
33
        super(url, mimeType, type, loaderIdentifier, targetId, requestIdentifier, requestMethod, requestHeaders, requestData, requestSentTimestamp, initiatorSourceCodeLocation);
34
34
35
        this._timestamp = timestamp;
36
        this._walltime = walltime;
35
        this._readyState = WebInspector.WebSocketResource.ReadyState.Connecting;
37
        this._readyState = WebInspector.WebSocketResource.ReadyState.Connecting;
36
        this._frames = [];
38
        this._frames = [];
37
    }
39
    }
Lines 39-44 WebInspector.WebSocketResource = class WebSocketResource extends WebInspector.Re a/Source/WebInspectorUI/UserInterface/Models/WebSocketResource.js_sec2
39
    // Public
41
    // Public
40
42
41
    get frames() { return this._frames; }
43
    get frames() { return this._frames; }
44
    get walltime() { return this._walltime; }
42
45
43
    get readyState()
46
    get readyState()
44
    {
47
    {
Lines 56-68 WebInspector.WebSocketResource = class WebSocketResource extends WebInspector.Re a/Source/WebInspectorUI/UserInterface/Models/WebSocketResource.js_sec3
56
        this.dispatchEventToListeners(WebInspector.WebSocketResource.Event.ReadyStateChanged, {previousState, state});
59
        this.dispatchEventToListeners(WebInspector.WebSocketResource.Event.ReadyStateChanged, {previousState, state});
57
    }
60
    }
58
61
59
    addFrame(data, isIncoming, opcode, timestamp, elapsedTime)
62
    addFrame(data, isOutgoing, opcode, timestamp, elapsedTime)
60
    {
63
    {
61
        let frame = {data, isIncoming, opcode, timestamp, elapsedTime};
64
        let frame = {data, isOutgoing, opcode, walltime: this._walltimeForWebSocketTimestamp(timestamp)};
62
        this._frames.push(frame);
65
        this._frames.push(frame);
63
66
67
        this.increaseSize(data.length, elapsedTime);
68
64
        this.dispatchEventToListeners(WebInspector.WebSocketResource.Event.FrameAdded, frame);
69
        this.dispatchEventToListeners(WebInspector.WebSocketResource.Event.FrameAdded, frame);
65
    }
70
    }
71
72
    // Private
73
74
    _walltimeForWebSocketTimestamp(timestamp)
75
    {
76
        return this._walltime + (timestamp - this._timestamp);
77
    }
66
};
78
};
67
79
68
WebInspector.WebSocketResource.Event = {
80
WebInspector.WebSocketResource.Event = {
Lines 75-77 WebInspector.WebSocketResource.ReadyState = { a/Source/WebInspectorUI/UserInterface/Models/WebSocketResource.js_sec4
75
    Connecting: Symbol("web-socket-ready-state-connecting"),
87
    Connecting: Symbol("web-socket-ready-state-connecting"),
76
    Open: Symbol("web-socket-ready-state-open"),
88
    Open: Symbol("web-socket-ready-state-open"),
77
};
89
};
90
91
WebInspector.WebSocketResource.OpCodes = {
92
    ContinuationFrame: 0,
93
    TextFrame: 1,
94
    BinaryFrame: 2,
95
    ConnectionCloseFrame: 8,
96
    PingFrame: 9,
97
    PongFrame: 10,
98
};
- a/Source/WebInspectorUI/UserInterface/Protocol/NetworkObserver.js -6 / +6 lines
Lines 67-75 WebInspector.NetworkObserver = class NetworkObserver a/Source/WebInspectorUI/UserInterface/Protocol/NetworkObserver.js_sec1
67
        WebInspector.frameResourceManager.webSocketCreated(requestId, url);
67
        WebInspector.frameResourceManager.webSocketCreated(requestId, url);
68
    }
68
    }
69
69
70
    webSocketWillSendHandshakeRequest(requestId, timestamp, request)
70
    webSocketWillSendHandshakeRequest(requestId, timestamp, walltime, request)
71
    {
71
    {
72
        WebInspector.frameResourceManager.webSocketWillSendHandshakeRequest(requestId, timestamp, request);
72
        WebInspector.frameResourceManager.webSocketWillSendHandshakeRequest(requestId, timestamp, walltime, request);
73
    }
73
    }
74
74
75
    webSocketHandshakeResponseReceived(requestId, timestamp, response)
75
    webSocketHandshakeResponseReceived(requestId, timestamp, response)
Lines 87-99 WebInspector.NetworkObserver = class NetworkObserver a/Source/WebInspectorUI/UserInterface/Protocol/NetworkObserver.js_sec2
87
        WebInspector.frameResourceManager.webSocketFrameReceived(requestId, timestamp, response);
87
        WebInspector.frameResourceManager.webSocketFrameReceived(requestId, timestamp, response);
88
    }
88
    }
89
89
90
    webSocketFrameError(requestId, timestamp, errorMessage)
90
    webSocketFrameSent(requestId, timestamp, response)
91
    {
91
    {
92
        // FIXME: Not implemented.
92
        WebInspector.frameResourceManager.webSocketFrameSent(requestId, timestamp, response);
93
    }
93
    }
94
94
95
    webSocketFrameSent(requestId, timestamp, response)
95
    webSocketFrameError(requestId, timestamp, errorMessage)
96
    {
96
    {
97
        WebInspector.frameResourceManager.webSocketFrameSent(requestId, timestamp, response);
97
        // FIXME: Not implemented.
98
    }
98
    }
99
};
99
};
- a/Source/WebInspectorUI/UserInterface/Views/NetworkSidebarPanel.js -7 / +4 lines
Lines 168-180 WebInspector.NetworkSidebarPanel = class NetworkSidebarPanel extends WebInspecto a/Source/WebInspectorUI/UserInterface/Views/NetworkSidebarPanel.js_sec1
168
        closeButton.addEventListener(WebInspector.TreeElementStatusButton.Event.Clicked, this._treeElementCloseButtonClicked, this);
168
        closeButton.addEventListener(WebInspector.TreeElementStatusButton.Event.Clicked, this._treeElementCloseButtonClicked, this);
169
        fragment.appendChild(closeButton.element);
169
        fragment.appendChild(closeButton.element);
170
170
171
        // FIXME: <webkit.org/b/169011> Web Inspector: Show individual messages in the content pane for a WebSocket
171
        let goToButton = new WebInspector.TreeElementStatusButton(WebInspector.createGoToArrowButton());
172
        if (treeElement.resource.type !== WebInspector.Resource.Type.WebSocket) {
172
        goToButton[WebInspector.NetworkSidebarPanel.TreeElementSymbol] = treeElement;
173
            let goToButton = new WebInspector.TreeElementStatusButton(WebInspector.createGoToArrowButton());
173
        goToButton.addEventListener(WebInspector.TreeElementStatusButton.Event.Clicked, this._treeElementGoToArrowWasClicked, this);
174
            goToButton[WebInspector.NetworkSidebarPanel.TreeElementSymbol] = treeElement;
174
        fragment.appendChild(goToButton.element);
175
            goToButton.addEventListener(WebInspector.TreeElementStatusButton.Event.Clicked, this._treeElementGoToArrowWasClicked, this);
176
            fragment.appendChild(goToButton.element);
177
        }
178
175
179
        treeElement.status = fragment;
176
        treeElement.status = fragment;
180
    }
177
    }
- a/Source/WebInspectorUI/UserInterface/Views/ResourceClusterContentView.js -1 / +1 lines
Lines 84-90 WebInspector.ResourceClusterContentView = class ResourceClusterContentView exten a/Source/WebInspectorUI/UserInterface/Views/ResourceClusterContentView.js_sec1
84
            break;
84
            break;
85
85
86
        case WebInspector.Resource.Type.WebSocket:
86
        case WebInspector.Resource.Type.WebSocket:
87
            // FIXME: <webkit.org/b/169011> Web Inspector: Show individual messages in the content pane for a WebSocket
87
            this._responseContentView = new WebInspector.WebSocketContentView(this._resource);
88
            break;
88
            break;
89
89
90
        default:
90
        default:
- a/Source/WebInspectorUI/UserInterface/Views/WebSocketContentView.css +84 lines
Line 0 a/Source/WebInspectorUI/UserInterface/Views/WebSocketContentView.css_sec1
1
/*
2
 * Copyright (C) 2017 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23
 * THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
.web-socket.content-view > .data-grid {
27
    height: 100%;
28
}
29
30
.web-socket.content-view > .data-grid table.data {
31
    height: auto;
32
    background-image: none;
33
}
34
35
.web-socket.content-view > .data-grid td.data-column,
36
.web-socket.content-view .data-grid td.data-column > div {
37
    height: auto;
38
    white-space: pre-wrap;
39
}
40
41
body[dir=ltr] .web-socket.content-view > .data-grid .data-column > div {
42
    padding-left: 18px;
43
}
44
45
body[dir=rtl] .web-socket.content-view > .data-grid .data-column > div {
46
    padding-right: 18px;
47
}
48
49
.web-socket.content-view .icon {
50
    position: absolute;
51
    margin-top: -1px;
52
}
53
54
body[dir=ltr] .web-socket.content-view .icon {
55
    left: 4px;
56
    margin-right: 2px;
57
}
58
59
body[dir=rtl] .web-socket.content-view .icon {
60
    right: 4px;
61
    margin-left: 2px;
62
}
63
64
.web-socket.content-view .outgoing .icon {
65
    background-image: url("../Images/ArrowUp.svg");
66
}
67
68
.web-socket.content-view .data-grid.variable-height-rows table.data tr:nth-child(odd) {
69
    background-color: unset;
70
}
71
72
.web-socket.content-view .data-grid table.data tr.revealed {
73
    border-bottom: 0.5px solid hsla(0, 0%, 0%, 0.1);
74
}
75
76
.web-socket.content-view .data-grid.variable-height-rows table.data tr.outgoing {
77
    background-color: hsl(80, 85%, 92%);
78
    color: hsl(120, 100%, 16%);
79
}
80
81
.web-socket.content-view .data-grid.variable-height-rows table.data tr.non-text-frame {
82
    background-color: hsl(50, 100%, 90%);
83
    color: hsl(3, 96%, 27%);
84
}
- a/Source/WebInspectorUI/UserInterface/Views/WebSocketContentView.js +139 lines
Line 0 a/Source/WebInspectorUI/UserInterface/Views/WebSocketContentView.js_sec1
1
/*
2
 * Copyright (C) 2017 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23
 * THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
WebInspector.WebSocketContentView = class WebSocketContentView extends WebInspector.ContentView
27
{
28
    constructor(resource)
29
    {
30
        console.assert(resource instanceof WebInspector.WebSocketResource, resource);
31
32
        super(resource);
33
34
        this._resource = resource;
35
        this._framesRendered = 0;
36
37
        // COMPATIBILITY (iOS 10.3): `walltime` did not exist in 10.3 and earlier.
38
        this._showTimeColumn = NetworkAgent.hasEventParameter("webSocketWillSendHandshakeRequest", "walltime");
39
40
        this.element.classList.add("web-socket", "resource");
41
42
        let columns = {data: {}};
43
        columns.data.title = WebInspector.UIString("Data");
44
        columns.data.sortable = false;
45
        columns.data.icon = true;
46
        columns.data.width = "85%";
47
48
        if (this._showTimeColumn)
49
            columns.time = {title: WebInspector.UIString("Time"), sortable: true};
50
51
        this._dataGrid = new WebInspector.DataGrid(columns);
52
        this._dataGrid.variableHeightRows = true;
53
        this.addSubview(this._dataGrid);
54
55
        this._addRow(WebInspector.UIString("WebSocket Connection Established"), this._resource.walltime, ["non-text-frame"]);
56
57
        this._dataGrid.updateLayout();
58
    }
59
60
    // Static
61
62
    static textForOpcode(opcode)
63
    {
64
        switch (opcode) {
65
        case WebInspector.WebSocketResource.OpCodes.ContinuationFrame:
66
            return WebInspector.UIString("Continuation Frame");
67
        case WebInspector.WebSocketResource.OpCodes.TextFrame:
68
            return WebInspector.UIString("Text Frame");
69
        case WebInspector.WebSocketResource.OpCodes.BinaryFrame:
70
            return WebInspector.UIString("Binary Frame");
71
        case WebInspector.WebSocketResource.OpCodes.ConnectionCloseFrame:
72
            return WebInspector.UIString("Connection Close Frame");
73
        case WebInspector.WebSocketResource.OpCodes.PingFrame:
74
            return WebInspector.UIString("Ping Frame");
75
        case WebInspector.WebSocketResource.OpCodes.PongFrame:
76
            return WebInspector.UIString("Pong Frame");
77
        }
78
    }
79
80
    // Public
81
82
    shown()
83
    {
84
        this._updateFrames();
85
        this._resource.addEventListener(WebInspector.WebSocketResource.Event.FrameAdded, this._updateFrames, this);
86
    }
87
88
    hidden()
89
    {
90
        this._resource.removeEventListener(WebInspector.WebSocketResource.Event.FrameAdded, this._updateFrames, this);
91
    }
92
93
    addFrame(data, isOutgoing, opcode, time)
94
    {
95
        let nodeText;
96
        if (opcode === WebInspector.WebSocketResource.OpCodes.TextFrame)
97
            nodeText = data;
98
        else
99
            nodeText = WebInspector.WebSocketContentView.textForOpcode(opcode);
100
101
        let classNames = [
102
            isOutgoing ? "outgoing" : "incoming",
103
            opcode === WebInspector.WebSocketResource.OpCodes.TextFrame ? "text-frame" : "non-text-frame"
104
        ];
105
106
        this._addRow(nodeText, time, classNames);
107
    }
108
109
    // Private
110
111
    _updateFrames()
112
    {
113
        let framesLength = this._resource.frames.length;
114
        for (let index = this._framesRendered; index < framesLength; index++) {
115
            let frame = this._resource.frames[index];
116
            let {data, isOutgoing, opcode, walltime} = frame;
117
            this.addFrame(data, isOutgoing, opcode, walltime);
118
        }
119
        this._framesRendered = framesLength;
120
    }
121
122
    _addRow(data, time, classNames)
123
    {
124
        let node;
125
        if (this._showTimeColumn)
126
            node = new WebInspector.DataGridNode({data, time: this._timeStringFromTimestamp(time)});
127
        else
128
            node = new WebInspector.DataGridNode({data});
129
130
        this._dataGrid.appendChild(node);
131
132
        node.element.classList.add(...classNames);
133
    }
134
135
    _timeStringFromTimestamp(timestamp)
136
    {
137
        return new Date(timestamp * 1000).toLocaleTimeString();
138
    }
139
};

Return to Bug 169011