OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Research In Motion Limited. All rights reserved. | 2 * Copyright (C) 2012 Research In Motion Limited. All rights reserved. |
3 * | 3 * |
4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU Lesser General Public | 5 * modify it under the terms of the GNU Lesser General Public |
6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 * Lesser General Public License for more details. | 12 * Lesser General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU Lesser General Public | 14 * You should have received a copy of the GNU Lesser General Public |
15 * License along with this library; if not, write to the Free Software | 15 * License along with this library; if not, write to the Free Software |
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 US
A | 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 US
A |
17 */ | 17 */ |
18 | |
19 /** | 18 /** |
20 * @constructor | 19 * @unrestricted |
21 * @extends {WebInspector.VBox} | |
22 * @param {!WebInspector.NetworkRequest} request | |
23 */ | 20 */ |
24 WebInspector.ResourceWebSocketFrameView = function(request) | 21 WebInspector.ResourceWebSocketFrameView = class extends WebInspector.VBox { |
25 { | 22 /** |
26 WebInspector.VBox.call(this); | 23 * @param {!WebInspector.NetworkRequest} request |
27 this.registerRequiredCSS("network/webSocketFrameView.css"); | 24 */ |
28 this.element.classList.add("websocket-frame-view"); | 25 constructor(request) { |
| 26 super(); |
| 27 this.registerRequiredCSS('network/webSocketFrameView.css'); |
| 28 this.element.classList.add('websocket-frame-view'); |
29 this._request = request; | 29 this._request = request; |
30 | 30 |
31 this._splitWidget = new WebInspector.SplitWidget(false, true, "resourceWebSo
cketFrameSplitViewState"); | 31 this._splitWidget = new WebInspector.SplitWidget(false, true, 'resourceWebSo
cketFrameSplitViewState'); |
32 this._splitWidget.show(this.element); | 32 this._splitWidget.show(this.element); |
33 | 33 |
34 var columns = /** @type {!Array<!WebInspector.DataGrid.ColumnDescriptor>} */
([ | 34 var columns = /** @type {!Array<!WebInspector.DataGrid.ColumnDescriptor>} */
([ |
35 {id: "data", title: WebInspector.UIString("Data"), sortable: false, weig
ht: 88}, | 35 {id: 'data', title: WebInspector.UIString('Data'), sortable: false, weight
: 88}, { |
36 {id: "length", title: WebInspector.UIString("Length"), sortable: false,
align: WebInspector.DataGrid.Align.Right, weight: 5}, | 36 id: 'length', |
37 {id: "time", title: WebInspector.UIString("Time"), sortable: true, weigh
t: 7} | 37 title: WebInspector.UIString('Length'), |
| 38 sortable: false, |
| 39 align: WebInspector.DataGrid.Align.Right, |
| 40 weight: 5 |
| 41 }, |
| 42 {id: 'time', title: WebInspector.UIString('Time'), sortable: true, weight:
7} |
38 ]); | 43 ]); |
39 | 44 |
40 this._dataGrid = new WebInspector.SortableDataGrid(columns); | 45 this._dataGrid = new WebInspector.SortableDataGrid(columns); |
41 this._dataGrid.setRowContextMenuCallback(onRowContextMenu); | 46 this._dataGrid.setRowContextMenuCallback(onRowContextMenu); |
42 this._dataGrid.setStickToBottom(true); | 47 this._dataGrid.setStickToBottom(true); |
43 this._dataGrid.setCellClass("websocket-frame-view-td"); | 48 this._dataGrid.setCellClass('websocket-frame-view-td'); |
44 this._timeComparator = /** @type {!WebInspector.SortableDataGrid.NodeCompara
tor} */ (WebInspector.ResourceWebSocketFrameNodeTimeComparator); | 49 this._timeComparator = /** @type {!WebInspector.SortableDataGrid.NodeCompara
tor} */ ( |
| 50 WebInspector.ResourceWebSocketFrameNodeTimeComparator); |
45 this._dataGrid.sortNodes(this._timeComparator, false); | 51 this._dataGrid.sortNodes(this._timeComparator, false); |
46 this._dataGrid.markColumnAsSortedBy("time", WebInspector.DataGrid.Order.Asce
nding); | 52 this._dataGrid.markColumnAsSortedBy('time', WebInspector.DataGrid.Order.Asce
nding); |
47 this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged,
this._sortItems, this); | 53 this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged,
this._sortItems, this); |
48 | 54 |
49 this._dataGrid.setName("ResourceWebSocketFrameView"); | 55 this._dataGrid.setName('ResourceWebSocketFrameView'); |
50 this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, t
his._onFrameSelected, this); | 56 this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, t
his._onFrameSelected, this); |
51 this._dataGrid.addEventListener(WebInspector.DataGrid.Events.DeselectedNode,
this._onFrameDeselected, this); | 57 this._dataGrid.addEventListener(WebInspector.DataGrid.Events.DeselectedNode,
this._onFrameDeselected, this); |
52 this._splitWidget.setMainWidget(this._dataGrid.asWidget()); | 58 this._splitWidget.setMainWidget(this._dataGrid.asWidget()); |
53 | 59 |
54 var view = new WebInspector.EmptyWidget("Select frame to browse its content.
"); | 60 var view = new WebInspector.EmptyWidget('Select frame to browse its content.
'); |
55 this._splitWidget.setSidebarWidget(view); | 61 this._splitWidget.setSidebarWidget(view); |
56 | 62 |
57 /** @type {?WebInspector.ResourceWebSocketFrameNode} */ | 63 /** @type {?WebInspector.ResourceWebSocketFrameNode} */ |
58 this._selectedNode = null; | 64 this._selectedNode = null; |
59 | 65 |
60 /** | 66 /** |
61 * @param {!WebInspector.ContextMenu} contextMenu | 67 * @param {!WebInspector.ContextMenu} contextMenu |
62 * @param {!WebInspector.DataGridNode} node | 68 * @param {!WebInspector.DataGridNode} node |
63 */ | 69 */ |
64 function onRowContextMenu(contextMenu, node) | 70 function onRowContextMenu(contextMenu, node) { |
65 { | 71 contextMenu.appendItem( |
66 contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^message")
, InspectorFrontendHost.copyText.bind(InspectorFrontendHost, node.data.data)) | 72 WebInspector.UIString.capitalize('Copy ^message'), |
| 73 InspectorFrontendHost.copyText.bind(InspectorFrontendHost, node.data.d
ata)); |
67 } | 74 } |
| 75 } |
| 76 |
| 77 /** |
| 78 * @param {number} opCode |
| 79 * @param {boolean} mask |
| 80 * @return {string} |
| 81 */ |
| 82 static opCodeDescription(opCode, mask) { |
| 83 var rawDescription = WebInspector.ResourceWebSocketFrameView.opCodeDescripti
ons[opCode] || ''; |
| 84 var localizedDescription = WebInspector.UIString(rawDescription); |
| 85 return WebInspector.UIString('%s (Opcode %d%s)', localizedDescription, opCod
e, (mask ? ', mask' : '')); |
| 86 } |
| 87 |
| 88 /** |
| 89 * @override |
| 90 */ |
| 91 wasShown() { |
| 92 this.refresh(); |
| 93 this._request.addEventListener(WebInspector.NetworkRequest.Events.WebsocketF
rameAdded, this._frameAdded, this); |
| 94 } |
| 95 |
| 96 /** |
| 97 * @override |
| 98 */ |
| 99 willHide() { |
| 100 this._request.removeEventListener(WebInspector.NetworkRequest.Events.Websock
etFrameAdded, this._frameAdded, this); |
| 101 } |
| 102 |
| 103 /** |
| 104 * @param {!WebInspector.Event} event |
| 105 */ |
| 106 _frameAdded(event) { |
| 107 var frame = /** @type {!WebInspector.NetworkRequest.WebSocketFrame} */ (even
t.data); |
| 108 this._dataGrid.insertChild(new WebInspector.ResourceWebSocketFrameNode(this.
_request.url, frame)); |
| 109 } |
| 110 |
| 111 /** |
| 112 * @param {!WebInspector.Event} event |
| 113 */ |
| 114 _onFrameSelected(event) { |
| 115 var selectedNode = /** @type {!WebInspector.ResourceWebSocketFrameNode} */ (
event.target.selectedNode); |
| 116 this._currentSelectedNode = selectedNode; |
| 117 var contentProvider = selectedNode.contentProvider(); |
| 118 contentProvider.requestContent().then(contentHandler.bind(this)); |
| 119 |
| 120 /** |
| 121 * @param {(string|null)} content |
| 122 * @this {WebInspector.ResourceWebSocketFrameView} |
| 123 */ |
| 124 function contentHandler(content) { |
| 125 if (this._currentSelectedNode !== selectedNode) |
| 126 return; |
| 127 WebInspector.JSONView.parseJSON(content).then(handleJSONData.bind(this)); |
| 128 } |
| 129 |
| 130 /** |
| 131 * @param {?WebInspector.ParsedJSON} parsedJSON |
| 132 * @this {WebInspector.ResourceWebSocketFrameView} |
| 133 */ |
| 134 function handleJSONData(parsedJSON) { |
| 135 if (this._currentSelectedNode !== selectedNode) |
| 136 return; |
| 137 if (parsedJSON) |
| 138 this._splitWidget.setSidebarWidget(WebInspector.JSONView.createSearchabl
eView(parsedJSON)); |
| 139 else |
| 140 this._splitWidget.setSidebarWidget(new WebInspector.ResourceSourceFrame(
contentProvider)); |
| 141 } |
| 142 } |
| 143 |
| 144 /** |
| 145 * @param {!WebInspector.Event} event |
| 146 */ |
| 147 _onFrameDeselected(event) { |
| 148 this._currentSelectedNode = null; |
| 149 } |
| 150 |
| 151 refresh() { |
| 152 this._dataGrid.rootNode().removeChildren(); |
| 153 var frames = this._request.frames(); |
| 154 for (var i = 0; i < frames.length; ++i) |
| 155 this._dataGrid.insertChild(new WebInspector.ResourceWebSocketFrameNode(thi
s._request.url, frames[i])); |
| 156 } |
| 157 |
| 158 _sortItems() { |
| 159 this._dataGrid.sortNodes(this._timeComparator, !this._dataGrid.isSortOrderAs
cending()); |
| 160 } |
68 }; | 161 }; |
69 | 162 |
70 /** @enum {number} */ | 163 /** @enum {number} */ |
71 WebInspector.ResourceWebSocketFrameView.OpCodes = { | 164 WebInspector.ResourceWebSocketFrameView.OpCodes = { |
72 ContinuationFrame: 0, | 165 ContinuationFrame: 0, |
73 TextFrame: 1, | 166 TextFrame: 1, |
74 BinaryFrame: 2, | 167 BinaryFrame: 2, |
75 ConnectionCloseFrame: 8, | 168 ConnectionCloseFrame: 8, |
76 PingFrame: 9, | 169 PingFrame: 9, |
77 PongFrame: 10 | 170 PongFrame: 10 |
78 }; | 171 }; |
79 | 172 |
80 /** @type {!Array.<string> } */ | 173 /** @type {!Array.<string> } */ |
81 WebInspector.ResourceWebSocketFrameView.opCodeDescriptions = (function() | 174 WebInspector.ResourceWebSocketFrameView.opCodeDescriptions = (function() { |
82 { | 175 var opCodes = WebInspector.ResourceWebSocketFrameView.OpCodes; |
83 var opCodes = WebInspector.ResourceWebSocketFrameView.OpCodes; | 176 var map = []; |
84 var map = []; | 177 map[opCodes.ContinuationFrame] = 'Continuation Frame'; |
85 map[opCodes.ContinuationFrame] = "Continuation Frame"; | 178 map[opCodes.TextFrame] = 'Text Frame'; |
86 map[opCodes.TextFrame] = "Text Frame"; | 179 map[opCodes.BinaryFrame] = 'Binary Frame'; |
87 map[opCodes.BinaryFrame] = "Binary Frame"; | 180 map[opCodes.ContinuationFrame] = 'Connection Close Frame'; |
88 map[opCodes.ContinuationFrame] = "Connection Close Frame"; | 181 map[opCodes.PingFrame] = 'Ping Frame'; |
89 map[opCodes.PingFrame] = "Ping Frame"; | 182 map[opCodes.PongFrame] = 'Pong Frame'; |
90 map[opCodes.PongFrame] = "Pong Frame"; | 183 return map; |
91 return map; | |
92 })(); | 184 })(); |
93 | 185 |
94 /** | |
95 * @param {number} opCode | |
96 * @param {boolean} mask | |
97 * @return {string} | |
98 */ | |
99 WebInspector.ResourceWebSocketFrameView.opCodeDescription = function(opCode, mas
k) | |
100 { | |
101 var rawDescription = WebInspector.ResourceWebSocketFrameView.opCodeDescripti
ons[opCode] || ""; | |
102 var localizedDescription = WebInspector.UIString(rawDescription); | |
103 return WebInspector.UIString("%s (Opcode %d%s)", localizedDescription, opCod
e, (mask ? ", mask" : "")); | |
104 }; | |
105 | |
106 WebInspector.ResourceWebSocketFrameView.prototype = { | |
107 wasShown: function() | |
108 { | |
109 this.refresh(); | |
110 this._request.addEventListener(WebInspector.NetworkRequest.Events.Websoc
ketFrameAdded, this._frameAdded, this); | |
111 }, | |
112 | |
113 willHide: function() | |
114 { | |
115 this._request.removeEventListener(WebInspector.NetworkRequest.Events.Web
socketFrameAdded, this._frameAdded, this); | |
116 }, | |
117 | |
118 /** | |
119 * @param {!WebInspector.Event} event | |
120 */ | |
121 _frameAdded: function(event) | |
122 { | |
123 var frame = /** @type {!WebInspector.NetworkRequest.WebSocketFrame} */ (
event.data); | |
124 this._dataGrid.insertChild(new WebInspector.ResourceWebSocketFrameNode(t
his._request.url, frame)); | |
125 }, | |
126 | |
127 /** | |
128 * @param {!WebInspector.Event} event | |
129 */ | |
130 _onFrameSelected: function(event) | |
131 { | |
132 var selectedNode = /** @type {!WebInspector.ResourceWebSocketFrameNode}
*/ (event.target.selectedNode); | |
133 this._currentSelectedNode = selectedNode; | |
134 var contentProvider = selectedNode.contentProvider(); | |
135 contentProvider.requestContent().then(contentHandler.bind(this)); | |
136 | |
137 /** | |
138 * @param {(string|null)} content | |
139 * @this {WebInspector.ResourceWebSocketFrameView} | |
140 */ | |
141 function contentHandler(content) { | |
142 if (this._currentSelectedNode !== selectedNode) | |
143 return; | |
144 WebInspector.JSONView.parseJSON(content).then(handleJSONData.bind(th
is)); | |
145 } | |
146 | |
147 /** | |
148 * @param {?WebInspector.ParsedJSON} parsedJSON | |
149 * @this {WebInspector.ResourceWebSocketFrameView} | |
150 */ | |
151 function handleJSONData(parsedJSON) | |
152 { | |
153 if (this._currentSelectedNode !== selectedNode) | |
154 return; | |
155 if (parsedJSON) | |
156 this._splitWidget.setSidebarWidget(WebInspector.JSONView.createS
earchableView(parsedJSON)); | |
157 else | |
158 this._splitWidget.setSidebarWidget(new WebInspector.ResourceSour
ceFrame(contentProvider)); | |
159 } | |
160 }, | |
161 | |
162 /** | |
163 * @param {!WebInspector.Event} event | |
164 */ | |
165 _onFrameDeselected: function(event) | |
166 { | |
167 this._currentSelectedNode = null; | |
168 }, | |
169 | |
170 refresh: function() | |
171 { | |
172 this._dataGrid.rootNode().removeChildren(); | |
173 var frames = this._request.frames(); | |
174 for (var i = 0; i < frames.length; ++i) | |
175 this._dataGrid.insertChild(new WebInspector.ResourceWebSocketFrameNo
de(this._request.url, frames[i])); | |
176 }, | |
177 | |
178 _sortItems: function() | |
179 { | |
180 this._dataGrid.sortNodes(this._timeComparator, !this._dataGrid.isSortOrd
erAscending()); | |
181 }, | |
182 | |
183 __proto__: WebInspector.VBox.prototype | |
184 }; | |
185 | 186 |
186 /** | 187 /** |
187 * @constructor | 188 * @unrestricted |
188 * @extends {WebInspector.SortableDataGridNode} | |
189 * @param {string} url | |
190 * @param {!WebInspector.NetworkRequest.WebSocketFrame} frame | |
191 */ | 189 */ |
192 WebInspector.ResourceWebSocketFrameNode = function(url, frame) | 190 WebInspector.ResourceWebSocketFrameNode = class extends WebInspector.SortableDat
aGridNode { |
193 { | 191 /** |
| 192 * @param {string} url |
| 193 * @param {!WebInspector.NetworkRequest.WebSocketFrame} frame |
| 194 */ |
| 195 constructor(url, frame) { |
194 var dataText = frame.text; | 196 var dataText = frame.text; |
195 var length = frame.text.length; | 197 var length = frame.text.length; |
196 var time = new Date(frame.time * 1000); | 198 var time = new Date(frame.time * 1000); |
197 var timeText = ("0" + time.getHours()).substr(-2) + ":" + ("0" + time.getMin
utes()).substr(-2) + ":" + ("0" + time.getSeconds()).substr(-2) + "." + ("00" +
time.getMilliseconds()).substr(-3); | 199 var timeText = ('0' + time.getHours()).substr(-2) + ':' + ('0' + time.getMin
utes()).substr(-2) + ':' + |
198 var timeNode = createElement("div"); | 200 ('0' + time.getSeconds()).substr(-2) + '.' + ('00' + time.getMillisecond
s()).substr(-3); |
| 201 var timeNode = createElement('div'); |
199 timeNode.createTextChild(timeText); | 202 timeNode.createTextChild(timeText); |
200 timeNode.title = time.toLocaleString(); | 203 timeNode.title = time.toLocaleString(); |
201 | 204 |
202 var isTextFrame = frame.opCode === WebInspector.ResourceWebSocketFrameView.O
pCodes.TextFrame; | 205 var isTextFrame = frame.opCode === WebInspector.ResourceWebSocketFrameView.O
pCodes.TextFrame; |
203 if (!isTextFrame) | 206 if (!isTextFrame) |
204 dataText = WebInspector.ResourceWebSocketFrameView.opCodeDescription(fra
me.opCode, frame.mask); | 207 dataText = WebInspector.ResourceWebSocketFrameView.opCodeDescription(frame
.opCode, frame.mask); |
205 | 208 |
206 WebInspector.SortableDataGridNode.call(this, {data: dataText, length: length
, time: timeNode}); | 209 super({data: dataText, length: length, time: timeNode}); |
207 | 210 |
208 this._url = url; | 211 this._url = url; |
209 this._frame = frame; | 212 this._frame = frame; |
210 this._isTextFrame = isTextFrame; | 213 this._isTextFrame = isTextFrame; |
211 this._dataText = dataText; | 214 this._dataText = dataText; |
212 }; | 215 } |
213 | 216 |
214 WebInspector.ResourceWebSocketFrameNode.prototype = { | 217 /** |
215 /** | 218 * @override |
216 * @override | 219 */ |
217 */ | 220 createCells() { |
218 createCells: function() | 221 var element = this._element; |
219 { | 222 element.classList.toggle( |
220 var element = this._element; | 223 'websocket-frame-view-row-error', this._frame.type === WebInspector.Netw
orkRequest.WebSocketFrameType.Error); |
221 element.classList.toggle("websocket-frame-view-row-error", this._frame.t
ype === WebInspector.NetworkRequest.WebSocketFrameType.Error); | 224 element.classList.toggle( |
222 element.classList.toggle("websocket-frame-view-row-outcoming", this._fra
me.type === WebInspector.NetworkRequest.WebSocketFrameType.Send); | 225 'websocket-frame-view-row-outcoming', this._frame.type === WebInspector.
NetworkRequest.WebSocketFrameType.Send); |
223 element.classList.toggle("websocket-frame-view-row-opcode", !this._isTex
tFrame); | 226 element.classList.toggle('websocket-frame-view-row-opcode', !this._isTextFra
me); |
224 WebInspector.SortableDataGridNode.prototype.createCells.call(this); | 227 super.createCells(); |
225 }, | 228 } |
226 | 229 |
227 /** | 230 /** |
228 * @override | 231 * @override |
229 * @return {number} | 232 * @return {number} |
230 */ | 233 */ |
231 nodeSelfHeight: function() | 234 nodeSelfHeight() { |
232 { | 235 return 17; |
233 return 17; | 236 } |
234 }, | |
235 | 237 |
236 /** | 238 /** |
237 * @return {!WebInspector.ContentProvider} | 239 * @return {!WebInspector.ContentProvider} |
238 */ | 240 */ |
239 contentProvider: function() | 241 contentProvider() { |
240 { | 242 return WebInspector.StaticContentProvider.fromString( |
241 return WebInspector.StaticContentProvider.fromString(this._url, WebInspe
ctor.resourceTypes.WebSocket, this._dataText); | 243 this._url, WebInspector.resourceTypes.WebSocket, this._dataText); |
242 }, | 244 } |
243 | |
244 __proto__: WebInspector.SortableDataGridNode.prototype | |
245 }; | 245 }; |
246 | 246 |
247 /** | 247 /** |
248 * @param {!WebInspector.ResourceWebSocketFrameNode} a | 248 * @param {!WebInspector.ResourceWebSocketFrameNode} a |
249 * @param {!WebInspector.ResourceWebSocketFrameNode} b | 249 * @param {!WebInspector.ResourceWebSocketFrameNode} b |
250 * @return {number} | 250 * @return {number} |
251 */ | 251 */ |
252 WebInspector.ResourceWebSocketFrameNodeTimeComparator = function(a, b) | 252 WebInspector.ResourceWebSocketFrameNodeTimeComparator = function(a, b) { |
253 { | 253 return a._frame.time - b._frame.time; |
254 return a._frame.time - b._frame.time; | |
255 }; | 254 }; |
OLD | NEW |